修改台账树

This commit is contained in:
guanj
2026-06-17 09:23:35 +08:00
parent d9dfd804c5
commit 2330b50147
25 changed files with 853 additions and 476 deletions

View File

@@ -26,3 +26,30 @@ export function deleteUser(data: any) {
data: data
})
}
// 新增治理方案绑定
export function saveGovernPlan(data: any) {
return request({
url: '/cs-harmonic-boot/pqGovernPlan/save',
method: 'post',
data
})
}
// 修改治理方案绑定
export function updateGovernPlan(data: any) {
return request({
url: '/cs-harmonic-boot/pqGovernPlan/update',
method: 'post',
data
})
}
// 删除治理方案绑定
export function deleteGovernPlan(data: any) {
return request({
url: '/cs-harmonic-boot/pqGovernPlan/delete',
method: 'post',
data
})
}

View File

@@ -116,14 +116,14 @@ const tableStore: any = new TableStore({
{ title: '设备名称', field: 'devName', minWidth: 130, align: 'center' },
{ title: '项目名称', field: 'projectName', minWidth: 130, align: 'center' },
{ title: '工程名称', field: 'engineeringName', minWidth: 130, align: 'center' },
{
title: '监测类型',
field: 'position',
minWidth: '100',
formatter: (row: any) => {
return row.cellValue || '/'
}
},
// {
// title: '监测类型',
// field: 'position',
// minWidth: '100',
// formatter: (row: any) => {
// return row.cellValue || '/'
// }
// },
// {
// title: '监测点状态',
// field: 'runStatus',

View File

@@ -83,7 +83,7 @@ const tableStore: any = new TableStore({
},
{
title: '敏感用户类型',
title: '用户类型',
field: 'loadType',
minWidth: '70',
formatter: row => {

View File

@@ -1,6 +1,6 @@
export let color = ['#07CCCA', '#00BFF5', '#FFBF00', '#77DA63', '#Ff6600', '#FF9100', '#5B6E96', '#66FFEC', '#B3B3B3', '#9B59B6', '#3498DB', '#2ECC71']
export let color1 = [
'#00A8B5', // 青
'#3B7DD8', // 蓝
'#5B5FC7', // 靛
'#8B5CF6', // 紫
@@ -11,6 +11,7 @@ export let color1 = [
'#00A878', // 翠绿
'#7C9EB2', // 烟蓝
'#6B7B8C', // 板岩灰
'#00A8B5', // 青
'#A8A8A8' // 灰
]
export const gradeColor3 = ['#339966', '#FFCC33', '#A52a2a']

View File

@@ -74,7 +74,7 @@ import { useConfig } from '@/stores/config'
import type TableStoreClass from '@/utils/tableStore'
import { useRouter } from 'vue-router'
import { defaultAttribute } from '@/components/table/defaultAttribute'
import { buildExportBaseName } from '@/utils/echartMethod'
import { buildExportBaseName,formatExportDateTime } from '@/utils/echartMethod'
const config = useConfig()
const tableRef = ref<VxeTableInstance>()
@@ -165,7 +165,7 @@ watch(
() => tableStore.table.allFlag,
newVal => {
if (tableStore.table.allFlag) {
console.log('🚀 ~ tableStore.table.allData:', tableStore.table.allData)
// console.log('🚀 ~ tableStore.table.allData:', tableStore.table.allData)
tableRef.value?.exportData({
filename: getTableExportFilename(), // 文件名字

View File

@@ -52,7 +52,7 @@ const tree = ref<any[]>([])
const treRef = ref<InstanceType<typeof ElTree>>()
const filterText = ref('')
const defaultProps = { children: 'children', label: 'name', value: 'id' }
const defaultProps = { children: 'children', label: 'governName', value: 'id' }
const decorators = createLineTreeDecorators(() => config.getColorVal('elementUiPrimary'))
const filterNode = createTreeFilterNode()
@@ -78,11 +78,12 @@ function transformUserDevTree(data: Record<string, any[] | null>) {
...device,
level: 2,
pid: userId,
pname: userName
pname: userName,
}
applyMeta(node, {
icon: 'el-icon-Platform',
color: statusColor(device.runStatus)
icon: 'el-icon-Document',
color: primary(),
})
devices.push(node)
return node
@@ -91,7 +92,7 @@ function transformUserDevTree(data: Record<string, any[] | null>) {
const userNode: any = {
id: userId,
name: userName,
governName: userName,
level: 1,
...(children ? { children } : {})
}

View File

@@ -205,7 +205,7 @@ defineExpose({ treeRef })
:deep(.el-tree) {
border: 1px solid var(--el-border-color);
border-radius: 4px;
// border-radius: 4px;
}
:deep(.el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content) {

View File

@@ -35,7 +35,7 @@ const tableStore: any = new TableStore({
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
}
},
{ field: 'name', title: '名称' },
{ field: 'name', title: '方案名称' },
{ field: 'onlineRateLimit', title: '在线率阈值' },
{ field: 'integrityLimit', title: '完整性阈值' },
{ field: 'updateTime', title: '创建时间' },

View File

@@ -15,8 +15,8 @@
</el-select>
</el-form-item>
<el-form-item label="表名">
<el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.tableName" placeholder="请输入表名" clearable
/>
<el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.tableName"
placeholder="请输入表名" clearable />
</el-form-item>
</template>
<template #operation>
@@ -81,8 +81,15 @@ const tableStore: any = new TableStore({
}
},
{
field: 'unit', title: '单位', width: 80,
formatter: (row: any) => {
return row.cellValue || '/'
}
},
{ field: 'minValue', title: '指标下限', width: 100 },
{ field: 'maxValue', title: '指标上限', width: 100 },
{
field: 'isVoltage',
title: '电压等级参与',
@@ -99,13 +106,8 @@ const tableStore: any = new TableStore({
{ field: 'belongingSystem', title: '所属系统', width: 100 },
{
field: 'unit', title: '单位', width: 80,
formatter: (row: any) => {
return row.cellValue || '/'
}
},
{ field: 'sort', title: '排序', width: 70 },
{
field: 'otherAlgorithm', title: '条件描述', minWidth: 200,
formatter: (row: any) => {
@@ -117,7 +119,7 @@ const tableStore: any = new TableStore({
formatter: (row: any) => {
return row.cellValue || '/'
}
},
}, { field: 'sort', title: '排序', width: 70 },
{
title: '操作',

View File

@@ -133,21 +133,21 @@ const nodeClick = async (e: anyObj) => {
if (zblist.value.length === 0) {
await init()
}
getDevCapacity(formInline.devId)
.then(res => {
devCapacity.value = res.data
// getDevCapacity(formInline.devId)
// .then(res => {
// devCapacity.value = res.data
search()
})
.catch(() => {
loading.value = false
})
// })
// .catch(() => {
// loading.value = false
// })
}
}
const lineStyle = [
{ type: 'solid', width: 3 },
{ type: 'dashed', width: 3 },
{ type: 'dashed', width: 3 }
{ type: 'solid', },
{ type: 'dashed', },
{ type: 'dashed', }
]
const search = () => {
if (timeFlag.value) {

View File

@@ -91,9 +91,9 @@ const typelist = [
]
const lineStyle = [
{ type: 'solid', width: 3 },
{ type: 'dotted', width: 3 },
{ type: 'dashed', width: 3 }
{ type: 'solid', },
{ type: 'dotted', },
{ type: 'dashed', }
]
const getEngineeringTree = () => treeRef.value?.treRef?.treeRef4

View File

@@ -4,9 +4,9 @@
:showPush="true"></CloudDeviceEntryTree>
<div class="device-manage-right pd0 ">
<el-form :inline="true" class="demo-form-inline" style="height: 42px">
<el-form-item style="position: relative; z-index: 2"
v-if="!((nodeLevel == 3 || nodeLevel == 4) && connectionMethod == 'MQTT')">
<el-button icon="el-icon-Plus" type="primary" @click="add" v-if="nodeLevel != 4">
<el-form-item style="position: relative; z-index: 2">
<el-button icon="el-icon-Plus" type="primary" @click="add"
v-if="nodeLevel != 4 && !(connectionMethod == 'MQTT' && nodeLevel == 3)">
{{
nodeLevel == 0
? '新增工程'
@@ -19,8 +19,7 @@
: '新增监测点'
}}
</el-button>
<el-button icon="el-icon-Edit" type="primary" @click="update"
v-if="!(nodeLevel == 4 && connectionMethod == 'MQTT') && nodeLevel != 0">
<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">
@@ -40,11 +39,11 @@
修改提交
</el-button>
</el-form-item>
<el-form-item style="position: relative; z-index: 2" v-else>
<!-- <el-form-item style="position: relative; z-index: 2" v-else>
<span style="font-size: 16px; font-weight: bold; color: var(--el-color-primary)">
MQTT通讯方式的设备暂不支持修改
</span>
</el-form-item>
</el-form-item> -->
<el-form-item style="right: 300px; position: absolute; overflow: hidden">
<LocationInformation style="width: 16px; margin-right: 8px; color: var(--el-color-primary)" />
@@ -64,7 +63,7 @@
<el-form class="main-form overview_scroll" :label-position="'right'" label-width="130px" :inline="true"
ref="mainForm" :model="formData">
<el-tabs type="border-card" v-if="nodeLevel != 0">
<el-tab-pane :label="formData.engineeringParam.name || '工程信息'">
<!--工程-->
@@ -158,23 +157,31 @@
<el-form-item label="拓扑图" :prop="'projectInfoList[' + index + '].topoId'" :rules="[
{ required: true, message: '请选择拓扑图', trigger: 'change' }
]">
<el-select v-model="item.topoId" placeholder="请选择拓扑图"
popper-class="productSelector " :disabled="!(
(nodeLevel == 2 && pageStatus == 3) ||
((nodeLevel == 1 || (nodeLevel == 0 && pageStatus == 2)) &&
pageStatus == 2)
)
">
<el-option v-for="item in images" :key="item.id" :label="item.name"
:value="item.id">
<span>
<img :src="item.url" v-if="item.url" class="image-preview" />
</span>
<span style="float: right">
{{ item.name }}
</span>
</el-option>
</el-select>
<div style="display: flex; align-items: center;width: 100%">
<el-select v-model="item.topoId" placeholder="请选择拓扑图"
popper-class="productSelector " :disabled="!(
(nodeLevel == 2 && pageStatus == 3) ||
((nodeLevel == 1 || (nodeLevel == 0 && pageStatus == 2)) &&
pageStatus == 2)
)
">
<el-option v-for="item in images" :key="item.id" :label="item.name"
:value="item.id">
<span>
<img :src="item.url" v-if="item.url" class="image-preview" />
</span>
<span style="float: right">
{{ item.name }}
</span>
</el-option>
</el-select>
<el-button icon="el-icon-Plus" type="primary" class="ml10"
@click="addTopology"></el-button>
</div>
</el-form-item>
<el-form-item class="form-item" label="排序"
:prop="'projectInfoList[' + index + '].sort'"
@@ -252,7 +259,7 @@
{ required: true, message: '请选择设备通讯方式', trigger: 'change' }
]">
<el-select clearable filterable v-model="busItem.devAccessMethod"
placeholder="请选择设备通讯方式" style="width: 100%" :disabled="!(
placeholder="请选择设备通讯方式" style="width: 100%" :disabled="!(connectionMethod != 'MQTT' &&
(nodeLevel == 3 && pageStatus == 3) ||
((nodeLevel == 2 || (nodeLevel == 1 && pageStatus == 2)) &&
pageStatus == 2)
@@ -269,8 +276,11 @@
message: '请输入设备mac地址',
trigger: 'blur'
}">
<MacAddressInput v-model="busItem.mac"
:disabled="!(pageStatus == 2 && nodeLevel == 2)" />
<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" v-if="busItem.devAccessMethod == 'CLD'"
@@ -301,11 +311,15 @@
label="所属前置机" :prop="'deviceInfoList[' + bIndex + '].nodeId'" :rules="[
{ required: true, message: '请选择所属前置机', trigger: 'change' }
]">
<el-select clearable 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>
<div style="display: flex; align-items: center;width: 100%">
<el-select clearable 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-button icon="el-icon-Plus" type="primary" class="ml10"
@click="addAffiliatiedFront"></el-button>
</div>
</el-form-item>
<el-form-item v-if="busItem.devAccessMethod == 'CLD'" class="form-item" label="进程号"
:prop="'deviceInfoList[' + bIndex + '].nodeProcess'">
@@ -388,11 +402,12 @@
(nodeLevel >= 3 || pageStatus == 2) &&
formData.lineInfoList.length > 0
">
<!-- connectionMethod != 'MQTT' -->
<el-tabs type="border-card" v-model="lineIndex" :addable="false" :closable="pageStatus != 1"
@edit="handleLineTabsEdit" @tab-click="tabChange('lineIndex', $event)">
<el-tab-pane v-for="(lineItem, lIndex) in formData.lineInfoList" :key="lIndex"
:label="lineItem.name ? lineItem.name : '新建监测点' + lIndex" :name="lIndex + ''">
<div class="flex mt10" v-if="connectionMethod != 'MQTT'">
<div class="flex mt10">
<el-form-item class="form-item" label="监测点名称"
:prop="'lineInfoList[' + lIndex + '].name'" :rules="{
required: true,
@@ -407,7 +422,7 @@
)
"></el-input>
</el-form-item>
<el-form-item class="form-item" label="线路号"
<el-form-item class="form-item" label="线路号" v-if="connectionMethod != 'MQTT'"
:prop="'lineInfoList[' + lIndex + '].lineNo'" :rules="{
required: true,
message: '请选择线路号',
@@ -432,7 +447,7 @@
}">
<el-select clearable filterable v-model="lineItem.conType" placeholder="请选择接线方式"
:disabled="!(
(nodeLevel == 4 && pageStatus == 3) ||
connectionMethod != 'MQTT' && (nodeLevel == 4 && pageStatus == 3) ||
((nodeLevel == 3 || (nodeLevel == 2 && pageStatus == 2)) &&
pageStatus == 2)
)
@@ -449,7 +464,7 @@
}">
<el-select clearable filterable v-model="lineItem.volGrade"
@change="volGradeChange($event, lineItem)" placeholder="请选择电压等级" :disabled="!(
(nodeLevel == 4 && pageStatus == 3) ||
connectionMethod != 'MQTT' && (nodeLevel == 4 && pageStatus == 3) ||
((nodeLevel == 3 || (nodeLevel == 2 && pageStatus == 2)) &&
pageStatus == 2)
)
@@ -463,9 +478,9 @@
:prop="'lineInfoList[' + lIndex + '].ptRatio'"
:rules="{ required: true, message: '请输入pt', trigger: 'blur' }">
<div style="width: 100%; display: flex; justify-content: space-between">
<el-input maxlength="32" show-word-limit clearable-number :controls="false"
:min="1" style="width: 48%" oninput="value=value.replace(/[^\d]/g,'')"
v-model.number="lineItem.ptRatio" :disabled="!(
<el-input clearable-number :controls="false" :min="1" style="width: 48%"
oninput="value=value.replace(/[^\d]/g,'')"
v-model.number="lineItem.ptRatio" :disabled="!(connectionMethod != 'MQTT' &&
(nodeLevel == 4 && pageStatus == 3) ||
((nodeLevel == 3 ||
(nodeLevel == 2 && pageStatus == 2)) &&
@@ -479,9 +494,9 @@
">
:
</span>
<el-input maxlength="32" show-word-limit clearable-number :controls="false"
:min="1" style="width: 48%" oninput="value=value.replace(/[^\d]/g,'')"
v-model.number="lineItem.pt2Ratio" :disabled="!(
<el-input clearable-number :controls="false" :min="1" style="width: 48%"
oninput="value=value.replace(/[^\d]/g,'')"
v-model.number="lineItem.pt2Ratio" :disabled="!(connectionMethod != 'MQTT' &&
(nodeLevel == 4 && pageStatus == 3) ||
((nodeLevel == 3 ||
(nodeLevel == 2 && pageStatus == 2)) &&
@@ -494,9 +509,9 @@
:prop="'lineInfoList[' + lIndex + '].ctRatio'"
:rules="{ required: true, message: '请输入ct', trigger: 'blur' }">
<div style="width: 100%; display: flex; justify-content: space-between">
<el-input maxlength="32" show-word-limit clearable-number :controls="false"
:min="1" style="width: 48%" oninput="value=value.replace(/[^\d]/g,'')"
v-model.number="lineItem.ctRatio" :disabled="!(
<el-input clearable-number :controls="false" :min="1" style="width: 48%"
oninput="value=value.replace(/[^\d]/g,'')"
v-model.number="lineItem.ctRatio" :disabled="!(connectionMethod != 'MQTT' &&
(nodeLevel == 4 && pageStatus == 3) ||
((nodeLevel == 3 ||
(nodeLevel == 2 && pageStatus == 2)) &&
@@ -510,9 +525,9 @@
">
:
</span>
<el-input maxlength="32" show-word-limit clearable-number :controls="false"
:min="1" style="width: 48%" oninput="value=value.replace(/[^\d]/g,'')"
v-model.number="lineItem.ct2Ratio" :disabled="!(
<el-input clearable-number :controls="false" :min="1" style="width: 48%"
oninput="value=value.replace(/[^\d]/g,'')"
v-model.number="lineItem.ct2Ratio" :disabled="!(connectionMethod != 'MQTT' &&
(nodeLevel == 4 && pageStatus == 3) ||
((nodeLevel == 3 ||
(nodeLevel == 2 && pageStatus == 2)) &&
@@ -589,7 +604,7 @@
required: true,
message: '请选择运行状态',
trigger: 'change'
}">
}" v-if="connectionMethod != 'MQTT'">
<!-- 0运行1检修2停运3调试4退运 -->
<el-select clearable filterable v-model="lineItem.runStatus"
placeholder="请选择运行状态" :disabled="!(
@@ -618,7 +633,7 @@
:label="option.name" :value="option.id"></el-option>
</el-select>
</el-form-item> -->
<el-form-item class="form-item" label="监测对象类型">
<el-form-item class="form-item" label="监测对象类型" v-if="connectionMethod != 'MQTT'">
<el-select clearable filterable v-model="lineItem.monitorObj"
placeholder="请选择监测对象类型" :disabled="!(
(nodeLevel == 4 && pageStatus == 3) ||
@@ -656,7 +671,7 @@
</el-select>
</el-form-item> -->
<el-form-item class="form-item" label="日志等级"
<el-form-item class="form-item" label="日志等级" v-if="connectionMethod != 'MQTT'"
:prop="'lineInfoList[' + lIndex + '].lineLogLevel'" :rules="{
required: true,
message: '请选择日志等级',
@@ -674,7 +689,7 @@
:value="value.value"></el-option>
</el-select>
</el-form-item>
<el-form-item class="form-item" label="是否主要监测点"
<el-form-item class="form-item" label="是否主要监测点" v-if="connectionMethod != 'MQTT'"
:prop="'lineInfoList[' + lIndex + '].isImportant'" :rules="{
required: true,
message: '请选择是否主要监测点',
@@ -693,18 +708,12 @@
</el-select>
</el-form-item>
</div>
<div class="flex mt10" v-else>
<!-- <div class="flex mt10" v-else>
<el-form-item class="form-item" label="监测点名称">
<el-input maxlength="32" show-word-limit clearable v-model="lineItem.name"
placeholder="请输入监测点名称" :disabled="true"></el-input>
</el-form-item>
<!-- <el-form-item class="form-item" label="线路号">
<el-select clearable filterable v-model="lineItem.lineNo"
placeholder="请选择线路号" :disabled="true">
<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="接线方式">
<el-select clearable filterable v-model="lineItem.conType" placeholder="请选择接线方式"
:disabled="true">
@@ -770,17 +779,8 @@
</el-select>
</el-form-item>
<!-- <el-form-item class="form-item" label="运行状态">
<el-select clearable filterable v-model="lineItem.runStatus"
placeholder="请选择通讯状态" :disabled="true">
<el-option label="运行" :value="0" />
<el-option label="检修" :value="1" />
<el-option label="停运" :value="2" />
<el-option label="调试" :value="3" />
<el-option label="退运" :value="4" />
</el-select>
</el-form-item> -->
</div>
</div> -->
</el-tab-pane>
</el-tabs>
</div>
@@ -831,7 +831,7 @@ 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 { ref, reactive, onMounted, onActivated, computed } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
getById,
@@ -859,11 +859,10 @@ import { convertToObject } from 'typescript'
import { Loading } from '@element-plus/icons-vue'
import { getList } from '@/api/cs-harmonic-boot/recruitment'
import { getDicDataByTypeCode } from '@/api/system-boot/csDictData'
import { useRouter } from 'vue-router'
defineOptions({
name: '/cs-device-boot/cloudDeviceEntry'
})
const { push, options, currentRoute } = useRouter()
const TerminalRef = ref()
const pageHeight = mainHeight(80)
const Height = mainHeight(124)
@@ -1739,6 +1738,89 @@ const remove = () => {
})
}
// 下一步
const getEngineeringProps = () => [
'engineeringParam.name',
'engineeringParam.province',
'engineeringParam.city',
'engineeringParam.sort'
]
const getProjectProps = (index: string | number) => [
`projectInfoList[${index}].name`,
`projectInfoList[${index}].area`,
`projectInfoList[${index}].description`,
`projectInfoList[${index}].topoId`,
`projectInfoList[${index}].sort`
]
const getDeviceProps = (index: string | number) => {
const prefix = `deviceInfoList[${index}]`
const props = [
`${prefix}.name`,
`${prefix}.devType`,
`${prefix}.devModel`,
`${prefix}.devAccessMethod`,
`${prefix}.mac`,
`${prefix}.sort`
]
if (pageStatus.value === 2 && nodeLevel.value === 2) {
props.push(`${prefix}.nodeId`)
}
return props
}
const getLineProps = (index: string | number) => {
const prefix = `lineInfoList[${index}]`
const props = [
`${prefix}.name`,
`${prefix}.conType`,
`${prefix}.volGrade`,
`${prefix}.ptRatio`,
`${prefix}.ctRatio`,
`${prefix}.lineInterval`,
`${prefix}.basicCapacity`,
`${prefix}.shortCircuitCapacity`,
`${prefix}.devCapacity`,
`${prefix}.protocolCapacity`,
`${prefix}.runStatus`
]
if (connectionMethod.value !== 'MQTT') {
props.push(`${prefix}.lineNo`, `${prefix}.lineLogLevel`, `${prefix}.isImportant`)
}
return props
}
/** 仅校验当前激活 tab 对应表单字段 */
const getActiveFormProps = (): string[] => {
const level = nodeLevel.value
if (pageStatus.value === 2) {
if (level === 0) return getEngineeringProps()
if (level === 1) return getProjectProps(deviceIndex.value)
if (level === 2) return getDeviceProps(busBarIndex.value)
if (level >= 3) return getLineProps(lineIndex.value)
}
if (pageStatus.value === 3) {
if (level === 1) return getEngineeringProps()
if (level === 2) return getProjectProps(deviceIndex.value)
if (level === 3) return getDeviceProps(busBarIndex.value)
if (level === 4) return getLineProps(lineIndex.value)
}
return []
}
const validateActiveTabForm = (): Promise<boolean> => {
const props = getActiveFormProps()
if (!props.length || !mainForm.value) return Promise.resolve(true)
return new Promise(resolve => {
mainForm.value.validateField(props, (valid: boolean) => {
resolve(valid)
})
})
}
const next = async () => {
await mainForm.value.validate((valid: any) => {
if (valid) {
@@ -1852,55 +1934,59 @@ const black = () => {
// 确认提交
const onsubmit = async () => {
await mainForm.value.validate((valid: any) => {
if (valid) {
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 valid = await validateActiveTabForm()
if (!valid) {
ElMessage.warning('请检查表单数据是否填写完整!')
return
}
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 {
ElMessage.warning('请检查表单数据是否填写完整!')
// 单层级新增,使用原有的提交方式
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 = async () => {
const valid = await validateActiveTabForm()
if (!valid) {
ElMessage.warning('请检查表单数据是否填写完整!')
return
}
let submitData: any = {}
await mainForm.value.validate((valid: any) => {
if (valid) {
// 根据当前节点层级构建相应的数据结构
switch (nodeLevel.value) {
// 根据当前节点层级构建相应的数据结构
switch (nodeLevel.value) {
case 0: // 只有工程
submitData = {
engineering: tempAllLevelData.value.engineering || { ...formData.value.engineeringParam }
@@ -2142,54 +2228,52 @@ const submitAllLevelData = async () => {
}
}
break
}
// 发送请求
addLedger(submitData).then((res: any) => {
ElMessage({
type: 'success',
message: '数据提交成功'
})
pageStatus.value = 1
// 清空所有表单
resetAllForms()
// 刷新树并选中合适的节点
TerminalRef.value.info()
// 等待树更新完成后,根据之前点击的节点层级选中合适的节点
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
}
// 发送请求
addLedger(submitData).then((res: any) => {
ElMessage({
type: 'success',
message: '数据提交成功'
})
pageStatus.value = 1
// 清空所有表单
resetAllForms()
// 刷新树并选中合适的节点
TerminalRef.value.info()
// 等待树更新完成后,根据之前点击的节点层级选中合适的节点
if (nodeIdToSelect) {
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() // 选中根节点
}
treedata(nodeIdToSelect !== null ? nodeIdToSelect : undefined)
// 重新加载节点内容以显示最新数据
setTimeout(() => {
queryNodeContent()
}, 200)
}, 100)
})
}
} else {
treedata() // 选中根节点
}
}, 100)
})
}
/**
@@ -2771,13 +2855,7 @@ const reaseStatus = () => {
}
const devModelOptions = ref([])
const area = async () => {
nodeAllList()
.then(res => {
affiliatiedFrontArr.value = res.data
})
.catch(error => {
console.error('获取前置机数据失败:', error)
})
getAffiliatiedFront()
// icd
queryByCode('Icd_Model').then(res => {
const id = res.data.id
@@ -2805,7 +2883,7 @@ const area = async () => {
queryCsDictTree(res.data.id).then(res => {
devTypeOptions.value = res.data
console.log("🚀 ~ area ~ devTypeOptions.value", devTypeOptions.value)
// console.log("🚀 ~ area ~ devTypeOptions.value", devTypeOptions.value)
})
})
})
@@ -2823,13 +2901,64 @@ const area = async () => {
userList.value = res.data.records
})
}
// 获取前置机
const getAffiliatiedFront = () => {
nodeAllList()
.then(res => {
affiliatiedFrontArr.value = res.data
})
.catch(error => {
console.error('获取前置机数据失败:', error)
})
}
const accessLoading = ref(false)
const MONITORING_REFRESH_KEY = 'monitoringNeedRefreshAffiliatiedAndImage'
const refreshAffiliatiedAndImage = () => {
getAffiliatiedFront()
getImageList()
}
const markNeedRefreshAfterNavigate = () => {
sessionStorage.setItem(MONITORING_REFRESH_KEY, '1')
}
const tryRefreshAfterNavigate = () => {
if (sessionStorage.getItem(MONITORING_REFRESH_KEY)) {
sessionStorage.removeItem(MONITORING_REFRESH_KEY)
refreshAffiliatiedAndImage()
return true
}
return false
}
// 接入
// 新增拓扑图
const addTopology = () => {
markNeedRefreshAfterNavigate()
push({
name: 'govern/manage/gplot'
})
}
// 新增前置机
const addAffiliatiedFront = () => {
markNeedRefreshAfterNavigate()
push({
name: 'govern/setting/frontManagement'
})
}
onMounted(() => {
nodeData.value.level = 0
if (tryRefreshAfterNavigate()) return
getImageList()
})
onActivated(() => {
tryRefreshAfterNavigate()
})
area()
</script>

View File

@@ -16,6 +16,9 @@ import { ref } from 'vue'
import Factory from '@/views/govern/manage/factory.vue'
import Monitor from './components/monitoring.vue'
import { mainHeight } from '@/utils/layout'
defineOptions({
name: 'govern/cloudDeviceEntry'
})
const activeName = ref('1')
const layout = mainHeight(80)
</script>

View File

@@ -22,26 +22,6 @@
:value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="治理类型" class="top">
<el-select v-model.trim="form.governType" filterable placeholder="请选择治理类型" clearable>
<el-option label="暂态" value="event"></el-option>
<el-option label="稳态" value="harmonic"></el-option>
</el-select>
</el-form-item>
<el-form-item label="敏感用户" class="top">
<div style="display: flex;">
<el-select v-model.trim="form.monitorUser" style="width: 230px;" filterable placeholder="请选择敏感用户"
clearable>
<el-option v-for="option in userList" :key="option.id" :label="option.name"
:value="option.id"></el-option>
</el-select>
<el-button type="primary" icon="el-icon-Plus" class="ml10" @click="addMonitorUser" />
</div>
</el-form-item>
<el-form-item label="治理方法" class="top">
<el-input maxlength="32" show-word-limit v-model="form.governMethod" autocomplete="off" clearable
placeholder="例: 250A APF 或 100kVar SVG"></el-input>
</el-form-item>
<el-form-item label="通讯协议" prop="devAccessMethod" class="top">
<el-select v-model.trim="form.devAccessMethod" placeholder="请选择通讯协议" clearable disabled>
<el-option label="MQTT" value="MQTT"></el-option>
@@ -75,9 +55,9 @@ import {
portableDeviceRegister,
} from '@/api/cs-system-boot/device'
import { useRouter } from 'vue-router'
const router = useRouter() // 路由对象
const router = useRouter()
const props = defineProps<{
userList: any[]
engineeringList: any[]
devTypeOptions: any[]
devTypeOptions2: any
@@ -154,9 +134,6 @@ function getDefaultForm() {
associatedProject: '',
association: [] as any[],
sort: 0,
monitorUser: '',
governType: '',
governMethod: '',
id: undefined as string | number | undefined,
}
}
@@ -177,9 +154,6 @@ const buildSubmitPayload = () => {
associatedEngineering: normalizeFormValue(association[0]),
associatedProject: normalizeFormValue(association[1]),
sort: form.sort ?? 0,
monitorUser: normalizeFormValue(form.monitorUser),
governType: normalizeFormValue(form.governType),
governMethod: normalizeFormValue(form.governMethod),
}
}
@@ -253,12 +227,6 @@ const resetForm = () => {
visible.value = false
}
const addMonitorUser = () => {
sessionStorage.setItem('factoryNeedRefreshUserList', '1')
router.push({
name: 'govern/sensitiveLoadMange/index',
})
}
const addProject = () => {
sessionStorage.setItem('factoryNeedRefreshEngineeringList', '1')
router.push({

View File

@@ -90,7 +90,7 @@
</TableHeader>
<Table ref="tableRef" :checkbox-config="checkboxConfig" :key="tableKey" @sort-change="handleSortChange"></Table>
<FactoryForm ref="factoryFormRef" :user-list="userList" :engineering-list="engineeringList"
<FactoryForm ref="factoryFormRef" :engineering-list="engineeringList"
:dev-type-options="devTypeOptions" :dev-type-options2="devTypeOptions2" :dev-model-options="devModelOptions"
:dev-model-options2="devModelOptions2" @success="onFormSuccess" />
@@ -131,12 +131,10 @@ import html2canvas from 'html2canvas'
import { fullUrl } from '@/utils/common'
import JSZip from 'jszip'
import { saveAs } from 'file-saver'
import { getList } from '@/api/cs-harmonic-boot/recruitment'
defineOptions({
name: 'govern/manage/factory'
})
const userList: any = ref([])
const showQrCode = ref(false)
const devTypeOptions: any = ref([])
const devTypeOptions2: any = ref([])
@@ -255,30 +253,6 @@ const tableStore = new TableStore({
},
minWidth: 120
},
{
title: '治理类型',
field: 'governType',
minWidth: 100,
formatter: row => {
return row.cellValue === 'event' ? '暂态' : row.cellValue === 'harmonic' ? '稳态' : (row.cellValue || '/')
}
},
{
title: '治理方法',
field: 'governMethod',
minWidth: 100,
formatter: row => {
return row.cellValue || '/'
}
},
{
title: '敏感用户',
field: 'monitorUser',
minWidth: 120,
formatter: row => {
return userList.value.find((item: any) => item.id == row.cellValue)?.name || '/'
}
},
{
title: '通讯协议',
field: 'devAccessMethod',
@@ -829,15 +803,6 @@ const onFormSuccess = () => {
tableStore.onTableAction('search', {})
}
const getUserList = () => {
return getList({
pageNum: 1,
pageSize: 2000
}).then(res => {
userList.value = res.data.records
})
}
const getEngineeringList = () => {
return engineeringProject().then(res => {
engineeringList.value = res.data.filter(item => {
@@ -849,26 +814,19 @@ const getEngineeringList = () => {
})
}
// 页面被 keep-alive 缓存后,从敏感用户/工程页返回时刷新下拉列表
// 页面被 keep-alive 缓存后,从工程页返回时刷新下拉列表
onActivated(() => {
// if (sessionStorage.getItem('factoryNeedRefreshUserList')) {
// sessionStorage.removeItem('factoryNeedRefreshUserList')
getUserList()
// }
// if (sessionStorage.getItem('factoryNeedRefreshEngineeringList')) {
// sessionStorage.removeItem('factoryNeedRefreshEngineeringList')
if (sessionStorage.getItem('factoryNeedRefreshEngineeringList')) {
sessionStorage.removeItem('factoryNeedRefreshEngineeringList')
getEngineeringList()
// }
}
})
provide('tableStore', tableStore)
onMounted(() => {
queryTheDictionary()
// getUserList()
// getEngineeringList()
getEngineeringList()
setTimeout(() => { }, 100)
})

View File

@@ -81,15 +81,15 @@ const tableStore = new TableStore({
// }
},
{
title: '设备型号',
field: 'devType',
width: 130,
formatter: row => {
return devModelOptions.value.filter((item: any) => item.value == row.cellValue)[0]?.label
}
},
{ title: 'Mac地址', field: 'mac', width: 140 },
// {
// title: '设备型号',
// field: 'devType',
// width: 130,
// formatter: row => {
// return devModelOptions.value.filter((item: any) => item.value == row.cellValue)[0]?.label
// }
// },
// { title: 'Mac地址', field: 'mac', width: 140 },
// {
// title: '流程阶段',
// field: 'process',

View File

@@ -0,0 +1,102 @@
<template>
<div class="dictiontary-list-detail child-router">
<TableHeader>
<template #select>
<el-form-item label="">
<span class="text-large font-600 mr-3" style="font-weight: 600;">{{ props.bingRow.name
}}_绑定测点</span>
</el-form-item>
</template>
<template #operation>
<el-button icon="el-icon-Plus" type="primary" @click="add">新增</el-button>
<el-button icon="el-icon-Back" @click="$emit('close')">返回</el-button>
</template>
</TableHeader>
<Table ref="tableRef" />
<BindForm ref="bindFormRef" :pid="props.bingRow.id" />
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, provide } from 'vue'
import TableHeader from '@/components/table/header/index.vue'
import TableStore from '@/utils/tableStore'
import Table from '@/components/table/index.vue'
import BindForm from './bindForm.vue'
import { ElMessage } from 'element-plus'
import { deleteGovernPlan } from '@/api/cs-device-boot/sensitiveLoadMange'
const props = defineProps<{
bingRow: anyObj
}>()
defineEmits(['close'])
const bindFormRef = ref<InstanceType<typeof BindForm>>()
const tableStore = new TableStore({
url: '/cs-harmonic-boot/pqGovernPlan/getListByPid',
method: 'GET',
column: [
{ title: '治理点名称', field: 'governName', width: 200 },
{
title: '治理类型',
field: 'governType',
width: 120,
formatter: row => {
return row.cellValue == 'harmonic' ? '稳态' : '暂态'
}
},
{ title: '治理方法', field: 'governMethod', width: 120 },
{ title: '治理前-监测点', field: 'ledgerBefore', minWidth: 200, formatter: row => row.cellValue || row.row?.governBefore || '/' },
{ title: '治理后-监测点', field: 'ledgerAfter', minWidth: 200, formatter: row => row.cellValue || row.row?.governAfter || '/' },
{ title: '排序', field: 'sort', width: '80' },
{
title: '操作',
fixed: 'right',
width: '180',
render: 'buttons',
buttons: [
{
title: '编辑',
type: 'primary',
icon: 'el-icon-EditPen',
render: 'basicButton',
click: row => {
bindFormRef.value?.open('编辑', row)
}
},
{
title: '删除',
type: 'danger',
icon: 'el-icon-Delete',
render: 'confirmButton',
popconfirm: {
confirmButtonText: '确认',
cancelButtonText: '取消',
confirmButtonType: 'danger',
title: '确定删除该方案吗?'
},
click: row => {
deleteGovernPlan([row.id]).then(() => {
ElMessage.success('删除成功')
tableStore.index()
})
}
}
]
}
]
})
const add = () => {
bindFormRef.value?.open('新增')
}
provide('tableStore', tableStore)
onMounted(() => {
tableStore.table.params.pid = props.bingRow.id
tableStore.index()
})
</script>

View File

@@ -0,0 +1,241 @@
<template>
<el-dialog class="cn-operate-dialog" draggable width="500px" v-model="dialogVisible" :title="title">
<el-form :model="form" class="form-one" label-width="auto" ref="formRef" :rules="rules">
<el-form-item label="治理点名称" prop="governName">
<el-input maxlength="32" show-word-limit clearable v-model.trim="form.governName"
placeholder="请输入治理点名称" />
</el-form-item>
<el-form-item label="治理类型" prop="governType">
<el-select v-model="form.governType" placeholder="请选择治理类型" style="width: 100%">
<el-option label="稳态" value="harmonic" />
<el-option label="暂态" value="transient" />
</el-select>
</el-form-item>
<el-form-item label="治理方法" prop="governMethod">
<el-input maxlength="32" show-word-limit clearable v-model="form.governMethod"
placeholder="例: 250A APF 或 100kVar SVG" />
</el-form-item>
<el-form-item label="治理前-监测点">
<el-tree-select v-model="form.governBefore" :data="lineTreeData" clearable :props="treeProps" filterable
:filter-node-method="filterNode" check-strictly default-expand-all placeholder="请选择监测点"
style="width: 100%">
<template #default="{ data }">
<span>{{ data.name }}{{ getBoundSuffix(data) }}</span>
</template>
</el-tree-select>
</el-form-item>
<el-form-item label="治理后-监测点">
<el-tree-select v-model="form.governAfter" :data="lineTreeData" clearable :props="treeProps" filterable
:filter-node-method="filterNode" check-strictly default-expand-all placeholder="请选择监测点"
style="width: 100%">
<template #default="{ data }">
<span>{{ data.name }}{{ getBoundSuffix(data) }}</span>
</template>
</el-tree-select>
</el-form-item>
<el-form-item label="排序" prop="sort">
<el-input-number style="width: 100%" :min="0" v-model.number="form.sort" placeholder="请输入排序" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="submit">确认</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import { ref, reactive, inject, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import TableStore from '@/utils/tableStore'
import { isLineTreeLeaf } from '@/components/tree/govern/lineTreeUtils'
import { createTreeFilterNode } from '@/components/tree/govern/treeFilterUtils'
import { getLineTree } from '@/api/cs-device-boot/csLedger'
import { saveGovernPlan, updateGovernPlan } from '@/api/cs-device-boot/sensitiveLoadMange'
const props = defineProps<{
pid: string | number
}>()
const tableStore = inject('tableStore') as TableStore
const formRef = ref()
const dialogVisible = ref(false)
const title = ref('新增')
const lineTreeData = ref<any[]>([])
const filterNode = createTreeFilterNode()
const treeProps = {
value: 'id',
label: 'name',
children: 'children',
disabled: 'disabled'
}
const form = reactive<any>({
id: null,
pid: null,
governName: '',
governMethod: '',
governType: '',
governBefore: '',
governAfter: '',
sort: 100
})
const isEmptyPoint = (val: any) => val === '' || val === null || val === undefined
const getGovernPointError = (): string => {
const beforeEmpty = isEmptyPoint(form.governBefore)
const afterEmpty = isEmptyPoint(form.governAfter)
if (beforeEmpty && afterEmpty) return ''
if (beforeEmpty) return '已选择治理后监测点,请同时选择治理前监测点'
if (afterEmpty) return '已选择治理前监测点,请同时选择治理后监测点'
if (form.governBefore === form.governAfter) return '治理前与治理后监测点不能相同'
return ''
}
const rules = {
governName: [{ required: true, message: '请输入治理点名称', trigger: 'blur' }],
governMethod: [{ required: true, message: '请输入治理方法', trigger: 'blur' }],
governType: [{ required: true, message: '请选择治理类型', trigger: 'change' }],
sort: [{ required: true, message: '请输入排序', trigger: 'blur' }]
}
const getBoundSuffix = (node: any) => {
if (node?.sensitiveUserName) {
return `(已绑_${node.sensitiveUserName}_${node.governPlanName || ''})`
}
return ''
}
const findTreeNodeById = (nodes: any[], id: any): any => {
for (const node of nodes) {
if (node.id === id) return node
if (node.children?.length) {
const found = findTreeNodeById(node.children, id)
if (found) return found
}
}
return null
}
/** 监测点是否已被其他方案绑定(编辑时排除当前方案) */
const isPointBoundConflict = (node: any) => {
if (!node?.sensitiveUserName) return false
if (form.id && (node.governPlanId === form.id || node.governPlanName === form.governName)) {
return false
}
return true
}
const getBoundPointError = (): string => {
const messages: string[] = []
if (!isEmptyPoint(form.governBefore)) {
const node = findTreeNodeById(lineTreeData.value, form.governBefore)
if (node && isPointBoundConflict(node)) {
messages.push(`治理前监测点「${node.name}${getBoundSuffix(node)}`)
}
}
if (!isEmptyPoint(form.governAfter)) {
const node = findTreeNodeById(lineTreeData.value, form.governAfter)
if (node && isPointBoundConflict(node)) {
messages.push(`治理后监测点「${node.name}${getBoundSuffix(node)}`)
}
}
return messages.length ? `${messages.join('')},请选择未绑定的监测点` : ''
}
const markNonLeafDisabled = (nodes: any[] = []) => {
nodes.forEach(node => {
node.disabled = !isLineTreeLeaf(node)
if (node.children?.length) {
markNonLeafDisabled(node.children)
}
})
}
const loadLineTree = () => {
getLineTree({ type: 'engineering' }).then(res => {
const data = JSON.parse(JSON.stringify(res.data || []))
markNonLeafDisabled(data)
lineTreeData.value = data
})
}
const resetForm = () => {
form.id = null
form.pid = props.pid
form.governName = ''
form.governMethod = ''
form.governType = ''
form.governBefore = ''
form.governAfter = ''
form.sort = 100
}
const open = (text: string, data?: anyObj) => {
loadLineTree()
formRef.value?.resetFields()
title.value = text
dialogVisible.value = true
resetForm()
if (data) {
form.id = data.id
form.governName = data.governName ?? ''
form.governMethod = data.governMethod ?? ''
form.governType = data.governType ?? ''
form.governBefore = data.governBeforeId ?? data.governBefore ?? ''
form.governAfter = data.governAfterId ?? data.governAfter ?? ''
form.sort = data.sort ?? 100
}
}
const submit = () => {
const pointError = getGovernPointError()
if (pointError) {
ElMessage.warning(pointError)
return
}
const boundError = getBoundPointError()
if (boundError) {
ElMessage.warning(boundError)
return
}
formRef.value.validate(async (valid: boolean) => {
if (!valid) return
const payload = {
id: form.id,
pid: props.pid,
governName: form.governName,
governMethod: form.governMethod,
governType: form.governType,
governBefore: form.governBefore,
governAfter: form.governAfter,
sort: form.sort
}
if (form.id) {
await updateGovernPlan(payload)
} else {
await saveGovernPlan(payload)
}
ElMessage.success('操作成功')
tableStore.index()
dialogVisible.value = false
})
}
onMounted(() => {
})
defineExpose({ open })
</script>

View File

@@ -1,14 +1,12 @@
<template>
<el-dialog class="cn-operate-dialog" width="500px" v-model.trim="dialogVisible" :title="title">
<el-dialog class="cn-operate-dialog" draggable width="500px" v-model.trim="dialogVisible" :title="title">
<el-form :model="form" class="form-one" label-width="auto" ref="formRef" :rules="rules">
<el-form-item label="所属厂站名称" prop="substationName">
<el-input maxlength="32" show-word-limit v-model.trim="form.substationName" placeholder="请输入所属厂站名称"></el-input>
</el-form-item>
<el-form-item label="用户名称" prop="name">
<el-input maxlength="32" show-word-limit v-model.trim="form.name" placeholder="请输入用户名称"></el-input>
</el-form-item>
<el-form-item label="敏感负荷类型" prop="loadType">
<el-select v-model.trim="form.loadType" filterable clearable placeholder="请选择敏感负荷类型">
<el-form-item label="用户类型" prop="loadType">
<el-select v-model.trim="form.loadType" filterable clearable placeholder="请选择用户类型">
<el-option
v-for="item in DataTypeSelect"
:key="item.id"
@@ -17,6 +15,9 @@
></el-option>
</el-select>
</el-form-item>
<el-form-item label="所属厂站名称" prop="substationName">
<el-input maxlength="32" show-word-limit v-model.trim="form.substationName" placeholder="请输入所属厂站名称"></el-input>
</el-form-item>
<el-form-item label="用户协议容量(MVA)" prop="userAgreementCapacity">
<el-input-number style="width: 100%;" :min="0" v-model.number="form.userAgreementCapacity" placeholder="请输入用户协议容量"></el-input-number>
</el-form-item>
@@ -65,7 +66,7 @@ const form = reactive<any>({
const rules = {
substationName: [{ required: true, message: '请输入所属厂站名称', trigger: 'blur' }],
name: [{ required: true, message: '请输入用户名称', trigger: 'blur' }],
loadType: [{ required: true, message: '请输入请选择敏感负荷类型', trigger: 'blur' }],
loadType: [{ required: true, message: '请输入请选择用户类型', trigger: 'blur' }],
installedCapacity: [{ required: true, message: '请输入用户协议容量', trigger: 'blur' }],
userAgreementCapacity: [{ required: true, message: '请输入装机容量', trigger: 'blur' }],
sort: [{ required: true, message: '请输入排序', trigger: 'blur' }]

View File

@@ -1,16 +1,10 @@
<template>
<div class="default-main">
<div class="default-main" style="position: relative">
<TableHeader :showReset="false" showExport>
<template #select>
<el-form-item label="关键字筛选">
<el-input maxlength="32" show-word-limit
style="width: 240px"
v-model.trim="tableStore.table.params.searchValue"
clearable
placeholder="请输入用户名称"
/>
<el-input maxlength="32" show-word-limit style="width: 240px"
v-model.trim="tableStore.table.params.searchValue" clearable placeholder="请输入用户名称" />
</el-form-item>
</template>
<template #operation>
@@ -19,6 +13,7 @@
</TableHeader>
<Table ref="tableRef" />
<detail ref="detail"></detail>
<Bind ref="BindRef" :bingRow="bingRow" @close="bingRow = null" v-if="bingRow"></Bind>
</div>
</template>
<script setup lang="ts">
@@ -31,12 +26,14 @@ import { ElMessage } from 'element-plus'
import { deleteUser } from '@/api/cs-device-boot/sensitiveLoadMange'
import { Plus } from '@element-plus/icons-vue'
import { useDictData } from '@/stores/dictData'
import Bind from './component/bind.vue'
defineOptions({
name: 'govern/sensitiveLoadMange/index'
})
const detail = ref()
const BindRef = ref()
const bingRow = ref<anyObj | null>(null)
const dictData = useDictData()
const interferenceType = dictData.getBasicData('Interference_Source')
@@ -53,7 +50,7 @@ const tableStore: any = new TableStore({
},
{ title: '用户名称', field: 'name', minWidth: 180 },
{
title: '敏感用户类型',
title: '用户类型',
field: 'loadType',
minWidth: 120,
formatter: row => {
@@ -61,16 +58,27 @@ const tableStore: any = new TableStore({
}
},
{ title: '所属厂站名称', field: 'substationName', minWidth: 180 },
{ title: '用户协议容量(MVA)', field: 'userAgreementCapacity', minWidth: 100 },
{ title: '装机容量(MW)', field: 'installedCapacity', minWidth: 100 },
{
title: '操作', fixed: 'right',
align: 'center',
width: '180',
render: 'buttons',
buttons: [
{
name: 'edit',
title: '绑定测点',
type: 'primary',
icon: 'el-icon-EditPen',
render: 'basicButton',
click: row => {
bingRow.value = row
}
},
{
name: 'edit',
title: '编辑',
@@ -103,7 +111,7 @@ const tableStore: any = new TableStore({
]
}
],
loadCallback: () => {}
loadCallback: () => { }
})
tableStore.table.params.searchValue = ''

View File

@@ -5,27 +5,15 @@
<TableHeader>
<template v-slot:select>
<el-form-item label="前置等级">
<el-select
v-model="tableStore.table.params.nodeGrade"
clearable
placeholder="请选择前置等级"
>
<el-option
v-for="item in fontdveoption"
:key="item.id"
:label="item.name"
:value="item.id"
/>
<el-select v-model="tableStore.table.params.nodeGrade" clearable placeholder="请选择前置等级">
<el-option v-for="item in fontdveoption" :key="item.id" :label="item.name"
:value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="状态">
<el-select v-model="tableStore.table.params.searchState" clearable placeholder="请选择状态">
<el-option
v-for="item in statusoption"
:key="item.id"
:label="item.name"
:value="item.id"
/>
<el-option v-for="item in statusoption" :key="item.id" :label="item.name"
:value="item.id" />
</el-select>
</el-form-item>
</template>
@@ -33,28 +21,18 @@
<el-button type="primary" class="ml10" @click="add" icon="el-icon-Plus">新增</el-button>
</template>
</TableHeader>
<Table
ref="tableRef"
:row-config="{ isCurrent: true, isHover: true }"
@current-change="currentChangeEvent"
></Table>
<Table ref="tableRef" :row-config="{ isCurrent: true, isHover: true }"
@current-change="currentChangeEvent"></Table>
</div>
<div class="pd10" style="width: 300px" v-loading="loading">
<el-input maxlength="32" show-word-limit v-model="filterText" placeholder="请输入内容" clearable @input="change">
<el-input maxlength="32" show-word-limit v-model="filterText" placeholder="请输入内容" clearable
@input="change">
<template #prefix>
<Icon name="el-icon-Search" style="font-size: 16px" />
</template>
</el-input>
<el-tree
:style="height"
style="overflow-y: auto"
:data="dataSource"
node-key="id"
ref="treeRef"
default-expand-all
:props="defaultProps"
:filter-node-method="filterNode"
>
<el-tree :style="height" style="overflow-y: auto" class="mt10 elTree" :data="dataSource" node-key="id"
ref="treeRef" default-expand-all :props="defaultProps" :filter-node-method="filterNode">
<template #default="{ node, data }">
<div class="custom-tree-node">
<span>
@@ -62,34 +40,21 @@
{{ node.label }}
</span>
<span v-else>{{ data.name }}</span>
<span
v-if="data.processState != null"
class="iconSpan"
:style="{ background: data.processState == 0 ? '#ff0000' : '#00b07d' }"
></span>
<span v-if="data.processState != null" class="iconSpan"
:style="{ background: data.processState == 0 ? '#ff0000' : '#00b07d' }"></span>
</span>
<div>
<template v-if="data.id">
<el-tooltip content="编辑" placement="left">
<el-button
style="margin-left: 4px"
icon="el-icon-Edit"
type="primary"
@click="edit(data)"
link
></el-button>
<el-button style="margin-left: 4px" icon="el-icon-Edit" type="primary"
@click="edit(data)" link></el-button>
</el-tooltip>
</template>
<template v-else>
<el-popconfirm title="确定重启吗?" placement="left" @confirm="restart(data)">
<template #reference>
<el-button
style="margin-left: 4px"
icon="el-icon-Refresh"
type="warning"
link
@click.stop
/>
<el-button style="margin-left: 4px" icon="el-icon-Refresh" type="warning"
link @click.stop />
</template>
<template #actions="{ confirm, cancel }">
<el-button size="small" @click="cancel">取消</el-button>
@@ -104,52 +69,30 @@
</div>
</div>
<el-dialog
draggable
:title="dialogTitle"
v-model="dialogFormVisible"
:close-on-click-modal="false"
width="500px"
:before-close="resetForm"
>
<el-dialog draggable :title="dialogTitle" v-model="dialogFormVisible" :close-on-click-modal="false"
width="500px" :before-close="resetForm">
<el-form :model="formData" label-width="120px" :rules="rules" ref="ruleFormRef" class="form-one">
<el-form-item label="名称:" prop="name">
<el-input maxlength="32" show-word-limit
v-model="formData.name"
placeholder="请输入名称"
@input="handleInput"
></el-input>
<el-form-item label="前置机名称:" prop="name">
<el-input maxlength="32" show-word-limit v-model="formData.name" placeholder="请输入前置机名称"
@input="handleInput"></el-input>
</el-form-item>
<el-form-item label="IP:" prop="ip" class="top">
<el-input maxlength="32" show-word-limit v-model="formData.ip" placeholder="请输入Ip"></el-input>
<el-input maxlength="32" show-word-limit v-model="formData.ip" placeholder="请输入Ip"></el-input>
</el-form-item>
<el-form-item label="等级:" prop="nodeGrade" class="top">
<el-select v-model="formData.nodeGrade" placeholder="请选择等级" style="width: 100%">
<el-option
v-for="item in fontdveoption"
:key="item.id"
:label="item.name"
:value="item.id"
></el-option>
<el-option v-for="item in fontdveoption" :key="item.id" :label="item.name"
:value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item label="最大终端数:" prop="nodeDevNum" class="top">
<el-input show-word-limit
v-model="formData.nodeDevNum"
onkeyup="value = value.replace(/[^0-9]/g,'')"
maxlength="5"
placeholder="请输入最大终端数"
></el-input>
<el-input show-word-limit v-model="formData.nodeDevNum"
onkeyup="value = value.replace(/[^0-9]/g,'')" maxlength="5" placeholder="请输入最大终端数"></el-input>
</el-form-item>
<el-form-item label="最大进程数:" prop="maxProcessNum" class="top">
<el-input show-word-limit
v-model="formData.maxProcessNum"
onkeyup="value = value.replace(/[^0-9]/g,'')"
maxlength="5"
placeholder="请根据监测点规模填写合适进程数1个进程最大可承载200个监测点"
></el-input>
<el-input show-word-limit v-model="formData.maxProcessNum"
onkeyup="value = value.replace(/[^0-9]/g,'')" maxlength="5"
placeholder="请根据监测点规模填写合适进程数1个进程最大可承载200个监测点"></el-input>
<!-- <el-select v-model="formData.maxProcessNum" placeholder="请选择等级" style="width: 100%">
<el-option
v-for="item in NumList"
@@ -160,15 +103,12 @@
</el-select> -->
</el-form-item>
<el-form-item label="排序:" prop="sort" class="top">
<el-input maxlength="32" show-word-limit v-model="formData.sort" placeholder="请输入排序"></el-input>
<!-- <el-input maxlength="32" show-word-limit v-model="formData.sort" placeholder="请输入排序"></el-input> -->
<el-input-number style="width: 100%" :min="0" v-model.number="formData.sort" placeholder="请输入排序" />
</el-form-item>
<el-form-item label="描述:" prop="remark" class="top">
<el-input maxlength="300" show-word-limit
v-model="formData.remark"
:autosize="{ minRows: 2, maxRows: 4 }"
type="textarea"
placeholder="请输入描述"
></el-input>
<el-input maxlength="300" show-word-limit v-model="formData.remark"
:autosize="{ minRows: 2, maxRows: 4 }" type="textarea" placeholder="请输入描述"></el-input>
</el-form-item>
</el-form>
<template #footer>
@@ -178,38 +118,21 @@
</el-dialog>
<!-- 绑定进程号 -->
<el-dialog draggable title="绑定进程号" v-model="popUps" :close-on-click-modal="false" width="400px" >
<el-form :model="bindProcessForm" ref="bindProcessFormRef" label-width="80px" :rules="rules2" class="form-one">
<el-dialog draggable title="绑定进程号" v-model="popUps" :close-on-click-modal="false" width="400px">
<el-form :model="bindProcessForm" ref="bindProcessFormRef" label-width="80px" :rules="rules2"
class="form-one">
<el-form-item label="前置机" prop="nodeId">
<el-select
v-model="bindProcessForm.nodeId"
placeholder="请选择前置机"
style="width: 100%"
clearable
@change="handleNodeChange"
>
<el-option
v-for="item in tableStore.table.data"
:key="item.id"
:label="item.name"
:value="item.id"
></el-option>
<el-select v-model="bindProcessForm.nodeId" placeholder="请选择前置机" style="width: 100%" clearable
@change="handleNodeChange">
<el-option v-for="item in tableStore.table.data" :key="item.id" :label="item.name"
:value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item label="进程号" prop="processNo">
<el-select
v-model="bindProcessForm.processNo"
placeholder="请选择进程号"
style="width: 100%"
clearable
>
<el-option
v-for="item in processOptions"
:key="item.name"
:label="item.name"
:value="item.name"
></el-option>
<el-select v-model="bindProcessForm.processNo" placeholder="请选择进程号" style="width: 100%" clearable>
<el-option v-for="item in processOptions" :key="item.name" :label="item.name"
:value="item.name"></el-option>
</el-select>
</el-form-item>
</el-form>
@@ -251,7 +174,7 @@ const statusoption: any = ref([
{ id: 0, name: '未启用' },
{ id: 1, name: '启用' }
])
const height = mainHeight(70)
const height = mainHeight(80)
const loading = ref(false)
const popUps = ref(false)
const tableRef = ref()
@@ -280,7 +203,7 @@ const formData: any = ref({
maxProcessNum: ''
})
const rules = reactive({
name: [{ required: true, message: '名称不可为空', trigger: 'blur' }],
name: [{ required: true, message: '前置机名称不可为空', trigger: 'blur' }],
ip: [{ required: true, message: 'ip不可为空', trigger: 'blur' }],
nodeGrade: [{ required: true, message: '等级不可为空', trigger: 'blur' }],
nodeDevNum: [{ required: true, message: '最大终端数不可为空', trigger: 'blur' }],
@@ -309,8 +232,21 @@ const tableStore = new TableStore({
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
}
},
{ title: '名称', field: 'name', minWidth: '110' },
{ title: '前置机名称', field: 'name', minWidth: '110' },
{ title: 'IP', field: 'ip', minWidth: '110' },
{
title: '最大监测点数量',
field: 'nodeDevNum',
minWidth: '80',
},
{
title: '最大进程数',
field: 'maxProcessNum',
minWidth: '80',
},
{ title: '描述', field: 'remark', minWidth: '200', },
{
title: '等级',
field: 'nodeGrade',
@@ -327,21 +263,6 @@ const tableStore = new TableStore({
2: '备用'
}
},
{
title: '最大监测点数量',
field: 'nodeDevNum',
minWidth: '80',
},
{
title: '最大进程数',
field: 'maxProcessNum',
minWidth: '80',
},
{
title: '排序',
field: 'sort',
minWidth: '80'
},
{
title: '状态',
field: 'state',
@@ -356,7 +277,11 @@ const tableStore = new TableStore({
1: '启用'
}
},
{ title: '描述', field: 'remark', minWidth: '200', },
{
title: '排序',
field: 'sort',
minWidth: '80'
},
{
title: '操作',
fixed: 'right',
@@ -640,9 +565,11 @@ onMounted(() => {
height: 140px;
}
}
.default {
display: flex;
}
.custom-tree-node {
flex: 1;
display: flex;
@@ -652,6 +579,7 @@ onMounted(() => {
padding-right: 8px;
width: 300px;
}
.iconSpan {
display: inline-block;
width: 8px;
@@ -660,4 +588,8 @@ onMounted(() => {
border-radius: 50%;
margin-bottom: 2px;
}
.elTree {
border: 1px solid var(--el-border-color);
}
</style>

View File

@@ -3,19 +3,22 @@
<TableHeader>
<template #select>
<el-form-item label="">
<el-page-header @back="$emit('close')">
<template #content>
<span class="text-large font-600 mr-3">{{ props.detail.name }}详情信息</span>
</template>
</el-page-header>
<!-- <el-page-header @back="$emit('close')">
<template #content> -->
<span class="text-large font-600 mr-3" style="font-weight: 600;">{{ props.detail.name }}详情信息</span>
<!-- </template>
</el-page-header> -->
</el-form-item>
<el-form-item label="关键字筛选">
<el-input maxlength="32" show-word-limit style="width: 240px"
v-model.trim="tableStore.table.params.searchValue" clearable placeholder="请输入名称或编码筛选" />
</el-form-item>
</template>
<template #operation>
<el-button :icon="Plus" type="primary" @click="add">新增</el-button>
<el-button icon="el-icon-Back" @click="$emit('close')">返回</el-button>
</template>
</TableHeader>
<Table ref="tableRef" />
@@ -52,11 +55,11 @@ const tableStore = new TableStore({
column: [
{ title: '名称', field: 'name' },
{ title: '编码', field: 'code' },
{ title: '计算值', field: 'value' },
{ title: '事件等级', field: 'levelName' },
{ title: '算法描述', field: 'algoDescribe' },
{
title: '状态',
field: 'state',

View File

@@ -73,9 +73,9 @@ const tableStore = new TableStore({
type: 'primary',
icon: 'el-icon-ZoomIn',
render: 'basicButton',
click: row => {
detail.value = row
}
click: row => {
detail.value = row
}
},
{
title: '编辑',

View File

@@ -20,12 +20,13 @@
></el-input>
</el-form-item>
<el-form-item label="排序:" prop="sort" class="top">
<el-input maxlength="32" show-word-limit
<el-input-number style="width: 100%" :min="0" v-model.number="form.sort" placeholder="请输入排序" />
<!-- <el-input maxlength="32" show-word-limit
v-model.number="form.sort"
placeholder="请输入排序"
></el-input>
></el-input> -->
</el-form-item>
<el-form-item label="描述:" class="top">
<el-input maxlength="300" show-word-limit

View File

@@ -15,8 +15,8 @@
<el-input maxlength="32" show-word-limit v-model.trim="form.cron" clearable placeholder="请输入任务表达式" />
</el-form-item>
<el-form-item label="排序" prop="sort">
<el-input maxlength="32" show-word-limit style="width: 100%" v-model.number.trim="form.sort" placeholder="请输入排序" />
<el-input-number style="width: 100%" :min="0" v-model.number="form.sort" placeholder="请输入排序" />
<!-- <el-input maxlength="32" show-word-limit style="width: 100%" v-model.number.trim="form.sort" placeholder="请输入排序" /> -->
</el-form-item>
<el-form-item label="备注">
<el-input maxlength="300" show-word-limit v-model.trim="form.remark" clearable :rows="2" type="textarea" placeholder="请输入备注" />