create-tengits-app 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/PUBLISH.md +151 -0
  2. package/README.md +255 -0
  3. package/USAGE.md +154 -0
  4. package/bin/cli.js +195 -0
  5. package/eslint.config.mjs +33 -0
  6. package/global.d.ts +9 -0
  7. package/package.json +67 -0
  8. package/packages/main/.env +24 -0
  9. package/packages/main/.env.pre +3 -0
  10. package/packages/main/.env.test +4 -0
  11. package/packages/main/.eslintrc +9 -0
  12. package/packages/main/README.md +18 -0
  13. package/packages/main/dist/manifest.json +40 -0
  14. package/packages/main/index.html +80 -0
  15. package/packages/main/index.ts +12 -0
  16. package/packages/main/package.json +43 -0
  17. package/packages/main/postcss.config.js +7 -0
  18. package/packages/main/public/antd.dark.css +26419 -0
  19. package/packages/main/public/dark.css +32 -0
  20. package/packages/main/public/evaluation-template.csv +10 -0
  21. package/packages/main/rsbuild.config.ts +79 -0
  22. package/packages/main/src/App.tsx +108 -0
  23. package/packages/main/src/configSystemData.ts +27 -0
  24. package/packages/main/src/i18n.js +140 -0
  25. package/packages/main/src/index.jsx +22 -0
  26. package/packages/main/src/index.less +250 -0
  27. package/packages/main/src/menus.jsx +123 -0
  28. package/packages/main/src/pages/Home/index.tsx +102 -0
  29. package/packages/main/src/pages/Login/common.ts +26 -0
  30. package/packages/main/src/pages/Login/index.less +15 -0
  31. package/packages/main/src/pages/Login/index.tsx +238 -0
  32. package/packages/main/src/routes.tsx +75 -0
  33. package/packages/main/src/styles/index.css +38 -0
  34. package/packages/main/src/types/less.d.ts +4 -0
  35. package/packages/main/src/types/tengitsui.d.ts +7 -0
  36. package/packages/main/src/types/utils.d.ts +39 -0
  37. package/packages/main/src/utils/checkPermission.js +19 -0
  38. package/packages/main/src/utils/day.js +18 -0
  39. package/packages/main/src/utils/download.js +30 -0
  40. package/packages/main/src/utils/fileUtils.ts +45 -0
  41. package/packages/main/src/utils/guid.js +6 -0
  42. package/packages/main/src/utils/gzip.js +26 -0
  43. package/packages/main/src/utils/importFile.js +51 -0
  44. package/packages/main/src/utils/index.ts +9 -0
  45. package/packages/main/src/utils/request.js +40 -0
  46. package/packages/main/src/utils/uploadFileToCloud.js +102 -0
  47. package/packages/main/src/utils/utils.ts +331 -0
  48. package/packages/main/src/utils/uuid.js +13 -0
  49. package/packages/main/src/utils/version.js +158 -0
  50. package/packages/main/tailwind.config.js +27 -0
  51. package/packages/main/tsconfig.json +6 -0
  52. package/pnpm-workspace.yaml +16 -0
  53. package/tsconfig.json +23 -0
