正在显示
15 个修改的文件
包含
952 行增加
和
10 行删除
| 1 | -<!DOCTYPE html> | 1 | +<!doctype html> |
| 2 | <html lang=""> | 2 | <html lang=""> |
| 3 | <head> | 3 | <head> |
| 4 | - <meta charset="UTF-8"> | ||
| 5 | - <link rel="icon" href="/favicon.ico"> | 4 | + <meta charset="UTF-8" /> |
| 5 | + <link rel="icon" href="/favicon.ico" /> | ||
| 6 | <script src="https://cdn.tailwindcss.com"></script> | 6 | <script src="https://cdn.tailwindcss.com"></script> |
| 7 | - <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet"> | ||
| 8 | - <meta name="viewport" content="width=device-width, initial-scale=1.0"> | 7 | + <link |
| 8 | + href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" | ||
| 9 | + rel="stylesheet" | ||
| 10 | + /> | ||
| 11 | + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
| 9 | <title>Vite App</title> | 12 | <title>Vite App</title> |
| 10 | </head> | 13 | </head> |
| 11 | <body> | 14 | <body> |
| 12 | <div id="app"></div> | 15 | <div id="app"></div> |
| 13 | <script type="module" src="/src/main.js"></script> | 16 | <script type="module" src="/src/main.js"></script> |
| 17 | + <script type="text/javascript" src="/config.js"></script> | ||
| 14 | </body> | 18 | </body> |
| 15 | </html> | 19 | </html> |
| @@ -8,6 +8,7 @@ | @@ -8,6 +8,7 @@ | ||
| 8 | "name": "aigeo", | 8 | "name": "aigeo", |
| 9 | "version": "0.0.0", | 9 | "version": "0.0.0", |
| 10 | "dependencies": { | 10 | "dependencies": { |
| 11 | + "axios": "^1.11.0", | ||
| 11 | "chart.js": "^4.5.0", | 12 | "chart.js": "^4.5.0", |
| 12 | "pinia": "^3.0.3", | 13 | "pinia": "^3.0.3", |
| 13 | "sass": "^1.90.0", | 14 | "sass": "^1.90.0", |
| @@ -2009,6 +2010,12 @@ | @@ -2009,6 +2010,12 @@ | ||
| 2009 | "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", | 2010 | "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", |
| 2010 | "license": "MIT" | 2011 | "license": "MIT" |
| 2011 | }, | 2012 | }, |
| 2013 | + "node_modules/asynckit": { | ||
| 2014 | + "version": "0.4.0", | ||
| 2015 | + "resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz", | ||
| 2016 | + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", | ||
| 2017 | + "license": "MIT" | ||
| 2018 | + }, | ||
| 2012 | "node_modules/autoprefixer": { | 2019 | "node_modules/autoprefixer": { |
| 2013 | "version": "10.4.21", | 2020 | "version": "10.4.21", |
| 2014 | "resolved": "https://registry.npmmirror.com/autoprefixer/-/autoprefixer-10.4.21.tgz", | 2021 | "resolved": "https://registry.npmmirror.com/autoprefixer/-/autoprefixer-10.4.21.tgz", |
| @@ -2047,6 +2054,17 @@ | @@ -2047,6 +2054,17 @@ | ||
| 2047 | "postcss": "^8.1.0" | 2054 | "postcss": "^8.1.0" |
| 2048 | } | 2055 | } |
| 2049 | }, | 2056 | }, |
| 2057 | + "node_modules/axios": { | ||
| 2058 | + "version": "1.11.0", | ||
| 2059 | + "resolved": "https://registry.npmmirror.com/axios/-/axios-1.11.0.tgz", | ||
| 2060 | + "integrity": "sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==", | ||
| 2061 | + "license": "MIT", | ||
| 2062 | + "dependencies": { | ||
| 2063 | + "follow-redirects": "^1.15.6", | ||
| 2064 | + "form-data": "^4.0.4", | ||
| 2065 | + "proxy-from-env": "^1.1.0" | ||
| 2066 | + } | ||
| 2067 | + }, | ||
| 2050 | "node_modules/balanced-match": { | 2068 | "node_modules/balanced-match": { |
| 2051 | "version": "1.0.2", | 2069 | "version": "1.0.2", |
| 2052 | "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz", | 2070 | "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz", |
| @@ -2144,6 +2162,19 @@ | @@ -2144,6 +2162,19 @@ | ||
| 2144 | "url": "https://github.com/sponsors/sindresorhus" | 2162 | "url": "https://github.com/sponsors/sindresorhus" |
| 2145 | } | 2163 | } |
| 2146 | }, | 2164 | }, |
| 2165 | + "node_modules/call-bind-apply-helpers": { | ||
| 2166 | + "version": "1.0.2", | ||
| 2167 | + "resolved": "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", | ||
| 2168 | + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", | ||
| 2169 | + "license": "MIT", | ||
| 2170 | + "dependencies": { | ||
| 2171 | + "es-errors": "^1.3.0", | ||
| 2172 | + "function-bind": "^1.1.2" | ||
| 2173 | + }, | ||
| 2174 | + "engines": { | ||
| 2175 | + "node": ">= 0.4" | ||
| 2176 | + } | ||
| 2177 | + }, | ||
| 2147 | "node_modules/camelcase-css": { | 2178 | "node_modules/camelcase-css": { |
| 2148 | "version": "2.0.1", | 2179 | "version": "2.0.1", |
| 2149 | "resolved": "https://registry.npmmirror.com/camelcase-css/-/camelcase-css-2.0.1.tgz", | 2180 | "resolved": "https://registry.npmmirror.com/camelcase-css/-/camelcase-css-2.0.1.tgz", |
| @@ -2240,6 +2271,18 @@ | @@ -2240,6 +2271,18 @@ | ||
| 2240 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", | 2271 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", |
| 2241 | "license": "MIT" | 2272 | "license": "MIT" |
| 2242 | }, | 2273 | }, |
| 2274 | + "node_modules/combined-stream": { | ||
| 2275 | + "version": "1.0.8", | ||
| 2276 | + "resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz", | ||
| 2277 | + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", | ||
| 2278 | + "license": "MIT", | ||
| 2279 | + "dependencies": { | ||
| 2280 | + "delayed-stream": "~1.0.0" | ||
| 2281 | + }, | ||
| 2282 | + "engines": { | ||
| 2283 | + "node": ">= 0.8" | ||
| 2284 | + } | ||
| 2285 | + }, | ||
| 2243 | "node_modules/commander": { | 2286 | "node_modules/commander": { |
| 2244 | "version": "4.1.1", | 2287 | "version": "4.1.1", |
| 2245 | "resolved": "https://registry.npmmirror.com/commander/-/commander-4.1.1.tgz", | 2288 | "resolved": "https://registry.npmmirror.com/commander/-/commander-4.1.1.tgz", |
| @@ -2364,6 +2407,15 @@ | @@ -2364,6 +2407,15 @@ | ||
| 2364 | "url": "https://github.com/sponsors/sindresorhus" | 2407 | "url": "https://github.com/sponsors/sindresorhus" |
| 2365 | } | 2408 | } |
| 2366 | }, | 2409 | }, |
| 2410 | + "node_modules/delayed-stream": { | ||
| 2411 | + "version": "1.0.0", | ||
| 2412 | + "resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz", | ||
| 2413 | + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", | ||
| 2414 | + "license": "MIT", | ||
| 2415 | + "engines": { | ||
| 2416 | + "node": ">=0.4.0" | ||
| 2417 | + } | ||
| 2418 | + }, | ||
| 2367 | "node_modules/detect-libc": { | 2419 | "node_modules/detect-libc": { |
| 2368 | "version": "1.0.3", | 2420 | "version": "1.0.3", |
| 2369 | "resolved": "https://registry.npmmirror.com/detect-libc/-/detect-libc-1.0.3.tgz", | 2421 | "resolved": "https://registry.npmmirror.com/detect-libc/-/detect-libc-1.0.3.tgz", |
| @@ -2389,6 +2441,20 @@ | @@ -2389,6 +2441,20 @@ | ||
| 2389 | "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", | 2441 | "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", |
| 2390 | "license": "MIT" | 2442 | "license": "MIT" |
| 2391 | }, | 2443 | }, |
| 2444 | + "node_modules/dunder-proto": { | ||
| 2445 | + "version": "1.0.1", | ||
| 2446 | + "resolved": "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz", | ||
| 2447 | + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", | ||
| 2448 | + "license": "MIT", | ||
| 2449 | + "dependencies": { | ||
| 2450 | + "call-bind-apply-helpers": "^1.0.1", | ||
| 2451 | + "es-errors": "^1.3.0", | ||
| 2452 | + "gopd": "^1.2.0" | ||
| 2453 | + }, | ||
| 2454 | + "engines": { | ||
| 2455 | + "node": ">= 0.4" | ||
| 2456 | + } | ||
| 2457 | + }, | ||
| 2392 | "node_modules/eastasianwidth": { | 2458 | "node_modules/eastasianwidth": { |
| 2393 | "version": "0.2.0", | 2459 | "version": "0.2.0", |
| 2394 | "resolved": "https://registry.npmmirror.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz", | 2460 | "resolved": "https://registry.npmmirror.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz", |
| @@ -2430,6 +2496,51 @@ | @@ -2430,6 +2496,51 @@ | ||
| 2430 | "url": "https://github.com/sponsors/antfu" | 2496 | "url": "https://github.com/sponsors/antfu" |
| 2431 | } | 2497 | } |
| 2432 | }, | 2498 | }, |
| 2499 | + "node_modules/es-define-property": { | ||
| 2500 | + "version": "1.0.1", | ||
| 2501 | + "resolved": "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz", | ||
| 2502 | + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", | ||
| 2503 | + "license": "MIT", | ||
| 2504 | + "engines": { | ||
| 2505 | + "node": ">= 0.4" | ||
| 2506 | + } | ||
| 2507 | + }, | ||
| 2508 | + "node_modules/es-errors": { | ||
| 2509 | + "version": "1.3.0", | ||
| 2510 | + "resolved": "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz", | ||
| 2511 | + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", | ||
| 2512 | + "license": "MIT", | ||
| 2513 | + "engines": { | ||
| 2514 | + "node": ">= 0.4" | ||
| 2515 | + } | ||
| 2516 | + }, | ||
| 2517 | + "node_modules/es-object-atoms": { | ||
| 2518 | + "version": "1.1.1", | ||
| 2519 | + "resolved": "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz", | ||
| 2520 | + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", | ||
| 2521 | + "license": "MIT", | ||
| 2522 | + "dependencies": { | ||
| 2523 | + "es-errors": "^1.3.0" | ||
| 2524 | + }, | ||
| 2525 | + "engines": { | ||
| 2526 | + "node": ">= 0.4" | ||
| 2527 | + } | ||
| 2528 | + }, | ||
| 2529 | + "node_modules/es-set-tostringtag": { | ||
| 2530 | + "version": "2.1.0", | ||
| 2531 | + "resolved": "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", | ||
| 2532 | + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", | ||
| 2533 | + "license": "MIT", | ||
| 2534 | + "dependencies": { | ||
| 2535 | + "es-errors": "^1.3.0", | ||
| 2536 | + "get-intrinsic": "^1.2.6", | ||
| 2537 | + "has-tostringtag": "^1.0.2", | ||
| 2538 | + "hasown": "^2.0.2" | ||
| 2539 | + }, | ||
| 2540 | + "engines": { | ||
| 2541 | + "node": ">= 0.4" | ||
| 2542 | + } | ||
| 2543 | + }, | ||
| 2433 | "node_modules/esbuild": { | 2544 | "node_modules/esbuild": { |
| 2434 | "version": "0.25.8", | 2545 | "version": "0.25.8", |
| 2435 | "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.25.8.tgz", | 2546 | "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.25.8.tgz", |
| @@ -2595,6 +2706,26 @@ | @@ -2595,6 +2706,26 @@ | ||
| 2595 | "node": ">=8" | 2706 | "node": ">=8" |
| 2596 | } | 2707 | } |
| 2597 | }, | 2708 | }, |
| 2709 | + "node_modules/follow-redirects": { | ||
| 2710 | + "version": "1.15.11", | ||
| 2711 | + "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.11.tgz", | ||
| 2712 | + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", | ||
| 2713 | + "funding": [ | ||
| 2714 | + { | ||
| 2715 | + "type": "individual", | ||
| 2716 | + "url": "https://github.com/sponsors/RubenVerborgh" | ||
| 2717 | + } | ||
| 2718 | + ], | ||
| 2719 | + "license": "MIT", | ||
| 2720 | + "engines": { | ||
| 2721 | + "node": ">=4.0" | ||
| 2722 | + }, | ||
| 2723 | + "peerDependenciesMeta": { | ||
| 2724 | + "debug": { | ||
| 2725 | + "optional": true | ||
| 2726 | + } | ||
| 2727 | + } | ||
| 2728 | + }, | ||
| 2598 | "node_modules/foreground-child": { | 2729 | "node_modules/foreground-child": { |
| 2599 | "version": "3.3.1", | 2730 | "version": "3.3.1", |
| 2600 | "resolved": "https://registry.npmmirror.com/foreground-child/-/foreground-child-3.3.1.tgz", | 2731 | "resolved": "https://registry.npmmirror.com/foreground-child/-/foreground-child-3.3.1.tgz", |
| @@ -2611,6 +2742,22 @@ | @@ -2611,6 +2742,22 @@ | ||
| 2611 | "url": "https://github.com/sponsors/isaacs" | 2742 | "url": "https://github.com/sponsors/isaacs" |
| 2612 | } | 2743 | } |
| 2613 | }, | 2744 | }, |
| 2745 | + "node_modules/form-data": { | ||
| 2746 | + "version": "4.0.4", | ||
| 2747 | + "resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.4.tgz", | ||
| 2748 | + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", | ||
| 2749 | + "license": "MIT", | ||
| 2750 | + "dependencies": { | ||
| 2751 | + "asynckit": "^0.4.0", | ||
| 2752 | + "combined-stream": "^1.0.8", | ||
| 2753 | + "es-set-tostringtag": "^2.1.0", | ||
| 2754 | + "hasown": "^2.0.2", | ||
| 2755 | + "mime-types": "^2.1.12" | ||
| 2756 | + }, | ||
| 2757 | + "engines": { | ||
| 2758 | + "node": ">= 6" | ||
| 2759 | + } | ||
| 2760 | + }, | ||
| 2614 | "node_modules/fraction.js": { | 2761 | "node_modules/fraction.js": { |
| 2615 | "version": "4.3.7", | 2762 | "version": "4.3.7", |
| 2616 | "resolved": "https://registry.npmmirror.com/fraction.js/-/fraction.js-4.3.7.tgz", | 2763 | "resolved": "https://registry.npmmirror.com/fraction.js/-/fraction.js-4.3.7.tgz", |
| @@ -2658,6 +2805,43 @@ | @@ -2658,6 +2805,43 @@ | ||
| 2658 | "node": ">=6.9.0" | 2805 | "node": ">=6.9.0" |
| 2659 | } | 2806 | } |
| 2660 | }, | 2807 | }, |
| 2808 | + "node_modules/get-intrinsic": { | ||
| 2809 | + "version": "1.3.0", | ||
| 2810 | + "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz", | ||
| 2811 | + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", | ||
| 2812 | + "license": "MIT", | ||
| 2813 | + "dependencies": { | ||
| 2814 | + "call-bind-apply-helpers": "^1.0.2", | ||
| 2815 | + "es-define-property": "^1.0.1", | ||
| 2816 | + "es-errors": "^1.3.0", | ||
| 2817 | + "es-object-atoms": "^1.1.1", | ||
| 2818 | + "function-bind": "^1.1.2", | ||
| 2819 | + "get-proto": "^1.0.1", | ||
| 2820 | + "gopd": "^1.2.0", | ||
| 2821 | + "has-symbols": "^1.1.0", | ||
| 2822 | + "hasown": "^2.0.2", | ||
| 2823 | + "math-intrinsics": "^1.1.0" | ||
| 2824 | + }, | ||
| 2825 | + "engines": { | ||
| 2826 | + "node": ">= 0.4" | ||
| 2827 | + }, | ||
| 2828 | + "funding": { | ||
| 2829 | + "url": "https://github.com/sponsors/ljharb" | ||
| 2830 | + } | ||
| 2831 | + }, | ||
| 2832 | + "node_modules/get-proto": { | ||
| 2833 | + "version": "1.0.1", | ||
| 2834 | + "resolved": "https://registry.npmmirror.com/get-proto/-/get-proto-1.0.1.tgz", | ||
| 2835 | + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", | ||
| 2836 | + "license": "MIT", | ||
| 2837 | + "dependencies": { | ||
| 2838 | + "dunder-proto": "^1.0.1", | ||
| 2839 | + "es-object-atoms": "^1.0.0" | ||
| 2840 | + }, | ||
| 2841 | + "engines": { | ||
| 2842 | + "node": ">= 0.4" | ||
| 2843 | + } | ||
| 2844 | + }, | ||
| 2661 | "node_modules/get-stream": { | 2845 | "node_modules/get-stream": { |
| 2662 | "version": "9.0.1", | 2846 | "version": "9.0.1", |
| 2663 | "resolved": "https://registry.npmmirror.com/get-stream/-/get-stream-9.0.1.tgz", | 2847 | "resolved": "https://registry.npmmirror.com/get-stream/-/get-stream-9.0.1.tgz", |
| @@ -2707,6 +2891,45 @@ | @@ -2707,6 +2891,45 @@ | ||
| 2707 | "node": ">=10.13.0" | 2891 | "node": ">=10.13.0" |
| 2708 | } | 2892 | } |
| 2709 | }, | 2893 | }, |
| 2894 | + "node_modules/gopd": { | ||
| 2895 | + "version": "1.2.0", | ||
| 2896 | + "resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz", | ||
| 2897 | + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", | ||
| 2898 | + "license": "MIT", | ||
| 2899 | + "engines": { | ||
| 2900 | + "node": ">= 0.4" | ||
| 2901 | + }, | ||
| 2902 | + "funding": { | ||
| 2903 | + "url": "https://github.com/sponsors/ljharb" | ||
| 2904 | + } | ||
| 2905 | + }, | ||
| 2906 | + "node_modules/has-symbols": { | ||
| 2907 | + "version": "1.1.0", | ||
| 2908 | + "resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz", | ||
| 2909 | + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", | ||
| 2910 | + "license": "MIT", | ||
| 2911 | + "engines": { | ||
| 2912 | + "node": ">= 0.4" | ||
| 2913 | + }, | ||
| 2914 | + "funding": { | ||
| 2915 | + "url": "https://github.com/sponsors/ljharb" | ||
| 2916 | + } | ||
| 2917 | + }, | ||
| 2918 | + "node_modules/has-tostringtag": { | ||
| 2919 | + "version": "1.0.2", | ||
| 2920 | + "resolved": "https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz", | ||
| 2921 | + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", | ||
| 2922 | + "license": "MIT", | ||
| 2923 | + "dependencies": { | ||
| 2924 | + "has-symbols": "^1.0.3" | ||
| 2925 | + }, | ||
| 2926 | + "engines": { | ||
| 2927 | + "node": ">= 0.4" | ||
| 2928 | + }, | ||
| 2929 | + "funding": { | ||
| 2930 | + "url": "https://github.com/sponsors/ljharb" | ||
| 2931 | + } | ||
| 2932 | + }, | ||
| 2710 | "node_modules/hasown": { | 2933 | "node_modules/hasown": { |
| 2711 | "version": "2.0.2", | 2934 | "version": "2.0.2", |
| 2712 | "resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.2.tgz", | 2935 | "resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.2.tgz", |
| @@ -3016,6 +3239,15 @@ | @@ -3016,6 +3239,15 @@ | ||
| 3016 | "@jridgewell/sourcemap-codec": "^1.5.0" | 3239 | "@jridgewell/sourcemap-codec": "^1.5.0" |
| 3017 | } | 3240 | } |
| 3018 | }, | 3241 | }, |
| 3242 | + "node_modules/math-intrinsics": { | ||
| 3243 | + "version": "1.1.0", | ||
| 3244 | + "resolved": "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz", | ||
| 3245 | + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", | ||
| 3246 | + "license": "MIT", | ||
| 3247 | + "engines": { | ||
| 3248 | + "node": ">= 0.4" | ||
| 3249 | + } | ||
| 3250 | + }, | ||
| 3019 | "node_modules/merge2": { | 3251 | "node_modules/merge2": { |
| 3020 | "version": "1.4.1", | 3252 | "version": "1.4.1", |
| 3021 | "resolved": "https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz", | 3253 | "resolved": "https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz", |
| @@ -3050,6 +3282,27 @@ | @@ -3050,6 +3282,27 @@ | ||
| 3050 | "url": "https://github.com/sponsors/jonschlinkert" | 3282 | "url": "https://github.com/sponsors/jonschlinkert" |
| 3051 | } | 3283 | } |
| 3052 | }, | 3284 | }, |
| 3285 | + "node_modules/mime-db": { | ||
| 3286 | + "version": "1.52.0", | ||
| 3287 | + "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz", | ||
| 3288 | + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", | ||
| 3289 | + "license": "MIT", | ||
| 3290 | + "engines": { | ||
| 3291 | + "node": ">= 0.6" | ||
| 3292 | + } | ||
| 3293 | + }, | ||
| 3294 | + "node_modules/mime-types": { | ||
| 3295 | + "version": "2.1.35", | ||
| 3296 | + "resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz", | ||
| 3297 | + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", | ||
| 3298 | + "license": "MIT", | ||
| 3299 | + "dependencies": { | ||
| 3300 | + "mime-db": "1.52.0" | ||
| 3301 | + }, | ||
| 3302 | + "engines": { | ||
| 3303 | + "node": ">= 0.6" | ||
| 3304 | + } | ||
| 3305 | + }, | ||
| 3053 | "node_modules/minimatch": { | 3306 | "node_modules/minimatch": { |
| 3054 | "version": "9.0.5", | 3307 | "version": "9.0.5", |
| 3055 | "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.5.tgz", | 3308 | "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.5.tgz", |
| @@ -3623,6 +3876,12 @@ | @@ -3623,6 +3876,12 @@ | ||
| 3623 | "url": "https://github.com/sponsors/sindresorhus" | 3876 | "url": "https://github.com/sponsors/sindresorhus" |
| 3624 | } | 3877 | } |
| 3625 | }, | 3878 | }, |
| 3879 | + "node_modules/proxy-from-env": { | ||
| 3880 | + "version": "1.1.0", | ||
| 3881 | + "resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz", | ||
| 3882 | + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", | ||
| 3883 | + "license": "MIT" | ||
| 3884 | + }, | ||
| 3626 | "node_modules/queue-microtask": { | 3885 | "node_modules/queue-microtask": { |
| 3627 | "version": "1.2.3", | 3886 | "version": "1.2.3", |
| 3628 | "resolved": "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz", | 3887 | "resolved": "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz", |
| @@ -13,6 +13,7 @@ | @@ -13,6 +13,7 @@ | ||
| 13 | "format": "prettier --write src/" | 13 | "format": "prettier --write src/" |
| 14 | }, | 14 | }, |
| 15 | "dependencies": { | 15 | "dependencies": { |
| 16 | + "axios": "^1.11.0", | ||
| 16 | "chart.js": "^4.5.0", | 17 | "chart.js": "^4.5.0", |
| 17 | "pinia": "^3.0.3", | 18 | "pinia": "^3.0.3", |
| 18 | "sass": "^1.90.0", | 19 | "sass": "^1.90.0", |
public/config.js
0 → 100644
| 1 | +window.PLATFROM_CONFIG = { | ||
| 2 | + DEV_BASE_URL: 'http://erpapitest.yiwaixiao.net:80', // 开发环境 | ||
| 3 | + PRO_BASE_URL: 'http://erpapi.yiwaixiao.net', // 正式环境 | ||
| 4 | +} | ||
| 5 | + | ||
| 6 | + | ||
| 7 | +document.cookie = 'token=eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIwNzU1ODg4NDM3MDUiLCJzdWIiOiJ5aXdhaXhpYW8ubmV0IiwidXNlcl9pZCI6Mzc4LCJsb2dpbmlkIjoiaW5mbyIsImRvbWFpbiI6IjIxZ21haWwuY29tIiwiY29tcGFueV9pZCI6NywicGFyYW1fbGV2ZWwiOjAsImxvZ3BhdGgiOiJlOlxcbG9nc1xcMjFnbWFpbC5jb21cXGluZm9cXGVycm9yXFwiLCJpYXQiOjE3NTU0ODg1MjIsImV4cCI6MTc1NTQ5NTcyMn0.B7FNn8Zk-t2SvGUwHRUURLn_2QsJNX2lJX-w8pGJhRw'; |
src/api/aiapi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | + | ||
| 3 | +export const uploadFile = (data) => { | ||
| 4 | + return request({ | ||
| 5 | + url: '/ai/upload', | ||
| 6 | + method: 'post', | ||
| 7 | + data | ||
| 8 | + }) | ||
| 9 | +} | ||
| 10 | + | ||
| 11 | +export const saveHtml = (data) => { | ||
| 12 | + return request({ | ||
| 13 | + url: '/ai/saveHtml', | ||
| 14 | + method: 'post', | ||
| 15 | + data | ||
| 16 | + }) | ||
| 17 | +} | ||
| 18 | + | ||
| 19 | +export const saveDocx = (data) => { | ||
| 20 | + return request({ | ||
| 21 | + url: '/ai/generateFile', | ||
| 22 | + method: 'post', | ||
| 23 | + data | ||
| 24 | + }) | ||
| 25 | +} | ||
| 26 | + | ||
| 27 | +export const uploadFileToDataset = (data) => { | ||
| 28 | + return request({ | ||
| 29 | + url: '/ai/uploadFileToDataset', | ||
| 30 | + method: 'post', | ||
| 31 | + data | ||
| 32 | + }) | ||
| 33 | +} | ||
| 34 | + | ||
| 35 | + | ||
| 36 | +//<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>登录页面</title> <style> body { font-family: Arial, sans-serif; background-color: #f4f4f4; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; } .login-container { background: white; padding: 20px; border-radius: 5px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); } h2 { margin-bottom: 20px; } input[type="text"], input[type="password"] { width: 100%; padding: 10px; margin: 10px 0; border: 1px solid #ccc; border-radius: 3px; } input[type="submit"] { background-color: #4CAF50; color: white; border: none; padding: 10px; cursor: pointer; border-radius: 3px; width: 100%; } input[type="submit"]:hover { background-color: #45a049; } </style> </head> <body> <div class="login-container"> <h2>用户登录</h2> <form action="/login" method="POST"> <label for="username">用户名:</label> <input type="text" id="username" name="username" required> <label for="password">密码:</label> <input type="password" id="password" name="password" required> <input type="submit" value="登录"> </form> </div> </body> </html> |
src/assets/robot.png
0 → 100644
1.7 KB
src/assets/user-icon.png
0 → 100644
1.2 KB
| @@ -86,4 +86,18 @@ | @@ -86,4 +86,18 @@ | ||
| 86 | <script setup> | 86 | <script setup> |
| 87 | 87 | ||
| 88 | </script> | 88 | </script> |
| 89 | -<style scoped></style> | 89 | +<style scoped> |
| 90 | +@import 'tailwindcss/base'; | ||
| 91 | +@import 'tailwindcss/components'; | ||
| 92 | +@import 'tailwindcss/utilities'; | ||
| 93 | + | ||
| 94 | +@layer utilities { | ||
| 95 | + .content-auto { | ||
| 96 | + content-visibility: auto; | ||
| 97 | + } | ||
| 98 | + | ||
| 99 | + .sidebar-item-active { | ||
| 100 | + @apply bg-primary/10 text-primary border-l-4 border-primary; | ||
| 101 | + } | ||
| 102 | +} | ||
| 103 | +</style> |
| @@ -13,6 +13,11 @@ const router = createRouter({ | @@ -13,6 +13,11 @@ const router = createRouter({ | ||
| 13 | name: 'about', | 13 | name: 'about', |
| 14 | component: () => import('../views/test.vue'), | 14 | component: () => import('../views/test.vue'), |
| 15 | }, | 15 | }, |
| 16 | + { | ||
| 17 | + path: '/test1', | ||
| 18 | + name: 'test1', | ||
| 19 | + component: () => import('../views/test1.vue'), | ||
| 20 | + }, | ||
| 16 | ], | 21 | ], |
| 17 | }) | 22 | }) |
| 18 | 23 |
src/utils/config.js
0 → 100644
| 1 | +export const MAX_SIZE = 1024 * 1024 * 5; | ||
| 2 | +export const INVALID_TYPES = ['image/jpeg', 'image/png', 'image/gif', 'image/webp']; | ||
| 3 | + | ||
| 4 | +export const getCookie = (name) => { | ||
| 5 | + const cookieArr = document.cookie.split('; '); | ||
| 6 | + for (let item of cookieArr) { | ||
| 7 | + const [key, value] = item.split('='); | ||
| 8 | + if (key === name) { | ||
| 9 | + return decodeURIComponent(value); | ||
| 10 | + } | ||
| 11 | + } | ||
| 12 | + return null; | ||
| 13 | +} |
src/utils/request.js
0 → 100644
| 1 | +import axios from 'axios' | ||
| 2 | + | ||
| 3 | +// 根据环境获取基础URL | ||
| 4 | +// 从全局window对象获取配置 | ||
| 5 | +const config = window.PLATFROM_CONFIG || {} | ||
| 6 | +// 添加调试信息 | ||
| 7 | +const BASE_URL = import.meta.env.DEV ? config.DEV_BASE_URL : config.PRO_BASE_URL; | ||
| 8 | +// const API_BASE_URL="http://webdemo.yiwaixiao.net/" | ||
| 9 | +// 创建axios实例 | ||
| 10 | +const request = axios.create({ | ||
| 11 | + baseURL: BASE_URL, | ||
| 12 | + timeout: 60000, | ||
| 13 | + headers: { | ||
| 14 | + 'Content-Type': 'application/x-www-form-urlencoded', | ||
| 15 | + 'token': 'eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIwNzU1ODg4NDM3MDUiLCJzdWIiOiJ5aXdhaXhpYW8ubmV0IiwidXNlcl9pZCI6Mzc4LCJsb2dpbmlkIjoiaW5mbyIsImRvbWFpbiI6IjIxZ21haWwuY29tIiwiY29tcGFueV9pZCI6NywicGFyYW1fbGV2ZWwiOjAsImxvZ3BhdGgiOiJkOlxcbG9nc1xcMjFnbWFpbC5jb20iLCJpYXQiOjE3NTUwNTQ5NTksImV4cCI6MTc1Njc4Mjk1OX0.WfXb6Ol7ka8n3MHgnndor2la6VzmtBHpjZngsNjwHn0' | ||
| 16 | + } | ||
| 17 | +}) | ||
| 18 | + | ||
| 19 | +// 请求拦截器 | ||
| 20 | +request.interceptors.request.use( | ||
| 21 | + config => { | ||
| 22 | + console.log("config:", config) | ||
| 23 | + console.log(BASE_URL) | ||
| 24 | + return config | ||
| 25 | + }, | ||
| 26 | + error => { | ||
| 27 | + return Promise.reject(error) | ||
| 28 | + } | ||
| 29 | +) | ||
| 30 | + | ||
| 31 | +// 响应拦截器 | ||
| 32 | +request.interceptors.response.use( | ||
| 33 | + response => { | ||
| 34 | + return response.data | ||
| 35 | + }, | ||
| 36 | + error => { | ||
| 37 | + // if (error.response?.status == '800') { | ||
| 38 | + // // token过期处理 | ||
| 39 | + // const userStore = useUserStore() | ||
| 40 | + // userStore.clearToken() | ||
| 41 | + // window.location.href = '/login' | ||
| 42 | + // } | ||
| 43 | + return Promise.reject(error) | ||
| 44 | + } | ||
| 45 | +) | ||
| 46 | + | ||
| 47 | +export default request |
| @@ -541,6 +541,7 @@ | @@ -541,6 +541,7 @@ | ||
| 541 | import siderbar from '@/components/siderbar.vue'; | 541 | import siderbar from '@/components/siderbar.vue'; |
| 542 | import { ref, onMounted } from 'vue'; | 542 | import { ref, onMounted } from 'vue'; |
| 543 | import { Chart, registerables } from 'chart.js'; | 543 | import { Chart, registerables } from 'chart.js'; |
| 544 | +import { getCookie } from '@/utils/config'; | ||
| 544 | Chart.register(...registerables); | 545 | Chart.register(...registerables); |
| 545 | 546 | ||
| 546 | // 状态管理 | 547 | // 状态管理 |
| @@ -963,6 +964,8 @@ onMounted(() => { | @@ -963,6 +964,8 @@ onMounted(() => { | ||
| 963 | userDropdownOpen.value = false; | 964 | userDropdownOpen.value = false; |
| 964 | } | 965 | } |
| 965 | }); | 966 | }); |
| 967 | + const token = getCookie('token') | ||
| 968 | + console.log(token) | ||
| 966 | }); | 969 | }); |
| 967 | 970 | ||
| 968 | tailwind.config = { | 971 | tailwind.config = { |
| @@ -1033,8 +1036,4 @@ tailwind.config = { | @@ -1033,8 +1036,4 @@ tailwind.config = { | ||
| 1033 | @apply opacity-100 translate-y-0; | 1036 | @apply opacity-100 translate-y-0; |
| 1034 | } | 1037 | } |
| 1035 | } | 1038 | } |
| 1036 | - | ||
| 1037 | -.btn-primary { | ||
| 1038 | - background-color: rgb(0, 119, 255); | ||
| 1039 | -} | ||
| 1040 | </style> | 1039 | </style> |
src/views/test1.vue
0 → 100644
| 1 | +<script setup> | ||
| 2 | +import { saveDocx, saveHtml, uploadFile, uploadFileToDataset } from '@/api/aiapi'; | ||
| 3 | +import { ref, onMounted, computed } from 'vue'; | ||
| 4 | +import { MAX_SIZE, INVALID_TYPES } from '@/utils/config.js'; | ||
| 5 | +const messages = ref([]); | ||
| 6 | +const openaiMessages = ref([]); | ||
| 7 | +const inputMessage = ref(''); | ||
| 8 | +const isStreaming = ref(false); | ||
| 9 | +const ws = ref(null); | ||
| 10 | +const isConnected = ref(false); | ||
| 11 | +const currentMode = ref('Dify'); | ||
| 12 | +const modelOptions = ref(['gpt-4o-mini', 'o3-mini', 'gpt-5-mini', 'dall-e-3', 'gpt-3.5-turbo']); | ||
| 13 | +const selectedModel = ref('gpt-4o-mini'); | ||
| 14 | +const fileUrl = ref(''); | ||
| 15 | +const showFile = ref(false); | ||
| 16 | + | ||
| 17 | +const triggerMode = () => { | ||
| 18 | + if (currentMode.value === 'Dify') { | ||
| 19 | + currentMode.value = 'OpenAI'; | ||
| 20 | + } else { | ||
| 21 | + currentMode.value = 'Dify'; | ||
| 22 | + } | ||
| 23 | +}; | ||
| 24 | + | ||
| 25 | +const getCurrentMessages = () => { | ||
| 26 | + return currentMode.value === 'Dify' ? messages.value : openaiMessages.value; | ||
| 27 | +}; | ||
| 28 | + | ||
| 29 | +onMounted(() => { | ||
| 30 | + // 初始化WebSocket连接 | ||
| 31 | + ws.value = new WebSocket('ws://192.168.0.24/ws/chat/378'); | ||
| 32 | + | ||
| 33 | + ws.value.onopen = () => { | ||
| 34 | + isConnected.value = true; | ||
| 35 | + }; | ||
| 36 | + | ||
| 37 | + ws.value.onmessage = (event) => { | ||
| 38 | + const response = JSON.parse(event.data); | ||
| 39 | + console.log("*-**-*--------*", response) | ||
| 40 | + if (response.code === 200) { | ||
| 41 | + // 渲染AI回复 | ||
| 42 | + let aiMessage; | ||
| 43 | + if (response.task_id !== null) { | ||
| 44 | + aiMessage = messages.value.find(m => m.id === response.id && m.role === 'ai'); | ||
| 45 | + } else { | ||
| 46 | + openaiMessages.value.map(item => { | ||
| 47 | + console.log(item.id, response.id, item.id === response.id) | ||
| 48 | + if (item.id === response.id) { | ||
| 49 | + aiMessage = item | ||
| 50 | + } | ||
| 51 | + }) | ||
| 52 | + aiMessage = openaiMessages.value.find(m => m.id === response.id); | ||
| 53 | + } | ||
| 54 | + if (!aiMessage) { | ||
| 55 | + aiMessage = { | ||
| 56 | + role: response.task_id !== null ? 'ai' : 'assistant', | ||
| 57 | + type: 'text', | ||
| 58 | + content: '', | ||
| 59 | + id: response.id, | ||
| 60 | + }; | ||
| 61 | + if (currentMode.value === 'OpenAI') { | ||
| 62 | + openaiMessages.value.push(aiMessage); | ||
| 63 | + } else { | ||
| 64 | + aiMessage.conversation_id = response.conversation_id | ||
| 65 | + messages.value.push(aiMessage); | ||
| 66 | + } | ||
| 67 | + } | ||
| 68 | + // 追加流式内容 | ||
| 69 | + aiMessage.content += response.answer; | ||
| 70 | + } else if (response.code === 203) { | ||
| 71 | + // 回复结束 | ||
| 72 | + isStreaming.value = false; | ||
| 73 | + } else if (response.code === 500) { | ||
| 74 | + // 消息失败处理 | ||
| 75 | + if (currentMode.value === 'OpenAI') { | ||
| 76 | + openaiMessages.value.push({ | ||
| 77 | + role: 'system', | ||
| 78 | + type: 'text', | ||
| 79 | + content: '消息发送失败,请重试' | ||
| 80 | + }); | ||
| 81 | + } else { | ||
| 82 | + messages.value.push({ | ||
| 83 | + role: 'system', | ||
| 84 | + type: 'text', | ||
| 85 | + content: '消息发送失败,请重试' | ||
| 86 | + }); | ||
| 87 | + } | ||
| 88 | + isStreaming.value = false; | ||
| 89 | + } else if (response.code >= 300) { | ||
| 90 | + messages.value.push({ | ||
| 91 | + role: 'system', | ||
| 92 | + type: 'text', | ||
| 93 | + content: response.message | ||
| 94 | + }); | ||
| 95 | + } | ||
| 96 | + }; | ||
| 97 | + | ||
| 98 | + ws.value.onclose = () => { | ||
| 99 | + isConnected.value = false; | ||
| 100 | + }; | ||
| 101 | +}); | ||
| 102 | + | ||
| 103 | +const sendMessage = () => { | ||
| 104 | + if (!inputMessage.value.trim() || !isConnected.value) return; | ||
| 105 | + let data; | ||
| 106 | + if (currentMode.value === 'Dify') { | ||
| 107 | + data = difySendMessage() | ||
| 108 | + } else { | ||
| 109 | + openaiSendMessage() | ||
| 110 | + return | ||
| 111 | + } | ||
| 112 | + console.log("data:", data) | ||
| 113 | + | ||
| 114 | + ws.value.send(JSON.stringify({ | ||
| 115 | + method: currentMode.value, | ||
| 116 | + hasFile: true, | ||
| 117 | + dto: data | ||
| 118 | + })); | ||
| 119 | + fileUrl.value = ''; | ||
| 120 | + showFile.value = false; | ||
| 121 | + inputMessage.value = ''; | ||
| 122 | + isStreaming.value = true; | ||
| 123 | +}; | ||
| 124 | + | ||
| 125 | +const difySendMessage = () => { | ||
| 126 | + // 添加用户消息 | ||
| 127 | + messages.value.push({ | ||
| 128 | + role: 'user', | ||
| 129 | + type: 'text', | ||
| 130 | + content: inputMessage.value | ||
| 131 | + }); | ||
| 132 | + let data = { | ||
| 133 | + query: inputMessage.value | ||
| 134 | + } | ||
| 135 | + const aiMessage = messages.value.find(m => m.role === 'ai'); | ||
| 136 | + if (aiMessage && aiMessage.conversation_id) { | ||
| 137 | + data.conversation_id = aiMessage.conversation_id; | ||
| 138 | + } | ||
| 139 | + return data | ||
| 140 | +} | ||
| 141 | +const openaiSendMessage = () => { | ||
| 142 | + let data = { | ||
| 143 | + model: selectedModel.value, | ||
| 144 | + messages: [], | ||
| 145 | + } | ||
| 146 | + const newMessage = { | ||
| 147 | + role: 'user', | ||
| 148 | + type: 'text', | ||
| 149 | + content: inputMessage.value, | ||
| 150 | + }; | ||
| 151 | + // 如果有上传图片,添加到新消息 | ||
| 152 | + if (fileType.value !== null && fileType.value === 'image') { | ||
| 153 | + newMessage.image_url = uploadedImageUrl.value; | ||
| 154 | + } else if (fileType.value !== null && fileType.value === 'file') { | ||
| 155 | + data.fileContent = fileUrl.value; | ||
| 156 | + } | ||
| 157 | + openaiMessages.value.push(newMessage); | ||
| 158 | + openaiMessages.value.map(item => { | ||
| 159 | + if (item.hasOwnProperty('image_url')) { | ||
| 160 | + data.messages.push({ | ||
| 161 | + role: item.role, | ||
| 162 | + content: [{ | ||
| 163 | + type: 'text', | ||
| 164 | + text: item.content | ||
| 165 | + }, { | ||
| 166 | + type: 'image_url', | ||
| 167 | + image_url: { | ||
| 168 | + url: item.image_url | ||
| 169 | + } | ||
| 170 | + }] | ||
| 171 | + }) | ||
| 172 | + } else { | ||
| 173 | + data.messages.push({ | ||
| 174 | + role: item.role, | ||
| 175 | + content: item.content | ||
| 176 | + }) | ||
| 177 | + } | ||
| 178 | + }) | ||
| 179 | + console.log("11data:", data) | ||
| 180 | + ws.value.send(JSON.stringify({ | ||
| 181 | + method: currentMode.value, | ||
| 182 | + hasFile: true, | ||
| 183 | + dto: data | ||
| 184 | + })); | ||
| 185 | + fileUrl.value = ''; | ||
| 186 | + showFile.value = false; | ||
| 187 | + inputMessage.value = ''; | ||
| 188 | + isStreaming.value = true; | ||
| 189 | +} | ||
| 190 | + | ||
| 191 | +const triggerFileUpload = () => { | ||
| 192 | + document.getElementById('file-upload').click(); | ||
| 193 | +}; | ||
| 194 | + | ||
| 195 | +const handleFileUpload = async (event) => { | ||
| 196 | + try { | ||
| 197 | + const file = event.target.files[0]; | ||
| 198 | + if (!file) return; | ||
| 199 | + const formData = new FormData(); | ||
| 200 | + formData.append('file', file); | ||
| 201 | + const res = await uploadFileToDataset(formData); | ||
| 202 | + | ||
| 203 | + // if (file.size > MAX_SIZE) { | ||
| 204 | + // alert('文件大小不能超过5MB'); | ||
| 205 | + // return; | ||
| 206 | + // } | ||
| 207 | + // const res = await uploadFile(formData); | ||
| 208 | + // console.log("res:", res); | ||
| 209 | + // fileUrl.value = res.data; // 保存返回的URL | ||
| 210 | + // showFile.value = true; | ||
| 211 | + event.target.value = ''; | ||
| 212 | + } catch (err) { | ||
| 213 | + console.log("err:", err); | ||
| 214 | + alert('文件上传失败,请重试'); | ||
| 215 | + } | ||
| 216 | +}; | ||
| 217 | + | ||
| 218 | +const cancel = () => { | ||
| 219 | + fileUrl.value = ''; | ||
| 220 | + showFile.value = false; | ||
| 221 | +} | ||
| 222 | + | ||
| 223 | +const fileType = computed(() => { | ||
| 224 | + if (!fileUrl.value) return null; | ||
| 225 | + | ||
| 226 | + const url = fileUrl.value; | ||
| 227 | + const extension = url.split('.').pop().toLowerCase(); | ||
| 228 | + | ||
| 229 | + const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp']; | ||
| 230 | + | ||
| 231 | + return imageExtensions.includes(extension) ? 'image' : 'file'; | ||
| 232 | +}); | ||
| 233 | + | ||
| 234 | +const extractHtmlFromString = (str) => { | ||
| 235 | + const htmlStart = str.indexOf('```html') + '```html'.length; | ||
| 236 | + const htmlEnd = str.indexOf('```', htmlStart); | ||
| 237 | + | ||
| 238 | + if (htmlStart === -1 || htmlEnd === -1) { | ||
| 239 | + return null; // 没有找到HTML代码块 | ||
| 240 | + } | ||
| 241 | + | ||
| 242 | + return str.substring(htmlStart, htmlEnd).trim(); | ||
| 243 | +} | ||
| 244 | + | ||
| 245 | +const saveToHtml = async (content) => { | ||
| 246 | + const html = extractHtmlFromString(content) | ||
| 247 | + const res = await saveHtml({ | ||
| 248 | + html: html | ||
| 249 | + }) | ||
| 250 | + console.log("res:", res) | ||
| 251 | + if (res.code == '200' && res.data) { | ||
| 252 | + alert("保存成功") | ||
| 253 | + } else { | ||
| 254 | + alert("保存失败") | ||
| 255 | + } | ||
| 256 | +} | ||
| 257 | +function test1(input) { | ||
| 258 | + let processed = input; | ||
| 259 | + const hasSeparator = input.includes('---'); | ||
| 260 | + if (hasSeparator) { | ||
| 261 | + // 按分隔符分割并过滤空内容 | ||
| 262 | + const parts = input.split('---') | ||
| 263 | + .map(part => part.trim()) | ||
| 264 | + .filter(part => part.length > 0); | ||
| 265 | + // 取中间部分或首个有效内容 | ||
| 266 | + processed = parts.length > 1 ? parts.slice(1, -1).join('\n\n') || parts[1] : parts[0]; | ||
| 267 | + } | ||
| 268 | + const lines = processed.split('\n').map(line => line.trim()); | ||
| 269 | + let startIndex = -1; | ||
| 270 | + let endIndex = lines.length; | ||
| 271 | + // 找到第一个#标题的位置 | ||
| 272 | + for (let i = 0; i < lines.length; i++) { | ||
| 273 | + if (lines[i].startsWith('#')) { | ||
| 274 | + startIndex = i; | ||
| 275 | + break; | ||
| 276 | + } | ||
| 277 | + } | ||
| 278 | + if (startIndex === -1) { | ||
| 279 | + return lines.filter(line => line).join('\n'); | ||
| 280 | + } | ||
| 281 | + // 找到文章结束位置(连续空行或内容结束) | ||
| 282 | + for (let i = lines.length - 1; i >= startIndex; i--) { | ||
| 283 | + if (lines[i].length > 0) { | ||
| 284 | + endIndex = i + 1; | ||
| 285 | + break; | ||
| 286 | + } | ||
| 287 | + } | ||
| 288 | + return lines.slice(startIndex, endIndex).join('\n'); | ||
| 289 | +} | ||
| 290 | + | ||
| 291 | +const saveFile = async (content, type) => { | ||
| 292 | + const str = test1(content) | ||
| 293 | + const res = await saveDocx({ | ||
| 294 | + content: str, | ||
| 295 | + type | ||
| 296 | + }) | ||
| 297 | + console.log("res", res) | ||
| 298 | +} | ||
| 299 | + | ||
| 300 | +const test = async () => { | ||
| 301 | + // const file = event.target.files[0]; | ||
| 302 | + // const formData = new FormData(); | ||
| 303 | + // formData.append('file', file); | ||
| 304 | + // if (file.size > MAX_SIZE) { | ||
| 305 | + // alert('文件大小不能超过5MB'); | ||
| 306 | + // return; | ||
| 307 | + // } | ||
| 308 | + // const res = await uploadFile(formData); | ||
| 309 | + // console.log("res:", res); | ||
| 310 | + | ||
| 311 | +} | ||
| 312 | + | ||
| 313 | +</script> | ||
| 314 | +<template> | ||
| 315 | + <div class="chat-container"> | ||
| 316 | + <div class="chat-messages"> | ||
| 317 | + <div v-for="(message, index) in getCurrentMessages()" :key="index" class="message"> | ||
| 318 | + <div :class="['message-content', message.role]"> | ||
| 319 | + <img v-if="message.role === 'user'" src="@/assets/user-icon.png" class="avatar" /> | ||
| 320 | + <img v-else src="@/assets/robot.png" class="avatar" /> | ||
| 321 | + <div class="message-body"> | ||
| 322 | + <div v-if="message.type === 'text'"> | ||
| 323 | + {{ message.content }} | ||
| 324 | + <button v-if="message.content.includes('```html') && message.content.includes('```')" | ||
| 325 | + @click="saveToHtml(message.content)" class="save-btn"> | ||
| 326 | + 保存HTML | ||
| 327 | + </button> | ||
| 328 | + <button @click="saveFile(message.content, 'docx')" class="save-btn"> | ||
| 329 | + 生成DOCX | ||
| 330 | + </button> | ||
| 331 | + <button @click="saveFile(message.content, 'pdf')" class="save-btn"> | ||
| 332 | + 生成PDF | ||
| 333 | + </button> | ||
| 334 | + </div> | ||
| 335 | + <img v-else-if="message.type === 'image'" :src="message.content" class="uploaded-image" /> | ||
| 336 | + <div v-else-if="message.type === 'file'"> | ||
| 337 | + <a :href="message.content" target="_blank">下载文件</a> | ||
| 338 | + </div> | ||
| 339 | + </div> | ||
| 340 | + </div> | ||
| 341 | + </div> | ||
| 342 | + <div v-if="isStreaming" class="streaming-indicator"> | ||
| 343 | + <div class="typing-dots"> | ||
| 344 | + <span></span><span></span><span></span> | ||
| 345 | + </div> | ||
| 346 | + </div> | ||
| 347 | + </div> | ||
| 348 | + <div v-if="showFile" class="image-preview"> | ||
| 349 | + <img v-if="fileType === 'image'" :src="fileUrl" alt="预览图片" /> | ||
| 350 | + <span v-else>已上传文件:{{ fileUrl.split('/').pop() }}</span> | ||
| 351 | + | ||
| 352 | + <button class="cancel-btn" @click="cancel">取消</button> | ||
| 353 | + </div> | ||
| 354 | + | ||
| 355 | + <div class="chat-input"> | ||
| 356 | + <div class="upload-buttons"> | ||
| 357 | + <button class="small-button" @click="triggerMode">当前模式:{{ currentMode }}</button> | ||
| 358 | + <select v-if="currentMode === 'OpenAI'" v-model="selectedModel" class="model-select"> | ||
| 359 | + <option v-for="(model, index) in modelOptions" :value="model" :key="index">{{ model }}</option> | ||
| 360 | + </select> | ||
| 361 | + <div class="vertical-buttons" v-if="currentMode === 'OpenAI'"> | ||
| 362 | + <input type="file" id="file-upload" @change="handleFileUpload" style="display: none" /> | ||
| 363 | + <button class="small-button" @click="triggerFileUpload">上传文件</button> | ||
| 364 | + </div> | ||
| 365 | + </div> | ||
| 366 | + <textarea v-model="inputMessage" @keyup.enter="sendMessage" placeholder="输入消息..."></textarea> | ||
| 367 | + <button @click="sendMessage">发送</button> | ||
| 368 | + <button @click="saveFile">测试</button> | ||
| 369 | + <button @click="test">测试1</button> | ||
| 370 | + </div> | ||
| 371 | + </div> | ||
| 372 | +</template> | ||
| 373 | + | ||
| 374 | + | ||
| 375 | + | ||
| 376 | +<style scoped> | ||
| 377 | +.chat-container { | ||
| 378 | + display: flex; | ||
| 379 | + flex-direction: column; | ||
| 380 | + height: 100vh; | ||
| 381 | + max-width: 800px; | ||
| 382 | + margin: 0 auto; | ||
| 383 | + border: 1px solid #ddd; | ||
| 384 | +} | ||
| 385 | + | ||
| 386 | +.chat-messages { | ||
| 387 | + flex: 1; | ||
| 388 | + overflow-y: auto; | ||
| 389 | + padding: 20px; | ||
| 390 | +} | ||
| 391 | + | ||
| 392 | +.message { | ||
| 393 | + margin-bottom: 15px; | ||
| 394 | +} | ||
| 395 | + | ||
| 396 | +.message-content { | ||
| 397 | + display: flex; | ||
| 398 | + align-items: flex-start; | ||
| 399 | + gap: 10px; | ||
| 400 | +} | ||
| 401 | + | ||
| 402 | +.message-content.user { | ||
| 403 | + flex-direction: row-reverse; | ||
| 404 | +} | ||
| 405 | + | ||
| 406 | +.avatar { | ||
| 407 | + width: 40px; | ||
| 408 | + height: 40px; | ||
| 409 | + border-radius: 50%; | ||
| 410 | + object-fit: cover; | ||
| 411 | +} | ||
| 412 | + | ||
| 413 | +.message-body { | ||
| 414 | + max-width: 70%; | ||
| 415 | + padding: 10px 15px; | ||
| 416 | + border-radius: 18px; | ||
| 417 | + background: #f0f0f0; | ||
| 418 | +} | ||
| 419 | + | ||
| 420 | +.message-content.user .message-body { | ||
| 421 | + background: #007bff; | ||
| 422 | + color: white; | ||
| 423 | +} | ||
| 424 | + | ||
| 425 | +.uploaded-image { | ||
| 426 | + max-width: 200px; | ||
| 427 | + max-height: 200px; | ||
| 428 | + border-radius: 8px; | ||
| 429 | +} | ||
| 430 | + | ||
| 431 | +.chat-input { | ||
| 432 | + display: flex; | ||
| 433 | + padding: 10px; | ||
| 434 | + border-top: 1px solid #ddd; | ||
| 435 | + background: white; | ||
| 436 | + gap: 10px; | ||
| 437 | +} | ||
| 438 | + | ||
| 439 | +.upload-buttons { | ||
| 440 | + display: flex; | ||
| 441 | + flex-direction: column; | ||
| 442 | + gap: 5px; | ||
| 443 | + min-width: 120px; | ||
| 444 | +} | ||
| 445 | + | ||
| 446 | +.vertical-buttons { | ||
| 447 | + display: flex; | ||
| 448 | + flex-direction: column; | ||
| 449 | + gap: 5px; | ||
| 450 | +} | ||
| 451 | + | ||
| 452 | +/* 图片预览样式 */ | ||
| 453 | +.image-preview { | ||
| 454 | + padding: 10px; | ||
| 455 | + text-align: center; | ||
| 456 | + background: #f5f5f5; | ||
| 457 | + border-bottom: 1px solid #ddd; | ||
| 458 | +} | ||
| 459 | + | ||
| 460 | +.image-preview img { | ||
| 461 | + width: 80px; | ||
| 462 | + height: 80px; | ||
| 463 | + object-fit: cover; | ||
| 464 | + margin-bottom: 5px; | ||
| 465 | +} | ||
| 466 | + | ||
| 467 | +.cancel-btn { | ||
| 468 | + padding: 3px 8px; | ||
| 469 | + font-size: 12px; | ||
| 470 | + background: #ff4d4f; | ||
| 471 | +} | ||
| 472 | + | ||
| 473 | +textarea { | ||
| 474 | + flex: 1; | ||
| 475 | + padding: 10px; | ||
| 476 | + border: 1px solid #ddd; | ||
| 477 | + border-radius: 4px; | ||
| 478 | + resize: none; | ||
| 479 | + height: 60px; | ||
| 480 | +} | ||
| 481 | + | ||
| 482 | +button { | ||
| 483 | + padding: 10px 15px; | ||
| 484 | + background: #007bff; | ||
| 485 | + color: white; | ||
| 486 | + border: none; | ||
| 487 | + border-radius: 4px; | ||
| 488 | + cursor: pointer; | ||
| 489 | +} | ||
| 490 | + | ||
| 491 | +.streaming-indicator { | ||
| 492 | + padding: 10px; | ||
| 493 | +} | ||
| 494 | + | ||
| 495 | +.typing-dots span { | ||
| 496 | + display: inline-block; | ||
| 497 | + width: 8px; | ||
| 498 | + height: 8px; | ||
| 499 | + border-radius: 50%; | ||
| 500 | + background: #ccc; | ||
| 501 | + margin: 0 2px; | ||
| 502 | + animation: bounce 1.4s infinite ease-in-out; | ||
| 503 | +} | ||
| 504 | + | ||
| 505 | +.typing-dots span:nth-child(2) { | ||
| 506 | + animation-delay: 0.2s; | ||
| 507 | +} | ||
| 508 | + | ||
| 509 | +.typing-dots span:nth-child(3) { | ||
| 510 | + animation-delay: 0.4s; | ||
| 511 | +} | ||
| 512 | + | ||
| 513 | +@keyframes bounce { | ||
| 514 | + | ||
| 515 | + 0%, | ||
| 516 | + 60%, | ||
| 517 | + 100% { | ||
| 518 | + transform: translateY(0); | ||
| 519 | + } | ||
| 520 | + | ||
| 521 | + 30% { | ||
| 522 | + transform: translateY(-5px); | ||
| 523 | + } | ||
| 524 | +} | ||
| 525 | + | ||
| 526 | +.small-button { | ||
| 527 | + padding: 5px 10px; | ||
| 528 | + font-size: 12px; | ||
| 529 | + height: 30px; | ||
| 530 | +} | ||
| 531 | + | ||
| 532 | +.model-select { | ||
| 533 | + padding: 5px; | ||
| 534 | + border: 1px solid #ddd; | ||
| 535 | + border-radius: 4px; | ||
| 536 | + margin-right: 10px; | ||
| 537 | + height: 30px; | ||
| 538 | +} | ||
| 539 | + | ||
| 540 | +.image-preview { | ||
| 541 | + padding: 10px; | ||
| 542 | + border-bottom: 1px solid #ddd; | ||
| 543 | + text-align: center; | ||
| 544 | +} | ||
| 545 | + | ||
| 546 | +.image-preview img { | ||
| 547 | + max-width: 200px; | ||
| 548 | + max-height: 200px; | ||
| 549 | + margin-bottom: 10px; | ||
| 550 | +} | ||
| 551 | +</style> |
| @@ -15,4 +15,9 @@ export default defineConfig({ | @@ -15,4 +15,9 @@ export default defineConfig({ | ||
| 15 | '@': fileURLToPath(new URL('./src', import.meta.url)) | 15 | '@': fileURLToPath(new URL('./src', import.meta.url)) |
| 16 | }, | 16 | }, |
| 17 | }, | 17 | }, |
| 18 | + server: { | ||
| 19 | + host: '0.0.0.0', | ||
| 20 | + port: 5189, | ||
| 21 | + allowedHosts: ['erpwebtest.yiwaixiao.net', 'webdemo.yiwaixiao.net'] | ||
| 22 | + }, | ||
| 18 | }) | 23 | }) |
-
请 注册 或 登录 后发表评论