用户类 邀请码 商城

Change-Id: If3a9ef5c464386647ae3b876104cbf4c71265c4b
diff --git a/src/main/java/com/pt5/pthouduan/controller/InvitesController.java b/src/main/java/com/pt5/pthouduan/controller/InvitesController.java
index e3a8d8d..3eaf050 100644
--- a/src/main/java/com/pt5/pthouduan/controller/InvitesController.java
+++ b/src/main/java/com/pt5/pthouduan/controller/InvitesController.java
@@ -12,8 +12,8 @@
 public class InvitesController {
     @Autowired
     private InviteService inviteService;
-    @PostMapping("/sold")
-    public Map<String, Object> soldinvite(@RequestParam String buyername) {
-        return inviteService.setbuyername(buyername);
+    @GetMapping("/getuserinvite")
+    public Map<String, Object> getUserInfo(@RequestParam String username) {
+        return inviteService.getInvitesByUsername(username);
     }
 }
diff --git a/src/main/java/com/pt5/pthouduan/controller/UserController.java b/src/main/java/com/pt5/pthouduan/controller/UserController.java
index 9198708..4a23ea9 100644
--- a/src/main/java/com/pt5/pthouduan/controller/UserController.java
+++ b/src/main/java/com/pt5/pthouduan/controller/UserController.java
@@ -3,10 +3,20 @@
 import com.pt5.pthouduan.entity.User;
 import com.pt5.pthouduan.service.UserService;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.stereotype.Controller;
+import org.springframework.web.multipart.MultipartFile;
 
-import java.util.Map;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.text.SimpleDateFormat;
+import java.util.*;
 
 /**
  * <p>
@@ -21,6 +31,9 @@
 public class UserController {
     @Autowired
     private UserService userService;
+    private String uploadDir="../var/www/avatars/";  // 配置文件上传目录,例如: /var/www/avatars/
+
+    private String accessPath="../avatars/";
 
     @PostMapping("/register")
     public Map<String, Object> register(@RequestBody User user,@RequestParam String code,@RequestParam String emailcode) {//code是邀请码,emailcode是验证码
@@ -45,9 +58,12 @@
     }
 
     @PostMapping("/changeimage")
-    public Map<String, Object> changeimage(@RequestParam String username,
-                                           @RequestParam String image) {
-        return userService.changeImage(username,image);
+    public Map<String, Object> changeimage(@RequestParam String username, @RequestParam String image) {
+        Map<String, Object> response = new HashMap<>();
+        userService.changeImage(username,image);
+        response.put("success", true);
+        response.put("message", "头像更改成功");
+        return response;
     }
 
     @PostMapping("/changePassword")
@@ -77,4 +93,88 @@
         return userService.DeleteUser(username);
     }
 
+    @GetMapping("/alluser")
+    public Map<String, Object> alluser() {
+        return userService.getAllUser();
+    }
+
+    @GetMapping("/finduser")
+    public Map<String, Object> finduser(@RequestParam String keyword) {
+        return userService.findUser(keyword);
+    }
+
+    @GetMapping("/getDecoration")
+    public Map<String, Object> getDecoration(@RequestParam Long userid) {
+        return userService.getDecoration(userid);
+    }
+
+    @GetMapping("/getUserid")
+    public Map<String, Object> getuserid(@RequestParam String username) {
+        return userService.getuserid(username);
+    }
+
+    @PostMapping("/uploadimage")
+    public ResponseEntity<Map<String, Object>> uploadAvatar(@RequestParam("avatar") MultipartFile file) {
+        Map<String, Object> response = new HashMap<>();
+
+        // 1. 验证文件是否为空
+        if (file.isEmpty()) {
+            response.put("success", false);
+            response.put("message", "请选择要上传的文件");
+            return ResponseEntity.badRequest().body(response);
+        }
+
+        // 2. 验证文件类型
+        String contentType = file.getContentType();
+        if (!"image/jpeg".equals(contentType) &&
+                !"image/png".equals(contentType) &&
+                !"image/gif".equals(contentType)) {
+            response.put("success", false);
+            response.put("message", "只支持JPG/PNG/GIF格式的图片");
+            return ResponseEntity.badRequest().body(response);
+        }
+
+        // 3. 验证文件大小 (前端已验证,后端再次验证)
+        if (file.getSize() > 10 * 1024 * 1024) { // 10MB
+            response.put("success", false);
+            response.put("message", "图片大小不能超过10MB");
+            return ResponseEntity.badRequest().body(response);
+        }
+
+        try {
+            // 4. 创建上传目录(如果不存在)
+            File dir = new File(uploadDir);
+            if (!dir.exists()) {
+                dir.mkdirs();
+            }
+            System.out.println(dir.getAbsolutePath());
+            // 5. 生成唯一文件名 (日期+UUID+后缀)
+            String originalFilename = file.getOriginalFilename();
+            String fileExt = originalFilename.substring(originalFilename.lastIndexOf("."));
+            String newFilename = new SimpleDateFormat("yyyyMMdd").format(new Date()) +
+                    "_" + UUID.randomUUID().toString().replace("-", "") +
+                    fileExt.toLowerCase();
+
+            // 6. 保存文件
+            Path path = Paths.get(uploadDir, newFilename);
+            Files.copy(file.getInputStream(), path);
+
+            // 7. 返回访问URL
+            String fileUrl = accessPath + newFilename;
+
+            response.put("success", true);
+            response.put("url", fileUrl);
+            response.put("message", "头像上传成功");
+
+            return ResponseEntity.ok(response);
+
+        } catch (IOException e) {
+            e.printStackTrace();
+            response.put("success", false);
+            response.put("message", "文件上传失败: " + e.getMessage());
+            return ResponseEntity.status(500).body(response);
+        }
+    }
+
+
 }
diff --git a/src/main/java/com/pt5/pthouduan/mapper/InvitesMapper.java b/src/main/java/com/pt5/pthouduan/mapper/InvitesMapper.java
index fddf6df..62eb977 100644
--- a/src/main/java/com/pt5/pthouduan/mapper/InvitesMapper.java
+++ b/src/main/java/com/pt5/pthouduan/mapper/InvitesMapper.java
@@ -9,18 +9,32 @@
 import org.apache.ibatis.annotations.Update;
 import org.springframework.stereotype.Repository;
 
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author ljx
+ * @since 2025-04-14
+ */
 @Repository
 public interface InvitesMapper extends BaseMapper<Invites> {
 
     @Select("SELECT * FROM invite WHERE code = #{code}")
-    Invites selectByCode(String code);
+    Map<String, Object> 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();
+    @Select("SELECT * FROM invite WHERE (buyername = '' OR buyername IS NULL) LIMIT 1")
+    Map<String, Object> selectFirstEmptyBuyername();
 
     @Update("UPDATE invite SET buyername = #{buyername} WHERE code = #{code}")
     int updatebuyer(@Param("code") String code, @Param("buyername") String buyername);
+
+    @Select("SELECT * FROM invite WHERE buyername = #{username}")
+    List<Map<String, Object>> selectInvitesByUsername(@Param("username") String username);
 }
diff --git a/src/main/java/com/pt5/pthouduan/mapper/UserMapper.java b/src/main/java/com/pt5/pthouduan/mapper/UserMapper.java
index c3bc827..8d0301a 100644
--- a/src/main/java/com/pt5/pthouduan/mapper/UserMapper.java
+++ b/src/main/java/com/pt5/pthouduan/mapper/UserMapper.java
@@ -1,9 +1,10 @@
 package com.pt5.pthouduan.mapper;
 
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.pt5.pthouduan.entity.PeerInfo;
 import com.pt5.pthouduan.entity.User;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.apache.ibatis.annotations.*;
+import org.apache.ibatis.type.JdbcType;
 import org.springframework.stereotype.Repository;
 
 import java.util.List;
@@ -22,37 +23,22 @@
     @Insert("INSERT INTO user(username, password, email, passkey) VALUES(#{username}, #{password}, #{email}, #{passkey})")
     int insert(User user);
 
-    @Delete("DELETE FROM user_behavior WHERE user_id = (SELECT user_id FROM User WHERE username = #{username})")
+    @Delete("DELETE FROM user WHERE username = #{username})")
     int deleteByUsername(@Param("username") String username);
 
-    @Select("SELECT * FROM User WHERE username = #{username}")
-    User selectByUsername(String username);
+    @Select("SELECT * FROM user WHERE username = #{username}")
+    Map<String, Object> selectByUsername(String username);
 
-    @Select("SELECT * FROM User WHERE email = #{email}")
-    User selectByEmail(String email);
+    @Select("SELECT username FROM user WHERE email = #{email}")
+    String selectByEmail(String email);
 
-    @Select("SELECT credit FROM User WHERE username = #{username}")
+    @Select("SELECT credit FROM user WHERE username = #{username}")
     int getcreditByUsername(String username);
 
-    @Select("SELECT passkey FROM user WHERE userid = #{userid}")
-    String selectPasskeyByUserid(Long userid);
-
-    @Select("SELECT permission FROM user WHERE userid = #{userid}")
-    int getpermissionByUserid(Long userid);
-
-    @Select("SELECT username FROM user WHERE userid = #{userid}")
-    String selectUsernameByUserid(Long userid);
-
-    @Select("SELECT userid FROM user WHERE username = #{username}")
-    String selectUseridByusername(String username);
-
     @Update("UPDATE user SET credit = credit - #{price} WHERE username = #{username}")
     int deductCreditByUsername(@Param("username") String username, @Param("price") int price);
 
-    @Update("UPDATE user SET credit = credit + #{price} WHERE username = #{username}")
-    int addCreditByUsername(@Param("username") String username, @Param("price") int price);
-
-    @Update("UPDATE user SET upload = upload + #{upload} WHERE username = #{username}")
+    @Update("UPDATE user SET user_upload = user_upload + #{upload} WHERE username = #{username}")
     int increaseUploadByUsername(@Param("username") String username, @Param("upload") Integer upload);
 
     @Update("UPDATE user SET password = #{password} WHERE username = #{username}")
@@ -70,20 +56,7 @@
     @Update("UPDATE user SET decoration = CONCAT(IFNULL(decoration, ''), ' ', #{newDecoration}) WHERE username = #{username}")
     int appendUserDecoration(@Param("username") String username, @Param("newDecoration") String newDecoration);
 
-    @Delete("DELETE FROM user WHERE username = #{username})")
-    int deleteByUsername(@Param("username") String username);
-
-    @Select("SELECT username, passkey, grade_id FROM user")
-    List<Map<String, Object>> selectAllUsersBasicInfo();
-
-    @Select("SELECT * FROM user")
-    List<Map<String, Object>> selectAllUsers();
-
-    @Select("SELECT * FROM user WHERE username REGEXP #{regexPattern}")
-    List<Map<String, Object>> selectUserByFuzzyKeyword(@Param("regexPattern") String regexPattern);
-
     boolean existsByPasskey(String passkey);
-
     void incrementUserTraffic( @Param("info_hash") String infoHash,@Param("passkey") String passkey, @Param("user_upload") long uploaded, @Param("user_download") long downloaded);
 
     String getUsernameByPasskey(String passkey);
@@ -92,4 +65,29 @@
 
     @Select("SELECT passkey FROM user WHERE userid = #{userid}")
     String selectPasskeyByUserid(Long userid);
+
+    @Select("SELECT username, passkey, grade_id FROM user")
+    List<Map<String, Object>> selectAllUsersBasicInfo();
+
+    @Select("SELECT username FROM user WHERE userid = #{userid}")
+    String selectUsernameByUserid(Long userid);
+
+    @Select("SELECT image,decoration,username,grade_id FROM user WHERE userid = #{userid}")
+    Map<String, Object> selectdecorationByUserid(Long userid);
+
+    @Select("SELECT userid FROM user WHERE username = #{username}")
+    String selectUseridByusername(String username);
+
+    @Select("SELECT * FROM user")
+    List<Map<String, Object>> selectAllUsers();
+
+    @Select("SELECT * FROM user WHERE username REGEXP #{regexPattern}")
+    List<Map<String, Object>> selectUserByFuzzyKeyword(@Param("regexPattern") String regexPattern);
+
+    @Update("UPDATE user SET credit = credit + #{price} WHERE username = #{username}")
+    int addCreditByUsername(@Param("username") String username, @Param("price") int price);
+
+    @Select("SELECT permission FROM user WHERE userid = #{userid}")
+    int getpermissionByUserid(Long userid);
+
 }
diff --git a/src/main/java/com/pt5/pthouduan/service/InviteService.java b/src/main/java/com/pt5/pthouduan/service/InviteService.java
index f6ca8a6..a97929c 100644
--- a/src/main/java/com/pt5/pthouduan/service/InviteService.java
+++ b/src/main/java/com/pt5/pthouduan/service/InviteService.java
@@ -2,27 +2,28 @@
 
 import com.pt5.pthouduan.entity.Invites;
 import com.pt5.pthouduan.mapper.InvitesMapper;
+import com.pt5.pthouduan.mapper.UserMapper;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 @Service
 public class InviteService {
     @Autowired
     private InvitesMapper invitesMapper;
-    //批量生成邀请码并存入数据库(6位)(这个直接在数据库更新)
-    //邀请码卖出(set buyername)
-    public Map<String, Object> setbuyername(String buyername){
+    //获取“我的”邀请码
+    public Map<String, Object> getInvitesByUsername(String username){
         Map<String, Object> result = new HashMap<>();
-        Invites invite=invitesMapper.selectFirstEmptyBuyername();
-        invitesMapper.updatebuyer(invite.getCode(),buyername);
+        List<Map<String, Object>> invites = invitesMapper.selectInvitesByUsername(username);
         result.put("success", true);
-        result.put("invitecode", invite.getCode());
-        result.put("message", "邀请码购买成功");
+        result.put("invites", invites);
+        result.put("message", "获取成功");
         return result;
     }
 
 
+
 }
diff --git a/src/main/java/com/pt5/pthouduan/service/ShopService.java b/src/main/java/com/pt5/pthouduan/service/ShopService.java
index a85b5ef..84ab88f 100644
--- a/src/main/java/com/pt5/pthouduan/service/ShopService.java
+++ b/src/main/java/com/pt5/pthouduan/service/ShopService.java
@@ -65,10 +65,10 @@
         }
         //更新用户保种积分
         userMapper.deductCreditByUsername(buyername,price);
-        Invites invite=invitesMapper.selectFirstEmptyBuyername();
-        invitesMapper.updatebuyer(invite.getCode(),buyername);
+        Map<String, Object> invite=invitesMapper.selectFirstEmptyBuyername();
+        invitesMapper.updatebuyer((String) invite.get("code"),buyername);
         result.put("success", true);
-        result.put("invitecode", invite.getCode());
+        result.put("invitecode", (String) invite.get("code"));
         result.put("message", "邀请码购买成功");
         return result;
     }
diff --git a/src/main/java/com/pt5/pthouduan/service/UserService.java b/src/main/java/com/pt5/pthouduan/service/UserService.java
index 59865c2..affa9e8 100644
--- a/src/main/java/com/pt5/pthouduan/service/UserService.java
+++ b/src/main/java/com/pt5/pthouduan/service/UserService.java
@@ -2,6 +2,7 @@
 import com.pt5.pthouduan.entity.Invites;
 import com.pt5.pthouduan.entity.User;
 import com.pt5.pthouduan.mapper.InvitesMapper;
+import lombok.extern.java.Log;
 import org.springframework.beans.factory.annotation.Autowired;
 import com.pt5.pthouduan.mapper.UserMapper;
 import org.springframework.stereotype.Service;
@@ -10,8 +11,10 @@
 import java.security.SecureRandom;
 
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.UUID;
+import java.util.stream.Collectors;
 
 @Service
 public class UserService {
@@ -53,20 +56,21 @@
             return result;
         }
 
-        // 检查邮箱是否已存在
-        if (userMapper.selectByEmail(user.getEmail()) != 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);
+        Map<String, Object> invite= invitesMapper.selectByCode(code);
         if(invite==null){//邀请码不存在
             result.put("success", false);
             result.put("message","无效的邀请码");
             return result;
         }
-        if(invite.getIsUsed()==1){//邀请码已被使用
+        Boolean isused = (Boolean) invite.get("isUsed");
+        if(isused){//邀请码已被使用
             result.put("success", false);
             result.put("message","邀请码已被使用");
             return result;
@@ -93,7 +97,7 @@
     public Map<String, Object> login(String username, String password) {
         Map<String, Object> result = new HashMap<>();
 
-        User user = userMapper.selectByUsername(username);//首先验证用户名
+        Map<String, Object> user = userMapper.selectByUsername(username);//首先验证用户名
         if (user == null) {
             result.put("success", false);
             result.put("message", "用户不存在");
@@ -101,13 +105,12 @@
         }
 
         //验证密码
-        if(!password.equals(user.getPassword())){
+        if(!password.equals(user.get("password"))){
             result.put("success", false);
             result.put("message","密码错误,请检查后重新输入");
             return result;
         }
         // 登录成功,返回用户信息(密码置空)
-        user.setPassword(null);
         result.put("success", true);
         result.put("message", "登录成功");
         result.put("user", user);
@@ -117,20 +120,25 @@
     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());
+        Map<String, Object> user = userMapper.selectByUsername(username);
+        Number downloadNum = (Number) user.get("user_download");
+        long download = downloadNum.longValue();
+        Number uploadNum = (Number) user.get("user_upload");
+        long upload = uploadNum.longValue();
+        int grade=0;
+        if(upload+download<=500000*1024){
+            grade=1;
+        }else if(upload+download<=2000000*1024){
+            grade=2;
+        }else if(upload+download<= 3500000L *1024){
+            grade=3;
+        }else if(upload+download<= 6500000L *1024){
+            grade=4;
+        }else{ grade=5;}
+        userMapper.updateGrade(username,grade);
         result.put("success", true);
         result.put("message", "等级更新成功");
-        result.put("grade", user.getGradeId());
+        result.put("grade", grade);
         return result;
     }
     //设置性别
@@ -152,7 +160,7 @@
     //更改密码
     public Map<String, Object> changePassword(String username,String oldpassword,String newpassword){
         Map<String, Object> result = new HashMap<>();
-        User user = userMapper.selectByUsername(username);//首先验证用户名
+        Map<String, Object> user = userMapper.selectByUsername(username);//首先验证用户名
         if (user == null) {
             result.put("success", false);
             result.put("message", "用户不存在");
@@ -160,7 +168,7 @@
         }
 
         //验证密码
-        if(!oldpassword.equals(user.getPassword())){
+        if(!oldpassword.equals(user.get("password"))){
             result.put("success", false);
             result.put("message","密码错误,请检查后重新输入");
             return result;
@@ -174,15 +182,17 @@
     //获取用户信息(前端)
     public Map<String, Object> UserInfo(String username){
         Map<String, Object> result = new HashMap<>();
-        User user = userMapper.selectByUsername(username);
+        Map<String, Object> user = userMapper.selectByUsername(username);
         result.put("success", true);
         result.put("message", "用户信息获取成功");
         result.put("user", user);
         return result;
     }
     //直接创建用户
-    public Map<String, Object> CreateUser(User user){
+    public Map<String, Object> CreateUser(User user){//用户名、密码、邮箱
         Map<String, Object> result = new HashMap<>();
+        SecureRandom random = new SecureRandom();
+        user.setPasskey(String.valueOf(10000000 + random.nextInt(90000000)));
         userMapper.insert(user);
         result.put("success", true);
         result.put("message", "用户创建成功");
@@ -196,5 +206,44 @@
         result.put("message", "用户删除成功");
         return result;
     }
+    //获取所有用户
+    public Map<String, Object> getAllUser(){
+        Map<String, Object> result = new HashMap<>();
+        List<Map<String, Object>> users =userMapper.selectAllUsers();
+        result.put("data", users);
+        result.put("success", true);
+        result.put("message", "用户获取成功");
+        return result;
+    }
+    //模糊搜索用户名
+    public Map<String, Object> findUser(String keyword){
+        Map<String, Object> result = new HashMap<>();
+        String regexPattern = keyword.chars()
+                .mapToObj(c -> String.valueOf((char) c))
+                .collect(Collectors.joining(".*"));
+        List<Map<String, Object>> users = userMapper.selectUserByFuzzyKeyword(regexPattern);
+        result.put("data", users);
+        result.put("success", true);
+        result.put("message", "用户查找成功");
+        return result;
+    }
+    //根据用户id返回用户的头像和装饰
+    public Map<String, Object> getDecoration(Long userid){
+        Map<String, Object> result = new HashMap<>();
+        Map<String, Object> info = userMapper.selectdecorationByUserid(userid);
+        result.put("data", info);
+        result.put("success", true);
+        result.put("message", "获取信息成功");
+        return result;
+    }
+    //根据用户名返回用户id
+    public Map<String, Object> getuserid(String username){
+        Map<String, Object> result = new HashMap<>();
+        String userid = userMapper.selectUseridByusername(username);
+        result.put("data",userid);
+        result.put("success", true);
+        result.put("message", "获取信息成功");
+        return result;
+    }
 
 }
diff --git a/src/test/java/com/pt5/pthouduan/ControllerTest/InvitesControllerTest.java b/src/test/java/com/pt5/pthouduan/ControllerTest/InvitesControllerTest.java
index 9477df4..345d6a2 100644
--- a/src/test/java/com/pt5/pthouduan/ControllerTest/InvitesControllerTest.java
+++ b/src/test/java/com/pt5/pthouduan/ControllerTest/InvitesControllerTest.java
@@ -1,5 +1,6 @@
 package com.pt5.pthouduan.ControllerTest;
 
+
 import com.pt5.pthouduan.controller.InvitesController;
 import com.pt5.pthouduan.service.InviteService;
 import org.junit.jupiter.api.BeforeEach;
@@ -29,70 +30,96 @@
     }
 
     @Test
-    void soldinvite_ShouldCallServiceWithCorrectParameter() {
+    void getUserInfo_Success() {
         // 准备测试数据
-        String testBuyerName = "testBuyer";
         Map<String, Object> expectedResponse = new HashMap<>();
         expectedResponse.put("success", true);
-        expectedResponse.put("message", "Invite sold successfully");
+        expectedResponse.put("invites", 5);
+        expectedResponse.put("username", "testuser");
 
-        // 模拟服务行为
-        when(inviteService.setbuyername(anyString())).thenReturn(expectedResponse);
+        // 模拟服务层行为
+        when(inviteService.getInvitesByUsername(anyString()))
+                .thenReturn(expectedResponse);
 
         // 执行测试
-        Map<String, Object> actualResponse = invitesController.soldinvite(testBuyerName);
-
-        // 验证行为
-        verify(inviteService, times(1)).setbuyername(testBuyerName);
+        Map<String, Object> actualResponse = invitesController.getUserInfo("testuser");
 
         // 验证结果
         assertEquals(expectedResponse, actualResponse);
-        assertTrue((Boolean) actualResponse.get("success"));
-        assertEquals("Invite sold successfully", actualResponse.get("message"));
+        verify(inviteService, times(1)).getInvitesByUsername("testuser");
     }
 
     @Test
-    void soldinvite_ShouldHandleServiceFailure() {
-        // 准备测试数据
-        String testBuyerName = "testBuyer";
+    void getUserInfo_UserNotFound() {
         Map<String, Object> expectedResponse = new HashMap<>();
         expectedResponse.put("success", false);
-        expectedResponse.put("error", "Invalid buyer name");
+        expectedResponse.put("message", "用户不存在");
 
-        // 模拟服务行为
-        when(inviteService.setbuyername(anyString())).thenReturn(expectedResponse);
+        when(inviteService.getInvitesByUsername(anyString()))
+                .thenReturn(expectedResponse);
 
-        // 执行测试
-        Map<String, Object> actualResponse = invitesController.soldinvite(testBuyerName);
+        Map<String, Object> actualResponse = invitesController.getUserInfo("nonexistent");
 
-        // 验证行为
-        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() {
-        // 准备测试数据
+    void getUserInfo_EmptyUsername() {
         Map<String, Object> expectedResponse = new HashMap<>();
         expectedResponse.put("success", false);
-        expectedResponse.put("error", "Buyer name cannot be null");
+        expectedResponse.put("message", "用户名不能为空");
 
-        // 模拟服务行为
-        when(inviteService.setbuyername(null)).thenReturn(expectedResponse);
+        when(inviteService.getInvitesByUsername(""))
+                .thenReturn(expectedResponse);
 
-        // 执行测试
-        Map<String, Object> actualResponse = invitesController.soldinvite(null);
+        Map<String, Object> actualResponse = invitesController.getUserInfo("");
 
-        // 验证行为
-        verify(inviteService, times(1)).setbuyername(null);
-
-        // 验证结果
         assertEquals(expectedResponse, actualResponse);
-        assertFalse((Boolean) actualResponse.get("success"));
-        assertEquals("Buyer name cannot be null", actualResponse.get("error"));
+        assertEquals("用户名不能为空", actualResponse.get("message"));
+    }
+
+    @Test
+    void getUserInfo_ServiceException() {
+        when(inviteService.getInvitesByUsername(anyString()))
+                .thenThrow(new RuntimeException("数据库连接失败"));
+
+        assertThrows(RuntimeException.class, () -> {
+            invitesController.getUserInfo("testuser");
+        });
+    }
+
+    // 边界条件测试
+    @Test
+    void getUserInfo_LongUsername() {
+        String longUsername = "a".repeat(256);
+        Map<String, Object> expectedResponse = new HashMap<>();
+        expectedResponse.put("success", false);
+        expectedResponse.put("message", "用户名过长");
+
+        when(inviteService.getInvitesByUsername(longUsername))
+                .thenReturn(expectedResponse);
+
+        Map<String, Object> actualResponse = invitesController.getUserInfo(longUsername);
+
+        assertEquals(expectedResponse, actualResponse);
+    }
+
+    // 性能测试示例(实际项目中可能需要单独的测试类)
+    @Test
+    void getUserInfo_Performance() {
+        // 模拟快速响应
+        when(inviteService.getInvitesByUsername(anyString()))
+                .thenAnswer(invocation -> {
+                    Map<String, Object> response = new HashMap<>();
+                    response.put("success", true);
+                    return response;
+                });
+
+        long startTime = System.currentTimeMillis();
+        invitesController.getUserInfo("testuser");
+        long duration = System.currentTimeMillis() - startTime;
+
+        assertTrue(duration < 100, "响应时间应小于100毫秒");
     }
 }
diff --git a/src/test/java/com/pt5/pthouduan/ControllerTest/ShopControllerTest.java b/src/test/java/com/pt5/pthouduan/ControllerTest/ShopControllerTest.java
new file mode 100644
index 0000000..2ffdb01
--- /dev/null
+++ b/src/test/java/com/pt5/pthouduan/ControllerTest/ShopControllerTest.java
@@ -0,0 +1,136 @@
+package com.pt5.pthouduan.ControllerTest;
+
+import com.pt5.pthouduan.controller.ShopController;
+import com.pt5.pthouduan.service.ShopService;
+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 ShopControllerTest {
+
+    @Mock
+    private ShopService shopService;
+
+    @InjectMocks
+    private ShopController shopController;
+
+    @BeforeEach
+    void setUp() {
+        MockitoAnnotations.openMocks(this);
+    }
+
+    @Test
+    void soldDecoration_Success() {
+        // 准备测试数据
+        Map<String, Object> expectedResponse = new HashMap<>();
+        expectedResponse.put("success", true);
+        expectedResponse.put("message", "装饰购买成功");
+
+        // 模拟服务层行为
+        when(shopService.buyDecoration(anyString(), anyString(), anyInt()))
+                .thenReturn(expectedResponse);
+
+        // 执行测试
+        Map<String, Object> actualResponse = shopController.soldDecoration("user1", "decoration1", 100);
+
+        // 验证结果
+        assertEquals(expectedResponse, actualResponse);
+        verify(shopService, times(1)).buyDecoration("user1", "decoration1", 100);
+    }
+
+    @Test
+    void soldDecoration_Failure() {
+        Map<String, Object> expectedResponse = new HashMap<>();
+        expectedResponse.put("success", false);
+        expectedResponse.put("message", "余额不足");
+
+        when(shopService.buyDecoration(anyString(), anyString(), anyInt()))
+                .thenReturn(expectedResponse);
+
+        Map<String, Object> actualResponse = shopController.soldDecoration("user1", "decoration1", 1000);
+
+        assertEquals(expectedResponse, actualResponse);
+        assertFalse((Boolean) actualResponse.get("success"));
+    }
+
+    @Test
+    void soldUpload_Success() {
+        Map<String, Object> expectedResponse = new HashMap<>();
+        expectedResponse.put("success", true);
+        expectedResponse.put("upload", 500);
+
+        when(shopService.buyUpload(anyString(), anyInt(), anyInt()))
+                .thenReturn(expectedResponse);
+
+        Map<String, Object> actualResponse = shopController.soldUpload("user1", 50, 500);
+
+        assertEquals(expectedResponse, actualResponse);
+        verify(shopService).buyUpload("user1", 50, 500);
+    }
+
+    @Test
+    void soldInvite_Success() {
+        Map<String, Object> expectedResponse = new HashMap<>();
+        expectedResponse.put("success", true);
+        expectedResponse.put("inviteCode", "INV123");
+
+        when(shopService.setbuyername(anyString(), anyInt()))
+                .thenReturn(expectedResponse);
+
+        Map<String, Object> actualResponse = shopController.soldInvite("user1", 200);
+
+        assertEquals(expectedResponse, actualResponse);
+        assertNotNull(actualResponse.get("inviteCode"));
+    }
+
+    @Test
+    void soldInvite_InvalidPrice() {
+        Map<String, Object> expectedResponse = new HashMap<>();
+        expectedResponse.put("success", false);
+        expectedResponse.put("message", "价格无效");
+
+        when(shopService.setbuyername(anyString(), eq(0)))
+                .thenReturn(expectedResponse);
+
+        Map<String, Object> actualResponse = shopController.soldInvite("user1", 0);
+
+        assertEquals(expectedResponse, actualResponse);
+        assertFalse((Boolean) actualResponse.get("success"));
+    }
+
+    // 边界条件测试
+    @Test
+    void soldDecoration_ZeroPrice() {
+        Map<String, Object> expectedResponse = new HashMap<>();
+        expectedResponse.put("success", false);
+        expectedResponse.put("message", "价格必须大于0");
+
+        when(shopService.buyDecoration(anyString(), anyString(), eq(0)))
+                .thenReturn(expectedResponse);
+
+        Map<String, Object> actualResponse = shopController.soldDecoration("user1", "decoration1", 0);
+
+        assertEquals(expectedResponse, actualResponse);
+    }
+
+    // 异常情况测试
+    @Test
+    void soldDecoration_ServiceThrowsException() {
+        when(shopService.buyDecoration(anyString(), anyString(), anyInt()))
+                .thenThrow(new RuntimeException("服务异常"));
+
+        assertThrows(RuntimeException.class, () -> {
+            shopController.soldDecoration("user1", "decoration1", 100);
+        });
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/com/pt5/pthouduan/ControllerTest/UserControllerTest.java b/src/test/java/com/pt5/pthouduan/ControllerTest/UserControllerTest.java
index 18707e2..e843900 100644
--- a/src/test/java/com/pt5/pthouduan/ControllerTest/UserControllerTest.java
+++ b/src/test/java/com/pt5/pthouduan/ControllerTest/UserControllerTest.java
@@ -1,4 +1,5 @@
 package com.pt5.pthouduan.ControllerTest;
+
 import com.pt5.pthouduan.controller.UserController;
 import com.pt5.pthouduan.entity.User;
 import com.pt5.pthouduan.service.UserService;
@@ -8,13 +9,17 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.springframework.http.ResponseEntity;
+import org.springframework.mock.web.MockMultipartFile;
+import org.springframework.web.multipart.MultipartFile;
 
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.HashMap;
 import java.util.Map;
 
 import static org.junit.jupiter.api.Assertions.*;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.*;
 import static org.mockito.Mockito.*;
 
 class UserControllerTest {
@@ -30,103 +35,120 @@
         MockitoAnnotations.openMocks(this);
     }
 
-    // 测试注册功能
     @Test
-    void register_ShouldReturnSuccess() {
-        User user = new User(0L,"1");
-        user.setUsername("testUser");
-        Map<String, Object> expected = new HashMap<>();
-        expected.put("status", "success");
+    void register_Success() {
+        // 准备测试数据
+        User user = new User(0L,"");
+        Map<String, Object> expectedResponse = new HashMap<>();
+        expectedResponse.put("success", true);
+        expectedResponse.put("message", "注册成功");
 
+        // 模拟服务层行为
         when(userService.register(any(User.class), anyString(), anyString()))
-                .thenReturn(expected);
+                .thenReturn(expectedResponse);
 
-        Map<String, Object> result = userController.register(user, "INVITE123", "EMAIL456");
+        // 执行测试
+        Map<String, Object> actualResponse = userController.register(user, "invite123", "email123");
 
-        assertEquals(expected, result);
+        // 验证结果
+        assertEquals(expectedResponse, actualResponse);
         verify(userService, times(1)).register(any(), anyString(), anyString());
     }
 
-    // 测试登录功能
     @Test
-    void login_ShouldReturnToken() {
-        Map<String, Object> expected = new HashMap<>();
-        expected.put("token", "mockToken123");
+    void login_Success() {
+        Map<String, Object> expectedResponse = new HashMap<>();
+        expectedResponse.put("success", true);
+        expectedResponse.put("token", "test-token");
 
-        when(userService.login("testUser", "password123"))
-                .thenReturn(expected);
+        when(userService.login(anyString(), anyString()))
+                .thenReturn(expectedResponse);
 
-        Map<String, Object> result = userController.login("testUser", "password123");
+        Map<String, Object> actualResponse = userController.login("testuser", "password123");
 
-        assertEquals(expected, result);
-        assertNotNull(result.get("token"));
+        assertEquals(expectedResponse, actualResponse);
     }
 
-    // 测试获取用户信息
     @Test
-    void getUserInfo_ShouldReturnUserData() {
-        Map<String, Object> expected = new HashMap<>();
-        expected.put("username", "testUser");
-        expected.put("email", "test@example.com");
+    void uploadAvatar_Success() throws IOException {
+        // 准备测试文件
+        MultipartFile file = new MockMultipartFile(
+                "avatar",
+                "test.jpg",
+                "image/jpeg",
+                "test image content".getBytes()
+        );
 
-        when(userService.UserInfo("testUser"))
-                .thenReturn(expected);
+        // 模拟服务层行为
+        //doNothing().when(userService).changeImage(anyString(), anyString());
 
-        Map<String, Object> result = userController.getuser("testUser");
+        // 执行测试
+        ResponseEntity<Map<String, Object>> response = userController.uploadAvatar(file);
 
-        assertEquals("testUser", result.get("username"));
-        assertEquals("test@example.com", result.get("email"));
+        // 验证结果
+        assertEquals(200, response.getStatusCodeValue());
+        assertTrue((Boolean) response.getBody().get("success"));
+        assertNotNull(response.getBody().get("url"));
+
+        // 验证文件是否保存到正确路径
+//        Path expectedPath = Paths.get("../var/www/avatars/").resolve(anyString());
+        // 实际项目中需要添加文件存在性断言
     }
 
-    // 测试修改密码
     @Test
-    void changePassword_ShouldHandleSuccess() {
-        Map<String, Object> expected = new HashMap<>();
-        expected.put("message", "Password updated");
+    void uploadAvatar_InvalidFileType() {
+        MultipartFile file = new MockMultipartFile(
+                "avatar",
+                "test.txt",
+                "text/plain",
+                "invalid content".getBytes()
+        );
 
-        when(userService.changePassword("testUser", "oldPass", "newPass"))
-                .thenReturn(expected);
+        ResponseEntity<Map<String, Object>> response = userController.uploadAvatar(file);
 
-        Map<String, Object> result = userController.changePassword(
-                "testUser", "oldPass", "newPass");
-
-        assertEquals("Password updated", result.get("message"));
+        assertEquals(400, response.getStatusCodeValue());
+        assertEquals("只支持JPG/PNG/GIF格式的图片", response.getBody().get("message"));
     }
 
-    // 测试异常情况
     @Test
-    void login_ShouldHandleFailure() {
-        when(userService.login("wrongUser", "wrongPass"))
-                .thenThrow(new RuntimeException("Invalid credentials"));
+    void changeImage_Success() {
+        Map<String, Object> expectedResponse = new HashMap<>();
+        expectedResponse.put("success", true);
+        expectedResponse.put("message", "头像更改成功");
 
-        assertThrows(RuntimeException.class, () -> {
-            userController.login("wrongUser", "wrongPass");
-        });
+        // 执行测试
+        Map<String, Object> actualResponse = userController.changeimage("testuser", "new-avatar.jpg");
+
+        // 验证结果
+        assertEquals(expectedResponse, actualResponse);
+        verify(userService, times(1)).changeImage("testuser", "new-avatar.jpg");
     }
 
-    // 测试空参数情况
     @Test
-    void getUserInfo_ShouldHandleNullUsername() {
-        when(userService.UserInfo(null))
-                .thenReturn(Map.of("error", "Username required"));
+    void changePassword_Success() {
+        Map<String, Object> expectedResponse = new HashMap<>();
+        expectedResponse.put("success", true);
 
-        Map<String, Object> result = userController.getuser(null);
+        when(userService.changePassword(anyString(), anyString(), anyString()))
+                .thenReturn(expectedResponse);
 
-        assertEquals("Username required", result.get("error"));
+        Map<String, Object> actualResponse = userController.changePassword(
+                "testuser", "oldPass", "newPass");
+
+        assertEquals(expectedResponse, actualResponse);
     }
 
-    // 测试创建用户
+    // 其他方法测试示例
     @Test
-    void createUser_ShouldReturnUserId() {
-        User newUser = new User(0L,"1");
-        newUser.setUsername("newUser");
-        Map<String, Object> expected = Map.of("userId", 123);
+    void getUserInfo_Success() {
+        Map<String, Object> expectedResponse = new HashMap<>();
+        expectedResponse.put("username", "testuser");
 
-        when(userService.CreateUser(any(User.class)))
-                .thenReturn(expected);
+        when(userService.UserInfo(anyString()))
+                .thenReturn(expectedResponse);
 
-        Map<String, Object> result = userController.creatUser(newUser);
+        Map<String, Object> actualResponse = userController.getuser("testuser");
 
-        assertEquals(123, result.get("userId"));
+        assertEquals(expectedResponse, actualResponse);
     }
-}
+}
\ No newline at end of file