提交 4e4e165d authored 作者: 王鹏飞's avatar 王鹏飞

chore: update

上级 35a924d2
...@@ -12,12 +12,13 @@ ...@@ -12,12 +12,13 @@
"@fortaine/fetch-event-source": "^3.0.6", "@fortaine/fetch-event-source": "^3.0.6",
"@tanstack/react-query": "^5.67.1", "@tanstack/react-query": "^5.67.1",
"antd": "^5.24.3", "antd": "^5.24.3",
"axios": "^1.8.1", "axios": "^1.8.3",
"blueimp-md5": "^2.19.0", "blueimp-md5": "^2.19.0",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"lucide-react": "^0.477.0", "lucide-react": "^0.477.0",
"react": "^18.2.0", "openai": "^4.87.3",
"react-dom": "^18.2.0", "react": "^18.3.1",
"react-dom": "^18.3.1",
"react-markdown": "^10.1.0", "react-markdown": "^10.1.0",
"react-router": "^7.3.0", "react-router": "^7.3.0",
"remark-gfm": "^4.0.1", "remark-gfm": "^4.0.1",
...@@ -28,18 +29,18 @@ ...@@ -28,18 +29,18 @@
"@types/blueimp-md5": "^2.18.2", "@types/blueimp-md5": "^2.18.2",
"@types/lodash-es": "^4.17.12", "@types/lodash-es": "^4.17.12",
"@types/node": "^22.13.9", "@types/node": "^22.13.9",
"@types/react": "^18.2.66", "@types/react": "^18.3.18",
"@types/react-dom": "^18.2.22", "@types/react-dom": "^18.3.5",
"@typescript-eslint/eslint-plugin": "^7.2.0", "@typescript-eslint/eslint-plugin": "^7.18.0",
"@typescript-eslint/parser": "^7.2.0", "@typescript-eslint/parser": "^7.18.0",
"@vitejs/plugin-react-swc": "^3.5.0", "@vitejs/plugin-react-swc": "^3.8.0",
"eslint": "^8.57.0", "eslint": "^8.57.0",
"eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-react-refresh": "^0.4.6", "eslint-plugin-react-refresh": "^0.4.19",
"sass-embedded": "^1.85.1", "sass-embedded": "^1.85.1",
"typescript": "^5.2.2", "typescript": "^5.2.2",
"vite": "^5.2.0", "vite": "^6.2.2",
"vite-plugin-mkcert": "^1.17.7" "vite-plugin-mkcert": "^1.17.8"
} }
}, },
"node_modules/@ant-design/colors": { "node_modules/@ant-design/colors": {
...@@ -171,9 +172,9 @@ ...@@ -171,9 +172,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@esbuild/aix-ppc64": { "node_modules/@esbuild/aix-ppc64": {
"version": "0.21.5", "version": "0.25.1",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.1.tgz",
"integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", "integrity": "sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==",
"cpu": [ "cpu": [
"ppc64" "ppc64"
], ],
...@@ -184,13 +185,13 @@ ...@@ -184,13 +185,13 @@
"aix" "aix"
], ],
"engines": { "engines": {
"node": ">=12" "node": ">=18"
} }
}, },
"node_modules/@esbuild/android-arm": { "node_modules/@esbuild/android-arm": {
"version": "0.21.5", "version": "0.25.1",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.1.tgz",
"integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", "integrity": "sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
...@@ -201,13 +202,13 @@ ...@@ -201,13 +202,13 @@
"android" "android"
], ],
"engines": { "engines": {
"node": ">=12" "node": ">=18"
} }
}, },
"node_modules/@esbuild/android-arm64": { "node_modules/@esbuild/android-arm64": {
"version": "0.21.5", "version": "0.25.1",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.1.tgz",
"integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", "integrity": "sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
...@@ -218,13 +219,13 @@ ...@@ -218,13 +219,13 @@
"android" "android"
], ],
"engines": { "engines": {
"node": ">=12" "node": ">=18"
} }
}, },
"node_modules/@esbuild/android-x64": { "node_modules/@esbuild/android-x64": {
"version": "0.21.5", "version": "0.25.1",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.1.tgz",
"integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", "integrity": "sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
...@@ -235,13 +236,13 @@ ...@@ -235,13 +236,13 @@
"android" "android"
], ],
"engines": { "engines": {
"node": ">=12" "node": ">=18"
} }
}, },
"node_modules/@esbuild/darwin-arm64": { "node_modules/@esbuild/darwin-arm64": {
"version": "0.21.5", "version": "0.25.1",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.1.tgz",
"integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", "integrity": "sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
...@@ -252,13 +253,13 @@ ...@@ -252,13 +253,13 @@
"darwin" "darwin"
], ],
"engines": { "engines": {
"node": ">=12" "node": ">=18"
} }
}, },
"node_modules/@esbuild/darwin-x64": { "node_modules/@esbuild/darwin-x64": {
"version": "0.21.5", "version": "0.25.1",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.1.tgz",
"integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", "integrity": "sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
...@@ -269,13 +270,13 @@ ...@@ -269,13 +270,13 @@
"darwin" "darwin"
], ],
"engines": { "engines": {
"node": ">=12" "node": ">=18"
} }
}, },
"node_modules/@esbuild/freebsd-arm64": { "node_modules/@esbuild/freebsd-arm64": {
"version": "0.21.5", "version": "0.25.1",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.1.tgz",
"integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", "integrity": "sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
...@@ -286,13 +287,13 @@ ...@@ -286,13 +287,13 @@
"freebsd" "freebsd"
], ],
"engines": { "engines": {
"node": ">=12" "node": ">=18"
} }
}, },
"node_modules/@esbuild/freebsd-x64": { "node_modules/@esbuild/freebsd-x64": {
"version": "0.21.5", "version": "0.25.1",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.1.tgz",
"integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", "integrity": "sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
...@@ -303,13 +304,13 @@ ...@@ -303,13 +304,13 @@
"freebsd" "freebsd"
], ],
"engines": { "engines": {
"node": ">=12" "node": ">=18"
} }
}, },
"node_modules/@esbuild/linux-arm": { "node_modules/@esbuild/linux-arm": {
"version": "0.21.5", "version": "0.25.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.1.tgz",
"integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", "integrity": "sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
...@@ -320,13 +321,13 @@ ...@@ -320,13 +321,13 @@
"linux" "linux"
], ],
"engines": { "engines": {
"node": ">=12" "node": ">=18"
} }
}, },
"node_modules/@esbuild/linux-arm64": { "node_modules/@esbuild/linux-arm64": {
"version": "0.21.5", "version": "0.25.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.1.tgz",
"integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", "integrity": "sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
...@@ -337,13 +338,13 @@ ...@@ -337,13 +338,13 @@
"linux" "linux"
], ],
"engines": { "engines": {
"node": ">=12" "node": ">=18"
} }
}, },
"node_modules/@esbuild/linux-ia32": { "node_modules/@esbuild/linux-ia32": {
"version": "0.21.5", "version": "0.25.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.1.tgz",
"integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", "integrity": "sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ==",
"cpu": [ "cpu": [
"ia32" "ia32"
], ],
...@@ -354,13 +355,13 @@ ...@@ -354,13 +355,13 @@
"linux" "linux"
], ],
"engines": { "engines": {
"node": ">=12" "node": ">=18"
} }
}, },
"node_modules/@esbuild/linux-loong64": { "node_modules/@esbuild/linux-loong64": {
"version": "0.21.5", "version": "0.25.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.1.tgz",
"integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", "integrity": "sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg==",
"cpu": [ "cpu": [
"loong64" "loong64"
], ],
...@@ -371,13 +372,13 @@ ...@@ -371,13 +372,13 @@
"linux" "linux"
], ],
"engines": { "engines": {
"node": ">=12" "node": ">=18"
} }
}, },
"node_modules/@esbuild/linux-mips64el": { "node_modules/@esbuild/linux-mips64el": {
"version": "0.21.5", "version": "0.25.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.1.tgz",
"integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", "integrity": "sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg==",
"cpu": [ "cpu": [
"mips64el" "mips64el"
], ],
...@@ -388,13 +389,13 @@ ...@@ -388,13 +389,13 @@
"linux" "linux"
], ],
"engines": { "engines": {
"node": ">=12" "node": ">=18"
} }
}, },
"node_modules/@esbuild/linux-ppc64": { "node_modules/@esbuild/linux-ppc64": {
"version": "0.21.5", "version": "0.25.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.1.tgz",
"integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", "integrity": "sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg==",
"cpu": [ "cpu": [
"ppc64" "ppc64"
], ],
...@@ -405,13 +406,13 @@ ...@@ -405,13 +406,13 @@
"linux" "linux"
], ],
"engines": { "engines": {
"node": ">=12" "node": ">=18"
} }
}, },
"node_modules/@esbuild/linux-riscv64": { "node_modules/@esbuild/linux-riscv64": {
"version": "0.21.5", "version": "0.25.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.1.tgz",
"integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", "integrity": "sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ==",
"cpu": [ "cpu": [
"riscv64" "riscv64"
], ],
...@@ -422,13 +423,13 @@ ...@@ -422,13 +423,13 @@
"linux" "linux"
], ],
"engines": { "engines": {
"node": ">=12" "node": ">=18"
} }
}, },
"node_modules/@esbuild/linux-s390x": { "node_modules/@esbuild/linux-s390x": {
"version": "0.21.5", "version": "0.25.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.1.tgz",
"integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", "integrity": "sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ==",
"cpu": [ "cpu": [
"s390x" "s390x"
], ],
...@@ -439,13 +440,13 @@ ...@@ -439,13 +440,13 @@
"linux" "linux"
], ],
"engines": { "engines": {
"node": ">=12" "node": ">=18"
} }
}, },
"node_modules/@esbuild/linux-x64": { "node_modules/@esbuild/linux-x64": {
"version": "0.21.5", "version": "0.25.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.1.tgz",
"integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", "integrity": "sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
...@@ -456,13 +457,30 @@ ...@@ -456,13 +457,30 @@
"linux" "linux"
], ],
"engines": { "engines": {
"node": ">=12" "node": ">=18"
}
},
"node_modules/@esbuild/netbsd-arm64": {
"version": "0.25.1",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.1.tgz",
"integrity": "sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=18"
} }
}, },
"node_modules/@esbuild/netbsd-x64": { "node_modules/@esbuild/netbsd-x64": {
"version": "0.21.5", "version": "0.25.1",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.1.tgz",
"integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", "integrity": "sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
...@@ -473,13 +491,30 @@ ...@@ -473,13 +491,30 @@
"netbsd" "netbsd"
], ],
"engines": { "engines": {
"node": ">=12" "node": ">=18"
}
},
"node_modules/@esbuild/openbsd-arm64": {
"version": "0.25.1",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.1.tgz",
"integrity": "sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=18"
} }
}, },
"node_modules/@esbuild/openbsd-x64": { "node_modules/@esbuild/openbsd-x64": {
"version": "0.21.5", "version": "0.25.1",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.1.tgz",
"integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", "integrity": "sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
...@@ -490,13 +525,13 @@ ...@@ -490,13 +525,13 @@
"openbsd" "openbsd"
], ],
"engines": { "engines": {
"node": ">=12" "node": ">=18"
} }
}, },
"node_modules/@esbuild/sunos-x64": { "node_modules/@esbuild/sunos-x64": {
"version": "0.21.5", "version": "0.25.1",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.1.tgz",
"integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", "integrity": "sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
...@@ -507,13 +542,13 @@ ...@@ -507,13 +542,13 @@
"sunos" "sunos"
], ],
"engines": { "engines": {
"node": ">=12" "node": ">=18"
} }
}, },
"node_modules/@esbuild/win32-arm64": { "node_modules/@esbuild/win32-arm64": {
"version": "0.21.5", "version": "0.25.1",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.1.tgz",
"integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", "integrity": "sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
...@@ -524,13 +559,13 @@ ...@@ -524,13 +559,13 @@
"win32" "win32"
], ],
"engines": { "engines": {
"node": ">=12" "node": ">=18"
} }
}, },
"node_modules/@esbuild/win32-ia32": { "node_modules/@esbuild/win32-ia32": {
"version": "0.21.5", "version": "0.25.1",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.1.tgz",
"integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", "integrity": "sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A==",
"cpu": [ "cpu": [
"ia32" "ia32"
], ],
...@@ -541,13 +576,13 @@ ...@@ -541,13 +576,13 @@
"win32" "win32"
], ],
"engines": { "engines": {
"node": ">=12" "node": ">=18"
} }
}, },
"node_modules/@esbuild/win32-x64": { "node_modules/@esbuild/win32-x64": {
"version": "0.21.5", "version": "0.25.1",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.1.tgz",
"integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", "integrity": "sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
...@@ -558,7 +593,7 @@ ...@@ -558,7 +593,7 @@
"win32" "win32"
], ],
"engines": { "engines": {
"node": ">=12" "node": ">=18"
} }
}, },
"node_modules/@eslint-community/eslint-utils": { "node_modules/@eslint-community/eslint-utils": {
...@@ -1506,12 +1541,21 @@ ...@@ -1506,12 +1541,21 @@
"version": "22.13.9", "version": "22.13.9",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.9.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.9.tgz",
"integrity": "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw==", "integrity": "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"undici-types": "~6.20.0" "undici-types": "~6.20.0"
} }
}, },
"node_modules/@types/node-fetch": {
"version": "2.6.12",
"resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.12.tgz",
"integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==",
"license": "MIT",
"dependencies": {
"@types/node": "*",
"form-data": "^4.0.0"
}
},
"node_modules/@types/prop-types": { "node_modules/@types/prop-types": {
"version": "15.7.14", "version": "15.7.14",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz",
...@@ -1756,6 +1800,18 @@ ...@@ -1756,6 +1800,18 @@
"vite": "^4 || ^5 || ^6" "vite": "^4 || ^5 || ^6"
} }
}, },
"node_modules/abort-controller": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
"integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
"license": "MIT",
"dependencies": {
"event-target-shim": "^5.0.0"
},
"engines": {
"node": ">=6.5"
}
},
"node_modules/acorn": { "node_modules/acorn": {
"version": "8.14.1", "version": "8.14.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
...@@ -1779,6 +1835,18 @@ ...@@ -1779,6 +1835,18 @@
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
} }
}, },
"node_modules/agentkeepalive": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz",
"integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==",
"license": "MIT",
"dependencies": {
"humanize-ms": "^1.2.1"
},
"engines": {
"node": ">= 8.0.0"
}
},
"node_modules/ajv": { "node_modules/ajv": {
"version": "6.12.6", "version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
...@@ -1911,9 +1979,9 @@ ...@@ -1911,9 +1979,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/axios": { "node_modules/axios": {
"version": "1.8.1", "version": "1.8.3",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.8.1.tgz", "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.3.tgz",
"integrity": "sha512-NN+fvwH/kV01dYUQ3PTOZns4LWtWhOFCAhQ/pHb88WQ1hNe5V/dvFwc4VJcDL11LT9xSX0QtsR8sWUuyOuOq7g==", "integrity": "sha512-iP4DebzoNlP/YN2dpwCgb8zoCmhtkajzS48JvwmkSkXvPI3DHc7m+XYL5tGnSlJtR6nImXZmdCuN5aP8dh1d8A==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"follow-redirects": "^1.15.6", "follow-redirects": "^1.15.6",
...@@ -2331,9 +2399,9 @@ ...@@ -2331,9 +2399,9 @@
} }
}, },
"node_modules/esbuild": { "node_modules/esbuild": {
"version": "0.21.5", "version": "0.25.1",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.1.tgz",
"integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", "integrity": "sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==",
"dev": true, "dev": true,
"hasInstallScript": true, "hasInstallScript": true,
"license": "MIT", "license": "MIT",
...@@ -2341,32 +2409,34 @@ ...@@ -2341,32 +2409,34 @@
"esbuild": "bin/esbuild" "esbuild": "bin/esbuild"
}, },
"engines": { "engines": {
"node": ">=12" "node": ">=18"
}, },
"optionalDependencies": { "optionalDependencies": {
"@esbuild/aix-ppc64": "0.21.5", "@esbuild/aix-ppc64": "0.25.1",
"@esbuild/android-arm": "0.21.5", "@esbuild/android-arm": "0.25.1",
"@esbuild/android-arm64": "0.21.5", "@esbuild/android-arm64": "0.25.1",
"@esbuild/android-x64": "0.21.5", "@esbuild/android-x64": "0.25.1",
"@esbuild/darwin-arm64": "0.21.5", "@esbuild/darwin-arm64": "0.25.1",
"@esbuild/darwin-x64": "0.21.5", "@esbuild/darwin-x64": "0.25.1",
"@esbuild/freebsd-arm64": "0.21.5", "@esbuild/freebsd-arm64": "0.25.1",
"@esbuild/freebsd-x64": "0.21.5", "@esbuild/freebsd-x64": "0.25.1",
"@esbuild/linux-arm": "0.21.5", "@esbuild/linux-arm": "0.25.1",
"@esbuild/linux-arm64": "0.21.5", "@esbuild/linux-arm64": "0.25.1",
"@esbuild/linux-ia32": "0.21.5", "@esbuild/linux-ia32": "0.25.1",
"@esbuild/linux-loong64": "0.21.5", "@esbuild/linux-loong64": "0.25.1",
"@esbuild/linux-mips64el": "0.21.5", "@esbuild/linux-mips64el": "0.25.1",
"@esbuild/linux-ppc64": "0.21.5", "@esbuild/linux-ppc64": "0.25.1",
"@esbuild/linux-riscv64": "0.21.5", "@esbuild/linux-riscv64": "0.25.1",
"@esbuild/linux-s390x": "0.21.5", "@esbuild/linux-s390x": "0.25.1",
"@esbuild/linux-x64": "0.21.5", "@esbuild/linux-x64": "0.25.1",
"@esbuild/netbsd-x64": "0.21.5", "@esbuild/netbsd-arm64": "0.25.1",
"@esbuild/openbsd-x64": "0.21.5", "@esbuild/netbsd-x64": "0.25.1",
"@esbuild/sunos-x64": "0.21.5", "@esbuild/openbsd-arm64": "0.25.1",
"@esbuild/win32-arm64": "0.21.5", "@esbuild/openbsd-x64": "0.25.1",
"@esbuild/win32-ia32": "0.21.5", "@esbuild/sunos-x64": "0.25.1",
"@esbuild/win32-x64": "0.21.5" "@esbuild/win32-arm64": "0.25.1",
"@esbuild/win32-ia32": "0.25.1",
"@esbuild/win32-x64": "0.25.1"
} }
}, },
"node_modules/escape-string-regexp": { "node_modules/escape-string-regexp": {
...@@ -2440,16 +2510,16 @@ ...@@ -2440,16 +2510,16 @@
} }
}, },
"node_modules/eslint-plugin-react-hooks": { "node_modules/eslint-plugin-react-hooks": {
"version": "4.6.2", "version": "5.2.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz",
"integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", "integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=10" "node": ">=10"
}, },
"peerDependencies": { "peerDependencies": {
"eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0"
} }
}, },
"node_modules/eslint-plugin-react-refresh": { "node_modules/eslint-plugin-react-refresh": {
...@@ -2590,6 +2660,15 @@ ...@@ -2590,6 +2660,15 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/event-target-shim": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
"integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/extend": { "node_modules/extend": {
"version": "3.0.2", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
...@@ -2757,6 +2836,25 @@ ...@@ -2757,6 +2836,25 @@
"node": ">= 6" "node": ">= 6"
} }
}, },
"node_modules/form-data-encoder": {
"version": "1.7.2",
"resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz",
"integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==",
"license": "MIT"
},
"node_modules/formdata-node": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz",
"integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==",
"license": "MIT",
"dependencies": {
"node-domexception": "1.0.0",
"web-streams-polyfill": "4.0.0-beta.3"
},
"engines": {
"node": ">= 12.20"
}
},
"node_modules/fs.realpath": { "node_modules/fs.realpath": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
...@@ -3039,6 +3137,15 @@ ...@@ -3039,6 +3137,15 @@
"url": "https://opencollective.com/unified" "url": "https://opencollective.com/unified"
} }
}, },
"node_modules/humanize-ms": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
"integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==",
"license": "MIT",
"dependencies": {
"ms": "^2.0.0"
}
},
"node_modules/ignore": { "node_modules/ignore": {
"version": "5.3.2", "version": "5.3.2",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
...@@ -4304,6 +4411,45 @@ ...@@ -4304,6 +4411,45 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/node-domexception": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
"integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/jimmywarting"
},
{
"type": "github",
"url": "https://paypal.me/jimmywarting"
}
],
"license": "MIT",
"engines": {
"node": ">=10.5.0"
}
},
"node_modules/node-fetch": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
"license": "MIT",
"dependencies": {
"whatwg-url": "^5.0.0"
},
"engines": {
"node": "4.x || >=6.0.0"
},
"peerDependencies": {
"encoding": "^0.1.0"
},
"peerDependenciesMeta": {
"encoding": {
"optional": true
}
}
},
"node_modules/once": { "node_modules/once": {
"version": "1.4.0", "version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
...@@ -4314,6 +4460,51 @@ ...@@ -4314,6 +4460,51 @@
"wrappy": "1" "wrappy": "1"
} }
}, },
"node_modules/openai": {
"version": "4.87.3",
"resolved": "https://registry.npmjs.org/openai/-/openai-4.87.3.tgz",
"integrity": "sha512-d2D54fzMuBYTxMW8wcNmhT1rYKcTfMJ8t+4KjH2KtvYenygITiGBgHoIrzHwnDQWW+C5oCA+ikIR2jgPCFqcKQ==",
"license": "Apache-2.0",
"dependencies": {
"@types/node": "^18.11.18",
"@types/node-fetch": "^2.6.4",
"abort-controller": "^3.0.0",
"agentkeepalive": "^4.2.1",
"form-data-encoder": "1.7.2",
"formdata-node": "^4.3.2",
"node-fetch": "^2.6.7"
},
"bin": {
"openai": "bin/cli"
},
"peerDependencies": {
"ws": "^8.18.0",
"zod": "^3.23.8"
},
"peerDependenciesMeta": {
"ws": {
"optional": true
},
"zod": {
"optional": true
}
}
},
"node_modules/openai/node_modules/@types/node": {
"version": "18.19.80",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.80.tgz",
"integrity": "sha512-kEWeMwMeIvxYkeg1gTc01awpwLbfMRZXdIhwRcakd/KlK53jmRC26LqcbIt7fnAQTu5GzlnWmzA3H6+l1u6xxQ==",
"license": "MIT",
"dependencies": {
"undici-types": "~5.26.4"
}
},
"node_modules/openai/node_modules/undici-types": {
"version": "5.26.5",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
"license": "MIT"
},
"node_modules/optionator": { "node_modules/optionator": {
"version": "0.9.4", "version": "0.9.4",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
...@@ -6057,6 +6248,12 @@ ...@@ -6057,6 +6248,12 @@
"integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==", "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
"license": "MIT"
},
"node_modules/trim-lines": { "node_modules/trim-lines": {
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz",
...@@ -6147,7 +6344,6 @@ ...@@ -6147,7 +6344,6 @@
"version": "6.20.0", "version": "6.20.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
"integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/unified": { "node_modules/unified": {
...@@ -6283,21 +6479,21 @@ ...@@ -6283,21 +6479,21 @@
} }
}, },
"node_modules/vite": { "node_modules/vite": {
"version": "5.4.14", "version": "6.2.2",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.14.tgz", "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.2.tgz",
"integrity": "sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==", "integrity": "sha512-yW7PeMM+LkDzc7CgJuRLMW2Jz0FxMOsVJ8Lv3gpgW9WLcb9cTW+121UEr1hvmfR7w3SegR5ItvYyzVz1vxNJgQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"esbuild": "^0.21.3", "esbuild": "^0.25.0",
"postcss": "^8.4.43", "postcss": "^8.5.3",
"rollup": "^4.20.0" "rollup": "^4.30.1"
}, },
"bin": { "bin": {
"vite": "bin/vite.js" "vite": "bin/vite.js"
}, },
"engines": { "engines": {
"node": "^18.0.0 || >=20.0.0" "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
}, },
"funding": { "funding": {
"url": "https://github.com/vitejs/vite?sponsor=1" "url": "https://github.com/vitejs/vite?sponsor=1"
...@@ -6306,19 +6502,25 @@ ...@@ -6306,19 +6502,25 @@
"fsevents": "~2.3.3" "fsevents": "~2.3.3"
}, },
"peerDependencies": { "peerDependencies": {
"@types/node": "^18.0.0 || >=20.0.0", "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
"jiti": ">=1.21.0",
"less": "*", "less": "*",
"lightningcss": "^1.21.0", "lightningcss": "^1.21.0",
"sass": "*", "sass": "*",
"sass-embedded": "*", "sass-embedded": "*",
"stylus": "*", "stylus": "*",
"sugarss": "*", "sugarss": "*",
"terser": "^5.4.0" "terser": "^5.16.0",
"tsx": "^4.8.1",
"yaml": "^2.4.2"
}, },
"peerDependenciesMeta": { "peerDependenciesMeta": {
"@types/node": { "@types/node": {
"optional": true "optional": true
}, },
"jiti": {
"optional": true
},
"less": { "less": {
"optional": true "optional": true
}, },
...@@ -6339,17 +6541,23 @@ ...@@ -6339,17 +6541,23 @@
}, },
"terser": { "terser": {
"optional": true "optional": true
},
"tsx": {
"optional": true
},
"yaml": {
"optional": true
} }
} }
}, },
"node_modules/vite-plugin-mkcert": { "node_modules/vite-plugin-mkcert": {
"version": "1.17.7", "version": "1.17.8",
"resolved": "https://registry.npmjs.org/vite-plugin-mkcert/-/vite-plugin-mkcert-1.17.7.tgz", "resolved": "https://registry.npmjs.org/vite-plugin-mkcert/-/vite-plugin-mkcert-1.17.8.tgz",
"integrity": "sha512-w6897ZmEbn1dzQxY9fxXZBMEFNxeHWYDLJb42DBHSbLx+ASRnq5Mfy4v9bDMhqIGDz9ufhm2qXbVoCFe+8dazg==", "integrity": "sha512-S+4tNEyGqdZQ3RLAG54ETeO2qyURHWrVjUWKYikLAbmhh/iJ+36gDEja4OWwFyXNuvyXcZwNt5TZZR9itPeG5Q==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"axios": "^1.8.1", "axios": "^1.8.3",
"debug": "^4.4.0", "debug": "^4.4.0",
"picocolors": "^1.1.1" "picocolors": "^1.1.1"
}, },
...@@ -6360,6 +6568,31 @@ ...@@ -6360,6 +6568,31 @@
"vite": ">=3" "vite": ">=3"
} }
}, },
"node_modules/web-streams-polyfill": {
"version": "4.0.0-beta.3",
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz",
"integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==",
"license": "MIT",
"engines": {
"node": ">= 14"
}
},
"node_modules/webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
"license": "BSD-2-Clause"
},
"node_modules/whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
"license": "MIT",
"dependencies": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
}
},
"node_modules/which": { "node_modules/which": {
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
......
...@@ -14,12 +14,13 @@ ...@@ -14,12 +14,13 @@
"@fortaine/fetch-event-source": "^3.0.6", "@fortaine/fetch-event-source": "^3.0.6",
"@tanstack/react-query": "^5.67.1", "@tanstack/react-query": "^5.67.1",
"antd": "^5.24.3", "antd": "^5.24.3",
"axios": "^1.8.1", "axios": "^1.8.3",
"blueimp-md5": "^2.19.0", "blueimp-md5": "^2.19.0",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"lucide-react": "^0.477.0", "lucide-react": "^0.477.0",
"react": "^18.2.0", "openai": "^4.87.3",
"react-dom": "^18.2.0", "react": "^18.3.1",
"react-dom": "^18.3.1",
"react-markdown": "^10.1.0", "react-markdown": "^10.1.0",
"react-router": "^7.3.0", "react-router": "^7.3.0",
"remark-gfm": "^4.0.1", "remark-gfm": "^4.0.1",
...@@ -30,17 +31,17 @@ ...@@ -30,17 +31,17 @@
"@types/blueimp-md5": "^2.18.2", "@types/blueimp-md5": "^2.18.2",
"@types/lodash-es": "^4.17.12", "@types/lodash-es": "^4.17.12",
"@types/node": "^22.13.9", "@types/node": "^22.13.9",
"@types/react": "^18.2.66", "@types/react": "^18.3.18",
"@types/react-dom": "^18.2.22", "@types/react-dom": "^18.3.5",
"@typescript-eslint/eslint-plugin": "^7.2.0", "@typescript-eslint/eslint-plugin": "^7.18.0",
"@typescript-eslint/parser": "^7.2.0", "@typescript-eslint/parser": "^7.18.0",
"@vitejs/plugin-react-swc": "^3.5.0", "@vitejs/plugin-react-swc": "^3.8.0",
"eslint": "^8.57.0", "eslint": "^8.57.0",
"eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-react-refresh": "^0.4.6", "eslint-plugin-react-refresh": "^0.4.19",
"sass-embedded": "^1.85.1", "sass-embedded": "^1.85.1",
"typescript": "^5.2.2", "typescript": "^5.2.2",
"vite": "^5.2.0", "vite": "^6.2.2",
"vite-plugin-mkcert": "^1.17.7" "vite-plugin-mkcert": "^1.17.8"
} }
} }
...@@ -36,10 +36,1102 @@ export function getMapList() { ...@@ -36,10 +36,1102 @@ export function getMapList() {
// 我的数据集列表 // 我的数据集列表
export function getMyList(params?: Partial<{ page: number; 'per-page': number }>) { export function getMyList(params?: Partial<{ page: number; 'per-page': number }>) {
return Promise.resolve({
code: 0,
message: 'OK',
data: {
total: 10,
title: [
{
name: '序号',
english_name: 'pk_id',
type: 'INT',
},
{
name: '订单编号',
english_name: 'order_number',
type: 'VARCHAR(7)',
},
{
name: '品牌',
english_name: 'brand',
type: 'VARCHAR(12)',
},
{
name: '店铺',
english_name: 'store',
type: 'VARCHAR(21)',
},
{
name: '负责人',
english_name: 'person_in_charge',
type: 'VARCHAR(9)',
},
{
name: '商品',
english_name: 'product',
type: 'VARCHAR(21)',
},
{
name: '颜色',
english_name: 'color',
type: 'VARCHAR(6)',
},
{
name: '客户购买类型',
english_name: 'customer_purchase_type',
type: 'VARCHAR(6)',
},
{
name: '销量',
english_name: 'sales_volume',
type: 'SMALLINT',
},
{
name: '单价',
english_name: 'unit_price',
type: 'DECIMAL(5, 2)',
},
{
name: '销售额',
english_name: 'sales_amount',
type: 'DECIMAL(6, 2)',
},
{
name: '是否优惠',
english_name: 'is_discounted',
type: 'VARCHAR(18)',
},
{
name: '优惠金额',
english_name: 'discount_amount',
type: 'SMALLINT',
},
{
name: '实际单价',
english_name: 'actual_unit_price',
type: 'DECIMAL(5, 2)',
},
{
name: '实际付款',
english_name: 'actual_payment',
type: 'DECIMAL(6, 2)',
},
{
name: '成本',
english_name: 'cost',
type: 'DECIMAL(7, 3)',
},
{
name: '利润',
english_name: 'profit',
type: 'DECIMAL(6, 3)',
},
{
name: '客户性别',
english_name: 'customer_gender',
type: 'TINYINT',
},
{
name: '客户年龄',
english_name: 'customer_age',
type: 'VARCHAR(5)',
},
{
name: '会员情况',
english_name: 'membership_status',
type: 'VARCHAR(12)',
},
{
name: '是否访问页面',
english_name: 'has_visited_page',
type: 'VARCHAR(3)',
},
{
name: '访问页面时长',
english_name: 'page_visit_duration',
type: 'TINYINT',
},
{
name: '交易状态',
english_name: 'transaction_status',
type: 'VARCHAR(12)',
},
{
name: '商品状态',
english_name: 'product_status',
type: 'VARCHAR(9)',
},
{
name: '收货人姓名',
english_name: 'recipient_name',
type: 'VARCHAR(9)',
},
{
name: '收货人电话',
english_name: 'recipient_phone',
type: 'VARCHAR(11)',
},
{
name: '发货地址',
english_name: 'shipping_address',
type: 'VARCHAR(9)',
},
{
name: '收货地址省份',
english_name: 'recipient_province',
type: 'VARCHAR(21)',
},
{
name: '收货地址',
english_name: 'recipient_address',
type: 'VARCHAR(39)',
},
{
name: '物流公司',
english_name: 'logistics_company',
type: 'VARCHAR(15)',
},
{
name: '运单号',
english_name: 'waybill_number',
type: 'VARCHAR(7)',
},
{
name: '运送方式',
english_name: 'shipping_method',
type: 'VARCHAR(12)',
},
{
name: '支付时间',
english_name: 'payment_time',
type: 'VARCHAR(10)',
},
{
name: '预计到达时间',
english_name: 'estimated_arrival_time',
type: 'VARCHAR(10)',
},
{
name: '实际到达时间',
english_name: 'actual_arrival_time',
type: 'VARCHAR(10)',
},
{
name: '快递反馈',
english_name: 'courier_feedback',
type: 'VARCHAR(6)',
},
{
name: '是否退货',
english_name: 'is_returned',
type: 'VARCHAR(3)',
},
{
name: '退款原因',
english_name: 'refund_reason',
type: 'VARCHAR(9)',
},
{
name: '客户满意度',
english_name: 'customer_satisfaction',
type: 'VARCHAR(9)',
},
{
name: '出生日期',
english_name: 'date_of_birth',
type: 'VARCHAR(17)',
},
{
name: '品类',
english_name: 'category',
type: 'VARCHAR(9)',
},
{
name: '材质',
english_name: 'material',
type: 'VARCHAR(6)',
},
],
list: [
{
pk_id: '1',
order_number: 'A929818',
brand: '丽丽',
store: '卡卡家女装',
person_in_charge: '袁英',
product: '安全裤',
color: '红色',
customer_purchase_type: '零售',
sales_volume: '256',
unit_price: '156.14',
sales_amount: '156.14',
is_discounted: '店铺活动优惠',
discount_amount: '12',
actual_unit_price: '144.14',
actual_payment: '144.14',
cost: '99.460',
profit: '44.680',
customer_gender: '0',
customer_age: '33岁',
membership_status: '无会员',
has_visited_page: '是',
page_visit_duration: '2',
transaction_status: '交易成功',
product_status: '已收货',
recipient_name: '孙倩',
recipient_phone: '181****4056',
shipping_address: '福建省',
recipient_province: '陕西省',
recipient_address: '陕西省延安市子长县',
logistics_company: ' 百世快递',
waybill_number: 'L810590',
shipping_method: '公路运输',
payment_time: '6/21/2020',
estimated_arrival_time: '6/26/2020',
actual_arrival_time: '6/26/2020',
courier_feedback: '准时',
is_returned: '否',
refund_reason: '无',
customer_satisfaction: '中评',
date_of_birth: '1989年10月26日',
category: '女裤',
material: '麻质',
},
{
pk_id: '2',
order_number: 'A451538',
brand: '雅羊人',
store: '秋兰女装专卖店',
person_in_charge: '刘佳',
product: '不规则连衣裙',
color: '粉色',
customer_purchase_type: '零售',
sales_volume: '198',
unit_price: '247.44',
sales_amount: '247.44',
is_discounted: '无',
discount_amount: '0',
actual_unit_price: '247.44',
actual_payment: '247.44',
cost: '158.360',
profit: '89.080',
customer_gender: '0',
customer_age: '36岁',
membership_status: '无会员',
has_visited_page: '是',
page_visit_duration: '8',
transaction_status: '交易成功',
product_status: '已收货',
recipient_name: '余玉英',
recipient_phone: '181****8027',
shipping_address: '广东省',
recipient_province: '⼴西壮族⾃治区',
recipient_address: '广西壮族自治区贵港市',
logistics_company: '极兔快 递',
waybill_number: 'L806051',
shipping_method: '公路运输',
payment_time: '4/13/2023',
estimated_arrival_time: '4/15/2023',
actual_arrival_time: '4/15/2023',
courier_feedback: '准时',
is_returned: '否',
refund_reason: '无',
customer_satisfaction: '好评',
date_of_birth: '1986年7月17日',
category: '连衣裙',
material: '氨纶',
},
{
pk_id: '3',
order_number: 'A479212',
brand: '威兰西',
store: '威兰西旗舰店',
person_in_charge: '陈建平',
product: '网红同款连衣裙',
color: '白色',
customer_purchase_type: '零售',
sales_volume: '128',
unit_price: '245.49',
sales_amount: '245.49',
is_discounted: '双12优惠',
discount_amount: '15',
actual_unit_price: '230.49',
actual_payment: '230.49',
cost: '117.550',
profit: '112.940',
customer_gender: '0',
customer_age: '22岁',
membership_status: '无会员',
has_visited_page: '是',
page_visit_duration: '4',
transaction_status: '交易成功',
product_status: '已收货',
recipient_name: '杨军',
recipient_phone: '139****7024',
shipping_address: '浙江省',
recipient_province: '河北省',
recipient_address: '河北省衡水市武强县',
logistics_company: '顺丰快递',
waybill_number: 'L356804',
shipping_method: '公路运输',
payment_time: '12/1/2019',
estimated_arrival_time: '12/6/2019',
actual_arrival_time: '12/7/2019',
courier_feedback: '延后',
is_returned: '否',
refund_reason: '无',
customer_satisfaction: '好评',
date_of_birth: '2000年5月3日',
category: '连衣裙',
material: '棉质',
},
{
pk_id: '4',
order_number: 'A389270',
brand: 'H&R',
store: '壹佰女装',
person_in_charge: '杨兰英',
product: '蕾丝花边T恤',
color: '紫色',
customer_purchase_type: '批发',
sales_volume: '13',
unit_price: '168.30',
sales_amount: '2187.90',
is_discounted: '双11优惠',
discount_amount: '200',
actual_unit_price: '152.92',
actual_payment: '1987.90',
cost: '1013.830',
profit: '974.070',
customer_gender: '0',
customer_age: '26岁',
membership_status: '无会员',
has_visited_page: '是',
page_visit_duration: '4',
transaction_status: '交易成功',
product_status: '已收货',
recipient_name: '郑强',
recipient_phone: '159****6299',
shipping_address: '四川省',
recipient_province: '河南省',
recipient_address: '河南省郑州市新密市',
logistics_company: '顺丰快递',
waybill_number: 'L335437',
shipping_method: '公路运输',
payment_time: '11/10/2019',
estimated_arrival_time: '11/14/2019',
actual_arrival_time: '11/15/2019',
courier_feedback: '延后',
is_returned: '否',
refund_reason: '无',
customer_satisfaction: '好评',
date_of_birth: '1996年5月4日',
category: '上衣',
material: '棉质',
},
{
pk_id: '5',
order_number: 'A327122',
brand: 'H&R',
store: 'H&R旗舰店',
person_in_charge: '袁英',
product: '春夏新款连衣裙',
color: '红色',
customer_purchase_type: '批发',
sales_volume: '13',
unit_price: '119.64',
sales_amount: '1555.32',
is_discounted: '无',
discount_amount: '0',
actual_unit_price: '119.64',
actual_payment: '1555.32',
cost: '839.870',
profit: '715.450',
customer_gender: '0',
customer_age: '22岁',
membership_status: '无会员',
has_visited_page: '是',
page_visit_duration: '8',
transaction_status: '交易成功',
product_status: '已收货',
recipient_name: '刘冬梅',
recipient_phone: '185****4586',
shipping_address: '广东省',
recipient_province: '陕西省',
recipient_address: '陕西省延安市富县',
logistics_company: '中通快递',
waybill_number: 'L209106',
shipping_method: '公路运输',
payment_time: '4/28/2019',
estimated_arrival_time: '4/30/2019',
actual_arrival_time: '4/30/2019',
courier_feedback: '准时',
is_returned: '否',
refund_reason: '无',
customer_satisfaction: '无评论',
date_of_birth: '2000年7月3日',
category: '连衣裙',
material: '氨纶',
},
{
pk_id: '6',
order_number: 'A577484',
brand: 'H&R',
store: 'COCO女装',
person_in_charge: '刘佳',
product: '秋冬款连衣裙',
color: '粉色',
customer_purchase_type: '批发',
sales_volume: '12',
unit_price: '173.70',
sales_amount: '2084.40',
is_discounted: '店铺活动优惠',
discount_amount: '100',
actual_unit_price: '165.37',
actual_payment: '1984.40',
cost: '1091.420',
profit: '892.980',
customer_gender: '0',
customer_age: '61岁',
membership_status: '钻石会员',
has_visited_page: '是',
page_visit_duration: '7',
transaction_status: '交易成功',
product_status: '已收货',
recipient_name: '谢博',
recipient_phone: '147****5024',
shipping_address: '广东省',
recipient_province: '⽢肃省',
recipient_address: '甘肃省甘南藏族自治州卓尼县',
logistics_company: '申通快递',
waybill_number: 'L913348',
shipping_method: '航空运输',
payment_time: '4/7/2019',
estimated_arrival_time: '4/11/2019',
actual_arrival_time: '4/11/2019',
courier_feedback: '准时',
is_returned: '否',
refund_reason: '无',
customer_satisfaction: '中评',
date_of_birth: '1961年8月12日',
category: '连衣裙',
material: '麻质',
},
{
pk_id: '7',
order_number: 'A293474',
brand: '拉夏贝尔',
store: '拉夏贝尔旗舰店',
person_in_charge: '刘佳',
product: '泫雅风T恤',
color: '粉色',
customer_purchase_type: '批发',
sales_volume: '12',
unit_price: '162.02',
sales_amount: '1944.24',
is_discounted: '双11优惠',
discount_amount: '200',
actual_unit_price: '145.35',
actual_payment: '1744.24',
cost: '1186.080',
profit: '558.160',
customer_gender: '0',
customer_age: '59岁',
membership_status: '普通会员',
has_visited_page: '是',
page_visit_duration: '2',
transaction_status: '交易成功',
product_status: '已收货',
recipient_name: '赵丽丽',
recipient_phone: '186****8566',
shipping_address: '浙江省',
recipient_province: '⼴东省',
recipient_address: '广东省梅州市',
logistics_company: '圆通快递',
waybill_number: 'L841704',
shipping_method: '铁路运输',
payment_time: '11/10/2019',
estimated_arrival_time: '11/15/2019',
actual_arrival_time: '11/15/2019',
courier_feedback: '准时',
is_returned: '否',
refund_reason: '无',
customer_satisfaction: '中评',
date_of_birth: '1963年5月27日',
category: '上衣',
material: '氨纶',
},
{
pk_id: '8',
order_number: 'A424004',
brand: '艾米丽',
store: '卡卡家女装',
person_in_charge: '宋建华',
product: '大码牛仔裤',
color: '红色',
customer_purchase_type: '批发',
sales_volume: '11',
unit_price: '73.54',
sales_amount: '808.94',
is_discounted: '双11优惠',
discount_amount: '100',
actual_unit_price: '64.45',
actual_payment: '708.94',
cost: '425.360',
profit: '283.580',
customer_gender: '0',
customer_age: '23岁',
membership_status: '无会员',
has_visited_page: '是',
page_visit_duration: '8',
transaction_status: '交易成功',
product_status: '已收货',
recipient_name: '谢雷',
recipient_phone: '150****7487',
shipping_address: '浙江省',
recipient_province: '宁夏回族自治区',
recipient_address: '宁夏回族自治区银川市贺兰县',
logistics_company: ' 百世快递',
waybill_number: 'L451724',
shipping_method: '公路运输',
payment_time: '11/27/2023',
estimated_arrival_time: '12/1/2023',
actual_arrival_time: '12/1/2023',
courier_feedback: '准时',
is_returned: '否',
refund_reason: '无',
customer_satisfaction: '好评',
date_of_birth: '1999年12月18日',
category: '女裤',
material: '锦纶',
},
{
pk_id: '9',
order_number: 'A561021',
brand: 'TARA',
store: 'TARA旗舰店',
person_in_charge: '邹勇',
product: '春夏季新款裤子',
color: '橙色',
customer_purchase_type: '批发',
sales_volume: '11',
unit_price: '57.25',
sales_amount: '629.75',
is_discounted: '双12优惠',
discount_amount: '150',
actual_unit_price: '43.61',
actual_payment: '479.75',
cost: '287.850',
profit: '191.900',
customer_gender: '0',
customer_age: '36岁',
membership_status: '普通会员',
has_visited_page: '是',
page_visit_duration: '7',
transaction_status: '交易成功',
product_status: '已收货',
recipient_name: '王桂珍',
recipient_phone: '137****8424',
shipping_address: '福建省',
recipient_province: '湖南省',
recipient_address: '湖南省永州市市辖区',
logistics_company: '申通快递',
waybill_number: 'L948843',
shipping_method: '公路运输',
payment_time: '12/17/2019',
estimated_arrival_time: '12/19/2019',
actual_arrival_time: '12/19/2019',
courier_feedback: '准时',
is_returned: '否',
refund_reason: '无',
customer_satisfaction: '好评',
date_of_birth: '1986年6月1日',
category: '女裤',
material: '锦纶',
},
{
pk_id: '10',
order_number: 'A191677',
brand: '富贵人',
store: '富贵人旗舰店',
person_in_charge: '刘佳',
product: '蕾丝花边T恤',
color: '粉色',
customer_purchase_type: '批发',
sales_volume: '11',
unit_price: '117.92',
sales_amount: '1297.12',
is_discounted: '无',
discount_amount: '0',
actual_unit_price: '117.92',
actual_payment: '1297.12',
cost: '674.500',
profit: '622.620',
customer_gender: '0',
customer_age: '38岁',
membership_status: '无会员',
has_visited_page: '否',
page_visit_duration: '0',
transaction_status: '交易取消',
product_status: '已取消',
recipient_name: '梁秀华',
recipient_phone: '136****1451',
shipping_address: '广东省',
recipient_province: '⼭东省',
recipient_address: '山东省聊城市冠县',
logistics_company: '申通快递',
waybill_number: 'L385723',
shipping_method: '航空运输',
payment_time: '12/3/2019',
estimated_arrival_time: '12/8/2019',
actual_arrival_time: '12/8/2019',
courier_feedback: '准时',
is_returned: '是',
refund_reason: '不喜欢',
customer_satisfaction: '无评论',
date_of_birth: '1984年2月27日',
category: '上衣',
material: '棉质',
},
],
info: {
id: '7306145818979860480',
experiment_id: '7028276368903241728',
name: '王',
table_name: '7028276368903241728_6602032005293015040_my_data',
type: '2',
source: {
name: '《商务数据分析基础》数据集-电子商务-10条.xlsx',
url: 'https://webapp-pub.ezijing.com/upload/saas-bi/f6a1ab335e0a19935b750537e5d8a6f2.xlsx',
},
created_operator: '6602032005293015040',
created_time: '2025-03-14 10:55:04',
updated_operator: '6602032005293015040',
updated_time: '2025-03-14 16:31:47',
},
},
})
return httpRequest.get('/api/bi/v1/data/my/list', { params }) return httpRequest.get('/api/bi/v1/data/my/list', { params })
} }
// 查看字段详情 // 查看字段详情
export function getMyField() { export function getMyField() {
return Promise.resolve({
code: 0,
message: 'OK',
data: [
{
name: '订单编号',
english_name: 'order_number',
type: 'VARCHAR(7)',
length: '7',
point: '',
null: '允许',
default: '',
type_name: '字符串',
},
{
name: '品牌',
english_name: 'brand',
type: 'VARCHAR(12)',
length: '12',
point: '',
null: '允许',
default: '',
type_name: '字符串',
},
{
name: '店铺',
english_name: 'store',
type: 'VARCHAR(21)',
length: '21',
point: '',
null: '允许',
default: '',
type_name: '字符串',
},
{
name: '负责人',
english_name: 'person_in_charge',
type: 'VARCHAR(9)',
length: '9',
point: '',
null: '允许',
default: '',
type_name: '字符串',
},
{
name: '商品',
english_name: 'product',
type: 'VARCHAR(21)',
length: '21',
point: '',
null: '允许',
default: '',
type_name: '字符串',
},
{
name: '颜色',
english_name: 'color',
type: 'VARCHAR(6)',
length: '6',
point: '',
null: '允许',
default: '',
type_name: '字符串',
},
{
name: '客户购买类型',
english_name: 'customer_purchase_type',
type: 'VARCHAR(6)',
length: '6',
point: '',
null: '允许',
default: '',
type_name: '字符串',
},
{
name: '销量',
english_name: 'sales_volume',
type: 'SMALLINT',
length: '',
point: '',
null: '允许',
default: '',
type_name: '整数',
},
{
name: '单价',
english_name: 'unit_price',
type: 'DECIMAL(5, 2)',
length: '5',
point: '2',
null: '允许',
default: '',
type_name: '小数',
},
{
name: '销售额',
english_name: 'sales_amount',
type: 'DECIMAL(6, 2)',
length: '6',
point: '2',
null: '允许',
default: '',
type_name: '小数',
},
{
name: '是否优惠',
english_name: 'is_discounted',
type: 'VARCHAR(18)',
length: '18',
point: '',
null: '允许',
default: '',
type_name: '字符串',
},
{
name: '优惠金额',
english_name: 'discount_amount',
type: 'SMALLINT',
length: '',
point: '',
null: '允许',
default: '',
type_name: '整数',
},
{
name: '实际单价',
english_name: 'actual_unit_price',
type: 'DECIMAL(5, 2)',
length: '5',
point: '2',
null: '允许',
default: '',
type_name: '小数',
},
{
name: '实际付款',
english_name: 'actual_payment',
type: 'DECIMAL(6, 2)',
length: '6',
point: '2',
null: '允许',
default: '',
type_name: '小数',
},
{
name: '成本',
english_name: 'cost',
type: 'DECIMAL(7, 3)',
length: '7',
point: '3',
null: '允许',
default: '',
type_name: '小数',
},
{
name: '利润',
english_name: 'profit',
type: 'DECIMAL(6, 3)',
length: '6',
point: '3',
null: '允许',
default: '',
type_name: '小数',
},
{
name: '客户性别',
english_name: 'customer_gender',
type: 'TINYINT',
length: '',
point: '',
null: '允许',
default: '',
type_name: '整数',
},
{
name: '客户年龄',
english_name: 'customer_age',
type: 'VARCHAR(5)',
length: '5',
point: '',
null: '允许',
default: '',
type_name: '字符串',
},
{
name: '会员情况',
english_name: 'membership_status',
type: 'VARCHAR(12)',
length: '12',
point: '',
null: '允许',
default: '',
type_name: '字符串',
},
{
name: '是否访问页面',
english_name: 'has_visited_page',
type: 'VARCHAR(3)',
length: '3',
point: '',
null: '允许',
default: '',
type_name: '字符串',
},
{
name: '访问页面时长',
english_name: 'page_visit_duration',
type: 'TINYINT',
length: '',
point: '',
null: '允许',
default: '',
type_name: '整数',
},
{
name: '交易状态',
english_name: 'transaction_status',
type: 'VARCHAR(12)',
length: '12',
point: '',
null: '允许',
default: '',
type_name: '字符串',
},
{
name: '商品状态',
english_name: 'product_status',
type: 'VARCHAR(9)',
length: '9',
point: '',
null: '允许',
default: '',
type_name: '字符串',
},
{
name: '收货人姓名',
english_name: 'recipient_name',
type: 'VARCHAR(9)',
length: '9',
point: '',
null: '允许',
default: '',
type_name: '字符串',
},
{
name: '收货人电话',
english_name: 'recipient_phone',
type: 'VARCHAR(11)',
length: '11',
point: '',
null: '允许',
default: '',
type_name: '字符串',
},
{
name: '发货地址',
english_name: 'shipping_address',
type: 'VARCHAR(9)',
length: '9',
point: '',
null: '允许',
default: '',
type_name: '字符串',
},
{
name: '收货地址省份',
english_name: 'recipient_province',
type: 'VARCHAR(21)',
length: '21',
point: '',
null: '允许',
default: '',
type_name: '字符串',
},
{
name: '收货地址',
english_name: 'recipient_address',
type: 'VARCHAR(39)',
length: '39',
point: '',
null: '允许',
default: '',
type_name: '字符串',
},
{
name: '物流公司',
english_name: 'logistics_company',
type: 'VARCHAR(15)',
length: '15',
point: '',
null: '允许',
default: '',
type_name: '字符串',
},
{
name: '运单号',
english_name: 'waybill_number',
type: 'VARCHAR(7)',
length: '7',
point: '',
null: '允许',
default: '',
type_name: '字符串',
},
{
name: '运送方式',
english_name: 'shipping_method',
type: 'VARCHAR(12)',
length: '12',
point: '',
null: '允许',
default: '',
type_name: '字符串',
},
{
name: '支付时间',
english_name: 'payment_time',
type: 'VARCHAR(10)',
length: '10',
point: '',
null: '允许',
default: '',
type_name: '字符串',
},
{
name: '预计到达时间',
english_name: 'estimated_arrival_time',
type: 'VARCHAR(10)',
length: '10',
point: '',
null: '允许',
default: '',
type_name: '字符串',
},
{
name: '实际到达时间',
english_name: 'actual_arrival_time',
type: 'VARCHAR(10)',
length: '10',
point: '',
null: '允许',
default: '',
type_name: '字符串',
},
{
name: '快递反馈',
english_name: 'courier_feedback',
type: 'VARCHAR(6)',
length: '6',
point: '',
null: '允许',
default: '',
type_name: '字符串',
},
{
name: '是否退货',
english_name: 'is_returned',
type: 'VARCHAR(3)',
length: '3',
point: '',
null: '允许',
default: '',
type_name: '字符串',
},
{
name: '退款原因',
english_name: 'refund_reason',
type: 'VARCHAR(9)',
length: '9',
point: '',
null: '允许',
default: '',
type_name: '字符串',
},
{
name: '客户满意度',
english_name: 'customer_satisfaction',
type: 'VARCHAR(9)',
length: '9',
point: '',
null: '允许',
default: '',
type_name: '字符串',
},
{
name: '出生日期',
english_name: 'date_of_birth',
type: 'VARCHAR(17)',
length: '17',
point: '',
null: '允许',
default: '',
type_name: '字符串',
},
{
name: '品类',
english_name: 'category',
type: 'VARCHAR(9)',
length: '9',
point: '',
null: '允许',
default: '',
type_name: '字符串',
},
{
name: '材质',
english_name: 'material',
type: 'VARCHAR(6)',
length: '6',
point: '',
null: '允许',
default: '',
type_name: '字符串',
},
],
})
return httpRequest.get('/api/bi/v1/data/my/field-detail') return httpRequest.get('/api/bi/v1/data/my/field-detail')
} }
...@@ -55,6 +55,7 @@ const AppList = forwardRef<AppListRef, AppListProps>( ...@@ -55,6 +55,7 @@ const AppList = forwardRef<AppListRef, AppListProps>(
} }
const pagination = { const pagination = {
hideOnSinglePage: true,
showSizeChanger: true, showSizeChanger: true,
showQuickJumper: true, showQuickJumper: true,
pageSizeOptions: [10, 20, 30, 40, 50], pageSizeOptions: [10, 20, 30, 40, 50],
......
...@@ -13,6 +13,8 @@ ...@@ -13,6 +13,8 @@
height: calc(100% - 56px); height: calc(100% - 56px);
} }
.input-container { .input-container {
padding: 10px;
background-color: #fff;
margin-top: 10px; margin-top: 10px;
fill: #fff; fill: #fff;
border: 1px solid #e0e3e6; border: 1px solid #e0e3e6;
...@@ -21,44 +23,41 @@ ...@@ -21,44 +23,41 @@
stroke: #d9d9d9; stroke: #d9d9d9;
filter: drop-shadow(0px 0px 11px rgba(0, 0, 0, 0.05)); filter: drop-shadow(0px 0px 11px rgba(0, 0, 0, 0.05));
transition: border-color 0.3s; transition: border-color 0.3s;
overflow: hidden; .input-box {
} .edit-area {
.input-box { max-height: 100px;
display: flex; overflow: hidden auto;
align-items: center; }
padding: 10px; .pre-prompt {
background-color: #fff; position: absolute;
.edit-area { top: 0;
flex: 1; left: 0;
position: relative; z-index: 1;
max-height: 160px; line-height: 1.7;
overflow: hidden auto; background-color: #e6eaf0;
} border-radius: 4px;
.pre-prompt { padding: 4px 8px 3px;
position: absolute; font-size: 14px;
top: 0; font-weight: 500;
left: 0; }
z-index: 1; .content {
line-height: 1.7; padding: 0;
background-color: #e6eaf0; border: 0;
border-radius: 4px; background: none;
padding: 4px 8px 3px; box-shadow: none;
font-size: 14px; font-size: 14px;
font-weight: 500; line-height: 30px;
} }
.content {
padding: 0;
border: 0;
background: none;
box-shadow: none;
font-size: 14px;
line-height: 30px;
} }
.input-tools { .input-tools {
align-self: flex-end; margin-top: 10px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between;
gap: 10px; gap: 10px;
.ant-select {
--ant-border-radius: 15px;
}
} }
} }
......
import { useState, KeyboardEvent } from 'react' import { useState, KeyboardEvent, useEffect, useRef } from 'react'
import { Button, Card, FloatButton, Select } from 'antd' import { Button, Card, FloatButton, Select } from 'antd'
import { CircleArrowLeft, CircleArrowRight } from 'lucide-react' import { CircleArrowLeft, CircleArrowRight } from 'lucide-react'
import './AIChat.scss' import './AIChat.scss'
import { OpenAIOutlined, SendOutlined } from '@ant-design/icons' import { OpenAIOutlined, ArrowUpOutlined } from '@ant-design/icons'
import TextArea from 'antd/es/input/TextArea' import TextArea from 'antd/es/input/TextArea'
import { useAI, AIMessage } from '@/hooks/useAI' import { useAI, AIMessage } from '@/hooks/useAI'
import Markdown from 'react-markdown' import Markdown from 'react-markdown'
...@@ -21,7 +21,7 @@ export const MessageItem = ({ message }: { message: AIMessage }) => { ...@@ -21,7 +21,7 @@ export const MessageItem = ({ message }: { message: AIMessage }) => {
} }
export default function AIChat() { export default function AIChat() {
const [collapsed, setCollapsed] = useState(false) const [collapsed, setCollapsed] = useState(true)
const toggleCollapsed = () => { const toggleCollapsed = () => {
setCollapsed(!collapsed) setCollapsed(!collapsed)
...@@ -42,6 +42,14 @@ export default function AIChat() { ...@@ -42,6 +42,14 @@ export default function AIChat() {
post({ content }) post({ content })
} }
const messageScrollRef = useRef<HTMLDivElement | null>(null)
useEffect(() => {
if (messageScrollRef.current) {
const scrollContainer = messageScrollRef.current
scrollContainer.scrollTop = scrollContainer.scrollHeight
}
}, [isLoading])
if (collapsed) { if (collapsed) {
return ( return (
<Card <Card
...@@ -49,12 +57,11 @@ export default function AIChat() { ...@@ -49,12 +57,11 @@ export default function AIChat() {
title="AI对话" title="AI对话"
extra={<span onClick={toggleCollapsed}>{collapsed ? <CircleArrowRight /> : <CircleArrowLeft />}</span>}> extra={<span onClick={toggleCollapsed}>{collapsed ? <CircleArrowRight /> : <CircleArrowLeft />}</span>}>
<div className="ai-chat-container"> <div className="ai-chat-container">
<div className="message-scroll"> <div className="message-scroll" ref={messageScrollRef}>
{messages.map((message) => { {messages.map((message) => {
return <MessageItem message={message}></MessageItem> return <MessageItem message={message}></MessageItem>
})} })}
</div> </div>
<Select value={ai} options={options} onChange={setAI} style={{ width: '100%' }}></Select>
<div className="input-container"> <div className="input-container">
<div className="input-box"> <div className="input-box">
<div className="edit-area"> <div className="edit-area">
...@@ -62,20 +69,27 @@ export default function AIChat() { ...@@ -62,20 +69,27 @@ export default function AIChat() {
className="content" className="content"
autoSize autoSize
value={content} value={content}
placeholder="今天需要我做些什么?shift+enter换行" placeholder="shift+enter换行"
onChange={(e) => setContent(e.target.value)} onChange={(e) => setContent(e.target.value)}
onKeyDown={handleEnterSearch} onKeyDown={handleEnterSearch}
/> />
</div> </div>
<div className="input-tools"> </div>
<Button <div className="input-tools">
type="primary" <Select
size="large" value={ai}
icon={<SendOutlined />} options={options}
onClick={handleSearch} onChange={setAI}
loading={isLoading} variant="filled"
/> suffixIcon={null}
</div> popupMatchSelectWidth={100}></Select>
<Button
type="primary"
shape="circle"
icon={<ArrowUpOutlined />}
onClick={handleSearch}
loading={isLoading}
/>
</div> </div>
<div className="upload-list"></div> <div className="upload-list"></div>
</div> </div>
......
...@@ -17,7 +17,7 @@ export default function DataWrap({ ...@@ -17,7 +17,7 @@ export default function DataWrap({
buttons?: ReactNode buttons?: ReactNode
headerRender?: (data: any) => ReactNode headerRender?: (data: any) => ReactNode
empty?: ReactNode empty?: ReactNode
hasAI: boolean hasAI?: boolean
}) { }) {
const [pagination, setPagination] = useState({ page: 1, 'per-page': 100 }) const [pagination, setPagination] = useState({ page: 1, 'per-page': 100 })
const { data, isPending } = useDataQuery(pagination) const { data, isPending } = useDataQuery(pagination)
......
import { useState } from 'react'
import { Button, Radio, Divider, Flex, Modal, Steps } from 'antd'
import type { RadioChangeEvent } from 'antd'
import { useNavigate } from 'react-router'
const plainOptions = ['会员情况', '客户满意度', '出生日期', '访问页面时长', '交易状态', '商品状态', '快递反馈']
export default function ButtonModal() {
const navigate = useNavigate()
const [open, setOpen] = useState(false)
const [current, setCurrent] = useState(0)
const [value, setValue] = useState(1)
const onChange = (e: RadioChangeEvent) => {
setValue(e.target.value)
}
const next = () => {
setCurrent(current + 1)
}
const prev = () => {
setCurrent(current - 1)
}
const steps = [
{
title: '探索逻辑错误字段',
},
{
title: '处理逻辑错误',
},
]
const style: React.CSSProperties = {
display: 'flex',
flexDirection: 'column',
gap: 8,
}
return (
<>
<Button type="primary" onClick={() => setOpen(true)}>
逻辑错误值
</Button>
<Modal
title="逻辑错误值探索"
open={open}
footer={
<Flex justify="center" gap={20}>
{current === 0 && <Button type="primary">智能探索字段数据逻辑错误</Button>}
{current > 0 && (
<Button style={{ margin: '0 8px' }} onClick={() => prev()}>
上一步
</Button>
)}
{current < steps.length - 1 && (
<Button type="primary" onClick={() => next()}>
下一步
</Button>
)}
{current === steps.length - 1 && (
<Button type="primary" onClick={() => navigate('/data/preprocess/error')}>
跳转数据预处理
</Button>
)}
</Flex>
}
destroyOnClose
width={800}
onCancel={() => setOpen(false)}>
<div style={{ minHeight: 300, padding: '40px 0' }}>
<Steps current={current} labelPlacement="vertical" items={steps} />
<Divider />
<Flex justify="space-between">探索结果:</Flex>
<Divider dashed />
<Radio.Group options={plainOptions} value={value} onChange={onChange} style={style} />
</div>
</Modal>
</>
)
}
import { useState } from 'react'
import { Button, Radio, Divider, Flex, Modal, Steps } from 'antd'
import type { RadioChangeEvent } from 'antd'
import { useNavigate } from 'react-router'
const plainOptions = ['会员情况', '客户满意度', '出生日期', '访问页面时长', '交易状态', '商品状态', '快递反馈']
export default function ButtonModal() {
const navigate = useNavigate()
const [open, setOpen] = useState(false)
const [current, setCurrent] = useState(0)
const [value, setValue] = useState(1)
const onChange = (e: RadioChangeEvent) => {
setValue(e.target.value)
}
const next = () => {
setCurrent(current + 1)
}
const prev = () => {
setCurrent(current - 1)
}
const steps = [
{
title: '探索过大值字段',
},
{
title: '处理过大值',
},
]
const style: React.CSSProperties = {
display: 'flex',
flexDirection: 'column',
gap: 8,
}
return (
<>
<Button type="primary" onClick={() => setOpen(true)}>
过大值
</Button>
<Modal
title="过大值探索"
open={open}
footer={
<Flex justify="center" gap={20}>
{current === 0 && <Button type="primary">智能探索过大值字段</Button>}
{current > 0 && (
<Button style={{ margin: '0 8px' }} onClick={() => prev()}>
上一步
</Button>
)}
{current < steps.length - 1 && (
<Button type="primary" onClick={() => next()}>
下一步
</Button>
)}
{current === steps.length - 1 && (
<Button type="primary" onClick={() => navigate('/data/preprocess/max')}>
跳转数据预处理
</Button>
)}
</Flex>
}
destroyOnClose
width={800}
onCancel={() => setOpen(false)}>
<div style={{ minHeight: 300, padding: '40px 0' }}>
<Steps current={current} labelPlacement="vertical" items={steps} />
<Divider />
<Flex justify="space-between">探索结果:</Flex>
<Divider dashed />
<Radio.Group options={plainOptions} value={value} onChange={onChange} style={style} />
</div>
</Modal>
</>
)
}
import { useState } from 'react'
import { Button, Radio, Divider, Flex, Modal, Steps } from 'antd'
import type { RadioChangeEvent } from 'antd'
import { useNavigate } from 'react-router'
const plainOptions = ['会员情况', '客户满意度', '出生日期', '访问页面时长', '交易状态', '商品状态', '快递反馈']
export default function ButtonModal() {
const navigate = useNavigate()
const [open, setOpen] = useState(false)
const [current, setCurrent] = useState(0)
const [value, setValue] = useState(1)
const onChange = (e: RadioChangeEvent) => {
setValue(e.target.value)
}
const next = () => {
setCurrent(current + 1)
}
const prev = () => {
setCurrent(current - 1)
}
const steps = [
{
title: '探索过小值字段',
},
{
title: '处理过小值',
},
]
const style: React.CSSProperties = {
display: 'flex',
flexDirection: 'column',
gap: 8,
}
return (
<>
<Button type="primary" onClick={() => setOpen(true)}>
过小值
</Button>
<Modal
title="过小值探索"
open={open}
footer={
<Flex justify="center" gap={20}>
{current === 0 && <Button type="primary">智能探索过小值字段</Button>}
{current > 0 && (
<Button style={{ margin: '0 8px' }} onClick={() => prev()}>
上一步
</Button>
)}
{current < steps.length - 1 && (
<Button type="primary" onClick={() => next()}>
下一步
</Button>
)}
{current === steps.length - 1 && (
<Button type="primary" onClick={() => navigate('/data/preprocess/min')}>
跳转数据预处理
</Button>
)}
</Flex>
}
destroyOnClose
width={800}
onCancel={() => setOpen(false)}>
<div style={{ minHeight: 300, padding: '40px 0' }}>
<Steps current={current} labelPlacement="vertical" items={steps} />
<Divider />
<Flex justify="space-between">探索结果:</Flex>
<Divider dashed />
<Radio.Group options={plainOptions} value={value} onChange={onChange} style={style} />
</div>
</Modal>
</>
)
}
import { useState } from 'react'
import { Button, Checkbox, Divider, Flex, Modal, Steps } from 'antd'
import type { CheckboxProps } from 'antd'
import { useNavigate } from 'react-router'
const CheckboxGroup = Checkbox.Group
const plainOptions = ['会员情况', '客户满意度', '出生日期', '访问页面时长', '交易状态', '商品状态', '快递反馈']
const defaultCheckedList = ['会员情况', '客户满意度']
export default function ButtonModal() {
const navigate = useNavigate()
const [open, setOpen] = useState(false)
const [current, setCurrent] = useState(0)
const [checkedList, setCheckedList] = useState<string[]>(defaultCheckedList)
const checkAll = plainOptions.length === checkedList.length
const indeterminate = checkedList.length > 0 && checkedList.length < plainOptions.length
const onChange = (list: string[]) => {
setCheckedList(list)
}
const onCheckAllChange: CheckboxProps['onChange'] = (e) => {
setCheckedList(e.target.checked ? plainOptions : [])
}
const next = () => {
setCurrent(current + 1)
}
const prev = () => {
setCurrent(current - 1)
}
const steps = [
{
title: '探索缺失值字段',
content: (
<>
<Flex justify="space-between">
探索结果:
<Checkbox indeterminate={indeterminate} onChange={onCheckAllChange} checked={checkAll}>
全选
</Checkbox>
</Flex>
<Divider dashed />
<CheckboxGroup options={plainOptions} value={checkedList} onChange={onChange} />
</>
),
},
{
title: '探索字段缺失值',
content: (
<>
<Flex justify="space-between">探索结果:</Flex>
<Divider dashed />
<p>字段1:该字段有缺失值的数据有:A000001、A000002...</p>
<p>字段1:该字段有缺失值的数据有:A000001、A000002...</p>
<p>字段1:该字段有缺失值的数据有:A000001、A000002...</p>
<p>字段1:该字段有缺失值的数据有:A000001、A000002...</p>
<p>字段1:该字段有缺失值的数据有:A000001、A000002...</p>
</>
),
},
{
title: '填充字段缺失值',
content: (
<>
<Flex justify="space-between">
请选择需要填充的字段:
<Checkbox indeterminate={indeterminate} onChange={onCheckAllChange} checked={checkAll}>
全选
</Checkbox>
</Flex>
<Divider dashed />
<CheckboxGroup options={plainOptions} value={checkedList} onChange={onChange} />
</>
),
},
]
return (
<>
<Button type="primary" onClick={() => setOpen(true)}>
缺失值
</Button>
<Modal
title="缺失值探索"
open={open}
footer={
<Flex justify="center" gap={20}>
{current === 0 && <Button type="primary">智能探索缺失值字段</Button>}
{current === 0 && (
<Button type="primary" disabled={!checkedList.length} onClick={() => next()}>
进一步探索字段缺失值情况
</Button>
)}
{current > 0 && (
<Button style={{ margin: '0 8px' }} onClick={() => prev()}>
上一步
</Button>
)}
{current > 0 && current < steps.length - 1 && (
<Button type="primary" onClick={() => next()}>
下一步
</Button>
)}
{current === steps.length - 1 && (
<Button type="primary" onClick={() => navigate('/data/preprocess/null')}>
跳转数据预处理
</Button>
)}
</Flex>
}
destroyOnClose
width={800}
onCancel={() => setOpen(false)}>
<div style={{ minHeight: 300, padding: '40px 0' }}>
<Steps current={current} labelPlacement="vertical" items={steps} />
<Divider />
<div>{steps[current].content}</div>
</div>
</Modal>
</>
)
}
import { useState, useMemo } from 'react'
import { Button, Flex, Modal, Table, Checkbox } from 'antd'
import { DownloadOutlined } from '@ant-design/icons'
export default function ButtonModal() {
const [open, setOpen] = useState(false)
const [title, setTitle] = useState('')
const handleOpen = (button: { name: string; key: string }) => {
setSelectedButtons([button.key])
setTitle(`探索` + button.name)
setOpen(true)
}
const buttons = useMemo(() => {
return [
{ name: '最大值', key: 'max' },
{ name: '最小值', key: 'min' },
{ name: '平均值', key: 'mean' },
{ name: '中位数', key: 'median' },
{ name: '众数', key: 'mode' },
{ name: '1/4位数', key: 'q1' },
{ name: '3/4位数', key: 'q3' },
{ name: '方差', key: 'variance' },
{ name: '标准差', key: 'stdDev' },
{ name: '极差', key: 'range' },
]
}, [])
const [selectedButtons, setSelectedButtons] = useState<string[]>(['max'])
const dataSource = [
{
key: '1',
name: '学段1',
max: 99,
min: '--',
mean: 50,
median: 50,
mode: 50,
q1: 25,
q3: 75,
variance: 100,
stdDev: 10,
range: 99,
},
{
key: '2',
name: '学段2',
max: 102586,
min: '--',
mean: 51293,
median: 51293,
mode: 51293,
q1: 25646,
q3: 76939,
variance: 1000000,
stdDev: 1000,
range: 102586,
},
{
key: '3',
name: '学段3',
max: 859,
min: '--',
mean: 430,
median: 430,
mode: 430,
q1: 215,
q3: 645,
variance: 10000,
stdDev: 100,
range: 859,
},
{
key: '4',
name: '学段4',
max: 1568,
min: '--',
mean: 784,
median: 784,
mode: 784,
q1: 392,
q3: 1176,
variance: 20000,
stdDev: 141,
range: 1568,
},
]
const columns = useMemo(() => {
const baseColumns = [
{
title: '序号',
dataIndex: 'key',
width: 62,
align: 'center' as const,
},
{
title: '字段名称',
dataIndex: 'name',
align: 'center' as const,
},
]
const selectedColumns = buttons
.filter((button) => selectedButtons.includes(button.key))
.map((button) => ({
title: button.name,
dataIndex: button.key,
align: 'center' as const,
}))
return [...baseColumns, ...selectedColumns]
}, [selectedButtons, buttons])
const handleButtonChange = (checkedValues: string[]) => {
setSelectedButtons(checkedValues)
}
return (
<>
{buttons.map((button) => (
<Button type="primary" key={button.key} onClick={() => handleOpen(button)}>
{button.name}
</Button>
))}
<Modal
title={title}
open={open}
footer={
<Flex justify="center" gap={20}>
<Button type="primary">一键计算</Button>
</Flex>
}
destroyOnClose
width={1000}
onCancel={() => setOpen(false)}>
<div style={{ minHeight: 300, padding: '20px 0' }}>
<Flex justify="space-between" align="center" style={{ marginBottom: '20px' }}>
<div>
请选择字段:
<Button type="text" icon={<DownloadOutlined />} size="small">
导出
</Button>
</div>
<Checkbox.Group value={selectedButtons} onChange={handleButtonChange}>
{buttons.map((button) => (
<Checkbox key={button.key} value={button.key}>
{button.name}
</Checkbox>
))}
</Checkbox.Group>
</Flex>
<Table bordered dataSource={dataSource} columns={columns} pagination={false} scroll={{ x: 'max-content' }} />
</div>
</Modal>
</>
)
}
import { useState } from 'react'
import { Button, Divider, Flex, Modal, Steps } from 'antd'
import { useNavigate } from 'react-router'
export default function ButtonModal() {
const navigate = useNavigate()
const [open, setOpen] = useState(false)
const [current, setCurrent] = useState(0)
const next = () => {
setCurrent(current + 1)
}
const prev = () => {
setCurrent(current - 1)
}
const steps = [
{
title: '探索重复值',
},
{
title: '处理重复值',
},
]
return (
<>
<Button type="primary" onClick={() => setOpen(true)}>
重复值
</Button>
<Modal
title="重复值探索"
open={open}
footer={
<Flex justify="center" gap={20}>
{current === 0 && <Button type="primary">智能探索重复值字段</Button>}
{current > 0 && (
<Button style={{ margin: '0 8px' }} onClick={() => prev()}>
上一步
</Button>
)}
{current < steps.length - 1 && (
<Button type="primary" onClick={() => next()}>
下一步
</Button>
)}
{current === steps.length - 1 && (
<Button type="primary" onClick={() => navigate('/data/preprocess/repeat')}>
跳转数据预处理
</Button>
)}
</Flex>
}
destroyOnClose
width={800}
onCancel={() => setOpen(false)}>
<div style={{ minHeight: 300, padding: '40px 0' }}>
<Steps current={current} labelPlacement="vertical" items={steps} />
<Divider />
<Flex justify="space-between">探索结果:</Flex>
<Divider dashed />
<p>1、第XX行、第XX行的数据完全一样</p>
<p>2、第XX行、第XX行、第XX行的数据完全一样</p>
</div>
</Modal>
</>
)
}
import { lazy } from 'react'
import DataWrap from '@/components/data/DataWrap' import DataWrap from '@/components/data/DataWrap'
import { Button } from 'antd'
const NullButtonModal = lazy(() => import('../components/NullButtonModal'))
const RepeatButtonModal = lazy(() => import('../components/RepeatButtonModal'))
const MaxButtonModal = lazy(() => import('../components/MaxButtonModal'))
const MinButtonModal = lazy(() => import('../components/MinButtonModal'))
const ErrorButtonModal = lazy(() => import('../components/ErrorButtonModal'))
const OtherButtonModal = lazy(() => import('../components/OtherButtonModal'))
export default function DataWriteUpload() { export default function DataWriteUpload() {
const buttonsRender = () => { return (
const buttons = [ <DataWrap
{ name: '缺失值' }, title="数据探索"
{ name: '重复值' }, buttons={
{ name: '过大值' }, <>
{ name: '过小值' }, <NullButtonModal />
{ name: '逻辑错误值' }, <RepeatButtonModal />
{ name: '最大值' }, <MaxButtonModal />
{ name: '最小值' }, <MinButtonModal />
{ name: '平均值' }, <ErrorButtonModal />
{ name: '中位数' }, <OtherButtonModal />
{ name: '众数' }, </>
{ name: '1/4位数' }, }></DataWrap>
{ name: '3/4位数' }, )
{ name: '方差' },
{ name: '标准差' },
{ name: '极差' },
]
return buttons.map((item) => {
return (
<Button type="primary" key={item.name}>
{item.name}
</Button>
)
})
}
return <DataWrap title="数据探索" buttons={<>{buttonsRender()}</>}></DataWrap>
} }
import DataWrap from '@/components/data/DataWrap' import DataWrap from '@/components/data/DataWrap'
import { Button } from 'antd' import { Button } from 'antd'
import { useAI } from '@/hooks/useAI'
import { useDataQuery } from '@/hooks/useQuery'
export default function DataWriteUpload() { export default function DataWriteUpload() {
const { post } = useAI()
const { data } = useDataQuery()
function handleClick(type: number) {
if (type == 1) {
post({
content: '请仔细阅读我给你的数据集里面的数据,然后帮助我详细解释一下数据集里面每一个字段的含义。',
extra: JSON.stringify(data.list),
})
} else {
post({
content: '请仔细阅读我给你的数据集里面的数据,然后帮助我梳理数据集里面字段与字段之间的业务逻辑关系。',
extra: JSON.stringify(data.list),
})
}
}
return ( return (
<DataWrap <DataWrap
title="数据理解" title="数据理解"
buttons={ buttons={
<> <>
<Button type="primary">一键理解数据字段</Button> <Button type="primary" onClick={() => handleClick(1)}>
<Button type="primary">一键梳理字段关系</Button> 一键理解数据字段
</Button>
<Button type="primary" onClick={() => handleClick(2)}>
一键梳理字段关系
</Button>
</> </>
}></DataWrap> }></DataWrap>
) )
......
...@@ -7,20 +7,23 @@ import DataRender from '@/components/data/DataRender' ...@@ -7,20 +7,23 @@ import DataRender from '@/components/data/DataRender'
import { useImportDataset } from '../query' import { useImportDataset } from '../query'
import { upload } from '@/utils/upload' import { upload } from '@/utils/upload'
import { useNavigate } from 'react-router' import { useNavigate } from 'react-router'
import { uniqueId } from 'lodash-es'
export default function DataWriteUpload() { export default function DataWriteUpload() {
const [file, setFile] = useState<File | null>(null) const [file, setFile] = useState<File | null>(null)
const [data, setData] = useState<any[]>([]) const [dataset, setDataset] = useState<any[]>([])
const columns: any = const columns: any =
data.length > 0 dataset.length > 0
? Object.keys(data[0]).map((key) => ({ ? Object.keys(dataset[0]).map((key) => ({
title: key, title: key,
dataIndex: key, dataIndex: key,
align: 'center', align: 'center',
})) }))
: [] : []
const dataSource = dataset.map((item) => ({ ...item, pk_id: uniqueId() }))
const props: UploadProps = { const props: UploadProps = {
showUploadList: false, showUploadList: false,
accept: '.xlsx,.csv', accept: '.xlsx,.csv',
...@@ -31,7 +34,7 @@ export default function DataWriteUpload() { ...@@ -31,7 +34,7 @@ export default function DataWriteUpload() {
const sheetName = workbook.SheetNames[0] const sheetName = workbook.SheetNames[0]
const worksheet = workbook.Sheets[sheetName] const worksheet = workbook.Sheets[sheetName]
const jsonData = utils.sheet_to_json(worksheet) const jsonData = utils.sheet_to_json(worksheet)
setData(jsonData) setDataset(jsonData)
return false return false
}, },
...@@ -69,12 +72,12 @@ export default function DataWriteUpload() { ...@@ -69,12 +72,12 @@ export default function DataWriteUpload() {
<Button type="primary" shape="circle" size="large" icon={<PlusOutlined />}></Button> <Button type="primary" shape="circle" size="large" icon={<PlusOutlined />}></Button>
<span style={{ marginLeft: '10px' }}>{file?.name}</span> <span style={{ marginLeft: '10px' }}>{file?.name}</span>
</Upload> </Upload>
<p>共计:{data.length}条数据</p> <p>共计:{dataSource.length}条数据</p>
<Button type="primary" onClick={handleSave}> <Button type="primary" onClick={handleSave}>
保存 保存
</Button> </Button>
</Flex> </Flex>
<DataRender dataSource={data} columns={columns}></DataRender> <DataRender rowKey={'pk_id'} dataSource={dataSource} columns={columns}></DataRender>
</div> </div>
) : ( ) : (
<Upload.Dragger {...props}> <Upload.Dragger {...props}>
......
import { create } from 'zustand'
import axios from 'axios'
export interface Message {
id?: string
role: 'user' | 'assistant'
content: string
}
interface State {
ai: string
setAI: (ai: string) => void
messages: Message[]
isLoading: boolean
post: (data: { content: string }) => Promise<void>
}
// Zustand 状态管理
export const useAIStore = create<State>((set, get) => ({
ai: localStorage.getItem('ai') || 'yiyan',
setAI: (ai) => {
localStorage.setItem('ai', ai)
set({ ai })
},
messages: [],
isLoading: false,
post: async (data) => {
const { ai, messages } = get()
set({ isLoading: true, messages: [...messages, { role: 'user', content: data.content }] })
try {
let response = ''
switch (ai) {
case 'yiyan':
response = await yiyan(data)
break
case 'deepseek':
response = await deepseek(data)
break
case 'qwen':
response = await qwen(data)
break
case 'tiangong':
response = await tiangong(data)
break
default:
throw new Error('未找到对应的 AI 配置')
}
set((state) => ({
messages: [...state.messages, { role: 'assistant', content: response }],
isLoading: false,
}))
} catch (err) {
console.error('AI 请求失败:', err)
set({ isLoading: false })
}
},
}))
// AI API 调用函数
async function yiyan(data: any) {
const resp = await axios.post('/api/qianfan/chat', { messages: [{ role: 'user', content: data.content }] })
return resp.data.result
}
async function deepseek(data: any) {
const resp = await axios.post('/api/deepseek/chat/completions', {
model: 'deepseek-chat',
messages: [{ role: 'user', content: data.content }],
})
return resp.data.choices[0]?.message?.content || ''
}
async function qwen(data: any) {
const resp = await axios.post('/api/qwen/chat/completions', {
model: 'qwen-max',
messages: [{ role: 'user', content: data.content }],
})
return resp.data.choices[0]?.message?.content || ''
}
async function tiangong(data: any) {
const resp = await axios.post('/api/tiangong/chat', {
chat_history: [{ role: 'user', content: data.content }],
})
return resp.data.result
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论