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.
Files changed (313) hide show
  1. package/.claude/agents/code-reviewer.md +139 -0
  2. package/.claude/agents/project-manager.md +159 -0
  3. package/.claude/audio/completed.wav +0 -0
  4. package/.claude/commands/add-todo.md +255 -0
  5. package/.claude/commands/check.md +210 -0
  6. package/.claude/commands/crud.md +454 -0
  7. package/.claude/commands/dev.md +503 -0
  8. package/.claude/commands/init-docs.md +681 -0
  9. package/.claude/commands/next.md +251 -0
  10. package/.claude/commands/progress.md +242 -0
  11. package/.claude/commands/start.md +199 -0
  12. package/.claude/commands/sync.md +307 -0
  13. package/.claude/commands/update-status.md +428 -0
  14. package/.claude/docs/Mixin/344/275/277/347/224/250/346/214/207/345/215/227.md +299 -0
  15. package/.claude/docs/README.md +167 -0
  16. package/.claude/docs//345/211/215/347/253/257/345/274/200/345/217/221/346/214/207/345/215/227.md +599 -0
  17. package/.claude/docs//345/220/216/347/253/257/345/274/200/345/217/221/346/214/207/345/215/227.md +726 -0
  18. 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
  19. 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
  20. 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
  21. 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
  22. 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
  23. package/.claude/docs//346/241/206/346/236/266/350/257/264/346/230/216.md +393 -0
  24. package/.claude/docs//350/267/257/347/224/261/351/205/215/347/275/256/346/214/207/345/215/227.md +246 -0
  25. package/.claude/framework-config.json +73 -0
  26. package/.claude/hooks/pre-tool-use.js +117 -0
  27. package/.claude/hooks/skill-forced-eval.js +167 -0
  28. package/.claude/hooks/stop.js +58 -0
  29. package/.claude/settings.json +41 -0
  30. package/.claude/skills/add-skill/SKILL.md +352 -0
  31. package/.claude/skills/api-development/SKILL.md +560 -0
  32. package/.claude/skills/architecture-design/SKILL.md +756 -0
  33. package/.claude/skills/backend-annotations/SKILL.md +674 -0
  34. package/.claude/skills/banana-image/CHANGELOG.md +37 -0
  35. package/.claude/skills/banana-image/README.md +146 -0
  36. package/.claude/skills/banana-image/SKILL.md +164 -0
  37. package/.claude/skills/banana-image/assets/logo.png +0 -0
  38. package/.claude/skills/banana-image/references/advanced-usage.md +189 -0
  39. package/.claude/skills/banana-image/scripts/apply_template.py +125 -0
  40. package/.claude/skills/banana-image/scripts/banana_image_exec.ts +412 -0
  41. package/.claude/skills/banana-image/scripts/batch_prep.py +82 -0
  42. package/.claude/skills/banana-image/scripts/package-lock.json +1437 -0
  43. package/.claude/skills/banana-image/scripts/package.json +18 -0
  44. package/.claude/skills/banana-image/scripts/requirements.txt +10 -0
  45. package/.claude/skills/banana-image/templates/poster.json +22 -0
  46. package/.claude/skills/banana-image/templates/product.json +17 -0
  47. package/.claude/skills/banana-image/templates/social.json +22 -0
  48. package/.claude/skills/banana-image/templates/thumbnail.json +17 -0
  49. package/.claude/skills/brainstorm/SKILL.md +648 -0
  50. package/.claude/skills/bug-detective/SKILL.md +1206 -0
  51. package/.claude/skills/code-patterns/SKILL.md +590 -0
  52. package/.claude/skills/collaborating-with-codex/SKILL.md +174 -0
  53. package/.claude/skills/collaborating-with-codex/scripts/codex_bridge.py +275 -0
  54. package/.claude/skills/collaborating-with-gemini/SKILL.md +194 -0
  55. package/.claude/skills/collaborating-with-gemini/scripts/gemini_bridge.py +275 -0
  56. package/.claude/skills/crud-development/SKILL.md +649 -0
  57. package/.claude/skills/data-permission/SKILL.md +599 -0
  58. package/.claude/skills/database-ops/SKILL.md +407 -0
  59. package/.claude/skills/error-handler/SKILL.md +371 -0
  60. package/.claude/skills/file-oss-management/SKILL.md +863 -0
  61. package/.claude/skills/git-workflow/SKILL.md +375 -0
  62. package/.claude/skills/json-serialization/SKILL.md +357 -0
  63. package/.claude/skills/leniu-api-development/SKILL.md +803 -0
  64. package/.claude/skills/leniu-architecture-design/SKILL.md +598 -0
  65. package/.claude/skills/leniu-backend-annotations/SKILL.md +664 -0
  66. package/.claude/skills/leniu-code-patterns/SKILL.md +365 -0
  67. package/.claude/skills/leniu-crud-development/SKILL.md +1110 -0
  68. package/.claude/skills/leniu-data-permission/SKILL.md +256 -0
  69. package/.claude/skills/leniu-database-ops/SKILL.md +426 -0
  70. package/.claude/skills/leniu-error-handler/SKILL.md +462 -0
  71. package/.claude/skills/leniu-java-amount-handling/SKILL.md +461 -0
  72. package/.claude/skills/leniu-java-code-style/SKILL.md +510 -0
  73. package/.claude/skills/leniu-java-concurrent/SKILL.md +400 -0
  74. package/.claude/skills/leniu-java-entity/SKILL.md +751 -0
  75. package/.claude/skills/leniu-java-export/SKILL.md +560 -0
  76. package/.claude/skills/leniu-java-logging/SKILL.md +832 -0
  77. package/.claude/skills/leniu-java-mq/SKILL.md +338 -0
  78. package/.claude/skills/leniu-java-mybatis/SKILL.md +640 -0
  79. package/.claude/skills/leniu-java-report-query-param/SKILL.md +291 -0
  80. package/.claude/skills/leniu-java-task/SKILL.md +367 -0
  81. package/.claude/skills/leniu-java-total-line/SKILL.md +195 -0
  82. package/.claude/skills/leniu-marketing-price-rule-customizer/SKILL.md +301 -0
  83. package/.claude/skills/leniu-marketing-recharge-rule-customizer/SKILL.md +285 -0
  84. package/.claude/skills/leniu-mealtime/SKILL.md +215 -0
  85. package/.claude/skills/leniu-redis-cache/SKILL.md +316 -0
  86. package/.claude/skills/leniu-security-guard/SKILL.md +520 -0
  87. package/.claude/skills/leniu-utils-toolkit/SKILL.md +380 -0
  88. package/.claude/skills/openspec-apply-change/SKILL.md +156 -0
  89. package/.claude/skills/openspec-archive-change/SKILL.md +114 -0
  90. package/.claude/skills/openspec-bulk-archive-change/SKILL.md +246 -0
  91. package/.claude/skills/openspec-continue-change/SKILL.md +118 -0
  92. package/.claude/skills/openspec-explore/SKILL.md +290 -0
  93. package/.claude/skills/openspec-ff-change/SKILL.md +101 -0
  94. package/.claude/skills/openspec-new-change/SKILL.md +74 -0
  95. package/.claude/skills/openspec-onboard/SKILL.md +529 -0
  96. package/.claude/skills/openspec-sync-specs/SKILL.md +138 -0
  97. package/.claude/skills/openspec-verify-change/SKILL.md +168 -0
  98. package/.claude/skills/performance-doctor/SKILL.md +627 -0
  99. package/.claude/skills/project-navigator/SKILL.md +305 -0
  100. package/.claude/skills/redis-cache/SKILL.md +839 -0
  101. package/.claude/skills/scheduled-jobs/SKILL.md +633 -0
  102. package/.claude/skills/security-guard/SKILL.md +748 -0
  103. package/.claude/skills/sms-mail/SKILL.md +766 -0
  104. package/.claude/skills/social-login/SKILL.md +668 -0
  105. package/.claude/skills/store-pc/SKILL.md +366 -0
  106. package/.claude/skills/task-tracker/SKILL.md +307 -0
  107. package/.claude/skills/tech-decision/SKILL.md +393 -0
  108. package/.claude/skills/tenant-management/SKILL.md +603 -0
  109. package/.claude/skills/test-development/SKILL.md +755 -0
  110. package/.claude/skills/ui-pc/SKILL.md +438 -0
  111. package/.claude/skills/utils-toolkit/SKILL.md +615 -0
  112. package/.claude/skills/websocket-sse/SKILL.md +716 -0
  113. package/.claude/skills/workflow-engine/SKILL.md +676 -0
  114. package/.claude/templates//345/276/205/345/212/236/346/270/205/345/215/225/346/250/241/346/235/277.md +56 -0
  115. package/.claude/templates//351/234/200/346/261/202/346/226/207/346/241/243/346/250/241/346/235/277.md +85 -0
  116. package/.claude/templates//351/241/271/347/233/256/347/212/266/346/200/201/346/250/241/346/235/277.md +43 -0
  117. package/.codex/skills/add-skill/SKILL.md +352 -0
  118. package/.codex/skills/add-todo/SKILL.md +269 -0
  119. package/.codex/skills/api-development/SKILL.md +693 -0
  120. package/.codex/skills/architecture-design/SKILL.md +628 -0
  121. package/.codex/skills/backend-annotations/SKILL.md +664 -0
  122. package/.codex/skills/banana-image/CHANGELOG.md +37 -0
  123. package/.codex/skills/banana-image/README.md +146 -0
  124. package/.codex/skills/banana-image/SKILL.md +164 -0
  125. package/.codex/skills/banana-image/assets/logo.png +0 -0
  126. package/.codex/skills/banana-image/references/advanced-usage.md +189 -0
  127. package/.codex/skills/banana-image/scripts/apply_template.py +125 -0
  128. package/.codex/skills/banana-image/scripts/banana_image_exec.ts +412 -0
  129. package/.codex/skills/banana-image/scripts/batch_prep.py +82 -0
  130. package/.codex/skills/banana-image/scripts/package-lock.json +1437 -0
  131. package/.codex/skills/banana-image/scripts/package.json +18 -0
  132. package/.codex/skills/banana-image/scripts/requirements.txt +10 -0
  133. package/.codex/skills/banana-image/templates/poster.json +22 -0
  134. package/.codex/skills/banana-image/templates/product.json +17 -0
  135. package/.codex/skills/banana-image/templates/social.json +22 -0
  136. package/.codex/skills/banana-image/templates/thumbnail.json +17 -0
  137. package/.codex/skills/brainstorm/SKILL.md +648 -0
  138. package/.codex/skills/bug-detective/SKILL.md +1206 -0
  139. package/.codex/skills/check/SKILL.md +367 -0
  140. package/.codex/skills/code-patterns/SKILL.md +442 -0
  141. package/.codex/skills/collaborating-with-codex/SKILL.md +174 -0
  142. package/.codex/skills/collaborating-with-codex/scripts/codex_bridge.py +275 -0
  143. package/.codex/skills/collaborating-with-gemini/SKILL.md +194 -0
  144. package/.codex/skills/collaborating-with-gemini/scripts/gemini_bridge.py +275 -0
  145. package/.codex/skills/crud/SKILL.md +265 -0
  146. package/.codex/skills/crud-development/SKILL.md +637 -0
  147. package/.codex/skills/data-permission/SKILL.md +591 -0
  148. package/.codex/skills/database-ops/SKILL.md +553 -0
  149. package/.codex/skills/dev/SKILL.md +187 -0
  150. package/.codex/skills/error-handler/SKILL.md +361 -0
  151. package/.codex/skills/file-oss-management/SKILL.md +863 -0
  152. package/.codex/skills/git-workflow/SKILL.md +375 -0
  153. package/.codex/skills/init-docs/SKILL.md +194 -0
  154. package/.codex/skills/json-serialization/SKILL.md +357 -0
  155. package/.codex/skills/leniu-api-development/SKILL.md +803 -0
  156. package/.codex/skills/leniu-architecture-design/SKILL.md +594 -0
  157. package/.codex/skills/leniu-backend-annotations/SKILL.md +662 -0
  158. package/.codex/skills/leniu-code-patterns/SKILL.md +365 -0
  159. package/.codex/skills/leniu-crud-development/SKILL.md +1110 -0
  160. package/.codex/skills/leniu-data-permission/SKILL.md +256 -0
  161. package/.codex/skills/leniu-database-ops/SKILL.md +426 -0
  162. package/.codex/skills/leniu-error-handler/SKILL.md +462 -0
  163. package/.codex/skills/leniu-java-amount-handling/SKILL.md +461 -0
  164. package/.codex/skills/leniu-java-code-style/SKILL.md +510 -0
  165. package/.codex/skills/leniu-java-concurrent/SKILL.md +400 -0
  166. package/.codex/skills/leniu-java-entity/SKILL.md +751 -0
  167. package/.codex/skills/leniu-java-export/SKILL.md +560 -0
  168. package/.codex/skills/leniu-java-logging/SKILL.md +832 -0
  169. package/.codex/skills/leniu-java-mq/SKILL.md +338 -0
  170. package/.codex/skills/leniu-java-mybatis/SKILL.md +640 -0
  171. package/.codex/skills/leniu-java-report-query-param/SKILL.md +291 -0
  172. package/.codex/skills/leniu-java-task/SKILL.md +367 -0
  173. package/.codex/skills/leniu-java-total-line/SKILL.md +195 -0
  174. package/.codex/skills/leniu-marketing-price-rule-customizer/SKILL.md +301 -0
  175. package/.codex/skills/leniu-marketing-recharge-rule-customizer/SKILL.md +285 -0
  176. package/.codex/skills/leniu-mealtime/SKILL.md +215 -0
  177. package/.codex/skills/leniu-redis-cache/SKILL.md +316 -0
  178. package/.codex/skills/leniu-security-guard/SKILL.md +520 -0
  179. package/.codex/skills/leniu-utils-toolkit/SKILL.md +378 -0
  180. package/.codex/skills/next/SKILL.md +137 -0
  181. package/.codex/skills/openspec-apply-change/SKILL.md +156 -0
  182. package/.codex/skills/openspec-archive-change/SKILL.md +114 -0
  183. package/.codex/skills/openspec-bulk-archive-change/SKILL.md +246 -0
  184. package/.codex/skills/openspec-continue-change/SKILL.md +118 -0
  185. package/.codex/skills/openspec-explore/SKILL.md +290 -0
  186. package/.codex/skills/openspec-ff-change/SKILL.md +101 -0
  187. package/.codex/skills/openspec-new-change/SKILL.md +74 -0
  188. package/.codex/skills/openspec-onboard/SKILL.md +529 -0
  189. package/.codex/skills/openspec-sync-specs/SKILL.md +138 -0
  190. package/.codex/skills/openspec-verify-change/SKILL.md +168 -0
  191. package/.codex/skills/performance-doctor/SKILL.md +627 -0
  192. package/.codex/skills/progress/SKILL.md +193 -0
  193. package/.codex/skills/project-navigator/SKILL.md +286 -0
  194. package/.codex/skills/redis-cache/SKILL.md +829 -0
  195. package/.codex/skills/scheduled-jobs/SKILL.md +633 -0
  196. package/.codex/skills/security-guard/SKILL.md +739 -0
  197. package/.codex/skills/sms-mail/SKILL.md +766 -0
  198. package/.codex/skills/social-login/SKILL.md +668 -0
  199. package/.codex/skills/start/SKILL.md +154 -0
  200. package/.codex/skills/store-pc/SKILL.md +491 -0
  201. package/.codex/skills/sync/SKILL.md +149 -0
  202. package/.codex/skills/task-tracker/SKILL.md +307 -0
  203. package/.codex/skills/tech-decision/SKILL.md +393 -0
  204. package/.codex/skills/tenant-management/SKILL.md +603 -0
  205. package/.codex/skills/test-development/SKILL.md +755 -0
  206. package/.codex/skills/ui-pc/SKILL.md +475 -0
  207. package/.codex/skills/update-status/SKILL.md +159 -0
  208. package/.codex/skills/utils-toolkit/SKILL.md +593 -0
  209. package/.codex/skills/websocket-sse/SKILL.md +716 -0
  210. package/.codex/skills/workflow-engine/SKILL.md +676 -0
  211. package/.cursor/agents/code-reviewer.md +139 -0
  212. package/.cursor/agents/project-manager.md +159 -0
  213. package/.cursor/commands/opsx-apply.md +152 -0
  214. package/.cursor/commands/opsx-archive.md +157 -0
  215. package/.cursor/commands/opsx-bulk-archive.md +242 -0
  216. package/.cursor/commands/opsx-continue.md +114 -0
  217. package/.cursor/commands/opsx-explore.md +174 -0
  218. package/.cursor/commands/opsx-ff.md +94 -0
  219. package/.cursor/commands/opsx-new.md +69 -0
  220. package/.cursor/commands/opsx-onboard.md +525 -0
  221. package/.cursor/commands/opsx-sync.md +134 -0
  222. package/.cursor/commands/opsx-verify.md +164 -0
  223. package/.cursor/mcp.json +22 -0
  224. package/.cursor/skills/add-skill/SKILL.md +352 -0
  225. package/.cursor/skills/api-development/SKILL.md +560 -0
  226. package/.cursor/skills/architecture-design/SKILL.md +756 -0
  227. package/.cursor/skills/backend-annotations/SKILL.md +674 -0
  228. package/.cursor/skills/banana-image/CHANGELOG.md +37 -0
  229. package/.cursor/skills/banana-image/README.md +146 -0
  230. package/.cursor/skills/banana-image/SKILL.md +164 -0
  231. package/.cursor/skills/banana-image/assets/logo.png +0 -0
  232. package/.cursor/skills/banana-image/references/advanced-usage.md +189 -0
  233. package/.cursor/skills/banana-image/scripts/apply_template.py +125 -0
  234. package/.cursor/skills/banana-image/scripts/banana_image_exec.ts +412 -0
  235. package/.cursor/skills/banana-image/scripts/batch_prep.py +82 -0
  236. package/.cursor/skills/banana-image/scripts/package-lock.json +1437 -0
  237. package/.cursor/skills/banana-image/scripts/package.json +18 -0
  238. package/.cursor/skills/banana-image/scripts/requirements.txt +10 -0
  239. package/.cursor/skills/banana-image/templates/poster.json +22 -0
  240. package/.cursor/skills/banana-image/templates/product.json +17 -0
  241. package/.cursor/skills/banana-image/templates/social.json +22 -0
  242. package/.cursor/skills/banana-image/templates/thumbnail.json +17 -0
  243. package/.cursor/skills/brainstorm/SKILL.md +648 -0
  244. package/.cursor/skills/bug-detective/SKILL.md +1206 -0
  245. package/.cursor/skills/code-patterns/SKILL.md +590 -0
  246. package/.cursor/skills/collaborating-with-codex/SKILL.md +174 -0
  247. package/.cursor/skills/collaborating-with-codex/scripts/codex_bridge.py +275 -0
  248. package/.cursor/skills/collaborating-with-gemini/SKILL.md +194 -0
  249. package/.cursor/skills/collaborating-with-gemini/scripts/gemini_bridge.py +275 -0
  250. package/.cursor/skills/crud-development/SKILL.md +649 -0
  251. package/.cursor/skills/data-permission/SKILL.md +599 -0
  252. package/.cursor/skills/database-ops/SKILL.md +407 -0
  253. package/.cursor/skills/error-handler/SKILL.md +371 -0
  254. package/.cursor/skills/file-oss-management/SKILL.md +863 -0
  255. package/.cursor/skills/git-workflow/SKILL.md +375 -0
  256. package/.cursor/skills/json-serialization/SKILL.md +357 -0
  257. package/.cursor/skills/leniu-api-development/SKILL.md +803 -0
  258. package/.cursor/skills/leniu-architecture-design/SKILL.md +598 -0
  259. package/.cursor/skills/leniu-backend-annotations/SKILL.md +664 -0
  260. package/.cursor/skills/leniu-code-patterns/SKILL.md +365 -0
  261. package/.cursor/skills/leniu-crud-development/SKILL.md +1110 -0
  262. package/.cursor/skills/leniu-data-permission/SKILL.md +256 -0
  263. package/.cursor/skills/leniu-database-ops/SKILL.md +426 -0
  264. package/.cursor/skills/leniu-error-handler/SKILL.md +462 -0
  265. package/.cursor/skills/leniu-java-amount-handling/SKILL.md +461 -0
  266. package/.cursor/skills/leniu-java-code-style/SKILL.md +510 -0
  267. package/.cursor/skills/leniu-java-concurrent/SKILL.md +400 -0
  268. package/.cursor/skills/leniu-java-entity/SKILL.md +751 -0
  269. package/.cursor/skills/leniu-java-export/SKILL.md +560 -0
  270. package/.cursor/skills/leniu-java-logging/SKILL.md +832 -0
  271. package/.cursor/skills/leniu-java-mq/SKILL.md +338 -0
  272. package/.cursor/skills/leniu-java-mybatis/SKILL.md +640 -0
  273. package/.cursor/skills/leniu-java-report-query-param/SKILL.md +291 -0
  274. package/.cursor/skills/leniu-java-task/SKILL.md +367 -0
  275. package/.cursor/skills/leniu-java-total-line/SKILL.md +195 -0
  276. package/.cursor/skills/leniu-marketing-price-rule-customizer/SKILL.md +301 -0
  277. package/.cursor/skills/leniu-marketing-recharge-rule-customizer/SKILL.md +285 -0
  278. package/.cursor/skills/leniu-mealtime/SKILL.md +215 -0
  279. package/.cursor/skills/leniu-redis-cache/SKILL.md +316 -0
  280. package/.cursor/skills/leniu-security-guard/SKILL.md +520 -0
  281. package/.cursor/skills/leniu-utils-toolkit/SKILL.md +380 -0
  282. package/.cursor/skills/openspec-apply-change/SKILL.md +156 -0
  283. package/.cursor/skills/openspec-archive-change/SKILL.md +114 -0
  284. package/.cursor/skills/openspec-bulk-archive-change/SKILL.md +246 -0
  285. package/.cursor/skills/openspec-continue-change/SKILL.md +118 -0
  286. package/.cursor/skills/openspec-explore/SKILL.md +290 -0
  287. package/.cursor/skills/openspec-ff-change/SKILL.md +101 -0
  288. package/.cursor/skills/openspec-new-change/SKILL.md +74 -0
  289. package/.cursor/skills/openspec-onboard/SKILL.md +529 -0
  290. package/.cursor/skills/openspec-sync-specs/SKILL.md +138 -0
  291. package/.cursor/skills/openspec-verify-change/SKILL.md +168 -0
  292. package/.cursor/skills/performance-doctor/SKILL.md +627 -0
  293. package/.cursor/skills/project-navigator/SKILL.md +305 -0
  294. package/.cursor/skills/redis-cache/SKILL.md +839 -0
  295. package/.cursor/skills/scheduled-jobs/SKILL.md +633 -0
  296. package/.cursor/skills/security-guard/SKILL.md +748 -0
  297. package/.cursor/skills/sms-mail/SKILL.md +766 -0
  298. package/.cursor/skills/social-login/SKILL.md +668 -0
  299. package/.cursor/skills/store-pc/SKILL.md +366 -0
  300. package/.cursor/skills/task-tracker/SKILL.md +307 -0
  301. package/.cursor/skills/tech-decision/SKILL.md +393 -0
  302. package/.cursor/skills/tenant-management/SKILL.md +603 -0
  303. package/.cursor/skills/test-development/SKILL.md +755 -0
  304. package/.cursor/skills/ui-pc/SKILL.md +438 -0
  305. package/.cursor/skills/utils-toolkit/SKILL.md +615 -0
  306. package/.cursor/skills/websocket-sse/SKILL.md +716 -0
  307. package/.cursor/skills/workflow-engine/SKILL.md +676 -0
  308. package/AGENTS.md +669 -0
  309. package/CLAUDE.md +205 -0
  310. package/README.md +205 -0
  311. package/bin/index.js +179 -0
  312. package/init.sh +178 -0
  313. package/package.json +27 -0
