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,676 @@
1
+ ---
2
+ name: workflow-engine
3
+ description: |
4
+ 工作流引擎开发、流程管理、任务办理。基于 WarmFlow 实现审批流、业务流程集成。
5
+
6
+ 触发场景:
7
+ - 启动工作流程(发起审批、提交申请)
8
+ - 办理任务(审批通过、驳回、转办、委派)
9
+ - 流程定义管理(设计流程、配置节点)
10
+ - 业务模块集成工作流(订单审批、请假申请)
11
+ - 监听工作流事件(流程状态变更通知)
12
+ - 配置办理人(用户、角色、部门、岗位、SpEL表达式)
13
+
14
+ 触发词:工作流、流程、审批、WarmFlow、FlowEngine、任务、办理、驳回、转办、委派、加签、减签、抄送、流程实例、流程定义、办理人、GlobalListener、ProcessEvent
15
+ ---
16
+
17
+ # 工作流引擎开发规范
18
+
19
+ > 本项目基于 **WarmFlow** 实现工作流引擎,提供流程定义、流程实例、任务管理、办理人分配等功能。
20
+
21
+ ## 架构概述
22
+
23
+ ```
24
+ ┌─────────────────────────────────────────────────────────────────┐
25
+ │ Controller Layer │
26
+ │ FlwTaskController | FlwInstanceController | FlwDefinitionController
27
+ │ FlwCategoryController | FlwSpelController | TestLeaveController │
28
+ └─────────────────────────────┬───────────────────────────────────┘
29
+
30
+ ┌─────────────────────────────▼───────────────────────────────────┐
31
+ │ Service Layer │
32
+ │ FlwTaskService | FlwInstanceService | FlwDefinitionService │
33
+ │ FlwCategoryService | FlwSpelService | TestLeaveService │
34
+ │ │ │
35
+ │ ┌───────────────────────────▼─────────────────────────────────┐│
36
+ │ │ WarmFlow Core (FlowEngine) ││
37
+ │ │ TaskService | InsService | DefService | NodeService ││
38
+ │ └─────────────────────────────────────────────────────────────┘│
39
+ └─────────────────────────────┬───────────────────────────────────┘
40
+
41
+ ┌─────────────────────────────▼───────────────────────────────────┐
42
+ │ Mapper Layer │
43
+ │ FlwCategoryMapper | FlwSpelMapper | TestLeaveMapper │
44
+ │ FlwInstanceMapper | FlwTaskMapper | FlwInstanceBizExtMapper │
45
+ └─────────────────────────────┬───────────────────────────────────┘
46
+
47
+ ┌─────────────────────────────▼───────────────────────────────────┐
48
+ │ Listener & Handler │
49
+ │ WorkflowGlobalListener (任务监听) | FlowProcessEventHandler (事件发布)
50
+ └─────────────────────────────────────────────────────────────────┘
51
+ ```
52
+
53
+ ---
54
+
55
+ ## 核心组件
56
+
57
+ ### 1. FlowEngine 服务访问
58
+
59
+ ```java
60
+ import org.dromara.warm.flow.core.FlowEngine;
61
+
62
+ // 任务服务
63
+ FlowEngine.taskService()
64
+
65
+ // 实例服务
66
+ FlowEngine.insService()
67
+
68
+ // 流程定义服务
69
+ FlowEngine.defService()
70
+
71
+ // 节点服务
72
+ FlowEngine.nodeService()
73
+
74
+ // 历史任务服务
75
+ FlowEngine.hisTaskService()
76
+
77
+ // 用户服务
78
+ FlowEngine.userService()
79
+ ```
80
+
81
+ ### 2. 任务状态枚举
82
+
83
+ ```java
84
+ package org.dromara.workflow.common.enums;
85
+
86
+ public enum TaskStatusEnum {
87
+ CANCEL("cancel", "撤销"),
88
+ PASS("pass", "通过"),
89
+ WAITING("waiting", "待审核"),
90
+ INVALID("invalid", "作废"),
91
+ BACK("back", "退回"),
92
+ TERMINATION("termination", "终止"),
93
+ TRANSFER("transfer", "转办"),
94
+ DEPUTE("depute", "委托"),
95
+ COPY("copy", "抄送"),
96
+ SIGN("sign", "加签"),
97
+ SIGN_OFF("sign_off", "减签"),
98
+ TIMEOUT("timeout", "超时");
99
+
100
+ private final String status;
101
+ private final String desc;
102
+
103
+ // 判断状态是否为通过或退回
104
+ public static boolean isPassOrBack(String status) {
105
+ return PASS.getStatus().equals(status) || BACK.getStatus().equals(status);
106
+ }
107
+ }
108
+ ```
109
+
110
+ ### 3. 办理人类型枚举
111
+
112
+ > ⚠️ **注意**:USER 和 SPEL 类型没有前缀!
113
+
114
+ ```java
115
+ package org.dromara.workflow.common.enums;
116
+
117
+ public enum TaskAssigneeEnum {
118
+ USER("用户", ""), // ⚠️ 用户没有前缀
119
+ ROLE("角色", "role:"),
120
+ DEPT("部门", "dept:"),
121
+ POST("岗位", "post:"),
122
+ SPEL("SpEL表达式", ""); // ⚠️ SpEL 没有前缀,通过 $ 或 # 开头判断
123
+
124
+ private final String desc;
125
+ private final String code;
126
+
127
+ // 判断是否为 SPEL 表达式(以 $ 或 # 开头)
128
+ public static boolean isSpelExpression(String value) {
129
+ return StringUtils.startsWith(value, "$") || StringUtils.startsWith(value, "#");
130
+ }
131
+ }
132
+ ```
133
+
134
+ **storageId 格式示例**:
135
+ ```
136
+ 123 → 用户ID 123(无前缀)
137
+ role:456 → 角色ID 456
138
+ dept:789 → 部门ID 789
139
+ post:101 → 岗位ID 101
140
+ #{expression} → SpEL表达式(# 开头)
141
+ ${variable} → 默认变量策略($ 开头)
142
+ ```
143
+
144
+ ---
145
+
146
+ ## 常用操作
147
+
148
+ ### 1. 启动流程
149
+
150
+ ```java
151
+ @Autowired
152
+ private IFlwTaskService flwTaskService;
153
+
154
+ // 方式一:使用 FlwTaskService
155
+ public void startProcess() {
156
+ StartProcessBo bo = new StartProcessBo();
157
+ bo.setFlowCode("leave_apply"); // 流程编码
158
+ bo.setBusinessId("order_123"); // 业务ID
159
+ bo.setVariables(Map.of("amount", 1000)); // 流程变量
160
+
161
+ StartProcessReturnDTO result = flwTaskService.startWorkFlow(bo);
162
+ Long instanceId = result.getProcessInstanceId();
163
+ Long taskId = result.getTaskId();
164
+ }
165
+ ```
166
+
167
+ ```java
168
+ @Autowired
169
+ private WorkflowService workflowService;
170
+
171
+ // 方式二:使用 WorkflowService(供其他模块调用)
172
+ public void startProcess() {
173
+ StartProcessDTO dto = new StartProcessDTO();
174
+ dto.setFlowCode("leave_apply");
175
+ dto.setBusinessId("order_123");
176
+ dto.setVariables(Map.of("amount", 1000));
177
+
178
+ StartProcessReturnDTO result = workflowService.startWorkFlow(dto);
179
+ }
180
+ ```
181
+
182
+ ### 2. 办理任务
183
+
184
+ ```java
185
+ public void completeTask() {
186
+ CompleteTaskBo bo = new CompleteTaskBo();
187
+ bo.setTaskId(taskId); // 任务ID
188
+ bo.setMessage("同意"); // 审批意见
189
+ bo.setVariables(Map.of("approved", true)); // 流程变量
190
+
191
+ // 指定下一节点办理人(可选)
192
+ bo.setAssigneeMap(Map.of(
193
+ "pass:nodeCode", "user:1,user:2"
194
+ ));
195
+
196
+ flwTaskService.completeTask(bo);
197
+ }
198
+ ```
199
+
200
+ ### 3. 驳回任务
201
+
202
+ ```java
203
+ public void rejectTask() {
204
+ BackProcessBo bo = new BackProcessBo();
205
+ bo.setTaskId(taskId);
206
+ bo.setNodeCode("apply_node"); // 驳回到的节点
207
+ bo.setMessage("资料不完整");
208
+
209
+ flwTaskService.backProcess(bo);
210
+ }
211
+ ```
212
+
213
+ ### 4. 转办/委派
214
+
215
+ ```java
216
+ // 转办(转给他人办理,自己不再参与)
217
+ TaskOperationBo transferBo = new TaskOperationBo();
218
+ transferBo.setTaskId(taskId);
219
+ transferBo.setUserId("targetUserId");
220
+ transferBo.setMessage("转交处理");
221
+ flwTaskService.taskOperation(transferBo, FlowConstant.TRANSFER_TASK);
222
+
223
+ // 委派(委托他人代办,最终还需自己确认)
224
+ TaskOperationBo deputeBo = new TaskOperationBo();
225
+ deputeBo.setTaskId(taskId);
226
+ deputeBo.setUserId("targetUserId");
227
+ deputeBo.setMessage("请协助处理");
228
+ flwTaskService.taskOperation(deputeBo, FlowConstant.DELEGATE_TASK);
229
+ ```
230
+
231
+ ### 5. 加签/减签
232
+
233
+ ```java
234
+ // 加签(增加办理人)
235
+ TaskOperationBo addBo = new TaskOperationBo();
236
+ addBo.setTaskId(taskId);
237
+ addBo.setUserIds(List.of("user1", "user2"));
238
+ addBo.setMessage("增加会签人员");
239
+ flwTaskService.taskOperation(addBo, FlowConstant.ADD_SIGNATURE);
240
+
241
+ // 减签(减少办理人)
242
+ TaskOperationBo reduceBo = new TaskOperationBo();
243
+ reduceBo.setTaskId(taskId);
244
+ reduceBo.setUserIds(List.of("user1"));
245
+ reduceBo.setMessage("减少会签人员");
246
+ flwTaskService.taskOperation(reduceBo, FlowConstant.REDUCTION_SIGNATURE);
247
+ ```
248
+
249
+ ---
250
+
251
+ ## 业务集成
252
+
253
+ ### 1. 监听流程事件
254
+
255
+ > 事件类位于 `org.dromara.common.core.domain.event` 包
256
+
257
+ ```java
258
+ import org.springframework.context.event.EventListener;
259
+ import org.dromara.common.core.domain.event.ProcessEvent;
260
+ import org.dromara.common.core.domain.event.ProcessTaskEvent;
261
+ import org.dromara.common.core.domain.event.ProcessDeleteEvent;
262
+
263
+ @Component
264
+ public class OrderWorkflowListener {
265
+
266
+ /**
267
+ * 监听流程状态变更
268
+ */
269
+ @EventListener(condition = "#event.flowCode == 'order_approve'")
270
+ public void onProcessEvent(ProcessEvent event) {
271
+ String businessId = event.getBusinessId();
272
+ String status = event.getStatus();
273
+ boolean isSubmit = event.isSubmit();
274
+
275
+ // 申请人提交
276
+ if (isSubmit) {
277
+ orderService.updateStatus(businessId, "PENDING");
278
+ return;
279
+ }
280
+
281
+ // 根据流程状态更新业务数据
282
+ switch (status) {
283
+ case "finish" -> orderService.updateStatus(businessId, "APPROVED");
284
+ case "back" -> orderService.updateStatus(businessId, "REJECTED");
285
+ case "cancel" -> orderService.updateStatus(businessId, "CANCELLED");
286
+ case "termination" -> orderService.updateStatus(businessId, "TERMINATED");
287
+ case "invalid" -> orderService.updateStatus(businessId, "INVALID");
288
+ }
289
+ }
290
+
291
+ /**
292
+ * 监听任务创建(发送通知)
293
+ */
294
+ @EventListener(condition = "#event.flowCode == 'order_approve'")
295
+ public void onTaskCreated(ProcessTaskEvent event) {
296
+ Long taskId = event.getTaskId();
297
+ String businessId = event.getBusinessId();
298
+ // 获取待办人并发送通知
299
+ sendNotification(taskId);
300
+ }
301
+
302
+ /**
303
+ * 监听流程删除
304
+ */
305
+ @EventListener(condition = "#event.flowCode == 'order_approve'")
306
+ public void onProcessDeleted(ProcessDeleteEvent event) {
307
+ String businessId = event.getBusinessId();
308
+ // 清理业务相关数据
309
+ orderService.cleanupWorkflowData(businessId);
310
+ }
311
+ }
312
+ ```
313
+
314
+ ### 2. 事件类型说明
315
+
316
+ | 事件类 | 触发时机 | 主要字段 |
317
+ |-------|---------|---------|
318
+ | `ProcessEvent` | 流程状态变更(提交、通过、驳回、撤销、终止、作废、完成) | flowCode, businessId, status, submit |
319
+ | `ProcessTaskEvent` | 任务创建时 | flowCode, businessId, taskId, nodeCode |
320
+ | `ProcessDeleteEvent` | 流程删除时 | flowCode, businessId |
321
+
322
+ ### 3. 查询待办/已办任务
323
+
324
+ ```java
325
+ @Autowired
326
+ private IFlwTaskService flwTaskService;
327
+
328
+ // 查询当前用户待办任务
329
+ public TableDataInfo<FlowTaskVo> getTodoList(FlowTaskBo bo, PageQuery pageQuery) {
330
+ return flwTaskService.pageByTaskWait(bo, pageQuery);
331
+ }
332
+
333
+ // 查询当前用户已办任务
334
+ public TableDataInfo<FlowHisTaskVo> getDoneList(FlowTaskBo bo, PageQuery pageQuery) {
335
+ return flwTaskService.pageByTaskFinish(bo, pageQuery);
336
+ }
337
+
338
+ // 查询所有待办任务(管理员)
339
+ public TableDataInfo<FlowTaskVo> getAllTodoList(FlowTaskBo bo, PageQuery pageQuery) {
340
+ return flwTaskService.pageByAllTaskWait(bo, pageQuery);
341
+ }
342
+
343
+ // 查询所有已办任务(管理员)
344
+ public TableDataInfo<FlowHisTaskVo> getAllDoneList(FlowTaskBo bo, PageQuery pageQuery) {
345
+ return flwTaskService.pageByAllTaskFinish(bo, pageQuery);
346
+ }
347
+
348
+ // 查询抄送任务
349
+ public TableDataInfo<FlowTaskVo> getCopyList(FlowTaskBo bo, PageQuery pageQuery) {
350
+ return flwTaskService.pageByTaskCopy(bo, pageQuery);
351
+ }
352
+ ```
353
+
354
+ ---
355
+
356
+ ## 全局监听器
357
+
358
+ `WorkflowGlobalListener` 实现 `GlobalListener` 接口,在任务生命周期的关键节点执行:
359
+
360
+ ```java
361
+ package org.dromara.workflow.listener;
362
+
363
+ import org.dromara.warm.flow.core.listener.GlobalListener;
364
+ import org.dromara.warm.flow.core.listener.ListenerVariable;
365
+
366
+ @Component
367
+ public class WorkflowGlobalListener implements GlobalListener {
368
+
369
+ @Override
370
+ public void create(ListenerVariable listenerVariable) {
371
+ // 任务创建时执行
372
+ }
373
+
374
+ @Override
375
+ public void start(ListenerVariable listenerVariable) {
376
+ // 任务开始办理时执行
377
+ // 可在此处理:抄送设置、自定义变量
378
+ String ext = listenerVariable.getNode().getExt();
379
+ Map<String, Object> variable = listenerVariable.getVariable();
380
+ // 解析节点扩展配置...
381
+ }
382
+
383
+ @Override
384
+ public void assignment(ListenerVariable listenerVariable) {
385
+ // 分派监听器,动态修改待办任务信息
386
+ // 可在此处理:指定办理人、申请节点办理人设置
387
+ List<Task> nextTasks = listenerVariable.getNextTasks();
388
+ FlowParams flowParams = listenerVariable.getFlowParams();
389
+ // 处理办理人权限...
390
+ }
391
+
392
+ @Override
393
+ public void finish(ListenerVariable listenerVariable) {
394
+ // 任务完成后执行
395
+ // 可在此处理:状态更新、消息通知、抄送、事件发布
396
+ Instance instance = listenerVariable.getInstance();
397
+ Definition definition = listenerVariable.getDefinition();
398
+ // 发布流程事件...
399
+ }
400
+ }
401
+ ```
402
+
403
+ ---
404
+
405
+ ## 流程常量
406
+
407
+ ```java
408
+ package org.dromara.workflow.common.constant;
409
+
410
+ public interface FlowConstant {
411
+ // 基础常量
412
+ String INITIATOR = "initiator"; // 流程发起人
413
+ String INITIATOR_DEPT_ID = "initiatorDeptId"; // 发起人部门ID
414
+ String BUSINESS_ID = "businessId"; // 业务ID
415
+ String BUSINESS_CODE = "businessCode"; // 业务编码
416
+ String SUBMIT = "submit"; // 申请人提交标识
417
+
418
+ // 任务操作类型
419
+ String DELEGATE_TASK = "delegateTask"; // 委托任务
420
+ String TRANSFER_TASK = "transferTask"; // 转办任务
421
+ String ADD_SIGNATURE = "addSignature"; // 加签
422
+ String REDUCTION_SIGNATURE = "reductionSignature"; // 减签
423
+
424
+ // 抄送与消息
425
+ String FLOW_COPY_LIST = "flowCopyList"; // 抄送人列表
426
+ String MESSAGE_TYPE = "messageType"; // 消息类型
427
+ String MESSAGE_NOTICE = "messageNotice"; // 消息内容
428
+
429
+ // 自动化配置
430
+ String AUTO_PASS = "autoPass"; // 自动通过标识
431
+
432
+ // 流程分类
433
+ String CATEGORY_ID_TO_NAME = "category_id_to_name";
434
+ String FLOW_CATEGORY_NAME = "flow_category_name#30d";
435
+ Long FLOW_CATEGORY_ID = 100L; // 默认租户OA申请分类id
436
+
437
+ // 任务状态字典
438
+ String WF_TASK_STATUS = "wf_task_status";
439
+
440
+ // 忽略标识(高级配置)
441
+ String VAR_IGNORE = "ignore"; // 忽略办理权限校验
442
+ String VAR_IGNORE_DEPUTE = "ignoreDepute"; // 忽略委派处理
443
+ String VAR_IGNORE_COOPERATE = "ignoreCooperate"; // 忽略会签票签处理
444
+ }
445
+ ```
446
+
447
+ ---
448
+
449
+ ## 消息通知
450
+
451
+ ### 通知类型
452
+
453
+ ```java
454
+ package org.dromara.workflow.common.enums;
455
+
456
+ public enum MessageTypeEnum {
457
+ SYSTEM_MESSAGE("1", "站内信"),
458
+ EMAIL_MESSAGE("2", "邮箱"),
459
+ SMS_MESSAGE("3", "短信");
460
+
461
+ private final String code;
462
+ private final String desc;
463
+ }
464
+ ```
465
+
466
+ ### 配置消息通知
467
+
468
+ 在流程变量中设置:
469
+
470
+ ```java
471
+ Map<String, Object> variable = new HashMap<>();
472
+ variable.put(FlowConstant.MESSAGE_TYPE, List.of("1", "2")); // 站内信 + 邮箱
473
+ variable.put(FlowConstant.MESSAGE_NOTICE, "您有新的审批任务");
474
+ ```
475
+
476
+ ---
477
+
478
+ ## API 接口
479
+
480
+ ### 任务管理 (/workflow/task)
481
+
482
+ | 接口 | 方法 | 说明 |
483
+ |------|------|------|
484
+ | `/startWorkFlow` | POST | 启动流程 |
485
+ | `/completeTask` | POST | 办理任务 |
486
+ | `/backProcess` | POST | 驳回审批 |
487
+ | `/pageByTaskWait` | GET | 当前用户待办任务 |
488
+ | `/pageByTaskFinish` | GET | 当前用户已办任务 |
489
+ | `/pageByAllTaskWait` | GET | 所有待办任务 |
490
+ | `/pageByAllTaskFinish` | GET | 所有已办任务 |
491
+ | `/pageByTaskCopy` | GET | 当前用户抄送任务 |
492
+ | `/{taskId}` | GET | 根据 taskId 查询任务详情 |
493
+ | `/getNextNodeList` | POST | 获取下一节点信息 |
494
+ | `/{taskId}/{nowNodeCode}` | GET | 获取可驳回的前置节点 |
495
+ | `/terminationTask` | POST | 终止流程 |
496
+ | `/{taskOperation}` | POST | 任务操作(委派/转办/加签/减签) |
497
+ | `/{taskId}` | GET | 获取当前任务所有办理人 |
498
+ | `/updateAssignee/{userId}` | PUT | 修改任务办理人 |
499
+ | `/urgeTask` | POST | 催办任务 |
500
+
501
+ ### 实例管理 (/workflow/instance)
502
+
503
+ | 接口 | 方法 | 说明 |
504
+ |------|------|------|
505
+ | `/pageByRunning` | GET | 运行中的流程实例 |
506
+ | `/pageByFinish` | GET | 已完成的流程实例 |
507
+ | `/pageByCurrent` | GET | 当前用户发起的流程 |
508
+ | `/{businessId}` | GET | 根据业务ID查询实例 |
509
+ | `/flowHisTaskList/{businessId}` | GET | 获取流程图和审批记录 |
510
+ | `/cancelProcessApply` | PUT | 撤销流程申请 |
511
+ | `/invalid` | POST | 作废流程 |
512
+ | `/deleteByBusinessIds/{businessIds}` | DELETE | 按业务ID删除实例 |
513
+ | `/deleteByInstanceIds/{instanceIds}` | DELETE | 按实例ID删除实例 |
514
+ | `/deleteHisByInstanceIds/{instanceIds}` | DELETE | 删除已完成的实例 |
515
+ | `/instanceVariable/{instanceId}` | GET | 获取流程变量 |
516
+ | `/updateVariable` | PUT | 更新流程变量 |
517
+ | `/active/{id}` | PUT | 激活/挂起流程实例 |
518
+
519
+ ### 流程定义 (/workflow/definition)
520
+
521
+ | 接口 | 方法 | 说明 |
522
+ |------|------|------|
523
+ | `/list` | GET | 查询已发布的流程定义 |
524
+ | `/unPublishList` | GET | 查询未发布的流程定义 |
525
+ | `/{id}` | GET | 获取流程定义详情 |
526
+ | `/` | POST | 新增流程定义 |
527
+ | `/` | PUT | 修改流程定义 |
528
+ | `/publish/{id}` | PUT | 发布流程定义 |
529
+ | `/unPublish/{id}` | PUT | 取消发布流程定义 |
530
+ | `/{ids}` | DELETE | 删除流程定义 |
531
+ | `/copy/{id}` | POST | 复制流程定义 |
532
+ | `/importDef` | POST | 导入流程定义 |
533
+ | `/exportDef/{id}` | POST | 导出流程定义 |
534
+ | `/xmlString/{id}` | GET | 获取定义 JSON 字符串 |
535
+ | `/active/{id}` | PUT | 激活/挂起流程定义 |
536
+
537
+ ### 流程分类 (/workflow/category)
538
+
539
+ | 接口 | 方法 | 说明 |
540
+ |------|------|------|
541
+ | `/list` | GET | 查询流程分类列表 |
542
+ | `/export` | POST | 导出流程分类 |
543
+ | `/{categoryId}` | GET | 获取分类详情 |
544
+ | `/` | POST | 新增分类 |
545
+ | `/` | PUT | 修改分类 |
546
+ | `/{categoryId}` | DELETE | 删除分类 |
547
+ | `/categoryTree` | GET | 获取分类树列表 |
548
+
549
+ ---
550
+
551
+ ## 文件位置
552
+
553
+ ```
554
+ ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/
555
+ ├── controller/
556
+ │ ├── FlwTaskController.java # 任务管理
557
+ │ ├── FlwInstanceController.java # 实例管理
558
+ │ ├── FlwDefinitionController.java # 流程定义
559
+ │ ├── FlwCategoryController.java # 流程分类
560
+ │ ├── FlwSpelController.java # SpEL表达式
561
+ │ └── TestLeaveController.java # 请假示例
562
+ ├── service/
563
+ │ ├── IFlwTaskService.java
564
+ │ ├── IFlwInstanceService.java
565
+ │ ├── IFlwDefinitionService.java
566
+ │ ├── IFlwCategoryService.java
567
+ │ ├── IFlwSpelService.java
568
+ │ ├── IFlwTaskAssigneeService.java
569
+ │ ├── IFlwNodeExtService.java
570
+ │ ├── IFlwCommonService.java
571
+ │ ├── ITestLeaveService.java
572
+ │ └── impl/
573
+ │ ├── FlwTaskServiceImpl.java
574
+ │ ├── FlwInstanceServiceImpl.java
575
+ │ ├── FlwDefinitionServiceImpl.java
576
+ │ ├── FlwCategoryServiceImpl.java
577
+ │ ├── FlwSpelServiceImpl.java
578
+ │ ├── FlwTaskAssigneeServiceImpl.java
579
+ │ ├── FlwNodeExtServiceImpl.java
580
+ │ ├── FlwCommonServiceImpl.java
581
+ │ ├── TestLeaveServiceImpl.java
582
+ │ └── WorkflowServiceImpl.java # 通用工作流服务
583
+ ├── mapper/ # Mapper 层(非 DAO)
584
+ │ ├── FlwCategoryMapper.java
585
+ │ ├── FlwSpelMapper.java
586
+ │ ├── FlwTaskMapper.java
587
+ │ ├── FlwInstanceMapper.java
588
+ │ ├── FlwInstanceBizExtMapper.java
589
+ │ └── TestLeaveMapper.java
590
+ ├── listener/
591
+ │ └── WorkflowGlobalListener.java # 全局监听器
592
+ ├── handler/
593
+ │ ├── FlowProcessEventHandler.java # 事件发布
594
+ │ └── WorkflowPermissionHandler.java # 权限处理
595
+ ├── rule/
596
+ │ └── SpelRuleComponent.java # SpEL 规则组件
597
+ ├── domain/
598
+ │ ├── FlowCategory.java
599
+ │ ├── FlowSpel.java
600
+ │ ├── FlowInstanceBizExt.java
601
+ │ ├── TestLeave.java
602
+ │ ├── bo/ # 业务对象
603
+ │ │ ├── StartProcessBo.java
604
+ │ │ ├── CompleteTaskBo.java
605
+ │ │ ├── BackProcessBo.java
606
+ │ │ ├── TaskOperationBo.java
607
+ │ │ └── ...
608
+ │ └── vo/ # 视图对象
609
+ │ ├── FlowTaskVo.java
610
+ │ ├── FlowHisTaskVo.java
611
+ │ ├── FlowInstanceVo.java
612
+ │ └── ...
613
+ ├── config/
614
+ │ └── WarmFlowConfig.java # WarmFlow 配置
615
+ └── common/
616
+ ├── ConditionalOnEnable.java # 条件注解
617
+ ├── constant/
618
+ │ └── FlowConstant.java # 常量
619
+ └── enums/
620
+ ├── TaskStatusEnum.java # 任务状态
621
+ ├── TaskAssigneeEnum.java # 办理人类型
622
+ ├── TaskAssigneeType.java # 办理人类型扩展
623
+ ├── MessageTypeEnum.java # 消息类型
624
+ ├── ButtonPermissionEnum.java # 按钮权限
625
+ ├── CopySettingEnum.java # 抄送设置
626
+ ├── NodeExtEnum.java # 节点扩展
627
+ └── VariablesEnum.java # 变量枚举
628
+ ```
629
+
630
+ ---
631
+
632
+ ## 检查清单
633
+
634
+ - [ ] 是否正确使用 `FlowEngine` 访问核心服务?
635
+ - [ ] 是否使用 `ProcessEvent`/`ProcessTaskEvent` 监听流程状态变更?
636
+ - [ ] 是否正确配置办理人(注意:用户ID无前缀,角色/部门/岗位有前缀)?
637
+ - [ ] 是否在业务模块中正确集成 `WorkflowService`?
638
+ - [ ] 是否处理了流程各状态(通过、驳回、撤销、终止)的业务逻辑?
639
+ - [ ] 是否配置了消息通知(SSE/邮件/短信)?
640
+ - [ ] API 方法名是否使用 pageBy* 命名规范(如 pageByTaskWait)?
641
+
642
+ ---
643
+
644
+ ## 常见问题
645
+
646
+ ### Q1: 用户ID和角色ID在办理人配置中的区别?
647
+
648
+ ```java
649
+ // ✅ 用户ID - 无前缀
650
+ "123" // 直接是用户ID
651
+
652
+ // ✅ 角色ID - 有 role: 前缀
653
+ "role:456" // 角色ID
654
+
655
+ // ✅ 部门ID - 有 dept: 前缀
656
+ "dept:789" // 部门ID
657
+
658
+ // ✅ 岗位ID - 有 post: 前缀
659
+ "post:101" // 岗位ID
660
+ ```
661
+
662
+ ### Q2: 如何判断是否为 SpEL 表达式?
663
+
664
+ ```java
665
+ // SpEL 表达式以 # 或 $ 开头
666
+ TaskAssigneeEnum.isSpelExpression("#{initiator}") // true
667
+ TaskAssigneeEnum.isSpelExpression("${deptLeader}") // true
668
+ TaskAssigneeEnum.isSpelExpression("user:123") // false
669
+ ```
670
+
671
+ ### Q3: 如何忽略办理权限校验?
672
+
673
+ ```java
674
+ Map<String, Object> variable = new HashMap<>();
675
+ variable.put(FlowConstant.VAR_IGNORE, true); // 忽略办理权限校验
676
+ ```