feat: add Login and fix res error

This commit is contained in:
xion 2024-09-29 01:40:51 +08:00
parent 77485b34c0
commit 029710f31c
18 changed files with 178 additions and 118 deletions

View File

@ -18,7 +18,7 @@
"@ant-design/icons": "^5.5.1", "@ant-design/icons": "^5.5.1",
"@icon-park/react": "^1.4.2", "@icon-park/react": "^1.4.2",
"@kevisual/codemirror": "^0.0.2", "@kevisual/codemirror": "^0.0.2",
"@kevisual/query": "^0.0.2", "@kevisual/query": "^0.0.6",
"@kevisual/ui": "^0.0.2", "@kevisual/ui": "^0.0.2",
"@uiw/react-textarea-code-editor": "^3.0.2", "@uiw/react-textarea-code-editor": "^3.0.2",
"@xyflow/react": "^12.3.1", "@xyflow/react": "^12.3.1",
@ -46,8 +46,8 @@
"@tailwindcss/typography": "^0.5.15", "@tailwindcss/typography": "^0.5.15",
"@types/d3": "^7.4.3", "@types/d3": "^7.4.3",
"@types/lodash-es": "^4.17.12", "@types/lodash-es": "^4.17.12",
"@types/node": "^22.7.2", "@types/node": "^22.7.4",
"@types/react": "^18.3.9", "@types/react": "^18.3.10",
"@types/react-dom": "^18.3.0", "@types/react-dom": "^18.3.0",
"@vitejs/plugin-react": "^4.3.1", "@vitejs/plugin-react": "^4.3.1",
"autoprefixer": "^10.4.20", "autoprefixer": "^10.4.20",

82
pnpm-lock.yaml generated
View File

