添加更新用户流量的方法,并定时跟新到所有用户

Change-Id: I9aa5b3ace0bf327980554a89611b059caed12360
diff --git a/src/main/java/com/pt/CustomResponse.java b/src/main/java/com/pt/CustomResponse.java
new file mode 100644
index 0000000..dfcb1ea
--- /dev/null
+++ b/src/main/java/com/pt/CustomResponse.java
@@ -0,0 +1,35 @@
+package com.pt;
+
+import java.util.Map;
+
+public class CustomResponse {
+    private int code;
+    private String message;
+    private Map<String, Object> data;
+
+    public CustomResponse(int code, String message, Map<String, Object> data) {
+        this.code = code;
+        this.message = message;
+        this.data = data;
+    }
+
+    public int getCode() {
+        return code;
+    }
+    public void setCode(int code) {
+        this.code = code;
+    }
+    public String getMessage() {
+        return message;
+    }
+    public void setMessage(String message) {
+        this.message = message;
+    }
+    public Map<String, Object> getData() {
+        return data;
+    }
+    public void setData(Map<String, Object> data) {
+        this.data = data;
+    }
+
+}
diff --git a/src/main/java/com/pt/Item/CommentInfo.java b/src/main/java/com/pt/Item/CommentInfo.java
new file mode 100644
index 0000000..a4a20db
--- /dev/null
+++ b/src/main/java/com/pt/Item/CommentInfo.java
@@ -0,0 +1,68 @@
+package com.pt.Item;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+
+public class CommentInfo {
+
+    private int commentId;
+    private String content;
+    private String writer;
+    private int parentPost;
+    private LocalDateTime publishDate;
+    private String reviewer;
+    private int reviewerId;
+
+    public CommentInfo() {
+    }
+    public CommentInfo(int commentId, String content, String writer, int parentPost, LocalDateTime publishDate) {
+        this.commentId = commentId;
+        this.content = content;
+        this.writer = writer;
+        this.parentPost = parentPost;
+        this.publishDate = publishDate;
+    }
+
+    public int getCommentId() {
+        return commentId;
+    }
+    public void setCommentId(int commentId) {
+        this.commentId = commentId;
+    }
+    public String getContent() {
+        return content;
+    }
+    public void setContent(String content) {
+        this.content = content;
+    }
+    public String getWriter() {
+        return writer;
+    }
+    public void setWriter(String writer) {
+        this.writer = writer;
+    }
+    public int getParentPost() {
+        return parentPost;
+    }
+    public void setParentPost(int parentPost) {
+        this.parentPost = parentPost;
+    }
+    public LocalDateTime getPublishDate() {
+        return publishDate;
+    }
+    public void setPublishDate(LocalDateTime publishDate) {
+        this.publishDate = publishDate;
+    }
+    public String getReviewer() {
+        return reviewer;
+    }
+    public void setReviewer(String reviewer) {
+        this.reviewer = reviewer;
+    }
+    public int getReviewerId() {
+        return reviewerId;
+    }
+    public void setReviewerId(int reviewerId) {
+        this.reviewerId = reviewerId;
+    }
+}
diff --git a/src/main/java/com/pt/constant/Constants.java b/src/main/java/com/pt/constant/Constants.java
index e8cecd3..a54704c 100644
--- a/src/main/java/com/pt/constant/Constants.java
+++ b/src/main/java/com/pt/constant/Constants.java
@@ -2,7 +2,7 @@
 
 public class Constants {
 
-    public static final int DEFAULT_EXPIRE_TIME = 600000;
+    public static final long DEFAULT_EXPIRE_TIME = 7 * 24 * 3600000;
 
     /*
         * 用户角色
diff --git a/src/main/java/com/pt/controller/AdminController.java b/src/main/java/com/pt/controller/AdminController.java
index 8af5b56..71159e5 100644
--- a/src/main/java/com/pt/controller/AdminController.java
+++ b/src/main/java/com/pt/controller/AdminController.java
@@ -29,7 +29,11 @@
         Admin admin = adminService.findByUsernameAndPassword(username, password);
         if (admin != null) {
             ans.put("message", "Login successful");
-            ans.put("data", JWTUtils.generateToken(username, Constants.UserRole.ADMIN, Constants.DEFAULT_EXPIRE_TIME));
+            ans.put("data", Map.of(
+                    "token", JWTUtils.generateToken(username, Constants.UserRole.ADMIN, Constants.DEFAULT_EXPIRE_TIME),
+                    "uid", admin.getId(),
+                    "username", admin.getUsername()
+            ));
             return ResponseEntity.ok().body(ans);
         } else {
             ans.put("message", "Invalid username or password");
diff --git a/src/main/java/com/pt/controller/CommentController.java b/src/main/java/com/pt/controller/CommentController.java
index 00e091d..623d94a 100644
--- a/src/main/java/com/pt/controller/CommentController.java
+++ b/src/main/java/com/pt/controller/CommentController.java
@@ -1,13 +1,19 @@
 package com.pt.controller;
 
+import com.pt.Item.CommentInfo;
 import com.pt.constant.Constants;
+import com.pt.entity.Post;
+import com.pt.entity.User;
 import com.pt.service.CommentService;
+import com.pt.service.PostService;
+import com.pt.service.UserService;
 import com.pt.utils.JWTUtils;
 import com.pt.entity.Comment;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -20,6 +26,12 @@
     @Autowired
     private CommentService commentService;
 
+    @Autowired
+    private PostService postService;
+
+    @Autowired
+    private UserService userService;
+
     @PostMapping("/add")
     public ResponseEntity<?> addComment(
             @RequestHeader("token") String token,
@@ -28,6 +40,7 @@
         String content = request.get("content");
         String username = request.get("username");
         int postId = Integer.parseInt(request.get("postId"));
+        Integer reviewer = request.get("reviewer") != null ? Integer.parseInt(request.get("reviewer")) : null;
 
         Map<String, Object> ans = new HashMap<>();
 
@@ -36,7 +49,7 @@
             return ResponseEntity.badRequest().body(ans);
         }
 
-        commentService.addComment(content, username, postId);
+        commentService.addComment(content, username, postId, reviewer);
         ans.put("message", "Comment added successfully");
         return ResponseEntity.ok(ans);
     }
@@ -44,10 +57,9 @@
     @DeleteMapping("/delete")
     public ResponseEntity<?> deleteComment(
             @RequestHeader("token") String token,
-            @RequestBody Map<String, String> request
+            @RequestParam("username") String username,
+            @RequestParam("commentId") int commentId
     ) {
-        String username = request.get("username");
-        int commentId = Integer.parseInt(request.get("commentId"));
 
         Map<String, Object> ans = new HashMap<>();
 
@@ -74,10 +86,37 @@
             return ResponseEntity.badRequest().body(ans);
         }
 
+        Post post = postService.findPostById(postId);
         List<Comment> comments = commentService.getCommentsByPostId(postId);
+        List<CommentInfo> commentInfos = new ArrayList<>();
+        for(Comment comment : comments) {
+            CommentInfo commentInfo = new CommentInfo();
+            commentInfo.setCommentId(comment.getCommentId());
+            commentInfo.setContent(comment.getContent());
+            commentInfo.setWriter(comment.getWriter());
+            commentInfo.setPublishDate(comment.getPublishDate());
+
+            if(comment.getReviewer() != null) {
+                Comment r = commentService.getCommentById(comment.getReviewer());
+                if(r != null) {
+                    commentInfo.setReviewer(r.getWriter());
+                    commentInfo.setReviewerId(comment.getReviewer());
+                } else {
+                    commentInfo.setReviewer("Unknown Reviewer");
+                    commentInfo.setReviewerId(0);
+                }
+            } else {
+                commentInfo.setReviewer("");
+                commentInfo.setReviewerId(0);
+            }
+
+            commentInfos.add(commentInfo);
+        }
+
         ans.put("message", "Comments retrieved successfully");
         ans.put("data", Map.of(
-           "comments", comments
+                "content", post.getContent(),
+                "comments", commentInfos
         ));
         return ResponseEntity.ok(ans);
     }
diff --git a/src/main/java/com/pt/controller/PostController.java b/src/main/java/com/pt/controller/PostController.java
index 3723dbd..c61bd3e 100644
--- a/src/main/java/com/pt/controller/PostController.java
+++ b/src/main/java/com/pt/controller/PostController.java
@@ -44,12 +44,6 @@
             return ResponseEntity.badRequest().body(ans);
         }
 
-        Post existingPost = postService.findPostByTitle(title);
-        if (existingPost != null) {
-            ans.put("result", "Post with this title already exists");
-            return ResponseEntity.badRequest().body(ans);
-        }
-
         postService.createPost(title, content, author);
         ans.put("message", "Post created successfully");
         return ResponseEntity.ok(ans);
@@ -91,9 +85,15 @@
         if(date != null){
             posts.removeIf(post -> !post.getPublishDate().toString().equals(date));
         }
+
+        posts.sort(
+                // 按发布日期降序排序
+                (p1, p2) -> p2.getPublishDate().compareTo(p1.getPublishDate())
+        );
+
         ans.put("message", "Post retrieved successfully");
         ans.put("data", Map.of(
-                "post", posts
+                "posts", posts
         ));
         return ResponseEntity.ok(ans);
     }
@@ -108,11 +108,9 @@
     @DeleteMapping("/delete")
     public ResponseEntity<?> deletePost(
             @RequestHeader("token") String token,
-            @RequestBody Map<String, String> request
+            @RequestParam("username") String username,
+            @RequestParam("pid") int pid
     ) {
-        String username = request.get("username");
-        int pid = Integer.parseInt(request.get("pid"));
-
         Map<String, Object> ans = new HashMap<>();
 
         if(!JWTUtils.checkToken(token, username, Constants.UserRole.ADMIN)){
diff --git a/src/main/java/com/pt/controller/TrackerController.java b/src/main/java/com/pt/controller/TrackerController.java
index edae09f..33d8831 100644
--- a/src/main/java/com/pt/controller/TrackerController.java
+++ b/src/main/java/com/pt/controller/TrackerController.java
@@ -23,6 +23,13 @@
             String ip = request.getRemoteAddr();
             Map<String, String[]> params = request.getParameterMap();
 
+            // 验证必要参数
+            if (!params.containsKey("username")) {
+                response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+                response.getWriter().write("Missing required parameter: username");
+                return;
+            }
+
             byte[] bencodedResponse = trackerService.handleAnnounce(params, ip);
 
             response.setContentType("application/x-bittorrent");
diff --git a/src/main/java/com/pt/controller/UserController.java b/src/main/java/com/pt/controller/UserController.java
index 7222f36..d9f53ab 100644
--- a/src/main/java/com/pt/controller/UserController.java
+++ b/src/main/java/com/pt/controller/UserController.java
@@ -77,7 +77,14 @@
         if (user != null) {
             String token = JWTUtils.generateToken(username, Constants.UserRole.USER, Constants.DEFAULT_EXPIRE_TIME);
             ans.put("message", "Login successful");
-            ans.put("data", token);
+            ans.put("data", Map.of(
+                    "token", token,
+                    "uid", user.getUid(),
+                    "username", user.getUsername(),
+                    "email", user.getEmail(),
+                    "level", user.getLevel(),
+                    "points", user.getPoints()
+            ));
             return ResponseEntity.ok().body(ans);
         } else {
             ans.put("message", "Invalid username or password");
@@ -160,9 +167,8 @@
 
     @DeleteMapping("/delete")
     public ResponseEntity<?> deleteUser(@RequestHeader("token") String token,
-                                        @RequestBody Map<String, String> request) {
-        String username = request.get("username");
-        String targetUsername = request.get("targetUsername");
+                                        @RequestParam("username") String username,
+                                        @RequestParam("targetUsername") String targetUsername) {
 
         Map<String, Object> ans = new HashMap<>();
         if(!JWTUtils.checkToken(token, username, Constants.UserRole.ADMIN)) {
@@ -183,8 +189,7 @@
 
     @GetMapping("/list")
     public ResponseEntity<?> listUsers(@RequestHeader("token") String token,
-                                       @RequestBody Map<String, String> request) {
-        String username = request.get("username");
+                                       @RequestParam("username") String username) {
         if(!JWTUtils.checkToken(token, username, Constants.UserRole.ADMIN)) {
             return ResponseEntity.badRequest().body("Invalid token");
         }
@@ -203,8 +208,10 @@
                                          @RequestParam("username") String username) {
 
         Map<String, Object> ans = new HashMap<>();
+        System.out.println("Enter user info ");
         if(!JWTUtils.checkToken(token, username, Constants.UserRole.USER)) {
             ans.put("message", "Invalid token");
+            System.out.println("Invalid token");
             return ResponseEntity.badRequest().body(ans);
         }
 
@@ -212,10 +219,71 @@
         if (user != null) {
             ans.put("message", "User info retrieved successfully");
             ans.put("data", user);
+            System.out.println("User info retrieved successfully");
             return ResponseEntity.ok(ans);
         } else {
             ans.put("message", "User not found");
+            System.out.println("User not found");
             return ResponseEntity.badRequest().body(ans);
         }
     }
+
+    /**
+     * 获取用户统计信息
+     */
+    @GetMapping("/stats/{username}")
+    public ResponseEntity<?> getUserStats(
+            @RequestHeader("token") String token,
+            @PathVariable String username) {
+        
+        Map<String, Object> ans = new HashMap<>();
+        
+        if(!JWTUtils.checkToken(token, username, Constants.UserRole.USER)) {
+            ans.put("message", "Invalid token");
+            return ResponseEntity.badRequest().body(ans);
+        }
+
+        User user = userService.findByUsername(username);
+        if (user == null) {
+            ans.put("message", "User not found");
+            return ResponseEntity.badRequest().body(ans);
+        }
+
+        // 计算分享率
+        double ratio = user.getDownloaded() == 0 ? 
+            (user.getUploaded() > 0 ? Double.MAX_VALUE : 0) : 
+            (double) user.getUploaded() / user.getDownloaded();
+        
+        // 格式化分享率为两位小数
+        ratio = Math.round(ratio * 100.0) / 100.0;
+
+        // 构建返回数据
+        Map<String, Object> stats = new HashMap<>();
+        double uploadSize = user.getUploaded() / (1024.0 * 1024.0 * 1024.0);
+        double downloadSize = user.getDownloaded() / (1024.0 * 1024.0 * 1024.0);
+        
+        stats.put("uploadSize", uploadSize); // 转换为GB
+        stats.put("downloadSize", downloadSize); // 转换为GB
+        stats.put("ratio", ratio);
+        stats.put("points", user.getPoints());
+        stats.put("userClass", getUserClass(user.getLevel()));
+        stats.put("level", user.getLevel());
+
+        ans.put("message", "User stats retrieved successfully");
+        ans.put("data", stats);
+        return ResponseEntity.ok(ans);
+    }
+
+    /**
+     * 根据用户等级返回对应的用户类别名称
+     */
+    private String getUserClass(int level) {
+        switch (level) {
+            case 5: return "大佬";
+            case 4: return "专家";
+            case 3: return "熟练";
+            case 2: return "入门";
+            default: return "新用户";
+        }
+    }
 }
