@qlover/create-app 0.7.15 → 0.9.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 (363) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/configs/_common/.github/workflows/general-check.yml +1 -1
  3. package/dist/configs/_common/.github/workflows/release.yml +2 -2
  4. package/dist/configs/_common/.gitignore.template +6 -0
  5. package/dist/configs/_common/.prettierignore +17 -5
  6. package/dist/configs/_common/.vscode/settings.json +6 -1
  7. package/dist/index.cjs +1 -1
  8. package/dist/index.js +1 -1
  9. package/dist/templates/next-app/.env.template +1 -1
  10. package/dist/templates/next-app/README.en.md +0 -1
  11. package/dist/templates/next-app/README.md +0 -1
  12. package/dist/templates/next-app/config/Identifier/api.ts +5 -5
  13. package/dist/templates/next-app/config/Identifier/common/admint.table.ts +69 -0
  14. package/dist/templates/next-app/config/Identifier/common/common.ts +76 -0
  15. package/dist/templates/next-app/config/Identifier/common/index.ts +3 -0
  16. package/dist/templates/next-app/config/Identifier/{validator.ts → common/validators.ts} +5 -5
  17. package/dist/templates/next-app/config/Identifier/index.ts +2 -12
  18. package/dist/templates/next-app/config/Identifier/pages/index.ts +6 -0
  19. package/dist/templates/next-app/config/Identifier/pages/page.admin.home.ts +27 -0
  20. package/dist/templates/next-app/config/Identifier/pages/page.admin.locales.ts +266 -0
  21. package/dist/templates/next-app/config/Identifier/pages/page.admin.user.ts +293 -0
  22. package/dist/templates/{react-app/config/Identifier → next-app/config/Identifier/pages}/page.home.ts +15 -22
  23. package/dist/templates/next-app/config/Identifier/{page.login.ts → pages/page.login.ts} +28 -34
  24. package/dist/templates/next-app/config/Identifier/{page.register.ts → pages/page.register.ts} +30 -29
  25. package/dist/templates/next-app/config/adminNavs.ts +19 -0
  26. package/dist/templates/next-app/config/common.ts +22 -13
  27. package/dist/templates/next-app/config/i18n/HomeI18n.ts +5 -5
  28. package/dist/templates/next-app/config/i18n/admin18n.ts +61 -19
  29. package/dist/templates/next-app/config/i18n/i18nConfig.ts +2 -0
  30. package/dist/templates/next-app/config/i18n/i18nKeyScheam.ts +36 -0
  31. package/dist/templates/next-app/config/i18n/loginI18n.ts +22 -22
  32. package/dist/templates/next-app/config/i18n/register18n.ts +23 -24
  33. package/dist/templates/next-app/docs/en/index.md +0 -1
  34. package/dist/templates/next-app/docs/en/project-structure.md +0 -1
  35. package/dist/templates/next-app/docs/zh/index.md +0 -1
  36. package/dist/templates/next-app/docs/zh/project-structure.md +0 -1
  37. package/dist/templates/next-app/make/generateLocales.ts +19 -12
  38. package/dist/templates/next-app/migrations/schema/LocalesSchema.ts +15 -0
  39. package/dist/templates/next-app/migrations/sql/1694244000000.sql +11 -0
  40. package/dist/templates/next-app/package.json +7 -3
  41. package/dist/templates/next-app/public/locales/en.json +172 -207
  42. package/dist/templates/next-app/public/locales/zh.json +172 -207
  43. package/dist/templates/next-app/src/app/[locale]/admin/locales/page.tsx +153 -0
  44. package/dist/templates/next-app/src/app/[locale]/admin/users/page.tsx +48 -50
  45. package/dist/templates/next-app/src/app/[locale]/login/LoginForm.tsx +2 -2
  46. package/dist/templates/next-app/src/app/api/admin/locales/create/route.ts +34 -0
  47. package/dist/templates/next-app/src/app/api/admin/locales/import/route.ts +40 -0
  48. package/dist/templates/next-app/src/app/api/admin/locales/route.ts +42 -0
  49. package/dist/templates/next-app/src/app/api/admin/locales/update/route.ts +32 -0
  50. package/dist/templates/next-app/src/app/api/locales/json/route.ts +44 -0
  51. package/dist/templates/next-app/src/base/cases/AdminPageManager.ts +1 -13
  52. package/dist/templates/next-app/src/base/cases/Datetime.ts +18 -0
  53. package/dist/templates/next-app/src/base/cases/DialogErrorPlugin.ts +12 -6
  54. package/dist/templates/next-app/src/base/cases/ResourceState.ts +17 -0
  55. package/dist/templates/next-app/src/base/cases/TranslateI18nInterface.ts +25 -0
  56. package/dist/templates/next-app/src/base/cases/ZodColumnBuilder.ts +200 -0
  57. package/dist/templates/next-app/src/base/port/ZodBuilderInterface.ts +8 -0
  58. package/dist/templates/next-app/src/base/services/AdminLocalesService.ts +20 -0
  59. package/dist/templates/next-app/src/base/services/AdminPageEvent.ts +26 -0
  60. package/dist/templates/next-app/src/base/services/AdminPageScheduler.ts +42 -0
  61. package/dist/templates/next-app/src/base/services/ResourceService.ts +122 -0
  62. package/dist/templates/next-app/src/base/services/adminApi/AdminLocalesApi.ts +104 -0
  63. package/dist/templates/next-app/src/base/services/adminApi/AdminUserApi.ts +38 -5
  64. package/dist/templates/next-app/src/base/services/appApi/AppApiPlugin.ts +1 -1
  65. package/dist/templates/next-app/src/i18n/request.ts +30 -1
  66. package/dist/templates/next-app/src/server/PageParams.ts +2 -10
  67. package/dist/templates/next-app/src/server/port/DBBridgeInterface.ts +5 -0
  68. package/dist/templates/next-app/src/server/port/DBTableInterface.ts +2 -0
  69. package/dist/templates/next-app/src/server/port/LocalesRepositoryInterface.ts +43 -0
  70. package/dist/templates/next-app/src/server/repositorys/LocalesRepository.ts +197 -0
  71. package/dist/templates/next-app/src/server/services/ApiLocaleService.ts +122 -0
  72. package/dist/templates/next-app/src/server/sqlBridges/SupabaseBridge.ts +60 -11
  73. package/dist/templates/next-app/src/server/validators/ExtendedExecutorError.ts +6 -0
  74. package/dist/templates/next-app/src/server/validators/LocalesValidator.ts +131 -0
  75. package/dist/templates/next-app/src/server/validators/LoginValidator.ts +2 -5
  76. package/dist/templates/next-app/src/server/validators/PaginationValidator.ts +32 -16
  77. package/dist/templates/next-app/src/styles/css/antd-themes/pagination/_default.css +2 -1
  78. package/dist/templates/next-app/src/styles/css/antd-themes/pagination/dark.css +28 -29
  79. package/dist/templates/next-app/src/styles/css/antd-themes/pagination/pink.css +2 -1
  80. package/dist/templates/next-app/src/uikit/components/AdminLayout.tsx +17 -3
  81. package/dist/templates/next-app/src/uikit/components/BaseHeader.tsx +5 -4
  82. package/dist/templates/next-app/src/uikit/components/BaseLayout.tsx +5 -4
  83. package/dist/templates/next-app/src/uikit/components/BootstrapsProvider.tsx +3 -2
  84. package/dist/templates/next-app/src/uikit/components/ComboProvider.tsx +1 -1
  85. package/dist/templates/next-app/src/uikit/components/EditableCell.tsx +118 -0
  86. package/dist/templates/next-app/src/uikit/components/LogoutButton.tsx +5 -6
  87. package/dist/templates/next-app/src/uikit/components/ThemeSwitcher.tsx +1 -1
  88. package/dist/templates/next-app/src/uikit/components/With.tsx +2 -2
  89. package/dist/templates/next-app/src/uikit/components/localesImportButton/LocalesImportButton.tsx +62 -0
  90. package/dist/templates/next-app/src/uikit/components/localesImportButton/LocalesImportEvent.ts +28 -0
  91. package/dist/templates/next-app/src/uikit/components/localesImportButton/import.module.css +6 -0
  92. package/dist/templates/next-app/src/uikit/hook/useI18nInterface.ts +8 -14
  93. package/dist/templates/next-app/src/uikit/hook/useWarnTranslations.ts +25 -0
  94. package/dist/templates/react-app/.prettierignore +17 -0
  95. package/dist/templates/react-app/README.en.md +71 -54
  96. package/dist/templates/react-app/README.md +35 -18
  97. package/dist/templates/react-app/__tests__/__mocks__/BootstrapTest.ts +14 -0
  98. package/dist/templates/react-app/__tests__/__mocks__/MockAppConfit.ts +1 -1
  99. package/dist/templates/react-app/__tests__/__mocks__/MockDialogHandler.ts +2 -2
  100. package/dist/templates/react-app/__tests__/__mocks__/MockLogger.ts +1 -1
  101. package/dist/templates/react-app/__tests__/__mocks__/components/TestApp.tsx +45 -0
  102. package/dist/templates/react-app/__tests__/__mocks__/components/TestBootstrapsProvider.tsx +34 -0
  103. package/dist/templates/react-app/__tests__/__mocks__/components/TestRouter.tsx +46 -0
  104. package/dist/templates/react-app/__tests__/__mocks__/components/index.ts +12 -0
  105. package/dist/templates/react-app/__tests__/__mocks__/createMockGlobals.ts +1 -2
  106. package/dist/templates/react-app/__tests__/__mocks__/testIOC/TestIOC.ts +51 -0
  107. package/dist/templates/react-app/__tests__/__mocks__/testIOC/TestIOCRegister.ts +69 -0
  108. package/dist/templates/react-app/__tests__/setup/index.ts +1 -51
  109. package/dist/templates/react-app/__tests__/setup/setupGlobal.ts +51 -0
  110. package/dist/templates/react-app/__tests__/src/App.structure.test.tsx +115 -0
  111. package/dist/templates/react-app/__tests__/src/base/cases/AppConfig.test.ts +2 -2
  112. package/dist/templates/react-app/__tests__/src/base/cases/AppError.test.ts +1 -1
  113. package/dist/templates/react-app/__tests__/src/base/cases/DialogHandler.test.ts +3 -5
  114. package/dist/templates/react-app/__tests__/src/base/cases/I18nKeyErrorPlugin.test.ts +13 -2
  115. package/dist/templates/react-app/__tests__/src/base/cases/InversifyContainer.test.ts +1 -1
  116. package/dist/templates/react-app/__tests__/src/base/cases/PublicAssetsPath.test.ts +1 -1
  117. package/dist/templates/react-app/__tests__/src/base/cases/RequestLogger.test.ts +5 -5
  118. package/dist/templates/react-app/__tests__/src/base/cases/RequestStatusCatcher.test.ts +1 -2
  119. package/dist/templates/react-app/__tests__/src/base/cases/RouterLoader.test.ts +25 -15
  120. package/dist/templates/react-app/__tests__/src/base/services/I18nService.test.ts +29 -15
  121. package/dist/templates/react-app/__tests__/src/core/IOC.test.ts +19 -9
  122. package/dist/templates/react-app/__tests__/src/core/bootstraps/BootstrapClient.test.ts +153 -0
  123. package/dist/templates/react-app/__tests__/src/core/bootstraps/BootstrapsApp.test.ts +9 -7
  124. package/dist/templates/react-app/__tests__/src/main.integration.test.tsx +4 -5
  125. package/dist/templates/react-app/__tests__/src/main.test.tsx +4 -4
  126. package/dist/templates/react-app/__tests__/src/uikit/components/BaseHeader.test.tsx +68 -59
  127. package/dist/templates/react-app/__tests__/src/uikit/components/chatMessage/ChatRoot.test.tsx +274 -0
  128. package/dist/templates/react-app/config/IOCIdentifier.ts +11 -8
  129. package/dist/templates/react-app/config/Identifier/{common.error.ts → common/common.error.ts} +5 -5
  130. package/dist/templates/react-app/config/Identifier/{common.ts → common/common.ts} +9 -9
  131. package/dist/templates/react-app/config/Identifier/common/index.ts +2 -0
  132. package/dist/templates/react-app/config/Identifier/components/component.chatMessage.ts +56 -0
  133. package/dist/templates/react-app/config/Identifier/components/component.messageBaseList.ts +103 -0
  134. package/dist/templates/react-app/config/Identifier/index.ts +1 -9
  135. package/dist/templates/react-app/config/Identifier/pages/index.ts +9 -0
  136. package/dist/templates/react-app/config/Identifier/{page.about.ts → pages/page.about.ts} +34 -26
  137. package/dist/templates/react-app/config/Identifier/{page.executor.ts → pages/page.executor.ts} +47 -39
  138. package/dist/templates/{next-app/config/Identifier → react-app/config/Identifier/pages}/page.home.ts +24 -23
  139. package/dist/templates/react-app/config/Identifier/pages/page.identifiter.ts +102 -0
  140. package/dist/templates/react-app/config/Identifier/{page.jsonStorage.ts → pages/page.jsonStorage.ts} +18 -11
  141. package/dist/templates/react-app/config/Identifier/{page.login.ts → pages/page.login.ts} +37 -27
  142. package/dist/templates/react-app/config/Identifier/pages/page.message.ts +20 -0
  143. package/dist/templates/react-app/config/Identifier/{page.register.ts → pages/page.register.ts} +37 -25
  144. package/dist/templates/react-app/config/Identifier/{page.request.ts → pages/page.request.ts} +34 -44
  145. package/dist/templates/react-app/config/app.router.ts +81 -61
  146. package/dist/templates/react-app/config/i18n/PageI18nInterface.ts +51 -0
  147. package/dist/templates/react-app/config/i18n/aboutI18n.ts +42 -0
  148. package/dist/templates/react-app/config/i18n/chatMessageI18n.ts +17 -0
  149. package/dist/templates/react-app/config/i18n/executorI18n.ts +51 -0
  150. package/dist/templates/react-app/config/i18n/homeI18n.ts +24 -0
  151. package/dist/templates/react-app/config/i18n/i18nConfig.ts +30 -0
  152. package/dist/templates/react-app/config/i18n/identifiter18n.ts +30 -0
  153. package/dist/templates/react-app/config/i18n/jsonStorage18n.ts +27 -0
  154. package/dist/templates/react-app/config/i18n/login18n.ts +42 -0
  155. package/dist/templates/react-app/config/i18n/messageBaseListI18n.ts +22 -0
  156. package/dist/templates/react-app/config/i18n/messageI18n.ts +14 -0
  157. package/dist/templates/react-app/config/i18n/notFoundI18n.ts +34 -0
  158. package/dist/templates/react-app/config/i18n/register18n.ts +40 -0
  159. package/dist/templates/react-app/config/i18n/request18n.ts +41 -0
  160. package/dist/templates/react-app/config/theme.ts +14 -4
  161. package/dist/templates/react-app/docs/en/bootstrap.md +1670 -341
  162. package/dist/templates/react-app/docs/en/components/chat-message-component.md +314 -0
  163. package/dist/templates/react-app/docs/en/components/chat-message-refactor.md +270 -0
  164. package/dist/templates/react-app/docs/en/components/message-base-list-component.md +172 -0
  165. package/dist/templates/react-app/docs/en/development-guide.md +1021 -345
  166. package/dist/templates/react-app/docs/en/env.md +1132 -278
  167. package/dist/templates/react-app/docs/en/i18n.md +858 -147
  168. package/dist/templates/react-app/docs/en/index.md +733 -104
  169. package/dist/templates/react-app/docs/en/ioc.md +1228 -287
  170. package/dist/templates/react-app/docs/en/playwright/e2e-tests.md +321 -0
  171. package/dist/templates/react-app/docs/en/playwright/index.md +19 -0
  172. package/dist/templates/react-app/docs/en/playwright/installation-summary.md +332 -0
  173. package/dist/templates/react-app/docs/en/playwright/overview.md +222 -0
  174. package/dist/templates/react-app/docs/en/playwright/quickstart.md +325 -0
  175. package/dist/templates/react-app/docs/en/playwright/reorganization-notes.md +340 -0
  176. package/dist/templates/react-app/docs/en/playwright/setup-complete.md +290 -0
  177. package/dist/templates/react-app/docs/en/playwright/testing-guide.md +565 -0
  178. package/dist/templates/react-app/docs/en/store.md +1194 -184
  179. package/dist/templates/react-app/docs/en/why-no-globals.md +797 -0
  180. package/dist/templates/react-app/docs/zh/bootstrap.md +1670 -341
  181. package/dist/templates/react-app/docs/zh/components/chat-message-component.md +314 -0
  182. package/dist/templates/react-app/docs/zh/components/chat-message-refactor.md +270 -0
  183. package/dist/templates/react-app/docs/zh/components/message-base-list-component.md +172 -0
  184. package/dist/templates/react-app/docs/zh/development-guide.md +1021 -345
  185. package/dist/templates/react-app/docs/zh/env.md +1132 -275
  186. package/dist/templates/react-app/docs/zh/i18n.md +858 -147
  187. package/dist/templates/react-app/docs/zh/index.md +717 -104
  188. package/dist/templates/react-app/docs/zh/ioc.md +1229 -287
  189. package/dist/templates/react-app/docs/zh/playwright/e2e-tests.md +321 -0
  190. package/dist/templates/react-app/docs/zh/playwright/index.md +19 -0
  191. package/dist/templates/react-app/docs/zh/playwright/installation-summary.md +332 -0
  192. package/dist/templates/react-app/docs/zh/playwright/overview.md +222 -0
  193. package/dist/templates/react-app/docs/zh/playwright/quickstart.md +325 -0
  194. package/dist/templates/react-app/docs/zh/playwright/reorganization-notes.md +340 -0
  195. package/dist/templates/react-app/docs/zh/playwright/setup-complete.md +290 -0
  196. package/dist/templates/react-app/docs/zh/playwright/testing-guide.md +565 -0
  197. package/dist/templates/react-app/docs/zh/store.md +1192 -184
  198. package/dist/templates/react-app/docs/zh/why-no-globals.md +797 -0
  199. package/dist/templates/react-app/e2e/App.spec.ts +319 -0
  200. package/dist/templates/react-app/e2e/fixtures/base.fixture.ts +40 -0
  201. package/dist/templates/react-app/e2e/main.spec.ts +20 -0
  202. package/dist/templates/react-app/e2e/utils/test-helpers.ts +19 -0
  203. package/dist/templates/react-app/eslint.config.mjs +247 -0
  204. package/dist/templates/react-app/makes/eslint-utils.mjs +195 -0
  205. package/dist/templates/react-app/makes/generateTs2LocalesOptions.ts +26 -0
  206. package/dist/templates/react-app/package.json +31 -3
  207. package/dist/templates/react-app/playwright.config.ts +79 -0
  208. package/dist/templates/react-app/public/locales/en/common.json +233 -179
  209. package/dist/templates/react-app/public/locales/zh/common.json +233 -179
  210. package/dist/templates/react-app/src/App.tsx +15 -42
  211. package/dist/templates/react-app/src/base/apis/AiApi.ts +5 -5
  212. package/dist/templates/react-app/src/base/apis/feApi/FeApi.ts +1 -1
  213. package/dist/templates/react-app/src/base/apis/feApi/FeApiAdapter.ts +1 -1
  214. package/dist/templates/react-app/src/base/apis/feApi/FeApiBootstarp.ts +8 -8
  215. package/dist/templates/react-app/src/base/apis/feApi/FeApiType.ts +1 -1
  216. package/dist/templates/react-app/src/base/apis/userApi/UserApi.ts +6 -6
  217. package/dist/templates/react-app/src/base/apis/userApi/UserApiAdapter.ts +1 -1
  218. package/dist/templates/react-app/src/base/apis/userApi/UserApiBootstarp.ts +12 -14
  219. package/dist/templates/react-app/src/base/apis/userApi/UserApiType.ts +1 -1
  220. package/dist/templates/react-app/src/base/cases/DialogHandler.ts +5 -2
  221. package/dist/templates/react-app/src/base/cases/I18nKeyErrorPlugin.ts +3 -3
  222. package/dist/templates/react-app/src/base/cases/InversifyContainer.ts +3 -3
  223. package/dist/templates/react-app/src/base/cases/RequestLanguages.ts +2 -2
  224. package/dist/templates/react-app/src/base/cases/RequestLogger.ts +4 -4
  225. package/dist/templates/react-app/src/base/cases/RequestStatusCatcher.ts +1 -1
  226. package/dist/templates/react-app/src/base/cases/ResourceState.ts +23 -0
  227. package/dist/templates/react-app/src/base/cases/RouterLoader.ts +4 -4
  228. package/dist/templates/react-app/src/base/cases/TranslateI18nInterface.ts +26 -0
  229. package/dist/templates/react-app/src/base/port/ExecutorPageBridgeInterface.ts +2 -3
  230. package/dist/templates/react-app/src/base/port/I18nServiceInterface.ts +1 -1
  231. package/dist/templates/react-app/src/base/port/IOCInterface.ts +36 -0
  232. package/dist/templates/react-app/src/base/port/JSONStoragePageBridgeInterface.ts +2 -1
  233. package/dist/templates/react-app/src/base/port/ProcesserExecutorInterface.ts +1 -1
  234. package/dist/templates/react-app/src/base/port/RequestPageBridgeInterface.ts +2 -2
  235. package/dist/templates/react-app/src/base/port/RouteServiceInterface.ts +9 -5
  236. package/dist/templates/react-app/src/base/port/UserServiceInterface.ts +1 -1
  237. package/dist/templates/react-app/src/base/services/I18nService.ts +29 -29
  238. package/dist/templates/react-app/src/base/services/IdentifierService.ts +143 -0
  239. package/dist/templates/react-app/src/base/services/ProcesserExecutor.ts +3 -3
  240. package/dist/templates/react-app/src/base/services/RouteService.ts +27 -8
  241. package/dist/templates/react-app/src/base/services/UserService.ts +8 -8
  242. package/dist/templates/react-app/src/base/types/Page.ts +14 -2
  243. package/dist/templates/react-app/src/base/types/global.d.ts +1 -1
  244. package/dist/templates/react-app/src/core/IOC.ts +5 -46
  245. package/dist/templates/react-app/src/core/bootstraps/{BootstrapApp.ts → BootstrapClient.ts} +44 -17
  246. package/dist/templates/react-app/src/core/bootstraps/BootstrapsRegistry.ts +14 -7
  247. package/dist/templates/react-app/src/core/bootstraps/IocIdentifierTest.ts +1 -1
  248. package/dist/templates/react-app/src/core/bootstraps/PrintBootstrap.ts +1 -1
  249. package/dist/templates/react-app/src/core/clientIoc/ClientIOC.ts +40 -0
  250. package/dist/templates/react-app/src/core/{IocRegisterImpl.ts → clientIoc/ClientIOCRegister.ts} +35 -24
  251. package/dist/templates/react-app/src/core/globals.ts +9 -9
  252. package/dist/templates/react-app/src/main.tsx +4 -4
  253. package/dist/templates/react-app/src/pages/404.tsx +6 -3
  254. package/dist/templates/react-app/src/pages/500.tsx +5 -2
  255. package/dist/templates/react-app/src/pages/NoRouteFound.tsx +5 -0
  256. package/dist/templates/react-app/src/pages/auth/Layout.tsx +9 -6
  257. package/dist/templates/react-app/src/pages/auth/LoginPage.tsx +46 -56
  258. package/dist/templates/react-app/src/pages/auth/RegisterPage.tsx +46 -58
  259. package/dist/templates/react-app/src/pages/base/AboutPage.tsx +35 -40
  260. package/dist/templates/react-app/src/pages/base/ExecutorPage.tsx +51 -51
  261. package/dist/templates/react-app/src/pages/base/HomePage.tsx +14 -15
  262. package/dist/templates/react-app/src/pages/base/IdentifierPage.tsx +70 -11
  263. package/dist/templates/react-app/src/pages/base/JSONStoragePage.tsx +24 -25
  264. package/dist/templates/react-app/src/pages/base/Layout.tsx +2 -2
  265. package/dist/templates/react-app/src/pages/base/MessagePage.tsx +40 -0
  266. package/dist/templates/react-app/src/pages/base/RedirectPathname.tsx +3 -2
  267. package/dist/templates/react-app/src/pages/base/RequestPage.tsx +41 -59
  268. package/dist/templates/react-app/src/styles/css/antd-themes/{_default.css → _common/_default.css} +85 -0
  269. package/dist/templates/react-app/src/styles/css/antd-themes/{dark.css → _common/dark.css} +99 -0
  270. package/dist/templates/react-app/src/styles/css/antd-themes/_common/index.css +3 -0
  271. package/dist/templates/react-app/src/styles/css/antd-themes/{pink.css → _common/pink.css} +86 -0
  272. package/dist/templates/react-app/src/styles/css/antd-themes/index.css +4 -3
  273. package/dist/templates/react-app/src/styles/css/antd-themes/menu/_default.css +108 -0
  274. package/dist/templates/react-app/src/styles/css/antd-themes/menu/dark.css +67 -0
  275. package/dist/templates/react-app/src/styles/css/antd-themes/menu/index.css +3 -0
  276. package/dist/templates/react-app/src/styles/css/antd-themes/menu/pink.css +67 -0
  277. package/dist/templates/react-app/src/styles/css/antd-themes/pagination/_default.css +34 -0
  278. package/dist/templates/react-app/src/styles/css/antd-themes/pagination/dark.css +31 -0
  279. package/dist/templates/react-app/src/styles/css/antd-themes/pagination/index.css +3 -0
  280. package/dist/templates/react-app/src/styles/css/antd-themes/pagination/pink.css +36 -0
  281. package/dist/templates/react-app/src/styles/css/antd-themes/table/_default.css +44 -0
  282. package/dist/templates/react-app/src/styles/css/antd-themes/table/dark.css +43 -0
  283. package/dist/templates/react-app/src/styles/css/antd-themes/table/index.css +3 -0
  284. package/dist/templates/react-app/src/styles/css/antd-themes/table/pink.css +43 -0
  285. package/dist/templates/react-app/src/styles/css/page.css +4 -3
  286. package/dist/templates/react-app/src/styles/css/themes/_default.css +1 -0
  287. package/dist/templates/react-app/src/styles/css/themes/dark.css +1 -0
  288. package/dist/templates/react-app/src/styles/css/themes/pink.css +1 -0
  289. package/dist/templates/react-app/src/styles/css/zIndex.css +1 -1
  290. package/dist/templates/react-app/src/uikit/bridges/ExecutorPageBridge.ts +3 -3
  291. package/dist/templates/react-app/src/uikit/bridges/JSONStoragePageBridge.ts +2 -2
  292. package/dist/templates/react-app/src/uikit/bridges/NavigateBridge.ts +1 -1
  293. package/dist/templates/react-app/src/uikit/bridges/RequestPageBridge.ts +3 -3
  294. package/dist/templates/react-app/src/uikit/components/AppRouterProvider.tsx +35 -0
  295. package/dist/templates/react-app/src/uikit/components/BaseHeader.tsx +15 -11
  296. package/dist/templates/react-app/src/uikit/components/BaseRouteProvider.tsx +14 -11
  297. package/dist/templates/react-app/src/uikit/components/BaseRouteSeo.tsx +18 -0
  298. package/dist/templates/react-app/src/uikit/components/BootstrapsProvider.tsx +13 -0
  299. package/dist/templates/react-app/src/uikit/components/ClientSeo.tsx +62 -0
  300. package/dist/templates/react-app/src/uikit/components/ComboProvider.tsx +38 -0
  301. package/dist/templates/react-app/src/uikit/components/LanguageSwitcher.tsx +48 -27
  302. package/dist/templates/react-app/src/uikit/components/Loading.tsx +4 -2
  303. package/dist/templates/react-app/src/uikit/components/LocaleLink.tsx +4 -5
  304. package/dist/templates/react-app/src/uikit/components/LogoutButton.tsx +34 -11
  305. package/dist/templates/react-app/src/uikit/components/MessageBaseList.tsx +240 -0
  306. package/dist/templates/react-app/src/uikit/components/ProcessExecutorProvider.tsx +9 -5
  307. package/dist/templates/react-app/src/uikit/components/RouterRenderComponent.tsx +6 -3
  308. package/dist/templates/react-app/src/uikit/components/ThemeSwitcher.tsx +97 -40
  309. package/dist/templates/react-app/src/uikit/components/UserAuthProvider.tsx +5 -5
  310. package/dist/templates/react-app/src/uikit/components/With.tsx +17 -0
  311. package/dist/templates/react-app/src/uikit/components/chatMessage/ChatMessageBridge.ts +176 -0
  312. package/dist/templates/react-app/src/uikit/components/chatMessage/ChatRoot.tsx +21 -0
  313. package/dist/templates/react-app/src/uikit/components/chatMessage/FocusBar.tsx +106 -0
  314. package/dist/templates/react-app/src/uikit/components/chatMessage/MessageApi.ts +271 -0
  315. package/dist/templates/react-app/src/uikit/components/chatMessage/MessageItem.tsx +102 -0
  316. package/dist/templates/react-app/src/uikit/components/chatMessage/MessagesList.tsx +86 -0
  317. package/dist/templates/react-app/src/uikit/contexts/BaseRouteContext.ts +17 -11
  318. package/dist/templates/react-app/src/uikit/contexts/IOCContext.ts +13 -0
  319. package/dist/templates/react-app/src/uikit/hooks/useAppTranslation.ts +26 -0
  320. package/dist/templates/react-app/src/uikit/hooks/useI18nGuard.ts +8 -11
  321. package/dist/templates/react-app/src/uikit/hooks/useI18nInterface.ts +25 -0
  322. package/dist/templates/react-app/src/uikit/hooks/useIOC.ts +35 -0
  323. package/dist/templates/react-app/src/uikit/hooks/useNavigateBridge.ts +3 -3
  324. package/dist/templates/react-app/src/uikit/hooks/useStrictEffect.ts +0 -1
  325. package/dist/templates/react-app/tsconfig.e2e.json +21 -0
  326. package/dist/templates/react-app/tsconfig.json +8 -1
  327. package/dist/templates/react-app/tsconfig.node.json +1 -1
  328. package/dist/templates/react-app/tsconfig.test.json +3 -1
  329. package/dist/templates/react-app/vite.config.ts +50 -34
  330. package/package.json +2 -1
  331. package/dist/configs/react-app/eslint.config.js +0 -94
  332. package/dist/templates/next-app/config/Identifier/common.error.ts +0 -41
  333. package/dist/templates/next-app/config/Identifier/common.ts +0 -69
  334. package/dist/templates/next-app/config/Identifier/page.about.ts +0 -181
  335. package/dist/templates/next-app/config/Identifier/page.admin.ts +0 -48
  336. package/dist/templates/next-app/config/Identifier/page.executor.ts +0 -272
  337. package/dist/templates/next-app/config/Identifier/page.identifiter.ts +0 -39
  338. package/dist/templates/next-app/config/Identifier/page.jsonStorage.ts +0 -72
  339. package/dist/templates/next-app/config/Identifier/page.request.ts +0 -182
  340. package/dist/templates/next-app/src/base/cases/ChatAction.ts +0 -21
  341. package/dist/templates/next-app/src/base/cases/FocusBarAction.ts +0 -36
  342. package/dist/templates/next-app/src/base/cases/RequestState.ts +0 -20
  343. package/dist/templates/next-app/src/base/port/AdminPageInterface.ts +0 -85
  344. package/dist/templates/next-app/src/base/port/AsyncStateInterface.ts +0 -7
  345. package/dist/templates/next-app/src/base/services/AdminUserService.ts +0 -45
  346. package/dist/templates/next-app/src/uikit/components/ChatRoot.tsx +0 -17
  347. package/dist/templates/next-app/src/uikit/components/chat/ChatActionInterface.ts +0 -30
  348. package/dist/templates/next-app/src/uikit/components/chat/ChatFocusBar.tsx +0 -65
  349. package/dist/templates/next-app/src/uikit/components/chat/ChatMessages.tsx +0 -59
  350. package/dist/templates/next-app/src/uikit/components/chat/ChatWrap.tsx +0 -28
  351. package/dist/templates/next-app/src/uikit/components/chat/FocusBarActionInterface.ts +0 -19
  352. package/dist/templates/next-app/src/uikit/hook/useMountedClient.ts +0 -17
  353. package/dist/templates/next-app/src/uikit/hook/useStore.ts +0 -15
  354. package/dist/templates/react-app/__tests__/__mocks__/I18nService.ts +0 -13
  355. package/dist/templates/react-app/__tests__/src/App.test.tsx +0 -139
  356. package/dist/templates/react-app/config/Identifier/page.identifiter.ts +0 -39
  357. package/dist/templates/react-app/config/i18n.ts +0 -15
  358. package/dist/templates/react-app/docs/en/project-structure.md +0 -434
  359. package/dist/templates/react-app/docs/zh/project-structure.md +0 -434
  360. package/dist/templates/react-app/src/base/cases/RequestState.ts +0 -20
  361. package/dist/templates/react-app/src/base/port/AsyncStateInterface.ts +0 -7
  362. package/dist/templates/react-app/src/uikit/hooks/useDocumentTitle.ts +0 -15
  363. package/dist/templates/react-app/src/uikit/hooks/useStore.ts +0 -15
