# 自定义注解开发 **本文引用的文件** - [DataScope.java](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.java) - [DataScopeInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java) - [DataScopeTables.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeTables.java) - [DataScopeEnum.java](file://crm-auth/src/main/java/com/crm/auth/domain/enums/DataScopeEnum.java) - [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java) - [PermissionConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/PermissionConfig.java) - [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java) - [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java) - [DataOwnership.java](file://crm-base/src/main/java/com/crm/base/security/DataOwnership.java) - [DataScopeLevel.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeLevel.java) - [LoginUser.java](file://crm-base/src/main/java/com/crm/base/security/LoginUser.java) - [SecurityUtils.java](file://crm-base/src/main/java/com/crm/base/utils/SecurityUtils.java) - [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java) - [BusinessErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/BusinessErrorException.java) - [PermissionErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/PermissionErrorException.java) - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - [CrmSqlInjector.java](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.java) - [DataScopeIntegrationTest.java](file://crm-auth/src/test/java/com/crm/auth/security/scope/DataScopeIntegrationTest.java) - [TestOwnedData.java](file://crm-auth/src/test/java/com/crm/auth/security/scope/TestOwnedData.java) - [TestOwnedDataMapper.java](file://crm-auth/src/test/java/com/crm/auth/security/scope/TestOwnedDataMapper.java) ## 目录 1. [简介](#简介) 2. [项目结构](#项目结构) 3. [核心组件](#核心组件) 4. [架构总览](#架构总览) 5. [详细组件分析](#详细组件分析) 6. [依赖关系分析](#依赖关系分析) 7. [性能考虑](#性能考虑) 8. [故障排查指南](#故障排查指南) 9. [结论](#结论) 10. [附录](#附录) ## 简介 本文件围绕“自定义注解开发”展开,以 DataScope 数据权限注解为核心示例,系统讲解从注解定义、元注解使用、切面/拦截器实现到配置与集成的完整流程。文档面向不同技术背景的读者,既提供高层概览,也给出代码级分析与可视化图示,帮助开发者快速掌握在 Spring Boot + MyBatis-Plus 环境下实现数据权限控制的最佳实践。 ## 项目结构 本项目采用多模块组织,数据权限相关能力主要分布在以下模块: - crm-base:基础能力层,包含通用注解、安全上下文、异常体系、工具类与 MyBatis-Plus 扩展配置。 - crm-auth:认证授权模块,包含数据权限拦截器、权限配置、枚举定义以及集成测试。 - 其他模块(如 crm-app、crm-file)通过依赖引入上述能力,并在业务接口上按需使用 DataScope 注解。 ```mermaid graph TB subgraph "crm-base" A["注解: DataScope"] B["安全上下文: DataVisibilityContext"] C["辅助工具: DataScopeHelper"] D["异常: BusinessErrorException / PermissionErrorException"] E["MyBatis-Plus 配置: MybatisPlusConfig / CrmSqlInjector"] end subgraph "crm-auth" F["拦截器: DataScopeInterceptor"] G["表映射: DataScopeTables"] H["枚举: DataScopeEnum"] I["配置: SecurityConfig / PermissionConfig"] J["集成测试: DataScopeIntegrationTest"] end A --> F F --> G F --> H F --> I F --> E F --> B F --> C D --> F J --> F ``` 图表来源 - [DataScope.java](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.java) - [DataScopeInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java) - [DataScopeTables.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeTables.java) - [DataScopeEnum.java](file://crm-auth/src/main/java/com/crm/auth/domain/enums/DataScopeEnum.java) - [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java) - [PermissionConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/PermissionConfig.java) - [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java) - [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java) - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - [CrmSqlInjector.java](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.java) - [BusinessErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/BusinessErrorException.java) - [PermissionErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/PermissionErrorException.java) - [DataScopeIntegrationTest.java](file://crm-auth/src/test/java/com/crm/auth/security/scope/DataScopeIntegrationTest.java) 章节来源 - [DataScope.java](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.java) - [DataScopeInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java) - [DataScopeTables.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeTables.java) - [DataScopeEnum.java](file://crm-auth/src/main/java/com/crm/auth/domain/enums/DataScopeEnum.java) - [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java) - [PermissionConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/PermissionConfig.java) - [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java) - [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java) - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - [CrmSqlInjector.java](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.java) - [BusinessErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/BusinessErrorException.java) - [PermissionErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/PermissionErrorException.java) - [DataScopeIntegrationTest.java](file://crm-auth/src/test/java/com/crm/auth/security/scope/DataScopeIntegrationTest.java) ## 核心组件 - 注解定义:DataScope 用于在 Controller/Service 方法上声明数据范围策略与目标表字段映射等参数。 - 拦截器:DataScopeInterceptor 负责解析注解、读取当前登录用户的数据权限级别、生成并注入 SQL 片段,最终影响查询结果集。 - 表映射:DataScopeTables 维护表名与数据权限字段的映射关系,便于动态拼接 WHERE 条件。 - 枚举:DataScopeEnum 定义数据范围类型(如全部、本部门、本人等)。 - 安全上下文:DataVisibilityContext 与 LoginUser 承载当前请求的上下文信息(用户、部门、角色等)。 - 辅助工具:DataScopeHelper 封装数据权限计算逻辑;SecurityUtils 提供便捷访问上下文的方法。 - 配置:SecurityConfig/PermissionConfig 注册拦截器与权限规则;MybatisPlusConfig/CrmSqlInjector 将数据权限片段注入到 SQL 执行链路。 - 异常:BusinessErrorException/PermissionErrorException 统一处理业务与权限异常。 章节来源 - [DataScope.java](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.java) - [DataScopeInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java) - [DataScopeTables.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeTables.java) - [DataScopeEnum.java](file://crm-auth/src/main/java/com/crm/auth/domain/enums/DataScopeEnum.java) - [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java) - [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java) - [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java) - [PermissionConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/PermissionConfig.java) - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - [CrmSqlInjector.java](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.java) - [BusinessErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/BusinessErrorException.java) - [PermissionErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/PermissionErrorException.java) ## 架构总览 下图展示了 DataScope 注解驱动的数据权限控制整体流程:从请求进入,经拦截器解析注解与安全上下文,生成 SQL 片段,再由 MyBatis-Plus 注入到实际执行的 SQL 中,最终返回受数据范围限制的结果集。 ```mermaid sequenceDiagram participant Client as "客户端" participant Controller as "Controller/Service" participant Interceptor as "DataScopeInterceptor" participant Tables as "DataScopeTables" participant Context as "DataVisibilityContext" participant Helper as "DataScopeHelper" participant MP as "MyBatis-Plus" participant DB as "数据库" Client->>Controller : "发起请求" Controller->>Interceptor : "被注解 @DataScope 标记的方法调用" Interceptor->>Context : "获取当前登录用户与权限级别" Interceptor->>Tables : "解析目标表与字段映射" Interceptor->>Helper : "根据策略生成数据权限片段" Helper-->>Interceptor : "返回片段" Interceptor->>MP : "将片段注入到 SQL 执行链" MP->>DB : "执行带权限片段的 SQL" DB-->>MP : "返回受限结果集" MP-->>Controller : "返回结果" Controller-->>Client : "响应数据" ``` 图表来源 - [DataScopeInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java) - [DataScopeTables.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeTables.java) - [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java) - [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java) - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - [CrmSqlInjector.java](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.java) ## 详细组件分析 ### 注解定义与元注解使用 - DataScope 注解通常包含以下关键元素: - 数据范围类型(对应 DataScopeEnum) - 目标表或实体映射(由 DataScopeTables 管理) - 可选的字段过滤键(如 deptId、userId) - 是否启用强制校验、是否忽略空值等开关 - 元注解使用建议: - 使用 @Target(ElementType.METHOD) 限定在方法级别生效 - 使用 @Retention(RetentionPolicy.RUNTIME) 保证运行时可解析 - 使用 @Documented 便于 API 文档生成 - 最佳实践: - 为注解属性设置默认值,降低使用成本 - 对必填属性进行运行时校验,避免误用导致权限失效 - 结合枚举约束取值,减少非法输入 章节来源 - [DataScope.java](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.java) - [DataScopeEnum.java](file://crm-auth/src/main/java/com/crm/auth/domain/enums/DataScopeEnum.java) ### 拦截器与切面实现原理 - DataScopeInterceptor 的核心职责: - 解析方法上的 @DataScope 注解 - 从 DataVisibilityContext 获取当前用户与权限级别 - 依据 DataScopeTables 与 DataScopeHelper 生成 SQL 片段 - 将片段注入到 MyBatis-Plus 的 SQL 执行链路 - 典型流程: - 进入拦截器前,确保已加载当前用户上下文 - 若未标注 @DataScope,则跳过权限处理 - 若标注但缺少必要参数,抛出权限异常 - 根据策略拼接 WHERE 条件片段,交由 MP 执行 - 注意事项: - 避免在拦截器中进行重 IO 操作 - 对频繁调用的方法做缓存优化(如权限片段缓存) - 严格区分只读与写操作的权限策略 章节来源 - [DataScopeInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java) - [DataScopeTables.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeTables.java) - [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java) - [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java) ### 表映射与 SQL 注入机制 - DataScopeTables 维护表名与权限字段的映射,支持: - 单表映射:如 user -> dept_id, owner_id - 多表关联:在 JOIN 场景下指定各表的权限字段 - MyBatis-Plus 注入点: - MybatisPlusConfig 启用插件或拦截器 - CrmSqlInjector 在 SQL 构建阶段插入权限片段 - 设计要点: - 映射配置应集中管理,便于维护 - 针对复杂查询,优先在 Mapper XML 中显式声明权限字段 - 避免过度依赖自动拼接,必要时回退到手写 SQL 章节来源 - [DataScopeTables.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeTables.java) - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - [CrmSqlInjector.java](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.java) ### 安全上下文与用户模型 - DataVisibilityContext 提供线程安全的上下文存取: - 存储当前用户、部门、角色、租户等信息 - 提供清理方法防止内存泄漏 - LoginUser 承载用户基本信息与权限标识 - 使用建议: - 在请求入口初始化上下文,在出口清理 - 避免在上下文中存放大对象 - 对敏感信息进行脱敏处理 章节来源 - [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java) - [LoginUser.java](file://crm-base/src/main/java/com/crm/base/security/LoginUser.java) - [SecurityUtils.java](file://crm-base/src/main/java/com/crm/base/utils/SecurityUtils.java) ### 配置与注册 - SecurityConfig/PermissionConfig 负责: - 注册 DataScopeInterceptor - 配置拦截路径与排除路径 - 设定默认数据范围策略 - 建议: - 将白名单与黑名单配置化,便于环境差异化管理 - 为不同环境提供不同的默认策略 章节来源 - [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java) - [PermissionConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/PermissionConfig.java) ### 异常处理与参数验证 - 统一异常体系: - BusinessErrorException:业务错误 - PermissionErrorException:权限错误 - 参数验证: - 在注解解析阶段校验必填项 - 在拦截器中对上下文有效性进行检查 - 建议: - 明确区分参数错误与权限错误,便于前端提示 - 记录关键日志,便于问题定位 章节来源 - [BusinessErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/BusinessErrorException.java) - [PermissionErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/PermissionErrorException.java) - [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java) ### 数据所有权与层级控制 - DataOwnership 与 DataScopeLevel 用于表达数据所有权与层级关系: - 支持按个人、部门、公司等多层级范围 - 与 DataScopeEnum 配合形成完整的权限矩阵 - 使用建议: - 在建模时明确数据归属字段 - 在查询时优先使用层级聚合,减少多次扫描 章节来源 - [DataOwnership.java](file://crm-base/src/main/java/com/crm/base/security/DataOwnership.java) - [DataScopeLevel.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeLevel.java) ### 集成测试与使用场景 - DataScopeIntegrationTest 演示了如何: - 构造测试数据与上下文 - 调用标注 @DataScope 的方法 - 断言返回结果符合预期数据范围 - TestOwnedData/TestOwnedDataMapper 作为示例实体与映射,展示如何在真实场景中应用数据权限 章节来源 - [DataScopeIntegrationTest.java](file://crm-auth/src/test/java/com/crm/auth/security/scope/DataScopeIntegrationTest.java) - [TestOwnedData.java](file://crm-auth/src/test/java/com/crm/auth/security/scope/TestOwnedData.java) - [TestOwnedDataMapper.java](file://crm-auth/src/test/java/com/crm/auth/security/scope/TestOwnedDataMapper.java) ## 依赖关系分析 下图展示了 DataScope 相关组件之间的依赖关系,包括注解、拦截器、表映射、枚举、上下文、配置与异常体系。 ```mermaid classDiagram class DataScope { + "注解属性" } class DataScopeInterceptor { + "解析注解" + "生成SQL片段" + "注入执行链" } class DataScopeTables { + "表与字段映射" } class DataScopeEnum { + "数据范围类型" } class DataVisibilityContext { + "上下文存取" } class DataScopeHelper { + "权限计算" } class MybatisPlusConfig class CrmSqlInjector class SecurityConfig class PermissionConfig class BusinessErrorException class PermissionErrorException DataScope --> DataScopeInterceptor : "触发" DataScopeInterceptor --> DataScopeTables : "读取映射" DataScopeInterceptor --> DataScopeEnum : "匹配策略" DataScopeInterceptor --> DataVisibilityContext : "获取上下文" DataScopeInterceptor --> DataScopeHelper : "计算片段" DataScopeInterceptor --> MybatisPlusConfig : "依赖配置" DataScopeInterceptor --> CrmSqlInjector : "注入SQL" DataScopeInterceptor --> SecurityConfig : "注册拦截器" DataScopeInterceptor --> PermissionConfig : "权限规则" DataScopeInterceptor --> BusinessErrorException : "业务异常" DataScopeInterceptor --> PermissionErrorException : "权限异常" ``` 图表来源 - [DataScope.java](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.java) - [DataScopeInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java) - [DataScopeTables.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeTables.java) - [DataScopeEnum.java](file://crm-auth/src/main/java/com/crm/auth/domain/enums/DataScopeEnum.java) - [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java) - [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java) - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - [CrmSqlInjector.java](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.java) - [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java) - [PermissionConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/PermissionConfig.java) - [BusinessErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/BusinessErrorException.java) - [PermissionErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/PermissionErrorException.java) 章节来源 - [DataScope.java](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.java) - [DataScopeInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java) - [DataScopeTables.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeTables.java) - [DataScopeEnum.java](file://crm-auth/src/main/java/com/crm/auth/domain/enums/DataScopeEnum.java) - [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java) - [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java) - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - [CrmSqlInjector.java](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.java) - [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java) - [PermissionConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/PermissionConfig.java) - [BusinessErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/BusinessErrorException.java) - [PermissionErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/PermissionErrorException.java) ## 性能考虑 - 缓存优化: - 对频繁使用的权限片段进行缓存,避免重复计算 - 对表映射配置进行懒加载与热更新 - 上下文管理: - 严格控制上下文生命周期,避免内存泄漏 - 避免在上下文中存放大对象 - SQL 优化: - 尽量在 WHERE 中使用索引友好的字段 - 避免在权限片段中使用函数包裹字段 - 并发安全: - 确保上下文与缓存的线程安全性 - 合理设置超时与重试策略 [本节为通用指导,不直接分析具体文件] ## 故障排查指南 - 常见问题: - 注解参数缺失导致权限失效:检查注解必填项与默认值 - 上下文未初始化导致权限为空:确认请求入口是否正确设置上下文 - SQL 片段未注入:检查 MyBatis-Plus 插件与注入点配置 - 权限异常未捕获:确认全局异常处理器是否生效 - 排查步骤: - 开启调试日志,观察拦截器执行轨迹 - 打印生成的 SQL 片段,核对权限条件 - 使用集成测试复现问题,逐步缩小范围 章节来源 - [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java) - [BusinessErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/BusinessErrorException.java) - [PermissionErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/PermissionErrorException.java) - [DataScopeIntegrationTest.java](file://crm-auth/src/test/java/com/crm/auth/security/scope/DataScopeIntegrationTest.java) ## 结论 通过 DataScope 注解与拦截器的协同工作,项目实现了灵活、可扩展的数据权限控制。开发者只需在方法上标注注解,即可自动完成权限解析、SQL 注入与结果过滤。遵循本文的最佳实践,可在保证安全性的同时提升系统的可维护性与性能。 [本节为总结性内容,不直接分析具体文件] ## 附录 - 自定义注解开发清单: - 明确注解用途与属性设计 - 选择合适的元注解与保留策略 - 编写解析与执行逻辑(拦截器/切面) - 配置注册与路径控制 - 完善异常与日志 - 编写单元测试与集成测试 - 参考实现路径: - 注解定义:[DataScope.java](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.java) - 拦截器实现:[DataScopeInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java) - 表映射配置:[DataScopeTables.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeTables.java) - 枚举定义:[DataScopeEnum.java](file://crm-auth/src/main/java/com/crm/auth/domain/enums/DataScopeEnum.java) - 上下文与工具:[DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java), [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java) - 配置与注入:[SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java), [PermissionConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/PermissionConfig.java), [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java), [CrmSqlInjector.java](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.java) - 异常体系:[BusinessErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/BusinessErrorException.java), [PermissionErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/PermissionErrorException.java), [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java) - 集成测试:[DataScopeIntegrationTest.java](file://crm-auth/src/test/java/com/crm/auth/security/scope/DataScopeIntegrationTest.java)