diff --git a/src/main/java/com/pt/entity/Comment.java b/src/main/java/com/pt/entity/Comment.java
index b40100b..268ba64 100644
--- a/src/main/java/com/pt/entity/Comment.java
+++ b/src/main/java/com/pt/entity/Comment.java
@@ -4,6 +4,7 @@
 import jakarta.persistence.GeneratedValue;
 import jakarta.persistence.GenerationType;
 import jakarta.persistence.Id;
+import org.hibernate.annotations.Formula;
 
 import java.time.LocalDateTime;
 
@@ -20,6 +21,8 @@
 
     private LocalDateTime publishDate;
 
+    private Integer reviewer;
+
     public Comment() {
         publishDate = LocalDateTime.now();
     }
@@ -70,6 +73,13 @@
     public void setPublishDate(LocalDateTime publishDate) {
         this.publishDate = publishDate;
     }
+
+    public Integer getReviewer() {
+        return reviewer;
+    }
+    public void setReviewer(Integer reviewer) {
+        this.reviewer = reviewer;
+    }
 }
 
 
diff --git a/src/main/java/com/pt/entity/PeerInfoEntity.java b/src/main/java/com/pt/entity/PeerInfoEntity.java
index c19a269..d232a73 100644
--- a/src/main/java/com/pt/entity/PeerInfoEntity.java
+++ b/src/main/java/com/pt/entity/PeerInfoEntity.java
@@ -25,6 +25,8 @@
     private long downloaded;      // 已下载量
     private long left;            // 剩余下载量
 
