Merge changes I10e91036,I4838ea80

* changes:
  求助要资源帖子相关后端
  好友相关后端
diff --git a/src/main/java/com/pt5/pthouduan/controller/FriendsListController.java b/src/main/java/com/pt5/pthouduan/controller/FriendsListController.java
new file mode 100644
index 0000000..367114b
--- /dev/null
+++ b/src/main/java/com/pt5/pthouduan/controller/FriendsListController.java
@@ -0,0 +1,65 @@
+package com.pt5.pthouduan.controller;
+
+import com.pt5.pthouduan.entity.FriendsList;
+import com.pt5.pthouduan.service.FriendsListService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.stereotype.Controller;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * <p>
+ *  好友关系前端控制器
+ * </p>
+ *
+ * 功能:添加好友、删除好友、查询好友
+ *
+ * @author ym
+ * @since 2025-04-14
+ */
+@CrossOrigin(origins = "http://localhost:5173")
+@Controller
+@RequestMapping("/friends")
+public class FriendsListController {
+
+    @Autowired
+    private FriendsListService friendsListService;
+
+    // 添加好友(只是发起请求)
+    @PostMapping("/add")
+    @ResponseBody
+    public boolean addFriend(@RequestBody FriendsList friendsList) {
+        friendsList.setRequestTime(LocalDateTime.now());
+        friendsList.setStatus("pending"); // 初始状态为申请中
+        return friendsListService.addFriend(friendsList);
+    }
+
+    // 同意好友申请
+    @PostMapping("/accept")
+    @ResponseBody
+    public boolean acceptFriend(@RequestParam Long friend1, @RequestParam Long friend2) {
+        return friendsListService.acceptFriend(friend1, friend2);
+    }
+
+    @DeleteMapping("/delete")
+    @ResponseBody
+    public boolean deleteFriendByFriends(@RequestParam Long friend1, @RequestParam Long friend2) {
+        return friendsListService.deleteFriendByFriends(friend1, friend2);
+    }
+
+    // 查询某用户的所有已通过好友
+    @GetMapping("/list/{userid}")
+    @ResponseBody
+    public List<FriendsList> getFriendsByUserId(@PathVariable Long userid) {
+        return friendsListService.getAcceptedFriendsByUserId(userid);
+    }
+
+    // (可选)查看自己收到的申请(自己是 friend2,status=pending)
+    @GetMapping("/pending/{userid}")
+    @ResponseBody
+    public List<FriendsList> getPendingRequests(@PathVariable Long userid) {
+        return friendsListService.getPendingRequests(userid);
+    }
+}
diff --git a/src/main/java/com/pt5/pthouduan/controller/RequestResourcesController.java b/src/main/java/com/pt5/pthouduan/controller/RequestResourcesController.java
new file mode 100644
index 0000000..8e730e7
--- /dev/null
+++ b/src/main/java/com/pt5/pthouduan/controller/RequestResourcesController.java
@@ -0,0 +1,184 @@
+package com.pt5.pthouduan.controller;
+
+import com.pt5.pthouduan.entity.request_resources;
+import com.pt5.pthouduan.service.RequestResourcesService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.time.LocalDateTime;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+/**
+ * <p>
+ *  求助帖信息前端控制器
+ * </p>
+ *
+ * 功能:创建求助帖、修改金额、删除、按名称/用户查找、计算某名称总金额
+ * 支持上传图片
+ *
+ * @author ym
+ * @since 2025-05-10
+ */
+@CrossOrigin(origins = "http://localhost:5174")
+@Controller
+@RequestMapping("/request")
+public class RequestResourcesController {
+
+    @Autowired
+    private RequestResourcesService requestResourcesService;
+
+    @Value("${torrent.helppost-image-dir}")
+    private String uploadDir;
+
+    // 创建新的求助帖(移除 loaduser 参数)
+    @PostMapping("/create")
+    @ResponseBody
+    public boolean createRequest(
+            @RequestParam("userid") Long userid,
+            @RequestParam("name") String name,
+            @RequestParam("plot") String plot,
+            @RequestParam("money") Integer money,
+            @RequestParam(value = "photo", required = false) MultipartFile photoFile,
+            @RequestParam(value = "year", required = false) Integer year,
+            @RequestParam(value = "country", required = false) String country
+    ) {
+        request_resources request = new request_resources();
+        request.setUserid(userid);
+        request.setLoaduser(null); // 初始为空
+        request.setName(name);
+        request.setPlot(plot);
+        request.setMoney(money);
+        request.setYear(year);
+        request.setCountry(country);
+        request.setRequestTime(LocalDateTime.now());
+
+        if (photoFile != null && !photoFile.isEmpty()) {
+            try {
+                File dir = new File(uploadDir);
+                if (!dir.exists()) {
+                    boolean created = dir.mkdirs();  // 递归创建目录
+                    if (!created) {
+                        throw new IOException("无法创建目录:" + uploadDir);
+                    }
+                }
+                //String coverImageDir = "D:/torrenttest/covers/"; // 封面图片存储目录
+                String filename = System.currentTimeMillis()+"_"+photoFile.getOriginalFilename();
+                Path helprequestImagePath = Paths.get(uploadDir, filename);
+
+                try {
+                    Files.createDirectories(helprequestImagePath.getParent()); // 创建目录
+                    Files.copy(photoFile.getInputStream(), helprequestImagePath, StandardCopyOption.REPLACE_EXISTING);
+                } catch (IOException e) {
+                    throw new RuntimeException("无法存储需求贴图片", e);
+                }
+
+                // 设置访问URL
+                request.setPhoto('/' + uploadDir + filename);
+            } catch (IOException e) {
+                e.printStackTrace();
+                return false;
+            }
+        }
+
+        return requestResourcesService.createRequest(request);
+    }
+
+    // 修改求助帖的金额
+    @PutMapping("/updateMoney/{requestid}")
+    @ResponseBody
+    public boolean updateMoney(@PathVariable Integer requestid, @RequestParam Integer money) {
+        return requestResourcesService.updateMoney(requestid, money);
+    }
+
+    // 删除求助帖
+    @DeleteMapping("/delete/{requestid}")
+    @ResponseBody
+    public boolean deleteRequest(@PathVariable Integer requestid) {
+        return requestResourcesService.deleteRequest(requestid);
+    }
+
+    // 根据名称查找求助帖
+    @GetMapping("/findByName")
+    @ResponseBody
+    public List<request_resources> findByName(@RequestParam String name) {
+        return requestResourcesService.findByName(name);
+    }
+
+    // 根据用户查找求助帖
+    @GetMapping("/findByUserid")
+    @ResponseBody
+    public List<request_resources> findByUserid(@RequestParam Long userid) {
+        return requestResourcesService.findByUserid(userid);
+    }
+
+    // 计算某个名称对应的总金额
+    @GetMapping("/totalMoneyByName")
+    @ResponseBody
+    public Integer getTotalMoneyByName(@RequestParam String name) {
+        return requestResourcesService.calculateTotalMoneyByName(name);
+    }
+
+    // 根据被协助用户(loaduser)查找求助帖
+    @GetMapping("/findByLoaduser")
+    @ResponseBody
+    public List<request_resources> findByLoaduser(@RequestParam Long loaduser) {
+        return requestResourcesService.findByLoaduser(loaduser);
+    }
+
+    // ✅ 新增:根据名称批量更新 loaduser 字段
+    @PostMapping("/updateLoaduserByName")
+    @ResponseBody
+    public boolean updateLoaduserByName(@RequestParam String name, @RequestParam Long loaduser) {
+        return requestResourcesService.updateLoaduserByName(name, loaduser);
+    }
+
+    // ✅ 1. 更新指定 requestid 的 torrentid
+    @PutMapping("/updateTorrentid/{requestid}")
+    @ResponseBody
+    public boolean updateTorrentid(@PathVariable Integer requestid, @RequestParam Long torrentid) {
+        return requestResourcesService.updateTorrentid(requestid, torrentid);
+    }
+
+    // ✅ 2. 查询指定 requestid 的 torrentid
+    @GetMapping("/getTorrentid/{requestid}")
+    @ResponseBody
+    public Long getTorrentid(@PathVariable Integer requestid) {
+        request_resources request = requestResourcesService.findByRequestid(requestid);
+        return request != null ? request.getTorrentid() : null;
+    }
+
+    @GetMapping("/info/{requestid}")
+    @ResponseBody
+    public Map<String, Object> getInfoByRequestId(@PathVariable Integer requestid) {
+        request_resources request = requestResourcesService.findByRequestid(requestid);
+        if (request == null) {
+            return null; // 或返回一个空 Map,或自定义错误处理
+        }
+
+        Map<String, Object> result = new HashMap<>();
+        result.put("torrentid", request.getTorrentid());
+        result.put("money", request.getMoney());
+        result.put("loaduser", request.getLoaduser());
+        return result;
+    }
+
+
+    @GetMapping("/all")
+    @ResponseBody
+    public List<request_resources> getAllRequests() {
+        return requestResourcesService.getAllRequests();
+    }
+
+}
diff --git a/src/main/java/com/pt5/pthouduan/entity/FriendsList.java b/src/main/java/com/pt5/pthouduan/entity/FriendsList.java
index 36c164a..6de05b8 100644
--- a/src/main/java/com/pt5/pthouduan/entity/FriendsList.java
+++ b/src/main/java/com/pt5/pthouduan/entity/FriendsList.java
@@ -11,49 +11,48 @@
  * 用户好友关系列表
  * </p>
  *
