---
url: https://qiwuadmin.com/features/multi-tenancy.md
description: 一套部署同时服务多家公司：多租户开关、用租户编码或绑定域名登录、租户管理、租户套餐、平台人员进入租户、日志里的租户和已知上限。
---

# 多租户

**多租户**就是一套部署同时服务多家公司。每一家公司叫一个**租户**。所有租户共用一个 MySQL 数据库，但每家公司的数据各自隔离，互相看不到。适合用栖梧做 SaaS，把同一套后台卖给多家客户。

系统里始终有一个内置的**默认租户**（编码 `default`），它就是**平台**，也就是部署和运营这套系统的你自己。默认租户里的人员叫**平台人员**，超级管理员 `admin` 也在这里。

::: tip 默认关闭
多租户默认关闭。关闭时就是原来的单租户系统，所有数据都属于默认租户，登录页、侧栏和日志都看不出任何变化。不需要多租户的项目可以跳过这一页。
:::

## 打开开关

开关是服务端的环境变量 `APP_MULTI_TENANT`（写在 `apps/server/.env` 里，不是秘密），默认 `false`。界面上没有开关。它只在启动时读取，改完要重启**全部**服务端实例才算切换完成。

| 地方 | 关闭（默认） | 打开 |
| --- | --- | --- |
| 可用的租户 | 只有默认租户 | 所有已启用、未到期的租户 |
| 登录页 | 没有租户编码 | 多一个“租户编码”输入框（访问的域名已绑定租户时不显示） |
| **系统管理 → 租户管理**、**租户套餐** | 不在侧栏里，接口也用不了（菜单管理里照常列出） | 平台人员按权限使用 |
| 日志页 | 和原来一样 | 多一列租户，见[日志里的租户](#日志里的租户) |
| **系统监控 → 服务监控** | 和原来一样 | 多一行“多租户”，显示已开启 |

* **在本机试一试**：把 `apps/server/.env` 里的 `APP_MULTI_TENANT` 改为 `true`，运行 `pnpm db:migrate`，再重新启动 `pnpm dev`。
* **生产环境**：新安装可以一开始就打开；已有数据的库要分两次部署打开。步骤见[部署 · 打开或关闭多租户](/guide/deploy#打开或关闭多租户)。
* **上线前验收**：仓库里有一份两个租户的手工验收清单，见[两租户验收](https://github.com/732124645/qiwu-vue-admin/blob/main/docs/multi-tenancy.md#两租户验收)。

::: warning 打开后不能退回旧版本
打开过开关的数据库，不能再换回 1.1.0 以前的任何版本。关闭开关前，先停用不再服务的租户，否则以后再打开时，它们会立刻恢复可用。
:::

开关的完整说明见仓库的[多租户文档 · 开关](https://github.com/732124645/qiwu-vue-admin/blob/main/docs/multi-tenancy.md#开关)。

## 用户怎样登录

登录前，服务端按下面的顺序判断用户属于哪个租户：

1. 看访问的**域名**。这个域名绑定了某个租户，就是这个租户，登录页不显示租户编码；
2. 域名没有绑定租户，就看登录页填的**租户编码**；
3. 租户编码留空，就是默认租户。平台人员登录时留空即可。

![带租户编码的登录页](/screenshots/zh-tenant-login.webp)

* “租户编码”在“密码登录”“短信登录”两个页签的上方。用短信登录，或者勾选了“记住用户名”时，下次会自动填上这次的编码。找回密码页也有这个输入框；
* 租户编码填错、租户已停用或已到期时，提示和密码错误完全一样（“租户编码、用户名或密码错误”），别人无法借此猜出有哪些租户；
* 登录以后，用户属于哪个租户记在服务端，**没有任何请求头或参数能切换租户**；
* 用户正在使用时租户被停用或到期，他的登录立即失效，登录页提示“所在租户已停用或已到期，请联系管理员”；
* 手机端（App 和微信小程序）只能用租户编码登录，见[移动端 · 租户编码](/features/mobile#租户编码)；
* 注册只对默认租户开放。

登录失败锁定按租户分开计算，同名的用户在不同租户里互不影响；短信的发送次数限制按手机号和 IP 计算，不分租户。见[登录与账号 · 多租户时的租户编码](/features/login#多租户时的租户编码)。详细规则见仓库的[租户从哪里来](https://github.com/732124645/qiwu-vue-admin/blob/main/docs/multi-tenancy.md#租户从哪里来)。

## 租户管理

在 **系统管理 → 租户管理** 中开通和管理租户。这是平台页面，只有默认租户的人员能用，权限点是 `iam.tenant.*`：浏览、查看、新增、修改、进入租户（`enter`）、重置初始密码（`reset-password`）。

![租户管理列表](/screenshots/zh-tenant-list.webp)

列表里的默认租户带“默认租户”标签，它不能停用，也不能进入。

### 开通租户

点“新增”，填写“新增租户”表单：

| 字段 | 说明 |
| --- | --- |
| 租户编码 | 用户登录时填写。3–32 位小写字母、数字或中间的 `-`，以字母开头；`default`、`www`、`api`、`admin` 等保留字不能用。开通后不能修改，也永远不会给别的租户再用 |
| 租户名称 | 列表和横幅里显示的名称 |
| 租户套餐 | 必选，决定这个租户能用哪些功能，见[租户套餐](#租户套餐) |
| 到期时间 | 留空即永久有效 |
| 用户数上限 | 留空即不限，包括租户管理员 |
| 绑定域名 | 见[绑定域名](#绑定域名) |
| 品牌名称、品牌 logo | 见[品牌](#品牌) |
| 管理员用户名、显示名、手机号、邮箱 | 开通时创建的租户管理员 |

保存后一次完成以下工作，任何一步失败都会整体撤销：

* 创建租户；
* 准备这个租户的基础数据：以租户名称命名的根部门、内置角色“租户管理员”（`tenant_admin`）、流程模板等；
* 创建租户管理员。他拥有“租户管理员”角色，首次登录必须修改初始密码。

开通成功后弹出“租户已开通”，显示管理员用户名和**初始密码**。初始密码只显示这一次，点“复制”保存好，再点“我已保存”。这个租户以后新建或导入用户而不填密码时，也用这个初始密码。忘了可以在列表里点“重置初始密码”重新生成，已有用户的密码不受影响。

### 停用、到期和用户数

* **停用**：关掉列表里的“启用状态”开关。这个租户的用户立即下线，之后无法登录，数据保留。重新启用即恢复；
* **到期**：到期时间一到，效果和停用一样。续期即恢复；
* **用户数上限**：新建和导入用户时检查，超出时提示“已达到租户的用户数上限”。“已用/上限”一列显示当前用了多少。

::: info 租户从不删除
租户没有删除功能。不再服务的租户，停用或让它到期就行。它的数据原样保留，用户登录不了，后台任务也不再处理它。
:::

### 绑定域名

给租户绑定自己的域名后，用户在这个域名上登录不用填租户编码，别的租户的登录在这个域名上无效。平台人员仍然用主域名。

* 每个租户最多 20 个，小写，不含端口和通配符；
* 平台自己的域名不能绑定；一个域名只能绑给一个租户；
* 修改后最多 60 秒生效；
* 部署时 DNS、nginx 和 HTTPS 证书都要加上这些域名，见[部署 · 打开或关闭多租户](/guide/deploy#打开或关闭多租户)。

### 品牌

每个租户可以设置自己的**品牌名称**和**品牌 logo**，显示在侧栏、登录页、锁屏页和浏览器标题上。留空则使用系统的名称和图标。默认租户也可以设置品牌。

字段和修改效果的完整说明见仓库的[租户管理](https://github.com/732124645/qiwu-vue-admin/blob/main/docs/multi-tenancy.md#租户管理)。

## 租户套餐

**租户套餐**决定一个租户能用哪些菜单和按钮。在 **系统管理 → 租户套餐** 中管理，权限点是 `iam.tenantPackage.*`。

![租户套餐列表](/screenshots/zh-tenant-plans.webp)

* 编辑套餐时，在“可用菜单”树里勾选。平台专属的菜单（见下文）不在其中；
* 用代码生成器新建的模块、在菜单管理里新建的菜单，默认不在任何套餐里。要让租户使用，就把它勾进套餐；
* 套餐由**服务端**检查。租户用户的权限 = 他的角色授权和套餐的交集。绕过界面直接调用不在套餐里的接口，同样会被拒绝；
* 租户管理员（`tenant_admin`）自动拥有套餐里的全部功能；
* 租户在 **系统管理 → 角色管理** 里授权时，只能看到套餐里的菜单。套餐缩小后，原来的授权保留但不生效，套餐放大后自动恢复；
* 修改套餐或给租户换套餐后，已登录的用户在下一次操作时自动更新权限，不用重新登录；
* 租户没有套餐，或者套餐被停用时，这个租户什么都不能用。正在被租户使用的套餐不能删除；
* 手机端同样按套餐隐藏功能，比如套餐里没有流程审批时，不显示“审批”页签；
* 默认租户不受套餐限制。

::: details 平台专属的页面
下面这些页面由平台统一维护，所有租户共用，不能放进套餐：

* **系统监控**：服务监控、数据库监控、缓存监控、缓存列表、队列监控、定时任务、调度日志；
* **系统工具**：代码生成、表单构建、系统接口、Element Plus 文档；
* **系统管理**：菜单管理、字典管理、字典数据、参数设置、App 版本、客户端管理、租户管理、租户套餐；
* **系统管理 → 文件管理**：存储配置；
* **系统管理 → 消息中心**：邮件账号、短信渠道、站内信模板、邮件模板、短信模板；
* **系统管理 → 日志管理**：API 访问日志、API 错误日志。

开关打开时，API 访问日志、API 错误日志、缓存列表和队列监控含有所有租户的数据，只有超级管理员能看。其他平台页面，默认租户里有相应权限的角色照常使用。
:::

详细规则见仓库的[租户套餐](https://github.com/732124645/qiwu-vue-admin/blob/main/docs/multi-tenancy.md#租户套餐)。

## 平台人员进入租户

租户遇到问题时，平台人员可以**进入**这个租户，帮忙排查或代为操作。这是跨租户操作的唯一入口。

### 谁能进入

* 要有“进入租户”的权限（`iam.tenant.enter`），超级管理员本来就有；
* 进入后，数据范围仍按本人的角色计算。所以要给他配一个数据范围为“全部数据”的角色，否则在对方租户里看不到数据，见[权限与数据范围](/features/permission#数据范围)。

### 进入和退出

1. 在租户列表里，点那一行的“进入”；
2. 在弹框里填写“进入原因”（必填，最多 200 字），点“进入租户”；
3. 页面整页刷新。顶部一直显示横幅“正在以平台人员身份操作租户 某某，所有操作记入审计”，旁边是“退出租户”按钮，锁屏页也会提示。

![进入租户后的横幅](/screenshots/zh-tenant-enter.webp)

* 点横幅上的“退出租户”退出。满 **2 小时**、开关被关闭、或者本人的进入权限被收回时，下一次操作会自动退出；
* 只能在电脑端后台进入，手机端不行。停用、到期的租户也能进入，方便排查；
* 不是超级管理员的人，进入期间不能再进入别的租户，要先退出；
* 同时开着多个标签页时，另一个标签页进入或退出租户后，旧标签页会提示“当前标签页所在的租户已切换，请刷新页面”并自动刷新，不会把数据写到别的租户。

### 进入后能做什么

* 用**本人的权限**操作，不受对方套餐的限制；但平台功能的权限被去掉了，只有超级管理员进入期间还能打开平台页面；
* 进入的人不是对方的管理员：对方租户的所有者和租户管理员，仍然只有平台的超级管理员能修改；
* 个人资料、修改密码、表格列设置、我的站内信、公告，以及流程审批里的我的待办、我的已办、我的发起、抄送我的，进入期间仍是**自己租户**的。平台页面也仍在平台里运行，写入不会落到对方租户。

### 全程审计

* 进入和退出各记一条操作日志（动作“进入租户”“退出租户”），记在默认租户里，进入原因也一起记下；
* 进入期间的操作，记在对方租户的操作日志里。对方的管理员能看到，“操作者租户”显示“平台”，IP、地点等来源信息已遮蔽，也删不掉；
* 进入期间的每个请求，包括只是查看，都会写进 API 访问日志，完整的来源信息只在这里，只有平台的超级管理员能看。

详细规则见仓库的[平台人员进入租户](https://github.com/732124645/qiwu-vue-admin/blob/main/docs/multi-tenancy.md#平台人员进入租户)。

## 日志里的租户

开关打开后，日志页多了租户的信息：

| 页面 | 变化 |
| --- | --- |
| **系统管理 → 日志管理 → 操作日志** | 多一列“操作者租户”：平台人员的操作显示“平台”，否则显示租户名称 |
| **系统管理 → 日志管理 → 登录日志** | 多一列“租户”：显示“平台”、租户名称，或者“未解析租户”（登录时填的租户编码不存在）。超级管理员的搜索栏多一个“未解析租户”开关 |
| **系统管理 → 日志管理 → API 访问日志**、**API 错误日志** | 只有超级管理员能看，多一个租户筛选和“租户”列 |

每个租户只能看到自己的操作日志和登录日志。平台人员想看别的租户的日志，要先进入这个租户。各种日志的用法见[监控与日志](/features/monitor)。

## 已知上限

* 一个微信号只能绑定一个租户里的一个账号。想把它释放给别的租户，见仓库的[全局唯一值的释放](https://github.com/732124645/qiwu-vue-admin/blob/main/docs/multi-tenancy.md#全局唯一值的释放)；
* 在主域名上，同一个浏览器同一时间只能登录一个租户；
* 改绑域名最多 60 秒后生效；
* 修改任何一个套餐，所有已登录的用户都会重新加载一次权限；
* 平台人员看别的租户的日志，只能先进入这个租户；
* 品牌只有名称和 logo。浏览器标签上的小图标、网页的初始标题和 App 图标不变。

完整清单见仓库的[已知上限](https://github.com/732124645/qiwu-vue-admin/blob/main/docs/multi-tenancy.md#已知上限)。

## 在演示站体验

[在线演示](/guide/introduction#在线演示)已经打开了多租户。登录页的租户编码填 `yunshan` 或 `qinghe`，用户名 `admin`，密码 `KnjUB2fTabw2wnxL`，就能看到一家公司登录后的样子：两家示例公司有各自的品牌名，`qinghe` 的套餐里没有流程审批。租户编码留空、用平台账号（`admin` / `admin@123`）登录，可以在 **系统管理 → 租户管理** 里点“进入”，体验进入租户和横幅。演示模式下不能开通或修改租户，进入和退出不受限制。

## 开发指南

* 新建的表默认按租户隔离：建表时加 `tenant_id` 列，实体映射这一列，手写的 SQL 要自己带上租户条件。见[编写租户感知的代码](/core/tenancy)和仓库的[编写租户感知的项目代码](https://github.com/732124645/qiwu-vue-admin/blob/main/docs/multi-tenancy.md#编写租户感知的项目代码)；
* 用[代码生成器](/features/codegen)生成新模块后，记得把它的菜单勾进[租户套餐](#租户套餐)；
* 部署与开关的完整步骤见[部署](/guide/deploy#打开或关闭多租户)和仓库的[打开多租户开关](https://github.com/732124645/qiwu-vue-admin/blob/main/docs/deploy.md#打开多租户开关)。

相关功能：

* [登录与账号](/features/login)
* [权限与数据范围](/features/permission)
* [监控与日志](/features/monitor)
* [移动端](/features/mobile)
