bill 4 months ago
parent
commit
5a9d47b7d9

+ 18 - 16
src/api/material.ts

@@ -46,6 +46,7 @@ export type Material = {
   status: number;
   group: string;
   uploadId?: number;
+  isSystem?: number
   modelId?: number;
 };
 
@@ -76,22 +77,22 @@ export const fetchMaterialPage = async (params: MaterialPageProps) => {
     }))
   }
 
-  const testUrls = [
-    'dog.glb', 'man--running.glb', 'man--walk.glb', 'Soldier.glb', 'Xbot.glb', 'Man.glb'
-  ]
-  nm.list.unshift(
-    ...testUrls.map((item, ndx) => ({
-      id: ndx,
-      name: item,
-      format: 'glb',
-      url: `/animation/${item}`,
-      size: 1,
-      groupId: 1,
-      status: 1,
-      group: '动画模型',
-      uploadId: 1
-    }))
-  )
+  // const testUrls = [
+  //   'dog.glb', 'man--running.glb', 'man--walk.glb', 'Soldier.glb', 'Xbot.glb', 'Man.glb'
+  // ]
+  // nm.list.unshift(
+  //   ...testUrls.map((item, ndx) => ({
+  //     id: ndx,
+  //     name: item,
+  //     format: 'glb',
+  //     url: `/animation/${item}`,
+  //     size: 1,
+  //     groupId: 1,
+  //     status: 1,
+  //     group: '动画模型',
+  //     uploadId: 1
+  //   }))
+  // )
   
   return nm;
 };
