调试交互

Change-Id: Ib9d7b8432cb622c7e28c842ab4dc4e156fcd6414
diff --git a/src/main/java/com/example/myproject/service/DynamicService.java b/src/main/java/com/example/myproject/service/DynamicService.java
index 853604d..9190d57 100644
--- a/src/main/java/com/example/myproject/service/DynamicService.java
+++ b/src/main/java/com/example/myproject/service/DynamicService.java
@@ -1,3 +1,278 @@
+// package com.example.myproject.service;
+
+// import com.example.myproject.entity.*;
+// import com.example.myproject.repository.*;
+// import org.springframework.beans.factory.annotation.Autowired;
+// import org.springframework.stereotype.Service;
+// import org.springframework.web.multipart.MultipartFile;
+
+// import java.io.IOException;
+// import java.nio.file.Files;
+// import java.nio.file.Path;
+// import java.nio.file.Paths;
+// import java.util.*;
+
+// @Service
+// public class DynamicService {
+
+//     @Autowired
+//     private UserDynamicRepository userDynamicRepository;
+
+//     @Autowired
+//     private UserRepository userRepository;
+
+//     @Autowired
+//     private DynamicCommentRepository dynamicCommentRepository;
+
+//     @Autowired
+//     private DynamicLikesRepository dynamicLikesRepository;
+
+//     @Autowired
+//     private FriendRelationRepository friendRelationRepository;
+
+//     private static final String IMAGE_DIR = "uploads/post/";
+
+//     // 创建好友动态
+//     public Map<String, Object> createDynamic(Long userId, String title, String content, MultipartFile[] imageFiles) {
+//         // 查找用户信息
+//         Users user = userRepository.findById(userId)
+//                 .orElseThrow(() -> new RuntimeException("User not found"));
+
+//         // 创建新的动态
+//         UserDynamic userDynamic = new UserDynamic();
+//         userDynamic.setUserId(userId);
+//         userDynamic.setTitle(title != null ? title : "默认标题");
+//         userDynamic.setContent(content);
+//         userDynamic.setTime(new Date());
+//         userDynamic.setLikesCount(0);
+//         userDynamic.setCommentsCount(0);
+
+//         // 处理图片上传
+//         StringBuilder imageUrlsBuilder = new StringBuilder();
+//         if (imageFiles != null && imageFiles.length > 0) {
+//             for (int i = 0; i < imageFiles.length; i++) {
+//                 if (i > 0) {
+//                     imageUrlsBuilder.append(",");
+//                 }
+//                 try {
+//                     String imageUrl = saveImage(imageFiles[i]);
+//                     imageUrlsBuilder.append(imageUrl);
+//                 } catch (IOException e) {
+//                     throw new RuntimeException("Image upload failed: " + e.getMessage());
+//                 }
+//             }
+//         }
+
+//         // 将多个图片 URL 拼接
+//         userDynamic.setImageUrl(imageUrlsBuilder.toString());
+
+//         // 保存数据库
+//         UserDynamic savedUserDynamic = userDynamicRepository.save(userDynamic);
+
+//         // 返回结果
+//         Map<String, Object> response = new HashMap<>();
+//         response.put("dynamicId", savedUserDynamic.getDynamicId());
+//         response.put("message", "动态创建成功");
+//         return response;
+//     }
+
+//     // 保存图片并返回图片的 URL
+//     public String saveImage(MultipartFile imageFile) throws IOException {
+//         String fileName = imageFile.getOriginalFilename();
+//         Path path = Paths.get(IMAGE_DIR + fileName);
+//         Files.createDirectories(path.getParent());
+//         Files.write(path, imageFile.getBytes());
+//         return "/images/" + fileName;
+//     }
+
+//     // 删除动态
+//     public void deleteDynamic(Long dynamicId) {
+//         if (userDynamicRepository.existsById(dynamicId)) {
+//             userDynamicRepository.deleteById(dynamicId);
+//         } else {
+//             throw new RuntimeException("Dynamic with id " + dynamicId + " not found");
+//         }
+//     }
+
+//     //好友动态评论
+//     public Map<String, Object> addComment(Long userId, Long dynamicId, String commentContent) {
+//         Users user = userRepository.findById(userId)
+//                 .orElseThrow(() -> new RuntimeException("User not found"));
+
+//         UserDynamic dynamic = userDynamicRepository.findById(dynamicId)
+//                 .orElseThrow(() -> new RuntimeException("Dynamic not found"));
+
+//         DynamicComment comment = new DynamicComment();
+//         comment.setDynamicId(dynamicId);
+//         comment.setUserId(userId);
+//         comment.setCommentContent(commentContent);
+//         comment.setCommentTime(new Date());
+
+//         // 保存评论
+//         DynamicComment savedComment = dynamicCommentRepository.save(comment);
+
+//         // 返回成功消息
+//         Map<String, Object> response = new HashMap<>();
+//         response.put("comment_id", savedComment.getCommentId());
+//         response.put("message", "评论成功");
+//         return response;
+//     }
+
+//     //返回某个好友的所有动态
+//     public Map<String, Object> getAllUserDynamics(Long userId) {
+//         // 查找用户的所有动态
+//         List<UserDynamic> userDynamics = userDynamicRepository.findByUserId(userId);
+//         Map<String, Object> postData = new LinkedHashMap<>();
+//         List<Map<String, Object>> dynamicList = new ArrayList<>();
+
+//         // 遍历动态,获取点赞和评论
+//         for (UserDynamic dynamic : userDynamics) {
+//             Map<String, Object> dynamicData = new LinkedHashMap<>();
+//             dynamicData.put("dynamic_id", dynamic.getDynamicId());
+//             dynamicData.put("user_id", dynamic.getUserId());
+
+//             Users user = userRepository.findById(dynamic.getUserId()).orElse(null);
+//             if (user != null) {
+//                 dynamicData.put("username", user.getUsername());
+//                 dynamicData.put("avatar_url", user.getAvatarUrl());
+//             } else {
+//                 dynamicData.put("username", "Unknown");
+//                 dynamicData.put("avatar_url", "http://example.com/default-avatar.jpg");
+//             }
+
+//             dynamicData.put("title", dynamic.getTitle());
+//             dynamicData.put("content", dynamic.getContent());
+//             dynamicData.put("images", dynamic.getImageUrl());
+//             dynamicData.put("time", dynamic.getTime());
+
+//             // 获取点赞
+//             List<DynamicLikes> likes = dynamicLikesRepository.findByDynamicId(dynamic.getDynamicId());
+//             List<Map<String, Object>> likeList = new ArrayList<>();
+//             for (DynamicLikes like : likes) {
+//                 Map<String, Object> likeData = new HashMap<>();
+//                 likeData.put("user_id", like.getUserId());
+
+//                 // 获取点赞用户的用户名
+//                 Users likeUser = userRepository.findById(like.getUserId()).orElse(null);
+//                 if (likeUser != null) {
+//                     likeData.put("username", likeUser.getUsername());
+//                 } else {
+//                     likeData.put("username", "Unknown");
+//                 }
+
+//                 likeList.add(likeData);
+//             }
+//             dynamicData.put("likes", likeList);
+
+//             // 获取评论
+//             List<DynamicComment> comments = dynamicCommentRepository.findByDynamicId(dynamic.getDynamicId());
+//             List<Map<String, Object>> commentList = new ArrayList<>();
+//             for (DynamicComment comment : comments) {
+//                 Map<String, Object> commentData = new HashMap<>();
+//                 commentData.put("comment_id", comment.getCommentId());
+//                 commentData.put("user_id", comment.getUserId());
+
+//                 // 获取评论用户的用户名
+//                 Users commentUser = userRepository.findById(comment.getUserId()).orElse(null);
+//                 if (commentUser != null) {
+//                     commentData.put("username", commentUser.getUsername());
+//                 } else {
+//                     commentData.put("username", "Unknown");
+//                 }
+
+//                 commentData.put("content", comment.getCommentContent());
+//                 commentData.put("time", comment.getCommentTime());
+//                 commentList.add(commentData);
+//             }
+//             dynamicData.put("comments", commentList);
+
+//             dynamicList.add(dynamicData);
+//         }
+
+//         Map<String, Object> response = new HashMap<>();
+//         response.put("dynamic", dynamicList);
+//         return response;
+//     }
+
+//     //获取当前所有好友的id
+//     public List<Long> getAllFriendIds(Long userId) {
+//         List<FriendRelation> friendRelations = friendRelationRepository.findByUserId(userId);
+//         List<Long> friendIds = new ArrayList<>();
+
+//         for (FriendRelation relation : friendRelations) {
+//             // 添加好友ID
+//             if (!friendIds.contains(relation.getFriendId())) {
+//                 friendIds.add(relation.getFriendId());
+//             }
+//         }
+
+//         return friendIds;
+//     }
+
+//     public Map<String, Object> getAllUserAndFriendsDynamics(List<Long> userIds) {
+//         List<Map<String, Object>> allDynamics = new ArrayList<>();
+
+//         // 遍历所有用户获取他们的动态
+//         for (Long userId : userIds) {
+//             Map<String, Object> userDynamics = getAllUserDynamics(userId);
+//             if (userDynamics != null && !userDynamics.isEmpty()) {
+//                 allDynamics.addAll((List<Map<String, Object>>) userDynamics.get("dynamic"));
+//             }
+//         }
+
+//         // 返回所有动态的合集
+//         Map<String, Object> response = new HashMap<>();
+//         response.put("dynamic", allDynamics);
+//         return response;
+//     }
+
+//     //点赞动态
+//     public boolean likeDynamic(Long userId, Long dynamicId) {
+//         // 检查该用户是否已经点赞过该动态
+//         DynamicLikes existingLike = dynamicLikesRepository.findByUserIdAndDynamicId(userId, dynamicId);
+//         if (existingLike != null) {
+//             return false;
+//         }
+
+//         // 新增点赞记录
+//         DynamicLikes newLike = new DynamicLikes();
+//         newLike.setUserId(userId);
+//         newLike.setDynamicId(dynamicId);
+//         newLike.setLikeTime(new java.util.Date());
+//         dynamicLikesRepository.save(newLike);
+
+//         // 更新动态表的点赞数
+//         UserDynamic dynamic = userDynamicRepository.findById(dynamicId).orElse(null);
+//         if (dynamic != null) {
+//             dynamic.setLikesCount(dynamic.getLikesCount() + 1);
+//             userDynamicRepository.save(dynamic);
+//         }
+
+//         return true;
+//     }
+
+//     //取消点赞
+//     public boolean unlikeDynamic(Long userId, Long dynamicId) {
+//         // 查找该用户的点赞记录
+//         DynamicLikes existingLike = dynamicLikesRepository.findByUserIdAndDynamicId(userId, dynamicId);
+//         if (existingLike == null) {
+//             return false;
+//         }
+
+//         // 删除点赞记录
+//         dynamicLikesRepository.delete(existingLike);
+
+//         // 更新动态表的点赞数
+//         UserDynamic dynamic = userDynamicRepository.findById(dynamicId).orElse(null);
+//         if (dynamic != null) {
+//             dynamic.setLikesCount(dynamic.getLikesCount() - 1);
+//             userDynamicRepository.save(dynamic);
+//         }
+
+//         return true;
+//     }
+
+// }
 package com.example.myproject.service;
 
 import com.example.myproject.entity.*;
