<template> <div class="manage-container clerk-wrapper"> <el-row class="manage-head-wrapper"> <el-col :span="20"> <!-- 广场 --> <div class="manage-select-box"> <el-select v-model="mallVal" class="mall-opt" filterable placeholder="楼层" @change="chooseMall(mallVal)"> <el-option v-for="item in mallOpt" :label="item.name" :value="item.id" :key="item.value"> </el-option> </el-select> </div> <!-- 楼层选择 --> <div class="manage-select-box floor-box"> <el-select v-model="floorVal" filterable :placeholder="$t('pholder.floorSelect')" @change="chooseFloor(floorVal)"> <el-option v-for="item in floorOpt" :key="item.id" :label="item.name" :value="item.id" /> </el-select> </div> <el-button type="primary" class="search-btn" plain size="mini" @click="searchFun">{{ $t('button.search') }} </el-button> <!-- <el-button type="primary" class="search-btn" plain size="mini" @click="saveData">保存并应用 </el-button> --> </el-col> </el-row> <el-row class="manage-content"> <el-col :span="5" class="treeMenu"> <div v-show="floorVal" class="btn-box btn-radio"> <el-button type="primary" class="search-btn" plain size="mini" @click="addDesk">新增货架</el-button> </div> <el-table ref="singleTable" @row-click="setCurrent" @current-change="handleCurrentChange" :data="tableData" :max-height="tableHeight" :show-header='false' :highlight-current-row='true' style="width: 100%;" v-loading="loading" header-row-class-name="manage-tab-head"> <el-table-column align="left" prop="name"> <template slot-scope="scope"> <p>{{ scope.row.name }}<span v-if="scope.row.doorway==1" style="color:#f00;margin-left:5px;">{{$t('asisTab.inOut')}}</span></p> </template> </el-table-column> <el-table-column align="left" prop="bindType" width="80"> <template slot-scope="scope"> <span class="bind" @click="editDesk(scope.row)">编辑</span> <span class="unbind" @click="delDesk(scope.row)">删除</span> </template> </el-table-column> </el-table> <!-- <el-pagination class="treePage" small background :pageCount='4' layout="jumper, prev, pager, next" :total="total" @size-change="sizeChange" @current-change="currentChange"> </el-pagination> --> </el-col> <el-col :span="19" class="personInfo"> <ul class="legends"> <el-button size="mini" type="danger" @click="clearDesk">清除货架</el-button> <el-button size="mini" type="primary" @click="saveData">保存绘图</el-button> </ul> <div class="draw_desks"> <el-row v-if="ptype==1" :loading="loading" class="pwraper" :style="{ maxHeight: tableHeight + 'px' }"> <ul class="dlist" ref="dlist"> <li class="ditem" style="height:0;margin:0;"> <div class="dwrap"></div> </li> <li class="ditem" v-for="(item, index) in canvasList" :key="index"> <div class="dwrap"> <img class="dimg" :src="item.picUrl" /> <div class="label-box"> <p>{{ $t('table.monitorSiteName') + ': ' + item.name }}</p> <p>{{ $t('table.deviceNum') + ': ' + item.serialnum }}</p> </div> <div class="pview"> <Painter :cdata="item" :isEdit="true" :desk="currentRow" :list="tableData" @gclick="groupClick" @start="startDesk" @finish="finishDesk"></Painter> </div> </div> </li> </ul> </el-row> <el-row v-else> <div class="fwrap"> <img class="dimg" :src="floorImg" /> <div class="pview"> <Painter :cdata="floorData" :isFloor="true" :isEdit="true" :desk="currentRow" :list="tableData" @gclick="groupClick" @start="startDesk" @finish="finishDesk"></Painter> </div> </div> </el-row> <!-- <painter-view :maxHeight="tableHeight" :mallId="mallVal" :floorId="floorVal"></painter-view> --> </div> </el-col> </el-row> <add-desk-dialog ref="addDeskDialog" @submit="addField"></add-desk-dialog> </div> </template> <script> import _ from "underscore"; import Painter from "./Painter"; import addDeskDialog from "./addDesk"; export default { data() { return { ptype: 1, floorOpt: [], floorVal: "", floorImg: "", floorData: {}, mallName: "", mallVal: null, mallOpt: [], tableData: [], loading: true, dataMsg: "", gateList: [], canvasList: [], currentRow: {}, groupList: [], }; }, components: { "add-desk-dialog": addDeskDialog, Painter: Painter, }, computed: { tableHeight() { const windowInnerHeight = window.innerHeight; return windowInnerHeight - windowInnerHeight * 0.24; }, }, mounted() { this.getMallList(); this.dataMsg = this.$t("echartsTitle.loading"); }, methods: { startDesk(data) { let index = _.findIndex(this.groupList, (item) => { return item.desk.id == data.id; }); if (index > -1) { this.groupList[index].zr.remove(this.groupList[index]); this.groupList.splice(index, 1); if (data.coordinates) { this.delCoord(data); } } else { return false; } }, clearDesk() { if (_.isEmpty(this.currentRow)) { return this.$message({ showClose: true, type: "warning", message: "请先点击选择左侧货架", }); } this.startDesk(this.currentRow); }, finishDesk(data) { let index = _.findIndex(this.groupList, (item) => { return item.desk.id == data.desk.id; }); if (index > -1) { this.groupList.splice(index, 1); } this.groupList.push(data); }, editDesk(data) { this.$refs.addDeskDialog.dialogInit(data); }, delDesk(data) { this.$confirm(this.$t("message.delete"), this.$t("message.prompt"), { confirmButtonText: this.$t("message.confirm"), cancelButtonText: this.$t("message.cancel"), type: "warning", }).then(() => { this.$api.management.delDesk({ id: data.id }).then((res) => { this.$message({ showClose: true, type: "success", message: "删除成功", }); this.getDeskList(); }); }); }, setCurrent(row, column, event) { this.$refs.singleTable.setCurrentRow(row); }, groupClick(group) { this.$refs.singleTable.setCurrentRow(group.desk); }, handleCurrentChange(val) { this.currentRow = val; }, addDesk() { this.$refs.addDeskDialog.dialogInit(); }, addField(data) { if (!data.id) { data.accountId = this.$cookie.get("accountId"); data.mallId = this.mallVal; data.floorId = this.floorVal; } data.doorway = data.doorway ? 1 : 0; this.$api.management.editDesk(data).then((res) => { this.$message({ showClose: true, type: "success", message: data.id ? "修改成功" : "添加成功", }); this.getDeskList(); this.$refs.addDeskDialog.addDialogClose(); }); }, // 保存 saveData() { let ajaxs = []; if (this.groupList.length == 0) { return this.$message({ showClose: true, type: "warning", message: "请先绘制货架图", }); } _.each(this.groupList, (group) => { ajaxs.push(this.editCoord(group)); }); Promise.all(ajaxs).then((res) => { this.$message({ showClose: true, type: "success", message: "保存成功", }); }); }, delCoord(data) { data.coordinates = ""; data.gateId = ""; data.deviceId = ""; data.channelSerialnum = ""; //let desk = _.omit(data,'coordinates','gateId','deviceId','channelSerialnum'); this.$api.management.editDesk(data); }, editCoord(group) { let { position, points, __zr, cdata, desk } = group; let [width, height] = [__zr.getWidth(), __zr.getHeight()]; let coordinates = _.map(points, (point) => { return { x: parseInt((1920 * (point[0] + position[0])) / width), y: parseInt((1080 * (point[1] + position[1])) / height), }; }); desk.coordinates = JSON.stringify(coordinates); desk.gateId = cdata.id; desk.deviceId = cdata.deviceId; desk.channelSerialnum = cdata.serialnum; let params = Object.assign({}, desk); return this.$api.management.editDesk(params); }, // 广场出入口列表 getDeskList() { this.$api.management .getDeskList({ mallId: this.mallVal, floorId: this.floorVal, page: 1, pageNum: 999, }) .then((res) => { this.tableData = res.data.data.list; setTimeout(() => { this.loading = false; }, 500); }); }, // 列表数据 getTableData() { this.loading = true; this.dataMsg = this.$t("echartsTitle.loading"); this.tableData = []; this.getDeskList(); if (this.ptype == 1) { console.log(444); this.loadGateData(); } else { this.drawFloorMap(); } }, // 广场 getMallList() { this.mallOpt = []; this.mallVal = null; this.mallName = ""; const storageMallVal = this.getSessionLocal("mallId"); this.$api.base .mall( { accountId: this.$cookie.get("accountId"), status_arr: "1,3", }, null, true ) .then((res) => { let result = res.data.data; if (result.length > 0) { this.mallOpt = result; if (storageMallVal) { this.mallVal = storageMallVal - 0; const matchedMall = result.find( (item) => item.id === this.mallVal ); this.mallName = matchedMall.name; } else { this.mallVal = result[0].id; this.setSessionLocal("mallId", this.mallVal); this.mallName = result[0].name; } } this.floorFetch(11); }) .catch((err) => { console.log(err); }); }, chooseMall(mallId) { this.setSessionLocal("mallId", mallId); const matchedMall = this.mallOpt.find((item) => item.id == mallId); this.mallName = matchedMall.name; this.floorVal = ""; this.floorImg = ""; this.floorFetch(); }, // 楼层 floorFetch() { this.floorOpt = []; this.floorVal = ""; this.floorImg = ""; this.$api.base .floor({ mallId: this.mallVal, status: 1, }) .then((data) => { var result = data.data; this.floorOpt = result.data; if (result.data.length) { this.floorVal = result.data[0].id; this.floorImg = window._vionConfig.picUrl + result.data[0].floorPlan; this.getTableData(); } else { this.tableData = []; } }); }, chooseFloor(floorVal) { this.floorImg = window._vionConfig.picUrl + _.findWhere(this.floorOpt, { id: floorVal }).floorPlan; this.getTableData(); }, loadGateData() { this.gateList = []; _.each(this.canvasList, (item) => { if (item.zr && item.zr.clear) { item.zr.clear(); } }); this.canvasList = []; if (!this.floorVal) { return; } Promise.all([this.getGateList(), this.getShotList()]).then((res) => { this.gateList = _.map(res[0], (item) => { let shot = _.findWhere(res[1], { gateId: item.id }); if (shot) { item.serialnum = shot.serialnum; item.deviceSerialnum = shot.deviceSerialnum; item.deviceId = shot.deviceId; //item.picUrl='https://store.keliuyun.com/images//snapshot/real/8F2B-3A9C-2A2D-6A06-01.jpg?t=1652495146'; item.picUrl = window._vionConfig.picUrl + "/snapshot/real/" + item.serialnum + ".jpg?t=" + Date.parse(new Date()) / 1000; } item.coordinates && (item.coordinates = JSON.parse(item.coordinates)); return item; }); this.drawJoinMap(); }); }, drawJoinMap() { this.loading = false; let that = this; let canvasList = []; _.each(this.gateList.reverse(), (item, index) => { if (item.picUrl) { let img = new Image(); img.src = item.picUrl; img.onload = function () { item.width = this.width; item.height = this.height; canvasList.push(item); that.$nextTick(() => { item.cwidth = document .querySelector(".dwrap") .getBoundingClientRect().width; item.cheight = (item.cwidth * item.height) / item.width; that.canvasList = canvasList; console.log(that.canvasList); }); }; } }); }, drawFloorMap() { let that = this; let floorData = {}; let img = new Image(); img.src = this.floorImg; img.onload = function () { floorData.width = this.width; floorData.height = this.height; that.$nextTick(() => { floorData.cwidth = document .querySelector(".pview") .getBoundingClientRect().width; floorData.cheight = (floorData.cwidth * floorData.height) / floorData.width; that.floorData = floorData; }); }; }, /*獲取監控點*/ getGateList() { return this.$api.management .gateFilterList({ mallId: this.mallVal, floorId: this.floorVal, }) .then((res) => { return res.data.data; }); }, /*獲取通道列表*/ getShotList() { return this.$api.management .channelFilterList({ mallId: this.mallVal, floorId_arr: this.floorVal, }) .then((res) => { return res.data.data; }); }, searchFun() { this.getTableData(); }, }, }; </script> <style scoped lang="less"> .manage-select-box .el-select { width: 150px; } .manage-container { height: 100%; /deep/ .el-table .cell { padding-right: 0; } /deep/.el-table tr { cursor: pointer; } /deep/.el-table__body tr.current-row > td.el-table__cell { background-color: #c8e1ff; } } .manage-content { height: calc(100% - 100px); } .personInfo { // padding-left: 10px; //padding-right: 10px; } .treeMenu { padding-right: 5px; border-right: 3px solid #f0f3f9; height: 100%; .treePage { padding: 2px 0; position: fixed; bottom: 15px; /deep/.el-pagination__jump { line-height: 22px; margin-left: 0; } } .btn-box { margin-bottom: 10px; } .btn-radio { /deep/.el-radio-button { width: 33%; } /deep/.el-radio-button__inner { width: 100%; } } } .title { font-weight: 900; text-align: left; width: 100%; .btnGroup { float: right; margin-right: 10px; } } .bind { color: #008000; margin-right: 5px; cursor: pointer; } .unbind { color: #ff0000; cursor: pointer; } .legends { text-align: right; } .draw_desks { position: relative; width: 100%; } .pwraper { position: relative; overflow: auto; min-height: 300px; margin-top: 10px; } .dlist { position: relative; clear: both; width: 100%; .ditem { width: calc(50% - 10px); float: left; margin: 0 5px 8px 5px; .dimg { display: block; width: 100%; } } } .dwrap { position: relative; } .fwrap { position: relative; padding-left: 10px; padding-top: 10px; } .fwrap .dimg { width: 100%; } .label-box { position: absolute; pointer-events: none; left: 7px; bottom: 5px; color: #f00; } .pview { position: absolute; left: 0; top: 0; width: 100%; height: 100%; } </style>