Skip to content

Repository files navigation

logo

RuoYi v3.9.1

基于SpringBoot+Vue前后端分离的Java快速开发框架

介绍地址

B站 https://www.bilibili.com/video/BV15V9AYgEvL/?share_source=copy_web&vd_source=a4c1f9a58f1a8dd2e581c0f88e037fca

抖音 https://v.douyin.com/i5jgjvss/

1

2

增加功能

在不影响若依原本功能基础上,集成mybatisPlus、lombok、数据批量插入、优化前端代码生成

  1. 集成mybatisPlus 3.5.9
  2. 集成lombok 1.18.36
  3. 根据lombok、mybatisPlus与业务生成对应的dto和vo
  4. 生成lombok和mybatisPlus的代码
  5. 优化web前端生成,如果是文件类型生成的代码列表可以直接下载,动态显隐列,长文本内容可以隐藏
  6. 批量生成数据
  7. 批量导入功能

1、集成mybatisPlus 3.5.9与lombok 1.18.24

        <lombok.version>1.18.36</lombok.version>
        <mybatis-plus.version>3.5.9</mybatis-plus.version>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
                <optional>true</optional>
            </dependency>

            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
                <version>${mybatis-plus.version}</version>
            </dependency>

2、在自己需要导入mybatisPlus的模块导入依赖

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
        </dependency>

YY_2026-03-19_17-40-29

3、根据lombok、mybatisPlus与业务生成对应的dto和vo

image-20250227112112873

实体

package com.ruoyi.test.model.domain;

import java.io.Serializable;
import java.util.Map;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import com.ruoyi.common.annotation.Excel;
import com.fasterxml.jackson.annotation.JsonInclude;
/**
 * 位置信息对象 tb_address_info
 *
 * @author ruoyi
 * @date 2025-02-27
 */
@TableName("tb_address_info")
@Data
public class AddressInfo implements Serializable
{
    private static final long serialVersionUID = 1L;

    /** 编号 */
    @Excel(name = "编号")
    @TableId(value = "id", type = IdType.ASSIGN_ID)
    private Long id;

    /** 父级编号 */
    @Excel(name = "父级编号")
    private Long parentId;

    /** 位置名称 */
    @Excel(name = "位置名称")
    private String name;

    /** 类型 */
    @Excel(name = "类型")
    private String addressType;

    /** 图片 */
    @Excel(name = "图片")
    private String imageInfo;

    /** 文件 */
    @Excel(name = "文件")
    private String fileInfo;

    /** 备注 */
    @Excel(name = "备注")
    private String remark;

    /** 状态 */
    @Excel(name = "状态")
    private String status;

    /** 创建人 */
    @Excel(name = "创建人")
    private Long userId;

    /** 创建时间 */
    @JsonFormat(pattern = "yyyy-MM-dd")
    @Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd")
    private Date createTime;

    /** 更新时间 */
    @JsonFormat(pattern = "yyyy-MM-dd")
    @Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd")
    private Date updateTime;

    /** 请求参数 */
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    @TableField(exist = false)
    private Map<String, Object> params;
}

VO

package com.ruoyi.test.model.vo.addressInfo;

import java.io.Serializable;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import com.ruoyi.common.annotation.Excel;
import org.springframework.beans.BeanUtils;
import com.ruoyi.test.model.domain.AddressInfo;
/**
 * 位置信息Vo对象 tb_address_info
 *
 * @author ruoyi
 * @date 2025-02-27
 */
@Data
public class AddressInfoVo implements Serializable
{
    private static final long serialVersionUID = 1L;

    /** 编号 */
    @Excel(name = "编号")
    private Long id;

    /** 父级编号 */
    @Excel(name = "父级编号")
    private Long parentId;

    /** 位置名称 */
    @Excel(name = "位置名称")
    private String name;

    /** 类型 */
    @Excel(name = "类型")
    private String addressType;

    /** 图片 */
    @Excel(name = "图片")
    private String imageInfo;

    /** 文件 */
    @Excel(name = "文件")
    private String fileInfo;

    /** 备注 */
    @Excel(name = "备注")
    private String remark;

    /** 状态 */
    @Excel(name = "状态")
    private String status;

