论坛,聊天室前后端对接

Change-Id: I90740329ab40dc050e8a791a382ab187900d673a
diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue
index f339463..de56055 100644
--- a/src/views/HomeView.vue
+++ b/src/views/HomeView.vue
@@ -1,635 +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>

-      </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 Navbar from '@/components/Navbar.vue'

-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'

-

-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