From 6a381598dfad3f810ff419c33743f43d8241225e Mon Sep 17 00:00:00 2001 From: liutao <790864623@qq.com> Date: Wed, 10 Jun 2026 14:36:15 +0800 Subject: [PATCH 01/13] =?UTF-8?q?=E8=AE=BE=E5=A4=87=E8=8B=B1=E6=96=87?= =?UTF-8?q?=E8=BD=AC=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/locales/en-US.js | 8 +++++++- src/locales/index.js | 3 ++- src/locales/zh-CN.js | 8 +++++++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/locales/en-US.js b/src/locales/en-US.js index 79f8846..d3fcb84 100644 --- a/src/locales/en-US.js +++ b/src/locales/en-US.js @@ -20,6 +20,12 @@ export default { work: 'Manage', mine: 'Mine' }, + work:{ + mold: '模具', + equipmentMaintenance: 'Equipment Maintenance', + keypart: '关键件', + spare: '备件', + }, nav: { home: 'Home', mine: 'Profile', @@ -835,7 +841,7 @@ export default { confirmDeleteContent: 'Confirm delete category [{name}]?' }, equipmentLedger: { - moduleName: 'Equipment Ledger', + moduleName: 'Equipment Ledger11', subTitle: 'Equipment ledger management', detailTitle: 'Equipment Detail', basicInfo: 'Basic Info', diff --git a/src/locales/index.js b/src/locales/index.js index 0f309b8..1ab9806 100644 --- a/src/locales/index.js +++ b/src/locales/index.js @@ -129,7 +129,8 @@ const literalMap = { '模具详情': 'moldLedger.detailTitle', '模具点检': 'moldCheck.moduleName', '点检详情': 'moldCheck.detailTitle', - '新增点检': 'moldCheck.addTitle' + '新增点检': 'moldCheck.addTitle', + '设备运维': 'work.equipmentMaintenance' } export function getCurrentLocale() { diff --git a/src/locales/zh-CN.js b/src/locales/zh-CN.js index 3dcec29..08b62df 100644 --- a/src/locales/zh-CN.js +++ b/src/locales/zh-CN.js @@ -20,6 +20,12 @@ export default { work: '管理', mine: '我的' }, + work:{ + mold: '模具', + equipmentMaintenance: '设备运维', + keypart: '关键件', + spare: '备件', + }, nav: { home: '首页', mine: '个人中心', @@ -905,7 +911,7 @@ export default { repairCompleted: '已完成' }, equipmentMaintenance: { - moduleName: '设备维修', + moduleName: '设备维修22', createTitle: '新增设备维修', editTitle: '编辑设备维修', detailTitle: '设备维修详情', From aedb97f568814345c289b7788b063c74f0cb3c01 Mon Sep 17 00:00:00 2001 From: hwj Date: Fri, 12 Jun 2026 10:07:19 +0800 Subject: [PATCH 02/13] =?UTF-8?q?style=EF=BC=9A=E6=A8=A1=E5=85=B7=E4=BF=9D?= =?UTF-8?q?=E5=85=BB-=E4=BF=AE=E5=A4=8D=E4=B8=8A=E4=BC=A0=E5=9B=BE?= =?UTF-8?q?=E7=89=87=E7=BB=84=E4=BB=B6=E4=B9=B1=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages_function/pages/moldMaintain/detail.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages_function/pages/moldMaintain/detail.vue b/src/pages_function/pages/moldMaintain/detail.vue index 2360f1b..d15d304 100644 --- a/src/pages_function/pages/moldMaintain/detail.vue +++ b/src/pages_function/pages/moldMaintain/detail.vue @@ -87,7 +87,7 @@ mode="aspectFill" @click="previewImage(img, parseImages(item.images))" /> - + × + From 57d3f180453fc36040151e12093e60f862d77496 Mon Sep 17 00:00:00 2001 From: hwj Date: Fri, 12 Jun 2026 12:47:48 +0800 Subject: [PATCH 03/13] =?UTF-8?q?style=EF=BC=9A=E6=A8=A1=E5=85=B7=E7=82=B9?= =?UTF-8?q?=E6=A3=80/=E4=BF=9D=E5=85=BB-=E4=BF=9D=E5=AD=98=E5=90=8E?= =?UTF-8?q?=E5=88=B7=E6=96=B0=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/manifest.json | 4 +- src/pages_function/pages/moldCheck/detail.vue | 5 +- .../pages/moldMaintain/detail.vue | 5 +- src/pages_function/pages/moldRepair/index.vue | 60 +------------------ 4 files changed, 11 insertions(+), 63 deletions(-) diff --git a/src/manifest.json b/src/manifest.json index e4641a7..069ad36 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -22,7 +22,9 @@ "delay" : 0 }, /* 模块配置 */ - "modules" : {}, + "modules" : { + "Camera" : {} + }, /* 应用发布信息 */ "distribute" : { /* android打包配置 */ diff --git a/src/pages_function/pages/moldCheck/detail.vue b/src/pages_function/pages/moldCheck/detail.vue index 0cf626a..f5a972a 100644 --- a/src/pages_function/pages/moldCheck/detail.vue +++ b/src/pages_function/pages/moldCheck/detail.vue @@ -82,10 +82,10 @@ × @@ -346,6 +346,7 @@ async function handleSave() { try { await batchUpdateMoldCheckResults(payload) detailData.jobStatus = 1 + uni.setStorageSync('moldCheckListNeedRefresh', '1') uni.showToast({ title: t('functionCommon.saveSuccess'), icon: 'success' }) await fetchResults() } catch (error) { diff --git a/src/pages_function/pages/moldMaintain/detail.vue b/src/pages_function/pages/moldMaintain/detail.vue index d15d304..3703069 100644 --- a/src/pages_function/pages/moldMaintain/detail.vue +++ b/src/pages_function/pages/moldMaintain/detail.vue @@ -82,10 +82,10 @@ × @@ -346,6 +346,7 @@ async function handleSave() { try { await batchUpdateMoldCheckResults(payload) detailData.jobStatus = 1 + uni.setStorageSync('moldMaintainListNeedRefresh', '1') uni.showToast({ title: t('functionCommon.saveSuccess'), icon: 'success' }) await fetchResults() } catch (error) { diff --git a/src/pages_function/pages/moldRepair/index.vue b/src/pages_function/pages/moldRepair/index.vue index 6f9e446..4b9d9b5 100644 --- a/src/pages_function/pages/moldRepair/index.vue +++ b/src/pages_function/pages/moldRepair/index.vue @@ -24,9 +24,6 @@ {{ t('functionCommon.reset') }} - - - Date: Mon, 15 Jun 2026 11:56:58 +0800 Subject: [PATCH 04/13] =?UTF-8?q?=E4=B8=AD=E8=8B=B1=E6=96=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/locales/en-US.js | 6 +++--- src/locales/zh-CN.js | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/locales/en-US.js b/src/locales/en-US.js index 097a7f0..38a2237 100644 --- a/src/locales/en-US.js +++ b/src/locales/en-US.js @@ -521,7 +521,7 @@ export default { creatorName: 'Creator', createTime: 'Created At', updateTime: 'Updated At', - searchPlaceholder: 'Enter task name', + searchPlaceholder: 'Enter task name/device code/device name', empty: 'No equipment inspection tasks', createTicketSuccess: 'Work order created successfully', createTicketFail: 'Work order creation failed', @@ -549,7 +549,7 @@ export default { jobResultOk: 'Pass', jobResultNg: 'Fail', taskTime: 'Job Time', - searchPlaceholder: 'Enter task no.', + searchPlaceholder: 'Enter task no/device code/device name', empty: 'No equipment inspection records', progressTitle: 'Progress', inspectionMethod: 'Inspection Method', @@ -961,7 +961,7 @@ export default { autoCode: 'Auto Generate', deviceLabel: 'Equipment', reportTimeLabel: 'Report Time', - searchPlaceholder: 'Enter order no. or equipment code', + searchPlaceholder: 'Enter order no/device code/device name', empty: 'No repair records', statusPending: 'Pending Repair', statusPassed: 'Passed', diff --git a/src/locales/zh-CN.js b/src/locales/zh-CN.js index 7b3ff6b..bfed97e 100644 --- a/src/locales/zh-CN.js +++ b/src/locales/zh-CN.js @@ -521,7 +521,7 @@ export default { creatorName: '创建人', createTime: '创建时间', updateTime: '更新时间', - searchPlaceholder: '请输入任务名称', + searchPlaceholder: '请输入任务名称/设备编码/设备名称', empty: '暂无设备点检任务数据', createTicketSuccess: '工单创建成功', createTicketFail: '工单创建失败', @@ -549,7 +549,7 @@ export default { jobResultOk: '通过', jobResultNg: '不通过', taskTime: '作业时间', - searchPlaceholder: '请输入任务编号', + searchPlaceholder: '请输入任务编号/设备编码/设备名称', empty: '暂无设备点检记录数据', progressTitle: '执行进度', inspectionMethod: '检验方式', @@ -926,7 +926,7 @@ export default { repairCompleted: '已完成' }, equipmentMaintenance: { - moduleName: '设备维修22', + moduleName: '设备维修', createTitle: '新增设备维修', editTitle: '编辑设备维修', detailTitle: '设备维修详情', @@ -964,7 +964,7 @@ export default { autoCode: '自动生成', deviceLabel: '设备', reportTimeLabel: '报修时间', - searchPlaceholder: '请输入单号或设备编码', + searchPlaceholder: '请输入单号/设备编码/设备名称', empty: '暂无维修记录', statusPending: '待维修', statusPassed: '通过', From 93329264fbe23cbc17aa56b781795b9b777d5b05 Mon Sep 17 00:00:00 2001 From: zhongwenkai <3478244299@qq.com> Date: Mon, 15 Jun 2026 15:40:04 +0800 Subject: [PATCH 05/13] =?UTF-8?q?feat=EF=BC=9A=E4=BB=93=E5=82=A8=E7=AE=A1?= =?UTF-8?q?=E7=90=86-=E5=A4=87=E4=BB=B6=E5=85=A5=E5=BA=93=E6=A8=A1?= =?UTF-8?q?=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/mes/moldget.js | 9 + src/api/mes/sparepart.js | 13 + src/api/mes/sparepartInbound.js | 36 + src/locales/zh-CN.js | 45 +- src/pages.json | 24 + .../pages/sparepartInbound/create.vue | 1002 +++++++++++++++++ .../pages/sparepartInbound/index.vue | 594 ++++++++++ .../sparepartInbound/sparepartSelect.vue | 295 +++++ .../pages/sparepartInbound/userSelect.vue | 0 src/utils/permissionMenu.js | 4 + 10 files changed, 2020 insertions(+), 2 deletions(-) create mode 100644 src/api/mes/sparepart.js create mode 100644 src/api/mes/sparepartInbound.js create mode 100644 src/pages_function/pages/sparepartInbound/create.vue create mode 100644 src/pages_function/pages/sparepartInbound/index.vue create mode 100644 src/pages_function/pages/sparepartInbound/sparepartSelect.vue create mode 100644 src/pages_function/pages/sparepartInbound/userSelect.vue diff --git a/src/api/mes/moldget.js b/src/api/mes/moldget.js index 44fdb21..c1d333a 100644 --- a/src/api/mes/moldget.js +++ b/src/api/mes/moldget.js @@ -61,3 +61,12 @@ export function getSimpleUserList() { method: 'get' }) } + +// 仓库库区列表(根据仓库ID获取) +export function getWarehouseAreaSimpleList(warehouseId) { + return request({ + url: '/admin-api/erp/warehouse-area/simple-list', + method: 'get', + params: { warehouseId } + }) +} diff --git a/src/api/mes/sparepart.js b/src/api/mes/sparepart.js new file mode 100644 index 0000000..7b7ba32 --- /dev/null +++ b/src/api/mes/sparepart.js @@ -0,0 +1,13 @@ +import request from '@/utils/request' + +// 备件列表(分页查询全部产品,前端按 categoryType=5 过滤备件) +export function getSparepartSimpleList(pageNo = 1) { + return request({ + url: '/admin-api/erp/product/page', + method: 'get', + params: { + pageNo, + pageSize: 100 + } + }) +} diff --git a/src/api/mes/sparepartInbound.js b/src/api/mes/sparepartInbound.js new file mode 100644 index 0000000..c4ff7a8 --- /dev/null +++ b/src/api/mes/sparepartInbound.js @@ -0,0 +1,36 @@ +import request from '@/utils/request' + +// 备件入库单创建 +export function createSparepartInbound(data) { + return request({ + url: '/admin-api/erp/stock-in/create', + method: 'post', + data: { ...data, inType: '备件入库' } + }) +} +// 备件入库单分页查询(待入库/待审核) +export function getSparepartInboundPage(params = {}) { + return request({ + url: '/admin-api/erp/stock-in/page', + method: 'get', + params: { ...params, inType: '备件入库' } + }) +} + +// 备件入库单审核(status: 20=通过, 1=驳回) +export function auditSparepartInbound(data) { + return request({ + url: '/admin-api/erp/stock-in/audit', + method: 'put', + data + }) +} + +// 备件入库单删除 +export function deleteSparepartInbound(id) { + return request({ + url: '/admin-api/erp/stock-in/delete', + method: 'delete', + params: { ids: String(id) } + }) +} diff --git a/src/locales/zh-CN.js b/src/locales/zh-CN.js index ea2ae7f..4529fc8 100644 --- a/src/locales/zh-CN.js +++ b/src/locales/zh-CN.js @@ -749,7 +749,7 @@ export default { barCode: '物料条码', name: '物料名称', category: '物料分类', - unit: '单位', + unit: '库存单位', standard: '规格', expiryDay: '保质期天数', status: '状态', @@ -787,7 +787,7 @@ export default { code: 'BOM编码', version: '版本', product: '产品', - unit: '单位', + unit: '库存单位', yieldRate: '良品率', isEnable: '是否启用', enableYes: '是', @@ -1364,5 +1364,46 @@ export default { validatorRepairStatusRequired: '请选择维修结果', validatorFinishDateRequired: '请选择完成日期', validatorConfirmDateRequired: '请选择验收日期' + }, + sparepartInbound: { + moduleName: '备件入库', + tabPending: '待提交', + tabAuditing: '待审核', + searchPlaceholder: '搜索入库单号', + sparepartInfo: '备件信息', + inboundTime: '入库时间', + creator: '创建人', + quantity: '数量', + reviewer: '审核人', + approve: '已通过', + reject: '驳回', + confirmApprove: '确定审核通过该入库单吗?', + confirmReject: '确定驳回该入库单吗?', + approveSuccess: '审核通过', + rejectSuccess: '已驳回', + deleteSuccess: '删除成功', + empty: '暂无入库单据', + createTitle: '新增备件入库', + scanSparepart: '扫备件码', + selectSparepart: '选择备件', + searchSparepartPlaceholder: '搜索备件编码/名称', + sparepartCode: '备件编码', + category: '分类', + spec: '规格', + unit: '库存单位', + purchaseUnit: '采购单位', + convertRatio: '换算关系', + defaultWarehouse: '默认仓库/库区', + selectSparepart: '选择备件', + selectedSpareparts: '已选备件', + noSelectedSparepart: '请扫码或选择备件', + alreadySelected: '该备件已添加', + confirmRemove: '确定移除此备件吗?', + currentStock: '当前库存', + minStockUnit: '最小库存单位', + inboundQuantity: '入库数量', + qtyPlaceholder: '请输入', + noSparepartData: '暂无备件数据', + validatorSparepartRequired: '请选择备件' } } diff --git a/src/pages.json b/src/pages.json index 5ca6cd6..f4c1a77 100644 --- a/src/pages.json +++ b/src/pages.json @@ -365,6 +365,30 @@ "navigationStyle": "custom" } }, + { + "path": "sparepartInbound/index", + "style": { + "navigationBarTitleText": "备件入库", + "navigationStyle": "custom" + } + }, + { + "path": "sparepartInbound/create", + "style": { + "navigationBarTitleText": "新增备件入库", + "navigationStyle": "custom" + } + }, + + + { + "path": "sparepartInbound/sparepartSelect", + "style": { + "navigationBarTitleText": "选择备件", + "navigationStyle": "custom" + } + }, + { "path": "keypart/index", "style": { diff --git a/src/pages_function/pages/sparepartInbound/create.vue b/src/pages_function/pages/sparepartInbound/create.vue new file mode 100644 index 0000000..9c9c8ad --- /dev/null +++ b/src/pages_function/pages/sparepartInbound/create.vue @@ -0,0 +1,1002 @@ + + + + + diff --git a/src/pages_function/pages/sparepartInbound/index.vue b/src/pages_function/pages/sparepartInbound/index.vue new file mode 100644 index 0000000..bdc7497 --- /dev/null +++ b/src/pages_function/pages/sparepartInbound/index.vue @@ -0,0 +1,594 @@ + + + + + diff --git a/src/pages_function/pages/sparepartInbound/sparepartSelect.vue b/src/pages_function/pages/sparepartInbound/sparepartSelect.vue new file mode 100644 index 0000000..7730636 --- /dev/null +++ b/src/pages_function/pages/sparepartInbound/sparepartSelect.vue @@ -0,0 +1,295 @@ + + + + + diff --git a/src/pages_function/pages/sparepartInbound/userSelect.vue b/src/pages_function/pages/sparepartInbound/userSelect.vue new file mode 100644 index 0000000..e69de29 diff --git a/src/utils/permissionMenu.js b/src/utils/permissionMenu.js index f61f7e5..ef56ef7 100644 --- a/src/utils/permissionMenu.js +++ b/src/utils/permissionMenu.js @@ -87,6 +87,10 @@ const MENU_ROUTE_MAP = { mold: '/pages_function/pages/mold/index', equipment: '/pages_function/pages/equipment/index', spare: '/pages_function/pages/spare/index', + sparepartInbound: '/pages_function/pages/sparepartInbound/index', + sparepartinbound: '/pages_function/pages/sparepartInbound/index', + sparepartIn: '/pages_function/pages/sparepartInbound/index', + '备件入库': '/pages_function/pages/sparepartInbound/index', keypart: '/pages_function/pages/keypart/index', product: '/pages_function/pages/product/index' } From 14ae8b653485b204f4182a3900699a6d9034316c Mon Sep 17 00:00:00 2001 From: zhongwenkai <3478244299@qq.com> Date: Tue, 16 Jun 2026 10:18:38 +0800 Subject: [PATCH 06/13] =?UTF-8?q?feat=EF=BC=9A=E4=BB=93=E5=82=A8=E7=AE=A1?= =?UTF-8?q?=E7=90=86-=E5=A4=87=E4=BB=B6=E5=87=BA=E5=BA=93=E6=A8=A1?= =?UTF-8?q?=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/mes/sparepart.js | 9 + src/api/mes/sparepartOutbound.js | 28 + src/locales/zh-CN.js | 20 + src/pages.json | 14 + .../pages/sparepartInbound/create.vue | 71 +- .../pages/sparepartOutbound/create.vue | 711 ++++++++++++++++++ .../pages/sparepartOutbound/index.vue | 594 +++++++++++++++ src/utils/permissionMenu.js | 2 + 8 files changed, 1435 insertions(+), 14 deletions(-) create mode 100644 src/api/mes/sparepartOutbound.js create mode 100644 src/pages_function/pages/sparepartOutbound/create.vue create mode 100644 src/pages_function/pages/sparepartOutbound/index.vue diff --git a/src/api/mes/sparepart.js b/src/api/mes/sparepart.js index 7b7ba32..1afc49a 100644 --- a/src/api/mes/sparepart.js +++ b/src/api/mes/sparepart.js @@ -11,3 +11,12 @@ export function getSparepartSimpleList(pageNo = 1) { } }) } + +// 备件详情(含供应商、图片等完整信息) +export function getSparepartDetail(id) { + return request({ + url: '/admin-api/erp/product/get', + method: 'get', + params: { id } + }) +} diff --git a/src/api/mes/sparepartOutbound.js b/src/api/mes/sparepartOutbound.js new file mode 100644 index 0000000..5325f84 --- /dev/null +++ b/src/api/mes/sparepartOutbound.js @@ -0,0 +1,28 @@ +import request from '@/utils/request' + +// 备件出库单分页查询 +export function getSparepartOutboundPage(params = {}) { + return request({ + url: '/admin-api/erp/stock-out/page', + method: 'get', + params: { ...params, outType: '备件出库' } + }) +} + +// 备件出库单审核(status: 20=通过, 1=驳回) +export function auditSparepartOutbound(data) { + return request({ + url: '/admin-api/erp/stock-out/audit', + method: 'put', + data + }) +} + +// 备件出库单删除 +export function deleteSparepartOutbound(id) { + return request({ + url: '/admin-api/erp/stock-out/delete', + method: 'delete', + params: { ids: String(id) } + }) +} diff --git a/src/locales/zh-CN.js b/src/locales/zh-CN.js index 41327b8..ef11324 100644 --- a/src/locales/zh-CN.js +++ b/src/locales/zh-CN.js @@ -1411,5 +1411,25 @@ export default { qtyPlaceholder: '请输入', noSparepartData: '暂无备件数据', validatorSparepartRequired: '请选择备件' + }, + sparepartOutbound: { + moduleName: '备件出库', + tabPending: '待提交', + tabAuditing: '待审核', + searchPlaceholder: '搜索出库单号', + sparepartInfo: '备件信息', + outboundTime: '出库时间', + creator: '创建人', + quantity: '数量', + reviewer: '审核人', + approve: '已通过', + reject: '驳回', + confirmApprove: '确定审核通过该出库单吗?', + confirmReject: '确定驳回该出库单吗?', + approveSuccess: '审核通过', + rejectSuccess: '已驳回', + deleteSuccess: '删除成功', + empty: '暂无出库单据', + createTitle: '新增备件出库' } } diff --git a/src/pages.json b/src/pages.json index f4c1a77..169b348 100644 --- a/src/pages.json +++ b/src/pages.json @@ -388,6 +388,20 @@ "navigationStyle": "custom" } }, + { + "path": "sparepartOutbound/index", + "style": { + "navigationBarTitleText": "备件出库", + "navigationStyle": "custom" + } + }, + { + "path": "sparepartOutbound/create", + "style": { + "navigationBarTitleText": "新增备件出库", + "navigationStyle": "custom" + } + }, { "path": "keypart/index", diff --git a/src/pages_function/pages/sparepartInbound/create.vue b/src/pages_function/pages/sparepartInbound/create.vue index 9c9c8ad..6bafaee 100644 --- a/src/pages_function/pages/sparepartInbound/create.vue +++ b/src/pages_function/pages/sparepartInbound/create.vue @@ -30,8 +30,8 @@ @@ -107,17 +107,16 @@ - + 供应商 - + - - {{ supplierInfo.name || '请选择供应商' }} + + {{ defaultSupplierName || '未配置默认供应商' }} - @@ -236,12 +235,37 @@ import { useI18n } from 'vue-i18n' import NavBar from '@/components/common/NavBar.vue' import { getSimpleUserList, getWarehouseSimpleList, getWarehouseAreaSimpleList } from '@/api/mes/moldget' import { createSparepartInbound } from '@/api/mes/sparepartInbound' +import { getSparepartDetail } from '@/api/mes/sparepart' const { t } = useI18n() const selectedSparepart = ref({}) const inboundQty = ref(null) -const supplierInfo = ref({}) + +// 备件默认供应商(从备件数据中取) +const defaultSupplierName = computed(() => { + const suppliers = selectedSparepart.value.suppliers + const defaultId = selectedSparepart.value.defaultSupplierId + if (!suppliers || !suppliers.length) return '' + if (defaultId) { + const found = suppliers.find(s => s.supplierId === defaultId || s.id === defaultId) + if (found) return found.supplierName || '' + } + // 没配默认供应商,取第一个标记为默认的 + const firstDefault = suppliers.find(s => s.defaultStatus === 1) + return firstDefault?.supplierName || '' +}) +const defaultSupplierId = computed(() => { + const suppliers = selectedSparepart.value.suppliers + const defaultId = selectedSparepart.value.defaultSupplierId + if (!suppliers || !suppliers.length) return undefined + if (defaultId) { + const found = suppliers.find(s => s.supplierId === defaultId || s.id === defaultId) + if (found) return found.supplierId || found.id + } + const firstDefault = suppliers.find(s => s.defaultStatus === 1) + return firstDefault?.supplierId || firstDefault?.id +}) // 经办人下拉 const operatorOptions = ref([]) @@ -259,6 +283,14 @@ const selectedArea = ref(null) const showAreaDropdown = ref(false) const loadingAreas = ref(false) +// 备件图片(后端返回 images 字段,逗号分隔多图 URL,取第一张) +const sparepartImage = computed(() => { + const images = selectedSparepart.value.images + if (!images) return '' + if (Array.isArray(images)) return String(images[0] || '') + return String(images).split(',')[0]?.trim() || '' +}) + // 折算后库存数量 const calculatedStock = computed(() => { const qty = Number(inboundQty.value) || 0 @@ -308,10 +340,6 @@ function handleSelectSparepart() { }) } -function handleSelectSupplier() { - uni.showToast({ title: '选择供应商功能开发中', icon: 'none' }) -} - function toggleOperatorDropdown() { showOperatorDropdown.value = !showOperatorDropdown.value } @@ -422,7 +450,7 @@ async function handleSubmit() { isCode: true, inTime: Date.now(), stockUserId: String(selectedOperator.value.value), - supplierId: undefined, + supplierId: defaultSupplierId.value, status: 0, totalCount: count, totalPrice: 0, @@ -457,10 +485,25 @@ async function handleSubmit() { } } -onShow(() => { +onShow(async () => { const selectResult = getApp().globalData?._sparepartSelectResult if (selectResult) { selectedSparepart.value = selectResult + console.log('[sparepartInbound] 已选备件 suppliers:', JSON.stringify(selectResult.suppliers)) + console.log('[sparepartInbound] 已选备件 defaultSupplierId:', selectResult.defaultSupplierId) + // 补充获取备件详情(含供应商、图片等) + if (selectResult.id) { + try { + const res = await getSparepartDetail(selectResult.id) + const detail = res?.data || res + if (detail && detail.suppliers) { + console.log('[sparepartInbound] 详情接口 suppliers:', JSON.stringify(detail.suppliers)) + selectedSparepart.value = { ...selectedSparepart.value, ...detail } + } + } catch (e) { + console.error('获取备件详情失败:', e) + } + } inboundQty.value = null getApp().globalData._sparepartSelectResult = null } diff --git a/src/pages_function/pages/sparepartOutbound/create.vue b/src/pages_function/pages/sparepartOutbound/create.vue new file mode 100644 index 0000000..005d667 --- /dev/null +++ b/src/pages_function/pages/sparepartOutbound/create.vue @@ -0,0 +1,711 @@ + + + + + diff --git a/src/pages_function/pages/sparepartOutbound/index.vue b/src/pages_function/pages/sparepartOutbound/index.vue new file mode 100644 index 0000000..985b2a6 --- /dev/null +++ b/src/pages_function/pages/sparepartOutbound/index.vue @@ -0,0 +1,594 @@ + + + + + diff --git a/src/utils/permissionMenu.js b/src/utils/permissionMenu.js index ef56ef7..f431de9 100644 --- a/src/utils/permissionMenu.js +++ b/src/utils/permissionMenu.js @@ -88,6 +88,8 @@ const MENU_ROUTE_MAP = { equipment: '/pages_function/pages/equipment/index', spare: '/pages_function/pages/spare/index', sparepartInbound: '/pages_function/pages/sparepartInbound/index', + sparepartoutbound: '/pages_function/pages/sparepartOutbound/index', + '备件出库': '/pages_function/pages/sparepartOutbound/index', sparepartinbound: '/pages_function/pages/sparepartInbound/index', sparepartIn: '/pages_function/pages/sparepartInbound/index', '备件入库': '/pages_function/pages/sparepartInbound/index', From f81e94ea2ba42985f7ea353afe89257236246f90 Mon Sep 17 00:00:00 2001 From: hwj Date: Tue, 16 Jun 2026 10:46:09 +0800 Subject: [PATCH 07/13] =?UTF-8?q?style=EF=BC=9A=E8=8F=9C=E5=8D=95=E4=B8=AD?= =?UTF-8?q?=E8=8B=B1=E6=96=87=E9=80=82=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/PermissionMenuPage.vue | 25 +++++++++++++------- src/components/common/TabBar.vue | 5 ++-- src/pages_mine/pages/setting/index.vue | 2 +- src/utils/permissionMenu.js | 16 ++++++++++--- 4 files changed, 32 insertions(+), 16 deletions(-) diff --git a/src/components/common/PermissionMenuPage.vue b/src/components/common/PermissionMenuPage.vue index 8e1b115..314a4e5 100644 --- a/src/components/common/PermissionMenuPage.vue +++ b/src/components/common/PermissionMenuPage.vue @@ -37,7 +37,7 @@ - {{ translateLiteral(module.name) }} + {{ getDisplayName(module) }} @@ -60,9 +60,9 @@ size="24" :color="getModuleColor(moduleIndex)" > - {{ getMenuSymbol(entry.name, entryIndex) }} + {{ getMenuSymbol(getDisplayName(entry), entryIndex) }} - {{ translateLiteral(entry.name) }} + {{ getDisplayName(entry) }} @@ -77,10 +77,10 @@ diff --git a/src/pages_function/pages/moldoperate/dismount.vue b/src/pages_function/pages/moldoperate/dismount.vue index ada878e..acd1683 100644 --- a/src/pages_function/pages/moldoperate/dismount.vue +++ b/src/pages_function/pages/moldoperate/dismount.vue @@ -80,16 +80,6 @@ {{ t('moldOperate.product') }} {{ textValue(selectedMold.productName) }} - - {{ t('moldOperate.mountTime') }} - {{ textValue(selectedMold.mountTime) }} - - - - - {{ t('moldOperate.useCount') }} - {{ formatUseCount(selectedMold.useCount) }} - @@ -117,40 +107,15 @@ {{ t('moldOperate.operator') + ' & ' + t('moldOperate.remark') }} - - - - *{{ t('moldOperate.operator') }} - - - - {{ selectedOperator ? selectedOperator.label : t('moldOperate.placeholderOperator') }} - - - - - - - {{ item.label }} - - - 暂无数据 - + + + + *{{ t('moldOperate.operator') }} + + {{ currentUserName }} - {{ t('moldOperate.remark') }} @@ -202,11 +167,17 @@ import { computed, reactive, ref } from 'vue' import { onShow } from '@dcloudio/uni-app' import { useI18n } from 'vue-i18n' import NavBar from '@/components/common/NavBar.vue' -import { getLowerMoldList, getDeviceLedgerList, createMoldOperate } from '@/api/mes/moldoperate' +import { getDeviceLedgerList, createMoldOperate } from '@/api/mes/moldoperate' +import { getMoldBrandPage } from '@/api/mes/mold' +import useUserStore from '@/store/modules/user' import { getDeviceLineTree } from '@/api/mes/deviceLine' -import { getSimpleUserList } from '@/api/system/user' const { t } = useI18n() +const userStore = useUserStore() + +// 当前登录用户 +const currentUserName = computed(() => userStore.name || '未知用户') +const currentUserId = computed(() => userStore.userId) const lineInfoMap = ref(new Map()) // deviceLine id → { name, parentId, parentChain } @@ -282,10 +253,7 @@ const tempSelectedMoldId = ref(null) // ---- 操作人与备注 ---- const remarkText = ref('') -const operatorOptions = ref([]) const selectedOperator = ref(null) -const operatorIndex = ref(-1) -const showOperatorDropdown = ref(false) // ---- 工具函数 ---- function textValue(v) { @@ -295,12 +263,7 @@ function textValue(v) { return s || '-' } -function formatUseCount(count) { - if (count == null) return '-' - const num = Number(count) - if (isNaN(num)) return String(count) - return num.toLocaleString() + ' ' + t('moldOperate.countUnit') -} + function formatTime(time) { if (!time) return '-' @@ -374,45 +337,20 @@ function findArr(obj, d = 0) { return [] } -async function loadLowerMolds(deviceId) { +async function loadLowerMolds(deviceName) { lowerMoldLoading.value = true try { - // ====== 策略1:优先从持久化存储读取(按设备ID索引,不会互覆盖)====== - let map = {} - try { map = uni.getStorageSync('_mountedMoldInfoMap') || {} } catch {} - const savedInfo = map[String(deviceId)] || null - - console.log('[下模] 持久化在机模具信息 =', savedInfo ? JSON.stringify(savedInfo) : 'null', 'deviceId=', deviceId) - - if (savedInfo && savedInfo.mold) { - console.log('[下模] 命中持久化数据, deviceId=', deviceId) - const m = savedInfo.mold - lowerMoldOptions.value = [{ - id: m.id, - moldId: m.id, - moldName: m.name || m.moldName || '-', - moldCode: m.code || m.moldCode || '-', - productName: m.productName || '-', - mountTime: formatTime(savedInfo.mountTime), - useCount: '-' - }] - console.log('[下模] 使用持久化数据 =', JSON.stringify(lowerMoldOptions.value[0])) - return - } - console.log('[下模] 未命中持久化数据,进入接口查询') - - // ====== 策略2:fallback - 调用在机模具接口 ====== - let list = [] - try { - const res = await getLowerMoldList(deviceId) - const root = (res && res.data !== undefined) ? res.data : res - list = findArr(root) - } catch (apiErr) { - console.warn('[下模] getLowerMoldList 接口异常', apiErr) - } - - lowerMoldOptions.value = list - console.log('[下模] loadLowerMolds 返回 list.length =', list.length) + const res = await getMoldBrandPage({ deviceName, pageSize: 100 }) + const root = (res && res.data !== undefined) ? res.data : res + const pageData = root?.pageResult || root + const list = Array.isArray(pageData) ? pageData : (Array.isArray(pageData?.list) ? pageData.list : []) + lowerMoldOptions.value = list.map(m => ({ + id: m.id, + moldId: m.id, + moldName: m.name || '-', + moldCode: m.code || '-', + productName: m.productName || '-' + })) } catch (e) { console.error('loadLowerMolds error', e) } finally { @@ -450,8 +388,8 @@ function selectDevice(device) { selectedDevice.value = device || {} moldsLoaded.value = false selectedMold.value = {} - if (device?.id) { - loadLowerMolds(device.id).then(() => { + if (device?.deviceName) { + loadLowerMolds(device.deviceName).then(() => { moldsLoaded.value = true if (lowerMoldOptions.value.length > 0) { const first = lowerMoldOptions.value[0] @@ -459,9 +397,7 @@ function selectDevice(device) { id: first.id || first.moldId, moldName: first.moldName || first.name, moldCode: first.moldCode || first.code, - productName: first.productName || '-', - mountTime: first.mountTime || '-', - useCount: first.useCount ?? '-' + productName: first.productName || '-' } } }) @@ -475,12 +411,12 @@ function openDevicePicker() { // ---- 在机模具选择(更换下模对象)---- function openLowerMoldPicker() { - if (!selectedDevice.value?.id) { + if (!selectedDevice.value?.deviceName) { uni.showToast({ title: t('moldOperate.validatorDeviceRequired'), icon: 'none' }) return } tempSelectedMoldId.value = selectedMold.value ? String(selectedMold.value.id || selectedMold.value.moldId) : null - loadLowerMolds(selectedDevice.value.id).then(() => { + loadLowerMolds(selectedDevice.value.deviceName).then(() => { lowerMoldPickerRef.value?.open() }) } @@ -494,9 +430,7 @@ function confirmLowerMoldSelection() { id: mold.id || mold.moldId, moldName: mold.moldName || mold.name, moldCode: mold.moldCode || mold.code, - productName: mold.productName || '-', - mountTime: mold.mountTime || '-', - useCount: mold.useCount ?? '-' + productName: mold.productName || '-' } } lowerMoldPickerRef.value?.close() @@ -504,34 +438,16 @@ function confirmLowerMoldSelection() { function closeLowerMoldPicker() { lowerMoldPickerRef.value?.close() } -// ---- 操作人列表加载 ---- -async function loadOperators() { - try { - const res = await getSimpleUserList() - const data = Array.isArray(res) ? res : (Array.isArray(res?.data) ? res.data : []) - operatorOptions.value = data.map((u) => ({ - value: u.id || u.userId, - label: u.nickname || u.userName || u.name || String(u.id || '') - })) - } catch (e) { - console.error('loadOperators error', e) +// ---- 操作人自动设置为当前登录用户 ---- +function autoSetOperator() { + if (currentUserId.value && currentUserName.value) { + selectedOperator.value = { + value: currentUserId.value, + label: currentUserName.value + } } } -function toggleOperatorDropdown() { - showOperatorDropdown.value = !showOperatorDropdown.value -} - -function closeOperatorDropdown() { - showOperatorDropdown.value = false -} - -function handleSelectOperator(item, idx) { - selectedOperator.value = item - operatorIndex.value = idx - closeOperatorDropdown() -} - function goToHistory() { uni.navigateTo({ url: '/pages_function/pages/moldoperate/history?type=down' }) } @@ -578,21 +494,11 @@ async function handleConfirm() { console.log('[下模] 提交参数 =', JSON.stringify(payload)) await createMoldOperate(payload) uni.showToast({ title: t('functionCommon.createSuccess'), icon: 'success' }) - // 下模成功后清除该设备的持久化数据 - if (selectedDevice.value?.id) { - try { - const map = uni.getStorageSync('_mountedMoldInfoMap') || {} - delete map[String(selectedDevice.value.id)] - uni.setStorageSync('_mountedMoldInfoMap', map) - } catch {} - } // 重置表单 selectedDevice.value = {} selectedMold.value = {} lowerMoldOptions.value = [] remarkText.value = '' - selectedOperator.value = null - operatorIndex.value = -1 } catch (e) { console.error('[下模] 保存失败 =', e) const errMsg = e?.msg || (typeof e === 'string' ? e : e?.message) || '系统异常' @@ -608,7 +514,8 @@ function handleCancel() { } onShow(async () => { - await Promise.allSettled([loadDevices(), loadLineTree(), loadOperators()]) + autoSetOperator() + await Promise.allSettled([loadDevices(), loadLineTree()]) // 从 globalData 读取设备选择页回传的设备 const device = getApp().globalData._deviceSelectResult if (device) { @@ -854,6 +761,11 @@ onShow(async () => { font-size: 27rpx; color: #333; background: #f9fafb; + + &.readonly-input { + background: #f8fafc; + border-color: #f0f0f0; + } } .dropdown-value { diff --git a/src/pages_function/pages/moldoperate/index.vue b/src/pages_function/pages/moldoperate/index.vue index 656b25d..be8e0ff 100644 --- a/src/pages_function/pages/moldoperate/index.vue +++ b/src/pages_function/pages/moldoperate/index.vue @@ -115,35 +115,8 @@ *{{ t('moldOperate.operator') }} - - - - - {{ selectedOperator ? selectedOperator.label : t('moldOperate.placeholderOperator') }} - - - - - - - - {{ item.label }} - - - 暂无数据 - - + + {{ currentUserName }} @@ -176,9 +149,15 @@ import { onShow } from '@dcloudio/uni-app' import { useI18n } from 'vue-i18n' import NavBar from '@/components/common/NavBar.vue' import { getDeviceLedgerList, createMoldOperate } from '@/api/mes/moldoperate' -import { getSimpleUserList } from '@/api/system/user' +import { getMoldBrandPage } from '@/api/mes/mold' +import useUserStore from '@/store/modules/user' const { t } = useI18n() +const userStore = useUserStore() + +// 当前登录用户 +const currentUserName = computed(() => userStore.name || '未知用户') +const currentUserId = computed(() => userStore.userId) // ---- 工具函数 ---- function textValue(v) { @@ -217,9 +196,7 @@ const selectedDevice = ref({}) const selectedMountMolds = ref([]) const tempSelectedDeviceId = ref(null) const remarkText = ref('') -const operatorOptions = ref([]) const selectedOperator = ref(null) -const operatorIndex = ref(-1) // 设备状态 - 上模 const deviceStatusClass = computed(() => { @@ -241,7 +218,7 @@ const deviceStatusLabel = computed(() => { return map[status] || textValue(selectedDevice.value?.deviceStatus) || '-' }) -const MOLD_STATUS_MAP = { 0: '在机', 1: '待用', 2: '维修', 3: '报废' } +const MOLD_STATUS_MAP = { 0: '在机', 1: '待用', 2: '维修', 3: '报废', 4: '在库' } function getMoldStatusText(s) { return MOLD_STATUS_MAP[s] || textValue(s) } function getMoldStatusClass(s) { if (s === 0) return 'inuse-tag' @@ -250,91 +227,54 @@ function getMoldStatusClass(s) { return 'standby-tag' } -// ---- 持久化在机模具信息(按设备ID索引,避免多设备覆盖)---- -const MOUNTED_MOLD_KEY = '_mountedMoldInfoMap' -function getMountedMoldMap() { - try { - const data = uni.getStorageSync(MOUNTED_MOLD_KEY) || {} - return data - } catch (e) { - console.warn('[上模] getMountedMoldMap 异常', e) - return {} +// 当前在机模具 - 通过模具分页接口查询(machineId = 当前设备ID) +const currentMoldList = ref([]) + +async function fetchCurrentMolds(deviceName) { + if (!deviceName) { + currentMoldList.value = [] + return } -} -function getMountedMoldByDevice(deviceId) { - if (!deviceId) return null - const map = getMountedMoldMap() - const key = String(deviceId) - return map[key] || null -} -function saveMountedMoldInfo(info) { - if (!info || !info.deviceId) return try { - const map = getMountedMoldMap() - map[String(info.deviceId)] = info - uni.setStorageSync(MOUNTED_MOLD_KEY, map) - console.log('[上模] saveMountedMoldInfo 写入成功, deviceId=', info.deviceId, 'map keys=', Object.keys(map)) + // 查模具型号表,按当前设备名称筛选 + const params = { deviceName, pageSize: 100 } + console.log('[上模] fetchCurrentMolds 请求参数:', JSON.stringify(params)) + const res = await getMoldBrandPage(params) + console.log('[上模] fetchCurrentMolds 原始响应:', JSON.stringify(res)) + const root = res && res.data !== undefined ? res.data : res + const pageData = root?.pageResult || root + const list = Array.isArray(pageData) ? pageData : (Array.isArray(pageData?.list) ? pageData.list : []) + console.log('[上模] fetchCurrentMolds 解析后:', list.length, '条数据', list.map(m => ({ id: m.id, name: m.name, currentDevice: m.currentDevice }))) + currentMoldList.value = list } catch (e) { - console.warn('[上模] saveMountedMoldInfo 异常', e) + console.error('fetchCurrentMolds error', e) + currentMoldList.value = [] } } -function clearMountedMoldInfo(deviceId) { - if (!deviceId) { - try { uni.removeStorageSync(MOUNTED_MOLD_KEY) } catch {} - return - } - try { - const map = getMountedMoldMap() - delete map[String(deviceId)] - uni.setStorageSync(MOUNTED_MOLD_KEY, map) - } catch {} -} -// 当前在机模具 - 优先从持久化存储获取(实时),否则用设备台账静态字段 const currentMoldDisplay = computed(() => { if (!selectedDevice.value?.id) return '-' - const saved = getMountedMoldByDevice(selectedDevice.value.id) - if (saved) { - console.log('[上模] currentMoldDisplay 命中持久化, deviceId=', selectedDevice.value.id, 'mold=', saved.mold?.name || saved.mold?.moldName) - return saved.mold?.name || saved.mold?.moldName || '-' + if (currentMoldList.value.length > 0) { + return currentMoldList.value.map(m => m.name || '').filter(Boolean).join(',') || '-' } - return textValue(selectedDevice.value.currentMold) + return t('moldOperate.noMoldOnDevice') }) -// ---- 操作人列表加载 ---- -async function loadOperators() { - try { - const res = await getSimpleUserList() - const data = Array.isArray(res) ? res : (Array.isArray(res?.data) ? res.data : []) - operatorOptions.value = data.map((u) => ({ - value: u.id || u.userId, - label: u.nickname || u.userName || u.name || String(u.id || '') - })) - } catch (e) { - console.error('loadOperators error', e) +// ---- 操作人自动设置为当前登录用户 ---- +function autoSetOperator() { + if (currentUserId.value && currentUserName.value) { + selectedOperator.value = { + value: currentUserId.value, + label: currentUserName.value + } } } -const showOperatorDropdown = ref(false) - -function toggleOperatorDropdown() { - showOperatorDropdown.value = !showOperatorDropdown.value -} - -function closeOperatorDropdown() { - showOperatorDropdown.value = false -} - -function handleSelectOperator(item, idx) { - selectedOperator.value = item - operatorIndex.value = idx - closeOperatorDropdown() -} - function selectDevice(device) { selectedDevice.value = device || {} tempSelectedDeviceId.value = device ? device.id : null selectedMountMolds.value = [] + if (device?.deviceName) fetchCurrentMolds(device.deviceName) } function openDevicePicker() { @@ -394,22 +334,6 @@ async function handleConfirmMount() { console.log('=== 上模返回 ===', JSON.stringify(res)) uni.showToast({ title: t('functionCommon.createSuccess'), icon: 'success' }) - // 上模成功后持久化保存,供下模/设备选择页读取 - if (selectedMountMolds.value.length > 0) { - const info = { - deviceId: selectedDevice.value.id, - deviceCode: selectedDevice.value.deviceCode, - deviceName: selectedDevice.value.deviceName, - mold: selectedMountMolds.value[0], - mountTime: new Date().toLocaleString() - } - saveMountedMoldInfo(info) - // 同步到 globalData(兼容旧逻辑) - getApp().globalData._mountedMoldInfo = info - getApp().globalData._mountedMoldInfoMap = getMountedMoldMap() - console.log('=== 已保存在机模具信息 ===', JSON.stringify(info)) - } - selectedDevice.value = {} selectedMountMolds.value = [] } catch (e) { @@ -449,8 +373,6 @@ function handleCancel() { selectedDevice.value = {} selectedMountMolds.value = [] remarkText.value = '' - selectedOperator.value = null - operatorIndex.value = -1 // 返回上一页(管理页面) uni.navigateBack({ fail: () => uni.switchTab({ url: '/pages/work' }) @@ -462,7 +384,8 @@ function goToHistory() { } onShow(async () => { - await Promise.allSettled([loadDevices(), loadOperators()]) + autoSetOperator() + await Promise.allSettled([loadDevices()]) // 从 globalData 读取设备选择页回传的设备 const device = getApp().globalData._deviceSelectResult if (device) { @@ -706,6 +629,11 @@ onShow(async () => { font-size: 27rpx; color: #333; background: #f9fafb; + + &.readonly-input { + background: #f8fafc; + border-color: #f0f0f0; + } } .dropdown-value { diff --git a/src/pages_function/pages/moldoperate/moldSelect.vue b/src/pages_function/pages/moldoperate/moldSelect.vue index cfe4b3d..f867c66 100644 --- a/src/pages_function/pages/moldoperate/moldSelect.vue +++ b/src/pages_function/pages/moldoperate/moldSelect.vue @@ -77,7 +77,7 @@ function textValue(v) { return s || '-' } -const STATUS_MAP = { 0: '在机', 1: '待用', 2: '维修', 3: '报废' } +const STATUS_MAP = { 0: '在机', 1: '待用', 2: '维修', 3: '报废', 4: '在库' } function getStatusText(s) { return STATUS_MAP[s] || textValue(s) } function getStatusClass(s) { if (s === 0) return 'in-use-tag' @@ -87,9 +87,11 @@ function getStatusClass(s) { } const filteredList = computed(() => { + // 排除在机状态的模具(status=0),不能重复上模 + const available = moldList.value.filter(m => Number(m.status) !== 0) const keyword = searchText.value.trim().toLowerCase() - if (!keyword) return moldList.value - return moldList.value.filter((m) => { + if (!keyword) return available + return available.filter((m) => { return (m.name || '').toLowerCase().includes(keyword) || (m.code || '').toLowerCase().includes(keyword) || (m.productName || '').toLowerCase().includes(keyword) diff --git a/src/utils/permissionMenu.js b/src/utils/permissionMenu.js index f431de9..f40c1ed 100644 --- a/src/utils/permissionMenu.js +++ b/src/utils/permissionMenu.js @@ -311,10 +311,12 @@ export function resolveMenuUrl(menu) { return directRoute } - const keys = [menu?.component, menu?.path, menu?.enName, menu?.name] + // 优先用 menu.name(中文,最不容易冲突),再用 component/path + const keys = [menu?.name, menu?.enName, menu?.component, menu?.path] for (const key of keys) { const normalizedKey = normalizeMenuKey(key) if (normalizedKey && MENU_ROUTE_MAP[normalizedKey]) { + console.log('[resolveMenuUrl] menu.name="', menu?.name, '" matched key="', normalizedKey, '" → route="', MENU_ROUTE_MAP[normalizedKey], '"') return MENU_ROUTE_MAP[normalizedKey] } } From 6fbb7fbc5adc4db69774dd5ee073742e45da6442 Mon Sep 17 00:00:00 2001 From: hwj Date: Tue, 16 Jun 2026 14:30:47 +0800 Subject: [PATCH 09/13] =?UTF-8?q?style=EF=BC=9A=E6=9B=B4=E6=8D=A2=E5=8E=8B?= =?UTF-8?q?=E7=BD=91-=E5=8E=8B=E7=BD=91=E6=97=B6=E9=97=B4=E9=80=89?= =?UTF-8?q?=E6=8B=A9=E5=99=A8=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/locales/en-US.js | 4 ++ src/locales/zh-CN.js | 4 ++ .../pages/moldPressureNet/index.vue | 42 +++++++++++++++++-- 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/src/locales/en-US.js b/src/locales/en-US.js index 38a2237..6e9cec3 100644 --- a/src/locales/en-US.js +++ b/src/locales/en-US.js @@ -200,6 +200,7 @@ export default { loadFailed: 'Load failed', deleteSuccess: 'Deleted successfully', deleteFailed: 'Delete failed', + saveSuccess: 'Saved successfully', saveFailed: 'Save failed', createSuccess: 'Created successfully', updateSuccess: 'Updated successfully', @@ -1332,6 +1333,7 @@ export default { placeholderRequireDate: 'Select require date', placeholderAcceptedBy: 'Select repair user', placeholderConfirmBy: 'Select confirm user', + placeholderUserSearch: 'Search by nickname', placeholderMold: 'Select mold', placeholderMoldNameAuto: 'Auto filled', placeholderMoldCodeAuto: 'Auto filled', @@ -1351,6 +1353,7 @@ export default { moldNotFound: 'Mold not found', scanFailed: 'Scan failed', maxUploadCount: 'Max 9 images', + noUserData: 'No user data', saving: 'Saving', saveSuccess: 'Saved successfully', submitSuccess: 'Submitted successfully', @@ -1364,6 +1367,7 @@ export default { validatorFaultLevelRequired: 'Fault level is required', validatorIsShutdownRequired: 'Is shutdown is required', validatorFaultPhenomenonRequired: 'Fault phenomenon is required', + validatorUserRequired: 'Please select a user', validatorRepairStatusRequired: 'Repair result is required', validatorFinishDateRequired: 'Finish date is required', validatorConfirmDateRequired: 'Confirm date is required' diff --git a/src/locales/zh-CN.js b/src/locales/zh-CN.js index ef11324..29a25ba 100644 --- a/src/locales/zh-CN.js +++ b/src/locales/zh-CN.js @@ -200,6 +200,7 @@ export default { loadFailed: '加载失败', deleteSuccess: '删除成功', deleteFailed: '删除失败', + saveSuccess: '保存成功', saveFailed: '保存失败', createSuccess: '新增成功', updateSuccess: '更新成功', @@ -1335,6 +1336,7 @@ export default { placeholderRequireDate: '请选择报修日期', placeholderAcceptedBy: '请选择维修人员', placeholderConfirmBy: '请选择验收人员', + placeholderUserSearch: '请输入姓名搜索', placeholderMold: '请选择模具', placeholderMoldNameAuto: '自动带出', placeholderMoldCodeAuto: '自动带出', @@ -1354,6 +1356,7 @@ export default { moldNotFound: '未找到对应模具', scanFailed: '扫码失败', maxUploadCount: '最多上传 9 张图片', + noUserData: '暂无人员数据', saving: '保存中', saveSuccess: '保存成功', submitSuccess: '提交成功', @@ -1367,6 +1370,7 @@ export default { validatorFaultLevelRequired: '请选择故障等级', validatorIsShutdownRequired: '请选择是否停机', validatorFaultPhenomenonRequired: '请输入故障现象', + validatorUserRequired: '请选择人员', validatorRepairStatusRequired: '请选择维修结果', validatorFinishDateRequired: '请选择完成日期', validatorConfirmDateRequired: '请选择验收日期' diff --git a/src/pages_function/pages/moldPressureNet/index.vue b/src/pages_function/pages/moldPressureNet/index.vue index c901f4e..fa70621 100644 --- a/src/pages_function/pages/moldPressureNet/index.vue +++ b/src/pages_function/pages/moldPressureNet/index.vue @@ -83,7 +83,12 @@ {{ t('moldPressureNet.pressureNetTime') }}* - + {{ t('moldPressureNet.remark') }} @@ -317,6 +322,14 @@ function goHistory() { uni.navigateTo({ url: '/pages_function/pages/moldPressureNet/history' }) } +function onPressureNetTimeChange(value) { + const normalizedValue = normalizePressureNetTime(value) + pressureNetTime.value = normalizedValue + setTimeout(() => { + pressureNetTime.value = normalizePressureNetTime(pressureNetTime.value || value) || normalizedValue + }, 0) +} + async function handleSubmit() { if (submitLoading.value) return if (!selectedBrand.id) { @@ -327,7 +340,8 @@ async function handleSubmit() { uni.showToast({ title: t('moldPressureNet.selectSubMoldError'), icon: 'none' }) return } - if (!pressureNetTime.value) { + const normalizedPressureNetTime = normalizePressureNetTime(pressureNetTime.value) + if (!normalizedPressureNetTime) { uni.showToast({ title: t('moldPressureNet.selectReplaceTimeError'), icon: 'none' }) return } @@ -342,12 +356,12 @@ async function handleSubmit() { moldBrandName: selectedBrand.name, moldId: moldId, moldName: selected?.name || '', - pressureNetTime: pressureNetTime.value, + pressureNetTime: normalizedPressureNetTime, remark: remark.value.trim() || undefined } }) await createPressureNetRecord(createReqVOList) - uni.showToast({ title: t('moldPressureNet.submitSuccess'), icon: 'success' }) + uni.showToast({ title: t('functionCommon.saveSuccess'), icon: 'success' }) // 清空表单 selectedBrand.id = '' selectedBrand.name = '' @@ -362,6 +376,26 @@ async function handleSubmit() { submitLoading.value = false } } + +function normalizePressureNetTime(value) { + const text = String(value || '').trim().replace(/\//g, '-') + const dateOnlyMatch = text.match(/^(\d{4}-\d{2}-\d{2})(?:\s+(?:undefined|null|选择时间|select time))?$/i) + if (dateOnlyMatch) { + return `${dateOnlyMatch[1]} ${getCurrentTime()}` + } + const dateTimeMatch = text.match(/^(\d{4}-\d{2}-\d{2})[ T](\d{2}):(\d{2})(?::(\d{2}))?$/) + if (!dateTimeMatch) return '' + const [, date, hour, minute, second = '00'] = dateTimeMatch + return `${date} ${hour}:${minute}:${second}` +} + +function getCurrentTime() { + const date = new Date() + const hour = String(date.getHours()).padStart(2, '0') + const minute = String(date.getMinutes()).padStart(2, '0') + const second = String(date.getSeconds()).padStart(2, '0') + return `${hour}:${minute}:${second}` +} From 773e58c0afb0a0edaace2ce7d1350d47fdfe69e8 Mon Sep 17 00:00:00 2001 From: zhongwenkai <3478244299@qq.com> Date: Tue, 16 Jun 2026 15:56:54 +0800 Subject: [PATCH 11/13] =?UTF-8?q?style:=20=E4=B8=8A=E6=A8=A1/=E4=B8=8B?= =?UTF-8?q?=E6=A8=A1=E4=BF=AE=E5=A4=8D=E6=89=AB=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pages/moldoperate/deviceSelect.vue | 4 - .../pages/moldoperate/dismount.vue | 23 ++++- .../pages/moldoperate/index.vue | 97 +++++++++++++++++-- src/utils/permissionMenu.js | 1 - 4 files changed, 108 insertions(+), 17 deletions(-) diff --git a/src/pages_function/pages/moldoperate/deviceSelect.vue b/src/pages_function/pages/moldoperate/deviceSelect.vue index 8714cd9..cac770e 100644 --- a/src/pages_function/pages/moldoperate/deviceSelect.vue +++ b/src/pages_function/pages/moldoperate/deviceSelect.vue @@ -112,12 +112,9 @@ const deviceMoldMap = ref(new Map()) async function loadDeviceMolds() { try { const res = await getMoldBrandPage({ pageSize: 100 }) - console.log('[deviceSelect] getMoldBrandPage 原始响应:', JSON.stringify(res)) const root = res && res.data !== undefined ? res.data : res - console.log('[deviceSelect] root 类型:', typeof root, 'keys:', Object.keys(root || {})) const pageData = root?.pageResult || root const list = Array.isArray(pageData) ? pageData : (Array.isArray(pageData?.list) ? pageData.list : []) - console.log('[deviceSelect] 模具型号总数:', list.length, '前3条:', list.slice(0, 3).map(m => ({ name: m.name, deviceName: m.deviceName }))) const map = new Map() for (const mold of list) { const deviceName = mold.deviceName @@ -127,7 +124,6 @@ async function loadDeviceMolds() { } } deviceMoldMap.value = map - console.log('[deviceSelect] 在机模具映射表:', map.size, '个设备, keys:', [...map.keys()]) } catch (e) { console.error('loadDeviceMolds error', e) } diff --git a/src/pages_function/pages/moldoperate/dismount.vue b/src/pages_function/pages/moldoperate/dismount.vue index acd1683..8b11943 100644 --- a/src/pages_function/pages/moldoperate/dismount.vue +++ b/src/pages_function/pages/moldoperate/dismount.vue @@ -364,11 +364,26 @@ function handleScan() { onlyFromCamera: false, scanType: ['qrCode', 'barCode'], success(res) { - const code = res.result?.trim() + const code = (res.result || '').trim() if (!code) return - const matched = deviceOptions.value.find((d) => - d.raw.deviceCode === code || String(d.raw.code) === code || d.label.includes(code) - ) + let matched = null + if (code.toUpperCase().startsWith('EQUIPMENT-')) { + const idFromQr = code.replace(/EQUIPMENT-/i, '') + matched = deviceOptions.value.find((d) => String(d.raw.id) === idFromQr) + } + if (!matched) { + matched = deviceOptions.value.find((d) => + Object.values(d.raw).some((v) => + typeof v === 'string' && v.trim().toUpperCase() === code.toUpperCase() + ) || d.label.toUpperCase().includes(code.toUpperCase()) + ) + } + if (!matched) { + const idMatch = code.match(/(\d+)$/) + if (idMatch) { + matched = deviceOptions.value.find((d) => String(d.raw.id) === idMatch[1]) + } + } if (matched) { selectDevice(matched.raw) } else { diff --git a/src/pages_function/pages/moldoperate/index.vue b/src/pages_function/pages/moldoperate/index.vue index be8e0ff..20cbaf9 100644 --- a/src/pages_function/pages/moldoperate/index.vue +++ b/src/pages_function/pages/moldoperate/index.vue @@ -150,6 +150,7 @@ import { useI18n } from 'vue-i18n' import NavBar from '@/components/common/NavBar.vue' import { getDeviceLedgerList, createMoldOperate } from '@/api/mes/moldoperate' import { getMoldBrandPage } from '@/api/mes/mold' +import { getDeviceLineTree } from '@/api/mes/deviceLine' import useUserStore from '@/store/modules/user' const { t } = useI18n() @@ -190,6 +191,70 @@ async function loadDevices() { } } +// 产线树 - 用于设备产线名称转换 +const lineInfoMap = ref(new Map()) + +function flattenLineTree(nodes, parentId) { + if (!Array.isArray(nodes)) return + for (const node of nodes) { + if (node.id != null && node.name != null) { + lineInfoMap.value.set(String(node.id), { + id: node.id, + name: node.name, + parentId: node.parentId != null ? node.parentId : (parentId || null), + parentChain: node.parentChain || '' + }) + } + if (Array.isArray(node.children)) { + flattenLineTree(node.children, node.id) + } + } +} + +function getTopLineName(deviceLineId) { + if (deviceLineId == null) return '-' + const node = lineInfoMap.value.get(String(deviceLineId)) + if (!node) return '-' + if (node.parentChain) { + const firstId = node.parentChain.split(',')[0]?.trim() + if (firstId) { + const topNode = lineInfoMap.value.get(firstId) + if (topNode) return topNode.name + } + } + let current = node + const visited = new Set() + while (current.parentId != null && current.parentId > 0 && !visited.has(current.id)) { + visited.add(current.id) + const parent = lineInfoMap.value.get(String(current.parentId)) + if (!parent) break + current = parent + } + return current.name || '-' +} + +async function loadLineTree() { + if (lineInfoMap.value.size > 0) return + try { + const res = await getDeviceLineTree() + const tree = (res && res.data !== undefined) ? res.data : res + const nodes = Array.isArray(tree) ? tree : (tree?.list || tree?.children || []) + flattenLineTree(nodes) + } catch (e) { + console.error('load line tree error', e) + } +} + +// 设置设备产线名称(从产线树转换) +function setDeviceLineName(device) { + if (device && device.deviceLine != null) { + const lineName = getTopLineName(device.deviceLine) + if (lineName && lineName !== '-') { + device.workshopName = lineName + } + } +} + // ==================== 上模模块 ==================== const selectedDevice = ref({}) @@ -238,13 +303,10 @@ async function fetchCurrentMolds(deviceName) { try { // 查模具型号表,按当前设备名称筛选 const params = { deviceName, pageSize: 100 } - console.log('[上模] fetchCurrentMolds 请求参数:', JSON.stringify(params)) const res = await getMoldBrandPage(params) - console.log('[上模] fetchCurrentMolds 原始响应:', JSON.stringify(res)) const root = res && res.data !== undefined ? res.data : res const pageData = root?.pageResult || root const list = Array.isArray(pageData) ? pageData : (Array.isArray(pageData?.list) ? pageData.list : []) - console.log('[上模] fetchCurrentMolds 解析后:', list.length, '条数据', list.map(m => ({ id: m.id, name: m.name, currentDevice: m.currentDevice }))) currentMoldList.value = list } catch (e) { console.error('fetchCurrentMolds error', e) @@ -350,12 +412,31 @@ function handleScan() { onlyFromCamera: false, scanType: ['qrCode', 'barCode'], success(res) { - const code = res.result?.trim() + const code = (res.result || '').trim() if (!code) return - const matched = deviceOptions.value.find((d) => - d.raw.deviceCode === code || String(d.raw.code) === code || d.label.includes(code) - ) + let matched = null + // 格式1: EQUIPMENT-{设备ID} + if (code.toUpperCase().startsWith('EQUIPMENT-')) { + const idFromQr = code.replace(/EQUIPMENT-/i, '') + matched = deviceOptions.value.find((d) => String(d.raw.id) === idFromQr) + } + // 格式2: 匹配设备字段或 label + if (!matched) { + matched = deviceOptions.value.find((d) => + Object.values(d.raw).some((v) => + typeof v === 'string' && v.trim().toUpperCase() === code.toUpperCase() + ) || d.label.toUpperCase().includes(code.toUpperCase()) + ) + } + // 格式3: 提取末尾数字匹配设备ID + if (!matched) { + const idMatch = code.match(/(\d+)$/) + if (idMatch) { + matched = deviceOptions.value.find((d) => String(d.raw.id) === idMatch[1]) + } + } if (matched) { + setDeviceLineName(matched.raw) selectDevice(matched.raw) } else { uni.showToast({ title: t('moldOperate.deviceNotFound'), icon: 'none' }) @@ -385,7 +466,7 @@ function goToHistory() { onShow(async () => { autoSetOperator() - await Promise.allSettled([loadDevices()]) + await Promise.allSettled([loadDevices(), loadLineTree()]) // 从 globalData 读取设备选择页回传的设备 const device = getApp().globalData._deviceSelectResult if (device) { diff --git a/src/utils/permissionMenu.js b/src/utils/permissionMenu.js index baf5a51..885dbe5 100644 --- a/src/utils/permissionMenu.js +++ b/src/utils/permissionMenu.js @@ -317,7 +317,6 @@ export function resolveMenuUrl(menu) { for (const key of keys) { const normalizedKey = normalizeMenuKey(key) if (normalizedKey && MENU_ROUTE_MAP[normalizedKey]) { - console.log('[resolveMenuUrl] menu.name="', menu?.name, '" matched key="', normalizedKey, '" → route="', MENU_ROUTE_MAP[normalizedKey], '"') return MENU_ROUTE_MAP[normalizedKey] } } From 16d67cc1ddff0270b81b00ee7b2ac7705c84d97c Mon Sep 17 00:00:00 2001 From: hwj Date: Tue, 16 Jun 2026 16:59:55 +0800 Subject: [PATCH 12/13] =?UTF-8?q?style=EF=BC=9A=E6=9B=B4=E6=8D=A2=E5=8E=8B?= =?UTF-8?q?=E7=BD=91-=E5=8E=86=E5=8F=B2=E6=95=B0=E6=8D=AE=E6=8C=89?= =?UTF-8?q?=E9=92=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages_function/pages/moldPressureNet/index.vue | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/pages_function/pages/moldPressureNet/index.vue b/src/pages_function/pages/moldPressureNet/index.vue index fa70621..0bc0e87 100644 --- a/src/pages_function/pages/moldPressureNet/index.vue +++ b/src/pages_function/pages/moldPressureNet/index.vue @@ -3,8 +3,7 @@ @@ -400,8 +399,7 @@ function getCurrentTime() {