    /** 创建人 */
    @Excel(name = "创建人")
    private Long userId;

    /** 创建时间 */
    @JsonFormat(pattern = "yyyy-MM-dd")
    @Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd")
    private Date createTime;

    /** 更新时间 */
    @JsonFormat(pattern = "yyyy-MM-dd")
    @Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd")
    private Date updateTime;


 /**
 * 对象转封装类
 *
 * @param addressInfo AddressInfo实体对象
 * @return AddressInfoVo
 */
    public static AddressInfoVo objToVo(AddressInfo addressInfo) {
        if (addressInfo == null) {
            return null;
        }
        AddressInfoVo addressInfoVo = new AddressInfoVo();
        BeanUtils.copyProperties(addressInfo, addressInfoVo);
        return addressInfoVo;
    }
}

编辑DTO

package com.ruoyi.test.model.dto.addressInfo;

import java.io.Serializable;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.beans.BeanUtils;
import com.ruoyi.test.model.domain.AddressInfo;
/**
 * 位置信息Vo对象 tb_address_info
 *
 * @author ruoyi
 * @date 2025-02-27
 */
@Data
public class AddressInfoEdit implements Serializable
{
    private static final long serialVersionUID = 1L;

    /** 编号 */
    private Long id;

    /** 父级编号 */
    private Long parentId;

    /** 位置名称 */
    private String name;

    /** 类型 */
    private String addressType;

    /** 图片 */
    private String imageInfo;

    /** 文件 */
    private String fileInfo;

    /** 备注 */
    private String remark;

    /** 状态 */
    private String status;

    /** 创建人 */
    private Long userId;

    /**
     * 对象转封装类
     *
     * @param addressInfoEdit 编辑对象
     * @return AddressInfo
     */
    public static AddressInfo editToObj(AddressInfoEdit addressInfoEdit) {
        if (addressInfoEdit == null) {
            return null;
        }
        AddressInfo addressInfo = new AddressInfo();
        BeanUtils.copyProperties(addressInfoEdit, addressInfo);
        return addressInfo;
    }
}

插入DTO

package com.ruoyi.test.model.dto.addressInfo;

import java.io.Serializable;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.beans.BeanUtils;
import com.ruoyi.test.model.domain.AddressInfo;
/**
 * 位置信息Vo对象 tb_address_info
 *
 * @author ruoyi
 * @date 2025-02-27
 */
@Data
public class AddressInfoInsert implements Serializable
{
    private static final long serialVersionUID = 1L;

    /** 编号 */
    private Long id;

    /** 父级编号 */
    private Long parentId;

    /** 位置名称 */
    private String name;

    /** 类型 */
    private String addressType;

    /** 图片 */
    private String imageInfo;

    /** 文件 */
    private String fileInfo;

    /** 备注 */
    private String remark;

    /** 状态 */
    private String status;

    /** 创建人 */
    private Long userId;

    /**
     * 对象转封装类
     *
     * @param addressInfoInsert 插入对象
     * @return AddressInfoInsert
     */
    public static AddressInfo insertToObj(AddressInfoInsert addressInfoInsert) {
        if (addressInfoInsert == null) {
            return null;
        }
        AddressInfo addressInfo = new AddressInfo();
        BeanUtils.copyProperties(addressInfoInsert, addressInfo);
        return addressInfo;
    }
}

查询DTO

package com.ruoyi.test.model.dto.addressInfo;

import java.util.Map;
import java.io.Serializable;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonInclude;
import org.springframework.beans.BeanUtils;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.baomidou.mybatisplus.annotation.TableField;
import com.ruoyi.test.model.domain.AddressInfo;
/**
 * 位置信息Query对象 tb_address_info
 *
 * @author ruoyi
 * @date 2025-02-27
 */
@Data
public class AddressInfoQuery implements Serializable
{
    private static final long serialVersionUID = 1L;

    /** 父级编号 */
    private Long parentId;

    /** 位置名称 */
    private String name;

    /** 类型 */
    private String addressType;

    /** 状态 */
    private String status;

    /** 创建人 */
    private Long userId;

    /** 创建时间 */
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date createTime;

    /** 更新时间 */
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date updateTime;

