Files
his/MD/specs/BACKEND_DEVELOPMENT_STANDARD.md
华佗 3578a24254 docs(specs): 汇总铁律和前后端开发规范文档到MD目录
- 新增 MD/specs/IRON_RULES.md — 执行铁律汇总(v2.0, 8条铁律)
- 新增 MD/specs/BACKEND_DEVELOPMENT_STANDARD.md — 后端开发规范
- 新增 MD/specs/FRONTEND_DEVELOPMENT_STANDARD.md — 前端开发规范
- 新增 healthlink-his-ui/AGENTS.md — 前端铁律引用
- 更新 healthlink-his-server/AGENTS.md — 同步规范文档引用
- 修复10个文档缺失的元数据(文档类型标签)
- 全部30个文档通过命名规范和元数据检查
2026-06-06 09:33:20 +08:00

10 KiB
Raw Blame History

HealthLink-HIS 后端开发规范

文档类型: 技术规范 适用范围: 后端 Java 开发 版本: v1.0 编制日期: 2026-06-06 最后更新: 2026-06-06


一、技术栈

组件 版本 说明
JDK 25 OpenJDK 25 (LTS)
Spring Boot 4.0.6 框架核心
MyBatis-Plus 3.5.16 ORM框架
PostgreSQL 15+ 主数据库
Redis 7.x 缓存/会话
Maven 3.9+ 构建工具

二、项目结构

healthlink-his-server/
├── healthlink-his-common/          # 公共模块(枚举、常量、工具类)
├── healthlink-his-domain/          # 领域层实体、Mapper、Flyway迁移
├── healthlink-his-application/     # 应用层Controller、Service、业务逻辑
├── core-common/                    # 若依公共核心
├── core-system/                    # 若依系统模块
├── core-framework/                 # 若依框架核心
├── core-quartz/                    # 定时任务
├── core-generator/                 # 代码生成
├── core-flowable/                  # 工作流
└── core-admin/                     # 管理后台

三、分层架构规范

3.1 Controller 层

  • 路径:com.healthlink.his.web.{module}.controller
  • 职责接收请求、参数校验、调用AppService、返回统一结果
  • 禁止:直接操作数据库、编写业务逻辑
@RestController
@RequestMapping("/api/v1/registration")
@Api(tags = "挂号管理")
public class RegistrationController {

    @Autowired
    private IRegistrationAppService registrationAppService;

    @GetMapping("/list")
    @PreAuthorize("@ss.hasPermi('registration:list')")
    public TableDataInfo list(RegistrationQueryDto query) {
        startPage();
        List<RegistrationDto> list = registrationAppService.selectList(query);
        return getDataTable(list);
    }
}

3.2 AppService 层(应用服务)

  • 路径:com.healthlink.his.web.{module}.appservice
  • 职责编排业务流程、协调多个Service、事务管理
  • 命名:XxxAppService(接口)+ XxxAppServiceImpl(实现)

3.3 Service 层

  • 路径:com.healthlink.his.web.{module}.service
  • 职责单表CRUD、基础业务逻辑
  • 命名:IXxxService(接口)+ XxxServiceImpl(实现)

3.4 Mapper 层

  • 路径:com.healthlink.his.web.{module}.mapper
  • 职责数据访问、SQL映射
  • 命名:XxxMapper(接口)+ XxxMapper.xmlXML映射

3.5 Entity/Domain 层

  • 路径:com.healthlink.his.domain.{module}
  • 职责:实体定义、数据库表映射
  • 命名:Xxx(实体类)

3.6 DTO 层

  • 路径:com.healthlink.his.web.{module}.dto
  • 职责:数据传输对象、查询参数、返回结果

四、命名规范

4.1 包命名

com.healthlink.his.web.{模块名}.{层级}

4.2 类命名

类型 命名规则 示例
Controller XxxController RegistrationController
AppService接口 IXxxAppService IRegistrationAppService
AppService实现 XxxAppServiceImpl RegistrationAppServiceImpl
Service接口 IXxxService IRegistrationService
Service实现 XxxServiceImpl RegistrationServiceImpl
Mapper XxxMapper RegistrationMapper
Entity Xxx Registration
DTO XxxDto / XxxQueryDto RegistrationDto
Enum XxxEnum / XxxType ItemType

4.3 方法命名

场景 命名规则 示例
查询列表 selectList / queryList selectList(query)
查询详情 selectById / getById selectById(id)
新增 insert / save / add insert(dto)
修改 update / modify update(dto)
删除 delete / remove deleteById(id)
批量操作 batchXxx batchInsert(list)

4.4 数据库命名

类型 命名规则 示例
表名 {模块}_{功能} 小写下划线 reg_registration
字段名 小写下划线 patient_id, create_time
主键 id{表名}_id registration_id
外键 {关联表}_id patient_id
时间字段 create_time, update_time
软删除 del_flag
租户 tenant_id

五、编码规范

5.1 Controller 规范

// ✅ 正确
@RestController
@RequestMapping("/api/v1/patient")
@Api(tags = "患者管理")
@Slf4j
public class PatientController {

    @Autowired
    private IPatientAppService patientAppService;

    @GetMapping("/{id}")
    @PreAuthorize("@ss.hasPermi('patient:query')")
    public AjaxResult getInfo(@PathVariable Long id) {
        return success(patientAppService.selectById(id));
    }

    @PostMapping
    @PreAuthorize("@ss.hasPermi('patient:add')")
    public AjaxResult add(@Validated @RequestBody PatientDto dto) {
        return toAjax(patientAppService.insert(dto));
    }
}

