cx-chat 0.0.1

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 (404) hide show
  1. package/.cursor/rules/i18n-cn-gloss-comments.mdc +31 -0
  2. package/.cursor/rules/list-page-view-pageconfig.mdc +32 -0
  3. package/.cursor/rules/no-over-defensive-programming.mdc +90 -0
  4. package/.cursor/rules/requirement-description-for-agent.mdc +33 -0
  5. package/.cursor/rules/use-showToast-not-antd-message.mdc +28 -0
  6. package/.docker/Dockerfile +7 -0
  7. package/.env +9 -0
  8. package/.env.development +7 -0
  9. package/.env.production +7 -0
  10. package/.gitlab-ci/docker-build.yaml +28 -0
  11. package/.gitlab-ci/k8s-deploy-dev-master.yaml +42 -0
  12. package/.gitlab-ci/npm-build.yaml +17 -0
  13. package/.gitlab-ci.yml +8 -0
  14. package/.k8s/0-namespace.yaml +6 -0
  15. package/.k8s/1-configmap-web.yaml +7 -0
  16. package/.k8s/1-nginx-conf-dev.yaml +110 -0
  17. package/.k8s/2-deployment.yaml +27 -0
  18. package/.k8s/3-service.yaml +16 -0
  19. package/.k8s/4-ingress-dev.yaml +30 -0
  20. package/.lingma/rules/use-showToast-not-antd-message.md +34 -0
  21. package/.nginx/nginx.conf +52 -0
  22. package/.prettierrc +9 -0
  23. package/README.md +1 -0
  24. package/eslint.config.js +32 -0
  25. package/index.html +13 -0
  26. package/package.json +67 -0
  27. package/postcss.config.js +6 -0
  28. package/public/favicon.ico +0 -0
  29. package/public/vite.svg +1 -0
  30. package/src/App.tsx +96 -0
  31. package/src/_doc/0.docs-overview.md +28 -0
  32. package/src/_doc/cx-ui/0.docs-overview.md +30 -0
  33. package/src/_doc/cx-ui/comp.1.cx-ui-overview.md +82 -0
  34. package/src/_doc/cx-ui/comp.2.cx-modal.md +82 -0
  35. package/src/_doc/cx-ui/comp.3.cx-button.md +89 -0
  36. package/src/_doc/cx-ui/comp.4.cx-form.md +72 -0
  37. package/src/_doc/cx-ui/comp.5.cx-fields.md +76 -0
  38. package/src/_doc/cx-ui/comp.6.cx-tag.md +57 -0
  39. package/src/_doc/cx-ui/comp.7.cx-empty-state.md +29 -0
  40. package/src/_doc/meta/0.docs-overview.md +24 -0
  41. package/src/_doc/meta/comp.1.enum-runtime.md +33 -0
  42. package/src/_doc/meta/comp.2.dict-runtime.md +39 -0
  43. package/src/_doc/router/0.docs-overview.md +14 -0
  44. package/src/_doc/router/guide.1.menu-component-config.md +181 -0
  45. package/src/_doc/router/guide.2.router-auto-registration.md +114 -0
  46. package/src/_doc/table-view/0.docs-overview.md +30 -0
  47. package/src/_doc/table-view/comp.1.table-view.md +542 -0
  48. package/src/_doc/table-view/props.1.create-table-view-config.md +193 -0
  49. package/src/_doc/table-view/props.2.table-view-search-fields.md +106 -0
  50. package/src/api/_mock/README.md +340 -0
  51. package/src/api/_mock/api.ts +1642 -0
  52. package/src/api/_mock/bundle-shim.ts +16 -0
  53. package/src/api/_mock/handler-shim.ts +6 -0
  54. package/src/api/_mock/handler.ts +458 -0
  55. package/src/api/_mock/index.ts +711 -0
  56. package/src/api/_mock/interceptor.ts +15 -0
  57. package/src/api/_mock/mod.ts +12 -0
  58. package/src/api/_mock/utils.ts +65 -0
  59. package/src/api/base/memory.js +24 -0
  60. package/src/api/chat.js +210 -0
  61. package/src/api/common/auth.js +70 -0
  62. package/src/api/menus/business-rules.js +76 -0
  63. package/src/api/menus/feedback.js +102 -0
  64. package/src/api/menus/knowledge.js +159 -0
  65. package/src/api/menus/model-metadata/manage.js +70 -0
  66. package/src/api/menus/model-metadata/role.js +50 -0
  67. package/src/api/menus/model-metadata/training-detail-mock-data.js +569 -0
  68. package/src/api/menus/model-metadata/training.js +28 -0
  69. package/src/api/menus/skill.js +40 -0
  70. package/src/api/system/agent-config.js +16 -0
  71. package/src/api/system/department.js +94 -0
  72. package/src/api/system/dict.js +86 -0
  73. package/src/api/system/menu.js +37 -0
  74. package/src/api/system/permission.js +26 -0
  75. package/src/api/system/role.js +34 -0
  76. package/src/api/system/sys-config.js +16 -0
  77. package/src/api/system/sys-log.js +17 -0
  78. package/src/api/system/user.js +75 -0
  79. package/src/api/upload.js +39 -0
  80. package/src/assets/react.svg +1 -0
  81. package/src/components/auth/current-user-avatar.tsx +77 -0
  82. package/src/components/common/code-view.tsx +149 -0
  83. package/src/components/common/detail-link.tsx +67 -0
  84. package/src/components/common/error-boundary.tsx +98 -0
  85. package/src/components/common/language-switcher.tsx +91 -0
  86. package/src/components/common/lite-table/index.tsx +135 -0
  87. package/src/components/common/md-editor.tsx +126 -0
  88. package/src/components/common/modal/confirm-dialog.tsx +113 -0
  89. package/src/components/common/modal/dep-user-select-multi.tsx +324 -0
  90. package/src/components/common/modal/dep-user-select.tsx +249 -0
  91. package/src/components/common/modal/user-select-multi.tsx +266 -0
  92. package/src/components/common/pagination.tsx +472 -0
  93. package/src/components/common/path.tsx +175 -0
  94. package/src/components/common/system-logo-mark.tsx +48 -0
  95. package/src/components/cx-ui/button/index.less +208 -0
  96. package/src/components/cx-ui/button/index.tsx +611 -0
  97. package/src/components/cx-ui/checkbox/index.tsx +78 -0
  98. package/src/components/cx-ui/date-picker/index.less +17 -0
  99. package/src/components/cx-ui/date-picker/index.tsx +193 -0
  100. package/src/components/cx-ui/drawer/index.tsx +47 -0
  101. package/src/components/cx-ui/empty-state/index.tsx +20 -0
  102. package/src/components/cx-ui/floating-shell/CxFloatingShell.tsx +89 -0
  103. package/src/components/cx-ui/floating-shell/cx-floating-shell.less +283 -0
  104. package/src/components/cx-ui/floating-shell/has-floating-value.ts +41 -0
  105. package/src/components/cx-ui/form/CxForm.tsx +15 -0
  106. package/src/components/cx-ui/form/index.tsx +20 -0
  107. package/src/components/cx-ui/form-item/index.less +26 -0
  108. package/src/components/cx-ui/form-item/index.tsx +36 -0
  109. package/src/components/cx-ui/index.ts +70 -0
  110. package/src/components/cx-ui/input/auto-complete.tsx +134 -0
  111. package/src/components/cx-ui/input/index.tsx +259 -0
  112. package/src/components/cx-ui/input-number/index.jsx +66 -0
  113. package/src/components/cx-ui/modal/index.jsx +212 -0
  114. package/src/components/cx-ui/modal/index.less +144 -0
  115. package/src/components/cx-ui/modal/useCxModal.ts +125 -0
  116. package/src/components/cx-ui/multi-select/index.jsx +74 -0
  117. package/src/components/cx-ui/multi-select/index.less +40 -0
  118. package/src/components/cx-ui/multi-select/index2.tsx +361 -0
  119. package/src/components/cx-ui/radio/index.tsx +33 -0
  120. package/src/components/cx-ui/range-picker/index.less +65 -0
  121. package/src/components/cx-ui/range-picker/index.tsx +219 -0
  122. package/src/components/cx-ui/select/index.less +34 -0
  123. package/src/components/cx-ui/select/index.tsx +196 -0
  124. package/src/components/cx-ui/skeleton/index.tsx +12 -0
  125. package/src/components/cx-ui/steps/index.tsx +14 -0
  126. package/src/components/cx-ui/styles/_tokens.less +79 -0
  127. package/src/components/cx-ui/styles/index.less +246 -0
  128. package/src/components/cx-ui/switch/index.less +106 -0
  129. package/src/components/cx-ui/switch/index.tsx +120 -0
  130. package/src/components/cx-ui/table/index.less +160 -0
  131. package/src/components/cx-ui/table/index.tsx +152 -0
  132. package/src/components/cx-ui/tabs/index.less +15 -0
  133. package/src/components/cx-ui/tabs/index.tsx +34 -0
  134. package/src/components/cx-ui/tag/index.less +51 -0
  135. package/src/components/cx-ui/tag/index.tsx +140 -0
  136. package/src/components/cx-ui/timeline/index.tsx +14 -0
  137. package/src/components/cx-ui/tooltip/index.tsx +67 -0
  138. package/src/components/cx-ui/tree/index.tsx +193 -0
  139. package/src/components/cx-ui/tree-select/index.jsx +91 -0
  140. package/src/components/cx-ui/tree-select/index.less +27 -0
  141. package/src/components/cx-ui/upload-file/index.less +223 -0
  142. package/src/components/cx-ui/upload-file/index.tsx +640 -0
  143. package/src/components/cx-ui/upload-img/index.tsx +291 -0
  144. package/src/components/layout/components/Header.tsx +216 -0
  145. package/src/components/layout/components/Sidebar.tsx +717 -0
  146. package/src/components/layout/index.tsx +95 -0
  147. package/src/components/table-view/components/search-area.tsx +411 -0
  148. package/src/components/table-view/components/table-view-config.tsx +528 -0
  149. package/src/components/table-view/components/table-view.types.ts +478 -0
  150. package/src/components/table-view/components/tree-api-normalize.ts +38 -0
  151. package/src/components/table-view/components/tree-data-annotate.ts +31 -0
  152. package/src/components/table-view/components/tree-sidebar.tsx +74 -0
  153. package/src/components/table-view/index.tsx +61 -0
  154. package/src/components/table-view/list-page-view.tsx +1049 -0
  155. package/src/components/table-view/select-table-view.tsx +1094 -0
  156. package/src/components/table-view/styles/select-table-view.less +51 -0
  157. package/src/config/default-system-name.ts +9 -0
  158. package/src/config/system.ts +165 -0
  159. package/src/constants/countryCodes.ts +3 -0
  160. package/src/contexts/AuthContext.tsx +256 -0
  161. package/src/contexts/ChatContext.tsx +839 -0
  162. package/src/contexts/MenuContext.tsx +62 -0
  163. package/src/contexts/ToastContext.tsx +181 -0
  164. package/src/hooks/useCopyToClipboard.ts +47 -0
  165. package/src/hooks/useModalSubmit.ts +104 -0
  166. package/src/hooks/useRouter.ts +240 -0
  167. package/src/hooks/useStepForm.ts +46 -0
  168. package/src/hooks/useStickyHeader.ts +42 -0
  169. package/src/hooks/useThreadActions.ts +105 -0
  170. package/src/hooks/useUserPreferences.ts +101 -0
  171. package/src/http/axios.js +372 -0
  172. package/src/http/mock.interceptor.ts +9 -0
  173. package/src/http/obfuscationKey.ts +41 -0
  174. package/src/i18n.ts +60 -0
  175. package/src/index.js +1 -0
  176. package/src/index.less +169 -0
  177. package/src/locales/en/auth.ts +70 -0
  178. package/src/locales/en/base/memory.ts +28 -0
  179. package/src/locales/en/base/settings.ts +41 -0
  180. package/src/locales/en/chat.ts +40 -0
  181. package/src/locales/en/common.ts +173 -0
  182. package/src/locales/en/enum.ts +27 -0
  183. package/src/locales/en/menus/business-rules.ts +48 -0
  184. package/src/locales/en/menus/feedback.ts +62 -0
  185. package/src/locales/en/menus/knowledge.ts +120 -0
  186. package/src/locales/en/menus/model-metadata/index.ts +10 -0
  187. package/src/locales/en/menus/model-metadata/manage.ts +151 -0
  188. package/src/locales/en/menus/model-metadata/role.ts +48 -0
  189. package/src/locales/en/menus/model-metadata/training.ts +65 -0
  190. package/src/locales/en/menus/skill.ts +34 -0
  191. package/src/locales/en/system/agent-config.ts +34 -0
  192. package/src/locales/en/system/department.ts +68 -0
  193. package/src/locales/en/system/dict.ts +44 -0
  194. package/src/locales/en/system/menu.ts +45 -0
  195. package/src/locales/en/system/permission.ts +89 -0
  196. package/src/locales/en/system/role.ts +25 -0
  197. package/src/locales/en/system/sys-config.ts +33 -0
  198. package/src/locales/en/system/sys-log.ts +38 -0
  199. package/src/locales/en/system/user.ts +113 -0
  200. package/src/locales/en.ts +68 -0
  201. package/src/locales/zh/auth.ts +70 -0
  202. package/src/locales/zh/base/memory.ts +29 -0
  203. package/src/locales/zh/base/settings.ts +41 -0
  204. package/src/locales/zh/chat.ts +47 -0
  205. package/src/locales/zh/common.ts +178 -0
  206. package/src/locales/zh/enum.ts +28 -0
  207. package/src/locales/zh/menus/business-rules.ts +47 -0
  208. package/src/locales/zh/menus/feedback.ts +62 -0
  209. package/src/locales/zh/menus/knowledge.ts +117 -0
  210. package/src/locales/zh/menus/model-metadata/index.ts +10 -0
  211. package/src/locales/zh/menus/model-metadata/manage.ts +151 -0
  212. package/src/locales/zh/menus/model-metadata/role.ts +47 -0
  213. package/src/locales/zh/menus/model-metadata/training.ts +64 -0
  214. package/src/locales/zh/menus/skill.ts +34 -0
  215. package/src/locales/zh/system/agent-config.ts +33 -0
  216. package/src/locales/zh/system/department.ts +69 -0
  217. package/src/locales/zh/system/dict.ts +44 -0
  218. package/src/locales/zh/system/menu.ts +47 -0
  219. package/src/locales/zh/system/permission.ts +94 -0
  220. package/src/locales/zh/system/role.ts +25 -0
  221. package/src/locales/zh/system/sys-config.ts +32 -0
  222. package/src/locales/zh/system/sys-log.ts +38 -0
  223. package/src/locales/zh/system/user.ts +114 -0
  224. package/src/locales/zh.ts +67 -0
  225. package/src/main.tsx +50 -0
  226. package/src/meta/const/index.ts +40 -0
  227. package/src/meta/index-dict.ts +56 -0
  228. package/src/meta/index-enum.ts +95 -0
  229. package/src/meta/index.ts +14 -0
  230. package/src/meta/module/dict-data/runtime.ts +199 -0
  231. package/src/meta/module/dict-data/types.ts +17 -0
  232. package/src/meta/module/enum-data/runtime.ts +75 -0
  233. package/src/meta/module/enum-data/types.ts +18 -0
  234. package/src/router/index.tsx +312 -0
  235. package/src/styles/AntdThemeProvider.tsx +40 -0
  236. package/src/styles/antd-theme.ts +20 -0
  237. package/src/styles/global.less +107 -0
  238. package/src/styles/variable.less +103 -0
  239. package/src/types/feedback.ts +43 -0
  240. package/src/types/index.ts +85 -0
  241. package/src/types/menu.ts +43 -0
  242. package/src/utils/aesUtil.ts +123 -0
  243. package/src/utils/chatUtils.ts +524 -0
  244. package/src/utils/cn.ts +6 -0
  245. package/src/utils/crypto.ts +164 -0
  246. package/src/utils/date.ts +72 -0
  247. package/src/utils/file-icons.tsx +79 -0
  248. package/src/utils/index.ts +168 -0
  249. package/src/utils/markdown-math-plugins.ts +21 -0
  250. package/src/utils/menuI18n.ts +305 -0
  251. package/src/utils/menuRouteRegistry.ts +78 -0
  252. package/src/utils/permission-crud.ts +147 -0
  253. package/src/utils/routeConfig.ts +350 -0
  254. package/src/utils/storage.ts +135 -0
  255. package/src/utils/toastBridge.ts +26 -0
  256. package/src/utils/url.ts +38 -0
  257. package/src/utils/validation.ts +16 -0
  258. package/src/views/auth/auth-code/index.less +169 -0
  259. package/src/views/auth/auth-code/index.module.less +174 -0
  260. package/src/views/auth/auth-code/index.tsx +233 -0
  261. package/src/views/auth/login.tsx +498 -0
  262. package/src/views/auth/register.tsx +388 -0
  263. package/src/views/base/memory/index.tsx +136 -0
  264. package/src/views/base/memory/modal/detail-modal.tsx +89 -0
  265. package/src/views/base/memory/modal/submit-modal.tsx +134 -0
  266. package/src/views/base/settings/index.tsx +657 -0
  267. package/src/views/chat/chat.less +323 -0
  268. package/src/views/chat/components/chat-input.tsx +298 -0
  269. package/src/views/chat/components/header-thread-title.tsx +210 -0
  270. package/src/views/chat/components/message-list/content-answer.tsx +100 -0
  271. package/src/views/chat/components/message-list/content-question.tsx +18 -0
  272. package/src/views/chat/components/message-list/index.tsx +520 -0
  273. package/src/views/chat/components/message-list/message-item.tsx +199 -0
  274. package/src/views/chat/components/message-list/preparation-demo-items.ts +147 -0
  275. package/src/views/chat/components/message-list/preparation-steps.tsx +506 -0
  276. package/src/views/chat/components/message-list/suggestion-list.tsx +36 -0
  277. package/src/views/chat/components/message-list/thinking-process.tsx +49 -0
  278. package/src/views/chat/components/message-list/toolbar.tsx +224 -0
  279. package/src/views/chat/components/message-list/use-message-list-scroll.ts +214 -0
  280. package/src/views/chat/components/references-knowledge/context.tsx +57 -0
  281. package/src/views/chat/components/references-knowledge/index.ts +9 -0
  282. package/src/views/chat/components/references-knowledge/modal/knowledge-detail-drawer.tsx +556 -0
  283. package/src/views/chat/components/references-knowledge/modal/knowledge-doc-detail-drawer.tsx +529 -0
  284. package/src/views/chat/components/references-knowledge/panel.tsx +115 -0
  285. package/src/views/chat/hooks/use-chat-common.ts +19 -0
  286. package/src/views/chat/index-session.tsx +647 -0
  287. package/src/views/chat/index.tsx +127 -0
  288. package/src/views/page-error/401.tsx +56 -0
  289. package/src/views/page-error/404.tsx +56 -0
  290. package/src/views/page-menus/business-rules/index.tsx +376 -0
  291. package/src/views/page-menus/business-rules/modal/detail-modal.tsx +186 -0
  292. package/src/views/page-menus/business-rules/modal/scope-modal.tsx +272 -0
  293. package/src/views/page-menus/business-rules/modal/submit-modal.tsx +142 -0
  294. package/src/views/page-menus/feedback/components/feedback-dataset-list.tsx +471 -0
  295. package/src/views/page-menus/feedback/index.tsx +166 -0
  296. package/src/views/page-menus/feedback/modal/export-feedback-modal.tsx +367 -0
  297. package/src/views/page-menus/knowledge/components/doc-editor-by-type.tsx +32 -0
  298. package/src/views/page-menus/knowledge/components/doc-editor-type-file.tsx +330 -0
  299. package/src/views/page-menus/knowledge/detail.tsx +600 -0
  300. package/src/views/page-menus/knowledge/index.tsx +337 -0
  301. package/src/views/page-menus/knowledge/modal/detail-modal.tsx +618 -0
  302. package/src/views/page-menus/knowledge/modal/doc-detail-modal.tsx +550 -0
  303. package/src/views/page-menus/knowledge/modal/doc-parse.ts +99 -0
  304. package/src/views/page-menus/knowledge/modal/doc-submit-modal.tsx +349 -0
  305. package/src/views/page-menus/knowledge/modal/doc-type-picker-modal.tsx +88 -0
  306. package/src/views/page-menus/knowledge/modal/knowledge-user-select-modal.tsx +283 -0
  307. package/src/views/page-menus/knowledge/modal/submit-modal.tsx +179 -0
  308. package/src/views/page-menus/model-metadata/manage/components/metadata-detail-schema-tab.tsx +114 -0
  309. package/src/views/page-menus/model-metadata/manage/components/step1-basic-info.tsx +232 -0
  310. package/src/views/page-menus/model-metadata/manage/components/step2-schema.tsx +316 -0
  311. package/src/views/page-menus/model-metadata/manage/components/step3-permissions.tsx +134 -0
  312. package/src/views/page-menus/model-metadata/manage/components/step4-documents.tsx +134 -0
  313. package/src/views/page-menus/model-metadata/manage/components/step5-example-sql.tsx +101 -0
  314. package/src/views/page-menus/model-metadata/manage/components/submit-add.tsx +338 -0
  315. package/src/views/page-menus/model-metadata/manage/components/submit-edit.tsx +276 -0
  316. package/src/views/page-menus/model-metadata/manage/detail.tsx +298 -0
  317. package/src/views/page-menus/model-metadata/manage/hooks/model-metadata-submit-shared.ts +113 -0
  318. package/src/views/page-menus/model-metadata/manage/hooks/use-model-metadata-item-state.ts +20 -0
  319. package/src/views/page-menus/model-metadata/manage/index.tsx +304 -0
  320. package/src/views/page-menus/model-metadata/manage/modal/components/table-schema.ts +374 -0
  321. package/src/views/page-menus/model-metadata/manage/modal/components/use-table-detail-tabs.tsx +151 -0
  322. package/src/views/page-menus/model-metadata/manage/modal/components/use-table-submit-tabs.tsx +423 -0
  323. package/src/views/page-menus/model-metadata/manage/modal/detail-modal.tsx +218 -0
  324. package/src/views/page-menus/model-metadata/manage/modal/submit-modal.tsx +261 -0
  325. package/src/views/page-menus/model-metadata/manage/modal/table-detail-modal.tsx +196 -0
  326. package/src/views/page-menus/model-metadata/manage/modal/table-submit-modal.tsx +229 -0
  327. package/src/views/page-menus/model-metadata/manage/submit.tsx +31 -0
  328. package/src/views/page-menus/model-metadata/role/index.tsx +207 -0
  329. package/src/views/page-menus/model-metadata/role/modal/detail-modal.tsx +97 -0
  330. package/src/views/page-menus/model-metadata/role/modal/role-assign-users-modal.tsx +254 -0
  331. package/src/views/page-menus/model-metadata/role/modal/role-assign-users-panel.tsx +393 -0
  332. package/src/views/page-menus/model-metadata/role/modal/role-assign-users-utils.ts +120 -0
  333. package/src/views/page-menus/model-metadata/role/modal/role-permission-assign-panel.tsx +698 -0
  334. package/src/views/page-menus/model-metadata/role/modal/role-permission-modal.tsx +237 -0
  335. package/src/views/page-menus/model-metadata/role/modal/submit-modal.tsx +135 -0
  336. package/src/views/page-menus/model-metadata/training/components/detail-records/index.ts +4 -0
  337. package/src/views/page-menus/model-metadata/training/components/detail-records/node-card.tsx +72 -0
  338. package/src/views/page-menus/model-metadata/training/components/detail-records/summary-lines.ts +196 -0
  339. package/src/views/page-menus/model-metadata/training/components/detail-records/summary-list.tsx +153 -0
  340. package/src/views/page-menus/model-metadata/training/components/detail-records/timeline.tsx +103 -0
  341. package/src/views/page-menus/model-metadata/training/components/detail-records/types.ts +82 -0
  342. package/src/views/page-menus/model-metadata/training/detail.tsx +159 -0
  343. package/src/views/page-menus/model-metadata/training/index.tsx +236 -0
  344. package/src/views/page-menus/model-metadata/training/modal/update-detail-modal.tsx +154 -0
  345. package/src/views/page-menus/skill/index.tsx +201 -0
  346. package/src/views/page-menus/skill/modal/detail-modal.tsx +156 -0
  347. package/src/views/page-menus/skill/modal/submit-modal.tsx +214 -0
  348. package/src/views/page-system/agent-config/index.tsx +370 -0
  349. package/src/views/page-system/department/departmentFormShared.ts +36 -0
  350. package/src/views/page-system/department/index.tsx +541 -0
  351. package/src/views/page-system/department/modal/detail-modal.tsx +94 -0
  352. package/src/views/page-system/department/modal/member-role-modal.tsx +128 -0
  353. package/src/views/page-system/department/modal/submit-modal.tsx +265 -0
  354. package/src/views/page-system/dict/index.tsx +440 -0
  355. package/src/views/page-system/dict/modal/cate-submit-modal.tsx +315 -0
  356. package/src/views/page-system/dict/modal/submit-modal.tsx +184 -0
  357. package/src/views/page-system/logs/components/index.ts +3 -0
  358. package/src/views/page-system/logs/components/log-message-demo.tsx +30 -0
  359. package/src/views/page-system/logs/components/log-message-stream.ts +184 -0
  360. package/src/views/page-system/logs/components/message-list/content-answer.tsx +100 -0
  361. package/src/views/page-system/logs/components/message-list/content-question.tsx +18 -0
  362. package/src/views/page-system/logs/components/message-list/index.tsx +515 -0
  363. package/src/views/page-system/logs/components/message-list/message-item.tsx +193 -0
  364. package/src/views/page-system/logs/components/message-list/preparation-demo-items.ts +147 -0
  365. package/src/views/page-system/logs/components/message-list/preparation-steps.tsx +506 -0
  366. package/src/views/page-system/logs/components/message-list/suggestion-list.tsx +36 -0
  367. package/src/views/page-system/logs/components/message-list/thinking-process.tsx +49 -0
  368. package/src/views/page-system/logs/components/message-list/toolbar.tsx +134 -0
  369. package/src/views/page-system/logs/components/message-list/use-message-list-scroll.ts +214 -0
  370. package/src/views/page-system/logs/components/message-modal.tsx +239 -0
  371. package/src/views/page-system/logs/index.tsx +132 -0
  372. package/src/views/page-system/logs/modal/detail-modal.tsx +157 -0
  373. package/src/views/page-system/menu/components/menuFormShared.ts +283 -0
  374. package/src/views/page-system/menu/index.less +12 -0
  375. package/src/views/page-system/menu/index.tsx +410 -0
  376. package/src/views/page-system/menu/modal/icon-modal.less +51 -0
  377. package/src/views/page-system/menu/modal/icon-modal.tsx +87 -0
  378. package/src/views/page-system/menu/modal/submit-modal.tsx +263 -0
  379. package/src/views/page-system/permission/index.tsx +562 -0
  380. package/src/views/page-system/permission/modal/detail-modal.tsx +179 -0
  381. package/src/views/page-system/permission/modal/submit-modal.less +146 -0
  382. package/src/views/page-system/permission/modal/submit-modal.tsx +650 -0
  383. package/src/views/page-system/role/index.tsx +163 -0
  384. package/src/views/page-system/role/modal/detail-modal.tsx +127 -0
  385. package/src/views/page-system/role/modal/permission-assign-group-rules.ts +86 -0
  386. package/src/views/page-system/role/modal/permission-modal.tsx +111 -0
  387. package/src/views/page-system/role/modal/role-modal-shell-styles.ts +21 -0
  388. package/src/views/page-system/role/modal/role-permission-assign-panel.tsx +916 -0
  389. package/src/views/page-system/role/modal/role-permission-assign-shared.ts +1047 -0
  390. package/src/views/page-system/role/modal/submit-modal.tsx +193 -0
  391. package/src/views/page-system/sys-config/index.tsx +294 -0
  392. package/src/views/page-system/user/components/user-role-column.tsx +87 -0
  393. package/src/views/page-system/user/index.tsx +439 -0
  394. package/src/views/page-system/user/modal/assign-roles-modal.tsx +389 -0
  395. package/src/views/page-system/user/modal/detail-modal.tsx +72 -0
  396. package/src/views/page-system/user/modal/modal-style/submit-modal.less +40 -0
  397. package/src/views/page-system/user/modal/submit-modal.less +40 -0
  398. package/src/views/page-system/user/modal/submit-modal.tsx +287 -0
  399. package/src/views/page-system/user/userFormShared.ts +51 -0
  400. package/tailwind.config.js +17 -0
  401. package/tsconfig.app.json +48 -0
  402. package/tsconfig.json +11 -0
  403. package/tsconfig.node.json +26 -0
  404. package/vite.config.ts +264 -0
