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/rqc/MesQcRqcController.java |  188 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 186 insertions(+), 2 deletions(-)

diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/rqc/MesQcRqcController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/rqc/MesQcRqcController.java
index 56f5c35..8ddc929 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/rqc/MesQcRqcController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/rqc/MesQcRqcController.java
@@ -1,20 +1,32 @@
 package cn.iocoder.yudao.module.mes.controller.admin.qc.rqc;
 
 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.rqc.vo.MesQcRqcPageReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.rqc.vo.MesQcRqcRespVO;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.rqc.vo.MesQcRqcSaveReqVO;
+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.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.rqc.MesQcRqcDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.qc.rqc.MesQcRqcLineDO;
+import cn.iocoder.yudao.module.mes.dal.mysql.qc.rqc.MesQcRqcLineMapper;
+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.qc.indicator.MesQcIndicatorService;
+import cn.iocoder.yudao.module.mes.service.qc.indicatorresult.MesQcIndicatorResultService;
 import cn.iocoder.yudao.module.mes.service.qc.rqc.MesQcRqcService;
 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
@@ -29,9 +41,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;
@@ -50,6 +67,12 @@
     private MesMdItemService itemService;
     @Resource
     private MesMdUnitMeasureService unitMeasureService;
+    @Resource
+    private MesQcIndicatorResultService indicatorResultService;
+    @Resource
+    private MesQcIndicatorService indicatorService;
+    @Resource
+    private MesQcRqcLineMapper rqcLineMapper;
 
     @Resource
     private AdminUserApi adminUserApi;
@@ -112,8 +135,8 @@
                                HttpServletResponse response) throws IOException {
         pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
         List<MesQcRqcDO> list = rqcService.getRqcPage(pageReqVO).getList();
-        List<MesQcRqcRespVO> voList = buildRqcRespVOList(list);
-        ExcelUtils.write(response, "閫�璐ф楠屽崟.xls", "鏁版嵁", MesQcRqcRespVO.class, voList);
+        List<MesQcQualityExportVO> exportList = buildRqcQualityExportList(list);
+        ExcelUtils.write(response, "閫�璐ф楠屽崟.xls", "鏁版嵁", MesQcQualityExportVO.class, exportList);
     }
 
     // ==================== 鎷兼帴 VO ====================
@@ -131,6 +154,8 @@
         // 鎵归噺鏌ヨ妫�娴嬩汉鍛�
         Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
                 convertSet(list, MesQcRqcDO::getInspectorUserId));
+        // 鎵归噺鏌ヨ妫�楠岄」鎸囨爣
+        Map<Long, String> indicatorSummaryMap = buildIndicatorSummaryMap(list);
         // 鎷艰 VO
         return BeanUtils.toBean(list, MesQcRqcRespVO.class, vo -> {
             findAndThen(itemMap, vo.getItemId(), item -> {
@@ -140,7 +165,166 @@
             });
             findAndThen(userMap, vo.getInspectorUserId(),
                     user -> vo.setInspectorNickname(user.getNickname()));
+            vo.setIndicatorResultSummary(indicatorSummaryMap.getOrDefault(vo.getId(), ""));
         });
     }
 
+    /**
+     * 鏋勫缓姣忎釜妫�楠屽崟鐨勬楠岄」鎸囨爣姹囨�诲瓧绗︿覆锛坬cType = RQC锛�
+     */
+    private Map<Long, String> buildIndicatorSummaryMap(List<MesQcRqcDO> list) {
+        Map<Long, String> indicatorSummaryMap = new HashMap<>();
+        Set<Long> qcIds = convertSet(list, MesQcRqcDO::getId);
+        if (CollUtil.isEmpty(qcIds)) {
+            return indicatorSummaryMap;
+        }
+        // 鎸� QC ID 鎵归噺鏌ヨ妫�楠岀粨鏋�
+        List<MesQcIndicatorResultDO> indicatorResults = indicatorResultService.getIndicatorResultListByQcIdsAndType(
+                new ArrayList<>(qcIds), MesBizTypeConstants.QC_RQC);
+        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> buildRqcQualityExportList(List<MesQcRqcDO> list) {
+        if (CollUtil.isEmpty(list)) {
+            return Collections.emptyList();
+        }
+        // 鎵归噺鏌ヨ妫�娴嬩汉鍛�
+        Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
+                convertSet(list, MesQcRqcDO::getInspectorUserId));
+        // 鎵归噺鏌ヨ鐗╂枡
+        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
+                convertSet(list, MesQcRqcDO::getItemId));
+        // 鎵归噺鏌ヨ琛屾槑缁�
+        List<MesQcRqcLineDO> lines = rqcLineMapper.selectListByRqcIds(convertSet(list, MesQcRqcDO::getId));
+        Map<Long, List<MesQcRqcLineDO>> lineMap = lines.stream()
+                .collect(Collectors.groupingBy(MesQcRqcLineDO::getRqcId));
+        // 鎵归噺鏌ヨ妫�娴嬫寚鏍�
+        Map<Long, MesQcIndicatorDO> indicatorMap = CollUtil.isEmpty(lines) ? Collections.emptyMap()
+                : indicatorService.getIndicatorMap(convertSet(lines, MesQcRqcLineDO::getIndicatorId));
+        // 鎵归噺鏌ヨ瀹炴祴鍊硷細妫�楠屽崟 ID -> {鎸囨爣 ID -> 瀹炴祴鍊紏
+        Map<Long, Map<Long, String>> measureMap = buildMeasureValueMap(
+                convertSet(list, MesQcRqcDO::getId), MesBizTypeConstants.QC_RQC);
+        // 缁勮瀵煎嚭琛�
+        List<MesQcQualityExportVO> exportList = new ArrayList<>(list.size());
+        for (MesQcRqcDO rqc : list) {
+            MesQcQualityExportVO vo = new MesQcQualityExportVO();
+            vo.setDocName(rqc.getName());
+            MesMdItemDO item = itemMap.get(rqc.getItemId());
+            vo.setItemName(item != null ? item.getName() : "");
+            vo.setBatchNo(rqc.getBatchCode());
+            vo.setInspectDate(MesQcQualityExportVO.formatDateTime(rqc.getInspectDate()));
+            List<String> indicatorNames = new ArrayList<>();
+            List<String> judgementSegments = new ArrayList<>();
+            for (MesQcRqcLineDO line : lineMap.getOrDefault(rqc.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(rqc.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(rqc.getCheckResult()));
+            findAndThen(userMap, rqc.getInspectorUserId(),
+                    user -> vo.setInspectorName(user.getNickname()));
+            // 鏆傛棤瀹℃牳浜烘暟鎹潵婧愶紝瀵煎嚭绌哄垪
+            vo.setAuditorName("");
+            vo.setRemark(rqc.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