Jelajahi Sumber

feat: 相机布局完成

chauncey 1 tahun lalu
induk
melakukan
60483c6135

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

@@ -434,7 +434,29 @@ export function getPcCompanyLayoutListApi(params: { companyIds: number[] }) {
 export function getMobileCompanyLayoutList(params: { companyIds: number[] }) {
   return http.request<CompanyLayoutInfoList[]>({
     url: '/admin/homepageConfig/getMobileCompanyLayoutList',
-    method: 'get',
+    method: 'post',
+    params,
+  });
+}
+/**
+ * @description 查询相机主页布局列表-PC
+ * @author chauncey
+ */
+export function getPcCameraLayoutList(params: { workshopIdList: number[] }) {
+  return http.request<CompanyLayoutInfoList[]>({
+    url: '/admin/homepageConfig/getPcWorkshopLayoutList',
+    method: 'post',
+    params,
+  });
+}
+/**
+ * @description 查询相机主页布局列表-Mobile
+ * @author chauncey
+ */
+export function getMobileCameraLayoutList(params: { workshopIdList: number[] }) {
+  return http.request<CompanyLayoutInfoList[]>({
+    url: '/admin/homepageConfig/getMobileWorkshopLayoutList',
+    method: 'post',
     params,
   });
 }

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

@@ -1,6 +1,8 @@
 export interface CompanyInfoList {
   id: number;
   name: string;
+}
+export interface LayoutInfoList extends CompanyInfoList {
   layout: string;
   imgUrl: string;
 }

+ 4 - 223
src/views/page-config/PageCameraList.vue

@@ -1,229 +1,10 @@
 <template>
-  <div class="scene-layout">
-    <header class="scene-layout__header">
-      <div class="header__btn" @click="router.back">
-        <img :src="rollback" />
-        <span>返回</span>
-      </div>
-    </header>
-    <main class="scene-layout__main">
-      <section v-if="length > 0" class="main__layout">
-        <el-card
-          v-for="company in companyList"
-          :key="company.id"
-          shadow="hover"
-          class="layout-cards"
-        >
-          <div class="layout-card" @click="handleClickCompany(company.id, company.name)">
-            <div v-if="company.layout">
-              <MapContainerSmall
-                ref="mapContainerRef"
-                :bg-image-url="(company.layout as any).bgInfo.img"
-                :show-shops="(company.layout as any).shopList"
-                class="content-pic"
-              />
-            </div>
-
-            <div v-else>
-              <img :src="noLayout" />
-              <span>请添加场景布局</span>
-            </div>
-          </div>
-          <template #footer>
-            <span class="footer--default">{{ company.name }}</span>
-            <div class="icons">
-              <el-image
-                v-if="company.layout"
-                :src="preview"
-                :preview-src-list="[company.layout]"
-                hide-on-click-modal
-                fit="cover"
-              />
-
-              <img :src="edit" @click="handleClickCompany(company.id, company.name)" />
-            </div>
-          </template>
-        </el-card>
-      </section>
-      <section class="main__empty" v-else>
-        <img :src="empty" />
-        <span>
-          目前无内容,
-          <router-link to="/scene/workshop">请先添加公司</router-link>
-        </span>
-      </section>
-    </main>
-  </div>
+  <BasicLayoutList :layout-type="LayoutConfigType.camera" />
 </template>
 
 <script lang="ts" setup>
-  import rollback from '@/assets/rollback.png';
-  import empty from '@/assets/images/table/table-empty.png';
-  import noLayout from '@/assets/images/page-config/no-layout.png';
-  import preview from '@/assets/images/table/table-preview.png';
-  import edit from '@/assets/images/table/table-edit.png';
-  import router from '@/router';
-  import { CompanyInfoList } from '@/types/scene-layout/type';
-  import { ViewType } from '@/types/page-config/type';
-  import {
-    getCompanyListApi,
-    getPcCompanyLayoutListApi,
-    getMobileCompanyLayoutList,
-  } from '@/api/scene/scene';
-  import { computed, onMounted, ref } from 'vue';
-  import MapContainerSmall from '@/views/page-config/component/mapContainer/MapContainerSmall.vue';
-  const companyList = ref<CompanyInfoList[]>([]);
-  const length = computed(() => {
-    return companyList.value.length;
-  });
-
-  const viewType = ref<number>();
-
-  const handleClickCompany = (companyId, companyName) => {
-    router.push({
-      path: '/layout/scene-config',
-      query: { companyId, companyName, viewType: viewType.value },
-    });
-  };
-
-  onMounted(async () => {
-    viewType.value = Number(router.currentRoute.value.query.viewType);
-    companyList.value = await getCompanyListApi();
-    const companyIDList = companyList.value.map((x) => x.id);
-
-    const platformApiMap = {
-      [ViewType.companyHomepage_PC]: getPcCompanyLayoutListApi,
-      [ViewType.companyHomepage_phone]: getMobileCompanyLayoutList,
-    };
-
-    platformApiMap[viewType.value]({ companyIds: companyIDList }).then((res) => {
-      res.map((companyWithLayout) => {
-        companyList.value.find((company) => company.id === companyWithLayout.id)!.layout =
-          JSON.parse(companyWithLayout.layout);
-      });
-    });
-  });
+import BasicLayoutList from './component/BasicLayoutList.vue';
+import { LayoutConfigType } from '@/types/page-config/type';
 </script>
 
-<style lang="scss" scoped>
-  .footer--default {
-    opacity: 0.45;
-  }
-
-  .scene-layout {
-    position: absolute;
-    top: 0;
-    left: 0;
-    width: 100%;
-    height: calc(100vh - 64px);
-
-    &__header {
-      display: flex;
-      align-items: center;
-      width: inherit;
-      height: 54px;
-      padding-left: 23px;
-      background: #ffffff;
-      border-top: 1px solid rgba(0, 0, 0, 0.1);
-      box-shadow: 0px 0px 6px 0px rgba(0, 0, 0, 0.12);
-
-      .header__btn {
-        display: flex;
-        gap: 10px;
-        cursor: pointer;
-      }
-
-      img {
-        width: 14px;
-        height: 14px;
-      }
-
-      span {
-        line-height: 14px;
-
-        &:hover {
-          text-shadow: 5px 5px 6px rgba(0, 0, 0, 0.12);
-        }
-      }
-    }
-
-    &__main {
-      margin-top: 12px;
-      width: inherit;
-      height: calc(100vh - 64px - 54px - 12px);
-      background: #ffffff;
-      box-shadow: 0px 0px 6px 0px rgba(0, 0, 0, 0.12);
-      border-radius: 6px;
-    }
-
-    .main__layout {
-      display: flex;
-      gap: 25px;
-      flex-wrap: wrap;
-      align-content: flex-start;
-      width: inherit;
-      height: inherit;
-      padding: 22px 24px 22px 24px;
-    }
-
-    .layout-cards {
-      width: 216px;
-      height: 190px;
-
-      .layout-card div {
-        display: flex;
-        flex-direction: column;
-        justify-content: center;
-        align-items: center;
-        gap: 4px;
-      }
-    }
-
-    :deep(.el-card__body) {
-      width: inherit;
-      height: 145px;
-      display: flex;
-      flex-direction: column;
-      justify-content: center;
-      align-items: center;
-      padding: 0;
-      background: #f5f5f5;
-      cursor: pointer;
-    }
-
-    :deep(.el-card__footer) {
-      display: flex;
-      justify-content: space-between;
-      align-items: center;
-      width: inherit;
-      height: 45px;
-      padding: 0 12px 0 12px;
-
-      .icons {
-        display: flex;
-        gap: 10px;
-
-        img,
-        el-image {
-          cursor: pointer;
-          opacity: 0.4;
-          transition: opacity 0.5s ease-in-out;
-
-          &:hover {
-            opacity: 1;
-          }
-        }
-      }
-    }
-
-    .main__empty {
-      display: flex;
-      flex-direction: column;
-      gap: 2px;
-      justify-content: center;
-      align-items: center;
-      width: inherit;
-      height: inherit;
-    }
-  }
-</style>
+<style lang="scss" scoped></style>

+ 4 - 223
src/views/page-config/PageSceneList.vue

@@ -1,229 +1,10 @@
 <template>
-  <div class="scene-layout">
-    <header class="scene-layout__header">
-      <div class="header__btn" @click="router.back">
-        <img :src="rollback" />
-        <span>返回</span>
-      </div>
-    </header>
-    <main class="scene-layout__main">
-      <section v-if="length > 0" class="main__layout">
-        <el-card
-          v-for="company in companyList"
-          :key="company.id"
-          shadow="hover"
-          class="layout-cards"
-        >
-          <div class="layout-card" @click="handleClickCompany(company.id, company.name)">
-            <div v-if="company.layout">
-              <MapContainerSmall
-                ref="mapContainerRef"
-                :bg-image-url="(company.layout as any).bgInfo.img"
-                :show-shops="(company.layout as any).shopList"
-                class="content-pic"
-              />
-            </div>
-
-            <div v-else>
-              <img :src="noLayout" />
-              <span>请添加场景布局</span>
-            </div>
-          </div>
-          <template #footer>
-            <span class="footer--default">{{ company.name }}</span>
-            <div class="icons">
-              <el-image
-                v-if="company.layout"
-                :src="preview"
-                :preview-src-list="[company.layout]"
-                hide-on-click-modal
-                fit="cover"
-              />
-
-              <img :src="edit" @click="handleClickCompany(company.id, company.name)" />
-            </div>
-          </template>
-        </el-card>
-      </section>
-      <section class="main__empty" v-else>
-        <img :src="empty" />
-        <span>
-          目前无内容,
-          <router-link to="/scene/workshop">请先添加公司</router-link>
-        </span>
-      </section>
-    </main>
-  </div>
+  <BasicLayoutList :layout-type="LayoutConfigType.scene" />
 </template>
 
 <script lang="ts" setup>
-  import rollback from '@/assets/rollback.png';
-  import empty from '@/assets/images/table/table-empty.png';
-  import noLayout from '@/assets/images/page-config/no-layout.png';
-  import preview from '@/assets/images/table/table-preview.png';
-  import edit from '@/assets/images/table/table-edit.png';
-  import router from '@/router';
-  import { CompanyInfoList } from '@/types/scene-layout/type';
-  import { ViewType } from '@/types/page-config/type';
-  import {
-    getCompanyListApi,
-    getPcCompanyLayoutListApi,
-    getMobileCompanyLayoutList,
-  } from '@/api/scene/scene';
-  import { computed, onMounted, ref } from 'vue';
-  import MapContainerSmall from '@/views/page-config/component/mapContainer/MapContainerSmall.vue';
-  const companyList = ref<CompanyInfoList[]>([]);
-  const length = computed(() => {
-    return companyList.value.length;
-  });
-
-  const viewType = ref<number>();
-
-  const handleClickCompany = (companyId, companyName) => {
-    router.push({
-      path: '/layout/scene-config',
-      query: { companyId, companyName, viewType: viewType.value },
-    });
-  };
-
-  onMounted(async () => {
-    viewType.value = Number(router.currentRoute.value.query.viewType);
-    companyList.value = await getCompanyListApi();
-    const companyIDList = companyList.value.map((x) => x.id);
-
-    const platformApiMap = {
-      [ViewType.companyHomepage_PC]: getPcCompanyLayoutListApi,
-      [ViewType.companyHomepage_phone]: getMobileCompanyLayoutList,
-    };
-
-    platformApiMap[viewType.value]({ companyIds: companyIDList }).then((res) => {
-      res.map((companyWithLayout) => {
-        companyList.value.find((company) => company.id === companyWithLayout.id)!.layout =
-          JSON.parse(companyWithLayout.layout);
-      });
-    });
-  });
+import BasicLayoutList from './component/BasicLayoutList.vue';
+import { LayoutConfigType } from '@/types/page-config/type';
 </script>
 
-<style lang="scss" scoped>
-  .footer--default {
-    opacity: 0.45;
-  }
-
-  .scene-layout {
-    position: absolute;
-    top: 0;
-    left: 0;
-    width: 100%;
-    height: calc(100vh - 64px);
-
-    &__header {
-      display: flex;
-      align-items: center;
-      width: inherit;
-      height: 54px;
-      padding-left: 23px;
-      background: #ffffff;
-      border-top: 1px solid rgba(0, 0, 0, 0.1);
-      box-shadow: 0px 0px 6px 0px rgba(0, 0, 0, 0.12);
-
-      .header__btn {
-        display: flex;
-        gap: 10px;
-        cursor: pointer;
-      }
-
-      img {
-        width: 14px;
-        height: 14px;
-      }
-
-      span {
-        line-height: 14px;
-
-        &:hover {
-          text-shadow: 5px 5px 6px rgba(0, 0, 0, 0.12);
-        }
-      }
-    }
-
-    &__main {
-      margin-top: 12px;
-      width: inherit;
-      height: calc(100vh - 64px - 54px - 12px);
-      background: #ffffff;
-      box-shadow: 0px 0px 6px 0px rgba(0, 0, 0, 0.12);
-      border-radius: 6px;
-    }
-
-    .main__layout {
-      display: flex;
-      gap: 25px;
-      flex-wrap: wrap;
-      align-content: flex-start;
-      width: inherit;
-      height: inherit;
-      padding: 22px 24px 22px 24px;
-    }
-
-    .layout-cards {
-      width: 216px;
-      height: 190px;
-
-      .layout-card div {
-        display: flex;
-        flex-direction: column;
-        justify-content: center;
-        align-items: center;
-        gap: 4px;
-      }
-    }
-
-    :deep(.el-card__body) {
-      width: inherit;
-      height: 145px;
-      display: flex;
-      flex-direction: column;
-      justify-content: center;
-      align-items: center;
-      padding: 0;
-      background: #f5f5f5;
-      cursor: pointer;
-    }
-
-    :deep(.el-card__footer) {
-      display: flex;
-      justify-content: space-between;
-      align-items: center;
-      width: inherit;
-      height: 45px;
-      padding: 0 12px 0 12px;
-
-      .icons {
-        display: flex;
-        gap: 10px;
-
-        img,
-        el-image {
-          cursor: pointer;
-          opacity: 0.4;
-          transition: opacity 0.5s ease-in-out;
-
-          &:hover {
-            opacity: 1;
-          }
-        }
-      }
-    }
-
-    .main__empty {
-      display: flex;
-      flex-direction: column;
-      gap: 2px;
-      justify-content: center;
-      align-items: center;
-      width: inherit;
-      height: inherit;
-    }
-  }
-</style>
+<style lang="scss" scoped></style>

+ 276 - 0
src/views/page-config/component/BasicLayoutList.vue

@@ -0,0 +1,276 @@
+<template>
+  <div class="scene-layout">
+    <header class="scene-layout__header">
+      <div class="header__btn" @click="router.back">
+        <img :src="rollback" />
+        <span>返回</span>
+      </div>
+      <el-select v-model="selectCompany" placeholder="请选择公司" class="header__select"
+        v-if="layoutType === LayoutConfigType.camera" @change="handleSelectChange">
+        <el-option v-for="company in companyList" :key="company.id" :label="company.name" :value="company.id" />
+      </el-select>
+    </header>
+    <main class="scene-layout__main">
+      <section v-if="length > 0" class="main__layout">
+        <el-card v-for="layout in layoutList" :key="layout.id" shadow="hover" class="layout-cards">
+          <div class="layout-card" @click="handleClickCompany(layout.id, layout.name)">
+            <div v-if="layout.layout">
+              <MapContainerSmall ref="mapContainerRef" :bg-image-url="layout.layout" class="content-pic" />
+            </div>
+
+            <div v-else>
+              <img :src="noLayout" />
+              <span>请添加场景布局</span>
+            </div>
+          </div>
+          <template #footer>
+            <span class="footer--default">{{ layout.name }}</span>
+            <div class="icons">
+              <el-image v-if="layout.layout" :src="preview" :preview-src-list="[layout.layout]" hide-on-click-modal
+                fit="cover" />
+
+              <img :src="edit" @click="handleClickCompany(layout.id, layout.name)" />
+            </div>
+          </template>
+        </el-card>
+      </section>
+      <section class="main__empty" v-else>
+        <img :src="empty" />
+        <span>
+          目前无内容,
+          <router-link to="/scene/workshop">
+            {{ props.layoutType === LayoutConfigType.scene ? '请先添加公司' : '请先添加车间' }}
+          </router-link>
+        </span>
+      </section>
+    </main>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import rollback from '@/assets/rollback.png';
+import empty from '@/assets/images/table/table-empty.png';
+import noLayout from '@/assets/images/page-config/no-layout.png';
+import preview from '@/assets/images/table/table-preview.png';
+import edit from '@/assets/images/table/table-edit.png';
+import router from '@/router';
+import { CompanyInfoList, LayoutInfoList } from '@/types/scene-layout/type';
+import { LayoutConfigType, ViewType } from '@/types/page-config/type';
+import {
+  getCompanyListApi,
+  getPcCompanyLayoutListApi,
+  getMobileCompanyLayoutList,
+  getWorkshopListApi,
+  getPcCameraLayoutList,
+  getMobileCameraLayoutList
+} from '@/api/scene/scene';
+import { computed, onMounted, ref } from 'vue';
+import MapContainerSmall from '@/views/page-config/component/mapContainer/MapContainerSmall.vue';
+const props = defineProps<{
+  layoutType: LayoutConfigType.scene | LayoutConfigType.camera
+}>()
+const companyList = ref<CompanyInfoList[]>([]);
+const layoutList = ref<LayoutInfoList[]>([]);
+const length = computed(() => {
+  return layoutList.value.length;
+});
+const selectCompany = ref<number>();
+const viewType = ref<number>();
+const handleSelectChange = async () => {
+  layoutList.value = await getLayoutInfoList(props.layoutType)
+  const layoutIDList = layoutList.value.map((x) => x.id);
+  getLayoutInfoImg(props.layoutType, viewType.value!, layoutIDList)
+}
+
+const handleClickCompany = (id, name) => {
+  if (props.layoutType === LayoutConfigType.scene) {
+    router.push({
+      path: '/layout/scene-config',
+      query: { companyId: id, companyName: name, viewType: viewType.value },
+    });
+    return
+  }
+  router.push({
+    path: '/layout/camera-config',
+    query: { workshopId: id, workshopName: name, viewType: viewType.value },
+  });
+};
+const getLayoutInfoList = async (layoutType: LayoutConfigType.scene | LayoutConfigType.camera) => {
+  switch (layoutType) {
+    case LayoutConfigType.scene:
+      return companyList.value
+    case LayoutConfigType.camera:
+      if (!selectCompany.value) {
+        return []
+      }
+      const res = await getWorkshopListApi({ companyId: selectCompany.value })
+      return res
+  }
+}
+const scenePlatformApiMap = {
+  [ViewType.companyHomepage_PC]: getPcCompanyLayoutListApi,
+  [ViewType.companyHomepage_phone]: getMobileCompanyLayoutList,
+};
+const cameraPlatformApiMap = {
+  [ViewType.companyHomepage_PC]: getPcCameraLayoutList,
+  [ViewType.companyHomepage_phone]: getMobileCameraLayoutList,
+};
+const getLayoutInfoImg = (layoutType: LayoutConfigType.scene | LayoutConfigType.camera, viewType: number, idList: number[]) => {
+  switch (layoutType) {
+    case LayoutConfigType.scene:
+      scenePlatformApiMap[viewType]({ companyIds: idList }).then((res) => {
+        res.map((companyWithLayout) => {
+          layoutList.value.find((company) => company.id === companyWithLayout.id)!.layout =
+            JSON.parse(companyWithLayout.layout).bgInfo.img;
+        });
+      });
+      break;
+    case LayoutConfigType.camera:
+      cameraPlatformApiMap[viewType]({ workshopIdList: idList }).then((res) => {
+        res.map((workshopWithLayout) => {
+          layoutList.value.find((workshop) => workshop.id === workshopWithLayout.targetId)!.layout =
+            JSON.parse(workshopWithLayout.layout).bgImgUrl;
+        });
+      });
+      break;
+  }
+}
+
+onMounted(async () => {
+  viewType.value = Number(router.currentRoute.value.query.viewType);
+  companyList.value = await getCompanyListApi();
+  if (!companyList.value) return;
+  selectCompany.value = companyList.value[0].id;
+  layoutList.value = await getLayoutInfoList(props.layoutType)
+  const layoutIDList = layoutList.value.map((x) => x.id);
+  getLayoutInfoImg(props.layoutType, viewType.value, layoutIDList)
+});
+</script>
+
+<style lang="scss" scoped>
+.footer--default {
+  opacity: 0.45;
+}
+
+.scene-layout {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: calc(100vh - 64px);
+
+  &__header {
+    display: flex;
+    gap: 50px;
+    align-items: center;
+    width: inherit;
+    height: 54px;
+    padding-left: 23px;
+    background: #ffffff;
+    border-top: 1px solid rgba(0, 0, 0, 0.1);
+    box-shadow: 0px 0px 6px 0px rgba(0, 0, 0, 0.12);
+
+    .header__btn {
+      display: flex;
+      gap: 10px;
+      cursor: pointer;
+    }
+
+    .header__select {
+      width: 200px;
+    }
+
+    img {
+      width: 14px;
+      height: 14px;
+    }
+
+    span {
+      line-height: 14px;
+
+      &:hover {
+        text-shadow: 5px 5px 6px rgba(0, 0, 0, 0.12);
+      }
+    }
+  }
+
+  &__main {
+    margin-top: 12px;
+    width: inherit;
+    height: calc(100vh - 64px - 54px - 12px);
+    background: #ffffff;
+    box-shadow: 0px 0px 6px 0px rgba(0, 0, 0, 0.12);
+    border-radius: 6px;
+  }
+
+  .main__layout {
+    display: flex;
+    gap: 25px;
+    flex-wrap: wrap;
+    align-content: flex-start;
+    width: inherit;
+    height: inherit;
+    padding: 22px 24px 22px 24px;
+  }
+
+  .layout-cards {
+    width: 216px;
+    height: 190px;
+
+    .layout-card div {
+      display: flex;
+      flex-direction: column;
+      justify-content: center;
+      align-items: center;
+      gap: 4px;
+    }
+  }
+
+  :deep(.el-card__body) {
+    width: inherit;
+    height: 145px;
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+    padding: 0;
+    background: #f5f5f5;
+    cursor: pointer;
+  }
+
+  :deep(.el-card__footer) {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    width: inherit;
+    height: 45px;
+    padding: 0 12px 0 12px;
+
+    .icons {
+      display: flex;
+      gap: 10px;
+
+      img,
+      el-image {
+        cursor: pointer;
+        opacity: 0.4;
+        transition: opacity 0.5s ease-in-out;
+
+        &:hover {
+          opacity: 1;
+        }
+      }
+    }
+  }
+
+  .main__empty {
+    display: flex;
+    flex-direction: column;
+    gap: 2px;
+    justify-content: center;
+    align-items: center;
+    width: inherit;
+    height: inherit;
+  }
+}
+</style>

+ 77 - 79
src/views/page-config/component/mapContainer/MapContainerSmall.vue

@@ -6,103 +6,101 @@
         <v-group v-for="item in props.showShops" :key="item.id" :config="getGroupConfig(item)">
           <LabelItem :shop="item" />
         </v-group>
-        <!-- <v-transformer ref="transformerRef" :config="transformerConfig" /> -->
       </v-layer>
     </v-stage>
   </div>
 </template>
 
 <script setup lang="ts">
-  import { ref, watch } from 'vue';
-  import LabelItem from './LabelItem.vue';
-  // import { storeToRefs } from 'pinia';
-  import { MapWorkShopInfoItem } from '../../stores/useMapEditor';
-  import Konva from 'konva';
-  import { useGlobSetting } from '@/hooks/setting';
-  import urlJoin from 'url-join';
+import { ref, watch } from 'vue';
+import LabelItem from './LabelItem.vue';
+import { MapWorkShopInfoItem } from '../../stores/useMapEditor';
+import Konva from 'konva';
+import { useGlobSetting } from '@/hooks/setting';
+import urlJoin from 'url-join';
 
-  const globSetting = useGlobSetting();
-  const props = defineProps<{ showShops?; bgImageUrl? }>();
-  const bgImage = ref<HTMLImageElement>(new Image());
-  const stageRef = ref<Konva.Stage>();
-  const layerRef = ref<Konva.Layer>();
+const globSetting = useGlobSetting();
+const props = defineProps<{ showShops?; bgImageUrl?}>();
+const bgImage = ref<HTMLImageElement>(new Image());
+const stageRef = ref<Konva.Stage>();
+const layerRef = ref<Konva.Layer>();
 
-  const stageSize = ref({
-    width: 214,
-    height: 120,
-  });
+const stageSize = ref({
+  width: 214,
+  height: 120,
+});
 
-  const bgConfig = ref({
-    width: 1920,
-    height: 1080,
-    image: bgImage.value,
-    name: 'bg',
-  });
+const bgConfig = ref({
+  width: 1920,
+  height: 1080,
+  image: bgImage.value,
+  name: 'bg',
+});
 
-  const getGroupConfig = (shop: MapWorkShopInfoItem) => {
-    return {
-      x: shop.x,
-      y: shop.y,
-      scaleX: shop.scaleX,
-      scaleY: shop.scaleY,
-      id: shop.id + '',
-      name: 'group',
-    };
+const getGroupConfig = (shop: MapWorkShopInfoItem) => {
+  return {
+    x: shop.x,
+    y: shop.y,
+    scaleX: shop.scaleX,
+    scaleY: shop.scaleY,
+    id: shop.id + '',
+    name: 'group',
   };
+};
 
-  const addBg = () => {
-    return new Promise((resolve) => {
-      const imgUrl = props.bgImageUrl.includes('skyeye-file-upload')
-        ? props.bgImageUrl
-        : urlJoin(globSetting.imgUrl!, props.bgImageUrl);
+const addBg = () => {
+  return new Promise((resolve) => {
+    const imgUrl = props.bgImageUrl.includes('skyeye-file-upload')
+      ? props.bgImageUrl
+      : urlJoin(globSetting.imgUrl!, props.bgImageUrl);
 
-      const tempImg = new Image();
-      tempImg.src = imgUrl;
-      tempImg.onload = () => {
-        bgConfig.value.image = tempImg;
-      };
-      resolve(null);
-    });
-  };
+    const tempImg = new Image();
+    tempImg.src = imgUrl;
+    tempImg.onload = () => {
+      bgConfig.value.image = tempImg;
+    };
+    resolve(null);
+  });
+};
 
-  const zoomOut = () => {
-    const stage = stageRef.value!.getStage();
-    if (!stage) return;
+const zoomOut = () => {
+  const stage = stageRef.value!.getStage();
+  if (!stage) return;
 
-    const targetWidth = 214;
-    const targetHeight = 120;
-    const fixWidth = 1920;
-    const fixHeight = 1080;
-    //得到缩放比
-    const scaleX = targetWidth / fixWidth;
-    const scaleY = targetHeight / fixHeight;
+  const targetWidth = 214;
+  const targetHeight = 120;
+  const fixWidth = 1920;
+  const fixHeight = 1080;
+  //得到缩放比
+  const scaleX = targetWidth / fixWidth;
+  const scaleY = targetHeight / fixHeight;
 
-    //背景图片缩小
-    bgConfig.value.width = targetWidth;
-    bgConfig.value.height = targetHeight;
+  //背景图片缩小
+  bgConfig.value.width = targetWidth;
+  bgConfig.value.height = targetHeight;
 
-    //缩小group
-    const children = stage.find('.group');
-    children.forEach((node) => {
-      const newScaleX = node.attrs.scaleX * scaleX;
-      const newScaleY = node.attrs.scaleY * scaleY;
-      node.attrs.scaleX = newScaleX;
-      node.attrs.scaleY = newScaleY;
-      node.x(node.x() * scaleX);
-      node.y(node.y() * scaleY);
-    });
-    stage.batchDraw();
-  };
+  //缩小group
+  const children = stage.find('.group');
+  children.forEach((node) => {
+    const newScaleX = node.attrs.scaleX * scaleX;
+    const newScaleY = node.attrs.scaleY * scaleY;
+    node.attrs.scaleX = newScaleX;
+    node.attrs.scaleY = newScaleY;
+    node.x(node.x() * scaleX);
+    node.y(node.y() * scaleY);
+  });
+  stage.batchDraw();
+};
 
-  watch(
-    () => props.bgImageUrl,
-    () => {
-      addBg().then(() => {
-        zoomOut();
-      });
-    },
-    { immediate: true },
-  );
+watch(
+  () => props.bgImageUrl,
+  () => {
+    addBg().then(() => {
+      zoomOut();
+    });
+  },
+  { immediate: true },
+);
 </script>
 
 <style scoped></style>