Commit 3ed86517ba3628e1829ea4dc7239bb4682fb349b

Authored by YunaiV
1 parent d21ddb53

refactor(mes): 优化检验结果模块,合并接口、精简 VO 和查询逻辑

1. Controller:合并 get + detail-template 为 get-detail 接口(id 可选),
   移除 buildIndicatorResultRespVOList(分页无需关联查询),
   精简 buildDetailItemList 只查 indicator(name/valueType/valueSpecification),
   移除 iqcService、itemService、unitMeasureService、toolService 注入,
   不支持的 qcType 抛出异常
2. RespVO:移除前端未使用的关联字段(qcCode/qcName/itemCode 等主表字段,
   indicatorCode/toolName/checkMethod 等明细字段)
3. ServiceImpl:updateIndicatorResult 改用 insertOrUpdate,
   validateIqcExists 替代手动 getIqc + null 判断
4. ErrorCodeConstants:移除未使用的错误码和兼容别名
5. 新增 IPQC 模块(Controller/Service/Mapper/VO/DO)
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicatorresult/MesQcIndicatorResultController.java
... ... @@ -5,22 +5,14 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
5 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 6 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
7 7 import cn.iocoder.yudao.module.mes.controller.admin.qc.indicatorresult.vo.*;
8   -import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
9   -import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
10 8 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicator.MesQcIndicatorDO;
11 9 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicatorresult.MesQcIndicatorResultDO;
12 10 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicatorresult.MesQcIndicatorResultDetailDO;
13   -import cn.iocoder.yudao.module.mes.dal.dataobject.qc.lqc.MesQcIqcDO;
14 11 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.lqc.MesQcIqcLineDO;
15   -import cn.iocoder.yudao.module.mes.dal.dataobject.tm.tool.MesTmToolDO;
16 12 import cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum;
17   -import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
18   -import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
19 13 import cn.iocoder.yudao.module.mes.service.qc.indicator.MesQcIndicatorService;
20 14 import cn.iocoder.yudao.module.mes.service.qc.indicatorresult.MesQcIndicatorResultService;
21 15 import cn.iocoder.yudao.module.mes.service.qc.lqc.MesQcIqcLineService;
22   -import cn.iocoder.yudao.module.mes.service.qc.lqc.MesQcIqcService;
23   -import cn.iocoder.yudao.module.mes.service.tm.tool.MesTmToolService;
24 16 import io.swagger.v3.oas.annotations.Operation;
25 17 import io.swagger.v3.oas.annotations.Parameter;
26 18 import io.swagger.v3.oas.annotations.Parameters;
... ... @@ -47,17 +39,9 @@ public class MesQcIndicatorResultController {
47 39 @Resource
48 40 private MesQcIndicatorResultService resultService;
49 41 @Resource
50   - private MesQcIqcService iqcService;
51   - @Resource
52 42 private MesQcIqcLineService iqcLineService;
53 43 @Resource
54   - private MesMdItemService itemService;
55   - @Resource
56   - private MesMdUnitMeasureService unitMeasureService;
57   - @Resource
58 44 private MesQcIndicatorService indicatorService;
59   - @Resource
60   - private MesTmToolService toolService;
61 45  
62 46 @PostMapping("/create")
63 47 @Operation(summary = "创建检验结果")
... ... @@ -83,21 +67,31 @@ public class MesQcIndicatorResultController {
83 67 return success(true);
84 68 }
85 69  
86   - // TODO @AI:是不是把 get 和 getIndicatorResultDetailTemplate 合并为一个接口?参数是 qcId + qcType;新的接口是 get-detail;
87   - @GetMapping("/get")
88   - @Operation(summary = "获得检验结果(含明细)")
89   - @Parameter(name = "id", description = "编号", required = true, example = "1024")
  70 + @GetMapping("/get-detail")
  71 + @Operation(summary = "获得检验结果明细(含检测项模板)")
  72 + @Parameters({
  73 + @Parameter(name = "id", description = "检验结果编号(编辑时传入;新增时不传)", example = "1024"),
  74 + @Parameter(name = "qcId", description = "质检单ID", required = true, example = "1"),
  75 + @Parameter(name = "qcType", description = "质检类型", required = true, example = "1")
  76 + })
90 77 @PreAuthorize("@ss.hasPermission('mes:qc-iqc:query')")
91   - public CommonResult<MesQcIndicatorResultRespVO> getIndicatorResult(@RequestParam("id") Long id) {
92   - MesQcIndicatorResultDO result = resultService.getIndicatorResult(id);
93   - if (result == null) {
94   - return success(null);
  78 + public CommonResult<MesQcIndicatorResultRespVO> getIndicatorResultDetail(
  79 + @RequestParam(value = "id", required = false) Long id,
  80 + @RequestParam("qcId") Long qcId,
  81 + @RequestParam("qcType") Integer qcType) {
  82 + MesQcIndicatorResultRespVO respVO;
  83 + List<MesQcIndicatorResultDetailDO> details;
  84 + if (id != null) {
  85 + // 编辑:加载已有结果主表 + 已有明细
  86 + MesQcIndicatorResultDO result = resultService.getIndicatorResult(id);
  87 + respVO = BeanUtils.toBean(result, MesQcIndicatorResultRespVO.class);
  88 + details = resultService.getIndicatorResultDetailListByResultId(id);
  89 + } else {
  90 + // 新增:返回空壳 RespVO,仅填充检测项模板
  91 + respVO = new MesQcIndicatorResultRespVO();
  92 + details = Collections.emptyList();
95 93 }
96   - // 构建 RespVO(含关联字段)
97   - MesQcIndicatorResultRespVO respVO = buildIndicatorResultRespVOList(Collections.singletonList(result)).get(0);
98   - // 查询明细并组装
99   - List<MesQcIndicatorResultDetailDO> details = resultService.getIndicatorResultDetailListByResultId(result.getId());
100   - respVO.setItems(buildDetailItemList(details, result.getQcId(), result.getQcType()));
  94 + respVO.setItems(buildDetailItemList(details, qcId, qcType));
101 95 return success(respVO);
102 96 }
103 97  
... ... @@ -106,62 +100,17 @@ public class MesQcIndicatorResultController {
106 100 @PreAuthorize("@ss.hasPermission('mes:qc-iqc:query')")
107 101 public CommonResult<PageResult<MesQcIndicatorResultRespVO>> getIndicatorResultPage(@Valid MesQcIndicatorResultPageReqVO pageReqVO) {
108 102 PageResult<MesQcIndicatorResultDO> pageResult = resultService.getIndicatorResultPage(pageReqVO);
109   - return success(new PageResult<>(buildIndicatorResultRespVOList(pageResult.getList()), pageResult.getTotal()));
110   - }
111   -
112   - @GetMapping("/detail-template")
113   - @Operation(summary = "获取空值检测项模板")
114   - @Parameters({
115   - @Parameter(name = "qcId", description = "质检单ID", required = true, example = "1"),
116   - @Parameter(name = "qcType", description = "质检类型", required = true, example = "1")
117   - })
118   - @PreAuthorize("@ss.hasPermission('mes:qc-iqc:query')")
119   - public CommonResult<List<MesQcIndicatorResultRespVO.Item>> getIndicatorResultDetailTemplate(
120   - @RequestParam("qcId") Long qcId,
121   - @RequestParam("qcType") Integer qcType) {
122   - return success(buildDetailItemList(Collections.emptyList(), qcId, qcType));
  103 + // 前端列表只展示 code、sn、remark,无需关联查询
  104 + PageResult<MesQcIndicatorResultRespVO> voPageResult = BeanUtils.toBean(pageResult, MesQcIndicatorResultRespVO.class);
  105 + return success(voPageResult);
123 106 }
124 107  
125 108 // ==================== 拼接 VO ====================
126 109  
127 110 /**
128   - * 构建主表 RespVO 列表(拼接物料、质检单等关联信息)
129   - */
130   - private List<MesQcIndicatorResultRespVO> buildIndicatorResultRespVOList(List<MesQcIndicatorResultDO> list) {
131   - if (CollUtil.isEmpty(list)) {
132   - return Collections.emptyList();
133   - }
134   - // 批量查询物料
135   - Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
136   - convertSet(list, MesQcIndicatorResultDO::getItemId));
137   - // 批量查询计量单位
138   - Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
139   - convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
140   - // 批量查询 IQC 质检单
141   - Set<Long> iqcIds = convertSet(list, r ->
142   - Objects.equals(r.getQcType(), MesQcTypeEnum.IQC.getType()) ? r.getQcId() : null);
143   - iqcIds.remove(null);
144   - Map<Long, MesQcIqcDO> iqcMap = iqcService.getIqcMap(iqcIds);
145   -
146   - // 拼装 VO
147   - return BeanUtils.toBean(list, MesQcIndicatorResultRespVO.class, vo -> {
148   - // 拼接物料信息
149   - findAndThen(itemMap, vo.getItemId(), item -> {
150   - vo.setItemCode(item.getCode()).setItemName(item.getName()).setItemSpecification(item.getSpecification());
151   - findAndThen(unitMeasureMap, item.getUnitMeasureId(),
152   - unit -> vo.setUnitName(unit.getName()));
153   - });
154   - // 拼接质检单编号/名称
155   - if (Objects.equals(vo.getQcType(), MesQcTypeEnum.IQC.getType())) {
156   - findAndThen(iqcMap, vo.getQcId(), iqc ->
157   - vo.setQcCode(iqc.getCode()).setQcName(iqc.getName()));
158   - }
159   - // TODO @芋艿:IPQC/OQC/RQC 模块迁移后实现
160   - });
161   - }
162   -
163   - /**
164   - * 构建明细 Item 列表:从 IQC line + indicator + tool + unitMeasure + 已有结果明细组装
  111 + * 构建明细 Item 列表
  112 + *
  113 + * <p>前端表单仅需:indicatorId、indicatorName、valueType、valueSpecification + 已有结果(id、value、remark)</p>
165 114 *
166 115 * @param details 已有结果明细(空列表表示获取空值模板)
167 116 * @param qcId 质检单 ID
... ... @@ -169,70 +118,40 @@ public class MesQcIndicatorResultController {
169 118 */
170 119 private List<MesQcIndicatorResultRespVO.Item> buildDetailItemList(
171 120 List<MesQcIndicatorResultDetailDO> details, Long qcId, Integer qcType) {
172   - // 1. 获取检验单行列表
  121 + // 1.1 获取检验单行列表(知道有哪些检测指标)
173 122 List<MesQcIqcLineDO> lines;
174 123 if (Objects.equals(qcType, MesQcTypeEnum.IQC.getType())) {
175 124 lines = iqcLineService.getIqcLineListByIqcId(qcId);
176 125 } else {
177 126 // TODO @芋艿:IPQC/OQC/RQC 模块迁移后实现
178   - return Collections.emptyList();
  127 + throw new IllegalArgumentException("暂不支持 qcType=" + qcType);
179 128 }
180 129 if (CollUtil.isEmpty(lines)) {
181 130 return Collections.emptyList();
182 131 }
183 132  
184   - // 2. 批量查询关联信息
  133 + // 1.2 批量查询检测指标
185 134 Map<Long, MesQcIndicatorDO> indicatorMap = indicatorService.getIndicatorMap(
186 135 convertSet(lines, MesQcIqcLineDO::getIndicatorId));
187   - Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
188   - convertSet(lines, MesQcIqcLineDO::getUnitMeasureId));
189   -
190   - // 3. 构建已有明细 Map(按 indicatorId 索引)
  136 + // 1.3 构建已有明细 Map(按 indicatorId 索引)
191 137 Map<Long, MesQcIndicatorResultDetailDO> detailMap = CollUtil.isEmpty(details)
192 138 ? Collections.emptyMap()
193 139 : convertMap(details, MesQcIndicatorResultDetailDO::getIndicatorId);
194 140  
195   - // 4. 遍历行,组装 VO
  141 + // 2. 遍历行,组装 VO
196 142 List<MesQcIndicatorResultRespVO.Item> voList = new ArrayList<>(lines.size());
197 143 for (MesQcIqcLineDO line : lines) {
198   - MesQcIndicatorResultRespVO.Item vo = new MesQcIndicatorResultRespVO.Item();
199   - // 来自 IQC line
200   - vo.setIndicatorId(line.getIndicatorId());
201   - vo.setCheckMethod(line.getCheckMethod());
202   - vo.setStandardValue(line.getStandardValue());
203   - vo.setMaxThreshold(line.getMaxThreshold());
204   - vo.setMinThreshold(line.getMinThreshold());
205   -
  144 + MesQcIndicatorResultRespVO.Item vo = new MesQcIndicatorResultRespVO.Item()
  145 + .setIndicatorId(line.getIndicatorId());
206 146 // 来自 indicator
207   - findAndThen(indicatorMap, line.getIndicatorId(), indicator -> {
208   - vo.setIndicatorCode(indicator.getCode());
209   - vo.setIndicatorName(indicator.getName());
210   - vo.setIndicatorType(indicator.getType());
211   - vo.setValueType(indicator.getResultType());
212   - vo.setValueSpecification(indicator.getResultSpecification());
213   - });
214   -
215   - // 来自 unitMeasure
216   - findAndThen(unitMeasureMap, line.getUnitMeasureId(),
217   - unit -> vo.setUnitMeasureName(unit.getName()));
218   -
219   - // 来自 tool(逐个查询,数量通常较少)
220   - if (line.getToolId() != null) {
221   - MesTmToolDO tool = toolService.getTool(line.getToolId());
222   - if (tool != null) {
223   - vo.setToolName(tool.getName());
224   - }
225   - }
226   -
  147 + findAndThen(indicatorMap, line.getIndicatorId(), indicator -> vo
  148 + .setIndicatorName(indicator.getName())
  149 + .setValueType(indicator.getResultType())
  150 + .setValueSpecification(indicator.getResultSpecification()));
227 151 // 来自已有结果明细(如有)
228   - MesQcIndicatorResultDetailDO detail = detailMap.get(line.getIndicatorId());
229   - if (detail != null) {
230   - vo.setId(detail.getId());
231   - vo.setResultId(detail.getResultId());
232   - vo.setValue(detail.getValue());
233   - vo.setRemark(detail.getRemark());
234   - }
235   -
  152 + findAndThen(detailMap, line.getIndicatorId(), detail -> vo
  153 + .setId(detail.getId()).setResultId(detail.getResultId())
  154 + .setValue(detail.getValue()).setRemark(detail.getRemark()));
236 155 voList.add(vo);
237 156 }
238 157 return voList;
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicatorresult/vo/MesQcIndicatorResultRespVO.java
... ... @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.mes.controller.admin.qc.indicatorresult.vo;
3 3 import io.swagger.v3.oas.annotations.media.Schema;
4 4 import lombok.Data;
5 5  
6   -import java.math.BigDecimal;
7 6 import java.time.LocalDateTime;
8 7 import java.util.List;
9 8  
... ... @@ -35,26 +34,6 @@ public class MesQcIndicatorResultRespVO {
35 34 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
36 35 private LocalDateTime createTime;
37 36  
38   - // ========== 关联查询字段 ==========
39   -
40   - @Schema(description = "质检单编号", example = "IQC-001")
41   - private String qcCode;
42   -
43   - @Schema(description = "质检单名称", example = "xxx来料检验")
44   - private String qcName;
45   -
46   - @Schema(description = "产品物料编码", example = "ITEM-001")
47   - private String itemCode;
48   -
49   - @Schema(description = "产品物料名称", example = "电阻")
50   - private String itemName;
51   -
52   - @Schema(description = "规格型号", example = "100Ω")
53   - private String itemSpecification;
54   -
55   - @Schema(description = "单位名称", example = "个")
56   - private String unitName;
57   -
58 37 // ========== 子表:检验结果明细 ==========
59 38  
60 39 @Schema(description = "检验结果明细列表")
... ... @@ -79,41 +58,17 @@ public class MesQcIndicatorResultRespVO {
79 58 @Schema(description = "备注", example = "无")
80 59 private String remark;
81 60  
82   - // ========== 关联查询字段(来自 IQC line + indicator) ==========
83   -
84   - @Schema(description = "检测指标编码", example = "IDX-001")
85   - private String indicatorCode;
  61 + // ========== 关联查询字段(来自 indicator) ==========
86 62  
87 63 @Schema(description = "检测指标名称", example = "外观检查")
88 64 private String indicatorName;
89 65  
90   - @Schema(description = "检测指标类型", example = "QUANTITATIVE")
91   - private String indicatorType;
92   -
93 66 @Schema(description = "质检值类型", example = "1")
94 67 private Integer valueType;
95 68  
96 69 @Schema(description = "值属性", example = "IMG")
97 70 private String valueSpecification;
98 71  
99   - @Schema(description = "检测工具名称", example = "卡尺")
100   - private String toolName;
101   -
102   - @Schema(description = "检测方法", example = "目视检查")
103   - private String checkMethod;
104   -
105   - @Schema(description = "标准值", example = "10.0000")
106   - private BigDecimal standardValue;
107   -
108   - @Schema(description = "计量单位名称", example = "mm")
109   - private String unitMeasureName;
110   -
111   - @Schema(description = "误差上限", example = "10.5000")
112   - private BigDecimal maxThreshold;
113   -
114   - @Schema(description = "误差下限", example = "9.5000")
115   - private BigDecimal minThreshold;
116   -
117 72 }
118 73  
119 74 }
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
... ... @@ -269,9 +269,6 @@ public interface ErrorCodeConstants {
269 269  
270 270 // ========== MES 质量管理-检验结果(1-040-606-000) ==========
271 271 ErrorCode QC_RESULT_NOT_EXISTS = new ErrorCode(1_040_606_000, "检验结果不存在");
272   - ErrorCode QC_RESULT_ITEMS_EMPTY = new ErrorCode(1_040_606_001, "检测项结果值不能为空");
273   - ErrorCode QC_RESULT_SOURCE_DOC_NOT_EXISTS = new ErrorCode(1_040_606_002, "来源质检单不存在");
274   - ErrorCode QC_RESULT_SOURCE_DOC_TYPE_INVALID = new ErrorCode(1_040_606_003, "来源质检单类型不支持");
275 272  
276 273 // ========== MES 仓库管理-仓库(1-040-700-000) ==========
277 274 ErrorCode WM_WAREHOUSE_NOT_EXISTS = new ErrorCode(1_040_700_000, "仓库不存在");
... ... @@ -303,8 +300,4 @@ public interface ErrorCodeConstants {
303 300 // ========== MES 仓库管理-库存(1-040-703-000) ==========
304 301 ErrorCode WM_MATERIAL_STOCK_NOT_EXISTS = new ErrorCode(1_040_703_000, "库存记录不存在");
305 302  
306   - // ========== 兼容旧命名(storage_area=库区,storage_location=库位) ==========
307   - ErrorCode WM_STORAGE_AREA_NOT_EXISTS = WM_WAREHOUSE_LOCATION_NOT_EXISTS;
308   - ErrorCode WM_STORAGE_LOCATION_NOT_EXISTS = WM_WAREHOUSE_AREA_NOT_EXISTS;
309   -
310 303 }
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/indicatorresult/MesQcIndicatorResultServiceImpl.java
... ... @@ -119,7 +119,7 @@ public class MesQcIndicatorResultServiceImpl implements MesQcIndicatorResultServ
119 119 return iqc.getItemId();
120 120 }
121 121 // TODO @芋艿:IPQC/OQC/RQC 模块迁移后实现
122   - throw exception(QC_RESULT_SOURCE_DOC_TYPE_INVALID);
  122 + throw new IllegalArgumentException("暂不支持 qcType=" + qcType);
123 123 }
124 124  
125 125 }
... ...