From f74a063d441534d7f9dd308aae7048551a33ef78 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Fri, 20 Feb 2026 22:49:14 +0800 Subject: [PATCH] feat(mes):通过枚举和用户关联来重构缺陷处理流程,并增强内部质量控制功能 --- yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/MesQcIqcController.java | 10 ++++++++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/MesQcIqcDefectController.java | 12 ++++++------ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/MesQcIqcLineController.java | 8 ++++---- yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/vo/MesQcIqcPageReqVO.java | 7 +++++-- yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/vo/MesQcIqcRespVO.java | 11 +++++++---- yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/vo/MesQcIqcSaveReqVO.java | 8 ++++---- yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/vo/defect/MesQcIqcDefectRespVO.java | 4 ++-- yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/vo/defect/MesQcIqcDefectSaveReqVO.java | 6 +++--- yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/lqc/MesQcIqcDO.java | 21 +++++++++++---------- yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/lqc/MesQcIqcDefectDO.java | 5 ++--- yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/qc/lqc/MesQcIqcMapper.java | 1 + yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcCheckResultEnum.java | 38 ++++++++++++++++++++++++++++++++++++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcDefectLevelEnum.java | 38 ++++++++++++++++++++++++++++++++++++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcIqcStatusEnum.java | 37 +++++++++++++++++++++++++++++++++++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcTypeEnum.java | 39 +++++++++++++++++++++++++++++++++++++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcDefectService.java | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcDefectServiceImpl.java | 194 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcLineService.java | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcLineServiceImpl.java | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcService.java | 61 ++----------------------------------------------------------- yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcServiceImpl.java | 261 +++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 21 files changed, 628 insertions(+), 313 deletions(-) create mode 100644 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcCheckResultEnum.java create mode 100644 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcDefectLevelEnum.java create mode 100644 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcIqcStatusEnum.java create mode 100644 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcTypeEnum.java create mode 100644 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcDefectService.java create mode 100644 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcDefectServiceImpl.java create mode 100644 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcLineService.java create mode 100644 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcLineServiceImpl.java diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/MesQcIqcController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/MesQcIqcController.java index 87848a7..ef172f9 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/MesQcIqcController.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/MesQcIqcController.java @@ -18,6 +18,8 @@ import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService; import cn.iocoder.yudao.module.mes.service.md.vendor.MesMdVendorService; import cn.iocoder.yudao.module.mes.service.qc.lqc.MesQcIqcService; +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; @@ -53,6 +55,9 @@ public class MesQcIqcController { @Resource private MesMdUnitMeasureService unitMeasureService; + @Resource + private AdminUserApi adminUserApi; + @PostMapping("/create") @Operation(summary = "创建来料检验单") @PreAuthorize("@ss.hasPermission('mes:qc-iqc:create')") @@ -130,6 +135,9 @@ public class MesQcIqcController { // 批量查询计量单位(通过物料的 unitMeasureId) Map unitMeasureMap = unitMeasureService.getUnitMeasureMap( convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId)); + // 批量查询检测人员 + Map userMap = adminUserApi.getUserMap( + convertSet(list, MesQcIqcDO::getInspectorUserId)); // 拼装 VO return BeanUtils.toBean(list, MesQcIqcRespVO.class, vo -> { findAndThen(vendorMap, vo.getVendorId(), @@ -141,6 +149,8 @@ public class MesQcIqcController { findAndThen(unitMeasureMap, item.getUnitMeasureId(), unit -> vo.setUnitName(unit.getName())); }); + findAndThen(userMap, vo.getInspectorUserId(), + user -> vo.setInspectorNickname(user.getNickname())); }); } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/MesQcIqcDefectController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/MesQcIqcDefectController.java index cd94296..549338a 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/MesQcIqcDefectController.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/MesQcIqcDefectController.java @@ -7,7 +7,7 @@ import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.defect.MesQcIqcDef import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.defect.MesQcIqcDefectRespVO; import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.defect.MesQcIqcDefectSaveReqVO; import cn.iocoder.yudao.module.mes.dal.dataobject.qc.lqc.MesQcIqcDefectDO; -import cn.iocoder.yudao.module.mes.service.qc.lqc.MesQcIqcService; +import cn.iocoder.yudao.module.mes.service.qc.lqc.MesQcIqcDefectService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; @@ -26,20 +26,20 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; public class MesQcIqcDefectController { @Resource - private MesQcIqcService iqcService; + private MesQcIqcDefectService iqcDefectService; @PostMapping("/create") @Operation(summary = "创建来料检验缺陷记录") @PreAuthorize("@ss.hasPermission('mes:qc-iqc:create')") public CommonResult createIqcDefect(@Valid @RequestBody MesQcIqcDefectSaveReqVO createReqVO) { - return success(iqcService.createIqcDefect(createReqVO)); + return success(iqcDefectService.createIqcDefect(createReqVO)); } @PutMapping("/update") @Operation(summary = "更新来料检验缺陷记录") @PreAuthorize("@ss.hasPermission('mes:qc-iqc:update')") public CommonResult updateIqcDefect(@Valid @RequestBody MesQcIqcDefectSaveReqVO updateReqVO) { - iqcService.updateIqcDefect(updateReqVO); + iqcDefectService.updateIqcDefect(updateReqVO); return success(true); } @@ -48,7 +48,7 @@ public class MesQcIqcDefectController { @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('mes:qc-iqc:update')") public CommonResult deleteIqcDefect(@RequestParam("id") Long id) { - iqcService.deleteIqcDefect(id); + iqcDefectService.deleteIqcDefect(id); return success(true); } @@ -56,7 +56,7 @@ public class MesQcIqcDefectController { @Operation(summary = "获得来料检验缺陷记录分页") @PreAuthorize("@ss.hasPermission('mes:qc-iqc:query')") public CommonResult> getIqcDefectPage(@Valid MesQcIqcDefectPageReqVO pageReqVO) { - PageResult pageResult = iqcService.getIqcDefectPage(pageReqVO); + PageResult pageResult = iqcDefectService.getIqcDefectPage(pageReqVO); return success(BeanUtils.toBean(pageResult, MesQcIqcDefectRespVO.class)); } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/MesQcIqcLineController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/MesQcIqcLineController.java index d082287..0f964f9 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/MesQcIqcLineController.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/MesQcIqcLineController.java @@ -11,7 +11,7 @@ import cn.iocoder.yudao.module.mes.dal.dataobject.qc.lqc.MesQcIqcLineDO; import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicator.MesQcIndicatorDO; import cn.iocoder.yudao.module.mes.dal.dataobject.tm.tool.MesTmToolDO; import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService; -import cn.iocoder.yudao.module.mes.service.qc.lqc.MesQcIqcService; +import cn.iocoder.yudao.module.mes.service.qc.lqc.MesQcIqcLineService; import cn.iocoder.yudao.module.mes.service.qc.indicator.MesQcIndicatorService; import cn.iocoder.yudao.module.mes.service.tm.tool.MesTmToolService; import io.swagger.v3.oas.annotations.Operation; @@ -41,7 +41,7 @@ import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAnd public class MesQcIqcLineController { @Resource - private MesQcIqcService iqcService; + private MesQcIqcLineService iqcLineService; @Resource private MesQcIndicatorService indicatorService; @Resource @@ -54,7 +54,7 @@ public class MesQcIqcLineController { @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('mes:qc-iqc:query')") public CommonResult getIqcLine(@RequestParam("id") Long id) { - MesQcIqcLineDO line = iqcService.getIqcLine(id); + MesQcIqcLineDO line = iqcLineService.getIqcLine(id); return success(buildLineRespVOList(Collections.singletonList(line)).get(0)); } @@ -62,7 +62,7 @@ public class MesQcIqcLineController { @Operation(summary = "获得来料检验单行分页") @PreAuthorize("@ss.hasPermission('mes:qc-iqc:query')") public CommonResult> getIqcLinePage(@Valid MesQcIqcLinePageReqVO pageReqVO) { - PageResult pageResult = iqcService.getIqcLinePage(pageReqVO); + PageResult pageResult = iqcLineService.getIqcLinePage(pageReqVO); return success(new PageResult<>(buildLineRespVOList(pageResult.getList()), pageResult.getTotal())); } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/vo/MesQcIqcPageReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/vo/MesQcIqcPageReqVO.java index 175fc3b..5f9b243 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/vo/MesQcIqcPageReqVO.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/vo/MesQcIqcPageReqVO.java @@ -29,12 +29,15 @@ public class MesQcIqcPageReqVO extends PageParam { @Schema(description = "产品物料 ID", example = "20") private Long itemId; - @Schema(description = "检测结果", example = "PASS") - private String checkResult; + @Schema(description = "检测结果", example = "1") + private Integer checkResult; @Schema(description = "状态", example = "0") private Integer status; + @Schema(description = "检测人员用户 ID", example = "1") + private Long inspectorUserId; + @Schema(description = "来料日期") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] receiveDate; diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/vo/MesQcIqcRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/vo/MesQcIqcRespVO.java index 7f3ad39..60c34a2 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/vo/MesQcIqcRespVO.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/vo/MesQcIqcRespVO.java @@ -119,9 +119,9 @@ public class MesQcIqcRespVO { // ========== 检验 ========== - @Schema(description = "检测结果", example = "PASS") + @Schema(description = "检测结果", example = "1") @ExcelProperty("检测结果") - private String checkResult; + private Integer checkResult; @Schema(description = "来料日期") @ExcelProperty("来料日期") @@ -131,9 +131,12 @@ public class MesQcIqcRespVO { @ExcelProperty("检测日期") private LocalDateTime inspectDate; - @Schema(description = "检测人员", example = "张三") + @Schema(description = "检测人员用户 ID", example = "1") + private Long inspectorUserId; + + @Schema(description = "检测人员昵称", example = "张三") @ExcelProperty("检测人员") - private String inspector; + private String inspectorNickname; @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") @ExcelProperty("状态") diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/vo/MesQcIqcSaveReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/vo/MesQcIqcSaveReqVO.java index dcb1277..6050d9f 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/vo/MesQcIqcSaveReqVO.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/vo/MesQcIqcSaveReqVO.java @@ -79,8 +79,8 @@ public class MesQcIqcSaveReqVO { // ========== 检验 ========== - @Schema(description = "检测结果", example = "PASS") - private String checkResult; + @Schema(description = "检测结果", example = "1") + private Integer checkResult; @Schema(description = "来料日期") private LocalDateTime receiveDate; @@ -88,8 +88,8 @@ public class MesQcIqcSaveReqVO { @Schema(description = "检测日期") private LocalDateTime inspectDate; - @Schema(description = "检测人员", example = "张三") - private String inspector; + @Schema(description = "检测人员用户 ID", example = "1") + private Long inspectorUserId; @Schema(description = "备注", example = "备注") private String remark; diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/vo/defect/MesQcIqcDefectRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/vo/defect/MesQcIqcDefectRespVO.java index 08cf055..f74b06e 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/vo/defect/MesQcIqcDefectRespVO.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/vo/defect/MesQcIqcDefectRespVO.java @@ -21,8 +21,8 @@ public class MesQcIqcDefectRespVO { @Schema(description = "缺陷描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "表面划伤") private String defectName; - @Schema(description = "缺陷等级", requiredMode = Schema.RequiredMode.REQUIRED, example = "CRITICAL") - private String defectLevel; + @Schema(description = "缺陷等级", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Integer defectLevel; @Schema(description = "缺陷数量", example = "1") private Integer defectQuantity; diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/vo/defect/MesQcIqcDefectSaveReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/vo/defect/MesQcIqcDefectSaveReqVO.java index 3b030d0..11aa66c 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/vo/defect/MesQcIqcDefectSaveReqVO.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/vo/defect/MesQcIqcDefectSaveReqVO.java @@ -24,9 +24,9 @@ public class MesQcIqcDefectSaveReqVO { @NotEmpty(message = "缺陷描述不能为空") private String defectName; - @Schema(description = "缺陷等级", requiredMode = Schema.RequiredMode.REQUIRED, example = "CRITICAL") - @NotEmpty(message = "缺陷等级不能为空") - private String defectLevel; + @Schema(description = "缺陷等级", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "缺陷等级不能为空") + private Integer defectLevel; @Schema(description = "缺陷数量", example = "1") private Integer defectQuantity; diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/lqc/MesQcIqcDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/lqc/MesQcIqcDO.java index edb3be7..a4ceffa 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/lqc/MesQcIqcDO.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/lqc/MesQcIqcDO.java @@ -12,9 +12,8 @@ import lombok.*; import java.math.BigDecimal; import java.time.LocalDateTime; -// TODO @AI:IQC 完整的拼写,也加下; /** - * MES 来料检验单(IQC) DO + * MES 来料检验单(IQC, Incoming Quality Control) DO * * @author 芋道源码 */ @@ -147,13 +146,12 @@ public class MesQcIqcDO extends BaseDO { // ========== 检验 ========== - // TODO @AI:需要搞个枚举么?使用 int 把。现在就搞了; /** * 检测结果 * - * 字典 mes_qc_check_result + * 枚举 {@link cn.iocoder.yudao.module.mes.enums.qc.MesQcCheckResultEnum} */ - private String checkResult; + private Integer checkResult; /** * 来料日期 */ @@ -165,13 +163,16 @@ public class MesQcIqcDO extends BaseDO { /** * 检测人员 */ - // TODO @AI:改成 inspectorUserId; - private String inspector; - // TODO @AI:需要搞个枚举么?使用 int 把。现在就搞了; /** - * 状态(0=草稿 1=已完成) + * 检测人员用户 ID * - * 字典 mes_qc_iqc_status + * 关联 AdminUserDO 的 id + */ + private Long inspectorUserId; + /** + * 状态 + * + * 枚举 {@link cn.iocoder.yudao.module.mes.enums.qc.MesQcIqcStatusEnum} */ private Integer status; /** diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/lqc/MesQcIqcDefectDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/lqc/MesQcIqcDefectDO.java index a939dee..0b27f21 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/lqc/MesQcIqcDefectDO.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/lqc/MesQcIqcDefectDO.java @@ -42,13 +42,12 @@ public class MesQcIqcDefectDO extends BaseDO { * 缺陷描述 */ private String defectName; - // TODO @AI:要不枚举值也加下,也改成 int; /** * 缺陷等级 * - * 字典 mes_defect_level + * 枚举 {@link cn.iocoder.yudao.module.mes.enums.qc.MesQcDefectLevelEnum} */ - private String defectLevel; + private Integer defectLevel; /** * 缺陷数量 */ diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/qc/lqc/MesQcIqcMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/qc/lqc/MesQcIqcMapper.java index 08aeba5..384f088 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/qc/lqc/MesQcIqcMapper.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/qc/lqc/MesQcIqcMapper.java @@ -25,6 +25,7 @@ public interface MesQcIqcMapper extends BaseMapperX { .eqIfPresent(MesQcIqcDO::getStatus, reqVO.getStatus()) .betweenIfPresent(MesQcIqcDO::getReceiveDate, reqVO.getReceiveDate()) .betweenIfPresent(MesQcIqcDO::getInspectDate, reqVO.getInspectDate()) + .eqIfPresent(MesQcIqcDO::getInspectorUserId, reqVO.getInspectorUserId()) .orderByDesc(MesQcIqcDO::getId)); } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcCheckResultEnum.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcCheckResultEnum.java new file mode 100644 index 0000000..e604759 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcCheckResultEnum.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.mes.enums.qc; + +import cn.iocoder.yudao.framework.common.core.ArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +/** + * MES 检测结果枚举 + * + * @author 芋道源码 + */ +@Getter +@AllArgsConstructor +public enum MesQcCheckResultEnum implements ArrayValuable { + + PASS(1, "合格"), // TODO @AI:检验通过; + FAIL(2, "不合格"), // TODO @AI:检验不通过; + ACCEPT(3, "让步接收"); // TODO @AI:去掉; + + public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesQcCheckResultEnum::getType).toArray(Integer[]::new); + + /** + * 结果值 + */ + private final Integer type; + /** + * 结果名 + */ + private final String name; + + @Override + public Integer[] array() { + return ARRAYS; + } + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcDefectLevelEnum.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcDefectLevelEnum.java new file mode 100644 index 0000000..0ceba09 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcDefectLevelEnum.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.mes.enums.qc; + +import cn.iocoder.yudao.framework.common.core.ArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +/** + * MES 缺陷等级枚举 + * + * @author 芋道源码 + */ +@Getter +@AllArgsConstructor +public enum MesQcDefectLevelEnum implements ArrayValuable { + + CRITICAL(1, "致命"), + MAJOR(2, "严重"), + MINOR(3, "轻微"); + + public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesQcDefectLevelEnum::getType).toArray(Integer[]::new); + + /** + * 等级值 + */ + private final Integer type; + /** + * 等级名 + */ + private final String name; + + @Override + public Integer[] array() { + return ARRAYS; + } + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcIqcStatusEnum.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcIqcStatusEnum.java new file mode 100644 index 0000000..85b7371 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcIqcStatusEnum.java @@ -0,0 +1,37 @@ +package cn.iocoder.yudao.module.mes.enums.qc; + +import cn.iocoder.yudao.framework.common.core.ArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +/** + * MES 检验单状态枚举 + * + * @author 芋道源码 + */ +@Getter +@AllArgsConstructor +public enum MesQcIqcStatusEnum implements ArrayValuable { + + PREPARE(0, "草稿"), + FINISHED(1, "已完成"); + + public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesQcIqcStatusEnum::getType).toArray(Integer[]::new); + + /** + * 状态值 + */ + private final Integer type; + /** + * 状态名 + */ + private final String name; + + @Override + public Integer[] array() { + return ARRAYS; + } + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcTypeEnum.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcTypeEnum.java new file mode 100644 index 0000000..c5af747 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcTypeEnum.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.mes.enums.qc; + +import cn.iocoder.yudao.framework.common.core.ArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +/** + * MES 检测种类枚举 + * + * @author 芋道源码 + */ +@Getter +@AllArgsConstructor +public enum MesQcTypeEnum implements ArrayValuable { + + IQC(1, "来料检验"), + IPQC(2, "过程检验"), + OQC(3, "出货检验"), + RQC(4, "退货检验"); + + public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesQcTypeEnum::getType).toArray(Integer[]::new); + + /** + * 类型值 + */ + private final Integer type; + /** + * 类型名 + */ + private final String name; + + @Override + public Integer[] array() { + return ARRAYS; + } + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcDefectService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcDefectService.java new file mode 100644 index 0000000..b676930 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcDefectService.java @@ -0,0 +1,53 @@ +package cn.iocoder.yudao.module.mes.service.qc.lqc; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.defect.MesQcIqcDefectPageReqVO; +import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.defect.MesQcIqcDefectSaveReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.qc.lqc.MesQcIqcDefectDO; +import jakarta.validation.Valid; + +/** + * MES 来料检验缺陷记录 Service 接口 + * + * @author 芋道源码 + */ +public interface MesQcIqcDefectService { + + /** + * 创建来料检验缺陷记录 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createIqcDefect(@Valid MesQcIqcDefectSaveReqVO createReqVO); + + /** + * 更新来料检验缺陷记录 + * + * @param updateReqVO 更新信息 + */ + void updateIqcDefect(@Valid MesQcIqcDefectSaveReqVO updateReqVO); + + /** + * 删除来料检验缺陷记录 + * + * @param id 编号 + */ + void deleteIqcDefect(Long id); + + /** + * 获得来料检验缺陷记录分页 + * + * @param pageReqVO 分页查询 + * @return 来料检验缺陷记录分页 + */ + PageResult getIqcDefectPage(MesQcIqcDefectPageReqVO pageReqVO); + + /** + * 根据来料检验单 ID 级联删除所有缺陷记录 + * + * @param iqcId 来料检验单 ID + */ + void deleteByIqcId(Long iqcId); + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcDefectServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcDefectServiceImpl.java new file mode 100644 index 0000000..85e23e2 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcDefectServiceImpl.java @@ -0,0 +1,194 @@ +package cn.iocoder.yudao.module.mes.service.qc.lqc; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.defect.MesQcIqcDefectPageReqVO; +import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.defect.MesQcIqcDefectSaveReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.qc.lqc.MesQcIqcDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.qc.lqc.MesQcIqcDefectDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.qc.lqc.MesQcIqcLineDO; +import cn.iocoder.yudao.module.mes.dal.mysql.qc.lqc.MesQcIqcDefectMapper; +import cn.iocoder.yudao.module.mes.dal.mysql.qc.lqc.MesQcIqcLineMapper; +import cn.iocoder.yudao.module.mes.dal.mysql.qc.lqc.MesQcIqcMapper; +import cn.iocoder.yudao.module.mes.enums.qc.MesQcDefectLevelEnum; +import jakarta.annotation.Resource; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.List; +import java.util.Objects; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; + +/** + * MES 来料检验缺陷记录 Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Validated +public class MesQcIqcDefectServiceImpl implements MesQcIqcDefectService { + + @Resource + private MesQcIqcDefectMapper iqcDefectMapper; + @Resource + private MesQcIqcLineMapper iqcLineMapper; + @Resource + private MesQcIqcMapper iqcMapper; + @Resource + @Lazy + private MesQcIqcLineService iqcLineService; + + @Override + @Transactional(rollbackFor = Exception.class) + public Long createIqcDefect(MesQcIqcDefectSaveReqVO createReqVO) { + // 1.1 校验 IQC 存在 + validateIqcExists(createReqVO.getIqcId()); + // 1.2 校验行存在 + validateIqcLineExists(createReqVO.getLineId()); + + // 2. 插入 + MesQcIqcDefectDO defect = BeanUtils.toBean(createReqVO, MesQcIqcDefectDO.class); + iqcDefectMapper.insert(defect); + + // 3. 重新计算缺陷统计 + recalculateDefectStats(createReqVO.getIqcId()); + return defect.getId(); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateIqcDefect(MesQcIqcDefectSaveReqVO updateReqVO) { + // 1. 校验存在 + validateIqcDefectExists(updateReqVO.getId()); + + // 2. 更新 + MesQcIqcDefectDO updateObj = BeanUtils.toBean(updateReqVO, MesQcIqcDefectDO.class); + iqcDefectMapper.updateById(updateObj); + + // 3. 重新计算缺陷统计 + recalculateDefectStats(updateReqVO.getIqcId()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteIqcDefect(Long id) { + // 1. 校验存在 + MesQcIqcDefectDO defect = validateIqcDefectExists(id); + + // 2. 删除 + iqcDefectMapper.deleteById(id); + + // 3. 重新计算缺陷统计 + recalculateDefectStats(defect.getIqcId()); + } + + @Override + public PageResult getIqcDefectPage(MesQcIqcDefectPageReqVO pageReqVO) { + return iqcDefectMapper.selectPage(pageReqVO); + } + + @Override + public void deleteByIqcId(Long iqcId) { + iqcDefectMapper.deleteByIqcId(iqcId); + } + + private void validateIqcExists(Long iqcId) { + if (iqcMapper.selectById(iqcId) == null) { + throw exception(QC_IQC_NOT_EXISTS); + } + } + + private void validateIqcLineExists(Long lineId) { + MesQcIqcLineDO line = iqcLineService.getIqcLine(lineId); + if (line == null) { + throw exception(QC_IQC_LINE_NOT_EXISTS); + } + } + + private MesQcIqcDefectDO validateIqcDefectExists(Long id) { + MesQcIqcDefectDO defect = iqcDefectMapper.selectById(id); + if (defect == null) { + throw exception(QC_IQC_DEFECT_NOT_EXISTS); + } + return defect; + } + + /** + * 重新计算缺陷统计(行级 + 主表级) + * + * @param iqcId 来料检验单 ID + */ + private void recalculateDefectStats(Long iqcId) { + // 1. 查询所有缺陷记录 + List defects = iqcDefectMapper.selectListByIqcId(iqcId); + + // 2. 更新每行的缺陷数量 + List lines = iqcLineService.selectListByIqcId(iqcId); + for (MesQcIqcLineDO line : lines) { + int critical = 0; + int major = 0; + int minor = 0; + for (MesQcIqcDefectDO defect : defects) { + // TODO @AI:notEquals continue;减少括号层级; + if (Objects.equals(defect.getLineId(), line.getId())) { + // TODO @AI:defaultIfNull;变量改成 quantity + int qty = defect.getDefectQuantity() != null ? defect.getDefectQuantity() : 1; + if (Objects.equals(defect.getDefectLevel(), MesQcDefectLevelEnum.CRITICAL.getType())) { + critical += qty; + } else if (Objects.equals(defect.getDefectLevel(), MesQcDefectLevelEnum.MAJOR.getType())) { + major += qty; + } else if (Objects.equals(defect.getDefectLevel(), MesQcDefectLevelEnum.MINOR.getType())) { + minor += qty; + } + // TODO @AI:抛出异常;未知的缺陷等级 + } + } + MesQcIqcLineDO updateLine = new MesQcIqcLineDO().setId(line.getId()) + .setCriticalQuantity(critical).setMajorQuantity(major).setMinorQuantity(minor); + // 直接通过 lineService 内部更新(避免循环依赖,使用 mapper) + // TODO @AI:单独搞个 updateLineDefectStats 方法;减少 updateLine 变量的作用域; + iqcLineMapper.updateById(updateLine); + } + + // 3.1 汇总主表的缺陷数量 + int totalCritical = 0, totalMajor = 0, totalMinor = 0; + for (MesQcIqcDefectDO defect : defects) { + // TODO @AI:defaultIfNull;变量改成 quantity + int qty = defect.getDefectQuantity() != null ? defect.getDefectQuantity() : 1; + if (Objects.equals(defect.getDefectLevel(), MesQcDefectLevelEnum.CRITICAL.getType())) { + totalCritical += qty; + } else if (Objects.equals(defect.getDefectLevel(), MesQcDefectLevelEnum.MAJOR.getType())) { + totalMajor += qty; + } else if (Objects.equals(defect.getDefectLevel(), MesQcDefectLevelEnum.MINOR.getType())) { + totalMinor += qty; + } + // TODO @AI:抛出异常;未知的缺陷等级 + } + // 3.2 计算缺陷率 + MesQcIqcDO iqc = iqcMapper.selectById(iqcId); + BigDecimal criticalRate = BigDecimal.ZERO; + BigDecimal majorRate = BigDecimal.ZERO; + BigDecimal minorRate = BigDecimal.ZERO; + if (iqc != null && iqc.getCheckQuantity() != null && iqc.getCheckQuantity() > 0) { + BigDecimal checkQty = BigDecimal.valueOf(iqc.getCheckQuantity()); + criticalRate = BigDecimal.valueOf(totalCritical).multiply(BigDecimal.valueOf(100)) + .divide(checkQty, 2, RoundingMode.HALF_UP); + majorRate = BigDecimal.valueOf(totalMajor).multiply(BigDecimal.valueOf(100)) + .divide(checkQty, 2, RoundingMode.HALF_UP); + minorRate = BigDecimal.valueOf(totalMinor).multiply(BigDecimal.valueOf(100)) + .divide(checkQty, 2, RoundingMode.HALF_UP); + } + // 3.3 更新主表 + MesQcIqcDO updateIqc = new MesQcIqcDO().setId(iqcId) + .setCriticalQuantity(totalCritical).setMajorQuantity(totalMajor).setMinorQuantity(totalMinor) + .setCriticalRate(criticalRate).setMajorRate(majorRate).setMinorRate(minorRate); + iqcMapper.updateById(updateIqc); + } + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcLineService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcLineService.java new file mode 100644 index 0000000..dd0b8b9 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcLineService.java @@ -0,0 +1,55 @@ +package cn.iocoder.yudao.module.mes.service.qc.lqc; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.line.MesQcIqcLinePageReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.qc.lqc.MesQcIqcLineDO; + +import java.util.List; + +/** + * MES 来料检验单行 Service 接口 + * + * @author 芋道源码 + */ +public interface MesQcIqcLineService { + + /** + * 获得来料检验行 + * + * @param id 编号 + * @return 来料检验行 + */ + MesQcIqcLineDO getIqcLine(Long id); + + /** + * 获得来料检验行分页 + * + * @param pageReqVO 分页查询 + * @return 来料检验行分页 + */ + PageResult getIqcLinePage(MesQcIqcLinePageReqVO pageReqVO); + + /** + * 根据来料检验单 ID 查询所有行 + * + * @param iqcId 来料检验单 ID + * @return 行列表 + */ + List selectListByIqcId(Long iqcId); + + /** + * 从模板指标自动生成检验行 + * + * @param iqcId 来料检验单 ID + * @param templateId 模板 ID + */ + void createLinesFromTemplate(Long iqcId, Long templateId); + + /** + * 根据来料检验单 ID 级联删除所有行 + * + * @param iqcId 来料检验单 ID + */ + void deleteByIqcId(Long iqcId); + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcLineServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcLineServiceImpl.java new file mode 100644 index 0000000..c3fb83e --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcLineServiceImpl.java @@ -0,0 +1,72 @@ +package cn.iocoder.yudao.module.mes.service.qc.lqc; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.line.MesQcIqcLinePageReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.qc.lqc.MesQcIqcLineDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.qc.template.MesQcTemplateIndicatorDO; +import cn.iocoder.yudao.module.mes.dal.mysql.qc.lqc.MesQcIqcLineMapper; +import cn.iocoder.yudao.module.mes.dal.mysql.qc.template.MesQcTemplateIndicatorMapper; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import java.util.List; + +/** + * MES 来料检验单行 Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Validated +public class MesQcIqcLineServiceImpl implements MesQcIqcLineService { + + @Resource + private MesQcIqcLineMapper iqcLineMapper; + @Resource + private MesQcTemplateIndicatorMapper templateIndicatorMapper; + + @Override + public MesQcIqcLineDO getIqcLine(Long id) { + return iqcLineMapper.selectById(id); + } + + @Override + public PageResult getIqcLinePage(MesQcIqcLinePageReqVO pageReqVO) { + return iqcLineMapper.selectPage(pageReqVO); + } + + @Override + public List selectListByIqcId(Long iqcId) { + return iqcLineMapper.selectListByIqcId(iqcId); + } + + @Override + public void createLinesFromTemplate(Long iqcId, Long templateId) { + List indicators = templateIndicatorMapper.selectListByTemplateId(templateId); + // TODO @AI:convertList; + for (MesQcTemplateIndicatorDO indicator : indicators) { + // TODO @AI:链式设置; + MesQcIqcLineDO line = new MesQcIqcLineDO(); + line.setIqcId(iqcId); + line.setIndicatorId(indicator.getIndicatorId()); + line.setToolId(null); // TODO @芋艿:模板指标暂无 toolId,后续可扩展 + line.setCheckMethod(indicator.getCheckMethod()); + line.setStandardValue(indicator.getStandardValue()); + line.setUnitMeasureId(indicator.getUnitMeasureId()); + line.setMaxThreshold(indicator.getThresholdMax()); + line.setMinThreshold(indicator.getThresholdMin()); + line.setCriticalQuantity(0); + line.setMajorQuantity(0); + line.setMinorQuantity(0); + // TODO @AI:insertBatch; + iqcLineMapper.insert(line); + } + } + + @Override + public void deleteByIqcId(Long iqcId) { + iqcLineMapper.deleteByIqcId(iqcId); + } + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcService.java index 57e9ce1..d84a14d 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcService.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcService.java @@ -1,16 +1,11 @@ package cn.iocoder.yudao.module.mes.service.qc.lqc; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.*; -import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.defect.MesQcIqcDefectPageReqVO; -import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.defect.MesQcIqcDefectSaveReqVO; -import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.line.MesQcIqcLinePageReqVO; +import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.MesQcIqcPageReqVO; +import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.MesQcIqcSaveReqVO; import cn.iocoder.yudao.module.mes.dal.dataobject.qc.lqc.MesQcIqcDO; -import cn.iocoder.yudao.module.mes.dal.dataobject.qc.lqc.MesQcIqcDefectDO; -import cn.iocoder.yudao.module.mes.dal.dataobject.qc.lqc.MesQcIqcLineDO; import jakarta.validation.Valid; -// TODO @AI:和别的模块一样,拆分成多个 service /** * MES 来料检验单(IQC) Service 接口 * @@ -18,8 +13,6 @@ import jakarta.validation.Valid; */ public interface MesQcIqcService { - // ========== 来料检验主表 ========== - /** * 创建来料检验单 * @@ -65,54 +58,4 @@ public interface MesQcIqcService { */ PageResult getIqcPage(MesQcIqcPageReqVO pageReqVO); - // ========== 来料检验行(只读) ========== - - /** - * 获得来料检验行 - * - * @param id 编号 - * @return 来料检验行 - */ - MesQcIqcLineDO getIqcLine(Long id); - - /** - * 获得来料检验行分页 - * - * @param pageReqVO 分页查询 - * @return 来料检验行分页 - */ - PageResult getIqcLinePage(MesQcIqcLinePageReqVO pageReqVO); - - // ========== 来料检验缺陷记录 ========== - - /** - * 创建来料检验缺陷记录 - * - * @param createReqVO 创建信息 - * @return 编号 - */ - Long createIqcDefect(@Valid MesQcIqcDefectSaveReqVO createReqVO); - - /** - * 更新来料检验缺陷记录 - * - * @param updateReqVO 更新信息 - */ - void updateIqcDefect(@Valid MesQcIqcDefectSaveReqVO updateReqVO); - - /** - * 删除来料检验缺陷记录 - * - * @param id 编号 - */ - void deleteIqcDefect(Long id); - - /** - * 获得来料检验缺陷记录分页 - * - * @param pageReqVO 分页查询 - * @return 来料检验缺陷记录分页 - */ - PageResult getIqcDefectPage(MesQcIqcDefectPageReqVO pageReqVO); - } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcServiceImpl.java index 1fe6d1c..4535934 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcServiceImpl.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcServiceImpl.java @@ -3,36 +3,26 @@ package cn.iocoder.yudao.module.mes.service.qc.lqc; import cn.hutool.core.util.ObjUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; -import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.*; -import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.defect.MesQcIqcDefectPageReqVO; -import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.defect.MesQcIqcDefectSaveReqVO; -import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.line.MesQcIqcLinePageReqVO; +import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.MesQcIqcPageReqVO; +import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.MesQcIqcSaveReqVO; import cn.iocoder.yudao.module.mes.dal.dataobject.qc.lqc.MesQcIqcDO; -import cn.iocoder.yudao.module.mes.dal.dataobject.qc.lqc.MesQcIqcDefectDO; -import cn.iocoder.yudao.module.mes.dal.dataobject.qc.lqc.MesQcIqcLineDO; import cn.iocoder.yudao.module.mes.dal.dataobject.qc.template.MesQcTemplateDO; -import cn.iocoder.yudao.module.mes.dal.dataobject.qc.template.MesQcTemplateIndicatorDO; import cn.iocoder.yudao.module.mes.dal.dataobject.qc.template.MesQcTemplateItemDO; -import cn.iocoder.yudao.module.mes.dal.mysql.qc.lqc.MesQcIqcDefectMapper; -import cn.iocoder.yudao.module.mes.dal.mysql.qc.lqc.MesQcIqcLineMapper; import cn.iocoder.yudao.module.mes.dal.mysql.qc.lqc.MesQcIqcMapper; -import cn.iocoder.yudao.module.mes.dal.mysql.qc.template.MesQcTemplateIndicatorMapper; import cn.iocoder.yudao.module.mes.dal.mysql.qc.template.MesQcTemplateItemMapper; import cn.iocoder.yudao.module.mes.dal.mysql.qc.template.MesQcTemplateMapper; +import cn.iocoder.yudao.module.mes.enums.qc.MesQcIqcStatusEnum; +import cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; -import java.math.BigDecimal; -import java.math.RoundingMode; -import java.util.List; import java.util.Objects; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; -// TODO @AI:和别的模块一样,拆分成多个 service /** * MES 来料检验单(IQC) Service 实现类 * @@ -42,41 +32,34 @@ import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; @Validated public class MesQcIqcServiceImpl implements MesQcIqcService { - // TODO @AI:搞个枚举类; - /** - * IQC 检测种类值(对应 mes_qc_type 字典 value=1) - */ - private static final int QC_TYPE_IQC = 1; - @Resource private MesQcIqcMapper iqcMapper; @Resource - private MesQcIqcLineMapper iqcLineMapper; - @Resource - private MesQcIqcDefectMapper iqcDefectMapper; - @Resource private MesQcTemplateMapper templateMapper; @Resource - private MesQcTemplateIndicatorMapper templateIndicatorMapper; - @Resource private MesQcTemplateItemMapper templateItemMapper; - // ========== 来料检验主表 ========== + @Resource + private MesQcIqcLineService iqcLineService; + @Resource + private MesQcIqcDefectService iqcDefectService; @Override @Transactional(rollbackFor = Exception.class) public Long createIqc(MesQcIqcSaveReqVO createReqVO) { - // 1. 校验编号唯一 + // 1.1 校验编号唯一 validateIqcCodeUnique(null, createReqVO.getCode()); - - // 2. 查找物料关联的 IQC 检测模板 + // 1.2 查找物料关联的 IQC 检测模板 Long templateId = createReqVO.getTemplateId(); + // TODO @AI:直接使用 templateService 的 validateTemplateExists() 方法,后续如果有更多模板相关的校验,也可以放在该方法中 MesQcTemplateDO template = templateMapper.selectById(templateId); - if (template == null || template.getTypes() == null || !template.getTypes().contains(QC_TYPE_IQC)) { + // TODO @AI:CollUtil.contains 这样更合适; + if (template == null || template.getTypes() == null || !template.getTypes().contains(MesQcTypeEnum.IQC.getType())) { throw exception(QC_IQC_NO_TEMPLATE); } - // 3. 从模板的产品关联中获取检测参数(min_check_quantity、max_unqualified_quantity) + // 3.1 从模板的产品关联中获取检测参数(min_check_quantity、max_unqualified_quantity) + // TODO @AI:使用 templateItemService 方法,不要直接使用对方的 mapper; MesQcTemplateItemDO templateItem = templateItemMapper.selectByTemplateIdAndItemId( templateId, createReqVO.getItemId()); if (templateItem != null) { @@ -87,57 +70,43 @@ public class MesQcIqcServiceImpl implements MesQcIqcService { createReqVO.setMaxUnqualifiedQuantity(templateItem.getQuantityUnqualified()); } } - - // 4. 插入主表 + // 3.2 插入主表 MesQcIqcDO iqc = BeanUtils.toBean(createReqVO, MesQcIqcDO.class); - iqc.setStatus(0); // 草稿 + iqc.setStatus(MesQcIqcStatusEnum.PREPARE.getType()); iqcMapper.insert(iqc); - // 5. 从模板指标自动生成检验行 - List indicators = templateIndicatorMapper.selectListByTemplateId(templateId); - for (MesQcTemplateIndicatorDO indicator : indicators) { - MesQcIqcLineDO line = new MesQcIqcLineDO(); - line.setIqcId(iqc.getId()); - line.setIndicatorId(indicator.getIndicatorId()); - line.setToolId(null); // TODO @芋艿:模板指标暂无 toolId,后续可扩展 - line.setCheckMethod(indicator.getCheckMethod()); - line.setStandardValue(indicator.getStandardValue()); - line.setUnitMeasureId(indicator.getUnitMeasureId()); - line.setMaxThreshold(indicator.getThresholdMax()); - line.setMinThreshold(indicator.getThresholdMin()); - line.setCriticalQuantity(0); - line.setMajorQuantity(0); - line.setMinorQuantity(0); - iqcLineMapper.insert(line); - } - + // 4. 从模板指标自动生成检验行 + iqcLineService.createLinesFromTemplate(iqc.getId(), templateId); return iqc.getId(); } @Override public void updateIqc(MesQcIqcSaveReqVO updateReqVO) { - // 1. 校验存在 + // 1.1 校验存在 MesQcIqcDO iqc = validateIqcExists(updateReqVO.getId()); - // 2. 校验状态为草稿 - if (!Objects.equals(iqc.getStatus(), 0)) { + // 1.2 校验状态为草稿 + // TODO @AI:notEquals; + // TODO @AI:抽成一个方法,这样 completeIqc 和 deleteIqc 也可以复用,避免重复代码; + if (!Objects.equals(iqc.getStatus(), MesQcIqcStatusEnum.PREPARE.getType())) { throw exception(QC_IQC_ONLY_PREPARE_CAN_COMPLETE); } - // 3. 校验编号唯一 + // 1.3 校验编号唯一 validateIqcCodeUnique(updateReqVO.getId(), updateReqVO.getCode()); - // 4. 更新 + + // 2. 更新 MesQcIqcDO updateObj = BeanUtils.toBean(updateReqVO, MesQcIqcDO.class); iqcMapper.updateById(updateObj); } @Override public void completeIqc(Long id) { - // 1. 校验存在 + // 1.1 校验存在 MesQcIqcDO iqc = validateIqcExists(id); - // 2. 校验状态为草稿 - if (!Objects.equals(iqc.getStatus(), 0)) { + // 1.2 校验状态为草稿 + if (!Objects.equals(iqc.getStatus(), MesQcIqcStatusEnum.PREPARE.getType())) { throw exception(QC_IQC_ONLY_PREPARE_CAN_COMPLETE); } - // 3. 校验合格品 + 不合格品 = 检测数量 + // 1.3 校验合格品 + 不合格品 = 检测数量 if (iqc.getCheckQuantity() != null && iqc.getCheckQuantity() > 0) { int total = (iqc.getQualifiedQuantity() != null ? iqc.getQualifiedQuantity() : 0) + (iqc.getUnqualifiedQuantity() != null ? iqc.getUnqualifiedQuantity() : 0); @@ -145,29 +114,31 @@ public class MesQcIqcServiceImpl implements MesQcIqcService { throw exception(QC_IQC_QUANTITY_MISMATCH); } } - // 4. 更新状态为已完成 - MesQcIqcDO updateObj = new MesQcIqcDO(); - updateObj.setId(id); - updateObj.setStatus(1); + + // 2. 更新状态为已完成 + MesQcIqcDO updateObj = new MesQcIqcDO() + .setId(id).setStatus(MesQcIqcStatusEnum.FINISHED.getType()); iqcMapper.updateById(updateObj); + // TODO @芋艿:WM 模块迁移后,更新到货通知单行/外协入库单行的检验结果 } @Override @Transactional(rollbackFor = Exception.class) public void deleteIqc(Long id) { - // 1. 校验存在 + // 1.1 校验存在 MesQcIqcDO iqc = validateIqcExists(id); - // 2. 仅草稿可删 - if (!Objects.equals(iqc.getStatus(), 0)) { + // 1.2 仅草稿可删 + if (!Objects.equals(iqc.getStatus(), MesQcIqcStatusEnum.PREPARE.getType())) { throw exception(QC_IQC_ONLY_PREPARE_CAN_DELETE); } - // 3. 删除主表 + + // 2.1 删除主表 iqcMapper.deleteById(id); - // 4. 级联删除行 - iqcLineMapper.deleteByIqcId(id); - // 5. 级联删除缺陷记录 - iqcDefectMapper.deleteByIqcId(id); + // 2.2 级联删除行 + iqcLineService.deleteByIqcId(id); + // 2.3 级联删除缺陷记录 + iqcDefectService.deleteByIqcId(id); } private MesQcIqcDO validateIqcExists(Long id) { @@ -198,146 +169,4 @@ public class MesQcIqcServiceImpl implements MesQcIqcService { return iqcMapper.selectPage(pageReqVO); } - // ========== 来料检验行(只读) ========== - - @Override - public MesQcIqcLineDO getIqcLine(Long id) { - return iqcLineMapper.selectById(id); - } - - @Override - public PageResult getIqcLinePage(MesQcIqcLinePageReqVO pageReqVO) { - return iqcLineMapper.selectPage(pageReqVO); - } - - // ========== 来料检验缺陷记录 ========== - - @Override - @Transactional(rollbackFor = Exception.class) - public Long createIqcDefect(MesQcIqcDefectSaveReqVO createReqVO) { - // 1. 校验 IQC 存在 - validateIqcExists(createReqVO.getIqcId()); - // 2. 校验行存在 - validateIqcLineExists(createReqVO.getLineId()); - // 3. 插入 - MesQcIqcDefectDO defect = BeanUtils.toBean(createReqVO, MesQcIqcDefectDO.class); - iqcDefectMapper.insert(defect); - // 4. 重新计算缺陷统计 - recalculateDefectStats(createReqVO.getIqcId()); - return defect.getId(); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void updateIqcDefect(MesQcIqcDefectSaveReqVO updateReqVO) { - // 1. 校验存在 - validateIqcDefectExists(updateReqVO.getId()); - // 2. 更新 - MesQcIqcDefectDO updateObj = BeanUtils.toBean(updateReqVO, MesQcIqcDefectDO.class); - iqcDefectMapper.updateById(updateObj); - // 3. 重新计算缺陷统计 - recalculateDefectStats(updateReqVO.getIqcId()); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void deleteIqcDefect(Long id) { - // 1. 校验存在 - MesQcIqcDefectDO defect = validateIqcDefectExists(id); - // 2. 删除 - iqcDefectMapper.deleteById(id); - // 3. 重新计算缺陷统计 - recalculateDefectStats(defect.getIqcId()); - } - - private void validateIqcLineExists(Long id) { - if (iqcLineMapper.selectById(id) == null) { - throw exception(QC_IQC_LINE_NOT_EXISTS); - } - } - - private MesQcIqcDefectDO validateIqcDefectExists(Long id) { - MesQcIqcDefectDO defect = iqcDefectMapper.selectById(id); - if (defect == null) { - throw exception(QC_IQC_DEFECT_NOT_EXISTS); - } - return defect; - } - - @Override - public PageResult getIqcDefectPage(MesQcIqcDefectPageReqVO pageReqVO) { - return iqcDefectMapper.selectPage(pageReqVO); - } - - // ========== 内部方法 ========== - - /** - * 重新计算缺陷统计(行级 + 主表级) - * - * @param iqcId 来料检验单 ID - */ - private void recalculateDefectStats(Long iqcId) { - // 1. 查询所有缺陷记录 - List defects = iqcDefectMapper.selectListByIqcId(iqcId); - - // 2. 更新每行的缺陷数量 - List lines = iqcLineMapper.selectListByIqcId(iqcId); - for (MesQcIqcLineDO line : lines) { - int critical = 0, major = 0, minor = 0; - for (MesQcIqcDefectDO defect : defects) { - if (Objects.equals(defect.getLineId(), line.getId())) { - int qty = defect.getDefectQuantity() != null ? defect.getDefectQuantity() : 1; - switch (defect.getDefectLevel()) { - case "CRITICAL": critical += qty; break; - case "MAJOR": major += qty; break; - case "MINOR": minor += qty; break; - } - } - } - MesQcIqcLineDO updateLine = new MesQcIqcLineDO(); - updateLine.setId(line.getId()); - updateLine.setCriticalQuantity(critical); - updateLine.setMajorQuantity(major); - updateLine.setMinorQuantity(minor); - iqcLineMapper.updateById(updateLine); - } - - // 3. 汇总主表的缺陷数量 - int totalCritical = 0, totalMajor = 0, totalMinor = 0; - for (MesQcIqcDefectDO defect : defects) { - int qty = defect.getDefectQuantity() != null ? defect.getDefectQuantity() : 1; - switch (defect.getDefectLevel()) { - case "CRITICAL": totalCritical += qty; break; - case "MAJOR": totalMajor += qty; break; - case "MINOR": totalMinor += qty; break; - } - } - - // 4. 计算缺陷率 - MesQcIqcDO iqc = iqcMapper.selectById(iqcId); - BigDecimal criticalRate = BigDecimal.ZERO; - BigDecimal majorRate = BigDecimal.ZERO; - BigDecimal minorRate = BigDecimal.ZERO; - if (iqc != null && iqc.getCheckQuantity() != null && iqc.getCheckQuantity() > 0) { - BigDecimal checkQty = BigDecimal.valueOf(iqc.getCheckQuantity()); - criticalRate = BigDecimal.valueOf(totalCritical).multiply(BigDecimal.valueOf(100)) - .divide(checkQty, 2, RoundingMode.HALF_UP); - majorRate = BigDecimal.valueOf(totalMajor).multiply(BigDecimal.valueOf(100)) - .divide(checkQty, 2, RoundingMode.HALF_UP); - minorRate = BigDecimal.valueOf(totalMinor).multiply(BigDecimal.valueOf(100)) - .divide(checkQty, 2, RoundingMode.HALF_UP); - } - - // 5. 更新主表 - MesQcIqcDO updateIqc = new MesQcIqcDO(); - updateIqc.setId(iqcId); - updateIqc.setCriticalQuantity(totalCritical); - updateIqc.setMajorQuantity(totalMajor); - updateIqc.setMinorQuantity(totalMinor); - updateIqc.setCriticalRate(criticalRate); - updateIqc.setMajorRate(majorRate); - updateIqc.setMinorRate(minorRate); - iqcMapper.updateById(updateIqc); - } - } -- libgit2 0.21.4