整合前端

Change-Id: Iff8728bd5b87e5aa6a72f02ff3ad19ce99952e6d
diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue
index de56055..3e1af4e 100644
--- a/src/views/HomeView.vue
+++ b/src/views/HomeView.vue
@@ -1,640 +1,640 @@
-<template>
-  <div class="home-page">
-    <!-- 导航栏 -->
-    <Navbar />
-
-    <!-- 主内容区 -->
-    <div class="main-content">
-      <!-- 欢迎卡片 -->
-      <div class="welcome-card">
-        <div class="welcome-header">
-          <h1>欢迎回来,{{ username }}!</h1>
-          <p>当前时间:{{ currentTime }}</p>
-        </div>
-        
-        <!-- 用户统计概览 -->
-        <div class="stats-overview" v-if="userInfo">
-          <div class="stat-item">
-            <div class="stat-icon upload">
-              <el-icon size="24"><Upload /></el-icon>
-            </div>
-            <div class="stat-content">
-              <h3>{{ formatBytes(userInfo.user.uploaded) }}</h3>
-              <p>总上传</p>
-            </div>
-          </div>
-          
-          <div class="stat-item">
-            <div class="stat-icon download">
-              <el-icon size="24"><Download /></el-icon>
-            </div>
-            <div class="stat-content">
-              <h3>{{ formatBytes(userInfo.user.downloaded) }}</h3>
-              <p>总下载</p>
-            </div>
-          </div>
-          
-          <div class="stat-item">
-            <div class="stat-icon ratio">
-              <el-icon size="24"><TrendCharts /></el-icon>
-            </div>
-            <div class="stat-content">
-              <h3>{{ calculateRatio(userInfo.user.uploaded, userInfo.user.downloaded) }}</h3>
-              <p>分享率</p>
-            </div>
-          </div>
-          
-          <div class="stat-item">
-            <div class="stat-icon points">
-              <el-icon size="24"><Star /></el-icon>
-            </div>
-            <div class="stat-content">
-              <h3>{{ userInfo.user.karma || '0' }}</h3>
-              <p>积分</p>
-            </div>
-          </div>
-        </div>
-      </div>
-
-      <!-- 功能快捷入口 -->
-      <div class="quick-actions">
-        <h2>快捷操作</h2>
-        <div class="actions-grid">
-          <div class="action-card" @click="$router.push('/upload')">
-            <el-icon size="32" color="#67c23a"><Upload /></el-icon>
-            <h3>上传种子</h3>
-            <p>分享你的资源</p>
-          </div>
-          
-          <div class="action-card" @click="$router.push('/torrents')">
-            <el-icon size="32" color="#409eff"><Search /></el-icon>
-            <h3>浏览种子</h3>
-            <p>发现新内容</p>
-          </div>
-          
-          <div class="action-card" @click="$router.push('/forum')">
-            <el-icon size="32" color="#e6a23c"><ChatDotRound /></el-icon>
-            <h3>社区论坛</h3>
-            <p>交流讨论</p>
-          </div>
-          
-          <div class="action-card" @click="$router.push('/profile')">
-            <el-icon size="32" color="#f56c6c"><User /></el-icon>
-            <h3>个人中心</h3>
-            <p>管理账户</p>
-          </div>
-          <div class="action-card" @click="$router.push('/chat')">
-            <el-icon size="32" color="#8e44ad"><ChatDotRound /></el-icon>
-            <h3>聊天室</h3>
-            <p>实时聊天互动</p>
-          </div>
-        </div>
-      </div>
-
-      <!-- API连接状态测试 -->
-      <div class="api-status-card">
-        <h2>API连接状态</h2>
-        <div class="status-items">
-          <div class="status-item">
-            <el-icon :color="loginStatusColor"><CircleCheck /></el-icon>
-            <span>登录状态:{{ loginStatusText }}</span>
-            <el-button size="small" @click="checkLoginStatus">检查状态</el-button>
-          </div>
-          
-          <div class="status-item">
-            <el-icon :color="userInfoStatusColor"><User /></el-icon>
-            <span>用户信息:{{ userInfoStatusText }}</span>
-            <el-button size="small" @click="refreshUserInfo">刷新信息</el-button>
-          </div>
-        </div>
-        
-        <!-- 用户详细信息展示 -->
-        <div class="user-details" v-if="userInfo">
-          <h3>用户详细信息</h3>
-          <div class="details-grid">
-            <div class="detail-item">
-              <label>用户ID:</label>
-              <span>{{ userInfo.user.id }}</span>
-            </div>
-            <div class="detail-item">
-              <label>用户名:</label>
-              <span>{{ userInfo.user.username }}</span>
-            </div>
-            <div class="detail-item">
-              <label>邮箱:</label>
-              <span>{{ userInfo.user.email }}</span>
-            </div>
-            <div class="detail-item">
-              <label>用户组:</label>
-              <span>{{ userInfo.user.group?.displayName || '未知' }}</span>
-            </div>
-            <div class="detail-item">
-              <label>注册时间:</label>
-              <span>{{ formatDate(userInfo.user.createdAt) }}</span>
-            </div>
-            <div class="detail-item">
-              <label>个性签名:</label>
-              <span>{{ userInfo.user.signature || '这个用户很懒,还没有个性签名' }}</span>
-            </div>
-          </div>
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-import { ref, computed, onMounted, onUnmounted } from 'vue'
-import { useRouter } from 'vue-router'
-import { useStore } from 'vuex'
-import { ElMessage, ElMessageBox } from 'element-plus'
-import {
-  ArrowDown,
-  User,
-  Setting,
-  SwitchButton,
-  Upload,
-  Download,
-  TrendCharts,
-  Star,
-  Search,
-  ChatDotRound,
-  CircleCheck
-} from '@element-plus/icons-vue'
-import Navbar from "@/components/Navbar.vue";
-
-export default {
-  name: 'HomeView',
-  components: {
-    ArrowDown,
-    User,
-    Setting,
-    SwitchButton,
-    Upload,
-    Download,
-    TrendCharts,
-    Star,
-    Search,
-    ChatDotRound,
-    CircleCheck,
-    Navbar
-  },
-  setup() {
-    const router = useRouter()
-    const store = useStore()
-    
-    const currentTime = ref('')
-    const timeInterval = ref(null)
-    
-    // 从store获取用户信息
-    const userInfo = computed(() => store.getters['auth/userInfo'])
-    const username = computed(() => store.getters['auth/username'])
-    const userAvatar = computed(() => store.getters['auth/avatar'])
-    const isAuthenticated = computed(() => store.getters['auth/isAuthenticated'])
-    
-    // API状态
-    const loginStatusColor = computed(() => isAuthenticated.value ? '#67c23a' : '#f56c6c')
-    const loginStatusText = computed(() => isAuthenticated.value ? '已登录' : '未登录')
-    
-    const userInfoStatusColor = computed(() => userInfo.value ? '#67c23a' : '#f56c6c')
-    const userInfoStatusText = computed(() => userInfo.value ? '已获取' : '未获取')
-    
-    // 更新当前时间
-    const updateCurrentTime = () => {
-      currentTime.value = new Date().toLocaleString('zh-CN')
-    }
-    
-    // 格式化字节数
-    const formatBytes = (bytes) => {
-      if (!bytes || bytes === 0) return '0 B'
-      
-      const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
-      const i = Math.floor(Math.log(bytes) / Math.log(1024))
-      const size = (bytes / Math.pow(1024, i)).toFixed(2)
-      
-      return `${size} ${sizes[i]}`
-    }
-    
-    // 计算分享率
-    const calculateRatio = (uploaded, downloaded) => {
-      if (!uploaded || !downloaded || downloaded === 0) {
-        return uploaded > 0 ? '∞' : '0.00'
-      }
-      return (uploaded / downloaded).toFixed(2)
-    }
-    
-    // 格式化日期
-    const formatDate = (timestamp) => {
-      if (!timestamp) return '未知'
-      return new Date(timestamp).toLocaleDateString('zh-CN')
-    }
-    
-    // 检查登录状态
-    const checkLoginStatus = async () => {
-      try {
-        await store.dispatch('auth/checkLoginStatus')
-        ElMessage.success('登录状态检查完成')
-      } catch (error) {
-        console.error('检查登录状态失败:', error)
-        ElMessage.error('检查登录状态失败')
-      }
-    }
-    
-    // 刷新用户信息
-    const refreshUserInfo = async () => {
-      try {
-        await store.dispatch('auth/checkLoginStatus')
-        ElMessage.success('用户信息刷新成功')
-      } catch (error) {
-        console.error('刷新用户信息失败:', error)
-        ElMessage.error('刷新用户信息失败')
-      }
-    }
-    
-    // 处理用户菜单命令
-    const handleUserCommand = async (command) => {
-      switch (command) {
-        case 'profile':
-          router.push('/profile')
-          break
-        case 'settings':
-          ElMessage.info('设置功能开发中...')
-          break
-        case 'logout':
-          try {
-            await ElMessageBox.confirm('确定要退出登录吗?', '提示', {
-              confirmButtonText: '确定',
-              cancelButtonText: '取消',
-              type: 'warning'
-            })
-            
-            await store.dispatch('auth/logout')
-            router.push('/login')
-          } catch (error) {
-            // 用户取消操作
-            if (error !== 'cancel') {
-              console.error('退出登录失败:', error)
-            }
-          }
-          break
-      }
-    }
-    
-    onMounted(() => {
-      // 开始时间更新
-      updateCurrentTime()
-      timeInterval.value = setInterval(updateCurrentTime, 1000)
-      
-      // 检查登录状态
-      if (!isAuthenticated.value) {
-        checkLoginStatus()
-      }
-    })
-    
-    onUnmounted(() => {
-      // 清理定时器
-      if (timeInterval.value) {
-        clearInterval(timeInterval.value)
-      }
-    })
-    
-    return {
-      currentTime,
-      userInfo,
-      username,
-      userAvatar,
-      isAuthenticated,
-      loginStatusColor,
-      loginStatusText,
-      userInfoStatusColor,
-      userInfoStatusText,
-      formatBytes,
-      calculateRatio,
-      formatDate,
-      checkLoginStatus,
-      refreshUserInfo,
-      handleUserCommand
-    }
-  }
-}
-</script>
-
-<style lang="scss" scoped>
-.home-page {
-  min-height: 100vh;
-  background: #f5f5f5;
-}
-
-.navbar {
-  background: #fff;
-  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
-  height: 60px;
-  display: flex;
-  align-items: center;
-  justify-content: space-between;
-  padding: 0 24px;
-  position: sticky;
-  top: 0;
-  z-index: 1000;
-}
-
-.navbar-brand {
-  font-size: 20px;
-  font-weight: 700;
-  color: #409eff;
-  text-decoration: none;
-}
-
-.navbar-nav {
-  display: flex;
-  align-items: center;
-  gap: 24px;
-}
-
-.navbar-item {
-  color: #606266;
-  text-decoration: none;
-  font-weight: 500;
-  transition: color 0.3s;
-  
-  &:hover {
-    color: #409eff;
-  }
-}
-
-.navbar-user {
-  display: flex;
-  align-items: center;
-  gap: 8px;
-  cursor: pointer;
-  padding: 8px;
-  border-radius: 6px;
-  transition: background-color 0.3s;
-  
-  &:hover {
-    background-color: #f5f7fa;
-  }
-  
-  .username {
-    font-weight: 500;
-    color: #303133;
-  }
-}
-
-.main-content {
-  max-width: 1200px;
-  margin: 0 auto;
-  padding: 24px;
-}
-
-.welcome-card {
-  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
-  color: white;
-  border-radius: 12px;
-  padding: 32px;
-  margin-bottom: 24px;
-  
-  .welcome-header {
-    text-align: center;
-    margin-bottom: 24px;
-    
-    h1 {
-      font-size: 28px;
-      margin-bottom: 8px;
-    }
-    
-    p {
-      opacity: 0.9;
-      font-size: 14px;
-    }
-  }
-  
-  .stats-overview {
-    display: grid;
-    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
-    gap: 16px;
-    
-    .stat-item {
-      background: rgba(255, 255, 255, 0.1);
-      backdrop-filter: blur(10px);
-      border-radius: 8px;
-      padding: 20px;
-      display: flex;
-      align-items: center;
-      gap: 16px;
-      
-      .stat-icon {
-        width: 48px;
-        height: 48px;
-        border-radius: 50%;
-        background: rgba(255, 255, 255, 0.2);
-        display: flex;
-        align-items: center;
-        justify-content: center;
-      }
-      
-      .stat-content {
-        h3 {
-          font-size: 20px;
-          font-weight: 600;
-          margin: 0 0 4px 0;
-        }
-        
-        p {
-          font-size: 14px;
-          opacity: 0.8;
-          margin: 0;
-        }
-      }
-    }
-  }
-}
-
-.quick-actions {
-  background: #fff;
-  border-radius: 12px;
-  padding: 24px;
-  margin-bottom: 24px;
-  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
-  
-  h2 {
-    font-size: 20px;
-    color: #303133;
-    margin: 0 0 20px 0;
-  }
-  
-  .actions-grid {
-    display: grid;
-    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
-    gap: 16px;
-    
-    .action-card {
-      background: #f8f9fa;
-      border-radius: 8px;
-      padding: 24px;
-      text-align: center;
-      cursor: pointer;
-      transition: all 0.3s;
-      border: 2px solid transparent;
-      
-      &:hover {
-        transform: translateY(-2px);
-        box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
-        border-color: #409eff;
-      }
-      
-      h3 {
-        font-size: 16px;
-        color: #303133;
-        margin: 12px 0 8px 0;
-      }
-      
-      p {
-        font-size: 14px;
-        color: #909399;
-        margin: 0;
-      }
-    }
-  }
-}
-
-.api-status-card {
-  background: #fff;
-  border-radius: 12px;
-  padding: 24px;
-  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
-  
-  h2 {
-    font-size: 20px;
-    color: #303133;
-    margin: 0 0 20px 0;
-  }
-  
-  .status-items {
-    margin-bottom: 24px;
-    
-    .status-item {
-      display: flex;
-      align-items: center;
-      gap: 12px;
-      padding: 12px 0;
-      border-bottom: 1px solid #ebeef5;
-      
-      &:last-child {
-        border-bottom: none;
-      }
-      
-      span {
-        flex: 1;
-        font-size: 14px;
-        color: #606266;
-      }
-    }
-  }
-  
-  .user-details {
-    border-top: 1px solid #ebeef5;
-    padding-top: 20px;
-    
-    h3 {
-      font-size: 16px;
-      color: #303133;
-      margin: 0 0 16px 0;
-    }
-    
-    .details-grid {
-      display: grid;
-      grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
-      gap: 12px;
-      
-      .detail-item {
-        display: flex;
-        align-items: center;
-        padding: 8px 0;
-        
-        label {
-          font-weight: 500;
-          color: #909399;
-          min-width: 80px;
-          font-size: 14px;
-        }
-        
-        span {
-          color: #606266;
-          font-size: 14px;
-        }
-      }
-    }
-  }
-}
-
-@media (max-width: 768px) {
-  .navbar {
-    padding: 0 16px;
-    
-    .navbar-nav {
-      gap: 16px;
-    }
-    
-    .navbar-user .username {
-      display: none;
-    }
-  }
-  
-  .main-content {
-    padding: 16px;
-  }
-  
-  .welcome-card {
-    padding: 24px 16px;
-    
-    .welcome-header h1 {
-      font-size: 24px;
-    }
-    
-    .stats-overview {
-      grid-template-columns: repeat(2, 1fr);
-      gap: 12px;
-      
-      .stat-item {
-        padding: 16px;
-        
-        .stat-content h3 {
-          font-size: 16px;
-        }
-      }
-    }
-  }
-  
-  .actions-grid {
-    grid-template-columns: repeat(2, 1fr);
-    gap: 12px;
-    
-    .action-card {
-      padding: 16px;
-      
-      h3 {
-        font-size: 14px;
-      }
-      
-      p {
-        font-size: 12px;
-      }
-    }
-  }
-  
-  .details-grid {
-    grid-template-columns: 1fr;
-  }
-}
-
-@media (max-width: 480px) {
-  .stats-overview {
-    grid-template-columns: 1fr;
-  }
-  
-  .actions-grid {
-    grid-template-columns: 1fr;
-  }
-}
+<template>

