From 3495965b99dfcbf191eefb8294a8de05bedc160a Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期五, 04 九月 2026 13:40:34 +0800
Subject: [PATCH] feat(mes): 新增批量查询方法并优化IPQC/IQC导出功能

---
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ipqc/MesQcIpqcController.java |  189 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 187 insertions(+), 2 deletions(-)

diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ipqc/MesQcIpqcController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ipqc/MesQcIpqcController.java
index 3e1c52b..1113942 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ipqc/MesQcIpqcController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ipqc/MesQcIpqcController.java
@@ -1,26 +1,38 @@
 package cn.iocoder.yudao.module.mes.controller.admin.qc.ipqc;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageParam;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.framework.dict.core.DictFrameworkUtils;
 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.ipqc.vo.MesQcIpqcPageReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.ipqc.vo.MesQcIpqcRespVO;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.ipqc.vo.MesQcIpqcSaveReqVO;
+import cn.iocoder.yudao.module.mes.controller.admin.qc.vo.MesQcQualityExportVO;
 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.md.workstation.MesMdWorkstationDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.pro.process.MesProProcessDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicator.MesQcIndicatorDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicatorresult.MesQcIndicatorResultDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicatorresult.MesQcIndicatorResultDetailDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.ipqc.MesQcIpqcDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.qc.ipqc.MesQcIpqcLineDO;
+import cn.iocoder.yudao.module.mes.dal.mysql.qc.ipqc.MesQcIpqcLineMapper;
+import cn.iocoder.yudao.module.mes.enums.DictTypeConstants;
+import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants;
 import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
 import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
 import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationService;
 import cn.iocoder.yudao.module.mes.service.pro.process.MesProProcessService;
 import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService;
+import cn.iocoder.yudao.module.mes.service.qc.indicator.MesQcIndicatorService;
+import cn.iocoder.yudao.module.mes.service.qc.indicatorresult.MesQcIndicatorResultService;
 import cn.iocoder.yudao.module.mes.service.qc.ipqc.MesQcIpqcService;
 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
@@ -35,9 +47,14 @@
 import org.springframework.web.bind.annotation.*;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
 
 import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -62,6 +79,12 @@
     private MesMdItemService itemService;
     @Resource
     private MesMdUnitMeasureService unitMeasureService;
+    @Resource
+    private MesQcIndicatorResultService indicatorResultService;
+    @Resource
+    private MesQcIndicatorService indicatorService;
+    @Resource
+    private MesQcIpqcLineMapper ipqcLineMapper;
 
     @Resource
     private AdminUserApi adminUserApi;
@@ -124,8 +147,8 @@
                                 HttpServletResponse response) throws IOException {
         pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
         List<MesQcIpqcDO> list = ipqcService.getIpqcPage(pageReqVO).getList();
-        List<MesQcIpqcRespVO> voList = buildIpqcRespVOList(list);
-        ExcelUtils.write(response, "杩囩▼妫�楠屽崟.xls", "鏁版嵁", MesQcIpqcRespVO.class, voList);
+        List<MesQcQualityExportVO> exportList = buildIpqcQualityExportList(list);
+        ExcelUtils.write(response, "杩囩▼妫�楠屽崟.xls", "鏁版嵁", MesQcQualityExportVO.class, exportList);
     }
 
     // ==================== 鎷兼帴 VO ====================
@@ -152,6 +175,8 @@
         // 鎵归噺鏌ヨ妫�娴嬩汉鍛�
         Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
                 convertSet(list, MesQcIpqcDO::getInspectorUserId));
+        // 鎵归噺鏌ヨ妫�楠岄」鎸囨爣
+        Map<Long, String> indicatorSummaryMap = buildIndicatorSummaryMap(list);
         // 鎷艰 VO
         return BeanUtils.toBean(list, MesQcIpqcRespVO.class, vo -> {
             findAndThen(workOrderMap, vo.getWorkOrderId(), workOrder -> vo
@@ -167,7 +192,167 @@
             });
             findAndThen(userMap, vo.getInspectorUserId(),
                     user -> vo.setInspectorNickname(user.getNickname()));
+            vo.setIndicatorResultSummary(indicatorSummaryMap.getOrDefault(vo.getId(), ""));
         });
     }
 