@ -13,7 +13,7 @@ importers:
version: 0.0.1-alpha.9(@emotion/css@11.13.0)(crypto-js@4.2.0)(eventemitter3@5.0.1) version: 0.0.1-alpha.9(@emotion/css@11.13.0)(crypto-js@4.2.0)(eventemitter3@5.0.1)
'@abearxiong/flows': '@abearxiong/flows':
specifier: 0.0.1-alpha.9 specifier: 0.0.1-alpha.9
version: 0.0.1-alpha.9(@xyflow/react@12.3.1(@types/react@18.3.9)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(zustand@4.5.5(@types/react@18.3.9)(immer@10.1.1)(react@18.3.1)) version: 0.0.1-alpha.9(@xyflow/react@12.3.1(@types/react@18.3.10)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(zustand@4.5.5(@types/react@18.3.10)(immer@10.1.1)(react@18.3.1))
'@abearxiong/ui': '@abearxiong/ui':
specifier: 0.0.1-alpha.0 specifier: 0.0.1-alpha.0
version: 0.0.1-alpha.0 version: 0.0.1-alpha.0
@ -27,8 +27,8 @@ importers:
specifier: ^0.0.2 specifier: ^0.0.2
version: 0.0.2 version: 0.0.2
'@kevisual/query': '@kevisual/query':
specifier: ^0.0.2 specifier: ^0.0.6
version: 0.0.2 version: 0.0.6
'@kevisual/ui': '@kevisual/ui':
specifier: ^0.0.2 specifier: ^0.0.2
version: 0.0.2 version: 0.0.2
@ -37,7 +37,7 @@ importers:
version: 3.0.2(@babel/runtime@7.25.6)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) version: 3.0.2(@babel/runtime@7.25.6)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@xyflow/react': '@xyflow/react':
specifier: ^12.3.1 specifier: ^12.3.1
version: 12.3.1(@types/react@18.3.9)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) version: 12.3.1(@types/react@18.3.10)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
antd: antd:
specifier: ^5.21.1 specifier: ^5.21.1
version: 5.21.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) version: 5.21.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@ -85,10 +85,10 @@ importers:
version: 10.0.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) version: 10.0.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
vite-plugin-tsconfig-paths: vite-plugin-tsconfig-paths:
specifier: ^1.4.1 specifier: ^1.4.1
version: 1.4.1(typescript@5.6.2)(vite@5.4.8(@types/node@22.7.2)) version: 1.4.1(typescript@5.6.2)(vite@5.4.8(@types/node@22.7.4))
zustand: zustand:
specifier: ^4.5.5 specifier: ^4.5.5
version: 4.5.5(@types/react@18.3.9)(immer@10.1.1)(react@18.3.1) version: 4.5.5(@types/react@18.3.10)(immer@10.1.1)(react@18.3.1)
devDependencies: devDependencies:
'@eslint/js': '@eslint/js':
specifier: ^9.11.1 specifier: ^9.11.1
@ -96,9 +96,6 @@ importers:
'@tailwindcss/aspect-ratio': '@tailwindcss/aspect-ratio':
specifier: ^0.4.2 specifier: ^0.4.2
version: 0.4.2(tailwindcss@3.4.13) version: 0.4.2(tailwindcss@3.4.13)
'@tailwindcss/line-clamp':
specifier: ^0.4.4
version: 0.4.4(tailwindcss@3.4.13)
'@tailwindcss/typography': '@tailwindcss/typography':
specifier: ^0.5.15 specifier: ^0.5.15
version: 0.5.15(tailwindcss@3.4.13) version: 0.5.15(tailwindcss@3.4.13)
@ -109,17 +106,17 @@ importers:
specifier: ^4.17.12 specifier: ^4.17.12
version: 4.17.12 version: 4.17.12
'@types/node': '@types/node':
specifier: ^22.7.2 specifier: ^22.7.4
version: 22.7.2 version: 22.7.4
'@types/react': '@types/react':
specifier: ^18.3.9 specifier: ^18.3.10
version: 18.3.9 version: 18.3.10
'@types/react-dom': '@types/react-dom':
specifier: ^18.3.0 specifier: ^18.3.0
version: 18.3.0 version: 18.3.0
'@vitejs/plugin-react': '@vitejs/plugin-react':
specifier: ^4.3.1 specifier: ^4.3.1
version: 4.3.1(vite@5.4.8(@types/node@22.7.2)) version: 4.3.1(vite@5.4.8(@types/node@22.7.4))
autoprefixer: autoprefixer:
specifier: ^10.4.20 specifier: ^10.4.20
version: 10.4.20(postcss@8.4.47) version: 10.4.20(postcss@8.4.47)
@ -158,7 +155,7 @@ importers:
version: 8.7.0(eslint@9.11.1(jiti@1.21.6))(typescript@5.6.2) version: 8.7.0(eslint@9.11.1(jiti@1.21.6))(typescript@5.6.2)
vite: vite:
specifier: ^5.4.8 specifier: ^5.4.8
version: 5.4.8(@types/node@22.7.2) version: 5.4.8(@types/node@22.7.4)
packages: packages:
@ -574,8 +571,8 @@ packages:
'@kevisual/codemirror@0.0.2': '@kevisual/codemirror@0.0.2':
resolution: {integrity: sha512-z+hINypSarYBj+13en8+Hj/CqTAMVIYN3Rs0ICHRzbikvrDnsnT4ohpnFgcbFPQ/zX3E1mS9ANbx4jGSJEHaPQ==} resolution: {integrity: sha512-z+hINypSarYBj+13en8+Hj/CqTAMVIYN3Rs0ICHRzbikvrDnsnT4ohpnFgcbFPQ/zX3E1mS9ANbx4jGSJEHaPQ==}
'@kevisual/query@0.0.2': '@kevisual/query@0.0.6':
resolution: {integrity: sha512-xE2KhqlF2WDJ8Mt/AKKYnKeBPGxlbNhh7uXSxhO1/Rz95SVfJm0QF6pCEiWi/OHQ93gxIt5qUNEGp9avXHsWxw==} resolution: {integrity: sha512-J+poZwIx4r956GDN5zI8zM0YyyxJqARZVVOFYplRThaQLqpsbRNYJoYiT5DekvBftxtFjs/OlI3RzcHDOv3Fjw==}
'@kevisual/ui@0.0.2': '@kevisual/ui@0.0.2':
resolution: {integrity: sha512-MDZDQTrYToLyj3WhiVJQLJ0PUHiN4D0Z5yJIyGzzPewPGpP2xwNgKO1BFX37J95cGZckzCdZwTKP0XKAOq0QtA==} resolution: {integrity: sha512-MDZDQTrYToLyj3WhiVJQLJ0PUHiN4D0Z5yJIyGzzPewPGpP2xwNgKO1BFX37J95cGZckzCdZwTKP0XKAOq0QtA==}
@ -749,11 +746,6 @@ packages:
peerDependencies: peerDependencies:
tailwindcss: '>=2.0.0 || >=3.0.0 || >=3.0.0-alpha.1' tailwindcss: '>=2.0.0 || >=3.0.0 || >=3.0.0-alpha.1'
'@tailwindcss/line-clamp@0.4.4':
resolution: {integrity: sha512-5U6SY5z8N42VtrCrKlsTAA35gy2VSyYtHWCsg1H87NU1SXnEfekTVlrga9fzUDrrHcGi2Lb5KenUWb4lRQT5/g==}
peerDependencies:
tailwindcss: '>=2.0.0 || >=3.0.0 || >=3.0.0-alpha.1'
'@tailwindcss/typography@0.5.15': '@tailwindcss/typography@0.5.15':
resolution: {integrity: sha512-AqhlCXl+8grUz8uqExv5OTtgpjuVIwFTSXTrh8y9/pw6q2ek7fJ+Y8ZEVw7EB2DCcuCOtEjf9w3+J3rzts01uA==} resolution: {integrity: sha512-AqhlCXl+8grUz8uqExv5OTtgpjuVIwFTSXTrh8y9/pw6q2ek7fJ+Y8ZEVw7EB2DCcuCOtEjf9w3+J3rzts01uA==}
peerDependencies: peerDependencies:
@ -891,8 +883,8 @@ packages:
'@types/mdast@4.0.4': '@types/mdast@4.0.4':
resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==}
'@types/node@22.7.2': '@types/node@22.7.4':
resolution: {integrity: sha512-866lXSrpGpgyHBZUa2m9YNWqHDjjM0aBTJlNtYaGEw4rqY/dcD7deRVTbBBAJelfA7oaGDbNftXF/TL/A6RgoA==} resolution: {integrity: sha512-y+NPi1rFzDs1NdQHHToqeiX2TIS79SWEAw9GYhkkx8bD0ChpfqC+n2j5OXOCpzfojBEBt6DnEnnG9MY0zk1XLg==}
'@types/parse-json@4.0.2': '@types/parse-json@4.0.2':
resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==}
@ -906,8 +898,8 @@ packages:
'@types/react-dom@18.3.0': '@types/react-dom@18.3.0':
resolution: {integrity: sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==} resolution: {integrity: sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==}
'@types/react@18.3.9': '@types/react@18.3.10':
resolution: {integrity: sha512-+BpAVyTpJkNWWSSnaLBk6ePpHLOGJKnEQNbINNovPWzvEUyAe3e+/d494QdEh71RekM/qV7lw6jzf1HGrJyAtQ==} resolution: {integrity: sha512-02sAAlBnP39JgXwkAq3PeU9DVaaGpZyF3MGcC0MKgQVkZor5IiiDAipVaxQHtDJAmO4GIy/rVBy/LzVj76Cyqg==}
'@types/unist@2.0.11': '@types/unist@2.0.11':
resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==}
@ -2621,17 +2613,17 @@ snapshots:
eventemitter3: 5.0.1 eventemitter3: 5.0.1
nanoid: 5.0.7 nanoid: 5.0.7
'@abearxiong/flows@0.0.1-alpha.9(@xyflow/react@12.3.1(@types/react@18.3.9)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(zustand@4.5.5(@types/react@18.3.9)(immer@10.1.1)(react@18.3.1))': '@abearxiong/flows@0.0.1-alpha.9(@xyflow/react@12.3.1(@types/react@18.3.10)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(zustand@4.5.5(@types/react@18.3.10)(immer@10.1.1)(react@18.3.1))':
dependencies: dependencies:
'@ant-design/icons': 5.5.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@ant-design/icons': 5.5.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@icon-park/react': 1.4.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@icon-park/react': 1.4.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@xyflow/react': 12.3.1(@types/react@18.3.9)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@xyflow/react': 12.3.1(@types/react@18.3.10)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
clsx: 2.1.1 clsx: 2.1.1
eventemitter3: 5.0.1 eventemitter3: 5.0.1
immer: 10.1.1 immer: 10.1.1
react: 18.3.1 react: 18.3.1
react-tooltip: 5.28.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react-tooltip: 5.28.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
zustand: 4.5.5(@types/react@18.3.9)(immer@10.1.1)(react@18.3.1) zustand: 4.5.5(@types/react@18.3.10)(immer@10.1.1)(react@18.3.1)
transitivePeerDependencies: transitivePeerDependencies:
- react-dom - react-dom
@ -3037,7 +3029,7 @@ snapshots:
'@kevisual/codemirror@0.0.2': {} '@kevisual/codemirror@0.0.2': {}
'@kevisual/query@0.0.2': {} '@kevisual/query@0.0.6': {}
'@kevisual/ui@0.0.2': '@kevisual/ui@0.0.2':
dependencies: dependencies:
@ -3183,10 +3175,6 @@ snapshots:
dependencies: dependencies:
tailwindcss: 3.4.13 tailwindcss: 3.4.13
'@tailwindcss/line-clamp@0.4.4(tailwindcss@3.4.13)':
dependencies:
tailwindcss: 3.4.13
'@tailwindcss/typography@0.5.15(tailwindcss@3.4.13)': '@tailwindcss/typography@0.5.15(tailwindcss@3.4.13)':
dependencies: dependencies:
lodash.castarray: 4.4.0 lodash.castarray: 4.4.0
@ -3359,7 +3347,7 @@ snapshots:
dependencies: dependencies:
'@types/unist': 3.0.3 '@types/unist': 3.0.3
'@types/node@22.7.2': '@types/node@22.7.4':
dependencies: dependencies:
undici-types: 6.19.8 undici-types: 6.19.8
@ -3371,9 +3359,9 @@ snapshots:
'@types/react-dom@18.3.0': '@types/react-dom@18.3.0':
dependencies: dependencies:
'@types/react': 18.3.9 '@types/react': 18.3.10
'@types/react@18.3.9': '@types/react@18.3.10':
dependencies: dependencies:
'@types/prop-types': 15.7.13 '@types/prop-types': 15.7.13
csstype: 3.1.3 csstype: 3.1.3
@ -3473,24 +3461,24 @@ snapshots:
'@ungap/structured-clone@1.2.0': {} '@ungap/structured-clone@1.2.0': {}
'@vitejs/plugin-react@4.3.1(vite@5.4.8(@types/node@22.7.2))': '@vitejs/plugin-react@4.3.1(vite@5.4.8(@types/node@22.7.4))':
dependencies: dependencies:
'@babel/core': 7.25.2 '@babel/core': 7.25.2
'@babel/plugin-transform-react-jsx-self': 7.24.7(@babel/core@7.25.2) '@babel/plugin-transform-react-jsx-self': 7.24.7(@babel/core@7.25.2)
'@babel/plugin-transform-react-jsx-source': 7.24.7(@babel/core@7.25.2) '@babel/plugin-transform-react-jsx-source': 7.24.7(@babel/core@7.25.2)
'@types/babel__core': 7.20.5 '@types/babel__core': 7.20.5
react-refresh: 0.14.2 react-refresh: 0.14.2
vite: 5.4.8(@types/node@22.7.2) vite: 5.4.8(@types/node@22.7.4)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@xyflow/react@12.3.1(@types/react@18.3.9)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': '@xyflow/react@12.3.1(@types/react@18.3.10)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies: dependencies:
'@xyflow/system': 0.0.43 '@xyflow/system': 0.0.43
classcat: 5.0.5 classcat: 5.0.5
react: 18.3.1 react: 18.3.1
react-dom: 18.3.1(react@18.3.1) react-dom: 18.3.1(react@18.3.1)
zustand: 4.5.5(@types/react@18.3.9)(immer@10.1.1)(react@18.3.1) zustand: 4.5.5(@types/react@18.3.10)(immer@10.1.1)(react@18.3.1)
transitivePeerDependencies: transitivePeerDependencies:
- '@types/react' - '@types/react'
- immer - immer
@ -5275,20 +5263,20 @@ snapshots:
'@types/unist': 3.0.3 '@types/unist': 3.0.3
vfile-message: 4.0.2 vfile-message: 4.0.2
vite-plugin-tsconfig-paths@1.4.1(typescript@5.6.2)(vite@5.4.8(@types/node@22.7.2)): vite-plugin-tsconfig-paths@1.4.1(typescript@5.6.2)(vite@5.4.8(@types/node@22.7.4)):
dependencies: dependencies:
typescript-paths: 1.5.1(typescript@5.6.2) typescript-paths: 1.5.1(typescript@5.6.2)
vite: 5.4.8(@types/node@22.7.2) vite: 5.4.8(@types/node@22.7.4)
transitivePeerDependencies: transitivePeerDependencies:
- typescript - typescript
vite@5.4.8(@types/node@22.7.2): vite@5.4.8(@types/node@22.7.4):
dependencies: dependencies:
esbuild: 0.21.5 esbuild: 0.21.5
postcss: 8.4.47 postcss: 8.4.47
rollup: 4.22.0 rollup: 4.22.0
optionalDependencies: optionalDependencies:
'@types/node': 22.7.2 '@types/node': 22.7.4
fsevents: 2.3.3 fsevents: 2.3.3
web-namespaces@2.0.1: {} web-namespaces@2.0.1: {}
@ -5319,11 +5307,11 @@ snapshots:
yocto-queue@0.1.0: {} yocto-queue@0.1.0: {}
zustand@4.5.5(@types/react@18.3.9)(immer@10.1.1)(react@18.3.1): zustand@4.5.5(@types/react@18.3.10)(immer@10.1.1)(react@18.3.1):
dependencies: dependencies:
use-sync-external-store: 1.2.2(react@18.3.1) use-sync-external-store: 1.2.2(react@18.3.1)
optionalDependencies: optionalDependencies:
'@types/react': 18.3.9 '@types/react': 18.3.10
immer: 10.1.1 immer: 10.1.1
react: 18.3.1 react: 18.3.1

