From 5dce2ad2f3c92d82295c7d524f2b72538c52d3bf Mon Sep 17 00:00:00 2001 From: zhongwenkai <3478244299@qq.com> Date: Wed, 10 Jun 2026 15:13:15 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=A8=A1=E5=85=B7=E7=AE=A1=E7=90=86-?= =?UTF-8?q?=E4=B8=8A=E4=B8=8B=E6=A8=A1=E5=BC=B9=E7=AA=97=E7=9B=AE=E6=A0=87?= =?UTF-8?q?=E4=BA=A7=E7=BA=BF=E6=94=B9=E4=B8=BA=E8=87=AA=E5=8A=A8=E5=A1=AB?= =?UTF-8?q?=E5=85=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/mes/deviceledger/index.ts | 2 + .../erp/mold/components/MoldOperateView.vue | 51 +++++++++++---- src/views/mes/moldoperate/MoldOperateForm.vue | 62 ++++++++++++++----- 3 files changed, 89 insertions(+), 26 deletions(-) diff --git a/src/api/mes/deviceledger/index.ts b/src/api/mes/deviceledger/index.ts index ff3d1883..2db4634f 100644 --- a/src/api/mes/deviceledger/index.ts +++ b/src/api/mes/deviceledger/index.ts @@ -15,6 +15,8 @@ export interface DeviceLedgerVO { deviceSpec: string // 设备规格 deviceType: string | number // 设备类型 deviceLine?: string | number // 设备产线 + topCategoryId?: number // 顶级分类 id + topCategoryName?: string // 顶级分类名称 deviceTypeName?: string // 设备类型名称 supplier: string // 供应商 workshop: string // 所属车间 diff --git a/src/views/erp/mold/components/MoldOperateView.vue b/src/views/erp/mold/components/MoldOperateView.vue index c7e11a2f..e7ca8a09 100644 --- a/src/views/erp/mold/components/MoldOperateView.vue +++ b/src/views/erp/mold/components/MoldOperateView.vue @@ -46,11 +46,8 @@
- - - - + + ([]) +const deviceLineTree = ref([]) +const displayTopCategory = ref('') const operatorOptions = ref([]) // 最近操作记录 @@ -177,10 +174,10 @@ const getImageList = (images?: string) => { const initOperateOptions = async () => { try { - const data = await OrganizationApi.getOrganizationList() - lineOptions.value = Array.isArray(data) ? data : [] + const data = await DeviceLineApi.getDeviceLineTree() + deviceLineTree.value = Array.isArray(data) ? data : [] } catch { - lineOptions.value = [] + deviceLineTree.value = [] } try { operatorOptions.value = (await getSimpleUserList()) ?? [] @@ -189,6 +186,34 @@ const initOperateOptions = async () => { } } +// 选择设备后自动匹配产线名称 +watch(() => operateFormData.deviceId, async (deviceId) => { + displayTopCategory.value = '' + if (!deviceId) return + try { + const detail = await DeviceLedgerApi.getDeviceLedger(deviceId) + if (detail?.deviceLine != null) { + operateFormData.lineId = detail.deviceLine + } + // 优先用后端返回的顶级分类名称 + displayTopCategory.value = detail?.topCategoryName || '' + // fallback: 用产线树匹配根节点名称 + if (!displayTopCategory.value && detail?.deviceLine != null && deviceLineTree.value.length) { + const lineId = Number(detail.deviceLine) + const containsId = (nodes: DeviceLineTreeVO[] | undefined, id: number): boolean => { + if (!nodes) return false + return nodes.some((n) => n.id === id || containsId(n.children, id)) + } + for (const root of deviceLineTree.value) { + if (root.id === lineId || containsId(root.children, lineId)) { + displayTopCategory.value = root.name + break + } + } + } + } catch {} +}) + const fetchRecentOperateList = async () => { if (!props.mold?.id) return recentLoading.value = true @@ -217,6 +242,7 @@ const submitOperateForm = async () => { operateType: props.type, moldId: props.mold?.id, lineId: operateFormData.lineId, + lineName: displayTopCategory.value, deviceId: operateFormData.deviceId, remark: operateFormData.remark, operateTime: operateFormData.operateTime, @@ -240,6 +266,7 @@ const open = async () => { operateFormData.operateTime = undefined operateFormData.operatorId = undefined operateFormData.remark = undefined + displayTopCategory.value = '' await initOperateOptions() recentPageNo.value = 1 await fetchRecentOperateList() diff --git a/src/views/mes/moldoperate/MoldOperateForm.vue b/src/views/mes/moldoperate/MoldOperateForm.vue index 555bdcc2..e22ed40e 100644 --- a/src/views/mes/moldoperate/MoldOperateForm.vue +++ b/src/views/mes/moldoperate/MoldOperateForm.vue @@ -26,10 +26,8 @@ @click="openMoldSelectDialog" /> - - - - + + ([]) +const deviceLineTree = ref([]) +const displayTopCategory = ref('') const operatorOptions = ref([]) const initializingOperateType = ref(false) @@ -169,7 +168,6 @@ const validateMoldId = (_rule: any, value: any, callback: (error?: Error) => voi const formRules = reactive({ operateType: [{ required: true, message: t('MoldManagement.MoldOperate.validatorOperateTypeRequired'), trigger: 'blur' }], deviceId: [{ required: true, message: t('MoldManagement.MoldOperate.validatorDeviceRequired'), trigger: 'change' }], - lineId: [{ required: true, message: t('MoldManagement.MoldOperate.validatorProductionLineRequired'), trigger: 'change' }], moldId: [{ required: true, validator: validateMoldId, trigger: 'change' }], operateTime: [{ required: true, message: t('MoldManagement.MoldOperate.validatorOperateTimeRequired'), trigger: 'blur' }], operatorId: [{ required: true, message: t('MoldManagement.MoldOperate.validatorOperatorRequired'), trigger: 'change' }], @@ -265,6 +263,7 @@ const submitForm = async () => { deviceId: raw.deviceId, moldId: raw.moldId, lineId: raw.lineId, + lineName: displayTopCategory.value, // 产线名称,用于列表显示 operateTime: raw.operateTime, operatorId: raw.operatorId, remark: raw.remark, @@ -292,12 +291,12 @@ const submitForm = async () => { } const ensureLineOptionsLoaded = async () => { - if (lineOptions.value.length) return + if (deviceLineTree.value.length) return try { - const data = await OrganizationApi.getOrganizationList() - lineOptions.value = Array.isArray(data) ? data : [] + const data = await DeviceLineApi.getDeviceLineTree() + deviceLineTree.value = Array.isArray(data) ? data : [] } catch { - lineOptions.value = [] + deviceLineTree.value = [] } try { operatorOptions.value = (await getSimpleUserList()) ?? [] @@ -347,6 +346,7 @@ const resetForm = () => { selectedMoldRows.value = [] ids.value = [] moldIds.value = [] + displayTopCategory.value = '' formRef.value?.resetFields() } const deviceColumns = [ @@ -377,12 +377,42 @@ const fetchMoldBrandPage = async (params: Record) => { } const selectedDeviceRows = ref([]) const selectedMoldRows = ref([]) -const handleDeviceSelectConfirm = (payload: { ids: (number | string)[]; rows: any[] }) => { +const handleDeviceSelectConfirm = async (payload: { ids: (number | string)[]; rows: any[] }) => { const row = payload.rows[0] if (row) { selectedDeviceRows.value = [row] - formData.value.deviceId = Number(row.id) - ids.value = [Number(row.id)] + const deviceId = Number(row.id) + formData.value.deviceId = deviceId + ids.value = [deviceId] + // 选择设备后调详情接口获取完整的 deviceLine 字段(分页接口不返回该字段) + try { + const detail = await DeviceLedgerApi.getDeviceLedger(deviceId) + console.log('设备详情:', { detail, topCategoryName: detail?.topCategoryName, topCategoryId: detail?.topCategoryId, deviceLine: detail?.deviceLine }) + if (detail?.deviceLine != null) { + formData.value.lineId = detail.deviceLine + } + // 优先用后端返回的顶级分类名称 + displayTopCategory.value = detail?.topCategoryName || '' + // fallback: 用产线树(DeviceLineTree)匹配,找到根节点名称 + if (!displayTopCategory.value && detail?.deviceLine != null && deviceLineTree.value.length) { + const lineId = Number(detail.deviceLine) + console.log('fallback 匹配: deviceLine=', lineId, '产线树根数=', deviceLineTree.value.length) + // 检查每个顶层节点是否包含目标节点(自身或后代),返回根节点名称 + const containsId = (nodes: DeviceLineTreeVO[] | undefined, id: number): boolean => { + if (!nodes) return false + return nodes.some((n) => n.id === id || containsId(n.children, id)) + } + for (const root of deviceLineTree.value) { + if (root.id === lineId || containsId(root.children, lineId)) { + displayTopCategory.value = root.name + console.log('产线匹配成功:', root.name) + break + } + } + } + } catch (e) { + console.error('获取设备详情失败', e) + } } else { selectedDeviceRows.value = [] formData.value.deviceId = undefined @@ -481,6 +511,10 @@ const moldDisplayText = computed(() => { return map.get(formData.value.moldId) || '' }) +const displayLineName = computed(() => displayTopCategory.value) + + + const openCriticalComponentDialog = async () => { searchParams.deviceCode=''