低代码配置功能实现得好,能大幅提升开发效率。但是不得不说,在平台里按照规范和约定一步步来操作,在某些情况下确实不如源码开发灵活和方便,存在类似的配置工作重复执行繁琐枯燥的情况。这时候,就需要平台进一步提升操作的便捷性,来提升配置效率。
如何提升呢?
核心思路有两个,一是基于面向对象的继承思路;二是来源于原型设计模式的原型拷贝思路。
基于平台的顶层设计,实体建立了统一的基类,在基类里定义了标识、创建人、创建时间、修改人、修改时间、版本号(乐观锁)、逻辑删除标志位。这几个字段,主要是技术相关,与业务关联性不大。
所有业务上的实体类,都继承自此基类 。
可以根据实际业务情况,继承该基类,扩展新属性,形成新的父类。
实体配置的时候,选择需要继承的父类,只添加新的属性即可。
通过继承的方式,避免了重复配置,提升了效率。
平台实现了复制新增功能,可以在数据列表页面,直接选中一条或多条数据,然后点击“复制新增”按钮,系统会自动以选中的数据为原型,复制新数据出来。例如在实体属性配置环节,如果一个要创建属性,跟已创建的一个属性差不多,都是数据字典或日期类型,则可以通过复制新增的方式,快速生成1条新记录,然后修改下名称和编码就可以了,其他属性都可以保持跟参照数据一致,也可以微调,从而实现快速配置的目的。
需要注意的是,该功能是跳过了数据验证环节,因此记得及时修改通过复制新增产生的记录,要不然很可能系统中会出现2条相同的数据,违反数据约束规则。
此外,为了区分哪条是新增的,平台会在数据主属性后自动附加“ 副本”来识别。
复制新增功能已经在平台底层实现,由所有实体的基类BaseServiceImpl实现
/**
* 复制新增
*
* @param idListString id列表字符串,多个id用逗号间隔
* @return
*/
@Transactional(rollbackFor = Exception.class)
@Override
public boolean addByCopy(String idListString, String... value) {
String[] idArray = StringUtils.split(idListString.toString(), ",");
for (String item : idArray) {
T entity = getEntity(item);
T newEntity = init();
mapperFacade.map(entity, newEntity);
// 清空系统属性
newEntity.setId(null);
newEntity.setCreateId(null);
newEntity.setCreateTime(null);
newEntity.setUpdateId(null);
newEntity.setUpdateTime(null);
newEntity.setVersion(1);
newEntity.setDeleteFlag(null);
// 拷贝属性处理
copyPropertyHandle(newEntity, value);
super.save(newEntity);
afterAddByCopy(entity, newEntity);
}
return true;
}
具体的实现类,可以根据实际需求,覆写copyPropertyHandle方法即可。
基本的复制新增,可以提升“点”的开发效率,接下来要说的级联处理,则可以带来“面”的提升。
系统中管理的业务实体,除了最简单的单一层级,大多存在两级或多级关联关系。
以实体配置模块的视图功能为例,视图自身的属性没几个,配置起来比较简单,但视图对应的配置起来很复杂。如果通过复制新增的方式只是拷贝视图自身,带来的提升有限。这时候,就可以通过级联的复制新增的方式将从属的视图配置也一块创建出来。
例如,同一实体模型的编辑视图以及查看视图,与新增视图高度相似,可以先将新增视图配置好,然后复制新增来创建编辑视图和查看视图。列表视图配置工作更加复杂,对应多种配置信息(页面按钮、查询条件、查询结果、行按钮),通过级联复制的方式,提升的效率非常可观。
实际上,我们完全可以做到更进一步,对一个实体进行级联复制,从顶层到最底层,一块打包复制。也就是,对实体进行复制新增,同时会拷贝实体从属的数据模型,数据模型从属的视图,视图从属的视图配置。
实际上,得益于平台的设计,以上功能实现起来并不复杂,虽然级联复制的是多层级的对象,但对于当前层级而言,只需要负责直接从属的对象拷贝工作,不需要关注间接从属对象。
在复制新增这条路上,可以走得更远一些。为了提升配置效率,我们可以预先做一些配置,形成标准模板,后续可以直接基于模板复制新增,再在其基础上调整,也能提升不少开发效率。
下面来说下视图按钮模板和实体模板。
系统中不同实体的视图,功能按钮是类似的,例如列表页面的刷新、新增、删除,行记录的修改、删除、启用、停用等。每个页面重复配置,效率低下。为了快速配置,可以采用预配置模式,形成按钮模板,如下图所示:
按钮模板维护界面如下:
编码是按钮的唯一性标识,也对应着点击按钮触发的方法名。
内容属性中可以直接写js方法体,该属性非必须,常用的方法实现,往往已经在mixin中实现了,只有自定义方法,或想覆盖mixin默认实现的情况下才需要填充内容。
图标就是按钮的图标,如设置了,则会生成带图标的按钮。
是否需要确认,若是,则需要进一步输入确认信息,代码生成时会调用confirm对话框。
是否更多,主要是考虑某些功能的功能项比较多,从而对应的按钮比较多,一行放不下或者节省行按钮占用空间,一些冷僻不常用功能,统一放到一个“更多”的下拉菜单中。
在视图配置时,可以直接从按钮模板库中选择预置按钮,快速生成视图的按钮,并可以在其基础上修改。
如上图所示,我们预先配置一个名为“模板”的实体,把常用的属性,如名称、编码、排序、备注预先配置好,再加上不同数据类型的字段,如数据字典、日期、时间。同时该模板预置了常用的列表、新增、修改、查看视图。
需要建实体的时候,如果系统中已经有类似的实体,可以基于实体复制,如果没有,则可以基于该模板复制,在其基础上调整。
通过复制新增先创建后调整的模式,有些数据通过修改保留下来了,但不可避免会有一些数据不适用,需要删除,这样就产生了一定量的逻辑删除数据。客观地说,这部分数据的数据量有限,对系统几乎没有影响,不过还是可以通过一个简易的方式来清理。
写一个sql存储过程,遍历库表,将逻辑删除的记录物理删除,具体脚本如下:
CREATE PROCEDURE `clear_records_logic_delete`()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE schema_name VARCHAR(64);
DECLARE table_name VARCHAR(64);
DECLARE delete_sql VARCHAR(1000);
DECLARE cur CURSOR FOR
SELECT t.TABLE_SCHEMA, t.TABLE_NAME
FROM information_schema.TABLES t,INFORMATION_SCHEMA.COLUMNS c
WHERE t.TABLE_SCHEMA='abc'
AND t.TABLE_NAME=c.TABLE_NAME
AND c.COLUMN_NAME='delete_flag';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cur;
read_loop: LOOP
FETCH cur INTO schema_name, table_name;
IF done THEN
LEAVE read_loop;
END IF;
SET @delete_sql = CONCAT('DELETE FROM ', table_name, ' WHERE delete_flag = \'YES\'');
PREPARE stmt FROM @delete_sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END LOOP;
CLOSE cur;
END;
开发阶段可以通过该脚本来清理这些配置过程中产生的逻辑删除数据,但不要在生产环境干这事。并且为了避免误操作,生产库就不要放这脚本。
平台名称:一二三开发平台
简介: 企业级通用开发平台
设计资料:csdn专栏
开源地址:Gitee
开源协议:MIT
欢迎收藏、点赞、评论,你的支持是我前行的动力。