    /** 请求参数 */
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    @TableField(exist = false)
    private Map<String, Object> params;

    /**
     * 对象转封装类
     *
     * @param addressInfoQuery 查询对象
     * @return AddressInfo
     */
    public static AddressInfo queryToObj(AddressInfoQuery addressInfoQuery) {
        if (addressInfoQuery == null) {
            return null;
        }
        AddressInfo addressInfo = new AddressInfo();
        BeanUtils.copyProperties(addressInfoQuery, addressInfo);
        return addressInfo;
    }
}

前端页面优化展示

image-20250227112620456

批量插入

image-20250227112750064

公共功能

1.自定义缓存

1.缓存注解

/**
 * 自定义缓存注解,父类字段无法拿到
 * 坚持是前行的舟
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomCacheable {
    String keyPrefix();          // 缓存 key 的前缀,你要设置的key的前缀

    String keyField() default "";           // 从方法入参中提取 key 的字段路径(支持嵌套字段)

    long expireTime() default 3600L; // 缓存时间(秒)

    boolean paginate() default false; // 是否启用分页缓存

    String pageNumberField() default ""; // 页码字段(如果 paginate 为 true,则使用该字段)

    String pageSizeField() default "";  // 每页大小字段(如果 paginate 为 true,则使用该字段)

    boolean useQueryParamsAsKey() default false; // 是否将整个查询对象转换为 JSON 字符串作为缓存 key 的一部分
}

2. 删除缓存

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CustomCacheEvict {

    String[] keyPrefixes();     //你定义的缓存前缀

    String[] keyFields() default {}; // 支持嵌套,如 "request.userId"

    boolean useQueryParamsAsKey() default false; // 如果true,加上参数JSON串模糊删除

}

2.自定义排序

  1. 注解
/**
 * 自定义排序注解
 * 首先我希望我变好,也希望你
 *
 * @Author: YY
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CustomSort {
    /*
       createTime-create_time,这样一一对应,对应数据库字段
     */
    String[] sortFields() default {};   //排序字段,就是你前端传过来的字段,一一对应

    String[] sortMappingFields() default {}; //映射字段,前端只需要传过来字段名,如果多表查询设置映射字段,映射字段为查询时所需字段
}
  1. 查询mapper
        <choose>
            <when test="params.sortSql != null and params.sortSql != ''">
                ${params.sortSql}
            </when>
            <otherwise>
                order by create_time desc
            </otherwise>
        </choose>
  1. 使用
    @CustomSort(
            sortFields = {"usageCount", "lookCount", "downloadCount", "createTime", "updateTime", "orderNum"},
            sortMappingFields = {
                    "usage_count", "look_count", "download_count", "create_time", "update_time", "order_num"
            })
    @Override
    public List<PictureCategoryInfo> selectPictureCategoryInfoList(PictureCategoryInfo pictureCategoryInfo) {
        return pictureCategoryInfoMapper.selectPictureCategoryInfoList(pictureCategoryInfo);
    }
  1. 前端使用,此注解当前主要使用在管理端,目前演示的是vue3,如果vue2也可以参考这个,具体实现需要自己去实现

  2. 在el-table加上@sort-change="customSort"自定义排序方法和ref

    <el-table ref="tableRef" v-loading="loading" :data="accountInfoList" @selection-change="handleSelectionChange" @sort-change="customSort">
  1. 在字段加上自定义排序标志
      <el-table-column label="充值总金额" align="center" prop="rechargeAmount" sortable="custom"
                       v-if="columns[6].visible" :show-overflow-tooltip="true"/>
  1. 排序字段
const isAsc = ref();
const orderByColumn = ref('');
  1. 新增方法
//自定义排序
function customSort({column, prop, order}) {
  if (prop !== undefined && prop !== '' && order !== null && order !== '') {
    orderByColumn.value = prop;
    isAsc.value = order === "ascending";
  } else {
    orderByColumn.value = null;
    isAsc.value = null;
  }
  queryParams.value.pageNum = 1;
  getList();
}
  1. 在getList添加
  if (orderByColumn.value != null && isAsc.value !== null) {
    queryParams.value.params["orderByColumn"] = orderByColumn.value;
    queryParams.value.params["isAsc"] = isAsc.value;
  }
  1. 在重置按钮更新ref
