@_tc/template-core 0.0.3 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (177) hide show
  1. package/.skills/tc-generator/SKILL.md +62 -0
  2. package/.skills/tc-generator/reference/example.md +357 -0
  3. package/.skills/tc-generator/reference/model-schema.md +326 -0
  4. package/.skills/tc-generator/reference/project-template/app/controller/product.js +73 -0
  5. package/.skills/tc-generator/reference/project-template/app/router/product.js +9 -0
  6. package/.skills/tc-generator/reference/project-template/config/config.default.js +3 -0
  7. package/.skills/tc-generator/reference/project-template/index.js +17 -0
  8. package/.skills/tc-generator/reference/project-template/model/product/mode.js +179 -0
  9. package/.skills/tc-generator/reference/project-template/model/product/project/default.js +4 -0
  10. package/.skills/tc-generator/reference/project-template/package.json +10 -0
  11. package/README.md +239 -17
  12. package/cjs/_virtual/_rolldown/runtime.js +1 -1
  13. package/cjs/app/controller/base.js +1 -1
  14. package/cjs/app/controller/project.js +1 -1
  15. package/cjs/app/controller/view.js +1 -1
  16. package/cjs/app/extend/$fetch.js +1 -1
  17. package/cjs/app/extend/db.js +1 -1
  18. package/cjs/app/extend/generateErrorMessage.js +1 -1
  19. package/cjs/app/extend/logger.js +1 -1
  20. package/cjs/app/extend/parsingParamsOnUrl.js +1 -1
  21. package/cjs/app/middleware/api-sign-verify.js +1 -1
  22. package/cjs/app/middleware/error-handle.js +1 -1
  23. package/cjs/app/middleware/project-handler.js +1 -1
  24. package/cjs/app/middleware.js +1 -1
  25. package/cjs/app/router/project.js +1 -1
  26. package/cjs/app/router/view.js +1 -1
  27. package/cjs/app/router-schema/project.js +1 -1
  28. package/cjs/app/service/base.js +1 -1
  29. package/cjs/app/service/project.js +1 -1
  30. package/cjs/app/type.js +0 -1
  31. package/cjs/app/typings.js +0 -1
  32. package/cjs/app/view/entry.tpl +27 -28
  33. package/cjs/bundler/defaultAlias.js +1 -1
  34. package/cjs/bundler/dev.js +1 -1
  35. package/cjs/bundler/index.js +1 -1
  36. package/cjs/bundler/prod.js +1 -1
  37. package/cjs/bundler/state.js +1 -1
  38. package/cjs/config/config.default.js +1 -0
  39. package/cjs/index.js +1 -1
  40. package/cjs/packages/common/LRUCache.js +1 -1
  41. package/cjs/packages/common/array/index.js +1 -1
  42. package/cjs/packages/common/cache/LRUCache.js +1 -1
  43. package/cjs/packages/common/cache/index.js +1 -1
  44. package/cjs/packages/common/guards/index.js +1 -1
  45. package/cjs/packages/common/http/index.js +1 -1
  46. package/cjs/packages/common/i18n/default.js +1 -1
  47. package/cjs/packages/common/i18n/en-US.js +1 -1
  48. package/cjs/packages/common/i18n/index.js +1 -1
  49. package/cjs/packages/common/i18n/locales.js +1 -1
  50. package/cjs/packages/common/i18n/types.js +0 -1
  51. package/cjs/packages/common/index.js +1 -1
  52. package/cjs/packages/common/log/index.js +1 -1
  53. package/cjs/packages/common/number/index.js +1 -1
  54. package/cjs/packages/common/object/filterEmpty.js +1 -1
  55. package/cjs/packages/common/object/filtereEmpty.js +1 -1
  56. package/cjs/packages/common/object/index.js +1 -1
  57. package/cjs/packages/common/string/index.js +1 -1
  58. package/cjs/packages/common/types/index.js +0 -1
  59. package/cjs/packages/core/env.js +1 -1
  60. package/cjs/packages/core/index.js +1 -1
  61. package/cjs/packages/core/loader/config.js +1 -1
  62. package/cjs/packages/core/loader/controller.js +1 -1
  63. package/cjs/packages/core/loader/extend.js +1 -1
  64. package/cjs/packages/core/loader/middleware.js +1 -1
  65. package/cjs/packages/core/loader/router-schema.js +1 -1
  66. package/cjs/packages/core/loader/service.js +1 -1
  67. package/cjs/packages/core/paths.js +1 -1
  68. package/cjs/packages/core/types.js +0 -1
  69. package/cjs/packages/utils/getAllFnReturnValue.js +0 -1
  70. package/cjs/packages/utils/index.js +1 -1
  71. package/esm/_virtual/_rolldown/runtime.js +2 -15
  72. package/esm/app/controller/view.js +13 -11
  73. package/esm/app/middleware/api-sign-verify.js +9 -11
  74. package/esm/app/middleware.js +6 -6
  75. package/esm/app/view/entry.tpl +27 -28
  76. package/esm/config/config.default.js +9 -0
  77. package/esm/index.js +1 -1
  78. package/esm/packages/core/index.js +24 -26
  79. package/esm/packages/core/loader/config.js +11 -10
  80. package/esm/packages/core/loader/extend.js +13 -8
  81. package/fe/frontend/apps/dash/Dashboard.js +100 -1
  82. package/fe/frontend/apps/dash/dash.entry.js +2 -2
  83. package/fe/frontend/apps/ui-components/index.js +8 -0
  84. package/fe/frontend/apps/ui-components/ui-components.entry.d.ts +2 -0
  85. package/fe/frontend/src/api/baseInfo.d.ts +2 -2
  86. package/fe/frontend/src/common/fetchErrorShow.js +2 -1
  87. package/fe/frontend/src/common/generateMenuData.js +2 -1
  88. package/fe/frontend/src/common/importComponent.js +5 -2
  89. package/fe/frontend/src/common/language.d.ts +2 -1
  90. package/fe/frontend/src/common/language.js +7 -5
  91. package/fe/frontend/src/common/logFn/index.js +6 -4
  92. package/fe/frontend/src/common/request.js +6 -4
  93. package/fe/frontend/src/components/BasePage/HeaderView.d.ts +2 -1
  94. package/fe/frontend/src/components/BasePage/HeaderView.js +9 -4
  95. package/fe/frontend/src/defaultPages/Iframe/index.js +1 -7
  96. package/fe/frontend/src/defaultPages/NotFoundPage/index.d.ts +3 -0
  97. package/fe/frontend/src/defaultPages/NotFoundPage/index.js +7 -0
  98. package/fe/frontend/src/defaultPages/SchemaPage/components/CallCom/DetailPanel.js +3 -2
  99. package/fe/frontend/src/defaultPages/SchemaPage/components/CallCom/PopFrom.js +8 -2
  100. package/fe/frontend/src/defaultPages/SchemaPage/components/SchemaTable/index.js +4 -3
  101. package/fe/frontend/src/defaultPages/SchemaPage/index.css +0 -55
  102. package/fe/frontend/src/defaultPages/SchemaPage/index.js +3 -1
  103. package/fe/frontend/src/defaultPages/SchemaPage/utils/validator.d.ts +5 -1
  104. package/fe/frontend/src/defaultPages/SchemaPage/utils/validator.js +142 -7
  105. package/fe/frontend/src/defaultPages/SidebarSlotPage/index.js +2 -1
  106. package/fe/frontend/src/defaultPages/SidebarSlotPageTmp.js +1 -1
  107. package/fe/frontend/src/defaultPages/SlotPage/index.js +2 -1
  108. package/fe/frontend/src/hooks/useCurrentMenuData.js +1 -1
  109. package/fe/frontend/src/index.d.ts +4 -0
  110. package/fe/frontend/src/index.js +4 -0
  111. package/fe/frontend/src/language/en-US.d.ts +76 -0
  112. package/fe/frontend/src/language/en-US.js +75 -0
  113. package/fe/frontend/src/language/index.d.ts +66 -0
  114. package/fe/frontend/src/language/index.js +69 -0
  115. package/fe/frontend/src/language/zh-CN.d.ts +76 -0
  116. package/fe/frontend/src/language/zh-CN.js +75 -0
  117. package/fe/frontend/src/typing/window.d.ts +2 -0
  118. package/fe/model/types/data/button.d.ts +2 -2
  119. package/fe/model/types/data/button.js +1 -1
  120. package/fe/model/types/model.d.ts +19 -12
  121. package/fe/packages/ui/react/components/Card/Card.d.ts +10 -0
  122. package/fe/packages/ui/react/components/Card/Card.js +8 -0
  123. package/fe/packages/ui/react/components/Card/index.d.ts +2 -0
  124. package/fe/packages/ui/react/components/Card/index.js +1 -0
  125. package/fe/packages/ui/react/components/DataTable/index.js +7 -3
  126. package/fe/packages/ui/react/components/ImagePreview/ImagePreview.js +3 -3
  127. package/fe/packages/ui/react/components/Layout/Layout.d.ts +11 -0
  128. package/fe/packages/ui/react/components/Layout/Layout.js +8 -0
  129. package/fe/packages/ui/react/components/Layout/index.d.ts +2 -0
  130. package/fe/packages/ui/react/components/Layout/index.js +1 -0
  131. package/fe/packages/ui/react/components/Loading/Loading.d.ts +9 -0
  132. package/fe/packages/ui/react/components/Loading/Loading.js +13 -0
  133. package/fe/packages/ui/react/components/Loading/index.d.ts +2 -0
  134. package/fe/packages/ui/react/components/Loading/index.js +1 -0
  135. package/fe/packages/ui/react/components/Menu/Menu.js +3 -2
  136. package/fe/packages/ui/react/components/Notification/Notification.d.ts +14 -0
  137. package/fe/packages/ui/react/components/Notification/Notification.js +29 -0
  138. package/fe/packages/ui/react/components/Notification/index.d.ts +2 -0
  139. package/fe/packages/ui/react/components/Notification/index.js +1 -0
  140. package/fe/packages/ui/react/components/Radio/Radio.d.ts +9 -0
  141. package/fe/packages/ui/react/components/Radio/Radio.js +20 -0
  142. package/fe/packages/ui/react/components/Radio/RadioGroup.d.ts +19 -0
  143. package/fe/packages/ui/react/components/Radio/RadioGroup.js +21 -0
  144. package/fe/packages/ui/react/components/Radio/index.d.ts +3 -0
  145. package/fe/packages/ui/react/components/Radio/index.js +2 -0
  146. package/fe/packages/ui/react/components/Search/Search.d.ts +1 -1
  147. package/fe/packages/ui/react/components/Search/Search.js +1 -5
  148. package/fe/packages/ui/react/components/Tabs/Tabs.d.ts +16 -0
  149. package/fe/packages/ui/react/components/Tabs/Tabs.js +19 -0
  150. package/fe/packages/ui/react/components/Tabs/index.d.ts +2 -0
  151. package/fe/packages/ui/react/components/Tabs/index.js +1 -0
  152. package/fe/packages/ui/react/components/hooks/useInputController.js +0 -1
  153. package/fe/packages/ui/react/components/index.d.ts +6 -0
  154. package/fe/packages/ui/react/components/index.js +6 -0
  155. package/fe/packages/ui/react/components/table/table.d.ts +3 -0
  156. package/fe/packages/ui/react/components/table/table.js +6 -6
  157. package/fe/packages/ui/react/components/testPage/index.js +54 -11
  158. package/fe/packages/ui/react/index.css +4 -0
  159. package/model/index.d.ts +1 -1
  160. package/model/types/data/button.d.ts +2 -2
  161. package/model/types/index.d.ts +1 -1
  162. package/model/types/model.d.ts +19 -12
  163. package/package.json +15 -16
  164. package/types/app/typings.d.ts +1 -1
  165. package/types/config/config.default.d.ts +3 -2
  166. package/types/index.d.ts +1 -1
  167. package/types/packages/core/index.d.ts +3 -3
  168. package/types/packages/core/loader/extend.d.ts +1 -1
  169. package/types/packages/core/paths.d.ts +4 -7
  170. package/types/packages/core/types.d.ts +31 -6
  171. package/cjs/app/data/signKey.js +0 -1
  172. package/esm/app/data/signKey.js +0 -8
  173. package/fe/frontend/apps/testPage/index.js +0 -6
  174. package/fe/frontend/apps/testPage/testPage.entry.d.ts +0 -2
  175. package/types/app/data/signKey.d.ts +0 -1
  176. /package/fe/frontend/apps/{testPage → ui-components}/index.d.ts +0 -0
  177. /package/fe/frontend/apps/{testPage/testPage.entry.js → ui-components/ui-components.entry.js} +0 -0