View File

@ -1,9 +1,28 @@
import { Query } from '@kevisual/query'; import { Query, QueryClient } from '@kevisual/query';
export const query = new Query({}); import { QueryWs } from '@kevisual/query/ws';
export const request = query.post; import { modal } from './redirect-to-login';
export const ws = new WebSocket('ws://localhost:6010/api/router');
import { create } from 'zustand'; import { create } from 'zustand';
export const query = new Query();
query.beforeRequest = async (config) => {
if (config.headers) {
const token = localStorage.getItem('token');
if (token) {
config.headers['Authorization'] = 'Bearer ' + token;
}
}
return config;
};
query.afterResponse = async (res) => {
if (res.code === 401 || res.code === 403) {
modal.setOpen(true);
}
return res;
};
export const request = query.post;
export const queryWs = new QueryWs({
url: '/api/router',
});
export const ws = queryWs.ws;
type Store = { type Store = {
connected: boolean; connected: boolean;
setConnected: (connected: boolean) => void; setConnected: (connected: boolean) => void;
@ -18,11 +37,6 @@ ws.onopen = () => {
console.log('Connected to WebSocket server'); console.log('Connected to WebSocket server');
useStore.getState().setConnected(true); useStore.getState().setConnected(true);
}; };
// 接收服务器的消息
ws.onmessage = (event) => {
// console.log('Received message:', event.data);
// const message = JSON.parse(event.data);
};
// 处理 WebSocket 关闭 // 处理 WebSocket 关闭
ws.onclose = () => { ws.onclose = () => {

View File

@ -0,0 +1,26 @@
import { DialogModal } from '@kevisual/ui';
import '@kevisual/ui/dist/index.css';
const content = document.createElement('div');
content.innerHTML = `
<div class="bg-white p-8 rounded shadow-md w-full max-w-md text-center">
<h2 class="text-2xl font-bold mb-4">Token </h2>
<p class="mb-6"></p>
<a href="/user/login" class="inline-block bg-red-500 text-white py-2 px-4 rounded hover:bg-red-600 transition duration-200"></a>
</div>
`;
export const modal = DialogModal.render(content, {
id: 'redirect-to-login',
contentStyle: {
width: 'unset',
},
dialogTitleStyle: {
display: 'none',
padding: '0',
},
dialogContentStyle: {
padding: '0',
},
mask: true,
open: false,
});

View File

@ -34,7 +34,7 @@ export const useAgentStore = create<AgentStore>((set, get) => {
if (res.code === 200) { if (res.code === 200) {
set({ list: res.data }); set({ list: res.data });
} else { } else {
message.error(res.msg || 'Request failed'); message.error(res.message || 'Request failed');
} }
}, },
updateData: async (data) => { updateData: async (data) => {
@ -49,7 +49,7 @@ export const useAgentStore = create<AgentStore>((set, get) => {
set({ showEdit: false, formData: [] }); set({ showEdit: false, formData: [] });
getList(); getList();
} else { } else {
message.error(res.msg || 'Request failed'); message.error(res.message || 'Request failed');
} }
}, },
deleteData: async (id) => { deleteData: async (id) => {
@ -63,7 +63,7 @@ export const useAgentStore = create<AgentStore>((set, get) => {
getList(); getList();
message.success('Success'); message.success('Success');
} else { } else {
message.error(res.msg || 'Request failed'); message.error(res.message || 'Request failed');
} }
}, },
publishData: async (data) => { publishData: async (data) => {
@ -87,7 +87,7 @@ export const useAgentStore = create<AgentStore>((set, get) => {
if (res.code === 200) { if (res.code === 200) {
message.success('Success'); message.success('Success');
} else { } else {
message.error(res.msg || 'Request failed'); message.error(res.message || 'Request failed');
} }
}, },
}; };

View File

@ -1,6 +1,6 @@
import { useShallow } from 'zustand/react/shallow'; import { useShallow } from 'zustand/react/shallow';
import { useAiStore } from './store/ai-store'; import { useAiStore } from './store/ai-store';
import { CloseOutlined } from '@ant-design/icons'; import { CloseOutlined, HistoryOutlined } from '@ant-design/icons';
import { Button, Form, Input } from 'antd'; import { Button, Form, Input } from 'antd';
import { useEffect } from 'react'; import { useEffect } from 'react';
import { TextArea } from '../container/components/TextArea'; import { TextArea } from '../container/components/TextArea';
@ -49,6 +49,9 @@ export const AiMoudle = () => {
<div className='flex gap-4 bg-slate-400 p-2'> <div className='flex gap-4 bg-slate-400 p-2'>
<Button className='position ml-4 !bg-slate-400 !border-black' onClick={() => aiStore.setOpen(false)} icon={<CloseOutlined />}></Button> <Button className='position ml-4 !bg-slate-400 !border-black' onClick={() => aiStore.setOpen(false)} icon={<CloseOutlined />}></Button>
<h1 className='ml-10'>Ai Moudle</h1> <h1 className='ml-10'>Ai Moudle</h1>
<div>
<HistoryOutlined />
</div>
</div> </div>
<div className='flex-grow p-2 overflow-hidden h-full flex flex-col'> <div className='flex-grow p-2 overflow-hidden h-full flex flex-col'>
<div className='flex flex-col'> <div className='flex flex-col'>
@ -58,8 +61,9 @@ export const AiMoudle = () => {
return ( return (
<div key={index} className=' justify-between px-4 w-full'> <div key={index} className=' justify-between px-4 w-full'>
<div className='h3 font-bold'>{message?.role}</div> <div className='h3 font-bold'>{message?.role}</div>
<div className='p-4 text-xs border shadow-sm rounded-sm scrollbar max-h-[200px] w-full overflow-scroll' dangerouslySetInnerHTML={{ __html: html }}> <div
</div> className='p-4 text-xs border shadow-sm rounded-sm scrollbar max-h-[200px] w-full overflow-scroll'
dangerouslySetInnerHTML={{ __html: html }}></div>
</div> </div>
); );
})} })}

