WholeProcessPlatform/backend/docs/业务模块开发技术规范.md
2026-05-21 11:35:09 +08:00

17 KiB
Raw Blame History

WholeProcessPlatform Backend 业务模块开发技术规范

1. 文档目的

本文档用于统一 d:\shuili\WholeProcessPlatform\backend 项目中业务模块的开发方式,重点覆盖:

  • 模块目录与分层设计规范
  • Controller、Service、Mapper、VO、Domain 的职责边界
  • 基于 Spring Boot 4.0.3 + Java 21 + MyBatis/MyBatis-Plus 的编码约束
  • 当前项目已形成的事实标准
  • 新增业务模块、旧系统迁移模块、字典/基础数据模块的推荐实现方式
  • SQL、异常、接口返回、分页、文档、测试、性能与安全要求

本文档适用于本项目所有新增或改造的业务模块,尤其适用于 env 目录下的生态环境类业务。

2. 技术基线

根据项目当前 pom.xml,本项目业务开发技术基线如下:

  • JDK21
  • Spring Boot4.0.3
  • Spring WebMVC
  • Spring Security已引入
  • Springdoc OpenAPI3.0.2
  • MyBatis3.5.16
  • MyBatis Spring Boot Starter4.0.1
  • MyBatis-Plus3.5.16,使用 mybatis-plus-spring-boot4-starter
  • 数据库驱动MySQL、Oracle、达梦
  • 工具库Hutool、Lombok、Guava、POI

3. 外部参考原则

本文档参考了当前主流的 Spring Boot 4 / 现代 Spring 开发建议,并结合项目现状做了落地约束,核心依据如下:

  • Spring Boot 官方文档强调代码结构、配置类组织、依赖注入、外部化配置、日志、Web、Data、Validation、Actuator 等能力应作为应用开发基础。
  • Springdoc 官方文档建议使用 springdoc-openapi-starter-webmvc-ui 作为 OpenAPI/Swagger UI 集成方式,并通过注解与配置文件维持接口文档。
  • MyBatis Spring Boot Starter 官方文档强调在 Boot 4 体系中使用官方 starter、自动扫描 Mapper、使用配置项统一管理 MyBatis 行为。
  • MyBatis-Plus 官方文档明确支持 Spring Boot 4推荐使用 Boot 4 对应 starter并采用 BaseMapperServiceImpl、分页对象等标准方式实现常规 CRUD。

说明:

  • 本规范不是照搬互联网通用模板,而是“以本项目实际代码为准,吸收外部最佳实践后形成的可执行规范”。
  • 若通用建议与现有项目框架存在冲突,优先保证现有项目兼容性,再逐步演进。

4. 当前项目模块结构总结

env 模块已经形成两类主流实现风格。

4.1 基础资料型模块

典型文件:

  • controller/SdCountryBController.java
  • service/ISdCountryBService.java
  • service/impl/SdCountryBServiceImpl.java
  • mapper/SdCountryBMapper.java
  • domain/SdCountryB.java

特征:

  • 面向单表或轻量多表的增删改查
  • Service 通常继承 ServiceImpl<Mapper, Domain>
  • 使用 BaseMapper 和 MyBatis-Plus lambdaQuery()
  • Controller 以分页查询、列表查询、详情查询为主

适用场景:

  • 字典表
  • 基础资料表
  • 标准后台管理页面

4.2 业务查询/迁移型模块

