From 1dcfa3702505f0c431757312b5304531029f90f6 Mon Sep 17 00:00:00 2001
From: zhou zhou <3272660260@qq.com>
Date: 星期四, 09 四月 2026 18:57:38 +0800
Subject: [PATCH] #getter$摘出entity

---
 rsf-server/src/main/java/com/vincent/rsf/server/manager/utils/buildPageRowsUtils.java |  976 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 917 insertions(+), 59 deletions(-)

diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/utils/buildPageRowsUtils.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/utils/buildPageRowsUtils.java
index daa0467..47bd756 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/utils/buildPageRowsUtils.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/utils/buildPageRowsUtils.java
@@ -1,51 +1,653 @@
 package com.vincent.rsf.server.manager.utils;
 
-
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
 import com.vincent.rsf.framework.common.Cools;
 import com.vincent.rsf.framework.common.SpringUtils;
 import com.vincent.rsf.server.common.service.RedisService;
+import com.vincent.rsf.server.common.domain.PageResult;
+import com.vincent.rsf.server.manager.entity.Companys;
+import com.vincent.rsf.server.manager.entity.Warehouse;
+import com.vincent.rsf.server.manager.entity.WarehouseAreas;
+import com.vincent.rsf.server.manager.service.CompanysService;
+import com.vincent.rsf.server.manager.service.WarehouseService;
+import com.vincent.rsf.server.system.constant.DictTypeCode;
+import com.vincent.rsf.server.system.entity.DictData;
 import com.vincent.rsf.server.system.entity.User;
