1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150 |
- <template>
- <div class="app-container">
- <el-row :gutter="20">
- <el-col :span="4" :xs="24">
- <div v-if="activeTab === 'area'" >
- <div class="head-container">
- <el-input v-model="areaName" placeholder="请输入区块名称" clearable size="small" prefix-icon="el-icon-search"
- style="margin-bottom: 20px" />
- </div>
- <div class="head-container">
- <el-tree :data="areaList" :props="defaultProps" :expand-on-click-node="false" :filter-node-method="filterNode" ref="tree"
- node-key="id" default-expand-all highlight-current @node-click="handleNodeClick" style="height: calc(100vh - 50px); overflow-y: auto;">
- <template slot-scope="scope">
- <div class="custom-tree-node">
- <span>{{ scope.node.label }}</span>
- <el-button
- v-if="scope.node.data.id !== 'all' && scope.node.data.children && scope.node.data.children.length > 0"
- size="mini"
- type="text"
- icon="el-icon-map-location"
- @click="showTopology(scope.node.data)"
- >拓扑图</el-button>
- </div>
- </template>
- </el-tree>
- </div>
- </div>
- <div v-if="activeTab === 'organ'">
- <div class="head-container">
- <el-input v-model="deptName" placeholder="请输入区块名称" clearable size="small" prefix-icon="el-icon-search"
- style="margin-bottom: 20px" />
- </div>
- <div class="head-container">
- <el-tree :key="treeKey" :data="deptList" :props="defaultDeptProps" :expand-on-click-node="false" :filter-node-method="filterNode" ref="tree"
- node-key="deptId" default-expand-all highlight-current @node-click="handleDeptNodeClick" style="height: calc(100vh - 50px); overflow-y: auto;">
- </el-tree>
- </div>
- </div>
- <div v-if="activeTab === 'facs'">
- <div class="head-container">
- <el-input v-model="areaName" placeholder="请输入区块名称" clearable size="small" prefix-icon="el-icon-search"
- style="margin-bottom: 20px"
- />
- </div>
- <div class="head-container">
- <el-tree :key="tableKey" :data="facsOptions" :props="defaultFacsProps" :expand-on-click-node="false"
- :filter-node-method="filterNode" ref="tree"
- node-key="id" default-expand-all highlight-current @node-click="handleFacsNodeClick"
- style="height: calc(100vh - 50px); overflow-y: auto;">
- </el-tree>
- </div>
- </div>
- <div v-if="activeTab === 'device'" class="device-tree-container">
- <div class="head-container">
- <el-input v-model="areaName" placeholder="请输入区块名称" clearable size="small" prefix-icon="el-icon-search"
- style="margin-bottom: 20px"
- />
- </div>
- <div class="head-container">
- <el-tree :key="tableKey" :data="deviceOptions" :props="defaultFacsProps" :expand-on-click-node="false"
- :filter-node-method="filterNode" ref="tree"
- node-key="id" default-expand-all highlight-current @node-click="handleDeviceNodeClick"
- class="device-tree">
- </el-tree>
- </div>
- </div>
- </el-col>
- <el-tabs v-model="activeTab" @tab-click="handleTabClick">
- <el-tab-pane label="地理位置" name="area"></el-tab-pane>
- <el-tab-pane label="组织机构" name="organ"></el-tab-pane>
- <el-tab-pane label="设施" name="facs"></el-tab-pane>
- <el-tab-pane label="设备" name="device"></el-tab-pane>
- </el-tabs>
- <el-col :span="20" :xs="24">
- <!-- 地理位置 -->
- <div v-if="activeTab === 'area'">
- <el-tabs v-model="activeDeviceTab" @tab-click="handleADTabClick">
- <el-tab-pane label="电表" name="electricMeter"></el-tab-pane>
- <el-tab-pane label="水表" name="waterMeter"></el-tab-pane>
- </el-tabs>
- <SubTitle title="已绑定列表" />
- <el-table v-loading="loading" :data="areaBound" style="width: 100%">
- <el-table-column label="表计编号" align="left" prop="meterDevice" />
- <el-table-column label="表计名称" align="left" prop="meterDeviceName" />
- <el-table-column label="边界类型" align="left" prop="objType">
- <template slot-scope="scope">
- {{ getObjTypeLabel(scope.row.objType) }}
- </template>
- </el-table-column>
- <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
- <template slot-scope="scope">
- <el-button size="mini" type="text" icon="el-icon-arrow-down" @click="downToDevice(scope.row, 'area')">取消绑定</el-button>
- </template>
- </el-table-column>
- </el-table>
- <SubTitle title="未绑定列表" />
- <el-table v-loading="loading" :data="areaUnbound" style="width: 100%">
- <el-table-column label="表计编号" align="left" prop="deviceCode" />
- <el-table-column label="表计名称" align="left" prop="deviceName" width="200px"/>
- <el-table-column label="安装位置" align="left" prop="deviceLocation" width="200px"/>
- <el-table-column label="计量标签" align="center" prop="objTag">
- <template slot-scope="scope">
- {{formatDict(scope.row.objTag,'objTagOptions')}}
- </template>
- </el-table-column>
- <el-table-column label="采集方式" align="center" prop="colMode">
- <template slot-scope="scope">
- <span>{{ getColModeName(scope.row.colMode) }}</span>
- </template>
- </el-table-column>
- <el-table-column label="采集周期" align="center" prop="colCycle">
- <template slot-scope="scope">
- <span>{{ getColCycleName(scope.row.colCycle) }}</span>
- </template>
- </el-table-column>
- <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
- <template slot-scope="scope">
- <div v-if="isAlreadyBound(scope.row.deviceCode, 'area')">
- <span>已绑定</span>
- </div>
- <div v-else>
- <el-button size="mini" type="text" icon="el-icon-arrow-up" @click="moveToDevice(scope.row, 'area')">绑定</el-button>
- </div>
- </template>
- </el-table-column>
- </el-table>
- <pagination v-show="total>0" :total="total" :page.sync="MeterQueryParams.pageNum"
- :limit.sync="MeterQueryParams.pageSize" @pagination="getMeterData('area')"
- />
- </div>
- <!-- 组织机构 -->
- <div v-if="activeTab === 'organ'">
- <el-tabs v-model="activeDeviceTab" @tab-click="handleADTabClick">
- <el-tab-pane label="电表" name="electricMeter"></el-tab-pane>
- <el-tab-pane label="水表" name="waterMeter"></el-tab-pane>
- </el-tabs>
- <SubTitle title="已绑定列表" />
- <el-table v-loading="loading" :data="organBound" style="width: 100%">
- <el-table-column label="表计编号" align="left" prop="meterDevice" />
- <el-table-column label="表计名称" align="left" prop="meterDeviceName" />
- <el-table-column label="边界类型" align="left" prop="objType">
- <template slot-scope="scope">
- {{ getObjTypeLabel(scope.row.objType) }}
- </template>
- </el-table-column>
- <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
- <template slot-scope="scope">
- <el-button size="mini" type="text" icon="el-icon-arrow-down" @click="downToDevice(scope.row, 'organ')">取消绑定</el-button>
- </template>
- </el-table-column>
- </el-table>
- <SubTitle title="未绑定列表" />
- <el-table v-loading="loading" :data="organUnbound" style="width: 100%">
- <el-table-column label="表计编号" align="left" prop="deviceCode" />
- <el-table-column label="表计名称" align="left" prop="deviceName" width="200px"/>
- <el-table-column label="安装位置" align="left" prop="deviceLocation" width="200px"/>
- <el-table-column label="计量标签" align="center" prop="objTag">
- <template slot-scope="scope">
- {{formatDict(scope.row.objTag,'objTagOptions')}}
- </template>
- </el-table-column>
- <el-table-column label="采集方式" align="center" prop="colMode">
- <template slot-scope="scope">
- <span>{{ getColModeName(scope.row.colMode) }}</span>
- </template>
- </el-table-column>
- <el-table-column label="采集周期" align="center" prop="colCycle">
- <template slot-scope="scope">
- <span>{{ getColCycleName(scope.row.colCycle) }}</span>
- </template>
- </el-table-column>
- <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
- <template slot-scope="scope">
- <div v-if="isAlreadyBound(scope.row.deviceCode, 'organ')">
- <span>已绑定</span>
- </div>
- <div v-else>
- <el-button size="mini" type="text" icon="el-icon-arrow-up" @click="moveToDevice(scope.row, 'organ')">绑定</el-button>
- </div>
- </template>
- </el-table-column>
- </el-table>
- <pagination v-show="total>0" :total="total" :page.sync="MeterQueryParams.pageNum"
- :limit.sync="MeterQueryParams.pageSize" @pagination="getMeterData('organ')" />
- </div>
- <!-- 设施 -->
- <div v-if="activeTab === 'facs'">
- <el-tabs v-model="activeDeviceTab" @tab-click="handleADTabClick">
- <el-tab-pane label="电表" name="electricMeter"></el-tab-pane>
- <el-tab-pane label="水表" name="waterMeter"></el-tab-pane>
- </el-tabs>
- <SubTitle title="已绑定列表" />
- <el-table v-loading="loading" :data="facsBound" style="width: 100%">
- <el-table-column label="表计编号" align="left" prop="meterDevice" />
- <el-table-column label="表计名称" align="left" prop="meterDeviceName" />
- <el-table-column label="边界类型" align="left" prop="objType">
- <template slot-scope="scope">
- {{ getObjTypeLabel(scope.row.objType) }}
- </template>
- </el-table-column>
- <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
- <template slot-scope="scope">
- <el-button size="mini" type="text" icon="el-icon-arrow-down" @click="downToDevice(scope.row, 'facs')">取消绑定</el-button>
- </template>
- </el-table-column>
- </el-table>
- <SubTitle title="未绑定列表" />
- <el-table v-loading="loading" :data="facsUnbound" style="width: 100%">
- <el-table-column label="表计编号" align="left" prop="deviceCode" />
- <el-table-column label="表计名称" align="left" prop="deviceName" width="200px"/>
- <el-table-column label="安装位置" align="left" prop="deviceLocation" width="200px"/>
- <el-table-column label="计量标签" align="center" prop="objTag">
- <template slot-scope="scope">
- {{formatDict(scope.row.objTag,'objTagOptions')}}
- </template>
- </el-table-column>
- <el-table-column label="采集方式" align="center" prop="colMode">
- <template slot-scope="scope">
- <span>{{ getColModeName(scope.row.colMode) }}</span>
- </template>
- </el-table-column>
- <el-table-column label="采集周期" align="center" prop="colCycle">
- <template slot-scope="scope">
- <span>{{ getColCycleName(scope.row.colCycle) }}</span>
- </template>
- </el-table-column>
- <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
- <template slot-scope="scope">
- <div v-if="isAlreadyBound(scope.row.deviceCode, 'facs')">
- <span>已绑定</span>
- </div>
- <div v-else>
- <el-button size="mini" type="text" icon="el-icon-arrow-up" @click="moveToDevice(scope.row, 'facs')">绑定</el-button>
- </div>
- </template>
- </el-table-column>
- </el-table>
- <pagination v-show="total>0" :total="total" :page.sync="MeterQueryParams.pageNum"
- :limit.sync="MeterQueryParams.pageSize" @pagination="getMeterData('facs')" />
- </div>
- <!--设备 -->
- <div v-if="activeTab === 'device'">
- <el-tabs v-model="activeDeviceTab" @tab-click="handleADTabClick">
- <el-tab-pane label="电表" name="electricMeter"></el-tab-pane>
- <el-tab-pane label="水表" name="waterMeter"></el-tab-pane>
- </el-tabs>
- <SubTitle title="已绑定列表" />
- <el-table v-loading="loading" :data="deviceBound" style="width: 100%">
- <el-table-column label="表计编号" align="left" prop="meterDevice" />
- <el-table-column label="表计名称" align="left" prop="meterDeviceName" />
- <el-table-column label="边界类型" align="left" prop="objType">
- <template slot-scope="scope">
- {{ getObjTypeLabel(scope.row.objType) }}
- </template>
- </el-table-column>
- <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
- <template slot-scope="scope">
- <el-button size="mini" type="text" icon="el-icon-arrow-down" @click="downToDevice(scope.row, 'device')">取消绑定</el-button>
- </template>
- </el-table-column>
- </el-table>
- <SubTitle title="未绑定列表" />
- <el-table v-loading="loading" :data="deviceUnbound" style="width: 100%">
- <el-table-column label="表计编号" align="left" prop="deviceCode" />
- <el-table-column label="表计名称" align="left" prop="deviceName" width="200px"/>
- <el-table-column label="安装位置" align="left" prop="deviceLocation" width="200px"/>
- <el-table-column label="计量标签" align="center" prop="objTag">
- <template slot-scope="scope">
- {{formatDict(scope.row.objTag,'objTagOptions')}}
- </template>
- </el-table-column>
- <el-table-column label="采集方式" align="center" prop="colMode">
- <template slot-scope="scope">
- <span>{{ getColModeName(scope.row.colMode) }}</span>
- </template>
- </el-table-column>
- <el-table-column label="采集周期" align="center" prop="colCycle">
- <template slot-scope="scope">
- <span>{{ getColCycleName(scope.row.colCycle) }}</span>
- </template>
- </el-table-column>
- <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
- <template slot-scope="scope">
- <div v-if="isAlreadyBound(scope.row.deviceCode, 'device')">
- <span>已绑定</span>
- </div>
- <div v-else>
- <el-button size="mini" type="text" icon="el-icon-arrow-up" @click="moveToDevice(scope.row, 'device')">绑定</el-button>
- </div>
- </template>
- </el-table-column>
- </el-table>
- <pagination v-show="total>0" :total="total" :page.sync="MeterQueryParams.pageNum"
- :limit.sync="MeterQueryParams.pageSize" @pagination="getMeterData('device')" />
- </div>
- </el-col>
- </el-row>
- <!-- 拓扑图弹框 -->
- <el-dialog :visible.sync="topologyDialogVisible" title="拓扑图" width="1500px" @open="scrollToCenter">
- <div class="topology-chart-container" ref="topologyChartContainer">
- <div ref="topologyChart" class="topology-chart" style="width: 8000px; height: 600px;"></div>
- </div>
- </el-dialog>
- </div>
- </template>
- <script>
- import * as echarts from 'echarts';
- import Treeselect from '@riophae/vue-treeselect'
- import '@riophae/vue-treeselect/dist/vue-treeselect.css'
- import { areaTreeSelect, listDetailArea } from '@/api/basecfg/area'
- import SubTitle from '@/components/SubTitle/index.vue'
- import { getDevProcess, getEmsTag } from '@/api/commonApi'
- import { listDevice } from '@/api/device/meterDevice'
- import { addAllByObj, listByObj ,getBoundaryTreeByArea } from '@/api/basecfg/meterBoundary'
- import { listDept } from '@/api/system/dept'
- import { getFacsCategoryTree, listAllFacs } from '@/api/basecfg/emsfacs'
- import { listSubsystemAll } from '@/api/adapter/subsystem'
- import {getTreeByFacs} from '@/api/device/device.js'
- export default {
- name: 'Device',
- dicts: ['sys_normal_disable'],
- components: { SubTitle, Treeselect },
- data() {
- return {
- topologyDialogVisible: false,
- activeTab: 'area',
- areaOptions: [],
- organOptions: [],
- facsOptions: undefined,
- facsAllOptions:undefined,
- deviceOptions:undefined,
- // 区域名称
- areaName: undefined,
- deptName:undefined,
- defaultProps: {
- children: 'children',
- label: 'areaName'
- },
- defaultDeptProps: {
- children: 'children',
- label: 'deptName'
- },
- defaultFacsProps: {
- children: 'children',
- label: 'label'
- },
- treeKey: 0,
- tableKey: 0,
- // 遮罩层
- loading: true,
- // 选中数组
- ids: [],
- // 非单个禁用
- single: true,
- // 非多个禁用
- multiple: true,
- // 显示搜索条件
- showSearch: true,
- // 区域对象表格数据
- areaList: [],
- deptList:[],
- facsList:[],
- deviceList:[],
- // 总条数
- total: 0,
- // 弹出层标题
- title: "",
- // 是否显示弹出层
- open: false,
- // 是否展开,默认全部展开
- isExpandAll: true,
- // 重新渲染表格状态
- refreshTable: true,
- // 标签选项
- emsTagOptions: [],
- tagCodeToColorMap:{},
- // 地理位置查询参数
- queryParams: {
- pageNum: 1,
- pageSize: 10,
- areaCode: null,
- parentCode: null,
- ancestors: null,
- areaName: null,
- shortName: null,
- desc: null,
- orderNum: null,
- status: null,
- tagNames:null,
- areaAttr:{}
- },
- // 组织机构查询参数
- DeptQueryParams: {
- deptName: undefined,
- status: undefined
- },
- // 设施 查询参数
- FacsQueryParams: {
- pageNum: 1,
- pageSize: 10,
- facsCode: null,
- facsName: null,
- facsCategory: 'E',
- facsSubCategory: null,
- enable: null,
- refArea: null,
- customAttrs: null
- },
- // 设备查询参数
- DeviceQueryParams: {
- psCode: null,
- pageNum: 1,
- pageSize: 10,
- deviceCode: null,
- deviceSubCategory: '',
- deviceCategory: 'E',
- locationRef: null,
- refFacs: null,
- customAttrs: null
- },
- // 水表、电表查询参数
- MeterQueryParams: {
- pageNum: 1,
- pageSize: 10,
- areaCode: null,
- bldgCode: null,
- deviceCode: null,
- meterCls: null,
- objTag: null,
- colCycle: null,
- colMode: null,
- magnification: null,
- specDesc: null
- },
- objStatusMapping: {
- 0: '正常',
- 1: '停用',
- },
- // 表单参数
- form: {
- areaAttr: {
- areaCode:null,
- attrOrg: null,
- mgrOrg: null,
- leader: null,
- phone: null,
- openDate: null,
- floorArea: null,
- usableArea: null,
- floor: null,
- tagCodes:null,
- tagNames:null,
- tagCodeList:[]
- }
- },
- // 表单校验
- rules: {
- areaCode: [
- { required: true, message: "区域代码不能为空", trigger: "blur" }
- ],
- areaName: [
- { required: true, message: "区域名称不能为空", trigger: "blur" }
- ],
- },
- objTagOptions: [
- { code: 0, name: '公摊表' },
- { code: 1, name: '个户表' }
- ],
- allAreaNode: {
- id: 'all',
- areaName: '全部',
- children: []
- },
- allDeptNode: {
- deptId: 'all',
- deptName: '全部',
- children: []
- },
- // 设施分类列表
- facsCategoryOptions: undefined,
- facsSubCategoryOptions: undefined,
- // 设备分类
- subCategoryOptions: undefined,
- subsystemOptions: undefined,
- subcategoryCode: '',
- devOptions: undefined,
- parentAreaCode:'',
- dialogTitle: '',
- deviceDialogVisible: false,
- activeDeviceTab: 'electricMeter',
- areaBound: [],
- areaUnbound: [],
- organBound: [],
- organUnbound: [],
- facsBound: [],
- facsUnbound: [],
- deviceBound: [],
- deviceUnbound: [],
- }
- },
- mounted() {
- this.getList();
- this.getFacsList();
- this.getDeviceList();
- },
- created() {
- this.getAreaFacsTree('0', 1)
- this.getAreaDeviceTree('0', 1)
- this.getAllDevProcess(this.subcategoryCode)
- this.getEmsTag('Area');
- this.getFacsOptions()
- this.getSubsystem()
- this.form.areaAttr = {};
- this.getList();
- },
- methods: {
- getAreaFacsTree(areaCode, layer) {
- areaTreeSelect(areaCode, layer).then(response => {
- this.facsOptions = [{
- id: '-1',
- label: '全部',
- children: response.data
- }]
- })
- },
- getAreaDeviceTree(areaCode, layer) {
- areaTreeSelect(areaCode, layer).then(response => {
- this.deviceOptions = [{
- id: null,
- label: '全部',
- children: response.data
- }]
- })
- },
- filterNode(value, data) {
- if (!value) return true
- return data.label.indexOf(value) !== -1
- },
- getObjTypeLabel(objType) {
- const typeLabels = {
- 1: '区域位置',
- 2: '设施',
- 3: '设备',
- 4: '组织'
- };
- return typeLabels[objType] || '未知类型';
- },
- formatDict(val, options, key = 'code', text = 'name') {
- if (!this[options] || !Array.isArray(this[options])) {
- console.error(`Expected an array for this[${options}], but got ${typeof this[options]}`);
- return '';
- }
- let name = '';
- this[options].forEach(item => {
- if (val === item[key]) {
- name = item[text];
- }
- });
- return name;
- },
- getColCycleName(colCycle) {
- const cycleMap = {
- 0: '实时',
- 1: '分钟',
- 2: '小时',
- 3: '天',
- 4: '月'
- }
- return cycleMap[colCycle] || ''
- },
- getColModeName(colMode) {
- const modeMap = {
- 0: '自动抄表',
- 1: '手动抄表'
- }
- return modeMap[colMode] || '未知'
- },
- /**分页*/
- handleTabClick(tab) {
- this.reset();
- this.MeterQueryParams.pageNum = 1;
- this.activeDeviceTab= 'electricMeter';
- if (tab.name === 'area') {
- this.showSearch = true;
- this.getList();
- } else if (tab.name === 'organ') {
- this.showSearch = true;
- this.getDeptList();
- } else if (tab.name === 'facs') {
- this.showSearch = true;
- this.getFacsList()
- }else if (tab.name === 'device') {
- this.showSearch = true;
- this.getDeviceList();
- }
- },
- /**电表、水表分页*/
- handleADTabClick(tab){
- this.activeDeviceTab = tab.name;
- this.getMeterData();
- },
- /**地理位置*/
- handleNodeClick(data) {
- // 不执行任何操作
- if (data.id === 'all') {
- return;
- }
- this.queryParams.areaCode = data.areaCode;
- if (data && data.ancestors) {
- const ancestorsArray = data.ancestors.split(',');
- if (ancestorsArray.length > 1) {
- // 当 ancestors 长度大于 1 时,取第二个 areaCode 作为父级 areaCode
- this.MeterQueryParams.areaCode= ancestorsArray[1];
- } else if (ancestorsArray.length === 1) {
- // 当 ancestors 长度等于 1 时,取该对象本身的 areaCode 作为父级 areaCode
- this.MeterQueryParams.areaCode = data.areaCode;
- }
- }
- this.getMeterData(data);
- },
- /**组织机构*/
- handleDeptNodeClick(data) {
- if (data.deptId === 'all') {
- return;
- }
- // 递归查找第一个叶子节点
- const firstLeafNode = this.findFirstLeafDeptNode(data);
- if (firstLeafNode) {
- this.queryParams.areaCode = firstLeafNode.deptId;
- } else {
- this.queryParams.areaCode = data.deptId;
- }
- this.getMeterData();
- },
- findFirstLeafDeptNode(node) {
- if (!node.children || node.children.length === 0) {
- return node;
- }
- for (let child of node.children) {
- const leafNode = this.findFirstLeafDeptNode(child);
- if (leafNode) {
- return leafNode;
- }
- }
- return null;
- },
- /** 设施节点点击事件 */
- handleFacsNodeClick(data) {
- if (data.id === '-1') {
- this.queryParams.areaCode = null;
- this.MeterQueryParams.areaCode = null;
- } else {
- this.queryParams.areaCode = data.id;
- }
- this.getMeterData();
- },
- /**设备*/
- handleDeviceNodeClick(data) {
- if (data.id === null) {
- this.queryParams.areaCode = null;
- this.MeterQueryParams.areaCode = null;
- } else {
- this.queryParams.areaCode = data.id;
- }
- this.getMeterData();
- },
- /** 查询区域对象树列表 */
- getList() {
- this.loading = true;
- listDetailArea(this.queryParams).then(response => {
- this.areaList = this.handleTree(response.data, "areaCode", "parentCode");
- this.areaList = this.extractTagNames(this.areaList);
- this.tableKey += 1; // 改变 key 值以强制重新渲染
- this.handleNodeClick(this.areaList[0]);//常泰北区
- this.loading = false;
- });
- },
- // 递归提取 tagNames
- extractTagNames(list) {
- return list.map(item => {
- if (item.areaAttr && item.areaAttr.tagNames) {
- item.tagNames = item.areaAttr.tagNames;
- } else {
- item.tagNames = '';
- }
- if (item.children) {
- item.children = this.extractTagNames(item.children);
- }
- return item;
- });
- },
- /** 查询 组织机构(部门)树列表 */
- getDeptList() {
- this.loading = true;
- listDept(this.DeptQueryParams).then(response => {
- this.deptList = this.handleTree(response.data, "deptId");
- this.deptList = this.extractTagNames(this.deptList);
- this.treeKey += 1;
- this.loading = false;
- this.handleDeptNodeClick(this.deptList[0]);
- });
- },
- /** 查询能源设施树列表 */
- getFacsList() {
- this.loading = true;
- getFacsCategoryTree().then(response => {
- this.facsOptions = response.data;
- this.tableKey += 1;
- // 第一个叶子节点
- if (this.facsOptions && this.facsOptions.length > 0 && this.facsOptions[0].children) {
- const firstLeafNode = this.findFirstLeafNode(this.facsOptions[0].children);
- if (firstLeafNode) {
- this.queryParams.areaCode = firstLeafNode.id;
- this.getMeterData();
- }
- }
- this.loading = false;
- })
- },
- /** 查询能源设备树列表 */
- getDeviceList() {
- this.loading = true;
- getTreeByFacs().then(response => {
- this.deviceOptions = response.data;
- this.loading = false;
- if (this.deviceOptions && this.deviceOptions.length > 0 && this.deviceOptions[0].children) {
- const firstLeafNode = this.findFirstLeafNode(this.deviceOptions[0].children);
- if (firstLeafNode) {
- this.queryParams.areaCode = firstLeafNode.id;
- this.getMeterData();
- }
- }
- })
- this.loading = false;
- },
- findFirstLeafNode(nodes) {
- if (!nodes || nodes.length === 0) return null;
- for (let node of nodes) {
- if (!node.children || node.children.length === 0) {
- return node;
- } else {
- const leafNode = this.findFirstLeafNode(node.children);
- if (leafNode) return leafNode;
- }
- }
- return null;
- },
- // 表单重置
- reset() {
- this.form = {
- id: null,
- areaCode: null,
- parentCode: null,
- ancestors: null,
- areaName: null,
- shortName: null,
- desc: null,
- orderNum: null,
- status: null,
- areaAttr: {
- areaCode: null,
- attrOrg: null,
- mgrOrg: null,
- leader: null,
- phone: null,
- openDate: null,
- floorArea: null,
- usableArea: null,
- floor: null,
- tagCodes: null,
- tagNames: null,
- tagCodeList: []
- }
- };
- this.resetForm("form");
- this.queryParams = {
- pageNum: 1,
- pageSize: 10,
- areaCode: null,
- parentCode: null,
- ancestors: null,
- areaName: null,
- shortName: null,
- desc: null,
- orderNum: null,
- status: null,
- tagNames:null,
- areaAttr:{}
- };
- },
- filterDataByAreaCode(list, areaCode) {
- let result = [];
- for (let i = 0; i < list.length; i++) {
- if (list[i].areaCode === areaCode) {
- if (list[i].children && list[i].children.length > 0) {
- list[i].children.forEach(child => {
- result.push(child);
- if (child.children && child.children.length > 0) {
- result = result.concat(this.filterDataByAreaCode(child.children, areaCode));
- }
- });
- }
- return result;
- } else if (list[i].children && list[i].children.length > 0) {
- const foundChildren = this.filterDataByAreaCode(list[i].children, areaCode);
- if (foundChildren.length > 0) {
- return foundChildren;
- }
- }
- }
- return result;
- },
- // 多选框选中数据
- handleSelectionChange(selection) {
- this.ids = selection.map(item => item.id)
- this.single = selection.length !== 1
- this.multiple = !selection.length
- },
- /**计量设备*/
- getMeterData() {
- this.loading = true;
- let meterCls = '';
- if (this.activeDeviceTab === 'electricMeter') {
- meterCls = 45;
- } else if (this.activeDeviceTab === 'waterMeter') {
- meterCls = 70;
- }
- let objType;
- if (this.activeTab === 'area') {
- objType = 1;
- listDevice({ ...this.MeterQueryParams, meterCls }).then(response => {
- this.areaUnbound = response.rows;
- this.total = response.total;
- this.loading = false; // 关闭加载状态
- });
- listByObj(objType, meterCls, this.queryParams.areaCode).then(response => {
- this.areaBound = response.data;
- this.loading = false;
- });
- } else if (this.activeTab === 'organ') {
- objType = 4;
- listDevice({ ...this.MeterQueryParams, meterCls }).then(response => {
- this.organUnbound = response.rows;
- this.total = response.total;
- this.loading = false;
- })
- listByObj(objType, meterCls, this.queryParams.areaCode).then(response => {
- this.organBound = response.data;
- this.loading = false;
- });
- this.loading = false;
- } else if (this.activeTab === 'facs') {
- objType = 2;
- listDevice({ ...this.MeterQueryParams, meterCls }).then(response => {
- this.facsUnbound = response.rows;
- this.total = response.total;
- this.loading = false;
- });
- listByObj(objType, meterCls, this.queryParams.areaCode).then(response => {
- this. facsBound = response.data;
- this.loading = false;
- });
- } else if (this.activeTab === 'device') {
- objType = 3;
- listDevice({ ...this.MeterQueryParams, meterCls }).then(response => {
- this.deviceUnbound = response.rows;
- this.total = response.total;
- this.loading = false;
- })
- listByObj(objType, meterCls, this.queryParams.areaCode).then(response => {
- this.deviceBound = response.data;
- this.loading = false;
- });
- }
- },
- /**绑定设备*/
- moveToDevice(row, tabType) {
- this.$confirm('是否确定绑定?', '提示', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning'
- }).then(() => {
- let objType;
- if (tabType === 'area') {
- objType = 1;
- } else if (tabType === 'organ') {
- objType = 4;
- } else if (tabType === 'facs') {
- objType = 2;
- } else if (tabType === 'device') {
- objType = 3;
- }
- const index = this[`${tabType}Unbound`].indexOf(row);
- if (index !== -1) {
- this[`${tabType}Unbound`].splice(index, 1);
- }
- const boundRow = {
- meterDeviceName: row.deviceName,
- meterDevice: row.deviceCode,
- boundaryObj: this.queryParams.areaCode,
- objType: objType
- };
- this[`${tabType}Bound`].push(boundRow);
- this.saveByObj(tabType);
- }).catch(() => {});
- },
- isAlreadyBound(deviceCode, tabType) {
- return this[`${tabType}Bound`].some(boundDevice => boundDevice.meterDevice === deviceCode);
- },
- /**取消绑定设备*/
- downToDevice(row, tabType) {
- this.$confirm('是否取消绑定?', '提示', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning'
- }).then(() => {
- const index = this[`${tabType}Bound`].indexOf(row);
- if (index !== -1) {
- this[`${tabType}Bound`].splice(index, 1);
- this[`${tabType}Unbound`].push(row);
- const objType = row.objType;
- const boundaryObj = row.boundaryObj;
- const meterCls = row.meterCls || (this.activeDeviceTab === 'electricMeter' ? 45 : 70);
- delete row.boundaryObj;
- delete row.meterDevice;
- delete row.objType;
- this.saveByObj(tabType, objType, boundaryObj, meterCls);
- }
- })
- },
- /**绑定保存*/
- saveByObj(tabType, objType = null, boundaryObj = null, meterCls = null) {
- const dataToSave = this[`${tabType}Bound`].map(item => {
- return {
- boundaryObj: item.boundaryObj,
- id: item.id,
- meterCls: item.meterCls || (this.activeDeviceTab === 'electricMeter' ? 45 : 70),
- meterDevice: item.meterDevice,
- objType: item.objType
- };
- });
- if (dataToSave.length === 0) {
- objType = objType || this.queryParams.objType;
- boundaryObj = boundaryObj || this.queryParams.areaCode;
- meterCls = meterCls || (this.activeDeviceTab === 'electricMeter' ? 45 : 70);
- } else {
- objType = dataToSave[0].objType;
- boundaryObj = dataToSave[0].boundaryObj;
- meterCls = dataToSave[0].meterCls;
- }
- addAllByObj(objType, meterCls, boundaryObj, dataToSave)
- .then(response => {
- if (response.code === 200) {
- this.$message.success('保存成功');
- this.getMeterData(tabType);
- }
- })
- },
- // 设施下拉框选项
- getFacsOptions() {
- const getFacsParams = {
- facsCategory: this.DeviceQueryParams.deviceCategory,
- subCategory: this.DeviceQueryParams.deviceSubCategory
- }
- listAllFacs(getFacsParams).then(response => {
- this.facsAllOptions = response.data
- })
- },
- getSubsystem() {
- listSubsystemAll().then(response => {
- this.subsystemOptions = response.data
- })
- },
- getAllDevProcess(subcategoryCode) {
- getDevProcess(subcategoryCode).then(response => {
- this.devOptions = response.data
- })
- },
- getEmsTag(tagModel) {
- getEmsTag(tagModel).then(response => {
- if (response && response.data) {
- this.emsTagOptions = response.data.map(item => ({
- label: item.tagName,
- value: item.tagCode,
- color: item.tagColor
- }));
- //颜色映射
- this.tagCodeToColorMap = {};
- this.emsTagOptions.forEach(item => {
- this.tagCodeToColorMap[item.value] = item.color;
- });
- }
- })
- },
- /**拓扑图*/
- showTopology(data) {
- this.topologyDialogVisible = true;
- this.$nextTick(() => {
- getBoundaryTreeByArea(data.areaCode).then(response => {
- const topologyData = response.data;
- console.log("拓扑图接口获取数据",topologyData);
- this.initTreeECharts(topologyData);
- });
- });
- },
- initTreeECharts(topologyData) {
- const chartDom = this.$refs.topologyChart;
- const myChart = echarts.init(chartDom);
- // 递归处理拓扑图数据,生成echarts需要的数据格式
- const processTopologyData = (data) => {
- const hasBoundDevices = data.bindElecMeterDevs && data.bindElecMeterDevs.length > 0;
- const nodeColor = hasBoundDevices ? '#99e170' : '#D3D3D3';
- const bindElecMeterDevsStr = hasBoundDevices
- ? `绑定电表:${data.bindElecMeterDevs.join('\n ')}`
- : '绑定电表:无';
- return {
- name: `${data.objName}\n${bindElecMeterDevsStr}`,
- children: data.children ? data.children.map(child => processTopologyData(child)) : [],
- value: [data.bindElecMeterDevs].flat().join(', '),
- itemStyle: { // 设置节点样式
- borderColor: '#D8D3D1',
- borderWidth: 1,
- color: nodeColor
- }
- };
- };
- // 处理根节点数据
- const processedData = processTopologyData(topologyData);
- // 指定图表的配置项和数据
- const option = {
- tooltip: {
- trigger: 'item',
- triggerOn: 'mousemove',
- },
- series: [
- {
- name: '拓扑图',
- type: 'tree',
- layout: 'orthogonal',
- orient: 'TB', // 从上到下的布局
- roam: true,
- data: [processedData], // 直接使用传入的数据
- symbol: 'rect', // 设置节点形状为长方形
- symbolSize: [120, 70],
- label: {
- position: 'inside',
- verticalAlign: 'middle',
- align: 'center',
- fontSize: 12,
- },
- leaves: {
- label: {
- position: 'inside', // 叶子节点标签位置在内部
- verticalAlign: 'middle',
- align: 'center'
- }
- },
- expandAndCollapse: true,
- animationDuration: 550,
- animationDurationUpdate: 750,
- itemStyle: {
- borderColor: '#555',
- borderWidth: 1,
- },
- edgeLabel: {
- position: 'middle',
- fontSize: 10
- },
- emphasis: {
- itemStyle: {
- borderColor: '#333',
- borderWidth: 2
- }
- },
- }
- ]
- };
- myChart.setOption(option);
- },
- scrollToCenter() {
- this.$nextTick(() => {
- const container = this.$refs.topologyChartContainer;
- container.scrollTo(container.scrollWidth / 2 - container.offsetWidth / 2, 0);
- });
- },
- }
- }
- </script>
- <style lang="scss" scoped>
- .custom-tree-node {
- flex: 1;
- display: flex;
- align-items: center;
- justify-content: flex-start;
- }
- .custom-tree-node .el-button {
- margin-left: 8px;
- }
- .topology-chart-container {
- overflow-x: auto;
- width: 100%;
- }
- .topology-chart {
- width: 8000px;
- height: 600px;
- }
- .device-tree-container {
- height: calc(100vh - 50px);
- overflow: auto;
- }
- .device-tree {
- font-size: 12px;
- width: 100%;
- }
- </style>
|