后端推荐系统相关接口实现

Change-Id: Ia9ec3d4edb7dc554fe36e1695f1cc7d8f58ad174
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/torrent/controller/BtTorrentController.java b/ruoyi-admin/src/main/java/com/ruoyi/torrent/controller/BtTorrentController.java
index 46345c7..c80db77 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/torrent/controller/BtTorrentController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/torrent/controller/BtTorrentController.java
@@ -6,7 +6,7 @@
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
-
+import com.ruoyi.common.utils.http.HttpUtils;
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
@@ -60,6 +60,7 @@
     private IBtTorrentFileService btTorrentFileService;
     @Autowired
     private IBtTorrentAnnounceService btTorrentAnnounceService;
+    private static final String RECOMMEND_API = "http://127.0.0.1:5000/recommend_torrents";
 
     private static final String boundary = "----WebKitFormBoundary" + UUID.randomUUID().toString().replace("-", "");
 
@@ -178,12 +179,37 @@
      * 查询种子主列表
      */
     @PreAuthorize("@ss.hasPermi('system:torrent:list')")
-    @GetMapping("/list")
-    public TableDataInfo list(BtTorrent btTorrent)
-    {
-        startPage();
-        List<BtTorrent> list = btTorrentService.selectBtTorrentList(btTorrent);
-        return getDataTable(list);
+    @PostMapping("/recommend")
+    public TableDataInfo recommendTorrents(@RequestParam("user_id") String userId) {
+        try {
+            // 1. 构造 JSON 请求体
+            String jsonRequest = "{\"user_id\": \"" + userId + "\"}";
+
+            // 2. 向 Flask 服务发 POST 请求,返回 JSON 数组
+            String jsonResponse = HttpUtils.sendPost(RECOMMEND_API, jsonRequest);
+
+            // 3. 使用 Jackson 解析 JSON 数组为 List<Long>
+            ObjectMapper mapper = new ObjectMapper();
+            List<Long> idList = mapper.readValue(jsonResponse, new TypeReference<List<Long>>() {});
+
+            // 4. 根据 ID 查询完整种子信息,并保持推荐顺序
+            List<BtTorrent> resultList = btTorrentService.selectBtTorrentsByIdsOrdered(idList);
+
+            // 5. 封装成 TableDataInfo 返回
+            TableDataInfo rsp = new TableDataInfo();
+            rsp.setCode(200);
+            rsp.setMsg("推荐成功");
+            rsp.setRows(resultList);
+            rsp.setTotal(resultList.size());
+            return rsp;
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            TableDataInfo error = new TableDataInfo();
+            error.setCode(500);
+            error.setMsg("推荐失败:" + e.getMessage());
+            return error;
+        }
     }
 
     /**
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/torrent/mapper/BtTorrentMapper.java b/ruoyi-admin/src/main/java/com/ruoyi/torrent/mapper/BtTorrentMapper.java
index 180f052..529043c 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/torrent/mapper/BtTorrentMapper.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/torrent/mapper/BtTorrentMapper.java
@@ -2,6 +2,8 @@
 
 import java.util.List;
 import com.ruoyi.torrent.domain.BtTorrent;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
 
 /**
  * 种子主Mapper接口
@@ -9,6 +11,7 @@
  * @author ruoyi
  * @date 2025-04-21
  */
+@Mapper
 public interface BtTorrentMapper 
 {
     /**
@@ -58,4 +61,12 @@
      * @return 结果
      */
     public int deleteBtTorrentByTorrentIds(Long[] torrentIds);
+
+    /**
+     * 根据ID列表查询种子信息(保持顺序)
+     *
+     * @param ids 种子ID列表
+     * @return 种子列表
+     */
+    List<BtTorrent> selectBtTorrentsByIdsOrdered(@Param("list") List<Long> ids);
 }
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/torrent/service/IBtTorrentService.java b/ruoyi-admin/src/main/java/com/ruoyi/torrent/service/IBtTorrentService.java
index e741711..f3835cf 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/torrent/service/IBtTorrentService.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/torrent/service/IBtTorrentService.java
@@ -58,4 +58,12 @@
      * @return 结果
      */
     public int deleteBtTorrentByTorrentId(Long torrentId);
+
+    /**
+     * 根据推荐ID列表查询种子信息(保持推荐顺序)
+     *
+     * @param ids 推荐的种子ID列表
+     * @return 按照推荐顺序排列的种子列表
+     */
+    List<BtTorrent> selectBtTorrentsByIdsOrdered(List<Long> ids);
 }
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/torrent/service/impl/BtTorrentServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/torrent/service/impl/BtTorrentServiceImpl.java
index 3b714f2..204eaff 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/torrent/service/impl/BtTorrentServiceImpl.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/torrent/service/impl/BtTorrentServiceImpl.java
@@ -6,6 +6,9 @@
 import com.ruoyi.torrent.mapper.BtTorrentMapper;
 import com.ruoyi.torrent.domain.BtTorrent;
 import com.ruoyi.torrent.service.IBtTorrentService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import java.util.Collections;
 
 /**
  * 种子主Service业务层处理
@@ -90,4 +93,15 @@
     {
         return btTorrentMapper.deleteBtTorrentByTorrentId(torrentId);
     }
+
+    /**
+     * 根据推荐ID列表查询种子信息(保持推荐顺序)
+     */
+    @Override
+    public List<BtTorrent> selectBtTorrentsByIdsOrdered(List<Long> ids) {
+        if (ids == null || ids.isEmpty()) {
+            return Collections.emptyList();
+        }
+        return btTorrentMapper.selectBtTorrentsByIdsOrdered(ids);
+    }
 }
diff --git a/ruoyi-admin/src/main/resources/mapper/system/BtTorrentMapper.xml b/ruoyi-admin/src/main/resources/mapper/system/BtTorrentMapper.xml
index e19128a..4f5cf3f 100644
--- a/ruoyi-admin/src/main/resources/mapper/system/BtTorrentMapper.xml
+++ b/ruoyi-admin/src/main/resources/mapper/system/BtTorrentMapper.xml
@@ -45,6 +45,19 @@
         where torrent_id = #{torrentId}
     </select>
 
+    <select id="selectBtTorrentsByIdsOrdered" resultType="BtTorrent">
+        SELECT * FROM bt_torrent
+        WHERE id IN
+        <foreach collection="list" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+        ORDER BY FIELD(id
+        <foreach collection="list" item="id" separator=",">
+            #{id}
+        </foreach>
+        )
+    </select>
+
     <insert id="insertBtTorrent" parameterType="BtTorrent" useGeneratedKeys="true" keyProperty="torrentId">
         insert into bt_torrent
         <trim prefix="(" suffix=")" suffixOverrides=",">