Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

建议增加注解如下DictObject 关联对象下面的注解查询 #4228

Closed
TomYule opened this issue Nov 15, 2022 · 7 comments
Closed

建议增加注解如下DictObject 关联对象下面的注解查询 #4228

TomYule opened this issue Nov 15, 2022 · 7 comments

Comments

@TomYule
Copy link

TomYule commented Nov 15, 2022

版本号:

3.2.0

前端版本:vue3版?还是 vue2版?
问题描述:

比如 我要查用户详情 用户关联部门下面的数据字典也能查出来

截图&代码:
package org.jeecg.common.aspect.annotation;

import java.lang.annotation.*;

/**
 * @Description 需要翻译的实体对象
 * @Author Jie Cheng
 * @Date 14:57 2021/8/12
 */
@Target({ElementType.TYPE, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface DictObject {
}

package org.jeecg.common.aspect;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.ReflectUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
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.CommonAPI;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.Dict;
import org.jeecg.common.aspect.annotation.DictList;
import org.jeecg.common.aspect.annotation.DictObject;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.util.oConvertUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Description: 字典aop类
 * @Author: dangzhenghui
 * @Date: 2019-3-17 21:50
 * @Version: 1.0
 */
@Aspect
@Component
@Slf4j
public class DictAspect {

    @Autowired
    private CommonAPI commonAPI;

    // 定义切点Pointcut
    @Pointcut("execution(public * org.jeecg.modules..*.*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) {
            Object typeUnknownRes = ((Result) result).getResult();
            if (typeUnknownRes instanceof IPage) {
                List<JSONObject> items = new ArrayList<>();
                for (Object record : ((IPage) ((Result) result).getResult()).getRecords()) {
                    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);
                    handle(record, item);
                    items.add(item);
                }
                ((IPage) typeUnknownRes).setRecords(items);
            } else if (typeUnknownRes instanceof JSONObject) { // 添加对返回集为JsonObject类型的字典翻译
                JSONObject res = (JSONObject) ((Result) result).getResult();
                for (Map.Entry<String, Object> entry : res.entrySet()) {
                    String key = entry.getKey();
                    Object obj = entry.getValue();
                    if (obj instanceof List) { // 数据类型为集合
                        JSONArray jsonArray = res.getJSONArray(key);
                        for (int i = 0; i < ((List<?>) obj).size(); i++) {
                            if (typeVerify(jsonArray.get(i))) {
                                JSONObject jsonObject = jsonArray.getJSONObject(i);
                                // 处理json对象的字典字段
                                handle(((List<?>) obj).get(i), jsonObject);
                                jsonArray.set(i, jsonObject);
                            }
                        }
                        res.put(key, jsonArray);
                    } else if (typeVerify(obj)) { // 数据类型为普通实体类
                        JSONObject jsonObject = res.getJSONObject(key);
                        // 处理json对象的字典字段
                        handle(obj, jsonObject);
                        res.put(key, jsonObject);
                    }
                }
            } else if (typeUnknownRes instanceof List) {
                List<?> list = (List) ((Result) result).getResult();
                if (CollUtil.isNotEmpty(list) && typeVerify(list.get(0))) {
                    List<JSONObject> items = new ArrayList<>();
                    for (Object obj : list) {
                        JSONObject jsonItem = translateDictOfObject(obj);
                        items.add(jsonItem);
                    }
                    ((Result) result).setResult(items);
                }
            } else if (typeUnknownRes != null && typeUnknownRes.getClass().isAnnotationPresent(DictObject.class)) {
                JSONObject jsonObject = translateDictOfObject(typeUnknownRes);
                ((Result) result).setResult(jsonObject);
            }
        }
    }

    /**
     * 翻译字典文本
     *
     * @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;
            log.debug(" 字典 key : " + k);
            if (k.trim().length() == 0) {
                continue; //跳过循环
            }
            if (!StringUtils.isEmpty(table)) {
                log.debug("--DictAspect------dicTable=" + table + " ,dicText= " + text + " ,dicCode=" + code);
                tmpValue = commonAPI.translateDictFromTable(table, text, code, k.trim());
            } else {
                tmpValue = commonAPI.translateDict(code, k.trim());
            }
            if (tmpValue != null) {
                if (!"".equals(textValue.toString())) {
                    textValue.append(",");
                }
                textValue.append(tmpValue);
            }

        }
        return textValue.toString();
    }

    public JSONObject translateDictOfObject(Object object) {
        JSONObject jsonObject = new JSONObject();
        try {
            String json = new ObjectMapper().writeValueAsString(object);
            jsonObject = JSONObject.parseObject(json);
            handle(object, jsonObject);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return jsonObject;
    }

    /**
     * 处理返回集对象
     *
     * @param obj  实体对象
     * @param item jsonObject
     */
    private void handle(Object obj, JSONObject item) {
        for (Field field : oConvertUtils.getAllFields(obj)) {
            String fieldName = field.getName();
            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(fieldName));
                //翻译字典值对应的txt
                String textValue = translateDictValue(code, text, table, key);
                log.debug(" 字典Val : " + textValue);
                log.debug(" __翻译字典字段__ " + fieldName + CommonConstant.DICT_TEXT_SUFFIX + ": " + textValue);
                item.put(fieldName + CommonConstant.DICT_TEXT_SUFFIX, textValue);
            } else if (field.isAnnotationPresent(DictObject.class)) {
                Optional.ofNullable(ReflectUtil.getFieldValue(obj, field)).filter(this::typeVerify).ifPresent(fieldVal -> {
                    JSONObject fieldDictVal = translateDictOfObject(fieldVal);
                    item.put(fieldName, fieldDictVal);
                });
            } else if (field.isAnnotationPresent(DictList.class)) {
                Optional.ofNullable(ReflectUtil.getFieldValue(obj, field)).filter(this::typeVerify).ifPresent(fieldVal -> {
                    JSONArray jsonArray = new JSONArray();
                    ((List<Object>) fieldVal).forEach(listItem -> {
                        JSONObject jsonObject = translateDictOfObject(listItem);
                        jsonArray.add(jsonObject);
                    });
                    item.put(fieldName, jsonArray);
                });
            }
            //date类型默认转换string格式化日期
            if ("java.util.Date".equals(field.getType().getName()) && field.getAnnotation(JsonFormat.class) == null && item.get(fieldName) != null) {
                SimpleDateFormat aDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Object val = item.get(fieldName);
                if (val instanceof Long) {
                    item.put(fieldName, aDate.format(new Date((Long) item.get(fieldName))));
                }
            }
        }
    }

    /**
     * 类型校验
     *
     * @param obj
     * @return
     */
    private boolean typeVerify(Object obj) {
        return obj != null && !(obj instanceof String || obj instanceof Date || ClassUtil.isBasicType(obj.getClass()));
    }

}

