Merge "连接GET:search" into main
diff --git a/src/api/torrent.js b/src/api/torrent.js
index cd66464..2bde101 100644
--- a/src/api/torrent.js
+++ b/src/api/torrent.js
@@ -21,6 +21,7 @@
  * @param {Object} searchParams - 搜索参数

  * @param {string} searchParams.keyword - 搜索关键词

  * @param {string} searchParams.category - 分类

+

  * @param {string} searchParams.sortBy - 排序字段

  * @param {string} searchParams.sortOrder - 排序方向

  * @param {number} searchParams.page - 页码

@@ -28,21 +29,61 @@
  * @returns {Promise}

  */

 export function searchTorrents(searchParams) {

-  return request({

-    url: '/torrent/search',

-    method: 'post',

-    data: searchParams

-  }).catch(error => {

-    console.error('🚨 API请求失败:', {

-      url: '/torrent/search',

-      requestedURL: error.config?.url,

-      baseURL: error.config?.baseURL,

-      fullURL: error.config?.baseURL ? error.config.baseURL + error.config.url : error.config?.url,

-      status: error.response?.status,

-      statusText: error.response?.statusText

+  const hasCategory = searchParams.category 

+  

+  if (hasCategory) {

+    // 使用GET方式,支持category查询参数

+    const queryParams = new URLSearchParams()

+    

+    if (searchParams.keyword) {

+      queryParams.append('keyword', searchParams.keyword)

+    }

+    queryParams.append('entriesPerPage', searchParams.entriesPerPage || 20)

+    queryParams.append('page', searchParams.page || 0)

+    

+    // 优先使用category参数,如果没有则使用categoryId

+    const categoryValue = searchParams.category || searchParams.categoryId

+    if (categoryValue) {

+      queryParams.append('category', categoryValue)

+    }

+    

+    const url = `/torrent/search?${queryParams.toString()}`

+    console.log('🔍 使用GET方式搜索种子,URL:', url)

+    

+    return request({

+      url: url,

+      method: 'get'

+    }).catch(error => {

+      console.error('🚨 GET API请求失败:', {

+        url: url,

+        requestedURL: error.config?.url,

+        baseURL: error.config?.baseURL,

+        fullURL: error.config?.baseURL ? error.config.baseURL + error.config.url : error.config?.url,

+        status: error.response?.status,

+        statusText: error.response?.statusText

+      })

+      throw error

     })

-    throw error

-  })

+  } else {

+    // 使用POST方式,兼容原有的搜索方式

+    console.log('🔍 使用POST方式搜索种子,参数:', searchParams)

+    

+    return request({

+      url: '/torrent/search',

+      method: 'post',

+      data: searchParams

+    }).catch(error => {

+      console.error('🚨 POST API请求失败:', {

+        url: '/torrent/search',

+        requestedURL: error.config?.url,

+        baseURL: error.config?.baseURL,

+        fullURL: error.config?.baseURL ? error.config.baseURL + error.config.url : error.config?.url,

+        status: error.response?.status,

+        statusText: error.response?.statusText

+      })

+      throw error

+    })

+  }

 }

 

 /**

diff --git a/src/router/index.js b/src/router/index.js
index 9bf3278..41af4c6 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -68,7 +68,7 @@
     }

   },

   {

-    path: '/torrent/:id',

+    path: '/torrent/:infoHash',

     name: 'TorrentDetail',

     component: () => import('@/views/torrent/TorrentDetailView.vue'),

     meta: {

diff --git a/src/views/torrent/TorrentDetailView.vue b/src/views/torrent/TorrentDetailView.vue
index c8ee498..c3c367e 100644
--- a/src/views/torrent/TorrentDetailView.vue
+++ b/src/views/torrent/TorrentDetailView.vue
@@ -1,261 +1,285 @@
 <template>

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

     <div class="page-container">

-      <!-- 返回按钮 -->

-      <div class="back-button">

-        <el-button :icon="ArrowLeft" @click="$router.back()">

-          返回列表

-        </el-button>

+      <!-- 加载状态 -->

+      <div v-if="loading" class="loading-container">

+        <el-skeleton :rows="8" animated />

       </div>

 

-      <!-- 种子基本信息 -->

-      <div class="torrent-header">

-        <div class="header-content">

-          <div class="torrent-cover">

-            <el-image

-              :src="torrentInfo.coverImage || '/default-cover.jpg'"

-              :alt="torrentInfo.title"

-              fit="cover"

-              class="cover-image"

-            >

-              <template #error>

-                <div class="image-placeholder">

-                  <el-icon size="48"><Picture /></el-icon>

-                  <span>暂无封面</span>

+      <!-- 详情内容 -->

+      <div v-else-if="torrentInfo">

+        <!-- 返回按钮 -->

+        <div class="back-button">

+          <el-button :icon="ArrowLeft" @click="$router.back()">

+            返回列表

+          </el-button>

+        </div>

+

+        <!-- 种子基本信息 -->

+        <div class="torrent-header">

+          <div class="header-content">

+            <div class="torrent-cover">

+              <el-image

+                :src="torrentInfo.coverImage || '/default-cover.jpg'"

+                :alt="torrentInfo.title"

+                fit="cover"

+                class="cover-image"

+              >

+                <template #error>

+                  <div class="image-placeholder">

+                    <el-icon size="48"><Picture /></el-icon>

+                    <span>暂无封面</span>

+                  </div>

+                </template>

+              </el-image>

+            </div>

+            

+            <div class="torrent-info">

+              <div class="category-tag">

+                <el-tag :type="getCategoryType(torrentInfo.category?.slug)" size="large">

+                  {{ torrentInfo.category?.name || '未分类' }}

+                </el-tag>

+                <el-tag v-if="torrentInfo.subTitle" type="info" size="small">

+                  {{ torrentInfo.subTitle }}

+                </el-tag>

+              </div>

+              

+              <h1 class="torrent-title">{{ torrentInfo.title }}</h1>

+              

+              <div class="torrent-tags" v-if="torrentInfo.tag && torrentInfo.tag.length > 0">

+                <el-tag

+                  v-for="(tag, index) in parsedTags"

+                  :key="index"

+                  size="small"

+                  effect="plain"

+                >

+                  {{ tag }}

+                </el-tag>

+              </div>

+              

+              <div class="torrent-meta">

+                <div class="meta-item">

+                  <el-icon><User /></el-icon>

+                  <span>上传者:{{ torrentInfo.user?.username || '未知' }}</span>

                 </div>

-              </template>

-            </el-image>

-          </div>

-          

-          <div class="torrent-info">

-            <div class="category-tag">

-              <el-tag :type="getCategoryType(torrentInfo.category)" size="large">

-                {{ getCategoryName(torrentInfo.category) }}

-              </el-tag>

-              <el-tag v-if="torrentInfo.subcategory" type="info" size="small">

-                {{ torrentInfo.subcategory }}

-              </el-tag>

-            </div>

-            

-            <h1 class="torrent-title">{{ torrentInfo.title }}</h1>

-            

-            <div class="torrent-tags">

-              <el-tag

-                v-for="tag in torrentInfo.tags"

-                :key="tag"

-                size="small"

-                effect="plain"

-              >

-                {{ tag }}

-              </el-tag>

-            </div>

-            

-            <div class="torrent-meta">

-              <div class="meta-item">

-                <el-icon><User /></el-icon>

-                <span>上传者:{{ torrentInfo.uploader }}</span>

+                <div class="meta-item">

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

+                  <span>上传时间:{{ formatDateTime(torrentInfo.createdAt) }}</span>

+                </div>

+                <div class="meta-item">

+                  <el-icon><Document /></el-icon>

+                  <span>文件大小:{{ formatFileSize(torrentInfo.size) }}</span>

+                </div>

+                <div class="meta-item">

+                  <el-icon><Files /></el-icon>

+                  <span>完成次数:{{ torrentInfo.finishes }} 次</span>

+                </div>

+                <div class="meta-item">

+                  <el-icon><Star /></el-icon>

+                  <span>推广策略:{{ torrentInfo.promotionPolicy?.displayName || '默认' }}</span>

+                </div>

               </div>

-              <div class="meta-item">

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

-                <span>上传时间:{{ formatDateTime(torrentInfo.uploadTime) }}</span>

+              

+              <div class="torrent-stats">

+                <div class="stat-item seeders">

+                  <span class="stat-number">{{ peerStats.seeders }}</span>

+                  <span class="stat-label">做种</span>

+                </div>

+                <div class="stat-item leechers">

+                  <span class="stat-number">{{ peerStats.leechers }}</span>

+                  <span class="stat-label">下载</span>

+                </div>

+                <div class="stat-item downloads">

+                  <span class="stat-number">{{ torrentInfo.finishes }}</span>

+                  <span class="stat-label">完成</span>

+                </div>

               </div>

-              <div class="meta-item">

-                <el-icon><Document /></el-icon>

-                <span>文件大小:{{ torrentInfo.size }}</span>

+              

+              <div class="action-buttons">

+                <el-button 

+                  type="primary" 

+                  size="large" 

+                  :icon="Download"

+                  @click="handleDownload"

+                  :loading="downloading"

+                >

+                  {{ downloading ? '准备中...' : '下载种子' }}

+                </el-button>

+                <el-button 

+                  type="success" 

+                  size="large" 

+                  :icon="Star"

+                  @click="handleFavorite"

+                >

+                  {{ isFavorited ? '已收藏' : '收藏' }}

+                </el-button>

+                <el-button 

+                  type="warning" 

+                  size="large" 

+                  :icon="Flag"

+                  @click="handleReport"

+                >

+                  举报

+                </el-button>

               </div>

-              <div class="meta-item">

-                <el-icon><Files /></el-icon>

-                <span>文件数量:{{ torrentInfo.fileCount }} 个</span>

-              </div>

-            </div>

-            

-            <div class="torrent-stats">

-              <div class="stat-item seeders">

-                <span class="stat-number">{{ torrentInfo.seeders }}</span>

-                <span class="stat-label">做种</span>

-              </div>

-              <div class="stat-item leechers">

-                <span class="stat-number">{{ torrentInfo.leechers }}</span>

-                <span class="stat-label">下载</span>

-              </div>

-              <div class="stat-item downloads">

-                <span class="stat-number">{{ torrentInfo.downloads }}</span>

-                <span class="stat-label">完成</span>

-              </div>

-            </div>

-            

-            <div class="action-buttons">

-              <el-button 

-                type="primary" 

-                size="large" 

-                :icon="Download"

-                @click="handleDownload"

-                :loading="downloading"

-              >

-                {{ downloading ? '准备中...' : '下载种子' }}

-              </el-button>

-              <el-button 

-                type="success" 

-                size="large" 

-                :icon="Star"

-                @click="handleFavorite"

-              >

-                {{ isFavorited ? '已收藏' : '收藏' }}

-              </el-button>

-              <el-button 

-                type="warning" 

-                size="large" 

-                :icon="Flag"

-                @click="handleReport"

-              >

-                举报

-              </el-button>

             </div>

           </div>

         </div>

-      </div>

 

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

-      <div class="detail-tabs">

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

-          <!-- 种子描述 -->

-          <el-tab-pane label="详细描述" name="description">

-            <div class="description-content">

-              <div v-if="torrentInfo.description" v-html="formatDescription(torrentInfo.description)"></div>

-              <div v-else class="no-description">暂无详细描述</div>

-            </div>

-          </el-tab-pane>

-          

-          <!-- 文件列表 -->

-          <el-tab-pane label="文件列表" name="files" lazy>

-            <div class="files-list">

-              <el-table :data="torrentInfo.files" stripe>

-                <el-table-column label="文件名" prop="name" min-width="400">

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

-                    <div class="file-name">

-                      <el-icon v-if="row.type === 'folder'"><Folder /></el-icon>

-                      <el-icon v-else><Document /></el-icon>

-                      <span>{{ row.name }}</span>

-                    </div>

-                  </template>

-                </el-table-column>

-                <el-table-column label="大小" prop="size" width="120" align="right" />

-                <el-table-column label="路径" prop="path" min-width="300" />

-              </el-table>

-            </div>

-          </el-tab-pane>

-          

-          <!-- 用户活动 -->

-          <el-tab-pane label="用户活动" name="activity">

-            <div class="activity-section">

-              <div class="activity-stats">

-                <div class="stats-grid">

-                  <div class="stat-card">

-                    <h3>做种用户</h3>

-                    <p class="stat-number">{{ torrentInfo.seeders }}</p>

-                  </div>

-                  <div class="stat-card">

-                    <h3>下载用户</h3>

-                    <p class="stat-number">{{ torrentInfo.leechers }}</p>

-                  </div>

-                  <div class="stat-card">

-                    <h3>完成用户</h3>

-                    <p class="stat-number">{{ torrentInfo.downloads }}</p>

-                  </div>

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

+        <div class="detail-tabs">

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

+            <!-- 种子描述 -->

+            <el-tab-pane label="详细描述" name="description">

+              <div class="description-content">

+                <div v-if="torrentInfo.description" v-html="formatDescription(torrentInfo.description)"></div>

+                <div v-else class="no-description">暂无详细描述</div>

+              </div>

+            </el-tab-pane>

+            

+            <!-- 文件列表 -->

+            <el-tab-pane label="文件列表" name="files" lazy>

+              <div class="files-list">

+                <div v-if="torrentFiles.length > 0">

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

+                    <el-table-column label="文件名" prop="name" min-width="400">

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

+                        <div class="file-name">

+                          <el-icon v-if="row.type === 'folder'"><Folder /></el-icon>

+                          <el-icon v-else><Document /></el-icon>

+                          <span>{{ row.name }}</span>

+                        </div>

+                      </template>

+                    </el-table-column>

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

+                    <el-table-column label="路径" prop="path" min-width="300" />

+                  </el-table>

+                </div>

+                <div v-else class="no-files">

+                  <el-empty description="文件列表加载中..." />

                 </div>

               </div>

-              

-              <div class="user-lists">

-                <el-tabs v-model="activityTab" type="card">

-                  <el-tab-pane label="做种用户" name="seeders">

-                    <el-table :data="seedersList" max-height="400">

-                      <el-table-column label="用户" prop="username" />

-                      <el-table-column label="上传量" prop="uploaded" />

-                      <el-table-column label="下载量" prop="downloaded" />

-                      <el-table-column label="分享率" prop="ratio" />

-                      <el-table-column label="做种时间" prop="seedTime" />

-                    </el-table>

-                  </el-tab-pane>

-                  

-                  <el-tab-pane label="下载用户" name="leechers">

-                    <el-table :data="leechersList" max-height="400">

-                      <el-table-column label="用户" prop="username" />

-                      <el-table-column label="进度" prop="progress">

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

-                          <el-progress :percentage="row.progress" :stroke-width="6" />

-                        </template>

-                      </el-table-column>

-                      <el-table-column label="下载速度" prop="downloadSpeed" />

-                      <el-table-column label="剩余时间" prop="eta" />

-                    </el-table>

-                  </el-tab-pane>

-                </el-tabs>

-              </div>

-            </div>

-          </el-tab-pane>

-          

-          <!-- 评论区 -->

-          <el-tab-pane label="评论" name="comments">

-            <div class="comments-section">

-              <!-- 发表评论 -->

-              <div class="comment-form">

-                <el-input

-                  v-model="newComment"

-                  type="textarea"

-                  :rows="4"

-                  placeholder="发表你的评论..."

-                  maxlength="500"

-                  show-word-limit

-                />

-                <div class="comment-actions">

-                  <el-button type="primary" @click="submitComment" :loading="submittingComment">

-                    发表评论

-                  </el-button>

-                </div>

-              </div>

-              

-              <!-- 评论列表 -->

-              <div class="comments-list">

-                <div

-                  v-for="comment in comments"

-                  :key="comment.id"

-                  class="comment-item"

-                >

-                  <div class="comment-avatar">

-                    <el-avatar :size="40">{{ comment.username.charAt(0) }}</el-avatar>

-                  </div>

-                  <div class="comment-content">

-                    <div class="comment-header">

-                      <span class="comment-username">{{ comment.username }}</span>

-                      <span class="comment-time">{{ formatDateTime(comment.time) }}</span>

+            </el-tab-pane>

+            

+            <!-- 用户活动 -->

+            <el-tab-pane label="用户活动" name="activity">

+              <div class="activity-section">

+                <div class="activity-stats">

+                  <div class="stats-grid">

+                    <div class="stat-card">

+                      <h3>做种用户</h3>

+                      <p class="stat-number">{{ peerStats.seeders }}</p>

                     </div>

-                    <div class="comment-text">{{ comment.content }}</div>

-                    <div class="comment-actions">

-                      <el-button type="text" size="small" @click="likeComment(comment.id)">

-                        <el-icon><Like /></el-icon>

-                        {{ comment.likes || 0 }}

-                      </el-button>

-                      <el-button type="text" size="small" @click="replyComment(comment.id)">

-                        回复

-                      </el-button>

+                    <div class="stat-card">

+                      <h3>下载用户</h3>

+                      <p class="stat-number">{{ peerStats.leechers }}</p>

+                    </div>

+                    <div class="stat-card">

+                      <h3>完成用户</h3>

+                      <p class="stat-number">{{ torrentInfo.finishes }}</p>

                     </div>

                   </div>

                 </div>

                 

-                <div v-if="comments.length === 0" class="no-comments">

-                  暂无评论,快来发表第一条评论吧!

+                <div class="user-lists">

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

+                    <el-tab-pane label="做种用户" name="seeders">

+                      <el-table :data="seedersList" max-height="400">

+                        <el-table-column label="用户" prop="username" />

+                        <el-table-column label="上传量" prop="uploaded" />

+                        <el-table-column label="下载量" prop="downloaded" />

+                        <el-table-column label="分享率" prop="ratio" />

+                        <el-table-column label="做种时间" prop="seedTime" />

+                      </el-table>

+                    </el-tab-pane>

+                    

+                    <el-tab-pane label="下载用户" name="leechers">

+                      <el-table :data="leechersList" max-height="400">

+                        <el-table-column label="用户" prop="username" />

+                        <el-table-column label="进度" prop="progress">

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

+                            <el-progress :percentage="row.progress" :stroke-width="6" />

+                          </template>

+                        </el-table-column>

+                        <el-table-column label="下载速度" prop="downloadSpeed" />

+                        <el-table-column label="剩余时间" prop="eta" />

+                      </el-table>

+                    </el-tab-pane>

+                  </el-tabs>

                 </div>

               </div>

-            </div>

-          </el-tab-pane>

-        </el-tabs>

+            </el-tab-pane>

+            

+            <!-- 评论区 -->

+            <el-tab-pane label="评论" name="comments">

+              <div class="comments-section">

+                <!-- 发表评论 -->

+                <div class="comment-form">

+                  <el-input

+                    v-model="newComment"

+                    type="textarea"

+                    :rows="4"

+                    placeholder="发表你的评论..."

+                    maxlength="500"

+                    show-word-limit

+                  />

+                  <div class="comment-actions">

+                    <el-button type="primary" @click="submitComment" :loading="submittingComment">

+                      发表评论

+                    </el-button>

+                  </div>

+                </div>

+                

+                <!-- 评论列表 -->

+                <div class="comments-list">

+                  <div

+                    v-for="comment in comments"

+                    :key="comment.id"

+                    class="comment-item"

+                  >

+                    <div class="comment-avatar">

+                      <el-avatar :size="40">{{ comment.username.charAt(0) }}</el-avatar>

+                    </div>

+                    <div class="comment-content">

+                      <div class="comment-header">

+                        <span class="comment-username">{{ comment.username }}</span>

+                        <span class="comment-time">{{ formatDateTime(comment.time) }}</span>

+                      </div>

+                      <div class="comment-text">{{ comment.content }}</div>

+                      <div class="comment-actions">

+                        <el-button type="text" size="small" @click="likeComment(comment.id)">

+                          <el-icon><Like /></el-icon>

+                          {{ comment.likes || 0 }}

+                        </el-button>

+                        <el-button type="text" size="small" @click="replyComment(comment.id)">

+                          回复

+                        </el-button>

+                      </div>

+                    </div>

+                  </div>

+                  

+                  <div v-if="comments.length === 0" class="no-comments">

+                    暂无评论,快来发表第一条评论吧!

+                  </div>

+                </div>

+              </div>

+            </el-tab-pane>

+          </el-tabs>

+        </div>

+      </div>

+

+      <!-- 错误状态 -->

+      <div v-else class="error-container">

+        <el-empty description="种子信息加载失败">

+          <el-button type="primary" @click="retry">重试</el-button>

+        </el-empty>

       </div>

     </div>

   </div>

 </template>

 

 <script>

-import { ref, onMounted } from 'vue'

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

 import { useRoute, useRouter } from 'vue-router'

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

 import {

@@ -271,6 +295,7 @@
   Folder,

   Like

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

+import axios from 'axios'

 

 export default {

   name: 'TorrentDetailView',

@@ -278,6 +303,7 @@
     const route = useRoute()

     const router = useRouter()

     

+    const loading = ref(true)

     const activeTab = ref('description')

     const activityTab = ref('seeders')

     const downloading = ref(false)

@@ -285,101 +311,140 @@
     const submittingComment = ref(false)

     const newComment = ref('')

     

-    const torrentInfo = ref({

-      id: 1,

-      title: '[4K蓝光原盘] 阿凡达:水之道 Avatar: The Way of Water (2022)',

-      category: 'movie',

-      subcategory: '科幻片',

-      uploader: 'MovieMaster',

-      uploadTime: '2025-06-03T10:30:00',

-      size: '85.6 GB',

-      fileCount: 125,

-      seeders: 128,

-      leechers: 45,

-      downloads: 892,

-      coverImage: 'https://example.com/avatar2-cover.jpg',

-      tags: ['4K', '蓝光原盘', '科幻', '詹姆斯·卡梅隆'],

-      description: `

-        <h3>影片信息</h3>

-        <p><strong>片名:</strong>阿凡达:水之道 / Avatar: The Way of Water</p>

-        <p><strong>年份:</strong>2022</p>

-        <p><strong>导演:</strong>詹姆斯·卡梅隆</p>

-        <p><strong>主演:</strong>萨姆·沃辛顿 / 佐伊·索尔达娜 / 西格妮·韦弗</p>

-        <p><strong>类型:</strong>科幻 / 动作 / 冒险</p>

-        <p><strong>制片国家/地区:</strong>美国</p>

-        <p><strong>语言:</strong>英语</p>

-        <p><strong>上映日期:</strong>2022-12-16</p>

-        <p><strong>片长:</strong>192分钟</p>

-        

-        <h3>影片简介</h3>

-        <p>杰克·萨利和奈蒂莉组建了家庭,他们的孩子也逐渐成长。当危险威胁到他们时,杰克和奈蒂莉必须为彼此而战,为家庭而战,为生存而战。</p>

-        

-        <h3>技术规格</h3>

-        <ul>

-          <li>视频:4K UHD 2160p / HEVC / HDR10</li>

-          <li>音频:Dolby Atmos TrueHD 7.1 / DTS-HD MA 7.1</li>

-          <li>字幕:中文 / 英文</li>

-          <li>片源:4K UHD 蓝光原盘</li>

-        </ul>

-        

-        <h3>下载说明</h3>

-        <p>本资源为4K蓝光原盘,保持了最高的画质和音质。建议使用支持4K播放的设备观看。</p>

-      `,

-      files: [

-        { name: 'BDMV', type: 'folder', size: '85.6 GB', path: '/' },

-        { name: 'CERTIFICATE', type: 'folder', size: '2.1 MB', path: '/' },

-        { name: 'Avatar.The.Way.of.Water.2022.2160p.UHD.Blu-ray.x265.HDR.Atmos-DETAIL.mkv', type: 'file', size: '32.8 GB', path: '/BDMV/STREAM/' },

-        { name: 'Avatar.The.Way.of.Water.2022.Extras.mkv', type: 'file', size: '12.4 GB', path: '/BDMV/STREAM/' }

-      ]

+    const torrentInfo = ref(null)

+    const torrentFiles = ref([])

+    const peerStats = ref({

+      seeders: 0,

+      leechers: 0

     })

     

-    const seedersList = ref([

-      { username: 'SeedMaster', uploaded: '2.5 TB', downloaded: '850 GB', ratio: '3.02', seedTime: '15天' },

-      { username: 'MovieFan88', uploaded: '1.8 TB', downloaded: '1.2 TB', ratio: '1.50', seedTime: '8天' },

-      { username: 'CinemaLover', uploaded: '3.2 TB', downloaded: '900 GB', ratio: '3.56', seedTime: '22天' }

-    ])

+    const seedersList = ref([])

+    const leechersList = ref([])

+    const comments = ref([])

     

-    const leechersList = ref([

-      { username: 'NewUser123', progress: 65, downloadSpeed: '15.2 MB/s', eta: '2小时15分' },

-      { username: 'MovieSeeker', progress: 23, downloadSpeed: '8.7 MB/s', eta: '8小时32分' },

-      { username: 'FilmCollector', progress: 89, downloadSpeed: '22.1 MB/s', eta: '45分钟' }

-    ])

-    

-    const comments = ref([

-      {

-        id: 1,

-        username: 'MovieReviewer',

-        content: '画质非常棒!4K HDR效果惊艳,水下场景美不胜收。感谢分享!',

-        time: '2025-06-03T12:00:00',

-        likes: 15

-      },

-      {

-        id: 2,

-        username: 'CinemaExpert',

-        content: '音效也很棒,Dolby Atmos的环绕效果让人身临其境。推荐大家下载!',

-        time: '2025-06-03T11:30:00',

-        likes: 8

+    // 解析标签

+    const parsedTags = computed(() => {

+      if (!torrentInfo.value?.tag || !Array.isArray(torrentInfo.value.tag)) {

+        return []

       }

-    ])

+      

+      const tags = []

+      torrentInfo.value.tag.forEach(tagString => {

+        try {

+          const parsed = JSON.parse(tagString)

+          if (Array.isArray(parsed)) {

+            tags.push(...parsed)

+          } else {

+            tags.push(parsed)

+          }

+        } catch (e) {

+          tags.push(tagString)

+        }

+      })

+      return tags

+    })

     

     onMounted(() => {

-      const torrentId = route.params.id

-      fetchTorrentDetail(torrentId)

+      const infoHash = route.params.infoHash || route.params.id

+      if (infoHash) {

+        fetchTorrentDetail(infoHash)

+      } else {

+        ElMessage.error('缺少种子标识符')

+        router.back()

+      }

     })

     

-    const fetchTorrentDetail = async (id) => {

+    const fetchTorrentDetail = async (infoHash) => {

       try {

-        // 模拟API调用

-        console.log('获取种子详情:', id)

-        // 这里应该调用真实的API

+        loading.value = true

+        

+        // 获取种子详情

+        const response = await axios.get(`http://localhost:8081/api/torrent/view/${infoHash}`)

+        

+        if (response.data.code === 0) {

+          torrentInfo.value = response.data

+          

+          // 获取文件列表(如果有相关API)

+          await fetchTorrentFiles(infoHash)

+          

+          // 获取用户活动数据(如果有相关API)

+          await fetchPeerStats(infoHash)

+          

+          // 获取评论(如果有相关API)

+          await fetchComments(infoHash)

+        } else {

+          throw new Error(response.data.message || '获取种子详情失败')

+        }

       } catch (error) {

-        ElMessage.error('获取种子详情失败')

-        router.back()

+        console.error('获取种子详情失败:', error)

+        ElMessage.error(error.message || '获取种子详情失败')

+        torrentInfo.value = null

+      } finally {

+        loading.value = false

       }

     }

     

-    const formatDateTime = (dateString) => {

-      const date = new Date(dateString)

+    const fetchTorrentFiles = async (infoHash) => {

+      try {

+        // 这里应该调用获取文件列表的API

+        // const response = await axios.get(`http://localhost:8081/api/torrent/${infoHash}/files`)

+        // torrentFiles.value = response.data

+        

+        // 临时模拟数据

+        torrentFiles.value = [

+          { 

+            name: 'example_file.iso', 

+            type: 'file', 

+            size: formatFileSize(torrentInfo.value?.size || 0), 

+            path: '/' 

+          }

+        ]

+      } catch (error) {

+        console.error('获取文件列表失败:', error)

+      }

+    }

+    

+    const fetchPeerStats = async (infoHash) => {

+      try {

+        // 这里应该调用获取用户活动数据的API

+        // const response = await axios.get(`http://localhost:8081/api/torrent/${infoHash}/peers`)

+        // peerStats.value = response.data

+        

+        // 临时模拟数据

+        peerStats.value = {

+          seeders: Math.floor(Math.random() * 50) + 10,

+          leechers: Math.floor(Math.random() * 30) + 5

+        }

+        

+        // 模拟用户列表

+        seedersList.value = [

+          { username: 'SeedMaster', uploaded: '2.5 TB', downloaded: '850 GB', ratio: '3.02', seedTime: '15天' }

+        ]

+        

+        leechersList.value = [

+          { username: 'NewUser123', progress: 65, downloadSpeed: '15.2 MB/s', eta: '2小时15分' }

+        ]

+      } catch (error) {

+        console.error('获取用户活动数据失败:', error)

+      }

+    }

+    

+    const fetchComments = async (infoHash) => {

+      try {

+        // 这里应该调用获取评论的API

+        // const response = await axios.get(`http://localhost:8081/api/torrent/${infoHash}/comments`)

+        // comments.value = response.data

+        

+        // 临时模拟数据

+        comments.value = []

+      } catch (error) {

+        console.error('获取评论失败:', error)

+      }

+    }

+    

+    const formatDateTime = (timestamp) => {

+      if (!timestamp) return '未知'

+      const date = new Date(timestamp)

       return date.toLocaleString('zh-CN', {

         year: 'numeric',

         month: '2-digit',

@@ -389,47 +454,57 @@
       })

     }

     

+    const formatFileSize = (bytes) => {

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

+      

+      const k = 1024

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

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

+      

+      return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]

+    }

+    

     const formatDescription = (description) => {

-      // 简单的HTML清理,实际项目中应该使用专门的库

+      if (!description) return ''

       return description.replace(/\n/g, '<br>')

     }

     

-    const getCategoryType = (category) => {

+    const getCategoryType = (categorySlug) => {

       const types = {

+        'os': 'primary',

         '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 types[categorySlug] || 'default'

     }

     

     const handleDownload = async () => {

+      if (!torrentInfo.value) return

+      

       downloading.value = true

       try {

-        // 模拟下载准备过程

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

+        // 这里应该调用下载种子文件的API

+        const response = await axios.get(

+          `http://localhost:8081/api/torrent/download/${torrentInfo.value.infoHash}`,

+          { responseType: 'blob' }

+        )

         

-        // 实际项目中这里应该下载.torrent文件

+        // 创建下载链接

+        const url = window.URL.createObjectURL(new Blob([response.data]))

         const link = document.createElement('a')

-        link.href = '#' // 实际的种子文件下载链接

+        link.href = url

         link.download = `${torrentInfo.value.title}.torrent`

+        document.body.appendChild(link)

         link.click()

+        document.body.removeChild(link)

+        window.URL.revokeObjectURL(url)

         

         ElMessage.success('种子文件下载完成')

       } catch (error) {

+        console.error('下载失败:', error)

         ElMessage.error('下载失败,请稍后重试')

       } finally {

         downloading.value = false

@@ -464,7 +539,12 @@
       

       submittingComment.value = true

       try {

-        // 模拟提交评论

+        // 这里应该调用提交评论的API

+        // await axios.post(`http://localhost:8081/api/torrent/${torrentInfo.value.infoHash}/comments`, {

+        //   content: newComment.value

+        // })

+        

+        // 模拟提交

         await new Promise(resolve => setTimeout(resolve, 1000))

         

         const comment = {

@@ -480,6 +560,7 @@
         

         ElMessage.success('评论发表成功')

       } catch (error) {

+        console.error('发表评论失败:', error)

         ElMessage.error('发表评论失败')

       } finally {

         submittingComment.value = false

@@ -495,11 +576,18 @@
     }

     

     const replyComment = (commentId) => {

-      // 实现回复功能

       ElMessage.info('回复功能开发中...')

     }

     

+    const retry = () => {

+      const infoHash = route.params.infoHash || route.params.id

+      if (infoHash) {

+        fetchTorrentDetail(infoHash)

+      }

+    }

+    

     return {

+      loading,

       activeTab,

       activityTab,

       downloading,

@@ -507,19 +595,23 @@
       submittingComment,

       newComment,

       torrentInfo,

+      torrentFiles,

+      peerStats,

+      parsedTags,

       seedersList,

       leechersList,

       comments,

       formatDateTime,

+      formatFileSize,

       formatDescription,

       getCategoryType,

-      getCategoryName,

       handleDownload,

       handleFavorite,

       handleReport,

       submitComment,

       likeComment,

       replyComment,

+      retry,

       ArrowLeft,

       Download,

       Star,

@@ -545,6 +637,13 @@
   min-height: 100vh;

 }

 

+.loading-container, .error-container {

+  background: #fff;

+  border-radius: 12px;

+  padding: 40px;

+  text-align: center;

+}

+

 .back-button {

   margin-bottom: 16px;

 }

@@ -645,16 +744,17 @@
             font-size: 24px;

             font-weight: 600;

             margin-bottom: 4px;

-            

-            &.seeders { color: #67c23a; }

-            &.leechers { color: #f56c6c; }

-            &.downloads { color: #409eff; }

+            color: #2c3e50;

           }

           

           .stat-label {

             font-size: 14px;

             color: #909399;

           }

+          

+          &.seeders .stat-number { color: #67c23a; }

+          &.leechers .stat-number { color: #f56c6c; }

+          &.downloads .stat-number { color: #409eff; }

         }

       }

       

@@ -722,6 +822,10 @@
         color: #909399;

       }

     }

+    

+    .no-files {

+      padding: 40px 0;

+    }

   }

   

   .activity-section {

@@ -859,4 +963,4 @@
     gap: 12px;

   }

 }

-</style>
\ No newline at end of file
+</style>

diff --git a/src/views/torrent/TorrentsView.vue b/src/views/torrent/TorrentsView.vue
index 28b73f1..736c92d 100644
--- a/src/views/torrent/TorrentsView.vue
+++ b/src/views/torrent/TorrentsView.vue
@@ -27,10 +27,9 @@
       
       <div class="filters">
         <el-select v-model="selectedCategory" placeholder="分类" @change="handleFilter">
-          <el-option label="全部" value="" />
           <el-option
-            v-for="category in categories"
-            :key="category.id"
+            v-for="category in categoryOptions"
+            :key="category.slug"
             :label="category.name"
             :value="category.slug"
           />
@@ -155,7 +154,7 @@
 </template>
 
 <script>
-import { ref, onMounted, watch } from 'vue'
+import { ref, onMounted, watch, computed } from 'vue'
 import { useRouter, useRoute } from 'vue-router'
 import { ElMessage } from 'element-plus'
 import {
@@ -206,39 +205,33 @@
     const fetchTorrents = async () => {
       loading.value = true
       try {
-        const searchParams = {
-          keyword: searchQuery.value || '', // 搜索关键词
-          //category: selectedCategory.value || '',
-          page: currentPage.value - 1,      // 后端页码从0开始
-          entriesPerPage: pageSize.value    // 每页显示数量
-        }
+        if (selectedCategory.value) {
+          // 使用 GET 请求
+          const response = await fetch(`/api/torrent/search?category=${selectedCategory.value}`)
+        .then(res => res.json())
 
-        console.log('🔍 发送搜索请求,参数:', searchParams)
-        
-        const response = await searchTorrents(searchParams)
-
-        console.log('✅ 接收到响应:', response)
-        
-        if (response) {  // response直接就是数据
           torrents.value = response.torrents || []
           totalCount.value = response.totalElements || 0
           totalPages.value = response.totalPages || 1
-          
-          console.log('📊 处理后的数据:', {
-            torrentsCount: torrents.value.length,
-            totalCount: totalCount.value,
-            firstTorrent: torrents.value[0]
-          })
+
+        } else {
+          // 使用 POST 请求(搜索)
+          const searchParams = {
+            keyword: searchQuery.value || '',
+            page: currentPage.value - 1,
+            entriesPerPage: pageSize.value
+          }
+
+          const response = await searchTorrents(searchParams)
+
+          torrents.value = response.torrents || []
+          totalCount.value = response.totalElements || 0
+          totalPages.value = response.totalPages || 1
         }
+
       } catch (error) {
         console.error('获取种子列表失败:', error)
-        console.error('📝 错误详情:', {
-          message: error.message,
-          status: error.response?.status,
-          data: error.response?.data
-        })
-        ElMessage.error(`获取种子列表失败: ${error.response?.data?.message || error.message}`)
-        // 如果请求失败,清空数据
+        ElMessage.error('获取种子列表失败')
         torrents.value = []
         totalCount.value = 0
       } finally {
@@ -249,10 +242,14 @@
     const fetchCategories = async () => {
       try {
         const response = await getCategories()
+        console.log('分类列表响应:', response)
+        
         if (response && Array.isArray(response)) {
           categories.value = response
+          console.log('分类列表加载成功:', categories.value)
         } else {
           console.error('获取分类列表失败: 响应格式错误', response)
+          ElMessage.warning('分类列表格式不正确')
         }
       } catch (error) {
         console.error('获取分类列表失败:', error)
@@ -345,6 +342,13 @@
       return types[category.slug] || ''
     }
     
+    const categoryOptions = computed(() => {
+      return [
+        { id: '', name: '全部' },
+        ...categories.value
+      ]
+    })
+    
     return {
       loading,
       searchQuery,
@@ -356,6 +360,7 @@
       totalCount,
       torrents,
       categories,
+      categoryOptions,
       handleSearch,
       handleFilter,
       handleRowClick,