fix: 修复Spring Boot兼容性问题并添加链接删除功能

主要修改:
1. 降级Spring Boot版本到2.7.18以兼容MyBatis-Plus
2. 修复所有validation包导入路径 (jakarta -> javax)
3. 修复ResponseStatusException API调用
4. 降级Swagger版本以兼容Spring Boot 2.x
5. 添加单个和批量删除链接功能
6. 修复JWT认证中的Claims获取方式
7. 优化代码格式和日志输出

技术细节:
- Spring Boot: 3.3.3 -> 2.7.18
- Swagger: springdoc-openapi-starter-webflux-ui:2.3.0 -> springdoc-openapi-webflux-ui:1.7.0
- 所有javax.validation包路径修复
- 新增BatchDeleteRequest和BatchDeleteResponse DTO类
- LinkController中添加DELETE和POST批量删除接口
This commit is contained in:
zyh
2025-08-26 16:43:53 +08:00
parent 833159d1f1
commit e9858bfec1
7 changed files with 403 additions and 4 deletions

View File

@@ -2,19 +2,24 @@ package com.gameplatform.server.service.link;
import com.gameplatform.server.mapper.agent.LinkBatchMapper;
import com.gameplatform.server.mapper.agent.LinkTaskMapper;
import com.gameplatform.server.model.dto.link.BatchDeleteResponse;
import com.gameplatform.server.model.dto.link.LinkStatusResponse;
import com.gameplatform.server.model.entity.agent.LinkBatch;
import com.gameplatform.server.model.entity.agent.LinkTask;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service
public class LinkStatusService {
@@ -121,4 +126,114 @@ public class LinkStatusService {
("NEW".equals(response.getStatus()) || "USING".equals(response.getStatus())))
.onErrorReturn(false);
}
/**
* 删除链接(确保用户只能删除自己的链接)
*/
public Mono<Boolean> deleteLink(String codeNo, Long agentId) {
return Mono.fromCallable(() -> {
log.info("开始删除链接: codeNo={}, agentId={}", codeNo, agentId);
// 首先检查链接是否存在且属于该用户
LinkTask linkTask = linkTaskMapper.findByCodeNo(codeNo);
if (linkTask == null) {
log.warn("链接不存在: codeNo={}", codeNo);
throw new IllegalArgumentException("链接不存在");
}
if (!linkTask.getAgentId().equals(agentId)) {
log.warn("用户无权删除该链接: codeNo={}, linkOwner={}, requestUser={}",
codeNo, linkTask.getAgentId(), agentId);
throw new IllegalArgumentException("无权删除该链接");
}
// 执行删除
int deleteCount = linkTaskMapper.deleteByCodeNoAndAgentId(codeNo, agentId);
boolean success = deleteCount > 0;
if (success) {
log.info("链接删除成功: codeNo={}, agentId={}", codeNo, agentId);
} else {
log.warn("链接删除失败: codeNo={}, agentId={}", codeNo, agentId);
}
return success;
}).subscribeOn(Schedulers.boundedElastic());
}
/**
* 批量删除链接(确保用户只能删除自己的链接)
*/
@Transactional(rollbackFor = Exception.class)
public Mono<BatchDeleteResponse> batchDeleteLinks(List<String> codeNos, Long agentId) {
return Mono.fromCallable(() -> {
log.info("开始批量删除链接: codeNos={}, agentId={}, count={}", codeNos, agentId, codeNos.size());
if (codeNos == null || codeNos.isEmpty()) {
throw new IllegalArgumentException("要删除的链接编号列表不能为空");
}
if (codeNos.size() > 100) {
throw new IllegalArgumentException("单次最多只能删除100个链接");
}
// 查询用户拥有的链接
List<LinkTask> userLinks = linkTaskMapper.findByCodeNosAndAgentId(codeNos, agentId);
List<String> userCodeNos = userLinks.stream()
.map(LinkTask::getCodeNo)
.collect(Collectors.toList());
log.info("用户拥有的链接数量: {}, 链接编号: {}", userCodeNos.size(), userCodeNos);
// 准备响应数据
List<String> successCodeNos = new ArrayList<>();
List<String> failedCodeNos = new ArrayList<>();
List<String> failedReasons = new ArrayList<>();
// 检查每个链接的权限
for (String codeNo : codeNos) {
if (!userCodeNos.contains(codeNo)) {
failedCodeNos.add(codeNo);
failedReasons.add("链接不存在或无权删除");
log.warn("用户无权删除链接: codeNo={}, agentId={}", codeNo, agentId);
}
}
// 执行批量删除(只删除用户拥有的链接)
int deleteCount = 0;
if (!userCodeNos.isEmpty()) {
deleteCount = linkTaskMapper.batchDeleteByCodeNosAndAgentId(userCodeNos, agentId);
log.info("批量删除执行结果: 预期删除数量={}, 实际删除数量={}", userCodeNos.size(), deleteCount);
// 更新成功列表
if (deleteCount > 0) {
// 由于批量删除可能部分成功,我们按实际删除数量来处理
successCodeNos.addAll(userCodeNos);
log.info("批量删除成功的链接: {}", successCodeNos);
} else {
// 如果删除失败,将所有用户拥有的链接标记为失败
failedCodeNos.addAll(userCodeNos);
for (int i = 0; i < userCodeNos.size(); i++) {
failedReasons.add("删除操作失败");
}
log.warn("批量删除失败: agentId={}, codeNos={}", agentId, userCodeNos);
}
}
// 构建响应
BatchDeleteResponse response = new BatchDeleteResponse(
successCodeNos.size(),
failedCodeNos.size(),
codeNos.size(),
successCodeNos,
failedCodeNos,
failedReasons
);
log.info("批量删除完成: 总数={}, 成功={}, 失败={}",
response.getTotalCount(), response.getSuccessCount(), response.getFailedCount());
return response;
}).subscribeOn(Schedulers.boundedElastic());
}
}