@qlover/create-app 0.7.15 → 0.8.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 (340) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/configs/_common/.gitignore.template +6 -0
  3. package/dist/configs/_common/.prettierignore +17 -5
  4. package/dist/configs/_common/.vscode/settings.json +6 -1
  5. package/dist/index.cjs +1 -1
  6. package/dist/index.js +1 -1
  7. package/dist/templates/next-app/.env.template +1 -1
  8. package/dist/templates/next-app/README.en.md +0 -1
  9. package/dist/templates/next-app/README.md +0 -1
  10. package/dist/templates/next-app/config/Identifier/api.ts +5 -5
  11. package/dist/templates/next-app/config/Identifier/common/admint.table.ts +69 -0
  12. package/dist/templates/next-app/config/Identifier/common/common.ts +76 -0
  13. package/dist/templates/next-app/config/Identifier/common/index.ts +3 -0
  14. package/dist/templates/next-app/config/Identifier/{validator.ts → common/validators.ts} +5 -5
  15. package/dist/templates/next-app/config/Identifier/index.ts +2 -12
  16. package/dist/templates/next-app/config/Identifier/pages/index.ts +6 -0
  17. package/dist/templates/next-app/config/Identifier/pages/page.admin.home.ts +27 -0
  18. package/dist/templates/next-app/config/Identifier/pages/page.admin.locales.ts +266 -0
  19. package/dist/templates/next-app/config/Identifier/pages/page.admin.user.ts +293 -0
  20. package/dist/templates/{react-app/config/Identifier → next-app/config/Identifier/pages}/page.home.ts +15 -22
  21. package/dist/templates/next-app/config/Identifier/{page.login.ts → pages/page.login.ts} +28 -34
  22. package/dist/templates/next-app/config/Identifier/{page.register.ts → pages/page.register.ts} +30 -29
  23. package/dist/templates/next-app/config/adminNavs.ts +19 -0
  24. package/dist/templates/next-app/config/common.ts +22 -13
  25. package/dist/templates/next-app/config/i18n/HomeI18n.ts +5 -5
  26. package/dist/templates/next-app/config/i18n/admin18n.ts +61 -19
  27. package/dist/templates/next-app/config/i18n/i18nConfig.ts +2 -0
  28. package/dist/templates/next-app/config/i18n/i18nKeyScheam.ts +36 -0
  29. package/dist/templates/next-app/config/i18n/loginI18n.ts +22 -22
  30. package/dist/templates/next-app/config/i18n/register18n.ts +23 -24
  31. package/dist/templates/next-app/docs/en/index.md +0 -1
  32. package/dist/templates/next-app/docs/en/project-structure.md +0 -1
  33. package/dist/templates/next-app/docs/zh/index.md +0 -1
  34. package/dist/templates/next-app/docs/zh/project-structure.md +0 -1
  35. package/dist/templates/next-app/make/generateLocales.ts +19 -12
  36. package/dist/templates/next-app/migrations/schema/LocalesSchema.ts +15 -0
  37. package/dist/templates/next-app/migrations/sql/1694244000000.sql +11 -0
  38. package/dist/templates/next-app/package.json +7 -3
  39. package/dist/templates/next-app/public/locales/en.json +172 -207
  40. package/dist/templates/next-app/public/locales/zh.json +172 -207
  41. package/dist/templates/next-app/src/app/[locale]/admin/locales/page.tsx +153 -0
  42. package/dist/templates/next-app/src/app/[locale]/admin/users/page.tsx +48 -50
  43. package/dist/templates/next-app/src/app/[locale]/login/LoginForm.tsx +2 -2
  44. package/dist/templates/next-app/src/app/api/admin/locales/create/route.ts +34 -0
  45. package/dist/templates/next-app/src/app/api/admin/locales/import/route.ts +40 -0
  46. package/dist/templates/next-app/src/app/api/admin/locales/route.ts +42 -0
  47. package/dist/templates/next-app/src/app/api/admin/locales/update/route.ts +32 -0
  48. package/dist/templates/next-app/src/app/api/locales/json/route.ts +44 -0
  49. package/dist/templates/next-app/src/base/cases/AdminPageManager.ts +1 -13
  50. package/dist/templates/next-app/src/base/cases/Datetime.ts +18 -0
  51. package/dist/templates/next-app/src/base/cases/DialogErrorPlugin.ts +12 -6
  52. package/dist/templates/next-app/src/base/cases/ResourceState.ts +17 -0
  53. package/dist/templates/next-app/src/base/cases/TranslateI18nInterface.ts +25 -0
  54. package/dist/templates/next-app/src/base/cases/ZodColumnBuilder.ts +200 -0
  55. package/dist/templates/next-app/src/base/port/ZodBuilderInterface.ts +8 -0
  56. package/dist/templates/next-app/src/base/services/AdminLocalesService.ts +20 -0
  57. package/dist/templates/next-app/src/base/services/AdminPageEvent.ts +26 -0
  58. package/dist/templates/next-app/src/base/services/AdminPageScheduler.ts +42 -0
  59. package/dist/templates/next-app/src/base/services/ResourceService.ts +122 -0
  60. package/dist/templates/next-app/src/base/services/adminApi/AdminLocalesApi.ts +104 -0
  61. package/dist/templates/next-app/src/base/services/adminApi/AdminUserApi.ts +38 -5
  62. package/dist/templates/next-app/src/base/services/appApi/AppApiPlugin.ts +1 -1
  63. package/dist/templates/next-app/src/i18n/request.ts +30 -1
  64. package/dist/templates/next-app/src/server/PageParams.ts +2 -10
  65. package/dist/templates/next-app/src/server/port/DBBridgeInterface.ts +5 -0
  66. package/dist/templates/next-app/src/server/port/DBTableInterface.ts +2 -0
  67. package/dist/templates/next-app/src/server/port/LocalesRepositoryInterface.ts +43 -0
  68. package/dist/templates/next-app/src/server/repositorys/LocalesRepository.ts +197 -0
  69. package/dist/templates/next-app/src/server/services/ApiLocaleService.ts +122 -0
  70. package/dist/templates/next-app/src/server/sqlBridges/SupabaseBridge.ts +60 -11
  71. package/dist/templates/next-app/src/server/validators/ExtendedExecutorError.ts +6 -0
  72. package/dist/templates/next-app/src/server/validators/LocalesValidator.ts +131 -0
  73. package/dist/templates/next-app/src/server/validators/LoginValidator.ts +2 -5
  74. package/dist/templates/next-app/src/server/validators/PaginationValidator.ts +32 -16
  75. package/dist/templates/next-app/src/styles/css/antd-themes/pagination/_default.css +2 -1
  76. package/dist/templates/next-app/src/styles/css/antd-themes/pagination/dark.css +28 -29
  77. package/dist/templates/next-app/src/styles/css/antd-themes/pagination/pink.css +2 -1
  78. package/dist/templates/next-app/src/uikit/components/AdminLayout.tsx +17 -3
  79. package/dist/templates/next-app/src/uikit/components/BaseHeader.tsx +5 -4
  80. package/dist/templates/next-app/src/uikit/components/BaseLayout.tsx +5 -4
  81. package/dist/templates/next-app/src/uikit/components/BootstrapsProvider.tsx +3 -2
  82. package/dist/templates/next-app/src/uikit/components/ComboProvider.tsx +1 -1
  83. package/dist/templates/next-app/src/uikit/components/EditableCell.tsx +118 -0
  84. package/dist/templates/next-app/src/uikit/components/LogoutButton.tsx +5 -6
  85. package/dist/templates/next-app/src/uikit/components/ThemeSwitcher.tsx +1 -1
  86. package/dist/templates/next-app/src/uikit/components/With.tsx +2 -2
  87. package/dist/templates/next-app/src/uikit/components/localesImportButton/LocalesImportButton.tsx +62 -0
  88. package/dist/templates/next-app/src/uikit/components/localesImportButton/LocalesImportEvent.ts +28 -0
  89. package/dist/templates/next-app/src/uikit/components/localesImportButton/import.module.css +6 -0
  90. package/dist/templates/next-app/src/uikit/hook/useI18nInterface.ts +8 -14
  91. package/dist/templates/next-app/src/uikit/hook/useWarnTranslations.ts +25 -0
  92. package/dist/templates/react-app/.prettierignore +17 -0
  93. package/dist/templates/react-app/README.en.md +71 -54
  94. package/dist/templates/react-app/README.md +35 -18
  95. package/dist/templates/react-app/__tests__/__mocks__/BootstrapTest.ts +14 -0
  96. package/dist/templates/react-app/__tests__/__mocks__/MockAppConfit.ts +1 -1
  97. package/dist/templates/react-app/__tests__/__mocks__/MockDialogHandler.ts +2 -2
  98. package/dist/templates/react-app/__tests__/__mocks__/MockLogger.ts +1 -1
  99. package/dist/templates/react-app/__tests__/__mocks__/components/TestApp.tsx +45 -0
  100. package/dist/templates/react-app/__tests__/__mocks__/components/TestBootstrapsProvider.tsx +34 -0
  101. package/dist/templates/react-app/__tests__/__mocks__/components/TestRouter.tsx +46 -0
  102. package/dist/templates/react-app/__tests__/__mocks__/components/index.ts +12 -0
  103. package/dist/templates/react-app/__tests__/__mocks__/createMockGlobals.ts +1 -2
  104. package/dist/templates/react-app/__tests__/__mocks__/testIOC/TestIOC.ts +51 -0
  105. package/dist/templates/react-app/__tests__/__mocks__/testIOC/TestIOCRegister.ts +69 -0
  106. package/dist/templates/react-app/__tests__/setup/index.ts +1 -51
  107. package/dist/templates/react-app/__tests__/setup/setupGlobal.ts +51 -0
  108. package/dist/templates/react-app/__tests__/src/App.structure.test.tsx +115 -0
  109. package/dist/templates/react-app/__tests__/src/base/cases/AppConfig.test.ts +2 -2
  110. package/dist/templates/react-app/__tests__/src/base/cases/AppError.test.ts +1 -1
  111. package/dist/templates/react-app/__tests__/src/base/cases/DialogHandler.test.ts +3 -5
  112. package/dist/templates/react-app/__tests__/src/base/cases/I18nKeyErrorPlugin.test.ts +13 -2
  113. package/dist/templates/react-app/__tests__/src/base/cases/InversifyContainer.test.ts +1 -1
  114. package/dist/templates/react-app/__tests__/src/base/cases/PublicAssetsPath.test.ts +1 -1
  115. package/dist/templates/react-app/__tests__/src/base/cases/RequestLogger.test.ts +5 -5
  116. package/dist/templates/react-app/__tests__/src/base/cases/RequestStatusCatcher.test.ts +1 -2
  117. package/dist/templates/react-app/__tests__/src/base/cases/RouterLoader.test.ts +25 -15
  118. package/dist/templates/react-app/__tests__/src/base/services/I18nService.test.ts +29 -15
  119. package/dist/templates/react-app/__tests__/src/core/IOC.test.ts +19 -9
  120. package/dist/templates/react-app/__tests__/src/core/bootstraps/BootstrapClient.test.ts +153 -0
  121. package/dist/templates/react-app/__tests__/src/core/bootstraps/BootstrapsApp.test.ts +9 -7
  122. package/dist/templates/react-app/__tests__/src/main.integration.test.tsx +4 -5
  123. package/dist/templates/react-app/__tests__/src/main.test.tsx +4 -4
  124. package/dist/templates/react-app/__tests__/src/uikit/components/BaseHeader.test.tsx +68 -59
  125. package/dist/templates/react-app/config/IOCIdentifier.ts +8 -8
  126. package/dist/templates/react-app/config/Identifier/{common.error.ts → common/common.error.ts} +5 -5
  127. package/dist/templates/react-app/config/Identifier/{common.ts → common/common.ts} +9 -9
  128. package/dist/templates/react-app/config/Identifier/common/index.ts +2 -0
  129. package/dist/templates/react-app/config/Identifier/index.ts +1 -9
  130. package/dist/templates/react-app/config/Identifier/pages/index.ts +8 -0
  131. package/dist/templates/react-app/config/Identifier/{page.about.ts → pages/page.about.ts} +34 -26
  132. package/dist/templates/react-app/config/Identifier/{page.executor.ts → pages/page.executor.ts} +47 -39
  133. package/dist/templates/{next-app/config/Identifier → react-app/config/Identifier/pages}/page.home.ts +24 -23
  134. package/dist/templates/react-app/config/Identifier/pages/page.identifiter.ts +102 -0
  135. package/dist/templates/react-app/config/Identifier/{page.jsonStorage.ts → pages/page.jsonStorage.ts} +18 -11
  136. package/dist/templates/react-app/config/Identifier/{page.login.ts → pages/page.login.ts} +37 -27
  137. package/dist/templates/react-app/config/Identifier/{page.register.ts → pages/page.register.ts} +37 -25
  138. package/dist/templates/react-app/config/Identifier/{page.request.ts → pages/page.request.ts} +34 -44
  139. package/dist/templates/react-app/config/app.router.ts +66 -69
  140. package/dist/templates/react-app/config/i18n/PageI18nInterface.ts +51 -0
  141. package/dist/templates/react-app/config/i18n/aboutI18n.ts +42 -0
  142. package/dist/templates/react-app/config/i18n/executorI18n.ts +51 -0
  143. package/dist/templates/react-app/config/i18n/homeI18n.ts +24 -0
  144. package/dist/templates/react-app/config/i18n/i18nConfig.ts +30 -0
  145. package/dist/templates/react-app/config/i18n/identifiter18n.ts +30 -0
  146. package/dist/templates/react-app/config/i18n/jsonStorage18n.ts +27 -0
  147. package/dist/templates/react-app/config/i18n/login18n.ts +42 -0
  148. package/dist/templates/react-app/config/i18n/notFoundI18n.ts +34 -0
  149. package/dist/templates/react-app/config/i18n/register18n.ts +40 -0
  150. package/dist/templates/react-app/config/i18n/request18n.ts +41 -0
  151. package/dist/templates/react-app/config/theme.ts +14 -4
  152. package/dist/templates/react-app/docs/en/bootstrap.md +1670 -341
  153. package/dist/templates/react-app/docs/en/development-guide.md +1021 -345
  154. package/dist/templates/react-app/docs/en/env.md +1132 -278
  155. package/dist/templates/react-app/docs/en/i18n.md +858 -147
  156. package/dist/templates/react-app/docs/en/index.md +733 -104
  157. package/dist/templates/react-app/docs/en/ioc.md +1228 -287
  158. package/dist/templates/react-app/docs/en/playwright/e2e-tests.md +321 -0
  159. package/dist/templates/react-app/docs/en/playwright/index.md +19 -0
  160. package/dist/templates/react-app/docs/en/playwright/installation-summary.md +332 -0
  161. package/dist/templates/react-app/docs/en/playwright/overview.md +222 -0
  162. package/dist/templates/react-app/docs/en/playwright/quickstart.md +325 -0
  163. package/dist/templates/react-app/docs/en/playwright/reorganization-notes.md +340 -0
  164. package/dist/templates/react-app/docs/en/playwright/setup-complete.md +290 -0
  165. package/dist/templates/react-app/docs/en/playwright/testing-guide.md +565 -0
  166. package/dist/templates/react-app/docs/en/store.md +1194 -184
  167. package/dist/templates/react-app/docs/en/why-no-globals.md +797 -0
  168. package/dist/templates/react-app/docs/zh/bootstrap.md +1670 -341
  169. package/dist/templates/react-app/docs/zh/development-guide.md +1021 -345
  170. package/dist/templates/react-app/docs/zh/env.md +1132 -275
  171. package/dist/templates/react-app/docs/zh/i18n.md +858 -147
  172. package/dist/templates/react-app/docs/zh/index.md +717 -104
  173. package/dist/templates/react-app/docs/zh/ioc.md +1229 -287
  174. package/dist/templates/react-app/docs/zh/playwright/e2e-tests.md +321 -0
  175. package/dist/templates/react-app/docs/zh/playwright/index.md +19 -0
  176. package/dist/templates/react-app/docs/zh/playwright/installation-summary.md +332 -0
  177. package/dist/templates/react-app/docs/zh/playwright/overview.md +222 -0
  178. package/dist/templates/react-app/docs/zh/playwright/quickstart.md +325 -0
  179. package/dist/templates/react-app/docs/zh/playwright/reorganization-notes.md +340 -0
  180. package/dist/templates/react-app/docs/zh/playwright/setup-complete.md +290 -0
  181. package/dist/templates/react-app/docs/zh/playwright/testing-guide.md +565 -0
  182. package/dist/templates/react-app/docs/zh/store.md +1192 -184
  183. package/dist/templates/react-app/docs/zh/why-no-globals.md +797 -0
  184. package/dist/templates/react-app/e2e/App.spec.ts +319 -0
  185. package/dist/templates/react-app/e2e/fixtures/base.fixture.ts +40 -0
  186. package/dist/templates/react-app/e2e/main.spec.ts +20 -0
  187. package/dist/templates/react-app/e2e/utils/test-helpers.ts +19 -0
  188. package/dist/templates/react-app/eslint.config.mjs +247 -0
  189. package/dist/templates/react-app/makes/eslint-utils.mjs +195 -0
  190. package/dist/templates/react-app/makes/generateTs2LocalesOptions.ts +26 -0
  191. package/dist/templates/react-app/package.json +31 -3
  192. package/dist/templates/react-app/playwright.config.ts +79 -0
  193. package/dist/templates/react-app/public/locales/en/common.json +190 -179
  194. package/dist/templates/react-app/public/locales/zh/common.json +190 -179
  195. package/dist/templates/react-app/src/App.tsx +15 -42
  196. package/dist/templates/react-app/src/base/apis/AiApi.ts +5 -5
  197. package/dist/templates/react-app/src/base/apis/feApi/FeApi.ts +1 -1
  198. package/dist/templates/react-app/src/base/apis/feApi/FeApiAdapter.ts +1 -1
  199. package/dist/templates/react-app/src/base/apis/feApi/FeApiBootstarp.ts +8 -8
  200. package/dist/templates/react-app/src/base/apis/feApi/FeApiType.ts +1 -1
  201. package/dist/templates/react-app/src/base/apis/userApi/UserApi.ts +6 -6
  202. package/dist/templates/react-app/src/base/apis/userApi/UserApiAdapter.ts +1 -1
  203. package/dist/templates/react-app/src/base/apis/userApi/UserApiBootstarp.ts +12 -14
  204. package/dist/templates/react-app/src/base/apis/userApi/UserApiType.ts +1 -1
  205. package/dist/templates/react-app/src/base/cases/DialogHandler.ts +5 -2
  206. package/dist/templates/react-app/src/base/cases/I18nKeyErrorPlugin.ts +3 -3
  207. package/dist/templates/react-app/src/base/cases/InversifyContainer.ts +3 -3
  208. package/dist/templates/react-app/src/base/cases/RequestLanguages.ts +2 -2
  209. package/dist/templates/react-app/src/base/cases/RequestLogger.ts +4 -4
  210. package/dist/templates/react-app/src/base/cases/RequestStatusCatcher.ts +1 -1
  211. package/dist/templates/react-app/src/base/cases/ResourceState.ts +23 -0
  212. package/dist/templates/react-app/src/base/cases/RouterLoader.ts +4 -4
  213. package/dist/templates/react-app/src/base/cases/TranslateI18nInterface.ts +26 -0
  214. package/dist/templates/react-app/src/base/port/ExecutorPageBridgeInterface.ts +2 -3
  215. package/dist/templates/react-app/src/base/port/I18nServiceInterface.ts +1 -1
  216. package/dist/templates/react-app/src/base/port/IOCInterface.ts +36 -0
  217. package/dist/templates/react-app/src/base/port/JSONStoragePageBridgeInterface.ts +2 -1
  218. package/dist/templates/react-app/src/base/port/ProcesserExecutorInterface.ts +1 -1
  219. package/dist/templates/react-app/src/base/port/RequestPageBridgeInterface.ts +2 -2
  220. package/dist/templates/react-app/src/base/port/RouteServiceInterface.ts +9 -5
  221. package/dist/templates/react-app/src/base/port/UserServiceInterface.ts +1 -1
  222. package/dist/templates/react-app/src/base/services/I18nService.ts +29 -29
  223. package/dist/templates/react-app/src/base/services/IdentifierService.ts +143 -0
  224. package/dist/templates/react-app/src/base/services/ProcesserExecutor.ts +3 -3
  225. package/dist/templates/react-app/src/base/services/RouteService.ts +27 -8
  226. package/dist/templates/react-app/src/base/services/UserService.ts +8 -8
  227. package/dist/templates/react-app/src/base/types/Page.ts +14 -2
  228. package/dist/templates/react-app/src/base/types/global.d.ts +1 -1
  229. package/dist/templates/react-app/src/core/IOC.ts +5 -46
  230. package/dist/templates/react-app/src/core/bootstraps/{BootstrapApp.ts → BootstrapClient.ts} +44 -17
  231. package/dist/templates/react-app/src/core/bootstraps/BootstrapsRegistry.ts +14 -7
  232. package/dist/templates/react-app/src/core/bootstraps/IocIdentifierTest.ts +1 -1
  233. package/dist/templates/react-app/src/core/bootstraps/PrintBootstrap.ts +1 -1
  234. package/dist/templates/react-app/src/core/clientIoc/ClientIOC.ts +40 -0
  235. package/dist/templates/react-app/src/core/{IocRegisterImpl.ts → clientIoc/ClientIOCRegister.ts} +35 -24
  236. package/dist/templates/react-app/src/core/globals.ts +9 -9
  237. package/dist/templates/react-app/src/main.tsx +4 -4
  238. package/dist/templates/react-app/src/pages/404.tsx +6 -3
  239. package/dist/templates/react-app/src/pages/500.tsx +5 -2
  240. package/dist/templates/react-app/src/pages/NoRouteFound.tsx +5 -0
  241. package/dist/templates/react-app/src/pages/auth/Layout.tsx +9 -6
  242. package/dist/templates/react-app/src/pages/auth/LoginPage.tsx +46 -56
  243. package/dist/templates/react-app/src/pages/auth/RegisterPage.tsx +46 -58
  244. package/dist/templates/react-app/src/pages/base/AboutPage.tsx +35 -40
  245. package/dist/templates/react-app/src/pages/base/ExecutorPage.tsx +51 -51
  246. package/dist/templates/react-app/src/pages/base/HomePage.tsx +14 -15
  247. package/dist/templates/react-app/src/pages/base/IdentifierPage.tsx +70 -11
  248. package/dist/templates/react-app/src/pages/base/JSONStoragePage.tsx +24 -25
  249. package/dist/templates/react-app/src/pages/base/Layout.tsx +2 -2
  250. package/dist/templates/react-app/src/pages/base/RedirectPathname.tsx +3 -2
  251. package/dist/templates/react-app/src/pages/base/RequestPage.tsx +41 -59
  252. package/dist/templates/react-app/src/styles/css/antd-themes/{_default.css → _common/_default.css} +85 -0
  253. package/dist/templates/react-app/src/styles/css/antd-themes/{dark.css → _common/dark.css} +99 -0
  254. package/dist/templates/react-app/src/styles/css/antd-themes/_common/index.css +3 -0
  255. package/dist/templates/react-app/src/styles/css/antd-themes/{pink.css → _common/pink.css} +86 -0
  256. package/dist/templates/react-app/src/styles/css/antd-themes/index.css +4 -3
  257. package/dist/templates/react-app/src/styles/css/antd-themes/menu/_default.css +108 -0
  258. package/dist/templates/react-app/src/styles/css/antd-themes/menu/dark.css +67 -0
  259. package/dist/templates/react-app/src/styles/css/antd-themes/menu/index.css +3 -0
  260. package/dist/templates/react-app/src/styles/css/antd-themes/menu/pink.css +67 -0
  261. package/dist/templates/react-app/src/styles/css/antd-themes/pagination/_default.css +34 -0
  262. package/dist/templates/react-app/src/styles/css/antd-themes/pagination/dark.css +31 -0
  263. package/dist/templates/react-app/src/styles/css/antd-themes/pagination/index.css +3 -0
  264. package/dist/templates/react-app/src/styles/css/antd-themes/pagination/pink.css +36 -0
  265. package/dist/templates/react-app/src/styles/css/antd-themes/table/_default.css +44 -0
  266. package/dist/templates/react-app/src/styles/css/antd-themes/table/dark.css +43 -0
  267. package/dist/templates/react-app/src/styles/css/antd-themes/table/index.css +3 -0
  268. package/dist/templates/react-app/src/styles/css/antd-themes/table/pink.css +43 -0
  269. package/dist/templates/react-app/src/styles/css/page.css +4 -3
  270. package/dist/templates/react-app/src/styles/css/themes/_default.css +1 -0
  271. package/dist/templates/react-app/src/styles/css/themes/dark.css +1 -0
  272. package/dist/templates/react-app/src/styles/css/themes/pink.css +1 -0
  273. package/dist/templates/react-app/src/styles/css/zIndex.css +1 -1
  274. package/dist/templates/react-app/src/uikit/bridges/ExecutorPageBridge.ts +3 -3
  275. package/dist/templates/react-app/src/uikit/bridges/JSONStoragePageBridge.ts +2 -2
  276. package/dist/templates/react-app/src/uikit/bridges/NavigateBridge.ts +1 -1
  277. package/dist/templates/react-app/src/uikit/bridges/RequestPageBridge.ts +3 -3
  278. package/dist/templates/react-app/src/uikit/components/AppRouterProvider.tsx +35 -0
  279. package/dist/templates/react-app/src/uikit/components/BaseHeader.tsx +15 -11
  280. package/dist/templates/react-app/src/uikit/components/BaseRouteProvider.tsx +14 -11
  281. package/dist/templates/react-app/src/uikit/components/BaseRouteSeo.tsx +18 -0
  282. package/dist/templates/react-app/src/uikit/components/BootstrapsProvider.tsx +13 -0
  283. package/dist/templates/react-app/src/uikit/components/ClientSeo.tsx +62 -0
  284. package/dist/templates/react-app/src/uikit/components/ComboProvider.tsx +38 -0
  285. package/dist/templates/react-app/src/uikit/components/LanguageSwitcher.tsx +48 -27
  286. package/dist/templates/react-app/src/uikit/components/Loading.tsx +4 -2
  287. package/dist/templates/react-app/src/uikit/components/LocaleLink.tsx +4 -5
  288. package/dist/templates/react-app/src/uikit/components/LogoutButton.tsx +34 -11
  289. package/dist/templates/react-app/src/uikit/components/ProcessExecutorProvider.tsx +9 -5
  290. package/dist/templates/react-app/src/uikit/components/RouterRenderComponent.tsx +6 -3
  291. package/dist/templates/react-app/src/uikit/components/ThemeSwitcher.tsx +97 -40
  292. package/dist/templates/react-app/src/uikit/components/UserAuthProvider.tsx +5 -5
  293. package/dist/templates/react-app/src/uikit/components/With.tsx +17 -0
  294. package/dist/templates/react-app/src/uikit/contexts/BaseRouteContext.ts +17 -11
  295. package/dist/templates/react-app/src/uikit/contexts/IOCContext.ts +13 -0
  296. package/dist/templates/react-app/src/uikit/hooks/useAppTranslation.ts +26 -0
  297. package/dist/templates/react-app/src/uikit/hooks/useI18nGuard.ts +8 -11
  298. package/dist/templates/react-app/src/uikit/hooks/useI18nInterface.ts +25 -0
  299. package/dist/templates/react-app/src/uikit/hooks/useIOC.ts +35 -0
  300. package/dist/templates/react-app/src/uikit/hooks/useNavigateBridge.ts +3 -3
  301. package/dist/templates/react-app/src/uikit/hooks/useStrictEffect.ts +0 -1
  302. package/dist/templates/react-app/tsconfig.e2e.json +21 -0
  303. package/dist/templates/react-app/tsconfig.json +8 -1
  304. package/dist/templates/react-app/tsconfig.node.json +1 -1
  305. package/dist/templates/react-app/tsconfig.test.json +3 -1
  306. package/dist/templates/react-app/vite.config.ts +50 -34
  307. package/package.json +2 -1
  308. package/dist/configs/react-app/eslint.config.js +0 -94
  309. package/dist/templates/next-app/config/Identifier/common.error.ts +0 -41
  310. package/dist/templates/next-app/config/Identifier/common.ts +0 -69
  311. package/dist/templates/next-app/config/Identifier/page.about.ts +0 -181
  312. package/dist/templates/next-app/config/Identifier/page.admin.ts +0 -48
  313. package/dist/templates/next-app/config/Identifier/page.executor.ts +0 -272
  314. package/dist/templates/next-app/config/Identifier/page.identifiter.ts +0 -39
  315. package/dist/templates/next-app/config/Identifier/page.jsonStorage.ts +0 -72
  316. package/dist/templates/next-app/config/Identifier/page.request.ts +0 -182
  317. package/dist/templates/next-app/src/base/cases/ChatAction.ts +0 -21
  318. package/dist/templates/next-app/src/base/cases/FocusBarAction.ts +0 -36
  319. package/dist/templates/next-app/src/base/cases/RequestState.ts +0 -20
  320. package/dist/templates/next-app/src/base/port/AdminPageInterface.ts +0 -85
  321. package/dist/templates/next-app/src/base/port/AsyncStateInterface.ts +0 -7
  322. package/dist/templates/next-app/src/base/services/AdminUserService.ts +0 -45
  323. package/dist/templates/next-app/src/uikit/components/ChatRoot.tsx +0 -17
  324. package/dist/templates/next-app/src/uikit/components/chat/ChatActionInterface.ts +0 -30
  325. package/dist/templates/next-app/src/uikit/components/chat/ChatFocusBar.tsx +0 -65
  326. package/dist/templates/next-app/src/uikit/components/chat/ChatMessages.tsx +0 -59
  327. package/dist/templates/next-app/src/uikit/components/chat/ChatWrap.tsx +0 -28
  328. package/dist/templates/next-app/src/uikit/components/chat/FocusBarActionInterface.ts +0 -19
  329. package/dist/templates/next-app/src/uikit/hook/useMountedClient.ts +0 -17
  330. package/dist/templates/next-app/src/uikit/hook/useStore.ts +0 -15
  331. package/dist/templates/react-app/__tests__/__mocks__/I18nService.ts +0 -13
  332. package/dist/templates/react-app/__tests__/src/App.test.tsx +0 -139
  333. package/dist/templates/react-app/config/Identifier/page.identifiter.ts +0 -39
  334. package/dist/templates/react-app/config/i18n.ts +0 -15
  335. package/dist/templates/react-app/docs/en/project-structure.md +0 -434
  336. package/dist/templates/react-app/docs/zh/project-structure.md +0 -434
  337. package/dist/templates/react-app/src/base/cases/RequestState.ts +0 -20
  338. package/dist/templates/react-app/src/base/port/AsyncStateInterface.ts +0 -7
  339. package/dist/templates/react-app/src/uikit/hooks/useDocumentTitle.ts +0 -15
  340. package/dist/templates/react-app/src/uikit/hooks/useStore.ts +0 -15
