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 数据库初始化

  1. 创建数据库(默认名 ry-vue ,可自定义):
CREATE DATABASE `ry-vue` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
  1. 执行初始化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 注解保持一致

实际案例:创建一个"订单管理"菜单

  1. 系统管理 → 菜单管理 → 新增
  2. 填写基本信息:
    • 菜单名称:订单管理
    • 路由地址:/order
    • 组件路径:system/order/index
  3. 权限配置:
    • 权限字符: system:order:list
  4. 后端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切面实现,支持五种范围:

  1. 全部数据权限(无过滤)
  2. 自定数据权限(自定义SQL)
  3. 本部门数据
  4. 本部门及以下部门数据
  5. 仅本人数据

使用方法是在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 前后端联调建议

  1. 接口调试

    • 使用 ruoyi-admin 内置的Swagger(访问 /swagger-ui.html
    • 或配置 knife4j 增强文档(需添加依赖)
  2. 跨域处理 : 开发环境可以在 vue.config.js 中配置代理:

devServer: {
  proxy: {
    '/prod-api': {
      target: 'http://localhost:8080',
      changeOrigin: true,
      pathRewrite: {
        '^/prod-api': ''
      }
    }
  }
}
  1. 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 性能优化方案

  1. Redis缓存优化
    • application.yml 中配置缓存过期时间:
spring:
  cache:
    redis:
      time-to-live: 1800000 # 30分钟
  1. MyBatis二级缓存 : 在mapper.xml中添加:
<cache eviction="LRU" flushInterval="60000" size="512" readOnly="true"/>
  1. 前端懒加载 : 修改路由配置,使用动态导入:
{
  path: '/system/order',
  component: () => import('@/views/system/order/index'),
  name: 'Order',
  meta: { title: '订单管理', icon: 'tree' }
}
  1. 打包优化 : 在 vue.config.js 中配置CDN:
configureWebpack: {
  externals: {
    'vue': 'Vue',
    'element-ui': 'ELEMENT'
  }
}
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