jeecgboot改造:枚举加入字典,控制器返回列表翻译字典

  • Post author:
  • Post category:其他


jeecgboot版本:2.4.5

虽然jeecg提供了数据字典功能,使用很方便,但在实际业务中,有根据不同值编写不同代码进行操作的需求,如果将这些代码写进数据字典中,那么字典值一旦被人修改,就会使代码运行不正常。使用枚举,就是为了避免此类问题,经尝试,改了些代码后,将枚举项的使用与数据字典一致化,使用起来会方便些。


枚举加入字典的方法

修改 SysDictServiceImpl.getDictItems

@Override
    public List<DictModel> getDictItems(String dictCode) {
        List<DictModel> ls;
        if (dictCode.contains(",")) {
            //关联表字典(举例:sys_user,realname,id)
            String[] params = dictCode.split(",");
            if (params.length < 3) {
                // 字典Code格式不正确
                return null;
            }
            //SQL注入校验(只限制非法串改数据库)
            final String[] sqlInjCheck = {params[0], params[1], params[2]};
            SqlInjectionUtil.filterContent(sqlInjCheck);
            if (params.length == 4) {
                // SQL注入校验(查询条件SQL 特殊check,此方法仅供此处使用)
                SqlInjectionUtil.specialFilterContent(params[3]);
                ls = this.queryTableDictItemsByCodeAndFilter(params[0], params[1], params[2], params[3]);
            } else if (params.length == 3) {
                ls = this.queryTableDictItemsByCode(params[0], params[1], params[2]);
            } else {
                // 字典Code格式不正确
                return null;
            }
        } else {
            if (dictCode.indexOf(":") != -1) {
                //从枚举获取
                //格式 enum:DynamicDataTypeEnum
                String[] split = dictCode.split(":");
                String enumType = split[1];
                String className = DictEnumCache.getClassName(enumType);
                List<DictModel> list = new LinkedList<>();
                try {
                    Class<?> aClass = Class.forName(className);
                    Method toList = aClass.getDeclaredMethod("toList");
                    Object[] oo = aClass.getEnumConstants();
                    List<Map<String, Object>> invoke = (List<Map<String, Object>>) toList.invoke(oo[0]);
                    invoke.forEach(f -> {
                        DictModel dictModel = new DictModel();
                        dictModel.setText(f.get("name").toString());
                        dictModel.setValue(f.get("code").toString());
                        list.add(dictModel);

                    });
                } catch (Exception ex) {
                    log.error("获取枚举项出错:{}",ex.getMessage());
                }
                ls = list;

            } else {
                //字典表
                ls = this.queryDictItemsByCode(dictCode);
            }
        }
        return ls;
    }

完成后可以使用 /sys/dict/getDictItems/enum:FieldTypeEnum 获取枚举值项

修改 CommonAPI 加入方法

  /**
     * 从枚举型中取字典
     * @param code
     * @param key
     * @return
     */
    String translateDictFromEnum(String code,String key);

修改 SysBaseApiImpl 实现上述方法

@Override
	public String translateDictFromEnum(String code, String key){
        //格式 enum:DynamicDataTypeEnum
        String[] split = code.split(":");
        String enumType = split[1];
        String className = DictEnumCache.getClassName(enumType);
        List<DictModel> list = new LinkedList<>();
        try {
            Class<?> aClass = Class.forName(className);
            Method toList = aClass.getDeclaredMethod("toList");
            Object[] oo = aClass.getEnumConstants();
            List<Map<String, Object>> invoke = (List<Map<String, Object>>) toList.invoke(oo[0]);
            Map<String, Object> code1 = invoke.stream().filter(f -> f.get("code").toString().equals(key)).findFirst().orElse(null);
            if(code1!=null){
                return code1.get("name").toString();
            }
        } catch (Exception ex) {
            log.error("获取枚举项出错:{}",ex.getMessage());
        }
	    return null;
    }

修改 DictAspect.parseDictText 方法,原方法只 对 Ipage 中的项翻译字典,修改后可对 List 页进行翻译

