沉梦手记 沉梦手记
首页
  • 基础篇
  • 集合篇
  • 并发篇
  • JVM
  • 新特性
  • 计算机网络
  • 操作系统
  • 数据结构与算法
  • 数据库基础
  • MySql
  • Redis
  • 达梦数据库
  • Spring
  • SpringBoot
  • Mybatis
  • Shiro
  • 设计须知
  • UML画图
  • 权限校验
  • 设计模式
  • API网关
  • 网络通信
  • 消息队列
  • SpringCloud
  • 分布式事务
  • 云存储
  • 搜索引擎
  • 前端环境搭建
  • HTML与CSS
  • JS学习
  • Axios入门
  • Vue Router入门
  • Pinia入门
  • Vue3入门
  • Vue3进阶
  • 黑马Vue3
  • 开发工具篇
  • 工具库篇
  • 开发技巧篇
  • 工具类系列
  • 运维与部署
  • 音视频处理
  • 随笔
  • 博客搭建
  • 网站收藏箱
  • 断墨寻径摘录
  • 费曼学习法
Github (opens new window)

沉梦听雨

时间是最好的浸渍剂,而沉淀是最好的提纯器🚀
首页
  • 基础篇
  • 集合篇
  • 并发篇
  • JVM
  • 新特性
  • 计算机网络
  • 操作系统
  • 数据结构与算法
  • 数据库基础
  • MySql
  • Redis
  • 达梦数据库
  • Spring
  • SpringBoot
  • Mybatis
  • Shiro
  • 设计须知
  • UML画图
  • 权限校验
  • 设计模式
  • API网关
  • 网络通信
  • 消息队列
  • SpringCloud
  • 分布式事务
  • 云存储
  • 搜索引擎
  • 前端环境搭建
  • HTML与CSS
  • JS学习
  • Axios入门
  • Vue Router入门
  • Pinia入门
  • Vue3入门
  • Vue3进阶
  • 黑马Vue3
  • 开发工具篇
  • 工具库篇
  • 开发技巧篇
  • 工具类系列
  • 运维与部署
  • 音视频处理
  • 随笔
  • 博客搭建
  • 网站收藏箱
  • 断墨寻径摘录
  • 费曼学习法
Github (opens new window)
  • 脚手架搭建
  • 瑞吉外卖

  • 黑马点评

  • vue-blog

  • 沉梦接口开放平台

  • 用户中心

  • 聚合搜索平台

  • 仿12306项目

  • 壁纸小程序项目

  • RuoYi-Vue

    • 若依学习笔记
      • 如何快速上手开源项目?
      • 文件结构
        • 后端结构
        • 前端结构
      • 1.1 什么是若依?
      • 1.2 使用若依
      • 1.3 登录
        • 1.3.1 生成验证码
        • 1.3.2 登录的具体流程
        • 1.3.3 getInfo
        • 1.3.4 getRouters
        • 1.4 用户管理
        • 1.5 添加数据
        • 1.6 修改数据
        • 1.7 删除数据
        • 1.8 异步任务管理器
        • 1.9 代码自动生成
        • 1、创建数据表
        • 2、系统工具 -> 代码生成
        • 3、编辑
        • 4、点击生成代码
        • 5、解压
        • 6、导入代码,重启项目
    • ruoyi-vue部署篇
    • 项目技术亮点
  • 项目笔记
  • RuoYi-Vue
沉梦听雨
2023-06-13
目录

若依学习笔记

# 若依(前后端分离版)

# 如何快速上手开源项目?

  • 先看前端,再看后端
  • 打开浏览器,检查网络,粘贴请求的路径
  • 看前端代码
  • 到后端代码按全局文件搜索:Ctrl + Shift + F 该路径,快速找到对应代码

# 文件结构

# 后端结构

com.ruoyi     
├── common            // 工具类
│       └── annotation                    // 自定义注解
│       └── config                        // 全局配置
│       └── constant                      // 通用常量
│       └── core                          // 核心控制
│       └── enums                         // 通用枚举
│       └── exception                     // 通用异常
│       └── filter                        // 过滤器处理
│       └── utils                         // 通用类处理
├── framework         // 框架核心
│       └── aspectj                       // 注解实现
│       └── config                        // 系统配置
│       └── datasource                    // 数据权限
│       └── interceptor                   // 拦截器
│       └── manager                       // 异步处理
│       └── security                      // 权限控制
│       └── web                           // 前端控制
├── ruoyi-generator   // 代码生成(可移除)
├── ruoyi-quartz      // 定时任务(可移除)
├── ruoyi-system      // 系统代码
├── ruoyi-admin       // 后台服务
├── ruoyi-xxxxxx      // 其他模块
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 前端结构

