finstep-template-cli 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -0
- package/cli.js +117 -0
- package/package.json +39 -0
- package/template/.env.development +3 -0
- package/template/.env.production +3 -0
- package/template/.env.staging +3 -0
- package/template/.env.test +3 -0
- package/template/.eslintrc.cjs +21 -0
- package/template/README.md +69 -0
- package/template/auto-imports.d.ts +47 -0
- package/template/eslint.config.js +26 -0
- package/template/index.html +16 -0
- package/template/package.json +46 -0
- package/template/postcss.config.js +5 -0
- package/template/public/logo.svg +85 -0
- package/template/public/vite.svg +1 -0
- package/template/src/App.css +42 -0
- package/template/src/App.tsx +25 -0
- package/template/src/api/home/index.ts +56 -0
- package/template/src/api/home/typings.d.ts +8 -0
- package/template/src/assets/logo.svg +85 -0
- package/template/src/assets/react.svg +1 -0
- package/template/src/components/admin-layout.tsx +211 -0
- package/template/src/components/f-b-footer.tsx +46 -0
- package/template/src/components/f-b-header.tsx +894 -0
- package/template/src/components/global-loading.tsx +143 -0
- package/template/src/components/hero-section.tsx +371 -0
- package/template/src/components/products-preview.tsx +175 -0
- package/template/src/components/stats-section.tsx +85 -0
- package/template/src/components/trusted-by.tsx +53 -0
- package/template/src/hooks/useGlobalLoading.ts +57 -0
- package/template/src/index.css +341 -0
- package/template/src/main.tsx +30 -0
- package/template/src/pages/admin/index.tsx +361 -0
- package/template/src/pages/admin/pages/applications/index.tsx +558 -0
- package/template/src/pages/home/index.tsx +129 -0
- package/template/src/router/index.tsx +9 -0
- package/template/src/router/routes.tsx +30 -0
- package/template/src/stores/loading.store.ts +46 -0
- package/template/src/stores/root.store.ts +22 -0
- package/template/src/stores/store-context.tsx +43 -0
- package/template/src/stores/user.store.ts +46 -0
- package/template/src/utils/index.ts +14 -0
- package/template/src/utils/request.ts +116 -0
- package/template/src/utils/tokenManager.ts +168 -0
- package/template/src/vite-env.d.ts +1 -0
- package/template/tailwind.config.js +19 -0
- package/template/tsconfig.app.json +29 -0
- package/template/tsconfig.json +7 -0
- package/template/tsconfig.node.json +26 -0
- package/template/vite.config.ts +36 -0
package/README.md
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# Finstep Template CLI
|
2
|
+
|
3
|
+
一个用于快速创建 Finstep 项目模板的脚手架工具。
|
4
|
+
|
5
|
+
## 特性
|
6
|
+
|
7
|
+
- 🚀 基于 React 18 + TypeScript + Vite
|
8
|
+
- 🎨 集成 Ant Design + Tailwind CSS
|
9
|
+
- 📱 响应式设计
|
10
|
+
- 🔄 状态管理 (MobX)
|
11
|
+
- 🛣️ 路由管理 (React Router)
|
12
|
+
- 📦 包管理 (pnpm)
|
13
|
+
- 🔧 开发工具配置完整
|
14
|
+
|
15
|
+
## 安装
|
16
|
+
|
17
|
+
```bash
|
18
|
+
npm install -g finstep-template-cli
|
19
|
+
```
|
20
|
+
|
21
|
+
## 使用
|
22
|
+
|
23
|
+
### 创建新项目
|
24
|
+
|
25
|
+
```bash
|
26
|
+
# 交互式创建
|
27
|
+
create-finstep-app
|
28
|
+
|
29
|
+
# 直接指定项目名称
|
30
|
+
create-finstep-app my-project
|
31
|
+
```
|
32
|
+
|
33
|
+
### 开发
|
34
|
+
|
35
|
+
```bash
|
36
|
+
cd my-project
|
37
|
+
pnpm install
|
38
|
+
pnpm dev
|
39
|
+
```
|
40
|
+
|
41
|
+
## 项目结构
|
package/cli.js
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
#!/usr/bin/env node
|
2
|
+
|
3
|
+
// AI生成的脚手架CLI工具
|
4
|
+
const { program } = require('commander');
|
5
|
+
const inquirer = require('inquirer');
|
6
|
+
const fs = require('fs-extra');
|
7
|
+
const path = require('path');
|
8
|
+
const chalk = require('chalk');
|
9
|
+
const ora = require('ora');
|
10
|
+
|
11
|
+
program
|
12
|
+
.name('create-finstep-app')
|
13
|
+
.description('创建Finstep项目模板')
|
14
|
+
.version('1.0.0');
|
15
|
+
|
16
|
+
program
|
17
|
+
.argument('[project-name]', '项目名称')
|
18
|
+
.action(async (projectName) => {
|
19
|
+
try {
|
20
|
+
// 如果没有提供项目名称,则询问用户
|
21
|
+
if (!projectName) {
|
22
|
+
const answers = await inquirer.prompt([
|
23
|
+
{
|
24
|
+
type: 'input',
|
25
|
+
name: 'projectName',
|
26
|
+
message: '请输入项目名称:',
|
27
|
+
validate: (input) => {
|
28
|
+
if (!input.trim()) {
|
29
|
+
return '项目名称不能为空';
|
30
|
+
}
|
31
|
+
if (!/^[a-zA-Z0-9-_]+$/.test(input)) {
|
32
|
+
return '项目名称只能包含字母、数字、连字符和下划线';
|
33
|
+
}
|
34
|
+
return true;
|
35
|
+
}
|
36
|
+
}
|
37
|
+
]);
|
38
|
+
projectName = answers.projectName;
|
39
|
+
}
|
40
|
+
|
41
|
+
// 检查目录是否已存在
|
42
|
+
const targetDir = path.resolve(process.cwd(), projectName);
|
43
|
+
if (fs.existsSync(targetDir)) {
|
44
|
+
const { overwrite } = await inquirer.prompt([
|
45
|
+
{
|
46
|
+
type: 'confirm',
|
47
|
+
name: 'overwrite',
|
48
|
+
message: `目录 ${projectName} 已存在,是否覆盖?`,
|
49
|
+
default: false
|
50
|
+
}
|
51
|
+
]);
|
52
|
+
|
53
|
+
if (!overwrite) {
|
54
|
+
console.log(chalk.yellow('操作已取消'));
|
55
|
+
process.exit(0);
|
56
|
+
}
|
57
|
+
|
58
|
+
await fs.remove(targetDir);
|
59
|
+
}
|
60
|
+
|
61
|
+
// 创建项目
|
62
|
+
await createProject(projectName, targetDir);
|
63
|
+
|
64
|
+
} catch (error) {
|
65
|
+
console.error(chalk.red('创建项目失败:'), error.message);
|
66
|
+
process.exit(1);
|
67
|
+
}
|
68
|
+
});
|
69
|
+
|
70
|
+
/**
|
71
|
+
* 创建项目函数
|
72
|
+
* @param {string} projectName - 项目名称
|
73
|
+
* @param {string} targetDir - 目标目录
|
74
|
+
*/
|
75
|
+
async function createProject(projectName, targetDir) {
|
76
|
+
const spinner = ora('正在创建项目...').start();
|
77
|
+
|
78
|
+
try {
|
79
|
+
// 复制模板文件
|
80
|
+
const templateDir = path.join(__dirname, 'template');
|
81
|
+
// 检查模板目录是否存在
|
82
|
+
if (!fs.existsSync(templateDir)) {
|
83
|
+
throw new Error('模板目录不存在,请检查安装是否完整');
|
84
|
+
}
|
85
|
+
await fs.copy(templateDir, targetDir);
|
86
|
+
|
87
|
+
// 更新package.json中的项目名称
|
88
|
+
const packageJsonPath = path.join(targetDir, 'package.json');
|
89
|
+
const packageJson = await fs.readJson(packageJsonPath);
|
90
|
+
packageJson.name = projectName;
|
91
|
+
await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 });
|
92
|
+
|
93
|
+
// 更新README.md
|
94
|
+
const readmePath = path.join(targetDir, 'README.md');
|
95
|
+
let readmeContent = await fs.readFile(readmePath, 'utf-8');
|
96
|
+
readmeContent = readmeContent.replace(/finstep-b-protal/g, projectName);
|
97
|
+
await fs.writeFile(readmePath, readmeContent);
|
98
|
+
|
99
|
+
spinner.succeed('项目创建成功!');
|
100
|
+
|
101
|
+
console.log();
|
102
|
+
console.log(chalk.green(`✨ 项目 ${projectName} 创建成功!`));
|
103
|
+
console.log();
|
104
|
+
console.log('接下来的步骤:');
|
105
|
+
console.log(chalk.cyan(` cd ${projectName}`));
|
106
|
+
console.log(chalk.cyan(' pnpm install'));
|
107
|
+
console.log(chalk.cyan(' pnpm dev'));
|
108
|
+
console.log();
|
109
|
+
console.log('祝你开发愉快! 🚀');
|
110
|
+
|
111
|
+
} catch (error) {
|
112
|
+
spinner.fail('项目创建失败');
|
113
|
+
throw error;
|
114
|
+
}
|
115
|
+
}
|
116
|
+
|
117
|
+
program.parse();
|
package/package.json
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
{
|
2
|
+
"name": "finstep-template-cli",
|
3
|
+
"version": "1.0.1",
|
4
|
+
"description": "Finstep项目模板脚手架工具",
|
5
|
+
"main": "index.js",
|
6
|
+
"bin": {
|
7
|
+
"create-finstep-app": "cli.js"
|
8
|
+
},
|
9
|
+
"files": [
|
10
|
+
"template/",
|
11
|
+
"cli.js",
|
12
|
+
"README.md"
|
13
|
+
],
|
14
|
+
"scripts": {
|
15
|
+
"build": "node build.js",
|
16
|
+
"prepublishOnly": "npm run build"
|
17
|
+
},
|
18
|
+
"keywords": [
|
19
|
+
"finstep",
|
20
|
+
"template",
|
21
|
+
"react",
|
22
|
+
"typescript",
|
23
|
+
"vite",
|
24
|
+
"antd"
|
25
|
+
],
|
26
|
+
"author": "finstep",
|
27
|
+
"license": "MIT",
|
28
|
+
"dependencies": {
|
29
|
+
"chalk": "^5.5.0",
|
30
|
+
"commander": "^11.1.0",
|
31
|
+
"fs-extra": "^11.3.1",
|
32
|
+
"inquirer": "^9.3.7",
|
33
|
+
"ora": "^7.0.1"
|
34
|
+
},
|
35
|
+
"devDependencies": {
|
36
|
+
"@types/fs-extra": "^11.0.4",
|
37
|
+
"@types/inquirer": "^9.0.9"
|
38
|
+
}
|
39
|
+
}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
/* AI Generated Code - ESLint 配置文件 */
|
2
|
+
module.exports = {
|
3
|
+
root: true,
|
4
|
+
env: { browser: true, es2020: true },
|
5
|
+
extends: [
|
6
|
+
'eslint:recommended',
|
7
|
+
'@typescript-eslint/recommended',
|
8
|
+
'plugin:react-hooks/recommended',
|
9
|
+
],
|
10
|
+
ignorePatterns: ['dist', '.eslintrc.cjs'],
|
11
|
+
parser: '@typescript-eslint/parser',
|
12
|
+
plugins: ['react-refresh'],
|
13
|
+
rules: {
|
14
|
+
'react-refresh/only-export-components': [
|
15
|
+
'warn',
|
16
|
+
{ allowConstantExport: true },
|
17
|
+
],
|
18
|
+
'react-hooks/exhaustive-deps': 'off',
|
19
|
+
'@typescript-eslint/no-unused-vars': 'warn',
|
20
|
+
},
|
21
|
+
}
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# React + TypeScript + Vite
|
2
|
+
|
3
|
+
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
|
4
|
+
|
5
|
+
Currently, two official plugins are available:
|
6
|
+
|
7
|
+
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh
|
8
|
+
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
|
9
|
+
|
10
|
+
## Expanding the ESLint configuration
|
11
|
+
|
12
|
+
If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
|
13
|
+
|
14
|
+
```js
|
15
|
+
export default tseslint.config([
|
16
|
+
globalIgnores(['dist']),
|
17
|
+
{
|
18
|
+
files: ['**/*.{ts,tsx}'],
|
19
|
+
extends: [
|
20
|
+
// Other configs...
|
21
|
+
|
22
|
+
// Remove tseslint.configs.recommended and replace with this
|
23
|
+
...tseslint.configs.recommendedTypeChecked,
|
24
|
+
// Alternatively, use this for stricter rules
|
25
|
+
...tseslint.configs.strictTypeChecked,
|
26
|
+
// Optionally, add this for stylistic rules
|
27
|
+
...tseslint.configs.stylisticTypeChecked,
|
28
|
+
|
29
|
+
// Other configs...
|
30
|
+
],
|
31
|
+
languageOptions: {
|
32
|
+
parserOptions: {
|
33
|
+
project: ['./tsconfig.node.json', './tsconfig.app.json'],
|
34
|
+
tsconfigRootDir: import.meta.dirname,
|
35
|
+
},
|
36
|
+
// other options...
|
37
|
+
},
|
38
|
+
},
|
39
|
+
])
|
40
|
+
```
|
41
|
+
|
42
|
+
You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:
|
43
|
+
|
44
|
+
```js
|
45
|
+
// eslint.config.js
|
46
|
+
import reactX from 'eslint-plugin-react-x'
|
47
|
+
import reactDom from 'eslint-plugin-react-dom'
|
48
|
+
|
49
|
+
export default tseslint.config([
|
50
|
+
globalIgnores(['dist']),
|
51
|
+
{
|
52
|
+
files: ['**/*.{ts,tsx}'],
|
53
|
+
extends: [
|
54
|
+
// Other configs...
|
55
|
+
// Enable lint rules for React
|
56
|
+
reactX.configs['recommended-typescript'],
|
57
|
+
// Enable lint rules for React DOM
|
58
|
+
reactDom.configs.recommended,
|
59
|
+
],
|
60
|
+
languageOptions: {
|
61
|
+
parserOptions: {
|
62
|
+
project: ['./tsconfig.node.json', './tsconfig.app.json'],
|
63
|
+
tsconfigRootDir: import.meta.dirname,
|
64
|
+
},
|
65
|
+
// other options...
|
66
|
+
},
|
67
|
+
},
|
68
|
+
])
|
69
|
+
```
|
@@ -0,0 +1,47 @@
|
|
1
|
+
/* eslint-disable */
|
2
|
+
/* prettier-ignore */
|
3
|
+
// @ts-nocheck
|
4
|
+
// noinspection JSUnusedGlobalSymbols
|
5
|
+
// Generated by unplugin-auto-import
|
6
|
+
// biome-ignore lint: disable
|
7
|
+
export {}
|
8
|
+
declare global {
|
9
|
+
const Link: typeof import('react-router-dom')['Link']
|
10
|
+
const NavLink: typeof import('react-router-dom')['NavLink']
|
11
|
+
const Navigate: typeof import('react-router-dom')['Navigate']
|
12
|
+
const Outlet: typeof import('react-router-dom')['Outlet']
|
13
|
+
const Route: typeof import('react-router-dom')['Route']
|
14
|
+
const Routes: typeof import('react-router-dom')['Routes']
|
15
|
+
const createRef: typeof import('react')['createRef']
|
16
|
+
const forwardRef: typeof import('react')['forwardRef']
|
17
|
+
const lazy: typeof import('react')['lazy']
|
18
|
+
const memo: typeof import('react')['memo']
|
19
|
+
const startTransition: typeof import('react')['startTransition']
|
20
|
+
const useCallback: typeof import('react')['useCallback']
|
21
|
+
const useContext: typeof import('react')['useContext']
|
22
|
+
const useDebugValue: typeof import('react')['useDebugValue']
|
23
|
+
const useDeferredValue: typeof import('react')['useDeferredValue']
|
24
|
+
const useEffect: typeof import('react')['useEffect']
|
25
|
+
const useHref: typeof import('react-router')['useHref']
|
26
|
+
const useId: typeof import('react')['useId']
|
27
|
+
const useImperativeHandle: typeof import('react')['useImperativeHandle']
|
28
|
+
const useInRouterContext: typeof import('react-router')['useInRouterContext']
|
29
|
+
const useInsertionEffect: typeof import('react')['useInsertionEffect']
|
30
|
+
const useLayoutEffect: typeof import('react')['useLayoutEffect']
|
31
|
+
const useLinkClickHandler: typeof import('react-router-dom')['useLinkClickHandler']
|
32
|
+
const useLocation: typeof import('react-router')['useLocation']
|
33
|
+
const useMemo: typeof import('react')['useMemo']
|
34
|
+
const useNavigate: typeof import('react-router')['useNavigate']
|
35
|
+
const useNavigationType: typeof import('react-router')['useNavigationType']
|
36
|
+
const useOutlet: typeof import('react-router')['useOutlet']
|
37
|
+
const useOutletContext: typeof import('react-router')['useOutletContext']
|
38
|
+
const useParams: typeof import('react-router')['useParams']
|
39
|
+
const useReducer: typeof import('react')['useReducer']
|
40
|
+
const useRef: typeof import('react')['useRef']
|
41
|
+
const useResolvedPath: typeof import('react-router')['useResolvedPath']
|
42
|
+
const useRoutes: typeof import('react-router')['useRoutes']
|
43
|
+
const useSearchParams: typeof import('react-router-dom')['useSearchParams']
|
44
|
+
const useState: typeof import('react')['useState']
|
45
|
+
const useSyncExternalStore: typeof import('react')['useSyncExternalStore']
|
46
|
+
const useTransition: typeof import('react')['useTransition']
|
47
|
+
}
|
@@ -0,0 +1,26 @@
|
|
1
|
+
import js from '@eslint/js'
|
2
|
+
import globals from 'globals'
|
3
|
+
import reactHooks from 'eslint-plugin-react-hooks'
|
4
|
+
import reactRefresh from 'eslint-plugin-react-refresh'
|
5
|
+
import tseslint from 'typescript-eslint'
|
6
|
+
|
7
|
+
export default tseslint.config(
|
8
|
+
{ ignores: ['dist'] },
|
9
|
+
{
|
10
|
+
extends: [js.configs.recommended, ...tseslint.configs.recommended],
|
11
|
+
files: ['**/*.{ts,tsx}'],
|
12
|
+
languageOptions: {
|
13
|
+
ecmaVersion: 2020,
|
14
|
+
globals: globals.browser,
|
15
|
+
},
|
16
|
+
plugins: {
|
17
|
+
'react-hooks': reactHooks,
|
18
|
+
'react-refresh': reactRefresh,
|
19
|
+
},
|
20
|
+
rules: {
|
21
|
+
...reactHooks.configs.recommended.rules,
|
22
|
+
"react-hooks/exhaustive-deps": "off",
|
23
|
+
'react-refresh/only-export-components': 'off',
|
24
|
+
},
|
25
|
+
},
|
26
|
+
)
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
<html lang="en">
|
3
|
+
|
4
|
+
<head>
|
5
|
+
<meta charset="UTF-8" />
|
6
|
+
<link rel="icon" type="image/svg+xml" href="/logo.svg" />
|
7
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
8
|
+
<title>财跃星辰</title>
|
9
|
+
</head>
|
10
|
+
|
11
|
+
<body>
|
12
|
+
<div id="root"></div>
|
13
|
+
<script type="module" src="/src/main.tsx"></script>
|
14
|
+
</body>
|
15
|
+
|
16
|
+
</html>
|
@@ -0,0 +1,46 @@
|
|
1
|
+
{
|
2
|
+
"name": "finstep-b-protal",
|
3
|
+
"private": true,
|
4
|
+
"version": "0.0.0",
|
5
|
+
"type": "module",
|
6
|
+
"scripts": {
|
7
|
+
"dev": "vite",
|
8
|
+
"build": "tsc -b && vite build",
|
9
|
+
"build:test": "vite build --mode test",
|
10
|
+
"build:stag": "vite build -mode stag",
|
11
|
+
"lint": "eslint .",
|
12
|
+
"preview": "vite preview"
|
13
|
+
},
|
14
|
+
"dependencies": {
|
15
|
+
"@ant-design/icons": "^6.0.0",
|
16
|
+
"@tailwindcss/postcss": "^4.1.11",
|
17
|
+
"antd": "^5.26.7",
|
18
|
+
"autoprefixer": "^10.4.21",
|
19
|
+
"axios": "^1.11.0",
|
20
|
+
"finstep-b-components": "1.0.8",
|
21
|
+
"framer-motion": "^12.23.12",
|
22
|
+
"mobx": "^6.13.6",
|
23
|
+
"mobx-persist-store": "^1.1.5",
|
24
|
+
"mobx-react-lite": "^4.1.0",
|
25
|
+
"postcss": "^8.5.6",
|
26
|
+
"react": "^18.3.1",
|
27
|
+
"react-dom": "^18.3.1",
|
28
|
+
"react-router-dom": "^6.28.0",
|
29
|
+
"tailwindcss": "^4.1.11"
|
30
|
+
},
|
31
|
+
"devDependencies": {
|
32
|
+
"@eslint/js": "^9.30.1",
|
33
|
+
"@types/node": "^24.2.0",
|
34
|
+
"@types/react": "^18.3.12",
|
35
|
+
"@types/react-dom": "^18.3.1",
|
36
|
+
"@vitejs/plugin-react": "^4.6.0",
|
37
|
+
"eslint": "^9.30.1",
|
38
|
+
"eslint-plugin-react-hooks": "^5.2.0",
|
39
|
+
"eslint-plugin-react-refresh": "^0.4.20",
|
40
|
+
"globals": "^16.3.0",
|
41
|
+
"typescript": "~5.8.3",
|
42
|
+
"typescript-eslint": "^8.35.1",
|
43
|
+
"unplugin-auto-import": "^0.19.0",
|
44
|
+
"vite": "^7.0.4"
|
45
|
+
}
|
46
|
+
}
|
@@ -0,0 +1,85 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<svg id="_图层_2" data-name="图层 2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 274.54 211.7">
|
3
|
+
<defs>
|
4
|
+
<style>
|
5
|
+
.cls-1 {
|
6
|
+
fill: url(#_未命名的渐变_21);
|
7
|
+
}
|
8
|
+
|
9
|
+
.cls-1, .cls-2, .cls-3, .cls-4, .cls-5, .cls-6, .cls-7 {
|
10
|
+
stroke-width: 0px;
|
11
|
+
}
|
12
|
+
|
13
|
+
.cls-2 {
|
14
|
+
fill: url(#_未命名的渐变_20);
|
15
|
+
}
|
16
|
+
|
17
|
+
.cls-2, .cls-3, .cls-4, .cls-5, .cls-6, .cls-7 {
|
18
|
+
fill-rule: evenodd;
|
19
|
+
}
|
20
|
+
|
21
|
+
.cls-3 {
|
22
|
+
fill: url(#_未命名的渐变_23);
|
23
|
+
}
|
24
|
+
|
25
|
+
.cls-4 {
|
26
|
+
fill: url(#_未命名的渐变_12);
|
27
|
+
}
|
28
|
+
|
29
|
+
.cls-5 {
|
30
|
+
fill: url(#_未命名的渐变_3);
|
31
|
+
}
|
32
|
+
|
33
|
+
.cls-6 {
|
34
|
+
fill: url(#_未命名的渐变_12-2);
|
35
|
+
}
|
36
|
+
|
37
|
+
.cls-7 {
|
38
|
+
fill: url(#_未命名的渐变_3-2);
|
39
|
+
}
|
40
|
+
</style>
|
41
|
+
<linearGradient id="_未命名的渐变_12" data-name="未命名的渐变 12" x1="20.63" y1="111.57" x2="27.95" y2="68.34" gradientUnits="userSpaceOnUse">
|
42
|
+
<stop offset="0" stop-color="#f9b1ff"/>
|
43
|
+
<stop offset="1" stop-color="#9764ff"/>
|
44
|
+
</linearGradient>
|
45
|
+
<linearGradient id="_未命名的渐变_3" data-name="未命名的渐变 3" x1="0" y1="26.46" x2="211.7" y2="26.46" gradientUnits="userSpaceOnUse">
|
46
|
+
<stop offset="0" stop-color="#12b3fd"/>
|
47
|
+
<stop offset="1" stop-color="#8efdf4"/>
|
48
|
+
</linearGradient>
|
49
|
+
<linearGradient id="_未命名的渐变_23" data-name="未命名的渐变 23" x1="166.3" y1="187.93" x2="258.08" y2="29.64" gradientUnits="userSpaceOnUse">
|
50
|
+
<stop offset="0" stop-color="#df102a"/>
|
51
|
+
<stop offset=".17" stop-color="#e11730"/>
|
52
|
+
<stop offset=".42" stop-color="#e72a42"/>
|
53
|
+
<stop offset=".72" stop-color="#f04a5f"/>
|
54
|
+
<stop offset="1" stop-color="#fc7081"/>
|
55
|
+
</linearGradient>
|
56
|
+
<linearGradient id="_未命名的渐变_12-2" data-name="未命名的渐变 12" x1="45.83" y1="172" x2="150.59" y2="172" xlink:href="#_未命名的渐变_12"/>
|
57
|
+
<linearGradient id="_未命名的渐变_3-2" data-name="未命名的渐变 3" x1="45.83" y1="105.85" x2="165.87" y2="105.85" xlink:href="#_未命名的渐变_3"/>
|
58
|
+
<linearGradient id="_未命名的渐变_21" data-name="未命名的渐变 21" x1="87.39" y1="155.31" x2="91.71" y2="129.71" gradientUnits="userSpaceOnUse">
|
59
|
+
<stop offset="0" stop-color="#7f26fc"/>
|
60
|
+
<stop offset=".15" stop-color="#7629fc"/>
|
61
|
+
<stop offset=".4" stop-color="#6033fc"/>
|
62
|
+
<stop offset=".7" stop-color="#3b43fc"/>
|
63
|
+
<stop offset="1" stop-color="#0f57fd"/>
|
64
|
+
</linearGradient>
|
65
|
+
<linearGradient id="_未命名的渐变_20" data-name="未命名的渐变 20" x1="21.98" y1="67.7" x2="35.9" y2="44.2" gradientUnits="userSpaceOnUse">
|
66
|
+
<stop offset="0" stop-color="#7f26fc"/>
|
67
|
+
<stop offset=".17" stop-color="#7928fc"/>
|
68
|
+
<stop offset=".37" stop-color="#6b2efc"/>
|
69
|
+
<stop offset=".58" stop-color="#5339fc"/>
|
70
|
+
<stop offset=".8" stop-color="#3247fc"/>
|
71
|
+
<stop offset="1" stop-color="#0f57fd"/>
|
72
|
+
</linearGradient>
|
73
|
+
</defs>
|
74
|
+
<g id="_图层_1-2" data-name="图层 1">
|
75
|
+
<g>
|
76
|
+
<path class="cls-4" d="M27.96,4.5L0,52.92l27.96,48.42c1.15,2,4.04,2,5.2,0l27.96-48.42L33.15,4.5c-1.15-2-4.04-2-5.2,0Z"/>
|
77
|
+
<path class="cls-5" d="M208.69,0H32.29c-1.07,0-2.06.57-2.6,1.5L0,52.92h181.6c1.07,0,2.06-.57,2.6-1.5l27.09-46.92c1.15-2-.29-4.5-2.6-4.5Z"/>
|
78
|
+
<path class="cls-3" d="M153.65,157.27L241.85,4.5c1.15-2,4.04-2,5.2,0l27.09,46.92c.54.93.54,2.07,0,3l-88.2,152.77c-1.15,2-4.04,2-5.2,0l-27.09-46.92c-.54-.93-.54-2.07,0-3Z"/>
|
79
|
+
<path class="cls-6" d="M106.95,132.31h-61.11l44.97,77.89c.54.93,1.53,1.5,2.6,1.5h54.18c2.31,0,3.75-2.5,2.6-4.5l-43.24-74.89Z"/>
|
80
|
+
<path class="cls-7" d="M162.86,79.39h-84.74c-1.07,0-2.06.57-2.6,1.5l-29.69,51.42h89.94c1.07,0,2.06-.57,2.6-1.5l27.09-46.92c1.15-2-.29-4.5-2.6-4.5Z"/>
|
81
|
+
<polygon class="cls-1" points="106.95 132.31 129.99 172.13 45.83 132.31 106.95 132.31"/>
|
82
|
+
<polygon class="cls-2" points="61.11 52.92 0 52.92 48 75.64 61.11 52.92"/>
|
83
|
+
</g>
|
84
|
+
</g>
|
85
|
+
</svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
@@ -0,0 +1,42 @@
|
|
1
|
+
#root {
|
2
|
+
max-width: 1280px;
|
3
|
+
margin: 0 auto;
|
4
|
+
padding: 2rem;
|
5
|
+
text-align: center;
|
6
|
+
}
|
7
|
+
|
8
|
+
.logo {
|
9
|
+
height: 6em;
|
10
|
+
padding: 1.5em;
|
11
|
+
will-change: filter;
|
12
|
+
transition: filter 300ms;
|
13
|
+
}
|
14
|
+
.logo:hover {
|
15
|
+
filter: drop-shadow(0 0 2em #646cffaa);
|
16
|
+
}
|
17
|
+
.logo.react:hover {
|
18
|
+
filter: drop-shadow(0 0 2em #61dafbaa);
|
19
|
+
}
|
20
|
+
|
21
|
+
@keyframes logo-spin {
|
22
|
+
from {
|
23
|
+
transform: rotate(0deg);
|
24
|
+
}
|
25
|
+
to {
|
26
|
+
transform: rotate(360deg);
|
27
|
+
}
|
28
|
+
}
|
29
|
+
|
30
|
+
@media (prefers-reduced-motion: no-preference) {
|
31
|
+
a:nth-of-type(2) .logo {
|
32
|
+
animation: logo-spin infinite 20s linear;
|
33
|
+
}
|
34
|
+
}
|
35
|
+
|
36
|
+
.card {
|
37
|
+
padding: 2em;
|
38
|
+
}
|
39
|
+
|
40
|
+
.read-the-docs {
|
41
|
+
color: #888;
|
42
|
+
}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
// AI生成的代码 - 主应用组件
|
2
|
+
import { HashRouter } from "react-router-dom";
|
3
|
+
import Router from "./router";
|
4
|
+
// AI生成的代码 - 导入状态管理Provider
|
5
|
+
import { StoreProvider } from "./stores/store-context";
|
6
|
+
import GlobalLoading from "./components/global-loading";
|
7
|
+
|
8
|
+
// 创建路由实例
|
9
|
+
|
10
|
+
// AI生成的代码 - 主应用组件,包含 Ant Design App 组件以支持上下文感知的 message API
|
11
|
+
function App() {
|
12
|
+
return (
|
13
|
+
<StoreProvider>
|
14
|
+
<div className="min-h-screen bg-slate-950">
|
15
|
+
<HashRouter>
|
16
|
+
<Router />
|
17
|
+
</HashRouter>
|
18
|
+
{/* AI生成的代码 - 全局Loading组件 */}
|
19
|
+
<GlobalLoading />
|
20
|
+
</div>
|
21
|
+
</StoreProvider>
|
22
|
+
);
|
23
|
+
}
|
24
|
+
|
25
|
+
export default App;
|
@@ -0,0 +1,56 @@
|
|
1
|
+
import request from "@/utils/request";
|
2
|
+
|
3
|
+
// AI生成的代码 - 用户名密码登录接口
|
4
|
+
export async function login(data: {
|
5
|
+
username: string;
|
6
|
+
password: string;
|
7
|
+
}): Promise<HomeAPi.LoginInfoResponse> {
|
8
|
+
return request({
|
9
|
+
url: "auth/oauth2/token",
|
10
|
+
method: "post",
|
11
|
+
isLoginApi: true, // AI生成的代码 - 标识这是登录接口
|
12
|
+
headers: {
|
13
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
14
|
+
},
|
15
|
+
data: {
|
16
|
+
...data,
|
17
|
+
grant_type: "password",
|
18
|
+
scope: "server",
|
19
|
+
},
|
20
|
+
});
|
21
|
+
}
|
22
|
+
// AI生成的代码 - 飞书登录接口
|
23
|
+
export async function feishuLogin(data: {
|
24
|
+
mobile: string;
|
25
|
+
}): Promise<HomeAPi.LoginInfoResponse> {
|
26
|
+
return request({
|
27
|
+
url: "auth/oauth2/token",
|
28
|
+
method: "post",
|
29
|
+
isLoginApi: true, // AI生成的代码 - 标识这是登录接口
|
30
|
+
headers: {
|
31
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
32
|
+
},
|
33
|
+
data: {
|
34
|
+
...data,
|
35
|
+
grant_type: "mobile",
|
36
|
+
scope: "server",
|
37
|
+
},
|
38
|
+
});
|
39
|
+
}
|
40
|
+
export async function refreshToken(data: {
|
41
|
+
refresh_token: string;
|
42
|
+
}): Promise<HomeAPi.LoginInfoResponse> {
|
43
|
+
return request({
|
44
|
+
url: "auth/oauth2/token",
|
45
|
+
method: "post",
|
46
|
+
isLoginApi: true, // AI生成的代码 - 标识这是登录接口
|
47
|
+
headers: {
|
48
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
49
|
+
},
|
50
|
+
data: {
|
51
|
+
...data,
|
52
|
+
grant_type: "refresh_token",
|
53
|
+
scope: "server",
|
54
|
+
},
|
55
|
+
});
|
56
|
+
}
|