添加了接口文档
Change-Id: Idc25e39438af13bb9505c08bca5ab1c29789b8ff
diff --git a/src/main/java/edu/bjtu/groupone/backend/api/DbTestController.java b/src/main/java/edu/bjtu/groupone/backend/api/DbTestController.java
index ea24d21..77991fb 100644
--- a/src/main/java/edu/bjtu/groupone/backend/api/DbTestController.java
+++ b/src/main/java/edu/bjtu/groupone/backend/api/DbTestController.java
@@ -1,5 +1,11 @@
package edu.bjtu.groupone.backend.api;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.ExampleObject;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -8,6 +14,7 @@
import javax.sql.DataSource;
import java.sql.Connection;
+@Tag(name = "数据库测试", description = "用于检测后端 DataSource 是否能正常连接数据库")
@RestController
@RequestMapping("/test")
public class DbTestController {
@@ -15,6 +22,31 @@
@Autowired
private DataSource dataSource;
+ @Operation(summary = "测试数据库连接", description = "尝试获取 Connection 并返回 JDBC URL")
+ @ApiResponses({
+ @ApiResponse(
+ responseCode = "200",
+ description = "成功连接数据库",
+ content = @Content(
+ mediaType = "text/plain",
+ examples = @ExampleObject(
+ name = "连接成功示例",
+ value = "✅ 成功连接数据库:jdbc:mysql://localhost:3306/groupone_db"
+ )
+ )
+ ),
+ @ApiResponse(
+ responseCode = "500",
+ description = "无法连接数据库",
+ content = @Content(
+ mediaType = "text/plain",
+ examples = @ExampleObject(
+ name = "连接失败示例",
+ value = "❌ 无法连接数据库:Communications link failure"
+ )
+ )
+ )
+ })
@GetMapping("/db")
public String testDb() {
try (Connection conn = dataSource.getConnection()) {
diff --git a/src/main/java/edu/bjtu/groupone/backend/api/TorrentController.java b/src/main/java/edu/bjtu/groupone/backend/api/TorrentController.java
index 773c5f6..ef321b1 100644
--- a/src/main/java/edu/bjtu/groupone/backend/api/TorrentController.java
+++ b/src/main/java/edu/bjtu/groupone/backend/api/TorrentController.java
@@ -3,6 +3,14 @@
import edu.bjtu.groupone.backend.domain.entity.Torrent;
import edu.bjtu.groupone.backend.service.TorrentService;
import edu.bjtu.groupone.backend.utils.GetTokenUserId;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.ExampleObject;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
@@ -13,6 +21,7 @@
import java.util.List;
+@Tag(name = "Torrent 管理", description = "种子文件的上传、下载及列表查询")
@RestController
@RequestMapping("/api/torrents")
public class TorrentController {
@@ -25,17 +34,66 @@
this.torrentService = torrentService;
}
+ @Operation(summary = "上传种子文件", description = "接收前端上传的 .torrent 文件,并保存到服务器和数据库")
+ @ApiResponses({
+ @ApiResponse(
+ responseCode = "200",
+ description = "上传成功,返回 Torrent 对象",
+ content = @Content(
+ mediaType = "application/json",
+ schema = @Schema(implementation = Torrent.class),
+ examples = @ExampleObject(
+ name = "上传成功示例",
+ value = "{\n" +
+ " \"id\": 1,\n" +
+ " \"infoHash\": \"ABCDEF1234567890ABCDEF1234567890ABCDEF12\",\n" +
+ " \"fileName\": \"movie.torrent\",\n" +
+ " \"userId\": 1,\n" +
+ " \"uploadTime\": \"2025-06-07T16:35:12\"\n" +
+ "}"
+ )
+ )
+ ),
+ @ApiResponse(responseCode = "400", description = "文件格式不支持或参数错误")
+ })
@PostMapping("/upload")
public ResponseEntity<?> uploadTorrent(
+ @Parameter(
+ description = "种子文件 (.torrent)",
+ required = true,
+ content = @Content(
+ mediaType = "application/octet-stream",
+ schema = @Schema(type = "string", format = "binary")
+ )
+ )
@RequestParam("file") MultipartFile file,
+ @Parameter(description = "上传者用户 ID", required = true, example = "1")
@RequestParam("id") Long id ) throws Exception {
Torrent saved = torrentService.uploadTorrent(file, id);
return ResponseEntity.ok(saved);
}
+
+ @Operation(summary = "下载种子文件", description = "根据 infoHash 返回对应的 .torrent 文件,支持断点续传")
+ @ApiResponses({
+ @ApiResponse(
+ responseCode = "200",
+ description = "返回 .torrent 文件流",
+ content = @Content(
+ mediaType = "application/x-bittorrent",
+ examples = @ExampleObject(
+ name = "下载文件示例",
+ value = "<二进制流略>"
+ )
+ )
+ ),
+ @ApiResponse(responseCode = "404", description = "未找到对应的种子文件")
+ })
@GetMapping("/download/{infoHash}")
- public ResponseEntity<Resource> downloadTorrent(@PathVariable String infoHash) {
+ public ResponseEntity<Resource> downloadTorrent(
+ @Parameter(description = "种子文件的唯一 infoHash", required = true, example = "207d69a047830000620c586e199fc3424e7e5dd8")
+ @PathVariable String infoHash) {
try {
Resource resource = torrentService.downloadTorrent(infoHash);
return ResponseEntity.ok()
@@ -45,6 +103,35 @@
return ResponseEntity.notFound().build();
}
}
+
+ @Operation(summary = "获取种子列表", description = "查询所有已上传的种子记录,无分页")
+ @ApiResponse(
+ responseCode = "200",
+ description = "返回种子列表",
+ content = @Content(
+ mediaType = "application/json",
+ schema = @Schema(implementation = Torrent[].class),
+ examples = @ExampleObject(
+ name = "列表示例",
+ value = "[\n" +
+ " {\n" +
+ " \"id\": 1,\n" +
+ " \"infoHash\": \"ABCDEF1234567890ABCDEF1234567890ABCDEF12\",\n" +
+ " \"fileName\": \"movie.torrent\",\n" +
+ " \"userId\": 1,\n" +
+ " \"uploadTime\": \"2025-06-07T16:35:12\"\n" +
+ " },\n" +
+ " {\n" +
+ " \"id\": 2,\n" +
+ " \"infoHash\": \"123456ABCDEF123456ABCDEF123456ABCDEF1234\",\n" +
+ " \"fileName\": \"song.torrent\",\n" +
+ " \"userId\": 1,\n" +
+ " \"uploadTime\": \"2025-06-07T17:02:45\"\n" +
+ " }\n" +
+ "]"
+ )
+ )
+ )
@PostMapping("/getTorrentList")
public ResponseEntity<?> getTorrentList() throws Exception {
diff --git a/src/main/java/edu/bjtu/groupone/backend/config/OpenApiConfig.java b/src/main/java/edu/bjtu/groupone/backend/config/OpenApiConfig.java
new file mode 100644
index 0000000..c2e1c74
--- /dev/null
+++ b/src/main/java/edu/bjtu/groupone/backend/config/OpenApiConfig.java
@@ -0,0 +1,25 @@
+package edu.bjtu.groupone.backend.config;
+
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.oas.models.info.Contact;
+import io.swagger.v3.oas.models.info.Info;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class OpenApiConfig {
+
+ @Bean
+ public OpenAPI groupOneOpenAPI() {
+ return new OpenAPI()
+ .info(new Info()
+ .title("GroupOne 后端 API 文档")
+ .description("基于 Springdoc OpenAPI 自动生成")
+ .version("v1.0.0")
+ .contact(new Contact()
+ .name("GroupOne 团队")
+ .email("22301023@bjtu.edu.cn")
+ )
+ );
+ }
+}
diff --git a/src/main/java/edu/bjtu/groupone/backend/domain/entity/Torrent.java b/src/main/java/edu/bjtu/groupone/backend/domain/entity/Torrent.java
index ec9d123..be5af10 100644
--- a/src/main/java/edu/bjtu/groupone/backend/domain/entity/Torrent.java
+++ b/src/main/java/edu/bjtu/groupone/backend/domain/entity/Torrent.java
@@ -2,11 +2,11 @@
import lombok.AllArgsConstructor;
import lombok.Data;
-import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
public class Torrent {
+
private Long id;
private String name;
private String infoHash;
@@ -19,9 +19,7 @@
private String url;
- public Long getId() {
- return this.id;
- }
+ public Long getId() {return this.id;}
public String getName() {
return this.name;