From a7a57f0c7362adab81bf8b95889b2c91b372fa39 Mon Sep 17 00:00:00 2001 From: liutao <790864623@qq.com> Date: Mon, 8 Jun 2026 10:07:22 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E8=AE=BE=E5=A4=87=E5=8F=B0=E8=B4=A6?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/locales/en.ts | 6 +++++- src/locales/zh-CN.ts | 6 +++++- src/views/mes/deviceledger/detail/editIndex.vue | 2 +- src/views/mes/deviceledger/detail/index.vue | 10 +++++----- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/locales/en.ts b/src/locales/en.ts index 4eb0b64d..eb77d4ed 100644 --- a/src/locales/en.ts +++ b/src/locales/en.ts @@ -1369,7 +1369,11 @@ export default { actualCapacity: 'Actual Capacity', Detail: { invalidId: 'Invalid device ID' - } + }, + DeviceQRCode: 'Device QR Code', + codeTitle:'Scan to view device details', + featureDescription:'SupportsSpotCheck/repair/maintenance', + BasicInformation:'Device Basic Information' }, // Capacity Report CapacityReport: { diff --git a/src/locales/zh-CN.ts b/src/locales/zh-CN.ts index 66ca0463..3275ce1c 100644 --- a/src/locales/zh-CN.ts +++ b/src/locales/zh-CN.ts @@ -1359,7 +1359,11 @@ export default { actualCapacity: '实际产能', Detail: { invalidId: '无效的设备ID' - } + }, + DeviceQRCode: '设备二维码', + codeTitle:'扫码查看设备详情', + featureDescription:'支持点检 / 报修 / 维保', + BasicInformation:'设备基本信息' }, // 产能报表 CapacityReport: { diff --git a/src/views/mes/deviceledger/detail/editIndex.vue b/src/views/mes/deviceledger/detail/editIndex.vue index 8b0dbb26..0adf9f09 100644 --- a/src/views/mes/deviceledger/detail/editIndex.vue +++ b/src/views/mes/deviceledger/detail/editIndex.vue @@ -2,7 +2,7 @@
-
设备基本信息
+
{{t('EquipmentManagement.EquipmentLedger.BasicInformation')}}
-
设备二维码
+
{{t('EquipmentManagement.EquipmentLedger.DeviceQRCode')}}
-
扫码查看设备详情
-
支持点检 / 报修 / 维保
+
{{t('EquipmentManagement.EquipmentLedger.codeTitle')}}
+
{{t('EquipmentManagement.EquipmentLedger.featureDescription')}}
@@ -1128,14 +1128,14 @@ onMounted(async () => { .device-ledger-detail-qrcode-desc { margin-top: 12px; color: var(--el-text-color-regular); - font-size: 13px; + font-size: 11px; line-height: 20px; } .device-ledger-detail-qrcode-sub { margin-top: 2px; color: var(--el-text-color-secondary); - font-size: 12px; + font-size: 9px; line-height: 18px; } From f1982f255508f73bbfbeec1ea48c3458eb28e887 Mon Sep 17 00:00:00 2001 From: liutao <790864623@qq.com> Date: Wed, 10 Jun 2026 08:18:46 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E6=96=87=E4=BB=B6=E4=B8=8A=E4=BC=A0?= =?UTF-8?q?=E7=9A=84=E5=A4=A7=E5=B0=8F=E5=8F=8A=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/UploadFile/src/UploadFile.vue | 13 ++++++++++ .../mes/deviceledger/detail/editIndex.vue | 25 ++++++++++++++++--- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/components/UploadFile/src/UploadFile.vue b/src/components/UploadFile/src/UploadFile.vue index cd68809b..c5e002b7 100644 --- a/src/components/UploadFile/src/UploadFile.vue +++ b/src/components/UploadFile/src/UploadFile.vue @@ -9,6 +9,7 @@ :disabled="disabled" :drag="drag" :http-request="httpRequest" + :accept="acceptTypes" :limit="props.limit" :multiple="props.limit > 1" :on-error="excelUploadError" @@ -102,6 +103,18 @@ const nameMap = ref>({}) const { uploadUrl, httpRequest } = useUpload() +const acceptTypes = computed(() => + props.fileType + .map((type: string) => { + const normalizedType = String(type).trim() + if (!normalizedType) return '' + if (normalizedType.startsWith('.') || normalizedType.includes('/')) return normalizedType + return `.${normalizedType}` + }) + .filter(Boolean) + .join(',') +) + const emitUploadingChange = () => { emit('uploading-change', uploadPendingCount.value > 0) } diff --git a/src/views/mes/deviceledger/detail/editIndex.vue b/src/views/mes/deviceledger/detail/editIndex.vue index 0adf9f09..02459aac 100644 --- a/src/views/mes/deviceledger/detail/editIndex.vue +++ b/src/views/mes/deviceledger/detail/editIndex.vue @@ -176,6 +176,8 @@ @@ -426,8 +428,6 @@ const parseIdsValue = (value: any): number[] => { const selectedRows = ref([]) // 存储所有选中的行 const bjSelectedRows = ref([]) // 存储所有选中的行 const queryParams = reactive({ - pageNo: 1, - pageSize: 10, code: undefined as string | undefined, name: undefined as string | undefined, description: undefined as string | undefined, @@ -734,6 +734,25 @@ const formLoading = ref(false) const fileUploading = ref(false) const formType = ref('update') const formRef = ref() +const materialFileTypes = [ + 'png', + 'jpg', + 'jpeg', + 'webp', + 'doc', + 'docx', + 'xls', + 'xlsx', + 'ppt', + 'pptx', + 'pdf', + 'zip', + 'rar', + '7z', + 'dwg', + 'dxf', + 'mp4' +] const formData = ref({ ...initFormData() }) @@ -1442,5 +1461,3 @@ onBeforeUnmount(() => { - - 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 3/3] =?UTF-8?q?feat:=20=E6=A8=A1=E5=85=B7=E7=AE=A1?= =?UTF-8?q?=E7=90=86-=E4=B8=8A=E4=B8=8B=E6=A8=A1=E5=BC=B9=E7=AA=97?= =?UTF-8?q?=E7=9B=AE=E6=A0=87=E4=BA=A7=E7=BA=BF=E6=94=B9=E4=B8=BA=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E5=A1=AB=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=''