/** 重置按钮操作 */
function resetQuery() {
  daterangeCreateTime.value = [];
  daterangeUpdateTime.value = [];
  orderByColumn.value = null
  isAsc.value = null;
  proxy.resetForm("queryRef");
  proxy.$refs.tableRef.clearSort();
  handleQuery();
}

3.异常抛出工具类

/**
 * 异常处理工具类
 *
 * @Author YY
 */
public class ThrowUtils {

    /**
     * 条件成立则抛异常
     *
     * @param condition        条件
     * @param runtimeException 异常
     */
    public static void throwIf(boolean condition, RuntimeException runtimeException) {
        if (condition) {
            throw runtimeException;
        }
    }

    /**
     * 条件成立则抛异常
     *
     * @param condition 条件
     * @param message   错误信息
     */
    public static void throwIf(boolean condition, String message) {
        throwIf(condition, new ServiceException(message));
    }

    /**
     * 条件成立则抛异常
     *
     * @param condition 条件
     * @param errorCode 错误码
     * @param message   错误信息
     */
    public static void throwIf(boolean condition, Integer errorCode, String message) {
        throwIf(condition, new ServiceException(message, errorCode));
    }
}

平台简介

若依是一套全部开源的快速开发平台,毫无保留给个人及企业免费使用。

  • 前端采用Vue、Element UI。
  • 后端采用Spring Boot、Spring Security、Redis & Jwt。
  • 权限认证使用Jwt,支持多终端认证系统。
  • 支持加载动态权限菜单,多方式轻松权限控制。
  • 高效率开发,使用代码生成器可以一键生成前后端代码。
  • 提供了技术栈(Vue3 Element Plus Vite)版本RuoYi-Vue3,保持同步更新。
  • 提供了单应用版本RuoYi-Vue-fast,Oracle版本RuoYi-Vue-Oracle,保持同步更新。
  • 不分离版本,请移步RuoYi,微服务版本,请移步RuoYi-Cloud
  • 阿里云折扣场:点我进入,腾讯云秒杀场:点我进入  

内置功能

  1. 用户管理:用户是系统操作者,该功能主要完成系统用户配置。
  2. 部门管理:配置系统组织机构(公司、部门、小组),树结构展现支持数据权限。
  3. 岗位管理:配置系统用户所属担任职务。
  4. 菜单管理:配置系统菜单,操作权限,按钮权限标识等。
  5. 角色管理:角色菜单权限分配、设置角色按机构进行数据范围权限划分。
  6. 字典管理:对系统中经常使用的一些较为固定的数据进行维护。
  7. 参数管理:对系统动态配置常用参数。
  8. 通知公告:系统通知公告信息发布维护。
  9. 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。
  10. 登录日志:系统登录日志记录查询包含登录异常。
  11. 在线用户:当前系统中活跃用户状态监控。
  12. 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。
  13. 代码生成:前后端代码的生成(java、html、xml、sql)支持CRUD下载 。
  14. 系统接口:根据业务代码自动生成相关的api接口文档。
  15. 服务监控:监视当前系统CPU、内存、磁盘、堆栈等相关信息。
  16. 缓存监控:对系统的缓存信息查询,命令统计等。
  17. 在线构建器:拖动表单元素生成相应的HTML代码。
  18. 连接池监视:监视当前系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈。

在线体验

  • admin/admin123
  • 陆陆续续收到一些打赏,为了更好的体验已用于演示服务器升级。谢谢各位小伙伴。

演示地址:http://vue.ruoyi.vip
文档地址:http://doc.ruoyi.vip

演示图

若依前后端分离交流群

QQ群: 加入QQ群 加入QQ群 加入QQ群 加入QQ群 加入QQ群 加入QQ群 加入QQ群 加入QQ群 加入QQ群 加入QQ群 加入QQ群 加入QQ群 加入QQ群 加入QQ群 加入QQ群 加入QQ群 加入QQ群 加入QQ群 加入QQ群 加入QQ群 加入QQ群 加入QQ群 加入QQ群 加入QQ群 点击按钮入群。

About

若依框架电子合同管理平台

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages