Ver Fonte

架构项目

李富豪 há 11 meses atrás
commit
c23a7bc8dc
57 ficheiros alterados com 5669 adições e 0 exclusões
  1. 14 0
      .gitignore
  2. 36 0
      README.md
  3. 8 0
      env/.env.development
  4. 8 0
      env/.env.production
  5. 17 0
      index.html
  6. 2983 0
      package-lock.json
  7. 33 0
      package.json
  8. 103 0
      src/App.tsx
  9. 78 0
      src/LocalStorage.ts
  10. 66 0
      src/apis/api.ts
  11. 14 0
      src/apis/config.ts
  12. 20 0
      src/apis/index.ts
  13. BIN
      src/assets/login/background.jpg
  14. BIN
      src/assets/public/logo.png
  15. BIN
      src/assets/public/notFound.png
  16. 16 0
      src/components/404/index.tsx
  17. 23 0
      src/components/404/style.less
  18. 20 0
      src/components/iconFont/index.tsx
  19. 24 0
      src/main.tsx
  20. 44 0
      src/pages/dataExport/index.tsx
  21. 47 0
      src/pages/dataExport/store.ts
  22. 83 0
      src/pages/dataExport/style.less
  23. 19 0
      src/pages/dataExport/types.ts
  24. 44 0
      src/pages/knowledgeBase/info/index.tsx
  25. 47 0
      src/pages/knowledgeBase/info/store.ts
  26. 83 0
      src/pages/knowledgeBase/info/style.less
  27. 19 0
      src/pages/knowledgeBase/info/types.ts
  28. 44 0
      src/pages/knowledgeBase/list/index.tsx
  29. 47 0
      src/pages/knowledgeBase/list/store.ts
  30. 83 0
      src/pages/knowledgeBase/list/style.less
  31. 19 0
      src/pages/knowledgeBase/list/types.ts
  32. 27 0
      src/pages/layout/components/Breadcrumb.tsx
  33. 64 0
      src/pages/layout/components/Header.tsx
  34. 73 0
      src/pages/layout/components/Nav.tsx
  35. 74 0
      src/pages/layout/index.tsx
  36. 128 0
      src/pages/layout/store.ts
  37. 102 0
      src/pages/layout/style.less
  38. 54 0
      src/pages/layout/types.ts
  39. 18 0
      src/pages/login/components/Copyright.tsx
  40. 112 0
      src/pages/login/index.tsx
  41. 110 0
      src/pages/login/store.tsx
  42. 50 0
      src/pages/login/style.less
  43. 26 0
      src/pages/login/types.ts
  44. 44 0
      src/pages/questionAnswerApp/info/index.tsx
  45. 47 0
      src/pages/questionAnswerApp/info/store.ts
  46. 83 0
      src/pages/questionAnswerApp/info/style.less
  47. 19 0
      src/pages/questionAnswerApp/info/types.ts
  48. 44 0
      src/pages/questionAnswerApp/list/index.tsx
  49. 47 0
      src/pages/questionAnswerApp/list/store.ts
  50. 83 0
      src/pages/questionAnswerApp/list/style.less
  51. 19 0
      src/pages/questionAnswerApp/list/types.ts
  52. 152 0
      src/router.tsx
  53. 103 0
      src/style/global.less
  54. 6 0
      src/typings/images.d.ts
  55. 37 0
      src/utils/index.ts
  56. 36 0
      tsconfig.json
  57. 69 0
      vite.config.ts

+ 14 - 0
.gitignore

@@ -0,0 +1,14 @@
+# 系统文件
+.DS_Store
+*.rar
+*.zip
+
+# 编辑器配置
+.vscode/
+.idea/
+
+# 项目依赖
+node_modules
+
+# 打包文件
+/build

+ 36 - 0
README.md

@@ -0,0 +1,36 @@
+##  基础运行环境
+01. `node 18.15.0`
+02. `npm 9.5.0`
+
+##  本地启动项目
+01. `npm ci`
+02. `npm run *start`
+
+##  服务构建项目
+01. `npm ci`
+02. `npm run *build`
+
+##  技术栈
+01. 框架——React@v18  
+02. 路由——React-Router-Dom@v7  
+03. 状态管理——Mobx@v6  
+04. UI组件库——Ant-Design@v5  
+05. 语法——TypeScript Less  
+06. 网络——Axios  
+07. 日期——Day.js  
+08. 打包工具——Vite@v6  
+
+##  文件结构
+src                资源文件  
+|-- apis           网络请求  
+|-- assets         静态资源  
+|-- components     全局组件  
+|-- pages          页面目录  
+|-- style          全局样式  
+|-- typings        类 型 库  
+|-- utils          通用方法  
+|-- App            根 组 件  
+|-- LocalStorage  本地存储  
+|-- main          入口文件  
+|-- router        全局路由  
+vite.config        打包配置  

+ 8 - 0
env/.env.development

@@ -0,0 +1,8 @@
+# 开发环境
+VITE_ENV = 'development'
+
+# Api地址
+VITE_API_URL = 'http://192.168.1.10:8080'
+
+# WebSocket地址
+VITE_WEBSOCKET_URL = 'ws://192.168.1.10:8080/ws'

+ 8 - 0
env/.env.production

@@ -0,0 +1,8 @@
+# 生产环境
+VITE_ENV = 'production'
+
+# Api地址
+VITE_API_URL = 'https://www.baidu.com'
+
+# WebSocket地址
+VITE_WEBSOCKET_URL = 'wss://www.baidu.com/wss'

+ 17 - 0
index.html

@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+  <meta charset="UTF-8" />
+  <meta name="renderer" content="webkit" />
+  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+  <link rel="icon" href="/src/assets/public/logo.png" />
+  <title>建科•小智</title>
+</head>
+
+<body>
+  <div id="root"></div>
+  <script type="module" src="/src/main.tsx"></script>
+</body>
+
+</html>

+ 2983 - 0
package-lock.json

@@ -0,0 +1,2983 @@
+{
+  "name": "chat-admin-web",
+  "version": "1.0.0",
+  "lockfileVersion": 3,
+  "requires": true,
+  "packages": {
+    "": {
+      "name": "chat-admin-web",
+      "version": "1.0.0",
+      "license": "ISC",
+      "dependencies": {
+        "antd": "^5.22.0",
+        "axios": "^1.7.0",
+        "dayjs": "^1.11.0",
+        "mobx": "^6.13.0",
+        "mobx-react": "^9.2.0",
+        "react": "^18.2.0",
+        "react-dom": "^18.2.0",
+        "react-router-dom": "^7.1.0"
+      },
+      "devDependencies": {
+        "@types/node": "^22.0.0",
+        "@types/react": "^18.2.0",
+        "@types/react-dom": "^18.2.0",
+        "@vitejs/plugin-react": "^4.3.0",
+        "less": "^4.2.0",
+        "typescript": "^5.7.0",
+        "vite": "^6.0.0"
+      }
+    },
+    "node_modules/@ampproject/remapping": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmmirror.com/@ampproject/remapping/-/remapping-2.3.0.tgz",
+      "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
+      "dev": true,
+      "dependencies": {
+        "@jridgewell/gen-mapping": "^0.3.5",
+        "@jridgewell/trace-mapping": "^0.3.24"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@ant-design/colors": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmmirror.com/@ant-design/colors/-/colors-7.1.0.tgz",
+      "integrity": "sha512-MMoDGWn1y9LdQJQSHiCC20x3uZ3CwQnv9QMz6pCmJOrqdgM9YxsoVVY0wtrdXbmfSgnV0KNk6zi09NAhMR2jvg==",
+      "dependencies": {
+        "@ctrl/tinycolor": "^3.6.1"
+      }
+    },
+    "node_modules/@ant-design/cssinjs": {
+      "version": "1.22.1",
+      "resolved": "https://registry.npmmirror.com/@ant-design/cssinjs/-/cssinjs-1.22.1.tgz",
+      "integrity": "sha512-SLuXM4wiEE1blOx94iXrkOgseMZHzdr4ngdFu3VVDq6AOWh7rlwqTkMAtJho3EsBF6x/eUGOtK53VZXGQG7+sQ==",
+      "dependencies": {
+        "@babel/runtime": "^7.11.1",
+        "@emotion/hash": "^0.8.0",
+        "@emotion/unitless": "^0.7.5",
+        "classnames": "^2.3.1",
+        "csstype": "^3.1.3",
+        "rc-util": "^5.35.0",
+        "stylis": "^4.3.4"
+      },
+      "peerDependencies": {
+        "react": ">=16.0.0",
+        "react-dom": ">=16.0.0"
+      }
+    },
+    "node_modules/@ant-design/cssinjs-utils": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmmirror.com/@ant-design/cssinjs-utils/-/cssinjs-utils-1.1.3.tgz",
+      "integrity": "sha512-nOoQMLW1l+xR1Co8NFVYiP8pZp3VjIIzqV6D6ShYF2ljtdwWJn5WSsH+7kvCktXL/yhEtWURKOfH5Xz/gzlwsg==",
+      "dependencies": {
+        "@ant-design/cssinjs": "^1.21.0",
+        "@babel/runtime": "^7.23.2",
+        "rc-util": "^5.38.0"
+      },
+      "peerDependencies": {
+        "react": ">=16.9.0",
+        "react-dom": ">=16.9.0"
+      }
+    },
+    "node_modules/@ant-design/fast-color": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmmirror.com/@ant-design/fast-color/-/fast-color-2.0.6.tgz",
+      "integrity": "sha512-y2217gk4NqL35giHl72o6Zzqji9O7vHh9YmhUVkPtAOpoTCH4uWxo/pr4VE8t0+ChEPs0qo4eJRC5Q1eXWo3vA==",
+      "dependencies": {
+        "@babel/runtime": "^7.24.7"
+      },
+      "engines": {
+        "node": ">=8.x"
+      }
+    },
+    "node_modules/@ant-design/icons": {
+      "version": "5.5.2",
+      "resolved": "https://registry.npmmirror.com/@ant-design/icons/-/icons-5.5.2.tgz",
+      "integrity": "sha512-xc53rjVBl9v2BqFxUjZGti/RfdDeA8/6KYglmInM2PNqSXc/WfuGDTifJI/ZsokJK0aeKvOIbXc9y2g8ILAhEA==",
+      "dependencies": {
+        "@ant-design/colors": "^7.0.0",
+        "@ant-design/icons-svg": "^4.4.0",
+        "@babel/runtime": "^7.24.8",
+        "classnames": "^2.2.6",
+        "rc-util": "^5.31.1"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "peerDependencies": {
+        "react": ">=16.0.0",
+        "react-dom": ">=16.0.0"
+      }
+    },
+    "node_modules/@ant-design/icons-svg": {
+      "version": "4.4.2",
+      "resolved": "https://registry.npmmirror.com/@ant-design/icons-svg/-/icons-svg-4.4.2.tgz",
+      "integrity": "sha512-vHbT+zJEVzllwP+CM+ul7reTEfBR0vgxFe7+lREAsAA7YGsYpboiq2sQNeQeRvh09GfQgs/GyFEvZpJ9cLXpXA=="
+    },
+    "node_modules/@ant-design/react-slick": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/@ant-design/react-slick/-/react-slick-1.1.2.tgz",
+      "integrity": "sha512-EzlvzE6xQUBrZuuhSAFTdsr4P2bBBHGZwKFemEfq8gIGyIQCxalYfZW/T2ORbtQx5rU69o+WycP3exY/7T1hGA==",
+      "dependencies": {
+        "@babel/runtime": "^7.10.4",
+        "classnames": "^2.2.5",
+        "json2mq": "^0.2.0",
+        "resize-observer-polyfill": "^1.5.1",
+        "throttle-debounce": "^5.0.0"
+      },
+      "peerDependencies": {
+        "react": ">=16.9.0"
+      }
+    },
+    "node_modules/@babel/code-frame": {
+      "version": "7.26.2",
+      "resolved": "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.26.2.tgz",
+      "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-validator-identifier": "^7.25.9",
+        "js-tokens": "^4.0.0",
+        "picocolors": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/compat-data": {
+      "version": "7.26.3",
+      "resolved": "https://registry.npmmirror.com/@babel/compat-data/-/compat-data-7.26.3.tgz",
+      "integrity": "sha512-nHIxvKPniQXpmQLb0vhY3VaFb3S0YrTAwpOWJZh1wn3oJPjJk9Asva204PsBdmAE8vpzfHudT8DB0scYvy9q0g==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/core": {
+      "version": "7.26.0",
+      "resolved": "https://registry.npmmirror.com/@babel/core/-/core-7.26.0.tgz",
+      "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==",
+      "dev": true,
+      "dependencies": {
+        "@ampproject/remapping": "^2.2.0",
+        "@babel/code-frame": "^7.26.0",
+        "@babel/generator": "^7.26.0",
+        "@babel/helper-compilation-targets": "^7.25.9",
+        "@babel/helper-module-transforms": "^7.26.0",
+        "@babel/helpers": "^7.26.0",
+        "@babel/parser": "^7.26.0",
+        "@babel/template": "^7.25.9",
+        "@babel/traverse": "^7.25.9",
+        "@babel/types": "^7.26.0",
+        "convert-source-map": "^2.0.0",
+        "debug": "^4.1.0",
+        "gensync": "^1.0.0-beta.2",
+        "json5": "^2.2.3",
+        "semver": "^6.3.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/babel"
+      }
+    },
+    "node_modules/@babel/generator": {
+      "version": "7.26.3",
+      "resolved": "https://registry.npmmirror.com/@babel/generator/-/generator-7.26.3.tgz",
+      "integrity": "sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==",
+      "dev": true,
+      "dependencies": {
+        "@babel/parser": "^7.26.3",
+        "@babel/types": "^7.26.3",
+        "@jridgewell/gen-mapping": "^0.3.5",
+        "@jridgewell/trace-mapping": "^0.3.25",
+        "jsesc": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-compilation-targets": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz",
+      "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==",
+      "dev": true,
+      "dependencies": {
+        "@babel/compat-data": "^7.25.9",
+        "@babel/helper-validator-option": "^7.25.9",
+        "browserslist": "^4.24.0",
+        "lru-cache": "^5.1.1",
+        "semver": "^6.3.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-module-imports": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz",
+      "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==",
+      "dev": true,
+      "dependencies": {
+        "@babel/traverse": "^7.25.9",
+        "@babel/types": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-module-transforms": {
+      "version": "7.26.0",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz",
+      "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-module-imports": "^7.25.9",
+        "@babel/helper-validator-identifier": "^7.25.9",
+        "@babel/traverse": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/helper-plugin-utils": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz",
+      "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-string-parser": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz",
+      "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-validator-identifier": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
+      "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-validator-option": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz",
+      "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helpers": {
+      "version": "7.26.0",
+      "resolved": "https://registry.npmmirror.com/@babel/helpers/-/helpers-7.26.0.tgz",
+      "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==",
+      "dev": true,
+      "dependencies": {
+        "@babel/template": "^7.25.9",
+        "@babel/types": "^7.26.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/parser": {
+      "version": "7.26.3",
+      "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.26.3.tgz",
+      "integrity": "sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/types": "^7.26.3"
+      },
+      "bin": {
+        "parser": "bin/babel-parser.js"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-react-jsx-self": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz",
+      "integrity": "sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-react-jsx-source": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.9.tgz",
+      "integrity": "sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/runtime": {
+      "version": "7.26.0",
+      "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.26.0.tgz",
+      "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==",
+      "dependencies": {
+        "regenerator-runtime": "^0.14.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/template": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/template/-/template-7.25.9.tgz",
+      "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==",
+      "dev": true,
+      "dependencies": {
+        "@babel/code-frame": "^7.25.9",
+        "@babel/parser": "^7.25.9",
+        "@babel/types": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/traverse": {
+      "version": "7.26.4",
+      "resolved": "https://registry.npmmirror.com/@babel/traverse/-/traverse-7.26.4.tgz",
+      "integrity": "sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==",
+      "dev": true,
+      "dependencies": {
+        "@babel/code-frame": "^7.26.2",
+        "@babel/generator": "^7.26.3",
+        "@babel/parser": "^7.26.3",
+        "@babel/template": "^7.25.9",
+        "@babel/types": "^7.26.3",
+        "debug": "^4.3.1",
+        "globals": "^11.1.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/types": {
+      "version": "7.26.3",
+      "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.26.3.tgz",
+      "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-string-parser": "^7.25.9",
+        "@babel/helper-validator-identifier": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@ctrl/tinycolor": {
+      "version": "3.6.1",
+      "resolved": "https://registry.npmmirror.com/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz",
+      "integrity": "sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==",
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/@emotion/hash": {
+      "version": "0.8.0",
+      "resolved": "https://registry.npmmirror.com/@emotion/hash/-/hash-0.8.0.tgz",
+      "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow=="
+    },
+    "node_modules/@emotion/unitless": {
+      "version": "0.7.5",
+      "resolved": "https://registry.npmmirror.com/@emotion/unitless/-/unitless-0.7.5.tgz",
+      "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg=="
+    },
+    "node_modules/@esbuild/aix-ppc64": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz",
+      "integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==",
+      "cpu": [
+        "ppc64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "aix"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/android-arm": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.24.2.tgz",
+      "integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/android-arm64": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz",
+      "integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/android-x64": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.24.2.tgz",
+      "integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/darwin-arm64": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz",
+      "integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/darwin-x64": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz",
+      "integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/freebsd-arm64": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz",
+      "integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/freebsd-x64": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz",
+      "integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/linux-arm": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz",
+      "integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/linux-arm64": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz",
+      "integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/linux-ia32": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz",
+      "integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/linux-loong64": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz",
+      "integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==",
+      "cpu": [
+        "loong64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/linux-mips64el": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz",
+      "integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==",
+      "cpu": [
+        "mips64el"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/linux-ppc64": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz",
+      "integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==",
+      "cpu": [
+        "ppc64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/linux-riscv64": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz",
+      "integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==",
+      "cpu": [
+        "riscv64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/linux-s390x": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz",
+      "integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==",
+      "cpu": [
+        "s390x"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/linux-x64": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz",
+      "integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/netbsd-arm64": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz",
+      "integrity": "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "netbsd"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/netbsd-x64": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz",
+      "integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "netbsd"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/openbsd-arm64": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz",
+      "integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "openbsd"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/openbsd-x64": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz",
+      "integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "openbsd"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/sunos-x64": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz",
+      "integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "sunos"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/win32-arm64": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz",
+      "integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/win32-ia32": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz",
+      "integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/win32-x64": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz",
+      "integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@jridgewell/gen-mapping": {
+      "version": "0.3.8",
+      "resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
+      "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==",
+      "dev": true,
+      "dependencies": {
+        "@jridgewell/set-array": "^1.2.1",
+        "@jridgewell/sourcemap-codec": "^1.4.10",
+        "@jridgewell/trace-mapping": "^0.3.24"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@jridgewell/resolve-uri": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+      "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@jridgewell/set-array": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmmirror.com/@jridgewell/set-array/-/set-array-1.2.1.tgz",
+      "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@jridgewell/sourcemap-codec": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
+      "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
+      "dev": true
+    },
+    "node_modules/@jridgewell/trace-mapping": {
+      "version": "0.3.25",
+      "resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
+      "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
+      "dev": true,
+      "dependencies": {
+        "@jridgewell/resolve-uri": "^3.1.0",
+        "@jridgewell/sourcemap-codec": "^1.4.14"
+      }
+    },
+    "node_modules/@rc-component/async-validator": {
+      "version": "5.0.4",
+      "resolved": "https://registry.npmmirror.com/@rc-component/async-validator/-/async-validator-5.0.4.tgz",
+      "integrity": "sha512-qgGdcVIF604M9EqjNF0hbUTz42bz/RDtxWdWuU5EQe3hi7M8ob54B6B35rOsvX5eSvIHIzT9iH1R3n+hk3CGfg==",
+      "dependencies": {
+        "@babel/runtime": "^7.24.4"
+      },
+      "engines": {
+        "node": ">=14.x"
+      }
+    },
+    "node_modules/@rc-component/color-picker": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/@rc-component/color-picker/-/color-picker-2.0.1.tgz",
+      "integrity": "sha512-WcZYwAThV/b2GISQ8F+7650r5ZZJ043E57aVBFkQ+kSY4C6wdofXgB0hBx+GPGpIU0Z81eETNoDUJMr7oy/P8Q==",
+      "dependencies": {
+        "@ant-design/fast-color": "^2.0.6",
+        "@babel/runtime": "^7.23.6",
+        "classnames": "^2.2.6",
+        "rc-util": "^5.38.1"
+      },
+      "peerDependencies": {
+        "react": ">=16.9.0",
+        "react-dom": ">=16.9.0"
+      }
+    },
+    "node_modules/@rc-component/context": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmmirror.com/@rc-component/context/-/context-1.4.0.tgz",
+      "integrity": "sha512-kFcNxg9oLRMoL3qki0OMxK+7g5mypjgaaJp/pkOis/6rVxma9nJBF/8kCIuTYHUQNr0ii7MxqE33wirPZLJQ2w==",
+      "dependencies": {
+        "@babel/runtime": "^7.10.1",
+        "rc-util": "^5.27.0"
+      },
+      "peerDependencies": {
+        "react": ">=16.9.0",
+        "react-dom": ">=16.9.0"
+      }
+    },
+    "node_modules/@rc-component/mini-decimal": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/@rc-component/mini-decimal/-/mini-decimal-1.1.0.tgz",
+      "integrity": "sha512-jS4E7T9Li2GuYwI6PyiVXmxTiM6b07rlD9Ge8uGZSCz3WlzcG5ZK7g5bbuKNeZ9pgUuPK/5guV781ujdVpm4HQ==",
+      "dependencies": {
+        "@babel/runtime": "^7.18.0"
+      },
+      "engines": {
+        "node": ">=8.x"
+      }
+    },
+    "node_modules/@rc-component/mutate-observer": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/@rc-component/mutate-observer/-/mutate-observer-1.1.0.tgz",
+      "integrity": "sha512-QjrOsDXQusNwGZPf4/qRQasg7UFEj06XiCJ8iuiq/Io7CrHrgVi6Uuetw60WAMG1799v+aM8kyc+1L/GBbHSlw==",
+      "dependencies": {
+        "@babel/runtime": "^7.18.0",
+        "classnames": "^2.3.2",
+        "rc-util": "^5.24.4"
+      },
+      "engines": {
+        "node": ">=8.x"
+      },
+      "peerDependencies": {
+        "react": ">=16.9.0",
+        "react-dom": ">=16.9.0"
+      }
+    },
+    "node_modules/@rc-component/portal": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/@rc-component/portal/-/portal-1.1.2.tgz",
+      "integrity": "sha512-6f813C0IsasTZms08kfA8kPAGxbbkYToa8ALaiDIGGECU4i9hj8Plgbx0sNJDrey3EtHO30hmdaxtT0138xZcg==",
+      "dependencies": {
+        "@babel/runtime": "^7.18.0",
+        "classnames": "^2.3.2",
+        "rc-util": "^5.24.4"
+      },
+      "engines": {
+        "node": ">=8.x"
+      },
+      "peerDependencies": {
+        "react": ">=16.9.0",
+        "react-dom": ">=16.9.0"
+      }
+    },
+    "node_modules/@rc-component/qrcode": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/@rc-component/qrcode/-/qrcode-1.0.0.tgz",
+      "integrity": "sha512-L+rZ4HXP2sJ1gHMGHjsg9jlYBX/SLN2D6OxP9Zn3qgtpMWtO2vUfxVFwiogHpAIqs54FnALxraUy/BCO1yRIgg==",
+      "dependencies": {
+        "@babel/runtime": "^7.24.7",
+        "classnames": "^2.3.2",
+        "rc-util": "^5.38.0"
+      },
+      "engines": {
+        "node": ">=8.x"
+      },
+      "peerDependencies": {
+        "react": ">=16.9.0",
+        "react-dom": ">=16.9.0"
+      }
+    },
+    "node_modules/@rc-component/tour": {
+      "version": "1.15.1",
+      "resolved": "https://registry.npmmirror.com/@rc-component/tour/-/tour-1.15.1.tgz",
+      "integrity": "sha512-Tr2t7J1DKZUpfJuDZWHxyxWpfmj8EZrqSgyMZ+BCdvKZ6r1UDsfU46M/iWAAFBy961Ssfom2kv5f3UcjIL2CmQ==",
+      "dependencies": {
+        "@babel/runtime": "^7.18.0",
+        "@rc-component/portal": "^1.0.0-9",
+        "@rc-component/trigger": "^2.0.0",
+        "classnames": "^2.3.2",
+        "rc-util": "^5.24.4"
+      },
+      "engines": {
+        "node": ">=8.x"
+      },
+      "peerDependencies": {
+        "react": ">=16.9.0",
+        "react-dom": ">=16.9.0"
+      }
+    },
+    "node_modules/@rc-component/trigger": {
+      "version": "2.2.6",
+      "resolved": "https://registry.npmmirror.com/@rc-component/trigger/-/trigger-2.2.6.tgz",
+      "integrity": "sha512-/9zuTnWwhQ3S3WT1T8BubuFTT46kvnXgaERR9f4BTKyn61/wpf/BvbImzYBubzJibU707FxwbKszLlHjcLiv1Q==",
+      "dependencies": {
+        "@babel/runtime": "^7.23.2",
+        "@rc-component/portal": "^1.1.0",
+        "classnames": "^2.3.2",
+        "rc-motion": "^2.0.0",
+        "rc-resize-observer": "^1.3.1",
+        "rc-util": "^5.44.0"
+      },
+      "engines": {
+        "node": ">=8.x"
+      },
+      "peerDependencies": {
+        "react": ">=16.9.0",
+        "react-dom": ">=16.9.0"
+      }
+    },
+    "node_modules/@rollup/rollup-android-arm-eabi": {
+      "version": "4.29.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.29.1.tgz",
+      "integrity": "sha512-ssKhA8RNltTZLpG6/QNkCSge+7mBQGUqJRisZ2MDQcEGaK93QESEgWK2iOpIDZ7k9zPVkG5AS3ksvD5ZWxmItw==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "android"
+      ]
+    },
+    "node_modules/@rollup/rollup-android-arm64": {
+      "version": "4.29.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.29.1.tgz",
+      "integrity": "sha512-CaRfrV0cd+NIIcVVN/jx+hVLN+VRqnuzLRmfmlzpOzB87ajixsN/+9L5xNmkaUUvEbI5BmIKS+XTwXsHEb65Ew==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "android"
+      ]
+    },
+    "node_modules/@rollup/rollup-darwin-arm64": {
+      "version": "4.29.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.29.1.tgz",
+      "integrity": "sha512-2ORr7T31Y0Mnk6qNuwtyNmy14MunTAMx06VAPI6/Ju52W10zk1i7i5U3vlDRWjhOI5quBcrvhkCHyF76bI7kEw==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ]
+    },
+    "node_modules/@rollup/rollup-darwin-x64": {
+      "version": "4.29.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.29.1.tgz",
+      "integrity": "sha512-j/Ej1oanzPjmN0tirRd5K2/nncAhS9W6ICzgxV+9Y5ZsP0hiGhHJXZ2JQ53iSSjj8m6cRY6oB1GMzNn2EUt6Ng==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ]
+    },
+    "node_modules/@rollup/rollup-freebsd-arm64": {
+      "version": "4.29.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.29.1.tgz",
+      "integrity": "sha512-91C//G6Dm/cv724tpt7nTyP+JdN12iqeXGFM1SqnljCmi5yTXriH7B1r8AD9dAZByHpKAumqP1Qy2vVNIdLZqw==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "freebsd"
+      ]
+    },
+    "node_modules/@rollup/rollup-freebsd-x64": {
+      "version": "4.29.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.29.1.tgz",
+      "integrity": "sha512-hEioiEQ9Dec2nIRoeHUP6hr1PSkXzQaCUyqBDQ9I9ik4gCXQZjJMIVzoNLBRGet+hIUb3CISMh9KXuCcWVW/8w==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "freebsd"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+      "version": "4.29.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.29.1.tgz",
+      "integrity": "sha512-Py5vFd5HWYN9zxBv3WMrLAXY3yYJ6Q/aVERoeUFwiDGiMOWsMs7FokXihSOaT/PMWUty/Pj60XDQndK3eAfE6A==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+      "version": "4.29.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.29.1.tgz",
+      "integrity": "sha512-RiWpGgbayf7LUcuSNIbahr0ys2YnEERD4gYdISA06wa0i8RALrnzflh9Wxii7zQJEB2/Eh74dX4y/sHKLWp5uQ==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-arm64-gnu": {
+      "version": "4.29.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.29.1.tgz",
+      "integrity": "sha512-Z80O+taYxTQITWMjm/YqNoe9d10OX6kDh8X5/rFCMuPqsKsSyDilvfg+vd3iXIqtfmp+cnfL1UrYirkaF8SBZA==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-arm64-musl": {
+      "version": "4.29.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.29.1.tgz",
+      "integrity": "sha512-fOHRtF9gahwJk3QVp01a/GqS4hBEZCV1oKglVVq13kcK3NeVlS4BwIFzOHDbmKzt3i0OuHG4zfRP0YoG5OF/rA==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
+      "version": "4.29.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.29.1.tgz",
+      "integrity": "sha512-5a7q3tnlbcg0OodyxcAdrrCxFi0DgXJSoOuidFUzHZ2GixZXQs6Tc3CHmlvqKAmOs5eRde+JJxeIf9DonkmYkw==",
+      "cpu": [
+        "loong64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
+      "version": "4.29.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.29.1.tgz",
+      "integrity": "sha512-9b4Mg5Yfz6mRnlSPIdROcfw1BU22FQxmfjlp/CShWwO3LilKQuMISMTtAu/bxmmrE6A902W2cZJuzx8+gJ8e9w==",
+      "cpu": [
+        "ppc64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+      "version": "4.29.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.29.1.tgz",
+      "integrity": "sha512-G5pn0NChlbRM8OJWpJFMX4/i8OEU538uiSv0P6roZcbpe/WfhEO+AT8SHVKfp8qhDQzaz7Q+1/ixMy7hBRidnQ==",
+      "cpu": [
+        "riscv64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-s390x-gnu": {
+      "version": "4.29.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.29.1.tgz",
+      "integrity": "sha512-WM9lIkNdkhVwiArmLxFXpWndFGuOka4oJOZh8EP3Vb8q5lzdSCBuhjavJsw68Q9AKDGeOOIHYzYm4ZFvmWez5g==",
+      "cpu": [
+        "s390x"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-x64-gnu": {
+      "version": "4.29.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.29.1.tgz",
+      "integrity": "sha512-87xYCwb0cPGZFoGiErT1eDcssByaLX4fc0z2nRM6eMtV9njAfEE6OW3UniAoDhX4Iq5xQVpE6qO9aJbCFumKYQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-x64-musl": {
+      "version": "4.29.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.29.1.tgz",
+      "integrity": "sha512-xufkSNppNOdVRCEC4WKvlR1FBDyqCSCpQeMMgv9ZyXqqtKBfkw1yfGMTUTs9Qsl6WQbJnsGboWCp7pJGkeMhKA==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-win32-arm64-msvc": {
+      "version": "4.29.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.29.1.tgz",
+      "integrity": "sha512-F2OiJ42m77lSkizZQLuC+jiZ2cgueWQL5YC9tjo3AgaEw+KJmVxHGSyQfDUoYR9cci0lAywv2Clmckzulcq6ig==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "win32"
+      ]
+    },
+    "node_modules/@rollup/rollup-win32-ia32-msvc": {
+      "version": "4.29.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.29.1.tgz",
+      "integrity": "sha512-rYRe5S0FcjlOBZQHgbTKNrqxCBUmgDJem/VQTCcTnA2KCabYSWQDrytOzX7avb79cAAweNmMUb/Zw18RNd4mng==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "win32"
+      ]
+    },
+    "node_modules/@rollup/rollup-win32-x64-msvc": {
+      "version": "4.29.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.29.1.tgz",
+      "integrity": "sha512-+10CMg9vt1MoHj6x1pxyjPSMjHTIlqs8/tBztXvPAx24SKs9jwVnKqHJumlH/IzhaPUaj3T6T6wfZr8okdXaIg==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "win32"
+      ]
+    },
+    "node_modules/@types/babel__core": {
+      "version": "7.20.5",
+      "resolved": "https://registry.npmmirror.com/@types/babel__core/-/babel__core-7.20.5.tgz",
+      "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/parser": "^7.20.7",
+        "@babel/types": "^7.20.7",
+        "@types/babel__generator": "*",
+        "@types/babel__template": "*",
+        "@types/babel__traverse": "*"
+      }
+    },
+    "node_modules/@types/babel__generator": {
+      "version": "7.6.8",
+      "resolved": "https://registry.npmmirror.com/@types/babel__generator/-/babel__generator-7.6.8.tgz",
+      "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==",
+      "dev": true,
+      "dependencies": {
+        "@babel/types": "^7.0.0"
+      }
+    },
+    "node_modules/@types/babel__template": {
+      "version": "7.4.4",
+      "resolved": "https://registry.npmmirror.com/@types/babel__template/-/babel__template-7.4.4.tgz",
+      "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
+      "dev": true,
+      "dependencies": {
+        "@babel/parser": "^7.1.0",
+        "@babel/types": "^7.0.0"
+      }
+    },
+    "node_modules/@types/babel__traverse": {
+      "version": "7.20.6",
+      "resolved": "https://registry.npmmirror.com/@types/babel__traverse/-/babel__traverse-7.20.6.tgz",
+      "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==",
+      "dev": true,
+      "dependencies": {
+        "@babel/types": "^7.20.7"
+      }
+    },
+    "node_modules/@types/cookie": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmmirror.com/@types/cookie/-/cookie-0.6.0.tgz",
+      "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA=="
+    },
+    "node_modules/@types/estree": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.6.tgz",
+      "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
+      "dev": true
+    },
+    "node_modules/@types/node": {
+      "version": "22.10.2",
+      "resolved": "https://registry.npmmirror.com/@types/node/-/node-22.10.2.tgz",
+      "integrity": "sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==",
+      "dev": true,
+      "dependencies": {
+        "undici-types": "~6.20.0"
+      }
+    },
+    "node_modules/@types/prop-types": {
+      "version": "15.7.14",
+      "resolved": "https://registry.npmmirror.com/@types/prop-types/-/prop-types-15.7.14.tgz",
+      "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==",
+      "dev": true
+    },
+    "node_modules/@types/react": {
+      "version": "18.3.18",
+      "resolved": "https://registry.npmmirror.com/@types/react/-/react-18.3.18.tgz",
+      "integrity": "sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/prop-types": "*",
+        "csstype": "^3.0.2"
+      }
+    },
+    "node_modules/@types/react-dom": {
+      "version": "18.3.5",
+      "resolved": "https://registry.npmmirror.com/@types/react-dom/-/react-dom-18.3.5.tgz",
+      "integrity": "sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q==",
+      "dev": true,
+      "peerDependencies": {
+        "@types/react": "^18.0.0"
+      }
+    },
+    "node_modules/@vitejs/plugin-react": {
+      "version": "4.3.4",
+      "resolved": "https://registry.npmmirror.com/@vitejs/plugin-react/-/plugin-react-4.3.4.tgz",
+      "integrity": "sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==",
+      "dev": true,
+      "dependencies": {
+        "@babel/core": "^7.26.0",
+        "@babel/plugin-transform-react-jsx-self": "^7.25.9",
+        "@babel/plugin-transform-react-jsx-source": "^7.25.9",
+        "@types/babel__core": "^7.20.5",
+        "react-refresh": "^0.14.2"
+      },
+      "engines": {
+        "node": "^14.18.0 || >=16.0.0"
+      },
+      "peerDependencies": {
+        "vite": "^4.2.0 || ^5.0.0 || ^6.0.0"
+      }
+    },
+    "node_modules/antd": {
+      "version": "5.22.7",
+      "resolved": "https://registry.npmmirror.com/antd/-/antd-5.22.7.tgz",
+      "integrity": "sha512-koT5QMliDgXc21yNcs4Uyuq6TeB5AJbzGZ2qjNExzE7Tjr8yYIX6sJsQfunsEV80wC1mpF7m9ldKuNj+PafcFA==",
+      "dependencies": {
+        "@ant-design/colors": "^7.1.0",
+        "@ant-design/cssinjs": "^1.21.1",
+        "@ant-design/cssinjs-utils": "^1.1.3",
+        "@ant-design/icons": "^5.5.2",
+        "@ant-design/react-slick": "~1.1.2",
+        "@babel/runtime": "^7.25.7",
+        "@ctrl/tinycolor": "^3.6.1",
+        "@rc-component/color-picker": "~2.0.1",
+        "@rc-component/mutate-observer": "^1.1.0",
+        "@rc-component/qrcode": "~1.0.0",
+        "@rc-component/tour": "~1.15.1",
+        "@rc-component/trigger": "^2.2.6",
+        "classnames": "^2.5.1",
+        "copy-to-clipboard": "^3.3.3",
+        "dayjs": "^1.11.11",
+        "rc-cascader": "~3.30.0",
+        "rc-checkbox": "~3.3.0",
+        "rc-collapse": "~3.9.0",
+        "rc-dialog": "~9.6.0",
+        "rc-drawer": "~7.2.0",
+        "rc-dropdown": "~4.2.1",
+        "rc-field-form": "~2.7.0",
+        "rc-image": "~7.11.0",
+        "rc-input": "~1.6.4",
+        "rc-input-number": "~9.3.0",
+        "rc-mentions": "~2.17.0",
+        "rc-menu": "~9.16.0",
+        "rc-motion": "^2.9.5",
+        "rc-notification": "~5.6.2",
+        "rc-pagination": "~5.0.0",
+        "rc-picker": "~4.8.3",
+        "rc-progress": "~4.0.0",
+        "rc-rate": "~2.13.0",
+        "rc-resize-observer": "^1.4.3",
+        "rc-segmented": "~2.5.0",
+        "rc-select": "~14.16.4",
+        "rc-slider": "~11.1.7",
+        "rc-steps": "~6.0.1",
+        "rc-switch": "~4.1.0",
+        "rc-table": "~7.49.0",
+        "rc-tabs": "~15.4.0",
+        "rc-textarea": "~1.8.2",
+        "rc-tooltip": "~6.2.1",
+        "rc-tree": "~5.10.1",
+        "rc-tree-select": "~5.24.5",
+        "rc-upload": "~4.8.1",
+        "rc-util": "^5.44.3",
+        "scroll-into-view-if-needed": "^3.1.0",
+        "throttle-debounce": "^5.0.2"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/ant-design"
+      },
+      "peerDependencies": {
+        "react": ">=16.9.0",
+        "react-dom": ">=16.9.0"
+      }
+    },
+    "node_modules/asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
+    },
+    "node_modules/axios": {
+      "version": "1.7.9",
+      "resolved": "https://registry.npmmirror.com/axios/-/axios-1.7.9.tgz",
+      "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==",
+      "dependencies": {
+        "follow-redirects": "^1.15.6",
+        "form-data": "^4.0.0",
+        "proxy-from-env": "^1.1.0"
+      }
+    },
+    "node_modules/browserslist": {
+      "version": "4.24.3",
+      "resolved": "https://registry.npmmirror.com/browserslist/-/browserslist-4.24.3.tgz",
+      "integrity": "sha512-1CPmv8iobE2fyRMV97dAcMVegvvWKxmq94hkLiAkUGwKVTyDLw33K+ZxiFrREKmmps4rIw6grcCFCnTMSZ/YiA==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/browserslist"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/browserslist"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "dependencies": {
+        "caniuse-lite": "^1.0.30001688",
+        "electron-to-chromium": "^1.5.73",
+        "node-releases": "^2.0.19",
+        "update-browserslist-db": "^1.1.1"
+      },
+      "bin": {
+        "browserslist": "cli.js"
+      },
+      "engines": {
+        "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+      }
+    },
+    "node_modules/caniuse-lite": {
+      "version": "1.0.30001690",
+      "resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001690.tgz",
+      "integrity": "sha512-5ExiE3qQN6oF8Clf8ifIDcMRCRE/dMGcETG/XGMD8/XiXm6HXQgQTh1yZYLXXpSOsEUlJm1Xr7kGULZTuGtP/w==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/browserslist"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ]
+    },
+    "node_modules/classnames": {
+      "version": "2.5.1",
+      "resolved": "https://registry.npmmirror.com/classnames/-/classnames-2.5.1.tgz",
+      "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow=="
+    },
+    "node_modules/combined-stream": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz",
+      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+      "dependencies": {
+        "delayed-stream": "~1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/compute-scroll-into-view": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmmirror.com/compute-scroll-into-view/-/compute-scroll-into-view-3.1.0.tgz",
+      "integrity": "sha512-rj8l8pD4bJ1nx+dAkMhV1xB5RuZEyVysfxJqB1pRchh1KVvwOv9b7CGB8ZfjTImVv2oF+sYMUkMZq6Na5Ftmbg=="
+    },
+    "node_modules/convert-source-map": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-2.0.0.tgz",
+      "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+      "dev": true
+    },
+    "node_modules/cookie": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/cookie/-/cookie-1.0.2.tgz",
+      "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==",
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/copy-anything": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmmirror.com/copy-anything/-/copy-anything-2.0.6.tgz",
+      "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==",
+      "dev": true,
+      "dependencies": {
+        "is-what": "^3.14.1"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/mesqueeb"
+      }
+    },
+    "node_modules/copy-to-clipboard": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npmmirror.com/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz",
+      "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==",
+      "dependencies": {
+        "toggle-selection": "^1.0.6"
+      }
+    },
+    "node_modules/csstype": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz",
+      "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
+    },
+    "node_modules/dayjs": {
+      "version": "1.11.13",
+      "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.13.tgz",
+      "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg=="
+    },
+    "node_modules/debug": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.0.tgz",
+      "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
+      "dev": true,
+      "dependencies": {
+        "ms": "^2.1.3"
+      },
+      "engines": {
+        "node": ">=6.0"
+      },
+      "peerDependenciesMeta": {
+        "supports-color": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
+    "node_modules/electron-to-chromium": {
+      "version": "1.5.76",
+      "resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.5.76.tgz",
+      "integrity": "sha512-CjVQyG7n7Sr+eBXE86HIulnL5N8xZY1sgmOPGuq/F0Rr0FJq63lg0kEtOIDfZBk44FnDLf6FUJ+dsJcuiUDdDQ==",
+      "dev": true
+    },
+    "node_modules/errno": {
+      "version": "0.1.8",
+      "resolved": "https://registry.npmmirror.com/errno/-/errno-0.1.8.tgz",
+      "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "prr": "~1.0.1"
+      },
+      "bin": {
+        "errno": "cli.js"
+      }
+    },
+    "node_modules/esbuild": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.24.2.tgz",
+      "integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==",
+      "dev": true,
+      "hasInstallScript": true,
+      "bin": {
+        "esbuild": "bin/esbuild"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "optionalDependencies": {
+        "@esbuild/aix-ppc64": "0.24.2",
+        "@esbuild/android-arm": "0.24.2",
+        "@esbuild/android-arm64": "0.24.2",
+        "@esbuild/android-x64": "0.24.2",
+        "@esbuild/darwin-arm64": "0.24.2",
+        "@esbuild/darwin-x64": "0.24.2",
+        "@esbuild/freebsd-arm64": "0.24.2",
+        "@esbuild/freebsd-x64": "0.24.2",
+        "@esbuild/linux-arm": "0.24.2",
+        "@esbuild/linux-arm64": "0.24.2",
+        "@esbuild/linux-ia32": "0.24.2",
+        "@esbuild/linux-loong64": "0.24.2",
+        "@esbuild/linux-mips64el": "0.24.2",
+        "@esbuild/linux-ppc64": "0.24.2",
+        "@esbuild/linux-riscv64": "0.24.2",
+        "@esbuild/linux-s390x": "0.24.2",
+        "@esbuild/linux-x64": "0.24.2",
+        "@esbuild/netbsd-arm64": "0.24.2",
+        "@esbuild/netbsd-x64": "0.24.2",
+        "@esbuild/openbsd-arm64": "0.24.2",
+        "@esbuild/openbsd-x64": "0.24.2",
+        "@esbuild/sunos-x64": "0.24.2",
+        "@esbuild/win32-arm64": "0.24.2",
+        "@esbuild/win32-ia32": "0.24.2",
+        "@esbuild/win32-x64": "0.24.2"
+      }
+    },
+    "node_modules/escalade": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmmirror.com/escalade/-/escalade-3.2.0.tgz",
+      "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/follow-redirects": {
+      "version": "1.15.9",
+      "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.9.tgz",
+      "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
+      "funding": [
+        {
+          "type": "individual",
+          "url": "https://github.com/sponsors/RubenVerborgh"
+        }
+      ],
+      "engines": {
+        "node": ">=4.0"
+      },
+      "peerDependenciesMeta": {
+        "debug": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/form-data": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.1.tgz",
+      "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==",
+      "dependencies": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.8",
+        "mime-types": "^2.1.12"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/fsevents": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz",
+      "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+      "dev": true,
+      "hasInstallScript": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+      }
+    },
+    "node_modules/gensync": {
+      "version": "1.0.0-beta.2",
+      "resolved": "https://registry.npmmirror.com/gensync/-/gensync-1.0.0-beta.2.tgz",
+      "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/globals": {
+      "version": "11.12.0",
+      "resolved": "https://registry.npmmirror.com/globals/-/globals-11.12.0.tgz",
+      "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/graceful-fs": {
+      "version": "4.2.11",
+      "resolved": "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.11.tgz",
+      "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/iconv-lite": {
+      "version": "0.6.3",
+      "resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.6.3.tgz",
+      "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "safer-buffer": ">= 2.1.2 < 3.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/image-size": {
+      "version": "0.5.5",
+      "resolved": "https://registry.npmmirror.com/image-size/-/image-size-0.5.5.tgz",
+      "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==",
+      "dev": true,
+      "optional": true,
+      "bin": {
+        "image-size": "bin/image-size.js"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-what": {
+      "version": "3.14.1",
+      "resolved": "https://registry.npmmirror.com/is-what/-/is-what-3.14.1.tgz",
+      "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==",
+      "dev": true
+    },
+    "node_modules/js-tokens": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz",
+      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
+    },
+    "node_modules/jsesc": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmmirror.com/jsesc/-/jsesc-3.1.0.tgz",
+      "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
+      "dev": true,
+      "bin": {
+        "jsesc": "bin/jsesc"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/json2mq": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmmirror.com/json2mq/-/json2mq-0.2.0.tgz",
+      "integrity": "sha512-SzoRg7ux5DWTII9J2qkrZrqV1gt+rTaoufMxEzXbS26Uid0NwaJd123HcoB80TgubEppxxIGdNxCx50fEoEWQA==",
+      "dependencies": {
+        "string-convert": "^0.2.0"
+      }
+    },
+    "node_modules/json5": {
+      "version": "2.2.3",
+      "resolved": "https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz",
+      "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+      "dev": true,
+      "bin": {
+        "json5": "lib/cli.js"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/less": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmmirror.com/less/-/less-4.2.1.tgz",
+      "integrity": "sha512-CasaJidTIhWmjcqv0Uj5vccMI7pJgfD9lMkKtlnTHAdJdYK/7l8pM9tumLyJ0zhbD4KJLo/YvTj+xznQd5NBhg==",
+      "dev": true,
+      "dependencies": {
+        "copy-anything": "^2.0.1",
+        "parse-node-version": "^1.0.1",
+        "tslib": "^2.3.0"
+      },
+      "bin": {
+        "lessc": "bin/lessc"
+      },
+      "engines": {
+        "node": ">=6"
+      },
+      "optionalDependencies": {
+        "errno": "^0.1.1",
+        "graceful-fs": "^4.1.2",
+        "image-size": "~0.5.0",
+        "make-dir": "^2.1.0",
+        "mime": "^1.4.1",
+        "needle": "^3.1.0",
+        "source-map": "~0.6.0"
+      }
+    },
+    "node_modules/loose-envify": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmmirror.com/loose-envify/-/loose-envify-1.4.0.tgz",
+      "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+      "dependencies": {
+        "js-tokens": "^3.0.0 || ^4.0.0"
+      },
+      "bin": {
+        "loose-envify": "cli.js"
+      }
+    },
+    "node_modules/lru-cache": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz",
+      "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+      "dev": true,
+      "dependencies": {
+        "yallist": "^3.0.2"
+      }
+    },
+    "node_modules/make-dir": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/make-dir/-/make-dir-2.1.0.tgz",
+      "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "pify": "^4.0.1",
+        "semver": "^5.6.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/make-dir/node_modules/semver": {
+      "version": "5.7.2",
+      "resolved": "https://registry.npmmirror.com/semver/-/semver-5.7.2.tgz",
+      "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+      "dev": true,
+      "optional": true,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/mime": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmmirror.com/mime/-/mime-1.6.0.tgz",
+      "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+      "dev": true,
+      "optional": true,
+      "bin": {
+        "mime": "cli.js"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/mime-db": {
+      "version": "1.52.0",
+      "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
+      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/mime-types": {
+      "version": "2.1.35",
+      "resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz",
+      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+      "dependencies": {
+        "mime-db": "1.52.0"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/mobx": {
+      "version": "6.13.5",
+      "resolved": "https://registry.npmmirror.com/mobx/-/mobx-6.13.5.tgz",
+      "integrity": "sha512-/HTWzW2s8J1Gqt+WmUj5Y0mddZk+LInejADc79NJadrWla3rHzmRHki/mnEUH1AvOmbNTZ1BRbKxr8DSgfdjMA==",
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/mobx"
+      }
+    },
+    "node_modules/mobx-react": {
+      "version": "9.2.0",
+      "resolved": "https://registry.npmmirror.com/mobx-react/-/mobx-react-9.2.0.tgz",
+      "integrity": "sha512-dkGWCx+S0/1mfiuFfHRH8D9cplmwhxOV5CkXMp38u6rQGG2Pv3FWYztS0M7ncR6TyPRQKaTG/pnitInoYE9Vrw==",
+      "dependencies": {
+        "mobx-react-lite": "^4.1.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/mobx"
+      },
+      "peerDependencies": {
+        "mobx": "^6.9.0",
+        "react": "^16.8.0 || ^17 || ^18 || ^19"
+      },
+      "peerDependenciesMeta": {
+        "react-dom": {
+          "optional": true
+        },
+        "react-native": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/mobx-react-lite": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmmirror.com/mobx-react-lite/-/mobx-react-lite-4.1.0.tgz",
+      "integrity": "sha512-QEP10dpHHBeQNv1pks3WnHRCem2Zp636lq54M2nKO2Sarr13pL4u6diQXf65yzXUn0mkk18SyIDCm9UOJYTi1w==",
+      "dependencies": {
+        "use-sync-external-store": "^1.4.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/mobx"
+      },
+      "peerDependencies": {
+        "mobx": "^6.9.0",
+        "react": "^16.8.0 || ^17 || ^18 || ^19"
+      },
+      "peerDependenciesMeta": {
+        "react-dom": {
+          "optional": true
+        },
+        "react-native": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/ms": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz",
+      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+      "dev": true
+    },
+    "node_modules/nanoid": {
+      "version": "3.3.8",
+      "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.8.tgz",
+      "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "bin": {
+        "nanoid": "bin/nanoid.cjs"
+      },
+      "engines": {
+        "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+      }
+    },
+    "node_modules/needle": {
+      "version": "3.3.1",
+      "resolved": "https://registry.npmmirror.com/needle/-/needle-3.3.1.tgz",
+      "integrity": "sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "iconv-lite": "^0.6.3",
+        "sax": "^1.2.4"
+      },
+      "bin": {
+        "needle": "bin/needle"
+      },
+      "engines": {
+        "node": ">= 4.4.x"
+      }
+    },
+    "node_modules/node-releases": {
+      "version": "2.0.19",
+      "resolved": "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.19.tgz",
+      "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
+      "dev": true
+    },
+    "node_modules/parse-node-version": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/parse-node-version/-/parse-node-version-1.0.1.tgz",
+      "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
+    "node_modules/picocolors": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz",
+      "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+      "dev": true
+    },
+    "node_modules/pify": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmmirror.com/pify/-/pify-4.0.1.tgz",
+      "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/postcss": {
+      "version": "8.4.49",
+      "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.49.tgz",
+      "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/postcss/"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/postcss"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "dependencies": {
+        "nanoid": "^3.3.7",
+        "picocolors": "^1.1.1",
+        "source-map-js": "^1.2.1"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14"
+      }
+    },
+    "node_modules/proxy-from-env": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+      "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
+    },
+    "node_modules/prr": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/prr/-/prr-1.0.1.tgz",
+      "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/rc-cascader": {
+      "version": "3.30.0",
+      "resolved": "https://registry.npmmirror.com/rc-cascader/-/rc-cascader-3.30.0.tgz",
+      "integrity": "sha512-rrzSbk1Bdqbu+pDwiLCLHu72+lwX9BZ28+JKzoi0DWZ4N29QYFeip8Gctl33QVd2Xg3Rf14D3yAOG76ElJw16w==",
+      "dependencies": {
+        "@babel/runtime": "^7.25.7",
+        "classnames": "^2.3.1",
+        "rc-select": "~14.16.2",
+        "rc-tree": "~5.10.1",
+        "rc-util": "^5.43.0"
+      },
+      "peerDependencies": {
+        "react": ">=16.9.0",
+        "react-dom": ">=16.9.0"
+      }
+    },
+    "node_modules/rc-checkbox": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmmirror.com/rc-checkbox/-/rc-checkbox-3.3.0.tgz",
+      "integrity": "sha512-Ih3ZaAcoAiFKJjifzwsGiT/f/quIkxJoklW4yKGho14Olulwn8gN7hOBve0/WGDg5o/l/5mL0w7ff7/YGvefVw==",
+      "dependencies": {
+        "@babel/runtime": "^7.10.1",
+        "classnames": "^2.3.2",
+        "rc-util": "^5.25.2"
+      },
+      "peerDependencies": {
+        "react": ">=16.9.0",
+        "react-dom": ">=16.9.0"
+      }
+    },
+    "node_modules/rc-collapse": {
+      "version": "3.9.0",
+      "resolved": "https://registry.npmmirror.com/rc-collapse/-/rc-collapse-3.9.0.tgz",
+      "integrity": "sha512-swDdz4QZ4dFTo4RAUMLL50qP0EY62N2kvmk2We5xYdRwcRn8WcYtuetCJpwpaCbUfUt5+huLpVxhvmnK+PHrkA==",
+      "dependencies": {
+        "@babel/runtime": "^7.10.1",
+        "classnames": "2.x",
+        "rc-motion": "^2.3.4",
+        "rc-util": "^5.27.0"
+      },
+      "peerDependencies": {
+        "react": ">=16.9.0",
+        "react-dom": ">=16.9.0"
+      }
+    },
+    "node_modules/rc-dialog": {
+      "version": "9.6.0",
+      "resolved": "https://registry.npmmirror.com/rc-dialog/-/rc-dialog-9.6.0.tgz",
+      "integrity": "sha512-ApoVi9Z8PaCQg6FsUzS8yvBEQy0ZL2PkuvAgrmohPkN3okps5WZ5WQWPc1RNuiOKaAYv8B97ACdsFU5LizzCqg==",
+      "dependencies": {
+        "@babel/runtime": "^7.10.1",
+        "@rc-component/portal": "^1.0.0-8",
+        "classnames": "^2.2.6",
+        "rc-motion": "^2.3.0",
+        "rc-util": "^5.21.0"
+      },
+      "peerDependencies": {
+        "react": ">=16.9.0",
+        "react-dom": ">=16.9.0"
+      }
+    },
+    "node_modules/rc-drawer": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmmirror.com/rc-drawer/-/rc-drawer-7.2.0.tgz",
+      "integrity": "sha512-9lOQ7kBekEJRdEpScHvtmEtXnAsy+NGDXiRWc2ZVC7QXAazNVbeT4EraQKYwCME8BJLa8Bxqxvs5swwyOepRwg==",
+      "dependencies": {
+        "@babel/runtime": "^7.23.9",
+        "@rc-component/portal": "^1.1.1",
+        "classnames": "^2.2.6",
+        "rc-motion": "^2.6.1",
+        "rc-util": "^5.38.1"
+      },
+      "peerDependencies": {
+        "react": ">=16.9.0",
+        "react-dom": ">=16.9.0"
+      }
+    },
+    "node_modules/rc-dropdown": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmmirror.com/rc-dropdown/-/rc-dropdown-4.2.1.tgz",
+      "integrity": "sha512-YDAlXsPv3I1n42dv1JpdM7wJ+gSUBfeyPK59ZpBD9jQhK9jVuxpjj3NmWQHOBceA1zEPVX84T2wbdb2SD0UjmA==",
+      "dependencies": {
+        "@babel/runtime": "^7.18.3",
+        "@rc-component/trigger": "^2.0.0",
+        "classnames": "^2.2.6",
+        "rc-util": "^5.44.1"
+      },
+      "peerDependencies": {
+        "react": ">=16.11.0",
+        "react-dom": ">=16.11.0"
+      }
+    },
+    "node_modules/rc-field-form": {
+      "version": "2.7.0",
+      "resolved": "https://registry.npmmirror.com/rc-field-form/-/rc-field-form-2.7.0.tgz",
+      "integrity": "sha512-hgKsCay2taxzVnBPZl+1n4ZondsV78G++XVsMIJCAoioMjlMQR9YwAp7JZDIECzIu2Z66R+f4SFIRrO2DjDNAA==",
+      "dependencies": {
+        "@babel/runtime": "^7.18.0",
+        "@rc-component/async-validator": "^5.0.3",
+        "rc-util": "^5.32.2"
+      },
+      "engines": {
+        "node": ">=8.x"
+      },
+      "peerDependencies": {
+        "react": ">=16.9.0",
+        "react-dom": ">=16.9.0"
+      }
+    },
+    "node_modules/rc-image": {
+      "version": "7.11.0",
+      "resolved": "https://registry.npmmirror.com/rc-image/-/rc-image-7.11.0.tgz",
+      "integrity": "sha512-aZkTEZXqeqfPZtnSdNUnKQA0N/3MbgR7nUnZ+/4MfSFWPFHZau4p5r5ShaI0KPEMnNjv4kijSCFq/9wtJpwykw==",
+      "dependencies": {
+        "@babel/runtime": "^7.11.2",
+        "@rc-component/portal": "^1.0.2",
+        "classnames": "^2.2.6",
+        "rc-dialog": "~9.6.0",
+        "rc-motion": "^2.6.2",
+        "rc-util": "^5.34.1"
+      },
+      "peerDependencies": {
+        "react": ">=16.9.0",
+        "react-dom": ">=16.9.0"
+      }
+    },
+    "node_modules/rc-input": {
+      "version": "1.6.4",
+      "resolved": "https://registry.npmmirror.com/rc-input/-/rc-input-1.6.4.tgz",
+      "integrity": "sha512-lBZhfRD4NSAUW0zOKLUeI6GJuXkxeZYi0hr8VcJgJpyTNOvHw1ysrKWAHcEOAAHj7guxgmWYSi6xWrEdfrSAsA==",
+      "dependencies": {
+        "@babel/runtime": "^7.11.1",
+        "classnames": "^2.2.1",
+        "rc-util": "^5.18.1"
+      },
+      "peerDependencies": {
+        "react": ">=16.0.0",
+        "react-dom": ">=16.0.0"
+      }
+    },
+    "node_modules/rc-input-number": {
+      "version": "9.3.0",
+      "resolved": "https://registry.npmmirror.com/rc-input-number/-/rc-input-number-9.3.0.tgz",
+      "integrity": "sha512-JQ363ywqRyxwgVxpg2z2kja3CehTpYdqR7emJ/6yJjRdbvo+RvfE83fcpBCIJRq3zLp8SakmEXq60qzWyZ7Usw==",
+      "dependencies": {
+        "@babel/runtime": "^7.10.1",
+        "@rc-component/mini-decimal": "^1.0.1",
+        "classnames": "^2.2.5",
+        "rc-input": "~1.6.0",
+        "rc-util": "^5.40.1"
+      },
+      "peerDependencies": {
+        "react": ">=16.9.0",
+        "react-dom": ">=16.9.0"
+      }
+    },
+    "node_modules/rc-mentions": {
+      "version": "2.17.0",
+      "resolved": "https://registry.npmmirror.com/rc-mentions/-/rc-mentions-2.17.0.tgz",
+      "integrity": "sha512-sfHy+qLvc+p8jx8GUsujZWXDOIlIimp6YQz7N5ONQ6bHsa2kyG+BLa5k2wuxgebBbH97is33wxiyq5UkiXRpHA==",
+      "dependencies": {
+        "@babel/runtime": "^7.22.5",
+        "@rc-component/trigger": "^2.0.0",
+        "classnames": "^2.2.6",
+        "rc-input": "~1.6.0",
+        "rc-menu": "~9.16.0",
+        "rc-textarea": "~1.8.0",
+        "rc-util": "^5.34.1"
+      },
+      "peerDependencies": {
+        "react": ">=16.9.0",
+        "react-dom": ">=16.9.0"
+      }
+    },
+    "node_modules/rc-menu": {
+      "version": "9.16.0",
+      "resolved": "https://registry.npmmirror.com/rc-menu/-/rc-menu-9.16.0.tgz",
+      "integrity": "sha512-vAL0yqPkmXWk3+YKRkmIR8TYj3RVdEt3ptG2jCJXWNAvQbT0VJJdRyHZ7kG/l1JsZlB+VJq/VcYOo69VR4oD+w==",
+      "dependencies": {
+        "@babel/runtime": "^7.10.1",
+        "@rc-component/trigger": "^2.0.0",
+        "classnames": "2.x",
+        "rc-motion": "^2.4.3",
+        "rc-overflow": "^1.3.1",
+        "rc-util": "^5.27.0"
+      },
+      "peerDependencies": {
+        "react": ">=16.9.0",
+        "react-dom": ">=16.9.0"
+      }
+    },
+    "node_modules/rc-motion": {
+      "version": "2.9.5",
+      "resolved": "https://registry.npmmirror.com/rc-motion/-/rc-motion-2.9.5.tgz",
+      "integrity": "sha512-w+XTUrfh7ArbYEd2582uDrEhmBHwK1ZENJiSJVb7uRxdE7qJSYjbO2eksRXmndqyKqKoYPc9ClpPh5242mV1vA==",
+      "dependencies": {
+        "@babel/runtime": "^7.11.1",
+        "classnames": "^2.2.1",
+        "rc-util": "^5.44.0"
+      },
+      "peerDependencies": {
+        "react": ">=16.9.0",
+        "react-dom": ">=16.9.0"
+      }
+    },
+    "node_modules/rc-notification": {
+      "version": "5.6.2",
+      "resolved": "https://registry.npmmirror.com/rc-notification/-/rc-notification-5.6.2.tgz",
+      "integrity": "sha512-Id4IYMoii3zzrG0lB0gD6dPgJx4Iu95Xu0BQrhHIbp7ZnAZbLqdqQ73aIWH0d0UFcElxwaKjnzNovTjo7kXz7g==",
+      "dependencies": {
+        "@babel/runtime": "^7.10.1",
+        "classnames": "2.x",
+        "rc-motion": "^2.9.0",
+        "rc-util": "^5.20.1"
+      },
+      "engines": {
+        "node": ">=8.x"
+      },
+      "peerDependencies": {
+        "react": ">=16.9.0",
+        "react-dom": ">=16.9.0"
+      }
+    },
+    "node_modules/rc-overflow": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmmirror.com/rc-overflow/-/rc-overflow-1.3.2.tgz",
+      "integrity": "sha512-nsUm78jkYAoPygDAcGZeC2VwIg/IBGSodtOY3pMof4W3M9qRJgqaDYm03ZayHlde3I6ipliAxbN0RUcGf5KOzw==",
+      "dependencies": {
+        "@babel/runtime": "^7.11.1",
+        "classnames": "^2.2.1",
+        "rc-resize-observer": "^1.0.0",
+        "rc-util": "^5.37.0"
+      },
+      "peerDependencies": {
+        "react": ">=16.9.0",
+        "react-dom": ">=16.9.0"
+      }
+    },
+    "node_modules/rc-pagination": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmmirror.com/rc-pagination/-/rc-pagination-5.0.0.tgz",
+      "integrity": "sha512-QjrPvbAQwps93iluvFM62AEYglGYhWW2q/nliQqmvkTi4PXP4HHoh00iC1Sa5LLVmtWQHmG73fBi2x6H6vFHRg==",
+      "dependencies": {
+        "@babel/runtime": "^7.10.1",
+        "classnames": "^2.3.2",
+        "rc-util": "^5.38.0"
+      },
+      "peerDependencies": {
+        "react": ">=16.9.0",
+        "react-dom": ">=16.9.0"
+      }
+    },
+    "node_modules/rc-picker": {
+      "version": "4.8.3",
+      "resolved": "https://registry.npmmirror.com/rc-picker/-/rc-picker-4.8.3.tgz",
+      "integrity": "sha512-hJ45qoEs4mfxXPAJdp1n3sKwADul874Cd0/HwnsEOE60H+tgiJUGgbOD62As3EG/rFVNS5AWRfBCDJJfmRqOVQ==",
+      "dependencies": {
+        "@babel/runtime": "^7.24.7",
+        "@rc-component/trigger": "^2.0.0",
+        "classnames": "^2.2.1",
+        "rc-overflow": "^1.3.2",
+        "rc-resize-observer": "^1.4.0",
+        "rc-util": "^5.43.0"
+      },
+      "engines": {
+        "node": ">=8.x"
+      },
+      "peerDependencies": {
+        "date-fns": ">= 2.x",
+        "dayjs": ">= 1.x",
+        "luxon": ">= 3.x",
+        "moment": ">= 2.x",
+        "react": ">=16.9.0",
+        "react-dom": ">=16.9.0"
+      },
+      "peerDependenciesMeta": {
+        "date-fns": {
+          "optional": true
+        },
+        "dayjs": {
+          "optional": true
+        },
+        "luxon": {
+          "optional": true
+        },
+        "moment": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/rc-progress": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/rc-progress/-/rc-progress-4.0.0.tgz",
+      "integrity": "sha512-oofVMMafOCokIUIBnZLNcOZFsABaUw8PPrf1/y0ZBvKZNpOiu5h4AO9vv11Sw0p4Hb3D0yGWuEattcQGtNJ/aw==",
+      "dependencies": {
+        "@babel/runtime": "^7.10.1",
+        "classnames": "^2.2.6",
+        "rc-util": "^5.16.1"
+      },
+      "peerDependencies": {
+        "react": ">=16.9.0",
+        "react-dom": ">=16.9.0"
+      }
+    },
+    "node_modules/rc-rate": {
+      "version": "2.13.0",
+      "resolved": "https://registry.npmmirror.com/rc-rate/-/rc-rate-2.13.0.tgz",
+      "integrity": "sha512-oxvx1Q5k5wD30sjN5tqAyWTvJfLNNJn7Oq3IeS4HxWfAiC4BOXMITNAsw7u/fzdtO4MS8Ki8uRLOzcnEuoQiAw==",
+      "dependencies": {
+        "@babel/runtime": "^7.10.1",
+        "classnames": "^2.2.5",
+        "rc-util": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8.x"
+      },
+      "peerDependencies": {
+        "react": ">=16.9.0",
+        "react-dom": ">=16.9.0"
+      }
+    },
+    "node_modules/rc-resize-observer": {
+      "version": "1.4.3",
+      "resolved": "https://registry.npmmirror.com/rc-resize-observer/-/rc-resize-observer-1.4.3.tgz",
+      "integrity": "sha512-YZLjUbyIWox8E9i9C3Tm7ia+W7euPItNWSPX5sCcQTYbnwDb5uNpnLHQCG1f22oZWUhLw4Mv2tFmeWe68CDQRQ==",
+      "dependencies": {
+        "@babel/runtime": "^7.20.7",
+        "classnames": "^2.2.1",
+        "rc-util": "^5.44.1",
+        "resize-observer-polyfill": "^1.5.1"
+      },
+      "peerDependencies": {
+        "react": ">=16.9.0",
+        "react-dom": ">=16.9.0"
+      }
+    },
+    "node_modules/rc-segmented": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmmirror.com/rc-segmented/-/rc-segmented-2.5.0.tgz",
+      "integrity": "sha512-B28Fe3J9iUFOhFJET3RoXAPFJ2u47QvLSYcZWC4tFYNGPEjug5LAxEasZlA/PpAxhdOPqGWsGbSj7ftneukJnw==",
+      "dependencies": {
+        "@babel/runtime": "^7.11.1",
+        "classnames": "^2.2.1",
+        "rc-motion": "^2.4.4",
+        "rc-util": "^5.17.0"
+      },
+      "peerDependencies": {
+        "react": ">=16.0.0",
+        "react-dom": ">=16.0.0"
+      }
+    },
+    "node_modules/rc-select": {
+      "version": "14.16.4",
+      "resolved": "https://registry.npmmirror.com/rc-select/-/rc-select-14.16.4.tgz",
+      "integrity": "sha512-jP6qf7+vjnxGvPpfPWbGYfFlSl3h8L2XcD4O7g2GYXmEeBC0mw+nPD7i++OOE8v3YGqP8xtYjRKAWCMLfjgxlw==",
+      "dependencies": {
+        "@babel/runtime": "^7.10.1",
+        "@rc-component/trigger": "^2.1.1",
+        "classnames": "2.x",
+        "rc-motion": "^2.0.1",
+        "rc-overflow": "^1.3.1",
+        "rc-util": "^5.16.1",
+        "rc-virtual-list": "^3.5.2"
+      },
+      "engines": {
+        "node": ">=8.x"
+      },
+      "peerDependencies": {
+        "react": "*",
+        "react-dom": "*"
+      }
+    },
+    "node_modules/rc-slider": {
+      "version": "11.1.7",
+      "resolved": "https://registry.npmmirror.com/rc-slider/-/rc-slider-11.1.7.tgz",
+      "integrity": "sha512-ytYbZei81TX7otdC0QvoYD72XSlxvTihNth5OeZ6PMXyEDq/vHdWFulQmfDGyXK1NwKwSlKgpvINOa88uT5g2A==",
+      "dependencies": {
+        "@babel/runtime": "^7.10.1",
+        "classnames": "^2.2.5",
+        "rc-util": "^5.36.0"
+      },
+      "engines": {
+        "node": ">=8.x"
+      },
+      "peerDependencies": {
+        "react": ">=16.9.0",
+        "react-dom": ">=16.9.0"
+      }
+    },
+    "node_modules/rc-steps": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmmirror.com/rc-steps/-/rc-steps-6.0.1.tgz",
+      "integrity": "sha512-lKHL+Sny0SeHkQKKDJlAjV5oZ8DwCdS2hFhAkIjuQt1/pB81M0cA0ErVFdHq9+jmPmFw1vJB2F5NBzFXLJxV+g==",
+      "dependencies": {
+        "@babel/runtime": "^7.16.7",
+        "classnames": "^2.2.3",
+        "rc-util": "^5.16.1"
+      },
+      "engines": {
+        "node": ">=8.x"
+      },
+      "peerDependencies": {
+        "react": ">=16.9.0",
+        "react-dom": ">=16.9.0"
+      }
+    },
+    "node_modules/rc-switch": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmmirror.com/rc-switch/-/rc-switch-4.1.0.tgz",
+      "integrity": "sha512-TI8ufP2Az9oEbvyCeVE4+90PDSljGyuwix3fV58p7HV2o4wBnVToEyomJRVyTaZeqNPAp+vqeo4Wnj5u0ZZQBg==",
+      "dependencies": {
+        "@babel/runtime": "^7.21.0",
+        "classnames": "^2.2.1",
+        "rc-util": "^5.30.0"
+      },
+      "peerDependencies": {
+        "react": ">=16.9.0",
+        "react-dom": ">=16.9.0"
+      }
+    },
+    "node_modules/rc-table": {
+      "version": "7.49.0",
+      "resolved": "https://registry.npmmirror.com/rc-table/-/rc-table-7.49.0.tgz",
+      "integrity": "sha512-/FoPLX94muAQOxVpi1jhnpKjOIqUbT81eELQPAzSXOke4ky4oCWYUXOcVpL31ZCO90xScwVSXRd7coqtgtB1Ng==",
+      "dependencies": {
+        "@babel/runtime": "^7.10.1",
+        "@rc-component/context": "^1.4.0",
+        "classnames": "^2.2.5",
+        "rc-resize-observer": "^1.1.0",
+        "rc-util": "^5.41.0",
+        "rc-virtual-list": "^3.14.2"
+      },
+      "engines": {
+        "node": ">=8.x"
+      },
+      "peerDependencies": {
+        "react": ">=16.9.0",
+        "react-dom": ">=16.9.0"
+      }
+    },
+    "node_modules/rc-tabs": {
+      "version": "15.4.0",
+      "resolved": "https://registry.npmmirror.com/rc-tabs/-/rc-tabs-15.4.0.tgz",
+      "integrity": "sha512-llKuyiAVqmXm2z7OrmhX5cNb2ueZaL8ZyA2P4R+6/72NYYcbEgOXibwHiQCFY2RiN3swXl53SIABi2CumUS02g==",
+      "dependencies": {
+        "@babel/runtime": "^7.11.2",
+        "classnames": "2.x",
+        "rc-dropdown": "~4.2.0",
+        "rc-menu": "~9.16.0",
+        "rc-motion": "^2.6.2",
+        "rc-resize-observer": "^1.0.0",
+        "rc-util": "^5.34.1"
+      },
+      "engines": {
+        "node": ">=8.x"
+      },
+      "peerDependencies": {
+        "react": ">=16.9.0",
+        "react-dom": ">=16.9.0"
+      }
+    },
+    "node_modules/rc-textarea": {
+      "version": "1.8.2",
+      "resolved": "https://registry.npmmirror.com/rc-textarea/-/rc-textarea-1.8.2.tgz",
+      "integrity": "sha512-UFAezAqltyR00a8Lf0IPAyTd29Jj9ee8wt8DqXyDMal7r/Cg/nDt3e1OOv3Th4W6mKaZijjgwuPXhAfVNTN8sw==",
+      "dependencies": {
+        "@babel/runtime": "^7.10.1",
+        "classnames": "^2.2.1",
+        "rc-input": "~1.6.0",
+        "rc-resize-observer": "^1.0.0",
+        "rc-util": "^5.27.0"
+      },
+      "peerDependencies": {
+        "react": ">=16.9.0",
+        "react-dom": ">=16.9.0"
+      }
+    },
+    "node_modules/rc-tooltip": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmmirror.com/rc-tooltip/-/rc-tooltip-6.2.1.tgz",
+      "integrity": "sha512-rws0duD/3sHHsD905Nex7FvoUGy2UBQRhTkKxeEvr2FB+r21HsOxcDJI0TzyO8NHhnAA8ILr8pfbSBg5Jj5KBg==",
+      "dependencies": {
+        "@babel/runtime": "^7.11.2",
+        "@rc-component/trigger": "^2.0.0",
+        "classnames": "^2.3.1"
+      },
+      "peerDependencies": {
+        "react": ">=16.9.0",
+        "react-dom": ">=16.9.0"
+      }
+    },
+    "node_modules/rc-tree": {
+      "version": "5.10.1",
+      "resolved": "https://registry.npmmirror.com/rc-tree/-/rc-tree-5.10.1.tgz",
+      "integrity": "sha512-FPXb3tT/u39mgjr6JNlHaUTYfHkVGW56XaGDahDpEFLGsnPxGcVLNTjcqoQb/GNbSCycl7tD7EvIymwOTP0+Yw==",
+      "dependencies": {
+        "@babel/runtime": "^7.10.1",
+        "classnames": "2.x",
+        "rc-motion": "^2.0.1",
+        "rc-util": "^5.16.1",
+        "rc-virtual-list": "^3.5.1"
+      },
+      "engines": {
+        "node": ">=10.x"
+      },
+      "peerDependencies": {
+        "react": "*",
+        "react-dom": "*"
+      }
+    },
+    "node_modules/rc-tree-select": {
+      "version": "5.24.5",
+      "resolved": "https://registry.npmmirror.com/rc-tree-select/-/rc-tree-select-5.24.5.tgz",
+      "integrity": "sha512-PnyR8LZJWaiEFw0SHRqo4MNQWyyZsyMs8eNmo68uXZWjxc7QqeWcjPPoONN0rc90c3HZqGF9z+Roz+GLzY5GXA==",
+      "dependencies": {
+        "@babel/runtime": "^7.25.7",
+        "classnames": "2.x",
+        "rc-select": "~14.16.2",
+        "rc-tree": "~5.10.1",
+        "rc-util": "^5.43.0"
+      },
+      "peerDependencies": {
+        "react": "*",
+        "react-dom": "*"
+      }
+    },
+    "node_modules/rc-upload": {
+      "version": "4.8.1",
+      "resolved": "https://registry.npmmirror.com/rc-upload/-/rc-upload-4.8.1.tgz",
+      "integrity": "sha512-toEAhwl4hjLAI1u8/CgKWt30BR06ulPa4iGQSMvSXoHzO88gPCslxqV/mnn4gJU7PDoltGIC9Eh+wkeudqgHyw==",
+      "dependencies": {
+        "@babel/runtime": "^7.18.3",
+        "classnames": "^2.2.5",
+        "rc-util": "^5.2.0"
+      },
+      "peerDependencies": {
+        "react": ">=16.9.0",
+        "react-dom": ">=16.9.0"
+      }
+    },
+    "node_modules/rc-util": {
+      "version": "5.44.3",
+      "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.44.3.tgz",
+      "integrity": "sha512-q6KCcOFk3rv/zD3MckhJteZxb0VjAIFuf622B7ElK4vfrZdAzs16XR5p3VTdy3+U5jfJU5ACz4QnhLSuAGe5dA==",
+      "dependencies": {
+        "@babel/runtime": "^7.18.3",
+        "react-is": "^18.2.0"
+      },
+      "peerDependencies": {
+        "react": ">=16.9.0",
+        "react-dom": ">=16.9.0"
+      }
+    },
+    "node_modules/rc-virtual-list": {
+      "version": "3.16.1",
+      "resolved": "https://registry.npmmirror.com/rc-virtual-list/-/rc-virtual-list-3.16.1.tgz",
+      "integrity": "sha512-algM5UsB7vrlPNr9lsZEH8s9KHkP8XbT/Y0qylyPkiM8mIOlSJLjBNADcmbYPEQCm4zW82mZRJuVHNzqqN0EAQ==",
+      "dependencies": {
+        "@babel/runtime": "^7.20.0",
+        "classnames": "^2.2.6",
+        "rc-resize-observer": "^1.0.0",
+        "rc-util": "^5.36.0"
+      },
+      "engines": {
+        "node": ">=8.x"
+      },
+      "peerDependencies": {
+        "react": ">=16.9.0",
+        "react-dom": ">=16.9.0"
+      }
+    },
+    "node_modules/react": {
+      "version": "18.3.1",
+      "resolved": "https://registry.npmmirror.com/react/-/react-18.3.1.tgz",
+      "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
+      "dependencies": {
+        "loose-envify": "^1.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/react-dom": {
+      "version": "18.3.1",
+      "resolved": "https://registry.npmmirror.com/react-dom/-/react-dom-18.3.1.tgz",
+      "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
+      "dependencies": {
+        "loose-envify": "^1.1.0",
+        "scheduler": "^0.23.2"
+      },
+      "peerDependencies": {
+        "react": "^18.3.1"
+      }
+    },
+    "node_modules/react-is": {
+      "version": "18.3.1",
+      "resolved": "https://registry.npmmirror.com/react-is/-/react-is-18.3.1.tgz",
+      "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="
+    },
+    "node_modules/react-refresh": {
+      "version": "0.14.2",
+      "resolved": "https://registry.npmmirror.com/react-refresh/-/react-refresh-0.14.2.tgz",
+      "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/react-router": {
+      "version": "7.1.1",
+      "resolved": "https://registry.npmmirror.com/react-router/-/react-router-7.1.1.tgz",
+      "integrity": "sha512-39sXJkftkKWRZ2oJtHhCxmoCrBCULr/HAH4IT5DHlgu/Q0FCPV0S4Lx+abjDTx/74xoZzNYDYbOZWlJjruyuDQ==",
+      "dependencies": {
+        "@types/cookie": "^0.6.0",
+        "cookie": "^1.0.1",
+        "set-cookie-parser": "^2.6.0",
+        "turbo-stream": "2.4.0"
+      },
+      "engines": {
+        "node": ">=20.0.0"
+      },
+      "peerDependencies": {
+        "react": ">=18",
+        "react-dom": ">=18"
+      },
+      "peerDependenciesMeta": {
+        "react-dom": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/react-router-dom": {
+      "version": "7.1.1",
+      "resolved": "https://registry.npmmirror.com/react-router-dom/-/react-router-dom-7.1.1.tgz",
+      "integrity": "sha512-vSrQHWlJ5DCfyrhgo0k6zViOe9ToK8uT5XGSmnuC2R3/g261IdIMpZVqfjD6vWSXdnf5Czs4VA/V60oVR6/jnA==",
+      "dependencies": {
+        "react-router": "7.1.1"
+      },
+      "engines": {
+        "node": ">=20.0.0"
+      },
+      "peerDependencies": {
+        "react": ">=18",
+        "react-dom": ">=18"
+      }
+    },
+    "node_modules/regenerator-runtime": {
+      "version": "0.14.1",
+      "resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
+      "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
+    },
+    "node_modules/resize-observer-polyfill": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmmirror.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
+      "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
+    },
+    "node_modules/rollup": {
+      "version": "4.29.1",
+      "resolved": "https://registry.npmmirror.com/rollup/-/rollup-4.29.1.tgz",
+      "integrity": "sha512-RaJ45M/kmJUzSWDs1Nnd5DdV4eerC98idtUOVr6FfKcgxqvjwHmxc5upLF9qZU9EpsVzzhleFahrT3shLuJzIw==",
+      "dev": true,
+      "dependencies": {
+        "@types/estree": "1.0.6"
+      },
+      "bin": {
+        "rollup": "dist/bin/rollup"
+      },
+      "engines": {
+        "node": ">=18.0.0",
+        "npm": ">=8.0.0"
+      },
+      "optionalDependencies": {
+        "@rollup/rollup-android-arm-eabi": "4.29.1",
+        "@rollup/rollup-android-arm64": "4.29.1",
+        "@rollup/rollup-darwin-arm64": "4.29.1",
+        "@rollup/rollup-darwin-x64": "4.29.1",
+        "@rollup/rollup-freebsd-arm64": "4.29.1",
+        "@rollup/rollup-freebsd-x64": "4.29.1",
+        "@rollup/rollup-linux-arm-gnueabihf": "4.29.1",
+        "@rollup/rollup-linux-arm-musleabihf": "4.29.1",
+        "@rollup/rollup-linux-arm64-gnu": "4.29.1",
+        "@rollup/rollup-linux-arm64-musl": "4.29.1",
+        "@rollup/rollup-linux-loongarch64-gnu": "4.29.1",
+        "@rollup/rollup-linux-powerpc64le-gnu": "4.29.1",
+        "@rollup/rollup-linux-riscv64-gnu": "4.29.1",
+        "@rollup/rollup-linux-s390x-gnu": "4.29.1",
+        "@rollup/rollup-linux-x64-gnu": "4.29.1",
+        "@rollup/rollup-linux-x64-musl": "4.29.1",
+        "@rollup/rollup-win32-arm64-msvc": "4.29.1",
+        "@rollup/rollup-win32-ia32-msvc": "4.29.1",
+        "@rollup/rollup-win32-x64-msvc": "4.29.1",
+        "fsevents": "~2.3.2"
+      }
+    },
+    "node_modules/safer-buffer": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz",
+      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/sax": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmmirror.com/sax/-/sax-1.4.1.tgz",
+      "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/scheduler": {
+      "version": "0.23.2",
+      "resolved": "https://registry.npmmirror.com/scheduler/-/scheduler-0.23.2.tgz",
+      "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
+      "dependencies": {
+        "loose-envify": "^1.1.0"
+      }
+    },
+    "node_modules/scroll-into-view-if-needed": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmmirror.com/scroll-into-view-if-needed/-/scroll-into-view-if-needed-3.1.0.tgz",
+      "integrity": "sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==",
+      "dependencies": {
+        "compute-scroll-into-view": "^3.0.2"
+      }
+    },
+    "node_modules/semver": {
+      "version": "6.3.1",
+      "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz",
+      "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver.js"
+      }
+    },
+    "node_modules/set-cookie-parser": {
+      "version": "2.7.1",
+      "resolved": "https://registry.npmmirror.com/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz",
+      "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ=="
+    },
+    "node_modules/source-map": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",
+      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/source-map-js": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz",
+      "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/string-convert": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmmirror.com/string-convert/-/string-convert-0.2.1.tgz",
+      "integrity": "sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A=="
+    },
+    "node_modules/stylis": {
+      "version": "4.3.4",
+      "resolved": "https://registry.npmmirror.com/stylis/-/stylis-4.3.4.tgz",
+      "integrity": "sha512-osIBl6BGUmSfDkyH2mB7EFvCJntXDrLhKjHTRj/rK6xLH0yuPrHULDRQzKokSOD4VoorhtKpfcfW1GAntu8now=="
+    },
+    "node_modules/throttle-debounce": {
+      "version": "5.0.2",
+      "resolved": "https://registry.npmmirror.com/throttle-debounce/-/throttle-debounce-5.0.2.tgz",
+      "integrity": "sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==",
+      "engines": {
+        "node": ">=12.22"
+      }
+    },
+    "node_modules/toggle-selection": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmmirror.com/toggle-selection/-/toggle-selection-1.0.6.tgz",
+      "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ=="
+    },
+    "node_modules/tslib": {
+      "version": "2.8.1",
+      "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.8.1.tgz",
+      "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+      "dev": true
+    },
+    "node_modules/turbo-stream": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmmirror.com/turbo-stream/-/turbo-stream-2.4.0.tgz",
+      "integrity": "sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g=="
+    },
+    "node_modules/typescript": {
+      "version": "5.7.2",
+      "resolved": "https://registry.npmmirror.com/typescript/-/typescript-5.7.2.tgz",
+      "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==",
+      "dev": true,
+      "bin": {
+        "tsc": "bin/tsc",
+        "tsserver": "bin/tsserver"
+      },
+      "engines": {
+        "node": ">=14.17"
+      }
+    },
+    "node_modules/undici-types": {
+      "version": "6.20.0",
+      "resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-6.20.0.tgz",
+      "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
+      "dev": true
+    },
+    "node_modules/update-browserslist-db": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz",
+      "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/browserslist"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/browserslist"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "dependencies": {
+        "escalade": "^3.2.0",
+        "picocolors": "^1.1.0"
+      },
+      "bin": {
+        "update-browserslist-db": "cli.js"
+      },
+      "peerDependencies": {
+        "browserslist": ">= 4.21.0"
+      }
+    },
+    "node_modules/use-sync-external-store": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmmirror.com/use-sync-external-store/-/use-sync-external-store-1.4.0.tgz",
+      "integrity": "sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==",
+      "peerDependencies": {
+        "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+      }
+    },
+    "node_modules/vite": {
+      "version": "6.0.6",
+      "resolved": "https://registry.npmmirror.com/vite/-/vite-6.0.6.tgz",
+      "integrity": "sha512-NSjmUuckPmDU18bHz7QZ+bTYhRR0iA72cs2QAxCqDpafJ0S6qetco0LB3WW2OxlMHS0JmAv+yZ/R3uPmMyGTjQ==",
+      "dev": true,
+      "dependencies": {
+        "esbuild": "^0.24.2",
+        "postcss": "^8.4.49",
+        "rollup": "^4.23.0"
+      },
+      "bin": {
+        "vite": "bin/vite.js"
+      },
+      "engines": {
+        "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/vitejs/vite?sponsor=1"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.3.3"
+      },
+      "peerDependencies": {
+        "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
+        "jiti": ">=1.21.0",
+        "less": "*",
+        "lightningcss": "^1.21.0",
+        "sass": "*",
+        "sass-embedded": "*",
+        "stylus": "*",
+        "sugarss": "*",
+        "terser": "^5.16.0",
+        "tsx": "^4.8.1",
+        "yaml": "^2.4.2"
+      },
+      "peerDependenciesMeta": {
+        "@types/node": {
+          "optional": true
+        },
+        "jiti": {
+          "optional": true
+        },
+        "less": {
+          "optional": true
+        },
+        "lightningcss": {
+          "optional": true
+        },
+        "sass": {
+          "optional": true
+        },
+        "sass-embedded": {
+          "optional": true
+        },
+        "stylus": {
+          "optional": true
+        },
+        "sugarss": {
+          "optional": true
+        },
+        "terser": {
+          "optional": true
+        },
+        "tsx": {
+          "optional": true
+        },
+        "yaml": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/yallist": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmmirror.com/yallist/-/yallist-3.1.1.tgz",
+      "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+      "dev": true
+    }
+  }
+}

