让Ai阅读若依源码?秒懂若依【后端六大模块】+【前端架构】+【主子表联动】
在 Java 快速开发领域,若依(RuoYi) 毫无疑问是很多企业的首选脚手架。它就像一把瑞士军刀,开箱即用。但很多开发者在使用时,往往陷入了“舒适区陷阱”:❌ 只会点“下一步”生成单表 CRUD,遇到**“主子表(一对多)”**这种稍微复杂的业务就卡壳;❌ 需求一变,不知道改 Controller 还是 Service,甚至搞不清 ruoyi-common 和 ruoyi-system 的区别;
在 Java 快速开发领域,若依(RuoYi) 毫无疑问是很多企业的首选脚手架。它就像一把瑞士军刀,开箱即用。
但很多开发者在使用时,往往陷入了“舒适区陷阱”:
❌ 只会点“下一步”生成单表 CRUD,遇到**“主子表(一对多)”**这种稍微复杂的业务就卡壳;
❌ 需求一变,不知道改 Controller 还是 Service,甚至搞不清 ruoyi-common 和 ruoyi-system 的区别;
❌ 面试被问到“若依如何保证主子表数据一致性”,支支吾吾答不上来。
只会用工具,你永远只是“API 调用工程师”;只有拆解工具,你才能进阶为架构师。
今天,我将结合多年的 Java 实战经验与 AI 辅助编程心得,带你通过一次“外科手术式”的拆解,彻底搞懂若依的前后端架构。本文包括以下几个章节,将详细介绍若依框架架构。每个章节分别讲述以下内容:
-
项目概览
-
后端6大模块详解:每个模块的职责、功能、依赖关系
-
前端结构分析:目录结构、前后端对应关系、核心组件
-
CRUD完整流程:包含主子表操作实战案例
-
技术架构深度解析 AI 提示词(Prompt)

核心技术栈