+  <div class="home-page">

+    <!-- 导航栏 -->

+    <Navbar />

+

+    <!-- 主内容区 -->

+    <div class="main-content">

+      <!-- 欢迎卡片 -->

+      <div class="welcome-card">

+        <div class="welcome-header">

+          <h1>欢迎回来,{{ username }}!</h1>

+          <p>当前时间:{{ currentTime }}</p>

+        </div>

+        

+        <!-- 用户统计概览 -->

+        <div class="stats-overview" v-if="userInfo">

+          <div class="stat-item">

+            <div class="stat-icon upload">

+              <el-icon size="24"><Upload /></el-icon>

+            </div>

+            <div class="stat-content">

+              <h3>{{ formatBytes(userInfo.user.uploaded) }}</h3>

+              <p>总上传</p>

+            </div>

+          </div>

+          

+          <div class="stat-item">

+            <div class="stat-icon download">

+              <el-icon size="24"><Download /></el-icon>

+            </div>

+            <div class="stat-content">

+              <h3>{{ formatBytes(userInfo.user.downloaded) }}</h3>

+              <p>总下载</p>

+            </div>

+          </div>

+          

+          <div class="stat-item">

+            <div class="stat-icon ratio">

+              <el-icon size="24"><TrendCharts /></el-icon>

