bill 2 лет назад
Родитель
Сommit
c7edbb5f81

+ 3 - 3
src/main.ts

@@ -28,8 +28,8 @@ app.use(Components);
 
 app.mount("#app");
 
-if (params.theme) {
-  document.documentElement.classList.add(params.theme);
-}
+// if (params.theme) {
+document.documentElement.classList.add(params.theme);
+// }
 
 export default app;

+ 4 - 1
src/sdk/types/sdk.ts

@@ -331,6 +331,7 @@ export type FixPoint3DArgs = {
   measure: boolean;
   graph?: Pos3D[];
   pos?: Pos3D;
+  basePoint?: Pos3D;
 };
 export type FixPoint3D = {
   // 销毁当前固定点对象,测量、形状一起删除
@@ -339,12 +340,14 @@ export type FixPoint3D = {
   quitMeasure(): void;
   // 当不会形状时 外面可以修改固定点位置, 通过这个函数通知3d对象
   changePos(data: Pos3D): void;
+  // 当不会形状时 外面可以修改固定点位置, 通过这个函数通知3d对象
+  changeBase(data: Pos3D): void;
   // 当正在绘制形状时,外面可以确定完成 或者取消, 确定完成时通过这个对象告知
   graphDrawComplete(): void;
 
   bus: Emitter<{
     // 测量线被选中对象,值为是否选中
-    selectMeasure: boolean;
+    selected: boolean;
     // 形状被选中事件,值为是否选中
     selectGraph: boolean;
     // 这个不用实现

+ 7 - 3
src/store/fixPoint.ts

@@ -14,11 +14,15 @@ type FixPointBase = {
   id: string;
   text: string;
   pos: Point;
-} & { measure: boolean; lines: Point[][] };
+} & {
+  measure: boolean;
+  lines: { points: Point[]; dis: number }[];
+  baseId?: string;
+};
 
-type PFixPoint = FixPointBase & { type: FixType.POINT };
+export type PFixPoint = FixPointBase & { type: FixType.POINT };
 
-type GFixPoint = FixPointBase & { type: FixType.GRAPH; points: Point[] };
+export type GFixPoint = FixPointBase & { type: FixType.GRAPH; points: Point[] };
 
 export type FixPoint = FixPointBase | PFixPoint | GFixPoint;
 

+ 1 - 1
src/views/scene/covers/fixPoint.vue

@@ -39,7 +39,7 @@ const fix3d = getFix3d(props.data);
 
 if (fix3d) {
   fix3d.bus.on("selectGraph", (select) => (select ? emit("focus") : emit("blur")));
-  fix3d.bus.on("selectMeasure", (select) =>
+  fix3d.bus.on("selected", (select) =>
     select ? emit("focusMeasure") : emit("blurMeasure")
   );
 }

+ 2 - 5
src/views/scene/covers/fixPoints.vue

@@ -98,12 +98,9 @@ const activeActionMenus = computed(() =>
           color: "#FF4D4F",
           iconColor: "#fff",
           onClick() {
-            const index = fixPoints.value.indexOf(customMap.activeFixPoint);
-            if (~index) {
-              fixPoints.value.splice(index, 1);
-              edit.value = null;
+            if (delFix3d(customMap.activeFixPoint)) {
               customMap.activeFixPoint = null;
-              delFix3d(customMap.activeFixPoint);
+              edit.value = null;
             }
           },
         },

+ 126 - 10
src/views/scene/fixManage.ts

@@ -1,11 +1,77 @@
-import { useSDK } from "@/hook";
-import { FixPoint3D, FixPoint3DArgs } from "@/sdk";
-import { FixPoint, FixType } from "@/store/fixPoint";
-import { ref, shallowRef, watchEffect } from "vue";
+import { CustomCom, customMap, useAsyncSDK, useConfirm, useSDK } from "@/hook";
+import { Base, FixPoint3D, FixPoint3DArgs, SDK } from "@/sdk";
+import { baseLines } from "@/store/baseLine";
+import { BasePoint, basePoints } from "@/store/basePoint";
+import { FixPoint, FixType, fixPoints } from "@/store/fixPoint";
+import { Message } from "@kankan/components/expose-common";
+import { ref, nextTick, shallowRef, watch, watchEffect } from "vue";
+import { goto } from "./menus/data";
 
-const sdk = useSDK();
+let sdk: SDK;
+useAsyncSDK().then((a) => (sdk = a));
 const fix3ds: { [key in string]: FixPoint3D } = {};
 
+let basePointId: string;
+export const baseCheck = () => {
+  if (!measureMode.value) {
+    return true;
+  }
+  if (!baseLines.value.length) {
+    useConfirm({
+      title: "提示",
+      content: "请线绘制基准线",
+      okText: "去绘制",
+      noText: "取消",
+    }).then((ok) => {
+      if (ok) {
+        goto(["baseLineOrPoint", "baseLine"]);
+      }
+    });
+    return false;
+  }
+  if (!basePoints.value.length) {
+    useConfirm({
+      title: "提示",
+      content: "请线创建基准点",
+      okText: "创建基准点",
+      noText: "取消",
+    }).then((ok) => {
+      if (ok) {
+        goto(["baseLineOrPoint", "basePoint"]);
+      }
+    });
+    return false;
+  }
+
+  let hideTip;
+  let stopWatch;
+  return {
+    stop() {
+      hideTip && hideTip();
+      hideTip = null;
+      stopWatch && stopWatch();
+      stopWatch = null;
+    },
+    promise: new Promise<BasePoint>((resolve) => {
+      stopWatch = watchEffect(() => {
+        if (!customMap.activeBasePoint) {
+          hideTip = Message.success({ msg: "请选择一个基准点" });
+        } else {
+          resolve(customMap.activeBasePoint);
+          hideTip && hideTip();
+          hideTip = null;
+          nextTick(() => {
+            stopWatch && stopWatch();
+            stopWatch = null;
+          });
+        }
+      });
+    }).then((basePoint) => {
+      basePointId = basePoint.id;
+    }),
+  };
+};
+
 export enum DrawStatus {
   un,
   ing,
@@ -14,9 +80,6 @@ export enum DrawStatus {
 }
 export const drawstatus = ref(DrawStatus.un);
 export const measureMode = ref(false);
-watchEffect(() => {
-  console.error(measureMode.value);
-});
 const drawingFix3d = shallowRef<FixPoint3D[]>([]);
 
 watchEffect(() => {
@@ -28,13 +91,47 @@ watchEffect(() => {
     drawingFix3d.value = [];
   } else if (drawstatus.value === DrawStatus.quit) {
     drawingFix3d.value.forEach((fix3d) => {
-      fix3d.destroy();
       fix3d.bus.emit("graphDrawComplete", false);
+      fix3d.destroy();
     });
     drawingFix3d.value = [];
   }
 });
 
+// 固定点关联基准线 基准点
+const fixJoinBase = (data: FixPoint, fix3d: FixPoint3D) => {
+  const stopBaseExixtsWatch = watch(
+    () => ({
+      existsBasePoint: !basePoints.value.some(
+        (base) => base.id === data.baseId
+      ),
+      existsBaseLine: baseLines.value.length === 0,
+    }),
+    (args) => {
+      if (!args.existsBasePoint || !args.existsBaseLine) {
+        quitMeasure(data);
+        stopBaseExixtsWatch();
+      }
+    }
+  );
+
+  const stopBasePosWatch = watch(
+    () => {
+      const basePoint = basePoints.value.find(
+        (base) => base.id === data.baseId
+      );
+      return basePoint ? { ...basePoint.pos } : null;
+    },
+    (basePos) => {
+      if (!basePos) {
+        stopBasePosWatch();
+      } else {
+        fix3d.changeBase(basePos);
+      }
+    }
+  );
+};
+
 export const getFix3d = (data: FixPoint) => {
   if (fix3ds[data.id]) {
     return fix3ds[data.id];
@@ -53,6 +150,17 @@ export const getFix3d = (data: FixPoint) => {
   if (!args.measure && !args.graph) {
     return;
   }
+  if (args.measure) {
+    let basePoint: BasePoint;
+    let baseId = data.baseId || basePointId;
+    if (
+      !baseId ||
+      !(basePoint = basePoints.value.find((item) => item.id === baseId))
+    ) {
+      return;
+    }
+    args.basePoint = basePoint.pos;
+  }
 
   const fix3d = sdk.scene.createFixPoint(args);
   if (drawstatus.value === DrawStatus.ing) {
@@ -71,6 +179,7 @@ export const getFix3d = (data: FixPoint) => {
     });
   }
   fix3ds[data.id] = fix3d;
+  fixJoinBase(data, fix3d);
 };
 
 export const quitMeasure = (data: FixPoint) => {
@@ -94,9 +203,16 @@ export const delFix3d = (data) => {
   const fix3d = fix3ds[data.id];
   if (fix3d) {
     fix3d.destroy();
-    const index = drawingFix3d.value.indexOf(fix3d);
+    let index = drawingFix3d.value.indexOf(fix3d);
     if (~index) {
       drawingFix3d.value.splice(index, 1);
     }
+    index = fixPoints.value.indexOf(data);
+    if (~index) {
+      fixPoints.value.splice(index, 1);
+    }
+    return true;
+  } else {
+    return false;
   }
 };

+ 1 - 0
src/views/scene/index.vue

@@ -135,6 +135,7 @@ import { roadPhotos } from "@/store/roadPhotos";
 import { types, accidentPhotos } from "@/store/accidentPhotos";
 import { debounce, getQueryString } from "@/utils";
 import { tables } from "@/store/tables";
+import { goto } from "./menus/data";
 const layoutRef = ref(null);
 const activeMenuKeys = ref<string[]>([]);
 const accodentSortPhotos = computed(() => {

+ 89 - 49
src/views/scene/menus/actions.ts

@@ -7,7 +7,7 @@ import {
 import { list, MeasureAtom, MeasureType } from "@/store/measure";
 import { baseLines } from "@/store/baseLine";
 import { basePoints } from "@/store/basePoint";
-import { nextTick, Ref, watch } from "vue";
+import { nextTick, reactive, Ref, watch } from "vue";
 import {
   activeBasePointStack,
   activeFixPointStack,
@@ -21,6 +21,7 @@ import { FixPoint, fixPoints, FixType } from "@/store/fixPoint";
 import Message from "@/components/base/components/message/message.vue";
 import { getId } from "@/utils";
 import {
+  baseCheck,
   delFix3d,
   drawstatus,
   DrawStatus,
@@ -132,64 +133,103 @@ const menuActions = {
     };
   },
   [menuEnum.FIX_POINT]: (_, onComplete) => {
-    let hide = Message.success({ msg: "请单击选择固定点位置" });
-    const onDestroy = trackPosMenuAction(
-      () => {
-        hide && hide();
+    const add = () => {
+      hide = Message.success({ msg: "请单击选择固定点位置" });
+      onDestroy = trackPosMenuAction(
+        () => {
+          hide && hide();
+          onComplete();
+        },
+        (pos) => {
+          const len = fixPoints.value.push({
+            id: getId(),
+            pos,
+            text: "固定点",
+            type: FixType.POINT,
+            measure: measureMode.value,
+            lines: undefined,
+          });
+          activeFixPointStack.current.value.value = fixPoints.value[
+            len - 1
+          ] as FixPoint;
+          if (hide) {
+            hide();
+            hide = null;
+          }
+        },
+        false
+      );
+    };
+
+    let onDestroy;
+    let hide;
+    let stop;
+    const result = baseCheck();
+    if (typeof result === "boolean") {
+      if (result) {
+        add();
+      } else {
         onComplete();
-      },
-      (pos) => {
-        const len = fixPoints.value.push({
-          id: getId(),
-          pos,
-          text: "固定点",
-          type: FixType.POINT,
-          measure: measureMode.value,
-          lines: undefined,
-        });
-        activeFixPointStack.current.value.value = fixPoints.value[
-          len - 1
-        ] as FixPoint;
-        if (hide) {
-          hide();
-          hide = null;
-        }
-      },
-      false
-    );
+      }
+    } else {
+      stop = result.stop;
+      result.promise.then(() => {
+        add();
+      });
+    }
     return () => {
-      onDestroy();
+      console.log("?????");
+      onDestroy && onDestroy();
       hide && hide();
+      stop && stop();
     };
   },
   [menuEnum.FIX_GRANH]: (_, onComplete) => {
-    let hide = Message.success({ msg: "请单击绘制固定点形状" });
-    const data: FixPoint = {
-      id: getId(),
-      pos: { x: 0, y: 0, z: 0 },
-      text: "形状",
-      type: FixType.GRAPH,
-      measure: measureMode.value,
-      lines: undefined,
+    let hide;
+    const add = () => {
+      hide = Message.success({ msg: "请单击绘制固定点形状" });
+      const data: FixPoint = reactive({
+        id: getId(),
+        pos: { x: 0, y: 0, z: 0 },
+        text: "形状",
+        type: FixType.GRAPH,
+        measure: measureMode.value,
+        lines: undefined,
+      });
+      drawstatus.value = DrawStatus.ing;
+      getFix3d(data).bus.on("graphDrawComplete", (complete) => {
+        if (complete) {
+          const len = fixPoints.value.push(data);
+          activeFixPointStack.current.value.value = fixPoints.value[
+            len - 1
+          ] as FixPoint;
+        }
+        if (hide) {
+          hide();
+          hide = null;
+        }
+        onComplete();
+      });
     };
-    drawstatus.value = DrawStatus.ing;
-    getFix3d(data).bus.on("graphDrawComplete", (complete) => {
-      if (complete) {
-        const len = fixPoints.value.push(data);
-        activeFixPointStack.current.value.value = fixPoints.value[
-          len - 1
-        ] as FixPoint;
-      }
-      if (hide) {
-        hide();
-        hide = null;
-      }
-      onComplete();
-    });
 
+    let stop;
+    const result = baseCheck();
+    if (typeof result === "boolean") {
+      if (result) {
+        add();
+      } else {
+        onComplete();
+      }
+    } else {
+      stop = result.stop;
+      result.promise.then(() => {
+        add();
+      });
+    }
     return () => {
       drawstatus.value = DrawStatus.quit;
       hide && hide();
+      stop && stop();
     };
   },
   // [menuEnum.FIX_MEASURE]: (_, onComplete) => {
@@ -263,7 +303,7 @@ const menuActions = {
 export const joinActions = (activeKey: Ref<string>) => {
   return watch(
     () => activeKey.value,
-    (key, oldKey, onCleanup) => {
+    async (key, oldKey, onCleanup) => {
       if (key && menuActions[key]) {
         const menu = findMenuByKey(key as any);
         const cleanup = menuActions[key](menu, () => {

+ 45 - 0
src/views/scene/menus/data.ts

@@ -0,0 +1,45 @@
+import { MenuRaw, generateMixMenus } from "./menus";
+
+const stores = [];
+export const createStore = (data: MenuRaw[]) => {
+  const store = generateMixMenus("children", (m) => m, data);
+  stores.push(store);
+  return {
+    store,
+    destroy() {
+      let index = stores.indexOf(store);
+      if (~index) {
+        stores.splice(index, 1);
+      }
+    },
+  };
+};
+
+export const goto = (local: string[], localStores = stores) => {
+  for (let i = 0; i < localStores.length; i++) {
+    const store = localStores[i];
+    for (const menu of store.menus) {
+      if (menu.key === local[0]) {
+        store.child.value = null;
+        store.child.itemActiveKey = null;
+        setTimeout(() => {
+          menu.onClick();
+
+          if (
+            "defaultSelect" in menu &&
+            (menu.defaultSelect || menu.defaultSelect())
+          ) {
+            setTimeout(() => {
+              menu.onClick();
+            });
+          }
+
+          if (local.length > 1) {
+            setTimeout(() => goto(local.slice(1)), 10);
+          }
+        });
+        return;
+      }
+    }
+  }
+};

+ 5 - 3
src/views/scene/menus/pane.vue

@@ -23,8 +23,8 @@ import ActionMenus from "@/components/group-button/index.vue";
 import { generateMixMenus, MenuRaw, menus, findMenuByKey } from "./menus";
 import { joinActions } from "./actions";
 import { computed, onMounted, onUnmounted, ref, watchEffect } from "vue";
-import { disabledMap, laserModeStack } from "@/hook";
-import { Mode } from "@/sdk";
+import { disabledMap } from "@/hook";
+import { createStore } from "./data";
 
 const props = withDefaults(
   defineProps<{ menus?: MenuRaw[]; level?: number; parentKey?: string }>(),
@@ -45,9 +45,11 @@ const backMenu = {
 };
 
 const menusMix = computed(() => (props.level === 1 ? menus : [backMenu, ...props.menus]));
-const store = generateMixMenus("children", (m) => m, menusMix.value);
+const { store, destroy } = createStore(menusMix.value);
 const childActive = ref<string[]>([]);
 
+onUnmounted(destroy);
+
 watchEffect(() => {
   const currentActive = store.activeMenuKey.value || store.itemActiveKey.value;
   if (currentActive) {

+ 54 - 33
src/views/scene/photo.vue

@@ -1,7 +1,7 @@
 <template>
   <img :src="tempPhoto" class="face-animation" v-if="tempPhoto" ref="coverRef" />
   <div class="photo-layout" v-if="disabledMap.photo">
-    <ButtonPane class="photo-btn fun-ctrl" :size="size" @click="photo">
+    <ButtonPane class="photo-btn fun-ctrl" :size="size" @click="photo" box-shadow>
       <ui-icon type="photo" class="icon" :size="size / 2" />
     </ButtonPane>
 
@@ -23,7 +23,7 @@
 import UiIcon from "@/components/base/components/icon/index.vue";
 import ButtonPane from "@/components/button-pane/index.vue";
 import { list } from "@/store/measure";
-import { fixPoints } from "@/store/fixPoint";
+import { FixType, GFixPoint, fixPoints } from "@/store/fixPoint";
 import { baseLines } from "@/store/baseLine";
 import { basePoints } from "@/store/basePoint";
 import { photos } from "@/store/photos";
@@ -35,7 +35,7 @@ import { base64ToBlob, formatDate, getId } from "@/utils";
 import { computed, nextTick, ref, watchEffect } from "vue";
 import { api, downloadImage, uploadImage } from "@/store/sync";
 import { router, writeRouteName } from "@/router";
-import { LaserSDK, Pos, Pos3D } from "@/sdk";
+import { LaserSDK, Pos, Pos3D, TypeEmu } from "@/sdk";
 import { useStaticUrl } from "@/hook/useStaticUrl";
 import { Loading } from "@kankan/components/index";
 import { generateMixMenus, MenuRaw, menus, findMenuByKey } from "./menus/menus";
@@ -120,40 +120,61 @@ const photo = async () => {
   tempPhoto.value = await api.getFile(data.rawUrl);
   console.log("获取到临时文件");
   await nextTick();
+  return new Promise((resolve, reject) => {
+    const handler = async () => {
+      coverRef.value.removeEventListener("animationend", handler);
+      tempPhoto.value = null;
 
-  const handler = async () => {
-    coverRef.value.removeEventListener("animationend", handler);
-    tempPhoto.value = null;
-    const photoData = {
-      id: getId(),
-      url: data.url,
-      urlRaw: data.rawUrl,
-      time: new Date().getTime(),
-      meterPerPixel: data.meterPerPixel,
-      measures: list.value
-        .map((data) => {
-          const pos = getCurrentScreens(data.points);
-          if (pos.length) {
-            return { pos, dis: sdk.carry.measureMap.get(data).getDistance().value };
-          } else {
-            return null;
-          }
+      const fixMeasures = fixPoints.value
+        .filter((fix) => fix.measure && fix.lines)
+        .map((fix) => {
+          return fix.lines.reduce(
+            (t, line) => t.concat({ dis: line.dis, pos: getCurrentScreens(line.points) }),
+            [] as { pos: Pos[]; dis: number }[]
+          );
         })
-        .filter((poss) => poss?.pos.length === 2),
-      baseLines: baseLines.value
-        .map((data) => getCurrentScreens(data.points))
-        .filter((poss) => poss.length === 2),
-      fixPoints: fixPoints.value
-        .map((data) => ({ text: data.text, pos: getCurrentScreen(data.pos) }))
-        .filter((data) => !!data.pos),
-      basePoints: getCurrentScreens(basePoints.value.map((data) => data.pos)),
+        .flat();
+      const fixGraph = fixPoints.value
+        .filter((fix) => "type" in fix && fix.type === FixType.GRAPH)
+        .map((fix) => getCurrentScreens((fix as GFixPoint).points))
+        .filter((points) => points.length > 1);
+
+      const photoData = {
+        id: getId(),
+        url: data.url,
+        urlRaw: data.rawUrl,
+        time: new Date().getTime(),
+        meterPerPixel: data.meterPerPixel,
+        measures: list.value
+          .map((data) => {
+            const pos = getCurrentScreens(data.points);
+            if (pos.length) {
+              return { pos, dis: sdk.carry.measureMap.get(data).getDistance().value };
+            } else {
+              return null;
+            }
+          })
+          .concat(fixMeasures)
+          .filter((poss) => poss?.pos.length === 2),
+        fixGraph,
+        baseLines: baseLines.value
+          .map((data) => getCurrentScreens(data.points))
+          .filter((poss) => poss.length === 2),
+        fixPoints: fixPoints.value
+          .map((data) => ({ text: data.text, pos: getCurrentScreen(data.pos) }))
+          .filter((data) => !!data.pos),
+        basePoints: getCurrentScreens(basePoints.value.map((data) => data.pos)),
+      };
+      console.log(photoData);
+      photos.value.push(photoData);
+      Loading.hide();
+      resolve(photoData);
     };
-    console.log(photoData);
-    photos.value.push(photoData);
-    Loading.hide();
-  };
-  coverRef.value.addEventListener("animationend", handler);
+    coverRef.value.addEventListener("animationend", handler);
+  });
 };
+
+(window as any).photo = photo;
 </script>
 
 <style scoped lang="scss">