blob: c2562bc68fc5670390b37dc2b75fdbfbab30850c [file] [log] [blame]
Raverf79fdb62025-06-03 06:02:49 +00001package api;
2
3import java.io.File;
4
Raveraae06122025-06-05 08:13:35 +00005import javax.annotation.PostConstruct;
6
Raverf79fdb62025-06-03 06:02:49 +00007import org.springframework.core.io.FileSystemResource;
8import org.springframework.core.io.Resource;
9import org.springframework.http.HttpHeaders;
Raveraae06122025-06-05 08:13:35 +000010import org.springframework.http.HttpStatus;
Raverf79fdb62025-06-03 06:02:49 +000011import org.springframework.http.MediaType;
12import org.springframework.http.ResponseEntity;
13import org.springframework.web.bind.annotation.RequestParam;
14import org.springframework.web.bind.annotation.RestController;
15import org.springframework.web.multipart.MultipartFile;
Raveraae06122025-06-05 08:13:35 +000016import org.springframework.web.bind.annotation.CrossOrigin;
rhjc6a4ee02025-06-06 00:45:18 +080017import org.springframework.web.bind.annotation.RequestBody;
18import org.springframework.web.bind.annotation.PostMapping;
Raveraae06122025-06-05 08:13:35 +000019
20import com.fasterxml.jackson.core.JsonProcessingException;
21import com.fasterxml.jackson.databind.ObjectMapper;
Raverf79fdb62025-06-03 06:02:49 +000022
23import database.Database1;
Raverf79fdb62025-06-03 06:02:49 +000024import tracker.Tracker;
25
rhjc6a4ee02025-06-06 00:45:18 +080026import entity.Seed;
27import entity.User;
rhj46f62c42025-06-06 23:24:10 +080028import entity.Post;
rhj5b69b7e2025-06-07 01:28:08 +080029import entity.PostReply;
rhj5ebd93c2025-06-07 15:57:28 +080030import entity.UserPT;
rhjc6a4ee02025-06-06 00:45:18 +080031
32import java.util.UUID;
Raveraae06122025-06-05 08:13:35 +000033
Raverf79fdb62025-06-03 06:02:49 +000034@RestController
35public class ApiController implements ApiInterface {
36
Raveraae06122025-06-05 08:13:35 +000037 private static Database1 db1;
Raverf79fdb62025-06-03 06:02:49 +000038 private static Tracker tracker;
Raveraae06122025-06-05 08:13:35 +000039 private static ObjectMapper mapper;
rhjc6a4ee02025-06-06 00:45:18 +080040 private static HttpHeaders headers;
41 private static HttpHeaders errorHeaders;
Raveraae06122025-06-05 08:13:35 +000042
43 @PostConstruct
44 public void init() {
45 db1 = new Database1();
46 tracker = new Tracker();
47 mapper = new ObjectMapper();
48 mapper.configure(com.fasterxml.jackson.databind.SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
rhjc6a4ee02025-06-06 00:45:18 +080049 headers = new HttpHeaders();
50 headers.add("Access-Control-Allow-Origin", "*");
51 headers.add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
52 headers.add("Access-Control-Allow-Headers", "Content-Type, Authorization");
53 errorHeaders = new HttpHeaders();
54 errorHeaders.add("Access-Control-Allow-Origin", "*");
55 errorHeaders.add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
56 errorHeaders.add("Access-Control-Allow-Headers", "Content-Type, Authorization");
Raveraae06122025-06-05 08:13:35 +000057 }
Raverf79fdb62025-06-03 06:02:49 +000058
59 @Override
60 public ResponseEntity<Integer> saveTorrent(
61 @RequestParam("userid") String userid,
62 @RequestParam("title") String title,
63 @RequestParam("tag") String tag,
64 @RequestParam("file") MultipartFile file
65 ) {
66 try {
67 Seed seed = new Seed();
rhjc6a4ee02025-06-06 00:45:18 +080068 seed.seedid = UUID.randomUUID().toString(); // 生成唯一的种子ID
69 seed.seeduserid = userid;
70 seed.title = title;
71 seed.seedsize = "1GB";
72 seed.seedtag = tag;
Raverf79fdb62025-06-03 06:02:49 +000073 seed.url = "http://example.com/torrent"; // 示例URL
rhjc6a4ee02025-06-06 00:45:18 +080074 System.out.println("seed is null? " + (seed == null));
Raveraae06122025-06-05 08:13:35 +000075 int ret = db1.RegisterSeed(seed);
rhjc6a4ee02025-06-06 00:45:18 +080076 if (ret != 0) {
77 // 如果注册种子失败,返回错误状态
78 return new ResponseEntity<>(ret, headers, HttpStatus.INTERNAL_SERVER_ERROR);
79 }
Raverf79fdb62025-06-03 06:02:49 +000080 File tempFile = File.createTempFile(seed.seedid, file.getOriginalFilename());
81 file.transferTo(tempFile);
82 tracker.SaveTorrent(seed.seedid, tempFile);
Raveraae06122025-06-05 08:13:35 +000083 return new ResponseEntity<>(0, headers, HttpStatus.OK); // 返回 0 表示成功
Raverf79fdb62025-06-03 06:02:49 +000084 } catch (Exception e) {
85 e.printStackTrace();
Raveraae06122025-06-05 08:13:35 +000086 return new ResponseEntity<>(1, errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR); // 返回 1 表示失败
Raverf79fdb62025-06-03 06:02:49 +000087 }
88 }
89
90 @Override
Raveraae06122025-06-05 08:13:35 +000091 @CrossOrigin(origins = "*", allowedHeaders = "*") // 允许所有来源和头部
Raverf79fdb62025-06-03 06:02:49 +000092 public ResponseEntity<Resource> getTorrent(
rhjc6a4ee02025-06-06 00:45:18 +080093 @RequestParam("torrentId") String seedid,
94 @RequestParam("userId") String userid
Raverf79fdb62025-06-03 06:02:49 +000095 ) {
Raveraae06122025-06-05 08:13:35 +000096 File file = tracker.GetTTorent(seedid, userid);
Raverf79fdb62025-06-03 06:02:49 +000097 if (file != null) {
98 FileSystemResource resource = new FileSystemResource(file);
99 return ResponseEntity.ok()
100 .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + file.getName() + "\"")
Raveraae06122025-06-05 08:13:35 +0000101 .header(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, HttpHeaders.CONTENT_DISPOSITION) // 关键:允许前端访问Content-Disposition
Raverf79fdb62025-06-03 06:02:49 +0000102 .contentType(MediaType.APPLICATION_OCTET_STREAM)
103 .body(resource);
104 } else {
Raveraae06122025-06-05 08:13:35 +0000105 return ResponseEntity.notFound().build();
106 }
107 }
108
Raveraae06122025-06-05 08:13:35 +0000109 @Override
110 public ResponseEntity<String> getSeedListByTag(
111 @RequestParam("tag") String tag
112 ) {
113 try {
114 Seed[] seeds = db1.GetSeedListByTag(tag);
rhjc6a4ee02025-06-06 00:45:18 +0800115 if (seeds == null || seeds.length == 0) {
116 return new ResponseEntity<>("[]", errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR); // 返回 404 表示未找到种子
117 }
Raveraae06122025-06-05 08:13:35 +0000118 String json = mapper.writeValueAsString(seeds);
Raveraae06122025-06-05 08:13:35 +0000119 return new ResponseEntity<>(json, headers, HttpStatus.OK);
120 } catch (JsonProcessingException e) {
121 e.printStackTrace();
Raveraae06122025-06-05 08:13:35 +0000122 return new ResponseEntity<>("[]", errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR);
123 }
124 }
125
126 @Override
rhjc6a4ee02025-06-06 00:45:18 +0800127 public ResponseEntity<String> getUserProfile(
128 @RequestParam("userid") String userid
129 ) {
130 try {
131 User user = db1.GetInformation(userid);
132 if (user == null) {
133 return new ResponseEntity<>("", errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR);
134 }
135 String json = mapper.writeValueAsString(user);
136 return new ResponseEntity<>(json, headers, HttpStatus.OK);
137 } catch (JsonProcessingException e) {
138 e.printStackTrace();
139 return new ResponseEntity<>("", errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR);
140 }
141 }
142
143 @Override
144 @CrossOrigin(origins = "*", allowedHeaders = "*")
145 public ResponseEntity<Integer> changeProfile(
146 @RequestBody String requestBody
147 ) {
148 try {
149 // 解析 JSON 数据
150 com.fasterxml.jackson.databind.JsonNode jsonNode = mapper.readTree(requestBody);
151
152 // 安全地获取 userid 字段
153 com.fasterxml.jackson.databind.JsonNode useridNode = jsonNode.get("userid");
154 if (useridNode == null) {
155 return new ResponseEntity<>(1, HttpStatus.BAD_REQUEST);
156 }
157 String userid = useridNode.asText();
158
159 // 添加参数验证
160 if (userid == null || userid.trim().isEmpty()) {
161 return new ResponseEntity<>(1, HttpStatus.BAD_REQUEST);
162 }
163
164 // 手动映射前端字段到 User 对象,处理类型转换
165 User user = new User();
166 user.userid = userid;
167
168 // 安全地获取其他字段并进行类型转换
169 if (jsonNode.has("username") && !jsonNode.get("username").isNull()) {
170 user.username = jsonNode.get("username").asText();
171 }
172 if (jsonNode.has("school") && !jsonNode.get("school").isNull()) {
173 user.school = jsonNode.get("school").asText();
174 }
175 if (jsonNode.has("gender") && !jsonNode.get("gender").isNull()) {
176 user.sex = jsonNode.get("gender").asText();
177 }
178 if (jsonNode.has("avatar_url") && !jsonNode.get("avatar_url").isNull()) {
179 user.pictureurl = jsonNode.get("avatar_url").asText();
180 }
181
182 // 处理 account_status 的类型转换(字符串/数字 -> 布尔值)
183 if (jsonNode.has("account_status") && !jsonNode.get("account_status").isNull()) {
184 com.fasterxml.jackson.databind.JsonNode statusNode = jsonNode.get("account_status");
185 if (statusNode.isTextual()) {
186 String statusStr = statusNode.asText();
187 user.accountstate = "1".equals(statusStr) || "封禁".equals(statusStr);
188 } else if (statusNode.isNumber()) {
189 user.accountstate = statusNode.asInt() == 1;
190 } else if (statusNode.isBoolean()) {
191 user.accountstate = statusNode.asBoolean();
192 }
193 }
194
195 // 处理 invite_left 的类型转换(字符串 -> 整数)
196 if (jsonNode.has("invite_left") && !jsonNode.get("invite_left").isNull()) {
197 com.fasterxml.jackson.databind.JsonNode inviteNode = jsonNode.get("invite_left");
198 if (inviteNode.isTextual()) {
199 try {
200 user.invitetimes = Integer.parseInt(inviteNode.asText());
201 } catch (NumberFormatException e) {
202 user.invitetimes = 0; // 默认值
203 }
204 } else if (inviteNode.isNumber()) {
205 user.invitetimes = inviteNode.asInt();
206 }
207 }
208
209 int ret = db1.UpdateInformation(user);
210 if (ret == 0) {
211 return new ResponseEntity<>(0, HttpStatus.OK); // 返回 0 表示成功
212 } else {
213 return new ResponseEntity<>(ret, HttpStatus.INTERNAL_SERVER_ERROR); // 返回其他状态表示失败
214 }
215 } catch (JsonProcessingException e) {
216 e.printStackTrace();
217 return new ResponseEntity<>(1, HttpStatus.INTERNAL_SERVER_ERROR); // 返回 1 表示处理失败
218 } catch (Exception e) {
219 e.printStackTrace();
220 return new ResponseEntity<>(1, HttpStatus.INTERNAL_SERVER_ERROR);
221 }
222 }
223
224 @Override
225 public ResponseEntity<String> getUserSeeds(
226 @RequestParam("userid") String userid
227 ) {
228 try {
229 Seed[] seeds = db1.GetSeedListByUser(userid);
230 if (seeds == null || seeds.length == 0) {
231 return new ResponseEntity<>("[]", errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR); // 返回 404 表示未找到种子
232 }
233 String json = mapper.writeValueAsString(seeds);
234 return new ResponseEntity<>(json, headers, HttpStatus.OK);
235 } catch (JsonProcessingException e) {
236 e.printStackTrace();
237 return new ResponseEntity<>("[]", errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR);
238 }
239 }
240
241 @Override
242 @CrossOrigin(origins = "*", allowedHeaders = "*")
243 public ResponseEntity<Integer> deleteSeed(
244 @RequestBody String requestBody
245 ) {
246 try {
247 // 解析 JSON 数据
248 com.fasterxml.jackson.databind.JsonNode jsonNode = mapper.readTree(requestBody);
249 com.fasterxml.jackson.databind.JsonNode seedidNode = jsonNode.get("seedid");
250 if (seedidNode == null) {
251 return new ResponseEntity<>(1, HttpStatus.BAD_REQUEST);
252 }
253 String seedid = seedidNode.asText();
254
255 // 添加参数验证
256 if (seedid == null || seedid.trim().isEmpty()) {
257 return new ResponseEntity<>(1, HttpStatus.BAD_REQUEST);
258 }
259
260 int ret = db1.DeleteSeed(seedid);
261 if (ret == 0) {
262 return new ResponseEntity<>(0, HttpStatus.OK);
263 } else {
264 return new ResponseEntity<>(ret, HttpStatus.INTERNAL_SERVER_ERROR);
265 }
266 } catch (Exception e) {
267 e.printStackTrace();
268 return new ResponseEntity<>(1, HttpStatus.INTERNAL_SERVER_ERROR);
269 }
270 }
271
272 @Override
273 public ResponseEntity<String> getUserStat(
274 @RequestParam("userid") String userid
275 ) {
276 try {
277 User user = db1.GetInformation(userid);
278 if (user == null) {
279 return new ResponseEntity<>("", errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR);
280 }
281 String json = mapper.writeValueAsString(user);
282 return new ResponseEntity<>(json, headers, HttpStatus.OK);
283 } catch (JsonProcessingException e) {
284 e.printStackTrace();
285 return new ResponseEntity<>("", errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR);
286 }
287 }
288
289 @Override
Raveraae06122025-06-05 08:13:35 +0000290 public ResponseEntity<String> getTorrentDetail(
291 @RequestParam("id") String seedid
292 ) {
293 try {
294 Seed seed = db1.GetSeedInformation(seedid);
295 if (seed != null) {
296 String json = mapper.writeValueAsString(seed);
297 HttpHeaders headers = new HttpHeaders();
298 headers.add("Access-Control-Allow-Origin", "*");
299 headers.add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
300 headers.add("Access-Control-Allow-Headers", "Content-Type, Authorization");
301 return new ResponseEntity<>(json, headers, HttpStatus.OK);
302 } else {
303 return ResponseEntity.notFound().build(); // 返回 404 表示种子未找到
304 }
305 } catch (JsonProcessingException e) {
306 e.printStackTrace();
307 HttpHeaders errorHeaders = new HttpHeaders();
308 errorHeaders.add("Access-Control-Allow-Origin", "*");
309 errorHeaders.add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
310 errorHeaders.add("Access-Control-Allow-Headers", "Content-Type, Authorization");
311 return new ResponseEntity<>("{}", errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR);
Raverf79fdb62025-06-03 06:02:49 +0000312 }
313 }
rhj46f62c42025-06-06 23:24:10 +0800314
315 @Override
316 @CrossOrigin(origins = "*", allowedHeaders = "*")
317 public ResponseEntity<String> loginUser(
318 @RequestBody String requestBody
319 ) {
320 try {
321 // 解析前端发送的JSON数据 {email: xxx, password: xxx}
322 com.fasterxml.jackson.databind.JsonNode jsonNode = mapper.readTree(requestBody);
323
324 // 获取email和password字段
325 com.fasterxml.jackson.databind.JsonNode emailNode = jsonNode.get("email");
326 com.fasterxml.jackson.databind.JsonNode passwordNode = jsonNode.get("password");
327
328 if (emailNode == null || passwordNode == null) {
329 com.fasterxml.jackson.databind.node.ObjectNode errorJson = mapper.createObjectNode();
330 errorJson.put("message", "缺少必要参数");
331 String jsonError = mapper.writeValueAsString(errorJson);
332 return new ResponseEntity<>(jsonError, HttpStatus.BAD_REQUEST);
333 }
334
335 String email = emailNode.asText();
336 String password = passwordNode.asText();
337
338 // 参数验证
339 if (email == null || email.trim().isEmpty() ||
340 password == null || password.trim().isEmpty()) {
341 com.fasterxml.jackson.databind.node.ObjectNode errorJson = mapper.createObjectNode();
342 errorJson.put("message", "邮箱和密码不能为空");
343 String jsonError = mapper.writeValueAsString(errorJson);
344 return new ResponseEntity<>(jsonError, HttpStatus.BAD_REQUEST);
345 }
346
347 // 创建User对象进行登录验证
348 User user = new User();
349 user.email = email.trim();
350 user.password = password;
351
352 String userid = db1.LoginUser(user);
353 if (userid != null) {
354 com.fasterxml.jackson.databind.node.ObjectNode responseJson = mapper.createObjectNode();
355 responseJson.put("userId", userid);
356 responseJson.put("userid", userid);
357 responseJson.put("message", "登录成功");
358 String jsonResponse = mapper.writeValueAsString(responseJson);
359 return new ResponseEntity<>(jsonResponse, HttpStatus.OK);
360 } else {
361 // 返回JSON格式的错误信息
362 com.fasterxml.jackson.databind.node.ObjectNode errorJson = mapper.createObjectNode();
363 errorJson.put("message", "登录失败,请检查账号密码");
364 String jsonError = mapper.writeValueAsString(errorJson);
365 return new ResponseEntity<>(jsonError, HttpStatus.UNAUTHORIZED);
366 }
367 } catch (JsonProcessingException e) {
368 e.printStackTrace();
369 com.fasterxml.jackson.databind.node.ObjectNode errorJson = mapper.createObjectNode();
370 try {
371 errorJson.put("message", "服务器内部错误");
372 String jsonError = mapper.writeValueAsString(errorJson);
373 return new ResponseEntity<>(jsonError, HttpStatus.INTERNAL_SERVER_ERROR);
374 } catch (JsonProcessingException ex) {
375 return new ResponseEntity<>("{\"message\":\"服务器内部错误\"}", HttpStatus.INTERNAL_SERVER_ERROR);
376 }
377 } catch (Exception e) {
378 e.printStackTrace();
379 com.fasterxml.jackson.databind.node.ObjectNode errorJson = mapper.createObjectNode();
380 try {
381 errorJson.put("message", "服务器内部错误");
382 String jsonError = mapper.writeValueAsString(errorJson);
383 return new ResponseEntity<>(jsonError, HttpStatus.INTERNAL_SERVER_ERROR);
384 } catch (JsonProcessingException ex) {
385 return new ResponseEntity<>("{\"message\":\"服务器内部错误\"}", HttpStatus.INTERNAL_SERVER_ERROR);
386 }
387 }
388 }
389
390 @Override
391 @CrossOrigin(origins = "*", allowedHeaders = "*")
392 public ResponseEntity<Integer> registerUser(
393 @RequestBody String requestBody
394 ) {
395 try {
396 System.out.println("Register request body: " + requestBody);
397 // 解析 JSON 数据
398 com.fasterxml.jackson.databind.JsonNode jsonNode = mapper.readTree(requestBody);
399
400 // 安全地获取字段
401 com.fasterxml.jackson.databind.JsonNode usernameNode = jsonNode.get("username");
402 com.fasterxml.jackson.databind.JsonNode passwordNode = jsonNode.get("password");
403 com.fasterxml.jackson.databind.JsonNode inviteEmailNode = jsonNode.get("invite_email");
404
405 if (usernameNode == null || passwordNode == null || inviteEmailNode == null) {
406 return new ResponseEntity<>(2, HttpStatus.BAD_REQUEST); // 参数不完整
407 }
408
409 String username = usernameNode.asText();
410 String password = passwordNode.asText();
411 String inviteEmail = inviteEmailNode.asText();
412
413 // 参数验证
414 if (username == null || username.trim().isEmpty() ||
415 password == null || password.trim().isEmpty() ||
416 inviteEmail == null || inviteEmail.trim().isEmpty()) {
417 return new ResponseEntity<>(2, HttpStatus.BAD_REQUEST);
418 }
419
420 // 创建 User 对象
421 User user = new User();
422 user.userid = java.util.UUID.randomUUID().toString(); // 生成唯一用户ID
423 user.username = username.trim();
424 user.password = password;
425 user.email = inviteEmail.trim(); // 使用邀请邮箱作为用户邮箱
426
427 // 设置默认值
428 user.sex = "m"; // 默认性别
429 user.school = ""; // 默认学校
430 user.pictureurl = ""; // 默认头像URL
431 user.profile = ""; // 默认个人简介
432 user.accountstate = false; // 默认账号状态为正常
433 user.invitetimes = 5; // 默认邀请次数
434
435 // 设置时间字段
436 user.lastDetectedTime = new java.util.Date();
437 user.fakeLastDetectedTime = new java.util.Date();
438
439 // 调用数据库注册方法
440 int ret = db1.RegisterUser(user);
441 System.out.println("Register result: " + ret);
442
443 // // 如果注册成功,还需要创建对应的 UserPT 记录
444 // if (ret == 0) {
445 // try {
446 // entity.UserPT userPT = new entity.UserPT();
447 // userPT.userid = user.userid;
448 // userPT.magic = 100; // 初始魔力值
449 // userPT.upload = 0L; // 初始上传量
450 // userPT.download = 0L; // 初始下载量
451 // userPT.share = 0.0; // 初始分享率
452 // userPT.farmurl = ""; // 默认做种路径
453 // userPT.viptime = 0; // 初始VIP次数
454 // userPT.user = user; // 设置关联
455
456 // int ptRet = db1.RegisterUserPT(userPT);
457 // if (ptRet != 0) {
458 // // 如果 UserPT 创建失败,记录日志但不影响主要注册流程
459 // System.err.println("Warning: Failed to create UserPT for user " + user.userid);
460 // }
461 // } catch (Exception e) {
462 // System.err.println("Warning: Exception creating UserPT: " + e.getMessage());
463 // }
464 // }
465
466 if (ret == 0) {
467 return new ResponseEntity<>(0, HttpStatus.OK); // 返回 0 表示注册成功
468 } else if (ret == 1) {
469 return new ResponseEntity<>(1, HttpStatus.CONFLICT); // 返回 1 表示邮箱重复
470 } else {
471 return new ResponseEntity<>(ret, HttpStatus.BAD_REQUEST); // 返回 2 表示未被邀请或其他错误
472 }
473 } catch (JsonProcessingException e) {
474 e.printStackTrace();
475 return new ResponseEntity<>(2, HttpStatus.INTERNAL_SERVER_ERROR); // 返回 2 表示处理失败
476 } catch (Exception e) {
477 e.printStackTrace();
478 return new ResponseEntity<>(2, HttpStatus.INTERNAL_SERVER_ERROR);
479 }
480 }
481
482 @Override
rhj5b69b7e2025-06-07 01:28:08 +0800483 @CrossOrigin(origins = "*", allowedHeaders = "*")
rhj46f62c42025-06-06 23:24:10 +0800484 public ResponseEntity<String> getForum() {
485 try {
486 Post[] posts = db1.GetPostList();
487 if (posts == null || posts.length == 0) {
488 return new ResponseEntity<>("[]", HttpStatus.OK); // 返回空数组表示没有帖子
489 }
490 String json = mapper.writeValueAsString(posts);
491 return new ResponseEntity<>(json, HttpStatus.OK);
492 } catch (JsonProcessingException e) {
493 e.printStackTrace();
494 return new ResponseEntity<>("[]", HttpStatus.INTERNAL_SERVER_ERROR);
495 } catch (Exception e) {
496 e.printStackTrace();
497 return new ResponseEntity<>("[]", HttpStatus.INTERNAL_SERVER_ERROR);
498 }
499 }
rhj5b69b7e2025-06-07 01:28:08 +0800500
501 @Override
502 @CrossOrigin(origins = "*", allowedHeaders = "*")
503 public ResponseEntity<String> getPostById(
504 @RequestParam("postid") String postid
505 ) {
506 try {
507 Post post = db1.GetPost(postid);
508 PostReply[] replies = db1.GetPostReplyList(postid);
509 if (post == null) {
510 return new ResponseEntity<>("", HttpStatus.NOT_FOUND); // 返回 404 表示帖子未找到
511 }
512
513 // 创建合并的 JSON 对象
514 com.fasterxml.jackson.databind.node.ObjectNode resultJson = mapper.createObjectNode();
515
516 // 添加 post 的所有字段
517 resultJson.put("postid", post.postid);
518 resultJson.put("posttitle", post.posttitle);
519 resultJson.put("postcontent", post.postcontent);
520 resultJson.put("postuserid", post.postuserid);
521 resultJson.put("replytime", post.replytime);
522 resultJson.put("readtime", post.readtime);
523
524 if (post.posttime != null) {
525 resultJson.put("posttime", post.posttime.getTime());
526 }
527
528 // 添加作者信息
529 if (post.author != null) {
530 com.fasterxml.jackson.databind.node.ObjectNode authorJson = mapper.createObjectNode();
531 authorJson.put("userid", post.author.userid);
532 authorJson.put("username", post.author.username);
533 authorJson.put("email", post.author.email);
534 authorJson.put("sex", post.author.sex);
535 authorJson.put("school", post.author.school);
536 authorJson.put("pictureurl", post.author.pictureurl);
537 authorJson.put("profile", post.author.profile);
538 authorJson.put("accountstate", post.author.accountstate);
539 authorJson.put("invitetimes", post.author.invitetimes);
540 if (post.author.lastDetectedTime != null) {
541 authorJson.put("lastDetectedTime", post.author.lastDetectedTime.getTime());
542 }
543 if (post.author.fakeLastDetectedTime != null) {
544 authorJson.put("fakeLastDetectedTime", post.author.fakeLastDetectedTime.getTime());
545 }
546 resultJson.set("author", authorJson);
547 }
548
549 // 添加 replies 数组
550 com.fasterxml.jackson.databind.node.ArrayNode repliesArray = mapper.createArrayNode();
551 if (replies != null) {
rhj5b69b7e2025-06-07 01:28:08 +0800552 for (PostReply reply : replies) {
553 com.fasterxml.jackson.databind.node.ObjectNode replyJson = mapper.createObjectNode();
554 replyJson.put("replyid", reply.replyid);
555 replyJson.put("postid", reply.postid);
556 replyJson.put("authorid", reply.authorid);
557 replyJson.put("content", reply.content);
558 if (reply.createdAt != null) {
559 replyJson.put("createdAt", reply.createdAt.getTime());
560 }
561
562 // 添加回复作者信息
563 if (reply.author != null) {
564 com.fasterxml.jackson.databind.node.ObjectNode replyAuthorJson = mapper.createObjectNode();
565 replyAuthorJson.put("userid", reply.author.userid);
566 replyAuthorJson.put("username", reply.author.username);
567 replyAuthorJson.put("email", reply.author.email);
568 replyAuthorJson.put("sex", reply.author.sex);
569 replyAuthorJson.put("school", reply.author.school);
570 replyAuthorJson.put("pictureurl", reply.author.pictureurl);
571 replyAuthorJson.put("profile", reply.author.profile);
572 replyAuthorJson.put("accountstate", reply.author.accountstate);
573 replyAuthorJson.put("invitetimes", reply.author.invitetimes);
574 if (reply.author.lastDetectedTime != null) {
575 replyAuthorJson.put("lastDetectedTime", reply.author.lastDetectedTime.getTime());
576 }
577 if (reply.author.fakeLastDetectedTime != null) {
578 replyAuthorJson.put("fakeLastDetectedTime", reply.author.fakeLastDetectedTime.getTime());
579 }
580 replyJson.set("author", replyAuthorJson);
581 }
582
583 repliesArray.add(replyJson);
584 }
585 }
586 resultJson.set("replies", repliesArray);
587
588 String json = mapper.writeValueAsString(resultJson);
589 return new ResponseEntity<>(json, HttpStatus.OK);
590 } catch (JsonProcessingException e) {
591 // e.printStackTrace();
592 return new ResponseEntity<>("", HttpStatus.INTERNAL_SERVER_ERROR);
593 } catch (Exception e) {
594 // e.printStackTrace();
595 return new ResponseEntity<>("", HttpStatus.INTERNAL_SERVER_ERROR);
596 }
597 }
598
599 @Override
600 @CrossOrigin(origins = "*", allowedHeaders = "*")
601 public ResponseEntity<Integer> addPostReply(
602 @RequestBody String requestBody
603 ) {
604 try {
rhj5b69b7e2025-06-07 01:28:08 +0800605 // 解析 JSON 数据
606 com.fasterxml.jackson.databind.JsonNode jsonNode = mapper.readTree(requestBody);
607 com.fasterxml.jackson.databind.JsonNode postidNode = jsonNode.get("postid");
608 com.fasterxml.jackson.databind.JsonNode authoridNode = jsonNode.get("replyuserid");
609 com.fasterxml.jackson.databind.JsonNode contentNode = jsonNode.get("replycontent");
610
611 if (postidNode == null || authoridNode == null || contentNode == null) {
612 return new ResponseEntity<>(1, HttpStatus.BAD_REQUEST); // 参数不完整
613 }
614
615 String postid = postidNode.asText();
616 String authorid = authoridNode.asText();
617 String content = contentNode.asText();
618
rhj5b69b7e2025-06-07 01:28:08 +0800619 // 参数验证
620 if (postid == null || postid.trim().isEmpty() ||
621 authorid == null || authorid.trim().isEmpty() ||
622 content == null || content.trim().isEmpty()) {
623 return new ResponseEntity<>(1, HttpStatus.BAD_REQUEST);
624 }
625
626 int ret = db1.AddComment(postid, authorid, content);
rhj5b69b7e2025-06-07 01:28:08 +0800627 if (ret == 0) {
628 return new ResponseEntity<>(0, HttpStatus.OK); // 返回 0 表示成功
629 } else {
630 return new ResponseEntity<>(ret, HttpStatus.INTERNAL_SERVER_ERROR); // 返回其他状态表示失败
631 }
632 } catch (JsonProcessingException e) {
633 e.printStackTrace();
634 return new ResponseEntity<>(1, HttpStatus.INTERNAL_SERVER_ERROR); // 返回 1 表示处理失败
635 } catch (Exception e) {
636 e.printStackTrace();
637 return new ResponseEntity<>(1, HttpStatus.INTERNAL_SERVER_ERROR);
638 }
639 }
640
641 @Override
642 public ResponseEntity<String> searchSeeds(
643 @RequestParam("tag") String tag,
644 @RequestParam("keyword") String query
645 ) {
rhj5ebd93c2025-06-07 15:57:28 +0800646 try {
647 Seed[] seeds = db1.SearchSeed(query);
648 if (seeds == null || seeds.length == 0) {
649 return new ResponseEntity<>("[]", errorHeaders, HttpStatus.NOT_FOUND); // 返回 404 表示未找到种子
650 }
651
652 // 过滤掉与前端要求tag不同的种子
653 java.util.List<Seed> filteredSeeds = new java.util.ArrayList<>();
654 for (Seed seed : seeds) {
655 if (seed.seedtag != null && seed.seedtag.equals(tag)) {
656 filteredSeeds.add(seed);
657 }
658 }
659
660 // 如果过滤后没有匹配的种子,返回空数组
661 if (filteredSeeds.isEmpty()) {
662 return new ResponseEntity<>("[]", errorHeaders, HttpStatus.NOT_FOUND);
663 }
664
665 Seed[] filteredSeedsArray = filteredSeeds.toArray(new Seed[0]);
666 String json = mapper.writeValueAsString(filteredSeedsArray);
667 return new ResponseEntity<>(json, headers, HttpStatus.OK);
668 } catch (JsonProcessingException e) {
669 e.printStackTrace();
670 return new ResponseEntity<>("[]", errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR);
671 } catch (Exception e) {
672 e.printStackTrace();
673 return new ResponseEntity<>("[]", errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR);
674 }
675 }
676
677 @Override
678 public ResponseEntity<String> searchPosts(
679 @RequestParam("keyword") String query
680 ) {
681 try {
682 Post[] posts = db1.SearchPost(query);
683 if (posts == null || posts.length == 0) {
684 return new ResponseEntity<>("[]", errorHeaders, HttpStatus.NOT_FOUND); // 返回 404 表示未找到帖子
685 }
686 String json = mapper.writeValueAsString(posts);
687 return new ResponseEntity<>(json, headers, HttpStatus.OK);
688 } catch (JsonProcessingException e) {
689 e.printStackTrace();
690 return new ResponseEntity<>("[]", errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR);
691 } catch (Exception e) {
692 e.printStackTrace();
693 return new ResponseEntity<>("[]", errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR);
694 }
695 }
696
697 @Override
698 public ResponseEntity<String> getUserPT(
699 @RequestParam("userid") String userid
700 ) {
701 try {
702 UserPT userPT = db1.GetInformationPT(userid);
703 if (userPT == null) {
704 return new ResponseEntity<>("", errorHeaders, HttpStatus.NOT_FOUND); // 返回 404 表示未找到用户PT信息
705 }
706 String json = mapper.writeValueAsString(userPT);
707 return new ResponseEntity<>(json, headers, HttpStatus.OK);
708 } catch (JsonProcessingException e) {
709 e.printStackTrace();
710 return new ResponseEntity<>("", errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR);
711 } catch (Exception e) {
712 e.printStackTrace();
713 return new ResponseEntity<>("", errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR);
714 }
rhj5b69b7e2025-06-07 01:28:08 +0800715 }
Raverf79fdb62025-06-03 06:02:49 +0000716}