Files
weixin_uniapp_1818AIGC/docs/CODE_STANDARDS.md
2026-02-13 17:15:00 +08:00

428 lines
9.9 KiB
Markdown
Raw 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.

# 代码开发规范
## 一、项目结构规范
```
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): 更新部署文档
```