+            </div>

+            <div class="stat-content">

+              <h3>{{ calculateRatio(userInfo.user.uploaded, userInfo.user.downloaded) }}</h3>

+              <p>分享率</p>

+            </div>

+          </div>

+          

+          <div class="stat-item">

+            <div class="stat-icon points">

+              <el-icon size="24"><Star /></el-icon>

+            </div>

+            <div class="stat-content">

+              <h3>{{ userInfo.user.karma || '0' }}</h3>

+              <p>积分</p>

+            </div>

+          </div>

+        </div>

+      </div>

+

+      <!-- 功能快捷入口 -->

+      <div class="quick-actions">

+        <h2>快捷操作</h2>

+        <div class="actions-grid">

+          <div class="action-card" @click="$router.push('/upload')">

+            <el-icon size="32" color="#67c23a"><Upload /></el-icon>

+            <h3>上传种子</h3>

+            <p>分享你的资源</p>

+          </div>

+          

+          <div class="action-card" @click="$router.push('/torrents')">

+            <el-icon size="32" color="#409eff"><Search /></el-icon>

+            <h3>浏览种子</h3>

+            <p>发现新内容</p>

+          </div>

+          

+          <div class="action-card" @click="$router.push('/forum')">

+            <el-icon size="32" color="#e6a23c"><ChatDotRound /></el-icon>

