diff --git a/rc_autoplc_front/src/router/index.ts b/rc_autoplc_front/src/router/index.ts index 216f6be..b2b5308 100644 --- a/rc_autoplc_front/src/router/index.ts +++ b/rc_autoplc_front/src/router/index.ts @@ -115,6 +115,11 @@ const router = createRouter({ component: () => import('../views/recordinfo/index.vue'), meta: { permission: 'tb:exceptionrecord' }, }, + { + path: '/status-monitor', + name: 'status-monitor', + component: () => import('../views/statusmonitor/index.vue'), + }, ], }, ], diff --git a/rc_autoplc_front/src/views/Layout.vue b/rc_autoplc_front/src/views/Layout.vue index 845c347..0ecd42f 100644 --- a/rc_autoplc_front/src/views/Layout.vue +++ b/rc_autoplc_front/src/views/Layout.vue @@ -103,6 +103,10 @@ 进样控制 + + + 状态监控界面 + 样品记录 @@ -182,6 +186,7 @@ const getMenuIcon = (menuName: string) => { '标准流程管理': Files, '流程创建': EditPen, 进样控制: Operation, + 监控: Monitor, } return iconMap[menuName] || EditPen } diff --git a/rc_autoplc_front/src/views/devinfo/index.vue b/rc_autoplc_front/src/views/devinfo/index.vue index 764f1c2..0d231cf 100644 --- a/rc_autoplc_front/src/views/devinfo/index.vue +++ b/rc_autoplc_front/src/views/devinfo/index.vue @@ -25,9 +25,10 @@ clearable style="width: 200px" > - - - + + + + @@ -376,19 +377,31 @@ const getIndex = (index: number) => { return (pagination.pageNum - 1) * pagination.pageSize + index + 1 } +const normalizeStatus = (value: any) => { + if (value === 0 || value === '0' || value === 'offline' || value === 'OFFLINE' || value === '离线') return 0 + if (value === 1 || value === '1' || value === 'idle' || value === 'IDLE' || value === '空闲') return 1 + if (value === 2 || value === '2' || value === 'busy' || value === 'BUSY' || value === '忙碌') return 2 + if (value === 5 || value === '5' || value === 'fault' || value === 'FAULT' || value === '故障') return 5 + return 0 +} + // 获取状态类型 -const getStatusType = (status: number | null | undefined) => { - if (status === 0) return 'success' // 空闲 - if (status === 1) return 'warning' // 运行 - if (status === 4) return 'danger' // 故障 +const getStatusType = (status: number | string | null | undefined) => { + const normalized = normalizeStatus(status) + if (normalized === 0) return 'info' + if (normalized === 1) return 'success' + if (normalized === 2) return 'warning' + if (normalized === 5) return 'danger' return 'info' } // 获取状态文本 -const getStatusText = (status: number | null | undefined) => { - if (status === 0) return '空闲' - if (status === 1) return '运行' - if (status === 4) return '故障' +const getStatusText = (status: number | string | null | undefined) => { + const normalized = normalizeStatus(status) + if (normalized === 0) return '离线' + if (normalized === 1) return '空闲' + if (normalized === 2) return '忙碌' + if (normalized === 5) return '故障' return '未知' } @@ -736,6 +749,9 @@ const currentDevice = ref(null) const paramList = ref([]) // 参数列表(分页) const paramTotal = ref(0) // 参数总数 const boundParamIds = ref>(new Set()) // 已绑定的参数ID集合 +const selectedParamIds = ref>(new Set()) // 当前配置中已勾选的参数ID集合(跨页保持) +const paramSelectionCache = ref>({}) // 参数勾选缓存(用于分页回显) +const syncingParamSelection = ref(false) // 是否正在程序化同步勾选状态 const paramConfigTableRef = ref(null) // 参数表格引用 const categoryMap = ref>({}) // 参数分类ID到名称的映射 const categoryDicTypeId = ref(null) // 参数分类的字典类型ID @@ -783,12 +799,34 @@ const getRowDevIds = (row: any): Set => { return parseDevIdsField(row?.devIds ?? row?.dev_ids ?? row?.devIDS ?? row?.devIdsStr) } +// 打开参数配置对话框 +const getParamSelectionCacheKey = () => { + return currentDevice.value?.id ? String(currentDevice.value.id) : '' +} + +const syncParamSelectionCache = () => { + const cacheKey = getParamSelectionCacheKey() + if (!cacheKey) return + paramSelectionCache.value[cacheKey] = Array.from(selectedParamIds.value) +} + // 打开参数配置对话框 const handleConfigParams = async (row: any) => { currentDevice.value = row paramConfigDialogVisible.value = true + selectedParamIds.value = new Set() await loadCategoryList() await loadBoundParams() + + const cacheKey = getParamSelectionCacheKey() + const cacheSelection = cacheKey ? paramSelectionCache.value[cacheKey] : undefined + if (cacheSelection?.length) { + selectedParamIds.value = new Set(cacheSelection.map((id) => Number(id))) + } else { + selectedParamIds.value = new Set(boundParamIds.value) + syncParamSelectionCache() + } + await loadParamList() await nextTick() setSelectedParams() @@ -953,18 +991,41 @@ const getParamCategoryName = (dicDataId: number | string | undefined | null) => const setSelectedParams = () => { if (!paramConfigTableRef.value) return + syncingParamSelection.value = true paramConfigTableRef.value.clearSelection() paramList.value.forEach((param: any) => { - if (boundParamIds.value.has(param.id)) { + if (selectedParamIds.value.has(Number(param.id))) { paramConfigTableRef.value.toggleRowSelection(param, true) } }) + + nextTick(() => { + syncingParamSelection.value = false + }) } // 参数选择变化 -const handleParamSelectionChange = (_selection: any[]) => { - // noop +const handleParamSelectionChange = (selection: any[]) => { + if (syncingParamSelection.value) return + + const currentPageSelectedIds = new Set( + selection + .map((item: any) => item.id) + .filter((id: any) => id !== null && id !== undefined) + .map((id: any) => Number(id)), + ) + + paramList.value.forEach((param: any) => { + const paramId = Number(param.id) + if (currentPageSelectedIds.has(paramId)) { + selectedParamIds.value.add(paramId) + } else { + selectedParamIds.value.delete(paramId) + } + }) + + syncParamSelectionCache() } // 参数查询 @@ -1001,16 +1062,9 @@ const handleSaveParamConfig = async () => { try { paramConfigSubmitting.value = true - const selectedParams = paramConfigTableRef.value?.getSelectionRows() || [] - const selectedParamIds = new Set( - selectedParams - .map((p: any) => p.id) - .filter((id: any) => id !== null && id !== undefined) - .map((id: any) => Number(id)), - ) - - const toBind = Array.from(selectedParamIds).filter((id: number) => !boundParamIds.value.has(id)) - const toUnbind = Array.from(boundParamIds.value).filter((id: number) => !selectedParamIds.has(id)) + const selectedIds = new Set(Array.from(selectedParamIds.value).map(id => Number(id))) + const toBind = Array.from(selectedIds).filter((id: number) => !boundParamIds.value.has(id)) + const toUnbind = Array.from(boundParamIds.value).filter((id: number) => !selectedIds.has(id)) const currentDevId = Number(currentDevice.value.id) @@ -1022,7 +1076,11 @@ const handleSaveParamConfig = async () => { ElMessage.success('参数配置保存成功') paramConfigDialogVisible.value = false - boundParamIds.value = selectedParamIds + boundParamIds.value = new Set(selectedIds) + syncParamSelectionCache() + if (currentDevice.value?.id) { + delete paramSelectionCache.value[String(currentDevice.value.id)] + } } catch (error) { console.error('保存参数配置失败:', error) ElMessage.error('保存参数配置失败') @@ -1037,6 +1095,11 @@ const handleParamConfigDialogClose = () => { paramList.value = [] paramTotal.value = 0 boundParamIds.value = new Set() + selectedParamIds.value = new Set() + if (currentDevice.value?.id) { + delete paramSelectionCache.value[String(currentDevice.value.id)] + } + syncingParamSelection.value = false paramQueryForm.paramTypeData = '' paramPagination.pageNum = 1 paramPagination.pageSize = 10 diff --git a/rc_autoplc_front/src/views/recordinfo/index.vue b/rc_autoplc_front/src/views/recordinfo/index.vue index 5ed7cec..c48e56c 100644 --- a/rc_autoplc_front/src/views/recordinfo/index.vue +++ b/rc_autoplc_front/src/views/recordinfo/index.vue @@ -158,7 +158,7 @@ v-permission="'tb:exceptionrecord:upd'" type="primary" :loading="saveLoading" - @click="handleDealSave" + @click="handleDealSave" > {{ dealEditable ? '保存' : '编辑' }} diff --git a/rc_autoplc_front/src/views/statusmonitor/index.vue b/rc_autoplc_front/src/views/statusmonitor/index.vue new file mode 100644 index 0000000..4876849 --- /dev/null +++ b/rc_autoplc_front/src/views/statusmonitor/index.vue @@ -0,0 +1,637 @@ + + + + +