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/HuanjingWeishengwuRenderer.java | 425 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 425 insertions(+), 0 deletions(-)
diff --git a/jnpf-lims/jnpf-lims-biz/src/main/java/jnpf/limsService/print/HuanjingWeishengwuRenderer.java b/jnpf-lims/jnpf-lims-biz/src/main/java/jnpf/limsService/print/HuanjingWeishengwuRenderer.java
new file mode 100644
index 0000000..189e73d
--- /dev/null
+++ b/jnpf-lims/jnpf-lims-biz/src/main/java/jnpf/limsService/print/HuanjingWeishengwuRenderer.java
@@ -0,0 +1,425 @@
+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.LimsHuanjingJianceBaogaoEntity;
+import jnpf.limsEntity.LimsHuanjingJianceBaogaoZixiangEntity;
+import jnpf.limsEntity.LimsHuanjingJianceBiaozhunEntity;
+import jnpf.limsEntity.LimsHuanjingJianceYijuEntity;
+import jnpf.limsEntity.LimsHuanjingQuyuEntity;
+import jnpf.limsEntity.LimsPrintTemplateEntity;
+import jnpf.limsMapper.LimsHuanjingJianceBaogaoMapper;
+import jnpf.limsMapper.LimsHuanjingJianceBaogaoZixiangMapper;
+import jnpf.limsMapper.LimsHuanjingJianceBiaozhunMapper;
+import jnpf.limsMapper.LimsHuanjingJianceYijuMapper;
+import jnpf.limsMapper.LimsHuanjingQuyuMapper;
+import jnpf.permission.UserApi;
+import jnpf.permission.entity.UserEntity;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.math.BigDecimal;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * "琛ㄩ潰寰敓鐗╂娴嬭褰�"妯℃澘娓叉煋鍣紙template_id = huanjing_weishengwu锛夈��
+ *
+ * <p>杈撳叆锛歭ims_huanjing_jiance_baogao.f_id锛涘瓙椤规潵鑷�
+ * lims_huanjing_jiance_baogao_zixiang.f_foreign_id銆�
+ */
+@Component
+public class HuanjingWeishengwuRenderer implements PrintTemplateRenderer {
+
+ public static final String TEMPLATE_ID = "huanjing_weishengwu";
+
+ private static final String DEFAULT_COMPANY_NAME = "鍗庨亾锛堜笂娴凤級鐢熺墿鍖昏嵂鏈夐檺鍏徃";
+ private static final String DEFAULT_DOC_NUMBER = "SOP-MBC-A020-TO-R01-02";
+ private static final String DEFAULT_REVIEW_CYCLE = "3骞�";
+ private static final String DEFAULT_METHOD_TEXT = "SOP-MBC-A020-TO銆婅〃闈㈠井鐢熺墿妫�娴嬫爣鍑嗘搷浣滆绋嬨��";
+
+ @Autowired
+ private LimsHuanjingJianceBaogaoMapper baogaoMapper;
+
+ @Autowired
+ private LimsHuanjingJianceBaogaoZixiangMapper zixiangMapper;
+
+ @Autowired
+ private LimsHuanjingJianceBiaozhunMapper biaozhunMapper;
+
+ @Autowired
+ private LimsHuanjingJianceYijuMapper yijuMapper;
+
+ @Autowired
+ private LimsHuanjingQuyuMapper quyuMapper;
+
+ @Autowired
+ private UserApi usersApi;
+
+ @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.isEmpty()) {
+ throw new DataException("缂哄皯鐜鐩戞祴鎶ュ憡 id");
+ }
+
+ Map<String, Object> baogao = getBaogaoMap(baogaoId);
+ if (baogao.isEmpty()) {
+ throw new DataException("鐜鐩戞祴鎶ュ憡涓嶅瓨鍦ㄦ垨宸插垹闄�: " + baogaoId);
+ }
+
+ Map<String, Object> cfg = parseConfig(tpl);
+ List<Map<String, Object>> items = buildItems(baogaoId);
+ Map<String, String> userNames = fetchUserNames(baogao);
+
+ Map<String, Object> data = new LinkedHashMap<>();
+ data.put("template_id", tpl.getTemplateId());
+ data.put("template_name", tpl.getTemplateName());
+ data.put("companyName", asString(cfg.get("company_name"), DEFAULT_COMPANY_NAME));
+ data.put("docNumber", asString(cfg.get("doc_number"), DEFAULT_DOC_NUMBER));
+ data.put("reviewCycle", asString(cfg.get("review_cycle"), DEFAULT_REVIEW_CYCLE));
+ data.put("distributionDepartment", asString(cfg.get("distribution_department")));
+ data.put("effectiveDate", formatDate(getAny(baogao, "fuhe_riqi")));
+ data.put("methodText", resolveMethodText(baogao, cfg));
+ data.put("header", buildHeader(baogao));
+ data.put("items", items);
+ data.put("standardRows", buildStandardRows(cfg));
+ data.put("jielun", normalizeConclusion(asString(getAny(baogao, "jielun"))));
+ data.put("signatures", buildSignatures(baogao, userNames));
+ data.put("beizhu", asString(getAny(baogao, "beizhu"), asString(cfg.get("beizhu"))));
+ return data;
+ }
+
+ private Map<String, Object> getBaogaoMap(String baogaoId) {
+ QueryWrapper<LimsHuanjingJianceBaogaoEntity> wrapper = new QueryWrapper<>();
+ wrapper.eq("f_id", baogaoId);
+ wrapper.and(w -> w.isNull("f_delete_mark").or().ne("f_delete_mark", 1));
+ List<Map<String, Object>> rows = baogaoMapper.selectMaps(wrapper);
+ return rows.isEmpty() ? Collections.emptyMap() : new LinkedHashMap<>(rows.get(0));
+ }
+
+ private List<Map<String, Object>> buildItems(String baogaoId) {
+ QueryWrapper<LimsHuanjingJianceBaogaoZixiangEntity> wrapper = new QueryWrapper<>();
+ wrapper.eq("f_foreign_id", baogaoId);
+ wrapper.and(w -> w.isNull("f_delete_mark").or().ne("f_delete_mark", 1));
+ wrapper.orderByAsc("weizhi_bianhao", "quyangdian_mingcheng", "f_id");
+
+ List<Map<String, Object>> items = new ArrayList<>();
+ for (Map<String, Object> row : zixiangMapper.selectMaps(wrapper)) {
+ Map<String, Object> item = new LinkedHashMap<>();
+ item.put("weizhi_bianhao", asString(getAny(row, "weizhi_bianhao")));
+ item.put("weizhi_mingcheng", asString(getAny(row, "weizhi_mingcheng")));
+ item.put("quyangdian_mingcheng", asString(getAny(row, "quyangdian_mingcheng")));
+ item.put("ceshi_jieguo", asString(getAny(row, "ceshi_jieguo")));
+ item.put("shifou_hege", normalizeYesNo(asString(getAny(row, "shifou_hege"))));
+ items.add(item);
+ }
+ return items;
+ }
+
+ private Map<String, Object> buildHeader(Map<String, Object> row) {
+ Map<String, Object> h = new LinkedHashMap<>();
+ String quyuId = asString(getAny(row, "jiance_quyu"));
+ h.put("jiance_quyu", quyuId);
+ h.put("jiance_quyu_name", resolveQuyuName(quyuId));
+ h.put("jiance_riqi", formatDate(getAny(row, "jiance_riqi")));
+ h.put("jiance_zhuangtai", asString(getAny(row, "jiance_zhuangtai")));
+ h.put("qizhi_shijian", asString(getAny(row, "qizhi_shijian")));
+ h.put("peiyangji_pihao", asString(getAny(row, "peiyangji_pihao")));
+ h.put("peiyangji_youxiaoqi", formatDate(getAny(row, "peiyangji_youxiaoqi")));
+ h.put("peiyang_shebei_biaohao", asString(getAny(row, "peiyang_shebei_biaohao")));
+ h.put("jiaozhun_youxiaoqi", formatDate(getAny(row, "jiaozhun_youxiaoqi")));
+ h.put("peiyang_kaishi_shijian", formatDate(getAny(row, "peiyang_kaishi_shijian")));
+ h.put("peiyang_jieshu_shijian", formatDate(getAny(row, "peiyang_jieshu_shijian")));
+ h.put("jiejing_jibie", formatLevel(asString(getAny(row, "jiejing_jibie"))));
+ h.put("biaozhun_guiding", asString(getAny(row, "biaozhun_guiding")));
+ h.put("moren_danwei", asString(getAny(row, "moren_danwei")));
+ h.put("beizhu", asString(getAny(row, "beizhu")));
+ return h;
+ }
+
+ private String resolveMethodText(Map<String, Object> baogao, Map<String, Object> cfg) {
+ String biaozhunIdOrCode = asString(getAny(baogao, "biaozhun_guiding"));
+ Map<String, Object> biaozhun = findBiaozhun(biaozhunIdOrCode);
+ if (biaozhun.isEmpty()) {
+ return asString(cfg.get("method_text"), DEFAULT_METHOD_TEXT);
+ }
+
+ String biaozhunGuiding = asString(getAny(biaozhun, "biaozhun_guiding"));
+ String yijuIdOrText = asString(getAny(biaozhun, "jiance_yiju"));
+ String jianceYiju = findJianceYiju(yijuIdOrText);
+
+ if (!biaozhunGuiding.isEmpty() && !jianceYiju.isEmpty()) {
+ return biaozhunGuiding + " " + jianceYiju;
+ }
+ if (!biaozhunGuiding.isEmpty()) {
+ return biaozhunGuiding;
+ }
+ if (!jianceYiju.isEmpty()) {
+ return jianceYiju;
+ }
+ return asString(cfg.get("method_text"), DEFAULT_METHOD_TEXT);
+ }
+
+ private Map<String, Object> findBiaozhun(String biaozhunIdOrCode) {
+ if (biaozhunIdOrCode == null || biaozhunIdOrCode.isEmpty()) {
+ return Collections.emptyMap();
+ }
+
+ QueryWrapper<LimsHuanjingJianceBiaozhunEntity> byGuiding = new QueryWrapper<>();
+ byGuiding.eq("biaozhun_guiding", biaozhunIdOrCode);
+ byGuiding.and(w -> w.isNull("f_delete_mark").or().ne("f_delete_mark", 1));
+ List<Map<String, Object>> rows = biaozhunMapper.selectMaps(byGuiding);
+ if (!rows.isEmpty()) {
+ return new LinkedHashMap<>(rows.get(0));
+ }
+
+ QueryWrapper<LimsHuanjingJianceBiaozhunEntity> byId = new QueryWrapper<>();
+ byId.eq("f_id", biaozhunIdOrCode);
+ byId.and(w -> w.isNull("f_delete_mark").or().ne("f_delete_mark", 1));
+ rows = biaozhunMapper.selectMaps(byId);
+ return rows.isEmpty() ? Collections.emptyMap() : new LinkedHashMap<>(rows.get(0));
+ }
+
+ private String findJianceYiju(String yijuIdOrText) {
+ if (yijuIdOrText == null || yijuIdOrText.isEmpty()) {
+ return "";
+ }
+
+ QueryWrapper<LimsHuanjingJianceYijuEntity> byId = new QueryWrapper<>();
+ byId.eq("f_id", yijuIdOrText);
+ byId.and(w -> w.isNull("f_delete_mark").or().ne("f_delete_mark", 1));
+ List<LimsHuanjingJianceYijuEntity> rows = yijuMapper.selectList(byId);
+ if (!rows.isEmpty() && rows.get(0).getJianceYiju() != null) {
+ return rows.get(0).getJianceYiju();
+ }
+
+ QueryWrapper<LimsHuanjingJianceYijuEntity> byText = new QueryWrapper<>();
+ byText.eq("jiance_yiju", yijuIdOrText);
+ byText.and(w -> w.isNull("f_delete_mark").or().ne("f_delete_mark", 1));
+ rows = yijuMapper.selectList(byText);
+ if (rows.isEmpty() || rows.get(0).getJianceYiju() == null) {
+ return yijuIdOrText;
+ }
+ return rows.get(0).getJianceYiju();
+ }
+
+ private String resolveQuyuName(String quyuId) {
+ if (quyuId == null || quyuId.isEmpty()) {
+ return "";
+ }
+ QueryWrapper<LimsHuanjingQuyuEntity> wrapper = new QueryWrapper<>();
+ wrapper.eq("f_id", quyuId);
+ wrapper.and(w -> w.isNull("f_delete_mark").or().ne("f_delete_mark", 1));
+ List<LimsHuanjingQuyuEntity> list = quyuMapper.selectList(wrapper);
+ if (list.isEmpty() || list.get(0).getJianceQuyu() == null) {
+ return quyuId;
+ }
+ return list.get(0).getJianceQuyu();
+ }
+
+ @SuppressWarnings("unchecked")
+ private List<Map<String, Object>> buildStandardRows(Map<String, Object> cfg) {
+ Object rows = cfg.get("standard_rows");
+ if (rows instanceof List) {
+ return (List<Map<String, Object>>) rows;
+ }
+
+ List<Map<String, Object>> result = new ArrayList<>();
+ result.add(standardRow("A", "<1", "<1"));
+ result.add(standardRow("C", "25", "25"));
+ result.add(standardRow("D", "50", "50"));
+ return result;
+ }
+
+ private Map<String, Object> standardRow(String level, String staticLimit, String dynamicLimit) {
+ Map<String, Object> row = new LinkedHashMap<>();
+ row.put("level", level);
+ row.put("static_limit", staticLimit);
+ row.put("dynamic_limit", dynamicLimit);
+ return row;
+ }
+
+ private Map<String, Object> buildSignatures(Map<String, Object> row, Map<String, String> userNames) {
+ Map<String, Object> sig = new LinkedHashMap<>();
+ sig.put("operator", makeSignature(
+ asString(getAny(row, "jiance_ren")),
+ formatDate(getAny(row, "jiance_riqi")),
+ userNames));
+ sig.put("recorder", makeSignature(
+ asString(getAny(row, "jiance_ren")),
+ formatDate(getAny(row, "jiance_riqi")),
+ userNames));
+ sig.put("reviewer", makeSignature(
+ asString(getAny(row, "fuhe_ren")),
+ formatDate(getAny(row, "fuhe_riqi")),
+ userNames));
+ return sig;
+ }
+
+ private Map<String, Object> makeSignature(String userId, String date, Map<String, String> userNames) {
+ Map<String, Object> m = new LinkedHashMap<>();
+ m.put("user_id", userId);
+ m.put("name", userId == null ? "" : asString(userNames.get(userId)));
+ m.put("date", date);
+ return m;
+ }
+
+ private Map<String, String> fetchUserNames(Map<String, Object> row) {
+ List<String> userIds = Arrays.asList(
+ asString(getAny(row, "jiance_ren")),
+ asString(getAny(row, "quyang_ren")),
+ asString(getAny(row, "fuhe_ren")))
+ .stream()
+ .filter(s -> s != null && !s.isEmpty())
+ .distinct()
+ .collect(Collectors.toList());
+ if (userIds.isEmpty()) {
+ return Collections.emptyMap();
+ }
+
+ Map<String, String> idToRealName = new HashMap<>();
+ List<UserEntity> users = usersApi.getUserName(userIds);
+ if (users != null) {
+ for (UserEntity u : users) {
+ if (u != null && u.getId() != null) {
+ idToRealName.put(u.getId(), u.getRealName());
+ }
+ }
+ }
+ return idToRealName;
+ }
+
+ private Map<String, Object> parseConfig(LimsPrintTemplateEntity tpl) {
+ String json = tpl.getConfig();
+ if (json == null || json.isEmpty()) {
+ return Collections.emptyMap();
+ }
+ try {
+ return objectMapper.readValue(json, new TypeReference<Map<String, Object>>() {});
+ } catch (Exception e) {
+ throw new DataException("鎵撳嵃妯℃澘 config JSON 瑙f瀽澶辫触: " + e.getMessage());
+ }
+ }
+
+ private static Object getAny(Map<String, Object> row, String key) {
+ if (row == null || row.isEmpty()) {
+ return null;
+ }
+ if (row.containsKey(key)) {
+ return row.get(key);
+ }
+ String lowerKey = normalizeKey(key);
+ for (Map.Entry<String, Object> e : row.entrySet()) {
+ if (e.getKey() != null && normalizeKey(e.getKey()).equals(lowerKey)) {
+ return e.getValue();
+ }
+ }
+ return null;
+ }
+
+ private static String normalizeKey(String key) {
+ return key == null ? "" : key.replace("_", "").toLowerCase();
+ }
+
+ private static String formatDate(Object value) {
+ return format(value, "yyyy-MM-dd");
+ }
+
+ private static String formatDateTime(Object value) {
+ return format(value, "yyyy-MM-dd");
+ }
+
+ private static String format(Object value, String pattern) {
+ if (value == null) {
+ return "";
+ }
+ if (value instanceof Date) {
+ return new SimpleDateFormat(pattern).format((Date) value);
+ }
+ String text = value.toString();
+ if ("yyyy-MM-dd".equals(pattern) && text.matches("^\\d{4}-\\d{2}-\\d{2}.*")) {
+ return text.substring(0, 10);
+ }
+ return text;
+ }
+
+ private static String formatLevel(String level) {
+ if (level == null || level.isEmpty()) {
+ return "";
+ }
+ String lower = level.toLowerCase();
+ if (Arrays.asList("a", "b", "c", "d").contains(lower)) {
+ return lower.toUpperCase() + "绾�";
+ }
+ return level;
+ }
+
+ private static String normalizeConclusion(String value) {
+ if ("compliant".equalsIgnoreCase(value)
+ || "qualified".equalsIgnoreCase(value)
+ || "fuheguiding".equalsIgnoreCase(value)
+ || "yes".equalsIgnoreCase(value)
+ || "鍚堟牸".equals(value)
+ || "绗﹀悎瑙勫畾".equals(value)) {
+ return "yes";
+ }
+ if ("non_compliant".equalsIgnoreCase(value)
+ || "uncompliant".equalsIgnoreCase(value)
+ || "unqualified".equalsIgnoreCase(value)
+ || "bufuheguiding".equalsIgnoreCase(value)
+ || "no".equalsIgnoreCase(value)
+ || "涓嶅悎鏍�".equals(value)
+ || "涓嶇鍚堣瀹�".equals(value)) {
+ return "no";
+ }
+ return value;
+ }
+
+ private static String normalizeYesNo(String value) {
+ if ("yes".equalsIgnoreCase(value)
+ || "true".equalsIgnoreCase(value)
+ || "1".equals(value)
+ || "鏄�".equals(value)
+ || "鍚堟牸".equals(value)) {
+ return "yes";
+ }
+ if ("no".equalsIgnoreCase(value)
+ || "false".equalsIgnoreCase(value)
+ || "0".equals(value)
+ || "鍚�".equals(value)
+ || "涓嶅悎鏍�".equals(value)) {
+ return "no";
+ }
+ return value;
+ }
+
+ private static String asString(Object v) {
+ if (v instanceof BigDecimal) {
+ return ((BigDecimal) v).stripTrailingZeros().toPlainString();
+ }
+ return v == null ? "" : v.toString();
+ }
+
+ private static String asString(Object v, String fallback) {
+ String s = asString(v);
+ return s.isEmpty() ? fallback : s;
+ }
+}
--
Gitblit v1.8.0