+ 33 - 0
package.json

@@ -0,0 +1,33 @@
+{
+  "name": "chat-admin-web",
+  "version": "1.0.0",
+  "private": true,
+  "description": "AI问答-管理端",
+  "type": "module",
+  "license": "ISC",
+  "scripts": {
+    "start": "vite --mode development",
+    "start:prod": "vite --mode production",
+    "build": "vite build --mode development",
+    "build:prod": "vite build --mode production"
+  },
+  "dependencies": {
+    "antd": "^5.22.0",
+    "axios": "^1.7.0",
+    "dayjs": "^1.11.0",
+    "mobx": "^6.13.0",
+    "mobx-react": "^9.2.0",
+    "react": "^18.2.0",
+    "react-dom": "^18.2.0",
+    "react-router-dom": "^7.1.0"
+  },
+  "devDependencies": {
+    "@types/node": "^22.0.0",
+    "@types/react": "^18.2.0",
+    "@types/react-dom": "^18.2.0",
+    "@vitejs/plugin-react": "^4.3.0",
+    "less": "^4.2.0",
+    "typescript": "^5.7.0",
+    "vite": "^6.0.0"
+  }
+}

+ 103 - 0
src/App.tsx

@@ -0,0 +1,103 @@
+import * as React from 'react';
+import { RouterProvider } from 'react-router-dom';
+import {
+    ConfigProvider as AntdConfigProvider,
+    App as AntdApp,
+    message,
+    notification,
+} from 'antd';
+import zhCN from 'antd/locale/zh_CN';
+import router from '@/router';
+
+interface ConfigProviderProps {
+    children: React.ReactNode,
+}
+
+// Ant-Design全局化配置
+const ConfigProvider: React.FC<ConfigProviderProps> = (props: ConfigProviderProps) => {
+    function getDesignToken() {
+        // 获取元素
+        const root = document.getElementById('root');
+        // 获取元素计算样式
+        const styles = getComputedStyle(root!);
+        // 获取Ant-Design主题-属性
+        const colorPrimary = styles.getPropertyValue('--primary-color');
+        const colorTextBase = styles.getPropertyValue('--text-color');
+        const borderRadiusArray = styles.getPropertyValue('--border-radius').match(/\d+/);
+
+        return {
+            colorPrimary: colorPrimary || undefined,
+            colorTextBase: colorTextBase || undefined,
+            borderRadius: borderRadiusArray ? Number(borderRadiusArray[0]) : undefined,
+        }
+    }
+
+    const designToken = getDesignToken();
+
+    return (
+        <AntdConfigProvider
+            // 组件-中文
+            locale={zhCN}
+            // 警告等级
+            warning={{
+                strict: true,// 严格模式
+            }}
+            // 渲染父节点到body上
+            getPopupContainer={() => document.body}
+            // 设置主题
+            theme={{
+                token: {
+                    colorPrimary: designToken.colorPrimary,// 主题颜色
+                    colorTextBase: designToken.colorTextBase,// 文本颜色
+                    borderRadius: designToken.borderRadius,// 圆角大小
+                },
+                components: {
+                    Table: {
+                        headerBg: '#F4F5FA',
+                        headerSplitColor: 'transparent',
+                    },
+                },
+            }}
+            /* 组件配置 */
+            button={{
+                autoInsertSpace: false,// 移除按钮两个汉字之间的空格
+            }}
+        >
+            {props.children}
+        </AntdConfigProvider>
+    );
+}
+
+const App: React.FC = () => {
+    // 全局提示
+    message.config({
+        duration: 2,// 2秒自动关闭
+        maxCount: 1,// 最多显示1条
+    });
+
+    // 通知提醒
+    notification.config({
+        duration: 2,// 2秒自动关闭
+        maxCount: 1,// 最多显示1条
+    });
+
+    // 全局配置
+    AntdConfigProvider.config({
+        // 静态方法
+        holderRender: (children) => (
+            <ConfigProvider>
+                {children}
+            </ConfigProvider>
+        )
+    });
+
+    return (
+        <ConfigProvider>
+            <AntdApp style={{ height: '100%', lineHeight: 'normal' }}>
+                <RouterProvider router={router} />
+            </AntdApp>
+        </ConfigProvider>
+    );
+};
+
+export default App;