@@ -95,7 +370,7 @@
     }
 
     //好友动态评论
-    public Map<String, Object> addComment(Long userId, Long dynamicId, String commentContent) {
+    public Map<String, Object> addComment(Long userId, Long dynamicId, String commentContent, Long parentCommentId) {
         Users user = userRepository.findById(userId)
                 .orElseThrow(() -> new RuntimeException("User not found"));
 
@@ -107,6 +382,7 @@
         comment.setUserId(userId);
         comment.setCommentContent(commentContent);
         comment.setCommentTime(new Date());
+        comment.setParentCommentId(parentCommentId);  // 设置父评论ID
 
         // 保存评论
         DynamicComment savedComment = dynamicCommentRepository.save(comment);
@@ -114,10 +390,12 @@
         // 返回成功消息
         Map<String, Object> response = new HashMap<>();
         response.put("comment_id", savedComment.getCommentId());
+        response.put("parent_comment_id", savedComment.getParentCommentId());
         response.put("message", "评论成功");
         return response;
     }
 
+
     //返回某个好友的所有动态
     public Map<String, Object> getAllUserDynamics(Long userId) {
         // 查找用户的所有动态
diff --git a/src/main/java/com/example/myproject/service/PostService.java b/src/main/java/com/example/myproject/service/PostService.java
index af032a5..5cacdc5 100644
--- a/src/main/java/com/example/myproject/service/PostService.java
+++ b/src/main/java/com/example/myproject/service/PostService.java
@@ -76,7 +76,7 @@
         Path path = Paths.get(IMAGE_DIR + fileName);
         Files.createDirectories(path.getParent());
         Files.write(path, imageFile.getBytes());
-        return "/images/" + fileName;
+        return "/uploads/post/" + fileName;
     }
 
     // 编辑帖子 - 添加 @Transactional
diff --git a/src/main/java/com/example/myproject/service/TorrentService.java b/src/main/java/com/example/myproject/service/TorrentService.java
index 941804d..36891d2 100644
--- a/src/main/java/com/example/myproject/service/TorrentService.java
+++ b/src/main/java/com/example/myproject/service/TorrentService.java
@@ -1,3 +1,40 @@
+// package com.example.myproject.service;
+
+// import com.example.myproject.common.base.Result;
+// import com.example.myproject.entity.TorrentEntity;
+// import com.example.myproject.dto.param.TorrentParam;
+// import com.example.myproject.dto.param.TorrentUploadParam;
+// import com.example.myproject.dto.TorrentUpdateDTO;
+// import org.springframework.web.multipart.MultipartFile;
+
+// import java.io.IOException;
+// import java.util.List;
+
+// public interface TorrentService {
+//     List<TorrentEntity> search(TorrentParam param);
+    
+//     TorrentEntity selectBySeedId(Long seedId);
+    
+//     void uploadTorrent(MultipartFile file, TorrentUploadParam param) throws IOException;
+    
+//     byte[] fetch(Long seedId, String passkey) throws IOException;
+    
+//     Result favorite(Long seedId, Long userId);
+    
+//     void deleteTorrent(Long seedId);
+    
+//     void updateTorrent(Long seedId, TorrentUpdateDTO updateDTO);
+    
+//     boolean canUserDeleteTorrent(Long seedId, Long userId);
+    
+//     boolean canUserUpdateTorrent(Long seedId, Long userId);
+    
+//     boolean checkUserUploadRatio(Long userId);
+    
+//     double calculateDownloadSize(Long torrentId, Long userId);
+    
+//     void recordDownload(Long torrentId, Long userId, double downloadSize);
+// }
 package com.example.myproject.service;
 
 import com.example.myproject.common.base.Result;
@@ -34,4 +71,6 @@
     double calculateDownloadSize(Long torrentId, Long userId);
     
     void recordDownload(Long torrentId, Long userId, double downloadSize);
+
+    TorrentEntity selectByInfoHash(String infoHash);
 }
