本系统采用 SaaS 多租户架构,面向多个独立企业/组织在同一平台统一部署与运营。立项背景是:传统单租户模式难以满足多客户并行接入、权限隔离、按需开通功能的需求。建设目标是:平台方统一维护租户套餐与功能边界,按套餐为各租户分配菜单、插件及账号额度;租户管理员在授权范围内独立管理本租户用户与业务;实现“一套系统、多租户隔离、按套餐差异化服务”,降低运维成本并支撑商业化订阅。
2、软件功能、核心功能模块的介绍
核心模块包括:(1)租户套餐管理:配置套餐名称、状态、价格、时长、关联菜单权限、包含插件(Addon)等,数据存储于 system_tenant_package 表;(2)租户管理:维护租户名称、联系人、套餐绑定、账号额度、过期时间、绑定域名及状态,支持新增、编辑、删除、导出;(3)权限与菜单:登录后通过 get-permission-info 加载用户角色与菜单,套餐 menu_ids 决定租户超级管理员可见功能;(4)平台套餐配置(Platform):以卡片形式管理套餐,支持推荐标签、插件关联、菜单数量展示,与系统租户模块共用套餐数据;(5)辅助能力:字典数据、租户切换、站内信未读提醒等,支撑管理端日常运营。
3、业务流程、功能路径描述
业务流程如下:① 平台管理员进入「平台管理 → 套餐配置」或「系统管理 → 租户套餐」,新建并启用套餐,勾选菜单、配置插件,保存至 system_tenant_package;② 进入「系统管理 → 租户管理 → 租户列表」,点击新增,填写租户信息并选择已启用套餐(调用 /system/tenant-package/simple-list 获取下拉选项),设置账号额度与过期时间,提交后系统自动创建租户管理员账号与角色;③ 租户管理员登录后,系统按套餐 menu_ids 过滤菜单,仅展示授权功能;④ 运营中若调整套餐,编辑租户并更换套餐,超级管理员菜单同步更新;⑤ 平台方通过租户列表查看套餐绑定、插件、状态与到期情况,到期或禁用的租户无法正常使用。整体路径为:套餐定义 → 租户开通 → 权限生效 → 日常运营 → 套餐变更/到期管控。
项目采用前后端分离的 SaaS 多租户架构。后端基于 Spring Boot + MyBatis-Plus,按 yudao 模块化拆分:system 模块负责租户、权限、字典等基础能力,platform 模块负责套餐与 Addon 插件管理,通过 @TenantIgnore 实现套餐等全局数据的租户隔离绕过。前端为 Vue3 + Element Plus + TypeScript,路由由后端菜单动态生成。数据层使用 MySQL(system_tenant、system_tenant_package 等表),Redis 做缓存,登录鉴权走 JWT + Spring Security。设计上以「套餐定义功能边界 → 租户绑定套餐 → 菜单/权限动态下发」为主线,platform 与 system 共用 system_tenant_package 表,实现套餐统一维护、租户差异化授权。
我主要负责系统管理中的租户与套餐相关功能排查与梳理,覆盖后端 TenantPackageController、TenantServiceImpl 及前端 tenant/index.vue、tenantPackage API 等模块。通过日志与代码对照,定位登录初始化链路(get-permission-info 约 491ms、dict-data 1035 条、tenant simple-list 5 条租户),确认租户列表、套餐下拉、权限加载均正常触发。梳理出 2 套套餐管理入口(系统管理-租户套餐、平台管理-套餐配置),明确共用 1 张套餐表、2 组 API。输出完整业务流程说明(套餐配置→租户开通→权限生效→运营变更),为后续修复与联调提供依据。
主要难点是「租户套餐页面无数据」表象与真实原因不一致。排查发现:菜单 component 指向 system/tenantPackage/index,但前端缺少对应 Vue 页面,路由 findIndex 为 -1 导致组件 undefined,页面空白且不会发起 tenant-package 接口请求;同时项目已将套餐管理迁移至 platform/package/PackageList.vue,旧菜单未同步更新,造成“有菜单、无页面、无数据”的错觉。另外,租户表单下拉仅返回 status=0 的启用套餐,若库中无数据或全为禁用也会表现为空。解决方案:① 补全 tenantPackage 前端页面,或 ② 将菜单 component 改指向 platform/package/PackageList;③ 执行 platform-menu-seed.sql 并分配角色权限;④ 校验 system_tenant_package 表数据及 status 字段,确保有启用套餐供租户绑定。