添加API接口,修改DB1文件

Change-Id: I5a493962f5a8b0c60e6944a7d630263789d3b4ee
diff --git a/.gitignore b/.gitignore
index a221ac1..764386a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
 target/
 .vscode/
+torrents/
\ No newline at end of file
diff --git a/src/main/java/api/ApiApplication.java b/src/main/java/api/ApiApplication.java
index 93eb640..6d65a81 100644
--- a/src/main/java/api/ApiApplication.java
+++ b/src/main/java/api/ApiApplication.java
@@ -8,4 +8,18 @@
     public static void main(String[] args) {
         SpringApplication.run(ApiApplication.class, args);
     }
+
+    // @Bean
+    // public WebMvcConfigurer corsConfigurer() {
+    //     return new WebMvcConfigurer() {
+    //         @Override
+    //         public void addCorsMappings(CorsRegistry registry) {
+    //             registry.addMapping("/**")
+    //                     .allowedOrigins("*")
+    //                     .allowedMethods("*")
+    //                     .allowedHeaders("*")
+    //                     .exposedHeaders(HttpHeaders.CONTENT_DISPOSITION);
+    //         }
+    //     };
+    // }
 }
\ No newline at end of file
diff --git a/src/main/java/api/ApiController.java b/src/main/java/api/ApiController.java
index a683b0e..d8528db 100644
--- a/src/main/java/api/ApiController.java
+++ b/src/main/java/api/ApiController.java
@@ -2,25 +2,41 @@
 
 import java.io.File;
 
+import javax.annotation.PostConstruct;
+
 import org.springframework.core.io.FileSystemResource;
 import org.springframework.core.io.Resource;
 import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
 import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.bind.annotation.CrossOrigin;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
 
 import database.Database1;
 import entity.Seed;
 import tracker.Tracker;
 
+
 @RestController
 public class ApiController implements ApiInterface {
 
-    private static Database1 db;
-
+    private static Database1 db1;
     private static Tracker tracker;
+    private static ObjectMapper mapper;
+
+    @PostConstruct
+    public void init() {
+        db1 = new Database1();
+        tracker = new Tracker();
+        mapper = new ObjectMapper();
+        mapper.configure(com.fasterxml.jackson.databind.SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
+    }
 
     @Override
     public ResponseEntity<Integer> saveTorrent(
@@ -37,42 +53,106 @@
             seed.seedsize = "1GB"; // 示例种子大小
             seed.seedtag = tag; // 示例标签
             seed.url = "http://example.com/torrent"; // 示例URL
-            db = new Database1();
-            tracker = new Tracker();
-            int ret = db.RegisterSeed(seed);
-            System.out.println("RegisterSeed ret: " + ret);
-            System.out.println(seed.seedid + " " + seed.seeduserid + " " + seed.title + " " + seed.seedsize + " " + seed.seedtag + " " + seed.url);
+
+            int ret = db1.RegisterSeed(seed);
+            // System.out.println("RegisterSeed ret: " + ret);
+            // System.out.println(seed.seedid + " " + seed.seeduserid + " " + seed.title + " " + seed.seedsize + " " + seed.seedtag + " " + seed.url);
+
             // Convert MultipartFile to File
             File tempFile = File.createTempFile(seed.seedid, file.getOriginalFilename());
             file.transferTo(tempFile);
+
             tracker.SaveTorrent(seed.seedid, tempFile);
+
             // Optionally, delete the temp file after saving if not needed
             // tempFile.delete();
-            return ResponseEntity.ok(0); // 返回 0 表示成功
+
+            // 创建带有 CORS 响应头的 ResponseEntity
+            HttpHeaders headers = new HttpHeaders();
+            headers.add("Access-Control-Allow-Origin", "*"); // 允许所有域名访问,可以根据需要调整为特定域名
+            headers.add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); // 允许的 HTTP 方法
+            headers.add("Access-Control-Allow-Headers", "Content-Type, Authorization"); // 允许的请求头
+
+            return new ResponseEntity<>(0, headers, HttpStatus.OK); // 返回 0 表示成功
         } catch (Exception e) {
             e.printStackTrace();
-            return ResponseEntity.status(500).body(1); // 返回 1 表示失败
+
+            // 创建带有 CORS 响应头的错误 ResponseEntity
+            HttpHeaders errorHeaders = new HttpHeaders();
+            errorHeaders.add("Access-Control-Allow-Origin", "*");
+            errorHeaders.add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
+            errorHeaders.add("Access-Control-Allow-Headers", "Content-Type, Authorization");
+
+            return new ResponseEntity<>(1, errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR); // 返回 1 表示失败
         }
     }
 
     @Override
