Переглянути джерело

Merge branch 'dev' into prod

bill 1 рік тому
батько
коміт
c72a48baac

+ 1 - 0
package.json

@@ -19,6 +19,7 @@
     "konva": "9.3.6",
     "mitt": "^3.0.1",
     "ol": "^9.1.0",
+    "piexifjs": "^1.0.6",
     "pinia": "^2.1.7",
     "proj4": "^2.11.0",
     "qrcode": "^1.5.3",

+ 6 - 0
pnpm-lock.yaml

@@ -13,6 +13,7 @@ specifiers:
   konva: 9.3.6
   mitt: ^3.0.1
   ol: ^9.1.0
+  piexifjs: ^1.0.6
   pinia: ^2.1.7
   proj4: ^2.11.0
   qrcode: ^1.5.3
@@ -35,6 +36,7 @@ dependencies:
   konva: 9.3.6
   mitt: 3.0.1
   ol: 9.2.4
+  piexifjs: 1.0.6
   pinia: 2.1.7_lku3umiefploqzvdryeqiyorrq
   proj4: 2.11.0
   qrcode: 1.5.3
@@ -1234,6 +1236,10 @@ packages:
     engines: {node: '>=8.6'}
     dev: true
 
+  /piexifjs/1.0.6:
+    resolution: {integrity: sha512-0wVyH0cKohzBQ5Gi2V1BuxYpxWfxF3cSqfFXfPIpl5tl9XLS5z4ogqhUCD20AbHi0h9aJkqXNJnkVev6gwh2ag==}
+    dev: false
+
   /pinia/2.1.7_lku3umiefploqzvdryeqiyorrq:
     resolution: {integrity: sha512-+C2AHFtcFqjPih0zpYuvof37SFxMQ7OEG2zV9jRI12i9BOy3YQVAHwdKtyyc8pDcDyIc33WCIsZaCFWU7WWxGQ==}
     peerDependencies:

+ 100 - 0
src/components/point-input.vue

@@ -0,0 +1,100 @@
+<template>
+  <el-dialog
+    :model-value="visible"
+    @update:model-value="(val) => emit('update:visible', val)"
+    title="测点信息"
+    width="500"
+  >
+    <el-form label-width="auto">
+      <el-form-item label="坐标" v-if="coordInfo">
+        <el-input :value="coordInfo" readonly type="textarea" rows="3" disabled />
+      </el-form-item>
+
+      <el-form-item label="测点类型" required>
+        <el-select v-model="ivalue.type" placeholder="测点类型">
+          <el-option :label="type" :value="type" v-for="type in typeOptions" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="测点说明" required>
+        <el-input
+          v-model.trim="ivalue.name"
+          :maxlength="100"
+          rows="4"
+          show-word-limit
+          placeholder="请输入"
+          type="textarea"
+        />
+      </el-form-item>
+      <el-form-item label="备注">
+        <el-input
+          v-model.trim="ivalue.remark"
+          :maxlength="100"
+          show-word-limit
+          placeholder="请输入"
+        />
+      </el-form-item>
+    </el-form>
+
+    <template #footer>
+      <div class="dialog-footer">
+        <el-button @click="emit('update:visible', false)">取消</el-button>
+        <el-button type="primary" @click="submit"> 确定 </el-button>
+      </div>
+    </template>
+  </el-dialog>
+</template>
+
+<script setup lang="ts">
+import { ElMessage } from "element-plus";
+import { ref, watchEffect, computed, watch } from "vue";
+import { ScenePoint } from "@/store/scene";
+import { PointTypeEnum } from "drawing-board";
+import { toDegrees } from "@/util";
+
+const props = defineProps<{
+  visible: boolean;
+  value: ScenePoint;
+  updateValue: (value: ScenePoint) => void;
+}>();
+
+const typeOptions = [
+  PointTypeEnum.border,
+  PointTypeEnum.center,
+  PointTypeEnum.marker,
+  PointTypeEnum.other,
+];
+
+const coordInfo = computed(() => {
+  const point = ivalue.value.pos;
+  if (!(!point || point.length === 0 || point.some((i) => !i))) {
+    return `经度:${toDegrees(ivalue.value.pos[0])}
+纬度:${toDegrees(ivalue.value.pos[1])}
+高程:${ivalue.value.pos[2]}`;
+  }
+});
+
+const emit = defineEmits<{
+  (e: "update:visible", visible: boolean): void;
+}>();
+
+const ivalue = ref<ScenePoint>();
+watchEffect(() => {
+  ivalue.value = { ...props.value, name: props.value.name || "" };
+});
+
+watch(
+  () => props.value?.type,
+  (type) => {
+    ivalue.value.type = type || PointTypeEnum.other;
+  },
+  { immediate: true }
+);
+
+const submit = async () => {
+  if (ivalue.value.name.trim().length === 0) {
+    return ElMessage.error(`测点说明不能为空!`);
+  }
+  await props.updateValue(ivalue.value);
+  emit("update:visible", false);
+};
+</script>

