Commit f74a063d441534d7f9dd308aae7048551a33ef78

Authored by YunaiV
1 parent 94b808d7

feat(mes):通过枚举和用户关联来重构缺陷处理流程,并增强内部质量控制功能

Showing 21 changed files with 628 additions and 313 deletions
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;
18 18 import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
19 19 import cn.iocoder.yudao.module.mes.service.md.vendor.MesMdVendorService;
20 20 import cn.iocoder.yudao.module.mes.service.qc.lqc.MesQcIqcService;
  21 +import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  22 +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
21 23 import io.swagger.v3.oas.annotations.Operation;
22 24 import io.swagger.v3.oas.annotations.Parameter;
23 25 import io.swagger.v3.oas.annotations.tags.Tag;
... ... @@ -53,6 +55,9 @@ public class MesQcIqcController {
53 55 @Resource
54 56 private MesMdUnitMeasureService unitMeasureService;
55 57  
  58 + @Resource
  59 + private AdminUserApi adminUserApi;
  60 +
56 61 @PostMapping("/create")
57 62 @Operation(summary = "创建来料检验单")
58 63 @PreAuthorize("@ss.hasPermission('mes:qc-iqc:create')")
... ... @@ -130,6 +135,9 @@ public class MesQcIqcController {
130 135 // 批量查询计量单位(通过物料的 unitMeasureId)
131 136 Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
132 137 convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
  138 + // 批量查询检测人员
  139 + Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
  140 + convertSet(list, MesQcIqcDO::getInspectorUserId));
133 141 // 拼装 VO
134 142 return BeanUtils.toBean(list, MesQcIqcRespVO.class, vo -> {
135 143 findAndThen(vendorMap, vo.getVendorId(),
... ... @@ -141,6 +149,8 @@ public class MesQcIqcController {
141 149 findAndThen(unitMeasureMap, item.getUnitMeasureId(),
142 150 unit -> vo.setUnitName(unit.getName()));
143 151 });
  152 + findAndThen(userMap, vo.getInspectorUserId(),
  153 + user -> vo.setInspectorNickname(user.getNickname()));
144 154 });
145 155 }
146 156  
... ...
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
7 7 import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.defect.MesQcIqcDefectRespVO;
8 8 import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.defect.MesQcIqcDefectSaveReqVO;
9 9 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.lqc.MesQcIqcDefectDO;
10   -import cn.iocoder.yudao.module.mes.service.qc.lqc.MesQcIqcService;
  10 +import cn.iocoder.yudao.module.mes.service.qc.lqc.MesQcIqcDefectService;