+ 78 - 0
src/LocalStorage.ts

@@ -0,0 +1,78 @@
+interface AccountPassword {
+    account: string,
+    password: string,
+};
+
+interface UserInfo {
+    id: number,
+    name: string,
+};
+
+class LocalStorage {
+    // 存储账号密码
+    setAccountPassword = (accountPassword?: AccountPassword) => {
+        if (accountPassword) {
+            localStorage.setItem('accountPassword', JSON.stringify(accountPassword));
+        } else {
+            localStorage.removeItem('accountPassword');
+        }
+    }
+
+    // 存储token
+    setToken = (token: string) => {
+        localStorage.setItem('token', token);
+    }
+
+    // 存储用户信息
+    setUserInfo = (userInfo: UserInfo) => {
+        localStorage.setItem('userInfo', JSON.stringify(userInfo));
+    }
+
+    // 获取账号密码
+    getAccountPassword = () => {
+        const accountPasswordString = localStorage.getItem('accountPassword');
+
+        if (accountPasswordString) {
+            const accountPassword: AccountPassword = JSON.parse(accountPasswordString);
+            return accountPassword;
+        }
+        return undefined;
+    }
+
+    // 获取token
+    getToken = (): string | undefined => {
+        const token = localStorage.getItem('token');
+
+        if (token) {
+            return token;
+        } else {
+            this.clear();
+            return undefined;
+        }
+    }
+
+    // 获取用户信息
+    getUserInfo = () => {
+        const userInfoString = localStorage.getItem('userInfo');
+
+        if (userInfoString) {
+            const userInfo: UserInfo = JSON.parse(userInfoString);
+            return userInfo;
+        }
+        return undefined;
+    }
+
+    // 清除
+    clear = () => {
+        /*
+         * 保留密码
+         */
+        const accountPassword = this.getAccountPassword();
+        const cloneAccountPassword = accountPassword ? { ...accountPassword } : undefined;
+
+        localStorage.clear();
+        this.setAccountPassword(cloneAccountPassword);
+    }
+}
+
+export default new LocalStorage();