+    private String username;  // 添加用户名字段
+
     public Long getId() {
         return id;
     }
@@ -113,4 +115,12 @@
     public void setActive(boolean active) {
         isActive = active;
     }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
 }
diff --git a/src/main/java/com/pt/repository/PeerInfoRepository.java b/src/main/java/com/pt/repository/PeerInfoRepository.java
index b096a35..c76df9f 100644
--- a/src/main/java/com/pt/repository/PeerInfoRepository.java
+++ b/src/main/java/com/pt/repository/PeerInfoRepository.java
@@ -3,6 +3,7 @@
 import com.pt.entity.PeerInfoEntity;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
 
 import java.time.LocalDateTime;
 import java.util.List;
@@ -21,4 +22,14 @@
     // 获取需要清理的非活跃 peer
     @Query("SELECT p FROM PeerInfoEntity p WHERE p.lastSeen < :threshold")
     List<PeerInfoEntity> findInactivePeers(LocalDateTime threshold);
+
+    // 添加按用户名查询的方法
+    List<PeerInfoEntity> findByUsername(String username);
+
+    // 添加查询用户总流量的方法
+    @Query("SELECT SUM(p.uploaded) FROM PeerInfoEntity p WHERE p.username = :username")
+    Long sumUploadedByUsername(@Param("username") String username);
+
+    @Query("SELECT SUM(p.downloaded) FROM PeerInfoEntity p WHERE p.username = :username")
+    Long sumDownloadedByUsername(@Param("username") String username);
 }
diff --git a/src/main/java/com/pt/scheduler/UserTrafficSyncScheduler.java b/src/main/java/com/pt/scheduler/UserTrafficSyncScheduler.java
new file mode 100644
index 0000000..0ec838d
--- /dev/null
+++ b/src/main/java/com/pt/scheduler/UserTrafficSyncScheduler.java
@@ -0,0 +1,65 @@
+package com.pt.scheduler;
+
+import com.pt.entity.PeerInfoEntity;
+import com.pt.entity.User;
+import com.pt.repository.PeerInfoRepository;
+import com.pt.service.UserService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+/**
+ * 定时任务,用于同步用户的流量数据
+ */
+@Component
+public class UserTrafficSyncScheduler {
+
+    private static final Logger logger = LoggerFactory.getLogger(UserTrafficSyncScheduler.class);
+
+    @Autowired
+    private UserService userService;
+
+    @Autowired
+    private PeerInfoRepository peerInfoRepository;
+
+    /**
+     * 每小时执行一次流量同步
+     * 确保用户的总流量数据准确
+     */
+    @Scheduled(cron = "0 0 * * * ?")
+    @Transactional
+    public void syncUserTraffic() {
+        logger.info("开始执行定时任务:同步用户流量数据...");
+        try {
+            List<User> users = userService.listAll();
+            for (User user : users) {
+                // 获取用户所有peer的总流量
+                Long totalUploaded = peerInfoRepository.sumUploadedByUsername(user.getUsername());
+                Long totalDownloaded = peerInfoRepository.sumDownloadedByUsername(user.getUsername());
+
+                // 如果查询结果为空,设置为0
+                totalUploaded = totalUploaded != null ? totalUploaded : 0L;
+                totalDownloaded = totalDownloaded != null ? totalDownloaded : 0L;
+
+                // 更新用户流量
+                user.setUploaded(totalUploaded);
+                user.setDownloaded(totalDownloaded);
+                userService.save(user);
+
+                // 更新用户等级
+                userService.updateUserLevel(user.getUid());
+
+                logger.info("用户 {} 流量同步完成: 上传={}, 下载={}", 
+                    user.getUsername(), totalUploaded, totalDownloaded);
+            }
+            logger.info("定时任务完成:所有用户流量数据已同步");
+        } catch (Exception e) {
+            logger.error("执行用户流量同步定时任务时发生错误", e);
+        }
+    }
+} 
\ No newline at end of file
diff --git a/src/main/java/com/pt/service/CommentService.java b/src/main/java/com/pt/service/CommentService.java
index 3d8b7dd..1ac817e 100644
--- a/src/main/java/com/pt/service/CommentService.java
+++ b/src/main/java/com/pt/service/CommentService.java
@@ -17,11 +17,16 @@
         this.commentRepository = commentRepository;
     }
 
