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:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -26,3 +26,5 @@ Thumbs.db
|
|||||||
# Temporary files
|
# Temporary files
|
||||||
*.tmp
|
*.tmp
|
||||||
*.temp
|
*.temp
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package com.gameplatform.server.controller.link;
|
package com.gameplatform.server.controller.link;
|
||||||
|
|
||||||
|
import com.gameplatform.server.model.dto.link.BatchDeleteRequest;
|
||||||
|
import com.gameplatform.server.model.dto.link.BatchDeleteResponse;
|
||||||
import com.gameplatform.server.model.dto.link.LinkGenerateRequest;
|
import com.gameplatform.server.model.dto.link.LinkGenerateRequest;
|
||||||
import com.gameplatform.server.model.dto.link.LinkGenerateResponse;
|
import com.gameplatform.server.model.dto.link.LinkGenerateResponse;
|
||||||
import com.gameplatform.server.model.dto.link.LinkListRequest;
|
import com.gameplatform.server.model.dto.link.LinkListRequest;
|
||||||
@@ -14,12 +16,9 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
|||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.http.HttpHeaders;
|
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.server.ServerWebExchange;
|
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@@ -56,7 +55,13 @@ public class LinkController {
|
|||||||
log.info("认证用户: {}", authentication.getName());
|
log.info("认证用户: {}", authentication.getName());
|
||||||
|
|
||||||
// 获取用户ID
|
// 获取用户ID
|
||||||
Claims claims = (Claims) authentication.getCredentials();
|
Claims claims = (Claims) authentication.getDetails();
|
||||||
|
if (claims == null) {
|
||||||
|
log.error("=== 认证失败:Claims为空 ===");
|
||||||
|
log.error("Authentication details: {}", authentication.getDetails());
|
||||||
|
return Mono.error(new IllegalArgumentException("用户未认证:Claims为空"));
|
||||||
|
}
|
||||||
|
|
||||||
Long agentId = claims.get("userId", Long.class);
|
Long agentId = claims.get("userId", Long.class);
|
||||||
String userType = claims.get("userType", String.class);
|
String userType = claims.get("userType", String.class);
|
||||||
|
|
||||||
@@ -189,6 +194,95 @@ public class LinkController {
|
|||||||
log.debug("检查链接是否有效: codeNo={}", codeNo);
|
log.debug("检查链接是否有效: codeNo={}", codeNo);
|
||||||
return linkStatusService.isLinkValid(codeNo);
|
return linkStatusService.isLinkValid(codeNo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/{codeNo}")
|
||||||
|
@Operation(summary = "删除链接", description = "删除指定的链接,用户只能删除自己创建的链接")
|
||||||
|
public Mono<Boolean> deleteLink(@PathVariable("codeNo") String codeNo, Authentication authentication) {
|
||||||
|
log.info("=== 开始删除链接 ===");
|
||||||
|
log.info("链接编号: {}", codeNo);
|
||||||
|
|
||||||
|
if (authentication == null) {
|
||||||
|
log.error("=== 认证失败:Authentication为空 ===");
|
||||||
|
return Mono.error(new IllegalArgumentException("用户未认证:Authentication为空"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取用户ID
|
||||||
|
Claims claims = (Claims) authentication.getDetails();
|
||||||
|
if (claims == null) {
|
||||||
|
log.error("=== 认证失败:Claims为空 ===");
|
||||||
|
log.error("Authentication details: {}", authentication.getDetails());
|
||||||
|
return Mono.error(new IllegalArgumentException("用户未认证:Claims为空"));
|
||||||
|
}
|
||||||
|
|
||||||
|
Long agentId = claims.get("userId", Long.class);
|
||||||
|
String userType = claims.get("userType", String.class);
|
||||||
|
|
||||||
|
log.info("用户信息: agentId={}, userType={}", agentId, userType);
|
||||||
|
|
||||||
|
if (agentId == null) {
|
||||||
|
log.error("=== 无法获取用户ID ===");
|
||||||
|
return Mono.error(new IllegalArgumentException("无法获取用户ID"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return linkStatusService.deleteLink(codeNo, agentId)
|
||||||
|
.doOnSuccess(success -> {
|
||||||
|
if (success) {
|
||||||
|
log.info("链接删除成功: codeNo={}, agentId={}", codeNo, agentId);
|
||||||
|
} else {
|
||||||
|
log.warn("链接删除失败: codeNo={}, agentId={}", codeNo, agentId);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.doOnError(error -> {
|
||||||
|
log.error("删除链接时发生错误: codeNo={}, agentId={}, error={}",
|
||||||
|
codeNo, agentId, error.getMessage(), error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/batch-delete")
|
||||||
|
@Operation(summary = "批量删除链接", description = "批量删除指定的链接,用户只能删除自己创建的链接,最多一次删除100个")
|
||||||
|
public Mono<BatchDeleteResponse> batchDeleteLinks(@RequestBody BatchDeleteRequest request, Authentication authentication) {
|
||||||
|
log.info("=== 开始批量删除链接 ===");
|
||||||
|
log.info("要删除的链接数量: {}", request.getCodeNos().size());
|
||||||
|
log.info("链接编号列表: {}", request.getCodeNos());
|
||||||
|
|
||||||
|
if (authentication == null) {
|
||||||
|
log.error("=== 认证失败:Authentication为空 ===");
|
||||||
|
return Mono.error(new IllegalArgumentException("用户未认证:Authentication为空"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取用户ID
|
||||||
|
Claims claims = (Claims) authentication.getDetails();
|
||||||
|
if (claims == null) {
|
||||||
|
log.error("=== 认证失败:Claims为空 ===");
|
||||||
|
log.error("Authentication details: {}", authentication.getDetails());
|
||||||
|
return Mono.error(new IllegalArgumentException("用户未认证:Claims为空"));
|
||||||
|
}
|
||||||
|
|
||||||
|
Long agentId = claims.get("userId", Long.class);
|
||||||
|
String userType = claims.get("userType", String.class);
|
||||||
|
|
||||||
|
log.info("用户信息: agentId={}, userType={}", agentId, userType);
|
||||||
|
|
||||||
|
if (agentId == null) {
|
||||||
|
log.error("=== 无法获取用户ID ===");
|
||||||
|
return Mono.error(new IllegalArgumentException("无法获取用户ID"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return linkStatusService.batchDeleteLinks(request.getCodeNos(), agentId)
|
||||||
|
.doOnSuccess(response -> {
|
||||||
|
log.info("批量删除链接完成: 总数={}, 成功={}, 失败={}, agentId={}",
|
||||||
|
response.getTotalCount(), response.getSuccessCount(),
|
||||||
|
response.getFailedCount(), agentId);
|
||||||
|
if (!response.isAllSuccess()) {
|
||||||
|
log.warn("部分链接删除失败: 失败的链接={}, 失败原因={}",
|
||||||
|
response.getFailedCodeNos(), response.getFailedReasons());
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.doOnError(error -> {
|
||||||
|
log.error("批量删除链接时发生错误: agentId={}, codeNos={}, error={}",
|
||||||
|
agentId, request.getCodeNos(), error.getMessage(), error);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -70,4 +70,24 @@ public interface LinkTaskMapper extends BaseMapper<LinkTask> {
|
|||||||
@Param("status") String status,
|
@Param("status") String status,
|
||||||
@Param("batchId") Long batchId,
|
@Param("batchId") Long batchId,
|
||||||
@Param("isExpired") Boolean isExpired);
|
@Param("isExpired") Boolean isExpired);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据链接编号删除链接任务
|
||||||
|
*/
|
||||||
|
int deleteByCodeNo(@Param("codeNo") String codeNo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据链接编号和代理ID删除链接任务(确保用户只能删除自己的链接)
|
||||||
|
*/
|
||||||
|
int deleteByCodeNoAndAgentId(@Param("codeNo") String codeNo, @Param("agentId") Long agentId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除链接任务(根据链接编号列表和代理ID)
|
||||||
|
*/
|
||||||
|
int batchDeleteByCodeNosAndAgentId(@Param("codeNos") List<String> codeNos, @Param("agentId") Long agentId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据链接编号列表和代理ID查询链接任务(用于验证权限)
|
||||||
|
*/
|
||||||
|
List<LinkTask> findByCodeNosAndAgentId(@Param("codeNos") List<String> codeNos, @Param("agentId") Long agentId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package com.gameplatform.server.model.dto.link;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotEmpty;
|
||||||
|
import javax.validation.constraints.Size;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除链接请求DTO
|
||||||
|
*
|
||||||
|
* @author GamePlatform
|
||||||
|
*/
|
||||||
|
@Schema(description = "批量删除链接请求")
|
||||||
|
public class BatchDeleteRequest {
|
||||||
|
|
||||||
|
@NotEmpty(message = "删除的链接编号列表不能为空")
|
||||||
|
@Size(max = 100, message = "单次最多只能删除100个链接")
|
||||||
|
@Schema(description = "要删除的链接编号列表", example = "[\"EPRGF7ZJ\", \"XKLD9F2M\", \"QWER5TYU\"]", required = true)
|
||||||
|
private List<String> codeNos;
|
||||||
|
|
||||||
|
public BatchDeleteRequest() {}
|
||||||
|
|
||||||
|
public BatchDeleteRequest(List<String> codeNos) {
|
||||||
|
this.codeNos = codeNos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getCodeNos() {
|
||||||
|
return codeNos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCodeNos(List<String> codeNos) {
|
||||||
|
this.codeNos = codeNos;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
package com.gameplatform.server.model.dto.link;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除链接响应DTO
|
||||||
|
*
|
||||||
|
* @author GamePlatform
|
||||||
|
*/
|
||||||
|
@Schema(description = "批量删除链接响应")
|
||||||
|
public class BatchDeleteResponse {
|
||||||
|
|
||||||
|
@Schema(description = "成功删除的数量", example = "3")
|
||||||
|
private int successCount;
|
||||||
|
|
||||||
|
@Schema(description = "删除失败的数量", example = "1")
|
||||||
|
private int failedCount;
|
||||||
|
|
||||||
|
@Schema(description = "总数量", example = "4")
|
||||||
|
private int totalCount;
|
||||||
|
|
||||||
|
@Schema(description = "成功删除的链接编号列表", example = "[\"EPRGF7ZJ\", \"XKLD9F2M\"]")
|
||||||
|
private List<String> successCodeNos;
|
||||||
|
|
||||||
|
@Schema(description = "删除失败的链接编号列表", example = "[\"QWER5TYU\"]")
|
||||||
|
private List<String> failedCodeNos;
|
||||||
|
|
||||||
|
@Schema(description = "删除失败的原因列表", example = "[\"链接不存在或无权删除\"]")
|
||||||
|
private List<String> failedReasons;
|
||||||
|
|
||||||
|
@Schema(description = "是否全部成功", example = "false")
|
||||||
|
private boolean allSuccess;
|
||||||
|
|
||||||
|
public BatchDeleteResponse() {}
|
||||||
|
|
||||||
|
public BatchDeleteResponse(int successCount, int failedCount, int totalCount,
|
||||||
|
List<String> successCodeNos, List<String> failedCodeNos,
|
||||||
|
List<String> failedReasons) {
|
||||||
|
this.successCount = successCount;
|
||||||
|
this.failedCount = failedCount;
|
||||||
|
this.totalCount = totalCount;
|
||||||
|
this.successCodeNos = successCodeNos;
|
||||||
|
this.failedCodeNos = failedCodeNos;
|
||||||
|
this.failedReasons = failedReasons;
|
||||||
|
this.allSuccess = failedCount == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getters and Setters
|
||||||
|
public int getSuccessCount() {
|
||||||
|
return successCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSuccessCount(int successCount) {
|
||||||
|
this.successCount = successCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getFailedCount() {
|
||||||
|
return failedCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFailedCount(int failedCount) {
|
||||||
|
this.failedCount = failedCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTotalCount() {
|
||||||
|
return totalCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotalCount(int totalCount) {
|
||||||
|
this.totalCount = totalCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getSuccessCodeNos() {
|
||||||
|
return successCodeNos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSuccessCodeNos(List<String> successCodeNos) {
|
||||||
|
this.successCodeNos = successCodeNos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getFailedCodeNos() {
|
||||||
|
return failedCodeNos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFailedCodeNos(List<String> failedCodeNos) {
|
||||||
|
this.failedCodeNos = failedCodeNos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getFailedReasons() {
|
||||||
|
return failedReasons;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFailedReasons(List<String> failedReasons) {
|
||||||
|
this.failedReasons = failedReasons;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAllSuccess() {
|
||||||
|
return allSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAllSuccess(boolean allSuccess) {
|
||||||
|
this.allSuccess = allSuccess;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,19 +2,24 @@ package com.gameplatform.server.service.link;
|
|||||||
|
|
||||||
import com.gameplatform.server.mapper.agent.LinkBatchMapper;
|
import com.gameplatform.server.mapper.agent.LinkBatchMapper;
|
||||||
import com.gameplatform.server.mapper.agent.LinkTaskMapper;
|
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.dto.link.LinkStatusResponse;
|
||||||
import com.gameplatform.server.model.entity.agent.LinkBatch;
|
import com.gameplatform.server.model.entity.agent.LinkBatch;
|
||||||
import com.gameplatform.server.model.entity.agent.LinkTask;
|
import com.gameplatform.server.model.entity.agent.LinkTask;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
import reactor.core.scheduler.Schedulers;
|
import reactor.core.scheduler.Schedulers;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class LinkStatusService {
|
public class LinkStatusService {
|
||||||
@@ -121,4 +126,114 @@ public class LinkStatusService {
|
|||||||
("NEW".equals(response.getStatus()) || "USING".equals(response.getStatus())))
|
("NEW".equals(response.getStatus()) || "USING".equals(response.getStatus())))
|
||||||
.onErrorReturn(false);
|
.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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -170,4 +170,31 @@
|
|||||||
</if>
|
</if>
|
||||||
</where>
|
</where>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<delete id="deleteByCodeNo">
|
||||||
|
DELETE FROM link_task WHERE code_no = #{codeNo}
|
||||||
|
</delete>
|
||||||
|
|
||||||
|
<delete id="deleteByCodeNoAndAgentId">
|
||||||
|
DELETE FROM link_task WHERE code_no = #{codeNo} AND agent_id = #{agentId}
|
||||||
|
</delete>
|
||||||
|
|
||||||
|
<delete id="batchDeleteByCodeNosAndAgentId">
|
||||||
|
DELETE FROM link_task
|
||||||
|
WHERE agent_id = #{agentId}
|
||||||
|
AND code_no IN
|
||||||
|
<foreach collection="codeNos" item="codeNo" open="(" close=")" separator=",">
|
||||||
|
#{codeNo}
|
||||||
|
</foreach>
|
||||||
|
</delete>
|
||||||
|
|
||||||
|
<select id="findByCodeNosAndAgentId" resultMap="LinkTaskMap">
|
||||||
|
SELECT id, batch_id, agent_id, code_no, token_hash, expire_at, status, region, machine_id, login_at, refund_at, revoked_at, created_at, updated_at
|
||||||
|
FROM link_task
|
||||||
|
WHERE agent_id = #{agentId}
|
||||||
|
AND code_no IN
|
||||||
|
<foreach collection="codeNos" item="codeNo" open="(" close=")" separator=",">
|
||||||
|
#{codeNo}
|
||||||
|
</foreach>
|
||||||
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|||||||
Reference in New Issue
Block a user