chauncey 1 год назад
Родитель
Сommit
95f8826c04

BIN
src/assets/images/page-config/card-bg-default.png


+ 4 - 0
src/types/page-config/type.ts

@@ -1,3 +1,7 @@
+export enum LayoutConfigType {
+  scene = 1,
+  camera = 2,
+}
 export enum ViewType {
   companyHomepage_PC = 1,
   minimap_PC,

+ 10 - 0
src/views/page-config/PageCamera.vue

@@ -0,0 +1,10 @@
+<template>
+    <BasicLayoutEntry :layout-type="LayoutConfigType.camera" />
+</template>
+
+<script lang="ts" setup>
+import BasicLayoutEntry from './component/BasicLayoutEntry.vue';
+import { LayoutConfigType } from '@/types/page-config/type';
+</script>
+
+<style lang="scss" scoped></style>

src/views/page-config/PageSceneLayout.vue → src/views/page-config/PageCameraList.vue


+ 0 - 98
src/views/page-config/PageConfig.vue

@@ -1,98 +0,0 @@
-<template>
-  <div class="page-config-content">
-    <main class="main__config">
-      <div class="card--default" @click="toSceneLayout(ViewType.companyHomepage_PC)">
-        <section class="card__left">
-          <img :src="PCIcon" />
-        </section>
-        <section class="card__right">
-          <span class="span__card--title"> PC端{{ titleDefault }} </span>
-          <span class="span__card--describe"> {{ describeDefault }} PC端生效 </span>
-        </section>
-      </div>
-      <div class="card--default" @click="toSceneLayout(ViewType.companyHomepage_phone)">
-        <section class="card__left">
-          <img :src="PhoneIcon" />
-        </section>
-        <section class="card__right">
-          <span class="span__card--title"> 手机端{{ titleDefault }} </span>
-          <span class="span__card--describe"> {{ describeDefault }} 手机端生效 </span>
-        </section>
-      </div>
-    </main>
-  </div>
-</template>
-<script lang="ts" setup>
-  import PCIcon from '@/assets/images/page-config/config-pc.png';
-  import PhoneIcon from '@/assets/images/page-config/config-phone.png';
-  import router from '@/router';
-  import { ViewType } from '@/types/page-config/type';
-  const titleDefault = '主页布局';
-  const describeDefault = '编辑的主页布局、 \n位置标签等在\n';
-  const toSceneLayout = (type: ViewType.companyHomepage_PC | ViewType.companyHomepage_phone) => {
-    router.push(`/layout/scene-list?viewType=${type}`);
-  };
-</script>
-
-<style lang="scss" scoped>
-  .page-config-content {
-    width: 100%;
-    height: calc(100vh - 64px - 12px);
-    padding: 47px 84px 0 84px;
-    background: #ffffff;
-    box-shadow: 0px 0px 6px 0px rgba(0, 0, 0, 0.12);
-    border-radius: 6px;
-  }
-
-  .main__config {
-    display: flex;
-    justify-content: space-between;
-    width: 100%;
-    height: auto;
-
-    .card--default {
-      display: flex;
-      width: 490px;
-      height: 300px;
-      background-repeat: no-repeat;
-      background-size: cover;
-      background-image: url('@/assets/images/page-config/card-bg-default.png');
-      transition: background-image 0.3s ease-in-out;
-      cursor: pointer;
-
-      &:hover {
-        background-image: url('@/assets/images/page-config/card-bg-hover.png');
-      }
-    }
-
-    .card__left {
-      display: flex;
-      justify-content: center;
-      align-items: center;
-      flex: 1;
-      height: inherit;
-    }
-
-    .card__right {
-      display: flex;
-      justify-content: center;
-      flex-direction: column;
-      gap: 20px;
-      flex: 1;
-
-      .span__card--title {
-        font-weight: 600;
-        font-size: 28px;
-        color: #1777ff;
-      }
-
-      .span__card--describe {
-        font-weight: 400;
-        font-size: 24px;
-        line-height: 33px;
-        color: #909399;
-        white-space: pre-line;
-      }
-    }
-  }
-</style>

+ 10 - 0
src/views/page-config/PageScene.vue

@@ -0,0 +1,10 @@
+<template>
+    <BasicLayoutEntry :layout-type="LayoutConfigType.scene" />
+</template>
+
+<script lang="ts" setup>
+import BasicLayoutEntry from './component/BasicLayoutEntry.vue';
+import { LayoutConfigType } from '@/types/page-config/type';
+</script>
+
+<style lang="scss" scoped></style>

+ 229 - 0
src/views/page-config/PageSceneList.vue

@@ -0,0 +1,229 @@
+<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>
+</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);
+      });
+    });
+  });
+</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>