-    public void addComment(String content, String username, int postId) {
+    public void addComment(String content, String username, int postId, Integer reviewer) {
+        System.out.println("Adding comment: " + content + " by " + username + " on post ID: " + postId + " with reviewer ID: " + reviewer);
         Comment comment = new Comment();
         comment.setContent(content);
         comment.setWriter(username);
         comment.setParentPost(postId);
+        if(reviewer != null) {
+            System.out.println("Setting reviewer ID: " + reviewer);
+            comment.setReviewer(reviewer);
+        }
         commentRepository.save(comment);
     }
 
@@ -37,4 +42,8 @@
         );
         return comments;
     }
+
+    public Comment getCommentById(int commentId) {
+        return commentRepository.findById(commentId).orElse(null);
+    }
 }
diff --git a/src/main/java/com/pt/service/TorrentService.java b/src/main/java/com/pt/service/TorrentService.java
index 1fdb700..ad38622 100644
--- a/src/main/java/com/pt/service/TorrentService.java
+++ b/src/main/java/com/pt/service/TorrentService.java
@@ -18,6 +18,10 @@
     private TorrentMetaRepository torrentMetaRepository;
 
     public TorrentMeta parseAndSaveTorrent(byte[] torrentBytes) throws Exception {
+        System.out.println("111");
+        for (byte b : torrentBytes) {
+            System.out.println(b);
+        }
         Map<String, Object> torrentDict = (Map<String, Object>) BencodeCodec.decode(torrentBytes);
         if (!torrentDict.containsKey("info")) {
             throw new IllegalArgumentException("Invalid torrent file: missing 'info' dictionary");
@@ -25,12 +29,14 @@
 
         Map<String, Object> infoDict = (Map<String, Object>) torrentDict.get("info");
 
+        System.out.println(222);
         // 计算 info_hash
         byte[] infoEncoded = BencodeCodec.encode(infoDict);
         MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
         byte[] infoHashBytes = sha1.digest(infoEncoded);
         String infoHash = bytesToHex(infoHashBytes);
 
+        System.out.println(333);
         // 获取文件名,大小等
         String name = (String) infoDict.get("name");
         long length = 0;
diff --git a/src/main/java/com/pt/service/TrackerService.java b/src/main/java/com/pt/service/TrackerService.java
index 191479b..8a654d0 100644
--- a/src/main/java/com/pt/service/TrackerService.java
+++ b/src/main/java/com/pt/service/TrackerService.java
@@ -2,10 +2,13 @@
 
 import com.pt.entity.PeerInfoEntity;
 import com.pt.entity.TorrentMeta;
+import com.pt.entity.User;
 import com.pt.exception.ResourceNotFoundException;
 import com.pt.repository.PeerInfoRepository;
 import com.pt.repository.TorrentMetaRepository;
 import com.pt.utils.BencodeCodec;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -18,6 +21,8 @@
 @Service
 public class TrackerService {
 
+    private static final Logger logger = LoggerFactory.getLogger(TrackerService.class);
+
     @Autowired
     private TorrentMetaRepository torrentMetaRepository;
 
@@ -26,6 +31,9 @@
 
     @Autowired
     private TorrentStatsService statsService;
+    
+    @Autowired
+    private UserService userService;
 
     @Transactional
     public byte[] handleAnnounce(Map<String, String[]> params, String ipAddress) {
@@ -39,6 +47,7 @@
             // 解析参数
             String infoHash = decodeParam(params.get("info_hash")[0]);
             String peerId = decodeParam(params.get("peer_id")[0]);
+            String username = decodeParam(params.get("username")[0]);
             int port = Integer.parseInt(params.get("port")[0]);
 
             // 获取事件类型
@@ -57,8 +66,16 @@
 
             // 创建或更新 peer 信息
             PeerInfoEntity peer = findOrCreatePeer(peerId, infoHash);
+            
+            // 计算流量增量
+            long uploadedDelta = uploaded - peer.getUploaded();
+            long downloadedDelta = downloaded - peer.getDownloaded();
+            
+            // 更新用户总流量
+            updateUserTraffic(username, uploadedDelta, downloadedDelta);
 
             // 设置 peer 属性
+            peer.setUsername(username);
             setPeerProperties(peer, ipAddress, port, uploaded, downloaded, left);
 
             // 处理事件类型
@@ -81,6 +98,34 @@
         }
     }
 
+    // 添加更新用户流量的方法
+    @Transactional
+    private void updateUserTraffic(String username, long uploadedDelta, long downloadedDelta) {
+        if (uploadedDelta <= 0 && downloadedDelta <= 0) {
+            return; // 没有新的流量,不需要更新
+        }
+
+        User user = userService.findByUsername(username);
+        if (user != null) {
+            long oldUploaded = user.getUploaded();
+            long oldDownloaded = user.getDownloaded();
+            
+            user.setUploaded(oldUploaded + uploadedDelta);
+            user.setDownloaded(oldDownloaded + downloadedDelta);
+            userService.save(user);
+            
+            // 更新用户等级
+            userService.updateUserLevel(user.getUid());
+            
+            logger.info("用户 {} 流量更新: 上传 {} -> {} (+{}), 下载 {} -> {} (+{})", 
+                username,
+                oldUploaded, user.getUploaded(), uploadedDelta,
+                oldDownloaded, user.getDownloaded(), downloadedDelta);
+        } else {
+            logger.warn("尝试更新不存在的用户流量: {}", username);
+        }
+    }
+
     // 辅助方法:获取事件参数
     private String getEventParam(Map<String, String[]> params) {
         return params.containsKey("event") ?
@@ -96,7 +141,15 @@
     // 辅助方法:查找或创建 peer
     private PeerInfoEntity findOrCreatePeer(String peerId, String infoHash) {
         return peerInfoRepository.findByPeerIdAndInfoHash(peerId, infoHash)
-                .orElseGet(PeerInfoEntity::new);
+                .orElseGet(() -> {
+                    PeerInfoEntity newPeer = new PeerInfoEntity();
+                    newPeer.setPeerId(peerId);
+                    newPeer.setInfoHash(infoHash);
+                    newPeer.setActive(true);
+                    newPeer.setStatus("downloading");
+                    newPeer.setLastSeen(LocalDateTime.now());
+                    return newPeer;
+                });
     }
 
     // 辅助方法:设置 peer 属性
diff --git a/src/main/java/com/pt/testResponse/TestController.java b/src/main/java/com/pt/testResponse/TestController.java
index a0dbae9..52715ac 100644
--- a/src/main/java/com/pt/testResponse/TestController.java
+++ b/src/main/java/com/pt/testResponse/TestController.java
@@ -1,15 +1,25 @@
 package com.pt.testResponse;
 
+import com.pt.CustomResponse;
 import org.springframework.web.bind.annotation.CrossOrigin;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RestController;
 
+import java.util.Map;
+
 @RestController
 @CrossOrigin(origins = "*")
 public class TestController {
 
     @GetMapping("/api/test")
-    public String testResponse() {
-        return "Hello, world!";
+    public CustomResponse testResponse() {
+        return new CustomResponse(
+                1,
+                "This is a test response",
+                Map.of(
+                        "key1", "value1",
+                        "key2", "value2"
+                )
+        );
     }
 }
diff --git a/src/main/java/com/pt/utils/JWTUtils.java b/src/main/java/com/pt/utils/JWTUtils.java
index 70a1221..6b93c9d 100644
--- a/src/main/java/com/pt/utils/JWTUtils.java
+++ b/src/main/java/com/pt/utils/JWTUtils.java
@@ -56,7 +56,7 @@
 
     public static String generateToken(String username,
                                  Constants.UserRole userType,
-                                 int expireTime) {
+                                 long expireTime) {
         Map<String, Object> claims = new HashMap<>();
         claims.put("username", username);
         claims.put("userType", userType.getValue());
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 97c5ef8..ddef23c 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -3,5 +3,9 @@
 spring.datasource.url=jdbc:mysql://202.205.102.121:3306/g12develop
 spring.datasource.username=team12
 spring.datasource.password=123456abc
+
+#spring.datasource.url=jdbc:mysql://localhost:3306/g12develop
+#spring.datasource.username=root
+#spring.datasource.password=060050aaa
 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
 spring.jackson.time-zone = Asia/Shanghai
\ No newline at end of file