lyh
2025-01-21 7b3ff5b7c7bc669a3da292728c3a647de4fdac4f
修改流程  增加字典深度翻译 增加List翻译
已添加5个文件
已修改8个文件
765 ■■■■■ 文件已修改
lxzn-boot-base-core/src/main/java/org/jeecg/common/aspect/DictAspect.java 65 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-boot-base-core/src/main/java/org/jeecg/common/aspect/annotation/DictExt.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-boot-base-core/src/main/java/org/jeecg/common/aspect/annotation/FieldQuery.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/activiti/controller/AssignFileStreamController.java 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/activiti/service/IAssignFileStreamService.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/activiti/service/impl/AssignFileStreamServiceImpl.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/aspect/DncDictAspect.java 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/aspect/DicAspectService.java 311 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/aspect/FieldBatchQuery.java 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/mapper/SysDictMapper.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/SysDictMapper.xml 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/service/ISysDictService.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysDictServiceImpl.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-boot-base-core/src/main/java/org/jeecg/common/aspect/DictAspect.java
@@ -94,6 +94,12 @@
    private Object parseDictText(Object result) {
        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<>(5);
                //取出结果集
                List<Object> records=((IPage) ((Result) result).getResult()).getRecords();
                //update-begin--Author:zyf -- Date:20220606 ----for:【VUEN-1230】 åˆ¤æ–­æ˜¯å¦å«æœ‰å­—典注解,没有注解返回-----
@@ -101,58 +107,6 @@
                if(!hasDict){
                    return result;
                }
                List<JSONObject> dictText = getDictText(records);
                ((IPage) ((Result) result).getResult()).setRecords(dictText);
            }
            else {
                //取出结果集
                Object object=  (Object) ((Result) result).getResult();
                Class<?> aClass = ((Result) result).getResult().getClass();
                if ("java.util.HashMap".equals(aClass.getName())){
                    //将map转换为集合在转换为map
                    Map<String, Object> mapset = new HashMap<>();
                    Map<String,Object> map=  (Map<String,Object>) object;
                    for (String s : map.keySet()) {
                        Object a1 = map.get(s);
                        List<Object> records=new ArrayList<>();
                        Class<?> aClass1 = a1.getClass();
                        if ("java.util.ArrayList".equals(aClass1.getName())){
                            records = (ArrayList)map.get(s);
                        }else{
                            records = oConvertUtils.castList(a1, Object.class);
                        }
                        Boolean hasDict= checkHasDict(records);
                        if(!hasDict){
                            return result;
                        }
                        List<JSONObject> dictText = getDictText(records);
                        mapset.put(s,dictText);
                    }
                    ((Result) result).setResult(mapset);
                }else {
                    List<Object> records = oConvertUtils.castList(object, Object.class);
                    //update-begin--Author:zyf -- Date:20220606 ----for:【VUEN-1230】 åˆ¤æ–­æ˜¯å¦å«æœ‰å­—典注解,没有注解返回-----
                    Boolean hasDict= checkHasDict(records);
                    if(!hasDict){
                        return result;
                    }
                    List<JSONObject> dictText = getDictText(records);
                    ((Result) result).setResult(dictText);
                }
            }
        }
        return result;
    }
    /**
     ä¼ å…¥é›†åˆ ç¿»è¯‘字典值
     **/
    private List<JSONObject> getDictText(List<Object> records){
        List<JSONObject> items = new ArrayList<>();
        //step.1 ç­›é€‰å‡ºåŠ äº† Dict æ³¨è§£çš„字段列表
        List<Field> dictFieldList = new ArrayList<>();
        // å­—典数据列表, key = å­—å…¸code,value=数据列表
        Map<String, List<String>> dataListMap = new HashMap<>(5);
        log.debug(" __ è¿›å…¥å­—典翻译切面 DictAspect â€”— " );
        //update-end--Author:zyf -- Date:20220606 ----for:【VUEN-1230】 åˆ¤æ–­æ˜¯å¦å«æœ‰å­—典注解,没有注解返回-----
@@ -242,7 +196,12 @@
                }
            }
        }
        return items;
                ((IPage) ((Result) result).getResult()).setRecords(items);
            }
        }
        return result;
    }
    /**
lxzn-boot-base-core/src/main/java/org/jeecg/common/aspect/annotation/DictExt.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,38 @@
package org.jeecg.common.aspect.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * å­—典注解扩展,支持多字段匹配
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DictExt {
    /**
     * æ•°æ®å­—典表
     * @return
     */
    String dicTable() default "";
    /**
     * æ•°æ®Text
     * @return
     */
    String dicText() default "";
    /**
     * æ•°æ®code数组
     * @return
     */
    String[] dicCode();
    /**
     * æ•°æ®å‚数数组,参数跟code数组一一对应
     * @return
     */
    String[] dicParams();
}
lxzn-boot-base-core/src/main/java/org/jeecg/common/aspect/annotation/FieldQuery.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,37 @@
package org.jeecg.common.aspect.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * å­—典注解
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldQuery{
    /**
     * å…³è”数据表
     * @return
     */
    String dicTable() default "";
    /**
     * æ•°æ®Text
     * @return
     */
    String dicText() default "";
    /**
     * æ•°æ®code数组
     * @return
     */
    String[] dicCode();
    /**
     * æ•°æ®å‚数数组,参数跟code数组一一对应
     * @return
     */
    String[] dicParams();
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/activiti/controller/AssignFileStreamController.java
@@ -1,5 +1,6 @@
package org.jeecg.modules.activiti.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
@@ -52,11 +53,10 @@
    @AutoLog(value = "DNC流程操作-获取当前用户的待办及可拾取的任务")
    @ApiOperation(value = "DNC流程操作-获取当前用户的待办及可拾取的任务", notes = "DNC流程操作-获取当前用户的待办及可拾取的任务")
    @GetMapping("/find/task/list")
    public QueryListResponseResult<ActTaskExt> getUndoTaskList() {
        List<ActTaskExt> list = assignFileStreamService.getUndoTaskList();
        if(list == null)
            list = Collections.emptyList();
        return new QueryListResponseResult<>(CommonCode.SUCCESS, list);
    public Result<?> getUndoTaskList(@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                               @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
        IPage<ActTaskExt> actTaskExtIPage = assignFileStreamService.getUndoTaskList(pageNo,pageSize);
        return Result.ok(actTaskExtIPage);
    }
    @AutoLog(value = "DNC流程操作-批量指派到设备")
lxzn-module-dnc/src/main/java/org/jeecg/modules/activiti/service/IAssignFileStreamService.java
@@ -1,5 +1,6 @@
package org.jeecg.modules.activiti.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.common.api.vo.Result;
import org.jeecg.modules.activiti.entity.AssignFileStream;
@@ -38,7 +39,7 @@
     * èŽ·å–å½“å‰ç”¨æˆ·çš„å¾…åŠžåŠå¯æ‹¾å–çš„ä»»åŠ¡
     * @return
     */
    List<ActTaskExt> getUndoTaskList();
    IPage<ActTaskExt> getUndoTaskList(Integer pageNo, Integer pageSize);
    /**
     * å…³è”用户表 èŽ·å–ç”¨æˆ·æ˜µç§°
lxzn-module-dnc/src/main/java/org/jeecg/modules/activiti/service/impl/AssignFileStreamServiceImpl.java
@@ -512,7 +512,7 @@
    }
    @Override
    public List<ActTaskExt> getUndoTaskList() {
    public IPage<ActTaskExt> getUndoTaskList(Integer pageNo,Integer pageSize) {
        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        String userId = user.getId();
        if(!ValidateUtil.validateString(userId))
@@ -537,7 +537,10 @@
                ext.setAssignFileStream(streamDetail);
            extList.add(ext);
        });
        return extList;
        //封装Page
        IPage<ActTaskExt> page = new Page<>(pageNo,pageSize);
        page.setRecords(extList);
        return page;
    }
    @Override
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/aspect/DncDictAspect.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,80 @@
package org.jeecg.modules.dnc.aspect;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.jeecg.common.api.vo.Result;
import org.jeecg.modules.system.aspect.DicAspectService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.*;
/**
 * @Description: Dnc字典aopç±»
 * @Version: 1.0
 */
@Aspect
@Component
@Slf4j
public class DncDictAspect {
    @Autowired
    private DicAspectService dicAspectService;
    // å®šä¹‰åˆ‡ç‚¹Pointcut
    @Pointcut("execution(public * org.jeecg.modules.dnc..*.*Controller.*(..))")
    public void excudeService() {
    }
    @Around("excudeService()")
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
        long time1=System.currentTimeMillis();
        Object result = pjp.proceed();
        long time2=System.currentTimeMillis();
        log.debug("获取JSON数据 è€—时:"+(time2-time1)+"ms");
        long start=System.currentTimeMillis();
        this.parseDictText(result);
        long end=System.currentTimeMillis();
        log.debug("解析注入JSON数据  è€—æ—¶"+(end-start)+"ms");
        return result;
    }
    /**
     * æœ¬æ–¹æ³•针对返回对象为Result çš„IPage的分页列表数据进行动态字典注入
     * å­—典注入实现 é€šè¿‡å¯¹å®žä½“类添加注解@dict æ¥æ ‡è¯†éœ€è¦çš„字典内容,字典分为单字典code即可 ï¼Œtable字典 code table text配合使用与原来jeecg的用法相同
     * ç¤ºä¾‹ä¸ºSysUser   å­—段为sex æ·»åŠ äº†æ³¨è§£@Dict(dicCode = "sex") ä¼šåœ¨å­—典服务立马查出来对应的text ç„¶åŽåœ¨è¯·æ±‚list的时候将这个字典text,已字段名称加_dictText形式返回到前端
     * ä¾‹è¾“入当前返回值的就会多出一个sex_dictText字段
     * {
     *      sex:1,
     *      sex_dictText:"男"
     * }
     * å‰ç«¯ç›´æŽ¥å–值sext_dictText在table里面无需再进行前端的字典转换了
     *  customRender:function (text) {
     *               if(text==1){
     *                 return "男";
     *               }else if(text==2){
     *                 return "女";
     *               }else{
     *                 return text;
     *               }
     *             }
     *             ç›®å‰vue是这么进行字典渲染到table上的多了就很麻烦了 è¿™ä¸ªç›´æŽ¥åœ¨æœåŠ¡ç«¯æ¸²æŸ“å®Œæˆå‰ç«¯å¯ä»¥ç›´æŽ¥ç”¨
     * @param result
     */
    private void parseDictText(Object result) {
        if (result instanceof Result) {
            if (((Result) result).getResult() instanceof IPage) {
                List<JSONObject> items = dicAspectService.detailDict(((IPage) ((Result) result).getResult()).getRecords());
                ((IPage) ((Result) result).getResult()).setRecords(items);
            }
            else if(((Result) result).getResult() instanceof List){
                List<JSONObject> items = dicAspectService.detailDict(((List) ((Result) result).getResult()));
                ((Result) result).setResult(items);
            }
        }
    }
}
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/aspect/DicAspectService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,311 @@
package org.jeecg.modules.system.aspect;
import cn.hutool.core.util.ArrayUtil;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import cn.hutool.core.util.ReflectUtil;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.aspect.annotation.Dict;
import org.jeecg.common.aspect.annotation.DictExt;
import org.jeecg.common.aspect.annotation.DictList;
import org.jeecg.common.aspect.annotation.FieldQuery;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.system.service.ISysDictService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.*;
/**
 * å­—典字段翻译服务
 *   æ”¯æŒåµŒå¥—翻译
 * @since 2020/5/27
 */
@Service
@Slf4j
public class DicAspectService {
    @Autowired
    private ISysDictService dictService;
    /**
     * æœ¬æ–¹æ³•针对列表数据进行动态字典注入
     * å­—典注入实现 é€šè¿‡å¯¹å®žä½“类添加注解@dict æ¥æ ‡è¯†éœ€è¦çš„字典内容,字典分为单字典code即可 ï¼Œtable字典 code table text配合使用与原来jeecg的用法相同
     * ç¤ºä¾‹ä¸ºSysUser   å­—段为sex æ·»åŠ äº†æ³¨è§£@Dict(dicCode = "sex") ä¼šåœ¨å­—典服务立马查出来对应的text ç„¶åŽåœ¨è¯·æ±‚list的时候将这个字典text,已字段名称加_dictText形式返回到前端
     * ä¾‹è¾“入当前返回值的就会多出一个sex_dictText字段
     * {
     *      sex:1,
     *      sex_dictText:"男"
     * }
     * å‰ç«¯ç›´æŽ¥å–值sext_dictText在table里面无需再进行前端的字典转换了
     *  customRender:function (text) {
     *               if(text==1){
     *                 return "男";
     *               }else if(text==2){
     *                 return "女";
     *               }else{
     *                 return text;
     *               }
     *             }
     *             ç›®å‰vue是这么进行字典渲染到table上的多了就很麻烦了 è¿™ä¸ªç›´æŽ¥åœ¨æœåŠ¡ç«¯æ¸²æŸ“å®Œæˆå‰ç«¯å¯ä»¥ç›´æŽ¥ç”¨
     * @param records
     * @return
     */
    public List<JSONObject> detailDict(List<Object> records){
        List<JSONObject> items = new ArrayList<>();
        FieldBatchQuery batchQuery = new FieldBatchQuery();
        boolean hasDict = false;
        for (Object record : records) {
            JSONObject item = parseDictItem(record);
            Field[] fieldsArray = oConvertUtils.getAllFields(record);
            for (int i = 0; i < fieldsArray.length; i++) {
                Field field = fieldsArray[i];
                if (field.getAnnotation(Dict.class) != null && records.size()<=500) {
                    hasDict = true;
                    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);
                    item.put(field.getName() + CommonConstant.DICT_TEXT_SUFFIX, textValue);
                }
                // å­—典翻译扩展功能,支持字典多字段匹配
                else if(field.getAnnotation(DictExt.class) != null && records.size() <= 500){
                    hasDict = true;
                    String[] code = field.getAnnotation(DictExt.class).dicCode();
                    String text = field.getAnnotation(DictExt.class).dicText();
                    String table = field.getAnnotation(DictExt.class).dicTable();
                    String[] params = field.getAnnotation(DictExt.class).dicParams();
                    String[] paramValues = this.getParamValues(item, params);
                    String textValue = this.translateDictValue(code, text, table, paramValues);
                    item.put(field.getName() + CommonConstant.DICT_TEXT_SUFFIX, textValue);
                    item.put(field.getName(), ArrayUtil.join(paramValues, ","));
                }
                else if(field.getAnnotation(FieldQuery.class) != null && records.size() <= 500){
                    FieldQuery ann = field.getAnnotation(FieldQuery.class);
                    batchQuery.put(ann.dicTable(), ann.dicText(), ann.dicCode(),
                            this.getParamValues(item, ann.dicParams()));
                }
                // æ·±åº¦ç¿»è¯‘list元素
                else if(field.getAnnotation(DictList.class) != null){
                    Object fieldValue = ReflectUtil.getFieldValue(record, field);
                    if(fieldValue == null){
                        // no-op
                    }
                    else if(null != fieldValue && fieldValue instanceof List){
                        try{
                            List<JSONObject> listDetail = this.detailDict((List)fieldValue);
                            item.put(field.getName(), listDetail);
                        }catch (Exception e){
                            log.error("字段翻译错误,index=" + i + ",fieldName=" + field.getName() + ",fieldValue=" + fieldValue + ",record=" + record);
                        }
                    }else{
                        log.error("深度字典翻译只支持List类型,当前类型为" + fieldValue.getClass());
                    }
                }
                //date类型默认转换string格式化日期
                if (field.getType().getName().equals("java.util.Date")&&field.getAnnotation(JsonFormat.class)==null&&item.get(field.getName())!=null){
                    SimpleDateFormat aDate=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    item.put(field.getName(), aDate.format(new Date((Long) item.get(field.getName()))));
                }
            }
            if(records.size()>500 && hasDict){
                log.error("使用 @Dict注解超过500条记录请使用分页查询");
            }
            items.add(item);
        }
        // æ‰¹é‡æŸ¥è¯¢å…³è”数据
        if(batchQuery.size() > 0){
            Map<String, List<Map>> batchResult = new HashMap<>();
            batchQuery.forEach((queryKey, queryParam) -> {
                // æ‰¹é‡æŸ¥è¯¢
                try {
                    queryParam.setQueryResult(this.batchQueryFieldValue(queryParam.getQueryTable(),
                            queryParam.getColumns(),
                            queryParam.getParamName(),
                            queryParam.getParamValues()));
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            });
            for (int i = 0; i < records.size(); i++) {
                Object record = records.get(i);
                JSONObject item = items.get(i);
                try {
                    this.fillItemValue(record, item, batchQuery);
                } catch (Exception e) {
                    e.printStackTrace();
                    log.info("批量查询数据填充出错:{}", e.getMessage());
                }
            }
        }
        return items;
    }
    /**
     * å•表批量查询
     *
     * @param queryTable
     * @param columns
     * @param paramName
     * @param paramValues
     * @return
     */
    private List<Map> batchQueryFieldValue(String queryTable, String[] columns,
                                           String paramName, String[] paramValues) throws Exception {
        try{
            return this.dictService.queryTableFieldByParams(queryTable, columns, paramName, paramValues);
        }catch (Exception e){
            log.error("FieldQuery查询错误", e);
            throw new Exception("FieldQuery查询错误");
        }
    }
    /**
     * å¡«å……item批量查询数据
     * @param record
     * @param item
     * @param batchQuery
     */
    private void fillItemValue(Object record, JSONObject item, FieldBatchQuery batchQuery) throws Exception{
        for (Field field : oConvertUtils.getAllFields(record)) {
            if(field.getAnnotation(FieldQuery.class) != null){
                FieldQuery fieldQuery = field.getAnnotation(FieldQuery.class);
                String[] paramValues = this.getParamValues(item, fieldQuery.dicParams());
                Object textValue = batchQuery.findResult(fieldQuery.dicTable(),
                        fieldQuery.dicCode(), paramValues, fieldQuery.dicText());
                item.put(field.getName() + CommonConstant.DICT_TEXT_SUFFIX, textValue);
                item.put(field.getName(), ArrayUtil.join(paramValues, ","));
            }
        }
    }
    /**
     * è§£æžå­—å…¸Item
     * @param record
     * @return
     */
    private JSONObject parseDictItem(Object record) {
        ObjectMapper mapper = new ObjectMapper();
        String json="{}";
        try {
            //解决@JsonFormat注解解析不了的问题详见SysAnnouncement类的@JsonFormat
            json = mapper.writeValueAsString(record);
        } catch (JsonProcessingException e) {
            log.error("json解析失败"+e.getMessage(),e);
        }
        return JSONObject.parseObject(json);
    }
    /**
     * èŽ·å–å‚æ•°æ•°å€¼
     * @param item
     * @param paramNames
     * @return
     */
    private String[] getParamValues(JSONObject item, String[] paramNames) {
        // èŽ·å–å®žé™…å‚æ•°
        String[] values = new String[paramNames.length];
        for (int i = 0; i < paramNames.length; i++) {
            String param = paramNames[i];
            if(param.startsWith("$")){
                values[i] = (String) item.get(param.substring(1));
            }else{
                values[i] = param;
            }
            if(values[i] == null) return null;
            if(values[i].indexOf("&&") > -1){
                log.error(">>>参数["+values[i]+"]包含非法字符','");
                return null;
            }
        }
        return values;
    }
    /**
     * ç¿»è¯‘字典文本
     *
     * @param code
     * @param text
     * @param table
     * @param paramValues
     * @return
     */
    private String translateDictValue(String[] code, String text, String table, String[] paramValues) {
        if(paramValues == null || paramValues.length <=0 || oConvertUtils.isEmpty(table)){
            return null;
        }
        try{
            return this.dictService.queryTableDictByParams(table,text,
                    ArrayUtil.join(code, "&&"),
                    ArrayUtil.join(paramValues, "&&"));
        }catch (Exception e){
            log.error("字典翻译异常table={},text={},code={},paramValues={}", table, text, ArrayUtil.join(code, "&&"),ArrayUtil.join(paramValues, "&&") );
            throw e;
        }
    }
    /**
     *  ç¿»è¯‘字典文本
     * @param code
     * @param text
     * @param table
     * @param key
     * @return
     */
    private String translateDictValue(String code, String text, String table, String key) {
        if(oConvertUtils.isEmpty(key)) {
            return null;
        }
        StringBuffer textValue=new StringBuffer();
        String[] keys = key.split(",");
        for (String k : keys) {
            String tmpValue = null;
            if (k.trim().length() == 0) {
                continue; //跳过循环
            }
            if (!StringUtils.isEmpty(table)){
                tmpValue= dictService.queryTableDictTextByKey(table,text,code,k.trim());
            }else {
                tmpValue = dictService.queryDictTextByKey(code, k.trim());
            }
            if (tmpValue != null) {
                if (!"".equals(textValue.toString())) {
                    textValue.append(",");
                }
                textValue.append(tmpValue);
            }
        }
        return textValue.toString();
    }
}
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/aspect/FieldBatchQuery.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,135 @@
package org.jeecg.modules.system.aspect;
import cn.hutool.core.util.ArrayUtil;
import java.util.*;
import java.util.function.BiConsumer;
/**
 * æ‰¹é‡æŸ¥è¯¢å™¨
 */
public class FieldBatchQuery {
    // key=查询要素=table+paramName, value=查询条件
    private Map<String, QueryParam> queryBatch = new HashMap<>();
    /**
     * ä¾¿åˆ©æŸ¥è¯¢è¦ç´ 
     * @param action
     */
    public void forEach(BiConsumer<? super String, ? super QueryParam> action) {
        this.queryBatch.forEach(action);
    }
    /**
     * æŸ¥è¯¢è¡¨æ•°é‡
     * @return
     */
    public int size() {
        return queryBatch.size();
    }
    /**
     * æŸ¥æ‰¾æŸ¥è¯¢ç»“æžœ
     * @param tableName
     * @param paramName
     * @param paramValue
     * @param column
     * @return
     */
    public Object findResult(String tableName, String[] paramName, String[] paramValue, String column) {
        String queryKey = tableName + "()" + ArrayUtil.join(paramName, ",");
        if(!this.queryBatch.containsKey(queryKey)) return null;
        return this.queryBatch.get(queryKey).findResult(paramValue, column);
    }
    /**
     * ä¿å­˜æŸ¥è¯¢æ¡ä»¶
     * @param tableName æŸ¥è¯¢è¡¨å
     * @param textName æŸ¥è¯¢å­—段名称
     * @param paramName æŸ¥è¯¢å‚数名称
     * @param paramValue æŸ¥è¯¢å‚数值
     */
    public void put(String tableName, String textName, String[] paramName, String[] paramValue) {
        String queryKey = tableName + "()" + ArrayUtil.join(paramName, ",");
        QueryParam queryParams;
        if(this.queryBatch.containsKey(queryKey)){
            queryParams = this.queryBatch.get(queryKey);
        }else{
            queryParams = new QueryParam(tableName, paramName);
            this.queryBatch.put(queryKey, queryParams);
        }
        // æ·»åŠ æŸ¥è¯¢ç»“æžœcolumn名称
        queryParams.addTextName(textName);
        // æ·»åŠ æŸ¥è¯¢å‚æ•°
        queryParams.addParamValue(paramValue);
    }
    public static class QueryParam {
        private String queryTable;
        private Set<String> columns = new HashSet<>();
        private Set<String> paramValueSet = new HashSet<>();
        private String[] paramName;
        private List<Map> queryResult = new ArrayList<>();
        private Map<String, Integer> resultIndex = new HashMap<>();
        public QueryParam(String tableName, String[] column) {
            this.queryTable = tableName;
            this.paramName = column;
        }
        public void addTextName(String textName) {
            this.columns.add(textName);
        }
        public void addParamValue(String[] paramValue) {
            paramValueSet.add(ArrayUtil.join(paramValue, ","));
        }
        public String getQueryTable() {
            return queryTable;
        }
        public String[] getColumns() {
            String[] ret = new String[this.columns.size()];
            this.columns.toArray(ret);
            return ret;
        }
        public String getParamName() {
            return "concat(" + ArrayUtil.join(this.paramName, ",',',") + ")";
        }
        public String[] getParamValues() {
            String[] ret = new String[this.paramValueSet.size()];
            this.paramValueSet.toArray(ret);
            return ret;
        }
        public void setQueryResult(List<Map> queryResult) {
            this.queryResult = queryResult;
        }
        public Object findResult(String[] paramValue, String column) {
            if(paramValue == null) return null;
            String value = ArrayUtil.join(paramValue, ",");
            if(this.resultIndex.containsKey(value)){
                return this.queryResult.get(this.resultIndex.get(value)).get(column);
            }
            for (int i = 0; i < this.queryResult.size(); i++) {
                Map<String, Object> map = queryResult.get(i);
                if(value.equals(map.get("paramValue"))){
                    this.resultIndex.put(value, i);
                    return map.get(column);
                }
            }
            return null;
        }
    }
}
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/mapper/SysDictMapper.java
@@ -263,4 +263,25 @@
     */
    @Deprecated
    List<DictModel> queryTableDictByKeysAndFilterSql(@Param("table") String table, @Param("text") String text, @Param("code") String code, @Param("filterSql") String filterSql,  @Param("codeValues") List<String> codeValues);
    /**
     * ä½¿ç”¨å­Sql查询字典数据
     * @param table
     * @param text
     * @param subSql
     * @return
     */
    String queryTableDictTextBySubSql(@Param("table") String table, @Param("text") String text, @Param("subSql") String subSql);
    /**
     * å•表批量查询
     * @param queryTable
     * @param columns
     * @param paramName
     * @param paramValues
     * @return
     */
    List<Map> queryTableFieldByParams(@Param("table") String queryTable, @Param("columns") String columns, @Param("paramName") String paramName, @Param("paramValues") String[] paramValues);
}
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/SysDictMapper.xml
@@ -213,7 +213,16 @@
            and ${filterSql}
        </if>
    </select>
    <select id="queryTableDictTextBySubSql" resultType="java.lang.String">
        select ${text} as "text" from ${table} where ${subSql}
    </select>
    <select id="queryTableFieldByParams" resultType="java.util.Map">
        select ${columns},${paramName} as paramValue
        from ${table} where ${paramName} in
        <foreach item="key" collection="paramValues" open="(" separator="," close=")">
            #{key}
        </foreach>
    </select>
