<template> <div class="adm-device"> <statistics :statistics-msg="statisticsMsg"/> <div class="operation"> <el-cascader :options="list" clearable v-model="deviceType" :props="optionProps" @change="handleChangeDevice" class="adm-select"></el-cascader> <admSearch @SearchValue="SearchValue"/> <el-button type="default" @click="addDevice" class="adm-btn">添加设备</el-button> </div> <div class="hr"></div> <div class="content"> <el-tabs v-model="activeName" type="card" @tab-click="handleClick"> <el-tab-pane v-for="(item,index) in paneMsg" :key="index" :label="item" :name="index.toString()"/> </el-tabs> <div class="table" v-loading="loading"> <template v-if="deviceType.length > 0"> <admMultiTable :currentHeader="currentHeader" @handleCurrentEdit="handleCurrentEdit" :tableData="tableData" :headersStage="headersStage"/> <Pagination v-if="tableData.length > 0" :paginationList="paginationList" @handleCurrentChange="handleCurrentChange" @handleSizeChange="handleSizeChange"/> </template> <div v-else class="void align"> <svg-icon name="void" :width="String(120)" :height="String(123)"/> <p class="void-title">暂无内容</p> <p class="void-tips">可点击左上角选择设备类型</p> </div> </div> </div> <!-- 添加/编辑 设备--> <el-scrollbar style="height:400px;"> <el-dialog :title="deviceMsg" :width="!isWidth ? '20%':''" :visible.sync="dialogVisible" @close="close"> <template slot="title"> <div class="alertTitle"> <span>{{ deviceMsg }}</span> <el-button type="text"> <span class="el-icon-question"/> <a href="/datacenter/object/equip/downloads" download="维护帮助"> 维护帮助</a> </el-button> </div> </template> <template v-if="deviceMsg == '添加设备'"> <template v-if="next"> <div class="align " :style="{ 'height': isWidth ? '400px':'200px' }"> <span class="text ">设备类别</span> <el-cascader :options="list" clearable v-model="deviceVal" :props="optionProps" class="adm-select"></el-cascader> </div> <el-button type="primary" class="fr" @click="handleNext">下一步</el-button> </template> <template v-else-if="displayLocation && deviceVal"> <deviceGraph ref="deviceGraph" :equip="curEquip" @goBack="goBack"/> <span slot="footer" class="dialog-footer"> <el-button type="primary" @click="saveLocation">确定</el-button> <el-button type="default" @click="resetLocation">重置</el-button> </span> </template> <template v-else> <dataForm :deviceHeaders="deviceHeaders" ref="dataForm" :currRowContent="currRowContent"/> <span slot="footer" class="dialog-footer"> <el-button type="primary" @click="handleDataForm">确 定</el-button> <el-button @click="handlePosition">维护位置</el-button> </span> </template> </template> <template v-else> <template v-if="displayLocation && deviceVal"> <deviceGraph ref="deviceGraph" :equip="curEquip" @goBack="goBack"/> <span slot="footer" class="dialog-footer"> <el-button type="primary" @click="saveLocation">确定</el-button> <el-button type="default" @click="resetLocation">重置</el-button> </span> </template> <template v-else> <dataForm :deviceHeaders="deviceHeaders" ref="dataForm" :currRowContent="currRowContent"/> <span slot="footer" class="dialog-footer"> <el-button type="danger" style="float: left" @click="deleteDevice">删除设备</el-button> <el-button type="primary" @click="handleDataForm">确 定</el-button> <el-button @click="handlePosition">维护位置</el-button> </span> </template> </template> </el-dialog> </el-scrollbar> </div> </template> <script lang="ts"> import {Component, Vue, Watch} from "vue-property-decorator"; import {AdmMultiTable, AdmSearch, dataForm, Pagination, Statistics} from '../components/index' import {allDevice, BeatchQueryParam, dictInfo} from "@/api/equipComponent"; import {createEquip, queryCount, queryEquip, updateEquip, deleteEquip} from "@/api/datacenter"; import {UserModule} from "@/store/modules/user"; import deviceGraph from "./components/deviceGraph.vue" import tools from "@/utils/maintain" @Component({ name: 'adm-device', components: {Statistics, AdmSearch, AdmMultiTable, Pagination, dataForm, deviceGraph} }) export default class extends Vue { optionProps = { value: 'code', label: 'aliasName', children: 'children' } // loading loading = false // 统计信息对象 private statisticsMsg = { title: '全部设备', total: 0 } // 设置高度 isWidth = false // 设备类值 deviceType = '' // 弹窗设备类值 deviceVal = '' // 维护位置 displayLocation = false // 表头信息集合 headerInformation = {} // 表头阶段信息结合 headersStage = {} // 当前阶段表头信息点集合 all = [] // 搜索内容 inputSearch = '' // 下拉数据 list = [] // 弹窗开关 dialogVisible = false // tabs数据 paneMsg = [] // 当前tabs值 activeName = 0 // 分页 paginationList = { page: 1, size: 50, sizes: [10, 30, 50, 100, 150, 200], total: 0 } // 下一步 next = true // 弹窗 title deviceMsg = '' // 默认当前阶段 currentHeader = '' // 主体数据 tableData = [] codeToDataSource = {} deviceHeaders = {} // 当前行数据 currRowContent = {} // 维护位置开关 maintain = '' // 传到维护位置的设备信息 curEquip = {} // 项目id get projectId(): string { return UserModule.projectId } created() { this.deviceList(); this.dataCount() } //查询统计数量 dataCount() { queryCount({}).then(res => { this.statisticsMsg.total = res.count }) } // 设备类数据 deviceList() { allDevice({}).then(res => { this.list = res.content console.log(res) }) } handleChangeDevice() { if (this.deviceType[1]) { this.loading = true let param = { category: this.deviceType[1] } let param2 = { filters: this.deviceType[1] ? `classCode='${this.deviceType[1]}'` : undefined, pageNumber: this.paginationList.page, pageSize: this.paginationList.size, orders: "createTime desc, id asc", projectId: this.projectId, cascade: [{"name": "floor",}, {"name": "objectInfo"}] } if (this.inputSearch != '') { param2.filters += `;codeName contain '${this.inputSearch}' or systemCategory contain '${this.inputSearch}' or bimTypeId contain '${this.inputSearch}' or localId contain '${this.inputSearch}'` } let promise = new Promise(resolve => { dictInfo(param).then((res: []) => { resolve(res) }) }) let promise2 = new Promise(resolve => { queryEquip(param2).then((res: []) => { resolve(res) }) }) Promise.all([promise, promise2]).then(res => { this.loading = false // 类型下信息点,默认设计阶段 this.headerInformation = res[0] // 获取表头 // this.tableData = res[1].content // 主体数据 this.tableData = res[1].content this.paneMsg = res[0].dictStages.map(i => i.name) this.currentHeader = this.paneMsg[this.activeName] this.headerStage() this.paginationList.total = res[1].total }) } else { this.headerInformation = {} } } async handleNext() { if (this.deviceVal[1]) { this.next = false this.isWidth = true let param = { category: this.deviceVal[1] } await dictInfo(param).then(res => { const basicInfos = [{path: 'bimTypeName', aliasName: '构件分类名称', category: "STATIC", editable: true}, {path: 'localId', aliasName: '本地编码', category: "STATIC", editable: true}, {path: 'floor.localName', editable: false, aliasName: '所属楼层', category: "STATIC"}, { path: 'onSpace', editable: false, aliasName: '所在空间', dataType: 'STRING', category: "STATIC", render: (obj: any) => { return obj?.objectInfo && obj.objectInfo.map((item: any) => item.localName).join(',') || '' } }] this.deviceHeaders = { basicInfos, dictStages: res.dictStages } }) } else { console.log(5) } } headerStage() { let pic = [], base = [] if (Object.keys(this.headerInformation).length > 0) { this.headerInformation.dictStages.forEach(item => { if (this.currentHeader == item.name) { item.infos && item.infos.forEach(val => { if (val.dataType == 'ATTACHMENT') { pic.push(val) } else { base.push(val) } }) } }) } // this.headersStage = { // basicInfos: { // name: '基础信息台账', // data: this.headerInformation.basicInfos // }, // dictStages: { // name: this.currentHeader, // data: pic.length > 0 ? [...base, ...pic] : [...base] // } // } // todo 固定写死基础信息台账 this.headersStage = { basicInfos: { name: '基础信息台账', data: [ {path: 'bimTypeName', aliasName: '构件分类名称', category: "STATIC"}, {path: 'localId', aliasName: '本地编码', category: "STATIC"}, {path: 'floor.localName', editable: false, aliasName: '所属楼层', category: "STATIC"}, { path: 'onSpace', editable: false, aliasName: '所在空间', dataType: 'STRING', category: "STATIC", render: (obj: any) => { return obj?.objectInfo && obj.objectInfo.map((item: any) => item.localName).join(',') || '' } } ], }, dictStages: { name: this.currentHeader, data: pic.length > 0 ? [...base, ...pic] : [...base] } } // 信息点集合 this.all = [...this.headersStage.basicInfos.data, ...this.headersStage.dictStages.data] this.codeToDataSource = {} this.all.forEach(item => { if (item.dataSource) { try { this.codeToDataSource[item.code] = {} item.dataSource.forEach(dic => { this.codeToDataSource[item.code][dic.code] = dic.name; }) } catch (e) { console.log(e); } } }); this.getBatch(this.tableData) } // 查询动态数据 getBatch(data) { let param = { groupCode: 'WD', appId: 'datacenter', projectId: this.projectId, data: [] } this.all.forEach(head => { if (head.category != 'STATIC') { data.forEach(item => { let cur = tools.dataForKey(item, head.path) if (cur) { param.data.push({ objectId: item.id, infoCode: head.code }) } }) } }) if (param.data.length > 0) { BeatchQueryParam(param).then(res => { this.tableData = data.map(item => { res.data.map(child => { if (item.id == child.objectId) { if (!!child.data || child.data == 0) { this.all.map(head => { if (head.code == child.infoCode) { let contentVal = child.data if (this.codeToDataSource[child.infoCode]) { contentVal = this.codeToDataSource[child.infoCode][child.data] } tools.setDataForKey(item, head.path, contentVal); } }) } else { this.all.map(head => { if (head.code == child.infoCode) { tools.setDataForKey( item, head.path, child.error ? child.value ? "表号功能号格式错误" : "表号功能号不存在" : "暂未采集到实时数据" ); } }); } } }) return item }) }) } } // 维护阶段 tabs async handleClick(val: any) { this.currentHeader = val.label await this.headerStage() } // 搜索 SearchValue(val: string) { this.inputSearch = val this.handleChangeDevice(this.deviceType[1]) } // 当前分页 handleCurrentChange(val: number) { console.log(val) this.paginationList.page = val this.handleChangeDevice(this.deviceType[1]) } handleSizeChange(val: number) { this.paginationList.size = val this.handleChangeDevice(this.deviceType[1]) } // 添加设备 addDevice() { this.deviceMsg = '添加设备' this.dialogVisible = true this.currRowContent = {} } // 维护位置 handlePosition() { this.currentRow = this.$refs.dataForm.form this.$refs.dataForm.submitForm(this.handlePositionSave) } handlePositionSave() { this.curEquip = tools.formatData(this.$refs.dataForm.form) this.displayLocation = true } // 添加 事件处理 handleDataForm() { this.$refs.dataForm.submitForm(this.handleDataFormSave) } // 删除设备 deleteDevice() { deleteEquip([{id: this.currRowContent.id}]).then(res => { if (res.result == 'success') { this.$message.success('删除成功') this.handleChangeDevice() this.dialogVisible = false; } }) } handleDataFormSave() { const eq = tools.formatData(this.$refs.dataForm.form); if (eq.id) { //更新 this.handleUpdateEquip(eq); } else { eq.classCode = this.deviceVal[1] // 创建 this.handleCreateEquip(eq); } } // 编辑当前行 handleCurrentEdit(val: object) { this.deviceMsg = '编辑设备' this.currRowContent = val this.handleNext() this.dialogVisible = true } // close close() { this.next = true this.isWidth = false if (this.deviceType) { this.deviceVal = this.deviceType } else { this.deviceVal = '' } this.displayLocation = false } // 取消 cancelLocation() { // @ts-ignore this.$refs.deviceGraph.cancelLocation() } // 保存 saveLocation() { // @ts-ignore const data = this.$refs.deviceGraph.getLocation() if (data) { this.curEquip.bimLocation = `${data.x},${data.y},${data.z}`; this.curEquip.buildingId = data.buildingId; this.curEquip.floorId = data.floorId; } if (this.curEquip.id) { //更新 this.handleUpdateEquip(this.curEquip); } else { this.curEquip.classCode = this.deviceVal[1] // 创建 this.handleCreateEquip(this.curEquip); } } // 更新设备 handleUpdateEquip(obj) { let pa; if (Array.isArray(obj)) { pa = {content: obj} } else { pa = {content: [obj]} } updateEquip(pa).then(res => { if (res.result == 'success') { this.$message.success('更新成功'); this.dialogVisible = false; this.handleChangeDevice() } }) } // 创建设备 handleCreateEquip(obj: any) { let pa; if (Array.isArray(obj)) { pa = {content: obj} } else { pa = {content: [obj]} } createEquip(pa).then(res => { if (res.result == 'success') { this.$message.success('创建成功'); this.dialogVisible = false; this.handleChangeDevice() } }) } // 重置 resetLocation() { // @ts-ignore this.$refs.deviceGraph.resetLocation() } // 返回 goBack() { this.displayLocation = false this.currRowContent = this.currentRow } @Watch("deviceType", {immediate: true, deep: true}) handleDeviceMsg() { this.deviceVal = this.deviceType } } </script> <style lang="scss" scoped> $margin: 12px; $border: 1px solid #E1E7EA; .align { display: flex; align-items: center; justify-content: center; flex-direction: column; flex-wrap: wrap; .text { margin-right: 150px; margin-bottom: 10px; } } .adm-device { background: #fff; padding: 12px; height: 100%; .el-dialog__header { padding: 10px; } .operation { margin: 12px 0; .adm-select { margin-right: $margin; } .adm-btn { float: right; } } .hr { background: #E1E7EA; color: #E1E7EA; width: 100%; height: 1px; margin-bottom: 16px; } .content { position: relative; height: calc(100% - 140px); .table { border-left: $border; border-right: $border; border-bottom: $border; height: calc(100% - 41px); padding: 12px; padding-bottom: 50px; .void { margin-top: 200px; } .void-title { color: #333333; line-height: 21px; font-size: 16px; } .void-tips { color: #9CA1A9; line-height: 22px; font-size: 14px; } } .adm-multi-table { } } .adm-pagination { right: 10px; position: absolute; bottom: 10px; } } </style> <style lang="scss"> .adm-device { .el-dialog__header { padding: 10px; } .el-select, .el-date-editor.el-input, .el-date-editor.el-input__inner { width: 100%; } } .data-form { height: 430px; } .text { color: #000000; margin-bottom: 10px; } .el-tabs__header { margin: 0; } .el-dialog__header { border-bottom: 1px solid #D8D8D8; } .fr { float: right; } .dialog-button { float: right; margin-left: 10px; margin-top: 30px; } .el-dialog { .el-dialog__body { padding: 20px; max-height: 643px !important; min-height: 100px; overflow-y: auto; overflow-x: hidden; } } .alertTitle { overflow: hidden; line-height: 32px; button { float: right; margin-right: 40px; } } </style>