package com.vincent.rsf.server.manager.utils;
|
|
|
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.system.entity.User;
|
import com.vincent.rsf.server.system.service.UserService;
|
|
import java.lang.reflect.Field;
|
import java.util.*;
|
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;
|
|
public static <T> Map<Long, String> userNameMap(List<T> records){
|
if (Cools.isEmpty(records)) {
|
return Collections.emptyMap();
|
}
|
Set<Long> collect = records.stream()
|
.filter(Objects::nonNull)
|
.flatMap(item -> Stream.of(
|
readUserId(item, "createBy"),
|
readUserId(item, "updateBy")
|
))
|
.filter(Objects::nonNull)
|
.collect(Collectors.toSet());
|
|
Map<Long, String> userNameMap = loadUserNameMap(collect);
|
fillUserNameFields(records, userNameMap);
|
return userNameMap;
|
}
|
|
private static Long readUserId(Object record, String fieldName) {
|
if (record == null || Cools.isEmpty(fieldName)) {
|
return null;
|
}
|
Field field = Cools.getField(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;
|
}
|
if (value instanceof Number) {
|
return ((Number) value).longValue();
|
}
|
if (value instanceof String && !((String) value).trim().isEmpty()) {
|
return Long.parseLong(((String) value).trim());
|
}
|
} 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);
|
continue;
|
}
|
userNameMap.put(userId, cachedUserName);
|
}
|
if (missingUserIds.isEmpty()) {
|
return userNameMap;
|
}
|
UserService userService = SpringUtils.getBean(UserService.class);
|
Map<Long, String> loadedUserNameMap = userService.listByIds(missingUserIds)
|
.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;
|
}
|
|
private static RedisService getRedisService() {
|
try {
|
return SpringUtils.getBean(RedisService.class);
|
} catch (Exception ignored) {
|
return null;
|
}
|
}
|
|
private static String getCachedUserName(RedisService redisService, Long userId) {
|
if (redisService == null || userId == null) {
|
return null;
|
}
|
try {
|
String value = redisService.getValue(USER_NAME_CACHE_FLAG, String.valueOf(userId));
|
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)) {
|
return;
|
}
|
userNameMap.forEach((userId, userName) -> {
|
if (userId == null || Cools.isEmpty(userName)) {
|
return;
|
}
|
try {
|
redisService.setValue(USER_NAME_CACHE_FLAG, String.valueOf(userId), userName, USER_NAME_CACHE_TTL_SECONDS);
|
} catch (Exception ignored) {
|
}
|
});
|
}
|
|
private static <T> void fillUserNameFields(List<T> records, Map<Long, String> userNameMap) {
|
if (Cools.isEmpty(records) || Cools.isEmpty(userNameMap)) {
|
return;
|
}
|
records.stream()
|
.filter(Objects::nonNull)
|
.forEach(record -> {
|
writeUserName(record, "createBy$", userNameMap.get(readUserId(record, "createBy")));
|
writeUserName(record, "updateBy$", userNameMap.get(readUserId(record, "updateBy")));
|
});
|
}
|
|
private static void writeUserName(Object record, String fieldName, String userName) {
|
if (record == null || Cools.isEmpty(fieldName) || userName == null) {
|
return;
|
}
|
Field field = Cools.getField(record.getClass(), fieldName);
|
if (field == null || !String.class.equals(field.getType())) {
|
return;
|
}
|
boolean accessible = field.isAccessible();
|
try {
|
field.setAccessible(true);
|
field.set(record, userName);
|
} catch (IllegalAccessException ignored) {
|
} finally {
|
field.setAccessible(accessible);
|
}
|
}
|
}
|