- * @author ljx
+ * @author ym
  * @since 2025-04-14
  */
-@TableName("friends_list")
+@TableName("friendslist")
 public class FriendsList implements Serializable {
 
     private static final long serialVersionUID = 1L;
 
-    @TableId(value = "relation_id", type = IdType.AUTO)
-    private Long relationId;
+    @TableId(value = "relationid", type = IdType.AUTO)
+    private Long relationid;
 
-    private Long userid;
+    private Long friend1;
 
-    private Long friendId;
+    private Long friend2;
 
     private LocalDateTime requestTime;
 
-    private String type;
+    private String status; // pending(申请中),accepted(已通过)
 
-    private String rightLevel;
 
-    public Long getRelationId() {
-        return relationId;
+    public Long getRelationid() {
+        return relationid;
     }
 
-    public void setRelationId(Long relationId) {
-        this.relationId = relationId;
+    public void setRelationid(Long relationid) {
+        this.relationid = relationid;
     }
 
-    public Long getUserid() {
-        return userid;
+    public Long getFriend1() {
+        return friend1;
     }
 
-    public void setUserid(Long userid) {
-        this.userid = userid;
+    public void setFriend1(Long friend1) {
+        this.friend1 = friend1;
     }
 
-    public Long getFriendId() {
-        return friendId;
+    public Long getFriend2() {
+        return friend2;
     }
 
-    public void setFriendId(Long friendId) {
-        this.friendId = friendId;
+    public void setFriend2(Long friend2) {
+        this.friend2 = friend2;
     }
 
     public LocalDateTime getRequestTime() {
@@ -64,31 +63,23 @@
         this.requestTime = requestTime;
     }
 
-    public String getType() {
-        return type;
+    public String getStatus() {
+        return status;
     }
 
-    public void setType(String type) {
-        this.type = type;
+    public void setStatus(String status) {
+        this.status = status;
     }
 
-    public String getRightLevel() {
-        return rightLevel;
-    }
-
-    public void setRightLevel(String rightLevel) {
-        this.rightLevel = rightLevel;
-    }
 
     @Override
     public String toString() {
         return "FriendsList{" +
-        "relationId = " + relationId +
-        ", userid = " + userid +
-        ", friendId = " + friendId +
+        "relationid = " + relationid +
+        ", friend1 = " + friend1 +
+        ", friend2 = " + friend2 +
         ", requestTime = " + requestTime +
-        ", type = " + type +
-        ", rightLevel = " + rightLevel +
+                ", status = " + status +
         "}";
     }
 }
diff --git a/src/main/java/com/pt5/pthouduan/entity/request_resources.java b/src/main/java/com/pt5/pthouduan/entity/request_resources.java
new file mode 100644
index 0000000..68800c6
--- /dev/null
+++ b/src/main/java/com/pt5/pthouduan/entity/request_resources.java
@@ -0,0 +1,163 @@
+package com.pt5.pthouduan.entity;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ *
+ * </p>
+ *
+ * @author ym
+ * @since 2025-05-10
+ */
+@TableName("request_resources")
+public class request_resources implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId("requestid")
+    private Integer requestid;
+
+    private Integer money;
+
+    private Integer year;
+
+    private String name;
+
+    private String plot;
+
+    private Long userid;
+
+    private Long loaduser;
+
+    private Long torrentid;
+
+
+    private String photo;
+
+
+    private String country;
+
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime requesttime;
+
+    public Integer getRequestid() {
+        return requestid;
+    }
+
+    public void setRequestid(Integer requestid) {
+        this.requestid = requestid;
+    }
+
+
+
+    public String getName() {//获取标签
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+
+    public String getPlot() {//获取标签
+        return plot;
+    }
+
+    public void setPlot(String plot) {
+        this.plot = plot;
+    }
+
+
+    public Long getUserid() {
+        return userid;
+    }
+
+    public void setUserid(Long userid) {
+        this.userid = userid;
+    }
+
+
+    public Long getTorrentid() {
+        return torrentid;
+    }
+
+    public void setTorrentid(Long torrentid) {
+        this.torrentid = torrentid;
+    }
+
+
+    public Long getLoaduser() {
+        return loaduser;
+    }
+
+    public void setLoaduser(Long loaduser) {
+        this.loaduser = loaduser;
+    }
+
+
+    public Integer getMoney() {
+        return money;
+    }
+
+    public void setMoney(Integer money) {
+        this.money = money;
+    }
+
+
+    public String getPhoto() {//获取标签
+        return photo;
+    }
+
+    public void setPhoto(String photo) {
+        this.photo = photo;
+    }
+
+    public Integer getYear() {
+        return year;
+    }
+
+    public void setYear(Integer year) {
+        this.year = year;
+    }
+
+    public String getCountry() {//获取标签
+        return country;
+    }
+
+    public void setCountry(String country) {
+        this.country = country;
+    }
+
+    public LocalDateTime getRequestTime() {
+        return requesttime;
+    }
+
+    public void setRequestTime(LocalDateTime requestTime) {
+        this.requesttime = requestTime;
+    }
+
+
+
+    @Override
+    public String toString() {
+        return "request_resources{" +
+                "requestid = " + requestid +
+                ", name = " + name +
+                ", plot = " + plot +
+                ", userid = " + userid +
+                ", loaduser = " + loaduser +
+                ", money = " + money +
+                ", photo = " + photo +
+                ", year = " + year +
+                ", requesttime = " + requesttime +
+                ", country='" + country + '\'' +
+                ", torrentid = " + torrentid +
+                "}";
+    }
+}
diff --git a/src/main/java/com/pt5/pthouduan/mapper/FriendsListMapper.java b/src/main/java/com/pt5/pthouduan/mapper/FriendsListMapper.java
index a6d5b56..2465af5 100644
--- a/src/main/java/com/pt5/pthouduan/mapper/FriendsListMapper.java
+++ b/src/main/java/com/pt5/pthouduan/mapper/FriendsListMapper.java
@@ -3,16 +3,43 @@
 import com.pt5.pthouduan.entity.FriendsList;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
 
 /**
  * <p>
- * 用户好友关系列表 Mapper 接口
+ *  好友关系 Mapper 接口
  * </p>
  *
- * @author ljx
+ * 功能:
+ *  - 添加好友请求
+ *  - 同意好友请求
+ *  - 删除好友
+ *  - 查询某用户所有好友
+ *  - 查询待处理的好友请求
+ *
+ * @author 杨蔓
  * @since 2025-04-14
  */
 @Mapper
 public interface FriendsListMapper extends BaseMapper<FriendsList> {
 
+    // 插入好友申请(status = "pending")
+    int insertFriendRequest(FriendsList friendsList);
+
+    // 同意好友申请(更新 status = "accepted")
+    int updateFriendStatus(@Param("friend1") Long friend1,
+                           @Param("friend2") Long friend2,
+                           @Param("status") String status);
+
+    // 删除好友(无论谁是 friend1 或 friend2)
+    int deleteByFriendPair(@Param("friend1") Long friend1,
+                           @Param("friend2") Long friend2);
+
+    // 查询某用户所有已通过好友(status = "accepted")
+    List<FriendsList> selectAcceptedFriends(@Param("userid") Long userid);
+
+    // 查询自己收到的好友请求(自己是 friend2,status = "pending")
+    List<FriendsList> selectPendingRequests(@Param("userid") Long userid);
 }
diff --git a/src/main/java/com/pt5/pthouduan/mapper/RequestResourcesMapper.java b/src/main/java/com/pt5/pthouduan/mapper/RequestResourcesMapper.java
new file mode 100644
index 0000000..e7937a8
--- /dev/null
+++ b/src/main/java/com/pt5/pthouduan/mapper/RequestResourcesMapper.java
@@ -0,0 +1,58 @@
+package com.pt5.pthouduan.mapper;
+
+import com.pt5.pthouduan.entity.request_resources;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 求助帖 Mapper 接口
+ * </p>
+ *
+ * 功能:创建、修改金额、删除、按名称/用户/被协助用户查询、统计某名称总金额
+ * 可扩展自定义 SQL
+ *
+ * @author ym
+ * @since 2025-05-10
+ */
+@Mapper
+public interface RequestResourcesMapper extends BaseMapper<request_resources> {
+
+    // 创建求助帖(可选,BaseMapper 已有 insert 方法)
+    void save(request_resources request);
+
+    // 修改求助帖金额
+    int updateMoney(@Param("requestid") Integer requestid, @Param("money") Integer money);
+
+    // 根据名称查询求助帖
+    List<request_resources> selectByName(@Param("name") String name);
+
+    // 计算某个名称对应的总金额
+    Integer sumMoneyByName(@Param("name") String name);
+
+    // 根据发帖人 ID 查询求助帖
+    List<request_resources> selectByUserid(@Param("userid") Long userid);
+
+    // 根据被协助人 ID 查询求助帖
+    List<request_resources> selectByLoaduser(@Param("loaduser") Long loaduser);
+
+    // ✅ 批量更新被协助用户 ID(loaduser)
+    int updateLoaduserByName(@Param("name") String name, @Param("loaduser") Long loaduser);
+
+    // ✅ 获取所有求助帖
+    List<request_resources> selectAllRequests();
+
+    // ✅ 1. 根据 requestid 更新 torrentid
+    int updateTorrentid(@Param("requestid") Integer requestid, @Param("torrentid") Long torrentid);
+
+    // ✅ 2. 根据 requestid 查询单个求助帖(BaseMapper 已有 selectById,但保留自定义扩展性)
+    request_resources selectByRequestid(@Param("requestid") Integer requestid);
+
+    // ✅ 3. 根据 userid + name + plot 查询唯一 request(用于获取 requestid)
+    request_resources findByUseridNamePlot(@Param("userid") Long userid,
+                                           @Param("name") String name,
+                                           @Param("plot") String plot);
+}
diff --git a/src/main/java/com/pt5/pthouduan/service/FriendsListService.java b/src/main/java/com/pt5/pthouduan/service/FriendsListService.java
new file mode 100644
index 0000000..5fade0f
--- /dev/null
+++ b/src/main/java/com/pt5/pthouduan/service/FriendsListService.java
@@ -0,0 +1,33 @@
+package com.pt5.pthouduan.service;
+
+import com.pt5.pthouduan.entity.FriendsList;
+
+import java.util.List;
+
+/**
+ * <p>
+ *  好友关系服务接口
+ * </p>
+ *
+ * 功能:
+ *  - 发起好友申请(待确认)
+ *  - 同意好友申请(状态变更)
+ *  - 删除好友
+ *  - 查询用户所有已通过好友
+ *  - 查询用户所有待确认好友请求
+ *
+ * @author 杨蔓
+ * @since 2025-04-14
+ */
+public interface FriendsListService {
+
+    boolean addFriend(FriendsList friendsList);              // 发起好友申请
+
+    boolean acceptFriend(Long friend1, Long friend2);        // 同意好友申请(状态设为 accepted)
+
+    boolean deleteFriendByFriends(Long friend1, Long friend2); // 删除好友关系
+
+    List<FriendsList> getAcceptedFriendsByUserId(Long userid); // 查询某用户的所有已通过好友
+
+    List<FriendsList> getPendingRequests(Long userid);         // 查询待确认好友请求(自己是 friend2)
+}
diff --git a/src/main/java/com/pt5/pthouduan/service/RequestResourcesService.java b/src/main/java/com/pt5/pthouduan/service/RequestResourcesService.java
new file mode 100644
index 0000000..9a8fb20
--- /dev/null
+++ b/src/main/java/com/pt5/pthouduan/service/RequestResourcesService.java
@@ -0,0 +1,44 @@
+package com.pt5.pthouduan.service;
+
+import com.pt5.pthouduan.entity.request_resources;
+
+import java.util.List;
+
+public interface RequestResourcesService {
+
+    // 创建求助帖
+    boolean createRequest(request_resources request);
+
+    // 修改求助帖金额
+    boolean updateMoney(Integer requestid, Integer money);
+
+    // 删除求助帖
+    boolean deleteRequest(Integer requestid);
+
+    // 根据名称查找求助帖
+    List<request_resources> findByName(String name);
+
+    // 计算某名称的求助帖总金额
+    Integer calculateTotalMoneyByName(String name);
+
+    // 根据发帖用户ID查找求助帖
+    List<request_resources> findByUserid(Long userid);
+
+    // 根据被协助用户ID查找求助帖
+    List<request_resources> findByLoaduser(Long loaduser);
+
+    // 根据帖子名称批量更新loaduser字段
+    boolean updateLoaduserByName(String name, Long loaduser);
+
+    // 展示所有求助帖
+    List<request_resources> getAllRequests();
+
+    // ✅ 新增:根据 requestid 更新 torrentid
+    boolean updateTorrentid(Integer requestid, Long torrentid);
+
+    // ✅ 新增:根据 requestid 查询 request 对象
+    request_resources findByRequestid(Integer requestid);
+
+    // ✅(可选)根据 userid + name + plot 查询 requestid
+    request_resources findByUseridAndNameAndPlot(Long userid, String name, String plot);
+}
diff --git a/src/main/java/com/pt5/pthouduan/service/impl/FriendsListServiceImpl.java b/src/main/java/com/pt5/pthouduan/service/impl/FriendsListServiceImpl.java
new file mode 100644
index 0000000..50d5f07
--- /dev/null
+++ b/src/main/java/com/pt5/pthouduan/service/impl/FriendsListServiceImpl.java
@@ -0,0 +1,61 @@
+package com.pt5.pthouduan.service.impl;
+
+import com.pt5.pthouduan.entity.FriendsList;
+import com.pt5.pthouduan.mapper.FriendsListMapper;
+import com.pt5.pthouduan.service.FriendsListService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * <p>
+ *  好友服务实现类
+ * </p>
+ *
+ * 功能:
+ *  - 发起好友申请
+ *  - 同意好友请求
+ *  - 删除好友
+ *  - 查询所有好友
+ *  - 查询所有待同意请求
+ *
+ * @author 杨蔓
+ * @since 2025-04-14
+ */
+@Service
+public class FriendsListServiceImpl implements FriendsListService {
+
+    @Autowired
+    private FriendsListMapper friendsListMapper;
+
+    /** 发起好友申请(status = pending) */
+    @Override
+    public boolean addFriend(FriendsList friendsList) {
+        return friendsListMapper.insertFriendRequest(friendsList) > 0;
+    }
+
+    /** 同意好友申请(更新 status = accepted) */
+    @Override
+    public boolean acceptFriend(Long friend1, Long friend2) {
+        return friendsListMapper.updateFriendStatus(friend1, friend2, "accepted") > 0;
+    }
+
+    /** 删除好友(无论谁是 friend1 或 friend2) */
+    @Override
+    public boolean deleteFriendByFriends(Long friend1, Long friend2) {
+        return friendsListMapper.deleteByFriendPair(friend1, friend2) > 0;
+    }
+
+    /** 查询某用户所有已通过的好友 */
+    @Override
+    public List<FriendsList> getAcceptedFriendsByUserId(Long userid) {
+        return friendsListMapper.selectAcceptedFriends(userid);
+    }
+
+    /** 查询所有待同意的好友申请(自己是 friend2 且 status = pending) */
+    @Override
+    public List<FriendsList> getPendingRequests(Long userid) {
+        return friendsListMapper.selectPendingRequests(userid);
+    }
+}
diff --git a/src/main/java/com/pt5/pthouduan/service/impl/RequestResourcesServiceImpl.java b/src/main/java/com/pt5/pthouduan/service/impl/RequestResourcesServiceImpl.java
new file mode 100644
index 0000000..abc23cb
--- /dev/null
+++ b/src/main/java/com/pt5/pthouduan/service/impl/RequestResourcesServiceImpl.java
@@ -0,0 +1,114 @@
+package com.pt5.pthouduan.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.pt5.pthouduan.entity.request_resources;
+import com.pt5.pthouduan.mapper.RequestResourcesMapper;
+import com.pt5.pthouduan.service.RequestResourcesService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class RequestResourcesServiceImpl implements RequestResourcesService {
+
+    @Autowired
+    private RequestResourcesMapper requestResourcesMapper;
+
+    // 创建求助帖
+    @Override
+    public boolean createRequest(request_resources request) {
+        return requestResourcesMapper.insert(request) > 0;
+    }
+
+    // 修改求助帖金额
+    @Override
+    public boolean updateMoney(Integer requestid, Integer money) {
+        request_resources request = requestResourcesMapper.selectById(requestid);
+        if (request != null) {
+            request.setMoney(money);
+            return requestResourcesMapper.updateById(request) > 0;
+        }
+        return false;
+    }
+
+    // 删除求助帖
+    @Override
+    public boolean deleteRequest(Integer requestid) {
+        return requestResourcesMapper.deleteById(requestid) > 0;
+    }
+
+    // 根据名称查找求助帖
+    @Override
+    public List<request_resources> findByName(String name) {
+        QueryWrapper<request_resources> wrapper = new QueryWrapper<>();
+        wrapper.eq("name", name);
+        return requestResourcesMapper.selectList(wrapper);
+    }
+
+    // 计算某名称的求助帖总金额
+    @Override
+    public Integer calculateTotalMoneyByName(String name) {
+        QueryWrapper<request_resources> wrapper = new QueryWrapper<>();
+        wrapper.eq("name", name).select("money");
+        List<request_resources> list = requestResourcesMapper.selectList(wrapper);
+        return list.stream()
+                .map(request_resources::getMoney)
+                .reduce(0, Integer::sum);
+    }
+
+    // 根据发帖用户ID查找求助帖
+    @Override
+    public List<request_resources> findByUserid(Long userid) {
+        QueryWrapper<request_resources> wrapper = new QueryWrapper<>();
+        wrapper.eq("userid", userid);
+        return requestResourcesMapper.selectList(wrapper);
+    }
+
+    // 根据被协助用户ID查找求助帖
+    @Override
+    public List<request_resources> findByLoaduser(Long loaduser) {
+        QueryWrapper<request_resources> wrapper = new QueryWrapper<>();
+        wrapper.eq("loaduser", loaduser);
+        return requestResourcesMapper.selectList(wrapper);
+    }
+
+    // 批量更新 loaduser
+    @Override
+    public boolean updateLoaduserByName(String name, Long loaduser) {
+        UpdateWrapper<request_resources> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.eq("name", name).set("loaduser", loaduser);
+        return requestResourcesMapper.update(null, updateWrapper) > 0;
+    }
+
+    // 获取所有求助帖
+    @Override
+    public List<request_resources> getAllRequests() {
+        return requestResourcesMapper.selectList(null);
+    }
+
+    // ✅ 新增:根据 requestid 更新 torrentid
+    @Override
+    public boolean updateTorrentid(Integer requestid, Long torrentid) {
+        UpdateWrapper<request_resources> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.eq("requestid", requestid).set("torrentid", torrentid);
+        return requestResourcesMapper.update(null, updateWrapper) > 0;
+    }
+
+    // ✅ 新增:根据 requestid 查询对象
+    @Override
+    public request_resources findByRequestid(Integer requestid) {
+        return requestResourcesMapper.selectById(requestid);
+    }
+
+    // ✅ 新增:根据 userid + name + plot 查找唯一 request(获取 requestid 用)
+    @Override
+    public request_resources findByUseridAndNameAndPlot(Long userid, String name, String plot) {
+        QueryWrapper<request_resources> wrapper = new QueryWrapper<>();
+        wrapper.eq("userid", userid)
+                .eq("name", name)
+                .eq("plot", plot);
+        return requestResourcesMapper.selectOne(wrapper);
+    }
+}
diff --git a/src/main/resources/mapper/xml/FriendsListMapper.xml b/src/main/resources/mapper/xml/FriendsListMapper.xml
new file mode 100644
index 0000000..3053fc2
--- /dev/null
+++ b/src/main/resources/mapper/xml/FriendsListMapper.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="com.pt5.pthouduan.mapper.FriendsListMapper">
+
+    <!-- 插入好友申请 -->
+    <insert id="insertFriendRequest" parameterType="com.pt5.pthouduan.entity.FriendsList">
+        INSERT INTO friendslist (relationid, friend1, friend2, requestTime, status)
+        VALUES (#{relationid}, #{friend1}, #{friend2}, #{requestTime}, #{status})
+    </insert>
+
+    <!-- 同意好友申请(更新 status) -->
+    <update id="updateFriendStatus">
+        UPDATE friendslist
+        SET status = #{status}
+        WHERE (friend1 = #{friend1} AND friend2 = #{friend2})
+           OR (friend1 = #{friend2} AND friend2 = #{friend1})
+    </update>
+
+    <!-- 删除好友关系(不区分 friend1 和 friend2) -->
+    <delete id="deleteByFriendPair">
+        DELETE FROM friendslist
+        WHERE (friend1 = #{friend1} AND friend2 = #{friend2})
+           OR (friend1 = #{friend2} AND friend2 = #{friend1})
+    </delete>
+
+    <!-- 查询某用户所有已通过好友 -->
+    <select id="selectAcceptedFriends" parameterType="long" resultType="com.pt5.pthouduan.entity.FriendsList">
+        SELECT * FROM friendslist
+        WHERE (friend1 = #{userid} OR friend2 = #{userid})
+          AND status = 'accepted'
+    </select>
+
+    <!-- 查询自己收到的好友请求(自己是 friend2 且 status = 'pending') -->
+    <select id="selectPendingRequests" parameterType="long" resultType="com.pt5.pthouduan.entity.FriendsList">
+        SELECT * FROM friendslist
+        WHERE friend2 = #{userid}
+          AND status = 'pending'
+        ORDER BY requestTime DESC
+    </select>
+
+</mapper>
diff --git a/src/main/resources/mapper/xml/RequestResourcesMapper.xml b/src/main/resources/mapper/xml/RequestResourcesMapper.xml
new file mode 100644
index 0000000..fc0d53a
--- /dev/null
+++ b/src/main/resources/mapper/xml/RequestResourcesMapper.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="com.pt5.pthouduan.mapper.RequestResourcesMapper">
+
+    <!-- 创建求助帖 -->
+    <insert id="save" parameterType="com.pt5.pthouduan.entity.request_resources">
+        INSERT INTO request_resources (userid, loaduser, name, plot, money, year, country, requesttime, photo)
+        VALUES (#{userid}, #{loaduser}, #{name}, #{plot}, #{money}, #{year}, #{country}, #{requesttime}, #{photo})
+    </insert>
+
+    <!-- 修改求助帖金额 -->
+    <update id="updateMoney">
+        UPDATE request_resources
+        SET money = #{money}
+        WHERE requestid = #{requestid}
+    </update>
+
+    <!-- 根据 requestid 更新 torrentid -->
+    <update id="updateTorrentid">
+        UPDATE request_resources
+        SET torrentid = #{torrentid}
+        WHERE requestid = #{requestid}
+    </update>
+
+    <!-- 批量更新 loaduser -->
+    <update id="updateLoaduserByName">
+        UPDATE request_resources
+        SET loaduser = #{loaduser}
+        WHERE name = #{name}
+    </update>
+
+    <!-- 根据名称查询求助帖 -->
+    <select id="selectByName" resultType="com.pt5.pthouduan.entity.request_resources">
+        SELECT * FROM request_resources
+        WHERE name = #{name}
+        ORDER BY requesttime DESC
+    </select>
+
+    <!-- 根据 userid 查询求助帖 -->
+    <select id="selectByUserid" resultType="com.pt5.pthouduan.entity.request_resources">
+        SELECT * FROM request_resources
+        WHERE userid = #{userid}
+        ORDER BY requesttime DESC
+    </select>
+
+    <!-- 根据 loaduser 查询求助帖 -->
+    <select id="selectByLoaduser" resultType="com.pt5.pthouduan.entity.request_resources">
+        SELECT * FROM request_resources
+        WHERE loaduser = #{loaduser}
+        ORDER BY requesttime DESC
+    </select>
+
+    <!-- 统计某名称的总金额 -->
+    <select id="sumMoneyByName" resultType="java.lang.Integer">
+        SELECT SUM(money) FROM request_resources
+        WHERE name = #{name}
+    </select>
+
+    <!-- 查询所有求助帖 -->
+    <select id="selectAllRequests" resultType="com.pt5.pthouduan.entity.request_resources">
+        SELECT * FROM request_resources
+        ORDER BY requesttime DESC
+    </select>
+
+    <!-- 根据 requestid 查询单条记录 -->
+    <select id="selectByRequestid" resultType="com.pt5.pthouduan.entity.request_resources">
+        SELECT * FROM request_resources
+        WHERE requestid = #{requestid}
+    </select>
+
+    <!-- 根据 userid + name + plot 查询唯一记录 -->
+    <select id="findByUseridNamePlot" resultType="com.pt5.pthouduan.entity.request_resources">
+        SELECT * FROM request_resources
+        WHERE userid = #{userid} AND name = #{name} AND plot = #{plot}
+            LIMIT 1
+    </select>
+
+</mapper>
diff --git a/src/test/java/com/pt5/pthouduan/controller/FriendsListControllerTest.java b/src/test/java/com/pt5/pthouduan/controller/FriendsListControllerTest.java
new file mode 100644
index 0000000..7c5048b
--- /dev/null
+++ b/src/test/java/com/pt5/pthouduan/controller/FriendsListControllerTest.java
@@ -0,0 +1,97 @@
+package com.pt5.pthouduan.controller;
+
+import com.pt5.pthouduan.entity.FriendsList;
+import com.pt5.pthouduan.service.FriendsListService;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.time.LocalDateTime;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+class FriendsListControllerTest {
+
+    @Mock
+    private FriendsListService friendsListService;
+
+    @InjectMocks
+    private FriendsListController friendsListController;
+
+    @BeforeEach
+    void setUp() {
+        MockitoAnnotations.openMocks(this);
+    }
+
+    @Test
+    void addFriend_ShouldReturnTrue_WhenSuccessful() {
+        FriendsList request = new FriendsList();
+        request.setFriend1(1L);
+        request.setFriend2(2L);
+
+        when(friendsListService.addFriend(any(FriendsList.class))).thenReturn(true);
+
+        boolean result = friendsListController.addFriend(request);
+
+        assertTrue(result);
+        verify(friendsListService).addFriend(any(FriendsList.class));
+    }
+
+    @Test
+    void acceptFriend_ShouldReturnTrue_WhenSuccessful() {
+        when(friendsListService.acceptFriend(1L, 2L)).thenReturn(true);
+
+        boolean result = friendsListController.acceptFriend(1L, 2L);
+
+        assertTrue(result);
+        verify(friendsListService).acceptFriend(1L, 2L);
+    }
+
+    @Test
+    void deleteFriend_ShouldReturnTrue_WhenSuccessful() {
+        when(friendsListService.deleteFriendByFriends(1L, 2L)).thenReturn(true);
+
+        boolean result = friendsListController.deleteFriendByFriends(1L, 2L);
+
+        assertTrue(result);
+        verify(friendsListService).deleteFriendByFriends(1L, 2L);
+    }
+
+    @Test
+    void getFriendsByUserId_ShouldReturnFriendList() {
+        FriendsList f1 = new FriendsList();
+        f1.setFriend1(1L);
+        f1.setFriend2(2L);
+        f1.setStatus("accepted");
+
+        when(friendsListService.getAcceptedFriendsByUserId(1L)).thenReturn(List.of(f1));
+
+        List<FriendsList> result = friendsListController.getFriendsByUserId(1L);
+
+        assertEquals(1, result.size());
+        assertEquals("accepted", result.get(0).getStatus());
+    }
+
+    @Test
+    void getPendingRequests_ShouldReturnPendingList() {
+        FriendsList pending = new FriendsList();
+        pending.setFriend1(3L);
+        pending.setFriend2(1L);
+        pending.setStatus("pending");
+        pending.setRequestTime(LocalDateTime.now());
+
+        when(friendsListService.getPendingRequests(1L)).thenReturn(Arrays.asList(pending));
+
+        List<FriendsList> result = friendsListController.getPendingRequests(1L);
+
+        assertEquals(1, result.size());
+        assertEquals("pending", result.get(0).getStatus());
+        assertEquals(3L, result.get(0).getFriend1());
+        assertEquals(1L, result.get(0).getFriend2());
+    }
+}
diff --git a/src/test/java/com/pt5/pthouduan/controller/RequestResourcesControllerTest.java b/src/test/java/com/pt5/pthouduan/controller/RequestResourcesControllerTest.java
new file mode 100644
index 0000000..322b4f9
--- /dev/null
+++ b/src/test/java/com/pt5/pthouduan/controller/RequestResourcesControllerTest.java
@@ -0,0 +1,157 @@
+package com.pt5.pthouduan.controller;
+
+import com.pt5.pthouduan.entity.request_resources;
+import com.pt5.pthouduan.service.RequestResourcesService;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+class RequestResourcesControllerTest {
+
+    @Mock
+    private RequestResourcesService requestResourcesService;
+
+    @InjectMocks
+    private RequestResourcesController requestResourcesController;
+
+    @BeforeEach
+    void setUp() {
+        MockitoAnnotations.openMocks(this);
+    }
+
+    @Test
+    void updateMoney_ShouldReturnTrue_WhenSuccess() {
+        when(requestResourcesService.updateMoney(1, 100)).thenReturn(true);
+
+        boolean result = requestResourcesController.updateMoney(1, 100);
+
+        assertTrue(result);
+        verify(requestResourcesService).updateMoney(1, 100);
+    }
+
+    @Test
+    void deleteRequest_ShouldReturnTrue_WhenSuccess() {
+        when(requestResourcesService.deleteRequest(1)).thenReturn(true);
+
+        boolean result = requestResourcesController.deleteRequest(1);
+
+        assertTrue(result);
+        verify(requestResourcesService).deleteRequest(1);
+    }
+
+    @Test
+    void findByName_ShouldReturnMatchingRequests() {
+        request_resources req = new request_resources();
+        req.setName("Urgent Help");
+
+        when(requestResourcesService.findByName("Urgent Help")).thenReturn(List.of(req));
+
+        List<request_resources> result = requestResourcesController.findByName("Urgent Help");
+
+        assertEquals(1, result.size());
+        assertEquals("Urgent Help", result.get(0).getName());
+    }
+
+    @Test
+    void findByUserid_ShouldReturnUserRequests() {
+        request_resources req = new request_resources();
+        req.setUserid(123L);
+
+        when(requestResourcesService.findByUserid(123L)).thenReturn(List.of(req));
+
+        List<request_resources> result = requestResourcesController.findByUserid(123L);
+
+        assertEquals(1, result.size());
+        assertEquals(123L, result.get(0).getUserid());
+    }
+
+    @Test
+    void getTotalMoneyByName_ShouldReturnCorrectSum() {
+        when(requestResourcesService.calculateTotalMoneyByName("Education")).thenReturn(500);
+
+        int total = requestResourcesController.getTotalMoneyByName("Education");
+
+        assertEquals(500, total);
+    }
+
+    @Test
+    void findByLoaduser_ShouldReturnLoaduserRequests() {
+        request_resources req = new request_resources();
+        req.setLoaduser(456L);
+
+        when(requestResourcesService.findByLoaduser(456L)).thenReturn(List.of(req));
+
+        List<request_resources> result = requestResourcesController.findByLoaduser(456L);
+
+        assertEquals(1, result.size());
+        assertEquals(456L, result.get(0).getLoaduser());
+    }
+
+    @Test
+    void updateLoaduserByName_ShouldReturnTrue_WhenSuccess() {
+        when(requestResourcesService.updateLoaduserByName("Medical", 789L)).thenReturn(true);
+
+        boolean result = requestResourcesController.updateLoaduserByName("Medical", 789L);
+
+        assertTrue(result);
+    }
+
+    @Test
+    void updateTorrentid_ShouldReturnTrue_WhenSuccess() {
+        when(requestResourcesService.updateTorrentid(1, 999L)).thenReturn(true);
+
+        boolean result = requestResourcesController.updateTorrentid(1, 999L);
+
+        assertTrue(result);
+    }
+
+    @Test
+    void getTorrentid_ShouldReturnCorrectValue() {
+        request_resources req = new request_resources();
+        req.setTorrentid(888L);
+
+        when(requestResourcesService.findByRequestid(1)).thenReturn(req);
+
+        Long result = requestResourcesController.getTorrentid(1);
+
+        assertEquals(888L, result);
+    }
+
+    @Test
+    void getInfoByRequestId_ShouldReturnInfoMap() {
+        request_resources req = new request_resources();
+        req.setMoney(200);
+        req.setLoaduser(101L);
+        req.setTorrentid(555L);
+
+        when(requestResourcesService.findByRequestid(1)).thenReturn(req);
+
+        var result = requestResourcesController.getInfoByRequestId(1);
+
+        assertEquals(200, result.get("money"));
+        assertEquals(101L, result.get("loaduser"));
+        assertEquals(555L, result.get("torrentid"));
+    }
+
+    @Test
+    void getAllRequests_ShouldReturnAllRequests() {
+        request_resources r1 = new request_resources();
+        r1.setRequestid(1);
+        request_resources r2 = new request_resources();
+        r2.setRequestid(2);
+
+        when(requestResourcesService.getAllRequests()).thenReturn(List.of(r1, r2));
+
+        List<request_resources> result = requestResourcesController.getAllRequests();
+
+        assertEquals(2, result.size());
+    }
+}