@ -1,5 +1,6 @@
package org.jeecg.common.aspect ;
import com.alibaba.fastjson.JSON ;
import com.alibaba.fastjson.JSONObject ;
import com.baomidou.mybatisplus.core.metadata.IPage ;
import com.fasterxml.jackson.annotation.JsonFormat ;
@ -14,17 +15,17 @@ import org.jeecg.common.api.CommonAPI;
import org.jeecg.common.api.vo.Result ;
import org.jeecg.common.aspect.annotation.Dict ;
import org.jeecg.common.constant.CommonConstant ;
import org.jeecg. modules.base.service.BaseCommonService ;
import org.jeecg. common.system.vo.DictModel ;
import org.jeecg.common.util.oConvertUtils ;
import org.springframework.beans.factory.annotation.Autowired ;
import org.springframework.data.redis.core.RedisTemplate ;
import org.springframework.stereotype.Component ;
import org.springframework.util.StringUtils ;
import java.lang.reflect.Field ;
import java.text.SimpleDateFormat ;
import java.util.ArrayList ;
import java.util.Date ;
import java.util.List ;
import java.util.* ;
import java.util.stream.Collectors ;
/ * *
* @Description : 字 典 aop 类
@ -56,7 +57,7 @@ public class DictAspect {
long start = System . currentTimeMillis ( ) ;
this . parseDictText ( result ) ;
long end = System . currentTimeMillis ( ) ;
log . debug ( " 解析 注入JSON数据 耗时"+ ( end - start ) + "ms" ) ;
log . debug ( " 注入字典到 JSON数据 耗时"+ ( end - start ) + "ms" ) ;
return result ;
}
@ -86,6 +87,12 @@ public class DictAspect {
if ( result instanceof Result ) {
if ( ( ( Result ) result ) . getResult ( ) instanceof IPage ) {
List < JSONObject > items = new ArrayList < > ( ) ;
//step.1 筛选出加了 Dict 注解的字段列表
List < Field > dictFieldList = new ArrayList < > ( ) ;
// 字典数据列表, key = 字典code, value=数据列表
Map < String , List < String > > dataListMap = new HashMap < > ( ) ;
for ( Object record : ( ( IPage ) ( ( Result ) result ) . getResult ( ) ) . getRecords ( ) ) {
ObjectMapper mapper = new ObjectMapper ( ) ;
String json = "{}" ;
@ -98,20 +105,28 @@ public class DictAspect {
JSONObject item = JSONObject . parseObject ( json ) ;
//update-begin--Author:scott -- Date:20190603 ----for: 解决继承实体字段无法翻译问题------
//for (Field field : record.getClass().getDeclaredFields()) {
// 遍历所有字段, 把字典Code取出来, 放到 map 里
for ( Field field : oConvertUtils . getAllFields ( record ) ) {
String value = item . getString ( field . getName ( ) ) ;
if ( oConvertUtils . isEmpty ( value ) ) {
continue ;
}
//update-end--Author:scott -- Date:20190603 ----for: 解决继承实体字段无法翻译问题------
if ( field . getAnnotation ( Dict . class ) ! = null ) {
if ( ! dictFieldList . contains ( field ) ) {
dictFieldList . add ( field ) ;
}
String code = field . getAnnotation ( Dict . class ) . dicCode ( ) ;
String text = field . getAnnotation ( Dict . class ) . dicText ( ) ;
String table = field . getAnnotation ( Dict . class ) . dictTable ( ) ;
String key = String . valueOf ( item . get ( field . getName ( ) ) ) ;
//翻译字典值对应的txt
String textValue = translateDictValue ( code , text , table , key ) ;
log . debug ( " 字典Val : " + textValue ) ;
log . debug ( " __翻译字典字段__ " + field . getName ( ) + CommonConstant . DICT_TEXT_SUFFIX + ": " + textValue ) ;
item . put ( field . getName ( ) + CommonConstant . DICT_TEXT_SUFFIX , textValue ) ;
List < String > dataList ;
String dictCode = code ;
if ( ! StringUtils . isEmpty ( table ) ) {
dictCode = String . format ( "%s,%s,%s" , table , text , code ) ;
}
dataList = dataListMap . computeIfAbsent ( dictCode , k - > new ArrayList < > ( ) ) ;
this . listAddAllDeduplicate ( dataList , Arrays . asList ( value . split ( "," ) ) ) ;
}
//date类型默认转换string格式化日期
if ( field . getType ( ) . getName ( ) . equals ( "java.util.Date" ) & & field . getAnnotation ( JsonFormat . class ) = = null & & item . get ( field . getName ( ) ) ! = null ) {
@ -121,12 +136,194 @@ public class DictAspect {
}
items . add ( item ) ;
}
//step.2 调用翻译方法,一次性翻译
Map < String , List < DictModel > > translText = this . translateAllDict ( dataListMap ) ;
//step.3 将翻译结果填充到返回结果里
for ( JSONObject record : items ) {
for ( Field field : dictFieldList ) {
String code = field . getAnnotation ( Dict . class ) . dicCode ( ) ;
String text = field . getAnnotation ( Dict . class ) . dicText ( ) ;
String table = field . getAnnotation ( Dict . class ) . dictTable ( ) ;
String fieldDictCode = code ;
if ( ! StringUtils . isEmpty ( table ) ) {
fieldDictCode = String . format ( "%s,%s,%s" , table , text , code ) ;
}
String value = record . getString ( field . getName ( ) ) ;
if ( oConvertUtils . isNotEmpty ( value ) ) {
List < DictModel > dictModels = translText . get ( fieldDictCode ) ;
if ( dictModels = = null | | dictModels . size ( ) = = 0 ) {
continue ;
}
String textValue = this . translDictText ( dictModels , value ) ;
log . debug ( " 字典Val : " + textValue ) ;
log . debug ( " __翻译字典字段__ " + field . getName ( ) + CommonConstant . DICT_TEXT_SUFFIX + ": " + textValue ) ;
// TODO-sun 测试输出,待删
log . debug ( " ---- dictCode: " + fieldDictCode ) ;
log . debug ( " ---- value: " + value ) ;
log . debug ( " ----- text: " + textValue ) ;
log . debug ( " ---- dictModels: " + JSON . toJSONString ( dictModels ) ) ;
record . put ( field . getName ( ) + CommonConstant . DICT_TEXT_SUFFIX , textValue ) ;
}
}
}
( ( IPage ) ( ( Result ) result ) . getResult ( ) ) . setRecords ( items ) ;
}
}
}
/ * *
* list 去 重 添 加
* /
private void listAddAllDeduplicate ( List < String > dataList , List < String > addList ) {
// 筛选出dataList中没有的数据
List < String > filterList = addList . stream ( ) . filter ( i - > ! dataList . contains ( i ) ) . collect ( Collectors . toList ( ) ) ;
dataList . addAll ( filterList ) ;
}
/ * *
* 一 次 性 把 所 有 的 字 典 都 翻 译 了
* 1. 所 有 的 普 通 数 据 字 典 的 所 有 数 据 只 执 行 一 次 SQL
* 2. 表 字 典 相 同 的 所 有 数 据 只 执 行 一 次 SQL
* @param dataListMap
* @return
* /
private Map < String , List < DictModel > > translateAllDict ( Map < String , List < String > > dataListMap ) {
// 翻译后的字典文本, key=dictCode
Map < String , List < DictModel > > translText = new HashMap < > ( ) ;
// 需要翻译的数据( 有些可以从redis缓存中获取, 就不走数据库查询)
List < String > needTranslData = new ArrayList < > ( ) ;
//step.1 先通过redis中获取缓存字典数据
for ( String dictCode : dataListMap . keySet ( ) ) {
List < String > dataList = dataListMap . get ( dictCode ) ;
if ( dataList . size ( ) = = 0 ) {
continue ;
}
// 表字典需要翻译的数据
List < String > needTranslDataTable = new ArrayList < > ( ) ;
for ( String s : dataList ) {
String data = s . trim ( ) ;
if ( data . length ( ) = = 0 ) {
continue ; //跳过循环
}
if ( dictCode . contains ( "," ) ) {
String keyString = String . format ( "sys:cache:dictTable::SimpleKey [%s,%s]" , dictCode , data ) ;
if ( redisTemplate . hasKey ( keyString ) ) {
try {
String text = oConvertUtils . getString ( redisTemplate . opsForValue ( ) . get ( keyString ) ) ;
List < DictModel > list = translText . computeIfAbsent ( dictCode , k - > new ArrayList < > ( ) ) ;
list . add ( new DictModel ( data , text ) ) ;
} catch ( Exception e ) {
log . warn ( e . getMessage ( ) ) ;
}
} else if ( ! needTranslDataTable . contains ( data ) ) {
// 去重添加
needTranslDataTable . add ( data ) ;
}
} else {
String keyString = String . format ( "sys:cache:dict::%s:%s" , dictCode , data ) ;
if ( redisTemplate . hasKey ( keyString ) ) {
try {
String text = oConvertUtils . getString ( redisTemplate . opsForValue ( ) . get ( keyString ) ) ;
List < DictModel > list = translText . computeIfAbsent ( dictCode , k - > new ArrayList < > ( ) ) ;
list . add ( new DictModel ( data , text ) ) ;
} catch ( Exception e ) {
log . warn ( e . getMessage ( ) ) ;
}
} else if ( ! needTranslData . contains ( data ) ) {
// 去重添加
needTranslData . add ( data ) ;
}
}
}
//step.2 调用数据库翻译表字典
if ( needTranslDataTable . size ( ) > 0 ) {
String [ ] arr = dictCode . split ( "," ) ;
String table = arr [ 0 ] , text = arr [ 1 ] , code = arr [ 2 ] ;
String values = String . join ( "," , needTranslDataTable ) ;
log . info ( "translateDictFromTableByKeys.dictCode:" + dictCode ) ;
log . info ( "translateDictFromTableByKeys.values:" + values ) ;
List < DictModel > texts = commonAPI . translateDictFromTableByKeys ( table , text , code , values ) ;
log . info ( "translateDictFromTableByKeys.result:" + texts ) ;
List < DictModel > list = translText . computeIfAbsent ( dictCode , k - > new ArrayList < > ( ) ) ;
list . addAll ( texts ) ;
// 做 redis 缓存
for ( DictModel dict : texts ) {
String redisKey = String . format ( "sys:cache:dictTable::SimpleKey [%s,%s]" , dictCode , dict . getValue ( ) ) ;
try {
redisTemplate . opsForValue ( ) . set ( redisKey , dict . getText ( ) ) ;
} catch ( Exception e ) {
log . warn ( e . getMessage ( ) , e ) ;
}
}
}
}
//step.3 调用数据库进行翻译普通字典
if ( needTranslData . size ( ) > 0 ) {
List < String > dictCodeList = Arrays . asList ( dataListMap . keySet ( ) . toArray ( new String [ ] { } ) ) ;
// 将不包含逗号的字典code筛选出来, 因为带逗号的是表字典, 而不是普通的数据字典
List < String > filterDictCodes = dictCodeList . stream ( ) . filter ( key - > ! key . contains ( "," ) ) . collect ( Collectors . toList ( ) ) ;
String dictCodes = String . join ( "," , filterDictCodes ) ;
String values = String . join ( "," , needTranslData ) ;
log . info ( "translateManyDict.dictCodes:" + dictCodes ) ;
log . info ( "translateManyDict.values:" + values ) ;
Map < String , List < DictModel > > manyDict = commonAPI . translateManyDict ( dictCodes , values ) ;
log . info ( "translateManyDict.result:" + manyDict ) ;
for ( String dictCode : manyDict . keySet ( ) ) {
List < DictModel > list = translText . computeIfAbsent ( dictCode , k - > new ArrayList < > ( ) ) ;
List < DictModel > newList = manyDict . get ( dictCode ) ;
list . addAll ( newList ) ;
// 做 redis 缓存
for ( DictModel dict : newList ) {
String redisKey = String . format ( "sys:cache:dict::%s:%s" , dictCode , dict . getValue ( ) ) ;
try {
redisTemplate . opsForValue ( ) . set ( redisKey , dict . getText ( ) ) ;
} catch ( Exception e ) {
log . warn ( e . getMessage ( ) , e ) ;
}
}
}
}
return translText ;
}
/ * *
* 字 典 值 替 换 文 本
*
* @param dictModels
* @param values
* @return
* /
private String translDictText ( List < DictModel > dictModels , String values ) {
List < String > result = new ArrayList < > ( ) ;
// 允许多个逗号分隔,允许传数组对象
String [ ] splitVal = values . split ( "," ) ;
for ( String val : splitVal ) {
String dictText = val ;
for ( DictModel dict : dictModels ) {
if ( val . equals ( dict . getValue ( ) ) ) {
dictText = dict . getText ( ) ;
break ;
}
}
result . add ( dictText ) ;
}
return String . join ( "," , result ) ;
}
/ * *
* 翻 译 字 典 文 本
* @param code
@ -135,6 +332,7 @@ public class DictAspect {
* @param key
* @return
* /
@Deprecated
private String translateDictValue ( String code , String text , String table , String key ) {
if ( oConvertUtils . isEmpty ( key ) ) {
return null ;