init
This commit is contained in:
34
ruoyi-common/ruoyi-common-translation/pom.xml
Normal file
34
ruoyi-common/ruoyi-common-translation/pom.xml
Normal file
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-common</artifactId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>ruoyi-common-translation</artifactId>
|
||||
|
||||
<description>
|
||||
ruoyi-common-translation 通用翻译功能
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- 序列化模块 -->
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-common-json</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- api模块 -->
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,32 @@
|
||||
package org.dromara.common.translation.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 通用翻译注解
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.FIELD, ElementType.METHOD})
|
||||
@Documented
|
||||
public @interface Translation {
|
||||
|
||||
/**
|
||||
* 类型 (需与实现类上的 {@link TranslationType} 注解type对应)
|
||||
* <p>
|
||||
* 默认取当前字段的值 如果设置了 @{@link Translation#mapper()} 则取映射字段的值
|
||||
*/
|
||||
String type();
|
||||
|
||||
/**
|
||||
* 映射字段 (如果不为空则取此字段的值)
|
||||
*/
|
||||
String mapper() default "";
|
||||
|
||||
/**
|
||||
* 其他条件 例如: 字典type(sys_user_gender)
|
||||
*/
|
||||
String other() default "";
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.dromara.common.translation.annotation;
|
||||
|
||||
import org.dromara.common.translation.core.TranslationInterface;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 翻译类型注解 (标注到{@link TranslationInterface} 的实现类)
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@Inherited
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.TYPE})
|
||||
@Documented
|
||||
public @interface TranslationType {
|
||||
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
String type();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.dromara.common.translation.config;
|
||||
|
||||
import org.dromara.common.translation.core.TranslationInterface;
|
||||
import org.dromara.common.translation.core.handler.TranslationJsonFieldProcessor;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 翻译模块配置类
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@AutoConfiguration
|
||||
public class TranslationConfig {
|
||||
|
||||
/**
|
||||
* 创建翻译 JSON 字段处理器。
|
||||
*
|
||||
* @param list 翻译实现集合
|
||||
* @return 翻译 JSON 字段处理器
|
||||
*/
|
||||
@Bean
|
||||
public TranslationJsonFieldProcessor translationJsonFieldProcessor(List<TranslationInterface<?>> list) {
|
||||
return new TranslationJsonFieldProcessor(list);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package org.dromara.common.translation.constant;
|
||||
|
||||
/**
|
||||
* 翻译常量
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
public interface TransConstant {
|
||||
|
||||
/**
|
||||
* 用户id转账号
|
||||
*/
|
||||
String USER_ID_TO_NAME = "user_id_to_name";
|
||||
|
||||
/**
|
||||
* 用户id转用户昵称
|
||||
*/
|
||||
String USER_ID_TO_NICKNAME = "user_id_to_nickname";
|
||||
|
||||
/**
|
||||
* 部门id转名称
|
||||
*/
|
||||
String DEPT_ID_TO_NAME = "dept_id_to_name";
|
||||
|
||||
/**
|
||||
* 字典type转label
|
||||
*/
|
||||
String DICT_TYPE_TO_LABEL = "dict_type_to_label";
|
||||
|
||||
/**
|
||||
* ossId转url
|
||||
*/
|
||||
String OSS_ID_TO_URL = "oss_id_to_url";
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package org.dromara.common.translation.core;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import org.dromara.common.core.utils.StreamUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.translation.annotation.TranslationType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* 翻译接口 (实现类需标注 {@link TranslationType} 注解标明翻译类型)
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
public interface TranslationInterface<T> {
|
||||
|
||||
Logger log = LoggerFactory.getLogger(TranslationInterface.class);
|
||||
|
||||
/**
|
||||
* 按翻译键执行转换。
|
||||
*
|
||||
* @param key 需要被翻译的键(不为空)
|
||||
* @param other 其他参数
|
||||
* @return 返回键对应的翻译值
|
||||
*/
|
||||
T translation(Object key, String other);
|
||||
|
||||
/**
|
||||
* 批量翻译。
|
||||
*
|
||||
* @param keys 需要被翻译的键集合
|
||||
* @param other 其他参数
|
||||
* @return 翻译结果映射
|
||||
*/
|
||||
default Map<Object, T> translationBatch(Set<Object> keys, String other) {
|
||||
TranslationType annotation = this.getClass().getAnnotation(TranslationType.class);
|
||||
String type = annotation != null ? annotation.type() : this.getClass().getSimpleName();
|
||||
log.warn("翻译类型 [{}] 未覆盖 translationBatch 方法,已退化为逐条查询,建议实现批量查询以提升性能", type);
|
||||
Map<Object, T> result = new LinkedHashMap<>(keys.size());
|
||||
for (Object key : keys) {
|
||||
result.put(key, translation(key, other));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 收集 Long 类型键集合。
|
||||
*
|
||||
* @param keys 原始键集合
|
||||
* @return Long 键集合
|
||||
*/
|
||||
default Set<Long> collectLongIds(Collection<Object> keys) {
|
||||
Set<Long> result = new LinkedHashSet<>();
|
||||
for (Object key : keys) {
|
||||
if (key instanceof String ids) {
|
||||
result.addAll(parseLongIds(ids));
|
||||
} else if (key != null) {
|
||||
result.add(Convert.toLong(key));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析逗号分隔的 Long ID 列表。
|
||||
*
|
||||
* @param ids 逗号分隔字符串
|
||||
* @return Long 列表
|
||||
*/
|
||||
default List<Long> parseLongIds(String ids) {
|
||||
return StreamUtils.toList(
|
||||
StreamUtils.filter(Arrays.asList(ids.split(StringUtils.SEPARATOR)), StringUtils::isNotBlank),
|
||||
value -> Convert.toLong(value.trim())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 按原始 ID 顺序拼接映射值。
|
||||
*
|
||||
* @param ids 原始 ID 字符串
|
||||
* @param mapper ID 到值的映射函数
|
||||
* @param <E> 值类型
|
||||
* @return 拼接后的结果字符串
|
||||
*/
|
||||
default <E> String joinMappedValues(String ids, Function<Long, E> mapper) {
|
||||
return StreamUtils.join(parseLongIds(ids), id -> {
|
||||
E value = mapper.apply(id);
|
||||
return value == null ? null : String.valueOf(value);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
package org.dromara.common.translation.core.handler;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.core.utils.reflect.ReflectUtils;
|
||||
import org.dromara.common.json.enhance.JsonEnhancementContext;
|
||||
import org.dromara.common.json.enhance.JsonFieldContext;
|
||||
import org.dromara.common.json.enhance.JsonFieldProcessor;
|
||||
import org.dromara.common.translation.annotation.Translation;
|
||||
import org.dromara.common.translation.annotation.TranslationType;
|
||||
import org.dromara.common.translation.core.TranslationInterface;
|
||||
import org.springframework.core.annotation.Order;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 翻译响应处理器。
|
||||
*/
|
||||
@Slf4j
|
||||
@Order(0)
|
||||
public class TranslationJsonFieldProcessor implements JsonFieldProcessor {
|
||||
|
||||
/**
|
||||
* 响应增强上下文中保存待批量翻译数据的属性键。
|
||||
*/
|
||||
private static final String ATTR_BATCHES = TranslationJsonFieldProcessor.class.getName() + ".batches";
|
||||
|
||||
/**
|
||||
* 响应增强上下文中保存批量翻译结果的属性键。
|
||||
*/
|
||||
private static final String ATTR_RESULTS = TranslationJsonFieldProcessor.class.getName() + ".results";
|
||||
|
||||
/**
|
||||
* 翻译类型与翻译实现映射。
|
||||
*/
|
||||
private final Map<String, TranslationInterface<?>> translationMap;
|
||||
|
||||
/**
|
||||
* 构造翻译响应处理器。
|
||||
*
|
||||
* @param translations 翻译实现列表
|
||||
*/
|
||||
public TranslationJsonFieldProcessor(List<TranslationInterface<?>> translations) {
|
||||
Map<String, TranslationInterface<?>> map = new LinkedHashMap<>(translations.size());
|
||||
for (TranslationInterface<?> t : translations) {
|
||||
TranslationType annotation = t.getClass().getAnnotation(TranslationType.class);
|
||||
if (annotation != null) {
|
||||
map.put(annotation.type(), t);
|
||||
}
|
||||
}
|
||||
this.translationMap = Collections.unmodifiableMap(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断字段是否包含翻译注解。
|
||||
*
|
||||
* @param fieldContext 字段上下文
|
||||
* @return true 需要处理 false 无需处理
|
||||
*/
|
||||
@Override
|
||||
public boolean supports(JsonFieldContext fieldContext) {
|
||||
return fieldContext.getAnnotation(Translation.class) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 收集字段上的翻译注解和原始值,供后续批量翻译使用。
|
||||
*
|
||||
* @param fieldContext 字段上下文
|
||||
* @param context 响应增强上下文
|
||||
*/
|
||||
@Override
|
||||
public void collect(JsonFieldContext fieldContext, JsonEnhancementContext context) {
|
||||
Translation translation = fieldContext.getAnnotation(Translation.class);
|
||||
if (translation == null) {
|
||||
return;
|
||||
}
|
||||
Object sourceValue = resolveSourceValue(fieldContext, translation);
|
||||
if (sourceValue == null) {
|
||||
return;
|
||||
}
|
||||
Map<TranslationBatchKey, Set<Object>> batches = getOrCreateBatches(context);
|
||||
batches.computeIfAbsent(new TranslationBatchKey(translation.type(), translation.other()), key -> new LinkedHashSet<>())
|
||||
.add(sourceValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据收集到的原始值执行批量翻译,并将翻译结果写入响应增强上下文。
|
||||
*
|
||||
* @param context 响应增强上下文
|
||||
*/
|
||||
@Override
|
||||
public void prepare(JsonEnhancementContext context) {
|
||||
Map<TranslationBatchKey, Set<Object>> batches = context.getAttribute(ATTR_BATCHES);
|
||||
if (batches == null || batches.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Map<TranslationBatchKey, Map<Object, Object>> results = new LinkedHashMap<>(batches.size());
|
||||
for (Map.Entry<TranslationBatchKey, Set<Object>> entry : batches.entrySet()) {
|
||||
TranslationInterface<?> translation = getTranslation(entry.getKey().type());
|
||||
if (translation == null) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
Map<Object, ?> translated = translation.translationBatch(entry.getValue(), entry.getKey().other());
|
||||
results.put(entry.getKey(), new LinkedHashMap<>(translated));
|
||||
} catch (Exception e) {
|
||||
log.error("批量翻译处理异常,type: {}, other: {}", entry.getKey().type(), entry.getKey().other(), e);
|
||||
}
|
||||
}
|
||||
context.setAttribute(ATTR_RESULTS, results);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理单个字段的翻译值,优先使用批量翻译结果,缺失时回退到单值翻译。
|
||||
*
|
||||
* @param fieldContext 字段上下文
|
||||
* @param value 当前字段值
|
||||
* @param context 响应增强上下文
|
||||
* @return 翻译后的字段值
|
||||
*/
|
||||
@Override
|
||||
public Object process(JsonFieldContext fieldContext, Object value, JsonEnhancementContext context) {
|
||||
Translation translation = fieldContext.getAnnotation(Translation.class);
|
||||
if (translation == null) {
|
||||
return value;
|
||||
}
|
||||
Object sourceValue = resolveSourceValue(fieldContext, translation);
|
||||
if (sourceValue == null) {
|
||||
return value;
|
||||
}
|
||||
TranslationBatchKey batchKey = new TranslationBatchKey(translation.type(), translation.other());
|
||||
Map<TranslationBatchKey, Map<Object, Object>> results = context.getAttribute(ATTR_RESULTS);
|
||||
if (results != null) {
|
||||
Map<Object, Object> translatedMap = results.get(batchKey);
|
||||
if (translatedMap != null && translatedMap.containsKey(sourceValue)) {
|
||||
return translatedMap.get(sourceValue);
|
||||
}
|
||||
}
|
||||
TranslationInterface<?> trans = getTranslation(translation.type());
|
||||
if (ObjectUtil.isNull(trans)) {
|
||||
return value;
|
||||
}
|
||||
try {
|
||||
return trans.translation(sourceValue, translation.other());
|
||||
} catch (Exception e) {
|
||||
log.error("翻译处理异常,type: {}, value: {}", translation.type(), sourceValue, e);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取或创建待批量翻译数据映射。
|
||||
*
|
||||
* @param context 响应增强上下文
|
||||
* @return 待批量翻译数据映射
|
||||
*/
|
||||
private Map<TranslationBatchKey, Set<Object>> getOrCreateBatches(JsonEnhancementContext context) {
|
||||
return context.getOrCreateAttribute(ATTR_BATCHES, LinkedHashMap::new);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析翻译原始值。
|
||||
*
|
||||
* @param fieldContext 字段上下文
|
||||
* @param translation 翻译注解
|
||||
* @return 翻译原始值
|
||||
*/
|
||||
private Object resolveSourceValue(JsonFieldContext fieldContext, Translation translation) {
|
||||
if (StringUtils.isNotBlank(translation.mapper())) {
|
||||
return ReflectUtils.invokeGetter(fieldContext.owner(), translation.mapper());
|
||||
}
|
||||
return fieldContext.value();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据翻译类型获取翻译实现。
|
||||
*
|
||||
* @param type 翻译类型
|
||||
* @return 翻译实现
|
||||
*/
|
||||
private TranslationInterface<?> getTranslation(String type) {
|
||||
return translationMap.get(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量翻译分组键。
|
||||
*
|
||||
* @param type 翻译类型
|
||||
* @param other 额外参数
|
||||
*/
|
||||
private record TranslationBatchKey(String type, String other) {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package org.dromara.common.translation.core.impl;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.dromara.common.translation.annotation.TranslationType;
|
||||
import org.dromara.common.translation.constant.TransConstant;
|
||||
import org.dromara.common.translation.core.TranslationInterface;
|
||||
import org.dromara.system.api.DeptService;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 部门翻译实现
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@TranslationType(type = TransConstant.DEPT_ID_TO_NAME)
|
||||
public class DeptNameTranslationImpl implements TranslationInterface<String> {
|
||||
|
||||
private final DeptService deptService;
|
||||
|
||||
/**
|
||||
* 将部门 ID 或 ID 集合翻译为部门名称。
|
||||
*
|
||||
* @param key 部门 ID 或逗号分隔的 ID 字符串
|
||||
* @param other 额外参数
|
||||
* @return 部门名称
|
||||
*/
|
||||
@Override
|
||||
public String translation(Object key, String other) {
|
||||
if (key instanceof String ids) {
|
||||
return deptService.selectDeptNameByIds(ids);
|
||||
} else if (key instanceof Long id) {
|
||||
return deptService.selectDeptNameByIds(id.toString());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量将部门 ID 翻译为部门名称。
|
||||
*
|
||||
* @param keys 部门 ID 集合
|
||||
* @param other 额外参数
|
||||
* @return 部门 ID 与部门名称映射
|
||||
*/
|
||||
@Override
|
||||
public Map<Object, String> translationBatch(Set<Object> keys, String other) {
|
||||
Set<Long> deptIds = collectLongIds(keys);
|
||||
if (deptIds.isEmpty()) {
|
||||
return Map.of();
|
||||
}
|
||||
Map<Long, String> deptNames = deptService.selectDeptNamesByIds(deptIds);
|
||||
Map<Object, String> result = new LinkedHashMap<>(keys.size());
|
||||
for (Object key : keys) {
|
||||
result.put(key, buildValue(key, deptNames));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据原始键构建部门名称翻译值。
|
||||
*
|
||||
* @param source 原始键
|
||||
* @param deptNames 部门 ID 与部门名称映射
|
||||
* @return 部门名称
|
||||
*/
|
||||
private String buildValue(Object source, Map<Long, String> deptNames) {
|
||||
if (source instanceof String ids) {
|
||||
return joinMappedValues(ids, deptNames::get);
|
||||
}
|
||||
return source == null ? null : deptNames.get(Convert.toLong(source));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package org.dromara.common.translation.core.impl;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.dromara.common.core.service.DictService;
|
||||
import org.dromara.common.core.utils.StreamUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.translation.annotation.TranslationType;
|
||||
import org.dromara.common.translation.constant.TransConstant;
|
||||
import org.dromara.common.translation.core.TranslationInterface;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 字典翻译实现
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@TranslationType(type = TransConstant.DICT_TYPE_TO_LABEL)
|
||||
public class DictTypeTranslationImpl implements TranslationInterface<String> {
|
||||
|
||||
private final DictService dictService;
|
||||
|
||||
/**
|
||||
* 根据字典类型和字典值翻译显示标签。
|
||||
*
|
||||
* @param key 字典值
|
||||
* @param other 字典类型
|
||||
* @return 字典标签
|
||||
*/
|
||||
@Override
|
||||
public String translation(Object key, String other) {
|
||||
if (key instanceof String dictValue && StringUtils.isNotBlank(other)) {
|
||||
return dictService.getDictLabel(other, dictValue);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量根据字典类型和字典值翻译显示标签。
|
||||
*
|
||||
* @param keys 字典值集合
|
||||
* @param other 字典类型
|
||||
* @return 字典值与字典标签映射
|
||||
*/
|
||||
@Override
|
||||
public Map<Object, String> translationBatch(Set<Object> keys, String other) {
|
||||
if (keys.isEmpty() || StringUtils.isBlank(other)) {
|
||||
return Map.of();
|
||||
}
|
||||
Map<String, String> dictMap = dictService.getAllDictByDictType(other);
|
||||
Map<Object, String> result = new LinkedHashMap<>(keys.size());
|
||||
for (Object key : keys) {
|
||||
if (key instanceof String dictValue) {
|
||||
result.put(key, StreamUtils.join(
|
||||
StreamUtils.filter(Arrays.asList(dictValue.split(",")), StringUtils::isNotBlank),
|
||||
value -> dictMap.get(value.trim())
|
||||
));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package org.dromara.common.translation.core.impl;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.dromara.common.translation.annotation.TranslationType;
|
||||
import org.dromara.common.translation.constant.TransConstant;
|
||||
import org.dromara.common.translation.core.TranslationInterface;
|
||||
import org.dromara.system.api.UserService;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 用户昵称翻译实现
|
||||
*
|
||||
* @author may
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@TranslationType(type = TransConstant.USER_ID_TO_NICKNAME)
|
||||
public class NicknameTranslationImpl implements TranslationInterface<String> {
|
||||
|
||||
private final UserService userService;
|
||||
|
||||
/**
|
||||
* 将用户 ID 或 ID 集合翻译为用户昵称。
|
||||
*
|
||||
* @param key 用户 ID 或逗号分隔的 ID 字符串
|
||||
* @param other 额外参数
|
||||
* @return 用户昵称
|
||||
*/
|
||||
@Override
|
||||
public String translation(Object key, String other) {
|
||||
if (key instanceof Long id) {
|
||||
return userService.selectNicknameById(id);
|
||||
} else if (key instanceof String ids) {
|
||||
return userService.selectNicknameByIds(ids);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量将用户 ID 翻译为用户昵称。
|
||||
*
|
||||
* @param keys 用户 ID 集合
|
||||
* @param other 额外参数
|
||||
* @return 用户 ID 与用户昵称映射
|
||||
*/
|
||||
@Override
|
||||
public Map<Object, String> translationBatch(Set<Object> keys, String other) {
|
||||
Set<Long> userIds = collectLongIds(keys);
|
||||
if (userIds.isEmpty()) {
|
||||
return Map.of();
|
||||
}
|
||||
Map<Long, String> userNames = userService.selectUserNicksByIds(userIds);
|
||||
Map<Object, String> result = new LinkedHashMap<>(keys.size());
|
||||
for (Object key : keys) {
|
||||
result.put(key, buildValue(key, userNames));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据原始键构建用户昵称翻译值。
|
||||
*
|
||||
* @param source 原始键
|
||||
* @param userNames 用户 ID 与用户昵称映射
|
||||
* @return 用户昵称
|
||||
*/
|
||||
private String buildValue(Object source, Map<Long, String> userNames) {
|
||||
if (source instanceof String ids) {
|
||||
return joinMappedValues(ids, userNames::get);
|
||||
}
|
||||
return source == null ? null : userNames.get(Convert.toLong(source));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package org.dromara.common.translation.core.impl;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.dromara.common.core.utils.StreamUtils;
|
||||
import org.dromara.common.translation.annotation.TranslationType;
|
||||
import org.dromara.common.translation.constant.TransConstant;
|
||||
import org.dromara.common.translation.core.TranslationInterface;
|
||||
import org.dromara.system.api.OssService;
|
||||
import org.dromara.system.api.domain.OssDTO;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* OSS翻译实现
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@TranslationType(type = TransConstant.OSS_ID_TO_URL)
|
||||
public class OssUrlTranslationImpl implements TranslationInterface<String> {
|
||||
|
||||
private final OssService ossService;
|
||||
|
||||
/**
|
||||
* 将 OSS ID 或 ID 集合翻译为访问地址。
|
||||
*
|
||||
* @param key OSS ID 或逗号分隔的 ID 字符串
|
||||
* @param other 额外参数
|
||||
* @return 访问地址
|
||||
*/
|
||||
@Override
|
||||
public String translation(Object key, String other) {
|
||||
if (key instanceof String ids) {
|
||||
return ossService.selectUrlByIds(ids);
|
||||
} else if (key instanceof Long id) {
|
||||
return ossService.selectUrlByIds(id.toString());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量将 OSS ID 翻译为访问地址。
|
||||
*
|
||||
* @param keys OSS ID 集合
|
||||
* @param other 额外参数
|
||||
* @return OSS ID 与访问地址映射
|
||||
*/
|
||||
@Override
|
||||
public Map<Object, String> translationBatch(Set<Object> keys, String other) {
|
||||
Set<Long> ossIds = collectLongIds(keys);
|
||||
if (ossIds.isEmpty()) {
|
||||
return Map.of();
|
||||
}
|
||||
String idText = ossIds.stream().map(String::valueOf).collect(Collectors.joining(","));
|
||||
Map<Long, String> ossUrls = new LinkedHashMap<>(StreamUtils.toMap(ossService.selectByIds(idText), OssDTO::getOssId, OssDTO::getUrl));
|
||||
Map<Object, String> result = new LinkedHashMap<>(keys.size());
|
||||
for (Object key : keys) {
|
||||
result.put(key, buildValue(key, ossUrls));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据原始键构建 OSS 地址翻译值。
|
||||
*
|
||||
* @param source 原始键
|
||||
* @param ossUrls OSS ID 与访问地址映射
|
||||
* @return OSS 访问地址
|
||||
*/
|
||||
private String buildValue(Object source, Map<Long, String> ossUrls) {
|
||||
if (source instanceof String ids) {
|
||||
return joinMappedValues(ids, ossUrls::get);
|
||||
}
|
||||
return source == null ? null : ossUrls.get(Convert.toLong(source));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package org.dromara.common.translation.core.impl;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.dromara.common.core.utils.StreamUtils;
|
||||
import org.dromara.common.translation.annotation.TranslationType;
|
||||
import org.dromara.common.translation.constant.TransConstant;
|
||||
import org.dromara.common.translation.core.TranslationInterface;
|
||||
import org.dromara.system.api.UserService;
|
||||
import org.dromara.system.api.domain.UserDTO;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 用户名翻译实现
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@TranslationType(type = TransConstant.USER_ID_TO_NAME)
|
||||
public class UserNameTranslationImpl implements TranslationInterface<String> {
|
||||
|
||||
private final UserService userService;
|
||||
|
||||
/**
|
||||
* 将用户 ID 翻译为用户名。
|
||||
*
|
||||
* @param key 用户 ID
|
||||
* @param other 额外参数
|
||||
* @return 用户名
|
||||
*/
|
||||
@Override
|
||||
public String translation(Object key, String other) {
|
||||
return userService.selectUserNameById(Convert.toLong(key));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量将用户 ID 翻译为用户名。
|
||||
*
|
||||
* @param keys 用户 ID 集合
|
||||
* @param other 额外参数
|
||||
* @return 用户 ID 与用户名映射
|
||||
*/
|
||||
@Override
|
||||
public Map<Object, String> translationBatch(Set<Object> keys, String other) {
|
||||
Set<Long> userIds = collectLongIds(keys);
|
||||
if (userIds.isEmpty()) {
|
||||
return Map.of();
|
||||
}
|
||||
Map<Long, String> userNames = new LinkedHashMap<>(StreamUtils.toMap(userService.selectListByIds(userIds), UserDTO::getUserId, UserDTO::getUserName));
|
||||
Map<Object, String> result = new LinkedHashMap<>(keys.size());
|
||||
for (Object key : keys) {
|
||||
result.put(key, buildValue(key, userNames));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据原始键构建用户名翻译值。
|
||||
*
|
||||
* @param source 原始键
|
||||
* @param userNames 用户 ID 与用户名映射
|
||||
* @return 用户名
|
||||
*/
|
||||
private String buildValue(Object source, Map<Long, String> userNames) {
|
||||
if (source instanceof String ids) {
|
||||
return joinMappedValues(ids, userNames::get);
|
||||
}
|
||||
return userNames.get(Convert.toLong(source));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
org.dromara.common.translation.config.TranslationConfig
|
||||
org.dromara.common.translation.core.impl.DeptNameTranslationImpl
|
||||
org.dromara.common.translation.core.impl.DictTypeTranslationImpl
|
||||
org.dromara.common.translation.core.impl.OssUrlTranslationImpl
|
||||
org.dromara.common.translation.core.impl.UserNameTranslationImpl
|
||||
org.dromara.common.translation.core.impl.NicknameTranslationImpl
|
||||
Reference in New Issue
Block a user