11 11 import io.swagger.v3.oas.annotations.Operation;
12 12 import io.swagger.v3.oas.annotations.Parameter;
13 13 import io.swagger.v3.oas.annotations.tags.Tag;
... ... @@ -26,20 +26,20 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
26 26 public class MesQcIqcDefectController {
27 27  
28 28 @Resource
29   - private MesQcIqcService iqcService;
  29 + private MesQcIqcDefectService iqcDefectService;
30 30  
31 31 @PostMapping("/create")
32 32 @Operation(summary = "创建来料检验缺陷记录")
33 33 @PreAuthorize("@ss.hasPermission('mes:qc-iqc:create')")
34 34 public CommonResult<Long> createIqcDefect(@Valid @RequestBody MesQcIqcDefectSaveReqVO createReqVO) {
35   - return success(iqcService.createIqcDefect(createReqVO));
  35 + return success(iqcDefectService.createIqcDefect(createReqVO));
36 36 }
37 37  
38 38 @PutMapping("/update")
39 39 @Operation(summary = "更新来料检验缺陷记录")
40 40 @PreAuthorize("@ss.hasPermission('mes:qc-iqc:update')")
41 41 public CommonResult<Boolean> updateIqcDefect(@Valid @RequestBody MesQcIqcDefectSaveReqVO updateReqVO) {
42   - iqcService.updateIqcDefect(updateReqVO);
  42 + iqcDefectService.updateIqcDefect(updateReqVO);
43 43 return success(true);
44 44 }
45 45  
... ... @@ -48,7 +48,7 @@ public class MesQcIqcDefectController {
48 48 @Parameter(name = "id", description = "编号", required = true)
49 49 @PreAuthorize("@ss.hasPermission('mes:qc-iqc:update')")
50 50 public CommonResult<Boolean> deleteIqcDefect(@RequestParam("id") Long id) {
51   - iqcService.deleteIqcDefect(id);
  51 + iqcDefectService.deleteIqcDefect(id);
52 52 return success(true);
53 53 }
54 54  
... ... @@ -56,7 +56,7 @@ public class MesQcIqcDefectController {
56 56 @Operation(summary = "获得来料检验缺陷记录分页")
57 57 @PreAuthorize("@ss.hasPermission('mes:qc-iqc:query')")
58 58 public CommonResult<PageResult<MesQcIqcDefectRespVO>> getIqcDefectPage(@Valid MesQcIqcDefectPageReqVO pageReqVO) {
59   - PageResult<MesQcIqcDefectDO> pageResult = iqcService.getIqcDefectPage(pageReqVO);
  59 + PageResult<MesQcIqcDefectDO> pageResult = iqcDefectService.getIqcDefectPage(pageReqVO);
60 60 return success(BeanUtils.toBean(pageResult, MesQcIqcDefectRespVO.class));
61 61 }
62 62  
... ...
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;
11 11 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicator.MesQcIndicatorDO;
12 12 import cn.iocoder.yudao.module.mes.dal.dataobject.tm.tool.MesTmToolDO;
13 13 import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
14   -import cn.iocoder.yudao.module.mes.service.qc.lqc.MesQcIqcService;
  14 +import cn.iocoder.yudao.module.mes.service.qc.lqc.MesQcIqcLineService;
15 15 import cn.iocoder.yudao.module.mes.service.qc.indicator.MesQcIndicatorService;
16 16 import cn.iocoder.yudao.module.mes.service.tm.tool.MesTmToolService;
17 17 import io.swagger.v3.oas.annotations.Operation;
... ... @@ -41,7 +41,7 @@ import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAnd
41 41 public class MesQcIqcLineController {
42 42  
43 43 @Resource
44   - private MesQcIqcService iqcService;
  44 + private MesQcIqcLineService iqcLineService;
45 45 @Resource
46 46 private MesQcIndicatorService indicatorService;
47 47 @Resource
... ... @@ -54,7 +54,7 @@ public class MesQcIqcLineController {
54 54 @Parameter(name = "id", description = "编号", required = true, example = "1024")
55 55 @PreAuthorize("@ss.hasPermission('mes:qc-iqc:query')")
56 56 public CommonResult<MesQcIqcLineRespVO> getIqcLine(@RequestParam("id") Long id) {
57   - MesQcIqcLineDO line = iqcService.getIqcLine(id);
  57 + MesQcIqcLineDO line = iqcLineService.getIqcLine(id);
58 58 return success(buildLineRespVOList(Collections.singletonList(line)).get(0));
59 59 }
60 60  
... ... @@ -62,7 +62,7 @@ public class MesQcIqcLineController {
62 62 @Operation(summary = "获得来料检验单行分页")
63 63 @PreAuthorize("@ss.hasPermission('mes:qc-iqc:query')")
64 64 public CommonResult<PageResult<MesQcIqcLineRespVO>> getIqcLinePage(@Valid MesQcIqcLinePageReqVO pageReqVO) {
65   - PageResult<MesQcIqcLineDO> pageResult = iqcService.getIqcLinePage(pageReqVO);
  65 + PageResult<MesQcIqcLineDO> pageResult = iqcLineService.getIqcLinePage(pageReqVO);
66 66 return success(new PageResult<>(buildLineRespVOList(pageResult.getList()), pageResult.getTotal()));
67 67 }
68 68  
... ...
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 {
29 29 @Schema(description = "产品物料 ID", example = "20")
30 30 private Long itemId;
31 31  
32   - @Schema(description = "检测结果", example = "PASS")
33   - private String checkResult;
  32 + @Schema(description = "检测结果", example = "1")
  33 + private Integer checkResult;
34 34  
35 35 @Schema(description = "状态", example = "0")
36 36 private Integer status;
37 37  
  38 + @Schema(description = "检测人员用户 ID", example = "1")
  39 + private Long inspectorUserId;
  40 +
38 41 @Schema(description = "来料日期")
39 42 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
40 43 private LocalDateTime[] receiveDate;
... ...
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 {
119 119  
120 120 // ========== 检验 ==========
121 121  
122   - @Schema(description = "检测结果", example = "PASS")
  122 + @Schema(description = "检测结果", example = "1")
123 123 @ExcelProperty("检测结果")
124   - private String checkResult;
  124 + private Integer checkResult;
125 125  
126 126 @Schema(description = "来料日期")
127 127 @ExcelProperty("来料日期")
... ... @@ -131,9 +131,12 @@ public class MesQcIqcRespVO {
131 131 @ExcelProperty("检测日期")
132 132 private LocalDateTime inspectDate;
133 133  
134   - @Schema(description = "检测人员", example = "张三")
  134 + @Schema(description = "检测人员用户 ID", example = "1")
  135 + private Long inspectorUserId;
  136 +
  137 + @Schema(description = "检测人员昵称", example = "张三")
135 138 @ExcelProperty("检测人员")
136   - private String inspector;
  139 + private String inspectorNickname;
137 140  
138 141 @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
139 142 @ExcelProperty("状态")
... ...
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 {
79 79  
80 80 // ========== 检验 ==========
81 81  
82   - @Schema(description = "检测结果", example = "PASS")
83   - private String checkResult;
  82 + @Schema(description = "检测结果", example = "1")
  83 + private Integer checkResult;
84 84  
85 85 @Schema(description = "来料日期")
86 86 private LocalDateTime receiveDate;
... ... @@ -88,8 +88,8 @@ public class MesQcIqcSaveReqVO {
88 88 @Schema(description = "检测日期")
89 89 private LocalDateTime inspectDate;
90 90  
91   - @Schema(description = "检测人员", example = "张三")
92   - private String inspector;
  91 + @Schema(description = "检测人员用户 ID", example = "1")
  92 + private Long inspectorUserId;
93 93  
94 94 @Schema(description = "备注", example = "备注")
95 95 private String remark;
... ...
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 {
21 21 @Schema(description = "缺陷描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "表面划伤")
22 22 private String defectName;
23 23  
24   - @Schema(description = "缺陷等级", requiredMode = Schema.RequiredMode.REQUIRED, example = "CRITICAL")
25   - private String defectLevel;
  24 + @Schema(description = "缺陷等级", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  25 + private Integer defectLevel;
26 26  
27 27 @Schema(description = "缺陷数量", example = "1")
28 28 private Integer defectQuantity;
... ...
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 {
24 24 @NotEmpty(message = "缺陷描述不能为空")
25 25 private String defectName;
26 26  
27   - @Schema(description = "缺陷等级", requiredMode = Schema.RequiredMode.REQUIRED, example = "CRITICAL")
28   - @NotEmpty(message = "缺陷等级不能为空")
29   - private String defectLevel;
  27 + @Schema(description = "缺陷等级", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  28 + @NotNull(message = "缺陷等级不能为空")
  29 + private Integer defectLevel;
30 30  
31 31 @Schema(description = "缺陷数量", example = "1")
32 32 private Integer defectQuantity;
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/lqc/MesQcIqcDO.java
... ... @@ -12,9 +12,8 @@ import lombok.*;
12 12 import java.math.BigDecimal;
13 13 import java.time.LocalDateTime;
14 14  
15   -// TODO @AI:IQC 完整的拼写,也加下;
16 15 /**
17   - * MES 来料检验单(IQC) DO
  16 + * MES 来料检验单(IQC, Incoming Quality Control) DO
18 17 *
19 18 * @author 芋道源码
20 19 */
... ... @@ -147,13 +146,12 @@ public class MesQcIqcDO extends BaseDO {
147 146  
148 147 // ========== 检验 ==========
149 148  
150   - // TODO @AI:需要搞个枚举么?使用 int 把。现在就搞了;
151 149 /**
152 150 * 检测结果
153 151 *
154   - * 字典 mes_qc_check_result
  152 + * 枚举 {@link cn.iocoder.yudao.module.mes.enums.qc.MesQcCheckResultEnum}
155 153 */
156   - private String checkResult;
  154 + private Integer checkResult;
157 155 /**
158 156 * 来料日期
159 157 */
... ... @@ -165,13 +163,16 @@ public class MesQcIqcDO extends BaseDO {
165 163 /**
166 164 * 检测人员
167 165 */
168   - // TODO @AI:改成 inspectorUserId;
169   - private String inspector;
170   - // TODO @AI:需要搞个枚举么?使用 int 把。现在就搞了;
171 166 /**
172   - * 状态(0=草稿 1=已完成)
  167 + * 检测人员用户 ID
173 168 *
174   - * 字典 mes_qc_iqc_status
  169 + * 关联 AdminUserDO 的 id
  170 + */
  171 + private Long inspectorUserId;
  172 + /**
  173 + * 状态
  174 + *
  175 + * 枚举 {@link cn.iocoder.yudao.module.mes.enums.qc.MesQcIqcStatusEnum}
175 176 */
176 177 private Integer status;
177 178 /**
... ...
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 {
42 42 * 缺陷描述
43 43 */
44 44 private String defectName;
45   - // TODO @AI:要不枚举值也加下,也改成 int;
46 45 /**
47 46 * 缺陷等级
48 47 *
49   - * 字典 mes_defect_level
  48 + * 枚举 {@link cn.iocoder.yudao.module.mes.enums.qc.MesQcDefectLevelEnum}
50 49 */
51   - private String defectLevel;
  50 + private Integer defectLevel;
52 51 /**
53 52 * 缺陷数量
54 53 */
... ...
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&lt;MesQcIqcDO&gt; {
25 25 .eqIfPresent(MesQcIqcDO::getStatus, reqVO.getStatus())
26 26 .betweenIfPresent(MesQcIqcDO::getReceiveDate, reqVO.getReceiveDate())
27 27 .betweenIfPresent(MesQcIqcDO::getInspectDate, reqVO.getInspectDate())
  28 + .eqIfPresent(MesQcIqcDO::getInspectorUserId, reqVO.getInspectorUserId())
28 29 .orderByDesc(MesQcIqcDO::getId));
29 30 }
30 31  
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcCheckResultEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.enums.qc;
  2 +
  3 +import cn.iocoder.yudao.framework.common.core.ArrayValuable;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Getter;
  6 +
  7 +import java.util.Arrays;
  8 +
  9 +/**
  10 + * MES 检测结果枚举
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Getter
  15 +@AllArgsConstructor
  16 +public enum MesQcCheckResultEnum implements ArrayValuable<Integer> {
  17 +
  18 + PASS(1, "合格"), // TODO @AI:检验通过;
  19 + FAIL(2, "不合格"), // TODO @AI:检验不通过;
  20 + ACCEPT(3, "让步接收"); // TODO @AI:去掉;
  21 +
  22 + public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesQcCheckResultEnum::getType).toArray(Integer[]::new);
  23 +
  24 + /**
  25 + * 结果值
  26 + */
  27 + private final Integer type;
  28 + /**
  29 + * 结果名
  30 + */
  31 + private final String name;
  32 +
  33 + @Override
  34 + public Integer[] array() {
  35 + return ARRAYS;
  36 + }
  37 +
  38 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcDefectLevelEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.enums.qc;
  2 +
  3 +import cn.iocoder.yudao.framework.common.core.ArrayValuable;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Getter;
  6 +
  7 +import java.util.Arrays;
  8 +
  9 +/**
  10 + * MES 缺陷等级枚举
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Getter
  15 +@AllArgsConstructor
  16 +public enum MesQcDefectLevelEnum implements ArrayValuable<Integer> {
  17 +
  18 + CRITICAL(1, "致命"),
  19 + MAJOR(2, "严重"),
  20 + MINOR(3, "轻微");
  21 +
  22 + public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesQcDefectLevelEnum::getType).toArray(Integer[]::new);
  23 +
  24 + /**
  25 + * 等级值
  26 + */
  27 + private final Integer type;
  28 + /**
  29 + * 等级名
  30 + */
  31 + private final String name;
  32 +
  33 + @Override
  34 + public Integer[] array() {
  35 + return ARRAYS;
  36 + }
  37 +
  38 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcIqcStatusEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.enums.qc;
  2 +
  3 +import cn.iocoder.yudao.framework.common.core.ArrayValuable;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Getter;
  6 +
  7 +import java.util.Arrays;
  8 +
  9 +/**
  10 + * MES 检验单状态枚举
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Getter
  15 +@AllArgsConstructor
  16 +public enum MesQcIqcStatusEnum implements ArrayValuable<Integer> {
  17 +
  18 + PREPARE(0, "草稿"),
  19 + FINISHED(1, "已完成");
  20 +
  21 + public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesQcIqcStatusEnum::getType).toArray(Integer[]::new);
  22 +
  23 + /**
  24 + * 状态值
  25 + */
  26 + private final Integer type;
  27 + /**
  28 + * 状态名
  29 + */
  30 + private final String name;
  31 +
  32 + @Override
  33 + public Integer[] array() {
  34 + return ARRAYS;
  35 + }
  36 +
  37 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcTypeEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.enums.qc;
  2 +
  3 +import cn.iocoder.yudao.framework.common.core.ArrayValuable;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Getter;
  6 +
  7 +import java.util.Arrays;
  8 +
  9 +/**
  10 + * MES 检测种类枚举
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Getter
  15 +@AllArgsConstructor
  16 +public enum MesQcTypeEnum implements ArrayValuable<Integer> {
  17 +
  18 + IQC(1, "来料检验"),
  19 + IPQC(2, "过程检验"),
  20 + OQC(3, "出货检验"),
  21 + RQC(4, "退货检验");
  22 +
  23 + public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesQcTypeEnum::getType).toArray(Integer[]::new);
  24 +
  25 + /**
  26 + * 类型值
  27 + */
  28 + private final Integer type;
  29 + /**
  30 + * 类型名
  31 + */
  32 + private final String name;
  33 +
  34 + @Override
  35 + public Integer[] array() {
  36 + return ARRAYS;
  37 + }
  38 +
  39 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcDefectService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.service.qc.lqc;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.defect.MesQcIqcDefectPageReqVO;
  5 +import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.defect.MesQcIqcDefectSaveReqVO;
  6 +import cn.iocoder.yudao.module.mes.dal.dataobject.qc.lqc.MesQcIqcDefectDO;
  7 +import jakarta.validation.Valid;
  8 +
  9 +/**
  10 + * MES 来料检验缺陷记录 Service 接口
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +public interface MesQcIqcDefectService {
  15 +
  16 + /**
  17 + * 创建来料检验缺陷记录
  18 + *
  19 + * @param createReqVO 创建信息
  20 + * @return 编号
  21 + */
  22 + Long createIqcDefect(@Valid MesQcIqcDefectSaveReqVO createReqVO);
  23 +
  24 + /**
  25 + * 更新来料检验缺陷记录
  26 + *
  27 + * @param updateReqVO 更新信息
  28 + */
  29 + void updateIqcDefect(@Valid MesQcIqcDefectSaveReqVO updateReqVO);
  30 +
  31 + /**
  32 + * 删除来料检验缺陷记录
  33 + *
  34 + * @param id 编号
  35 + */
  36 + void deleteIqcDefect(Long id);
  37 +
  38 + /**
  39 + * 获得来料检验缺陷记录分页
  40 + *
  41 + * @param pageReqVO 分页查询
  42 + * @return 来料检验缺陷记录分页
  43 + */
  44 + PageResult<MesQcIqcDefectDO> getIqcDefectPage(MesQcIqcDefectPageReqVO pageReqVO);
  45 +
  46 + /**
  47 + * 根据来料检验单 ID 级联删除所有缺陷记录
  48 + *
  49 + * @param iqcId 来料检验单 ID
  50 + */
  51 + void deleteByIqcId(Long iqcId);
  52 +
  53 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcDefectServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.service.qc.lqc;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  5 +import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.defect.MesQcIqcDefectPageReqVO;
  6 +import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.defect.MesQcIqcDefectSaveReqVO;
  7 +import cn.iocoder.yudao.module.mes.dal.dataobject.qc.lqc.MesQcIqcDO;
  8 +import cn.iocoder.yudao.module.mes.dal.dataobject.qc.lqc.MesQcIqcDefectDO;
  9 +import cn.iocoder.yudao.module.mes.dal.dataobject.qc.lqc.MesQcIqcLineDO;
  10 +import cn.iocoder.yudao.module.mes.dal.mysql.qc.lqc.MesQcIqcDefectMapper;
  11 +import cn.iocoder.yudao.module.mes.dal.mysql.qc.lqc.MesQcIqcLineMapper;
  12 +import cn.iocoder.yudao.module.mes.dal.mysql.qc.lqc.MesQcIqcMapper;
  13 +import cn.iocoder.yudao.module.mes.enums.qc.MesQcDefectLevelEnum;
  14 +import jakarta.annotation.Resource;
  15 +import org.springframework.context.annotation.Lazy;
  16 +import org.springframework.stereotype.Service;
  17 +import org.springframework.transaction.annotation.Transactional;
  18 +import org.springframework.validation.annotation.Validated;
  19 +
  20 +import java.math.BigDecimal;
  21 +import java.math.RoundingMode;
  22 +import java.util.List;
  23 +import java.util.Objects;
  24 +
  25 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  26 +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
  27 +
  28 +/**
  29 + * MES 来料检验缺陷记录 Service 实现类
  30 + *
  31 + * @author 芋道源码
  32 + */
  33 +@Service
  34 +@Validated
  35 +public class MesQcIqcDefectServiceImpl implements MesQcIqcDefectService {
  36 +
  37 + @Resource
  38 + private MesQcIqcDefectMapper iqcDefectMapper;
  39 + @Resource
  40 + private MesQcIqcLineMapper iqcLineMapper;
  41 + @Resource
  42 + private MesQcIqcMapper iqcMapper;
  43 + @Resource
  44 + @Lazy
  45 + private MesQcIqcLineService iqcLineService;
  46 +
  47 + @Override
  48 + @Transactional(rollbackFor = Exception.class)
  49 + public Long createIqcDefect(MesQcIqcDefectSaveReqVO createReqVO) {
  50 + // 1.1 校验 IQC 存在
  51 + validateIqcExists(createReqVO.getIqcId());
  52 + // 1.2 校验行存在
  53 + validateIqcLineExists(createReqVO.getLineId());
  54 +
  55 + // 2. 插入
  56 + MesQcIqcDefectDO defect = BeanUtils.toBean(createReqVO, MesQcIqcDefectDO.class);
  57 + iqcDefectMapper.insert(defect);
  58 +
  59 + // 3. 重新计算缺陷统计
  60 + recalculateDefectStats(createReqVO.getIqcId());
  61 + return defect.getId();
  62 + }
  63 +
  64 + @Override
  65 + @Transactional(rollbackFor = Exception.class)
  66 + public void updateIqcDefect(MesQcIqcDefectSaveReqVO updateReqVO) {
  67 + // 1. 校验存在
  68 + validateIqcDefectExists(updateReqVO.getId());
  69 +
  70 + // 2. 更新
  71 + MesQcIqcDefectDO updateObj = BeanUtils.toBean(updateReqVO, MesQcIqcDefectDO.class);
  72 + iqcDefectMapper.updateById(updateObj);
  73 +
  74 + // 3. 重新计算缺陷统计
  75 + recalculateDefectStats(updateReqVO.getIqcId());
  76 + }
  77 +
  78 + @Override
  79 + @Transactional(rollbackFor = Exception.class)
  80 + public void deleteIqcDefect(Long id) {
  81 + // 1. 校验存在
  82 + MesQcIqcDefectDO defect = validateIqcDefectExists(id);
  83 +
  84 + // 2. 删除
  85 + iqcDefectMapper.deleteById(id);
  86 +
  87 + // 3. 重新计算缺陷统计
  88 + recalculateDefectStats(defect.getIqcId());
  89 + }
  90 +
  91 + @Override
  92 + public PageResult<MesQcIqcDefectDO> getIqcDefectPage(MesQcIqcDefectPageReqVO pageReqVO) {
  93 + return iqcDefectMapper.selectPage(pageReqVO);
  94 + }
  95 +
  96 + @Override
  97 + public void deleteByIqcId(Long iqcId) {
  98 + iqcDefectMapper.deleteByIqcId(iqcId);
  99 + }
  100 +
  101 + private void validateIqcExists(Long iqcId) {
  102 + if (iqcMapper.selectById(iqcId) == null) {
  103 + throw exception(QC_IQC_NOT_EXISTS);
  104 + }
  105 + }
  106 +
  107 + private void validateIqcLineExists(Long lineId) {
  108 + MesQcIqcLineDO line = iqcLineService.getIqcLine(lineId);
  109 + if (line == null) {
  110 + throw exception(QC_IQC_LINE_NOT_EXISTS);
  111 + }
  112 + }
  113 +
  114 + private MesQcIqcDefectDO validateIqcDefectExists(Long id) {
  115 + MesQcIqcDefectDO defect = iqcDefectMapper.selectById(id);
  116 + if (defect == null) {
  117 + throw exception(QC_IQC_DEFECT_NOT_EXISTS);
  118 + }
  119 + return defect;
  120 + }
  121 +
  122 + /**
  123 + * 重新计算缺陷统计(行级 + 主表级)
  124 + *
  125 + * @param iqcId 来料检验单 ID
  126 + */
  127 + private void recalculateDefectStats(Long iqcId) {
  128 + // 1. 查询所有缺陷记录
  129 + List<MesQcIqcDefectDO> defects = iqcDefectMapper.selectListByIqcId(iqcId);
  130 +
  131 + // 2. 更新每行的缺陷数量
  132 + List<MesQcIqcLineDO> lines = iqcLineService.selectListByIqcId(iqcId);
  133 + for (MesQcIqcLineDO line : lines) {
  134 + int critical = 0;
  135 + int major = 0;
  136 + int minor = 0;
  137 + for (MesQcIqcDefectDO defect : defects) {
  138 + // TODO @AI:notEquals continue;减少括号层级;
  139 + if (Objects.equals(defect.getLineId(), line.getId())) {
  140 + // TODO @AI:defaultIfNull;变量改成 quantity
  141 + int qty = defect.getDefectQuantity() != null ? defect.getDefectQuantity() : 1;
  142 + if (Objects.equals(defect.getDefectLevel(), MesQcDefectLevelEnum.CRITICAL.getType())) {
  143 + critical += qty;
  144 + } else if (Objects.equals(defect.getDefectLevel(), MesQcDefectLevelEnum.MAJOR.getType())) {
  145 + major += qty;
  146 + } else if (Objects.equals(defect.getDefectLevel(), MesQcDefectLevelEnum.MINOR.getType())) {
  147 + minor += qty;
  148 + }
  149 + // TODO @AI:抛出异常;未知的缺陷等级
  150 + }
  151 + }
  152 + MesQcIqcLineDO updateLine = new MesQcIqcLineDO().setId(line.getId())
  153 + .setCriticalQuantity(critical).setMajorQuantity(major).setMinorQuantity(minor);
  154 + // 直接通过 lineService 内部更新(避免循环依赖,使用 mapper)
  155 + // TODO @AI:单独搞个 updateLineDefectStats 方法;减少 updateLine 变量的作用域;
  156 + iqcLineMapper.updateById(updateLine);
  157 + }
  158 +
  159 + // 3.1 汇总主表的缺陷数量
  160 + int totalCritical = 0, totalMajor = 0, totalMinor = 0;
  161 + for (MesQcIqcDefectDO defect : defects) {
  162 + // TODO @AI:defaultIfNull;变量改成 quantity
  163 + int qty = defect.getDefectQuantity() != null ? defect.getDefectQuantity() : 1;
  164 + if (Objects.equals(defect.getDefectLevel(), MesQcDefectLevelEnum.CRITICAL.getType())) {
  165 + totalCritical += qty;
  166 + } else if (Objects.equals(defect.getDefectLevel(), MesQcDefectLevelEnum.MAJOR.getType())) {
  167 + totalMajor += qty;
  168 + } else if (Objects.equals(defect.getDefectLevel(), MesQcDefectLevelEnum.MINOR.getType())) {
  169 + totalMinor += qty;
  170 + }
  171 + // TODO @AI:抛出异常;未知的缺陷等级
  172 + }
  173 + // 3.2 计算缺陷率
  174 + MesQcIqcDO iqc = iqcMapper.selectById(iqcId);
  175 + BigDecimal criticalRate = BigDecimal.ZERO;
  176 + BigDecimal majorRate = BigDecimal.ZERO;
  177 + BigDecimal minorRate = BigDecimal.ZERO;
  178 + if (iqc != null && iqc.getCheckQuantity() != null && iqc.getCheckQuantity() > 0) {
  179 + BigDecimal checkQty = BigDecimal.valueOf(iqc.getCheckQuantity());
  180 + criticalRate = BigDecimal.valueOf(totalCritical).multiply(BigDecimal.valueOf(100))
  181 + .divide(checkQty, 2, RoundingMode.HALF_UP);
  182 + majorRate = BigDecimal.valueOf(totalMajor).multiply(BigDecimal.valueOf(100))
  183 + .divide(checkQty, 2, RoundingMode.HALF_UP);
  184 + minorRate = BigDecimal.valueOf(totalMinor).multiply(BigDecimal.valueOf(100))
  185 + .divide(checkQty, 2, RoundingMode.HALF_UP);
  186 + }
  187 + // 3.3 更新主表
  188 + MesQcIqcDO updateIqc = new MesQcIqcDO().setId(iqcId)
  189 + .setCriticalQuantity(totalCritical).setMajorQuantity(totalMajor).setMinorQuantity(totalMinor)
  190 + .setCriticalRate(criticalRate).setMajorRate(majorRate).setMinorRate(minorRate);
  191 + iqcMapper.updateById(updateIqc);
  192 + }
  193 +
  194 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcLineService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.service.qc.lqc;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.line.MesQcIqcLinePageReqVO;
  5 +import cn.iocoder.yudao.module.mes.dal.dataobject.qc.lqc.MesQcIqcLineDO;
  6 +
  7 +import java.util.List;
  8 +
  9 +/**
  10 + * MES 来料检验单行 Service 接口
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +public interface MesQcIqcLineService {
  15 +
  16 + /**
  17 + * 获得来料检验行
  18 + *
  19 + * @param id 编号
  20 + * @return 来料检验行
  21 + */
  22 + MesQcIqcLineDO getIqcLine(Long id);
  23 +
  24 + /**
  25 + * 获得来料检验行分页
  26 + *
  27 + * @param pageReqVO 分页查询
  28 + * @return 来料检验行分页
  29 + */
  30 + PageResult<MesQcIqcLineDO> getIqcLinePage(MesQcIqcLinePageReqVO pageReqVO);
  31 +
  32 + /**
  33 + * 根据来料检验单 ID 查询所有行
  34 + *
  35 + * @param iqcId 来料检验单 ID
  36 + * @return 行列表
  37 + */
  38 + List<MesQcIqcLineDO> selectListByIqcId(Long iqcId);
  39 +
  40 + /**
  41 + * 从模板指标自动生成检验行
  42 + *
  43 + * @param iqcId 来料检验单 ID
  44 + * @param templateId 模板 ID
  45 + */
  46 + void createLinesFromTemplate(Long iqcId, Long templateId);
  47 +
  48 + /**
  49 + * 根据来料检验单 ID 级联删除所有行
  50 + *
  51 + * @param iqcId 来料检验单 ID
  52 + */
  53 + void deleteByIqcId(Long iqcId);
  54 +
  55 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcLineServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.service.qc.lqc;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.line.MesQcIqcLinePageReqVO;
  5 +import cn.iocoder.yudao.module.mes.dal.dataobject.qc.lqc.MesQcIqcLineDO;
  6 +import cn.iocoder.yudao.module.mes.dal.dataobject.qc.template.MesQcTemplateIndicatorDO;
  7 +import cn.iocoder.yudao.module.mes.dal.mysql.qc.lqc.MesQcIqcLineMapper;
  8 +import cn.iocoder.yudao.module.mes.dal.mysql.qc.template.MesQcTemplateIndicatorMapper;
  9 +import jakarta.annotation.Resource;
  10 +import org.springframework.stereotype.Service;
  11 +import org.springframework.validation.annotation.Validated;
  12 +
  13 +import java.util.List;
  14 +
  15 +/**
  16 + * MES 来料检验单行 Service 实现类
  17 + *
  18 + * @author 芋道源码
  19 + */
  20 +@Service
  21 +@Validated
  22 +public class MesQcIqcLineServiceImpl implements MesQcIqcLineService {
  23 +
  24 + @Resource
  25 + private MesQcIqcLineMapper iqcLineMapper;
  26 + @Resource
  27 + private MesQcTemplateIndicatorMapper templateIndicatorMapper;
  28 +
  29 + @Override
  30 + public MesQcIqcLineDO getIqcLine(Long id) {
  31 + return iqcLineMapper.selectById(id);
  32 + }
  33 +
  34 + @Override
  35 + public PageResult<MesQcIqcLineDO> getIqcLinePage(MesQcIqcLinePageReqVO pageReqVO) {
  36 + return iqcLineMapper.selectPage(pageReqVO);
  37 + }
  38 +
  39 + @Override
  40 + public List<MesQcIqcLineDO> selectListByIqcId(Long iqcId) {
  41 + return iqcLineMapper.selectListByIqcId(iqcId);
  42 + }
  43 +
  44 + @Override
  45 + public void createLinesFromTemplate(Long iqcId, Long templateId) {
  46 + List<MesQcTemplateIndicatorDO> indicators = templateIndicatorMapper.selectListByTemplateId(templateId);
  47 + // TODO @AI:convertList;
  48 + for (MesQcTemplateIndicatorDO indicator : indicators) {
  49 + // TODO @AI:链式设置;
  50 + MesQcIqcLineDO line = new MesQcIqcLineDO();
  51 + line.setIqcId(iqcId);
  52 + line.setIndicatorId(indicator.getIndicatorId());
  53 + line.setToolId(null); // TODO @芋艿:模板指标暂无 toolId,后续可扩展
  54 + line.setCheckMethod(indicator.getCheckMethod());
  55 + line.setStandardValue(indicator.getStandardValue());
  56 + line.setUnitMeasureId(indicator.getUnitMeasureId());
  57 + line.setMaxThreshold(indicator.getThresholdMax());
  58 + line.setMinThreshold(indicator.getThresholdMin());
  59 + line.setCriticalQuantity(0);
  60 + line.setMajorQuantity(0);
  61 + line.setMinorQuantity(0);
  62 + // TODO @AI:insertBatch;
  63 + iqcLineMapper.insert(line);
  64 + }
  65 + }
  66 +
  67 + @Override
  68 + public void deleteByIqcId(Long iqcId) {
  69 + iqcLineMapper.deleteByIqcId(iqcId);
  70 + }
  71 +
  72 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcService.java
1 1 package cn.iocoder.yudao.module.mes.service.qc.lqc;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4   -import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.*;
5   -import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.defect.MesQcIqcDefectPageReqVO;
6   -import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.defect.MesQcIqcDefectSaveReqVO;
7   -import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.line.MesQcIqcLinePageReqVO;
  4 +import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.MesQcIqcPageReqVO;
  5 +import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.MesQcIqcSaveReqVO;
8 6 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.lqc.MesQcIqcDO;
9   -import cn.iocoder.yudao.module.mes.dal.dataobject.qc.lqc.MesQcIqcDefectDO;
10   -import cn.iocoder.yudao.module.mes.dal.dataobject.qc.lqc.MesQcIqcLineDO;
11 7 import jakarta.validation.Valid;
12 8  
13   -// TODO @AI:和别的模块一样,拆分成多个 service
14 9 /**
15 10 * MES 来料检验单(IQC) Service 接口
16 11 *
... ... @@ -18,8 +13,6 @@ import jakarta.validation.Valid;
18 13 */
19 14 public interface MesQcIqcService {
20 15  
21   - // ========== 来料检验主表 ==========
22   -
23 16 /**
24 17 * 创建来料检验单
25 18 *
... ... @@ -65,54 +58,4 @@ public interface MesQcIqcService {
65 58 */
66 59 PageResult<MesQcIqcDO> getIqcPage(MesQcIqcPageReqVO pageReqVO);
67 60  
68   - // ========== 来料检验行(只读) ==========
69   -
70   - /**
71   - * 获得来料检验行
72   - *
73   - * @param id 编号
74   - * @return 来料检验行
75   - */
76   - MesQcIqcLineDO getIqcLine(Long id);
77   -
78   - /**
79   - * 获得来料检验行分页
80   - *
81   - * @param pageReqVO 分页查询
82   - * @return 来料检验行分页
83   - */
84   - PageResult<MesQcIqcLineDO> getIqcLinePage(MesQcIqcLinePageReqVO pageReqVO);
85   -
86   - // ========== 来料检验缺陷记录 ==========
87   -
88   - /**
89   - * 创建来料检验缺陷记录
90   - *
91   - * @param createReqVO 创建信息
92   - * @return 编号
93   - */
94   - Long createIqcDefect(@Valid MesQcIqcDefectSaveReqVO createReqVO);
95   -
96   - /**
97   - * 更新来料检验缺陷记录
98   - *
99   - * @param updateReqVO 更新信息
100   - */
101   - void updateIqcDefect(@Valid MesQcIqcDefectSaveReqVO updateReqVO);
102   -
103   - /**
104   - * 删除来料检验缺陷记录
105   - *
106   - * @param id 编号
107   - */
108   - void deleteIqcDefect(Long id);
109   -
110   - /**
111   - * 获得来料检验缺陷记录分页
112   - *
113   - * @param pageReqVO 分页查询
114   - * @return 来料检验缺陷记录分页
115   - */
116   - PageResult<MesQcIqcDefectDO> getIqcDefectPage(MesQcIqcDefectPageReqVO pageReqVO);
117   -
118 61 }
... ...
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;
3 3 import cn.hutool.core.util.ObjUtil;
4 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
6   -import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.*;
7   -import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.defect.MesQcIqcDefectPageReqVO;
8   -import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.defect.MesQcIqcDefectSaveReqVO;
9   -import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.line.MesQcIqcLinePageReqVO;
  6 +import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.MesQcIqcPageReqVO;
  7 +import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.MesQcIqcSaveReqVO;
10 8 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.lqc.MesQcIqcDO;
11   -import cn.iocoder.yudao.module.mes.dal.dataobject.qc.lqc.MesQcIqcDefectDO;
12   -import cn.iocoder.yudao.module.mes.dal.dataobject.qc.lqc.MesQcIqcLineDO;
13 9 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.template.MesQcTemplateDO;
14   -import cn.iocoder.yudao.module.mes.dal.dataobject.qc.template.MesQcTemplateIndicatorDO;
15 10 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.template.MesQcTemplateItemDO;
16   -import cn.iocoder.yudao.module.mes.dal.mysql.qc.lqc.MesQcIqcDefectMapper;
17   -import cn.iocoder.yudao.module.mes.dal.mysql.qc.lqc.MesQcIqcLineMapper;
18 11 import cn.iocoder.yudao.module.mes.dal.mysql.qc.lqc.MesQcIqcMapper;
19   -import cn.iocoder.yudao.module.mes.dal.mysql.qc.template.MesQcTemplateIndicatorMapper;
20 12 import cn.iocoder.yudao.module.mes.dal.mysql.qc.template.MesQcTemplateItemMapper;
21 13 import cn.iocoder.yudao.module.mes.dal.mysql.qc.template.MesQcTemplateMapper;
  14 +import cn.iocoder.yudao.module.mes.enums.qc.MesQcIqcStatusEnum;
  15 +import cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum;
22 16 import jakarta.annotation.Resource;
23 17 import org.springframework.stereotype.Service;
24 18 import org.springframework.transaction.annotation.Transactional;
25 19 import org.springframework.validation.annotation.Validated;
26 20  
27   -import java.math.BigDecimal;
28   -import java.math.RoundingMode;
29   -import java.util.List;
30 21 import java.util.Objects;
31 22  
32 23 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
33 24 import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
34 25  
35   -// TODO @AI:和别的模块一样,拆分成多个 service
36 26 /**
37 27 * MES 来料检验单(IQC) Service 实现类
38 28 *
... ... @@ -42,41 +32,34 @@ import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
42 32 @Validated
43 33 public class MesQcIqcServiceImpl implements MesQcIqcService {
44 34  
45   - // TODO @AI:搞个枚举类;
46   - /**
47   - * IQC 检测种类值(对应 mes_qc_type 字典 value=1)
48   - */
49   - private static final int QC_TYPE_IQC = 1;
50   -
51 35 @Resource
52 36 private MesQcIqcMapper iqcMapper;
53 37 @Resource
54   - private MesQcIqcLineMapper iqcLineMapper;
55   - @Resource
56   - private MesQcIqcDefectMapper iqcDefectMapper;
57   - @Resource
58 38 private MesQcTemplateMapper templateMapper;
59 39 @Resource
60   - private MesQcTemplateIndicatorMapper templateIndicatorMapper;
61   - @Resource
62 40 private MesQcTemplateItemMapper templateItemMapper;
63 41  
64   - // ========== 来料检验主表 ==========
  42 + @Resource
  43 + private MesQcIqcLineService iqcLineService;
  44 + @Resource
  45 + private MesQcIqcDefectService iqcDefectService;
65 46  
66 47 @Override
67 48 @Transactional(rollbackFor = Exception.class)
68 49 public Long createIqc(MesQcIqcSaveReqVO createReqVO) {
69   - // 1. 校验编号唯一
  50 + // 1.1 校验编号唯一
70 51 validateIqcCodeUnique(null, createReqVO.getCode());
71   -
72   - // 2. 查找物料关联的 IQC 检测模板
  52 + // 1.2 查找物料关联的 IQC 检测模板
73 53 Long templateId = createReqVO.getTemplateId();
  54 + // TODO @AI:直接使用 templateService 的 validateTemplateExists() 方法,后续如果有更多模板相关的校验,也可以放在该方法中
74 55 MesQcTemplateDO template = templateMapper.selectById(templateId);
75   - if (template == null || template.getTypes() == null || !template.getTypes().contains(QC_TYPE_IQC)) {
  56 + // TODO @AI:CollUtil.contains 这样更合适;
  57 + if (template == null || template.getTypes() == null || !template.getTypes().contains(MesQcTypeEnum.IQC.getType())) {
76 58 throw exception(QC_IQC_NO_TEMPLATE);
77 59 }
78 60  
79   - // 3. 从模板的产品关联中获取检测参数(min_check_quantity、max_unqualified_quantity)
  61 + // 3.1 从模板的产品关联中获取检测参数(min_check_quantity、max_unqualified_quantity)
  62 + // TODO @AI:使用 templateItemService 方法,不要直接使用对方的 mapper;
80 63 MesQcTemplateItemDO templateItem = templateItemMapper.selectByTemplateIdAndItemId(
81 64 templateId, createReqVO.getItemId());
82 65 if (templateItem != null) {
... ... @@ -87,57 +70,43 @@ public class MesQcIqcServiceImpl implements MesQcIqcService {
87 70 createReqVO.setMaxUnqualifiedQuantity(templateItem.getQuantityUnqualified());
88 71 }
89 72 }
90   -
91   - // 4. 插入主表
  73 + // 3.2 插入主表
92 74 MesQcIqcDO iqc = BeanUtils.toBean(createReqVO, MesQcIqcDO.class);
93   - iqc.setStatus(0); // 草稿
  75 + iqc.setStatus(MesQcIqcStatusEnum.PREPARE.getType());
94 76 iqcMapper.insert(iqc);
95 77  
96   - // 5. 从模板指标自动生成检验行
97   - List<MesQcTemplateIndicatorDO> indicators = templateIndicatorMapper.selectListByTemplateId(templateId);
98   - for (MesQcTemplateIndicatorDO indicator : indicators) {
99   - MesQcIqcLineDO line = new MesQcIqcLineDO();
100   - line.setIqcId(iqc.getId());
101   - line.setIndicatorId(indicator.getIndicatorId());
102   - line.setToolId(null); // TODO @芋艿:模板指标暂无 toolId,后续可扩展
103   - line.setCheckMethod(indicator.getCheckMethod());
104   - line.setStandardValue(indicator.getStandardValue());
105   - line.setUnitMeasureId(indicator.getUnitMeasureId());
106   - line.setMaxThreshold(indicator.getThresholdMax());
107   - line.setMinThreshold(indicator.getThresholdMin());
108   - line.setCriticalQuantity(0);
109   - line.setMajorQuantity(0);
110   - line.setMinorQuantity(0);
111   - iqcLineMapper.insert(line);
112   - }
113   -
  78 + // 4. 从模板指标自动生成检验行
  79 + iqcLineService.createLinesFromTemplate(iqc.getId(), templateId);
114 80 return iqc.getId();
115 81 }
116 82  
117 83 @Override
118 84 public void updateIqc(MesQcIqcSaveReqVO updateReqVO) {
119   - // 1. 校验存在
  85 + // 1.1 校验存在
120 86 MesQcIqcDO iqc = validateIqcExists(updateReqVO.getId());
121   - // 2. 校验状态为草稿
122   - if (!Objects.equals(iqc.getStatus(), 0)) {
  87 + // 1.2 校验状态为草稿
  88 + // TODO @AI:notEquals;
  89 + // TODO @AI:抽成一个方法,这样 completeIqc 和 deleteIqc 也可以复用,避免重复代码;
  90 + if (!Objects.equals(iqc.getStatus(), MesQcIqcStatusEnum.PREPARE.getType())) {
123 91 throw exception(QC_IQC_ONLY_PREPARE_CAN_COMPLETE);
124 92 }
125   - // 3. 校验编号唯一
  93 + // 1.3 校验编号唯一
126 94 validateIqcCodeUnique(updateReqVO.getId(), updateReqVO.getCode());
127   - // 4. 更新
  95 +
  96 + // 2. 更新
128 97 MesQcIqcDO updateObj = BeanUtils.toBean(updateReqVO, MesQcIqcDO.class);
129 98 iqcMapper.updateById(updateObj);
130 99 }
131 100  
132 101 @Override
133 102 public void completeIqc(Long id) {
134   - // 1. 校验存在
  103 + // 1.1 校验存在
135 104 MesQcIqcDO iqc = validateIqcExists(id);
136   - // 2. 校验状态为草稿
137   - if (!Objects.equals(iqc.getStatus(), 0)) {
  105 + // 1.2 校验状态为草稿
  106 + if (!Objects.equals(iqc.getStatus(), MesQcIqcStatusEnum.PREPARE.getType())) {
138 107 throw exception(QC_IQC_ONLY_PREPARE_CAN_COMPLETE);
139 108 }
140   - // 3. 校验合格品 + 不合格品 = 检测数量
  109 + // 1.3 校验合格品 + 不合格品 = 检测数量
141 110 if (iqc.getCheckQuantity() != null && iqc.getCheckQuantity() > 0) {
142 111 int total = (iqc.getQualifiedQuantity() != null ? iqc.getQualifiedQuantity() : 0)
143 112 + (iqc.getUnqualifiedQuantity() != null ? iqc.getUnqualifiedQuantity() : 0);
... ... @@ -145,29 +114,31 @@ public class MesQcIqcServiceImpl implements MesQcIqcService {
145 114 throw exception(QC_IQC_QUANTITY_MISMATCH);
146 115 }
147 116 }
148   - // 4. 更新状态为已完成
149   - MesQcIqcDO updateObj = new MesQcIqcDO();
150   - updateObj.setId(id);
151   - updateObj.setStatus(1);
  117 +
  118 + // 2. 更新状态为已完成
  119 + MesQcIqcDO updateObj = new MesQcIqcDO()
  120 + .setId(id).setStatus(MesQcIqcStatusEnum.FINISHED.getType());
152 121 iqcMapper.updateById(updateObj);
  122 +
153 123 // TODO @芋艿:WM 模块迁移后,更新到货通知单行/外协入库单行的检验结果
154 124 }
155 125  
156 126 @Override
157 127 @Transactional(rollbackFor = Exception.class)
158 128 public void deleteIqc(Long id) {
159   - // 1. 校验存在
  129 + // 1.1 校验存在
160 130 MesQcIqcDO iqc = validateIqcExists(id);
161   - // 2. 仅草稿可删
162   - if (!Objects.equals(iqc.getStatus(), 0)) {
  131 + // 1.2 仅草稿可删
  132 + if (!Objects.equals(iqc.getStatus(), MesQcIqcStatusEnum.PREPARE.getType())) {
163 133 throw exception(QC_IQC_ONLY_PREPARE_CAN_DELETE);
164 134 }
165   - // 3. 删除主表
  135 +
  136 + // 2.1 删除主表
166 137 iqcMapper.deleteById(id);
167   - // 4. 级联删除行
168   - iqcLineMapper.deleteByIqcId(id);
169   - // 5. 级联删除缺陷记录
170   - iqcDefectMapper.deleteByIqcId(id);
  138 + // 2.2 级联删除行
  139 + iqcLineService.deleteByIqcId(id);
  140 + // 2.3 级联删除缺陷记录
  141 + iqcDefectService.deleteByIqcId(id);
171 142 }
172 143  
173 144 private MesQcIqcDO validateIqcExists(Long id) {
... ... @@ -198,146 +169,4 @@ public class MesQcIqcServiceImpl implements MesQcIqcService {
198 169 return iqcMapper.selectPage(pageReqVO);
199 170 }
200 171  
201   - // ========== 来料检验行(只读) ==========
202   -
203   - @Override
204   - public MesQcIqcLineDO getIqcLine(Long id) {
205   - return iqcLineMapper.selectById(id);
206   - }
207   -
208   - @Override
209   - public PageResult<MesQcIqcLineDO> getIqcLinePage(MesQcIqcLinePageReqVO pageReqVO) {
210   - return iqcLineMapper.selectPage(pageReqVO);
211   - }
212   -
213   - // ========== 来料检验缺陷记录 ==========
214   -
215   - @Override
216   - @Transactional(rollbackFor = Exception.class)
217   - public Long createIqcDefect(MesQcIqcDefectSaveReqVO createReqVO) {
218   - // 1. 校验 IQC 存在
219   - validateIqcExists(createReqVO.getIqcId());
220   - // 2. 校验行存在
221   - validateIqcLineExists(createReqVO.getLineId());
222   - // 3. 插入
223   - MesQcIqcDefectDO defect = BeanUtils.toBean(createReqVO, MesQcIqcDefectDO.class);
224   - iqcDefectMapper.insert(defect);
225   - // 4. 重新计算缺陷统计
226   - recalculateDefectStats(createReqVO.getIqcId());
227   - return defect.getId();
228   - }
229   -
230   - @Override
231   - @Transactional(rollbackFor = Exception.class)
232   - public void updateIqcDefect(MesQcIqcDefectSaveReqVO updateReqVO) {
233   - // 1. 校验存在
234   - validateIqcDefectExists(updateReqVO.getId());
235   - // 2. 更新
236   - MesQcIqcDefectDO updateObj = BeanUtils.toBean(updateReqVO, MesQcIqcDefectDO.class);
237   - iqcDefectMapper.updateById(updateObj);
238   - // 3. 重新计算缺陷统计
239   - recalculateDefectStats(updateReqVO.getIqcId());
240   - }
241   -
242   - @Override
243   - @Transactional(rollbackFor = Exception.class)
244   - public void deleteIqcDefect(Long id) {
245   - // 1. 校验存在
246   - MesQcIqcDefectDO defect = validateIqcDefectExists(id);
247   - // 2. 删除
248   - iqcDefectMapper.deleteById(id);
249   - // 3. 重新计算缺陷统计
250   - recalculateDefectStats(defect.getIqcId());
251   - }
252   -
253   - private void validateIqcLineExists(Long id) {
254   - if (iqcLineMapper.selectById(id) == null) {
255   - throw exception(QC_IQC_LINE_NOT_EXISTS);
256   - }
257   - }
258   -
259   - private MesQcIqcDefectDO validateIqcDefectExists(Long id) {
260   - MesQcIqcDefectDO defect = iqcDefectMapper.selectById(id);
261   - if (defect == null) {
262   - throw exception(QC_IQC_DEFECT_NOT_EXISTS);
263   - }
264   - return defect;
265   - }
266   -
267   - @Override
268   - public PageResult<MesQcIqcDefectDO> getIqcDefectPage(MesQcIqcDefectPageReqVO pageReqVO) {
269   - return iqcDefectMapper.selectPage(pageReqVO);
270   - }
271   -
272   - // ========== 内部方法 ==========
273   -
274   - /**
275   - * 重新计算缺陷统计(行级 + 主表级)
276   - *
277   - * @param iqcId 来料检验单 ID
278   - */
279   - private void recalculateDefectStats(Long iqcId) {
280   - // 1. 查询所有缺陷记录
281   - List<MesQcIqcDefectDO> defects = iqcDefectMapper.selectListByIqcId(iqcId);
282   -
283   - // 2. 更新每行的缺陷数量
284   - List<MesQcIqcLineDO> lines = iqcLineMapper.selectListByIqcId(iqcId);
285   - for (MesQcIqcLineDO line : lines) {
286   - int critical = 0, major = 0, minor = 0;
287   - for (MesQcIqcDefectDO defect : defects) {
288   - if (Objects.equals(defect.getLineId(), line.getId())) {
289   - int qty = defect.getDefectQuantity() != null ? defect.getDefectQuantity() : 1;
290   - switch (defect.getDefectLevel()) {
291   - case "CRITICAL": critical += qty; break;
292   - case "MAJOR": major += qty; break;
293   - case "MINOR": minor += qty; break;
294   - }
295   - }
296   - }
297   - MesQcIqcLineDO updateLine = new MesQcIqcLineDO();
298   - updateLine.setId(line.getId());
299   - updateLine.setCriticalQuantity(critical);
300   - updateLine.setMajorQuantity(major);
301   - updateLine.setMinorQuantity(minor);
302   - iqcLineMapper.updateById(updateLine);
303   - }
304   -
305   - // 3. 汇总主表的缺陷数量
306   - int totalCritical = 0, totalMajor = 0, totalMinor = 0;
307   - for (MesQcIqcDefectDO defect : defects) {
308   - int qty = defect.getDefectQuantity() != null ? defect.getDefectQuantity() : 1;
309   - switch (defect.getDefectLevel()) {
310   - case "CRITICAL": totalCritical += qty; break;
311   - case "MAJOR": totalMajor += qty; break;
312   - case "MINOR": totalMinor += qty; break;
313   - }
314   - }
315   -
316   - // 4. 计算缺陷率
317   - MesQcIqcDO iqc = iqcMapper.selectById(iqcId);
318   - BigDecimal criticalRate = BigDecimal.ZERO;
319   - BigDecimal majorRate = BigDecimal.ZERO;
320   - BigDecimal minorRate = BigDecimal.ZERO;
321   - if (iqc != null && iqc.getCheckQuantity() != null && iqc.getCheckQuantity() > 0) {
322   - BigDecimal checkQty = BigDecimal.valueOf(iqc.getCheckQuantity());
323   - criticalRate = BigDecimal.valueOf(totalCritical).multiply(BigDecimal.valueOf(100))
324   - .divide(checkQty, 2, RoundingMode.HALF_UP);
325   - majorRate = BigDecimal.valueOf(totalMajor).multiply(BigDecimal.valueOf(100))
326   - .divide(checkQty, 2, RoundingMode.HALF_UP);
327   - minorRate = BigDecimal.valueOf(totalMinor).multiply(BigDecimal.valueOf(100))
328   - .divide(checkQty, 2, RoundingMode.HALF_UP);
329   - }
330   -
331   - // 5. 更新主表
332   - MesQcIqcDO updateIqc = new MesQcIqcDO();
333   - updateIqc.setId(iqcId);
334   - updateIqc.setCriticalQuantity(totalCritical);
335   - updateIqc.setMajorQuantity(totalMajor);
336   - updateIqc.setMinorQuantity(totalMinor);
337   - updateIqc.setCriticalRate(criticalRate);
338   - updateIqc.setMajorRate(majorRate);
339   - updateIqc.setMinorRate(minorRate);
340   - iqcMapper.updateById(updateIqc);
341   - }
342   -
343 172 }
... ...