From 691bee4229856f8bf81c2720092ecee1c9f21509 Mon Sep 17 00:00:00 2001
From: zhou zhou <3272660260@qq.com>
Date: 星期四, 09 四月 2026 19:18:12 +0800
Subject: [PATCH] #getter$摘出entity
---
rsf-server/src/main/java/com/vincent/rsf/server/manager/utils/buildPageRowsUtils.java | 962 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 904 insertions(+), 58 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..ca537f5 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,615 @@
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.*;
+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.UserService;
+import com.vincent.rsf.server.system.service.*;
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 String DICT_LABEL_CACHE_FLAG = "PAGE_ROWS_DICT_LABEL";
+ private static final String ENTITY_FIELD_CACHE_FLAG = "PAGE_ROWS_ENTITY_FIELD";
+ private static final int NAME_CACHE_TTL_SECONDS = 300;
+ private static final Consumer<List<Object>> NO_OP_ENRICHER = records -> {
+ };
+ private static final List<IdFieldMapping> COMMON_ID_FIELD_MAPPINGS = List.of(
+ new IdFieldMapping("tenantId", "tenantId$", TenantService.class, "name"),
+ new IdFieldMapping("deptId", "deptId$", DeptService.class, "name"),
+ new IdFieldMapping("dictTypeId", "dictTypeId$", 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$", WarehouseAreasService.class, "name"),
+ new IdFieldMapping("areaId", "areaId$", 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$", MatnrGroupService.class, "name"),
+ new IdFieldMapping("locId", "locId$", LocService.class, "code"),
+ new IdFieldMapping("locTypeId", "locTypeId$", LocTypeService.class, "name")
+ );
+ private static final Map<Class<?>, Consumer<List<Object>>> SPECIAL_RECORD_ENRICHERS = createSpecialRecordEnrichers();
+ private static final Map<Class<?>, Consumer<List<Object>>> RESOLVED_ENRICHER_CACHE = new ConcurrentHashMap<>();
+ private static final Map<Class<?>, List<IdFieldMapping>> APPLICABLE_ID_FIELD_MAPPINGS_CACHE = new ConcurrentHashMap<>();
+ 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<>();
+ private static final Map<Class<?>, Map<String, String>> COLUMN_CACHE = new ConcurrentHashMap<>();
+ private static final Map<Class<?>, Optional<IService<?>>> SERVICE_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) || isSimpleValueType(recordClass)) {
+ return;
+ }
+ if (WarehouseAreas.class.isAssignableFrom(recordClass)) {
+ warehouseAreasRowsMap(records.stream()
+ .map(WarehouseAreas.class::cast)
+ .collect(Collectors.toList()));
+ return;
+ }
+ userNameMap(records);
+ applyCommonIdFieldMappings(recordClass, records);
+ Consumer<List<Object>> enricher = findSpecialRecordEnricher(recordClass);
+ if (enricher != null) {
+ enricher.accept(records);
+ }
+ fillUserRoleIds(records);
+ }
+
+ private static void applyCommonIdFieldMappings(Class<?> recordClass, List<Object> records) {
+ for (IdFieldMapping mapping : getApplicableIdFieldMappings(recordClass)) {
+ 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) {
+ Consumer<List<Object>> enricher = RESOLVED_ENRICHER_CACHE.computeIfAbsent(recordClass, buildPageRowsUtils::resolveSpecialRecordEnricher);
+ return enricher == NO_OP_ENRICHER ? null : enricher;
+ }
+
+ private static Consumer<List<Object>> resolveSpecialRecordEnricher(Class<?> recordClass) {
+ for (Map.Entry<Class<?>, Consumer<List<Object>>> entry : SPECIAL_RECORD_ENRICHERS.entrySet()) {
+ if (entry.getKey().isAssignableFrom(recordClass)) {
+ return entry.getValue();
+ }
+ }
+ return NO_OP_ENRICHER;
+ }
+
+ 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) {
+ 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) {
+ 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();
+ }
+ RedisService redisService = getRedisService();
+ String cacheFlag = buildEntityFieldCacheFlag(serviceClass, returnField);
+ return loadValueMap(
+ ids,
+ id -> getCachedStringValue(redisService, id, cacheFlag),
+ missingIds -> {
+ IService<?> service = getServiceBean(serviceClass);
+ return service == null ? Collections.emptyList() : service.listByIds(new ArrayList<>(missingIds));
+ },
+ buildPageRowsUtils::readEntityId,
+ entity -> normalizeStringValue(readFieldValue(entity, returnField)),
+ loadedValueMap -> cacheStringValues(redisService, loadedValueMap, cacheFlag)
+ );
+ }
+
+ 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");
+ }
+
+ 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 +622,116 @@
}
} 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()) {
+ RedisService redisService = getRedisService();
+ UserService userService = getServiceBean(UserService.class, UserService.class);
+ return loadValueMap(
+ userIds,
+ userId -> getCachedStringValue(redisService, userId, USER_NAME_CACHE_FLAG),
+ missingUserIds -> userService == null ? Collections.emptyList() : userService.listByIds(missingUserIds),
+ User::getId,
+ User::getNickname,
+ loadedUserNameMap -> cacheStringValues(redisService, loadedUserNameMap, USER_NAME_CACHE_FLAG)
+ );
+ }
+
+ private static Map<Long, String> loadWarehouseNameMap(Set<Long> warehouseIds) {
+ RedisService redisService = getRedisService();
+ WarehouseService warehouseService = getServiceBean(WarehouseService.class, WarehouseService.class);
+ return loadValueMap(
+ warehouseIds,
+ id -> getCachedStringValue(redisService, id, WAREHOUSE_NAME_CACHE_FLAG),
+ missingIds -> warehouseService == null ? Collections.emptyList() : warehouseService.listByIds(missingIds),
+ Warehouse::getId,
+ Warehouse::getName,
+ loadedNameMap -> cacheStringValues(redisService, loadedNameMap, WAREHOUSE_NAME_CACHE_FLAG)
+ );
+ }
+
+ private static Map<Long, String> loadCompanyNameMap(Set<Long> companyIds) {
+ RedisService redisService = getRedisService();
+ CompanysService companysService = getServiceBean(CompanysService.class, CompanysService.class);
+ return loadValueMap(
+ companyIds,
+ id -> getCachedStringValue(redisService, id, COMPANY_NAME_CACHE_FLAG),
+ missingIds -> companysService == null ? Collections.emptyList() : companysService.listByIds(missingIds),
+ Companys::getId,
+ Companys::getName,
+ loadedNameMap -> cacheStringValues(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();
}
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);
+ DictDataService dictDataService = getServiceBean(DictDataService.class, DictDataService.class);
+ String cacheFlag = buildDictLabelCacheFlag(dictTypeCode);
+ return loadValueMap(
+ values,
+ value -> getCachedStringValue(redisService, value, cacheFlag),
+ missingValues -> {
+ if (dictDataService == null) {
+ return Collections.emptyList();
+ }
+ return dictDataService.list(
+ new LambdaQueryWrapper<DictData>()
+ .eq(DictData::getDictTypeCode, dictTypeCode)
+ .in(DictData::getValue, missingValues)
+ );
+ },
+ DictData::getValue,
+ DictData::getLabel,
+ loadedLabelMap -> cacheStringValues(redisService, loadedLabelMap, cacheFlag)
+ );
+ }
+
+ private static <K, E> Map<K, String> loadValueMap(Set<K> keys,
+ Function<K, String> cacheGetter,
+ Function<List<K>, List<E>> entityLoader,
+ Function<E, K> keyGetter,
+ Function<E, String> valueGetter,
+ Consumer<Map<K, String>> cacheWriter) {
+ if (Cools.isEmpty(keys)) {
+ return Collections.emptyMap();
+ }
+ List<K> normalizedKeys = keys.stream()
+ .filter(Objects::nonNull)
+ .distinct()
+ .toList();
+ if (normalizedKeys.isEmpty()) {
+ return Collections.emptyMap();
+ }
+ Map<K, String> valueMap = new HashMap<>();
+ List<K> missingKeys = new ArrayList<>();
+ for (K key : normalizedKeys) {
+ String cachedValue = cacheGetter.apply(key);
+ if (cachedValue == null) {
+ missingKeys.add(key);
continue;
}
- userNameMap.put(userId, cachedUserName);
+ valueMap.put(key, cachedValue);
}
- if (missingUserIds.isEmpty()) {
- return userNameMap;
+ if (missingKeys.isEmpty()) {
+ return valueMap;
}
- UserService userService = SpringUtils.getBean(UserService.class);
- Map<Long, String> loadedUserNameMap = userService.listByIds(missingUserIds)
- .stream()
+ List<E> loadedEntities = entityLoader.apply(missingKeys);
+ if (loadedEntities == null) {
+ return valueMap;
+ }
+ Map<K, String> loadedValueMap = 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;
+ .map(item -> new java.util.AbstractMap.SimpleEntry<>(keyGetter.apply(item), valueGetter.apply(item)))
+ .filter(item -> item.getKey() != null && item.getValue() != null)
+ .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (left, right) -> left));
+ valueMap.putAll(loadedValueMap);
+ cacheWriter.accept(loadedValueMap);
+ return valueMap;
}
private static RedisService getRedisService() {
@@ -107,31 +742,171 @@
}
}
- private static String getCachedUserName(RedisService redisService, Long userId) {
- if (redisService == null || userId == null) {
+ private static IService<?> getServiceBean(Class<?> serviceClass) {
+ if (serviceClass == null) {
+ return null;
+ }
+ return SERVICE_CACHE.computeIfAbsent(serviceClass, key -> {
+ try {
+ Object bean = SpringUtils.getBean(key);
+ return bean instanceof IService<?> iService ? Optional.of(iService) : Optional.empty();
+ } catch (Exception ignored) {
+ return Optional.empty();
+ }
+ }).orElse(null);
+ }
+
+ private static <T> T getServiceBean(Class<?> serviceClass, Class<T> targetType) {
+ IService<?> serviceBean = getServiceBean(serviceClass);
+ return targetType != null && targetType.isInstance(serviceBean) ? targetType.cast(serviceBean) : null;
+ }
+
+ 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 String resolveColumnName(Class<?> entityClass, String fieldName) {
+ if (entityClass == null || Cools.isEmpty(fieldName)) {
+ return fieldName;
+ }
+ return COLUMN_CACHE
+ .computeIfAbsent(entityClass, key -> new ConcurrentHashMap<>())
+ .computeIfAbsent(fieldName, key -> resolveColumnNameInternal(entityClass, key));
+ }
+
+ private static String resolveColumnNameInternal(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 List<IdFieldMapping> getApplicableIdFieldMappings(Class<?> recordClass) {
+ if (recordClass == null) {
+ return Collections.emptyList();
+ }
+ return APPLICABLE_ID_FIELD_MAPPINGS_CACHE.computeIfAbsent(recordClass, key -> COMMON_ID_FIELD_MAPPINGS.stream()
+ .filter(mapping -> hasField(key, mapping.sourceField()) && hasField(key, mapping.targetField()))
+ .toList());
+ }
+
+ 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 getCachedStringValue(RedisService redisService, Object key, String cacheFlag) {
+ if (redisService == null || key == null || Cools.isEmpty(cacheFlag)) {
+ return null;
+ }
+ try {
+ String value = redisService.getValue(cacheFlag, String.valueOf(key));
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 cacheStringValues(RedisService redisService, Map<?, String> valueMap, String cacheFlag) {
+ if (redisService == null || Cools.isEmpty(valueMap) || Cools.isEmpty(cacheFlag)) {
return;
}
- userNameMap.forEach((userId, userName) -> {
- if (userId == null || Cools.isEmpty(userName)) {
+ valueMap.forEach((key, value) -> {
+ if (key == null || Cools.isEmpty(value)) {
return;
}
try {
- redisService.setValue(USER_NAME_CACHE_FLAG, String.valueOf(userId), userName, USER_NAME_CACHE_TTL_SECONDS);
+ redisService.setValue(cacheFlag, String.valueOf(key), value, NAME_CACHE_TTL_SECONDS);
} catch (Exception ignored) {
}
});
+ }
+
+ private static String buildDictLabelCacheFlag(String dictTypeCode) {
+ return DICT_LABEL_CACHE_FLAG + "." + dictTypeCode;
+ }
+
+ private static String buildEntityFieldCacheFlag(Class<?> serviceClass, String returnField) {
+ return ENTITY_FIELD_CACHE_FLAG + "." + serviceClass.getName() + "." + returnField;
}
private static <T> void fillUserNameFields(List<T> records, Map<Long, String> userNameMap) {
@@ -141,26 +916,97 @@
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(Class<?> recordClass, String fieldName) {
+ return recordClass != null && !Cools.isEmpty(fieldName) && getCachedField(recordClass, fieldName) != null;
+ }
+
+ private static boolean hasField(Object record, String fieldName) {
+ return record != null && hasField(record.getClass(), fieldName);
+ }
+
+ private static boolean isSimpleValueType(Class<?> type) {
+ return type != null
+ && (type.isPrimitive()
+ || Number.class.isAssignableFrom(type)
+ || CharSequence.class.isAssignableFrom(type)
+ || Boolean.class.isAssignableFrom(type)
+ || Character.class.isAssignableFrom(type)
+ || Enum.class.isAssignableFrom(type)
+ || java.util.Date.class.isAssignableFrom(type)
+ || java.time.temporal.Temporal.class.isAssignableFrom(type));
+ }
+
+ private record IdFieldMapping(String sourceField, String targetField, Class<?> serviceClass, String returnField) {
}
}
--
Gitblit v1.9.1