Різницю між файлами не показано, бо вона завелика
+ 29 - 5
src/lib/board/4dmap.d.ts


Різницю між файлами не показано, бо вона завелика
+ 1259 - 1167
src/lib/board/4dmap.js


Різницю між файлами не показано, бо вона завелика
+ 6 - 6
src/lib/board/4dmap.umd.cjs


+ 20 - 31
src/request/drawing.ts

@@ -1,40 +1,29 @@
-import { sendFetch, PageProps } from './index'
+import { PolygonsAttrib } from "drawing-board";
+import { sendFetch, PageProps } from "./index";
 import * as URL from "./URL";
-import {
 
-    PolygonsAttrib,
-} from "./type";
-
-// 
+//
 export type PolyDataType = {
-    id: string
-    lineIds: string[]
-    name?: string
-
-}
-
-export interface DrawingDataType extends PolygonsAttrib {
-    id?: string;
-    polygons: PolyDataType[],
-}
+  id: string;
+  lineIds: string[];
+  name?: string;
+};
 
 export type DrawingParamsType = {
-    data: DrawingDataType,
-    relicsId: string
-    drawingId?: string
-}
+  data: PolygonsAttrib;
+  relicsId: string;
+  drawingId?: string;
+};
 
 export const addOrUpdateDrawingFetch = (params: Partial<DrawingParamsType>) =>
-    sendFetch<PageProps<DrawingDataType>>(URL.addOrUpdateDrawing, {
-        method: "post",
-        body: JSON.stringify(params),
-    });
-
-
+  sendFetch<PageProps<PolygonsAttrib>>(URL.addOrUpdateDrawing, {
+    method: "post",
+    body: JSON.stringify(params),
+  });
 
 export const getDrawingDetailFetch = (drawingId: string) =>
-    sendFetch<PageProps<DrawingParamsType>>(
-        URL.getDrawingInfoByRelicsId,
-        { method: "post", body: JSON.stringify({}) },
-        { paths: { drawingId: drawingId } }
-    );
+  sendFetch<PageProps<DrawingParamsType>>(
+    URL.getDrawingInfoByRelicsId,
+    { method: "post", body: JSON.stringify({}) },
+    { paths: { drawingId: drawingId } }
+  );

+ 24 - 14
src/request/index.ts

