zhudie 2 anni fa
parent
commit
39d248ebf0

+ 18 - 8
src/hooks/useSceneInfos.ts

@@ -60,14 +60,24 @@ export function useSceneInfos() {
 
   const getCameraList = (workshop: number) => {
     return getCamerasByWorkSpace({ workshopId: workshop }).then((res) => {
-      res[0].cameraList.push({
-        name: 'C204',
-        code: 'C204',
-        cameraIp: '192.168.1.203',
-        remark: '',
-        status: 0,
-        pushstreamIp: 'http://192.168.1.138:8080/live/C203.flv',
-      });
+      res[0]?.cameraList?.push(
+        {
+          name: 'C204',
+          code: 'C204',
+          cameraIp: '192.168.1.203',
+          remark: '',
+          status: 0,
+          pushstreamIp: 'http://192.168.1.138:8080/live/C203.flv',
+        },
+        {
+          name: 'C205',
+          code: 'C205',
+          cameraIp: '192.168.1.203',
+          remark: '',
+          status: 0,
+          pushstreamIp: 'http://192.168.1.138:8080/live/C203.flv',
+        },
+      );
       return res;
     });
   };

+ 106 - 203
src/views/map-config/mini-map/MapBase/KonvaMap.vue

@@ -1,25 +1,25 @@
 <template>
   <div>
-    <v-stage :config="stageConfig" @click="handleStageClick">
+    <v-stage ref="stageAll" :config="stageConfig" @click="handleStageClick">
       <v-layer ref="layer">
-        <v-image :config="bgConfig" v-show="props.bgImgUrl" />
+        <v-image :config="bgConfig" v-show="bgImgUrl" />
         <v-group
           v-for="camera in cameras"
           :key="camera.id"
           :id="camera.id"
           :attrs="camera"
-          :config="groupConfig"
-          @click="(e) => handleCameraClick(camera, e)"
-          @mouseover="(e) => handleMouseOver(camera, e)"
-          @mouseleave="(e) => handleMouseLeave(camera, e)"
-          @dragstart="(e) => handleDragStart(camera, e)"
+          :config="camera.groupConfig"
+          @click="handleCameraClick(camera)"
+          @mouseover="(e) => handleMouseOver(e)"
+          @mouseleave="handleMouseLeave()"
+          @dragstart="handleDragStart()"
         >
-          <v-image :config="camera.config" @dragend="(e) => handleCameraDragEnd(camera, e)" />
+          <v-image :config="camera.config" />
           <!-- <v-image :config="defaultIconConfig2" /> -->
           <v-image v-if="camera.isDefault" ref="defaultIcon" :config="defaultIconConfig" />
         </v-group>
-        <v-image ref="defaultIcon" :config="defaultIconConfig" />
-        <v-transformer ref="transformer" />
+        <!-- <v-image ref="defaultIcon" :config="defaultIconConfig" /> -->
+        <v-transformer :config="transformerConfig" ref="transformer" />
       </v-layer>
     </v-stage>
     <!-- <OptBar :disabled="defaultShow" /> -->
@@ -39,55 +39,46 @@
 </template>
 
 <script setup lang="ts">
-  import { ref, onMounted, onBeforeUnmount, watch, nextTick } from 'vue';
-  import Konva from 'konva';
+  import { ref, onMounted, onBeforeUnmount, watch } from 'vue';
   import { ElMessage } from 'element-plus';
-  import OptBar from '../components/CameraOptBar.vue';
   import { useGlobSetting } from '@/hooks/setting';
   import DefaultTip from '../components/DefaultTip.vue';
   import urlJoin from 'url-join';
   import cameraImgSrc from '@/assets/camera/cameraImg.png';
-  // import cameraImg from '@/assets/camera/cameraImg.png';
   import favoritesImgSrc from '@/assets/camera/favorites.png';
   import { TipPositionEnum } from '../type';
-  // import { nextTick } from 'process';
-  // import { watch } from 'fs';
-
-  const props = defineProps<{
-    bgImgUrl?: string;
-    bar?: number;
-  }>();
 
   const globSetting = useGlobSetting();
 
+  const emit = defineEmits(['changeDefaultCarema', 'delete']);
+
   interface caremasImgType {
-    width: number;
-    height: number;
-    image: HTMLImageElement;
-    name: string;
+    x?: number;
+    y?: number;
+    width?: number;
+    height?: number;
+    draggable?: boolean;
+    rotation?: number;
+    scaleX?: number;
+    scaleY?: number;
+    image?: HTMLImageElement;
+    name?: string;
+    url?: string;
   }
 
   interface caremasGroupType {
     id?: string;
+    groupConfig: caremasImgType;
     config: caremasImgType;
     isDefault?: boolean;
   }
 
-  // const stageWidth = ref<number>(800);
-
-  // const stageHeight = ref<number>(600);
-
   const stageConfig = ref({
     width: 800,
     height: 600,
-    fill: 'red',
-    // background: red,
   });
 
-  const cameraConfig = {};
-
   const bgImg = new Image();
-  const cameraImg = new Image();
   const favoritesImg = new Image();
   favoritesImg.src = favoritesImgSrc;
 
@@ -98,15 +89,13 @@
   const posTipX = ref<number>();
   const posTipY = ref<number>();
   const pos = ref(TipPositionEnum.TOP);
-  //可能的默认相机
-  const caremaIdMay = ref('');
+  //上一次点击的相机
   const lastClickedGroupId = ref<string | null>(null);
 
-  const bgImgUrl = ref('');
+  const bgImgUrl = ref<string | null>('');
   const cameras = ref<caremasGroupType[]>([]);
   //默认相机id
   const defaultCameraId = ref('');
-  const defaultIconVisible = ref(false);
   const tipShow = ref(false);
 
   //标签
@@ -125,41 +114,13 @@
     backgroundSize: 'cover',
   });
 
