feat(tenant): 实现 ProjectSecurityWebFilter 项目权限集合校验

新增 ProjectSecurityWebFilter:
- 集合校验: user.authorizedProjectIds.contains(header.projectId)
- 默认项目选择: DEFAULT编码 → 最小ID → 单项目自动选中 → 无授权403
- @ProjectIgnore URL 自动跳过
- 注册在 WebFilterOrderEnum.PROJECT_SECURITY_FILTER (-98)

框架层:
- ProjectCommonApi: 新增 getAuthorizedProjectIds, getDefaultProjectId
- ProjectFrameworkService: 新增授权查询 + Caffeine 缓存(60s/1000条)
- ViewshTenantAutoConfiguration: 注册 Filter + 扫描 @ProjectIgnore

业务层:
- ProjectService: 新增 getAuthorizedProjectIds, getDefaultProjectId
- ProjectServiceImpl: 默认项目3级回退逻辑
- ProjectApiImpl: 实现 Feign 端点

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
lzh
2026-04-16 23:35:56 +08:00
parent c85f84ea46
commit 423bf3ec3f
8 changed files with 320 additions and 0 deletions

View File

@@ -26,4 +26,13 @@ public interface ProjectCommonApi {
@Parameter(name = "id", description = "项目编号", required = true, example = "1024")
CommonResult<Boolean> validProject(@RequestParam("id") Long id);
@GetMapping(PREFIX + "/authorized-ids")
@Operation(summary = "获得用户授权的项目编号列表")
CommonResult<List<Long>> getAuthorizedProjectIds(@RequestParam("userId") Long userId);
@GetMapping(PREFIX + "/default-id")
@Operation(summary = "获得用户的默认项目编号")
@Parameter(name = "userId", description = "用户编号", required = true)
CommonResult<Long> getDefaultProjectId(@RequestParam("userId") Long userId);
}