add torrent upload(finished) and tracker announce(unimplemnt)

Change-Id: I017c03df2bc1c40c4a080837821d56dfe58d6eb6
diff --git a/src/main/java/com/example/g8backend/service/ITorrentService.java b/src/main/java/com/example/g8backend/service/ITorrentService.java
new file mode 100644
index 0000000..5e48dc4
--- /dev/null
+++ b/src/main/java/com/example/g8backend/service/ITorrentService.java
@@ -0,0 +1,13 @@
+package com.example.g8backend.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.example.g8backend.entity.Torrent;
+
+import java.io.File;
+import java.io.IOException;
+
+public interface ITorrentService extends IService<Torrent> {
+    Torrent handleTorrentUpload(File file, Long userId, String passkey) throws IOException;
+    Torrent findByInfoHash(String infoHash);
+    Torrent findByTorrentId(Long torrentId);
+}
diff --git a/src/main/java/com/example/g8backend/service/IUserService.java b/src/main/java/com/example/g8backend/service/IUserService.java
index 2fb4fc9..f407c37 100644
--- a/src/main/java/com/example/g8backend/service/IUserService.java
+++ b/src/main/java/com/example/g8backend/service/IUserService.java
@@ -7,5 +7,6 @@
 public interface IUserService extends IService<User> {
     User getUserByName(@Param("name") String name);
     User getUserByEmail(@Param("email") String email);
+    User getUserByPasskey(@Param("passkey") String passkey);
     void registerUser(User user);;
 }
diff --git a/src/main/java/com/example/g8backend/service/TrackerServiceImpl.java b/src/main/java/com/example/g8backend/service/TrackerServiceImpl.java
deleted file mode 100644
index ae12f70..0000000
--- a/src/main/java/com/example/g8backend/service/TrackerServiceImpl.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.example.g8backend.service;
-
-import org.springframework.stereotype.Service;
-
-@Service
-public class TrackerServiceImpl implements ITrackerService {
-}
diff --git a/src/main/java/com/example/g8backend/service/impl/TorrentServiceImpl.java b/src/main/java/com/example/g8backend/service/impl/TorrentServiceImpl.java
new file mode 100644
index 0000000..03185ba
--- /dev/null
+++ b/src/main/java/com/example/g8backend/service/impl/TorrentServiceImpl.java
@@ -0,0 +1,67 @@
+package com.example.g8backend.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.example.g8backend.entity.Torrent;
+import com.example.g8backend.mapper.TorrentMapper;
+import com.example.g8backend.service.ITorrentService;
+import com.example.g8backend.util.TorrentUtil;
+import jakarta.annotation.Resource;
+import org.springframework.stereotype.Service;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+@Service
+public class TorrentServiceImpl  extends ServiceImpl<TorrentMapper, Torrent> implements ITorrentService {
+    @Resource
+    private TorrentMapper torrentMapper;
+
+    @Override
+    public Torrent handleTorrentUpload(File file, Long userId, String passkey) throws IOException{
+        String tracker = "http://127.0.0.1:8080/announce/" + passkey;
+
+        // 修改 announce 字段
+        byte[] modifiedBytes = TorrentUtil.injectTracker(file, tracker);
+
+        // 计算 info_hash
+        String infoHash = TorrentUtil.getInfoHash(file);
+
+        // 文件大小(以MB为单位)
+        double fileSize = file.length() / 1024.0 / 1024.0;
+
+        // 保存新的种子文件(可选)
+        File outputDir = new File("uploaded-torrents");
+        if (!outputDir.exists()) {
+            if (!outputDir.mkdirs()){
+                throw new IOException("Failed to create directory: " + outputDir.getAbsolutePath());
+            }
+        }
+
+        File savedFile = new File(outputDir, file.getName());
+        try (FileOutputStream fos = new FileOutputStream(savedFile)) {
+            fos.write(modifiedBytes);
+        }
+
+        // 插入数据库
+        torrentMapper.insertTorrent(userId, file.getName(), infoHash, fileSize);
+
+        // 构建返回实体
+        Torrent torrent = new Torrent();
+        torrent.setUserId(userId);
+        torrent.setTorrentName(file.getName());
+        torrent.setInfoHash(infoHash);
+        torrent.setFileSize(fileSize);
+        return torrent;
+    }
+
+    @Override
+    public Torrent findByInfoHash(String infoHash){
+        return torrentMapper.getTorrentByInfoHash(infoHash);
+    }
+
+    @Override
+    public Torrent findByTorrentId(Long torrentId){
+        return torrentMapper.getTorrentByTorrentId(torrentId);
+    }
+}
diff --git a/src/main/java/com/example/g8backend/service/impl/TrackerServiceImpl.java b/src/main/java/com/example/g8backend/service/impl/TrackerServiceImpl.java
new file mode 100644
index 0000000..c0dba70
--- /dev/null
+++ b/src/main/java/com/example/g8backend/service/impl/TrackerServiceImpl.java
@@ -0,0 +1,8 @@
+package com.example.g8backend.service.impl;
+
+import com.example.g8backend.service.ITrackerService;
+import org.springframework.stereotype.Service;
+
+@Service
+public class TrackerServiceImpl implements ITrackerService {
+}
diff --git a/src/main/java/com/example/g8backend/service/UserServiceImpl.java b/src/main/java/com/example/g8backend/service/impl/UserServiceImpl.java
similarity index 76%
rename from src/main/java/com/example/g8backend/service/UserServiceImpl.java
rename to src/main/java/com/example/g8backend/service/impl/UserServiceImpl.java
index 567c5f3..3f3357c 100644
--- a/src/main/java/com/example/g8backend/service/UserServiceImpl.java
+++ b/src/main/java/com/example/g8backend/service/impl/UserServiceImpl.java
@@ -1,11 +1,10 @@
-package com.example.g8backend.service;
+package com.example.g8backend.service.impl;
 
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.example.g8backend.entity.User;
 import com.example.g8backend.mapper.UserMapper;
+import com.example.g8backend.service.IUserService;
 import jakarta.annotation.Resource;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.crypto.password.PasswordEncoder;
 import org.springframework.stereotype.Service;
 
 
@@ -14,9 +13,6 @@
     @Resource
     private UserMapper userMapper; // 手动注入 UserMapper
 
-    @Autowired
-    private PasswordEncoder passwordEncoder;
-
     @Override
     public User getUserByName(String name) { return userMapper.getUserByName(name);} // 调用 UserMapper 的自定义 SQL
 
@@ -24,5 +20,8 @@
     public User getUserByEmail(String email) { return userMapper.getUserByEmail(email);}
 
     @Override
+    public User getUserByPasskey(String passkey) { return userMapper.getUserByPasskey(passkey);}
+
+    @Override
     public void registerUser(User user) {userMapper.insert(user);}
 }