├── build                      // 构建相关  
├── bin                        // 执行脚本
├── public                     // 公共文件
│   ├── favicon.ico            // favicon图标
│   └── index.html             // html模板
│   └── robots.txt             // 反爬虫
├── src                        // 源代码
│   ├── api                    // 所有请求
│   ├── assets                 // 主题 字体等静态资源
│   ├── components             // 全局公用组件
│   ├── directive              // 全局指令
│   ├── layout                 // 布局
│   ├── plugins                // 通用方法
│   ├── router                 // 路由
│   ├── store                  // 全局 store管理
│   ├── utils                  // 全局公用方法
│   ├── views                  // view
│   ├── App.vue                // 入口页面
│   ├── main.js                // 入口 加载组件 初始化等
│   ├── permission.js          // 权限管理
│   └── settings.js            // 系统配置
├── .editorconfig              // 编码格式
├── .env.development           // 开发环境配置
├── .env.production            // 生产环境配置
├── .env.staging               // 测试环境配置
├── .eslintignore              // 忽略语法检查
├── .eslintrc.js               // eslint 配置项
├── .gitignore                 // git 忽略项
├── babel.config.js            // babel.config.js
├── package.json               // package.json
└── vue.config.js              // vue.config.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

# 1.1 什么是若依?

开源项目,学习开源项目的目标:

  1. 用,减少自己的工作量
  2. 学习优秀开源项目底层的编程思想,设计思路,提高自己的编程能力

