feat(tenant): 租户-项目两级架构 Phase 0+1 — 基础框架层
Phase 0 技术验证: - ProjectBaseDO extends TenantBaseDO,新增 projectId 字段 - ProjectContextHolder (TransmittableThreadLocal) 项目上下文管理 - ProjectDatabaseInterceptor 实现 TenantLineHandler,返回 project_id 列 - 注册第二个 TenantLineInnerInterceptor,通过 @Qualifier 保证初始化顺序 - DualInterceptorTest 11 个用例验证双拦截器 SQL 注入(SELECT/INSERT/UPDATE/DELETE + JOIN + 子查询) Phase 1 基础框架层: - @ProjectIgnore 注解 + ProjectIgnoreAspect (SpEL 条件支持) - ProjectUtils 工具类 (execute/executeIgnore) - ProjectContextWebFilter 从请求 Header 解析 project-id - WebFrameworkUtils 扩展 HEADER_PROJECT_ID + getProjectId() - WebFilterOrderEnum 新增 PROJECT_CONTEXT_FILTER、PROJECT_SECURITY_FILTER - RPC: TenantRequestInterceptor 自动透传 project-id - MQ: Kafka/RocketMQ/RabbitMQ/Redis 全部支持 project-id 发送与消费 - @ProjectJob + ProjectJobAspect (@Order(2) 内层,配合 @TenantJob 使用) - TenantJobAspect 补充 @Order(1) 外层标记 - ProjectDO + UserProjectDO + Mapper + ProjectService + ProjectController - ProjectCommonApi (Feign) + ProjectApiImpl + ProjectFrameworkServiceImpl (Guava 缓存) - TenantServiceImpl.createTenant() 联动创建默认项目 - ErrorCodeConstants 新增 1-002-030-xxx 项目错误码 Review 修复: - Bean 初始化顺序: projectLineInnerInterceptor 依赖 @Qualifier 确保顺序 - computeIgnoreTable: @ProjectIgnore 检查优先于 isAssignableFrom - ProjectFrameworkServiceImpl 注册为 Spring Bean - RocketMQ SendHook: project-id 独立于 tenantId 传播 - createDefaultProject 移入 TenantUtils.execute 事务块内 - 全部 MQ/RPC 统一使用 HEADER_PROJECT_ID 常量 - ProjectJobAspect 增加租户上下文防御校验 - 移除 ProjectDO/UserProjectDO 无效的 @KeySequence - ProjectServiceImpl/ProjectApiImpl 移除冗余 TenantUtils.execute 嵌套 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -171,4 +171,11 @@ public interface ErrorCodeConstants {
|
||||
// ========== 站内信发送 1-002-028-000 ==========
|
||||
ErrorCode NOTIFY_SEND_TEMPLATE_PARAM_MISS = new ErrorCode(1_002_028_000, "模板参数({})缺失");
|
||||
|
||||
// ========== 项目 1-002-030-000 ==========
|
||||
ErrorCode PROJECT_NOT_EXISTS = new ErrorCode(1_002_030_000, "项目不存在");
|
||||
ErrorCode PROJECT_DISABLE = new ErrorCode(1_002_030_001, "名字为【{}】的项目已被禁用");
|
||||
ErrorCode PROJECT_NAME_DUPLICATE = new ErrorCode(1_002_030_002, "名字为【{}】的项目已存在");
|
||||
ErrorCode PROJECT_CODE_DUPLICATE = new ErrorCode(1_002_030_003, "编码为【{}】的项目已存在");
|
||||
ErrorCode PROJECT_NOT_AUTHORIZED = new ErrorCode(1_002_030_004, "您未被授权访问该项目");
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user