@@ -1,274 +1,431 @@
1
- # Development Guidelines
1
+ # Development Guide
2
2
 
3
- ## Table of Contents
3
+ > **📖 This document provides a complete page development workflow and practical guide to help you quickly get started with project development.**
4
4
 
5
- 1. [Project Structure Standards](#project-structure-standards)
6
- 2. [Code Style Standards](#code-style-standards)
7
- 3. [Component Development Standards](#component-development-standards)
8
- 4. [State Management Standards](#state-management-standards)
9
- 5. [Router Development Standards](#router-development-standards)
10
- 6. [Internationalization Development Standards](#internationalization-development-standards)
11
- 7. [Theme Style Standards](#theme-style-standards)
12
- 8. [Testing Standards](#testing-standards)
13
- 9. [Documentation Standards](#documentation-standards)
5
+ ## 📋 Table of Contents
14
6
 
15
- ## Project Structure Standards
7
+ - [What's Needed to Develop a Page](#-whats-needed-to-develop-a-page)
8
+ - [Complete Development Workflow](#-complete-development-workflow)
9
+ - [Practical Example: User List Page](#-practical-example-user-list-page)
10
+ - [Common Scenarios](#-common-scenarios)
11
+ - [Code Standards](#-code-standards)
12
+ - [Development Tools](#-development-tools)
16
13
 
17
- > 💡 Only basic standards are listed here. For complete project structure documentation, please refer to [Project Structure Documentation](./project-structure.md)
14
+ ---
18
15
 
19
- ### 1. Directory Structure
16
+ ## 🎯 What's Needed to Develop a Page
17
+
18
+ ### Core Checklist
19
+
20
+ A complete page typically requires the following components:
20
21
 
21
22
  ```
22
- src/
23
- ├── base/ # Base functionality implementation
24
- │ ├── cases/ # Business scenario implementations
25
- │ ├── services/ # Core service implementations
26
- │ └── types/ # Type definitions
27
- ├── core/ # Core functionality
28
- │ ├── bootstraps/ # Startup related
29
- │ ├── registers/ # Registries
30
- │ └── IOC.ts # IOC container
31
- ├── pages/ # Page components
32
- │ ├── auth/ # Authentication related pages
33
- │ └── base/ # Base pages
34
- ├── styles/ # Style files
35
- │ └── css/
36
- │ ├── themes/ # Theme related
37
- │ └── antd-themes/ # Ant Design themes
38
- ├── uikit/ # UI component library
39
- │ ├── components/ # Common components
40
- │ ├── contexts/ # React Contexts
41
- │ ├── hooks/ # Custom Hooks
42
- │ └── providers/ # Provider components
43
- └── App.tsx # Application entry
23
+ ✅ 1. Interface Definition (Port) - base/port/XxxServiceInterface.ts
24
+ 2. Service Implementation - base/services/XxxService.ts
25
+ 3. API Adapter (Optional) - base/apis/xxxApi/XxxApi.ts
26
+ 4. Route Configuration - config/app.router.ts
27
+ 5. i18n Text Definition - config/Identifier/pages/page.xxx.ts
28
+ 6. Page Component - pages/xxx/XxxPage.tsx
29
+ 7. IOC Registration (New Services) - core/clientIoc/ClientIOCRegister.ts
30
+ 8. Test Files - __tests__/src/pages/xxx/XxxPage.test.tsx
44
31
  ```
45
32
 
46
- ### 2. Naming Conventions
33
+ ### Dependency Diagram
47
34
 
48
- - **File Naming**:
49
- - Component files: `PascalCase.tsx` (e.g., `UserProfile.tsx`)
50
- - Utility files: `camelCase.ts` (e.g., `formatDate.ts`)
51
- - Type files: `PascalCase.types.ts` (e.g., `User.types.ts`)
52
- - Style files: `camelCase.css` (e.g., `buttonStyles.css`)
35
+ ```
36
+ ┌─────────────────────────────────────────┐
37
+ Route Configuration (app.router.ts)
38
+ Define page paths and metadata │
39
+ └──────────────┬──────────────────────────┘
40
+
41
+ ┌─────────────────────────────────────────┐
42
+ │ Page Component (XxxPage.tsx) │
43
+ │ - Use useIOC to get services │
44
+ │ - Use useStore to subscribe to state │
45
+ │ - Use useAppTranslation for i18n │
46
+ │ - Handle UI rendering & interactions │
47
+ └──────────────┬──────────────────────────┘
48
+
49
+ ┌─────────────────────────────────────────┐
50
+ │ Service Layer (XxxService.ts) │
51
+ │ - Implement business logic │
52
+ │ - Extend StoreInterface │
53
+ │ - Dependency injection │
54
+ └──────────────┬──────────────────────────┘
55
+
56
+ ┌─────────────────────────────────────────┐
57
+ │ Interface Definition (XxxServiceInterface.ts) │
58
+ │ - Define service contract │
59
+ │ - Easy to test and mock │
60
+ └─────────────────────────────────────────┘
61
+
62
+ ┌─────────────────────────────────────────┐
63
+ │ API Adapter (XxxApi.ts) │
64
+ │ - Encapsulate HTTP requests │
65
+ │ - Transform data formats │
66
+ └─────────────────────────────────────────┘
67
+
68
+ ┌─────────────────────────────────────────┐
69
+ │ i18n Text (page.xxx.ts) │
70
+ │ - Define all text keys for page │
71
+ │ - Auto-generate translation files │
72
+ └─────────────────────────────────────────┘
73
+ ```
53
74
 
54
- - **Directory Naming**:
55
- - All lowercase, using hyphens (e.g., `user-profile/`)
56
- - Feature modules use singular form (e.g., `auth/`, not `auths/`)
75
+ ---
57
76
 
58
- ## Code Style Standards
77
+ ## 🚀 Complete Development Workflow
59
78
 
60
- > 💡 Only basic standards are listed here. For more TypeScript and React development standards, please refer to [TypeScript Development Standards](./typescript-guide.md)
79
+ ### Workflow Diagram
61
80
 
62
- ### 1. TypeScript Standards
81
+ ```
82
+ 📝 1. Requirements Analysis
83
+ ├── Determine page features
84
+ ├── Determine data sources (API)
85
+ └── Determine interaction logic
86
+
87
+ 🎨 2. Define i18n Keys
88
+ ├── Page titles, button text, etc.
89
+ └── Error messages, success messages, etc.
90
+
91
+ 🔌 3. Define Interfaces (Port)
92
+ ├── Service interfaces
93
+ └── Data types
94
+
95
+ ⚙️ 4. Implement Service
96
+ ├── Extend StoreInterface
97
+ ├── Implement business logic
98
+ └── Dependency injection
99
+
100
+ 🌐 5. Implement API Adapter (if needed)
101
+ ├── Encapsulate HTTP requests
102
+ └── Data transformation
103
+
104
+ 🗺️ 6. Configure Routes
105
+ ├── Add route configuration
106
+ └── Set metadata
107
+
108
+ 🎭 7. Implement Page Component
109
+ ├── Use useIOC to get services
110
+ ├── Use useStore to subscribe to state
111
+ └── Implement UI rendering
112
+
113
+ 🔗 8. Register to IOC (if new service)
114
+ └── Register in ClientIOCRegister
115
+
116
+ 🧪 9. Write Tests
117
+ ├── Service tests (logic)
118
+ ├── UI tests (rendering)
119
+ └── Integration tests (workflow)
120
+
121
+ ✅ 10. Self-test and Submit
122
+ ├── Feature testing
123
+ ├── Code review
124
+ └── Submit PR
125
+ ```
63
126
 
64
- ```typescript
65
- // Use interface for object types
66
- interface UserProfile {
67
- id: string;
68
- name: string;
69
- age?: number; // Optional properties use ?
70
- }
127
+ ---
71
128
 
72
- // Use type for union types or utility types
73
- type Theme = 'light' | 'dark' | 'pink';
74
- type Nullable<T> = T | null;
129
+ ## 📚 Practical Example: User List Page
75
130
 
76
- // Use enum for constant enumerations
77
- enum UserRole {
78
- ADMIN = 'ADMIN',
79
- USER = 'USER',
80
- GUEST = 'GUEST'
81
- }
131
+ Let's assume we want to develop a user list page with the following features:
82
132
 
83
- // Function type declarations
84
- function processUser(user: UserProfile): void {
85
- // Implementation
86
- }
133
+ - Display user list
134
+ - Search users
135
+ - Pagination
136
+ - View user details
87
137
 
88
- // Use meaningful names for generics
89
- interface Repository<TEntity> {
90
- find(id: string): Promise<TEntity>;
91
- }
92
- ```
138
+ ### 1. Requirements Analysis
93
139
 
94
- ### 2. React Standards
140
+ **Feature List:**
95
141
 
96
- ```tsx
97
- // Function components use FC type
98
- interface Props {
99
- name: string;
100
- age: number;
101
- }
142
+ - 📄 Display user list (avatar, name, email, role)
143
+ - 🔍 Search users (by name)
144
+ - 📃 Pagination (10 items per page)
145
+ - 👁️ View details (click to navigate to detail page)
146
+ - 🔄 Refresh list
102
147
 
103
- const UserCard: FC<Props> = ({ name, age }) => {
104
- return (
105
- <div>
106
- <h3>{name}</h3>
107
- <p>{age}</p>
108
- </div>
109
- );
110
- };
148
+ **Data Source:**
111
149
 
112
- // Hooks standards
113
- const useUser = (userId: string) => {
114
- const [user, setUser] = useState<UserProfile | null>(null);
115
- const [loading, setLoading] = useState(false);
150
+ - API: `GET /api/users?page=1&pageSize=10&keyword=xxx`
116
151
 
117
- useEffect(() => {
118
- // Implementation
119
- }, [userId]);
152
+ ### 2. Define i18n Keys
153
+
154
+ ```typescript
155
+ // config/Identifier/pages/page.users.ts
156
+
157
+ /**
158
+ * @description User list page title
159
+ * @localZh 用户列表
160
+ * @localEn User List
161
+ */
162
+ export const PAGE_USERS_TITLE = 'page.users.title';
163
+
164
+ /**
165
+ * @description Search user placeholder
166
+ * @localZh 搜索用户姓名
167
+ * @localEn Search user name
168
+ */
169
+ export const PAGE_USERS_SEARCH_PLACEHOLDER = 'page.users.search.placeholder';
170
+
171
+ /**
172
+ * @description View user detail button
173
+ * @localZh 查看详情
174
+ * @localEn View Detail
175
+ */
176
+ export const PAGE_USERS_VIEW_DETAIL = 'page.users.viewDetail';
177
+
178
+ /**
179
+ * @description Refresh button
180
+ * @localZh 刷新
181
+ * @localEn Refresh
182
+ */
183
+ export const PAGE_USERS_REFRESH = 'page.users.refresh';
120
184
 
121
- return { user, loading };
122
- };
185
+ /**
186
+ * @description Loading message
187
+ * @localZh 加载中...
188
+ * @localEn Loading...
189
+ */
190
+ export const PAGE_USERS_LOADING = 'page.users.loading';
191
+
192
+ /**
193
+ * @description Empty message
194
+ * @localZh 暂无用户数据
195
+ * @localEn No users found
196
+ */
197
+ export const PAGE_USERS_EMPTY = 'page.users.empty';
123
198
  ```
124
199
 
125
- ## Component Development Standards
200
+ ### 3. Define Interfaces and Types
126
201
 
127
- > 💡 Only basic standards are listed here. For complete component development guide, please refer to [Component Development Guide](./component-guide.md)
202
+ ```typescript
203
+ // base/port/UserServiceInterface.ts
128
204
 
129
- ### 1. Component Categories
205
+ import { StoreInterface } from '@qlover/corekit-bridge';
130
206
 
131
- - **Page Components**: Located in `pages/` directory
132
- - **Business Components**: Located in corresponding business module directories
133
- - **Common Components**: Located in `uikit/components/` directory
134
- - **Layout Components**: Located in `uikit/layouts/` directory
207
+ /**
208
+ * User information
209
+ */
210
+ export interface UserInfo {
211
+ id: string;
212
+ name: string;
213
+ email: string;
214
+ avatar: string;
215
+ role: 'admin' | 'user';
216
+ }
135
217
 
136
- ### 2. Component Implementation
218
+ /**
219
+ * User list query parameters
220
+ */
221
+ export interface UserListParams {
222
+ page: number;
223
+ pageSize: number;
224
+ keyword?: string;
225
+ }
137
226
 
138
- ```tsx
139
- // 1. Import order
140
- import { FC, useEffect, useState } from 'react'; // React related
141
- import { useTranslation } from 'react-i18next'; // Third-party libraries
142
- import { UserService } from '@/services/user'; // Internal project imports
143
- import { Button } from './Button'; // Relative path imports
227
+ /**
228
+ * User list response
229
+ */
230
+ export interface UserListResponse {
231
+ list: UserInfo[];
232
+ total: number;
233
+ page: number;
234
+ pageSize: number;
235
+ }
144
236
 
145
- // 2. Type definitions
146
- interface Props {
147
- userId: string;
148
- onUpdate?: (user: User) => void;
237
+ /**
238
+ * User service state
239
+ */
240
+ export interface UserServiceState extends StoreStateInterface {
241
+ users: UserInfo[];
242
+ total: number;
243
+ page: number;
244
+ pageSize: number;
245
+ loading: boolean;
246
+ error: Error | null;
149
247
  }
150
248
 
151
- // 3. Component implementation
152
- export const UserProfile: FC<Props> = ({ userId, onUpdate }) => {
153
- // 3.1 Hooks declarations
154
- const { t } = useTranslation();
155
- const [user, setUser] = useState<User | null>(null);
249
+ /**
250
+ * User service interface
251
+ */
252
+ export abstract class UserServiceInterface extends StoreInterface<UserServiceState> {
253
+ /**
254
+ * Fetch user list
255
+ */
256
+ abstract fetchUsers(params: UserListParams): Promise<void>;
156
257
 
157
- // 3.2 Side effects
158
- useEffect(() => {
159
- // Implementation
160
- }, [userId]);
258
+ /**
259
+ * Search users
260
+ */
261
+ abstract searchUsers(keyword: string): Promise<void>;
161
262
 
162
- // 3.3 Event handlers
163
- const handleUpdate = () => {
164
- // Implementation
165
- };
263
+ /**
264
+ * Refresh list
265
+ */
266
+ abstract refreshUsers(): Promise<void>;
166
267
 
167
- // 3.4 Render methods
168
- const renderHeader = () => {
169
- return <h2>{user?.name}</h2>;
268
+ /**
269
+ * Selectors
270
+ */
271
+ abstract selector: {
272
+ users: (state: UserServiceState) => UserInfo[];
273
+ loading: (state: UserServiceState) => boolean;
274
+ total: (state: UserServiceState) => number;
170
275
  };
171
-
172
- // 3.5 Return JSX
173
- return (
174
- <div>
175
- {renderHeader()}
176
- <Button onClick={handleUpdate}>{t('common.update')}</Button>
177
- </div>
178
- );
179
- };
276
+ }
180
277
  ```
181
278
 
182
- ## State Management Standards
279
+ ### 4. Implement API Adapter
183
280
 
184
- > 💡 Only basic standards are listed here. For complete state management guide, please refer to [Store Development Guide](./store.md)
281
+ ```typescript
282
+ // base/apis/userApi/UserApi.ts
185
283
 
186
- ### 1. Store Implementation
284
+ import { injectable, inject } from 'inversify';
285
+ import { HttpClient } from '@/base/cases/HttpClient';
286
+ import type {
287
+ UserListParams,
288
+ UserListResponse
289
+ } from '@/base/port/UserServiceInterface';
187
290
 
188
- ```typescript
189
- // 1. State interface definition
190
- interface UserState extends StoreStateInterface {
191
- currentUser: User | null;
192
- loading: boolean;
193
- error: string | null;
291
+ @injectable()
292
+ export class UserApi {
293
+ constructor(@inject(HttpClient) private http: HttpClient) {}
294
+
295
+ /**
296
+ * Get user list
297
+ */
298
+ async getUserList(params: UserListParams): Promise<UserListResponse> {
299
+ const response = await this.http.get('/api/users', { params });
300
+
301
+ // Transform backend data format
302
+ return {
303
+ list: response.data.items.map((item: any) => ({
304
+ id: item.user_id,
305
+ name: item.user_name,
306
+ email: item.user_email,
307
+ avatar: item.avatar_url,
308
+ role: item.user_role
309
+ })),
310
+ total: response.data.total_count,
311
+ page: response.data.current_page,
312
+ pageSize: response.data.page_size
313
+ };
314
+ }
194
315
  }
316
+ ```
317
+
318
+ ### 5. Implement Service
319
+
320
+ ```typescript
321
+ // base/services/UserService.ts
322
+
323
+ import { injectable, inject } from 'inversify';
324
+ import {
325
+ UserServiceInterface,
326
+ UserServiceState
327
+ } from '@/base/port/UserServiceInterface';
328
+ import { UserApi } from '@/base/apis/userApi/UserApi';
329
+ import type { UserListParams } from '@/base/port/UserServiceInterface';
195
330
 
196
- // 2. Store implementation
197
331
  @injectable()
198
- export class UserStore extends StoreInterface<UserState> {
199
- constructor() {
332
+ export class UserService extends UserServiceInterface {
333
+ constructor(@inject(UserApi) private api: UserApi) {
334
+ // Initialize state
200
335
  super(() => ({
201
- currentUser: null,
336
+ users: [],
337
+ total: 0,
338
+ page: 1,
339
+ pageSize: 10,
202
340
  loading: false,
203
341
  error: null
204
342
  }));
205
343
  }
206
344
 
207
- // 3. Selector definitions
345
+ /**
346
+ * Selectors
347
+ */
208
348
  selector = {
209
- currentUser: (state: UserState) => state.currentUser,
210
- loading: (state: UserState) => state.loading
349
+ users: (state: UserServiceState) => state.users,
350
+ loading: (state: UserServiceState) => state.loading,
351
+ total: (state: UserServiceState) => state.total,
352
+ page: (state: UserServiceState) => state.page,
353
+ pageSize: (state: UserServiceState) => state.pageSize
211
354
  };
212
355
 
213
- // 4. Operation methods
214
- async fetchUser(id: string) {
356
+ /**
357
+ * Fetch user list
358
+ */
359
+ async fetchUsers(params: UserListParams): Promise<void> {
215
360
  try {
216
- this.emit({ ...this.state, loading: true });
217
- const user = await api.getUser(id);
218
- this.emit({ ...this.state, currentUser: user, loading: false });
361
+ // 1. Set loading state
362
+ this.emit({ ...this.state, loading: true, error: null });
363
+
364
+ // 2. Call API
365
+ const response = await this.api.getUserList(params);
366
+
367
+ // 3. Update state
368
+ this.emit({
369
+ users: response.list,
370
+ total: response.total,
371
+ page: response.page,
372
+ pageSize: response.pageSize,
373
+ loading: false,
374
+ error: null
375
+ });
219
376
  } catch (error) {
377
+ // 4. Error handling
220
378
  this.emit({
221
379
  ...this.state,
222
- error: error.message,
223
- loading: false
380
+ loading: false,
381
+ error: error as Error
224
382
  });
225
383
  }
226
384
  }
227
- }
228
- ```
229
385
 
230
- ### 2. Store Usage
231
-
232
- ```tsx
233
- function UserProfile() {
234
- const userStore = IOC(UserStore);
235
- const user = useStore(userStore, userStore.selector.currentUser);
236
- const loading = useStore(userStore, userStore.selector.loading);
386
+ /**
387
+ * Search users
388
+ */
389
+ async searchUsers(keyword: string): Promise<void> {
390
+ await this.fetchUsers({
391
+ page: 1,
392
+ pageSize: this.state.pageSize,
393
+ keyword
394
+ });
395
+ }
237
396
 
238
- return <div>{loading ? <Loading /> : <UserInfo user={user} />}</div>;
397
+ /**
398
+ * Refresh list
399
+ */
400
+ async refreshUsers(): Promise<void> {
401
+ await this.fetchUsers({
402
+ page: this.state.page,
403
+ pageSize: this.state.pageSize
404
+ });
405
+ }
239
406
  }
240
407
  ```
241
408
 
242
- ## Router Development Standards
409
+ ### 6. Configure Routes
243
410
 
244
- > 💡 Only basic standards are listed here. For complete router development guide, please refer to [Router Development Guide](./router.md)
245
-
246
- ### 1. Basic Standards
247
-
248
- - Route configurations are centrally managed in `config/app.router.ts`
249
- - Use declarative route configuration
250
- - Route components are placed in the `pages` directory
251
- - Support route-level code splitting
252
- - Route configurations include metadata support
411
+ ```typescript
412
+ // config/app.router.ts
253
413
 
254
- ### 2. Example
414
+ import * as i18nKeys from './Identifier/pages/page.users';
255
415
 
256
- ```typescript
257
- // Route configuration example
258
416
  export const baseRoutes: RouteConfigValue[] = [
259
417
  {
260
418
  path: '/:lng',
261
419
  element: 'base/Layout',
262
- meta: {
263
- category: 'main'
264
- },
265
420
  children: [
421
+ // ... other routes
266
422
  {
267
423
  path: 'users',
268
- element: 'users/UserList',
424
+ element: 'users/UserListPage',
269
425
  meta: {
270
426
  title: i18nKeys.PAGE_USERS_TITLE,
271
- auth: true
427
+ requiresAuth: true, // Requires authentication
428
+ category: 'main'
272
429
  }
273
430
  }
274
431
  ]
@@ -276,248 +433,767 @@ export const baseRoutes: RouteConfigValue[] = [
276
433
  ];
277
434
  ```
278
435
 
279
- For more route configuration and usage examples, please refer to [Router Development Guide](./router.md).
436
+ ### 7. Implement Page Component
437
+
438
+ ```typescript
439
+ // pages/users/UserListPage.tsx
440
+
441
+ import { useEffect, useState } from 'react';
442
+ import { Table, Input, Button, Avatar, Space } from 'antd';
443
+ import { ReloadOutlined, EyeOutlined } from '@ant-design/icons';
444
+ import { useIOC } from '@/uikit/hooks/useIOC';
445
+ import { useStore } from '@brain-toolkit/react-kit/hooks/useStore';
446
+ import { useAppTranslation } from '@/uikit/hooks/useAppTranslation';
447
+ import { IOCIdentifier } from '@config/IOCIdentifier';
448
+ import * as i18nKeys from '@config/Identifier/pages/page.users';
449
+ import type { UserInfo } from '@/base/port/UserServiceInterface';
450
+
451
+ export default function UserListPage() {
452
+ // 1. Get services
453
+ const userService = useIOC(IOCIdentifier.UserServiceInterface);
454
+ const routeService = useIOC(IOCIdentifier.RouteServiceInterface);
455
+ const { t } = useAppTranslation();
456
+
457
+ // 2. Subscribe to state
458
+ const users = useStore(userService, userService.selector.users);
459
+ const loading = useStore(userService, userService.selector.loading);
460
+ const total = useStore(userService, userService.selector.total);
461
+ const page = useStore(userService, userService.selector.page);
462
+ const pageSize = useStore(userService, userService.selector.pageSize);
463
+
464
+ // 3. Local state
465
+ const [keyword, setKeyword] = useState('');
466
+
467
+ // 4. Initialize loading
468
+ useEffect(() => {
469
+ userService.fetchUsers({ page: 1, pageSize: 10 });
470
+ }, []);
471
+
472
+ // 5. Event handlers
473
+ const handleSearch = () => {
474
+ userService.searchUsers(keyword);
475
+ };
476
+
477
+ const handleRefresh = () => {
478
+ userService.refreshUsers();
479
+ };
280
480
 
281
- ## Internationalization Development Standards
481
+ const handlePageChange = (newPage: number, newPageSize: number) => {
482
+ userService.fetchUsers({ page: newPage, pageSize: newPageSize, keyword });
483
+ };
282
484
 
283
- > 💡 Only basic standards are listed here. For complete internationalization development guide, please refer to [Internationalization Development Guide](./i18n.md)
485
+ const handleViewDetail = (userId: string) => {
486
+ routeService.push(`/users/${userId}`);
487
+ };
284
488
 
285
- ### 1. Basic Standards
489
+ // 6. Table column configuration
490
+ const columns = [
491
+ {
492
+ title: t(i18nKeys.PAGE_USERS_COLUMN_AVATAR),
493
+ dataIndex: 'avatar',
494
+ key: 'avatar',
495
+ render: (avatar: string) => <Avatar src={avatar} />
496
+ },
497
+ {
498
+ title: t(i18nKeys.PAGE_USERS_COLUMN_NAME),
499
+ dataIndex: 'name',
500
+ key: 'name'
501
+ },
502
+ {
503
+ title: t(i18nKeys.PAGE_USERS_COLUMN_EMAIL),
504
+ dataIndex: 'email',
505
+ key: 'email'
506
+ },
507
+ {
508
+ title: t(i18nKeys.PAGE_USERS_COLUMN_ROLE),
509
+ dataIndex: 'role',
510
+ key: 'role',
511
+ render: (role: string) => t(`common.role.${role}`)
512
+ },
513
+ {
514
+ title: t(i18nKeys.PAGE_USERS_COLUMN_ACTIONS),
515
+ key: 'actions',
516
+ render: (_: any, record: UserInfo) => (
517
+ <Button
518
+ type="link"
519
+ icon={<EyeOutlined />}
520
+ onClick={() => handleViewDetail(record.id)}
521
+ >
522
+ {t(i18nKeys.PAGE_USERS_VIEW_DETAIL)}
523
+ </Button>
524
+ )
525
+ }
526
+ ];
286
527
 
287
- - Use identifier constants to manage translation keys
288
- - Generate translation resources through TypeScript comments
289
- - Support multi-language routes
290
- - Centrally manage translation files
528
+ // 7. Render
529
+ return (
530
+ <div className="p-6">
531
+ {/* Page title */}
532
+ <h1 className="text-2xl font-bold mb-4">
533
+ {t(i18nKeys.PAGE_USERS_TITLE)}
534
+ </h1>
535
+
536
+ {/* Search bar */}
537
+ <div className="mb-4 flex gap-2">
538
+ <Input.Search
539
+ placeholder={t(i18nKeys.PAGE_USERS_SEARCH_PLACEHOLDER)}
540
+ value={keyword}
541
+ onChange={(e) => setKeyword(e.target.value)}
542
+ onSearch={handleSearch}
543
+ style={{ width: 300 }}
544
+ />
545
+ <Button
546
+ icon={<ReloadOutlined />}
547
+ onClick={handleRefresh}
548
+ loading={loading}
549
+ >
550
+ {t(i18nKeys.PAGE_USERS_REFRESH)}
551
+ </Button>
552
+ </div>
553
+
554
+ {/* User table */}
555
+ <Table
556
+ columns={columns}
557
+ dataSource={users}
558
+ rowKey="id"
559
+ loading={loading}
560
+ pagination={{
561
+ current: page,
562
+ pageSize: pageSize,
563
+ total: total,
564
+ onChange: handlePageChange,
565
+ showSizeChanger: true,
566
+ showTotal: (total) => `${t('common.total')} ${total} ${t('common.items')}`
567
+ }}
568
+ locale={{
569
+ emptyText: t(i18nKeys.PAGE_USERS_EMPTY)
570
+ }}
571
+ />
572
+ </div>
573
+ );
574
+ }
575
+ ```
291
576
 
292
- ### 2. Example
577
+ ### 8. Register to IOC (if new service)
293
578
 
294
579
  ```typescript
295
- /**
296
- * @description User list page title
297
- * @localZh 用户列表
298
- * @localEn User List
299
- */
300
- export const PAGE_USERS_TITLE = 'page.users.title';
580
+ // core/clientIoc/ClientIOCRegister.ts
581
+
582
+ export class ClientIOCRegister {
583
+ protected registerImplement(ioc: IOCContainerInterface): void {
584
+ // ... other service registrations
585
+
586
+ // Register UserService
587
+ ioc.bind(IOCIdentifier.UserServiceInterface, ioc.get(UserService));
588
+ }
589
+ }
301
590
  ```
302
591
 
303
- For more internationalization configuration and usage examples, please refer to [Internationalization Development Guide](./i18n.md).
592
+ ### 9. Write Tests
304
593
 
305
- ## Theme Style Standards
594
+ ```typescript
595
+ // __tests__/src/base/services/UserService.test.ts
306
596
 
307
- > 💡 Only basic standards are listed here. For complete theme development guide, please refer to [Theme Development Guide](./theme.md)
597
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
598
+ import { UserService } from '@/base/services/UserService';
308
599
 
309
- ### 1. Basic Standards
600
+ describe('UserService', () => {
601
+ let userService: UserService;
602
+ let mockApi: any;
310
603
 
311
- - Use CSS variables to manage themes
312
- - Follow Tailwind CSS usage standards
313
- - Modularize component styles
314
- - Support multiple theme switching
604
+ beforeEach(() => {
605
+ mockApi = {
606
+ getUserList: vi.fn()
607
+ };
315
608
 
316
- ### 2. Example
609
+ userService = new UserService(mockApi);
610
+ });
317
611
 
318
- ```css
319
- :root {
320
- --color-brand: 37 99 235;
321
- --text-primary: 15 23 42;
322
- }
323
- ```
612
+ it('should fetch users and update state', async () => {
613
+ const mockResponse = {
614
+ list: [
615
+ {
616
+ id: '1',
617
+ name: 'John',
618
+ email: 'john@example.com',
619
+ avatar: '',
620
+ role: 'user'
621
+ }
622
+ ],
623
+ total: 1,
624
+ page: 1,
625
+ pageSize: 10
626
+ };
324
627
 
325
- For more theme configuration and usage examples, please refer to [Theme Development Guide](./theme.md).
628
+ mockApi.getUserList.mockResolvedValue(mockResponse);
326
629
 
327
- ## Testing Standards
630
+ const states: any[] = [];
631
+ userService.subscribe((state) => states.push({ ...state }));
328
632
 
329
- > 💡 Only basic standards are listed here. For complete testing guide, please refer to [Testing Development Guide](./testing.md)
633
+ await userService.fetchUsers({ page: 1, pageSize: 10 });
330
634
 
331
- ### 1. Basic Standards
635
+ // Verify state changes
636
+ expect(states).toHaveLength(2);
637
+ expect(states[0].loading).toBe(true);
638
+ expect(states[1].loading).toBe(false);
639
+ expect(states[1].users).toEqual(mockResponse.list);
640
+ expect(states[1].total).toBe(1);
641
+ });
332
642
 
333
- - Unit tests cover core logic
334
- - Component tests focus on interaction and rendering
335
- - Use Jest and Testing Library
336
- - Keep tests simple and maintainable
643
+ it('should handle error when fetch fails', async () => {
644
+ mockApi.getUserList.mockRejectedValue(new Error('Network error'));
337
645
 
338
- ### 2. Example
646
+ await userService.fetchUsers({ page: 1, pageSize: 10 });
647
+
648
+ expect(userService.getState().error).toBeTruthy();
649
+ expect(userService.getState().loading).toBe(false);
650
+ });
651
+ });
652
+ ```
339
653
 
340
654
  ```typescript
341
- describe('UserProfile', () => {
342
- it('should render user info', () => {
343
- const user = { id: '1', name: 'Test' };
344
- render(<UserProfile user={user} />);
345
- expect(screen.getByText(user.name)).toBeInTheDocument();
655
+ // __tests__/src/pages/users/UserListPage.test.tsx
656
+
657
+ import { describe, it, expect, vi } from 'vitest';
658
+ import { render, screen, fireEvent, waitFor } from '@testing-library/react';
659
+ import UserListPage from '@/pages/users/UserListPage';
660
+ import { IOCProvider } from '@/uikit/contexts/IOCContext';
661
+
662
+ describe('UserListPage', () => {
663
+ it('should display user list', async () => {
664
+ const mockUsers = [
665
+ {
666
+ id: '1',
667
+ name: 'John',
668
+ email: 'john@example.com',
669
+ avatar: '',
670
+ role: 'user'
671
+ }
672
+ ];
673
+
674
+ const mockUserService = {
675
+ fetchUsers: vi.fn(),
676
+ searchUsers: vi.fn(),
677
+ refreshUsers: vi.fn(),
678
+ subscribe: vi.fn(),
679
+ getState: () => ({ users: mockUsers, loading: false, total: 1 }),
680
+ selector: {
681
+ users: (state: any) => state.users,
682
+ loading: (state: any) => state.loading,
683
+ total: (state: any) => state.total
684
+ }
685
+ };
686
+
687
+ const mockIOC = (identifier: string) => {
688
+ if (identifier === 'UserServiceInterface') return mockUserService;
689
+ if (identifier === 'RouteServiceInterface') return { push: vi.fn() };
690
+ };
691
+
692
+ render(
693
+ <IOCProvider value={mockIOC}>
694
+ <UserListPage />
695
+ </IOCProvider>
696
+ );
697
+
698
+ await waitFor(() => {
699
+ expect(screen.getByText('John')).toBeInTheDocument();
700
+ expect(screen.getByText('john@example.com')).toBeInTheDocument();
701
+ });
702
+ });
703
+
704
+ it('should search users when search button clicked', async () => {
705
+ const mockUserService = {
706
+ fetchUsers: vi.fn(),
707
+ searchUsers: vi.fn(),
708
+ subscribe: vi.fn(),
709
+ getState: () => ({ users: [], loading: false }),
710
+ selector: {
711
+ users: () => [],
712
+ loading: () => false,
713
+ total: () => 0
714
+ }
715
+ };
716
+
717
+ const mockIOC = (identifier: string) => {
718
+ if (identifier === 'UserServiceInterface') return mockUserService;
719
+ if (identifier === 'RouteServiceInterface') return { push: vi.fn() };
720
+ };
721
+
722
+ render(
723
+ <IOCProvider value={mockIOC}>
724
+ <UserListPage />
725
+ </IOCProvider>
726
+ );
727
+
728
+ const searchInput = screen.getByPlaceholderText(/search/i);
729
+ fireEvent.change(searchInput, { target: { value: 'John' } });
730
+
731
+ const searchButton = screen.getByRole('button', { name: /search/i });
732
+ fireEvent.click(searchButton);
733
+
734
+ expect(mockUserService.searchUsers).toHaveBeenCalledWith('John');
346
735
  });
347
736
  });
348
737
  ```
349
738
 
350
- For more testing examples and best practices, please refer to [Testing Development Guide](./testing.md).
739
+ ---
351
740
 
352
- ## Documentation Standards
741
+ ## 🎬 Common Scenarios
353
742
 
354
- > 💡 Only basic standards are listed here. For complete documentation writing guide, please refer to [Documentation Writing Guide](./documentation.md)
743
+ ### Scenario 1: Adding a New Button Feature
355
744
 
356
- ### 1. Code Comments
745
+ Suppose we want to add a "bulk delete" feature to the user list page:
357
746
 
358
747
  ```typescript
748
+ // 1. Add i18n Key
359
749
  /**
360
- * User service
361
- *
362
- * @description Handles user-related business logic
363
- * @example
364
- * const userService = IOC(UserService);
365
- * await userService.login(credentials);
750
+ * @description Delete selected users
751
+ * @localZh 删除选中用户
752
+ * @localEn Delete Selected
366
753
  */
754
+ export const PAGE_USERS_DELETE_SELECTED = 'page.users.deleteSelected';
755
+
756
+ // 2. Add method to service
367
757
  @injectable()
368
- export class UserService {
369
- /**
370
- * User login
371
- *
372
- * @param credentials - Login credentials
373
- * @returns Logged-in user information
374
- * @throws {AuthError} Thrown when authentication fails
375
- */
376
- async login(credentials: Credentials): Promise<User> {
377
- // Implementation
758
+ export class UserService extends UserServiceInterface {
759
+ async deleteUsers(userIds: string[]): Promise<void> {
760
+ try {
761
+ this.emit({ ...this.state, loading: true });
762
+ await this.api.deleteUsers(userIds);
763
+ await this.refreshUsers(); // Refresh list
764
+ } catch (error) {
765
+ this.emit({ ...this.state, loading: false, error: error as Error });
766
+ }
378
767
  }
379
768
  }
769
+
770
+ // 3. Use in page
771
+ function UserListPage() {
772
+ const [selectedRowKeys, setSelectedRowKeys] = useState<string[]>([]);
773
+
774
+ const handleDelete = async () => {
775
+ await userService.deleteUsers(selectedRowKeys);
776
+ setSelectedRowKeys([]);
777
+ };
778
+
779
+ return (
780
+ <div>
781
+ <Button
782
+ danger
783
+ onClick={handleDelete}
784
+ disabled={selectedRowKeys.length === 0}
785
+ >
786
+ {t(i18nKeys.PAGE_USERS_DELETE_SELECTED)}
787
+ </Button>
788
+
789
+ <Table
790
+ rowSelection={{
791
+ selectedRowKeys,
792
+ onChange: setSelectedRowKeys
793
+ }}
794
+ // ...
795
+ />
796
+ </div>
797
+ );
798
+ }
380
799
  ```
381
800
 
382
- ### 2. Documentation Structure
801
+ ### Scenario 2: Adding a Modal Form
383
802
 
384
- - **README.md**: Project overview, installation instructions, quick start
385
- - **docs/**:
386
- - `zh/`: Chinese documentation
387
- - `en/`: English documentation
388
- - Organize documentation files by feature modules
803
+ Suppose we want to add an "edit user" modal:
389
804
 
390
- ### 3. Documentation Format
805
+ ```typescript
806
+ // 1. Create modal component
807
+ // components/UserEditModal.tsx
808
+ interface UserEditModalProps {
809
+ user: UserInfo | null;
810
+ visible: boolean;
811
+ onClose: () => void;
812
+ onSubmit: (user: UserInfo) => void;
813
+ }
391
814
 
392
- ```markdown
393
- # Module Name
815
+ export function UserEditModal({ user, visible, onClose, onSubmit }: UserEditModalProps) {
816
+ const [form] = Form.useForm();
817
+ const { t } = useAppTranslation();
394
818
 
395
- ## Overview
819
+ useEffect(() => {
820
+ if (user) {
821
+ form.setFieldsValue(user);
822
+ }
823
+ }, [user]);
396
824
 
397
- Brief explanation of module functionality and purpose.
825
+ const handleSubmit = async () => {
826
+ const values = await form.validateFields();
827
+ onSubmit(values);
828
+ };
398
829
 
399
- ## Usage
830
+ return (
831
+ <Modal
832
+ title={t(i18nKeys.PAGE_USERS_EDIT_TITLE)}
833
+ open={visible}
834
+ onCancel={onClose}
835
+ onOk={handleSubmit}
836
+ >
837
+ <Form form={form} layout="vertical">
838
+ <Form.Item
839
+ name="name"
840
+ label={t(i18nKeys.PAGE_USERS_FORM_NAME)}
841
+ rules={[{ required: true }]}
842
+ >
843
+ <Input />
844
+ </Form.Item>
845
+ <Form.Item
846
+ name="email"
847
+ label={t(i18nKeys.PAGE_USERS_FORM_EMAIL)}
848
+ rules={[{ required: true, type: 'email' }]}
849
+ >
850
+ <Input />
851
+ </Form.Item>
852
+ </Form>
853
+ </Modal>
854
+ );
855
+ }
400
856
 
401
- Code examples and usage instructions.
857
+ // 2. Add update method to service
858
+ @injectable()
859
+ export class UserService extends UserServiceInterface {
860
+ async updateUser(userId: string, data: Partial<UserInfo>): Promise<void> {
861
+ this.emit({ ...this.state, loading: true });
862
+ await this.api.updateUser(userId, data);
863
+ await this.refreshUsers();
864
+ }
865
+ }
402
866
 
403
- ## API Documentation
867
+ // 3. Use in page
868
+ function UserListPage() {
869
+ const [editUser, setEditUser] = useState<UserInfo | null>(null);
870
+ const [modalVisible, setModalVisible] = useState(false);
404
871
 
405
- Detailed API descriptions.
872
+ const handleEdit = (user: UserInfo) => {
873
+ setEditUser(user);
874
+ setModalVisible(true);
875
+ };
406
876
 
407
- ## Best Practices
877
+ const handleSubmit = async (values: UserInfo) => {
878
+ await userService.updateUser(editUser!.id, values);
879
+ setModalVisible(false);
880
+ setEditUser(null);
881
+ };
408
882
 
409
- Usage suggestions and considerations.
883
+ return (
884
+ <div>
885
+ <Table
886
+ columns={[
887
+ // ...
888
+ {
889
+ title: 'Actions',
890
+ render: (_, record) => (
891
+ <Button onClick={() => handleEdit(record)}>Edit</Button>
892
+ )
893
+ }
894
+ ]}
895
+ // ...
896
+ />
897
+
898
+ <UserEditModal
899
+ user={editUser}
900
+ visible={modalVisible}
901
+ onClose={() => setModalVisible(false)}
902
+ onSubmit={handleSubmit}
903
+ />
904
+ </div>
905
+ );
906
+ }
410
907
  ```
411
908
 
412
- ## Git Commit Standards
909
+ ### Scenario 3: Adding Real-time Search
413
910
 
414
- > 💡 Only basic standards are listed here. For complete Git workflow, please refer to [Git Workflow Guide](./git-workflow.md)
911
+ Suppose we want to implement "auto-search while typing":
415
912
 
416
- ### 1. Commit Message Format
913
+ ```typescript
914
+ function UserListPage() {
915
+ const [keyword, setKeyword] = useState('');
417
916
 
418
- ```
419
- <type>(<scope>): <subject>
917
+ // Use debounce to optimize search
918
+ const debouncedKeyword = useDebounce(keyword, 500);
420
919
 
421
- <body>
920
+ useEffect(() => {
921
+ if (debouncedKeyword !== undefined) {
922
+ userService.searchUsers(debouncedKeyword);
923
+ }
924
+ }, [debouncedKeyword]);
422
925
 
423
- <footer>
424
- ```
926
+ return (
927
+ <Input
928
+ placeholder={t(i18nKeys.PAGE_USERS_SEARCH_PLACEHOLDER)}
929
+ value={keyword}
930
+ onChange={(e) => setKeyword(e.target.value)}
931
+ />
932
+ );
933
+ }
425
934
 
426
- - **type**:
427
- - `feat`: New feature
428
- - `fix`: Bug fix
429
- - `docs`: Documentation updates
430
- - `style`: Code formatting (changes that don't affect code execution)
431
- - `refactor`: Code refactoring
432
- - `test`: Adding tests
433
- - `chore`: Build process or auxiliary tool changes
935
+ // Custom Hook
936
+ function useDebounce<T>(value: T, delay: number): T {
937
+ const [debouncedValue, setDebouncedValue] = useState(value);
434
938
 
435
- - **scope**: Impact scope (optional)
436
- - **subject**: Brief description
437
- - **body**: Detailed description (optional)
438
- - **footer**: Breaking changes, issue closure (optional)
939
+ useEffect(() => {
940
+ const timer = setTimeout(() => {
941
+ setDebouncedValue(value);
942
+ }, delay);
439
943
 
440
- ### 2. Example
944
+ return () => {
945
+ clearTimeout(timer);
946
+ };
947
+ }, [value, delay]);
441
948
 
949
+ return debouncedValue;
950
+ }
442
951
  ```
443
- feat(auth): add user role management functionality
444
952
 
445
- - Add role creation and editing interface
446
- - Implement role permission configuration
447
- - Add role assignment functionality
953
+ ---
448
954
 
449
- Closes #123
450
- ```
955
+ ## 📐 Code Standards
451
956
 
452
- ## Performance Optimization Standards
957
+ ### 1. Naming Conventions
453
958
 
454
- > 💡 Only basic standards are listed here. For complete performance optimization guide, please refer to [Performance Optimization Guide](./performance.md)
959
+ ```typescript
960
+ // ✅ Good naming
961
+ const userService = useIOC('UserServiceInterface'); // Service: camelCase
962
+ const UserListPage = () => {
963
+ /* ... */
964
+ }; // Component: PascalCase
965
+ const PAGE_USERS_TITLE = 'page.users.title'; // Constant: UPPER_SNAKE_CASE
966
+ interface UserInfo {
967
+ /* ... */
968
+ } // Interface: PascalCase
969
+ type UserRole = 'admin' | 'user'; // Type: PascalCase
970
+
971
+ // ❌ Bad naming
972
+ const UserService = useIOC('UserServiceInterface'); // Should be camelCase
973
+ const userListPage = () => {
974
+ /* ... */
975
+ }; // Component should be PascalCase
976
+ const pageUsersTitle = 'page.users.title'; // Constant should be UPPER_CASE
977
+ interface userInfo {
978
+ /* ... */
979
+ } // Interface should be PascalCase
980
+ ```
455
981
 
456
- ### 1. Code Splitting
982
+ ### 2. File Organization
457
983
 
458
984
  ```typescript
459
- // Route-level code splitting
460
- const UserModule = lazy(() => import('./pages/users'));
985
+ // Good file organization
986
+ import { FC, useEffect, useState } from 'react'; // React
987
+ import { Button, Table, Input } from 'antd'; // Third-party UI
988
+ import { useIOC } from '@/uikit/hooks/useIOC'; // Internal project
989
+ import { useAppTranslation } from '@/uikit/hooks/useAppTranslation';
990
+ import * as i18nKeys from '@config/Identifier/pages/page.users';
991
+ import './UserListPage.css'; // Styles
992
+
993
+ // Type definitions
994
+ interface Props {
995
+ /* ... */
996
+ }
461
997
 
462
- // Component-level code splitting
463
- const HeavyComponent = lazy(() => import('./components/Heavy'));
998
+ // Component
999
+ export default function UserListPage() {
1000
+ /* ... */
1001
+ }
1002
+
1003
+ // ❌ Bad file organization
1004
+ import './UserListPage.css'; // Styles shouldn't be first
1005
+ import * as i18nKeys from '@config/Identifier/pages/page.users';
1006
+ import { Button } from 'antd';
1007
+ import { useIOC } from '@/uikit/hooks/useIOC';
1008
+ import { FC } from 'react';
464
1009
  ```
465
1010
 
466
- ### 2. Performance Considerations
1011
+ ### 3. Component Structure
467
1012
 
468
1013
  ```typescript
469
- // Use useMemo to cache computation results
470
- const sortedUsers = useMemo(() => {
471
- return users.sort((a, b) => a.name.localeCompare(b.name));
472
- }, [users]);
473
-
474
- // Use useCallback to cache functions
475
- const handleUpdate = useCallback(() => {
476
- // Implementation
477
- }, [dependencies]);
478
-
479
- // Use React.memo to avoid unnecessary re-renders
480
- const UserCard = React.memo(({ user }) => {
481
- return <div>{user.name}</div>;
482
- });
483
- ```
484
-
485
- ## Security Standards
1014
+ // Good component structure
1015
+ export default function UserListPage() {
1016
+ // 1. Hooks
1017
+ const userService = useIOC('UserServiceInterface');
1018
+ const { t } = useAppTranslation();
486
1019
 
487
- > 💡 Only basic standards are listed here. For complete security development guide, please refer to [Security Development Guide](./security.md)
1020
+ // 2. State
1021
+ const users = useStore(userService, userService.selector.users);
1022
+ const [keyword, setKeyword] = useState('');
488
1023
 
489
- ### 1. Data Handling
1024
+ // 3. Side effects
1025
+ useEffect(() => {
1026
+ userService.fetchUsers({ page: 1, pageSize: 10 });
1027
+ }, []);
490
1028
 
491
- ```typescript
492
- // Sensitive data encryption
493
- const encryptedData = encrypt(sensitiveData);
1029
+ // 4. Event handlers
1030
+ const handleSearch = () => {
1031
+ userService.searchUsers(keyword);
1032
+ };
494
1033
 
495
- // XSS protection
496
- const sanitizedHtml = sanitizeHtml(userInput);
1034
+ // 5. Render functions
1035
+ const renderActions = (record: UserInfo) => {
1036
+ return <Button onClick={() => handleEdit(record)}>Edit</Button>;
1037
+ };
497
1038
 
498
- // CSRF protection
499
- api.defaults.headers['X-CSRF-Token'] = getCsrfToken();
1039
+ // 6. Return JSX
1040
+ return (
1041
+ <div>
1042
+ {/* ... */}
1043
+ </div>
1044
+ );
1045
+ }
500
1046
  ```
501
1047
 
502
- ### 2. Permission Control
1048
+ ### 4. Comment Standards
503
1049
 
504
1050
  ```typescript
505
- // Route permissions
506
- const PrivateRoute: FC = ({ children }) => {
507
- const auth = useAuth();
508
- return auth.isAuthenticated ? children : <Navigate to="/login" />;
509
- };
1051
+ /**
1052
+ * User list page
1053
+ *
1054
+ * @description Display user list with search, pagination, and view details functionality
1055
+ */
1056
+ export default function UserListPage() {
1057
+ /**
1058
+ * Handle search
1059
+ * Search users by keyword
1060
+ */
1061
+ const handleSearch = () => {
1062
+ userService.searchUsers(keyword);
1063
+ };
510
1064
 
511
- // Operation permissions
512
- function AdminPanel() {
513
- const { hasPermission } = useAuth();
1065
+ // Initialize user list loading
1066
+ useEffect(() => {
1067
+ userService.fetchUsers({ page: 1, pageSize: 10 });
1068
+ }, []);
514
1069
 
515
1070
  return (
516
1071
  <div>
517
- {hasPermission('ADMIN') && (
518
- <button>Admin Operation</button>
519
- )}
1072
+ {/* Search bar */}
1073
+ <Input.Search onSearch={handleSearch} />
1074
+
1075
+ {/* User table */}
1076
+ <Table dataSource={users} />
520
1077
  </div>
521
1078
  );
522
1079
  }
523
1080
  ```
1081
+
1082
+ ---
1083
+
1084
+ ## 🛠️ Development Tools
1085
+
1086
+ ### Recommended VSCode Extensions
1087
+
1088
+ ```
1089
+ ✅ ESLint - Code linting
1090
+ ✅ Prettier - Code formatting
1091
+ ✅ TypeScript Vue Plugin (Volar) - Vue/React support
1092
+ ✅ Tailwind CSS IntelliSense - Tailwind autocomplete
1093
+ ✅ i18n Ally - i18n management
1094
+ ✅ GitLens - Git enhancement
1095
+ ✅ Error Lens - Error display
1096
+ ✅ Auto Rename Tag - Tag auto-rename
1097
+ ```
1098
+
1099
+ ### Quick Commands
1100
+
1101
+ ```bash
1102
+ # Development
1103
+ npm run dev # Start dev server
1104
+ npm run dev:staging # Start staging environment
1105
+
1106
+ # Build
1107
+ npm run build # Production build
1108
+ npm run preview # Preview build result
1109
+
1110
+ # Code quality
1111
+ npm run lint # ESLint check
1112
+ npm run lint:fix # ESLint auto-fix
1113
+ npm run type-check # TypeScript type checking
1114
+
1115
+ # Testing
1116
+ npm run test # Run tests
1117
+ npm run test:watch # Watch mode testing
1118
+ npm run test:coverage # Test coverage
1119
+
1120
+ # i18n
1121
+ npm run i18n:generate # Generate translation files
1122
+ ```
1123
+
1124
+ ### Debugging Tips
1125
+
1126
+ ```typescript
1127
+ // 1. Use logger
1128
+ import { logger } from '@/core/globals';
1129
+
1130
+ logger.debug('User data:', user);
1131
+ logger.error('Failed to fetch users:', error);
1132
+
1133
+ // 2. Use React DevTools
1134
+ // Install React Developer Tools browser extension
1135
+
1136
+ // 3. Use Redux DevTools (if needed)
1137
+ // View Store state changes
1138
+
1139
+ // 4. Use VSCode breakpoint debugging
1140
+ // Click on the left side of a code line to set breakpoint, then F5 to start debugging
1141
+ ```
1142
+
1143
+ ---
1144
+
1145
+ ## 🎯 Development Checklist
1146
+
1147
+ ### Feature Development
1148
+
1149
+ - [ ] Define i18n Keys
1150
+ - [ ] Define interfaces and types
1151
+ - [ ] Implement API adapter (if needed)
1152
+ - [ ] Implement service
1153
+ - [ ] Configure routes
1154
+ - [ ] Implement page component
1155
+ - [ ] Register to IOC (if new service)
1156
+ - [ ] Feature self-testing
1157
+
1158
+ ### Code Quality
1159
+
1160
+ - [ ] Pass ESLint check
1161
+ - [ ] Pass TypeScript type check
1162
+ - [ ] Code formatting (Prettier)
1163
+ - [ ] Remove console.log and debug code
1164
+ - [ ] Remove unused imports
1165
+
1166
+ ### Testing
1167
+
1168
+ - [ ] Write service tests
1169
+ - [ ] Write UI tests
1170
+ - [ ] Test coverage > 80%
1171
+ - [ ] All tests passing
1172
+
1173
+ ### Documentation
1174
+
1175
+ - [ ] Update related documentation
1176
+ - [ ] Add necessary code comments
1177
+ - [ ] Update API documentation (if any)
1178
+
1179
+ ### Submission
1180
+
1181
+ - [ ] Git commit follows conventions
1182
+ - [ ] Code reviewed
1183
+ - [ ] Merged to main branch
1184
+
1185
+ ---
1186
+
1187
+ ## 📚 Related Documentation
1188
+
1189
+ - **[Project Architecture Design](./index.md)** - Understand overall architecture
1190
+ - **[IOC Container](./ioc.md)** - Dependency injection and UI separation
1191
+ - **[Store State Management](./store.md)** - How application layer notifies UI layer
1192
+ - **[Bootstrap Initializer](./bootstrap.md)** - Application startup and initialization
1193
+ - **[Environment Variables](./env.md)** - Multi-environment configuration
1194
+ - **[Internationalization](./i18n.md)** - i18n Key and translation management
1195
+
1196
+ ---
1197
+
1198
+ **Feedback:**
1199
+ If you encounter any problems during development, please discuss in the team channel or submit an Issue.