// ❌ 错误 - Controller里写业务逻辑
public AjaxResult add(@RequestBody PatientDto dto) {
    // 不应该在这里写验证逻辑
    if (dto.getName() == null) {
        return error("名称不能为空");
    }
    // 不应该在这里写数据库操作
    patientMapper.insert(patient);
    return success();
}

5.2 Service 规范

// ✅ 正确 - 事务注解
@Transactional(rollbackFor = Exception.class)
public int insert(PatientDto dto) {
    Patient patient = BeanUtils.copyProperties(dto, Patient.class);
    patient.setCreateTime(new Date());
    patient.setCreateBy(SecurityUtils.getUsername());
    return patientMapper.insert(patient);
}

// ❌ 错误 - 自调用导致事务失效
public void batchProcess(List<PatientDto> list) {
    for (PatientDto dto : list) {
        this.insert(dto);  // 自调用,事务不生效!
    }
}

5.3 Mapper 规范

// ✅ 正确 - 使用LambdaQueryWrapper
public List<Patient> selectList(PatientQueryDto query) {
    LambdaQueryWrapper<Patient> wrapper = new LambdaQueryWrapper<>();
    wrapper.like(StringUtils.isNotBlank(query.getName()), Patient::getName, query.getName())
           .eq(Patient::getDelFlag, "0")
           .orderByDesc(Patient::getCreateTime);
    return patientMapper.selectList(wrapper);
}

// ❌ 错误 - 字符串拼接SQL
public List<Patient> selectList(String name) {
    String sql = "SELECT * FROM patient WHERE name = '" + name + "'";
    return jdbcTemplate.queryForList(sql, Patient.class);
}

5.4 统一返回格式

// 成功
return AjaxResult.success(data);
return AjaxResult.success("操作成功", data);

// 失败
return AjaxResult.error("患者不存在");
return AjaxResult.error(MessageUtils.message("patient.not.found"));

// 列表
TableDataInfo dataPage = getDataTable(list);

六、异常处理规范

6.1 业务异常

throw new ServiceException("患者编号不能为空");
throw new ServiceException(MessageUtils.message("patient.id.required"));

6.2 全局异常处理

  • 使用 @RestControllerAdvice + @ExceptionHandler
  • 不在 Controller 中 try-catch 后返回错误
  • 所有异常最终返回统一格式 {code, msg, data}

6.3 日志规范

// ✅ 正确
log.info("患者挂号成功: patientId={}, registrationId={}", patientId, regId);
log.error("挂号失败: patientId={}", patientId, e);

// ❌ 错误
log.info("患者身份证号: " + idCard);  // 敏感信息泄露
System.out.println("debug");          // 不使用System.out

七、安全规范

7.1 数据脱敏

  • 患者身份证号:*** 掩码
  • 患者手机号前3后4中间 ****
  • 密码BCrypt 加密,不可逆

7.2 SQL注入防护

  • 所有查询使用参数化查询
  • 禁止字符串拼接 SQL
  • 使用 MyBatis-Plus 的 QueryWrapper / LambdaQueryWrapper

7.3 权限控制

  • 所有接口标注 @PreAuthorize
  • 数据级权限校验(医生只能访问本科室患者)
  • 敏感操作需二次确认

八、测试规范

8.1 测试类型

类型 工具 覆盖范围
单元测试 JUnit 5 + Mockito Service/工具类
接口测试 MockMvc + SpringBootTest Controller接口
白盒测试 Maven编译 全量代码
黑盒测试 手动/自动化 核心业务流程

8.2 接口测试规范

@SpringBootTest
@AutoConfigureMockMvc
public class PatientApiTest {

    @Test
    public void testGetPatientInfo() throws Exception {
        mockMvc.perform(get("/healthlink-his/api/v1/patient/{id}", 1L)
                .header("Authorization", "Bearer " + token))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.code").value(200))
            .andExpect(jsonPath("$.data").isNotEmpty())
            .andExpect(jsonPath("$.data.name").isNotEmpty());
    }
}

8.3 测试数据要求

  • 测试数据必须基于业务逻辑设计
  • 验证业务返回内容非仅HTTP状态码
  • 覆盖正常流程和异常流程
  • 包含边界条件测试

九、性能规范

9.1 数据库查询

  • 无N+1查询问题使用 JOIN 或批量查询)
  • 大表查询必须有分页限制
  • 慢查询已优化(执行时间 < 500ms
  • 索引已覆盖高频查询条件

9.2 接口性能

  • 核心接口响应时间 < 1秒
  • 列表接口支持分页,无全量返回
  • 大文件下载使用流式传输

9.3 缓存使用

  • 频繁查询的字典数据使用Redis缓存
  • 缓存必须设置过期时间
  • 数据变更时主动清除相关缓存

十、Git提交规范

Commit Message 格式

<type>(<scope>): <subject>

<body>

<footer>

Type 类型

Type 说明
feat 新功能
fix Bug修复
docs 文档变更
style 代码格式(不影响功能)
refactor 重构
test 测试相关
chore 构建/工具变更

示例

feat(registration): 新增患者过敏史管理功能

- 新增 PatientAllergy 实体和 Mapper
- 新增 IRegistrationAppService.getPatientAllergy()
- 新增 /api/v1/registration/allergy 接口
- Flyway迁移脚本: V2.0.1__add_patient_allergy.sql

Co-authored-by: zhangsan <zhangsan@healthlink.com>

文档版本: v1.0 最后更新: 2026-06-06