You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

26 KiB

开发规范

**本文引用的文件** - [CrmAppApplication.java](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java) - [application.yml](file://crm-app/src/main/resources/application.yml) - [AuthApplication.java](file://crm-auth/src/main/java/com/crm/auth/AuthApplication.java) - [application.yml](file://crm-auth/src/main/resources/application.yml) - [BaseEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/BaseEntity.java) - [OwnedEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/OwnedEntity.java) - [BaseDTO.java](file://crm-base/src/main/java/com/crm/base/domain/dto/BaseDTO.java) - [BaseParam.java](file://crm-base/src/main/java/com/crm/base/domain/param/BaseParam.java) - [Result.java](file://crm-base/src/main/java/com/crm/base/domain/result/Result.java) - [PageResult.java](file://crm-base/src/main/java/com/crm/base/domain/result/PageResult.java) - [ResultCodeEnum.java](file://crm-base/src/main/java/com/crm/base/domain/result/ResultCodeEnum.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) - [MissingParameterException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/MissingParameterException.java) - [PermissionErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/PermissionErrorException.java) - [ResourceNotExistException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/ResourceNotExistException.java) - [DataScope.java](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.java) - [DataOwnership.java](file://crm-base/src/main/java/com/crm/base/security/DataOwnership.java) - [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java) - [DataScopeLevel.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeLevel.java) - [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/security/SecurityUtils.java) - [TraceIdFilter.java](file://crm-base/src/main/java/com/crm/base/filter/TraceIdFilter.java) - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - [MetaObjectFillHandler.java](file://crm-base/src/main/java/com/crm/base/config/MetaObjectFillHandler.java) - [SnowflakeIdWorker.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.java) - [CustomIdGenerator.java](file://crm-base/src/main/java/com/crm/base/config/CustomIdGenerator.java) - [AuthService.java](file://crm-auth/src/main/java/com/crm/auth/service/IAuthService.java) - [AuthServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthServiceImpl.java) - [AuthController.java](file://crm-auth/src/main/java/com/crm/auth/controller/AuthController.java) - [JwtAuthenticationFilter.java](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java) - [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java) - [SecurityExceptionHandlers.java](file://crm-auth/src/main/java/com/crm/auth/security/SecurityExceptionHandlers.java) - [LoginParam.java](file://crm-auth/src/main/java/com/crm/auth/domain/param/LoginParam.java) - [LoginResultDTO.java](file://crm-auth/src/main/java/com/crm/auth/domain/dto/LoginResultDTO.java) - [UserInfoDTO.java](file://crm-auth/src/main/java/com/crm/auth/domain/dto/UserInfoDTO.java) - [AuthUser.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/AuthUser.java) - [AuthIdentity.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/AuthIdentity.java) - [SysDept.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysDept.java) - [SysMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysMenu.java) - [SysRole.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRole.java) - [SysRoleMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRoleMenu.java) - [SysUserDept.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysUserDept.java) - [SysUserRole.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysUserRole.java) - [DataScopeEnum.java](file://crm-auth/src/main/java/com/crm/auth/domain/enums/DataScopeEnum.java) - [IdentityTypeEnum.java](file://crm-auth/src/main/java/com/crm/auth/domain/enums/IdentityTypeEnum.java) - [MenuTypeEnum.java](file://crm-auth/src/main/java/com/crm/auth/domain/enums/MenuTypeEnum.java) - [FileApi.java](file://crm-file/src/main/java/com/crm/file/api/FileApi.java) - [FileController.java](file://crm-file/src/main/java/com/crm/file/controller/FileController.java) - [FileInfo.java](file://crm-file/src/main/java/com/crm/file/domain/entity/FileInfo.java) - [IFileInfoService.java](file://crm-file/src/main/java/com/crm/file/service/IFileInfoService.java) - [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java) - [FileApiImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileApiImpl.java) - [KkFileViewClient.java](file://crm-file/src/main/java/com/crm/file/service/KkFileViewClient.java) - [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java) - [pom.xml](file://pom.xml)

目录

  1. 简介
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖分析
  7. 性能考虑
  8. 故障排查指南
  9. 结论
  10. 附录

简介

本规范面向 CRM 后端多模块工程,统一代码风格、命名约定、包结构、实体与数据传输对象设计、异常与日志规范、注释规范以及 Git 工作流与代码审查流程。目标是通过一致的编码标准提升代码质量、可维护性与团队协作效率。

项目结构

本项目采用多模块 Maven 工程,按领域与职责划分:

  • crm-app:应用启动入口与全局配置
  • crm-base:基础能力(通用实体、DTO/Param/Result、安全上下文、数据权限、异常、工具类、MyBatis Plus 配置)
  • crm-auth:认证授权与系统管理(用户、角色、菜单、部门、第三方登录等)
  • crm-file:文件服务(上传、分片、预览、清理任务等)
graph TB
subgraph "应用层"
APP["crm-app<br/>启动与配置"]
end
subgraph "业务域"
AUTH["crm-auth<br/>认证与系统管理"]
FILE["crm-file<br/>文件服务"]
end
subgraph "基础能力"
BASE["crm-base<br/>通用实体/DTO/Param/Result<br/>安全上下文/异常/工具/配置"]
end
APP --> AUTH
APP --> FILE
AUTH --> BASE
FILE --> BASE

图示来源

  • CrmAppApplication.java
  • AuthApplication.java
  • pom.xml

章节来源

  • CrmAppApplication.java
  • AuthApplication.java
  • pom.xml

核心组件

  • 通用实体基类与数据所有权
    • BaseEntity:统一审计字段(如创建时间、更新时间等),配合元数据填充处理器自动落库
    • OwnedEntity:在 BaseEntity 基础上增加数据归属字段,结合数据可见性上下文实现行级数据权限控制
  • 数据传输对象
    • BaseDTO:通用 DTO 基类,用于接口返回或跨层传输
    • BaseParam:通用请求参数基类,用于入参校验与封装
    • Result/PageResult:统一响应包装与分页结果
  • 安全与数据权限
    • LoginUser/SecurityUtils:当前登录用户上下文获取
    • DataOwnership/DataScope/DataScopeLevel/DataScopeHelper/DataVisibilityContext:数据权限注解、级别、辅助方法与上下文
  • 异常体系
    • BusinessErrorException/MissingParameterException/PermissionErrorException/ResourceNotExistException:业务、参数、权限、资源不存在等异常类型
    • GlobalExceptionHandlerAdvice:全局异常处理,统一错误码与消息
  • MyBatis Plus 增强
    • MetaObjectFillHandler:自动填充审计字段
    • SnowflakeIdWorker/CustomIdGenerator:分布式 ID 生成策略
    • MybatisPlusConfig:MP 配置注入

章节来源

  • BaseEntity.java
  • OwnedEntity.java
  • BaseDTO.java
  • BaseParam.java
  • Result.java
  • PageResult.java
  • ResultCodeEnum.java
  • GlobalExceptionHandlerAdvice.java
  • BusinessErrorException.java
  • MissingParameterException.java
  • PermissionErrorException.java
  • ResourceNotExistException.java
  • DataOwnership.java
  • DataScope.java
  • DataScopeLevel.java
  • DataScopeHelper.java
  • DataVisibilityContext.java
  • LoginUser.java
  • SecurityUtils.java
  • MetaObjectFillHandler.java
  • SnowflakeIdWorker.java
  • CustomIdGenerator.java
  • MybatisPlusConfig.java

架构总览

分层与边界:

  • 表现层(Controller):接收请求、参数校验、调用 Service
  • 服务层(Service):业务编排、事务边界、调用 Mapper 与外部客户端
  • 持久层(Mapper):数据访问,基于 MyBatis Plus
  • 安全与数据权限:过滤器/拦截器 + 注解 + 上下文,贯穿 Controller -> Service -> Mapper
  • 基础设施:统一异常、日志追踪、ID 生成、分页、枚举、工具类
sequenceDiagram
participant Client as "客户端"
participant AuthCtrl as "认证控制器"
participant TokenSvc as "令牌服务"
participant AuthService as "认证服务"
participant DB as "数据库"
Client->>AuthCtrl : "POST /auth/login"
AuthCtrl->>AuthService : "验证用户名密码"
AuthService->>DB : "查询用户信息"
DB-->>AuthService : "用户记录"
AuthService-->>AuthCtrl : "用户信息"
AuthCtrl->>TokenSvc : "签发JWT"
TokenSvc-->>AuthCtrl : "令牌"
AuthCtrl-->>Client : "登录成功响应"

图示来源

  • AuthController.java
  • AuthService.java
  • AuthServiceImpl.java
  • TokenService.java

详细组件分析

实体类设计规范(BaseEntity 与 OwnedEntity)

  • BaseEntity
    • 职责:提供统一的审计字段(如创建人、创建时间、更新人、更新时间等)
    • 使用方式:所有持久化实体继承 BaseEntity;配合元数据填充处理器自动设置审计字段
    • 复杂度:O(1) 字段赋值,填充发生在插入/更新前
  • OwnedEntity
    • 职责:在 BaseEntity 基础上增加“数据所有者”字段,用于数据隔离与权限过滤
    • 使用方式:需要数据归属控制的实体继承 OwnedEntity;结合 DataOwnership/DataScope 注解与上下文进行行级过滤
    • 注意:避免在批量操作中遗漏数据所有者,确保上下文正确设置
classDiagram
class BaseEntity {
+审计字段集合
+默认填充逻辑
}
class OwnedEntity {
+数据所有者字段
+数据可见性关联
}
BaseEntity <|-- OwnedEntity : "继承"

图示来源

  • BaseEntity.java
  • OwnedEntity.java

章节来源

  • BaseEntity.java
  • OwnedEntity.java
  • MetaObjectFillHandler.java

数据传输对象设计(DTO、Param、Result)

  • BaseDTO
    • 用途:作为通用 DTO 基类,承载接口返回数据或跨层传输数据
    • 建议:仅包含必要字段,避免直接暴露实体内部结构
  • BaseParam
    • 用途:作为通用请求参数基类,承载入参校验与封装
    • 建议:与表单/查询参数一一对应,必要时使用分组校验
  • Result/PageResult
    • 用途:统一 API 响应包装,包含状态码、消息、数据体;PageResult 扩展分页信息
    • 建议:保持响应结构一致,便于前端解析与错误处理
  • 枚举与常量
    • ResultCodeEnum:统一错误码定义,避免硬编码
    • 业务枚举:集中定义于 domain/enums 包下,保证一致性
classDiagram
class BaseDTO {
+通用DTO字段
}
class BaseParam {
+通用参数字段
+校验规则
}
class Result {
+状态码
+消息
+数据体
}
class PageResult {
+分页信息
+数据列表
}
class ResultCodeEnum {
+错误码定义
}
Result --> ResultCodeEnum : "引用"
PageResult --> Result : "扩展"

图示来源

  • BaseDTO.java
  • BaseParam.java
  • Result.java
  • PageResult.java
  • ResultCodeEnum.java

章节来源

  • BaseDTO.java
  • BaseParam.java
  • Result.java
  • PageResult.java
  • ResultCodeEnum.java

认证与鉴权流程

  • 登录流程
    • 控制器接收登录参数,调用认证服务验证用户
    • 认证成功后由令牌服务签发 JWT,并返回给客户端
  • 鉴权流程
    • 请求进入时通过 JWT 过滤器解析令牌,构建登录用户上下文
    • 数据权限通过 DataScope 注解与 DataOwnership 注解共同作用,结合 DataVisibilityContext 进行行级过滤
sequenceDiagram
participant Client as "客户端"
participant Filter as "JWT过滤器"
participant Ctrl as "业务控制器"
participant Svc as "业务服务"
participant MP as "MyBatis Plus"
Client->>Filter : "携带JWT的请求"
Filter->>Filter : "解析令牌与用户上下文"
Filter-->>Ctrl : "放行并注入上下文"
Ctrl->>Svc : "执行业务方法"
Svc->>MP : "执行SQL带数据权限条件"
MP-->>Svc : "返回受控数据"
Svc-->>Ctrl : "业务结果"
Ctrl-->>Client : "统一响应"

图示来源

  • JwtAuthenticationFilter.java
  • TokenService.java
  • DataScope.java
  • DataOwnership.java
  • DataScopeHelper.java
  • DataVisibilityContext.java

章节来源

  • JwtAuthenticationFilter.java
  • TokenService.java
  • DataScope.java
  • DataOwnership.java
  • DataScopeHelper.java
  • DataVisibilityContext.java

文件服务组件

  • FileController:提供文件上传、下载、预览等接口
  • IFileInfoService/FileInfoServiceImpl:文件信息管理与业务逻辑
  • FileApiImpl:对外文件能力抽象实现
  • KkFileViewClient:第三方文件预览客户端
  • OrphanChunkCleanupTask:定时清理孤立分片任务
classDiagram
class FileController {
+上传接口
+下载接口
+预览接口
}
class IFileInfoService {
+文件信息管理
}
class FileInfoServiceImpl {
+实现文件业务逻辑
}
class FileApiImpl {
+对外API实现
}
class KkFileViewClient {
+预览客户端
}
class OrphanChunkCleanupTask {
+清理任务
}
FileController --> IFileInfoService : "调用"
IFileInfoService <|.. FileInfoServiceImpl : "实现"
FileApiImpl --> IFileInfoService : "依赖"
FileController --> KkFileViewClient : "预览"
OrphanChunkCleanupTask --> IFileInfoService : "清理"

图示来源

  • FileController.java
  • IFileInfoService.java
  • FileInfoServiceImpl.java
  • FileApiImpl.java
  • KkFileViewClient.java
  • OrphanChunkCleanupTask.java

章节来源

  • FileController.java
  • IFileInfoService.java
  • FileInfoServiceImpl.java
  • FileApiImpl.java
  • KkFileViewClient.java
  • OrphanChunkCleanupTask.java

复杂逻辑流程图(数据权限过滤)

flowchart TD
Start(["进入受控方法"]) --> CheckAnno["检查是否标注数据权限注解"]
CheckAnno --> |是| BuildScope["构建数据范围条件"]
CheckAnno --> |否| Skip["跳过数据权限过滤"]
BuildScope --> ApplyScope["应用到查询条件"]
ApplyScope --> ExecQuery["执行数据库查询"]
Skip --> ExecQuery
ExecQuery --> Return["返回受控结果"]

图示来源

  • DataScope.java
  • DataScopeHelper.java
  • DataVisibilityContext.java

章节来源

  • DataScope.java
  • DataScopeHelper.java
  • DataVisibilityContext.java

依赖分析

模块间依赖关系清晰,遵循“上层依赖下层”的原则:

  • crm-app 依赖 crm-auth 与 crm-file
  • crm-auth 与 crm-file 均依赖 crm-base
  • 各模块内按 controller -> service -> mapper 分层依赖
graph LR
APP["crm-app"] --> AUTH["crm-auth"]
APP --> FILE["crm-file"]
AUTH --> BASE["crm-base"]
FILE --> BASE

图示来源

  • pom.xml

章节来源

  • pom.xml

性能考虑

  • 分布式 ID:使用雪花算法生成唯一 ID,避免自增主键在高并发下的瓶颈
  • 元数据填充:通过 MyBatis Plus 的元数据填充减少手动赋值开销
  • 数据权限:尽量将数据权限条件下推到 SQL 层,减少内存过滤
  • 缓存与限流:对热点数据(如部门树、菜单)考虑引入缓存;对外部调用(如第三方登录、文件预览)增加超时与重试策略
  • 分页查询:合理使用分页,避免一次性加载大量数据

[本节为通用指导,不直接分析具体文件]

故障排查指南

  • 全局异常处理
    • 统一捕获业务异常、参数异常、权限异常与资源不存在异常
    • 返回统一 Result 结构,便于前端处理
  • 常见异常定位
    • 参数缺失:检查 BaseParam 校验规则与入参映射
    • 权限不足:检查 DataScope/DataOwnership 注解与上下文设置
    • 资源不存在:检查查询条件与数据归属
  • 日志追踪
    • TraceIdFilter:为每个请求生成追踪 ID,贯穿日志链路
    • 建议在关键路径打印必要上下文,避免泄露敏感信息

章节来源

  • GlobalExceptionHandlerAdvice.java
  • BusinessErrorException.java
  • MissingParameterException.java
  • PermissionErrorException.java
  • ResourceNotExistException.java
  • TraceIdFilter.java

结论

本规范从代码风格、命名约定、包结构到实体与 DTO 设计、异常与日志、Git 工作流与代码审查,提供了完整的开发标准。遵循这些规范有助于提升代码质量、降低协作成本,并为后续扩展与维护奠定基础。

附录

代码风格与命名约定

  • 类名:大驼峰,名词或名词短语(如 UserService、FileInfo)
  • 方法名:小驼峰,动词开头(如 getUserById、uploadFile)
  • 常量:全大写加下划线(如 MAX_RETRY_COUNT)
  • 包名:全小写,按功能划分(controller、service、mapper、domain、config、security、utils)
  • 字段命名:小驼峰,语义明确,避免缩写歧义

包结构规范

  • controller:HTTP 接口层,仅做参数校验与调用服务
  • service:业务逻辑层,事务边界与方法编排
  • mapper:数据访问层,基于 MyBatis Plus
  • domain:
    • entity:持久化实体
    • dto:数据传输对象
    • param:请求参数
    • enums:枚举定义
  • config:配置类(Spring、MyBatis Plus、Redis、Knife4j 等)
  • security:安全相关(过滤器、拦截器、上下文、工具)
  • utils:通用工具类
  • advice:全局异常处理
  • filter:过滤器(如追踪 ID)

实体类设计规范

  • 所有实体继承 BaseEntity,获得审计字段
  • 需要数据归属控制的实体继承 OwnedEntity
  • 避免在实体中放置业务逻辑,保持 POJO 特性
  • 字段注释完整,便于文档生成与理解

DTO、Param、Result 设计模式

  • DTO:面向接口输出,精简字段,避免泄露内部结构
  • Param:面向输入,严格校验,必要时使用分组校验
  • Result/PageResult:统一响应格式,便于前端解析
  • 枚举:集中定义,避免魔法值

异常处理规范

  • 自定义异常分类:业务异常、参数异常、权限异常、资源不存在异常
  • 全局异常处理器统一捕获并转换为 Result
  • 避免吞掉异常,确保错误可追溯

日志记录规范

  • 使用统一日志框架,区分 INFO/WARN/ERROR
  • 关键路径记录必要上下文,避免敏感信息泄露
  • 使用 TraceIdFilter 生成的追踪 ID 串联日志

注释编写规范

  • 类与方法必须有清晰注释,说明职责、参数、返回值与异常
  • 复杂逻辑添加行内注释,解释关键步骤
  • 枚举与常量需有含义明确的描述

Git 提交信息规范

  • 格式:():
  • type:feat、fix、docs、style、refactor、test、chore
  • scope:模块或功能范围(如 auth、file、base)
  • subject:简洁明了,不超过 50 字符

分支管理策略

  • main:稳定版本,仅接受合并请求
  • develop:开发主干,日常集成
  • feature/*:功能分支,完成后合并至 develop
  • hotfix/*:热修复分支,紧急修复后合并至 main 与 develop

代码审查流程

  • 提交前自检:编译通过、单元测试覆盖、符合规范
  • 发起 MR/PR:填写变更说明与影响范围
  • 审查要点:逻辑正确性、性能、安全性、可维护性
  • 通过后合并:确保 CI 通过且无冲突