+            <h3>社区论坛</h3>

+            <p>交流讨论</p>

+          </div>

+          

+          <div class="action-card" @click="$router.push('/profile')">

+            <el-icon size="32" color="#f56c6c"><User /></el-icon>

+            <h3>个人中心</h3>

+            <p>管理账户</p>

+          </div>

+          <div class="action-card" @click="$router.push('/chat')">

+            <el-icon size="32" color="#8e44ad"><ChatDotRound /></el-icon>

+            <h3>聊天室</h3>

+            <p>实时聊天互动</p>

+          </div>

+        </div>

+      </div>

+

+      <!-- API连接状态测试 -->

+      <div class="api-status-card">

+        <h2>API连接状态</h2>

+        <div class="status-items">

+          <div class="status-item">

+            <el-icon :color="loginStatusColor"><CircleCheck /></el-icon>

+            <span>登录状态:{{ loginStatusText }}</span>

+            <el-button size="small" @click="checkLoginStatus">检查状态</el-button>

+          </div>

+          

+          <div class="status-item">

+            <el-icon :color="userInfoStatusColor"><User /></el-icon>

+            <span>用户信息:{{ userInfoStatusText }}</span>

+            <el-button size="small" @click="refreshUserInfo">刷新信息</el-button>

+          </div>

