ai-engineering-init 1.1.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/code-reviewer.md +139 -0
- package/.claude/agents/project-manager.md +159 -0
- package/.claude/audio/completed.wav +0 -0
- package/.claude/commands/add-todo.md +255 -0
- package/.claude/commands/check.md +210 -0
- package/.claude/commands/crud.md +454 -0
- package/.claude/commands/dev.md +503 -0
- package/.claude/commands/init-docs.md +681 -0
- package/.claude/commands/next.md +251 -0
- package/.claude/commands/progress.md +242 -0
- package/.claude/commands/start.md +199 -0
- package/.claude/commands/sync.md +307 -0
- package/.claude/commands/update-status.md +428 -0
- package/.claude/docs/Mixin/344/275/277/347/224/250/346/214/207/345/215/227.md +299 -0
- package/.claude/docs/README.md +167 -0
- package/.claude/docs//345/211/215/347/253/257/345/274/200/345/217/221/346/214/207/345/215/227.md +599 -0
- package/.claude/docs//345/220/216/347/253/257/345/274/200/345/217/221/346/214/207/345/215/227.md +726 -0
- package/.claude/docs//345/267/245/344/275/234/346/265/201/345/274/200/345/217/221/346/214/207/345/215/227.md +714 -0
- package/.claude/docs//345/267/245/345/205/267/347/261/273/344/275/277/347/224/250/346/214/207/345/215/227.md +463 -0
- package/.claude/docs//346/225/260/346/215/256/345/272/223/350/256/276/350/256/241/350/247/204/350/214/203.md +390 -0
- package/.claude/docs//346/226/260/345/212/237/350/203/275/345/274/200/345/217/221/346/265/201/347/250/213/350/247/204/350/214/203.md +688 -0
- package/.claude/docs//346/226/260/351/241/271/347/233/256/345/274/200/345/217/221/346/265/201/347/250/213.md +365 -0
- package/.claude/docs//346/241/206/346/236/266/350/257/264/346/230/216.md +393 -0
- package/.claude/docs//350/267/257/347/224/261/351/205/215/347/275/256/346/214/207/345/215/227.md +246 -0
- package/.claude/framework-config.json +73 -0
- package/.claude/hooks/pre-tool-use.js +117 -0
- package/.claude/hooks/skill-forced-eval.js +167 -0
- package/.claude/hooks/stop.js +58 -0
- package/.claude/settings.json +41 -0
- package/.claude/skills/add-skill/SKILL.md +352 -0
- package/.claude/skills/api-development/SKILL.md +560 -0
- package/.claude/skills/architecture-design/SKILL.md +756 -0
- package/.claude/skills/backend-annotations/SKILL.md +674 -0
- package/.claude/skills/banana-image/CHANGELOG.md +37 -0
- package/.claude/skills/banana-image/README.md +146 -0
- package/.claude/skills/banana-image/SKILL.md +164 -0
- package/.claude/skills/banana-image/assets/logo.png +0 -0
- package/.claude/skills/banana-image/references/advanced-usage.md +189 -0
- package/.claude/skills/banana-image/scripts/apply_template.py +125 -0
- package/.claude/skills/banana-image/scripts/banana_image_exec.ts +412 -0
- package/.claude/skills/banana-image/scripts/batch_prep.py +82 -0
- package/.claude/skills/banana-image/scripts/package-lock.json +1437 -0
- package/.claude/skills/banana-image/scripts/package.json +18 -0
- package/.claude/skills/banana-image/scripts/requirements.txt +10 -0
- package/.claude/skills/banana-image/templates/poster.json +22 -0
- package/.claude/skills/banana-image/templates/product.json +17 -0
- package/.claude/skills/banana-image/templates/social.json +22 -0
- package/.claude/skills/banana-image/templates/thumbnail.json +17 -0
- package/.claude/skills/brainstorm/SKILL.md +648 -0
- package/.claude/skills/bug-detective/SKILL.md +1206 -0
- package/.claude/skills/code-patterns/SKILL.md +590 -0
- package/.claude/skills/collaborating-with-codex/SKILL.md +174 -0
- package/.claude/skills/collaborating-with-codex/scripts/codex_bridge.py +275 -0
- package/.claude/skills/collaborating-with-gemini/SKILL.md +194 -0
- package/.claude/skills/collaborating-with-gemini/scripts/gemini_bridge.py +275 -0
- package/.claude/skills/crud-development/SKILL.md +649 -0
- package/.claude/skills/data-permission/SKILL.md +599 -0
- package/.claude/skills/database-ops/SKILL.md +407 -0
- package/.claude/skills/error-handler/SKILL.md +371 -0
- package/.claude/skills/file-oss-management/SKILL.md +863 -0
- package/.claude/skills/git-workflow/SKILL.md +375 -0
- package/.claude/skills/json-serialization/SKILL.md +357 -0
- package/.claude/skills/leniu-api-development/SKILL.md +803 -0
- package/.claude/skills/leniu-architecture-design/SKILL.md +598 -0
- package/.claude/skills/leniu-backend-annotations/SKILL.md +664 -0
- package/.claude/skills/leniu-code-patterns/SKILL.md +365 -0
- package/.claude/skills/leniu-crud-development/SKILL.md +1110 -0
- package/.claude/skills/leniu-data-permission/SKILL.md +256 -0
- package/.claude/skills/leniu-database-ops/SKILL.md +426 -0
- package/.claude/skills/leniu-error-handler/SKILL.md +462 -0
- package/.claude/skills/leniu-java-amount-handling/SKILL.md +461 -0
- package/.claude/skills/leniu-java-code-style/SKILL.md +510 -0
- package/.claude/skills/leniu-java-concurrent/SKILL.md +400 -0
- package/.claude/skills/leniu-java-entity/SKILL.md +751 -0
- package/.claude/skills/leniu-java-export/SKILL.md +560 -0
- package/.claude/skills/leniu-java-logging/SKILL.md +832 -0
- package/.claude/skills/leniu-java-mq/SKILL.md +338 -0
- package/.claude/skills/leniu-java-mybatis/SKILL.md +640 -0
- package/.claude/skills/leniu-java-report-query-param/SKILL.md +291 -0
- package/.claude/skills/leniu-java-task/SKILL.md +367 -0
- package/.claude/skills/leniu-java-total-line/SKILL.md +195 -0
- package/.claude/skills/leniu-marketing-price-rule-customizer/SKILL.md +301 -0
- package/.claude/skills/leniu-marketing-recharge-rule-customizer/SKILL.md +285 -0
- package/.claude/skills/leniu-mealtime/SKILL.md +215 -0
- package/.claude/skills/leniu-redis-cache/SKILL.md +316 -0
- package/.claude/skills/leniu-security-guard/SKILL.md +520 -0
- package/.claude/skills/leniu-utils-toolkit/SKILL.md +380 -0
- package/.claude/skills/openspec-apply-change/SKILL.md +156 -0
- package/.claude/skills/openspec-archive-change/SKILL.md +114 -0
- package/.claude/skills/openspec-bulk-archive-change/SKILL.md +246 -0
- package/.claude/skills/openspec-continue-change/SKILL.md +118 -0
- package/.claude/skills/openspec-explore/SKILL.md +290 -0
- package/.claude/skills/openspec-ff-change/SKILL.md +101 -0
- package/.claude/skills/openspec-new-change/SKILL.md +74 -0
- package/.claude/skills/openspec-onboard/SKILL.md +529 -0
- package/.claude/skills/openspec-sync-specs/SKILL.md +138 -0
- package/.claude/skills/openspec-verify-change/SKILL.md +168 -0
- package/.claude/skills/performance-doctor/SKILL.md +627 -0
- package/.claude/skills/project-navigator/SKILL.md +305 -0
- package/.claude/skills/redis-cache/SKILL.md +839 -0
- package/.claude/skills/scheduled-jobs/SKILL.md +633 -0
- package/.claude/skills/security-guard/SKILL.md +748 -0
- package/.claude/skills/sms-mail/SKILL.md +766 -0
- package/.claude/skills/social-login/SKILL.md +668 -0
- package/.claude/skills/store-pc/SKILL.md +366 -0
- package/.claude/skills/task-tracker/SKILL.md +307 -0
- package/.claude/skills/tech-decision/SKILL.md +393 -0
- package/.claude/skills/tenant-management/SKILL.md +603 -0
- package/.claude/skills/test-development/SKILL.md +755 -0
- package/.claude/skills/ui-pc/SKILL.md +438 -0
- package/.claude/skills/utils-toolkit/SKILL.md +615 -0
- package/.claude/skills/websocket-sse/SKILL.md +716 -0
- package/.claude/skills/workflow-engine/SKILL.md +676 -0
- package/.claude/templates//345/276/205/345/212/236/346/270/205/345/215/225/346/250/241/346/235/277.md +56 -0
- package/.claude/templates//351/234/200/346/261/202/346/226/207/346/241/243/346/250/241/346/235/277.md +85 -0
- package/.claude/templates//351/241/271/347/233/256/347/212/266/346/200/201/346/250/241/346/235/277.md +43 -0
- package/.codex/skills/add-skill/SKILL.md +352 -0
- package/.codex/skills/add-todo/SKILL.md +269 -0
- package/.codex/skills/api-development/SKILL.md +693 -0
- package/.codex/skills/architecture-design/SKILL.md +628 -0
- package/.codex/skills/backend-annotations/SKILL.md +664 -0
- package/.codex/skills/banana-image/CHANGELOG.md +37 -0
- package/.codex/skills/banana-image/README.md +146 -0
- package/.codex/skills/banana-image/SKILL.md +164 -0
- package/.codex/skills/banana-image/assets/logo.png +0 -0
- package/.codex/skills/banana-image/references/advanced-usage.md +189 -0
- package/.codex/skills/banana-image/scripts/apply_template.py +125 -0
- package/.codex/skills/banana-image/scripts/banana_image_exec.ts +412 -0
- package/.codex/skills/banana-image/scripts/batch_prep.py +82 -0
- package/.codex/skills/banana-image/scripts/package-lock.json +1437 -0
- package/.codex/skills/banana-image/scripts/package.json +18 -0
- package/.codex/skills/banana-image/scripts/requirements.txt +10 -0
- package/.codex/skills/banana-image/templates/poster.json +22 -0
- package/.codex/skills/banana-image/templates/product.json +17 -0
- package/.codex/skills/banana-image/templates/social.json +22 -0
- package/.codex/skills/banana-image/templates/thumbnail.json +17 -0
- package/.codex/skills/brainstorm/SKILL.md +648 -0
- package/.codex/skills/bug-detective/SKILL.md +1206 -0
- package/.codex/skills/check/SKILL.md +367 -0
- package/.codex/skills/code-patterns/SKILL.md +442 -0
- package/.codex/skills/collaborating-with-codex/SKILL.md +174 -0
- package/.codex/skills/collaborating-with-codex/scripts/codex_bridge.py +275 -0
- package/.codex/skills/collaborating-with-gemini/SKILL.md +194 -0
- package/.codex/skills/collaborating-with-gemini/scripts/gemini_bridge.py +275 -0
- package/.codex/skills/crud/SKILL.md +265 -0
- package/.codex/skills/crud-development/SKILL.md +637 -0
- package/.codex/skills/data-permission/SKILL.md +591 -0
- package/.codex/skills/database-ops/SKILL.md +553 -0
- package/.codex/skills/dev/SKILL.md +187 -0
- package/.codex/skills/error-handler/SKILL.md +361 -0
- package/.codex/skills/file-oss-management/SKILL.md +863 -0
- package/.codex/skills/git-workflow/SKILL.md +375 -0
- package/.codex/skills/init-docs/SKILL.md +194 -0
- package/.codex/skills/json-serialization/SKILL.md +357 -0
- package/.codex/skills/leniu-api-development/SKILL.md +803 -0
- package/.codex/skills/leniu-architecture-design/SKILL.md +594 -0
- package/.codex/skills/leniu-backend-annotations/SKILL.md +662 -0
- package/.codex/skills/leniu-code-patterns/SKILL.md +365 -0
- package/.codex/skills/leniu-crud-development/SKILL.md +1110 -0
- package/.codex/skills/leniu-data-permission/SKILL.md +256 -0
- package/.codex/skills/leniu-database-ops/SKILL.md +426 -0
- package/.codex/skills/leniu-error-handler/SKILL.md +462 -0
- package/.codex/skills/leniu-java-amount-handling/SKILL.md +461 -0
- package/.codex/skills/leniu-java-code-style/SKILL.md +510 -0
- package/.codex/skills/leniu-java-concurrent/SKILL.md +400 -0
- package/.codex/skills/leniu-java-entity/SKILL.md +751 -0
- package/.codex/skills/leniu-java-export/SKILL.md +560 -0
- package/.codex/skills/leniu-java-logging/SKILL.md +832 -0
- package/.codex/skills/leniu-java-mq/SKILL.md +338 -0
- package/.codex/skills/leniu-java-mybatis/SKILL.md +640 -0
- package/.codex/skills/leniu-java-report-query-param/SKILL.md +291 -0
- package/.codex/skills/leniu-java-task/SKILL.md +367 -0
- package/.codex/skills/leniu-java-total-line/SKILL.md +195 -0
- package/.codex/skills/leniu-marketing-price-rule-customizer/SKILL.md +301 -0
- package/.codex/skills/leniu-marketing-recharge-rule-customizer/SKILL.md +285 -0
- package/.codex/skills/leniu-mealtime/SKILL.md +215 -0
- package/.codex/skills/leniu-redis-cache/SKILL.md +316 -0
- package/.codex/skills/leniu-security-guard/SKILL.md +520 -0
- package/.codex/skills/leniu-utils-toolkit/SKILL.md +378 -0
- package/.codex/skills/next/SKILL.md +137 -0
- package/.codex/skills/openspec-apply-change/SKILL.md +156 -0
- package/.codex/skills/openspec-archive-change/SKILL.md +114 -0
- package/.codex/skills/openspec-bulk-archive-change/SKILL.md +246 -0
- package/.codex/skills/openspec-continue-change/SKILL.md +118 -0
- package/.codex/skills/openspec-explore/SKILL.md +290 -0
- package/.codex/skills/openspec-ff-change/SKILL.md +101 -0
- package/.codex/skills/openspec-new-change/SKILL.md +74 -0
- package/.codex/skills/openspec-onboard/SKILL.md +529 -0
- package/.codex/skills/openspec-sync-specs/SKILL.md +138 -0
- package/.codex/skills/openspec-verify-change/SKILL.md +168 -0
- package/.codex/skills/performance-doctor/SKILL.md +627 -0
- package/.codex/skills/progress/SKILL.md +193 -0
- package/.codex/skills/project-navigator/SKILL.md +286 -0
- package/.codex/skills/redis-cache/SKILL.md +829 -0
- package/.codex/skills/scheduled-jobs/SKILL.md +633 -0
- package/.codex/skills/security-guard/SKILL.md +739 -0
- package/.codex/skills/sms-mail/SKILL.md +766 -0
- package/.codex/skills/social-login/SKILL.md +668 -0
- package/.codex/skills/start/SKILL.md +154 -0
- package/.codex/skills/store-pc/SKILL.md +491 -0
- package/.codex/skills/sync/SKILL.md +149 -0
- package/.codex/skills/task-tracker/SKILL.md +307 -0
- package/.codex/skills/tech-decision/SKILL.md +393 -0
- package/.codex/skills/tenant-management/SKILL.md +603 -0
- package/.codex/skills/test-development/SKILL.md +755 -0
- package/.codex/skills/ui-pc/SKILL.md +475 -0
- package/.codex/skills/update-status/SKILL.md +159 -0
- package/.codex/skills/utils-toolkit/SKILL.md +593 -0
- package/.codex/skills/websocket-sse/SKILL.md +716 -0
- package/.codex/skills/workflow-engine/SKILL.md +676 -0
- package/.cursor/agents/code-reviewer.md +139 -0
- package/.cursor/agents/project-manager.md +159 -0
- package/.cursor/commands/opsx-apply.md +152 -0
- package/.cursor/commands/opsx-archive.md +157 -0
- package/.cursor/commands/opsx-bulk-archive.md +242 -0
- package/.cursor/commands/opsx-continue.md +114 -0
- package/.cursor/commands/opsx-explore.md +174 -0
- package/.cursor/commands/opsx-ff.md +94 -0
- package/.cursor/commands/opsx-new.md +69 -0
- package/.cursor/commands/opsx-onboard.md +525 -0
- package/.cursor/commands/opsx-sync.md +134 -0
- package/.cursor/commands/opsx-verify.md +164 -0
- package/.cursor/mcp.json +22 -0
- package/.cursor/skills/add-skill/SKILL.md +352 -0
- package/.cursor/skills/api-development/SKILL.md +560 -0
- package/.cursor/skills/architecture-design/SKILL.md +756 -0
- package/.cursor/skills/backend-annotations/SKILL.md +674 -0
- package/.cursor/skills/banana-image/CHANGELOG.md +37 -0
- package/.cursor/skills/banana-image/README.md +146 -0
- package/.cursor/skills/banana-image/SKILL.md +164 -0
- package/.cursor/skills/banana-image/assets/logo.png +0 -0
- package/.cursor/skills/banana-image/references/advanced-usage.md +189 -0
- package/.cursor/skills/banana-image/scripts/apply_template.py +125 -0
- package/.cursor/skills/banana-image/scripts/banana_image_exec.ts +412 -0
- package/.cursor/skills/banana-image/scripts/batch_prep.py +82 -0
- package/.cursor/skills/banana-image/scripts/package-lock.json +1437 -0
- package/.cursor/skills/banana-image/scripts/package.json +18 -0
- package/.cursor/skills/banana-image/scripts/requirements.txt +10 -0
- package/.cursor/skills/banana-image/templates/poster.json +22 -0
- package/.cursor/skills/banana-image/templates/product.json +17 -0
- package/.cursor/skills/banana-image/templates/social.json +22 -0
- package/.cursor/skills/banana-image/templates/thumbnail.json +17 -0
- package/.cursor/skills/brainstorm/SKILL.md +648 -0
- package/.cursor/skills/bug-detective/SKILL.md +1206 -0
- package/.cursor/skills/code-patterns/SKILL.md +590 -0
- package/.cursor/skills/collaborating-with-codex/SKILL.md +174 -0
- package/.cursor/skills/collaborating-with-codex/scripts/codex_bridge.py +275 -0
- package/.cursor/skills/collaborating-with-gemini/SKILL.md +194 -0
- package/.cursor/skills/collaborating-with-gemini/scripts/gemini_bridge.py +275 -0
- package/.cursor/skills/crud-development/SKILL.md +649 -0
- package/.cursor/skills/data-permission/SKILL.md +599 -0
- package/.cursor/skills/database-ops/SKILL.md +407 -0
- package/.cursor/skills/error-handler/SKILL.md +371 -0
- package/.cursor/skills/file-oss-management/SKILL.md +863 -0
- package/.cursor/skills/git-workflow/SKILL.md +375 -0
- package/.cursor/skills/json-serialization/SKILL.md +357 -0
- package/.cursor/skills/leniu-api-development/SKILL.md +803 -0
- package/.cursor/skills/leniu-architecture-design/SKILL.md +598 -0
- package/.cursor/skills/leniu-backend-annotations/SKILL.md +664 -0
- package/.cursor/skills/leniu-code-patterns/SKILL.md +365 -0
- package/.cursor/skills/leniu-crud-development/SKILL.md +1110 -0
- package/.cursor/skills/leniu-data-permission/SKILL.md +256 -0
- package/.cursor/skills/leniu-database-ops/SKILL.md +426 -0
- package/.cursor/skills/leniu-error-handler/SKILL.md +462 -0
- package/.cursor/skills/leniu-java-amount-handling/SKILL.md +461 -0
- package/.cursor/skills/leniu-java-code-style/SKILL.md +510 -0
- package/.cursor/skills/leniu-java-concurrent/SKILL.md +400 -0
- package/.cursor/skills/leniu-java-entity/SKILL.md +751 -0
- package/.cursor/skills/leniu-java-export/SKILL.md +560 -0
- package/.cursor/skills/leniu-java-logging/SKILL.md +832 -0
- package/.cursor/skills/leniu-java-mq/SKILL.md +338 -0
- package/.cursor/skills/leniu-java-mybatis/SKILL.md +640 -0
- package/.cursor/skills/leniu-java-report-query-param/SKILL.md +291 -0
- package/.cursor/skills/leniu-java-task/SKILL.md +367 -0
- package/.cursor/skills/leniu-java-total-line/SKILL.md +195 -0
- package/.cursor/skills/leniu-marketing-price-rule-customizer/SKILL.md +301 -0
- package/.cursor/skills/leniu-marketing-recharge-rule-customizer/SKILL.md +285 -0
- package/.cursor/skills/leniu-mealtime/SKILL.md +215 -0
- package/.cursor/skills/leniu-redis-cache/SKILL.md +316 -0
- package/.cursor/skills/leniu-security-guard/SKILL.md +520 -0
- package/.cursor/skills/leniu-utils-toolkit/SKILL.md +380 -0
- package/.cursor/skills/openspec-apply-change/SKILL.md +156 -0
- package/.cursor/skills/openspec-archive-change/SKILL.md +114 -0
- package/.cursor/skills/openspec-bulk-archive-change/SKILL.md +246 -0
- package/.cursor/skills/openspec-continue-change/SKILL.md +118 -0
- package/.cursor/skills/openspec-explore/SKILL.md +290 -0
- package/.cursor/skills/openspec-ff-change/SKILL.md +101 -0
- package/.cursor/skills/openspec-new-change/SKILL.md +74 -0
- package/.cursor/skills/openspec-onboard/SKILL.md +529 -0
- package/.cursor/skills/openspec-sync-specs/SKILL.md +138 -0
- package/.cursor/skills/openspec-verify-change/SKILL.md +168 -0
- package/.cursor/skills/performance-doctor/SKILL.md +627 -0
- package/.cursor/skills/project-navigator/SKILL.md +305 -0
- package/.cursor/skills/redis-cache/SKILL.md +839 -0
- package/.cursor/skills/scheduled-jobs/SKILL.md +633 -0
- package/.cursor/skills/security-guard/SKILL.md +748 -0
- package/.cursor/skills/sms-mail/SKILL.md +766 -0
- package/.cursor/skills/social-login/SKILL.md +668 -0
- package/.cursor/skills/store-pc/SKILL.md +366 -0
- package/.cursor/skills/task-tracker/SKILL.md +307 -0
- package/.cursor/skills/tech-decision/SKILL.md +393 -0
- package/.cursor/skills/tenant-management/SKILL.md +603 -0
- package/.cursor/skills/test-development/SKILL.md +755 -0
- package/.cursor/skills/ui-pc/SKILL.md +438 -0
- package/.cursor/skills/utils-toolkit/SKILL.md +615 -0
- package/.cursor/skills/websocket-sse/SKILL.md +716 -0
- package/.cursor/skills/workflow-engine/SKILL.md +676 -0
- package/AGENTS.md +669 -0
- package/CLAUDE.md +205 -0
- package/README.md +205 -0
- package/bin/index.js +179 -0
- package/init.sh +178 -0
- package/package.json +27 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dev
|
|
3
|
+
description: |
|
|
4
|
+
当需要从零开始开发新功能、完整开发流程时自动使用此 Skill。
|
|
5
|
+
|
|
6
|
+
触发场景:
|
|
7
|
+
- 需要从零开始开发一个新功能
|
|
8
|
+
- 需要设计数据库表并生成代码
|
|
9
|
+
- 需要完整的开发流程引导
|
|
10
|
+
- 需要配置代码生成器并生成后端代码
|
|
11
|
+
|
|
12
|
+
触发词:开发功能、dev、新功能、功能开发、从零开发、完整开发、开发新模块
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# /dev - 开发新功能(RuoYi-Vue-Plus 纯后端版)
|
|
16
|
+
|
|
17
|
+
智能代码生成器配置助手,专为 RuoYi-Vue-Plus 三层架构(Controller→Service→Mapper)设计。
|
|
18
|
+
|
|
19
|
+
## 🎯 核心优势
|
|
20
|
+
- ✅ **纯后端专注**:无前端,专注后端 CRUD 代码生成
|
|
21
|
+
- ✅ **包名适配**:`org.dromara.*`
|
|
22
|
+
- ✅ **智能推断**:模块 → 表前缀 → 包名 → 图标自动识别
|
|
23
|
+
- ✅ **全自动配置**:代码生成器配置完整(gen_table + gen_table_column)
|
|
24
|
+
- ✅ **菜单权限**:自动生成完整的菜单和权限配置
|
|
25
|
+
|
|
26
|
+
## 🚀 执行流程
|
|
27
|
+
|
|
28
|
+
### 第一步:需求确认
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
请告诉我要开发的功能:
|
|
32
|
+
|
|
33
|
+
1. **功能名称**?(如:广告管理、反馈管理)
|
|
34
|
+
2. **所属模块**?(system/business/其他)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**自动推断**:
|
|
38
|
+
|
|
39
|
+
| 模块 | 表前缀 | 包名 | 上级菜单 |
|
|
40
|
+
|------|--------|------|---------|
|
|
41
|
+
| system | `sys_` | `org.dromara.system` | 系统管理 |
|
|
42
|
+
| business | `b_` | `org.dromara.business` | 业务管理 |
|
|
43
|
+
| 其他(如 demo) | `demo_` | `org.dromara.demo` | [模块]管理 |
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
### 第二步:功能重复检查(强制执行)⭐⭐⭐⭐⭐
|
|
48
|
+
|
|
49
|
+
**⚠️ 重要**:检查功能是否已存在,避免重复开发
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
# 1. 检查后端代码
|
|
53
|
+
Grep pattern: "[功能名]Service" path: ruoyi-modules/ output_mode: files_with_matches
|
|
54
|
+
Grep pattern: "[功能名]Controller" path: ruoyi-modules/ output_mode: files_with_matches
|
|
55
|
+
|
|
56
|
+
# 2. 检查数据库表
|
|
57
|
+
SHOW TABLES LIKE '[表前缀]%';
|
|
58
|
+
|
|
59
|
+
# 3. 检查菜单
|
|
60
|
+
SELECT menu_name FROM sys_menu WHERE menu_name LIKE '%[功能名]%';
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
### 第三步:数据库现状分析(自动执行)
|
|
66
|
+
|
|
67
|
+
从 `ruoyi-admin/src/main/resources/application-dev.yml` 动态读取数据库配置。
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
### 第四步:智能表结构设计
|
|
72
|
+
|
|
73
|
+
#### 智能字段命名和推断
|
|
74
|
+
|
|
75
|
+
| 字段后缀 | 推断结果 | 控件类型 | 查询方式 |
|
|
76
|
+
|---------|---------|---------|---------|
|
|
77
|
+
| `xxx_name` | 名称 | input | LIKE |
|
|
78
|
+
| `xxx_title` | 标题 | input | LIKE |
|
|
79
|
+
| `xxx_content` | 内容 | editor | 富文本 |
|
|
80
|
+
| `status` | 状态 | select | EQ + sys_normal_disable |
|
|
81
|
+
| `xxx_type` | 分类 | select | EQ + 自定义字典 |
|
|
82
|
+
| `is_xxx` | 是否 | radio | EQ + sys_boolean_flag |
|
|
83
|
+
| `xxx_amount` / `xxx_price` | 金额 | numberInput | EQ |
|
|
84
|
+
| `xxx_time` / `xxx_date` | 时间 | datetime | BETWEEN |
|
|
85
|
+
|
|
86
|
+
#### 标准表结构模板
|
|
87
|
+
|
|
88
|
+
```sql
|
|
89
|
+
CREATE TABLE [表前缀]_[功能名] (
|
|
90
|
+
id BIGINT(20) NOT NULL COMMENT '主键ID',
|
|
91
|
+
tenant_id VARCHAR(20) DEFAULT '000000' COMMENT '租户ID',
|
|
92
|
+
|
|
93
|
+
-- 业务字段
|
|
94
|
+
xxx_name VARCHAR(100) NOT NULL COMMENT '名称',
|
|
95
|
+
xxx_type CHAR(1) DEFAULT '1' COMMENT '类型',
|
|
96
|
+
status CHAR(1) DEFAULT '1' COMMENT '状态(0停用 1正常)',
|
|
97
|
+
|
|
98
|
+
-- 审计字段
|
|
99
|
+
create_by BIGINT(20) DEFAULT NULL COMMENT '创建人',
|
|
100
|
+
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
|
101
|
+
update_by BIGINT(20) DEFAULT NULL COMMENT '更新人',
|
|
102
|
+
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
|
103
|
+
remark VARCHAR(500) DEFAULT NULL COMMENT '备注',
|
|
104
|
+
del_flag CHAR(1) DEFAULT '0' COMMENT '删除标志',
|
|
105
|
+
|
|
106
|
+
PRIMARY KEY (id)
|
|
107
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='xxx表';
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
### 第五步:生成方案并确认(仅此一次确认)
|
|
113
|
+
|
|
114
|
+
```markdown
|
|
115
|
+
## 📋 代码生成方案
|
|
116
|
+
|
|
117
|
+
### 基本配置
|
|
118
|
+
- **功能名称**:广告管理
|
|
119
|
+
- **模块**:business
|
|
120
|
+
- **表名**:b_ad
|
|
121
|
+
- **Java类名**:Ad
|
|
122
|
+
- **包名**:org.dromara.business
|
|
123
|
+
- **接口路径**:/business/ad
|
|
124
|
+
|
|
125
|
+
### 菜单配置
|
|
126
|
+
- **上级菜单**:业务管理 (menu_id: 1001)
|
|
127
|
+
- **菜单顺序**:20
|
|
128
|
+
- **菜单图标**:ad (自动匹配)
|
|
129
|
+
|
|
130
|
+
**确认开始生成?**
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
### 第六步:自动执行生成(无需确认)
|
|
136
|
+
|
|
137
|
+
用户确认后,AI 自动执行:
|
|
138
|
+
1. 建表 SQL
|
|
139
|
+
2. 创建字典(如需要)
|
|
140
|
+
3. 生成代码生成器配置 SQL
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
### 第七步:完成报告
|
|
145
|
+
|
|
146
|
+
```markdown
|
|
147
|
+
## 🎉 代码生成方案配置完成!
|
|
148
|
+
|
|
149
|
+
### 已完成
|
|
150
|
+
- ✅ 数据库表创建:b_ad
|
|
151
|
+
- ✅ 业务字典创建:b_ad_type(3 个字典项)
|
|
152
|
+
- ✅ 菜单配置:广告管理(自动导入启用)
|
|
153
|
+
- ✅ 代码生成配置:表 + 11 个字段
|
|
154
|
+
|
|
155
|
+
## 🚀 下一步:前往代码生成器生成代码
|
|
156
|
+
|
|
157
|
+
1. **登录系统后台**:http://localhost:8080
|
|
158
|
+
2. **导航**:系统工具 → 代码生成
|
|
159
|
+
3. **查找表**:找到 `b_ad` 表
|
|
160
|
+
4. **生成代码**:点击【生成代码】按钮
|
|
161
|
+
5. **重启服务**:代码生成后需重启后端服务
|
|
162
|
+
|
|
163
|
+
### 生成后的文件结构
|
|
164
|
+
|
|
165
|
+
\`\`\`
|
|
166
|
+
ruoyi-system/
|
|
167
|
+
├── controller/business/AdController.java
|
|
168
|
+
├── domain/Ad.java
|
|
169
|
+
├── domain/bo/AdBo.java
|
|
170
|
+
├── domain/vo/AdVo.java
|
|
171
|
+
├── mapper/AdMapper.java
|
|
172
|
+
├── service/IAdService.java
|
|
173
|
+
└── service/impl/AdServiceImpl.java
|
|
174
|
+
\`\`\`
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## ⚠️ AI 执行规则
|
|
180
|
+
|
|
181
|
+
1. ✅ **仅后端**:三层架构(Controller→Service→Mapper)
|
|
182
|
+
2. ✅ **包名**:必须是 `org.dromara.*`
|
|
183
|
+
3. ✅ **一次确认**:第五步确认后全自动执行
|
|
184
|
+
4. ✅ **tenant_id**:框架自动处理,所有权限配置为 0
|
|
185
|
+
5. ✅ **检查功能重复**:禁止重复开发相同功能
|
|
186
|
+
6. ✅ **智能字段推断**:根据字段名后缀自动推断控件和查询方式
|
|
187
|
+
7. ✅ **字典智能处理**:检查字典存在性,不存在则创建
|
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: error-handler
|
|
3
|
+
description: |
|
|
4
|
+
后端异常处理规范。包含 ServiceException 用法、全局异常处理器、参数校验、日志规范、错误码设计。
|
|
5
|
+
|
|
6
|
+
触发场景:
|
|
7
|
+
- 抛出业务异常(ServiceException)
|
|
8
|
+
- 全局异常处理器配置
|
|
9
|
+
- 参数校验异常处理
|
|
10
|
+
- 日志记录规范
|
|
11
|
+
- 错误码设计与国际化
|
|
12
|
+
- 事务异常处理
|
|
13
|
+
|
|
14
|
+
触发词:异常、ServiceException、throw、错误处理、全局异常、@Validated、参数校验、日志、log、错误码、事务、@Transactional、try-catch、异常捕获
|
|
15
|
+
|
|
16
|
+
注意:
|
|
17
|
+
- 如果是安全相关(认证授权、数据脱敏),请使用 security-guard。
|
|
18
|
+
- 如果是数据权限(@DataPermission),请使用 data-permission。
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
# 后端异常处理指南
|
|
22
|
+
|
|
23
|
+
> 本项目是纯后端项目,本文档专注于 Java 后端异常处理规范。
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## 快速索引
|
|
28
|
+
|
|
29
|
+
| 场景 | 推荐方式 |
|
|
30
|
+
|------|---------|
|
|
31
|
+
| 业务异常 | `throw new ServiceException("msg")` |
|
|
32
|
+
| 带参数异常 | `throw new ServiceException("用户 {} 不存在", userId)` |
|
|
33
|
+
| 带错误码 | `throw new ServiceException("msg", 200101)` |
|
|
34
|
+
| 参数校验 | `@Validated(AddGroup.class)` |
|
|
35
|
+
| 日志记录 | `log.error("msg: {}", e.getMessage(), e)` |
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## 1. 业务异常 - ServiceException
|
|
40
|
+
|
|
41
|
+
### 基本用法
|
|
42
|
+
|
|
43
|
+
```java
|
|
44
|
+
import org.dromara.common.core.exception.ServiceException;
|
|
45
|
+
|
|
46
|
+
// ✅ 基本用法:抛出业务异常
|
|
47
|
+
throw new ServiceException("用户不存在");
|
|
48
|
+
|
|
49
|
+
// ✅ 带占位符(支持 {} 占位符,使用 Hutool StrFormatter)
|
|
50
|
+
throw new ServiceException("用户 {} 不存在", userId);
|
|
51
|
+
throw new ServiceException("订单 {} 状态 {} 无法支付", orderId, status);
|
|
52
|
+
|
|
53
|
+
// ✅ 带错误码(第二个参数是 Integer code)
|
|
54
|
+
throw new ServiceException("用户不存在", 200101);
|
|
55
|
+
|
|
56
|
+
// ✅ 条件抛出(手动检查)
|
|
57
|
+
if (ObjectUtil.isNull(user)) {
|
|
58
|
+
throw new ServiceException("用户不存在");
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// ✅ 参数校验
|
|
62
|
+
if (StringUtils.isBlank(bo.getName())) {
|
|
63
|
+
throw new ServiceException("名称不能为空");
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### ServiceException 完整 API
|
|
68
|
+
|
|
69
|
+
> **🔴 重要**:ServiceException **没有静态工厂方法**(如 `of()`)和条件检查方法(如 `throwIf()`, `notNull()`),必须使用 `new` 关键字创建异常对象。
|
|
70
|
+
|
|
71
|
+
| 构造函数 | 说明 | 示例 |
|
|
72
|
+
|---------|------|------|
|
|
73
|
+
| `new ServiceException(String message)` | 只有错误消息 | `new ServiceException("操作失败")` |
|
|
74
|
+
| `new ServiceException(String message, Object... args)` | 带占位符参数 | `new ServiceException("用户{}不存在", userId)` |
|
|
75
|
+
| `new ServiceException(String message, Integer code)` | 带错误码 | `new ServiceException("用户不存在", 200101)` |
|
|
76
|
+
|
|
77
|
+
**链式调用方法**:
|
|
78
|
+
- `setMessage(String message)`: 设置错误消息
|
|
79
|
+
- `setDetailMessage(String detailMessage)`: 设置详细错误(用于内部调试)
|
|
80
|
+
|
|
81
|
+
**源码位置**: `ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/ServiceException.java`
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## 2. 全局异常处理器
|
|
86
|
+
|
|
87
|
+
框架已提供全局异常处理器,自动捕获并处理各类异常。
|
|
88
|
+
|
|
89
|
+
**位置**: `ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/handler/GlobalExceptionHandler.java`
|
|
90
|
+
|
|
91
|
+
### 异常处理映射
|
|
92
|
+
|
|
93
|
+
> **注意**:所有异常的 HTTP 响应状态码均为 200,错误码通过 `R.code` 字段返回。
|
|
94
|
+
|
|
95
|
+
| 异常类型 | 处理方式 | R.code |
|
|
96
|
+
|---------|---------|--------|
|
|
97
|
+
| `ServiceException` | 返回业务错误信息 | 自定义 code 或 500 |
|
|
98
|
+
| `BindException` | 返回参数绑定错误 | 500 |
|
|
99
|
+
| `ConstraintViolationException` | 返回参数校验错误 | 500 |
|
|
100
|
+
| `MethodArgumentNotValidException` | 返回参数校验错误 | 500 |
|
|
101
|
+
| `HandlerMethodValidationException` | 返回 @Validated 校验错误 | 500 |
|
|
102
|
+
| `HttpRequestMethodNotSupportedException` | 请求方式不支持 | 405 |
|
|
103
|
+
| `NoHandlerFoundException` | 路由不存在 | 404 |
|
|
104
|
+
| `JsonParseException` | JSON 解析失败 | 400 |
|
|
105
|
+
| `HttpMessageNotReadableException` | 请求参数格式错误 | 400 |
|
|
106
|
+
| `ExpressionException` | SpEL 表达式解析失败 | 500 |
|
|
107
|
+
| `RuntimeException` / `Exception` | 系统错误 | 500 |
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## 3. 参数校验
|
|
112
|
+
|
|
113
|
+
### 使用 @Validated 自动校验
|
|
114
|
+
|
|
115
|
+
```java
|
|
116
|
+
import org.dromara.common.core.validate.AddGroup;
|
|
117
|
+
import org.dromara.common.core.validate.EditGroup;
|
|
118
|
+
|
|
119
|
+
// Controller 层校验
|
|
120
|
+
@PostMapping
|
|
121
|
+
public R<Long> add(@Validated(AddGroup.class) @RequestBody XxxBo bo) {
|
|
122
|
+
// 参数校验失败会自动抛出异常
|
|
123
|
+
// 全局异常处理器会自动捕获并返回错误信息
|
|
124
|
+
return R.ok(xxxService.insert(bo));
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
@PutMapping
|
|
128
|
+
public R<Void> edit(@Validated(EditGroup.class) @RequestBody XxxBo bo) {
|
|
129
|
+
return toAjax(xxxService.update(bo));
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### BO 类校验注解
|
|
134
|
+
|
|
135
|
+
```java
|
|
136
|
+
public class XxxBo extends BaseEntity {
|
|
137
|
+
|
|
138
|
+
@NotNull(message = "ID不能为空", groups = { EditGroup.class })
|
|
139
|
+
private Long id;
|
|
140
|
+
|
|
141
|
+
@NotBlank(message = "名称不能为空", groups = { AddGroup.class, EditGroup.class })
|
|
142
|
+
@Size(max = 100, message = "名称长度不能超过100个字符")
|
|
143
|
+
private String name;
|
|
144
|
+
|
|
145
|
+
@Email(message = "邮箱格式不正确")
|
|
146
|
+
private String email;
|
|
147
|
+
|
|
148
|
+
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
|
|
149
|
+
private String phone;
|
|
150
|
+
|
|
151
|
+
@Min(value = 0, message = "数量不能小于0")
|
|
152
|
+
@Max(value = 9999, message = "数量不能大于9999")
|
|
153
|
+
private Integer count;
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### 手动校验(Service 层)
|
|
158
|
+
|
|
159
|
+
```java
|
|
160
|
+
import org.dromara.common.core.utils.ValidatorUtils;
|
|
161
|
+
|
|
162
|
+
// 手动触发校验
|
|
163
|
+
ValidatorUtils.validate(bo, AddGroup.class);
|
|
164
|
+
ValidatorUtils.validate(bo, EditGroup.class);
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## 4. 日志规范
|
|
170
|
+
|
|
171
|
+
### 日志级别
|
|
172
|
+
|
|
173
|
+
| 级别 | 使用场景 | 示例 |
|
|
174
|
+
|------|---------|------|
|
|
175
|
+
| ERROR | 系统错误、业务异常 | 数据库连接失败、第三方接口超时 |
|
|
176
|
+
| WARN | 警告信息、潜在问题 | 缓存未命中、重试操作 |
|
|
177
|
+
| INFO | 重要业务流程、操作记录 | 用户登录、订单创建 |
|
|
178
|
+
| DEBUG | 开发调试信息 | 方法入参、中间变量 |
|
|
179
|
+
| TRACE | 详细追踪信息 | 循环内部数据 |
|
|
180
|
+
|
|
181
|
+
### 日志最佳实践
|
|
182
|
+
|
|
183
|
+
```java
|
|
184
|
+
import lombok.extern.slf4j.Slf4j;
|
|
185
|
+
|
|
186
|
+
@Slf4j
|
|
187
|
+
@Service
|
|
188
|
+
public class XxxServiceImpl implements IXxxService {
|
|
189
|
+
|
|
190
|
+
// ✅ 好的:使用占位符(性能更好)
|
|
191
|
+
log.info("处理订单: {}, 状态: {}", orderId, status);
|
|
192
|
+
|
|
193
|
+
// ❌ 不好:字符串拼接(每次都会拼接,即使日志级别不输出)
|
|
194
|
+
log.info("处理订单: " + orderId + ", 状态: " + status);
|
|
195
|
+
|
|
196
|
+
// ✅ 好的:异常日志带堆栈(第三个参数传异常对象)
|
|
197
|
+
log.error("处理失败: {}", e.getMessage(), e);
|
|
198
|
+
|
|
199
|
+
// ❌ 不好:只记录消息,丢失堆栈
|
|
200
|
+
log.error("处理失败: {}", e.getMessage());
|
|
201
|
+
|
|
202
|
+
// ✅ 好的:判断日志级别(避免不必要的序列化开销)
|
|
203
|
+
if (log.isDebugEnabled()) {
|
|
204
|
+
log.debug("详细数据: {}", JsonUtils.toJsonString(data));
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// ✅ 好的:敏感信息脱敏
|
|
208
|
+
log.info("用户登录,手机: {}", DesensitizedUtil.mobilePhone(phone));
|
|
209
|
+
|
|
210
|
+
// ❌ 不好:记录敏感信息
|
|
211
|
+
log.info("用户登录,手机: {}", phone);
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Service 层日志示例
|
|
216
|
+
|
|
217
|
+
```java
|
|
218
|
+
@Slf4j
|
|
219
|
+
@RequiredArgsConstructor
|
|
220
|
+
@Service
|
|
221
|
+
public class SysUserServiceImpl implements ISysUserService {
|
|
222
|
+
|
|
223
|
+
private final SysUserMapper baseMapper;
|
|
224
|
+
|
|
225
|
+
@Override
|
|
226
|
+
@Transactional(rollbackFor = Exception.class)
|
|
227
|
+
public Long insertUser(SysUserBo bo) {
|
|
228
|
+
log.info("开始新增用户,用户名: {}", bo.getUserName());
|
|
229
|
+
|
|
230
|
+
// 1. 业务校验
|
|
231
|
+
SysUser existUser = baseMapper.selectUserByUserName(bo.getUserName());
|
|
232
|
+
if (ObjectUtil.isNotNull(existUser)) {
|
|
233
|
+
throw new ServiceException("用户名 {} 已存在", bo.getUserName());
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// 2. 执行插入
|
|
237
|
+
SysUser user = MapstructUtils.convert(bo, SysUser.class);
|
|
238
|
+
baseMapper.insert(user);
|
|
239
|
+
|
|
240
|
+
log.info("新增用户成功,用户ID: {}, 用户名: {}", user.getUserId(), user.getUserName());
|
|
241
|
+
return user.getUserId();
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
@Override
|
|
245
|
+
public SysUserVo selectUserById(Long userId) {
|
|
246
|
+
SysUser user = baseMapper.selectById(userId);
|
|
247
|
+
if (ObjectUtil.isNull(user)) {
|
|
248
|
+
throw new ServiceException("用户 {} 不存在", userId);
|
|
249
|
+
}
|
|
250
|
+
return MapstructUtils.convert(user, SysUserVo.class);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
## 5. 错误码设计
|
|
258
|
+
|
|
259
|
+
### 错误码规范
|
|
260
|
+
|
|
261
|
+
```java
|
|
262
|
+
// 格式: 模块(2位) + 类型(2位) + 序号(2位)
|
|
263
|
+
// 模块: 10-系统, 20-用户, 30-订单, 40-商品
|
|
264
|
+
// 类型: 01-参数错误, 02-业务错误, 03-权限错误, 04-系统错误
|
|
265
|
+
|
|
266
|
+
public class ErrorCode {
|
|
267
|
+
// 通用错误
|
|
268
|
+
public static final int SUCCESS = 200;
|
|
269
|
+
public static final int ERROR = 500;
|
|
270
|
+
public static final int UNAUTHORIZED = 401;
|
|
271
|
+
public static final int FORBIDDEN = 403;
|
|
272
|
+
|
|
273
|
+
// 用户模块 20xxxx
|
|
274
|
+
public static final int USER_NOT_FOUND = 200201; // 用户不存在
|
|
275
|
+
public static final int USER_PASSWORD_ERROR = 200202; // 密码错误
|
|
276
|
+
public static final int USER_DISABLED = 200203; // 用户已禁用
|
|
277
|
+
|
|
278
|
+
// 订单模块 30xxxx
|
|
279
|
+
public static final int ORDER_NOT_FOUND = 300201; // 订单不存在
|
|
280
|
+
public static final int ORDER_STATUS_ERROR = 300202; // 订单状态错误
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// 使用示例
|
|
284
|
+
throw new ServiceException("用户不存在", ErrorCode.USER_NOT_FOUND);
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### 错误消息国际化
|
|
288
|
+
|
|
289
|
+
```java
|
|
290
|
+
import org.dromara.common.core.utils.MessageUtils;
|
|
291
|
+
|
|
292
|
+
// 使用 MessageUtils.message() 获取国际化消息
|
|
293
|
+
throw new ServiceException(MessageUtils.message("user.not.exists"));
|
|
294
|
+
|
|
295
|
+
// 带参数的国际化消息
|
|
296
|
+
throw new ServiceException(MessageUtils.message("user.password.retry.limit.exceed", maxRetryCount));
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
---
|
|
300
|
+
|
|
301
|
+
## 6. 用户友好提示
|
|
302
|
+
|
|
303
|
+
### 错误提示规范
|
|
304
|
+
|
|
305
|
+
```java
|
|
306
|
+
// ✅ 好的:用户友好提示
|
|
307
|
+
throw new ServiceException("订单已发货,无法取消");
|
|
308
|
+
throw new ServiceException("库存不足,请减少购买数量");
|
|
309
|
+
throw new ServiceException("验证码已过期,请重新获取");
|
|
310
|
+
throw new ServiceException("该用户名已被注册,请换一个试试");
|
|
311
|
+
|
|
312
|
+
// ❌ 不好:技术术语
|
|
313
|
+
throw new ServiceException("order.status.invalid");
|
|
314
|
+
throw new ServiceException("NullPointerException at line 123");
|
|
315
|
+
throw new ServiceException("数据库连接失败");
|
|
316
|
+
throw new ServiceException("Duplicate entry for key 'uk_username'");
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
---
|
|
320
|
+
|
|
321
|
+
## 7. 事务异常处理
|
|
322
|
+
|
|
323
|
+
```java
|
|
324
|
+
@Transactional(rollbackFor = Exception.class) // 所有异常都回滚
|
|
325
|
+
public void batchOperation() {
|
|
326
|
+
// 业务逻辑
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// ✅ 好的:指定回滚异常类型
|
|
330
|
+
@Transactional(rollbackFor = Exception.class)
|
|
331
|
+
|
|
332
|
+
// ❌ 不好:使用默认(只回滚 RuntimeException)
|
|
333
|
+
@Transactional
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
338
|
+
## 错误处理检查清单
|
|
339
|
+
|
|
340
|
+
- [ ] 业务异常使用 `new ServiceException()`(不是 `ServiceException.of()`)
|
|
341
|
+
- [ ] 条件检查使用 `if + ObjectUtil.isNull()` 判断
|
|
342
|
+
- [ ] 参数校验使用 `@Validated(XxxGroup.class)`
|
|
343
|
+
- [ ] 事务方法添加 `@Transactional(rollbackFor = Exception.class)`
|
|
344
|
+
- [ ] 日志记录异常堆栈:`log.error("msg: {}", e.getMessage(), e)`
|
|
345
|
+
- [ ] 日志使用占位符 `{}`,不使用字符串拼接
|
|
346
|
+
- [ ] 敏感信息脱敏后再记录日志
|
|
347
|
+
- [ ] 重要操作记录 INFO 日志
|
|
348
|
+
- [ ] 错误提示使用用户友好语言
|
|
349
|
+
|
|
350
|
+
---
|
|
351
|
+
|
|
352
|
+
## 快速对照表
|
|
353
|
+
|
|
354
|
+
| ❌ 错误写法 | ✅ 正确写法 |
|
|
355
|
+
|-----------|-----------|
|
|
356
|
+
| `throw ServiceException.of("msg")` | `throw new ServiceException("msg")` |
|
|
357
|
+
| `ServiceException.throwIf(cond, "msg")` | `if (cond) { throw new ServiceException("msg"); }` |
|
|
358
|
+
| `ServiceException.notNull(obj, "msg")` | `if (ObjectUtil.isNull(obj)) { throw new ServiceException("msg"); }` |
|
|
359
|
+
| `log.error("失败: " + e.getMessage())` | `log.error("失败: {}", e.getMessage(), e)` |
|
|
360
|
+
| `@Transactional` | `@Transactional(rollbackFor = Exception.class)` |
|
|
361
|
+
| `throw new ServiceException("DB error")` | `throw new ServiceException("数据保存失败,请重试")` |
|