View File

@ -1,4 +1,4 @@
import { Button, Input, message, Modal, Table } from 'antd'; import { Button, Input, message, Modal, Select, Table, Tooltip } from 'antd';
import { Fragment, useEffect, useMemo, useState } from 'react'; import { Fragment, useEffect, useMemo, useState } from 'react';
import { TextArea } from '../components/TextArea'; import { TextArea } from '../components/TextArea';
import { useContainerStore } from '../store'; import { useContainerStore } from '../store';
@ -6,9 +6,10 @@ import { useShallow } from 'zustand/react/shallow';
import { Form } from 'antd'; import { Form } from 'antd';
import copy from 'copy-to-clipboard'; import copy from 'copy-to-clipboard';
import { useNavigate } from 'react-router'; import { useNavigate } from 'react-router';
import { EditOutlined, SettingOutlined, LinkOutlined, SaveOutlined, DeleteOutlined, LeftOutlined } from '@ant-design/icons'; import { EditOutlined, SettingOutlined, LinkOutlined, SaveOutlined, DeleteOutlined, LeftOutlined, MessageOutlined } from '@ant-design/icons';
import clsx from 'clsx'; import clsx from 'clsx';
import { isObjectNull } from '@/utils/is-null'; import { isObjectNull } from '@/utils/is-null';
import { CardBlank } from '@/components/card/CardBlank';
const FormModal = () => { const FormModal = () => {
const [form] = Form.useForm(); const [form] = Form.useForm();
const containerStore = useContainerStore( const containerStore = useContainerStore(
@ -67,6 +68,9 @@ const FormModal = () => {
<Form.Item name='description' label='description'> <Form.Item name='description' label='description'>
<Input.TextArea rows={4} /> <Input.TextArea rows={4} />
</Form.Item> </Form.Item>
<Form.Item name='tags' label='tags'>
<Select mode='tags' />
</Form.Item>
<Form.Item name='code' label='code'> <Form.Item name='code' label='code'>
<TextArea /> <TextArea />
</Form.Item> </Form.Item>
@ -128,13 +132,14 @@ export const ContainerList = () => {
}}> }}>
<div className='px-4 cursor-pointer'> <div className='px-4 cursor-pointer'>
<div <div
className='font-bold' className='font-bold flex items-center'
onClick={(e) => { onClick={(e) => {
copy(item.code); copy(item.code);
e.stopPropagation(); e.stopPropagation();
message.success('copy code success'); message.success('copy code success');
}}> }}>
{item.title || '-'} {item.title || '-'}
<div className='font-thin card-key ml-3 text-xs'>{item.tags ? item.tags.join(', ') : ''}</div>
</div> </div>
<div className='font-light text-xs mt-2'>{item.description ? item.description : '-'}</div> <div className='font-light text-xs mt-2'>{item.description ? item.description : '-'}</div>
</div> </div>
@ -171,9 +176,7 @@ export const ContainerList = () => {
</Fragment> </Fragment>
); );
})} })}
{new Array(4).fill(0).map((_, index) => { <CardBlank className='w-[400px]' />
return <div key={index} className='w-[400px]'></div>;
})}
{containerStore.list.length == 0 && ( {containerStore.list.length == 0 && (
<div className='text-center' key={'no-data'}> <div className='text-center' key={'no-data'}>
No Data No Data
@ -184,18 +187,33 @@ export const ContainerList = () => {
<div className={clsx('bg-gray-100 border-l border-bg-slate-300 w-[600px] flex-shrink-0', !codeEdit && 'hidden')}> <div className={clsx('bg-gray-100 border-l border-bg-slate-300 w-[600px] flex-shrink-0', !codeEdit && 'hidden')}>
<div className='bg-white p-2'> <div className='bg-white p-2'>
<div className='mt-2 ml-2 flex gap-2'> <div className='mt-2 ml-2 flex gap-2'>
<Button <Tooltip title='返回'>
onClick={() => { <Button
setCodeEdit(false); onClick={() => {
containerStore.setFormData({}); setCodeEdit(false);
}} containerStore.setFormData({});
icon={<LeftOutlined />}></Button> }}
<Button icon={<LeftOutlined />}></Button>
onClick={() => { </Tooltip>
console.log('save', containerStore.formData); <Tooltip title='保存'>
containerStore.updateData({ ...containerStore.formData, code }); <Button
}} onClick={() => {
icon={<SaveOutlined />}></Button> console.log('save', containerStore.formData);
containerStore.updateData({ ...containerStore.formData, code });
}}
icon={<SaveOutlined />}></Button>
</Tooltip>
<Tooltip title='预览'>
<Button
onClick={(e) => {
// navicate('/container/preview/' + item.id);
e.stopPropagation();
}}
icon={<LinkOutlined />}></Button>
</Tooltip>
<Tooltip title='ai编程'>
<Button onClick={(e) => {}} icon={<MessageOutlined />}></Button>
</Tooltip>
</div> </div>
</div> </div>
<div className='h-[94%] p-2 rounded-2 shadow-sm'> <div className='h-[94%] p-2 rounded-2 shadow-sm'>

View File

@ -80,7 +80,7 @@ export const Preview = () => {
}; };
init([code]); init([code]);
} else { } else {
message.error(res.msg || 'Failed to fetch data'); message.error(res.message || 'Failed to fetch data');
} }
}; };
const refresh = (data: any) => { const refresh = (data: any) => {
@ -131,7 +131,7 @@ export const PreviewWrapper = () => {
fetch(); fetch();
}, []); }, []);
const fetch = async () => { const fetch = async () => {
const res = await query.post({ const res = await query.post<any, any>({
path: 'container', path: 'container',
key: 'get', key: 'get',
id, id,
@ -149,7 +149,7 @@ export const PreviewWrapper = () => {
}; };
init([code]); init([code]);
} else { } else {
message.error(res.msg || 'Failed to fetch data'); message.error(res.message || 'Failed to fetch data');
} }
}; };
const refresh = (data: any) => { const refresh = (data: any) => {

View File

@ -34,7 +34,7 @@ export const useContainerStore = create<ContainerStore>((set, get) => {
if (res.code === 200) { if (res.code === 200) {
set({ list: res.data }); set({ list: res.data });
} else { } else {
message.error(res.msg || 'Request failed'); message.error(res.message || 'Request failed');
} }
}, },
updateData: async (data) => { updateData: async (data) => {
@ -49,7 +49,7 @@ export const useContainerStore = create<ContainerStore>((set, get) => {
set({ showEdit: false, formData: [] }); set({ showEdit: false, formData: [] });
getList(); getList();
} else { } else {
message.error(res.msg || 'Request failed'); message.error(res.message || 'Request failed');
} }
}, },
deleteData: async (id) => { deleteData: async (id) => {
@ -63,7 +63,7 @@ export const useContainerStore = create<ContainerStore>((set, get) => {
getList(); getList();
message.success('Success'); message.success('Success');
} else { } else {
message.error(res.msg || 'Request failed'); message.error(res.message || 'Request failed');
} }
}, },
publishData: async (data) => { publishData: async (data) => {
@ -87,7 +87,7 @@ export const useContainerStore = create<ContainerStore>((set, get) => {
if (res.code === 200) { if (res.code === 200) {
message.success('Success'); message.success('Success');
} else { } else {
message.error(res.msg || 'Request failed'); message.error(res.message || 'Request failed');
} }
}, },
}; };

View File

@ -31,8 +31,8 @@ const ServerPath = () => {
const navigate = useNavigate(); const navigate = useNavigate();
return ( return (
<div className='p-2 w-full h-full bg-gray-200'> <div className='p-2 w-full h-full bg-gray-200'>
<h1 className='p-4 w-1/2 m-auto h1'>Map</h1> <h1 className='p-4 w-1/2 m-auto h1'>Site Map</h1>
<div className='flex flex-col w-1/2 m-auto bg-white p-4 border rounded-md shadow-md'> <div className='flex flex-col w-1/2 m-auto bg-white p-4 border rounded-md shadow-md min-w-[600px]'>
{serverPath.map((item) => { {serverPath.map((item) => {
const links = item.links.map((link) => { const links = item.links.map((link) => {
const hasId = link.includes(':id'); const hasId = link.includes(':id');

View File

@ -31,7 +31,7 @@ export const useEditStore = create<EditStore>((set, get) => {
if (res.code === 200) { if (res.code === 200) {
set({ list: res.data }); set({ list: res.data });
} else { } else {
message.error(res.msg || 'Request failed'); message.error(res.message || 'Request failed');
} }
}, },
updateData: async (data) => { updateData: async (data) => {
@ -46,7 +46,7 @@ export const useEditStore = create<EditStore>((set, get) => {
set({ showEditModal: false, formData: [] }); set({ showEditModal: false, formData: [] });
getList(); getList();
} else { } else {
message.error(res.msg || 'Request failed'); message.error(res.message || 'Request failed');
} }
}, },
deleteData: async (id) => { deleteData: async (id) => {
@ -60,7 +60,7 @@ export const useEditStore = create<EditStore>((set, get) => {
message.success('Success'); message.success('Success');
getList(); getList();
} else { } else {
message.error(res.msg || 'Request failed'); message.error(res.message || 'Request failed');
} }
}, },
}; };

View File

@ -50,7 +50,7 @@ export const usePanelStore = create<PanelStore>((set, get) => {
}), }),
); );
} else { } else {
message.error(res.msg || 'Request failed'); message.error(res.message || 'Request failed');
} }
}, },
saveNodesEdges: async ({ edges, nodes, viewport }) => { saveNodesEdges: async ({ edges, nodes, viewport }) => {
@ -77,7 +77,7 @@ export const usePanelStore = create<PanelStore>((set, get) => {
}), }),
); );
} else { } else {
message.error(res.msg || 'Request failed'); message.error(res.message || 'Request failed');
} }
}, },
updateNodeData: async (data) => { updateNodeData: async (data) => {
@ -95,7 +95,7 @@ export const usePanelStore = create<PanelStore>((set, get) => {
message.success('Success'); message.success('Success');
// getList(); // getList();
} else { } else {
message.error(res.msg || 'Request failed'); message.error(res.message || 'Request failed');
} }
}, },
updateNodeDataStyle: async (data) => { updateNodeDataStyle: async (data) => {
@ -118,7 +118,7 @@ export const usePanelStore = create<PanelStore>((set, get) => {
// getList(); // getList();
return true; return true;
} else { } else {
message.error(res.msg || 'Request failed'); message.error(res.message || 'Request failed');
} }
return false; return false;
}, },

