Browse Source

Merge branch 'all-v4-fjc' into 'all-v4'

All v4 fjc

See merge request skyeye/skyeye_frontend/skyeye-admin!232
Fei Liu 1 year ago
parent
commit
d3e7b5a99b

+ 1 - 1
src/api/scene/scene.ts

@@ -23,7 +23,7 @@ export const getLayoutApi = (param: { workshopId: string; viewType: ViewType })
 };
 
 /** 查询车间小地图布局 */
-export const getWorkshopMiniMapLayoutApi = (workshopId: string) => {
+export const getWorkshopMiniMapLayoutApi = (workshopId: number) => {
   return http.request<SceneTypes.LayoutResp>({
     url: `/layout/getPcWorkshopLayout?workshopId=${workshopId}`,
     method: 'get',

+ 0 - 1
src/hooks/useSceneInfos.ts

@@ -54,7 +54,6 @@ export function useSceneInfos() {
     getShopSpaceList().then((res) => {
       scenesInfos.value = res;
       scenesTree.value = calculateTreeData(res, treeProps, 1);
-      console.log(scenesTree.value);
     });
   };
 

+ 1 - 0
src/types/scene-layout/type.ts

@@ -2,6 +2,7 @@ export interface CompanyInfoList {
   id: number;
   name: string;
   layout: string;
+  imgUrl: string;
 }
 
 export interface CompanyLayoutInfoList {

+ 9 - 3
src/types/scene/type.ts

@@ -144,6 +144,7 @@ export interface UpdateViewLayoutParam {
 
 /** ??? */
 export type CameraItem = {
+  id: number;
   /** 相机名称 */
   name: string;
   /** 相机code */
@@ -153,10 +154,16 @@ export type CameraItem = {
   /** 相机描述 */
   remark: string;
   /** 状态: 0-启用, 1-禁用 */
-  status: number;
+  status?: number;
   /** 推流地址 */
-  pushstreamIp: string;
+  pushstreamIp?: string;
 };
+export interface ShopMapCamera extends CameraItem {
+  isSet: number;
+  /** 工位名称 */
+  workSpaceName: string;
+  integrationState?: number;
+}
 
 /** ??? */
 export type WorkSpaceCameraRelative = WorkSpaceInfoItem & { cameraList: CameraItem[] };
@@ -442,7 +449,6 @@ export interface UseWorkspaceType {
 }
 /** --------------------------------------------------------------------------------- */
 
-
 // 根据车间id查工位-相机列表
 export interface GetCameraStatusByWorkshopRes {
   /*节点类型 */

+ 41 - 56
src/views/map-config/mini-map/MapBase/KonvaMap.vue

@@ -49,9 +49,7 @@
 <script setup lang="ts">
   import { ref, onMounted, onBeforeUnmount, watch } from 'vue';
   import { ElMessage, ElMessageBox } from 'element-plus';
-  import { useGlobSetting } from '@/hooks/setting';
   import DefaultTip from '../components/DefaultTip.vue';
-  import urlJoin from 'url-join';
   import cameraImgSrc from '@/assets/camera/cameraImg.png';
   import favoritesImgSrc from '@/assets/camera/favorites.png';
   import { TipPositionEnum, camerasGroupType } from '../type';
@@ -60,26 +58,13 @@
   import { storeToRefs } from 'pinia';
   import { updateMinMapViewLayoutApi } from '@/api/scene/scene';
   import CameraPreview from './CameraPreview.vue';
-
-  const globSetting = useGlobSetting();
+  import { ShopMapCamera } from '@/types/scene/type'
 
   const miniMap = useMiniMap();
   const { shopCameraList } = storeToRefs(miniMap);
 
-  interface DataType {
-    name: string;
-    code: string;
-    cameraIp: string;
-    remark: string;
-    status: number;
-    pushstreamIp: string;
-    isSet: number;
-    workSpaceName: string;
-    integrationState?: number;
-  }
-
   const emit = defineEmits(['changeDefaultCamera', 'sendCameraId', 'change']);
-  const props = defineProps<{ filterData: DataType[] }>();
+  const props = defineProps<{ filterData: ShopMapCamera[] }>();
   const camImg = new Image();
 
   const stageConfig = ref({
@@ -117,7 +102,7 @@
   const transformer = ref();
   const defaultIcon = ref();
 
-  function addIntegrationState(data: camerasGroupType[], updateData: DataType[]) {
+  function addIntegrationState(data: camerasGroupType[], updateData: ShopMapCamera[]) {
     for (let i = 0; i < data.length; i++) {
       const camera = data[i];
       const matchedCamera = updateData.find((item) => item.code === camera.id);
@@ -395,40 +380,40 @@
   };
 
   //删除相机
-  const handleKeyDown = (e) => {
-    if (e.keyCode === 46 || e.code === 'Delete' || e.keyCode === 8 || e.code === 'Backspace') {
-      if (lastClickedGroupId.value === defaultCameraId.value) {
-        // ElMessage.error({
-        //   message: '无法删除默认相机',
-        // });
-        // return;
-        ElMessageBox.confirm('此相机为默认相机,您确认要删除此相机?', 'Warning', {
-          confirmButtonText: '确认',
-          cancelButtonText: '取消',
-          type: 'warning',
-        })
-          .then(() => {
-            const index = cameras.value.findIndex((item) => item.id === lastClickedGroupId.value);
-            index >= 0 && cameras.value.splice(index, 1);
-            lastClickedGroupId.value = '';
-
-            //取消transformer
-            const transformerNode = transformer.value.getNode();
-            transformerNode.nodes([]);
-          })
-          .catch(() => {});
-      } else {
-        const index = cameras.value.findIndex((item) => item.id === lastClickedGroupId.value);
-        index >= 0 && cameras.value.splice(index, 1);
-        lastClickedGroupId.value = '';
-
-        //取消transformer
-        const transformerNode = transformer.value.getNode();
-        transformerNode.nodes([]);
-      }
-      emit('change', true);
-    }
-  };
+  // const handleKeyDown = (e) => {
+  //   if (e.keyCode === 46 || e.code === 'Delete' || e.keyCode === 8 || e.code === 'Backspace') {
+  //     if (lastClickedGroupId.value === defaultCameraId.value) {
+  //       // ElMessage.error({
+  //       //   message: '无法删除默认相机',
+  //       // });
+  //       // return;
+  //       ElMessageBox.confirm('此相机为默认相机,您确认要删除此相机?', 'Warning', {
+  //         confirmButtonText: '确认',
+  //         cancelButtonText: '取消',
+  //         type: 'warning',
+  //       })
+  //         .then(() => {
+  //           const index = cameras.value.findIndex((item) => item.id === lastClickedGroupId.value);
+  //           index >= 0 && cameras.value.splice(index, 1);
+  //           lastClickedGroupId.value = '';
+
+  //           //取消transformer
+  //           const transformerNode = transformer.value.getNode();
+  //           transformerNode.nodes([]);
+  //         })
+  //         .catch(() => {});
+  //     } else {
+  //       const index = cameras.value.findIndex((item) => item.id === lastClickedGroupId.value);
+  //       index >= 0 && cameras.value.splice(index, 1);
+  //       lastClickedGroupId.value = '';
+
+  //       //取消transformer
+  //       const transformerNode = transformer.value.getNode();
+  //       transformerNode.nodes([]);
+  //     }
+  //     emit('change', true);
+  //   }
+  // };
 
   //重置
   const resetMap = () => {
@@ -498,13 +483,13 @@
   });
 
   onMounted(() => {
-    window.addEventListener('keydown', handleKeyDown);
+    // window.addEventListener('keydown', handleKeyDown);
     camImg.src = cameraImgSrc;
   });
 
-  onBeforeUnmount(() => {
-    window.removeEventListener('keydown', handleKeyDown);
-  });
+  // onBeforeUnmount(() => {
+  //   window.removeEventListener('keydown', handleKeyDown);
+  // });
 </script>
 
 <style scoped lang="scss">

+ 418 - 403
src/views/map-config/mini-map/MiniMapConfig.vue

@@ -1,29 +1,23 @@
 <template>
   <div class="page">
     <div class="page-head flex items-center">
-      <el-icon size="20"><ArrowLeft /></el-icon>
+      <div class="page-head__btn" @click="router.back">
+        <img :src="rollback" />
+        <span>返回</span>
+      </div>
+      <!-- <el-icon size="20">
+        <ArrowLeft />
+      </el-icon> -->
       <div class="head-opt flex-1 flex justify-between items-center">
-        <div>
-          <span>场景:</span>
-          <el-tree-select
-            v-model="selectedShopCode"
-            :data="scenesTree"
-            accordion
-            :render-after-expand="false"
-            :default-expand-all="true"
-            :teleported="false"
-            placeholder="请选择相关场景"
-            @change="changeShop"
-            style="width: 200px"
-          />
+        <div class="workshop-name">{{ selectedName }}
+          <!-- <span>场景:</span>
+          <el-tree-select v-model="selectedShopCode" :data="scenesTree" accordion :render-after-expand="false"
+            :default-expand-all="true" :teleported="false" placeholder="请选择相关场景" @change="changeShop"
+            style="width: 200px" /> -->
         </div>
         <div v-if="shopCameraList.length === 1" class="upload-option">
-          <el-tooltip
-            class="box-item"
-            effect="dark"
-            content="选择'是'则表示需要上传背景图片;选择'否'则表示无需上传背景图片,直接点击保存为布局即可"
-            placement="top"
-          >
+          <el-tooltip class="box-item" effect="dark" content="选择'是'则表示需要上传背景图片;选择'否'则表示无需上传背景图片,直接点击保存为布局即可"
+            placement="top">
             <div class="upload-title">上传背景图片</div>
           </el-tooltip>
           <div class="my-2 flex items-center text-sm">
@@ -31,27 +25,17 @@
               <el-radio :label="true">是</el-radio>
               <el-radio :label="false">否</el-radio>
             </el-radio-group>
-          </div></div
-        >
+          </div>
+        </div>
         <div class="flex">
-          <el-upload
-            class="avatar-uploader flex justify-center items-center"
-            :action="actionUrl"
-            :show-file-list="false"
-            :on-success="handleAvatarSuccess"
-            :with-credentials="true"
-            name="file"
-            :headers="getHeaders()"
-          >
+          <el-upload class="avatar-uploader flex justify-center items-center" :action="actionUrl"
+            :show-file-list="false" :on-success="handleAvatarSuccess" :with-credentials="true" name="file"
+            :headers="getHeaders()">
             <el-button :icon="Refresh" :disabled="!hasBg"> 替换照片 </el-button>
           </el-upload>
 
-          <el-button
-            @click="handleSave"
-            style="margin-left: 40px"
-            type="primary"
-            :disabled="!isSave && isUploadBg"
-            >保存为布局
+          <el-button @click="handleSave" style="margin-left: 40px" type="primary"
+            :disabled="!isSave && isUploadBg">保存为布局
           </el-button>
         </div>
       </div>
@@ -60,36 +44,21 @@
       <div class="camera-list">
         <div>
           <span class="label-text flex">相机列表:</span>
-          <ElInput
-            class="search-put"
-            style="margin: 10px 0; width: 230px"
-            placeholder="请输入搜索内容"
-            v-model="searchKey"
-            :suffix-icon="Search"
-          />
+          <ElInput class="search-put" style="margin: 10px 0; width: 230px" placeholder="请输入搜索内容" v-model="searchKey"
+            :suffix-icon="Search" />
         </div>
         <span v-if="filterShopCameraList.length == 0" class="ml-1" style="color: #3f3f3f">
-          提示:请先选择相应场景和图片
+          提示:该车间还未配置相机
         </span>
         <el-scrollbar v-else style="position: relative; height: calc(100% - 90px)">
-          <div
-            v-for="item in filterShopCameraList"
-            :key="item.code"
-            class="camera-item flex justify-start items-center"
+          <div v-for="item in filterShopCameraList" :key="item.code" class="camera-item flex justify-start items-center"
             :class="{
               isAdded: isAddedCamera(item.code),
               isActive: item.code === caremaActiveId,
               integrationState: item.integrationState === 1,
-            }"
-            @click="handleAddCamera(item.code)"
-          >
+            }" @click="handleAddCamera(item.code)">
             <span class="camera-id">{{ item.name }}</span>
-            <el-popover
-              placement="bottom-start"
-              trigger="hover"
-              :content="item.name"
-              :teleported="false"
-            >
+            <el-popover placement="bottom-start" trigger="hover" :content="item.name" :teleported="false">
               <template #reference>
                 <span class="space-name">{{ item.workSpaceName }}</span>
               </template>
@@ -97,382 +66,428 @@
           </div>
         </el-scrollbar>
       </div>
-      <div
-        ref="drawContainer"
-        v-show="isUploadBg || shopCameraList.length !== 1"
-        class="draw-container"
-        :class="{ 'bg-background': hasBg ? true : false }"
-      >
-        <KonvaMap
-          ref="konvaMap"
-          :filter-data="filterShopCameraList"
-          @change-default-camera="changeDefault"
-          @send-camera-id="sendCameras"
-          @change="changeMap"
-          v-moveable:1
-        />
+      <div ref="drawContainer" v-show="isUploadBg || shopCameraList.length !== 1" class="draw-container"
+        :class="{ 'bg-background': hasBg ? true : false }">
+        <KonvaMap ref="konvaMap" :filter-data="filterShopCameraList" @change-default-camera="changeDefault"
+          @send-camera-id="sendCameras" @change="changeMap" v-moveable:1 />
         <div id="editContainer" v-moveable:1></div>
-        <el-upload
-          v-if="!hasBg"
-          class="upload-icon flex justify-center items-center"
-          :action="actionUrl"
-          :show-file-list="false"
-          :before-upload="handleBeforeUpload"
-          :on-success="handleAvatarSuccess"
-          :with-credentials="true"
-          name="file"
-          :headers="getHeaders()"
-        >
+        <el-upload v-if="!hasBg" class="upload-icon flex justify-center items-center" :action="actionUrl"
+          :show-file-list="false" :before-upload="handleBeforeUpload" :on-success="handleAvatarSuccess"
+          :with-credentials="true" name="file" :headers="getHeaders()">
           <img src="~@/assets/images/img-upload.png" />
         </el-upload>
       </div>
-      <div v-show="!isUploadBg && shopCameraList.length === 1" class="camera-one-tip"
-        >仅此一个相机,无需添加背景图片</div
-      >
+      <div v-show="!isUploadBg && shopCameraList.length === 1" class="camera-one-tip">仅此一个相机,无需添加背景图片</div>
     </div>
   </div>
 </template>
 
 <script setup lang="ts">
-  import useMiniMap from './use-mini-map';
-  import { storeToRefs } from 'pinia';
-  import { ElMessage, ElInput, ElMessageBox } from 'element-plus';
-  import { onMounted, onUnmounted, ref } from 'vue';
-  import { updateMinMapViewLayoutApi } from '@/api/scene/scene';
-  import { computed } from 'vue';
-  import { Search, Refresh, ArrowLeft } from '@element-plus/icons-vue';
-  import KonvaMap from './MapBase/KonvaMap.vue';
-  import useCameraStatus from '@/views/cameras/preview/store/useCameraStatus';
-  import { onBeforeRouteLeave } from 'vue-router';
-  import urlJoin from 'url-join';
-  import { useGlobSetting } from '@/hooks/setting';
-  import { getHeaders } from '@/utils/http/axios';
-
-  const cameraStatus = useCameraStatus();
-  const { openInterval, closeInterval } = cameraStatus;
-
-  const miniMap = useMiniMap();
-  const { scenesTree, shopCameraList, selectedShopCode, selectedShopDetail } = storeToRefs(miniMap);
-  const { getScenesTree, getShowCameras, getMapLayout } = miniMap;
-
-  const drawContainer = ref<HTMLDivElement>();
-
-  const konvaMap = ref();
-  const caremaActiveId = ref<string>('');
-  const camerasAdded = ref<string[]>([]);
-  const imgUrlBg = ref<string>('');
-
-  const searchKey = ref('');
-  // 是否已有背景图
-  const hasBg = ref(false);
-
-  //是否能够保存
-  const isSave = computed(() => selectedShopCode.value && hasBg.value);
-
-  //是否修改
-  const isChange = ref<boolean>(false);
-
-  //单个相机时是否上传图片
-  const isUploadBg = ref<boolean>(true);
-  const isMap = ref(false);
-
-  const { urlPrefix } = useGlobSetting();
-
-  const actionUrl = computed(() => {
-    return urlJoin(urlPrefix!, `/admin/minimap/uploadPicture`);
-  });
-
-  function updataState(data, updateData) {
-    for (let i = 0; i < data.length; i++) {
-      const camera = data[i];
-      const matchedCamera = updateData.find((item) => item.cameraCode === camera.code);
-      if (matchedCamera) {
-        camera.status = matchedCamera.status;
-        camera.integrationState = matchedCamera.integrationState;
-      }
+// import useMiniMap from './use-mini-map';
+// import { storeToRefs } from 'pinia';
+import { ElMessage, ElInput, ElMessageBox } from 'element-plus';
+import { onMounted, onUnmounted, ref } from 'vue';
+import { updateMinMapViewLayoutApi, getCamerasByWorkShopId, getWorkshopMiniMapLayoutApi } from '@/api/scene/scene';
+import { computed } from 'vue';
+import { Search, Refresh, ArrowLeft } from '@element-plus/icons-vue';
+import KonvaMap from './MapBase/KonvaMap.vue';
+import useCameraStatus from '@/views/cameras/preview/store/useCameraStatus';
+import { onBeforeRouteLeave, useRoute } from 'vue-router';
+import urlJoin from 'url-join';
+import { useGlobSetting } from '@/hooks/setting';
+import { getHeaders } from '@/utils/http/axios';
+import rollback from '@/assets/rollback.png'
+import router from '@/router';
+import { ShopMapCamera } from '@/types/scene/type'
+const cameraStatus = useCameraStatus();
+const { openInterval, closeInterval } = cameraStatus;
+
+// const miniMap = useMiniMap();
+// const { scenesTree, selectedShopCode, selectedShopDetail } = storeToRefs(miniMap);
+// const { getScenesTree, getMapLayout } = miniMap;
+// const { scenesTree, shopCameraList, selectedShopCode, selectedShopDetail } = storeToRefs(miniMap);
+// const { getScenesTree, getShowCameras, getMapLayout } = miniMap;
+
+const drawContainer = ref<HTMLDivElement>();
+
+const konvaMap = ref();
+const caremaActiveId = ref<string>('');
+const camerasAdded = ref<string[]>([]);
+const imgUrlBg = ref<string>('');
+
+const searchKey = ref('');
+// 是否已有背景图
+const hasBg = ref(false);
+
+//是否能够保存
+const isSave = computed(() => selectedShopId.value && hasBg.value);
+
+//是否修改
+const isChange = ref<boolean>(false);
+
+//单个相机时是否上传图片
+const isUploadBg = ref<boolean>(true);
+const isMap = ref(false);
+
+const { urlPrefix } = useGlobSetting();
+
+const actionUrl = computed(() => {
+  return urlJoin(urlPrefix!, `/admin/minimap/uploadPicture`);
+});
+
+function updataState(data, updateData) {
+  for (let i = 0; i < data.length; i++) {
+    const camera = data[i];
+    const matchedCamera = updateData.find((item) => item.cameraCode === camera.code);
+    if (matchedCamera) {
+      camera.status = matchedCamera.status;
+      camera.integrationState = matchedCamera.integrationState;
     }
   }
+}
 
-  const changeUploadBg = () => {
-    if (isUploadBg.value && !isMap.value) {
-      konvaMap.value.resetMap();
-      hasBg.value = false;
-    }
-  };
-
-  const handleBeforeUpload = () => {
-    if (!selectedShopCode.value) {
-      ElMessage.error({
-        message: '请先选择车间',
-      });
-      return false;
-    }
-  };
-  const sendCameras = (camerasList) => {
-    camerasAdded.value = camerasList.map((item) => {
-      return item.id;
-    });
-  };
-
-  /** 判断相机是否已经添加 */
-  const isAddedCamera = (cameraId: string) => {
-    const index = camerasAdded.value.findIndex((item) => item === cameraId);
-    return index >= 0;
-  };
-
-  const changeDefault = (defaultCameraId) => {
-    caremaActiveId.value = defaultCameraId;
-  };
-
-  const handleAvatarSuccess = (e) => {
-    imgUrlBg.value = e.data;
-    konvaMap.value.addBg(imgUrlBg.value);
-    hasBg.value = true;
-  };
-
-  const changeShop = (code: string) => {
+const changeUploadBg = () => {
+  if (isUploadBg.value && !isMap.value) {
     konvaMap.value.resetMap();
-    getShopContent(code);
     hasBg.value = false;
-  };
+  }
+};
 
-  const getShopContent = (code: string) => {
-    getShowCameras(code).then(() => {
-      const codeList = filterShopCameraList.value.map((item) => item.code);
-      openInterval(codeList, (targetData) => {
-        updataState(filterShopCameraList.value, targetData);
-      });
-      getMapLayout(code).then((res) => {
-        if (!res) {
-          return;
-        }
-        hasBg.value = true;
-        isMap.value = res.isUploadBg;
-        if (res.isUploadBg) {
-          isUploadBg.value = true;
-          konvaMap.value.createMap(res, selectedShopDetail.value?.id);
-        } else {
-          hasBg.value = false;
-          isUploadBg.value = res.isUploadBg;
-        }
-      });
+const handleBeforeUpload = () => {
+  if (!selectedShopId.value) {
+    ElMessage.error({
+      message: '请先选择车间',
     });
-  };
-
-  onMounted(() => {
-    getScenesTree({ level: 2, valueKey: 'code', labelKey: 'name', disabled: true });
-    konvaMap.value.resizeContainer(
-      drawContainer.value!.clientWidth,
-      drawContainer.value!.clientHeight,
-    );
-    if (selectedShopCode.value) {
-      getShopContent(selectedShopCode.value);
-    }
-  });
-
-  onUnmounted(() => {
-    closeInterval();
-  });
-
-  const filterShopCameraList = computed(() => {
-    const k = searchKey.value.trim();
-    if (!k) return shopCameraList.value;
-    return shopCameraList.value.filter(
-      (x) => x.code?.includes(k) || x.name?.includes(k) || x.workSpaceName?.includes(k),
-    );
-  });
-
-  const handleAddCamera = (cameraId: string) => {
-    if (isAddedCamera(cameraId)) {
-      const camera = konvaMap.value.findCamera(cameraId);
-      konvaMap.value.handleCameraClick(camera);
-      return;
-    }
-    if (!hasBg.value) {
-      ElMessage.warning({
-        message: '请先添加背景图片',
-      });
-      return;
-    }
-    konvaMap.value.addCamera(cameraId);
-  };
-
-  const handleSave = () => {
-    if (shopCameraList.value.length === 1 && !isUploadBg.value) {
-      isMap.value = false;
-      const layout = JSON.stringify({
-        isUploadBg: isUploadBg.value,
-        defaultCameraId: shopCameraList.value[0].code,
-      });
-      updateMinMapViewLayoutApi({
-        layout,
-        targetId: String(selectedShopDetail.value?.id),
-        viewType: 2,
-      }).then((res) => {
-        console.log('updateMinMapViewLayoutApi', res);
-        ElMessage.success('保存成功');
-      });
-    } else {
-      isMap.value = true;
-      const layout = konvaMap.value.saveLayout();
-      updateMinMapViewLayoutApi({
-        layout: JSON.stringify({ ...JSON.parse(layout), isUploadBg: true }),
-        targetId: String(selectedShopDetail.value?.id),
-        viewType: 2,
-      }).then((res) => {
-        console.log('updateMinMapViewLayoutApi', res);
-        ElMessage.success('保存成功');
-      });
-    }
-  };
-
-  const changeMap = (val) => {
-    isChange.value = val;
-  };
-
-  onBeforeRouteLeave(async () => {
-    if (isChange.value) {
-      await ElMessageBox.confirm('是否保存当前修改?', '提示', {
-        confirmButtonText: '是',
-        cancelButtonText: '否',
-        type: 'warning',
-      })
-        .then(() => {
-          handleSave();
-        })
-        .catch(() => {
-          return true;
-        });
-    } else {
-      return true;
-    }
-  });
-</script>
-
-<style scoped lang="scss">
-  .page {
+    return false;
   }
-  .page-head {
-    height: 54px;
-    padding-left: 15px;
-    background-color: #ffffff;
-  }
-  .head-opt {
-    margin-left: 20px;
-    padding-right: 15px;
-    font-size: 14px;
-    color: #3f3f3f;
-  }
-
-  .upload-option {
-    display: flex;
+};
+const sendCameras = (camerasList) => {
+  camerasAdded.value = camerasList.map((item) => {
+    return item.id;
+  });
+};
+
+/** 判断相机是否已经添加 */
+const isAddedCamera = (cameraId: string) => {
+  const index = camerasAdded.value.findIndex((item) => item === cameraId);
+  return index >= 0;
+};
+
+const changeDefault = (defaultCameraId) => {
+  caremaActiveId.value = defaultCameraId;
+};
+
+const handleAvatarSuccess = (e) => {
+  imgUrlBg.value = e.data;
+  konvaMap.value.addBg(imgUrlBg.value);
+  hasBg.value = true;
+};
+
+// const changeShop = (code: string) => {
+//   konvaMap.value.resetMap();
+//   getShopContent(code);
+//   hasBg.value = false;
+// };
+const getMapLayout = async (id: number) => {
+  const res = await getWorkshopMiniMapLayoutApi(id);
+  if (!res) return;
+  const layoutJSON = JSON.parse(res.layout);
+  return layoutJSON;
+}
+const getShopContent = async (id: number) => {
+  await getShowCameras(id);
+  // const idList = filterShopCameraList.value.map((item) => item.id);
+  const res = await getMapLayout(id);
+  if (!res) return;
+  hasBg.value = true;
+  isMap.value = res.isUploadBg;
+  if (res.isUploadBg) {
+    isUploadBg.value = true;
+    konvaMap.value.createMap(res, selectedShopId.value);
+  } else {
+    hasBg.value = false;
+    isUploadBg.value = res.isUploadBg;
   }
-  .upload-title {
-    margin-top: 13px;
+  // openInterval(codeList, (targetData) => {
+  //   updataState(filterShopCameraList.value, targetData);
+  // });
+  // getMapLayout(code).then((res) => {
+  //   if (!res) {
+  //     return;
+  //   }
+  //   hasBg.value = true;
+  //   isMap.value = res.isUploadBg;
+  //   if (res.isUploadBg) {
+  //     isUploadBg.value = true;
+  //     konvaMap.value.createMap(res, selectedShopDetail.value?.id);
+  //   } else {
+  //     hasBg.value = false;
+  //     isUploadBg.value = res.isUploadBg;
+  //   }
+  // });
+};
+const selectedShopId = ref();
+const selectedName = ref();
+const viewType = ref();
+const shopCameraList = ref<ShopMapCamera[]>([]);
+const route = useRoute();
+const getShowCameras = async (id: number) => {
+  const res = await getCamerasByWorkShopId({ workshopId: id });
+  if (!res) return;
+  res.children.forEach((item) => {
+    if (!item.children || item.children.length <= 0) return
+    item.children.forEach(camera => {
+      shopCameraList.value.push({ ...camera, isSet: 0, workSpaceName: item.name })
+    })
+  })
+};
+onMounted(async () => {
+  // getScenesTree({ level: 2, valueKey: 'code', labelKey: 'name', disabled: true });
+  konvaMap.value.resizeContainer(
+    drawContainer.value!.clientWidth,
+    drawContainer.value!.clientHeight,
+  );
+  selectedShopId.value = Number(route.query.workshopId);
+  selectedName.value = route.query.workshopName;
+  viewType.value = route.query.viewType;
+  await getShopContent(selectedShopId.value)
+  // if (selectedShopCode.value) {
+  //   getShopContent(selectedShopCode.value);
+  // }
+});
+
+onUnmounted(() => {
+  closeInterval();
+});
+
+const filterShopCameraList = computed(() => {
+  const k = searchKey.value.trim();
+  if (!k) return shopCameraList.value;
+  return shopCameraList.value.filter(
+    (x) => x.code?.includes(k) || x.name?.includes(k) || x.workSpaceName?.includes(k),
+  );
+});
+
+const handleAddCamera = (cameraId: string) => {
+  if (isAddedCamera(cameraId)) {
+    const camera = konvaMap.value.findCamera(cameraId);
+    konvaMap.value.handleCameraClick(camera);
+    return;
   }
-
-  .camera-one-tip {
-    color: rgb(197, 97, 20);
-    font-size: 30px;
-    margin: 200px auto;
+  if (!hasBg.value) {
+    ElMessage.warning({
+      message: '请先添加背景图片',
+    });
+    return;
   }
-  .avatar-uploader {
-    border-radius: 4px;
-    margin-left: 30px;
+  konvaMap.value.addCamera(cameraId);
+};
+
+const handleSave = () => {
+  if (shopCameraList.value.length === 1 && !isUploadBg.value) {
+    isMap.value = false;
+    const layout = JSON.stringify({
+      isUploadBg: isUploadBg.value,
+      defaultCameraId: shopCameraList.value[0].code,
+    });
+    updateMinMapViewLayoutApi({
+      layout,
+      targetId: String(selectedShopId.value),
+      viewType: viewType.value,
+    }).then((res) => {
+      console.log('updateMinMapViewLayoutApi', res);
+      ElMessage.success('保存成功');
+    });
+  } else {
+    isMap.value = true;
+    const layout = konvaMap.value.saveLayout();
+    updateMinMapViewLayoutApi({
+      layout: JSON.stringify({ ...JSON.parse(layout), isUploadBg: true }),
+      targetId: String(selectedShopId.value),
+      viewType: viewType.value,
+    }).then((res) => {
+      console.log('updateMinMapViewLayoutApi', res);
+      ElMessage.success('保存成功');
+    });
   }
-  .upload-icon {
-    position: absolute;
-    top: 0;
-    right: 0;
-    left: 0;
-    bottom: 0;
-    margin: auto;
+};
+
+const changeMap = (val) => {
+  isChange.value = val;
+};
+
+onBeforeRouteLeave(async () => {
+  if (isChange.value) {
+    await ElMessageBox.confirm('是否保存当前修改?', '提示', {
+      confirmButtonText: '是',
+      cancelButtonText: '否',
+      type: 'warning',
+    })
+      .then(() => {
+        handleSave();
+      })
+      .catch(() => {
+        return true;
+      });
+  } else {
+    return true;
   }
+});
+</script>
 
-  .paint-tool {
-    position: relative;
-    height: calc(100vh - 138px);
-    margin-top: 2px;
-  }
+<style scoped lang="scss">
+.page-head {
+  height: 54px;
+  padding-left: 15px;
+  background-color: #ffffff;
 
-  .camera-list {
-    width: 250px;
-    padding: 0 10px;
-    background-color: #ffffff;
-  }
-  .label-text {
-    font-size: 14px;
-    font-weight: 600;
-    margin: 10px 0 5px 10px;
-  }
-  .camera-item {
-    height: 32px;
+  &__btn {
+    display: flex;
+    gap: 10px;
+    align-items: center;
     font-size: 14px;
-    padding-left: 8px;
-    font-weight: 400;
-    color: #404040;
-    line-height: 14px;
     cursor: pointer;
 
-    &:hover {
-      background-color: #e6f7ff;
-      color: #1890ff;
+    img {
+      width: 14px;
     }
   }
-  .isAdded {
-    color: #1890ff;
-    //cursor: not-allowed;
-  }
-  .isActive {
-    background-color: #e6f7ff;
-    color: #1890ff;
-  }
-  .camera-item-disabled {
-    color: #c6c6c6;
-  }
-  .camera-id {
-    width: 110px;
-  }
-  .space-name {
-    width: 120px;
-    white-space: nowrap;
-    overflow: hidden;
-    text-overflow: ellipsis;
-  }
+}
 
-  .draw-container {
-    position: relative;
-    width: calc(100% - 300px);
-    margin: 20px;
-    overflow: hidden;
-    //background-color: rgba(0, 0, 0, 0.6);
-  }
+.head-opt {
+  margin-left: 20px;
+  padding-right: 15px;
+  font-size: 14px;
+  color: #3f3f3f;
 
-  .bg-background {
-    background-color: rgba(0, 0, 0, 0.6);
-  }
-
-  .integrationState {
-    cursor: not-allowed;
-    color: #ccc;
-  }
-
-  :deep(.search-put .el-input__wrapper) {
-    background-color: #f0f2f5;
-  }
-  :deep(.el-popper__arrow) {
-    display: none;
-  }
-  :deep(.el-tree-node__content:hover) {
-    background: #e6f4ff;
-  }
-  :deep(.el-button--primary) {
-    --el-button-disabled-bg-color: #bfbfbf;
+  .workshop-name {
+    font-weight: 600;
   }
-  :deep(.el-popover) {
-    width: unset !important;
-    min-width: 110px;
-    text-align: center;
-    font-weight: 400;
+}
+
+.upload-option {
+  display: flex;
+}
+
+.upload-title {
+  margin-top: 13px;
+}
+
+.camera-one-tip {
+  color: rgb(197, 97, 20);
+  font-size: 30px;
+  margin: 200px auto;
+}
+
+.avatar-uploader {
+  border-radius: 4px;
+  margin-left: 30px;
+}
+
+.upload-icon {
+  position: absolute;
+  top: 0;
+  right: 0;
+  left: 0;
+  bottom: 0;
+  margin: auto;
+}
+
+.paint-tool {
+  position: relative;
+  height: calc(100vh - 138px);
+  margin-top: 2px;
+}
+
+.camera-list {
+  width: 250px;
+  padding: 0 10px;
+  background-color: #ffffff;
+}
+
+.label-text {
+  font-size: 14px;
+  font-weight: 600;
+  margin: 10px 0 5px 10px;
+}
+
+.camera-item {
+  height: 32px;
+  font-size: 14px;
+  padding-left: 8px;
+  font-weight: 400;
+  color: #404040;
+  line-height: 14px;
+  cursor: pointer;
+
+  &:hover {
+    background-color: #e6f7ff;
+    color: #1890ff;
   }
+}
+
+.isAdded {
+  color: #1890ff;
+  //cursor: not-allowed;
+}
+
+.isActive {
+  background-color: #e6f7ff;
+  color: #1890ff;
+}
+
+.camera-item-disabled {
+  color: #c6c6c6;
+}
+
+.camera-id {
+  width: 110px;
+}
+
+.space-name {
+  width: 120px;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+
+.draw-container {
+  position: relative;
+  width: calc(100% - 300px);
+  margin: 20px;
+  overflow: hidden;
+  //background-color: rgba(0, 0, 0, 0.6);
+}
+
+.bg-background {
+  background-color: rgba(0, 0, 0, 0.6);
+}
+
+.integrationState {
+  cursor: not-allowed;
+  color: #ccc;
+}
+
+:deep(.search-put .el-input__wrapper) {
+  background-color: #f0f2f5;
+}
+
+:deep(.el-popper__arrow) {
+  display: none;
+}
+
+:deep(.el-tree-node__content:hover) {
+  background: #e6f4ff;
+}
+
+:deep(.el-button--primary) {
+  --el-button-disabled-bg-color: #bfbfbf;
+}
+
+:deep(.el-popover) {
+  width: unset !important;
+  min-width: 110px;
+  text-align: center;
+  font-weight: 400;
+}
 </style>

+ 1 - 1
src/views/map-config/mini-map/use-mini-map.ts

@@ -56,7 +56,7 @@ export const useMiniMap = defineStore('mini-map', () => {
       ElMessage.error('摄像头code未找到对应信息');
       return Promise.reject();
     }
-    return getWorkshopMiniMapLayoutApi(String(shopId)).then((res) => {
+    return getWorkshopMiniMapLayoutApi(shopId).then((res) => {
       const layoutJSON = res?.layout ? safeParse(res.layout) : null;
       return layoutJSON;
     });

+ 61 - 161
src/views/page-config/ConfigEdit.vue

@@ -4,49 +4,15 @@
       <div class="head-opt flex-1 flex justify-between items-center" style="margin-left: 0px">
         <div>
           <!-- <span>场景:</span> -->
-          <!-- <el-select
-            v-model="selectedCompany"
-            class="m-2"
-            placeholder="请选择相关公司"
-            style="width: 216px"
-            @change="changeCompany"
-          >
-            <el-option
-              v-for="item in scenesInfos"
-              :key="item.id"
-              :label="item.name"
-              :value="item.id"
-            />
-          </el-select> -->
         </div>
-        <!-- <div v-if="selectedCompany" style="display: flex">
-          <div style="display: flex">
-            <div class="label-workshop" style="margin-left: 0px">选择标签:</div>
-            <div>
-              <el-radio-group
-                v-model="label"
-                :border="true"
-                style="display: flex"
-                @change="changeShop"
-              >
-                <el-radio-button
-                  v-for="item in labelList"
-                  :key="item.id"
-                  :label="item.id!"
-                  class="label-select"
-                  >{{ item.name }}</el-radio-button
-                >
-              </el-radio-group></div
-            >
-          </div>
-        </div> -->
         <div class="top-bar">
-          <div class="back-btn" @click="router.back">
-            <img src="@/assets/rollback.png" />
-            <span>返回</span>
+          <div class="back-and-company">
+            <div class="back" @click="router.back">
+              <img src="@/assets/rollback.png" />
+              <span>返回</span>
+            </div>
             <div class="company-name">{{ companyName }}</div>
           </div>
-          <!-- <el-button @click="toJson">tojson</el-button> -->
           <div class="operation-btns">
             <el-upload
               class="avatar-uploader"
@@ -62,7 +28,7 @@
               <el-button :icon="Refresh"> 替换照片 </el-button>
             </el-upload>
 
-            <el-button :icon="Refresh" @click="clearLayout"> 重置 </el-button>
+            <el-button :icon="Refresh" @click="clearLayout"> 重置布局 </el-button>
 
             <el-button @click="handleSave" type="primary" :disabled="!companyId"> 保存 </el-button>
           </div>
@@ -81,9 +47,6 @@
             :suffix-icon="Search"
           />
         </div>
-        <!-- <span v-if="filterShopList.length == 0" class="ml-1" style="color: #3f3f3f">
-          提示:请先选择相应公司和图片
-        </span> -->
         <el-scrollbar style="position: relative; height: calc(100% - 90px)">
           <div
             v-for="item in filterShopList"
@@ -101,12 +64,7 @@
       </div>
       <div ref="drawContainer" id="drawContainer" class="draw-container">
         <div id="shopEditContainer" v-moveable:1 class="shop-edit-container">
-          <MapContainer
-            ref="mapContainerRef"
-            :is-mobile-view="isMobileView"
-            :module-code="labelMouduleCode"
-            @on-open="openConfig"
-          />
+          <MapContainer ref="mapContainerRef" :is-mobile-view="isMobileView" />
         </div>
         <el-upload
           v-if="!hasBg"
@@ -121,39 +79,15 @@
           :headers="getHeaders()"
         >
           <img src="~@/assets/images/img-upload.png" />
+          <div class="upload-tips-text"
+            >请上传1920*1080尺寸的布局背景图,其他尺寸会影响布局准确性!
+          </div>
         </el-upload>
       </div>
       <div class="shop-tag-edit-area" v-if="hasBg">
         <ShopTagEditArea @transformer-change="transformChange" />
       </div>
     </div>
-    <!-- <el-tooltip
-      class="box-item position-tooltip"
-      effect="dark"
-      content="显示侧边栏" 
-      :offset="12"
-      placement="left"
-    >
-      <div
-        v-if="leftShow && activeShopId && !isMobileView && activeShopId != -1"
-        class="circle-rectangle"
-        :class="{ 'shape-shadow': shadow }"
-        @mouseover="shadowAdd"
-        @mouseout="shadowRemove"
-        @click="dialogReopen"
-      >
-        <el-icon class="left-icon" size="16px"><ArrowLeftBold /></el-icon>
-        <el-icon style="margin-top: 7px" size="16px"><ArrowLeftBold /></el-icon>
-      </div>
-    </el-tooltip> -->
-
-    <!-- <ConfigDialog
-      v-if="!isMobileView"
-      ref="configDrawer"
-      @on-close="onClose"
-      @transformer-change="transformChange"
-      class="drawer-position"
-    /> -->
 
     <ConfigFinish
       :visible="visibleResult"
@@ -165,10 +99,9 @@
 </template>
 
 <script setup lang="ts">
-  import ConfigDialog from './component/ConfigDrawer.vue';
   import ConfigFinish from './component/ConfigFinish.vue';
   import { storeToRefs } from 'pinia';
-  import { ElMessage, ElInput, ElSwitch, ElMessageBox } from 'element-plus';
+  import { ElMessage, ElInput, ElMessageBox } from 'element-plus';
   import { onBeforeUnmount, onMounted, reactive, ref, watch } from 'vue';
   import { getWorkshopListApi } from '@/api/scene/scene';
   import { computed } from 'vue';
@@ -182,17 +115,18 @@
   import urlJoin from 'url-join';
   import { useGlobSetting } from '@/hooks/setting';
   import { getHeaders } from '@/utils/http/axios';
-  import { CompanyLayoutType, LayoutType, ShopType } from '@/types/page-config/type';
+  import { ShopType } from '@/types/page-config/type';
   import ShopTagEditArea from './component/ShopTagEditArea.vue';
 
   const mapEditor = useMapEditor();
-  const { bgImg, addedShops, activeShopId, showShops } = storeToRefs(mapEditor);
+  const { bgImg, addedShops, activeShopId, showShops, mapHeight, mapWidth } =
+    storeToRefs(mapEditor);
   const { addShop, addBg, calcLayout, resetMap, createMap, deleteShop } = mapEditor;
 
   const router = useRouter();
 
   const pageConfig = usePageConfig();
-  const { scenesInfos, label, labelList, layoutId } = pageConfig;
+  const { label, layoutId } = pageConfig;
   const { urlPrefix } = useGlobSetting();
   const drawContainer = ref<HTMLDivElement>();
   const mapContainerRef = ref();
@@ -210,16 +144,17 @@
 
   const shopList = ref<ShopType[]>([]); // 车间列表
 
-  // // mapContainer宽高
-  // const mapContainerStageSize = reactive({ height: 0, width: 777 });
+  // mapContainer宽高
+  const mapContainerStageSize = reactive({ height: 0, width: 0 });
+  // // mapContainer缩放比例
+  const scale = computed(() =>
+    Math.min(
+      mapContainerStageSize.width / mapWidth.value,
+      mapContainerStageSize.height / mapHeight.value,
+    ),
+  );
 
   const handleBeforeUpload = (rawFile) => {
-    // if (!selectedCompany.value || !label.value) {
-    //   ElMessage.error({
-    //     message: '请先选择公司和标签',
-    //   });
-    //   return false;
-    // }
     if (
       rawFile.type !== 'image/jpg' &&
       rawFile.type !== 'image/jpeg' &&
@@ -236,18 +171,11 @@
     return index >= 0;
   };
 
-  //左边的浮动按钮
-  const leftShow = ref(true);
-  const onClose = (val) => {
-    leftShow.value = val;
-  };
-
   const transformChange = () => {
     mapContainerRef.value.updateLayoutTransformer();
   };
 
   const actionUrl = computed(() => {
-    // return urlJoin(urlPrefix, '/homepageConfig/updateCompanyPicture');
     return urlJoin(urlPrefix, '/admin/homepageConfig/uploadCompanyPicture');
   });
 
@@ -259,23 +187,6 @@
     { deep: true },
   );
 
-  const shadow = ref(false);
-  const shadowAdd = () => {
-    shadow.value = true;
-  };
-  const shadowRemove = () => {
-    shadow.value = false;
-  };
-
-  const configDrawer = ref();
-  const dialogReopen = () => {
-    configDrawer.value.openDialog();
-  };
-
-  const openConfig = () => {
-    configDrawer.value.openDialog();
-  };
-
   //总体的保存,将整个数据传过去
   const visibleResult = ref(false);
   const configStatus = ref(true);
@@ -290,23 +201,7 @@
     addBg();
   };
 
-  const labelMouduleCode = computed(() => {
-    return (
-      scenesInfos.value
-        .find((item) => item.id === companyId.value)
-        ?.labelModuleList.find((item) => item.sceneLabel.id === label.value)?.sceneModule.code ||
-      'default'
-    );
-  });
-
-  const changeShop = () => {
-    hasBg.value = false;
-    resetMap();
-    getShopContent();
-  };
-
   const getShopContent = () => {
-    // getCompanyLayoutApi({ companyId: selectedCompany.value || 2 }).then((res) => {
     getWorkshopListApi({ companyId: companyId.value! }).then((res) => {
       shopList.value = res;
     });
@@ -329,10 +224,7 @@
     });
   };
 
-  // const changeCompany = () => {
   const clearLayout = () => {
-    // label.value = undefined;
-
     ElMessageBox.confirm('是否重置当前设置?', '提示', {
       confirmButtonText: '确认',
       cancelButtonText: '取消',
@@ -347,7 +239,6 @@
     // 删除键
     if (e.keyCode === 46 || e.code === 'Delete') {
       deleteShop();
-      configDrawer.value.closeDialog();
     }
   };
 
@@ -367,7 +258,6 @@
     //如果已经存在车间,则禁止加入
     const existingCamera = addedShops.value.find((item) => item.id === shop.id);
     if (existingCamera) return;
-    // activeShopId.value = shop.id;
     if (!hasBg.value) {
       ElMessage.warning({
         message: '请先添加背景图片',
@@ -389,15 +279,11 @@
       posType: LabelPositionEnum.LEFT,
     };
     addShop(shopNode);
-    // dialogReopen();
   };
 
   const handleSave = () => {
-    const { json, scale } = mapContainerRef.value?.getLayout();
-    console.log('layout json', JSON.parse(json));
-    console.log('scale', scale);
-    const layout = hasBg.value === false ? '' : calcLayout(json, scale);
-    if (hasBg.value) console.log('Calc layout', JSON.parse(layout));
+    const { json } = mapContainerRef.value?.getLayout();
+    const layout = hasBg.value === false ? '' : calcLayout(json);
     const param = {
       layout,
       targetId: companyId.value || 2,
@@ -417,8 +303,17 @@
     }
   };
 
+  watch(
+    () => mapHeight.value,
+    () => {
+      mapContainerStageSize.height = document.getElementById('drawContainer')?.clientHeight!;
+      mapContainerStageSize.width = document.getElementById('drawContainer')?.clientWidth!;
+    },
+  );
+
   onBeforeUnmount(() => {
     window.removeEventListener('keydown', handleKeyDown);
+    window.onresize = null;
     resetMap();
   });
 
@@ -430,20 +325,16 @@
       companyName.value = String(routerParams.companyName);
       viewType.value = Number(routerParams.viewType);
     }
-    // if (routerParams.labelId) {
-    //   label.value = Number(routerParams.labelId);
-    // }
 
     window.addEventListener('keydown', handleKeyDown);
+    window.onresize = () => {
+      mapContainerStageSize.height = document.getElementById('drawContainer')?.clientHeight!;
+      mapContainerStageSize.width = document.getElementById('drawContainer')?.clientWidth!;
+    };
 
     if (companyId.value) {
       getShopContent();
     }
-
-    // console.log('clientHeight', document.getElementById('shopEditContainer')?.clientHeight);
-    // console.log('clientWidth', document.getElementById('shopEditContainer')?.clientWidth);
-    // mapContainerStageSize.height = document.getElementById('shopEditContainer')?.clientHeight!;
-    // mapContainerStageSize.width = document.getElementById('shopEditContainer')?.clientWidth!;
   });
 </script>
 
@@ -541,15 +432,15 @@
   .draw-container {
     height: calc(100vh - 160px);
     position: relative;
-    width: calc(100% - 600px);
     margin: 10px;
     overflow: hidden;
-    border: 1px solid #1890ff;
+    display: flex;
+    justify-content: center;
+    align-items: center;
   }
 
   .shop-edit-container {
-    height: 100%;
-    border: 1px solid #ff7118;
+    scale: v-bind(scale);
   }
 
   .drawer-position {
@@ -604,17 +495,22 @@
     display: flex;
     justify-content: space-between;
     align-items: center;
-    .back-btn {
+    .back-and-company {
       display: flex;
       align-items: center;
       gap: 10px;
-      cursor: pointer;
-      img {
-        width: 14px;
-        height: 14px;
-      }
-      span {
-        line-height: 14px;
+      .back {
+        display: flex;
+        align-items: center;
+        gap: 10px;
+        cursor: pointer;
+        img {
+          width: 14px;
+          height: 14px;
+        }
+        span {
+          line-height: 14px;
+        }
       }
       .company-name {
         font-weight: 600;
@@ -623,7 +519,7 @@
       }
     }
     .operation-btns {
-      width: 350px;
+      width: 380px;
       display: flex;
       align-items: center;
       .el-button {
@@ -637,6 +533,10 @@
     background-color: #ffffff;
   }
 
+  :deep(.el-upload) {
+    flex-direction: column;
+  }
+
   :deep(.search-put .el-input__wrapper) {
     background-color: #f0f2f5;
   }

+ 1 - 8
src/views/page-config/component/ShopTagEditArea.vue

@@ -1,7 +1,6 @@
 <template>
   <div class="shop-tag-edit-area">
     <div>
-      <!-- //这里要变选值 -->
       <div class="content-title"
         ><div class="uploader-title"> <div class="block"></div>标签设置</div>
       </div>
@@ -119,16 +118,14 @@
       <hr />
     </div>
     <div class="save-wrapper">
-      <!-- <el-button type="primary" @click="saveWorkshopConfig">保存</el-button> -->
       <el-button type="primary" @click="deleteShop">删除</el-button>
     </div>
   </div>
 </template>
 
 <script setup lang="ts">
-  import { computed, ref } from 'vue';
+  import { computed } from 'vue';
   import { storeToRefs } from 'pinia';
-  import { cloneDeep } from 'lodash-es';
   import { colorRGB2Hex } from '@/utils';
   import useMapEditor, { LabelPositionEnum, MapWorkShopInfoItem } from '../stores/useMapEditor';
 
@@ -152,10 +149,6 @@
     emit('transformerChange');
   };
 
-  const saveWorkshopConfig = () => {
-    addedShops.value = cloneDeep(showShops.value);
-  };
-
   const deleteShop = () => {
     const tempId = editShop.value.id;
     showShops.value = showShops.value.filter((x) => x.id != tempId);

+ 11 - 82
src/views/page-config/component/mapContainer/MapContainer.vue

@@ -12,17 +12,16 @@
           v-for="item in showShops"
           :key="item.id"
           :config="getGroupConfig(item)"
-          @dblclick="handleClick"
           @dragend="handleGroupDragend"
           @transform="handleTransform"
         >
-          <LabelItemMobile
+          <!-- <LabelItemMobile
             v-if="isMobileView"
             :shop="item"
             :is-mobile-view="isMobileView"
             :module-code="moduleCode"
-          />
-          <LabelItem v-else :shop="item" :is-mobile-view="isMobileView" />
+          /> -->
+          <LabelItem :shop="item" :is-mobile-view="isMobileView" />
         </v-group>
         <v-transformer ref="transformerRef" :config="transformerConfig" />
       </v-layer>
@@ -31,63 +30,36 @@
 </template>
 
 <script setup lang="ts">
-  import { computed, ref, reactive, watch, nextTick, onMounted } from 'vue';
+  import { computed, ref, watch, nextTick } from 'vue';
   import LabelItem from './LabelItem.vue';
   import LabelItemMobile from './LabelItemMobile.vue';
   import { storeToRefs } from 'pinia';
   import useMapEditor, { MapWorkShopInfoItem } from '../../stores/useMapEditor';
   import Konva from 'konva';
-  import { stages } from 'konva/lib/Stage';
 
   const mapEditor = useMapEditor();
-  const { showShops, addedShops, bgImage, activeShopId, mapHeight, mapWidth } =
-    storeToRefs(mapEditor);
+  const { showShops, addedShops, bgImage, activeShopId } = storeToRefs(mapEditor);
 
   const props = defineProps<{
     isMobileView: boolean;
-    moduleCode: string;
+    // moduleCode: string;
   }>();
 
-  const emit = defineEmits(['onOpen']);
-
   const stageRef = ref<Konva.Stage>();
   const layerRef = ref<Konva.Layer>();
   const transformerRef = ref<Konva.Transformer>();
 
-  // mapContainer宽高
-  const mapContainerStageSize = reactive({ height: 0, width: 0 });
-
   const stageSize = computed(() => {
     return {
-      height: mapContainerStageSize.height,
-      width: mapContainerStageSize.width,
-      // scale: scale,
-      // scaleY: scale,
-      // scaleX: scale,
-      // offsetX: mapContainerStageSize.width * 2,
-      // offsetY: mapContainerStageSize.height * 2,
-      // scaleY: 0.5,
-      // scaleX: 0.5,
-      // width: 1920,
-      // height: 1080,
+      height: 1080,
+      width: 1920,
     };
   });
 
-  const scale = computed(() =>
-    Math.min(
-      mapContainerStageSize.width / mapWidth.value,
-      mapContainerStageSize.height / mapHeight.value,
-    ),
-  );
-
   const bgConfig = computed(() => {
-    // const scale = Math.min(
-    //   mapContainerStageSize.width / mapWidth.value,
-    //   mapContainerStageSize.height / mapHeight.value,
-    // );
     return {
-      width: bgImage.value.width * scale.value,
-      height: bgImage.value.height * scale.value,
+      height: 1080,
+      width: 1920,
       image: bgImage.value,
       name: 'bg',
     };
@@ -186,10 +158,6 @@
     }
   };
 
-  const handleClick = () => {
-    emit('onOpen');
-  };
-
   watch(activeShopId, () => {
     nextTick(() => {
       updateTransformer();
@@ -198,48 +166,9 @@
 
   const getLayout = () => {
     const json = stageRef.value?.getStage().toJSON();
-    return { json, scale: scale.value };
+    return { json };
   };
 
-  onMounted(() => {
-    console.log('clientHeight', document.getElementById('shopEditContainer')?.clientHeight);
-    console.log('clientWidth', document.getElementById('shopEditContainer')?.clientWidth);
-    mapContainerStageSize.height = document.getElementById('shopEditContainer')?.clientHeight!;
-    mapContainerStageSize.width = document.getElementById('shopEditContainer')?.clientWidth!;
-  });
-
-  watch(
-    () => mapWidth.value,
-    (newValue) => {
-      console.log(
-        'mapWidth newValue',
-        newValue,
-        `mapContainerStageSize.width ${mapContainerStageSize.width}`,
-      );
-      console.log('mapWidth / mapContainerStageSize.width', mapContainerStageSize.width / newValue);
-    },
-  );
-  watch(
-    () => mapHeight.value,
-    (newValue) => {
-      console.log(
-        'mapHeight newValue',
-        newValue,
-        `mapContainerStageSize.height ${mapContainerStageSize.height}`,
-      );
-      console.log(
-        'mapHeight / mapContainerStageSize.height',
-        mapContainerStageSize.height / newValue,
-      );
-    },
-  );
-  watch(
-    () => stageSize.value,
-    (newValue) => {
-      console.log('stageSize.value newValue', newValue);
-    },
-  );
-
   defineExpose({ getLayout, updateLayoutTransformer });
 </script>
 

+ 3 - 24
src/views/page-config/stores/useMapEditor.ts

@@ -71,34 +71,13 @@ export const useMapEditor = defineStore('home-map-ediotr', () => {
     showShops.value.push(cloneDeep(shop));
   };
 
-  const calcLayout = (json: string, scale = 1) => {
+  const calcLayout = (json: string) => {
     const mapJson = safeParse(json);
     const mapData = mapJson.children[0].children.filter((item) => item.className === 'Group');
-    // const scale = Math.min(
-    //   document.getElementById('shopEditContainer')?.clientWidth! / mapWidth.value,
-    //   document.getElementById('shopEditContainer')?.clientHeight! / mapHeight.value,
-    // );
-
-    console.log('scale', scale);
 
     const shopListAdded = addedShops.value.map((item, index) => {
-      console.log('mapData[index].attrs.x', mapData[index].attrs.x);
-
-      console.log('mapHeight.value', mapHeight.value);
-      console.log('mapWidth.value', mapWidth.value);
-
-      console.log('(mapData[index].attrs.x / scale)', mapData[index].attrs.x / scale);
-
-      console.log('(1920 / mapWidth.value)', 1920 / mapWidth.value);
-
-      item.x = (mapData[index].attrs.x / scale) * (1920 / mapWidth.value) - 13;
-      item.y = (mapData[index].attrs.y / scale) * (1080 / mapHeight.value) + 3;
-      // item.x = mapData[index].attrs.x / scale;
-      // item.y = mapData[index].attrs.y / scale + 1
-      // 0;
-
-      // item.x = mapData[index].attrs.x;
-      // item.y = mapData[index].attrs.y;
+      item.x = mapData[index].attrs.x;
+      item.y = mapData[index].attrs.y;
       item.scaleX = mapData[index].attrs.scaleX || 1;
       item.scaleY = mapData[index].attrs.scaleY || 1;
       return item;