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,68 @@
// Toast 通知管理
let toastContainer = null
let toastId = 0
export function showToast(message, type = 'info', title = '', duration = 3000) {
// 创建容器
if (!toastContainer) {
toastContainer = document.createElement('div')
toastContainer.id = 'toast-container'
toastContainer.style.cssText = 'position: fixed; top: 20px; right: 20px; z-index: 10000;'
document.body.appendChild(toastContainer)
}
// 创建 toast
const id = ++toastId
const toast = document.createElement('div')
toast.className = `toast rounded-2xl p-4 shadow-2xl backdrop-blur-sm toast-${type}`
toast.style.cssText = `
position: relative;
min-width: 320px;
max-width: 500px;
margin-bottom: 16px;
transform: translateX(100%);
transition: transform 0.3s ease-in-out;
`
const iconMap = {
success: 'fas fa-check-circle',
error: 'fas fa-times-circle',
warning: 'fas fa-exclamation-triangle',
info: 'fas fa-info-circle'
}
toast.innerHTML = `
<div class="flex items-start gap-3">
<div class="flex-shrink-0 mt-0.5">
<i class="${iconMap[type]} text-lg"></i>
</div>
<div class="flex-1 min-w-0">
${title ? `<h4 class="font-semibold text-sm mb-1">${title}</h4>` : ''}
<p class="text-sm opacity-90 leading-relaxed">${message}</p>
</div>
<button onclick="this.parentElement.parentElement.remove()"
class="flex-shrink-0 text-white/70 hover:text-white transition-colors ml-2">
<i class="fas fa-times"></i>
</button>
</div>
`
toastContainer.appendChild(toast)
// 触发动画
setTimeout(() => {
toast.style.transform = 'translateX(0)'
}, 10)
// 自动移除
if (duration > 0) {
setTimeout(() => {
toast.style.transform = 'translateX(100%)'
setTimeout(() => {
toast.remove()
}, 300)
}, duration)
}
return id
}