spec.md 6.4 KB

用户租户登录与授权优化

status: done created: 2026-06-25 complexity: 🟡中等

1. 背景与目标

用户管理当前支持单用户授权和单用户租户绑定,但缺少批量操作入口;登录页不能在登录前选择租户并应用对应租户展示配置;用户编辑表单需要支持“所属租户”多选并保持“默认租户”为单值;用户类型在部分回显场景显示数字;登录页未登录态无法渲染租户自定义文件 logo。完成后应支持在用户管理批量给用户分配角色、批量加入目标租户,登录前选择租户并按所选租户渲染登录页配置,用户列表展示多个租户名称,用户编辑表单字段稳定回显中文。

2. 代码现状(Research Findings)

2.1 相关入口与链路

  • forge-admin-ui/src/views/system/user.vue 使用 AiCrudPage 渲染用户管理,已有单用户授权弹窗、单用户租户绑定弹窗。
  • forge-server/.../SysUserController.java 已有 POST /system/user/{userId}/rolesPOST /system/user/{userId}/tenants 单用户接口。
  • forge-server/.../SysUserServiceImpl.java 已有 syncUserRolesbindUserTenantsupsertUserTenant 等复用能力。
  • forge-admin-ui/src/views/login/index.vue 登录页只按 userClient 加载 /auth/loginConfig,未传租户。
  • forge-server/.../AuthController.javaGET /auth/loginConfig 仅接收 userClient

2.2 现有实现

  • LoginRequest 已包含 tenantId,认证策略 UsernamePasswordAuthStrategyUsernamePasswordCaptchaAuthStrategy 已把 request.getTenantId() 传给用户加载服务。
  • sys_user_tenant 已由 V1.0.55__add_user_tenant_membership.sql 建立,具备用户多租户绑定模型。
  • AiCrudPage 暴露 getSelectedKeys()clearSelection(),可用于用户页批量操作。

2.3 发现与风险

  • 批量授权必须复用现有角色可管理范围校验,避免租户管理员越权。
  • 登录页租户配置读取不能依赖需要登录态的 /system/tenant/userTenantConfig
  • 用户多租户关系存在时,编辑表单仍只能编辑默认/当前上下文租户,不能把 tenantIds 数组塞给 tenantId 单选字段。

3. 功能点

  • 用户管理选中多名用户后,可批量分配当前操作租户下角色。
  • 用户管理选中多名用户后,可批量加入一个目标租户,并指定成员类型。
  • 登录页加载公开启用租户列表,登录前选择租户,登录配置和展示配置按所选租户生效。
  • 用户编辑时 tenantIds 支持多选,tenantId 作为默认租户保持单值;用户类型按字典中文回显。
  • 用户列表租户名称展示多个租户。
  • 登录页租户 logo/favicon 使用白名单公开图片接口渲染,不放开通用文件下载权限。

4. 业务规则

  • 批量授权不允许操作当前登录用户。
  • 超级管理员可批量加入任意启用租户;非超级管理员仍只能操作当前租户内普通用户。
  • 批量授权的角色必须属于操作租户,非超级管理员只能分配自己拥有的角色。
  • 登录页租户列表仅返回启用租户,不暴露敏感字段。

5. 数据变更

操作 表名 字段/索引 说明
- - 复用 sys_user_tenantsys_user_role

6. 接口变更

操作 接口 方法 变更内容
新增 /auth/tenant/options GET 公开返回启用租户选项
修改 /auth/loginConfig GET 增加可选 tenantId,返回租户展示配置
新增 /system/user/batch/roles POST 批量给用户绑定角色
新增 /system/user/batch/tenants POST 批量把用户加入目标租户
新增 /auth/tenant/assets/{tenantId}/{assetType} GET 登录页只读访问启用租户配置中引用的 logo/favicon

7. 影响范围

  • 登录页品牌展示、验证码加载、登录参数。
  • 用户管理页工具栏、授权弹窗、租户绑定弹窗。
  • 系统用户服务、认证服务接口。

8. 风险与关注点

⚠️ 涉及权限变更。必须保留现有角色租户校验、当前用户自操作保护和租户管理员权限边界。

8.5 测试策略

  • 测试范围:系统插件编译、前端构建、关键 XML/接口签名检查。
  • 覆盖率目标:本轮以编译与构建验证为主,不新增持久化表结构。
  • 独立 Test Spec:是。

9. 待澄清

  • 无阻塞项,按现有 sys_user_tenant 多租户模型实现。

10. 技术决策

  • 新增批量接口只做薄封装,内部复用现有单用户绑定逻辑,减少权限规则分叉。
  • 登录页新增 /auth/tenant/options,避免未登录态调用 /system/tenant/*

11. 执行日志

Task 状态 实际改动文件 备注
Task 1 done AuthController.java, IAuthService.java, LoginConfigResult.java, LoginTenantOption.java, SystemAuthServiceImpl.java, SaTokenConfig.java 新增登录租户选项和按租户读取登录配置
Task 2 done SysUserController.java, ISysUserService.java, SysUserServiceImpl.java, BatchUserRoleBindDTO.java, BatchUserTenantBindDTO.java 批量授权采用追加语义,批量加入租户仅超级管理员可操作
Task 3 done login/api.js, login/index.vue, login/callback.vue, tenant-config.js, crypto-config.js 登录前选择租户并刷新验证码、三方登录和租户展示配置
Task 4 done system/user.vue 用户批量操作入口、租户单选回显、用户类型字典回显
Task 5 done test-spec.md, execution-log.md 后端模块编译和前端生产构建通过
Follow-up done LoginTenantAssetController.java, tenant-config.js, login/index.vue, system/user.vue, SysUserMapper.xml, SysUserServiceImpl.java 编辑所属租户改为多选、列表聚合多租户名、登录 logo/favicon 走安全白名单图片接口

12. 审查结论

13. 确认记录(HARD-GATE)

  • 确认时间:2026-06-25
  • 确认人:用户直接提出优化需求

归档记录(HARD-GATE)

  • 状态:done
  • 归档时间:2026-06-27
  • 归档人:yaomd(批量归档)
  • 归档路径:code-copilot/changes/archive/2026-06-27-user-tenant-login-authorization-optimization/
  • 判定依据:任务清单全部完成,execution-log 验证通过(编译/构建/lint 闭环)。