@@ -23,7 +23,12 @@ import {
 
 const error = throttle((msg: string) => ElMessage.error(msg), 2000);
 
-type Other = { params?: Param; paths?: Param; useResult?: boolean, noToken?: boolean };
+type Other = {
+  params?: Param;
+  paths?: Param;
+  useResult?: boolean;
+  noToken?: boolean;
+};
 export const sendFetch = <T>(
   url: string,
   init: RequestInit,
@@ -42,7 +47,7 @@ export const sendFetch = <T>(
         sendUrl + "?" + new URLSearchParams({ ...gParams, ...other.params });
     }
     if (other.noToken) {
-      delete gHeaders['relics-token']
+      delete gHeaders["relics-token"];
     }
   }
   lifeHook.forEach(({ start }) => start());
@@ -51,9 +56,9 @@ export const sendFetch = <T>(
     ...init,
     headers: headers
       ? {
-        ...headers,
-        ...gHeaders,
-      }
+          ...headers,
+          ...gHeaders,
+        }
       : gHeaders,
   })
     .then((res) => {
@@ -67,7 +72,7 @@ export const sendFetch = <T>(
     })
     .then((data) => {
       if (other && other.useResult) {
-        return data
+        return data;
       } else {
         if (data.code !== 0) {
           error(data.message);
@@ -92,12 +97,11 @@ export const loginFetch = (props: LoginProps) =>
     body: JSON.stringify(props),
   });
 
-  export const loginOutFetch = () =>
-    sendFetch<{ user: UserInfo; token: string }>(URL.logout, {
-      method: "post",
-      body: JSON.stringify({}),
-    });
-  
+export const loginOutFetch = () =>
+  sendFetch<{ user: UserInfo; token: string }>(URL.logout, {
+    method: "post",
+    body: JSON.stringify({}),
+  });
 
 export const userInfoFetch = () =>
   sendFetch<UserInfo>(URL.getUserInfo, { method: "post" });
@@ -187,10 +191,16 @@ export const delRelicsScenesFetch = (
     { method: "post", body: JSON.stringify(scenes) },
     { paths: { relicsId } }
   );
-export const updateRelicsScenePosNameFetch = (posId: number, name: string) =>
+
+export const updateRelicsScenePosNameFetch = (point: ScenePoint) =>
   sendFetch(URL.updateRelicsScenePosName, {
     method: "post",
-    body: JSON.stringify({ id: posId, name }),
+    body: JSON.stringify({
+      id: point.id,
+      name: point.name,
+      type: point.type,
+      remark: point.remark,
+    }),
   });
 
 export const relicsScenePosInfoFetch = (posId: number) =>

+ 3 - 17
src/request/type.ts

@@ -5,11 +5,7 @@ import {
   creationMethodDesc,
 } from "@/store/relics";
 import { SceneStatus } from "@/store/scene";
-import {
-  WholeLineLineAttrib,
-  WholeLinePointAttrib,
-  WholeLinePolygonAttrib,
-} from "drawing-board";
+import { PointTypeEnum } from "drawing-board";
 
 type UserInfoRoles = {
   roleId: number;
@@ -53,6 +49,7 @@ export type ResResult = {
   timestamp: string;
 };
 export type ScenePoint = {
+  type: PointTypeEnum;
   tbStatus: number;
   createTime: string;
   updateTime: string;
@@ -61,6 +58,7 @@ export type ScenePoint = {
   id: number;
   uuid: number;
   name: string;
+  remark: string;
   pos: [number, number, number] | [];
   location: [number, number, number];
   centerLocation: [number, number, number];
@@ -154,15 +152,3 @@ export type Device = {
   userId: 2;
   userName: string;
 };
-
-export type PolygonsPointAttrib = WholeLinePointAttrib & {
-  rtk: boolean;
-  title: string;
-};
-export type PolygonsLineAttrib = WholeLineLineAttrib;
-
-export type PolygonsAttrib = {
-  lines: PolygonsLineAttrib[];
-  polygons: WholeLinePolygonAttrib[];
-  points: PolygonsPointAttrib[];
-};

+ 6 - 11
src/store/polygons.ts

@@ -1,16 +1,11 @@
-import {
-  WholeLineLineAttrib,
-  WholeLinePointAttrib,
-  WholeLinePolygonAttrib,
-} from "drawing-board";
+import { PolygonsAttrib } from "drawing-board";
 import { ref } from "vue";
 
-export type Polygons = {
-  id: string;
-  lines: WholeLineLineAttrib[];
-  polygons: WholeLinePolygonAttrib[];
-  points: (WholeLinePointAttrib & { rtk: boolean })[];
-};
+export type Polygons = PolygonsAttrib;
+export type {
+  PolygonsLineAttrib as LineAttrib,
+  PolygonsPointAttrib as PontAttrib,
+} from "drawing-board";
 
 export const polygons = ref<Polygons>({
   id: "0",

+ 17 - 5
src/store/scene.ts

@@ -105,11 +105,8 @@ export const refreshScenes = async () => {
   await refreshBoardData();
 };
 
-export const updateScenePointName = async (
-  point: ScenePoint,
-  newName: string
-) => {
-  await updateRelicsScenePosNameFetch(point.id, newName);
+export const updateScenePointName = async (point: ScenePoint) => {
+  await updateRelicsScenePosNameFetch(point);
   relicsId.value && (await refreshScenes());
 };
 
@@ -188,6 +185,7 @@ const scenePosTransform = (scenes: Scene[]) => {
       points.push({
         x: pos.pos[0],
         y: pos.pos[1],
+        type: pos.type,
         title: pos.index
           ? pos.index + (pos.name ? "-" + pos.name : "")
           : pos.name,
@@ -225,6 +223,20 @@ watch(
         poyData.points[ndx] = { ...points[i] };
       }
     }
+
+    poyData.lines = poyData.lines.filter(
+      (p) =>
+        !p.pointIds.some(
+          (id) => !poyData.points.some((point) => point.id === id)
+        )
+    );
+
+    poyData.polygons.forEach((p) => {
+      p.lineIds = p.lineIds.filter((lid) =>
+        poyData.lines.some((l) => l.id === lid)
+      );
+    });
+    console.log(poyData);
   },
   { immediate: true, flush: "sync" }
 );

+ 74 - 0
src/util/image-exif.ts

@@ -0,0 +1,74 @@
+import * as piexif from "piexifjs";
+
+// 读取图片的EXIF信息
+export function readExif(file: Blob) {
+  return new Promise((resolve, reject) => {
+    const reader = new FileReader();
+    reader.onload = (e) => {
+      const exif = piexif.load(e.target.result);
+      console.log(exif);
+      resolve(exif);
+    };
+    reader.onerror = reject;
+    reader.readAsDataURL(file);
+  });
+}
+
+function convertToDMS(value: number) {
+  const degrees = Math.floor(value);
+  const minutes = Math.floor((value - degrees) * 60);
+  const seconds = (value - degrees - minutes / 60) * 3600;
+  return [degrees, minutes, seconds];
+}
+
+function createGPSIFD(lat: number, lon: number, alt: number) {
+  const latDMS = convertToDMS(Math.abs(lat));
+  const lonDMS = convertToDMS(Math.abs(lon));
+
+  const gpsIFD = {
+    [piexif.GPSIFD.GPSVersionID]: [2, 3, 0, 0],
+    [piexif.GPSIFD.GPSLatitudeRef]: lat >= 0 ? "N" : "S",
+    [piexif.GPSIFD.GPSLatitude]: [
+      [latDMS[0], 1],
+      [latDMS[1], 1],
+      [latDMS[2] * 100, 100],
+    ],
+    [piexif.GPSIFD.GPSLongitudeRef]: lon >= 0 ? "E" : "W",
+    [piexif.GPSIFD.GPSLongitude]: [
+      [lonDMS[0], 1],
+      [lonDMS[1], 1],
+      [lonDMS[2] * 100, 100],
+    ],
+    [piexif.GPSIFD.GPSAltitudeRef]: alt >= 0 ? 0 : 1,
+    [piexif.GPSIFD.GPSAltitude]: [Math.abs(alt), 1],
+  };
+  return gpsIFD;
+}
+
+export const attachImageCoord = (blob: Blob, latlngalt: number[]) => {
+  const reader = new FileReader();
+
+  const promise = new Promise<Blob>((resolve) => {
+    reader.onload = function (event) {
+      const exifObj = piexif.load(event.target.result);
+      const gpsIFD = createGPSIFD(latlngalt[0], latlngalt[1], latlngalt[2]);
+      exifObj["GPS"] = gpsIFD;
+
+      const exifBytes = piexif.dump(exifObj);
+      const newImageData = piexif.insert(exifBytes, event.target.result);
+
+      const base64Data = newImageData.split(",")[1];
+      const byteCharacters = atob(base64Data);
+      const byteNumbers = new Array(byteCharacters.length);
+      for (let i = 0; i < byteCharacters.length; i++) {
+        byteNumbers[i] = byteCharacters.charCodeAt(i);
+      }
+      const byteArray = new Uint8Array(byteNumbers);
+      const blob = new Blob([byteArray], { type: "image/jpeg" });
+      resolve(blob);
+    };
+  });
+  reader.readAsDataURL(blob);
+
+  return promise;
+};

+ 25 - 11
src/util/pc4xlsl.ts

@@ -1,3 +1,4 @@
+import { PointTypeEnum } from "@/lib/board/4dmap";
 import { round, toDegrees } from "./";
 import { saveAs } from "./file-serve";
 import * as URL from "@/request/URL";
@@ -54,25 +55,35 @@ export const downloadPointsXLSL1 = async (
 
 export const downloadPointsXLSL2 = async (
   points: number[][],
-  desc: { title: string; desc: string }[] = [],
-  name: string
+  desc: { title: string; desc: string; type: string }[] = [],
+  name: string,
+  version: string
 ) => {
   const tabs = points.map((point, i) => {
-    const des = desc[i] || { title: "无", desc: "无" };
+    const des = desc[i] || {
+      title: "无",
+      desc: "无",
+      type: "其他",
+      remark: "无",
+    };
     return {
       latitude: toDegrees(point[1], 4),
       longitude: toDegrees(point[0], 4),
       altitude: round(point[2], 4),
       description: des.title,
       remark: des.desc,
+      type: des.type,
     };
   });
 
-  const data = await fetch(basePath + URL.exportCoordinateData, {
-    headers: gHeaders,
-    method: "post",
-    body: JSON.stringify(tabs),
-  }).then((res) => res.blob());
+  const data = await fetch(
+    basePath + URL.exportCoordinateData + "/" + version,
+    {
+      headers: gHeaders,
+      method: "post",
+      body: JSON.stringify(tabs),
+    }
+  ).then((res) => res.blob());
 
   return saveAs(data, `${name}.xls`);
 };
@@ -83,7 +94,10 @@ export const downloadPointsXLSL = async (
   name: string
 ) => {
   downloadPointsXLSL1(points, desc, name);
-  downloadPointsXLSL2(points, desc, name + "本体边界坐标");
+  downloadPointsXLSL2(
+    points,
+    desc.map((t) => ({ ...t, type: PointTypeEnum.other })),
+    name + "本体边界坐标",
+    "V1"
+  );
 };
-
-

+ 54 - 16
src/view/map/coord.vue

@@ -65,7 +65,14 @@
                     {{ node.label }}
                   </span>
                   <span :class="{ disable: data.disable }" class="name">
-                    {{ data.raw.name }}
+                    <span
+                      class="color"
+                      :style="{
+                        backgroundColor:
+                          pointColorMap[data.raw.type || PointTypeEnum.other],
+                      }"
+                    ></span>
+                    {{ data.raw.name }} &nbsp;
                   </span>
                 </div>
               </el-tooltip>
@@ -110,14 +117,22 @@
       </div>
     </div>
 
-    <template v-if="!queryMode">
+    <template v-if="!queryMode && treeNode.length">
       <el-button
         type="primary"
         :icon="Download"
         style="width: 100%"
-        @click="exportFile(getSelectPoints(), 2, relics?.name)"
+        @click="exportFile(getSelectPoints(), 2, relics?.name, 'V2')"
       >
-        导出本体边界坐标
+        导出本体边界坐标(V1.4模板)
+      </el-button>
+      <el-button
+        type="primary"
+        :icon="Download"
+        style="width: 100%; margin-top: 20px; margin-left: 0"
+        @click="exportFile(getSelectPoints(), 2, relics?.name, 'V1')"
+      >
+        导出本体边界坐标(V1.2模板)
       </el-button>
 
       <el-button
@@ -127,20 +142,16 @@
         @click="exportImage(getSelectPoints(), relics?.name)"
       >
         下载全景图
-        {{ inputPoint?.name }}
       </el-button>
     </template>
   </div>
 
   <SingleInput
-    :key="inputPoint?.id"
+    v-if="inputPoint"
     :visible="!!inputPoint"
     @update:visible="inputPoint = null"
-    :value="inputPoint?.name || ''"
+    :value="inputPoint"
     :update-value="updatePointName"
-    is-allow-empty
-    title="测点说明"
-    placeholder="请填写测点说明"
   />
 </template>
 
@@ -167,7 +178,7 @@ import {
   scenePoints,
 } from "@/store/scene";
 import { relics } from "@/store/relics";
-import SingleInput from "@/components/single-input.vue";
+import SingleInput from "@/components/point-input.vue";
 import { selectScenes } from "../quisk";
 import { addRelicsScenesFetch, delRelicsScenesFetch } from "@/request";
 import { exportFile, exportImage } from "./pc4Helper";
@@ -181,25 +192,41 @@ import {
   PolygonsPointAttrib,
   getWholeLineLinesByPointId,
   getWholeLinePoint,
+  pointColorMap,
+  PointTypeEnum,
 } from "drawing-board";
 import { flyScene, gotoPointPage, mapManage } from "./install";
 import { board } from "./install";
+// import { attachImageCoord, readExif } from "@/util/image-exif";
+// import { saveAs } from "@/util/file-serve";
+
+// const changfile = async (ev) => {
+//   readExif(ev.target.files[0]);
+//   const blob = await attachImageCoord(ev.target.files[0], [
+//     127.101412416667,
+//     37.338276944444,
+//     5,
+//   ]);
+//   saveAs(blob);
+// };
 
 const inputPoint = ref<ScenePoint | null>(null);
-const updatePointName = async (title: string) => {
+const updatePointName = async (scenePoint: ScenePoint) => {
   const point = getWholeLinePoint(
     boardData.value,
     inputPoint.value.id.toString()
   ) as PolygonsPointAttrib;
+
   await Promise.all([
     boardDataChange(() => {
       if (point) {
-        point.title = inputPoint.value.index
-          ? inputPoint.value.index + "-" + title
-          : title;
+        point.title = scenePoint.index
+          ? scenePoint.index + "-" + scenePoint.name
+          : scenePoint.name;
+        point.type = scenePoint.type;
       }
     }),
-    updateScenePointName(inputPoint.value!, title),
+    updateScenePointName(scenePoint),
   ]);
 };
 
@@ -323,6 +350,9 @@ onBeforeUnmount(() => {
   board.polygon.bus.off("clickPoint", pointClickHandler);
   board.polygon.container.stage.off("click.checkPointSelect");
   board.polygon.status.lightPointId = null;
+
+  // treeRef.value.setCheckedNodes([]);
+  board.polygon.status.selectPoiIds = [];
 });
 </script>
 
@@ -382,6 +412,14 @@ onBeforeUnmount(() => {
       text-overflow: ellipsis; //文本溢出显示省略号
       overflow: hidden;
       white-space: nowrap; //文本不会换行
+
+      .color {
+        display: inline-block;
+        width: 8px;
+        height: 8px;
+        margin-right: 8px;
+        border-radius: 4px;
+      }
     }
   }
 

+ 1 - 2
src/view/map/install.ts

@@ -65,9 +65,8 @@ watch(
 export const board = createBoard({ map: mapManage.map });
 watch(
   boardData,
-  (data, oldData) => {
+  (data) => {
     data && board.setData(data);
-    console.log(data, data === oldData);
   },
   {
     immediate: true,

+ 20 - 11
src/view/map/layout.vue

@@ -51,19 +51,13 @@
             </el-select>
           </div>
         </div>
-        <div class="map-bottom-out-pano" v-if="!isCoordPage">
+        <div class="map-bottom-out-pano">
           <div class="point-info">
-            <div>
-              <el-icon size="20" color="rgb(230, 162, 60)">
+            <div v-for="type in typeOptions">
+              <el-icon size="20" :color="pointColorMap[type]">
                 <locationIcon />
               </el-icon>
-              <p>RTK点位</p>
-            </div>
-            <div>
-              <el-icon size="20" color="rgba(64, 158, 255)">
-                <locationIcon />
-              </el-icon>
-              <p>地图选点</p>
+              <p>{{ type }}</p>
             </div>
           </div>
         </div>
@@ -95,10 +89,24 @@ import {
 import { computed, ref, watch } from "vue";
 import { initSelfRelics, relics } from "@/store/relics";
 import { queryMode } from "./install";
-import { PoPoint } from "drawing-board";
+import { PointTypeEnum, pointColorMap, PoPoint } from "drawing-board";
 import { boardData, scenePoints } from "@/store/scene";
 import saveAs from "@/util/file-serve";
 
+const typeOptions = computed(() => {
+  const options = [
+    PointTypeEnum.border,
+    PointTypeEnum.center,
+    PointTypeEnum.marker,
+    PointTypeEnum.other,
+  ];
+
+  if (!isCoordPage.value) {
+    options.push(PointTypeEnum.mapSelect);
+  }
+  return options;
+});
+
 const menus = [
   {
     icon: locationIcon,
@@ -177,6 +185,7 @@ const capture = async () => {
   await new Promise((resolve) => setTimeout(resolve, 300));
   try {
     const dataURL = await board.toDataURL(2);
+
     await saveAs(dataURL, `${relics.value.name}-位置图.jpg`);
   } finally {
     captureing.value = false;

+ 15 - 4
src/view/map/pc4Helper.ts

@@ -10,11 +10,13 @@ import {
   downloadPointsXLSL2,
 } from "@/util/pc4xlsl";
 import { noValidPoint } from "./install";
+import { PointTypeEnum } from "@/lib/board/4dmap";
 
 export const exportFile = async (
   points: ScenePoint[],
   type: number,
-  name: string = ""
+  name: string = "",
+  version = "v1"
 ) => {
   if (!points.length) {
     ElMessage.error("请选择要导出的点位");
@@ -31,14 +33,23 @@ export const exportFile = async (
   if (type === 1) {
     await downloadPointsXLSL1(
       points.map((point) => point.pos),
-      points.map((point) => ({ title: point.name, desc: point.name })),
+      points.map((point) => ({
+        title: point.name,
+        desc: point.remark || "无",
+        type: point.type || PointTypeEnum.other,
+      })),
       name + "绘制矢量数据"
     );
   } else if (type === 2) {
     await downloadPointsXLSL2(
       points.map((point) => point.pos),
-      points.map((point) => ({ title: point.name, desc: "无" })),
-      name + "本体边界坐标"
+      points.map((point) => ({
+        title: point.name,
+        desc: point.remark || "无",
+        type: point.type || PointTypeEnum.other,
+      })),
+      name + "本体边界坐标",
+      version
     );
   } else {
     await downloadPointsXLSL(

+ 3 - 6
src/view/pano/pano.vue

@@ -32,17 +32,14 @@
   <SingleInput
     v-if="point"
     :visible="update"
-    isAllowEmpty
     @update:visible="update = false"
-    :value="point.name || ''"
-    :update-value="tex => updateScenePointName(point!, tex)"
-    title="测点说明"
-    placeholder="请填写测点说明"
+    :value="point"
+    :update-value="(npoint) => updateScenePointName(npoint)"
   />
 </template>
 
 <script setup lang="ts">
-import SingleInput from "@/components/single-input.vue";
+import SingleInput from "@/components/point-input.vue";
 import { router, setDocTitle } from "@/router";
 import { mergeFuns, round } from "@/util";
 import { computed, onMounted, onUnmounted, ref, watchEffect } from "vue";