+        </div>

+        

+        <!-- 用户详细信息展示 -->

+        <div class="user-details" v-if="userInfo">

+          <h3>用户详细信息</h3>

+          <div class="details-grid">

+            <div class="detail-item">

+              <label>用户ID:</label>

+              <span>{{ userInfo.user.id }}</span>

+            </div>

+            <div class="detail-item">

+              <label>用户名:</label>

+              <span>{{ userInfo.user.username }}</span>

+            </div>

+            <div class="detail-item">

+              <label>邮箱:</label>

+              <span>{{ userInfo.user.email }}</span>

+            </div>

+            <div class="detail-item">

+              <label>用户组:</label>

+              <span>{{ userInfo.user.group?.displayName || '未知' }}</span>

+            </div>

+            <div class="detail-item">

+              <label>注册时间:</label>

+              <span>{{ formatDate(userInfo.user.createdAt) }}</span>

+            </div>

+            <div class="detail-item">

+              <label>个性签名:</label>

+              <span>{{ userInfo.user.signature || '这个用户很懒,还没有个性签名' }}</span>

+            </div>

+          </div>

+        </div>

+      </div>

+    </div>

+  </div>

+</template>

+

+<script>

+import { ref, computed, onMounted, onUnmounted } from 'vue'

+import { useRouter } from 'vue-router'

