From 7e8242aa5857c0ffe48a002c86b10874be21b77c Mon Sep 17 00:00:00 2001 From: zhongwenkai <3478244299@qq.com> Date: Tue, 21 Jul 2026 09:04:42 +0800 Subject: [PATCH 1/4] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=B2=BE=E5=BA=A6?= =?UTF-8?q?=E4=B8=A2=E5=A4=B1=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/TaskScheduleDialog.vue | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/views/mes/tasksummary/components/TaskScheduleDialog.vue b/src/views/mes/tasksummary/components/TaskScheduleDialog.vue index e0e24bd4..f7011498 100644 --- a/src/views/mes/tasksummary/components/TaskScheduleDialog.vue +++ b/src/views/mes/tasksummary/components/TaskScheduleDialog.vue @@ -252,8 +252,8 @@ const currentDeviceRelationRow = ref() const currentProductData = ref() const selectedDeviceRows = ref([]) const deviceRelationForm = reactive({ - productId: undefined as number | undefined, - devices: [] as { id: number; name: string }[] + productId: undefined as string | undefined, + devices: [] as { id: string; name: string }[] }) const deviceColumns = computed(() => [ @@ -304,7 +304,7 @@ const taskDetailRequestMap = new Map>() const currentDetailRequestId = ref(0) const taskTableBusy = computed(() => taskLoading.value || taskSelectionLoading.value) -const getRelationName = (item: Record, nameKeys: string[], fallbackPrefix: string, id: number) => { +const getRelationName = (item: Record, nameKeys: string[], fallbackPrefix: string, id: string) => { for (const key of nameKeys) { const value = item[key] if (value !== undefined && value !== null && String(value).trim() !== '') { @@ -318,11 +318,11 @@ const normalizeRelationList = ( fallbackRows: any[] | undefined, nameKeys: string[], fallbackPrefix: string -): { id: number; name: string }[] => { - const fallbackMap = new Map() +): { id: string; name: string }[] => { + const fallbackMap = new Map() ;(fallbackRows || []).forEach((row) => { - const id = Number(row?.id) - if (!Number.isFinite(id)) return + const id = String(row?.id) + if (!id || id === 'undefined' || id === 'null') return fallbackMap.set(id, getRelationName(row, nameKeys, fallbackPrefix, id)) }) const parseArray = (source: unknown): any[] => { @@ -342,23 +342,23 @@ const normalizeRelationList = ( return parseArray(value) .map((item) => { if (typeof item === 'object' && item !== null) { - const id = Number((item as any).id) - if (!Number.isFinite(id)) return undefined + const id = String((item as any).id) + if (!id || id === 'undefined' || id === 'null') return undefined return { id, name: getRelationName(item as any, nameKeys, fallbackPrefix, id) } } - const id = Number(item) - if (!Number.isFinite(id)) return undefined + const id = String(item) + if (!id || id === 'undefined' || id === 'null') return undefined return { id, name: fallbackMap.get(id) || `${fallbackPrefix}ID:${id}` } }) - .filter((item): item is { id: number; name: string } => Boolean(item)) + .filter((item): item is { id: string; name: string } => Boolean(item)) } -const toDeviceRows = (devices: { id: number; name: string }[]) => { +const toDeviceRows = (devices: { id: string; name: string }[]) => { return devices.map((item) => ({ id: item.id, deviceName: item.name, @@ -625,7 +625,7 @@ const openDeviceRelationDialog = async (row: any) => { deviceRelationLoading.value = true selectedDeviceRows.value = [] try { - const productData = await ProductApi.getProduct(Number(row.productId)) + const productData = await ProductApi.getProduct(String(row.productId)) currentProductData.value = productData const devices = normalizeRelationList( (productData as any).devices ?? (productData as any).deviceIds, @@ -633,7 +633,7 @@ const openDeviceRelationDialog = async (row: any) => { ['name', 'deviceName', 'code'], t('ProductionPlan.TaskSummary.deviceColumnName') ) - deviceRelationForm.productId = Number(row.productId) + deviceRelationForm.productId = String(row.productId) deviceRelationForm.devices = devices selectedDeviceRows.value = toDeviceRows(devices) } finally { @@ -656,7 +656,7 @@ const handleDeviceSelectConfirm = (payload: { ids: (number | string)[]; rows: an name: item.deviceName || item.name || item.code || `${t('ProductionPlan.TaskSummary.deviceColumnName')}ID:${id}` } }) - .filter((item): item is { id: number; name: string } => Boolean(item)) + .filter((item): item is { id: string; name: string } => Boolean(item)) selectedDeviceRows.value = payload.rows } const refreshDetailListAfterDeviceSaved = async () => { From 95455f0f195ca083714577499c9116ccc4850756 Mon Sep 17 00:00:00 2001 From: hwj Date: Tue, 21 Jul 2026 16:37:53 +0800 Subject: [PATCH 2/4] =?UTF-8?q?style=EF=BC=9A=E7=89=A9=E8=81=94=E8=AE=BE?= =?UTF-8?q?=E5=A4=87-=E7=82=B9=E4=BD=8D=E7=B1=BB=E5=9E=8B=E5=BF=85?= =?UTF-8?q?=E5=A1=AB/=E5=80=8D=E7=8E=87=E7=A6=81=E7=94=A8=E5=8E=BB?= =?UTF-8?q?=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/iot/device/components/DeviceAttributeForm.vue | 5 +++-- .../iot/devicemodel/components/DeviceModelAttributeForm.vue | 3 +-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/views/iot/device/components/DeviceAttributeForm.vue b/src/views/iot/device/components/DeviceAttributeForm.vue index 31b3a270..17b35c37 100644 --- a/src/views/iot/device/components/DeviceAttributeForm.vue +++ b/src/views/iot/device/components/DeviceAttributeForm.vue @@ -38,7 +38,7 @@ v-model="formData.dataUnit" clearable + :decision="2" :step="0.01" class="!w-full" /> + class="!w-full"/> Date: Tue, 21 Jul 2026 17:41:59 +0800 Subject: [PATCH 3/4] =?UTF-8?q?feat:=20=E8=AE=BE=E5=A4=87=E5=8F=B0?= =?UTF-8?q?=E8=B4=A6/=E7=BB=B4=E4=BF=AE=E5=B7=A5=E5=8D=95/=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E8=AE=A1=E5=88=92/=E7=82=B9=E6=A3=80=E4=BF=9D?= =?UTF-8?q?=E5=85=BB=E5=B7=A5=E5=8D=95/=E6=A8=A1=E5=85=B7=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E9=A1=B5=E9=9D=A2=E5=A2=9E=E5=8A=A0=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E7=BB=9F=E8=AE=A1=E5=8D=A1=E7=89=87=EF=BC=8C=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E6=90=9C=E7=B4=A2=E6=A1=86=E5=B1=95=E5=BC=80=E6=94=B6=E8=B5=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/locales/zh-CN.ts | 20 ++++ src/views/erp/mold/index.vue | 12 +- src/views/erp/stock/overview/index.vue | 16 ++- src/views/mes/deviceledger/index.vue | 106 ++++++++++++++++-- src/views/mes/dvrepair/DvRepairForm.vue | 13 ++- src/views/mes/dvrepair/index.vue | 88 ++++++++++++++- .../mes/taskManagement/TaskManagementForm.vue | 38 ++++++- src/views/mes/taskManagement/index.vue | 99 +++++++++++++++- src/views/mes/workOrderManagement/index.vue | 86 ++++++++++++++ src/views/mold/moldrepair/index.vue | 85 +++++++++++++- src/views/mold/taskConfiguration/index.vue | 80 ++++++++++++- src/views/mold/workOrderInquiry/index.vue | 86 ++++++++++++++ 12 files changed, 692 insertions(+), 37 deletions(-) diff --git a/src/locales/zh-CN.ts b/src/locales/zh-CN.ts index b0ccae2f..1b96d3be 100644 --- a/src/locales/zh-CN.ts +++ b/src/locales/zh-CN.ts @@ -2007,7 +2007,11 @@ export default { validatorDeviceCodeRequired: '编码不能为空', gjTitle: '选择关键件', bjTitle: '选择备件', + all: '全部', normal: '正常', + disabled: '停用', + scheduled: '已排产', + unscheduled: '未排产', stop: '停用', maintenance: '维修', scrap: '报废', @@ -2149,6 +2153,7 @@ export default { // 任务管理 TaskManagement: { + all: '全部', name: '名称', taskType: '类型', taskTypeInspect: '点检', @@ -2159,6 +2164,7 @@ export default { planEndDate: '计划结束时间', cronExpression: 'cron 表达式', enabled: '启用', + disabled: '未启用', creatorName: '创建人', createTime: '创建时间', updateTime: '更新时间', @@ -2199,11 +2205,17 @@ export default { // 工单管理 WorkOrderManagement: { + all: '全部', basicInfo: '基本信息', planNo: '单号', planType: '类型', planTypeInspect: '点检', planTypeMaintain: '保养', + unworked: '未作业', + worked: '已作业', + overtimeUnworked: '超时未作业', + overtimeWorked: '超时已作业', + canceled: '取消', jobStatus: '作业状态', jobResult: '结果', deviceName: '设备名称', @@ -2253,6 +2265,7 @@ export default { // 维修单 DvRepair: { + all: '全部', repairCode: '维修单号', repairName: '维修单', machineryName: '设备名称', @@ -3115,6 +3128,7 @@ export default { }, MoldRepair: { + all: '全部', moduleName: '维修单', basicInfo: '基本信息', faultInfo: '故障信息', @@ -3322,12 +3336,18 @@ export default { }, MoldWorkOrderInquiry: { + all: '全部', moduleName: '工单查询', basicInfo: '基本信息', planNo: '单号', planType: '类型', planTypeInspect: '点检', planTypeMaintain: '保养', + unworked: '未作业', + worked: '已作业', + overtimeUnworked: '超时未作业', + overtimeWorked: '超时已作业', + canceled: '取消', jobStatus: '作业状态', jobResult: '结果', jobResultOk: '通过', diff --git a/src/views/erp/mold/index.vue b/src/views/erp/mold/index.vue index 776a03dd..5cc8210d 100644 --- a/src/views/erp/mold/index.vue +++ b/src/views/erp/mold/index.vue @@ -230,9 +230,9 @@ const onKeywordClear = () => { const statusCards = computed(() => [ { key: 'all', label: t('MoldManagement.MoldBrandPage.all'), value: counters.allCount, status: undefined }, - { key: 'onMachine', label: t('MoldManagement.MoldBrandPage.onMachine'), value: counters.onMachineCount, status: 1 }, + { key: 'onMachine', label: t('MoldManagement.MoldBrandPage.onMachine'), value: counters.onMachineCount, status: 0 }, { key: 'inStock', label: t('MoldManagement.MoldBrandPage.inStock'), value: counters.inStockCount, status: 4 }, - { key: 'standby', label: t('MoldManagement.MoldBrandPage.standby'), value: counters.standbyCount, status: 0 }, + { key: 'standby', label: t('MoldManagement.MoldBrandPage.standby'), value: counters.standbyCount, status: 1 }, { key: 'repairing', label: t('MoldManagement.MoldBrandPage.repairing'), value: counters.repairingCount, status: 2 }, { key: 'scrapped', label: t('MoldManagement.MoldBrandPage.scrapped'), value: counters.scrappedCount, status: 3 } ]) @@ -458,12 +458,12 @@ onBeforeUnmount(() => { diff --git a/src/views/erp/stock/overview/index.vue b/src/views/erp/stock/overview/index.vue index b35b8fe4..1cb72397 100644 --- a/src/views/erp/stock/overview/index.vue +++ b/src/views/erp/stock/overview/index.vue @@ -33,8 +33,7 @@
- +
{{ item.title }}
@@ -45,7 +44,7 @@
{{ item.tip }}
- +
@@ -507,13 +506,22 @@ onMounted(async () => { } .stock-overview__card-wrap { + padding: 16px 18px; + border: 1px solid var(--el-border-color-light); + border-radius: 12px; + background: #fff; + cursor: pointer; + transition: box-shadow 0.2s ease; margin-bottom: 0 !important; + + &:hover { + box-shadow: 0 10px 24px rgba(64, 158, 255, 0.12); + } } .stock-overview__card { display: flex; justify-content: space-between; - min-height: 174px; } .stock-overview__card-main { diff --git a/src/views/mes/deviceledger/index.vue b/src/views/mes/deviceledger/index.vue index 09fd7cde..67a622ba 100644 --- a/src/views/mes/deviceledger/index.vue +++ b/src/views/mes/deviceledger/index.vue @@ -143,12 +143,19 @@
+
+
+
{{ card.label }}
+
{{ card.value }}
+
+
- + + + + + {{ showAllFilters ? t('FactoryModeling.FactoryStructure.collapseText') : t('FactoryModeling.FactoryStructure.expandText') }} + + @@ -678,20 +695,47 @@ const loading = ref(true) // 列表的加载中 const list = ref([]) // 列表的数据 const total = ref(0) // 列表的总页数 const selectedDeviceLineId = ref(undefined) +const currentStatusKey = ref('all') +const counters = reactive({ + allCount: 0, + normalCount: 0, + disabledCount: 0, + scheduledCount: 0, + unscheduledCount: 0 +}) +const statusCards = computed(() => [ + { key: 'all', label: t('EquipmentManagement.EquipmentLedger.all'), value: counters.allCount, status: undefined, isSchedueld: undefined }, + { key: 'normal', label: t('EquipmentManagement.EquipmentLedger.normal'), value: counters.normalCount, status: 0, isSchedueld: undefined }, + { key: 'disabled', label: t('EquipmentManagement.EquipmentLedger.disabled'), value: counters.disabledCount, status: 1, isSchedueld: undefined }, + { key: 'scheduled', label: t('EquipmentManagement.EquipmentLedger.scheduled'), value: counters.scheduledCount, status: undefined, isSchedueld: 1 }, + { key: 'unscheduled', label: t('EquipmentManagement.EquipmentLedger.unscheduled'), value: counters.unscheduledCount, status: undefined, isSchedueld: 0 } +]) +const changeStatus = (key: string, status?: number, isSchedueld?: number) => { + currentStatusKey.value = key + queryParams.deviceStatus = status + queryParams.isSchedueld = isSchedueld + handleQuery() +} const queryParams = reactive({ pageNo: 1, pageSize: 10, deviceCode: undefined, deviceName: undefined, - deviceStatus: undefined, + deviceStatus: undefined as number | undefined, deviceBrand: undefined, sn: undefined, outgoingTime: undefined, deviceType: undefined as string | undefined, - deviceLine: undefined as string | undefined + deviceLine: undefined as string | undefined, + isSchedueld: undefined as number | undefined }) const queryFormRef = ref() // 搜索的表单 const exportLoading = ref(false) +const showAllFilters = ref(false) +const filterCount = 7 +const toggleFilters = () => { + showAllFilters.value = !showAllFilters.value +} const tableRef = ref() const planTableMaxHeight = ref(520) @@ -1012,10 +1056,16 @@ const getList = async () => { sn: queryParams.sn, outgoingTime: queryParams.outgoingTime, deviceType: queryParams.deviceType, - deviceLine: queryParams.deviceLine + deviceLine: queryParams.deviceLine, + isScheduled: queryParams.isSchedueld }) - list.value = data.list - total.value = data.total + list.value = data.list ?? [] + total.value = data.total ?? 0 + counters.allCount = Number(data?.allCount ?? data?.total ?? 0) + counters.normalCount = Number(data?.normalCount ?? 0) + counters.disabledCount = Number(data?.disabledCount ?? 0) + counters.scheduledCount = Number(data?.scheduledCount ?? 0) + counters.unscheduledCount = Number(data?.unscheduledCount ?? 0) } finally { loading.value = false updatePlanTableMaxHeight() @@ -1031,6 +1081,9 @@ const handleQuery = () => { /** 重置按钮操作 */ const resetQuery = () => { queryFormRef.value.resetFields() + currentStatusKey.value = 'all' + queryParams.deviceStatus = undefined + queryParams.isSchedueld = undefined handleQuery() } @@ -1122,6 +1175,45 @@ onBeforeUnmount(() => { min-width: 0; } +.device-ledger__header { + display: grid; + grid-template-columns: repeat(5, minmax(0, 1fr)); + gap: 12px; + width: 100%; + margin-bottom: 16px; +} + +.device-ledger__stat { + padding: 16px 18px; + border: 1px solid var(--el-border-color-light); + border-radius: 12px; + cursor: pointer; + transition: box-shadow 0.2s ease; + background: #fff; + + &:hover { + box-shadow: 0 10px 24px rgba(64, 158, 255, 0.12); + } + + &.is-active { + border-color: var(--el-color-primary); + box-shadow: 0 10px 24px rgba(64, 158, 255, 0.12); + } +} + +.device-ledger__stat-title { + color: var(--el-text-color-regular); + font-size: 14px; +} + +.device-ledger__stat-value { + margin-top: 8px; + color: var(--el-text-color-primary); + font-size: 28px; + font-weight: 700; + line-height: 1; +} + .simple-grid-view { background-color: #fff; border-radius: 4px; diff --git a/src/views/mes/dvrepair/DvRepairForm.vue b/src/views/mes/dvrepair/DvRepairForm.vue index 8386317e..7d7d6219 100644 --- a/src/views/mes/dvrepair/DvRepairForm.vue +++ b/src/views/mes/dvrepair/DvRepairForm.vue @@ -727,14 +727,14 @@ const ensureDeviceOptionsLoaded = async () => { } } -const deviceTypeNameMap = ref>({}) +const deviceTypeNameMap = ref>({}) const buildDeviceTypeNameMap = (nodes: DeviceTypeTreeVO[]) => { - const map: Record = {} + const map: Record = {} const walk = (list: DeviceTypeTreeVO[]) => { list.forEach((node) => { - if (typeof node?.id === 'number') { - map[node.id] = node.name ?? '' + if (node?.id != null) { + map[String(node.id)] = node.name ?? '' } if (Array.isArray(node?.children)) walk(node.children) }) @@ -744,8 +744,9 @@ const buildDeviceTypeNameMap = (nodes: DeviceTypeTreeVO[]) => { } const getDeviceTypeName = (value: any) => { - const id = typeof value === 'number' ? value : Number(value) - if (!Number.isNaN(id) && deviceTypeNameMap.value[id]) return deviceTypeNameMap.value[id] + if (value == null || value === '') return '-' + const key = String(value) + if (deviceTypeNameMap.value[key]) return deviceTypeNameMap.value[key] return value ?? '-' } diff --git a/src/views/mes/dvrepair/index.vue b/src/views/mes/dvrepair/index.vue index ca8f25c3..28c54a9f 100644 --- a/src/views/mes/dvrepair/index.vue +++ b/src/views/mes/dvrepair/index.vue @@ -2,6 +2,13 @@