From 6e22c01dd81e9916f418a1a61c135a415aac092c Mon Sep 17 00:00:00 2001 From: sjl <1716605279@qq.com> Date: Thu, 24 Jul 2025 08:29:03 +0800 Subject: [PATCH] =?UTF-8?q?=E9=80=9A=E9=81=93=E9=85=8D=E5=AF=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../home/components/deviceConnectionPopup.vue | 87 ++++++++++----- frontend/src/views/home/components/table.vue | 105 +++++++++++++++++- frontend/src/views/home/tabs/dashboard.vue | 30 ++--- .../plan/planList/components/childrenPlan.vue | 58 +++++++--- frontend/src/views/plan/planList/index.vue | 20 +++- 5 files changed, 235 insertions(+), 65 deletions(-) diff --git a/frontend/src/views/home/components/deviceConnectionPopup.vue b/frontend/src/views/home/components/deviceConnectionPopup.vue index 747480d..0ebe949 100644 --- a/frontend/src/views/home/components/deviceConnectionPopup.vue +++ b/frontend/src/views/home/components/deviceConnectionPopup.vue @@ -44,6 +44,9 @@ import {dialogBig} from "@/utils/elementBind"; import {Platform,Promotion,Flag} from '@element-plus/icons-vue' import { c } from 'vite/dist/node/types.d-aGj9QkWt'; import { de, el } from 'element-plus/es/locale'; +import { Device } from '@/api/device/interface/device'; +import { Plan } from '@/api/plan/interface'; +import { StandardDevice } from '@/api/device/interface/standardDevice'; const dialogVisible = ref(false) // 初始化 VueFlow const { edges} = useVueFlow() @@ -331,30 +334,69 @@ function logConnections() { } const nodes = ref([]) -const open = async () => { - nodes.value = createNodes() +const open = async (device:Device.ResPqDev[],standardDev:StandardDevice.ResPqStandardDevice[]) => { + nodes.value = createNodes(device,standardDev) dialogVisible.value = true } - // 每台设备的通道数量 - const channelCounts = { - '1': 1, // 被检设备1 → 4个通道 - '3': 3, // 被检设备2 → 2个通道 - '5': 2, // 被检设备3 → 2个通道 - '7': 4 // 被检设备4 → 4个通道 - } + // // 每台设备的通道数量 + // const channelCounts = { + // '1': 1, // 被检设备1 → 4个通道 + // '3': 3, // 被检设备2 → 2个通道 + // '5': 2, // 被检设备3 → 2个通道 + // '7': 4 // 被检设备4 → 4个通道 + // } // 每台设备的通道数量 - const channelCounts2 = { - '2': 2, // 标准设备1 → 2个通道 - '4': 1, // 标准设备2 → 1个通道 - } + // const channelCounts2 = { + // '2': 2, // 标准设备1 → 2个通道 + // '4': 1, // 标准设备2 → 1个通道 + // } + + // const inspectionDevices = [ + // { id: '1', name: '被检设备1', type: 'normal', deviceType: 'PQS-882B4' }, + // { id: '3', name: '被检设备2', type: 'normal', deviceType: 'PQS-883A2' }, + // { id: '5', name: '被检设备3', type: 'normal', deviceType: 'PQS-882B2' }, + // { id: '7', name: '被检设备4', type: 'normal', deviceType: 'PQS_883B' } + // ] + +// const standardDevices = [ +// { id: '2', name: '标准设备1', type: 'normal', deviceType: 'PQS-882A' }, +// { id: '4', name: '标准设备2', type: 'normal', deviceType: 'PQS-882B2' }, +// ] + +const createNodes = (device: Device.ResPqDev[], standardDev: StandardDevice.ResPqStandardDevice[]) => { + + const channelCounts: Record = {} + // 每台被检设备的通道数量 + device.forEach(device => { + channelCounts[device.id] = device.devChns || 0 + }) + // 每台被检设备的信息 + const inspectionDevices = device.map(d => ({ + id: d.id, + name: d.name, + type: 'normal', + deviceType: d.devType + })) + + const channelCounts2: Record = {} + // 每台标准设备的通道数量 + standardDev.forEach(dev => { + const channelList = dev.inspectChannel ? dev.inspectChannel.split(',') : [] + channelCounts2[dev.id] = channelList.length + }) + console.log(standardDev) + // 每台标准设备的信息 + const standardDevices = standardDev.map(d => ({ + id: d.id, + name: d.name, + type: 'normal', + deviceType: d.devType + })) + - -const createNodes = () => { const newNodes: any[] = [] - - // 存储每组被检/标准通道的垂直范围 const deviceChannelGroups: { deviceId: string; centerY: number; }[] = [] const standardChannelGroups: any[] = [] @@ -472,17 +514,6 @@ const createNodes = () => { return newNodes } -const inspectionDevices = [ - { id: '1', name: '被检设备1', type: 'normal', deviceType: 'PQS-882B4' }, - { id: '3', name: '被检设备2', type: 'normal', deviceType: 'PQS-883A2' }, - { id: '5', name: '被检设备3', type: 'normal', deviceType: 'PQS-882B2' }, - { id: '7', name: '被检设备4', type: 'normal', deviceType: 'PQS_883B' } -] - -const standardDevices = [ - { id: '2', name: '标准设备1', type: 'normal', deviceType: 'PQS-882A' }, - { id: '4', name: '标准设备2', type: 'normal', deviceType: 'PQS-882B2' }, -] defineExpose({open}) diff --git a/frontend/src/views/home/components/table.vue b/frontend/src/views/home/components/table.vue index b328bfb..e7502b0 100644 --- a/frontend/src/views/home/components/table.vue +++ b/frontend/src/views/home/components/table.vue @@ -274,7 +274,7 @@ import reportPopup from './reportPopup.vue' import dataCheckPopup from './dataCheckSingleChannelSingleTestPopup.vue' import dataCheckChangeErrSysPopup from './dataCheckChangeErrSysPopup.vue' import {generateDevReport, getBoundPqDevList} from '@/api/plan/plan.ts' -import {onBeforeMount, onMounted, reactive, ref, watch} from 'vue' +import {onBeforeMount, onMounted, PropType, reactive, ref, watch} from 'vue' import {useDictStore} from '@/stores/modules/dict' import ChannelsTest from './channelsTest.vue' import {useModeStore,useAppSceneStore} from '@/stores/modules/mode' // 引入模式 store @@ -291,6 +291,9 @@ import {ResultEnum} from '@/enums/httpEnum' import SelectTestItemPopup from "@/views/home/components/selectTestItemPopup.vue"; import WriteTHPopup from "@/views/home/components/writeTHPopup.vue"; import DeviceConnectionPopup from '@/views/home/components/deviceConnectionPopup.vue' +import { Plan } from '@/api/plan/interface' +import { StandardDevice } from '@/api/device/interface/standardDevice' +import { s } from 'vite/dist/node/types.d-aGj9QkWt' const dictStore = useDictStore() const checkStore = useCheckStore() @@ -363,6 +366,10 @@ const props = defineProps({ type: Object, default: null, }, + planArray: { + type: Array as PropType, + default: null, +}, }) const appSceneStore = useAppSceneStore() @@ -522,13 +529,47 @@ const columns = reactive[]>([ { prop: 'devType', label: '设备类型', - minWidth: 100, + minWidth: 150, // render: (scope) => { // // 查找设备类型名称 // const name = devTypeOptions.value.find(option => option.id === scope.row.devType) // return {name?.name} // }, }, + { + prop: 'boundPlanName', + label: '来源计划名称', + minWidth: 200, + isShow:modeStore.currentMode === '比对式', + render(scope) { + return scope.row.boundPlanName ? scope.row.boundPlanName : props.plan.name + } + }, + { + prop: 'standardDevs', + label: '标准设备', + minWidth: 200, + isShow:modeStore.currentMode === '比对式', + render(scope) { + const boundPlanName = ref('') + if(scope.row.boundPlanName){ + boundPlanName.value = scope.row.boundPlanName + }else{ + boundPlanName.value = props.plan.name + } + const standardDevNames = props.planArray.flatMap(item => { + if (item.children) { + return item.children + .filter(child => child.name === boundPlanName.value) + .flatMap(child => + child.standardDevs.map(dev => dev.name) + ) + } + return [] + }) + return standardDevNames.length > 0 ? standardDevNames.join(',') : '/' + } + }, { prop: 'devChns', label: '通道数', @@ -631,6 +672,7 @@ const resetSearchForm = () => { let testType = 'test'//检测还是复检 const handleSelectionChange = (selection: any[]) => { + channelsSelection.value = selection devNum = selection.length devChannelsNum = 0 @@ -852,7 +894,64 @@ const addDevice = (val: string) => { const handleTest2 = () => { - deviceConnectionPopupRef.value?.open() + if (devNum == 0) { + ElMessageBox.confirm( + '请先选择被检设备', + '提示', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning', + }, + ) + return + } + const planName = channelsSelection.value.map(item => item.boundPlanName) + const isPlanConsistent = new Set(planName).size === 1 + if (!isPlanConsistent) { + ElMessageBox.confirm( + '所勾选被检设备所属计划名称不一致,请重新选择', + '提示', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning', + }, + ) + return + } + + const boundPlanName = ref('') + if(channelsSelection.value[0].boundPlanName){ + boundPlanName.value = channelsSelection.value[0].boundPlanName + }else{ + boundPlanName.value = props.plan.name + } + const pqStandardDevList=ref([]) + pqStandardDevList.value = props.planArray.flatMap(item => { + if (item.children) { + return item.children + .filter(child => child.name === boundPlanName.value) + .flatMap(child => + child.standardDevs + ) + } + return [] + }) + + if(pqStandardDevList.value.length==0){ + ElMessageBox.confirm( + '所勾选被检设备所属计划无标准设备,请重新选择', + '提示', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning', + }, + ) + return + } + deviceConnectionPopupRef.value?.open(channelsSelection.value,pqStandardDevList.value) } const handleTest = async (val: string) => { diff --git a/frontend/src/views/home/tabs/dashboard.vue b/frontend/src/views/home/tabs/dashboard.vue index a862ebd..b32feea 100644 --- a/frontend/src/views/home/tabs/dashboard.vue +++ b/frontend/src/views/home/tabs/dashboard.vue @@ -95,7 +95,7 @@
-
+
@@ -148,6 +148,7 @@ const tabPaneHeight = ref('calc(100% - 5px)') // 初始高度 const tableHeight = ref('calc(100% - 50px)') // 初始高度 const planList = ref>() +const planList2 = ref>()//备份含子计划的结构 const select_Plan = ref() const isLabelLineShow = ref(true) const { popupBaseView,viewWidth, viewHeight } = useViewSize() @@ -205,7 +206,6 @@ const tableRef1 = ref() const tableRef2 = ref() const currentId = ref('') - watch( () => form.value, (val, oldVal) => { @@ -244,15 +244,13 @@ watch( }, ) - - const pieRef1 = ref(), - pieRef2 = ref(), - pieRef3 = ref() +pieRef2 = ref(), +pieRef3 = ref() const chartsData1: any = ref([]), - chartsData2: any = ref([]), - chartsData3: any = ref([]) +chartsData2: any = ref([]), +chartsData3: any = ref([]) const findPlanById = (plans: Plan.ReqPlan[], id: string): Plan.ReqPlan | undefined => { for (const plan of plans) { @@ -301,10 +299,12 @@ const getPieData = async (id: string) => { if (id) { const boundPqDevList = ref([])//根据检测计划id查询出所有已绑定的设备 const plan = findPlanById(planList.value, id) - console.log('所选计划:',plan) + planName.value = '所选计划:' + plan.name - + + select_Plan.value = plan + console.log('所选计划:',plan) const pqDevList_Result2 = await getBoundPqDevList({ 'planIdList': [id], 'checkStateList': [0, 1, 2, 3] }) boundPqDevList.value = pqDevList_Result2.data as Device.ResPqDev[] @@ -325,7 +325,6 @@ const getPieData = async (id: string) => { } }) - // 检查 checkStateCount 是否全为 0 if(boundPqDevList.value.length != 0){ @@ -379,12 +378,7 @@ const getPieData = async (id: string) => { { value: 0 , itemStyle: { color: '#eeeeee' } }, ]; } - - - - }else{ - planName.value = '所选计划:' } @@ -497,8 +491,8 @@ const initPlan = async () => { standardDevIds:[], standardDevMap: new Map(), } - planList.value = (await getPlanListByPattern(reqPlan)) as ResultData - + planList2.value = (await getPlanListByPattern(reqPlan)) as ResultData + planList.value = JSON.parse(JSON.stringify(planList2.value)); planList.value = planList.value.data.map((item: any) => { if (item.children) { item.children = item.children.filter(child => child.pid === '0'); diff --git a/frontend/src/views/plan/planList/components/childrenPlan.vue b/frontend/src/views/plan/planList/components/childrenPlan.vue index 6f91c9f..02cc048 100644 --- a/frontend/src/views/plan/planList/components/childrenPlan.vue +++ b/frontend/src/views/plan/planList/components/childrenPlan.vue @@ -8,7 +8,6 @@ :title="title" :width="width" :modal="false" - @close="handleClose" >
@@ -283,6 +282,7 @@ const editableTabs = computed(() => { return tabs }) +//解绑被检设备 const unbindDevice = (row: any) => { if(row.state == '/') return @@ -327,7 +327,7 @@ const addNewChildTab = async () => { await props.refreshTable!()//刷新检测计划列表 } - +//分配被检设备 const distribute = (childPlan: Plan.ResPlan, scope: any) => { // 获取当前选中的设备对象 @@ -435,6 +435,26 @@ const findItemById = (data: any[], id: string): any => { return null; // 未找到匹配项 }; + + +//主计划下移除被检设备 +const handleRemove = async (row: any) => { + ElMessageBox.confirm(`确定要移除计划【${row.name}】吗?`, '提示', { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + }).then(async () => { + if(row.assign != 0){ + ElMessage.warning(`当前设备已被子计划绑定,无法删除!`); + return + } + console.log('shcn',planFormContent.value) + proTable.value?.getTableList(); // 刷新当前表格 + }).catch(() => { + // 用户取消操作 + }); +} + //子计划下移除被检设备 const subHandleRemove = async (row: any) => { ElMessageBox.confirm(`确定要移除计划【${row.name}】吗?`, '提示', { @@ -491,15 +511,25 @@ const subBatchRemove = async (selectedListIds: string[]) => { defineExpose({ open,handleTableDataUpdate }) -const props = defineProps<{ - refreshTable: (() => Promise) | undefined; - width: { - type: Number, - default: 800, - }, - height: { - type: Number, - default: 744, - }, -}>() +interface ChildrenPlanProps { + refreshTable?: () => Promise + width?: number + height?: number +} + +const props = withDefaults(defineProps(), { + width: 800, + height: 744 +}) +// const props = defineProps<{ +// refreshTable: (() => Promise) | undefined; +// width: { +// type: Number, +// default: 800, +// }, +// height: { +// type: Number, +// default: 744, +// }, +// }>() \ No newline at end of file diff --git a/frontend/src/views/plan/planList/index.vue b/frontend/src/views/plan/planList/index.vue index d5ce133..858f661 100644 --- a/frontend/src/views/plan/planList/index.vue +++ b/frontend/src/views/plan/planList/index.vue @@ -360,7 +360,13 @@ const columns = reactive[]>([ label: '标准设备', minWidth: 250, isShow: modeStore.currentMode == "比对式", - + render: scope => { + const standardDevNameStr = scope.row.standardDevNameStr + if (!standardDevNameStr) { + return '/' + } + return standardDevNameStr + } }, { prop: 'testItemNameStr', @@ -481,7 +487,17 @@ const exportClick = () => { // 打开 drawer(新增、编辑) const openDialog = (titleType: string, row: Partial = {}) => { - planPopup.value?.open(titleType, row,modeStore.currentMode,0)//0主计划 1子计划 2修改子计划 + if(modeStore.currentMode == '比对式'){ + if(row.children?.length > 0){ + planPopup.value?.open(titleType, row,modeStore.currentMode,0)//0主计划 1子计划 2修改子计划 + }else{ + planPopup.value?.open(titleType, row,modeStore.currentMode,2)//0主计划 1子计划 2修改子计划 + } + }else{ + planPopup.value?.open(titleType, row,modeStore.currentMode,0)//0主计划 1子计划 2修改子计划 + } + + }