典型文件:

  • controller/SdWTMonitorController.java
  • service/SdWtMonitorService.java
  • service/impl/SdWtMonitorServiceImpl.java
  • service/AlongListService.java
  • service/impl/AlongListServiceImpl.java
  • mapper/AlongDetailMapper.java
  • mapper/SdWtMonitorMapper.java
  • entity/vo/*

特征:

  • 来自旧系统迁移的复杂业务查询较多
  • Controller 聚合多个业务接口
  • Service 接口与实现手写,通常不继承 ServiceImpl
  • 同时存在注解 SQL、动态 SQL、MyBatis-Plus 分页
  • 使用 DataSourceRequestDataSourceResult 适配旧平台 Kendo/DevExtreme 风格

适用场景:

  • 旧系统模块迁移
  • 复杂统计、图表、对比分析、联表明细
  • 需要兼容旧平台入参与返回结构的接口

5. 模块分层规范

5.1 Controller 层职责

Controller 仅负责:

  • 暴露路由
  • 参数接收
  • 基础空值校验
  • 调用 Service
  • 统一包装 ResponseResult

Controller 禁止:

  • 拼接 SQL
  • 大段业务判断
  • 循环组装复杂结果
  • 直接操作 Mapper

当前项目推荐写法:

  • 类上使用 @RestController
  • 类上使用 @RequestMapping
  • 类上使用 @Tag
  • 方法上使用 @Operation
  • 返回值统一为 ResponseResult

示例风格:

  • 业务聚合 ControllerSdWTMonitorController
  • 管理型 ControllerSdCountryBController

5.2 Service 层职责

Service 层负责:

  • 业务编排
  • 参数解析
  • 分页对象生成
  • 调用 Mapper
  • Java 层补充计算
  • 返回对象组装

Service 层应根据模块类型选择实现方式:

  • 基础 CRUD优先 IxxxService + ServiceImpl
  • 复杂业务查询:优先 XxxService + XxxServiceImpl
  • 旧系统迁移模块:优先显式定义业务接口,避免泛化成通用 CRUD Service

5.3 Mapper 层职责

Mapper 层负责:

  • 数据查询与数据写入
  • 注解 SQL 或 XML SQL
  • 复杂 join、exists、聚合、分页 SQL

Mapper 层禁止:

  • 放业务语义不清的万能 SQL
  • 将参数语义不明确地混在同一个方法中
  • 为了省事直接将前端字段名等同于数据库字段名而不做映射说明

5.4 VO / DTO / Domain 职责

当前项目已存在三类对象:

  • domain:数据库实体,主要服务于 MyBatis-Plus CRUD
  • entity/vo:前端返回对象、业务查询对象
  • common:分页、过滤、排序、结果包装对象

规范要求:

  • 单表管理页优先使用 domain
  • 复杂查询、聚合结果、旧接口兼容结构必须使用独立 VO
  • 不允许复用 domain 直接承接复杂联表查询结果
  • 前端字段名与数据库字段名不一致时SQL 必须用旧字段名作为别名返回

6. 推荐目录规范

新增业务模块建议按如下目录落位:

src/main/java/com/yfd/platform/<module>/
  controller/
  service/
  service/impl/
  mapper/
  domain/
  entity/vo/

命名建议:

  • ControllerXxxController
  • ServiceXxxService
  • ServiceImplXxxServiceImpl
  • MapperXxxMapper
  • 管理类 ServiceIXxxService
  • 管理类 ServiceImplXxxServiceImpl extends ServiceImpl
  • Domain与表/业务实体对应
  • VO以业务含义命名SdYearListVOWtFishVo

7. 接口设计规范

7.1 返回结构规范

本项目统一返回对象为 ResponseResult,必须使用:

  • ResponseResult.success()
  • ResponseResult.successData(data)
  • ResponseResult.error(msg)

禁止:

  • Controller 直接返回裸对象
  • 不同模块返回结构不一致
  • 同类接口同时混用 Map、实体、裸数组作为顶层响应

7.2 异常规范

业务异常统一使用 BizException

适用场景:

  • 必填参数缺失
  • 业务前置条件不满足
  • 站点、工程、字典等基础数据不存在
  • 旧接口兼容校验失败

推荐写法:

if (StrUtil.isBlank(stcd)) {
    throw new BizException("站点编码不能为空.");
}

禁止:

  • throw new RuntimeException(...)
  • Controller 静默吞异常
  • Service 返回 null 表示明确错误

7.3 参数接收规范

当前项目主要有两类接口:

  • Kendo/DevExtreme 风格:@RequestBody DataSourceRequest
  • 标准后台管理风格:@RequestParam + 分页参数

规范要求:

  • 旧平台迁移接口优先保留 DataSourceRequest
  • 后台管理接口优先使用显式参数
  • 不允许将大量业务字段塞入 Map<String, Object> 作为常规入参
  • Map<String, Object> 仅用于动态字段更新、非结构化补丁写入等少数场景

8. 分页与筛选规范

8.1 DataSourceRequest 适用范围

DataSourceRequest 是本项目重要的兼容层对象,适用于:

  • 迁移旧平台 Kendo Grid 接口
  • 需要复杂 filter/group/sort/select 的业务页面
  • 旧接口需要兼容前端请求结构时

规范要求:

  • 迁移旧接口时优先从 DataSourceRequest 中提取明确字段
  • 尽量封装公共提取逻辑,如使用 QgcQueryWrapperUtil.getFilterFieldValue(...)
  • 对必要参数要先做空值校验

8.2 DataSourceResult 规范

使用 DataSourceResult 时应设置:

  • data
  • total
  • aggregates

推荐:

  • 无聚合时设置空 HashMap<>
  • 无数据时返回空列表而不是 null

9. 依赖注入规范

现状:

  • 项目中大量使用 @Resource 字段注入

建议:

  • 存量代码允许继续使用 @Resource
  • 新增业务模块优先使用构造器注入
  • 若为了保持模块风格一致,可在同一文件中延续现有注入方式

统一要求:

  • 不允许通过 SpringContextHolder 主动取 Bean 代替正常依赖注入,除非是历史兼容场景且无法重构

10. SQL 与数据访问规范

10.1 选型原则

优先级如下:

  1. 单表 CRUD、简单条件分页MyBatis-Plus
  2. 明确的小型查询Mapper 注解 SQL
  3. 复杂迁移查询、动态列、旧 SQL 兼容:MicroservicDynamicSQLMapper
  4. 复杂 XML 已有现成资产且迁移成本高:可保留 XML

10.2 MyBatis-Plus 适用规范

适用于:

  • 基础字典
  • 台账管理
  • 后台标准分页列表

要求:

  • 使用 lambdaQuery()lambdaUpdate()
  • 条件判断写在链式条件中
  • 避免大量手写 SQL 替代简单 CRUD

10.3 动态 SQL 适用规范

当前项目已有 MicroservicDynamicSQLMapper,适用于:

  • 旧系统 SQL 平移
  • 表结构拆分后的复杂重写
  • 返回 VO 列较多且结构动态

使用规范:

  • 动态 SQL 必须先在 Service 中拼装完整语义,不允许把参数语义留给前端猜测
  • SQL 返回字段必须使用 VO 字段名别名
  • 参数统一通过 Map<String, Object> 绑定,禁止字符串直接拼接用户输入
  • 非必要不要在 Service 中写多个层层嵌套的查询,优先压缩为可维护的单条 SQL 或小规模明确查询

10.4 SQL 编写要求

必须遵循:

  • 过滤条件尽量前置
  • 明确 IS_DELETED = 0
  • 与旧系统兼容时保留 USFLMWAYDTIN_TYPESTTP 等业务条件
  • 联表字段语义必须先确认再关联
  • 能用 EXISTS 的场景优先评估是否优于无谓 join
  • 排序字段应稳定,避免前端列表顺序漂移

禁止:

  • 用错误语义字段强行 join
  • 在 SQL 中随意猜测旧字段映射
  • 使用无法参数化的用户输入拼接 SQL

10.5 旧系统迁移专项规则

迁移模块时必须先做三件事:

  1. 找到旧 Controller/Service/Mapper/XML 主入口
  2. 梳理旧表关系和字段语义
  3. 建立旧表到新表的映射说明

禁止:

  • 未分析旧 SQL 语义就直接按字段名猜测重写
  • 把旧“横表字段”误当成新“关系表字段”
  • 为了快速实现,破坏旧接口请求和返回结构

11. 业务模块编码规范

11.1 Controller 编码规范

  • 一个 Controller 只承载同一业务域或同一前端页面聚合能力
  • 聚合型 Controller 可以包含多个子接口,但应保持前缀一致
  • 方法名与 @Operation(summary = "...") 应表达真实业务语义
  • 空值校验放在 Controller 或 Service 入口,不能完全依赖底层报错

11.2 Service 编码规范

  • 一个方法只表达一个明确业务能力
  • 复杂逻辑可拆为少量私有方法,但不要抽象出与旧业务语义脱节的“工具方法泛滥”
  • 允许在 Service 层做二次排序、月份格式化、标志位组装、列头组装等 Java 后处理
  • 数据库语义判断优先放 SQL纯展示逻辑优先放 Java

11.3 VO 编码规范

  • VO 字段必须服务于前端返回,不要无意义堆字段
  • 对旧接口兼容字段要保持命名稳定
  • 使用 Lombok 时优先 @Data@Getter/@Setter
  • 对外 VO 建议加 @Schema 注释

11.4 Domain 编码规范

  • Domain 应与真实表结构对齐
  • 建议保持字段名、注释、表映射一致
  • 不要将 VO 字段、临时业务字段塞进 Domain

12. 文档与 OpenAPI 规范

项目当前已引入 springdoc-openapi-starter-webmvc-ui,因此新增接口必须同时维护接口文档。

要求:

  • Controller 类使用 @Tag
  • 方法使用 @Operation
  • 复杂 VO 使用 @Schema
  • 对外接口要有清晰的 summary

推荐:

  • 对关键参数补充 description
  • 对复杂返回结构单独定义 VO不返回匿名 Map
  • 将生产环境的 OpenAPI/Swagger UI 访问权限纳入安全控制

13. 配置管理规范

根据 Spring Boot 官方建议,配置应外部化管理。

项目要求:

  • 数据源、缓存、安全、文档开关、日志级别等必须放配置文件
  • 多环境配置使用 profile 管理
  • 不允许将数据库地址、账号、密码、第三方密钥硬编码进 Java 代码
  • 与数据库方言相关的行为尽量通过配置或基础层封装统一管理

14. 日志与可观测性规范

项目已引入 spring-boot-starter-actuator,因此新增模块应具备基本可观测性意识。

要求:

  • 业务异常使用统一异常体系,不在正常分支打 error 日志
  • 大查询、长耗时任务、批量处理建议记录 info/debug 级别日志
  • 不记录敏感字段原文
  • 生产问题定位优先结合 Actuator、日志、SQL 条件进行

建议:

  • 对复杂迁移接口记录关键参数与结果数量
  • 对导入、导出、批处理记录耗时

15. 安全规范

由于项目已引入 Spring Security新增模块应遵循最小暴露原则。

要求:

  • Swagger/OpenAPI 文档在生产环境应受控
  • 任何写接口必须考虑权限控制与审计要求
  • 参数校验必须前置,避免越权探测和异常信息泄露
  • 对动态 SQL 特别关注注入风险,所有用户输入都必须通过参数绑定

16. 测试规范

16.1 必测场景

新增业务模块至少要验证:

  • 正常查询
  • 必填参数缺失
  • 空数据返回
  • 关键筛选条件命中
  • 排序/分页正确

16.2 测试建议

  • 单表 CRUD 模块:优先补 Service/Mapper 单元或集成测试
  • 迁移型查询模块:至少保留典型请求体样例和 SQL 验证说明
  • 高风险接口:建议补接口级集成测试

16.3 不建议

  • 为了补测试而写无价值的样板测试
  • 完全重复实现逻辑本身的测试

17. 性能规范

17.1 查询性能

  • 优先明确主表与过滤条件
  • 少用无必要的多层嵌套子查询
  • 大表统计优先关注时间条件、站点条件、逻辑删除条件是否下推
  • ROWNUM = 1FETCH FIRST 1 ROWS ONLY 等默认值查询必须确保排序稳定

17.2 Java 21 使用建议

本项目使用 Java 21但业务模块默认仍以同步 MVC 为主。

建议:

  • 普通查询接口保持同步风格,避免过早引入响应式复杂度
  • CPU 密集或 I/O 密集的异步能力需经过明确评估后再引入
  • 语言特性应以可读性优先,避免为了“新语法”牺牲团队可维护性

18. 新增业务模块推荐模板

18.1 基础管理模块模板

  • domain/Xxx.java
  • mapper/XxxMapper.java
  • service/IXxxService.java
  • service/impl/XxxServiceImpl.java
  • controller/XxxController.java

适用:

  • 国家、流域、字典、基础表管理

18.2 复杂查询模块模板

  • entity/vo/XxxVO.java
  • mapper/XxxMapper.java
  • service/XxxService.java
  • service/impl/XxxServiceImpl.java
  • controller/XxxController.java

适用:

  • 旧平台迁移
  • 统计分析
  • 图表联查
  • 多表业务判断

19. 开发禁止项

以下行为在新增业务模块中原则上禁止:

  • Controller 直接操作 Mapper
  • 直接返回裸 Map 作为通用接口响应
  • 大量复制旧 SQL 但不校验字段语义
  • 将前端字段名直接拼成 SQL 片段
  • 业务异常使用 RuntimeException
  • 多个接口返回结构风格不统一
  • 在 Service 中堆积无法复用、语义不清的“万能工具方法”
  • 未确认表语义就擅自把旧表字段映射到新表字段
  • 对外接口无 @Operation 文档说明

20. 迁移模块专项检查清单

新增或改造迁移模块时,提交前必须自检:

  • 是否定位了旧入口 Controller/Service/Mapper/XML
  • 是否梳理了旧表职责与表关系
  • 是否建立了旧表到新表的映射说明
  • 是否保持了旧接口路径、入参名、返回字段的兼容性
  • 是否校验了关键 SQL 的过滤条件、排序条件和时间口径
  • 是否补充了空值、默认值、无数据场景处理
  • 是否检查了 IS_DELETEDUSFLMWAYDTIN_TYPE 等业务条件
  • 是否校验了 ResponseResultDataSourceResult、VO 返回结构
  • 是否完成最基本的诊断或测试验证

21. 推荐落地原则

本项目业务模块开发建议遵循以下顺序:

  1. 先确认业务语义与表关系
  2. 再确定模块属于 CRUD 型还是迁移查询型
  3. 再选择 MyBatis-Plus、注解 SQL 或动态 SQL
  4. 再定义 VO/Domain/Service/Controller 落位
  5. 最后补异常、文档、校验、测试与性能检查

一句话原则:

以项目现有架构为主线,以 Spring Boot 4.0 现代实践为约束以“业务语义正确、接口兼容、SQL 可维护、结构可复用”为最终标准。

22. 附录:外部参考资料