+import { useStore } from 'vuex'

+import { ElMessage, ElMessageBox } from 'element-plus'

+import {

+  ArrowDown,

+  User,

+  Setting,

+  SwitchButton,

+  Upload,

+  Download,

+  TrendCharts,

+  Star,

+  Search,

+  ChatDotRound,

+  CircleCheck

+} from '@element-plus/icons-vue'

+import Navbar from "@/components/Navbar.vue";

+

+export default {

+  name: 'HomeView',

+  components: {

+    ArrowDown,

+    User,

+    Setting,

+    SwitchButton,

+    Upload,

+    Download,

+    TrendCharts,

+    Star,

+    Search,

+    ChatDotRound,

+    CircleCheck,

+    Navbar

+  },

+  setup() {

+    const router = useRouter()

+    const store = useStore()

+    

+    const currentTime = ref('')

+    const timeInterval = ref(null)

+    

+    // 从store获取用户信息

+    const userInfo = computed(() => store.getters['auth/userInfo'])

+    const username = computed(() => store.getters['auth/username'])

+    const userAvatar = computed(() => store.getters['auth/avatar'])

+    const isAuthenticated = computed(() => store.getters['auth/isAuthenticated'])

+    

+    // API状态

+    const loginStatusColor = computed(() => isAuthenticated.value ? '#67c23a' : '#f56c6c')

+    const loginStatusText = computed(() => isAuthenticated.value ? '已登录' : '未登录')

+    

+    const userInfoStatusColor = computed(() => userInfo.value ? '#67c23a' : '#f56c6c')

+    const userInfoStatusText = computed(() => userInfo.value ? '已获取' : '未获取')

+    

+    // 更新当前时间

+    const updateCurrentTime = () => {

+      currentTime.value = new Date().toLocaleString('zh-CN')

+    }

+    

+    // 格式化字节数

+    const formatBytes = (bytes) => {

+      if (!bytes || bytes === 0) return '0 B'

+      

+      const sizes = ['B', 'KB', 'MB', 'GB', 'TB']

+      const i = Math.floor(Math.log(bytes) / Math.log(1024))

+      const size = (bytes / Math.pow(1024, i)).toFixed(2)

+      

+      return `${size} ${sizes[i]}`

+    }

+    

+    // 计算分享率

+    const calculateRatio = (uploaded, downloaded) => {

+      if (!uploaded || !downloaded || downloaded === 0) {

+        return uploaded > 0 ? '∞' : '0.00'

+      }

+      return (uploaded / downloaded).toFixed(2)

+    }

+    

+    // 格式化日期

+    const formatDate = (timestamp) => {

+      if (!timestamp) return '未知'

+      return new Date(timestamp).toLocaleDateString('zh-CN')

+    }

+    

+    // 检查登录状态

+    const checkLoginStatus = async () => {

+      try {

+        await store.dispatch('auth/checkLoginStatus')

+        ElMessage.success('登录状态检查完成')

+      } catch (error) {

+        console.error('检查登录状态失败:', error)

+        ElMessage.error('检查登录状态失败')

+      }

+    }

+    

+    // 刷新用户信息

+    const refreshUserInfo = async () => {

+      try {

+        await store.dispatch('auth/checkLoginStatus')

+        ElMessage.success('用户信息刷新成功')

+      } catch (error) {

+        console.error('刷新用户信息失败:', error)

+        ElMessage.error('刷新用户信息失败')

+      }

+    }

+    

+    // 处理用户菜单命令

+    const handleUserCommand = async (command) => {

+      switch (command) {

+        case 'profile':

+          router.push('/profile')

+          break

+        case 'settings':

+          ElMessage.info('设置功能开发中...')

+          break

+        case 'logout':

+          try {

+            await ElMessageBox.confirm('确定要退出登录吗?', '提示', {

+              confirmButtonText: '确定',

+              cancelButtonText: '取消',

+              type: 'warning'

+            })

+            

+            await store.dispatch('auth/logout')

+            router.push('/login')

+          } catch (error) {

+            // 用户取消操作

+            if (error !== 'cancel') {

+              console.error('退出登录失败:', error)

+            }

+          }

+          break

+      }

+    }

+    

+    onMounted(() => {

+      // 开始时间更新

+      updateCurrentTime()

+      timeInterval.value = setInterval(updateCurrentTime, 1000)

+      

+      // 检查登录状态

+      if (!isAuthenticated.value) {

+        checkLoginStatus()

+      }

+    })

+    

+    onUnmounted(() => {

+      // 清理定时器

+      if (timeInterval.value) {

+        clearInterval(timeInterval.value)

+      }

+    })

+    

+    return {

+      currentTime,

+      userInfo,

+      username,

+      userAvatar,

+      isAuthenticated,

+      loginStatusColor,

+      loginStatusText,

+      userInfoStatusColor,

+      userInfoStatusText,

+      formatBytes,

+      calculateRatio,

+      formatDate,

+      checkLoginStatus,

+      refreshUserInfo,

+      handleUserCommand

+    }

+  }

+}

