7.1 KiB
后端业务功能开发规范
本文是本项目后端新增或修改业务功能时的权威规范。开发后台管理端业务模块时,必须优先遵循本项目现有架构,而不是套用通用 Spring Boot 三层模板。
架构原则
后端业务代码按 Controller -> ApplicationService -> Model -> db Service/Mapper 组织。
优先参考这些现有模块:
backend/agileboot-domain/src/main/java/com/agileboot/domain/system/postbackend/agileboot-domain/src/main/java/com/agileboot/domain/system/userbackend/agileboot-domain/src/main/java/com/agileboot/domain/system/rolebackend/agileboot-domain/src/main/java/com/agileboot/domain/system/noticebackend/agileboot-admin/src/main/java/com/agileboot/admin/controller/system
不要让 Controller 直接调用 Mapper,不要把业务规则写在 Controller,也不要直接把 Entity 或 DO 返回给前端。
开发准备
开发新后端业务功能前,应先确认需求所属领域、涉及的数据表、接口范围、权限标识和相似模块。本文是后端业务功能开发的统一规范。
开始编码前必须先做一次相似模块调研,确认目标功能最接近 post、user、role、notice 还是其他模块,再按相似模块的命名、包路径、注解、分页、异常、权限、日志和测试风格实现。
目录结构
后台管理端入口放在 agileboot-admin:
backend/agileboot-admin/src/main/java/com/agileboot/admin/controller/<area>/
└── XxxController.java
业务代码放在 agileboot-domain:
backend/agileboot-domain/src/main/java/com/agileboot/domain/<area>/xxx/
├── XxxApplicationService.java
├── command/
│ ├── AddXxxCommand.java
│ └── UpdateXxxCommand.java
├── query/
│ └── XxxQuery.java
├── dto/
│ ├── XxxDTO.java
│ └── XxxDetailDTO.java
├── model/
│ ├── XxxModel.java
│ └── XxxModelFactory.java
└── db/
├── XxxEntity.java
├── XxxDO.java
├── XxxMapper.java
├── XxxService.java
└── XxxServiceImpl.java
XxxDO 是可选文件。只有当查询结果包含 join、聚合、报表字段或其他不完全匹配 Entity 的字段时才创建。
如果业务属于已有领域,例如 system,放到现有领域下;如果是独立业务领域,创建新的 <area> 包名,例如 business。
各层职责
Controller 只负责 HTTP 层:
- 声明
@RestController、@RequestMapping、@Validated、Swagger 注解。 - 接收
Command、Query、路径参数和请求参数。 - 使用
@PreAuthorize("@permission.has('xxx:yyy:zzz')")做权限控制。 - 对新增、修改、删除、导出等操作使用
@AccessLog。 - 调用
XxxApplicationService。 - 使用
ResponseDTO.ok(...)返回结果。
ApplicationService 负责编排业务用例:
- 分页查询、详情查询、导出查询、新增、修改、删除。
- 创建或加载
XxxModel。 - 调用领域模型完成业务校验和状态变化。
- 调用
db包中的 Service 完成查询和持久化。 - 将 Entity 或 DO 转换为 DTO。
- 分页结果使用
PageDTO<T>。
Model 承载业务规则:
- 从
AddXxxCommand、UpdateXxxCommand加载字段。 - 封装唯一性校验、状态校验、是否允许删除、业务状态流转等规则。
- 需要数据库判断时,通过构造注入的
XxxService查询。 - 业务失败时抛出
ApiException,不要返回布尔值让上层解释。
ModelFactory 负责创建和加载模型:
create()返回带有依赖的空模型。loadById(id)从数据库加载 Entity,并包装为 Model。- 如果未找到必要数据,按项目现有异常风格处理。
db 包只负责持久化:
XxxEntity映射数据库表。XxxDO承载复杂查询结果,例如关联表字段、统计字段、报表字段。XxxMapper继承 MyBatis PlusBaseMapper<XxxEntity>。XxxService继承IService<XxxEntity>,声明复用型查询方法。XxxServiceImpl继承ServiceImpl<XxxMapper, XxxEntity>,实现唯一性检查、关联检查、复杂查询等。- 复杂 SQL 放到 mapper XML,简单条件优先使用 MyBatis Plus wrapper。
XxxDO 属于数据库查询结果对象,不是前端响应对象,也不是请求对象。Mapper 或 Service 可以返回 XxxDO,但 ApplicationService 必须转换为 XxxDTO 后再交给 Controller 返回。
Command、Query、DTO 的边界:
Command用于新增、修改等写请求,不要直接接收 Entity。Query用于列表、搜索、分页条件,并提供toPage()、toQueryWrapper()等项目已有风格的方法。DTO用于响应前端,不要直接暴露 Entity 或 DO。- 批量删除优先使用
BulkOperationCommand<Long>。
开发流程
- 检索并阅读一个最相似的现有模块,确认命名、包路径、注解、分页、异常、测试风格。
- 确认数据库表结构,保持主键、软删除、审计字段、字段命名与现有表一致。
- 创建
db包:Entity、Mapper、Service、ServiceImpl;如查询结果包含关联表字段、统计字段或报表字段,再增加XxxDO。 - 创建 API 契约:
AddXxxCommand、UpdateXxxCommand、XxxQuery、XxxDTO,需要详情时添加XxxDetailDTO。 - 创建
XxxModel和XxxModelFactory,把业务校验放进 Model。 - 创建
XxxApplicationService,编排查询、新增、修改、删除、导出等用例。 - 创建
XxxController,加路由、权限、操作日志和统一响应。 - 如功能出现在后台菜单,补充权限标识、菜单 SQL 或清楚说明需要配置的权限码。
- 增加聚焦测试,至少覆盖核心业务校验和主要用例。
- 运行相关 Maven 测试或编译检查;如果不能运行,说明原因。
开发过程中如果发现本文未覆盖的模式,优先参考现有模块,而不是引入新的架构风格。确实需要新增模式时,应先更新本文,再按新规范实现。
权限、日志和错误
权限码必须和前端菜单或按钮权限保持一致,格式参考现有系统功能:
@PreAuthorize("@permission.has('system:post:add')")
操作日志按业务动作选择类型:
@AccessLog(title = "业务名称", businessType = BusinessTypeEnum.ADD)
@AccessLog(title = "业务名称", businessType = BusinessTypeEnum.MODIFY)
@AccessLog(title = "业务名称", businessType = BusinessTypeEnum.DELETE)
@AccessLog(title = "业务名称", businessType = BusinessTypeEnum.EXPORT)
业务错误使用 ApiException 和 ErrorCode.Business。新增业务错误时,按现有错误码结构补充枚举或常量,不要在 Controller 中拼接错误响应。
验收清单
- 新代码目录结构与相似模块一致。
- Controller 只有 HTTP 编排逻辑。
- 业务校验位于 Model 或 ApplicationService,不散落在前端或 Controller。
- 查询返回 DTO,分页返回
PageDTO<T>。 - 写请求使用 Command。
- 复杂查询结果对象使用 DO,并在 ApplicationService 转换为 DTO。
- 权限、日志、异常、测试和现有项目风格一致。