Files
huachuang/.claude/skills/nl-java-style/references/rules.md

102 lines
7.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# NL Java 编码规范
## 必须遵守
- 回复、代码注释、日志统一使用中文。
- 使用 Java 17、UTF-8、4 空格缩进。
- 提交前使用 IDE 格式化代码,并确保 `mvn clean install` 通过。
- 接口返回值使用 `ResultPo`
- 分页接口返回值使用 `Result<PageResult>`
- 分页查询的 service 入参使用 request 对象,不要用基本类型散传。
- 参数校验使用注解,例如 `@NotNull`,不要在业务代码里重复判空兜底。
- 方法里面如果有校验逻辑,先校验,再做业务。
- 注入统一使用 `@Resource`,不要使用构造器注入。
- 默认按 `id` 倒序,除非需求明确指定其他排序。
- 每个接口方法和每个 `private` 方法上方都写中文注释,说明作用。
- 类里的字段、方法上方要加中文注释。
- 代码里的日志统一使用中文。
- 调用其他服务后必须判断 `isSuccess`,失败时抛出业务异常。
- 文字类提醒异常统一使用 `ServiceException`
- 跨模块共享的数据结构放在 `product-api`,不要泄露 `product-server` 内部类型。
- `Provider``Api` 这类对外暴露接口,参数对象命名为 `XXXReq`,返回对象命名为 `XXXResp`
- 新增和编辑如果是两个接口,请求参数定义为两个对象,可以让 `UpdateXXXReq` 继承 `InsertXXXReq`
- 枚举如果没有特殊要求,默认只有一个字段 `code`,查询方法叫 `getByCode``code` 类型根据数据库字段决定,可以是 `String``Integer`
- 类上非必要注解不要写,比如 `@EqualsAndHashCode``@ToString`;可以使用 `@Data` 和 Apifox 相关注解。
- Apifox 接口上的 `example` 不要写。
- `Collectors.toMap` 时,如果 key 是 `id`value 使用 `Function.identity()`
- 如果数据库查询出来的字段是 `Boolean`,并且数据库保证不为空,直接使用 `if (shop.getIsEnable())`,不要写 `!Boolean.TRUE.equals(shop.getIsEnable())`
- 如果是api层的接口就别用swagger注解了用java自带的注解就可以了
- 判断集合是否为空用CollectionUtils,ObjectUtils.isEmpty()这种工具类,别用集合对象.isEmpty()
- java枚举如果code跟名称一样就别单独写code了
- set的时候用reqDTO.getPrepareHouseType() != null ? reqDTO.getPrepareHouseType().getCode(): null
- 如果需要用productcompareMapper.updateById更新数据库的话那么这个参数需要自己new出来别用数据库查询出来的数据
- 调用第三方接口的时候,如果异常了需要打印请求参数,跟返回值,格式类似 log.error("取消出库失败dtos={}, wms返回信息={}", JSON.toJSONString(dtos), JSON.toJSONString(stringResultVo));
- 尽量不要为了简单工具方法抽工具类对象超过3个或者复杂的工具类才需要抽出对象
- 如果是业务方法,尽量一个接口一个对象,如果有多层对象,尽量用内部类
- service方法注解一定需要的需要把方法的核心简单用简短干练的注释说明
- java中controller层或者feign层的方法名称是驼峰那么请求url也驼峰把跟方法保持一致
- 尽量不要try catch如果是需要异常以后继续运行的才进行try catch
- 如果是接口幂等的逻辑,不要返回正常结果,而是抛出业务异常
- 尽量不要抽方法行数在5行一下的方法
- 业务配置放在nacos里面取值用@Value("${alibaba1688.access_token}"), 尽量不用兜底如果没有就报错系统配置放在application里面
- bean对象的转换用mapStruct模仿MemberConfigConvert
- 如果在类里面定义常量那么常量的key跟value尽量保持一致如果是格式不一样值至少是一样的
- 如果是系统内部的类mapper跟mapper对象的dto先不分包manager层外部的也先不分包都放一个包里面。
- 生成的mapper跟表的结构保持一致比如order_item, OrderItemMapper.xml
- 生成单元测试用Spring那一套@SpringBootTest, 可以模仿ProductCompareServiceLocalSpringTest
- 发钉钉通知的话标题里面要带通知或者告警
- 允许简单 SQL 使用 MyBatis-Plus 自带查询方法,例如 `.selectOne`
## 代码结构规范
controller、service、enum、按照业务分包、manager外部调用包装暂时不分包
如果是方法的参数就放在当前包里面的vo、bo、dto包里面
## 数据库规范
- 不要使用 MyBatis-Plus 自带查询方法,例如 `.selectOne`
- 只要有查询逻辑,都写到 xxxMapper.xml 里。
- 不要使用 `@Select` 这类注解 SQL。
- SQL 统一写在 MyBatis XML 文件里。
- 查询条件直接使用 `is_deleted = 0`,不要额外写默认值兜底。
- 根据 `id` 删除时mapper 方法命名就叫 `deleteById`,不要加 `soft` 一类前缀。
- 操作数据库时,不需要手动指定更新时间,数据库有默认值。
- 数据库默认不为空的字段,从数据库拿到后不要再做兜底逻辑。
- 数据库有默认值的字段,查询出来后不要再判断 `null`,除非是审批时间这类本身允许为空的业务字段。
- 生成 DDL 时,不要追加 `DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci`
- 唯一索引只有在明确需要唯一约束时才添加。
- 默认不要使用联合索引,除非需求明确说明。
- 如果是根据XXXid查询的如果是主键或者唯一索引的话返回一个对象是关联的id那么返回List别用limit1兜底
- 数据库字段命名是下划线的
- 建表的时候要贴合业务,别取短而抽象的表明,要取能说明业务的表明,见名知意比名字短更重要
- 联动信息不存快照比如更新人名称只存关联的id
## 测试规范
- 如果没有明确要求生成单元测试,就不要生成测试。
- 如果要求生成测试,只生成 Spring 风格集成测试,不生成 mock 测试。
- 测试默认按本地 Spring 集成测试格式编写:使用 `@SpringBootTest``@ActiveProfiles("local")`
- 测试类命名可参考 `*LocalSpringTest`
- 通过 `@Resource` 注入待测 Bean。
- 测试方法至少包含一个有效断言,例如 `Assertions.assertNotNull(...)`
- 严禁生成 Mockito 风格测试骨架,例如 `@Mock``@InjectMocks``Mockito.when``Mockito.verify`
## 禁止事项
- 禁止使用 `BeanUtils.copyProperties`,改为逐字段赋值,或者直接让 mapper 返回目标对象。
- 禁止无意义的 `trim/null` 兜底。
- 禁止写 `normalizeXxx``distinctNonNull``getXxxOrThrow` 这类辅助方法。
- 禁止类似 `normalizeSourceType` 这种兜底方法;接口层会通过注解限制,如果注解解决不了,就在业务方法里直接校验。
- 禁止为数据库默认值手动补空值、补更新时间、补 `is_deleted`
- 禁止一行代码也抽方法的过度封装。
- 禁止过度封装“查不到就抛错”的一层薄方法。
- 禁止无需求说明时省略默认排序。
- 禁止在 service 分页查询接口中散传基本类型参数。
- 禁止写列表转分页时的 `instanceof Page<?>` 兼容分支。
- 禁止使用 `@Select` 注解写 SQL。
- 禁止在业务代码里重复写接口参数判空兜底。
- 禁止为了一个方法去创建对象承载多个参数;如果某个地方需要返回多个参数,直接在核心业务逻辑里处理即可。
- 禁止 java8 使用 orElse
- 禁止直接用从数据库查询出来的对象去更新数据类似productcompareMapper.updateById(existed);
- 禁止使用trim()这个方法做一些字符串的兜底