JAVA 后端使用Aop实现数据字典转换

package com.jst.mdm.boot.common.ascpect;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jst.mdm.api.dto.PageModel;
import com.jst.mdm.api.dto.dict.SysDictItemDto;
import com.jst.mdm.api.dto.language.SysLanguageTransfDto;
import com.jst.mdm.boot.modules.entity.TSysDictItem;
import com.jst.mdm.boot.modules.entity.TSysLanguageTransf;
import com.jst.mdm.boot.modules.service.DictItemService;
import com.jst.mdm.boot.modules.service.LanguageTransfService;
import com.jst.mdm.commons.annotation.Dict;
import com.jst.mdm.commons.annotation.DtoId;
import com.jst.mdm.commons.annotation.Language;
import com.jst.mdm.commons.constant.CommonConstant;
import com.jst.mdm.commons.result.Result;
import com.jst.mdm.commons.util.SpringContextUtils;
import com.jst.mdm.commons.util.oConvertUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Description: 字典和多语言aop类
 */
@Aspect
@Component
@Slf4j
public class DictLanguageAspect {
    @Autowired
    public DictItemService dictComService;

    @Autowired
    public LanguageTransfService langService;

    public final static String LANG_ZH = "ZH";
    public final static String LANG_EN = "EN";
    public final static String LANG_SPAN = "SPAN";
    public final static String categoryName = "mdm";
    public final static String lang = "lang";

    // 定义切点Pointcut
    @Pointcut("execution(public * com.jst.mdm.boot.modules..*.SysPermissionController.*(..))")
    public void excudeService() {
    }

