修改一下tracker的url
Change-Id: I7b7fed5938012ca563c9f83548cdabc4eaa3c8d5
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java b/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java
index ffda0e7..1a4fc01 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java
@@ -4,6 +4,10 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.boot.web.server.ConfigurableWebServerFactory;
+import org.springframework.boot.web.server.ErrorPage;
+import org.springframework.boot.web.server.WebServerFactoryCustomizer;
+import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
/**
@@ -37,4 +41,12 @@
System.out.println(blue + " ----我爱雨滔身体好好 喵喵 喵 喵" + reset);
}
+
+ @Bean
+ public WebServerFactoryCustomizer<ConfigurableWebServerFactory> webServerFactoryCustomizer() {
+ return factory -> {
+ ErrorPage error404Page = new ErrorPage("/index.html");
+ factory.addErrorPages(error404Page);
+ };
+ }
}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/Server/AnnounceService.java b/ruoyi-admin/src/main/java/com/ruoyi/web/Server/AnnounceService.java
index b983acd..37e2135 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/Server/AnnounceService.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/Server/AnnounceService.java
@@ -54,7 +54,7 @@
updateUserInfo(request);
// 返回peer列表给客户端
- //TODO 默认值是60,改为动态调整
+
Integer interval = getAnnounceInterval(request);
TrackerResponse trackerResponse = TrackerResponse.build(interval, 60, torrent.getSeeders(), torrent.getLeechers(), peerList);
return trackerResponse.toResultMap();
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/Server/BT/TorrentService.java b/ruoyi-admin/src/main/java/com/ruoyi/web/Server/BT/TorrentService.java
index b6f1b72..497b1ca 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/Server/BT/TorrentService.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/Server/BT/TorrentService.java
@@ -3,6 +3,7 @@
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dampcake.bencode.Bencode;
import com.dampcake.bencode.Type;
@@ -16,6 +17,8 @@
import com.ruoyi.web.dao.BT.TorrentDao;
import com.ruoyi.web.domain.BT.*;
import com.ruoyi.web.Server.sys.UserService;
+import com.ruoyi.web.domain.BT.dto.TorrentSearchRequest;
+import com.ruoyi.web.domain.BT.dto.TorrentSearchResult;
import com.ruoyi.web.domain.sys.UserCredentialEntity;
import com.ruoyi.web.domain.sys.UserEntity;
import lombok.RequiredArgsConstructor;
@@ -63,6 +66,7 @@
entity.setStatus(TorrentEntity.Status.CANDIDATE);
entity.setFileStatus(0);
entity.setOwner(userService.getUserId());
+ entity.setId(torrentDao.countId()+1);
torrentDao.insert(entity);
return entity.getId();
}
@@ -124,8 +128,100 @@
return infoBencode.encode(decodedMap);
}
- public void audit(TorrentAuditParam param) {
+ public Page<TorrentSearchResult> searchTorrents(TorrentSearchRequest request) {
+ // 创建分页对象
+ Page<TorrentEntity> page = new Page<>(request.getPageNum(), request.getPageSize());
+
+ // 构建查询条件
+ QueryWrapper<TorrentEntity> queryWrapper = buildQueryWrapper(request);
+
+ // 执行查询
+ Page<TorrentEntity> torrentPage = torrentDao.selectPage(page, queryWrapper);
+
+ // 转换结果
+ Page<TorrentSearchResult> resultPage = new Page<>(
+ torrentPage.getCurrent(),
+ torrentPage.getSize(),
+ torrentPage.getTotal()
+ );
+
+ for (TorrentEntity torrent : torrentPage.getRecords()) {
+ TorrentSearchResult result = new TorrentSearchResult();
+ result.setTorrent(torrent);
+
+ // 查询并设置用户信息
+ UserEntity owner = getOwnerInfo(torrent.getOwner());
+ result.setOwnerInfo(owner);
+
+ resultPage.getRecords().add(result);
+ }
+
+ return resultPage;
+ }
+
+ private QueryWrapper<TorrentEntity> buildQueryWrapper(TorrentSearchRequest request) {
+ QueryWrapper<TorrentEntity> wrapper = new QueryWrapper<>();
+
+ // 精准搜索条件
+ if (request.getInfoHash() != null && !request.getInfoHash().isEmpty()) {
+ wrapper.eq("info_hash", request.getInfoHash());
+ }
+ if (request.getCategory() != null) {
+ wrapper.eq("category", request.getCategory());
+ }
+ if (request.getStatus() != null) {
+ wrapper.eq("status", request.getStatus());
+ }
+ if (request.getFileStatus() != null) {
+ wrapper.eq("file_status", request.getFileStatus());
+ }
+ if (request.getOwner() != null) {
+ wrapper.eq("owner", request.getOwner());
+ }
+ if (request.getType() != null) {
+ wrapper.eq("type", request.getType());
+ }
+
+ // 模糊搜索条件
+ if (request.getNameKeyword() != null && !request.getNameKeyword().isEmpty()) {
+ wrapper.like("name", request.getNameKeyword());
+ }
+ if (request.getTitleKeyword() != null && !request.getTitleKeyword().isEmpty()) {
+ wrapper.like("title", request.getTitleKeyword());
+ }
+ if (request.getDescriptionKeyword() != null && !request.getDescriptionKeyword().isEmpty()) {
+ wrapper.like("description", request.getDescriptionKeyword());
+ }
+
+ // 范围搜索条件
+ if (request.getMinSize() != null) {
+ wrapper.ge("size", request.getMinSize());
+ }
+ if (request.getMaxSize() != null) {
+ wrapper.le("size", request.getMaxSize());
+ }
+ if (request.getCreateTimeStart() != null) {
+ wrapper.ge("create_time", request.getCreateTimeStart());
+ }
+ if (request.getCreateTimeEnd() != null) {
+ wrapper.le("create_time", request.getCreateTimeEnd());
+ }
+
+ // 排序条件
+ if (request.getSortField() != null && !request.getSortField().isEmpty()) {
+ boolean isAsc = "asc".equalsIgnoreCase(request.getSortDirection());
+ wrapper.orderBy(true, isAsc, request.getSortField());
+ }
+
+ return wrapper;
+ }
+
+ private UserEntity getOwnerInfo(Integer ownerId) {
+ return userService.getUserById(ownerId);
+ }
+
+ public void audit(TorrentAuditParam param) {
Integer id = param.getId();
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/BT/TagController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/BT/TagController.java
index 3cedd5d..6e82701 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/BT/TagController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/BT/TagController.java
@@ -10,9 +10,7 @@
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
import java.util.List;
@@ -35,6 +33,57 @@
return Result.ok(tags);
}
+ @Operation(summary = "删除标签", description = "根据ID删除标签")
+ @DeleteMapping("/delete/{id}")
+ public Result deleteTag(@PathVariable Long id) {
+ // 检查标签是否存在
+ TagEntity tag = tagDao.findById(id);
+ if (tag == null) {
+ return Result.error("标签不存在");
+ }
+
+ int rows = tagDao.deleteById(id);
+ if (rows > 0) {
+ return Result.ok();
+ } else {
+ return Result.error("删除标签失败");
+ }
+ }
+
+ @Operation(summary = "更新标签", description = "根据ID更新标签信息")
+ @PutMapping("/update")
+ public Result updateTag(@RequestBody TagEntity tag) {
+ // 检查标签是否存在
+ TagEntity oldTag = tagDao.findById((long)tag.getId());
+ if (oldTag == null) {
+ return Result.error("标签不存在");
+ }
+
+ // 检查新标签名是否已存在(排除自身)
+ boolean exists = tagDao.existsByNameAndNotId(tag.getName(), (long)tag.getId());
+ if (exists) {
+ return Result.error("标签名已被其他标签使用");
+ }
+
+ int rows = tagDao.update(tag);
+ if (rows > 0) {
+ return Result.ok();
+ } else {
+ return Result.error("更新标签失败");
+ }
+ }
+
+ @Operation(summary = "获取单个标签", description = "根据ID获取标签信息")
+ @GetMapping("/{id}")
+ public Result getTag(@PathVariable Long id) {
+ TagEntity tag = tagDao.findById(id);
+ if (tag != null) {
+ return Result.ok(tag);
+ } else {
+ return Result.error("标签不存在");
+ }
+ }
+
@Operation(summary = "所有分类", description = "返回所有分类,电影之类的")
@GetMapping("/all_cat")
public Result allCat() {
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/BT/TorrentController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/BT/TorrentController.java
index 7a84cd5..ed8e869 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/BT/TorrentController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/BT/TorrentController.java
@@ -1,7 +1,9 @@
package com.ruoyi.web.controller.BT;
import cn.dev33.satoken.annotation.SaIgnore;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.PageInfo;
+import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.web.Server.BT.TorrentCommentService;
import com.ruoyi.web.Server.BT.TorrentService;
import com.ruoyi.web.Server.BT.TrackerURLService;
@@ -15,6 +17,8 @@
import com.ruoyi.web.domain.BT.*;
import com.ruoyi.web.Server.sys.UserService;
+import com.ruoyi.web.domain.BT.dto.TorrentSearchRequest;
+import com.ruoyi.web.domain.BT.dto.TorrentSearchResult;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
@@ -58,6 +62,17 @@
private final SuggestDao suggestDao;
private final UserService userService;
private final TorrentCommentService torrentCommentService;
+ /**
+ * The purpose of the method:
+ *
+ * 种子搜索
+ * {@code @date} 2025/6/8 13:11
+ */
+ @PostMapping("/search")
+ public Result searchTorrents(@RequestBody TorrentSearchRequest request) {
+ Page<TorrentSearchResult> result = torrentService.searchTorrents(request);
+ return Result.ok(result);
+ }
/**
* 种子列表查询
@@ -125,7 +140,7 @@
@Operation(summary = "新增种子")
@PostMapping("/add")
- public Result add(TorrentAddParam param) {
+ public Result add(@RequestBody TorrentAddParam param) {
Integer id = torrentService.add(param);
return Result.ok(id);
}
@@ -160,7 +175,7 @@
@Operation(summary = "上传文件并生成种子")
@PostMapping("/upload")
- public ResponseEntity<byte[]> upload(@RequestPart("file") MultipartFile file,
+ public Result upload(@RequestPart("file") MultipartFile file,
@RequestParam Integer id) {
try {
if (file.isEmpty()) {
@@ -205,14 +220,10 @@
// 2. 使用 RFC 5987 标准的 filename* 语法设置响应头
String contentDisposition = "attachment; filename*=UTF-8''" + encodedFilename;
- return ResponseEntity.ok()
- .contentType(MediaType.parseMediaType("application/x-bittorrent")) // 明确类型
- .header(HttpHeaders.CONTENT_DISPOSITION, contentDisposition) // 使用 RFC 5987
- .body(fileBytes);
+ return Result.ok();
} catch (IOException | RocketPTException e) {
- return ResponseEntity.status(501)
- .body(e.getMessage().getBytes());
+ return Result.error("上传失败,站内种子已存在");
}
}
@Operation(summary = "修改种子")
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/Constants.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/Constants.java
index e3fa91b..4d1511f 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/Constants.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/Constants.java
@@ -50,7 +50,7 @@
String PROTOCOL = "http";
- Integer PORT = 8080;
+ Integer PORT = 5004;
}
}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/dao/BT/TagDao.java b/ruoyi-admin/src/main/java/com/ruoyi/web/dao/BT/TagDao.java
index 2d3ce55..931f777 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/dao/BT/TagDao.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/dao/BT/TagDao.java
@@ -3,8 +3,7 @@
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.web.domain.BT.TagCatEntity;
import com.ruoyi.web.domain.BT.TagEntity;
-import org.apache.ibatis.annotations.Mapper;
-import org.apache.ibatis.annotations.Select;
+import org.apache.ibatis.annotations.*;
import java.util.List;
@@ -15,4 +14,33 @@
List<TagEntity> all_tag();
@Select("select * from bt_cat")
List<TagCatEntity> all_cat();
+ @Select("select * from bt_tag where id=#{id}")
+ TagEntity findById(Long id);
+
+ @Select("SELECT COUNT(*) FROM bt_tag WHERE name = #{name}")
+ @ResultType(Integer.class)
+ boolean existsByName(String name);
+
+ @Select("SELECT COUNT(*) FROM bt_tag WHERE name = #{name} AND id != #{id}")
+ @ResultType(Integer.class)
+ boolean existsByNameAndNotId(String name, Long id);
+
+ @Insert("INSERT INTO bt_tag (name, description, create_time, update_time) " +
+ "VALUES (#{name}, #{description}, #{createTime}, #{updateTime})")
+ @Options(useGeneratedKeys = true, keyProperty = "id")
+ int insert(TagEntity tag);
+
+ @Delete("DELETE FROM bt_tag WHERE id = #{id}")
+ int delete(Long id);
+
+ @Update("""
+ UPDATE bt_tag
+ SET name = #{name},
+ remark = #{remark},
+ cat = #{cat},
+ update_time = #{updateTime}
+ WHERE id = #{id}
+""")
+ int update(TagEntity tag);
+
}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/dao/BT/TorrentDao.java b/ruoyi-admin/src/main/java/com/ruoyi/web/dao/BT/TorrentDao.java
index 0ccc066..31f1fff 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/dao/BT/TorrentDao.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/dao/BT/TorrentDao.java
@@ -29,6 +29,7 @@
" #{visible}, #{anonymous}, #{leechers}, #{seeders}, #{completions}, \n" +
" #{remark}\n" +
")")
+ @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
int insert(TorrentEntity entity);
@Select("select * from bt_torrent where id=#{id}")
@@ -37,6 +38,8 @@
@Select("SELECT COUNT(*) FROM bt_torrent WHERE info_hash = #{infoHash}")
long selectCountByInfoHash(byte[] infoHash);
+ @Select("SELECT COUNT(*) FROM bt_torrent")
+ int countId();
default List<TorrentEntity> advancedSearch(AdvancedTorrentParam param) {
QueryWrapper<TorrentEntity> wrapper = new QueryWrapper<>();
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/domain/BT/dto/TorrentSearchRequest.java b/ruoyi-admin/src/main/java/com/ruoyi/web/domain/BT/dto/TorrentSearchRequest.java
new file mode 100644
index 0000000..040841f
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/domain/BT/dto/TorrentSearchRequest.java
@@ -0,0 +1,35 @@
+package com.ruoyi.web.domain.BT.dto;
+
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+public class TorrentSearchRequest {
+ // 精准搜索字段
+ private String infoHash; // 种子哈希
+ private Integer category; // 类别
+ private Integer status; // 状态
+ private Integer fileStatus; // 文件状态
+ private Integer owner; // 拥有者
+ private Integer type; // 类型
+
+ // 模糊搜索字段
+ private String nameKeyword; // 名称关键词
+ private String titleKeyword; // 标题关键词
+ private String descriptionKeyword; // 描述关键词
+
+ // 范围搜索字段
+ private Long minSize; // 最小文件大小
+ private Long maxSize; // 最大文件大小
+ private LocalDateTime createTimeStart; // 创建时间开始
+ private LocalDateTime createTimeEnd; // 创建时间结束
+
+ // 排序字段
+ private String sortField = "createTime"; // 排序字段,默认按创建时间
+ private String sortDirection = "desc"; // 排序方向,默认降序
+
+ // 分页信息
+ private Integer pageNum = 1; // 当前页码
+ private Integer pageSize = 20; // 每页数量
+}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/domain/BT/dto/TorrentSearchResult.java b/ruoyi-admin/src/main/java/com/ruoyi/web/domain/BT/dto/TorrentSearchResult.java
new file mode 100644
index 0000000..b443ed9
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/domain/BT/dto/TorrentSearchResult.java
@@ -0,0 +1,12 @@
+package com.ruoyi.web.domain.BT.dto;
+
+
+import com.ruoyi.web.domain.BT.TorrentEntity;
+import com.ruoyi.web.domain.sys.UserEntity;
+import lombok.Data;
+
+@Data
+public class TorrentSearchResult {
+ private TorrentEntity torrent;
+ private UserEntity ownerInfo;
+}
\ No newline at end of file