blob: b8ee0c1cbf8a37630b63ecbf42f9076435a9fd1b [file] [log] [blame]
package api;
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 org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.PostMapping;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import database.Database1;
import tracker.Tracker;
import entity.Seed;
import entity.User;
import entity.Post;
import java.util.UUID;
@RestController
public class ApiController implements ApiInterface {
private static Database1 db1;
private static Tracker tracker;
private static ObjectMapper mapper;
private static HttpHeaders headers;
private static HttpHeaders errorHeaders;
@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);
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");
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");
}
@Override
public ResponseEntity<Integer> saveTorrent(
@RequestParam("userid") String userid,
@RequestParam("title") String title,
@RequestParam("tag") String tag,
@RequestParam("file") MultipartFile file
) {
try {
Seed seed = new Seed();
seed.seedid = UUID.randomUUID().toString(); // 生成唯一的种子ID
seed.seeduserid = userid;
seed.title = title;
seed.seedsize = "1GB";
seed.seedtag = tag;
seed.url = "http://example.com/torrent"; // 示例URL
System.out.println("seed is null? " + (seed == null));
int ret = db1.RegisterSeed(seed);
if (ret != 0) {
// 如果注册种子失败,返回错误状态
return new ResponseEntity<>(ret, headers, HttpStatus.INTERNAL_SERVER_ERROR);
}
File tempFile = File.createTempFile(seed.seedid, file.getOriginalFilename());
file.transferTo(tempFile);
tracker.SaveTorrent(seed.seedid, tempFile);
return new ResponseEntity<>(0, headers, HttpStatus.OK); // 返回 0 表示成功
} catch (Exception e) {
e.printStackTrace();
return new ResponseEntity<>(1, errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR); // 返回 1 表示失败
}
}
@Override
@CrossOrigin(origins = "*", allowedHeaders = "*") // 允许所有来源和头部
public ResponseEntity<Resource> getTorrent(
@RequestParam("torrentId") String seedid,
@RequestParam("userId") String userid
) {
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();
}
}
@Override
public ResponseEntity<String> getSeedListByTag(
@RequestParam("tag") String tag
) {
try {
Seed[] seeds = db1.GetSeedListByTag(tag);
if (seeds == null || seeds.length == 0) {
return new ResponseEntity<>("[]", errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR); // 返回 404 表示未找到种子
}
String json = mapper.writeValueAsString(seeds);
return new ResponseEntity<>(json, headers, HttpStatus.OK);
} catch (JsonProcessingException e) {
e.printStackTrace();
return new ResponseEntity<>("[]", errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@Override
public ResponseEntity<String> getUserProfile(
@RequestParam("userid") String userid
) {
try {
User user = db1.GetInformation(userid);
if (user == null) {
return new ResponseEntity<>("", errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR);
}
String json = mapper.writeValueAsString(user);
return new ResponseEntity<>(json, headers, HttpStatus.OK);
} catch (JsonProcessingException e) {
e.printStackTrace();
return new ResponseEntity<>("", errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@Override
@CrossOrigin(origins = "*", allowedHeaders = "*")
public ResponseEntity<Integer> changeProfile(
@RequestBody String requestBody
) {
try {
// 解析 JSON 数据
com.fasterxml.jackson.databind.JsonNode jsonNode = mapper.readTree(requestBody);
// 安全地获取 userid 字段
com.fasterxml.jackson.databind.JsonNode useridNode = jsonNode.get("userid");
if (useridNode == null) {
return new ResponseEntity<>(1, HttpStatus.BAD_REQUEST);
}
String userid = useridNode.asText();
// 添加参数验证
if (userid == null || userid.trim().isEmpty()) {
return new ResponseEntity<>(1, HttpStatus.BAD_REQUEST);
}
// 手动映射前端字段到 User 对象,处理类型转换
User user = new User();
user.userid = userid;
// 安全地获取其他字段并进行类型转换
if (jsonNode.has("username") && !jsonNode.get("username").isNull()) {
user.username = jsonNode.get("username").asText();
}
if (jsonNode.has("school") && !jsonNode.get("school").isNull()) {
user.school = jsonNode.get("school").asText();
}
if (jsonNode.has("gender") && !jsonNode.get("gender").isNull()) {
user.sex = jsonNode.get("gender").asText();
}
if (jsonNode.has("avatar_url") && !jsonNode.get("avatar_url").isNull()) {
user.pictureurl = jsonNode.get("avatar_url").asText();
}
// 处理 account_status 的类型转换(字符串/数字 -> 布尔值)
if (jsonNode.has("account_status") && !jsonNode.get("account_status").isNull()) {
com.fasterxml.jackson.databind.JsonNode statusNode = jsonNode.get("account_status");
if (statusNode.isTextual()) {
String statusStr = statusNode.asText();
user.accountstate = "1".equals(statusStr) || "封禁".equals(statusStr);
} else if (statusNode.isNumber()) {
user.accountstate = statusNode.asInt() == 1;
} else if (statusNode.isBoolean()) {
user.accountstate = statusNode.asBoolean();
}
}
// 处理 invite_left 的类型转换(字符串 -> 整数)
if (jsonNode.has("invite_left") && !jsonNode.get("invite_left").isNull()) {
com.fasterxml.jackson.databind.JsonNode inviteNode = jsonNode.get("invite_left");
if (inviteNode.isTextual()) {
try {
user.invitetimes = Integer.parseInt(inviteNode.asText());
} catch (NumberFormatException e) {
user.invitetimes = 0; // 默认值
}
} else if (inviteNode.isNumber()) {
user.invitetimes = inviteNode.asInt();
}
}
int ret = db1.UpdateInformation(user);
if (ret == 0) {
return new ResponseEntity<>(0, HttpStatus.OK); // 返回 0 表示成功
} else {
return new ResponseEntity<>(ret, HttpStatus.INTERNAL_SERVER_ERROR); // 返回其他状态表示失败
}
} catch (JsonProcessingException e) {
e.printStackTrace();
return new ResponseEntity<>(1, HttpStatus.INTERNAL_SERVER_ERROR); // 返回 1 表示处理失败
} catch (Exception e) {
e.printStackTrace();
return new ResponseEntity<>(1, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@Override
public ResponseEntity<String> getUserSeeds(
@RequestParam("userid") String userid
) {
try {
Seed[] seeds = db1.GetSeedListByUser(userid);
if (seeds == null || seeds.length == 0) {
return new ResponseEntity<>("[]", errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR); // 返回 404 表示未找到种子
}
String json = mapper.writeValueAsString(seeds);
return new ResponseEntity<>(json, headers, HttpStatus.OK);
} catch (JsonProcessingException e) {
e.printStackTrace();
return new ResponseEntity<>("[]", errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@Override
@CrossOrigin(origins = "*", allowedHeaders = "*")
public ResponseEntity<Integer> deleteSeed(
@RequestBody String requestBody
) {
try {
// 解析 JSON 数据
com.fasterxml.jackson.databind.JsonNode jsonNode = mapper.readTree(requestBody);
com.fasterxml.jackson.databind.JsonNode seedidNode = jsonNode.get("seedid");
if (seedidNode == null) {
return new ResponseEntity<>(1, HttpStatus.BAD_REQUEST);
}
String seedid = seedidNode.asText();
// 添加参数验证
if (seedid == null || seedid.trim().isEmpty()) {
return new ResponseEntity<>(1, HttpStatus.BAD_REQUEST);
}
int ret = db1.DeleteSeed(seedid);
if (ret == 0) {
return new ResponseEntity<>(0, HttpStatus.OK);
} else {
return new ResponseEntity<>(ret, HttpStatus.INTERNAL_SERVER_ERROR);
}
} catch (Exception e) {
e.printStackTrace();
return new ResponseEntity<>(1, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@Override
public ResponseEntity<String> getUserStat(
@RequestParam("userid") String userid
) {
try {
User user = db1.GetInformation(userid);
if (user == null) {
return new ResponseEntity<>("", errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR);
}
String json = mapper.writeValueAsString(user);
return new ResponseEntity<>(json, headers, HttpStatus.OK);
} catch (JsonProcessingException e) {
e.printStackTrace();
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);
}
}
@Override
@CrossOrigin(origins = "*", allowedHeaders = "*")
public ResponseEntity<String> loginUser(
@RequestBody String requestBody
) {
try {
// 解析前端发送的JSON数据 {email: xxx, password: xxx}
com.fasterxml.jackson.databind.JsonNode jsonNode = mapper.readTree(requestBody);
// 获取email和password字段
com.fasterxml.jackson.databind.JsonNode emailNode = jsonNode.get("email");
com.fasterxml.jackson.databind.JsonNode passwordNode = jsonNode.get("password");
if (emailNode == null || passwordNode == null) {
com.fasterxml.jackson.databind.node.ObjectNode errorJson = mapper.createObjectNode();
errorJson.put("message", "缺少必要参数");
String jsonError = mapper.writeValueAsString(errorJson);
return new ResponseEntity<>(jsonError, HttpStatus.BAD_REQUEST);
}
String email = emailNode.asText();
String password = passwordNode.asText();
// 参数验证
if (email == null || email.trim().isEmpty() ||
password == null || password.trim().isEmpty()) {
com.fasterxml.jackson.databind.node.ObjectNode errorJson = mapper.createObjectNode();
errorJson.put("message", "邮箱和密码不能为空");
String jsonError = mapper.writeValueAsString(errorJson);
return new ResponseEntity<>(jsonError, HttpStatus.BAD_REQUEST);
}
// 创建User对象进行登录验证
User user = new User();
user.email = email.trim();
user.password = password;
String userid = db1.LoginUser(user);
if (userid != null) {
com.fasterxml.jackson.databind.node.ObjectNode responseJson = mapper.createObjectNode();
responseJson.put("userId", userid);
responseJson.put("userid", userid);
responseJson.put("message", "登录成功");
String jsonResponse = mapper.writeValueAsString(responseJson);
return new ResponseEntity<>(jsonResponse, HttpStatus.OK);
} else {
// 返回JSON格式的错误信息
com.fasterxml.jackson.databind.node.ObjectNode errorJson = mapper.createObjectNode();
errorJson.put("message", "登录失败,请检查账号密码");
String jsonError = mapper.writeValueAsString(errorJson);
return new ResponseEntity<>(jsonError, HttpStatus.UNAUTHORIZED);
}
} catch (JsonProcessingException e) {
e.printStackTrace();
com.fasterxml.jackson.databind.node.ObjectNode errorJson = mapper.createObjectNode();
try {
errorJson.put("message", "服务器内部错误");
String jsonError = mapper.writeValueAsString(errorJson);
return new ResponseEntity<>(jsonError, HttpStatus.INTERNAL_SERVER_ERROR);
} catch (JsonProcessingException ex) {
return new ResponseEntity<>("{\"message\":\"服务器内部错误\"}", HttpStatus.INTERNAL_SERVER_ERROR);
}
} catch (Exception e) {
e.printStackTrace();
com.fasterxml.jackson.databind.node.ObjectNode errorJson = mapper.createObjectNode();
try {
errorJson.put("message", "服务器内部错误");
String jsonError = mapper.writeValueAsString(errorJson);
return new ResponseEntity<>(jsonError, HttpStatus.INTERNAL_SERVER_ERROR);
} catch (JsonProcessingException ex) {
return new ResponseEntity<>("{\"message\":\"服务器内部错误\"}", HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
@Override
@CrossOrigin(origins = "*", allowedHeaders = "*")
public ResponseEntity<Integer> registerUser(
@RequestBody String requestBody
) {
try {
System.out.println("Register request body: " + requestBody);
// 解析 JSON 数据
com.fasterxml.jackson.databind.JsonNode jsonNode = mapper.readTree(requestBody);
// 安全地获取字段
com.fasterxml.jackson.databind.JsonNode usernameNode = jsonNode.get("username");
com.fasterxml.jackson.databind.JsonNode passwordNode = jsonNode.get("password");
com.fasterxml.jackson.databind.JsonNode inviteEmailNode = jsonNode.get("invite_email");
if (usernameNode == null || passwordNode == null || inviteEmailNode == null) {
return new ResponseEntity<>(2, HttpStatus.BAD_REQUEST); // 参数不完整
}
String username = usernameNode.asText();
String password = passwordNode.asText();
String inviteEmail = inviteEmailNode.asText();
// 参数验证
if (username == null || username.trim().isEmpty() ||
password == null || password.trim().isEmpty() ||
inviteEmail == null || inviteEmail.trim().isEmpty()) {
return new ResponseEntity<>(2, HttpStatus.BAD_REQUEST);
}
// 创建 User 对象
User user = new User();
user.userid = java.util.UUID.randomUUID().toString(); // 生成唯一用户ID
user.username = username.trim();
user.password = password;
user.email = inviteEmail.trim(); // 使用邀请邮箱作为用户邮箱
// 设置默认值
user.sex = "m"; // 默认性别
user.school = ""; // 默认学校
user.pictureurl = ""; // 默认头像URL
user.profile = ""; // 默认个人简介
user.accountstate = false; // 默认账号状态为正常
user.invitetimes = 5; // 默认邀请次数
// 设置时间字段
user.lastDetectedTime = new java.util.Date();
user.fakeLastDetectedTime = new java.util.Date();
// 调用数据库注册方法
int ret = db1.RegisterUser(user);
System.out.println("Register result: " + ret);
// // 如果注册成功,还需要创建对应的 UserPT 记录
// if (ret == 0) {
// try {
// entity.UserPT userPT = new entity.UserPT();
// userPT.userid = user.userid;
// userPT.magic = 100; // 初始魔力值
// userPT.upload = 0L; // 初始上传量
// userPT.download = 0L; // 初始下载量
// userPT.share = 0.0; // 初始分享率
// userPT.farmurl = ""; // 默认做种路径
// userPT.viptime = 0; // 初始VIP次数
// userPT.user = user; // 设置关联
// int ptRet = db1.RegisterUserPT(userPT);
// if (ptRet != 0) {
// // 如果 UserPT 创建失败,记录日志但不影响主要注册流程
// System.err.println("Warning: Failed to create UserPT for user " + user.userid);
// }
// } catch (Exception e) {
// System.err.println("Warning: Exception creating UserPT: " + e.getMessage());
// }
// }
if (ret == 0) {
return new ResponseEntity<>(0, HttpStatus.OK); // 返回 0 表示注册成功
} else if (ret == 1) {
return new ResponseEntity<>(1, HttpStatus.CONFLICT); // 返回 1 表示邮箱重复
} else {
return new ResponseEntity<>(ret, HttpStatus.BAD_REQUEST); // 返回 2 表示未被邀请或其他错误
}
} catch (JsonProcessingException e) {
e.printStackTrace();
return new ResponseEntity<>(2, HttpStatus.INTERNAL_SERVER_ERROR); // 返回 2 表示处理失败
} catch (Exception e) {
e.printStackTrace();
return new ResponseEntity<>(2, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@Override
public ResponseEntity<String> getForum() {
try {
Post[] posts = db1.GetPostList();
if (posts == null || posts.length == 0) {
return new ResponseEntity<>("[]", HttpStatus.OK); // 返回空数组表示没有帖子
}
String json = mapper.writeValueAsString(posts);
return new ResponseEntity<>(json, HttpStatus.OK);
} catch (JsonProcessingException e) {
e.printStackTrace();
return new ResponseEntity<>("[]", HttpStatus.INTERNAL_SERVER_ERROR);
} catch (Exception e) {
e.printStackTrace();
return new ResponseEntity<>("[]", HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}