likes
comments
collection
share

fly coding字典改造(一):引用剥离,功能直接关联查询字典

作者站长头像
站长
· 阅读数 3

此前,我内置表单功能中,已有自动关联字典数据方式。由于,此前字典数据过于依赖表单字段,导致内存占用较高,字典数据重复性较大,字典缓存清理不便捷。

故,我欲改造之,将其与表单字段,单独剥离,并统一与功能对象进行关联,从而解决如上问题。

开发思路

后端,需设计“功能字典关联表”用于查询,独立“字典配置”注解,改造功能管理类。

前端,需提供通用字典获取函数,改造使用字典的元素如(下拉框、单选框、多选框等)。

整体看来,此次改造还是比较简单的,接下来就直接进入编码环节。

后端

orm对象表定义

package com.flycoding.drivenlibrary.engine.function.entity;

import com.flycoding.dblibrary.annotation.create.Column;
import com.flycoding.dblibrary.annotation.create.PrimaryAuto;
import com.flycoding.dblibrary.annotation.create.Table;
import com.flycoding.dblibrary.enums.ColumnType;
import com.flycoding.drivenlibrary.engine.constants.SqlConstants;
import com.flycoding.drivenlibrary.engine.function.entity.base.BaseFunctionMessage;

/**
 * 功能字典关联表
 *
 * @author 赵屈犇
 * @version 1.0
 * @date 创建时间: 2022/10/18 20:47
 * @Copyright(C): 2022 by 赵屈犇
 */
@Table(tableName = "Sy_Func_Dict")
public class FuncDictInfo extends BaseFunctionMessage {

    /** 主键 */
    @PrimaryAuto
    private Integer id;
    /** 普通字典编码 */
    @Column(columnName = "dict_code", columnType = ColumnType.VARCHAR, length = SqlConstants.DB_CODE_SIZE)
    private String dictCode;
    /** 数据字典编码 */
    @Column(columnName = "data_dict_code", columnType = ColumnType.VARCHAR, length = SqlConstants.DB_CODE_SIZE)
    private String dataDictCode;
    /** 字典驱动库关联配置编码 */
    @Column(columnName = "db_config_code", columnType = ColumnType.VARCHAR, length = SqlConstants.DB_CODE_SIZE)
    private String dbConfigCode;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getDictCode() {
        return dictCode;
    }

    public void setDictCode(String dictCode) {
        this.dictCode = dictCode;
    }

    public String getDataDictCode() {
        return dataDictCode;
    }

    public void setDataDictCode(String dataDictCode) {
        this.dataDictCode = dataDictCode;
    }

    public String getDbConfigCode() {
        return dbConfigCode;
    }

    public void setDbConfigCode(String dbConfigCode) {
        this.dbConfigCode = dbConfigCode;
    }
}

此对象,用于功能与字典之间的关联。当,用户获取功能时,后台通过此函数,自动装载入字典数据。

字典配置注解

package com.threeox.drivenlibrary.engine.annotation.function.form.field;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 字典配置
 *
 * @author 赵屈犇
 * @version 1.0
 * @date 创建时间: 2022/10/18 20:18
 * @Copyright(C): 2022 by 赵屈犇
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.ANNOTATION_TYPE })
public @interface DictConfig {

    /**
     * 普通字典编码
     *
     * @return
     */
    String dictCode() default "";

    /**
     * 数据字典编码
     *
     * @return
     */
    String dataDictCode() default "";

    /**
     * 字典驱动库关联配置
     *
     * @return
     */
    String dbConfigCode() default "";
    /**
     * 是否使用配置
     *
     * @return
     */
    boolean isUseConfig() default true;

}

此注解,暂用于表单字段与字典配置的关联函数。

生成数据预览

fly coding字典改造(一):引用剥离,功能直接关联查询字典

可以看到,字典数据已于功能进行绑定。

接下来,我准备将字典数据,直接绑定至功能对象上,并返回给前端。

查询关联字典数据

为提升查询效率, 此处仍采用初次查询,后续缓存的方式。

package com.threeox.drivenlibrary.engine.function.factory.config;

import com.threeox.drivenlibrary.cache.impl.function.FuncDictCacheManager;
import com.threeox.drivenlibrary.engine.constants.config.request.ConfigRequestConstants;
import com.threeox.drivenlibrary.engine.function.entity.FuncDictInfo;
import com.threeox.drivenlibrary.engine.function.factory.base.BaseCustomFactory;
import com.threeox.drivenlibrary.engine.request.execute.ExecuteRequestFactory;

import java.util.List;

/**
* 功能字典关联工厂
*
* @author 赵屈犇
* @version 1.0
* @date 创建时间: 2022/10/20 20:42
* @Copyright(C): 2022 by 赵屈犇
*/
public class FuncDictFactory extends BaseCustomFactory<List<FuncDictInfo>> {