官方文档:[介绍 | RuoYi (opens new window)](http://doc.ruoyi.vip/ruoyi-vue/)

更系统的学习,建议看官方文档

基础:Spring Boot + Vue

环境要求:

  1. JDK 1.8+
  2. MySQL
  3. Redis
  4. Maven
  5. Vue

# 1.2 使用若依

使用开源项目的步骤:

  1. 下载并运行
  2. 看懂业务流程
  3. 进行二次开发

具体操作:

  • 去官网下载源代码
  • 配置数据库 MySQL、Redis
  • 本地执行 SQL 脚本
  • 在工程中配置数据库 —— application-druid.yml 文件中修改
  • Redis 配置

启动前端:

  1. 安装依赖 npm install
  2. 启动 npm run dev

# 1.3 登录

# 1.3.1 生成验证码

基本思路:

后端生成一个表达式,如 1+1=2:

  • 1+1=?@2:1+1=? 转成图片,传到前端进行展示
  • 2(答案)存入 Redis

前端:

  • 请求地址:http://localhost/dev-api/captchaImage
  • 页面信息都在 views 文件夹里面
  • Vue 获取图片,前端还是后端?—— 后端
  • 反向代理,url 请求前端,进行代理,映射到后端,解决跨域问题

image

/dev-api 替换成'' 再映射到
http://localhost:8080
1
2

即:http://localhost:8080/captchaImage

后端:

到后端代码按全局文件搜索:Ctrl + Shift + F 该路径,快速找到对应代码

image

# 1.3.2 登录的具体流程

后端:

  1. 校验验证码
  2. 校验用户名和密码
  3. 生成 Token

使用异步任务管理器,结合线程池,实现了异步的操作。日志记录和业务逻辑实现异步解耦合。

# 1.3.3 getInfo

获取当前用户的角色和权限信息,存储到 Vuex 中。

* 是通配符,格式为 模块:菜单:功能:

// spring security 里面的东西
// 代表所有权限
*:*:*
1
2
3

image

后端相应代码:

image

# 1.3.4 getRouters

根据当前用户的权限获取动态路由,不同权限的用户,展现的菜单不一样。

parent_id 为 0 的是最高级菜单,其他为子菜单。

image

先查询出的是父节点菜单,子菜单包含在 children 里。

image

# 1.4 用户管理

流程:加载 Vue 页面 → 请求后台数据

  1. getList —— 加载用户管理列表

image

1.1、startPage() —— 分页

PageHelper 中的 reasonable 对参数进行逻辑处理,保证参数的正确性,当 pageNum = 0/-1 时,自动填写 pageNum = 1。

1.2、userService.selectUserList(user)

注解 @DataScope(deptAlias = "d", userAlias = "u") 给表设置别名,sys_dept d,sys_user u。

  1. treeselect —— 加载左边的树状图列表

    (1)查出所有的部门数据

    (2)组装成树状结构

    buildDeptTreeSelect:将 10 条记录组装成一个树状图。

    recursionFn(depts, dept):

    2.1、先找到顶级节点,找到它的子节点

    2.2、遍历顶级节点的子节点,再找到它的子节点

image

点击树状图中的数据:

image

# 1.5 添加数据

前端 —— 添加的方法:

image

  • reset 是表单重置
  • getTreeselect 获取部门树状图
  • getUser 获取角色和部门信息

后端 —— User 业务:

插入用户的方法包含插入三张表,目的是增添关联表的记录。

image

# 1.6 修改数据

image

这里的 getUser 方法除了要获取所有的岗位和角色信息之外,还要获取当前用户已经拥有的岗位和角色。

image

数据库:

  1. 修改 user
  2. 重新维护 user_post 和 user_role

修改的逻辑是:先删后增。这样子更加安全,不用判断是否存在。

image

# 1.7 删除数据

image

做判断,不能删除当前用户,并使用注解记录删除操作的日志信息到数据库中。

# 1.8 异步任务管理器

image

AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
1

通过异步任务管理器记录登录日志:

  1. AsyncManager.me() 获取一个 AsyncManager 对象

image

  1. 执行 execute 方法,执行任务,传入的是一个 Task 对象(在异步工厂的类里写),实现了 Runnable 接口,是一个任务,由线程 Thread 去执行。
/**
 * 记录登录信息
 * 
 * @param username 用户名
 * @param status 状态
 * @param message 消息
 * @param args 列表
 * @return 任务task
 */
public static TimerTask recordLogininfor(final String username, final String status, final String message,
        final Object... args)
{
    final UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
    final String ip = IpUtils.getIpAddr();
    return new TimerTask()
    {
        @Override
        public void run()
        {
            String address = AddressUtils.getRealAddressByIP(ip);
            StringBuilder s = new StringBuilder();
            s.append(LogUtils.getBlock(ip));
            s.append(address);
            s.append(LogUtils.getBlock(username));
            s.append(LogUtils.getBlock(status));
            s.append(LogUtils.getBlock(message));
            // 打印信息到日志
            sys_user_logger.info(s.toString(), args);
            // 获取客户端操作系统
            String os = userAgent.getOperatingSystem().getName();
            // 获取客户端浏览器
            String browser = userAgent.getBrowser().getName();
            // 封装对象
            SysLogininfor logininfor = new SysLogininfor();
            logininfor.setUserName(username);
            logininfor.setIpaddr(ip);
            logininfor.setLoginLocation(address);
            logininfor.setBrowser(browser);
            logininfor.setOs(os);
            logininfor.setMsg(message);
            // 日志状态
            if (StringUtils.equalsAny(status, Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER))
            {
                logininfor.setStatus(Constants.SUCCESS);
            }
            else if (Constants.LOGIN_FAIL.equals(status))
            {
                logininfor.setStatus(Constants.FAIL);
            }
            // 插入数据
            SpringUtils.getBean(ISysLogininforService.class).insertLogininfor(logininfor);
        }
    };
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

封装了登录用户的信息,执行添加操作,这里不会执行,而是将任务交给线程对象来执行。

异步任务管理器,内部定义了一个线程池,然后根据业务创建添加日志的任务,交给线程池来处理,这样做到日志和业务的抽象,解耦合,日志全部统一处理。

使用线程池有什么用?

提高线程利用率

# 1.9 代码自动生成

# 1、创建数据表

use ruoyi_vue;

create table test_user(
    id int primary key auto_increment,
    name varchar(11),
    password varchar(11)
);
1
2
3
4
5
6
7

# 2、系统工具 -> 代码生成

image

# 3、编辑

基本信息:

image

字段信息:

image

生成信息:

image

# 4、点击生成代码

image

# 5、解压

生成代码后下载压缩包,里面有三个文件:

  • main(Java 后端代码)
  • vue(Vue 前端代码)
  • SQL(菜单 SQL)

# 6、导入代码,重启项目

  • 如果后端抛出 404 异常,可能是因为代码刚导进项目,还未被扫描到
  • rebuild project,重新启动即可
上次更新: 2026/10/10 17:43:40
项目技术亮点
ruoyi-vue部署篇

← 项目技术亮点 ruoyi-vue部署篇→

Theme by Vdoing | Copyright © 2023-2026 沉梦听雨 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式