基本功能实现

Change-Id: I4fb8dfa2eed093c13d7c1e4304c4b4d012512ba9
diff --git a/src/views/torrent/TorrentsView.vue b/src/views/torrent/TorrentsView.vue
new file mode 100644
index 0000000..f3231da
--- /dev/null
+++ b/src/views/torrent/TorrentsView.vue
@@ -0,0 +1,479 @@
+<template>
+  <div class="torrents-page">
+    <div class="page-header">
+      <h1>种子资源</h1>
+      <div class="header-actions">
+        <el-button type="primary" :icon="Upload" @click="$router.push('/upload')">
+          上传种子
+        </el-button>
+      </div>
+    </div>
+
+    <!-- 搜索和筛选 -->
+    <div class="search-section">
+      <div class="search-bar">
+        <el-input
+          v-model="searchQuery"
+          placeholder="搜索种子..."
+          :prefix-icon="Search"
+          size="large"
+          @keyup.enter="handleSearch"
+          clearable
+        />
+        <el-button type="primary" size="large" @click="handleSearch">
+          搜索
+        </el-button>
+      </div>
+      
+      <div class="filters">
+        <el-select v-model="selectedCategory" placeholder="分类" @change="handleFilter">
+          <el-option label="全部" value="" />
+          <el-option label="电影" value="movie" />
+          <el-option label="电视剧" value="tv" />
+          <el-option label="音乐" value="music" />
+          <el-option label="软件" value="software" />
+          <el-option label="游戏" value="game" />
+        </el-select>
+        
+        <el-select v-model="sortBy" placeholder="排序方式" @change="handleFilter">
+          <el-option label="上传时间" value="upload_time" />
+          <el-option label="文件大小" value="size" />
+          <el-option label="做种数" value="seeders" />
+          <el-option label="下载数" value="leechers" />
+          <el-option label="完成数" value="downloads" />
+        </el-select>
+        
+        <el-radio-group v-model="sortOrder" @change="handleFilter">
+          <el-radio-button label="desc">降序</el-radio-button>
+          <el-radio-button label="asc">升序</el-radio-button>
+        </el-radio-group>
+      </div>
+    </div>
+
+    <!-- 种子列表 -->
+    <div class="torrents-list">
+      <div class="list-header">
+        <span class="results-count">共找到 {{ totalCount }} 个种子</span>
+      </div>
+      
+      <el-table 
+        :data="torrents" 
+        v-loading="loading"
+        @row-click="handleRowClick"
+        stripe
+        class="torrents-table"
+      >
+        <el-table-column label="分类" width="80">
+          <template #default="{ row }">
+            <el-tag :type="getCategoryType(row.category)" size="small">
+              {{ getCategoryName(row.category) }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        
+        <el-table-column label="种子信息" min-width="400">
+          <template #default="{ row }">
+            <div class="torrent-info">
+              <h4 class="torrent-title">{{ row.title }}</h4>
+              <div class="torrent-meta">
+                <span class="uploader">
+                  <el-icon><User /></el-icon>
+                  {{ row.uploader }}
+                </span>
+                <span class="upload-time">
+                  <el-icon><Clock /></el-icon>
+                  {{ formatTime(row.uploadTime) }}
+                </span>
+                <span class="file-size">
+                  <el-icon><Document /></el-icon>
+                  {{ row.size }}
+                </span>
+              </div>
+            </div>
+          </template>
+        </el-table-column>
+        
+        <el-table-column label="做种" width="80" align="center">
+          <template #default="{ row }">
+            <span class="seeders">{{ row.seeders }}</span>
+          </template>
+        </el-table-column>
+        
+        <el-table-column label="下载" width="80" align="center">
+          <template #default="{ row }">
+            <span class="leechers">{{ row.leechers }}</span>
+          </template>
+        </el-table-column>
+        
+        <el-table-column label="完成" width="80" align="center">
+          <template #default="{ row }">
+            <span>{{ row.downloads }}</span>
+          </template>
+        </el-table-column>
+        
+        <el-table-column label="操作" width="120" align="center">
+          <template #default="{ row }">
+            <el-button 
+              type="primary" 
+              size="small" 
+              :icon="Download"
+              @click.stop="handleDownload(row)"
+            >
+              下载
+            </el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      
+      <!-- 分页 -->
+      <div class="pagination-wrapper">
+        <el-pagination
+          v-model:current-page="currentPage"
+          v-model:page-size="pageSize"
+          :page-sizes="[20, 50, 100]"
+          :total="totalCount"
+          layout="total, sizes, prev, pager, next, jumper"
+          @size-change="handleSizeChange"
+          @current-change="handleCurrentChange"
+        />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { ref, onMounted, watch } from 'vue'
+import { useRouter, useRoute } from 'vue-router'
+import { ElMessage } from 'element-plus'
+import {
+  Search,
+  Upload,
+  Download,
+  User,
+  Clock,
+  Document
+} from '@element-plus/icons-vue'
+
+export default {
+  name: 'TorrentsView',
+  setup() {
+    const router = useRouter()
+    const route = useRoute()
+    
+    const loading = ref(false)
+    const searchQuery = ref('')
+    const selectedCategory = ref('')
+    const sortBy = ref('upload_time')
+    const sortOrder = ref('desc')
+    const currentPage = ref(1)
+    const pageSize = ref(20)
+    const totalCount = ref(0)
+    
+    const torrents = ref([
+      {
+        id: 1,
+        title: '[4K蓝光原盘] 阿凡达:水之道 Avatar: The Way of Water (2022)',
+        category: 'movie',
+        uploader: 'MovieMaster',
+        uploadTime: '2025-06-03T10:30:00',
+        size: '85.6 GB',
+        seeders: 128,
+        leechers: 45,
+        downloads: 892
+      },
+      {
+        id: 2,
+        title: '[FLAC] Taylor Swift - Midnights (Deluxe Edition) [2022]',
+        category: 'music',
+        uploader: 'MusicLover',
+        uploadTime: '2025-06-03T09:15:00',
+        size: '1.2 GB',
+        seeders: 67,
+        leechers: 12,
+        downloads: 456
+      },
+      {
+        id: 3,
+        title: '[合集] Adobe Creative Suite 2025 完整版',
+        category: 'software',
+        uploader: 'TechGuru',
+        uploadTime: '2025-06-03T08:45:00',
+        size: '12.8 GB',
+        seeders: 234,
+        leechers: 89,
+        downloads: 1205
+      }
+    ])
+    
+    onMounted(() => {
+      // 从URL参数初始化搜索条件
+      if (route.query.q) {
+        searchQuery.value = route.query.q
+      }
+      if (route.query.category) {
+        selectedCategory.value = route.query.category
+      }
+      
+      fetchTorrents()
+    })
+    
+    const fetchTorrents = async () => {
+      loading.value = true
+      try {
+        // 模拟API调用
+        await new Promise(resolve => setTimeout(resolve, 1000))
+        totalCount.value = 156
+      } catch (error) {
+        ElMessage.error('获取种子列表失败')
+      } finally {
+        loading.value = false
+      }
+    }
+    
+    const handleSearch = () => {
+      currentPage.value = 1
+      updateURL()
+      fetchTorrents()
+    }
+    
+    const handleFilter = () => {
+      currentPage.value = 1
+      updateURL()
+      fetchTorrents()
+    }
+    
+    const updateURL = () => {
+      const query = {}
+      if (searchQuery.value) query.q = searchQuery.value
+      if (selectedCategory.value) query.category = selectedCategory.value
+      if (sortBy.value !== 'upload_time') query.sort = sortBy.value
+      if (sortOrder.value !== 'desc') query.order = sortOrder.value
+      if (currentPage.value > 1) query.page = currentPage.value
+      
+      router.replace({ query })
+    }
+    
+    const handleRowClick = (row) => {
+      router.push(`/torrent/${row.id}`)
+    }
+    
+    const handleDownload = (row) => {
+      ElMessage.success(`开始下载: ${row.title}`)
+      // 这里实现下载逻辑
+    }
+    
+    const handleSizeChange = (size) => {
+      pageSize.value = size
+      currentPage.value = 1
+      fetchTorrents()
+    }
+    
+    const handleCurrentChange = (page) => {
+      currentPage.value = page
+      updateURL()
+      fetchTorrents()
+    }
+    
+    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)
+      return `${days}天前`
+    }
+    
+    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
+    }
+    
+    return {
+      loading,
+      searchQuery,
+      selectedCategory,
+      sortBy,
+      sortOrder,
+      currentPage,
+      pageSize,
+      totalCount,
+      torrents,
+      handleSearch,
+      handleFilter,
+      handleRowClick,
+      handleDownload,
+      handleSizeChange,
+      handleCurrentChange,
+      formatTime,
+      getCategoryType,
+      getCategoryName,
+      Search,
+      Upload,
+      Download,
+      User,
+      Clock,
+      Document
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.torrents-page {
+  max-width: 1200px;
+  margin: 0 auto;
+  padding: 24px;
+}
+
+.page-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 24px;
+  
+  h1 {
+    font-size: 28px;
+    font-weight: 600;
+    color: #2c3e50;
+    margin: 0;
+  }
+}
+
+.search-section {
+  background: #fff;
+  border-radius: 12px;
+  padding: 24px;
+  margin-bottom: 24px;
+  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
+  
+  .search-bar {
+    display: flex;
+    gap: 12px;
+    margin-bottom: 16px;
+    
+    .el-input {
+      flex: 1;
+    }
+  }
+  
+  .filters {
+    display: flex;
+    gap: 16px;
+    flex-wrap: wrap;
+    align-items: center;
+    
+    .el-select {
+      width: 120px;
+    }
+  }
+}
+
+.torrents-list {
+  background: #fff;
+  border-radius: 12px;
+  padding: 24px;
+  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
+  
+  .list-header {
+    margin-bottom: 16px;
+    
+    .results-count {
+      font-size: 14px;
+      color: #909399;
+    }
+  }
+  
+  .torrents-table {
+    .torrent-info {
+      .torrent-title {
+        font-size: 16px;
+        font-weight: 500;
+        color: #2c3e50;
+        margin: 0 0 8px 0;
+        line-height: 1.4;
+        cursor: pointer;
+        
+        &:hover {
+          color: #409eff;
+        }
+      }
+      
+      .torrent-meta {
+        display: flex;
+        gap: 16px;
+        font-size: 12px;
+        color: #909399;
+        
+        span {
+          display: flex;
+          align-items: center;
+          gap: 4px;
+        }
+      }
+    }
+    
+    .seeders {
+      color: #67c23a;
+      font-weight: 600;
+    }
+    
+    .leechers {
+      color: #f56c6c;
+      font-weight: 600;
+    }
+  }
+  
+  .pagination-wrapper {
+    margin-top: 24px;
+    text-align: center;
+  }
+}
+
+@media (max-width: 768px) {
+  .torrents-page {
+    padding: 16px;
+  }
+  
+  .page-header {
+    flex-direction: column;
+    gap: 16px;
+    align-items: flex-start;
+  }
+  
+  .filters {
+    flex-direction: column;
+    align-items: flex-start;
+    
+    .el-select {
+      width: 100%;
+    }
+  }
+  
+  .torrents-table {
+    :deep(.el-table__header),
+    :deep(.el-table__body) {
+      font-size: 12px;
+    }
+  }
+}
+</style>
\ No newline at end of file