first commit
This commit is contained in:
427
docs/CODE_STANDARDS.md
Normal file
427
docs/CODE_STANDARDS.md
Normal file
@@ -0,0 +1,427 @@
|
||||
# 代码开发规范
|
||||
|
||||
## 一、项目结构规范
|
||||
|
||||
```
|
||||
src/main/java/com/dora/
|
||||
├── WeixinApplication.java # 启动类
|
||||
├── common/ # 公共模块
|
||||
│ ├── constant/ # 常量定义
|
||||
│ ├── enums/ # 枚举类
|
||||
│ ├── exception/ # 异常处理
|
||||
│ └── result/ # 统一响应
|
||||
├── config/ # 配置类
|
||||
├── controller/ # 控制器层(接收请求)
|
||||
├── service/ # 业务服务层
|
||||
│ └── impl/ # 服务实现
|
||||
├── mapper/ # 数据访问层
|
||||
├── entity/ # 数据库实体
|
||||
├── dto/ # 数据传输对象(入参)
|
||||
├── vo/ # 视图对象(出参)
|
||||
├── util/ # 工具类
|
||||
└── aspect/ # 切面
|
||||
```
|
||||
|
||||
## 二、命名规范
|
||||
|
||||
### 2.1 类命名
|
||||
| 类型 | 规范 | 示例 |
|
||||
|------|------|------|
|
||||
| Controller | XxxController | UserController |
|
||||
| Service接口 | XxxService | UserService |
|
||||
| Service实现 | XxxServiceImpl | UserServiceImpl |
|
||||
| Mapper | XxxMapper | UserMapper |
|
||||
| Entity | 与表名对应,驼峰 | User, AiWork |
|
||||
| DTO | XxxDTO / XxxRequest | UserLoginDTO |
|
||||
| VO | XxxVO | UserInfoVO |
|
||||
| 枚举 | XxxEnum | UserStatusEnum |
|
||||
| 常量 | XxxConstant | RedisConstant |
|
||||
| 工具类 | XxxUtil | DateUtil |
|
||||
| 配置类 | XxxConfig | RedisConfig |
|
||||
|
||||
### 2.2 方法命名
|
||||
| 操作 | 命名规范 | 示例 |
|
||||
|------|----------|------|
|
||||
| 查询单个 | getXxx / findXxx | getUserById |
|
||||
| 查询列表 | listXxx | listUserByStatus |
|
||||
| 分页查询 | pageXxx | pageUser |
|
||||
| 新增 | save / add / create | saveUser |
|
||||
| 修改 | update / modify | updateUser |
|
||||
| 删除 | delete / remove | deleteUser |
|
||||
| 统计 | countXxx | countUserByVip |
|
||||
| 判断 | isXxx / hasXxx | isVipUser |
|
||||
|
||||
### 2.3 变量命名
|
||||
- 使用小驼峰:`userId`, `orderNo`
|
||||
- 布尔类型:`isXxx`, `hasXxx`, `canXxx`
|
||||
- 集合类型:复数形式 `users`, `orderList`
|
||||
- 常量:全大写下划线分隔 `MAX_RETRY_COUNT`
|
||||
|
||||
## 三、Controller规范
|
||||
|
||||
```java
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/user")
|
||||
@RequiredArgsConstructor
|
||||
public class UserController {
|
||||
|
||||
private final UserService userService;
|
||||
|
||||
/**
|
||||
* 获取用户信息
|
||||
*
|
||||
* @param id 用户ID
|
||||
* @return 用户信息
|
||||
*/
|
||||
@GetMapping("/{id}")
|
||||
public Result<UserVO> getById(@PathVariable Long id) {
|
||||
return Result.success(userService.getById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询用户
|
||||
*/
|
||||
@GetMapping("/page")
|
||||
public Result<IPage<UserVO>> page(UserPageDTO dto) {
|
||||
return Result.success(userService.page(dto));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增用户
|
||||
*/
|
||||
@PostMapping
|
||||
public Result<Long> save(@RequestBody @Valid UserSaveDTO dto) {
|
||||
return Result.success(userService.save(dto));
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新用户
|
||||
*/
|
||||
@PutMapping("/{id}")
|
||||
public Result<Void> update(@PathVariable Long id, @RequestBody @Valid UserUpdateDTO dto) {
|
||||
userService.update(id, dto);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除用户
|
||||
*/
|
||||
@DeleteMapping("/{id}")
|
||||
public Result<Void> delete(@PathVariable Long id) {
|
||||
userService.delete(id);
|
||||
return Result.success();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Controller规则
|
||||
1. 使用 `@RequiredArgsConstructor` 构造器注入,禁止 `@Autowired`
|
||||
2. 方法必须有注释说明
|
||||
3. 入参使用 DTO,出参使用 VO
|
||||
4. 参数校验使用 `@Valid`
|
||||
5. 统一返回 `Result<T>`
|
||||
6. 不写业务逻辑,只做参数接收和结果返回
|
||||
|
||||
## 四、Service规范
|
||||
|
||||
```java
|
||||
public interface UserService {
|
||||
|
||||
UserVO getById(Long id);
|
||||
|
||||
IPage<UserVO> page(UserPageDTO dto);
|
||||
|
||||
Long save(UserSaveDTO dto);
|
||||
|
||||
void update(Long id, UserUpdateDTO dto);
|
||||
|
||||
void delete(Long id);
|
||||
}
|
||||
```
|
||||
|
||||
```java
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class UserServiceImpl implements UserService {
|
||||
|
||||
private final UserMapper userMapper;
|
||||
private final RedisUtil redisUtil;
|
||||
|
||||
@Override
|
||||
public UserVO getById(Long id) {
|
||||
User user = userMapper.selectById(id);
|
||||
if (user == null) {
|
||||
throw new BusinessException(ResultCode.USER_NOT_FOUND);
|
||||
}
|
||||
return convertToVO(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long save(UserSaveDTO dto) {
|
||||
// 1. 参数校验
|
||||
checkPhoneExists(dto.getPhone());
|
||||
|
||||
// 2. 构建实体
|
||||
User user = new User();
|
||||
BeanUtils.copyProperties(dto, user);
|
||||
|
||||
// 3. 保存数据
|
||||
userMapper.insert(user);
|
||||
|
||||
// 4. 返回结果
|
||||
return user.getId();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Service规则
|
||||
1. 接口与实现分离
|
||||
2. 事务注解加在实现类方法上:`@Transactional(rollbackFor = Exception.class)`
|
||||
3. 复杂业务逻辑拆分为私有方法
|
||||
4. 异常使用 `BusinessException` 抛出
|
||||
5. 日志记录关键操作
|
||||
|
||||
## 五、Entity规范
|
||||
|
||||
```java
|
||||
@Data
|
||||
@TableName("user")
|
||||
public class User {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private String openid;
|
||||
|
||||
private String nickname;
|
||||
|
||||
private String phone;
|
||||
|
||||
private Integer vipLevel;
|
||||
|
||||
private LocalDateTime vipExpireTime;
|
||||
|
||||
private Integer points;
|
||||
|
||||
private Integer status;
|
||||
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private LocalDateTime updatedAt;
|
||||
|
||||
@TableLogic
|
||||
private Integer deleted;
|
||||
}
|
||||
```
|
||||
|
||||
### Entity规则
|
||||
1. 使用 `@Data` 简化代码
|
||||
2. 字段类型与数据库对应
|
||||
3. 时间类型使用 `LocalDateTime`
|
||||
4. 逻辑删除字段使用 `@TableLogic`
|
||||
5. 禁止在Entity中写业务方法
|
||||
|
||||
## 六、DTO/VO规范
|
||||
|
||||
```java
|
||||
// 入参DTO
|
||||
@Data
|
||||
public class UserSaveDTO {
|
||||
|
||||
@NotBlank(message = "手机号不能为空")
|
||||
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
|
||||
private String phone;
|
||||
|
||||
@NotBlank(message = "昵称不能为空")
|
||||
@Size(max = 64, message = "昵称最长64个字符")
|
||||
private String nickname;
|
||||
}
|
||||
|
||||
// 出参VO
|
||||
@Data
|
||||
public class UserVO {
|
||||
|
||||
private Long id;
|
||||
|
||||
private String nickname;
|
||||
|
||||
private String avatar;
|
||||
|
||||
private Integer vipLevel;
|
||||
|
||||
private String vipLevelName;
|
||||
|
||||
private Integer points;
|
||||
|
||||
private LocalDateTime createdAt;
|
||||
}
|
||||
```
|
||||
|
||||
### DTO/VO规则
|
||||
1. DTO用于接收入参,必须加校验注解
|
||||
2. VO用于返回数据,可添加格式化字段
|
||||
3. 禁止直接返回Entity
|
||||
4. 敏感字段(密码、token)不放入VO
|
||||
|
||||
## 七、Mapper规范
|
||||
|
||||
```java
|
||||
@Mapper
|
||||
public interface UserMapper extends BaseMapper<User> {
|
||||
|
||||
/**
|
||||
* 根据手机号查询用户
|
||||
*/
|
||||
User selectByPhone(@Param("phone") String phone);
|
||||
|
||||
/**
|
||||
* 批量更新状态
|
||||
*/
|
||||
int batchUpdateStatus(@Param("ids") List<Long> ids, @Param("status") Integer status);
|
||||
}
|
||||
```
|
||||
|
||||
### Mapper规则
|
||||
1. 继承 `BaseMapper<T>` 使用通用方法
|
||||
2. 复杂SQL写在XML文件中
|
||||
3. 参数使用 `@Param` 注解
|
||||
4. 禁止在Mapper中写业务逻辑
|
||||
|
||||
## 八、异常处理规范
|
||||
|
||||
```java
|
||||
// 抛出业务异常
|
||||
throw new BusinessException(ResultCode.USER_NOT_FOUND);
|
||||
throw new BusinessException("自定义错误信息");
|
||||
throw new BusinessException(4001, "自定义错误码和信息");
|
||||
|
||||
// 参数校验
|
||||
if (user == null) {
|
||||
throw new BusinessException(ResultCode.USER_NOT_FOUND);
|
||||
}
|
||||
|
||||
// 使用断言(推荐)
|
||||
Assert.notNull(user, "用户不存在");
|
||||
```
|
||||
|
||||
## 九、日志规范
|
||||
|
||||
```java
|
||||
@Slf4j
|
||||
public class UserServiceImpl {
|
||||
|
||||
public void doSomething() {
|
||||
// DEBUG:调试信息
|
||||
log.debug("查询用户参数: {}", dto);
|
||||
|
||||
// INFO:关键业务操作
|
||||
log.info("用户注册成功, userId={}, phone={}", user.getId(), user.getPhone());
|
||||
|
||||
// WARN:警告信息
|
||||
log.warn("用户登录失败次数过多, userId={}", userId);
|
||||
|
||||
// ERROR:异常错误(带异常堆栈)
|
||||
log.error("调用第三方接口失败, url={}", url, e);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 日志规则
|
||||
1. 使用 `@Slf4j` 注解
|
||||
2. 使用占位符 `{}`,禁止字符串拼接
|
||||
3. ERROR日志必须带异常对象
|
||||
4. 敏感信息脱敏处理
|
||||
|
||||
## 十、数据库规范
|
||||
|
||||
### 10.1 连接池配置
|
||||
项目使用 HikariCP 连接池,已优化配置:
|
||||
- 最小空闲连接:10
|
||||
- 最大连接数:50
|
||||
- 空闲超时:10分钟
|
||||
- 连接最大存活:30分钟
|
||||
- 泄漏检测:60秒
|
||||
|
||||
### 10.2 SQL规范
|
||||
1. 禁止 `SELECT *`,明确指定字段
|
||||
2. 大表查询必须走索引
|
||||
3. 禁止在循环中执行SQL
|
||||
4. 批量操作使用 `saveBatch`
|
||||
5. 分页查询必须有排序字段
|
||||
|
||||
```java
|
||||
// 错误示例
|
||||
for (Long id : ids) {
|
||||
userMapper.selectById(id); // N+1问题
|
||||
}
|
||||
|
||||
// 正确示例
|
||||
List<User> users = userMapper.selectBatchIds(ids);
|
||||
```
|
||||
|
||||
### 10.3 事务规范
|
||||
```java
|
||||
// 只读事务
|
||||
@Transactional(readOnly = true)
|
||||
public UserVO getById(Long id) { }
|
||||
|
||||
// 写事务
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void save(UserDTO dto) { }
|
||||
```
|
||||
|
||||
## 十一、接口规范
|
||||
|
||||
### 11.1 RESTful规范
|
||||
| 操作 | 方法 | 路径 | 示例 |
|
||||
|------|------|------|------|
|
||||
| 查询 | GET | /资源 | GET /users |
|
||||
| 详情 | GET | /资源/{id} | GET /users/1 |
|
||||
| 新增 | POST | /资源 | POST /users |
|
||||
| 修改 | PUT | /资源/{id} | PUT /users/1 |
|
||||
| 删除 | DELETE | /资源/{id} | DELETE /users/1 |
|
||||
|
||||
### 11.2 响应格式
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "操作成功",
|
||||
"data": {},
|
||||
"timestamp": 1704067200000
|
||||
}
|
||||
```
|
||||
|
||||
## 十二、安全规范
|
||||
|
||||
1. 敏感配置使用环境变量或配置中心
|
||||
2. 密码使用 BCrypt 加密存储
|
||||
3. 接口做权限校验
|
||||
4. 防止SQL注入,使用参数化查询
|
||||
5. 防止XSS,对输出内容转义
|
||||
6. 日志脱敏处理敏感信息
|
||||
|
||||
## 十三、Git提交规范
|
||||
|
||||
```
|
||||
<type>(<scope>): <subject>
|
||||
|
||||
feat: 新功能
|
||||
fix: 修复bug
|
||||
docs: 文档更新
|
||||
style: 代码格式
|
||||
refactor: 重构
|
||||
test: 测试
|
||||
chore: 构建/工具
|
||||
```
|
||||
|
||||
示例:
|
||||
```
|
||||
feat(user): 添加用户注册功能
|
||||
fix(order): 修复订单金额计算错误
|
||||
docs(readme): 更新部署文档
|
||||
```
|
||||
Reference in New Issue
Block a user