@@ -1,7 +1,7 @@
1
- import type { AppConfig } from '@/base/cases/AppConfig';
2
1
  import { IOCIdentifier } from '@config/IOCIdentifier';
3
2
  import { RequestAdapterFetch } from '@qlover/fe-corekit';
4
3
  import { inject, injectable } from 'inversify';
4
+ import type { AppConfig } from '@/base/cases/AppConfig';
5
5
 
6
6
  @injectable()
7
7
  export class UserApiAdapter extends RequestAdapterFetch {
@@ -1,13 +1,4 @@
1
- import {
2
- FetchAbortPlugin,
3
- RequestAdapterConfig,
4
- RequestAdapterResponse,
5
- RequestTransactionInterface
6
- } from '@qlover/fe-corekit';
7
- import { IOC } from '@/core/IOC';
8
1
  import { IOCIdentifier } from '@config/IOCIdentifier';
9
- import { RequestLogger } from '@/base/cases/RequestLogger';
10
- import { FetchURLPlugin } from '@qlover/fe-corekit';
11
2
  import {
12
3
  type BootstrapContext,
13
4
  type BootstrapExecutorPlugin,
@@ -15,8 +6,15 @@ import {
15
6
  type ApiCatchPluginConfig,
16
7
  type ApiCatchPluginResponse
17
8
  } from '@qlover/corekit-bridge';
9
+ import { FetchAbortPlugin, FetchURLPlugin } from '@qlover/fe-corekit';
10
+ import { RequestLogger } from '@/base/cases/RequestLogger';
18
11
  import { UserApi } from './UserApi';
19
12
  import { RequestLanguages } from '../../cases/RequestLanguages';
13
+ import type {
14
+ RequestAdapterConfig,
15
+ RequestAdapterResponse,
16
+ RequestTransactionInterface
17
+ } from '@qlover/fe-corekit';
20
18
 
21
19
  /**
22
20
  * UserApiConfig
@@ -68,13 +66,13 @@ export class UserApiBootstarp implements BootstrapExecutorPlugin {
68
66
  ioc
69
67
  .get<UserApi>(UserApi)
70
68
  .usePlugin(new FetchURLPlugin())
71
- .usePlugin(IOC.get(IOCIdentifier.FeApiCommonPlugin))
69
+ .usePlugin(ioc.get(IOCIdentifier.FeApiCommonPlugin))
72
70
  .usePlugin(
73
71
  new RequestLanguages(ioc.get(IOCIdentifier.I18nServiceInterface))
74
72
  )
75
- .usePlugin(IOC.get(IOCIdentifier.ApiMockPlugin))
76
- .usePlugin(IOC.get(RequestLogger))
77
- .usePlugin(IOC.get(FetchAbortPlugin))
78
- .usePlugin(IOC.get(IOCIdentifier.ApiCatchPlugin));
73
+ .usePlugin(ioc.get(IOCIdentifier.ApiMockPlugin))
74
+ .usePlugin(ioc.get(RequestLogger))
75
+ .usePlugin(ioc.get(FetchAbortPlugin))
76
+ .usePlugin(ioc.get(IOCIdentifier.ApiCatchPlugin));
79
77
  }
80
78
  }
@@ -1,4 +1,4 @@
1
- import { UserApiTransaction } from './UserApiBootstarp';
1
+ import type { UserApiTransaction } from './UserApiBootstarp';
2
2
 
3
3
  export type UserInfo = {
4
4
  name: string;
@@ -4,8 +4,11 @@ import type {
4
4
  ModalApi,
5
5
  NotificationApi
6
6
  } from '@brain-toolkit/antd-theme-override/react';
7
- import { UIDialogInterface, NotificationOptions } from '@qlover/corekit-bridge';
8
- import { ModalFuncProps } from 'antd';
7
+ import type {
8
+ UIDialogInterface,
9
+ NotificationOptions
10
+ } from '@qlover/corekit-bridge';
11
+ import type { ModalFuncProps } from 'antd';
9
12
 
10
13
  export interface DialogHandlerOptions
11
14
  extends NotificationOptions,
@@ -1,8 +1,8 @@
1
- import type { ExecutorContext, ExecutorPlugin } from '@qlover/fe-corekit';
2
- import type { LoggerInterface } from '@qlover/logger';
3
- import { inject, injectable } from 'inversify';
4
1
  import { IOCIdentifier } from '@config/IOCIdentifier';
2
+ import { inject, injectable } from 'inversify';
5
3
  import type { I18nServiceInterface } from '../port/I18nServiceInterface';
4
+ import type { ExecutorContext, ExecutorPlugin } from '@qlover/fe-corekit';
5
+ import type { LoggerInterface } from '@qlover/logger';
6
6
 
7
7
  /**
8
8
  * When throw error, it will be converted to i18n key
@@ -1,9 +1,9 @@
1
- import { IOCIdentifierMap } from '@config/IOCIdentifier';
2
- import {
1
+ import { Container } from 'inversify';
2
+ import type { IOCIdentifierMap } from '@config/IOCIdentifier';
3
+ import type {
3
4
  IOCContainerInterface,
4
5
  ServiceIdentifier
5
6
  } from '@qlover/corekit-bridge';
6
- import { Container } from 'inversify';
7
7
 
8
8
  export class InversifyContainer implements IOCContainerInterface {
9
9
  protected container: Container;
@@ -1,5 +1,5 @@
1
- import { I18nServiceInterface } from '@/base/port/I18nServiceInterface';
2
- import {
1
+ import type { I18nServiceInterface } from '@/base/port/I18nServiceInterface';
2
+ import type {
3
3
  ExecutorContext,
4
4
  ExecutorPlugin,
5
5
  RequestAdapterConfig
@@ -1,14 +1,14 @@
1
1
  import { IOCIdentifier } from '@config/IOCIdentifier';
2
+ import {
3
+ type ApiCatchPluginConfig,
4
+ type ApiCatchPluginResponse
5
+ } from '@qlover/corekit-bridge';
2
6
  import {
3
7
  type ExecutorPlugin,
4
8
  type ExecutorContext,
5
9
  type RequestAdapterFetchConfig,
6
10
  type RequestAdapterResponse
7
11
  } from '@qlover/fe-corekit';
8
- import {
9
- type ApiCatchPluginConfig,
10
- type ApiCatchPluginResponse
11
- } from '@qlover/corekit-bridge';
12
12
  import { injectable, inject } from 'inversify';
13
13
  import type { LoggerInterface } from '@qlover/logger';
14
14
 
@@ -1,8 +1,8 @@
1
1
  import { IOCIdentifier } from '@config/IOCIdentifier';
2
+ import { inject, injectable } from 'inversify';
2
3
  import type { RequestCatcherInterface } from '@qlover/corekit-bridge';
3
4
  import type { RequestAdapterResponse } from '@qlover/fe-corekit';
4
5
  import type { LoggerInterface } from '@qlover/logger';
5
- import { inject, injectable } from 'inversify';
6
6
 
7
7
  @injectable()
8
8
  export class RequestStatusCatcher
@@ -0,0 +1,23 @@
1
+ import { RequestState } from '@qlover/corekit-bridge';
2
+ import type {
3
+ ResourceQuery,
4
+ ResourceStateInterface
5
+ } from '@qlover/corekit-bridge';
6
+
7
+ export interface PaginationInterface<T> {
8
+ list: T[];
9
+ total: number;
10
+ page: number;
11
+ pageSize: number;
12
+ }
13
+
14
+ export class ResourceState implements ResourceStateInterface {
15
+ searchParams: ResourceQuery = {
16
+ page: 1,
17
+ pageSize: 10,
18
+ orderBy: 'updated_at',
19
+ order: 1
20
+ };
21
+ initState = new RequestState<unknown>();
22
+ listState = new RequestState<PaginationInterface<unknown>>();
23
+ }
@@ -1,8 +1,8 @@
1
- import type { ComponentType, LazyExoticComponent, ReactNode } from 'react';
2
- import { RouteObject } from 'react-router-dom';
3
1
  import isString from 'lodash/isString';
4
- import { RouteMeta } from '../types/Page';
5
- import { LoggerInterface } from '@qlover/logger';
2
+ import type { RouteMeta } from '../types/Page';
3
+ import type { LoggerInterface } from '@qlover/logger';
4
+ import type { ComponentType, LazyExoticComponent, ReactNode } from 'react';
5
+ import type { RouteObject } from 'react-router-dom';
6
6
 
7
7
  /**
8
8
  * Component mapping type for lazy-loaded components
@@ -0,0 +1,26 @@
1
+ import type { PageI18nInterface } from '@config/i18n/PageI18nInterface';
2
+ import type { TFunction } from 'i18next';
3
+
4
+ /**
5
+ * Translate I18n Interface tools class
6
+ *
7
+ * @param i18nInterface - The i18n interface to translate
8
+ * @param t - The translations function
9
+ * @returns The translated i18n interface
10
+ */
11
+ export class TranslateI18nInterface {
12
+ static translate<T extends PageI18nInterface | Record<string, string>>(
13
+ source: T,
14
+ t: TFunction<string, string>
15
+ ): T {
16
+ return Object.fromEntries(
17
+ Object.entries(source).map(([key, value]) => {
18
+ if (typeof value === 'string') {
19
+ // 禁用命名空间分隔符,避免冒号被解析为命名空间
20
+ return [key, t(value, { nsSeparator: false })];
21
+ }
22
+ return [key, value];
23
+ })
24
+ ) as T;
25
+ }
26
+ }
@@ -1,8 +1,7 @@
1
- import { StoreInterface, StoreStateInterface } from '@qlover/corekit-bridge';
2
- import { RequestState } from '../cases/RequestState';
1
+ import { StoreInterface } from '@qlover/corekit-bridge';
2
+ import type { StoreStateInterface, RequestState } from '@qlover/corekit-bridge';
3
3
 
4
4
  export interface ExecutorPageStateInterface extends StoreStateInterface {
5
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
6
5
  helloState: RequestState<any>;
7
6
  }
8
7
 
@@ -1,4 +1,4 @@
1
- import { BootstrapExecutorPlugin } from '@qlover/corekit-bridge';
1
+ import type { BootstrapExecutorPlugin } from '@qlover/corekit-bridge';
2
2
 
3
3
  export interface I18nServiceInterface extends BootstrapExecutorPlugin {
4
4
  t(key: string, params?: Record<string, unknown>): string;
@@ -0,0 +1,36 @@
1
+ import type {
2
+ EnvConfigInterface,
3
+ IOCContainerInterface,
4
+ IOCFunctionInterface,
5
+ IOCRegisterInterface
6
+ } from '@qlover/corekit-bridge';
7
+
8
+ /**
9
+ * IOC register options
10
+ */
11
+ export type IocRegisterOptions = {
12
+ /**
13
+ * The pathname of the current page
14
+ */
15
+ pathname: string;
16
+
17
+ /**
18
+ * The app config
19
+ */
20
+ appConfig: EnvConfigInterface;
21
+ };
22
+
23
+ export interface IOCInterface<
24
+ IdentifierMap,
25
+ IOCContainer extends IOCContainerInterface
26
+ > {
27
+ create(
28
+ options: IocRegisterOptions
29
+ ): IOCFunctionInterface<IdentifierMap, IOCContainer>;
30
+ }
31
+
32
+ /**
33
+ * 提供一个快捷的注册器类型名
34
+ */
35
+ export interface IOCRegister
36
+ extends IOCRegisterInterface<IOCContainerInterface, IocRegisterOptions> {}
@@ -1,4 +1,5 @@
1
- import { StoreInterface, StoreStateInterface } from '@qlover/corekit-bridge';
1
+ import { StoreInterface } from '@qlover/corekit-bridge';
2
+ import type { StoreStateInterface } from '@qlover/corekit-bridge';
2
3
 
3
4
  export interface JSONStoragePageStateInterface extends StoreStateInterface {
4
5
  testKey1?: number;
@@ -1,4 +1,4 @@
1
- import { ExecutorPlugin } from '@qlover/fe-corekit';
1
+ import type { ExecutorPlugin } from '@qlover/fe-corekit';
2
2
 
3
3
  export interface ProcesserExecutorInterface extends ExecutorPlugin {
4
4
  /**
@@ -1,5 +1,5 @@
1
- import { StoreInterface, StoreStateInterface } from '@qlover/corekit-bridge';
2
- import { RequestState } from '../cases/RequestState';
1
+ import { StoreInterface } from '@qlover/corekit-bridge';
2
+ import type { StoreStateInterface, RequestState } from '@qlover/corekit-bridge';
3
3
 
4
4
  export interface RequestPageStateInterface extends StoreStateInterface {
5
5
  helloState: RequestState<unknown>;
@@ -1,10 +1,10 @@
1
- import {
1
+ import { StoreInterface } from '@qlover/corekit-bridge';
2
+ import type { RouteConfigValue } from '../cases/RouterLoader';
3
+ import type {
2
4
  LoggerInterface,
3
- StoreInterface,
4
5
  StoreStateInterface
5
6
  } from '@qlover/corekit-bridge';
6
- import { RouteConfigValue } from '../cases/RouterLoader';
7
- import { NavigateFunction, NavigateOptions } from 'react-router-dom';
7
+ import type { NavigateFunction, NavigateOptions } from 'react-router-dom';
8
8
 
9
9
  export interface RouteServiceStateInterface extends StoreStateInterface {
10
10
  routes: RouteConfigValue[];
@@ -23,5 +23,9 @@ export abstract class RouteServiceInterface extends StoreInterface<RouteServiceS
23
23
  abstract gotoLogin(): void;
24
24
  abstract replaceToHome(): void;
25
25
  abstract redirectToDefault(navigate: NavigateFunction): void;
26
- abstract i18nGuard(lng: string, navigate: NavigateFunction): void;
26
+ abstract i18nGuard(
27
+ currentPath: string,
28
+ lng: string,
29
+ navigate?: NavigateFunction
30
+ ): void;
27
31
  }
@@ -1,6 +1,6 @@
1
1
  import { UserAuthService } from '@qlover/corekit-bridge';
2
- import { ExecutorPlugin } from '@qlover/fe-corekit';
3
2
  import type { UserInfo } from '@/base/apis/userApi/UserApiType';
3
+ import type { ExecutorPlugin } from '@qlover/fe-corekit';
4
4
 
5
5
  export abstract class UserServiceInterface
6
6
  extends UserAuthService<UserInfo>
@@ -1,23 +1,23 @@
1
- import i18n from 'i18next';
2
- import { initReactI18next } from 'react-i18next';
3
- import LanguageDetector from 'i18next-browser-languagedetector';
4
- import HttpApi from 'i18next-http-backend';
5
- import merge from 'lodash/merge';
6
- import i18nConfig from '@config/i18n';
1
+ /* eslint-disable import/no-named-as-default-member */
2
+ import { useLocaleRoutes } from '@config/common';
3
+ import { i18nConfig } from '@config/i18n/i18nConfig';
7
4
  import {
8
5
  type StoreStateInterface,
9
6
  StoreInterface
10
7
  } from '@qlover/corekit-bridge';
11
- import { useLocaleRoutes } from '@config/common';
12
- import { I18nServiceInterface } from '../port/I18nServiceInterface';
8
+ import i18n from 'i18next';
9
+ import LanguageDetector from 'i18next-browser-languagedetector';
10
+ import HttpApi from 'i18next-http-backend';
11
+ import merge from 'lodash/merge';
12
+ import { initReactI18next } from 'react-i18next';
13
+ import type { LocaleType } from '@config/i18n/i18nConfig';
14
+ import type { I18nServiceInterface } from '../port/I18nServiceInterface';
13
15
 
14
16
  const { supportedLngs, fallbackLng } = i18nConfig;
15
17
 
16
- export type I18nServiceLocale = (typeof supportedLngs)[number];
17
-
18
18
  export class I18nServiceState implements StoreStateInterface {
19
19
  loading: boolean = false;
20
- constructor(public language: I18nServiceLocale) {}
20
+ constructor(public language: LocaleType) {}
21
21
  }
22
22
 
23
23
  export class I18nService
@@ -27,11 +27,12 @@ export class I18nService
27
27
  readonly pluginName = 'I18nService';
28
28
 
29
29
  selector = {
30
- loading: (state: I18nServiceState) => state.loading
30
+ loading: (state: I18nServiceState) => state.loading,
31
+ language: (state: I18nServiceState) => state.language
31
32
  };
32
33
 
33
34
  constructor(protected pathname: string) {
34
- super(() => new I18nServiceState(i18n.language as I18nServiceLocale));
35
+ super(() => new I18nServiceState(i18n.language as LocaleType));
35
36
  }
36
37
 
37
38
  /**
@@ -70,31 +71,30 @@ export class I18nService
70
71
  }
71
72
 
72
73
  return fallbackLng;
73
- },
74
- cacheUserLanguage(lng: string) {
75
- // Only cache language if not using locale routes
76
- if (!useLocaleRoutes) {
77
- localStorage.setItem('i18nextLng', lng);
78
- }
79
74
  }
80
75
  };
81
76
  i18n.services.languageDetector.addDetector(pathLanguageDetector);
77
+
78
+ // Sync i18n.language with state.language
79
+ i18n.on('languageChanged', (lng: string) => {
80
+ if (this.isValidLanguage(lng) && this.state.language !== lng) {
81
+ this.emit({ ...this.state, language: lng as LocaleType });
82
+ }
83
+ });
82
84
  }
83
85
 
84
- async changeLanguage(language: I18nServiceLocale): Promise<void> {
86
+ async changeLanguage(language: LocaleType): Promise<void> {
85
87
  await i18n.changeLanguage(language);
86
- // 如果不使用本地化路由,则保存语言设置到本地存储
87
- if (!useLocaleRoutes) {
88
- localStorage.setItem('i18nextLng', language);
89
- }
88
+ // Sync state with i18n.language
89
+ this.emit({ ...this.state, language });
90
90
  }
91
91
 
92
92
  changeLoading(loading: boolean): void {
93
93
  this.emit({ ...this.state, loading });
94
94
  }
95
95
 
96
- getCurrentLanguage(): I18nServiceLocale {
97
- return i18n.language as I18nServiceLocale;
96
+ getCurrentLanguage(): LocaleType {
97
+ return i18n.language as LocaleType;
98
98
  }
99
99
 
100
100
  /**
@@ -102,11 +102,11 @@ export class I18nService
102
102
  * @param language - language to check
103
103
  * @returns true if the language is supported, false otherwise
104
104
  */
105
- isValidLanguage(language: string): language is I18nServiceLocale {
106
- return supportedLngs.includes(language as I18nServiceLocale);
105
+ isValidLanguage(language: string): language is LocaleType {
106
+ return supportedLngs.includes(language as LocaleType);
107
107
  }
108
108
 
109
- getSupportedLanguages(): I18nServiceLocale[] {
109
+ getSupportedLanguages(): LocaleType[] {
110
110
  return [...supportedLngs];
111
111
  }
112
112
 
@@ -0,0 +1,143 @@
1
+ import { routerPrefix } from '@config/common';
2
+ import { I } from '@config/IOCIdentifier';
3
+ import {
4
+ RequestState,
5
+ type ResourceStateInterface,
6
+ type ResourceServiceInterface,
7
+ type ResourceInterface,
8
+ type ResourceQuery,
9
+ ResourceStore
10
+ } from '@qlover/corekit-bridge';
11
+ import { inject, injectable } from 'inversify';
12
+ import type { LocaleType } from '@config/i18n/i18nConfig';
13
+ import { I18nService } from './I18nService';
14
+ import { PaginationInterface, ResourceState } from '../cases/ResourceState';
15
+
16
+ export interface IdentifierRecord {
17
+ id: string;
18
+ locale: LocaleType;
19
+ localeValue: string;
20
+ }
21
+
22
+ @injectable()
23
+ export class IdentifierService<T>
24
+ implements ResourceServiceInterface<T, ResourceStore<ResourceStateInterface>>
25
+ {
26
+ readonly unionKey: string = 'id';
27
+ readonly serviceName: string = 'IdentifierService';
28
+ readonly store: ResourceStore<ResourceStateInterface>;
29
+ // Not implemented
30
+ readonly resourceApi!: ResourceInterface<T>;
31
+ private unsubscribe: (() => void) | null = null;
32
+
33
+ constructor(
34
+ @inject(I.I18nServiceInterface)
35
+ protected readonly i18nService: I18nService
36
+ ) {
37
+ this.store = new ResourceStore(() => new ResourceState());
38
+ }
39
+
40
+ getStore(): ResourceStore<ResourceStateInterface> {
41
+ return this.store;
42
+ }
43
+
44
+ protected async init(): Promise<unknown> {
45
+ this.store.changeInitState(new RequestState(true));
46
+
47
+ try {
48
+ const result = await this.search({
49
+ locale: this.i18nService.getCurrentLanguage() as LocaleType
50
+ });
51
+
52
+ this.store.changeInitState(new RequestState(false, result).end());
53
+ return result;
54
+ } catch (error) {
55
+ this.store.changeInitState(new RequestState(false, null, error).end());
56
+
57
+ return error;
58
+ }
59
+ }
60
+
61
+ /**
62
+ * @override
63
+ */
64
+ async created(): Promise<unknown> {
65
+ this.unsubscribe = this.i18nService.observe(
66
+ (state) => state.language,
67
+ () => {
68
+ this.init();
69
+ }
70
+ );
71
+
72
+ return this.init();
73
+ }
74
+
75
+ /**
76
+ * @override
77
+ */
78
+ destroyed(): void {
79
+ this.unsubscribe?.();
80
+ this.unsubscribe = null;
81
+
82
+ this.store.reset();
83
+ }
84
+
85
+ /**
86
+ * @override
87
+ */
88
+ updated(): void {}
89
+
90
+ async search(
91
+ params: Partial<ResourceQuery & { locale: LocaleType }>
92
+ ): Promise<PaginationInterface<IdentifierRecord>> {
93
+ this.store.changeListState(
94
+ new RequestState(true, this.store.state.listState.result)
95
+ );
96
+
97
+ const locale = params.locale!;
98
+
99
+ const response = await fetch(
100
+ `${routerPrefix}/locales/${locale}/common.json`
101
+ );
102
+ const data = await response.json();
103
+
104
+ let index = 0;
105
+ const resultList: IdentifierRecord[] = Object.entries(data).map(
106
+ ([key, value]) => ({
107
+ index: (index += 1),
108
+ id: key,
109
+ locale: locale,
110
+ localeValue: value as string
111
+ })
112
+ );
113
+
114
+ const result: PaginationInterface<IdentifierRecord> = {
115
+ list: resultList,
116
+ total: resultList.length,
117
+ page: 1,
118
+ pageSize: 10
119
+ };
120
+
121
+ this.store.changeListState(new RequestState(false, result).end());
122
+
123
+ return result;
124
+ }
125
+
126
+ refresh(): Promise<unknown> {
127
+ return this.search(this.store.state.searchParams);
128
+ }
129
+
130
+ async update(_data: Partial<T>): Promise<unknown> {
131
+ return Promise.resolve(null);
132
+ }
133
+
134
+ create(_data: T): Promise<unknown> {
135
+ return Promise.resolve(null);
136
+ }
137
+ remove(_data: T): Promise<unknown> {
138
+ return Promise.resolve(null);
139
+ }
140
+ export(_data: T): Promise<unknown> {
141
+ return Promise.resolve(null);
142
+ }
143
+ }
@@ -1,14 +1,14 @@
1
+ import { IOCIdentifier } from '@config/IOCIdentifier';
1
2
  import {
2
3
  AsyncExecutor,
3
4
  ExecutorContext,
4
5
  ExecutorPlugin
5
6
  } from '@qlover/fe-corekit';
6
- import { IOCIdentifier } from '@config/IOCIdentifier';
7
7
  import { injectable, inject } from 'inversify';
8
- import type { LoggerInterface } from '@qlover/logger';
9
8
  import type { ProcesserExecutorInterface } from '../port/ProcesserExecutorInterface';
10
- import type { BootstrapContextValue } from '@qlover/corekit-bridge';
11
9
  import type { RouteServiceInterface } from '../port/RouteServiceInterface';
10
+ import type { BootstrapContextValue } from '@qlover/corekit-bridge';
11
+ import type { LoggerInterface } from '@qlover/logger';
12
12
 
13
13
  @injectable()
14
14
  export class ProcesserExecutor implements ProcesserExecutorInterface {
@@ -1,14 +1,16 @@
1
+ import { i18nConfig } from '@config/i18n/i18nConfig';
1
2
  import type { RouteConfigValue } from '@/base/cases/RouterLoader';
2
- import type { NavigateFunction, NavigateOptions } from 'react-router-dom';
3
- import type { LoggerInterface } from '@qlover/logger';
4
3
  import { RouteServiceInterface } from '../port/RouteServiceInterface';
4
+ import type { I18nServiceInterface } from '../port/I18nServiceInterface';
5
5
  import type {
6
6
  UIBridgeInterface,
7
7
  StoreStateInterface
8
8
  } from '@qlover/corekit-bridge';
9
- import { I18nServiceInterface } from '../port/I18nServiceInterface';
9
+ import type { LoggerInterface } from '@qlover/logger';
10
+ import type { NavigateFunction, NavigateOptions } from 'react-router-dom';
10
11
 
11
12
  export type RouterServiceOptions = {
13
+ routerPrefix: string;
12
14
  routes: RouteConfigValue[];
13
15
  /**
14
16
  * Whether to use locale routes
@@ -82,15 +84,32 @@ export class RouteService extends RouteServiceInterface {
82
84
  this.goto('/', { replace: true, navigate });
83
85
  }
84
86
 
85
- override i18nGuard(lng: string, navigate?: NavigateFunction): void {
87
+ override i18nGuard(
88
+ currentPath: string,
89
+ lng: string,
90
+ navigate?: NavigateFunction
91
+ ): void {
92
+ // 只在使用本地化路由时才检查
86
93
  if (!this.state.localeRoutes) {
87
94
  return;
88
95
  }
89
96
 
90
- if (!lng) {
91
- this.goto('/404', { replace: true, navigate });
92
- } else if (!this.i18nService.isValidLanguage(lng)) {
93
- this.goto('/404', { replace: true, navigate });
97
+ const _navigate = navigate || this.uiBridge.getUIBridge();
98
+
99
+ lng = lng || i18nConfig.fallbackLng;
100
+
101
+ // 如果没有语言参数或语言无效
102
+ if (!this.i18nService.isValidLanguage(lng)) {
103
+ // 重定向到默认语言?
104
+ if (i18nConfig.noValidRedirectFallbackLng) {
105
+ const newPath = currentPath.replace(lng, i18nConfig.fallbackLng);
106
+
107
+ _navigate?.(newPath, { replace: true });
108
+ return;
109
+ }
110
+
111
+ // 不支持的语言直接404
112
+ _navigate?.('/404', { replace: true });
94
113
  }
95
114
  }
96
115
  }