View File

@ -41,7 +41,7 @@ export const usePromptStore = create<PromptStore>((set, get) => {
if (res.code === 200) { if (res.code === 200) {
set({ list: res.data }); set({ list: res.data });
} else { } else {
message.error(res.msg || 'Request failed'); message.error(res.message || 'Request failed');
} }
}, },
updateData: async (data) => { updateData: async (data) => {
@ -56,7 +56,7 @@ export const usePromptStore = create<PromptStore>((set, get) => {
set({ showEdit: false, formData: [] }); set({ showEdit: false, formData: [] });
getList(); getList();
} else { } else {
message.error(res.msg || 'Request failed'); message.error(res.message || 'Request failed');
} }
}, },
deleteData: async (id) => { deleteData: async (id) => {
@ -70,7 +70,7 @@ export const usePromptStore = create<PromptStore>((set, get) => {
getList(); getList();
message.success('Success'); message.success('Success');
} else { } else {
message.error(res.msg || 'Request failed'); message.error(res.message || 'Request failed');
} }
}, },
runAi: async () => { runAi: async () => {

View File

@ -33,7 +33,7 @@ export const usePublishStore = create<Store>((set, get) => {
if (res.code === 200) { if (res.code === 200) {
set({ list: res.data }); set({ list: res.data });
} else { } else {
message.error(res.msg || 'Request failed'); message.error(res.message || 'Request failed');
} }
}, },
updateData: async (data) => { updateData: async (data) => {
@ -48,7 +48,7 @@ export const usePublishStore = create<Store>((set, get) => {
set({ showEdit: false, formData: [] }); set({ showEdit: false, formData: [] });
getList(); getList();
} else { } else {
message.error(res.msg || 'Request failed'); message.error(res.message || 'Request failed');
} }
}, },
deleteData: async (id) => { deleteData: async (id) => {
@ -62,7 +62,7 @@ export const usePublishStore = create<Store>((set, get) => {
getList(); getList();
message.success('Success'); message.success('Success');
} else { } else {
message.error(res.msg || 'Request failed'); message.error(res.message || 'Request failed');
} }
}, },
}; };

