通用化重构
前面我们以一个实体为目标对象,完成了功能开发与调试。
在此基础上,我们对功能进行重构,使其成为平台的标准化、通用化的功能。
前端重构
首先,先把自定义组件挪到了平台公共组件目录下,如下:
然后将列表页面list.vue中原本写死的地方进行改造,原实现如下:
// 打开自定义查询对话框
customQuery() {
//TODO 更换为动态变量
this.$refs.customQuery.init('Template')
}
平台原本的实体配置会统一输出当前的实体类型编码,不过遵循的是小驼峰命名,如下:
在工具类增加一个首字母转大写的方法,转换下就能实现通用化,如下:
// 打开自定义查询对话框
customQuery() {
this.$refs.customQuery.init(this.$StringUtil.capitalizeFirstLetter(this.entityType))
}
完成上面工作,使用到自定义查询的列表页面list.vue,还是需要引入自定义查询组件。既然是通用标准化功能了,那就可以将其放到mixin中统一处理了,将自定义查询相关功能迁移到listMixin.js
中,如下:
经过上述迁移改造后,各实体的列表页面还剩下两部分,功能按钮和页面定义,如下:
调整列表视图list.vue的代码模板,将自定义查询功能默认输出,让用户多一种选择,如某个实体确定不需要该功能,开发人员可以人工移除,删两行代码,1分钟内就能完成。
后续可以调整平台实体配置功能,将是否启用自定义查询功能变为可配置项,并通过代码模板根据配置项输出或不输出查询按钮和自定义查询组件。
此外,还有一个小地方需要修改,把自定义查询的api,加入到公共方法常量中去,如下:
后端重构
后端重构实际简单的多,复杂的查询转换都是公共方法类,需要在controller的代码模板中增加自定义查询的方法即可,如下:
//region 扩展操作
/**
* 自定义查询
*/
@PostMapping("/customQuery")
@SystemLog(value = "${table.comment!}-自定义查询")
@PreAuthorize("hasPermission(null,'${package.ModuleName}:${entity?uncap_first}:query')")
public ResponseEntity<Result> customQuery(@RequestBody String customQueryString, PageInfo pageInfo, SortInfo sortInfo) {
// 构造分页对象
IPage<${entity}> page = new Page<${entity}>(pageInfo.getPageNum(), pageInfo.getPageSize());
// 构造查询条件
QueryWrapper<${entity}> queryWrapper = CustomQueryGenerator.generateQueryWrapper(${entity}.class, customQueryString, sortInfo);
// 查询数据
${entity?uncap_first}Service.page(page, queryWrapper);
// 转换vo
IPage<${entity}VO> pageVO = mapperFacade.map(page, IPage.class);
List<${entity}VO> ${entity?uncap_first}VOList=convert2VO(page.getRecords());
pageVO.setRecords(${entity?uncap_first}VOList);
return ResultUtil.success(pageVO);
}
//endregion
此外,需要将原先放在实体配置entityconfig模块下的工具类CustomQueryGenerator
移动到平台最底层的通用模块platform-common下,以便上层模块使用(若放在entityconfig,受依赖关系限制,系统管理下的实体如用户,就无法使用该工具类),如下:
同理,还有三个与筛选器组件相关的vo对象,也需要移动到platform-common模块下,如下:
功能测试
使用系统管理模块(system)下的用户实体作为测试,生成代码如下:
/**
* 自定义查询
*/
@PostMapping("/customQuery")
@SystemLog(value = "用户-自定义查询")
@PreAuthorize("hasPermission(null,'system:user:query')")
public ResponseEntity<Result> customQuery(@RequestBody String customQueryString, PageInfo pageInfo, SortInfo sortInfo) {
// 构造分页对象
IPage<User> page = new Page<User>(pageInfo.getPageNum(), pageInfo.getPageSize());
// 构造查询条件
QueryWrapper<User> queryWrapper = CustomQueryGenerator.generateQueryWrapper(User.class, customQueryString, sortInfo);
// 查询数据
userService.page(page, queryWrapper);
// 转换vo
IPage<UserVO> pageVO = mapperFacade.map(page, IPage.class);
List<UserVO> userVOList=convert2VO(page.getRecords());
pageVO.setRecords(userVOList);
return ResultUtil.success(pageVO);
}
在前端拷贝自定义查询按钮及自定义查询页面,运行如下:
整体无报错,但是发现BUG,查询方案的下拉列表显示的不仅仅是用户实体下的方案,连“模板”实体下的方案也显示出来了,推测是没加实体类型进行过滤,接下来修复该BUG。
BUG修复
修改查询方案的下拉列表,增加entityModelCode属性,监听该属性,如不为空则触发数据加载,如下:
<template>
<el-select
v-model="selectedValue"
:size="size"
clearable
:disabled="readonly"
style="width: 200px; margin: 20 auto"
@change="change"
>
<el-option
v-for="item in dictionaryItemList"
:key="item.id"
:value="item.id"
:label="item.name"
/>
</el-select>
</template>
<script>
export default {
name: 'QueryPlanSelect',
label: '查询方案下拉',
props: {
modelValue: {
type: String,
required: false,
default: ''
},
code: {
type: String,
default: ''
},
readonly: {
type: Boolean,
required: false,
default: false
},
size: {
type: String,
default: ''
},
entityModelCode: {
type: String,
default: ''
}
},
data() {
return {
dictionaryItemList: [],
selectedValue: ''
}
},
watch: {
modelValue: {
immediate: true,
handler: 'setSelected'
},
entityModelCode: {
immediate: true,
handler: 'loadData'
}
},
methods: {
change(value) {
let rowData = null
this.dictionaryItemList.forEach((item) => {
if (item.id === value) {
rowData = item
return
}
})
// 更新绑定值
this.$emit('update:modelValue', value)
// 注意,此处若命令为change,则可能会与底层实现冲突,导致执行两次
this.$emit('my-change', value, rowData)
},
setSelected() {
this.selectedValue = this.modelValue
},
loadData() {
if (this.entityModelCode) {
this.dictionaryItemList = []
this.$api.system.queryPlan.list({ entityModelCode: this.entityModelCode }).then((res) => {
this.dictionaryItemList = res.data
if (this.dictionaryItemList.length == 1) {
this.selectedValue = this.dictionaryItemList[0].id
this.$emit('my-change', this.dictionaryItemList[0].id, this.dictionaryItemList[0])
} else {
this.selectedValue = ''
this.$emit('my-change', '', null)
}
})
}
}
}
}
</script>
然后在自定义查询页面中,将模型编码绑定到查询方案下拉组件的属性上,如下:
<QueryPlanSelect
@my-change="queryPlanChanged"
:entity-model-code="entityModelCode"
ref="queryPlanSelect"
style="margin: auto 20px"
></QueryPlanSelect>
完成上述调整后,获取查询方案时就可以区分不同的实体了。
开源平台资料
平台名称:一二三开发平台
简介: 企业级通用开发平台
设计资料:[csdn专栏]
开源地址:[Gitee]
开源协议:MIT
如果您在阅读本文时获得了帮助或受到了启发,希望您能够喜欢并收藏这篇文章,为它点赞~
请在评论区与我分享您的想法和心得,一起交流学习,不断进步,遇见更加优秀的自己!