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,599 @@
1
+ ---
2
+ name: data-permission
3
+ description: |
4
+ 数据权限开发指南。实现行级数据隔离,支持部门权限、本人权限、自定义权限等 6 种权限类型。
5
+
6
+ 触发场景:
7
+ - 为业务模块添加数据权限过滤
8
+ - 配置部门级数据隔离
9
+ - 扩展自定义数据权限类型
10
+ - 临时忽略数据权限查询全量数据
11
+ - 排查数据权限不生效问题
12
+
13
+ 触发词:数据权限、@DataPermission、DataScope、行级权限、数据隔离、部门权限、本人权限、自定义权限、权限过滤、数据过滤、按部门过滤、按创建人过滤
14
+
15
+ 注意:如果是认证授权(登录、Token、Sa-Token)或菜单/按钮权限,请使用 security-guard。
16
+ ---
17
+
18
+ # 数据权限开发指南
19
+
20
+ ## 概述
21
+
22
+ 数据权限是**行级**数据过滤机制,通过 MyBatis 拦截器在 SQL 执行前自动注入过滤条件,实现"不同用户看到不同数据"。
23
+
24
+ **与功能权限的区别**:
25
+ - **功能权限**(security-guard):控制"能不能访问这个接口"
26
+ - **数据权限**(本技能):控制"访问接口后能看到哪些数据"
27
+
28
+ ---
29
+
30
+ ## 1. 核心概念
31
+
32
+ ### 1.1 六种权限类型
33
+
34
+ | 类型 | 字典值 | 说明 | SQL 效果 |
35
+ |------|--------|------|---------|
36
+ | **全部数据** | 1 | 无过滤条件 | 不拼接任何条件 |
37
+ | **自定义权限** | 2 | 按角色关联的部门 | `dept_id IN (1,2,3)` |
38
+ | **本部门** | 3 | 只看本部门 | `dept_id = 100` |
39
+ | **本部门及以下** | 4 | 本部门 + 子部门 | `dept_id IN (100,101,102)` |
40
+ | **仅本人** | 5 | 只看自己创建的 | `create_by = 1` |
41
+ | **部门及以下或本人** | 6 | 混合模式 | `dept_id IN (...) OR create_by = 1` |
42
+
43
+ ### 1.2 技术架构
44
+
45
+ ```
46
+ 请求 → Controller → Service (@DataPermission) → Mapper
47
+
48
+ PlusDataPermissionInterceptor 拦截
49
+
50
+ PlusDataPermissionHandler 解析 SpEL
51
+
52
+ 拼接 WHERE 条件 → 执行 SQL
53
+ ```
54
+
55
+ ### 1.3 核心类位置
56
+
57
+ | 类 | 路径 | 职责 |
58
+ |---|------|------|
59
+ | `@DataPermission` | `ruoyi-common/ruoyi-common-mybatis/.../annotation/` | 权限注解 |
60
+ | `@DataColumn` | `ruoyi-common/ruoyi-common-mybatis/.../annotation/` | 列配置注解 |
61
+ | `DataScopeType` | `ruoyi-common/ruoyi-common-mybatis/.../enums/` | 权限类型枚举 |
62
+ | `PlusDataPermissionInterceptor` | `ruoyi-common/ruoyi-common-mybatis/.../interceptor/` | SQL 拦截器 |
63
+ | `PlusDataPermissionHandler` | `ruoyi-common/ruoyi-common-mybatis/.../handler/` | 权限处理器 |
64
+ | `DataPermissionHelper` | `ruoyi-common/ruoyi-common-mybatis/.../helper/` | 权限助手类 |
65
+ | `ISysDataScopeService` | `ruoyi-modules/ruoyi-system/.../service/` | 权限数据服务 |
66
+
67
+ ---
68
+
69
+ ## 2. 快速上手(3 分钟添加权限)
70
+
71
+ ### 步骤 1:在 Service 方法上添加注解
72
+
73
+ ```java
74
+ import org.dromara.common.mybatis.annotation.DataPermission;
75
+ import org.dromara.common.mybatis.annotation.DataColumn;
76
+
77
+ @Service
78
+ @RequiredArgsConstructor
79
+ public class OrderServiceImpl implements IOrderService {
80
+
81
+ private final OrderMapper baseMapper; // ✅ 直接注入 Mapper(NO DAO!)
82
+
83
+ /**
84
+ * 分页查询(带数据权限)
85
+ */
86
+ @DataPermission({
87
+ @DataColumn(key = "deptName", value = "create_dept"),
88
+ @DataColumn(key = "userName", value = "create_by")
89
+ })
90
+ @Override
91
+ public TableDataInfo<OrderVo> pageWithPermission(OrderBo bo, PageQuery pageQuery) {
92
+ LambdaQueryWrapper<Order> lqw = buildQueryWrapper(bo);
93
+ Page<OrderVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
94
+ return TableDataInfo.build(result);
95
+ }
96
+ }
97
+ ```
98
+
99
+ ### 步骤 2:确保表有权限字段
100
+
101
+ ```sql
102
+ CREATE TABLE m_order (
103
+ id BIGINT(20) NOT NULL COMMENT '主键ID',
104
+ -- ... 业务字段 ...
105
+
106
+ -- ✅ 必须有这两个字段用于数据权限
107
+ create_dept BIGINT(20) DEFAULT NULL COMMENT '创建部门',
108
+ create_by BIGINT(20) DEFAULT NULL COMMENT '创建人',
109
+
110
+ -- 其他审计字段
111
+ create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
112
+ PRIMARY KEY (id)
113
+ );
114
+ ```
115
+
116
+ ### 步骤 3:配置角色的数据权限
117
+
118
+ 在系统管理 → 角色管理中,为角色配置数据权限范围(全部/本部门/本部门及以下/仅本人/自定义)。
119
+
120
+ ---
121
+
122
+ ## 3. 使用场景模板
123
+
124
+ ### 场景 A:按部门过滤
125
+
126
+ 最常见的场景,用户只能看到本部门及以下的数据。
127
+
128
+ ```java
129
+ /**
130
+ * 按部门过滤
131
+ *
132
+ * 权限效果:
133
+ * - 全部数据:无过滤
134
+ * - 本部门:WHERE create_dept = 100
135
+ * - 本部门及以下:WHERE create_dept IN (100, 101, 102)
136
+ * - 自定义:WHERE create_dept IN (角色关联的部门ID)
137
+ */
138
+ @DataPermission({
139
+ @DataColumn(key = "deptName", value = "create_dept")
140
+ })
141
+ @Override
142
+ public List<Order> listWithPermission(OrderBo bo) {
143
+ return list(buildQueryWrapper(bo));
144
+ }
145
+ ```
146
+
147
+ ### 场景 B:按创建人过滤
148
+
149
+ 用户只能看到自己创建的数据。
150
+
151
+ ```java
152
+ /**
153
+ * 按创建人过滤
154
+ *
155
+ * 权限效果:
156
+ * - 仅本人:WHERE create_by = 1(当前用户ID)
157
+ */
158
+ @DataPermission({
159
+ @DataColumn(key = "userName", value = "create_by")
160
+ })
161
+ @Override
162
+ public List<Task> listMyTasks(TaskBo bo) {
163
+ return list(buildQueryWrapper(bo));
164
+ }
165
+ ```
166
+
167
+ ### 场景 C:部门 + 创建人混合
168
+
169
+ 同时支持按部门和按创建人过滤,根据角色配置自动选择。
170
+
171
+ ```java
172
+ /**
173
+ * 部门 + 创建人混合
174
+ *
175
+ * 权限效果:
176
+ * - 本部门:WHERE create_dept = 100
177
+ * - 仅本人:WHERE create_by = 1
178
+ * - 部门及以下或本人:WHERE create_dept IN (...) OR create_by = 1
179
+ */
180
+ @DataPermission({
181
+ @DataColumn(key = "deptName", value = "create_dept"),
182
+ @DataColumn(key = "userName", value = "create_by")
183
+ })
184
+ @Override
185
+ public TableDataInfo<ProjectVo> pageWithPermission(ProjectBo bo, PageQuery pageQuery) {
186
+ LambdaQueryWrapper<Project> lqw = buildQueryWrapper(bo);
187
+ Page<ProjectVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
188
+ return TableDataInfo.build(result);
189
+ }
190
+ ```
191
+
192
+ ### 场景 D:关联查询时的表别名
193
+
194
+ 当 SQL 涉及多表关联时,需要使用正确的表别名。
195
+
196
+ ```java
197
+ /**
198
+ * 多表关联查询
199
+ *
200
+ * SQL 示例:
201
+ * SELECT u.*, d.dept_name
202
+ * FROM sys_user u
203
+ * LEFT JOIN sys_dept d ON u.dept_id = d.dept_id
204
+ *
205
+ * 注意:value 中使用表别名 u.dept_id
206
+ */
207
+ @DataPermission({
208
+ @DataColumn(key = "deptName", value = "u.dept_id"),
209
+ @DataColumn(key = "userName", value = "u.user_id")
210
+ })
211
+ @Override
212
+ public TableDataInfo<SysUserVo> pageWithPermission(SysUserBo bo, PageQuery pageQuery) {
213
+ // ...
214
+ }
215
+ ```
216
+
217
+ ### 场景 E:临时忽略数据权限
218
+
219
+ 某些场景需要查询全量数据(如统计、初始化)。
220
+
221
+ ```java
222
+ import org.dromara.common.mybatis.helper.DataPermissionHelper;
223
+
224
+ @Service
225
+ public class StatisticsServiceImpl implements IStatisticsService {
226
+
227
+ @Autowired
228
+ private IOrderService orderService;
229
+
230
+ /**
231
+ * 统计总数(需要全量数据)
232
+ */
233
+ @Override
234
+ public Long countTotal() {
235
+ // 忽略数据权限,查询所有数据
236
+ return DataPermissionHelper.ignore(() -> {
237
+ return orderService.count();
238
+ });
239
+ }
240
+
241
+ /**
242
+ * 初始化缓存(需要全量数据)
243
+ */
244
+ @Override
245
+ public void initCache() {
246
+ DataPermissionHelper.ignore(() -> {
247
+ List<Config> configs = configService.list();
248
+ // 处理缓存...
249
+ return null;
250
+ });
251
+ }
252
+ }
253
+ ```
254
+
255
+ ### 场景 F:指定权限标识跳过过滤
256
+
257
+ 拥有特定权限的角色可以跳过数据过滤。
258
+
259
+ ```java
260
+ /**
261
+ * 拥有 order:all 权限的角色可以查看所有订单
262
+ */
263
+ @DataPermission({
264
+ @DataColumn(key = "deptName", value = "create_dept", permission = "order:all")
265
+ })
266
+ @Override
267
+ public List<Order> listAllOrders(OrderBo bo) {
268
+ return list(buildQueryWrapper(bo));
269
+ }
270
+ ```
271
+
272
+ ---
273
+
274
+ ## 4. 扩展自定义权限类型
275
+
276
+ ### 4.1 添加新的权限类型
277
+
278
+ **步骤 1**:修改 `DataScopeType` 枚举
279
+
280
+ ```java
281
+ // 位置:ruoyi-common-mybatis/.../enums/DataScopeType.java
282
+
283
+ public enum DataScopeType {
284
+
285
+ // ... 现有类型 ...
286
+
287
+ /**
288
+ * 按区域过滤(自定义类型示例)
289
+ */
290
+ REGION("7", "按区域", "#{#regionName} IN ( #{@sdss.getUserRegions( #user.userId )} )"),
291
+ ;
292
+
293
+ // ... 其他代码 ...
294
+ }
295
+ ```
296
+
297
+ **步骤 2**:在 `ISysDataScopeService` 中添加方法
298
+
299
+ ```java
300
+ // 接口
301
+ public interface ISysDataScopeService {
302
+ // ... 现有方法 ...
303
+
304
+ /**
305
+ * 获取用户关联的区域ID列表
306
+ */
307
+ String getUserRegions(Long userId);
308
+ }
309
+
310
+ // 实现
311
+ @Service("sdss")
312
+ public class SysDataScopeServiceImpl implements ISysDataScopeService {
313
+
314
+ @Override
315
+ @Cacheable(cacheNames = CacheNames.SYS_USER_REGIONS, key = "#userId")
316
+ public String getUserRegions(Long userId) {
317
+ List<Long> regionIds = userRegionMapper.selectRegionIdsByUserId(userId);
318
+ if (CollUtil.isEmpty(regionIds)) {
319
+ return "-1"; // 返回 -1 表示无权限
320
+ }
321
+ return StringUtils.join(regionIds, ",");
322
+ }
323
+ }
324
+ ```
325
+
326
+ **步骤 3**:使用新权限类型
327
+
328
+ ```java
329
+ @DataPermission({
330
+ @DataColumn(key = "regionName", value = "region_id")
331
+ })
332
+ @Override
333
+ public List<Store> listByRegion(StoreBo bo) {
334
+ return list(buildQueryWrapper(bo));
335
+ }
336
+ ```
337
+
338
+ ### 4.2 添加自定义变量
339
+
340
+ 通过 `DataPermissionHelper` 设置自定义变量供 SpEL 表达式使用。
341
+
342
+ ```java
343
+ @Service
344
+ @RequiredArgsConstructor
345
+ public class OrderServiceImpl implements IOrderService {
346
+
347
+ private final OrderMapper baseMapper; // ✅ 直接注入 Mapper(NO DAO!)
348
+
349
+ @Override
350
+ public TableDataInfo<OrderVo> pageByShop(Long shopId, OrderBo bo, PageQuery pageQuery) {
351
+ // 设置自定义变量(请求结束后 SaStorage 自动清理,无需手动移除)
352
+ DataPermissionHelper.setVariable("shopId", shopId);
353
+ return pageWithPermission(bo, pageQuery);
354
+ }
355
+
356
+ // Service 中使用
357
+ @DataPermission({
358
+ @DataColumn(key = "shopId", value = "shop_id") // 使用自定义变量
359
+ })
360
+ private TableDataInfo<OrderVo> pageWithPermission(OrderBo bo, PageQuery pageQuery) {
361
+ LambdaQueryWrapper<Order> lqw = buildQueryWrapper(bo);
362
+ Page<OrderVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
363
+ return TableDataInfo.build(result);
364
+ }
365
+ }
366
+ ```
367
+
368
+ ---
369
+
370
+ ## 5. 禁止项与必须项
371
+
372
+ ### 5.1 绝对禁止
373
+
374
+ ```java
375
+ // ❌ 禁止 1:在 ISysDataScopeService 内调用带权限的方法(导致死循环)
376
+ @Service("sdss")
377
+ public class SysDataScopeServiceImpl implements ISysDataScopeService {
378
+
379
+ @Override
380
+ public String getDeptAndChild(Long deptId) {
381
+ // ❌ 禁止!deptService.list() 如果带 @DataPermission 会死循环
382
+ List<SysDept> depts = deptService.list(wrapper);
383
+
384
+ // ✅ 正确:直接使用 Mapper 或忽略权限
385
+ List<SysDept> depts = deptMapper.selectList(wrapper);
386
+ // 或
387
+ List<SysDept> depts = DataPermissionHelper.ignore(() -> deptService.list(wrapper));
388
+ }
389
+ }
390
+
391
+ // ❌ 禁止 2:表别名不匹配
392
+ @DataPermission({
393
+ @DataColumn(key = "deptName", value = "user.dept_id") // ❌ 别名是 user
394
+ })
395
+ // 但 SQL 是:SELECT * FROM sys_user u ... // 别名是 u
396
+
397
+ // ✅ 正确
398
+ @DataPermission({
399
+ @DataColumn(key = "deptName", value = "u.dept_id") // ✅ 与 SQL 别名一致
400
+ })
401
+
402
+ // ❌ 禁止 3:在 Controller 层使用 @DataPermission
403
+ @RestController
404
+ public class OrderController {
405
+ @DataPermission({...}) // ❌ 无效!必须在 Service/Mapper 层
406
+ @GetMapping("/list")
407
+ public R<List<OrderVo>> list() { }
408
+ }
409
+ ```
410
+
411
+ ### 5.2 必须遵守
412
+
413
+ ```java
414
+ // ✅ 必须 1:Entity 继承 TenantEntity(包含 create_dept、create_by)
415
+ @Data
416
+ @EqualsAndHashCode(callSuper = true)
417
+ @TableName("m_order")
418
+ public class Order extends TenantEntity { // ✅ 继承 TenantEntity
419
+ // ...
420
+ }
421
+
422
+ // ✅ 必须 2:@DataPermission 放在 Service 实现类或 Mapper 接口上
423
+ @Service
424
+ @RequiredArgsConstructor
425
+ public class OrderServiceImpl implements IOrderService {
426
+
427
+ private final OrderMapper baseMapper; // ✅ 直接注入 Mapper
428
+
429
+ @DataPermission({...}) // ✅ 正确位置
430
+ @Override
431
+ public TableDataInfo<OrderVo> pageWithPermission(...) { }
432
+ }
433
+
434
+ // ✅ 必须 3:多表查询时使用正确的表别名
435
+ // SQL: SELECT o.*, u.user_name FROM m_order o LEFT JOIN sys_user u ON o.create_by = u.user_id
436
+ @DataPermission({
437
+ @DataColumn(key = "deptName", value = "o.create_dept"), // ✅ 订单表别名 o
438
+ @DataColumn(key = "userName", value = "o.create_by") // ✅ 使用 o.create_by
439
+ })
440
+ ```
441
+
442
+ ---
443
+
444
+ ## 6. 问题排查清单
445
+
446
+ ### 6.1 数据权限不生效
447
+
448
+ | 检查项 | 可能原因 | 解决方案 |
449
+ |--------|---------|---------|
450
+ | 是否超级管理员 | 超管和租户管理员自动跳过权限 | 使用普通用户测试 |
451
+ | 角色是否配置数据权限 | 角色的数据范围为"全部数据" | 修改角色数据权限范围 |
452
+ | 注解位置是否正确 | @DataPermission 不在 Service/Mapper 层 | 移动注解到 Service 实现类 |
453
+ | 表别名是否匹配 | value 中的别名与 SQL 不一致 | 检查并修正表别名 |
454
+ | 是否调用了带注解的方法 | Service 调用了不带注解的方法 | 确保调用带 @DataPermission 的方法 |
455
+
456
+ ### 6.2 SQL 语法错误
457
+
458
+ | 错误现象 | 可能原因 | 解决方案 |
459
+ |---------|---------|---------|
460
+ | `Unknown column` | 表别名不存在 | 检查 value 中的表别名 |
461
+ | `dept_id IN ()` | 权限服务返回空 | 检查 ISysDataScopeService 实现 |
462
+ | 条件重复拼接 | 多次调用带权限的方法 | 检查调用链 |
463
+
464
+ ### 6.3 调试技巧
465
+
466
+ ```yaml
467
+ # application.yml - 开启 SQL 日志查看拼接结果
468
+ mybatis-plus:
469
+ configuration:
470
+ log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
471
+ ```
472
+
473
+ ```java
474
+ // 代码中打印当前用户权限信息
475
+ LoginUser user = LoginHelper.getLoginUser();
476
+ log.info("当前用户: {}, 部门: {}, 角色: {}",
477
+ user.getUserId(),
478
+ user.getDeptId(),
479
+ user.getRoles().stream()
480
+ .map(r -> r.getRoleName() + "(" + r.getDataScope() + ")")
481
+ .collect(Collectors.joining(",")));
482
+ ```
483
+
484
+ ---
485
+
486
+ ## 7. 常见问题 FAQ
487
+
488
+ ### Q1:如何让某个接口不受数据权限限制?
489
+
490
+ ```java
491
+ // 方法 1:使用 DataPermissionHelper.ignore()
492
+ public List<Order> listAll() {
493
+ return DataPermissionHelper.ignore(() -> orderService.list());
494
+ }
495
+
496
+ // 方法 2:调用不带 @DataPermission 的 Service 方法
497
+ public List<Order> listAll() {
498
+ return orderService.list(); // 这个方法没有 @DataPermission
499
+ }
500
+
501
+ // 方法 3:使用 permission 参数
502
+ @DataPermission({
503
+ @DataColumn(key = "deptName", value = "create_dept", permission = "order:all")
504
+ })
505
+ // 拥有 order:all 权限的角色不过滤
506
+ ```
507
+
508
+ ### Q2:多角色用户权限如何计算?
509
+
510
+ - **SELECT 查询**:多个角色的权限用 `OR` 连接(权限并集)
511
+ - **UPDATE/DELETE**:多个角色的权限用 `AND` 连接(权限交集)
512
+ - 可通过 `joinStr` 参数自定义
513
+
514
+ ```java
515
+ @DataPermission(value = {
516
+ @DataColumn(key = "deptName", value = "create_dept")
517
+ }, joinStr = "AND") // 强制使用 AND 连接
518
+ ```
519
+
520
+ ### Q3:如何只对特定方法启用数据权限?
521
+
522
+ ```java
523
+ @Service
524
+ @RequiredArgsConstructor
525
+ public class OrderServiceImpl implements IOrderService {
526
+
527
+ private final OrderMapper baseMapper; // ✅ 直接注入 Mapper
528
+
529
+ // 不带权限的普通查询
530
+ @Override
531
+ public List<Order> list(LambdaQueryWrapper<Order> wrapper) {
532
+ return baseMapper.selectList(wrapper);
533
+ }
534
+
535
+ // 带权限的查询(命名区分)
536
+ @DataPermission({
537
+ @DataColumn(key = "deptName", value = "create_dept")
538
+ })
539
+ @Override
540
+ public List<Order> listWithPermission(LambdaQueryWrapper<Order> wrapper) {
541
+ return baseMapper.selectList(wrapper);
542
+ }
543
+ }
544
+ ```
545
+
546
+ ### Q4:如何在 Mapper XML 中使用数据权限?
547
+
548
+ ```java
549
+ // Mapper 接口
550
+ @DataPermission({
551
+ @DataColumn(key = "deptName", value = "o.create_dept")
552
+ })
553
+ List<OrderVo> selectOrderReport(@Param("bo") OrderBo bo);
554
+ ```
555
+
556
+ ```xml
557
+ <!-- Mapper XML -->
558
+ <select id="selectOrderReport" resultType="OrderVo">
559
+ SELECT o.*, u.user_name
560
+ FROM m_order o
561
+ LEFT JOIN sys_user u ON o.create_by = u.user_id
562
+ WHERE o.status = #{bo.status}
563
+ <!-- 数据权限会自动追加到这里 -->
564
+ </select>
565
+ ```
566
+
567
+ ---
568
+
569
+ ## 8. 参考文件路径
570
+
571
+ ### 核心文件
572
+
573
+ | 文件 | 路径 |
574
+ |------|------|
575
+ | @DataPermission | `ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/annotation/DataPermission.java` |
576
+ | @DataColumn | `ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/annotation/DataColumn.java` |
577
+ | DataScopeType | `ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/enums/DataScopeType.java` |
578
+ | PlusDataPermissionInterceptor | `ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/interceptor/PlusDataPermissionInterceptor.java` |
579
+ | PlusDataPermissionHandler | `ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/PlusDataPermissionHandler.java` |
580
+ | DataPermissionHelper | `ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/helper/DataPermissionHelper.java` |
581
+ | ISysDataScopeService | `ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysDataScopeService.java` |
582
+
583
+ ### 使用示例
584
+
585
+ | 文件 | 路径 |
586
+ |------|------|
587
+ | SysUserServiceImpl | `ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java` |
588
+ | SysRoleServiceImpl | `ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java` |
589
+ | SysDeptMapper | `ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysDeptMapper.java` |
590
+
591
+ ---
592
+
593
+ ## 多项目适配说明
594
+
595
+
596
+ ## 注意事项
597
+
598
+ - 如果需要 leniu-tengyun-core 项目的数据权限开发规范,请使用 `leniu-data-permission` skill
599
+ - leniu-tengyun-core 使用物理库隔离架构,与 RuoYi-Vue-Plus 的逻辑隔离方式不同