diff --git a/src/main/java/com/example/myproject/service/UserService.java b/src/main/java/com/example/myproject/service/UserService.java
index 283a85c..de6bf8b 100644
--- a/src/main/java/com/example/myproject/service/UserService.java
+++ b/src/main/java/com/example/myproject/service/UserService.java
@@ -1,8 +1,10 @@
 package com.example.myproject.service;
-
+import cn.dev33.satoken.stp.StpUtil;
+import com.example.myproject.entity.FriendRelation;
 import com.example.myproject.entity.User;
 import com.example.myproject.entity.Users;
 import com.example.myproject.entity.UserInviteCode;
+import com.example.myproject.repository.FriendRelationRepository;
 import com.example.myproject.repository.UserRepository;
 import com.example.myproject.repository.UserInviteCodeRepository;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -27,6 +29,9 @@
     @Autowired
     private UserInviteCodeRepository userInviteCodeRepository;
 
+    @Autowired
+    private FriendRelationRepository friendRelationRepository;
+
     // 生成邀请码
     public Map<String, Object> generateInviteCode(Long userId) {
         // 获取用户信息
@@ -135,6 +140,17 @@
         // 保存用户信息
         userRepository.save(newUser);
 
+        FriendRelation newFriendRelation  = new FriendRelation();
+        newFriendRelation.setUserId(newUser.getUserId());
+        newFriendRelation.setCreateTime(new Date());
+        newFriendRelation.setFriendId(inviteUserId);
+
+        FriendRelation newFriendRelations  = new FriendRelation();
+        newFriendRelations.setUserId(inviteUserId);
+        newFriendRelations.setCreateTime(new Date());
+        newFriendRelations.setFriendId(newUser.getUserId());
+        friendRelationRepository.save(newFriendRelation);
+        friendRelationRepository.save(newFriendRelations);
         // 更新邀请码的使用状态
         inviteEntity.setIsUsed(true);
         userInviteCodeRepository.save(inviteEntity);
@@ -156,7 +172,8 @@
         if (!user.getPassword().equals(password)) {
             return "密码错误";
         }
-
+        StpUtil.login(user.getUserId());
+        
         // 登录成功
         return "登录成功";
     }