View File

@ -27,18 +27,23 @@ export const Login = () => {
loginStore.login(); loginStore.login();
}; };
return ( return (
<div className='flex w-full h-full'> <div className='flex w-full h-full bg-slate-200'>
<div className='w-[600px] mx-auto mt-[10%] '> <div className='w-[600px] mx-auto mt-[10%] '>
<h1 className='mb-4 tracking-widest'>Login</h1> <h1 className='mb-4 tracking-widest'>Login</h1>
<div className='card border-t-2'> <div className='card border-t-2 pt-8 px-8'>
<Form form={form} onFinish={onFinish}> <Form
form={form}
onFinish={onFinish}
labelCol={{
span: 4,
}}>
<Form.Item label='username' name='username'> <Form.Item label='username' name='username'>
<Input /> <Input />
</Form.Item> </Form.Item>
<Form.Item label='password' name='password'> <Form.Item label='password' name='password'>
<Input type='password' /> <Input type='password' />
</Form.Item> </Form.Item>
<Form.Item label=' ' noStyle colon={false}> <Form.Item label=' ' colon={false}>
<div className='flex gap-2'> <div className='flex gap-2'>
<Button type='primary' htmlType='submit'> <Button type='primary' htmlType='submit'>
Login Login

View File

@ -33,7 +33,7 @@ export const useUserStore = create<UserStore>((set, get) => {
if (res.code === 200) { if (res.code === 200) {
set({ list: res.data }); set({ list: res.data });
} else { } else {
message.error(res.msg || 'Request failed'); message.error(res.message || 'Request failed');
} }
}, },
updateData: async (data) => { updateData: async (data) => {
@ -48,7 +48,7 @@ export const useUserStore = create<UserStore>((set, get) => {
set({ showEdit: false, formData: [] }); set({ showEdit: false, formData: [] });
getList(); getList();
} else { } else {
message.error(res.msg || 'Request failed'); message.error(res.message || 'Request failed');
} }
}, },
deleteData: async (id) => { deleteData: async (id) => {
@ -62,7 +62,7 @@ export const useUserStore = create<UserStore>((set, get) => {
getList(); getList();
message.success('Success'); message.success('Success');
} else { } else {
message.error(res.msg || 'Request failed'); message.error(res.message || 'Request failed');
} }
}, },
}; };

