浏览代码

Merge branch 'konva-zd' into staffNoFix

zhudie 2 年之前
父节点
当前提交
556922b463

+ 1 - 1
.env.development

@@ -1,5 +1,5 @@
 # 只在开发模式中被载入
-VITE_PORT = 8097
+VITE_PORT = 8092
 
 # 网站根目录
 VITE_PUBLIC_PATH = /skyeye-admin/

+ 1 - 1
package.json

@@ -50,7 +50,7 @@
     "element-resize-detector": "1.2.4",
     "fabric": "5.3.0",
     "flv.js": "1.6.2",
-    "html2canvas": "1.4.1",
+    "html2canvas": "1.0.0",
     "konva": "9.3.0",
     "lodash-es": "4.17.21",
     "mockjs": "1.1.0",

+ 10 - 23
pnpm-lock.yaml

@@ -63,8 +63,8 @@ dependencies:
     specifier: 1.6.2
     version: 1.6.2
   html2canvas:
-    specifier: 1.4.1
-    version: 1.4.1
+    specifier: 1.0.0
+    version: 1.0.0
   konva:
     specifier: 9.3.0
     version: 9.3.0
@@ -2387,8 +2387,8 @@ packages:
     resolution: {integrity: sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==}
     dev: true
 
-  /base64-arraybuffer@1.0.2:
-    resolution: {integrity: sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==}
+  /base64-arraybuffer@0.2.0:
+    resolution: {integrity: sha512-7emyCsu1/xiBXgQZrscw/8KPRT44I4Yq9Pe6EGs3aPRTsWuggML1/1DTuZUuIaJPIm1FTDUVXl4x/yW8s0kQDQ==}
     engines: {node: '>= 0.6.0'}
     dev: false
 
@@ -3084,10 +3084,10 @@ packages:
     engines: {node: '>=12.22'}
     dev: true
 
-  /css-line-break@2.1.0:
-    resolution: {integrity: sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==}
+  /css-line-break@1.1.1:
+    resolution: {integrity: sha512-1feNVaM4Fyzdj4mKPIQNL2n70MmuYzAXZ1aytlROFX1JsOo070OsugwGjj7nl6jnDJWHDM8zRZswkmeYVWZJQA==}
     dependencies:
-      utrie: 1.0.2
+      base64-arraybuffer: 0.2.0
     dev: false
 
   /css-select@4.3.0:
@@ -4861,12 +4861,11 @@ packages:
     resolution: {integrity: sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==}
     dev: false
 
-  /html2canvas@1.4.1:
-    resolution: {integrity: sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==}
+  /html2canvas@1.0.0:
+    resolution: {integrity: sha512-0d/f2Aj1Brn+EeNWkuRdtnT13qu1NdvxhBMvts3ssme7jgPU7dtuwnm1P6cXvXmnDdUUerH5XdhveWvuLfqkew==}
     engines: {node: '>=8.0.0'}
     dependencies:
-      css-line-break: 2.1.0
-      text-segmentation: 1.0.3
+      css-line-break: 1.1.1
     dev: false
 
   /htmlparser2@3.10.1:
@@ -7682,12 +7681,6 @@ packages:
     engines: {node: '>=0.10'}
     dev: true
 
-  /text-segmentation@1.0.3:
-    resolution: {integrity: sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==}
-    dependencies:
-      utrie: 1.0.2
-    dev: false
-
   /text-table@0.2.0:
     resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
     dev: true
@@ -8027,12 +8020,6 @@ packages:
     engines: {node: '>= 0.4.0'}
     dev: true
 
-  /utrie@1.0.2:
-    resolution: {integrity: sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==}
-    dependencies:
-      base64-arraybuffer: 1.0.2
-    dev: false
-
   /v8-compile-cache-lib@3.0.1:
     resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
     dev: true

文件差异内容过多而无法显示
+ 23 - 0
src/assets/1.svg


文件差异内容过多而无法显示
+ 16 - 0
src/assets/test/1-curv.svg


文件差异内容过多而无法显示
+ 20 - 0
src/assets/test/1-curv2.svg


文件差异内容过多而无法显示
+ 23 - 0
src/assets/test/1.svg


+ 23 - 0
src/assets/test/2-rect.svg

@@ -0,0 +1,23 @@
+<svg width="160" height="38" fill="currentColor" xmlns="http://www.w3.org/2000/svg"
+    xmlns:xlink="http://www.w3.org/1999/xlink">
+    <defs>
+        <linearGradient x1="100%" y1="51.673%" x2="0%" y2="48.327%" id="prefix__a">
+            <stop stop-color="currentColor" offset="0%" />
+            <stop stop-color="currentColor" stop-opacity=".5" offset="100%" />
+        </linearGradient>
+    </defs>
+    <g transform="translate(0 1)" fill="none" fill-rule="evenodd">
+        <g transform="translate(8.27 23.337)" fill-rule="nonzero">
+            <path stroke="currentColor" stroke-width=".5" d="M.664.476l3.984 2.857h80.56L89.191.476h52.674" />
+            <circle fill="currentColor" cx=".664" cy=".476" r="1" />
+            <path fill="currentColor" d="M102.471.476H92.069v1h10.402z" />
+            <path fill="currentColor" d="M85.207 3.333H4.647v1h80.56z" />
+        </g>
+        <path d="M13.426 14.448l-10.62 5.32V9.129l10.62 5.32z" stroke="currentColor" stroke-width=".5" />
+        <path fill="currentColor" d="M10.175 14.448l-6.349 3.18v-6.36z" />
+        <path d="M146.904 14.448l10.62 5.32V9.129l-10.62 5.32z" stroke="currentColor" stroke-width=".5" />
+        <path fill="currentColor" d="M150.155 14.448l6.349 3.18v-6.36z" />
+        <path d="M159.428.25v28.705H5.179L.25 24.36V2.315L3.428.25h156z" stroke-opacity=".498" stroke="#FFFFFF"
+            stroke-width=".5" fill-opacity=".7" fill="url(#prefix__a)" transform="translate(0 -.154)" />
+    </g>
+</svg>

文件差异内容过多而无法显示
+ 6 - 0
src/assets/test/2-shine.svg


文件差异内容过多而无法显示
+ 25 - 0
src/assets/test/2.svg


+ 1 - 0
src/main.ts

@@ -12,6 +12,7 @@ import router, { setupRouter } from './router';
 import { setupStore } from '@/store';
 import 'virtual:svg-icons-register';
 import { setupElement, setupDirectives, setupCustomComponents } from '@/plugins';
+// import VueKonva from 'vue-konva';
 
 async function bootstrap() {
   const app = createApp(App);

+ 8 - 8
src/views/page-config/ConfigEdit.vue

@@ -87,7 +87,7 @@
             class="camera-item flex justify-start items-center"
             :class="{
               isAdded: isAddedShop(item.id),
-              isActive: item.id === activeShop.id,
+              isActive: item.id === activeShopId,
             }"
             @click="handleAddShop(item)"
           >
@@ -97,7 +97,7 @@
       </div>
       <div ref="drawContainer" id="drawContainer" class="draw-container">
         <div id="shopEditContainer" v-moveable:1>
-          <MapContainer />
+          <MapContainer ref="mapContainerRef" />
         </div>
         <el-upload
           v-if="!hasBg"
@@ -131,9 +131,7 @@
       >
         <el-icon class="left-icon" size="16px"><ArrowLeftBold /></el-icon>
         <el-icon style="margin-top: 7px" size="16px"><ArrowLeftBold /></el-icon>
-        <!-- <el-icon class="left-icon"><DArrowLeft /></el-icon> -->
       </div>
-      <!-- <img src="~@/assets/icons/slide.png" alt="" class="dialog-btn" /> -->
     </el-tooltip>
 
     <ConfigDialog ref="configDrawer" @on-close="onClose" class="drawer-position" />
@@ -155,7 +153,7 @@
   import { onBeforeUnmount, onMounted, ref } from 'vue';
   import { WorkShopInfoItem } from '@/api/scene/scene';
   import { computed } from 'vue';
-  import { Search, Refresh } from '@element-plus/icons-vue';
+  import { Search, Refresh, ArrowLeftBold, ArrowLeft } from '@element-plus/icons-vue';
   import usePageConfig from './usePageConfig';
   import MapContainer from './component/mapContainer/MapContainer.vue';
   import useMapEditor, { LabelPositionEnum } from './stores/useMapEditor';
@@ -164,8 +162,8 @@
   import { useRouter } from 'vue-router';
 
   const mapEditor = useMapEditor();
-  const { bgImg, addedShops, activeShop } = storeToRefs(mapEditor);
-  const { addShop, addBg, toJson, resetMap, createMap, deleteShop } = mapEditor;
+  const { bgImg, addedShops, activeShopId } = storeToRefs(mapEditor);
+  const { addShop, addBg, calcLayout, resetMap, createMap, deleteShop } = mapEditor;
 
   const router = useRouter();
 
@@ -173,6 +171,7 @@
   const { selectedCompany, scenesInfos, label, labelList, shopList, layoutId } = pageConfig;
 
   const drawContainer = ref<HTMLDivElement>();
+  const mapContainerRef = ref();
 
   const searchKey = ref('');
   // 是否已有背景图
