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=''