Merge changes I3c13243a,I4eb3223e,I81fa2661,I7e8b26d4,Ib28dc79d

* changes:
  举报相关上传
  对话相关上传
  公告相关上传
  global图片路径上传
  帖子post重提交
diff --git a/src/main/java/com/pt5/pthouduan/config/GlobalCorsConfig.java b/src/main/java/com/pt5/pthouduan/config/GlobalCorsConfig.java
new file mode 100644
index 0000000..f11baff
--- /dev/null
+++ b/src/main/java/com/pt5/pthouduan/config/GlobalCorsConfig.java
@@ -0,0 +1,19 @@
+package com.pt5.pthouduan.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.*;
+
+@Configuration
+public class GlobalCorsConfig implements WebMvcConfigurer {
+
+    @Override
+    public void addCorsMappings(CorsRegistry registry) {
+        registry.addMapping("/**") // 匹配所有请求路径
+                .allowedOriginPatterns("*") // 支持通配符的来源
+                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 支持的方法
+                .allowedHeaders("*") // 允许的请求头
+                .allowCredentials(true) // 是否允许携带 cookie
+                .maxAge(3600); // 预检请求的缓存时间
+    }
+}
diff --git a/src/main/java/com/pt5/pthouduan/controller/ActivityController.java b/src/main/java/com/pt5/pthouduan/controller/ActivityController.java
new file mode 100644
index 0000000..5a60a24
--- /dev/null
+++ b/src/main/java/com/pt5/pthouduan/controller/ActivityController.java
@@ -0,0 +1,160 @@
+package com.pt5.pthouduan.controller;
+
+import com.pt5.pthouduan.entity.Activity;
+import com.pt5.pthouduan.service.ActivityService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.File;
+import java.io.IOException;
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+/**
+ * <p>
+ * 活动控制器
+ * </p>
+ *
+ * 功能:增删改查活动公告(支持上传图片)
+ *
+ * @author ym
+ * @since 2025-05-16
+ */
+@CrossOrigin(origins = {"http://localhost:5173", "http://localhost:3000"})
+@Controller
+@RequestMapping("/activity")
+public class ActivityController {
+
+    @Autowired
+    private ActivityService activityService;
+
+    // 获取所有 is_show == 0 的活动标题和图片(活动预览)
+    @GetMapping("/preview")
+    @ResponseBody
+    public List<Activity> getVisibleActivityPreviews() {
+        List<Activity> allVisible = activityService.findByIsShow(0);
+        return allVisible.stream().map(activity -> {
+            Activity preview = new Activity();
+            preview.setActivityid(activity.getActivityid());
+            preview.setContent(activity.getContent());
+            preview.setTitle(activity.getTitle());
+            preview.setAward(activity.getAward());
+            preview.setTime(activity.getTime());
+            preview.setPhoto(activity.getPhoto());
+            return preview;
+        }).collect(Collectors.toList());
+    }
+
+    // 获取所有 is_show == 0 的完整活动信息
+    @GetMapping("/full")
+    @ResponseBody
+    public List<Activity> getVisibleActivities() {
+        return activityService.findByIsShow(0);
+    }
+
+    // 创建新的公告(支持图片上传)
+    @PostMapping("/create")
+    @ResponseBody
+    public boolean createActivity(
+            @RequestParam("title") String title,
+            @RequestParam("content") String content,
+            @RequestParam(value = "photo", required = false) MultipartFile photoFile,
+            @RequestParam(value = "isShow", required = false, defaultValue = "0") Integer isShow,
+            @RequestParam(value = "award", required = false, defaultValue = "0") Integer award
+    ) {
+        Activity activity = new Activity();
+        activity.setTitle(title);
+        activity.setContent(content);
+        activity.setIs_show(isShow);
+        activity.setAward(award);
+        activity.setTime(LocalDateTime.now()); // 设置当前时间
+
+        // 处理图片上传
+        if (photoFile != null && !photoFile.isEmpty()) {
+            String uploadDir = "D:/activityuploads/";
+            File dir = new File(uploadDir);
+            if (!dir.exists()) dir.mkdirs();
+
+            String fileName = UUID.randomUUID() + "_" + photoFile.getOriginalFilename();
+            File dest = new File(uploadDir + fileName);
+            try {
+                photoFile.transferTo(dest);
+                // 设置图片访问路径(请确保 /images 映射到了 uploadDir)
+                activity.setPhoto("/activity/" + fileName);
+            } catch (IOException e) {
+                e.printStackTrace();
+                return false;
+            }
+        }
+
+        return activityService.save(activity);
+    }
+
+
+    // 删除公告(根据ID)
+    @DeleteMapping("/delete/{id}")
+    @ResponseBody
+    public boolean deleteActivity(@PathVariable Integer id) {
+        return activityService.removeById(id);
+    }
+
+    // 获取所有活动(无论展示状态)
+    @GetMapping("/all")
+    @ResponseBody
+    public List<Activity> getAllActivities() {
+        // 假设 activityService 有 list() 方法,返回所有活动
+        return activityService.list();
+    }
+
+    //根据题目搜索公告
+    @GetMapping("/search")
+    @ResponseBody
+    public List<Activity> searchActivitiesByTitle(@RequestParam("title") String title) {
+        return activityService.searchByTitle(title);
+    }
+
+    // 修改公告(根据ID)
+    @PutMapping("/update")
+    @ResponseBody
+    public boolean updateActivity(
+            @RequestParam("activityid") Integer id,
+            @RequestParam("title") String title,
+            @RequestParam("content") String content,
+            @RequestParam(value = "photo", required = false) MultipartFile photoFile,
+            @RequestParam(value = "isShow", required = false, defaultValue = "0") Integer isShow,
+            @RequestParam(value = "award", required = false, defaultValue = "0") Integer award
+    ) {
+        Activity activity = activityService.getById(id);
+        if (activity == null) {
+            return false;
+        }
+
+        activity.setTitle(title);
+        activity.setContent(content);
+        activity.setIs_show(isShow);
+        activity.setAward(award);
+
+        // 上传新图片(可选)
+        if (photoFile != null && !photoFile.isEmpty()) {
+            String uploadDir = "D:/activityuploads/";
+            File dir = new File(uploadDir);
+            if (!dir.exists()) dir.mkdirs();
+
+            String fileName = UUID.randomUUID() + "_" + photoFile.getOriginalFilename();
+            File dest = new File(uploadDir + fileName);
+            try {
+                photoFile.transferTo(dest);
+                activity.setPhoto("/activity/" + fileName);
+            } catch (IOException e) {
+                e.printStackTrace();
+                return false;
+            }
+        }
+
+        return activityService.updateById(activity);
+    }
+}
diff --git a/src/main/java/com/pt5/pthouduan/controller/ChatInformationController.java b/src/main/java/com/pt5/pthouduan/controller/ChatInformationController.java
new file mode 100644
index 0000000..81756a6
--- /dev/null
+++ b/src/main/java/com/pt5/pthouduan/controller/ChatInformationController.java
@@ -0,0 +1,58 @@
+package com.pt5.pthouduan.controller;
+
+import com.pt5.pthouduan.entity.ChatInformation;
+import com.pt5.pthouduan.service.ChatInformationService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.stereotype.Controller;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 聊天记录前端控制器
+ * </p>
+ *
+ * 功能:添加聊天记录、删除聊天记录、查询用户与所有人的聊天、查询两个用户之间的聊天
+ *
+ * @author 杨蔓
+ * @since 2025-06-03
+ */
+@CrossOrigin(origins = {"http://localhost:5173", "http://localhost:3000"})
+@Controller
+@RequestMapping("/chat")
+public class ChatInformationController {
+
+    @Autowired
+    private ChatInformationService chatInformationService;
+
+    // 创建聊天记录
+    @PostMapping("/create")
+    @ResponseBody
+    public ChatInformation createChat(@RequestBody ChatInformation chatInformation) {
+        return chatInformationService.createChat(chatInformation);
+    }
+
+    // 删除聊天记录(根据信息ID)
+    @DeleteMapping("/delete/{informationid}")
+    @ResponseBody
+    public String deleteChat(@PathVariable Integer informationid) {
+        boolean deleted = chatInformationService.deleteChatById(informationid);
+        return deleted ? "删除成功" : "删除失败";
+    }
+
+    // 获取某个用户与所有人的聊天记录(作为发送者或接收者)
+    @GetMapping("/user/{userId}")
+    @ResponseBody
+    public List<ChatInformation> getChatsByUser(@PathVariable Long userId) {
+        return chatInformationService.getChatsByUser(userId);
+    }
+
+    // 获取两个用户之间的聊天记录
+    @GetMapping("/between")
+    @ResponseBody
+    public List<ChatInformation> getChatsBetweenUsers(@RequestParam Long user1,
+                                                      @RequestParam Long user2) {
+        return chatInformationService.getChatsBetweenUsers(user1, user2);
+    }
+}
diff --git a/src/main/java/com/pt5/pthouduan/controller/ComplainController.java b/src/main/java/com/pt5/pthouduan/controller/ComplainController.java
new file mode 100644
index 0000000..45ef0e2
--- /dev/null
+++ b/src/main/java/com/pt5/pthouduan/controller/ComplainController.java
@@ -0,0 +1,78 @@
+package com.pt5.pthouduan.controller;
+
+import com.pt5.pthouduan.entity.Complain;
+import com.pt5.pthouduan.service.ComplainService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.stereotype.Controller;
+
+import java.util.List;
+
+/**
+ * <p>
+ *  投诉前端控制器
+ * </p>
+ *
+ * 功能:增、删、改、查(按被投诉用户ID)
+ *
+ * @author ym
+ * @since 2025-04-14
+ */
+@CrossOrigin(origins = {"http://localhost:5173", "http://localhost:3000"})
+@Controller
+@RequestMapping("/complain")
+public class ComplainController {
+
+    @Autowired
+    private ComplainService complainService;
+
+    // 创建投诉
+    @PostMapping("/create")
+    @ResponseBody
+    public Complain createComplain(@RequestBody Complain complain) {
+        System.out.println("Received complain: " + complain);  // 输出接收到的投诉数据
+        return complainService.createComplain(complain);
+    }
+
+    // 删除投诉(根据complainid)
+    @DeleteMapping("/delete/{complainid}")
+    @ResponseBody
+    public boolean deleteComplain(@PathVariable Integer complainid) {
+        return complainService.deleteComplain(complainid);
+    }
+
+    // 更新投诉内容
+    @PutMapping("/update")
+    @ResponseBody
+    public boolean updateComplain(@RequestBody Complain complain) {
+        return complainService.updateComplain(complain);
+    }
+
+    // 获取某个用户被投诉的所有记录(根据duser)
+    @GetMapping("/target/{duser}")
+    @ResponseBody
+    public List<Complain> getComplainsByTargetUser(@PathVariable Long duser) {
+        return complainService.getComplainsByTargetUser(duser);
+    }
+
+    // 获取某个用户提交的所有投诉记录(根据puse)
+    @GetMapping("/from/{puse}")
+    @ResponseBody
+    public List<Complain> getComplainsByPostingUser(@PathVariable Long puse) {
+        return complainService.getComplainsByPostingUser(puse);
+    }
+
+    // 获取所有投诉记录(管理员查看用)
+    @GetMapping("/all")
+    @ResponseBody
+    public List<Complain> getAllComplains() {
+        return complainService.getAllComplains();
+    }
+
+    // 根据投诉号获取对应的投诉人、被投诉人和种子号
+    @GetMapping("/info/{complainid}")
+    @ResponseBody
+    public Complain getComplainInfo(@PathVariable Integer complainid) {
+        return complainService.getComplainById(complainid);
+    }
+}
diff --git a/src/main/java/com/pt5/pthouduan/controller/PostController.java b/src/main/java/com/pt5/pthouduan/controller/PostController.java
index a3a9017..c497d87 100644
--- a/src/main/java/com/pt5/pthouduan/controller/PostController.java
+++ b/src/main/java/com/pt5/pthouduan/controller/PostController.java
@@ -23,7 +23,7 @@
  * @author
  * @since 2025-05-10
  */