</mapper>
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/service/ISysDictService.java
@@ -255,4 +255,16 @@
     */
    List<DictModel> loadDict(String dictCode, String keyword, Integer pageSize);
    String queryTableDictByParams(String table, String text, String codes, String params);
    /**
     * å•表批量查询
     * @param queryTable
     * @param columns
     * @param paramName
     * @param paramValues
     * @return
     */
    List<Map> queryTableFieldByParams(String queryTable, String[] columns, String paramName, String[] paramValues);
}
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysDictServiceImpl.java
@@ -1,5 +1,7 @@
package org.jeecg.modules.system.service.impl;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ArrayUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -475,4 +477,37 @@
        }
    }
    @Override
    @Cacheable(value = CacheConstant.SYS_DICT_TABLE_CACHE)
    public String queryTableDictByParams(String table, String text, String codes, String params) {
        log.info("无缓存dictTable queryTableDictByKeys的时候调用这里!");
        String[] codeArr = codes.split("&&");
        String[] paramArr = params.split("&&");
        String subSql = "";
        for (int i = 0; i < codeArr.length; i++) {
            String column = codeArr[i];
            // é»˜è®¤å‚数为空字符串
            String param = paramArr.length > i ? paramArr[i] : "";
            if(column == null || ! Validator.isGeneral(column)){
                log.error("<<<非法字段:" + column);
                return null;
            }
            if(null == param || (!"-1".equals(param) && ! Validator.isGeneralWithChinese(param.replaceAll(" ", "")))){
                log.error("<<<非法参数:" + param);
                return null;
            }
            if(i != 0) subSql += " and ";
            subSql += column+" = '"+param+"'";
        }
        return sysDictMapper.queryTableDictTextBySubSql(table,text,subSql);
    }
    @Override
    public List<Map> queryTableFieldByParams(String queryTable, String[] columns, String paramName, String[] paramValues) {
        String column = ArrayUtil.join(columns, ",");
        return this.baseMapper.queryTableFieldByParams(queryTable, column, paramName, paramValues);
    }
}