+ 66 - 0
src/apis/api.ts

@@ -0,0 +1,66 @@
+import axios, { AxiosResponse } from 'axios';
+import { message } from 'antd';
+import config from './config';
+import LocalStorage from '@/LocalStorage';
+import router from '@/router';
+
+export const getHeaders = () => {
+    const headers: { 'token'?: string } = {};
+    const token = LocalStorage.getToken();
+    if (token) {
+        headers['token'] = token;
+    }
+    return headers;
+};
+
+// 创建axios实例
+const axiosInstance = axios.create({
+    baseURL: config.baseURL,
+    timeout: 30000,// 请求超时30秒
+});
+
+// 请求拦截器
+axiosInstance.interceptors.request.use(
+    (config: any) => {
+        config.headers = getHeaders();
+        if (!navigator.onLine) {
+            message.error('网络故障');
+        }
+        return config;
+    }
+);
+
+// 响应拦截器
+axiosInstance.interceptors.response.use(
+    (response: AxiosResponse) => {// 成功信息
+        const { data } = response;
+        if (data.code === 200) {// 成功
+            return Promise.resolve(data);
+        } else {// 失败
+            if (data.code === 401) {
+                LocalStorage.clear();
+                router.navigate({ pathname: '/login' }, { replace: true });
+                message.error('登录过期');
+                return Promise.reject();
+            } else {
+                return Promise.reject(data);
+            }
+        }
+    },
+    (error) => {// 错误信息
+        // HTTP状态码
+        const statusCode = error.response.status;
+        if (String(error).includes('timeout')) {
+            message.error('请求超时');
+        } else {
+            if (statusCode < 500) {
+                message.error('请求失败');
+            } else {
+                message.error('服务异常');
+            }
+        }
+        return Promise.reject();
+    }
+);
+
+export default axiosInstance;

+ 14 - 0
src/apis/config.ts

@@ -0,0 +1,14 @@
+const apiURL = import.meta.env.VITE_API_URL;
+
+const webSocketURL = import.meta.env.VITE_WEBSOCKET_URL;
+
+const baseURL = '/api';
+
+const config = {
+    apiURL: apiURL,
+    webSocketURL: webSocketURL,
+    baseURL: baseURL,
+    v1URL: baseURL + '/v1',
+};
+
+export default config;