View File

@ -1,6 +1,7 @@
import { query } from '@/modules'; import { query } from '@/modules';
import { message } from 'antd'; import { message } from 'antd';
import { create } from 'zustand'; import { create } from 'zustand';
import { history } from '@/utils/history';
type LoginStore = { type LoginStore = {
loading: boolean; loading: boolean;
setLoading: (loading: boolean) => void; setLoading: (loading: boolean) => void;
@ -29,11 +30,14 @@ export const useLoginStore = create<LoginStore>((set, get) => {
const res = await query.post({ path: 'user', key: 'login', username, password }); const res = await query.post({ path: 'user', key: 'login', username, password });
loaded(); loaded();
if (res.code === 200) { if (res.code === 200) {
const { token } = res.data;
message.success('Success'); message.success('Success');
set({ isLogin: true }); set({ isLogin: true });
localStorage.setItem('token', token);
// 跳到某一个页面更新localStorage // 跳到某一个页面更新localStorage
history.push('/map');
} else { } else {
message.error(res.msg || 'Request failed'); message.error(res.message || 'Request failed');
} }
}, },
register: async () => { register: async () => {
@ -44,8 +48,9 @@ export const useLoginStore = create<LoginStore>((set, get) => {
if (res.code === 200) { if (res.code === 200) {
message.success('Success'); message.success('Success');
// 跳到某一个页面 // 跳到某一个页面
// history.push('/map', {}, true);
} else { } else {
message.error(res.msg || 'Request failed'); message.error(res.message || 'Request failed');
} }
}, },
isLogin: false, isLogin: false,

2
theme

@ -1 +1 @@
Subproject commit 36f865b026b70cd8f90a44f4d3b5f9dced9709af Subproject commit 66aae218f3962f2e5ab8f22f3a463b74d5e17362