+    /**
+     * 鏋勫缓姣忎釜妫�楠屽崟鐨勬楠岄」鎸囨爣姹囨�诲瓧绗︿覆锛坬cType = IPQC锛�
+     */
+    private Map<Long, String> buildIndicatorSummaryMap(List<MesQcIpqcDO> list) {
+        Map<Long, String> indicatorSummaryMap = new HashMap<>();
+        Set<Long> qcIds = convertSet(list, MesQcIpqcDO::getId);
+        if (CollUtil.isEmpty(qcIds)) {
+            return indicatorSummaryMap;
+        }
+        // 鎸� QC ID 鎵归噺鏌ヨ妫�楠岀粨鏋�
+        List<MesQcIndicatorResultDO> indicatorResults = indicatorResultService.getIndicatorResultListByQcIdsAndType(
+                new ArrayList<>(qcIds), MesBizTypeConstants.QC_IPQC);
+        if (CollUtil.isEmpty(indicatorResults)) {
+            return indicatorSummaryMap;
+        }
+        // 鎸� QC ID 鍒嗙粍缁撴灉
+        Map<Long, List<MesQcIndicatorResultDO>> resultMap = indicatorResults.stream()
+                .collect(Collectors.groupingBy(MesQcIndicatorResultDO::getQcId));
+        // 鎵归噺鏌ヨ妫�楠岀粨鏋滄槑缁�
+        Set<Long> resultIds = convertSet(indicatorResults, MesQcIndicatorResultDO::getId);
+        List<MesQcIndicatorResultDetailDO> indicatorDetails = indicatorResultService.getIndicatorResultDetailListByResultIds(
+                new ArrayList<>(resultIds));
+        // 鎸夌粨鏋� ID 鍒嗙粍鏄庣粏
+        Map<Long, List<MesQcIndicatorResultDetailDO>> detailMapByResultId = indicatorDetails.stream()
+                .collect(Collectors.groupingBy(MesQcIndicatorResultDetailDO::getResultId));
+        // 鎵归噺鏌ヨ妫�娴嬫寚鏍�
+        Set<Long> indicatorIds = convertSet(indicatorDetails, MesQcIndicatorResultDetailDO::getIndicatorId);
+        Map<Long, MesQcIndicatorDO> indicatorMap = indicatorService.getIndicatorMap(indicatorIds);
+
+        // 鏋勫缓姣忎釜 QC 鐨勬寚鏍囨眹鎬诲瓧绗︿覆
+        resultMap.forEach((qcId, results) -> {
+            List<String> indicatorSummaries = new ArrayList<>();
+            for (MesQcIndicatorResultDO result : results) {
+                List<MesQcIndicatorResultDetailDO> details = detailMapByResultId.getOrDefault(result.getId(), Collections.emptyList());
+                for (MesQcIndicatorResultDetailDO detail : details) {
+                    // 閫氳繃 indicatorId 鍏宠仈鎸囨爣鍚嶇О锛屾煡涓嶅埌鍒欏洖閫�涓� "鎸囨爣"
+                    String indicatorName = "鎸囨爣";
+                    MesQcIndicatorDO indicator = indicatorMap.get(detail.getIndicatorId());
+                    if (indicator != null && StrUtil.isNotBlank(indicator.getName())) {
+                        indicatorName = indicator.getName();
+                    }
+                    String value = detail.getValue();
+                    String remark = detail.getRemark();
+                    // 鏍煎紡鍖栦负 "鎸囨爣鍚嶇О:鍊�" 鎴� "鎸囨爣鍚嶇О:鍊�(澶囨敞)"
+                    String indicatorStr = indicatorName + ":" + value;
+                    if (StrUtil.isNotBlank(remark)) {
+                        indicatorStr += "(" + remark + ")";
+                    }
+                    indicatorSummaries.add(indicatorStr);
+                }
+            }
+            indicatorSummaryMap.put(qcId, String.join(", ", indicatorSummaries));
+        });
+        return indicatorSummaryMap;
+    }
+
+    /**
+     * 鏋勫缓瀵煎嚭琛岋細涓�鍗曚竴琛岋紝妫�楠屾寚鏍� / 鍒ゅ畾渚濇嵁鍙栬嚜琛屾槑缁嗗苟鎷兼帴
+     */
+    private List<MesQcQualityExportVO> buildIpqcQualityExportList(List<MesQcIpqcDO> list) {
+        if (CollUtil.isEmpty(list)) {
+            return Collections.emptyList();
+        }
+        // 鎵归噺鏌ヨ妫�娴嬩汉鍛�
+        Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
+                convertSet(list, MesQcIpqcDO::getInspectorUserId));
+        // 鎵归噺鏌ヨ鐗╂枡
+        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
+                convertSet(list, MesQcIpqcDO::getItemId));
+        // 鎵归噺鏌ヨ琛屾槑缁�
+        List<MesQcIpqcLineDO> lines = ipqcLineMapper.selectListByIpqcIds(convertSet(list, MesQcIpqcDO::getId));
+        Map<Long, List<MesQcIpqcLineDO>> lineMap = lines.stream()
+                .collect(Collectors.groupingBy(MesQcIpqcLineDO::getIpqcId));
+        // 鎵归噺鏌ヨ妫�娴嬫寚鏍�
+        Map<Long, MesQcIndicatorDO> indicatorMap = CollUtil.isEmpty(lines) ? Collections.emptyMap()
+                : indicatorService.getIndicatorMap(convertSet(lines, MesQcIpqcLineDO::getIndicatorId));
+        // 鎵归噺鏌ヨ瀹炴祴鍊硷細妫�楠屽崟 ID -> {鎸囨爣 ID -> 瀹炴祴鍊紏
+        Map<Long, Map<Long, String>> measureMap = buildMeasureValueMap(
+                convertSet(list, MesQcIpqcDO::getId), MesBizTypeConstants.QC_IPQC);
+        // 缁勮瀵煎嚭琛�
+        List<MesQcQualityExportVO> exportList = new ArrayList<>(list.size());
+        for (MesQcIpqcDO ipqc : list) {
+            MesQcQualityExportVO vo = new MesQcQualityExportVO();
+            vo.setDocName(ipqc.getName());
+            MesMdItemDO item = itemMap.get(ipqc.getItemId());
+            vo.setItemName(item != null ? item.getName() : "");
+            // IPQC 鏃犳壒娆″彿瀛楁锛屾殏鐢ㄦ潵婧愬崟鎹紪鍙凤紙涓�鑸负鐢熶骇宸ュ崟鍙凤級浣滀负鎵瑰彿
+            vo.setBatchNo(ipqc.getSourceDocCode());
+            vo.setInspectDate(MesQcQualityExportVO.formatDateTime(ipqc.getInspectDate()));
+            List<String> indicatorNames = new ArrayList<>();
+            List<String> judgementSegments = new ArrayList<>();
+            for (MesQcIpqcLineDO line : lineMap.getOrDefault(ipqc.getId(), Collections.emptyList())) {
+                MesQcIndicatorDO indicator = indicatorMap.get(line.getIndicatorId());
+                String name = indicator != null && StrUtil.isNotBlank(indicator.getName())
+                        ? indicator.getName() : "";
+                String range = MesQcQualityExportVO.buildRangeText(
+                        line.getStandardValue(), line.getMinThreshold(), line.getMaxThreshold());
+                if (StrUtil.isNotBlank(name)) {
+                    String measuredValue = measureMap
+                            .getOrDefault(ipqc.getId(), Collections.emptyMap())
+                            .get(line.getIndicatorId());
+                    indicatorNames.add(StrUtil.isNotBlank(measuredValue) ? name + ":" + measuredValue : name);
+                    if (StrUtil.isNotBlank(range)) {
+                        judgementSegments.add(name + range);
+                    }
+                }
+            }
+            vo.setIndicatorNames(String.join("銆�", indicatorNames));
+            vo.setJudgementBasis(String.join("锛�", judgementSegments));
+            vo.setCheckResultText(getCheckResultLabel(ipqc.getCheckResult()));
+            findAndThen(userMap, ipqc.getInspectorUserId(),
+                    user -> vo.setInspectorName(user.getNickname()));
+            // 鏆傛棤瀹℃牳浜烘暟鎹潵婧愶紝瀵煎嚭绌哄垪
+            vo.setAuditorName("");
+            vo.setRemark(ipqc.getRemark());
+            exportList.add(vo);
+        }
+        return exportList;
+    }
+
+    /**
+     * 鏋勫缓 妫�楠屽崟 ID -> {鎸囨爣 ID -> 瀹炴祴鍊紏 鏄犲皠锛屽疄娴嬪�煎彇鑷楠岀粨鏋滄槑缁嗚〃
+     */
+    private Map<Long, Map<Long, String>> buildMeasureValueMap(Set<Long> qcIds, int qcType) {
+        Map<Long, Map<Long, String>> measureMap = new HashMap<>();
+        if (CollUtil.isEmpty(qcIds)) {
+            return measureMap;
+        }
+        List<MesQcIndicatorResultDO> results = indicatorResultService.getIndicatorResultListByQcIdsAndType(
+                new ArrayList<>(qcIds), qcType);
+        if (CollUtil.isEmpty(results)) {
+            return measureMap;
+        }
+        Map<Long, Long> resultQcMap = results.stream()
+                .collect(Collectors.toMap(MesQcIndicatorResultDO::getId, MesQcIndicatorResultDO::getQcId));
+        List<MesQcIndicatorResultDetailDO> details = indicatorResultService.getIndicatorResultDetailListByResultIds(
+                new ArrayList<>(resultQcMap.keySet()));
+        if (CollUtil.isEmpty(details)) {
+            return measureMap;
+        }
+        for (MesQcIndicatorResultDetailDO detail : details) {
+            Long qcId = resultQcMap.get(detail.getResultId());
+            if (qcId == null) {
+                continue;
+            }
+            measureMap.computeIfAbsent(qcId, k -> new HashMap<>())
+                    .put(detail.getIndicatorId(), detail.getValue());
+        }
+        return measureMap;
+    }
+
+    private String getCheckResultLabel(Integer checkResult) {
+        if (checkResult == null) {
+            return "";
+        }
+        return DictFrameworkUtils.parseDictDataLabel(
+                DictTypeConstants.MES_QC_CHECK_RESULT, String.valueOf(checkResult));
+    }
+
 }

--
Gitblit v1.9.3