    private static FuncDictFactory inst = null;

    public static FuncDictFactory getInstance() {
        if (inst == null) {
            synchronized (FuncDictFactory.class) {
                if (inst == null) {
                    inst = new FuncDictFactory();
                }
            }
        }
        return inst;
    }

    private FuncDictFactory() {
    }

    @Override
    protected void init() {
    }

    @Override
    protected void initCacheManager() {
        cache = FuncDictCacheManager.getInstance();
    }

    @Override
    protected List<FuncDictInfo> initResult(ExecuteRequestFactory requestFactory, String dbConfigCode, Object key, Integer relatedId, Object... extendParams) throws Exception {
        // 查询关联字典配置根据功能主键
        return getResult(requestFactory, ConfigRequestConstants.QUERY_FUNC_DICT_BY_FUNC_ID, relatedId);
    }
}

绑定字典结果至功能

最后,我在获取功能对象时,动态获取字典配置,并绑定字典结果数据。

为兼容普通字典和数据字典主键可能重复问题,我根据dictCode,dataDictCode,dbConfigCode进行拼接,生成新的key值。

/**
* 初始化功能字典数据
*
* @param functionInfo
* @return a
* @author 赵屈犇
* @date 创建时间: 2022/10/20 20:58
* @version 1.0
*/
private void initFuncDictData(FunctionMessage functionInfo) {
    if (functionInfo != null) {
    // 获取关联字典数据
    List<FuncDictInfo> dictInfos = funcDictFactory.getResult(functionInfo.getDbConfigCode(), functionInfo.getFuncCode(), functionInfo.getFuncId());
    if (ArrayUtils.isNotEmpty(dictInfos)) {
        Map <String, List<DictDataInfo>> dictMap = new HashMap<>();
        dictInfos.forEach(dictInfo - > {
            // key
            String key = StringUtils.appendStrings(dictInfo.getDictCode(), dictInfo.getDataDictCode(), dictInfo.getDbConfigCode());
            if (!dictMap.containsKey(key)) {
                List<DictDataInfo> dictionaryInfos = null;
                // 普通字典
                if (StringUtils.isNotEmpty(dictInfo.getDictCode())) {
                    // 普通字典类型
                    dictionaryInfos = dictFactory.getResult(dictInfo.getDbConfigCode(), dictInfo.getDictCode());
                    // 数据字典
                } else if (StringUtils.isNotEmpty(dictInfo.getDataDictCode())) {
                    dictionaryInfos = dataDictResultFactory.getResult(dictInfo.getDataDictCode());
                }
                dictMap.put(key, dictionaryInfos);
            }
        });
        functionInfo.setDictDatas(dictMap);
    }
}

至此,后端功能业已完成。此下,将进行改造前端功能。

前端

通用字典获取函数

/**
 * 获取字典数据
 *
 * @param elementConfig
 * @returns {null|*}
 */
engine.getDictData = function (elementConfig) {
    if (self.funcMessage) {
        let key = [elementConfig['dictCode'], elementConfig['dataDictCode'], elementConfig['dictDBConfigCode']].join(
            "");
        return self.funcMessage.dictDatas[key];
    }
    return null;
}

此函数,内置在基础引擎js段中,故可以直接获取功能对象,并通过功能对象直接获取字典数据。

选择框元素

此下,我选了选择框元素进行改造,其他的复刻即可。

// 定义选择框元素
let selectView = factory.byId("${fieldCode}");
// 定义过滤lay
let layFilter = "${fieldCode}_" + self.containerId;
// 设置属性
selectView.attr("lay-filter", layFilter);
// 获取字典
let dicts = factory.getDictData(elementConfig);
if (!engineCommon.isListEmpty(dicts)) {
  for (let i = 0, length = dicts.length; i < length; i++) {
    try {
      let dict = dicts[i];
      let dictionaryValue = dict["dictionaryValue"];
      let optionHtml = "<option name='" + layFilter + "' id='${fieldCode}_" + dictionaryValue + "' value='" + dictionaryValue + "'>" + dictionary["dictionaryName"] + "</option>";
      selectView.append(optionHtml);
    } catch(e) {
      console.log(e);
    }
  }
  layFactory.render('select');
}
// 监听选中事件
layFactory.on(LayEventConstants.SELECT, layFilter, function(data){
  selectView.val(data.value);
  // 回调lay事件
  if (self.factory && self.factory['onLayEvent']) {
    self.factory.onLayEvent('${fieldCode}', LayEventConstants.SELECT, data);
  }
});

至此,其他字典组件相继修改,既完成。