diff --git a/src/main/java/com/example/myproject/service/serviceImpl/TorrentServiceImpl.java b/src/main/java/com/example/myproject/service/serviceImpl/TorrentServiceImpl.java
index cb26f7a..4870fd5 100644
--- a/src/main/java/com/example/myproject/service/serviceImpl/TorrentServiceImpl.java
+++ b/src/main/java/com/example/myproject/service/serviceImpl/TorrentServiceImpl.java
@@ -1,5 +1,305 @@
+// package com.example.myproject.service.serviceImpl;
+
+// import com.example.myproject.entity.TorrentEntity;
+// import com.example.myproject.entity.User;
+// import com.example.myproject.mapper.TorrentMapper;
+// import com.example.myproject.mapper.UserMapper;
+// import com.example.myproject.service.TorrentService;
+// import com.example.myproject.service.PromotionService;
+// import com.example.myproject.dto.param.TorrentParam;
+// import com.example.myproject.dto.param.TorrentUploadParam;
+// import com.example.myproject.dto.TorrentUpdateDTO;
+// import com.turn.ttorrent.bcodec.BDecoder;
+// import com.turn.ttorrent.bcodec.BEValue;
+// import com.turn.ttorrent.bcodec.BEncoder;
+// import com.turn.ttorrent.client.SimpleClient;
+// import com.turn.ttorrent.common.creation.MetadataBuilder;
+// import com.turn.ttorrent.tracker.Tracker;
+// import com.turn.ttorrent.tracker.TrackedTorrent;
+// import com.example.myproject.common.base.Result;
+
+// import com.turn.ttorrent.tracker.TrackedTorrent;
+// import org.apache.commons.codec.binary.Hex;
+// import org.springframework.beans.factory.annotation.Autowired;
+// import org.springframework.stereotype.Service;
+// import org.springframework.transaction.annotation.Transactional;
+// import org.springframework.web.multipart.MultipartFile;
+
+// import java.io.ByteArrayInputStream;
+// import java.io.ByteArrayOutputStream;
+// import java.io.IOException;
+// import java.net.InetAddress;
+// import java.nio.file.Files;
+// import java.nio.file.Path;
+// import java.nio.file.Paths;
+// import java.nio.file.StandardCopyOption;
+// import java.security.MessageDigest;
+// import java.security.NoSuchAlgorithmException;
+// import java.time.LocalTime;
+// import java.util.HashMap;
+// import java.util.List;
+// import java.util.Map;
+// import java.util.concurrent.ExecutorService;
+// import java.util.concurrent.Executors;
+
+// @Service
+// public class TorrentServiceImpl implements TorrentService {
+//     @Autowired
+//     private Tracker tracker;
+
+//     @Autowired
+//     private TorrentMapper torrentMapper;
+
+//     private final Map<String, TrackedTorrent> torrentRegistry = new HashMap<>();
+
+
+//     @Autowired
+//     private UserMapper userMapper;
+
+//     @Autowired
+//     private PromotionService promotionService;
+
+//     private static final double MIN_UPLOAD_RATIO = 0.5; // 最小上传比例要求
+
+//     @Override
+//     public List<TorrentEntity> search(TorrentParam param) {
+//         return torrentMapper.search(param);
+//     }
+
+//     @Override
+//     public TorrentEntity selectBySeedId(Long seedId) {
+//         return torrentMapper.selectById(seedId);
+//     }
+//     private final ExecutorService seederExecutor = Executors.newCachedThreadPool();
+
+//     @Override
+//     @Transactional
+//     public void uploadTorrent(MultipartFile file, TorrentUploadParam param) throws IOException {
+//         // 验证用户权限
+//         User user = userMapper.selectByUserId(Long.valueOf(param.getUploader()));
+//         if (user == null) {
+//             throw new RuntimeException("用户不存在");
+//         }
+//         String workingDir = System.getProperty("user.dir");
+//         Path originalDir = Paths.get(workingDir, "data", "files");
+//         Files.createDirectories(originalDir);
+//         Path originalFilePath = originalDir.resolve(file.getOriginalFilename());
+//         Files.copy(file.getInputStream(), originalFilePath, StandardCopyOption.REPLACE_EXISTING);
+
+//         MetadataBuilder builder = new MetadataBuilder()
+//                 .addFile(originalFilePath.toFile(), file.getOriginalFilename()) // 添加原始文件
+//                 .setTracker(" ") // 设置Tracker地址
+//                 .setPieceLength(512 * 1024) // 分片大小512KB
+//                 .setComment("Generated by PT站")
+//                 .setCreatedBy("PT-Server");
+
+//         // 处理种子文件
+//         byte[] torrentBytes = file.getBytes();
+//         String infoHash = null;
+//         try {
+//             infoHash = calculateInfoHash(torrentBytes);
+//         } catch (NoSuchAlgorithmException e) {
+//             throw new RuntimeException(e);
+//         }
+
+//         // 保存种子文件到data/torrents目录
+//         Path torrentDir = Paths.get(workingDir, "data", "torrents");
+//         Files.createDirectories(torrentDir);
+//         Path torrentPath = torrentDir.resolve(infoHash + ".torrent");
+//         Files.copy(new ByteArrayInputStream(torrentBytes), torrentPath, StandardCopyOption.REPLACE_EXISTING);
+
+//         // 注册到Tracker
+//         TrackedTorrent torrent = TrackedTorrent.load(torrentPath.toFile());
+//         tracker.announce(torrent);
+
+
+//         // 异步启动做种客户端
+//         seederExecutor.submit(() -> {
+//             try {
+//                 startSeeding(torrentPath, originalDir);
+//             } catch (Exception e) {
+//                 Result.error("做种失败: " + e.getMessage());
+//             }
+//         });
+
+
+
+
+//         // 保存种子信息
+//         TorrentEntity entity= new TorrentEntity();
+//         entity.setUploader(param.getUploader());
+//         entity.setFileName(file.getOriginalFilename());
+//         entity.setSize(file.getSize());
+//         entity.setCategory(param.getCategory());
+//         entity.setTags(param.getTags());
+//         entity.setTitle(param.getTitle());
+//         entity.setImageUrl(param.getImageUrl());
+//         entity.setTorrentFile(torrentBytes);
+//         entity.setInfoHash(infoHash);
+
+//         torrentMapper.insert(entity);
+//     }
+
+//     @Override
+//     public byte[] fetch(Long seedId, String passkey) {
+//         TorrentEntity torrent = selectBySeedId(seedId);
+//         if (torrent == null) {
+//             throw new RuntimeException("种子不存在");
+//         }
+
+//         byte[] torrentBytes = torrent.getTorrentFile();
+
+//         try {
+//             // 1. 解码 .torrent 文件为 Map
+//             Map<String, BEValue> decoded = BDecoder.bdecode(new ByteArrayInputStream(torrentBytes)).getMap();
+
+//             // 2. 获取原始 announce 字段
+//             String announce = decoded.get("announce").getString();
+
+//             // 3. 注入 passkey 到 announce URL
+//             if (!announce.contains("passkey=")) {
+//                 announce = announce + "?passkey=" + passkey;
+//                 decoded.put("announce", new BEValue(announce));
+//             }
+
+//             // 4. 编码成新的 .torrent 文件字节数组
+//             ByteArrayOutputStream out = new ByteArrayOutputStream();
+//             BEncoder.bencode(decoded, out);
+//             return out.toByteArray();
+
+//         } catch (Exception e) {
+//             throw new RuntimeException("处理 torrent 文件失败", e);
+//         }
+//     }
+
+//     @Override
+//     @Transactional
+//     public Result favorite(Long seedId, Long userId) {
+//         try {
+//             boolean exists = torrentMapper.checkFavorite(seedId, userId);
+//             if (exists) {
+//                 torrentMapper.removeFavorite(seedId, userId);
+//                 return Result.success("取消收藏成功");
+//             } else {
+//                 torrentMapper.addFavorite(seedId, userId);
+//                 return Result.success("收藏成功");
+//             }
+//         } catch (Exception e) {
+//             return Result.error("失败: " + e.getMessage());
+//         }
+//     }
+
+//     @Override
+//     @Transactional
+//     public void deleteTorrent(Long seedId) {
+//         torrentMapper.deleteById(seedId);
+//     }
+
+//     @Override
+//     @Transactional
+//     public void updateTorrent(Long seedId, TorrentUpdateDTO updateDTO) {
+//         TorrentEntity torrent = selectBySeedId(seedId);
+//         if (torrent == null) {
+//             throw new RuntimeException("种子不存在");
+//         }
+
+
+//         torrent.setDescription(updateDTO.getDescription());
+//         torrent.setCategory(updateDTO.getCategory());
+//         torrent.setTitle(updateDTO.getTitle());
+//         torrent.setTags(updateDTO.getTags());
+//         torrent.setImageUrl(updateDTO.getImageUrl());
+
+//         torrentMapper.updateById(torrent);
+//     }
+
+//     @Override
+//     public boolean canUserDeleteTorrent(Long seedId, Long userId) {
+//         TorrentEntity torrent = selectBySeedId(seedId);
+//         if (torrent == null) {
+//             return false;
+//         }
+
+//         // 检查是否是种子发布者或管理员
+//         return torrent.getUploader().equals(userId) ||
+//                 userMapper.hasRole(userId, "admin");
+//     }
+
+//     @Override
+//     public boolean canUserUpdateTorrent(Long seedId, Long userId) {
+//         return canUserDeleteTorrent(seedId, userId);
+//     }
+
+//     @Override
+//     public boolean checkUserUploadRatio(Long userId) {
+//         User user = userMapper.selectById(userId);
+//         if (user == null) {
+//             return false;
+//         }
+
+//         // 防止除以零
+//         if (user.getDownloaded() == 0) {
+//             return true;
+//         }
+
+//         double uploadRatio = user.getUploaded() / (double) user.getDownloaded();
+//         return uploadRatio >= MIN_UPLOAD_RATIO;
+//     }
+//     /**
+//      * 启动做种客户端
+//      */
+//     private void startSeeding(Path torrentPath, Path dataDir) throws Exception {
+//         SimpleClient seederClient = new SimpleClient();
+//         seederClient.downloadTorrent(
+//                 torrentPath.toString(),
+//                 dataDir.toString(),
+//                 InetAddress.getLocalHost());
+//         // 保持做种状态(阻塞线程)
+//         while (true) {
+//             Thread.sleep(60000); // 每60秒检查一次
+//         }
+//     }
+
+
+//     @Override
+//     public double calculateDownloadSize(Long torrentId, Long userId) {
+//         TorrentEntity torrent = selectBySeedId(torrentId);
+//         if (torrent == null) {
+//             throw new RuntimeException("种子不存在");
+//         }
+
+//         // 获取当前有效的促销活动
+//         double discount = promotionService.getCurrentDiscount(torrentId);
+
+//         // 计算实际下载量
+//         return torrent.getSize() * (1 - discount / 100.0);
+//     }
+
+//     @Override
+//     @Transactional
+//     public void recordDownload(Long torrentId, Long userId, double downloadSize) {
+//         // 更新用户下载量
+//         userMapper.increaseDownloaded(userId, downloadSize);
+
+//         // 更新种子下载次数
+//         torrentMapper.increaseDownloads(torrentId);
+//     }
+//     /**
+//      * 计算种子文件的infoHash
+//      */
+//     private String calculateInfoHash(byte[] torrentData) throws NoSuchAlgorithmException  {
+//         MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
+//         sha1.update(torrentData);
+//         byte[] hashBytes = sha1.digest();
+//         return Hex.encodeHexString(hashBytes);
+//     }
+// }
+
 package com.example.myproject.service.serviceImpl;
 
