tenant_info、按库隔离、登录带 tenantCode、JWT 带 tenantId、请求里切库并注入 TenantConfigContext。JwtUtils + APPToken,没有 tenantId、不切库、也不用租户配置。tenantCode,C 端用登录参数和/或请求头如 X-Tenant-Code)。tenantId,用 framework 的过滤器做切库和 TenantConfigContext 注入。| 类别 | 改什么 | 怎么改 |
|---|---|---|
| 租户识别 | C 端如何知道是哪个租户 | 方案 A:登录接口增加 tenantCode,写入 Token;方案 B:请求头 X-Tenant-Code,在 Filter 里解析出 tenantId。可 A+B 组合。 |
| fs-user-app | 接入多租户链路 | 1)依赖 fs-framework;2)数据源改为用 framework 的 DynamicDataSource(含租户库);3)登录时查主库 tenant_info、切租户、LoginUser.setTenantId(),用 TokenService.createToken() 生成 JWT;4)在 Security 里加入 JwtAuthenticationTokenFilter,保证每次请求按 tenantId 切库并设置 TenantConfigContext;5)TokenService.getLoginUser() 支持从 APPToken 取 Token;6)AppBaseController 增加 getTenantId()。 |
| fs-doctor-app / company / store 等 | 与 user-app 一致支持多租户 | 同样:依赖 framework、用 DynamicDataSource、登录/请求带 tenantCode 或 tenantId、使用 JwtAuthenticationTokenFilter、业务从 SecurityUtils/TenantConfigContext 取租户。 |
| fs-framework(可选增强) | 租户解析与 Token 兼容 | 新增 TenantResolver(从请求头/域名解析 tenantCode→tenantId);TokenService 支持从 APPToken 取 Token。 |
| Redis | 多租户下 Key 隔离 | 使用已配置 TenantKeyRedisSerializer 的 RedisTemplate,并保证在 Filter 里先设置好 LoginUser.tenantId 再执行业务。 |
| 数据库 | 保持现有隔离方式 | 继续「每租户一库」,无需给业务表加 tenant_id;若以后要做共享库再单独规划。 |
TenantConfigContext。完整步骤、架构图和涉及文件清单都在 docs/SaaS改造方案.md 里,可按该文档逐步落地。如果你希望从某一块先动手(例如先只改 user-app 或先做 TenantResolver),可以说一下,我可以按那一块给出更具体的改法或示例代码。
查看 fs-quartz 和 fs-qw-task 的当前实现,以便给出 SaaS 下定时任务的处理方案。
sys_job(当前是单库),Quartz 用单一 DataSource 加载并触发,执行时没有租户上下文。TenantDataSourceManager.switchTenant(tenantInfo) 切到该租户库 → 从该租户库的 sys_job 里查出本分钟该触发的任务 → 对每个任务执行 JobInvokeUtil.invokeMethod(sysJob);TenantJobDispatcherJob),实现上述 1~3,并在启动时只把该分发器注册到 Scheduler。SysJobServiceImpl.init() 改为只注册这一条「分发器」任务,不再从当前库 selectJobAll 注册所有任务(具体是否保留 init 可根据你是否把 sys_job 迁主库而定)。TenantTaskRunner.runForEachTenant(Consumer<TenantInfo> action):从主库查启用租户 → 对每个租户切库、设置 TenantConfigContext → 执行 action → 清理上下文。tenantTaskRunner.runForEachTenant(t -> qwSopService.checkSopRuleTime());addTag()、wxSop()、sendQwGroupMsgTask() 等同理,都包在 runForEachTenant 里。TenantTaskRunner、逐个 @Scheduled 包一层 runForEachTenant,验证多租户数据与配置隔离。更细的步骤、方案 B(sys_job 上迁主库 + tenant_id)以及涉及的文件清单,都在 docs/SaaS改造方案.md 的 第七章 里,可直接按文档落地。