-  // watch(
-  //   () => props.bgImgUrl,
-  //   (newValue) => {
-  //     console.log('22', newValue);
-  //     const stage = transformer.value.getNode().getStage();
-  //     const bg = stage.findOne('#bgImg');
-  //     // attrs.height;
-  //     console.log('bg', bg);
-  //     nextTick(() => {
-  //       console.log('height', bg.attrs.height);
-  //       console.log('width', bg.attrs.width);
-  //     });
-  //   },
-  //   // { immediate: true },
-  // );
+  const transformerConfig = ref({ keepRatio: true, rotateAnchorOffset: 30 });
+
   const resizeContainer = (width, height) => {
-    // const newWidth = width > initWidth ? width : initWidth;
-    // const newHeight = height > initHeight ? height : initHeight;
-    // stage?.width(newWidth);
-    // stage?.height(newHeight);
-    // console.log('width', width);
-    // console.log('height', height);
-    // stageWidth.value = width;
-    // stageHeight.value = height;
     stageConfig.value.width = width;
     stageConfig.value.height = height;
   };
 
-  const groupConfig = ref({
-    x: 50,
-    y: 50,
-    draggable: true,
-    name: 'group',
-  });
-
   const defaultIconConfig = ref({
     x: 18,
     y: -16,
@@ -167,14 +128,9 @@
     height: 16,
     id: 'defaultIcon',
     image: favoritesImg,
-    // visible: defaultIconVisible.value,
   });
 
-  // const setDefaultCamera = () => {
-  //   defaultShow.value = false;
-  // };
-
-  const handleMouseOver = (camera, e) => {
+  const handleMouseOver = (e) => {
     document.oncontextmenu = () => {
       return false;
     };
@@ -210,77 +166,54 @@
       // createDefaultTip(x, y, pos);
     }
   };
