feat: 添加axios依赖并初始化数据管理
refactor: 重构页面组件以使用本地数据 style: 调整组件代码结构以提高可读性 docs: 更新组件注释和文档
Showing
20 changed files
with
432 additions
and
72 deletions
| ... | @@ -11,6 +11,7 @@ | ... | @@ -11,6 +11,7 @@ |
| 11 | }, | 11 | }, |
| 12 | "dependencies": { | 12 | "dependencies": { |
| 13 | "@vitejs/plugin-vue-jsx": "4.1.2", | 13 | "@vitejs/plugin-vue-jsx": "4.1.2", |
| 14 | + "axios": "^1.8.4", | ||
| 14 | "pinia": "^2.1.7", | 15 | "pinia": "^2.1.7", |
| 15 | "vue": "^3.4.21", | 16 | "vue": "^3.4.21", |
| 16 | "vue-router": "^4.3.0" | 17 | "vue-router": "^4.3.0" | ... | ... |
| ... | @@ -11,6 +11,9 @@ importers: | ... | @@ -11,6 +11,9 @@ importers: |
| 11 | '@vitejs/plugin-vue-jsx': | 11 | '@vitejs/plugin-vue-jsx': |
| 12 | specifier: 4.1.2 | 12 | specifier: 4.1.2 |
| 13 | version: 4.1.2(vite@5.4.18)(vue@3.5.13) | 13 | version: 4.1.2(vite@5.4.18)(vue@3.5.13) |
| 14 | + axios: | ||
| 15 | + specifier: ^1.8.4 | ||
| 16 | + version: 1.8.4 | ||
| 14 | pinia: | 17 | pinia: |
| 15 | specifier: ^2.1.7 | 18 | specifier: ^2.1.7 |
| 16 | version: 2.3.1(vue@3.5.13) | 19 | version: 2.3.1(vue@3.5.13) |
| ... | @@ -617,6 +620,9 @@ packages: | ... | @@ -617,6 +620,9 @@ packages: |
| 617 | argparse@2.0.1: | 620 | argparse@2.0.1: |
| 618 | resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} | 621 | resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} |
| 619 | 622 | ||
| 623 | + asynckit@0.4.0: | ||
| 624 | + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} | ||
| 625 | + | ||
| 620 | autoprefixer@10.4.21: | 626 | autoprefixer@10.4.21: |
| 621 | resolution: {integrity: sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==} | 627 | resolution: {integrity: sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==} |
| 622 | engines: {node: ^10 || ^12 || >=14} | 628 | engines: {node: ^10 || ^12 || >=14} |
| ... | @@ -624,6 +630,9 @@ packages: | ... | @@ -624,6 +630,9 @@ packages: |
| 624 | peerDependencies: | 630 | peerDependencies: |
| 625 | postcss: ^8.1.0 | 631 | postcss: ^8.1.0 |
| 626 | 632 | ||
| 633 | + axios@1.8.4: | ||
| 634 | + resolution: {integrity: sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==} | ||
| 635 | + | ||
| 627 | balanced-match@1.0.2: | 636 | balanced-match@1.0.2: |
| 628 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} | 637 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} |
| 629 | 638 | ||
| ... | @@ -649,6 +658,10 @@ packages: | ... | @@ -649,6 +658,10 @@ packages: |
| 649 | engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} | 658 | engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} |
| 650 | hasBin: true | 659 | hasBin: true |
| 651 | 660 | ||
| 661 | + call-bind-apply-helpers@1.0.2: | ||
| 662 | + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} | ||
| 663 | + engines: {node: '>= 0.4'} | ||
| 664 | + | ||
| 652 | callsites@3.1.0: | 665 | callsites@3.1.0: |
| 653 | resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} | 666 | resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} |
| 654 | engines: {node: '>=6'} | 667 | engines: {node: '>=6'} |
| ... | @@ -675,6 +688,10 @@ packages: | ... | @@ -675,6 +688,10 @@ packages: |
| 675 | color-name@1.1.4: | 688 | color-name@1.1.4: |
| 676 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} | 689 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} |
| 677 | 690 | ||
| 691 | + combined-stream@1.0.8: | ||
| 692 | + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} | ||
| 693 | + engines: {node: '>= 0.8'} | ||
| 694 | + | ||
| 678 | commander@4.1.1: | 695 | commander@4.1.1: |
| 679 | resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} | 696 | resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} |
| 680 | engines: {node: '>= 6'} | 697 | engines: {node: '>= 6'} |
| ... | @@ -709,12 +726,20 @@ packages: | ... | @@ -709,12 +726,20 @@ packages: |
| 709 | deep-is@0.1.4: | 726 | deep-is@0.1.4: |
| 710 | resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} | 727 | resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} |
| 711 | 728 | ||
| 729 | + delayed-stream@1.0.0: | ||
| 730 | + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} | ||
| 731 | + engines: {node: '>=0.4.0'} | ||
| 732 | + | ||
| 712 | didyoumean@1.2.2: | 733 | didyoumean@1.2.2: |
| 713 | resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} | 734 | resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} |
| 714 | 735 | ||
| 715 | dlv@1.1.3: | 736 | dlv@1.1.3: |
| 716 | resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} | 737 | resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} |
| 717 | 738 | ||
| 739 | + dunder-proto@1.0.1: | ||
| 740 | + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} | ||
| 741 | + engines: {node: '>= 0.4'} | ||
| 742 | + | ||
| 718 | eastasianwidth@0.2.0: | 743 | eastasianwidth@0.2.0: |
| 719 | resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} | 744 | resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} |
| 720 | 745 | ||
| ... | @@ -731,6 +756,22 @@ packages: | ... | @@ -731,6 +756,22 @@ packages: |
| 731 | resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} | 756 | resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} |
| 732 | engines: {node: '>=0.12'} | 757 | engines: {node: '>=0.12'} |
| 733 | 758 | ||
| 759 | + es-define-property@1.0.1: | ||
| 760 | + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} | ||
| 761 | + engines: {node: '>= 0.4'} | ||
| 762 | + | ||
| 763 | + es-errors@1.3.0: | ||
| 764 | + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} | ||
| 765 | + engines: {node: '>= 0.4'} | ||
| 766 | + | ||
| 767 | + es-object-atoms@1.1.1: | ||
| 768 | + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} | ||
| 769 | + engines: {node: '>= 0.4'} | ||
| 770 | + | ||
| 771 | + es-set-tostringtag@2.1.0: | ||
| 772 | + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} | ||
| 773 | + engines: {node: '>= 0.4'} | ||
| 774 | + | ||
| 734 | esbuild@0.21.5: | 775 | esbuild@0.21.5: |
| 735 | resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} | 776 | resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} |
| 736 | engines: {node: '>=12'} | 777 | engines: {node: '>=12'} |
| ... | @@ -838,10 +879,23 @@ packages: | ... | @@ -838,10 +879,23 @@ packages: |
| 838 | flatted@3.3.3: | 879 | flatted@3.3.3: |
| 839 | resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} | 880 | resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} |
| 840 | 881 | ||
| 882 | + follow-redirects@1.15.9: | ||
| 883 | + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} | ||
| 884 | + engines: {node: '>=4.0'} | ||
| 885 | + peerDependencies: | ||
| 886 | + debug: '*' | ||
| 887 | + peerDependenciesMeta: | ||
| 888 | + debug: | ||
| 889 | + optional: true | ||
| 890 | + | ||
| 841 | foreground-child@3.3.1: | 891 | foreground-child@3.3.1: |
| 842 | resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} | 892 | resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} |
| 843 | engines: {node: '>=14'} | 893 | engines: {node: '>=14'} |
| 844 | 894 | ||
| 895 | + form-data@4.0.2: | ||
| 896 | + resolution: {integrity: sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==} | ||
| 897 | + engines: {node: '>= 6'} | ||
| 898 | + | ||
| 845 | fraction.js@4.3.7: | 899 | fraction.js@4.3.7: |
| 846 | resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} | 900 | resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} |
| 847 | 901 | ||
| ... | @@ -857,6 +911,14 @@ packages: | ... | @@ -857,6 +911,14 @@ packages: |
| 857 | resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} | 911 | resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} |
| 858 | engines: {node: '>=6.9.0'} | 912 | engines: {node: '>=6.9.0'} |
| 859 | 913 | ||
| 914 | + get-intrinsic@1.3.0: | ||
| 915 | + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} | ||
| 916 | + engines: {node: '>= 0.4'} | ||
| 917 | + | ||
| 918 | + get-proto@1.0.1: | ||
| 919 | + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} | ||
| 920 | + engines: {node: '>= 0.4'} | ||
| 921 | + | ||
| 860 | glob-parent@5.1.2: | 922 | glob-parent@5.1.2: |
| 861 | resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} | 923 | resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} |
| 862 | engines: {node: '>= 6'} | 924 | engines: {node: '>= 6'} |
| ... | @@ -881,10 +943,22 @@ packages: | ... | @@ -881,10 +943,22 @@ packages: |
| 881 | resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} | 943 | resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} |
| 882 | engines: {node: '>=18'} | 944 | engines: {node: '>=18'} |
| 883 | 945 | ||
| 946 | + gopd@1.2.0: | ||
| 947 | + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} | ||
| 948 | + engines: {node: '>= 0.4'} | ||
| 949 | + | ||
| 884 | has-flag@4.0.0: | 950 | has-flag@4.0.0: |
| 885 | resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} | 951 | resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} |
| 886 | engines: {node: '>=8'} | 952 | engines: {node: '>=8'} |
| 887 | 953 | ||
| 954 | + has-symbols@1.1.0: | ||
| 955 | + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} | ||
| 956 | + engines: {node: '>= 0.4'} | ||
| 957 | + | ||
| 958 | + has-tostringtag@1.0.2: | ||
| 959 | + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} | ||
| 960 | + engines: {node: '>= 0.4'} | ||
| 961 | + | ||
| 888 | hasown@2.0.2: | 962 | hasown@2.0.2: |
| 889 | resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} | 963 | resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} |
| 890 | engines: {node: '>= 0.4'} | 964 | engines: {node: '>= 0.4'} |
| ... | @@ -994,6 +1068,10 @@ packages: | ... | @@ -994,6 +1068,10 @@ packages: |
| 994 | magic-string@0.30.17: | 1068 | magic-string@0.30.17: |
| 995 | resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} | 1069 | resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} |
| 996 | 1070 | ||
| 1071 | + math-intrinsics@1.1.0: | ||
| 1072 | + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} | ||
| 1073 | + engines: {node: '>= 0.4'} | ||
| 1074 | + | ||
| 997 | merge2@1.4.1: | 1075 | merge2@1.4.1: |
| 998 | resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} | 1076 | resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} |
| 999 | engines: {node: '>= 8'} | 1077 | engines: {node: '>= 8'} |
| ... | @@ -1002,6 +1080,14 @@ packages: | ... | @@ -1002,6 +1080,14 @@ packages: |
| 1002 | resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} | 1080 | resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} |
| 1003 | engines: {node: '>=8.6'} | 1081 | engines: {node: '>=8.6'} |
| 1004 | 1082 | ||
| 1083 | + mime-db@1.52.0: | ||
| 1084 | + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} | ||
| 1085 | + engines: {node: '>= 0.6'} | ||
| 1086 | + | ||
| 1087 | + mime-types@2.1.35: | ||
| 1088 | + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} | ||
| 1089 | + engines: {node: '>= 0.6'} | ||
| 1090 | + | ||
| 1005 | minimatch@3.1.2: | 1091 | minimatch@3.1.2: |
| 1006 | resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} | 1092 | resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} |
| 1007 | 1093 | ||
| ... | @@ -1152,6 +1238,9 @@ packages: | ... | @@ -1152,6 +1238,9 @@ packages: |
| 1152 | resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} | 1238 | resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} |
| 1153 | engines: {node: '>= 0.8.0'} | 1239 | engines: {node: '>= 0.8.0'} |
| 1154 | 1240 | ||
| 1241 | + proxy-from-env@1.1.0: | ||
| 1242 | + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} | ||
| 1243 | + | ||
| 1155 | punycode@2.3.1: | 1244 | punycode@2.3.1: |
| 1156 | resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} | 1245 | resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} |
| 1157 | engines: {node: '>=6'} | 1246 | engines: {node: '>=6'} |
| ... | @@ -1921,6 +2010,8 @@ snapshots: | ... | @@ -1921,6 +2010,8 @@ snapshots: |
| 1921 | 2010 | ||
| 1922 | argparse@2.0.1: {} | 2011 | argparse@2.0.1: {} |
| 1923 | 2012 | ||
| 2013 | + asynckit@0.4.0: {} | ||
| 2014 | + | ||
| 1924 | autoprefixer@10.4.21(postcss@8.5.3): | 2015 | autoprefixer@10.4.21(postcss@8.5.3): |
| 1925 | dependencies: | 2016 | dependencies: |
| 1926 | browserslist: 4.24.4 | 2017 | browserslist: 4.24.4 |
| ... | @@ -1931,6 +2022,14 @@ snapshots: | ... | @@ -1931,6 +2022,14 @@ snapshots: |
| 1931 | postcss: 8.5.3 | 2022 | postcss: 8.5.3 |
| 1932 | postcss-value-parser: 4.2.0 | 2023 | postcss-value-parser: 4.2.0 |
| 1933 | 2024 | ||
| 2025 | + axios@1.8.4: | ||
| 2026 | + dependencies: | ||
| 2027 | + follow-redirects: 1.15.9 | ||
| 2028 | + form-data: 4.0.2 | ||
| 2029 | + proxy-from-env: 1.1.0 | ||
| 2030 | + transitivePeerDependencies: | ||
| 2031 | + - debug | ||
| 2032 | + | ||
| 1934 | balanced-match@1.0.2: {} | 2033 | balanced-match@1.0.2: {} |
| 1935 | 2034 | ||
| 1936 | binary-extensions@2.3.0: {} | 2035 | binary-extensions@2.3.0: {} |
| ... | @@ -1957,6 +2056,11 @@ snapshots: | ... | @@ -1957,6 +2056,11 @@ snapshots: |
| 1957 | node-releases: 2.0.19 | 2056 | node-releases: 2.0.19 |
| 1958 | update-browserslist-db: 1.1.3(browserslist@4.24.4) | 2057 | update-browserslist-db: 1.1.3(browserslist@4.24.4) |
| 1959 | 2058 | ||
| 2059 | + call-bind-apply-helpers@1.0.2: | ||
| 2060 | + dependencies: | ||
| 2061 | + es-errors: 1.3.0 | ||
| 2062 | + function-bind: 1.1.2 | ||
| 2063 | + | ||
| 1960 | callsites@3.1.0: {} | 2064 | callsites@3.1.0: {} |
| 1961 | 2065 | ||
| 1962 | camelcase-css@2.0.1: {} | 2066 | camelcase-css@2.0.1: {} |
| ... | @@ -1986,6 +2090,10 @@ snapshots: | ... | @@ -1986,6 +2090,10 @@ snapshots: |
| 1986 | 2090 | ||
| 1987 | color-name@1.1.4: {} | 2091 | color-name@1.1.4: {} |
| 1988 | 2092 | ||
| 2093 | + combined-stream@1.0.8: | ||
| 2094 | + dependencies: | ||
| 2095 | + delayed-stream: 1.0.0 | ||
| 2096 | + | ||
| 1989 | commander@4.1.1: {} | 2097 | commander@4.1.1: {} |
| 1990 | 2098 | ||
| 1991 | concat-map@0.0.1: {} | 2099 | concat-map@0.0.1: {} |
| ... | @@ -2008,10 +2116,18 @@ snapshots: | ... | @@ -2008,10 +2116,18 @@ snapshots: |
| 2008 | 2116 | ||
| 2009 | deep-is@0.1.4: {} | 2117 | deep-is@0.1.4: {} |
| 2010 | 2118 | ||
| 2119 | + delayed-stream@1.0.0: {} | ||
| 2120 | + | ||
| 2011 | didyoumean@1.2.2: {} | 2121 | didyoumean@1.2.2: {} |
| 2012 | 2122 | ||
| 2013 | dlv@1.1.3: {} | 2123 | dlv@1.1.3: {} |
| 2014 | 2124 | ||
| 2125 | + dunder-proto@1.0.1: | ||
| 2126 | + dependencies: | ||
| 2127 | + call-bind-apply-helpers: 1.0.2 | ||
| 2128 | + es-errors: 1.3.0 | ||
| 2129 | + gopd: 1.2.0 | ||
| 2130 | + | ||
| 2015 | eastasianwidth@0.2.0: {} | 2131 | eastasianwidth@0.2.0: {} |
| 2016 | 2132 | ||
| 2017 | electron-to-chromium@1.5.137: {} | 2133 | electron-to-chromium@1.5.137: {} |
| ... | @@ -2022,6 +2138,21 @@ snapshots: | ... | @@ -2022,6 +2138,21 @@ snapshots: |
| 2022 | 2138 | ||
| 2023 | entities@4.5.0: {} | 2139 | entities@4.5.0: {} |
| 2024 | 2140 | ||
| 2141 | + es-define-property@1.0.1: {} | ||
| 2142 | + | ||
| 2143 | + es-errors@1.3.0: {} | ||
| 2144 | + | ||
| 2145 | + es-object-atoms@1.1.1: | ||
| 2146 | + dependencies: | ||
| 2147 | + es-errors: 1.3.0 | ||
| 2148 | + | ||
| 2149 | + es-set-tostringtag@2.1.0: | ||
| 2150 | + dependencies: | ||
| 2151 | + es-errors: 1.3.0 | ||
| 2152 | + get-intrinsic: 1.3.0 | ||
| 2153 | + has-tostringtag: 1.0.2 | ||
| 2154 | + hasown: 2.0.2 | ||
| 2155 | + | ||
| 2025 | esbuild@0.21.5: | 2156 | esbuild@0.21.5: |
| 2026 | optionalDependencies: | 2157 | optionalDependencies: |
| 2027 | '@esbuild/aix-ppc64': 0.21.5 | 2158 | '@esbuild/aix-ppc64': 0.21.5 |
| ... | @@ -2186,11 +2317,20 @@ snapshots: | ... | @@ -2186,11 +2317,20 @@ snapshots: |
| 2186 | 2317 | ||
| 2187 | flatted@3.3.3: {} | 2318 | flatted@3.3.3: {} |
| 2188 | 2319 | ||
| 2320 | + follow-redirects@1.15.9: {} | ||
| 2321 | + | ||
| 2189 | foreground-child@3.3.1: | 2322 | foreground-child@3.3.1: |
| 2190 | dependencies: | 2323 | dependencies: |
| 2191 | cross-spawn: 7.0.6 | 2324 | cross-spawn: 7.0.6 |
| 2192 | signal-exit: 4.1.0 | 2325 | signal-exit: 4.1.0 |
| 2193 | 2326 | ||
| 2327 | + form-data@4.0.2: | ||
| 2328 | + dependencies: | ||
| 2329 | + asynckit: 0.4.0 | ||
| 2330 | + combined-stream: 1.0.8 | ||
| 2331 | + es-set-tostringtag: 2.1.0 | ||
| 2332 | + mime-types: 2.1.35 | ||
| 2333 | + | ||
| 2194 | fraction.js@4.3.7: {} | 2334 | fraction.js@4.3.7: {} |
| 2195 | 2335 | ||
| 2196 | fsevents@2.3.3: | 2336 | fsevents@2.3.3: |
| ... | @@ -2200,6 +2340,24 @@ snapshots: | ... | @@ -2200,6 +2340,24 @@ snapshots: |
| 2200 | 2340 | ||
| 2201 | gensync@1.0.0-beta.2: {} | 2341 | gensync@1.0.0-beta.2: {} |
| 2202 | 2342 | ||
| 2343 | + get-intrinsic@1.3.0: | ||
| 2344 | + dependencies: | ||
| 2345 | + call-bind-apply-helpers: 1.0.2 | ||
| 2346 | + es-define-property: 1.0.1 | ||
| 2347 | + es-errors: 1.3.0 | ||
| 2348 | + es-object-atoms: 1.1.1 | ||
| 2349 | + function-bind: 1.1.2 | ||
| 2350 | + get-proto: 1.0.1 | ||
| 2351 | + gopd: 1.2.0 | ||
| 2352 | + has-symbols: 1.1.0 | ||
| 2353 | + hasown: 2.0.2 | ||
| 2354 | + math-intrinsics: 1.1.0 | ||
| 2355 | + | ||
| 2356 | + get-proto@1.0.1: | ||
| 2357 | + dependencies: | ||
| 2358 | + dunder-proto: 1.0.1 | ||
| 2359 | + es-object-atoms: 1.1.1 | ||
| 2360 | + | ||
| 2203 | glob-parent@5.1.2: | 2361 | glob-parent@5.1.2: |
| 2204 | dependencies: | 2362 | dependencies: |
| 2205 | is-glob: 4.0.3 | 2363 | is-glob: 4.0.3 |
| ... | @@ -2225,8 +2383,16 @@ snapshots: | ... | @@ -2225,8 +2383,16 @@ snapshots: |
| 2225 | 2383 | ||
| 2226 | globals@14.0.0: {} | 2384 | globals@14.0.0: {} |
| 2227 | 2385 | ||
| 2386 | + gopd@1.2.0: {} | ||
| 2387 | + | ||
| 2228 | has-flag@4.0.0: {} | 2388 | has-flag@4.0.0: {} |
| 2229 | 2389 | ||
| 2390 | + has-symbols@1.1.0: {} | ||
| 2391 | + | ||
| 2392 | + has-tostringtag@1.0.2: | ||
| 2393 | + dependencies: | ||
| 2394 | + has-symbols: 1.1.0 | ||
| 2395 | + | ||
| 2230 | hasown@2.0.2: | 2396 | hasown@2.0.2: |
| 2231 | dependencies: | 2397 | dependencies: |
| 2232 | function-bind: 1.1.2 | 2398 | function-bind: 1.1.2 |
| ... | @@ -2315,6 +2481,8 @@ snapshots: | ... | @@ -2315,6 +2481,8 @@ snapshots: |
| 2315 | dependencies: | 2481 | dependencies: |
| 2316 | '@jridgewell/sourcemap-codec': 1.5.0 | 2482 | '@jridgewell/sourcemap-codec': 1.5.0 |
| 2317 | 2483 | ||
| 2484 | + math-intrinsics@1.1.0: {} | ||
| 2485 | + | ||
| 2318 | merge2@1.4.1: {} | 2486 | merge2@1.4.1: {} |
| 2319 | 2487 | ||
| 2320 | micromatch@4.0.8: | 2488 | micromatch@4.0.8: |
| ... | @@ -2322,6 +2490,12 @@ snapshots: | ... | @@ -2322,6 +2490,12 @@ snapshots: |
| 2322 | braces: 3.0.3 | 2490 | braces: 3.0.3 |
| 2323 | picomatch: 2.3.1 | 2491 | picomatch: 2.3.1 |
| 2324 | 2492 | ||
| 2493 | + mime-db@1.52.0: {} | ||
| 2494 | + | ||
| 2495 | + mime-types@2.1.35: | ||
| 2496 | + dependencies: | ||
| 2497 | + mime-db: 1.52.0 | ||
| 2498 | + | ||
| 2325 | minimatch@3.1.2: | 2499 | minimatch@3.1.2: |
| 2326 | dependencies: | 2500 | dependencies: |
| 2327 | brace-expansion: 1.1.11 | 2501 | brace-expansion: 1.1.11 |
| ... | @@ -2447,6 +2621,8 @@ snapshots: | ... | @@ -2447,6 +2621,8 @@ snapshots: |
| 2447 | 2621 | ||
| 2448 | prelude-ls@1.2.1: {} | 2622 | prelude-ls@1.2.1: {} |
| 2449 | 2623 | ||
| 2624 | + proxy-from-env@1.1.0: {} | ||
| 2625 | + | ||
| 2450 | punycode@2.3.1: {} | 2626 | punycode@2.3.1: {} |
| 2451 | 2627 | ||
| 2452 | queue-microtask@1.2.3: {} | 2628 | queue-microtask@1.2.3: {} | ... | ... |
| ... | @@ -13,6 +13,7 @@ | ... | @@ -13,6 +13,7 @@ |
| 13 | * @Description: 文件描述 | 13 | * @Description: 文件描述 |
| 14 | */ | 14 | */ |
| 15 | <template> | 15 | <template> |
| 16 | + <AppProvider> | ||
| 16 | <div class="flex flex-col min-h-screen"> | 17 | <div class="flex flex-col min-h-screen"> |
| 17 | <Header /> | 18 | <Header /> |
| 18 | <main class="flex-grow"> | 19 | <main class="flex-grow"> |
| ... | @@ -20,12 +21,14 @@ | ... | @@ -20,12 +21,14 @@ |
| 20 | </main> | 21 | </main> |
| 21 | <Footer /> | 22 | <Footer /> |
| 22 | </div> | 23 | </div> |
| 24 | + </AppProvider> | ||
| 23 | </template> | 25 | </template> |
| 24 | 26 | ||
| 25 | <script setup> | 27 | <script setup> |
| 26 | import { onMounted } from 'vue' | 28 | import { onMounted } from 'vue' |
| 27 | import Header from './components/layout/Header.vue' | 29 | import Header from './components/layout/Header.vue' |
| 28 | import Footer from './components/layout/Footer.vue' | 30 | import Footer from './components/layout/Footer.vue' |
| 31 | +import AppProvider from './providers/AppProvider.vue' | ||
| 29 | 32 | ||
| 30 | // 更新文档标题 | 33 | // 更新文档标题 |
| 31 | onMounted(() => { | 34 | onMounted(() => { | ... | ... |
src/assets/images/avatars/default_avatar.svg
0 → 100644
| ... | @@ -42,7 +42,7 @@ | ... | @@ -42,7 +42,7 @@ |
| 42 | <div class="relative"> | 42 | <div class="relative"> |
| 43 | <button @click="toggleProfileDropdown" class="flex items-center space-x-2"> | 43 | <button @click="toggleProfileDropdown" class="flex items-center space-x-2"> |
| 44 | <div class="h-8 w-8 rounded-full overflow-hidden border-2 border-green-500"> | 44 | <div class="h-8 w-8 rounded-full overflow-hidden border-2 border-green-500"> |
| 45 | - <img :src="currentUser?.avatar || '/assets/images/avatars/default_avatar.png'" alt="User Avatar" class="h-full w-full object-cover" /> | 45 | + <img :src="currentUser?.avatar || '/src/assets/images/avatars/default_avatar.svg'" alt="User Avatar" class="h-full w-full object-cover" /> |
| 46 | </div> | 46 | </div> |
| 47 | <span class="hidden lg:block text-sm font-medium text-gray-700">{{ currentUser?.name || 'User' }}</span> | 47 | <span class="hidden lg:block text-sm font-medium text-gray-700">{{ currentUser?.name || 'User' }}</span> |
| 48 | <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | 48 | <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | ... | ... |
| ... | @@ -19,7 +19,7 @@ | ... | @@ -19,7 +19,7 @@ |
| 19 | </button> | 19 | </button> |
| 20 | </template> | 20 | </template> |
| 21 | 21 | ||
| 22 | -<script setup> | 22 | +<script> |
| 23 | import { computed } from 'vue' | 23 | import { computed } from 'vue' |
| 24 | 24 | ||
| 25 | const buttonVariants = { | 25 | const buttonVariants = { |
| ... | @@ -50,7 +50,10 @@ const buttonRounded = { | ... | @@ -50,7 +50,10 @@ const buttonRounded = { |
| 50 | 50 | ||
| 51 | const buttonBlock = 'w-full flex justify-center' | 51 | const buttonBlock = 'w-full flex justify-center' |
| 52 | 52 | ||
| 53 | -const props = defineProps({ | 53 | +const baseClasses = 'flex items-center justify-center font-medium border shadow-sm transition duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500 disabled:opacity-50 disabled:cursor-not-allowed' |
| 54 | + | ||
| 55 | +export default { | ||
| 56 | + props: { | ||
| 54 | variant: { | 57 | variant: { |
| 55 | type: String, | 58 | type: String, |
| 56 | default: 'primary', | 59 | default: 'primary', |
| ... | @@ -90,13 +93,20 @@ const props = defineProps({ | ... | @@ -90,13 +93,20 @@ const props = defineProps({ |
| 90 | type: String, | 93 | type: String, |
| 91 | default: 'button' | 94 | default: 'button' |
| 92 | } | 95 | } |
| 93 | -}) | 96 | + }, |
| 94 | - | 97 | + emits: ['click'], |
| 95 | -defineEmits(['click']) | 98 | + setup(props) { |
| 96 | - | 99 | + const variantClass = computed(() => buttonVariants[props.variant] || buttonVariants.primary) |
| 97 | -const baseClasses = 'flex items-center justify-center font-medium border shadow-sm transition duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500 disabled:opacity-50 disabled:cursor-not-allowed' | 100 | + const sizeClass = computed(() => buttonSizes[props.size] || buttonSizes.md) |
| 101 | + const roundedClass = computed(() => buttonRounded[props.rounded] || buttonRounded.md) | ||
| 98 | 102 | ||
| 99 | -const variantClass = computed(() => buttonVariants[props.variant] || buttonVariants.primary) | 103 | + return { |
| 100 | -const sizeClass = computed(() => buttonSizes[props.size] || buttonSizes.md) | 104 | + baseClasses, |
| 101 | -const roundedClass = computed(() => buttonRounded[props.rounded] || buttonRounded.md) | 105 | + variantClass, |
| 106 | + sizeClass, | ||
| 107 | + roundedClass, | ||
| 108 | + buttonBlock | ||
| 109 | + } | ||
| 110 | + } | ||
| 111 | +} | ||
| 102 | </script> | 112 | </script> | ... | ... |
| ... | @@ -51,7 +51,7 @@ | ... | @@ -51,7 +51,7 @@ |
| 51 | </div> | 51 | </div> |
| 52 | </template> | 52 | </template> |
| 53 | 53 | ||
| 54 | -<script setup> | 54 | +<script> |
| 55 | import { computed } from 'vue' | 55 | import { computed } from 'vue' |
| 56 | 56 | ||
| 57 | const inputSizes = { | 57 | const inputSizes = { |
| ... | @@ -60,7 +60,9 @@ const inputSizes = { | ... | @@ -60,7 +60,9 @@ const inputSizes = { |
| 60 | lg: 'px-4 py-3 text-lg' | 60 | lg: 'px-4 py-3 text-lg' |
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | -const props = defineProps({ | 63 | +export default { |
| 64 | + name: 'Input', | ||
| 65 | + props: { | ||
| 64 | modelValue: { | 66 | modelValue: { |
| 65 | type: [String, Number], | 67 | type: [String, Number], |
| 66 | default: '' | 68 | default: '' |
| ... | @@ -114,10 +116,16 @@ const props = defineProps({ | ... | @@ -114,10 +116,16 @@ const props = defineProps({ |
| 114 | type: [String, Object], | 116 | type: [String, Object], |
| 115 | default: null | 117 | default: null |
| 116 | } | 118 | } |
| 117 | -}) | 119 | + }, |
| 118 | - | 120 | + emits: ['update:modelValue', 'blur'], |
| 119 | -defineEmits(['update:modelValue', 'blur']) | 121 | + setup(props) { |
| 122 | + const inputId = computed(() => `input-${props.name}`) | ||
| 123 | + const sizeClass = computed(() => inputSizes[props.size] || inputSizes.md) | ||
| 120 | 124 | ||
| 121 | -const inputId = computed(() => `input-${props.name}`) | 125 | + return { |
| 122 | -const sizeClass = computed(() => inputSizes[props.size] || inputSizes.md) | 126 | + inputId, |
| 127 | + sizeClass | ||
| 128 | + } | ||
| 129 | + } | ||
| 130 | +} | ||
| 123 | </script> | 131 | </script> | ... | ... |
| 1 | <script setup> | 1 | <script setup> |
| 2 | -import { ref, onMounted, onUnmounted, watch } from 'vue'; | 2 | +import { ref, onMounted, onUnmounted, watch, computed } from 'vue'; |
| 3 | + | ||
| 4 | +// Set sizes based on the size prop | ||
| 5 | +const sizeClasses = { | ||
| 6 | + sm: 'max-w-md', | ||
| 7 | + md: 'max-w-lg', | ||
| 8 | + lg: 'max-w-2xl', | ||
| 9 | + xl: 'max-w-4xl', | ||
| 10 | + full: 'max-w-full mx-4' | ||
| 11 | +}; | ||
| 3 | 12 | ||
| 4 | const props = defineProps({ | 13 | const props = defineProps({ |
| 5 | isOpen: { | 14 | isOpen: { |
| ... | @@ -33,15 +42,6 @@ const emit = defineEmits(['close']); | ... | @@ -33,15 +42,6 @@ const emit = defineEmits(['close']); |
| 33 | const modalRef = ref(null); | 42 | const modalRef = ref(null); |
| 34 | const isMounted = ref(false); | 43 | const isMounted = ref(false); |
| 35 | 44 | ||
| 36 | -// Set sizes based on the size prop | ||
| 37 | -const sizeClasses = { | ||
| 38 | - sm: 'max-w-md', | ||
| 39 | - md: 'max-w-lg', | ||
| 40 | - lg: 'max-w-2xl', | ||
| 41 | - xl: 'max-w-4xl', | ||
| 42 | - full: 'max-w-full mx-4' | ||
| 43 | -}; | ||
| 44 | - | ||
| 45 | const modalSize = computed(() => sizeClasses[props.size] || sizeClasses.md); | 45 | const modalSize = computed(() => sizeClasses[props.size] || sizeClasses.md); |
| 46 | 46 | ||
| 47 | // Handle ESC key press | 47 | // Handle ESC key press | ... | ... |
| ... | @@ -21,6 +21,12 @@ | ... | @@ -21,6 +21,12 @@ |
| 21 | </div> | 21 | </div> |
| 22 | </template> | 22 | </template> |
| 23 | 23 | ||
| 24 | +<script> | ||
| 25 | +// Define valid values for variant and size props | ||
| 26 | +const validVariants = ['underline', 'pills', 'bordered']; | ||
| 27 | +const validSizes = ['sm', 'md', 'lg']; | ||
| 28 | +</script> | ||
| 29 | + | ||
| 24 | <script setup> | 30 | <script setup> |
| 25 | import { ref, computed } from 'vue'; | 31 | import { ref, computed } from 'vue'; |
| 26 | 32 | ||
| ... | @@ -39,13 +45,13 @@ const props = defineProps({ | ... | @@ -39,13 +45,13 @@ const props = defineProps({ |
| 39 | }, | 45 | }, |
| 40 | variant: { | 46 | variant: { |
| 41 | type: String, | 47 | type: String, |
| 42 | - default: 'underline', // 'underline', 'pills', 'bordered' | 48 | + default: 'underline', |
| 43 | - validator: (value) => ['underline', 'pills', 'bordered'].includes(value) | 49 | + validator: (value) => validVariants.includes(value) |
| 44 | }, | 50 | }, |
| 45 | size: { | 51 | size: { |
| 46 | type: String, | 52 | type: String, |
| 47 | - default: 'md', // 'sm', 'md', 'lg' | 53 | + default: 'md', |
| 48 | - validator: (value) => ['sm', 'md', 'lg'].includes(value) | 54 | + validator: (value) => validSizes.includes(value) |
| 49 | } | 55 | } |
| 50 | }); | 56 | }); |
| 51 | 57 | ... | ... |
src/data/activities.json
0 → 100644
| 1 | +{ | ||
| 2 | + "activities": [ | ||
| 3 | + { | ||
| 4 | + "id": "A0001", | ||
| 5 | + "title": "Vue.js 3.0 读书会", | ||
| 6 | + "description": "每周四晚上8点,我们一起学习Vue.js 3.0的新特性和最佳实践。", | ||
| 7 | + "start_time": "2024-04-18 20:00:00", | ||
| 8 | + "end_time": "2024-04-18 22:00:00", | ||
| 9 | + "location": "线上会议室", | ||
| 10 | + "max_participants": 20, | ||
| 11 | + "current_participants": 5, | ||
| 12 | + "organizer_id": "U0001", | ||
| 13 | + "organizer_name": "张三", | ||
| 14 | + "status": "upcoming", | ||
| 15 | + "is_public": true, | ||
| 16 | + "tags": [ | ||
| 17 | + "Vue.js", | ||
| 18 | + "前端开发", | ||
| 19 | + "读书会" | ||
| 20 | + ], | ||
| 21 | + "requirements": "需要基本的JavaScript和Vue.js基础知识", | ||
| 22 | + "materials": [ | ||
| 23 | + "Vue.js 3.0官方文档", | ||
| 24 | + "示例代码仓库" | ||
| 25 | + ], | ||
| 26 | + "created_at": "2024-04-10 10:00:00", | ||
| 27 | + "updated_at": "2024-04-10 10:00:00" | ||
| 28 | + } | ||
| 29 | + ] | ||
| 30 | +} |
src/data/messages.json
0 → 100644
| 1 | +{ | ||
| 2 | + "messages": [ | ||
| 3 | + { | ||
| 4 | + "id": "M0001", | ||
| 5 | + "sender_id": "system", | ||
| 6 | + "recipient_id": "U0001", | ||
| 7 | + "title": "活动提醒", | ||
| 8 | + "content": "您报名的Vue.js 3.0读书会将在明天晚上8点开始,请准时参加。", | ||
| 9 | + "type": "notification", | ||
| 10 | + "priority": "normal", | ||
| 11 | + "read_status": false, | ||
| 12 | + "created_at": "2024-04-17 10:00:00", | ||
| 13 | + "updated_at": "2024-04-17 10:00:00" | ||
| 14 | + } | ||
| 15 | + ] | ||
| 16 | +} |
src/data/registrations.json
0 → 100644
| 1 | +{ | ||
| 2 | + "registrations": [ | ||
| 3 | + { | ||
| 4 | + "id": "R0001", | ||
| 5 | + "activity_id": "A0001", | ||
| 6 | + "user_id": "U0001", | ||
| 7 | + "registration_time": "2024-04-15 14:30:00", | ||
| 8 | + "status": "confirmed", | ||
| 9 | + "custom_fields": [ | ||
| 10 | + { | ||
| 11 | + "field_name": "experience_level", | ||
| 12 | + "field_type": "select", | ||
| 13 | + "field_label": "Vue.js经验水平", | ||
| 14 | + "field_options": ["入门", "进阶", "专家"] | ||
| 15 | + } | ||
| 16 | + ], | ||
| 17 | + "custom_answers": { | ||
| 18 | + "experience_level": "进阶" | ||
| 19 | + }, | ||
| 20 | + "notes": "期待参加读书会!", | ||
| 21 | + "created_at": "2024-04-15 14:30:00", | ||
| 22 | + "updated_at": "2024-04-15 14:30:00" | ||
| 23 | + } | ||
| 24 | + ] | ||
| 25 | +} |
src/data/users.json
0 → 100644
| 1 | +{ | ||
| 2 | + "users": [ | ||
| 3 | + { | ||
| 4 | + "id": "U0001", | ||
| 5 | + "name": "张三", | ||
| 6 | + "email": "zhangsan@example.com", | ||
| 7 | + "avatar": "/assets/images/avatars/default.png", | ||
| 8 | + "role": "member", | ||
| 9 | + "created_at": "2024-01-01 00:00:00", | ||
| 10 | + "updated_at": "2024-01-01 00:00:00", | ||
| 11 | + "last_login": "2024-04-17 10:00:00", | ||
| 12 | + "status": "active", | ||
| 13 | + "preferences": { | ||
| 14 | + "notification_email": true, | ||
| 15 | + "notification_web": true | ||
| 16 | + } | ||
| 17 | + } | ||
| 18 | + ] | ||
| 19 | +} |
| ... | @@ -379,17 +379,22 @@ const submitRegistration = async () => { | ... | @@ -379,17 +379,22 @@ const submitRegistration = async () => { |
| 379 | onMounted(async () => { | 379 | onMounted(async () => { |
| 380 | try { | 380 | try { |
| 381 | const activityId = route.params.id | 381 | const activityId = route.params.id |
| 382 | - const response = await store.fetchActivity(activityId) | 382 | + const foundActivity = activities.value.find(a => a.id === activityId) |
| 383 | - activity.value = response | 383 | + if (foundActivity) { |
| 384 | - loading.value = false | 384 | + activity.value = foundActivity |
| 385 | - | ||
| 386 | // Check registration status | 385 | // Check registration status |
| 387 | - const registration = await store.checkRegistration(activityId) | 386 | + const registration = registrations.value.find(r => r.activity_id === activityId) |
| 388 | hasRegistered.value = registration !== null | 387 | hasRegistered.value = registration !== null |
| 389 | registrationStatus.value = registration?.status | 388 | registrationStatus.value = registration?.status |
| 390 | 389 | ||
| 391 | - // Fetch similar activities | 390 | + // Find similar activities |
| 392 | - similarActivities.value = await store.fetchSimilarActivities(activityId) | 391 | + similarActivities.value = activities.value |
| 392 | + .filter(a => a.id !== activityId && a.category === foundActivity.category) | ||
| 393 | + .slice(0, 3) | ||
| 394 | + } else { | ||
| 395 | + error.value = '活动不存在' | ||
| 396 | + } | ||
| 397 | + loading.value = false | ||
| 393 | } catch (err) { | 398 | } catch (err) { |
| 394 | error.value = err.message | 399 | error.value = err.message |
| 395 | loading.value = false | 400 | loading.value = false | ... | ... |
| ... | @@ -258,12 +258,16 @@ | ... | @@ -258,12 +258,16 @@ |
| 258 | <script setup> | 258 | <script setup> |
| 259 | import { ref, onMounted, watch } from 'vue' | 259 | import { ref, onMounted, watch } from 'vue' |
| 260 | import { useRoute, useRouter } from 'vue-router' | 260 | import { useRoute, useRouter } from 'vue-router' |
| 261 | -import { useAppStore } from '../stores/app' | 261 | +import activitiesData from '../data/activities.json' |
| 262 | +import registrationsData from '../data/registrations.json' | ||
| 263 | +import usersData from '../data/users.json' | ||
| 262 | import Button from '../components/shared/Button.vue' | 264 | import Button from '../components/shared/Button.vue' |
| 263 | 265 | ||
| 264 | const route = useRoute() | 266 | const route = useRoute() |
| 265 | const router = useRouter() | 267 | const router = useRouter() |
| 266 | -const appStore = useAppStore() | 268 | +const activities = ref(activitiesData.activities) |
| 269 | +const registrations = ref(registrationsData.registrations) | ||
| 270 | +const currentUser = ref(usersData.users[0]) | ||
| 267 | 271 | ||
| 268 | const activityId = route.params.activityId | 272 | const activityId = route.params.activityId |
| 269 | const activity = ref(null) | 273 | const activity = ref(null) |
| ... | @@ -280,21 +284,19 @@ const isSubmitting = ref(false) | ... | @@ -280,21 +284,19 @@ const isSubmitting = ref(false) |
| 280 | // Fetch activity details and user registration | 284 | // Fetch activity details and user registration |
| 281 | const fetchData = async () => { | 285 | const fetchData = async () => { |
| 282 | try { | 286 | try { |
| 283 | - if (!appStore.currentUser) { | 287 | + if (!currentUser.value) { |
| 284 | error.value = '请先登录' | 288 | error.value = '请先登录' |
| 285 | loading.value = false | 289 | loading.value = false |
| 286 | return | 290 | return |
| 287 | } | 291 | } |
| 288 | 292 | ||
| 289 | - if (appStore.activities.length > 0) { | 293 | + const foundActivity = activities.value.find(a => a.id === activityId) |
| 290 | - const foundActivity = appStore.getActivityById(activityId) | ||
| 291 | - | ||
| 292 | if (foundActivity) { | 294 | if (foundActivity) { |
| 293 | activity.value = foundActivity | 295 | activity.value = foundActivity |
| 294 | 296 | ||
| 295 | // Find user registration for this activity | 297 | // Find user registration for this activity |
| 296 | - const registration = appStore.registrations.find( | 298 | + const registration = registrations.value.find( |
| 297 | - reg => reg.activity_id === activityId && reg.user_id === appStore.currentUser.id | 299 | + reg => reg.activity_id === activityId && reg.user_id === currentUser.value.id |
| 298 | ) | 300 | ) |
| 299 | 301 | ||
| 300 | if (registration) { | 302 | if (registration) { |
| ... | @@ -314,7 +316,7 @@ const fetchData = async () => { | ... | @@ -314,7 +316,7 @@ const fetchData = async () => { |
| 314 | } else { | 316 | } else { |
| 315 | error.value = '未找到活动信息' | 317 | error.value = '未找到活动信息' |
| 316 | } | 318 | } |
| 317 | - } | 319 | + |
| 318 | loading.value = false | 320 | loading.value = false |
| 319 | } catch (err) { | 321 | } catch (err) { |
| 320 | console.error('Failed to fetch data:', err) | 322 | console.error('Failed to fetch data:', err) | ... | ... |
| ... | @@ -86,12 +86,12 @@ | ... | @@ -86,12 +86,12 @@ |
| 86 | </template> | 86 | </template> |
| 87 | 87 | ||
| 88 | <script setup> | 88 | <script setup> |
| 89 | -import { ref, computed, watchEffect } from 'vue' | 89 | +import { ref, watchEffect } from 'vue' |
| 90 | -import { useAppStore } from '../stores/app' | 90 | +import activitiesData from '../data/activities.json' |
| 91 | import ActivityCard from '../components/shared/ActivityCard.vue' | 91 | import ActivityCard from '../components/shared/ActivityCard.vue' |
| 92 | 92 | ||
| 93 | -const store = useAppStore() | 93 | +const activities = ref(activitiesData.activities) |
| 94 | -const { activities, loading } = store | 94 | +const loading = ref(false) |
| 95 | 95 | ||
| 96 | const upcomingActivities = ref([]) | 96 | const upcomingActivities = ref([]) |
| 97 | const ongoingActivities = ref([]) | 97 | const ongoingActivities = ref([]) | ... | ... |
| ... | @@ -169,13 +169,15 @@ | ... | @@ -169,13 +169,15 @@ |
| 169 | <script setup> | 169 | <script setup> |
| 170 | import { ref, computed, onMounted } from 'vue' | 170 | import { ref, computed, onMounted } from 'vue' |
| 171 | import { useRoute, useRouter } from 'vue-router' | 171 | import { useRoute, useRouter } from 'vue-router' |
| 172 | -import { useAppStore } from '../stores/app' | 172 | +import activitiesData from '../data/activities.json' |
| 173 | +import registrationsData from '../data/registrations.json' | ||
| 173 | import Button from '../components/shared/Button.vue' | 174 | import Button from '../components/shared/Button.vue' |
| 174 | import Input from '../components/shared/Input.vue' | 175 | import Input from '../components/shared/Input.vue' |
| 175 | 176 | ||
| 176 | const route = useRoute() | 177 | const route = useRoute() |
| 177 | const router = useRouter() | 178 | const router = useRouter() |
| 178 | -const store = useAppStore() | 179 | +const activities = ref(activitiesData.activities) |
| 180 | +const registrations = ref(registrationsData.registrations) | ||
| 179 | 181 | ||
| 180 | const activityId = route.params.activityId | 182 | const activityId = route.params.activityId |
| 181 | const activity = ref(null) | 183 | const activity = ref(null) |
| ... | @@ -196,9 +198,7 @@ const formErrors = ref({}) | ... | @@ -196,9 +198,7 @@ const formErrors = ref({}) |
| 196 | // Fetch activity details | 198 | // Fetch activity details |
| 197 | onMounted(async () => { | 199 | onMounted(async () => { |
| 198 | try { | 200 | try { |
| 199 | - if (store.activities.length > 0) { | 201 | + const foundActivity = activities.value.find(a => a.id === activityId) |
| 200 | - const foundActivity = store.getActivityById(activityId) | ||
| 201 | - | ||
| 202 | if (foundActivity) { | 202 | if (foundActivity) { |
| 203 | activity.value = foundActivity | 203 | activity.value = foundActivity |
| 204 | 204 | ||
| ... | @@ -214,7 +214,7 @@ onMounted(async () => { | ... | @@ -214,7 +214,7 @@ onMounted(async () => { |
| 214 | } else { | 214 | } else { |
| 215 | error.value = '未找到活动信息' | 215 | error.value = '未找到活动信息' |
| 216 | } | 216 | } |
| 217 | - } | 217 | + |
| 218 | loading.value = false | 218 | loading.value = false |
| 219 | } catch (err) { | 219 | } catch (err) { |
| 220 | console.error('Failed to fetch activity details:', err) | 220 | console.error('Failed to fetch activity details:', err) | ... | ... |
| ... | @@ -17,7 +17,7 @@ | ... | @@ -17,7 +17,7 @@ |
| 17 | <div class="flex flex-col md:flex-row items-center"> | 17 | <div class="flex flex-col md:flex-row items-center"> |
| 18 | <div | 18 | <div |
| 19 | class="h-24 w-24 md:h-32 md:w-32 rounded-full overflow-hidden border-4 border-white mb-4 md:mb-0 md:mr-6"> | 19 | class="h-24 w-24 md:h-32 md:w-32 rounded-full overflow-hidden border-4 border-white mb-4 md:mb-0 md:mr-6"> |
| 20 | - <img :src="currentUser.avatar || '/assets/images/avatars/default_avatar.png'" | 20 | + <img :src="currentUser.avatar || '/src/assets/images/avatars/default_avatar.svg'" |
| 21 | :alt="currentUser.name" class="h-full w-full object-cover" /> | 21 | :alt="currentUser.name" class="h-full w-full object-cover" /> |
| 22 | </div> | 22 | </div> |
| 23 | <div class="text-center md:text-left"> | 23 | <div class="text-center md:text-left"> | ... | ... |
| 1 | import { defineStore } from 'pinia' | 1 | import { defineStore } from 'pinia' |
| 2 | import { ref, computed } from 'vue' | 2 | import { ref, computed } from 'vue' |
| 3 | +import usersData from '../data/users.json' | ||
| 4 | +import activitiesData from '../data/activities.json' | ||
| 5 | +import registrationsData from '../data/registrations.json' | ||
| 6 | +import messagesData from '../data/messages.json' | ||
| 3 | 7 | ||
| 4 | export const useAppStore = defineStore('app', () => { | 8 | export const useAppStore = defineStore('app', () => { |
| 5 | const currentUser = ref(null) | 9 | const currentUser = ref(null) |
| ... | @@ -10,29 +14,21 @@ export const useAppStore = defineStore('app', () => { | ... | @@ -10,29 +14,21 @@ export const useAppStore = defineStore('app', () => { |
| 10 | const userMessages = ref([]) | 14 | const userMessages = ref([]) |
| 11 | 15 | ||
| 12 | // 初始化应用数据 | 16 | // 初始化应用数据 |
| 13 | - async function fetchInitialData() { | 17 | + function fetchInitialData() { |
| 14 | try { | 18 | try { |
| 15 | loading.value = true | 19 | loading.value = true |
| 16 | 20 | ||
| 17 | // 获取用户数据 | 21 | // 获取用户数据 |
| 18 | - const usersResponse = await fetch('/data/users.json') | 22 | + currentUser.value = usersData.users[0] |
| 19 | - const usersData = await usersResponse.json() | ||
| 20 | - currentUser.value = usersData[0] | ||
| 21 | 23 | ||
| 22 | // 获取活动数据 | 24 | // 获取活动数据 |
| 23 | - const activitiesResponse = await fetch('/data/activities.json') | 25 | + activities.value = activitiesData.activities |
| 24 | - const activitiesData = await activitiesResponse.json() | ||
| 25 | - activities.value = activitiesData | ||
| 26 | 26 | ||
| 27 | // 获取报名数据 | 27 | // 获取报名数据 |
| 28 | - const registrationsResponse = await fetch('/data/registrations.json') | 28 | + registrations.value = registrationsData.registrations |
| 29 | - const registrationsData = await registrationsResponse.json() | ||
| 30 | - registrations.value = registrationsData | ||
| 31 | 29 | ||
| 32 | // 获取消息数据 | 30 | // 获取消息数据 |
| 33 | - const messagesResponse = await fetch('/data/messages.json') | 31 | + userMessages.value = messagesData.messages |
| 34 | - const messagesData = await messagesResponse.json() | ||
| 35 | - userMessages.value = messagesData | ||
| 36 | 32 | ||
| 37 | loading.value = false | 33 | loading.value = false |
| 38 | } catch (err) { | 34 | } catch (err) { | ... | ... |
src/utils/axios.js
0 → 100644
| 1 | +import axios from 'axios' | ||
| 2 | + | ||
| 3 | +// 创建axios实例 | ||
| 4 | +const instance = axios.create({ | ||
| 5 | + baseURL: '/src/data', // 基础URL,根据实际环境配置 | ||
| 6 | + timeout: 10000, // 请求超时时间 | ||
| 7 | + headers: { | ||
| 8 | + 'Content-Type': 'application/json', | ||
| 9 | + }, | ||
| 10 | +}) | ||
| 11 | + | ||
| 12 | +// 请求拦截器 | ||
| 13 | +instance.interceptors.request.use( | ||
| 14 | + (config) => { | ||
| 15 | + // 在发送请求之前做些什么 | ||
| 16 | + // 例如:添加token | ||
| 17 | + // const token = localStorage.getItem('token'); | ||
| 18 | + // if (token) { | ||
| 19 | + // config.headers.Authorization = `Bearer ${token}`; | ||
| 20 | + // } | ||
| 21 | + return config | ||
| 22 | + }, | ||
| 23 | + (error) => { | ||
| 24 | + // 对请求错误做些什么 | ||
| 25 | + console.error('Request error:', error) | ||
| 26 | + return Promise.reject(error) | ||
| 27 | + }, | ||
| 28 | +) | ||
| 29 | + | ||
| 30 | +// 响应拦截器 | ||
| 31 | +instance.interceptors.response.use( | ||
| 32 | + (response) => { | ||
| 33 | + // 对响应数据做点什么 | ||
| 34 | + return response.data | ||
| 35 | + }, | ||
| 36 | + (error) => { | ||
| 37 | + // 对响应错误做点什么 | ||
| 38 | + console.error('Response error:', error) | ||
| 39 | + if (error.response) { | ||
| 40 | + switch (error.response.status) { | ||
| 41 | + case 401: | ||
| 42 | + // 未授权处理 | ||
| 43 | + break | ||
| 44 | + case 404: | ||
| 45 | + // 资源不存在处理 | ||
| 46 | + break | ||
| 47 | + case 500: | ||
| 48 | + // 服务器错误处理 | ||
| 49 | + break | ||
| 50 | + default: | ||
| 51 | + break | ||
| 52 | + } | ||
| 53 | + } | ||
| 54 | + return Promise.reject(error) | ||
| 55 | + }, | ||
| 56 | +) | ||
| 57 | + | ||
| 58 | +export default instance |
-
Please register or login to post a comment