若依框架——从零到一:前后端分离版实战部署与核心权限系统解析
1. 若依框架初探:为什么选择它?
第一次接触若依(RuoYi)框架是在三年前的一个企业级项目里。当时团队需要快速搭建一个具备完整权限管理功能的后台系统,从零开发显然不现实。在对比了多个开源方案后,我们发现这个基于Spring Boot和Vue的前后端分离框架,简直就是为国内开发者量身定制的瑞士军刀。
若依最吸引我的地方在于它 开箱即用的权限系统 。不同于需要自己搭建基础的Spring Security脚手架,它已经帮你实现了:
- 四层权限控制 :菜单可见性、页面按钮操作、API接口访问、数据行级过滤
- 可视化配置 :通过管理后台就能完成权限分配,不需要反复修改代码
- 多维度隔离 :支持按部门、角色、用户等多个维度进行权限组合
记得第一次用若依生成代码时,我们团队的前端小伙伴惊呼:"这比我们手动写CRUD快10倍!"确实,它的代码生成器能根据数据库表结构,自动生成包含前端页面和后端接口的完整功能模块。对于常见的用户管理、订单管理这类功能,基本上半小时就能跑通全流程。
2. 环境搭建:从零启动项目
2.1 准备工作清单
在开始前,请确保你的开发环境满足以下要求(实测版本):
- 后端环境 :
- JDK 1.8+(推荐Amazon Corretto 11)
- MySQL 5.7+(注意需要开启大小写敏感)
- Redis 5.0+
- Maven 3.6+
- 前端环境 :
- Node.js 14+(推荐LTS版本)
- npm 6+ 或 yarn 1.22+
踩坑提示:我曾遇到过MySQL 8.0默认认证方式导致连接失败的问题,解决方法是在application-druid.yml中配置
useSSL=false&allowPublicKeyRetrieval=true
2.2 数据库初始化
- 创建数据库(默认名
ry-vue,可自定义):
CREATE DATABASE `ry-vue` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
- 执行初始化SQL(项目sql目录下):
mysql -uroot -p ry-vue < ry_20230210.sql
mysql -uroot -p ry-vue < quartz.sql
2.3 后端配置要点
修改 ruoyi-admin/src/main/resources 下的配置文件:
- application-druid.yml :
# 数据源配置
spring:
datasource:
druid:
master:
url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull
username: root
password: yourpassword
- application.yml :
# Redis配置
redis:
host: 127.0.0.1
port: 6379
password:
database: 0
启动时如果报错 Failed to configure a DataSource ,检查是否漏了 @MapperScan 注解,或者在启动类加上:
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
2.4 前端启动技巧
在 ruoyi-ui 目录下执行:
# 首次运行需要安装依赖
npm install --registry=https://registry.npmmirror.com
# 开发模式启动
npm run dev
常见问题解决方案:
- 端口冲突 :修改
vue.config.js中的devServer.port - 依赖安装失败 :删除node_modules后重试,或使用yarn
- ESLint报错 :临时关闭可在package.json中移除
@vue/cli-plugin-eslint
3. 权限系统深度解析
3.1 菜单权限:控制可见性
在若依中创建菜单时,这几个参数最容易混淆:
- 路由地址 :对应Vue路由配置的path
- 组件路径 :指向
src/views下的具体组件文件 - 权限字符 :需要与后端
@PreAuthorize注解保持一致
实际案例:创建一个"订单管理"菜单
- 系统管理 → 菜单管理 → 新增
- 填写基本信息:
- 菜单名称:订单管理
- 路由地址:/order
- 组件路径:system/order/index
- 权限配置:
- 权限字符:
system:order:list
- 权限字符:
- 后端Controller添加注解:
@PreAuthorize("@ss.hasPermi('system:order:list')")
@GetMapping("/list")
public TableDataInfo list(Order order) {
// ...
}
3.2 按钮权限:精细化控制
按钮权限的实现原理是通过自定义指令 v-hasPermi 。在模板中这样使用:
<el-button
v-hasPermi="['system:order:add']"
@click="handleAdd">
新增订单
</el-button>
背后的权限校验逻辑在 src/directive/permission/hasPermi.js 中实现,核心代码:
function checkPermission(el, binding) {
const { value } = binding
const all_permission = "*:*:*"
const permissions = store.getters && store.getters.permissions
if (value && value instanceof Array) {
if (value.length > 0) {
const permissionFlag = value
const hasPermissions = permissions.some(permission => {
return all_permission === permission || permissionFlag.includes(permission)
})
// 无权限则移除DOM元素
if (!hasPermissions) {
el.parentNode && el.parentNode.removeChild(el)
}
}
} else {
throw new Error(`请设置操作权限标签值`)
}
}
3.3 接口权限:最后的安全防线
即使前端做了按钮隐藏,恶意用户仍可能直接调用API。若依通过Spring Security的注解提供双重保障:
@PreAuthorize("@ss.hasPermi('system:order:remove')")
@Log(title = "订单管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{orderIds}")
public AjaxResult remove(@PathVariable Long[] orderIds) {
return toAjax(orderService.deleteOrderByIds(orderIds));
}
这里的 @ss 是若依自定义的权限校验Bean,核心逻辑在 SysPermissionService 中实现,支持:
- 权限字符串校验(如
system:user:list) - 角色校验(如
@ss.hasRole('admin')) - 逻辑运算符组合(如
hasPermi('a') or hasPermi('b'))
3.4 数据权限:实现数据隔离
若依的数据权限通过AOP切面实现,支持五种范围:
- 全部数据权限(无过滤)
- 自定数据权限(自定义SQL)
- 本部门数据
- 本部门及以下部门数据
- 仅本人数据
使用方法是在Service方法上添加注解:
@DataScope(deptAlias = "d", userAlias = "u")
public List<Order> selectOrderList(Order order) {
return mapper.selectOrderList(order);
}
切面会动态拼接SQL条件,例如当用户有"本部门数据"权限时,实际执行的SQL会变成:
SELECT * FROM sys_order
WHERE dept_id = 当前用户部门ID
4. 实战技巧与性能优化
4.1 代码生成器高级用法
若依的代码生成器可以通过修改 ruoyi-generator 模块的模板文件实现定制化:
- 修改
vm/java/controller.java.vm可以改变生成的Controller风格 - 在
vm/js/api.js.vm中添加统一的错误处理逻辑 - 通过
vm/sql/sql.vm调整生成的DDL语句
生成代码时有个实用技巧:先在界面上配置好"生成选项",然后点击"预览代码",复制页面URL中的参数(如 tables=sys_user ),以后就可以通过命令行快速生成:
# 生成sys_user表相关代码
curl "http://localhost:8080/tool/gen/genCode/sys_user"
4.2 前后端联调建议
-
接口调试 :
- 使用
ruoyi-admin内置的Swagger(访问/swagger-ui.html) - 或配置
knife4j增强文档(需添加依赖)
- 使用
-
跨域处理 : 开发环境可以在
vue.config.js中配置代理:
devServer: {
proxy: {
'/prod-api': {
target: 'http://localhost:8080',
changeOrigin: true,
pathRewrite: {
'^/prod-api': ''
}
}
}
}
- API封装技巧 : 在
src/api中封装请求时,建议统一错误处理:
import request from '@/utils/request'
export function listOrder(query) {
return request({
url: '/system/order/list',
method: 'get',
params: query,
// 添加请求拦截器
interceptors: {
requestInterceptor: config => {
// 可在此添加全局参数
config.headers['X-Custom-Header'] = 'value'
return config
},
responseInterceptor: response => {
// 对响应数据做处理
if (response.code !== 200) {
Message.error(response.msg)
}
return response
}
}
})
}
4.3 性能优化方案
- Redis缓存优化 :
- 在
application.yml中配置缓存过期时间:
- 在
spring:
cache:
redis:
time-to-live: 1800000 # 30分钟
- MyBatis二级缓存 : 在mapper.xml中添加:
<cache eviction="LRU" flushInterval="60000" size="512" readOnly="true"/>
- 前端懒加载 : 修改路由配置,使用动态导入:
{
path: '/system/order',
component: () => import('@/views/system/order/index'),
name: 'Order',
meta: { title: '订单管理', icon: 'tree' }
}
- 打包优化 : 在
vue.config.js中配置CDN:
configureWebpack: {
externals: {
'vue': 'Vue',
'element-ui': 'ELEMENT'
}
}
更多推荐

所有评论(0)