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,242 @@
|
|
|
1
|
+
# Bug 排查详细错误案例库
|
|
2
|
+
|
|
3
|
+
> 本文件是 `bug-detective` 技能的参考文档,包含完整的错误排查案例。
|
|
4
|
+
|
|
5
|
+
## 1. NullPointerException 详细排查
|
|
6
|
+
|
|
7
|
+
```java
|
|
8
|
+
// 常见场景
|
|
9
|
+
User user = baseMapper.selectById(id); // 可能返回 null
|
|
10
|
+
user.getName(); // NPE
|
|
11
|
+
|
|
12
|
+
// 修复方案
|
|
13
|
+
XxxEntity entity = Optional.ofNullable(xxxMapper.selectById(id))
|
|
14
|
+
.orElseThrow(() -> new LeException("记录不存在"));
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
**本项目常见 NPE 位置**:
|
|
18
|
+
- `xxxMapper.selectById(id)` 返回 null
|
|
19
|
+
- `BeanUtil.copyProperties()` 源对象为 null
|
|
20
|
+
- 链式调用中间某环节为 null
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 2. SQL 异常详细排查
|
|
25
|
+
|
|
26
|
+
```sql
|
|
27
|
+
-- 检查表是否存在
|
|
28
|
+
SHOW TABLES LIKE 'xxx_table';
|
|
29
|
+
|
|
30
|
+
-- 检查字段
|
|
31
|
+
DESC xxx_table;
|
|
32
|
+
|
|
33
|
+
-- 直接执行验证
|
|
34
|
+
SELECT * FROM xxx_table WHERE id = 1;
|
|
35
|
+
|
|
36
|
+
-- 唯一键冲突检查
|
|
37
|
+
SELECT * FROM xxx_table WHERE unique_field = 'value';
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## 3. 权限问题详细排查
|
|
43
|
+
|
|
44
|
+
```java
|
|
45
|
+
// 1. 检查认证注解
|
|
46
|
+
@RequiresAuthentication // leniu 项目使用此注解
|
|
47
|
+
@RequiresGuest // 免登录接口
|
|
48
|
+
|
|
49
|
+
// 2. 检查请求头
|
|
50
|
+
// Admin-Token: xxx (localStorage)
|
|
51
|
+
// MERCHANT-ID: xxx (租户标识)
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## 4. 事务问题详细排查
|
|
57
|
+
|
|
58
|
+
```java
|
|
59
|
+
// 1. 是否加了事务注解
|
|
60
|
+
@Transactional(rollbackFor = Exception.class)
|
|
61
|
+
|
|
62
|
+
// 2. 异常是否被 try-catch 吞掉
|
|
63
|
+
try {
|
|
64
|
+
// 操作
|
|
65
|
+
} catch (Exception e) {
|
|
66
|
+
log.error("错误", e);
|
|
67
|
+
throw e; // 必须重新抛出,否则事务不回滚
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// 3. 是否在非 public 方法上使用(不生效)
|
|
71
|
+
@Transactional // private 方法不生效
|
|
72
|
+
private void doSomething() {}
|
|
73
|
+
|
|
74
|
+
// 4. 同类调用是否通过 self
|
|
75
|
+
@Autowired @Lazy
|
|
76
|
+
private XxxBusiness self;
|
|
77
|
+
self.transactionalMethod(); // 通过代理调用
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## 5. 日志分析完整示例
|
|
83
|
+
|
|
84
|
+
### 场景:接口报 500
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
AI 执行步骤:
|
|
88
|
+
1. Read ./logs/sys-console.log
|
|
89
|
+
-> 找到最后一个 ERROR:NullPointerException at XxxService.java:45
|
|
90
|
+
|
|
91
|
+
2. Read 对应源文件第 45 行
|
|
92
|
+
-> 代码:user.getName()
|
|
93
|
+
|
|
94
|
+
3. 分析日志中的 SQL
|
|
95
|
+
-> SELECT * FROM xxx WHERE id = 999 返回空
|
|
96
|
+
|
|
97
|
+
4. 数据库验证
|
|
98
|
+
-> 确认 ID 999 不存在
|
|
99
|
+
|
|
100
|
+
5. 诊断:用户不存在时代码未判空
|
|
101
|
+
-> 解决:添加 Optional 判空
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### 场景:查询慢
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
1. 搜索 SQL 日志
|
|
108
|
+
grep "p6spy" ./logs/sys-console.log
|
|
109
|
+
|
|
110
|
+
2. 分析 Cost 耗时
|
|
111
|
+
- Cost < 50ms -> 正常
|
|
112
|
+
- Cost 50-200ms -> 关注
|
|
113
|
+
- Cost > 200ms -> 优化
|
|
114
|
+
|
|
115
|
+
3. 检查 N+1 查询
|
|
116
|
+
4. 建议添加索引或批量查询
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### 场景:租户数据问题
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
1. 搜索 SQL 日志中的查询语句
|
|
123
|
+
2. 检查是否使用了正确的 Executors 切换
|
|
124
|
+
- Executors.doInSystem() -> 系统库
|
|
125
|
+
- 默认 -> 商户库(根据 MERCHANT-ID)
|
|
126
|
+
3. 对比实际数据
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## 6. 前端问题排查
|
|
132
|
+
|
|
133
|
+
### 接口调用失败
|
|
134
|
+
|
|
135
|
+
| 状态码 | 含义 | 解决 |
|
|
136
|
+
|--------|------|------|
|
|
137
|
+
| 400 | 参数错误 | 检查参数类型格式 |
|
|
138
|
+
| 401 | 未认证 | 检查 Admin-Token (localStorage) |
|
|
139
|
+
| 403 | 无权限 | 检查角色权限、v-hasPerm |
|
|
140
|
+
| 404 | 接口不存在 | 检查 URL、后端是否启动 |
|
|
141
|
+
| 500 | 服务端错误 | 查后端日志 |
|
|
142
|
+
|
|
143
|
+
### 前端特有问题
|
|
144
|
+
|
|
145
|
+
```javascript
|
|
146
|
+
// 前端成功码是 10000(非 200)
|
|
147
|
+
if (res.code === 10000) { ... }
|
|
148
|
+
|
|
149
|
+
// 金额单位是分,展示需转元
|
|
150
|
+
money(amountInFen)
|
|
151
|
+
|
|
152
|
+
// 加密使用 SM4
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## 7. 数据库排查 SQL 模板
|
|
158
|
+
|
|
159
|
+
### 数据关联检查
|
|
160
|
+
|
|
161
|
+
```sql
|
|
162
|
+
SELECT a.*, b.*
|
|
163
|
+
FROM table_a a
|
|
164
|
+
LEFT JOIN table_b b ON a.id = b.a_id
|
|
165
|
+
WHERE a.id = ?;
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### 重复数据检查
|
|
169
|
+
|
|
170
|
+
```sql
|
|
171
|
+
SELECT id, COUNT(*) FROM 表 GROUP BY id HAVING COUNT(*) > 1;
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### 孤立数据检查
|
|
175
|
+
|
|
176
|
+
```sql
|
|
177
|
+
SELECT a.id FROM 主表 a
|
|
178
|
+
LEFT JOIN 子表 b ON a.id = b.主表id
|
|
179
|
+
WHERE b.id IS NULL;
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### 性能检查
|
|
183
|
+
|
|
184
|
+
```sql
|
|
185
|
+
-- 执行计划
|
|
186
|
+
EXPLAIN SELECT * FROM 表 WHERE 条件;
|
|
187
|
+
|
|
188
|
+
-- type: ALL(全表扫描需优化) | index | range | ref | const(最优)
|
|
189
|
+
|
|
190
|
+
-- 检查索引
|
|
191
|
+
SHOW INDEX FROM 表;
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## 8. 多数据库差异
|
|
197
|
+
|
|
198
|
+
| 功能 | MySQL | PostgreSQL |
|
|
199
|
+
|------|-------|------------|
|
|
200
|
+
| 分页 | `LIMIT 10` | `LIMIT 10` |
|
|
201
|
+
| 字符串连接 | `CONCAT()` | `||` |
|
|
202
|
+
| 当前时间 | `NOW()` | `NOW()` |
|
|
203
|
+
| 类型转换 | `CAST()` | `::` |
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## 9. Bean 注入失败排查
|
|
208
|
+
|
|
209
|
+
```java
|
|
210
|
+
// NoSuchBeanDefinitionException 排查步骤:
|
|
211
|
+
// 1. 检查是否有 @Service/@Component
|
|
212
|
+
@Service
|
|
213
|
+
public class XxxServiceImpl implements XxxService { ... }
|
|
214
|
+
|
|
215
|
+
// 2. 检查包路径(必须 net.xnzn.core.*)
|
|
216
|
+
package net.xnzn.core.xxx.service.impl;
|
|
217
|
+
|
|
218
|
+
// 3. 检查循环依赖(A->B->A)
|
|
219
|
+
// 4. 检查接口与实现类是否匹配
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## 10. 排查清单
|
|
225
|
+
|
|
226
|
+
### 后端
|
|
227
|
+
|
|
228
|
+
- [ ] 是否读取了日志文件 `./logs/sys-console.log`?
|
|
229
|
+
- [ ] 异常堆栈包名是否为 `net.xnzn.core.*`?
|
|
230
|
+
- [ ] Controller 路由前缀是否正确(`/api/v2/web|mobile|android/{module}`)?
|
|
231
|
+
- [ ] Service 是否直接注入 Mapper(无 DAO 层)?
|
|
232
|
+
- [ ] 非字符串字段是否使用了 eq/in/between 而不是 like?
|
|
233
|
+
- [ ] BeanUtil.copyProperties() 转换前是否判空?
|
|
234
|
+
- [ ] 双库切换是否正确(Executors.doInSystem/doInTenant)?
|
|
235
|
+
- [ ] del_flag 是否用 2=正常、1=删除?
|
|
236
|
+
- [ ] 数据库中是否真的存在需要的数据?
|
|
237
|
+
|
|
238
|
+
### 前端
|
|
239
|
+
|
|
240
|
+
- [ ] Network 中接口状态码和响应内容?
|
|
241
|
+
- [ ] 成功码是否判断 10000?
|
|
242
|
+
- [ ] Admin-Token 和 MERCHANT-ID 请求头是否正确?
|
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: check
|
|
3
|
+
description: |
|
|
4
|
+
当需要检查后端代码规范、验证代码质量时自动使用此 Skill。
|
|
5
|
+
|
|
6
|
+
触发场景:
|
|
7
|
+
- 开发完成后检查代码是否符合规范
|
|
8
|
+
- 代码审查前进行规范检查
|
|
9
|
+
- 检查包名、API路径、权限注解等规范
|
|
10
|
+
- 检查对象转换是否使用 MapstructUtils
|
|
11
|
+
|
|
12
|
+
触发词:代码检查、check、规范检查、代码规范、代码审查、包名检查、API检查、权限检查
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# /check - 后端代码规范检查
|
|
16
|
+
|
|
17
|
+
作为代码规范检查助手,自动检测项目代码是否符合 RuoYi-Vue-Plus 后端规范。
|
|
18
|
+
|
|
19
|
+
## 检查范围
|
|
20
|
+
|
|
21
|
+
支持三种检查模式:
|
|
22
|
+
|
|
23
|
+
1. **全量检查**:`/check` - 检查所有代码
|
|
24
|
+
2. **模块检查**:`/check system` - 检查指定模块
|
|
25
|
+
3. **文件检查**:`/check XxxServiceImpl.java` - 检查指定文件
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 检查清单总览
|
|
30
|
+
|
|
31
|
+
| 检查项 | 级别 | 说明 |
|
|
32
|
+
|--------|------|------|
|
|
33
|
+
| 包名规范 | 🔴 严重 | 必须是 `org.dromara.*` |
|
|
34
|
+
| 完整类型引用 | 🔴 严重 | 禁止内联全限定名,必须 import |
|
|
35
|
+
| API 路径规范 | 🔴 严重 | Controller 方法路径必须规范 |
|
|
36
|
+
| 权限注解检查 | 🟡 警告 | 必须使用 @SaCheckPermission |
|
|
37
|
+
| Service 接口 | 🟡 警告 | Service 接口必须有标准方法声明 |
|
|
38
|
+
| Entity 基类 | 🟡 警告 | 业务实体应继承 TenantEntity |
|
|
39
|
+
| BO 映射注解 | 🟡 警告 | 必须使用 @AutoMapper |
|
|
40
|
+
| 对象转换 | 🟡 警告 | 必须用 MapstructUtils,禁止 BeanUtil |
|
|
41
|
+
| Mapper 继承 | 🟢 建议 | 必须继承 BaseMapperPlus |
|
|
42
|
+
| Map 传递数据 | 🟢 建议 | 禁止用 Map 封装业务数据 |
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## 检查详情
|
|
47
|
+
|
|
48
|
+
### 1. 包名规范 [🔴 严重]
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# 检查错误包名
|
|
52
|
+
Grep pattern: "package com\.ruoyi\." path: ruoyi-modules/ output_mode: files_with_matches
|
|
53
|
+
Grep pattern: "import com\.ruoyi\." path: ruoyi-modules/ output_mode: files_with_matches
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
```java
|
|
57
|
+
// ❌ 错误
|
|
58
|
+
package com.ruoyi.system.service;
|
|
59
|
+
import com.ruoyi.common.core.domain.R;
|
|
60
|
+
|
|
61
|
+
// ✅ 正确
|
|
62
|
+
package org.dromara.system.service;
|
|
63
|
+
import org.dromara.common.core.domain.R;
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### 2. 完整类型引用 [🔴 严重]
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
# 检查完整类型引用
|
|
70
|
+
Grep pattern: "org\.dromara\.[a-z]+\.[A-Z][a-zA-Z]+\s" path: ruoyi-modules/ glob: "*.java" output_mode: content
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
```java
|
|
74
|
+
// ❌ 错误
|
|
75
|
+
public org.dromara.common.core.domain.R<XxxVo> getXxx(Long id) { ... }
|
|
76
|
+
|
|
77
|
+
// ✅ 正确
|
|
78
|
+
import org.dromara.common.core.domain.R;
|
|
79
|
+
public R<XxxVo> getXxx(Long id) { ... }
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### 3. API 路径规范 [🔴 严重]
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
# 检查 Controller 方法的路径规范
|
|
86
|
+
Grep pattern: "@(GetMapping|PostMapping|PutMapping|DeleteMapping)\(" path: ruoyi-modules/ glob: "*Controller.java" output_mode: content -C 1
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**规范要求**:
|
|
90
|
+
|
|
91
|
+
| 操作 | HTTP 方法 | 路径格式 | 示例 |
|
|
92
|
+
|------|---------|--------|------|
|
|
93
|
+
| 分页查询 | GET | `/list` 或 `/` 空路径 | `@GetMapping("/list")` |
|
|
94
|
+
| 获取详情 | GET | `/{id}` | `@GetMapping("/{id}")` |
|
|
95
|
+
| 新增 | POST | `/` 空路径 | `@PostMapping` |
|
|
96
|
+
| 修改 | PUT | `/` 空路径 | `@PutMapping` |
|
|
97
|
+
| 删除 | DELETE | `/{ids}` | `@DeleteMapping("/{ids}")` |
|
|
98
|
+
| 导出 | POST | `/export` | `@PostMapping("/export")` |
|
|
99
|
+
|
|
100
|
+
```java
|
|
101
|
+
// ❌ 错误(路径不规范)
|
|
102
|
+
@GetMapping("/queryList") // 应该用 /list
|
|
103
|
+
@PostMapping("/add") // POST 应该不加路径
|
|
104
|
+
@PutMapping("/update") // PUT 应该不加路径
|
|
105
|
+
|
|
106
|
+
// ✅ 正确
|
|
107
|
+
@GetMapping("/list")
|
|
108
|
+
@PostMapping
|
|
109
|
+
@PutMapping
|
|
110
|
+
@DeleteMapping("/{ids}")
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### 4. 权限注解检查 [🟡 警告]
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
# 检查 Controller 是否使用权限注解
|
|
117
|
+
Grep pattern: "@SaCheckPermission" path: ruoyi-modules/ glob: "*Controller.java" output_mode: files_with_matches
|
|
118
|
+
Grep pattern: "public.*\(.*\)\s*\{" path: ruoyi-modules/ glob: "*Controller.java" output_mode: content -B 1
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
**规范要求**:Controller 的所有公开接口都必须添加 `@SaCheckPermission` 注解
|
|
122
|
+
|
|
123
|
+
```java
|
|
124
|
+
// ❌ 错误(缺少权限注解)
|
|
125
|
+
@GetMapping("/list")
|
|
126
|
+
public TableDataInfo<XxxVo> list(XxxBo bo, PageQuery pageQuery) {
|
|
127
|
+
return service.queryPageList(bo, pageQuery);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// ✅ 正确
|
|
131
|
+
@SaCheckPermission("xxx:list")
|
|
132
|
+
@GetMapping("/list")
|
|
133
|
+
public TableDataInfo<XxxVo> list(XxxBo bo, PageQuery pageQuery) {
|
|
134
|
+
return service.queryPageList(bo, pageQuery);
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### 5. Service 接口 [🟡 警告]
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
# 检查 Service 接口是否声明标准方法
|
|
142
|
+
Grep pattern: "public interface I.*Service" path: ruoyi-modules/ glob: "*Service.java" output_mode: files_with_matches
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
**规范要求**:Service 接口必须声明以下标准方法
|
|
146
|
+
|
|
147
|
+
```java
|
|
148
|
+
// ✅ 正确
|
|
149
|
+
public interface IXxxService {
|
|
150
|
+
XxxVo queryById(Long id);
|
|
151
|
+
TableDataInfo<XxxVo> queryPageList(XxxBo bo, PageQuery pageQuery);
|
|
152
|
+
List<XxxVo> queryList(XxxBo bo);
|
|
153
|
+
Boolean insertByBo(XxxBo bo);
|
|
154
|
+
Boolean updateByBo(XxxBo bo);
|
|
155
|
+
Boolean deleteByIds(Collection<Long> ids);
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### 6. Entity 基类 [🟡 警告]
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
# 检查业务实体是否继承 TenantEntity
|
|
163
|
+
Grep pattern: "extends TenantEntity" path: ruoyi-modules/ glob: "*.java" output_mode: files_with_matches
|
|
164
|
+
Grep pattern: "extends BaseEntity" path: ruoyi-modules/ glob: "*.java" output_mode: files_with_matches
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
```java
|
|
168
|
+
// ⚠️ 普通实体(非多租户)
|
|
169
|
+
public class SysNotice extends BaseEntity { }
|
|
170
|
+
|
|
171
|
+
// ✅ 业务实体(多租户)
|
|
172
|
+
public class XxxEntity extends TenantEntity { }
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### 7. BO 映射注解 [🟡 警告]
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
# 检查 BO 是否使用 @AutoMapper
|
|
179
|
+
Grep pattern: "@AutoMapper" path: ruoyi-modules/ glob: "*Bo.java" output_mode: files_with_matches
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
```java
|
|
183
|
+
// ❌ 错误
|
|
184
|
+
public class XxxBo extends BaseEntity { }
|
|
185
|
+
|
|
186
|
+
// ✅ 正确
|
|
187
|
+
@AutoMapper(target = Xxx.class, reverseConvertGenerate = false)
|
|
188
|
+
public class XxxBo extends BaseEntity { }
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### 8. 对象转换 [🟡 警告]
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
# 检查是否使用 BeanUtil
|
|
195
|
+
Grep pattern: "BeanUtil\.copy" path: ruoyi-modules/ output_mode: files_with_matches
|
|
196
|
+
Grep pattern: "BeanUtils\.copy" path: ruoyi-modules/ output_mode: files_with_matches
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
```java
|
|
200
|
+
// ❌ 错误
|
|
201
|
+
BeanUtil.copyProperties(bo, entity);
|
|
202
|
+
BeanUtils.copyProperties(source, target);
|
|
203
|
+
|
|
204
|
+
// ✅ 正确
|
|
205
|
+
XxxVo vo = MapstructUtils.convert(entity, XxxVo.class);
|
|
206
|
+
List<XxxVo> voList = MapstructUtils.convert(entityList, XxxVo.class);
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### 9. Mapper 继承 [🟢 建议]
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
Grep pattern: "extends BaseMapperPlus" path: ruoyi-modules/ output_mode: files_with_matches
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
```java
|
|
216
|
+
// ✅ 正确
|
|
217
|
+
public interface XxxMapper extends BaseMapperPlus<Xxx, XxxVo> { }
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### 10. Map 传递数据 [🟢 建议]
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
Grep pattern: "Map<String,\s*Object>" path: ruoyi-modules/ glob: "*Service*.java" output_mode: files_with_matches
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
```java
|
|
227
|
+
// ❌ 错误
|
|
228
|
+
public Map<String, Object> getXxx(Long id) {
|
|
229
|
+
Map<String, Object> result = new HashMap<>();
|
|
230
|
+
result.put("id", entity.getId());
|
|
231
|
+
return result;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// ✅ 正确(创建 VO 类)
|
|
235
|
+
public XxxVo getXxx(Long id) {
|
|
236
|
+
return MapstructUtils.convert(entity, XxxVo.class);
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## 输出格式
|
|
243
|
+
|
|
244
|
+
```markdown
|
|
245
|
+
# 🔍 代码规范检查报告
|
|
246
|
+
|
|
247
|
+
**检查时间**:YYYY-MM-DD HH:mm
|
|
248
|
+
**检查范围**:[全量 / 模块名 / 文件名]
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## 📋 检查结果汇总
|
|
253
|
+
|
|
254
|
+
| 类别 | 通过 | 警告 | 错误 |
|
|
255
|
+
|------|------|------|------|
|
|
256
|
+
| 后端 Java | X | X | X |
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## 🔴 严重问题(必须修复)
|
|
261
|
+
|
|
262
|
+
### 1. [问题类型]
|
|
263
|
+
|
|
264
|
+
**文件**:`path/to/file.java:42`
|
|
265
|
+
**问题**:包名使用了 com.ruoyi
|
|
266
|
+
**代码**:
|
|
267
|
+
\```java
|
|
268
|
+
package com.ruoyi.system.service;
|
|
269
|
+
\```
|
|
270
|
+
**修复**:
|
|
271
|
+
\```java
|
|
272
|
+
package org.dromara.system.service;
|
|
273
|
+
\```
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
## 🟡 警告问题(建议修复)
|
|
278
|
+
|
|
279
|
+
### 1. [问题类型]
|
|
280
|
+
...
|
|
281
|
+
|
|
282
|
+
---
|
|
283
|
+
|
|
284
|
+
## 🟢 建议优化
|
|
285
|
+
|
|
286
|
+
### 1. [优化建议]
|
|
287
|
+
...
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
## ✅ 检查通过项
|
|
292
|
+
|
|
293
|
+
- [x] 包名规范
|
|
294
|
+
- [x] 对象转换
|
|
295
|
+
- ...
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
## 检查优先级
|
|
301
|
+
|
|
302
|
+
### 开发完成后必查(阻塞提交)
|
|
303
|
+
|
|
304
|
+
1. 包名是否是 `org.dromara.*`
|
|
305
|
+
2. 是否有完整类型引用(内联全限定名)
|
|
306
|
+
3. API 路径是否规范
|
|
307
|
+
4. 对象转换是否使用 MapstructUtils
|
|
308
|
+
5. 权限注解是否完整
|
|
309
|
+
|
|
310
|
+
### 代码审查建议查
|
|
311
|
+
|
|
312
|
+
1. Service 接口是否有标准方法声明
|
|
313
|
+
2. BO 是否有 @AutoMapper
|
|
314
|
+
3. Entity 是否继承正确的基类
|
|
315
|
+
4. Mapper 是否继承 BaseMapperPlus
|
|
316
|
+
5. 是否有冗余的 Map 传递
|
|
317
|
+
|
|
318
|
+
---
|
|
319
|
+
|
|
320
|
+
## 快速修复指南
|
|
321
|
+
|
|
322
|
+
### 包名错误修复
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
# 查找所有错误包名
|
|
326
|
+
Grep pattern: "package com\.ruoyi\." path: ruoyi-modules/ output_mode: files_with_matches
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
批量替换:`com.ruoyi` → `org.dromara`
|
|
330
|
+
|
|
331
|
+
### API 路径修复
|
|
332
|
+
|
|
333
|
+
| 错误写法 | 正确写法 | 说明 |
|
|
334
|
+
|---------|--------|------|
|
|
335
|
+
| `@GetMapping("/queryList")` | `@GetMapping("/list")` | 列表查询统一用 /list |
|
|
336
|
+
| `@PostMapping("/add")` | `@PostMapping` | POST 新增不加路径 |
|
|
337
|
+
| `@PutMapping("/update")` | `@PutMapping` | PUT 修改不加路径 |
|
|
338
|
+
| `@GetMapping` | `@GetMapping("/{id}")` | 单条查询必须加 ID 参数 |
|
|
339
|
+
|
|
340
|
+
### 权限注解修复
|
|
341
|
+
|
|
342
|
+
```java
|
|
343
|
+
// 快速修复模板
|
|
344
|
+
@SaCheckPermission("模块:功能:操作")
|
|
345
|
+
@GetMapping("/list")
|
|
346
|
+
public TableDataInfo<XxxVo> list(...) { ... }
|
|
347
|
+
|
|
348
|
+
// 权限标识符格式
|
|
349
|
+
// system:notice:list - 系统模块的通知管理-列表权限
|
|
350
|
+
// demo:xxx:add - demo 模块的 xxx 功能-新增权限
|
|
351
|
+
// 模块:功能:操作 - [模块]:[功能]:[操作]
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
### 对象转换修复
|
|
355
|
+
|
|
356
|
+
| 替换前 | 替换后 |
|
|
357
|
+
|--------|--------|
|
|
358
|
+
| `BeanUtil.copyProperties(a, b)` | `MapstructUtils.convert(a, B.class)` |
|
|
359
|
+
| `BeanUtils.copyProperties(a, b)` | `MapstructUtils.convert(a, B.class)` |
|
|
360
|
+
| `new HashMap<>()` (传递业务数据) | 创建专属 VO 类 |
|
|
361
|
+
|
|
362
|
+
---
|
|
363
|
+
|
|
364
|
+
## 参考
|
|
365
|
+
|
|
366
|
+
- 正确后端代码:`ruoyi-system/.../controller/system/SysNoticeController.java`
|
|
367
|
+
- 正确 Service 代码:`ruoyi-system/.../service/impl/SysNoticeServiceImpl.java`
|