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,803 @@
1
+ ---
2
+ name: leniu-api-development
3
+ description: |
4
+ leiu-yunshitang-core 项目 API 接口开发规范。基于 pigx-framework 三层架构的 RESTful API 开发指南。
5
+
6
+ 触发场景:
7
+ - 设计 leniu 项目 RESTful API 接口
8
+ - 编写 leniu Controller 层代码
9
+ - 配置接口权限注解
10
+ - 接口返回值类型选择
11
+ - 数据验证和参数校验
12
+
13
+ 适用项目:leniu-tengyun-core(云食堂项目)
14
+
15
+ 触发词:leniu-API、leniu-接口、leniu-Controller、leniu-RESTful、LeResult、云食堂接口、云食堂API
16
+ ---
17
+
18
+ # leiu-yunshitang-core API 接口开发规范
19
+
20
+ ## 项目定位
21
+
22
+ 本技能专用于 **leiu-tengyun-core 云食堂项目** 的 API 接口开发。
23
+
24
+ | 项目 | 路径 |
25
+ |------|------|
26
+ | **云食堂后端** | `/Users/xujiajun/Developer/core/leniu-tengyun-core` |
27
+ | **包名前缀** | `net.xnzn.core.*` |
28
+
29
+ ---
30
+
31
+ ## 核心架构差异
32
+
33
+ | 特征 | RuoYi-Vue-Plus | leniu-tengyun-core |
34
+ |-----|----------------|-------------------|
35
+ | **JDK 版本** | 17 | 21 |
36
+ | **包名前缀** | `org.dromara.*` | `net.xnzn.core.*` |
37
+ | **请求封装** | 直接使用 BO | `LeRequest<T>` 包装 |
38
+ | **响应封装** | `R<T>`, `TableDataInfo<T>` | `Page<T>`, `LeResponse<T>`, `void` |
39
+ | **分组校验** | `AddGroup`, `EditGroup` | `InsertGroup`, `UpdateGroup` |
40
+ | **认证注解** | `@SaCheckPermission` | `@RequiresAuthentication`, `@RequiresGuest` |
41
+ | **异常类** | `ServiceException` | `LeException` |
42
+ | **审计字段** | `create_by/create_time/update_by/update_time` | `crby/crtime/upby/uptime` |
43
+ | **主键策略** | 雪花ID (`IdType.ASSIGN_ID`) | 自增ID (`IdType.AUTO`) |
44
+
45
+ ---
46
+
47
+ ## 核心规范
48
+
49
+ ### 1. 接口定义原则
50
+
51
+ | 原则 | 说明 |
52
+ |------|------|
53
+ | **统一入口** | 所有接口使用 POST 或 RESTful 风格 |
54
+ | **认证保护** | 业务接口使用 `@RequiresAuthentication`,部分使用 `@RequiresGuest` |
55
+ | **参数校验** | 使用分组校验区分新增/修改场景 |
56
+ | **统一响应** | 分页用 `Page<T>`,单数据用 `LeResponse<T>` 或直接返回 VO |
57
+ | **请求封装** | 使用 `LeRequest<T>` 包装请求参数 |
58
+
59
+ ### 2. HTTP 方法规范
60
+
61
+ | 操作 | HTTP 方法 | 路径 | 说明 |
62
+ |------|---------|------|------|
63
+ | **列表查询** | POST | `/query` 或 `/page-*` | 分页查询列表 |
64
+ | **获取详情** | GET/POST | `/{id}` 或 `/get-*` | 根据 ID 查询 |
65
+ | **新增** | POST | `/add` | 创建新数据 |
66
+ | **修改** | POST/PUT | `/update` 或 `/modify-*` | 更新数据 |
67
+ | **删除** | DELETE/POST | `/delete` 或 `/batch/delete` | 删除数据 |
68
+ | **导出** | POST | `/export` | 导出数据到 Excel |
69
+ | **导入** | POST | `/import-excel` | 从 Excel 导入数据 |
70
+
71
+ ---
72
+
73
+ ## Controller 类模板
74
+
75
+ ### 标准模板(带参数校验)
76
+
77
+ ```java
78
+ @Api(tags = "模块-功能描述")
79
+ @RestController
80
+ @RequiresAuthentication
81
+ @RequestMapping("/module/feature")
82
+ public class XxxController {
83
+
84
+ @Autowired
85
+ private XxxService xxxService;
86
+
87
+ @PostMapping("/add")
88
+ @ApiOperation(value = "功能描述-新增")
89
+ public void add(@Validated(InsertGroup.class) @RequestBody LeRequest<XxxDTO> request) {
90
+ xxxService.add(request.getContent());
91
+ }
92
+
93
+ @PostMapping("/update")
94
+ @ApiOperation(value = "功能描述-修改")
95
+ public void update(@Validated(UpdateGroup.class) @RequestBody LeRequest<XxxDTO> request) {
96
+ xxxService.update(request.getContent());
97
+ }
98
+
99
+ @PostMapping("/query")
100
+ @ApiOperation(value = "功能描述-分页查询")
101
+ public Page<XxxVO> query(@Validated @RequestBody LeRequest<XxxQueryParam> request) {
102
+ return xxxService.page(request.getContent());
103
+ }
104
+
105
+ @PostMapping("/delete")
106
+ @ApiOperation(value = "功能描述-删除")
107
+ public void delete(@RequestBody LeRequest<Long> request) {
108
+ xxxService.delete(request.getContent());
109
+ }
110
+ }
111
+ ```
112
+
113
+ ### 简化模板(无分组校验)
114
+
115
+ ```java
116
+ @Api(tags = "模块-功能描述")
117
+ @RestController
118
+ @RequiresAuthentication
119
+ @RequestMapping("/module/feature")
120
+ public class XxxController {
121
+
122
+ @Autowired
123
+ private XxxService xxxService;
124
+
125
+ @PostMapping("/add")
126
+ @ApiOperation(value = "功能描述-新增")
127
+ public void add(@RequestBody LeRequest<XxxDTO> request) {
128
+ xxxService.add(request.getContent());
129
+ }
130
+
131
+ @PostMapping("/query")
132
+ @ApiOperation(value = "功能描述-分页查询")
133
+ public Page<XxxVO> query(@RequestBody LeRequest<XxxQueryParam> request) {
134
+ return xxxService.page(request.getContent());
135
+ }
136
+ }
137
+ ```
138
+
139
+ ---
140
+
141
+ ## 请求/响应封装
142
+
143
+ ### 1. 请求参数封装 `LeRequest<T>`
144
+
145
+ ```java
146
+ import com.pig4cloud.pigx.common.core.util.LeRequest;
147
+
148
+ @PostMapping("/query")
149
+ public Page<XxxVO> query(@RequestBody LeRequest<XxxQueryParam> request) {
150
+ XxxQueryParam param = request.getContent(); // 获取实际参数
151
+ return xxxService.page(param);
152
+ }
153
+ ```
154
+
155
+ ### 2. 响应类型
156
+
157
+ #### 分页响应(最常用)
158
+
159
+ ```java
160
+ // 使用 MyBatis-Plus 的 Page 对象
161
+ @PostMapping("/query")
162
+ @ApiOperation(value = "分页查询")
163
+ public Page<XxxVO> query(@RequestBody LeRequest<XxxQueryParam> request) {
164
+ return xxxService.page(request.getContent());
165
+ }
166
+ ```
167
+
168
+ #### 单数据响应(LeResponse)
169
+
170
+ ```java
171
+ import com.pig4cloud.pigx.common.core.util.LeResponse;
172
+
173
+ @PostMapping("/get-config")
174
+ @ApiOperation(value = "查询配置")
175
+ public LeResponse<String> getConfig(@RequestBody LeRequest<Long> request) {
176
+ return LeResponse.succ(xxxService.getConfig(request.getContent()));
177
+ }
178
+ ```
179
+
180
+ #### 直接返回 VO(用于复杂对象)
181
+
182
+ ```java
183
+ @PostMapping("/get-detail")
184
+ @ApiOperation(value = "查询详情(聚合)")
185
+ public XxxDetailVO getDetail(@RequestBody LeRequest<Long> request) {
186
+ return xxxService.getDetail(request.getContent());
187
+ }
188
+ ```
189
+
190
+ #### 无返回值操作
191
+
192
+ ```java
193
+ @PostMapping("/add")
194
+ @ApiOperation(value = "新增")
195
+ public void add(@RequestBody LeRequest<XxxDTO> request) {
196
+ xxxService.add(request.getContent());
197
+ }
198
+ ```
199
+
200
+ ---
201
+
202
+ ## 参数校验规范
203
+
204
+ ### 1. JDK 21 必须使用 Jakarta Validation
205
+
206
+ ```java
207
+ import jakarta.validation.Valid;
208
+ import jakarta.validation.constraints.NotNull;
209
+ import jakarta.validation.constraints.NotBlank;
210
+ import jakarta.validation.constraints.NotEmpty;
211
+ import jakarta.validation.constraints.Size;
212
+ import jakarta.validation.constraints.Pattern;
213
+ import jakarta.validation.constraints.Min;
214
+ import jakarta.validation.constraints.Max;
215
+
216
+ @Data
217
+ public class XxxDTO {
218
+
219
+ @NotNull(message = "ID不能为空", groups = {UpdateGroup.class})
220
+ private Long id;
221
+
222
+ @NotBlank(message = "名称不能为空", groups = {InsertGroup.class, UpdateGroup.class})
223
+ @Size(max = 100, message = "名称长度不能超过100个字符")
224
+ private String name;
225
+
226
+ @Min(value = 0, message = "数量不能小于0")
227
+ @Max(value = 9999, message = "数量不能大于9999")
228
+ private Integer count;
229
+
230
+ @Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
231
+ private String phone;
232
+ }
233
+ ```
234
+
235
+ ### 2. 分组校验定义
236
+
237
+ ```java
238
+ // 定义校验分组
239
+ public interface InsertGroup {}
240
+ public interface UpdateGroup {}
241
+
242
+ // Controller 中应用分组
243
+ @PostMapping("/add")
244
+ public void add(@Validated(InsertGroup.class) @RequestBody LeRequest<XxxDTO> request)
245
+
246
+ @PostMapping("/update")
247
+ public void update(@Validated(UpdateGroup.class) @RequestBody LeRequest<XxxDTO> request)
248
+ ```
249
+
250
+ ### 3. 简单校验(无分组)
251
+
252
+ ```java
253
+ // 直接使用 @Valid 或在方法上加 @Validated
254
+ @PostMapping("/query")
255
+ public Page<XxxVO> query(@Validated @RequestBody LeRequest<XxxQueryParam> request)
256
+
257
+ @PostMapping("/check")
258
+ public LeResponse<Boolean> check(@Valid @RequestBody LeRequest<XxxDTO> request)
259
+ ```
260
+
261
+ ---
262
+
263
+ ## 认证注解规范
264
+
265
+ | 注解 | 用途 | 使用场景 |
266
+ |------|------|---------|
267
+ | `@RequiresAuthentication` | 需要登录认证 | 大部分业务接口 |
268
+ | `@RequiresGuest` | 允许游客访问 | 不需要登录的接口 |
269
+
270
+ ```java
271
+ // 需要登录
272
+ @RequiresAuthentication
273
+ @PostMapping("/query")
274
+ public Page<XxxVO> query(@RequestBody LeRequest<XxxQueryParam> request) { }
275
+
276
+ // 允许游客访问
277
+ @RequiresGuest
278
+ @PostMapping("/public")
279
+ public void publicApi(@RequestBody LeRequest<XxxDTO> request) { }
280
+ ```
281
+
282
+ ---
283
+
284
+ ## 审计字段规范
285
+
286
+ leiu-tengyun-core 项目使用以下审计字段:
287
+
288
+ | 字段 | 类型 | 说明 | MyBatis-Plus 注解 |
289
+ |------|------|------|------------------|
290
+ | `crby` | String | 创建人 | `@TableField(fill = FieldFill.INSERT)` |
291
+ | `crtime` | LocalDateTime | 创建时间 | `@TableField(fill = FieldFill.INSERT)` |
292
+ | `upby` | String | 更新人 | `@TableField(fill = FieldFill.INSERT_UPDATE)` |
293
+ | `uptime` | LocalDateTime | 更新时间 | `@TableField(fill = FieldFill.INSERT_UPDATE)` |
294
+
295
+ ### Entity 审计字段示例
296
+
297
+ ```java
298
+ import com.baomidou.mybatisplus.annotation.FieldFill;
299
+ import com.baomidou.mybatisplus.annotation.TableField;
300
+
301
+ @Data
302
+ @TableName("xxx_table")
303
+ public class XxxEntity implements Serializable {
304
+
305
+ // 主键(自增)
306
+ @ApiModelProperty("主键ID")
307
+ @TableId(value = "id", type = IdType.AUTO)
308
+ private Long id;
309
+
310
+ // 审计字段
311
+ @ApiModelProperty("创建人")
312
+ @TableField(fill = FieldFill.INSERT)
313
+ private String crby;
314
+
315
+ @ApiModelProperty("创建时间")
316
+ @TableField(fill = FieldFill.INSERT)
317
+ private LocalDateTime crtime;
318
+
319
+ @ApiModelProperty("更新人")
320
+ @TableField(fill = FieldFill.INSERT_UPDATE)
321
+ private String upby;
322
+
323
+ @ApiModelProperty("更新时间")
324
+ @TableField(fill = FieldFill.INSERT_UPDATE)
325
+ private LocalDateTime uptime;
326
+ }
327
+ ```
328
+
329
+ ---
330
+
331
+ ## 常见场景示例
332
+
333
+ ### 1. 带 Redisson 分布式锁的导入
334
+
335
+ ```java
336
+ import org.redisson.api.RLock;
337
+ import org.redisson.api.RedissonClient;
338
+ import java.util.concurrent.TimeUnit;
339
+
340
+ @Autowired
341
+ private RedissonClient redissonClient;
342
+
343
+ @PostMapping("/import-excel")
344
+ @ApiOperation(value = "Excel导入")
345
+ public void importExcel(@RequestParam(value = "file") MultipartFile file) {
346
+ RLock lock = redissonClient.getLock("import:lock:" + TenantContextHolder.getTenantId());
347
+ if (!lock.tryLock(5, 60, TimeUnit.SECONDS)) {
348
+ throw new LeException("正在处理中,请稍后再试");
349
+ }
350
+ try {
351
+ xxxService.importExcel(file);
352
+ } finally {
353
+ if (lock.isLocked() && lock.isHeldByCurrentThread()) {
354
+ lock.unlock();
355
+ }
356
+ }
357
+ }
358
+ ```
359
+
360
+ ### 2. 批量删除
361
+
362
+ ```java
363
+ @PutMapping("/batch/delete")
364
+ @ApiOperation(value = "批量删除")
365
+ public void batchDelete(@RequestBody LeRequest<List<Long>> request) {
366
+ xxxService.batchDelete(request.getContent());
367
+ }
368
+ ```
369
+
370
+ ### 3. 树形结构查询
371
+
372
+ ```java
373
+ import cn.hutool.core.lang.tree.Tree;
374
+
375
+ @PostMapping("/tree")
376
+ @ApiOperation(value = "树形结构查询")
377
+ public List<Tree<Long>> getTree(@RequestBody LeRequest<XxxQueryParam> request) {
378
+ return xxxService.getTree(request.getContent());
379
+ }
380
+ ```
381
+
382
+ ### 4. 列表查询(不分页)
383
+
384
+ ```java
385
+ @PostMapping("/list-all")
386
+ @ApiOperation(value = "查询所有列表")
387
+ public List<XxxVO> listAll(@RequestBody LeRequest<XxxQueryParam> request) {
388
+ return xxxService.listAll(request.getContent());
389
+ }
390
+ ```
391
+
392
+ ---
393
+
394
+ ## 真实代码示例(来自 order/report 模块)
395
+
396
+ ### 示例0:ReportAnalysisController(报表模块典型 Controller)
397
+
398
+ ```java
399
+ @RestController
400
+ @RequestMapping("/summary/analysis")
401
+ @Api(value = "报表中心/经营分析", tags = "报表/经营分析-新")
402
+ public class ReportAnalysisController {
403
+
404
+ @Autowired
405
+ @Lazy
406
+ protected ExportApi exportApi; // 跨模块依赖用 @Lazy 避免循环依赖
407
+ @Autowired
408
+ private ReportAnalysisTurnoverService reportAnalysisTurnoverService;
409
+
410
+ // 报表查询:返回直接 VO 对象
411
+ @ApiOperation(value = "营业分析-总营业额")
412
+ @PostMapping("/turnover/total")
413
+ public ReportTurnoverPO getTurnoverTotal(@RequestBody LeRequest<ReportAnalysisTurnoverParam> request) {
414
+ return reportAnalysisTurnoverService.getTurnoverTotal(request.getContent());
415
+ }
416
+
417
+ // 报表分页:返回 ReportBaseTotalVO(含合计行)
418
+ @ApiOperation(value = "营业分析-营业额报表")
419
+ @PostMapping("/turnover/detail")
420
+ public ReportBaseTotalVO<ReportAnalysisTurnoverDetailVO> getTurnoverDetail(
421
+ @RequestBody LeRequest<ReportAnalysisTurnoverParam> request) {
422
+ return reportAnalysisTurnoverService.getTurnoverDetail(request.getContent());
423
+ }
424
+
425
+ // 同步导出(小数据量)
426
+ @SneakyThrows
427
+ @ApiOperation(value = "食堂满意度统计导出")
428
+ @PostMapping("/evaluate/export")
429
+ public void exportEvaluateSummary(@RequestBody LeRequest<ReportAnalysisEvaluateParam> request,
430
+ HttpServletResponse response) {
431
+ ReportAnalysisEvaluateParam param = request.getContent();
432
+ ReportBaseTotalVO<ReportAnalysisEvaluateVO> result = reportAnalysisEvaluateService.pageSummary(param);
433
+ List<ReportAnalysisEvaluateVO> list = (List<ReportAnalysisEvaluateVO>)
434
+ CollUtil.addAll(result.getResultPage().getRecords(), result.getTotalLine());
435
+ EasyExcelUtil.writeExcelByDownLoadIncludeWrite(response, "文件",
436
+ ReportAnalysisEvaluateVO.class, ReportConstant.REPORT_TITLE_DETAILS, list, param.getExportCols());
437
+ }
438
+
439
+ // 异步导出(大数据量)
440
+ @ApiOperation(value = "异步导出菜品销售排行")
441
+ @PostMapping("/export-async/dishes/sale/export")
442
+ public void exportDishesSaleSummary(@RequestBody LeRequest<ReportAnalysisDishesSaleParam> request) {
443
+ ReportAnalysisDishesSaleParam param = request.getContent();
444
+ ReportBaseTotalVO<ReportAnalysisDishesSaleVO> result = reportAnalysisDishesSaleService.pageSummary(param);
445
+ List<ReportAnalysisDishesSaleVO> list = (List<ReportAnalysisDishesSaleVO>)
446
+ CollUtil.addAll(result.getResultPage().getRecords(), result.getTotalLine());
447
+ exportApi.startExcelExportTaskByPage(
448
+ "菜品销售排行",
449
+ I18n.getMessage(ReportConstant.REPORT_TITLE_DETAILS),
450
+ ReportAnalysisDishesSaleVO.class,
451
+ param.getExportCols(),
452
+ param.getPage(),
453
+ null,
454
+ () -> PageVO.of(list));
455
+ }
456
+ }
457
+ ```
458
+
459
+ ### 示例0b:OrderInfoExportWebController(订单导出 Controller)
460
+
461
+ ```java
462
+ // 导出功能独立到单独的 Controller,与查询 Controller 分离
463
+ @Slf4j
464
+ @RestController
465
+ @RequestMapping(value = "/api/v2/web/order/export")
466
+ public class OrderInfoExportWebController {
467
+
468
+ @Autowired
469
+ @Lazy
470
+ protected OrderWebBusiness orderWebBusiness;
471
+ @Autowired
472
+ @Lazy
473
+ protected OrderClients orderClients;
474
+
475
+ // 使用 orderClients.export() 启动异步导出(通过 client 代理)
476
+ @PostMapping(value = "/detail")
477
+ public void exportOrderDetail(@RequestBody LeRequest<OrderDetailWebDTO> request) {
478
+ OrderDetailWebDTO orderDetailDTO = request.getContent();
479
+ orderClients.export().startExcelExportTaskByPage(
480
+ I18n.getMessage("order.title.order-detail"), // 文件名(国际化)
481
+ orderSheetName(), // 工作表名
482
+ OrderListWebVO.class, // 数据类
483
+ orderDetailDTO.getExportCols(), // 导出列
484
+ orderDetailDTO, // 分页参数(Param 直接实现 PageDTO)
485
+ null, // 合计行(可选)
486
+ () -> orderWebBusiness.queryOrderInfoWebByPage(orderDetailDTO, orderDetailDTO));
487
+ }
488
+ }
489
+ ```
490
+
491
+ ### 示例0c:OrderInfoWebController(订单查询 Controller)
492
+
493
+ ```java
494
+ @Validated
495
+ @RestController
496
+ @RequestMapping(value = "/api/v2/web/order")
497
+ public class OrderInfoWebController {
498
+
499
+ @Autowired
500
+ private OrderWebBusiness orderWebBusiness;
501
+
502
+ // GET 详情:直接 @PostMapping 加 @Valid 校验
503
+ @PostMapping(value = "/info")
504
+ public OrderInfoWebVO info(@Valid @RequestBody LeRequest<OrderInfoWebDTO> request) {
505
+ return orderWebBusiness.getOrderInfo(request.getContent().getOrderId());
506
+ }
507
+
508
+ // 分页查询:返回 PageVO
509
+ @PostMapping(value = "/page/detail")
510
+ public PageVO<OrderListWebVO> pageOrderDetail(@RequestBody LeRequest<OrderDetailWebDTO> request) {
511
+ OrderDetailWebDTO content = request.getContent();
512
+ return orderWebBusiness.queryOrderInfoWebByPage(PageDTO.of(content.getCurrent(), content.getSize()), content);
513
+ }
514
+
515
+ // 抛出 LeException 明确告知失败原因
516
+ @PostMapping(value = "/refund")
517
+ public OrderRefundResultVO orderRefundWeb(@RequestBody LeRequest<OrderRefundSubmitWebDTO> request) throws LeCheckedException {
518
+ OrderRefundResultVO result = orderRefundBusiness.orderRefund(
519
+ request.getContent().convertToOrderRefundParam(), OrderRefundBizEnum.WEB);
520
+ if (!result.ifSuccess()) {
521
+ throw new LeException(result.getResultCode(), result.getResultMsg());
522
+ }
523
+ return result;
524
+ }
525
+ }
526
+ ```
527
+
528
+ ---
529
+
530
+ ## 路径命名规范(基于真实代码)
531
+
532
+ | 模式 | 示例 | 说明 |
533
+ |------|------|------|
534
+ | 统一前缀 | `/api/v2/xxx` | 标准业务接口前缀 |
535
+ | 报表前缀 | `/summary/xxx` | 报表/统计类接口 |
536
+ | 查询接口 | `/page/detail`, `/page`, `/query` | 分页查询 |
537
+ | 枚举接口 | `/xxx/type-list`, `/xxx/state-list` | 枚举数据查询 |
538
+ | 导出接口 | `/export`, `/export-async/xxx` | 同步/异步导出 |
539
+ | 功能动作 | `/write/off`, `/sync-pay-state`, `/refund` | 业务操作 |
540
+
541
+ ---
542
+
543
+ ## 真实代码示例
544
+
545
+ ### 示例1:AttendanceLeaveInfoController
546
+
547
+ ```java
548
+ package net.xnzn.core.attendance.leave.controller;
549
+
550
+ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
551
+ import com.pig4cloud.pigx.common.core.exception.LeException;
552
+ import com.pig4cloud.pigx.common.core.util.LeRequest;
553
+ import io.swagger.annotations.Api;
554
+ import io.swagger.annotations.ApiOperation;
555
+ import org.springframework.beans.factory.annotation.Autowired;
556
+ import org.springframework.web.bind.annotation.*;
557
+
558
+ import java.util.List;
559
+
560
+ @Api(tags = "zjl-考勤-请假信息")
561
+ @RestController
562
+ @RequiresAuthentication
563
+ @RequestMapping("/attendance/leave-info")
564
+ public class AttendanceLeaveInfoController {
565
+
566
+ @Autowired
567
+ AttendanceLeaveInfoService attendanceLeaveInfoService;
568
+ @Autowired
569
+ RedissonClient redissonClient;
570
+
571
+ @PostMapping("/add")
572
+ @ApiOperation(value = "请假信息-新增")
573
+ public void add(@RequestBody LeRequest<AddOrUpdateAttendanceLeaveInfoDTO> request) {
574
+ attendanceLeaveInfoService.add(request.getContent());
575
+ }
576
+
577
+ @PutMapping("/batch/delete")
578
+ @ApiOperation(value = "请假信息-批量删除")
579
+ public void batchDelete(@RequestBody LeRequest<List<Long>> request) {
580
+ attendanceLeaveInfoService.batchDelete(request.getContent());
581
+ }
582
+
583
+ @PutMapping("/update")
584
+ @ApiOperation(value = "请假信息-修改")
585
+ public void update(@RequestBody LeRequest<AddOrUpdateAttendanceLeaveInfoDTO> request) {
586
+ attendanceLeaveInfoService.update(request.getContent());
587
+ }
588
+
589
+ @PostMapping("/query")
590
+ @ApiOperation(value = "请假信息-分页查询")
591
+ public Page<QueryAttendanceLeaveInfoVO> query(@RequestBody LeRequest<QueryAttendanceLeaveInfoDTO> request) {
592
+ return attendanceLeaveInfoService.page(request.getContent());
593
+ }
594
+
595
+ @PostMapping("/import-excel")
596
+ @ApiOperation(value = "请假信息-excel导入")
597
+ public void importExcel(@RequestParam(value = "leaveInfoExcel") MultipartFile leaveInfoExcel) throws Exception {
598
+ RLock lock = redissonClient.getLock("import:lock:" + TenantContextHolder.getTenantId());
599
+ if (!lock.tryLock(5, TimeUnit.SECONDS)) {
600
+ throw new LeException("考勤-请假数据导入中,请等待...");
601
+ }
602
+ try {
603
+ attendanceLeaveInfoService.importExcel(new ImportLeaveInfoExcelDTO().setLeaveInfoExcel(leaveInfoExcel));
604
+ } finally {
605
+ if (lock.isLocked() && lock.isHeldByCurrentThread()) {
606
+ lock.unlock();
607
+ }
608
+ }
609
+ }
610
+ }
611
+ ```
612
+
613
+ ### 示例2:AllocCanteenController
614
+
615
+ ```java
616
+ package net.xnzn.core.allocation.canteen.controller;
617
+
618
+ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
619
+ import com.pig4cloud.pigx.common.core.util.LeRequest;
620
+ import com.pig4cloud.pigx.common.core.util.LeResponse;
621
+ import io.swagger.annotations.Api;
622
+ import io.swagger.annotations.ApiOperation;
623
+ import net.xnzn.framework.secure.filter.annotation.RequiresGuest;
624
+ import org.springframework.beans.factory.annotation.Autowired;
625
+ import org.springframework.context.annotation.Lazy;
626
+ import org.springframework.web.bind.annotation.*;
627
+
628
+ import jakarta.validation.Valid;
629
+ import java.util.List;
630
+
631
+ @Slf4j
632
+ @RestController
633
+ @RequestMapping("/api/v2/alloc/canteen")
634
+ @Api(tags = "lsh_食堂档口相关控制器")
635
+ public class AllocCanteenController {
636
+
637
+ @Autowired
638
+ @Lazy
639
+ private AllocCanteenService allocCanteenService;
640
+
641
+ @ApiOperation("分页查询食堂列表")
642
+ @PostMapping("/page-canteen")
643
+ public Page<AllocCanteenVO> pageCanteen(@RequestBody LeRequest<AllocCanteenStallPageParam> request) {
644
+ return allocCanteenService.pageCanteen(request.getContent());
645
+ }
646
+
647
+ @ApiOperation("查询区域食堂档口餐线编号")
648
+ @PostMapping("/get-canteen-num")
649
+ public LeResponse<String> getCanteenNum(@Valid @RequestBody LeRequest<AllocCanteenNumParam> request) {
650
+ return LeResponse.succ(allocCanteenBusiness.getCanteenNum(request.getContent()));
651
+ }
652
+
653
+ @ApiOperation("新增食堂")
654
+ @PostMapping("/add-canteen")
655
+ @RequiresGuest
656
+ public void addCanteen(@Valid @RequestBody LeRequest<AllocCanteenModel> request) {
657
+ allocCanteenBusiness.addCanteen(request.getContent());
658
+ }
659
+
660
+ @ApiOperation("删除食堂")
661
+ @PostMapping("/remove-canteen")
662
+ public void removeCanteen(@Valid @RequestBody LeRequest<Long> request) {
663
+ allocCanteenBusiness.removeCanteen(request.getContent());
664
+ }
665
+ }
666
+ ```
667
+
668
+ ### 示例3:MgrMenuController
669
+
670
+ ```java
671
+ package net.xnzn.core.auth.menu.controller;
672
+
673
+ import com.pig4cloud.pigx.common.core.util.LeRequest;
674
+ import io.swagger.annotations.Api;
675
+ import io.swagger.annotations.ApiOperation;
676
+ import net.xnzn.framework.secure.filter.annotation.RequiresAuthentication;
677
+ import net.xnzn.framework.secure.filter.annotation.RequiresGuest;
678
+ import org.springframework.beans.factory.annotation.Autowired;
679
+ import org.springframework.web.bind.annotation.*;
680
+
681
+ import jakarta.validation.Valid;
682
+ import java.util.List;
683
+
684
+ @RestController
685
+ @RequestMapping("/api/v1/mgrmenu")
686
+ @Api(value = "mgrmenu", tags = "菜单权限表管理")
687
+ public class MgrMenuController {
688
+
689
+ @Autowired
690
+ private MgrMenuService mgrMenuService;
691
+
692
+ @ApiOperation(value = "新增菜单")
693
+ @PostMapping("/add")
694
+ @RequiresAuthentication
695
+ public void saveMenu(@Valid @RequestBody LeRequest<MgrMenuVO> request) {
696
+ MgrMenuVO mgrMenuVO = request.getContent();
697
+ mgrMenuService.saveMenu(mgrMenuVO);
698
+ }
699
+
700
+ @ApiOperation(value = "更新菜单")
701
+ @PostMapping("/update")
702
+ @RequiresAuthentication
703
+ public boolean updateMenu(@Valid @RequestBody LeRequest<MgrMenuVO> request) {
704
+ MgrMenuVO mgrMenuVO = request.getContent();
705
+ return mgrMenuService.updateMenu(mgrMenuVO);
706
+ }
707
+
708
+ @ApiOperation(value = "删除菜单")
709
+ @DeleteMapping("/{id}")
710
+ @RequiresGuest
711
+ public boolean removeById(@PathVariable Long id) {
712
+ return mgrMenuService.removeById(id);
713
+ }
714
+ }
715
+ ```
716
+
717
+ ---
718
+
719
+ ## 检查清单
720
+
721
+ 生成 API 代码前必须检查:
722
+
723
+ - [ ] **认证注解是否添加**?(`@RequiresAuthentication` 或 `@RequiresGuest`)
724
+ - [ ] **API 文档注解是否添加**?(`@Api`, `@ApiOperation`)
725
+ - [ ] **参数校验是否正确**?(`@Validated` + 分组,或 `@Valid`)
726
+ - [ ] **是否使用 `LeRequest<T>` 封装请求**?
727
+ - [ ] **返回值类型是否正确**?(分页用 `Page<VO>`,单数据用 `LeResponse<T>` 或 VO)
728
+ - [ ] **HTTP 方法是否正确**?(查询 POST/GET,新增 POST,修改 POST/PUT)
729
+ - [ ] **路径命名是否规范**?(`/add`, `/update`, `/query`, `/delete`)
730
+ - [ ] **是否使用中文注释和错误提示**?
731
+ - [ ] **敏感操作是否加了分布式锁**?
732
+ - [ ] **审计字段是否正确配置**?(crby/crtime/upby/uptime)
733
+
734
+ ---
735
+
736
+ ## 错误对比
737
+
738
+ ### ❌ 不要做
739
+
740
+ ```java
741
+ // 错误 1: 缺少认证注解
742
+ @RestController
743
+ public class XxxController { }
744
+
745
+ // 错误 2: 不使用参数封装
746
+ @PostMapping("/add")
747
+ public Long add(@RequestBody XxxDTO dto) { } // 应该用 LeRequest<XxxDTO>
748
+
749
+ // 错误 3: 不使用分组校验
750
+ @PostMapping("/add")
751
+ public Long add(@Valid @RequestBody LeRequest<XxxDTO> request) { } // 应该用 @Validated(InsertGroup.class)
752
+
753
+ // 错误 4: 使用 javax.validation(JDK 21 应用 jakarta.validation)
754
+ import javax.validation.constraints.NotNull; // ❌ 错误
755
+
756
+ // 错误 5: 审计字段使用 RuoYi 命名
757
+ private String createBy; // ❌ 应该用 crby
758
+
759
+ // 错误 6: 主键策略错误
760
+ @TableId(type = IdType.ASSIGN_ID) // ❌ leniu 使用自增
761
+ // 应该用
762
+ @TableId(value = "id", type = IdType.AUTO)
763
+ ```
764
+
765
+ ### ✅ 正确做法
766
+
767
+ ```java
768
+ // 正确 1: 添加认证注解
769
+ @RestController
770
+ @RequiresAuthentication
771
+ public class XxxController { }
772
+
773
+ // 正确 2: 使用参数封装
774
+ @PostMapping("/add")
775
+ public void add(@RequestBody LeRequest<XxxDTO> request) {
776
+ xxxService.add(request.getContent());
777
+ }
778
+
779
+ // 正确 3: 使用分组校验
780
+ @Validated(InsertGroup.class)
781
+
782
+ // 正确 4: 使用 Jakarta Validation
783
+ import jakarta.validation.constraints.NotNull; // ✅ 正确
784
+
785
+ // 正确 5: 使用 leniu 审计字段
786
+ @TableField(fill = FieldFill.INSERT)
787
+ private String crby;
788
+
789
+ // 正确 6: 使用自增主键
790
+ @TableId(value = "id", type = IdType.AUTO)
791
+ private Long id;
792
+ ```
793
+
794
+ ---
795
+
796
+ ## 相关技能
797
+
798
+ | 需要了解 | 激活 Skill |
799
+ |---------|-----------|
800
+ | Service 层规范 | `leniu-service-development` |
801
+ | Entity 实体规范 | `leniu-entity-design` |
802
+ | 数据库设计 | `leniu-database-design` |
803
+ | 原始 API 规范 | `api-development` (RuoYi-Vue-Plus) |