+    @CrossOrigin(origins = "*", allowedHeaders = "*") // 允许所有来源和头部
     public ResponseEntity<Resource> getTorrent(
-        @RequestParam("seedid") String seedid,
-        @RequestParam("userid") String userid,
-        @RequestParam("ip") String ip
+            @RequestParam("torrentId") String seedid,
+            @RequestParam("userId") String userid
     ) {
-        // 实现获取种子文件的逻辑
-        // 示例:从本地目录中查找文件
-        tracker = new Tracker();
-        File file = tracker.GetTTorent(seedid, userid, ip);
+        File file = tracker.GetTTorent(seedid, userid);
         if (file != null) {
             FileSystemResource resource = new FileSystemResource(file);
             return ResponseEntity.ok()
                 .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + file.getName() + "\"")
+                .header(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, HttpHeaders.CONTENT_DISPOSITION) // 关键:允许前端访问Content-Disposition
                 .contentType(MediaType.APPLICATION_OCTET_STREAM)
                 .body(resource);
         } else {
-            return ResponseEntity.notFound().build(); // 返回 404 表示文件未找到
+            return ResponseEntity.notFound().build();
+        }
+    }
+
+    //无按标签查询的函数
+    @Override
+    public ResponseEntity<String> getSeedListByTag(
+        @RequestParam("tag") String tag
+    ) {
+        try {
+            Seed[] seeds = db1.GetSeedListByTag(tag);
+            String json = mapper.writeValueAsString(seeds);
+            // System.out.println("getSeedListByTag: " + json);
+            HttpHeaders headers = new HttpHeaders();
+            headers.add("Access-Control-Allow-Origin", "*");
+            headers.add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
+            headers.add("Access-Control-Allow-Headers", "Content-Type, Authorization");
+            return new ResponseEntity<>(json, headers, HttpStatus.OK);
+        } catch (JsonProcessingException e) {
+            e.printStackTrace();
+            HttpHeaders errorHeaders = new HttpHeaders();
+            errorHeaders.add("Access-Control-Allow-Origin", "*");
+            errorHeaders.add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
+            errorHeaders.add("Access-Control-Allow-Headers", "Content-Type, Authorization");
+            return new ResponseEntity<>("[]", errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR);
+        }
+    }
+
+    @Override
+    public ResponseEntity<String> getTorrentDetail(
+        @RequestParam("id") String seedid
+    ) {
+        try {
+            Seed seed = db1.GetSeedInformation(seedid);
+            if (seed != null) {
+                String json = mapper.writeValueAsString(seed);
+                HttpHeaders headers = new HttpHeaders();
+                headers.add("Access-Control-Allow-Origin", "*");
+                headers.add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
+                headers.add("Access-Control-Allow-Headers", "Content-Type, Authorization");
+                return new ResponseEntity<>(json, headers, HttpStatus.OK);
+            } else {
+                return ResponseEntity.notFound().build(); // 返回 404 表示种子未找到
+            }
+        } catch (JsonProcessingException e) {
+            e.printStackTrace();
+            HttpHeaders errorHeaders = new HttpHeaders();
+            errorHeaders.add("Access-Control-Allow-Origin", "*");
+            errorHeaders.add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
+            errorHeaders.add("Access-Control-Allow-Headers", "Content-Type, Authorization");
+            return new ResponseEntity<>("{}", errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR);
         }
     }
 }
\ No newline at end of file
diff --git a/src/main/java/api/ApiInterface.java b/src/main/java/api/ApiInterface.java
index ab3408c..6859aa6 100644
--- a/src/main/java/api/ApiInterface.java
+++ b/src/main/java/api/ApiInterface.java
@@ -23,8 +23,17 @@
 
     @GetMapping("/get-torrent")
     ResponseEntity<Resource> getTorrent(
-        @RequestParam("seedid") String seedid,
-        @RequestParam("userid") String userid,
-        @RequestParam("ip") String ip
+        @RequestParam("torrentId") String seedid,
+        @RequestParam("userId") String userid
+    );
+
+    @GetMapping("/get-seed-list-by-tag")
+    ResponseEntity<String> getSeedListByTag(
+        @RequestParam("tag") String tag
+    );
+
+    @GetMapping("/torrent-detail")
+    ResponseEntity<String> getTorrentDetail(
+        @RequestParam("id") String seedid
     );
 }
\ No newline at end of file
diff --git a/src/main/java/database/DataManagerInterface.java b/src/main/java/database/DataManagerInterface.java
index b92d18d..e737daa 100644
--- a/src/main/java/database/DataManagerInterface.java
+++ b/src/main/java/database/DataManagerInterface.java
@@ -23,7 +23,8 @@
     public int UpdateSeed(Seed seedinfo);//接收新的种子然后更新其全部属性;
 
     public Seed[] SearchSeed(String userQ);//传入搜索的关键词或句子,返回搜索到的种子信息(按照公共字符数量排序)
-    
+    public Seed[] GetSeedListByTag(String tag);//获取某个标签下的种子列表
+
     public int AddNotice(Notice notice);//返回状态:0 success,1 重复,2其他原因
     public boolean UpdateNotice(Notice notice);//返回状态:0 success,1 重复,2其他原因
     public boolean DeleteNotice(String noticeid);//删除公告,返回状态:0 success,1 重复,2其他原因
diff --git a/src/main/java/database/Database1.java b/src/main/java/database/Database1.java
index f835288..ed64717 100644
--- a/src/main/java/database/Database1.java
+++ b/src/main/java/database/Database1.java
@@ -156,20 +156,40 @@
         return seed;
     }
 
