整合前端

Change-Id: Iff8728bd5b87e5aa6a72f02ff3ad19ce99952e6d
diff --git a/src/views/ChatRoom.vue b/src/views/ChatRoom.vue
index ad63f9d..979dcc0 100644
--- a/src/views/ChatRoom.vue
+++ b/src/views/ChatRoom.vue
@@ -1,4 +1,5 @@
 <template>
+  <Navbar />
   <div class="chat-room">
     <h2>聊天室</h2>
     <div class="chat-messages" ref="messagesRef">
@@ -19,6 +20,9 @@
 import { ref, onMounted, onBeforeUnmount, nextTick } from 'vue'
 import { useStore } from 'vuex'
 import axios from 'axios'
+import Navbar from '@/components/Navbar.vue';
+
+
 
 const store = useStore()
 const wsUrl = 'ws://localhost:8081/api/ws/chat'
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
diff --git a/src/views/auth/ProfileView.vue b/src/views/auth/ProfileView.vue
index 640f893..73bdc57 100644
--- a/src/views/auth/ProfileView.vue
+++ b/src/views/auth/ProfileView.vue
@@ -1,1222 +1,1347 @@
-<template>
-  <div class="profile-page">
-    <div class="page-container">
-      <!-- 个人信息卡片 -->
-      <div class="profile-header">
-        <div class="user-avatar-section">
-          <div class="avatar-container">
-            <el-avatar :size="120" :src="userProfile.avatar">
-              {{ userProfile.username.charAt(0).toUpperCase() }}
-            </el-avatar>
-            <el-button 
-              type="primary" 
-              size="small" 
-              class="change-avatar-btn"
-              @click="showAvatarDialog = true"
-            >
-              更换头像
-            </el-button>
-          </div>
-          
-          <div class="user-basic-info">
-            <h1 class="username">{{ userBase.username }}</h1>
-            <div class="user-title">
-              <el-tag :type="getUserTitleType(userProfile.userLevel)" size="large">
-                {{ userProfile.userTitle }}
-              </el-tag>
-            </div>
-            <div class="join-info">
-              <el-icon><Calendar /></el-icon>
-              <span>加入时间:{{ userBase.joinDate }}</span>
-            </div>
-            <!-- <div class="last-login">
-              <el-icon><Clock /></el-icon>
-              <span>最后登录:{{ formatTime(userProfile.lastLogin) }}</span>
-            </div> -->
-          </div>
-        </div>
-        
-        <div class="user-stats-overview">
-          <div class="stats-grid">
-            <div class="stat-card">
-              <div class="stat-icon upload">
-                <el-icon size="32"><Upload /></el-icon>
-              </div>
-              <div class="stat-info">
-                <h3>{{ stats.uploaded || '-' }}</h3>
-                <p>上传量</p>
-              </div>
-            </div>
-            
-            <div class="stat-card">
-              <div class="stat-icon download">
-                <el-icon size="32"><Download /></el-icon>
-              </div>
-              <div class="stat-info">
-                <h3>{{ stats.downloaded || '-' }}</h3>
-                <p>下载量</p>
-              </div>
-            </div>
-            
-            <div class="stat-card">
-              <div class="stat-icon ratio" :class="getRatioClass(calcRatio)">
-                <el-icon size="32"><TrendCharts /></el-icon>
-              </div>
-              <div class="stat-info">
-                <h3>{{ calcRatio }}</h3>
-                <p>分享率</p>
-              </div>
-            </div>
-            
-            <div class="stat-card">
-              <div class="stat-icon points">
-                <el-icon size="32"><Star /></el-icon>
-              </div>
-              <div class="stat-info">
-                <h3>{{ stats.points || '-' }}</h3>
-                <p>积分</p>
-              </div>
-            </div>
-          </div>
-        </div>
-      </div>
-
-      <!-- 详细信息选项卡 -->
-      <div class="profile-content">
-        <el-tabs v-model="activeTab" type="border-card">
-          <!-- 数据统计 -->
-          <el-tab-pane label="数据统计" name="stats">
-            <div class="stats-section" v-if="stats">
-              <div class="stats-overview">
-                <div class="overview-grid">
-                  <div class="overview-card">
-                    <h3>上传统计</h3>
-                    <div class="stat-details">
-                      <div class="detail-item">
-                        <span class="label">总上传量:</span>
-                        <span class="value">{{ stats.uploaded || '-' }}</span>
-                      </div>
-                      <div class="detail-item">
-                        <span class="label">真实上传:</span>
-                        <span class="value">{{ stats.realUploaded || '-' }}</span>
-                      </div>
-                      <div class="detail-item">
-                        <span class="label">上传带宽:</span>
-                        <span class="value">{{ stats.uploadBandwidth || '-' }}</span>
-                      </div>
-                    </div>
-                  </div>
-                  
-                  <div class="overview-card">
-                    <h3>下载统计</h3>
-                    <div class="stat-details">
-                      <div class="detail-item">
-                        <span class="label">总下载量:</span>
-                        <span class="value">{{ stats.downloaded || '-' }}</span>
-                      </div>
-                      <div class="detail-item">
-                        <span class="label">真实下载:</span>
-                        <span class="value">{{ stats.realDownloaded || '-' }}</span>
-                      </div>
-                      <div class="detail-item">
-                        <span class="label">下载带宽:</span>
-                        <span class="value">{{ stats.downloadBandwidth || '-' }}</span>
-                      </div>
-                    </div>
-                  </div>
-                  
-                  <div class="overview-card">
-                    <h3>做种统计</h3>
-                    <div class="stat-details">
-                      <div class="detail-item">
-                        <span class="label">正在做种:</span>
-                        <span class="value">{{ stats.seeding || '-' }}</span>
-                      </div>
-                      <div class="detail-item">
-                        <span class="label">做种时间:</span>
-                        <span class="value">{{ stats.seedingTime || '-' }}</span>
-                      </div>
-                      <div class="detail-item">
-                        <span class="label">做种排名:</span>
-                        <span class="value">{{ stats.seedingRank || '-' }}</span>
-                      </div>
-                    </div>
-                  </div>
-
-                  <div class="overview-card">
-                    <h3>积分记录</h3>
-                    <div class="stat-details">
-                      <div class="detail-item">
-                        <span class="label">当前积分:</span>
-                        <span class="value">{{ stats.points || '-' }}</span>
-                      </div>
-                      <div class="detail-item">
-                        <span class="label">邀请名额:</span>
-                        <span class="value">{{ stats.inviteSlot || '-' }}</span>
-                      </div>
-                      <div class="detail-item">
-                        <span class="label">ISP:</span>
-                        <span class="value">{{ stats.isp || '-' }}</span>
-                      </div>
-                    </div>
-                  </div>
-                </div>
-              </div>
-              
-              <!-- 数据图表 -->
-              <div class="charts-section">
-                <div class="chart-card">
-                  <h3>上传下载趋势</h3>
-                  <div class="chart-placeholder">
-                    <el-icon size="48" color="#e4e7ed"><TrendCharts /></el-icon>
-                    <p>图表功能开发中...</p>
-                  </div>
-                </div>
-              </div>
-            </div>
-          </el-tab-pane>
-          
-          <!-- 我的种子 -->
-          <el-tab-pane label="我的种子" name="torrents">
-            <div class="torrents-section">
-              <div class="section-header">
-                <h3>我上传的种子</h3>
-                <el-button type="primary" :icon="Upload" @click="$router.push('/upload')">
-                  上传新种子
-                </el-button>
-              </div>
-              
-              <el-table :data="userTorrents" stripe>
-                <el-table-column label="种子名称" min-width="300">
-                  <template #default="{ row }">
-                    <div class="torrent-info">
-                      <el-tag :type="getCategoryType(row.category)" size="small">
-                        {{ getCategoryName(row.category) }}
-                      </el-tag>
-                      <span class="torrent-title">{{ row.title }}</span>
-                    </div>
-                  </template>
-                </el-table-column>
-                
-                <el-table-column label="大小" prop="size" width="100" />
-                <el-table-column label="做种" prop="seeders" width="80" align="center" />
-                <el-table-column label="下载" prop="leechers" width="80" align="center" />
-                <el-table-column label="完成" prop="downloads" width="80" align="center" />
-                <el-table-column label="上传时间" width="120">
-                  <template #default="{ row }">
-                    {{ formatDate(row.uploadTime) }}
-                  </template>
-                </el-table-column>
-                
-                <el-table-column label="操作" width="120" align="center">
-                  <template #default="{ row }">
-                    <el-button 
-                      type="primary" 
-                      size="small" 
-                      @click="$router.push(`/torrent/${row.id}`)"
-                    >
-                      查看
-                    </el-button>
-                  </template>
-                </el-table-column>
-              </el-table>
-              
-              <div class="pagination-wrapper">
-                <el-pagination
-                  :current-page="torrentsPage"
-                  :page-size="10"
-                  :total="userTorrents.length"
-                  layout="prev, pager, next"
-                  small
-                  @current-change="(page) => torrentsPage = page"
-                />
-              </div>
-            </div>
-          </el-tab-pane>
-          
-          <!-- 活动记录 -->
-          <el-tab-pane label="活动记录" name="activity">
-            <div class="activity-section">
-              <div class="activity-filters">
-                <el-select v-model="activityFilter" placeholder="活动类型">
-                  <el-option label="全部活动" value="" />
-                  <el-option label="上传种子" value="upload" />
-                  <el-option label="下载种子" value="download" />
-                  <el-option label="论坛发帖" value="post" />
-                  <el-option label="积分变动" value="points" />
-                </el-select>
-              </div>
-              
-              <div class="activity-timeline">
-                <el-timeline>
-                  <el-timeline-item
-                    v-for="activity in filteredActivities"
-                    :key="activity.id"
-                    :timestamp="formatTime(activity.time)"
-                    :type="getActivityType(activity.type)"
-                  >
-                    <div class="activity-content">
-                      <div class="activity-header">
-                        <el-icon>
-                          <component :is="getActivityIcon(activity.type)" />
-                        </el-icon>
-                        <span class="activity-title">{{ activity.title }}</span>
-                      </div>
-                      <div class="activity-description">{{ activity.description }}</div>
-                    </div>
-                  </el-timeline-item>
-                </el-timeline>
-              </div>
-            </div>
-          </el-tab-pane>
-        </el-tabs>
-      </div>
-    </div>
-
-    <!-- 更换头像对话框 -->
-    <el-dialog v-model="showAvatarDialog" title="更换头像" width="400px">
-      <div class="avatar-upload">
-        <el-upload
-          ref="avatarUploadRef"
-          :auto-upload="false"
-          :limit="1"
-          accept="image/*"
-          :on-change="handleAvatarChange"
-          list-type="picture-card"
-          class="avatar-uploader"
-        >
-          <el-icon><Plus /></el-icon>
-        </el-upload>
-        <div class="upload-tips">
-          <p>支持 JPG、PNG 格式</p>
-          <p>建议尺寸 200x200 像素</p>
-          <p>文件大小不超过 2MB</p>
-        </div>
-      </div>
-      
-      <template #footer>
-        <el-button @click="showAvatarDialog = false">取消</el-button>
-        <el-button type="primary" @click="uploadAvatar" :loading="uploadingAvatar">
-          上传头像
-        </el-button>
-      </template>
-    </el-dialog>
-  </div>
-</template>
-
-<script>
-import { ref, reactive, computed, onMounted, nextTick } from 'vue'
-import { useRouter } from 'vue-router'
-import { ElMessage } from 'element-plus'
-import {
-  Calendar,
-  Clock,
-  Upload,
-  Download,
-  TrendCharts,
-  Star,
-  QuestionFilled,
-  Plus,
-  ChatDotRound,
-  Flag,
-  Coin
-} from '@element-plus/icons-vue'
-import { userApi } from '@/api/user'
-
-export default {
-  name: 'ProfileView',
-  setup() {
-    const router = useRouter()
-    const profileFormRef = ref(null)
-    const passwordFormRef = ref(null)
-    const avatarUploadRef = ref(null)
-    const interestInputRef = ref(null)
-    
-    const activeTab = ref('info')
-    const showAvatarDialog = ref(false)
-    const saving = ref(false)
-    const changingPassword = ref(false)
-    const uploadingAvatar = ref(false)
-    const interestInputVisible = ref(false)
-    const interestInputValue = ref('')
-    const activityFilter = ref('')
-    const torrentsPage = ref(1)
-    
-    const userProfile = ref({
-      username: 'MovieExpert',
-      email: 'movieexpert@example.com',
-      realName: '',
-      avatar: '',
-      userLevel: 5,
-      userTitle: '资深会员',
-      joinDate: '2023-01-15T10:00:00',
-      lastLogin: '2025-06-03T14:30:00',
-      location: ['北京市', '朝阳区'],
-      signature: '热爱电影,分享快乐!',
-      website: 'https://movieblog.com',
-      interests: ['电影', '音乐', '科技', '摄影'],
-      emailPublic: false,
-      statsPublic: true,
-      activityPublic: true,
-      stats: {
-        uploaded: '256.8 GB',
-        downloaded: '89.6 GB',
-        ratio: '2.87',
-        points: '15,680'
-      },
-      detailedStats: {
-        totalUploaded: '256.8 GB',
-        uploadedTorrents: 45,
-        avgUploadSize: '5.7 GB',
-        totalDownloaded: '89.6 GB',
-        downloadedTorrents: 123,
-        completedTorrents: 118,
-        seeding: 32,
-        seedingTime: '1,245 小时',
-        seedingRank: 86,
-        totalEarnedPoints: '28,940',
-        totalSpentPoints: '13,260'
-      }
-    })
-    
-    const editProfile = reactive({
-      username: '',
-      email: '',
-      customTitle: '',
-      realName: '',
-      location: [],
-      signature: '',
-      website: '',
-      interests: [],
-      emailPublic: false,
-      statsPublic: true,
-      activityPublic: true
-    })
-    
-    const passwordForm = reactive({
-      currentPassword: '',
-      newPassword: '',
-      confirmPassword: ''
-    })
-    
-    const profileRules = {
-      email: [
-        { required: true, message: '请输入邮箱地址', trigger: 'blur' },
-        { type: 'email', message: '请输入正确的邮箱格式', trigger: 'blur' }
-      ]
-    }
-    
-    const passwordRules = {
-      currentPassword: [
-        { required: true, message: '请输入当前密码', trigger: 'blur' }
-      ],
-      newPassword: [
-        { required: true, message: '请输入新密码', trigger: 'blur' },
-        { min: 6, message: '密码长度至少6个字符', trigger: 'blur' }
-      ],
-      confirmPassword: [
-        { required: true, message: '请确认新密码', trigger: 'blur' },
-        {
-          validator: (rule, value, callback) => {
-            if (value !== passwordForm.newPassword) {
-              callback(new Error('两次输入的密码不一致'))
-            } else {
-              callback()
-            }
-          },
-          trigger: 'blur'
-        }
-      ]
-    }
-    
-    const locationOptions = [
-      {
-        value: '北京市',
-        label: '北京市',
-        children: [
-          { value: '朝阳区', label: '朝阳区' },
-          { value: '海淀区', label: '海淀区' },
-          { value: '丰台区', label: '丰台区' }
-        ]
-      },
-      {
-        value: '上海市',
-        label: '上海市',
-        children: [
-          { value: '浦东新区', label: '浦东新区' },
-          { value: '黄浦区', label: '黄浦区' },
-          { value: '静安区', label: '静安区' }
-        ]
-      }
-    ]
-    
-    const userTorrents = ref([
-      {
-        id: 1,
-        title: '[4K蓝光原盘] 阿凡达:水之道',
-        category: 'movie',
-        size: '85.6 GB',
-        seeders: 45,
-        leechers: 12,
-        downloads: 234,
-        uploadTime: '2025-05-15T10:00:00'
-      },
-      {
-        id: 2,
-        title: '[FLAC] 古典音乐合集',
-        category: 'music',
-        size: '2.3 GB',
-        seeders: 23,
-        leechers: 5,
-        downloads: 89,
-        uploadTime: '2025-04-20T15:30:00'
-      }
-    ])
-    
-    const activities = ref([
-      {
-        id: 1,
-        type: 'upload',
-        title: '上传种子',
-        description: '上传了《阿凡达:水之道》4K蓝光原盘',
-        time: '2025-06-03T10:30:00'
-      },
-      {
-        id: 2,
-        type: 'download',
-        title: '下载种子',
-        description: '下载了《星际穿越》IMAX版本',
-        time: '2025-06-02T14:20:00'
-      },
-      {
-        id: 3,
-        type: 'post',
-        title: '发布主题',
-        description: '在电影讨论区发布了新主题',
-        time: '2025-06-01T16:45:00'
-      },
-      {
-        id: 4,
-        type: 'points',
-        title: '积分变动',
-        description: '做种奖励获得 +50 积分',
-        time: '2025-05-31T09:15:00'
-      }
-    ])
-    
-    const loginHistory = ref([
-      {
-        time: '2025-06-03T14:30:00',
-        ip: '192.168.1.100',
-        device: 'Windows 11 / Chrome 120',
-        success: true
-      },
-      {
-        time: '2025-06-02T09:15:00',
-        ip: '192.168.1.100',
-        device: 'Windows 11 / Chrome 120',
-        success: true
-      },
-      {
-        time: '2025-06-01T22:30:00',
-        ip: '192.168.1.100',
-        device: 'Android / Chrome Mobile',
-        success: true
-      }
-    ])
-    
-    const filteredActivities = computed(() => {
-      if (!activityFilter.value) return activities.value
-      return activities.value.filter(activity => activity.type === activityFilter.value)
-    })
-    
-    const stats = reactive({
-      uploaded: '-',
-      realUploaded: '-',
-      uploadBandwidth: '-',
-      downloaded: '-',
-      realDownloaded: '-',
-      downloadBandwidth: '-',
-      seeding: '-',
-      seedingTime: '-',
-      seedingRank: '-',
-      points: '-',
-      inviteSlot: '-',
-      isp: '-'
-    })
-    
-    const calcRatio = computed(() => {
-      if (!stats.uploaded || !stats.downloaded || stats.downloaded === '-' || stats.uploaded === '-') return '-'
-      const parseGB = (str) => {
-        if (typeof str !== 'string') return 0
-        if (str.endsWith('TB')) return parseFloat(str) * 1024
-        if (str.endsWith('GB')) return parseFloat(str)
-        if (str.endsWith('MB')) return parseFloat(str) / 1024
-        if (str.endsWith('KB')) return parseFloat(str) / 1024 / 1024
-        if (str.endsWith('B')) return parseFloat(str) / 1024 / 1024 / 1024
-        return parseFloat(str)
-      }
-      const up = parseGB(stats.uploaded)
-      const down = parseGB(stats.downloaded)
-      if (!down) return up > 0 ? '∞' : '0.00'
-      return (up / down).toFixed(2)
-    })
-    
-    const userBase = reactive({
-      username: '-',
-      joinDate: '-',
-    })
-    
-    onMounted(async () => {
-      try {
-        const res = await userApi.getCurrentUser()
-        if (res.user && res.user.user) {
-          const u = res.user.user
-          stats.uploaded = formatBytes(u.uploaded)
-          stats.realUploaded = formatBytes(u.realUploaded)
-          stats.uploadBandwidth = u.uploadBandwidth || '-'
-          stats.downloaded = formatBytes(u.downloaded)
-          stats.realDownloaded = formatBytes(u.realDownloaded)
-          stats.downloadBandwidth = u.downloadBandwidth || '-'
-          stats.seeding = u.seeding || '-'
-          stats.seedingTime = formatSeedingTime(u.seedingTime)
-          stats.seedingRank = u.seedingRank || '-'
-          stats.points = u.karma || '-'
-          stats.inviteSlot = u.inviteSlot || '-'
-          stats.isp = u.isp || '-'
-          userBase.username = u.username || '-'
-          userBase.joinDate = u.createdAt ? formatDate(u.createdAt) : '-'
-        }
-      } catch (e) {
-        ElMessage.error('获取数据失败')
-      }
-    })
-    
-    const getUserTitleByLevel = (level) => {
-      if (level == null) return '新手'
-      if (level >= 8) return '管理员'
-      if (level >= 6) return '资深会员'
-      if (level >= 4) return '正式会员'
-      if (level >= 2) return '初级会员'
-      return '新手'
-    }
-    
-    const formatBytes = (bytes) => {
-      if (!bytes || isNaN(bytes)) return '0 B'
-      const k = 1024
-      const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']
-      const i = Math.floor(Math.log(bytes) / Math.log(k))
-      return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
-    }
-    
-    const formatSeedingTime = (seconds) => {
-      if (!seconds || isNaN(seconds)) return '0 小时'
-      const hours = Math.floor(seconds / 3600)
-      const days = Math.floor(hours / 24)
-      if (days > 0) {
-        return `${days} 天 ${hours % 24} 小时`
-      } else {
-        return `${hours} 小时`
-      }
-    }
-    
-    const formatDate = (dateString) => {
-      const date = new Date(dateString)
-      return date.toLocaleDateString('zh-CN')
-    }
-    
-    const formatTime = (timeString) => {
-      const date = new Date(timeString)
-      const now = new Date()
-      const diff = now - date
-      const hours = Math.floor(diff / (1000 * 60 * 60))
-      
-      if (hours < 1) return '刚刚'
-      if (hours < 24) return `${hours}小时前`
-      const days = Math.floor(hours / 24)
-      if (days < 7) return `${days}天前`
-      
-      return date.toLocaleDateString('zh-CN')
-    }
-    
-    const formatDateTime = (dateString) => {
-      const date = new Date(dateString)
-      return date.toLocaleString('zh-CN')
-    }
-    
-    const getUserTitleType = (level) => {
-      if (level >= 8) return 'danger'  // 管理员
-      if (level >= 6) return 'warning' // 资深会员
-      if (level >= 4) return 'success' // 正式会员
-      if (level >= 2) return 'info'    // 初级会员
-      return 'default' // 新手
-    }
-    
-    const getRatioClass = (ratio) => {
-      const r = parseFloat(ratio)
-      if (r >= 2) return 'excellent'
-      if (r >= 1) return 'good'
-      return 'warning'
-    }
-    
-    const getCategoryType = (category) => {
-      const types = {
-        'movie': 'primary',
-        'tv': 'info',
-        'music': 'success',
-        'software': 'warning',
-        'game': 'danger'
-      }
-      return types[category] || 'default'
-    }
-    
-    const getCategoryName = (category) => {
-      const names = {
-        'movie': '电影',
-        'tv': '电视剧',
-        'music': '音乐',
-        'software': '软件',
-        'game': '游戏'
-      }
-      return names[category] || category
-    }
-
-    const getLanguageName = (language) => {
-      const languages = {
-        'zh-CN': '简体中文',
-        'zh-TW': '繁体中文',
-        'en-US': 'English',
-        'ja-JP': '日本語',
-        'ko-KR': '한국어'
-      }
-      return languages[language] || language
-    }
-    
-    const getActivityType = (type) => {
-      const types = {
-        'upload': 'success',
-        'download': 'primary',
-        'post': 'warning',
-        'points': 'info'
-      }
-      return types[type] || 'primary'
-    }
-    
-    const getActivityIcon = (type) => {
-      const icons = {
-        'upload': 'Upload',
-        'download': 'Download',
-        'post': 'ChatDotRound',
-        'points': 'Coin'
-      }
-      return icons[type] || 'Star'
-    }
-    
-    const showInterestInput = () => {
-      interestInputVisible.value = true
-      nextTick(() => {
-        interestInputRef.value?.focus()
-      })
-    }
-    
-    const addInterest = () => {
-      const interest = interestInputValue.value.trim()
-      if (interest && !editProfile.interests.includes(interest)) {
-        editProfile.interests.push(interest)
-      }
-      interestInputVisible.value = false
-      interestInputValue.value = ''
-    }
-    
-    const removeInterest = (interest) => {
-      const index = editProfile.interests.indexOf(interest)
-      if (index > -1) {
-        editProfile.interests.splice(index, 1)
-      }
-    }
-    
-    const saveProfile = async () => {
-      try {
-        const payload = {
-          username: editProfile.username,
-          email: editProfile.email
-        }
-        await userApi.updateProfile(payload)
-        ElMessage.success('保存成功')
-      } catch (error) {
-        ElMessage.error('保存失败')
-      }
-    }
-    
-    const resetProfile = () => {
-      loadUserProfile()
-      ElMessage.info('已重置为原始数据')
-    }
-    
-    const changePassword = async () => {
-      try {
-        await passwordFormRef.value?.validate()
-        
-        changingPassword.value = true
-        
-        // 模拟密码修改过程
-        await new Promise(resolve => setTimeout(resolve, 1500))
-        
-        // 重置表单
-        passwordFormRef.value?.resetFields()
-        Object.assign(passwordForm, {
-          currentPassword: '',
-          newPassword: '',
-          confirmPassword: ''
-        })
-        
-        ElMessage.success('密码修改成功')
-        
-      } catch (error) {
-        console.error('表单验证失败:', error)
-      } finally {
-        changingPassword.value = false
-      }
-    }
-    
-    const handleAvatarChange = (file) => {
-      const isImage = file.raw.type.startsWith('image/')
-      const isLt2M = file.raw.size / 1024 / 1024 < 2
-      
-      if (!isImage) {
-        ElMessage.error('只能上传图片文件!')
-        return false
-      }
-      if (!isLt2M) {
-        ElMessage.error('图片大小不能超过 2MB!')
-        return false
-      }
-      
-      return true
-    }
-    
-    const uploadAvatar = async () => {
-      const files = avatarUploadRef.value?.uploadFiles
-      if (!files || files.length === 0) {
-        ElMessage.warning('请选择头像文件')
-        return
-      }
-      
-      uploadingAvatar.value = true
-      try {
-        // 模拟上传过程
-        await new Promise(resolve => setTimeout(resolve, 2000))
-        
-        // 更新头像URL
-        userProfile.value.avatar = URL.createObjectURL(files[0].raw)
-        
-        ElMessage.success('头像上传成功')
-        showAvatarDialog.value = false
-        avatarUploadRef.value?.clearFiles()
-        
-      } catch (error) {
-        ElMessage.error('头像上传失败')
-      } finally {
-        uploadingAvatar.value = false
-      }
-    }
-    
-    return {
-      activeTab,
-      showAvatarDialog,
-      saving,
-      changingPassword,
-      uploadingAvatar,
-      interestInputVisible,
-      interestInputValue,
-      activityFilter,
-      torrentsPage,
-      userProfile,
-      editProfile,
-      passwordForm,
-      profileRules,
-      passwordRules,
-      locationOptions,
-      userTorrents,
-      filteredActivities,
-      loginHistory,
-      profileFormRef,
-      passwordFormRef,
-      avatarUploadRef,
-      interestInputRef,
-      formatDate,
-      formatTime,
-      formatDateTime,
-      getUserTitleType,
-      getRatioClass,
-      getCategoryType,
-      getCategoryName,
-      getActivityType,
-      getActivityIcon,
-      showInterestInput,
-      addInterest,
-      removeInterest,
-      saveProfile,
-      resetProfile,
-      changePassword,
-      handleAvatarChange,
-      uploadAvatar,
-      Calendar,
-      Clock,
-      Upload,
-      Download,
-      TrendCharts,
-      Star,
-      QuestionFilled,
-      Plus,
-      ChatDotRound,
-      Flag,
-      Coin,
-      stats,
-      calcRatio,
-      userBase
-    }
-  }
-}
-</script>
-
-<style lang="scss" scoped>
-.profile-page {
-  max-width: 1200px;
-  margin: 0 auto;
-  padding: 24px;
-  background: #f5f5f5;
-  min-height: 100vh;
-}
-
-.profile-header {
-  background: #fff;
-  border-radius: 12px;
-  padding: 32px;
-  margin-bottom: 24px;
-  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
-  
-  display: grid;
-  grid-template-columns: 1fr 1fr;
-  gap: 32px;
-  
-  .user-avatar-section {
-    display: flex;
-    gap: 24px;
-    
-    .avatar-container {
-      text-align: center;
-      
-      .change-avatar-btn {
-        margin-top: 12px;
-      }
-    }
-    
-    .user-basic-info {
-      flex: 1;
-      
-      .username {
-        font-size: 28px;
-        font-weight: 600;
-        color: #2c3e50;
-        margin: 0 0 12px 0;
-      }
-      
-      .user-title {
-        margin-bottom: 16px;
-      }
-      
-      .join-info, .last-login {
-        display: flex;
-        align-items: center;
-        gap: 8px;
-        font-size: 14px;
-        color: #7f8c8d;
-        margin-bottom: 8px;
-      }
-    }
-  }
-  
-  .user-stats-overview {
-    .stats-grid {
-      display: grid;
-      grid-template-columns: repeat(2, 1fr);
-      gap: 16px;
-      
-      .stat-card {
-        background: #f8f9fa;
-        border-radius: 8px;
-        padding: 20px;
-        display: flex;
-        align-items: center;
-        gap: 16px;
-        
-        .stat-icon {
-          width: 48px;
-          height: 48px;
-          border-radius: 50%;
-          display: flex;
-          align-items: center;
-          justify-content: center;
-          
-          &.upload { background: rgba(103, 194, 58, 0.1); color: #67c23a; }
-          &.download { background: rgba(64, 158, 255, 0.1); color: #409eff; }
-          &.ratio {
-            &.excellent { background: rgba(103, 194, 58, 0.1); color: #67c23a; }
-            &.good { background: rgba(230, 162, 60, 0.1); color: #e6a23c; }
-            &.warning { background: rgba(245, 108, 108, 0.1); color: #f56c6c; }
-          }
-          &.points { background: rgba(245, 108, 108, 0.1); color: #f56c6c; }
-        }
-        
-        .stat-info {
-          h3 {
-            font-size: 20px;
-            font-weight: 600;
-            color: #2c3e50;
-            margin: 0 0 4px 0;
-          }
-          
-          p {
-            font-size: 14px;
-            color: #7f8c8d;
-            margin: 0;
-          }
-        }
-      }
-    }
-  }
-}
-
-.profile-content {
-  background: #fff;
-  border-radius: 12px;
-  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
-  
-  :deep(.el-tabs__content) {
-    padding: 24px;
-  }
-}
-
-.info-section {
-  .form-section {
-    margin-bottom: 32px;
-    
-    h3 {
-      font-size: 18px;
-      font-weight: 600;
-      color: #2c3e50;
-      margin: 0 0 20px 0;
-      padding-bottom: 8px;
-      border-bottom: 2px solid #f0f0f0;
-    }
-  }
-  
-  .interests-input {
-    display: flex;
-    flex-wrap: wrap;
-    gap: 8px;
-    align-items: center;
-    
-    .interest-tag {
-      margin: 0;
-    }
-  }
-  
-  .setting-tip {
-    margin-left: 12px;
-    font-size: 12px;
-    color: #909399;
-  }
-  
-  .form-actions {
-    text-align: center;
-    margin-top: 32px;
-    
-    .el-button {
-      margin: 0 8px;
-      min-width: 100px;
-    }
-  }
-}
-
-.stats-section {
-  .stats-overview {
-    margin-bottom: 32px;
-    
-    .overview-grid {
-      display: grid;
-      grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
-      gap: 20px;
-      
-      .overview-card {
-        background: #f8f9fa;
-        border-radius: 8px;
-        padding: 24px;
-        
-        h3 {
-          font-size: 16px;
-          font-weight: 600;
-          color: #2c3e50;
-          margin: 0 0 16px 0;
-        }
-        
-        .stat-details {
-          .detail-item {
-            display: flex;
-            justify-content: space-between;
-            align-items: center;
-            margin-bottom: 12px;
-            
-            .label {
-              font-size: 14px;
-              color: #7f8c8d;
-            }
-            
-            .value {
-              font-size: 14px;
-              font-weight: 600;
-              color: #2c3e50;
-            }
-          }
-        }
-      }
-    }
-  }
-  
-  .charts-section {
-    .chart-card {
-      background: #f8f9fa;
-      border-radius: 8px;
-      padding: 24px;
-      
-      h3 {
-        font-size: 16px;
-        font-weight: 600;
-        color: #2c3e50;
-        margin: 0 0 20px 0;
-      }
-      
-      .chart-placeholder {
-        text-align: center;
-        padding: 60px 0;
-        color: #909399;
-        
-        p {
-          margin: 12px 0 0 0;
-        }
-      }
-    }
-  }
-}
-
-.torrents-section {
-  .section-header {
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-    margin-bottom: 20px;
-    
-    h3 {
-      font-size: 18px;
-      font-weight: 600;
-      color: #2c3e50;
-      margin: 0;
-    }
-  }
-  
-  .torrent-info {
-    display: flex;
-    align-items: center;
-    gap: 12px;
-    
-    .torrent-title {
-      font-weight: 500;
-    }
-  }
-  
-  .pagination-wrapper {
-    margin-top: 16px;
-    text-align: center;
-  }
-}
-
-.activity-section {
-  .activity-filters {
-    margin-bottom: 24px;
-    
-    .el-select {
-      width: 150px;
-    }
-  }
-  
-  .activity-timeline {
-    .activity-content {
-      .activity-header {
-        display: flex;
-        align-items: center;
-        gap: 8px;
-        margin-bottom: 8px;
-        
-        .activity-title {
-          font-weight: 600;
-          color: #2c3e50;
-        }
-      }
-      
-      .activity-description {
-        font-size: 14px;
-        color: #7f8c8d;
-        line-height: 1.5;
-      }
-    }
-  }
-}
-
-.avatar-upload {
-  text-align: center;
-  
-  .avatar-uploader {
-    margin-bottom: 16px;
-  }
-  
-  .upload-tips {
-    font-size: 12px;
-    color: #909399;
-    
-    p {
-      margin: 4px 0;
-    }
-  }
-}
-
-@media (max-width: 768px) {
-  .profile-page {
-    padding: 16px;
-  }
-  
-  .profile-header {
-    grid-template-columns: 1fr;
-    gap: 24px;
-    
-    .user-avatar-section {
-      flex-direction: column;
-      text-align: center;
-    }
-    
-    .user-stats-overview .stats-grid {
-      grid-template-columns: 1fr;
-    }
-  }
-  
-  .stats-overview .overview-grid {
-    grid-template-columns: 1fr;
-  }
-  
-  .torrents-section .section-header {
-    flex-direction: column;
-    gap: 16px;
-    align-items: flex-start;
-  }
-}
+<template>

+  <Navbar />

+  <div class="profile-page">

+    <div class="page-container">

+      <!-- 个人信息卡片 -->

+      <div class="profile-header">

+        <div class="user-avatar-section">

+          <div class="avatar-container">

+            <el-avatar :size="120" :src="userProfile.avatar">

+              {{ userProfile.username.charAt(0).toUpperCase() }}

+            </el-avatar>

+            <el-button 

+              type="primary" 

+              size="small" 

+              class="change-avatar-btn"

+              @click="showAvatarDialog = true"

+            >

+              更换头像

+            </el-button>

+          </div>

+          

+          <div class="user-basic-info">

+            <h1 class="username">{{ userProfile.username }}</h1>

+            <div class="user-title">

+              <el-tag :type="getUserTitleType(userProfile.userLevel)" size="large">

+                {{ userProfile.userTitle }}

+              </el-tag>

+            </div>

+            <div class="join-info">

+              <el-icon><Calendar /></el-icon>

+              <span>加入时间:{{ formatDate(userProfile.joinDate) }}</span>

+            </div>

+            <div class="last-login">

+              <el-icon><Clock /></el-icon>

+              <span>最后登录:{{ formatTime(userProfile.lastLogin) }}</span>

+            </div>

+          </div>

+        </div>

+        

+        <div class="user-stats-overview">

+          <div class="stats-grid">

+            <div class="stat-card">

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

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

+              </div>

+              <div class="stat-info">

+                <h3>{{ userProfile.stats.uploaded }}</h3>

+                <p>上传量</p>

+              </div>

+            </div>

+            

+            <div class="stat-card">

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

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

+              </div>

+              <div class="stat-info">

+                <h3>{{ userProfile.stats.downloaded }}</h3>

+                <p>下载量</p>

+              </div>

+            </div>

+            

+            <div class="stat-card">

+              <div class="stat-icon ratio" :class="getRatioClass(userProfile.stats.ratio)">

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

+              </div>

+              <div class="stat-info">

+                <h3>{{ userProfile.stats.ratio }}</h3>

+                <p>分享率</p>

+              </div>

+            </div>

+            

+            <div class="stat-card">

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

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

+              </div>

+              <div class="stat-info">

+                <h3>{{ userProfile.stats.points }}</h3>

+                <p>积分</p>

+              </div>

+            </div>

+          </div>

+        </div>

+      </div>

+

+      <!-- 详细信息选项卡 -->

+      <div class="profile-content">

+        <el-tabs v-model="activeTab" type="border-card">

+          <!-- 个人信息 -->

+          <el-tab-pane label="个人信息" name="info">

+            <div class="info-section">

+              <el-form

+                ref="profileFormRef"

+                :model="editProfile"

+                :rules="profileRules"

+                label-width="120px"

+                size="large"

+              >

+                <div class="form-section">

+                  <h3>基本信息</h3>

+                  <el-form-item label="用户名">

+                    <el-input v-model="editProfile.username" disabled>

+                      <template #suffix>

+                        <el-tooltip content="用户名不可修改">

+                          <el-icon><QuestionFilled /></el-icon>

+                        </el-tooltip>

+                      </template>

+                    </el-input>

+                  </el-form-item>

+                  

+                  <el-form-item label="邮箱地址" prop="email">

+                    <el-input v-model="editProfile.email" type="email" />

+                  </el-form-item>

+                  

+                  <el-form-item label="真实姓名" prop="realName">

+                    <el-input v-model="editProfile.realName" placeholder="可选填写" />

+                  </el-form-item>

+                  

+                  <el-form-item label="所在地区">

+                    <el-cascader

+                      v-model="editProfile.location"

+                      :options="locationOptions"

+                      placeholder="请选择地区"

+                      clearable

+                    />

+                  </el-form-item>

+                </div>

+                

+                <div class="form-section">

+                  <h3>个人介绍</h3>

+                  <el-form-item label="个人签名">

+                    <el-input

+                      v-model="editProfile.signature"

+                      type="textarea"

+                      :rows="3"

+                      maxlength="200"

+                      show-word-limit

+                      placeholder="介绍一下自己吧..."

+                    />

+                  </el-form-item>

+                  

+                  <el-form-item label="个人网站">

+                    <el-input v-model="editProfile.website" placeholder="https://" />

+                  </el-form-item>

+                  

+                  <el-form-item label="兴趣爱好">

+                    <div class="interests-input">

+                      <el-tag

+                        v-for="interest in editProfile.interests"

+                        :key="interest"

+                        closable

+                        @close="removeInterest(interest)"

+                        class="interest-tag"

+                      >

+                        {{ interest }}

+                      </el-tag>

+                      <el-input

+                        v-if="interestInputVisible"

+                        ref="interestInputRef"

+                        v-model="interestInputValue"

+                        size="small"

+                        @keyup.enter="addInterest"

+                        @blur="addInterest"

+                        style="width: 120px;"

+                      />

+                      <el-button

+                        v-else

+                        size="small"

+                        @click="showInterestInput"

+                      >

+                        + 添加兴趣

+                      </el-button>

+                    </div>

+                  </el-form-item>

+                </div>

+                

+                <div class="form-section">

+                  <h3>隐私设置</h3>

+                  <el-form-item label="邮箱公开">

+                    <el-switch v-model="editProfile.emailPublic" />

+                    <span class="setting-tip">是否在个人资料中显示邮箱</span>

+                  </el-form-item>

+                  

+                  <el-form-item label="统计公开">

+                    <el-switch v-model="editProfile.statsPublic" />

+                    <span class="setting-tip">是否公开上传下载统计</span>

+                  </el-form-item>

+                  

+                  <el-form-item label="活动记录">

+                    <el-switch v-model="editProfile.activityPublic" />

+                    <span class="setting-tip">是否公开活动记录</span>

+                  </el-form-item>

+                </div>

+                

+                <div class="form-actions">

+                  <el-button @click="resetProfile">重置</el-button>

+                  <el-button type="primary" @click="saveProfile" :loading="saving">

+                    保存修改

+                  </el-button>

+                </div>

+              </el-form>

+            </div>

+          </el-tab-pane>

+          

+          <!-- 数据统计 -->

+          <el-tab-pane label="数据统计" name="stats">

+            <div class="stats-section">

+              <div class="stats-overview">

+                <div class="overview-grid">

+                  <div class="overview-card">

+                    <h3>上传统计</h3>

+                    <div class="stat-details">

+                      <div class="detail-item">

+                        <span class="label">总上传量:</span>

+                        <span class="value">{{ userProfile.detailedStats.totalUploaded }}</span>

+                      </div>

+                      <div class="detail-item">

+                        <span class="label">上传种子:</span>

+                        <span class="value">{{ userProfile.detailedStats.uploadedTorrents }} 个</span>

+                      </div>

+                      <div class="detail-item">

+                        <span class="label">平均大小:</span>

+                        <span class="value">{{ userProfile.detailedStats.avgUploadSize }}</span>

+                      </div>

+                    </div>

+                  </div>

+                  

+                  <div class="overview-card">

+                    <h3>下载统计</h3>

+                    <div class="stat-details">

+                      <div class="detail-item">

+                        <span class="label">总下载量:</span>

+                        <span class="value">{{ userProfile.detailedStats.totalDownloaded }}</span>

+                      </div>

+                      <div class="detail-item">

+                        <span class="label">下载种子:</span>

+                        <span class="value">{{ userProfile.detailedStats.downloadedTorrents }} 个</span>

+                      </div>

+                      <div class="detail-item">

+                        <span class="label">完成种子:</span>

+                        <span class="value">{{ userProfile.detailedStats.completedTorrents }} 个</span>

+                      </div>

+                    </div>

+                  </div>

+                  

+                  <div class="overview-card">

+                    <h3>做种统计</h3>

+                    <div class="stat-details">

+                      <div class="detail-item">

+                        <span class="label">正在做种:</span>

+                        <span class="value">{{ userProfile.detailedStats.seeding }} 个</span>

+                      </div>

+                      <div class="detail-item">

+                        <span class="label">做种时间:</span>

+                        <span class="value">{{ userProfile.detailedStats.seedingTime }}</span>

+                      </div>

+                      <div class="detail-item">

+                        <span class="label">做种排名:</span>

+                        <span class="value">第 {{ userProfile.detailedStats.seedingRank }} 名</span>

+                      </div>

+                    </div>

+                  </div>

+                  

+                  <div class="overview-card">

+                    <h3>积分记录</h3>

+                    <div class="stat-details">

+                      <div class="detail-item">

+                        <span class="label">当前积分:</span>

+                        <span class="value">{{ userProfile.stats.points }}</span>

+                      </div>

+                      <div class="detail-item">

+                        <span class="label">累计获得:</span>

+                        <span class="value">{{ userProfile.detailedStats.totalEarnedPoints }}</span>

+                      </div>

+                      <div class="detail-item">

+                        <span class="label">累计消费:</span>

+                        <span class="value">{{ userProfile.detailedStats.totalSpentPoints }}</span>

+                      </div>

+                    </div>

+                  </div>

+                </div>

+              </div>

+              

+              <!-- 数据图表 -->

+              <div class="charts-section">

+                <div class="chart-card">

+                  <h3>上传下载趋势</h3>

+                  <div class="chart-placeholder">

+                    <el-icon size="48" color="#e4e7ed"><TrendCharts /></el-icon>

+                    <p>图表功能开发中...</p>

+                  </div>

+                </div>

+              </div>

+            </div>

+          </el-tab-pane>

+          

+          <!-- 我的种子 -->

+          <el-tab-pane label="我的种子" name="torrents">

+            <div class="torrents-section">

+              <div class="section-header">

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

+                <el-button type="primary" :icon="Upload" @click="$router.push('/upload')">

+                  上传新种子

+                </el-button>

+              </div>

+              

+              <el-table :data="userTorrents" stripe>

+                <el-table-column label="种子名称" min-width="300">

+                  <template #default="{ row }">

+                    <div class="torrent-info">

+                      <el-tag :type="getCategoryType(row.category)" size="small">

+                        {{ getCategoryName(row.category) }}

+                      </el-tag>

+                      <span class="torrent-title">{{ row.title }}</span>

+                    </div>

+                  </template>

+                </el-table-column>

+                

+                <el-table-column label="大小" prop="size" width="100" />

+                <el-table-column label="做种" prop="seeders" width="80" align="center" />

+                <el-table-column label="下载" prop="leechers" width="80" align="center" />

+                <el-table-column label="完成" prop="downloads" width="80" align="center" />

+                <el-table-column label="上传时间" width="120">

+                  <template #default="{ row }">

+                    {{ formatDate(row.uploadTime) }}

+                  </template>

+                </el-table-column>

+                

+                <el-table-column label="操作" width="120" align="center">

+                  <template #default="{ row }">

+                    <el-button 

+                      type="primary" 

+                      size="small" 

+                      @click="$router.push(`/torrent/${row.id}`)"

+                    >

+                      查看

+                    </el-button>

+                  </template>

+                </el-table-column>

+              </el-table>

+              

+              <div class="pagination-wrapper">

+                <el-pagination

+                  v-model:current-page="torrentsPage"

+                  :page-size="10"

+                  :total="userTorrents.length"

+                  layout="prev, pager, next"

+                  small

+                />

+              </div>

+            </div>

+          </el-tab-pane>

+          

+          <!-- 活动记录 -->

+          <el-tab-pane label="活动记录" name="activity">

+            <div class="activity-section">

+              <div class="activity-filters">

+                <el-select v-model="activityFilter" placeholder="活动类型">

+                  <el-option label="全部活动" value="" />

+                  <el-option label="上传种子" value="upload" />

+                  <el-option label="下载种子" value="download" />

+                  <el-option label="论坛发帖" value="post" />

+                  <el-option label="积分变动" value="points" />

+                </el-select>

+              </div>

+              

+              <div class="activity-timeline">

+                <el-timeline>

+                  <el-timeline-item

+                    v-for="activity in filteredActivities"

+                    :key="activity.id"

+                    :timestamp="formatTime(activity.time)"

+                    :type="getActivityType(activity.type)"

+                  >

+                    <div class="activity-content">

+                      <div class="activity-header">

+                        <el-icon>

+                          <component :is="getActivityIcon(activity.type)" />

+                        </el-icon>

+                        <span class="activity-title">{{ activity.title }}</span>

+                      </div>

+                      <div class="activity-description">{{ activity.description }}</div>

+                    </div>

+                  </el-timeline-item>

+                </el-timeline>

+              </div>

+            </div>

+          </el-tab-pane>

+          

+          <!-- 安全设置 -->

+          <el-tab-pane label="安全设置" name="security">

+            <div class="security-section">

+              <div class="security-card">

+                <h3>修改密码</h3>

+                <el-form

+                  ref="passwordFormRef"

+                  :model="passwordForm"

+                  :rules="passwordRules"

+                  label-width="120px"

+                >

+                  <el-form-item label="当前密码" prop="currentPassword">

+                    <el-input

+                      v-model="passwordForm.currentPassword"

+                      type="password"

+                      show-password

+                      placeholder="请输入当前密码"

+                    />

+                  </el-form-item>

+                  

+                  <el-form-item label="新密码" prop="newPassword">

+                    <el-input

+                      v-model="passwordForm.newPassword"

+                      type="password"

+                      show-password

+                      placeholder="请输入新密码"

+                    />

+                  </el-form-item>

+                  

+                  <el-form-item label="确认密码" prop="confirmPassword">

+                    <el-input

+                      v-model="passwordForm.confirmPassword"

+                      type="password"

+                      show-password

+                      placeholder="请再次输入新密码"

+                    />

+                  </el-form-item>

+                  

+                  <el-form-item>

+                    <el-button type="primary" @click="changePassword" :loading="changingPassword">

+                      修改密码

+                    </el-button>

+                  </el-form-item>

+                </el-form>

+              </div>

+              

+              <div class="security-card">

+                <h3>登录记录</h3>

+                <el-table :data="loginHistory" stripe>

+                  <el-table-column label="登录时间" width="180">

+                    <template #default="{ row }">

+                      {{ formatDateTime(row.time) }}

+                    </template>

+                  </el-table-column>

+                  <el-table-column label="IP地址" prop="ip" width="150" />

+                  <el-table-column label="设备信息" prop="device" />

+                  <el-table-column label="登录结果" width="100">

+                    <template #default="{ row }">

+                      <el-tag :type="row.success ? 'success' : 'danger'" size="small">

+                        {{ row.success ? '成功' : '失败' }}

+                      </el-tag>

+                    </template>

+                  </el-table-column>

+                </el-table>

+              </div>

+            </div>

+          </el-tab-pane>

+        </el-tabs>

+      </div>

+    </div>

+

+    <!-- 更换头像对话框 -->

+    <el-dialog v-model="showAvatarDialog" title="更换头像" width="400px">

+      <div class="avatar-upload">

+        <el-upload

+          ref="avatarUploadRef"

+          :auto-upload="false"

+          :limit="1"

+          accept="image/*"

+          :on-change="handleAvatarChange"

+          list-type="picture-card"

+          class="avatar-uploader"

+        >

+          <el-icon><Plus /></el-icon>

+        </el-upload>

+        <div class="upload-tips">

+          <p>支持 JPG、PNG 格式</p>

+          <p>建议尺寸 200x200 像素</p>

+          <p>文件大小不超过 2MB</p>

+        </div>

+      </div>

+      

+      <template #footer>

+        <el-button @click="showAvatarDialog = false">取消</el-button>

+        <el-button type="primary" @click="uploadAvatar" :loading="uploadingAvatar">

+          上传头像

+        </el-button>

+      </template>

+    </el-dialog>

+  </div>

+</template>

+

+<script>

+import { ref, reactive, computed, onMounted, nextTick } from 'vue'

+import { useRouter } from 'vue-router'

+import { ElMessage } from 'element-plus'

+import {

+  Calendar,

+  Clock,

+  Upload,

+  Download,

+  TrendCharts,

+  Star,

+  QuestionFilled,

+  Plus,

+  ChatDotRound,

+  Flag,

+  Coin

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

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

+export default {

+  name: 'ProfileView',

+  components:{

+    Navbar

+  },

+  setup() {

+    const router = useRouter()

+    const profileFormRef = ref(null)

+    const passwordFormRef = ref(null)

+    const avatarUploadRef = ref(null)

+    const interestInputRef = ref(null)

+    

+    const activeTab = ref('info')

+    const showAvatarDialog = ref(false)

+    const saving = ref(false)

+    const changingPassword = ref(false)

+    const uploadingAvatar = ref(false)

+    const interestInputVisible = ref(false)

+    const interestInputValue = ref('')

+    const activityFilter = ref('')

+    const torrentsPage = ref(1)

+    

+    const userProfile = ref({

+      username: 'MovieExpert',

+      email: 'movieexpert@example.com',

+      realName: '',

+      avatar: '',

+      userLevel: 5,

+      userTitle: '资深会员',

+      joinDate: '2023-01-15T10:00:00',

+      lastLogin: '2025-06-03T14:30:00',

+      location: ['北京市', '朝阳区'],

+      signature: '热爱电影,分享快乐!',

+      website: 'https://movieblog.com',

+      interests: ['电影', '音乐', '科技', '摄影'],

+      emailPublic: false,

+      statsPublic: true,

+      activityPublic: true,

+      stats: {

+        uploaded: '256.8 GB',

+        downloaded: '89.6 GB',

+        ratio: '2.87',

+        points: '15,680'

+      },

+      detailedStats: {

+        totalUploaded: '256.8 GB',

+        uploadedTorrents: 45,

+        avgUploadSize: '5.7 GB',

+        totalDownloaded: '89.6 GB',

+        downloadedTorrents: 123,

+        completedTorrents: 118,

+        seeding: 32,

+        seedingTime: '1,245 小时',

+        seedingRank: 86,

+        totalEarnedPoints: '28,940',

+        totalSpentPoints: '13,260'

+      }

+    })

+    

+    const editProfile = reactive({

+      username: '',

+      email: '',

+      realName: '',

+      location: [],

+      signature: '',

+      website: '',

+      interests: [],

+      emailPublic: false,

+      statsPublic: true,

+      activityPublic: true

+    })

+    

+    const passwordForm = reactive({

+      currentPassword: '',

+      newPassword: '',

+      confirmPassword: ''

+    })

+    

+    const profileRules = {

+      email: [

+        { required: true, message: '请输入邮箱地址', trigger: 'blur' },

+        { type: 'email', message: '请输入正确的邮箱格式', trigger: 'blur' }

+      ]

+    }

+    

+    const passwordRules = {

+      currentPassword: [

+        { required: true, message: '请输入当前密码', trigger: 'blur' }

+      ],

+      newPassword: [

+        { required: true, message: '请输入新密码', trigger: 'blur' },

+        { min: 6, message: '密码长度至少6个字符', trigger: 'blur' }

+      ],

+      confirmPassword: [

+        { required: true, message: '请确认新密码', trigger: 'blur' },

+        {

+          validator: (rule, value, callback) => {

+            if (value !== passwordForm.newPassword) {

+              callback(new Error('两次输入的密码不一致'))

+            } else {

+              callback()

+            }

+          },

+          trigger: 'blur'

+        }

+      ]

+    }

+    

+    const locationOptions = [

+      {

+        value: '北京市',

+        label: '北京市',

+        children: [

+          { value: '朝阳区', label: '朝阳区' },

+          { value: '海淀区', label: '海淀区' },

+          { value: '丰台区', label: '丰台区' }

+        ]

+      },

+      {

+        value: '上海市',

+        label: '上海市',

+        children: [

+          { value: '浦东新区', label: '浦东新区' },

+          { value: '黄浦区', label: '黄浦区' },

+          { value: '静安区', label: '静安区' }

+        ]

+      }

+    ]

+    

+    const userTorrents = ref([

+      {

+        id: 1,

+        title: '[4K蓝光原盘] 阿凡达:水之道',

+        category: 'movie',

+        size: '85.6 GB',

+        seeders: 45,

+        leechers: 12,

+        downloads: 234,

+        uploadTime: '2025-05-15T10:00:00'

+      },

+      {

+        id: 2,

+        title: '[FLAC] 古典音乐合集',

+        category: 'music',

+        size: '2.3 GB',

+        seeders: 23,

+        leechers: 5,

+        downloads: 89,

+        uploadTime: '2025-04-20T15:30:00'

+      }

+    ])

+    

+    const activities = ref([

+      {

+        id: 1,

+        type: 'upload',

+        title: '上传种子',

+        description: '上传了《阿凡达:水之道》4K蓝光原盘',

+        time: '2025-06-03T10:30:00'

+      },

+      {

+        id: 2,

+        type: 'download',

+        title: '下载种子',

+        description: '下载了《星际穿越》IMAX版本',

+        time: '2025-06-02T14:20:00'

+      },

+      {

+        id: 3,

+        type: 'post',

+        title: '发布主题',

+        description: '在电影讨论区发布了新主题',

+        time: '2025-06-01T16:45:00'

+      },

+      {

+        id: 4,

+        type: 'points',

+        title: '积分变动',

+        description: '做种奖励获得 +50 积分',

+        time: '2025-05-31T09:15:00'

+      }

+    ])

+    

+    const loginHistory = ref([

+      {

+        time: '2025-06-03T14:30:00',

+        ip: '192.168.1.100',

+        device: 'Windows 11 / Chrome 120',

+        success: true

+      },

+      {

+        time: '2025-06-02T09:15:00',

+        ip: '192.168.1.100',

+        device: 'Windows 11 / Chrome 120',

+        success: true

+      },

+      {

+        time: '2025-06-01T22:30:00',

+        ip: '192.168.1.100',

+        device: 'Android / Chrome Mobile',

+        success: true

+      }

+    ])

+    

+    const filteredActivities = computed(() => {

+      if (!activityFilter.value) return activities.value

+      return activities.value.filter(activity => activity.type === activityFilter.value)

+    })

+    

+    onMounted(() => {

+      loadUserProfile()

+    })

+    

+    const loadUserProfile = () => {

+      // 加载用户资料到编辑表单

+      Object.assign(editProfile, {

+        username: userProfile.value.username,

+        email: userProfile.value.email,

+        realName: userProfile.value.realName,

+        location: userProfile.value.location,

+        signature: userProfile.value.signature,

+        website: userProfile.value.website,

+        interests: [...userProfile.value.interests],

+        emailPublic: userProfile.value.emailPublic,

+        statsPublic: userProfile.value.statsPublic,

+        activityPublic: userProfile.value.activityPublic

+      })

+    }

+    

+    const formatDate = (dateString) => {

+      const date = new Date(dateString)

+      return date.toLocaleDateString('zh-CN')

+    }

+    

+    const formatTime = (timeString) => {

+      const date = new Date(timeString)

+      const now = new Date()

+      const diff = now - date

+      const hours = Math.floor(diff / (1000 * 60 * 60))

+      

+      if (hours < 1) return '刚刚'

+      if (hours < 24) return `${hours}小时前`

+      const days = Math.floor(hours / 24)

+      if (days < 7) return `${days}天前`

+      

+      return date.toLocaleDateString('zh-CN')

+    }

+    

+    const formatDateTime = (dateString) => {

+      const date = new Date(dateString)

+      return date.toLocaleString('zh-CN')

+    }

+    

+    const getUserTitleType = (level) => {

+      if (level >= 8) return 'danger'  // 管理员

+      if (level >= 6) return 'warning' // 资深会员

+      if (level >= 4) return 'success' // 正式会员

+      if (level >= 2) return 'info'    // 初级会员

+      return 'default' // 新手

+    }

+    

+    const getRatioClass = (ratio) => {

+      const r = parseFloat(ratio)

+      if (r >= 2) return 'excellent'

+      if (r >= 1) return 'good'

+      return 'warning'

+    }

+    

+    const getCategoryType = (category) => {

+      const types = {

+        'movie': 'primary',

+        'tv': 'info',

+        'music': 'success',

+        'software': 'warning',

+        'game': 'danger'

+      }

+      return types[category] || 'default'

+    }

+    

+    const getCategoryName = (category) => {

+      const names = {

+        'movie': '电影',

+        'tv': '电视剧',

+        'music': '音乐',

+        'software': '软件',

+        'game': '游戏'

+      }

+      return names[category] || category

+    }

+    

+    const getActivityType = (type) => {

+      const types = {

+        'upload': 'success',

+        'download': 'primary',

+        'post': 'warning',

+        'points': 'info'

+      }

+      return types[type] || 'primary'

+    }

+    

+    const getActivityIcon = (type) => {

+      const icons = {

+        'upload': 'Upload',

+        'download': 'Download',

+        'post': 'ChatDotRound',

+        'points': 'Coin'

+      }

+      return icons[type] || 'Star'

+    }

+    

+    const showInterestInput = () => {

+      interestInputVisible.value = true

+      nextTick(() => {

+        interestInputRef.value?.focus()

+      })

+    }

+    

+    const addInterest = () => {

+      const interest = interestInputValue.value.trim()

+      if (interest && !editProfile.interests.includes(interest)) {

+        editProfile.interests.push(interest)

+      }

+      interestInputVisible.value = false

+      interestInputValue.value = ''

+    }

+    

+    const removeInterest = (interest) => {

+      const index = editProfile.interests.indexOf(interest)

+      if (index > -1) {

+        editProfile.interests.splice(index, 1)

+      }

+    }

+    

+    const saveProfile = async () => {

+      try {

+        await profileFormRef.value?.validate()

+        

+        saving.value = true

+        

+        // 模拟保存过程

+        await new Promise(resolve => setTimeout(resolve, 1500))

+        

+        // 更新用户资料

+        Object.assign(userProfile.value, editProfile)

+        

+        ElMessage.success('个人资料保存成功')

+        

+      } catch (error) {

+        console.error('表单验证失败:', error)

+      } finally {

+        saving.value = false

+      }

+    }

+    

+    const resetProfile = () => {

+      loadUserProfile()

+      ElMessage.info('已重置为原始数据')

+    }

+    

+    const changePassword = async () => {

+      try {

+        await passwordFormRef.value?.validate()

+        

+        changingPassword.value = true

+        

+        // 模拟密码修改过程

+        await new Promise(resolve => setTimeout(resolve, 1500))

+        

+        // 重置表单

+        passwordFormRef.value?.resetFields()

+        Object.assign(passwordForm, {

+          currentPassword: '',

+          newPassword: '',

+          confirmPassword: ''

+        })

+        

+        ElMessage.success('密码修改成功')

+        

+      } catch (error) {

+        console.error('表单验证失败:', error)

+      } finally {

+        changingPassword.value = false

+      }

+    }

+    

+    const handleAvatarChange = (file) => {

+      const isImage = file.raw.type.startsWith('image/')

+      const isLt2M = file.raw.size / 1024 / 1024 < 2

+      

+      if (!isImage) {

+        ElMessage.error('只能上传图片文件!')

+        return false

+      }

+      if (!isLt2M) {

+        ElMessage.error('图片大小不能超过 2MB!')

+        return false

+      }

+      

+      return true

+    }

+    

+    const uploadAvatar = async () => {

+      const files = avatarUploadRef.value?.uploadFiles

+      if (!files || files.length === 0) {

+        ElMessage.warning('请选择头像文件')

+        return

+      }

+      

+      uploadingAvatar.value = true

+      try {

+        // 模拟上传过程

+        await new Promise(resolve => setTimeout(resolve, 2000))

+        

+        // 更新头像URL

+        userProfile.value.avatar = URL.createObjectURL(files[0].raw)

+        

+        ElMessage.success('头像上传成功')

+        showAvatarDialog.value = false

+        avatarUploadRef.value?.clearFiles()

+        

+      } catch (error) {

+        ElMessage.error('头像上传失败')

+      } finally {

+        uploadingAvatar.value = false

+      }

+    }

+    

+    return {

+      activeTab,

+      showAvatarDialog,

+      saving,

+      changingPassword,

+      uploadingAvatar,

+      interestInputVisible,

+      interestInputValue,

+      activityFilter,

+      torrentsPage,

+      userProfile,

+      editProfile,

+      passwordForm,

+      profileRules,

+      passwordRules,

+      locationOptions,

+      userTorrents,

+      filteredActivities,

+      loginHistory,

+      profileFormRef,

+      passwordFormRef,

+      avatarUploadRef,

+      interestInputRef,

+      formatDate,

+      formatTime,

+      formatDateTime,

+      getUserTitleType,

+      getRatioClass,

+      getCategoryType,

+      getCategoryName,

+      getActivityType,

+      getActivityIcon,

+      showInterestInput,

+      addInterest,

+      removeInterest,

+      saveProfile,

+      resetProfile,

+      changePassword,

+      handleAvatarChange,

+      uploadAvatar,

+      Calendar,

+      Clock,

+      Upload,

+      Download,

+      TrendCharts,

+      Star,

+      QuestionFilled,

+      Plus,

+      ChatDotRound,

+      Flag,

+      Coin

+    }

+  }

+}

+</script>

+

+<style lang="scss" scoped>

+.profile-page {

+  max-width: 1200px;

+  margin: 0 auto;

+  padding: 24px;

+  background: #f5f5f5;

+  min-height: 100vh;

+}

+

+.profile-header {

+  background: #fff;

+  border-radius: 12px;

+  padding: 32px;

+  margin-bottom: 24px;

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

+  

+  display: grid;

+  grid-template-columns: 1fr 1fr;

+  gap: 32px;

+  

+  .user-avatar-section {

+    display: flex;

+    gap: 24px;

+    

+    .avatar-container {

+      text-align: center;

+      

+      .change-avatar-btn {

+        margin-top: 12px;

+      }

+    }

+    

+    .user-basic-info {

+      flex: 1;

+      

+      .username {

+        font-size: 28px;

+        font-weight: 600;

+        color: #2c3e50;

+        margin: 0 0 12px 0;

+      }

+      

+      .user-title {

+        margin-bottom: 16px;

+      }

+      

+      .join-info, .last-login {

+        display: flex;

+        align-items: center;

+        gap: 8px;

+        font-size: 14px;

+        color: #7f8c8d;

+        margin-bottom: 8px;

+      }

+    }

+  }

+  

+  .user-stats-overview {

+    .stats-grid {

+      display: grid;

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

+      gap: 16px;

+      

+      .stat-card {

+        background: #f8f9fa;

+        border-radius: 8px;

+        padding: 20px;

+        display: flex;

+        align-items: center;

+        gap: 16px;

+        

+        .stat-icon {

+          width: 48px;

+          height: 48px;

+          border-radius: 50%;

+          display: flex;

+          align-items: center;

+          justify-content: center;

+          

+          &.upload { background: rgba(103, 194, 58, 0.1); color: #67c23a; }

+          &.download { background: rgba(64, 158, 255, 0.1); color: #409eff; }

+          &.ratio {

+            &.excellent { background: rgba(103, 194, 58, 0.1); color: #67c23a; }

+            &.good { background: rgba(230, 162, 60, 0.1); color: #e6a23c; }

+            &.warning { background: rgba(245, 108, 108, 0.1); color: #f56c6c; }

+          }

+          &.points { background: rgba(245, 108, 108, 0.1); color: #f56c6c; }

+        }

+        

+        .stat-info {

+          h3 {

+            font-size: 20px;

+            font-weight: 600;

+            color: #2c3e50;

+            margin: 0 0 4px 0;

+          }

+          

+          p {

+            font-size: 14px;

+            color: #7f8c8d;

+            margin: 0;

+          }

+        }

+      }

+    }

+  }

+}

+

+.profile-content {

+  background: #fff;

+  border-radius: 12px;

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

+  

+  :deep(.el-tabs__content) {

+    padding: 24px;

+  }

+}

+

+.info-section {

+  .form-section {

+    margin-bottom: 32px;

+    

+    h3 {

+      font-size: 18px;

+      font-weight: 600;

+      color: #2c3e50;

+      margin: 0 0 20px 0;

+      padding-bottom: 8px;

+      border-bottom: 2px solid #f0f0f0;

+    }

+  }

+  

+  .interests-input {

+    display: flex;

+    flex-wrap: wrap;

+    gap: 8px;

+    align-items: center;

+    

+    .interest-tag {

+      margin: 0;

+    }

+  }

+  

+  .setting-tip {

+    margin-left: 12px;

+    font-size: 12px;

+    color: #909399;

+  }

+  

+  .form-actions {

+    text-align: center;

+    margin-top: 32px;

+    

+    .el-button {

+      margin: 0 8px;

+      min-width: 100px;

+    }

+  }

+}

+

+.stats-section {

+  .stats-overview {

+    margin-bottom: 32px;

+    

+    .overview-grid {

+      display: grid;

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

+      gap: 20px;

+      

+      .overview-card {

+        background: #f8f9fa;

+        border-radius: 8px;

+        padding: 24px;

+        

+        h3 {

+          font-size: 16px;

+          font-weight: 600;

+          color: #2c3e50;

+          margin: 0 0 16px 0;

+        }

+        

+        .stat-details {

+          .detail-item {

+            display: flex;

+            justify-content: space-between;

+            align-items: center;

+            margin-bottom: 12px;

+            

+            .label {

+              font-size: 14px;

+              color: #7f8c8d;

+            }

+            

+            .value {

+              font-size: 14px;

+              font-weight: 600;

+              color: #2c3e50;

+            }

+          }

+        }

+      }

+    }

+  }

+  

+  .charts-section {

+    .chart-card {

+      background: #f8f9fa;

+      border-radius: 8px;

+      padding: 24px;

+      

+      h3 {

+        font-size: 16px;

+        font-weight: 600;

+        color: #2c3e50;

+        margin: 0 0 20px 0;

+      }

+      

+      .chart-placeholder {

+        text-align: center;

+        padding: 60px 0;

+        color: #909399;

+        

+        p {

+          margin: 12px 0 0 0;

+        }

+      }

+    }

+  }

+}

+

+.torrents-section {

+  .section-header {

+    display: flex;

+    justify-content: space-between;

+    align-items: center;

+    margin-bottom: 20px;

+    

+    h3 {

+      font-size: 18px;

+      font-weight: 600;

+      color: #2c3e50;

+      margin: 0;

+    }

+  }

+  

+  .torrent-info {

+    display: flex;

+    align-items: center;

+    gap: 12px;

+    

+    .torrent-title {

+      font-weight: 500;

+    }

+  }

+  

+  .pagination-wrapper {

+    margin-top: 16px;

+    text-align: center;

+  }

+}

+

+.activity-section {

+  .activity-filters {

+    margin-bottom: 24px;

+    

+    .el-select {

+      width: 150px;

+    }

+  }

+  

+  .activity-timeline {

+    .activity-content {

+      .activity-header {

+        display: flex;

+        align-items: center;

+        gap: 8px;

+        margin-bottom: 8px;

+        

+        .activity-title {

+          font-weight: 600;

+          color: #2c3e50;

+        }

+      }

+      

+      .activity-description {

+        font-size: 14px;

+        color: #7f8c8d;

+        line-height: 1.5;

+      }

+    }

+  }

+}

+

+.security-section {

+  .security-card {

+    background: #f8f9fa;

+    border-radius: 8px;

+    padding: 24px;

+    margin-bottom: 24px;

+    

+    h3 {

+      font-size: 18px;

+      font-weight: 600;

+      color: #2c3e50;

+      margin: 0 0 20px 0;

+    }

+  }

+}

+

+.avatar-upload {

+  text-align: center;

+  

+  .avatar-uploader {

+    margin-bottom: 16px;

+  }

+  

+  .upload-tips {

+    font-size: 12px;

+    color: #909399;

+    

+    p {

+      margin: 4px 0;

+    }

+  }

+}

+

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

+  .profile-page {

+    padding: 16px;

+  }

+  

+  .profile-header {

+    grid-template-columns: 1fr;

+    gap: 24px;

+    

+    .user-avatar-section {

+      flex-direction: column;

+      text-align: center;

+    }

+    

+    .user-stats-overview .stats-grid {

+      grid-template-columns: 1fr;

+    }

+  }

+  

+  .stats-overview .overview-grid {

+    grid-template-columns: 1fr;

+  }

+  

+  .torrents-section .section-header {

+    flex-direction: column;

+    gap: 16px;

+    align-items: flex-start;

+  }

+}

 </style>
\ No newline at end of file
diff --git a/src/views/forum/ForumSectionView.vue b/src/views/forum/ForumSectionView.vue
index ccb88f5..98c9780 100644
--- a/src/views/forum/ForumSectionView.vue
+++ b/src/views/forum/ForumSectionView.vue
@@ -1,4 +1,5 @@
 <template>

+  <Navbar />

   <div class="section-page">

     <Navbar />

     <div class="page-container">

diff --git a/src/views/forum/ForumTopicView.vue b/src/views/forum/ForumTopicView.vue
index 170e313..b3fe08b 100644
--- a/src/views/forum/ForumTopicView.vue
+++ b/src/views/forum/ForumTopicView.vue
@@ -1,4 +1,5 @@
 <template>

+  <Navbar />

   <div class="topic-detail-page">

     <Navbar />

     <div class="page-container">

diff --git a/src/views/forum/ForumView.vue b/src/views/forum/ForumView.vue
index 703e4f5..cd7e7bf 100644
--- a/src/views/forum/ForumView.vue
+++ b/src/views/forum/ForumView.vue
@@ -1,6 +1,7 @@
 <template>

+  <Navbar />

   <div class="forum-page">

-    <Navbar />

+    

     <div class="page-container">

       <!-- 论坛头部 -->

       <div class="forum-header">

@@ -255,7 +256,7 @@
 import { ref, reactive, onMounted, nextTick } from 'vue'

 import { useRouter } from 'vue-router'

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

-import {

+import { 

   Edit,

   ChatDotRound,

   Comment,

diff --git a/src/views/torrent/TorrentDetailView.vue b/src/views/torrent/TorrentDetailView.vue
index 046c00b..28af1f6 100644
--- a/src/views/torrent/TorrentDetailView.vue
+++ b/src/views/torrent/TorrentDetailView.vue
@@ -1,4 +1,5 @@
 <template>
+  <Navbar />
   <div class="torrent-detail-page">
     <div class="page-container">
       <!-- 加载状态 -->
@@ -309,10 +310,12 @@
   Like
 } from '@element-plus/icons-vue'
 import axios from 'axios'
+import Navbar from '@/components/Navbar.vue'
 
 export default {
   name: 'TorrentDetailView',
   components: {
+    Navbar,
     ArrowLeft,
     Download,
     Star,
diff --git a/src/views/torrent/TorrentsView.vue b/src/views/torrent/TorrentsView.vue
index 34af25d..596ca22 100644
--- a/src/views/torrent/TorrentsView.vue
+++ b/src/views/torrent/TorrentsView.vue
@@ -1,6 +1,6 @@
 <template>
+  <Navbar />
   <div class="torrents-page">
-    <Navbar />
     <div class="page-header">
       <h1>种子资源</h1>
       <div class="header-actions">
diff --git a/src/views/torrent/UploadView.vue b/src/views/torrent/UploadView.vue
index 9807cd1..72b7638 100644
--- a/src/views/torrent/UploadView.vue
+++ b/src/views/torrent/UploadView.vue
@@ -1,4 +1,5 @@
 <template>

+  <Navbar />

   <div class="upload-page">

     <div class="upload-container">

       <h2>上传种子</h2>

@@ -102,9 +103,12 @@
 import { useRouter } from 'vue-router'

 import { ElMessage } from 'element-plus'

 import { uploadTorrent, getCategories, getTags } from '@/api/torrent'

-

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

 export default {

   name: 'UploadView',

+  components:{

+    Navbar

+  },

   setup() {

     const router = useRouter()

     const uploadFormRef = ref(null)