feat(mes): 新增产品质量等级分类支持
- 在 MesQcOqcCheckResultEnum 枚举中新增 TYPE_3、EXCELLENT、QUALIFIED、UNQUALIFIED 四个产品等级
- 修改 OQC 出货检验逻辑,将可发货等级从 1型/2型扩展为 1型/2型/3型/优等品/合格品
- 更新 SQL 配置文件中 MES 出货检验检测结果的数据字典定义
- 修复 Mermaid 质量流程图中出货判定的条件描述
- 更新相关文档中的产品等级判定规则说明
- 调整 canShip 方法逻辑,排除废品和不合格品两个等级的发货
- 修正数据对象文档中 OQC 出货检验的产品等级描述
| | |
| | | {"stage": "联动", "action": "审批通过按工序标记: 倒冲→自动物料消耗扣线边库(允许负库存);质检→产出待检行等 IPQC;关键非检→直接产出入库", "roles": ["系统自动"]}, |
| | | {"stage": "完工", "action": "仅末道工序回写工单已生产数量,达标自动完成;MPS 累计判断完成并发事件给销售订单", "roles": ["系统自动"]}]}, |
| | | {"id": "quality", "name": "质量流程", "mermaid": "mermaid/05-quality-flow.mmd", "color": "#e06c6c", |
| | | "summary": "四道检验闸口(IQC/IPQC/OQC/RQC,二态 0→4) + 判定四果(合格/特采/退货/报废;OQC 改按产品等级 1型/2型/废品,仅废品判不合格) + NCR 评审处置关闭;AI 提供判定建议;NCR 当前仅台账不触发返工单。支持化工报告范式:分组指标树+公式文本+平行测量批次+采样表头+签字区,浏览器打印检验报告;并可导出产品检验单 Word(纸质检验单版式,判定结论带出检验结果、检验·复核·批准签字带出检测人·复核人·审核人姓名、质检章留空盖章,Word 打印)。", |
| | | "summary": "四道检验闸口(IQC/IPQC/OQC/RQC,二态 0→4) + 判定四果(合格/特采/退货/报废;OQC 改按产品等级 1型/2型/3型/优等品/合格品/废品/不合格品,废品与不合格品判不合格) + NCR 评审处置关闭;AI 提供判定建议;NCR 当前仅台账不触发返工单。支持化工报告范式:分组指标树+公式文本+平行测量批次+采样表头+签字区,浏览器打印检验报告;并可导出产品检验单 Word(纸质检验单版式,判定结论带出检验结果、检验·复核·批准签字带出检测人·复核人·审核人姓名、质检章留空盖章,Word 打印)。", |
| | | "steps": [ |
| | | {"stage": "来料", "action": "到货通知/外协入库→IQC,结论回写推进待入库或触发退货", "roles": ["IQC 质检员"]}, |
| | | {"stage": "过程", "action": "报工质检工序产出行→IPQC,合格拆行入库、不合格生成 NCR", "roles": ["IPQC 质检员"]}, |
| | | {"stage": "出货", "action": "销售出库提交→OQC(检测结果按产品等级 1型/2型/废品必填,1型/2型判行合格,废品判行不合格),全部合格后出库单进入待拣货,出现废品则整单取消", "roles": ["OQC 质检员"]}, |
| | | {"stage": "出货", "action": "销售出库提交→OQC(检测结果按产品等级 1型/2型/3型/优等品/合格品/废品/不合格品必填,1型/2型/3型/优等品/合格品判行合格,废品与不合格品判行不合格),全部合格后出库单进入待拣货,出现废品或不合格品则整单取消", "roles": ["OQC 质检员"]}, |
| | | {"stage": "退货", "action": "退料/销售退货/售后退货→RQC,结论回调单据与售后", "roles": ["RQC 质检员"]}, |
| | | {"stage": "报告", "action": "检验结果按分组树+测量批次录入,/indicator-result/report 聚合后前端打印检验报告(含采样地点/证书编号/执行标准/判定结论·质检专用章/复核·审核签字区;判定结论带出检验结果·质检章留空盖章·无平行测量时列头称测量值);/indicator-result/export-product-word 导出产品检验单Word(无技术指标列·判定结论带出检验结果·检验·复核·批准签字带出检测人/复核人/审核人姓名·质检章留空盖章·平行测量顿号合并·下载后Word打印;质检单详情检测结果Tab可按样品查看只读检测值明细)", "roles": ["质检员", "复核人", "审核人"]}, |
| | | {"stage": "不合格", "action": "NCR: 待评审→评审→处置(退货/报废/返工/让步接收/降级)→关闭", "roles": ["质量工程师"]}]}, |
| | |
| | | {"name": "批次", "module": "仓储", "table": "mes_wm_batch", "doc": "关联物料/工单/供应商/客户/质量状态;SN 码含批次 uuid;条码支持18种业务对象", "upstream": ["入库单据"], "downstream": ["库存台账"], "keywords": "批次 batch SN 条码 追溯"}, |
| | | {"name": "IQC来料检验", "module": "质量", "table": "mes_qc_iqc", "doc": "到货通知/外协入库触发,草稿0→完成4,结论回写来源单据", "upstream": ["到货通知", "外协入库"], "downstream": ["采购入库", "供应商退货", "NCR"], "keywords": "IQC 来料检验"}, |
| | | {"name": "IPQC过程检验", "module": "质量", "table": "mes_qc_ipqc", "doc": "报工质检工序产出行触发,完成回调推进报工与产出入库;表头=来源单据(只读)+产品物料(MDM,必填)+批号(必填)+数量+检验信息,已去掉生产订单/工位/生产任务/工序", "upstream": ["报工"], "downstream": ["产出入库", "NCR"], "keywords": "IPQC 过程检验 巡检 批号"}, |
| | | {"name": "OQC出货检验", "module": "质量", "table": "mes_qc_oqc", "doc": "销售出库提交触发,草稿0→完成4;检测结果按产品等级判定(1型/2型/废品,必填),1型/2型判行合格并推进出库单待拣货,废品判行不合格并取消销售出库单;发货数量/出货日期可空", "upstream": ["销售出库单"], "downstream": ["销售出库单(推进或取消)"], "keywords": "OQC 出货检验 出厂检验 1型 2型 废品"}, |
| | | {"name": "OQC出货检验", "module": "质量", "table": "mes_qc_oqc", "doc": "销售出库提交触发,草稿0→完成4;检测结果按产品等级判定(1型/2型/3型/优等品/合格品/废品/不合格品,必填),1型/2型/3型/优等品/合格品判行合格并推进出库单待拣货,废品与不合格品判行不合格并取消销售出库单;发货数量/出货日期可空", "upstream": ["销售出库单"], "downstream": ["销售出库单(推进或取消)"], "keywords": "OQC 出货检验 出厂检验 1型 2型 3型 优等品 合格品 废品 不合格品"}, |
| | | {"name": "RQC退货检验", "module": "质量", "table": "mes_qc_rqc", "doc": "生产退料/销售退货/售后退货触发,结论回调售后;四类检验单均支持采样地点/证书编号/执行标准表头与复核·审核人,并可打印检验报告", "upstream": ["退料", "退货"], "downstream": ["退货入库", "售后回调", "检验报告打印"], "keywords": "RQC 退货检验"}, |
| | | {"name": "检验指标", "module": "质量", "table": "mes_qc_indicator", "doc": "支持两级分组树(itemType录入/分组+parentId)、公式文本展示、单位文本、同级排序;分组项不录值;有子项禁删;同层级名称可重复", "upstream": [], "downstream": ["质检方案", "检验报告打印"], "keywords": "检验指标 indicator 分组 公式 化工"}, |
| | | {"name": "检验报告打印", "module": "质量", "table": "mes_qc_indicator_result_detail", "doc": "化工报告范式:平行测量批次(measure_no)+分组矩阵+公式列+签字区;/mes/qc/indicator-result/report 聚合,前端浏览器打印", "upstream": ["IQC来料检验", "IPQC过程检验", "OQC出货检验", "RQC退货检验", "检验指标"], "downstream": [], "keywords": "打印 报告 测量批次 签字 正丁醇 GB/T6027"}, |
| | |
| | | R -->|3 不合格退货| Q3[生成NCR·走供应商退货或销售退货] |
| | | R -->|4 不合格报废| Q4[生成NCR·走报废出库] |
| | | A3 --> R2{出货判定 MesQcOqcCheckResultEnum·必填} |
| | | R2 -->|1型/2型| S1[出库行判合格·推进出库单待拣货] |
| | | R2 -->|废品| S2[出库行判不合格·取消销售出库单] |
| | | R2 -->|1型/2型/3型/优等品/合格品| S1[出库行判合格·推进出库单待拣货] |
| | | R2 -->|废品/不合格品| S2[出库行判不合格·取消销售出库单] |
| | | A3 -.-> N5[表头:发货数量/出货日期非必填·检测结果必填] |
| | | A2 -.-> N6[表头:来源单据只读·产品物料(MDM)必填·批号必填·已去掉生产订单/工位/生产任务/工序] |
| | | A2 -->|合格数量| Q5[报工转完成·产出拆行入库] |
| | |
| | | ('2046', 'MES 维修工单状态', 'mes_dv_repair_status', '0', 'MES 设备管理 - 维修工单状态(10=待维修,20=维修中,30=已完成,40=已验收)', '1', '2026-02-20 10:56:24', '1', '2026-02-20 10:56:24', X'00', NULL), |
| | | ('2047', 'MES 维修结果', 'mes_dv_repair_result', '0', 'MES 设备管理 - 维修结果(1=修复成功,2=报废)', '1', '2026-02-20 10:56:24', '1', '2026-02-20 10:56:24', X'00', NULL), |
| | | ('2049', 'MES 检测结果', 'mes_qc_check_result', '0', '来料检验的最终结果判定', '1', '2026-02-20 11:23:35', '1', '2026-02-20 11:23:35', X'00', NULL), |
| | | ('1065400', 'MES 出货检验检测结果', 'mes_oqc_check_result', '0', '出货检验单(OQC)判定结果:1型/2型为可发货等级,废品不放行', '1', '2026-09-22 00:00:00', '1', '2026-09-22 00:00:00', X'00', NULL), |
| | | ('1065400', 'MES 出货检验检测结果', 'mes_oqc_check_result', '0', '出货检验单(OQC)判定结果:1型/2型/3型/优等品/合格品为可发货等级,废品与不合格品不放行', '1', '2026-09-22 00:00:00', '1', '2026-09-22 00:00:00', X'00', NULL), |
| | | ('2050', 'MES 来源单据类型', 'mes_qc_source_doc_type', '0', 'IQC 来料检验的来源单据类型', '1', '2026-02-20 11:23:35', '1', '2026-02-20 11:23:35', X'00', NULL), |
| | | ('2051', 'MES 安灯处置状态', 'mes_pro_andon_status', '0', 'MES 生产管理 - 安灯处置状态(0=未处置,1=已处置)', '1', '2026-02-21 00:08:38', '1', '2026-02-21 00:08:38', X'00', NULL), |
| | | ('2052', 'MES 安灯级别', 'mes_pro_andon_level', '0', 'MES 生产管理 - 安灯级别(1=一级,2=二级,3=三级)', '1', '2026-02-21 00:08:38', '1', '2026-02-21 00:08:38', X'00', NULL), |
| | |
| | | ('1065401', '1', '1型', '1', 'mes_oqc_check_result', '0', 'success', '', '', '1', '2026-09-22 00:00:00', '1', '2026-09-22 00:00:00', X'00'), |
| | | ('1065402', '2', '2型', '2', 'mes_oqc_check_result', '0', 'primary', '', '', '1', '2026-09-22 00:00:00', '1', '2026-09-22 00:00:00', X'00'), |
| | | ('1065403', '3', '废品', '3', 'mes_oqc_check_result', '0', 'danger', '', '', '1', '2026-09-22 00:00:00', '1', '2026-09-22 00:00:00', X'00'), |
| | | ('1065404', '4', '3型', '4', 'mes_oqc_check_result', '0', 'success', '', '', '1', '2026-09-24 00:00:00', '1', '2026-09-24 00:00:00', X'00'), |
| | | ('1065405', '5', '优等品', '5', 'mes_oqc_check_result', '0', 'success', '', '', '1', '2026-09-24 00:00:00', '1', '2026-09-24 00:00:00', X'00'), |
| | | ('1065406', '6', '合格品', '6', 'mes_oqc_check_result', '0', 'primary', '', '', '1', '2026-09-24 00:00:00', '1', '2026-09-24 00:00:00', X'00'), |
| | | ('1065407', '7', '不合格品', '7', 'mes_oqc_check_result', '0', 'danger', '', '', '1', '2026-09-24 00:00:00', '1', '2026-09-24 00:00:00', X'00'), |
| | | ('3166', '0', '未处置', '0', 'mes_pro_andon_status', '0', 'danger', '', '', '1', '2026-02-21 00:08:38', '1', '2026-02-21 00:08:38', X'00'), |
| | | ('3167', '1', '已处置', '1', 'mes_pro_andon_status', '0', 'success', '', '', '1', '2026-02-21 00:08:38', '1', '2026-02-21 00:08:38', X'00'), |
| | | ('3168', '1', '一级', '1', 'mes_pro_andon_level', '0', 'danger', '', '', '1', '2026-02-21 00:08:38', '1', '2026-02-21 00:08:38', X'00'), |
| | |
| | | @Schema(description = "出厂检验单号(OQC)", example = "OQC20250801001") |
| | | private String oqcCode; |
| | | |
| | | @Schema(description = "OQC 检验结论(字典 mes_qc_check_result)", example = "1") |
| | | @Schema(description = "OQC 检验结论(字典 mes_oqc_check_result)", example = "1") |
| | | private Integer checkResult; |
| | | |
| | | @Schema(description = "物料 ID", example = "1") |
| | |
| | | |
| | | TYPE_1(1, "1型"), |
| | | TYPE_2(2, "2型"), |
| | | SCRAP(3, "废品"); |
| | | SCRAP(3, "废品"), |
| | | TYPE_3(4, "3型"), |
| | | EXCELLENT(5, "优等品"), |
| | | QUALIFIED(6, "合格品"), |
| | | UNQUALIFIED(7, "不合格品"); |
| | | |
| | | public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesQcOqcCheckResultEnum::getType).toArray(Integer[]::new); |
| | | |
| | |
| | | /** |
| | | * 判断是否可以放行发货 |
| | | * |
| | | * <p>1 型、2 型均为可发货等级,仅废品不放行</p> |
| | | * <p>废品、不合格品不放行,其余等级(1 型、2 型、3 型、优等品、合格品)均可发货</p> |
| | | * |
| | | * @param type 检测结果 |
| | | * @return true 可以放行 |
| | | */ |
| | | public static boolean canShip(Integer type) { |
| | | return type != null && !SCRAP.getType().equals(type); |
| | | return type != null |
| | | && !SCRAP.getType().equals(type) |
| | | && !UNQUALIFIED.getType().equals(type); |
| | | } |
| | | |
| | | } |
| | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void updateProductSalesLineWhenOqcFinish(Long id, Long oqcId, Integer checkResult) { |
| | | // 1. 更新行的 oqcId + qualityStatus(1型/2型放行,废品判不合格) |
| | | // 1. 更新行的 oqcId + qualityStatus(1型/2型/3型/优等品/合格品放行,废品与不合格品判不合格) |
| | | Integer qualityStatus = MesQcOqcCheckResultEnum.canShip(checkResult) |
| | | ? MesWmQualityStatusEnum.PASS.getStatus() : MesWmQualityStatusEnum.FAIL.getStatus(); |
| | | productSalesLineMapper.updateById(new MesWmProductSalesLineDO() |