@@ -0,0 +1,123 @@
1
+ import React from 'react';
2
+ import { TUIIconPark } from 'tengits-ui5';
3
+ import { t } from './i18n';
4
+
5
+ export const getMenus = () => [
6
+ {
7
+ menuName: t('Home'),
8
+ key: '/Home',
9
+ icon: <TUIIconPark type="workbench-h7gmkp2e" />,
10
+ label: t('Home'),
11
+ path: 'Home',
12
+ },
13
+ {
14
+ icon: <TUIIconPark type="peoples" />,
15
+ menuName: t('SystemManagement', 'Common'),
16
+ label: t('SystemManagement', 'Common'),
17
+ key: '/systemManagement',
18
+ path: 'systemManagement',
19
+ children: [
20
+ {
21
+ menuName: t('AModel'),
22
+ key: 'modelManage',
23
+ icon: '',
24
+ label: t('Model'),
25
+ path: 'modelManage',
26
+ },
27
+ {
28
+ menuName: t('Evaluation'),
29
+ key: 'evaluation',
30
+ icon: '',
31
+ label: t('Evaluation'),
32
+ path: 'evaluation',
33
+ },
34
+ {
35
+ icon: '',
36
+ menuName: t('UserManagement'),
37
+ label: t('UserManagement'),
38
+ key: 'userManagement',
39
+ path: 'userManagement',
40
+ menuAuth: [{ id: 0, name: '用户管理' }],
41
+ },
42
+ {
43
+ icon: '',
44
+ menuName: t('BasicManagement'),
45
+ label: t('BasicManagement'),
46
+ key: 'basicManagement',
47
+ path: 'basicManagement',
48
+ children: [
49
+ {
50
+ icon: '',
51
+ menuName: t('UserGroupManagement'),
52
+ label: t('UserGroupManagement'),
53
+ key: 'userGroups',
54
+ path: 'userGroups',
55
+ menuAuth: [{ id: 0, name: '用户组管理' }],
56
+ },
57
+ {
58
+ icon: '',
59
+ menuName: t('RoleManagement'),
60
+ label: t('RoleManagement'),
61
+ key: 'roleManagement',
62
+ path: 'roleManagement',
63
+ menuAuth: [{ id: 0, name: '角色管理' }],
64
+ },
65
+ {
66
+ icon: '',
67
+ menuName: t('OperationPermissionManagement'),
68
+ label: t('OperationPermissionManagement'),
69
+ key: 'permissionsManagement',
70
+ path: 'permissionsManagement',
71
+ menuAuth: [{ id: 0, name: '操作权限管理' }],
72
+ },
73
+ {
74
+ icon: '',
75
+ menuName: t('OrganizationalStructureManagement'),
76
+ label: t('OrganizationalStructureManagement'),
77
+ key: 'organizationManagement',
78
+ path: 'organizationManagement',
79
+ menuAuth: [{ id: 0, name: '组织机构管理' }],
80
+ },
81
+ ],
82
+ },
83
+ ],
84
+ },
85
+ ];
86
+
87
+ /**
88
+ * 树形结构属性替换
89
+ * @param item
90
+ * @param resetItem 重置某一项的值,item => {}
91
+ * @returns
92
+ */
93
+ export function replaceMapTree(item, resetItem = it => ({}), level = 1) {
94
+ const haveChildren = Array.isArray(item.children) && item.children.length > 0;
95
+ const newLevel = level + 1;
96
+ return {
97
+ ...resetItem(item),
98
+ menuLevel: newLevel,
99
+ children: haveChildren ? item.children.map(itr => replaceMapTree(itr, resetItem, newLevel)) : [],
100
+ };
101
+ }
102
+
103
+ /**
104
+ * 根据列表权限过滤菜单
105
+ *
106
+ */
107
+ export function filterMenus(child = []) {
108
+ const isHaveList = item => item.menuAuth.find(it => it.name === item.menuName);
109
+
110
+ const filterChild = child.filter((item) => {
111
+ if (item.children && item.children.length)
112
+ return filterMenus(item.children).length || isHaveList(item);
113
+
114
+ else
115
+ return isHaveList(item);
116
+ }).map((item) => {
117
+ if (item.children && item.children.length)
118
+ item.children = isHaveList(item) ? item.children : filterMenus(item.children);
119
+
120
+ return item;
121
+ });
122
+ return filterChild;
123
+ }
@@ -0,0 +1,102 @@
1
+ import React from 'react';
2
+ import { Card, Row, Col, Button, Typography, Space } from 'antd';
3
+ import {TUIIconPark} from 'tengits-ui5';
4
+
5
+ const { Title, Paragraph } = Typography;
6
+
7
+ /**
8
+ * 首页组件
9
+ * 展示项目介绍和主要功能
10
+ */
11
+ const Home: React.FC = () => {
12
+ const features = [
13
+ {
14
+ icon: <TUIIconPark type="rocket-outlined" />,
15
+ title: 'Rsbuild 构建',
16
+ description: '基于 Rsbuild 的快速构建工具,提供极致的开发体验'
17
+ },
18
+ {
19
+ icon: <TUIIconPark type="star-outlined" />,
20
+ title: 'TypeScript',
21
+ description: '完整的 TypeScript 支持,提供类型安全和更好的开发体验'
22
+ },
23
+ {
24
+ icon: <TUIIconPark type="heart-outlined" />,
25
+ title: 'Antd + Tailwind',
26
+ description: '结合 Ant Design 组件库和 Tailwind CSS 样式框架'
27
+ }
28
+ ];
29
+
30
+ const handleGetStarted = () => {
31
+ console.log('开始使用模板!');
32
+ };
33
+
34
+ return (
35
+ <div className="p-6">
36
+ <div className="text-center mb-12">
37
+ <Title level={1} className="mb-4">
38
+ React + Rsbuild 项目模板
39
+ </Title>
40
+ <Paragraph className="text-lg text-gray-600 max-w-2xl mx-auto">
41
+ 这是一个现代化的 React 项目模板,集成了 Rsbuild、TypeScript、Tailwind CSS 和 Ant Design。
42
+ 为您的下一个项目提供最佳的开发体验和生产环境优化。
43
+ </Paragraph>
44
+ <Space size="large" className="mt-6">
45
+ <Button
46
+ type="primary"
47
+ size="large"
48
+ icon={<TUIIconPark type="rocket-outlined" />}
49
+ onClick={handleGetStarted}
50
+ >
51
+ 开始使用
52
+ </Button>
53
+ <Button
54
+ size="large"
55
+ icon={<TUIIconPark type="github-outlined" />}
56
+ >
57
+ 查看源码
58
+ </Button>
59
+ </Space>
60
+ </div>
61
+
62
+ <Row gutter={[24, 24]} className="mb-12">
63
+ {features.map((feature, index) => (
64
+ <Col xs={24} md={8} key={index}>
65
+ <Card
66
+ hoverable
67
+ className="h-full text-center"
68
+ bodyStyle={{ padding: '32px 24px' }}
69
+ >
70
+ <div className="mb-4">{feature.icon}</div>
71
+ <Title level={4} className="mb-3">
72
+ {feature.title}
73
+ </Title>
74
+ <Paragraph className="text-gray-600">
75
+ {feature.description}
76
+ </Paragraph>
77
+ </Card>
78
+ </Col>
79
+ ))}
80
+ </Row>
81
+
82
+ <Card title="快速开始" className="mb-6">
83
+ <div className="space-y-4">
84
+ <div>
85
+ <Title level={5}>1. 安装依赖</Title>
86
+ <pre className="bg-gray-100 p-3 rounded">pnpm install</pre>
87
+ </div>
88
+ <div>
89
+ <Title level={5}>2. 启动开发服务器</Title>
90
+ <pre className="bg-gray-100 p-3 rounded">pnpm start</pre>
91
+ </div>
92
+ <div>
93
+ <Title level={5}>3. 构建生产版本</Title>
94
+ <pre className="bg-gray-100 p-3 rounded">pnpm build</pre>
95
+ </div>
96
+ </div>
97
+ </Card>
98
+ </div>
99
+ );
100
+ };
101
+
102
+ export default Home;
@@ -0,0 +1,26 @@
1
+ export const configObj = {
2
+ loginTitleColor: [
3
+ { id: 1, field: 'light', name: '黑' },
4
+ { id: 2, field: 'dark', name: '白' },
5
+ ],
6
+ loginType: [
7
+ { id: 1, field: 'rightModal', name: '登录框在右' },
8
+ { id: 2, field: 'rightDrawer', name: '抽屉登录框' },
9
+ { id: 3, field: 'Center', name: '登录框居中' },
10
+ ],
11
+ LoginBckType: [
12
+ { id: 1, field: 'img', name: '图片' },
13
+ { id: 2, field: 'video', name: '视频' },
14
+ ],
15
+ loginBGMask: [
16
+ { id: 1, field: 'default', name: '随主题' },
17
+ { id: 2, field: 'whiteMask', name: '白蒙版' },
18
+ { id: 3, field: 'darkMask', name: '黑蒙版' },
19
+ ],
20
+
21
+ };
22
+
23
+ export function getConfigValueByField(ConfigField, val, field = 'field') {
24
+ const fItem = configObj[ConfigField].find(it => it.id === val);
25
+ return fItem ? fItem[field] : '';
26
+ }
@@ -0,0 +1,15 @@
1
+ .configIcon {
2
+ color: var(--ant-color-primary, #1989fa);
3
+ }
4
+ .TUI-JunmpLink {
5
+ display: none;
6
+ }
7
+
8
+ .TUI-LoginLayout .LoginPage {
9
+ .head {
10
+ height: 47px;
11
+ img {
12
+ height: inherit;
13
+ }
14
+ }
15
+ }
@@ -0,0 +1,238 @@
1
+ import { App } from 'antd';
2
+ import { useEffect, useState } from 'react';
3
+ import { useNavigate } from 'react-router-dom';
4
+ import { encrypt, getSearchParams, httpClient, jugeIsVideo, LOCAL_STORAGE_KEY, LoginPage, setLocalStorageJSON, TUISkeleton, useUserDispatch } from 'tengits-ui5';
5
+
6
+ import { request } from '../../utils/request';
7
+ import { getConfigValueByField } from './common';
8
+ import { t } from '../../i18n';
9
+ import './index.less';
10
+
11
+ export enum LoginWayTypeEnum {
12
+ /**
13
+ * 单点独立登录
14
+ */
15
+ Single = 1,
16
+ /**
17
+ * 聚合登录(统一门户)
18
+ */
19
+ Juhe = 2,
20
+ /**
21
+ * 聚合登录(子系统)
22
+ */
23
+ JuheCilent = 3,
24
+ }
25
+ const defaultConfig = {
26
+ loginTitleColor: 2,
27
+ loginType: 1,
28
+ sysTitleType: 'img',
29
+ systemName: 'https://static-1255466169.cos.ap-guangzhou.myqcloud.com/assets/logo/teng_title.png',
30
+ systemSubTitle: '',
31
+ LoginBckType: 2,
32
+ logo: 'https://static-1255466169.cos.ap-guangzhou.myqcloud.com/assets/logo/default_logo.png',
33
+ shinkLogo: 'https://static-1255466169.cos.ap-guangzhou.myqcloud.com/assets/logo/default_shink_logo.png',
34
+ backImage: 'https://static-1255466169.cos.ap-guangzhou.myqcloud.com/ThemeAssets/loginVideo.mp4',
35
+ footer: '',
36
+ formWidth: 430,
37
+ loginBGMask: 1,
38
+ };
39
+
40
+ interface LoginProps {
41
+ page: 'login' | 'resetPass';
42
+ }
43
+ const TTOSHost = import.meta.env.VITE_REACT_APP_HOST;
44
+ export default function Login({ page = 'login' }: LoginProps) {
45
+ const { message } = App.useApp();
46
+ const navigate = useNavigate();
47
+ const { jumpUrl } = getSearchParams();
48
+
49
+ const [pageConfig, setPageConfig] = useState({});
50
+ const [tenantPara, setTenantPara] = useState({});
51
+
52
+ const dispatch = useUserDispatch();
53
+
54
+ /** 登录saas后台管理 */
55
+ const loginCallback = () => {
56
+ // navigate('/');
57
+ // window.location.href = tenantPara.pageType === LoginWayTypeEnum.Juhe ? '/home' : '/';
58
+ window.location.href = '/';
59
+ };
60
+
61
+ /** 登录接口 */
62
+ const LoginService = async (values) => {
63
+ return await request('/ttos/user/login', {
64
+ isSpt: tenantPara.pageType === LoginWayTypeEnum.Single ? 1 : 0,
65
+ password: encrypt(values.password),
66
+ loginType: tenantPara.pageType || 1,
67
+ account: values.account,
68
+ token: values.token,
69
+ ...tenantPara,
70
+ }).then(async (r) => {
71
+ console.log('r000--', r);
72
+ if (r.status === 0) {
73
+ const { cookie } = r.data;
74
+ localStorage.setItem(LOCAL_STORAGE_KEY.TOKEN, cookie);
75
+ let userInfo = {};
76
+ // 拉用户信息
77
+ await request('/ttos/user/getUserInfo', {
78
+ Authorization: cookie,
79
+ ...tenantPara,
80
+ // currentTenantId: tenantPara.tenantId,
81
+ tenantId: undefined,
82
+ }).then(async (r) => {
83
+ if (r.status === 0) {
84
+ userInfo = {
85
+ ...r.data,
86
+ simpleName: (r.data.username || '').substring(0, 4),
87
+ account: r.data.phoneNum,
88
+ name: r.data.username,
89
+ phone: r.data.phoneNum,
90
+ permissions: [],
91
+ };
92
+ }
93
+ });
94
+
95
+ await request('/ttos/roleMenu/getUserRoleList', {
96
+ Authorization: cookie,
97
+ platformType: tenantPara.platformType,
98
+ applicationId: tenantPara.applicationId,
99
+ // currentTenantId: tenantPara.tenantId,
100
+ }).then((r) => {
101
+ if (r && r.status === 0) {
102
+ userInfo = {
103
+ ...userInfo,
104
+ ...r.data,
105
+ };
106
+ console.log('userInfo--', userInfo);
107
+ dispatch({ type: 'replaceData', payload: userInfo });
108
+ setLocalStorageJSON(LOCAL_STORAGE_KEY.USERSTATUS, userInfo);
109
+ loginCallback();
110
+ return userInfo;
111
+ }
112
+ }).catch((e) => {
113
+ console.log('e--', e);
114
+ });
115
+ }
116
+ else {
117
+ message.error(r.message || '处理失败,请稍后重试');
118
+ }
119
+ }).catch((e) => { });
120
+ };
121
+
122
+ const {
123
+ systemName,
124
+ systemSubTitle,
125
+ copyright,
126
+ backImage,
127
+ loginBgMask,
128
+ loginFormWidth,
129
+ loginTitleColor,
130
+ loginType,
131
+ logo,
132
+ } = pageConfig;
133
+
134
+ /** 登录页配置项转换 */
135
+ const resultPageConfig = () => ({
136
+ sysTitle: t('AIWorkbench'),
137
+ ...pageConfig,
138
+ sysSubTitle: systemSubTitle,
139
+ LoginLogo: logo,
140
+
141
+ loginTitleColor: getConfigValueByField('loginTitleColor', loginTitleColor ? Number(loginTitleColor) : 2),
142
+ loginType: getConfigValueByField('loginType', loginType ? Number(loginType) : 1),
143
+ loginBGMask: getConfigValueByField('loginBGMask', loginBgMask ? Number(loginBgMask) : 1),
144
+
145
+ LoginBckType: jugeIsVideo(backImage) ? 'video' : 'img',
146
+ LoginBck: backImage,
147
+
148
+ formWidth: loginFormWidth || undefined,
149
+ footer: copyright,
150
+ });
151
+
152
+ /** 拉登录页配置 */
153
+ const getLoginPageService = async () => {
154
+ // 本地调式需要调 配置的环境变量地址
155
+ const currentUrl = jumpUrl || (window.location.origin.includes('localhost') ? TTOSHost : window.location.origin);
156
+ await httpClient.post('/ttos/fullloginpage/getFullLoginPage', {
157
+ keyWord: currentUrl || TTOSHost,
158
+ }).then(async (r) => {
159
+ console.log('r--登录页--客户端', r);
160
+ if (r.status === 0) {
161
+ const { platformType, tenantId, applicationId } = r.data;
162
+ await httpClient.post('/saas/project/getLoginPageDetail', {
163
+ tenantId,
164
+ url: currentUrl || TTOSHost,
165
+ }).then((res) => {
166
+ if (res.status === 0) {
167
+ // 1 单点登录 2 聚合登录
168
+ const pageType = res.data.type || (res.data.customLoginPageDto.id ? 2 : 1);
169
+ const pageDataT = pageType === LoginWayTypeEnum.Single ? res.data.singleLoginPageDto : res.data.customLoginPageDto;
170
+ const systemName = pageType === LoginWayTypeEnum.Single ? pageDataT.applicationPushName : pageDataT.systemName;
171
+ const pageData = {
172
+ ...pageDataT,
173
+ systemName,
174
+ title: pageDataT.title || systemName,
175
+ logo: pageDataT.logo || defaultConfig.logo,
176
+ shinkLogo: pageDataT.shinkLogo || defaultConfig.shinkLogo,
177
+ };
178
+ setLocalStorageJSON(LOCAL_STORAGE_KEY.TENANTSESSION, {
179
+ tenantId,
180
+ applicationId,
181
+ platformType,
182
+ pageType,
183
+ applicationIdList: pageType === LoginWayTypeEnum.Single ? undefined : pageData.dtoList ? pageData.dtoList.map(itr => ({ id: itr.applicationId, name: itr.applicationPushName })) : undefined,
184
+ });
185
+ setTenantPara({ tenantId, applicationId, platformType, pageType });
186
+
187
+ console.log('res--登录页--配置', res, systemName, pageData);
188
+ setPageConfig(pageData);
189
+ setLocalStorageJSON(LOCAL_STORAGE_KEY.LOGINCONFIG, pageData);
190
+ }
191
+ }).catch((err) => {
192
+ console.log('err--', err);
193
+ throw err;
194
+ });
195
+ }
196
+ }).catch((e) => {
197
+ console.log('e--', e);
198
+ setPageConfig(defaultConfig);
199
+ });
200
+ };
201
+
202
+ const SliderValidateService = (params) => {
203
+ return request('/ttos/thirdpartsdk/validateCaptcha', {
204
+ ...params,
205
+ }).catch((e) => {
206
+ message.error(e.message || '验证码出错');
207
+ });
208
+ };
209
+
210
+ useEffect(() => {
211
+ if (!jumpUrl) {
212
+ const savedLanguage = localStorage.getItem('language');
213
+ localStorage.removeItem('Local_BreadcrumbArr');
214
+ localStorage.removeItem(LOCAL_STORAGE_KEY.USERSTATUS);
215
+ localStorage.clear();
216
+ if (savedLanguage) {
217
+ localStorage.setItem(LOCAL_STORAGE_KEY.LANGUAGE, savedLanguage);
218
+ }
219
+ }
220
+
221
+ getLoginPageService();
222
+ }, []);
223
+
224
+ if (!pageConfig.systemName)
225
+ return <TUISkeleton />;
226
+
227
+ return (
228
+ <LoginPage
229
+ page={page}
230
+ navigate={navigate}
231
+ {...resultPageConfig()}
232
+ loginCallback={loginCallback}
233
+ LoginService={LoginService}
234
+ SliderValidateService={SliderValidateService}
235
+ // NotShowSliderValidate
236
+ />
237
+ );
238
+ }
@@ -0,0 +1,75 @@
1
+ import i18n, { t } from './i18n';
2
+ import Home from './pages/Home';
3
+ import Login from './pages/Login';
4
+ // import { LazyComponents } from './utils/lazyLoad';
5
+
6
+
7
+ export const otherRoutes = [
8
+ { path: '/login', element: <Login page="login" /> },
9
+ { path: '/resetPass', element: <Login page="resetPass" /> },
10
+ ];
11
+
12
+ /** 自定义路由 */
13
+ export const customRoutes = () => {
14
+ return [
15
+ {
16
+ path: 'home',
17
+ children: [
18
+ { path: '', label: i18n.t('Build'), element: <Home /> }
19
+ ],
20
+ },
21
+
22
+ // {
23
+ // path: 'systemManagement',
24
+ // children: [
25
+ // {
26
+ // path: 'userManagement',
27
+ // label: i18n.t('UserManagement'),
28
+ // element: <LazyComponents.UserManage {...userAppProps} />,
29
+ // },
30
+ // {
31
+ // path: 'basicManagement',
32
+ // label: i18n.t('BasicManagement'),
33
+ // children: [
34
+ // {
35
+ // path: 'userGroups',
36
+ // label: i18n.t('UserGroupManagement'),
37
+ // element: <LazyComponents.UserGroups {...userAppProps} />,
38
+ // },
39
+ // {
40
+ // path: 'roleManagement',
41
+ // label: i18n.t('RoleManagement'),
42
+ // element: <LazyComponents.RoleManagement {...userAppProps} />,
43
+ // },
44
+ // {
45
+ // path: 'permissionsManagement',
46
+ // label: i18n.t('OperationPermissionManagement'),
47
+ // element: <LazyComponents.PermissionsManagement {...userAppProps} />,
48
+ // },
49
+ // {
50
+ // path: 'organizationManagement',
51
+ // label: i18n.t('OrganizationalStructureManagement'),
52
+ // element: <LazyComponents.OrganizationManage {...userAppProps} />,
53
+ // },
54
+ // // {
55
+ // // path: 'dataPermissionsManagement',
56
+ // // label: i18n.t('DataPermissionManagement'),
57
+
58
+ // // children: [
59
+ // // {
60
+ // // path: '',
61
+ // // element: <LazyComponents.DataPermissionsManage {...userAppProps} />,
62
+ // // },
63
+ // // {
64
+ // // path: 'permission',
65
+ // // label: t('DataConfiguration', 'Common'),
66
+ // // element: <LazyComponents.DataAppPermissionsManage {...userAppProps} />,
67
+ // // },
68
+ // // ],
69
+ // // },
70
+ // ],
71
+ // },
72
+ // ],
73
+ // },
74
+ ];
75
+ };
@@ -0,0 +1,38 @@
1
+ /* Tailwind CSS 基础样式 */
2
+ @tailwind base;
3
+ @tailwind components;
4
+ @tailwind utilities;
5
+
6
+ /* Ant Design 样式重置和自定义 */
7
+ @import 'antd/dist/reset.css';
8
+
9
+ /* 全局样式 */
10
+ html, body, #root {
11
+ height: 100%;
12
+ margin: 0;
13
+ padding: 0;
14
+ }
15
+
16
+ * {
17
+ box-sizing: border-box;
18
+ }
19
+
20
+ /* 自定义组件样式 */
21
+ .ant-layout-sider {
22
+ box-shadow: 2px 0 6px rgba(0, 21, 41, 0.35);
23
+ }
24
+
25
+ .ant-menu-dark {
26
+ background: transparent;
27
+ }
28
+
29
+ /* 响应式设计 */
30
+ @media (max-width: 768px) {
31
+ .ant-layout-sider {
32
+ position: fixed !important;
33
+ left: 0;
34
+ top: 0;
35
+ bottom: 0;
36
+ z-index: 999;
37
+ }
38
+ }
@@ -0,0 +1,4 @@
1
+ declare module '*.less' {
2
+ const classes: { [key: string]: string };
3
+ export default classes;
4
+ }
@@ -0,0 +1,7 @@
1
+ declare module 'rehype-mathjax'
2
+ declare module 'remark-math'
3
+ declare module 'remark-gfm'
4
+ declare module 'react-markdown'
5
+ declare module 'react-markdown-reader'
6
+ declare module 'dayjs'
7
+ declare module 'bisheng'
@@ -0,0 +1,39 @@
1
+ declare module '@ai/utils/guid' {
2
+ export default function guid(): string;
3
+ }
4
+
5
+ declare module '@ai/utils/request' {
6
+ export function request<T = any>(
7
+ url: string,
8
+ data?: Record<string, any>,
9
+ options?: {
10
+ method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
11
+ headers?: Record<string, string>;
12
+ [key: string]: any;
13
+ }
14
+ ): Promise<T>;
15
+
16
+ export function addRequestHookBefore(
17
+ url: string,
18
+ hook: (params: Record<string, any>) => Record<string, any>
19
+ ): void;
20
+
21
+ export function getToken(): void;
22
+ }
23
+
24
+ declare module '@ai/i18n' {
25
+ const i18n: {
26
+ t(key: string): string;
27
+ };
28
+ export const t: (key: string, namespace?: string) => string;
29
+ export default i18n;
30
+ }
31
+
32
+ declare module '@ai/utils/utils' {
33
+ export function arrayToTree<T extends { id: number | string; parentId: number | string }>(
34
+ array: T[],
35
+ parentId?: number | string
36
+ ): (T & { children: T[] })[];
37
+
38
+ export function getIsTenant(): boolean;
39
+ }
@@ -0,0 +1,19 @@
1
+ export function getUserPermissions() {
2
+ let s = sessionStorage.getItem("userInfo") || localStorage.getItem("userInfo");
3
+ return JSON.parse(s)
4
+ ? JSON.parse(s).permissions
5
+ : [];
6
+ }
7
+ export function hasPermissions(auth) {
8
+ let show;
9
+ const permissions = getUserPermissions() || [];
10
+ if (typeof auth === 'number') {
11
+ show = permissions.includes(auth);
12
+ } else if (Array.isArray(auth)) {
13
+ show = auth.some(item => permissions.includes(item));
14
+ }
15
+ return show;
16
+ }
17
+ export default ({ children, auth }) => {
18
+ return hasPermissions(auth) ? children : null;
19
+ };