.rules.mdc
4.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
---
alwaysApply: false
---
# 项目代码规范
## 项目结构
```
src/main/java/com/infoloop/tianting/
├── controller/ # REST API 控制器
├── service/ # 业务逻辑接口
│ ├── impl/ # 业务逻辑实现
│ └── client/ # gRPC/HTTP 客户端封装
├── model/ # 数据模型
│ ├── dto/ # 数据传输对象
│ ├── vo/ # 视图对象
│ ├── bo/ # 业务对象
│ └── common/ # 通用模型
├── config/ # 配置类
├── constant/ # 常量定义
├── enums/ # 枚举类
├── exception/ # 异常定义
├── logic/ # 业务逻辑(定时任务、延迟任务等)
├── utils/ # 工具类
└── store/ # Redis 存储封装
```
## 代码风格
### 类注解顺序
```java
@Slf4j
@Service // 或 @Component, @RestController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class XxxServiceImpl implements XxxService {
```
### Controller 规范
- 使用 `@Api(tags = "模块名")` 标注 Swagger 分组
- 使用 `@ApiOperation(value = "接口描述")` 标注接口
- 使用 `@ResponseStatus` 指定 HTTP 状态码
- 使用 `@Valid` 进行参数校验
### Service 规范
- 接口定义在 `service/` 目录
- 实现类在 `service/impl/` 目录,命名为 `XxxServiceImpl`
- gRPC 客户端封装在 `service/client/` 目录,命名为 `XxxServiceRpcClient`
### 配置常量
- 配置项定义在 `ConfigConstants` 接口中
- 使用 `@Value(ConfigConstants.XXX)` 注入配置
### 依赖注入
- 优先使用构造器注入:`@RequiredArgsConstructor(onConstructor = @__(@Autowired))`
- 配置值使用 `@Value` 注入
### 日志规范
- 使用 `@Slf4j` 注解
- 使用 `log.info/warn/error` 记录日志
- 异常日志使用 `log.error("message", e)`
### gRPC 调用
- 通过 `XxxServiceRpcClient` 封装 gRPC 调用
- 在 `GrpcConfig` 中配置 Channel 和 Stub
### 定时任务
- 放在 `logic/task/` 目录
- 使用 `@Scheduled(cron = "...")` 注解
- 使用 `@Component` 注册为 Bean
## 命名规范
- DTO 类:`XxxDTO` 或内部类 `XxxDTO.CreateXxxDTO`
- VO 类:`XxxVO`
- 枚举类:`XxxEnum`
- 常量类:`XxxConstants`
- 工具类:`XxxUtil`
## 禁止事项
### 禁止循环依赖
- **Service 之间禁止循环调用**:ServiceA 调用 ServiceB,ServiceB 不能再调用 ServiceA
- **避免循环依赖注入**:如果出现循环依赖,需要重构代码,提取公共逻辑到新的 Service
- **分层调用原则**:Controller → Service → RpcClient/Store,禁止反向调用
### 禁止循环调用 gRPC 方法
- **禁止在循环中调用 gRPC 方法**:会导致大量网络请求,严重影响性能
- **必须使用批量接口**:如果需要处理多条数据,必须使用批量查询/批量创建接口
- **先收集 ID 再批量查询**:先收集所有需要查询的 ID,一次性批量查询
```java
// ❌ 错误示例:循环调用 gRPC
for (Long id : ids) {
var result = rpcClient.getById(id); // 禁止!
results.add(result);
}
// ✅ 正确示例:批量调用
var results = rpcClient.getByIds(ids); // 一次批量查询
```
### 批量接口设计规范
- **Proto 定义批量方法**:`GetXxxsByIds`、`BatchCreateXxx`、`BatchUpdateXxx`
- **RpcClient 封装批量方法**:提供 `getByIds(List<Long> ids)` 等批量方法
- **空集合检查**:批量方法调用前检查集合是否为空,避免无效请求
### 参数类型规范
- **禁止使用 Object 作为参数类型**:必须明确定义具体类型
- **禁止使用 Map<String, Object>**:应定义具体的 DTO 类
- **集合类型必须指定泛型**:使用 `List<XxxDTO>` 而非 `List`
- **方法参数类型要明确**:避免使用 `var` 定义方法参数
- **返回值类型要明确**:禁止返回 `Object`,必须定义具体类型
### 示例
```java
// ❌ 错误示例
public Object process(Map<String, Object> params) { ... }
// ✅ 正确示例
public OrderVO process(CreateOrderDTO params) { ... }
```