+ 121 - 0
src/views/page-config/component/BasicLayoutEntry.vue

@@ -0,0 +1,121 @@
+<template>
+  <div class="page-config-content">
+    <main class="main__config">
+      <div class="card--default" @click="toLayout(ViewType.companyHomepage_PC)">
+        <section class="card__left">
+          <img :src="PCIcon" />
+        </section>
+        <section class="card__right">
+          <span class="span__card--title"> PC端{{ titleDefault }} </span>
+          <span class="span__card--describe"> {{ describeDefault }} PC端生效 </span>
+        </section>
+      </div>
+      <div class="card--default" @click="toLayout(ViewType.companyHomepage_phone)">
+        <section class="card__left">
+          <img :src="PhoneIcon" />
+        </section>
+        <section class="card__right">
+          <span class="span__card--title"> 手机端{{ titleDefault }} </span>
+          <span class="span__card--describe"> {{ describeDefault }} 手机端生效 </span>
+        </section>
+      </div>
+    </main>
+  </div>
+</template>
+<script lang="ts" setup>
+import PCIcon from '@/assets/images/page-config/config-pc.png';
+import PhoneIcon from '@/assets/images/page-config/config-phone.png';
+import router from '@/router';
+import { LayoutConfigType, ViewType } from '@/types/page-config/type';
+import { ref, onMounted } from 'vue';
+const props = defineProps<{
+  layoutType: LayoutConfigType.scene | LayoutConfigType.camera
+}>()
+const titleDefault = ref('');
+const describeDefault = ref('');
+const generateContentDefault = (layoutType: LayoutConfigType.scene | LayoutConfigType.camera) => {
+  switch (layoutType) {
+    case LayoutConfigType.scene:
+      titleDefault.value = '主页布局';
+      describeDefault.value = '编辑的主页布局、 \n标签位置等在\n'
+      break;
+    case LayoutConfigType.camera:
+      titleDefault.value = '车间布局';
+      describeDefault.value = '编辑的车间布局、 \n摄像头位置等在\n'
+      break;
+  }
+}
+const toLayout = (type: ViewType.companyHomepage_PC | ViewType.companyHomepage_phone) => {
+  if (props.layoutType === LayoutConfigType.scene) {
+    router.push(`/layout/scene-list?viewType=${type}`);
+    return;
+  }
+  router.push(`/layout/camera-list?viewType=${type}`);
+};
+onMounted(() => {
+  generateContentDefault(props.layoutType);
+})
+</script>
+
+<style lang="scss" scoped>
+.page-config-content {
+  width: 100%;
+  height: calc(100vh - 64px - 12px);
+  padding: 47px 84px 0 84px;
+  background: #ffffff;
+  box-shadow: 0px 0px 6px 0px rgba(0, 0, 0, 0.12);
+  border-radius: 6px;
+}
+
+.main__config {
+  display: flex;
+  justify-content: space-evenly;
+  width: 100%;
+  height: auto;
+
+  .card--default {
+    display: flex;
+    width: 506px;
+    height: 315px;
+    background-repeat: no-repeat;
+    background-size: cover;
+    background-image: url('@/assets/images/page-config/card-bg-default.png');
+    transition: background-image 0.3s ease-in-out;
+    cursor: pointer;
+
+    &:hover {
+      background-image: url('@/assets/images/page-config/card-bg-hover.png');
+    }
+  }
+
+  .card__left {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    flex: 1;
+    height: inherit;
+  }
+
+  .card__right {
+    display: flex;
+    justify-content: center;
+    flex-direction: column;
+    gap: 20px;
+    flex: 1;
+
+    .span__card--title {
+      font-weight: 600;
+      font-size: 28px;
+      color: #1777ff;
+    }
+
+    .span__card--describe {
+      font-weight: 400;
+      font-size: 24px;
+      line-height: 33px;
+      color: #909399;
+      white-space: pre-line;
+    }
+  }
+}
+</style>

+ 2 - 2
src/views/system-config/business-scene/PageBusinessScene.vue

@@ -13,9 +13,9 @@
                 setting: false,
             }" />
         </main>
+        <InfoDrawer :title="drawerTitle" :data="tableInfo" @close-drawer="drawerVisiable = false"
+            @fetch-table="getTableData()" v-if="drawerVisiable" />
     </div>
-    <InfoDrawer :title="drawerTitle" :data="tableInfo" @close-drawer="drawerVisiable = false"
-        @fetch-table="getTableData()" v-if="drawerVisiable" />
 </template>
 
 <script lang="ts" setup>