From 3acc821de57026fa86a8d092310b6e19b942b6ec Mon Sep 17 00:00:00 2001 From: YunaiV Date: Tue, 26 May 2026 08:42:49 +0800 Subject: [PATCH] =?UTF-8?q?feat(mes):=20=E8=BF=81=E7=A7=BB=E2=80=9C?= =?UTF-8?q?=E7=94=9F=E4=BA=A7=E6=8A=A5=E5=B7=A5=EF=BC=88pro=5Ffeedback?= =?UTF-8?q?=EF=BC=89=E2=80=9D=E7=9A=84=20antd=20=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/api/mes/pro/feedback/index.ts | 113 ++++ apps/web-antd/src/api/mes/pro/task/index.ts | 68 +++ .../src/api/mes/wm/itemconsume/line/index.ts | 37 ++ .../api/mes/wm/productproduce/line/index.ts | 37 ++ .../src/views/mes/pro/feedback/data.ts | 575 ++++++++++++++++++ .../src/views/mes/pro/feedback/index.vue | 182 ++++++ .../views/mes/pro/feedback/modules/form.vue | 307 ++++++++++ .../feedback/modules/item-consume-list.vue | 57 ++ .../feedback/modules/product-produce-list.vue | 68 +++ .../views/mes/pro/task/components/index.ts | 1 + .../pro/task/components/pro-task-select.vue | 163 +++++ packages/constants/src/dict-enum.ts | 1 + packages/locales/src/langs/en-US/common.json | 2 + packages/locales/src/langs/zh-CN/common.json | 2 + 14 files changed, 1613 insertions(+) create mode 100644 apps/web-antd/src/api/mes/pro/feedback/index.ts create mode 100644 apps/web-antd/src/api/mes/pro/task/index.ts create mode 100644 apps/web-antd/src/api/mes/wm/itemconsume/line/index.ts create mode 100644 apps/web-antd/src/api/mes/wm/productproduce/line/index.ts create mode 100644 apps/web-antd/src/views/mes/pro/feedback/data.ts create mode 100644 apps/web-antd/src/views/mes/pro/feedback/index.vue create mode 100644 apps/web-antd/src/views/mes/pro/feedback/modules/form.vue create mode 100644 apps/web-antd/src/views/mes/pro/feedback/modules/item-consume-list.vue create mode 100644 apps/web-antd/src/views/mes/pro/feedback/modules/product-produce-list.vue create mode 100644 apps/web-antd/src/views/mes/pro/task/components/index.ts create mode 100644 apps/web-antd/src/views/mes/pro/task/components/pro-task-select.vue diff --git a/apps/web-antd/src/api/mes/pro/feedback/index.ts b/apps/web-antd/src/api/mes/pro/feedback/index.ts new file mode 100644 index 000000000..21a988ba8 --- /dev/null +++ b/apps/web-antd/src/api/mes/pro/feedback/index.ts @@ -0,0 +1,113 @@ +import type { PageParam, PageResult } from '@vben/request'; + +import { requestClient } from '#/api/request'; + +export namespace MesProFeedbackApi { + /** MES 生产报工 */ + export interface Feedback { + id?: number; + code?: string; // 报工单编号 + type?: number; // 报工类型 + channel?: string; // 报工途径 + feedbackTime?: number; // 报工时间 + workstationId?: number; // 工作站编号 + workstationCode?: string; // 工作站编码 + workstationName?: string; // 工作站名称 + routeId?: number; // 工艺路线编号 + routeCode?: string; // 工艺路线编码 + processId?: number; // 工序编号 + processCode?: string; // 工序编码 + processName?: string; // 工序名称 + checkFlag?: boolean; // 是否需要检验 + workOrderId?: number; // 生产工单编号 + workOrderCode?: string; // 工单编码 + workOrderName?: string; // 工单名称 + taskId?: number; // 生产任务编号 + taskCode?: string; // 任务编码 + itemId?: number; // 产品物料编号 + itemCode?: string; // 物料编码 + itemName?: string; // 物料名称 + itemSpecification?: string; // 规格型号 + unitMeasureId?: number; // 单位编号 + unitMeasureName?: string; // 单位名称 + expireDate?: number; // 过期日期 + scheduledQuantity?: number; // 排产数量 + feedbackQuantity?: number; // 本次报工数量 + qualifiedQuantity?: number; // 合格品数量 + unqualifiedQuantity?: number; // 不良品数量 + uncheckQuantity?: number; // 待检测数量 + laborScrapQuantity?: number; // 工废数量 + materialScrapQuantity?: number; // 料废数量 + otherScrapQuantity?: number; // 其他废品数量 + feedbackUserId?: number; // 报工用户编号 + feedbackUserNickname?: string; // 报工人昵称 + approveUserId?: number; // 审核用户编号 + approveUserNickname?: string; // 审核人昵称 + status?: number; // 状态 + remark?: string; // 备注 + creator?: string; // 创建人 + createTime?: number; // 创建时间 + } + + /** MES 生产报工分页查询参数 */ + export interface PageParams extends PageParam { + code?: string; + type?: number; + workOrderId?: number; + itemId?: number; + feedbackUserId?: number; + creator?: string; + status?: number; + feedbackTime?: string[]; + } +} + +/** 查询生产报工分页 */ +export function getFeedbackPage(params: MesProFeedbackApi.PageParams) { + return requestClient.get>( + '/mes/pro/feedback/page', + { params }, + ); +} + +/** 查询生产报工详情 */ +export function getFeedback(id: number) { + return requestClient.get( + `/mes/pro/feedback/get?id=${id}`, + ); +} + +/** 新增生产报工 */ +export function createFeedback(data: MesProFeedbackApi.Feedback) { + return requestClient.post('/mes/pro/feedback/create', data); +} + +/** 修改生产报工 */ +export function updateFeedback(data: MesProFeedbackApi.Feedback) { + return requestClient.put('/mes/pro/feedback/update', data); +} + +/** 删除生产报工 */ +export function deleteFeedback(id: number) { + return requestClient.delete(`/mes/pro/feedback/delete?id=${id}`); +} + +/** 导出生产报工 Excel */ +export function exportFeedback(params: Partial) { + return requestClient.download('/mes/pro/feedback/export-excel', { params }); +} + +/** 提交生产报工 */ +export function submitFeedback(id: number) { + return requestClient.put(`/mes/pro/feedback/submit?id=${id}`); +} + +/** 驳回生产报工 */ +export function rejectFeedback(id: number) { + return requestClient.put(`/mes/pro/feedback/reject?id=${id}`); +} + +/** 审批生产报工(返回是否已审批完成) */ +export function approveFeedback(id: number) { + return requestClient.put(`/mes/pro/feedback/approve?id=${id}`); +} diff --git a/apps/web-antd/src/api/mes/pro/task/index.ts b/apps/web-antd/src/api/mes/pro/task/index.ts new file mode 100644 index 000000000..d7bfd2f5e --- /dev/null +++ b/apps/web-antd/src/api/mes/pro/task/index.ts @@ -0,0 +1,68 @@ +import type { PageParam, PageResult } from '@vben/request'; + +import { requestClient } from '#/api/request'; + +export namespace MesProTaskApi { + /** MES 生产任务 */ + export interface Task { + id?: number; + code?: string; // 任务编码 + name?: string; // 任务名称 + workOrderId?: number; // 生产工单编号 + workOrderCode?: string; // 工单编码 + workOrderName?: string; // 工单名称 + workstationId?: number; // 工作站编号 + workstationCode?: string; // 工作站编码 + workstationName?: string; // 工作站名称 + routeId?: number; // 工艺路线编号 + processId?: number; // 工序编号 + processName?: string; // 工序名称 + itemId?: number; // 产品物料编号 + itemCode?: string; // 产品编码 + itemName?: string; // 产品名称 + itemSpecification?: string; // 规格型号 + unitMeasureId?: number; // 单位编号 + unitMeasureName?: string; // 单位名称 + quantity?: number; // 排产数量 + producedQuantity?: number; // 已生产数量 + qualifyQuantity?: number; // 合格品数量 + unqualifyQuantity?: number; // 不良品数量 + changedQuantity?: number; // 调整数量 + clientId?: number; // 客户编号 + clientName?: string; // 客户名称 + startTime?: number; // 开始生产时间 + endTime?: number; // 结束生产时间 + duration?: number; // 生产时长(工作日,1=8小时) + requestDate?: number; // 需求日期(从工单查) + finishDate?: number; // 完成日期 + cancelDate?: number; // 取消日期 + colorCode?: string; // 甘特图显示颜色 + status?: number; // 任务状态 + checkFlag?: boolean; // 是否质检(派生自工艺路线工序) + remark?: string; // 备注 + } + + /** MES 生产任务分页查询参数 */ + export interface PageParams extends PageParam { + code?: string; + name?: string; + workOrderId?: number; + workstationId?: number; + itemId?: number; + statuses?: number[]; + status?: number; + } +} + +/** 查询生产任务分页 */ +export function getTaskPage(params: MesProTaskApi.PageParams) { + return requestClient.get>( + '/mes/pro/task/page', + { params }, + ); +} + +/** 查询生产任务详情 */ +export function getTask(id: number) { + return requestClient.get(`/mes/pro/task/get?id=${id}`); +} diff --git a/apps/web-antd/src/api/mes/wm/itemconsume/line/index.ts b/apps/web-antd/src/api/mes/wm/itemconsume/line/index.ts new file mode 100644 index 000000000..2a353b766 --- /dev/null +++ b/apps/web-antd/src/api/mes/wm/itemconsume/line/index.ts @@ -0,0 +1,37 @@ +import type { PageParam, PageResult } from '@vben/request'; + +import { requestClient } from '#/api/request'; + +export namespace MesWmItemConsumeLineApi { + /** MES 物料消耗行 */ + export interface ItemConsumeLine { + id?: number; + feedbackId?: number; // 报工编号 + itemId?: number; // 物料编号 + itemCode?: string; // 物资编码 + itemName?: string; // 物资名称 + specification?: string; // 规格型号 + unitId?: number; // 单位编号 + unitName?: string; // 单位 + quantity?: number; // 消耗数量 + batchCode?: string; // 批次号 + locationId?: number; // 库位编号 + locationName?: string; // 库位名称 + remark?: string; // 备注 + } + + /** MES 物料消耗行分页查询参数 */ + export interface PageParams extends PageParam { + feedbackId?: number; + } +} + +/** 查询物料消耗行分页 */ +export function getItemConsumeLinePage( + params: MesWmItemConsumeLineApi.PageParams, +) { + return requestClient.get>( + '/mes/wm/item-consume-line/page', + { params }, + ); +} diff --git a/apps/web-antd/src/api/mes/wm/productproduce/line/index.ts b/apps/web-antd/src/api/mes/wm/productproduce/line/index.ts new file mode 100644 index 000000000..ab3f49f29 --- /dev/null +++ b/apps/web-antd/src/api/mes/wm/productproduce/line/index.ts @@ -0,0 +1,37 @@ +import type { PageParam, PageResult } from '@vben/request'; + +import { requestClient } from '#/api/request'; + +export namespace MesWmProductProduceLineApi { + /** MES 产品产出行 */ + export interface ProductProduceLine { + id?: number; + feedbackId?: number; // 报工编号 + itemId?: number; // 物料编号 + itemCode?: string; // 物资编码 + itemName?: string; // 物资名称 + specification?: string; // 规格型号 + unitMeasureId?: number; // 单位编号 + unitMeasureName?: string; // 单位 + quantity?: number; // 产出数量 + batchCode?: string; // 批次号 + qualityStatus?: number; // 质量状态 + locationId?: number; // 库位编号 + locationName?: string; // 库位名称 + remark?: string; // 备注 + } + + /** MES 产品产出行分页查询参数 */ + export interface PageParams extends PageParam { + feedbackId?: number; + } +} + +/** 查询产品产出行分页 */ +export function getProductProduceLinePage( + params: MesWmProductProduceLineApi.PageParams, +) { + return requestClient.get< + PageResult + >('/mes/wm/product-produce-line/page', { params }); +} diff --git a/apps/web-antd/src/views/mes/pro/feedback/data.ts b/apps/web-antd/src/views/mes/pro/feedback/data.ts new file mode 100644 index 000000000..4d1af1810 --- /dev/null +++ b/apps/web-antd/src/views/mes/pro/feedback/data.ts @@ -0,0 +1,575 @@ +import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; +import type { MesProFeedbackApi } from '#/api/mes/pro/feedback'; +import type { MesProTaskApi } from '#/api/mes/pro/task'; + +import { h, markRaw } from 'vue'; + +import { DICT_TYPE } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; + +import { Button } from 'ant-design-vue'; + +import { generateAutoCode } from '#/api/mes/md/autocode/record'; +import { getRouteProcessByRouteAndProcess } from '#/api/mes/pro/route/process'; +import { getSimpleUserList } from '#/api/system/user'; +import { getRangePickerDefaultProps } from '#/utils'; +import { MdItemSelect } from '#/views/mes/md/item/components'; +import { MdWorkstationSelect } from '#/views/mes/md/workstation/components'; +import { ProTaskSelect } from '#/views/mes/pro/task/components'; +import { ProWorkOrderSelect } from '#/views/mes/pro/workorder/components'; +import { + MesAutoCodeRuleCode, + MesProTaskStatusEnum, + MesProWorkOrderStatusEnum, +} from '#/views/mes/utils/constants'; + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'code', + label: '报工单号', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入报工单号', + }, + }, + { + fieldName: 'type', + label: '报工类型', + component: 'Select', + componentProps: { + allowClear: true, + options: getDictOptions(DICT_TYPE.MES_PRO_FEEDBACK_TYPE, 'number'), + placeholder: '请选择报工类型', + }, + }, + { + fieldName: 'workOrderId', + label: '生产工单', + component: markRaw(ProWorkOrderSelect), + componentProps: { + allowClear: true, + placeholder: '请选择工单', + }, + }, + { + fieldName: 'itemId', + label: '产品物料', + component: markRaw(MdItemSelect), + componentProps: { + allowClear: true, + placeholder: '请选择产品物料', + }, + }, + { + fieldName: 'feedbackUserId', + label: '报工人', + component: 'ApiSelect', + componentProps: { + allowClear: true, + api: getSimpleUserList, + labelField: 'nickname', + placeholder: '请选择报工人', + valueField: 'id', + }, + }, + { + fieldName: 'creator', + label: '记录人', + component: 'ApiSelect', + componentProps: { + allowClear: true, + api: getSimpleUserList, + labelField: 'nickname', + placeholder: '请选择记录人', + valueField: 'id', + }, + }, + { + fieldName: 'status', + label: '状态', + component: 'Select', + componentProps: { + allowClear: true, + options: getDictOptions(DICT_TYPE.MES_PRO_FEEDBACK_STATUS, 'number'), + placeholder: '请选择状态', + }, + }, + { + fieldName: 'feedbackTime', + label: '报工时间', + component: 'RangePicker', + componentProps: { + ...getRangePickerDefaultProps(), + allowClear: true, + }, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + field: 'code', + title: '报工单号', + width: 160, + slots: { default: 'code' }, + }, + { + field: 'type', + title: '报工类型', + width: 100, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.MES_PRO_FEEDBACK_TYPE }, + }, + }, + { field: 'workstationName', title: '工作站', width: 120 }, + { field: 'processName', title: '工序', width: 100 }, + { field: 'workOrderCode', title: '生产工单编码', width: 160 }, + { field: 'itemCode', title: '产品物料编码', width: 120 }, + { field: 'itemName', title: '产品物料名称', minWidth: 140 }, + { field: 'itemSpecification', title: '规格型号', width: 120 }, + { field: 'unitMeasureName', title: '单位', width: 80 }, + { field: 'feedbackQuantity', title: '报工数量', width: 100 }, + { field: 'feedbackUserNickname', title: '报工人', width: 100 }, + { + field: 'feedbackTime', + title: '报工时间', + width: 180, + formatter: 'formatDateTime', + }, + { field: 'approveUserNickname', title: '审核人', width: 100 }, + { + field: 'status', + title: '状态', + width: 100, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.MES_PRO_FEEDBACK_STATUS }, + }, + }, + { + title: '操作', + width: 240, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} + +/** + * 新增/编辑/提交/审批/详情生产报工的表单 + * + * - create / update:录入报工主体信息和数量 + * - submit / approve / detail:主体字段只读 + * + * 数量区域根据 `checkFlag` 和 `unqualifiedQuantity` 动态显示: + * - 非质检工序:报工数量 = 合格 + 不良;不良 > 0 时再展开工废/料废/其他废品 + * - 质检工序:只填报工数量(视为待检数量) + */ +export function useFormSchema( + formType: string, + formApi?: VbenFormApi, +): VbenFormSchema[] { + const isHeaderReadonly = ['approve', 'detail', 'submit'].includes(formType); + return [ + { + fieldName: 'id', + component: 'Input', + dependencies: { triggerFields: [''], show: () => false }, + }, + { + fieldName: 'checkFlag', + component: 'Input', + dependencies: { triggerFields: [''], show: () => false }, + defaultValue: true, + }, + { + fieldName: 'routeId', + component: 'Input', + dependencies: { triggerFields: [''], show: () => false }, + }, + { + fieldName: 'processId', + component: 'Input', + dependencies: { triggerFields: [''], show: () => false }, + }, + { + fieldName: 'itemId', + component: 'Input', + dependencies: { triggerFields: [''], show: () => false }, + }, + { + fieldName: 'code', + label: '报工单号', + component: 'Input', + componentProps: { + disabled: isHeaderReadonly, + placeholder: '请输入报工单号', + }, + rules: 'required', + suffix: () => + h( + Button, + { + disabled: isHeaderReadonly, + type: 'default', + onClick: async () => { + const code = await generateAutoCode( + MesAutoCodeRuleCode.PRO_FEEDBACK_CODE, + ); + await formApi?.setFieldValue('code', code); + }, + }, + { default: () => '生成' }, + ), + }, + { + fieldName: 'type', + label: '报工类型', + component: 'Select', + componentProps: { + disabled: isHeaderReadonly, + options: getDictOptions(DICT_TYPE.MES_PRO_FEEDBACK_TYPE, 'number'), + placeholder: '请选择报工类型', + }, + rules: 'required', + }, + { + fieldName: 'workOrderId', + label: '生产工单', + component: markRaw(ProWorkOrderSelect), + componentProps: { + disabled: isHeaderReadonly, + placeholder: '请选择工单', + status: MesProWorkOrderStatusEnum.CONFIRMED, + // 工单变更:清空任务及任务带出的产品信息、数量区域控制位 + onChange: async () => { + await formApi?.setValues({ + checkFlag: true, + itemCode: undefined, + itemId: undefined, + itemName: undefined, + itemSpecification: undefined, + processId: undefined, + routeId: undefined, + taskId: undefined, + unitMeasureName: undefined, + workstationId: undefined, + }); + }, + }, + rules: 'selectRequired', + }, + { + fieldName: 'taskId', + label: '生产任务', + component: markRaw(ProTaskSelect), + dependencies: { + triggerFields: ['workOrderId', 'workstationId'], + componentProps: (values) => ({ + disabled: isHeaderReadonly || !values.workOrderId, + placeholder: values.workOrderId ? '请选择任务' : '请先选择工单', + statuses: [MesProTaskStatusEnum.PREPARE], + workOrderId: values.workOrderId, + workstationId: values.workstationId, + }), + }, + // 任务变更:自动填充关联字段、产品信息、checkFlag + componentProps: { + onChange: async (task?: MesProTaskApi.Task) => { + if (!task) { + return; + } + await formApi?.setValues({ + itemCode: task.itemCode, + itemId: task.itemId, + itemName: task.itemName, + itemSpecification: task.itemSpecification, + processId: task.processId, + routeId: task.routeId, + unitMeasureName: task.unitMeasureName, + workstationId: task.workstationId, + }); + // 工艺路线工序的 checkFlag 决定数量区域展示 + if (task.routeId && task.processId) { + try { + const routeProcess = await getRouteProcessByRouteAndProcess( + task.routeId, + task.processId, + ); + await formApi?.setFieldValue( + 'checkFlag', + routeProcess?.checkFlag ?? false, + ); + } catch { + await formApi?.setFieldValue('checkFlag', true); + } + } + }, + }, + rules: 'selectRequired', + }, + { + fieldName: 'workstationId', + label: '工作站', + component: markRaw(MdWorkstationSelect), + componentProps: { + disabled: isHeaderReadonly, + placeholder: '请选择工作站', + }, + rules: 'selectRequired', + }, + { + fieldName: 'itemCode', + label: '产品编码', + component: 'Input', + componentProps: { disabled: true }, + dependencies: { + triggerFields: ['itemCode'], + show: (values) => !!values.itemCode, + }, + }, + { + fieldName: 'itemName', + label: '产品名称', + component: 'Input', + componentProps: { disabled: true }, + dependencies: { + triggerFields: ['itemCode'], + show: (values) => !!values.itemCode, + }, + }, + { + fieldName: 'unitMeasureName', + label: '单位', + component: 'Input', + componentProps: { disabled: true }, + dependencies: { + triggerFields: ['itemCode'], + show: (values) => !!values.itemCode, + }, + }, + { + fieldName: 'itemSpecification', + label: '规格', + component: 'Input', + componentProps: { disabled: true }, + dependencies: { + triggerFields: ['itemCode'], + show: (values) => !!values.itemCode, + }, + }, + { + fieldName: 'feedbackQuantity', + label: '报工数量', + component: 'InputNumber', + componentProps: { class: 'w-full', min: 0, precision: 2 }, + dependencies: { + triggerFields: ['checkFlag'], + // 非质检工序时,报工数量 = 合格 + 不良,禁用直接编辑 + componentProps: (values) => ({ + class: 'w-full', + disabled: !values.checkFlag, + min: 0, + placeholder: '请输入报工数量', + precision: 2, + }), + }, + rules: 'required', + }, + { + fieldName: 'qualifiedQuantity', + label: '合格品数量', + component: 'InputNumber', + componentProps: { + class: 'w-full', + min: 0, + precision: 2, + // 合格/不良变更,自动累计为报工数量 + onChange: async () => { + const values = await formApi?.getValues(); + await formApi?.setFieldValue( + 'feedbackQuantity', + (values?.qualifiedQuantity || 0) + + (values?.unqualifiedQuantity || 0), + ); + }, + }, + defaultValue: 0, + dependencies: { + triggerFields: ['checkFlag'], + show: (values) => !values.checkFlag, + }, + }, + { + fieldName: 'unqualifiedQuantity', + label: '不良品数量', + component: 'InputNumber', + componentProps: { + class: 'w-full', + min: 0, + precision: 2, + // 合格/不良变更,自动累计为报工数量 + onChange: async () => { + const values = await formApi?.getValues(); + await formApi?.setFieldValue( + 'feedbackQuantity', + (values?.qualifiedQuantity || 0) + + (values?.unqualifiedQuantity || 0), + ); + }, + }, + defaultValue: 0, + dependencies: { + triggerFields: ['checkFlag'], + show: (values) => !values.checkFlag, + }, + }, + { + fieldName: 'laborScrapQuantity', + label: '工废数量', + component: 'InputNumber', + componentProps: { + class: 'w-full', + min: 0, + precision: 2, + // 废品分类变更,自动累计为不良品数量及报工数量 + onChange: async () => { + const values = await formApi?.getValues(); + const unqualified = + (values?.laborScrapQuantity || 0) + + (values?.materialScrapQuantity || 0) + + (values?.otherScrapQuantity || 0); + await formApi?.setValues({ + feedbackQuantity: + (values?.qualifiedQuantity || 0) + unqualified, + unqualifiedQuantity: unqualified, + }); + }, + }, + defaultValue: 0, + dependencies: { + triggerFields: ['checkFlag', 'unqualifiedQuantity'], + show: (values) => + !values.checkFlag && (values.unqualifiedQuantity || 0) > 0, + }, + }, + { + fieldName: 'materialScrapQuantity', + label: '料废数量', + component: 'InputNumber', + componentProps: { + class: 'w-full', + min: 0, + precision: 2, + // 废品分类变更,自动累计为不良品数量及报工数量 + onChange: async () => { + const values = await formApi?.getValues(); + const unqualified = + (values?.laborScrapQuantity || 0) + + (values?.materialScrapQuantity || 0) + + (values?.otherScrapQuantity || 0); + await formApi?.setValues({ + feedbackQuantity: + (values?.qualifiedQuantity || 0) + unqualified, + unqualifiedQuantity: unqualified, + }); + }, + }, + defaultValue: 0, + dependencies: { + triggerFields: ['checkFlag', 'unqualifiedQuantity'], + show: (values) => + !values.checkFlag && (values.unqualifiedQuantity || 0) > 0, + }, + }, + { + fieldName: 'otherScrapQuantity', + label: '其他废品', + component: 'InputNumber', + componentProps: { + class: 'w-full', + min: 0, + precision: 2, + // 废品分类变更,自动累计为不良品数量及报工数量 + onChange: async () => { + const values = await formApi?.getValues(); + const unqualified = + (values?.laborScrapQuantity || 0) + + (values?.materialScrapQuantity || 0) + + (values?.otherScrapQuantity || 0); + await formApi?.setValues({ + feedbackQuantity: + (values?.qualifiedQuantity || 0) + unqualified, + unqualifiedQuantity: unqualified, + }); + }, + }, + defaultValue: 0, + dependencies: { + triggerFields: ['checkFlag', 'unqualifiedQuantity'], + show: (values) => + !values.checkFlag && (values.unqualifiedQuantity || 0) > 0, + }, + }, + { + fieldName: 'feedbackUserId', + label: '报工人', + component: 'ApiSelect', + componentProps: { + allowClear: true, + api: getSimpleUserList, + disabled: isHeaderReadonly, + labelField: 'nickname', + placeholder: '请选择报工人', + valueField: 'id', + }, + rules: 'selectRequired', + }, + { + fieldName: 'feedbackTime', + label: '报工时间', + component: 'DatePicker', + componentProps: { + class: 'w-full', + disabled: isHeaderReadonly, + format: 'YYYY-MM-DD HH:mm:ss', + placeholder: '请选择报工时间', + showTime: true, + valueFormat: 'x', + }, + rules: 'required', + }, + { + fieldName: 'approveUserId', + label: '审核人', + component: 'ApiSelect', + componentProps: { + allowClear: true, + api: getSimpleUserList, + disabled: isHeaderReadonly, + labelField: 'nickname', + placeholder: '请选择审核人', + valueField: 'id', + }, + rules: 'selectRequired', + }, + { + fieldName: 'remark', + label: '备注', + component: 'Textarea', + formItemClass: 'col-span-3', + componentProps: { + disabled: formType === 'detail', + placeholder: '请输入备注', + rows: 3, + }, + }, + ]; +} diff --git a/apps/web-antd/src/views/mes/pro/feedback/index.vue b/apps/web-antd/src/views/mes/pro/feedback/index.vue new file mode 100644 index 000000000..d2a045908 --- /dev/null +++ b/apps/web-antd/src/views/mes/pro/feedback/index.vue @@ -0,0 +1,182 @@ + + + diff --git a/apps/web-antd/src/views/mes/pro/feedback/modules/form.vue b/apps/web-antd/src/views/mes/pro/feedback/modules/form.vue new file mode 100644 index 000000000..4d770d825 --- /dev/null +++ b/apps/web-antd/src/views/mes/pro/feedback/modules/form.vue @@ -0,0 +1,307 @@ + + + diff --git a/apps/web-antd/src/views/mes/pro/feedback/modules/item-consume-list.vue b/apps/web-antd/src/views/mes/pro/feedback/modules/item-consume-list.vue new file mode 100644 index 000000000..6ac69a535 --- /dev/null +++ b/apps/web-antd/src/views/mes/pro/feedback/modules/item-consume-list.vue @@ -0,0 +1,57 @@ + + + diff --git a/apps/web-antd/src/views/mes/pro/feedback/modules/product-produce-list.vue b/apps/web-antd/src/views/mes/pro/feedback/modules/product-produce-list.vue new file mode 100644 index 000000000..9b313f0cb --- /dev/null +++ b/apps/web-antd/src/views/mes/pro/feedback/modules/product-produce-list.vue @@ -0,0 +1,68 @@ + + + diff --git a/apps/web-antd/src/views/mes/pro/task/components/index.ts b/apps/web-antd/src/views/mes/pro/task/components/index.ts new file mode 100644 index 000000000..0642acb68 --- /dev/null +++ b/apps/web-antd/src/views/mes/pro/task/components/index.ts @@ -0,0 +1 @@ +export { default as ProTaskSelect } from './pro-task-select.vue'; diff --git a/apps/web-antd/src/views/mes/pro/task/components/pro-task-select.vue b/apps/web-antd/src/views/mes/pro/task/components/pro-task-select.vue new file mode 100644 index 000000000..d8edc8e0a --- /dev/null +++ b/apps/web-antd/src/views/mes/pro/task/components/pro-task-select.vue @@ -0,0 +1,163 @@ + + + diff --git a/packages/constants/src/dict-enum.ts b/packages/constants/src/dict-enum.ts index 7a127bbc1..9ef6e2310 100644 --- a/packages/constants/src/dict-enum.ts +++ b/packages/constants/src/dict-enum.ts @@ -216,6 +216,7 @@ const MES_DICT = { MES_WM_BARCODE_BIZ_TYPE: 'mes_wm_barcode_biz_type', // MES 条码业务类型 MES_WM_BARCODE_FORMAT: 'mes_wm_barcode_format', // MES 条码格式 MES_WM_PRODUCT_SALES_STATUS: 'mes_wm_product_sales_status', // MES 销售出库单状态 + MES_WM_QUALITY_STATUS: 'mes_wm_quality_status', // MES 质量状态 } as const; /** ========== WMS - 仓储管理模块 ========== */ diff --git a/packages/locales/src/langs/en-US/common.json b/packages/locales/src/langs/en-US/common.json index 0d289b3ab..308c26ea3 100644 --- a/packages/locales/src/langs/en-US/common.json +++ b/packages/locales/src/langs/en-US/common.json @@ -21,6 +21,8 @@ "detail": "Detail", "yes": "Yes", "no": "No", + "submit": "Submit", + "approve": "Approve", "showSearchPanel": "Show search panel", "hideSearchPanel": "Hide search panel" } diff --git a/packages/locales/src/langs/zh-CN/common.json b/packages/locales/src/langs/zh-CN/common.json index b90087f1a..9905b4738 100644 --- a/packages/locales/src/langs/zh-CN/common.json +++ b/packages/locales/src/langs/zh-CN/common.json @@ -21,6 +21,8 @@ "detail": "详情", "yes": "是", "no": "否", + "submit": "提交", + "approve": "审批", "showSearchPanel": "显示搜索面板", "hideSearchPanel": "隐藏搜索面板" }