@@ -2,12 +2,94 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
2
2
  import { useEffect, useMemo, useRef, useState } from 'react';
3
3
  import { Outlet, useNavigate } from 'react-router-dom';
4
4
  import { generateMenuItemData } from '../../src/common/generateMenuData';
5
+ import { getText } from '../../src/common/language';
5
6
  import { findMenuItem, leftSidebarBasePath } from '../../src/common/menu';
6
7
  import HeaderView from '../../src/components/BasePage/HeaderView';
7
8
  import useRouterParams from '../../src/hooks/useRouterParams';
8
9
  import { useModeStore } from '../../src/stores/mode';
9
10
  import { Menu } from '../../../packages/ui/react/components';
10
11
  import useInit from '../../../packages/ui/react/hooks/useInit';
12
+ const normalizePathname = (pathname) => {
13
+ if (!pathname)
14
+ return '/';
15
+ const normalized = pathname.startsWith('/') ? pathname : `/${pathname}`;
16
+ return normalized.length > 1 ? normalized.replace(/\/+$/, '') : normalized;
17
+ };
18
+ const stripCurrentBasePath = (pathname) => {
19
+ const normalizedPathname = normalizePathname(pathname);
20
+ const basePath = normalizePathname(window._basePath ?? '');
21
+ if (basePath === '/')
22
+ return normalizedPathname;
23
+ if (normalizedPathname === basePath)
24
+ return '/';
25
+ if (normalizedPathname.startsWith(`${basePath}/`)) {
26
+ return normalizePathname(normalizedPathname.slice(basePath.length));
27
+ }
28
+ return normalizedPathname;
29
+ };
30
+ const getSearchParams = (search) => new URLSearchParams(search?.replace(/^\?/, ''));
31
+ const includesSearchParams = (expectedSearch, actualSearch) => {
32
+ const expectedParams = getSearchParams(expectedSearch);
33
+ const actualParams = getSearchParams(actualSearch);
34
+ for (const [key, value] of expectedParams.entries()) {
35
+ if (actualParams.get(key) !== value)
36
+ return false;
37
+ }
38
+ return true;
39
+ };
40
+ const parseDashboardPath = (path) => {
41
+ const targetPath = path.trim();
42
+ if (!targetPath)
43
+ return;
44
+ const url = new URL(targetPath, window.location.origin);
45
+ if (url.origin !== window.location.origin)
46
+ return;
47
+ return {
48
+ pathname: stripCurrentBasePath(url.pathname),
49
+ search: url.search,
50
+ hash: url.hash,
51
+ };
52
+ };
53
+ const collectRenderableMenuPaths = (menu, pathnamePrefix = '', selectedKey) => {
54
+ const paths = [];
55
+ menu.forEach((item) => {
56
+ if (item.menuType === 'group') {
57
+ paths.push(...collectRenderableMenuPaths(item.subMenu ?? [], pathnamePrefix, selectedKey));
58
+ return;
59
+ }
60
+ if (item.moduleType === 'sidebar') {
61
+ paths.push(...collectRenderableMenuPaths(item.sidebarConfig?.menu ?? [], `${pathnamePrefix}/${item.key}`, selectedKey ?? item.key));
62
+ return;
63
+ }
64
+ const menuItem = findMenuItem(menu, item.key);
65
+ if (menuItem?.path?.pathname) {
66
+ paths.push({
67
+ pathname: normalizePathname(`${pathnamePrefix}${menuItem.path.pathname}`),
68
+ search: menuItem.path.search,
69
+ selectedKey: selectedKey ?? item.key,
70
+ });
71
+ }
72
+ });
73
+ return paths;
74
+ };
75
+ const getRenderableHomePage = (projectInfo) => {
76
+ const homePage = parseDashboardPath(projectInfo.homePage);
77
+ if (!homePage)
78
+ return;
79
+ const pathnamePrefix = projectInfo.menuLayout === 'top' ? '' : `/${leftSidebarBasePath}`;
80
+ const menuPaths = collectRenderableMenuPaths(projectInfo.menu, pathnamePrefix);
81
+ const targetMenuPath = menuPaths.find((item) => {
82
+ return item.pathname === homePage.pathname && includesSearchParams(item.search, homePage.search);
83
+ });
84
+ if (!targetMenuPath)
85
+ return;
86
+ return {
87
+ pathname: homePage.pathname,
88
+ search: homePage.search,
89
+ hash: homePage.hash,
90
+ selectedKey: projectInfo.menuLayout === 'top' ? targetMenuPath.selectedKey : undefined,
91
+ };
92
+ };
11
93
  const Dashboard = () => {
12
94
  const { initModeData, initData, projectInfo } = useModeStore();
13
95
  useInit(() => {
@@ -33,6 +115,17 @@ const Dashboard = () => {
33
115
  if (initData && projectInfo) {
34
116
  if (isInit.current)
35
117
  return;
118
+ const homePage = getRenderableHomePage(projectInfo);
119
+ // 配置中的 homePage 需要能命中当前菜单可渲染路径
120
+ // 命中则直接重定向至 homePage,否则走下面的默认重定向逻辑
121
+ if (homePage) {
122
+ homePage.selectedKey && uSK(homePage.selectedKey);
123
+ isInit.current = true;
124
+ nav(homePage, {
125
+ replace: true,
126
+ });
127
+ return;
128
+ }
36
129
  if (projectInfo.menuLayout !== 'top') {
37
130
  console.log('left sidebar');
38
131
  // 如果有参数 说明跳转的不是 根路径 并且路径带有专属前缀
@@ -69,7 +162,13 @@ const Dashboard = () => {
69
162
  isInit.current = true;
70
163
  }
71
164
  }, [initData, projectInfo, params, nav]);
72
- return (_jsxs("div", { className: "dash-main h-screen flex flex-col overflow-hidden bg-theme-bg text-foreground", children: [_jsx(HeaderView, { title: projectInfo?.desc, menu: menu }), _jsx("div", { className: "dash-container min-h-0 flex-1 overflow-hidden", children: _jsx(Outlet, {}) })] }));
165
+ const getTitle = () => {
166
+ const title = projectInfo?.desc ?? projectInfo?.name;
167
+ if (!isInit.current && title)
168
+ document.title = projectInfo?.name ?? title;
169
+ return title ? getText(title) : undefined;
170
+ };
171
+ return (_jsxs("div", { className: "dash-main h-screen flex flex-col overflow-hidden bg-theme-bg text-foreground", children: [_jsx(HeaderView, { icon: projectInfo?.icon, title: getTitle(), menu: menu }), _jsx("div", { className: "dash-container min-h-0 flex-1 overflow-hidden", children: _jsx(Outlet, {}) })] }));
73
172
  };
74
173
  Dashboard.displayName = 'Dashboard';
75
174
  export default Dashboard;
@@ -14,8 +14,8 @@ const baseRoutes = [
14
14
  component: renderImportComponent(import('../../src/defaultPages/SlotPage')),
15
15
  },
16
16
  {
17
- path: `/testPage`,
18
- component: renderImportComponent(import('../testPage')),
17
+ path: `/ui-components`,
18
+ component: renderImportComponent(import('../ui-components')),
19
19
  },
20
20
  // sidebarRoutes 追加在这
21
21
  // {
@@ -0,0 +1,8 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { getText } from "../../src/common/language";
3
+ import { frontendLangKeys } from "../../src/language";
4
+ import { Button } from "../../../packages/ui/react/components";
5
+ import UiComponentsPreview from "../../../packages/ui/react/components/testPage";
6
+ export default () => {
7
+ return (_jsxs("div", { children: [_jsx("h1", { children: getText(frontendLangKeys.uiComponentsTitle) }), _jsx(Button, { children: getText(frontendLangKeys.uiComponentsButton) }), _jsx(UiComponentsPreview, {})] }));
8
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ui-components.entry.d.ts.map
@@ -1,5 +1,5 @@
1
- import type { ModeMenuType } from '../../../model/types/model';
2
- type ProjectMenuType = ModeMenuType;
1
+ import type { MBMenuType } from '../../../model/types/model';
2
+ type ProjectMenuType = MBMenuType;
3
3
  export type ModelInfo = {
4
4
  model: {
5
5
  key: string;
@@ -1,8 +1,9 @@
1
+ import { getText } from '../common/language';
1
2
  import { message } from '../../../packages/ui/react/components';
2
3
  export const handlingRequestErrors = async (data) => {
3
4
  const res = await data;
4
5
  if (res.data.code !== 0) {
5
- message.error(res.data.message);
6
+ message.error(getText(res.data.message));
6
7
  }
7
8
  return res;
8
9
  };
@@ -1,9 +1,10 @@
1
+ import { getText } from './language';
1
2
  export const generateMenuItemData = (data) => {
2
3
  return data.map((m) => {
3
4
  const children = (m.menuType === 'group' && m.subMenu.length ? generateMenuItemData(m.subMenu) : undefined);
4
5
  return {
5
6
  key: m.key,
6
- label: m.name,
7
+ label: getText(m.name),
7
8
  icon: m.icon,
8
9
  children: children,
9
10
  minWidth: 100,
@@ -1,8 +1,11 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Skeleton } from '../../../packages/ui/react/components';
2
3
  import { lazy, Suspense } from 'react';
4
+ const PageLoading = () => {
5
+ return (_jsx("div", { className: "h-full min-h-[240px] w-full overflow-hidden bg-theme-bg", children: _jsx(Skeleton, { mode: "pageloading", rows: 5 }) }));
6
+ };
3
7
  export const renderImportComponent = (c, fallback) => {
4
8
  const Component = lazy(() => c);
5
- // TODO 加上页面级 loading
6
- const showFallback = typeof fallback !== 'undefined' ? fallback : 'loading';
9
+ const showFallback = typeof fallback !== 'undefined' ? fallback : _jsx(PageLoading, {});
7
10
  return (_jsx(Suspense, { fallback: showFallback, children: _jsx(Component, {}) }));
8
11
  };
@@ -1,2 +1,3 @@
1
- export declare const getText: (key: string) => string;
1
+ import type { I18nInterpolationValues, I18nTranslateOptions } from '../../../packages/ui/react/i18n';
2
+ export declare const getText: (key: string, fillingData?: I18nInterpolationValues, options?: I18nTranslateOptions) => string;
2
3
  //# sourceMappingURL=language.d.ts.map
@@ -1,9 +1,11 @@
1
- import { i18n } from '../../../packages/ui/react/i18n';
2
- const useI18nKey = '$i18n_';
3
- export const getText = (key) => {
1
+ import { frontendI18nResources, i18nKeyPrefix } from '../language';
2
+ import { i18n, i18nStore } from '../../../packages/ui/react/i18n';
3
+ i18nStore.getState().addResources('zh-CN', frontendI18nResources['zh-CN'] ?? {});
4
+ i18nStore.getState().addResources('en-US', frontendI18nResources['en-US'] ?? {});
5
+ export const getText = (key, fillingData, options) => {
4
6
  // 如果有占位符号
5
- if (key.includes(useI18nKey)) {
6
- return i18n(key);
7
+ if (key.includes(i18nKeyPrefix)) {
8
+ return i18n(key.replace(i18nKeyPrefix, ''), fillingData, options);
7
9
  }
8
10
  return key;
9
11
  };
@@ -1,9 +1,11 @@
1
+ import { getText } from '../../common/language';
2
+ import { frontendLangKeys } from '../../language';
1
3
  const logJoin = (...logs) => logs.join(`
2
4
  ---------
3
5
  `);
4
6
  export const logPageNotFound = () => {
5
- console.error(logJoin('url有问题 或者 自定义页面未在路由器注册', 'The URL is incorrect, or the custom page is not registered with the router.'));
7
+ console.error(logJoin(getText(frontendLangKeys.logPageNotFound), getText(frontendLangKeys.logPageNotFoundEn)));
6
8
  };
7
- export const logIllegalComponentCallback = (comName) => console.error(logJoin(`非法的组件回调 - ${comName}`, `Illegal component callback - ${comName}`));
8
- export const logSubscriptionError = () => console.error(logJoin('不曾订阅过,请检查代码,关注函数与取消函数必须为同一个', "You haven't subscribed. Please check your code; the follow function and unsubscribe function must be the same."));
9
- export const logApiTamper = () => console.error(logJoin('api属性不允许篡改', 'API attributes cannot be tampered with'));
9
+ export const logIllegalComponentCallback = (comName) => console.error(logJoin(getText(frontendLangKeys.logIllegalComponentCallback, { comName }), getText(frontendLangKeys.logIllegalComponentCallbackEn, { comName })));
10
+ export const logSubscriptionError = () => console.error(logJoin(getText(frontendLangKeys.logSubscriptionError), getText(frontendLangKeys.logSubscriptionErrorEn)));
11
+ export const logApiTamper = () => console.error(logJoin(getText(frontendLangKeys.logApiTamper), getText(frontendLangKeys.logApiTamperEn)));
@@ -1,7 +1,9 @@
1
+ import { frontendLangKeys } from '../language';
1
2
  import { apiFreezerStore, FreezeState } from '../stores/apiFreezer';
2
3
  import { FetchAxios } from '../../../packages/common/http';
3
4
  import md5 from 'md5';
4
5
  import { API_AUTH_HEADER_KEY, AUTH_HEADER_KEY, clearAuthToken, getApiAuth, getAuthToken } from './auth';
6
+ import { getText } from './language';
5
7
  const BASE_URL = '/api';
6
8
  const NumberConcurrentCalls = 4;
7
9
  const isRequestWhitelisted = (api, params) => {
@@ -117,7 +119,7 @@ api.interceptors.request.use(async (config) => {
117
119
  config.headers = {
118
120
  ...config.headers,
119
121
  s_t: time + '',
120
- s_sign: md5(`sakjdfnkjwjfnfkjkjldljksndf_${time}`),
122
+ s_sign: md5(`${window['_signKey']}_${time}`),
121
123
  [API_AUTH_HEADER_KEY]: aauto,
122
124
  };
123
125
  if (token) {
@@ -151,7 +153,7 @@ api.interceptors.response.use((res) => res, async (err) => {
151
153
  // ---- Helpers ----
152
154
  function extractErrorMessage(err) {
153
155
  if (!(err instanceof Error))
154
- return 'Unknown error';
156
+ return getText(frontendLangKeys.unknownError);
155
157
  const axiosErr = err;
156
158
  if (axiosErr.response?.data && typeof axiosErr.response.data === 'object' && axiosErr.response.data !== null) {
157
159
  const data = axiosErr.response.data;
@@ -166,8 +168,8 @@ function extractErrorMessage(err) {
166
168
  if (axiosErr.message)
167
169
  return axiosErr.message;
168
170
  if (axiosErr.code === 'ECONNABORTED')
169
- return 'Request timed out';
170
- return 'Network error';
171
+ return getText(frontendLangKeys.requestTimedOut);
172
+ return getText(frontendLangKeys.networkError);
171
173
  }
172
174
  /**
173
175
  * GET/DELETE 不发送 body;统一把 data 转到 params。
@@ -1,5 +1,6 @@
1
- import { PropsWithChildren, ReactNode } from "react";
1
+ import { PropsWithChildren, ReactNode } from 'react';
2
2
  export interface HeaderViewProps extends PropsWithChildren {
3
+ icon?: ReactNode;
3
4
  menu?: ReactNode;
4
5
  title?: ReactNode;
5
6
  userArea?: ReactNode;
@@ -1,14 +1,19 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { cn } from "../../../../packages/ui/react/index";
3
- const defaultTitle = _jsx("span", { children: "Template Core" });
2
+ import { getText } from '../../common/language';
3
+ import { frontendLangKeys } from '../../language';
4
+ import { cn } from '../../../../packages/ui/react/index';
5
+ import { Boxes } from 'lucide-react';
4
6
  const defaultProps = {};
5
7
  const headerThemeStyle = {
6
8
  "--header-fg": "hsl(var(--theme-text))",
7
9
  "--header-bg": "hsl(var(--theme-bg))",
8
10
  "--header-shadow": "hsl(var(--foreground) / 0.08)",
9
11
  };
12
+ const imageLogoPattern = /^(https?:\/\/|data:image\/|\/|\.\/|\.\.\/|.*\.(svg|png|jpe?g|webp|gif)$)/i;
10
13
  const HeaderView = (props) => {
11
- const { title, menu, userArea, children } = props ?? defaultProps;
12
- return (_jsxs("div", { className: "header-view", style: headerThemeStyle, children: [_jsxs("header", { className: cn("header flex h-14 shrink-0 items-center border-b border-border/70 bg-background/95 text-(--header-fg)", "shadow-[0_1px_0_var(--header-shadow)]"), children: [_jsx("div", { className: "brand flex w-56 items-center px-5 text-sm font-semibold tracking-normal text-foreground", children: title ?? defaultTitle }), _jsx("div", { className: "top-menu flex min-w-0 flex-1 items-center px-3 text-(--header-fg)", children: menu }), _jsx("div", { className: "user-area flex min-w-0 items-center justify-end px-5 text-(--header-fg)", children: userArea })] }), children] }));
14
+ const { icon, title, menu, userArea, children } = props ?? defaultProps;
15
+ const defaultTitle = getText(frontendLangKeys.appTitle);
16
+ const brandLogo = icon ? (typeof icon === "string" ? (imageLogoPattern.test(icon) ? (_jsx("img", { className: "h-full max-w-[112px] object-contain", src: icon, alt: "" })) : (_jsx("span", { className: "max-w-[112px] truncate text-[13px] font-semibold leading-none", children: icon }))) : (icon)) : (_jsx(Boxes, { className: "h-4 w-4" }));
17
+ return (_jsxs("div", { className: "header-view", style: headerThemeStyle, children: [_jsxs("header", { className: cn("header flex h-14 shrink-0 items-center border-b border-border/70 bg-background/95 text-(--header-fg)", "shadow-[0_1px_0_var(--header-shadow)]"), children: [_jsxs("div", { className: "brand flex w-64 min-w-0 items-center gap-3 px-5 text-foreground", children: [_jsx("span", { className: "brand-logo flex h-8 min-w-12 max-w-32 shrink-0 items-center justify-center overflow-hidden rounded-md bg-foreground/7 px-2.5 text-foreground shadow-[inset_0_0_0_1px_hsl(var(--border)/0.9)]", children: brandLogo }), _jsx("span", { className: "brand-title min-w-0 truncate text-sm font-semibold leading-5 tracking-normal", children: title ?? defaultTitle })] }), _jsx("div", { className: "top-menu flex min-w-0 flex-1 items-center px-3 text-(--header-fg)", children: menu }), _jsx("div", { className: "user-area flex min-w-0 items-center justify-end px-5 text-(--header-fg)", children: userArea })] }), children] }));
13
18
  };
14
19
  export default HeaderView;
@@ -1,14 +1,8 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import useCurrentMenuData from '../../hooks/useCurrentMenuData';
3
- import { useMemo } from 'react';
4
3
  const Iframe = () => {
5
4
  const { menu } = useCurrentMenuData(true);
6
- const ifUrl = useMemo(() => {
7
- if (menu.moduleType === 'iframe') {
8
- return menu.iframeConfig.path;
9
- }
10
- return '';
11
- }, []);
5
+ const ifUrl = menu.moduleType === 'iframe' ? menu.iframeConfig.path : '';
12
6
  return (_jsx("div", { className: "iframe w-full h-full", children: _jsx("iframe", { className: " w-full h-full", src: ifUrl }) }));
13
7
  };
14
8
  export default Iframe;
@@ -0,0 +1,3 @@
1
+ declare const NotFoundPage: () => import("react/jsx-runtime").JSX.Element;
2
+ export default NotFoundPage;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { getText } from '../../common/language';
3
+ import { frontendLangKeys } from '../../language';
4
+ const NotFoundPage = () => {
5
+ return (_jsx("div", { className: "flex h-full min-h-[240px] w-full items-center justify-center bg-theme-bg px-6 text-foreground", children: _jsxs("div", { className: "flex max-w-sm flex-col items-center text-center", children: [_jsx("div", { className: "mb-4 rounded-md border border-border bg-background/70 px-3 py-1 text-xs font-medium text-muted-foreground", children: "404" }), _jsx("h1", { className: "text-lg font-semibold tracking-normal", children: getText(frontendLangKeys.notFoundTitle) }), _jsx("p", { className: "mt-2 text-sm leading-6 text-muted-foreground", children: getText(frontendLangKeys.notFoundDescription) })] }) }));
6
+ };
7
+ export default NotFoundPage;
@@ -2,6 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { handlingRequestErrors } from '../../../../common/fetchErrorShow';
3
3
  import { getText } from '../../../../common/language';
4
4
  import { request } from '../../../../common/request';
5
+ import { frontendLangKeys } from '../../../../language';
5
6
  import { schemaEventBus } from '../../../../stores/schemaEventBus';
6
7
  import { Drawer } from '../../../../../../packages/ui/react/components';
7
8
  import useExecuteOnce from '../../../../../../packages/ui/react/hooks/useExecuteOnce';
@@ -48,7 +49,7 @@ const formatValue = (value, fieldInfo) => {
48
49
  .join(', ');
49
50
  }
50
51
  if (typeof value === 'boolean')
51
- return value ? getText('是') : getText('否');
52
+ return value ? getText(frontendLangKeys.yes) : getText(frontendLangKeys.no);
52
53
  return stringifyValue(value);
53
54
  };
54
55
  const generateFields = (schema, data) => {
@@ -89,6 +90,6 @@ const DetailPanel = memo((props) => {
89
90
  return (_jsx("div", { className: "detail-panel", children: _jsx(Drawer, { title: getText(config?.title ?? ''), open: open, onClose: () => {
90
91
  setOpen(false);
91
92
  schemaEventBus.getState().emitCom({ type: merge(eventsInfo.closeCom) });
92
- }, children: fields.length > 0 ? (_jsx("div", { className: "grid grid-cols-1 gap-x-6 gap-y-4 sm:grid-cols-2", children: fields.map((field) => (_jsxs("div", { className: "min-w-0 border-b border-border pb-3", children: [_jsx("div", { className: "mb-1 text-xs text-muted-foreground", children: field.label }), _jsx("div", { className: "break-words text-sm leading-6 text-foreground", children: field.value })] }, field.key))) })) : (_jsx("div", { className: "py-8 text-center text-sm text-muted-foreground", children: getText('暂无数据') })) }) }));
93
+ }, children: fields.length > 0 ? (_jsx("div", { className: "grid grid-cols-1 gap-x-6 gap-y-4 sm:grid-cols-2", children: fields.map((field) => (_jsxs("div", { className: "min-w-0 border-b border-border pb-3", children: [_jsx("div", { className: "mb-1 text-xs text-muted-foreground", children: field.label }), _jsx("div", { className: "break-words text-sm leading-6 text-foreground", children: field.value })] }, field.key))) })) : (_jsx("div", { className: "py-8 text-center text-sm text-muted-foreground", children: getText(frontendLangKeys.noData) })) }) }));
93
94
  });
94
95
  export default DetailPanel;
@@ -2,6 +2,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { handlingRequestErrors } from '../../../../common/fetchErrorShow';
3
3
  import { getText } from '../../../../common/language';
4
4
  import { post, put, request } from '../../../../common/request';
5
+ import { frontendLangKeys } from '../../../../language';
5
6
  import { schemaEventBus } from '../../../../stores/schemaEventBus';
6
7
  import { Modal, SchemaForm } from '../../../../../../packages/ui/react/components';
7
8
  import useExecuteOnce from '../../../../../../packages/ui/react/hooks/useExecuteOnce';
@@ -26,10 +27,15 @@ const generateSchemas = (schema) => {
26
27
  required: schema.required?.includes(key),
27
28
  rules: [
28
29
  ...(schema.required?.includes(key)
29
- ? [{ required: true, message: `请输入${getText(fieldInfo.label)}` }]
30
+ ? [
31
+ {
32
+ required: true,
33
+ message: getText(frontendLangKeys.requiredInput, { label: getText(fieldInfo.label) }),
34
+ },
35
+ ]
30
36
  : []),
31
37
  {
32
- validator: createAjvValidator(fieldInfo),
38
+ validator: createAjvValidator(fieldInfo, { required: schema.required?.includes(key) }),
33
39
  },
34
40
  ],
35
41
  fieldProps: {
@@ -2,6 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { handlingRequestErrors } from '../../../../common/fetchErrorShow';
3
3
  import { getText } from '../../../../common/language';
4
4
  import { del, get } from '../../../../common/request';
5
+ import { frontendLangKeys } from '../../../../language';
5
6
  import { schemaEventBus } from '../../../../stores/schemaEventBus';
6
7
  import { useSchemaStore } from '../../../../stores/schemaStore';
7
8
  import { Button, DataTable, modal, } from '../../../../../../packages/ui/react/components';
@@ -14,7 +15,7 @@ import { memo, useCallback, useImperativeHandle, useMemo, useState } from 'react
14
15
  import { useShallow } from 'zustand/react/shallow';
15
16
  import { eventsInfo } from '../../data/eventInfo';
16
17
  import { merge } from '../../utils/permissions';
17
- const VALUE_KEY = 'schema::';
18
+ const VALUE_KEY = '$schema::';
18
19
  const generateColumns = (config) => {
19
20
  const keys = Object.keys(config);
20
21
  const columns = [];
@@ -58,7 +59,7 @@ const generateRowActions = (btnConfigs, rowData, api) => {
58
59
  return o;
59
60
  }, {});
60
61
  modal.confirm({
61
- content: `确认删除?`,
62
+ content: getText(frontendLangKeys.confirmDelete),
62
63
  async onOk() {
63
64
  await handlingRequestErrors(del(api, apiParams));
64
65
  schemaEventBus.getState().emitCom({ type: merge(eventsInfo.initTable) });
@@ -124,7 +125,7 @@ const SchemaTable = memo(({ ref }) => {
124
125
  if (rowButtons) {
125
126
  actionColumn.push({
126
127
  key: 'action',
127
- title: getText('操作'),
128
+ title: getText(frontendLangKeys.operation),
128
129
  actions: (_value, _record, index) => [
129
130
  ...generateRowActions(rowButtons, _record, params.api),
130
131
  // { key: `text-${index}`, label: 'text' },
@@ -110,58 +110,3 @@
110
110
  height: 34px;
111
111
  border-radius: 7px;
112
112
  }
113
-
114
- .schema-table .tc-ui-data-table {
115
- flex: 1;
116
- overflow: hidden;
117
- border: 1px solid var(--schema-soft-border);
118
- border-radius: var(--schema-radius);
119
- background-color: hsl(var(--background) / 0.58);
120
- box-shadow: none;
121
- }
122
-
123
- .schema-table .tc-ui-table {
124
- border-radius: var(--schema-radius) var(--schema-radius) 0 0;
125
- }
126
-
127
- .schema-table .tc-ui-table-header {
128
- background: hsl(var(--muted) / 0.5);
129
- }
130
-
131
- .schema-table .tc-ui-table-head {
132
- height: 40px;
133
- padding: 0 16px;
134
- font-size: 12px;
135
- font-weight: 600;
136
- color: hsl(var(--muted-foreground));
137
- }
138
-
139
- .schema-table .tc-ui-table-cell {
140
- padding: 13px 16px;
141
- }
142
-
143
- .schema-table .tc-ui-table-row {
144
- border-color: hsl(var(--border) / 0.58);
145
- }
146
-
147
- .schema-table .tc-ui-table-row:hover {
148
- background-color: hsl(var(--muted) / 0.28);
149
- }
150
-
151
- .schema-table .tc-ui-table-head[style*='right'],
152
- .schema-table .tc-ui-table-cell[style*='right'] {
153
- box-shadow: -1px 0 0 hsl(var(--border) / 0.58);
154
- }
155
-
156
- .schema-table .tc-ui-data-table > .px-6 {
157
- margin-top: 0;
158
- border-top: 1px solid hsl(var(--border) / 0.58);
159
- padding: 12px 16px;
160
- }
161
-
162
- .schema-table .tc-ui-data-table > .px-6 .tc-ui-select > div:first-child {
163
- min-height: 34px;
164
- border-radius: 7px;
165
- background: hsl(var(--muted) / 0.58);
166
- padding-block: 7px;
167
- }
@@ -1,5 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { getText } from '../../common/language';
2
3
  import { logIllegalComponentCallback } from '../../common/logFn';
4
+ import { frontendLangKeys } from '../../language';
3
5
  import useCurrentMenuData from '../../hooks/useCurrentMenuData';
4
6
  import { schemaEventBus } from '../../stores/schemaEventBus';
5
7
  import { useSchemaStore } from '../../stores/schemaStore';
@@ -67,7 +69,7 @@ const Schema = memo(() => {
67
69
  return (_jsxs("div", { className: "schema-container flex h-full min-h-0 w-full flex-col overflow-hidden bg-theme-bg px-4 py-3", children: [_jsxs("div", { className: "schema-workspace flex min-h-0 flex-1 flex-col overflow-hidden", children: [_jsx("div", { className: "schema-search-region shrink-0", children: _jsx(SchemaSearch, {}) }), _jsx("div", { className: "schema-table-region min-h-0 flex-1 overflow-auto p-3", children: _jsx(SchemaTable, { ref: TableRef }) })] }), _jsx(Suspense, { children: CallCom && _jsx(CallCom, { ...comProps }) })] }));
68
70
  }
69
71
  else
70
- return _jsx("div", { className: "flex h-full items-center justify-center text-sm text-muted-foreground", children: "loading" });
72
+ return (_jsx("div", { className: "flex h-full items-center justify-center text-sm text-muted-foreground", children: getText(frontendLangKeys.loading) }));
71
73
  }, [comProps, schemaStoreAvailable, showCompoentKey]);
72
74
  return dom;
73
75
  });
@@ -1,7 +1,11 @@
1
1
  import { Ajv } from 'ajv';
2
2
  export declare const ajvInstance: Ajv;
3
+ type AjvValidatorOptions = {
4
+ required?: boolean;
5
+ };
3
6
  /**
4
7
  * 创建验证器
5
8
  */
6
- export declare function createAjvValidator(schema: object): (rule: object, value: unknown, callback: (errors?: string[]) => void) => void;
9
+ export declare function createAjvValidator(schema: object, options?: AjvValidatorOptions): (rule: object, value: unknown, callback: (errors?: string[]) => void) => void;
10
+ export {};
7
11
  //# sourceMappingURL=validator.d.ts.map