一二三应用开发平台自定义查询设计与实现系列3——通用化重构

通用化重构

前面我们以一个实体为目标对象,完成了功能开发与调试。

在此基础上,我们对功能进行重构,使其成为平台的标准化、通用化的功能。

前端重构

首先,先把自定义组件挪到了平台公共组件目录下,如下:

然后将列表页面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);// 转换voIPage<${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);// 转换voIPage<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-selectv-model="selectedValue":size="size"clearable:disabled="readonly"style="width: 200px; margin: 20 auto"@change="change"><el-optionv-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 = nullthis.dictionaryItemList.forEach((item) => {if (item.id === value) {rowData = itemreturn}})// 更新绑定值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.dataif (this.dictionaryItemList.length == 1) {this.selectedValue = this.dictionaryItemList[0].idthis.$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
如果您在阅读本文时获得了帮助或受到了启发,希望您能够喜欢并收藏这篇文章,为它点赞~
请在评论区与我分享您的想法和心得,一起交流学习,不断进步,遇见更加优秀的自己!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/464526.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RabbitMQ交换机类型

RabbitMQ交换机类型 1、RabbitMQ工作模型2、RabbitMQ交换机类型2.1、Fanout Exchange&#xff08;扇形&#xff09;2.1.1、介绍2.1.2、示例2.1.2.1、生产者2.1.2.2、消费者2.1.2.3、测试 2.2、Direct Exchange&#xff08;直连&#xff09;2.2.1、介绍2.2.2、示例2.2.2.1、生产…

qt QMenuBar详解

1、概述 QMenuBar是Qt框架中用于创建菜单栏的类&#xff0c;它继承自QWidget。QMenuBar通常位于QMainWindow对象的标题栏下方&#xff0c;用于组织和管理多个QMenu&#xff08;菜单&#xff09;和QAction&#xff08;动作&#xff09;。菜单栏提供了一个水平排列的容器&#x…

数据转换 | Matlab基于SP符号递归图(Symbolic recurrence plots)一维数据转二维图像方法

目录 基本介绍程序设计参考资料获取方式 基本介绍 Matlab基于SP符号递归图&#xff08;Symbolic recurrence plots&#xff09;一维数据转二维图像方法 符号递归图(Symbolic recurrence plots)是一种一维时间序列转图像的技术&#xff0c;可用于平稳和非平稳数据集;对噪声具有…

特殊矩阵的压缩存储

一维数组的存储结构 ElemType arr[10]; 各数组元素大小相同&#xff0c;且物理上连续存放。 数组元素a[i]的存放地址 LOC i * sizeof(ElemType)。&#xff08;LOC为起始地址&#xff09; 二维数组的存储结构 ElemType b[2][4];二维数组也具有随机存取的特性&#xff08;需…

MySQL utf8mb3 和 utf8mb4引发的问题

问题描述 Cause: java.sql.SQLException: Incorrect string value: \xF4\x8F\xBB\xBF-b... for column sddd_aaa_ark at row 1 sddd_aaa_ark 存储中文字符时&#xff0c;出现上述问题 原因分析 sddd_aaa_ark在数据库中结构是 utf8字符的最大字节数是3 byte&#xff0c;但是某些…

RK3568开发板Openwrt文件系统构建

RK3568开发板Openwrt文件系统构建 iTOP-RK3568开发板使用教程更新&#xff0c;后续资料会不断更新&#xff0c;不断完善&#xff0c;帮助用户快速入门&#xff0c;大大提升研发速度。 本次更新内容为《iTOP-3568开发板文件系统构建手册》&#xff0c;对Openwrt文件系统的编译…

Linux之crontab使用

一&#xff0c;查看cron是否已经在运行 查看crontab的运行状态 sudo service cron statussystemctl status cron 开启crontab: sudo service cron startsudo service cron restart 二&#xff0c;编辑cron定时任务 crontab -e加入你自己的命令&#xff0c;定时跑脚本&a…

OpenEuler 使用ffmpeg x11grab捕获屏幕流,rtsp推流,并用vlc播放

环境准备 安装x11grab(用于捕获屏幕流)和libx264(用于编码) # 基础开发环境&x11grab sudo dnf install -y \autoconf \automake \bzip2 \bzip2-devel \cmake \freetype-devel \gcc \gcc-c \git \libtool \make \mercurial \pkgconfig \zlib-devel \libX11-devel \libXext…

矩阵的奇异值分解SVD

