SaaS 多租户
SaaS 多租户用于在同一套 RuoYi Office 服务中承载多个企业或组织。系统通过租户、租户套餐、租户上下文、菜单过滤和数据隔离,让不同租户在共享代码和数据库能力的同时保持业务数据边界。
本地实现位置
| 层 | 位置 |
|---|---|
| 租户页面 | ruoyi-office-vben/apps/web-antd/src/views/system/tenant |
| 租户套餐页面 | ruoyi-office-vben/apps/web-antd/src/views/system/tenantPackage |
| 租户 API | src/api/system/tenant、src/api/system/tenant-package |
| 后端 Controller | yudao-module-system-server/.../tenant/TenantController.java、TenantPackageController.java |
| 多租户框架 | ruoyi-office/yudao-framework/yudao-spring-boot-starter-biz-tenant |
核心概念
| 概念 | 说明 |
|---|---|
| 租户 | 一个独立企业或组织,拥有联系人、账号数、有效期、域名、状态等配置 |
| 租户套餐 | 一组可开通菜单能力,用来控制租户可使用的系统功能 |
| 租户上下文 | 请求进入后识别当前租户,业务查询和写入按租户隔离 |
| 租户忽略 | 登录、租户查询、平台级管理等场景可使用 @TenantIgnore |
租户管理
租户列表支持分页、新增、编辑、删除、批量删除和导出。管理端会在查询前加载租户套餐列表,用于表格展示和表单选择。
| 操作 | 接口 | 权限标识 |
|---|---|---|
| 创建租户 | POST /system/tenant/create | system:tenant:create |
| 更新租户 | PUT /system/tenant/update | system:tenant:update |
| 删除租户 | DELETE /system/tenant/delete | system:tenant:delete |
| 批量删除 | DELETE /system/tenant/delete-list | system:tenant:delete |
| 分页查询 | GET /system/tenant/page | 页面查询使用 |
| 导出租户 | GET /system/tenant/export-excel | system:tenant:export |
租户表单通常关注:租户名称、联系人、联系电话、套餐、账号额度、过期时间、绑定域名、状态以及初始化管理员账号。
租户套餐
租户套餐用于把菜单能力打包后分配给租户。套餐页面支持新增、编辑、删除和批量删除,表单会选择允许开通的菜单集合。
| 操作 | 接口 | 权限标识 |
|---|---|---|
| 创建套餐 | POST /system/tenant-package/create | system:tenant-package:create |
| 更新套餐 | PUT /system/tenant-package/update | system:tenant-package:update |
| 删除套餐 | DELETE /system/tenant-package/delete | system:tenant-package:delete |
| 分页查询 | GET /system/tenant-package/page | 页面查询使用 |
| 精简列表 | GET /system/tenant-package/get-simple-list | 租户表单下拉使用 |
当角色分配菜单时,后端会按租户套餐过滤未开通菜单,避免租户管理员越权分配。
登录与域名识别
TenantController 提供了几个允许匿名访问且忽略租户上下文的接口:
| 接口 | 用途 |
|---|---|
GET /system/tenant/get-id-by-name | 登录页根据租户名称获取租户编号 |
GET /system/tenant/simple-list | 登录页或租户选择器获取启用租户列表 |
GET /system/tenant/get-by-website | 根据访问域名识别租户 |
这些接口使用 @TenantIgnore,因为在识别租户之前还没有稳定的租户上下文。
启用与维护建议
- 先建套餐,再建租户:租户创建时需要绑定套餐,套餐决定可用功能边界。
- 谨慎调整套餐菜单:减少菜单可能导致租户角色已有授权被过滤,增加菜单后还需要租户内角色重新授权。
- 关注过期时间和账号数:到期或超额会影响租户正常使用,应配合运营流程提前预警。
- 域名格式要合法:
get-by-website对域名做格式校验,绑定域名时不要带协议路径。
排查清单
| 现象 | 排查方向 |
|---|---|
| 登录页找不到租户 | 租户名称是否正确,租户状态是否启用 |
| 域名无法识别租户 | 租户 websites 是否包含当前 host,格式是否只写域名和端口 |
| 租户管理员看不到某菜单 | 租户套餐是否包含该菜单,角色是否重新分配菜单 |
| 租户间数据串查 | 检查接口是否误加 @TenantIgnore,或 SQL 是否绕过租户拦截 |
| 新租户初始化账号失败 | 检查租户创建表单中的管理员账号、密码和账号额度 |