+import cn.dev33.satoken.stp.StpUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.example.myproject.entity.TorrentEntity;
 import com.example.myproject.entity.User;
 import com.example.myproject.mapper.TorrentMapper;
@@ -13,6 +313,8 @@
 import com.turn.ttorrent.bcodec.BEValue;
 import com.turn.ttorrent.bcodec.BEncoder;
 import com.turn.ttorrent.client.SimpleClient;
+import com.turn.ttorrent.common.TorrentMetadata;
+import com.turn.ttorrent.common.TorrentParser;
 import com.turn.ttorrent.common.creation.MetadataBuilder;
 import com.turn.ttorrent.tracker.Tracker;
 import com.turn.ttorrent.tracker.TrackedTorrent;
@@ -80,66 +382,29 @@
         if (user == null) {
             throw new RuntimeException("用户不存在");
         }
-        String workingDir = System.getProperty("user.dir");
-        Path originalDir = Paths.get(workingDir, "data", "files");
-        Files.createDirectories(originalDir);
-        Path originalFilePath = originalDir.resolve(file.getOriginalFilename());
-        Files.copy(file.getInputStream(), originalFilePath, StandardCopyOption.REPLACE_EXISTING);
 
-        MetadataBuilder builder = new MetadataBuilder()
-                .addFile(originalFilePath.toFile(), file.getOriginalFilename()) // 添加原始文件
-                .setTracker(" ") // 设置Tracker地址
-                .setPieceLength(512 * 1024) // 分片大小512KB
-                .setComment("Generated by PT站")
-                .setCreatedBy("PT-Server");
-
-        // 处理种子文件
         byte[] torrentBytes = file.getBytes();
