diff --git a/apps/web-antd/src/views/mes/qc/ipqc/data.ts b/apps/web-antd/src/views/mes/qc/ipqc/data.ts new file mode 100644 index 000000000..73c19bc51 --- /dev/null +++ b/apps/web-antd/src/views/mes/qc/ipqc/data.ts @@ -0,0 +1,566 @@ +import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; +import type { MesQcIpqcApi } from '#/api/mes/qc/ipqc'; +import type { MesQcIpqcLineApi } from '#/api/mes/qc/ipqc/line'; + +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 { getSimpleUserList } from '#/api/system/user'; +import MdItemSelect from '#/views/mes/md/item/components/md-item-select.vue'; +import MdWorkstationSelect from '#/views/mes/md/workstation/components/md-workstation-select.vue'; +import ProTaskSelect from '#/views/mes/pro/task/components/pro-task-select.vue'; +import ProWorkOrderSelect from '#/views/mes/pro/workorder/components/pro-work-order-select.vue'; +import { + MesAutoCodeRuleCode, + MesProTaskStatusEnum, + MesProWorkOrderStatusEnum, +} from '#/views/mes/utils/constants'; + +/** 表单类型 */ +export type FormType = 'create' | 'detail' | 'update'; + +/** 把不合格品数量同步为工废 + 料废 + 其他废品之和 */ +function syncUnqualified(formApi?: VbenFormApi) { + if (!formApi) { + return; + } + void (async () => { + const values = await formApi.getValues(); + const next = + Number(values.laborScrapQuantity || 0) + + Number(values.materialScrapQuantity || 0) + + Number(values.otherScrapQuantity || 0); + await formApi.setFieldValue('unqualifiedQuantity', next); + })(); +} + +/** 新增/修改的表单 */ +export function useFormSchema(formApi?: VbenFormApi): VbenFormSchema[] { + return [ + { + fieldName: 'id', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'sourceDocId', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'sourceLineId', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'status', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'code', + label: '检验单编号', + component: 'Input', + componentProps: { + placeholder: '请输入检验单编号', + }, + rules: 'required', + suffix: () => + h( + Button, + { + type: 'default', + onClick: async () => { + try { + const code = await generateAutoCode( + MesAutoCodeRuleCode.QC_IPQC_CODE, + ); + await formApi?.setFieldValue('code', code); + } catch (error) { + console.error(error); + } + }, + }, + { default: () => '生成' }, + ), + }, + { + fieldName: 'name', + label: '检验单名称', + component: 'Input', + componentProps: { + placeholder: '请输入检验单名称', + }, + rules: 'required', + }, + { + fieldName: 'type', + label: '检验类型', + component: 'Select', + componentProps: { + allowClear: true, + options: getDictOptions(DICT_TYPE.MES_IPQC_TYPE, 'number'), + placeholder: '请选择检验类型', + }, + rules: 'selectRequired', + }, + { + fieldName: 'sourceDocType', + label: '来源单据类型', + component: 'Select', + componentProps: { + disabled: true, + options: getDictOptions(DICT_TYPE.MES_QC_SOURCE_DOC_TYPE, 'number'), + placeholder: '来源单据类型', + }, + dependencies: { + triggerFields: ['sourceDocType'], + show: (values) => !!values.sourceDocType, + }, + }, + { + fieldName: 'sourceDocCode', + label: '来源单据编号', + component: 'Input', + componentProps: { + disabled: true, + placeholder: '来源单据编号', + }, + dependencies: { + triggerFields: ['sourceDocType', 'sourceDocId'], + show: (values) => !!values.sourceDocType && !!values.sourceDocId, + }, + }, + { + fieldName: 'workOrderId', + label: '生产工单', + component: markRaw(ProWorkOrderSelect), + componentProps: { + placeholder: '请选择生产工单', + status: MesProWorkOrderStatusEnum.CONFIRMED, + // 工单变更时清空生产任务 + onChange: () => formApi?.setFieldValue('taskId', undefined), + }, + rules: 'selectRequired', + dependencies: { + triggerFields: ['sourceDocId'], + componentProps: (values) => ({ + disabled: !!values.sourceDocId, + placeholder: '请选择生产工单', + status: MesProWorkOrderStatusEnum.CONFIRMED, + onChange: () => formApi?.setFieldValue('taskId', undefined), + }), + }, + }, + { + fieldName: 'workstationId', + label: '工位', + component: markRaw(MdWorkstationSelect), + componentProps: { + placeholder: '请选择工位', + }, + rules: 'selectRequired', + dependencies: { + triggerFields: ['sourceDocId'], + componentProps: (values) => ({ + disabled: !!values.sourceDocId, + placeholder: '请选择工位', + }), + }, + }, + { + fieldName: 'taskId', + label: '生产任务', + component: markRaw(ProTaskSelect), + componentProps: { + placeholder: '请选择生产任务', + statuses: [MesProTaskStatusEnum.PREPARE], + }, + dependencies: { + triggerFields: ['sourceDocId', 'workOrderId', 'workstationId'], + componentProps: (values) => ({ + disabled: !!values.sourceDocId || !values.workOrderId, + placeholder: '请选择生产任务', + statuses: [MesProTaskStatusEnum.PREPARE], + workOrderId: values.workOrderId, + workstationId: values.workstationId, + }), + }, + }, + { + fieldName: 'checkQuantity', + label: '检测数量', + component: 'InputNumber', + componentProps: { + class: '!w-full', + min: 0, + placeholder: '请输入检测数量', + precision: 2, + }, + rules: 'required', + dependencies: { + triggerFields: ['sourceDocId'], + componentProps: (values) => ({ + class: '!w-full', + disabled: !!values.sourceDocId, + min: 0, + placeholder: '请输入检测数量', + precision: 2, + }), + }, + }, + { + fieldName: 'qualifiedQuantity', + label: '合格品数量', + component: 'InputNumber', + componentProps: { + class: '!w-full', + min: 0, + placeholder: '请输入合格品数量', + precision: 2, + }, + rules: 'required', + }, + { + fieldName: 'unqualifiedQuantity', + label: '不合格品数量', + component: 'InputNumber', + componentProps: { + class: '!w-full', + min: 0, + placeholder: '请输入不合格品数量', + precision: 2, + }, + rules: 'required', + }, + { + fieldName: 'laborScrapQuantity', + label: '工废数量', + component: 'InputNumber', + componentProps: { + class: '!w-full', + min: 0, + placeholder: '请输入工废数量', + precision: 2, + onChange: () => syncUnqualified(formApi), + }, + rules: 'required', + dependencies: { + triggerFields: ['unqualifiedQuantity'], + show: (values) => + values.unqualifiedQuantity != null && values.unqualifiedQuantity > 0, + }, + }, + { + fieldName: 'materialScrapQuantity', + label: '料废数量', + component: 'InputNumber', + componentProps: { + class: '!w-full', + min: 0, + placeholder: '请输入料废数量', + precision: 2, + onChange: () => syncUnqualified(formApi), + }, + rules: 'required', + dependencies: { + triggerFields: ['unqualifiedQuantity'], + show: (values) => + values.unqualifiedQuantity != null && values.unqualifiedQuantity > 0, + }, + }, + { + fieldName: 'otherScrapQuantity', + label: '其他废品数量', + component: 'InputNumber', + componentProps: { + class: '!w-full', + min: 0, + placeholder: '请输入其他废品数量', + precision: 2, + onChange: () => syncUnqualified(formApi), + }, + rules: 'required', + dependencies: { + triggerFields: ['unqualifiedQuantity'], + show: (values) => + values.unqualifiedQuantity != null && values.unqualifiedQuantity > 0, + }, + }, + { + fieldName: 'inspectorUserId', + label: '检测人员', + component: 'ApiSelect', + componentProps: { + allowClear: true, + api: getSimpleUserList, + labelField: 'nickname', + placeholder: '请选择检测人员', + valueField: 'id', + }, + rules: 'selectRequired', + }, + { + fieldName: 'inspectDate', + label: '检测日期', + component: 'DatePicker', + componentProps: { + format: 'YYYY-MM-DD', + placeholder: '请选择检测日期', + valueFormat: 'x', + }, + rules: 'required', + }, + { + fieldName: 'checkResult', + label: '检测结果', + component: 'Select', + componentProps: { + allowClear: true, + options: getDictOptions(DICT_TYPE.MES_QC_CHECK_RESULT, 'number'), + placeholder: '请选择检测结果', + }, + }, + { + fieldName: 'remark', + label: '备注', + component: 'Textarea', + formItemClass: 'col-span-3', + componentProps: { + placeholder: '请输入备注', + rows: 3, + }, + }, + ]; +} + +/** 列表的搜索表单 */ +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_IPQC_TYPE, 'number'), + placeholder: '请选择检验类型', + }, + }, + { + fieldName: 'workOrderId', + label: '生产工单', + component: markRaw(ProWorkOrderSelect), + componentProps: { + placeholder: '请选择生产工单', + }, + }, + { + fieldName: 'itemId', + label: '产品物料', + component: markRaw(MdItemSelect), + componentProps: { + placeholder: '请选择产品物料', + }, + }, + { + fieldName: 'checkResult', + label: '检测结果', + component: 'Select', + componentProps: { + allowClear: true, + options: getDictOptions(DICT_TYPE.MES_QC_CHECK_RESULT, 'number'), + placeholder: '请选择检测结果', + }, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + field: 'code', + title: '检验单编号', + width: 160, + slots: { default: 'code' }, + }, + { + field: 'name', + title: '检验单名称', + minWidth: 180, + }, + { + field: 'type', + title: '检验类型', + width: 120, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.MES_IPQC_TYPE }, + }, + }, + { + field: 'workOrderCode', + title: '生产工单编号', + width: 140, + }, + { + field: 'itemCode', + title: '产品物料编码', + width: 130, + }, + { + field: 'itemName', + title: '产品物料名称', + minWidth: 150, + }, + { + field: 'itemSpecification', + title: '规格型号', + width: 130, + }, + { + field: 'unitName', + title: '单位', + width: 80, + }, + { + field: 'checkQuantity', + title: '检测数量', + width: 100, + }, + { + field: 'checkResult', + title: '检测结果', + width: 110, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.MES_QC_CHECK_RESULT }, + }, + }, + { + field: 'inspectDate', + title: '检测日期', + width: 120, + formatter: 'formatDate', + }, + { + field: 'inspectorNickname', + title: '检测人员', + width: 100, + }, + { + field: 'status', + title: '单据状态', + width: 100, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.MES_ORDER_STATUS }, + }, + }, + { + title: '操作', + width: 180, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} + +/** 过程检验单行子表的字段 */ +export function useLineGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + field: 'indicatorName', + title: '检测项名称', + minWidth: 150, + }, + { + field: 'indicatorType', + title: '检测项类型', + width: 120, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.MES_INDICATOR_TYPE }, + }, + }, + { + field: 'toolName', + title: '检测工具', + width: 120, + }, + { + field: 'checkMethod', + title: '检测方法', + minWidth: 180, + }, + { + field: 'standardValue', + title: '标准值', + width: 100, + }, + { + field: 'unitMeasureName', + title: '单位', + width: 80, + }, + { + field: 'maxThreshold', + title: '误差上限', + width: 100, + }, + { + field: 'minThreshold', + title: '误差下限', + width: 100, + }, + { + field: 'criticalQuantity', + title: '致命缺陷数', + width: 110, + }, + { + field: 'majorQuantity', + title: '严重缺陷数', + width: 110, + }, + { + field: 'minorQuantity', + title: '轻微缺陷数', + width: 110, + }, + { + title: '操作', + width: 110, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} diff --git a/apps/web-antd/src/views/mes/qc/ipqc/index.vue b/apps/web-antd/src/views/mes/qc/ipqc/index.vue new file mode 100644 index 000000000..1bdb9c826 --- /dev/null +++ b/apps/web-antd/src/views/mes/qc/ipqc/index.vue @@ -0,0 +1,167 @@ + + + diff --git a/apps/web-antd/src/views/mes/qc/ipqc/modules/line-list.vue b/apps/web-antd/src/views/mes/qc/ipqc/modules/line-list.vue new file mode 100644 index 000000000..e6aaea4bb --- /dev/null +++ b/apps/web-antd/src/views/mes/qc/ipqc/modules/line-list.vue @@ -0,0 +1,97 @@ + + + diff --git a/apps/web-antd/src/views/mes/qc/oqc/data.ts b/apps/web-antd/src/views/mes/qc/oqc/data.ts new file mode 100644 index 000000000..2c70c0a7f --- /dev/null +++ b/apps/web-antd/src/views/mes/qc/oqc/data.ts @@ -0,0 +1,518 @@ +import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; +import type { MesQcOqcApi } from '#/api/mes/qc/oqc'; +import type { MesQcOqcLineApi } from '#/api/mes/qc/oqc/line'; + +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 { getSimpleUserList } from '#/api/system/user'; +import MdClientSelect from '#/views/mes/md/client/components/md-client-select.vue'; +import MdItemSelect from '#/views/mes/md/item/components/md-item-select.vue'; +import { MesAutoCodeRuleCode } from '#/views/mes/utils/constants'; + +/** 表单类型 */ +export type FormType = 'create' | 'detail' | 'update'; + +/** 新增/修改的表单 */ +export function useFormSchema(formApi?: VbenFormApi): VbenFormSchema[] { + return [ + { + fieldName: 'id', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'sourceDocId', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'sourceLineId', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'status', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'code', + label: '检验单编号', + component: 'Input', + componentProps: { + placeholder: '请输入检验单编号', + }, + rules: 'required', + suffix: () => + h( + Button, + { + type: 'default', + onClick: async () => { + try { + const code = await generateAutoCode( + MesAutoCodeRuleCode.QC_OQC_CODE, + ); + await formApi?.setFieldValue('code', code); + } catch (error) { + console.error(error); + } + }, + }, + { default: () => '生成' }, + ), + }, + { + fieldName: 'name', + label: '检验单名称', + component: 'Input', + componentProps: { + placeholder: '请输入检验单名称', + }, + rules: 'required', + }, + { + fieldName: 'sourceDocType', + label: '来源单据类型', + component: 'Select', + componentProps: { + disabled: true, + options: getDictOptions(DICT_TYPE.MES_QC_SOURCE_DOC_TYPE, 'number'), + placeholder: '来源单据类型', + }, + dependencies: { + triggerFields: ['sourceDocType'], + show: (values) => !!values.sourceDocType, + }, + }, + { + fieldName: 'sourceDocCode', + label: '来源单据编号', + component: 'Input', + componentProps: { + disabled: true, + placeholder: '来源单据编号', + }, + dependencies: { + triggerFields: ['sourceDocType', 'sourceDocId'], + show: (values) => !!values.sourceDocType && !!values.sourceDocId, + }, + }, + { + fieldName: 'itemId', + label: '产品物料', + component: markRaw(MdItemSelect), + componentProps: { + placeholder: '请选择产品物料', + }, + rules: 'selectRequired', + dependencies: { + triggerFields: ['sourceDocId'], + componentProps: (values) => ({ + disabled: !!values.sourceDocId, + placeholder: '请选择产品物料', + }), + }, + }, + { + fieldName: 'clientId', + label: '客户', + component: markRaw(MdClientSelect), + componentProps: { + placeholder: '请选择客户', + }, + rules: 'selectRequired', + dependencies: { + triggerFields: ['sourceDocId'], + componentProps: (values) => ({ + disabled: !!values.sourceDocId, + placeholder: '请选择客户', + }), + }, + }, + { + fieldName: 'batchCode', + label: '批次号', + component: 'Input', + componentProps: { + placeholder: '请输入批次号', + }, + }, + { + fieldName: 'outQuantity', + label: '发货数量', + component: 'InputNumber', + componentProps: { + class: '!w-full', + min: 0, + placeholder: '请输入发货数量', + precision: 2, + // 新建态下,发货数量变化时把 checkQuantity 也填上同值 + onChange: async (value: null | number | undefined) => { + if (value == null || !formApi) return; + const values = await formApi.getValues(); + if (!values.id && values.checkQuantity == null) { + await formApi.setFieldValue('checkQuantity', value); + } + }, + }, + rules: 'required', + dependencies: { + triggerFields: ['sourceDocId'], + componentProps: (values) => ({ + class: '!w-full', + disabled: !!values.sourceDocId, + min: 0, + placeholder: '请输入发货数量', + precision: 2, + onChange: async (value: null | number | undefined) => { + if (value == null || !formApi) return; + const current = await formApi.getValues(); + if (!current.id && current.checkQuantity == null) { + await formApi.setFieldValue('checkQuantity', value); + } + }, + }), + }, + }, + { + fieldName: 'checkQuantity', + label: '检测数量', + component: 'InputNumber', + componentProps: { + class: '!w-full', + min: 0, + placeholder: '请输入检测数量', + // 新建态下,检测数量变化时把 outQuantity 也填上同值 + onChange: async (value: null | number | undefined) => { + if (value == null || !formApi) return; + const values = await formApi.getValues(); + if (!values.id && values.outQuantity == null) { + await formApi.setFieldValue('outQuantity', value); + } + }, + }, + rules: 'required', + }, + { + fieldName: 'qualifiedQuantity', + label: '合格品数量', + component: 'InputNumber', + componentProps: { + class: '!w-full', + min: 0, + placeholder: '请输入合格品数量', + }, + rules: 'required', + }, + { + fieldName: 'unqualifiedQuantity', + label: '不合格品数量', + component: 'InputNumber', + componentProps: { + class: '!w-full', + min: 0, + placeholder: '请输入不合格品数量', + }, + rules: 'required', + }, + { + fieldName: 'inspectorUserId', + label: '检测人员', + component: 'ApiSelect', + componentProps: { + allowClear: true, + api: getSimpleUserList, + labelField: 'nickname', + placeholder: '请选择检测人员', + valueField: 'id', + }, + rules: 'selectRequired', + }, + { + fieldName: 'outDate', + label: '出货日期', + component: 'DatePicker', + componentProps: { + format: 'YYYY-MM-DD', + placeholder: '请选择出货日期', + valueFormat: 'x', + }, + rules: 'required', + }, + { + fieldName: 'inspectDate', + label: '检测日期', + component: 'DatePicker', + componentProps: { + format: 'YYYY-MM-DD', + placeholder: '请选择检测日期', + valueFormat: 'x', + }, + rules: 'required', + }, + { + fieldName: 'checkResult', + label: '检测结果', + component: 'Select', + componentProps: { + allowClear: true, + options: getDictOptions(DICT_TYPE.MES_QC_CHECK_RESULT, 'number'), + placeholder: '请选择检测结果', + }, + }, + { + fieldName: 'remark', + label: '备注', + component: 'Textarea', + formItemClass: 'col-span-3', + componentProps: { + placeholder: '请输入备注', + rows: 3, + }, + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'code', + label: '检验单编号', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入检验单编号', + }, + }, + { + fieldName: 'clientId', + label: '客户', + component: markRaw(MdClientSelect), + componentProps: { + placeholder: '请选择客户', + }, + }, + { + fieldName: 'batchCode', + label: '批次号', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入批次号', + }, + }, + { + fieldName: 'itemId', + label: '产品物料', + component: markRaw(MdItemSelect), + componentProps: { + placeholder: '请选择产品物料', + }, + }, + { + fieldName: 'checkResult', + label: '检测结果', + component: 'Select', + componentProps: { + allowClear: true, + options: getDictOptions(DICT_TYPE.MES_QC_CHECK_RESULT, 'number'), + placeholder: '请选择检测结果', + }, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + field: 'code', + title: '检验单编号', + width: 160, + slots: { default: 'code' }, + }, + { + field: 'name', + title: '检验单名称', + minWidth: 180, + }, + { + field: 'clientNickname', + title: '客户名称', + width: 120, + }, + { + field: 'batchCode', + title: '批次号', + width: 130, + }, + { + field: 'itemCode', + title: '产品物料编码', + width: 130, + }, + { + field: 'itemName', + title: '产品物料名称', + minWidth: 150, + }, + { + field: 'itemSpecification', + title: '规格型号', + minWidth: 150, + }, + { + field: 'unitName', + title: '单位', + width: 80, + }, + { + field: 'outQuantity', + title: '发货数量', + width: 100, + }, + { + field: 'checkQuantity', + title: '检测数量', + width: 100, + }, + { + field: 'unqualifiedQuantity', + title: '不合格数', + width: 100, + }, + { + field: 'checkResult', + title: '检测结果', + width: 110, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.MES_QC_CHECK_RESULT }, + }, + }, + { + field: 'outDate', + title: '出货日期', + width: 120, + formatter: 'formatDate', + }, + { + field: 'inspectDate', + title: '检测日期', + width: 120, + formatter: 'formatDate', + }, + { + field: 'inspectorNickname', + title: '检测人员', + width: 100, + }, + { + field: 'status', + title: '单据状态', + width: 100, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.MES_ORDER_STATUS }, + }, + }, + { + title: '操作', + width: 220, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} + +/** 出货检验单行子表的字段 */ +export function useLineGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + field: 'indicatorName', + title: '检测项名称', + minWidth: 150, + }, + { + field: 'indicatorType', + title: '检测项类型', + width: 120, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.MES_INDICATOR_TYPE }, + }, + }, + { + field: 'tool', + title: '检测工具', + width: 120, + }, + { + field: 'checkMethod', + title: '检测方法', + minWidth: 180, + }, + { + field: 'standardValue', + title: '标准值', + width: 100, + }, + { + field: 'unitMeasureName', + title: '单位', + width: 80, + }, + { + field: 'maxThreshold', + title: '误差上限', + width: 100, + }, + { + field: 'minThreshold', + title: '误差下限', + width: 100, + }, + { + field: 'criticalQuantity', + title: '致命缺陷数', + width: 110, + }, + { + field: 'majorQuantity', + title: '严重缺陷数', + width: 110, + }, + { + field: 'minorQuantity', + title: '轻微缺陷数', + width: 110, + }, + { + title: '操作', + width: 110, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} diff --git a/apps/web-antd/src/views/mes/qc/oqc/index.vue b/apps/web-antd/src/views/mes/qc/oqc/index.vue new file mode 100644 index 000000000..bda817e71 --- /dev/null +++ b/apps/web-antd/src/views/mes/qc/oqc/index.vue @@ -0,0 +1,167 @@ + + + diff --git a/apps/web-antd/src/views/mes/qc/oqc/modules/form.vue b/apps/web-antd/src/views/mes/qc/oqc/modules/form.vue new file mode 100644 index 000000000..f6e737cce --- /dev/null +++ b/apps/web-antd/src/views/mes/qc/oqc/modules/form.vue @@ -0,0 +1,231 @@ + + + diff --git a/apps/web-antd/src/views/mes/qc/oqc/modules/line-list.vue b/apps/web-antd/src/views/mes/qc/oqc/modules/line-list.vue new file mode 100644 index 000000000..b0f15b132 --- /dev/null +++ b/apps/web-antd/src/views/mes/qc/oqc/modules/line-list.vue @@ -0,0 +1,97 @@ + + + diff --git a/apps/web-antd/src/views/mes/qc/rqc/data.ts b/apps/web-antd/src/views/mes/qc/rqc/data.ts new file mode 100644 index 000000000..c08aa23f8 --- /dev/null +++ b/apps/web-antd/src/views/mes/qc/rqc/data.ts @@ -0,0 +1,495 @@ +import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; +import type { MesQcRqcApi } from '#/api/mes/qc/rqc'; +import type { MesQcRqcLineApi } from '#/api/mes/qc/rqc/line'; + +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 { getSimpleUserList } from '#/api/system/user'; +import MdItemSelect from '#/views/mes/md/item/components/md-item-select.vue'; +import { + MesAutoCodeRuleCode, + MesQcSourceDocTypeEnum, +} from '#/views/mes/utils/constants'; + +/** 表单类型 */ +export type FormType = 'create' | 'detail' | 'update'; + +/** 列表搜索专用:来源单据类型字典只允许 RQC 用到的两种 */ +function getRqcSourceDocTypeOptions() { + const allowed = new Set([ + MesQcSourceDocTypeEnum.RETURN_ISSUE, + MesQcSourceDocTypeEnum.RETURN_SALES, + ]); + return getDictOptions(DICT_TYPE.MES_QC_SOURCE_DOC_TYPE, 'number').filter( + (item) => allowed.has(Number(item.value)), + ); +} + +/** 新增/修改的表单 */ +export function useFormSchema(formApi?: VbenFormApi): VbenFormSchema[] { + return [ + { + fieldName: 'id', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'sourceDocId', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'sourceLineId', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'status', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'code', + label: '检验单编号', + component: 'Input', + componentProps: { + placeholder: '请输入检验单编号', + }, + rules: 'required', + suffix: () => + h( + Button, + { + type: 'default', + onClick: async () => { + try { + const code = await generateAutoCode( + MesAutoCodeRuleCode.QC_RQC_CODE, + ); + await formApi?.setFieldValue('code', code); + } catch (error) { + console.error(error); + } + }, + }, + { default: () => '生成' }, + ), + }, + { + fieldName: 'name', + label: '检验单名称', + component: 'Input', + componentProps: { + placeholder: '请输入检验单名称', + }, + rules: 'required', + }, + { + fieldName: 'sourceDocType', + label: '来源单据类型', + component: 'Select', + componentProps: { + disabled: true, + options: getDictOptions(DICT_TYPE.MES_QC_SOURCE_DOC_TYPE, 'number'), + placeholder: '来源单据类型', + }, + dependencies: { + triggerFields: ['sourceDocType'], + show: (values) => !!values.sourceDocType, + }, + }, + { + fieldName: 'sourceDocCode', + label: '来源单据编号', + component: 'Input', + componentProps: { + disabled: true, + placeholder: '来源单据编号', + }, + dependencies: { + triggerFields: ['sourceDocType', 'sourceDocId'], + show: (values) => !!values.sourceDocType && !!values.sourceDocId, + }, + }, + { + fieldName: 'type', + label: '检验类型', + component: 'Select', + componentProps: { + allowClear: true, + options: getDictOptions(DICT_TYPE.MES_RQC_TYPE, 'number'), + placeholder: '请选择检验类型', + }, + rules: 'selectRequired', + }, + { + fieldName: 'itemId', + label: '产品物料', + component: markRaw(MdItemSelect), + componentProps: { + placeholder: '请选择产品物料', + }, + rules: 'selectRequired', + dependencies: { + triggerFields: ['sourceDocId'], + componentProps: (values) => ({ + disabled: !!values.sourceDocId, + placeholder: '请选择产品物料', + }), + }, + }, + { + fieldName: 'batchCode', + label: '批次号', + component: 'Input', + componentProps: { + placeholder: '请输入批次号', + }, + }, + { + fieldName: 'checkQuantity', + label: '检测数量', + component: 'InputNumber', + componentProps: { + class: '!w-full', + min: 0, + placeholder: '请输入', + precision: 2, + }, + rules: 'required', + dependencies: { + triggerFields: ['sourceDocId'], + componentProps: (values) => ({ + class: '!w-full', + disabled: !!values.sourceDocId, + min: 0, + placeholder: '请输入', + precision: 2, + }), + }, + }, + { + fieldName: 'qualifiedQuantity', + label: '合格品数量', + component: 'InputNumber', + componentProps: { + class: '!w-full', + min: 0, + placeholder: '请输入', + precision: 2, + }, + rules: 'required', + }, + { + fieldName: 'unqualifiedQuantity', + label: '不合格品数量', + component: 'InputNumber', + componentProps: { + class: '!w-full', + min: 0, + placeholder: '请输入', + precision: 2, + }, + rules: 'required', + }, + { + fieldName: 'inspectDate', + label: '检测日期', + component: 'DatePicker', + componentProps: { + format: 'YYYY-MM-DD HH:mm:ss', + placeholder: '请选择检测日期', + showTime: true, + valueFormat: 'x', + }, + rules: 'required', + }, + { + fieldName: 'inspectorUserId', + label: '检测人员', + component: 'ApiSelect', + componentProps: { + allowClear: true, + api: getSimpleUserList, + labelField: 'nickname', + placeholder: '请选择检测人员', + valueField: 'id', + }, + rules: 'selectRequired', + }, + { + fieldName: 'checkResult', + label: '检测结果', + component: 'Select', + componentProps: { + allowClear: true, + options: getDictOptions(DICT_TYPE.MES_QC_CHECK_RESULT, 'number'), + placeholder: '请选择检测结果', + }, + }, + { + fieldName: 'remark', + label: '备注', + component: 'Textarea', + formItemClass: 'col-span-3', + componentProps: { + placeholder: '请输入备注', + rows: 3, + }, + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'code', + label: '检验单编号', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入检验单编号', + }, + }, + { + fieldName: 'sourceDocType', + label: '来源单据类型', + component: 'Select', + componentProps: { + allowClear: true, + options: getRqcSourceDocTypeOptions(), + placeholder: '请选择来源单据类型', + }, + }, + { + fieldName: 'sourceDocCode', + label: '来源单据编号', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入来源单据编号', + }, + }, + { + fieldName: 'itemId', + label: '产品物料', + component: markRaw(MdItemSelect), + componentProps: { + placeholder: '请选择产品物料', + }, + }, + { + fieldName: 'batchCode', + label: '批次号', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入批次号', + }, + }, + { + fieldName: 'checkResult', + label: '检测结果', + component: 'Select', + componentProps: { + allowClear: true, + options: getDictOptions(DICT_TYPE.MES_QC_CHECK_RESULT, 'number'), + placeholder: '请选择检测结果', + }, + }, + { + fieldName: 'inspectorUserId', + label: '检测人员', + component: 'ApiSelect', + componentProps: { + allowClear: true, + api: getSimpleUserList, + labelField: 'nickname', + placeholder: '请选择检测人员', + valueField: 'id', + }, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + field: 'code', + title: '检验单编号', + width: 160, + slots: { default: 'code' }, + }, + { + field: 'name', + title: '检验单名称', + minWidth: 180, + }, + { + field: 'sourceDocType', + title: '来源单据类型', + width: 120, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.MES_QC_SOURCE_DOC_TYPE }, + }, + }, + { + field: 'sourceDocCode', + title: '来源单据编码', + width: 160, + }, + { + field: 'itemCode', + title: '产品物料编码', + width: 130, + }, + { + field: 'itemName', + title: '产品物料名称', + minWidth: 150, + }, + { + field: 'itemSpecification', + title: '规格型号', + width: 130, + }, + { + field: 'unitName', + title: '单位', + width: 80, + }, + { + field: 'batchCode', + title: '批次号', + width: 130, + }, + { + field: 'checkResult', + title: '检测结果', + width: 110, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.MES_QC_CHECK_RESULT }, + }, + }, + { + field: 'inspectDate', + title: '检测日期', + width: 160, + formatter: 'formatDateTime', + }, + { + field: 'inspectorNickname', + title: '检测人员', + width: 100, + }, + { + field: 'status', + title: '单据状态', + width: 100, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.MES_ORDER_STATUS }, + }, + }, + { + title: '操作', + width: 180, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} + +/** 退货检验单行子表的字段 */ +export function useLineGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + field: 'indicatorName', + title: '检测项名称', + minWidth: 150, + }, + { + field: 'indicatorType', + title: '检测项类型', + width: 120, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.MES_INDICATOR_TYPE }, + }, + }, + { + field: 'tool', + title: '检测工具', + width: 120, + }, + { + field: 'checkMethod', + title: '检测方法', + minWidth: 180, + }, + { + field: 'standardValue', + title: '标准值', + width: 100, + }, + { + field: 'unitMeasureName', + title: '单位', + width: 80, + }, + { + field: 'maxThreshold', + title: '误差上限', + width: 100, + }, + { + field: 'minThreshold', + title: '误差下限', + width: 100, + }, + { + field: 'criticalQuantity', + title: '致命缺陷数', + width: 110, + }, + { + field: 'majorQuantity', + title: '严重缺陷数', + width: 110, + }, + { + field: 'minorQuantity', + title: '轻微缺陷数', + width: 110, + }, + { + title: '操作', + width: 110, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} diff --git a/apps/web-antd/src/views/mes/qc/rqc/index.vue b/apps/web-antd/src/views/mes/qc/rqc/index.vue new file mode 100644 index 000000000..f37370a86 --- /dev/null +++ b/apps/web-antd/src/views/mes/qc/rqc/index.vue @@ -0,0 +1,167 @@ + + + diff --git a/apps/web-antd/src/views/mes/qc/rqc/modules/form.vue b/apps/web-antd/src/views/mes/qc/rqc/modules/form.vue new file mode 100644 index 000000000..2d8efce96 --- /dev/null +++ b/apps/web-antd/src/views/mes/qc/rqc/modules/form.vue @@ -0,0 +1,232 @@ + + + diff --git a/apps/web-antd/src/views/mes/qc/rqc/modules/line-list.vue b/apps/web-antd/src/views/mes/qc/rqc/modules/line-list.vue new file mode 100644 index 000000000..8c50238fa --- /dev/null +++ b/apps/web-antd/src/views/mes/qc/rqc/modules/line-list.vue @@ -0,0 +1,97 @@ + + + diff --git a/apps/web-ele/src/views/mes/qc/ipqc/data.ts b/apps/web-ele/src/views/mes/qc/ipqc/data.ts new file mode 100644 index 000000000..2ecd804ba --- /dev/null +++ b/apps/web-ele/src/views/mes/qc/ipqc/data.ts @@ -0,0 +1,573 @@ +import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; +import type { MesQcIpqcApi } from '#/api/mes/qc/ipqc'; +import type { MesQcIpqcLineApi } from '#/api/mes/qc/ipqc/line'; + +import { h, markRaw } from 'vue'; + +import { DICT_TYPE } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; + +import { ElButton } from 'element-plus'; + +import { generateAutoCode } from '#/api/mes/md/autocode/record'; +import { getSimpleUserList } from '#/api/system/user'; +import MdItemSelect from '#/views/mes/md/item/components/md-item-select.vue'; +import MdWorkstationSelect from '#/views/mes/md/workstation/components/md-workstation-select.vue'; +import ProTaskSelect from '#/views/mes/pro/task/components/pro-task-select.vue'; +import ProWorkOrderSelect from '#/views/mes/pro/workorder/components/pro-work-order-select.vue'; +import { + MesAutoCodeRuleCode, + MesProTaskStatusEnum, + MesProWorkOrderStatusEnum, +} from '#/views/mes/utils/constants'; + +/** 表单类型 */ +export type FormType = 'create' | 'detail' | 'update'; + +/** 把不合格品数量同步为工废 + 料废 + 其他废品之和 */ +function syncUnqualified(formApi?: VbenFormApi) { + if (!formApi) { + return; + } + void (async () => { + const values = await formApi.getValues(); + const next = + Number(values.laborScrapQuantity || 0) + + Number(values.materialScrapQuantity || 0) + + Number(values.otherScrapQuantity || 0); + await formApi.setFieldValue('unqualifiedQuantity', next); + })(); +} + +/** 新增/修改的表单 */ +export function useFormSchema(formApi?: VbenFormApi): VbenFormSchema[] { + return [ + { + fieldName: 'id', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'sourceDocId', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'sourceLineId', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'status', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'code', + label: '检验单编号', + component: 'Input', + componentProps: { + placeholder: '请输入检验单编号', + }, + rules: 'required', + suffix: () => + h( + ElButton, + { + onClick: async () => { + try { + const code = await generateAutoCode( + MesAutoCodeRuleCode.QC_IPQC_CODE, + ); + await formApi?.setFieldValue('code', code); + } catch (error) { + console.error(error); + } + }, + }, + { default: () => '生成' }, + ), + }, + { + fieldName: 'name', + label: '检验单名称', + component: 'Input', + componentProps: { + placeholder: '请输入检验单名称', + }, + rules: 'required', + }, + { + fieldName: 'type', + label: '检验类型', + component: 'Select', + componentProps: { + clearable: true, + options: getDictOptions(DICT_TYPE.MES_IPQC_TYPE, 'number'), + placeholder: '请选择检验类型', + }, + rules: 'selectRequired', + }, + { + fieldName: 'sourceDocType', + label: '来源单据类型', + component: 'Select', + componentProps: { + disabled: true, + options: getDictOptions(DICT_TYPE.MES_QC_SOURCE_DOC_TYPE, 'number'), + placeholder: '来源单据类型', + }, + dependencies: { + triggerFields: ['sourceDocType'], + show: (values) => !!values.sourceDocType, + }, + }, + { + fieldName: 'sourceDocCode', + label: '来源单据编号', + component: 'Input', + componentProps: { + disabled: true, + placeholder: '来源单据编号', + }, + dependencies: { + triggerFields: ['sourceDocType', 'sourceDocId'], + show: (values) => !!values.sourceDocType && !!values.sourceDocId, + }, + }, + { + fieldName: 'workOrderId', + label: '生产工单', + component: markRaw(ProWorkOrderSelect), + componentProps: { + placeholder: '请选择生产工单', + status: MesProWorkOrderStatusEnum.CONFIRMED, + // 工单变更时清空生产任务 + onChange: () => formApi?.setFieldValue('taskId', undefined), + }, + rules: 'selectRequired', + dependencies: { + triggerFields: ['sourceDocId'], + componentProps: (values) => ({ + disabled: !!values.sourceDocId, + placeholder: '请选择生产工单', + status: MesProWorkOrderStatusEnum.CONFIRMED, + onChange: () => formApi?.setFieldValue('taskId', undefined), + }), + }, + }, + { + fieldName: 'workstationId', + label: '工位', + component: markRaw(MdWorkstationSelect), + componentProps: { + placeholder: '请选择工位', + }, + rules: 'selectRequired', + dependencies: { + triggerFields: ['sourceDocId'], + componentProps: (values) => ({ + disabled: !!values.sourceDocId, + placeholder: '请选择工位', + }), + }, + }, + { + fieldName: 'taskId', + label: '生产任务', + component: markRaw(ProTaskSelect), + componentProps: { + placeholder: '请选择生产任务', + statuses: [MesProTaskStatusEnum.PREPARE], + }, + dependencies: { + triggerFields: ['sourceDocId', 'workOrderId', 'workstationId'], + componentProps: (values) => ({ + disabled: !!values.sourceDocId || !values.workOrderId, + placeholder: '请选择生产任务', + statuses: [MesProTaskStatusEnum.PREPARE], + workOrderId: values.workOrderId, + workstationId: values.workstationId, + }), + }, + }, + { + fieldName: 'checkQuantity', + label: '检测数量', + component: 'InputNumber', + componentProps: { + class: '!w-full', + controlsPosition: 'right', + min: 0, + placeholder: '请输入检测数量', + precision: 2, + }, + rules: 'required', + dependencies: { + triggerFields: ['sourceDocId'], + componentProps: (values) => ({ + class: '!w-full', + controlsPosition: 'right', + disabled: !!values.sourceDocId, + min: 0, + placeholder: '请输入检测数量', + precision: 2, + }), + }, + }, + { + fieldName: 'qualifiedQuantity', + label: '合格品数量', + component: 'InputNumber', + componentProps: { + class: '!w-full', + controlsPosition: 'right', + min: 0, + placeholder: '请输入合格品数量', + precision: 2, + }, + rules: 'required', + }, + { + fieldName: 'unqualifiedQuantity', + label: '不合格品数量', + component: 'InputNumber', + componentProps: { + class: '!w-full', + controlsPosition: 'right', + min: 0, + placeholder: '请输入不合格品数量', + precision: 2, + }, + rules: 'required', + }, + { + fieldName: 'laborScrapQuantity', + label: '工废数量', + component: 'InputNumber', + componentProps: { + class: '!w-full', + controlsPosition: 'right', + min: 0, + placeholder: '请输入工废数量', + precision: 2, + onChange: () => syncUnqualified(formApi), + }, + rules: 'required', + dependencies: { + triggerFields: ['unqualifiedQuantity'], + show: (values) => + values.unqualifiedQuantity != null && values.unqualifiedQuantity > 0, + }, + }, + { + fieldName: 'materialScrapQuantity', + label: '料废数量', + component: 'InputNumber', + componentProps: { + class: '!w-full', + controlsPosition: 'right', + min: 0, + placeholder: '请输入料废数量', + precision: 2, + onChange: () => syncUnqualified(formApi), + }, + rules: 'required', + dependencies: { + triggerFields: ['unqualifiedQuantity'], + show: (values) => + values.unqualifiedQuantity != null && values.unqualifiedQuantity > 0, + }, + }, + { + fieldName: 'otherScrapQuantity', + label: '其他废品数量', + component: 'InputNumber', + componentProps: { + class: '!w-full', + controlsPosition: 'right', + min: 0, + placeholder: '请输入其他废品数量', + precision: 2, + onChange: () => syncUnqualified(formApi), + }, + rules: 'required', + dependencies: { + triggerFields: ['unqualifiedQuantity'], + show: (values) => + values.unqualifiedQuantity != null && values.unqualifiedQuantity > 0, + }, + }, + { + fieldName: 'inspectorUserId', + label: '检测人员', + component: 'ApiSelect', + componentProps: { + api: getSimpleUserList, + clearable: true, + labelField: 'nickname', + placeholder: '请选择检测人员', + valueField: 'id', + }, + rules: 'selectRequired', + }, + { + fieldName: 'inspectDate', + label: '检测日期', + component: 'DatePicker', + componentProps: { + format: 'YYYY-MM-DD', + placeholder: '请选择检测日期', + type: 'date', + valueFormat: 'x', + }, + rules: 'required', + }, + { + fieldName: 'checkResult', + label: '检测结果', + component: 'Select', + componentProps: { + clearable: true, + options: getDictOptions(DICT_TYPE.MES_QC_CHECK_RESULT, 'number'), + placeholder: '请选择检测结果', + }, + }, + { + fieldName: 'remark', + label: '备注', + component: 'Textarea', + formItemClass: 'col-span-3', + componentProps: { + placeholder: '请输入备注', + rows: 3, + }, + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'code', + label: '检验单编号', + component: 'Input', + componentProps: { + clearable: true, + placeholder: '请输入检验单编号', + }, + }, + { + fieldName: 'type', + label: '检验类型', + component: 'Select', + componentProps: { + clearable: true, + options: getDictOptions(DICT_TYPE.MES_IPQC_TYPE, 'number'), + placeholder: '请选择检验类型', + }, + }, + { + fieldName: 'workOrderId', + label: '生产工单', + component: markRaw(ProWorkOrderSelect), + componentProps: { + placeholder: '请选择生产工单', + }, + }, + { + fieldName: 'itemId', + label: '产品物料', + component: markRaw(MdItemSelect), + componentProps: { + placeholder: '请选择产品物料', + }, + }, + { + fieldName: 'checkResult', + label: '检测结果', + component: 'Select', + componentProps: { + clearable: true, + options: getDictOptions(DICT_TYPE.MES_QC_CHECK_RESULT, 'number'), + placeholder: '请选择检测结果', + }, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + field: 'code', + title: '检验单编号', + width: 160, + slots: { default: 'code' }, + }, + { + field: 'name', + title: '检验单名称', + minWidth: 180, + }, + { + field: 'type', + title: '检验类型', + width: 120, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.MES_IPQC_TYPE }, + }, + }, + { + field: 'workOrderCode', + title: '生产工单编号', + width: 140, + }, + { + field: 'itemCode', + title: '产品物料编码', + width: 130, + }, + { + field: 'itemName', + title: '产品物料名称', + minWidth: 150, + }, + { + field: 'itemSpecification', + title: '规格型号', + width: 130, + }, + { + field: 'unitName', + title: '单位', + width: 80, + }, + { + field: 'checkQuantity', + title: '检测数量', + width: 100, + }, + { + field: 'checkResult', + title: '检测结果', + width: 110, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.MES_QC_CHECK_RESULT }, + }, + }, + { + field: 'inspectDate', + title: '检测日期', + width: 120, + formatter: 'formatDate', + }, + { + field: 'inspectorNickname', + title: '检测人员', + width: 100, + }, + { + field: 'status', + title: '单据状态', + width: 100, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.MES_ORDER_STATUS }, + }, + }, + { + title: '操作', + width: 180, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} + +/** 过程检验单行子表的字段 */ +export function useLineGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + field: 'indicatorName', + title: '检测项名称', + minWidth: 150, + }, + { + field: 'indicatorType', + title: '检测项类型', + width: 120, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.MES_INDICATOR_TYPE }, + }, + }, + { + field: 'toolName', + title: '检测工具', + width: 120, + }, + { + field: 'checkMethod', + title: '检测方法', + minWidth: 180, + }, + { + field: 'standardValue', + title: '标准值', + width: 100, + }, + { + field: 'unitMeasureName', + title: '单位', + width: 80, + }, + { + field: 'maxThreshold', + title: '误差上限', + width: 100, + }, + { + field: 'minThreshold', + title: '误差下限', + width: 100, + }, + { + field: 'criticalQuantity', + title: '致命缺陷数', + width: 110, + }, + { + field: 'majorQuantity', + title: '严重缺陷数', + width: 110, + }, + { + field: 'minorQuantity', + title: '轻微缺陷数', + width: 110, + }, + { + title: '操作', + width: 110, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} diff --git a/apps/web-ele/src/views/mes/qc/ipqc/index.vue b/apps/web-ele/src/views/mes/qc/ipqc/index.vue new file mode 100644 index 000000000..5cf39a502 --- /dev/null +++ b/apps/web-ele/src/views/mes/qc/ipqc/index.vue @@ -0,0 +1,168 @@ + + + diff --git a/apps/web-ele/src/views/mes/qc/ipqc/modules/form.vue b/apps/web-ele/src/views/mes/qc/ipqc/modules/form.vue new file mode 100644 index 000000000..9180f1662 --- /dev/null +++ b/apps/web-ele/src/views/mes/qc/ipqc/modules/form.vue @@ -0,0 +1,233 @@ + + + diff --git a/apps/web-ele/src/views/mes/qc/ipqc/modules/line-list.vue b/apps/web-ele/src/views/mes/qc/ipqc/modules/line-list.vue new file mode 100644 index 000000000..cfb8dc99d --- /dev/null +++ b/apps/web-ele/src/views/mes/qc/ipqc/modules/line-list.vue @@ -0,0 +1,98 @@ + + + diff --git a/apps/web-ele/src/views/mes/qc/oqc/data.ts b/apps/web-ele/src/views/mes/qc/oqc/data.ts new file mode 100644 index 000000000..b5027d32b --- /dev/null +++ b/apps/web-ele/src/views/mes/qc/oqc/data.ts @@ -0,0 +1,524 @@ +import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; +import type { MesQcOqcApi } from '#/api/mes/qc/oqc'; +import type { MesQcOqcLineApi } from '#/api/mes/qc/oqc/line'; + +import { h, markRaw } from 'vue'; + +import { DICT_TYPE } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; + +import { ElButton } from 'element-plus'; + +import { generateAutoCode } from '#/api/mes/md/autocode/record'; +import { getSimpleUserList } from '#/api/system/user'; +import MdClientSelect from '#/views/mes/md/client/components/md-client-select.vue'; +import MdItemSelect from '#/views/mes/md/item/components/md-item-select.vue'; +import { MesAutoCodeRuleCode } from '#/views/mes/utils/constants'; + +/** 表单类型 */ +export type FormType = 'create' | 'detail' | 'update'; + +/** 新增/修改的表单 */ +export function useFormSchema(formApi?: VbenFormApi): VbenFormSchema[] { + return [ + { + fieldName: 'id', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'sourceDocId', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'sourceLineId', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'status', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'code', + label: '检验单编号', + component: 'Input', + componentProps: { + placeholder: '请输入检验单编号', + }, + rules: 'required', + suffix: () => + h( + ElButton, + { + onClick: async () => { + try { + const code = await generateAutoCode( + MesAutoCodeRuleCode.QC_OQC_CODE, + ); + await formApi?.setFieldValue('code', code); + } catch (error) { + console.error(error); + } + }, + }, + { default: () => '生成' }, + ), + }, + { + fieldName: 'name', + label: '检验单名称', + component: 'Input', + componentProps: { + placeholder: '请输入检验单名称', + }, + rules: 'required', + }, + { + fieldName: 'sourceDocType', + label: '来源单据类型', + component: 'Select', + componentProps: { + disabled: true, + options: getDictOptions(DICT_TYPE.MES_QC_SOURCE_DOC_TYPE, 'number'), + placeholder: '来源单据类型', + }, + dependencies: { + triggerFields: ['sourceDocType'], + show: (values) => !!values.sourceDocType, + }, + }, + { + fieldName: 'sourceDocCode', + label: '来源单据编号', + component: 'Input', + componentProps: { + disabled: true, + placeholder: '来源单据编号', + }, + dependencies: { + triggerFields: ['sourceDocType', 'sourceDocId'], + show: (values) => !!values.sourceDocType && !!values.sourceDocId, + }, + }, + { + fieldName: 'itemId', + label: '产品物料', + component: markRaw(MdItemSelect), + componentProps: { + placeholder: '请选择产品物料', + }, + rules: 'selectRequired', + dependencies: { + triggerFields: ['sourceDocId'], + componentProps: (values) => ({ + disabled: !!values.sourceDocId, + placeholder: '请选择产品物料', + }), + }, + }, + { + fieldName: 'clientId', + label: '客户', + component: markRaw(MdClientSelect), + componentProps: { + placeholder: '请选择客户', + }, + rules: 'selectRequired', + dependencies: { + triggerFields: ['sourceDocId'], + componentProps: (values) => ({ + disabled: !!values.sourceDocId, + placeholder: '请选择客户', + }), + }, + }, + { + fieldName: 'batchCode', + label: '批次号', + component: 'Input', + componentProps: { + placeholder: '请输入批次号', + }, + }, + { + fieldName: 'outQuantity', + label: '发货数量', + component: 'InputNumber', + componentProps: { + class: '!w-full', + controlsPosition: 'right', + min: 0, + placeholder: '请输入发货数量', + precision: 2, + // 新建态下,发货数量变化时把 checkQuantity 也填上同值 + onChange: async (value: null | number | undefined) => { + if (value == null || !formApi) return; + const values = await formApi.getValues(); + if (!values.id && values.checkQuantity == null) { + await formApi.setFieldValue('checkQuantity', value); + } + }, + }, + rules: 'required', + dependencies: { + triggerFields: ['sourceDocId'], + componentProps: (values) => ({ + class: '!w-full', + controlsPosition: 'right', + disabled: !!values.sourceDocId, + min: 0, + placeholder: '请输入发货数量', + precision: 2, + onChange: async (value: null | number | undefined) => { + if (value == null || !formApi) return; + const current = await formApi.getValues(); + if (!current.id && current.checkQuantity == null) { + await formApi.setFieldValue('checkQuantity', value); + } + }, + }), + }, + }, + { + fieldName: 'checkQuantity', + label: '检测数量', + component: 'InputNumber', + componentProps: { + class: '!w-full', + controlsPosition: 'right', + min: 0, + placeholder: '请输入检测数量', + // 新建态下,检测数量变化时把 outQuantity 也填上同值 + onChange: async (value: null | number | undefined) => { + if (value == null || !formApi) return; + const values = await formApi.getValues(); + if (!values.id && values.outQuantity == null) { + await formApi.setFieldValue('outQuantity', value); + } + }, + }, + rules: 'required', + }, + { + fieldName: 'qualifiedQuantity', + label: '合格品数量', + component: 'InputNumber', + componentProps: { + class: '!w-full', + controlsPosition: 'right', + min: 0, + placeholder: '请输入合格品数量', + }, + rules: 'required', + }, + { + fieldName: 'unqualifiedQuantity', + label: '不合格品数量', + component: 'InputNumber', + componentProps: { + class: '!w-full', + controlsPosition: 'right', + min: 0, + placeholder: '请输入不合格品数量', + }, + rules: 'required', + }, + { + fieldName: 'inspectorUserId', + label: '检测人员', + component: 'ApiSelect', + componentProps: { + api: getSimpleUserList, + clearable: true, + labelField: 'nickname', + placeholder: '请选择检测人员', + valueField: 'id', + }, + rules: 'selectRequired', + }, + { + fieldName: 'outDate', + label: '出货日期', + component: 'DatePicker', + componentProps: { + format: 'YYYY-MM-DD', + placeholder: '请选择出货日期', + type: 'date', + valueFormat: 'x', + }, + rules: 'required', + }, + { + fieldName: 'inspectDate', + label: '检测日期', + component: 'DatePicker', + componentProps: { + format: 'YYYY-MM-DD', + placeholder: '请选择检测日期', + type: 'date', + valueFormat: 'x', + }, + rules: 'required', + }, + { + fieldName: 'checkResult', + label: '检测结果', + component: 'Select', + componentProps: { + clearable: true, + options: getDictOptions(DICT_TYPE.MES_QC_CHECK_RESULT, 'number'), + placeholder: '请选择检测结果', + }, + }, + { + fieldName: 'remark', + label: '备注', + component: 'Textarea', + formItemClass: 'col-span-3', + componentProps: { + placeholder: '请输入备注', + rows: 3, + }, + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'code', + label: '检验单编号', + component: 'Input', + componentProps: { + clearable: true, + placeholder: '请输入检验单编号', + }, + }, + { + fieldName: 'clientId', + label: '客户', + component: markRaw(MdClientSelect), + componentProps: { + placeholder: '请选择客户', + }, + }, + { + fieldName: 'batchCode', + label: '批次号', + component: 'Input', + componentProps: { + clearable: true, + placeholder: '请输入批次号', + }, + }, + { + fieldName: 'itemId', + label: '产品物料', + component: markRaw(MdItemSelect), + componentProps: { + placeholder: '请选择产品物料', + }, + }, + { + fieldName: 'checkResult', + label: '检测结果', + component: 'Select', + componentProps: { + clearable: true, + options: getDictOptions(DICT_TYPE.MES_QC_CHECK_RESULT, 'number'), + placeholder: '请选择检测结果', + }, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + field: 'code', + title: '检验单编号', + width: 160, + slots: { default: 'code' }, + }, + { + field: 'name', + title: '检验单名称', + minWidth: 180, + }, + { + field: 'clientNickname', + title: '客户名称', + width: 120, + }, + { + field: 'batchCode', + title: '批次号', + width: 130, + }, + { + field: 'itemCode', + title: '产品物料编码', + width: 130, + }, + { + field: 'itemName', + title: '产品物料名称', + minWidth: 150, + }, + { + field: 'itemSpecification', + title: '规格型号', + minWidth: 150, + }, + { + field: 'unitName', + title: '单位', + width: 80, + }, + { + field: 'outQuantity', + title: '发货数量', + width: 100, + }, + { + field: 'checkQuantity', + title: '检测数量', + width: 100, + }, + { + field: 'unqualifiedQuantity', + title: '不合格数', + width: 100, + }, + { + field: 'checkResult', + title: '检测结果', + width: 110, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.MES_QC_CHECK_RESULT }, + }, + }, + { + field: 'outDate', + title: '出货日期', + width: 120, + formatter: 'formatDate', + }, + { + field: 'inspectDate', + title: '检测日期', + width: 120, + formatter: 'formatDate', + }, + { + field: 'inspectorNickname', + title: '检测人员', + width: 100, + }, + { + field: 'status', + title: '单据状态', + width: 100, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.MES_ORDER_STATUS }, + }, + }, + { + title: '操作', + width: 220, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} + +/** 出货检验单行子表的字段 */ +export function useLineGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + field: 'indicatorName', + title: '检测项名称', + minWidth: 150, + }, + { + field: 'indicatorType', + title: '检测项类型', + width: 120, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.MES_INDICATOR_TYPE }, + }, + }, + { + field: 'tool', + title: '检测工具', + width: 120, + }, + { + field: 'checkMethod', + title: '检测方法', + minWidth: 180, + }, + { + field: 'standardValue', + title: '标准值', + width: 100, + }, + { + field: 'unitMeasureName', + title: '单位', + width: 80, + }, + { + field: 'maxThreshold', + title: '误差上限', + width: 100, + }, + { + field: 'minThreshold', + title: '误差下限', + width: 100, + }, + { + field: 'criticalQuantity', + title: '致命缺陷数', + width: 110, + }, + { + field: 'majorQuantity', + title: '严重缺陷数', + width: 110, + }, + { + field: 'minorQuantity', + title: '轻微缺陷数', + width: 110, + }, + { + title: '操作', + width: 110, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} diff --git a/apps/web-ele/src/views/mes/qc/oqc/index.vue b/apps/web-ele/src/views/mes/qc/oqc/index.vue new file mode 100644 index 000000000..f736d25c1 --- /dev/null +++ b/apps/web-ele/src/views/mes/qc/oqc/index.vue @@ -0,0 +1,168 @@ + + + diff --git a/apps/web-ele/src/views/mes/qc/oqc/modules/form.vue b/apps/web-ele/src/views/mes/qc/oqc/modules/form.vue new file mode 100644 index 000000000..88d95e6ab --- /dev/null +++ b/apps/web-ele/src/views/mes/qc/oqc/modules/form.vue @@ -0,0 +1,233 @@ + + + diff --git a/apps/web-ele/src/views/mes/qc/oqc/modules/line-list.vue b/apps/web-ele/src/views/mes/qc/oqc/modules/line-list.vue new file mode 100644 index 000000000..18af3731c --- /dev/null +++ b/apps/web-ele/src/views/mes/qc/oqc/modules/line-list.vue @@ -0,0 +1,98 @@ + + + diff --git a/apps/web-ele/src/views/mes/qc/rqc/data.ts b/apps/web-ele/src/views/mes/qc/rqc/data.ts new file mode 100644 index 000000000..1486090ec --- /dev/null +++ b/apps/web-ele/src/views/mes/qc/rqc/data.ts @@ -0,0 +1,498 @@ +import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; +import type { MesQcRqcApi } from '#/api/mes/qc/rqc'; +import type { MesQcRqcLineApi } from '#/api/mes/qc/rqc/line'; + +import { h, markRaw } from 'vue'; + +import { DICT_TYPE } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; + +import { ElButton } from 'element-plus'; + +import { generateAutoCode } from '#/api/mes/md/autocode/record'; +import { getSimpleUserList } from '#/api/system/user'; +import MdItemSelect from '#/views/mes/md/item/components/md-item-select.vue'; +import { + MesAutoCodeRuleCode, + MesQcSourceDocTypeEnum, +} from '#/views/mes/utils/constants'; + +/** 表单类型 */ +export type FormType = 'create' | 'detail' | 'update'; + +/** 列表搜索专用:来源单据类型字典只允许 RQC 用到的两种 */ +function getRqcSourceDocTypeOptions() { + const allowed = new Set([ + MesQcSourceDocTypeEnum.RETURN_ISSUE, + MesQcSourceDocTypeEnum.RETURN_SALES, + ]); + return getDictOptions(DICT_TYPE.MES_QC_SOURCE_DOC_TYPE, 'number').filter( + (item) => allowed.has(Number(item.value)), + ); +} + +/** 新增/修改的表单 */ +export function useFormSchema(formApi?: VbenFormApi): VbenFormSchema[] { + return [ + { + fieldName: 'id', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'sourceDocId', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'sourceLineId', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'status', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'code', + label: '检验单编号', + component: 'Input', + componentProps: { + placeholder: '请输入检验单编号', + }, + rules: 'required', + suffix: () => + h( + ElButton, + { + onClick: async () => { + try { + const code = await generateAutoCode( + MesAutoCodeRuleCode.QC_RQC_CODE, + ); + await formApi?.setFieldValue('code', code); + } catch (error) { + console.error(error); + } + }, + }, + { default: () => '生成' }, + ), + }, + { + fieldName: 'name', + label: '检验单名称', + component: 'Input', + componentProps: { + placeholder: '请输入检验单名称', + }, + rules: 'required', + }, + { + fieldName: 'sourceDocType', + label: '来源单据类型', + component: 'Select', + componentProps: { + disabled: true, + options: getDictOptions(DICT_TYPE.MES_QC_SOURCE_DOC_TYPE, 'number'), + placeholder: '来源单据类型', + }, + dependencies: { + triggerFields: ['sourceDocType'], + show: (values) => !!values.sourceDocType, + }, + }, + { + fieldName: 'sourceDocCode', + label: '来源单据编号', + component: 'Input', + componentProps: { + disabled: true, + placeholder: '来源单据编号', + }, + dependencies: { + triggerFields: ['sourceDocType', 'sourceDocId'], + show: (values) => !!values.sourceDocType && !!values.sourceDocId, + }, + }, + { + fieldName: 'type', + label: '检验类型', + component: 'Select', + componentProps: { + clearable: true, + options: getDictOptions(DICT_TYPE.MES_RQC_TYPE, 'number'), + placeholder: '请选择检验类型', + }, + rules: 'selectRequired', + }, + { + fieldName: 'itemId', + label: '产品物料', + component: markRaw(MdItemSelect), + componentProps: { + placeholder: '请选择产品物料', + }, + rules: 'selectRequired', + dependencies: { + triggerFields: ['sourceDocId'], + componentProps: (values) => ({ + disabled: !!values.sourceDocId, + placeholder: '请选择产品物料', + }), + }, + }, + { + fieldName: 'batchCode', + label: '批次号', + component: 'Input', + componentProps: { + placeholder: '请输入批次号', + }, + }, + { + fieldName: 'checkQuantity', + label: '检测数量', + component: 'InputNumber', + componentProps: { + class: '!w-full', + controlsPosition: 'right', + min: 0, + placeholder: '请输入', + precision: 2, + }, + rules: 'required', + dependencies: { + triggerFields: ['sourceDocId'], + componentProps: (values) => ({ + class: '!w-full', + controlsPosition: 'right', + disabled: !!values.sourceDocId, + min: 0, + placeholder: '请输入', + precision: 2, + }), + }, + }, + { + fieldName: 'qualifiedQuantity', + label: '合格品数量', + component: 'InputNumber', + componentProps: { + class: '!w-full', + controlsPosition: 'right', + min: 0, + placeholder: '请输入', + precision: 2, + }, + rules: 'required', + }, + { + fieldName: 'unqualifiedQuantity', + label: '不合格品数量', + component: 'InputNumber', + componentProps: { + class: '!w-full', + controlsPosition: 'right', + min: 0, + placeholder: '请输入', + precision: 2, + }, + rules: 'required', + }, + { + fieldName: 'inspectDate', + label: '检测日期', + component: 'DatePicker', + componentProps: { + format: 'YYYY-MM-DD HH:mm:ss', + placeholder: '请选择检测日期', + type: 'datetime', + valueFormat: 'x', + }, + rules: 'required', + }, + { + fieldName: 'inspectorUserId', + label: '检测人员', + component: 'ApiSelect', + componentProps: { + api: getSimpleUserList, + clearable: true, + labelField: 'nickname', + placeholder: '请选择检测人员', + valueField: 'id', + }, + rules: 'selectRequired', + }, + { + fieldName: 'checkResult', + label: '检测结果', + component: 'Select', + componentProps: { + clearable: true, + options: getDictOptions(DICT_TYPE.MES_QC_CHECK_RESULT, 'number'), + placeholder: '请选择检测结果', + }, + }, + { + fieldName: 'remark', + label: '备注', + component: 'Textarea', + formItemClass: 'col-span-3', + componentProps: { + placeholder: '请输入备注', + rows: 3, + }, + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'code', + label: '检验单编号', + component: 'Input', + componentProps: { + clearable: true, + placeholder: '请输入检验单编号', + }, + }, + { + fieldName: 'sourceDocType', + label: '来源单据类型', + component: 'Select', + componentProps: { + clearable: true, + options: getRqcSourceDocTypeOptions(), + placeholder: '请选择来源单据类型', + }, + }, + { + fieldName: 'sourceDocCode', + label: '来源单据编号', + component: 'Input', + componentProps: { + clearable: true, + placeholder: '请输入来源单据编号', + }, + }, + { + fieldName: 'itemId', + label: '产品物料', + component: markRaw(MdItemSelect), + componentProps: { + placeholder: '请选择产品物料', + }, + }, + { + fieldName: 'batchCode', + label: '批次号', + component: 'Input', + componentProps: { + clearable: true, + placeholder: '请输入批次号', + }, + }, + { + fieldName: 'checkResult', + label: '检测结果', + component: 'Select', + componentProps: { + clearable: true, + options: getDictOptions(DICT_TYPE.MES_QC_CHECK_RESULT, 'number'), + placeholder: '请选择检测结果', + }, + }, + { + fieldName: 'inspectorUserId', + label: '检测人员', + component: 'ApiSelect', + componentProps: { + api: getSimpleUserList, + clearable: true, + labelField: 'nickname', + placeholder: '请选择检测人员', + valueField: 'id', + }, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + field: 'code', + title: '检验单编号', + width: 160, + slots: { default: 'code' }, + }, + { + field: 'name', + title: '检验单名称', + minWidth: 180, + }, + { + field: 'sourceDocType', + title: '来源单据类型', + width: 120, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.MES_QC_SOURCE_DOC_TYPE }, + }, + }, + { + field: 'sourceDocCode', + title: '来源单据编码', + width: 160, + }, + { + field: 'itemCode', + title: '产品物料编码', + width: 130, + }, + { + field: 'itemName', + title: '产品物料名称', + minWidth: 150, + }, + { + field: 'itemSpecification', + title: '规格型号', + width: 130, + }, + { + field: 'unitName', + title: '单位', + width: 80, + }, + { + field: 'batchCode', + title: '批次号', + width: 130, + }, + { + field: 'checkResult', + title: '检测结果', + width: 110, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.MES_QC_CHECK_RESULT }, + }, + }, + { + field: 'inspectDate', + title: '检测日期', + width: 160, + formatter: 'formatDateTime', + }, + { + field: 'inspectorNickname', + title: '检测人员', + width: 100, + }, + { + field: 'status', + title: '单据状态', + width: 100, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.MES_ORDER_STATUS }, + }, + }, + { + title: '操作', + width: 180, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} + +/** 退货检验单行子表的字段 */ +export function useLineGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + field: 'indicatorName', + title: '检测项名称', + minWidth: 150, + }, + { + field: 'indicatorType', + title: '检测项类型', + width: 120, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.MES_INDICATOR_TYPE }, + }, + }, + { + field: 'tool', + title: '检测工具', + width: 120, + }, + { + field: 'checkMethod', + title: '检测方法', + minWidth: 180, + }, + { + field: 'standardValue', + title: '标准值', + width: 100, + }, + { + field: 'unitMeasureName', + title: '单位', + width: 80, + }, + { + field: 'maxThreshold', + title: '误差上限', + width: 100, + }, + { + field: 'minThreshold', + title: '误差下限', + width: 100, + }, + { + field: 'criticalQuantity', + title: '致命缺陷数', + width: 110, + }, + { + field: 'majorQuantity', + title: '严重缺陷数', + width: 110, + }, + { + field: 'minorQuantity', + title: '轻微缺陷数', + width: 110, + }, + { + title: '操作', + width: 110, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} diff --git a/apps/web-ele/src/views/mes/qc/rqc/index.vue b/apps/web-ele/src/views/mes/qc/rqc/index.vue new file mode 100644 index 000000000..7621abb5c --- /dev/null +++ b/apps/web-ele/src/views/mes/qc/rqc/index.vue @@ -0,0 +1,168 @@ + + + diff --git a/apps/web-ele/src/views/mes/qc/rqc/modules/form.vue b/apps/web-ele/src/views/mes/qc/rqc/modules/form.vue new file mode 100644 index 000000000..bb2e7d6a2 --- /dev/null +++ b/apps/web-ele/src/views/mes/qc/rqc/modules/form.vue @@ -0,0 +1,233 @@ + + + diff --git a/apps/web-ele/src/views/mes/qc/rqc/modules/line-list.vue b/apps/web-ele/src/views/mes/qc/rqc/modules/line-list.vue new file mode 100644 index 000000000..751137b85 --- /dev/null +++ b/apps/web-ele/src/views/mes/qc/rqc/modules/line-list.vue @@ -0,0 +1,98 @@ + + +