@@ -0,0 +1,693 @@
1
+ ---
2
+ name: api-development
3
+ description: |
4
+ 后端 API 接口设计规范。基于 RuoYi-Vue-Plus 三层架构的 RESTful API 开发指南。
5
+
6
+ 触发场景:
7
+ - 设计 RESTful API 接口
8
+ - 编写 Controller 层代码
9
+ - 配置接口权限、日志、防重复提交注解
10
+ - 接口返回值类型选择(R/TableDataInfo/void)
11
+ - 数据验证(@Validated/ValidatorUtils)
12
+
13
+ 触发词:API、接口、RESTful、Controller、GetMapping、PostMapping、@SaCheckPermission、@Log、@RepeatSubmit、TableDataInfo、R<T>、toAjax、接口规范
14
+ ---
15
+
16
+ # API 接口设计规范(RuoYi-Vue-Plus 三层架构版)
17
+
18
+ > **⚠️ 重要声明**: 本项目是 **RuoYi-Vue-Plus 纯后端项目**,采用三层架构!
19
+ > 本文档规范基于 **TestDemo 模块**的真实 API 实现。
20
+
21
+ ## 核心架构特征
22
+
23
+ | 对比项 | 本项目 (RuoYi-Vue-Plus) |
24
+ |--------|----------------------|
25
+ | **包名前缀** | `org.dromara.*` |
26
+ | **API 路径** | 标准 RESTful:`/list`、`/{id}`、`/export`、`/importData` |
27
+ | **Controller 基类** | `extends BaseController` |
28
+ | **HTTP 方法** | GET(查询), POST(新增/导出/导入), PUT(修改), DELETE(删除) |
29
+ | **返回类型** | `R<T>`(单个数据)或 `TableDataInfo<T>`(列表)或 `void`(导出) |
30
+ | **权限控制** | `@SaCheckPermission("module:resource:operation")` |
31
+ | **操作日志** | `@Log(title = "xxx", businessType = BusinessType.XXX)` |
32
+ | **幂等性** | `@RepeatSubmit(interval = 2, timeUnit = TimeUnit.SECONDS)` |
33
+ | **数据验证** | `@Validated(QueryGroup.class)` 或 `ValidatorUtils.validate()` |
34
+ | **Excel 处理** | `ExcelUtil.importExcel()` 和 `ExcelUtil.exportExcel()` |
35
+
36
+ ---
37
+
38
+ ## 1. 标准 RESTful API 路径规范
39
+
40
+ ### 路径格式
41
+
42
+ | 操作 | HTTP 方法 | 路径 | 说明 |
43
+ |------|---------|------|------|
44
+ | **列表查询** | GET | `/list` | 分页查询列表 |
45
+ | **获取详情** | GET | `/{id}` | 根据 ID 查询单个数据 |
46
+ | **新增** | POST | `/` (空) | 创建新数据 |
47
+ | **修改** | PUT | `/` (空) | 更新数据 |
48
+ | **删除** | DELETE | `/{ids}` | 批量删除 |
49
+ | **导出** | POST | `/export` | 导出数据到 Excel |
50
+ | **导入** | POST | `/importData` | 从 Excel 导入数据 |
51
+ | **自定义查询** | GET | `/page` | 自定义分页逻辑 |
52
+
53
+ ### 路径示例
54
+
55
+ ```java
56
+ @RequestMapping("/demo/demo") // 基础路径
57
+ public class TestDemoController {
58
+
59
+ @GetMapping("/list") // GET /demo/demo/list
60
+ @GetMapping("/{id}") // GET /demo/demo/{id}
61
+ @PostMapping() // POST /demo/demo
62
+ @PutMapping() // PUT /demo/demo
63
+ @DeleteMapping("/{ids}") // DELETE /demo/demo/{ids}
64
+ @PostMapping("/export") // POST /demo/demo/export
65
+ @PostMapping("/importData") // POST /demo/demo/importData
66
+ }
67
+ ```
68
+
69
+ ---
70
+
71
+ ## 2. API 方法完整模板
72
+
73
+ ### 2.1 列表查询(分页)
74
+
75
+ ```java
76
+ /**
77
+ * 查询列表
78
+ * ✅ 返回 TableDataInfo<T>(自动分页)
79
+ * ✅ 使用 @Validated(QueryGroup.class) 进行参数验证
80
+ * ✅ 使用 @SaCheckPermission 进行权限检查
81
+ */
82
+ @SaCheckPermission("demo:demo:list")
83
+ @GetMapping("/list")
84
+ public TableDataInfo<TestDemoVo> list(
85
+ @Validated(QueryGroup.class) TestDemoBo bo,
86
+ PageQuery pageQuery) {
87
+ return testDemoService.queryPageList(bo, pageQuery);
88
+ }
89
+ ```
90
+
91
+ **关键点**:
92
+ - `@Validated(QueryGroup.class)` - 使用查询分组进行验证
93
+ - `PageQuery` - 分页参数(页码、页大小、排序)
94
+ - `TableDataInfo<T>` - 自动包装分页结果(包含 total、rows)
95
+ - `@SaCheckPermission` - 权限控制,参数格式:"module:resource:operation"
96
+
97
+ ---
98
+
99
+ ### 2.2 自定义分页查询
100
+
101
+ ```java
102
+ /**
103
+ * 自定义分页查询
104
+ * ✅ 用于需要特殊业务逻辑的分页查询
105
+ * ✅ 调用 Service 的 customPageList() 方法
106
+ */
107
+ @SaCheckPermission("demo:demo:list")
108
+ @GetMapping("/page")
109
+ public TableDataInfo<TestDemoVo> page(
110
+ @Validated(QueryGroup.class) TestDemoBo bo,
111
+ PageQuery pageQuery) {
112
+ return testDemoService.customPageList(bo, pageQuery);
113
+ }
114
+ ```
115
+
116
+ **使用场景**:
117
+ - 需要与标准列表查询不同的业务逻辑
118
+ - 数据需要额外的计算或组装
119
+ - 返回结果需要特殊处理
120
+
121
+ ---
122
+
123
+ ### 2.3 获取详情
124
+
125
+ ```java
126
+ /**
127
+ * 获取详情
128
+ * ✅ 返回 R<T> 包装单个数据
129
+ * ✅ 使用 @NotNull 验证 ID 参数
130
+ * ✅ @SaCheckPermission 使用 "query" 操作
131
+ */
132
+ @SaCheckPermission("demo:demo:query")
133
+ @GetMapping("/{id}")
134
+ public R<TestDemoVo> getInfo(
135
+ @NotNull(message = "主键不能为空")
136
+ @PathVariable("id") Long id) {
137
+ return R.ok(testDemoService.queryById(id));
138
+ }
139
+ ```
140
+
141
+ **关键点**:
142
+ - `@PathVariable` - 从 URL 路径提取 ID
143
+ - `@NotNull` - 参数验证注解
144
+ - `R.ok(data)` - 包装成功响应
145
+ - `@SaCheckPermission` - 参数为 "query" 表示查询权限
146
+
147
+ ---
148
+
149
+ ### 2.4 新增数据
150
+
151
+ ```java
152
+ /**
153
+ * 新增
154
+ * ✅ POST 到空路径
155
+ * ✅ 返回 R<Void> via toAjax()
156
+ * ✅ 使用 ValidatorUtils 进行验证(非 @Validated)
157
+ * ✅ @RepeatSubmit 防止重复提交
158
+ * ✅ @Log 记录操作日志
159
+ */
160
+ @SaCheckPermission("demo:demo:add")
161
+ @Log(title = "测试单表", businessType = BusinessType.INSERT)
162
+ @RepeatSubmit(interval = 2, timeUnit = TimeUnit.SECONDS,
163
+ message = "{repeat.submit.message}")
164
+ @PostMapping()
165
+ public R<Void> add(@RequestBody TestDemoBo bo) {
166
+ // ✅ 使用 ValidatorUtils 而非 @Validated(用于非 Controller 校验)
167
+ ValidatorUtils.validate(bo, AddGroup.class);
168
+ return toAjax(testDemoService.insertByBo(bo));
169
+ }
170
+ ```
171
+
172
+ **关键点**:
173
+ - `@PostMapping()` - POST 到空路径(不带子路径)
174
+ - `@RequestBody` - 从请求体解析 JSON
175
+ - `ValidatorUtils.validate(bo, AddGroup.class)` - 手动验证
176
+ - `@RepeatSubmit(interval = 2, timeUnit = TimeUnit.SECONDS)` - 2 秒内防重
177
+ - `toAjax()` - 继承自 BaseController,将 boolean/int 转 R<Void>
178
+ - `@Log` 记录日志,`businessType = BusinessType.INSERT`
179
+
180
+ ---
181
+
182
+ ### 2.5 修改数据
183
+
184
+ ```java
185
+ /**
186
+ * 修改
187
+ * ✅ PUT 到空路径
188
+ * ✅ 返回 R<Void> via toAjax()
189
+ * ✅ 使用 @Validated(EditGroup.class) 验证
190
+ * ✅ @RepeatSubmit 使用默认配置
191
+ * ✅ @Log 记录操作日志
192
+ */
193
+ @SaCheckPermission("demo:demo:edit")
194
+ @Log(title = "测试单表", businessType = BusinessType.UPDATE)
195
+ @RepeatSubmit
196
+ @PutMapping()
197
+ public R<Void> edit(
198
+ @Validated(EditGroup.class) @RequestBody TestDemoBo bo) {
199
+ return toAjax(testDemoService.updateByBo(bo));
200
+ }
201
+ ```
202
+
203
+ **关键点**:
204
+ - `@PutMapping()` - PUT 到空路径
205
+ - `@Validated(EditGroup.class)` - BO 级别验证(BO 上需要标注 @NotNull(groups = {EditGroup.class}))
206
+ - `@RepeatSubmit` - 使用默认防重配置(不指定间隔,框架默认值)
207
+ - `toAjax()` - 返回结果包装
208
+ - `businessType = BusinessType.UPDATE`
209
+
210
+ ---
211
+
212
+ ### 2.6 删除数据
213
+
214
+ ```java
215
+ /**
216
+ * 删除
217
+ * ✅ DELETE /{ids} 接受多个 ID
218
+ * ✅ 返回 R<Void> via toAjax()
219
+ * ✅ 使用 @NotEmpty 验证 ID 数组非空
220
+ * ✅ @Log 记录操作日志
221
+ */
222
+ @SaCheckPermission("demo:demo:remove")
223
+ @Log(title = "测试单表", businessType = BusinessType.DELETE)
224
+ @DeleteMapping("/{ids}")
225
+ public R<Void> remove(
226
+ @NotEmpty(message = "主键不能为空")
227
+ @PathVariable Long[] ids) {
228
+ return toAjax(testDemoService.deleteWithValidByIds(
229
+ Arrays.asList(ids), true));
230
+ }
231
+ ```
232
+
233
+ **关键点**:
234
+ - `@DeleteMapping("/{ids}")` - DELETE 到 /{ids} 路径
235
+ - `Long[] ids` - 接收数组格式 ID(路径参数)
236
+ - `@NotEmpty` - 验证数组非空
237
+ - `Arrays.asList(ids)` - 转换为 List
238
+ - `true` 参数 - 通常表示验证权限或检查是否存在
239
+ - `businessType = BusinessType.DELETE`
240
+
241
+ ---
242
+
243
+ ### 2.7 导出数据
244
+
245
+ ```java
246
+ /**
247
+ * 导出
248
+ * ✅ POST 到 /export 路径
249
+ * ✅ 返回 void(直接写入 HttpServletResponse)
250
+ * ✅ 使用 @Validated 验证查询参数
251
+ * ✅ @Log 记录操作日志
252
+ */
253
+ @SaCheckPermission("demo:demo:export")
254
+ @Log(title = "测试单表", businessType = BusinessType.EXPORT)
255
+ @PostMapping("/export")
256
+ public void export(
257
+ @Validated TestDemoBo bo,
258
+ HttpServletResponse response) {
259
+ List<TestDemoVo> list = testDemoService.queryList(bo);
260
+ ExcelUtil.exportExcel(list, "测试单表", TestDemoVo.class, response);
261
+ }
262
+ ```
263
+
264
+ **关键点**:
265
+ - `@PostMapping("/export")` - POST 到 /export 子路径
266
+ - `HttpServletResponse response` - 用于写入 Excel 文件
267
+ - 返回 `void` - 直接返回文件,不需要 R<T> 包装
268
+ - `ExcelUtil.exportExcel(records, title, voClass, response)` - 导出 Excel
269
+ - `businessType = BusinessType.EXPORT`
270
+
271
+ **ExcelUtil 导出参数说明**:
272
+ ```java
273
+ ExcelUtil.exportExcel(
274
+ list, // 数据列表
275
+ "测试单表", // 文件名(不含后缀)
276
+ TestDemoVo.class, // VO 类(包含 @ExcelProperty)
277
+ response // HttpServletResponse
278
+ );
279
+ ```
280
+
281
+ ---
282
+
283
+ ### 2.8 导入数据
284
+
285
+ ```java
286
+ /**
287
+ * 导入
288
+ * ✅ POST 到 /importData 路径
289
+ * ✅ consumes = MediaType.MULTIPART_FORM_DATA_VALUE
290
+ * ✅ 返回 R<Void> 包含导入结果分析
291
+ * ✅ @RequestPart 接收文件
292
+ * ✅ @Log 记录操作日志
293
+ */
294
+ @Log(title = "测试单表", businessType = BusinessType.IMPORT)
295
+ @SaCheckPermission("demo:demo:import")
296
+ @PostMapping(value = "/importData",
297
+ consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
298
+ public R<Void> importData(@RequestPart("file") MultipartFile file) throws Exception {
299
+ // ✅ 使用 ExcelUtil 导入,指定 ImportVo 类
300
+ ExcelResult<TestDemoImportVo> excelResult =
301
+ ExcelUtil.importExcel(file.getInputStream(),
302
+ TestDemoImportVo.class, true);
303
+
304
+ // ✅ 转换为 Entity
305
+ List<TestDemo> list = MapstructUtils.convert(
306
+ excelResult.getList(), TestDemo.class);
307
+
308
+ // ✅ 保存到数据库
309
+ testDemoService.saveBatch(list);
310
+
311
+ // ✅ 返回导入分析结果
312
+ return R.ok(excelResult.getAnalysis());
313
+ }
314
+ ```
315
+
316
+ **关键点**:
317
+ - `@PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)`
318
+ - `@RequestPart("file")` - 文件上传字段名为 "file"
319
+ - `throws Exception` - 处理文件异常
320
+ - `ExcelUtil.importExcel(inputStream, ImportVo.class, true)` - 导入 Excel
321
+ - 第三个参数 `true` 表示是否需要导入分析(错误统计等)
322
+ - `excelResult.getList()` - 得到导入的数据
323
+ - `excelResult.getAnalysis()` - 得到导入分析结果(错误行数等)
324
+ - `MapstructUtils.convert()` - 转换为 Entity
325
+ - `saveBatch()` - 批量保存
326
+
327
+ ---
328
+
329
+ ## 3. 注解使用规范
330
+
331
+ ### 3.1 权限控制 - @SaCheckPermission
332
+
333
+ ```java
334
+ // 格式:@SaCheckPermission("module:resource:operation")
335
+ @SaCheckPermission("demo:demo:list") // list - 列表查询
336
+ @SaCheckPermission("demo:demo:query") // query - 详情查询
337
+ @SaCheckPermission("demo:demo:add") // add - 新增
338
+ @SaCheckPermission("demo:demo:edit") // edit - 修改
339
+ @SaCheckPermission("demo:demo:remove") // remove - 删除
340
+ @SaCheckPermission("demo:demo:export") // export - 导出
341
+ @SaCheckPermission("demo:demo:import") // import - 导入
342
+ ```
343
+
344
+ **权限字符串规则**:
345
+ - 格式:`module:resource:operation`
346
+ - `module` - 业务模块名(如 demo、system、business)
347
+ - `resource` - 资源名称(如 user、menu、xxx)
348
+ - `operation` - 操作类型(list、query、add、edit、remove、export、import)
349
+
350
+ ---
351
+
352
+ ### 3.2 操作日志 - @Log
353
+
354
+ ```java
355
+ // 格式:@Log(title = "功能名称", businessType = BusinessType.XXX)
356
+ @Log(title = "测试单表", businessType = BusinessType.INSERT) // 新增
357
+ @Log(title = "测试单表", businessType = BusinessType.UPDATE) // 修改
358
+ @Log(title = "测试单表", businessType = BusinessType.DELETE) // 删除
359
+ @Log(title = "测试单表", businessType = BusinessType.EXPORT) // 导出
360
+ @Log(title = "测试单表", businessType = BusinessType.IMPORT) // 导入
361
+ ```
362
+
363
+ **BusinessType 枚举值**:
364
+ ```java
365
+ public enum BusinessType {
366
+ OTHER, // 其他
367
+ INSERT, // 新增
368
+ UPDATE, // 修改
369
+ DELETE, // 删除
370
+ GRANT, // 授权
371
+ EXPORT, // 导出
372
+ IMPORT, // 导入
373
+ FORCE, // 强退
374
+ GENCODE, // 代码生成
375
+ CLEAN // 清空数据
376
+ }
377
+ ```
378
+
379
+ ---
380
+
381
+ ### 3.3 幂等性防护 - @RepeatSubmit
382
+
383
+ ```java
384
+ // 使用默认配置
385
+ @RepeatSubmit
386
+ public R<Void> add(...) { ... }
387
+
388
+ // 自定义间隔和单位
389
+ @RepeatSubmit(interval = 2, timeUnit = TimeUnit.SECONDS,
390
+ message = "{repeat.submit.message}")
391
+ public R<Void> add(...) { ... }
392
+
393
+ // 自定义消息(i18n 国际化)
394
+ @RepeatSubmit(message = "{repeat.submit.message}")
395
+ ```
396
+
397
+ **参数说明**:
398
+ - `interval` - 防重间隔(默认值由框架定义)
399
+ - `timeUnit` - 时间单位(SECONDS、MILLISECONDS 等)
400
+ - `message` - 提示消息(支持 i18n 占位符,格式:{key})
401
+
402
+ ---
403
+
404
+ ### 3.4 数据验证 - @Validated 和 ValidatorUtils
405
+
406
+ #### 方式一:@Validated 注解(Controller 级别)
407
+
408
+ ```java
409
+ // ✅ 列表查询:使用 QueryGroup
410
+ @GetMapping("/list")
411
+ public TableDataInfo<TestDemoVo> list(
412
+ @Validated(QueryGroup.class) TestDemoBo bo,
413
+ PageQuery pageQuery) { ... }
414
+
415
+ // ✅ 修改:使用 EditGroup
416
+ @PutMapping()
417
+ public R<Void> edit(
418
+ @Validated(EditGroup.class) @RequestBody TestDemoBo bo) { ... }
419
+
420
+ // ✅ 新增或导出:不指定分组(使用默认或所有分组)
421
+ @PostMapping("/export")
422
+ public void export(@Validated TestDemoBo bo, HttpServletResponse response) { ... }
423
+ ```
424
+
425
+ #### 方式二:ValidatorUtils 工具类(手动验证)
426
+
427
+ ```java
428
+ // ✅ 在 Controller 方法内手动验证
429
+ @PostMapping()
430
+ public R<Void> add(@RequestBody TestDemoBo bo) {
431
+ ValidatorUtils.validate(bo, AddGroup.class);
432
+ return toAjax(testDemoService.insertByBo(bo));
433
+ }
434
+
435
+ // ✅ 用途:
436
+ // - 非 Controller 方法内验证(Service/DAO 层)
437
+ // - 需要自定义验证逻辑的地方
438
+ // - 手动捕获验证异常
439
+ ```
440
+
441
+ **验证分组说明**:
442
+
443
+ | 分组 | 用途 | 在 BO 中标注 |
444
+ |------|------|----------|
445
+ | `QueryGroup.class` | 查询时验证 | `@NotNull(groups = QueryGroup.class)` |
446
+ | `AddGroup.class` | 新增时验证 | `@NotNull(groups = AddGroup.class)` |
447
+ | `EditGroup.class` | 修改时验证 | `@NotNull(groups = EditGroup.class)` |
448
+
449
+ ---
450
+
451
+ ## 4. 返回值类型规范
452
+
453
+ ### 4.1 R<T> - 单个数据返回
454
+
455
+ ```java
456
+ // ✅ 返回成功(包含数据)
457
+ return R.ok(data); // 返回数据
458
+
459
+ // ✅ 返回成功(无数据)
460
+ return R.ok(); // 仅返回 {code: 200}
461
+
462
+ // ✅ 使用 toAjax() 包装服务返回值
463
+ return toAjax(testDemoService.insertByBo(bo)); // int/boolean → R<Void>
464
+
465
+ // ✅ 返回失败
466
+ return R.fail("错误信息");
467
+ ```
468
+
469
+ **R<T> 响应格式**:
470
+ ```json
471
+ {
472
+ "code": 200, // 响应码
473
+ "msg": "操作成功", // 响应消息
474
+ "data": {...} // 数据
475
+ }
476
+ ```
477
+
478
+ ---
479
+
480
+ ### 4.2 TableDataInfo<T> - 分页列表返回
481
+
482
+ ```java
483
+ // ✅ Service 返回分页结果
484
+ @GetMapping("/list")
485
+ public TableDataInfo<TestDemoVo> list(
486
+ @Validated(QueryGroup.class) TestDemoBo bo,
487
+ PageQuery pageQuery) {
488
+ return testDemoService.queryPageList(bo, pageQuery);
489
+ }
490
+ ```
491
+
492
+ **TableDataInfo<T> 响应格式**:
493
+ ```json
494
+ {
495
+ "total": 100, // 总条数
496
+ "rows": [ // 数据行
497
+ {...},
498
+ {...}
499
+ ],
500
+ "code": 200,
501
+ "msg": "操作成功"
502
+ }
503
+ ```
504
+
505
+ ---
506
+
507
+ ### 4.3 void - 直接响应(导出)
508
+
509
+ ```java
510
+ // ✅ 导出时不使用返回值,直接写入 HttpServletResponse
511
+ @PostMapping("/export")
512
+ public void export(@Validated TestDemoBo bo, HttpServletResponse response) {
513
+ List<TestDemoVo> list = testDemoService.queryList(bo);
514
+ ExcelUtil.exportExcel(list, "测试单表", TestDemoVo.class, response);
515
+ }
516
+ ```
517
+
518
+ ---
519
+
520
+ ## 5. 数据验证注解
521
+
522
+ | 注解 | 用途 | 示例 |
523
+ |------|------|------|
524
+ | `@NotNull` | 不能为 null | `@NotNull(message = "主键不能为空")` |
525
+ | `@NotBlank` | 字符串不能为空或空白 | `@NotBlank(message = "名称不能为空")` |
526
+ | `@NotEmpty` | 集合/数组不能为空 | `@NotEmpty(message = "ID 不能为空")` |
527
+ | `@Min` | 最小值 | `@Min(value = 0, message = "不能小于0")` |
528
+ | `@Max` | 最大值 | `@Max(value = 100, message = "不能大于100")` |
529
+ | `@Length` | 字符串长度 | `@Length(min = 1, max = 50)` |
530
+ | `@Pattern` | 正则表达式 | `@Pattern(regexp = "^[0-9]+$")` |
531
+ | `@Email` | 邮箱格式 | `@Email(message = "邮箱格式错误")` |
532
+
533
+ ---
534
+
535
+ ## 6. BaseController 工具方法
536
+
537
+ ### toAjax() 方法
538
+
539
+ ```java
540
+ // ✅ 将 Service 返回的 int/boolean 转换为 R<Void>
541
+ return toAjax(testDemoService.insertByBo(bo));
542
+ return toAjax(testDemoService.updateByBo(bo));
543
+ return toAjax(testDemoService.deleteWithValidByIds(ids, true));
544
+
545
+ // 原理:
546
+ // - 入参 > 0 或 true → R.ok()
547
+ // - 入参 = 0 或 false → R.fail()
548
+ ```
549
+
550
+ ---
551
+
552
+ ## 7. 常见错误对比
553
+
554
+ ### ❌ 不要做
555
+
556
+ ```java
557
+ // 错误 1: 用 /page 替代 /list 作为标准列表端点
558
+ @GetMapping("/page") // ❌ 不能替代 /list(/page 仅用于自定义分页,见 2.2 节)
559
+
560
+ // 错误 2: 返回值不包装
561
+ public List<TestDemoVo> list() { ... } // ❌ 禁止!应返回 TableDataInfo<T>
562
+ public TestDemoVo getInfo(Long id) { ... } // ❌ 禁止!应返回 R<T>
563
+
564
+ // 错误 3: 不使用权限注解
565
+ @GetMapping("/list")
566
+ public TableDataInfo<TestDemoVo> list(...) { ... } // ❌ 缺少 @SaCheckPermission
567
+
568
+ // 错误 4: 不使用日志注解
569
+ @PostMapping()
570
+ public R<Void> add(...) { ... } // ❌ 缺少 @Log
571
+
572
+ // 错误 5: 新增/修改不防重复提交
573
+ @PostMapping()
574
+ public R<Void> add(...) { ... } // ❌ 缺少 @RepeatSubmit
575
+
576
+ // 错误 6: 使用 @Validated 而不指定分组
577
+ @PostMapping()
578
+ public R<Void> add(@Validated @RequestBody TestDemoBo bo) { ... }
579
+ // ❌ 应该用 ValidatorUtils.validate(bo, AddGroup.class)
580
+
581
+ // 错误 7: 导出返回 R<T>
582
+ @PostMapping("/export")
583
+ public R<List<TestDemoVo>> export(...) { ... } // ❌ 应返回 void
584
+ ```
585
+
586
+ ### ✅ 正确做法
587
+
588
+ ```java
589
+ // 正确 1: 路径唯一,遵循 RESTful 规范
590
+ @GetMapping("/list") // ✅
591
+ @GetMapping("/{id}") // ✅
592
+ @PostMapping() // ✅
593
+ @PutMapping() // ✅
594
+ @DeleteMapping("/{ids}") // ✅
595
+
596
+ // 正确 2: 返回值类型正确
597
+ public TableDataInfo<TestDemoVo> list(...) { ... } // ✅
598
+ public R<TestDemoVo> getInfo(Long id) { ... } // ✅
599
+ public R<Void> add(...) { ... } // ✅
600
+
601
+ // 正确 3: 使用权限注解
602
+ @SaCheckPermission("demo:demo:list")
603
+ @GetMapping("/list")
604
+ public TableDataInfo<TestDemoVo> list(...) { ... } // ✅
605
+
606
+ // 正确 4: 使用日志注解
607
+ @Log(title = "测试单表", businessType = BusinessType.INSERT)
608
+ @PostMapping()
609
+ public R<Void> add(...) { ... } // ✅
610
+
611
+ // 正确 5: 新增/修改防重复提交
612
+ @RepeatSubmit(interval = 2, timeUnit = TimeUnit.SECONDS)
613
+ @PostMapping()
614
+ public R<Void> add(...) { ... } // ✅
615
+
616
+ // 正确 6: 手动验证 BO
617
+ @PostMapping()
618
+ public R<Void> add(@RequestBody TestDemoBo bo) {
619
+ ValidatorUtils.validate(bo, AddGroup.class); // ✅
620
+ return toAjax(testDemoService.insertByBo(bo));
621
+ }
622
+
623
+ // 正确 7: 导出返回 void
624
+ @PostMapping("/export")
625
+ public void export(@Validated TestDemoBo bo, HttpServletResponse response) {
626
+ // ... 导出逻辑 ...
627
+ } // ✅
628
+ ```
629
+
630
+ ---
631
+
632
+ ## 8. 检查清单
633
+
634
+ 生成 API 代码前必须检查:
635
+
636
+ - [ ] **权限注解是否添加**?(`@SaCheckPermission`)
637
+ - [ ] **操作日志是否添加**?(`@Log(title = "xxx", businessType = BusinessType.XXX)`)
638
+ - [ ] **新增/修改是否防重复提交**?(`@RepeatSubmit`)
639
+ - [ ] **返回值类型是否正确**?(LIST→TableDataInfo, GET→R<T>, DELETE/UPDATE→R<Void>, EXPORT→void)
640
+ - [ ] **HTTP 方法是否正确**?(GET查询, POST新增/导出/导入, PUT修改, DELETE删除)
641
+ - [ ] **路径是否遵循 RESTful 规范**?(/list, /{id}, /export, /importData)
642
+ - [ ] **数据验证是否正确**?(@Validated + 分组 或 ValidatorUtils)
643
+ - [ ] **是否使用了 toAjax() 包装返回值**?(用于 int/boolean → R<Void>)
644
+ - [ ] **是否使用了 MapstructUtils** 进行对象转换?(导入数据时)
645
+ - [ ] **是否所有类型都先 import 再使用短类名**?(禁止完整类名内联)
646
+ - [ ] **Controller 是否继承 BaseController**?
647
+ - [ ] **Service 接口是否遵循三层架构**?(Service → Mapper,无 DAO)
648
+ - [ ] **导出是否使用 ExcelUtil.exportExcel()**?
649
+ - [ ] **导入是否使用 ExcelUtil.importExcel() 和 MapstructUtils.convert()**?
650
+
651
+ ---
652
+
653
+ ## 9. 参考实现
654
+
655
+ 查看已有的完整实现:
656
+
657
+ - **Controller 参考**: `org.dromara.demo.controller.TestDemoController`(完整的 7 个 API 方法)
658
+ - **Service 参考**: `org.dromara.demo.service.impl.TestDemoServiceImpl`
659
+ - **Entity 参考**: `org.dromara.demo.domain.TestDemo`
660
+ - **BO 参考**: `org.dromara.demo.domain.bo.TestDemoBo`
661
+ - **VO 参考**: `org.dromara.demo.domain.vo.TestDemoVo`
662
+ - **Mapper 参考**: `org.dromara.demo.mapper.TestDemoMapper`
663
+
664
+ **特别注意**:上述参考代码是本项目的标准实现,严格遵循 RESTful 规范和三层架构。
665
+
666
+ ---
667
+
668
+ ## 10. 快速参考
669
+
670
+ ### HTTP 方法速查
671
+
672
+ ```
673
+ GET /list → 列表查询(分页)
674
+ GET /{id} → 获取详情
675
+ POST / → 新增数据
676
+ PUT / → 修改数据
677
+ DELETE /{ids} → 删除数据
678
+ POST /export → 导出数据
679
+ POST /importData → 导入数据
680
+ ```
681
+
682
+ ### 注解组合速查
683
+
684
+ ```
685
+ LIST: @SaCheckPermission + @GetMapping("/list") + @Validated(QueryGroup.class)
686
+ GET: @SaCheckPermission + @GetMapping("/{id}") + @NotNull + R.ok()
687
+ ADD: @SaCheckPermission + @Log(INSERT) + @RepeatSubmit + ValidatorUtils
688
+ EDIT: @SaCheckPermission + @Log(UPDATE) + @RepeatSubmit + @Validated(EditGroup.class)
689
+ DELETE: @SaCheckPermission + @Log(DELETE) + @DeleteMapping("/{ids}") + toAjax()
690
+ EXPORT: @SaCheckPermission + @Log(EXPORT) + @PostMapping("/export") + void
691
+ IMPORT: @SaCheckPermission + @Log(IMPORT) + @PostMapping("/importData") + R<Void>
692
+ ```
693
+