为了论述矩阵的奇异值与奇异值分解!需要下面的结论!

H5开发指南|掌握核心技术,玩转私域营销利器

随着互联网技术的不断发展和用户需求的日益增长&#xff0c;H5页面逐渐成为了企业和个人展示信息、吸引用户关注的重要手段。具有跨平台兼容性强、网页链接分享、更新迭代方便快捷、低开发成本、可搜索和优化、数据分析与追踪、灵活性与扩展性以及无需下载安装等特点。不仅可以…

Ubuntu Linux

背景 Ubuntu起源于南非&#xff0c;其名称“Ubuntu”来源于非洲南部祖鲁语或豪萨语&#xff0c;意为“人性”、“我的存在是因为大家的存在”&#xff0c;这体现了非洲传统的一种价值观。Ubuntu由南非计算机科学家马克沙特尔沃斯&#xff08;Mark Shuttleworth&#xff09;创办…

你适合哪种tiktok广告账户类型?

TikTok在广告营销方面的分类体系极为详尽。在开设广告账户时&#xff0c;根据不同的海外市场和商品类型&#xff0c;TikTok会有各自的开户标准。此外&#xff0c;广告主所开设的TikTok广告账户类型会直接影响其可投放的广告类型。在广告出价方面&#xff0c;广告主的营销目标不…

平衡者:陈欣的宇宙使命

第一章 异象初现 2145年&#xff0c;地球已经不再是人类唯一的家园。随着科技的飞速发展&#xff0c;人类在银河系内建立了多个殖民星球。然而&#xff0c;这些新世界的繁荣背后隐藏着一个巨大的危机——各个星球之间的资源分配不均&#xff0c;导致了严重的社会动荡和冲突。 …

《AI产品经理手册》——解锁AI时代的商业密钥

在当今这个日新月异的AI时代&#xff0c;每一位产品经理都面临着前所未有的挑战与机遇&#xff0c;唯有紧跟时代潮流&#xff0c;深入掌握AI技术的精髓&#xff0c;才能在激烈的市场竞争中独占鳌头。《AI产品经理手册》正是这样一部为AI产品经理量身定制的实战宝典&#xff0c;…

React第十三章(useTransition)

useTransition useTransition 是 React 18 中引入的一个 Hook&#xff0c;用于管理 UI 中的过渡状态&#xff0c;特别是在处理长时间运行的状态更新时。它允许你将某些更新标记为“过渡”状态&#xff0c;这样 React 可以优先处理更重要的更新&#xff0c;比如用户输入&#x…

使用wordcloud与jieba库制作词云图

目录 一、WordCloud库 例子&#xff1a; 结果&#xff1a; 二、Jieba库 两个基本方法 jieba.cut() jieba.cut_for_serch() 关键字提取&#xff1a; jieba.analyse包 extract_tags() 一、WordCloud库 词云图&#xff0c;以视觉效果提现关键词&#xff0c;可以过滤文本…

2024年云手机推荐榜单:高性能云手机推荐

无论是手游玩家、APP测试人员&#xff0c;还是数字营销工作者&#xff0c;云手机都为他们带来了极大的便利。本文将为大家推荐几款在市场上表现优异的云手机&#xff0c;希望这篇推荐指南可以帮助大家找到最适合自己的云手机&#xff01; 1. OgPhone云手机 OgPhone云手机是一款…

Template Method(模板方法)

1)意图 定义一个操作中的算法骨架&#xff0c;而将一些步骤延迟到子类中。Template Method 使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 2)结构 模板方法模式的结构图如图7-47 所示。 其中: AbstractClass(抽象类) 定义抽象的原语操作&#xff0c;具体…

自研小程序-心情追忆

在近期从繁忙的工作中暂时抽身之后&#xff0c;我决定利用这段宝贵的时间来保持我的Java技能不致生疏&#xff0c;并通过一个个人项目来探索人工智能的魅力。 我在Hugging Face&#xff08;国内镜像站点&#xff1a;HF-Mirror&#xff09;上发现了一个关于情感分析的练习项目&…

【设计模式】策略模式定义及其实现代码示例

文章目录 一、策略模式1.1 策略模式的定义1.2 策略模式的参与者1.3 策略模式的优点1.4 策略模式的缺点1.5 策略模式的使用场景 二、策略模式简单实现2.1 案例描述2.2 实现代码 三、策略模式的代码优化3.1 优化思路3.2 抽象策略接口3.3 上下文3.4 具体策略实现类3.5 测试 参考资…