@@ -100,6 +101,7 @@ export const fetchMaterialGroups = async () => {
   return (await axios.get<ServiceMaterialGroup[]>(MATERIAL_GROUP_LIST)).map(
     (item) => ({
       name: item.dictName,
+      key: item.dictKey,
       id: item.id,
     })
   ) as MaterialGroup[];

+ 5 - 1
src/app.vue

@@ -18,7 +18,11 @@
       :style="layoutStyles"
       :class="layoutClassNames"
     >
-      <div :ref="(el: any) => appEl = (el as HTMLDivElement)" v-if="loaded">
+      <div
+        :ref="(el: any) => appEl = (el as HTMLDivElement)"
+        v-if="loaded"
+        class="app-con"
+      >
         <router-view v-slot="{ Component }">
           <!-- <keep-alive> -->
           <component :is="Component" />

+ 8 - 1
src/components/materials/index.vue

@@ -118,6 +118,7 @@ const props = defineProps<{
   visible: boolean;
   count?: number;
   readonly?: boolean;
+  groupIds: number[];
   afterClose?: () => void;
 }>();
 
@@ -136,8 +137,8 @@ const Search = Input.Search;
 const params = reactive({
   pageNum: 1,
   pageSize: 10,
-  groupIds: [],
   formats: props.format,
+  groupIds: props.groupIds,
 }) as MaterialPageProps;
 const origin = ref<PagingResult<Material[]>>({
   list: [],
@@ -172,6 +173,7 @@ const rowSelection: any = ref({
   },
 });
 const cloumns = computed(() => {
+  const groupIds = params.groupIds;
   const cloumns = [
     {
       title: "名称",
@@ -201,12 +203,17 @@ const cloumns = computed(() => {
       title: "分组",
       dataIndex: "group",
       key: "group",
+      filteredValue: groupIds,
       filters: props.readonly
         ? undefined
         : groups.value.map((g) => ({
             text: g.name,
             value: g.id,
           })),
+      // filters: groups.value.map((g) => ({
+      //   text: g.name,
+      //   value: g.id,
+      // })),
     },
   ];
   if (!props.readonly) {

+ 2 - 0
src/components/materials/quisk.ts

@@ -6,9 +6,11 @@ import { reactive } from "vue";
 export const selectMaterials = async (props: {
   uploadFormat?: string[],
   format?: string[];
+  isSystem?: number,
   maxSize?: number;
   count?: number
   readonly?: boolean;
+  groupIds?: number[]
 } = {}) => {
   return new Promise<Material[] | null>((resolve) => {
     const mprops = reactive({

+ 29 - 0
src/components/monitor-exit/index.vue

@@ -0,0 +1,29 @@
+<template>
+  <div class="exit fun-ctrl" @click="onClick">
+    <ui-icon type="close" />
+  </div>
+</template>
+
+<script setup lang="ts">
+defineProps<{ onClick: () => void }>();
+</script>
+
+<style lang="scss" scoped>
+.exit {
+  position: absolute;
+  top: 20px;
+  right: 20px;
+  width: 50px;
+  height: 50px;
+  background-color: rgba(0, 0, 0, 0.5);
+  border-radius: 50%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  z-index: 99999;
+
+  .icon {
+    font-size: 18px;
+  }
+}
+</style>

+ 30 - 6
src/components/view-setting/index.vue

@@ -11,8 +11,8 @@
             <ui-input
               @click.stop
               type="checkbox"
-              :modelValue="option.stack.current.value.value"
-              @update:modelValue="(s: boolean) => option.stack.current.value.value = s"
+              :modelValue="option.stack.value"
+              @update:modelValue="(s: boolean) => option.stack.value = s"
               :label="option.text"
             />
           </menu-item>
@@ -31,13 +31,37 @@ import {
   showTaggingsStack,
 } from "@/env";
 import { DownOutlined } from "@ant-design/icons-vue";
+import { computed, watchEffect } from "vue";
+import { selectPaths } from "@/store";
+
+const props = defineProps<{ value?: Record<string, boolean> }>();
+const emit = defineEmits<{ (e: "update:value", v: Record<string, boolean>): void }>();
 
 const showOptions = [
-  { text: "标签", stack: showTaggingsStack },
-  { text: "监控", stack: showMonitorsStack },
-  { text: "路径", stack: showPathsStack },
-  { text: "测量", stack: showMeasuresStack },
+  { key: "showTagging", text: "标签", stack: showTaggingsStack.current.value },
+  { key: "showMeasure", text: "测量", stack: showMeasuresStack.current.value },
+  {
+    key: "showPath",
+    text: "路径",
+    stack: computed({
+      get: () => selectPaths.all.value || selectPaths.selects.value.length > 0,
+      set: (val: boolean) => (selectPaths.all.value = val),
+    }),
+  },
 ];
+watchEffect(() => {
+  if (!props.value) return;
+  showOptions.forEach((item) => {
+    item.stack.value = props.value![item.key];
+  });
+});
+
+watchEffect(() => {
+  emit(
+    "update:value",
+    Object.fromEntries(showOptions.map((item) => [item.key, item.stack.value] as const))
+  );
+});
 </script>
 
 <style lang="scss" scoped>

+ 2 - 0
src/hook/ids.ts

@@ -13,7 +13,9 @@ export const useSelects = <T extends { id: any }>(items: Ref<T[]>, test = false)
     }
   };
   const updateSelectId = (id: any, select: boolean) => {
+    console.log('===>', id)
     const item = items.value.find((s) => s.id === id);
+    console.log('===>', item)
     item && updateSelect(item, select);
   };
 

+ 0 - 6
src/sdk/association/animation.ts

@@ -126,7 +126,6 @@ export const addFrame = (
     ([map, exists]) => {
       if (!map?.am) return;
       if (exists && !map.frames[data.id]) {
-        console.error('addFrame', am.title, data)
         map.frames[data.id] = map.am.addFrame(data);
       } else if (!exists && map.frames[data.id]) {
         map.frames[data.id].destroy();
@@ -183,7 +182,6 @@ export const addAction = (
     ([map, exists]) => {
       if (!map?.am) return;
       if (exists && !map.actions[data.id]) {
-        console.error('addAction', am.title, data)
         map.actions[data.id] = map.am.addAction(data);
       } else if (!exists && map.actions[data.id]) {
         map.actions[data.id].destroy();
@@ -266,7 +264,6 @@ export const addPath = (
     watchEffect(() => amMap[key]?.paths[data.id]?.changeReverse(data.reverse)),
     watchEffect(() => amMap[key]?.paths[data.id]?.changeDuration(data.duration)),
     watchEffect(() => {
-      console.error(path.value, pathData.value)
       path.value &&amMap[key]?.paths[data.id]?.changePath(path.value)
     })
   );
@@ -313,7 +310,6 @@ export const addSubtitle = (data: AnimationModelSubtitle) => {
     ([map, exists]) => {
       if (!map?.am) return;
       if (exists && !map.subtitles[data.id]) {
-        console.error('add subtitle', am.title, data)
         map.subtitles[data.id] = mount(
           document.querySelector("#app")!,
           Subtitle,
@@ -472,7 +468,6 @@ export const associationAnimation = (sdk: SDK, el: HTMLDivElement) => {
       for (const am of added) {
         const am3d = amMap[am.id]
         if (!am3d || !am3d.am) continue;
-        console.error('global-frame', am3d.am)
         const frame = am3d.am!.addFrame({
           id: uuid(),
           mat: am.mat || am3d.am.getModelPose(),
@@ -486,7 +481,6 @@ export const associationAnimation = (sdk: SDK, el: HTMLDivElement) => {
             console.log('set-global-frame', am.mat)
           }),
           () => {
-            console.error('destroy-global-frame', am3d.am)
             frame.destroy();
             am3d.globalFrame = undefined;
             delete cleanupMap[am.id]

+ 9 - 2
src/sdk/association/guide.ts

@@ -2,7 +2,7 @@ import { SceneGuide, sdk } from "../sdk";
 import { toRaw, ref, watch, watchEffect, computed } from "vue";
 import { viewModeStack, showLeftPanoStack, custom, showTaggingsStack, showPathsStack, showMeasuresStack, showSearchStack } from "@/env";
 import { togetherCallback, asyncTimeout } from "@/utils";
-import { fuseModels, isEdit, sysBus, fuseModelsLoaded } from "@/store";
+import { fuseModels, isEdit, sysBus, fuseModelsLoaded, selectPaths } from "@/store";
 import type { FuseModel, FuseModels, Guide, GuidePath } from "@/store";
 import { analysisPoseInfo } from ".";
 import { fullView, isScenePlayRun, pauseScene, playScene } from "@/utils/full";
@@ -103,9 +103,16 @@ export const playSceneGuide = (
           }
           changeIndexCallback && changeIndexCallback(index);
         });
+        const oldSelect = [...selectPaths.selects.value]
+        const oldUSelect = [...selectPaths.unSelects.value]
+        selectPaths.all.value = guide ? guide.showPath :  true
         pop = togetherCallback([
           showTaggingsStack.push(computed(() => guide ? guide.showTagging : true)),
-          showPathsStack.push(computed(() => guide ? guide.showPath : true)),
+          () => {
+            oldSelect.forEach(item => selectPaths.updateSelectId(item.id, true))
+            oldUSelect.forEach(item => selectPaths.updateSelectId(item.id, false))
+          },
+          // showPathsStack.push(computed(() => guide ? guide.showPath : true)),
           showMeasuresStack.push(computed(() => guide ? guide.showMeasure : true)),
           showSearchStack.push(ref(false))
         ])

+ 2 - 1
src/sdk/association/index.ts

@@ -13,6 +13,7 @@ import { associationMessaures } from "./measure";
 import { custom } from "@/env";
 import { associationPaths } from "./path";
 import { associationAnimation } from "./animation";
+import { associationMonitor } from "./monitor";
 
 export const getSupperPanoModel = () => {
   const supperModel = ref<FuseModel | null>(null);
@@ -25,7 +26,6 @@ export const getSupperPanoModel = () => {
       const data = sdk.canTurnToPanoMode();
       if (data?.model) {
         const smodel = getFuseModel(data.model)!
-        console.log('?优质')
         supperModel.value = smodel;
       } else {
         supperModel.value = null;
@@ -122,6 +122,7 @@ export const setupAssociation = (mountEl: HTMLDivElement, sdk: SDK) => {
       associationSetting(sdk, mountEl);
       associationPaths(sdk, mountEl)
       associationAnimation(sdk, mountEl)
+      associationMonitor(sdk, mountEl)
       nextTick(() => stopWatch());
     }
   });

+ 38 - 0
src/sdk/association/monitor.ts

@@ -0,0 +1,38 @@
+import { mergeFuns } from "@/components/drawing/hook";
+import { SDK } from "../sdk";
+import { mount } from "@/utils";
+import monitorExit from "../../components/monitor-exit/index.vue";
+import { showRightPanoStack } from "@/env";
+import { ref } from "vue";
+
+export const associationMonitor = (sdk: SDK, el: HTMLDivElement) => {
+  const hideControl = () => {
+    const layerApp = document.querySelector("#layout-app") as HTMLDivElement;
+    const doms = [
+      ...Array.from(
+        document.querySelectorAll("#layout-app > .app-con >*:not(.laser-layer)")
+      ),
+      ...Array.from(
+        document.querySelectorAll(
+          "#layout-app .laser-layer >*:not(.scene-canvas)"
+        )
+      ),
+    ];
+
+    const cleanups = Array.from(doms).map((dom) => {
+      dom.classList.add("hide-control");
+      return () => dom.classList.remove("hide-control");
+    });
+    cleanups.push(
+      mount(layerApp, monitorExit, {
+        onClick: () => recover(),
+      }),
+      showRightPanoStack.push(ref(false)),
+      () => sdk.exitWatchMonitor()
+    );
+
+    const recover = mergeFuns(cleanups);
+  };
+  setTimeout(hideControl, 2000);
+  sdk.sceneBus.on("watchMonitor", hideControl);
+};

+ 0 - 1
src/sdk/association/path.ts

@@ -33,7 +33,6 @@ export const pathsGroup = groupProxy(() => {
       nodes.push(node);
     }
   }
-  console.error(nodes)
   return nodes;
 });
 

+ 2 - 0
src/sdk/sdk.ts

@@ -161,10 +161,12 @@ export interface SDK {
   layout: HTMLDivElement;
   sceneBus: Emitter<{
     cameraChange: SceneLocalPos;
+    watchMonitor: void
     panoModelChange: SceneModel;
     modeChange: { mode: "pano" | "fuse"; active: SceneModel };
   }>;
 
+  exitWatchMonitor: () => void
   setBackdrop: (
     drop: string,
     type: SettingResourceType,

+ 4 - 0
src/style.scss

@@ -155,4 +155,8 @@ input::-ms-clear,input::-ms-reveal {
 
 .nameInput.ui-input .text.suffix input {
   padding-right: 70px;
+}
+
+.hide-control {
+  display: none !important;
 }

+ 7 - 1
src/views/animation/left.vue

@@ -49,6 +49,7 @@ import { ref, watch, watchEffect } from "vue";
 import { TabPane, Tabs } from "ant-design-vue";
 import { ams, AnimationModel, createAnimationModel } from "@/store/animation";
 import { useSelects } from "@/hook/ids";
+import { fetchMaterialGroups } from "@/api/material";
 
 useViewStack(() =>
   togetherCallback([
@@ -100,11 +101,16 @@ const clickHandler = (item: AnimationModel) => {
 };
 
 const selectModel = async () => {
+  const groups = await fetchMaterialGroups();
+  const group = groups.find((item) => item.name === "动画模型");
+  console.error(group);
   const list = await selectMaterials({
     uploadFormat: ["animation-model"],
-    format: ["glb"],
+    // format: ["glb"],
+    isSystem: 1,
     maxSize: 2 * 1024 * 1024 * 1024,
     readonly: true,
+    groupIds: group ? [group.id] : undefined,
   });
   if (!list?.length) return;
   list.forEach((item) => {

+ 16 - 2
src/views/guide/guide/edit-paths.vue

@@ -10,7 +10,21 @@
         添加视角
       </ui-button>
     </div>
-    <ViewSetting class="show-setting" />
+    <ViewSetting
+      class="setting"
+      :value="{
+        showTagging: data.showTagging,
+        showMeasure: data.showMeasure,
+        showPath: data.showPath,
+      }"
+      @update:value="
+        (v) => {
+          data.showMeasure = v.showMeasure;
+          data.showPath = v.showPath;
+          data.showTagging = v.showTagging;
+        }
+      "
+    />
 
     <div class="info" v-if="paths.length">
       <div class="meta">
@@ -301,7 +315,7 @@ onUnmounted(() => {
     }
   }
 
-  .show-setting {
+  .setting {
     position: absolute;
     right: 20px;
     bottom: 100%;