From 61172b9a685943e078023b7dae4cbae1755f4f7a Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 31 May 2026 10:21:23 +0800 Subject: [PATCH] =?UTF-8?q?fix(mes):=20=E4=BF=AE=E5=A4=8D=20MES=20?= =?UTF-8?q?=E8=BF=81=E7=A7=BB=20review=20=E5=8F=91=E7=8E=B0=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=EF=BC=88B001-B032=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 系统性修复 MES migration review(INDEX.md,MES-R001~R042)发现的迁移问题, 覆盖 web-antd 与 web-ele 两端,按严重级别从 P0 到 P3。 P0 - B001: DICT_TYPE/BarcodeBizTypeEnum 等常量从 'vue' 误导入致 TS2305/运行时崩溃, 改从 @vben/constants 导入(20 个文件)。 P1 - B002 itemreceipt 入库单名称误必填;B003 条码工单选择补 CONFIRMED 过滤; B004 库存台账冻结开关补更新权限禁用;B005 returnsales 上架明细批次号误必填; B006 checkrecord/maintenrecord 计划/执行人误必填;B007 returnsales 退货行 rqcCheckFlag 默认改回 false;B019 OQC 预填 checkQuantity 缺省取 outQuantity; B024 repair 完成维修态放开 finishDate 录入;B025 tool 编码管理类型库存数量锁定为 1; B027 详情态自动编码按钮隐藏/禁用(md/cal/dv/tm 13 模块)。 P2 - B008 IPQC 废品数量补 0 默认值;B009 共享选择器去掉 catch+console.error 吞错; B011 route 自定义 SFC 改 markRaw;B012 ele 自动编码按钮去 type:'default'; B014 md 编辑态编码字段误禁用;B015 dv/subject 选择器仅展示启用项(保留历史回显); B016 盘点结果回填 batchId;B017 源 vue3 miscissue 业务类型字典误用 getStrDictOptions; B018 stocktaking/plan 盘点条件表单 schema 化;B020 清理 TODO @AI; B026 repair 验收信息字段按状态门控只读。 P3 - B010 QcIndicatorSelect 去吞错;B013/B019/B030/B031 componentProps、列对象多行化等 code style;B021 自动编码循环方式列条件展示;B022 盘点结果选中清单行后字段禁用; B023 质检指标 resultSpecification 抽 ResultSpecificationInput 消除重复 fieldName; B032 barcode/batch/sn API 字段补注释。 风格统一 - getTitle 统一为「特殊态 if 提前 return + create/update 三元」(pro/card、 stocktaking/task、repair);headerReadonly 抽 isHeaderReadonly 辅助函数对齐 pro/workorder/transfer 写法;computed 解释注释移入 computed 内部。 验证: - 两端 pnpm exec eslint 改动文件通过 - 两端 pnpm -F @vben/web-antd / @vben/web-ele exec vue-tsc 过滤 src/views/mes、 api/mes 无报错 - git diff --check 通过 备注:R037(defectrecord 命名漂移)经复核为原 finding 前提有误(两端本就一致), 已 rejected,未占 MES-B 编号。R008/R009 为 disputed 待裁决。 本提交仅含 src/views/mes 与 src/api/mes 下文件,排除 .env.development、vite.config.ts、 infra/codegen、docs changelog 等无关旁支改动。 --- apps/web-antd/src/api/mes/wm/barcode/index.ts | 22 ++--- apps/web-antd/src/api/mes/wm/batch/index.ts | 32 +++---- apps/web-antd/src/api/mes/wm/sn/index.ts | 10 +-- apps/web-antd/src/views/mes/cal/plan/data.ts | 32 ++++--- .../src/views/mes/cal/plan/modules/form.vue | 2 +- apps/web-antd/src/views/mes/cal/team/data.ts | 32 ++++--- .../src/views/mes/cal/team/modules/form.vue | 2 +- .../src/views/mes/dv/checkplan/data.ts | 32 ++++--- .../views/mes/dv/checkplan/modules/form.vue | 2 +- .../src/views/mes/dv/machinery/data.ts | 27 +++--- .../src/views/mes/dv/machinery/type/data.ts | 37 +++++--- .../mes/dv/machinery/type/modules/form.vue | 4 +- apps/web-antd/src/views/mes/dv/repair/data.ts | 84 +++++++++++++++---- .../src/views/mes/dv/repair/modules/form.vue | 37 ++++---- .../web-antd/src/views/mes/dv/subject/data.ts | 32 ++++--- .../src/views/mes/dv/subject/modules/form.vue | 2 +- apps/web-antd/src/views/mes/md/client/data.ts | 36 ++++---- .../src/views/mes/md/client/modules/form.vue | 2 +- .../modules/product-sales-line-list.vue | 30 +++++-- .../md/client/modules/product-sales-list.vue | 18 +++- apps/web-antd/src/views/mes/md/item/data.ts | 36 ++++---- .../src/views/mes/md/item/modules/form.vue | 2 +- .../mes/md/item/modules/product-bom-form.vue | 28 +++++-- .../md/item/modules/product-media-list.vue | 25 ++++-- .../src/views/mes/md/item/type/data.ts | 39 +++++---- .../views/mes/md/item/type/modules/form.vue | 4 +- apps/web-antd/src/views/mes/md/vendor/data.ts | 36 ++++---- .../src/views/mes/md/vendor/modules/form.vue | 2 +- .../md/vendor/modules/item-receipt-detail.vue | 36 ++++++-- .../vendor/modules/item-receipt-line-list.vue | 30 +++++-- .../md/vendor/modules/item-receipt-list.vue | 36 ++++++-- .../src/views/mes/md/workstation/data.ts | 36 ++++---- .../views/mes/md/workstation/modules/form.vue | 2 +- .../md/workstation/modules/machine-list.vue | 29 +++++-- .../mes/md/workstation/modules/tool-list.vue | 29 +++++-- .../md/workstation/modules/worker-list.vue | 29 +++++-- .../views/mes/md/workstation/workshop/data.ts | 36 ++++---- .../md/workstation/workshop/modules/form.vue | 2 +- .../src/views/mes/pro/feedback/data.ts | 22 +++-- apps/web-antd/src/views/mes/pro/route/data.ts | 80 ++++++++++++++---- apps/web-antd/src/views/mes/tm/tool/data.ts | 52 ++++++++---- .../src/views/mes/tm/tool/modules/form.vue | 2 +- .../src/views/mes/tm/tool/type/data.ts | 32 ++++--- .../views/mes/tm/tool/type/modules/form.vue | 2 +- apps/web-ele/src/api/mes/wm/barcode/index.ts | 22 ++--- apps/web-ele/src/api/mes/wm/batch/index.ts | 32 +++---- apps/web-ele/src/api/mes/wm/sn/index.ts | 10 +-- apps/web-ele/src/views/mes/cal/plan/data.ts | 30 ++++--- .../src/views/mes/cal/plan/modules/form.vue | 2 +- apps/web-ele/src/views/mes/cal/team/data.ts | 30 ++++--- .../src/views/mes/cal/team/modules/form.vue | 2 +- .../src/views/mes/dv/checkplan/data.ts | 30 ++++--- .../views/mes/dv/checkplan/modules/form.vue | 2 +- .../src/views/mes/dv/machinery/data.ts | 25 +++--- .../src/views/mes/dv/machinery/type/data.ts | 35 +++++--- .../mes/dv/machinery/type/modules/form.vue | 4 +- apps/web-ele/src/views/mes/dv/repair/data.ts | 82 +++++++++++++++--- .../src/views/mes/dv/repair/modules/form.vue | 37 ++++---- apps/web-ele/src/views/mes/dv/subject/data.ts | 30 ++++--- .../src/views/mes/dv/subject/modules/form.vue | 2 +- apps/web-ele/src/views/mes/md/client/data.ts | 34 ++++---- .../src/views/mes/md/client/modules/form.vue | 2 +- .../modules/product-sales-line-list.vue | 30 +++++-- .../md/client/modules/product-sales-list.vue | 18 +++- apps/web-ele/src/views/mes/md/item/data.ts | 34 ++++---- .../src/views/mes/md/item/modules/form.vue | 2 +- .../mes/md/item/modules/product-bom-form.vue | 21 +++-- .../md/item/modules/product-media-list.vue | 19 ++++- .../src/views/mes/md/item/type/data.ts | 37 ++++---- .../views/mes/md/item/type/modules/form.vue | 4 +- apps/web-ele/src/views/mes/md/vendor/data.ts | 34 ++++---- .../src/views/mes/md/vendor/modules/form.vue | 2 +- .../md/vendor/modules/item-receipt-detail.vue | 36 ++++++-- .../vendor/modules/item-receipt-line-list.vue | 30 +++++-- .../md/vendor/modules/item-receipt-list.vue | 36 ++++++-- .../src/views/mes/md/workstation/data.ts | 34 ++++---- .../views/mes/md/workstation/modules/form.vue | 2 +- .../md/workstation/modules/machine-list.vue | 29 +++++-- .../mes/md/workstation/modules/tool-list.vue | 29 +++++-- .../md/workstation/modules/worker-list.vue | 29 +++++-- .../views/mes/md/workstation/workshop/data.ts | 34 ++++---- .../md/workstation/workshop/modules/form.vue | 2 +- .../src/views/mes/pro/feedback/data.ts | 16 +++- apps/web-ele/src/views/mes/pro/route/data.ts | 44 +++++++--- apps/web-ele/src/views/mes/tm/tool/data.ts | 50 ++++++++--- .../src/views/mes/tm/tool/modules/form.vue | 2 +- .../src/views/mes/tm/tool/type/data.ts | 30 ++++--- .../views/mes/tm/tool/type/modules/form.vue | 2 +- 88 files changed, 1465 insertions(+), 654 deletions(-) diff --git a/apps/web-antd/src/api/mes/wm/barcode/index.ts b/apps/web-antd/src/api/mes/wm/barcode/index.ts index 7e8154141..39673a3ae 100644 --- a/apps/web-antd/src/api/mes/wm/barcode/index.ts +++ b/apps/web-antd/src/api/mes/wm/barcode/index.ts @@ -5,17 +5,17 @@ import { requestClient } from '#/api/request'; export namespace MesWmBarcodeApi { /** MES 条码清单 */ export interface Barcode { - id?: number; - configId?: number; - format?: number; - bizType?: number; - content?: string; - bizId?: number; - bizCode?: string; - bizName?: string; - status?: number; - remark?: string; - createTime?: Date; + id?: number; // 条码编号 + configId?: number; // 条码配置编号 + format?: number; // 条码格式 + bizType?: number; // 业务类型 + content?: string; // 条码内容 + bizId?: number; // 业务对象编号 + bizCode?: string; // 业务对象编码 + bizName?: string; // 业务对象名称 + status?: number; // 状态 + remark?: string; // 备注 + createTime?: Date; // 创建时间 } } diff --git a/apps/web-antd/src/api/mes/wm/batch/index.ts b/apps/web-antd/src/api/mes/wm/batch/index.ts index 7ce0a76f9..14d5fa1bd 100644 --- a/apps/web-antd/src/api/mes/wm/batch/index.ts +++ b/apps/web-antd/src/api/mes/wm/batch/index.ts @@ -39,22 +39,22 @@ export namespace MesWmBatchApi { /** MES 批次分页查询参数 */ export interface PageParams extends PageParam { - code?: string; - itemId?: number; - vendorId?: number; - clientId?: number; - workOrderId?: number; - taskId?: number; - workstationId?: number; - toolId?: number; - moldId?: number; - salesOrderCode?: string; - purchaseOrderCode?: string; - lotNumber?: string; - qualityStatus?: number; - produceDate?: string[]; - expireDate?: string[]; - receiptDate?: string[]; + code?: string; // 批次号 + itemId?: number; // 物料编号 + vendorId?: number; // 供应商编号 + clientId?: number; // 客户编号 + workOrderId?: number; // 工单编号 + taskId?: number; // 生产任务编号 + workstationId?: number; // 工作站编号 + toolId?: number; // 工具编号 + moldId?: number; // 模具编号 + salesOrderCode?: string; // 销售订单号 + purchaseOrderCode?: string; // 采购订单号 + lotNumber?: string; // 批号 + qualityStatus?: number; // 质量状态 + produceDate?: string[]; // 生产日期 + expireDate?: string[]; // 过期日期 + receiptDate?: string[]; // 入库日期 } } diff --git a/apps/web-antd/src/api/mes/wm/sn/index.ts b/apps/web-antd/src/api/mes/wm/sn/index.ts index 5a733fa39..6970a796a 100644 --- a/apps/web-antd/src/api/mes/wm/sn/index.ts +++ b/apps/web-antd/src/api/mes/wm/sn/index.ts @@ -27,11 +27,11 @@ export namespace MesWmSnApi { /** MES SN 码分组分页查询参数 */ export interface PageParams extends PageParam { - uuid?: string; - code?: string; - itemId?: number; - batchCode?: string; - createTime?: string[]; + uuid?: string; // 分组 UUID + code?: string; // SN 码 + itemId?: number; // 物料编号 + batchCode?: string; // 批次号 + createTime?: string[]; // 创建时间 } } diff --git a/apps/web-antd/src/views/mes/cal/plan/data.ts b/apps/web-antd/src/views/mes/cal/plan/data.ts index c0c957956..2fcb12099 100644 --- a/apps/web-antd/src/views/mes/cal/plan/data.ts +++ b/apps/web-antd/src/views/mes/cal/plan/data.ts @@ -16,7 +16,10 @@ import { getRangePickerDefaultProps } from '#/utils'; export type FormType = 'create' | 'detail' | 'update'; /** 新增/修改排班计划的表单 */ -export function useFormSchema(formApi?: VbenFormApi): VbenFormSchema[] { +export function useFormSchema( + formType: FormType, + formApi?: VbenFormApi, +): VbenFormSchema[] { return [ { fieldName: 'id', @@ -43,18 +46,21 @@ export function useFormSchema(formApi?: VbenFormApi): VbenFormSchema[] { placeholder: '请输入计划编码', }, rules: 'required', - suffix: () => - h( - Button, - { - type: 'default', - onClick: async () => { - const code = await generateAutoCode(MesAutoCodeRuleCode.CAL_PLAN_CODE); - await formApi?.setFieldValue('code', code); - }, - }, - { default: () => '生成' }, - ), + suffix: + formType === 'detail' + ? undefined + : () => + h( + Button, + { + type: 'default', + onClick: async () => { + const code = await generateAutoCode(MesAutoCodeRuleCode.CAL_PLAN_CODE); + await formApi?.setFieldValue('code', code); + }, + }, + { default: () => '生成' }, + ), }, { fieldName: 'name', diff --git a/apps/web-antd/src/views/mes/cal/plan/modules/form.vue b/apps/web-antd/src/views/mes/cal/plan/modules/form.vue index c2402d002..3ecbda54e 100644 --- a/apps/web-antd/src/views/mes/cal/plan/modules/form.vue +++ b/apps/web-antd/src/views/mes/cal/plan/modules/form.vue @@ -103,11 +103,11 @@ const [Modal, modalApi] = useVbenModal({ formData.value = undefined; return; } - formApi.setState({ schema: useFormSchema(formApi) }); subTabsName.value = 'shift'; // 加载数据 const data = modalApi.getData<{ formType: FormType; id?: number }>(); formType.value = data.formType; + formApi.setState({ schema: useFormSchema(data.formType, formApi) }); formApi.setDisabled(formType.value === 'detail'); modalApi.setState({ showConfirmButton: formType.value !== 'detail' }); if (!data?.id) { diff --git a/apps/web-antd/src/views/mes/cal/team/data.ts b/apps/web-antd/src/views/mes/cal/team/data.ts index fac2487aa..fb28dd230 100644 --- a/apps/web-antd/src/views/mes/cal/team/data.ts +++ b/apps/web-antd/src/views/mes/cal/team/data.ts @@ -16,7 +16,10 @@ import { generateAutoCode } from '#/api/mes/md/autocode/record'; export type FormType = 'create' | 'detail' | 'update'; /** 新增/修改班组的表单 */ -export function useFormSchema(formApi?: VbenFormApi): VbenFormSchema[] { +export function useFormSchema( + formType: FormType, + formApi?: VbenFormApi, +): VbenFormSchema[] { return [ { fieldName: 'id', @@ -35,18 +38,21 @@ export function useFormSchema(formApi?: VbenFormApi): VbenFormSchema[] { placeholder: '请输入班组编码', }, rules: z.string().min(1, '班组编码不能为空').max(64), - suffix: () => - h( - Button, - { - type: 'default', - onClick: async () => { - const code = await generateAutoCode(MesAutoCodeRuleCode.CAL_TEAM_CODE); - await formApi?.setFieldValue('code', code); - }, - }, - { default: () => '生成' }, - ), + suffix: + formType === 'detail' + ? undefined + : () => + h( + Button, + { + type: 'default', + onClick: async () => { + const code = await generateAutoCode(MesAutoCodeRuleCode.CAL_TEAM_CODE); + await formApi?.setFieldValue('code', code); + }, + }, + { default: () => '生成' }, + ), }, { fieldName: 'name', diff --git a/apps/web-antd/src/views/mes/cal/team/modules/form.vue b/apps/web-antd/src/views/mes/cal/team/modules/form.vue index 388db173d..2406bcd43 100644 --- a/apps/web-antd/src/views/mes/cal/team/modules/form.vue +++ b/apps/web-antd/src/views/mes/cal/team/modules/form.vue @@ -79,11 +79,11 @@ const [Modal, modalApi] = useVbenModal({ formData.value = undefined; return; } - formApi.setState({ schema: useFormSchema(formApi) }); subTabsName.value = 'member'; // 加载数据 const data = modalApi.getData<{ formType: FormType; id?: number }>(); formType.value = data.formType; + formApi.setState({ schema: useFormSchema(data.formType, formApi) }); formApi.setDisabled(formType.value === 'detail'); modalApi.setState({ showConfirmButton: formType.value !== 'detail' }); if (!data?.id) { diff --git a/apps/web-antd/src/views/mes/dv/checkplan/data.ts b/apps/web-antd/src/views/mes/dv/checkplan/data.ts index 6c42eb7b3..bb77b4879 100644 --- a/apps/web-antd/src/views/mes/dv/checkplan/data.ts +++ b/apps/web-antd/src/views/mes/dv/checkplan/data.ts @@ -17,7 +17,10 @@ import { getRangePickerDefaultProps } from '#/utils'; export type FormType = 'create' | 'detail' | 'update'; /** 新增/修改点检保养方案的表单 */ -export function useFormSchema(formApi?: VbenFormApi): VbenFormSchema[] { +export function useFormSchema( + formType: FormType, + formApi?: VbenFormApi, +): VbenFormSchema[] { return [ { fieldName: 'id', @@ -44,18 +47,21 @@ export function useFormSchema(formApi?: VbenFormApi): VbenFormSchema[] { placeholder: '请输入方案编码', }, rules: 'required', - suffix: () => - h( - Button, - { - type: 'default', - onClick: async () => { - const code = await generateAutoCode(MesAutoCodeRuleCode.DV_CHECK_PLAN_CODE); - await formApi?.setFieldValue('code', code); - }, - }, - { default: () => '生成' }, - ), + suffix: + formType === 'detail' + ? undefined + : () => + h( + Button, + { + type: 'default', + onClick: async () => { + const code = await generateAutoCode(MesAutoCodeRuleCode.DV_CHECK_PLAN_CODE); + await formApi?.setFieldValue('code', code); + }, + }, + { default: () => '生成' }, + ), }, { fieldName: 'name', diff --git a/apps/web-antd/src/views/mes/dv/checkplan/modules/form.vue b/apps/web-antd/src/views/mes/dv/checkplan/modules/form.vue index 94b3f064d..391ab971d 100644 --- a/apps/web-antd/src/views/mes/dv/checkplan/modules/form.vue +++ b/apps/web-antd/src/views/mes/dv/checkplan/modules/form.vue @@ -78,11 +78,11 @@ const [Modal, modalApi] = useVbenModal({ formData.value = undefined; return; } - formApi.setState({ schema: useFormSchema(formApi) }); subTabsName.value = 'machinery'; // 加载数据 const data = modalApi.getData<{ formType: FormType; id?: number }>(); formType.value = data.formType; + formApi.setState({ schema: useFormSchema(data.formType, formApi) }); formApi.setDisabled(formType.value === 'detail'); modalApi.setState({ showConfirmButton: formType.value !== 'detail' }); if (!data?.id) { diff --git a/apps/web-antd/src/views/mes/dv/machinery/data.ts b/apps/web-antd/src/views/mes/dv/machinery/data.ts index b32f87ad9..b54a2c556 100644 --- a/apps/web-antd/src/views/mes/dv/machinery/data.ts +++ b/apps/web-antd/src/views/mes/dv/machinery/data.ts @@ -41,18 +41,21 @@ export function useFormSchema(formType: FormType, formApi?: VbenFormApi): VbenFo componentProps: (values) => ({ disabled: !!values.id }), }, rules: 'required', - suffix: () => - h( - Button, - { - type: 'default', - onClick: async () => { - const code = await generateAutoCode(MesAutoCodeRuleCode.DV_MACHINERY_CODE); - await formApi?.setFieldValue('code', code); - }, - }, - { default: () => '生成' }, - ), + suffix: + formType === 'detail' + ? undefined + : () => + h( + Button, + { + type: 'default', + onClick: async () => { + const code = await generateAutoCode(MesAutoCodeRuleCode.DV_MACHINERY_CODE); + await formApi?.setFieldValue('code', code); + }, + }, + { default: () => '生成' }, + ), }, { fieldName: 'name', diff --git a/apps/web-antd/src/views/mes/dv/machinery/type/data.ts b/apps/web-antd/src/views/mes/dv/machinery/type/data.ts index 604ea3054..5bdf07bf6 100644 --- a/apps/web-antd/src/views/mes/dv/machinery/type/data.ts +++ b/apps/web-antd/src/views/mes/dv/machinery/type/data.ts @@ -14,8 +14,14 @@ import { z } from '#/adapter/form'; import { getMachineryTypeList } from '#/api/mes/dv/machinery/type'; import { generateAutoCode } from '#/api/mes/md/autocode/record'; +/** 表单类型 */ +export type FormType = 'create' | 'detail' | 'update'; + /** 新增/修改设备类型的表单 */ -export function useFormSchema(formApi?: VbenFormApi): VbenFormSchema[] { +export function useFormSchema( + formType: FormType, + formApi?: VbenFormApi, +): VbenFormSchema[] { return [ { fieldName: 'id', @@ -52,18 +58,23 @@ export function useFormSchema(formApi?: VbenFormApi): VbenFormSchema[] { placeholder: '请输入类型编码', }, rules: z.string().min(1, '类型编码不能为空').max(64), - suffix: () => - h( - Button, - { - type: 'default', - onClick: async () => { - const code = await generateAutoCode(MesAutoCodeRuleCode.DV_MACHINERY_TYPE_CODE); - await formApi?.setFieldValue('code', code); - }, - }, - { default: () => '生成' }, - ), + suffix: + formType === 'detail' + ? undefined + : () => + h( + Button, + { + type: 'default', + onClick: async () => { + const code = await generateAutoCode( + MesAutoCodeRuleCode.DV_MACHINERY_TYPE_CODE, + ); + await formApi?.setFieldValue('code', code); + }, + }, + { default: () => '生成' }, + ), }, { fieldName: 'name', diff --git a/apps/web-antd/src/views/mes/dv/machinery/type/modules/form.vue b/apps/web-antd/src/views/mes/dv/machinery/type/modules/form.vue index 4a0269d17..f88cb4c0f 100644 --- a/apps/web-antd/src/views/mes/dv/machinery/type/modules/form.vue +++ b/apps/web-antd/src/views/mes/dv/machinery/type/modules/form.vue @@ -64,9 +64,11 @@ const [Modal, modalApi] = useVbenModal({ formData.value = undefined; return; } - formApi.setState({ schema: useFormSchema(formApi) }); // 加载数据 const data = modalApi.getData(); + formApi.setState({ + schema: useFormSchema(data?.id ? 'update' : 'create', formApi), + }); if (!data || !data.id) { formData.value = data || undefined; if (data) { diff --git a/apps/web-antd/src/views/mes/dv/repair/data.ts b/apps/web-antd/src/views/mes/dv/repair/data.ts index 524f41e87..a2eaaae1f 100644 --- a/apps/web-antd/src/views/mes/dv/repair/data.ts +++ b/apps/web-antd/src/views/mes/dv/repair/data.ts @@ -16,8 +16,17 @@ import { DvMachinerySelect } from '#/views/mes/dv/machinery/components'; /** 表单类型 */ export type FormType = 'confirm' | 'create' | 'detail' | 'finish' | 'update'; +/** 表头是否只读(完成维修、验收、详情态;finishDate 在 confirm 单独放开) */ +function isHeaderReadonly(formType: FormType): boolean { + return ['confirm', 'detail', 'finish'].includes(formType); +} + /** 新增/修改维修工单的表单 */ -export function useFormSchema(formApi?: VbenFormApi): VbenFormSchema[] { +export function useFormSchema( + formType: FormType, + formApi?: VbenFormApi, +): VbenFormSchema[] { + const headerReadonly = isHeaderReadonly(formType); return [ { fieldName: 'id', @@ -45,27 +54,30 @@ export function useFormSchema(formApi?: VbenFormApi): VbenFormSchema[] { }, dependencies: { triggerFields: ['id'], - componentProps: (values) => ({ disabled: !!values.id }), + componentProps: (values) => ({ disabled: headerReadonly || !!values.id }), }, rules: 'required', - suffix: () => - h( - Button, - { - type: 'default', - onClick: async () => { - const code = await generateAutoCode(MesAutoCodeRuleCode.DV_REPAIR_CODE); - await formApi?.setFieldValue('code', code); - }, - }, - { default: () => '生成' }, - ), + suffix: headerReadonly + ? undefined + : () => + h( + Button, + { + type: 'default', + onClick: async () => { + const code = await generateAutoCode(MesAutoCodeRuleCode.DV_REPAIR_CODE); + await formApi?.setFieldValue('code', code); + }, + }, + { default: () => '生成' }, + ), }, { fieldName: 'name', label: '维修单名称', component: 'Input', componentProps: { + disabled: headerReadonly, placeholder: '请输入维修单名称', }, rules: 'required', @@ -75,6 +87,7 @@ export function useFormSchema(formApi?: VbenFormApi): VbenFormSchema[] { label: '设备', component: markRaw(DvMachinerySelect), componentProps: { + disabled: headerReadonly, placeholder: '请选择设备', }, rules: 'selectRequired', @@ -84,6 +97,7 @@ export function useFormSchema(formApi?: VbenFormApi): VbenFormSchema[] { label: '报修日期', component: 'DatePicker', componentProps: { + disabled: headerReadonly, format: 'YYYY-MM-DD HH:mm:ss', placeholder: '请选择报修日期', showTime: true, @@ -98,10 +112,18 @@ export function useFormSchema(formApi?: VbenFormApi): VbenFormSchema[] { componentProps: { allowClear: true, api: getSimpleUserList, + disabled: true, labelField: 'nickname', placeholder: '请选择维修人', valueField: 'id', }, + // 维修人为待验收(≥APPROVING)态自动产生的只读回显字段 + dependencies: { + triggerFields: ['status'], + if: (values) => + values.status != null && + values.status >= MesDvRepairStatusEnum.APPROVING, + }, }, { fieldName: 'finishDate', @@ -113,6 +135,15 @@ export function useFormSchema(formApi?: VbenFormApi): VbenFormSchema[] { showTime: true, valueFormat: 'x', }, + // 维修中(≥CONFIRMED)态展示;仅"完成维修"弹窗可编辑并必填,其余态只读回显 + dependencies: { + triggerFields: ['status'], + if: (values) => + values.status != null && + values.status >= MesDvRepairStatusEnum.CONFIRMED, + disabled: formType !== 'confirm', + rules: () => (formType === 'confirm' ? 'required' : null), + }, }, { fieldName: 'confirmUserId', @@ -121,21 +152,37 @@ export function useFormSchema(formApi?: VbenFormApi): VbenFormSchema[] { componentProps: { allowClear: true, api: getSimpleUserList, + disabled: true, labelField: 'nickname', placeholder: '请选择验收人', valueField: 'id', }, + // 验收信息为已确认(≥FINISHED)态自动产生的只读回显字段 + dependencies: { + triggerFields: ['status'], + if: (values) => + values.status != null && + values.status >= MesDvRepairStatusEnum.FINISHED, + }, }, { fieldName: 'confirmDate', label: '验收日期', component: 'DatePicker', componentProps: { + disabled: true, format: 'YYYY-MM-DD HH:mm:ss', placeholder: '请选择验收日期', showTime: true, valueFormat: 'x', }, + // 验收信息为已确认(≥FINISHED)态自动产生的只读回显字段 + dependencies: { + triggerFields: ['status'], + if: (values) => + values.status != null && + values.status >= MesDvRepairStatusEnum.FINISHED, + }, }, { fieldName: 'result', @@ -143,9 +190,17 @@ export function useFormSchema(formApi?: VbenFormApi): VbenFormSchema[] { component: 'RadioGroup', componentProps: { buttonStyle: 'solid', + disabled: true, optionType: 'button', options: getDictOptions(DICT_TYPE.MES_DV_REPAIR_RESULT, 'number'), }, + // 验收信息为已确认(≥FINISHED)态自动产生的只读回显字段 + dependencies: { + triggerFields: ['status'], + if: (values) => + values.status != null && + values.status >= MesDvRepairStatusEnum.FINISHED, + }, }, { fieldName: 'remark', @@ -153,6 +208,7 @@ export function useFormSchema(formApi?: VbenFormApi): VbenFormSchema[] { component: 'Textarea', formItemClass: 'col-span-3', componentProps: { + disabled: headerReadonly, placeholder: '请输入备注', rows: 3, }, diff --git a/apps/web-antd/src/views/mes/dv/repair/modules/form.vue b/apps/web-antd/src/views/mes/dv/repair/modules/form.vue index 1ae2e612b..efbe2058b 100644 --- a/apps/web-antd/src/views/mes/dv/repair/modules/form.vue +++ b/apps/web-antd/src/views/mes/dv/repair/modules/form.vue @@ -28,20 +28,29 @@ const emit = defineEmits(['success']); const formType = ref('create'); const formData = ref(); const isDetail = computed(() => formType.value === 'detail'); -const isReadonly = computed(() => ['confirm', 'detail', 'finish'].includes(formType.value)); +const isLineReadonly = computed(() => + // 明细只读:完成维修/验收/详情态明细均不可编辑 + ['confirm', 'detail', 'finish'].includes(formType.value), +); +const isFormDisabled = computed(() => + // 整表禁用:仅详情/验收态;完成维修态需放开 finishDate,故单头只读改由 schema 逐字段控制 + ['detail', 'finish'].includes(formType.value), +); const canSubmit = computed( () => formType.value === 'update' && formData.value?.status === MesDvRepairStatusEnum.PREPARE, ); -const getTitle = computed( - () => - ({ - create: '新增维修工单', - update: '修改维修工单', - confirm: '完成维修', - finish: '验收维修', - detail: '查看维修工单', - })[formType.value], -); +const getTitle = computed(() => { + if (formType.value === 'detail') { + return '查看维修工单'; + } + if (formType.value === 'confirm') { + return '完成维修'; + } + if (formType.value === 'finish') { + return '验收维修'; + } + return formType.value === 'update' ? '修改维修工单' : '新增维修工单'; +}); const [Form, formApi] = useVbenForm({ commonConfig: { @@ -161,11 +170,11 @@ const [Modal, modalApi] = useVbenModal({ formData.value = undefined; return; } - formApi.setState({ schema: useFormSchema(formApi) }); // 加载数据 const data = modalApi.getData<{ formType: FormType; id?: number }>(); formType.value = data.formType; - formApi.setDisabled(isReadonly.value); + formApi.setState({ schema: useFormSchema(data.formType, formApi) }); + formApi.setDisabled(isFormDisabled.value); modalApi.setState({ showConfirmButton: ['create', 'update'].includes(formType.value) }); if (!data?.id) { return; @@ -184,7 +193,7 @@ const [Modal, modalApi] = useVbenModal({