数据字典回显功能设计与实现

数据字典回显功能设计与实现

1. 业务场景

我们日常开发中经常会遇到:数据字典类型的字段存储至数据库的是id或者code,然而页面显示的时候却是名称

2. 实现设计

关于解决上述问题有以下几种方案:

2.1 注解+AOP切面

注解主要起标记作用,然后采用切面处理标记字段,把id或code转化成字典名称。这种方式可以灵活的标记是否需要回显转化处理,后面我采用这种方式举例说明

2.2 注解+mybatis拦截器

注解主要起标记作用,mybatis拦截器拦截之后,判断注解标记字段,把id或code转化成字典名称

2.3 注解+序列化

注解主要起标记作用,需增加专门的序列化处理器,序列化的过程中判断注解标记字段,把id或code转化成字典名称

2.4 涉及字段直接申明成字典引用类型+mybatis拦截器+反序列化处理

这种方式最为灵活,意思就是把涉及数据字典的字段,申明成字典类型(比如说DictData),前端就直接可以拿到字典的所有内容(包括id、code、名称)。

该种方式的实现需要三步操作
1.涉及字段直接申明成字典引用类型
2.mybatis拦截之后通过id或code补全字典数据
3.前端传递的id或code在反序列化的过程中补全字典数据

3. 具体实现

  • 定义方法标记注解,主要用来判断该接口是否需要字典转化
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface NeedEchoDict {

}
  • 定义字段标记注解,主要用来判断字典类型字段
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DictData {
    /**
     * 字典类型
     *
     * @return
     */
    String type() default "";
}
  • AOP切面处理
@Slf4j
@Aspect
@Component
public class DictEchoAspect {


    @Around("@annotation(com.jiayuan.common.annotation.NeedEchoDict)")
    public Object translation(final ProceedingJoinPoint pjp) throws Throwable {
        //目标方法执行
        Object resultR = pjp.proceed();
        if (ObjectUtil.isNull(resultR)) {
            return resultR;
        }

        //获取返回data值
        Object result = ((Result) resultR).getData();

        if (result instanceof PageData) {
            // 分页的情况
            PageData page = (PageData) result;
            result = ((PageData) result).getList();
            result = translate(result);
            page.setList((List) result);
            ((Result) resultR).setData(page);
            return resultR;
        }

        result = translate(result);
        ((Result) resultR).setData(result);
        return resultR;
    }


    /**
     * 返回值转换,增加字典回显
     *
     * @param result
     * @return
     */
    private Object translate(Object result) {
        if (result instanceof List || result instanceof ArrayList) {
            for (Object entity : (List) result) {
                to(entity);
            }
        } else {
            to(result);
        }
        return result;
    }


    /**
     * 根据类上注解,设置目标属性值
     *
     * @param entity 返回对象
     */
    public void to(Object entity) {
        Class c = entity.getClass();
        for (; c != Object.class; c = c.getSuperclass()) {
            try {
                Field[] fields = c.getDeclaredFields();
                for (Field field : fields) {
                    field.setAccessible(true);
                    Object preValue = field.get(entity);
                    Class<?> type = field.getType();

                    if (ObjectUtil.isNotNull(preValue)) {
                        //如果对象中包含list,判断list中是否包含注解
                        if (type.equals(List.class) || type.equals(ArrayList.class)) {
                            // 当前集合的泛型类型
                            Type genericType = field.getGenericType();
                            if (null == genericType) {
                                continue;
                            }

                            if (genericType instanceof ParameterizedType) {
                                for (Object o : (List) preValue) {
                                    to(o);
                                }
                            }
                        }

                        //todo 自定义对象方式
                        if (field.isAnnotationPresent(DictData.class)) {
                            final String dictName = DictCache.getDictName(preValue.toString());
                            //设置字典内容
                            field.set(entity, dictName);
                        }

                    }
                }
                //父类存在子类不存在情况
            } catch (Exception e) {
                log.error("字典回显失败:{}", JSONUtil.toJsonStr(entity));
                e.printStackTrace();
            }
        }
    }

}
  • 使用案例
@NeedEchoDict
@GetMapping("pageForApproval")
@ApiOperation("审批分页")
public Result<PageData<ApprovalAcademicActivityResponse>> pageForApproval(@Validated ApprovalAcademicActivityRequest request,
                                                                          @Validated PageDTO pageDTO) {
    PageData<ApprovalAcademicActivityResponse> page = academicActivityService.pageForApproval(request, pageDTO);
    return Result.ok(page);
}

@Data
@ApiModel(value = "审批分页学术活动结果")
public class ApprovalAcademicActivityResponse Serializable {
    private static final long serialVersionUID = -4402178057699015363L;

    @DictData
    @ApiModelProperty(value = "活动性质")
    private String activityNature;

    @DictData
    @ApiModelProperty(value = "活动范围")
    private String activityScope;
    
    。。。
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值