+</script>

+

+<style lang="scss" scoped>

+.home-page {

+  min-height: 100vh;

+  background: #f5f5f5;

+}

+

+.navbar {

+  background: #fff;

+  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);

+  height: 60px;

+  display: flex;

+  align-items: center;

+  justify-content: space-between;

+  padding: 0 24px;

+  position: sticky;

+  top: 0;

+  z-index: 1000;

+}

+

+.navbar-brand {

+  font-size: 20px;

+  font-weight: 700;

+  color: #409eff;

+  text-decoration: none;

+}

+

+.navbar-nav {

+  display: flex;

+  align-items: center;

+  gap: 24px;

+}

+

+.navbar-item {

+  color: #606266;

+  text-decoration: none;

+  font-weight: 500;

+  transition: color 0.3s;

+  

+  &:hover {

+    color: #409eff;

+  }

+}

+

+.navbar-user {

+  display: flex;

+  align-items: center;

+  gap: 8px;

+  cursor: pointer;

+  padding: 8px;

+  border-radius: 6px;

+  transition: background-color 0.3s;

+  

+  &:hover {

+    background-color: #f5f7fa;

+  }

+  

+  .username {

+    font-weight: 500;

+    color: #303133;

+  }

+}

+

+.main-content {

+  max-width: 1200px;

+  margin: 0 auto;

+  padding: 24px;

+}

+

+.welcome-card {

+  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);

+  color: white;

+  border-radius: 12px;

+  padding: 32px;

+  margin-bottom: 24px;

+  

+  .welcome-header {

+    text-align: center;

+    margin-bottom: 24px;

+    

+    h1 {

+      font-size: 28px;

+      margin-bottom: 8px;

+    }

+    

+    p {

+      opacity: 0.9;

+      font-size: 14px;

+    }

+  }

+  

+  .stats-overview {

+    display: grid;

+    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));

+    gap: 16px;

+    