-@CrossOrigin(origins = "http://localhost:5173")
+@CrossOrigin(origins = {"http://localhost:5173", "http://localhost:3000"})
 @Controller
 @RequestMapping("/post")
 public class PostController {
@@ -49,7 +49,7 @@
         post.setPostContent(post_content);
         post.setTags(tags);
         post.setRannge(rannge);
-        post.setIsSticky(is_pinned != null && is_pinned);
+        post.setIsPinned(is_pinned != null && is_pinned);
         post.setPostCreatedTime(LocalDateTime.now());
         post.setUpdatedTime(LocalDateTime.now());
         post.setLikes(0);
@@ -146,4 +146,18 @@
     public List<Post> findPinnedPosts() {
         return postService.findPinnedPosts();
     }
+
+   
+
+    // 添加切换置顶状态的新端点
+    @PutMapping("/togglePin/{postid}")
+    @ResponseBody
+    public Boolean togglePinStatus(@PathVariable Integer postid) {
+        Post post = postService.getById(postid);
+        if (post == null) return null;
+
+        boolean newStatus = !post.getIsPinned();
+        boolean result = postService.setPinnedStatus(postid, newStatus);
+        return result ? newStatus : null; // ✅ 返回新状态
+    }
 }
diff --git a/src/main/java/com/pt5/pthouduan/entity/Activity.java b/src/main/java/com/pt5/pthouduan/entity/Activity.java
new file mode 100644
index 0000000..089ecfa
--- /dev/null
+++ b/src/main/java/com/pt5/pthouduan/entity/Activity.java
@@ -0,0 +1,110 @@
+package com.pt5.pthouduan.entity;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+import java.util.Date;
+
+/**
+ * <p>
+ *
+ * </p>
+ *
+ * @author 杨蔓
+ * @since 2025-05-16
+ */
+@TableName("activity")
+public class Activity implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId("activityid")
+    private Integer activityid;
+
+    private String title;
+
+    private String content;
+
+    private String photo;
+
+    private LocalDateTime time;
+
+    private Integer is_show;
+
+    private Integer award;
+
+
+    public Integer getActivityid() {
+        return activityid;
+    }
+
+    public void setActivityid(Integer activityid) {
+        this.activityid = activityid;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getContent() {
+        return content;
+    }
+
+    public void setContent(String content) {
+        this.content = content;
+    }
+
+    public String getPhoto() {//获取标签
+        return photo;
+    }
+
+    public void setPhoto(String photo) {
+        this.photo = photo;
+    }
+
+    public LocalDateTime getTime() {
+        return time;
+    }
+
+    public void setTime(LocalDateTime time) {
+        this.time = time;
+    }
+
+    public Integer getIs_show() {
+        return is_show;
+    }
+
+    public void setIs_show(Integer is_show) {
+        this.is_show = is_show;
+    }
+
+    public Integer getAward() {
+        return award;
+    }
+
+    public void setAward(Integer award) {
+        this.award = award;
+    }
+
+
+
+
+    @Override
+    public String toString() {
+        return "Activity{" +
+                "activityid=" + activityid +
+                ", title=" + title  +
+                ", content=" + content +
+                ", photo=" + photo +
+                ", time=" + time +
+                ", is_show=" + is_show +
+                ", award=" + award +
+                '}';
+    }
+}
diff --git a/src/main/java/com/pt5/pthouduan/entity/ChatInformation.java b/src/main/java/com/pt5/pthouduan/entity/ChatInformation.java
index 03ed650..0659d73 100644
--- a/src/main/java/com/pt5/pthouduan/entity/ChatInformation.java
+++ b/src/main/java/com/pt5/pthouduan/entity/ChatInformation.java
@@ -1,46 +1,83 @@
 package com.pt5.pthouduan.entity;
 