+ 20 - 0
src/apis/index.ts

@@ -0,0 +1,20 @@
+import api from './api';
+import config from './config';
+
+// Api参数类型
+export type LoginApiParams = {
+    account: string,
+    password: string,
+};
+
+// Api函数类型
+export type LoginApi = (data: LoginApiParams) => Promise<any>;
+
+// 登录
+const loginApi: LoginApi = async (data) => {
+    return api.post('/auth/login', data, { baseURL: config.v1URL });
+};
+
+export const apis = {
+    login: loginApi,
+};

BIN
src/assets/login/background.jpg


BIN
src/assets/public/logo.png


BIN
src/assets/public/notFound.png


+ 16 - 0
src/components/404/index.tsx

@@ -0,0 +1,16 @@
+import * as React from 'react';
+import notFoundSrc from '@/assets/public/notFound.png';
+import './style.less';
+
+const NotFound: React.FC = () => {
+    return (
+        <div className='notFound'>
+            <img src={notFoundSrc} />
+            <div className='notFound-text'>
+                404!页面走失了~
+            </div>
+        </div>
+    );
+};
+
+export default NotFound;

+ 23 - 0
src/components/404/style.less

@@ -0,0 +1,23 @@
+.notFound {
+    width: 100%;
+    height: 100%;
+    padding-bottom: 30px;
+    background: #FFFFFF;
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+
+    img {
+        width: 350px;
+        object-fit: cover;
+        pointer-events: none;
+    }
+
+    &-text {
+        font-size: 16px;
+        font-weight: bold;
+        color: @primary-color;
+        margin-bottom: 20px;
+    }
+}

+ 20 - 0
src/components/iconFont/index.tsx

@@ -0,0 +1,20 @@
+import * as React from 'react';
+import { createFromIconfontCN } from '@ant-design/icons';
+
+interface Props {
+	name: string,
+};
+
+const IconFont: React.FC<Props> = (props: Props) => {
+	const { name } = props;
+
+	const IconFont = createFromIconfontCN({
+		scriptUrl: '//at.alicdn.com/t/c/font_3589633_0nxlhu0gjmco.js',
+	});
+
+	return (
+		<IconFont type={name} />
+	);
+}
+
+export default IconFont;

+ 24 - 0
src/main.tsx

@@ -0,0 +1,24 @@
+import { createRoot } from 'react-dom/client';
+import { configure } from 'mobx';
+import { Provider } from 'mobx-react';
+import App from '@/App';
+import dayjs from 'dayjs';
+import 'dayjs/locale/zh-cn';
+import '@/style/global.less';
+
+// Mobx配置
+configure({
+    enforceActions: 'never',// 非严格模式
+});
+
+// 日期-中文
+dayjs.locale('zh-cn');
+
+// React@v18 Render方法
+const root = createRoot(document.getElementById('root')!);
+
+root.render(
+    <Provider>
+        <App />
+    </Provider>
+);

+ 44 - 0
src/pages/dataExport/index.tsx

@@ -0,0 +1,44 @@
+import * as React from 'react';
+import { observer } from 'mobx-react';
+import store from './store';
+import './style.less';
+
+const WorkbenchApp: React.FC = () => {
+    const {
+        state,
+        init,
+        reset
+    } = store;
+    const {
+        pageLoading
+    } = state;
+
+    React.useEffect(() => {
+        init();
+        return () => reset();
+    }, []);
+
+    return (
+        <div className='workbench'>
+            <div className='workbench-top'>
+                <div className='workbench-top-style'>
+                    <div className='workbench-top-style-welcome'>
+                        <div className='workbench-top-style-welcome-text'>
+                        
+                        </div>
+                        <div className='workbench-top-style-welcome-picture'>
+
+                        </div>
+                    </div>
+                    <div className='workbench-top-style-fast'></div>
+                </div>
+                <div className='workbench-top-weather'>
+
+                </div>
+            </div>
+            <div className='workbench-bottom'></div>
+        </div>
+    );
+};
+
+export default observer(WorkbenchApp);

+ 47 - 0
src/pages/dataExport/store.ts

@@ -0,0 +1,47 @@
+import { makeAutoObservable } from 'mobx';
+import { apis } from '@/apis';
+import { State, ReadonlyState, StateAction, WorkbenchStore } from './types';
+
+// 定义状态
+const stateGenerator = (): ReadonlyState => ({
+    pageLoading: false,
+});
+
+// 修改状态
+const stateActionsGenerator = (state: State): StateAction => {
+    return {
+        setPageLoading: (loading) => {
+            state.pageLoading = loading;
+        },
+    };
+};
+
+// 使用仓库
+const useWorkbenchStore = (): WorkbenchStore => {
+    const state = makeAutoObservable(stateGenerator());
+    const actions = stateActionsGenerator(state);
+
+    const api = {
+
+    }
+
+    // 初始渲染
+    const init = () => {
+
+    }
+
+    // 状态重置
+    const reset = () => {
+        const initialPageLoading = stateGenerator().pageLoading;
+
+        actions.setPageLoading(initialPageLoading);
+    }
+
+    return {
+        state,
+        init,
+        reset
+    };
+};
+
+export default useWorkbenchStore();

+ 83 - 0
src/pages/dataExport/style.less

@@ -0,0 +1,83 @@
+.workbench {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+
+  &-top {
+    margin-bottom: 20px;
+    display: flex;
+
+    &-style {
+      width: 100%;
+      height: 290px;
+      margin-right: 20px;
+
+      &-welcome {
+        width: 100%;
+        height: 130px;
+        padding: 0 20px;
+        background: #FFFFFF;
+        border-radius: @border-radius-base;
+        margin-bottom: 20px;
+        display: flex;
+
+        &-text {
+          width: 30%;
+          display: flex;
+          flex-direction: column;
+          justify-content: center;
+          color: @primary-color;
+
+          &-first {
+            font-size: 20px;
+            font-weight: 500;
+          }
+
+          &-second {
+            font-size: 24px;
+            font-weight: 500;
+          }
+        }
+
+        &-picture {
+          width: 70%;
+
+          img {
+            width: 100%;
+            height: 100%;
+            object-fit: cover;
+            -webkit-user-drag: none;
+          }
+        }
+      }
+
+      &-fast {
+        width: 100%;
+        height: 140px;
+        background: #FFFFFF;
+        border-radius: @border-radius-base;
+      }
+    }
+
+    &-weather {
+      width: 300px;
+      height: 290px;
+      padding: 20px 20px 0;
+      background: #FFFFFF;
+      border-radius: @border-radius-base;
+    }
+  }
+
+  &-bottom {
+    width: 100%;
+    height: 0;
+    flex: 1;
+    padding: 20px;
+    background: #FFFFFF;
+    border-radius: @border-radius-base;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+  }
+}

+ 19 - 0
src/pages/dataExport/types.ts

@@ -0,0 +1,19 @@
+// 定义状态
+export type State = {
+    pageLoading: boolean,
+};
+
+// 只读状态
+export type ReadonlyState = Readonly<State>;
+
+// 修改状态
+export type StateAction = {
+    setPageLoading: (loading: boolean) => void,
+};
+
+// 仓库类型
+export type WorkbenchStore = {
+    state: ReadonlyState,
+    init: () => void,
+    reset: () => void,
+};

+ 44 - 0
src/pages/knowledgeBase/info/index.tsx

@@ -0,0 +1,44 @@
+import * as React from 'react';
+import { observer } from 'mobx-react';
+import store from './store';
+import './style.less';
+
+const WorkbenchApp: React.FC = () => {
+    const {
+        state,
+        init,
+        reset
+    } = store;
+    const {
+        pageLoading
+    } = state;
+
+    React.useEffect(() => {
+        init();
+        return () => reset();
+    }, []);
+
+    return (
+        <div className='workbench'>
+            <div className='workbench-top'>
+                <div className='workbench-top-style'>
+                    <div className='workbench-top-style-welcome'>
+                        <div className='workbench-top-style-welcome-text'>
+                        
+                        </div>
+                        <div className='workbench-top-style-welcome-picture'>
+
+                        </div>
+                    </div>
+                    <div className='workbench-top-style-fast'></div>
+                </div>
+                <div className='workbench-top-weather'>
+
+                </div>
+            </div>
+            <div className='workbench-bottom'></div>
+        </div>
+    );
+};
+
+export default observer(WorkbenchApp);

+ 47 - 0
src/pages/knowledgeBase/info/store.ts

@@ -0,0 +1,47 @@
+import { makeAutoObservable } from 'mobx';
+import { apis } from '@/apis';
+import { State, ReadonlyState, StateAction, WorkbenchStore } from './types';
+
+// 定义状态
+const stateGenerator = (): ReadonlyState => ({
+    pageLoading: false,
+});
+
+// 修改状态
+const stateActionsGenerator = (state: State): StateAction => {
+    return {
+        setPageLoading: (loading) => {
+            state.pageLoading = loading;
+        },
+    };
+};
+
+// 使用仓库
+const useWorkbenchStore = (): WorkbenchStore => {
+    const state = makeAutoObservable(stateGenerator());
+    const actions = stateActionsGenerator(state);
+
+    const api = {
+
+    }
+
+    // 初始渲染
+    const init = () => {
+
+    }
+
+    // 状态重置
+    const reset = () => {
+        const initialPageLoading = stateGenerator().pageLoading;
+
+        actions.setPageLoading(initialPageLoading);
+    }
+
+    return {
+        state,
+        init,
+        reset
+    };
+};
+
+export default useWorkbenchStore();

+ 83 - 0
src/pages/knowledgeBase/info/style.less

@@ -0,0 +1,83 @@
+.workbench {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+
+  &-top {
+    margin-bottom: 20px;
+    display: flex;
+
+    &-style {
+      width: 100%;
+      height: 290px;
+      margin-right: 20px;
+
+      &-welcome {
+        width: 100%;
+        height: 130px;
+        padding: 0 20px;
+        background: #FFFFFF;
+        border-radius: @border-radius-base;
+        margin-bottom: 20px;
+        display: flex;
+
+        &-text {
+          width: 30%;
+          display: flex;
+          flex-direction: column;
+          justify-content: center;
+          color: @primary-color;
+
+          &-first {
+            font-size: 20px;
+            font-weight: 500;
+          }
+
+          &-second {
+            font-size: 24px;
+            font-weight: 500;
+          }
+        }
+
+        &-picture {
+          width: 70%;
+
+          img {
+            width: 100%;
+            height: 100%;
+            object-fit: cover;
+            -webkit-user-drag: none;
+          }
+        }
+      }
+
+      &-fast {
+        width: 100%;
+        height: 140px;
+        background: #FFFFFF;
+        border-radius: @border-radius-base;
+      }
+    }
+
+    &-weather {
+      width: 300px;
+      height: 290px;
+      padding: 20px 20px 0;
+      background: #FFFFFF;
+      border-radius: @border-radius-base;
+    }
+  }
+
+  &-bottom {
+    width: 100%;
+    height: 0;
+    flex: 1;
+    padding: 20px;
+    background: #FFFFFF;
+    border-radius: @border-radius-base;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+  }
+}

+ 19 - 0
src/pages/knowledgeBase/info/types.ts

@@ -0,0 +1,19 @@
+// 定义状态
+export type State = {
+    pageLoading: boolean,
+};
+
+// 只读状态
+export type ReadonlyState = Readonly<State>;
+
+// 修改状态
+export type StateAction = {
+    setPageLoading: (loading: boolean) => void,
+};
+
+// 仓库类型
+export type WorkbenchStore = {
+    state: ReadonlyState,
+    init: () => void,
+    reset: () => void,
+};

+ 44 - 0
src/pages/knowledgeBase/list/index.tsx

@@ -0,0 +1,44 @@
+import * as React from 'react';
+import { observer } from 'mobx-react';
+import store from './store';
+import './style.less';
+
+const WorkbenchApp: React.FC = () => {
+    const {
+        state,
+        init,
+        reset
+    } = store;
+    const {
+        pageLoading
+    } = state;
+
+    React.useEffect(() => {
+        init();
+        return () => reset();
+    }, []);
+
+    return (
+        <div className='workbench'>
+            <div className='workbench-top'>
+                <div className='workbench-top-style'>
+                    <div className='workbench-top-style-welcome'>
+                        <div className='workbench-top-style-welcome-text'>
+                        
+                        </div>
+                        <div className='workbench-top-style-welcome-picture'>
+
+                        </div>
+                    </div>
+                    <div className='workbench-top-style-fast'></div>
+                </div>
+                <div className='workbench-top-weather'>
+
+                </div>
+            </div>
+            <div className='workbench-bottom'></div>
+        </div>
+    );
+};
+
+export default observer(WorkbenchApp);

+ 47 - 0
src/pages/knowledgeBase/list/store.ts

@@ -0,0 +1,47 @@
+import { makeAutoObservable } from 'mobx';
+import { apis } from '@/apis';
+import { State, ReadonlyState, StateAction, WorkbenchStore } from './types';
+
+// 定义状态
+const stateGenerator = (): ReadonlyState => ({
+    pageLoading: false,
+});
+
+// 修改状态
+const stateActionsGenerator = (state: State): StateAction => {
+    return {
+        setPageLoading: (loading) => {
+            state.pageLoading = loading;
+        },
+    };
+};
+
+// 使用仓库
+const useWorkbenchStore = (): WorkbenchStore => {
+    const state = makeAutoObservable(stateGenerator());
+    const actions = stateActionsGenerator(state);
+
+    const api = {
+
+    }
+
+    // 初始渲染
+    const init = () => {
+
+    }
+
+    // 状态重置
+    const reset = () => {
+        const initialPageLoading = stateGenerator().pageLoading;
+
+        actions.setPageLoading(initialPageLoading);
+    }
+
+    return {
+        state,
+        init,
+        reset
+    };
+};
+
+export default useWorkbenchStore();

+ 83 - 0
src/pages/knowledgeBase/list/style.less

@@ -0,0 +1,83 @@
+.workbench {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+
+  &-top {
+    margin-bottom: 20px;
+    display: flex;
+
+    &-style {
+      width: 100%;
+      height: 290px;
+      margin-right: 20px;
+
+      &-welcome {
+        width: 100%;
+        height: 130px;
+        padding: 0 20px;
+        background: #FFFFFF;
+        border-radius: @border-radius-base;
+        margin-bottom: 20px;
+        display: flex;
+
+        &-text {
+          width: 30%;
+          display: flex;
+          flex-direction: column;
+          justify-content: center;
+          color: @primary-color;
+
+          &-first {
+            font-size: 20px;
+            font-weight: 500;
+          }
+
+          &-second {
+            font-size: 24px;
+            font-weight: 500;
+          }
+        }
+
+        &-picture {
+          width: 70%;
+
+          img {
+            width: 100%;
+            height: 100%;
+            object-fit: cover;
+            -webkit-user-drag: none;
+          }
+        }
+      }
+
+      &-fast {
+        width: 100%;
+        height: 140px;
+        background: #FFFFFF;
+        border-radius: @border-radius-base;
+      }
+    }
+
+    &-weather {
+      width: 300px;
+      height: 290px;
+      padding: 20px 20px 0;
+      background: #FFFFFF;
+      border-radius: @border-radius-base;
+    }
+  }
+
+  &-bottom {
+    width: 100%;
+    height: 0;
+    flex: 1;
+    padding: 20px;
+    background: #FFFFFF;
+    border-radius: @border-radius-base;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+  }
+}

+ 19 - 0
src/pages/knowledgeBase/list/types.ts

@@ -0,0 +1,19 @@
+// 定义状态
+export type State = {
+    pageLoading: boolean,
+};
+
+// 只读状态
+export type ReadonlyState = Readonly<State>;
+
+// 修改状态
+export type StateAction = {
+    setPageLoading: (loading: boolean) => void,
+};
+
+// 仓库类型
+export type WorkbenchStore = {
+    state: ReadonlyState,
+    init: () => void,
+    reset: () => void,
+};

+ 27 - 0
src/pages/layout/components/Breadcrumb.tsx

@@ -0,0 +1,27 @@
+import * as React from 'react';
+import { Link } from 'react-router-dom';
+import { observer } from 'mobx-react';
+import { Breadcrumb as AntdBreadcrumb } from 'antd';
+import { BreadcrumbProps } from '../types';
+
+const Breadcrumb: React.FC<BreadcrumbProps> = (props: BreadcrumbProps) => {
+    const { routerMatchList } = props;
+
+    const items = routerMatchList.map((item, index) => {
+        const color = (index === 0 || index < routerMatchList.length - 1) ? '#8C8C8C' : '#595959';
+        return {
+            key: index,
+            title: <Link
+                style={{ color: color }}
+                to={item.path}>
+                {item.breadcrumbName}
+            </Link>,
+        }
+    });
+
+    return (
+        <AntdBreadcrumb className='breadcrumb' items={items} />
+    );
+};
+
+export default observer(Breadcrumb);

+ 64 - 0
src/pages/layout/components/Header.tsx

@@ -0,0 +1,64 @@
+import * as React from 'react';
+import { observer } from 'mobx-react';
+import { Layout, MenuProps, Modal, Dropdown } from 'antd';
+import { CaretDownOutlined, PoweroffOutlined } from '@ant-design/icons';
+import logoSrc from '@/assets/public/logo.png';
+import router from '@/router';
+import { HeaderProps } from '../types';
+
+const { Header: AntdHeader } = Layout;
+
+const Header: React.FC<HeaderProps> = (props: HeaderProps) => {
+    const {
+        userName,
+        onClickLogout
+    } = props;
+
+    const items: MenuProps['items'] = [
+        {
+            key: 'logout',
+            label: (
+                <a onClick={() => {
+                    Modal.confirm({
+                        title: '提示',
+                        content: '确定退出平台吗?',
+                        async onOk() {
+                            await onClickLogout();
+                        }
+                    });
+                }}>
+                    <PoweroffOutlined style={{ marginRight: 5 }} />
+                    退出登录
+                </a>
+            ),
+        }
+    ];
+
+    return (
+        <AntdHeader className='header'>
+            <div className='header-logo' onClick={() => {
+                router.navigate({ pathname: '/' });
+            }}>
+                <div className='header-logo-picture'>
+                    <img src={logoSrc} />
+                </div>
+                <div className='header-logo-text'>
+                    建科•小智管理后台
+                </div>
+            </div>
+            <Dropdown menu={{ items }}>
+                <div className='header-operation'>
+                    <div className='header-operation-picture'>
+                        {userName.slice(0, 1)}
+                    </div>
+                    <div className='header-operation-name'>
+                        {userName}
+                    </div>
+                    <CaretDownOutlined className='header-operation-down' />
+                </div>
+            </Dropdown>
+        </AntdHeader>
+    );
+};
+
+export default observer(Header);

+ 73 - 0
src/pages/layout/components/Nav.tsx

