Files
admin-govern/src/views/govern/cloudDeviceEntry/index.vue
2025-10-20 09:42:01 +08:00

2365 lines
91 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="default-main device-manage" :style="{ height: pageHeight.height }" v-loading="loading">
<splitpanes style="height: 100%" class="default-theme" id="navigation-splitpanes">
<pane :size="size">
<CloudDeviceEntryTree ref="TerminalRef" @node-click="nodeClick" @init="nodeClick" @onAdd="onAdd"></CloudDeviceEntryTree>
</pane>
<pane style="background: #fff">
<div class="device-manage-right">
<el-form :inline="true" class="demo-form-inline" style="height: 42px">
<el-form-item style="position: relative; z-index: 2" >
<el-button icon="el-icon-Plus" type="primary" @click="add" v-if="nodeLevel != 4">
{{
nodeLevel == 0
? '新增工程'
: nodeLevel == 1
? '新增项目'
: nodeLevel == 2
? '新增设备'
: nodeLevel == 3
? '新增监测点'
: '新增'
}}
</el-button>
<el-button icon="el-icon-Edit" type="primary" @click="update" v-if="nodeLevel != 0">
修改
</el-button>
<el-button icon="el-icon-Close" type="danger" @click="remove" v-if="nodeLevel != 0">
删除
</el-button>
<el-button
icon="el-icon-Right"
:disabled="nextfalg"
type="primary"
@click="next"
v-if="nodeLevel != 4 && pageStatus == 2"
>
下一步
</el-button>
<el-button
type="info"
@click="black"
icon="el-icon-Back"
v-if="pageStatus == 2 || pageStatus == 3"
>
</el-button>
<el-button icon="el-icon-Check" type="primary" v-if="pageStatus == 2" @click="onsubmit">
确认提交
</el-button>
<el-button icon="el-icon-Check" type="primary" v-if="pageStatus == 3" @click="onsubmit">
修改提交
</el-button>
</el-form-item>
<el-form-item style="right: 500px; position: absolute; overflow: hidden">
<LocationInformation style="width: 16px; margin-right: 8px; color: var(--el-color-primary)" />
<span style="font-size: 16px; font-weight: bold; color: var(--el-color-primary)">当前操作节点</span>
</el-form-item>
<el-form-item style="right: 0; position: absolute; overflow: hidden">
<div class="title" :class="titleList.length > 5 ? 'titleScroll' : ''">
<span v-for="(item, index) in titleList" :key="index">{{ index == 0 ? '' : ' > ' }}{{ item }}</span>
</div>
</el-form-item>
</el-form>
<div id="scrollBox" :style="{ height: Height.height }" style="overflow-y: auto">
<el-form
class="main-form overview_scroll"
:label-position="'right'"
label-width="120px"
:inline="true"
ref="mainForm"
>
<el-form-item
id="id100"
class="form-item"
label="设备名称:"
:rules="{ required: true, message: '请输入设备名称', trigger: 'blur' }"
>
<el-select
filterable
v-model="project[2].name"
:disabled="true"
placeholder="请选择设备类型"
>
<el-option
v-for="item in project"
:key="item.name"
:label="item.name"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
<!--工程-->
<!-- 省下拉框 -->
<el-form-item
id="id200"
class="form-item"
label="省:"
v-if="nodeLevel > 0 || pageStatus == 2"
:rules="{ required: true, message: '请选择省', trigger: 'change' }"
>
<el-select
filterable
v-model="engineeringParam.province"
:disabled="!((nodeLevel == 1 && pageStatus == 3) || (nodeLevel == 0 && pageStatus == 2))"
placeholder="请选择省"
@change="provinceChange"
>
<el-option
v-for="item in provinceOptions"
:key="item.value"
:label="item.text"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
<!-- 市下拉框 -->
<el-form-item
id="id200"
class="form-item"
label="市:"
v-if="(nodeLevel > 0 || pageStatus == 2)"
:rules="{ required: true, message: '请选择市', trigger: 'change' }"
>
<el-select
filterable
v-model="engineeringParam.city"
:disabled="!((nodeLevel == 1 && pageStatus == 3) || (nodeLevel == 0 && pageStatus == 2))"
placeholder="请选择市"
>
<el-option
v-for="item in cityOptions"
:key="item.value"
:label="item.text"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item
id="id300"
class="form-item"
label="工程名称:"
v-if="nodeLevel > 0 || pageStatus == 2"
:prop="'name'"
:rules="{ required: true, message: '请输入工程名称', trigger: 'blur' }"
>
<el-input
v-model="engineeringParam.name"
placeholder="请输入工程名称"
:disabled="!((nodeLevel == 1 && pageStatus == 3) || (nodeLevel == 0 && pageStatus == 2))"
></el-input>
</el-form-item>
<el-form-item
id="id300"
class="form-item"
label="描述:"
v-if="nodeLevel > 0 || pageStatus == 2"
>
<el-input
v-model="engineeringParam.description"
placeholder="请输入描述"
:disabled="!((nodeLevel == 1 && pageStatus == 3) || (nodeLevel == 0 && pageStatus == 2))"
></el-input>
</el-form-item>
<!--项目-->
<div style="width: 100%" v-if="nodeLevel > 0 || pageStatus == 2">
<el-tabs
v-model="deviceIndex"
type="card"
:addable="false"
:closable="pageStatus != 1"
@edit="handleDeviceTabsEdit"
@tab-click="tabChange('deviceIndex')"
>
<el-tab-pane
v-for="(item, index) in projectInfoList"
:key="index"
:label="item.name ? item.name : '新建项目' + index"
:name="index + ''"
>
<div class="flex mt10">
<el-form-item
class="form-item"
label="项目名称:"
:rules="[{ required: true, message: '请输入项目名称', trigger: 'blur' }]"
>
<el-input
v-model="item.name"
placeholder="请输入项目名称"
:disabled="!((nodeLevel == 2 && pageStatus == 3) || ((nodeLevel == 1 || (nodeLevel == 0 && pageStatus == 2)) && pageStatus == 2))"
></el-input>
</el-form-item>
<el-form-item
class="form-item"
label="地市:"
:rules="[{ required: true, message: '请输入地市', trigger: 'blur' }]"
>
<el-input
v-model="item.area"
placeholder="请输入地市"
:disabled="!((nodeLevel == 2 && pageStatus == 3) || ((nodeLevel == 1 || (nodeLevel == 0 && pageStatus == 2)) && pageStatus == 2))"
></el-input>
</el-form-item>
<el-form-item
class="form-item"
label="描述:"
:rules="[{ required: true, message: '请输入描述', trigger: 'blur' }]"
>
<el-input
v-model="item.description"
placeholder="请输入描述"
:disabled="!((nodeLevel == 2 && pageStatus == 3) || ((nodeLevel == 1 || (nodeLevel == 0 && pageStatus == 2)) && pageStatus == 2))"
></el-input>
</el-form-item>
</div>
</el-tab-pane>
</el-tabs>
</div>
<!--设备-->
<div style="width: 100%" v-if="(nodeLevel > 1 || pageStatus == 2) && (nodeLevel >= 2 || pageStatus == 2)">
<el-tabs
v-model="busBarIndex"
type="card"
:addable="false"
:closable="pageStatus != 1"
@edit="handleBusBarTabsEdit"
@tab-click="tabChange('busBarIndex')"
>
<el-tab-pane
v-for="(busItem, bIndex) in deviceInfoList"
:key="bIndex"
:label="busItem.name ? busItem.name : '新建装置' + bIndex"
:name="bIndex + ''"
>
<div class="flex mt10">
<el-form-item
class="form-item"
label="装置名称:"
:rules="[{ required: true, message: '请输入装置名称', trigger: 'blur' }]"
>
<el-input
v-model="busItem.name"
placeholder="请输入装置名称"
:disabled="!((nodeLevel == 3 && pageStatus == 3) || ((nodeLevel == 2 || (nodeLevel == 1 && pageStatus == 2)) && pageStatus == 2))"
></el-input>
</el-form-item>
<el-form-item
id="id200"
class="form-item"
label="装置类型:"
:rules="[{ required: true, message: '请选择装置类型', trigger: 'change' }]"
>
<el-select
filterable
v-model="busItem.devType"
placeholder="请选择装置类型"
style="width: 100%"
:disabled="!((nodeLevel == 3 && pageStatus == 3) || ((nodeLevel == 2 || (nodeLevel == 1 && pageStatus == 2)) && pageStatus == 2))"
>
<el-option
v-for="item in formDevTypeOptions"
:key="item.value"
:label="item.label || item.name"
:value="item.value || item.id"
></el-option>
</el-select>
</el-form-item>
<el-form-item
id="id200"
class="form-item"
label="装置型号:"
:rules="[{ required: true, message: '请选择装置型号', trigger: 'change' }]"
>
<el-select
filterable
v-model="busItem.devModel"
placeholder="请选择装置型号"
style="width: 100%"
:disabled="!((nodeLevel == 3 && pageStatus == 3) || ((nodeLevel == 2 || (nodeLevel == 1 && pageStatus == 2)) && pageStatus == 2))"
>
<el-option
v-for="option in devCLD"
:key="option.id"
:label="option.name"
:value="option.id"
></el-option>
</el-select>
</el-form-item>
<el-form-item
id="id200"
class="form-item"
label="装置接入方式:"
:rules="[{ required: true, message: '请选择装置接入方式', trigger: 'change' }]"
>
<el-select
filterable
v-model="busItem.devAccessMethod"
placeholder="请选择装置接入方式"
style="width: 100%"
:disabled="!((nodeLevel == 3 && pageStatus == 3) || ((nodeLevel == 2 || (nodeLevel == 1 && pageStatus == 2)) && pageStatus == 2))"
>
<el-option label="CLD" value="CLD"></el-option>
</el-select>
</el-form-item>
<el-form-item
class="form-item"
label="装置mac地址:"
:rules="{ required: true, message: '请输入装置mac地址', trigger: 'blur' }"
>
<MacAddressInput v-model="busItem.mac" :disabled="!((nodeLevel == 3 && pageStatus == 3) || ((nodeLevel == 2 || (nodeLevel == 1 && pageStatus == 2)) && pageStatus == 2))"/>
</el-form-item>
<!-- <el-form-item
class="form-item"
label="网络设备ID:"
:rules="[{ required: true, message: '请输入网络设备ID', trigger: 'blur' }]"
>
<el-input
v-model="busItem.ndid"
disabled
placeholder="请输入网络设备ID"
></el-input>
</el-form-item> -->
<el-form-item class="form-item" label="合同号:">
<el-input
v-model="busItem.cntractNo"
placeholder="请输入合同号"
:disabled="!((nodeLevel == 3 && pageStatus == 3) || ((nodeLevel == 2 || (nodeLevel == 1 && pageStatus == 2)) && pageStatus == 2))"
></el-input>
</el-form-item>
<el-form-item
class="form-item"
label="所属前置机:"
:rules="[
{ required: true, message: '请选择所属前置机', trigger: 'change' }
]"
>
<el-select
filterable
v-model="busItem.nodeId"
placeholder="请选择所属前置机"
:disabled="!(pageStatus == 2 && nodeLevel >= 2)"
>
<el-option
v-for="option in affiliatiedFrontArr"
:key="option.id"
:label="option.name"
:value="option.id"
></el-option>
</el-select>
</el-form-item>
<el-form-item class="form-item" label="进程号:">
<el-input
v-model="busItem.nodeProcess"
placeholder="自动分配"
:disabled="true"
></el-input>
</el-form-item>
<el-form-item
class="form-item"
label="排序:"
:rules="[{ required: true, message: '请输入排序', trigger: 'blur' }]"
>
<el-input
v-model="busItem.sort"
placeholder="请输入排序"
:disabled="!((nodeLevel == 3 && pageStatus == 3) || ((nodeLevel == 2 || (nodeLevel == 1 && pageStatus == 2)) && pageStatus == 2))"
></el-input>
</el-form-item>
</div>
</el-tab-pane>
</el-tabs>
</div>
<!--监测点-->
<div style="width: 100%" v-if="(nodeLevel > 2 || pageStatus == 2) && (nodeLevel >= 3 || pageStatus == 2)">
<el-tabs
type="card"
v-model="lineIndex"
:addable="false"
:closable="pageStatus != 1"
@edit="handleLineTabsEdit"
@tab-click="tabChange('lineIndex')"
>
<el-tab-pane
v-for="(lineItem, lIndex) in lineInfoList"
:key="lIndex"
:label="lineItem.name ? lineItem.name : '新建监测点' + lIndex"
:name="lIndex + ''"
>
<div class="flex mt10">
<el-form-item
class="form-item"
label="监测点名称:"
:rules="{
required: true,
message: '请输入监测点名称',
trigger: 'blur'
}"
>
<el-input
v-model="lineItem.name"
placeholder="请输入监测点名称"
:disabled="!((nodeLevel == 4 && pageStatus == 3) || ((nodeLevel == 3 || (nodeLevel == 2 && pageStatus == 2)) && pageStatus == 2))"
></el-input>
</el-form-item>
<el-form-item
class="form-item"
label="线路号:"
:rules="{
required: true,
message: '请选择线路号',
trigger: 'blur'
}"
>
<el-select
filterable
v-model="lineItem.lineNo"
placeholder="请选择线路号"
:disabled="!((nodeLevel == 4 && pageStatus == 3) || ((nodeLevel == 3 || (nodeLevel == 2 && pageStatus == 2)) && pageStatus == 2))"
>
<el-option
v-for="option in pointNumArr"
:key="option.name"
:label="option.name"
:value="option.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item
class="form-item"
label="接线方式:"
:rules="{ required: true, message: '请选择接线方式', trigger: 'blur' }"
>
<el-select
filterable
v-model="lineItem.conType"
placeholder="请选择接线方式"
:disabled="!((nodeLevel == 4 && pageStatus == 3) || ((nodeLevel == 3 || (nodeLevel == 2 && pageStatus == 2)) && pageStatus == 2))"
>
<el-option
v-for="option in wiringTypeArr"
:key="option.name"
:label="option.name"
:value="option.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item
class="form-item"
label="统计间隔:"
:rules="{ required: true, message: '请选择统计间隔', trigger: 'blur' }"
>
<el-select
filterable
v-model="lineItem.lineInterval"
placeholder="请选择统计间隔"
:disabled="!((nodeLevel == 4 && pageStatus == 3) || ((nodeLevel == 3 || (nodeLevel == 2 && pageStatus == 2)) && pageStatus == 2))"
>
<el-option
v-for="option in lineSpaceArr"
:key="option.name"
:label="option.name"
:value="option.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item
class="form-item"
label="PT变比:"
:rules="{ required: true, message: '请输入pt', trigger: 'blur' }"
>
<div style="width: 100%; display: flex; justify-content: space-between">
<el-input
style="width: 48%"
v-model="lineItem.ptRatio"
:disabled="!((nodeLevel == 4 && pageStatus == 3) || ((nodeLevel == 3 || (nodeLevel == 2 && pageStatus == 2)) && pageStatus == 2))"
></el-input>
<span style="display: flex; align-items: center; justify-content: center;">:</span>
<el-input
style="width: 48%"
v-model="lineItem.pt2Ratio"
:disabled="!((nodeLevel == 4 && pageStatus == 3) || ((nodeLevel == 3 || (nodeLevel == 2 && pageStatus == 2)) && pageStatus == 2))"
></el-input>
</div>
</el-form-item>
<el-form-item
class="form-item"
label="CT变比:"
:rules="{ required: true, message: '请输入ct', trigger: 'blur' }"
>
<div style="width: 100%; display: flex; justify-content: space-between">
<el-input
style="width: 48%"
v-model="lineItem.ctRatio"
:disabled="!((nodeLevel == 4 && pageStatus == 3) || ((nodeLevel == 3 || (nodeLevel == 2 && pageStatus == 2)) && pageStatus == 2))"
></el-input>
<span style="display: flex; align-items: center; justify-content: center;">:</span>
<el-input
style="width: 48%"
v-model="lineItem.ct2Ratio"
:disabled="!((nodeLevel == 4 && pageStatus == 3) || ((nodeLevel == 3 || (nodeLevel == 2 && pageStatus == 2)) && pageStatus == 2))"
></el-input>
</div>
</el-form-item>
<el-form-item
class="form-item"
label="电压等级:"
:rules="{ required: true, message: '请选择电压等级', trigger: 'blur' }"
>
<el-select
filterable
v-model="lineItem.volGrade"
placeholder="请选择电压等级"
:disabled="!((nodeLevel == 4 && pageStatus == 3) || ((nodeLevel == 3 || (nodeLevel == 2 && pageStatus == 2)) && pageStatus == 2))"
>
<el-option
v-for="option in voltageLevelOptions"
:key="option.value"
:label="option.name"
:value="option.value"
>
</el-option>
</el-select>
</el-form-item>
</div>
</el-tab-pane>
</el-tabs>
</div>
</el-form>
</div>
</div>
</pane>
</splitpanes>
<el-dialog
v-model="resultDialogVisible"
title="台账推送结果"
width="50%"
:close-on-click-modal="false"
:close-on-press-escape="false"
:show-close="true"
@close="handleDialogClose"
>
<div v-if="pushResult" style="padding: 20px;">
<el-result
:icon="pushResult.success ? 'success' : 'error'"
:title="pushResult.success ? '推送成功' : '推送失败'"
:sub-title="pushResult.message"
>
</el-result>
<!-- 日志展示区域 -->
<div style="margin-top: 20px;">
<h3>推送日志:</h3>
<div style="max-height: 300px; overflow-y: auto; border: 1px solid #ebeef5; border-radius: 4px; padding: 10px;">
<div
v-for="(log, index) in pushResult.logs"
:key="index"
style="padding: 5px 0; border-bottom: 1px solid #f0f0f0;"
>
<span style="margin-left: 10px;">{{ log.message }}</span>
</div>
<div v-if="pushResult.logs.length === 0" style="text-align: center; color: #999; padding: 20px;">
暂无日志信息
</div>
</div>
</div>
</div>
<div v-else style="text-align: center; padding: 20px;">
<el-icon :size="40" class="is-loading" style="color: #409EFF;">
<Loading />
</el-icon>
<p style="margin-top: 15px; font-size: 16px;">正在推送台账信息,请稍候...</p>
<p style="margin-top: 10px; color: #999;">预计需要30秒左右</p>
<p style="margin-top: 10px; color: #999;">已等待: {{ countdown }}秒</p>
</div>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import 'splitpanes/dist/splitpanes.css'
import { Splitpanes, Pane } from 'splitpanes'
import { LocationInformation } from '@element-plus/icons-vue'
import CloudDeviceEntryTree from '@/components/tree/govern/cloudDeviceEntryTree.vue'
import { mainHeight } from '@/utils/layout'
import { useDictData } from '@/stores/dictData'
import { ref, reactive, onMounted, computed } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import {getById,getEngineerById,getProjectById,getEquipmentById,getInfoById,nodeAllList,addLedger,deleteProject,deleteLine,deleteEquipment,updateEquipment,updateLine,pushLog,queryPushResult} from '@/api/cs-device-boot/cloudDeviceEntry'
import tree from '@/assets/map/area.json'
import { queryByCode,queryCsDictTree } from '@/api/system-boot/dictTree'
import MacAddressInput from '@/components/form/mac/MacAddressInput.vue'
import { auditEngineering } from '@/api/cs-device-boot/edData'
import { convertToObject } from 'typescript'
import { Loading } from '@element-plus/icons-vue'
defineOptions({
name: '/cs-device-boot/cloudDeviceEntry'
})
const size = ref(0)
const TerminalRef = ref()
const pageHeight = mainHeight(20)
const Height = mainHeight(100)
const mainForm = ref()
const loading = ref(false)
const nextfalg = ref(false)
const dictData = useDictData()
const nodeLevel = ref(0)
const pageStatus = ref(1)
const titleList: any = ref([])
const nodeData: any = ref([])
const deviceIndex: any = ref('0')
const busBarIndex: any = ref('0')
const lineIndex: any = ref('0')
const projectId: any = ref('0')
const provinceId: any = ref('0')
const gdId: any = ref('0')
const subId: any = ref('0')
const devId: any = ref('0')
const busBarId: any = ref('0')
const lineId: any = ref('0')
const currentGdName: any = ref('')
const affiliatiedFrontArr: any = ref([])
const voltageLevelArr = dictData.getBasicData('Dev_Voltage_Stand')
const devCLD = ref<{ id: string; name: string }[] | null>(null)
const devTypeOptions = ref<{ id: string; name: string }[] | null>(null)
const devTypeOptions2: any = ref([])
const treeClickCount = ref(0)
const areaTree: any = tree
const project = ref([
{ name: '治理设备', value: '治理设备' },
{ name: '便携式设备', value: '便携式设备' },
{ name: '在线设备', value: '在线设备' }
])
const wiringTypeArr = ref([
{ name: '星型接线', value: 0 },
{ name: '三角型接线', value: 1 },
{ name: '开口三角型接线', value: 2 }
])
/**监测点序号 */
const pointNumArr = ref([
{ name: '1', value: 1 },
{ name: '2', value: 2 },
{ name: '3', value: 3 },
{ name: '4', value: 4 },
{ name: '5', value: 5 },
{ name: '6', value: 6 }
])
/**监测点间隔 */
const lineSpaceArr = ref([
{ name: '1分钟', value: 1 },
{ name: '3分钟', value: 3 },
{ name: '5分钟', value: 5 },
{ name: '10分钟', value: 10 }
])
//工程
const engineeringParam = ref({
city: '',
description: '',
name: '',
province: ''
})
interface ProjectInfo {
name: string
area: string
description: string
}
// 项目信息列表
const projectInfoList = ref<ProjectInfo[]>([])
interface DeviceInfo {
name: string
devModel: string
devType: string
devAccessMethod: string
mac: string
ndid: string
nodeId: string
cntractNo: string
sort: number
nodeProcess:string
}
// 设备信息列表
const deviceInfoList = ref<DeviceInfo[]>([])
interface LineInfo {
name: string
lineNo: number
conType: number
lineInterval: number
ptRatio: number
pt2Ratio: number
ctRatio: number
ct2Ratio: number
volGrade: number | string
devMac: string
}
// 监测点信息列表
const lineInfoList = ref<LineInfo[]>([])
const arrdess: any = ref((rule: any, value: any, callback: any) => {
let reg1 =
/^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/
let reg2 =
/^[A-Fa-f0-9]{1,2}\-[A-Fa-f0-9]{1,2}\-[A-Fa-f0-9]{1,2}\-[A-Fa-f0-9]{1,2}\-[A-Fa-f0-9]{1,2}\-[A-Fa-f0-9]{1,2}$/
let reg3 =
/^[A-Fa-f0-9]{1,2}\:[A-Fa-f0-9]{1,2}\:[A-Fa-f0-9]{1,2}\:[A-Fa-f0-9]{1,2}\:[A-Fa-f0-9]{1,2}\:[A-Fa-f0-9]{1,2}$/
if (reg1.test(value)) {
return true
} else if (reg2.test(value)) {
return true
} else if (reg3.test(value)) {
return true
} else if (value == '') {
return callback(new Error('请输入IP/MAC地址'))
} else {
callback(new Error('请输入正确IP/MAC地址'))
}
})
// 省市选择相关数据
const provinceOptions = computed(() => areaTree)
const cityOptions = computed(() => {
if (engineeringParam.value.province) {
const province = areaTree.find((item: any) => item.value === engineeringParam.value.province)
return province ? province.children : []
}
return []
})
const formDevTypeOptions = computed(() => {
return [devTypeOptions2.value]
})
// 电压等级选项,用于显示带单位的名称
const voltageLevelOptions = computed(() => {
// 确保 voltageLevelArr.value 是数组
if (!Array.isArray(voltageLevelArr)) {
return []
}
return voltageLevelArr.map((item: any) => {
return {
...item,
name: `${item.value}kV` // 优先使用code字段如果没有则构造带单位的名称
}
})
})
// 省改变时清空市的选择
const provinceChange = () => {
engineeringParam.value.city = ''
}
// 临时存储所有层级的数据
const tempAllLevelData = ref<any>({
engineering: null,
projects: [],
devices: [],
lines: []
})
const nodeDataList=ref()
const nodeEventList=ref()
const nodeClick = (e: anyObj, data: any) => {
nodeDataList.value = data
nodeEventList.value = e
treeClickCount.value++
if (treeClickCount.value > 2) return
if (treeClickCount.value == 1) {
if (pageStatus.value == 2 || pageStatus.value == 3) {
if (pageStatus.value == 3 || pageStatus.value == 2) {
ElMessage({
type: 'warning',
message: '请先提交,再做操作'
})
}
return
}
}
titleList.value = []
getparentsNode(data)
pageStatus.value = 1
nodeData.value = e
if(nodeData.value.level == 0){
nodeLevel.value = 0
}else if(nodeData.value.level == 1){//工程节点
nodeLevel.value = 1
}else if(nodeData.value.level == 2){//项目
nodeLevel.value = 2
}else if(nodeData.value.level == 3){ //设备
nodeLevel.value = 3
}else if(nodeData.value.level == 4){ //监测点
nodeLevel.value = 4
}
// 更新 nextfalg 状态
nextfalg.value = nodeLevel.value >= 4;
// 根据节点层级清理不需要的数据
cleanUnnecessaryData()
/**不是根节点请求数据 */
queryNodeContent()
treeClickCount.value = 0
}
const countdown = ref(0)
const resultDialogVisible = ref(false)
const pushResult = ref<{
success: boolean;
message: string;
logs: Array<{message: string }>
} | null>(null)
const timer = ref<number | null>(null)
const handleDialogClose = () => {
pushResult.value = null
resultDialogVisible.value = false
if (timer.value) {
clearInterval(timer.value)
timer.value = null
}
countdown.value = 0
}
const onAdd = async () => {
resultDialogVisible.value = true
pushResult.value = null
countdown.value = 0
// 启动倒计时
if (timer.value) clearInterval(timer.value)
timer.value = window.setInterval(() => {
countdown.value++
if (countdown.value >= 30) {
clearInterval(timer.value!)
timer.value = null
}
}, 1000)
try {
// 调用推送日志接口
const pushLogResponse = await pushLog()
// 检查返回的data是否为"暂无需要推送的数据"
if (pushLogResponse.data != "成功") {
// 直接提示用户没有数据推送
pushResult.value = {
success: false,
message: '暂无需要推送的数据',
logs: [{
message: '暂无需要推送的数据'
}]
}
return;
}
// 如果data不是"暂无需要推送的数据",则继续执行
if (pushLogResponse.data === "成功") {
// 等待30秒
await new Promise(resolve => setTimeout(resolve, 30000))
// 30秒后调用查询推送结果接口
const result = await queryPushResult()
// 处理返回的日志数据
const logs = Array.isArray(result.data) ? result.data : []
// 根据结果进行处理
pushResult.value = {
success: true,
message: '台账推送成功',
logs: logs.map((item: any) => ({
message: item.message || JSON.stringify(item)
}))
}
}
} catch (error: any) {
pushResult.value = {
success: false,
message: error.message || '推送过程中发生错误',
logs: [{
message: error.message || '未知错误'
}]
}
} finally {
if (timer.value) {
clearInterval(timer.value)
timer.value = null
}
countdown.value = 0
}
}
/**
* 根据当前节点层级清理不需要的数据
*/
const cleanUnnecessaryData = () => {
// 根据当前节点层级清理不需要的数据
switch(nodeLevel.value) {
case 0: // 根节点
// 清理所有数据
projectInfoList.value = []
deviceInfoList.value = []
lineInfoList.value = []
break
case 1: // 工程节点
// 清理设备和监测点数据
deviceInfoList.value = []
lineInfoList.value = []
break
case 2: // 项目节点
// 清理监测点数据
lineInfoList.value = []
break
case 3: // 设备节点
// 不清理任何数据
break
case 4: // 监测点节点
// 不清理任何数据
break
}
// 重置tab索引
if (nodeLevel.value < 2) {
deviceIndex.value = '0'
}
if (nodeLevel.value < 3) {
busBarIndex.value = '0'
}
if (nodeLevel.value < 4) {
lineIndex.value = '0'
}
}
const getparentsNode = (node: any) => {
// 检查node是否存在以及是否有parent属性
if (!node || !node.parent) {
return
}
titleList.value.unshift(node.label)
getparentsNode(node.parent) //调用递归
}
/**查询节点内容 */
const queryNodeContent = () => {
if (nodeData.value.id == null) {
return
}
if(nodeLevel.value == 1){
getEngineerById(nodeData.value.id)
}else if(nodeLevel.value == 2){
getProjectById(nodeData.value.id)
}else if(nodeLevel.value == 3){
getEquipmentById(nodeData.value.id)
}else if(nodeLevel.value == 4){
getById(nodeData.value.id)
}
getInfoById(nodeData.value.id).then((res: any) => {
Object.assign(engineeringParam.value, res.data);
engineeringParam.value.name = res.data.engineeringName
engineeringParam.value.description = res.data.engineeringDescription
projectInfoList.value = res.data.projectInfoList || []
if (nodeLevel.value >= 2) {
deviceInfoList.value = res.data.deviceInfoList || []
}
if (nodeLevel.value >= 3) {
lineInfoList.value = res.data.lineInfoList || []
lineInfoList.value.map((item: any) => {
item.volGrade = item.volGrade + 'kV'
})
}
})
}
// 新增
const add = () => {
if (pageStatus.value == 2 || pageStatus.value == 3) {
ElMessage({
type: 'warning',
message: '请先提交修改,再新增'
})
return
}
pageStatus.value = 2
// 根据当前节点层级添加对应的tab页
switch (nodeLevel.value) {
case 0: // 新增工程不需要添加tab
// 初始化工程参数
engineeringParam.value.city = ''
engineeringParam.value.description = ''
engineeringParam.value.name = ''
engineeringParam.value.province = ''
// 清理其他层级数据
projectInfoList.value = []
deviceInfoList.value = []
lineInfoList.value = []
break
case 1: // 新增项目添加一个新的项目tab
// 添加一个新的空项目到projectInfoList
projectInfoList.value.push({
name: '',
area: '',
description: ''
})
deviceIndex.value = (projectInfoList.value.length - 1).toString()
// 清理设备和监测点数据
deviceInfoList.value = []
lineInfoList.value = []
break
case 2: // 新增设备添加一个新的设备tab
// 添加一个新的空设备到deviceInfoList
deviceInfoList.value.push({
name: '',
devModel: '',
devType: '',
devAccessMethod: 'CLD',
mac: '',
ndid: '',
nodeId: '',
cntractNo: '',
sort: 0,
nodeProcess: '自动分配',
})
busBarIndex.value = (deviceInfoList.value.length - 1).toString()
// 清理监测点数据
lineInfoList.value = []
break
case 3: // 新增监测点添加一个新的监测点tab
// 添加一个新的空监测点到lineInfoList
lineInfoList.value.push({
name: '',
lineNo: 1,
conType: 0,
lineInterval: 1,
ptRatio: 0,
pt2Ratio: 0,
ctRatio: 0,
ct2Ratio: 0,
volGrade: '',
devMac:'',
})
lineIndex.value = (lineInfoList.value.length - 1).toString()
break
}
}
// 修改
const update = () => {
if (Object.keys(nodeData.value).length == 0) {
ElMessage({
type: 'warning',
message: '没有选中节点'
})
return
}
if (nodeData.value.level == 0) {
ElMessage({
type: 'warning',
message: '不能修改根节点'
})
return
}
if (pageStatus.value == 2 || pageStatus.value == 3) {
if (pageStatus.value == 2) {
ElMessage({
type: 'warning',
message: '请先新增完成在修改'
})
}
return
}
pageStatus.value = 3
// 使用 scrollTo 方法,并启用平滑滚动
const scrollBox: any = document.getElementById('scrollBox')
scrollBox.scrollTo({
top: scrollBox.scrollHeight, // 滚动到内容的最底部
behavior: 'smooth' // 启用平滑滚动动画
})
}
/**
* 修改工程
*/
const updateEngineering = (id: any) => {
// 获取工程信息
const engData = engineeringParam.value;
// 构建工程修改数据结构
const engineeringData = {
id: id, // 工程ID用于修改
city: engData.city,
description: engData.description,
name: engData.name,
province: engData.province,
};
auditEngineering(engineeringData).then((res: any) => {
ElMessage({
type: 'success',
message: '修改工程成功'
})
pageStatus.value = 1
TerminalRef.value.info()
})
}
/**
* 修改项目
*/
const updateProjectFunc = (id: any) => {
// 获取当前选中的项目信息
const currentProject = projectInfoList.value[deviceIndex.value];
if (!currentProject) {
ElMessage({
type: 'error',
message: '未找到项目信息'
});
return;
}
deleteProject(id,currentProject.name,currentProject.area, currentProject.description,1).then((res: any) => {
ElMessage({
type: 'success',
message: '修改项目成功'
})
pageStatus.value = 1
treedata()
})
}
/**
* 修改设备
*/
const updateEquipmentFunc = (id: any) => {
// 获取当前选中的设备信息
const currentDevice = deviceInfoList.value[busBarIndex.value];
if (!currentDevice) {
ElMessage({
type: 'error',
message: '未找到设备信息'
});
return;
}
// 构建与新增设备相同的结构体
const deviceData = {
id: id, // 设备ID用于修改
name: currentDevice.name,
devModel: currentDevice.devModel,
devType: currentDevice.devType,
devAccessMethod: currentDevice.devAccessMethod,
mac: currentDevice.mac,
nodeId: currentDevice.nodeId,
cntractNo: currentDevice.cntractNo,
ndid: currentDevice.mac.replace(/:/g, ''),
sort: currentDevice.sort,
};
updateEquipment(deviceData).then((res: any) => {
ElMessage({
type: 'success',
message: '修改设备成功'
})
pageStatus.value = 1
TerminalRef.value.info()
})
}
/**
* 修改监测点
*/
const updateLineFunc = (id: any) => {
// 获取当前选中的监测点信息
const currentLine = lineInfoList.value[lineIndex.value];
if (!currentLine) {
ElMessage({
type: 'error',
message: '未找到监测点信息'
});
return;
}
// 处理电压等级,去除"kV"后缀
let volGradeValue = currentLine.volGrade;
if (typeof volGradeValue === 'string' && volGradeValue.endsWith('kV')) {
volGradeValue = volGradeValue.slice(0, -2);
}
// 获取设备MAC地址和设备ID
let devMac = '';
let devId = '';
if (deviceInfoList.value && deviceInfoList.value[busBarIndex.value]) {
devMac = deviceInfoList.value[busBarIndex.value].mac || '';
// 如果有设备ID也获取它
if (deviceInfoList.value[busBarIndex.value].id) {
devId = deviceInfoList.value[busBarIndex.value].id || '';
}
}
// 构建与新增监测点相同的结构体
const lineData = {
lineId: id,
name: currentLine.name || '',
lineNo: currentLine.lineNo || 1,
conType: currentLine.conType || 0,
lineInterval: currentLine.lineInterval || 1,
ptRatio: currentLine.ptRatio || 0,
pt2Ratio: currentLine.pt2Ratio || 0,
ctRatio: currentLine.ctRatio || 0,
ct2Ratio: currentLine.ct2Ratio || 0,
volGrade: volGradeValue || 0,
devMac: devMac,
devId: devId,
};
updateLine(lineData).then((res: any) => {
ElMessage({
type: 'success',
message: '修改监测点成功'
})
pageStatus.value = 1
treedata()
})
}
// 删除
const remove = () => {
if (Object.keys(nodeData.value).length == 0) {
ElMessage({
type: 'warning',
message: '没有选中节点'
})
return
}
if (nodeData.value.level == 0) {
ElMessage({
type: 'error',
message: '无法删除根节点'
})
return
}
if (nodeData.value.id == null) {
ElMessage.warning('无法删除该节点')
return
}
ElMessageBox.confirm('此操作将永久删除, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
switch (nodeLevel.value) {
case 1:
let data = {
id: nodeData.value.id,
status: "0",
};
auditEngineering(data).then((res: any) => {
ElMessage({
type: 'success',
message: res.message
})
reaseStatus()
// 删除工程后选中根节点
setTimeout(() => {
treedata()
}, 100)
})
break;
case 2: // 项目层级
// 删除项目后选中工程节点
const engineeringId = nodeData.value.pids ? nodeData.value.pids.split(',')[1] : null
deleteProject(nodeData.value.id,'','','', 0).then((res: any) => {
ElMessage({
type: 'success',
message: res.message
})
reaseStatus()
console.log('engineeringId',engineeringId)
if (engineeringId) {
setTimeout(() => {
treedata(engineeringId)
}, 100)
} else {
treedata()
}
})
break;
case 3: // 设备层级
// 删除设备后选中项目节点
const projectId = nodeData.value.pids ? nodeData.value.pids.split(',')[2] : null
deleteEquipment(nodeData.value.id).then((res: any) => {
ElMessage({
type: 'success',
message: res.message
})
reaseStatus()
if (projectId) {
setTimeout(() => {
treedata(projectId)
}, 100)
} else {
treedata()
}
})
break;
case 4: // 监测点层级
const deviceId = nodeData.value.pids ? nodeData.value.pids.split(',')[3] : null
console.log(deviceId)
deleteLine(nodeData.value.id).then((res: any) => {
ElMessage({
type: 'success',
message: res.message
})
reaseStatus()
// 删除监测点后选中设备节点
if (deviceId) {
setTimeout(() => {
treedata(deviceId)
}, 100)
} else {
treedata()
}
})
break;
}
})
.catch(() => {
ElMessage({
type: 'info',
message: '已取消删除'
})
})
}
// 下一步
const next = async () => {
// 在新增模式下pageStatus == 2保存当前数据并创建下一个层级的Tab
switch (nodeLevel.value) {
case 0: // 工程层级下一步创建项目Tab
// 保存当前工程信息到临时存储
tempAllLevelData.value.engineering = { ...engineeringParam.value }
// 创建新的项目Tab
projectInfoList.value.push({
name: '',
area: '',
description: '',
})
deviceIndex.value = (projectInfoList.value.length - 1).toString()
nextfalg.value = false
nodeLevel.value = 1
break
case 1: // 项目层级下一步创建设备Tab
// 保存当前项目信息到临时存储
const currentProject = { ...projectInfoList.value[deviceIndex.value] }
tempAllLevelData.value.projects[deviceIndex.value] = currentProject
// 创建新的设备Tab
deviceInfoList.value.push({
name: '',
devModel: '',
devType: '',
devAccessMethod: 'CLD',
mac: '',
ndid: '',
nodeId: '',
cntractNo: '',
sort: 0,
nodeProcess: '自动分配',
})
busBarIndex.value = (deviceInfoList.value.length - 1).toString()
nextfalg.value = false
nodeLevel.value = 2
break
case 2: // 设备层级下一步创建监测点Tab
// 保存当前设备信息到临时存储
const currentDevice = { ...deviceInfoList.value[busBarIndex.value] }
tempAllLevelData.value.devices[busBarIndex.value] = currentDevice
// 创建新的监测点Tab
lineInfoList.value.push({
name: '',
lineNo: 1,
conType: 0,
lineInterval: 1,
ptRatio: 0,
pt2Ratio: 0,
ctRatio: 0,
ct2Ratio: 0,
volGrade: '',
devMac: '',
})
lineIndex.value = (lineInfoList.value.length - 1).toString()
nextfalg.value = true
nodeLevel.value = 3
break
case 3: // 监测点层级
// 保存当前监测点信息到临时存储
const currentLine = { ...lineInfoList.value[lineIndex.value] }
tempAllLevelData.value.lines[lineIndex.value] = currentLine
nextfalg.value = true
nodeLevel.value = 4
break
}
}
// 撤销
const black = () => {
pageStatus.value = 1
busBarIndex.value = '0'
deviceIndex.value = '0'
lineIndex.value = '0'
// 清空临时数据
tempAllLevelData.value = {
engineering: null,
projects: [],
devices: [],
lines: []
}
nodeClick(nodeEventList.value,nodeDataList.value)
}
// 确认提交
const onsubmit = () => {
if (pageStatus.value == 2) {
// 新增
// 检查是否是多层级新增还是单层级新增
if (tempAllLevelData.value.engineering !== null ||
tempAllLevelData.value.projects.length > 0 ||
tempAllLevelData.value.devices.length > 0 ||
tempAllLevelData.value.lines.length > 0) {
// 多层级新增,一次性提交所有数据
submitAllLevelData()
} else {
// 单层级新增,使用原有的提交方式
submitData()
}
} else if (pageStatus.value == 3) {
// 修改
switch (nodeLevel.value) {
case 1: // 修改工程
updateEngineering(nodeData.value.id)
break
case 2: // 修改项目
updateProjectFunc(nodeData.value.id)
break
case 3: // 修改设备
updateEquipmentFunc(nodeData.value.id)
break
case 4: // 修改监测点
updateLineFunc(nodeData.value.id)
break
}
}
}
/**
* 一次性提交所有层级数据
*/
const submitAllLevelData = () => {
let submitData: any = {}
// 根据当前节点层级构建相应的数据结构
switch (nodeLevel.value) {
case 0: // 只有工程
submitData = {
engineering: tempAllLevelData.value.engineering || { ...engineeringParam.value }
}
break
case 1: // 工程 + 项目
// 工程信息
const engineeringData = tempAllLevelData.value.engineering || { ...engineeringParam.value }
// 项目信息
const projectData = tempAllLevelData.value.projects.length > 0
? tempAllLevelData.value.projects[0]
: (projectInfoList.value[0] || {})
// 如果是从根节点开始新增工程和项目
if (nodeData.value.level === 0) {
submitData = {
engineering: engineeringData,
project: projectData
}
} else {
// 如果是从工程节点开始新增项目
submitData = {
engineeringIndex: nodeData.value?.id || "",
project: projectData
}
}
break
case 2: // 工程 + 项目 + 设备
// 工程信息
const engineeringData2 = tempAllLevelData.value.engineering || { ...engineeringParam.value }
// 项目信息
const projectData2 = tempAllLevelData.value.projects.length > 0
? tempAllLevelData.value.projects[0]
: (projectInfoList.value[0] || {})
// 设备信息
let devices = []
if (tempAllLevelData.value.devices.length > 0) {
devices = tempAllLevelData.value.devices.filter((d: any) => d && d.name)
} else {
devices = deviceInfoList.value.filter((d: any) => d && d.name)
}
// 如果是从根节点开始新增
if (nodeData.value.level === 0) {
submitData = {
engineering: engineeringData2,
project: projectData2,
device: devices.map((device: any) => ({
...device,
ndid: device.mac ? device.mac.replace(/:/g, '') : ''
}))
}
}
// 如果是从工程节点开始新增
else if (nodeData.value.level === 1) {
submitData = {
engineeringIndex: nodeData.value?.id || "",
project: projectData2,
device: devices.map((device: any) => ({
...device,
ndid: device.mac ? device.mac.replace(/:/g, '') : ''
}))
}
}
// 如果是从项目节点开始新增
else if (nodeData.value.level === 2) {
const pidsArray = nodeData.value?.pids ? nodeData.value.pids.split(',') : [];
const engineeringId = pidsArray.length >= 2 ? pidsArray[1] : "";
submitData = {
projectIndex: nodeData.value?.id || "",
engineeringIndex: engineeringId,
device: devices.map((device: any) => ({
...device,
ndid: device.mac ? device.mac.replace(/:/g, '') : ''
}))
}
}
break
case 3: // 工程 + 项目 + 设备 + 监测点
case 4:
// 工程信息
const engineeringData3 = tempAllLevelData.value.engineering || { ...engineeringParam.value }
// 项目信息
const projectData3 = tempAllLevelData.value.projects.length > 0
? tempAllLevelData.value.projects[0]
: (projectInfoList.value[0] || {})
// 设备信息
let devices2: any[] = []
if (tempAllLevelData.value.devices.length > 0) {
devices2 = tempAllLevelData.value.devices.filter((d: any) => d && d.name)
} else {
devices2 = deviceInfoList.value.filter((d: any) => d && d.name)
}
// 监测点信息
let lines = []
if (tempAllLevelData.value.lines.length > 0) {
lines = tempAllLevelData.value.lines.filter((l: any) => l && l.name)
} else {
lines = lineInfoList.value.filter((l: any) => l && l.name)
}
// 如果是从根节点开始新增
if (nodeData.value.level === 0) {
submitData = {
engineering: engineeringData3,
project: projectData3,
device: devices2.map((device: any) => ({
...device,
ndid: device.mac ? device.mac.replace(/:/g, '') : ''
})),
line: lines.map((line: any) => {
// 处理电压等级,去除"kV"后缀
let volGradeValue = line.volGrade
if (typeof volGradeValue === 'string' && volGradeValue.endsWith('kV')) {
volGradeValue = volGradeValue.slice(0, -2)
}
// 获取设备MAC地址
let devMac = ''
if (devices2.length > 0) {
devMac = devices2[0].mac || ''
}
return {
...line,
volGrade: volGradeValue,
devMac: devMac
}
})
}
}
// 如果是从工程节点开始新增
else if (nodeData.value.level === 1) {
submitData = {
engineeringIndex: nodeData.value?.id || "",
project: projectData3,
device: devices2.map((device: any) => ({
...device,
ndid: device.mac ? device.mac.replace(/:/g, '') : ''
})),
line: lines.map((line: any) => {
// 处理电压等级,去除"kV"后缀
let volGradeValue = line.volGrade
if (typeof volGradeValue === 'string' && volGradeValue.endsWith('kV')) {
volGradeValue = volGradeValue.slice(0, -2)
}
// 获取设备MAC地址
let devMac = ''
if (devices2.length > 0) {
devMac = devices2[0].mac || ''
}
return {
...line,
volGrade: volGradeValue,
devMac: devMac
}
})
}
}
// 如果是从项目节点开始新增
else if (nodeData.value.level === 2) {
const pidsArray = nodeData.value?.pids ? nodeData.value.pids.split(',') : [];
const engineeringId = pidsArray.length >= 2 ? pidsArray[1] : "";
submitData = {
device: devices2.map((device: any) => ({
...device,
ndid: device.mac ? device.mac.replace(/:/g, '') : ''
})),
projectIndex: nodeData.value?.id || "",
engineeringIndex: engineeringId,
line: lines.map((line: any) => {
// 处理电压等级,去除"kV"后缀
let volGradeValue = line.volGrade
if (typeof volGradeValue === 'string' && volGradeValue.endsWith('kV')) {
volGradeValue = volGradeValue.slice(0, -2)
}
// 获取设备MAC地址
let devMac = ''
if (devices2.length > 0) {
devMac = devices2[0].mac || ''
}
return {
...line,
volGrade: volGradeValue,
devMac: devMac
}
})
}
}
// 如果是从设备节点开始新增
else if (nodeData.value.level === 3) {
const pidsArray2 = nodeData.value?.pids ? nodeData.value.pids.split(',') : [];
const engineeringId2 = pidsArray2.length >= 2 ? pidsArray2[1] : "";
const projectId = pidsArray2.length >= 3 ? pidsArray2[2] : "";
submitData = {
devIndex: nodeData.value?.id || "",
projectIndex: projectId,
engineeringIndex: engineeringId2,
line: lines.map((line: any) => {
// 处理电压等级,去除"kV"后缀
let volGradeValue = line.volGrade
if (typeof volGradeValue === 'string' && volGradeValue.endsWith('kV')) {
volGradeValue = volGradeValue.slice(0, -2)
}
// 获取设备MAC地址
let devMac = ''
if (devices2.length > 0) {
devMac = devices2[0].mac || ''
}
return {
...line,
volGrade: volGradeValue,
devMac: devMac
}
})
}
}
break
}
// 发送请求
addLedger(submitData).then((res: any) => {
ElMessage({
type: 'success',
message: '数据提交成功'
})
pageStatus.value = 1
// 清空所有表单
resetAllForms()
// 刷新树并选中合适的节点
TerminalRef.value.info().then(() => {
// 等待树更新完成后,根据之前点击的节点层级选中合适的节点
setTimeout(() => {
let nodeIdToSelect: string|null|undefined = null;
// 根据新增的层级选择要选中的节点
switch (nodeLevel.value) {
case 0: // 新增了工程,选中根节点
nodeIdToSelect = null; // 根节点
break;
case 1: // 新增了项目,选中工程节点
nodeIdToSelect = nodeData.value.id; // 工程节点
break;
case 2: // 新增了设备,选中项目节点
nodeIdToSelect = nodeData.value.id; // 项目节点
break;
case 3: // 新增了监测点,选中设备节点
case 4:
nodeIdToSelect = nodeData.value.id; // 设备节点
break;
}
if (nodeIdToSelect) {
setTimeout(() => {
treedata(nodeIdToSelect !== null ? nodeIdToSelect : undefined);
// 重新加载节点内容以显示最新数据
setTimeout(() => {
queryNodeContent();
}, 200);
}, 100);
} else {
treedata(); // 选中根节点
}
}, 100);
})
})
}
/**
* 重置所有表单
*/
const resetAllForms = () => {
// 清空工程表单
engineeringParam.value.city = ''
engineeringParam.value.description = ''
engineeringParam.value.name = ''
engineeringParam.value.province = ''
// 清空项目表单
projectInfoList.value.forEach(project => {
project.name = ''
project.area = ''
project.description = ''
})
// 清空设备表单
deviceInfoList.value.forEach(device => {
device.name = ''
device.devModel = ''
device.devType = ''
device.devAccessMethod = 'CLD'
device.mac = ''
device.nodeId = ''
device.cntractNo = ''
device.sort = 0
})
// 清空监测点表单
lineInfoList.value.forEach(line => {
line.name = ''
line.lineNo = 1
line.conType = 0
line.lineInterval = 1
line.ptRatio = 0
line.pt2Ratio = 0
line.ctRatio = 0
line.ct2Ratio = 0
line.volGrade = ''
})
// 清空临时数据
tempAllLevelData.value = {
engineering: null,
projects: [],
devices: [],
lines: []
}
}
/**
* 提交数据
*/
const submitData = () => {
switch (nodeLevel.value) {
case 0: // 新增工程
const engineering = {
engineering: {
city: engineeringParam.value.city,
description: engineeringParam.value.description,
name: engineeringParam.value.name,
province: engineeringParam.value.province
},
};
addLedger(engineering).then((res: any) => {
ElMessage({
type: 'success',
message: '新增工程成功'
})
pageStatus.value = 1
// 刷新树并选中根节点
setTimeout(() => {
treedata(); // 选中根节点
}, 100);
})
break ;
case 1:// 新增项目
const project = {
engineeringIndex: nodeData.value?.id || "",
project: {
area: projectInfoList.value[deviceIndex.value]?.area || "",
description: projectInfoList.value[deviceIndex.value]?.description || "",
name: projectInfoList.value[deviceIndex.value]?.name || "",
engineeringId: nodeData.value?.id || "",
},
};
addLedger(project).then((res: any) => {
ElMessage({
type: 'success',
message: '新增项目成功'
})
pageStatus.value = 1
// 刷新树并选中工程节点(而不是新增的项目节点)
const engineeringId = nodeData.value?.id; // 工程ID
if (engineeringId) {
setTimeout(() => {
treedata(engineeringId); // 选中工程节点
// 重新加载节点内容以显示最新数据
setTimeout(() => {
queryNodeContent();
}, 200);
}, 100);
} else {
TerminalRef.value.info();
}
})
break;
case 2:// 新增设备
// 获取当前选中的设备信息
const currentDevice = deviceInfoList.value[busBarIndex.value];
if (!currentDevice) {
ElMessage({
type: 'error',
message: '未找到设备信息'
});
return;
}
const pidsArray = nodeData.value?.pids ? nodeData.value.pids.split(',') : [];
const engineeringId = pidsArray.length >= 2 ? pidsArray[1] : "";
const deviceData = {
projectIndex: nodeData.value?.id || "",
engineeringIndex: engineeringId,
device: [{
name: currentDevice.name,
devModel: currentDevice.devModel,
devType: currentDevice.devType,
devAccessMethod: currentDevice.devAccessMethod,
mac: currentDevice.mac,
nodeId: currentDevice.nodeId,
cntractNo: currentDevice.cntractNo,
ndid: currentDevice.mac.replace(/:/g, ''),
sort: currentDevice.sort,
}],
};
addLedger(deviceData).then((res: any) => {
ElMessage({
type: 'success',
message: '新增设备成功'
})
pageStatus.value = 1
// 刷新树并选中项目节点(而不是新增的设备节点)
const projectId = nodeData.value?.id; // 项目ID
if (projectId) {
setTimeout(() => {
treedata(projectId); // 选中项目节点
// 重新加载节点内容以显示最新数据
setTimeout(() => {
queryNodeContent();
}, 200);
}, 100);
} else {
TerminalRef.value.info();
}
})
break;
case 3:// 新增监测点
// 获取当前选中的监测点信息
const currentLine = lineInfoList.value[lineIndex.value];
if (!currentLine) {
ElMessage({
type: 'error',
message: '未找到监测点信息'
});
return;
}
// 处理电压等级,去除"kV"后缀
let volGradeValue = currentLine.volGrade;
if (typeof volGradeValue === 'string' && volGradeValue.endsWith('kV')) {
volGradeValue = volGradeValue.slice(0, -2);
}
// 从pids中提取工程ID和项目ID
const pidsArray2 = nodeData.value?.pids ? nodeData.value.pids.split(',') : [];
const engineeringId2 = pidsArray2.length >= 2 ? pidsArray2[1] : "";
const projectId2 = pidsArray2.length >= 3 ? pidsArray2[2] : "";
const lineData = {
devIndex: nodeData.value?.id || "",
projectIndex: projectId2, // 从pids中提取的项目ID
engineeringIndex: engineeringId2, // 从pids中提取的工程ID
line: [{
name: currentLine.name,
lineNo: currentLine.lineNo,
conType: currentLine.conType,
lineInterval: currentLine.lineInterval,
ptRatio: currentLine.ptRatio,
pt2Ratio: currentLine.pt2Ratio,
ctRatio: currentLine.ctRatio,
ct2Ratio: currentLine.ct2Ratio,
volGrade: volGradeValue,
devMac: deviceInfoList.value[busBarIndex.value].mac,
}]
};
addLedger(lineData).then((res: any) => {
ElMessage({
type: 'success',
message: '新增监测点成功'
})
pageStatus.value = 1
// 刷新树并选中设备节点(而不是新增的监测点节点)
const deviceId = nodeData.value?.id; // 设备ID
if (deviceId) {
setTimeout(() => {
treedata(deviceId); // 选中设备节点
// 重新加载节点内容以显示最新数据
setTimeout(() => {
queryNodeContent();
}, 200);
}, 100);
} else {
TerminalRef.value.info();
}
})
break;
}
}
/**
* 项目tab编辑新增/删除)
*/
const handleDeviceTabsEdit = (targetName: any, action: any) => {
if (action === 'add') {
// 新增项目
projectInfoList.value.push({
name: '',
area: '',
description: ''
})
deviceIndex.value = (projectInfoList.value.length - 1).toString()
} else if (action === 'remove') {
// 删除项目
ElMessageBox.confirm('此操作将永久删除, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
// 删除项目
if (projectInfoList.value[deviceIndex.value]?.id) {
deleteProject(
projectInfoList.value[deviceIndex.value].id,
projectInfoList.value[deviceIndex.value].name,
projectInfoList.value[deviceIndex.value].area,
projectInfoList.value[deviceIndex.value].description,
0 // 0表示删除
).then((res: any) => {
ElMessage({
type: 'success',
message: res.message
})
// 从列表中移除
projectInfoList.value.splice(deviceIndex.value, 1)
// 重新设置当前选中的tab
deviceIndex.value = projectInfoList.value.length
? (projectInfoList.value.length - 1).toString()
: '0'
// 重置相关索引
busBarIndex.value = '0'
lineIndex.value = '0'
pageStatus.value = 1
treedata()
})
} else {
// 如果是新增模式下删除未保存的项目
projectInfoList.value.splice(deviceIndex.value, 1)
deviceIndex.value = projectInfoList.value.length
? (projectInfoList.value.length - 1).toString()
: '0'
busBarIndex.value = '0'
lineIndex.value = '0'
ElMessage({
type: 'success',
message: '删除成功'
})
}
}).catch(() => {
ElMessage({
type: 'info',
message: '已取消删除'
})
})
}
}
/**
* 设备tab编辑新增/删除)
*/
const handleBusBarTabsEdit = (targetName: any, action: any) => {
if (action === 'add') {
// 新增设备
deviceInfoList.value.push({
name: '',
devModel: '',
devType: '',
devAccessMethod: 'CLD',
mac: '',
ndid: '',
nodeId: '',
cntractNo: '',
sort: 0,
nodeProcess: '自动分配',
})
busBarIndex.value = (deviceInfoList.value.length - 1).toString()
} else if (action === 'remove') {
// 删除设备
ElMessageBox.confirm('此操作将永久删除, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
// 如果是编辑现有设备
if ( deviceInfoList.value[busBarIndex.value]?.id) {
deleteEquipment(deviceInfoList.value[busBarIndex.value].id).then((res: any) => {
ElMessage({
type: 'success',
message: res.message
})
// 从列表中移除
deviceInfoList.value.splice(busBarIndex.value, 1)
// 重新设置当前选中的tab
busBarIndex.value = deviceInfoList.value.length
? (deviceInfoList.value.length - 1).toString()
: '0'
lineIndex.value = '0'
pageStatus.value = 1
treedata()
})
} else {
// 如果是新增模式下删除未保存的设备
deviceInfoList.value.splice(busBarIndex.value, 1)
busBarIndex.value = deviceInfoList.value.length
? (deviceInfoList.value.length - 1).toString()
: '0'
lineIndex.value = '0'
ElMessage({
type: 'success',
message: '删除成功'
})
}
}).catch(() => {
ElMessage({
type: 'info',
message: '已取消删除'
})
})
}
}
/**
* 监测点tab编辑新增/删除)
*/
const handleLineTabsEdit = (targetName: any, action: any) => {
if (action === 'add') {
// 新增监测点
lineInfoList.value.push({
name: '',
lineNo: 1,
conType: 0,
lineInterval: 1,
ptRatio: 0,
pt2Ratio: 0,
ctRatio: 0,
ct2Ratio: 0,
volGrade: '',
devMac: '',
})
lineIndex.value = (lineInfoList.value.length - 1).toString()
} else if (action === 'remove') {
// 删除监测点
ElMessageBox.confirm('此操作将永久删除, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
// 如果是编辑现有监测点
if (lineInfoList.value[lineIndex.value]?.lineId) {
deleteLine(lineInfoList.value[lineIndex.value].lineId).then((res: any) => {
ElMessage({
type: 'success',
message: res.message
})
// 从列表中移除
lineInfoList.value.splice(lineIndex.value, 1)
// 重新设置当前选中的tab
lineIndex.value = lineInfoList.value.length
? (lineInfoList.value.length - 1).toString()
: '0'
pageStatus.value = 1
treedata()
})
} else {
// 如果是新增模式下删除未保存的监测点
lineInfoList.value.splice(lineIndex.value, 1)
lineIndex.value = lineInfoList.value.length
? (lineInfoList.value.length - 1).toString()
: '0'
ElMessage({
type: 'success',
message: '删除成功'
})
}
}).catch(() => {
ElMessage({
type: 'info',
message: '已取消删除'
})
})
}
}
const tabChange = (type: string) => {
if (type == 'deviceIndex') {
busBarIndex.value = '0'
lineIndex.value = '0'
} else if (type == 'busBarIndex') {
lineIndex.value = '0'
}
}
const treedata = (selectedNodeId?: string) => {
if (selectedNodeId) {
TerminalRef.value.info(selectedNodeId);
} else {
TerminalRef.value.info();
}
titleList.value = []
titleList.value.unshift('在线设备')
}
/**
* 重置初始状态
*/
const reaseStatus = () => {
nodeData.value = {}
nodeLevel.value = 0
pageStatus.value = 1
projectId.value = 0
provinceId.value = 0
gdId.value = 0
subId.value = 0
devId.value = 0
busBarId.value = 0
lineId.value = 0
deviceIndex.value = '0'
busBarIndex.value = '0'
lineIndex.value = '0'
currentGdName.value = ''
}
const area = () => {
nodeAllList().then(res => {
affiliatiedFrontArr.value = res.data
}).catch(error => {
console.error('获取前置机数据失败:', error)
})
queryByCode('DEV_CLD').then(res => {
devTypeOptions2.value = res.data
return queryCsDictTree(res.data.id).then(res => {
devCLD.value = res.data
})
}).then(() => {
return queryByCode('Device_Type').then(res => {
return queryCsDictTree(res.data.id).then(res => {
devTypeOptions.value = res.data
})
})
}).catch(error => {
console.error('查询过程中出现错误:', error)
})
}
onMounted(() => {
nodeData.value.level = 0
const dom = document.getElementById('navigation-splitpanes')
if (dom) {
size.value = Math.round((180 / dom.offsetHeight) * 100)
}
})
area()
</script>
<style scoped>
</style>
<style lang="scss" scoped>
.is-loading {
animation: rotating 2s linear infinite;
}
@keyframes rotating {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.device-manage {
display: flex;
padding: 10px;
&-right {
overflow: hidden;
flex: 1;
padding: 10px 10px 10px 0;
.el-descriptions__header {
height: 36px;
margin-bottom: 7px;
display: flex;
align-items: center;
}
}
}
.main-form {
display: flex;
flex-wrap: wrap;
.form-top {
width: 100%;
}
.el-form-item {
width: 30%;
margin-bottom: 15px;
.el-select {
width: 100%;
min-width: 0px;
}
}
}
.el-tabs__content {
margin-top: 15px;
}
.splitpanes.default-theme .splitpanes__pane {
background: #fff !important;
}
.title {
width: 500px;
overflow: hidden;
// display: flex;
white-space: nowrap;
font-weight: bold;
}
.titleScroll {
animation: scroll 10s linear infinite; /* 滚动动画 */
}
@keyframes scroll {
0% {
transform: translateX(100%); /* 从右侧开始 */
}
100% {
transform: translateX(-160%); /* 滚动到左侧 */
}
}
</style>