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