@@ -0,0 +1,73 @@
+import * as React from 'react';
+import { observer } from 'mobx-react';
+import { Layout, Menu, MenuProps, Button } from 'antd';
+import { TeamOutlined, MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons';
+import IconFont from '@/components/iconFont';
+import router from '@/router';
+import { NavProps } from '../types';
+
+const Sider = Layout.Sider;
+
+const Nav: React.FC<NavProps> = (props: NavProps) => {
+    const {
+        selectedKey,
+        onChangeSelectedKey,
+        openKeys,
+        onOpenChange,
+        collapsed,
+        onClickCollapsed
+    } = props;
+
+    const items: MenuProps['items'] = [
+        {
+            key: '/questionAnswerApp',
+            icon: <TeamOutlined />,
+            label: '问答应用',
+            onClick: () => { router.navigate({ pathname: '/questionAnswerApp' }) }
+        },
+        {
+            key: '/knowledgeBase',
+            icon: <IconFont name='icon-home' />,
+            label: '知识库',
+            onClick: () => { router.navigate({ pathname: '/knowledgeBase' }) }
+        },
+        {
+            key: '/dataExport',
+            icon: <IconFont name='icon-home' />,
+            label: '数据导出',
+            onClick: () => { router.navigate({ pathname: '/dataExport' }) }
+        }
+    ]
+
+    return (
+        <Sider
+            className='nav'
+            collapsed={collapsed}
+        >
+            <div className='nav-menu'>
+                <Menu
+                    mode='inline'
+                    selectedKeys={[selectedKey]}
+                    onSelect={(item) => {
+                        const menuLevel = item.keyPath.length > 1 ? 2 : 1;
+                        onChangeSelectedKey(item.key, menuLevel);
+                    }}
+                    openKeys={openKeys}
+                    onOpenChange={(keys) => {
+                        // 点击菜单,收起其他展开的所有菜单
+                        const latestOpenKey = keys.find((key) => openKeys.indexOf(key) === -1);
+                        onOpenChange(latestOpenKey ? [latestOpenKey] : []);
+                    }}
+                    items={items}
+                />
+            </div>
+            <div className='nav-bottom'>
+                <Button type='primary' onClick={onClickCollapsed}>
+                    {collapsed ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />}
+                </Button>
+            </div>
+        </Sider>
+    );
+};
+
+export default observer(Nav);

+ 74 - 0
src/pages/layout/index.tsx

@@ -0,0 +1,74 @@
+import * as React from 'react';
+import { useMatches, Outlet } from 'react-router-dom';
+import { observer } from 'mobx-react';
+import { Layout } from 'antd';
+import Header from './components/Header';
+import Nav from './components/Nav';
+import Breadcrumb from './components/Breadcrumb';
+import store from './store';
+import './style.less';
+
+const { Content } = Layout;
+
+const LayoutApp: React.FC = () => {
+    const {
+        state,
+        onClickLogout,
+        onChangeSelectedKey,
+        onOpenChange,
+        onClickCollapsed,
+        init,
+        reset
+    } = store;
+    const {
+        routerMatchList,
+        userName,
+        collapsed,
+        selectedKey,
+        openKeys
+    } = state;
+
+    const matches = useMatches();
+
+    React.useEffect(() => {
+        const list = matches.filter((item: any) => item.handle?.menuLevel && item.handle?.breadcrumbName).map((item: any) => {
+            return {
+                path: item.pathname,
+                menuLevel: item.handle.menuLevel,
+                breadcrumbName: item.handle.breadcrumbName,
+            }
+        });
+        init(list);
+    }, [matches]);
+
+    React.useEffect(() => {
+        return () => reset();
+    }, []);
+
+    return (
+        <Layout style={{ height: '100vh' }}>
+            <Header
+                userName={userName}
+                onClickLogout={onClickLogout}
+            />
+            <Layout>
+                <Nav
+                    selectedKey={selectedKey}
+                    onChangeSelectedKey={onChangeSelectedKey}
+                    openKeys={openKeys}
+                    onOpenChange={onOpenChange}
+                    collapsed={collapsed}
+                    onClickCollapsed={onClickCollapsed}
+                />
+                <Layout>
+                    <Breadcrumb routerMatchList={routerMatchList} />
+                    <Content className='content'>
+                        <Outlet></Outlet>
+                    </Content>
+                </Layout>
+            </Layout>
+        </Layout>
+    );
+};
+
+export default observer(LayoutApp);

+ 128 - 0
src/pages/layout/store.ts

@@ -0,0 +1,128 @@
+import { makeAutoObservable } from 'mobx';
+import { message } from 'antd';
+import { apis } from '@/apis';
+import LocalStorage from '@/LocalStorage';
+import router from '@/router';
+import { State, ReadonlyState, StateAction, LayoutStore } from './types';
+
+// 定义状态
+const stateGenerator = (): ReadonlyState => ({
+    routerMatchList: [],
+    userName: '',
+    collapsed: false,
+    selectedKey: '',
+    openKeys: [],
+});
+
+// 修改状态
+const stateActionsGenerator = (state: State): StateAction => {
+    return {
+        setRouterMatchList: (list) => {
+            state.routerMatchList = list;
+        },
+        setUserName: (userName) => {
+            state.userName = userName;
+        },
+        setCollapsed: (status) => {
+            state.collapsed = status;
+        },
+        setSelectedKey: (key) => {
+            state.selectedKey = key;
+        },
+        setOpenKeys: (openKeys) => {
+            state.openKeys = openKeys;
+        },
+    };
+};
+
+// 使用仓库
+const useLayoutStore = (): LayoutStore => {
+    const state = makeAutoObservable(stateGenerator());
+    const actions = stateActionsGenerator(state);
+
+    const api = {
+        // 退出登录
+        logout: async () => {
+            try {
+                // await layoutApis.logout();
+                LocalStorage.clear();
+                router.navigate({ pathname: '/login' }, { replace: true });
+                message.success('退出成功');
+            } catch (e) {
+                console.error(e);
+            }
+        },
+    }
+
+    // 点击退出登录
+    const onClickLogout = async () => {
+        // 退出登录
+        await api.logout();
+    }
+
+    // 改变选中菜单
+    const onChangeSelectedKey = (path: string, menuLevel: number) => {
+        const firstKey = path.split('/')[1];
+        const secondKey = path.split('/')[2];
+
+        if (menuLevel === 2) {// 选中二级菜单
+            onOpenChange(['/' + firstKey]);
+            actions.setSelectedKey('/' + firstKey + '/' + secondKey);
+        } else {// 选中一级菜单
+            const initialOpenKeys = stateGenerator().openKeys;
+
+            onOpenChange(initialOpenKeys);
+            actions.setSelectedKey('/' + firstKey);
+        }
+    }
+
+    // 打开菜单
+    const onOpenChange = (openKeys: string[]) => {
+        actions.setOpenKeys(openKeys);
+    }
+
+    // 收缩释放菜单
+    const onClickCollapsed = () => {
+        actions.setCollapsed(!state.collapsed);
+    }
+
+    // 初始渲染
+    const init: LayoutStore['init'] = (list) => {
+        const userInfo = LocalStorage.getUserInfo();
+        if (userInfo) {
+            actions.setUserName(userInfo.name);
+        }
+        actions.setRouterMatchList(list);
+        const routerInfo = list[list.length - 1];
+        if (routerInfo) {
+            onChangeSelectedKey(routerInfo.path, routerInfo.menuLevel);
+        }
+    }
+
+    // 状态重置
+    const reset = () => {
+        const initialRouterMatchList = stateGenerator().routerMatchList;
+        const initialUserName = stateGenerator().userName;
+        const initialCollapsed = stateGenerator().collapsed;
+        const initialSelectedKey = stateGenerator().selectedKey;
+        const initialOpenKeys = stateGenerator().openKeys;
+
+        actions.setRouterMatchList(initialRouterMatchList);
+        actions.setUserName(initialUserName);
+        actions.setCollapsed(initialCollapsed);
+        actions.setSelectedKey(initialSelectedKey);
+        actions.setOpenKeys(initialOpenKeys);
+    }
+
+    return {
+        state,
+        onClickLogout,
+        onChangeSelectedKey,
+        onOpenChange,
+        onClickCollapsed,
+        init,
+        reset
+    };
+};
+
+export default useLayoutStore();

+ 102 - 0
src/pages/layout/style.less

@@ -0,0 +1,102 @@
+.header {
+    width: 100%;
+    height: 50px;
+    padding: 0 20px;
+    background: #FFFFFF;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+
+    &-logo {
+        display: flex;
+        align-items: center;
+        cursor: pointer;
+
+        &-picture {
+            width: 30px;
+            height: 30px;
+            background: #FFFFFF;
+            border-radius: @border-radius-base;
+            overflow: hidden;
+            margin-right: 10px;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+
+            img {
+                width: 30px;
+                height: 30px;
+            }
+        }
+
+        &-text {
+            font-weight: 500;
+        }
+    }
+
+    &-operation {
+        display: flex;
+        align-items: center;
+        cursor: pointer;
+
+        &-picture {
+            width: 30px;
+            height: 30px;
+            background: @primary-color;
+            border-radius: 50%;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            margin-right: 10px;
+            color: #FFFFFF;
+        }
+
+        &-name {
+            font-weight: 500;
+            color: @primary-color;
+            margin-right: 10px;
+        }
+
+        &-down {
+            color: @primary-color !important;
+        }
+    }
+}
+
+.nav {
+    width: 200px !important;
+    height: calc(100vh - 50px) !important;
+    background: #FFFFFF !important;
+
+    &-menu {
+        width: 100%;
+        height: calc(100vh - 100px);
+        overflow-x: hidden;
+        overflow-y: auto;
+    }
+
+    &-bottom {
+        width: 100%;
+        height: 50px;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+    }
+}
+
+.breadcrumb {
+    width: 100%;
+    height: 48px;
+    padding: 20px;
+    background: @background-color;
+    display: flex;
+    align-items: center;
+}
+
+.content {
+    width: 100%;
+    height: 100%;
+    padding: 0 20px 20px 20px;
+    background: @background-color;
+    overflow: auto;
+}

+ 54 - 0
src/pages/layout/types.ts

@@ -0,0 +1,54 @@
+// 定义状态
+export type State = {
+    routerMatchList: {
+        path: string,
+        menuLevel: number,
+        breadcrumbName: string,
+    }[],
+    userName: string,
+    collapsed: boolean,
+    selectedKey: string,
+    openKeys: string[],
+};
+
+// 只读状态
+export type ReadonlyState = Readonly<State>;
+
+// 修改状态
+export type StateAction = {
+    setRouterMatchList: (list: State['routerMatchList']) => void,
+    setUserName: (userName: string) => void,
+    setCollapsed: (status: boolean) => void,
+    setSelectedKey: (key: string) => void,
+    setOpenKeys: (openKeys: string[]) => void,
+};
+
+// 仓库类型
+export type LayoutStore = {
+    state: ReadonlyState,
+    onClickLogout: () => Promise<any>,
+    onChangeSelectedKey: (path: string, menuLevel: number) => void,
+    onOpenChange: (openKeys: string[]) => void,
+    onClickCollapsed: () => void,
+    init: (list: State['routerMatchList']) => void,
+    reset: () => void,
+};
+
+/* 组件类型 */
+export type HeaderProps = {
+    userName: string,
+    onClickLogout: () => Promise<any>,
+};
+
+export type NavProps = {
+    selectedKey: string,
+    onChangeSelectedKey: (path: string, menuLevel: number) => void,
+    openKeys: string[],
+    onOpenChange: (openKeys: string[]) => void,
+    collapsed: boolean,
+    onClickCollapsed: () => void,
+};
+
+export type BreadcrumbProps = {
+    routerMatchList: State['routerMatchList'],
+};

+ 18 - 0
src/pages/login/components/Copyright.tsx

@@ -0,0 +1,18 @@
+import * as React from 'react';
+import dayjs from 'dayjs';
+
+const Copyright: React.FC = () => {
+	// 公司名称
+	const companyName = '上海建科';
+
+	// 今年
+	const currentYear = dayjs().format('YYYY');
+
+	return (
+		<div className='login-right-copyright'>
+			{companyName} 版权所有CopyRight &copy; {currentYear} ALL RIGHTS RESERVED
+		</div>
+	);
+};
+
+export default Copyright;

+ 112 - 0
src/pages/login/index.tsx

@@ -0,0 +1,112 @@
+import * as React from 'react';
+import { observer } from 'mobx-react';
+import { Form, Input, Checkbox, Button } from 'antd';
+import Copyright from './components/Copyright';
+import backgroundSrc from '@/assets/login/background.jpg';
+import { regex } from '@/utils';
+import store from './store';
+import './style.less';
+
+const FormItem = Form.Item;
+
+const LoginApp: React.FC = () => {
+    const {
+        state,
+        onChangeRemember,
+        onClickLogin,
+        init,
+        reset
+    } = store;
+    const {
+        rememberChecked,
+        buttonLoading
+    } = state;
+
+    const [form] = Form.useForm();
+
+    React.useEffect(() => {
+        init(form);
+        return () => reset();
+    }, []);
+
+    // 检查密码
+    const checkPassword = (rule: any, value: string) => {
+        if (value) {
+            const passwordRegex = new RegExp(regex.password);
+            if (passwordRegex.test(value)) {
+                return Promise.resolve();
+            } else {
+                return Promise.reject('密码格式不正确');
+            }
+        } else {
+            return Promise.reject('密码不能为空');
+        }
+    };
+
+    return (
+        <div className='login'>
+            <div className='login-left'>
+                <img src={backgroundSrc} />
+            </div>
+            <div className='login-right'>
+                <div className='login-right-content'>
+                    <div className='login-right-content-title'>
+                        <span className='login-right-content-title-text'>
+                            平台登录
+                        </span>
+                    </div>
+                    <Form form={form}>
+                        <div style={{ height: 70 }}>
+                            <FormItem
+                                name='account'
+                                rules={[{ required: true, message: '账号不能为空', whitespace: true }]}
+                            >
+                                <Input size='large' placeholder='请输入账号' />
+                            </FormItem>
+                        </div>
+                        <div style={{ height: 70 }}>
+                            <FormItem
+                                name='password'
+                                rules={[{ validator: checkPassword, required: true }]}
+                            >
+                                <Input.Password size='large' placeholder='请输入密码' />
+                            </FormItem>
+                        </div>
+                        <Checkbox
+                            style={{ marginBottom: 30 }}
+                            checked={rememberChecked}
+                            onChange={(e) => {
+                                const checked = e.target.checked;
+                                onChangeRemember(checked);
+                            }}
+                        >
+                            记住密码
+                        </Checkbox>
+                        <Button
+                            style={{ width: '100%' }}
+                            type='primary'
+                            size='large'
+                            loading={buttonLoading}
+                            onClick={() => {
+                                form.validateFields().then(async (values) => {
+                                    const data = {
+                                        phone_number: values.account,
+                                        password: values.password
+                                    }
+                                    await onClickLogin(data);
+                                }).catch((error) => {
+                                    console.error(error);
+                                });
+                            }}
+                        >
+                            登录
+                        </Button>
+                    </Form>
+                </div>
+                <Copyright />
+            </div>
+        </div>
+    );
+};
+
+export default observer(LoginApp);

+ 110 - 0
src/pages/login/store.tsx

@@ -0,0 +1,110 @@
+import { makeAutoObservable } from 'mobx';
+import { message } from 'antd';
+import { apis, LoginApiParams } from '@/apis';
+import LocalStorage from '@/LocalStorage';
+import router from '@/router';
+import { State, ReadonlyState, StateAction, LoginStore } from './types';
+
+// 定义状态
+const stateGenerator = (): ReadonlyState => ({
+    rememberChecked: false,
+    buttonLoading: false,
+});
+
+// 修改状态
+const stateActionsGenerator = (state: State): StateAction => {
+    return {
+        setRememberChecked: (checked) => {
+            state.rememberChecked = checked;
+        },
+        setButtonLoading: (loading) => {
+            state.buttonLoading = loading;
+        },
+    };
+};
+
+// 使用仓库
+const useLoginStore = (): LoginStore => {
+    const state = makeAutoObservable(stateGenerator());
+    const actions = stateActionsGenerator(state);
+
+    const api = {
+        // 登录
+        login: async (data: LoginApiParams) => {
+            actions.setButtonLoading(true);
+            try {
+                // const res = await apis.login(data);
+                const res = {
+                    data: {
+                        token: '123',
+                        user_id: 1,
+                        user_name: '123',
+                    },
+                }
+                const info = res.data;
+                LocalStorage.setToken(info.token);
+                LocalStorage.setUserInfo({
+                    id: info.user_id,
+                    name: info.user_name,
+                });
+                if (state.rememberChecked) {// 记住密码
+                    LocalStorage.setAccountPassword({
+                        account: data.phone_number,
+                        password: data.password,
+                    });
+                } else {// 不记住密码
+                    LocalStorage.setAccountPassword(undefined);
+                }
+                router.navigate({ pathname: '/' }, { replace: true });
+                message.success('登录成功');
+            } catch (error: any) {
+                LocalStorage.clear();
+                message.error(error.msg);
+            } finally {
+                actions.setButtonLoading(false);
+            }
+        },
+    }
+
+    // 更改记住密码
+    const onChangeRemember: LoginStore['onChangeRemember'] = (checked) => {
+        actions.setRememberChecked(checked);
+    }
+
+    // 点击登录
+    const onClickLogin: LoginStore['onClickLogin'] = async (data) => {
+        // 登录
+        await api.login(data);
+    }
+
+    // 初始渲染
+    const init: LoginStore['init'] = (form) => {
+        const accountPassword = LocalStorage.getAccountPassword();
+        if (accountPassword) {
+            form.setFieldsValue({
+                account: accountPassword.account,
+                password: accountPassword.password,
+            });
+            actions.setRememberChecked(true);
+        }
+    }
+
+    // 状态重置
+    const reset: LoginStore['reset'] = () => {
+        const initialRememberChecked = stateGenerator().rememberChecked;
+        const initialButtonLoading = stateGenerator().buttonLoading;
+
+        actions.setRememberChecked(initialRememberChecked);
+        actions.setButtonLoading(initialButtonLoading);
+    }
+
+    return {
+        state,
+        onChangeRemember,
+        onClickLogin,
+        init,
+        reset
+    };
+};
+
+export default useLoginStore();

+ 50 - 0
src/pages/login/style.less

@@ -0,0 +1,50 @@
+.login {
+    width: 100%;
+    height: 100%;
+    display: flex;
+
+    &-left {
+        width: 50%;
+
+        img {
+            width: 100%;
+            height: 100%;
+            object-fit: cover;
+        }
+    }
+
+    &-right {
+        width: 50%;
+        display: flex;
+        flex-direction: column;
+        justify-content: center;
+        align-items: center;
+        position: relative;
+
+        &-content {
+            width: 50%;
+
+            &-title {
+                margin-bottom: 50px;
+
+                &-text {
+                    font-size: 24px;
+                    color: @primary-color;
+                    border-bottom: 2px solid @primary-color;
+                    background: linear-gradient(to bottom, #FFFFFF 50%, #b2cbf4 50%);
+                }
+            }
+        }
+
+        &-copyright {
+            width: 100%;
+            font-size: 12px;
+            color: #C0C3CC;
+            display: flex;
+            justify-content: center;
+            position: absolute;
+            bottom: 20px;
+            left: 0;
+        }
+    }
+}

+ 26 - 0
src/pages/login/types.ts

@@ -0,0 +1,26 @@
+import { FormInstance } from 'antd';
+import { LoginApiParams } from '@/apis';
+
+// 定义状态
+export type State = {
+    rememberChecked: boolean,
+    buttonLoading: boolean,
+};
+
+// 只读状态
+export type ReadonlyState = Readonly<State>;
+
+// 修改状态
+export type StateAction = {
+    setRememberChecked: (checked: State['rememberChecked']) => void,
+    setButtonLoading: (loading: State['buttonLoading']) => void,
+};
+
+// 仓库类型
+export type LoginStore = {
+    state: ReadonlyState,
+    onChangeRemember: (checked: boolean) => void,
+    onClickLogin: (data: LoginApiParams) => Promise<any>,
+    init: (form: FormInstance) => void,
+    reset: () => void,
+};

+ 44 - 0
src/pages/questionAnswerApp/info/index.tsx

@@ -0,0 +1,44 @@
+import * as React from 'react';
+import { observer } from 'mobx-react';
+import store from './store';
+import './style.less';
+
+const WorkbenchApp: React.FC = () => {
+    const {
+        state,
+        init,
+        reset
+    } = store;
+    const {
+        pageLoading
+    } = state;
+
+    React.useEffect(() => {
+        init();
+        return () => reset();
+    }, []);
+
+    return (
+        <div className='workbench'>
+            <div className='workbench-top'>
+                <div className='workbench-top-style'>
+                    <div className='workbench-top-style-welcome'>
+                        <div className='workbench-top-style-welcome-text'>
+                        
+                        </div>
+                        <div className='workbench-top-style-welcome-picture'>
+
+                        </div>
+                    </div>
+                    <div className='workbench-top-style-fast'></div>
+                </div>
+                <div className='workbench-top-weather'>
+
+                </div>
+            </div>
+            <div className='workbench-bottom'></div>
+        </div>
+    );
+};
+
+export default observer(WorkbenchApp);

+ 47 - 0
src/pages/questionAnswerApp/info/store.ts

@@ -0,0 +1,47 @@
+import { makeAutoObservable } from 'mobx';
+import { apis } from '@/apis';
+import { State, ReadonlyState, StateAction, WorkbenchStore } from './types';
+
+// 定义状态
+const stateGenerator = (): ReadonlyState => ({
+    pageLoading: false,
+});
+
+// 修改状态
+const stateActionsGenerator = (state: State): StateAction => {
+    return {
+        setPageLoading: (loading) => {
+            state.pageLoading = loading;
+        },
+    };
+};
+
+// 使用仓库
+const useWorkbenchStore = (): WorkbenchStore => {
+    const state = makeAutoObservable(stateGenerator());
+    const actions = stateActionsGenerator(state);
+
+    const api = {
+
+    }
+
+    // 初始渲染
+    const init = () => {
+
+    }
+
+    // 状态重置
+    const reset = () => {
+        const initialPageLoading = stateGenerator().pageLoading;
+
+        actions.setPageLoading(initialPageLoading);
+    }
+
+    return {
+        state,
+        init,
+        reset
+    };
+};
+
+export default useWorkbenchStore();

+ 83 - 0
src/pages/questionAnswerApp/info/style.less

@@ -0,0 +1,83 @@
+.workbench {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+
+  &-top {
+    margin-bottom: 20px;
+    display: flex;
+
+    &-style {
+      width: 100%;
+      height: 290px;
+      margin-right: 20px;
+
+      &-welcome {
+        width: 100%;
+        height: 130px;
+        padding: 0 20px;
+        background: #FFFFFF;
+        border-radius: @border-radius-base;
+        margin-bottom: 20px;
+        display: flex;
+
+        &-text {
+          width: 30%;
+          display: flex;
+          flex-direction: column;
+          justify-content: center;
+          color: @primary-color;
+
+          &-first {
+            font-size: 20px;
+            font-weight: 500;
+          }
+
+          &-second {
+            font-size: 24px;
+            font-weight: 500;
+          }
+        }
+
+        &-picture {
+          width: 70%;
+
+          img {
+            width: 100%;
+            height: 100%;
+            object-fit: cover;
+            -webkit-user-drag: none;
+          }
+        }
+      }
+
+      &-fast {
+        width: 100%;
+        height: 140px;
+        background: #FFFFFF;
+        border-radius: @border-radius-base;
+      }
+    }
+
+    &-weather {
+      width: 300px;
+      height: 290px;
+      padding: 20px 20px 0;
+      background: #FFFFFF;
+      border-radius: @border-radius-base;
+    }
+  }
+
+  &-bottom {
+    width: 100%;
+    height: 0;
+    flex: 1;
+    padding: 20px;
+    background: #FFFFFF;
+    border-radius: @border-radius-base;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+  }
+}

+ 19 - 0
src/pages/questionAnswerApp/info/types.ts

@@ -0,0 +1,19 @@
+// 定义状态
+export type State = {
+    pageLoading: boolean,
+};
+
+// 只读状态
+export type ReadonlyState = Readonly<State>;
+
+// 修改状态
+export type StateAction = {
+    setPageLoading: (loading: boolean) => void,
+};
+
+// 仓库类型
+export type WorkbenchStore = {
+    state: ReadonlyState,
+    init: () => void,
+    reset: () => void,
+};

+ 44 - 0
src/pages/questionAnswerApp/list/index.tsx

@@ -0,0 +1,44 @@
+import * as React from 'react';
+import { observer } from 'mobx-react';
+import store from './store';
+import './style.less';
+
+const WorkbenchApp: React.FC = () => {
+    const {
+        state,
+        init,
+        reset
+    } = store;
+    const {
+        pageLoading
+    } = state;
+
+    React.useEffect(() => {
+        init();
+        return () => reset();
+    }, []);
+
+    return (
+        <div className='workbench'>
+            <div className='workbench-top'>
+                <div className='workbench-top-style'>
+                    <div className='workbench-top-style-welcome'>
+                        <div className='workbench-top-style-welcome-text'>
+                        
+                        </div>
+                        <div className='workbench-top-style-welcome-picture'>
+
+                        </div>
+                    </div>
+                    <div className='workbench-top-style-fast'></div>
+                </div>
+                <div className='workbench-top-weather'>
+
+                </div>
+            </div>
+            <div className='workbench-bottom'></div>
+        </div>
+    );
+};
+
+export default observer(WorkbenchApp);

+ 47 - 0
src/pages/questionAnswerApp/list/store.ts

@@ -0,0 +1,47 @@
+import { makeAutoObservable } from 'mobx';
+import { apis } from '@/apis';
+import { State, ReadonlyState, StateAction, WorkbenchStore } from '../types';
+
+// 定义状态
+const stateGenerator = (): ReadonlyState => ({
+    pageLoading: false,
+});
+
+// 修改状态
+const stateActionsGenerator = (state: State): StateAction => {
+    return {
+        setPageLoading: (loading) => {
+            state.pageLoading = loading;
+        },
+    };
+};
+
+// 使用仓库
+const useWorkbenchStore = (): WorkbenchStore => {
+    const state = makeAutoObservable(stateGenerator());
+    const actions = stateActionsGenerator(state);
+
+    const api = {
+
+    }
+
+    // 初始渲染
+    const init = () => {
+
+    }
+
+    // 状态重置
+    const reset = () => {
+        const initialPageLoading = stateGenerator().pageLoading;
+
+        actions.setPageLoading(initialPageLoading);
+    }
+
+    return {
+        state,
+        init,
+        reset
+    };
+};
+
+export default useWorkbenchStore();

+ 83 - 0
src/pages/questionAnswerApp/list/style.less

@@ -0,0 +1,83 @@
+.workbench {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+
+  &-top {
+    margin-bottom: 20px;
+    display: flex;
+
+    &-style {
+      width: 100%;
+      height: 290px;
+      margin-right: 20px;
+
+      &-welcome {
+        width: 100%;
+        height: 130px;
+        padding: 0 20px;
+        background: #FFFFFF;
+        border-radius: @border-radius-base;
+        margin-bottom: 20px;
+        display: flex;
+
+        &-text {
+          width: 30%;
+          display: flex;
+          flex-direction: column;
+          justify-content: center;
+          color: @primary-color;
+
+          &-first {
+            font-size: 20px;
+            font-weight: 500;
+          }
+
+          &-second {
+            font-size: 24px;
+            font-weight: 500;
+          }
+        }
+
+        &-picture {
+          width: 70%;
+
+          img {
+            width: 100%;
+            height: 100%;
+            object-fit: cover;
+            -webkit-user-drag: none;
+          }
+        }
+      }
+
+      &-fast {
+        width: 100%;
+        height: 140px;
+        background: #FFFFFF;
+        border-radius: @border-radius-base;
+      }
+    }
+
+    &-weather {
+      width: 300px;
+      height: 290px;
+      padding: 20px 20px 0;
+      background: #FFFFFF;
+      border-radius: @border-radius-base;
+    }
+  }
+
+  &-bottom {
+    width: 100%;
+    height: 0;
+    flex: 1;
+    padding: 20px;
+    background: #FFFFFF;
+    border-radius: @border-radius-base;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+  }
+}

+ 19 - 0
src/pages/questionAnswerApp/list/types.ts

@@ -0,0 +1,19 @@
+// 定义状态
+export type State = {
+    pageLoading: boolean,
+};
+
+// 只读状态
+export type ReadonlyState = Readonly<State>;
+
+// 修改状态
+export type StateAction = {
+    setPageLoading: (loading: boolean) => void,
+};
+
+// 仓库类型
+export type WorkbenchStore = {
+    state: ReadonlyState,
+    init: () => void,
+    reset: () => void,
+};

+ 152 - 0
src/router.tsx

@@ -0,0 +1,152 @@
+import { lazy, Suspense } from 'react';
+import { RouteObject, Navigate, createBrowserRouter, useLocation } from 'react-router-dom';
+import { Spin } from 'antd';
+import LocalStorage from '@/LocalStorage';
+
+// 按需加载
+const lazyLoad = (loader: () => Promise<any>) => {
+    const Component = lazy(loader);
+
+    const Loading: React.FC = () => {
+        return (
+            <div className='router-lazyLoad'>
+                <Spin />
+            </div>
+        )
+    }
+
+    return (
+        <Suspense fallback={<Loading />}>
+            <Component />
+        </Suspense>
+    );
+};
+
+// React-Router-Dom@v6 路由表
+const routerList: RouteObject[] = [
+    {
+        path: '/',
+        element: lazyLoad(() => import('@/pages/layout/index')),
+        children: [
+            {
+                index: true,
+                element: <Navigate to='/questionAnswerApp' />,
+            },
+            {   /* 问答应用 */
+                path: '/questionAnswerApp',
+                handle: {
+                    menuLevel: 1,
+                    breadcrumbName: '问答应用',
+                },
+                children: [
+                    {
+                        index: true,
+                        element: lazyLoad(() => import('@/pages/questionAnswerApp/list/index')),
+                    },
+                    {   /* 问答应用-创建应用 */
+                        path: '/questionAnswerApp/create',
+                        handle: {
+                            menuLevel: 1,
+                            breadcrumbName: '创建应用',
+                        },
+                        element: lazyLoad(() => import('@/pages/questionAnswerApp/info/index')),
+                    },
+                    {   /* 问答应用-修改应用 */
+                        path: '/questionAnswerApp/modify',
+                        handle: {
+                            menuLevel: 1,
+                            breadcrumbName: '修改应用',
+                        },
+                        element: lazyLoad(() => import('@/pages/questionAnswerApp/info/index')),
+                    },
+                ]
+            },
+            {   /* 知识库 */
+                path: '/knowledgeBase',
+                handle: {
+                    menuLevel: 1,
+                    breadcrumbName: '知识库',
+                },
+                children: [
+                    {
+                        index: true,
+                        element: lazyLoad(() => import('@/pages/knowledgeBase/list/index')),
+                    },
+                    {   /* 知识库-创建知识库 */
+                        path: '/knowledgeBase/create',
+                        handle: {
+                            menuLevel: 1,
+                            breadcrumbName: '创建知识库',
+                        },
+                        element: lazyLoad(() => import('@/pages/knowledgeBase/info/index')),
+                    },
+                    {   /* 知识库-修改知识库 */
+                        path: '/knowledgeBase/modify',
+                        handle: {
+                            menuLevel: 1,
+                            breadcrumbName: '修改知识库',
+                        },
+                        element: lazyLoad(() => import('@/pages/knowledgeBase/info/index')),
+                    },
+                ]
+            },
+            {   /* 数据导出 */
+                path: '/dataExport',
+                handle: {
+                    menuLevel: 1,
+                    breadcrumbName: '数据导出',
+                },
+                element: lazyLoad(() => import('@/pages/dataExport/index')),
+            },
+            {   /* 404 */
+                path: '/404',
+                element: lazyLoad(() => import('@/components/404/index')),
+            },
+            {   /* 路由不存在重定向404 */
+                path: '/*',
+                element: <Navigate to='/404' replace={true} />,
+            },
+        ]
+    },
+    {   /* 登录 */
+        path: '/login',
+        element: lazyLoad(() => import('@/pages/login/index')),
+    }
+]
+
+// 路由模式-浏览器路由
+const router = createBrowserRouter(routerList);
+
+// 路由白名单
+const whiteList = ['/login'];
+
+// 前置路由
+router.routes.forEach((route: any) => {
+    interface RouterComponentProps {
+        component?: React.ReactNode,
+    }
+    // 路由组件-路由鉴权
+    function RouterComponent(props: RouterComponentProps) {
+        const { component } = props;
+
+        const location = useLocation();
+        const path = location.pathname;
+
+        if (LocalStorage.getToken()) {// 已登录
+            if (whiteList.includes(path)) {
+                return <Navigate to='/404' replace={true} />
+            } else {
+                return <>{component}</>
+            }
+        } else {// 未登录
+            if (whiteList.includes(path)) {
+                return <>{component}</>
+            } else {
+                return <Navigate to='/login' replace={true} />
+            }
+        }
+    }
+    route.element = <RouterComponent component={route.element} />
+});
+
+export default router;

+ 103 - 0
src/style/global.less

@@ -0,0 +1,103 @@
+@primary-color: #0052D9;
+@success-color: #52C41A;
+@warning-color: #FAAD14;
+@error-color: #FF4D4F;
+@gray-color: #B2B8C0;
+@text-color: #303133;
+@border-color: #DCDFE6;
+@background-color: #F7F8FA;
+@font-size-base: 14px;
+@border-radius-base: 4px;
+
+*,
+*::before,
+*::after {
+    box-sizing: border-box;
+}
+
+html,
+body {
+    width: 100%;
+    height: 100%;
+    padding: 0;
+    margin: 0;
+}
+
+#root {
+    height: 100%;
+    width: 100%;
+    font-size: @font-size-base;
+    color: @text-color;
+    // Ant-Design主题-属性
+    --primary-color: @primary-color;
+    --text-color: @text-color;
+    --border-radius: @border-radius-base;
+}
+
+a,
+a:hover,
+a:active {
+    cursor: pointer;
+    font-size: @font-size-base;
+    color: @primary-color;
+    text-decoration: none;
+}
+
+ul {
+    margin: 0;
+    padding: 0;
+}
+
+ul li {
+    list-style-type: none;
+}
+
+.text-primary,
+.text-primary:hover {
+    color: @primary-color;
+}
+
+.text-success,
+.text-success:hover {
+    color: @success-color;
+}
+
+.text-warning,
+.text-warning:hover {
+    color: @warning-color;
+}
+
+.text-error,
+.text-error:hover {
+    color: @error-color;
+}
+
+.text-gray,
+.text-gray:hover {
+    color: @gray-color;
+    cursor: not-allowed;
+}
+
+.router-lazyLoad {
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%, -50%);
+}
+
+// Ant-Design主题
+.ant-menu-inline {
+    border: none !important;
+}
+
+.ant-menu-inline-collapsed {
+    border: none !important;
+}
+
+.ant-form-item {
+    margin-bottom: 16px !important;
+}
+
+.ant-image-img {
+    object-fit: cover;
+}