@@ -304,7 +303,8 @@
   };
 
   const handleSave = () => {
-    const layout = toJson();
+    const json = mapContainerRef.value?.getLayout();
+    const layout = calcLayout(json);
     const param = {
       layout,
       targetId: selectedCompany.value || 2,

文件差异内容过多而无法显示
+ 123 - 0
src/views/page-config/ConfigEdit2.vue


+ 2 - 3
src/views/page-config/component/ConfigDrawer.vue

@@ -125,14 +125,13 @@
   import urlJoin from 'url-join';
 
   const mapEditor = useMapEditor();
-  const { addedShops, showShops, activeShop } = storeToRefs(mapEditor);
+  const { addedShops, showShops, activeShopId } = storeToRefs(mapEditor);
 
   const globSetting = useGlobSetting();
 
   const editShop = computed(
     () =>
-      showShops.value.find((item) => item.id === activeShop.value.id) ||
-      ({} as MapWorkShopInfoItem),
+      showShops.value.find((item) => item.id === activeShopId.value) || ({} as MapWorkShopInfoItem),
   );
 
   const emit = defineEmits(['onClose', 'saveConfig']);

+ 124 - 62
src/views/page-config/component/mapContainer/LabelItem.vue

@@ -1,71 +1,133 @@
 <template>
-  <div class="flex">
-    <SvgIcon icon-name="posPoint" :color="props.shop.bgColor" class="test-icon" />
-    <img
-      v-if="showThumbnail && props.shop.thumbnail"
-      class="hover-img"
-      :src="props.shop.thumbnail"
-      :alt="props.shop.name"
-    />
-    <div class="pos-rect">
-      <SvgIcon icon-name="posRect" :color="props.shop.bgColor" class="test-icon1" />
-      <span
-        class="label-name"
-        :style="{ fontSize: `${props.shop.fontSize}px`, color: props.shop.fontColor }"
-        >{{ props.shop.name }}</span
-      >
-    </div>
-  </div>
+  <v-image ref="pointRef" :config="getPointCurvConfig()" />
+  <v-image ref="rectRef" :config="getRectCurConfig()" />
+  <v-text :config="getTextConfig()" />
+  <v-image :config="shineConfig" />
 </template>
 
 <script setup lang="ts">
-  import { computed } from 'vue';
-  import { SvgIcon } from '@/components/SvgIcon';
+  import { ref, onMounted, nextTick, computed, watch } from 'vue';
+  import rectBlock from '@/assets/test/2-rect.svg';
+  import pointCurv from '@/assets/test/1-curv2.svg';
+  import shine from '@/assets/test/2-shine.svg';
+  import Konva from 'konva';
   import { MapWorkShopInfoItem } from '../../stores/useMapEditor';
 
-  const props = defineProps<{ shop: MapWorkShopInfoItem; show: boolean }>();
+  const props = defineProps<{ shop: MapWorkShopInfoItem }>();
 
-  const showThumbnail = computed(() => props.show);
+  const shopData = computed(() => props.shop);
+
+  const curvImage = ref<HTMLImageElement>(new Image());
+  const rectImage = ref<HTMLImageElement>(new Image());
+  const shineImage = ref<HTMLImageElement>(new Image());
+  const rectRef = ref<Konva.Image>();
+  const pointRef = ref<Konva.Image>();
+
+  const getRGBANum = (color: string) => {
+    if (!color) return [0, 0, 0, 0];
+    const pattern = /\((\d+),\s*(\d+),\s*(\d+),\s*(\d+(\.\d+)?)\)$/;
+    const array = color.match(pattern);
+    return [
+      Number(array![1]) || 0,
+      Number(array![2]) || 0,
+      Number(array![3]) || 0,
+      Number(array![4]) || 0,
+    ];
+  };
+
+  const nodeUpdateFilter = (node: Konva.Node) => {
+    node.cache();
+    const rgba = getRGBANum(shopData.value.bgColor);
+    node.red(rgba[0]);
+    node.green(rgba[1]);
+    node.blue(rgba[2]);
+    node.alpha(rgba[3]);
+  };
+
+  const getPointCurvConfig = () => {
+    return {
+      x: 0,
+      y: 0,
+      width: 32,
+      height: 39,
+      image: curvImage.value,
+    };
+  };
+
+  const getRectCurConfig = () => {
+    return {
+      x: 53,
+      y: 0,
+      width: 160,
+      height: 38,
+      image: rectImage.value,
+    };
+  };
+
+  const getTextConfig = () => {
+    return {
+      x: 53,
+      y: 0,
+      text: shopData.value.name,
+      fontSize: shopData.value.fontSize,
+      fontFamily: 'TRENDS',
+      fill: shopData.value.fontColor,
+      width: 160,
+      height: 32,
+      align: 'center',
+      verticalAlign: 'middle',
+    };
+  };
+
+  const shineConfig = computed(() => {
+    return {
+      x: 0,
+      y: 0,
+      width: 213,
+      height: 38,
+      image: shineImage.value,
+    };
+  });
+
+  watch(
+    shopData.value,
+    () => {
+      nextTick(() => {
+        nodeUpdateFilter(pointRef.value!.getNode());
+        nodeUpdateFilter(rectRef.value!.getNode());
+      });
+    },
+    { deep: true },
+  );
+
+  onMounted(() => {
+    const svgImg = new Image();
+    svgImg.onload = () => {
+      curvImage.value = svgImg;
+      nextTick(() => {
+        nodeUpdateFilter(pointRef.value?.getNode());
+      });
+    };
+    svgImg.src = pointCurv;
+
+    const rectImg = new Image();
+    rectImg.onload = () => {
+      rectImage.value = rectImg;
+      nextTick(() => {
+        nodeUpdateFilter(rectRef.value?.getNode());
+      });
+    };
+    rectImg.src = rectBlock;
+
+    const shineImg = new Image();
+    shineImg.onload = () => {
+      shineImage.value = shineImg;
+    };
+    shineImg.src = shine;
+
+    rectRef.value?.getNode().filters([Konva.Filters.RGBA]);
+    pointRef.value?.getNode().filters([Konva.Filters.RGBA]);
+  });
 </script>
 
-<style scoped>
-  .label-name {
-    position: absolute;
-    font-family: TRENDS;
-    margin-bottom: 10px;
-  }
-
-  .test-icon {
-    width: 40.2px;
-    height: 48px;
-    margin-right: 15px;
-  }
-
-  .hover-img {
-    position: absolute;
-    bottom: 0;
-    left: 0;
-    width: 81px;
-    height: 98px;
-    z-index: 10;
-    transform: translateX(-40%);
-  }
-
-  .pos-rect {
-    position: relative;
-    width: 241.5px;
-    height: 55.5px;
-    display: flex;
-    justify-content: center;
-    align-items: center;
-  }
-
-  .test-icon1 {
-    position: absolute;
-    top: 0;
-    left: 0;
-    width: 100%;
-    height: 100%;
-    object-fit: fill;
-  }
-</style>
+<style scoped></style>

+ 101 - 16
src/views/page-config/component/mapContainer/MapContainer.vue

@@ -1,29 +1,114 @@
 <template>
-  <div
-    :style="{
-      position: 'relative',
-      width: `${mapWidth}px`,
-      height: `${mapHeight}px`,
-      background: `url(${getRealImgUrl()})`,
-    }"
-  >
-    <Transformer v-for="item in showShops" :key="item.id" :shop="item" />
+  <div>
+    <v-stage
+      ref="stageRef"
+      :config="stageSize"
+      @mousedown="handleStageMouseDown"
+      @touchstart="handleStageMouseDown"
+    >
+      <v-layer ref="layerRef">
+        <v-image :config="bgConfig" />
+        <v-group
+          v-for="item in showShops"
+          :key="item.id"
+          :config="getGroupConfig(item)"
+          @transformend="handleTransformEnd"
+        >
+          <LabelItem :shop="item" />
+        </v-group>
+        <v-transformer ref="transformerRef" :config="transformerConfig" />
+      </v-layer>
+    </v-stage>
   </div>
 </template>
 
 <script setup lang="ts">
+  import { computed, ref } from 'vue';
+  import LabelItem from './LabelItem.vue';
   import { storeToRefs } from 'pinia';
-  import Transformer from './Transformer.vue';
-  import useMapEditor from '../../stores/useMapEditor';
-  import { useGlobSetting } from '@/hooks/setting';
-  import urlJoin from 'url-join';
+  import useMapEditor, { MapWorkShopInfoItem } from '../../stores/useMapEditor';
+  import Konva from 'konva';
 
   const mapEditor = useMapEditor();
-  const { mapWidth, mapHeight, bgImg, showShops } = storeToRefs(mapEditor);
+  const { mapWidth, mapHeight, showShops, bgImage } = storeToRefs(mapEditor);
 
-  const globSetting = useGlobSetting();
+  const stageRef = ref<Konva.Stage>();
+  const layerRef = ref<Konva.Layer>();
+  const transformerRef = ref<Konva.Transformer>();
 
-  const getRealImgUrl = () => urlJoin(globSetting.imgUrl!, bgImg.value);
+  let selectedShape = -1;
+
+  const stageSize = computed(() => {
+    return {
+      // width: mapWidth.value,
+      // height: mapHeight.value,
+      width: 1920,
+      height: 1080,
+    };
+  });
+
+  const bgConfig = computed(() => {
+    return {
+      width: 1920,
+      height: 1080,
+      image: bgImage.value,
+      name: 'bg',
+    };
+  });
+
+  const getGroupConfig = (shop: MapWorkShopInfoItem) => {
+    return {
+      x: shop.x,
+      y: shop.y,
+      id: shop.id + '',
+      draggable: true,
+      name: 'group',
+    };
+  };
+
+  const transformerConfig = {
+    keepRatio: true,
+    rotateEnabled: false,
+    enabledAnchors: ['top-left', 'top-right', 'bottom-left', 'bottom-right'],
+  };
+
+  const handleStageMouseDown = (e) => {
+    if (e.target.attrs.name === 'bg') {
+      selectedShape = -1;
+      updateTransformer();
+    }
+
+    if (e.target.parent.attrs.name === 'group') {
+      if (e.target.parent.id() === selectedShape) {
+        return;
+      }
+      selectedShape = e.target.parent.id();
+
+      updateTransformer();
+    }
+  };
+
+  const handleTransformEnd = (e) => {};
+
+  const updateTransformer = () => {
+    const transformerNode = transformerRef.value!.getNode();
+    const layer = layerRef.value!.getNode().getLayer();
+
+    if (selectedShape >= 0) {
+      const selectedNode = layer.findOne('#' + selectedShape);
+      (transformerNode as Konva.Transformer).nodes([selectedNode!]);
+    } else {
+      (transformerNode as Konva.Transformer).nodes([]);
+    }
+  };
+
+  const getLayout = () => {
+    const json = stageRef.value?.getStage().toJSON();
+
+    return json;
+  };
+
+  defineExpose({ getLayout });
 </script>
 
 <style scoped></style>

+ 0 - 360
src/views/page-config/hooks/useMapEditor.ts

@@ -1,360 +0,0 @@
-import { computed, h, onBeforeUnmount, onMounted, ref, render } from 'vue';
-import Konva from 'konva';
-import cameraImg from '@/assets/camera/cameraImg.png';
-import OptBar from '../components/CameraOptBar.vue';
-import DefaultTip from '../components/DefaultTip.vue';
-import { ElMessage } from 'element-plus';
-import { useGlobSetting } from '@/hooks/setting';
-import urlJoin from 'url-join';
-import { WorkShopInfoItem } from '@/api/scene/scene';
-import LabelItem from '../component/LabelItem.vue';
-import { SvgIcon } from '@/components/SvgIcon';
-import html2canvas from 'html2canvas';
-import { Canvg } from 'canvg';
-
-interface MapEditorOption {
-  onShopStyle?: (shop: WorkShopInfoItem) => void;
-}
-
-export function useMapEditor(opt: MapEditorOption) {
-  let initWidth; // 默认宽度
-  let initHeight; // 默认高度
-  let stage: Konva.Stage | null = null;
-  let layer: Konva.Layer | null = null;
-  const addedShops = ref<number[]>([]); // 已添加车间列表
-  const activeGroup = ref<Konva.Group | null>(null); // transformer激活的车间
-  let optBlock: HTMLDivElement | null = null; // 鼠标右击弹出的选项组
-  let isTransform = false; // 是否在变换中
-  const activeShopId = computed(() => activeGroup.value?.id()); // 当前选中车间ID
-  const bgImgUrl = ref<string>('');
-
-  const globSetting = useGlobSetting();
-
-  /** 容器初始化 */
-  const initContainer = (opt: Konva.StageConfig) => {
-    initWidth = opt.width || 0;
-    initHeight = opt.height || 0;
-    stage = new Konva.Stage(opt);
-    stage.on('click tap', handleStageClick);
-    layer = new Konva.Layer();
-    stage.add(layer);
-  };
-
-  /** 更换背景图时根据图片大小重置容器宽高 */
-  const resizeContainer = (width, height) => {
-    const newWidth = width > initWidth ? width : initWidth;
-    const newHeight = height > initHeight ? height : initHeight;
-    stage?.width(newWidth);
-    stage?.height(newHeight);
-  };
-
-  /** 添加背景 */
-  const addBg = () => {
-    // const imgUrl = urlJoin(globSetting.imgUrl!, bgImgUrl.value);
-    const imgUrl = bgImgUrl.value;
-    const bgNode = layer?.find('#bgImg')[0] as Konva.Image;
-    const bgImg = new Image();
-    bgImg.onload = () => {
-      // 判断是否已有背景
-      if (!bgNode) {
-        const mapBg = new Konva.Image({
-          x: 0,
-          y: 0,
-          image: bgImg,
-          width: bgImg.width,
-          height: bgImg.height,
-          id: 'bgImg',
-        });
-        layer?.add(mapBg);
-        mapBg.moveToBottom();
-      } else {
-        bgNode.width(bgImg.width);
-        bgNode.height(bgImg.height);
-        bgNode.image(bgImg);
-      }
-      resizeContainer(bgImg.width, bgImg.height);
-      layer?.batchDraw();
-    };
-    bgImg.src = imgUrl;
-  };
-
-  /** 变更需要激活transform的车间 */
-  const attachTransformer = (group: Konva.Group): Konva.Transformer => {
-    activeGroup.value = group;
-    stage!.find('Transformer')[0]?.destroy(); // 清除现有transformer
-    const id = group.id();
-    const tr = new Konva.Transformer({
-      keepRatio: true,
-      rotateAnchorOffset: 30,
-      rotateEnabled: false,
-      enabledAnchors: ['top-left', 'top-right', 'bottom-left', 'bottom-right'],
-      id: 'tr_' + id,
-    });
-    tr.nodes([group]);
-    layer?.add(tr);
-    layer?.draw();
-
-    group.on('dragstart', handleDragStart);
-    group.on('dragstart', handleDragEnd);
-
-    return tr;
-  };
-
-  /** 添加车间 */
-  const addShop = (shop: WorkShopInfoItem) => {
-    const group = new Konva.Group({
-      x: 100,
-      y: 100,
-      id: shop.id + '',
-      draggable: true,
-      name: 'group',
-    });
-    // Konva.Image.fromURL(point, (imageNode) => {
-    //   group.add(imageNode),
-    //     imageNode.setAttrs({
-    //       fill: 'red',
-    //     });
-    // });
-
-    const testImg = new Konva.Image({
-      width: 27,
-      height: 32,
-      image: undefined,
-    });
-    group?.add(testImg);
-    const dv = document.createElement('div');
-    dv.setAttribute('id', 'labelItem');
-    dv.setAttribute('style', `position: absolute; left: 0px; top: 0px;`);
-    const label = h(SvgIcon, {
-      iconName: 'posPoint',
-      color: '#ef684d',
-      style: { width: '27px', height: '32px' },
-    });
-    render(label, dv);
-    const labelSvg = dv.querySelector('svg');
-    const labelSvgStr = new XMLSerializer().serializeToString(labelSvg!);
-    const canvas = document.createElement('canvas') as HTMLCanvasElement;
-    const ctx = canvas.getContext('2d');
-    Canvg.from(ctx!, labelSvgStr).then(() => {
-      console.log('0-0-0-0-0-');
-
-      const ahref = document.createElement('a');
-      ahref.href = canvas.toDataURL('image/png');
-      ahref.download = 'exportPng';
-      ahref.click();
-
-      const parentEl = document.getElementById('drawContainer') as HTMLDivElement;
-      parentEl.append(canvas);
-      const test = new Konva.Image({
-        x: 10,
-        y: 10,
-        width: 27,
-        height: 32,
-        image: canvas,
-        name: 'image',
-      });
-      layer?.add(test);
-      test.moveToTop();
-      layer?.draw();
-    });
-
-    //     const test = new konva.Image({
-    //       x: 10,
-    //       y: 10,
-    //       width: 27,
-    //       height: 32,
-    //       image: canvas,
-    //       name: 'image',
-    //     });
-    //     layer.add(test);
-    //     test.moveToTop();
-    //     layer.draw();
-    //   },
-    // });
-
-    // const labelImg = new Image();
-    // const svgUrl = new Blob([labelSvgStr], { type: 'image/svg+xml;charset=utf-8' });
-    // const DOMURL = self.URL || self.webkitURL || self;
-    // const labelUrl = DOMURL.createObjectURL(svgUrl);
-    // console.log(labelSvgStr);
-
-    // labelImg.onload = () => {
-    //   const labelPoint = new Konva.Image({
-    //     width: 27,
-    //     height: 32,
-    //     image: labelImg,
-    //     name: 'image',
-    //   });
-    //   layer?.add(labelPoint);
-    //   layer?.batchDraw();
-    // };
-    // labelImg.src = labelUrl;
-
-    // parentEl.append(dv);
-    // html2canvas(dv, { backgroundColor: 'transparent' }).then((canvas) => {
-    //   console.log(canvas);
-
-    //   testImg.image(canvas);
-    //   layer?.batchDraw();
-    // });
-
-    const shopName = new Konva.Text({
-      text: shop.name,
-      fontSize: 14,
-      fontFamily: 'TRENDS',
-      fill: '#FFFFFF',
-    });
-    group.add(shopName);
-    const w = shopName.width();
-    const th = shopName.height();
-    const markCir = new Konva.Circle({
-      x: th / 2 + 3,
-      y: th / 2 + 3,
-      radius: th / 2 + 3,
-      fill: 'blue',
-    });
-    group.add(markCir);
-    shopName.moveUp();
-    const markRect = new Konva.Rect({
-      x: th + 20,
-      y: 0,
-      width: w + 10,
-      height: th + 6,
-      fill: 'blue',
-    });
-    group.add(markRect);
-    shopName.x(th + 25);
-    shopName.y(5);
-    shopName.moveUp();
-
-    testImg.moveToTop();
-
-    layer?.add(group);
-    attachTransformer(group); // 添加的车间默认激活transformer
-
-    opt.onShopStyle && opt.onShopStyle(shop);
-    addedShops.value.push(shop.id);
-  };
-
-  /** 创建右键选项组 */
-  const createOptBlock = (node: Konva.Group, x: number, y: number) => {};
-
-  /** 删除右键选项组 */
-  const destoryOptBlock = () => {
-    optBlock?.remove();
-    optBlock = null;
-  };
-
-  /** 删除车间 */
-  const deleteShop = () => {
-    const index = addedShops.value.findIndex((item) => item === activeGroup.value?.id());
-    index >= 0 && addedShops.value.splice(index, 1);
-    activeGroup.value?.destroy();
-    stage!.find('Transformer')[0]?.destroy();
-    layer?.draw();
-  };
-
-  /** 鼠标悬浮事件 */
-  const handleMouseOver = (e) => {
-    // 禁用浏览器默认鼠标事件
-    document.oncontextmenu = () => {
-      return false;
-    };
-  };
-
-  /** 鼠标离开事件 */
-  const handleMouseLeave = () => {
-    // 恢复浏览器默认事件
-    document.oncontextmenu = () => {
-      return true;
-    };
-  };
-
-  /** 开始拖拽事件 */
-  const handleDragStart = () => {
-    isTransform = true;
-    destoryOptBlock();
-  };
-
-  /** 结束拖拽事件 */
-  const handleDragEnd = () => {
-    isTransform = false;
-  };
-
-  /** 全局点击事件 */
-  const handleStageClick = (e) => {
-    // 点击舞台取消现有激活的transformer
-    if (e.target === stage) {
-      stage!.find('Transformer')[0].destroy();
-      layer!.draw();
-      return;
-    }
-
-    // 判断点击对象是否为车间
-    if (!e.target.hasName('image')) {
-      return;
-    }
-    const parent = e.target.parent;
-    if (!parent.hasName('group')) {
-      return;
-    }
-    const group = e.target.parent;
-    attachTransformer(group);
-    // 判断是否为右键点击
-    if (e.evt.button === 2) {
-      createOptBlock(group, e.evt.offsetX + 20, e.evt.offsetY);
-    }
-  };
-
-  /** 键盘点击事件 */
-  const handleKeyDown = (e) => {
-    // 删除键
-    if (e.keyCode === 46 || e.code === 'Delete') {
-      deleteShop();
-    }
-  };
-
-  // 基础监听事件绑定
-  const bindBaseEvt = (node: Konva.Node) => {
-    // node.on('transform', handleDragStart);
-    // node.on('transformend', handleDragEnd);
-    node.on('mouseover', handleMouseOver);
-    node.on('mouseleave', handleMouseLeave);
-  };
-
-  /** 输出布局json */
-  const toJson = () => {
-    const json = stage!.toJSON();
-    const layout = {
-      bgImg: bgImgUrl.value,
-      shopLis: [],
-    };
-
-    return JSON.stringify(layout);
-  };
-
-  /** 导入布局json */
-  const createMap = (json) => {};
-
-  onMounted(() => {
-    window.addEventListener('keydown', handleKeyDown);
-  });
-
-  onBeforeUnmount(() => {
-    window.removeEventListener('keydown', handleKeyDown);
-  });
-
-  return {
-    activeShopId,
-    addedShops,
-    bgImgUrl,
-    initContainer,
-    addBg,
-    addShop,
-    destoryOptBlock,
-    toJson,
-    createMap,
-  };
-}
-
-export default useMapEditor;

+ 0 - 272
src/views/page-config/hooks/useMapEditor1.ts

@@ -1,272 +0,0 @@
-import { computed, h, onBeforeUnmount, onMounted, ref, render } from 'vue';
-import Konva from 'konva';
-import cameraImg from '@/assets/camera/cameraImg.png';
-import OptBar from '../components/CameraOptBar.vue';
-import DefaultTip from '../components/DefaultTip.vue';
-import { ElMessage } from 'element-plus';
-import { useGlobSetting } from '@/hooks/setting';
-import urlJoin from 'url-join';
-import { WorkShopInfoItem } from '@/api/scene/scene';
-import point from '@/assets/icons/posPoint.svg';
-
-interface MapEditorOption {
-  onShopStyle?: (shop: WorkShopInfoItem) => void;
-}
-
-export function useMapEditor(opt: MapEditorOption) {
-  let initWidth; // 默认宽度
-  let initHeight; // 默认高度
-  let stage: Konva.Stage | null = null;
-  let layer: Konva.Layer | null = null;
-  const addedShops = ref<number[]>([]); // 已添加车间列表
-  const activeGroup = ref<Konva.Group | null>(null); // transformer激活的车间
-  let optBlock: HTMLDivElement | null = null; // 鼠标右击弹出的选项组
-  let isTransform = false; // 是否在变换中
-  const activeShopId = computed(() => activeGroup.value?.id()); // 当前选中车间ID
-  const bgImgUrl = ref<string>('');
-
-  const globSetting = useGlobSetting();
-
-  /** 容器初始化 */
-  const initContainer = (opt: Konva.StageConfig) => {
-    initWidth = opt.width || 0;
-    initHeight = opt.height || 0;
-    stage = new Konva.Stage(opt);
-    stage.on('click tap', handleStageClick);
-    layer = new Konva.Layer();
-    stage.add(layer);
-  };
-
-  /** 更换背景图时根据图片大小重置容器宽高 */
-  const resizeContainer = (width, height) => {
-    const newWidth = width > initWidth ? width : initWidth;
-    const newHeight = height > initHeight ? height : initHeight;
-    stage?.width(newWidth);
-    stage?.height(newHeight);
-  };
-
-  /** 添加背景 */
-  const addBg = () => {
-    // const imgUrl = urlJoin(globSetting.imgUrl!, bgImgUrl.value);
-    const imgUrl = bgImgUrl.value;
-    const bgNode = layer?.find('#bgImg')[0] as Konva.Image;
-    const bgImg = new Image();
-    bgImg.onload = () => {
-      // 判断是否已有背景
-      if (!bgNode) {
-        const mapBg = new Konva.Image({
-          x: 0,
-          y: 0,
-          image: bgImg,
-          width: bgImg.width,
-          height: bgImg.height,
-          id: 'bgImg',
-        });
-        layer?.add(mapBg);
-        mapBg.moveToBottom();
-      } else {
-        bgNode.width(bgImg.width);
-        bgNode.height(bgImg.height);
-        bgNode.image(bgImg);
-      }
-      resizeContainer(bgImg.width, bgImg.height);
-      layer?.batchDraw();
-    };
-    bgImg.src = imgUrl;
-  };
-
-  /** 变更需要激活transform的车间 */
-  const attachTransformer = (group: Konva.Group): Konva.Transformer => {
-    activeGroup.value = group;
-    stage!.find('Transformer')[0]?.destroy(); // 清除现有transformer
-    const id = group.id();
-    const tr = new Konva.Transformer({
-      keepRatio: true,
-      rotateAnchorOffset: 30,
-      rotateEnabled: false,
-      enabledAnchors: ['top-left', 'top-right', 'bottom-left', 'bottom-right'],
-      id: 'tr_' + id,
-    });
-    tr.nodes([group]);
-    layer?.add(tr);
-    layer?.draw();
-
-    group.on('dragstart', handleDragStart);
-    group.on('dragstart', handleDragEnd);
-
-    return tr;
-  };
-
-  /** 添加车间 */
-  const addShop = (shop: WorkShopInfoItem) => {
-    const group = new Konva.Group({
-      x: 100,
-      y: 100,
-      id: shop.id + '',
-      draggable: true,
-      name: 'group',
-    });
-    // Konva.Image.fromURL(point, (imageNode) => {
-    //   group.add(imageNode),
-    //     imageNode.setAttrs({
-    //       fill: 'red',
-    //     });
-    // });
-
-    const shopName = new Konva.Text({
-      text: shop.name,
-      fontSize: 14,
-      fontFamily: 'TRENDS',
-      fill: '#FFFFFF',
-    });
-    group.add(shopName);
-    const w = shopName.width();
-    const h = shopName.height();
-    const markCir = new Konva.Circle({
-      x: h / 2 + 3,
-      y: h / 2 + 3,
-      radius: h / 2 + 3,
-      fill: 'blue',
-    });
-    group.add(markCir);
-    shopName.moveUp();
-    const markRect = new Konva.Rect({
-      x: h + 20,
-      y: 0,
-      width: w + 10,
-      height: h + 6,
-      fill: 'blue',
-    });
-    group.add(markRect);
-    shopName.x(h + 25);
-    shopName.y(5);
-    shopName.moveUp();
-    layer?.add(group);
-    attachTransformer(group); // 添加的车间默认激活transformer
-
-    opt.onShopStyle && opt.onShopStyle(shop);
-    addedShops.value.push(shop.id);
-  };
-
-  /** 创建右键选项组 */
-  const createOptBlock = (node: Konva.Group, x: number, y: number) => {};
-
-  /** 删除右键选项组 */
-  const destoryOptBlock = () => {
-    optBlock?.remove();
-    optBlock = null;
-  };
-
-  /** 删除车间 */
-  const deleteShop = () => {
-    const index = addedShops.value.findIndex((item) => item === activeGroup.value?.id());
-    index >= 0 && addedShops.value.splice(index, 1);
-    activeGroup.value?.destroy();
-    stage!.find('Transformer')[0]?.destroy();
-    layer?.draw();
-  };
-
-  /** 鼠标悬浮事件 */
-  const handleMouseOver = (e) => {
-    // 禁用浏览器默认鼠标事件
-    document.oncontextmenu = () => {
-      return false;
-    };
-  };
-
-  /** 鼠标离开事件 */
-  const handleMouseLeave = () => {
-    // 恢复浏览器默认事件
-    document.oncontextmenu = () => {
-      return true;
-    };
-  };
-
-  /** 开始拖拽事件 */
-  const handleDragStart = () => {
-    isTransform = true;
-    destoryOptBlock();
-  };
-
-  /** 结束拖拽事件 */
-  const handleDragEnd = () => {
-    isTransform = false;
-  };
-
-  /** 全局点击事件 */
-  const handleStageClick = (e) => {
-    // 点击舞台取消现有激活的transformer
-    if (e.target === stage) {
-      stage!.find('Transformer')[0].destroy();
-      layer!.draw();
-      return;
-    }
-
-    // 判断点击对象是否为车间
-    if (!e.target.hasName('image')) {
-      return;
-    }
-    const parent = e.target.parent;
-    if (!parent.hasName('group')) {
-      return;
-    }
-    const group = e.target.parent;
-    attachTransformer(group);
-    // 判断是否为右键点击
-    if (e.evt.button === 2) {
-      createOptBlock(group, e.evt.offsetX + 20, e.evt.offsetY);
-    }
-  };
-
-  /** 键盘点击事件 */
-  const handleKeyDown = (e) => {
-    // 删除键
-    if (e.keyCode === 46 || e.code === 'Delete') {
-      deleteShop();
-    }
-  };
-
-  // 基础监听事件绑定
-  const bindBaseEvt = (node: Konva.Node) => {
-    // node.on('transform', handleDragStart);
-    // node.on('transformend', handleDragEnd);
-    node.on('mouseover', handleMouseOver);
-    node.on('mouseleave', handleMouseLeave);
-  };
-
-  /** 输出布局json */
-  const toJson = () => {
-    const json = stage!.toJSON();
-    const layout = {
-      bgImg: bgImgUrl.value,
-      shopLis: [],
-    };
-
-    return JSON.stringify(layout);
-  };
-
-  /** 导入布局json */
-  const createMap = (json) => {};
-
-  onMounted(() => {
-    window.addEventListener('keydown', handleKeyDown);
-  });
-
-  onBeforeUnmount(() => {
-    window.removeEventListener('keydown', handleKeyDown);
-  });
-
-  return {
-    activeShopId,
-    addedShops,
-    bgImgUrl,
-    initContainer,
-    addBg,
-    addShop,
-    destoryOptBlock,
-    toJson,
-    createMap,
-  };
-}
-
-export default useMapEditor;

+ 0 - 534
src/views/page-config/shops.json

@@ -1,534 +0,0 @@
-[
-  {
-    "id": 16,
-    "companyId": 6,
-    "sceneLabelId": 2,
-    "name": "硝盐槽",
-    "code": "nitrate tank",
-    "remark": "",
-    "status": 0,
-    "createdAt": "2023-12-11 12:04:17",
-    "updatedAt": "2023-12-11 14:00:40",
-    "isDeleted": 0,
-    "serial": 0,
-    "labelName": "安全管控",
-    "workshopModule": {
-      "id": 2,
-      "name": "厂房",
-      "code": "2",
-      "remark": "",
-      "status": 0,
-      "createdAt": "2023-12-22 11:44:06",
-      "updatedAt": "2023-12-22 11:44:06",
-      "isDeleted": 0
-    },
-    "children": []
-  },
-  {
-    "id": 17,
-    "companyId": 6,
-    "sceneLabelId": 2,
-    "name": "化学品库房",
-    "code": "cw",
-    "remark": "",
-    "status": 0,
-    "createdAt": "2023-12-11 12:04:42",
-    "updatedAt": "2023-12-11 12:04:42",
-    "isDeleted": 0,
-    "serial": 0,
-    "labelName": "安全管控",
-    "workshopModule": {
-      "id": 2,
-      "name": "厂房",
-      "code": "2",
-      "remark": "",
-      "status": 0,
-      "createdAt": "2023-12-22 11:44:06",
-      "updatedAt": "2023-12-22 11:44:06",
-      "isDeleted": 0
-    },
-    "children": []
-  },
-  {
-    "id": 18,
-    "companyId": 3,
-    "sceneLabelId": 2,
-    "name": "燃油实验室",
-    "code": "sfy-FL",
-    "remark": "",
-    "status": 0,
-    "createdAt": "2023-12-11 13:41:37",
-    "updatedAt": "2023-12-11 13:41:37",
-    "isDeleted": 0,
-    "serial": 0,
-    "labelName": "安全管控",
-    "workshopModule": {
-      "id": 1,
-      "name": "危险点",
-      "code": "1",
-      "remark": "",
-      "status": 0,
-      "createdAt": "2023-12-22 11:43:54",
-      "updatedAt": "2023-12-22 11:43:54",
-      "isDeleted": 0
-    },
-    "children": []
-  },
-  {
-    "id": 19,
-    "companyId": 5,
-    "sceneLabelId": 2,
-    "name": "配电站",
-    "code": "kf-substation",
-    "remark": "",
-    "status": 0,
-    "createdAt": "2023-12-26 11:09:22",
-    "updatedAt": "2023-12-26 11:09:22",
-    "isDeleted": 0,
-    "serial": 0,
-    "labelName": "安全管控",
-    "workshopModule": {
-      "id": 1,
-      "name": "危险点",
-      "code": "1",
-      "remark": "",
-      "status": 0,
-      "createdAt": "2023-12-22 11:43:54",
-      "updatedAt": "2023-12-22 11:43:54",
-      "isDeleted": 0
-    },
-    "children": []
-  },
-  {
-    "id": 20,
-    "companyId": 5,
-    "sceneLabelId": 2,
-    "name": "气瓶间",
-    "code": "kf-gcr",
-    "remark": "",
-    "status": 0,
-    "createdAt": "2023-12-26 11:09:59",
-    "updatedAt": "2023-12-26 11:09:59",
-    "isDeleted": 0,
-    "serial": 0,
-    "labelName": "安全管控",
-    "workshopModule": {
-      "id": 2,
-      "name": "厂房",
-      "code": "2",
-      "remark": "",
-      "status": 0,
-      "createdAt": "2023-12-22 11:44:06",
-      "updatedAt": "2023-12-22 11:44:06",
-      "isDeleted": 0
-    },
-    "children": []
-  },
-  {
-    "id": 21,
-    "companyId": 5,
-    "sceneLabelId": 2,
-    "name": "柴油发电机",
-    "code": "kf-dg",
-    "remark": "",
-    "status": 0,
-    "createdAt": "2023-12-26 11:10:19",
-    "updatedAt": "2023-12-26 11:10:19",
-    "isDeleted": 0,
-    "serial": 0,
-    "labelName": "安全管控",
-    "workshopModule": {
-      "id": 2,
-      "name": "厂房",
-      "code": "2",
-      "remark": "",
-      "status": 0,
-      "createdAt": "2023-12-22 11:44:06",
-      "updatedAt": "2023-12-22 11:44:06",
-      "isDeleted": 0
-    },
-    "children": []
-  },
-  {
-    "id": 22,
-    "companyId": 5,
-    "sceneLabelId": 2,
-    "name": "运行支持指挥中心",
-    "code": "kf-qrh",
-    "remark": "",
-    "status": 0,
-    "createdAt": "2023-12-26 11:10:40",
-    "updatedAt": "2024-01-16 15:01:28",
-    "isDeleted": 0,
-    "serial": 0,
-    "labelName": "安全管控",
-    "workshopModule": {
-      "id": 2,
-      "name": "厂房",
-      "code": "2",
-      "remark": "",
-      "status": 0,
-      "createdAt": "2023-12-22 11:44:06",
-      "updatedAt": "2023-12-22 11:44:06",
-      "isDeleted": 0
-    },
-    "children": []
-  },
-  {
-    "id": 23,
-    "companyId": 5,
-    "sceneLabelId": 2,
-    "name": "C919飞行模拟机",
-    "code": "kf-sl",
-    "remark": "",
-    "status": 0,
-    "createdAt": "2023-12-26 11:11:00",
-    "updatedAt": "2024-01-17 08:51:47",
-    "isDeleted": 0,
-    "serial": 0,
-    "labelName": "安全管控",
-    "workshopModule": {
-      "id": 2,
-      "name": "厂房",
-      "code": "2",
-      "remark": "",
-      "status": 0,
-      "createdAt": "2023-12-22 11:44:06",
-      "updatedAt": "2023-12-22 11:44:06",
-      "isDeleted": 0
-    },
-    "children": []
-  },
-  {
-    "id": 1,
-    "companyId": 2,
-    "sceneLabelId": 1,
-    "name": "ARJ21部装车间",
-    "code": "C12",
-    "remark": "",
-    "status": 0,
-    "createdAt": "2023-10-13 09:48:58",
-    "updatedAt": "2024-01-16 15:00:46",
-    "isDeleted": 0,
-    "serial": 0,
-    "labelName": "生产安全",
-    "workshopModule": {
-      "id": 2,
-      "name": "厂房",
-      "code": "2",
-      "remark": "",
-      "status": 0,
-      "createdAt": "2023-12-22 11:44:06",
-      "updatedAt": "2023-12-22 11:44:06",
-      "isDeleted": 0
-    },
-    "children": [
-      {
-        "id": 2,
-        "workshopId": 1,
-        "name": "西侧200室内气密试验区",
-        "code": "C12-W200test",
-        "remark": "",
-        "principal": "",
-        "status": 0,
-        "createdAt": "2023-12-27 14:07:15",
-        "updatedAt": "2024-01-05 09:05:52",
-        "isDeleted": 0,
-        "serial": 0
-      },
-      {
-        "id": 1,
-        "workshopId": 1,
-        "name": "东侧200室内气密试验区",
-        "code": "C12-E200test",
-        "remark": "",
-        "principal": "",
-        "status": 0,
-        "createdAt": "2023-12-27 14:06:46",
-        "updatedAt": "2024-01-05 09:05:52",
-        "isDeleted": 0,
-        "serial": 1
-      }
-    ]
-  },
-  {
-    "id": 3,
-    "companyId": 2,
-    "sceneLabelId": 1,
-    "name": "C919部装车间",
-    "code": "C02",
-    "remark": "",
-    "status": 0,
-    "createdAt": "2023-10-13 09:50:31",
-    "updatedAt": "2024-01-16 15:00:52",
-    "isDeleted": 0,
-    "serial": 0,
-    "labelName": "生产安全",
-    "workshopModule": {
-      "id": 2,
-      "name": "厂房",
-      "code": "2",
-      "remark": "",
-      "status": 0,
-      "createdAt": "2023-12-22 11:44:06",
-      "updatedAt": "2023-12-22 11:44:06",
-      "isDeleted": 0
-    },
-    "children": []
-  },
-  {
-    "id": 6,
-    "companyId": 2,
-    "sceneLabelId": 1,
-    "name": "胶接车间",
-    "code": "B16",
-    "remark": "",
-    "status": 0,
-    "createdAt": "2023-10-13 09:51:42",
-    "updatedAt": "2024-01-16 15:00:57",
-    "isDeleted": 0,
-    "serial": 0,
-    "labelName": "生产安全",
-    "workshopModule": {
-      "id": 2,
-      "name": "厂房",
-      "code": "2",
-      "remark": "",
-      "status": 0,
-      "createdAt": "2023-12-22 11:44:06",
-      "updatedAt": "2023-12-22 11:44:06",
-      "isDeleted": 0
-    },
-    "children": []
-  },
-  {
-    "id": 7,
-    "companyId": 2,
-    "sceneLabelId": 1,
-    "name": "复材车间",
-    "code": "B01",
-    "remark": "",
-    "status": 0,
-    "createdAt": "2023-10-13 09:52:02",
-    "updatedAt": "2024-01-16 15:00:59",
-    "isDeleted": 0,
-    "serial": 0,
-    "labelName": "生产安全",
-    "workshopModule": null,
-    "children": []
-  },
-  {
-    "id": 8,
-    "companyId": 2,
-    "sceneLabelId": 1,
-    "name": "工装中心",
-    "code": "B04",
-    "remark": "",
-    "status": 0,
-    "createdAt": "2023-10-13 09:53:01",
-    "updatedAt": "2023-10-13 09:53:01",
-    "isDeleted": 0,
-    "serial": 0,
-    "labelName": "生产安全",
-    "workshopModule": null,
-    "children": []
-  },
-  {
-    "id": 9,
-    "companyId": 2,
-    "sceneLabelId": 2,
-    "name": "B16热压罐",
-    "code": "B16autoclave",
-    "remark": "",
-    "status": 0,
-    "createdAt": "2023-10-13 10:22:20",
-    "updatedAt": "2023-10-19 19:12:27",
-    "isDeleted": 0,
-    "serial": 0,
-    "labelName": "安全管控",
-    "workshopModule": null,
-    "children": []
-  },
-  {
-    "id": 10,
-    "companyId": 2,
-    "sceneLabelId": 2,
-    "name": "B01热压罐",
-    "code": "B01autoclave",
-    "remark": "",
-    "status": 0,
-    "createdAt": "2023-10-13 10:22:39",
-    "updatedAt": "2023-10-13 10:22:39",
-    "isDeleted": 0,
-    "serial": 0,
-    "labelName": "安全管控",
-    "workshopModule": null,
-    "children": []
-  },
-  {
-    "id": 11,
-    "companyId": 2,
-    "sceneLabelId": 2,
-    "name": "110KV变电站",
-    "code": "110KVsubstation",
-    "remark": "",
-    "status": 0,
-    "createdAt": "2023-10-13 10:23:02",
-    "updatedAt": "2023-10-13 10:23:02",
-    "isDeleted": 0,
-    "serial": 0,
-    "labelName": "安全管控",
-    "workshopModule": null,
-    "children": []
-  },
-  {
-    "id": 12,
-    "companyId": 2,
-    "sceneLabelId": 2,
-    "name": "2011锅炉房",
-    "code": "2011boiler",
-    "remark": "",
-    "status": 0,
-    "createdAt": "2023-10-13 10:23:20",
-    "updatedAt": "2023-10-13 10:23:20",
-    "isDeleted": 0,
-    "serial": 0,
-    "labelName": "安全管控",
-    "workshopModule": {
-      "id": 1,
-      "name": "危险点",
-      "code": "1",
-      "remark": "",
-      "status": 0,
-      "createdAt": "2023-12-22 11:43:54",
-      "updatedAt": "2023-12-22 11:43:54",
-      "isDeleted": 0
-    },
-    "children": []
-  },
-  {
-    "id": 13,
-    "companyId": 2,
-    "sceneLabelId": 2,
-    "name": "2001a锅炉房",
-    "code": "2001aboiler",
-    "remark": "",
-    "status": 0,
-    "createdAt": "2023-10-13 10:23:36",
-    "updatedAt": "2023-10-13 10:23:36",
-    "isDeleted": 0,
-    "serial": 0,
-    "labelName": "安全管控",
-    "workshopModule": {
-      "id": 1,
-      "name": "危险点",
-      "code": "1",
-      "remark": "",
-      "status": 0,
-      "createdAt": "2023-12-22 11:43:54",
-      "updatedAt": "2023-12-22 11:43:54",
-      "isDeleted": 0
-    },
-    "children": []
-  },
-  {
-    "id": 15,
-    "companyId": 2,
-    "sceneLabelId": 2,
-    "name": "增材实验室",
-    "code": "sf-additive_lab",
-    "remark": "",
-    "status": 0,
-    "createdAt": "2023-12-11 13:40:33",
-    "updatedAt": "2023-12-11 13:40:33",
-    "isDeleted": 0,
-    "serial": 0,
-    "labelName": "安全管控",
-    "workshopModule": {
-      "id": 1,
-      "name": "危险点",
-      "code": "1",
-      "remark": "",
-      "status": 0,
-      "createdAt": "2023-12-22 11:43:54",
-      "updatedAt": "2023-12-22 11:43:54",
-      "isDeleted": 0
-    },
-    "children": []
-  },
-  {
-    "id": 2,
-    "companyId": 2,
-    "sceneLabelId": 1,
-    "name": "ARJ21总装车间",
-    "code": "C11",
-    "remark": "",
-    "status": 0,
-    "createdAt": "2023-10-13 09:49:31",
-    "updatedAt": "2024-01-16 15:00:48",
-    "isDeleted": 0,
-    "serial": 1,
-    "labelName": "生产安全",
-    "workshopModule": {
-      "id": 2,
-      "name": "厂房",
-      "code": "2",
-      "remark": "",
-      "status": 0,
-      "createdAt": "2023-12-22 11:44:06",
-      "updatedAt": "2023-12-22 11:44:06",
-      "isDeleted": 0
-    },
-    "children": []
-  },
-  {
-    "id": 4,
-    "companyId": 2,
-    "sceneLabelId": 1,
-    "name": "C919总装车间",
-    "code": "C01",
-    "remark": "",
-    "status": 0,
-    "createdAt": "2023-10-13 09:50:53",
-    "updatedAt": "2024-01-16 15:00:54",
-    "isDeleted": 0,
-    "serial": 1,
-    "labelName": "生产安全",
-    "workshopModule": {
-      "id": 2,
-      "name": "厂房",
-      "code": "2",
-      "remark": "",
-      "status": 0,
-      "createdAt": "2023-12-22 11:44:06",
-      "updatedAt": "2023-12-22 11:44:06",
-      "isDeleted": 0
-    },
-    "children": []
-  },
-  {
-    "id": 5,
-    "companyId": 2,
-    "sceneLabelId": 1,
-    "name": "维修交付中心",
-    "code": "repair",
-    "remark": "",
-    "status": 0,
-    "createdAt": "2023-10-13 09:51:22",
-    "updatedAt": "2024-01-16 15:00:55",
-    "isDeleted": 0,
-    "serial": 2,
-    "labelName": "生产安全",
-    "workshopModule": {
-      "id": 2,
-      "name": "厂房",
-      "code": "2",
-      "remark": "",
-      "status": 0,
-      "createdAt": "2023-12-22 11:44:06",
-      "updatedAt": "2023-12-22 11:44:06",
-      "isDeleted": 0
-    },
-    "children": []
-  }
-]

+ 111 - 0
src/views/page-config/stores/useMapEditor copy.ts

@@ -0,0 +1,111 @@
+import { ref } from 'vue';
+import { defineStore } from 'pinia';
+import { WorkShopInfoItem } from '@/api/scene/scene';
+import { cloneDeep } from 'lodash-es';
+import { useGlobSetting } from '@/hooks/setting';
+import urlJoin from 'url-join';
+
+export enum LabelPositionEnum {
+  LEFT = 'left',
+  RIGHT = 'right',
+  TOP = 'top',
+}
+
+export type EditStyle = {
+  x: number;
+  y: number;
+  scale: number;
+  thumbnail?: string;
+  bgColor: string;
+  fontSize: number;
+  fontColor: string;
+  posType: LabelPositionEnum;
+};
+
+export type MapWorkShopInfoItem = WorkShopInfoItem & EditStyle;
+
+export const useMapEditor = defineStore('home-map-ediotr', () => {
+  const globSetting = useGlobSetting();
+
+  const bgImg = ref('');
+  const mapWidth = ref(0);
+  const mapHeight = ref(0);
+  const addedShops = ref<MapWorkShopInfoItem[]>([]);
+  const showShops = ref<MapWorkShopInfoItem[]>([]);
+  const activeShop = ref<MapWorkShopInfoItem>({} as MapWorkShopInfoItem);
+
+  const addBg = () => {
+    const imgUrl = urlJoin(globSetting.imgUrl!, bgImg.value);
+    console.log(imgUrl);
+
+    const img = new Image();
+    img.onload = () => {
+      mapWidth.value = img.width;
+      mapHeight.value = img.height;
+    };
+    img.src = imgUrl;
+  };
+
+  const addShop = (shop: MapWorkShopInfoItem) => {
+    activeShop.value = shop;
+    addedShops.value.push(cloneDeep(shop));
+    showShops.value.push(cloneDeep(shop));
+  };
+
+  const toJson = () => {
+    const layout = {
+      bgInfo: {
+        width: mapWidth.value,
+        height: mapHeight.value,
+        img: bgImg.value,
+      },
+      shopList: addedShops.value.map((shop) => {
+        const temp = cloneDeep(shop) as any;
+        delete temp.children;
+        return temp;
+      }),
+    };
+
+    return JSON.stringify(layout);
+  };
+
+  const createMap = (layout) => {
+    bgImg.value = layout.bgInfo.img;
+    mapWidth.value = layout.bgInfo.width;
+    mapHeight.value = layout.bgInfo.height;
+    addedShops.value = cloneDeep(layout.shopList);
+    showShops.value = cloneDeep(layout.shopList);
+  };
+
+  const deleteShop = () => {
+    addedShops.value = addedShops.value.filter((item) => item.id !== activeShop.value.id);
+    showShops.value = showShops.value.filter((item) => item.id !== activeShop.value.id);
+    activeShop.value = {} as MapWorkShopInfoItem;
+  };
+
+  const resetMap = () => {
+    bgImg.value = '';
+    mapWidth.value = 0;
+    mapHeight.value = 0;
+    addedShops.value = [];
+    showShops.value = [];
+    activeShop.value = {} as MapWorkShopInfoItem;
+  };
+
+  return {
+    bgImg,
+    mapWidth,
+    mapHeight,
+    addedShops,
+    showShops,
+    activeShop,
+    addShop,
+    addBg,
+    toJson,
+    createMap,
+    deleteShop,
+    resetMap,
+  };
+});
+
+export default useMapEditor;

+ 27 - 14
src/views/page-config/stores/useMapEditor.ts

@@ -3,7 +3,9 @@ import { defineStore } from 'pinia';
 import { WorkShopInfoItem } from '@/api/scene/scene';
 import { cloneDeep } from 'lodash-es';
 import { useGlobSetting } from '@/hooks/setting';
+import safeParse from '@/utils/safeParse';
 import urlJoin from 'url-join';
+import emptyImg from '@/assets/images/table/table-empty.png';
 
 export enum LabelPositionEnum {
   LEFT = 'left',
@@ -32,27 +34,33 @@ export const useMapEditor = defineStore('home-map-ediotr', () => {
   const mapHeight = ref(0);
   const addedShops = ref<MapWorkShopInfoItem[]>([]);
   const showShops = ref<MapWorkShopInfoItem[]>([]);
-  const activeShop = ref<MapWorkShopInfoItem>({} as MapWorkShopInfoItem);
+  const activeShopId = ref<number>();
+
+  /** konva elements refs */
+  const bgImage = ref<HTMLImageElement>(new Image());
 
   const addBg = () => {
     const imgUrl = urlJoin(globSetting.imgUrl!, bgImg.value);
     console.log(imgUrl);
 
-    const img = new Image();
-    img.onload = () => {
-      mapWidth.value = img.width;
-      mapHeight.value = img.height;
+    const tempImg = new Image();
+    tempImg.onload = () => {
+      mapWidth.value = tempImg.width;
+      mapHeight.value = tempImg.height;
+      bgImage.value = tempImg;
     };
-    img.src = imgUrl;
+    tempImg.src = imgUrl;
   };
 
   const addShop = (shop: MapWorkShopInfoItem) => {
-    activeShop.value = shop;
+    activeShopId.value = shop.id;
     addedShops.value.push(cloneDeep(shop));
     showShops.value.push(cloneDeep(shop));
   };
 
-  const toJson = () => {
+  const calcLayout = (json: string) => {
+    const mapJson = safeParse(json);
+    const mapData = mapJson.children[0].children;
     const layout = {
       bgInfo: {
         width: mapWidth.value,
@@ -60,8 +68,12 @@ export const useMapEditor = defineStore('home-map-ediotr', () => {
         img: bgImg.value,
       },
       shopList: addedShops.value.map((shop) => {
+        const mapAttr = mapData.find((item) => item.id === shop.id + '')!.attrs;
         const temp = cloneDeep(shop) as any;
         delete temp.children;
+        temp.x = mapAttr.x;
+        temp.y = mapAttr.y;
+        temp.scale = mapAttr.scaleX || 1;
         return temp;
       }),
     };
@@ -78,9 +90,9 @@ export const useMapEditor = defineStore('home-map-ediotr', () => {
   };
 
   const deleteShop = () => {
-    addedShops.value = addedShops.value.filter((item) => item.id !== activeShop.value.id);
-    showShops.value = showShops.value.filter((item) => item.id !== activeShop.value.id);
-    activeShop.value = {} as MapWorkShopInfoItem;
+    addedShops.value = addedShops.value.filter((item) => item.id !== activeShopId.value);
+    showShops.value = showShops.value.filter((item) => item.id !== activeShopId.value);
+    activeShopId.value = undefined;
   };
 
   const resetMap = () => {
@@ -89,7 +101,7 @@ export const useMapEditor = defineStore('home-map-ediotr', () => {
     mapHeight.value = 0;
     addedShops.value = [];
     showShops.value = [];
-    activeShop.value = {} as MapWorkShopInfoItem;
+    activeShopId.value = undefined;
   };
 
   return {
@@ -98,10 +110,11 @@ export const useMapEditor = defineStore('home-map-ediotr', () => {
     mapHeight,
     addedShops,
     showShops,
-    activeShop,
+    activeShopId,
+    bgImage,
     addShop,
     addBg,
-    toJson,
+    calcLayout,
     createMap,
     deleteShop,
     resetMap,

+ 0 - 692
src/views/page-config/tree.json

@@ -1,692 +0,0 @@
-[
-  {
-    "id": 1,
-    "parentId": 0,
-    "name": "商飞公司",
-    "code": "COMAC",
-    "remark": "",
-    "status": 0,
-    "createdAt": "2023-10-10 19:53:58",
-    "updatedAt": "2024-01-02 15:25:01",
-    "serial": 0,
-    "isDeleted": 0,
-    "children": [],
-    "labelList": [
-      {
-        "id": 2,
-        "name": "安全管控",
-        "code": "2",
-        "remark": "",
-        "status": 0,
-        "createdAt": "2023-12-27 13:49:28",
-        "updatedAt": "2024-01-16 15:00:28",
-        "isDeleted": 0
-      }
-    ],
-    "moduleList": [
-      {
-        "id": 1,
-        "name": "生产安全模板",
-        "code": "12",
-        "remark": "32437857",
-        "status": 0,
-        "createdAt": "2023-12-22 11:43:05",
-        "updatedAt": "2024-01-04 14:37:40",
-        "isDeleted": 0
-      }
-    ]
-  },
-  {
-    "id": 6,
-    "parentId": 1,
-    "name": "上飞公司大场基地",
-    "code": "shangfeidachang",
-    "remark": "",
-    "status": 0,
-    "createdAt": "2023-12-11 09:07:53",
-    "updatedAt": "2023-12-11 09:07:53",
-    "serial": 0,
-    "isDeleted": 0,
-    "children": [
-      {
-        "id": 16,
-        "companyId": 6,
-        "sceneLabelId": 2,
-        "name": "硝盐槽",
-        "code": "nitrate tank",
-        "remark": "",
-        "status": 0,
-        "createdAt": "2023-12-11 12:04:17",
-        "updatedAt": "2023-12-11 14:00:40",
-        "isDeleted": 0,
-        "serial": 0,
-        "labelName": "安全管控",
-        "workshopModule": {
-          "id": 2,
-          "name": "厂房",
-          "code": "2",
-          "remark": "",
-          "status": 0,
-          "createdAt": "2023-12-22 11:44:06",
-          "updatedAt": "2023-12-22 11:44:06",
-          "isDeleted": 0
-        },
-        "children": []
-      },
-      {
-        "id": 17,
-        "companyId": 6,
-        "sceneLabelId": 2,
-        "name": "化学品库房",
-        "code": "cw",
-        "remark": "",
-        "status": 0,
-        "createdAt": "2023-12-11 12:04:42",
-        "updatedAt": "2023-12-11 12:04:42",
-        "isDeleted": 0,
-        "serial": 0,
-        "labelName": "安全管控",
-        "workshopModule": {
-          "id": 2,
-          "name": "厂房",
-          "code": "2",
-          "remark": "",
-          "status": 0,
-          "createdAt": "2023-12-22 11:44:06",
-          "updatedAt": "2023-12-22 11:44:06",
-          "isDeleted": 0
-        },
-        "children": []
-      }
-    ],
-    "labelList": [],
-    "moduleList": []
-  },
-  {
-    "id": 3,
-    "parentId": 1,
-    "name": "上飞院",
-    "code": "shangfeiyuan",
-    "remark": "",
-    "status": 0,
-    "createdAt": "2023-10-13 09:42:50",
-    "updatedAt": "2024-01-02 15:25:01",
-    "serial": 1,
-    "isDeleted": 0,
-    "children": [
-      {
-        "id": 18,
-        "companyId": 3,
-        "sceneLabelId": 2,
-        "name": "燃油实验室",
-        "code": "sfy-FL",
-        "remark": "",
-        "status": 0,
-        "createdAt": "2023-12-11 13:41:37",
-        "updatedAt": "2023-12-11 13:41:37",
-        "isDeleted": 0,
-        "serial": 0,
-        "labelName": "安全管控",
-        "workshopModule": {
-          "id": 1,
-          "name": "危险点",
-          "code": "1",
-          "remark": "",
-          "status": 0,
-          "createdAt": "2023-12-22 11:43:54",
-          "updatedAt": "2023-12-22 11:43:54",
-          "isDeleted": 0
-        },
-        "children": []
-      }
-    ],
-    "labelList": [],
-    "moduleList": []
-  },
-  {
-    "id": 4,
-    "parentId": 1,
-    "name": "北研中心",
-    "code": "beiyan",
-    "remark": "",
-    "status": 0,
-    "createdAt": "2023-10-13 09:43:09",
-    "updatedAt": "2024-01-02 15:25:01",
-    "serial": 2,
-    "isDeleted": 0,
-    "children": [],
-    "labelList": [],
-    "moduleList": []
-  },
-  {
-    "id": 5,
-    "parentId": 1,
-    "name": "客服中心",
-    "code": "kefu",
-    "remark": "",
-    "status": 1,
-    "createdAt": "2023-10-17 16:56:33",
-    "updatedAt": "2024-01-02 19:22:12",
-    "serial": 3,
-    "isDeleted": 0,
-    "children": [
-      {
-        "id": 19,
-        "companyId": 5,
-        "sceneLabelId": 2,
-        "name": "配电站",
-        "code": "kf-substation",
-        "remark": "",
-        "status": 0,
-        "createdAt": "2023-12-26 11:09:22",
-        "updatedAt": "2023-12-26 11:09:22",
-        "isDeleted": 0,
-        "serial": 0,
-        "labelName": "安全管控",
-        "workshopModule": {
-          "id": 1,
-          "name": "危险点",
-          "code": "1",
-          "remark": "",
-          "status": 0,
-          "createdAt": "2023-12-22 11:43:54",
-          "updatedAt": "2023-12-22 11:43:54",
-          "isDeleted": 0
-        },
-        "children": []
-      },
-      {
-        "id": 20,
-        "companyId": 5,
-        "sceneLabelId": 2,
-        "name": "气瓶间",
-        "code": "kf-gcr",
-        "remark": "",
-        "status": 0,
-        "createdAt": "2023-12-26 11:09:59",
-        "updatedAt": "2023-12-26 11:09:59",
-        "isDeleted": 0,
-        "serial": 0,
-        "labelName": "安全管控",
-        "workshopModule": {
-          "id": 2,
-          "name": "厂房",
-          "code": "2",
-          "remark": "",
-          "status": 0,
-          "createdAt": "2023-12-22 11:44:06",
-          "updatedAt": "2023-12-22 11:44:06",
-          "isDeleted": 0
-        },
-        "children": []
-      },
-      {
-        "id": 21,
-        "companyId": 5,
-        "sceneLabelId": 2,
-        "name": "柴油发电机",
-        "code": "kf-dg",
-        "remark": "",
-        "status": 0,
-        "createdAt": "2023-12-26 11:10:19",
-        "updatedAt": "2023-12-26 11:10:19",
-        "isDeleted": 0,
-        "serial": 0,
-        "labelName": "安全管控",
-        "workshopModule": {
-          "id": 2,
-          "name": "厂房",
-          "code": "2",
-          "remark": "",
-          "status": 0,
-          "createdAt": "2023-12-22 11:44:06",
-          "updatedAt": "2023-12-22 11:44:06",
-          "isDeleted": 0
-        },
-        "children": []
-      },
-      {
-        "id": 22,
-        "companyId": 5,
-        "sceneLabelId": 2,
-        "name": "运行支持指挥中心",
-        "code": "kf-qrh",
-        "remark": "",
-        "status": 0,
-        "createdAt": "2023-12-26 11:10:40",
-        "updatedAt": "2024-01-16 15:01:28",
-        "isDeleted": 0,
-        "serial": 0,
-        "labelName": "安全管控",
-        "workshopModule": {
-          "id": 2,
-          "name": "厂房",
-          "code": "2",
-          "remark": "",
-          "status": 0,
-          "createdAt": "2023-12-22 11:44:06",
-          "updatedAt": "2023-12-22 11:44:06",
-          "isDeleted": 0
-        },
-        "children": []
-      },
-      {
-        "id": 23,
-        "companyId": 5,
-        "sceneLabelId": 2,
-        "name": "C919飞行模拟机",
-        "code": "kf-sl",
-        "remark": "",
-        "status": 0,
-        "createdAt": "2023-12-26 11:11:00",
-        "updatedAt": "2024-01-17 08:51:47",
-        "isDeleted": 0,
-        "serial": 0,
-        "labelName": "安全管控",
-        "workshopModule": {
-          "id": 2,
-          "name": "厂房",
-          "code": "2",
-          "remark": "",
-          "status": 0,
-          "createdAt": "2023-12-22 11:44:06",
-          "updatedAt": "2023-12-22 11:44:06",
-          "isDeleted": 0
-        },
-        "children": []
-      }
-    ],
-    "labelList": [],
-    "moduleList": []
-  },
-  {
-    "id": 2,
-    "parentId": 1,
-    "name": "上飞厂",
-    "code": "shangfei",
-    "remark": "",
-    "status": 0,
-    "createdAt": "2023-10-13 09:42:21",
-    "updatedAt": "2024-01-02 19:22:12",
-    "serial": 4,
-    "isDeleted": 0,
-    "children": [
-      {
-        "id": 1,
-        "companyId": 2,
-        "sceneLabelId": 1,
-        "name": "ARJ21部装车间",
-        "code": "C12",
-        "remark": "",
-        "status": 0,
-        "createdAt": "2023-10-13 09:48:58",
-        "updatedAt": "2024-01-16 15:00:46",
-        "isDeleted": 0,
-        "serial": 0,
-        "labelName": "生产安全",
-        "workshopModule": {
-          "id": 2,
-          "name": "厂房",
-          "code": "2",
-          "remark": "",
-          "status": 0,
-          "createdAt": "2023-12-22 11:44:06",
-          "updatedAt": "2023-12-22 11:44:06",
-          "isDeleted": 0
-        },
-        "children": [
-          {
-            "id": 2,
-            "workshopId": 1,
-            "name": "西侧200室内气密试验区",
-            "code": "C12-W200test",
-            "remark": "",
-            "principal": "",
-            "status": 0,
-            "createdAt": "2023-12-27 14:07:15",
-            "updatedAt": "2024-01-05 09:05:52",
-            "isDeleted": 0,
-            "serial": 0
-          },
-          {
-            "id": 1,
-            "workshopId": 1,
-            "name": "东侧200室内气密试验区",
-            "code": "C12-E200test",
-            "remark": "",
-            "principal": "",
-            "status": 0,
-            "createdAt": "2023-12-27 14:06:46",
-            "updatedAt": "2024-01-05 09:05:52",
-            "isDeleted": 0,
-            "serial": 1
-          }
-        ]
-      },
-      {
-        "id": 3,
-        "companyId": 2,
-        "sceneLabelId": 1,
-        "name": "C919部装车间",
-        "code": "C02",
-        "remark": "",
-        "status": 0,
-        "createdAt": "2023-10-13 09:50:31",
-        "updatedAt": "2024-01-16 15:00:52",
-        "isDeleted": 0,
-        "serial": 0,
-        "labelName": "生产安全",
-        "workshopModule": {
-          "id": 2,
-          "name": "厂房",
-          "code": "2",
-          "remark": "",
-          "status": 0,
-          "createdAt": "2023-12-22 11:44:06",
-          "updatedAt": "2023-12-22 11:44:06",
-          "isDeleted": 0
-        },
-        "children": []
-      },
-      {
-        "id": 6,
-        "companyId": 2,
-        "sceneLabelId": 1,
-        "name": "胶接车间",
-        "code": "B16",
-        "remark": "",
-        "status": 0,
-        "createdAt": "2023-10-13 09:51:42",
-        "updatedAt": "2024-01-16 15:00:57",
-        "isDeleted": 0,
-        "serial": 0,
-        "labelName": "生产安全",
-        "workshopModule": {
-          "id": 2,
-          "name": "厂房",
-          "code": "2",
-          "remark": "",
-          "status": 0,
-          "createdAt": "2023-12-22 11:44:06",
-          "updatedAt": "2023-12-22 11:44:06",
-          "isDeleted": 0
-        },
-        "children": []
-      },
-      {
-        "id": 7,
-        "companyId": 2,
-        "sceneLabelId": 1,
-        "name": "复材车间",
-        "code": "B01",
-        "remark": "",
-        "status": 0,
-        "createdAt": "2023-10-13 09:52:02",
-        "updatedAt": "2024-01-16 15:00:59",
-        "isDeleted": 0,
-        "serial": 0,
-        "labelName": "生产安全",
-        "workshopModule": null,
-        "children": []
-      },
-      {
-        "id": 8,
-        "companyId": 2,
-        "sceneLabelId": 1,
-        "name": "工装中心",
-        "code": "B04",
-        "remark": "",
-        "status": 0,
-        "createdAt": "2023-10-13 09:53:01",
-        "updatedAt": "2023-10-13 09:53:01",
-        "isDeleted": 0,
-        "serial": 0,
-        "labelName": "生产安全",
-        "workshopModule": null,
-        "children": []
-      },
-      {
-        "id": 9,
-        "companyId": 2,
-        "sceneLabelId": 2,
-        "name": "B16热压罐",
-        "code": "B16autoclave",
-        "remark": "",
-        "status": 0,
-        "createdAt": "2023-10-13 10:22:20",
-        "updatedAt": "2023-10-19 19:12:27",
-        "isDeleted": 0,
-        "serial": 0,
-        "labelName": "安全管控",
-        "workshopModule": null,
-        "children": []
-      },
-      {
-        "id": 10,
-        "companyId": 2,
-        "sceneLabelId": 2,
-        "name": "B01热压罐",
-        "code": "B01autoclave",
-        "remark": "",
-        "status": 0,
-        "createdAt": "2023-10-13 10:22:39",
-        "updatedAt": "2023-10-13 10:22:39",
-        "isDeleted": 0,
-        "serial": 0,
-        "labelName": "安全管控",
-        "workshopModule": null,
-        "children": []
-      },
-      {
-        "id": 11,
-        "companyId": 2,
-        "sceneLabelId": 2,
-        "name": "110KV变电站",
-        "code": "110KVsubstation",
-        "remark": "",
-        "status": 0,
-        "createdAt": "2023-10-13 10:23:02",
-        "updatedAt": "2023-10-13 10:23:02",
-        "isDeleted": 0,
-        "serial": 0,
-        "labelName": "安全管控",
-        "workshopModule": null,
-        "children": []
-      },
-      {
-        "id": 12,
-        "companyId": 2,
-        "sceneLabelId": 2,
-        "name": "2011锅炉房",
-        "code": "2011boiler",
-        "remark": "",
-        "status": 0,
-        "createdAt": "2023-10-13 10:23:20",
-        "updatedAt": "2023-10-13 10:23:20",
-        "isDeleted": 0,
-        "serial": 0,
-        "labelName": "安全管控",
-        "workshopModule": {
-          "id": 1,
-          "name": "危险点",
-          "code": "1",
-          "remark": "",
-          "status": 0,
-          "createdAt": "2023-12-22 11:43:54",
-          "updatedAt": "2023-12-22 11:43:54",
-          "isDeleted": 0
-        },
-        "children": []
-      },
-      {
-        "id": 13,
-        "companyId": 2,
-        "sceneLabelId": 2,
-        "name": "2001a锅炉房",
-        "code": "2001aboiler",
-        "remark": "",
-        "status": 0,
-        "createdAt": "2023-10-13 10:23:36",
-        "updatedAt": "2023-10-13 10:23:36",
-        "isDeleted": 0,
-        "serial": 0,
-        "labelName": "安全管控",
-        "workshopModule": {
-          "id": 1,
-          "name": "危险点",
-          "code": "1",
-          "remark": "",
-          "status": 0,
-          "createdAt": "2023-12-22 11:43:54",
-          "updatedAt": "2023-12-22 11:43:54",
-          "isDeleted": 0
-        },
-        "children": []
-      },
-      {
-        "id": 15,
-        "companyId": 2,
-        "sceneLabelId": 2,
-        "name": "增材实验室",
-        "code": "sf-additive_lab",
-        "remark": "",
-        "status": 0,
-        "createdAt": "2023-12-11 13:40:33",
-        "updatedAt": "2023-12-11 13:40:33",
-        "isDeleted": 0,
-        "serial": 0,
-        "labelName": "安全管控",
-        "workshopModule": {
-          "id": 1,
-          "name": "危险点",
-          "code": "1",
-          "remark": "",
-          "status": 0,
-          "createdAt": "2023-12-22 11:43:54",
-          "updatedAt": "2023-12-22 11:43:54",
-          "isDeleted": 0
-        },
-        "children": []
-      },
-      {
-        "id": 2,
-        "companyId": 2,
-        "sceneLabelId": 1,
-        "name": "ARJ21总装车间",
-        "code": "C11",
-        "remark": "",
-        "status": 0,
-        "createdAt": "2023-10-13 09:49:31",
-        "updatedAt": "2024-01-16 15:00:48",
-        "isDeleted": 0,
-        "serial": 1,
-        "labelName": "生产安全",
-        "workshopModule": {
-          "id": 2,
-          "name": "厂房",
-          "code": "2",
-          "remark": "",
-          "status": 0,
-          "createdAt": "2023-12-22 11:44:06",
-          "updatedAt": "2023-12-22 11:44:06",
-          "isDeleted": 0
-        },
-        "children": []
-      },
-      {
-        "id": 4,
-        "companyId": 2,
-        "sceneLabelId": 1,
-        "name": "C919总装车间",
-        "code": "C01",
-        "remark": "",
-        "status": 0,
-        "createdAt": "2023-10-13 09:50:53",
-        "updatedAt": "2024-01-16 15:00:54",
-        "isDeleted": 0,
-        "serial": 1,
-        "labelName": "生产安全",
-        "workshopModule": {
-          "id": 2,
-          "name": "厂房",
-          "code": "2",
-          "remark": "",
-          "status": 0,
-          "createdAt": "2023-12-22 11:44:06",
-          "updatedAt": "2023-12-22 11:44:06",
-          "isDeleted": 0
-        },
-        "children": []
-      },
-      {
-        "id": 5,
-        "companyId": 2,
-        "sceneLabelId": 1,
-        "name": "维修交付中心",
-        "code": "repair",
-        "remark": "",
-        "status": 0,
-        "createdAt": "2023-10-13 09:51:22",
-        "updatedAt": "2024-01-16 15:00:55",
-        "isDeleted": 0,
-        "serial": 2,
-        "labelName": "生产安全",
-        "workshopModule": {
-          "id": 2,
-          "name": "厂房",
-          "code": "2",
-          "remark": "",
-          "status": 0,
-          "createdAt": "2023-12-22 11:44:06",
-          "updatedAt": "2023-12-22 11:44:06",
-          "isDeleted": 0
-        },
-        "children": []
-      }
-    ],
-    "labelList": [
-      {
-        "id": 1,
-        "name": "生产安全",
-        "code": "1",
-        "remark": "11",
-        "status": 0,
-        "createdAt": "2023-12-22 11:42:52",
-        "updatedAt": "2024-01-16 15:00:11",
-        "isDeleted": 0
-      },
-      {
-        "id": 2,
-        "name": "安全管控",
-        "code": "2",
-        "remark": "",
-        "status": 0,
-        "createdAt": "2023-12-27 13:49:28",
-        "updatedAt": "2024-01-16 15:00:28",
-        "isDeleted": 0
-      }
-    ],
-    "moduleList": [
-      {
-        "id": 1,
-        "name": "生产安全模板",
-        "code": "12",
-        "remark": "32437857",
-        "status": 0,
-        "createdAt": "2023-12-22 11:43:05",
-        "updatedAt": "2024-01-04 14:37:40",
-        "isDeleted": 0
-      },
-      {
-        "id": 1,
-        "name": "生产安全模板",
-        "code": "12",
-        "remark": "32437857",
-        "status": 0,
-        "createdAt": "2023-12-22 11:43:05",
-        "updatedAt": "2024-01-04 14:37:40",
-        "isDeleted": 0
-      }
-    ]
-  }
-]