-        String infoHash = null;
-        try {
-            infoHash = calculateInfoHash(torrentBytes);
-        } catch (NoSuchAlgorithmException e) {
-            throw new RuntimeException(e);
-        }
+        TorrentMetadata metadata = new TorrentParser().parse(torrentBytes);
 
-        // 保存种子文件到data/torrents目录
-        Path torrentDir = Paths.get(workingDir, "data", "torrents");
-        Files.createDirectories(torrentDir);
-        Path torrentPath = torrentDir.resolve(infoHash + ".torrent");
-        Files.copy(new ByteArrayInputStream(torrentBytes), torrentPath, StandardCopyOption.REPLACE_EXISTING);
-
-        // 注册到Tracker
-        TrackedTorrent torrent = TrackedTorrent.load(torrentPath.toFile());
-        tracker.announce(torrent);
-
-
-        // 异步启动做种客户端
-        seederExecutor.submit(() -> {
-            try {
-                startSeeding(torrentPath, originalDir);
-            } catch (Exception e) {
-                Result.error("做种失败: " + e.getMessage());
-            }
-        });
-
-
-
+        Long size = metadata.getFiles().stream().map(f -> f.size).reduce(0L, Long::sum);
 
         // 保存种子信息
         TorrentEntity entity= new TorrentEntity();
         entity.setUploader(param.getUploader());
         entity.setFileName(file.getOriginalFilename());