+ 6 - 0
src/typings/images.d.ts

@@ -0,0 +1,6 @@
+// 导入图片格式
+declare module '*.png';
+declare module '*.jpg';
+declare module '*.jpeg';
+declare module '*.gif';
+declare module '*.svg';

+ 37 - 0
src/utils/index.ts

@@ -0,0 +1,37 @@
+// 正则表达式
+export const regex = {
+    phoneNumber: /^1[13456789]\d{9}$/,// 手机号码
+    password: /^[a-zA-Z0-9]{6,16}$/,// 密码
+    email: /^([a-zA-Z0-9_\.\-])+@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/,// 电子邮箱
+}
+
+// 函数防抖
+export const debounce = (func: Function, interval?: number) => {
+    let timer: any;
+    const time = interval || 200;// 间隔时间默认0.2秒
+    return function (this: object, ...args: any[]) {
+        clearTimeout(timer);
+        timer = setTimeout(() => {
+            func.call(this, args);
+        }, time);
+    };
+}
+
+// 下载Excel
+export const downloadExcel = (url: string) => {
+    const elementA = document.createElement('a');
+    elementA.setAttribute('href', url);
+    elementA.style.display = 'none';
+    document.body.appendChild(elementA);
+    elementA.click();
+    document.body.removeChild(elementA);
+}
+
+// 模拟异步
+export const promise = (response: any, time: number): Promise<any> => {
+    return new Promise((resolve, reject) => {
+        setTimeout(() => {
+            resolve(response);
+        }, time * 1000);
+    });
+}

+ 36 - 0
tsconfig.json

@@ -0,0 +1,36 @@
+{
+  "compilerOptions": {
+    "target": "ESNext", // 目标语言版本
+    "module": "ESNext", // 生成代码的模板标准
+    "moduleResolution": "Node", // Node模块解析
+    "strict": true, // 启用严格模式
+    "jsx": "react-jsx", // jsx模板解析
+    // 引用的库
+    "lib": [
+      "DOM",
+      "ESNext"
+    ],
+    // 类型声明
+    "types": [
+      "vite/client"
+    ],
+    "esModuleInterop": true, // 通过为所有导入模块创建命名空间对象
+    "resolveJsonModule": true, // 允许导入.json文件
+    "baseUrl": "./", // 解析非相对模块的根地址
+    "paths": {
+      "@/*": [
+        "src/*"
+      ],
+    }
+  },
+  // 指定匹配列表
+  "include": [
+    "src",
+    "vite.config.ts"
+  ],
+  // 忽略文件列表
+  "exclude": [
+    "node_modules",
+    "build"
+  ]
+}

+ 69 - 0
vite.config.ts

@@ -0,0 +1,69 @@
+import { defineConfig, loadEnv } from 'vite';
+import path from 'path';
+import react from '@vitejs/plugin-react';
+
+export default defineConfig(({ mode, command }) => {
+  const env = loadEnv(mode, path.join(process.cwd(), 'env'));
+  return {
+    envDir: './env',// 环境目录
+    css: {
+      preprocessorOptions: {
+        less: {// 全局导入
+          charset: false,
+          additionalData: '@import "@/style/global.less";',
+        }
+      }
+    },
+    resolve: {
+      // 别名
+      alias: [
+        {
+          find: '@',
+          replacement: path.resolve(__dirname, 'src'),
+        }
+      ],
+      // 忽略文件后缀名
+      extensions: ['.js', '.jsx', '.ts', '.tsx', '.less', '.json']
+    },
+    server: {
+      // 监听所有地址
+      host: '0.0.0.0',
+      // 端口号
+      port: 3100,
+      // 自动打开浏览器
+      open: true,
+      // 热更新
+      hmr: true,
+      // 自动更换可用端口
+      strictPort: false,
+      // 代理规则
+      proxy: {
+        '/api': {
+          // 开启跨域
+          changeOrigin: true,
+          // 转发地址
+          target: env.VITE_API_URL,
+          // 路径重写
+          rewrite: (path) => path.replace(/^\/api/, ''),
+        },
+      }
+    },
+    build: {
+      outDir: 'build',// 打包文件目录
+      chunkSizeWarningLimit: 10240,// chunk大于10M触发警告
+      // 底层配置
+      rollupOptions: {
+        output: {
+          entryFileNames: 'js/[name]-[hash].js',
+          chunkFileNames: 'js/[name]-[hash].js',
+        }
+      },
+    },
+    esbuild: {
+      drop: command === 'build' ? ['console', 'debugger'] : [],
+    },
+    plugins: [
+      [react()],// React编译
+    ],
+  }
+})