SpringBoot注解驱动CRUD工具:spring-avue-plus

项目背景

作为一个后端小伙伴,最大的痛点就是写完的接口需要拥有一些可视化的页面去承载这些功能使用【如果是只给后端那么swagger也足够了,非后端有点呛】如果有专业前端去弄确实也快,但是小公司呀~~~

学呗~妈呀,现在的前端也挺卷,vue3啊element-ui呀typescript啊vite啊【我其实只想要一个简单的页面维护数据】

了解到AVue之后,觉得挺不错,降低不少门槛。内置的组件还挺多,嗯,不错。如果能把这种能力赋能给后端就更好了。

项目地址:

  • https://github.com/liukaixiong/spring-avue-plus
  • https://gitee.com/liukaixiong/spring-avue-plus

💡 为什么需要它?

  • 后端写完接口后,不想写前端又需要数据维护页面?
  • 小团队没有专业前端,自己学Vue/TS太头疼
  • 想用最简单的方式实现增删改查界面?试试注解驱动的AVue集成方案!

✨ 核心优势

零前端基础:不用搭前端环境,SpringBoot项目直接集成
注解即页面:Java注解定义表单,自动生成可视化CRUD
5分钟速成:从实体类到完整页面,一杯咖啡的时间搞定
丰富组件库:输入框/下拉选择/文件上传/JSON编辑器…全都有
无缝兼容:支持SpringBoot 2.x/3.x,JDK8+

如果你有后端一些基础功能需要简单的页面维护、又不想单独搞一套前端环境、可以尝试体验一下。

如何使用?

1、clone 项目

2、编译项目

mvn install 

3、客户端引入依赖

<dependency><groupId>com.liukx.spring</groupId><artifactId>spring-avue-starter</artifactId><version>2.0.0-SNAPSHOT</version>
</dependency>

4、启用注解

@EnableAVue(basePackages = {"你的模版路径"}, enumsPackages = {"你的枚举路径"})
  • 模版类路径指定【必填】
  • 枚举类路径指定【非必填】 : enumsPackagesenumsPackagesClasses
  • 静态资源指定【非必填】: jsonResourceDir

开启avue的接口扫描能力

5、定制模版

案例整体参考测试用例… com.liukx.spring.client.model

6、访问路径

端口号请更换成你的项目端口号

路径地址路径描述
http://localhost:9403/avue/server-crud?group=你的模版groupKey查看crud的列表页面
http://localhost:9403/avue/avue-component?group=avueUrlList所有avue的路由模版卡片列表
http://localhost:9403/avue/list所有avue的路由模版卡片列表[上面的简化版]

以上步骤即可渲染出增删改查页面,内置丰富的组件能力。详细参考AVue的crud

模版测试介绍

单个实体进行测试

com.ruoyi.client.handler.AVueAnnotationHandlerTest : 可针对单个实体进行测试得到JSON字符串.

整体测试

com.ruoyi.client.RuoYiClientTestApplication : 针对整个client配置进行测试

1、简单的模版

com.liukx.spring.client.model.AVueSimpleModel