二、后端模块详解
项目采用Maven多模块结构,共6个核心模块:
2.1 模块结构树状图
ruoyi (父工程)
├── ruoyi-admin [应用入口层]
├── ruoyi-framework [框架核心层]
├── ruoyi-system [业务实现层]
├── ruoyi-common [通用工具层]
├── ruoyi-generator [代码生成层]
├── ruoyi-quartz [定时任务层]
└── ruoyi-vue [前端vue页面层]
2.2 各模块详细职责
① ruoyi-admin - 应用入口层
职责:整个应用的启动入口和Web接口暴露
核心内容:
RuoYiApplication.java:Spring Boot启动类
controller目录:存放各种业务Controller
system:系统管理相关接口(用户、角色、菜单等)
monitor:系统监控接口(在线用户、日志等)
tool:工具接口(代码生成、Swagger等)
依赖关系:
依赖 ruoyi-framework(获取安全配置)
依赖 ruoyi-quartz(定时任务)
依赖 ruoyi-generator(代码生成)
新手小贴士:这是你启动项目运行的模块,相当于"总指挥"。所有HTTP请求的入口都在这里的Controller中。
② ruoyi-framework - 框架核心层
职责:提供安全认证、拦截器、配置等框架级功能核心内容:
framework/
├── config/ [配置类]
│ ├── SecurityConfig.java // Spring Security配置
│ ├── RedisConfig.java // Redis配置
│ ├── DruidConfig.java // 数据库连接池配置
│ └── MyBatisConfig.java // MyBatis配置
├── security/ [安全模块]
│ ├── filter/
│ │ └── JwtAuthenticationTokenFilter.java // JWT过滤器
│ ├── handle/ // 认证失败、退出处理器
│ └── service/ // 用户详情、权限服务
├── aspectj/ [切面]
│ ├── LogAspect.java // 日志切面
│ ├── DataScopeAspect.java // 数据权限切面
│ └── RateLimiterAspect.java // 限流切面
└── web/service/
└── TokenService.java // Token管理服务
关键设计思想:
JWT无状态认证:不使用Session,通过Token实现分布式会话
过滤器链:
请求
→ CorsFilter(跨域)
→ JwtAuthenticationTokenFilter(Token验证)
→ SecurityFilterChain(权限校验)
→ Controller
AOP切面编程:通过注解实现日志、权限、限流等功能
依赖关系:
依赖 ruoyi-common(工具类)
依赖 ruoyi-system(用户、菜单等业务)
③ ruoyi-system - 业务实现层
职责:系统核心业务逻辑实现
标准分层结构(以用户管理为例):
system/
├── controller/
│ └── SysUserController.java [接口层] 接收HTTP请求
├── service/
│ ├── ISysUserService.java [接口定义]
│ └── impl/
│ └── SysUserServiceImpl.java [业务逻辑]
├── mapper/
│ └── SysUserMapper.java [数据访问接口]
├── domain/
│ └── SysUser.java [实体类]
└── resources/mapper/
└── SysUserMapper.xml [SQL映射文件]
内置功能模块:
用户管理(sys_user)
角色管理(sys_role)
菜单管理(sys_menu)
部门管理(sys_dept)
岗位管理(sys_post)
字典管理(sys_dict)
参数配置(sys_config)
操作日志(sys_oper_log)
登录日志(sys_logininfor)
依赖关系:依赖 ruoyi-common(工具类、基类)
④ ruoyi-common - 通用工具层
职责:提供项目通用组件、工具类、常量、异常等
核心内容:
common/
├── annotation/ [自定义注解]
│ ├── Log.java // 操作日志注解
│ ├── DataScope.java // 数据权限注解
│ ├── RepeatSubmit.java // 防重复提交注解
│ ├── RateLimiter.java // 限流注解
│ └── Excel.java // Excel导出注解
├── core/ [核心类]
│ ├── controller/BaseController.java // Controller基类
│ ├── domain/
│ │ ├── AjaxResult.java // 统一返回结果
│ │ ├── BaseEntity.java // 实体基类
│ │ └── model/LoginUser.java // 登录用户信息
│ ├── page/
│ │ └── TableDataInfo.java // 分页数据
│ └── redis/RedisCache.java // Redis操作类
├── constant/ [常量类]
│ ├── Constants.java
│ └── HttpStatus.java
├── enums/ [枚举类]
├── exception/ [异常类]
├── utils/ [工具类]
│ ├── StringUtils.java
│ ├── DateUtils.java
│ ├── SecurityUtils.java // 安全工具类
│ ├── poi/ExcelUtil.java // Excel工具
│ └── file/FileUtils.java // 文件工具
└── filter/ [过滤器]
├── XssFilter.java // XSS过滤
└── RepeatableFilter.java // 可重复读取请求体
设计亮点:
统一返回格式:所有接口返回 AjaxResult
通用基类:BaseEntity 提供 createTime、updateTime 等公共字段
注解驱动:通过注解实现日志、Excel导出、数据权限等功能
⑤ ruoyi-generator - 代码生成层
职责:根据数据库表结构自动生成代码
生成内容:
Domain实体类
Mapper接口 + XML
Service接口 + 实现类
Controller接口
前端Vue页面(index.vue)
前端API(api.js)
菜单SQL
模板文件位置:
resources/vm/
├── java/
│ ├── domain.java.vm
│ ├── mapper.java.vm
│ ├── service.java.vm
│ ├── serviceImpl.java.vm
│ └── controller.java.vm
├── xml/mapper.xml.vm
├── vue/index.vue.vm
└── js/api.js.vm
新手小贴士:这是若依的"黑科技"!只需在页面上选择数据库表,点击生成,就能自动创建完整的CRUD代码,大大提高开发效率。
⑥ ruoyi-quartz - 定时任务层
职责:实现定时任务的调度管理
核心功能:
动态添加/修改/删除定时任务
任务执行日志记录
任务并发控制
Cron表达式配置
🎨 三、前端模块详解
3.1 目录结构
ruoyi-ui/
├── src/
│ ├── api/ [API接口]
│ │ ├── login.js // 登录接口
│ │ ├── menu.js // 菜单接口
│ │ └── system/ // 系统管理接口
│ ├── assets/ [静态资源]
│ │ ├── images/
│ │ └── styles/
│ ├── components/ [公共组件]
│ │ ├── Editor/ // 富文本编辑器
│ │ ├── FileUpload/ // 文件上传
│ │ ├── ImageUpload/ // 图片上传
│ │ └── RightToolbar/ // 表格工具栏
│ ├── directive/ [自定义指令]
│ │ ├── permission/ // 权限指令 v-hasPermi
│ │ └── dialog/ // 弹窗拖拽
│ ├── layout/ [布局组件]
│ │ ├── components/ // 头部、侧边栏、标签页
│ │ └── index.vue
│ ├── router/ [路由配置]
│ │ └── index.js
│ ├── store/ [Vuex状态管理]
│ │ ├── modules/
│ │ │ ├── user.js // 用户信息
│ │ │ ├── permission.js // 权限路由
│ │ │ └── settings.js // 系统设置
│ │ └── index.js
│ ├── utils/ [工具类]
│ │ ├── request.js // axios封装
│ │ ├── auth.js // Token管理
│ │ └── dict.js // 字典工具
│ ├── views/ [页面组件]
│ │ ├── login.vue // 登录页
│ │ ├── index.vue // 首页
│ │ └── system/ // 系统管理页面
│ │ ├── user/
│ │ ├── role/
│ │ └── menu/
│ ├── App.vue
│ ├── main.js [入口文件]
│ └── permission.js [路由守卫]
├── public/
│ └── index.html
├── .env.development [开发环境配置]
├── .env.production [生产环境配置]
└── vue.config.js [Vue配置]
3.2 前后端对应关系

