此前,我内置表单功能中,已有自动关联字典数据方式。由于,此前字典数据过于依赖表单字段,导致内存占用较高,字典数据重复性较大,字典缓存清理不便捷。
故,我欲改造之,将其与表单字段,单独剥离,并统一与功能对象进行关联,从而解决如上问题。
开发思路
后端,需设计"功能字典关联表"用于查询,独立"字典配置"注解,改造功能管理类。
前端,需提供通用字典获取函数,改造使用字典的元素如(下拉框、单选框、多选框等)。
整体看来,此次改造还是比较简单的,接下来就直接进入编码环节。
后端
orm对象表定义
java
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;
}
}
此对象,用于功能与字典之间的关联。当,用户获取功能时,后台通过此函数,自动装载入字典数据。
字典配置注解
java
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;
}
此注解,暂用于表单字段与字典配置的关联函数。
生成数据预览
可以看到,字典数据已于功能进行绑定。
接下来,我准备将字典数据,直接绑定至功能对象上,并返回给前端。
查询关联字典数据
为提升查询效率, 此处仍采用初次查询,后续缓存的方式。
java
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值。
java
/**
* 初始化功能字典数据
*
* @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);
}
}
至此,后端功能业已完成。此下,将进行改造前端功能。
前端
通用字典获取函数
js
/**
* 获取字典数据
*
* @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段中,故可以直接获取功能对象,并通过功能对象直接获取字典数据。
选择框元素
此下,我选了选择框元素进行改造,其他的复刻即可。
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);
}
});
至此,其他字典组件相继修改,既完成。