private void parseDictText(Object result) {
         if (result instanceof Result) {
            List<Object> list = new LinkedList<>();
            if (((Result) result).getResult() instanceof IPage) {
                list = ((IPage) ((Result) result).getResult()).getRecords();
            } else if (((Result) result).getResult() instanceof List) {
                List<Object> tmplist = (List<Object>) ((Result) result).getResult();
                if (tmplist.size() > 0) {
                    //判断能否转换成json
                    try {
                        String s = new ObjectMapper().writeValueAsString(tmplist.get(0));
                        if(s.startsWith("{")) {
                            list = (List<Object>) ((Result) result).getResult();
                        }
                    } catch (Exception e) {
                    }
                }
            }
            if (list.size() > 0) {
                List<JSONObject> items = new ArrayList<>();
                for (Object record : list) {
                    ObjectMapper mapper = new ObjectMapper();
                    String json = "{}";
                    try {
                        //解决@JsonFormat注解解析不了的问题详见SysAnnouncement类的@JsonFormat
                        json = mapper.writeValueAsString(record);
                    } catch (JsonProcessingException e) {
                        log.error("json解析失败" + e.getMessage(), e);
                    }

                    JSONObject item = JSONObject.parseObject(json);
                    //update-begin--Author:scott -- Date:20190603 ----for:解决继承实体字段无法翻译问题------
                    //for (Field field : record.getClass().getDeclaredFields()) {
                    for (Field field : oConvertUtils.getAllFields(record)) {
                        //update-end--Author:scott  -- Date:20190603 ----for:解决继承实体字段无法翻译问题------
                        if (field.getAnnotation(Dict.class) != null) {
                            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);
                        }
                        //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()))));
                        }
                    }
                    items.add(item);

                }
                if (((Result) result).getResult() instanceof IPage) {
                    ((IPage) ((Result) result).getResult()).setRecords(items);
                } else if (((Result) result).getResult() instanceof List) {
                    ((Result) result).setResult(items);
                }
            }
        }
    }

修改 DictAspect.translateDictValue方法 ,使其可对枚举型进行翻译

 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;
            log.debug(" 字典 key : "+ k);
            if (k.trim().length() == 0) {
                continue; //跳过循环
            }
            //update-begin--Author:scott -- Date:20210531 ----for: !56 优化微服务应用下存在表字段需要字典翻译时加载缓慢问题-----
            if (!StringUtils.isEmpty(table)){
                log.info("--DictAspect------dicTable="+ table+" ,dicText= "+text+" ,dicCode="+code);
                String keyString = String.format("sys:cache:dictTable::SimpleKey [%s,%s,%s,%s]",table,text,code,k.trim());
                if (redisTemplate.hasKey(keyString)){
                    try {
                        tmpValue = oConvertUtils.getString(redisTemplate.opsForValue().get(keyString));
                    } catch (Exception e) {
                        log.warn(e.getMessage());
                    }
                }else {
                    tmpValue= commonAPI.translateDictFromTable(table,text,code,k.trim());
                }
            }else if(code.indexOf(":")!=-1){
                //从枚举中获取字典值
                tmpValue = commonAPI.translateDictFromEnum(code,k.trim());
            }
            else{
                String keyString = String.format("sys:cache:dict::%s:%s",code,k.trim());
                if (redisTemplate.hasKey(keyString)){
                    try {
                        tmpValue = oConvertUtils.getString(redisTemplate.opsForValue().get(keyString));
                    } catch (Exception e) {
                       log.warn(e.getMessage());
                    }
                }else {
                    tmpValue = commonAPI.translateDict(code, k.trim());
                }
            }
            //update-end--Author:scott -- Date:20210531 ----for: !56 优化微服务应用下存在表字段需要字典翻译时加载缓慢问题-----

            if (tmpValue != null) {
                if (!"".equals(textValue.toString())) {
                    textValue.append(",");
                }
                textValue.append(tmpValue);
            }

        }
        return textValue.toString();
    }

后端字段定义:

@Dict(dicCode = "enum:FieldTypeEnum")
private java.lang.String itemType;

前端form中使用控件:

<j-dict-select-tag v-model="model.itemType" placeholder="请选择类型" dictCode="enum:FieldTypeEnum"/>

列表中使用,给字段设置值:字段名_dictText

<vxe-table
            v-else
            border
            highlight-hover-row
            highlight-current-row
            show-overflow
            row-id="id"
            ref="xTable"
            :data="itemList">
            <vxe-table-column field="itemType_dictText" title="类型" align="center" width="80"></vxe-table-column>
          </vxe-table>



版权声明:本文为wyljz原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。