友情提示(为了提高issue处理效率):

  • 未按格式要求发帖,会被直接删掉;
  • 描述过于简单或模糊,导致无法处理的,会被直接删掉;
  • 请自己初判问题描述是否清楚,是否方便我们调查处理;
  • 针对问题请说明是Online在线功能(需说明用的主题模板),还是生成的代码功能;

在原来基础上实现了
#建议能在新版本里面添加进去
使用如下

package org.jeecg.modules.app.vo;

import lombok.Data;
import org.jeecg.common.aspect.annotation.DictObject;
import org.jeecg.modules.app.entity.RegisRecord;
import org.jeecg.modules.app.entity.StudentOrder;

@Data
@DictObject
public class RegisRecordVo {
    @DictObject
    private RegisRecord record;

    @DictObject
    private StudentOrder order;
}

@eric-gitta-moore
Copy link

非常需要这个

1 similar comment
@kinglyx
Copy link

kinglyx commented May 16, 2023

非常需要这个

@zhangdaiscott
Copy link
Member

收到

@zhangdaiscott
Copy link
Member

ty

@tygithub1
Copy link

已修改,等下个版本发布

@Engine027
Copy link

这个更新了嘛

@Hzrr97
Copy link

Hzrr97 commented Sep 25, 2023

@TomYule 你好,少了个DictList的依赖,直接复制DictObject吗

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants