Merge "上传对应xml文件"
diff --git a/src/main/java/com/pt5/pthouduan/controller/InvitesController.java b/src/main/java/com/pt5/pthouduan/controller/InvitesController.java
new file mode 100644
index 0000000..e3a8d8d
--- /dev/null
+++ b/src/main/java/com/pt5/pthouduan/controller/InvitesController.java
@@ -0,0 +1,19 @@
+package com.pt5.pthouduan.controller;
+
+import com.pt5.pthouduan.entity.User;
+import com.pt5.pthouduan.service.InviteService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Map;
+
+@RestController
+@RequestMapping("/invite")
+public class InvitesController {
+    @Autowired
+    private InviteService inviteService;
+    @PostMapping("/sold")
+    public Map<String, Object> soldinvite(@RequestParam String buyername) {
+        return inviteService.setbuyername(buyername);
+    }
+}
diff --git a/src/main/java/com/pt5/pthouduan/controller/PostController.java b/src/main/java/com/pt5/pthouduan/controller/PostController.java
new file mode 100644
index 0000000..a3a9017
--- /dev/null
+++ b/src/main/java/com/pt5/pthouduan/controller/PostController.java
@@ -0,0 +1,149 @@
+package com.pt5.pthouduan.controller;
+
+import com.pt5.pthouduan.entity.Post;
+import com.pt5.pthouduan.service.PostService;
+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;
+
+/**
+ * <p>
+ *  帖子控制器
+ * </p>
+ *
+ * 功能:创建帖子(支持上传图片、置顶、范围控制)、点赞、取消点赞、关键词搜索、删除、更新、置顶与取消置顶
+ *
+ * @author
+ * @since 2025-05-10
+ */
+@CrossOrigin(origins = "http://localhost:5173")
+@Controller
+@RequestMapping("/post")
+public class PostController {
+
+    @Autowired
+    private PostService postService;
+
+    // 创建帖子(支持图片上传)
+    @PostMapping("/create")
+    @ResponseBody
+    public boolean createPost(
+            @RequestParam("userid") Long userid,
+            @RequestParam("post_title") String post_title,
+            @RequestParam("post_content") String post_content,
+            @RequestParam(value = "tags", required = false) String tags,
+            @RequestParam(value = "rannge", required = false) String rannge,
+            @RequestParam(value = "is_pinned", required = false) Boolean is_pinned,
+            @RequestParam(value = "photo", required = false) MultipartFile photoFile
+    ) {
+        Post post = new Post();
+        post.setUserid(userid);
+        post.setPostTitle(post_title);
+        post.setPostContent(post_content);
+        post.setTags(tags);
+        post.setRannge(rannge);
+        post.setIsSticky(is_pinned != null && is_pinned);
+        post.setPostCreatedTime(LocalDateTime.now());
+        post.setUpdatedTime(LocalDateTime.now());
+        post.setLikes(0);
+
+
+        // 保存图片
+        if (photoFile != null && !photoFile.isEmpty()) {
+            String uploadDir = "D:/postuploads/";
+            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);
+                post.setPhoto("/images/" + fileName);
+            } catch (IOException e) {
+                e.printStackTrace();
+                return false;
+            }
+        }
+
+        return postService.createPost(post) != null;
+    }
+
+
+
+    // 删除帖子
+    @DeleteMapping("/delete/{postid}")
+    @ResponseBody
+    public boolean deletePost(@PathVariable Integer postid) {
+        return postService.deletePost(postid);
+    }
+
+    // 更新帖子(包括置顶、范围、照片等)
+    @PutMapping("/update")
+    @ResponseBody
+    public boolean updatePost(@RequestBody Post post) {
+        return postService.updatePost(post);
+    }
+
+    // 关键词搜索
+    @GetMapping("/search")
+    @ResponseBody
+    public List<Post> searchPosts(@RequestParam String keyword) {
+        return postService.searchPostsByKeyword(keyword);
+    }
+
+    // 点赞
+    @PutMapping("/like/{postid}")
+    @ResponseBody
+    public boolean likePost(@PathVariable Integer postid) {
+        return postService.incrementLikes(postid);
+    }
+
+    @GetMapping("/all")
+    @ResponseBody
+    public List<Post> getAllPostsSorted() {
+        return postService.getAllPostsSorted();
+    }
+
+
+    // 取消点赞
+    @PutMapping("/unlike/{postid}")
+    @ResponseBody
+    public boolean unlikePost(@PathVariable Integer postid) {
+        return postService.decrementLikes(postid);
+    }
+
+    // 置顶帖子
+    @PutMapping("/pin/{postid}")
+    @ResponseBody
+    public boolean pinPost(@PathVariable Integer postid) {
+        return postService.setPinnedStatus(postid, true);
+    }
+
+    // 取消置顶
+    @PutMapping("/unpin/{postid}")
+    @ResponseBody
+    public boolean unpinPost(@PathVariable Integer postid) {
+        return postService.setPinnedStatus(postid, false);
+    }
+
+    // 根据用户ID获取该用户所有帖子
+    @GetMapping("/findByUserid")
+    @ResponseBody
+    public List<Post> findByUserid(@RequestParam Long userid) {
+        return postService.findByUserid(userid);
+    }
+
+    // 根据是否置顶查找帖子
+    @GetMapping("/findPinned")
+    @ResponseBody
+    public List<Post> findPinnedPosts() {
+        return postService.findPinnedPosts();
+    }
+}
diff --git a/src/main/java/com/pt5/pthouduan/controller/UserController.java b/src/main/java/com/pt5/pthouduan/controller/UserController.java
index 634f07f..82ac9fd 100644
--- a/src/main/java/com/pt5/pthouduan/controller/UserController.java
+++ b/src/main/java/com/pt5/pthouduan/controller/UserController.java
@@ -6,6 +6,8 @@
 import org.springframework.web.bind.annotation.*;
 import org.springframework.stereotype.Controller;
 
+import java.util.Map;
+
 /**
  * <p>
  *  前端控制器
@@ -14,19 +16,49 @@
  * @author ljx
  * @since 2025-04-14
  */
-@Controller
+@RestController
 @RequestMapping("/user")
 public class UserController {
     @Autowired
     private UserService userService;
 
-    // 创建用户
-    @PostMapping("/create")
-    @ResponseBody
-    public User createUser(@RequestBody User user) {
-        return userService.createUser(user);
+    @PostMapping("/register")
+    public Map<String, Object> register(@RequestBody User user,@RequestParam String code) {
+        return userService.register(user,code);
     }
 
+    @PostMapping("/login")
+    public Map<String, Object> login(@RequestParam String username,
+                                     @RequestParam String password) {
+        return userService.login(username, password);
+    }
 
+    @PostMapping("/calgrade")
+    public Map<String, Object> calgrade(@RequestParam String username) {
+        return userService.CalGrade(username);
+    }
 
+    @PostMapping("/changesex")
+    public Map<String, Object> changsex(@RequestParam String username,
+                                        @RequestParam String sex) {
+        return userService.changesex(username,sex);
+    }
+
+    @PostMapping("/changeimage")
+    public Map<String, Object> changeimage(@RequestParam String username,
+                                        @RequestParam String image) {
+        return userService.changeImage(username,image);
+    }
+
+    @PostMapping("/changePassword")
+    public Map<String, Object> changePassword(@RequestParam String username,
+                                              @RequestParam String oldpassword,
+                                              @RequestParam String newpassword) {
+        return userService.changePassword(username,oldpassword,newpassword);
+    }
+
+    @GetMapping("/info")
+    public Map<String, Object> getUserInfo(@RequestParam(required = false) String username) {
+        return userService.login(username, "");
+    }
 }
diff --git a/src/main/java/com/pt5/pthouduan/entity/Invites.java b/src/main/java/com/pt5/pthouduan/entity/Invites.java
index 80f37b4..2fdad23 100644
--- a/src/main/java/com/pt5/pthouduan/entity/Invites.java
+++ b/src/main/java/com/pt5/pthouduan/entity/Invites.java
@@ -13,7 +13,7 @@
  * @author ljx
  * @since 2025-04-14
  */
-@TableName("invites")
+@TableName("invite")
 public class Invites implements Serializable {
 
     private static final long serialVersionUID = 1L;
@@ -21,13 +21,16 @@
     @TableId("inviteid")
     private Long inviteid;
 
-    private Long userid;
+    private String username;//新用户用户名
 
-    private String invitedUserEmail;
+    private String buyername;//邀请人用户名
 
     private String code;
 
-    private Boolean isUsed;
+    private int isUsed;
+
+
+
 
     public Long getInviteid() {
         return inviteid;
@@ -37,21 +40,14 @@
         this.inviteid = inviteid;
     }
 
-    public Long getUserid() {
-        return userid;
+    public String getUsername() {
+        return username;
     }
 
-    public void setUserid(Long userid) {
-        this.userid = userid;
+    public void setUsername(String userid) {
+        this.username = userid;
     }
 
-    public String getInvitedUserEmail() {
-        return invitedUserEmail;
-    }
-
-    public void setInvitedUserEmail(String invitedUserEmail) {
-        this.invitedUserEmail = invitedUserEmail;
-    }
 
     public String getCode() {
         return code;
@@ -61,11 +57,11 @@
         this.code = code;
     }
 
-    public Boolean getIsUsed() {
+    public int getIsUsed() {
         return isUsed;
     }
 
-    public void setIsUsed(Boolean isUsed) {
+    public void setIsUsed(int isUsed) {
         this.isUsed = isUsed;
     }
 
@@ -73,10 +69,17 @@
     public String toString() {
         return "Invites{" +
         "inviteid = " + inviteid +
-        ", userid = " + userid +
-        ", invitedUserEmail = " + invitedUserEmail +
+        ", username = " + username + ", buyername = " + buyername +
         ", code = " + code +
         ", isUsed = " + isUsed +
         "}";
     }
+
+    public String getBuyername() {
+        return buyername;
+    }
+
+    public void setBuyername(String buyername) {
+        this.buyername = buyername;
+    }
 }
diff --git a/src/main/java/com/pt5/pthouduan/entity/Post.java b/src/main/java/com/pt5/pthouduan/entity/Post.java
index d04a601..843800d 100644
--- a/src/main/java/com/pt5/pthouduan/entity/Post.java
+++ b/src/main/java/com/pt5/pthouduan/entity/Post.java
@@ -11,7 +11,7 @@
  * 
  * </p>
  *
- * @author ljx
+ * @author ym
  * @since 2025-04-14
  */
 @TableName("post")
@@ -22,16 +22,26 @@
     @TableId("postid")
     private Integer postid;
 
+    private Integer likes;
+
     private Long userid;
 
-    private LocalDateTime updatedTime;
+    private String photo;
 
-    private Boolean isSticky;
+    private String rannge;
 
-    private String postTitle;
+    private LocalDateTime updated_time;
+
+    private Boolean is_pinned;
+
+    private String post_title;
 
     private LocalDateTime postCreatedTime;
 
+    private String post_content;
+
+    private String tags;
+
     public Integer getPostid() {
         return postid;
     }
@@ -40,6 +50,14 @@
         this.postid = postid;
     }
 
+    public Integer getLikes() {
+        return likes;
+    }
+
+    public void setLikes(Integer likes) {
+        this.likes = likes;
+    }
+
     public Long getUserid() {
         return userid;
     }
@@ -49,27 +67,52 @@
     }
 
     public LocalDateTime getUpdatedTime() {
-        return updatedTime;
+        return updated_time;
     }
 
-    public void setUpdatedTime(LocalDateTime updatedTime) {
-        this.updatedTime = updatedTime;
+    public void setUpdatedTime(LocalDateTime updated_time) {
+        this.updated_time = updated_time;
+    }
+
+    public String getTags() {//获取标签
+        return tags;
+    }
+
+    public void setTags(String tags) {
+        this.tags = tags;
+    }
+
+
+    public String getPhoto() {//获取标签
+        return photo;
+    }
+
+    public void setPhoto(String photo) {
+        this.photo = photo;
+    }
+
+    public String getRannge() {
+        return rannge;
+    }
+
+    public void setRannge(String rannge) {
+        this.rannge = rannge;
     }
 
     public Boolean getIsSticky() {
-        return isSticky;
+        return is_pinned;
     }
 
-    public void setIsSticky(Boolean isSticky) {
-        this.isSticky = isSticky;
+    public void setIsSticky(Boolean is_pinned) {
+        this.is_pinned = is_pinned;
     }
 
     public String getPostTitle() {
-        return postTitle;
+        return post_title;
     }
 
-    public void setPostTitle(String postTitle) {
-        this.postTitle = postTitle;
+    public void setPostTitle(String post_title) {
+        this.post_title = post_title;
     }
 
     public LocalDateTime getPostCreatedTime() {
@@ -80,15 +123,28 @@
         this.postCreatedTime = postCreatedTime;
     }
 
+    public String getPostContent() {
+        return post_content;
+    }
+
+    public void setPostContent(String post_content) {
+        this.post_content = post_content;
+    }
+
     @Override
     public String toString() {
         return "Post{" +
-        "postid = " + postid +
-        ", userid = " + userid +
-        ", updatedTime = " + updatedTime +
-        ", isSticky = " + isSticky +
-        ", postTitle = " + postTitle +
-        ", postCreatedTime = " + postCreatedTime +
-        "}";
+                "postid=" + postid +
+                ", userid=" + userid +
+                ", photo='" + photo + '\'' +
+                ", updatedTime=" + updated_time +
+                ", likes=" + likes +
+                ", is_pinned=" + is_pinned +
+                ", post_title='" + post_title + '\'' +
+                ", post_content='" + post_content + '\'' +
+                ", postCreatedTime=" + postCreatedTime +
+                ", tags='" + tags + '\'' +
+                ", rannge='" + rannge + '\'' +
+                '}';
     }
 }
diff --git a/src/main/java/com/pt5/pthouduan/entity/User.java b/src/main/java/com/pt5/pthouduan/entity/User.java
index 3a765b8..b1128be 100644
--- a/src/main/java/com/pt5/pthouduan/entity/User.java
+++ b/src/main/java/com/pt5/pthouduan/entity/User.java
@@ -40,14 +40,14 @@
 
     private String passkey;
 
-    private LocalDateTime userCreatedTime;
-
     private Double ratio;
 
     private Integer age;
 
     private Integer privacy;
 
+    private String email;
+
     // 构造函数
     public User(Long id, String name) {
         this.userid = id;
@@ -56,7 +56,7 @@
 
     public String getUsername() {
         return username;
-    }
+    }//用户名
 
     public void setUsername(String username) {
         this.username = username;
@@ -64,7 +64,7 @@
 
     public String getPassword() {
         return password;
-    }
+    }//密码
 
     public void setPassword(String password) {
         this.password = password;
@@ -72,7 +72,7 @@
 
     public Integer getUserUpload() {
         return userUpload;
-    }
+    }//上传量
 
     public void setUserUpload(Integer userUpload) {
         this.userUpload = userUpload;
@@ -80,7 +80,7 @@
 
     public Long getUserDownload() {
         return userDownload;
-    }
+    }//下载量
 
     public void setUserDownload(Long userDownload) {
         this.userDownload = userDownload;
@@ -88,7 +88,7 @@
 
     public Integer getCredit() {
         return credit;
-    }
+    }//保种积分
 
     public void setCredit(Integer credit) {
         this.credit = credit;
@@ -96,7 +96,7 @@
 
     public String getImage() {
         return image;
-    }
+    }//头像
 
     public void setImage(String image) {
         this.image = image;
@@ -104,7 +104,7 @@
 
     public String getSex() {
         return sex;
-    }
+    }//性别
 
     public void setSex(String sex) {
         this.sex = sex;
@@ -120,7 +120,7 @@
 
     public Integer getGradeId() {
         return gradeId;
-    }
+    }//等级
 
     public void setGradeId(Integer gradeId) {
         this.gradeId = gradeId;
@@ -128,23 +128,15 @@
 
     public String getPasskey() {
         return passkey;
-    }
+    }//密码
 
     public void setPasskey(String passkey) {
         this.passkey = passkey;
     }
 
-    public LocalDateTime getUserCreatedTime() {
-        return userCreatedTime;
-    }
-
-    public void setUserCreatedTime(LocalDateTime userCreatedTime) {
-        this.userCreatedTime = userCreatedTime;
-    }
-
     public Double getRatio() {
         return ratio;
-    }
+    }//分享率
 
     public void setRatio(Double ratio) {
         this.ratio = ratio;
@@ -152,7 +144,7 @@
 
     public Integer getAge() {
         return age;
-    }
+    }//年龄
 
     public void setAge(Integer age) {
         this.age = age;
@@ -160,7 +152,7 @@
 
     public Integer getPrivacy() {
         return privacy;
-    }
+    }//权限
 
     public void setPrivacy(Integer privacy) {
         this.privacy = privacy;
@@ -179,10 +171,17 @@
         ", userid = " + userid +
         ", gradeId = " + gradeId +
         ", passkey = " + passkey +
-        ", userCreatedTime = " + userCreatedTime +
         ", ratio = " + ratio +
         ", age = " + age +
-        ", privacy = " + privacy +
+        ", privacy = " + privacy + ", email = " + email +
         "}";
     }
+
+    public String getEmail() {
+        return email;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
 }
diff --git a/src/main/java/com/pt5/pthouduan/mapper/InvitesMapper.java b/src/main/java/com/pt5/pthouduan/mapper/InvitesMapper.java
index 6cc278b..fddf6df 100644
--- a/src/main/java/com/pt5/pthouduan/mapper/InvitesMapper.java
+++ b/src/main/java/com/pt5/pthouduan/mapper/InvitesMapper.java
@@ -2,17 +2,25 @@
 
 import com.pt5.pthouduan.entity.Invites;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.pt5.pthouduan.entity.User;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+import org.apache.ibatis.annotations.Update;
+import org.springframework.stereotype.Repository;
 
-/**
- * <p>
- *  Mapper 接口
- * </p>
- *
- * @author ljx
- * @since 2025-04-14
- */
-@Mapper
+@Repository
 public interface InvitesMapper extends BaseMapper<Invites> {
 
+    @Select("SELECT * FROM invite WHERE code = #{code}")
+    Invites selectByCode(String code);
+
+    @Update("UPDATE invite SET isUsed = 1, username = #{username} WHERE code = #{code}")
+    int updateInviteByCode(@Param("code") String code, @Param("username") String username);
+
+    @Select("SELECT * FROM invite WHERE buyername = '' LIMIT 1")
+    Invites selectFirstEmptyBuyername();
+
+    @Update("UPDATE invite SET buyername = #{buyername} WHERE code = #{code}")
+    int updatebuyer(@Param("code") String code, @Param("buyername") String buyername);
 }
diff --git a/src/main/java/com/pt5/pthouduan/mapper/PostMapper.java b/src/main/java/com/pt5/pthouduan/mapper/PostMapper.java
index 817e555..6b95c73 100644
--- a/src/main/java/com/pt5/pthouduan/mapper/PostMapper.java
+++ b/src/main/java/com/pt5/pthouduan/mapper/PostMapper.java
@@ -3,16 +3,50 @@
 import com.pt5.pthouduan.entity.Post;
 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
+ * 功能:增、删、改、查(按关键词)、点赞、置顶、用户帖子查询、置顶帖子查询
+ *
+ * 作者:杨蔓
  * @since 2025-04-14
  */
 @Mapper
 public interface PostMapper extends BaseMapper<Post> {
 
+    // 创建帖子
+    void save(Post post);
+
+    // 根据帖子ID删除
+    int deleteByPostid(@Param("postid") Integer postid);
+
+    // 更新帖子
+    int updatePost(Post post);
+
+    // 模糊搜索(标题或标签)
+    List<Post> searchByKeyword(@Param("keyword") String keyword);
+
+    // 点赞 +1
+    int incrementLikes(@Param("postid") Integer postid);
+
+    // 取消点赞 -1(最小为0)
+    int decrementLikes(@Param("postid") Integer postid);
+
+    // 设置置顶状态
+    int updatePinnedStatus(@Param("postid") Integer postid, @Param("pinned") boolean pinned);
+
+    // 根据用户ID查询该用户所有帖子
+    List<Post> findByUserid(@Param("userid") Long userid);
+
+    // 查询所有置顶帖子
+    List<Post> findPinnedPosts();
+
+    // ✅ 新增:查询所有帖子(置顶优先,时间倒序)
+    List<Post> selectAllSorted();
 }
diff --git a/src/main/java/com/pt5/pthouduan/mapper/UserMapper.java b/src/main/java/com/pt5/pthouduan/mapper/UserMapper.java
index 8a250f0..89c37ab 100644
--- a/src/main/java/com/pt5/pthouduan/mapper/UserMapper.java
+++ b/src/main/java/com/pt5/pthouduan/mapper/UserMapper.java
@@ -2,17 +2,30 @@
 
 import com.pt5.pthouduan.entity.User;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.*;
+import org.springframework.stereotype.Repository;
 
-/**
- * <p>
- *  Mapper 接口
- * </p>
- *
- * @author ljx
- * @since 2025-04-14
- */
-@Mapper
+
+@Repository
 public interface UserMapper extends BaseMapper<User> {
+    @Insert("INSERT INTO user(username, password, email, passkey) VALUES(#{username}, #{password}, #{email}, #{passkey})")
+    int insert(User user);
 
+    @Select("SELECT * FROM User WHERE username = #{username}")
+    User selectByUsername(String username);
+
+    @Select("SELECT * FROM User WHERE email = #{email}")
+    User selectByEmail(String email);
+
+    @Update("UPDATE user SET password = #{password} WHERE username = #{username}")
+    int updatePassword(@Param("username") String username, @Param("password") String password);
+
+    @Update("UPDATE user SET sex = #{sex} WHERE username = #{username}")
+    int updatesex(@Param("username") String username, @Param("sex") String sex);
+
+    @Update("UPDATE user SET image = #{image} WHERE username = #{username}")
+    int updateimage(@Param("username") String username, @Param("image") String image);
+
+    @Update("UPDATE user SET gradeId = #{gradeId} WHERE username = #{username}")
+    int updateGrade(@Param("username") String username, @Param("gradeId") Integer gradeId);
 }
diff --git a/src/main/java/com/pt5/pthouduan/service/InviteService.java b/src/main/java/com/pt5/pthouduan/service/InviteService.java
new file mode 100644
index 0000000..f6ca8a6
--- /dev/null
+++ b/src/main/java/com/pt5/pthouduan/service/InviteService.java
@@ -0,0 +1,28 @@
+package com.pt5.pthouduan.service;
+
+import com.pt5.pthouduan.entity.Invites;
+import com.pt5.pthouduan.mapper.InvitesMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Service
+public class InviteService {
+    @Autowired
+    private InvitesMapper invitesMapper;
+    //批量生成邀请码并存入数据库(6位)(这个直接在数据库更新)
+    //邀请码卖出(set buyername)
+    public Map<String, Object> setbuyername(String buyername){
+        Map<String, Object> result = new HashMap<>();
+        Invites invite=invitesMapper.selectFirstEmptyBuyername();
+        invitesMapper.updatebuyer(invite.getCode(),buyername);
+        result.put("success", true);
+        result.put("invitecode", invite.getCode());
+        result.put("message", "邀请码购买成功");
+        return result;
+    }
+
+
+}
diff --git a/src/main/java/com/pt5/pthouduan/service/PostService.java b/src/main/java/com/pt5/pthouduan/service/PostService.java
new file mode 100644
index 0000000..fabf254
--- /dev/null
+++ b/src/main/java/com/pt5/pthouduan/service/PostService.java
@@ -0,0 +1,46 @@
+package com.pt5.pthouduan.service;
+
+import com.pt5.pthouduan.entity.Post;
+
+import java.util.List;
+
+/**
+ * <p>
+ *  帖子服务接口
+ * </p>
+ *
+ * 功能:
+ *  - 增、删、改、查(按标签或标题)
+ *  - 点赞、取消点赞
+ *  - 设置置顶状态
+ *  - 可设置可见范围
+ *  - 上传图片(通常可选放在 Controller)
+ *  - 查找用户所有帖子
+ *  - 查找置顶帖子
+ *  - 获取所有帖子(置顶优先,时间倒序)
+ *
+ * @author 杨蔓
+ * @since 2025-04-14
+ */
+public interface PostService {
+
+    Post createPost(Post post);                      // 创建帖子
+
+    boolean deletePost(Integer postid);              // 删除帖子
+
+    boolean updatePost(Post post);                   // 更新帖子
+
+    List<Post> searchPostsByKeyword(String keyword); // 查找帖子(标题或标签)
+
+    boolean incrementLikes(Integer postid);          // 点赞(likes + 1)
+
+    boolean decrementLikes(Integer postid);          // 取消点赞(likes - 1,最小为0)
+
+    boolean setPinnedStatus(Integer postid, boolean pinned); // 设置是否置顶
+
+    List<Post> findByUserid(Long userid);            // 根据用户 ID 获取帖子
+
+    List<Post> findPinnedPosts();                    // 查找所有置顶帖子
+
+    List<Post> getAllPostsSorted();                  // ✅ 获取所有帖子(置顶优先,按时间排序)
+}
diff --git a/src/main/java/com/pt5/pthouduan/service/UserService.java b/src/main/java/com/pt5/pthouduan/service/UserService.java
index 1a14ad1..365580f 100644
--- a/src/main/java/com/pt5/pthouduan/service/UserService.java
+++ b/src/main/java/com/pt5/pthouduan/service/UserService.java
@@ -1,20 +1,159 @@
 package com.pt5.pthouduan.service;
-
+import com.pt5.pthouduan.entity.Invites;
 import com.pt5.pthouduan.entity.User;
-import com.baomidou.mybatisplus.extension.service.IService;
+import com.pt5.pthouduan.mapper.InvitesMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import com.pt5.pthouduan.mapper.UserMapper;
+import org.springframework.stereotype.Service;
+import org.springframework.util.DigestUtils;
+import org.springframework.util.StringUtils;
+import java.security.SecureRandom;
 
-/**
- * <p>
- *  服务类
- * </p>
- *
- * @author ljx
- * @since 2025-04-14
- */
-public interface UserService{
-    // 根据ID获取用户
-    // 创建用户
-    User createUser(User user);
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
 
+@Service
+public class UserService {
+    @Autowired
+    private UserMapper userMapper;
+    @Autowired
+    private InvitesMapper invitesMapper;
+    // 注册业务
+    public Map<String, Object> register(User user,String code) {
+        Map<String, Object> result = new HashMap<>();
 
+        // 参数校验
+        if (!StringUtils.hasText(user.getUsername())){
+            result.put("success", false);
+            result.put("message", "用户名不能为空");
+            return result;
+        }
+
+        if (!StringUtils.hasText(user.getPassword())) {
+            result.put("success", false);
+            result.put("message", "密码不能为空");
+            return result;
+        }
+
+        // 检查用户名是否已存在
+        if (userMapper.selectByUsername(user.getUsername()) != null) {
+            result.put("success", false);
+            result.put("message", "用户名已存在");
+            return result;
+        }
+
+        // 检查邮箱是否已存在
+        if (userMapper.selectByEmail(user.getEmail()) != null) {
+            result.put("success", false);
+            result.put("message", "邮箱已注册");
+            return result;
+        }
+        //检查邀请码是否有效
+        Invites invite= invitesMapper.selectByCode(code);
+        if(invite==null){//邀请码不存在
+            result.put("success", false);
+            result.put("message","无效的邀请码");
+            return result;
+        }
+        if(invite.getIsUsed()==1){//邀请码已被使用
+            result.put("success", false);
+            result.put("message","邀请码已被使用");
+            return result;
+        }
+        //邮箱发送验证码验证
+        //To do... ..
+        //生成passkey
+        SecureRandom random = new SecureRandom();
+        user.setPasskey(String.valueOf(10000000 + random.nextInt(90000000)));
+        // 保存用户
+        userMapper.insert(user);
+        invitesMapper.updateInviteByCode(code,user.getUsername());
+        result.put("success", true);
+        result.put("message", "注册成功");
+        return result;
+    }
+
+    // 登录业务
+    public Map<String, Object> login(String username, String password) {
+        Map<String, Object> result = new HashMap<>();
+
+        User user = userMapper.selectByUsername(username);//首先验证用户名
+        if (user == null) {
+            result.put("success", false);
+            result.put("message", "用户不存在");
+            return result;
+        }
+
+        //验证密码
+        if(!password.equals(user.getPassword())){
+            result.put("success", false);
+            result.put("message","密码错误,请检查后重新输入");
+            return result;
+        }
+        // 登录成功,返回用户信息(密码置空)
+        user.setPassword(null);
+        result.put("success", true);
+        result.put("message", "登录成功");
+        result.put("user", user);
+        return result;
+    }
+    //更新用户等级
+    public Map<String, Object> CalGrade(String username){
+        Map<String, Object> result = new HashMap<>();
+        //上传量+下载量0-500000 一级  510000-2000000 二级 2010000-3500000 三级 3510000-6500000 四级 6500000以上 五级
+        User user = userMapper.selectByUsername(username);
+        if(user.getUserUpload()+user.getUserDownload()<=500000*1024){
+            user.setGradeId(1);
+        }else if(user.getUserUpload()+user.getUserDownload()<=2000000*1024){
+            user.setGradeId(2);
+        }else if(user.getUserUpload()+user.getUserDownload()<= 3500000L *1024){
+            user.setGradeId(3);
+        }else if(user.getUserUpload()+user.getUserDownload()<= 6500000L *1024){
+            user.setGradeId(4);
+        }else{ user.setGradeId(5);}
+        userMapper.updateGrade(username,user.getGradeId());
+        result.put("success", true);
+        result.put("message", "等级更新成功");
+        result.put("grade", user.getGradeId());
+        return result;
+    }
+    //设置性别
+    public Map<String, Object> changesex(String username,String sex){
+        Map<String, Object> result = new HashMap<>();
+        userMapper.updatesex(username,sex);
+        result.put("success", true);
+        result.put("message", "性别设置成功");
+        return result;
+    }
+    //设置头像
+    public Map<String, Object> changeImage(String username,String image){
+        Map<String, Object> result = new HashMap<>();
+        userMapper.updateimage(username,image);
+        result.put("success", true);
+        result.put("message", "头像设置成功");
+        return result;
+    }
+    //更改密码
+    public Map<String, Object> changePassword(String username,String oldpassword,String newpassword){
+        Map<String, Object> result = new HashMap<>();
+        User user = userMapper.selectByUsername(username);//首先验证用户名
+        if (user == null) {
+            result.put("success", false);
+            result.put("message", "用户不存在");
+            return result;
+        }
+
+        //验证密码
+        if(!oldpassword.equals(user.getPassword())){
+            result.put("success", false);
+            result.put("message","密码错误,请检查后重新输入");
+            return result;
+        }
+        //更改数据库中的密码
+        userMapper.updatePassword(username,newpassword);
+        result.put("success", true);
+        result.put("message", "密码重置成功");
+        return result;
+    }
 }
diff --git a/src/main/java/com/pt5/pthouduan/service/impl/PostServiceImpl.java b/src/main/java/com/pt5/pthouduan/service/impl/PostServiceImpl.java
new file mode 100644
index 0000000..d1bda7f
--- /dev/null
+++ b/src/main/java/com/pt5/pthouduan/service/impl/PostServiceImpl.java
@@ -0,0 +1,76 @@
+package com.pt5.pthouduan.service.impl;
+
+import com.pt5.pthouduan.entity.Post;
+import com.pt5.pthouduan.mapper.PostMapper;
+import com.pt5.pthouduan.service.PostService;
+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 PostServiceImpl implements PostService {
+
+    @Autowired
+    private PostMapper postMapper;
+
+    @Override
+    public Post createPost(Post post) {
+        postMapper.save(post);
+        return post;
+    }
+
+    @Override
+    public boolean deletePost(Integer postid) {
+        return postMapper.deleteByPostid(postid) > 0;
+    }
+
+    @Override
+    public boolean updatePost(Post post) {
+        return postMapper.updatePost(post) > 0;
+    }
+
+    @Override
+    public List<Post> searchPostsByKeyword(String keyword) {
+        return postMapper.searchByKeyword(keyword);
+    }
+
+    @Override
+    public boolean incrementLikes(Integer postid) {
+        return postMapper.incrementLikes(postid) >= 0;
+    }
+
+    @Override
+    public boolean decrementLikes(Integer postid) {
+        return postMapper.decrementLikes(postid) >= 0;
+    }
+
+    @Override
+    public boolean setPinnedStatus(Integer postid, boolean pinned) {
+        return postMapper.updatePinnedStatus(postid, pinned) > 0;
+    }
+
+    @Override
+    public List<Post> findByUserid(Long userid) {
+        return postMapper.findByUserid(userid);
+    }
+
+    @Override
+    public List<Post> findPinnedPosts() {
+        return postMapper.findPinnedPosts();
+    }
+
+    /** ✅ 新增:获取所有帖子(置顶优先,时间倒序) */
+    @Override
+    public List<Post> getAllPostsSorted() {
+        return postMapper.selectAllSorted();
+    }
+}
diff --git a/src/main/java/com/pt5/pthouduan/service/impl/UserServiceImpl.java b/src/main/java/com/pt5/pthouduan/service/impl/UserServiceImpl.java
index 4811fe5..7db925d 100644
--- a/src/main/java/com/pt5/pthouduan/service/impl/UserServiceImpl.java
+++ b/src/main/java/com/pt5/pthouduan/service/impl/UserServiceImpl.java
@@ -1,9 +1,7 @@
 package com.pt5.pthouduan.service.impl;
 
 import com.pt5.pthouduan.entity.User;
-import com.pt5.pthouduan.mapper.UserMapper;
 import com.pt5.pthouduan.service.UserService;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.springframework.stereotype.Service;
 
 /**
@@ -15,12 +13,6 @@
  * @since 2025-04-14
  */
 @Service
-public class UserServiceImpl implements UserService {
-    @Override
-    public User createUser(User user) {
-        // 模拟创建用户
-        return user;
-    }
-
+public class UserServiceImpl extends UserService {
 
 }
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index e8d6bd9..34a3a7e 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -1,7 +1,7 @@
 spring.application.name=PT-houduan
 spring.datasource.url=jdbc:mysql://localhost:3306/pt?useSSL=false&serverTimezone=Asia/Shanghai
 spring.datasource.username=root
-spring.datasource.password=12345
+spring.datasource.password=123456
 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
 
 # MyBatis-Plus ??
diff --git a/src/main/resources/mapper/PostMapper.xml b/src/main/resources/mapper/PostMapper.xml
new file mode 100644
index 0000000..e676fcc
--- /dev/null
+++ b/src/main/resources/mapper/PostMapper.xml
@@ -0,0 +1,103 @@
+<?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.PostMapper">
+
+    <!-- 插入帖子 -->
+    <insert id="save" parameterType="com.pt5.pthouduan.entity.Post"
+            useGeneratedKeys="true" keyProperty="postid" keyColumn="postid">
+        INSERT INTO post (
+            userid,
+            photo,
+            rannge,
+            is_pinned,
+            post_title,
+            post_content,
+            postCreatedTime,
+            updated_time,
+            tags,
+            likes
+        ) VALUES (
+                     #{userid},
+                     #{photo},
+                     #{rannge},
+                     #{is_pinned},
+                     #{post_title},
+                     #{post_content},
+                     #{postCreatedTime},
+                     #{updated_time},
+                     #{tags},
+                     COALESCE(#{likes}, 0)
+                 )
+    </insert>
+
+    <!-- 删除帖子 -->
+    <delete id="deleteByPostid" parameterType="int">
+        DELETE FROM post WHERE postid = #{postid}
+    </delete>
+
+    <!-- 更新帖子 -->
+    <update id="updatePost" parameterType="com.pt5.pthouduan.entity.Post">
+        UPDATE post
+        SET
+            userid = #{userid},
+            photo = #{photo},
+            rannge = #{rannge},
+            updated_time = #{updated_time},
+            is_pinned = #{is_pinned},
+            post_title = #{post_title},
+            post_content = #{post_content},
+            postCreatedTime = #{postCreatedTime},
+            tags = #{tags},
+            likes = COALESCE(#{likes}, 0)
+        WHERE postid = #{postid}
+    </update>
+
+    <!-- 模糊搜索帖子 -->
+    <select id="searchByKeyword" resultType="com.pt5.pthouduan.entity.Post">
+        SELECT * FROM post
+        WHERE post_title LIKE CONCAT('%', #{keyword}, '%')
+           OR tags LIKE CONCAT('%', #{keyword}, '%')
+    </select>
+
+    <!-- 点赞 +1 -->
+    <update id="incrementLikes" parameterType="int">
+        UPDATE post
+        SET likes = likes + 1
+        WHERE postid = #{postid}
+    </update>
+
+    <!-- 取消点赞 -->
+    <update id="decrementLikes" parameterType="int">
+        UPDATE post
+        SET likes = CASE WHEN likes > 0 THEN likes - 1 ELSE 0 END
+        WHERE postid = #{postid}
+    </update>
+
+    <!-- 更新置顶状态 -->
+    <update id="updatePinnedStatus" parameterType="map">
+        UPDATE post
+        SET is_pinned = #{pinned}
+        WHERE postid = #{postid}
+    </update>
+
+    <!-- 根据用户 ID 查询其所有帖子 -->
+    <select id="findByUserid" resultType="com.pt5.pthouduan.entity.Post">
+        SELECT * FROM post
+        WHERE userid = #{userid}
+    </select>
+
+    <!-- 查询所有置顶帖子 -->
+    <select id="findPinnedPosts" resultType="com.pt5.pthouduan.entity.Post">
+        SELECT * FROM post
+        WHERE is_pinned = TRUE
+    </select>
+
+    <!-- 查询所有帖子,按置顶优先、创建时间倒序 -->
+    <select id="selectAllSorted" resultType="com.pt5.pthouduan.entity.Post">
+        SELECT * FROM post
+        ORDER BY is_pinned DESC, postCreatedTime DESC
+    </select>
+
+</mapper>
diff --git a/src/test/java/com/pt5/pthouduan/ControllerTest/InvitesControllerTest.java b/src/test/java/com/pt5/pthouduan/ControllerTest/InvitesControllerTest.java
new file mode 100644
index 0000000..9477df4
--- /dev/null
+++ b/src/test/java/com/pt5/pthouduan/ControllerTest/InvitesControllerTest.java
@@ -0,0 +1,98 @@
+package com.pt5.pthouduan.ControllerTest;
+
+import com.pt5.pthouduan.controller.InvitesController;
+import com.pt5.pthouduan.service.InviteService;
+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.HashMap;
+import java.util.Map;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.*;
+
+class InvitesControllerTest {
+
+    @Mock
+    private InviteService inviteService;
+
+    @InjectMocks
+    private InvitesController invitesController;
+
+    @BeforeEach
+    void setUp() {
+        MockitoAnnotations.openMocks(this);
+    }
+
+    @Test
+    void soldinvite_ShouldCallServiceWithCorrectParameter() {
+        // 准备测试数据
+        String testBuyerName = "testBuyer";
+        Map<String, Object> expectedResponse = new HashMap<>();
+        expectedResponse.put("success", true);
+        expectedResponse.put("message", "Invite sold successfully");
+
+        // 模拟服务行为
+        when(inviteService.setbuyername(anyString())).thenReturn(expectedResponse);
+
+        // 执行测试
+        Map<String, Object> actualResponse = invitesController.soldinvite(testBuyerName);
+
+        // 验证行为
+        verify(inviteService, times(1)).setbuyername(testBuyerName);
+
+        // 验证结果
+        assertEquals(expectedResponse, actualResponse);
+        assertTrue((Boolean) actualResponse.get("success"));
+        assertEquals("Invite sold successfully", actualResponse.get("message"));
+    }
+
+    @Test
+    void soldinvite_ShouldHandleServiceFailure() {
+        // 准备测试数据
+        String testBuyerName = "testBuyer";
+        Map<String, Object> expectedResponse = new HashMap<>();
+        expectedResponse.put("success", false);
+        expectedResponse.put("error", "Invalid buyer name");
+
+        // 模拟服务行为
+        when(inviteService.setbuyername(anyString())).thenReturn(expectedResponse);
+
+        // 执行测试
+        Map<String, Object> actualResponse = invitesController.soldinvite(testBuyerName);
+
+        // 验证行为
+        verify(inviteService, times(1)).setbuyername(testBuyerName);
+
+        // 验证结果
+        assertEquals(expectedResponse, actualResponse);
+        assertFalse((Boolean) actualResponse.get("success"));
+        assertEquals("Invalid buyer name", actualResponse.get("error"));
+    }
+
+    @Test
+    void soldinvite_ShouldHandleNullInput() {
+        // 准备测试数据
+        Map<String, Object> expectedResponse = new HashMap<>();
+        expectedResponse.put("success", false);
+        expectedResponse.put("error", "Buyer name cannot be null");
+
+        // 模拟服务行为
+        when(inviteService.setbuyername(null)).thenReturn(expectedResponse);
+
+        // 执行测试
+        Map<String, Object> actualResponse = invitesController.soldinvite(null);
+
+        // 验证行为
+        verify(inviteService, times(1)).setbuyername(null);
+
+        // 验证结果
+        assertEquals(expectedResponse, actualResponse);
+        assertFalse((Boolean) actualResponse.get("success"));
+        assertEquals("Buyer name cannot be null", actualResponse.get("error"));
+    }
+}
diff --git a/src/test/java/com/pt5/pthouduan/ControllerTest/UserControllerTest.java b/src/test/java/com/pt5/pthouduan/ControllerTest/UserControllerTest.java
new file mode 100644
index 0000000..00c8354
--- /dev/null
+++ b/src/test/java/com/pt5/pthouduan/ControllerTest/UserControllerTest.java
@@ -0,0 +1,222 @@
+package com.pt5.pthouduan.ControllerTest;
+
+import com.pt5.pthouduan.controller.UserController;
+import com.pt5.pthouduan.entity.User;
+import com.pt5.pthouduan.service.UserService;
+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.http.ResponseEntity;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.*;
+
+class UserControllerTest {
+
+    @Mock
+    private UserService userService;
+
+    @InjectMocks
+    private UserController userController;
+
+    @BeforeEach
+    void setUp() {
+        MockitoAnnotations.openMocks(this);
+    }
+
+    // 注册测试
+    @Test
+    void register_ShouldCallServiceWithCorrectParameters() {
+        // 准备测试数据
+        User testUser = new User(1L,"");
+        testUser.setUsername("testUser");
+        String testCode = "123456";
+        Map<String, Object> expectedResponse = new HashMap<>();
+        expectedResponse.put("success", true);
+        expectedResponse.put("message", "注册成功");
+
+        // 模拟服务行为
+        when(userService.register(any(User.class), anyString())).thenReturn(expectedResponse);
+
+        // 执行测试
+        Map<String, Object> actualResponse = userController.register(testUser, testCode);
+
+        // 验证行为
+        verify(userService, times(1)).register(testUser, testCode);
+
+        // 验证结果
+        assertEquals(expectedResponse, actualResponse);
+    }
+
+    // 登录测试
+    @Test
+    void login_ShouldReturnSuccessWhenCredentialsAreValid() {
+        // 准备测试数据
+        String username = "testUser";
+        String password = "correctPassword";
+        Map<String, Object> expectedResponse = new HashMap<>();
+        expectedResponse.put("success", true);
+        expectedResponse.put("token", "sampleToken");
+
+        // 模拟服务行为
+        when(userService.login(eq(username), eq(password))).thenReturn(expectedResponse);
+
+        // 执行测试
+        Map<String, Object> actualResponse = userController.login(username, password);
+
+        // 验证行为
+        verify(userService, times(1)).login(username, password);
+
+        // 验证结果
+        assertEquals(expectedResponse, actualResponse);
+        assertTrue((Boolean) actualResponse.get("success"));
+        assertNotNull(actualResponse.get("token"));
+    }
+
+    // 计算等级测试
+    @Test
+    void calgrade_ShouldReturnUserGrade() {
+        // 准备测试数据
+        String username = "testUser";
+        Map<String, Object> expectedResponse = new HashMap<>();
+        expectedResponse.put("grade", 5);
+        expectedResponse.put("exp", 1200);
+
+        // 模拟服务行为
+        when(userService.CalGrade(eq(username))).thenReturn(expectedResponse);
+
+        // 执行测试
+        Map<String, Object> actualResponse = userController.calgrade(username);
+
+        // 验证行为
+        verify(userService, times(1)).CalGrade(username);
+
+        // 验证结果
+        assertEquals(5, actualResponse.get("grade"));
+        assertEquals(1200, actualResponse.get("exp"));
+    }
+
+    // 修改性别测试
+    @Test
+    void changesex_ShouldUpdateUserSex() {
+        // 准备测试数据
+        String username = "testUser";
+        String newSex = "male";
+        Map<String, Object> expectedResponse = new HashMap<>();
+        expectedResponse.put("success", true);
+        expectedResponse.put("message", "性别更新成功");
+
+        // 模拟服务行为
+        when(userService.changesex(eq(username), eq(newSex))).thenReturn(expectedResponse);
+
+        // 执行测试
+        Map<String, Object> actualResponse = userController.changsex(username, newSex);
+
+        // 验证行为
+        verify(userService, times(1)).changesex(username, newSex);
+
+        // 验证结果
+        assertTrue((Boolean) actualResponse.get("success"));
+        assertEquals("性别更新成功", actualResponse.get("message"));
+    }
+
+    // 修改头像测试
+    @Test
+    void changeimage_ShouldUpdateUserImage() {
+        // 准备测试数据
+        String username = "testUser";
+        String newImage = "newImageUrl";
+        Map<String, Object> expectedResponse = new HashMap<>();
+        expectedResponse.put("success", true);
+        expectedResponse.put("message", "头像更新成功");
+
+        // 模拟服务行为
+        when(userService.changeImage(eq(username), eq(newImage))).thenReturn(expectedResponse);
+
+        // 执行测试
+        Map<String, Object> actualResponse = userController.changeimage(username, newImage);
+
+        // 验证行为
+        verify(userService, times(1)).changeImage(username, newImage);
+
+        // 验证结果
+        assertTrue((Boolean) actualResponse.get("success"));
+        assertEquals("头像更新成功", actualResponse.get("message"));
+    }
+
+    // 修改密码测试
+    @Test
+    void changePassword_ShouldReturnSuccessWhenOldPasswordIsCorrect() {
+        // 准备测试数据
+        String username = "testUser";
+        String oldPassword = "correctOldPassword";
+        String newPassword = "newSecurePassword";
+        Map<String, Object> expectedResponse = new HashMap<>();
+        expectedResponse.put("success", true);
+        expectedResponse.put("message", "密码修改成功");
+
+        // 模拟服务行为
+        when(userService.changePassword(eq(username), eq(oldPassword), eq(newPassword)))
+                .thenReturn(expectedResponse);
+
+        // 执行测试
+        Map<String, Object> actualResponse = userController.changePassword(username, oldPassword, newPassword);
+
+        // 验证行为
+        verify(userService, times(1)).changePassword(username, oldPassword, newPassword);
+
+        // 验证结果
+        assertTrue((Boolean) actualResponse.get("success"));
+        assertEquals("密码修改成功", actualResponse.get("message"));
+    }
+
+    // 获取用户信息测试
+    @Test
+    void getUserInfo_ShouldReturnUserInfo() {
+        // 准备测试数据
+        String username = "testUser";
+        Map<String, Object> expectedResponse = new HashMap<>();
+        expectedResponse.put("username", username);
+        expectedResponse.put("email", "test@example.com");
+
+        // 模拟服务行为
+        when(userService.login(eq(username), eq(""))).thenReturn(expectedResponse);
+
+        // 执行测试
+        Map<String, Object> actualResponse = userController.getUserInfo(username);
+
+        // 验证行为
+        verify(userService, times(1)).login(username, "");
+
+        // 验证结果
+        assertEquals(username, actualResponse.get("username"));
+        assertEquals("test@example.com", actualResponse.get("email"));
+    }
+
+    // 异常情况测试
+    @Test
+    void login_ShouldReturnFailureWhenCredentialsAreInvalid() {
+        // 准备测试数据
+        String username = "testUser";
+        String wrongPassword = "wrongPassword";
+        Map<String, Object> expectedResponse = new HashMap<>();
+        expectedResponse.put("success", false);
+        expectedResponse.put("message", "用户名或密码错误");
+
+        // 模拟服务行为
+        when(userService.login(eq(username), eq(wrongPassword))).thenReturn(expectedResponse);
+
+        // 执行测试
+        Map<String, Object> actualResponse = userController.login(username, wrongPassword);
+
+        // 验证结果
+        assertFalse((Boolean) actualResponse.get("success"));
+        assertEquals("用户名或密码错误", actualResponse.get("message"));
+    }
+}