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-biz-common/jnpf-biz-common-audit/src/main/java/jnpf/bizcommon/audit/service/value/JnpfUserFieldValueResolver.java | 235 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 235 insertions(+), 0 deletions(-)
diff --git a/jnpf-biz-common/jnpf-biz-common-audit/src/main/java/jnpf/bizcommon/audit/service/value/JnpfUserFieldValueResolver.java b/jnpf-biz-common/jnpf-biz-common-audit/src/main/java/jnpf/bizcommon/audit/service/value/JnpfUserFieldValueResolver.java
new file mode 100644
index 0000000..3401485
--- /dev/null
+++ b/jnpf-biz-common/jnpf-biz-common-audit/src/main/java/jnpf/bizcommon/audit/service/value/JnpfUserFieldValueResolver.java
@@ -0,0 +1,235 @@
+package jnpf.bizcommon.audit.service.value;
+
+import com.alibaba.fastjson.JSON;
+import jnpf.bizcommon.audit.entity.model.AuditFieldDiffViewVO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.annotation.Order;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
+import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * 鎶� {@code userSelect} 鎺т欢瀛樼殑鐢ㄦ埛 id 瑙f瀽鎴愩�岀湡瀹炲鍚�/璐﹀彿銆嶃��
+ *
+ * <p><b>涓轰粈涔堥渶瑕佸畠</b>锛歿@code userSelect} 鐨� valueType 鏄� {@code reference}锛堣
+ * {@link jnpf.bizcommon.audit.service.AuditFormRegistry} 鐨� valueType 鏄犲皠锛夛紝鑰�
+ * {@link jnpf.bizcommon.audit.service.AuditFieldDiffViewService} 瀵规病浜鸿棰嗙殑 reference 涓�寰嬪洖钀芥垚
+ * 銆屽悕绉版殏涓嶅彲鐢ㄣ�嶃�傛鍓嶅彧鏈夊瓧鍏歌В鏋愬櫒鍜岃楠屽崟涓撶敤瑙f瀽鍣紝鐢ㄦ埛 id 鏃犱汉璁ら鈥斺��2026-08-02
+ * 瀹炴祴鍒犻櫎鏍囬 {@code ys0001/ys0001淇敼涓嬪娉�/鍚嶇О鏆備笉鍙敤}锛屾渶鍚庨偅娈靛氨鏄彁浜や汉銆�
+ * <b>杩欐槸鏃㈡湁缂洪櫡鑰屼笉鏄垹闄ゅ満鏅紩鍏ョ殑</b>锛氫互鍓嶆爣棰樺彧鍕句簡缂栧彿鎵�浠ユ病鏆撮湶锛孌6 璁╁垪琛ㄥ嬀閫�
+ * 锛堝惈鎻愪氦浜猴級杩涙爣棰樻墠绗竴娆$幇褰€��
+ *
+ * <p><b>灞曠ず鏍煎紡璺熼殢鍓嶇</b>锛歿@code realName/account}锛堝銆岀鐞嗗憳/admin銆嶏級銆傚钩鍙拌嚜宸卞湪
+ * {@code FormInfoUtils}/{@code OnlineDevInfoUtils} 绛夊崄鍑犲閮芥槸杩欎釜鎷兼硶锛屽璁¢噷鎹釜鍐欐硶
+ * 鍙細璁╀汉鎬�鐤戞槸涓嶆槸鍙︿竴涓汉銆傚甫涓婅处鍙锋槸瀹¤鐨勫垰闇�鈥斺�旈噸鍚嶇殑涓や釜浜洪潬濮撳悕鍒嗕笉寮�銆�
+ *
+ * <p><b>涓嶈繃婊� f_delete_mark / f_enabled_mark</b>锛氬璁¤拷鐨勬槸銆屽綋鏃舵槸璋併�嶃�備汉绂昏亴浜嗐�佽处鍙�
+ * 鍋滅敤浜嗐�佺敤鎴疯鍒犱簡锛屼簨浠堕噷閭d釜 id 鎸囧悜鐨勪粛鐒舵槸鍚屼竴涓汉锛岃繖鏃跺�欐妸鍚嶅瓧鎹㈡垚銆屽悕绉版殏涓嶅彲鐢ㄣ��
+ * 鎭版伆鏄妸鏈�闇�瑕佽拷婧殑閭f潯璁板綍鍙樻垚涓嶅彲杩芥函銆傜鎴疯竟鐣屼粛鐒剁収绾︽潫鈥斺�旈偅鏄暟鎹殧绂伙紝涓嶆槸鍘嗗彶銆�
+ *
+ * <p>涓� {@link LimsQingyandanFieldValueResolver} 鐨勫垎宸ワ細閭d釜鏄〃涓撶敤瑙f瀽鍣紙{@code @Order}
+ * 鏇撮潬鍓嶏級锛寋@code lims_qingyandan.qingyan_ren} 鐢卞畠鎸夎嚜宸辩殑鏍煎紡瑙f瀽瀹岋紝鏈В鏋愬櫒鐪嬪埌
+ * display 宸茬粡鏈夊�煎氨涓嶅啀鎻掓墜锛坽@code displaysResolved}锛夛紝涓よ�呬笉浼氭墦鏋躲��
+ */
+@Slf4j
+@Component
+@Order(JnpfUserFieldValueResolver.ORDER)
+public class JnpfUserFieldValueResolver implements AuditFieldValueResolver {
+
+ /** 閫氱敤鍏滃簳瑙f瀽鍣紝鎺掑湪琛ㄤ笓鐢紙100锛変笌瀛楀吀锛�200锛変箣鍚庛�� */
+ public static final int ORDER = 300;
+
+ private static final String UNAVAILABLE = "鍚嶇О鏆備笉鍙敤";
+
+ /** 璁ら鐨勬帶浠剁被鍨嬶紙灏忓啓姣斿锛夈�傚彧璁や汉鍛橀�夋嫨鍣紝閮ㄩ棬/瑙掕壊/宀椾綅鍚勬湁鍚勭殑鍚嶇О琛紝涓嶅湪鏈被鑼冨洿銆� */
+ private static final String USER_COMPONENT = "userselect";
+
+ private final UserLookup lookup;
+
+ @Autowired
+ public JnpfUserFieldValueResolver(JdbcTemplate jdbcTemplate) {
+ this(new JdbcUserLookup(jdbcTemplate));
+ }
+
+ JnpfUserFieldValueResolver(UserLookup lookup) {
+ this.lookup = lookup;
+ }
+
+ @Override
+ public boolean supports(String targetTable) {
+ return true; // userSelect 鏄钩鍙版帶浠讹紝鍝紶涓氬姟琛ㄩ兘鍙兘鏈�
+ }
+
+ @Override
+ public void resolve(AuditFieldValueContext context, List<AuditFieldDiffViewVO> fields) {
+ if (context == null || blank(context.getTenantId()) || fields == null || fields.isEmpty()) {
+ return;
+ }
+ Set<String> userIds = new LinkedHashSet<>();
+ for (AuditFieldDiffViewVO field : fields) {
+ if (!isUserField(field) || displaysResolved(field)) {
+ continue;
+ }
+ userIds.addAll(parseValues(field.getOldData()));
+ userIds.addAll(parseValues(field.getNewData()));
+ }
+ if (userIds.isEmpty()) {
+ return;
+ }
+
+ // 鏁存壒涓�娆� IN 鏌ヨ锛圫PI 绾﹀畾锛氬眰 0 璺戝湪 MQ 娑堣垂绾跨▼涓婏紝閫� id 鏌ヤ細鎷栧灝娑堣垂閫熺巼锛�
+ Map<String, String> names = lookup.names(context.getTenantId().trim(), userIds);
+ for (AuditFieldDiffViewVO field : fields) {
+ if (!isUserField(field)) {
+ continue;
+ }
+ if (field.getOldDisplay() == null) {
+ field.setOldDisplay(display(field.getOldData(), names));
+ }
+ if (field.getNewDisplay() == null) {
+ field.setNewDisplay(display(field.getNewData(), names));
+ }
+ }
+ }
+
+ /**
+ * 鍒ゆ嵁鏄�<b>鎺т欢绫诲瀷</b>鑰屼笉鏄瓧娈靛悕锛氬瓧娈靛悕鏄笟鍔¤捣鐨勶紙{@code tijiao_ren}/{@code fuhe_ren}/
+ * {@code qingyan_ren}鈥︼級锛岀┓涓句笉瀹岋紱{@code jnpfKey} 鎵嶆槸銆岃繖涓�鍒楀瓨鐨勬槸鐢ㄦ埛 id銆嶇殑鏉冨▉澹版槑銆�
+ */
+ private static boolean isUserField(AuditFieldDiffViewVO field) {
+ return field != null && field.getComponentType() != null
+ && USER_COMPONENT.equals(field.getComponentType().trim().toLowerCase(Locale.ROOT));
+ }
+
+ /** 涓や晶瑕佷箞鏈潵灏辩┖銆佽涔堝凡琚墠搴忚В鏋愬櫒濉繃锛屽氨涓嶅繀鍐嶆煡搴撱�� */
+ private static boolean displaysResolved(AuditFieldDiffViewVO field) {
+ return (blank(field.getOldData()) || field.getOldDisplay() != null)
+ && (blank(field.getNewData()) || field.getNewDisplay() != null);
+ }
+
+ private static String display(String raw, Map<String, String> names) {
+ if (blank(raw)) {
+ return "";
+ }
+ List<String> ids = parseValues(raw);
+ if (ids.isEmpty()) {
+ return UNAVAILABLE;
+ }
+ List<String> result = new ArrayList<>(ids.size());
+ for (String id : ids) {
+ String name = names.get(id);
+ result.add(blank(name) ? UNAVAILABLE : name);
+ }
+ return String.join("銆�", result);
+ }
+
+ /** 澶氶�夛紙multiple=true锛夌殑 userSelect 瀛樼殑鏄� JSON 鏁扮粍锛屽崟閫夊瓨瑁� id銆� */
+ @SuppressWarnings("unchecked")
+ private static List<String> parseValues(String raw) {
+ if (blank(raw)) {
+ return Collections.emptyList();
+ }
+ String trimmed = raw.trim();
+ if (!trimmed.startsWith("[")) {
+ return Collections.singletonList(trimmed);
+ }
+ try {
+ Object parsed = JSON.parse(trimmed);
+ if (!(parsed instanceof Collection)) {
+ return Collections.emptyList();
+ }
+ List<String> ids = new ArrayList<>();
+ for (Object value : (Collection<Object>) parsed) {
+ if (value != null && !String.valueOf(value).trim().isEmpty()) {
+ ids.add(String.valueOf(value).trim());
+ }
+ }
+ return ids;
+ } catch (Throwable ignored) {
+ return Collections.emptyList();
+ }
+ }
+
+ /**
+ * 鍓嶇灞曠ず鏍煎紡鍗� {@code realName/account}锛堝銆岀鐞嗗憳/admin銆嶏級锛涚己涓�杈规椂閫�鍖栨垚杩樺墿鐨�
+ * 閭d竴杈癸紝涓嶇暀瀛ら浂闆剁殑鏂滄潬銆�
+ *
+ * <p>鏀惧湪澶栧眰绫昏�屼笉鏄� {@link JdbcUserLookup} 閲岋紝鏄负浜嗚鎺㈤拡澶熷緱鐫�鈥斺�旀牸寮忔湰韬氨鏄�
+ * 鏈淇鐨勯獙鏀舵爣鍑嗕箣涓�锛堛�屽垹闄ゆ爣棰橀噷鎻愪氦浜烘樉绀虹鐞嗗憳/admin銆嶏級锛屽煁鍦� JDBC 瀹炵幇閲�
+ * 灏卞彧鑳介潬绔埌绔墠楠屽緱鍑烘潵銆�
+ */
+ static String userDisplay(String realName, String account) {
+ if (blank(realName)) {
+ return blank(account) ? null : account.trim();
+ }
+ return blank(account) ? realName.trim() : realName.trim() + "/" + account.trim();
+ }
+
+ private static boolean blank(String value) {
+ return value == null || value.trim().isEmpty();
+ }
+
+ interface UserLookup {
+ Map<String, String> names(String tenantId, Set<String> ids);
+ }
+
+ /** 琛ㄥ悕鍜屽垪鍚嶅浐瀹氾紱id 涓庣鎴峰叏閮ㄥ弬鏁板寲銆� */
+ private static final class JdbcUserLookup implements UserLookup {
+ private final NamedParameterJdbcTemplate jdbc;
+
+ private JdbcUserLookup(JdbcTemplate jdbcTemplate) {
+ this.jdbc = new NamedParameterJdbcTemplate(jdbcTemplate);
+ }
+
+ @Override
+ public Map<String, String> names(String tenantId, Set<String> ids) {
+ if (ids.isEmpty()) {
+ return Collections.emptyMap();
+ }
+ try {
+ MapSqlParameterSource params = new MapSqlParameterSource()
+ .addValue("ids", ids)
+ .addValue("tenantId", tenantId);
+ List<Map<String, Object>> rows = jdbc.queryForList(
+ "SELECT f_id, f_real_name, f_account FROM base_user "
+ + "WHERE f_id IN (:ids) "
+ + "AND COALESCE(NULLIF(f_tenant_id, ''), '0') = :tenantId",
+ params);
+ Map<String, String> result = new LinkedHashMap<>();
+ for (Map<String, Object> row : rows) {
+ String id = text(row.get("f_id"));
+ String display = userDisplay(text(row.get("f_real_name")),
+ text(row.get("f_account")));
+ if (id != null && display != null) {
+ result.put(id, display);
+ }
+ }
+ return result;
+ } catch (RuntimeException ex) {
+ log.warn("[AUDIT-QUERY] 鐢ㄦ埛鍚嶇О鎵归噺瑙f瀽澶辫触 count={} err={}",
+ ids.size(), ex.getClass().getSimpleName());
+ return Collections.emptyMap();
+ }
+ }
+
+ private static String text(Object value) {
+ if (value == null) {
+ return null;
+ }
+ String text = String.valueOf(value).trim();
+ return text.isEmpty() ? null : text;
+ }
+ }
+}
--
Gitblit v1.8.0