ai-engineering-init 1.7.0 → 1.10.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/.claude/agents/bug-analyzer.md +103 -0
- package/.claude/agents/code-reviewer.md +115 -5
- package/.claude/agents/image-reader.md +154 -0
- package/.claude/agents/loki-runner.md +80 -0
- package/.claude/agents/mysql-runner.md +81 -0
- package/.claude/agents/requirements-analyzer.md +162 -0
- package/.claude/agents/task-fetcher.md +75 -0
- package/.claude/commands/dev.md +29 -0
- package/.claude/commands/next.md +31 -1
- package/.claude/commands/progress.md +23 -1
- package/.claude/hooks/skill-forced-eval.js +46 -62
- package/.claude/settings.json +10 -1
- package/.claude/skills/api-development/SKILL.md +179 -130
- package/.claude/skills/architecture-design/SKILL.md +102 -212
- package/.claude/skills/backend-annotations/SKILL.md +166 -220
- package/.claude/skills/bug-detective/SKILL.md +225 -186
- package/.claude/skills/code-patterns/SKILL.md +127 -244
- package/.claude/skills/collaborating-with-codex/SKILL.md +96 -113
- package/.claude/skills/crud-development/SKILL.md +226 -307
- package/.claude/skills/data-permission/SKILL.md +131 -202
- package/.claude/skills/database-ops/SKILL.md +158 -355
- package/.claude/skills/error-handler/SKILL.md +224 -285
- package/.claude/skills/file-oss-management/SKILL.md +174 -169
- package/.claude/skills/git-workflow/SKILL.md +123 -341
- package/.claude/skills/json-serialization/SKILL.md +121 -137
- package/.claude/skills/performance-doctor/SKILL.md +83 -89
- package/.claude/skills/redis-cache/SKILL.md +134 -185
- package/.claude/skills/scheduled-jobs/SKILL.md +187 -224
- package/.claude/skills/security-guard/SKILL.md +168 -276
- package/.claude/skills/sms-mail/SKILL.md +266 -228
- package/.claude/skills/social-login/SKILL.md +257 -195
- package/.claude/skills/tenant-management/SKILL.md +172 -188
- package/.claude/skills/utils-toolkit/SKILL.md +214 -222
- package/.claude/skills/websocket-sse/SKILL.md +251 -172
- package/.claude/skills/workflow-engine/SKILL.md +178 -250
- package/.codex/skills/api-development/SKILL.md +179 -130
- package/.codex/skills/architecture-design/SKILL.md +102 -212
- package/.codex/skills/backend-annotations/SKILL.md +166 -220
- package/.codex/skills/bug-detective/SKILL.md +225 -186
- package/.codex/skills/code-patterns/SKILL.md +127 -244
- package/.codex/skills/collaborating-with-codex/SKILL.md +96 -113
- package/.codex/skills/crud-development/SKILL.md +226 -307
- package/.codex/skills/data-permission/SKILL.md +131 -202
- package/.codex/skills/database-ops/SKILL.md +158 -355
- package/.codex/skills/dev/SKILL.md +476 -131
- package/.codex/skills/error-handler/SKILL.md +224 -285
- package/.codex/skills/file-oss-management/SKILL.md +174 -169
- package/.codex/skills/git-workflow/SKILL.md +123 -341
- package/.codex/skills/json-serialization/SKILL.md +121 -137
- package/.codex/skills/next/SKILL.md +186 -42
- package/.codex/skills/performance-doctor/SKILL.md +83 -89
- package/.codex/skills/progress/SKILL.md +147 -76
- package/.codex/skills/redis-cache/SKILL.md +134 -185
- package/.codex/skills/scheduled-jobs/SKILL.md +187 -224
- package/.codex/skills/security-guard/SKILL.md +168 -276
- package/.codex/skills/sms-mail/SKILL.md +266 -228
- package/.codex/skills/social-login/SKILL.md +257 -195
- package/.codex/skills/tenant-management/SKILL.md +172 -188
- package/.codex/skills/utils-toolkit/SKILL.md +214 -222
- package/.codex/skills/websocket-sse/SKILL.md +251 -172
- package/.codex/skills/workflow-engine/SKILL.md +178 -250
- package/.cursor/agents/bug-analyzer.md +102 -0
- package/.cursor/agents/code-reviewer.md +80 -97
- package/.cursor/agents/image-reader.md +154 -0
- package/.cursor/agents/loki-runner.md +80 -0
- package/.cursor/agents/mysql-runner.md +81 -0
- package/.cursor/agents/project-manager.md +1 -1
- package/.cursor/agents/requirements-analyzer.md +141 -0
- package/.cursor/agents/task-fetcher.md +75 -0
- package/.cursor/hooks/cursor-skill-eval.js +66 -6
- package/.cursor/skills/api-development/SKILL.md +179 -130
- package/.cursor/skills/architecture-design/SKILL.md +102 -212
- package/.cursor/skills/backend-annotations/SKILL.md +166 -220
- package/.cursor/skills/bug-detective/SKILL.md +225 -186
- package/.cursor/skills/code-patterns/SKILL.md +127 -244
- package/.cursor/skills/collaborating-with-codex/SKILL.md +96 -113
- package/.cursor/skills/crud-development/SKILL.md +226 -307
- package/.cursor/skills/data-permission/SKILL.md +131 -202
- package/.cursor/skills/database-ops/SKILL.md +158 -355
- package/.cursor/skills/error-handler/SKILL.md +224 -285
- package/.cursor/skills/file-oss-management/SKILL.md +174 -169
- package/.cursor/skills/git-workflow/SKILL.md +123 -341
- package/.cursor/skills/json-serialization/SKILL.md +121 -137
- package/.cursor/skills/performance-doctor/SKILL.md +83 -89
- package/.cursor/skills/redis-cache/SKILL.md +134 -185
- package/.cursor/skills/scheduled-jobs/SKILL.md +187 -224
- package/.cursor/skills/security-guard/SKILL.md +168 -276
- package/.cursor/skills/sms-mail/SKILL.md +266 -228
- package/.cursor/skills/social-login/SKILL.md +257 -195
- package/.cursor/skills/tenant-management/SKILL.md +172 -188
- package/.cursor/skills/utils-toolkit/SKILL.md +214 -222
- package/.cursor/skills/websocket-sse/SKILL.md +251 -172
- package/.cursor/skills/workflow-engine/SKILL.md +178 -250
- package/AGENTS.md +117 -540
- package/CLAUDE.md +105 -117
- package/README.md +37 -6
- package/bin/index.js +5 -1
- package/package.json +1 -1
- package/src/skills/api-development/SKILL.md +179 -130
- package/src/skills/architecture-design/SKILL.md +102 -212
- package/src/skills/backend-annotations/SKILL.md +166 -220
- package/src/skills/bug-detective/SKILL.md +225 -186
- package/src/skills/code-patterns/SKILL.md +127 -244
- package/src/skills/collaborating-with-codex/SKILL.md +96 -113
- package/src/skills/crud-development/SKILL.md +226 -307
- package/src/skills/data-permission/SKILL.md +131 -202
- package/src/skills/database-ops/SKILL.md +158 -355
- package/src/skills/error-handler/SKILL.md +224 -285
- package/src/skills/file-oss-management/SKILL.md +174 -169
- package/src/skills/git-workflow/SKILL.md +123 -341
- package/src/skills/json-serialization/SKILL.md +121 -137
- package/src/skills/performance-doctor/SKILL.md +83 -89
- package/src/skills/redis-cache/SKILL.md +134 -185
- package/src/skills/scheduled-jobs/SKILL.md +187 -224
- package/src/skills/security-guard/SKILL.md +168 -276
- package/src/skills/sms-mail/SKILL.md +266 -228
- package/src/skills/social-login/SKILL.md +257 -195
- package/src/skills/tenant-management/SKILL.md +172 -188
- package/src/skills/utils-toolkit/SKILL.md +214 -222
- package/src/skills/websocket-sse/SKILL.md +251 -172
- package/src/skills/workflow-engine/SKILL.md +178 -250
- package/.claude/skills/skill-creator/LICENSE.txt +0 -202
- package/.claude/skills/skill-creator/SKILL.md +0 -479
- package/.claude/skills/skill-creator/agents/analyzer.md +0 -274
- package/.claude/skills/skill-creator/agents/comparator.md +0 -202
- package/.claude/skills/skill-creator/agents/grader.md +0 -223
- package/.claude/skills/skill-creator/assets/eval_review.html +0 -146
- package/.claude/skills/skill-creator/eval-viewer/generate_review.py +0 -471
- package/.claude/skills/skill-creator/eval-viewer/viewer.html +0 -1325
- package/.claude/skills/skill-creator/references/schemas.md +0 -430
- package/.claude/skills/skill-creator/scripts/__init__.py +0 -0
- package/.claude/skills/skill-creator/scripts/aggregate_benchmark.py +0 -401
- package/.claude/skills/skill-creator/scripts/generate_report.py +0 -326
- package/.claude/skills/skill-creator/scripts/improve_description.py +0 -248
- package/.claude/skills/skill-creator/scripts/package_skill.py +0 -136
- package/.claude/skills/skill-creator/scripts/quick_validate.py +0 -103
- package/.claude/skills/skill-creator/scripts/run_eval.py +0 -310
- package/.claude/skills/skill-creator/scripts/run_loop.py +0 -332
- package/.claude/skills/skill-creator/scripts/utils.py +0 -47
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: task-fetcher
|
|
3
|
+
description: 获取云效任务信息并整理为结构化清单。当需要查看任务状态、同步需求、读取工作项时使用。仅做数据获取和整理,不做需求分析。
|
|
4
|
+
model: fast
|
|
5
|
+
readonly: true
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
你是云效任务获取助手。你的唯一职责是:**调用云效 API 获取任务数据并格式化返回**。不要分析需求,不要给出实现建议。
|
|
9
|
+
|
|
10
|
+
## 配置读取
|
|
11
|
+
|
|
12
|
+
从 `.claude/settings.json` 的 `mcpServers.yunxiao.env` 中读取 Token:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
TOKEN=$(python3 -c "
|
|
16
|
+
import json
|
|
17
|
+
s = json.load(open('$CLAUDE_PROJECT_DIR/.claude/settings.json'))
|
|
18
|
+
print(s.get('mcpServers',{}).get('yunxiao',{}).get('env',{}).get('YUNXIAO_ACCESS_TOKEN',''))
|
|
19
|
+
")
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## 已知信息
|
|
23
|
+
|
|
24
|
+
- 组织 ID: `61dbcd725356b19beeb1dc03`
|
|
25
|
+
- 用户: 徐嘉骏(ID: `66286d4b06679a65daed4d28`)
|
|
26
|
+
- 常用项目: SARW(`4574cb1c653fe873335b6c4716`)、EZML(`6f99a4e627fa88d6f8cb541e6c`)
|
|
27
|
+
- Base URL: `https://openapi-rdc.aliyuncs.com`
|
|
28
|
+
|
|
29
|
+
## API 调用模板
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# 通用请求
|
|
33
|
+
curl -s "https://openapi-rdc.aliyuncs.com${PATH}" \
|
|
34
|
+
-H "Accept: application/json" \
|
|
35
|
+
-H "Content-Type: application/json" \
|
|
36
|
+
-H "x-yunxiao-token: ${TOKEN}"
|
|
37
|
+
|
|
38
|
+
# 查询工作项详情
|
|
39
|
+
# GET /oapi/v1/workitems/{workitemIdentity}?organizationId={orgId}
|
|
40
|
+
|
|
41
|
+
# 搜索工作项
|
|
42
|
+
# GET /oapi/v1/workitems?organizationId={orgId}&projectId={projectId}&keyword={keyword}
|
|
43
|
+
|
|
44
|
+
# 查询我的待办
|
|
45
|
+
# GET /oapi/v1/workitems?organizationId={orgId}&assignedTo={userId}&status=开发中,待处理
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## 输出格式(严格遵守)
|
|
49
|
+
|
|
50
|
+
```markdown
|
|
51
|
+
## 云效任务信息
|
|
52
|
+
|
|
53
|
+
**项目**: [项目名]
|
|
54
|
+
**查询时间**: [时间]
|
|
55
|
+
|
|
56
|
+
### 任务列表
|
|
57
|
+
|
|
58
|
+
| 编号 | 标题 | 状态 | 负责人 | 优先级 | 截止日期 |
|
|
59
|
+
|------|------|------|--------|--------|---------|
|
|
60
|
+
| SARW-123 | xxx | 开发中 | 徐嘉骏 | P1 | 2026-03-15 |
|
|
61
|
+
|
|
62
|
+
### 任务详情(如查询单个任务)
|
|
63
|
+
|
|
64
|
+
- **标题**: [标题]
|
|
65
|
+
- **描述**: [描述内容]
|
|
66
|
+
- **状态**: [状态]
|
|
67
|
+
- **子任务**: [子任务列表]
|
|
68
|
+
- **评论**: [最近评论]
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## 约束
|
|
72
|
+
|
|
73
|
+
- 只获取数据,不分析需求
|
|
74
|
+
- 只格式化,不给实现建议
|
|
75
|
+
- Token 不存在时明确说"缺少云效 Token 配置"
|
|
@@ -222,11 +222,11 @@ const skillMap = [
|
|
|
222
222
|
},
|
|
223
223
|
{
|
|
224
224
|
name: 'backend-annotations',
|
|
225
|
-
keywords: ['
|
|
225
|
+
keywords: ['注解', '限流', '防重复', '脱敏', '加密注解', 'AOP注解']
|
|
226
226
|
},
|
|
227
227
|
{
|
|
228
228
|
name: 'utils-toolkit',
|
|
229
|
-
keywords: ['
|
|
229
|
+
keywords: ['工具类', '对象转换', '字符串工具', '集合工具', '日期工具', 'BeanUtils']
|
|
230
230
|
},
|
|
231
231
|
{
|
|
232
232
|
name: 'file-oss-management',
|
|
@@ -238,7 +238,7 @@ const skillMap = [
|
|
|
238
238
|
},
|
|
239
239
|
{
|
|
240
240
|
name: 'error-handler',
|
|
241
|
-
keywords: ['异常处理', '
|
|
241
|
+
keywords: ['异常处理', '全局异常', '业务异常', '参数校验异常', '@RestControllerAdvice']
|
|
242
242
|
},
|
|
243
243
|
{
|
|
244
244
|
name: 'performance-doctor',
|
|
@@ -250,7 +250,7 @@ const skillMap = [
|
|
|
250
250
|
},
|
|
251
251
|
{
|
|
252
252
|
name: 'security-guard',
|
|
253
|
-
keywords: ['
|
|
253
|
+
keywords: ['安全', '认证授权', '加密', 'XSS', 'SQL注入', '数据脱敏', 'Spring Security']
|
|
254
254
|
},
|
|
255
255
|
{
|
|
256
256
|
name: 'architecture-design',
|
|
@@ -298,7 +298,7 @@ const skillMap = [
|
|
|
298
298
|
},
|
|
299
299
|
{
|
|
300
300
|
name: 'scheduled-jobs',
|
|
301
|
-
keywords: ['定时任务', '
|
|
301
|
+
keywords: ['定时任务', '@Scheduled', 'Quartz', 'XXL-Job', '任务调度', '重试机制']
|
|
302
302
|
},
|
|
303
303
|
{
|
|
304
304
|
name: 'websocket-sse',
|
|
@@ -314,7 +314,7 @@ const skillMap = [
|
|
|
314
314
|
},
|
|
315
315
|
{
|
|
316
316
|
name: 'tenant-management',
|
|
317
|
-
keywords: ['多租户', '租户隔离', '
|
|
317
|
+
keywords: ['多租户', '租户隔离', 'tenantId', '跨租户', 'SaaS', '数据隔离']
|
|
318
318
|
},
|
|
319
319
|
{
|
|
320
320
|
name: 'ui-pc',
|
|
@@ -332,6 +332,10 @@ const skillMap = [
|
|
|
332
332
|
name: 'banana-image',
|
|
333
333
|
keywords: ['生成图片', 'AI图片', '产品图', '海报', '缩略图', '4K图片', '高清图', '制作图片', '/image']
|
|
334
334
|
},
|
|
335
|
+
{
|
|
336
|
+
name: 'codex-code-review',
|
|
337
|
+
keywords: ['代码审查', 'code review', 'review代码', '代码检查', 'codex审查']
|
|
338
|
+
},
|
|
335
339
|
{
|
|
336
340
|
name: 'collaborating-with-codex',
|
|
337
341
|
keywords: ['codex协作', '委托codex', 'openai codex', 'codex分析', '多模型协作', '让codex']
|
|
@@ -365,6 +369,62 @@ const skillMap = [
|
|
|
365
369
|
name: 'openspec-onboard',
|
|
366
370
|
keywords: ['openspec入门', 'opsx:onboard', 'openspec onboard', 'openspec教程',
|
|
367
371
|
'openspec新手', '学习openspec工作流']
|
|
372
|
+
},
|
|
373
|
+
{
|
|
374
|
+
name: 'loki-log-query',
|
|
375
|
+
keywords: ['Loki', '日志查询', '线上日志', 'Loki日志', '日志排查', 'LogQL']
|
|
376
|
+
},
|
|
377
|
+
{
|
|
378
|
+
name: 'yunxiao-task-management',
|
|
379
|
+
keywords: ['云效', '任务管理', '需求管理', '云效任务', 'yunxiao', '迭代管理']
|
|
380
|
+
},
|
|
381
|
+
{
|
|
382
|
+
name: 'crud',
|
|
383
|
+
keywords: ['快速CRUD', 'CRUD生成', '脚手架生成', '/crud']
|
|
384
|
+
},
|
|
385
|
+
{
|
|
386
|
+
name: 'dev',
|
|
387
|
+
keywords: ['开发新功能', '功能开发', '/dev', '新建功能']
|
|
388
|
+
},
|
|
389
|
+
{
|
|
390
|
+
name: 'check',
|
|
391
|
+
keywords: ['代码检查', '规范检查', '/check', '代码审查规范']
|
|
392
|
+
},
|
|
393
|
+
{
|
|
394
|
+
name: 'start',
|
|
395
|
+
keywords: ['项目启动', '初始化项目', '/start', '开始项目']
|
|
396
|
+
},
|
|
397
|
+
{
|
|
398
|
+
name: 'next',
|
|
399
|
+
keywords: ['下一步', '接下来', '/next', '继续做什么']
|
|
400
|
+
},
|
|
401
|
+
{
|
|
402
|
+
name: 'progress',
|
|
403
|
+
keywords: ['进度查看', '当前进度', '/progress', '任务进度']
|
|
404
|
+
},
|
|
405
|
+
{
|
|
406
|
+
name: 'sync',
|
|
407
|
+
keywords: ['同步代码', '代码同步', '/sync', '同步分支']
|
|
408
|
+
},
|
|
409
|
+
{
|
|
410
|
+
name: 'sync-back-merge',
|
|
411
|
+
keywords: ['回合并', 'sync back merge', '主分支同步', '回合主分支']
|
|
412
|
+
},
|
|
413
|
+
{
|
|
414
|
+
name: 'init-docs',
|
|
415
|
+
keywords: ['初始化文档', '项目文档', '生成文档', '/init-docs']
|
|
416
|
+
},
|
|
417
|
+
{
|
|
418
|
+
name: 'add-todo',
|
|
419
|
+
keywords: ['添加待办', '新增TODO', '任务添加', '/add-todo']
|
|
420
|
+
},
|
|
421
|
+
{
|
|
422
|
+
name: 'update-status',
|
|
423
|
+
keywords: ['更新状态', '状态变更', '修改状态', '/update-status']
|
|
424
|
+
},
|
|
425
|
+
{
|
|
426
|
+
name: 'skill-creator',
|
|
427
|
+
keywords: ['创建技能', '技能模板', '技能脚手架', 'skill scaffold', '新建skill']
|
|
368
428
|
}
|
|
369
429
|
];
|
|
370
430
|
|
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: api-development
|
|
3
3
|
description: |
|
|
4
|
-
后端 API
|
|
4
|
+
后端 API 接口设计规范。基于 Spring Boot 的 RESTful API 开发指南。
|
|
5
5
|
|
|
6
6
|
触发场景:
|
|
7
7
|
- 设计 RESTful API 接口
|
|
8
8
|
- 编写 Controller 层代码
|
|
9
|
-
-
|
|
9
|
+
- 配置接口权限、日志注解
|
|
10
10
|
- 接口返回值类型选择
|
|
11
11
|
- 数据验证和参数校验
|
|
12
12
|
|
|
13
13
|
触发词:API、接口、RESTful、Controller、GetMapping、PostMapping、权限注解、日志注解、分页查询、接口规范
|
|
14
14
|
|
|
15
15
|
注意:
|
|
16
|
-
-
|
|
17
|
-
- 参考 java-controller 技能获取更详细的 Controller 层规范
|
|
16
|
+
- 参考项目实际架构层次选择合适的分层模式
|
|
18
17
|
---
|
|
19
18
|
|
|
20
19
|
# API 接口设计规范
|
|
@@ -23,22 +22,22 @@ description: |
|
|
|
23
22
|
|
|
24
23
|
| 原则 | 说明 |
|
|
25
24
|
|------|------|
|
|
26
|
-
|
|
|
25
|
+
| RESTful 风格 | 使用标准 HTTP 方法表达语义 |
|
|
27
26
|
| 认证保护 | 所有业务接口必须添加认证注解 |
|
|
28
27
|
| 参数校验 | 使用分组校验区分新增/修改场景 |
|
|
29
28
|
| 统一响应 | 使用统一的响应格式包装返回数据 |
|
|
30
29
|
|
|
31
30
|
### HTTP 方法规范
|
|
32
31
|
|
|
33
|
-
| 操作 | 方法 |
|
|
34
|
-
|
|
35
|
-
| 列表查询 |
|
|
36
|
-
| 获取详情 |
|
|
37
|
-
| 新增 | POST | `/add` |
|
|
38
|
-
| 修改 |
|
|
39
|
-
| 删除 |
|
|
32
|
+
| 操作 | 方法 | 路径示例 |
|
|
33
|
+
|------|------|---------|
|
|
34
|
+
| 列表查询 | GET | `/list` 或 `/page` |
|
|
35
|
+
| 获取详情 | GET | `/{id}` |
|
|
36
|
+
| 新增 | POST | `/` 或 `/add` |
|
|
37
|
+
| 修改 | PUT | `/` 或 `/update` |
|
|
38
|
+
| 删除 | DELETE | `/{ids}` |
|
|
40
39
|
| 导出 | POST | `/export` |
|
|
41
|
-
| 导入 | POST | `/import
|
|
40
|
+
| 导入 | POST | `/import` |
|
|
42
41
|
|
|
43
42
|
---
|
|
44
43
|
|
|
@@ -47,65 +46,106 @@ description: |
|
|
|
47
46
|
```java
|
|
48
47
|
@Slf4j
|
|
49
48
|
@RestController
|
|
50
|
-
@
|
|
51
|
-
@RequestMapping("/
|
|
52
|
-
@Api(value = "模块/功能", tags = "模块/功能")
|
|
49
|
+
@RequiredArgsConstructor
|
|
50
|
+
@RequestMapping("/api/v1/[模块]/[功能]")
|
|
53
51
|
public class XxxController {
|
|
54
52
|
|
|
55
|
-
|
|
56
|
-
private XxxService xxxService;
|
|
53
|
+
private final XxxService xxxService;
|
|
57
54
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
55
|
+
/**
|
|
56
|
+
* 分页查询
|
|
57
|
+
*/
|
|
58
|
+
@GetMapping("/page")
|
|
59
|
+
public Result<PageResult<XxxVO>> page(XxxQueryDTO query) {
|
|
60
|
+
return Result.ok(xxxService.pageList(query));
|
|
62
61
|
}
|
|
63
62
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
63
|
+
/**
|
|
64
|
+
* 获取详情
|
|
65
|
+
*/
|
|
66
|
+
@GetMapping("/{id}")
|
|
67
|
+
public Result<XxxVO> getById(@PathVariable Long id) {
|
|
68
|
+
return Result.ok(xxxService.getById(id));
|
|
68
69
|
}
|
|
69
70
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
/**
|
|
72
|
+
* 新增
|
|
73
|
+
*/
|
|
74
|
+
@PostMapping
|
|
75
|
+
public Result<Long> add(@Validated(InsertGroup.class) @RequestBody XxxDTO dto) {
|
|
76
|
+
return Result.ok(xxxService.add(dto));
|
|
74
77
|
}
|
|
75
78
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
79
|
+
/**
|
|
80
|
+
* 修改
|
|
81
|
+
*/
|
|
82
|
+
@PutMapping
|
|
83
|
+
public Result<Void> update(@Validated(UpdateGroup.class) @RequestBody XxxDTO dto) {
|
|
84
|
+
xxxService.update(dto);
|
|
85
|
+
return Result.ok();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* 删除
|
|
90
|
+
*/
|
|
91
|
+
@DeleteMapping("/{ids}")
|
|
92
|
+
public Result<Void> delete(@PathVariable List<Long> ids) {
|
|
93
|
+
xxxService.deleteByIds(ids);
|
|
94
|
+
return Result.ok();
|
|
80
95
|
}
|
|
81
96
|
}
|
|
82
97
|
```
|
|
83
98
|
|
|
84
99
|
---
|
|
85
100
|
|
|
86
|
-
##
|
|
101
|
+
## 统一响应封装
|
|
87
102
|
|
|
88
|
-
###
|
|
103
|
+
### Result 包装类(通用模式)
|
|
89
104
|
|
|
90
105
|
```java
|
|
91
|
-
@
|
|
92
|
-
public
|
|
93
|
-
|
|
106
|
+
@Data
|
|
107
|
+
public class Result<T> {
|
|
108
|
+
private int code;
|
|
109
|
+
private String message;
|
|
110
|
+
private T data;
|
|
111
|
+
|
|
112
|
+
public static <T> Result<T> ok() {
|
|
113
|
+
return ok(null);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
public static <T> Result<T> ok(T data) {
|
|
117
|
+
Result<T> result = new Result<>();
|
|
118
|
+
result.setCode(200);
|
|
119
|
+
result.setMessage("success");
|
|
120
|
+
result.setData(data);
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
public static <T> Result<T> fail(String message) {
|
|
125
|
+
Result<T> result = new Result<>();
|
|
126
|
+
result.setCode(500);
|
|
127
|
+
result.setMessage(message);
|
|
128
|
+
return result;
|
|
129
|
+
}
|
|
94
130
|
}
|
|
95
131
|
```
|
|
96
132
|
|
|
97
|
-
###
|
|
133
|
+
### 分页响应
|
|
98
134
|
|
|
99
135
|
```java
|
|
100
136
|
@Data
|
|
101
|
-
public class
|
|
102
|
-
|
|
103
|
-
private
|
|
104
|
-
private
|
|
105
|
-
private
|
|
137
|
+
public class PageResult<T> {
|
|
138
|
+
private List<T> records;
|
|
139
|
+
private long total;
|
|
140
|
+
private long current;
|
|
141
|
+
private long size;
|
|
106
142
|
}
|
|
107
143
|
```
|
|
108
144
|
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## 参数校验
|
|
148
|
+
|
|
109
149
|
### 分组校验
|
|
110
150
|
|
|
111
151
|
```java
|
|
@@ -116,142 +156,152 @@ public class XxxDTO {
|
|
|
116
156
|
private Long id;
|
|
117
157
|
|
|
118
158
|
@NotBlank(message = "名称不能为空", groups = {InsertGroup.class, UpdateGroup.class})
|
|
159
|
+
@Size(max = 100, message = "名称长度不能超过100个字符")
|
|
119
160
|
private String name;
|
|
161
|
+
|
|
162
|
+
@Min(value = 0, message = "排序不能为负数")
|
|
163
|
+
private Integer sort;
|
|
120
164
|
}
|
|
121
165
|
|
|
122
166
|
// Controller 中应用
|
|
123
|
-
@PostMapping
|
|
124
|
-
public Long add(@Validated(InsertGroup.class) @RequestBody
|
|
125
|
-
```
|
|
167
|
+
@PostMapping
|
|
168
|
+
public Result<Long> add(@Validated(InsertGroup.class) @RequestBody XxxDTO dto) { ... }
|
|
126
169
|
|
|
127
|
-
|
|
170
|
+
@PutMapping
|
|
171
|
+
public Result<Void> update(@Validated(UpdateGroup.class) @RequestBody XxxDTO dto) { ... }
|
|
172
|
+
```
|
|
128
173
|
|
|
129
|
-
|
|
174
|
+
> Jakarta Validation: JDK 17+ 必须 `import jakarta.validation.constraints.*`
|
|
130
175
|
|
|
131
|
-
|
|
176
|
+
### 查询参数
|
|
132
177
|
|
|
133
178
|
```java
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
179
|
+
@Data
|
|
180
|
+
public class XxxQueryDTO {
|
|
181
|
+
private String keyword;
|
|
182
|
+
private Integer status;
|
|
137
183
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
public XxxVO getById(@PathVariable Long id) { ... }
|
|
184
|
+
@Min(value = 1)
|
|
185
|
+
private Integer pageNum = 1;
|
|
141
186
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
187
|
+
@Min(value = 1) @Max(value = 100)
|
|
188
|
+
private Integer pageSize = 10;
|
|
189
|
+
}
|
|
145
190
|
```
|
|
146
191
|
|
|
147
192
|
---
|
|
148
193
|
|
|
149
194
|
## 常见场景
|
|
150
195
|
|
|
151
|
-
###
|
|
196
|
+
### 带分布式锁的导入
|
|
152
197
|
|
|
153
198
|
```java
|
|
154
|
-
@PostMapping("/import
|
|
155
|
-
@
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
throw new LeException("文件不能为空");
|
|
159
|
-
}
|
|
160
|
-
RLock lock = redissonClient.getLock("import:lock:" + TenantContextHolder.getTenantId());
|
|
161
|
-
if (!lock.tryLock(5, 60, TimeUnit.SECONDS)) {
|
|
162
|
-
throw new LeException("正在处理中,请稍后再试");
|
|
199
|
+
@PostMapping("/import")
|
|
200
|
+
public Result<Void> importExcel(@RequestPart("file") MultipartFile file) {
|
|
201
|
+
if (file == null || file.isEmpty()) {
|
|
202
|
+
throw new [你的异常类]("文件不能为空");
|
|
163
203
|
}
|
|
204
|
+
RLock lock = redissonClient.getLock("import:lock:" + getCurrentTenantId());
|
|
164
205
|
try {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
206
|
+
if (!lock.tryLock(5, 60, TimeUnit.SECONDS)) {
|
|
207
|
+
throw new [你的异常类]("正在处理中,请稍后再试");
|
|
208
|
+
}
|
|
209
|
+
try {
|
|
210
|
+
xxxService.importExcel(file);
|
|
211
|
+
} finally {
|
|
212
|
+
if (lock.isLocked() && lock.isHeldByCurrentThread()) {
|
|
213
|
+
lock.unlock();
|
|
214
|
+
}
|
|
169
215
|
}
|
|
216
|
+
} catch (InterruptedException e) {
|
|
217
|
+
Thread.currentThread().interrupt();
|
|
218
|
+
throw new [你的异常类]("导入被中断");
|
|
170
219
|
}
|
|
220
|
+
return Result.ok();
|
|
171
221
|
}
|
|
172
222
|
```
|
|
173
223
|
|
|
174
224
|
### 批量删除
|
|
175
225
|
|
|
176
226
|
```java
|
|
177
|
-
@
|
|
178
|
-
@
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
throw new LeException("ID列表不能为空");
|
|
227
|
+
@DeleteMapping("/{ids}")
|
|
228
|
+
public Result<Void> delete(@PathVariable List<Long> ids) {
|
|
229
|
+
if (ids == null || ids.isEmpty()) {
|
|
230
|
+
throw new [你的异常类]("ID列表不能为空");
|
|
182
231
|
}
|
|
183
|
-
xxxService.
|
|
232
|
+
xxxService.deleteByIds(ids);
|
|
233
|
+
return Result.ok();
|
|
184
234
|
}
|
|
185
235
|
```
|
|
186
236
|
|
|
187
|
-
###
|
|
237
|
+
### 文件上传
|
|
188
238
|
|
|
189
239
|
```java
|
|
190
|
-
@PostMapping("/
|
|
191
|
-
@
|
|
192
|
-
|
|
193
|
-
ReportBaseTotalVO<XxxVO> result = new ReportBaseTotalVO<>();
|
|
194
|
-
result.setTotalLine(xxxService.getSummaryTotal(request.getContent()));
|
|
195
|
-
result.setResultPage(PageVO.of(xxxService.pageList(request.getContent())));
|
|
196
|
-
return result;
|
|
240
|
+
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
|
241
|
+
public Result<UploadResult> upload(@RequestPart("file") MultipartFile file) {
|
|
242
|
+
return Result.ok(ossService.upload(file));
|
|
197
243
|
}
|
|
198
244
|
```
|
|
199
245
|
|
|
200
246
|
---
|
|
201
247
|
|
|
202
|
-
##
|
|
248
|
+
## API 文档注解
|
|
249
|
+
|
|
250
|
+
### Swagger / SpringDoc 注解
|
|
203
251
|
|
|
204
252
|
```java
|
|
205
|
-
|
|
206
|
-
@
|
|
207
|
-
@
|
|
208
|
-
@
|
|
253
|
+
// SpringDoc (OpenAPI 3.0, 推荐)
|
|
254
|
+
@Tag(name = "用户管理") // Controller 类
|
|
255
|
+
@Operation(summary = "新增用户") // 方法
|
|
256
|
+
@Schema(description = "用户DTO") // DTO/VO 类
|
|
257
|
+
@Schema(description = "主键ID", requiredMode = REQUIRED) // 字段
|
|
258
|
+
|
|
259
|
+
// Swagger 2 (旧项目)
|
|
260
|
+
@Api(value = "用户管理", tags = "用户管理")
|
|
261
|
+
@ApiOperation(value = "新增用户")
|
|
262
|
+
@ApiModel("用户DTO")
|
|
263
|
+
@ApiModelProperty(value = "主键ID", required = true)
|
|
209
264
|
```
|
|
210
265
|
|
|
211
266
|
---
|
|
212
267
|
|
|
213
|
-
##
|
|
268
|
+
## 全局异常处理
|
|
214
269
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
- [ ] 返回值类型正确(分页用 `Page<VO>`)
|
|
219
|
-
- [ ] 使用 `LeRequest<T>` 封装请求
|
|
220
|
-
- [ ] 敏感操作加分布式锁
|
|
270
|
+
```java
|
|
271
|
+
@RestControllerAdvice
|
|
272
|
+
public class GlobalExceptionHandler {
|
|
221
273
|
|
|
222
|
-
|
|
274
|
+
@ExceptionHandler([你的异常类].class)
|
|
275
|
+
public Result<Void> handleBusinessException([你的异常类] e) {
|
|
276
|
+
return Result.fail(e.getMessage());
|
|
277
|
+
}
|
|
223
278
|
|
|
224
|
-
|
|
279
|
+
@ExceptionHandler(MethodArgumentNotValidException.class)
|
|
280
|
+
public Result<Void> handleValidException(MethodArgumentNotValidException e) {
|
|
281
|
+
String message = e.getBindingResult().getFieldErrors().stream()
|
|
282
|
+
.map(FieldError::getDefaultMessage)
|
|
283
|
+
.collect(Collectors.joining(", "));
|
|
284
|
+
return Result.fail(message);
|
|
285
|
+
}
|
|
225
286
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
| 认证 | `@SaCheckPermission` | `@RequiresAuthentication` |
|
|
234
|
-
| 异常 | `ServiceException` | `LeException` |
|
|
235
|
-
| 国际化 | `MessageUtils.message()` | `I18n.getMessage()` |
|
|
287
|
+
@ExceptionHandler(Exception.class)
|
|
288
|
+
public Result<Void> handleException(Exception e) {
|
|
289
|
+
log.error("系统异常", e);
|
|
290
|
+
return Result.fail("系统繁忙,请稍后再试");
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
```
|
|
236
294
|
|
|
237
295
|
---
|
|
238
296
|
|
|
239
|
-
##
|
|
297
|
+
## 检查清单
|
|
240
298
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
// ---- 正确 ----
|
|
249
|
-
@RestController @RequiresAuthentication
|
|
250
|
-
public Long add(@Validated(InsertGroup.class) @RequestBody LeRequest<XxxDTO> request) {
|
|
251
|
-
return xxxService.add(request.getContent());
|
|
252
|
-
}
|
|
253
|
-
import jakarta.validation.constraints.NotNull;
|
|
254
|
-
```
|
|
299
|
+
- [ ] 认证注解(`@PreAuthorize` / `[你的认证注解]`)
|
|
300
|
+
- [ ] API 文档注解(`@Operation` / `@ApiOperation`)
|
|
301
|
+
- [ ] 参数校验 `@Validated` + 分组
|
|
302
|
+
- [ ] 统一响应包装 `Result<T>`
|
|
303
|
+
- [ ] 敏感操作加分布式锁
|
|
304
|
+
- [ ] 全局异常处理器已配置
|
|
255
305
|
|
|
256
306
|
---
|
|
257
307
|
|
|
@@ -259,8 +309,7 @@ import jakarta.validation.constraints.NotNull;
|
|
|
259
309
|
|
|
260
310
|
| 需要了解 | Skill |
|
|
261
311
|
|---------|-------|
|
|
262
|
-
| Service 层 | `java-service` |
|
|
263
|
-
| Controller 详细 | `java-controller` |
|
|
264
312
|
| 异常处理 | `error-handler` |
|
|
265
|
-
| 参数校验 | `java-entity` |
|
|
266
313
|
| 数据库设计 | `database-ops` |
|
|
314
|
+
| 缓存 | `redis-cache` |
|
|
315
|
+
| 文件上传 | `file-oss-management` |
|