ai-engineering-init 1.4.3 → 1.6.0
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/.cursor/skills/bug-detective/SKILL.md +19 -19
- package/.cursor/skills/project-navigator/SKILL.md +164 -258
- package/README.md +20 -236
- package/bin/index.js +437 -7
- package/package.json +7 -1
- package/scripts/build-skills.js +180 -0
- package/src/platform-map.json +56 -0
- package/src/skills/add-skill/SKILL.md +488 -0
- package/src/skills/add-todo/SKILL.md +269 -0
- package/src/skills/api-development/SKILL.md +266 -0
- package/src/skills/architecture-design/SKILL.md +262 -0
- package/src/skills/backend-annotations/SKILL.md +302 -0
- package/src/skills/banana-image/CHANGELOG.md +37 -0
- package/src/skills/banana-image/README.md +146 -0
- package/src/skills/banana-image/SKILL.md +171 -0
- package/src/skills/banana-image/assets/logo.png +0 -0
- package/src/skills/banana-image/references/advanced-usage.md +189 -0
- package/src/skills/banana-image/scripts/apply_template.py +125 -0
- package/src/skills/banana-image/scripts/banana_image_exec.ts +412 -0
- package/src/skills/banana-image/scripts/batch_prep.py +82 -0
- package/src/skills/banana-image/scripts/package-lock.json +1437 -0
- package/src/skills/banana-image/scripts/package.json +18 -0
- package/src/skills/banana-image/scripts/requirements.txt +10 -0
- package/src/skills/banana-image/templates/poster.json +22 -0
- package/src/skills/banana-image/templates/product.json +17 -0
- package/src/skills/banana-image/templates/social.json +22 -0
- package/src/skills/banana-image/templates/thumbnail.json +17 -0
- package/src/skills/brainstorm/SKILL.md +216 -0
- package/src/skills/bug-detective/SKILL.md +256 -0
- package/src/skills/bug-detective/references/error-patterns.md +242 -0
- package/src/skills/check/SKILL.md +367 -0
- package/src/skills/code-patterns/SKILL.md +280 -0
- package/src/skills/code-patterns/references/leniu-code-patterns.md +87 -0
- package/src/skills/codex-code-review/SKILL.md +135 -0
- package/src/skills/collaborating-with-codex/SKILL.md +174 -0
- package/src/skills/collaborating-with-codex/scripts/codex_bridge.py +275 -0
- package/src/skills/collaborating-with-gemini/SKILL.md +194 -0
- package/src/skills/collaborating-with-gemini/scripts/gemini_bridge.py +275 -0
- package/src/skills/crud/SKILL.md +265 -0
- package/src/skills/crud-development/SKILL.md +409 -0
- package/src/skills/data-permission/SKILL.md +292 -0
- package/src/skills/data-permission/references/custom-data-scope.md +90 -0
- package/src/skills/database-ops/SKILL.md +407 -0
- package/src/skills/dev/SKILL.md +187 -0
- package/src/skills/error-handler/SKILL.md +371 -0
- package/src/skills/file-oss-management/SKILL.md +255 -0
- package/src/skills/file-oss-management/references/entities.md +105 -0
- package/src/skills/file-oss-management/references/service-impl.md +104 -0
- package/src/skills/git-workflow/SKILL.md +397 -0
- package/src/skills/init-docs/SKILL.md +194 -0
- package/src/skills/json-serialization/SKILL.md +357 -0
- package/src/skills/leniu-api-development/SKILL.md +319 -0
- package/src/skills/leniu-api-development/references/real-examples.md +273 -0
- package/src/skills/leniu-architecture-design/SKILL.md +383 -0
- package/src/skills/leniu-backend-annotations/SKILL.md +277 -0
- package/src/skills/leniu-brainstorm/SKILL.md +242 -0
- package/src/skills/leniu-brainstorm/references/business-scenarios.md +162 -0
- package/src/skills/leniu-code-patterns/SKILL.md +411 -0
- package/src/skills/leniu-crud-development/SKILL.md +404 -0
- package/src/skills/leniu-crud-development/references/templates.md +597 -0
- package/src/skills/leniu-customization-location/SKILL.md +410 -0
- package/src/skills/leniu-data-permission/SKILL.md +341 -0
- package/src/skills/leniu-database-ops/SKILL.md +426 -0
- package/src/skills/leniu-error-handler/SKILL.md +462 -0
- package/src/skills/leniu-java-amount-handling/SKILL.md +461 -0
- package/src/skills/leniu-java-code-style/SKILL.md +510 -0
- package/src/skills/leniu-java-concurrent/SKILL.md +400 -0
- package/src/skills/leniu-java-entity/SKILL.md +237 -0
- package/src/skills/leniu-java-entity/references/templates.md +237 -0
- package/src/skills/leniu-java-export/SKILL.md +570 -0
- package/src/skills/leniu-java-logging/SKILL.md +229 -0
- package/src/skills/leniu-java-logging/references/data-mask.md +46 -0
- package/src/skills/leniu-java-logging/references/logging-scenarios.md +113 -0
- package/src/skills/leniu-java-mq/SKILL.md +338 -0
- package/src/skills/leniu-java-mybatis/SKILL.md +267 -0
- package/src/skills/leniu-java-mybatis/references/report-mapper.md +88 -0
- package/src/skills/leniu-java-report-query-param/SKILL.md +291 -0
- package/src/skills/leniu-java-task/SKILL.md +367 -0
- package/src/skills/leniu-java-total-line/SKILL.md +196 -0
- package/src/skills/leniu-marketing-price-rule-customizer/SKILL.md +301 -0
- package/src/skills/leniu-marketing-recharge-rule-customizer/SKILL.md +285 -0
- package/src/skills/leniu-mealtime/SKILL.md +215 -0
- package/src/skills/leniu-redis-cache/SKILL.md +331 -0
- package/src/skills/leniu-report-customization/SKILL.md +335 -0
- package/src/skills/leniu-report-customization/references/table-fields.md +93 -0
- package/src/skills/leniu-report-standard-customization/SKILL.md +328 -0
- package/src/skills/leniu-report-standard-customization/references/analysis-module.md +64 -0
- package/src/skills/leniu-report-standard-customization/references/table-fields.md +113 -0
- package/src/skills/leniu-security-guard/SKILL.md +306 -0
- package/src/skills/leniu-utils-toolkit/SKILL.md +380 -0
- package/src/skills/mysql-debug/SKILL.md +364 -0
- package/src/skills/next/SKILL.md +137 -0
- package/src/skills/openspec-apply-change/SKILL.md +165 -0
- package/src/skills/openspec-archive-change/SKILL.md +122 -0
- package/src/skills/openspec-bulk-archive-change/SKILL.md +254 -0
- package/src/skills/openspec-continue-change/SKILL.md +126 -0
- package/src/skills/openspec-explore/SKILL.md +299 -0
- package/src/skills/openspec-ff-change/SKILL.md +109 -0
- package/src/skills/openspec-new-change/SKILL.md +82 -0
- package/src/skills/openspec-onboard/SKILL.md +414 -0
- package/src/skills/openspec-sync-specs/SKILL.md +146 -0
- package/src/skills/openspec-verify-change/SKILL.md +176 -0
- package/src/skills/performance-doctor/SKILL.md +303 -0
- package/src/skills/progress/SKILL.md +193 -0
- package/src/skills/project-navigator/SKILL.md +211 -0
- package/src/skills/redis-cache/SKILL.md +333 -0
- package/src/skills/redis-cache/references/listeners.md +23 -0
- package/src/skills/scheduled-jobs/SKILL.md +314 -0
- package/src/skills/security-guard/SKILL.md +353 -0
- package/src/skills/security-guard/references/encrypt-config.md +103 -0
- package/src/skills/security-guard/references/sensitive-strategies.md +42 -0
- package/src/skills/sms-mail/SKILL.md +308 -0
- package/src/skills/sms-mail/references/mail-config.md +88 -0
- package/src/skills/sms-mail/references/sms-config.md +74 -0
- package/src/skills/social-login/SKILL.md +266 -0
- package/src/skills/social-login/references/provider-configs.md +118 -0
- package/src/skills/start/SKILL.md +154 -0
- package/src/skills/store-pc/SKILL.md +366 -0
- package/src/skills/sync/SKILL.md +149 -0
- package/src/skills/task-tracker/SKILL.md +307 -0
- package/src/skills/tech-decision/SKILL.md +393 -0
- package/src/skills/tenant-management/SKILL.md +288 -0
- package/src/skills/tenant-management/references/tenant-scenarios.md +91 -0
- package/src/skills/test-development/SKILL.md +301 -0
- package/src/skills/test-development/references/parameterized-examples.md +119 -0
- package/src/skills/ui-pc/SKILL.md +438 -0
- package/src/skills/update-status/SKILL.md +159 -0
- package/src/skills/utils-toolkit/SKILL.md +362 -0
- package/src/skills/utils-toolkit/references/redis-utils-api.md +56 -0
- package/src/skills/websocket-sse/SKILL.md +271 -0
- package/src/skills/workflow-engine/SKILL.md +321 -0
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: code-patterns
|
|
3
|
+
description: |
|
|
4
|
+
后端代码禁令和编码规范速查。本项目是纯后端项目,前端代码在分离的项目中开发。
|
|
5
|
+
|
|
6
|
+
触发场景:
|
|
7
|
+
- 查看项目禁止事项(后端代码)
|
|
8
|
+
- 命名规范速查
|
|
9
|
+
- Git 提交规范
|
|
10
|
+
- 代码风格检查
|
|
11
|
+
- 避免过度工程
|
|
12
|
+
|
|
13
|
+
触发词:规范、禁止、命名、Git提交、代码风格、不能用、不允许、包名、架构
|
|
14
|
+
|
|
15
|
+
注意:后端 CRUD 开发规范请激活 crud-development,API 开发规范请激活 api-development,数据库设计规范请激活 database-ops。
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# 代码规范速查
|
|
19
|
+
|
|
20
|
+
## 后端禁令速查表
|
|
21
|
+
|
|
22
|
+
| # | 禁止项 | 错误写法 | 正确写法 |
|
|
23
|
+
|---|--------|---------|---------|
|
|
24
|
+
| 1 | 包名 | `com.ruoyi.*` / `plus.ruoyi.*` | `org.dromara.*` |
|
|
25
|
+
| 2 | 完整引用 | `org.dromara.xxx.Xxx` 内联 | `import` + 短类名 |
|
|
26
|
+
| 3 | 数据返回 | `Map<String, Object>` | 创建 VO 类 |
|
|
27
|
+
| 4 | Service设计 | `extends ServiceImpl<>` | `implements IXxxService` |
|
|
28
|
+
| 5 | 查询构建 | Controller 层 | **Service 层** `buildQueryWrapper()` |
|
|
29
|
+
| 6 | 接口路径 | `/pageXxxs`, `/getXxx/{id}` | `/list`, `/{id}`, `/` |
|
|
30
|
+
| 7 | 对象转换 | `BeanUtil.copyProperties()` | `MapstructUtils.convert()` |
|
|
31
|
+
| 8 | 主键 | `AUTO_INCREMENT` | 雪花ID(不指定type) |
|
|
32
|
+
| 9 | R.ok(string) | `R.ok(token)` | `R.ok(null, token)` |
|
|
33
|
+
| 10 | Entity基类 | 无基类 | `extends TenantEntity` / `BaseEntity` |
|
|
34
|
+
| 11 | @Cacheable | 返回 `List.of()`/`Set.of()` | `new ArrayList<>(List.of())` |
|
|
35
|
+
| 12 | Mapper注解 | 单目标用 `@AutoMappers` | 单目标用 `@AutoMapper` |
|
|
36
|
+
| 13 | 注释语言 | 英文注释 | **中文注释** |
|
|
37
|
+
| 14 | SQL COMMENT | `COMMENT 'user name'` | `COMMENT '用户名'` |
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## 禁令详解
|
|
42
|
+
|
|
43
|
+
### 1-2. 包名与引用
|
|
44
|
+
|
|
45
|
+
```java
|
|
46
|
+
// ✅
|
|
47
|
+
package org.dromara.system.service;
|
|
48
|
+
import org.dromara.common.core.domain.R;
|
|
49
|
+
public R<XxxVo> getXxx(Long id) { ... }
|
|
50
|
+
|
|
51
|
+
// ❌
|
|
52
|
+
package com.ruoyi.system.service;
|
|
53
|
+
public org.dromara.common.core.domain.R<XxxVo> getXxx(Long id) { ... }
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### 3. 禁止 Map 传业务数据
|
|
57
|
+
|
|
58
|
+
```java
|
|
59
|
+
// ✅ 创建 VO 类
|
|
60
|
+
public XxxVo getXxx(Long id) {
|
|
61
|
+
return MapstructUtils.convert(entity, XxxVo.class);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// ❌
|
|
65
|
+
public Map<String, Object> getXxx(Long id) { ... }
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### 4-5. Service 架构
|
|
69
|
+
|
|
70
|
+
```java
|
|
71
|
+
// ✅ 三层架构:不继承 ServiceImpl,直接注入 Mapper
|
|
72
|
+
@Service
|
|
73
|
+
public class XxxServiceImpl implements IXxxService {
|
|
74
|
+
private final XxxMapper baseMapper;
|
|
75
|
+
|
|
76
|
+
private LambdaQueryWrapper<Xxx> buildQueryWrapper(XxxBo bo) {
|
|
77
|
+
LambdaQueryWrapper<Xxx> lqw = Wrappers.lambdaQuery();
|
|
78
|
+
lqw.eq(bo.getStatus() != null, Xxx::getStatus, bo.getStatus());
|
|
79
|
+
lqw.like(StringUtils.isNotBlank(bo.getName()), Xxx::getName, bo.getName());
|
|
80
|
+
return lqw;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// ❌
|
|
85
|
+
public class XxxServiceImpl extends ServiceImpl<XxxMapper, Xxx> { }
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### 6. RESTful 路径
|
|
89
|
+
|
|
90
|
+
```java
|
|
91
|
+
// ✅
|
|
92
|
+
@GetMapping("/list") @GetMapping("/{id}")
|
|
93
|
+
@PostMapping @PutMapping
|
|
94
|
+
@DeleteMapping("/{ids}") @PostMapping("/export")
|
|
95
|
+
|
|
96
|
+
// ❌
|
|
97
|
+
@GetMapping("/pageAds") @GetMapping("/getAd/{id}")
|
|
98
|
+
@PostMapping("/addAd") @PutMapping("/updateAd")
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### 7. 对象转换
|
|
102
|
+
|
|
103
|
+
```java
|
|
104
|
+
// ✅ MapstructUtils
|
|
105
|
+
XxxVo vo = MapstructUtils.convert(entity, XxxVo.class);
|
|
106
|
+
List<XxxVo> voList = MapstructUtils.convert(entityList, XxxVo.class);
|
|
107
|
+
|
|
108
|
+
// ❌ BeanUtil
|
|
109
|
+
BeanUtil.copyProperties(entity, vo);
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### 8. 主键策略
|
|
113
|
+
|
|
114
|
+
```sql
|
|
115
|
+
-- ✅ 雪花ID
|
|
116
|
+
id BIGINT(20) NOT NULL COMMENT '主键ID'
|
|
117
|
+
|
|
118
|
+
-- ❌
|
|
119
|
+
id BIGINT(20) AUTO_INCREMENT
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### 9. R.ok() 返回 String 陷阱
|
|
123
|
+
|
|
124
|
+
```java
|
|
125
|
+
// ❌ 匹配 R.ok(String msg),字符串进入 msg 而非 data
|
|
126
|
+
return R.ok(token); // {code:200, msg:"xxx", data:null}
|
|
127
|
+
|
|
128
|
+
// ✅ 明确指定
|
|
129
|
+
return R.ok(null, token); // data=token, msg=null
|
|
130
|
+
return R.ok("获取成功", token); // 都有值
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### 10. Entity 基类
|
|
134
|
+
|
|
135
|
+
```java
|
|
136
|
+
// ✅ 业务表(需多租户隔离)
|
|
137
|
+
public class Xxx extends TenantEntity {
|
|
138
|
+
@TableId(value = "id")
|
|
139
|
+
private Long id;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// ✅ 系统表(不需多租户)
|
|
143
|
+
public class SysClient extends BaseEntity { }
|
|
144
|
+
|
|
145
|
+
// ❌ 不继承基类
|
|
146
|
+
public class Xxx { }
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### 11. @Cacheable 不可变集合
|
|
150
|
+
|
|
151
|
+
```java
|
|
152
|
+
// ❌ Redis 反序列化失败
|
|
153
|
+
@Cacheable(value = "xxx")
|
|
154
|
+
public List<String> listXxx() { return List.of("1", "2"); }
|
|
155
|
+
|
|
156
|
+
// ✅ 可变集合包装
|
|
157
|
+
@Cacheable(value = "xxx")
|
|
158
|
+
public List<String> listXxx() { return new ArrayList<>(List.of("1", "2")); }
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
> **原因**:Jackson DefaultTyping.NON_FINAL 会为 `ImmutableCollections$List12` 添加类型信息,反序列化时导致 `ClassNotFoundException`。
|
|
162
|
+
|
|
163
|
+
### 12. BO 映射注解
|
|
164
|
+
|
|
165
|
+
```java
|
|
166
|
+
// ✅ 单目标:@AutoMapper
|
|
167
|
+
@AutoMapper(target = Xxx.class, reverseConvertGenerate = false)
|
|
168
|
+
public class XxxBo { }
|
|
169
|
+
|
|
170
|
+
// ✅ 多目标:@AutoMappers
|
|
171
|
+
@AutoMappers({
|
|
172
|
+
@AutoMapper(target = SysOperLog.class, reverseConvertGenerate = false),
|
|
173
|
+
@AutoMapper(target = OperLogEvent.class)
|
|
174
|
+
})
|
|
175
|
+
public class SysOperLogBo { }
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### 13-14. 中文注释与 SQL COMMENT
|
|
179
|
+
|
|
180
|
+
```java
|
|
181
|
+
// ✅ 中文注释
|
|
182
|
+
/** 根据 ID 查询用户信息 */
|
|
183
|
+
public SysUserVo queryById(Long id) {
|
|
184
|
+
// 查询用户基本信息
|
|
185
|
+
return baseMapper.selectVoById(id);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// ❌ 英文注释
|
|
189
|
+
/** Query user info by ID */
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
```sql
|
|
193
|
+
-- ✅
|
|
194
|
+
`user_name` VARCHAR(50) NOT NULL COMMENT '用户名',
|
|
195
|
+
) ENGINE=InnoDB COMMENT='用户信息表';
|
|
196
|
+
|
|
197
|
+
-- ❌
|
|
198
|
+
`user_name` VARCHAR(50) NOT NULL COMMENT 'user name',
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## 命名后缀规范
|
|
204
|
+
|
|
205
|
+
| 类型 | 后缀 | 示例 |
|
|
206
|
+
|------|------|------|
|
|
207
|
+
| 实体类 | 无/Sys前缀 | `SysUser`, `TestDemo` |
|
|
208
|
+
| 业务对象 | Bo | `SysUserBo` |
|
|
209
|
+
| 视图对象 | Vo | `SysUserVo` |
|
|
210
|
+
| 服务接口 | IXxxService | `ISysUserService` |
|
|
211
|
+
| 服务实现 | XxxServiceImpl | `SysUserServiceImpl` |
|
|
212
|
+
| 控制器 | XxxController | `SysUserController` |
|
|
213
|
+
| Mapper | XxxMapper | `SysUserMapper` |
|
|
214
|
+
|
|
215
|
+
> 本项目是三层架构,没有 DAO 层。Service 直接注入 Mapper。
|
|
216
|
+
|
|
217
|
+
## 方法命名
|
|
218
|
+
|
|
219
|
+
| 操作 | Service 方法 | Controller URL |
|
|
220
|
+
|------|-------------|----------------|
|
|
221
|
+
| 分页查询 | `queryPageList(bo, pageQuery)` | `GET /list` |
|
|
222
|
+
| 查询单个 | `queryById(id)` | `GET /{id}` |
|
|
223
|
+
| 新增 | `insertByBo(bo)` | `POST /` |
|
|
224
|
+
| 修改 | `updateByBo(bo)` | `PUT /` |
|
|
225
|
+
| 删除 | `deleteWithValidByIds(ids)` | `DELETE /{ids}` |
|
|
226
|
+
| 导出 | `queryList(bo)` + ExcelUtil | `POST /export` |
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## Git 提交规范
|
|
231
|
+
|
|
232
|
+
```
|
|
233
|
+
<type>(<scope>): <description>
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
| type | 说明 | 示例 |
|
|
237
|
+
|------|------|------|
|
|
238
|
+
| `feat` | 新功能 | `feat(system): 新增用户反馈功能` |
|
|
239
|
+
| `fix` | 修复 | `fix(demo): 修复订单状态显示错误` |
|
|
240
|
+
| `refactor` | 重构 | `refactor(common): 重构分页查询工具类` |
|
|
241
|
+
| `perf` | 性能 | `perf(system): 优化用户列表查询性能` |
|
|
242
|
+
| `docs` | 文档 | `docs(readme): 更新安装说明` |
|
|
243
|
+
| `style` | 格式 | `chore` 构建/工具 | `test` 测试 |
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
## 多项目适配
|
|
248
|
+
|
|
249
|
+
| 特征 | RuoYi-Vue-Plus | leniu-tengyun-core |
|
|
250
|
+
|------|----------------|-------------------|
|
|
251
|
+
| 包名 | `org.dromara.*` | `net.xnzn.core.*` |
|
|
252
|
+
| JDK | 17 | 21 |
|
|
253
|
+
| 对象转换 | `MapstructUtils.convert()` | `BeanUtil.copyProperties()` |
|
|
254
|
+
| 分页 | `TableDataInfo<T>` | `Page<T>` |
|
|
255
|
+
| 异常 | `ServiceException` | `LeException` |
|
|
256
|
+
| 工具库 | 自定义工具类 | Hutool |
|
|
257
|
+
|
|
258
|
+
### leniu-tengyun-core 专用
|
|
259
|
+
|
|
260
|
+
```java
|
|
261
|
+
// 国际化
|
|
262
|
+
throw new LeException(I18n.getMessage("user.not.exists"));
|
|
263
|
+
|
|
264
|
+
// 租户上下文
|
|
265
|
+
Long tenantId = TenantContextHolder.getTenantId();
|
|
266
|
+
|
|
267
|
+
// 分页
|
|
268
|
+
PageMethod.startPage(param.getPage().getPageNum(), param.getPage().getPageSize());
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## 相关 Skill
|
|
274
|
+
|
|
275
|
+
| 需要了解 | 激活 Skill |
|
|
276
|
+
|---------|-----------|
|
|
277
|
+
| 后端 CRUD 开发 | `crud-development` |
|
|
278
|
+
| API 开发 | `api-development` |
|
|
279
|
+
| 数据库设计 | `database-ops` |
|
|
280
|
+
| 系统架构 | `architecture-design` |
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# leniu-tengyun-core 代码模式详解
|
|
2
|
+
|
|
3
|
+
## Hutool 工具类完整用法
|
|
4
|
+
|
|
5
|
+
```java
|
|
6
|
+
import cn.hutool.core.collection.CollUtil;
|
|
7
|
+
import cn.hutool.core.util.ObjectUtil;
|
|
8
|
+
import cn.hutool.core.util.StrUtil;
|
|
9
|
+
import cn.hutool.core.bean.BeanUtil;
|
|
10
|
+
|
|
11
|
+
// 1. 集合操作
|
|
12
|
+
if (CollUtil.isEmpty(list)) {
|
|
13
|
+
throw new LeException("列表不能为空");
|
|
14
|
+
}
|
|
15
|
+
if (CollUtil.isNotEmpty(list)) {
|
|
16
|
+
// 处理列表
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// 2. 对象判空
|
|
20
|
+
if (ObjectUtil.isNull(user)) {
|
|
21
|
+
throw new LeException("用户不存在");
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// 3. 字符串操作
|
|
25
|
+
if (StrUtil.isBlank(name)) {
|
|
26
|
+
throw new LeException("名称不能为空");
|
|
27
|
+
}
|
|
28
|
+
String trimmed = StrUtil.trim(name);
|
|
29
|
+
String joined = StrUtil.join(",", list);
|
|
30
|
+
|
|
31
|
+
// 4. 对象拷贝
|
|
32
|
+
TargetDTO target = BeanUtil.copyProperties(source, TargetDTO.class);
|
|
33
|
+
List<TargetDTO> targets = BeanUtil.copyToList(sources, TargetDTO.class);
|
|
34
|
+
|
|
35
|
+
// 5. 集合创建
|
|
36
|
+
List<String> list = CollUtil.newArrayList("a", "b", "c");
|
|
37
|
+
Map<String, Object> map = CollUtil.newHashMap();
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## 国际化消息
|
|
41
|
+
|
|
42
|
+
```java
|
|
43
|
+
import net.xnzn.core.common.i18n.I18n;
|
|
44
|
+
|
|
45
|
+
// RuoYi-Vue-Plus 风格
|
|
46
|
+
throw new ServiceException(MessageUtils.message("user.not.exists"));
|
|
47
|
+
|
|
48
|
+
// leniu-tengyun-core 风格
|
|
49
|
+
throw new LeException(I18n.getMessage("user.not.exists"));
|
|
50
|
+
|
|
51
|
+
// 带参数
|
|
52
|
+
throw new LeException(I18n.getMessage("user.password.retry.limit.exceed", maxRetryCount));
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## 租户上下文
|
|
56
|
+
|
|
57
|
+
```java
|
|
58
|
+
import net.xnzn.core.context.TenantContextHolder;
|
|
59
|
+
|
|
60
|
+
Long tenantId = TenantContextHolder.getTenantId();
|
|
61
|
+
TenantContextHolder.setTenantId(tenantId);
|
|
62
|
+
TenantContextHolder.clear();
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## 分页参数处理
|
|
66
|
+
|
|
67
|
+
```java
|
|
68
|
+
@Data
|
|
69
|
+
public class XxxQueryParam implements Serializable {
|
|
70
|
+
@ApiModelProperty(value = "分页参数", required = true)
|
|
71
|
+
@NotNull(message = "分页参数不能为空")
|
|
72
|
+
private PageDTO page;
|
|
73
|
+
|
|
74
|
+
@ApiModelProperty("关键字")
|
|
75
|
+
private String keyword;
|
|
76
|
+
|
|
77
|
+
@ApiModelProperty("状态")
|
|
78
|
+
private Integer status;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Service 层
|
|
82
|
+
public Page<XxxVO> pageList(XxxQueryParam param) {
|
|
83
|
+
PageMethod.startPage(param.getPage().getPageNum(), param.getPage().getPageSize());
|
|
84
|
+
List<XxxEntity> list = xxxMapper.selectList(buildWrapper(param));
|
|
85
|
+
return new Page<>(list);
|
|
86
|
+
}
|
|
87
|
+
```
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: codex-code-review
|
|
3
|
+
description: |
|
|
4
|
+
Codex 代码审查工作流。在代码实现或 Bug 修复完成后,调用 Codex CLI 进行代码审查,展示审查结果,用户确认后自动修复问题。
|
|
5
|
+
|
|
6
|
+
触发场景:
|
|
7
|
+
- /dev 或 /crud 命令完成代码生成后
|
|
8
|
+
- Bug 修复完成后
|
|
9
|
+
- 用户说"审查代码"、"review"、"代码审查"、"codex审查"
|
|
10
|
+
- 用户说"检查一下刚写的代码"
|
|
11
|
+
|
|
12
|
+
触发词:codex审查、代码审查、review代码、审查代码、codex review、代码review
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Codex 代码审查工作流
|
|
16
|
+
|
|
17
|
+
> 依赖 `collaborating-with-codex` skill 的 `codex_bridge.py` 脚本。
|
|
18
|
+
|
|
19
|
+
## 工作流
|
|
20
|
+
|
|
21
|
+
### Phase 1: 收集变更范围
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
# 获取当前未提交的变更文件
|
|
25
|
+
git diff --name-only HEAD
|
|
26
|
+
git diff --cached --name-only
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
如果没有变更文件,提示用户"没有检测到代码变更"并终止。
|
|
30
|
+
|
|
31
|
+
将变更文件按类型分组:
|
|
32
|
+
- **Java 文件**:Controller / Business / Service / Mapper / Entity / VO / DTO
|
|
33
|
+
- **XML 文件**:Mapper XML
|
|
34
|
+
- **SQL 文件**:建表/变更脚本
|
|
35
|
+
- **其他**:配置文件等
|
|
36
|
+
|
|
37
|
+
### Phase 2: 调用 Codex 审查
|
|
38
|
+
|
|
39
|
+
针对变更的 Java 文件,构造审查 PROMPT:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
python .claude/skills/collaborating-with-codex/scripts/codex_bridge.py \
|
|
43
|
+
--cd . \
|
|
44
|
+
--sandbox read-only \
|
|
45
|
+
--PROMPT "Review the following changed files for code quality issues:
|
|
46
|
+
|
|
47
|
+
FILES TO REVIEW:
|
|
48
|
+
{变更文件列表,含相对路径}
|
|
49
|
+
|
|
50
|
+
REVIEW CHECKLIST:
|
|
51
|
+
1. Bug risks: null pointer, off-by-one, resource leaks, concurrency issues
|
|
52
|
+
2. Security: SQL injection, XSS, missing auth checks, sensitive data exposure
|
|
53
|
+
3. Architecture: layer violations (Controller calling Mapper directly), missing Business layer for complex logic
|
|
54
|
+
4. Code quality: duplicate code, overly complex methods, missing error handling
|
|
55
|
+
5. Project conventions: wrong package name (must be net.xnzn.core.*), wrong audit fields (must use crby/crtime/upby/uptime), javax.validation (must use jakarta.validation)
|
|
56
|
+
|
|
57
|
+
OUTPUT FORMAT:
|
|
58
|
+
For each issue found, output:
|
|
59
|
+
- [SEVERITY] CRITICAL / WARNING / SUGGESTION
|
|
60
|
+
- [FILE] filepath:line_number
|
|
61
|
+
- [ISSUE] Brief description
|
|
62
|
+
- [FIX] Recommended fix
|
|
63
|
+
|
|
64
|
+
If no issues found, output: ALL CLEAR - No issues detected.
|
|
65
|
+
|
|
66
|
+
IMPORTANT LANGUAGE RULES:
|
|
67
|
+
- All review comments MUST be in Chinese
|
|
68
|
+
- File paths and code snippets remain in English"
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**关键约束**:
|
|
72
|
+
- 始终使用 `--sandbox read-only`,Codex 不直接修改文件
|
|
73
|
+
- 变更文件过多时(>10 个),按模块分批审查
|
|
74
|
+
- 使用 `run_in_background` 避免阻塞
|
|
75
|
+
|
|
76
|
+
### Phase 3: 展示审查结果
|
|
77
|
+
|
|
78
|
+
解析 Codex 返回的 JSON,提取 `agent_messages`,按严重程度分组展示:
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
## Codex 审查结果
|
|
82
|
+
|
|
83
|
+
### 🔴 严重问题 (CRITICAL)
|
|
84
|
+
- `OrderInfoService.java:42` — 未做空值检查,可能 NPE
|
|
85
|
+
建议:添加 ObjectUtil.isNull() 判断
|
|
86
|
+
|
|
87
|
+
### 🟡 警告 (WARNING)
|
|
88
|
+
- `OrderWebController.java:15` — 缺少 @RequiresAuthentication 注解
|
|
89
|
+
建议:添加认证注解
|
|
90
|
+
|
|
91
|
+
### 🔵 建议 (SUGGESTION)
|
|
92
|
+
- `OrderDTO.java:8` — 字段命名可优化
|
|
93
|
+
建议:使用更具描述性的名称
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
是否需要修复以上问题?
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
如果结果为 `ALL CLEAR`,展示"审查通过,未发现问题"并终止。
|
|
100
|
+
|
|
101
|
+
### Phase 4: 用户确认后修复
|
|
102
|
+
|
|
103
|
+
等待用户确认。用户可能:
|
|
104
|
+
- **全部修复**:"修复所有问题" → 逐个修复所有 CRITICAL + WARNING
|
|
105
|
+
- **选择性修复**:"只修复严重问题" → 仅修复 CRITICAL
|
|
106
|
+
- **跳过**:"不需要修复" → 终止
|
|
107
|
+
|
|
108
|
+
修复时:
|
|
109
|
+
1. 按文件逐个修复,使用 Edit 工具
|
|
110
|
+
2. 每修复一个文件,简要说明改动
|
|
111
|
+
3. SUGGESTION 级别的问题默认跳过,除非用户明确要求
|
|
112
|
+
4. 修复完成后运行 `git diff` 展示所有变更
|
|
113
|
+
|
|
114
|
+
### Phase 5: 可选二次审查
|
|
115
|
+
|
|
116
|
+
修复完成后询问:"是否需要再次审查确认?"
|
|
117
|
+
- 如果用户同意 → 回到 Phase 2 重新审查
|
|
118
|
+
- 如果用户拒绝 → 终止
|
|
119
|
+
|
|
120
|
+
## 审查重点(leniu 项目特有)
|
|
121
|
+
|
|
122
|
+
Codex PROMPT 中追加项目特有检查项:
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
PROJECT-SPECIFIC CHECKS:
|
|
126
|
+
- Package must be net.xnzn.core.* (NOT org.dromara.*)
|
|
127
|
+
- Audit fields: crby/crtime/upby/uptime (NOT createBy/createTime)
|
|
128
|
+
- del_flag: 1=deleted, 2=normal (NOT 0=normal)
|
|
129
|
+
- Use LeException (NOT ServiceException)
|
|
130
|
+
- Use BeanUtil.copyProperties() (NOT MapstructUtils)
|
|
131
|
+
- Use jakarta.validation.* (NOT javax.validation.*)
|
|
132
|
+
- No tenant_id field in Entity (dual-database physical isolation)
|
|
133
|
+
- Architecture: Controller → Business → Service → Mapper (4-layer)
|
|
134
|
+
- No Map for business data transfer (use VO/DTO)
|
|
135
|
+
```
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: collaborating-with-codex
|
|
3
|
+
description: |
|
|
4
|
+
与 OpenAI Codex CLI 协同开发。将编码任务委托给 Codex 进行原型开发、调试分析和代码审查。
|
|
5
|
+
|
|
6
|
+
触发场景:
|
|
7
|
+
- 需要算法实现或复杂逻辑分析
|
|
8
|
+
- 需要代码审查和 Bug 分析
|
|
9
|
+
- 需要生成 Unified Diff 补丁
|
|
10
|
+
- 用户明确要求使用 Codex 协作
|
|
11
|
+
- 复杂后端逻辑的原型设计
|
|
12
|
+
|
|
13
|
+
触发词:Codex、协作、多模型、原型、Diff、算法分析、代码审查、codex协同
|
|
14
|
+
|
|
15
|
+
前置要求:
|
|
16
|
+
- 已安装 Codex CLI (npm install -g @openai/codex)
|
|
17
|
+
- 已配置 OpenAI API Key
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
# 与 Codex CLI 协同开发
|
|
21
|
+
|
|
22
|
+
> 通过 Python 桥接脚本调用 Codex CLI,获取算法实现和代码审查建议。
|
|
23
|
+
|
|
24
|
+
## 快速开始
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# 相对路径(推荐,在项目根目录执行)
|
|
28
|
+
python .claude/skills/collaborating-with-codex/scripts/codex_bridge.py --cd . --PROMPT "Your task"
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**输出**: JSON 格式,包含 `success`、`SESSION_ID`、`agent_messages` 和可选的 `error`。
|
|
32
|
+
|
|
33
|
+
## 参数说明
|
|
34
|
+
|
|
35
|
+
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|
|
36
|
+
|------|------|------|--------|------|
|
|
37
|
+
| `--PROMPT` | str | ✅ | - | 发送给 Codex 的任务指令(使用英语) |
|
|
38
|
+
| `--cd` | Path | ✅ | - | 工作目录根路径 |
|
|
39
|
+
| `--sandbox` | Literal | ❌ | `read-only` | 沙箱策略:`read-only`/`workspace-write`/`danger-full-access` |
|
|
40
|
+
| `--SESSION_ID` | UUID | ❌ | `None` | 会话 ID(继续之前的对话) |
|
|
41
|
+
| `--skip-git-repo-check` | bool | ❌ | `True` | 允许在非 Git 仓库运行 |
|
|
42
|
+
| `--return-all-messages` | bool | ❌ | `False` | 返回完整推理信息 |
|
|
43
|
+
| `--image` | List[Path] | ❌ | `None` | 附加图片文件到提示词 |
|
|
44
|
+
| `--model` | str | ❌ | `None` | 指定模型(仅用户明确要求时使用) |
|
|
45
|
+
| `--yolo` | bool | ❌ | `False` | 跳过所有审批与沙箱限制(危险) |
|
|
46
|
+
|
|
47
|
+
## 使用模式
|
|
48
|
+
|
|
49
|
+
### 1. 基础调用(只读模式)
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
python .claude/skills/collaborating-with-codex/scripts/codex_bridge.py \
|
|
53
|
+
--cd . \
|
|
54
|
+
--PROMPT "Analyze the authentication flow in the login module"
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### 2. 多轮会话
|
|
58
|
+
|
|
59
|
+
**始终保存 SESSION_ID** 用于后续对话:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
# 第一轮:分析代码
|
|
63
|
+
python .claude/skills/collaborating-with-codex/scripts/codex_bridge.py \
|
|
64
|
+
--cd "/project" \
|
|
65
|
+
--PROMPT "Analyze the AdServiceImpl class"
|
|
66
|
+
|
|
67
|
+
# 后续轮次:使用 SESSION_ID 继续
|
|
68
|
+
python .claude/skills/collaborating-with-codex/scripts/codex_bridge.py \
|
|
69
|
+
--cd "/project" \
|
|
70
|
+
--SESSION_ID "uuid-from-previous-response" \
|
|
71
|
+
--PROMPT "Now write unit tests for the add method"
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### 3. 获取 Unified Diff 补丁
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
python .claude/skills/collaborating-with-codex/scripts/codex_bridge.py \
|
|
78
|
+
--cd "/project" \
|
|
79
|
+
--PROMPT "Generate a unified diff to add logging to AdServiceImpl. OUTPUT: Unified Diff Patch ONLY."
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### 4. 调试模式(返回完整信息)
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
python .claude/skills/collaborating-with-codex/scripts/codex_bridge.py \
|
|
86
|
+
--cd "/project" \
|
|
87
|
+
--PROMPT "Debug this error: NullPointerException in line 42" \
|
|
88
|
+
--return-all-messages
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## 返回值结构
|
|
92
|
+
|
|
93
|
+
**成功时:**
|
|
94
|
+
```json
|
|
95
|
+
{
|
|
96
|
+
"success": true,
|
|
97
|
+
"SESSION_ID": "550e8400-e29b-41d4-a716-446655440000",
|
|
98
|
+
"agent_messages": "模型回复内容..."
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**失败时:**
|
|
103
|
+
```json
|
|
104
|
+
{
|
|
105
|
+
"success": false,
|
|
106
|
+
"error": "错误信息描述"
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## 协作工作流
|
|
111
|
+
|
|
112
|
+
### 推荐场景
|
|
113
|
+
|
|
114
|
+
| 场景 | 说明 |
|
|
115
|
+
|------|------|
|
|
116
|
+
| **后端逻辑分析** | Codex 擅长复杂算法和后端逻辑 |
|
|
117
|
+
| **代码审查** | 获取代码质量和潜在问题的反馈 |
|
|
118
|
+
| **Debug 分析** | 利用其强大的调试能力定位问题 |
|
|
119
|
+
| **原型设计** | 快速获取实现思路(返回 Diff 而非直接修改) |
|
|
120
|
+
|
|
121
|
+
### 重要约束
|
|
122
|
+
|
|
123
|
+
1. **只读模式**: 始终使用 `--sandbox read-only`,禁止 Codex 直接修改文件
|
|
124
|
+
2. **英语交互**: 与 Codex 交互时使用英语,获得更好效果
|
|
125
|
+
3. **中文输出强制**: Codex 倾向于输出英文,必须在每次 PROMPT 末尾追加以下约束:
|
|
126
|
+
```
|
|
127
|
+
IMPORTANT LANGUAGE RULES:
|
|
128
|
+
- All SQL COMMENT values MUST be in Chinese (e.g., COMMENT '用户名' NOT COMMENT 'username')
|
|
129
|
+
- All Java/code comments (Javadoc, inline //, block /* */) MUST be in Chinese
|
|
130
|
+
- All field descriptions, table descriptions MUST be in Chinese
|
|
131
|
+
- Variable names and class names remain in English (camelCase/PascalCase)
|
|
132
|
+
```
|
|
133
|
+
4. **Diff 输出**: 在 PROMPT 中明确要求 `OUTPUT: Unified Diff Patch ONLY`
|
|
134
|
+
5. **重构代码**: 将 Codex 的输出视为"脏原型",由 Claude 重构为生产代码(**特别检查注释和 COMMENT 是否为中文,不是则修正**)
|
|
135
|
+
6. **后台运行**: 对于长时间任务,使用 `Run in the background`
|
|
136
|
+
|
|
137
|
+
## 与本项目的集成
|
|
138
|
+
|
|
139
|
+
### 典型用例:后端模块分析
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# 分析 Service 层实现
|
|
143
|
+
python .claude/skills/collaborating-with-codex/scripts/codex_bridge.py \
|
|
144
|
+
--cd . \
|
|
145
|
+
--PROMPT "Analyze the three-layer architecture (Controller -> Service -> Mapper) in ruoyi-modules/ruoyi-system. Focus on how buildQueryWrapper is implemented in Service layer."
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### 典型用例:代码审查
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
# 审查新增的业务模块
|
|
152
|
+
python .claude/skills/collaborating-with-codex/scripts/codex_bridge.py \
|
|
153
|
+
--cd "/project" \
|
|
154
|
+
--PROMPT "Review the XxxServiceImpl.java for potential bugs, security issues, and adherence to the project's three-layer architecture pattern (Controller -> Service -> Mapper, NO DAO layer). OUTPUT: Review comments with specific line numbers."
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## 安装前置
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
# 安装 Codex CLI
|
|
161
|
+
npm install -g @openai/codex
|
|
162
|
+
|
|
163
|
+
# 配置 API Key(可选,如果未设置环境变量)
|
|
164
|
+
codex auth login
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## 故障排除
|
|
168
|
+
|
|
169
|
+
| 问题 | 解决方案 |
|
|
170
|
+
|------|---------|
|
|
171
|
+
| `codex: command not found` | 确保已安装并添加到 PATH |
|
|
172
|
+
| `SESSION_ID` 获取失败 | 检查网络连接和 API Key |
|
|
173
|
+
| 输出被截断 | 使用 `--return-all-messages` 获取完整信息 |
|
|
174
|
+
| Windows 路径问题 | 使用正斜杠 `/` 或双反斜杠 `\\` |
|