|
@@ -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>
|