From 34981c30a78e8bbd7791131059a9210f9928b62c Mon Sep 17 00:00:00 2001
From: 刘光辉 <347230014@qq.com>
Date: 星期四, 17 九月 2026 09:24:09 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master' into master
---
jnpf-lims/jnpf-lims-biz/src/main/java/jnpf/limsService/print/WendingxingKaocaHuizongRenderer.java | 302 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 302 insertions(+), 0 deletions(-)
diff --git a/jnpf-lims/jnpf-lims-biz/src/main/java/jnpf/limsService/print/WendingxingKaocaHuizongRenderer.java b/jnpf-lims/jnpf-lims-biz/src/main/java/jnpf/limsService/print/WendingxingKaocaHuizongRenderer.java
new file mode 100644
index 0000000..8f95350
--- /dev/null
+++ b/jnpf-lims/jnpf-lims-biz/src/main/java/jnpf/limsService/print/WendingxingKaocaHuizongRenderer.java
@@ -0,0 +1,302 @@
+package jnpf.limsService.print;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import jnpf.exception.DataException;
+import jnpf.limsEntity.LimsJianyanXiangEntity;
+import jnpf.limsEntity.LimsPrintTemplateEntity;
+import jnpf.limsEntity.LimsQingyandanEntity;
+import jnpf.limsEntity.LimsWendingxingKaocaJihuaEntity;
+import jnpf.limsEntity.LimsWendingxingKaocaJihuaZhouqiEntity;
+import jnpf.limsMapper.LimsJianyanXiangMapper;
+import jnpf.limsMapper.LimsQingyandanMapper;
+import jnpf.limsMapper.LimsWendingxingKaocaJihuaMapper;
+import jnpf.limsMapper.LimsWendingxingKaocaJihuaZhouqiMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * 绋冲畾鎬ц�冨療姹囨�绘ā鏉挎覆鏌撳櫒锛坱emplate_id = wendingxing_kaoca_huizong锛夈��
+ */
+@Component
+public class WendingxingKaocaHuizongRenderer implements PrintTemplateRenderer {
+
+ public static final String TEMPLATE_ID = "wendingxing_kaoca_huizong";
+ private static final String EMPTY_RESULT = "/";
+
+ @Autowired
+ private LimsWendingxingKaocaJihuaMapper jihuaMapper;
+
+ @Autowired
+ private LimsWendingxingKaocaJihuaZhouqiMapper zhouqiMapper;
+
+ @Autowired
+ private LimsQingyandanMapper qingyandanMapper;
+
+ @Autowired
+ private LimsJianyanXiangMapper jianyanXiangMapper;
+
+ @Autowired
+ private ObjectMapper objectMapper;
+
+ @Override
+ public String getTemplateId() {
+ return TEMPLATE_ID;
+ }
+
+ @Override
+ public Map<String, Object> render(String baogaoId, LimsPrintTemplateEntity tpl) {
+ if (baogaoId == null || baogaoId.trim().isEmpty()) {
+ throw new DataException("缂哄皯绋冲畾鎬ц�冨療璁″垝 id");
+ }
+
+ LimsWendingxingKaocaJihuaEntity jihua = selectJihua(baogaoId);
+ if (jihua == null) {
+ throw new DataException("绋冲畾鎬ц�冨療璁″垝涓嶅瓨鍦ㄦ垨宸插垹闄�: " + baogaoId);
+ }
+
+ Map<String, Object> config = parseConfig(tpl);
+ List<LimsWendingxingKaocaJihuaZhouqiEntity> cycles = selectCycles(baogaoId);
+ Map<String, List<LimsQingyandanEntity>> qingyandanByCycle = selectQingyandan(baogaoId, cycles);
+ Map<String, List<LimsJianyanXiangEntity>> itemsByQingyandan = selectItems(qingyandanByCycle);
+
+ LinkedHashMap<String, String> periodLabels = buildPeriodLabels(cycles, config.get("zhouqiDanwei"));
+ Map<String, Object> data = new LinkedHashMap<>();
+ data.put("schemeName", jihua.getKaocaMingcheng());
+ data.put("periods", new ArrayList<>(periodLabels.values()));
+ data.put("reports", buildReports(cycles, periodLabels, qingyandanByCycle, itemsByQingyandan));
+ return data;
+ }
+
+ private LimsWendingxingKaocaJihuaEntity selectJihua(String baogaoId) {
+ QueryWrapper<LimsWendingxingKaocaJihuaEntity> query = new QueryWrapper<>();
+ query.eq("f_id", baogaoId);
+ query.and(w -> w.isNull("f_delete_mark").or().ne("f_delete_mark", 1));
+ return jihuaMapper.selectOne(query);
+ }
+
+ /**
+ *
+ * 鏍规嵁璁″垝 ID 鏌ヨ鍛ㄦ湡鍒楄〃鏁版嵁
+ *
+ * @param baogaoId
+ * @return
+ */
+ private List<LimsWendingxingKaocaJihuaZhouqiEntity> selectCycles(String baogaoId) {
+ QueryWrapper<LimsWendingxingKaocaJihuaZhouqiEntity> query = new QueryWrapper<>();
+ query.eq("kaoca_jihua_id", baogaoId);
+ query.and(w -> w.isNull("f_delete_mark").or().ne("f_delete_mark", 1));
+ query.and(w -> w.isNull("shifou_jixu_zhixing").or().ne("shifou_jixu_zhixing", "no"));
+ query.orderByAsc("jiahua_anpai_riqi", "f_id");
+ return zhouqiMapper.selectList(query);
+ }
+
+ private Map<String, List<LimsQingyandanEntity>> selectQingyandan(
+ String baogaoId, List<LimsWendingxingKaocaJihuaZhouqiEntity> cycles) {
+ if (cycles.isEmpty()) {
+ return Collections.emptyMap();
+ }
+
+ List<String> cycleIds = cycles.stream()
+ .map(LimsWendingxingKaocaJihuaZhouqiEntity::getId)
+ .collect(Collectors.toList());
+ QueryWrapper<LimsQingyandanEntity> query = new QueryWrapper<>();
+ query.eq("wendingxing_jilu_id", baogaoId);
+ query.in("wendingxing_zhouqi_id", cycleIds);
+ query.and(w -> w.isNull("f_delete_mark").or().ne("f_delete_mark", 1));
+ query.orderByAsc("f_id");
+
+ Map<String, List<LimsQingyandanEntity>> result = new HashMap<>();
+ for (LimsQingyandanEntity row : qingyandanMapper.selectList(query)) {
+ result.computeIfAbsent(row.getWendingxingZhouqiId(), key -> new ArrayList<>()).add(row);
+ }
+ return result;
+ }
+
+ private Map<String, List<LimsJianyanXiangEntity>> selectItems(
+ Map<String, List<LimsQingyandanEntity>> qingyandanByCycle) {
+ List<String> qingyandanIds = qingyandanByCycle.values().stream()
+ .flatMap(List::stream)
+ .map(LimsQingyandanEntity::getId)
+ .collect(Collectors.toList());
+ if (qingyandanIds.isEmpty()) {
+ return Collections.emptyMap();
+ }
+
+ QueryWrapper<LimsJianyanXiangEntity> query = new QueryWrapper<>();
+ query.in("qingyandan_id", qingyandanIds);
+ query.and(w -> w.isNull("f_delete_mark").or().ne("f_delete_mark", 1));
+ query.orderByAsc("f_id");
+
+ Map<String, List<LimsJianyanXiangEntity>> result = new HashMap<>();
+ for (LimsJianyanXiangEntity row : jianyanXiangMapper.selectList(query)) {
+ result.computeIfAbsent(row.getQingyandanId(), key -> new ArrayList<>()).add(row);
+ }
+ return result;
+ }
+
+ private LinkedHashMap<String, String> buildPeriodLabels(
+ List<LimsWendingxingKaocaJihuaZhouqiEntity> cycles, Object unitConfig) {
+ LinkedHashMap<String, String> result = new LinkedHashMap<>();
+ for (LimsWendingxingKaocaJihuaZhouqiEntity cycle : cycles) {
+ String key = periodKey(cycle);
+ result.putIfAbsent(key, formatNumber(cycle.getZhouqi())
+ + resolveUnit(cycle.getZhouqiDanwei(), unitConfig));
+ }
+ return result;
+ }
+
+ private List<Map<String, Object>> buildReports(
+ List<LimsWendingxingKaocaJihuaZhouqiEntity> cycles,
+ LinkedHashMap<String, String> periodLabels,
+ Map<String, List<LimsQingyandanEntity>> qingyandanByCycle,
+ Map<String, List<LimsJianyanXiangEntity>> itemsByQingyandan) {
+ LinkedHashMap<String, List<LimsWendingxingKaocaJihuaZhouqiEntity>> cyclesByBatch =
+ new LinkedHashMap<>();
+ for (LimsWendingxingKaocaJihuaZhouqiEntity cycle : cycles) {
+ cyclesByBatch.computeIfAbsent(valueOrEmpty(cycle.getPihao()), key -> new ArrayList<>())
+ .add(cycle);
+ }
+
+ List<Map<String, Object>> reports = new ArrayList<>();
+ for (Map.Entry<String, List<LimsWendingxingKaocaJihuaZhouqiEntity>> batch
+ : cyclesByBatch.entrySet()) {
+ LinkedHashMap<String, ReportRow> rows = new LinkedHashMap<>();
+ for (LimsWendingxingKaocaJihuaZhouqiEntity cycle : batch.getValue()) {
+ String periodKey = periodKey(cycle);
+ for (LimsQingyandanEntity qingyandan
+ : qingyandanByCycle.getOrDefault(cycle.getId(), Collections.emptyList())) {
+ for (LimsJianyanXiangEntity item
+ : itemsByQingyandan.getOrDefault(qingyandan.getId(), Collections.emptyList())) {
+ String rowKey = valueOrEmpty(item.getJianyanXiangmuMingcheng()) + "\u0000"
+ + valueOrEmpty(item.getBiaozhunGuiding());
+ String standard = resultOrSlash(item.getBiaozhunGuiding());
+ String value = resultOrSlash(item.getJianyanJieguo());
+ if ("鏁板��".equals(item.getShujuLeixing())) {
+ value += item.getFenjianDanwei();
+ standard += item.getFenjianDanwei();
+ }
+ String finalStandard = standard;
+ ReportRow row = rows.computeIfAbsent(rowKey,
+ key -> new ReportRow(item.getJianyanXiangmuMingcheng(), finalStandard));
+ if (!row.values.containsKey(periodKey)
+ || EMPTY_RESULT.equals(row.values.get(periodKey))) {
+ row.values.put(periodKey, value);
+ }
+ }
+ }
+ }
+
+ List<Map<String, Object>> reportRows = new ArrayList<>();
+ for (ReportRow source : rows.values()) {
+ Map<String, Object> row = new LinkedHashMap<>();
+ row.put("item", source.item);
+ row.put("standard", source.standard);
+ List<String> values = periodLabels.keySet().stream()
+ .map(key -> source.values.getOrDefault(key, EMPTY_RESULT))
+ .collect(Collectors.toList());
+ row.put("values", values);
+ reportRows.add(row);
+ }
+
+ Map<String, Object> report = new LinkedHashMap<>();
+ report.put("batchNo", batch.getKey());
+ report.put("rows", reportRows);
+ reports.add(report);
+ }
+ return reports;
+ }
+
+ private Map<String, Object> parseConfig(LimsPrintTemplateEntity tpl) {
+ if (tpl == null || tpl.getConfig() == null || tpl.getConfig().trim().isEmpty()) {
+ return Collections.emptyMap();
+ }
+ try {
+ return objectMapper.readValue(tpl.getConfig(), new TypeReference<Map<String, Object>>() { });
+ } catch (Exception e) {
+ throw new DataException("鎵撳嵃妯℃澘 config JSON 瑙f瀽澶辫触: " + e.getMessage());
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private String resolveUnit(String code, Object config) {
+ String source = valueOrEmpty(code);
+ if (config instanceof Map) {
+ Object configured = ((Map<String, Object>) config).get(source);
+ return labelOf(configured, source);
+ }
+ if (config instanceof List) {
+ for (Object entry : (List<?>) config) {
+ if (!(entry instanceof Map)) {
+ continue;
+ }
+ Map<String, Object> option = (Map<String, Object>) entry;
+ String value = firstString(option, "value", "id", "code", "enCode");
+ if (source.equals(value)) {
+ return firstNonEmpty(firstString(option, "label", "name", "fullName", "text"), source);
+ }
+ }
+ }
+ return source;
+ }
+
+ @SuppressWarnings("unchecked")
+ private String labelOf(Object configured, String fallback) {
+ if (configured instanceof Map) {
+ return firstNonEmpty(firstString((Map<String, Object>) configured,
+ "label", "name", "fullName", "text", "value"), fallback);
+ }
+ return configured == null ? fallback : configured.toString();
+ }
+
+ private String firstString(Map<String, Object> values, String... keys) {
+ for (String key : keys) {
+ Object value = values.get(key);
+ if (value != null && !value.toString().trim().isEmpty()) {
+ return value.toString();
+ }
+ }
+ return "";
+ }
+
+ private String periodKey(LimsWendingxingKaocaJihuaZhouqiEntity cycle) {
+ return formatNumber(cycle.getZhouqi()) + "\u0000" + valueOrEmpty(cycle.getZhouqiDanwei());
+ }
+
+ private String formatNumber(BigDecimal value) {
+ return value == null ? "" : value.stripTrailingZeros().toPlainString();
+ }
+
+ private String resultOrSlash(String value) {
+ return value == null || value.trim().isEmpty() ? EMPTY_RESULT : value;
+ }
+
+ private String firstNonEmpty(String value, String fallback) {
+ return value == null || value.trim().isEmpty() ? fallback : value;
+ }
+
+ private String valueOrEmpty(String value) {
+ return value == null ? "" : value;
+ }
+
+ private static final class ReportRow {
+ private final String item;
+ private final String standard;
+ private final Map<String, String> values = new HashMap<>();
+
+ private ReportRow(String item, String standard) {
+ this.item = item;
+ this.standard = standard;
+ }
+ }
+}
--
Gitblit v1.8.0