@gadmin2n/schematics 0.0.63 → 0.0.65

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 (223) hide show
  1. package/dist/lib/application/files/gadmin2-game-angle-demo/.dockerignore +2 -2
  2. package/dist/lib/application/files/gadmin2-game-angle-demo/Dockerfile +40 -26
  3. package/dist/lib/application/files/gadmin2-game-angle-demo/Jenkinsfile +30 -4
  4. package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/example.prisma +33 -0
  5. package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/system.prisma +163 -0
  6. package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/Event.ts +70 -0
  7. package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/Game.ts +6 -6
  8. package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/ITActivityDay.ts +70 -0
  9. package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/Log.ts +2 -2
  10. package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/Role.ts +2 -2
  11. package/dist/lib/application/files/gadmin2-game-angle-demo/server/.env +20 -9
  12. package/dist/lib/application/files/gadmin2-game-angle-demo/server/.env.local +1 -0
  13. package/dist/lib/application/files/gadmin2-game-angle-demo/server/.eslintrc.js +1 -0
  14. package/dist/lib/application/files/gadmin2-game-angle-demo/server/.prettierignore +1 -0
  15. package/dist/lib/application/files/gadmin2-game-angle-demo/server/README.md +2 -18
  16. package/dist/lib/application/files/gadmin2-game-angle-demo/server/gadmin-cli.json +1 -1
  17. package/dist/lib/application/files/gadmin2-game-angle-demo/server/migrate-between-pg-schemas.js +1232 -0
  18. package/dist/lib/application/files/gadmin2-game-angle-demo/server/package.json +65 -38
  19. package/dist/lib/application/files/gadmin2-game-angle-demo/server/prisma/.generator.prisma +4 -3
  20. package/dist/lib/application/files/gadmin2-game-angle-demo/server/prisma.config.ts +16 -0
  21. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/games.ts +1 -71
  22. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/index.ts +17 -21
  23. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/permissions.ts +278 -0
  24. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/seedDataMngtPages.ts +258 -0
  25. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/users.ts +7 -0
  26. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/alias.config.ts +7 -0
  27. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/app.controller.ts +151 -11
  28. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/app.module.ts +29 -13
  29. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/app.service.ts +151 -12
  30. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/lib/auth.guard.ts +87 -41
  31. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/lib/http-cache.interceptor.ts +21 -0
  32. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/lib/logger.ts +19 -0
  33. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/lib/safe-log.util.ts +176 -0
  34. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/lib/{yufuid.ts → taihu.ts} +49 -34
  35. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/lib/tracing.ts +174 -0
  36. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/lib/trim.pipe.ts +51 -0
  37. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/lib/utils.ts +91 -0
  38. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/lib/woaAuth.ts +25 -12
  39. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/main.ts +22 -12
  40. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/audit/audit.controller.spec.ts +20 -0
  41. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/audit/audit.controller.ts +190 -0
  42. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/audit/audit.module.ts +10 -0
  43. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/audit/audit.service.spec.ts +338 -0
  44. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/audit/audit.service.ts +83 -0
  45. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/game/game.controller.spec.ts +20 -0
  46. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/game/game.controller.ts +188 -0
  47. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/game/game.module.ts +10 -0
  48. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/game/game.service.spec.ts +18 -0
  49. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/game/game.service.ts +83 -0
  50. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/page/page.controller.spec.ts +20 -0
  51. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/page/page.controller.ts +250 -0
  52. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/page/page.module.ts +10 -0
  53. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/page/page.service.spec.ts +18 -0
  54. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/page/page.service.ts +1051 -0
  55. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/pageResource/pageResource.controller.spec.ts +20 -0
  56. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/pageResource/pageResource.controller.ts +196 -0
  57. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/pageResource/pageResource.module.ts +13 -0
  58. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/pageResource/pageResource.service.spec.ts +18 -0
  59. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/pageResource/pageResource.service.ts +219 -0
  60. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/resource/resource.controller.spec.ts +20 -0
  61. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/resource/resource.controller.ts +196 -0
  62. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/resource/resource.module.ts +10 -0
  63. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/resource/resource.service.spec.ts +18 -0
  64. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/resource/resource.service.ts +199 -0
  65. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/role/role.controller.spec.ts +20 -0
  66. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/role/role.controller.ts +210 -0
  67. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/role/role.module.ts +12 -0
  68. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/role/role.service.spec.ts +18 -0
  69. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/role/role.service.ts +849 -0
  70. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/role/roles-refresher.service.ts +133 -0
  71. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/rolePages/rolePages.controller.spec.ts +20 -0
  72. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/rolePages/rolePages.controller.ts +196 -0
  73. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/rolePages/rolePages.module.ts +10 -0
  74. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/rolePages/rolePages.service.spec.ts +18 -0
  75. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/rolePages/rolePages.service.ts +201 -0
  76. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/roleResource/roleResource.controller.spec.ts +20 -0
  77. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/roleResource/roleResource.controller.ts +196 -0
  78. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/roleResource/roleResource.module.ts +10 -0
  79. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/roleResource/roleResource.service.spec.ts +18 -0
  80. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/roleResource/roleResource.service.ts +216 -0
  81. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/user/user.controller.spec.ts +20 -0
  82. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/user/user.controller.ts +198 -0
  83. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/user/user.module.ts +10 -0
  84. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/user/user.service.spec.ts +18 -0
  85. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/user/user.service.ts +104 -0
  86. package/dist/lib/application/files/gadmin2-game-angle-demo/server/start-prod.sh +130 -0
  87. package/dist/lib/application/files/gadmin2-game-angle-demo/server/tsconfig.json +18 -3
  88. package/dist/lib/application/files/gadmin2-game-angle-demo/web/index.html +19 -0
  89. package/dist/lib/application/files/gadmin2-game-angle-demo/web/package.json +34 -42
  90. package/dist/lib/application/files/gadmin2-game-angle-demo/web/postcss.config.cjs +6 -0
  91. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/App.tsx +111 -185
  92. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/auditLogProvider.ts +5 -5
  93. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/contexts/color-mode/index.tsx +49 -51
  94. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/custom-avatar.tsx +38 -0
  95. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/index.ts +4 -0
  96. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/{header/index.tsx → header.tsx} +22 -31
  97. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/index.ts +3 -1
  98. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/layout.tsx +32 -0
  99. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/logo.tsx +19 -0
  100. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/sider.tsx +331 -166
  101. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/title.tsx +61 -0
  102. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/pagination-total.tsx +21 -0
  103. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/tags/index.ts +1 -0
  104. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/tags/role-tag.tsx +44 -0
  105. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/text.tsx +74 -0
  106. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/config/routeRegistry.tsx +258 -0
  107. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/constants/layout.ts +16 -0
  108. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/enums/audit-log.enum.ts +13 -0
  109. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/enums/index.ts +1 -0
  110. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/form.tsx +2 -0
  111. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/login.ts +22 -4
  112. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/useDynamicResources.tsx +211 -0
  113. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/useFetchData.ts +33 -0
  114. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/useRoles.ts +30 -0
  115. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/useUserPageAccess.ts +339 -0
  116. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/i18n.ts +8 -4
  117. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/index.tsx +3 -11
  118. package/dist/lib/application/files/gadmin2-game-angle-demo/web/{public → src}/locales/en/common.json +1 -1
  119. package/dist/lib/application/files/gadmin2-game-angle-demo/web/{public → src}/locales/zh_CN/common.json +1 -1
  120. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/audit/components/action-cell.css +3 -0
  121. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/audit/components/action-cell.tsx +134 -0
  122. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/audit/create.tsx +113 -0
  123. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/audit/edit.tsx +122 -0
  124. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/audit/index.ts +8 -0
  125. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/audit/index.tsx +6 -0
  126. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/audit/list.tsx +213 -0
  127. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/audit/show.tsx +61 -0
  128. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/Components/AssignRolesModal.tsx +168 -0
  129. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/Components/CreatePageModal.tsx +42 -0
  130. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/Components/EditPageModal.tsx +42 -0
  131. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/Components/PageDetailDrawer.tsx +101 -0
  132. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/Components/PageFormModal.tsx +731 -0
  133. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/create.tsx +113 -0
  134. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/edit.tsx +122 -0
  135. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/hooks/usePageManagement.ts +36 -0
  136. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/index.ts +8 -0
  137. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/index.tsx +6 -0
  138. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/list.tsx +1113 -0
  139. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/queries.ts +17 -0
  140. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/show.tsx +61 -0
  141. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/types.ts +44 -0
  142. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/pageResource/create.tsx +113 -0
  143. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/pageResource/edit.tsx +122 -0
  144. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/pageResource/index.tsx +6 -0
  145. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/pageResource/list.tsx +243 -0
  146. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/pageResource/show.tsx +61 -0
  147. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/permission-readme/index.tsx +1088 -0
  148. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/Components/CreateModal.tsx +25 -0
  149. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/Components/EditModal.tsx +28 -0
  150. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/Components/ResourceDetailDrawer.tsx +160 -0
  151. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/Components/modal.tsx +202 -0
  152. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/create.tsx +113 -0
  153. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/edit.tsx +122 -0
  154. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/index.ts +9 -0
  155. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/index.tsx +6 -0
  156. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/list.tsx +184 -0
  157. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/queries.ts +10 -0
  158. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/show.tsx +61 -0
  159. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/types.ts +9 -0
  160. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/Components/CreateModal.tsx +30 -0
  161. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/Components/EditModal.tsx +47 -0
  162. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/Components/RoleDetailDrawer.tsx +56 -0
  163. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/Components/modal.tsx +302 -0
  164. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/create.tsx +113 -0
  165. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/edit.tsx +122 -0
  166. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/hooks/useRolePage.ts +35 -0
  167. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/index.ts +8 -0
  168. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/index.tsx +6 -0
  169. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/list.tsx +382 -0
  170. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/queries.ts +8 -0
  171. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/show.tsx +61 -0
  172. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/types.ts +8 -0
  173. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/rolePages/create.tsx +113 -0
  174. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/rolePages/edit.tsx +122 -0
  175. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/rolePages/index.tsx +6 -0
  176. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/rolePages/list.tsx +243 -0
  177. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/rolePages/show.tsx +61 -0
  178. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/roleResource/create.tsx +113 -0
  179. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/roleResource/edit.tsx +122 -0
  180. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/roleResource/index.tsx +6 -0
  181. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/roleResource/list.tsx +243 -0
  182. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/roleResource/show.tsx +61 -0
  183. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/components/create-modal.tsx +17 -0
  184. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/components/edit-modal.tsx +19 -0
  185. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/components/form-modal.tsx +188 -0
  186. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/components/index.ts +5 -0
  187. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/components/role-tag.tsx +48 -0
  188. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/components/show-drawer.tsx +140 -0
  189. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/create.tsx +113 -0
  190. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/edit.tsx +122 -0
  191. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/index.ts +8 -0
  192. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/index.tsx +6 -0
  193. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/list.tsx +342 -0
  194. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/queries.ts +14 -0
  195. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/show.tsx +61 -0
  196. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/styles/antd.css +132 -0
  197. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/styles/fc.css +58 -0
  198. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/styles/index.css +128 -0
  199. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/styles/show-drawer.module.css +18 -0
  200. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/styles/show-page.module.css +21 -0
  201. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/types/audit-log.ts +1 -0
  202. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/types/index.ts +3 -0
  203. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/types/role.ts +7 -0
  204. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/types/user.ts +1 -0
  205. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/utilities/get-name-initials.ts +8 -0
  206. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/utilities/get-random-color.ts +27 -0
  207. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/utilities/index.ts +2 -0
  208. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/utilities/utils.tsx +5 -0
  209. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/vite-env.d.ts +1 -0
  210. package/dist/lib/application/files/gadmin2-game-angle-demo/web/tsconfig.json +3 -3
  211. package/dist/lib/application/files/gadmin2-game-angle-demo/web/vite.config.ts +31 -0
  212. package/package.json +1 -1
  213. package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/sample.prisma +0 -65
  214. package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/Source.ts +0 -76
  215. package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/Tasklog.ts +0 -76
  216. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/roles.ts +0 -4
  217. package/dist/lib/application/files/gadmin2-game-angle-demo/web/craco.config.js +0 -27
  218. package/dist/lib/application/files/gadmin2-game-angle-demo/web/public/index.html +0 -53
  219. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/styles.ts +0 -10
  220. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/react-app-env.d.ts +0 -1
  221. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/reportWebVitals.ts +0 -15
  222. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/styles/antd.less +0 -79
  223. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/VanillaJSONEditor/{index.js → index.jsx} +0 -0
