1.被检设备监测点新增是否参与检测

2.调整通道配对只显示绑定和参与检测的通道数
This commit is contained in:
sjl
2025-09-17 14:08:58 +08:00
parent 95c68942ed
commit c88128b63b
8 changed files with 174 additions and 54 deletions

View File

@@ -26,6 +26,7 @@ export namespace Monitor {
connection: string; //接线方式,字典表
statInterval: number; //统计间隔
harmSysId: string; //默认与谐波系统监测点ID相同
checkFlag: number;//是否参与检测0否1是
}
/**

View File

@@ -39,7 +39,7 @@
</template>
<script lang="ts" setup>
import { h, ref, onMounted } from 'vue'
import { h, ref, onMounted, PropType } from 'vue'
import { VueFlow, useVueFlow } from '@vue-flow/core'
import { dialogBig } from '@/utils/elementBind'
import { Platform, Flag } from '@element-plus/icons-vue'
@@ -68,6 +68,10 @@ const prop = defineProps({
planIdKey: {
type: String,
default: ''
},
deviceMonitor: {
type: Map as PropType<Map<string, any[]>>,
default: () => new Map()
}
})
// 计算对话框高度
@@ -222,7 +226,7 @@ const open = async () => {
devIds.value = prop.devIdList.map(d => d.id)
standardDevIds.value = prop.pqStandardDevList.map(d => d.id)
planId.value = prop.planIdKey
nodes.value = createNodes(prop.devIdList, prop.pqStandardDevList)
nodes.value = createNodes(prop.devIdList, prop.pqStandardDevList,prop.deviceMonitor)
dialogVisible.value = true
onPaneReady()
}
@@ -258,6 +262,8 @@ const handleNext = async () => {
{} as Record<string, string>
)
await generateChannelMapping()
console.log('通道映射:', channelMapping.value)
return
await checkStore.setChnNum(chnNumList)
return {
title: dialogTitle.value,
@@ -346,7 +352,7 @@ const generateChannelMapping = () => {
channelMapping.value = mapping
}
const createNodes = (device: Device.ResPqDev[], standardDev: StandardDevice.ResPqStandardDevice[]) => {
const createNodes = (device: Device.ResPqDev[], standardDev: StandardDevice.ResPqStandardDevice[], deviceMonitor: Map<string, any[]>) => {
const channelCounts: Record<string, number> = {}
device.forEach(device => {
channelCounts[device.id] = device.devChns || 0
@@ -381,83 +387,140 @@ const createNodes = (device: Device.ResPqDev[], standardDev: StandardDevice.ResP
const outputChannelX = 1050
const standardWidth = 1170
const yPosition = (vueFlowElement.value - Object.keys(channelCounts).length * 50) / 2
const yPosition2 = (vueFlowElement.value - Object.keys(channelCounts2).length * 50) / 2
// const yPosition = ref(75)
// const yPosition2 = ref(75)
// 添加被检通道
let currentYPosition = 50; // 初始Y位置
const deviceSpacing = 30; // 设备间的垂直间距
Object.entries(channelCounts).forEach(([deviceId, count]) => {
const yPosition = (vueFlowElement.value - count * 52) / 2
for (let i = 1; i <= count; i++) {
const channelId = `被检通道-${deviceId}-${i}`
// 从deviceMonitor中获取实际通道信息
let actualChannels = []; // 存储实际的通道号
// 如果deviceMonitor中有该设备的数据则使用实际监测点信息
if (deviceMonitor.has(deviceId)) {
const monitorPoints = deviceMonitor.get(deviceId) || [];
// 提取监测点的num值作为通道号
actualChannels = monitorPoints.map(point => point.num);
//console.log('deviceId', deviceId, '实际通道号:', actualChannels, '监测点:', monitorPoints);
} else {
// 如果没有monitor数据默认使用连续的通道号
actualChannels = Array.from({length: count}, (_, i) => i + 1);
}
const yPosition = currentYPosition;
// 遍历实际通道号而不是连续的数字
actualChannels.forEach((channelNum, index) => {
const channelId = `被检通道-${deviceId}-${channelNum}`;
newNodes.push({
id: channelId,
type: 'input',
data: { label: createLabel3(`被检通道${i}`) },
position: { x: inputChannelX, y: yPosition + (i - 1) * 50 },
// position: { x: inputChannelX, y: yPosition.value },
data: { label: createLabel3(`被检通道${channelNum}`) },
position: { x: inputChannelX, y: yPosition + index * 50 },
sourcePosition: 'right',
style: { width: '120px', border: 'none', boxShadow: 'none' }
})
});
deviceChannelGroups.push({
deviceId,
centerY: 0
})
}
})
});
});
// 更新currentYPosition为下一台设备留出空间
// 每台设备需要的空间 = 实际通道数 * 50 + 设备间距
currentYPosition += actualChannels.length * 50 + deviceSpacing;
});
// 添加标准通道
let currentYPosition2 = 50; // 初始Y位置
const standardDeviceSpacing = 30; // 标准设备间的垂直间距
Object.entries(channelCounts2).forEach(([deviceId, count]) => {
const yPosition2 = (vueFlowElement.value - count * 52) / 2
const yPosition2 = currentYPosition2;
for (let i = 1; i <= count; i++) {
const channelId = `标准通道-${deviceId}-${i}`
const channelId = `标准通道-${deviceId}-${i}`;
newNodes.push({
id: channelId,
type: 'output',
data: { label: createLabel3(`标准通道${i}`) },
// position: { x: outputChannelX, y: yPosition2.value },
position: { x: outputChannelX, y: yPosition2 + (i - 1) * 50 },
targetPosition: 'left',
style: { width: '120px', border: 'none', boxShadow: 'none' }
})
});
standardChannelGroups.push({
deviceId,
centerY: 0 //yPosition2.value - 25
})
centerY: 0
});
}
})
// 更新currentYPosition2为下一台标准设备留出空间
currentYPosition2 += count * 50 + standardDeviceSpacing;
});
// 添加被检设备
let deviceCurrentYPosition = 50; // 与通道计算保持一致的初始位置
let lastDeviceId = ''; // 记录上一个处理的设备ID
deviceChannelGroups.forEach(({ deviceId, centerY }) => {
const device = inspectionDevices.find(d => d.id === deviceId)
if (device) {
// 只有当设备ID变化时才计算新位置
if (lastDeviceId !== deviceId) {
// 计算该设备对应的实际通道数量
let actualChannelCount = channelCounts[deviceId] || 0;
// 如果deviceMonitor中有该设备的数据则使用实际监测点数量
if (deviceMonitor.has(deviceId)) {
const monitorPoints = deviceMonitor.get(deviceId) || [];
actualChannelCount = monitorPoints.length;
}
// 计算设备高度居中位置 - 基于该设备组的实际位置
const deviceCenterY = deviceCurrentYPosition + (actualChannelCount * 50) / 2 - 50
console.log('deviceCenterY', deviceId, deviceCenterY)
newNodes.push({
id: device.id,
data: { label: createLabel(device.name, device.deviceType, 1) },
// position: { x: deviceWidth, y: centerY },
position: { x: deviceWidth, y: (vueFlowElement.value - 112) / 2 },
position: { x: deviceWidth, y: deviceCenterY },
class: 'no-handle-node',
style: { width: '300px', border: 'none', boxShadow: 'none' }
})
// 更新位置为下一台设备的起始位置
deviceCurrentYPosition += actualChannelCount * 50 + 30
// 更新上一个设备ID
lastDeviceId = deviceId
}
}
})
// 添加标准设备
let standardDeviceCurrentYPosition = 50; // 与标准通道计算保持一致的初始位置
let lastStandardDeviceId = ''; // 记录上一个处理的标准设备ID
standardChannelGroups.forEach(({ deviceId, centerY }) => {
const device = standardDevices.find(d => d.id === deviceId)
if (device) {
// 只有当设备ID变化时才计算新位置
if (lastStandardDeviceId !== deviceId) {
// 计算该标准设备对应的通道数量
const channelCount = channelCounts2[deviceId] || 0
// 计算设备高度居中位置 - 基于该设备组的实际位置
const deviceCenterY = standardDeviceCurrentYPosition + (channelCount * 50) / 2 - 50
newNodes.push({
id: device.id,
data: { label: createLabel(device.name, device.deviceType, 2) },
position: { x: standardWidth, y: (vueFlowElement.value - 112) / 2 },
// position: { x: standardWidth, y: centerY + 25 },
position: { x: standardWidth, y: deviceCenterY },
class: 'no-handle-node',
style: { width: '300px', border: 'none', boxShadow: 'none' }
})
// 更新位置为下一台标准设备的起始位置
standardDeviceCurrentYPosition += channelCount * 50 + 30
// 更新上一个标准设备ID
lastStandardDeviceId = deviceId
}
}
})

View File

@@ -757,7 +757,6 @@ const initializeParameters = async () => {
onMounted(() => {
if (!checkStore.selectTestItems.preTest) {
console.log(222222)
// 判断是否预检测
initializeParameters()
}

View File

@@ -45,6 +45,7 @@
:devIdList="prop.devIdList"
:pqStandardDevList="prop.pqStandardDevList"
:planIdKey="prop.planIdKey"
:deviceMonitor="deviceMonitor2"
/>
</keep-alive>
<keep-alive>
@@ -132,7 +133,7 @@
</template>
<script lang="tsx" setup name="testPopup">
import { nextTick, reactive, ref, watch } from 'vue'
import { nextTick, PropType, reactive, ref, watch } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
Coin,
@@ -240,6 +241,7 @@ const standardDevIds = ref<[]>()
const pairs = ref<any>()
const testAgain = ref(false) //重新检测按钮是否显示
const checkNumber = ref(0) //检测次数
const deviceMonitor2= ref<Map<string, any[]>>();
const open = async (
title: string,
mapping: any,
@@ -247,11 +249,14 @@ const open = async (
login: string,
devIdsArray: [],
standardDevIdsArray: [],
pair: any
pair: any,
deviceMonitor:Map<string, any[]>
) => {
if (checkStore.selectTestItems.preTest && !checkStore.selectTestItems.test) {
testAgain.value = true
}
deviceMonitor2.value = deviceMonitor;
console.log('deviceMonitor:',deviceMonitor2.value)
checkStore.setNodesConnectable(true)
dialogTitle.value = title
channelMapping.value = mapping

View File

@@ -68,6 +68,7 @@ const dialogVisible = ref(false)
const selectTestItemPopupRef = ref<InstanceType<typeof SelectTestItemPopup>>()
const testPopup = ref()
const dialogTitle = ref('手动检测')
// 计算对话框高度
const dialogHeight = ref(600)
const CompareTestVisible = ref(false)
@@ -201,16 +202,20 @@ const standardDevIds = ref<string[]>()
const devIdList = ref<Device.ResPqDev[]>([])
const pqStandardDevList = ref<StandardDevice.ResPqStandardDevice[]>([])
const planIdKey = ref<string>('')
const deviceMonitor = ref<Map<string, any[]>>();
const open = async (
device: Device.ResPqDev[],
standardDev: StandardDevice.ResPqStandardDevice[],
fatherPlanId: string
fatherPlanId: string,
DeviceMonitoringMap: Map<string, any[]>
) => {
CompareTestVisible.value = false
selectTestItemPopupRef.value?.open()
devIdList.value = device
pqStandardDevList.value = standardDev
planIdKey.value = fatherPlanId
deviceMonitor.value = DeviceMonitoringMap
// edges.value = []
// devIds.value = device.map(d => d.id)
@@ -277,7 +282,8 @@ const openTestDialog = async () => {
jwtUtil.getLoginName(),
devIds.value,
standardDevIds.value,
connections
connections,
deviceMonitor.value
)
}, 100)
}

View File

@@ -697,6 +697,7 @@ function refreshStatusList() {
* 校验选中设备的一致性,然后打开通道配对弹窗
*/
const handleTest2 = async () => {
// 检查是否选择了设备
if (devNum == 0) {
ElMessageBox.confirm('请先选择被检设备', '提示', {
@@ -747,7 +748,6 @@ const handleTest2 = async () => {
}
const devBindMonList = await getPqMonList({ devIds: channelsSelection.value.map(d => d.id) })
// 创建一个映射来存储每个设备的监测点信息(支持多个监测点)
const deviceMonitoringMap = new Map<string, any[]>()
devBindMonList.data.forEach((item: any) => {
@@ -760,6 +760,33 @@ const handleTest2 = async () => {
}
})
// 收集所有监测点都未参与检测的设备
const allUncheckedDevices: string[] = [];
// 创建新对象存储过滤掉checkFlag === 0的监测点
const filteredDeviceMonitoringMap = new Map<string, any[]>();
deviceMonitoringMap.forEach((monitoringPoints, deviceId) => {
// 检查是否所有监测点的 checkFlag 都为 0
const allUnchecked = monitoringPoints.every(point => point.checkFlag === 0);
if (allUnchecked) {
// 根据deviceId找到设备名称
const device = channelsSelection.value.find(d => d.id === deviceId);
if (device) {
allUncheckedDevices.push(device.name);
}
}else {
// 过滤掉checkFlag === 0的监测点只保留参与检测的监测点
const filteredPoints = monitoringPoints.filter(point => point.checkFlag !== 0);
filteredDeviceMonitoringMap.set(deviceId, filteredPoints);
}
});
// 统一提示所有所有监测点都未参与检测的设备
if (allUncheckedDevices.length > 0) {
ElMessage.warning(`以下设备的所有监测点都不参与检测,请重新选择: ${allUncheckedDevices.join(', ')}`);
return
}
// 过滤出至少有一个监测点的设备
const filteredChannelsSelection = channelsSelection.value.filter(device => {
return deviceMonitoringMap.has(device.id)
@@ -767,6 +794,7 @@ const handleTest2 = async () => {
// 如果没有设备有监测点,则提示并返回
if (filteredChannelsSelection.length === 0) {
ElMessageBox.confirm('所选设备均无监测点,请检查设备配置', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
@@ -800,7 +828,8 @@ const handleTest2 = async () => {
}
// 只传递有监测点的设备
deviceConnectionPopupRef.value?.open(filteredChannelsSelection, pqStandardDevList.value, props.id)
deviceConnectionPopupRef.value?.open(filteredChannelsSelection, pqStandardDevList.value, props.id,filteredDeviceMonitoringMap)
}
/**

View File

@@ -69,6 +69,12 @@
<el-form-item label="谐波系统检测点id" prop="harmSysId" placeholder="请输入谐波系统检测点id" >
<el-input v-model="formContent.harmSysId" />
</el-form-item>
<el-form-item label="是否参与检测" prop="checkFlag" placeholder="请输入CT编号" >
<el-select v-model="formContent.checkFlag" clearable placeholder="请选择是否加密">
<el-option label="是" :value="1"></el-option>
<el-option label="否" :value="0"></el-option>
</el-select>
</el-form-item>
</el-form>
</div>
<template #footer>
@@ -114,6 +120,7 @@
connection: '',
statInterval: 1,
harmSysId: '',
checkFlag:1
})
return { dialogVisible, titleType, formContent }
}
@@ -135,6 +142,7 @@ const resetFormContent = () => {
connection: '',
statInterval: 1,
harmSysId: '',
checkFlag:1
}
}
@@ -163,6 +171,7 @@ const resetFormContent = () => {
connection: [{ required: true, message: '接线方式必选!', trigger: 'change' }],
busbar : [{ required: true, message: '所属母线必选!', trigger: 'change' }],
harmSysId : [{ required: true, message: '谐波系统检测点id必填', trigger: 'blur' }],
checkFlag : [{ required: true, message: '是否参与检测必选!', trigger: 'change' }]
})

View File

@@ -97,6 +97,14 @@ const columns = reactive<ColumnProps<Monitor.ResPqMon>[]>([
label: '统计间隔',
width: 130,
},
{
prop: 'checkFlag',
label: '是否参与检测',
render: (scope: any) => {
return scope.row.checkFlag === 1 ? '是' : '否'
},
width: 130,
},
{ prop: 'operation', label: '操作', fixed: 'right', width: 200 },
])