四、CRUD 完整流程
4.1 后端数据流
以用户列表查询为例:
① 前端发起请求
GET /system/user/list?pageNum=1&pageSize=10
② 请求到达后端过滤器链
CorsFilter → JwtAuthenticationTokenFilter → SecurityFilterChain
③ 进入Controller层
@GetMapping("/list")
public TableDataInfo list(SysUser user) {
startPage(); // 开启分页
List<SysUser> list = userService.selectUserList(user);
return getDataTable(list); // 封装分页数据
}
④ Service层业务处理
@Override
public List<SysUser> selectUserList(SysUser user) {
return userMapper.selectUserList(user);
}
⑤ Mapper层数据库查询
接口:SysUserMapper.selectUserList(SysUser user)
XML:<select id="selectUserList" ...>
SELECT * FROM sys_user WHERE ...
</select>
⑥ 返回数据
{
"code": 200,
"msg": "查询成功",
"rows": [...],
"total": 100
}
4.2 前端调用流程
// ① API定义 (src/api/system/user.js)
export function listUser(query) {
return request({
url: '/system/user/list',
method: 'get',
params: query
})
}
// ② 页面调用 (src/views/system/user/index.vue)
methods: { getList() {
this.loading = true;
listUser(this.queryParams).then(response => {
this.userList = response.rows;
this.total = response.total;
this.loading = false;
});
}
}
// ③ request.js统一拦截// 请求拦截:自动添加Token
request.interceptors.request.use(config => {
const token = getToken();
if (token) {
config.headers['Authorization'] = 'Bearer ' + token;
}
return config;
})
// 响应拦截:统一处理错误
request.interceptors.response.use(response => {
const code = response.data.code;
if (code === 401) {
// Token过期,跳转登录
}
return response.data;
})
4.3 主子表操作流程
以【合同管理(主表)+ 合同明细(子表)】为例:
数据库设计:
-- 主表
CREATE TABLE sys_contract (
contract_id BIGINT PRIMARY KEY,
contract_no VARCHAR(50),
contract_amount DECIMAL(10,2),
...
);
-- 子表
CREATE TABLE sys_contract_detail (
detail_id BIGINT PRIMARY KEY,
contract_id BIGINT, -- 外键关联主表
product_name VARCHAR(100),
quantity INT,
unit_price DECIMAL(10,2),
...
);
后端处理:
@Service
public class SysContractServiceImpl implements ISysContractService {
@Autowired
private SysContractMapper contractMapper;
@Autowired
private SysContractDetailMapper detailMapper;
@Transactional // 事务控制
@Override
public int insertContract(SysContract contract) {
// 1. 插入主表
int rows = contractMapper.insertContract(contract);
// 2. 插入子表
List<SysContractDetail> detailList = contract.getDetailList();
if (detailList != null && !detailList.isEmpty()) {
for (SysContractDetail detail : detailList) {
detail.setContractId(contract.getContractId());
detailMapper.insertContractDetail(detail);
}
}
return rows;
}
}
前端处理:
<template>
<!-- 主表表单 -->
<el-form :model="form">
<el-form-item label="合同编号">
<el-input v-model="form.contractNo"></el-input>
</el-form-item>
<!-- 子表表格 -->
<el-table :data="form.detailList">
<el-table-column label="产品名称" prop="productName"></el-table-column>
<el-table-column label="数量" prop="quantity"></el-table-column>
<el-table-column label="单价" prop="unitPrice"></el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button @click="handleDeleteDetail(scope.$index)">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-button @click="handleAddDetail">添加明细</el-button>
</el-form>
</template>
<script>
export default {
data() {
return {
form: {
contractNo: '',
contractAmount: 0,
detailList: [] // 子表数据
}
}
},
methods: {
// 添加明细行
handleAddDetail() {
this.form.detailList.push({
productName: '',
quantity: 0,
unitPrice: 0
});
},
// 计算合同总额
calculateTotal() {
let total = 0;
this.form.detailList.forEach(item => {
total += item.quantity * item.unitPrice;
});
this.form.contractAmount = total;
},
// 提交表单
submitForm() {
this.calculateTotal(); // 计算总额
addContract(this.form).then(response => {
this.$message.success('新增成功');
});
}
}
}
</script>
更多推荐



所有评论(0)