diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicator/vo/MesQcIndicatorPageReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicator/vo/MesQcIndicatorPageReqVO.java index 7163000..773814e 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicator/vo/MesQcIndicatorPageReqVO.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicator/vo/MesQcIndicatorPageReqVO.java @@ -21,7 +21,7 @@ public class MesQcIndicatorPageReqVO extends PageParam { @Schema(description = "检测项类型", example = "SIZE") private String type; - @Schema(description = "结果值类型", example = "FLOAT") - private String resultType; + @Schema(description = "结果值类型", example = "1") + private Integer resultType; } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicator/vo/MesQcIndicatorRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicator/vo/MesQcIndicatorRespVO.java index e2d7a76..eda78af 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicator/vo/MesQcIndicatorRespVO.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicator/vo/MesQcIndicatorRespVO.java @@ -36,14 +36,14 @@ public class MesQcIndicatorRespVO { @ExcelProperty("检测工具") private String tool; - @Schema(description = "结果值类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "FLOAT") + @Schema(description = "结果值类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") @ExcelProperty(value = "结果值类型", converter = DictConvert.class) @DictFormat(DictTypeConstants.MES_QC_RESULT_TYPE) - private String resultType; + private Integer resultType; @Schema(description = "结果值属性", example = "IMG") @ExcelProperty("结果值属性") - private String resultSpec; + private String resultSpecification; @Schema(description = "备注", example = "备注") @ExcelProperty("备注") diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicator/vo/MesQcIndicatorSaveReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicator/vo/MesQcIndicatorSaveReqVO.java index 778d083..7a04faf 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicator/vo/MesQcIndicatorSaveReqVO.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicator/vo/MesQcIndicatorSaveReqVO.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.mes.controller.admin.qc.indicator.vo; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; import lombok.Data; @Schema(description = "管理后台 - MES 质检指标新增/修改 Request VO") @@ -26,12 +27,12 @@ public class MesQcIndicatorSaveReqVO { @Schema(description = "检测工具", example = "卡尺") private String tool; - @Schema(description = "结果值类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "FLOAT") - @NotEmpty(message = "结果值类型不能为空") - private String resultType; + @Schema(description = "结果值类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "结果值类型不能为空") + private Integer resultType; @Schema(description = "结果值属性", example = "IMG") - private String resultSpec; + private String resultSpecification; @Schema(description = "备注", example = "备注") private String remark; diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicatorresult/MesQcResultController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicatorresult/MesQcResultController.java new file mode 100644 index 0000000..a0d9e0f --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicatorresult/MesQcResultController.java @@ -0,0 +1,146 @@ +package cn.iocoder.yudao.module.mes.controller.admin.qc.indicatorresult; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +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.indicatorresult.vo.*; +import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.qc.lqc.MesQcIqcDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicatorresult.MesQcResultDO; +import cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum; +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.qc.lqc.MesQcIqcService; +import cn.iocoder.yudao.module.mes.service.qc.indicatorresult.MesQcResultService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; +import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen; + +@Tag(name = "管理后台 - MES 检验结果") +@RestController +@RequestMapping("/mes/qc/result") +@Validated +public class MesQcResultController { + + @Resource + private MesQcResultService resultService; + @Resource + private MesQcIqcService iqcService; + @Resource + private MesMdItemService itemService; + @Resource + private MesMdUnitMeasureService unitMeasureService; + + @PostMapping("/create") + @Operation(summary = "创建检验结果") + @PreAuthorize("@ss.hasPermission('mes:qc-iqc:create')") + public CommonResult createResult(@Valid @RequestBody MesQcResultSaveReqVO createReqVO) { + return success(resultService.createResult(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新检验结果") + @PreAuthorize("@ss.hasPermission('mes:qc-iqc:update')") + public CommonResult updateResult(@Valid @RequestBody MesQcResultSaveReqVO updateReqVO) { + resultService.updateResult(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除检验结果") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('mes:qc-iqc:delete')") + public CommonResult deleteResult(@RequestParam("id") Long id) { + resultService.deleteResult(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得检验结果(含明细)") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('mes:qc-iqc:query')") + public CommonResult getResult(@RequestParam("id") Long id) { + MesQcResultDO result = resultService.getResult(id); + if (result == null) { + return success(null); + } + // 构建 RespVO(含关联字段 + 明细列表) + MesQcResultRespVO respVO = buildResultRespVOList(Collections.singletonList(result)).get(0); + // 组装明细 + // TODO @AI:先查询下;然后在 buildResultRespVOList 统一 build; + respVO.setItems(resultService.getResultDetailList(result.getId(), result.getQcId(), result.getQcType())); + return success(respVO); + } + + @GetMapping("/page") + @Operation(summary = "获得检验结果分页") + @PreAuthorize("@ss.hasPermission('mes:qc-iqc:query')") + public CommonResult> getResultPage(@Valid MesQcResultPageReqVO pageReqVO) { + PageResult pageResult = resultService.getResultPage(pageReqVO); + return success(new PageResult<>(buildResultRespVOList(pageResult.getList()), pageResult.getTotal())); + } + + // TODO @AI:resultService.getDetailTemplate(qcId, qcType) 放在 controller 里弄啊; + @GetMapping("/detail-template") + @Operation(summary = "获取空值检测项模板") + @Parameters({ + @Parameter(name = "qcId", description = "质检单ID", required = true, example = "1"), + @Parameter(name = "qcType", description = "质检类型", required = true, example = "1") + }) + @PreAuthorize("@ss.hasPermission('mes:qc-iqc:query')") + public CommonResult> getDetailTemplate( + @RequestParam("qcId") Long qcId, + @RequestParam("qcType") Integer qcType) { + return success(resultService.getDetailTemplate(qcId, qcType)); + } + + // ==================== 拼接 VO ==================== + + private List buildResultRespVOList(List list) { + if (CollUtil.isEmpty(list)) { + return Collections.emptyList(); + } + // 批量查询物料 + Map itemMap = itemService.getItemMap( + convertSet(list, MesQcResultDO::getItemId)); + // 批量查询计量单位 + Map unitMeasureMap = unitMeasureService.getUnitMeasureMap( + convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId)); + // 拼装 VO + return BeanUtils.toBean(list, MesQcResultRespVO.class, vo -> { + // 拼接物料信息 + findAndThen(itemMap, vo.getItemId(), item -> { + vo.setItemCode(item.getCode()).setItemName(item.getName()).setItemSpecification(item.getSpecification()); + findAndThen(unitMeasureMap, item.getUnitMeasureId(), + unit -> vo.setUnitName(unit.getName())); + }); + // 拼接质检单编号/名称(根据 qcType 从对应服务获取) + if (Objects.equals(vo.getQcType(), MesQcTypeEnum.IQC.getType())) { + // TODO @AI:findAndThen 方式优化; + MesQcIqcDO iqc = iqcService.getIqc(vo.getQcId()); + if (iqc != null) { + vo.setQcCode(iqc.getCode()).setQcName(iqc.getName()); + } + } + // TODO @芋艿:IPQC/OQC/RQC 模块迁移后实现 + }); + } + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicatorresult/vo/MesQcResultDetailRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicatorresult/vo/MesQcResultDetailRespVO.java new file mode 100644 index 0000000..165f997 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicatorresult/vo/MesQcResultDetailRespVO.java @@ -0,0 +1,80 @@ +package cn.iocoder.yudao.module.mes.controller.admin.qc.indicatorresult.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + +@Schema(description = "管理后台 - MES 检验结果明细 Response VO") +@Data +public class MesQcResultDetailRespVO { + + @Schema(description = "编号", example = "1024") + private Long id; + + @Schema(description = "关联检验结果ID", example = "1") + private Long resultId; + + @Schema(description = "检测指标ID", example = "1") + private Long indicatorId; + + @Schema(description = "检测工具ID", example = "1") + private Long toolId; + + @Schema(description = "计量单位ID", example = "1") + private Long unitMeasureId; + + @Schema(description = "质检值类型(1=浮点 2=整数 3=文本 4=字典 5=文件)", example = "1") + private Integer valueType; + + @Schema(description = "值属性", example = "IMG") + private String valueSpecification; + + @Schema(description = "浮点值", example = "3.14") + private BigDecimal valueFloat; + + @Schema(description = "整数值", example = "100") + private Integer valueInteger; + + @Schema(description = "文字值", example = "合格") + private String valueText; + + @Schema(description = "字典项值", example = "PASS") + private String valueDict; + + @Schema(description = "文件值", example = "https://xxx.com/file.jpg") + private String valueFile; + + @Schema(description = "备注", example = "无") + private String remark; + + // ========== 关联查询字段(来自 IQC line + indicator) ========== + + @Schema(description = "检测指标编码(关联查询)", example = "IDX-001") + private String indicatorCode; + + @Schema(description = "检测指标名称(关联查询)", example = "外观检查") + private String indicatorName; + + @Schema(description = "检测指标类型(关联查询)", example = "QUANTITATIVE") + private String indicatorType; + + @Schema(description = "检测工具名称(关联查询)", example = "卡尺") + private String toolName; + + @Schema(description = "检测方法(关联查询)", example = "目视检查") + private String checkMethod; + + @Schema(description = "标准值(关联查询)", example = "10.0000") + private BigDecimal standardValue; + + @Schema(description = "计量单位名称(关联查询)", example = "mm") + private String unitMeasureName; + + @Schema(description = "误差上限(关联查询)", example = "10.5000") + private BigDecimal maxThreshold; + + @Schema(description = "误差下限(关联查询)", example = "9.5000") + private BigDecimal minThreshold; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicatorresult/vo/MesQcResultDetailSaveReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicatorresult/vo/MesQcResultDetailSaveReqVO.java new file mode 100644 index 0000000..7ee2f7f --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicatorresult/vo/MesQcResultDetailSaveReqVO.java @@ -0,0 +1,48 @@ +package cn.iocoder.yudao.module.mes.controller.admin.qc.indicatorresult.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + +@Schema(description = "管理后台 - MES 检验结果明细创建/更新 Request VO") +@Data +public class MesQcResultDetailSaveReqVO { + + @Schema(description = "编号", example = "1024") + private Long id; + + @Schema(description = "检测指标ID", example = "1") + private Long indicatorId; + + @Schema(description = "检测工具ID", example = "1") + private Long toolId; + + @Schema(description = "计量单位ID", example = "1") + private Long unitMeasureId; + + @Schema(description = "质检值类型(1=浮点 2=整数 3=文本 4=字典 5=文件)", example = "1") + private Integer valueType; + + @Schema(description = "值属性", example = "IMG") + private String valueSpecification; + + @Schema(description = "浮点值", example = "3.14") + private BigDecimal valueFloat; + + @Schema(description = "整数值", example = "100") + private Integer valueInteger; + + @Schema(description = "文字值", example = "合格") + private String valueText; + + @Schema(description = "字典项值", example = "PASS") + private String valueDict; + + @Schema(description = "文件值", example = "https://xxx.com/file.jpg") + private String valueFile; + + @Schema(description = "备注", example = "无") + private String remark; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicatorresult/vo/MesQcResultPageReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicatorresult/vo/MesQcResultPageReqVO.java new file mode 100644 index 0000000..2a4c199 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicatorresult/vo/MesQcResultPageReqVO.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.module.mes.controller.admin.qc.indicatorresult.vo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.validation.InEnum; +import cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Schema(description = "管理后台 - MES 检验结果分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class MesQcResultPageReqVO extends PageParam { + + @Schema(description = "关联质检单ID", example = "1") + private Long qcId; + + @Schema(description = "质检类型", example = "1") + @InEnum(MesQcTypeEnum.class) + private Integer qcType; + + @Schema(description = "样品编号", example = "SPL-001") + private String code; + + @Schema(description = "产品物料ID", example = "1") + private Long itemId; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicatorresult/vo/MesQcResultRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicatorresult/vo/MesQcResultRespVO.java new file mode 100644 index 0000000..8cb7b54 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicatorresult/vo/MesQcResultRespVO.java @@ -0,0 +1,63 @@ +package cn.iocoder.yudao.module.mes.controller.admin.qc.indicatorresult.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.List; + +@Schema(description = "管理后台 - MES 检验结果 Response VO") +@Data +public class MesQcResultRespVO { + + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + private Long id; + + @Schema(description = "样品编号", example = "SPL-001") + private String code; + + @Schema(description = "关联质检单ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Long qcId; + + @Schema(description = "质检类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Integer qcType; + + @Schema(description = "产品物料ID", example = "1") + private Long itemId; + + @Schema(description = "物资SN", example = "SN-001") + private String sn; + + @Schema(description = "备注", example = "无") + private String remark; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + private LocalDateTime createTime; + + // ========== 关联查询字段 ========== + + @Schema(description = "质检单编号(关联查询)", example = "IQC-001") + private String qcCode; + + @Schema(description = "质检单名称(关联查询)", example = "xxx来料检验") + private String qcName; + + @Schema(description = "产品物料编码(关联查询)", example = "ITEM-001") + private String itemCode; + + @Schema(description = "产品物料名称(关联查询)", example = "电阻") + private String itemName; + + @Schema(description = "规格型号(关联查询)", example = "100Ω") + private String itemSpecification; + + @Schema(description = "单位名称(关联查询)", example = "个") + private String unitName; + + // ========== 子表:检验结果明细 ========== + + // TODO @AI:内嵌进来,不用队里类文件; + @Schema(description = "检验结果明细列表") + private List items; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicatorresult/vo/MesQcResultSaveReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicatorresult/vo/MesQcResultSaveReqVO.java new file mode 100644 index 0000000..1da6edc --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicatorresult/vo/MesQcResultSaveReqVO.java @@ -0,0 +1,37 @@ +package cn.iocoder.yudao.module.mes.controller.admin.qc.indicatorresult.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +import java.util.List; + +@Schema(description = "管理后台 - MES 检验结果创建/更新 Request VO") +@Data +public class MesQcResultSaveReqVO { + + @Schema(description = "编号", example = "1024") + private Long id; + + @Schema(description = "样品编号", example = "SPL-001") + private String code; + + @Schema(description = "关联质检单ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "关联质检单ID不能为空") + private Long qcId; + + @Schema(description = "质检类型(1=IQC 2=IPQC 3=OQC 4=RQC)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "质检类型不能为空") + private Integer qcType; + + @Schema(description = "物资SN", example = "SN-001") + private String sn; + + @Schema(description = "备注", example = "无") + private String remark; + + // TODO @AI:MesQcResultDetailSaveReqVO 内嵌进来;不用独立类; + @Schema(description = "检验结果明细列表") + private List items; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/indicator/MesQcIndicatorDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/indicator/MesQcIndicatorDO.java index ab7f13e..84f85f7 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/indicator/MesQcIndicatorDO.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/indicator/MesQcIndicatorDO.java @@ -47,15 +47,16 @@ public class MesQcIndicatorDO extends BaseDO { /** * 结果值类型 * - * 枚举 {@link cn.iocoder.yudao.module.mes.enums.DictTypeConstants#MES_QC_RESULT_TYPE} + * 枚举 {@link cn.iocoder.yudao.module.mes.enums.qc.MesQcResultValueTypeEnum} */ - private String resultType; + private Integer resultType; /** * 结果值属性 * - * FILE 时存 IMG/FILE;DICT 时存字典类型名 + * 1. FILE 时:存 IMG/FILE + * 2. DICT 时:存字典类型名 */ - private String resultSpec; + private String resultSpecification; /** * 备注 */ diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/indicatorresult/MesQcResultDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/indicatorresult/MesQcResultDO.java new file mode 100644 index 0000000..37cd96c --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/indicatorresult/MesQcResultDO.java @@ -0,0 +1,80 @@ +package cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicatorresult; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; +import cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +/** + * MES 检验结果记录 DO + * + * @author 芋道源码 + */ +@TableName("mes_qc_result") +@KeySequence("mes_qc_result_seq") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class MesQcResultDO extends BaseDO { + + /** + * 编号 + */ + @TableId + private Long id; + /** + * 样品编号 + */ + private String code; + // TODO @AI:关联下 linkter; + /** + * 关联质检单 ID(IQC/IPQC/OQC/RQC 的 id) + */ + private Long qcId; + /** + * 质检类型 + * + * 枚举 {@link MesQcTypeEnum} + */ + private Integer qcType; + /** + * 产品物料 ID + * + * 关联 {@link MesMdItemDO#getId()} + */ + private Long itemId; + /** + * 物资 SN + */ + private String sn; + /** + * 备注 + */ + private String remark; + + // ========== 预留字段 ========== + + /** + * 预留字段 1 + */ + private String attribute1; + /** + * 预留字段 2 + */ + private String attribute2; + /** + * 预留字段 3 + */ + private Integer attribute3; + /** + * 预留字段 4 + */ + private Integer attribute4; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/indicatorresult/MesQcResultDetailDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/indicatorresult/MesQcResultDetailDO.java new file mode 100644 index 0000000..1c6e12e --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/indicatorresult/MesQcResultDetailDO.java @@ -0,0 +1,117 @@ +package cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicatorresult; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO; +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.enums.qc.MesQcResultValueTypeEnum; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +import java.math.BigDecimal; + +/** + * MES 检验结果明细记录 DO + * + * @author 芋道源码 + */ +@TableName("mes_qc_result_detail") +@KeySequence("mes_qc_result_detail_seq") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class MesQcResultDetailDO extends BaseDO { + + /** + * 编号 + */ + @TableId + private Long id; + /** + * 关联检验结果 ID + * + * 关联 {@link MesQcResultDO#getId()} + */ + private Long resultId; + /** + * 检测指标 ID + * + * 关联 {@link MesQcIndicatorDO#getId()} + */ + private Long indicatorId; + // TODO @AI:toolId、unitMeasureId、valueType、valueSpecification 都不存储; + /** + * 检测工具 ID + * + * 关联 {@link MesTmToolDO#getId()} + */ + private Long toolId; + /** + * 计量单位 ID + * + * 关联 {@link MesMdUnitMeasureDO#getId()} + */ + private Long unitMeasureId; + /** + * 质检值类型 + * + * 枚举 {@link MesQcResultValueTypeEnum} + */ + private Integer valueType; + /** + * 值属性 + * + * FILE 时存 IMG/FILE;DICT 时存字典类型名 + */ + private String valueSpecification; + // TODO @AI:是不是可以调整成 String value? + /** + * 浮点值 + */ + private BigDecimal valueFloat; + /** + * 整数值 + */ + private Integer valueInteger; + /** + * 文字值 + */ + private String valueText; + /** + * 字典项值 + */ + private String valueDict; + /** + * 文件值 + */ + private String valueFile; + /** + * 备注 + */ + private String remark; + + // ========== 预留字段 ========== + + /** + * 预留字段 1 + */ + private String attribute1; + /** + * 预留字段 2 + */ + private String attribute2; + /** + * 预留字段 3 + */ + private Integer attribute3; + /** + * 预留字段 4 + */ + private Integer attribute4; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/qc/indicatorresult/MesQcResultDetailMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/qc/indicatorresult/MesQcResultDetailMapper.java new file mode 100644 index 0000000..612ab81 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/qc/indicatorresult/MesQcResultDetailMapper.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.mes.dal.mysql.qc.indicatorresult; + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicatorresult.MesQcResultDetailDO; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * MES 检验结果明细记录 Mapper + * + * @author 芋道源码 + */ +@Mapper +public interface MesQcResultDetailMapper extends BaseMapperX { + + default List selectListByResultId(Long resultId) { + return selectList(MesQcResultDetailDO::getResultId, resultId); + } + + default void deleteByResultId(Long resultId) { + delete(new LambdaQueryWrapperX() + .eq(MesQcResultDetailDO::getResultId, resultId)); + } + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/qc/indicatorresult/MesQcResultMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/qc/indicatorresult/MesQcResultMapper.java new file mode 100644 index 0000000..f2973a4 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/qc/indicatorresult/MesQcResultMapper.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.mes.dal.mysql.qc.indicatorresult; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.mes.controller.admin.qc.indicatorresult.vo.MesQcResultPageReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicatorresult.MesQcResultDO; +import org.apache.ibatis.annotations.Mapper; + +/** + * MES 检验结果记录 Mapper + * + * @author 芋道源码 + */ +@Mapper +public interface MesQcResultMapper extends BaseMapperX { + + default PageResult selectPage(MesQcResultPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(MesQcResultDO::getQcId, reqVO.getQcId()) + .eqIfPresent(MesQcResultDO::getQcType, reqVO.getQcType()) + .likeIfPresent(MesQcResultDO::getCode, reqVO.getCode()) + .eqIfPresent(MesQcResultDO::getItemId, reqVO.getItemId()) + .orderByDesc(MesQcResultDO::getId)); + } + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/qc/template/MesQcTemplateItemMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/qc/template/MesQcTemplateItemMapper.java index c9c227a..2e3b676 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/qc/template/MesQcTemplateItemMapper.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/qc/template/MesQcTemplateItemMapper.java @@ -27,6 +27,10 @@ public interface MesQcTemplateItemMapper extends BaseMapperX selectListByItemId(Long itemId) { + return selectList(MesQcTemplateItemDO::getItemId, itemId); + } + default MesQcTemplateItemDO selectByTemplateIdAndItemId(Long templateId, Long itemId) { return selectOne(new LambdaQueryWrapperX() .eq(MesQcTemplateItemDO::getTemplateId, templateId) diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java index 8742f1c..b65585f 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java @@ -267,6 +267,12 @@ public interface ErrorCodeConstants { ErrorCode QC_DEFECT_RECORD_LEVEL_UNKNOWN = new ErrorCode(1_040_605_001, "未知的缺陷等级"); ErrorCode QC_DEFECT_RECORD_QC_TYPE_UNSUPPORTED = new ErrorCode(1_040_605_002, "不支持的检验类型"); + // ========== MES 质量管理-检验结果(1-040-606-000) ========== + ErrorCode QC_RESULT_NOT_EXISTS = new ErrorCode(1_040_606_000, "检验结果不存在"); + ErrorCode QC_RESULT_ITEMS_EMPTY = new ErrorCode(1_040_606_001, "检测项结果值不能为空"); + ErrorCode QC_RESULT_SOURCE_DOC_NOT_EXISTS = new ErrorCode(1_040_606_002, "来源质检单不存在"); + ErrorCode QC_RESULT_SOURCE_DOC_TYPE_INVALID = new ErrorCode(1_040_606_003, "来源质检单类型不支持"); + // ========== MES 仓库管理-仓库(1-040-700-000) ========== ErrorCode WM_WAREHOUSE_NOT_EXISTS = new ErrorCode(1_040_700_000, "仓库不存在"); ErrorCode WM_WAREHOUSE_CODE_DUPLICATE = new ErrorCode(1_040_700_001, "仓库编码已存在"); diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcResultValueTypeEnum.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcResultValueTypeEnum.java new file mode 100644 index 0000000..659a42d --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcResultValueTypeEnum.java @@ -0,0 +1,40 @@ +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 MesQcResultValueTypeEnum implements ArrayValuable { + + FLOAT(1, "浮点"), + INTEGER(2, "整数"), + TEXT(3, "文本"), + DICT(4, "字典"), + FILE(5, "文件"); + + public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesQcResultValueTypeEnum::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/indicatorresult/MesQcResultService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/indicatorresult/MesQcResultService.java new file mode 100644 index 0000000..946a2ed --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/indicatorresult/MesQcResultService.java @@ -0,0 +1,76 @@ +package cn.iocoder.yudao.module.mes.service.qc.indicatorresult; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.mes.controller.admin.qc.indicatorresult.vo.MesQcResultDetailRespVO; +import cn.iocoder.yudao.module.mes.controller.admin.qc.indicatorresult.vo.MesQcResultPageReqVO; +import cn.iocoder.yudao.module.mes.controller.admin.qc.indicatorresult.vo.MesQcResultSaveReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicatorresult.MesQcResultDO; +import jakarta.validation.Valid; + +import java.util.List; + +/** + * MES 检验结果 Service 接口 + * + * @author 芋道源码 + */ +public interface MesQcResultService { + + /** + * 创建检验结果(含明细) + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createResult(@Valid MesQcResultSaveReqVO createReqVO); + + /** + * 更新检验结果(含明细) + * + * @param updateReqVO 更新信息 + */ + void updateResult(@Valid MesQcResultSaveReqVO updateReqVO); + + /** + * 删除检验结果(级联删除明细) + * + * @param id 编号 + */ + void deleteResult(Long id); + + /** + * 获得检验结果 + * + * @param id 编号 + * @return 检验结果 + */ + MesQcResultDO getResult(Long id); + + /** + * 获得检验结果分页 + * + * @param pageReqVO 分页查询 + * @return 检验结果分页 + */ + PageResult getResultPage(MesQcResultPageReqVO pageReqVO); + + /** + * 获取检验结果明细列表(含已填值,组装 IQC line + indicator 信息) + * + * @param resultId 检验结果 ID + * @param qcId 质检单 ID + * @param qcType 质检类型 + * @return 明细列表 + */ + List getResultDetailList(Long resultId, Long qcId, Integer qcType); + + /** + * 获取空值检测项模板(新建结果时用) + * + * @param qcId 质检单 ID + * @param qcType 质检类型 + * @return 空值明细列表 + */ + List getDetailTemplate(Long qcId, Integer qcType); + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/indicatorresult/MesQcResultServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/indicatorresult/MesQcResultServiceImpl.java new file mode 100644 index 0000000..082afcd --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/indicatorresult/MesQcResultServiceImpl.java @@ -0,0 +1,252 @@ +package cn.iocoder.yudao.module.mes.service.qc.indicatorresult; + +import cn.hutool.core.collection.CollUtil; +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.indicatorresult.vo.MesQcResultDetailRespVO; +import cn.iocoder.yudao.module.mes.controller.admin.qc.indicatorresult.vo.MesQcResultDetailSaveReqVO; +import cn.iocoder.yudao.module.mes.controller.admin.qc.indicatorresult.vo.MesQcResultPageReqVO; +import cn.iocoder.yudao.module.mes.controller.admin.qc.indicatorresult.vo.MesQcResultSaveReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicator.MesQcIndicatorDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.qc.lqc.MesQcIqcDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.qc.lqc.MesQcIqcLineDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicatorresult.MesQcResultDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicatorresult.MesQcResultDetailDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.tm.tool.MesTmToolDO; +import cn.iocoder.yudao.module.mes.dal.mysql.qc.lqc.MesQcIqcLineMapper; +import cn.iocoder.yudao.module.mes.dal.mysql.qc.indicatorresult.MesQcResultDetailMapper; +import cn.iocoder.yudao.module.mes.dal.mysql.qc.indicatorresult.MesQcResultMapper; +import cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum; +import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService; +import cn.iocoder.yudao.module.mes.service.qc.indicator.MesQcIndicatorService; +import cn.iocoder.yudao.module.mes.service.qc.lqc.MesQcIqcService; +import cn.iocoder.yudao.module.mes.service.tm.tool.MesTmToolService; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; + +import java.util.*; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; +import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen; +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; + +/** + * MES 检验结果 Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Validated +public class MesQcResultServiceImpl implements MesQcResultService { + + @Resource + private MesQcResultMapper resultMapper; + @Resource + private MesQcResultDetailMapper resultDetailMapper; + + @Resource + private MesQcIqcService iqcService; + @Resource + private MesQcIqcLineMapper iqcLineMapper; + @Resource + private MesQcIndicatorService indicatorService; + @Resource + private MesMdUnitMeasureService unitMeasureService; + @Resource + private MesTmToolService toolService; + + @Override + @Transactional(rollbackFor = Exception.class) + public Long createResult(MesQcResultSaveReqVO createReqVO) { + // 1. 校验明细不为空 + List items = createReqVO.getItems(); + if (CollUtil.isEmpty(items)) { + throw exception(QC_RESULT_ITEMS_EMPTY); + } + + // 2. 根据 qcType 查询源质检单,获取 itemId + Long itemId = getItemIdFromQcDoc(createReqVO.getQcId(), createReqVO.getQcType()); + + // 3. 插入主表 + MesQcResultDO result = BeanUtils.toBean(createReqVO, MesQcResultDO.class); + result.setItemId(itemId); + resultMapper.insert(result); + + // 4. 批量插入明细 + List details = BeanUtils.toBean(items, MesQcResultDetailDO.class); + details.forEach(detail -> detail.setResultId(result.getId())); + resultDetailMapper.insertBatch(details); + return result.getId(); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateResult(MesQcResultSaveReqVO updateReqVO) { + // 1. 校验存在 + validateResultExists(updateReqVO.getId()); + + // 2. 校验明细不为空 + List items = updateReqVO.getItems(); + if (CollUtil.isEmpty(items)) { + throw exception(QC_RESULT_ITEMS_EMPTY); + } + + // 3. 更新主表 + MesQcResultDO updateObj = BeanUtils.toBean(updateReqVO, MesQcResultDO.class); + resultMapper.updateById(updateObj); + + // 4. 更新明细:先删后插 + resultDetailMapper.deleteByResultId(updateReqVO.getId()); + List details = BeanUtils.toBean(items, MesQcResultDetailDO.class); + details.forEach(detail -> detail.setResultId(updateReqVO.getId())); + resultDetailMapper.insertBatch(details); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteResult(Long id) { + // 1. 校验存在 + validateResultExists(id); + // 2. 级联删除明细 + resultDetailMapper.deleteByResultId(id); + // 3. 删除主表 + resultMapper.deleteById(id); + } + + @Override + public MesQcResultDO getResult(Long id) { + return resultMapper.selectById(id); + } + + @Override + public PageResult getResultPage(MesQcResultPageReqVO pageReqVO) { + return resultMapper.selectPage(pageReqVO); + } + + @Override + public List getResultDetailList(Long resultId, Long qcId, Integer qcType) { + return buildDetailRespVOList(resultId, qcId, qcType); + } + + @Override + public List getDetailTemplate(Long qcId, Integer qcType) { + return buildDetailRespVOList(null, qcId, qcType); + } + + // ==================== 私有方法 ==================== + + private MesQcResultDO validateResultExists(Long id) { + MesQcResultDO result = resultMapper.selectById(id); + if (result == null) { + throw exception(QC_RESULT_NOT_EXISTS); + } + return result; + } + + /** + * 根据 qcType 查询源质检单,获取 itemId + */ + private Long getItemIdFromQcDoc(Long qcId, Integer qcType) { + if (Objects.equals(qcType, MesQcTypeEnum.IQC.getType())) { + MesQcIqcDO iqc = iqcService.getIqc(qcId); + if (iqc == null) { + throw exception(QC_RESULT_SOURCE_DOC_NOT_EXISTS); + } + return iqc.getItemId(); + } + // TODO @芋艿:IPQC/OQC/RQC 模块迁移后实现 + throw exception(QC_RESULT_SOURCE_DOC_TYPE_INVALID); + } + + /** + * 组装明细 VO 列表:从 IQC line + indicator + tool + unitMeasure + 已有结果明细 三方组装 + * + * @param resultId 检验结果 ID,为 null 时表示获取空值模板 + * @param qcId 质检单 ID + * @param qcType 质检类型 + */ + private List buildDetailRespVOList(Long resultId, Long qcId, Integer qcType) { + // 1. 获取检验单行列表 + List lines; + if (Objects.equals(qcType, MesQcTypeEnum.IQC.getType())) { + lines = iqcLineMapper.selectListByIqcId(qcId); + } else { + // TODO @芋艿:IPQC/OQC/RQC 模块迁移后实现 + return Collections.emptyList(); + } + if (CollUtil.isEmpty(lines)) { + return Collections.emptyList(); + } + + // 2. 批量查询关联信息 + Map indicatorMap = indicatorService.getIndicatorMap( + convertSet(lines, MesQcIqcLineDO::getIndicatorId)); + Map unitMeasureMap = unitMeasureService.getUnitMeasureMap( + convertSet(lines, MesQcIqcLineDO::getUnitMeasureId)); + + // 3. 查询已有结果明细(如有 resultId) + Map detailMap; + if (resultId != null) { + List details = resultDetailMapper.selectListByResultId(resultId); + detailMap = convertMap(details, MesQcResultDetailDO::getIndicatorId); + } else { + detailMap = Collections.emptyMap(); + } + + // 4. 遍历行,组装 VO + List voList = new ArrayList<>(lines.size()); + for (MesQcIqcLineDO line : lines) { + MesQcResultDetailRespVO vo = new MesQcResultDetailRespVO(); + // 来自 IQC line + vo.setIndicatorId(line.getIndicatorId()); + vo.setToolId(line.getToolId()); + vo.setUnitMeasureId(line.getUnitMeasureId()); + vo.setCheckMethod(line.getCheckMethod()); + vo.setStandardValue(line.getStandardValue()); + vo.setMaxThreshold(line.getMaxThreshold()); + vo.setMinThreshold(line.getMinThreshold()); + + // 来自 indicator + findAndThen(indicatorMap, line.getIndicatorId(), indicator -> { + vo.setIndicatorCode(indicator.getCode()); + vo.setIndicatorName(indicator.getName()); + vo.setIndicatorType(indicator.getType()); + vo.setValueType(indicator.getResultType()); + vo.setValueSpecification(indicator.getResultSpecification()); + }); + + // 来自 unitMeasure + findAndThen(unitMeasureMap, line.getUnitMeasureId(), + unit -> vo.setUnitMeasureName(unit.getName())); + + // 来自 tool(逐个查询,数量通常较少) + if (line.getToolId() != null) { + MesTmToolDO tool = toolService.getTool(line.getToolId()); + if (tool != null) { + vo.setToolName(tool.getName()); + } + } + + // 来自已有结果明细(如有) + MesQcResultDetailDO detail = detailMap.get(line.getIndicatorId()); + if (detail != null) { + vo.setId(detail.getId()); + vo.setResultId(detail.getResultId()); + vo.setValueFloat(detail.getValueFloat()); + vo.setValueInteger(detail.getValueInteger()); + vo.setValueText(detail.getValueText()); + vo.setValueDict(detail.getValueDict()); + vo.setValueFile(detail.getValueFile()); + } + + voList.add(vo); + } + return voList; + } + +}