package/src/main.tsx ADDED
@@ -0,0 +1,50 @@
1
+ import React from 'react';
2
+ import ReactDOM from 'react-dom/client';
3
+ import { HashRouter } from 'react-router-dom';
4
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
5
+ import App from './App';
6
+ import ErrorBoundary from './components/common/error-boundary';
7
+ import { AntdThemeProvider } from './styles/AntdThemeProvider';
8
+ import 'katex/dist/katex.min.css'
9
+ import './index.less';
10
+ import './i18n'; // Initialize i18n
11
+
12
+ import { mockManager } from '@api/_mock';
13
+ import { loadUnauthDictData, publicDictsReady } from '@/meta';
14
+ import { loadSystemConfigOnBoot } from '@/config/system';
15
+
16
+ const queryClient = new QueryClient();
17
+
18
+ // Mock:与 Vite `VITE_ENABLE_MOCK` 一致;生产默认关闭(见 `.env.production`)
19
+ const shouldEnableMock =
20
+ import.meta.env.MODE === 'production'
21
+ ? import.meta.env.VITE_ENABLE_MOCK === 'true'
22
+ : import.meta.env.VITE_ENABLE_MOCK !== 'false'
23
+ if (shouldEnableMock) {
24
+ mockManager.enable(300)
25
+ } else {
26
+ mockManager.disable()
27
+ }
28
+
29
+ /** 应用启动加载:免登录字典 + 系统配置(同步 await,避免首屏品牌信息闪烁)。 */
30
+ async function bootstrap() {
31
+ loadUnauthDictData()
32
+ await publicDictsReady
33
+ await loadSystemConfigOnBoot()
34
+ }
35
+
36
+ bootstrap().finally(() => {
37
+ ReactDOM.createRoot(document.getElementById('root')!).render(
38
+ <React.StrictMode>
39
+ <ErrorBoundary>
40
+ <AntdThemeProvider>
41
+ <QueryClientProvider client={queryClient}>
42
+ <HashRouter>
43
+ <App />
44
+ </HashRouter>
45
+ </QueryClientProvider>
46
+ </AntdThemeProvider>
47
+ </ErrorBoundary>
48
+ </React.StrictMode>
49
+ );
50
+ })
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Tag / 枚举条 / HTTP 方法等小色块用色(十六进制)。
3
+ * 与 `src/styles/antd-theme.ts` 的 `token.colorSuccess | colorWarning | colorError | colorInfo` 同源;
4
+ * 该文件从本常量注入主题,改色只改此处即可。
5
+ */
6
+ export const TAG_COLOR = {
7
+ success: '#22c55e',
8
+ warning: '#f59e0b',
9
+ error: '#ef4444',
10
+ /** 与 colorPrimary / colorInfo 一致 */
11
+ info: '#2563eb',
12
+ /** GET:查询语义,与 info 蓝区分(略偏青) */
13
+ httpGet: '#0284c7',
14
+ } as const
15
+
16
+ export type TagColorKey = keyof typeof TAG_COLOR
17
+
18
+ /**
19
+ * Table 列对齐(antd `ColumnType.align`)
20
+ * 避免在每个列配置中写 align: 'center' as const
21
+ */
22
+
23
+ export const ALIGN = {
24
+ LEFT: 'left' as const,
25
+ CENTER: 'center' as const,
26
+ RIGHT: 'right' as const,
27
+ } as const
28
+
29
+ /**
30
+ * Table 列固定方向(antd `ColumnType.fixed`)
31
+ * 与 {@link ALIGN} 不同:fixed 只有左/右固定,不包含 center。
32
+ */
33
+ export const FIXED = {
34
+ LEFT: 'start' as const,
35
+ RIGHT: 'end' as const,
36
+ } as const
37
+
38
+ /** antd 默认字体栈(用于 httpMethod 等需要与系统字体对齐的场景) */
39
+ export const FONT_FAMILY_ANTD_DEFAULT =
40
+ "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'"
@@ -0,0 +1,56 @@
1
+ /**
2
+ * 数据字典(主入口,对外请 `import … from '@/meta/index-dict'`)。
3
+ *
4
+ * 文档:`src/_doc/meta/comp.2.dict-runtime.md`
5
+ *
6
+ * ## 改配置(本文件下方)
7
+ * 修改 `unauthDictRegistry` / `commonDictRegistry` 即可。
8
+ * 运行时通过 **`initDictDataRuntime({ … })`** 传参注入(见 `./module/dict-data/runtime.ts`),子模块不反向 import 本文件。
9
+ *
10
+ * ## DICT_KEY
11
+ * 映射:前端访问键 → 后台分类 code(与 `DICT_DATA` 槽位 key 一致)。例:`DICT_DATA[DICT_KEY.permission]`。
12
+ *
13
+ * ## DICT_DATA
14
+ * `Record<后台分类code, { option, valueMap, defaultValue }>`;请求未完成前为空,拉取后写入。
15
+ *
16
+ * ## 加载
17
+ * `loadUnauthDictData()` 在应用入口调用;`loadCommonDictData()` 登录后由 Auth 触发。
18
+ * 管理端字典变更后请再调 `loadUnauthDictData()` + `loadCommonDictData(true)` 刷新前端缓存。
19
+ *
20
+ * ## 与 React 同步
21
+ * 使用 `useAuth().commonDictRevision` 或 `registerDictDataLoadedNotifier`。
22
+ */
23
+
24
+ import { initDictDataRuntime } from './module/dict-data/runtime'
25
+
26
+ export type { DictCodeSlot, DictOptionItem, DictRegistryItem } from './module/dict-data/types'
27
+
28
+ // ————————————————————————————————————————————————————————————————————————
29
+ // 免登录字典注册表(键 = 后台分类 code;仅改本段 + 按需调整 constKey)
30
+ // ————————————————————————————————————————————————————————————————————————
31
+ export const unauthDictRegistry = {
32
+ phone_area_code: { constKey: 'phoneArea' },
33
+ } as const
34
+
35
+ // ————————————————————————————————————————————————————————————————————————
36
+ // 登录后 batch 字典注册表
37
+ // ————————————————————————————————————————————————————————————————————————
38
+ export const commonDictRegistry = {
39
+ permission_code: { constKey: 'permission' },
40
+ LLM: { constKey: 'LLM' },
41
+ OCRLLM: { constKey: 'OCRLLM' },
42
+ db_type: { constKey: 'dbType' },
43
+ } as const
44
+
45
+ initDictDataRuntime({ unauthDictRegistry, commonDictRegistry })
46
+
47
+ export type DictAccessKey =
48
+ (typeof unauthDictRegistry)[keyof typeof unauthDictRegistry]['constKey'] |
49
+ (typeof commonDictRegistry)[keyof typeof commonDictRegistry]['constKey']
50
+
51
+ export type DictCategoryCode = keyof typeof unauthDictRegistry | keyof typeof commonDictRegistry
52
+
53
+ export {
54
+ DICT_DATA, DICT_KEY, getDictDefaultValue, getDictOptions, loadCommonDictData, loadUnauthDictData, publicDictsReady, registerCommonDictLoadedNotifier, registerDictDataLoadedNotifier
55
+ } from './module/dict-data/runtime'
56
+
@@ -0,0 +1,95 @@
1
+ /**
2
+ * 静态枚举(主入口,对外请 `import … from '@/meta/index-enum'` 或 `@/meta`)。
3
+ *
4
+ * 文档:`src/_doc/meta/comp.1.enum-runtime.md`
5
+ *
6
+ * 结构与 **`index-dict` 对齐**:注册表 + **`initEnumDataRuntime`**,用 **`ENUM_DATA`** 访问(枚举键稳定,无需再维护「访问键 → 分类 code」映射)。
7
+ *
8
+ * ## 改配置(本文件下方 `enumRegistry`)
9
+ * 键 = 稳定访问键(小驼峰,与 `ENUM_DATA` 槽位 key 一致);值为静态 `{ value, label }[]`,`label` 一般为 i18n key;可选 `color` 会写入该类的 `tagColorMap`(HTTP 方法键为大写)。
10
+ *
11
+ * ## ENUM_DATA
12
+ * 每槽:`option`、`valueMap`(`String(value)` → `label`)、`defaultValue`(当前恒 `''`)、`tagColorMap`。
13
+ *
14
+ * ## 与字典对照
15
+ * - 字典:`DICT_DATA[DICT_KEY.permission].option`、`getDictOptions(DICT_KEY.xxx)`
16
+ * - 枚举:`ENUM_DATA['commonStatus'].option`、`getEnumOptions('commonStatus')`
17
+ */
18
+
19
+ import { TAG_COLOR } from './const'
20
+ import { initEnumDataRuntime } from './module/enum-data/runtime'
21
+
22
+ export type { EnumCodeSlot, EnumOptionItem } from './module/enum-data/types'
23
+
24
+ // ————————————————————————————————————————————————————————————————————————
25
+
26
+ // 静态枚举注册表(键 = 访问键;仅改本段)
27
+
28
+ // ————————————————————————————————————————————————————————————————————————
29
+
30
+ export const enumRegistry = {
31
+ commonStatus: [
32
+ { value: 1, label: 'enum.commonStatus.1' },
33
+ { value: 0, label: 'enum.commonStatus.0' },
34
+ ],
35
+ /** 用户管理状态:1=激活 0=禁用(仅用户管理特例使用) */
36
+ activeStatus: [
37
+ { value: 1, label: 'enum.activeStatus.1' },
38
+ { value: 0, label: 'enum.activeStatus.0' },
39
+ ],
40
+ commonYesNo: [
41
+ { value: 1, label: 'enum.commonYesNo.1' },
42
+ { value: 0, label: 'enum.commonYesNo.0' },
43
+ ],
44
+ /** 0=系统内置 1=基础 2=扩展 */
45
+ permissionApiType: [
46
+ { value: 0, label: 'enum.permissionApiType.0', color: '#64748b' },
47
+ { value: 1, label: 'enum.permissionApiType.1', color: '#2563eb' },
48
+ { value: 2, label: 'enum.permissionApiType.2', color: '#9333ea' },
49
+ ],
50
+ /** HTTP 方法(通用枚举,label 与 value 一致,无需国际化;色见 `TAG_COLOR`) */
51
+ httpMethod: [
52
+ { value: 'GET', label: 'GET', color: TAG_COLOR.httpGet },
53
+ { value: 'POST', label: 'POST', color: TAG_COLOR.success },
54
+ { value: 'PUT', label: 'PUT', color: TAG_COLOR.warning },
55
+ { value: 'DELETE', label: 'DELETE', color: TAG_COLOR.error },
56
+ ],
57
+ /** 审核状态:10 草稿 20 待审核 25 审核中 30 审核通过 40 审核拒绝 */
58
+ auditStatus: [
59
+ { value: 10, label: 'enum.auditStatus.10', color: '#94a3b8', icon: 'FileText' },
60
+ { value: 20, label: 'enum.auditStatus.20', color: '#f59e0b', icon: 'Clock3' },
61
+ { value: 25, label: 'enum.auditStatus.25', color: '#f59e0b', icon: 'Loader2' },
62
+ { value: 30, label: 'enum.auditStatus.30', color: '#10b981', icon: 'CheckCircle2' },
63
+ { value: 40, label: 'enum.auditStatus.40', color: '#ef4444', icon: 'CircleX' },
64
+ ],
65
+ /** 知识库类型:0 个人 1 可公开(label 复用菜单 i18n key) */
66
+ knowledgeType: [
67
+ { value: 0, label: 'menus.knowledge.type_personal', color: 'blue' },
68
+ { value: 1, label: 'menus.knowledge.type_public', color: 'green' },
69
+ ],
70
+ /** 知识库文档类型:0 文本 1 文件(label 复用菜单 i18n key) */
71
+ knowledgeDocType: [
72
+ { value: 0, label: 'menus.knowledge.doc.type_text', color: 'blue' },
73
+ { value: 1, label: 'menus.knowledge.doc.type_file', color: 'green' },
74
+ ],
75
+ /** 常用数据库字符集 */
76
+ dbCharset: [
77
+ { value: 'utf8mb4', label: 'utf8mb4' },
78
+ { value: 'utf8', label: 'utf8' },
79
+ { value: 'gbk', label: 'gbk' },
80
+ { value: 'latin1', label: 'latin1' },
81
+ { value: 'ascii', label: 'ascii' },
82
+ { value: 'big5', label: 'big5' },
83
+ { value: 'cp1252', label: 'cp1252' },
84
+ { value: 'binary', label: 'binary' },
85
+ ],
86
+ }
87
+
88
+ initEnumDataRuntime({ enumRegistry })
89
+
90
+ /** 与 `enumRegistry` / `ENUM_DATA` 槽位 key 一致 */
91
+
92
+ export type EnumRegistryKey = keyof typeof enumRegistry
93
+
94
+ export { ENUM_DATA, getEnumDefaultValue, getEnumLabelKey, getEnumOptions } from './module/enum-data/runtime'
95
+
@@ -0,0 +1,14 @@
1
+ /**
2
+ * 统一入口:
3
+ * - index-enum:静态约定枚举(`ENUM_DATA`,主入口 `meta/index-enum.ts`)
4
+ * - index-dict:动态数据字典(主入口 `meta/index-dict.ts`,实现 `meta/module/dict-data/`)
5
+ * - const:常量定义(如 ALIGN 列对齐、FIXED 列固定)
6
+ *
7
+ * 文档:`src/_doc/meta/0.docs-overview.md`
8
+ */
9
+
10
+ export { ALIGN, FIXED, FONT_FAMILY_ANTD_DEFAULT, TAG_COLOR } from './const'
11
+ export type { TagColorKey } from './const'
12
+ export * from './index-dict'
13
+ export * from './index-enum'
14
+
@@ -0,0 +1,199 @@
1
+ /**
2
+ * 数据字典运行时:由 `initDictDataRuntime(config)` 注入注册表,不引用 `meta/index-dict.ts`,避免循环依赖。
3
+ */
4
+
5
+ import { batchGetDictDataAPI, getDictDataAPI } from '@/api/system/dict'
6
+ import type { DictCodeSlot, DictOptionItem, DictRegistryItem } from './types'
7
+
8
+ export type { DictCodeSlot } from './types'
9
+
10
+ export type DictRuntimeInit = {
11
+ unauthDictRegistry: Record<string, DictRegistryItem>
12
+ commonDictRegistry: Record<string, DictRegistryItem>
13
+ }
14
+
15
+ function createEmptyDictCodeSlot(): DictCodeSlot {
16
+ return {
17
+ option: [],
18
+ valueMap: {},
19
+ defaultValue: '',
20
+ }
21
+ }
22
+
23
+ let unauthDictRegistryRef: Record<string, DictRegistryItem> = {}
24
+ let commonDictRegistryRef: Record<string, DictRegistryItem> = {}
25
+
26
+ function getDictRegistryItem(code: string): DictRegistryItem | undefined {
27
+ if (Object.prototype.hasOwnProperty.call(unauthDictRegistryRef, code)) {
28
+ return unauthDictRegistryRef[code]
29
+ }
30
+ if (Object.prototype.hasOwnProperty.call(commonDictRegistryRef, code)) {
31
+ return commonDictRegistryRef[code]
32
+ }
33
+ return undefined
34
+ }
35
+
36
+ function parseDictData(code: string, data: any[]) {
37
+ const slot = DICT_DATA[code]
38
+ if (!slot) return
39
+ const list = data ?? []
40
+ const valueMap: Record<string, string> = {}
41
+ let defaultValue = ''
42
+ const reg = getDictRegistryItem(code)
43
+ const toOption = (raw: any): DictOptionItem =>
44
+ reg?.parseItem != null ? reg.parseItem(raw) : { value: raw.value, name: raw.name }
45
+
46
+ slot.option = list.map((item: any) => {
47
+ const opt = toOption(item)
48
+ valueMap[String(opt.value)] = opt.name
49
+ if (item.defaultFlag) defaultValue = String(opt.value)
50
+ return opt
51
+ })
52
+ slot.valueMap = valueMap
53
+ slot.defaultValue = defaultValue
54
+ }
55
+
56
+ /** 访问键 → 后台分类 code(由 init 填充) */
57
+ export const DICT_KEY = {} as Record<string, string>
58
+
59
+ export const DICT_DATA = {} as Record<string, DictCodeSlot>
60
+
61
+ export let publicDictsReady: Promise<void> = Promise.resolve()
62
+
63
+ let commonDictLoadPromise: Promise<void> | null = null
64
+ let commonDictLoadSettled = false
65
+ let unauthDictLoadSettled = false
66
+
67
+ const dictDataLoadedNotifiers = new Set<() => void>()
68
+
69
+ let unauthDictCodes: string[] = []
70
+ let commonDictCodes: string[] = []
71
+
72
+ function notifyDictDataLoaded() {
73
+ for (const fn of dictDataLoadedNotifiers) {
74
+ try {
75
+ fn()
76
+ } catch (e) {
77
+ console.warn('[dict-data] dictDataLoaded notifier failed', e)
78
+ }
79
+ }
80
+ }
81
+
82
+ let runtimeInited = false
83
+
84
+ /**
85
+ * 注入注册表并初始化 `DICT_KEY` / `DICT_DATA` 槽位。由 `meta/index-dict.ts` 在定义好注册表后调用一次。
86
+ */
87
+ export function initDictDataRuntime(config: DictRuntimeInit): void {
88
+ if (runtimeInited) return
89
+ runtimeInited = true
90
+
91
+ unauthDictRegistryRef = config.unauthDictRegistry
92
+ commonDictRegistryRef = config.commonDictRegistry
93
+
94
+ unauthDictCodes = Object.keys(unauthDictRegistryRef)
95
+ commonDictCodes = Object.keys(commonDictRegistryRef)
96
+
97
+ const dictByAccessKey: Record<string, string> = {}
98
+ for (const code of Object.keys(unauthDictRegistryRef)) {
99
+ dictByAccessKey[unauthDictRegistryRef[code].constKey] = code
100
+ }
101
+ for (const code of Object.keys(commonDictRegistryRef)) {
102
+ dictByAccessKey[commonDictRegistryRef[code].constKey] = code
103
+ }
104
+
105
+ for (const k of Object.keys(DICT_KEY)) {
106
+ delete (DICT_KEY as Record<string, string | undefined>)[k]
107
+ }
108
+ Object.assign(DICT_KEY, dictByAccessKey)
109
+
110
+ const registeredDictCodes = [...new Set([...unauthDictCodes, ...commonDictCodes])]
111
+ for (const k of Object.keys(DICT_DATA)) {
112
+ delete (DICT_DATA as Record<string, DictCodeSlot | undefined>)[k]
113
+ }
114
+ for (const code of registeredDictCodes) {
115
+ DICT_DATA[code] = createEmptyDictCodeSlot()
116
+ }
117
+
118
+ commonDictLoadPromise = null
119
+ commonDictLoadSettled = false
120
+ unauthDictLoadSettled = false
121
+ publicDictsReady = Promise.resolve()
122
+ }
123
+
124
+ /**
125
+ * 订阅字典数据写入 `DICT_DATA` 后的刷新时机:
126
+ * - `loadUnauthDictData` 一轮结束(免登录类)
127
+ * - `loadCommonDictData` 一轮结束(登录 batch 类)
128
+ */
129
+ export function registerDictDataLoadedNotifier(listener: () => void): () => void {
130
+ dictDataLoadedNotifiers.add(listener)
131
+ if (commonDictLoadSettled || unauthDictLoadSettled) {
132
+ try {
133
+ listener()
134
+ } catch (e) {
135
+ console.warn('[dict-data] dictDataLoaded notifier failed', e)
136
+ }
137
+ }
138
+ return () => {
139
+ dictDataLoadedNotifiers.delete(listener)
140
+ }
141
+ }
142
+
143
+ /** @deprecated 请使用 `registerDictDataLoadedNotifier` */
144
+ export const registerCommonDictLoadedNotifier = registerDictDataLoadedNotifier
145
+
146
+ export function getDictOptions(code: string) {
147
+ return DICT_DATA[code]?.option ?? []
148
+ }
149
+
150
+ export function getDictDefaultValue(code: string): string {
151
+ return DICT_DATA[code]?.defaultValue ?? ''
152
+ }
153
+
154
+ export function loadUnauthDictData(): void {
155
+ if (!unauthDictCodes.length) return
156
+ unauthDictLoadSettled = false
157
+ publicDictsReady = Promise.all(
158
+ unauthDictCodes.map((code) =>
159
+ getDictDataAPI(code)
160
+ .then((res: any) => {
161
+ if (res.data) {
162
+ parseDictData(code, res.data)
163
+ }
164
+ })
165
+ .catch(() => {}),
166
+ ),
167
+ )
168
+ .then(() => {})
169
+ .finally(() => {
170
+ unauthDictLoadSettled = true
171
+ notifyDictDataLoaded()
172
+ })
173
+ }
174
+
175
+ /**
176
+ * 拉取登录后 batch 字典。
177
+ * @param force 为 true 时丢弃缓存 Promise,重新请求(如管理端字典变更后)
178
+ */
179
+ export function loadCommonDictData(force = false): Promise<void> {
180
+ if (force) {
181
+ commonDictLoadPromise = null
182
+ commonDictLoadSettled = false
183
+ }
184
+ if (commonDictLoadPromise == null) {
185
+ commonDictLoadPromise = batchGetDictDataAPI([...commonDictCodes])
186
+ .then((res: any) => {
187
+ if (!res.data) return
188
+ for (const code of commonDictCodes) {
189
+ parseDictData(code, res.data[code] ?? [])
190
+ }
191
+ })
192
+ .catch(() => {})
193
+ .finally(() => {
194
+ commonDictLoadSettled = true
195
+ notifyDictDataLoaded()
196
+ })
197
+ }
198
+ return commonDictLoadPromise
199
+ }
@@ -0,0 +1,17 @@
1
+ /** 与数据字典接口约定一致:每项必有 `value`、`name`(展示名) */
2
+ export type DictOptionItem = { value: string | number; name: string }
3
+
4
+ /**
5
+ * 字典注册表项:键为后台「分类 code」时在 registry 对象上的 key。
6
+ * - `parseItem` 可选:将接口单条映射为 `DictOptionItem`(预留)。
7
+ */
8
+ export type DictRegistryItem = {
9
+ constKey: string
10
+ parseItem?: (raw: any) => DictOptionItem
11
+ }
12
+
13
+ export type DictCodeSlot = {
14
+ option: DictOptionItem[]
15
+ valueMap: Record<string, string>
16
+ defaultValue: string
17
+ }
@@ -0,0 +1,75 @@
1
+ /**
2
+ * 静态枚举运行时:由 `initEnumDataRuntime({ enumRegistry })` 注入,不引用 `meta/index-enum.ts`。
3
+ */
4
+
5
+ import type { EnumCodeSlot, EnumOptionItem } from './types'
6
+
7
+ export type { EnumCodeSlot, EnumOptionItem } from './types'
8
+
9
+ export type EnumRuntimeInit = {
10
+ /** 键 = 稳定访问键(小驼峰),与 `ENUM_DATA` 槽位 key 一致;值为选项数组 */
11
+ enumRegistry: Record<string, readonly EnumOptionItem[] | EnumOptionItem[]>
12
+ }
13
+
14
+ function buildTagColorMap(items: EnumOptionItem[]): Record<string, string> {
15
+ const m: Record<string, string> = {}
16
+ for (const it of items) {
17
+ if (it.color == null || it.color === '') continue
18
+ const raw = it.value
19
+ const k = typeof raw === 'string' ? `${raw}`.toUpperCase() : `${raw}`
20
+ m[k] = it.color
21
+ }
22
+ return m
23
+ }
24
+
25
+ function createEnumSlot(items: readonly EnumOptionItem[] | EnumOptionItem[]): EnumCodeSlot {
26
+ const list = [...items]
27
+ const valueMap = Object.fromEntries(list.map((i) => [`${i.value}`, i.label])) as Record<string, string>
28
+ const dataMap = Object.fromEntries(list.map((i) => [`${i.value}`, i])) as Record<string, EnumOptionItem>
29
+ return {
30
+ option: list,
31
+ valueMap,
32
+ defaultValue: '',
33
+ tagColorMap: buildTagColorMap(list),
34
+ dataMap,
35
+ }
36
+ }
37
+
38
+ export const ENUM_DATA = {} as Record<string, EnumCodeSlot>
39
+
40
+ let runtimeInited = false
41
+
42
+ /**
43
+ * 由 `meta/index-enum.ts` 在定义好 `enumRegistry` 后调用一次。
44
+ */
45
+ export function initEnumDataRuntime(config: EnumRuntimeInit): void {
46
+ if (runtimeInited) return
47
+ runtimeInited = true
48
+
49
+ const { enumRegistry } = config
50
+ for (const k of Object.keys(ENUM_DATA)) {
51
+ delete (ENUM_DATA as Record<string, EnumCodeSlot | undefined>)[k]
52
+ }
53
+
54
+ for (const key of Object.keys(enumRegistry)) {
55
+ ENUM_DATA[key] = createEnumSlot(enumRegistry[key])
56
+ }
57
+ }
58
+
59
+ export function getEnumOptions(code: string) {
60
+ return ENUM_DATA[code]?.option ?? []
61
+ }
62
+
63
+ export function getEnumDefaultValue(code: string): string {
64
+ return ENUM_DATA[code]?.defaultValue ?? ''
65
+ }
66
+
67
+ /**
68
+ * 根据枚举 code 和 value 获取 i18n label key
69
+ * @param code 枚举 code(如 'commonStatus')
70
+ * @param value 枚举值
71
+ * @returns i18n label key,不存在则返回 undefined
72
+ */
73
+ export function getEnumLabelKey(code: string, value: unknown): string | undefined {
74
+ return ENUM_DATA[code]?.valueMap[`${value}`]
75
+ }
@@ -0,0 +1,18 @@
1
+ /** 静态枚举项(与下拉约定:`value` + `label` 为 i18n key;可选 `color` 供 Tag;允许扩展字段如 `icon`) */
2
+ export type EnumOptionItem = {
3
+ value: string | number
4
+ label: string
5
+ color?: string
6
+ [key: string]: unknown
7
+ }
8
+
9
+ /** 与 `DICT_DATA` 槽位对齐的内存结构(静态枚举无接口 defaultFlag,故 `defaultValue` 恒为 `''`) */
10
+ export type EnumCodeSlot = {
11
+ option: EnumOptionItem[]
12
+ valueMap: Record<string, string>
13
+ defaultValue: string
14
+ /** `value`(字符串化;HTTP 方法为大写)→ Tag `color`,无 color 的项为空表 */
15
+ tagColorMap: Record<string, string>
16
+ /** `value`(字符串化)→ 原始枚举项(含扩展字段,如 `icon`) */
17
+ dataMap: Record<string, EnumOptionItem>
18
+ }