feat: 全新的Vue3管理后台(admin-spa)和路由重构

🎨 新增功能:
- 使用Vue3 + Vite构建的全新管理后台界面
- 支持Tab切换的API统计页面(统计查询/使用教程)
- 优雅的胶囊式Tab切换设计
- 同步了PR #106的会话窗口管理功能
- 完整的响应式设计和骨架屏加载状态

🔧 路由调整:
- 新版管理后台部署在 /admin-next/ 路径
- 将根路径 / 重定向到 /admin-next/api-stats
- 将 /web 页面路由重定向到新版,保留 /web/auth/* 认证路由
- 将 /apiStats 页面路由重定向到新版,保留API端点

🗑️ 清理工作:
- 删除旧版 web/admin/ 静态文件
- 删除旧版 web/apiStats/ 静态文件
- 清理相关的文件服务代码

🐛 修复问题:
- 修复重定向循环问题
- 修复环境变量配置
- 修复路由404错误
- 优化构建配置

🚀 生成方式:使用 Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
shaw
2025-07-29 12:40:51 +08:00
parent c98de2aca5
commit 414856f152
70 changed files with 18748 additions and 10314 deletions

View File

@@ -0,0 +1,166 @@
<template>
<div class="space-y-4">
<div class="flex items-center justify-between">
<h4 class="text-sm font-semibold text-gray-700">代理设置 (可选)</h4>
<label class="flex items-center cursor-pointer">
<input
type="checkbox"
v-model="proxy.enabled"
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500"
>
<span class="ml-2 text-sm text-gray-700">启用代理</span>
</label>
</div>
<div v-if="proxy.enabled" class="bg-gray-50 p-4 rounded-lg border border-gray-200 space-y-4">
<div class="flex items-start gap-3 mb-3">
<div class="w-8 h-8 bg-gray-500 rounded-lg flex items-center justify-center flex-shrink-0">
<i class="fas fa-server text-white text-sm"></i>
</div>
<div class="flex-1">
<p class="text-sm text-gray-700">
配置代理以访问受限的网络资源支持 SOCKS5 HTTP 代理
</p>
<p class="text-xs text-gray-500 mt-1">
请确保代理服务器稳定可用否则会影响账户的正常使用
</p>
</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">代理类型</label>
<select
v-model="proxy.type"
class="form-input w-full"
>
<option value="socks5">SOCKS5</option>
<option value="http">HTTP</option>
<option value="https">HTTPS</option>
</select>
</div>
<div class="grid grid-cols-2 gap-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">主机地址</label>
<input
v-model="proxy.host"
type="text"
placeholder="例如: 192.168.1.100"
class="form-input w-full"
>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">端口</label>
<input
v-model="proxy.port"
type="number"
placeholder="例如: 1080"
class="form-input w-full"
>
</div>
</div>
<div class="space-y-4">
<div class="flex items-center">
<input
type="checkbox"
v-model="showAuth"
id="proxyAuth"
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500"
>
<label for="proxyAuth" class="ml-2 text-sm text-gray-700 cursor-pointer">
需要身份验证
</label>
</div>
<div v-if="showAuth" class="grid grid-cols-2 gap-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">用户名</label>
<input
v-model="proxy.username"
type="text"
placeholder="代理用户名"
class="form-input w-full"
>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">密码</label>
<div class="relative">
<input
v-model="proxy.password"
:type="showPassword ? 'text' : 'password'"
placeholder="代理密码"
class="form-input w-full pr-10"
>
<button
type="button"
@click="showPassword = !showPassword"
class="absolute inset-y-0 right-0 pr-3 flex items-center text-gray-400 hover:text-gray-600"
>
<i :class="showPassword ? 'fas fa-eye-slash' : 'fas fa-eye'"></i>
</button>
</div>
</div>
</div>
</div>
<div class="bg-blue-50 p-3 rounded-lg border border-blue-200">
<p class="text-xs text-blue-700">
<i class="fas fa-info-circle mr-1"></i>
<strong>提示</strong>代理设置将用于所有与此账户相关的API请求请确保代理服务器支持HTTPS流量转发
</p>
</div>
</div>
</div>
</template>
<script setup>
import { ref, computed, watch } from 'vue'
const props = defineProps({
modelValue: {
type: Object,
default: () => ({
enabled: false,
type: 'socks5',
host: '',
port: '',
username: '',
password: ''
})
}
})
const emit = defineEmits(['update:modelValue'])
// 内部代理数据
const proxy = ref({ ...props.modelValue })
// UI状态
const showAuth = ref(!!(proxy.value.username || proxy.value.password))
const showPassword = ref(false)
// 监听modelValue变化
watch(() => props.modelValue, (newVal) => {
proxy.value = { ...newVal }
showAuth.value = !!(newVal.username || newVal.password)
}, { deep: true })
// 监听proxy变化更新父组件
watch(proxy, (newVal) => {
// 如果不需要认证,清空用户名密码
if (!showAuth.value) {
newVal.username = ''
newVal.password = ''
}
emit('update:modelValue', { ...newVal })
}, { deep: true })
// 监听认证开关
watch(showAuth, (newVal) => {
if (!newVal) {
proxy.value.username = ''
proxy.value.password = ''
}
})
</script>