+    .stat-item {

+      background: rgba(255, 255, 255, 0.1);

+      backdrop-filter: blur(10px);

+      border-radius: 8px;

+      padding: 20px;

+      display: flex;

+      align-items: center;

+      gap: 16px;

+      

+      .stat-icon {

+        width: 48px;

+        height: 48px;

+        border-radius: 50%;

+        background: rgba(255, 255, 255, 0.2);

+        display: flex;

+        align-items: center;

+        justify-content: center;

+      }

+      

+      .stat-content {

+        h3 {

+          font-size: 20px;

+          font-weight: 600;

+          margin: 0 0 4px 0;

+        }

+        

+        p {

+          font-size: 14px;

+          opacity: 0.8;

+          margin: 0;

+        }

+      }

+    }

+  }

+}

+

+.quick-actions {

+  background: #fff;

+  border-radius: 12px;

+  padding: 24px;

+  margin-bottom: 24px;

+  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);

+  

+  h2 {

+    font-size: 20px;

+    color: #303133;

+    margin: 0 0 20px 0;

+  }

+  

+  .actions-grid {

+    display: grid;

+    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));

+    gap: 16px;

+    

+    .action-card {

+      background: #f8f9fa;

+      border-radius: 8px;

+      padding: 24px;

+      text-align: center;

+      cursor: pointer;

+      transition: all 0.3s;

+      border: 2px solid transparent;

+      

+      &:hover {

+        transform: translateY(-2px);

+        box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);

+        border-color: #409eff;

+      }

+      

+      h3 {

+        font-size: 16px;

+        color: #303133;

+        margin: 12px 0 8px 0;

+      }

+      

+      p {

+        font-size: 14px;

+        color: #909399;

+        margin: 0;

+      }

+    }

+  }

+}

+

+.api-status-card {

+  background: #fff;

+  border-radius: 12px;

+  padding: 24px;

+  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);

+  

+  h2 {

+    font-size: 20px;

+    color: #303133;

+    margin: 0 0 20px 0;

+  }

+  

+  .status-items {

+    margin-bottom: 24px;

+    

+    .status-item {

+      display: flex;

+      align-items: center;

+      gap: 12px;

+      padding: 12px 0;

+      border-bottom: 1px solid #ebeef5;

+      

+      &:last-child {

+        border-bottom: none;

+      }

+      

+      span {

+        flex: 1;

+        font-size: 14px;

+        color: #606266;

+      }

+    }

+  }

+  

+  .user-details {

+    border-top: 1px solid #ebeef5;

+    padding-top: 20px;

+    

+    h3 {

+      font-size: 16px;

+      color: #303133;

+      margin: 0 0 16px 0;

+    }

+    

+    .details-grid {

+      display: grid;

+      grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));

+      gap: 12px;

+      

+      .detail-item {

+        display: flex;

+        align-items: center;

+        padding: 8px 0;

+        

+        label {

+          font-weight: 500;

+          color: #909399;

+          min-width: 80px;

+          font-size: 14px;

+        }

+        

+        span {

+          color: #606266;

+          font-size: 14px;

+        }

+      }

+    }

+  }

+}

+

+@media (max-width: 768px) {

+  .navbar {

+    padding: 0 16px;

+    

+    .navbar-nav {

+      gap: 16px;

+    }

+    

+    .navbar-user .username {

+      display: none;

+    }

+  }

+  

+  .main-content {

+    padding: 16px;

+  }

+  

+  .welcome-card {

+    padding: 24px 16px;

+    

+    .welcome-header h1 {

+      font-size: 24px;

+    }

+    

+    .stats-overview {

+      grid-template-columns: repeat(2, 1fr);

+      gap: 12px;

+      

+      .stat-item {

+        padding: 16px;

+        

+        .stat-content h3 {

+          font-size: 16px;

+        }

+      }

+    }

+  }

+  

+  .actions-grid {

+    grid-template-columns: repeat(2, 1fr);

+    gap: 12px;

+    

+    .action-card {

+      padding: 16px;

+      

+      h3 {

+        font-size: 14px;

+      }

+      

+      p {

+        font-size: 12px;

+      }

+    }

+  }

+  

+  .details-grid {

+    grid-template-columns: 1fr;

+  }

+}

+

+@media (max-width: 480px) {

+  .stats-overview {

+    grid-template-columns: 1fr;

+  }

+  

+  .actions-grid {

+    grid-template-columns: 1fr;

+  }

+}

 </style>
\ No newline at end of file