当前位置: 首页 > article >正文

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.kler.cn/a/586006.html

相关文章:

  • BOE(京东方)携手微博举办“微博影像年”年度影像大展 创新科技赋能专业影像惊艳呈现
  • 芯谷D8563TS:低功耗CMOS实时时钟/日历电路的优选方案
  • CentOS-7安装Docker(更新时间:2025-03-12)
  • markdown 转 word 工具 ‌Pandoc‌
  • 谷歌手机LEA流程
  • Vue 中的 transition 组件如何处理动画效果?
  • 世界坐标到UV纹理坐标的映射
  • PinnDE:基于物理信息神经网络的微分方程求解库
  • RabbitMQ入门:从安装到高级消息模式
  • axios配置全局接口超时时间
  • 某乎x-zse-96加密算法分析与还原
  • Leetcode3340:检查平衡字符串
  • 【漫话机器学习系列】132.概率质量函数(Probability Mass Function, PMF)
  • 软件性能测试与功能测试联系和区别
  • 开源:LMDB 操作工具:lmcmd
  • 笔试刷题专题(一)
  • 《MySQL数据库从零搭建到高效管理|表的增删改查(基础)》
  • STM32与HAL库开发实战:深入探索ESP8266的多种工作模式
  • 46. HarmonyOS NEXT 登录模块开发教程(一):模态窗口登录概述
  • Flask使用Blueprint注册管理路由