-
设备基本信息
+
{{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=''