@@ -0,0 +1,74 @@
1
+ import React from "react";
2
+
3
+ import { ConfigProvider, Typography } from "antd";
4
+
5
+ export type TextProps = {
6
+ size?:
7
+ | "xs"
8
+ | "sm"
9
+ | "md"
10
+ | "lg"
11
+ | "xl"
12
+ | "xxl"
13
+ | "xxxl"
14
+ | "huge"
15
+ | "xhuge"
16
+ | "xxhuge";
17
+ } & React.ComponentProps<typeof Typography.Text>;
18
+
19
+ const sizes = {
20
+ xs: {
21
+ fontSize: 12,
22
+ lineHeight: 20 / 12,
23
+ },
24
+ sm: {
25
+ fontSize: 14,
26
+ lineHeight: 22 / 14,
27
+ },
28
+ md: {
29
+ fontSize: 16,
30
+ lineHeight: 24 / 16,
31
+ },
32
+ lg: {
33
+ fontSize: 20,
34
+ lineHeight: 28 / 20,
35
+ },
36
+ xl: {
37
+ fontSize: 24,
38
+ lineHeight: 32 / 24,
39
+ },
40
+ xxl: {
41
+ fontSize: 30,
42
+ lineHeight: 38 / 30,
43
+ },
44
+ xxxl: {
45
+ fontSize: 38,
46
+ lineHeight: 46 / 38,
47
+ },
48
+ huge: {
49
+ fontSize: 46,
50
+ lineHeight: 54 / 46,
51
+ },
52
+ xhuge: {
53
+ fontSize: 56,
54
+ lineHeight: 64 / 56,
55
+ },
56
+ xxhuge: {
57
+ fontSize: 68,
58
+ lineHeight: 76 / 68,
59
+ },
60
+ };
61
+
62
+ export const Text: React.FC<TextProps> = ({ size = "sm", children, ...rest }) => {
63
+ return (
64
+ <ConfigProvider
65
+ theme={{
66
+ token: {
67
+ ...sizes[size],
68
+ },
69
+ }}
70
+ >
71
+ <Typography.Text {...rest}>{children}</Typography.Text>
72
+ </ConfigProvider>
73
+ );
74
+ };
@@ -0,0 +1,258 @@
1
+ import React, { lazy, Suspense } from "react";
2
+ import { Outlet, Route } from "react-router-dom";
3
+ import { Spin } from "antd";
4
+ import generatedResources from "generated/resources";
5
+
6
+ // ─── Types ───────────────────────────────────────────────────────────────────
7
+
8
+ type LazyComp = React.LazyExoticComponent<React.ComponentType<any>>;
9
+ // Allow both lazy and eagerly-imported components (generated/resources uses the latter)
10
+ type AnyComp = React.ComponentType<any>;
11
+
12
+ interface RouteEntry {
13
+ path: string;
14
+ component?: LazyComp | AnyComp;
15
+ wrapper?: LazyComp | AnyComp;
16
+ index?: boolean;
17
+ children?: Record<string, RouteEntry>;
18
+ }
19
+
20
+ // ─── Data-Mngt dynamic route helpers ─────────────────────────────────────────
21
+
22
+ /**
23
+ * Resource names already covered by the static registry entries below.
24
+ * These must NOT be auto-registered again under dataMngt.
25
+ */
26
+ const SYSTEM_RESOURCE_NAMES = new Set([
27
+ "user", "role", "page", "resource", "audit",
28
+ "game", "roleResource", "pageResource", "rolePages",
29
+ ]);
30
+
31
+ /** camelCase → PascalCase (reverses toCamelCase in seedDataMngtPages) */
32
+ function toPascalCase(str: string): string {
33
+ return str.charAt(0).toUpperCase() + str.slice(1);
34
+ }
35
+
36
+ /**
37
+ * PascalCase → kebab-case (same algorithm as seedDataMngtPages.ts so the
38
+ * generated route path always matches the page.path stored in the DB).
39
+ * "Event" → "event"
40
+ * "ITActivityDay" → "it-activity-day"
41
+ */
42
+ function toKebabCase(str: string): string {
43
+ return str
44
+ .replace(/([a-z0-9])([A-Z])/g, "$1-$2")
45
+ .replace(/([A-Z]+)([A-Z][a-z])/g, "$1-$2")
46
+ .toLowerCase();
47
+ }
48
+
49
+ /**
50
+ * Build RouteEntry children for the dataMngt segment by scanning
51
+ * generated/resources.tsx (produced by gadmin2 on every `generate:dev`).
52
+ *
53
+ * Each business-model resource becomes:
54
+ * <Route path="<slug>">
55
+ * <Route index element={<List />} />
56
+ * <Route path="show/:id" element={<Show />} />
57
+ * <Route path="edit/:id" element={<Edit />} />
58
+ * <Route path="create" element={<Create />} />
59
+ * </Route>
60
+ */
61
+ function buildDataMngtChildren(): Record<string, RouteEntry> {
62
+ const children: Record<string, RouteEntry> = {};
63
+
64
+ for (const res of generatedResources) {
65
+ if (SYSTEM_RESOURCE_NAMES.has(res.name)) continue;
66
+
67
+ // generated/resources stores components in meta.components
68
+ const { list: ListComp, show: ShowComp, edit: EditComp, create: CreateComp } =
69
+ (res.meta as any).components ?? {};
70
+
71
+ if (!ListComp) continue;
72
+
73
+ // Derive the URL slug from the PascalCase model name so it matches
74
+ // what seedDataMngtPages.ts writes into page.path.
75
+ const slug = toKebabCase(toPascalCase(res.name));
76
+
77
+ children[res.name] = {
78
+ path: slug,
79
+ // No component on the parent — React Router renders <Outlet /> so that
80
+ // the index / show / edit / create children can each occupy the full view.
81
+ children: {
82
+ list: { path: "", index: true, component: ListComp as AnyComp },
83
+ show: { path: "show/:id", component: ShowComp as AnyComp },
84
+ edit: { path: "edit/:id", component: EditComp as AnyComp },
85
+ create: { path: "create", component: CreateComp as AnyComp },
86
+ },
87
+ };
88
+ }
89
+
90
+ return children;
91
+ }
92
+
93
+ // ─── Suspense wrapper ────────────────────────────────────────────────────────
94
+
95
+ const S = ({ children }: { children: React.ReactNode }) => (
96
+ <Suspense fallback={<Spin size="large" />}>{children}</Suspense>
97
+ );
98
+
99
+ // ─── Route Registry ──────────────────────────────────────────────────────────
100
+
101
+ export const routeRegistry: Record<string, RouteEntry> = {
102
+ // ── Administration ─────────────────────────────────────────────────────────
103
+ admin: {
104
+ path: "/admin",
105
+ children: {
106
+ permission: {
107
+ path: "permission",
108
+ children: {
109
+ // 菜单指引 — sortOrder 1020, code: admin.permission.readme
110
+ permission_readme: {
111
+ path: "readme",
112
+ component: lazy(() =>
113
+ import("routes/permission-readme").then((m) => ({
114
+ default: m.PermissionReadmePage,
115
+ })),
116
+ ),
117
+ },
118
+ // 用户管理 — sortOrder 1030, code: admin.permission.user
119
+ user: {
120
+ path: "user",
121
+ component: lazy(() =>
122
+ import("routes/user").then((m) => ({ default: m.UserListPage })),
123
+ ),
124
+ },
125
+ // 角色管理 — sortOrder 1040, code: admin.permission.role
126
+ role: {
127
+ path: "role-list",
128
+ component: lazy(() =>
129
+ import("routes/role").then((m) => ({
130
+ default: m.RoleManagementListPage,
131
+ })),
132
+ ),
133
+ },
134
+ // 页面管理 — sortOrder 1050, code: admin.permission.page
135
+ page: {
136
+ path: "page-list",
137
+ component: lazy(() =>
138
+ import("routes/page/list").then((m) => ({
139
+ default: m.PageManagementListPage,
140
+ })),
141
+ ),
142
+ },
143
+ // 资源管理 — sortOrder 1060, code: admin.permission.resource
144
+ resource: {
145
+ path: "resource-list",
146
+ component: lazy(() =>
147
+ import("routes/resource").then((m) => ({
148
+ default: m.ResourceManagementListPage,
149
+ })),
150
+ ),
151
+ },
152
+ },
153
+ },
154
+ dataMngt: {
155
+ path: "data-mngt",
156
+ children: buildDataMngtChildren(),
157
+ },
158
+ game: {
159
+ path: "game-list",
160
+ children: {
161
+ list: { path: "", index: true, component: lazy(() => import("routes/game").then((m) => ({ default: m.GameList }))) },
162
+ show: { path: "show/:id", component: lazy(() => import("routes/game").then((m) => ({ default: m.GameShow }))) },
163
+ edit: { path: "edit/:id", component: lazy(() => import("routes/game").then((m) => ({ default: m.GameEdit }))) },
164
+ create: { path: "create", component: lazy(() => import("routes/game").then((m) => ({ default: m.GameCreate }))) },
165
+ },
166
+ },
167
+ // 操作日志 — sortOrder 1070, code: admin.audit
168
+ audits: {
169
+ path: "audit-log-list",
170
+ component: lazy(() =>
171
+ import("routes/audit").then((m) => ({ default: m.AuditLogPage })),
172
+ ),
173
+ },
174
+ },
175
+ },
176
+ };
177
+
178
+ // ─── Path Index (getRoutePath) ────────────────────────────────────────────────
179
+
180
+ function buildPathIndex(
181
+ entries: Record<string, RouteEntry>,
182
+ parentPath = "",
183
+ ): Record<string, string> {
184
+ const result: Record<string, string> = {};
185
+ for (const [key, entry] of Object.entries(entries)) {
186
+ const fullPath = entry.path.startsWith("/")
187
+ ? entry.path
188
+ : entry.path === ""
189
+ ? parentPath
190
+ : entry.path.startsWith("?")
191
+ ? parentPath + entry.path
192
+ : parentPath + "/" + entry.path;
193
+ result[key] = fullPath;
194
+ if (entry.children) {
195
+ Object.assign(result, buildPathIndex(entry.children, fullPath.split("?")[0]));
196
+ }
197
+ }
198
+ return result;
199
+ }
200
+
201
+ const pathIndex = buildPathIndex(routeRegistry);
202
+
203
+ export function getRoutePath(pageCode: string): string | null {
204
+ return pathIndex[pageCode] ?? null;
205
+ }
206
+
207
+ // ─── renderRoutes() ──────────────────────────────────────────────────────────
208
+
209
+ function renderEntry(key: string, entry: RouteEntry): React.ReactElement | null {
210
+ let element: React.ReactNode | undefined;
211
+ if (entry.component) {
212
+ const Comp = entry.component;
213
+ element = (
214
+ <S>
215
+ <Comp />
216
+ </S>
217
+ );
218
+ } else if (entry.wrapper) {
219
+ const W = entry.wrapper;
220
+ element = (
221
+ <S>
222
+ <W>
223
+ <Outlet />
224
+ </W>
225
+ </S>
226
+ );
227
+ }
228
+
229
+ if (entry.index) {
230
+ return <Route key={key} index element={element ?? null} />;
231
+ }
232
+
233
+ const routePath = entry.path.split("?")[0];
234
+
235
+ const childRoutes = Object.entries(entry.children ?? {})
236
+ .map(([k, e]) => renderEntry(k, e))
237
+ .filter(Boolean);
238
+
239
+ // Sidebar-only: no element, no renderable children
240
+ if (!element && childRoutes.length === 0) return null;
241
+
242
+ return childRoutes.length > 0 ? (
243
+ <Route key={key} path={routePath} element={element ?? <Outlet />}>
244
+ {childRoutes}
245
+ </Route>
246
+ ) : (
247
+ <Route key={key} path={routePath} element={element!} />
248
+ );
249
+ }
250
+
251
+ // Memoized at module level — registry is static, routes never change
252
+ const cachedRoutes: React.ReactElement[] = Object.entries(routeRegistry)
253
+ .map(([key, entry]) => renderEntry(key, entry))
254
+ .filter(Boolean) as React.ReactElement[];
255
+
256
+ export function renderRoutes(): React.ReactElement[] {
257
+ return cachedRoutes;
258
+ }
@@ -0,0 +1,16 @@
1
+ /** List / Create 页面顶层组件的内容区样式 */
2
+ export const LIST_CONTENT_PROPS = {
3
+ style: { marginTop: "1rem" },
4
+ } as const;
5
+
6
+ /** Show 页面顶层组件的内容区样式 */
7
+ export const SHOW_CONTENT_PROPS = {
8
+ style: {
9
+ backgroundColor: "#f5f5f5",
10
+ padding: 0,
11
+ marginTop: "1rem",
12
+ },
13
+ bodyStyle: {
14
+ padding: 0,
15
+ },
16
+ } as const;
@@ -0,0 +1,13 @@
1
+ export enum AuditLogActionEnum {
2
+ create = "create",
3
+ update = "update",
4
+ delete = "delete",
5
+ download = "download",
6
+ }
7
+
8
+ export const auditLogActionOptions = [
9
+ { label: "Create", value: AuditLogActionEnum.create },
10
+ { label: "Update", value: AuditLogActionEnum.update },
11
+ { label: "Delete", value: AuditLogActionEnum.delete },
12
+ { label: "Download", value: AuditLogActionEnum.download },
13
+ ];
@@ -0,0 +1 @@
1
+ export * from "./audit-log.enum";
@@ -127,6 +127,7 @@ function getElement(
127
127
  const hidden = !!fieldProps.hidden;
128
128
  const readonly = !!fieldProps.readonly;
129
129
  const showOptions = fieldProps.options;
130
+ const tooltip = field.uiType?.tooltip;
130
131
  const itemProps = {
131
132
  label: t(
132
133
  `resources.${resourceName}.fields.${fieldName}`,
@@ -153,6 +154,7 @@ function getElement(
153
154
  ...(field.rules || []),
154
155
  ],
155
156
  hidden,
157
+ ...(tooltip && { tooltip }),
156
158
  };
157
159
  if (field.component) {
158
160
  element = <Form.Item {...itemProps}>{field.component}</Form.Item>;
@@ -34,7 +34,7 @@ axiosInstance.interceptors.response.use(
34
34
  console.log("login expired");
35
35
  login();
36
36
  // 返回pending状态的promise,以免后续代码出错
37
- return new Promise(() => {});
37
+ return new Promise(() => { });
38
38
  }
39
39
  let message = error.response?.data?.message;
40
40
  if (message) {
@@ -42,9 +42,8 @@ axiosInstance.interceptors.response.use(
42
42
  message = message.join(" AND ");
43
43
  } else if (typeof message === "string") {
44
44
  if (message.includes("Unique constraint")) {
45
- message = `Unique constraint ${
46
- message.split("Unique constraint")[1]
47
- }`;
45
+ message = `Unique constraint ${message.split("Unique constraint")[1]
46
+ }`;
48
47
  } else {
49
48
  let strings = message.split(")");
50
49
  message = strings[strings.length - 1];
@@ -122,3 +121,22 @@ export function requestHeaders() {
122
121
  };
123
122
  return headers;
124
123
  }
124
+
125
+ type LowercaseMethod = 'get' | 'delete' | 'head' | 'options' | 'post' | 'put' | 'patch';
126
+
127
+ export async function customRequest<T>(
128
+ urlPath: string,
129
+ method: string,
130
+ params?: Record<string, any>
131
+ ) {
132
+ const url = `${apiUrl}/${urlPath}`;
133
+ const headers = {
134
+ "Content-Type": "application/json",
135
+ ...requestHeaders(),
136
+ };
137
+ const httpMethod = method.toLowerCase() as LowercaseMethod;
138
+ const axiosOptions = { headers };
139
+ const res = await axiosInstance[httpMethod](url, params, axiosOptions);
140
+ const { data } = res;
141
+ return data as T;
142
+ }
@@ -0,0 +1,211 @@
1
+ import { useMemo, useRef } from "react";
2
+ import type { IResourceItem, ResourceProps } from "@refinedev/core";
3
+ import {
4
+ DashboardOutlined,
5
+ SettingOutlined,
6
+ } from "@ant-design/icons";
7
+ import { getRoutePath } from "config/routeRegistry";
8
+ import { useUserPageAccess } from "./useUserPageAccess";
9
+ import generatedResources from "generated/resources";
10
+
11
+ /**
12
+ * Dynamic Resources Hook for erp-backend/web
13
+ *
14
+ * Features:
15
+ * 1. Get user accessible page resources from backend (via useUserPageAccess)
16
+ * 2. Convert backend data to Refine's IResourceItem[] format
17
+ * 3. Auto-generate show/edit/create paths for all pages
18
+ *
19
+ * Data Flow:
20
+ * useUserPageAccess → Accessible Pages → Resources → Sider Menu
21
+ *
22
+ * Performance:
23
+ * - Uses module-level cache - computed ONCE per page load
24
+ * - Returns same reference on every call after initial computation
25
+ * - Does NOT rebuild on route navigation or component re-renders
26
+ * - Permission changes require page refresh (handled by user)
27
+ */
28
+
29
+ // Module-level cache - computed once per page load
30
+ let cachedResources: IResourceItem[] | null = null;
31
+ let isComputing = false;
32
+
33
+ // 将 snake_case 转换为 camelCase
34
+ function snakeToCamel(str: string): string {
35
+ return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
36
+ }
37
+
38
+ // Icon 映射:page.code 到 React Icon 组件
39
+ export const iconMapping: Record<string, React.ReactNode> = {
40
+ dashboard: <DashboardOutlined />,
41
+ administration: <SettingOutlined />,
42
+ };
43
+
44
+ // Pages whose children are tabs (not separate menu items)
45
+ const PAGES_WITH_TABS: string[] = [];
46
+
47
+ export const useDynamicResources = (): IResourceItem[] => {
48
+ // Use shared page access data (single call, reused below)
49
+ const { accessiblePageIds, pagesData, pageMap, isLoading, roleNames } = useUserPageAccess();
50
+
51
+ // If we already have cached resources, return immediately
52
+ if (cachedResources !== null) {
53
+ return cachedResources;
54
+ }
55
+
56
+ // Return empty array while loading (will retry on next render)
57
+ if (isLoading || !pagesData || isComputing) {
58
+ return [];
59
+ }
60
+
61
+ // Mark as computing to prevent concurrent computation
62
+ isComputing = true;
63
+
64
+ if (import.meta.env.DEV) {
65
+ console.log('[useDynamicResources] 🔨 Computing resources (first time)');
66
+ }
67
+
68
+ // Filter accessible pages and build hierarchical sorted list
69
+ const accessiblePages = pagesData.filter(page => accessiblePageIds.has(page.id));
70
+
71
+ // Group pages by parentId
72
+ const pagesByParent = new Map<number | null, typeof accessiblePages>();
73
+ accessiblePages.forEach(page => {
74
+ const parentId = page.parentId ?? null;
75
+ if (!pagesByParent.has(parentId)) {
76
+ pagesByParent.set(parentId, []);
77
+ }
78
+ pagesByParent.get(parentId)!.push(page);
79
+ });
80
+
81
+ // Sort each group by sortOrder
82
+ pagesByParent.forEach(pages => {
83
+ pages.sort((a, b) => (a.sortOrder ?? Infinity) - (b.sortOrder ?? Infinity));
84
+ });
85
+
86
+ // Build sorted list using depth-first traversal
87
+ const sortedAccessiblePages: typeof accessiblePages = [];
88
+ const visited = new Set<number>();
89
+
90
+ const addPageWithChildren = (parentId: number | null) => {
91
+ const children = pagesByParent.get(parentId) || [];
92
+ children.forEach(page => {
93
+ if (visited.has(page.id)) return;
94
+ visited.add(page.id);
95
+ sortedAccessiblePages.push(page);
96
+ addPageWithChildren(page.id);
97
+ });
98
+ };
99
+
100
+ // Start from root level (parentId = null)
101
+ addPageWithChildren(null);
102
+
103
+ // Add any orphaned pages
104
+ accessiblePages.forEach(page => {
105
+ if (!visited.has(page.id)) {
106
+ sortedAccessiblePages.push(page);
107
+ }
108
+ });
109
+
110
+ // 检测哪些父页面有"index 子页面"(子页面路径与父页面相同,即 path: "" 的 index 路由)
111
+ // 这类父页面应作为纯分组节点(不注册 list 路径),否则 Refine 会优先选中父节点
112
+ // 导致 "全部" 等 index 子菜单项无法高亮
113
+ const parentIdsWithIndexChild = new Set<number>();
114
+ accessiblePages.forEach(childPage => {
115
+ if (!childPage.parentId) return;
116
+ const childPath = getRoutePath(childPage.code);
117
+ if (!childPath) return;
118
+ const parentPage = pageMap.get(childPage.parentId);
119
+ if (!parentPage) return;
120
+ const parentPath = getRoutePath(parentPage.code);
121
+ if (childPath === parentPath) {
122
+ parentIdsWithIndexChild.add(childPage.parentId);
123
+ }
124
+ });
125
+
126
+ // Build resources
127
+ const resultResources: IResourceItem[] = [];
128
+ const addedResourceNames = new Set<string>();
129
+
130
+ sortedAccessiblePages.forEach(page => {
131
+ if (!page) return;
132
+
133
+ // Skip virtual pages
134
+ if (page.isVirtual) return;
135
+
136
+ // Skip children of pages that use tabs
137
+ if (page.parentId) {
138
+ const parentPage = pageMap.get(page.parentId);
139
+ if (parentPage && PAGES_WITH_TABS.includes(parentPage.code)) {
140
+ return;
141
+ }
142
+ }
143
+
144
+ const permissionRes = snakeToCamel(page.code);
145
+
146
+ // Avoid duplicates
147
+ if (addedResourceNames.has(permissionRes)) return;
148
+
149
+ let parentPermissionRes: string | undefined;
150
+ if (page.parentId) {
151
+ const parentPage = pageMap.get(page.parentId);
152
+ if (parentPage) {
153
+ parentPermissionRes = snakeToCamel(parentPage.code);
154
+ }
155
+ }
156
+
157
+ // 优先从 routeRegistry 获取路径
158
+ // fallback 到 page.path(用于 gadmin2 页面)
159
+ const registryPath = getRoutePath(page.code);
160
+ const dbPath = page.path
161
+ ? page.path.startsWith("/") ? page.path : `/${page.path}`
162
+ : undefined;
163
+ const normalizedPath = registryPath ?? dbPath;
164
+
165
+ // 如果该页面是"有 index 子页面的父节点",则不注册 list/show/edit/create
166
+ // 使其成为纯分组节点(SubMenu),子页面(如"全部")的路径才负责 URL 匹配与菜单高亮
167
+ const isGroupParent = parentIdsWithIndexChild.has(page.id);
168
+
169
+ // Build resource item with auto-generated CRUD paths
170
+ // Store both zhLabel/enLabel in meta; Sider resolves at render time
171
+ const resource: IResourceItem = {
172
+ name: permissionRes,
173
+ ...(!isGroupParent && normalizedPath && {
174
+ list: normalizedPath,
175
+ show: `${normalizedPath}/show/:id`,
176
+ edit: `${normalizedPath}/edit/:id`,
177
+ create: `${normalizedPath}/create`,
178
+ }),
179
+ meta: {
180
+ label: page.enName || page.code,
181
+ zhLabel: page.zhName || page.code,
182
+ enLabel: page.enName || page.code,
183
+ icon: iconMapping[page.code] || "",
184
+ parent: parentPermissionRes,
185
+ route: normalizedPath,
186
+ pageCode: page.code,
187
+ parentPageCode: page.parentId
188
+ ? pageMap.get(page.parentId)?.code
189
+ : undefined,
190
+ },
191
+ };
192
+
193
+ resultResources.push(resource);
194
+ addedResourceNames.add(permissionRes);
195
+ });
196
+
197
+ // Build final resources array with auto-crud if needed
198
+ const dynamicResources = resultResources;
199
+ const allResources = dynamicResources;
200
+
201
+ // Cache the result - will be used for all subsequent calls
202
+ cachedResources = allResources;
203
+ isComputing = false;
204
+
205
+ if (import.meta.env.DEV) {
206
+ console.log('[useDynamicResources] ✅ Resources cached. Count:', cachedResources.length);
207
+ console.log('[useDynamicResources] 📌 This reference will be reused for all future calls');
208
+ }
209
+
210
+ return cachedResources;
211
+ };
@@ -0,0 +1,33 @@
1
+ import { useEffect, useState } from "react";
2
+
3
+ import { customRequest } from "helpers/login";
4
+
5
+ export const useFetchData = (
6
+ url: string,
7
+ type: "post" | "get",
8
+ defaultQuery?: any,
9
+ disableReq?: any,
10
+ errorCallBack?: () => void
11
+ ) => {
12
+ const [data, setData] = useState<any>();
13
+ const [reqQuery, setReqQuery] = useState<any>(defaultQuery);
14
+ const [loading, setLoading] = useState<boolean>(false);
15
+ const fetchData = async (query?: any) => {
16
+ if (!url) return;
17
+ setLoading(true);
18
+ try {
19
+ const res = await customRequest(url, type, query);
20
+ setData(res);
21
+ setReqQuery(query);
22
+ } catch (error) {
23
+ console.error(error);
24
+ errorCallBack && errorCallBack();
25
+ }
26
+ setLoading(false);
27
+ };
28
+
29
+ useEffect(() => {
30
+ !disableReq && url && fetchData(defaultQuery);
31
+ }, []);
32
+ return { data, loading, fetchData, reqQuery };
33
+ };