@_tc/template-core 0.0.1-bate.46 → 0.0.1-bate.48

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 (856) hide show
  1. package/.skills/tc-component-usage-skills/SKILL.md +132 -0
  2. package/.skills/tc-component-usage-skills/reference/component-api.md +801 -0
  3. package/.skills/tc-component-usage-skills/reference/examples.md +435 -0
  4. package/.skills/tc-component-usage-skills/reference/patterns.md +392 -0
  5. package/.skills/tc-component-usage-skills/reference/template-core-frontend.md +104 -0
  6. package/.skills/tc-generator/SKILL.md +70 -0
  7. package/.skills/tc-generator/reference/example.md +357 -0
  8. package/.skills/tc-generator/reference/model-schema.md +328 -0
  9. package/.skills/tc-generator/reference/project-template/app/controller/product.js +73 -0
  10. package/.skills/tc-generator/reference/project-template/app/router/product.js +9 -0
  11. package/.skills/tc-generator/reference/project-template/config/config.default.js +7 -0
  12. package/.skills/tc-generator/reference/project-template/index.js +17 -0
  13. package/.skills/tc-generator/reference/project-template/model/product/mode.js +179 -0
  14. package/.skills/tc-generator/reference/project-template/model/product/project/default.js +5 -0
  15. package/.skills/tc-generator/reference/project-template/package.json +25 -0
  16. package/.skills/tc-generator/reference/runtime-extensions.md +190 -0
  17. package/README.md +1723 -0
  18. package/cjs/_virtual/_rolldown/runtime.js +1 -37
  19. package/cjs/app/controller/base.js +1 -29
  20. package/cjs/app/controller/project.js +1 -60
  21. package/cjs/app/controller/view.js +1 -24
  22. package/cjs/app/extend/$fetch.js +1 -0
  23. package/cjs/app/extend/db.js +20 -8
  24. package/cjs/app/extend/generateErrorMessage.js +1 -16
  25. package/cjs/app/extend/logger.js +1 -35
  26. package/cjs/app/extend/parsingParamsOnUrl.js +1 -22
  27. package/cjs/app/extend/render-view.js +1 -24
  28. package/cjs/app/middleware/api-params-verify.js +1 -72
  29. package/cjs/app/middleware/api-sign-verify.js +1 -23
  30. package/cjs/app/middleware/error-handle.js +1 -38
  31. package/cjs/app/middleware/project-handler.js +1 -21
  32. package/cjs/app/middleware.js +1 -32
  33. package/cjs/app/router/project.js +1 -10
  34. package/cjs/app/router/view.js +1 -9
  35. package/cjs/app/router-schema/project.js +1 -16
  36. package/cjs/app/service/base.js +1 -17
  37. package/cjs/app/service/project.js +1 -38
  38. package/cjs/app/type.js +0 -1
  39. package/cjs/app/typings.js +0 -1
  40. package/cjs/app/view/entry.tpl +27 -28
  41. package/cjs/bundler/buildBE.js +1 -0
  42. package/cjs/bundler/defaultAlias.js +1 -5
  43. package/cjs/bundler/dev.js +1 -20
  44. package/cjs/bundler/index.js +1 -19
  45. package/cjs/bundler/prod.js +1 -21
  46. package/cjs/bundler/state.js +1 -0
  47. package/cjs/bundler/utils.js +1 -262
  48. package/cjs/config/config.default.js +1 -0
  49. package/cjs/index.js +1 -23
  50. package/cjs/packages/common/LRUCache.js +1 -4
  51. package/cjs/packages/common/array/index.js +1 -43
  52. package/cjs/packages/common/cache/LRUCache.js +1 -45
  53. package/cjs/packages/common/cache/index.js +1 -4
  54. package/cjs/packages/common/guards/index.js +1 -34
  55. package/cjs/packages/common/http/index.js +1 -0
  56. package/cjs/packages/common/i18n/default.js +1 -95
  57. package/cjs/packages/common/i18n/en-US.js +1 -95
  58. package/cjs/packages/common/i18n/index.js +1 -178
  59. package/cjs/packages/common/i18n/locales.js +1 -17
  60. package/cjs/packages/common/i18n/types.js +0 -1
  61. package/cjs/packages/common/index.js +1 -65
  62. package/cjs/packages/common/log/index.js +2 -160
  63. package/cjs/packages/common/number/index.js +1 -14
  64. package/cjs/packages/common/object/filterEmpty.js +1 -32
  65. package/cjs/packages/common/object/filtereEmpty.js +1 -5
  66. package/cjs/packages/common/object/index.js +1 -26
  67. package/cjs/packages/common/string/index.js +1 -17
  68. package/cjs/packages/common/types/index.js +0 -1
  69. package/cjs/packages/core/env.js +1 -27
  70. package/cjs/packages/core/index.js +1 -110
  71. package/cjs/packages/core/loader/config.js +1 -43
  72. package/cjs/packages/core/loader/controller.js +1 -33
  73. package/cjs/packages/core/loader/extend.js +1 -31
  74. package/cjs/packages/core/loader/middleware.js +1 -30
  75. package/cjs/packages/core/loader/model.js +1 -111
  76. package/cjs/packages/core/loader/router-schema.js +1 -36
  77. package/cjs/packages/core/loader/router.js +1 -62
  78. package/cjs/packages/core/loader/service.js +1 -30
  79. package/cjs/packages/core/paths.js +1 -12
  80. package/cjs/packages/core/types.js +0 -1
  81. package/cjs/packages/utils/getAllFilesInFolder.js +1 -14
  82. package/cjs/packages/utils/getAllFnReturnValue.js +0 -1
  83. package/cjs/packages/utils/index.js +1 -11
  84. package/cjs/packages/utils/loadFile.js +1 -55
  85. package/cjs/packages/utils/path.js +1 -31
  86. package/cjs/packages/utils/runFileFn.js +1 -51
  87. package/cjs/scripts/vite-build/build.js +3 -0
  88. package/cjs/scripts/vite-build/collect.js +1 -0
  89. package/cjs/scripts/vite-build/constants.js +1 -0
  90. package/cjs/scripts/vite-build/dts.js +1 -0
  91. package/cjs/scripts/vite-build/index.js +1 -0
  92. package/cjs/scripts/vite-build/normalize.js +1 -0
  93. package/cjs/scripts/vite-build/plugins.js +1 -0
  94. package/cjs/scripts/vite-build/resolve.js +1 -0
  95. package/cjs/scripts/vite-build/types.js +0 -0
  96. package/cjs/scripts/vite-build/utils.js +1 -0
  97. package/esm/_virtual/_rolldown/runtime.js +4 -29
  98. package/esm/app/controller/base.js +14 -16
  99. package/esm/app/controller/project.js +39 -46
  100. package/esm/app/controller/view.js +23 -19
  101. package/esm/app/extend/$fetch.js +15 -0
  102. package/esm/app/extend/db.js +138 -4
  103. package/esm/app/extend/generateErrorMessage.js +4 -12
  104. package/esm/app/extend/logger.js +9 -17
  105. package/esm/app/extend/parsingParamsOnUrl.js +11 -18
  106. package/esm/app/extend/render-view.js +18 -16
  107. package/esm/app/middleware/api-params-verify.js +36 -50
  108. package/esm/app/middleware/api-sign-verify.js +10 -16
  109. package/esm/app/middleware/error-handle.js +17 -30
  110. package/esm/app/middleware/project-handler.js +11 -16
  111. package/esm/app/middleware.js +12 -19
  112. package/esm/app/router/project.js +4 -6
  113. package/esm/app/router/view.js +4 -5
  114. package/esm/app/router-schema/project.js +2 -2
  115. package/esm/app/service/base.js +6 -7
  116. package/esm/app/service/project.js +18 -32
  117. package/esm/app/view/entry.tpl +27 -28
  118. package/esm/bundler/buildBE.js +54 -0
  119. package/esm/bundler/defaultAlias.js +2 -2
  120. package/esm/bundler/dev.js +8 -14
  121. package/esm/bundler/index.js +11 -9
  122. package/esm/bundler/prod.js +9 -14
  123. package/esm/bundler/state.js +10 -0
  124. package/esm/bundler/utils.js +115 -164
  125. package/esm/config/config.default.js +9 -0
  126. package/esm/index.js +12 -15
  127. package/esm/packages/common/LRUCache.js +2 -2
  128. package/esm/packages/common/array/index.js +21 -31
  129. package/esm/packages/common/cache/LRUCache.js +21 -25
  130. package/esm/packages/common/cache/index.js +2 -2
  131. package/esm/packages/common/guards/index.js +5 -23
  132. package/esm/packages/common/http/index.js +256 -0
  133. package/esm/packages/common/i18n/default.js +2 -7
  134. package/esm/packages/common/i18n/en-US.js +2 -7
  135. package/esm/packages/common/i18n/index.js +73 -144
  136. package/esm/packages/common/i18n/locales.js +6 -8
  137. package/esm/packages/common/index.js +14 -13
  138. package/esm/packages/common/log/index.js +69 -122
  139. package/esm/packages/common/number/index.js +7 -8
  140. package/esm/packages/common/object/filterEmpty.js +16 -22
  141. package/esm/packages/common/object/filtereEmpty.js +2 -2
  142. package/esm/packages/common/object/index.js +14 -17
  143. package/esm/packages/common/string/index.js +2 -11
  144. package/esm/packages/core/env.js +22 -24
  145. package/esm/packages/core/index.js +36 -92
  146. package/esm/packages/core/loader/config.js +21 -35
  147. package/esm/packages/core/loader/controller.js +8 -27
  148. package/esm/packages/core/loader/extend.js +19 -21
  149. package/esm/packages/core/loader/middleware.js +9 -22
  150. package/esm/packages/core/loader/model.js +50 -91
  151. package/esm/packages/core/loader/router-schema.js +13 -29
  152. package/esm/packages/core/loader/router.js +27 -51
  153. package/esm/packages/core/loader/service.js +8 -24
  154. package/esm/packages/core/paths.js +5 -5
  155. package/esm/packages/utils/getAllFilesInFolder.js +6 -8
  156. package/esm/packages/utils/index.js +5 -5
  157. package/esm/packages/utils/loadFile.js +28 -43
  158. package/esm/packages/utils/path.js +10 -22
  159. package/esm/packages/utils/runFileFn.js +32 -37
  160. package/esm/scripts/vite-build/build.js +141 -0
  161. package/esm/scripts/vite-build/collect.js +79 -0
  162. package/esm/scripts/vite-build/constants.js +34 -0
  163. package/esm/scripts/vite-build/dts.js +132 -0
  164. package/esm/scripts/vite-build/index.js +3 -0
  165. package/esm/scripts/vite-build/normalize.js +78 -0
  166. package/esm/scripts/vite-build/plugins.js +106 -0
  167. package/esm/scripts/vite-build/resolve.js +46 -0
  168. package/esm/scripts/vite-build/types.js +0 -0
  169. package/esm/scripts/vite-build/utils.js +24 -0
  170. package/fe/bundler/defaultAlias.js +4 -0
  171. package/fe/frontend/apps/dash/Dashboard.d.ts +6 -0
  172. package/fe/frontend/apps/dash/Dashboard.js +164 -0
  173. package/fe/frontend/apps/dash/dash.entry.js +54 -0
  174. package/fe/frontend/apps/dash/types.d.ts +25 -0
  175. package/fe/frontend/apps/dash/types.js +0 -0
  176. package/fe/frontend/apps/ui-components/index.js +16 -0
  177. package/fe/frontend/apps/ui-components/ui-components.entry.d.ts +2 -0
  178. package/fe/frontend/apps/ui-components/ui-components.entry.js +8 -0
  179. package/fe/frontend/extended/SchemaForm/data.d.ts +1 -1
  180. package/fe/frontend/extended/SchemaForm/data.js +7 -7
  181. package/fe/frontend/{widgets → src}/api/baseInfo.d.ts +2 -2
  182. package/fe/frontend/src/api/baseInfo.js +14 -0
  183. package/fe/frontend/src/common/CRUD/CRUD.d.ts +3 -0
  184. package/fe/frontend/src/common/CRUD/CRUD.js +2 -0
  185. package/fe/frontend/src/common/CRUD/index.d.ts +2 -0
  186. package/fe/frontend/src/common/CRUD/index.js +2 -0
  187. package/fe/frontend/src/common/auth/index.js +21 -0
  188. package/fe/frontend/{widgets/defaultPages/Schema/utils → src/common}/fetchErrorShow.d.ts +1 -1
  189. package/fe/frontend/src/common/fetchErrorShow.js +11 -0
  190. package/fe/frontend/src/common/generateMenuData.d.ts +4 -0
  191. package/fe/frontend/src/common/generateMenuData.js +16 -0
  192. package/fe/frontend/{widgets → src}/common/importComponent.d.ts +1 -1
  193. package/fe/frontend/src/common/importComponent.js +23 -0
  194. package/fe/frontend/src/common/language.d.ts +3 -0
  195. package/fe/frontend/src/common/language.js +12 -0
  196. package/fe/frontend/{widgets → src}/common/logFn/index.d.ts +1 -0
  197. package/fe/frontend/src/common/logFn/index.js +14 -0
  198. package/fe/frontend/{widgets → src}/common/menu.d.ts +1 -1
  199. package/fe/frontend/src/common/menu.js +97 -0
  200. package/fe/frontend/src/common/request.d.ts +37 -0
  201. package/fe/frontend/src/common/request.js +183 -0
  202. package/fe/frontend/{components → src/components}/AsyncSelect/AsyncSelect.d.ts +3 -3
  203. package/fe/frontend/src/components/AsyncSelect/AsyncSelect.js +35 -0
  204. package/fe/frontend/src/components/AsyncSelect/index.d.ts +4 -0
  205. package/fe/frontend/src/components/AsyncSelect/index.js +5 -0
  206. package/fe/frontend/{widgets → src}/components/BasePage/HeaderView.d.ts +1 -0
  207. package/fe/frontend/src/components/BasePage/HeaderView.js +55 -0
  208. package/fe/frontend/src/components/LanguageSwitch/LanguageSwitch.d.ts +14 -0
  209. package/fe/frontend/src/components/LanguageSwitch/LanguageSwitch.js +44 -0
  210. package/fe/frontend/src/components/LanguageSwitch/index.d.ts +4 -0
  211. package/fe/frontend/src/components/LanguageSwitch/index.js +5 -0
  212. package/fe/frontend/{widgets → src}/components/Router/index.d.ts +2 -2
  213. package/fe/frontend/src/components/Router/index.js +21 -0
  214. package/fe/frontend/src/components/Router/type.js +0 -0
  215. package/fe/frontend/src/components/ThemeSwitch/ThemeSwitch.d.ts +15 -0
  216. package/fe/frontend/src/components/ThemeSwitch/ThemeSwitch.js +83 -0
  217. package/fe/frontend/src/components/ThemeSwitch/index.d.ts +4 -0
  218. package/fe/frontend/src/components/ThemeSwitch/index.js +5 -0
  219. package/fe/frontend/src/components/index.d.ts +11 -0
  220. package/fe/frontend/src/components/index.js +7 -0
  221. package/fe/frontend/src/defaultPages/Iframe/index.js +15 -0
  222. package/fe/frontend/src/defaultPages/NotFoundPage/index.d.ts +3 -0
  223. package/fe/frontend/src/defaultPages/NotFoundPage/index.js +28 -0
  224. package/fe/frontend/{widgets/defaultPages/Schema → src/defaultPages/SchemaPage}/components/CallCom/DetailPanel.d.ts +1 -1
  225. package/fe/frontend/src/defaultPages/SchemaPage/components/CallCom/DetailPanel.js +102 -0
  226. package/fe/frontend/{widgets/defaultPages/Schema → src/defaultPages/SchemaPage}/components/CallCom/PopFrom.d.ts +1 -1
  227. package/fe/frontend/src/defaultPages/SchemaPage/components/CallCom/PopFrom.js +119 -0
  228. package/fe/frontend/src/defaultPages/SchemaPage/components/CallCom/builtIn.d.ts +44 -0
  229. package/fe/frontend/src/defaultPages/SchemaPage/components/CallCom/builtIn.js +10 -0
  230. package/fe/frontend/src/defaultPages/SchemaPage/components/CallCom/data.d.ts +4 -0
  231. package/fe/frontend/src/defaultPages/SchemaPage/components/CallCom/data.js +9 -0
  232. package/fe/frontend/src/defaultPages/SchemaPage/components/SchemaSearch/index.js +62 -0
  233. package/fe/frontend/{widgets/defaultPages/Schema → src/defaultPages/SchemaPage}/components/SchemaTable/index.d.ts +2 -2
  234. package/fe/frontend/src/defaultPages/SchemaPage/components/SchemaTable/index.js +200 -0
  235. package/fe/frontend/src/defaultPages/SchemaPage/data/eventInfo.js +9 -0
  236. package/fe/frontend/src/defaultPages/SchemaPage/data/index.js +4 -0
  237. package/fe/frontend/{widgets/defaultPages/Schema → src/defaultPages/SchemaPage}/hooks/useComConfig.d.ts +1 -1
  238. package/fe/frontend/src/defaultPages/SchemaPage/hooks/useComConfig.js +17 -0
  239. package/fe/frontend/src/defaultPages/SchemaPage/index.css +112 -0
  240. package/fe/frontend/{widgets/defaultPages/Schema → src/defaultPages/SchemaPage}/index.d.ts +1 -0
  241. package/fe/frontend/src/defaultPages/SchemaPage/index.js +90 -0
  242. package/fe/frontend/{widgets/defaultPages/Schema → src/defaultPages/SchemaPage}/schemaType.d.ts +7 -6
  243. package/fe/frontend/src/defaultPages/SchemaPage/schemaType.js +7 -0
  244. package/fe/frontend/src/defaultPages/SchemaPage/utils/permissions.js +6 -0
  245. package/fe/frontend/src/defaultPages/SchemaPage/utils/schemaConversion.d.ts +3 -0
  246. package/fe/frontend/src/defaultPages/SchemaPage/utils/schemaConversion.js +66 -0
  247. package/fe/frontend/src/defaultPages/SchemaPage/utils/validator.d.ts +11 -0
  248. package/fe/frontend/src/defaultPages/SchemaPage/utils/validator.js +122 -0
  249. package/fe/frontend/{widgets → src}/defaultPages/SidebarSlotPage/SidebarSlotContainer.d.ts +2 -2
  250. package/fe/frontend/src/defaultPages/SidebarSlotPage/SidebarSlotContainer.js +55 -0
  251. package/fe/frontend/src/defaultPages/SidebarSlotPage/index.js +21 -0
  252. package/fe/frontend/src/defaultPages/SidebarSlotPageTmp.js +21 -0
  253. package/fe/frontend/src/defaultPages/SlotPage/index.js +22 -0
  254. package/fe/frontend/src/exportStore.d.ts +17 -0
  255. package/fe/frontend/src/exportStore.js +5 -0
  256. package/fe/frontend/src/hooks/useCurrentMenuData.js +30 -0
  257. package/fe/frontend/src/hooks/useRouterParams.js +16 -0
  258. package/fe/frontend/src/index.d.ts +21 -0
  259. package/fe/frontend/src/index.js +19 -0
  260. package/fe/frontend/src/language/en-US.d.ts +89 -0
  261. package/fe/frontend/src/language/en-US.js +89 -0
  262. package/fe/frontend/src/language/index.d.ts +73 -0
  263. package/fe/frontend/src/language/index.js +79 -0
  264. package/fe/frontend/src/language/zh-CN.d.ts +89 -0
  265. package/fe/frontend/src/language/zh-CN.js +89 -0
  266. package/fe/frontend/src/main.css +96 -0
  267. package/fe/frontend/src/main.d.ts +27 -0
  268. package/fe/frontend/src/main.js +60 -0
  269. package/fe/frontend/src/stores/apiFreezer.d.ts +93 -0
  270. package/fe/frontend/src/stores/apiFreezer.js +53 -0
  271. package/fe/frontend/{widgets/store → src/stores}/mode.d.ts +3 -3
  272. package/fe/frontend/src/stores/mode.js +36 -0
  273. package/fe/frontend/{widgets/defaultPages/Schema → src}/stores/schemaEventBus.d.ts +1 -1
  274. package/fe/frontend/src/stores/schemaEventBus.js +53 -0
  275. package/fe/frontend/{widgets/defaultPages/Schema → src}/stores/schemaStore.d.ts +5 -5
  276. package/fe/frontend/src/stores/schemaStore.js +28 -0
  277. package/fe/frontend/{typing → src/typing}/scalability.d.ts +3 -3
  278. package/fe/frontend/src/typing/scalability.js +0 -0
  279. package/fe/frontend/src/typing/window.d.ts +9 -0
  280. package/fe/frontend/src/typing/window.js +0 -0
  281. package/fe/model/types/data/button.d.ts +4 -4
  282. package/fe/model/types/data/component.d.ts +32 -47
  283. package/fe/model/types/data/schema.d.ts +6 -6
  284. package/fe/model/types/data/search.d.ts +1 -1
  285. package/fe/model/types/model.d.ts +19 -12
  286. package/fe/packages/common/cache/LRUCache.js +43 -47
  287. package/fe/packages/common/guards/index.js +8 -24
  288. package/fe/packages/common/http/index.d.ts +90 -0
  289. package/fe/packages/common/http/index.js +300 -0
  290. package/fe/packages/common/i18n/default.js +91 -88
  291. package/fe/packages/common/i18n/en-US.js +91 -88
  292. package/fe/packages/common/i18n/index.d.ts +3 -3
  293. package/fe/packages/common/i18n/index.js +142 -153
  294. package/fe/packages/common/i18n/locales.d.ts +3 -3
  295. package/fe/packages/common/i18n/locales.js +10 -9
  296. package/fe/packages/common/index.d.ts +1 -0
  297. package/fe/packages/common/object/filterEmpty.js +25 -30
  298. package/fe/packages/react/hooks/useBreadcrumb.d.ts +10 -0
  299. package/fe/packages/react/hooks/useBreadcrumb.js +5 -0
  300. package/fe/packages/react/hooks/useExecuteOnce.js +47 -0
  301. package/fe/packages/react/hooks/useInit.js +11 -0
  302. package/fe/packages/react/hooks/useLanguage.d.ts +2 -0
  303. package/fe/packages/react/hooks/useLanguage.js +8 -0
  304. package/fe/packages/react/hooks/usePagination.js +30 -0
  305. package/fe/packages/{ui/react → react}/hooks/useRefState.d.ts +1 -1
  306. package/fe/packages/react/hooks/useRefState.js +35 -0
  307. package/fe/packages/react/hooks/useWatch.js +60 -0
  308. package/fe/packages/react/hooks/useWatch.test.js +24 -0
  309. package/fe/packages/react/ui/assets/table/no-result.js +4 -0
  310. package/fe/packages/{ui/react → react/ui}/components/Button/Button.d.ts +1 -1
  311. package/fe/packages/react/ui/components/Button/Button.js +88 -0
  312. package/fe/packages/react/ui/components/Button/SubmitButton.d.ts +13 -0
  313. package/fe/packages/react/ui/components/Button/SubmitButton.js +30 -0
  314. package/fe/packages/react/ui/components/Button/index.d.ts +4 -0
  315. package/fe/packages/react/ui/components/Button/index.js +3 -0
  316. package/fe/packages/react/ui/components/Card/Card.d.ts +15 -0
  317. package/fe/packages/react/ui/components/Card/Card.js +31 -0
  318. package/fe/packages/react/ui/components/Card/index.d.ts +2 -0
  319. package/fe/packages/react/ui/components/Card/index.js +2 -0
  320. package/fe/packages/{ui/react → react/ui}/components/Checkbox/Checkbox.d.ts +1 -1
  321. package/fe/packages/react/ui/components/Checkbox/Checkbox.js +52 -0
  322. package/fe/packages/react/ui/components/Checkbox/index.d.ts +2 -0
  323. package/fe/packages/react/ui/components/Checkbox/index.js +2 -0
  324. package/fe/packages/react/ui/components/ConfirmDialog/ConfirmDialog.js +41 -0
  325. package/fe/packages/react/ui/components/ConfirmDialog/index.d.ts +2 -0
  326. package/fe/packages/react/ui/components/ConfirmDialog/index.js +2 -0
  327. package/fe/packages/{ui/react → react/ui}/components/DataTable/ActionBtn.d.ts +1 -1
  328. package/fe/packages/react/ui/components/DataTable/ActionBtn.js +116 -0
  329. package/fe/packages/{ui/react → react/ui}/components/DataTable/index.d.ts +9 -7
  330. package/fe/packages/react/ui/components/DataTable/index.js +235 -0
  331. package/fe/packages/{ui/react → react/ui}/components/Date/Calendar.d.ts +2 -2
  332. package/fe/packages/react/ui/components/Date/Calendar.js +351 -0
  333. package/fe/packages/react/ui/components/Date/Date.js +210 -0
  334. package/fe/packages/react/ui/components/Date/DateTestPage.js +340 -0
  335. package/fe/packages/react/ui/components/Date/LocaleContext.js +11 -0
  336. package/fe/packages/{ui/react → react/ui}/components/Date/LocaleProvider.d.ts +2 -2
  337. package/fe/packages/react/ui/components/Date/LocaleProvider.js +31 -0
  338. package/fe/packages/react/ui/components/Date/TimePicker.js +136 -0
  339. package/fe/packages/react/ui/components/Date/data.js +7 -0
  340. package/fe/packages/{ui/react → react/ui}/components/Date/dateLocaleStore.d.ts +1 -1
  341. package/fe/packages/react/ui/components/Date/dateLocaleStore.js +14 -0
  342. package/fe/packages/react/ui/components/Date/dropdownPositioning.d.ts +3 -0
  343. package/fe/packages/react/ui/components/Date/dropdownPositioning.js +12 -0
  344. package/fe/packages/react/ui/components/Date/index.d.ts +6 -0
  345. package/fe/packages/react/ui/components/Date/index.js +6 -0
  346. package/fe/packages/react/ui/components/Date/locales.js +25 -0
  347. package/fe/packages/{ui/react → react/ui}/components/Drawer/Drawer.d.ts +1 -1
  348. package/fe/packages/react/ui/components/Drawer/Drawer.js +151 -0
  349. package/fe/packages/react/ui/components/Drawer/index.d.ts +3 -0
  350. package/fe/packages/react/ui/components/Drawer/index.js +2 -0
  351. package/fe/packages/{ui/react → react/ui}/components/Dropdown/Dropdown.d.ts +3 -2
  352. package/fe/packages/react/ui/components/Dropdown/Dropdown.js +105 -0
  353. package/fe/packages/react/ui/components/Dropdown/index.d.ts +2 -0
  354. package/fe/packages/react/ui/components/Dropdown/index.js +2 -0
  355. package/fe/packages/{ui/react → react/ui}/components/Form/Form.d.ts +2 -2
  356. package/fe/packages/react/ui/components/Form/Form.js +15 -0
  357. package/fe/packages/{ui/react → react/ui}/components/Form/FormItem.d.ts +3 -3
  358. package/fe/packages/react/ui/components/Form/FormItem.js +60 -0
  359. package/fe/packages/{ui/react → react/ui}/components/Form/SchemaForm/data.d.ts +8 -8
  360. package/fe/packages/react/ui/components/Form/SchemaForm/data.js +16 -0
  361. package/fe/packages/react/ui/components/Form/SchemaForm/defaultComponentsMap.d.ts +4 -0
  362. package/fe/packages/react/ui/components/Form/SchemaForm/defaultComponentsMap.js +4 -0
  363. package/fe/packages/{ui/react → react/ui}/components/Form/SchemaForm/index.d.ts +9 -9
  364. package/fe/packages/react/ui/components/Form/SchemaForm/index.js +119 -0
  365. package/fe/packages/react/ui/components/Form/index.d.ts +5 -0
  366. package/fe/packages/react/ui/components/Form/index.js +5 -0
  367. package/fe/packages/react/ui/components/Form/useForm.d.ts +3 -0
  368. package/fe/packages/react/ui/components/Form/useForm.js +2 -0
  369. package/fe/packages/react/ui/components/ImagePreview/ImagePreview.js +307 -0
  370. package/fe/packages/{ui/react → react/ui}/components/ImagePreview/PreviewImage.d.ts +2 -2
  371. package/fe/packages/react/ui/components/ImagePreview/PreviewImage.js +56 -0
  372. package/fe/packages/react/ui/components/ImagePreview/index.d.ts +3 -0
  373. package/fe/packages/react/ui/components/ImagePreview/index.js +3 -0
  374. package/fe/packages/{ui/react → react/ui}/components/Input/Input.d.ts +1 -1
  375. package/fe/packages/react/ui/components/Input/Input.js +88 -0
  376. package/fe/packages/react/ui/components/Input/index.d.ts +2 -0
  377. package/fe/packages/react/ui/components/Input/index.js +2 -0
  378. package/fe/packages/{ui/react → react/ui}/components/InputNumber/InputNumber.d.ts +2 -2
  379. package/fe/packages/react/ui/components/InputNumber/InputNumber.js +207 -0
  380. package/fe/packages/react/ui/components/InputNumber/index.d.ts +2 -0
  381. package/fe/packages/react/ui/components/InputNumber/index.js +2 -0
  382. package/fe/packages/react/ui/components/InputNumber/inputNumberUtils.js +45 -0
  383. package/fe/packages/react/ui/components/InputNumber/inputNumberUtils.test.js +59 -0
  384. package/fe/packages/{ui/react → react/ui}/components/Label/Label.d.ts +1 -1
  385. package/fe/packages/react/ui/components/Label/Label.js +58 -0
  386. package/fe/packages/react/ui/components/Label/index.d.ts +3 -0
  387. package/fe/packages/react/ui/components/Label/index.js +2 -0
  388. package/fe/packages/react/ui/components/Layout/Layout.d.ts +11 -0
  389. package/fe/packages/react/ui/components/Layout/Layout.js +33 -0
  390. package/fe/packages/react/ui/components/Layout/index.d.ts +2 -0
  391. package/fe/packages/react/ui/components/Layout/index.js +2 -0
  392. package/fe/packages/react/ui/components/Loading/Loading.d.ts +25 -0
  393. package/fe/packages/react/ui/components/Loading/Loading.js +48 -0
  394. package/fe/packages/react/ui/components/Loading/index.d.ts +2 -0
  395. package/fe/packages/react/ui/components/Loading/index.js +2 -0
  396. package/fe/packages/react/ui/components/Menu/Menu.js +147 -0
  397. package/fe/packages/react/ui/components/Menu/MenuContext.js +88 -0
  398. package/fe/packages/react/ui/components/Menu/MenuItem.js +78 -0
  399. package/fe/packages/react/ui/components/Menu/SubMenu.js +207 -0
  400. package/fe/packages/react/ui/components/Menu/index.d.ts +9 -0
  401. package/fe/packages/react/ui/components/Menu/index.js +5 -0
  402. package/fe/packages/{ui/react → react/ui}/components/Menu/menuTypes.d.ts +1 -1
  403. package/fe/packages/react/ui/components/Menu/menuTypes.js +0 -0
  404. package/fe/packages/react/ui/components/Menu/utils.js +8 -0
  405. package/fe/packages/{ui/react → react/ui}/components/Message/Message.d.ts +1 -1
  406. package/fe/packages/react/ui/components/Message/Message.js +76 -0
  407. package/fe/packages/{ui/react → react/ui}/components/Message/MessageManager.d.ts +2 -2
  408. package/fe/packages/react/ui/components/Message/MessageManager.js +104 -0
  409. package/fe/packages/react/ui/components/Message/data.js +4 -0
  410. package/fe/packages/react/ui/components/Message/index.d.ts +3 -0
  411. package/fe/packages/react/ui/components/Message/index.js +2 -0
  412. package/fe/packages/{ui/react → react/ui}/components/Modal/Modal.d.ts +1 -1
  413. package/fe/packages/react/ui/components/Modal/Modal.js +59 -0
  414. package/fe/packages/{ui/react → react/ui}/components/Modal/ModalManager.d.ts +5 -5
  415. package/fe/packages/react/ui/components/Modal/ModalManager.js +106 -0
  416. package/fe/packages/react/ui/components/Modal/index.d.ts +4 -0
  417. package/fe/packages/react/ui/components/Modal/index.js +3 -0
  418. package/fe/packages/react/ui/components/Notification/Notification.d.ts +14 -0
  419. package/fe/packages/react/ui/components/Notification/Notification.js +56 -0
  420. package/fe/packages/react/ui/components/Notification/index.d.ts +2 -0
  421. package/fe/packages/react/ui/components/Notification/index.js +2 -0
  422. package/fe/packages/{ui/react → react/ui}/components/Overlay/Overlay.d.ts +1 -1
  423. package/fe/packages/react/ui/components/Overlay/Overlay.js +61 -0
  424. package/fe/packages/react/ui/components/Overlay/index.d.ts +3 -0
  425. package/fe/packages/react/ui/components/Overlay/index.js +2 -0
  426. package/fe/packages/react/ui/components/Pagination/Pagination.js +115 -0
  427. package/fe/packages/react/ui/components/Pagination/index.d.ts +2 -0
  428. package/fe/packages/react/ui/components/Pagination/index.js +2 -0
  429. package/fe/packages/react/ui/components/Popup/Popup.js +86 -0
  430. package/fe/packages/react/ui/components/Popup/index.d.ts +2 -0
  431. package/fe/packages/react/ui/components/Popup/index.js +2 -0
  432. package/fe/packages/react/ui/components/Radio/Radio.d.ts +9 -0
  433. package/fe/packages/react/ui/components/Radio/Radio.js +36 -0
  434. package/fe/packages/react/ui/components/Radio/RadioGroup.d.ts +19 -0
  435. package/fe/packages/react/ui/components/Radio/RadioGroup.js +33 -0
  436. package/fe/packages/react/ui/components/Radio/index.d.ts +3 -0
  437. package/fe/packages/react/ui/components/Radio/index.js +3 -0
  438. package/fe/packages/{ui/react → react/ui}/components/Search/Search.d.ts +4 -4
  439. package/fe/packages/react/ui/components/Search/Search.js +24 -0
  440. package/fe/packages/react/ui/components/Search/index.d.ts +2 -0
  441. package/fe/packages/react/ui/components/Search/index.js +2 -0
  442. package/fe/packages/{ui/react → react/ui}/components/Select/Select.d.ts +1 -1
  443. package/fe/packages/react/ui/components/Select/Select.js +276 -0
  444. package/fe/packages/react/ui/components/Select/dropdownPositioning.d.ts +3 -0
  445. package/fe/packages/react/ui/components/Select/dropdownPositioning.js +16 -0
  446. package/fe/packages/react/ui/components/Select/index.d.ts +2 -0
  447. package/fe/packages/react/ui/components/Select/index.js +2 -0
  448. package/fe/packages/{ui/react → react/ui}/components/Skeleton/Skeleton.d.ts +1 -1
  449. package/fe/packages/react/ui/components/Skeleton/Skeleton.js +101 -0
  450. package/fe/packages/react/ui/components/Skeleton/index.d.ts +3 -0
  451. package/fe/packages/react/ui/components/Skeleton/index.js +2 -0
  452. package/fe/packages/{ui/react → react/ui}/components/Switch/Switch.d.ts +1 -1
  453. package/fe/packages/react/ui/components/Switch/Switch.js +28 -0
  454. package/fe/packages/react/ui/components/Switch/index.d.ts +2 -0
  455. package/fe/packages/react/ui/components/Switch/index.js +2 -0
  456. package/fe/packages/{ui/react → react/ui}/components/TableSearch/TableSearch.d.ts +6 -6
  457. package/fe/packages/react/ui/components/TableSearch/TableSearch.js +146 -0
  458. package/fe/packages/react/ui/components/TableSearch/index.d.ts +3 -0
  459. package/fe/packages/react/ui/components/TableSearch/index.js +2 -0
  460. package/fe/packages/react/ui/components/TableSearch/lang.js +14 -0
  461. package/fe/packages/{ui/react → react/ui}/components/TableSearch/tableSearchLocaleStore.d.ts +1 -1
  462. package/fe/packages/react/ui/components/TableSearch/tableSearchLocaleStore.js +10 -0
  463. package/fe/packages/react/ui/components/Tabs/Tabs.d.ts +16 -0
  464. package/fe/packages/react/ui/components/Tabs/Tabs.js +33 -0
  465. package/fe/packages/react/ui/components/Tabs/index.d.ts +2 -0
  466. package/fe/packages/react/ui/components/Tabs/index.js +2 -0
  467. package/fe/packages/react/ui/components/Textarea/Textarea.js +58 -0
  468. package/fe/packages/react/ui/components/Textarea/index.d.ts +2 -0
  469. package/fe/packages/react/ui/components/Textarea/index.js +2 -0
  470. package/fe/packages/react/ui/components/Tooltip/Tooltip.js +77 -0
  471. package/fe/packages/react/ui/components/Tooltip/index.d.ts +2 -0
  472. package/fe/packages/react/ui/components/Tooltip/index.js +2 -0
  473. package/fe/packages/react/ui/components/TreeSelect/TreeSelect.js +190 -0
  474. package/fe/packages/react/ui/components/TreeSelect/index.d.ts +2 -0
  475. package/fe/packages/react/ui/components/TreeSelect/index.js +2 -0
  476. package/fe/packages/react/ui/components/Upload/ImageUpload.js +101 -0
  477. package/fe/packages/{ui/react → react/ui}/components/Upload/Upload.d.ts +1 -1
  478. package/fe/packages/react/ui/components/Upload/Upload.js +29 -0
  479. package/fe/packages/react/ui/components/Upload/index.d.ts +3 -0
  480. package/fe/packages/react/ui/components/Upload/index.js +3 -0
  481. package/fe/packages/react/ui/components/breadcrumb/breadcrumb.js +155 -0
  482. package/fe/packages/react/ui/components/breadcrumb/index.d.ts +2 -0
  483. package/fe/packages/react/ui/components/breadcrumb/index.js +2 -0
  484. package/fe/packages/react/ui/components/hooks/useDropdownPositioning.js +121 -0
  485. package/fe/packages/react/ui/components/hooks/useInputController.js +39 -0
  486. package/fe/packages/react/ui/components/index.d.ts +36 -0
  487. package/fe/packages/react/ui/components/index.js +81 -0
  488. package/fe/packages/react/ui/components/table/index.d.ts +2 -0
  489. package/fe/packages/react/ui/components/table/index.js +2 -0
  490. package/fe/packages/{ui/react → react/ui}/components/table/table.d.ts +16 -3
  491. package/fe/packages/react/ui/components/table/table.js +166 -0
  492. package/fe/packages/react/ui/components/testPage/MenuTestPage.js +397 -0
  493. package/fe/packages/react/ui/components/testPage/index.js +1612 -0
  494. package/fe/packages/{ui/react → react/ui}/i18n/I18nProvider.d.ts +2 -2
  495. package/fe/packages/react/ui/i18n/I18nProvider.js +38 -0
  496. package/fe/packages/react/ui/i18n/index.d.ts +4 -0
  497. package/fe/packages/react/ui/i18n/index.js +7 -0
  498. package/fe/packages/react/ui/i18n/useI18n.d.ts +13 -0
  499. package/fe/packages/react/ui/i18n/useI18n.js +25 -0
  500. package/fe/packages/{ui/react → react/ui}/index.css +70 -9
  501. package/fe/packages/react/ui/index.d.ts +5 -0
  502. package/fe/packages/react/ui/index.js +58 -0
  503. package/fe/packages/{ui/react → react/ui}/lib/createStoreHook.d.ts +1 -1
  504. package/fe/packages/react/ui/lib/createStoreHook.js +9 -0
  505. package/fe/packages/{ui/react → react/ui}/lib/export.d.ts +1 -1
  506. package/fe/packages/react/ui/lib/export.js +112 -0
  507. package/fe/packages/react/ui/lib/utils.js +64 -0
  508. package/fe/packages/{ui/react → react/ui}/stores/breadcrumb.d.ts +1 -1
  509. package/fe/packages/react/ui/stores/breadcrumb.js +52 -0
  510. package/fe/packages/react/ui/stores/language.d.ts +4 -0
  511. package/fe/packages/react/ui/stores/language.js +4 -0
  512. package/fe/packages/react/ui/types/index.js +0 -0
  513. package/fe/typings/type.d.ts +1 -0
  514. package/model/index.d.ts +1 -1
  515. package/model/types/data/button.d.ts +4 -4
  516. package/model/types/data/component.d.ts +32 -47
  517. package/model/types/data/schema.d.ts +6 -6
  518. package/model/types/data/search.d.ts +1 -1
  519. package/model/types/index.d.ts +2 -1
  520. package/model/types/model.d.ts +19 -12
  521. package/package.json +37 -39
  522. package/types/app/controller/project.d.ts +14 -2
  523. package/types/app/controller/view.d.ts +1 -1
  524. package/types/app/extend/$fetch.d.ts +8 -0
  525. package/types/app/extend/db.d.ts +54 -1
  526. package/types/app/extend/render-view.d.ts +3 -0
  527. package/types/app/middleware/api-params-verify.d.ts +1 -1
  528. package/types/app/middleware/project-handler.d.ts +2 -2
  529. package/types/app/router/project.d.ts +1 -1
  530. package/types/app/service/base.d.ts +3 -4
  531. package/types/app/service/project.d.ts +7 -2
  532. package/types/app/type.d.ts +5 -3
  533. package/types/app/typings.d.ts +4 -2
  534. package/types/bundler/buildBE.d.ts +13 -0
  535. package/types/bundler/index.d.ts +4 -1
  536. package/types/bundler/state.d.ts +18 -0
  537. package/types/bundler/utils.d.ts +5 -0
  538. package/types/config/config.default.d.ts +33 -2
  539. package/types/index.d.ts +6 -5
  540. package/{fe/frontend/widgets/common/CRUD/CRUD.d.ts → types/packages/common/http/index.d.ts} +29 -10
  541. package/types/packages/common/i18n/default.d.ts +5 -0
  542. package/types/packages/common/i18n/en-US.d.ts +5 -0
  543. package/types/packages/common/i18n/index.d.ts +24 -0
  544. package/types/packages/common/i18n/types.d.ts +24 -0
  545. package/types/packages/common/index.d.ts +1 -0
  546. package/types/packages/core/index.d.ts +3 -3
  547. package/types/packages/core/loader/config.d.ts +6 -0
  548. package/types/packages/core/loader/controller.d.ts +14 -0
  549. package/types/packages/core/loader/extend.d.ts +6 -1
  550. package/types/packages/core/loader/middleware.d.ts +8 -0
  551. package/types/packages/core/loader/model.d.ts +22 -0
  552. package/types/packages/core/loader/router-schema.d.ts +15 -0
  553. package/types/packages/core/loader/router.d.ts +5 -0
  554. package/types/packages/core/loader/service.d.ts +14 -0
  555. package/types/packages/core/paths.d.ts +10 -7
  556. package/types/packages/core/types.d.ts +66 -3
  557. package/types/packages/utils/getAllFilesInFolder.d.ts +5 -0
  558. package/types/packages/utils/loadFile.d.ts +6 -0
  559. package/types/packages/utils/path.d.ts +18 -0
  560. package/types/scripts/vite-build/build.d.ts +24 -0
  561. package/types/scripts/vite-build/collect.d.ts +57 -0
  562. package/types/scripts/vite-build/constants.d.ts +6 -0
  563. package/types/scripts/vite-build/dts.d.ts +53 -0
  564. package/types/scripts/vite-build/index.d.ts +2 -0
  565. package/types/scripts/vite-build/normalize.d.ts +66 -0
  566. package/types/scripts/vite-build/plugins.d.ts +67 -0
  567. package/types/scripts/vite-build/resolve.d.ts +61 -0
  568. package/types/scripts/vite-build/types.d.ts +174 -0
  569. package/types/scripts/vite-build/utils.d.ts +35 -0
  570. package/types/typings/type.d.ts +1 -0
  571. package/cjs/app/README.md +0 -286
  572. package/cjs/app/data/signKey.js +0 -23
  573. package/esm/app/README.md +0 -286
  574. package/esm/app/data/signKey.js +0 -10
  575. package/fe/frontend/components/AsyncSelect/AsyncSelect.js +0 -32
  576. package/fe/frontend/components/AsyncSelect/index.d.ts +0 -4
  577. package/fe/frontend/components/AsyncSelect/index.js +0 -3
  578. package/fe/frontend/dash/Dashboard.d.ts +0 -7
  579. package/fe/frontend/dash/Dashboard.js +0 -73
  580. package/fe/frontend/dash/dash.entry.js +0 -93
  581. package/fe/frontend/dash/types.d.ts +0 -17
  582. package/fe/frontend/dash/types.js +0 -1
  583. package/fe/frontend/index.d.ts +0 -5
  584. package/fe/frontend/index.js +0 -2
  585. package/fe/frontend/main.css +0 -5
  586. package/fe/frontend/main.d.ts +0 -11
  587. package/fe/frontend/main.js +0 -19
  588. package/fe/frontend/testPage/index.js +0 -6
  589. package/fe/frontend/testPage/testPage.entry.d.ts +0 -2
  590. package/fe/frontend/testPage/testPage.entry.js +0 -3
  591. package/fe/frontend/typing/scalability.js +0 -1
  592. package/fe/frontend/typing/window.d.ts +0 -7
  593. package/fe/frontend/typing/window.js +0 -1
  594. package/fe/frontend/widgets/api/baseInfo.js +0 -15
  595. package/fe/frontend/widgets/common/CRUD/CRUD.js +0 -208
  596. package/fe/frontend/widgets/common/CRUD/index.d.ts +0 -2
  597. package/fe/frontend/widgets/common/CRUD/index.js +0 -1
  598. package/fe/frontend/widgets/common/auth/index.js +0 -20
  599. package/fe/frontend/widgets/common/generateMenuData.d.ts +0 -4
  600. package/fe/frontend/widgets/common/generateMenuData.js +0 -14
  601. package/fe/frontend/widgets/common/importComponent.js +0 -8
  602. package/fe/frontend/widgets/common/language.d.ts +0 -2
  603. package/fe/frontend/widgets/common/language.js +0 -9
  604. package/fe/frontend/widgets/common/logFn/index.js +0 -8
  605. package/fe/frontend/widgets/common/menu.js +0 -101
  606. package/fe/frontend/widgets/common/request.d.ts +0 -36
  607. package/fe/frontend/widgets/common/request.js +0 -133
  608. package/fe/frontend/widgets/components/BasePage/HeaderView.js +0 -16
  609. package/fe/frontend/widgets/components/Router/index.js +0 -11
  610. package/fe/frontend/widgets/components/Router/type.js +0 -1
  611. package/fe/frontend/widgets/defaultPages/Iframe/index.js +0 -14
  612. package/fe/frontend/widgets/defaultPages/Schema/components/CallCom/DetailPanel.js +0 -94
  613. package/fe/frontend/widgets/defaultPages/Schema/components/CallCom/PopFrom.js +0 -124
  614. package/fe/frontend/widgets/defaultPages/Schema/components/CallCom/data.d.ts +0 -3
  615. package/fe/frontend/widgets/defaultPages/Schema/components/CallCom/data.js +0 -6
  616. package/fe/frontend/widgets/defaultPages/Schema/components/SchemaSearch/index.js +0 -63
  617. package/fe/frontend/widgets/defaultPages/Schema/components/SchemaTable/index.js +0 -188
  618. package/fe/frontend/widgets/defaultPages/Schema/data/eventInfo.js +0 -6
  619. package/fe/frontend/widgets/defaultPages/Schema/data/index.js +0 -1
  620. package/fe/frontend/widgets/defaultPages/Schema/hooks/useComConfig.js +0 -14
  621. package/fe/frontend/widgets/defaultPages/Schema/index.js +0 -74
  622. package/fe/frontend/widgets/defaultPages/Schema/schemaType.js +0 -4
  623. package/fe/frontend/widgets/defaultPages/Schema/stores/schemaEventBus.js +0 -70
  624. package/fe/frontend/widgets/defaultPages/Schema/stores/schemaStore.js +0 -26
  625. package/fe/frontend/widgets/defaultPages/Schema/utils/fetchErrorShow.js +0 -8
  626. package/fe/frontend/widgets/defaultPages/Schema/utils/permissions.js +0 -3
  627. package/fe/frontend/widgets/defaultPages/Schema/utils/schemaConversion.d.ts +0 -3
  628. package/fe/frontend/widgets/defaultPages/Schema/utils/schemaConversion.js +0 -115
  629. package/fe/frontend/widgets/defaultPages/Schema/utils/validator.d.ts +0 -7
  630. package/fe/frontend/widgets/defaultPages/Schema/utils/validator.js +0 -36
  631. package/fe/frontend/widgets/defaultPages/SidebarSlotPage/SidebarSlotContainer.js +0 -38
  632. package/fe/frontend/widgets/defaultPages/SidebarSlotPage/index.js +0 -16
  633. package/fe/frontend/widgets/defaultPages/SidebarSlotPageTmp.js +0 -17
  634. package/fe/frontend/widgets/defaultPages/SlotPage/index.js +0 -26
  635. package/fe/frontend/widgets/defaultPages/Todo.d.ts +0 -3
  636. package/fe/frontend/widgets/defaultPages/Todo.js +0 -5
  637. package/fe/frontend/widgets/hooks/useCurrentMenuData.js +0 -28
  638. package/fe/frontend/widgets/hooks/useRouterParams.js +0 -11
  639. package/fe/frontend/widgets/store/mode.js +0 -37
  640. package/fe/model/types/data/button.js +0 -16
  641. package/fe/model/types/data/component.js +0 -11
  642. package/fe/model/types/data/fetchInfo.js +0 -1
  643. package/fe/model/types/data/schema.js +0 -1
  644. package/fe/model/types/data/search.js +0 -1
  645. package/fe/model/types/menuType.js +0 -1
  646. package/fe/model/types/model.js +0 -1
  647. package/fe/packages/common/array/index.js +0 -40
  648. package/fe/packages/common/cache/index.js +0 -1
  649. package/fe/packages/common/i18n/types.js +0 -1
  650. package/fe/packages/common/index.js +0 -9
  651. package/fe/packages/common/log/index.js +0 -176
  652. package/fe/packages/common/number/index.js +0 -10
  653. package/fe/packages/common/object/index.js +0 -25
  654. package/fe/packages/common/string/index.js +0 -17
  655. package/fe/packages/common/types/index.js +0 -1
  656. package/fe/packages/ui/react/components/Button/Button.js +0 -72
  657. package/fe/packages/ui/react/components/Button/SumbitButton.d.ts +0 -13
  658. package/fe/packages/ui/react/components/Button/SumbitButton.js +0 -25
  659. package/fe/packages/ui/react/components/Button/index.d.ts +0 -4
  660. package/fe/packages/ui/react/components/Button/index.js +0 -2
  661. package/fe/packages/ui/react/components/Checkbox/Checkbox.js +0 -39
  662. package/fe/packages/ui/react/components/Checkbox/index.d.ts +0 -2
  663. package/fe/packages/ui/react/components/Checkbox/index.js +0 -1
  664. package/fe/packages/ui/react/components/ConfirmDialog/ConfirmDialog.js +0 -11
  665. package/fe/packages/ui/react/components/ConfirmDialog/index.d.ts +0 -2
  666. package/fe/packages/ui/react/components/ConfirmDialog/index.js +0 -1
  667. package/fe/packages/ui/react/components/DataTable/ActionBtn.js +0 -94
  668. package/fe/packages/ui/react/components/DataTable/index.js +0 -155
  669. package/fe/packages/ui/react/components/Date/Calendar.js +0 -216
  670. package/fe/packages/ui/react/components/Date/Date.js +0 -201
  671. package/fe/packages/ui/react/components/Date/DateTestPage.js +0 -29
  672. package/fe/packages/ui/react/components/Date/LocaleContext.js +0 -8
  673. package/fe/packages/ui/react/components/Date/LocaleProvider.js +0 -24
  674. package/fe/packages/ui/react/components/Date/TimePicker.js +0 -78
  675. package/fe/packages/ui/react/components/Date/data.js +0 -4
  676. package/fe/packages/ui/react/components/Date/dateLocaleStore.js +0 -14
  677. package/fe/packages/ui/react/components/Date/dropdownPositioning.d.ts +0 -3
  678. package/fe/packages/ui/react/components/Date/dropdownPositioning.js +0 -12
  679. package/fe/packages/ui/react/components/Date/index.d.ts +0 -6
  680. package/fe/packages/ui/react/components/Date/index.js +0 -5
  681. package/fe/packages/ui/react/components/Date/locales.js +0 -21
  682. package/fe/packages/ui/react/components/Drawer/Drawer.js +0 -100
  683. package/fe/packages/ui/react/components/Drawer/index.d.ts +0 -3
  684. package/fe/packages/ui/react/components/Drawer/index.js +0 -1
  685. package/fe/packages/ui/react/components/Dropdown/Dropdown.js +0 -28
  686. package/fe/packages/ui/react/components/Dropdown/index.d.ts +0 -2
  687. package/fe/packages/ui/react/components/Dropdown/index.js +0 -1
  688. package/fe/packages/ui/react/components/Form/Form.js +0 -8
  689. package/fe/packages/ui/react/components/Form/FormItem.js +0 -43
  690. package/fe/packages/ui/react/components/Form/SchemaForm/data.js +0 -18
  691. package/fe/packages/ui/react/components/Form/SchemaForm/index.js +0 -79
  692. package/fe/packages/ui/react/components/Form/index.d.ts +0 -5
  693. package/fe/packages/ui/react/components/Form/index.js +0 -4
  694. package/fe/packages/ui/react/components/Form/useForm.d.ts +0 -3
  695. package/fe/packages/ui/react/components/Form/useForm.js +0 -1
  696. package/fe/packages/ui/react/components/ImagePreview/ImagePreview.js +0 -169
  697. package/fe/packages/ui/react/components/ImagePreview/PreviewImage.js +0 -28
  698. package/fe/packages/ui/react/components/ImagePreview/index.d.ts +0 -3
  699. package/fe/packages/ui/react/components/ImagePreview/index.js +0 -2
  700. package/fe/packages/ui/react/components/Input/Input.js +0 -61
  701. package/fe/packages/ui/react/components/Input/index.d.ts +0 -2
  702. package/fe/packages/ui/react/components/Input/index.js +0 -1
  703. package/fe/packages/ui/react/components/InputNumber/InputNumber.js +0 -144
  704. package/fe/packages/ui/react/components/InputNumber/index.d.ts +0 -2
  705. package/fe/packages/ui/react/components/InputNumber/index.js +0 -1
  706. package/fe/packages/ui/react/components/InputNumber/inputNumberUtils.js +0 -63
  707. package/fe/packages/ui/react/components/InputNumber/inputNumberUtils.test.js +0 -27
  708. package/fe/packages/ui/react/components/Label/Label.js +0 -35
  709. package/fe/packages/ui/react/components/Label/index.d.ts +0 -3
  710. package/fe/packages/ui/react/components/Label/index.js +0 -2
  711. package/fe/packages/ui/react/components/Menu/Menu.js +0 -102
  712. package/fe/packages/ui/react/components/Menu/MenuContext.js +0 -97
  713. package/fe/packages/ui/react/components/Menu/MenuItem.js +0 -33
  714. package/fe/packages/ui/react/components/Menu/SubMenu.js +0 -169
  715. package/fe/packages/ui/react/components/Menu/index.d.ts +0 -9
  716. package/fe/packages/ui/react/components/Menu/index.js +0 -5
  717. package/fe/packages/ui/react/components/Menu/menuTypes.js +0 -1
  718. package/fe/packages/ui/react/components/Menu/utils.js +0 -7
  719. package/fe/packages/ui/react/components/Message/Message.js +0 -58
  720. package/fe/packages/ui/react/components/Message/MessageManager.js +0 -90
  721. package/fe/packages/ui/react/components/Message/data.js +0 -1
  722. package/fe/packages/ui/react/components/Message/index.d.ts +0 -3
  723. package/fe/packages/ui/react/components/Message/index.js +0 -1
  724. package/fe/packages/ui/react/components/Modal/Modal.js +0 -14
  725. package/fe/packages/ui/react/components/Modal/ModalManager.js +0 -90
  726. package/fe/packages/ui/react/components/Modal/index.d.ts +0 -4
  727. package/fe/packages/ui/react/components/Modal/index.js +0 -2
  728. package/fe/packages/ui/react/components/Overlay/Overlay.js +0 -53
  729. package/fe/packages/ui/react/components/Overlay/index.d.ts +0 -3
  730. package/fe/packages/ui/react/components/Overlay/index.js +0 -1
  731. package/fe/packages/ui/react/components/Pagination/Pagination.js +0 -88
  732. package/fe/packages/ui/react/components/Pagination/index.d.ts +0 -2
  733. package/fe/packages/ui/react/components/Pagination/index.js +0 -1
  734. package/fe/packages/ui/react/components/Popup/Popup.js +0 -81
  735. package/fe/packages/ui/react/components/Popup/index.d.ts +0 -2
  736. package/fe/packages/ui/react/components/Popup/index.js +0 -1
  737. package/fe/packages/ui/react/components/Search/Search.js +0 -12
  738. package/fe/packages/ui/react/components/Search/index.d.ts +0 -2
  739. package/fe/packages/ui/react/components/Search/index.js +0 -1
  740. package/fe/packages/ui/react/components/Select/Select.js +0 -123
  741. package/fe/packages/ui/react/components/Select/dropdownPositioning.d.ts +0 -3
  742. package/fe/packages/ui/react/components/Select/dropdownPositioning.js +0 -13
  743. package/fe/packages/ui/react/components/Select/index.d.ts +0 -2
  744. package/fe/packages/ui/react/components/Select/index.js +0 -1
  745. package/fe/packages/ui/react/components/Skeleton/Skeleton.js +0 -31
  746. package/fe/packages/ui/react/components/Skeleton/index.d.ts +0 -3
  747. package/fe/packages/ui/react/components/Skeleton/index.js +0 -1
  748. package/fe/packages/ui/react/components/Switch/Switch.js +0 -22
  749. package/fe/packages/ui/react/components/Switch/index.d.ts +0 -2
  750. package/fe/packages/ui/react/components/Switch/index.js +0 -1
  751. package/fe/packages/ui/react/components/TableSearch/TableSearch.js +0 -121
  752. package/fe/packages/ui/react/components/TableSearch/index.d.ts +0 -2
  753. package/fe/packages/ui/react/components/TableSearch/index.js +0 -1
  754. package/fe/packages/ui/react/components/TableSearch/lang.js +0 -14
  755. package/fe/packages/ui/react/components/TableSearch/tableSearchLocaleStore.js +0 -11
  756. package/fe/packages/ui/react/components/Textarea/Textarea.js +0 -37
  757. package/fe/packages/ui/react/components/Textarea/index.d.ts +0 -2
  758. package/fe/packages/ui/react/components/Textarea/index.js +0 -1
  759. package/fe/packages/ui/react/components/Tooltip/Tooltip.js +0 -79
  760. package/fe/packages/ui/react/components/Tooltip/index.d.ts +0 -2
  761. package/fe/packages/ui/react/components/Tooltip/index.js +0 -1
  762. package/fe/packages/ui/react/components/TreeSelect/TreeSelect.js +0 -160
  763. package/fe/packages/ui/react/components/TreeSelect/index.d.ts +0 -2
  764. package/fe/packages/ui/react/components/TreeSelect/index.js +0 -1
  765. package/fe/packages/ui/react/components/Upload/ImageUpload.js +0 -75
  766. package/fe/packages/ui/react/components/Upload/Upload.js +0 -6
  767. package/fe/packages/ui/react/components/Upload/index.d.ts +0 -3
  768. package/fe/packages/ui/react/components/Upload/index.js +0 -2
  769. package/fe/packages/ui/react/components/breadcrumb/breadcrumb.js +0 -81
  770. package/fe/packages/ui/react/components/breadcrumb/index.d.ts +0 -2
  771. package/fe/packages/ui/react/components/breadcrumb/index.js +0 -1
  772. package/fe/packages/ui/react/components/hooks/useDropdownPositioning.js +0 -137
  773. package/fe/packages/ui/react/components/hooks/useInputController.js +0 -45
  774. package/fe/packages/ui/react/components/index.d.ts +0 -30
  775. package/fe/packages/ui/react/components/index.js +0 -29
  776. package/fe/packages/ui/react/components/table/index.d.ts +0 -2
  777. package/fe/packages/ui/react/components/table/index.js +0 -1
  778. package/fe/packages/ui/react/components/table/table.js +0 -20
  779. package/fe/packages/ui/react/components/testPage/MenuTestPage.js +0 -104
  780. package/fe/packages/ui/react/components/testPage/index.js +0 -314
  781. package/fe/packages/ui/react/hooks/useBreadcrumb.d.ts +0 -10
  782. package/fe/packages/ui/react/hooks/useBreadcrumb.js +0 -2
  783. package/fe/packages/ui/react/hooks/useExecuteOnce.js +0 -57
  784. package/fe/packages/ui/react/hooks/useInit.js +0 -9
  785. package/fe/packages/ui/react/hooks/useLanguage.d.ts +0 -2
  786. package/fe/packages/ui/react/hooks/useLanguage.js +0 -4
  787. package/fe/packages/ui/react/hooks/usePagination.js +0 -27
  788. package/fe/packages/ui/react/hooks/useRefState.js +0 -29
  789. package/fe/packages/ui/react/hooks/useWatch.js +0 -87
  790. package/fe/packages/ui/react/hooks/useWatch.test.js +0 -22
  791. package/fe/packages/ui/react/i18n/I18nProvider.js +0 -25
  792. package/fe/packages/ui/react/i18n/index.d.ts +0 -4
  793. package/fe/packages/ui/react/i18n/index.js +0 -3
  794. package/fe/packages/ui/react/i18n/useI18n.d.ts +0 -13
  795. package/fe/packages/ui/react/i18n/useI18n.js +0 -18
  796. package/fe/packages/ui/react/index.d.ts +0 -5
  797. package/fe/packages/ui/react/index.js +0 -6
  798. package/fe/packages/ui/react/lib/createStoreHook.js +0 -6
  799. package/fe/packages/ui/react/lib/export.js +0 -138
  800. package/fe/packages/ui/react/lib/utils.js +0 -70
  801. package/fe/packages/ui/react/stores/breadcrumb.js +0 -66
  802. package/fe/packages/ui/react/stores/language.d.ts +0 -4
  803. package/fe/packages/ui/react/stores/language.js +0 -2
  804. package/fe/packages/ui/react/types/index.js +0 -1
  805. package/fe/typings/type.js +0 -1
  806. package/types/app/data/signKey.d.ts +0 -1
  807. /package/fe/frontend/{dash → apps/dash}/dash.entry.d.ts +0 -0
  808. /package/fe/frontend/{testPage → apps/ui-components}/index.d.ts +0 -0
  809. /package/fe/frontend/{widgets → src}/common/auth/index.d.ts +0 -0
  810. /package/fe/frontend/{widgets → src}/components/Router/type.d.ts +0 -0
  811. /package/fe/frontend/{widgets → src}/defaultPages/Iframe/index.d.ts +0 -0
  812. /package/fe/frontend/{widgets/defaultPages/Schema → src/defaultPages/SchemaPage}/components/SchemaSearch/index.d.ts +0 -0
  813. /package/fe/frontend/{widgets/defaultPages/Schema → src/defaultPages/SchemaPage}/data/eventInfo.d.ts +0 -0
  814. /package/fe/frontend/{widgets/defaultPages/Schema → src/defaultPages/SchemaPage}/data/index.d.ts +0 -0
  815. /package/fe/frontend/{widgets/defaultPages/Schema → src/defaultPages/SchemaPage}/utils/permissions.d.ts +0 -0
  816. /package/fe/frontend/{widgets → src}/defaultPages/SidebarSlotPage/index.d.ts +0 -0
  817. /package/fe/frontend/{widgets → src}/defaultPages/SidebarSlotPageTmp.d.ts +0 -0
  818. /package/fe/frontend/{widgets → src}/defaultPages/SlotPage/index.d.ts +0 -0
  819. /package/fe/frontend/{widgets → src}/hooks/useCurrentMenuData.d.ts +0 -0
  820. /package/fe/frontend/{widgets → src}/hooks/useRouterParams.d.ts +0 -0
  821. /package/fe/packages/{ui/react → react}/hooks/useExecuteOnce.d.ts +0 -0
  822. /package/fe/packages/{ui/react → react}/hooks/useInit.d.ts +0 -0
  823. /package/fe/packages/{ui/react → react}/hooks/usePagination.d.ts +0 -0
  824. /package/fe/packages/{ui/react → react}/hooks/useWatch.d.ts +0 -0
  825. /package/fe/packages/{ui/react → react}/hooks/useWatch.test.d.ts +0 -0
  826. /package/fe/packages/{ui/react → react/ui}/assets/table/no-result.svg +0 -0
  827. /package/fe/packages/{ui/react → react/ui}/components/ConfirmDialog/ConfirmDialog.d.ts +0 -0
  828. /package/fe/packages/{ui/react → react/ui}/components/Date/Date.d.ts +0 -0
  829. /package/fe/packages/{ui/react → react/ui}/components/Date/DateTestPage.d.ts +0 -0
  830. /package/fe/packages/{ui/react → react/ui}/components/Date/LocaleContext.d.ts +0 -0
  831. /package/fe/packages/{ui/react → react/ui}/components/Date/TimePicker.d.ts +0 -0
  832. /package/fe/packages/{ui/react → react/ui}/components/Date/data.d.ts +0 -0
  833. /package/fe/packages/{ui/react → react/ui}/components/Date/locales.d.ts +0 -0
  834. /package/fe/packages/{ui/react → react/ui}/components/ImagePreview/ImagePreview.d.ts +0 -0
  835. /package/fe/packages/{ui/react → react/ui}/components/InputNumber/inputNumberUtils.d.ts +0 -0
  836. /package/fe/packages/{ui/react → react/ui}/components/InputNumber/inputNumberUtils.test.d.ts +0 -0
  837. /package/fe/packages/{ui/react → react/ui}/components/Menu/Menu.d.ts +0 -0
  838. /package/fe/packages/{ui/react → react/ui}/components/Menu/MenuContext.d.ts +0 -0
  839. /package/fe/packages/{ui/react → react/ui}/components/Menu/MenuItem.d.ts +0 -0
  840. /package/fe/packages/{ui/react → react/ui}/components/Menu/SubMenu.d.ts +0 -0
  841. /package/fe/packages/{ui/react → react/ui}/components/Menu/utils.d.ts +0 -0
  842. /package/fe/packages/{ui/react → react/ui}/components/Message/data.d.ts +0 -0
  843. /package/fe/packages/{ui/react → react/ui}/components/Pagination/Pagination.d.ts +0 -0
  844. /package/fe/packages/{ui/react → react/ui}/components/Popup/Popup.d.ts +0 -0
  845. /package/fe/packages/{ui/react → react/ui}/components/TableSearch/lang.d.ts +0 -0
  846. /package/fe/packages/{ui/react → react/ui}/components/Textarea/Textarea.d.ts +0 -0
  847. /package/fe/packages/{ui/react → react/ui}/components/Tooltip/Tooltip.d.ts +0 -0
  848. /package/fe/packages/{ui/react → react/ui}/components/TreeSelect/TreeSelect.d.ts +0 -0
  849. /package/fe/packages/{ui/react → react/ui}/components/Upload/ImageUpload.d.ts +0 -0
  850. /package/fe/packages/{ui/react → react/ui}/components/breadcrumb/breadcrumb.d.ts +0 -0
  851. /package/fe/packages/{ui/react → react/ui}/components/hooks/useDropdownPositioning.d.ts +0 -0
  852. /package/fe/packages/{ui/react → react/ui}/components/hooks/useInputController.d.ts +0 -0
  853. /package/fe/packages/{ui/react → react/ui}/components/testPage/MenuTestPage.d.ts +0 -0
  854. /package/fe/packages/{ui/react → react/ui}/components/testPage/index.d.ts +0 -0
  855. /package/fe/packages/{ui/react → react/ui}/lib/utils.d.ts +0 -0
  856. /package/fe/packages/{ui/react → react/ui}/types/index.d.ts +0 -0