+import com.vincent.rsf.server.system.service.DictDataService;
 import com.vincent.rsf.server.system.service.UserService;
 
 import java.lang.reflect.Field;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Consumer;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
 public class buildPageRowsUtils {
 
     private static final String USER_NAME_CACHE_FLAG = "PAGE_ROWS_USER_NAME";
-    private static final int USER_NAME_CACHE_TTL_SECONDS = 300;
+    private static final String WAREHOUSE_NAME_CACHE_FLAG = "PAGE_ROWS_WAREHOUSE_NAME";
+    private static final String COMPANY_NAME_CACHE_FLAG = "PAGE_ROWS_COMPANY_NAME";
+    private static final int NAME_CACHE_TTL_SECONDS = 300;
+    private static final List<IdFieldMapping> COMMON_ID_FIELD_MAPPINGS = List.of(
+            new IdFieldMapping("tenantId", "tenantId$", com.vincent.rsf.server.system.service.TenantService.class, "name"),
+            new IdFieldMapping("deptId", "deptId$", com.vincent.rsf.server.system.service.DeptService.class, "name"),
+            new IdFieldMapping("dictTypeId", "dictTypeId$", com.vincent.rsf.server.system.service.DictTypeService.class, "name"),
+            new IdFieldMapping("userId", "userId$", UserService.class, "nickname"),
+            new IdFieldMapping("root", "root$", UserService.class, "username"),
+            new IdFieldMapping("warehouseId", "warehouseId$", WarehouseService.class, "name"),
+            new IdFieldMapping("warehouse", "warehouse$", WarehouseService.class, "name"),
+            new IdFieldMapping("area", "area$", com.vincent.rsf.server.manager.service.WarehouseAreasService.class, "name"),
+            new IdFieldMapping("areaId", "areaId$", com.vincent.rsf.server.manager.service.WarehouseAreasService.class, "name"),
+            new IdFieldMapping("shipperId", "shipperId$", CompanysService.class, "name"),
+            new IdFieldMapping("supplierId", "supplierId$", CompanysService.class, "name"),
+            new IdFieldMapping("splrId", "splrId$", CompanysService.class, "name"),
+            new IdFieldMapping("groupId", "groupId$", com.vincent.rsf.server.manager.service.MatnrGroupService.class, "name"),
+            new IdFieldMapping("locId", "locId$", com.vincent.rsf.server.manager.service.LocService.class, "code"),
+            new IdFieldMapping("locTypeId", "locTypeId$", com.vincent.rsf.server.manager.service.LocTypeService.class, "name")
+    );
+    private static final Map<Class<?>, Consumer<List<Object>>> SPECIAL_RECORD_ENRICHERS = createSpecialRecordEnrichers();
+    private static final Map<Class<?>, Map<String, Optional<Field>>> FIELD_CACHE = new ConcurrentHashMap<>();
+    private static final Map<Class<?>, Optional<Field>> ID_FIELD_CACHE = new ConcurrentHashMap<>();
 
-    public static <T> Map<Long, String> userNameMap(List<T> records){
+    public static <T> T rowsMap(T data) {
+        if (data == null) {
+            return null;
+        }
+        if (data instanceof Page<?> page) {
+            rowsMapCollection(page.getRecords());
+            return data;
+        }
+        if (data instanceof PageResult<?> pageResult) {
+            rowsMapCollection(pageResult.getRecords());
+            return data;
+        }
+        if (data instanceof Collection<?> collection) {
+            rowsMapCollection(collection);
+            return data;
+        }
+        if (data.getClass().isArray()) {
+            int length = java.lang.reflect.Array.getLength(data);
+            List<Object> records = new ArrayList<>(length);
+            for (int i = 0; i < length; i++) {
+                records.add(java.lang.reflect.Array.get(data, i));
+            }
+            rowsMapCollection(records);
+            return data;
+        }
+        rowsMapCollection(Collections.singletonList(data));
+        return data;
+    }
+
+    public static <T> Map<Long, String> userNameMap(List<T> records) {
         if (Cools.isEmpty(records)) {
             return Collections.emptyMap();
         }
-        Set<Long> collect = records.stream()
+        Set<Long> userIds = records.stream()
                 .filter(Objects::nonNull)
                 .flatMap(item -> Stream.of(
-                        readUserId(item, "createBy"),
-                        readUserId(item, "updateBy")
+                        readLongId(item, "createBy"),
+                        readLongId(item, "updateBy")
                 ))
                 .filter(Objects::nonNull)
                 .collect(Collectors.toSet());
 
-        Map<Long, String> userNameMap = loadUserNameMap(collect);
+        Map<Long, String> userNameMap = loadUserNameMap(userIds);
         fillUserNameFields(records, userNameMap);
         return userNameMap;
     }
 
-    private static Long readUserId(Object record, String fieldName) {
+    public static void warehouseAreasRowsMap(List<WarehouseAreas> records) {
+        if (Cools.isEmpty(records)) {
+            return;
+        }
+        Set<Long> userIds = records.stream()
+                .filter(Objects::nonNull)
+                .flatMap(item -> Stream.of(item.getCreateBy(), item.getUpdateBy()))
+                .filter(Objects::nonNull)
+                .collect(Collectors.toSet());
+        Set<Long> warehouseIds = records.stream()
+                .map(WarehouseAreas::getWarehouseId)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toSet());
+        Set<Long> companyIds = records.stream()
+                .filter(Objects::nonNull)
+                .flatMap(item -> Stream.of(
+                        item.getShipperId(),
+                        item.getSupplierId() == null ? null : item.getSupplierId().longValue()
+                ))
+                .filter(Objects::nonNull)
+                .collect(Collectors.toCollection(LinkedHashSet::new));
+        Set<String> typeValues = records.stream()
+                .map(WarehouseAreas::getType)
+                .filter(type -> !Cools.isEmpty(type))
+                .collect(Collectors.toCollection(LinkedHashSet::new));
+
+        Map<Long, String> userNameMap = loadUserNameMap(userIds);
+        Map<Long, String> warehouseNameMap = loadWarehouseNameMap(warehouseIds);
+        Map<Long, String> companyNameMap = loadCompanyNameMap(companyIds);
+        Map<String, String> typeLabelMap = loadDictLabelMap(typeValues, DictTypeCode.SYS_WARE_AREAS_TYPE);
+
+        records.stream()
+                .filter(Objects::nonNull)
+                .forEach(record -> {
+                    record.setCreateBy$(userNameMap.get(record.getCreateBy()));
+                    record.setUpdateBy$(userNameMap.get(record.getUpdateBy()));
+                    record.setWarehouseId$(warehouseNameMap.get(record.getWarehouseId()));
+                    record.setShipperId$(companyNameMap.get(record.getShipperId()));
+                    record.setSupplierId$(record.getSupplierId() == null ? null : companyNameMap.get(record.getSupplierId().longValue()));
+                    record.setType$(Cools.isEmpty(record.getType()) ? "" : typeLabelMap.get(record.getType()));
+                });
+    }
+
+    private static void rowsMapCollection(Collection<?> sourceRecords) {
+        if (Cools.isEmpty(sourceRecords)) {
+            return;
+        }
+        Map<Class<?>, List<Object>> recordsByClass = new LinkedHashMap<>();
+        for (Object record : sourceRecords) {
+            if (record == null) {
+                continue;
+            }
+            recordsByClass.computeIfAbsent(record.getClass(), key -> new ArrayList<>()).add(record);
+        }
+        recordsByClass.forEach(buildPageRowsUtils::rowsMapByClass);
+    }
+
+    private static void rowsMapByClass(Class<?> recordClass, List<Object> records) {
+        if (recordClass == null || Cools.isEmpty(records)) {
+            return;
+        }
+        if (WarehouseAreas.class.isAssignableFrom(recordClass)) {
+            warehouseAreasRowsMap(records.stream()
+                    .map(WarehouseAreas.class::cast)
+                    .collect(Collectors.toList()));
+            return;
+        }
+        userNameMap(records);
+        applyCommonIdFieldMappings(records);
+        Consumer<List<Object>> enricher = findSpecialRecordEnricher(recordClass);
+        if (enricher != null) {
+            enricher.accept(records);
+        }
+        fillUserRoleIds(records);
+    }
+
+    private static void applyCommonIdFieldMappings(List<Object> records) {
+        for (IdFieldMapping mapping : COMMON_ID_FIELD_MAPPINGS) {
+            fillFieldById(records, mapping.sourceField(), mapping.targetField(), mapping.serviceClass(), mapping.returnField());
+        }
+    }
+
+    private static Map<Class<?>, Consumer<List<Object>>> createSpecialRecordEnrichers() {
+        Map<Class<?>, Consumer<List<Object>>> enrichers = new LinkedHashMap<>();
+        registerSpecialEnricher(enrichers, "com.vincent.rsf.server.system.entity.SerialRule", records -> fillDictField(records, "reset", "reset$", "sys_rule_type"));
+        registerSpecialEnricher(enrichers, "com.vincent.rsf.server.system.entity.SerialRuleItem", records -> fillDictField(records, "wkType", "wkType$", "sys_rule_item_type"));
+        registerSpecialEnricher(enrichers, "com.vincent.rsf.server.manager.entity.AsnOrderLog", records -> {
+            fillDictField(records, "exceStatus", "exceStatus$", DictTypeCode.DICT_ASN_EXCE_STATUS);
+            fillDictField(records, "type", "type$", DictTypeCode.DICT_SYS_ORDER_TYPE);
+            fillDictField(records, "wkType", "wkType$", DictTypeCode.DICT_SYS_BUSINESS_TYPE);
+        });
+        registerSpecialEnricher(enrichers, "com.vincent.rsf.server.manager.entity.BasContainer", records -> fillDictField(records, "containerType", "containerType$", "sys_container_type"));
+        registerSpecialEnricher(enrichers, "com.vincent.rsf.server.manager.entity.BasStation", records -> {
+            fillDictField(records, "useStatus", "useStatus$", "sys_sta_use_stas");
+            fillDictIdsField(records, "containerType", "containerTypes$", "sys_container_type");
+        });
+        registerSpecialEnricher(enrichers, "com.vincent.rsf.server.manager.entity.BasStationArea", records -> fillDictField(records, "useStatus", "useStatus$", "sys_sta_use_stas"));
+        registerSpecialEnricher(enrichers, "com.vincent.rsf.server.manager.entity.CheckDiff", records -> fillDictField(records, "exceStatus", "exceStatus$", DictTypeCode.SYS_CHECK_DIFF_EXCE_STATUS));
+        registerSpecialEnricher(enrichers, "com.vincent.rsf.server.manager.entity.CheckDiffItem", records -> fillDictField(records, "exceStatus", "exceStatus$", DictTypeCode.SYS_CHECK_DIFF_EXCE_STATUS));
+        registerSpecialEnricher(enrichers, "com.vincent.rsf.server.manager.entity.Companys", records -> fillDictField(records, "type", "companys$", DictTypeCode.DICT_COMPANY_TYPE));
+        registerSpecialEnricher(enrichers, "com.vincent.rsf.server.manager.entity.Delivery", records -> {
+            fillDictField(records, "exceStatus", "exceStatus$", DictTypeCode.SYS_PO_EXCE_STATUS);
+            fillDictField(records, "type", "type$", DictTypeCode.DICT_SYS_ORDER_TYPE);
+            fillDictField(records, "wkType", "wkType$", DictTypeCode.DICT_SYS_BUSINESS_TYPE);
+        });
+        registerSpecialEnricher(enrichers, "com.vincent.rsf.server.manager.entity.DeviceSite", records -> {
+            fillDictField(records, "type", "type$", DictTypeCode.DICT_SYS_TASK_TYPE);
+            fillDictField(records, "device", "device$", DictTypeCode.DICT_SYS_DEVICE_TYPE);
+        });
+        registerSpecialEnricher(enrichers, "com.vincent.rsf.server.manager.entity.Loc", buildPageRowsUtils::fillLocTypeNamesField);
+        registerSpecialEnricher(enrichers, "com.vincent.rsf.server.manager.entity.LocAreaMatRela", records ->
+                fillFieldById(records, "matnrId", "matnrId$", com.vincent.rsf.server.manager.service.MatnrService.class, "name"));
+        registerSpecialEnricher(enrichers, "com.vincent.rsf.server.manager.entity.LocItem", records -> {
+            fillDictField(records, "type", "type$", DictTypeCode.DICT_SYS_ORDER_TYPE);
+            fillDictField(records, "wkType", "wkType$", DictTypeCode.DICT_SYS_BUSINESS_TYPE);
+        });
+        registerSpecialEnricher(enrichers, "com.vincent.rsf.server.manager.entity.LocRevise", records -> fillDictField(records, "type", "type$", DictTypeCode.SYS_STOCK_REVISE_TYPE));
+        registerSpecialEnricher(enrichers, "com.vincent.rsf.server.manager.entity.LocTypeRela", records ->
+                fillFieldById(records, "locId", "areaId$", com.vincent.rsf.server.manager.service.LocService.class, "code"));
+        registerSpecialEnricher(enrichers, "com.vincent.rsf.server.manager.entity.Purchase", records -> {
+            fillDictField(records, "exceStatus", "exceStatus$", DictTypeCode.SYS_PO_EXCE_STATUS);
+            fillDictField(records, "type", "type$", DictTypeCode.DICT_SYS_ORDER_TYPE);
+            fillDictField(records, "wkType", "wkType$", DictTypeCode.DICT_SYS_BUSINESS_TYPE);
+        });
+        registerSpecialEnricher(enrichers, "com.vincent.rsf.server.manager.entity.QlyInspect", records -> {
+            fillDictField(records, "wkType", "wkType$", DictTypeCode.DICT_SYS_BUSINESS_TYPE);
+            fillDictField(records, "isptStatus", "isptStatus$", DictTypeCode.DICT_QLY_INSPECT_STATUS);
+        });
+        registerSpecialEnricher(enrichers, "com.vincent.rsf.server.manager.entity.QlyIsptItem", records -> {
+            fillDictField(records, "isptStatus", "isptStatus$", DictTypeCode.DICT_QLY_INSPECT_STATUS);
+            fillDictField(records, "isptResult", "isptResult$", DictTypeCode.DICT_INSPECT_RESULT);
+        });
+        registerSpecialEnricher(enrichers, "com.vincent.rsf.server.manager.entity.Stock", records -> {
+            fillDictField(records, "type", "type$", DictTypeCode.DICT_SYS_ORDER_TYPE);
+            fillDictField(records, "wkType", "wkType$", DictTypeCode.DICT_SYS_BUSINESS_TYPE);
+        });
+        registerSpecialEnricher(enrichers, "com.vincent.rsf.server.manager.entity.StockItem", records ->
+                fillFieldById(records, "matnrId", "matnrId$", com.vincent.rsf.server.manager.service.MatnrService.class, "unit"));
+        registerSpecialEnricher(enrichers, "com.vincent.rsf.server.manager.entity.Task", records -> {
+            fillDictFieldWithValue(records, "taskStatus", "taskStatus$", DictTypeCode.DICT_SYS_TASK_STATUS);
+            fillDictField(records, "warehType", "warehType$", DictTypeCode.DICT_SYS_DEVICE_TYPE);
+            fillStationNameWithId(records, "orgSite", "orgSite$");
+            fillStationNameWithId(records, "targSite", "targSite$");
+        });
+        registerSpecialEnricher(enrichers, "com.vincent.rsf.server.manager.entity.TaskItem", records -> {
+            fillDictField(records, "orderType", "orderType$", DictTypeCode.DICT_SYS_ORDER_TYPE);
+            fillDictField(records, "wkType", "wkType$", DictTypeCode.DICT_SYS_BUSINESS_TYPE);
+            fillDictField(records, "isptResult", "isptResult$", DictTypeCode.DICT_INSPECT_RESULT);
+        });
+        registerSpecialEnricher(enrichers, "com.vincent.rsf.server.manager.entity.TaskLog", records -> {
+            fillDictField(records, "taskStatus", "taskStatus$", DictTypeCode.DICT_SYS_TASK_STATUS);
+            fillDictField(records, "taskType", "taskType$", DictTypeCode.DICT_SYS_TASK_TYPE);
+        });
+        registerSpecialEnricher(enrichers, "com.vincent.rsf.server.manager.entity.Transfer", records -> {
+            fillDictField(records, "type", "type$", DictTypeCode.SYS_TRANSFER_TYPE);
+            fillDictField(records, "exceStatus", "exceStatus$", DictTypeCode.DICT_ASN_EXCE_STATUS);
+        });
+        registerSpecialEnricher(enrichers, "com.vincent.rsf.server.manager.entity.WaitPakin", records -> fillDictField(records, "ioStatus", "ioStatus$", DictTypeCode.SYS_ORDER_IN_STATUS));
+        registerSpecialEnricher(enrichers, "com.vincent.rsf.server.manager.entity.WaitPakinItem", records -> fillDictField(records, "isptResult", "isptResult$", DictTypeCode.DICT_INSPECT_RESULT));
+        registerSpecialEnricher(enrichers, "com.vincent.rsf.server.manager.entity.WaitPakinItemLog", records -> {
+            fillFieldById(records, "pakinId", "pakinId$", com.vincent.rsf.server.manager.service.WaitPakinService.class, "id");
+            fillFieldById(records, "matnrId", "matnrId$", com.vincent.rsf.server.manager.service.MatnrService.class, "unit");
+        });
+        registerSpecialEnricher(enrichers, "com.vincent.rsf.server.manager.entity.WarehouseAreasItem", records -> fillDictField(records, "isptResult", "isptResult$", DictTypeCode.DICT_INSPECT_RESULT));
+        registerSpecialEnricher(enrichers, "com.vincent.rsf.server.manager.entity.Wave", records -> fillDictFieldWithValue(records, "exceStatus", "exceStatus$", DictTypeCode.SYS_WAVE_EXCE_STATUS));
+        registerSpecialEnricher(enrichers, "com.vincent.rsf.server.manager.entity.WaveItem", records -> fillDictFieldWithValue(records, "exceStatus", "exceStatus$", DictTypeCode.SYS_WAVE_ITEM_EXCE_STATUS));
+        registerSpecialEnricher(enrichers, "com.vincent.rsf.server.manager.entity.WaveRule", records -> fillDictField(records, "type", "type$", DictTypeCode.SYS_WAVE_RULE_CODE));
+        registerSpecialEnricher(enrichers, "com.vincent.rsf.server.manager.entity.WkOrder", buildPageRowsUtils::fillWkOrderRows);
+        registerSpecialEnricher(enrichers, "com.vincent.rsf.server.manager.entity.WkOrderItem", records -> fillDictField(records, "isptResult", "isptResult$", DictTypeCode.DICT_INSPECT_RESULT));
+        return enrichers;
+    }
+
+    private static void registerSpecialEnricher(Map<Class<?>, Consumer<List<Object>>> enrichers, String className, Consumer<List<Object>> enricher) {
+        try {
+            enrichers.put(Class.forName(className), enricher);
+        } catch (ClassNotFoundException ignored) {
+        }
+    }
+
+    private static Consumer<List<Object>> findSpecialRecordEnricher(Class<?> recordClass) {
+        for (Map.Entry<Class<?>, Consumer<List<Object>>> entry : SPECIAL_RECORD_ENRICHERS.entrySet()) {
+            if (entry.getKey().isAssignableFrom(recordClass)) {
+                return entry.getValue();
+            }
+        }
+        return null;
+    }
+
+    private static void fillWkOrderRows(List<Object> records) {
+        fillDictField(records, "checkType", "checkType$", DictTypeCode.SYS_CHECK_TYPE);
+        fillDictField(records, "exceStatus", "exceStatus$", record -> Objects.equals(getStringFieldValue(record, "type"), com.vincent.rsf.server.manager.enums.OrderType.ORDER_CHECK.type)
+                ? DictTypeCode.SYS_CHECK_EXCE_STATUS
+                : DictTypeCode.DICT_ASN_EXCE_STATUS, false);
+        fillComputedStringField(records, "wkType$", record -> com.vincent.rsf.server.manager.enums.OrderWorkType.getWorkDesc(getStringFieldValue(record, "wkType")));
+    }
+
+    private static void fillComputedStringField(List<Object> records, String targetField, Function<Object, String> valueResolver) {
+        if (Cools.isEmpty(records) || !hasField(records.get(0), targetField) || valueResolver == null) {
+            return;
+        }
+        for (Object record : records) {
+            writeStringField(record, targetField, valueResolver.apply(record));
+        }
+    }
+
+    private static void fillDictField(List<Object> records, String sourceField, String targetField, String dictTypeCode) {
+        fillDictField(records, sourceField, targetField, record -> dictTypeCode, false);
+    }
+
+    private static void fillDictFieldWithValue(List<Object> records, String sourceField, String targetField, String dictTypeCode) {
+        fillDictField(records, sourceField, targetField, record -> dictTypeCode, true);
+    }
+
+    private static void fillDictField(List<Object> records,
+                                      String sourceField,
+                                      String targetField,
+                                      Function<Object, String> dictTypeResolver,
+                                      boolean appendValue) {
+        if (Cools.isEmpty(records) || !hasField(records.get(0), targetField) || dictTypeResolver == null) {
+            return;
+        }
+        Map<String, Set<String>> valuesByType = new LinkedHashMap<>();
+        for (Object record : records) {
+            String dictTypeCode = dictTypeResolver.apply(record);
+            String value = normalizeStringValue(readFieldValue(record, sourceField));
+            if (Cools.isEmpty(dictTypeCode) || Cools.isEmpty(value)) {
+                continue;
+            }
+            valuesByType.computeIfAbsent(dictTypeCode, key -> new LinkedHashSet<>()).add(value);
+        }
+        if (valuesByType.isEmpty()) {
+            return;
+        }
+        Map<String, Map<String, String>> labelMapByType = new HashMap<>();
+        valuesByType.forEach((dictTypeCode, values) -> labelMapByType.put(dictTypeCode, loadDictLabelMap(values, dictTypeCode)));
+        for (Object record : records) {
+            String dictTypeCode = dictTypeResolver.apply(record);
+            String value = normalizeStringValue(readFieldValue(record, sourceField));
+            if (Cools.isEmpty(dictTypeCode) || Cools.isEmpty(value)) {
+                continue;
+            }
+            String label = labelMapByType.getOrDefault(dictTypeCode, Collections.emptyMap()).get(value);
+            if (label == null) {
+                continue;
+            }
+            writeStringField(record, targetField, appendValue ? value + "." + label : label);
+        }
+    }
+
+    private static void fillDictIdsField(List<Object> records, String sourceField, String targetField, String dictTypeCode) {
+        if (Cools.isEmpty(records) || !hasField(records.get(0), targetField)) {
+            return;
+        }
+        Set<String> values = new LinkedHashSet<>();
+        for (Object record : records) {
+            Object sourceValue = readFieldValue(record, sourceField);
+            if (sourceValue instanceof Collection<?> collection) {
+                collection.stream()
+                        .map(buildPageRowsUtils::normalizeStringValue)
+                        .filter(item -> !Cools.isEmpty(item))
+                        .forEach(values::add);
+            }
+        }
+        if (values.isEmpty()) {
+            return;
+        }
+        List<?> dictDataList = listEntitiesByFieldIn(DictDataService.class, DictData.class, "value", values, Map.of("dictTypeCode", dictTypeCode));
+        Map<String, Long> dictIdMap = new HashMap<>();
+        for (Object dictData : dictDataList) {
+            String value = getStringFieldValue(dictData, "value");
+            Long id = getLongFieldValue(dictData, "id");
+            if (Cools.isEmpty(value) || id == null) {
+                continue;
+            }
+            dictIdMap.put(value, id);
+        }
+        for (Object record : records) {
+            Object sourceValue = readFieldValue(record, sourceField);
+            if (!(sourceValue instanceof Collection<?> collection)) {
+                continue;
+            }
+            List<Long> ids = collection.stream()
+                    .map(buildPageRowsUtils::normalizeStringValue)
+                    .map(dictIdMap::get)
+                    .filter(Objects::nonNull)
+                    .toList();
+            if (!ids.isEmpty()) {
+                writeField(record, targetField, ids);
+            }
+        }
+    }
+
+    private static void fillStationNameWithId(List<Object> records, String sourceField, String targetField) {
+        if (Cools.isEmpty(records) || !hasField(records.get(0), targetField)) {
+            return;
+        }
+        Set<String> stationNames = records.stream()
+                .map(record -> normalizeStringValue(readFieldValue(record, sourceField)))
+                .filter(item -> !Cools.isEmpty(item))
+                .collect(Collectors.toCollection(LinkedHashSet::new));
+        if (stationNames.isEmpty()) {
+            return;
+        }
+        List<?> stations = listEntitiesByFieldIn(
+                com.vincent.rsf.server.manager.service.BasStationService.class,
+                com.vincent.rsf.server.manager.entity.BasStation.class,
+                "stationName",
+                stationNames,
+                Collections.emptyMap()
+        );
+        Map<String, String> stationIdMap = new HashMap<>();
+        for (Object station : stations) {
+            String stationName = getStringFieldValue(station, "stationName");
+            String stationId = getStringFieldValue(station, "stationId");
+            if (Cools.isEmpty(stationName) || Cools.isEmpty(stationId)) {
+                continue;
+            }
+            stationIdMap.put(stationName, stationId);
+        }
+        for (Object record : records) {
+            String stationName = normalizeStringValue(readFieldValue(record, sourceField));
+            if (Cools.isEmpty(stationName)) {
+                continue;
+            }
+            String stationId = stationIdMap.get(stationName);
+            writeStringField(record, targetField, Cools.isEmpty(stationId) ? stationName : stationName + "(" + stationId + ")");
+        }
+    }
+
+    private static void fillLocTypeNamesField(List<Object> records) {
+        if (Cools.isEmpty(records) || !hasField(records.get(0), "typeIds$")) {
+            return;
+        }
+        Map<String, List<Long>> parsedIdsByValue = new HashMap<>();
+        Set<Long> allIds = new LinkedHashSet<>();
+        for (Object record : records) {
+            String value = normalizeStringValue(readFieldValue(record, "type"));
+            if (Cools.isEmpty(value)) {
+                continue;
+            }
+            List<Long> ids = parsedIdsByValue.computeIfAbsent(value, buildPageRowsUtils::parseLongIds);
+            allIds.addAll(ids);
+        }
+        if (allIds.isEmpty()) {
+            return;
+        }
+        Map<Long, String> nameMap = loadEntityFieldMap(com.vincent.rsf.server.manager.service.LocTypeService.class, allIds, "name");
+        for (Object record : records) {
+            String value = normalizeStringValue(readFieldValue(record, "type"));
+            List<Long> ids = value == null ? Collections.emptyList() : parsedIdsByValue.getOrDefault(value, Collections.emptyList());
+            if (ids.isEmpty()) {
+                continue;
+            }
+            List<String> names = ids.stream()
+                    .map(nameMap::get)
+                    .filter(item -> !Cools.isEmpty(item))
+                    .toList();
+            if (!names.isEmpty()) {
+                writeStringField(record, "typeIds$", String.join(",", names));
+            }
+        }
+    }
+
+    private static List<Long> parseLongIds(String value) {
+        if (Cools.isEmpty(value)) {
+            return Collections.emptyList();
+        }
+        return Stream.of(value.split(","))
+                .map(String::trim)
+                .filter(item -> !item.isEmpty())
+                .map(item -> {
+                    try {
+                        return Long.parseLong(item);
+                    } catch (NumberFormatException ignored) {
+                        return null;
+                    }
+                })
+                .filter(Objects::nonNull)
+                .toList();
+    }
+
+    private static String normalizeStringValue(Object value) {
+        if (value == null) {
+            return null;
+        }
+        String stringValue = String.valueOf(value).trim();
+        return stringValue.isEmpty() ? null : stringValue;
+    }
+
+    private static void fillUserRoleIds(List<Object> records) {
+        if (Cools.isEmpty(records) || !hasField(records.get(0), "userRoleIds")) {
+            return;
+        }
+        Set<Long> userIds = records.stream()
+                .map(record -> readLongId(record, "id"))
+                .filter(Objects::nonNull)
+                .collect(Collectors.toCollection(LinkedHashSet::new));
+        if (userIds.isEmpty()) {
+            return;
+        }
+        List<?> userRoles = listEntitiesByFieldIn(
+                com.vincent.rsf.server.system.service.UserRoleService.class,
+                com.vincent.rsf.server.system.entity.UserRole.class,
+                "userId",
+                userIds,
+                Collections.emptyMap()
+        );
+        Map<Long, List<Long>> userRoleMap = new HashMap<>();
+        for (Object userRole : userRoles) {
+            Long userId = getLongFieldValue(userRole, "userId");
+            Long roleId = getLongFieldValue(userRole, "roleId");
+            if (userId == null || roleId == null) {
+                continue;
+            }
+            userRoleMap.computeIfAbsent(userId, key -> new ArrayList<>()).add(roleId);
+        }
+        for (Object record : records) {
+            if (!hasField(record, "userRoleIds")) {
+                continue;
+            }
+            Long userId = readLongId(record, "id");
+            List<Long> roleIds = userId == null ? Collections.emptyList() : userRoleMap.getOrDefault(userId, Collections.emptyList());
+            writeField(record, "userRoleIds", roleIds.toArray(Long[]::new));
+        }
+    }
+
+    private static void fillFieldById(List<Object> records, String sourceField, String targetField, Class<?> serviceClass, String returnField) {
+        if (Cools.isEmpty(records) || !hasField(records.get(0), targetField) || !hasField(records.get(0), sourceField)) {
+            return;
+        }
+        Set<Long> ids = records.stream()
+                .map(record -> readLongId(record, sourceField))
+                .filter(Objects::nonNull)
+                .collect(Collectors.toCollection(LinkedHashSet::new));
+        if (ids.isEmpty()) {
+            return;
+        }
+        Map<Long, String> valueMap = loadEntityFieldMap(serviceClass, ids, returnField);
+        if (valueMap.isEmpty()) {
+            return;
+        }
+        for (Object record : records) {
+            if (!hasField(record, targetField)) {
+                continue;
+            }
+            writeStringField(record, targetField, valueMap.get(readLongId(record, sourceField)));
+        }
+    }
+
+    private static Map<Long, String> loadEntityFieldMap(Class<?> serviceClass, Set<Long> ids, String returnField) {
+        if (serviceClass == null || Cools.isEmpty(ids) || Cools.isEmpty(returnField)) {
+            return Collections.emptyMap();
+        }
+        IService<?> service = getServiceBean(serviceClass);
+        if (service == null) {
+            return Collections.emptyMap();
+        }
+        List<?> entities = service.listByIds(new ArrayList<>(ids));
+        if (Cools.isEmpty(entities)) {
+            return Collections.emptyMap();
+        }
+        Map<Long, String> valueMap = new HashMap<>();
+        for (Object entity : entities) {
+            Long id = readEntityId(entity);
+            Object value = readFieldValue(entity, returnField);
+            if (id == null || value == null) {
+                continue;
+            }
+            valueMap.put(id, String.valueOf(value));
+        }
+        return valueMap;
+    }
+
+    private static Long readEntityId(Object entity) {
+        if (entity == null) {
+            return null;
+        }
+        Field idField = getCachedIdField(entity.getClass());
+        if (idField != null) {
+            Object value = readFieldValue(entity, idField.getName());
+            if (value instanceof Number number) {
+                return number.longValue();
+            }
+        }
+        return getLongFieldValue(entity, "id");
+    }
+
+    public static String getDictLabel(String dictTypeCode, Object value) {
+        if (Cools.isEmpty(dictTypeCode) || value == null || Cools.isEmpty(String.valueOf(value))) {
+            return null;
+        }
+        Object dictData = getEntityByFields(
+                DictDataService.class,
+                DictData.class,
+                Map.of(
+                        "dictTypeCode", dictTypeCode,
+                        "value", value
+                )
+        );
+        return getStringFieldValue(dictData, "label");
+    }
+
+    public static String getDictLabelWithValue(String dictTypeCode, Object value) {
+        String label = getDictLabel(dictTypeCode, value);
+        if (label == null || value == null) {
+            return null;
+        }
+        return value + "." + label;
+    }
+
+    public static List<Long> getDictIds(String dictTypeCode, Collection<?> values) {
+        if (Cools.isEmpty(dictTypeCode) || Cools.isEmpty(values)) {
+            return Collections.emptyList();
+        }
+        List<?> dictDataList = listEntitiesByFieldIn(DictDataService.class, DictData.class, "value", values,
+                Map.of("dictTypeCode", dictTypeCode));
+        if (Cools.isEmpty(dictDataList)) {
+            return Collections.emptyList();
+        }
+        return dictDataList.stream()
+                .map(item -> getLongFieldValue(item, "id"))
+                .filter(Objects::nonNull)
+                .toList();
+    }
+
+    private static Long readLongId(Object record, String fieldName) {
         if (record == null || Cools.isEmpty(fieldName)) {
             return null;
         }
-        Field field = Cools.getField(record.getClass(), fieldName);
+        Field field = getCachedField(record.getClass(), fieldName);
         if (field == null) {
             return null;
         }
-        boolean accessible = field.isAccessible();
         try {
-            field.setAccessible(true);
             Object value = field.get(record);
             if (value instanceof Long) {
                 return (Long) value;
@@ -58,45 +660,117 @@
             }
         } catch (IllegalAccessException | NumberFormatException ignored) {
             return null;
-        } finally {
-            field.setAccessible(accessible);
         }
         return null;
     }
 
     private static Map<Long, String> loadUserNameMap(Set<Long> userIds) {
-        if (Cools.isEmpty(userIds)) {
-            return Collections.emptyMap();
-        }
-        List<Long> normalizedUserIds = userIds.stream()
-                .filter(Objects::nonNull)
-                .toList();
-        if (normalizedUserIds.isEmpty()) {
-            return Collections.emptyMap();
-        }
         RedisService redisService = getRedisService();
-        Map<Long, String> userNameMap = new HashMap<>();
-        List<Long> missingUserIds = new ArrayList<>();
-        for (Long userId : normalizedUserIds) {
-            String cachedUserName = getCachedUserName(redisService, userId);
-            if (cachedUserName == null) {
-                missingUserIds.add(userId);
+        return loadNameMap(
+                userIds,
+                userId -> getCachedName(redisService, userId, USER_NAME_CACHE_FLAG),
+                missingUserIds -> SpringUtils.getBean(UserService.class).listByIds(missingUserIds),
+                User::getId,
+                User::getNickname,
+                loadedUserNameMap -> cacheNames(redisService, loadedUserNameMap, USER_NAME_CACHE_FLAG)
+        );
+    }
+
+    private static Map<Long, String> loadWarehouseNameMap(Set<Long> warehouseIds) {
+        RedisService redisService = getRedisService();
+        return loadNameMap(
+                warehouseIds,
+                id -> getCachedName(redisService, id, WAREHOUSE_NAME_CACHE_FLAG),
+                missingIds -> SpringUtils.getBean(WarehouseService.class).listByIds(missingIds),
+                Warehouse::getId,
+                Warehouse::getName,
+                loadedNameMap -> cacheNames(redisService, loadedNameMap, WAREHOUSE_NAME_CACHE_FLAG)
+        );
+    }
+
+    private static Map<Long, String> loadCompanyNameMap(Set<Long> companyIds) {
+        RedisService redisService = getRedisService();
+        return loadNameMap(
+                companyIds,
+                id -> getCachedName(redisService, id, COMPANY_NAME_CACHE_FLAG),
+                missingIds -> SpringUtils.getBean(CompanysService.class).listByIds(missingIds),
+                Companys::getId,
+                Companys::getName,
+                loadedNameMap -> cacheNames(redisService, loadedNameMap, COMPANY_NAME_CACHE_FLAG)
+        );
+    }
+
+    private static Map<String, String> loadDictLabelMap(Set<String> values, String dictTypeCode) {
+        if (Cools.isEmpty(values) || Cools.isEmpty(dictTypeCode)) {
+            return Collections.emptyMap();
+        }
+        List<String> normalizedValues = values.stream()
+                .filter(value -> !Cools.isEmpty(value))
+                .distinct()
+                .toList();
+        if (normalizedValues.isEmpty()) {
+            return Collections.emptyMap();
+        }
+        DictDataService dictDataService;
+        try {
+            dictDataService = SpringUtils.getBean(DictDataService.class);
+        } catch (Exception ignored) {
+            return Collections.emptyMap();
+        }
+        List<DictData> dictDataList = dictDataService.list(
+                new LambdaQueryWrapper<DictData>()
+                        .eq(DictData::getDictTypeCode, dictTypeCode)
+                        .in(DictData::getValue, normalizedValues)
+        );
+        if (Cools.isEmpty(dictDataList)) {
+            return Collections.emptyMap();
+        }
+        return dictDataList.stream()
+                .filter(Objects::nonNull)
+                .filter(item -> !Cools.isEmpty(item.getValue()) && item.getLabel() != null)
+                .collect(Collectors.toMap(DictData::getValue, DictData::getLabel, (left, right) -> left));
+    }
+
+    private static <E> Map<Long, String> loadNameMap(Set<Long> ids,
+                                                     Function<Long, String> cacheGetter,
+                                                     Function<List<Long>, List<E>> entityLoader,
+                                                     Function<E, Long> idGetter,
+                                                     Function<E, String> nameGetter,
+                                                     Consumer<Map<Long, String>> cacheWriter) {
+        if (Cools.isEmpty(ids)) {
+            return Collections.emptyMap();
+        }
+        List<Long> normalizedIds = ids.stream()
+                .filter(Objects::nonNull)
+                .distinct()
+                .toList();
+        if (normalizedIds.isEmpty()) {
+            return Collections.emptyMap();
+        }
+        Map<Long, String> nameMap = new HashMap<>();
+        List<Long> missingIds = new ArrayList<>();
+        for (Long id : normalizedIds) {
+            String cachedName = cacheGetter.apply(id);
+            if (cachedName == null) {
+                missingIds.add(id);
                 continue;
             }
-            userNameMap.put(userId, cachedUserName);
+            nameMap.put(id, cachedName);
         }
-        if (missingUserIds.isEmpty()) {
-            return userNameMap;
+        if (missingIds.isEmpty()) {
+            return nameMap;
         }
-        UserService userService = SpringUtils.getBean(UserService.class);
-        Map<Long, String> loadedUserNameMap = userService.listByIds(missingUserIds)
-                .stream()
+        List<E> loadedEntities = entityLoader.apply(missingIds);
+        if (loadedEntities == null) {
+            return nameMap;
+        }
+        Map<Long, String> loadedNameMap = loadedEntities.stream()
                 .filter(Objects::nonNull)
-                .filter(user -> user.getId() != null && user.getNickname() != null)
-                .collect(Collectors.toMap(User::getId, User::getNickname, (left, right) -> left));
-        userNameMap.putAll(loadedUserNameMap);
-        cacheUserNames(redisService, loadedUserNameMap);
-        return userNameMap;
+                .filter(item -> idGetter.apply(item) != null && nameGetter.apply(item) != null)
+                .collect(Collectors.toMap(idGetter, nameGetter, (left, right) -> left));
+        nameMap.putAll(loadedNameMap);
+        cacheWriter.accept(loadedNameMap);
+        return nameMap;
     }
 
     private static RedisService getRedisService() {
@@ -107,28 +781,157 @@
         }
     }
 
-    private static String getCachedUserName(RedisService redisService, Long userId) {
-        if (redisService == null || userId == null) {
+    private static IService<?> getServiceBean(Class<?> serviceClass) {
+        try {
+            Object bean = SpringUtils.getBean(serviceClass);
+            return bean instanceof IService<?> iService ? iService : null;
+        } catch (Exception ignored) {
+            return null;
+        }
+    }
+
+    private static Object getEntityByFields(Class<?> serviceClass, Class<?> entityClass, Map<String, Object> conditions) {
+        List<?> entityList = listEntitiesByFields(serviceClass, entityClass, conditions, false);
+        return Cools.isEmpty(entityList) ? null : entityList.get(0);
+    }
+
+    private static List<?> listEntitiesByFieldIn(Class<?> serviceClass,
+                                                 Class<?> entityClass,
+                                                 String matchFieldName,
+                                                 Collection<?> matchValues,
+                                                 Map<String, Object> extraConditions) {
+        if (serviceClass == null || entityClass == null || Cools.isEmpty(matchFieldName) || Cools.isEmpty(matchValues)) {
+            return Collections.emptyList();
+        }
+        IService<?> service = getServiceBean(serviceClass);
+        if (service == null) {
+            return Collections.emptyList();
+        }
+        QueryWrapper<Object> queryWrapper = new QueryWrapper<>();
+        extraConditions.forEach((fieldName, value) -> queryWrapper.eq(resolveColumnName(entityClass, fieldName), value));
+        queryWrapper.in(resolveColumnName(entityClass, matchFieldName), matchValues);
+        return service.list((Wrapper) queryWrapper);
+    }
+
+    private static List<?> listEntitiesByFields(Class<?> serviceClass,
+                                                Class<?> entityClass,
+                                                Map<String, Object> conditions,
+                                                boolean all) {
+        if (serviceClass == null || entityClass == null || Cools.isEmpty(conditions)) {
+            return Collections.emptyList();
+        }
+        IService<?> service = getServiceBean(serviceClass);
+        if (service == null) {
+            return Collections.emptyList();
+        }
+        QueryWrapper<Object> queryWrapper = new QueryWrapper<>();
+        conditions.forEach((fieldName, value) -> queryWrapper.eq(resolveColumnName(entityClass, fieldName), value));
+        if (all) {
+            return service.list((Wrapper) queryWrapper);
+        }
+        Object entity = service.getOne((Wrapper) queryWrapper, false);
+        return entity == null ? Collections.emptyList() : Collections.singletonList(entity);
+    }
+
+    private static String resolveColumnName(Class<?> entityClass, String fieldName) {
+        Field field = getCachedField(entityClass, fieldName);
+        if (field == null) {
+            return camelToSnake(fieldName);
+        }
+        TableId tableId = field.getAnnotation(TableId.class);
+        if (tableId != null && !Cools.isEmpty(tableId.value())) {
+            return stripColumnQuotes(tableId.value());
+        }
+        TableField tableField = field.getAnnotation(TableField.class);
+        if (tableField != null && !Cools.isEmpty(tableField.value())) {
+            return stripColumnQuotes(tableField.value());
+        }
+        return camelToSnake(fieldName);
+    }
+
+    private static String stripColumnQuotes(String column) {
+        return column == null ? null : column.replace("`", "");
+    }
+
+    private static String camelToSnake(String value) {
+        if (Cools.isEmpty(value)) {
+            return value;
+        }
+        StringBuilder builder = new StringBuilder();
+        for (int i = 0; i < value.length(); i++) {
+            char current = value.charAt(i);
+            if (Character.isUpperCase(current)) {
+                if (i > 0) {
+                    builder.append('_');
+                }
+                builder.append(Character.toLowerCase(current));
+            } else {
+                builder.append(current);
+            }
+        }
+        return builder.toString();
+    }
+
+    private static String getStringFieldValue(Object entity, String fieldName) {
+        Object value = readFieldValue(entity, fieldName);
+        return value == null ? null : String.valueOf(value);
+    }
+
+    private static Long getLongFieldValue(Object entity, String fieldName) {
+        Object value = readFieldValue(entity, fieldName);
+        if (value instanceof Long longValue) {
+            return longValue;
+        }
+        if (value instanceof Number number) {
+            return number.longValue();
+        }
+        if (value instanceof String stringValue && !stringValue.isBlank()) {
+            try {
+                return Long.parseLong(stringValue.trim());
+            } catch (NumberFormatException ignored) {
+                return null;
+            }
+        }
+        return null;
+    }
+
+    private static Object readFieldValue(Object entity, String fieldName) {
+        if (entity == null || Cools.isEmpty(fieldName)) {
+            return null;
+        }
+        Field field = getCachedField(entity.getClass(), fieldName);
+        if (field == null) {
             return null;
         }
         try {
-            String value = redisService.getValue(USER_NAME_CACHE_FLAG, String.valueOf(userId));
+            return field.get(entity);
+        } catch (IllegalAccessException ignored) {
+            return null;
+        }
+    }
+
+    private static String getCachedName(RedisService redisService, Long id, String cacheFlag) {
+        if (redisService == null || id == null) {
+            return null;
+        }
+        try {
+            String value = redisService.getValue(cacheFlag, String.valueOf(id));
             return Cools.isEmpty(value) ? null : value;
         } catch (Exception ignored) {
             return null;
         }
     }
 
-    private static void cacheUserNames(RedisService redisService, Map<Long, String> userNameMap) {
-        if (redisService == null || Cools.isEmpty(userNameMap)) {
+    private static void cacheNames(RedisService redisService, Map<Long, String> nameMap, String cacheFlag) {
+        if (redisService == null || Cools.isEmpty(nameMap)) {
             return;
         }
-        userNameMap.forEach((userId, userName) -> {
-            if (userId == null || Cools.isEmpty(userName)) {
+        nameMap.forEach((id, name) -> {
+            if (id == null || Cools.isEmpty(name)) {
                 return;
             }
             try {
-                redisService.setValue(USER_NAME_CACHE_FLAG, String.valueOf(userId), userName, USER_NAME_CACHE_TTL_SECONDS);
+                redisService.setValue(cacheFlag, String.valueOf(id), name, NAME_CACHE_TTL_SECONDS);
             } catch (Exception ignored) {
             }
         });
@@ -141,26 +944,81 @@
         records.stream()
                 .filter(Objects::nonNull)
                 .forEach(record -> {
-                    writeUserName(record, "createBy$", userNameMap.get(readUserId(record, "createBy")));
-                    writeUserName(record, "updateBy$", userNameMap.get(readUserId(record, "updateBy")));
+                    writeStringField(record, "createBy$", userNameMap.get(readLongId(record, "createBy")));
+                    writeStringField(record, "updateBy$", userNameMap.get(readLongId(record, "updateBy")));
                 });
     }
 
-    private static void writeUserName(Object record, String fieldName, String userName) {
-        if (record == null || Cools.isEmpty(fieldName) || userName == null) {
+    private static void writeStringField(Object record, String fieldName, String fieldValue) {
+        if (record == null || Cools.isEmpty(fieldName) || fieldValue == null) {
             return;
         }
-        Field field = Cools.getField(record.getClass(), fieldName);
-        if (field == null || !String.class.equals(field.getType())) {
+        writeField(record, fieldName, fieldValue);
+    }
+
+    private static void writeField(Object record, String fieldName, Object fieldValue) {
+        if (record == null || Cools.isEmpty(fieldName) || fieldValue == null) {
             return;
         }
-        boolean accessible = field.isAccessible();
+        Field field = getCachedField(record.getClass(), fieldName);
+        if (field == null) {
+            return;
+        }
+        try {
+            field.set(record, fieldValue);
+        } catch (IllegalAccessException ignored) {
+        }
+    }
+
+    private static Field getCachedField(Class<?> type, String fieldName) {
+        if (type == null || Cools.isEmpty(fieldName)) {
+            return null;
+        }
+        return FIELD_CACHE
+                .computeIfAbsent(type, key -> new ConcurrentHashMap<>())
+                .computeIfAbsent(fieldName, key -> Optional.ofNullable(findField(type, key)))
+                .orElse(null);
+    }
+
+    private static Field getCachedIdField(Class<?> type) {
+        if (type == null) {
+            return null;
+        }
+        return ID_FIELD_CACHE.computeIfAbsent(type, key -> Optional.ofNullable(findIdField(key))).orElse(null);
+    }
+
+    private static Field findField(Class<?> type, String fieldName) {
+        Field field = Cools.getField(type, fieldName);
+        if (field == null) {
+            return null;
+        }
         try {
             field.setAccessible(true);
-            field.set(record, userName);
-        } catch (IllegalAccessException ignored) {
-        } finally {
-            field.setAccessible(accessible);
+        } catch (Exception ignored) {
         }
+        return field;
+    }
+
+    private static Field findIdField(Class<?> type) {
+        for (Class<?> current = type; current != null && !Object.class.equals(current); current = current.getSuperclass()) {
+            for (Field field : current.getDeclaredFields()) {
+                if (field.getAnnotation(TableId.class) == null) {
+                    continue;
+                }
+                try {
+                    field.setAccessible(true);
+                } catch (Exception ignored) {
+                }
+                return field;
+            }
+        }
+        return findField(type, "id");
+    }
+
+    private static boolean hasField(Object record, String fieldName) {
+        return record != null && !Cools.isEmpty(fieldName) && getCachedField(record.getClass(), fieldName) != null;
+    }
+
+    private record IdFieldMapping(String sourceField, String targetField, Class<?> serviceClass, String returnField) {
     }
 }

--
Gitblit v1.9.1