+    @Override
+    public Seed[] GetSeedListByTag(String tag){
+        JPAQuery<Seed> query = new JPAQuery<>(entitymanager);
+        QSeed s = QSeed.seed;
+        List<Seed> seeds = query.select(s).from(s).where(s.seedtag.eq(tag)).fetch();
+        return seeds.toArray(new Seed[0]);
+    }
+
     //添加一个新的种子,0成功,其他失败信息待定;
     @Override
     public int RegisterSeed(Seed seedinfo){
         try {
+            entitymanager.getTransaction().begin();
             JPAQuery<Seed> query = new JPAQuery<>(entitymanager);
             QSeed s = QSeed.seed;
             Seed seed = query.select(s).from(s).where(s.seedid.eq(seedinfo.seedid)).fetchOne();
+            User user = entitymanager.find(User.class, seedinfo.seeduserid);
+            if (user == null) {
+                entitymanager.getTransaction().rollback();
+                return 2; // 用户不存在
+            }
+            seed.user = user; // 设置种子的用户关联
             if (seed != null) {
+                entitymanager.getTransaction().rollback();
                 return 1;
             }
             entitymanager.persist(seedinfo);
+            entitymanager.getTransaction().commit();
             return 0;
         } catch (Exception e) {
             e.printStackTrace();
+            if (entitymanager.getTransaction().isActive()) {
+                entitymanager.getTransaction().rollback();
+            }
             return 2;
         }
     }
diff --git a/src/main/java/database/Database2.java b/src/main/java/database/Database2.java
index 8ea93b0..5152e47 100644
--- a/src/main/java/database/Database2.java
+++ b/src/main/java/database/Database2.java
@@ -128,6 +128,11 @@
     }
 
     @Override
+    public Seed[] GetSeedListByTag(String tag) {
+        return new Seed[0];
+    }
+
+    @Override
     public boolean AddCollect(String userid, String postid) {
         return false;
     }
diff --git a/src/main/java/tracker/Tracker.java b/src/main/java/tracker/Tracker.java
index da92c17..008ac4a 100644
--- a/src/main/java/tracker/Tracker.java
+++ b/src/main/java/tracker/Tracker.java
@@ -186,7 +186,7 @@
         }
     }
     @Override
-    public File GetTTorent(String seedid, String userid, String ip) {
+    public File GetTTorent(String seedid, String userid) {
         EntityManager em = emf.createEntityManager();
         EntityTransaction tx = em.getTransaction();
         File file = null;
@@ -203,7 +203,6 @@
             SeedDownload sd = new SeedDownload();
             sd.seedId = seedid;
             sd.userId = userid;
-            sd.clientIp = ip;
             LocalDateTime now = LocalDateTime.now();
             sd.downloadStart = now;
             sd.downloadEnd = now;
diff --git a/src/main/java/tracker/TrackerInterface.java b/src/main/java/tracker/TrackerInterface.java
index eb9d002..b65b8be 100644
--- a/src/main/java/tracker/TrackerInterface.java
+++ b/src/main/java/tracker/TrackerInterface.java
@@ -1,7 +1,6 @@
 package tracker;
 import java.io.File;
 
-import entity.TTorent;
 import entity.TransRecord;
 public interface TrackerInterface{
     public boolean AddUpLoad(String userid,int upload);//给用户新增上传量,返回0成功,返回1失败;
@@ -12,7 +11,7 @@
     public boolean ReduceMagic(String userid,int magic);//给用户减少魔力值,返回0成功,返回1失败;
 
     public int SaveTorrent(String seedid,File TTorent);//保存seedid对应的ttorent信息
-    public File GetTTorent(String seedid,String userid,String ip);//根据种子id获得ttorent信息然后构建Ttorent文件并返回,同时记录用户的下载行为
+    public File GetTTorent(String seedid,String userid);//根据种子id获得ttorent信息然后构建Ttorent文件并返回,同时记录用户的下载行为
     
     public int AddRecord(TransRecord rd);//新增一个seedid对应的种子的传输任务记录
 }
\ No newline at end of file
diff --git a/src/test/java/trackertest/TrackerTest.java b/src/test/java/trackertest/TrackerTest.java
index 8f45a4a..c307ba6 100644
--- a/src/test/java/trackertest/TrackerTest.java
+++ b/src/test/java/trackertest/TrackerTest.java
@@ -8,15 +8,18 @@
 import java.util.UUID;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
+
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
 import javax.persistence.EntityTransaction;
 import javax.persistence.Persistence;
+
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.DynamicTest;
 import org.junit.jupiter.api.TestFactory;
+
 import entity.Seed;
 import entity.TransRecord;
 import entity.TransportId;
@@ -327,7 +330,7 @@
                 Assertions.assertNotNull(seed.url, "Seed.url 应已被更新");
                 // 调用 GetTTorent 并断言路径一致
                 String uid = userIds.get(0), ip = "127.0.0.1";
-                File ret = tracker.GetTTorent(sid, uid, ip);
+                File ret = tracker.GetTTorent(sid, uid);
                 File expected = new File(seed.url);
                 Assertions.assertNotNull(ret, "应返回文件对象");
                 Assertions.assertEquals(