package/README.md ADDED
@@ -0,0 +1,1723 @@
1
+ # @_tc/template-core
2
+
3
+ TemplateCore 是一个基于 TypeScript、Koa、React 的后台框架包。它把后端约定式加载、前端 Dashboard、Schema CRUD 页面、模型配置和类型扩展放到同一个 npm 包里,项目只需要按目录补充自己的 `app/`、`model/`、`frontend/`。
4
+
5
+ ## 安装
6
+
7
+ ```bash
8
+ pnpm add @_tc/template-core
9
+ ```
10
+
11
+ 要求:
12
+
13
+ - Node.js >= 18
14
+ - pnpm >= 8
15
+ - 使用内置前端时,需要安装 React、Vite 等 peer dependencies
16
+
17
+ ## 可选:给项目 AI 助手的文档与 Skill
18
+
19
+ 如果你在项目中让 AI 助手协助开发,可以让它优先读取 npm 包内的 `AGENT_README.md`。安装后的路径通常是 `node_modules/@_tc/template-core/AGENT_README.md`。这份文档面向“协助使用 TemplateCore 的 AI 助手”,覆盖公开入口、最小启动、目录约定、model 配置、前端使用和构建方式。
20
+
21
+ 包内附带两份 Agent Skill,本质是可复用的 Agent 指令包,采用渐进式披露(SKILL.md + reference/)结构。
22
+
23
+ | Skill | 用途 |
24
+ | --- | --- |
25
+ | `tc-generator` | 按 TemplateCore 约定生成项目、model 配置、Schema CRUD、controller 和 router。 |
26
+ | `tc-component-usage-skills` | 指导 Agent 选用和正确使用内置 React 组件库(Button、Form、DataTable、Modal 等)。 |
27
+
28
+ 如果你的 Agent 支持本地 skills 目录,可以从已安装的 npm 包复制安装。以 Codex 为例:
29
+
30
+ ```bash
31
+ mkdir -p “${CODEX_HOME:-$HOME/.codex}/skills”
32
+ cp -R node_modules/@_tc/template-core/.skills/tc-generator “${CODEX_HOME:-$HOME/.codex}/skills/tc-generator”
33
+ cp -R node_modules/@_tc/template-core/.skills/tc-component-usage-skills “${CODEX_HOME:-$HOME/.codex}/skills/tc-component-usage-skills”
34
+ ```
35
+
36
+ 安装后重启对应 Agent,让新 skill 生效。使用时可以直接说”用 tc-generator 生成一个商品管理模块”或”用 tc-component-usage-skills 帮我写一个带搜索的分页表格”。
37
+
38
+ 其他 Agent 如果不支持自动安装 skill,也可以直接读取 `.skills/tc-generator/SKILL.md` 或 `.skills/tc-component-usage-skills/SKILL.md`,再按需读取 `reference/` 下的参考文件。
39
+
40
+ ## 快速使用
41
+
42
+ 项目建议结构:
43
+
44
+ ```text
45
+ my-admin/
46
+ ├── app/
47
+ │ ├── controller/
48
+ │ │ └── product.ts
49
+ │ ├── router/
50
+ │ │ └── product.ts
51
+ │ └── service/
52
+ ├── config/
53
+ │ └── config.default.ts
54
+ ├── frontend/
55
+ │ ├── src/ # 库代码
56
+ │ ├── apps/ # 应用入口
57
+ │ └── extended/ # 扩展点
58
+ ├── model/
59
+ │ └── product/
60
+ │ ├── mode.ts
61
+ │ └── project/
62
+ │ └── demo.ts
63
+ ├── typing/
64
+ │ └── template-core.d.ts
65
+ └── index.ts
66
+ ```
67
+
68
+ 启动入口:
69
+
70
+ ```ts
71
+ import { join } from 'path'
72
+ import { serverStart } from '@_tc/template-core'
73
+ import { buildFE } from '@_tc/template-core/bundler'
74
+
75
+ async function main() {
76
+ await serverStart({
77
+ name: 'my-admin',
78
+ baseDir: join(__dirname, '.'),
79
+ pageBasePage: '/',
80
+ additionalPublicPaths: join(__dirname, 'dist/public'),
81
+ })
82
+
83
+ await buildFE('dev')
84
+ }
85
+
86
+ main().catch((error) => {
87
+ console.error(error)
88
+ process.exit(1)
89
+ })
90
+ ```
91
+
92
+ 只用后端能力时,可以不调用 `buildFE('dev')`。
93
+
94
+ ### serverStart 参数说明
95
+
96
+ | 参数 | 类型 | 必填 | 默认值 | 说明 |
97
+ | --- | --- | --- | --- | --- |
98
+ | `name` | `string` | 否 | - | 应用名称 |
99
+ | `baseDir` | `string` | 否 | - | 项目根目录,通常为 `join(__dirname, '.')` |
100
+ | `pageBasePage` | `string` | 否 | `'/'` | 页面访问前缀,所有前端页面路由的基础路径 |
101
+ | `homePage` | `string` | 否 | - | 应用首页路径 |
102
+ | `frameBaseDir` | `string` | 否 | - | 框架根目录,通常不需要手动设置 |
103
+ | `additionalPublicPaths` | `string | string[]` | 否 | - | 追加静态资源目录和 Nunjucks 模板查找目录,必须传绝对路径 |
104
+
105
+ 框架会自动读取 `config/config.default.ts` 中的配置(如 `port`、`env` 等)。
106
+
107
+ 静态资源挂载和 Nunjucks 模板查找顺序均为:框架 `app/public`、项目 `app/public`、`additionalPublicPaths`。当 `buildFE` 输出到自定义目录时,可以用 `additionalPublicPaths` 把该目录交给 Koa 提供静态资源访问和模板渲染。
108
+
109
+ ### buildFE 参数说明
110
+
111
+ ```ts
112
+ buildFE(mode: 'dev' | 'prod', options?: BuildFEOptions)
113
+ ```
114
+
115
+ **mode**:构建模式
116
+ - `'dev'`:开发模式,构建一次并监听业务 `frontend/` 变化后重建
117
+ - `'prod'`:生产模式,构建优化后的静态资源
118
+
119
+ **options.output**:构建输出位置
120
+ - `'frame'`(默认):输出到框架包内的 `node_modules/@_tc/template-core/app/public/dist`
121
+ - `'run'`:输出到项目根目录的 `app/public/dist`,适合 TypeScript 编译后的项目
122
+ - `() => string`:自定义函数,返回输出目录的绝对路径
123
+
124
+ 示例:
125
+
126
+ ```ts
127
+ // 开发模式,默认输出到框架包
128
+ buildFE('dev')
129
+
130
+ // 生产模式,输出到项目目录
131
+ buildFE('prod', { output: 'run' })
132
+
133
+ // 自定义输出路径
134
+ buildFE('prod', {
135
+ output: () => join(__dirname, 'dist/public')
136
+ })
137
+ ```
138
+
139
+ 配置文件:
140
+
141
+ ```ts
142
+ // config/config.default.ts
143
+ export default {
144
+ port: 9000,
145
+ }
146
+ ```
147
+
148
+ 访问默认后台:
149
+
150
+ ```text
151
+ http://localhost:9000/dash?projk=demo
152
+ ```
153
+
154
+ `projk` 对应 `model/{modelKey}/project/{projectKey}.ts` 里的 `projectKey`。
155
+
156
+ ## 公开入口
157
+
158
+ | 入口 | 用途 |
159
+ | --- | --- |
160
+ | `@_tc/template-core` | 服务启动、基础 Controller/Service、Koa 类型 |
161
+ | `@_tc/template-core/bundler` | 构建入口,提供前端资源构建 `buildFE` 和消费方 Node/backend 构建 `buildBE` |
162
+ | `@_tc/template-core/fe` | 前端初始化、Dash 路由扩展、请求方法、SchemaPage 事件、共享状态和内置前端组件 |
163
+ | `@_tc/template-core/fe/rc` | UI/SchemaForm 组件和类型 |
164
+ | `@_tc/template-core/fe/tailwind_ui.css` | 前端全局样式入口,源码对应 `frontend/src/main.css` |
165
+ | `@_tc/template-core/model` | model 配置类型 |
166
+
167
+ ## 样式与 Tailwind V4
168
+
169
+ 使用内置前端或 UI 组件时,需要引入包内样式。默认 `@_tc/template-core/fe` 的 `initApp` 会经过源码入口 `frontend/src/main.tsx` 引入 `frontend/src/main.css`;如果项目侧自定义入口、只使用 `fe/rc` 组件,或希望样式入口更明确,建议显式引入:
170
+
171
+ ```ts
172
+ // frontend/xxx/xxx.entry.tsx
173
+ import '@_tc/template-core/fe/tailwind_ui.css'
174
+ ```
175
+
176
+ 如果项目有自己的全局样式入口,也可以在 CSS 中引入:
177
+
178
+ ```css
179
+ /* frontend/main.css */
180
+ @import "@_tc/template-core/fe/tailwind_ui.css";
181
+
182
+ /* 扫描项目源码 */
183
+ @source "./**/*.{js,ts,jsx,tsx}";
184
+ @source "../model/**/*.{js,ts,jsx,tsx}";
185
+ ```
186
+
187
+ Tailwind V4 默认会忽略 `node_modules` 和 `.gitignore` 中的文件。如果没有使用上面的 `tailwind_ui.css`,或者项目侧构建链路绕过了 TemplateCore 的样式入口,需要手动把包加入 Tailwind 扫描:
188
+
189
+ ```css
190
+ /* frontend/main.css */
191
+ @import "tailwindcss";
192
+
193
+ @source "./**/*.{js,ts,jsx,tsx}";
194
+ @source "../model/**/*.{js,ts,jsx,tsx}";
195
+ @source "../node_modules/@_tc/template-core";
196
+ ```
197
+
198
+ VS Code 建议安装官方 Tailwind CSS IntelliSense 插件,并在工作区 `.vscode/settings.json` 指向项目 CSS 入口:
199
+
200
+ ```json
201
+ {
202
+ "tailwindCSS.experimental.configFile": "frontend/main.css",
203
+ "files.associations": {
204
+ "*.css": "tailwindcss"
205
+ },
206
+ "css.lint.unknownAtRules": "ignore"
207
+ }
208
+ ```
209
+
210
+ 多入口项目可以写成对象:
211
+
212
+ ```json
213
+ {
214
+ "tailwindCSS.experimental.configFile": {
215
+ "frontend/main.css": "frontend/**/*.{ts,tsx,js,jsx}",
216
+ "frontend/admin/admin.css": "frontend/admin/**/*.{ts,tsx,js,jsx}"
217
+ }
218
+ }
219
+ ```
220
+
221
+ ## 内置功能
222
+
223
+ - Koa 服务启动:`serverStart(options)`。
224
+ - 约定式加载:自动加载 `config`、`extend`、`router-schema`、`service`、`controller`、`middleware`、`router`。
225
+ - 双层 app:框架内置 `app/` 和项目 `app/` 一起加载。
226
+ - 默认项目接口:
227
+ - `GET /api/project/model_list`
228
+ - `GET /api/project/list`
229
+ - `GET /api/project/:key`
230
+ - React Dashboard:内置 `/dash` 页面入口。
231
+ - 组件预览页面:内置 `/ui-components` 页面,用于查看和测试框架内置的 UI 组件。
232
+ - 菜单渲染:支持 `schema`、`custom`、`iframe`、`sidebar`。
233
+ - Schema CRUD:根据 `model` 中的 `schemaConfig` 生成搜索、表格、新增、编辑、详情。
234
+ - 内置 UI 组件:提供丰富的 React 组件库,详见下方"内置 UI 组件"章节。
235
+ - API 中间件:错误处理、静态资源、body parser、项目上下文、接口签名、参数校验。
236
+ - 前端构建:扫描 `frontend/**/*.entry.{ts,tsx,js,jsx}`,输出服务端可渲染的 `.entry.tpl`。
237
+ - 类型扩展:支持扩展 SchemaForm、CallCom、KoaApp。
238
+
239
+ ## 前端公共能力
240
+
241
+ 项目侧需要 TemplateCore 前端能力时,优先从 `@_tc/template-core/fe` 导入,不要直接依赖 `frontend/src/common/...`、`frontend/src/defaultPages/...`、`frontend/src/stores/...` 这类内部路径。
242
+
243
+ ```ts
244
+ import {
245
+ apiFreezerStore,
246
+ AsyncSelect,
247
+ eventsInfo,
248
+ FreezeState,
249
+ get,
250
+ LanguageSwitch,
251
+ merge,
252
+ modeStore,
253
+ post,
254
+ request,
255
+ schemaEventBus,
256
+ schemaStore,
257
+ ThemeSwitch,
258
+ useApiFreezer,
259
+ useModeStore,
260
+ useSchemaStore,
261
+ } from '@_tc/template-core/fe'
262
+
263
+ import type {
264
+ CallComComponentsMap,
265
+ CallComRenderer,
266
+ DashComponentsMap,
267
+ DashRoutesExtender,
268
+ FormFieldSchema,
269
+ ApiFreezerRequestMatcher,
270
+ SchemaFormComponentsMap,
271
+ SchemaFormNamespace,
272
+ SelectProps,
273
+ } from '@_tc/template-core/fe'
274
+ ```
275
+
276
+ 当前公共入口包含:
277
+
278
+ | 类型 | 导出内容 |
279
+ | --- | --- |
280
+ | 应用启动 | `initApp` |
281
+ | 内置前端组件 | `AsyncSelect`、`LanguageSwitch`、`ThemeSwitch` |
282
+ | Dash 扩展类型 | `DashRoutesExtender`、`DashRoutesContext`、`DashComponentsMap`、`DashHeaderUserAreaProps` |
283
+ | SchemaPage 类型 | `CallComComponentsMap`、`CallComRenderer` |
284
+ | SchemaForm 类型 | `FormFieldSchema`、`SchemaFormComponentsMap`、`SchemaFormNamespace`、`SelectProps` |
285
+ | 请求方法 | `request`、`get`、`post`、`put`、`patch`、`del` |
286
+ | 请求冻结 | `apiFreezerStore`、`useApiFreezer`、`FreezeState`、`ApiFreezerRequestMatcher` |
287
+ | 事件工具 | `eventsInfo`、`merge` |
288
+ | 共享状态 | `modeStore`、`useModeStore`、`schemaStore`、`useSchemaStore`、`schemaEventBus` |
289
+
290
+ `modeStore` 管项目模型和当前项目数据,`schemaStore` 管当前 Schema 页面的 schema/cache,`schemaEventBus` 用来在 Search、Table、CallCom 之间通信。
291
+
292
+ ### 前端多语言
293
+
294
+ TemplateCore 前端复用 `@tc/ui-react/i18n`。框架内置中文、英文资源,项目可以继续追加自己的资源。
295
+
296
+ **追加自定义语言资源**:
297
+
298
+ ```ts
299
+ import { i18nStore } from '@tc/ui-react/i18n'
300
+
301
+ i18nStore.getState().addResources('zh-CN', {
302
+ business: {
303
+ product: {
304
+ menu: '商品管理',
305
+ name: '商品名称',
306
+ create: '新增商品',
307
+ createTitle: '新增商品',
308
+ },
309
+ },
310
+ })
311
+
312
+ i18nStore.getState().addResources('en-US', {
313
+ business: {
314
+ product: {
315
+ menu: 'Products',
316
+ name: 'Product name',
317
+ create: 'Create product',
318
+ createTitle: 'Create product',
319
+ },
320
+ },
321
+ })
322
+ ```
323
+
324
+ 资源注册时不写 `$i18n::` 前缀,配置中使用时才写:
325
+
326
+ ```ts
327
+ const title = '$i18n::business.product.createTitle'
328
+ ```
329
+
330
+ **在 model / Schema 配置中使用**:
331
+
332
+ ```ts
333
+ {
334
+ name: '$i18n::business.product.menu',
335
+ moduleType: 'schema',
336
+ schemaConfig: {
337
+ schema: {
338
+ type: 'object',
339
+ properties: {
340
+ name: {
341
+ type: 'string',
342
+ label: '$i18n::business.product.name',
343
+ minLength: 2,
344
+ createFormOption: {
345
+ comType: 'input',
346
+ },
347
+ tableOption: {},
348
+ searchOption: {},
349
+ },
350
+ },
351
+ required: ['name'],
352
+ },
353
+ tableConfig: {
354
+ headerButtons: [
355
+ {
356
+ label: '$i18n::business.product.create',
357
+ eventKey: 'callComponent',
358
+ eventOption: { comName: 'createForm' },
359
+ },
360
+ ],
361
+ },
362
+ componentConfig: {
363
+ createForm: {
364
+ title: '$i18n::business.product.createTitle',
365
+ saveBtnText: '$i18n::common.submit',
366
+ },
367
+ },
368
+ },
369
+ }
370
+ ```
371
+
372
+ 已支持 `$i18n::...` 的常用位置:
373
+
374
+ - 菜单名:`menu.name`
375
+ - 项目标题:`projectInfo.desc` 或回退的 `projectInfo.name`
376
+ - Schema 字段名:`schema.properties.*.label`
377
+ - 表格按钮和行按钮:`headerButtons.*.label`、`rowButtons.*.label`
378
+ - 弹窗、抽屉标题:`componentConfig.*.title`
379
+ - 表单保存按钮:`componentConfig.*.saveBtnText`
380
+ - 接口错误提示:`BaseResponse.message`
381
+
382
+ **切换语言**:
383
+
384
+ ```ts
385
+ import { i18nStore } from '@tc/ui-react/i18n'
386
+
387
+ i18nStore.getState().setLanguage('en-US')
388
+ i18nStore.getState().setLanguage('zh-CN')
389
+ ```
390
+
391
+ 默认会写入 localStorage,key 是 `tc_language`。刷新页面后会继续使用上次语言。
392
+
393
+ 项目页面可以直接使用语言选择组件:
394
+
395
+ ```tsx
396
+ import { LanguageSwitch } from '@_tc/template-core/fe'
397
+
398
+ export function Toolbar() {
399
+ return <LanguageSwitch />
400
+ }
401
+ ```
402
+
403
+ `LanguageSwitch` 默认提供 `zh-CN` 和 `en-US`,也支持传入 `options` 覆盖语言列表。组件内部会调用 `i18nStore.getState().setLanguage()`,因此会沿用 `tc_language` 的持久化行为。
404
+
405
+ **AJV 校验文案**:
406
+
407
+ Schema 表单校验会把 AJV keyword 映射到内置语言 key,覆盖 `required`、`type`、`format`、`minimum`、`maximum`、`minLength`、`maxLength`、`pattern`、`enum`、`oneOf`、`anyOf` 等常见规则。
408
+
409
+ 非必填字段为空时会跳过 AJV 校验,空值包括 `undefined`、`null`、空字符串、空数组和空对象。
410
+
411
+ 如果需要扩展更多 AJV 文案,在源码项目中同步增加:
412
+
413
+ 1. `frontend/src/defaultPages/SchemaPage/utils/validator.ts` 的 `formatError()` 映射。
414
+ 2. `frontend/src/language/zh-CN.ts` 和 `frontend/src/language/en-US.ts` 文案。
415
+ 3. `frontend/src/language/index.ts` 的 `frontendLangKeys`。
416
+
417
+ ### 前端主题切换
418
+
419
+ 项目页面可以使用 `ThemeSwitch` 切换浅色和深色模式:
420
+
421
+ ```tsx
422
+ import { ThemeSwitch } from '@_tc/template-core/fe'
423
+
424
+ export function Toolbar() {
425
+ return <ThemeSwitch />
426
+ }
427
+ ```
428
+
429
+ `ThemeSwitch` 会切换 `document.documentElement` 上的 `dark` class,并同步 `color-scheme`。默认写入 localStorage,key 是 `tc_theme`。刷新页面后会优先读取本地主题;没有本地主题时,读取当前根节点是否已有 `dark` class。
430
+
431
+ 常用参数:
432
+
433
+ | 参数 | 说明 |
434
+ | --- | --- |
435
+ | `value` / `onChange` | 受控模式,值为 `light` 或 `dark`。 |
436
+ | `defaultValue` | 非受控初始主题。 |
437
+ | `showLabel` | 是否展示当前主题文本。 |
438
+ | `persist` | 是否写入 localStorage,默认 `true`。 |
439
+ | `storageKey` | 自定义本地存储 key,默认 `tc_theme`。 |
440
+
441
+ ### 前端请求封装详解
442
+
443
+ 框架内置的请求封装基于 `@tc/common/http`,底层使用原生 `fetch` API,实现了类似 Axios 的接口和拦截器机制,提供了签名、鉴权、错误处理等能力。
444
+
445
+ **基础配置**:
446
+ - `BASE_URL`:固定为 `/api`
447
+ - `timeout`:15000ms(15秒)
448
+ - `credentials`:`'include'`,支持跨域携带 cookie
449
+ - `window._signKey`:由服务端页面模板从 `app.config.signKey` 注入
450
+
451
+ **请求拦截器**:
452
+
453
+ 每个请求会自动添加以下 headers:
454
+
455
+ ```ts
456
+ {
457
+ 's_t': '当前时间戳',
458
+ 's_sign': 'md5(签名密钥_时间戳)',
459
+ 'projk': '当前项目 key(从 localStorage 读取)',
460
+ 'Authorization': 'Bearer token(如果已登录)'
461
+ }
462
+ ```
463
+
464
+ **签名机制**:
465
+ - 签名密钥:服务端从 `app.config.signKey` 读取,并在页面渲染时注入为 `window._signKey`
466
+ - 签名算法:`md5(签名密钥_${时间戳})`
467
+ - 服务端会在非 local 环境下校验签名和时间戳
468
+
469
+ **响应拦截器**:
470
+
471
+ - **401 处理**:自动清空 token 并跳转到 `/login`
472
+ - **错误提取**:自动从响应中提取 `message`、`msg` 或 `errors` 字段
473
+ - **超时处理**:请求超时会返回当前语言的超时提示
474
+ - **网络错误**:网络异常会返回当前语言的网络错误提示
475
+
476
+ **使用示例**:
477
+
478
+ ```ts
479
+ import { get, post, put, del } from '@_tc/template-core/fe'
480
+
481
+ // GET 请求
482
+ const data = await get('/product/list', { page: 1, pageSize: 10 })
483
+
484
+ // POST 请求
485
+ const result = await post('/product', { name: '商品名称', price: 100 })
486
+
487
+ // PUT 请求
488
+ await put('/product', { id: 1, name: '新名称' })
489
+
490
+ // DELETE 请求
491
+ await del('/product', { id: 1 })
492
+ ```
493
+
494
+ **请求冻结器**:
495
+
496
+ 请求冻结器用于在某段流程中暂停普通 API 请求,典型场景是 RT 刷新 token:刷新期间冻结其它请求,刷新接口本身走白名单放行,刷新完成后再解冻并回放队列。
497
+
498
+ 冻结器只在 `Freeze` 状态拦截请求;`Hibernation` 和 `Thawing` 状态都会直接放行。解冻时会按最多 4 个并发回放已冻结的请求;相同序列化参数的请求只会实际发送一次,多个调用方共享同一份响应或错误。
499
+
500
+ ```ts
501
+ import { apiFreezerStore } from '@_tc/template-core/fe'
502
+
503
+ const { freezing, thawing, setRequestWhitelist } = apiFreezerStore.getState()
504
+
505
+ setRequestWhitelist([
506
+ '/auth/refresh',
507
+ /^\/auth\//,
508
+ (api) => api.includes('/refresh-token'),
509
+ ])
510
+
511
+ freezing()
512
+
513
+ try {
514
+ await refreshToken()
515
+ } finally {
516
+ thawing()
517
+ }
518
+ ```
519
+
520
+ 白名单支持三种 matcher:
521
+
522
+ - `string`:精确匹配 API 路径
523
+ - `RegExp`:正则匹配 API 路径
524
+ - `(api, params) => boolean`:自定义判断,`params` 是请求函数收到的完整参数
525
+
526
+ **注意事项**:
527
+ - `get` 和 `del` 方法的参数会自动转为 query string
528
+ - `post`、`put`、`patch` 方法的参数会作为 request body
529
+ - 所有请求方法都会自动处理错误,无需手动 try-catch(除非需要自定义错误处理)
530
+ - 底层使用原生 `fetch` API,但提供了类似 Axios 的拦截器和配置接口
531
+
532
+ ## 内置 UI 组件
533
+
534
+ 框架通过 `@_tc/template-core/fe/rc` 提供了丰富的 React 组件库,可在项目中直接使用。
535
+
536
+ ### 基础组件
537
+
538
+ | 组件 | 用途 | 导入路径 |
539
+ | --- | --- | --- |
540
+ | `Button` | 按钮组件,支持多种样式和尺寸 | `@_tc/template-core/fe/rc` |
541
+ | `Input` | 输入框组件 | `@_tc/template-core/fe/rc` |
542
+ | `InputNumber` | 数字输入框组件 | `@_tc/template-core/fe/rc` |
543
+ | `Textarea` | 多行文本输入框组件 | `@_tc/template-core/fe/rc` |
544
+ | `Select` | 下拉选择组件,支持单选和多选 | `@_tc/template-core/fe/rc` |
545
+ | `Search` | 搜索输入组件 | `@_tc/template-core/fe/rc` |
546
+ | `TreeSelect` | 树形选择组件 | `@_tc/template-core/fe/rc` |
547
+ | `Dropdown` | 下拉菜单组件 | `@_tc/template-core/fe/rc` |
548
+ | `DatePicker` | 日期选择器 | `@_tc/template-core/fe/rc` |
549
+ | `Upload` | 文件上传组件 | `@_tc/template-core/fe/rc` |
550
+ | `FileUpload` | 通用文件上传组件 | `@_tc/template-core/fe/rc` |
551
+ | `ImageUpload` | 图片上传组件 | `@_tc/template-core/fe/rc` |
552
+ | `ImagePreview` | 图片预览组件 | `@_tc/template-core/fe/rc` |
553
+ | `Checkbox` | 复选框组件 | `@_tc/template-core/fe/rc` |
554
+ | `Radio` | 单选框组件 | `@_tc/template-core/fe/rc` |
555
+ | `Switch` | 开关组件 | `@_tc/template-core/fe/rc` |
556
+
557
+ ### 表单组件
558
+
559
+ | 组件 | 用途 | 导入路径 |
560
+ | --- | --- | --- |
561
+ | `Form` | 表单容器组件 | `@_tc/template-core/fe/rc` |
562
+ | `SchemaForm` | 配置驱动的表单组件,根据 schema 自动生成表单 | `@_tc/template-core/fe/rc` |
563
+ | `FormItem` | 表单项组件 | `@_tc/template-core/fe/rc` |
564
+
565
+ ### 数据展示组件
566
+
567
+ | 组件 | 用途 | 导入路径 |
568
+ | --- | --- | --- |
569
+ | `DataTable` | 数据表格组件,支持分页、排序、筛选 | `@_tc/template-core/fe/rc` |
570
+ | `Table` | 表格组件(含表头、列配置等子组件) | `@_tc/template-core/fe/rc` |
571
+ | `TableSearch` | 表格搜索组件,配合 DataTable 使用 | `@_tc/template-core/fe/rc` |
572
+ | `Pagination` | 分页组件 | `@_tc/template-core/fe/rc` |
573
+ | `Breadcrumb` | 面包屑导航组件 | `@_tc/template-core/fe/rc` |
574
+ | `Calendar` | 日历组件 | `@_tc/template-core/fe/rc` |
575
+ | `TimePicker` | 时间选择器组件 | `@_tc/template-core/fe/rc` |
576
+ | `Skeleton` | 骨架屏加载占位组件 | `@_tc/template-core/fe/rc` |
577
+
578
+ ### 反馈组件
579
+
580
+ | 组件 | 用途 | 导入路径 |
581
+ | --- | --- | --- |
582
+ | `Modal` | 模态框组件 | `@_tc/template-core/fe/rc` |
583
+ | `Drawer` | 抽屉组件 | `@_tc/template-core/fe/rc` |
584
+ | `Message` | 消息提示组件 | `@_tc/template-core/fe/rc` |
585
+ | `Notification` | 通知组件 | `@_tc/template-core/fe/rc` |
586
+ | `ConfirmDialog` | 确认对话框组件 | `@_tc/template-core/fe/rc` |
587
+ | `Popup` | 弹出层组件 | `@_tc/template-core/fe/rc` |
588
+ | `Tooltip` | 文字提示组件 | `@_tc/template-core/fe/rc` |
589
+ | `Overlay` | 页面遮罩层组件 | `@_tc/template-core/fe/rc` |
590
+ | `Loading` | 加载状态组件 | `@_tc/template-core/fe/rc` |
591
+
592
+ ### 布局组件
593
+
594
+ | 组件 | 用途 | 导入路径 |
595
+ | --- | --- | --- |
596
+ | `Layout` | 页面布局组件 | `@_tc/template-core/fe/rc` |
597
+ | `Card` | 卡片容器组件 | `@_tc/template-core/fe/rc` |
598
+ | `Tabs` | 标签页组件 | `@_tc/template-core/fe/rc` |
599
+ | `Menu` | 菜单组件(含 MenuItem 等子组件) | `@_tc/template-core/fe/rc` |
600
+ | `Label` | 标签组件 | `@_tc/template-core/fe/rc` |
601
+
602
+ ### 按钮组件
603
+
604
+ | 组件 | 用途 | 导入路径 |
605
+ | --- | --- | --- |
606
+ | `Button` | 通用按钮组件 | `@_tc/template-core/fe/rc` |
607
+ | `AsynchronousButton` | 异步按钮组件,支持加载状态 | `@_tc/template-core/fe/rc` |
608
+ | `SubmitButton` | 表单提交按钮组件 | `@_tc/template-core/fe/rc` |
609
+ | `ActionBtn` | 操作按钮组件 | `@_tc/template-core/fe/rc` |
610
+
611
+ ### 使用示例
612
+
613
+ ```tsx
614
+ import { Button, Input, Select, Modal, DataTable } from '@_tc/template-core/fe/rc'
615
+
616
+ function MyComponent() {
617
+ return (
618
+ <div>
619
+ <Button variant="primary" onClick={() => console.log('clicked')}>
620
+ 点击我
621
+ </Button>
622
+
623
+ <Input placeholder="请输入内容" />
624
+
625
+ <Select
626
+ options={[
627
+ { label: '选项1', value: '1' },
628
+ { label: '选项2', value: '2' },
629
+ ]}
630
+ />
631
+ </div>
632
+ )
633
+ }
634
+ ```
635
+
636
+ **注意**:
637
+ - 所有组件都支持 TypeScript 类型提示
638
+ - 组件样式基于 Tailwind CSS V4
639
+ - 详细的组件 API 和示例可以访问 `/ui-components` 页面查看
640
+
641
+ ## 后端约定
642
+
643
+ 项目目录会按下面规则加载:
644
+
645
+ ```text
646
+ app/controller/**/*.(js|ts) -> app.controller
647
+ app/service/**/*.(js|ts) -> app.service
648
+ app/middleware/**/*.(js|ts) -> app.middlewares
649
+ app/router/**/*.(js|ts) -> Koa router
650
+ app/router-schema/**/*.(js|ts) -> app.routerSchema
651
+ app/extend/*.(js|ts) -> app.extends
652
+ config/config.default.(js|ts) -> app.config
653
+ config/config.{env}.(js|ts) -> app.config
654
+ model/**/*.(js|ts) -> 项目模型配置
655
+ ```
656
+
657
+ 内置扩展:
658
+
659
+ - `app.extends.$fetch`:Node 侧基于 `fetch` 的 axios 风格请求实例,支持 `get/post/put/patch/delete` 和 `create(config)`。
660
+ - `app.extends.db`:默认 SQLite 框架数据库,提供 `getDBData/setDBData` 等通用数据方法。
661
+
662
+ ### 数据库扩展
663
+
664
+ 默认 `app.extends.db` 使用 SQLite 保存数据,数据库文件位于项目根目录 `.template-core/template-core.sqlite`。可以在配置中调整路径:
665
+
666
+ ```ts
667
+ // config/config.default.ts
668
+ export default {
669
+ db: {
670
+ path: 'data/app.sqlite',
671
+ },
672
+ }
673
+ ```
674
+
675
+ Controller 中使用:
676
+
677
+ ```ts
678
+ import { baseFn, type ControllerFN, type Ctx } from '@_tc/template-core'
679
+
680
+ const getSettingController = ((app) => {
681
+ const BaseController = baseFn.baseControllerFn(app)
682
+
683
+ return class SettingController extends BaseController {
684
+ detail = async (ctx: Ctx) => {
685
+ const data = app.extends.db.getDBData('site-setting', {
686
+ namespace: 'setting',
687
+ })
688
+
689
+ this.success(ctx, data ?? {})
690
+ }
691
+
692
+ save = async (ctx: Ctx) => {
693
+ app.extends.db.setDBData('site-setting', ctx.request.body, {
694
+ namespace: 'setting',
695
+ })
696
+
697
+ this.success(ctx, true)
698
+ }
699
+ }
700
+ }) satisfies ControllerFN
701
+
702
+ export default getSettingController
703
+ ```
704
+
705
+ 常用方法:
706
+
707
+ - `getDBData(key, options)`:读取 JSON 数据。
708
+ - `setDBData(key, value, options)`:写入 JSON 数据。
709
+ - `hasDBData(key, options)`:判断数据是否存在。
710
+ - `deleteDBData(key, options)`:删除单条数据。
711
+ - `listDBData(options)`:分页列出当前 namespace 下的数据。
712
+ - `countDBData(options)` / `clearDBData(options)`:统计和清空当前 namespace。
713
+ - `queryDB(sql, params)` / `runDB(sql, params)`:直接执行 SQLite SQL。
714
+ - `transactionDB(handler)`:事务执行。
715
+ - `closeDB()`:关闭连接。
716
+
717
+ SQL 注入边界:
718
+
719
+ - `getDBData`、`setDBData`、`deleteDBData`、`listDBData` 这类通用方法内部使用参数绑定,不需要手写 SQL。
720
+ - `queryDB`、`runDB`、`getDBFirst` 是原始 SQL 入口,用户输入必须放到 `params`,不要拼接到 SQL 字符串里。
721
+ - `execDB` 没有参数绑定能力,只建议用于固定 SQL,例如建表或迁移。
722
+
723
+ ```ts
724
+ // 推荐:参数绑定
725
+ const users = app.extends.db.queryDB(
726
+ 'SELECT * FROM user WHERE name = ?',
727
+ [ctx.query.name as string]
728
+ )
729
+
730
+ // 不推荐:拼接用户输入,有 SQL 注入风险
731
+ const unsafeUsers = app.extends.db.queryDB(
732
+ `SELECT * FROM user WHERE name = '${ctx.query.name}'`
733
+ )
734
+ ```
735
+
736
+ 业务项目可以用自己的 `app/extend/db.ts` 覆盖默认实现。建议保留同一组方法名,这样 controller/service 调用方不用调整。
737
+
738
+ ```ts
739
+ // app/extend/db.ts
740
+ import type { DB, DBFactory } from '@_tc/template-core'
741
+
742
+ interface DataOptions {
743
+ namespace?: string
744
+ }
745
+
746
+ const store = new Map<string, unknown>()
747
+
748
+ const getDB = ((_app) => {
749
+ const toKey = (key: string, namespace = 'framework') => `${namespace}:${key}`
750
+
751
+ const db = {
752
+ dbPath: 'memory',
753
+ getDBConnection: () => {
754
+ throw new Error('memory db 没有底层 SQLite connection')
755
+ },
756
+ execDB: () => undefined,
757
+ runDB: () => ({ changes: 0, lastInsertRowid: 0 }),
758
+ queryDB: <T extends object = Record<string, unknown>>() => [] as T[],
759
+ getDBFirst: <T extends object = Record<string, unknown>>() => undefined as T | undefined,
760
+ transactionDB: <T>(handler: (db: DB) => T) => handler(db),
761
+ getDBData: <T = unknown>(key: string, options?: DataOptions) => {
762
+ return store.get(toKey(key, options?.namespace)) as T | undefined
763
+ },
764
+ getDBDataRecord: <T = unknown>(key: string, options?: DataOptions) => {
765
+ const value = store.get(toKey(key, options?.namespace)) as T | undefined
766
+ if (value === undefined) return undefined
767
+
768
+ return {
769
+ key,
770
+ value,
771
+ namespace: options?.namespace ?? 'framework',
772
+ createdAt: '',
773
+ updatedAt: '',
774
+ }
775
+ },
776
+ setDBData: <T = unknown>(key: string, value: T, options?: DataOptions) => {
777
+ store.set(toKey(key, options?.namespace), value)
778
+ return { changes: 1, lastInsertRowid: 0 }
779
+ },
780
+ hasDBData: (key: string, options?: DataOptions) => {
781
+ return store.has(toKey(key, options?.namespace))
782
+ },
783
+ deleteDBData: (key: string, options?: DataOptions) => {
784
+ return store.delete(toKey(key, options?.namespace))
785
+ },
786
+ listDBData: <T = unknown>(options?: DataOptions) => {
787
+ const namespace = options?.namespace ?? 'framework'
788
+
789
+ return Array.from(store.entries())
790
+ .filter(([key]) => key.startsWith(`${namespace}:`))
791
+ .map(([key, value]) => ({
792
+ key: key.slice(namespace.length + 1),
793
+ value: value as T,
794
+ namespace,
795
+ createdAt: '',
796
+ updatedAt: '',
797
+ }))
798
+ },
799
+ countDBData: () => store.size,
800
+ clearDBData: () => {
801
+ const size = store.size
802
+ store.clear()
803
+ return size
804
+ },
805
+ closeDB: () => undefined,
806
+ } satisfies DB
807
+
808
+ return db
809
+ }) satisfies DBFactory
810
+
811
+ export default getDB
812
+ ```
813
+
814
+ Controller 示例:
815
+
816
+ ```ts
817
+ import { baseFn, type ControllerFN, type Ctx } from '@_tc/template-core'
818
+
819
+ const getProductController = ((app) => {
820
+ const BaseController = baseFn.baseControllerFn(app)
821
+
822
+ return class ProductController extends BaseController {
823
+ list = async (ctx: Ctx) => {
824
+ this.success(ctx, {
825
+ data: [],
826
+ page: 1,
827
+ pageSize: 10,
828
+ total: 0,
829
+ })
830
+ }
831
+ }
832
+ }) satisfies ControllerFN
833
+
834
+ export default getProductController
835
+ ```
836
+
837
+ Router 示例:
838
+
839
+ ```ts
840
+ import type { KoaApp, Router } from '@_tc/template-core'
841
+
842
+ export default (app: KoaApp, router: Router) => {
843
+ router.get('/api/product/list', app.controller.product.list)
844
+ }
845
+ ```
846
+
847
+ 路由挂载顺序:
848
+
849
+ - 每个 `app/router/*.ts` 文件都会获得独立的 `koa-router` 实例。
850
+ - 可以通过 `router.level = number` 控制挂载顺序,数值越小越早挂载。
851
+ - 默认 `level` 是 `0`,框架兜底 router 是 `99`。
852
+ - 通配、兜底、重定向类路由建议设置较大的 `level`,避免抢先匹配业务 API。
853
+
854
+ ```ts
855
+ import type { KoaApp, Router } from '@_tc/template-core'
856
+
857
+ export default (app: KoaApp, router: Router) => {
858
+ router.level = 10
859
+ router.get('/api/fallback/:id', app.controller.fallback.detail)
860
+ }
861
+ ```
862
+
863
+ ## model 数据如何配置
864
+
865
+ `model` 是后台菜单、项目和 Schema 页面的数据源。框架会读取:
866
+
867
+ ```text
868
+ model/{modelKey}/mode.ts
869
+ model/{modelKey}/project/{projectKey}.ts
870
+ ```
871
+
872
+ `mode.ts` 定义模型模板:
873
+
874
+ ```ts
875
+ import type { ModelDataType } from '@_tc/template-core/model'
876
+
877
+ const model: ModelDataType = {
878
+ mode: 'MB',
879
+ name: '商品后台',
880
+ desc: '商品管理',
881
+ icon: '',
882
+ homePage: '/_sidebar_/product?projk=demo',
883
+ menuLayout: 'left',
884
+ menu: [
885
+ {
886
+ key: 'product',
887
+ name: '商品列表',
888
+ menuType: 'module',
889
+ moduleType: 'schema',
890
+ schemaConfig: {
891
+ api: '/api/product',
892
+ schema: {
893
+ type: 'object',
894
+ properties: {
895
+ product_id: {
896
+ type: 'string',
897
+ label: '商品 ID',
898
+ tableOption: { width: 160 },
899
+ detailPanelOption: {},
900
+ editFormOption: {
901
+ comType: 'input',
902
+ disabled: true,
903
+ },
904
+ },
905
+ product_name: {
906
+ type: 'string',
907
+ label: '商品名称',
908
+ tableOption: {},
909
+ searchOption: { comType: 'input' },
910
+ createFormOption: { comType: 'input' },
911
+ editFormOption: { comType: 'input' },
912
+ detailPanelOption: {},
913
+ },
914
+ price: {
915
+ type: 'number',
916
+ label: '价格',
917
+ tableOption: {},
918
+ createFormOption: { comType: 'inputNumber' },
919
+ editFormOption: { comType: 'inputNumber' },
920
+ detailPanelOption: {},
921
+ },
922
+ },
923
+ required: ['product_name'],
924
+ },
925
+ componentConfig: {
926
+ createForm: {
927
+ title: '新增商品',
928
+ saveBtnText: '创建',
929
+ },
930
+ editForm: {
931
+ title: '编辑商品',
932
+ saveBtnText: '保存',
933
+ fetchKey: 'product_id',
934
+ },
935
+ detailPanel: {
936
+ title: '商品详情',
937
+ fetchKey: 'product_id',
938
+ },
939
+ },
940
+ tableConfig: {
941
+ headerButtons: [
942
+ {
943
+ label: '新增',
944
+ eventKey: 'callComponent',
945
+ variant: 'primary',
946
+ eventOption: { comName: 'createForm' },
947
+ },
948
+ ],
949
+ rowButtons: [
950
+ {
951
+ label: '编辑',
952
+ eventKey: 'callComponent',
953
+ eventOption: { comName: 'editForm' },
954
+ },
955
+ {
956
+ label: '详情',
957
+ eventKey: 'callComponent',
958
+ eventOption: { comName: 'detailPanel' },
959
+ },
960
+ {
961
+ label: '删除',
962
+ eventKey: 'remove',
963
+ eventOption: {
964
+ params: {
965
+ product_id: '$schema::product_id',
966
+ },
967
+ },
968
+ },
969
+ ],
970
+ },
971
+ },
972
+ },
973
+ ],
974
+ }
975
+
976
+ export default model
977
+ ```
978
+
979
+ `name`、`desc`、`icon`、`homePage` 都是可选项。Dashboard 页头标题优先使用 `desc`,没有时回退到 `name`;`icon` 可以是图片地址、图片路径、data image 或普通文本。未配置 `homePage` 时会自动跳到第一个可用菜单;配置时必须命中菜单生成的真实路由,左侧布局通常是 `/_sidebar_/{menuKey}`,顶部布局通常是 `/{menuKey}`。
980
+
981
+ `project/demo.ts` 定义项目覆盖:
982
+
983
+ ```ts
984
+ export default {
985
+ name: 'Demo 企业',
986
+ desc: 'Demo 企业商品后台',
987
+ homePage: '/_sidebar_/product?projk=demo',
988
+ }
989
+ ```
990
+
991
+ 合并规则:
992
+
993
+ - `project` 会继承同目录上层 `mode`。
994
+ - 对象递归合并,`project` 覆盖 `mode`。
995
+ - 数组按 `key` 合并:同 key 覆盖,不同 key 新增。
996
+ - `model/index.ts` 或 `model/index.js` 会被 loader 跳过。
997
+
998
+ ### model 数组合并示例
999
+
1000
+ 假设 `mode.ts` 定义了两个菜单项:
1001
+
1002
+ ```ts
1003
+ // model/product/mode.ts
1004
+ export default {
1005
+ name: '商品后台',
1006
+ menu: [
1007
+ {
1008
+ key: 'product',
1009
+ name: '商品列表',
1010
+ menuType: 'module',
1011
+ moduleType: 'schema',
1012
+ schemaConfig: {
1013
+ api: '/api/product',
1014
+ // ... 省略 schema 配置
1015
+ },
1016
+ },
1017
+ {
1018
+ key: 'category',
1019
+ name: '分类管理',
1020
+ menuType: 'module',
1021
+ moduleType: 'schema',
1022
+ schemaConfig: {
1023
+ api: '/api/category',
1024
+ // ... 省略 schema 配置
1025
+ },
1026
+ },
1027
+ ],
1028
+ }
1029
+ ```
1030
+
1031
+ `project/demo.ts` 可以:
1032
+
1033
+ ```ts
1034
+ // model/product/project/demo.ts
1035
+ export default {
1036
+ name: 'Demo 企业商品后台',
1037
+ menu: [
1038
+ // 1. 覆盖:修改 product 菜单的名称和配置
1039
+ {
1040
+ key: 'product',
1041
+ name: 'Demo 商品', // 覆盖 name
1042
+ schemaConfig: {
1043
+ api: '/api/demo/product', // 覆盖 api
1044
+ },
1045
+ },
1046
+ // 2. 新增:添加 brand 菜单
1047
+ {
1048
+ key: 'brand',
1049
+ name: '品牌管理',
1050
+ menuType: 'module',
1051
+ moduleType: 'schema',
1052
+ schemaConfig: {
1053
+ api: '/api/brand',
1054
+ },
1055
+ },
1056
+ // 3. 继承:category 菜单未在 project 中定义,会完整继承 mode 的配置
1057
+ ],
1058
+ }
1059
+ ```
1060
+
1061
+ 合并后的结果:
1062
+
1063
+ ```ts
1064
+ {
1065
+ name: 'Demo 企业商品后台', // project 覆盖
1066
+ menu: [
1067
+ {
1068
+ key: 'product',
1069
+ name: 'Demo 商品', // project 覆盖
1070
+ menuType: 'module', // mode 继承
1071
+ moduleType: 'schema', // mode 继承
1072
+ schemaConfig: {
1073
+ api: '/api/demo/product', // project 覆盖
1074
+ // schema 配置会递归合并
1075
+ },
1076
+ },
1077
+ {
1078
+ key: 'category', // mode 完整继承
1079
+ name: '分类管理',
1080
+ menuType: 'module',
1081
+ moduleType: 'schema',
1082
+ schemaConfig: {
1083
+ api: '/api/category',
1084
+ },
1085
+ },
1086
+ {
1087
+ key: 'brand', // project 新增
1088
+ name: '品牌管理',
1089
+ menuType: 'module',
1090
+ moduleType: 'schema',
1091
+ schemaConfig: {
1092
+ api: '/api/brand',
1093
+ },
1094
+ },
1095
+ ],
1096
+ }
1097
+ ```
1098
+
1099
+ **关键点**:
1100
+ - 数组合并依赖 `key` 字段,确保每个菜单项都有唯一的 `key`
1101
+ - 同 `key` 的项会递归合并,不是简单替换
1102
+ - `project` 中未定义的项会完整继承 `mode` 的配置
1103
+
1104
+ ## model 数据如何引用
1105
+
1106
+ 后端可以直接调用 loader:
1107
+
1108
+ ```ts
1109
+ import { modelLoader, type KoaApp } from '@_tc/template-core'
1110
+
1111
+ export default (app: KoaApp) => {
1112
+ const modelList = modelLoader(app)
1113
+ return modelList
1114
+ }
1115
+ ```
1116
+
1117
+ 前端默认不直接读文件,而是通过内置接口获取:
1118
+
1119
+ ```text
1120
+ GET /api/project/model_list
1121
+ GET /api/project/list?projk=demo
1122
+ GET /api/project/demo
1123
+ ```
1124
+
1125
+ Dashboard 会根据 `projk` 请求 `/api/project/:key`,再按返回的 `menu` 渲染页面。
1126
+
1127
+ Schema 页面的接口约定:
1128
+
1129
+ ```text
1130
+ GET {api}/list -> 表格列表
1131
+ GET {api} -> 编辑/详情拉取,参数由 fetchKey 决定
1132
+ POST {api} -> 新增
1133
+ PUT {api} -> 编辑
1134
+ DELETE {api} -> 删除
1135
+ ```
1136
+
1137
+ `$schema::字段名` 表示从当前表格行读取字段值,常用于删除按钮参数。
1138
+
1139
+ ## 如何扩展组件
1140
+
1141
+ ### 扩展 Dashboard 顶部用户区域
1142
+
1143
+ 业务项目可以创建 `frontend/extended/dash/components.tsx`,通过组件映射填充内置 Dashboard 页头右侧区域。
1144
+
1145
+ ```tsx
1146
+ // frontend/extended/dash/components.tsx
1147
+ import type { DashComponentsMap } from '@_tc/template-core/fe'
1148
+
1149
+ const components = {
1150
+ 'HeaderView.userArea': ({ projectInfo }) => {
1151
+ return <div>{projectInfo?.name}</div>
1152
+ },
1153
+ } satisfies DashComponentsMap
1154
+
1155
+ export default components
1156
+ ```
1157
+
1158
+ 当前支持的 Dashboard 组件扩展槽位:
1159
+
1160
+ - `HeaderView.userArea`:Dashboard 顶部右侧区域。
1161
+
1162
+ ### 扩展 SchemaForm 字段组件
1163
+
1164
+ 1. 声明字段类型。
1165
+ 2. 注册运行时组件。
1166
+ 3. 在 `model` 的 `createFormOption`、`editFormOption`、`searchOption` 中使用。
1167
+
1168
+ 类型声明:
1169
+
1170
+ ```ts
1171
+ // typing/template-core.d.ts
1172
+ import '@_tc/template-core/fe/rc'
1173
+ import type { SelectProps } from '@_tc/template-core/fe/rc'
1174
+
1175
+ declare module '@_tc/template-core/fe/rc' {
1176
+ export namespace SchemaFormNamespace {
1177
+ interface FieldTypes {
1178
+ businessSelect: true
1179
+ }
1180
+
1181
+ interface PropsMap {
1182
+ businessSelect: SelectProps & {
1183
+ requestUrl?: string
1184
+ valueField?: string
1185
+ labelField?: string
1186
+ }
1187
+ }
1188
+ }
1189
+ }
1190
+ ```
1191
+
1192
+ 运行时注册:
1193
+
1194
+ ```ts
1195
+ // frontend/extended/SchemaForm/data.ts
1196
+ import React from 'react'
1197
+ import type { SchemaFormComponentsMap } from '@_tc/template-core/fe/rc'
1198
+
1199
+ const componentsMap = {
1200
+ businessSelect: React.lazy(async () => ({
1201
+ default: (await import('../../components/BusinessSelect')).BusinessSelect,
1202
+ })),
1203
+ } satisfies SchemaFormComponentsMap
1204
+
1205
+ export default componentsMap
1206
+ ```
1207
+
1208
+ model 中使用:
1209
+
1210
+ ```ts
1211
+ status: {
1212
+ type: 'string',
1213
+ label: '状态',
1214
+ searchOption: {
1215
+ comType: 'businessSelect',
1216
+ requestUrl: '/api/status/options',
1217
+ valueField: 'value',
1218
+ labelField: 'label',
1219
+ },
1220
+ }
1221
+ ```
1222
+
1223
+ ### 扩展 SchemaPage CallCom
1224
+
1225
+ CallCom 是 SchemaPage 中的弹窗、抽屉、面板类组件。内置组件有:
1226
+
1227
+ - `createForm`
1228
+ - `editForm`
1229
+ - `detailPanel`
1230
+
1231
+ 声明配置类型:
1232
+
1233
+ ```ts
1234
+ // typing/template-core.d.ts
1235
+ import '@_tc/template-core/model'
1236
+
1237
+ declare module '@_tc/template-core/model' {
1238
+ export namespace CallComNamespace {
1239
+ interface ConfigMap {
1240
+ auditPanel: {
1241
+ title: string
1242
+ fetchKey: string
1243
+ approveApi?: string
1244
+ }
1245
+ }
1246
+
1247
+ interface OptionMap {
1248
+ auditPanel: {
1249
+ visible?: boolean
1250
+ }
1251
+ }
1252
+ }
1253
+ }
1254
+ ```
1255
+
1256
+ 注册运行时组件:
1257
+
1258
+ ```ts
1259
+ // frontend/extended/SchemaPage/CallCom/data.ts
1260
+ import { lazy } from 'react'
1261
+ import type { CallComComponentsMap } from '@_tc/template-core/fe'
1262
+
1263
+ const componentsMap = {
1264
+ auditPanel: lazy(() => import('../../components/AuditPanel')),
1265
+ } satisfies CallComComponentsMap
1266
+
1267
+ export default componentsMap
1268
+ ```
1269
+
1270
+ 组件示例:
1271
+
1272
+ ```tsx
1273
+ // frontend/src/components/AuditPanel.tsx
1274
+ import { eventsInfo, merge, schemaEventBus } from '@_tc/template-core/fe'
1275
+
1276
+ export default function AuditPanel(props: {
1277
+ data: Record<string, unknown>
1278
+ comName: 'auditPanel'
1279
+ }) {
1280
+ const closeAndRefresh = () => {
1281
+ schemaEventBus.getState().emitCom({
1282
+ type: merge(eventsInfo.closeCom, eventsInfo.initTable),
1283
+ })
1284
+ }
1285
+
1286
+ return (
1287
+ <div>
1288
+ <div>审核对象:{String(props.data.id ?? '')}</div>
1289
+ <button onClick={closeAndRefresh}>完成</button>
1290
+ </div>
1291
+ )
1292
+ }
1293
+ ```
1294
+
1295
+ model 中使用:
1296
+
1297
+ ```ts
1298
+ componentConfig: {
1299
+ auditPanel: {
1300
+ title: '审核',
1301
+ fetchKey: 'id',
1302
+ approveApi: '/api/audit/approve',
1303
+ },
1304
+ },
1305
+ tableConfig: {
1306
+ rowButtons: [
1307
+ {
1308
+ label: '审核',
1309
+ eventKey: 'callComponent',
1310
+ eventOption: {
1311
+ comName: 'auditPanel',
1312
+ },
1313
+ },
1314
+ ],
1315
+ },
1316
+ ```
1317
+
1318
+ 字段级配置使用 `${组件名}Option`:
1319
+
1320
+ ```ts
1321
+ remark: {
1322
+ type: 'string',
1323
+ label: '备注',
1324
+ auditPanelOption: {
1325
+ visible: true,
1326
+ },
1327
+ }
1328
+ ```
1329
+
1330
+ ## 如何配置类型扩展
1331
+
1332
+ ### tsconfig
1333
+
1334
+ 如果项目分了后端、前端、model 多个 TS 上下文,确保它们都 include 同一份声明文件:
1335
+
1336
+ ```json
1337
+ {
1338
+ "include": ["app/**/*", "model/**/*", "frontend/**/*", "typing/**/*.d.ts"]
1339
+ }
1340
+ ```
1341
+
1342
+ ### SchemaForm 类型扩展
1343
+
1344
+ 扩展目标:
1345
+
1346
+ ```ts
1347
+ declare module '@_tc/template-core/fe/rc' {
1348
+ export namespace SchemaFormNamespace {
1349
+ interface FieldTypes {}
1350
+ interface PropsMap {}
1351
+ }
1352
+ }
1353
+ ```
1354
+
1355
+ - `FieldTypes` 用来增加字段类型名。
1356
+ - `PropsMap` 用来绑定该字段的 props 类型。
1357
+ - 类型声明只负责 TS 校验,运行时还必须在 `frontend/extended/SchemaForm/data.ts` 注册组件。
1358
+
1359
+ ### Model mode 类型扩展
1360
+
1361
+ `mode` 和对应的数据结构一起扩展。内置 `MB` 对应管理后台菜单结构 `MBMenuType`。
1362
+
1363
+ ```ts
1364
+ // typing/template-core.d.ts
1365
+ import '@_tc/template-core/model'
1366
+
1367
+ declare module '@_tc/template-core/model' {
1368
+ interface ModelModeMap {
1369
+ portal: {
1370
+ portalConfig: {
1371
+ title: string
1372
+ theme?: 'light' | 'dark'
1373
+ }
1374
+ }
1375
+ }
1376
+ }
1377
+ ```
1378
+
1379
+ 使用新 `mode`:
1380
+
1381
+ ```ts
1382
+ import type { ModelDataType } from '@_tc/template-core/model'
1383
+
1384
+ const model: ModelDataType<'portal'> = {
1385
+ mode: 'portal',
1386
+ name: '门户',
1387
+ desc: '门户配置',
1388
+ homePage: '/',
1389
+ portalConfig: {
1390
+ title: 'Portal',
1391
+ theme: 'light',
1392
+ },
1393
+ }
1394
+
1395
+ export default model
1396
+ ```
1397
+
1398
+ 继续使用内置管理后台时:
1399
+
1400
+ ```ts
1401
+ import type { ModelDataType } from '@_tc/template-core/model'
1402
+
1403
+ const model: ModelDataType<'MB'> = {
1404
+ mode: 'MB',
1405
+ name: '商品后台',
1406
+ desc: '商品管理',
1407
+ homePage: '/_sidebar_/product?projk=demo',
1408
+ menu: [],
1409
+ }
1410
+ ```
1411
+
1412
+ ### CallCom 类型扩展
1413
+
1414
+ 扩展目标:
1415
+
1416
+ ```ts
1417
+ declare module '@_tc/template-core/model' {
1418
+ export namespace CallComNamespace {
1419
+ interface ConfigMap {}
1420
+ interface OptionMap {}
1421
+ }
1422
+ }
1423
+ ```
1424
+
1425
+ - `ConfigMap` 对应 `schemaConfig.componentConfig.xxx`。
1426
+ - `OptionMap` 对应字段上的 `xxxOption`。
1427
+ - 运行时组件注册在 `frontend/extended/SchemaPage/CallCom/data.ts`。
1428
+
1429
+ ### KoaApp 类型扩展
1430
+
1431
+ 使用方推荐增强根包 `@_tc/template-core`:
1432
+
1433
+ ```ts
1434
+ // typing/template-core.d.ts
1435
+ import '@_tc/template-core'
1436
+
1437
+ declare module '@_tc/template-core' {
1438
+ namespace FrameworkAugment {
1439
+ interface IServiceAugmented {
1440
+ product: {
1441
+ list(): Promise<unknown[]>
1442
+ }
1443
+ }
1444
+
1445
+ interface IControllerAugmented {
1446
+ product: {
1447
+ list(ctx: import('@_tc/template-core').Ctx): Promise<void>
1448
+ }
1449
+ }
1450
+
1451
+ interface IExtendsAugmented {
1452
+ redis: {
1453
+ get(key: string): Promise<string | null>
1454
+ }
1455
+ }
1456
+
1457
+ interface IMiddlewaresAugmented {
1458
+ auth: import('koa').Middleware
1459
+ }
1460
+
1461
+ interface AppConfigAugmented {
1462
+ authSecret: string
1463
+ }
1464
+ }
1465
+ }
1466
+ ```
1467
+
1468
+ 使用:
1469
+
1470
+ ```ts
1471
+ import type { KoaApp } from '@_tc/template-core'
1472
+
1473
+ export default (app: KoaApp) => {
1474
+ app.config.authSecret
1475
+ app.service.product.list()
1476
+ app.extends.$fetch.get('https://example.com/api')
1477
+ app.extends.redis.get('token')
1478
+ }
1479
+ ```
1480
+
1481
+ 如果在 TemplateCore 仓库源码内部扩展,声明目标通常是内部别名 `@tc/core`;npm 使用方不要依赖 `@tc/*` 内部路径。
1482
+
1483
+ ## 扩展自定义前端页面
1484
+
1485
+ 新增应用入口:
1486
+
1487
+ ```text
1488
+ frontend/admin/admin.entry.tsx
1489
+ ```
1490
+
1491
+ 入口文件名必须包含 `.entry.`,构建器才会扫描。
1492
+
1493
+ 扩展 Dashboard 路由:
1494
+
1495
+ ```tsx
1496
+ // frontend/extended/dash/customRoutes.tsx
1497
+ import type { DashRoutesExtender } from '@_tc/template-core/fe'
1498
+
1499
+ const extendDashRoutes: DashRoutesExtender = ({ topRoutes, sidebarRoutes }) => {
1500
+ topRoutes.push({
1501
+ path: 'custom-page',
1502
+ component: <div>Custom Page</div>,
1503
+ })
1504
+
1505
+ sidebarRoutes.push({
1506
+ path: 'custom-sidebar-page',
1507
+ component: <div>Custom Sidebar Page</div>,
1508
+ })
1509
+ }
1510
+
1511
+ export default extendDashRoutes
1512
+ ```
1513
+
1514
+ **路径规则说明**:
1515
+
1516
+ - **topRoutes**:追加到 Dashboard 顶层路由,路径相对于 `/dash`
1517
+ - 示例:`path: 'custom-page'` → 访问路径为 `/dash/custom-page`
1518
+ - 不要写成 `/custom-page`,使用相对路径即可
1519
+
1520
+ - **sidebarRoutes**:追加到侧边栏容器的子路由,路径相对于 `/dash/_sidebar_`
1521
+ - 示例:`path: 'custom-sidebar-page'` → 访问路径为 `/dash/_sidebar_/custom-sidebar-page`
1522
+ - 适用于 `menuLayout: 'left'` 的项目
1523
+
1524
+ model 中用 `custom` 菜单指向自定义路径:
1525
+
1526
+ ```ts
1527
+ {
1528
+ key: 'custom',
1529
+ name: '自定义页面',
1530
+ menuType: 'module',
1531
+ moduleType: 'custom',
1532
+ customConfig: {
1533
+ path: '/custom-page', // 注意:这里使用完整路径,以 / 开头
1534
+ },
1535
+ }
1536
+ ```
1537
+
1538
+ ## 前端构建 buildFE
1539
+
1540
+ 开发构建:
1541
+
1542
+ ```ts
1543
+ import { buildFE } from '@_tc/template-core/bundler'
1544
+
1545
+ buildFE('dev')
1546
+ ```
1547
+
1548
+ 生产构建:
1549
+
1550
+ ```ts
1551
+ buildFE('prod')
1552
+ ```
1553
+
1554
+ 默认输出到框架包的 `app/public/dist`。如果要输出到项目:
1555
+
1556
+ ```ts
1557
+ buildFE('prod', {
1558
+ output: 'run',
1559
+ })
1560
+ ```
1561
+
1562
+ ## Node/backend 构建 buildBE
1563
+
1564
+ 消费方 Node/backend 侧构建使用 `buildBE()`。它复用发布包内的 `scripts/vite-build/buildEntries`,只是提供消费方默认配置。
1565
+
1566
+ 最小用法:
1567
+
1568
+ ```ts
1569
+ import { buildBE } from '@_tc/template-core/bundler'
1570
+
1571
+ await buildBE()
1572
+ ```
1573
+
1574
+ 消费方脚本示例:
1575
+
1576
+ ```js
1577
+ // scripts/build-be.mjs
1578
+ import { buildBE } from '@_tc/template-core/bundler'
1579
+
1580
+ await buildBE({
1581
+ rootDir: process.cwd(),
1582
+ input: ['index.ts', 'index.js', 'app', 'config', 'model'],
1583
+ outDir: 'dist',
1584
+ format: 'cjs',
1585
+ alias: {
1586
+ '@app': './app',
1587
+ '@model': './model',
1588
+ },
1589
+ })
1590
+ ```
1591
+
1592
+ ```json
1593
+ {
1594
+ "scripts": {
1595
+ "build:be": "node scripts/build-be.mjs"
1596
+ }
1597
+ }
1598
+ ```
1599
+
1600
+ 监听文件变化并重新构建:
1601
+
1602
+ ```js
1603
+ // scripts/watch-be.mjs
1604
+ import chokidar from 'chokidar'
1605
+ import { buildBE } from '@_tc/template-core/bundler'
1606
+
1607
+ const input = ['index.ts', 'index.js', 'app', 'config', 'model']
1608
+
1609
+ let building = false
1610
+ let pending = false
1611
+
1612
+ async function runBuild() {
1613
+ if (building) {
1614
+ pending = true
1615
+ return
1616
+ }
1617
+
1618
+ building = true
1619
+
1620
+ try {
1621
+ console.log('[buildBE] building...')
1622
+ await buildBE({
1623
+ rootDir: process.cwd(),
1624
+ input,
1625
+ outDir: 'dist',
1626
+ format: 'cjs',
1627
+ alias: {
1628
+ '@app': './app',
1629
+ '@model': './model',
1630
+ },
1631
+ })
1632
+ console.log('[buildBE] done')
1633
+ } catch (error) {
1634
+ console.error('[buildBE] failed')
1635
+ console.error(error)
1636
+ } finally {
1637
+ building = false
1638
+
1639
+ if (pending) {
1640
+ pending = false
1641
+ await runBuild()
1642
+ }
1643
+ }
1644
+ }
1645
+
1646
+ await runBuild()
1647
+
1648
+ chokidar
1649
+ .watch(input, {
1650
+ ignored: ['dist/**', 'node_modules/**'],
1651
+ ignoreInitial: true,
1652
+ })
1653
+ .on('all', async (_event, filePath) => {
1654
+ console.log(`[buildBE] changed: ${filePath}`)
1655
+ await runBuild()
1656
+ })
1657
+ ```
1658
+
1659
+ ```json
1660
+ {
1661
+ "scripts": {
1662
+ "build:be": "node scripts/build-be.mjs",
1663
+ "build:be:watch": "node scripts/watch-be.mjs"
1664
+ },
1665
+ "devDependencies": {
1666
+ "chokidar": "^4.0.3"
1667
+ }
1668
+ }
1669
+ ```
1670
+
1671
+ 默认会在当前工作目录构建这些入口:
1672
+
1673
+ ```ts
1674
+ ['index.ts', 'index.js', 'app', 'config', 'model']
1675
+ ```
1676
+
1677
+ 不存在的默认入口会自动跳过;如果没有任何匹配源码,构建仍会失败。输出到 `dist`,格式为 `cjs`。默认 `outputStructure: "preserve"` 按源路径输出,`bundleDependencies: false` 会 external Node 内置模块和 npm 包,不会把依赖打进产物。`buildBE` 会按同一组 input 扫描并复制内置白名单资源扩展,主要覆盖 `app`、`config`、`model` 目录。
1678
+
1679
+ 常见配置:
1680
+
1681
+ ```ts
1682
+ await buildBE({
1683
+ input: ['app', 'config', 'model'],
1684
+ outDir: 'dist',
1685
+ format: ['es', 'cjs'],
1686
+ alias: {
1687
+ '@app': './app',
1688
+ '@model': './model',
1689
+ },
1690
+ })
1691
+ ```
1692
+
1693
+ 如果需要声明文件:
1694
+
1695
+ ```ts
1696
+ await buildBE({
1697
+ dts: {
1698
+ outDir: 'types',
1699
+ tsconfig: 'tsconfig.json',
1700
+ },
1701
+ })
1702
+ ```
1703
+
1704
+ `buildEntries()` 底层默认生成 d.ts,但 `buildBE()` 默认关闭声明文件;需要时按上面这样显式传 `dts`。
1705
+
1706
+ 如果传入自定义 `input`,缺失路径默认会报错;需要跳过时显式打开:
1707
+
1708
+ ```ts
1709
+ await buildBE({
1710
+ input: ['app', 'config', 'model'],
1711
+ allowMissingInput: true,
1712
+ })
1713
+ ```
1714
+
1715
+ ## 注意事项
1716
+
1717
+ - 不要在项目代码里引用 `dist/fe/*`、`dist/model/*` 这类构建产物路径。
1718
+ - npm 使用方只使用公开入口:`@_tc/template-core/*`。
1719
+ - SchemaForm 和 CallCom 的类型扩展、运行时注册都要做,少一个就只会“类型通过但页面不显示”或“页面能配但类型报错”。
1720
+ - `model` 数组合并依赖稳定 `key`。
1721
+ - Dashboard 默认需要 URL 带 `?projk=项目key`。
1722
+ - 前端入口必须命名为 `.entry.tsx`、`.entry.ts`、`.entry.jsx` 或 `.entry.js`。
1723
+ - **使用方不建议在 `/frontend/apps/` 下保留 `html` 文件。** Vite 构建时会根据模板文件(`app/view/entry.tpl`)自动生成 html,如果保留 html 文件,可能与模板不同步而导致内容过时。