@AVueRouteKey(groupKey = "test-config")
@AVueCrudOption(title = "这是一个测试")
// 增删改查的接口定义
@AVueConfig(list = AVueConfigControllerTest.LIST_URL, update = AVueConfigControllerTest.UPDATE_URL, save =
// 返回结果定义AVueConfigControllerTest.UPDATE_URL, successKeyword = "true", successField = "success", messageField = "message")
public class AVueSimpleModel {@AVueInput(prop = "id", label = "主键", addDisplay = false, row = true, editDisabled = true, search = true)private String id;@AVueInput(prop = "configGroup", label = "组名称", search = true, row = true, rules = {@AVueRule(required = true, message = "组名称要填咧"), @AVueRule(min = 5, max = 10, message = "我跟你讲最小5个,最大10个.")})private String configGroup;@AVueInput(prop = "configName", label = "配置名称", search = true, required = true, row = true)private String configName;@AVueSelect(prop = "configCode", label = "配置值", dicData = "StatusEnums", search = true, required = true, row = true)private String configCode;@AVueNumber(prop = "validDay", label = "有效天数", search = true, required = true, row = true)private Integer validDay;@AVueSwitch(prop = "status", label = "状态", dicData = "StatusEnums", row = true)private int status;}
对应的展示效果

在这里插入图片描述

在这里插入图片描述

2、复杂的模版

test目录下 : com.ruoyi.client.model.AVueCrudModel

// 每个模版的标识,根据该标识路径能访问到该地址
@AVueRouteKey(groupKey = "test-route", title = "复杂模版路由", description = "这个是用来处理一些比较复杂的模版,里面涵盖了crud,按钮,以及后端的接口路径的定义,包括分页的参数设置等等一系列的demo操作", img = "https://gw.alipayobjects.com/zos/rmsportal/WdGqmHpayyMjiEhcKoVE.png")
// 表格的标题,整个CRUD的配置,和table渲染相关的
@AVueCrudOption(title = "这是一个复杂的模版", dialogClickModal = true, dialogDrag = true, border = true, viewBtn = true)
// 构建自己的页面自定义数据结构
//@AVuePage(pageData = "data", pageNumber = "pageNo", pageSize = "pSize", pageTotal = "pageTotal")
// 适配后台服务的对应的处理接口
@AVueConfig(list = AVueControllerTest.LIST_URL, update = AVueControllerTest.UPDATE_URL, save = AVueControllerTest.UPDATE_URL, successKeyword = "true", successField = "success", messageField = "message")
// 设置后台接口调用之后成功或者失败的结构模型
@AVueEventButtons(// 每一行的按钮及事件定义tableRowButtons = {// 指定方法名称按钮事件名称@AVueClickButton(methodName = AVueJsFunctionEnum.confirmClickRemoteApi, btnName = "确认按钮", attrExt = {@AVueAttr(name = "title", value = "小伙子,你确定吗?有惊喜喔!"),@AVueAttr(name = "url", value = AVueControllerTest.BODY_URL)}),// 指定事件@AVueClickButton(type = "success", btnName = "弹层按钮测试", methodName = AVueJsFunctionEnum.openWindowJsonRemote, attrExt = {// 当前弹层的提交路径@AVueAttr(name = "submitUrl", value = AVueControllerTest.BODY_URL),// 找下一个模版@AVueAttr(name = "group", value = "test-config"),// 由于不是同一套模版,允许将数据结构进行转换填充。这里指定关系@AVueAttr(name = "fieldConvertMap", value = "dataJson=configJson&&age=validDay")}),// 指定事件@AVueClickButton(type = "success", btnName = "复制拓展字段", methodName = AVueJsFunctionEnum.copyField, attrExt = {// 当前弹层的提交路径@AVueAttr(name = "name", value = "dataJson"),}),// 指定事件@AVueClickButton(type = "success", btnName = "复制行", methodName = AVueJsFunctionEnum.copyField)},// 左上角按钮事件tableTopLeftButtons = {@AVueClickButton(methodName = AVueJsFunctionEnum.hrefClick, btnName = "跳转链接", type = "success", icon = "el-icon-setting", attrExt = {@AVueAttr(name = "url", value = "https://www.baidu.com")})}
)
public class AVueCrudModel {/*** 注解介绍** @AVueInput: 组件类型以@AVue开始,后面是具体的组件。* - input  : 代表文本框* - select : 代表选择框* - number : 代表数字框* - json   : 代表json组件* <p>* 属性介绍:* addDisplay       : 表示新增的时候是否展示* editDisabled     : 表示修改的时候是否不可编辑* search           : 代表列表页是否为搜索条件* searchRequired   : 代表搜索条件是否为必填* dicData          : 代表枚举字典* dicUrl           : 代表后台拉取对象* 具体属性释义可参考 :  <a href="https://avuejs.com/views/doc.html">...</a>* 注解文档参考 : <a href="https://gitee.com/liukaixiong/RuoYi-AVue-Plus/blob/master/doc/annotation.md">...</a>*/@AVueInput(prop = "id", label = "主键", addDisplay = false, editDisabled = true, search = true)private String id;@AVueInput(prop = "username", label = "用户名称", search = true, searchRequired = true, onClick = "testB")private String username;// 普通枚举@AVueSelect(prop = "checkStatus", label = "认证状态", dicData = "CheckStatusEnums", search = true)private String checkStatus = CheckStatusEnums.FOOTBALL.getCode().toString();@AVueSelect(prop = "likeStar", label = "喜欢明星", dicData = "test-likeStar-map")private Integer likeStar;@AVueSelect(label = "远端字典", dicUrl = "http://localhost:8765" + AVueControllerTest.DIC_URL, props = "{'label':'label','value':'value','res':'data'}", dicMethod = "post", dicQuery = "{'key':'key'}", search = true)private String remoteDic;/*** 联动 省市区*/@AVueSelect(label = "省份", cascader = {"city"}, dicUrl = "https://cli.avuejs.com/api/area/getProvince", props = "{'label':'name','value':'code'}", dicMethod = "get", dicQuery = "{'key':'key'}", search = true)private String province;@AVueSelect(label = "城市", cascader = {"area"}, dicUrl = "https://cli.avuejs.com/api/area/getCity/{{key}}?province={{province}}", props = "{'label':'name','value':'code'}", dicMethod = "get", dicQuery = "{'key':'key'}", search = true)private String city;@AVueSelect(label = "地区", dicUrl = "https://cli.avuejs.com/api/area/getArea/{{key}}?city={{city}}", props = "{'label':'name','value':'code'}", dicMethod = "get", dicQuery = "{'key':'key'}", search = true)private String area;@AVueNumber(prop = "age", label = "年龄", labelTip = "这是选择年龄的地方")private Integer age = 18;@AVueRadio(prop = "sex", label = "性别", border = true, dicData = "SexEnums")private int sex = (int) SexEnums.UNKNOWN.getCode();@AVueDatetime(prop = "validDate", label = "有效时间")private Date validDate;@AVueTime(prop = "time", label = "时分秒选择")private Date time;@AVueTimeRange(prop = "timeRange", label = "时分秒范围", rangeSeparator = "-")private List<String> timeRange;@AVueDateRange(prop = "dateRange", rangeSeparator = "-", label = "日期范围", searchRange = true, search = true)private List<Date> dateRange;@AVueCheckbox(prop = "interest", label = "兴趣爱好", dicData = "InterestEnums")private List<String> interest;@AVueSwitch(prop = "status", label = "状态", dicData = "StatusEnums")private int status;/*** 单图上传*/@AVueUpload(prop = "image", label = "单图上传", listType = "picture-img", action = "/upload", propsHttp = @AVueUploadPropsHttp(res = "single", name = "fileName"))private String image;/*** 多图上传*/@AVueUpload(prop = "imageList", dataType = "array", listType = "picture-card", label = "单图上传", action = "/upload", propsHttp = @AVueUploadPropsHttp(res = "single", name = "fileName"))private List<String> imageList;/*** json组件*/@AVueJson(prop = "dataJson", label = "拓展字段")private String dataJson;/*** 支持模版嵌套*/@AVueDynamic(prop = "simpleModel", label = "子表单测试")private AVueNodeModel simpleModel;/*** 支持分组类型*/@AVueGroup(prop = "groupModel", label = "分组测试1")private AVueNodeModel groupModel;@AVueGroup(prop = "groupModel2", label = "分组测试2")private AVueNodeModel groupModel2;
}
展示效果

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

更多测试案例:com.liukx.spring.client.model

3. 配置项

spring-avue-starter/src/test/resources/application.yml

spring:avue:debug: true  # 开发环境开启调试模式,IDEA-> Build -> Rebuild 模版类即可立即生效enable-login: true  # 是否开启登录模式username: admin     # 登录帐号password: 1234      # 登录的密码

📚 详情了解

项目地址:

  • https://github.com/liukaixiong/spring-avue-plus
  • https://gitee.com/liukaixiong/spring-avue-plus

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

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

相关文章

manus对比ChatGPT-Deep reaserch进行研究类学术相关数据分析!谁更胜一筹?

没有账号&#xff0c;只能挑选一个案例 一夜之间被这个用全英文介绍全华班出品的新爆款国产AI产品的小胖刷频。白天还没有切换语言的选项&#xff0c;晚上就加上了。简单看了看团队够成&#xff0c;使用很长实践的Monica创始人也在其中。逐渐可以理解&#xff0c;重心放在海外产…

蛋白质功能预测论文阅读记录2025(DPFunc、ProtCLIP)

前言 最近研究到瓶颈了&#xff0c;怎么优化都提升不了&#xff0c;遂开始看点最新的论文。 DPFunc 2025.1.2 Nature Communication 中南大学 论文地址&#xff1a;DPFunc: accurately predicting protein function via deep learning with domain-guided structure inform…

c语言经典案例题

1. 交换两个数的值&#xff1a; #include <stdio.h> #define CRT_SECURE_NO_WARNINGS int main() {int a 5, b 10, c 0;c a;a b;b c;printf("a%d b%d", a, b); } 2. 键盘录入一个数组判断数组最大值&#xff1a; #include <stdio.h> #define CR…

facebook游戏投广:提高广告关键数据的方法

在当今竞争激烈的数字营销领域&#xff0c;游戏广告的投放效果直接关系到游戏公司的市场表现和盈利能力。然而&#xff0c;许多游戏公司在广告投放上面临着诸多挑战&#xff0c;如高昂的成本、低效的转化率以及难以追踪的效果。那么&#xff0c;如何才能通过数据分析真正提升游…

《MySQL数据库从零搭建到高效管理|库的基本操作》

目录 一、数据库的操作 1.1 展示数据库 1.2 创建数据库 1.3 使用数据库 1.4 查看当前数据库 1.5 删除数据库 1.6 小结 二、常用数据类型 2.1 数值类型 2.2 字符串类型 2.3 日期类型 一、数据库的操作 打开MySQL命令行客户端&#xff0c;安装完MySQL后会有两个客户端…

告别复杂日志解析 用bin2sql轻松实现MySQL数据闪回

mysqlbinlog⼯具使用 use test; CREATE TABLE t1 (id INT(11) NOT NULL AUTO_INCREMENT,name VARCHAR(20) DEFAULT NULL,PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;INSERT INTO t1(id, name) SELECT 101, tome101; INSERT INTO t1(id, name) SELECT 102, tome1…

工业三防平板AORO-P300 Ultra,开创铁路检修与调度数字化新范式

在现代化铁路系统的庞大网络中&#xff0c;其设备维护与运营调度的精准性直接影响着运输效率和公共安全。在昼夜温差大、电磁环境复杂、震动粉尘交织的铁路作业场景中&#xff0c;AORO-P300 Ultra工业三防平板以高防护标准与智能化功能体系&#xff0c;开创了铁路行业移动端数字…

Microsoft Dragon Copilot:医疗AI革命开启,用语音终结手写病历时代

微软正式发布全球首个医疗行业一体化语音AI助手Microsoft Dragon Copilot,标志着临床工作流程正式迈入“人机协作”新时代。这款工具通过语音+文本混合架构,将医生口述内容实时转化为结构化病历,并深度整合电子健康记录(EHR)系统,彻底颠覆了传统手写病历模式。根据微软官…

数据库约束

数据库约束 1. NULL约束2. UNIQUE&#xff1a;唯一约束3. DEFAULT&#xff1a;默认值约束4. PRIMARY KEY&#xff1a;主键约束5. FOREIGN KEY&#xff1a;外键约束6. CHECK约束 数据库约束是关系型数据库的一个重要功能&#xff0c;主要作用是保证数据的正确性&#xff0c;也就…

NetAssist 5.0.14网络助手基础使用及自动应答使用方案

以下是NetAssist v5.0.14自动应答功能的详细使用步骤&#xff1a; 一、基础准备&#xff1a; 工具下载网址页面&#xff1a;https://www.cmsoft.cn/resource/102.html 下载安装好后&#xff0c;根据需要可以创建多个server&#xff0c;双击程序图标运行即可&#xff0c;下面…

ChatGPT课件分享(37页PPT)

资料解读&#xff1a;ChatGPT课件分享 详细资料请看本解读文章的最后内容。 近年来&#xff0c;人工智能技术的迅猛发展引发了全球范围内的广泛关注&#xff0c;尤其是以OpenAI为代表的公司在自然语言处理领域的突破性进展&#xff0c;彻底改变了人机交互的方式。本文将详细解…

【机器学习】主成分分析法(PCA)

【机器学习】主成分分析法&#xff08;PCA&#xff09; 一、摘要二、主成分分析的基本概念三、主成分分析的数学模型五、主成分分析法目标函数公式推导&#xff08;梯度上升法求解目标函数&#xff09;六、梯度上升法求解目标函数第一个主成分七、求解前n个主成分及PCA在数据预…

【蓝桥杯—单片机】第十五届省赛真题代码题解析 | 思路整理

第十五届省赛真题代码题解析 前言赛题代码思路笔记竞赛板配置建立模板明确基本要求显示功能部分频率界面正常显示高位熄灭 参数界面基础写法&#xff1a;两个界面分开来写优化写法&#xff1a;两个界面合一起写 时间界面回显界面校准校准过程校准错误显示 DAC输出部分按键功能部…

重邮数字信号处理-实验六用 MATLAB 设计 IIR 数字滤波器

一、实验目的 1、加深对 IIR 数字滤波器设计方法和设计步骤的理解&#xff1b; 2、掌握用模拟滤波器原型设计 IIR 数字滤波器的方法&#xff1b; 3、能编写 MATLAB 函数&#xff0c;掌握设计 IIR 数字滤波器的函数调用方法&#xff1b; 4、根据不同的应用场景&#xff0…

Linux中的基本指令(下)

目录 mv指令 more指令 less指令 head指令 tail 指令 继续理解文件 重定向和追加重定向操作 理解管道 find指令 whereis 指令 bc指令 uname ‒r指令 grep 指令 关机 扩展命令 zip/unzip 指令 tar指令 关于rzsz 系统间的文件互传 接上&#xff01; mv指令 m…

Python文件,模块

一.文件 1.生成一个文件: 2. 提示 : 第二次读时因为之前已经对文件进行了读取操作&#xff0c;文件指针可能已经移动到了文件末尾。在这种情况下&#xff0c;再次调用 read() 方法将不会读取到任何新的内容&#xff0c;因为已经没有未读取的数据了。可以使用 seek() 方法将文…

基于python的升级队列加速决策

a-f大等级是3级 a-c建筑每升1级分别需要8天 d-f建筑每升1级分别需要10天 目前以下建筑队列正在从0级升至1级 建筑A升级需要7天05&#xff1a;16&#xff1a;20 建筑b升级需要06&#xff1a;06&#xff1a;54 建筑c升级需要00&#xff1a;37&#xff1a;00 建筑d升级需要…

编译OpenSSL

OpenSSL简介 OpenSSL是一个用于加密和安全连接的开源软件库。它提供了一系列的加密算法、密码学功能和安全协议的实现&#xff0c;包括SSL&#xff08;Secure Sockets Layer&#xff09;和TLS&#xff08;Transport Layer Security&#xff09;等用于网络安全的协议。OpenSSL可…

Win 转 MacBook Pro 踩坑指南

前言 Window 和 macOS 系统的差异还是很大的&#xff0c;我从 Thinkpad 转用 M1 的 Macbook pro 已经一年了&#xff0c;几乎没有任何不适应&#xff0c;整体感受那是真的牛&#x1f443;&#xff0c;速度和续航惊艳到我了&#xff0c;同时开启 6个 vscode 加几十个浏览器标签…

uniapp uniCloud引发的血案(switchTab: Missing required args: “url“)!!!!!!!!!!

此文章懒得排版了&#xff0c;为了找出这个bug, 星期六的晚上我从9点查到0点多&#xff0c;此时我心中一万个草泥马在崩腾&#xff0c;超级想骂人&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; uniCloud 不想…