ai-engineering-init 1.13.0 → 1.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/hooks/stop.js +1 -2
- package/.claude/skills/analyze-requirements/SKILL.md +5 -38
- package/.claude/skills/auto-test/SKILL.md +182 -10
- package/.claude/skills/code-patterns/SKILL.md +119 -0
- package/.claude/skills/codex-code-review/SKILL.md +39 -0
- package/.claude/skills/collaborating-with-codex/SKILL.md +119 -96
- package/.claude/skills/leniu-code-patterns/SKILL.md +179 -2
- package/.codex/skills/analyze-requirements/SKILL.md +5 -38
- package/.codex/skills/code-patterns/SKILL.md +119 -0
- package/.codex/skills/collaborating-with-codex/SKILL.md +119 -96
- package/.codex/skills/leniu-code-patterns/SKILL.md +179 -2
- package/.cursor/skills/analyze-requirements/SKILL.md +5 -38
- package/.cursor/skills/code-patterns/SKILL.md +119 -0
- package/.cursor/skills/collaborating-with-codex/SKILL.md +119 -96
- package/.cursor/skills/leniu-code-patterns/SKILL.md +179 -2
- package/bin/index.js +144 -51
- package/package.json +1 -1
- package/src/skills/collaborating-with-codex/SKILL.md +119 -96
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: collaborating-with-codex
|
|
3
3
|
description: |
|
|
4
|
-
与
|
|
5
|
-
|
|
4
|
+
与 Codex MCP 协同开发。通过 GuDaStudio/codexmcp 集成,使用 mcp__codex__codex 工具。
|
|
5
|
+
默认沙箱:read-only(严禁 codex 修改真实代码)。
|
|
6
6
|
|
|
7
7
|
触发场景:
|
|
8
8
|
- 需要算法实现或复杂逻辑分析
|
|
@@ -14,110 +14,128 @@ description: |
|
|
|
14
14
|
触发词:Codex、协作、多模型、原型、Diff、算法分析、代码审查、codex协同
|
|
15
15
|
|
|
16
16
|
前置要求:
|
|
17
|
-
-
|
|
18
|
-
-
|
|
17
|
+
- 已通过 `claude mcp add codex -s user --transport stdio -- uvx --from git+https://github.com/GuDaStudio/codexmcp.git codexmcp` 注册
|
|
18
|
+
- ~/.claude/settings.json 的 permissions.allow 已加入 mcp__codex__codex
|
|
19
19
|
---
|
|
20
20
|
|
|
21
|
-
# 与 Codex
|
|
21
|
+
# 与 Codex MCP 协同开发
|
|
22
22
|
|
|
23
|
-
>
|
|
23
|
+
> 通过 `mcp__codex__codex` 工具直接调用,无需命令行。始终使用 `read-only` 沙箱,要求 codex 只输出 unified diff patch。
|
|
24
24
|
|
|
25
25
|
---
|
|
26
26
|
|
|
27
|
-
##
|
|
27
|
+
## MCP 工具说明
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
### 工具名
|
|
30
|
+
`mcp__codex__codex`
|
|
30
31
|
|
|
31
|
-
###
|
|
32
|
+
### 参数
|
|
32
33
|
|
|
33
|
-
|
|
|
34
|
-
|
|
35
|
-
| `
|
|
36
|
-
| `
|
|
37
|
-
| `
|
|
38
|
-
| `
|
|
39
|
-
|
|
40
|
-
|
|
34
|
+
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|
|
35
|
+
|------|------|------|--------|------|
|
|
36
|
+
| `PROMPT` | string | ✅ | - | 发送给 Codex 的任务指令(建议用英语) |
|
|
37
|
+
| `cd` | Path | ✅ | - | 工作目录根路径(必须存在) |
|
|
38
|
+
| `sandbox` | string | ❌ | `read-only` | `read-only` / `workspace-write` / `danger-full-access` |
|
|
39
|
+
| `SESSION_ID` | UUID | ❌ | None | 继续之前的会话,保持上下文 |
|
|
40
|
+
| `return_all_messages` | bool | ❌ | False | 是否返回推理过程和工具调用详情 |
|
|
41
|
+
| `model` | string | ❌ | None | 指定模型(None 使用用户默认配置) |
|
|
42
|
+
| `image` | List[Path] | ❌ | None | 附加图片文件 |
|
|
43
|
+
| `yolo` | bool | ❌ | False | 跳过沙箱审批(危险,不推荐) |
|
|
44
|
+
| `profile` | string | ❌ | None | 从 `~/.codex/config.toml` 加载的配置名 |
|
|
45
|
+
| `skip_git_repo_check` | bool | ❌ | False | 允许在非 Git 仓库中运行 |
|
|
46
|
+
|
|
47
|
+
### 返回值
|
|
48
|
+
|
|
49
|
+
```json
|
|
50
|
+
// 成功
|
|
51
|
+
{
|
|
52
|
+
"success": true,
|
|
53
|
+
"SESSION_ID": "uuid-string", // 必须保存,用于多轮交互
|
|
54
|
+
"agent_messages": "codex回复内容"
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// 失败
|
|
58
|
+
{
|
|
59
|
+
"success": false,
|
|
60
|
+
"error": "错误信息"
|
|
61
|
+
}
|
|
62
|
+
```
|
|
41
63
|
|
|
42
|
-
|
|
43
|
-
- "用 codex 工具分析 OrderInfoService 的业务逻辑"
|
|
44
|
-
- "用 codex review 检查当前未提交的代码变更"
|
|
45
|
-
- "用 codex 生成这个方法的单元测试,模型用 gpt-5.3-codex"
|
|
64
|
+
---
|
|
46
65
|
|
|
47
|
-
|
|
66
|
+
## 标准协作流程
|
|
48
67
|
|
|
49
|
-
|
|
68
|
+
```
|
|
69
|
+
1. 需求分析阶段
|
|
70
|
+
Claude 形成初步分析 → 告知 codex → codex 完善方案
|
|
50
71
|
|
|
51
|
-
|
|
72
|
+
2. 编码前(原型阶段)
|
|
73
|
+
调用 codex(read-only)→ 要求输出 unified diff patch
|
|
74
|
+
Claude 以 diff 为逻辑参考 → 重写为生产级代码
|
|
52
75
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
~/.codex/config.toml → profiles(review/analyze/prototype)
|
|
76
|
+
3. 编码后(审查阶段)
|
|
77
|
+
调用 codex review 改动 → 验证需求完成度和代码质量
|
|
56
78
|
```
|
|
57
79
|
|
|
58
80
|
---
|
|
59
81
|
|
|
60
|
-
##
|
|
82
|
+
## 调用示例
|
|
61
83
|
|
|
62
|
-
|
|
84
|
+
### 场景一:需求分析完善
|
|
63
85
|
|
|
64
|
-
|
|
86
|
+
```
|
|
87
|
+
PROMPT: "Here is my requirement: [需求描述]. My initial approach: [初步思路].
|
|
88
|
+
Please review and improve the analysis and implementation plan.
|
|
89
|
+
Output: structured analysis with potential risks."
|
|
65
90
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
--cd . --model gpt-5.3-codex --PROMPT "Your task"
|
|
91
|
+
cd: /path/to/project
|
|
92
|
+
sandbox: read-only
|
|
69
93
|
```
|
|
70
94
|
|
|
71
|
-
###
|
|
95
|
+
### 场景二:获取代码原型(Diff)
|
|
72
96
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
| `--SESSION_ID` | UUID | ❌ | `None` | 会话 ID(继续之前的对话) |
|
|
80
|
-
| `--profile` | str | ❌ | `None` | Codex profile(review/analyze/prototype) |
|
|
81
|
-
| `--return-all-messages` | bool | ❌ | `False` | 返回完整推理信息 |
|
|
82
|
-
| `--image` | List[Path] | ❌ | `None` | 附加图片 |
|
|
83
|
-
| `--yolo` | bool | ❌ | `False` | 跳过审批(危险) |
|
|
84
|
-
|
|
85
|
-
### 使用示例
|
|
97
|
+
```
|
|
98
|
+
PROMPT: "Generate a unified diff patch to implement [功能描述].
|
|
99
|
+
File: [目标文件路径]
|
|
100
|
+
Requirements:
|
|
101
|
+
- [要求1]
|
|
102
|
+
- [要求2]
|
|
86
103
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
# 代码审查
|
|
94
|
-
python .claude/skills/collaborating-with-codex/scripts/codex_bridge.py \
|
|
95
|
-
--cd . --model gpt-5.3-codex --profile review \
|
|
96
|
-
--PROMPT "Review OrderWebBusiness.java for bugs. OUTPUT: Review with line numbers."
|
|
97
|
-
|
|
98
|
-
# 生成 Diff 补丁
|
|
99
|
-
python .claude/skills/collaborating-with-codex/scripts/codex_bridge.py \
|
|
100
|
-
--cd . --model gpt-5.3-codex \
|
|
101
|
-
--PROMPT "Generate unified diff to add logging. OUTPUT: Unified Diff Patch ONLY."
|
|
102
|
-
|
|
103
|
-
# 多轮会话
|
|
104
|
-
python .claude/skills/collaborating-with-codex/scripts/codex_bridge.py \
|
|
105
|
-
--cd . --model gpt-5.3-codex \
|
|
106
|
-
--SESSION_ID "uuid-from-previous" \
|
|
107
|
-
--PROMPT "Now write unit tests for the method we discussed"
|
|
104
|
+
IMPORTANT: Output unified diff patch ONLY. Do NOT modify any real files.
|
|
105
|
+
IMPORTANT: All Java comments and SQL COMMENTs MUST be in Chinese."
|
|
106
|
+
|
|
107
|
+
cd: /path/to/project
|
|
108
|
+
sandbox: read-only
|
|
108
109
|
```
|
|
109
110
|
|
|
110
|
-
|
|
111
|
+
### 场景三:代码审查
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
PROMPT: "Review the following code changes for correctness, performance, and security.
|
|
115
|
+
[粘贴代码或说明文件路径]
|
|
116
|
+
|
|
117
|
+
Check:
|
|
118
|
+
1. Logic correctness
|
|
119
|
+
2. Edge cases
|
|
120
|
+
3. Performance issues
|
|
121
|
+
4. Security vulnerabilities
|
|
122
|
+
|
|
123
|
+
Output: review with line numbers and severity (CRITICAL/WARNING/INFO)."
|
|
124
|
+
|
|
125
|
+
cd: /path/to/project
|
|
126
|
+
sandbox: read-only
|
|
127
|
+
```
|
|
111
128
|
|
|
112
|
-
|
|
129
|
+
### 场景四:多轮交互(继续会话)
|
|
113
130
|
|
|
114
|
-
|
|
131
|
+
```
|
|
132
|
+
// 第一轮
|
|
133
|
+
SESSION_ID: None → 保存返回的 SESSION_ID
|
|
115
134
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
| `prototype` | gpt-5.3-codex | workspace-write | high | 原型生成 |
|
|
135
|
+
// 第二轮
|
|
136
|
+
SESSION_ID: "上一轮返回的 uuid"
|
|
137
|
+
PROMPT: "Now refine the diff based on the feedback: [反馈内容]"
|
|
138
|
+
```
|
|
121
139
|
|
|
122
140
|
---
|
|
123
141
|
|
|
@@ -125,24 +143,18 @@ python .claude/skills/collaborating-with-codex/scripts/codex_bridge.py \
|
|
|
125
143
|
|
|
126
144
|
| 角色 | Claude Code 负责 | Codex 负责 |
|
|
127
145
|
|------|-----------------|-----------|
|
|
128
|
-
| **架构** |
|
|
129
|
-
| **开发** |
|
|
130
|
-
| **审查** | 规范检查、最终判定 |
|
|
131
|
-
| **调试** |
|
|
146
|
+
| **架构** | 设计决策、规范审校 | 分析现有代码结构 |
|
|
147
|
+
| **开发** | 规范重写、最终代码实施 | 输出原型 diff(只读参考) |
|
|
148
|
+
| **审查** | 规范检查、最终判定 | 逐文件逻辑审查 |
|
|
149
|
+
| **调试** | 日志分析、问题定位 | 深度代码分析、补丁建议 |
|
|
132
150
|
|
|
133
151
|
### 重要约束
|
|
134
152
|
|
|
135
|
-
1.
|
|
136
|
-
2. **英语 Prompt
|
|
137
|
-
3.
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
- All SQL COMMENT values MUST be in Chinese
|
|
141
|
-
- All Java/code comments MUST be in Chinese
|
|
142
|
-
- Variable names and class names remain in English
|
|
143
|
-
```
|
|
144
|
-
4. **脏原型思维**: Codex 输出视为草稿,Claude 按项目规范重构
|
|
145
|
-
5. **后台运行**: 长时间任务用 subagent `run_in_background`
|
|
153
|
+
1. **只读优先**:始终使用 `sandbox="read-only"`
|
|
154
|
+
2. **英语 Prompt**:与 codex 交互用英语,代码注释要求中文
|
|
155
|
+
3. **脏原型思维**:codex 输出视为草稿,Claude 按项目规范重构
|
|
156
|
+
4. **保存 SESSION_ID**:每次调用后记录,多轮对话时传入
|
|
157
|
+
5. **质疑 codex**:codex 仅供参考,必须有独立判断
|
|
146
158
|
|
|
147
159
|
---
|
|
148
160
|
|
|
@@ -150,8 +162,19 @@ python .claude/skills/collaborating-with-codex/scripts/codex_bridge.py \
|
|
|
150
162
|
|
|
151
163
|
| 问题 | 解决方案 |
|
|
152
164
|
|------|---------|
|
|
153
|
-
|
|
|
154
|
-
| `
|
|
155
|
-
|
|
|
156
|
-
|
|
|
157
|
-
|
|
|
165
|
+
| 工具未出现 | 重启 Claude Code,检查 `~/.claude.json` 中 codex 配置 |
|
|
166
|
+
| `cd` 参数报错 | 确认目录存在,使用绝对路径 |
|
|
167
|
+
| 连接超时 | 检查网络,`uvx --from git+https://github.com/GuDaStudio/codexmcp.git codexmcp` 手动测试 |
|
|
168
|
+
| SESSION_ID 失效 | 重新开启新会话(不传 SESSION_ID) |
|
|
169
|
+
| codex 修改了文件 | 确认 `sandbox="read-only"` 已设置 |
|
|
170
|
+
|
|
171
|
+
## 安装验证
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
# 查看 MCP 配置
|
|
175
|
+
cat ~/.claude.json | python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('mcpServers', {}).get('codex', 'not found'))"
|
|
176
|
+
|
|
177
|
+
# 重启后运行
|
|
178
|
+
claude mcp list
|
|
179
|
+
# 期望看到: codex: uvx ... - ✓ Connected
|
|
180
|
+
```
|
|
@@ -394,9 +394,186 @@ public class OrderService {
|
|
|
394
394
|
}
|
|
395
395
|
```
|
|
396
396
|
|
|
397
|
-
##
|
|
397
|
+
## 数据类型规范
|
|
398
|
+
|
|
399
|
+
### 布尔字段命名
|
|
400
|
+
|
|
401
|
+
```java
|
|
402
|
+
// ❌ 错误:前缀冗余、类型错误
|
|
403
|
+
private Integer ifNarrow;
|
|
404
|
+
private Integer isEnabled;
|
|
405
|
+
|
|
406
|
+
// ✅ 正确:Boolean 类型,无前缀
|
|
407
|
+
private Boolean narrow; // getter → isNarrow()
|
|
408
|
+
private Boolean enabled; // getter → isEnabled()
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
### 枚举字段标注
|
|
412
|
+
|
|
413
|
+
```java
|
|
414
|
+
// ❌ 错误:只靠注释 @see
|
|
415
|
+
/** @see AccTradeTypeEnum */
|
|
416
|
+
private Integer tradeType;
|
|
417
|
+
|
|
418
|
+
// ✅ 方案一:VO/DTO 用枚举类型(配合 @JsonValue)
|
|
419
|
+
private AccTradeTypeEnum tradeType;
|
|
420
|
+
|
|
421
|
+
// ✅ 方案二:@ApiModelProperty 标注合法值
|
|
422
|
+
@ApiModelProperty(value = "操作类型:1-充值 2-消费 3-退款", allowableValues = "1,2,3")
|
|
423
|
+
private Integer tradeType;
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
## MyBatis-Plus 安全规范
|
|
427
|
+
|
|
428
|
+
### selectOne 必须有唯一保障
|
|
429
|
+
|
|
430
|
+
```java
|
|
431
|
+
// ❌ 危险:多条记录时抛 TooManyResultsException
|
|
432
|
+
Entity entity = mapper.selectOne(wrapper);
|
|
433
|
+
|
|
434
|
+
// ✅ 方案一:LIMIT 1
|
|
435
|
+
Entity entity = mapper.selectOne(wrapper.last("LIMIT 1"));
|
|
436
|
+
|
|
437
|
+
// ✅ 方案二:selectList 取第一条
|
|
438
|
+
List<Entity> list = mapper.selectList(wrapper);
|
|
439
|
+
Entity entity = CollUtil.isNotEmpty(list) ? list.get(0) : null;
|
|
440
|
+
|
|
441
|
+
// ✅ 方案三:确保有唯一索引(注释说明)
|
|
442
|
+
// 唯一索引:UNIQUE KEY (order_no, del_flag)
|
|
443
|
+
Entity entity = mapper.selectOne(wrapper);
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
### 存在性判断用 EXISTS,禁用 selectCount
|
|
447
|
+
|
|
448
|
+
```java
|
|
449
|
+
// ❌ 低效:100万行表 ~200ms
|
|
450
|
+
Long count = mapper.selectCount(wrapper);
|
|
451
|
+
if (count > 0) { ... }
|
|
452
|
+
|
|
453
|
+
// ✅ 高效:~2ms(MyBatis-Plus 3.5.4+)
|
|
454
|
+
boolean exists = mapper.exists(wrapper);
|
|
455
|
+
|
|
456
|
+
// ✅ 或 selectList + LIMIT 1
|
|
457
|
+
boolean exists = CollUtil.isNotEmpty(mapper.selectList(wrapper.last("LIMIT 1")));
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
### Wrapper 嵌套不超过 2 层
|
|
461
|
+
|
|
462
|
+
```java
|
|
463
|
+
// ❌ 过于复杂的 Wrapper
|
|
464
|
+
wrapper.and(w -> w.eq(A::getType, type)
|
|
465
|
+
.or(q -> q.eq(A::getType, 0))
|
|
466
|
+
.or(!PersonTypeEnum.LABOUR.getKey().equals(type),
|
|
467
|
+
q -> q.eq(A::getType, PSN_TYPE_SHARED)));
|
|
468
|
+
|
|
469
|
+
// ✅ 复杂查询写到 XML 中
|
|
470
|
+
List<Entity> list = mapper.selectByTypeCondition(type, isLabour);
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
### 禁止 SELECT *
|
|
474
|
+
|
|
475
|
+
```xml
|
|
476
|
+
<!-- ❌ 禁止 -->
|
|
477
|
+
<select id="selectAll">SELECT * FROM t_order WHERE del_flag = 2</select>
|
|
478
|
+
|
|
479
|
+
<!-- ✅ 明确列出字段 -->
|
|
480
|
+
<select id="selectAll">SELECT id, order_no, amount, status, crtime FROM t_order WHERE del_flag = 2</select>
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
## Redis 使用规范
|
|
484
|
+
|
|
485
|
+
### 禁止 KEYS 命令
|
|
398
486
|
|
|
399
|
-
|
|
487
|
+
```java
|
|
488
|
+
// ❌ 严禁:KEYS 阻塞 Redis
|
|
489
|
+
Set<Object> keys = keysByPattern(pattern);
|
|
490
|
+
Set<Object> keys = redisTemplate.keys(pattern);
|
|
491
|
+
|
|
492
|
+
// ✅ 使用 Redisson deleteByPattern(内部 SCAN + UNLINK)
|
|
493
|
+
RedissonClient redisson = SpringUtil.getBean(RedissonClient.class);
|
|
494
|
+
redisson.getKeys().deleteByPattern(keyPattern);
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
## Optional 使用规范
|
|
498
|
+
|
|
499
|
+
```java
|
|
500
|
+
// ❌ 错误:of() 不接受 null
|
|
501
|
+
Optional.of(value).orElse(defaultValue);
|
|
502
|
+
|
|
503
|
+
// ✅ 正确:ofNullable()
|
|
504
|
+
Optional.ofNullable(value).orElse(defaultValue);
|
|
505
|
+
|
|
506
|
+
// ✅ 链式安全转换
|
|
507
|
+
Optional.ofNullable(model.getReserveRate())
|
|
508
|
+
.map(BigDecimal::new)
|
|
509
|
+
.orElse(BigDecimal.ZERO);
|
|
510
|
+
|
|
511
|
+
// ❌ 禁止作为方法参数或类字段
|
|
512
|
+
// ✅ 允许作为方法返回值
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
## @Transactional 规范
|
|
516
|
+
|
|
517
|
+
```java
|
|
518
|
+
// ❌ 默认只回滚 RuntimeException
|
|
519
|
+
@Transactional
|
|
520
|
+
public void createOrder() { ... }
|
|
521
|
+
|
|
522
|
+
// ✅ 显式指定 rollbackFor
|
|
523
|
+
@Transactional(rollbackFor = Exception.class)
|
|
524
|
+
public void createOrder() { ... }
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
- 事务方法不要 try-catch 吞掉异常
|
|
528
|
+
- 只读查询不加 `@Transactional`
|
|
529
|
+
|
|
530
|
+
## 业务逻辑分层规范
|
|
531
|
+
|
|
532
|
+
```java
|
|
533
|
+
// ❌ 错误:业务判断混在数据操作中
|
|
534
|
+
public void processOrder(Long orderId) {
|
|
535
|
+
OrderInfo order = orderMapper.selectById(orderId);
|
|
536
|
+
if (order.getStatus() == 1 && order.getPayTime() != null
|
|
537
|
+
&& ChronoUnit.HOURS.between(order.getPayTime(), LocalDateTime.now()) < 24) {
|
|
538
|
+
order.setStatus(2);
|
|
539
|
+
orderMapper.updateById(order);
|
|
540
|
+
accWalletService.deduct(order.getCustId(), order.getAmount());
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
// ✅ 正确:分层清晰
|
|
545
|
+
public void processOrder(Long orderId) {
|
|
546
|
+
OrderInfo order = orderMapper.selectById(orderId);
|
|
547
|
+
if (ObjectUtil.isNull(order)) {
|
|
548
|
+
throw new LeException(I18n.getMessage("order_not_found"));
|
|
549
|
+
}
|
|
550
|
+
checkCanProcess(order); // 业务校验(独立方法)
|
|
551
|
+
order.markAsProcessed(); // 状态变更(Entity 方法封装)
|
|
552
|
+
orderMapper.updateById(order);
|
|
553
|
+
afterOrderProcessed(order); // 后续动作(独立方法)
|
|
554
|
+
}
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
| 层 | 职责 | 不应做的 |
|
|
558
|
+
|----|------|---------|
|
|
559
|
+
| Controller | 参数接收、格式转换 | 不含业务判断 |
|
|
560
|
+
| Business | 业务编排、跨 Service 协调 | 不直接操作 Mapper |
|
|
561
|
+
| Service | 单表 CRUD、单表事务 | 不含跨表业务逻辑 |
|
|
562
|
+
| Mapper | SQL 映射 | 不含业务逻辑 |
|
|
563
|
+
|
|
564
|
+
## TODO 管理规范
|
|
565
|
+
|
|
566
|
+
```java
|
|
567
|
+
// ❌ 错误
|
|
568
|
+
// TODO 修改一下
|
|
569
|
+
|
|
570
|
+
// ✅ 正确
|
|
571
|
+
// TODO(@陈沈杰, 2026-03-20, #TASK-1234): 移动端 AppId 赋值逻辑待产品确认
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
- 不用的代码直接删除,不要注释保留
|
|
575
|
+
|
|
576
|
+
## 通用代码规范
|
|
400
577
|
|
|
401
578
|
1. **禁止使用 `SELECT *`**:明确指定字段
|
|
402
579
|
2. **使用参数化查询**:`#{}` 而非 `${}`
|