-  const handleMouseLeave = (camera, e) => {
+  const handleMouseLeave = () => {
     document.oncontextmenu = () => {
       return true;
     };
     tipShow.value = false;
   };
 
-  const handleDragStart = (camera, e) => {
-    // document.oncontextmenu = () => {
-    //   return true;
-    // };
+  const handleDragStart = () => {
     tipShow.value = false;
   };
 
   const handleStageClick = (e: any) => {
-    console.log('e', e.target);
-    console.log('e', e.target.parent);
     defaultShow.value = false;
-    // const clickedNode = e.target;
     document.oncontextmenu = () => {
       return false;
     };
     const parent = e.target.parent;
     if (parent.hasName('group')) {
       lastClickedGroupId.value = parent.id();
-      console.log('group');
+      // 判断是否为右键点击
+      if (e.evt.button === 2) {
+        lastClickedGroupId.value = parent.id();
+        posX.value = e.evt.offsetX + 20;
+        posY.value = e.evt.offsetY;
+        defaultShow.value = defaultCameraId.value !== parent.id();
+      }
     } else {
-      console.log('stage');
+      lastClickedGroupId.value = null;
       //取消transformer选择
       const transformerNode = transformer.value.getNode();
       transformerNode.nodes([]);
     }
-
-    // 判断是否为右键点击
-    if (e.evt.button === 2) {
-      console.log('右击');
-      console.log(parent.id());
-      // groupSelect =
-      caremaIdMay.value = parent.id();
-      posX.value = e.evt.offsetX + 20;
-      posY.value = e.evt.offsetY;
-      defaultShow.value = defaultCameraId.value !== parent.id();
-      console.log(defaultShow.value);
-    }
   };
 
-  const handleCameraClick = (camera: any, event) => {
+  const handleCameraClick = (camera) => {
     tipShow.value = false;
     const transformerNode = transformer.value.getNode();
     const stage = transformerNode.getStage();
     const cameraNode = stage.findOne('#' + camera.id);
-    console.log('cameraNode', cameraNode);
 
     // 将变换器附加到点击的相机
     transformerNode.nodes([cameraNode]);
     transformerNode.moveToTop();
-    // camera.transformer = transformerNode;
-  };
-
-  const deleteCamera = () => {
-    const index = cameras.value.findIndex((camera) => camera.id === activeCameraId.value);
-    if (index === -1) return;
-    const updatedCameras = [...cameras.value];
-    updatedCameras.splice(index, 1);
-    cameras.value = updatedCameras;
   };
 
   const addCamera = (id: string) => {
     const existingCamera = cameras.value.find((camera) => camera.id === id);
     if (existingCamera) return;
-
     const camImg = new Image();
     camImg.src = cameraImgSrc;
     const config = {
@@ -288,14 +221,23 @@
       height: 37,
       image: camImg,
       name: 'image',
+      id: id,
+    };
+    const groupConfig = {
+      x: 50,
+      y: 50,
+      draggable: true,
+      name: 'group',
     };
     const cameraDetail = {
       id,
+      groupConfig,
       config,
       isDefault: false,
     };
     cameras.value.push(cameraDetail);
-    //可以加入判断,当只有一个相机时,自动设置默认相机
+
+    //当只有一个相机时,自动设置默认相机
     if (cameras.value.length === 1) {
       cameras.value[0].isDefault = true;
       defaultCameraId.value = id;
@@ -304,7 +246,7 @@
 
   const setDefaultCamera = () => {
     //选中的相机id号
-    defaultCameraId.value = caremaIdMay.value;
+    defaultCameraId.value = lastClickedGroupId.value!;
     cameras.value.forEach((item) => {
       if (item.id === defaultCameraId.value) {
         item.isDefault = true;
@@ -315,124 +257,85 @@
     defaultShow.value = false;
   };
 
-  const handleCameraDragEnd = (camera: any, e: any) => {
-    // if (camera.id === defaultCameraId.value) {
-    //   const tr = layer.findOne(`#tr_${camera.id}`);
-    //   tr.nodes([e.target]);
-    //   layer.batchDraw();
-    // }
-  };
-
-  const handleFileChange = (e: any) => {
-    const file = e.target.files[0];
-    if (!file) return;
-    const reader = new FileReader();
-    reader.onload = (event) => {
-      bgImgUrl.value = event.target?.result;
-      // addBg();
-    };
-    reader.readAsDataURL(file);
-  };
-
   const addBg = (imgBg) => {
-    bgImgUrl.value = urlJoin(globSetting.imgUrl!, imgBg) as string;
-
-    bgImg.src = bgImgUrl.value;
-    console.log('bgmin', bgImg);
-
+    bgImgUrl.value = imgBg;
+    bgImg.src = urlJoin(globSetting.imgUrl!, imgBg) as string;
     bgImg.onload = () => {
-      // const bgNode = layer.value?.findOne('#bgImg') as any;
       bgConfig.value.width = bgImg.width;
       bgConfig.value.height = bgImg.height;
-      // stageConfig.value.width = bgImg.width;
-      // stageConfig.value.height = bgImg.height;
       resizeContainer(bgImg.width, bgImg.height);
-      console.log('bgImg.width', bgImg.width);
-      console.log('bgImg.height', bgImg.height);
-      console.log('stageConfig', stageConfig.value);
-      console.log('bgConfig', bgConfig.value);
     };
   };
 
   const saveLayout = () => {
+    const stage = transformer.value.getNode().getStage();
+    const groups = stage.find('.group');
+    const camerasList = groups.map((item, index) => {
+      cameras.value[index].groupConfig.x = Math.round(item.attrs.x | 0);
+      cameras.value[index].groupConfig.y = Math.round(item.attrs.y | 0);
+      cameras.value[index].groupConfig.rotation = Number((item.attrs.rotation | 0).toFixed(2));
+      cameras.value[index].groupConfig.scaleX = Number((item.attrs.scaleX | 1).toFixed(1));
+      cameras.value[index].groupConfig.scaleY = Number((item.attrs.scaleY | 1).toFixed(1));
+      cameras.value[index].config.url = cameraImgSrc;
+      return cameras.value[index];
+    });
+    cameras.value = camerasList;
     const layout = {
-      bgInfo: {
-        bgImg: bgImgUrl.value,
-        width: bgImg.width,
-        height: bgImg.height,
-      },
+      stageConfig: stageConfig.value,
+      bgConfig: bgConfig.value,
+      bgImgUrl: bgImgUrl.value,
       defaultCameraId: defaultCameraId.value,
       cameraList: cameras.value,
     };
-    const jsonString = JSON.stringify(layout);
-    console.log(jsonString);
-    // Here you can do something with the layout JSON string, such as sending it to a server or saving it locally
+    return JSON.stringify(layout);
+  };
+
+  //删除相机
+  const handleKeyDown = (e) => {
+    if (e.keyCode === 46 || e.code === 'Delete') {
+      if (lastClickedGroupId.value === defaultCameraId.value) {
+        ElMessage.error({
+          message: '无法删除默认相机',
+        });
+        return;
+      }
+      const index = cameras.value.findIndex((item) => item.id === lastClickedGroupId.value);
+      index >= 0 && cameras.value.splice(index, 1);
+      //取消transformer
+      const transformerNode = transformer.value.getNode();
+      transformerNode.nodes([]);
+    }
   };
-  const handleKeyDown = () => {};
 
   //重置
   const resetMap = () => {
-    bgImgUrl.value = '';
-    // defaultIcon?.moveTo(copyLayer);
-    // layer?.clear();
-    // layer?.removeChildren();
-    // defaultIcon?.moveTo(layer);
-    // addedCameras.value = [];
-    // activeGroup.value = null;
-    // defaultCameraId.value = '';
-    // isTransform = false;
-    // bgImgUrl.value = '';
+    bgImgUrl.value = null;
+    addBg('');
+    cameras.value = [];
+    lastClickedGroupId.value = null;
+    defaultCameraId.value = '';
   };
 
   /** 导入布局json */
   const createMap = (layout) => {
-    // bgImgUrl.value = layout.bgInfo.bgImg;
-
-    // console.log('bgImgUrl.value11 ', bgImgUrl.value);
-    console.log('layout.bgInfo.bgImg', layout.bgInfo.bgImg);
-
-    addBg(layout.bgInfo.bgImg);
-    // layout.cameraList.forEach((camera) => {
-    //   const group = new Konva.Group({
-    //     x: camera.x,
-    //     y: camera.y,
-    //     id: camera.cameraId,
-    //     rotation: camera.rotation,
-    //     scaleX: camera.scaleX,
-    //     scaleY: camera.scaleY,
-    //     draggable: false,
-    //     name: 'group',
-    //   });
-    //   const camImg = new Image();
-    //   camImg.onload = () => {
-    //     const cameraIcon = new Konva.Image({
-    //       width: 52,
-    //       height: 37,
-    //       image: camImg,
-    //       name: 'image',
-    //     });
-    //     group.add(cameraIcon);
-    //     layer?.add(group);
-    //     bindBaseEvt(cameraIcon);
-    //     addedCameras.value.push(camera.cameraId);
-
-    //     if (camera.cameraId === layout.defaultCameraId) {
-    //       setDefaultCamera(group);
-    //       defaultIcon?.show();
-    //     }
-
-    //     if (addedCameras.value.length === layout.cameraList.length) {
-    //       layer?.batchDraw();
-    //     }
-    //   };
-    //   camImg.src = cameraImg;
-    // });
+    addBg(layout.bgImgUrl);
+    stageConfig.value = layout.stageConfig;
+    const camImg = new Image();
+    camImg.src = cameraImgSrc;
+    defaultCameraId.value = layout.defaultCameraId;
+    layout.cameraList = layout.cameraList?.map((item) => {
+      item.config.image = camImg;
+      return item;
+    });
+    cameras.value = layout.cameraList;
   };
 
-  defineExpose({ addBg, createMap, resetMap, addCamera, resizeContainer });
+  watch();
+
+  defineExpose({ addBg, createMap, resetMap, addCamera, resizeContainer, saveLayout });
 
   onMounted(() => {
-    // Add initial cameras, if needed
+    window.addEventListener('keydown', handleKeyDown);
   });
 
   onBeforeUnmount(() => {

+ 21 - 17
src/views/map-config/mini-map/MiniMapConfig.vue

@@ -84,7 +84,7 @@
       </div>
       <!-- <div ref="drawContainer" id="drawContainer" class="draw-container"> -->
       <div ref="drawContainer" class="draw-container">
-        <KonvaMap ref="konvaMap" :bg-img-url="imgUrlBg" />
+        <KonvaMap ref="konvaMap" v-moveable:1 />
         <div id="editContainer" v-moveable:1></div>
         <el-upload
           v-if="!hasBg"
@@ -112,12 +112,12 @@
   import { updateMinMapViewLayoutApi } from '@/api/scene/scene';
   import { computed } from 'vue';
   import { Search, Refresh } from '@element-plus/icons-vue';
-  import useMapEditor from './hooks/useMapEditor';
+  // import useMapEditor from './hooks/useMapEditor';
   import KonvaMap from './MapBase/KonvaMap.vue';
   // import { nextTick } from 'process';
 
-  const mapEditor = useMapEditor();
-  const { activeCameraId, addedCameras, bgImgUrl } = mapEditor;
+  // const mapEditor = useMapEditor();
+  // const { activeCameraId, addedCameras, bgImgUrl } = mapEditor;
   const miniMap = useMiniMap();
   const { scenesTree, shopCameraList, selectedShopCode, selectedShopDetail } = storeToRefs(miniMap);
   const { getScenesTree, getShowCameras, getMapLayout } = miniMap;
@@ -144,13 +144,13 @@
 
   /** 判断相机是否已经添加 */
   const isAddedCamera = (cameraId: string) => {
-    const index = addedCameras.value.findIndex((item) => item === cameraId);
-    const indexRe = camerasAdded.value.findIndex((item) => item === cameraId);
-    return indexRe >= 0;
+    // const index = addedCameras.value.findIndex((item) => item === cameraId);
+    const index = camerasAdded.value.findIndex((item) => item === cameraId);
+    return index >= 0;
   };
 
   const handleAvatarSuccess = (e) => {
-    bgImgUrl.value = e.data;
+    // bgImgUrl.value = e.data;
     //自己的
     imgUrlBg.value = e.data;
     console.log('imgUrlBg.value1', imgUrlBg.value);
@@ -161,32 +161,35 @@
   };
 
   const changeShop = (code: string) => {
-    mapEditor.resetMap();
+    // mapEditor.resetMap();
     konvaMap.value.resetMap();
     getShopContent(code);
     hasBg.value = false;
   };
 
   const getShopContent = (code: string) => {
+    console.log('getcode', code);
+
     getShowCameras(code);
     getMapLayout(code).then((res) => {
       if (!res) {
         return;
       }
       hasBg.value = true;
+      console.log('res.bgInfo.bgImg', res);
       konvaMap.value.createMap(res);
-      imgUrlBg.value = res.bgInfo.bgImg;
+
+      // imgUrlBg.value = res.bgInfo.bgImg;
       // console.log();
 
-      console.log('res.bgInfo.bgImg', res.bgInfo.bgImg);
-      mapEditor.createMap(res);
+      // mapEditor.createMap(res);
     });
   };
 
   const handleWholeClick = (e) => {
-    if (e.button === 0) {
-      mapEditor.destoryOptBlock();
-    }
+    // if (e.button === 0) {
+    //   mapEditor.destoryOptBlock();
+    // }
   };
 
   onMounted(() => {
@@ -224,12 +227,13 @@
       return;
     }
     konvaMap.value.addCamera(cameraId);
-    mapEditor.addCamera(cameraId);
+    // mapEditor.addCamera(cameraId);
     // konvaMap.value.addCamera(cameraId);
   };
 
   const handleSave = () => {
-    const layout = mapEditor.toJson();
+    // const layout = mapEditor.toJson();
+    const layout = konvaMap.value.saveLayout();
     updateMinMapViewLayoutApi({ layout, targetId: String(selectedShopDetail.value?.id) }).then(
       (res) => {
         console.log('updateMinMapViewLayoutApi', res);

+ 1 - 1
src/views/map-config/mini-map/hooks/useMapEditor.ts

@@ -111,7 +111,7 @@ export function useMapEditor() {
     activeGroup.value?.draggable(false);
     activeGroup.value = group;
     group.draggable(true);
-    stage!.find('Transformer')[0]?.destroy(); // 清除现有transformer
+    stage?.find?.('Transformer')[0]?.destroy(); // 清除现有transformer
     const id = group.id();
     const tr = new Konva.Transformer({
       keepRatio: true,