    @Around("excudeService()")
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
//        log.debug("------------解析字典和多语言 doAround--------------");
        HttpServletRequest request = SpringContextUtils.getHttpServletRequest();
        String langType = request.getHeader(lang);
        long time1=System.currentTimeMillis();
        Object result = pjp.proceed();
        long time2=System.currentTimeMillis();
//        log.debug("获取JSON数据 耗时:"+(time2-time1)+"ms");
//        long start=System.currentTimeMillis();
        this.transfLangText(result, langType);
//        long end=System.currentTimeMillis();
//        log.debug("解析注入JSON数据  耗时"+(end-start)+"ms");
        return result;
    }

    /**
     * @param result
     */
    public void transfLangText(Object result, String langType) {
//        log.debug("------------解析字典和多语言 transfLangText--------------");
        if (result instanceof Result) {
            Object res = ((Result) result).getResult();
//            if (res instanceof PageModel) {
//                List<JSONObject> items = multipleRecord(res, langType);
//                ((PageModel) res).setRecords(items);
//            }else
            if(res instanceof List){
                List<JSONObject> items = multipleRecord(res,langType);
                ((Result) result).setResult(items);
            }
//        else if(res instanceof Boolean || res instanceof Integer  || res instanceof Long
//                    || res instanceof Short  || res instanceof Byte  || res instanceof Float
//                    || res instanceof Double  || res instanceof Character || res instanceof BigInteger){
//
//            }else if(res instanceof Object){
//                if(null != res){
//                    Map<String, Map<String, String>> dictMap = getDictMap(res, langType);
//                    JSONObject item = recordToJson(res, dictMap, langType);
//                    if(null != item){
//                        ((Result) result).setResult(item);
//                    }
//                }
//            }
        }
    }

    /**
     *  多条记录操作
     */
    public List<JSONObject> multipleRecord (Object res, String langType){
        List<JSONObject> items = new ArrayList<>();
        List<Object> records = null;
        if(res instanceof PageModel){
            records = ((PageModel) res).getRecords();
        }else if(res instanceof List){
            records = (List)res;
        }
        Map<String, Map<String, String>> dictMap = null;
        if(null != records && records.size() > 0 ){
            dictMap = getDictMap(records.get(0), langType);
        }
        if(null != dictMap){
            for (Object record : records) {
                JSONObject item = recordToJson(record, dictMap, langType);
                items.add(item);
            }
        }

        return  items;
    }

    /**
     *  获取所有字典的keyValue
     */
    public Map<String, Map<String, String>> getDictMap(Object record, String langType){
        Map<String, Map<String, String>> dictMap = new HashMap<>();
        for (Field field : oConvertUtils.getAllFields(record)) {
            if (field.getAnnotation(Dict.class) != null) {
                String resultCode = field.getAnnotation(Dict.class).dicCode();
                String categoryCode="", code="";
                //判断是否包含mdm
                if(resultCode.contains("-")){
                    String[] strArr = resultCode.split("-");
                    categoryCode =strArr[0];
                    code = strArr[1];
                }else{
                    categoryCode =categoryName;
                    code = resultCode;
                }
                List<TSysDictItem> dictItemList;
                if(StringUtils.isEmpty(langType)){
                    dictItemList = dictComService.queryItemByCode(code, categoryCode);
                }else{
                    dictItemList = dictComService.queryItemByCodeAndLangType(code, categoryCode, langType);
                }
                if(null != dictItemList && dictItemList.size() > 0){
                    Map<String, String> valueTextMap = new HashMap<>();
                    dictItemList.forEach(dictItem -> {
                        if(StringUtils.isNotEmpty(dictItem.getItemText()) && StringUtils.isNotEmpty(dictItem.getItemValue()) ){
                            valueTextMap.put(dictItem.getItemValue(), dictItem.getItemText());
                        }
                    });
                    dictMap.put(resultCode, valueTextMap);
                }
            }
        }
        return dictMap;
    }

    /**
     *  记录转json并调用Dict和Language的注解转换
     * @return
     */
    public JSONObject recordToJson (Object record, Map<String, Map<String, String>> dictMap, String langType){
        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 = null;
        try {
            item = JSONObject.parseObject(json);
        }catch(Exception e){
            log.error("JSONObject解析失败"+e.getMessage(), e);
        }
        if(null != item){
            String itemId = "";
            for (Field field : oConvertUtils.getAllFields(record)) {
                //拿到主键ID
                if(StringUtils.isEmpty(itemId)){
                    if(field.getAnnotation(DtoId.class) != null){
                        itemId = String.valueOf(item.get(field.getName()));
                    }
                }
                //字典注解转换
                dictConvert(field, item, dictMap);

                //date类型默认转换string格式化日期
                if (field.getDeclaringClass().isAssignableFrom(Date.class)&&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(StringUtils.isNotEmpty(langType) && !LANG_ZH.equals(langType)){
                langConvert(itemId, record, item, langType);
            }
        }
        return item;
    }

    /**
     *  字典注解转换
     * @return
     */
    public void dictConvert(Field field, JSONObject item, Map<String, Map<String, String>> dictMap){
        if (field.getAnnotation(Dict.class) != null) {
            String resultCode = field.getAnnotation(Dict.class).dicCode();
            String key = String.valueOf(item.get(field.getName()));
            //翻译字典值对应的txt
            String textValue = translateDictValue(resultCode, key, dictMap);

//            log.debug(" 字典Val : "+ textValue);
//            log.debug(" __翻译字典字段__ "+field.getName() + CommonConstant.DICT_TEXT_SUFFIX+": "+ textValue);
            item.put(field.getName() + CommonConstant.DICT_TEXT_SUFFIX, textValue);
        }
    }

    /**
     *  翻译字典文本
     * @param code
     * @param key
     * @param dictMap
     * @return
     */
    public String translateDictValue(String code, String key, Map<String, Map<String, String>> dictMap) {
//        log.debug("------------解析数据字典 translateDictValue--------------");
//        log.debug("code:"+code+" key:"+key);
        if(oConvertUtils.isEmpty(key)) {
            return null;
        }
        String textValue = "";
        Map<String, String> valueTextMap = dictMap.get(code);
        if(null != valueTextMap){
            textValue = valueTextMap.get(key);
        }
        return textValue;
    }

    /**
     *  多语言注解转换
     * @return
     */
    public void langConvert(String itemId, Object record, JSONObject item, String langType){
        if(StringUtils.isNotEmpty(itemId)){
            for (Field field : oConvertUtils.getAllFields(record)) {
                if (field.getAnnotation(Language.class) != null) {
                    String tableName = field.getAnnotation(Language.class).langTable();
                    String columnName = field.getAnnotation(Language.class).langColumn();
                    String textValue = "";
                    //翻译英语和西班牙语txt
                    Map<String,String> langAll = translateLangValue(tableName, columnName, itemId);
                    if(null != langAll){
                        textValue = langAll.get(langType);
                        if(StringUtils.isEmpty(textValue)){
                            textValue = "";
                        }
                    }

//                    log.debug(" __翻译多语言字段__ "+field.getName() + "_"+langType+": "+ textValue);
                    item.put(field.getName() , textValue);
                }
            }
        }
    }

    /**
     *  翻译多语言文本
     * @param tableName
     * @param columnName
     * @param itemId
     * @return
     */
    public Map<String,String> translateLangValue(String tableName, String columnName, String itemId) {
//        log.debug("------------解析多语言 translateDictValue--------------");
        Map<String,String> result = new HashMap<String,String>();
        if(oConvertUtils.isEmpty(tableName) || oConvertUtils.isEmpty(columnName) || oConvertUtils.isEmpty(itemId)) {
            return null;
        }
        String textValue_EN = "";
        String textValue_ES = "";
//        log.debug(" 原表主键ID : "+ itemId);
        if (StringUtils.isNotEmpty(tableName) && StringUtils.isNotEmpty(columnName) && StringUtils.isNotEmpty(itemId)){
            List<TSysLanguageTransf> LangResult = langService.queryLangByTableInfoAndItemId(tableName,columnName,Long.valueOf(itemId));

            if(null != LangResult && LangResult.size() > 0){
                for(TSysLanguageTransf lang : LangResult){
                    if(null != lang){
                        if(StringUtils.isNotEmpty(lang.getLangType()) && StringUtils.isNotEmpty(lang.getText())){
                            if(LANG_EN.equals(lang.getLangType())){
                                textValue_EN = lang.getText();
                            }else if(LANG_SPAN.equals(lang.getLangType())){
                                textValue_ES = lang.getText();
                            }
                        }
                    }
                }
            }
        }
        result.put(LANG_EN,textValue_EN);
        result.put(LANG_SPAN,textValue_ES);
        return result;
    }

}

  

package com.jst.mdm.commons.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 Dict {
    /**
     * 方法描述:  数据code
     * @return 返回类型: String
     */
    String dicCode();

    /**
     * 方法描述:  数据Text
     * @return 返回类型: String
     */
    String dicText() default "";

    /**
     * 方法描述: 数据字典表
     * @return 返回类型: String
     */
    String dictTable() default "";

    /**
     * 多个字典项的情况下,进行分割处理
     *
     * 默认为空表示不分割,不为空按指定的分割符号进行分割
     *
     */
    String dictSplit() default "";

}

  

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.springframework.format.annotation.DateTimeFormat;

import java.io.Serializable;
import java.util.Date;
import java.util.List;


@Data
@Permission(name="开票申请信息",value = "InvoiceApplyDto",notes="InvoiceApplyDto")
public class InvoiceApplyDto extends BaseDto implements Serializable {


    /**红字确认单状态编码-实时*/
    @ApiModelProperty(value = "红字确认单状态编码-实时")
    @Dict(dicCode = "redCodeStatus")
    private String redConfirmCode;
    private String redConfirmCode_dictText;

    /**红字确认单状态编码-异步*/
    @ApiModelProperty(value = "红字确认单状态编码-异步")
    @Dict(dicCode = "redCodeStatus")
    private String redRtnCode;
    private String redRtnCode_dictText;

    

}

  上面代码顺序  Aop执行逻辑 => 自定义注解 => 在dto中的使用

posted @ 2025-08-15 10:54  Li_ll  Views(23)  Comments(0)    收藏  举报