|
@@ -1,5 +1,5 @@
|
|
|
<template>
|
|
<template>
|
|
|
- <div class="page" @click="handleWholeClick">
|
|
|
|
|
|
|
+ <div class="page">
|
|
|
<div class="page-head flex items-center">
|
|
<div class="page-head flex items-center">
|
|
|
<el-icon size="20"><ArrowLeft /></el-icon>
|
|
<el-icon size="20"><ArrowLeft /></el-icon>
|
|
|
<div class="head-opt flex-1 flex justify-between items-center">
|
|
<div class="head-opt flex-1 flex justify-between items-center">
|
|
@@ -23,7 +23,12 @@
|
|
|
<div v-if="selectedCompany" style="display: flex; margin-top: 8px">
|
|
<div v-if="selectedCompany" style="display: flex; margin-top: 8px">
|
|
|
<div class="label-workshop">选择标签:</div>
|
|
<div class="label-workshop">选择标签:</div>
|
|
|
<div>
|
|
<div>
|
|
|
- <el-radio-group v-model="label" :border="true" style="display: flex">
|
|
|
|
|
|
|
+ <el-radio-group
|
|
|
|
|
+ v-model="label"
|
|
|
|
|
+ :border="true"
|
|
|
|
|
+ style="display: flex"
|
|
|
|
|
+ @change="changeShop"
|
|
|
|
|
+ >
|
|
|
<el-radio-button
|
|
<el-radio-button
|
|
|
v-for="item in labelList"
|
|
v-for="item in labelList"
|
|
|
:key="item.id"
|
|
:key="item.id"
|
|
@@ -35,7 +40,7 @@
|
|
|
>
|
|
>
|
|
|
</div>
|
|
</div>
|
|
|
<div class="flex">
|
|
<div class="flex">
|
|
|
- <el-button @click="mapEditor.toJson">tojson</el-button>
|
|
|
|
|
|
|
+ <!-- <el-button @click="toJson">tojson</el-button> -->
|
|
|
<el-upload
|
|
<el-upload
|
|
|
class="avatar-uploader flex justify-center items-center"
|
|
class="avatar-uploader flex justify-center items-center"
|
|
|
action="/api/homepageConfig/updateCompanyPicture"
|
|
action="/api/homepageConfig/updateCompanyPicture"
|
|
@@ -43,6 +48,7 @@
|
|
|
:on-success="handleAvatarSuccess"
|
|
:on-success="handleAvatarSuccess"
|
|
|
:with-credentials="true"
|
|
:with-credentials="true"
|
|
|
name="file"
|
|
name="file"
|
|
|
|
|
+ :data="{ companyId: selectedCompany, labelId: label, deleteFileName: bgImg }"
|
|
|
>
|
|
>
|
|
|
<el-button style="font-size: 12px" :icon="Refresh" :disabled="!hasBg">
|
|
<el-button style="font-size: 12px" :icon="Refresh" :disabled="!hasBg">
|
|
|
替换照片
|
|
替换照片
|
|
@@ -80,17 +86,19 @@
|
|
|
:key="item.code"
|
|
:key="item.code"
|
|
|
class="camera-item flex justify-start items-center"
|
|
class="camera-item flex justify-start items-center"
|
|
|
:class="{
|
|
:class="{
|
|
|
- isAdded: isAddedCamera(item.id),
|
|
|
|
|
- isActive: item.code === activeShopId,
|
|
|
|
|
|
|
+ isAdded: isAddedShop(item.id),
|
|
|
|
|
+ isActive: item.id === activeShop.id,
|
|
|
}"
|
|
}"
|
|
|
- @click="handleAddCamera(item)"
|
|
|
|
|
|
|
+ @click="handleAddShop(item)"
|
|
|
>
|
|
>
|
|
|
<span class="camera-id">{{ item.name }}</span>
|
|
<span class="camera-id">{{ item.name }}</span>
|
|
|
</div>
|
|
</div>
|
|
|
</el-scrollbar>
|
|
</el-scrollbar>
|
|
|
</div>
|
|
</div>
|
|
|
<div ref="drawContainer" id="drawContainer" class="draw-container">
|
|
<div ref="drawContainer" id="drawContainer" class="draw-container">
|
|
|
- <div id="editContainer" v-moveable:1></div>
|
|
|
|
|
|
|
+ <div id="editContainer" v-moveable:1>
|
|
|
|
|
+ <MapContainer />
|
|
|
|
|
+ </div>
|
|
|
<el-upload
|
|
<el-upload
|
|
|
v-if="!hasBg"
|
|
v-if="!hasBg"
|
|
|
class="upload-icon flex justify-center items-center"
|
|
class="upload-icon flex justify-center items-center"
|
|
@@ -100,6 +108,7 @@
|
|
|
:on-success="handleAvatarSuccess"
|
|
:on-success="handleAvatarSuccess"
|
|
|
:with-credentials="true"
|
|
:with-credentials="true"
|
|
|
name="file"
|
|
name="file"
|
|
|
|
|
+ :data="{ companyId: selectedCompany, labelId: label }"
|
|
|
>
|
|
>
|
|
|
<img src="~@/assets/images/img-upload.png" />
|
|
<img src="~@/assets/images/img-upload.png" />
|
|
|
</el-upload>
|
|
</el-upload>
|
|
@@ -111,7 +120,6 @@
|
|
|
content="显示侧边栏"
|
|
content="显示侧边栏"
|
|
|
:offset="12"
|
|
:offset="12"
|
|
|
placement="left"
|
|
placement="left"
|
|
|
- @click="showEditConfig"
|
|
|
|
|
>
|
|
>
|
|
|
<div
|
|
<div
|
|
|
v-if="leftShow"
|
|
v-if="leftShow"
|
|
@@ -128,13 +136,8 @@
|
|
|
<!-- <img src="~@/assets/icons/slide.png" alt="" class="dialog-btn" /> -->
|
|
<!-- <img src="~@/assets/icons/slide.png" alt="" class="dialog-btn" /> -->
|
|
|
</el-tooltip>
|
|
</el-tooltip>
|
|
|
|
|
|
|
|
- <ConfigDialog
|
|
|
|
|
- ref="configDrawer"
|
|
|
|
|
- :shop="configShop"
|
|
|
|
|
- @on-close="onClose"
|
|
|
|
|
- @save-config="saveConfig"
|
|
|
|
|
- class="drawer-position"
|
|
|
|
|
- />
|
|
|
|
|
|
|
+ <ConfigDialog ref="configDrawer" @on-close="onClose" class="drawer-position" />
|
|
|
|
|
+
|
|
|
<ConfigFinish
|
|
<ConfigFinish
|
|
|
:visible="visibleResult"
|
|
:visible="visibleResult"
|
|
|
:status="configStatus"
|
|
:status="configStatus"
|
|
@@ -149,20 +152,25 @@
|
|
|
import ConfigFinish from './component/ConfigFinish.vue';
|
|
import ConfigFinish from './component/ConfigFinish.vue';
|
|
|
import { storeToRefs } from 'pinia';
|
|
import { storeToRefs } from 'pinia';
|
|
|
import { ElMessage, ElInput } from 'element-plus';
|
|
import { ElMessage, ElInput } from 'element-plus';
|
|
|
- import { onMounted, ref } from 'vue';
|
|
|
|
|
- import { updateMinMapViewLayoutApi, WorkShopInfoItem } from '@/api/scene/scene';
|
|
|
|
|
|
|
+ import { onBeforeUnmount, onMounted, ref } from 'vue';
|
|
|
|
|
+ import { WorkShopInfoItem } from '@/api/scene/scene';
|
|
|
import { computed } from 'vue';
|
|
import { computed } from 'vue';
|
|
|
import { Search, Refresh } from '@element-plus/icons-vue';
|
|
import { Search, Refresh } from '@element-plus/icons-vue';
|
|
|
- import useMapEditor from './hooks/useMapEditor';
|
|
|
|
|
import usePageConfig from './usePageConfig';
|
|
import usePageConfig from './usePageConfig';
|
|
|
- import tempBg from '@/assets/images/camera/video-live.png';
|
|
|
|
|
- import { title } from 'process';
|
|
|
|
|
|
|
+ import MapContainer from './component/mapContainer/MapContainer.vue';
|
|
|
|
|
+ import useMapEditor, { LabelPositionEnum } from './stores/useMapEditor';
|
|
|
|
|
+ import { uploadCompanyLayout, updateCompanyLayout, getCompanyLayoutApi } from '@/api/scene/scene';
|
|
|
|
|
+ import safeParse from '@/utils/safeParse';
|
|
|
|
|
+ import { useRouter } from 'vue-router';
|
|
|
|
|
|
|
|
- const mapEditor = useMapEditor({ onShopStyle });
|
|
|
|
|
- const { addedShops, bgImgUrl, activeShopId } = mapEditor;
|
|
|
|
|
|
|
+ const mapEditor = useMapEditor();
|
|
|
|
|
+ const { bgImg, addedShops, activeShop } = storeToRefs(mapEditor);
|
|
|
|
|
+ const { addShop, addBg, toJson, resetMap, createMap, deleteShop } = mapEditor;
|
|
|
|
|
+
|
|
|
|
|
+ const router = useRouter();
|
|
|
|
|
|
|
|
const pageConfig = usePageConfig();
|
|
const pageConfig = usePageConfig();
|
|
|
- const { selectedCompany, scenesInfos, label, labelList, shopList } = pageConfig;
|
|
|
|
|
|
|
+ const { selectedCompany, scenesInfos, label, labelList, shopList, layoutId } = pageConfig;
|
|
|
|
|
|
|
|
const drawContainer = ref<HTMLDivElement>();
|
|
const drawContainer = ref<HTMLDivElement>();
|
|
|
|
|
|
|
@@ -171,23 +179,20 @@
|
|
|
const hasBg = ref(false);
|
|
const hasBg = ref(false);
|
|
|
|
|
|
|
|
const handleBeforeUpload = () => {
|
|
const handleBeforeUpload = () => {
|
|
|
- if (!selectedShopCode.value) {
|
|
|
|
|
|
|
+ if (!selectedCompany.value || !label.value) {
|
|
|
ElMessage.error({
|
|
ElMessage.error({
|
|
|
- message: '请先选择车间',
|
|
|
|
|
|
|
+ message: '请先选择公司和标签',
|
|
|
});
|
|
});
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
/** 判断相机是否已经添加 */
|
|
/** 判断相机是否已经添加 */
|
|
|
- const isAddedCamera = (shopId: number) => {
|
|
|
|
|
- const index = addedShops.value.findIndex((item) => item === shopId);
|
|
|
|
|
|
|
+ const isAddedShop = (shopId: number) => {
|
|
|
|
|
+ const index = addedShops.value.findIndex((item) => item.id === shopId);
|
|
|
return index >= 0;
|
|
return index >= 0;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- /** -------- */
|
|
|
|
|
- const showEditConfig = () => {};
|
|
|
|
|
-
|
|
|
|
|
//左边的浮动按钮
|
|
//左边的浮动按钮
|
|
|
const leftShow = ref(true);
|
|
const leftShow = ref(true);
|
|
|
const onClose = (val) => {
|
|
const onClose = (val) => {
|
|
@@ -207,13 +212,6 @@
|
|
|
configDrawer.value.openDialog();
|
|
configDrawer.value.openDialog();
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- //需要从子组件中获得当前保存的车间数据
|
|
|
|
|
- const saveConfig = (val) => {
|
|
|
|
|
- console.log(val);
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- const configShop = ref<WorkShopInfoItem>({} as WorkShopInfoItem);
|
|
|
|
|
-
|
|
|
|
|
//总体的保存,将整个数据传过去
|
|
//总体的保存,将整个数据传过去
|
|
|
const visibleResult = ref(false);
|
|
const visibleResult = ref(false);
|
|
|
const configStatus = ref(true);
|
|
const configStatus = ref(true);
|
|
@@ -223,88 +221,120 @@
|
|
|
/** ------------- */
|
|
/** ------------- */
|
|
|
|
|
|
|
|
const handleAvatarSuccess = (e) => {
|
|
const handleAvatarSuccess = (e) => {
|
|
|
- bgImgUrl.value = e.data;
|
|
|
|
|
- mapEditor.addBg();
|
|
|
|
|
|
|
+ bgImg.value = e.data;
|
|
|
|
|
+ addBg();
|
|
|
hasBg.value = true;
|
|
hasBg.value = true;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- const changeShop = (code: string) => {
|
|
|
|
|
- getShopContent(code);
|
|
|
|
|
|
|
+ const changeShop = () => {
|
|
|
|
|
+ resetMap();
|
|
|
|
|
+ getShopContent();
|
|
|
hasBg.value = false;
|
|
hasBg.value = false;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- const mapJSON = ref();
|
|
|
|
|
-
|
|
|
|
|
- const getShopContent = (code: string) => {
|
|
|
|
|
- getShowCameras(code);
|
|
|
|
|
- getMapLayout(code).then((res) => {
|
|
|
|
|
- if (!res) {
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
- mapJSON.value = res;
|
|
|
|
|
- console.log(mapJSON);
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ const getShopContent = () => {
|
|
|
|
|
+ getCompanyLayoutApi({ companyId: selectedCompany.value || 2, labelId: label.value || 1 }).then(
|
|
|
|
|
+ (res) => {
|
|
|
|
|
+ if (!res) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ layoutId.value = res.id;
|
|
|
|
|
+ const layoutJSON = res.layout ? safeParse(res.layout) : null;
|
|
|
|
|
+ if (!layoutJSON) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ hasBg.value = true;
|
|
|
|
|
+ createMap(layoutJSON);
|
|
|
|
|
+ },
|
|
|
|
|
+ );
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- const handleWholeClick = (e) => {
|
|
|
|
|
- if (e.button === 0) {
|
|
|
|
|
- mapEditor.destoryOptBlock();
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ const changeCompany = () => {
|
|
|
|
|
+ label.value = undefined;
|
|
|
|
|
+ resetMap();
|
|
|
|
|
+ hasBg.value = false;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- const changeCompany = () => {};
|
|
|
|
|
|
|
+ const handleKeyDown = (e) => {
|
|
|
|
|
+ // 删除键
|
|
|
|
|
+ if (e.keyCode === 46 || e.code === 'Delete') {
|
|
|
|
|
+ deleteShop();
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
onMounted(() => {
|
|
|
- // getScenesTree({ level: 2, valueKey: 'code', labelKey: 'name', disabled: true });
|
|
|
|
|
- mapEditor.initContainer({
|
|
|
|
|
- container: 'editContainer',
|
|
|
|
|
- width: drawContainer.value!.clientWidth,
|
|
|
|
|
- height: drawContainer.value!.clientHeight,
|
|
|
|
|
- });
|
|
|
|
|
- // if (selectedShopCode.value) {
|
|
|
|
|
- // getShopContent(selectedShopCode.value);
|
|
|
|
|
- // }
|
|
|
|
|
-
|
|
|
|
|
- bgImgUrl.value = tempBg;
|
|
|
|
|
- mapEditor.addBg();
|
|
|
|
|
- hasBg.value = true;
|
|
|
|
|
|
|
+ const routerParams = router.currentRoute.value.query;
|
|
|
|
|
+ if (routerParams.companyId) {
|
|
|
|
|
+ selectedCompany.value = Number(routerParams.companyId);
|
|
|
|
|
+ console.log(selectedCompany.value);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ window.addEventListener('keydown', handleKeyDown);
|
|
|
|
|
+
|
|
|
|
|
+ if (selectedCompany.value && label.value) {
|
|
|
|
|
+ getShopContent();
|
|
|
|
|
+ }
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
const filterShopList = computed(() => {
|
|
const filterShopList = computed(() => {
|
|
|
const k = searchKey.value.trim();
|
|
const k = searchKey.value.trim();
|
|
|
if (!k) return shopList.value;
|
|
if (!k) return shopList.value;
|
|
|
- return shopList.value.filter((x) => x.name?.includes(k));
|
|
|
|
|
|
|
+ return shopList.value?.filter((x) => x.name?.includes(k));
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
- const handleAddCamera = (shop: WorkShopInfoItem) => {
|
|
|
|
|
|
|
+ const handleAddShop = (shop: WorkShopInfoItem) => {
|
|
|
if (!hasBg.value) {
|
|
if (!hasBg.value) {
|
|
|
ElMessage.warning({
|
|
ElMessage.warning({
|
|
|
message: '请先添加背景图片',
|
|
message: '请先添加背景图片',
|
|
|
});
|
|
});
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
- mapEditor.addShop(shop);
|
|
|
|
|
|
|
+ const shopNode = {
|
|
|
|
|
+ ...shop,
|
|
|
|
|
+ x: 20,
|
|
|
|
|
+ y: 20,
|
|
|
|
|
+ scale: 1,
|
|
|
|
|
+ bgColor: 'rgba(58, 170, 209, 1)',
|
|
|
|
|
+ fontSize: 14,
|
|
|
|
|
+ fontColor: '#ffffff',
|
|
|
|
|
+ posType: LabelPositionEnum.LEFT,
|
|
|
|
|
+ };
|
|
|
|
|
+ addShop(shopNode);
|
|
|
|
|
+ dialogReopen();
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
const handleSave = () => {
|
|
const handleSave = () => {
|
|
|
- const layout = mapEditor.toJson();
|
|
|
|
|
- updateMinMapViewLayoutApi({ layout, targetId: String(selectedShopDetail.value?.id) }).then(
|
|
|
|
|
- (res) => {
|
|
|
|
|
- console.log('updateMinMapViewLayoutApi', res);
|
|
|
|
|
|
|
+ const layout = toJson();
|
|
|
|
|
+ const param = {
|
|
|
|
|
+ layout,
|
|
|
|
|
+ targetId: selectedCompany.value || 2,
|
|
|
|
|
+ labelId: label.value || 1,
|
|
|
|
|
+ };
|
|
|
|
|
+ if (!layoutId.value) {
|
|
|
|
|
+ uploadCompanyLayout(param).then((res) => {
|
|
|
|
|
+ console.log('uploadCompanyLayout', res);
|
|
|
|
|
+ layoutId.value = res;
|
|
|
ElMessage.success('保存成功');
|
|
ElMessage.success('保存成功');
|
|
|
- },
|
|
|
|
|
- );
|
|
|
|
|
|
|
+ });
|
|
|
|
|
+ } else {
|
|
|
|
|
+ updateCompanyLayout({ ...param, id: layoutId.value }).then((res) => {
|
|
|
|
|
+ console.log('updateCompanyLayout', res);
|
|
|
|
|
+ layoutId.value = res;
|
|
|
|
|
+ ElMessage.success('更新成功');
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- function onShopStyle(shop: WorkShopInfoItem) {
|
|
|
|
|
- configShop.value = shop;
|
|
|
|
|
- dialogReopen();
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ onBeforeUnmount(() => {
|
|
|
|
|
+ window.removeEventListener('keydown', handleKeyDown);
|
|
|
|
|
+ resetMap();
|
|
|
|
|
+ });
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<style scoped lang="scss">
|
|
<style scoped lang="scss">
|
|
|
.page {
|
|
.page {
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
.page-head {
|
|
.page-head {
|
|
|
height: 54px;
|
|
height: 54px;
|
|
|
padding-left: 15px;
|
|
padding-left: 15px;
|
|
@@ -318,12 +348,18 @@
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.avatar-uploader {
|
|
.avatar-uploader {
|
|
|
- /* width: 120px; */
|
|
|
|
|
- /* height: 30px; */
|
|
|
|
|
- /* border: 1px solid #eee; */
|
|
|
|
|
border-radius: 4px;
|
|
border-radius: 4px;
|
|
|
margin-left: 30px;
|
|
margin-left: 30px;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ .label-workshop {
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ font-weight: 400;
|
|
|
|
|
+ margin-left: 36px;
|
|
|
|
|
+ margin-top: 6px;
|
|
|
|
|
+ margin-right: 16px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
.upload-icon {
|
|
.upload-icon {
|
|
|
position: absolute;
|
|
position: absolute;
|
|
|
top: 0;
|
|
top: 0;
|
|
@@ -456,5 +492,11 @@
|
|
|
text-align: center;
|
|
text-align: center;
|
|
|
font-weight: 400;
|
|
font-weight: 400;
|
|
|
}
|
|
}
|
|
|
|
|
+ ::v-deep.el-radio-button {
|
|
|
|
|
+ margin-right: 8px;
|
|
|
|
|
+ box-shadow: none;
|
|
|
|
|
+ border-radius: 4px !important;
|
|
|
|
|
+ border: 1px solid #d9d9d9 !important;
|
|
|
|
|
+ }
|
|
|
</style>
|
|
</style>
|
|
|
./MapBase/useCameraMap ./MapBase/CameraMapBak ./usePageConfig1
|
|
./MapBase/useCameraMap ./MapBase/CameraMapBak ./usePageConfig1
|