+import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
+
 import java.io.Serializable;
+import java.time.LocalDateTime;
 
 /**
  * <p>
- * 
+ * 聊天信息表
  * </p>
  *
- * @author ljx
- * @since 2025-04-14
+ * @author ym
+ * @since 2025-06-03
  */
 @TableName("chat_information")
 public class ChatInformation implements Serializable {
 
     private static final long serialVersionUID = 1L;
 
-    private Long userid;
+    @TableId("informationid")
+    private Integer informationid;
 
-    private String chatimformation;
+    private Long senderId;
 
-    public Long getUserid() {
-        return userid;
+    private Long receiverId;
+
+    private String content;
+
+    private LocalDateTime talkTime;
+
+    public Integer getInformationid() {
+        return informationid;
     }
 
-    public void setUserid(Long userid) {
-        this.userid = userid;
+    public void setInformationid(Integer informationid) {
+        this.informationid = informationid;
     }
 
-    public String getChatimformation() {
-        return chatimformation;
+    public Long getSenderId() {
+        return senderId;
     }
 
-    public void setChatimformation(String chatimformation) {
-        this.chatimformation = chatimformation;
+    public void setSenderId(Long senderId) {
+        this.senderId = senderId;
+    }
+
+    public Long getReceiverId() {
+        return receiverId;
+    }
+
+    public void setReceiverId(Long receiverId) {
+        this.receiverId = receiverId;
+    }
+
+    public String getContent() {
+        return content;
+    }
+
+    public void setContent(String content) {
+        this.content = content;
+    }
+
+    public LocalDateTime getTalkTime() {
+        return talkTime;
+    }
+
+    public void setTalkTime(LocalDateTime talkTime) {
+        this.talkTime = talkTime;
     }
 
     @Override
     public String toString() {
         return "ChatInformation{" +
-        "userid = " + userid +
-        ", chatimformation = " + chatimformation +
-        "}";
+                "informationid=" + informationid +
+                ", senderId=" + senderId +
+                ", receiverId=" + receiverId +
+                ", content='" + content + '\'' +
+                ", talkTime=" + talkTime +
+                '}';
     }
 }
diff --git a/src/main/java/com/pt5/pthouduan/entity/Complain.java b/src/main/java/com/pt5/pthouduan/entity/Complain.java
new file mode 100644
index 0000000..6a57648
--- /dev/null
+++ b/src/main/java/com/pt5/pthouduan/entity/Complain.java
@@ -0,0 +1,82 @@
+package com.pt5.pthouduan.entity;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 投诉记录实体类
+ * </p>
+ *
+ * @author ym
+ * @since 2025-04-14
+ */
+@TableName("complain")
+public class Complain implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId("complainid")
+    private Integer complainid;
+
+    private Long puse;
+
+    private Long duser;
+
+    private String content;
+
+    private Long torrentid;
+
+    public Integer getComplainid() {
+        return complainid;
+    }
+
+    public void setComplainid(Integer complainid) {
+        this.complainid = complainid;
+    }
+
+    public Long getPuse() {
+        return puse;
+    }
+
+    public void setPuse(Long puse) {
+        this.puse = puse;
+    }
+
+    public Long getDuser() {
+        return duser;
+    }
+
+    public void setDuser(Long duser) {
+        this.duser = duser;
+    }
+
+    public String getContent() {
+        return content;
+    }
+
+    public void setContent(String content) {
+        this.content = content;
+    }
+
+    public Long getTorrentid() {
+        return torrentid;
+    }
+
+    public void setTorrentid(Long torrentid) {
+        this.torrentid = torrentid;
+    }
+
+    @Override
+    public String toString() {
+        return "Complain{" +
+                "complainid=" + complainid +
+                ", puse=" + puse +
+                ", duser=" + duser +
+                ", content='" + content + '\'' +
+                ", torrentid=" + torrentid +
+                '}';
+    }
+}
diff --git a/src/main/java/com/pt5/pthouduan/entity/Post.java b/src/main/java/com/pt5/pthouduan/entity/Post.java
index 843800d..64f0c72 100644
--- a/src/main/java/com/pt5/pthouduan/entity/Post.java
+++ b/src/main/java/com/pt5/pthouduan/entity/Post.java
@@ -99,11 +99,11 @@
         this.rannge = rannge;
     }
 
-    public Boolean getIsSticky() {
+    public Boolean getIsPinned() {
         return is_pinned;
     }
 
-    public void setIsSticky(Boolean is_pinned) {
+    public void setIsPinned(Boolean is_pinned) {
         this.is_pinned = is_pinned;
     }
 
diff --git a/src/main/java/com/pt5/pthouduan/mapper/ActivityMapper.java b/src/main/java/com/pt5/pthouduan/mapper/ActivityMapper.java
new file mode 100644
index 0000000..c94aeb0
--- /dev/null
+++ b/src/main/java/com/pt5/pthouduan/mapper/ActivityMapper.java
@@ -0,0 +1,38 @@
+package com.pt5.pthouduan.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.pt5.pthouduan.entity.Activity;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * <p>
+ *  活动 Mapper 接口
+ * </p>
+ *
+ * 功能:增、删、改、查(按是否展示)
+ *
+ * 作者:杨蔓
+ * @since 2025-05-16
+ */
+@Mapper
+public interface ActivityMapper extends BaseMapper<Activity> {
+
+    // 根据是否展示状态查询活动列表(0:展示,1:隐藏)
+    List<Activity> selectByIsShow(@Param("is_show") Integer isShow);
+
+    // 插入新的活动
+    int insert(Activity activity);
+
+    // 根据活动ID删除活动
+    int deleteById(@Param("activityid") Integer activityid);
+
+    // 根据活动ID更新活动内容
+    int updateById(Activity activity);
+
+    // ✅ 新增:根据活动ID查询活动详情
+    Activity selectById(@Param("activityid") Integer activityid);
+
+}
diff --git a/src/main/java/com/pt5/pthouduan/mapper/ChatInformationMapper.java b/src/main/java/com/pt5/pthouduan/mapper/ChatInformationMapper.java
index f410562..54e748a 100644
--- a/src/main/java/com/pt5/pthouduan/mapper/ChatInformationMapper.java
+++ b/src/main/java/com/pt5/pthouduan/mapper/ChatInformationMapper.java
@@ -1,18 +1,34 @@
 package com.pt5.pthouduan.mapper;
 
-import com.pt5.pthouduan.entity.ChatInformation;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.pt5.pthouduan.entity.ChatInformation;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
 
 /**
  * <p>
- *  Mapper 接口
+ * 聊天记录 Mapper 接口
  * </p>
  *
- * @author ljx
- * @since 2025-04-14
+ * 功能:添加、删除、查询(按用户ID、用户对)
+ *
+ * @author ym
+ * @since 2025-06-03
  */
 @Mapper
 public interface ChatInformationMapper extends BaseMapper<ChatInformation> {
 
+    // 创建聊天记录
+    void insertChat(ChatInformation chatInformation);
+
+    // 根据信息ID删除聊天记录
+    int deleteChatById(@Param("informationid") Integer informationid);
+
+    // 获取某个用户参与的所有聊天记录(作为发送方或接收方)
+    List<ChatInformation> selectChatsByUser(@Param("userId") Long userId);
+
+    // 获取两个用户之间的聊天记录(无论谁是发送方或接收方)
+    List<ChatInformation> selectChatsBetweenUsers(@Param("user1") Long user1, @Param("user2") Long user2);
 }
diff --git a/src/main/java/com/pt5/pthouduan/mapper/ComplainMapper.java b/src/main/java/com/pt5/pthouduan/mapper/ComplainMapper.java
new file mode 100644
index 0000000..c39557d
--- /dev/null
+++ b/src/main/java/com/pt5/pthouduan/mapper/ComplainMapper.java
@@ -0,0 +1,45 @@
+package com.pt5.pthouduan.mapper;
+
+import com.pt5.pthouduan.entity.Complain;
+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>
+ *
+ * 功能:增、删、改、查(按被投诉用户ID和投诉发起人ID)
+ *
+ * @author ym
+ * @since 2025-04-14
+ */
+@Mapper
+public interface ComplainMapper extends BaseMapper<Complain> {
+
+    // 创建投诉
+    void save(Complain complain);
+
+    // 根据投诉ID删除
+    int deleteByComplainid(@Param("complainid") Integer complainid);
+
+    // 更新投诉
+    int updateComplain(Complain complain);
+
+    // 根据被投诉用户ID查询投诉列表
+    List<Complain> selectByDuser(@Param("duser") Long duser);
+
+    // 根据投诉发起人ID查询投诉列表
+    List<Complain> selectByPuse(@Param("puse") Long puse);
+
+    // 根据投诉ID查询投诉记录
+    Complain selectByComplainId(@Param("complainid") Integer complainid);
+
+    // 获取所有投诉记录
+    List<Complain> selectAllComplains();
+
+
+}
diff --git a/src/main/java/com/pt5/pthouduan/mapper/PostMapper.java b/src/main/java/com/pt5/pthouduan/mapper/PostMapper.java
index 6b95c73..0cd0480 100644
--- a/src/main/java/com/pt5/pthouduan/mapper/PostMapper.java
+++ b/src/main/java/com/pt5/pthouduan/mapper/PostMapper.java
@@ -39,7 +39,7 @@
     int decrementLikes(@Param("postid") Integer postid);
 
     // 设置置顶状态
-    int updatePinnedStatus(@Param("postid") Integer postid, @Param("pinned") boolean pinned);
+    int updatePinnedStatus(@Param("postid") Integer postid, @Param("isPinned") boolean isPinned);
 
     // 根据用户ID查询该用户所有帖子
     List<Post> findByUserid(@Param("userid") Long userid);
@@ -47,6 +47,9 @@
     // 查询所有置顶帖子
     List<Post> findPinnedPosts();
 
-    // ✅ 新增:查询所有帖子(置顶优先,时间倒序)
+    // ✅ 查询所有帖子(置顶优先,时间倒序)
     List<Post> selectAllSorted();
+
+    // ✅ 根据帖子ID查询单个帖子(用于 togglePin 等功能)
+    Post selectById(@Param("postid") Integer postid);
 }
diff --git a/src/main/java/com/pt5/pthouduan/service/ActivityService.java b/src/main/java/com/pt5/pthouduan/service/ActivityService.java
new file mode 100644
index 0000000..67b51e1
--- /dev/null
+++ b/src/main/java/com/pt5/pthouduan/service/ActivityService.java
@@ -0,0 +1,40 @@
+package com.pt5.pthouduan.service;
+
+import com.pt5.pthouduan.entity.Activity;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 活动服务接口
+ * </p>
+ *
+ * 功能:增、删、改、查(按是否显示状态)
+ * </p>
+ *
+ * @author ym
+ * @since 2025-05-16
+ */
+public interface ActivityService {
+
+    // 根据 is_show 状态查询活动列表(0:显示,1:隐藏等)
+    List<Activity> findByIsShow(Integer isShow);
+
+    // 创建活动
+    boolean save(Activity activity);
+
+    // 根据ID删除活动
+    boolean removeById(Integer activityid);
+
+    // 根据ID更新活动
+    boolean updateById(Activity activity);
+
+    // 根据ID获取活动
+    Activity getById(Integer activityid);
+
+    // 新增:获取所有活动(不分是否显示)
+    List<Activity> list();
+
+    //根据题目获得公告
+    List<Activity> searchByTitle(String title);
+}
diff --git a/src/main/java/com/pt5/pthouduan/service/ChatInformationService.java b/src/main/java/com/pt5/pthouduan/service/ChatInformationService.java
new file mode 100644
index 0000000..67613f4
--- /dev/null
+++ b/src/main/java/com/pt5/pthouduan/service/ChatInformationService.java
@@ -0,0 +1,30 @@
+package com.pt5.pthouduan.service;
+
+import com.pt5.pthouduan.entity.ChatInformation;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 聊天记录服务接口
+ * </p>
+ *
+ * 功能:添加聊天记录、删除聊天记录、查询用户与所有人的聊天、查询两个用户之间的聊天
+ *
+ * @author ym
+ * @since 2025-06-03
+ */
+public interface ChatInformationService {
+
+    // 创建聊天记录
+    ChatInformation createChat(ChatInformation chatInformation);
+
+    // 删除聊天记录
+    boolean deleteChatById(Integer informationid);
+
+    // 获取某个用户与所有人的聊天记录
+    List<ChatInformation> getChatsByUser(Long userId);
+
+    // 获取两个用户之间的聊天记录
+    List<ChatInformation> getChatsBetweenUsers(Long user1, Long user2);
+}
diff --git a/src/main/java/com/pt5/pthouduan/service/ComplainService.java b/src/main/java/com/pt5/pthouduan/service/ComplainService.java
new file mode 100644
index 0000000..896f748
--- /dev/null
+++ b/src/main/java/com/pt5/pthouduan/service/ComplainService.java
@@ -0,0 +1,38 @@
+package com.pt5.pthouduan.service;
+
+import com.pt5.pthouduan.entity.Complain;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 投诉服务接口
+ * </p>
+ *
+ * 功能:增、删、改、查(按被投诉用户ID、投诉发起人ID)
+ *
+ * @author ym
+ * @since 2025-04-14
+ */
+public interface ComplainService {
+
+    // 创建投诉
+    Complain createComplain(Complain complain);
+
+    // 删除投诉
+    boolean deleteComplain(Integer complainid);
+
+    // 更新投诉
+    boolean updateComplain(Complain complain);
+
+    // 根据被投诉用户ID查询投诉
+    List<Complain> getComplainsByTargetUser(Long duser);
+
+    // 根据投诉发起人ID查询投诉
+    List<Complain> getComplainsByPostingUser(Long puse);
+
+    List<Complain> getAllComplains();
+
+    Complain getComplainById(Integer complainid);
+
+}
diff --git a/src/main/java/com/pt5/pthouduan/service/PostService.java b/src/main/java/com/pt5/pthouduan/service/PostService.java
index fabf254..7db4d26 100644
--- a/src/main/java/com/pt5/pthouduan/service/PostService.java
+++ b/src/main/java/com/pt5/pthouduan/service/PostService.java
@@ -43,4 +43,6 @@
     List<Post> findPinnedPosts();                    // 查找所有置顶帖子
 
     List<Post> getAllPostsSorted();                  // ✅ 获取所有帖子(置顶优先,按时间排序)
+
+    Post getById(Integer postid);
 }
diff --git a/src/main/java/com/pt5/pthouduan/service/impl/ActivityServiceImpl.java b/src/main/java/com/pt5/pthouduan/service/impl/ActivityServiceImpl.java
new file mode 100644
index 0000000..3173589
--- /dev/null
+++ b/src/main/java/com/pt5/pthouduan/service/impl/ActivityServiceImpl.java
@@ -0,0 +1,67 @@
+package com.pt5.pthouduan.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.pt5.pthouduan.entity.Activity;
+import com.pt5.pthouduan.mapper.ActivityMapper;
+import com.pt5.pthouduan.service.ActivityService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 活动服务实现类
+ * </p>
+ *
+ * 实现了活动的增删改查逻辑
+ * </p>
+ *
+ * @author ym
+ * @since 2025-05-16
+ */
+@Service
+public class ActivityServiceImpl implements ActivityService {
+
+    @Autowired
+    private ActivityMapper activityMapper;
+
+    @Override
+    public List<Activity> findByIsShow(Integer isShow) {
+        return activityMapper.selectByIsShow(isShow);
+    }
+
+    @Override
+    public boolean save(Activity activity) {
+        return activityMapper.insert(activity) > 0;
+    }
+
+    @Override
+    public boolean removeById(Integer activityid) {
+        return activityMapper.deleteById(activityid) > 0;
+    }
+
+    @Override
+    public boolean updateById(Activity activity) {
+        return activityMapper.updateById(activity) > 0;
+    }
+
+    @Override
+    public Activity getById(Integer activityid) {
+        return activityMapper.selectById(activityid);
+    }
+
+    // 新增:查询所有活动(不分是否显示)
+    @Override
+    public List<Activity> list() {
+        return activityMapper.selectList(null);
+    }
+
+    @Override
+    public List<Activity> searchByTitle(String title) {
+        QueryWrapper<Activity> queryWrapper = new QueryWrapper<>();
+        // 模糊匹配 title 字段
+        queryWrapper.like("title", title);
+        return activityMapper.selectList(queryWrapper);
+    }
+}
diff --git a/src/main/java/com/pt5/pthouduan/service/impl/ChatInformationServiceImpl.java b/src/main/java/com/pt5/pthouduan/service/impl/ChatInformationServiceImpl.java
new file mode 100644
index 0000000..a4f84bb
--- /dev/null
+++ b/src/main/java/com/pt5/pthouduan/service/impl/ChatInformationServiceImpl.java
@@ -0,0 +1,47 @@
+package com.pt5.pthouduan.service.impl;
+
+import com.pt5.pthouduan.entity.ChatInformation;
+import com.pt5.pthouduan.mapper.ChatInformationMapper;
+import com.pt5.pthouduan.service.ChatInformationService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 聊天记录服务实现类
+ * </p>
+ *
+ * 实现了聊天记录的增删查逻辑
+ *
+ * @author ym
+ * @since 2025-06-03
+ */
+@Service
+public class ChatInformationServiceImpl implements ChatInformationService {
+
+    @Autowired
+    private ChatInformationMapper chatInformationMapper;
+
+    @Override
+    public ChatInformation createChat(ChatInformation chatInformation) {
+        chatInformationMapper.insertChat(chatInformation);
+        return chatInformation;
+    }
+
+    @Override
+    public boolean deleteChatById(Integer informationid) {
+        return chatInformationMapper.deleteChatById(informationid) > 0;
+    }
+
+    @Override
+    public List<ChatInformation> getChatsByUser(Long userId) {
+        return chatInformationMapper.selectChatsByUser(userId);
+    }
+
+    @Override
+    public List<ChatInformation> getChatsBetweenUsers(Long user1, Long user2) {
+        return chatInformationMapper.selectChatsBetweenUsers(user1, user2);
+    }
+}
diff --git a/src/main/java/com/pt5/pthouduan/service/impl/ComplainServiceImpl.java b/src/main/java/com/pt5/pthouduan/service/impl/ComplainServiceImpl.java
new file mode 100644
index 0000000..84b0be2
--- /dev/null
+++ b/src/main/java/com/pt5/pthouduan/service/impl/ComplainServiceImpl.java
@@ -0,0 +1,64 @@
+package com.pt5.pthouduan.service.impl;
+
+import com.pt5.pthouduan.entity.Complain;
+import com.pt5.pthouduan.mapper.ComplainMapper;
+import com.pt5.pthouduan.service.ComplainService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 投诉服务实现类
+ * </p>
+ *
+ * 实现了投诉的增删改查逻辑
+ *
+ * @author ym
+ * @since 2025-04-14
+ */
+@Service
+public class ComplainServiceImpl implements ComplainService {
+
+    @Autowired
+    private ComplainMapper complainMapper;
+
+    @Override
+    public Complain createComplain(Complain complain) {
+        complainMapper.save(complain);
+        return complain;
+    }
+
+    @Override
+    public boolean deleteComplain(Integer complainid) {
+        return complainMapper.deleteByComplainid(complainid) > 0;
+    }
+
+    @Override
+    public boolean updateComplain(Complain complain) {
+        return complainMapper.updateComplain(complain) > 0;
+    }
+
+    @Override
+    public List<Complain> getComplainsByTargetUser(Long duser) {
+        return complainMapper.selectByDuser(duser);
+    }
+
+    @Override
+    public List<Complain> getComplainsByPostingUser(Long puse) {
+        return complainMapper.selectByPuse(puse);
+    }
+
+    @Override
+    public List<Complain> getAllComplains() {
+        return complainMapper.selectList(null); // 查询全部记录
+    }
+
+    @Override
+    public Complain getComplainById(Integer complainid) {
+        return complainMapper.selectById(complainid); // 根据主键查记录
+    }
+
+
+}
diff --git a/src/main/java/com/pt5/pthouduan/service/impl/PostServiceImpl.java b/src/main/java/com/pt5/pthouduan/service/impl/PostServiceImpl.java
index d1bda7f..37edf51 100644
--- a/src/main/java/com/pt5/pthouduan/service/impl/PostServiceImpl.java
+++ b/src/main/java/com/pt5/pthouduan/service/impl/PostServiceImpl.java
@@ -12,6 +12,7 @@
  * <p>
  *  帖子服务实现类
  * </p>
+ * 提供帖子增删改查、点赞、置顶等功能的业务实现
  *
  * @author 杨蔓
  * @since 2025-04-14
@@ -29,8 +30,8 @@
     }
 
     @Override
-    public boolean deletePost(Integer postid) {
-        return postMapper.deleteByPostid(postid) > 0;
+    public boolean deletePost(Integer postId) {
+        return postMapper.deleteByPostid(postId) > 0;
     }
 
     @Override
@@ -44,23 +45,23 @@
     }
 
     @Override
-    public boolean incrementLikes(Integer postid) {
-        return postMapper.incrementLikes(postid) >= 0;
+    public boolean incrementLikes(Integer postId) {
+        return postMapper.incrementLikes(postId) >= 0;
     }
 
     @Override
-    public boolean decrementLikes(Integer postid) {
-        return postMapper.decrementLikes(postid) >= 0;
+    public boolean decrementLikes(Integer postId) {
+        return postMapper.decrementLikes(postId) >= 0;
     }
 
     @Override
-    public boolean setPinnedStatus(Integer postid, boolean pinned) {
-        return postMapper.updatePinnedStatus(postid, pinned) > 0;
+    public boolean setPinnedStatus(Integer postId, boolean isPinned) {
+        return postMapper.updatePinnedStatus(postId, isPinned) > 0;
     }
 
     @Override
-    public List<Post> findByUserid(Long userid) {
-        return postMapper.findByUserid(userid);
+    public List<Post> findByUserid(Long userId) {
+        return postMapper.findByUserid(userId);
     }
 
     @Override
@@ -68,9 +69,14 @@
         return postMapper.findPinnedPosts();
     }
 
-    /** ✅ 新增:获取所有帖子(置顶优先,时间倒序) */
     @Override
     public List<Post> getAllPostsSorted() {
         return postMapper.selectAllSorted();
     }
+
+    /** ✅ 补充:根据帖子 ID 获取帖子对象 */
+    @Override
+    public Post getById(Integer postId) {
+        return postMapper.selectById(postId);
+    }
 }
diff --git a/src/main/resources/mapper/ActivityMapper.xml b/src/main/resources/mapper/ActivityMapper.xml
new file mode 100644
index 0000000..84cad7a
--- /dev/null
+++ b/src/main/resources/mapper/ActivityMapper.xml
@@ -0,0 +1,60 @@
+<?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.ActivityMapper">
+
+    <!-- 插入活动 -->
+    <insert id="insert" parameterType="com.pt5.pthouduan.entity.Activity"
+            useGeneratedKeys="true" keyProperty="activityid" keyColumn="activityid">
+        INSERT INTO activity (
+            title,
+            content,
+            photo,
+            time,
+            is_show,
+            award
+        ) VALUES (
+                     #{title},
+                     #{content},
+                     #{photo},
+                     #{time},
+                     #{is_show},
+                     #{award}
+                 )
+    </insert>
+
+    <!-- 删除活动 -->
+    <delete id="deleteById" parameterType="int">
+        DELETE FROM activity WHERE activityid = #{activityid}
+    </delete>
+
+    <!-- 更新活动 -->
+    <update id="updateById" parameterType="com.pt5.pthouduan.entity.Activity">
+        UPDATE activity
+        SET
+            title = #{title},
+            content = #{content},
+            photo = #{photo},
+            time = #{time},
+            is_show = #{is_show},
+            award = #{award}
+        WHERE activityid = #{activityid}
+    </update>
+
+    <!-- 查询所有 is_show 为指定值的活动 -->
+    <select id="selectByIsShow" resultType="com.pt5.pthouduan.entity.Activity">
+        SELECT *
+        FROM activity
+        WHERE is_show = #{is_show}
+        ORDER BY time DESC
+    </select>
+
+    <!-- ✅ 新增:根据活动ID查询活动详情 -->
+    <select id="selectById" parameterType="int" resultType="com.pt5.pthouduan.entity.Activity">
+        SELECT *
+        FROM activity
+        WHERE activityid = #{activityid}
+    </select>
+
+</mapper>
diff --git a/src/main/resources/mapper/ChatInformationMapper.xml b/src/main/resources/mapper/ChatInformationMapper.xml
new file mode 100644
index 0000000..d9aac6f
--- /dev/null
+++ b/src/main/resources/mapper/ChatInformationMapper.xml
@@ -0,0 +1,34 @@
+<?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.ChatInformationMapper">
+
+    <!-- 插入聊天记录 -->
+    <insert id="insertChat" parameterType="com.pt5.pthouduan.entity.ChatInformation" useGeneratedKeys="true" keyProperty="informationid">
+        INSERT INTO chat_information (sender_id, receiver_id, content)
+        VALUES (#{senderId}, #{receiverId}, #{content})
+    </insert>
+
+    <!-- 删除聊天记录 -->
+    <delete id="deleteChatById" parameterType="int">
+        DELETE FROM chat_information WHERE informationid = #{value}
+    </delete>
+
+    <!-- 查询某用户参与的所有聊天记录 -->
+    <select id="selectChatsByUser" parameterType="long" resultType="com.pt5.pthouduan.entity.ChatInformation">
+        SELECT * FROM chat_information
+        WHERE sender_id = #{userId} OR receiver_id = #{userId}
+        ORDER BY talk_time ASC
+    </select>
+
+    <!-- 查询两个用户之间的聊天记录 -->
+    <select id="selectChatsBetweenUsers" parameterType="map" resultType="com.pt5.pthouduan.entity.ChatInformation">
+        SELECT * FROM chat_information
+        WHERE (sender_id = #{user1} AND receiver_id = #{user2})
+           OR (sender_id = #{user2} AND receiver_id = #{user1})
+        ORDER BY talk_time ASC
+    </select>
+
+</mapper>
diff --git a/src/main/resources/mapper/ComplainMapper.xml b/src/main/resources/mapper/ComplainMapper.xml
new file mode 100644
index 0000000..978ca2e
--- /dev/null
+++ b/src/main/resources/mapper/ComplainMapper.xml
@@ -0,0 +1,55 @@
+<?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.ComplainMapper">
+
+    <!-- 插入投诉 -->
+    <insert id="save" parameterType="com.pt5.pthouduan.entity.Complain" useGeneratedKeys="true" keyProperty="complainid">
+        INSERT INTO complain (puse, duser, content, torrentid)
+        VALUES (#{puse}, #{duser}, #{content}, #{torrentid})
+    </insert>
+
+    <!-- 根据投诉ID删除投诉 -->
+    <delete id="deleteByComplainid" parameterType="int">
+        DELETE FROM complain WHERE complainid = #{complainid}
+    </delete>
+
+    <!-- 更新投诉 -->
+    <update id="updateComplain" parameterType="com.pt5.pthouduan.entity.Complain">
+        UPDATE complain
+        SET puse = #{puse},
+            duser = #{duser},
+            content = #{content},
+            torrentid = #{torrentid}
+        WHERE complainid = #{complainid}
+    </update>
+
+    <!-- 根据被投诉用户ID查询投诉列表 -->
+    <select id="selectByDuser" parameterType="long" resultType="com.pt5.pthouduan.entity.Complain">
+        SELECT * FROM complain
+        WHERE duser = #{duser}
+        ORDER BY complainid DESC
+    </select>
+
+    <!-- 根据投诉发起人ID查询投诉列表 -->
+    <select id="selectByPuse" parameterType="long" resultType="com.pt5.pthouduan.entity.Complain">
+        SELECT * FROM complain
+        WHERE puse = #{puse}
+        ORDER BY complainid DESC
+    </select>
+
+    <!-- ✅ 获取所有投诉记录 -->
+    <select id="selectAllComplains" resultType="com.pt5.pthouduan.entity.Complain">
+        SELECT * FROM complain
+        ORDER BY complainid DESC
+    </select>
+
+    <!-- ✅ 根据投诉ID查询投诉详情 -->
+    <select id="selectByComplainId" parameterType="int" resultType="com.pt5.pthouduan.entity.Complain">
+        SELECT * FROM complain
+        WHERE complainid = #{complainid}
+    </select>
+
+</mapper>
diff --git a/src/main/resources/mapper/PostMapper.xml b/src/main/resources/mapper/PostMapper.xml
index e676fcc..ad6024c 100644
--- a/src/main/resources/mapper/PostMapper.xml
+++ b/src/main/resources/mapper/PostMapper.xml
@@ -78,7 +78,7 @@
     <!-- 更新置顶状态 -->
     <update id="updatePinnedStatus" parameterType="map">
         UPDATE post
-        SET is_pinned = #{pinned}
+        SET is_pinned = #{isPinned}
         WHERE postid = #{postid}
     </update>
 
@@ -100,4 +100,10 @@
         ORDER BY is_pinned DESC, postCreatedTime DESC
     </select>
 
+    <!-- ✅ 根据 postid 查询单个帖子 -->
+    <select id="selectById" parameterType="int" resultType="com.pt5.pthouduan.entity.Post">
+        SELECT * FROM post
+        WHERE postid = #{postid}
+    </select>
+
 </mapper>
diff --git a/src/test/java/com/pt5/pthouduan/controller/ActivityControllerTest.java b/src/test/java/com/pt5/pthouduan/controller/ActivityControllerTest.java
new file mode 100644
index 0000000..3d737a9
--- /dev/null
+++ b/src/test/java/com/pt5/pthouduan/controller/ActivityControllerTest.java
@@ -0,0 +1,140 @@
+package com.pt5.pthouduan.controller;
+
+import com.pt5.pthouduan.entity.Activity;
+import com.pt5.pthouduan.service.ActivityService;
+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.ArgumentMatchers.any;
+import static org.mockito.Mockito.*;
+
+class ActivityControllerTest {
+
+    @Mock
+    private ActivityService activityService;
+
+    @InjectMocks
+    private ActivityController activityController;
+
+    @BeforeEach
+    void setUp() {
+        MockitoAnnotations.openMocks(this);
+    }
+
+    @Test
+    void getVisibleActivityPreviews_ShouldReturnPreviewList() {
+        Activity fullActivity = new Activity();
+        fullActivity.setActivityid(1);
+        fullActivity.setTitle("Test");
+        fullActivity.setContent("Content");
+        fullActivity.setAward(10);
+        fullActivity.setPhoto("/activity/photo.jpg");
+        fullActivity.setTime(LocalDateTime.now());
+
+        when(activityService.findByIsShow(0)).thenReturn(Arrays.asList(fullActivity));
+
+        List<Activity> result = activityController.getVisibleActivityPreviews();
+
+        assertEquals(1, result.size());
+        assertEquals("Test", result.get(0).getTitle());
+        assertEquals("/activity/photo.jpg", result.get(0).getPhoto());
+    }
+
+    @Test
+    void getVisibleActivities_ShouldReturnList() {
+        Activity activity = new Activity();
+        activity.setActivityid(1);
+        activity.setTitle("Visible Activity");
+
+        when(activityService.findByIsShow(0)).thenReturn(List.of(activity));
+
+        List<Activity> result = activityController.getVisibleActivities();
+
+        assertEquals(1, result.size());
+        assertEquals("Visible Activity", result.get(0).getTitle());
+    }
+
+    @Test
+    void createActivity_ShouldReturnTrue_WhenSaved() {
+        when(activityService.save(any(Activity.class))).thenReturn(true);
+
+        boolean result = activityController.createActivity(
+                "New Title", "New Content", null, 0, 5
+        );
+
+        assertTrue(result);
+        verify(activityService).save(any(Activity.class));
+    }
+
+    @Test
+    void deleteActivity_ShouldReturnTrue_WhenDeleted() {
+        when(activityService.removeById(1)).thenReturn(true);
+
+        boolean result = activityController.deleteActivity(1);
+
+        assertTrue(result);
+        verify(activityService).removeById(1);
+    }
+
+    @Test
+    void getAllActivities_ShouldReturnAllActivities() {
+        Activity a1 = new Activity();
+        a1.setTitle("A1");
+
+        Activity a2 = new Activity();
+        a2.setTitle("A2");
+
+        when(activityService.list()).thenReturn(List.of(a1, a2));
+
+        List<Activity> result = activityController.getAllActivities();
+
+        assertEquals(2, result.size());
+        assertEquals("A1", result.get(0).getTitle());
+        assertEquals("A2", result.get(1).getTitle());
+    }
+
+    @Test
+    void searchActivitiesByTitle_ShouldReturnMatchingActivities() {
+        Activity match = new Activity();
+        match.setTitle("Matched");
+
+        when(activityService.searchByTitle("Match")).thenReturn(List.of(match));
+
+        List<Activity> result = activityController.searchActivitiesByTitle("Match");
+
+        assertEquals(1, result.size());
+        assertEquals("Matched", result.get(0).getTitle());
+    }
+
+    @Test
+    void updateActivity_ShouldReturnTrue_WhenSuccessful() {
+        Activity existing = new Activity();
+        existing.setActivityid(1);
+        existing.setTitle("Old");
+
+        when(activityService.getById(1)).thenReturn(existing);
+        when(activityService.updateById(any(Activity.class))).thenReturn(true);
+
+        boolean result = activityController.updateActivity(1, "New Title", "New Content", null, 1, 10);
+
+        assertTrue(result);
+        verify(activityService).updateById(any(Activity.class));
+    }
+
+    @Test
+    void updateActivity_ShouldReturnFalse_WhenActivityNotFound() {
+        when(activityService.getById(999)).thenReturn(null);
+
+        boolean result = activityController.updateActivity(999, "Title", "Content", null, 0, 0);
+
+        assertFalse(result);
+    }
+}
diff --git a/src/test/java/com/pt5/pthouduan/controller/ChatInformationControllerTest.java b/src/test/java/com/pt5/pthouduan/controller/ChatInformationControllerTest.java
new file mode 100644
index 0000000..f78c88d
--- /dev/null
+++ b/src/test/java/com/pt5/pthouduan/controller/ChatInformationControllerTest.java
@@ -0,0 +1,103 @@
+package com.pt5.pthouduan.controller;
+
+import com.pt5.pthouduan.entity.ChatInformation;
+import com.pt5.pthouduan.service.ChatInformationService;
+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.ArgumentMatchers.any;
+import static org.mockito.Mockito.*;
+
+class ChatInformationControllerTest {
+
+    @Mock
+    private ChatInformationService chatInformationService;
+
+    @InjectMocks
+    private ChatInformationController chatInformationController;
+
+    @BeforeEach
+    void setUp() {
+        MockitoAnnotations.openMocks(this);
+    }
+
+    @Test
+    void createChat_ShouldReturnSavedChat() {
+        ChatInformation chat = new ChatInformation();
+        chat.setSenderId(1L);
+        chat.setReceiverId(2L);
+        chat.setContent("Hello");
+        chat.setTalkTime(LocalDateTime.now());
+
+        when(chatInformationService.createChat(any(ChatInformation.class))).thenReturn(chat);
+
+        ChatInformation result = chatInformationController.createChat(chat);
+
+        assertNotNull(result);
+        assertEquals("Hello", result.getContent());
+        verify(chatInformationService).createChat(any(ChatInformation.class));
+    }
+
+    @Test
+    void deleteChat_ShouldReturnSuccessMessage_WhenDeleted() {
+        when(chatInformationService.deleteChatById(1)).thenReturn(true);
+
+        String result = chatInformationController.deleteChat(1);
+
+        assertEquals("删除成功", result);
+        verify(chatInformationService).deleteChatById(1);
+    }
+
+    @Test
+    void deleteChat_ShouldReturnFailureMessage_WhenNotDeleted() {
+        when(chatInformationService.deleteChatById(99)).thenReturn(false);
+
+        String result = chatInformationController.deleteChat(99);
+
+        assertEquals("删除失败", result);
+        verify(chatInformationService).deleteChatById(99);
+    }
+
+    @Test
+    void getChatsByUser_ShouldReturnChatList() {
+        ChatInformation chat1 = new ChatInformation();
+        chat1.setSenderId(1L);
+        chat1.setReceiverId(2L);
+        chat1.setContent("Hi");
+
+        ChatInformation chat2 = new ChatInformation();
+        chat2.setSenderId(2L);
+        chat2.setReceiverId(1L);
+        chat2.setContent("Hello");
+
+        when(chatInformationService.getChatsByUser(1L)).thenReturn(Arrays.asList(chat1, chat2));
+
+        List<ChatInformation> result = chatInformationController.getChatsByUser(1L);
+
+        assertEquals(2, result.size());
+        assertEquals("Hi", result.get(0).getContent());
+    }
+
+    @Test
+    void getChatsBetweenUsers_ShouldReturnChatListBetweenTwoUsers() {
+        ChatInformation chat = new ChatInformation();
+        chat.setSenderId(1L);
+        chat.setReceiverId(2L);
+        chat.setContent("Hey");
+
+        when(chatInformationService.getChatsBetweenUsers(1L, 2L)).thenReturn(List.of(chat));
+
+        List<ChatInformation> result = chatInformationController.getChatsBetweenUsers(1L, 2L);
+
+        assertEquals(1, result.size());
+        assertEquals("Hey", result.get(0).getContent());
+    }
+}
diff --git a/src/test/java/com/pt5/pthouduan/controller/ComplainControllerTest.java b/src/test/java/com/pt5/pthouduan/controller/ComplainControllerTest.java
new file mode 100644
index 0000000..105cc8b
--- /dev/null
+++ b/src/test/java/com/pt5/pthouduan/controller/ComplainControllerTest.java
@@ -0,0 +1,132 @@
+package com.pt5.pthouduan.controller;
+
+import com.pt5.pthouduan.entity.Complain;
+import com.pt5.pthouduan.service.ComplainService;
+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.util.Arrays;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+class ComplainControllerTest {
+
+    @Mock
+    private ComplainService complainService;
+
+    @InjectMocks
+    private ComplainController complainController;
+
+    @BeforeEach
+    void setUp() {
+        MockitoAnnotations.openMocks(this);
+    }
+
+    @Test
+    void createComplain_ShouldReturnCreatedComplain() {
+        Complain complain = new Complain();
+        complain.setComplainid(1);
+        complain.setPuse(100L);
+        complain.setDuser(200L);
+        complain.setContent("Bad behavior");
+        complain.setTorrentid(123L);
+
+        when(complainService.createComplain(any(Complain.class))).thenReturn(complain);
+
+        Complain result = complainController.createComplain(complain);
+
+        assertEquals("Bad behavior", result.getContent());
+        assertEquals(100L, result.getPuse());
+        verify(complainService).createComplain(any(Complain.class));
+    }
+
+    @Test
+    void deleteComplain_ShouldReturnTrue_WhenDeleted() {
+        when(complainService.deleteComplain(1)).thenReturn(true);
+
+        boolean result = complainController.deleteComplain(1);
+
+        assertTrue(result);
+        verify(complainService).deleteComplain(1);
+    }
+
+    @Test
+    void updateComplain_ShouldReturnTrue_WhenUpdated() {
+        Complain complain = new Complain();
+        complain.setComplainid(1);
+        complain.setContent("Updated complaint");
+
+        when(complainService.updateComplain(any(Complain.class))).thenReturn(true);
+
+        boolean result = complainController.updateComplain(complain);
+
+        assertTrue(result);
+        verify(complainService).updateComplain(complain);
+    }
+
+    @Test
+    void getComplainsByTargetUser_ShouldReturnList() {
+        Complain c1 = new Complain();
+        c1.setDuser(200L);
+        c1.setContent("Cheating");
+
+        when(complainService.getComplainsByTargetUser(200L)).thenReturn(List.of(c1));
+
+        List<Complain> result = complainController.getComplainsByTargetUser(200L);
+
+        assertEquals(1, result.size());
+        assertEquals("Cheating", result.get(0).getContent());
+    }
+
+    @Test
+    void getComplainsByPostingUser_ShouldReturnList() {
+        Complain c = new Complain();
+        c.setPuse(100L);
+        c.setContent("Spam complaint");
+
+        when(complainService.getComplainsByPostingUser(100L)).thenReturn(List.of(c));
+
+        List<Complain> result = complainController.getComplainsByPostingUser(100L);
+
+        assertEquals(1, result.size());
+        assertEquals("Spam complaint", result.get(0).getContent());
+    }
+
+    @Test
+    void getAllComplains_ShouldReturnAll() {
+        Complain c1 = new Complain();
+        c1.setContent("Complain A");
+        Complain c2 = new Complain();
+        c2.setContent("Complain B");
+
+        when(complainService.getAllComplains()).thenReturn(Arrays.asList(c1, c2));
+
+        List<Complain> result = complainController.getAllComplains();
+
+        assertEquals(2, result.size());
+        assertEquals("Complain A", result.get(0).getContent());
+        assertEquals("Complain B", result.get(1).getContent());
+    }
+
+    @Test
+    void getComplainInfo_ShouldReturnComplainDetails() {
+        Complain c = new Complain();
+        c.setComplainid(1);
+        c.setPuse(100L);
+        c.setDuser(200L);
+        c.setTorrentid(500L);
+
+        when(complainService.getComplainById(1)).thenReturn(c);
+
+        Complain result = complainController.getComplainInfo(1);
+
+        assertEquals(100L, result.getPuse());
+        assertEquals(200L, result.getDuser());
+        assertEquals(500L, result.getTorrentid());
+    }
+}
diff --git a/src/test/java/com/pt5/pthouduan/controller/PostControllerTest.java b/src/test/java/com/pt5/pthouduan/controller/PostControllerTest.java
new file mode 100644
index 0000000..05bf209
--- /dev/null
+++ b/src/test/java/com/pt5/pthouduan/controller/PostControllerTest.java
@@ -0,0 +1,145 @@
+package com.pt5.pthouduan.controller;
+
+import com.pt5.pthouduan.entity.Post;
+import com.pt5.pthouduan.service.PostService;
+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 org.springframework.web.multipart.MultipartFile;
+
+import java.time.LocalDateTime;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+class PostControllerTest {
+
+    @Mock
+    private PostService postService;
+
+    @InjectMocks
+    private PostController postController;
+
+    @BeforeEach
+    void setUp() {
+        MockitoAnnotations.openMocks(this);
+    }
+
+    @Test
+    void createPost_WithValidData_ShouldReturnTrue() {
+        MultipartFile photo = mock(MultipartFile.class);
+        when(photo.isEmpty()).thenReturn(true); // 模拟没有上传图片
+
+        Post mockPost = new Post();
+        mockPost.setPostid(1);
+        when(postService.createPost(any(Post.class))).thenReturn(mockPost);
+
+        boolean result = postController.createPost(
+                1L, "标题", "内容", "标签", "全站", true, photo
+        );
+
+        assertTrue(result);
+    }
+
+    @Test
+    void deletePost_ShouldReturnTrue_WhenServiceSucceeds() {
+        when(postService.deletePost(1)).thenReturn(true);
+        boolean result = postController.deletePost(1);
+        assertTrue(result);
+    }
+
+    @Test
+    void updatePost_ShouldReturnTrue_WhenUpdateSucceeds() {
+        Post post = new Post();
+        post.setPostid(1);
+        when(postService.updatePost(post)).thenReturn(true);
+        assertTrue(postController.updatePost(post));
+    }
+
+    @Test
+    void searchPosts_ShouldReturnMatchedPosts() {
+        Post post1 = new Post();
+        post1.setPostTitle("关键字匹配");
+
+        when(postService.searchPostsByKeyword("关键字")).thenReturn(List.of(post1));
+
+        List<Post> result = postController.searchPosts("关键字");
+
+        assertEquals(1, result.size());
+        assertEquals("关键字匹配", result.get(0).getPostTitle());
+    }
+
+    @Test
+    void likePost_ShouldReturnTrue() {
+        when(postService.incrementLikes(1)).thenReturn(true);
+        assertTrue(postController.likePost(1));
+    }
+
+    @Test
+    void unlikePost_ShouldReturnTrue() {
+        when(postService.decrementLikes(1)).thenReturn(true);
+        assertTrue(postController.unlikePost(1));
+    }
+
+    @Test
+    void pinPost_ShouldReturnTrue() {
+        when(postService.setPinnedStatus(1, true)).thenReturn(true);
+        assertTrue(postController.pinPost(1));
+    }
+
+    @Test
+    void unpinPost_ShouldReturnTrue() {
+        when(postService.setPinnedStatus(1, false)).thenReturn(true);
+        assertTrue(postController.unpinPost(1));
+    }
+
+    @Test
+    void findByUserid_ShouldReturnUserPosts() {
+        Post post = new Post();
+        post.setUserid(1L);
+        when(postService.findByUserid(1L)).thenReturn(List.of(post));
+
+        List<Post> result = postController.findByUserid(1L);
+        assertEquals(1, result.size());
+        assertEquals(1L, result.get(0).getUserid());
+    }
+
+    @Test
+    void findPinnedPosts_ShouldReturnPinnedList() {
+        Post post = new Post();
+        post.setIsPinned(true);
+        when(postService.findPinnedPosts()).thenReturn(List.of(post));
+
+        List<Post> result = postController.findPinnedPosts();
+        assertEquals(1, result.size());
+        assertTrue(result.get(0).getIsPinned());
+    }
+
+    @Test
+    void togglePinStatus_ShouldToggleAndReturnNewStatus() {
+        Post post = new Post();
+        post.setPostid(1);
+        post.setIsPinned(false);
+
+        when(postService.getById(1)).thenReturn(post);
+        when(postService.setPinnedStatus(1, true)).thenReturn(true);
+
+        Boolean result = postController.togglePinStatus(1);
+        assertTrue(result);
+    }
+
+    @Test
+    void getAllPostsSorted_ShouldReturnAllPosts() {
+        Post post1 = new Post();
+        Post post2 = new Post();
+        when(postService.getAllPostsSorted()).thenReturn(Arrays.asList(post1, post2));
+
+        List<Post> posts = postController.getAllPostsSorted();
+        assertEquals(2, posts.size());
+    }
+}