-        entity.setSize(file.getSize());
+        entity.setSize(size);
         entity.setCategory(param.getCategory());
         entity.setTags(param.getTags());
         entity.setTitle(param.getTitle());
         entity.setImageUrl(param.getImageUrl());
         entity.setTorrentFile(torrentBytes);
-        entity.setInfoHash(infoHash);
+        entity.setInfoHash(metadata.getHexInfoHash());
 
         torrentMapper.insert(entity);
     }
 
+
+
     @Override
     public byte[] fetch(Long seedId, String passkey) {
         TorrentEntity torrent = selectBySeedId(seedId);
@@ -154,14 +419,11 @@
             Map<String, BEValue> decoded = BDecoder.bdecode(new ByteArrayInputStream(torrentBytes)).getMap();
 
             // 2. 获取原始 announce 字段
-            String announce = decoded.get("announce").getString();
+// TODO: 对应本机应用地址
+//            String announce = "http://127.0.0.1:5011/seeds/announce?passkey="+passkey +"&userId=" + StpUtil.getLoginIdAsString();
+            String announce = "http://192.168.5.149:5011/seeds/announce?passkey=" + passkey + "&userId=" + StpUtil.getLoginIdAsString();
 
-            // 3. 注入 passkey 到 announce URL
-            if (!announce.contains("passkey=")) {
-                announce = announce + "?passkey=" + passkey;
-                decoded.put("announce", new BEValue(announce));
-            }
-
+            decoded.put("announce", new BEValue(announce));
             // 4. 编码成新的 .torrent 文件字节数组
             ByteArrayOutputStream out = new ByteArrayOutputStream();
             BEncoder.bencode(decoded, out);
@@ -284,6 +546,12 @@
         // 更新种子下载次数
         torrentMapper.increaseDownloads(torrentId);
     }
+
+    @Override
+    public TorrentEntity selectByInfoHash(String infoHash) {
+        return torrentMapper.selectByInfoHash(infoHash);
+    }
+
     /**
      * 计算种子文件的infoHash
      */