feat: 新增按状态批量删除链接功能
主要修改: 1. 在LinkController中新增按状态批量删除链接的接口,允许用户根据指定状态批量删除自己创建的链接。 2. 在LinkStatusService中实现批量删除逻辑,确保用户只能删除自己的链接,并进行状态验证。 3. 更新LinkTaskMapper和对应的XML文件,增加查询和删除链接任务的相关方法。 技术细节: - 通过新增的批量删除功能,提升了用户对链接的管理能力,确保操作的安全性和有效性,同时优化了数据库操作的灵活性。
This commit is contained in:
140
docs/按狀態批量刪除鏈接接口說明.md
Normal file
140
docs/按狀態批量刪除鏈接接口說明.md
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
# 按狀態批量刪除鏈接接口說明
|
||||||
|
|
||||||
|
## 功能概述
|
||||||
|
新增了一個按鏈接狀態批量刪除鏈接的接口,允許用戶根據指定的狀態列表批量刪除自己的鏈接。
|
||||||
|
|
||||||
|
## 接口詳情
|
||||||
|
|
||||||
|
### 請求路徑
|
||||||
|
`POST /api/link/batch-delete-by-status`
|
||||||
|
|
||||||
|
### 請求參數
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"statusList": ["EXPIRED", "REFUNDED"],
|
||||||
|
"confirmDelete": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 參數說明
|
||||||
|
- `statusList`: 要刪除的鏈接狀態列表,支持的狀態值:
|
||||||
|
- `NEW`: 新建
|
||||||
|
- `USING`: 使用中
|
||||||
|
- `LOGGED_IN`: 已登錄
|
||||||
|
- `COMPLETED`: 已完成
|
||||||
|
- `REFUNDED`: 已退款
|
||||||
|
- `EXPIRED`: 已過期
|
||||||
|
- `confirmDelete`: 是否確認刪除操作,必須設置為 `true` 才能執行刪除
|
||||||
|
|
||||||
|
#### 驗證規則
|
||||||
|
- 狀態列表不能為空
|
||||||
|
- 單次最多指定10個狀態
|
||||||
|
- 必須確認刪除操作(`confirmDelete = true`)
|
||||||
|
- 只能刪除用戶自己創建的鏈接
|
||||||
|
|
||||||
|
### 響應格式
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"successCount": 15,
|
||||||
|
"failedCount": 0,
|
||||||
|
"totalCount": 15,
|
||||||
|
"successCodeNos": ["ABC123", "DEF456", "..."],
|
||||||
|
"failedCodeNos": [],
|
||||||
|
"failedReasons": [],
|
||||||
|
"allSuccess": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 響應字段說明
|
||||||
|
- `successCount`: 成功刪除的數量
|
||||||
|
- `failedCount`: 刪除失敗的數量
|
||||||
|
- `totalCount`: 總數量
|
||||||
|
- `successCodeNos`: 成功刪除的鏈接編號列表
|
||||||
|
- `failedCodeNos`: 刪除失敗的鏈接編號列表
|
||||||
|
- `failedReasons`: 刪除失敗的原因列表
|
||||||
|
- `allSuccess`: 是否全部成功
|
||||||
|
|
||||||
|
## 實現細節
|
||||||
|
|
||||||
|
### 新增文件
|
||||||
|
1. `BatchDeleteByStatusRequest.java` - 請求DTO
|
||||||
|
2. `test_batch_delete_by_status.http` - 接口測試文件
|
||||||
|
3. `docs/按狀態批量刪除鏈接接口說明.md` - 接口說明文檔
|
||||||
|
|
||||||
|
### 修改文件
|
||||||
|
1. `LinkTaskMapper.java` - 添加數據庫查詢方法
|
||||||
|
2. `LinkTaskMapper.xml` - 添加SQL映射
|
||||||
|
3. `LinkStatusService.java` - 添加業務邏輯方法
|
||||||
|
4. `LinkController.java` - 添加控制器接口
|
||||||
|
|
||||||
|
### 數據庫操作
|
||||||
|
- `findByStatusListAndAgentId`: 查詢指定狀態和用戶的鏈接列表
|
||||||
|
- `countByStatusListAndAgentId`: 統計指定狀態和用戶的鏈接數量
|
||||||
|
- `batchDeleteByStatusListAndAgentId`: 批量刪除指定狀態和用戶的鏈接
|
||||||
|
|
||||||
|
## 安全考慮
|
||||||
|
|
||||||
|
### 權限控制
|
||||||
|
- 用戶只能刪除自己創建的鏈接
|
||||||
|
- 通過JWT token進行用戶身份驗證
|
||||||
|
- 通過 `agentId` 過濾確保數據隔離
|
||||||
|
|
||||||
|
### 操作確認
|
||||||
|
- 必須設置 `confirmDelete = true` 才能執行刪除操作
|
||||||
|
- 避免誤操作導致的數據丟失
|
||||||
|
|
||||||
|
### 參數驗證
|
||||||
|
- 驗證狀態值的有效性
|
||||||
|
- 限制單次操作的狀態數量(最多10個)
|
||||||
|
- 參數非空驗證
|
||||||
|
|
||||||
|
## 使用示例
|
||||||
|
|
||||||
|
### 1. 刪除過期鏈接
|
||||||
|
```http
|
||||||
|
POST /api/link/batch-delete-by-status
|
||||||
|
Authorization: Bearer {token}
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"statusList": ["EXPIRED"],
|
||||||
|
"confirmDelete": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 清理已退款和已過期的鏈接
|
||||||
|
```http
|
||||||
|
POST /api/link/batch-delete-by-status
|
||||||
|
Authorization: Bearer {token}
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"statusList": ["EXPIRED", "REFUNDED"],
|
||||||
|
"confirmDelete": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 錯誤處理
|
||||||
|
|
||||||
|
### 常見錯誤
|
||||||
|
- `用戶未認證` - JWT token無效或過期
|
||||||
|
- `必須確認刪除操作` - confirmDelete不為true
|
||||||
|
- `要删除的状态列表不能为空` - statusList為空
|
||||||
|
- `无效的状态值` - 狀態值不在允許範圍內
|
||||||
|
- `单次最多只能指定10个状态` - 狀態數量超過限制
|
||||||
|
|
||||||
|
### 響應狀態碼
|
||||||
|
- `200` - 操作成功
|
||||||
|
- `400` - 請求參數錯誤
|
||||||
|
- `401` - 用戶未認證
|
||||||
|
- `500` - 服務器內部錯誤
|
||||||
|
|
||||||
|
## 日誌記錄
|
||||||
|
系統會記錄以下關鍵信息:
|
||||||
|
- 刪除操作的發起用戶
|
||||||
|
- 指定的狀態列表
|
||||||
|
- 實際刪除的鏈接數量
|
||||||
|
- 操作結果(成功/失敗)
|
||||||
|
- 失敗原因(如有)
|
||||||
|
|
||||||
|
這些日誌有助於問題排查和操作審計。
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.gameplatform.server.controller.link;
|
package com.gameplatform.server.controller.link;
|
||||||
|
|
||||||
|
import com.gameplatform.server.model.dto.link.BatchDeleteByStatusRequest;
|
||||||
import com.gameplatform.server.model.dto.link.BatchDeleteRequest;
|
import com.gameplatform.server.model.dto.link.BatchDeleteRequest;
|
||||||
import com.gameplatform.server.model.dto.link.BatchDeleteResponse;
|
import com.gameplatform.server.model.dto.link.BatchDeleteResponse;
|
||||||
import com.gameplatform.server.model.dto.link.LinkGenerateRequest;
|
import com.gameplatform.server.model.dto.link.LinkGenerateRequest;
|
||||||
@@ -296,6 +297,58 @@ public Mono<Boolean> deleteLink(@PathVariable("codeNo") String codeNo, Authentic
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("/batch-delete-by-status")
|
||||||
|
@Operation(summary = "按状态批量删除链接", description = "根据指定的状态批量删除链接,用户只能删除自己创建的链接,支持删除的状态:NEW、USING、LOGGED_IN、COMPLETED、REFUNDED、EXPIRED")
|
||||||
|
public Mono<BatchDeleteResponse> batchDeleteLinksByStatus(@Valid @RequestBody BatchDeleteByStatusRequest request, Authentication authentication) {
|
||||||
|
log.info("=== 开始按状态批量删除链接 ===");
|
||||||
|
log.info("要删除的状态列表: {}", request.getStatusList());
|
||||||
|
log.info("是否确认删除: {}", request.getConfirmDelete());
|
||||||
|
|
||||||
|
if (authentication == null) {
|
||||||
|
log.error("=== 认证失败:Authentication为空 ===");
|
||||||
|
return Mono.error(new IllegalArgumentException("用户未认证:Authentication为空"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否确认删除
|
||||||
|
if (!Boolean.TRUE.equals(request.getConfirmDelete())) {
|
||||||
|
log.error("=== 未确认删除操作 ===");
|
||||||
|
return Mono.error(new IllegalArgumentException("必须确认删除操作,请设置confirmDelete为true"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取用户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.batchDeleteLinksByStatus(request.getStatusList(), 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={}, statusList={}, error={}",
|
||||||
|
agentId, request.getStatusList(), error.getMessage(), error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping("/batch-delete")
|
@PostMapping("/batch-delete")
|
||||||
@Operation(summary = "批量删除链接", description = "批量删除指定的链接,用户只能删除自己创建的链接,最多一次删除100个")
|
@Operation(summary = "批量删除链接", description = "批量删除指定的链接,用户只能删除自己创建的链接,最多一次删除100个")
|
||||||
public Mono<BatchDeleteResponse> batchDeleteLinks(@RequestBody BatchDeleteRequest request, Authentication authentication) {
|
public Mono<BatchDeleteResponse> batchDeleteLinks(@RequestBody BatchDeleteRequest request, Authentication authentication) {
|
||||||
|
|||||||
@@ -95,4 +95,19 @@ public interface LinkTaskMapper extends BaseMapper<LinkTask> {
|
|||||||
* 根据设备ID和状态查询链接任务
|
* 根据设备ID和状态查询链接任务
|
||||||
*/
|
*/
|
||||||
List<LinkTask> findByMachineIdAndStatus(@Param("machineId") String machineId, @Param("status") String status);
|
List<LinkTask> findByMachineIdAndStatus(@Param("machineId") String machineId, @Param("status") String status);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据状态列表和代理ID查询链接任务(用于验证权限和获取要删除的链接)
|
||||||
|
*/
|
||||||
|
List<LinkTask> findByStatusListAndAgentId(@Param("statusList") List<String> statusList, @Param("agentId") Long agentId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据状态列表和代理ID统计链接任务数量
|
||||||
|
*/
|
||||||
|
long countByStatusListAndAgentId(@Param("statusList") List<String> statusList, @Param("agentId") Long agentId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据状态列表和代理ID批量删除链接任务
|
||||||
|
*/
|
||||||
|
int batchDeleteByStatusListAndAgentId(@Param("statusList") List<String> statusList, @Param("agentId") Long agentId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
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 BatchDeleteByStatusRequest {
|
||||||
|
|
||||||
|
@NotEmpty(message = "要刪除的狀態列表不能為空")
|
||||||
|
@Size(max = 10, message = "單次最多只能指定10個狀態")
|
||||||
|
@Schema(description = "要刪除的鏈接狀態列表,可選值:NEW、USING、LOGGED_IN、COMPLETED、REFUNDED、EXPIRED",
|
||||||
|
example = "[\"EXPIRED\", \"REFUNDED\"]", required = true)
|
||||||
|
private List<String> statusList;
|
||||||
|
|
||||||
|
@Schema(description = "是否確認刪除,必須設置為true才能執行刪除操作", example = "true", required = true)
|
||||||
|
private Boolean confirmDelete = false;
|
||||||
|
|
||||||
|
public BatchDeleteByStatusRequest() {}
|
||||||
|
|
||||||
|
public BatchDeleteByStatusRequest(List<String> statusList, Boolean confirmDelete) {
|
||||||
|
this.statusList = statusList;
|
||||||
|
this.confirmDelete = confirmDelete;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getStatusList() {
|
||||||
|
return statusList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatusList(List<String> statusList) {
|
||||||
|
this.statusList = statusList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getConfirmDelete() {
|
||||||
|
return confirmDelete;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConfirmDelete(Boolean confirmDelete) {
|
||||||
|
this.confirmDelete = confirmDelete;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -266,6 +266,93 @@ public class LinkStatusService {
|
|||||||
}).subscribeOn(Schedulers.boundedElastic());
|
}).subscribeOn(Schedulers.boundedElastic());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按状态批量删除链接(确保用户只能删除自己的链接)
|
||||||
|
*/
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public Mono<BatchDeleteResponse> batchDeleteLinksByStatus(List<String> statusList, Long agentId) {
|
||||||
|
return Mono.fromCallable(() -> {
|
||||||
|
log.info("开始按状态批量删除链接: statusList={}, agentId={}", statusList, agentId);
|
||||||
|
|
||||||
|
if (statusList == null || statusList.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("要删除的状态列表不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (statusList.size() > 10) {
|
||||||
|
throw new IllegalArgumentException("单次最多只能指定10个状态");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证状态值是否有效
|
||||||
|
List<String> validStatuses = List.of("NEW", "USING", "LOGGED_IN", "COMPLETED", "REFUNDED", "EXPIRED");
|
||||||
|
for (String status : statusList) {
|
||||||
|
if (!validStatuses.contains(status)) {
|
||||||
|
throw new IllegalArgumentException("无效的状态值: " + status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 统计要删除的链接数量
|
||||||
|
long totalCount = linkTaskMapper.countByStatusListAndAgentId(statusList, agentId);
|
||||||
|
log.info("用户拥有的指定状态链接数量: {}", totalCount);
|
||||||
|
|
||||||
|
if (totalCount == 0) {
|
||||||
|
// 没有符合条件的链接
|
||||||
|
BatchDeleteResponse response = new BatchDeleteResponse(0, 0, 0,
|
||||||
|
List.of(), List.of(), List.of());
|
||||||
|
log.info("没有找到符合条件的链接");
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询要删除的链接详情(用于记录日志)
|
||||||
|
List<LinkTask> linksToDelete = linkTaskMapper.findByStatusListAndAgentId(statusList, agentId);
|
||||||
|
List<String> codeNosToDelete = linksToDelete.stream()
|
||||||
|
.map(LinkTask::getCodeNo)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
log.info("即将删除的链接: {}", codeNosToDelete);
|
||||||
|
|
||||||
|
// 执行批量删除
|
||||||
|
int deleteCount = linkTaskMapper.batchDeleteByStatusListAndAgentId(statusList, agentId);
|
||||||
|
log.info("批量删除执行结果: 预期删除数量={}, 实际删除数量={}", totalCount, deleteCount);
|
||||||
|
|
||||||
|
// 构建响应
|
||||||
|
List<String> successCodeNos = new ArrayList<>();
|
||||||
|
List<String> failedCodeNos = new ArrayList<>();
|
||||||
|
List<String> failedReasons = new ArrayList<>();
|
||||||
|
|
||||||
|
if (deleteCount == totalCount) {
|
||||||
|
// 全部删除成功
|
||||||
|
successCodeNos.addAll(codeNosToDelete);
|
||||||
|
} else if (deleteCount > 0) {
|
||||||
|
// 部分删除成功(这种情况比较少见,可能是并发操作导致)
|
||||||
|
successCodeNos.addAll(codeNosToDelete.subList(0, deleteCount));
|
||||||
|
failedCodeNos.addAll(codeNosToDelete.subList(deleteCount, codeNosToDelete.size()));
|
||||||
|
for (int i = deleteCount; i < codeNosToDelete.size(); i++) {
|
||||||
|
failedReasons.add("删除操作部分失败");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 全部删除失败
|
||||||
|
failedCodeNos.addAll(codeNosToDelete);
|
||||||
|
for (int i = 0; i < codeNosToDelete.size(); i++) {
|
||||||
|
failedReasons.add("删除操作失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BatchDeleteResponse response = new BatchDeleteResponse(
|
||||||
|
successCodeNos.size(),
|
||||||
|
failedCodeNos.size(),
|
||||||
|
codeNosToDelete.size(),
|
||||||
|
successCodeNos,
|
||||||
|
failedCodeNos,
|
||||||
|
failedReasons
|
||||||
|
);
|
||||||
|
|
||||||
|
log.info("按状态批量删除完成: 总数={}, 成功={}, 失败={}",
|
||||||
|
response.getTotalCount(), response.getSuccessCount(), response.getFailedCount());
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}).subscribeOn(Schedulers.boundedElastic());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 批量删除链接(确保用户只能删除自己的链接)
|
* 批量删除链接(确保用户只能删除自己的链接)
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -218,4 +218,34 @@
|
|||||||
FROM link_task
|
FROM link_task
|
||||||
WHERE machine_id = #{machineId} AND status = #{status}
|
WHERE machine_id = #{machineId} AND status = #{status}
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="findByStatusListAndAgentId" 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, need_refresh, refresh_time, qr_created_at, qr_expire_at, first_region_select_at, completed_points, completion_images
|
||||||
|
FROM link_task
|
||||||
|
WHERE agent_id = #{agentId}
|
||||||
|
AND status IN
|
||||||
|
<foreach collection="statusList" item="status" open="(" close=")" separator=",">
|
||||||
|
#{status}
|
||||||
|
</foreach>
|
||||||
|
ORDER BY created_at DESC
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="countByStatusListAndAgentId" resultType="long">
|
||||||
|
SELECT COUNT(1)
|
||||||
|
FROM link_task
|
||||||
|
WHERE agent_id = #{agentId}
|
||||||
|
AND status IN
|
||||||
|
<foreach collection="statusList" item="status" open="(" close=")" separator=",">
|
||||||
|
#{status}
|
||||||
|
</foreach>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<delete id="batchDeleteByStatusListAndAgentId">
|
||||||
|
DELETE FROM link_task
|
||||||
|
WHERE agent_id = #{agentId}
|
||||||
|
AND status IN
|
||||||
|
<foreach collection="statusList" item="status" open="(" close=")" separator=",">
|
||||||
|
#{status}
|
||||||
|
</foreach>
|
||||||
|
</delete>
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|||||||
82
test_batch_delete_by_status.http
Normal file
82
test_batch_delete_by_status.http
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
### 按狀態批量刪除鏈接接口測試
|
||||||
|
|
||||||
|
# 需要先獲取JWT token
|
||||||
|
POST http://localhost:8080/api/auth/login
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"username": "admin",
|
||||||
|
"password": "admin"
|
||||||
|
}
|
||||||
|
|
||||||
|
### 使用獲取到的token進行按狀態批量刪除
|
||||||
|
|
||||||
|
# 1. 刪除已過期的鏈接
|
||||||
|
POST http://localhost:8080/api/link/batch-delete-by-status
|
||||||
|
Content-Type: application/json
|
||||||
|
Authorization: Bearer {{token}}
|
||||||
|
|
||||||
|
{
|
||||||
|
"statusList": ["EXPIRED"],
|
||||||
|
"confirmDelete": true
|
||||||
|
}
|
||||||
|
|
||||||
|
### 2. 刪除已退款的鏈接
|
||||||
|
POST http://localhost:8080/api/link/batch-delete-by-status
|
||||||
|
Content-Type: application/json
|
||||||
|
Authorization: Bearer {{token}}
|
||||||
|
|
||||||
|
{
|
||||||
|
"statusList": ["REFUNDED"],
|
||||||
|
"confirmDelete": true
|
||||||
|
}
|
||||||
|
|
||||||
|
### 3. 同時刪除多種狀態的鏈接(已過期和已退款)
|
||||||
|
POST http://localhost:8080/api/link/batch-delete-by-status
|
||||||
|
Content-Type: application/json
|
||||||
|
Authorization: Bearer {{token}}
|
||||||
|
|
||||||
|
{
|
||||||
|
"statusList": ["EXPIRED", "REFUNDED"],
|
||||||
|
"confirmDelete": true
|
||||||
|
}
|
||||||
|
|
||||||
|
### 4. 測試錯誤情況:未確認刪除操作
|
||||||
|
POST http://localhost:8080/api/link/batch-delete-by-status
|
||||||
|
Content-Type: application/json
|
||||||
|
Authorization: Bearer {{token}}
|
||||||
|
|
||||||
|
{
|
||||||
|
"statusList": ["EXPIRED"],
|
||||||
|
"confirmDelete": false
|
||||||
|
}
|
||||||
|
|
||||||
|
### 5. 測試錯誤情況:無效的狀態值
|
||||||
|
POST http://localhost:8080/api/link/batch-delete-by-status
|
||||||
|
Content-Type: application/json
|
||||||
|
Authorization: Bearer {{token}}
|
||||||
|
|
||||||
|
{
|
||||||
|
"statusList": ["INVALID_STATUS"],
|
||||||
|
"confirmDelete": true
|
||||||
|
}
|
||||||
|
|
||||||
|
### 6. 測試錯誤情況:空狀態列表
|
||||||
|
POST http://localhost:8080/api/link/batch-delete-by-status
|
||||||
|
Content-Type: application/json
|
||||||
|
Authorization: Bearer {{token}}
|
||||||
|
|
||||||
|
{
|
||||||
|
"statusList": [],
|
||||||
|
"confirmDelete": true
|
||||||
|
}
|
||||||
|
|
||||||
|
### 7. 刪除新建狀態的鏈接(謹慎使用)
|
||||||
|
POST http://localhost:8080/api/link/batch-delete-by-status
|
||||||
|
Content-Type: application/json
|
||||||
|
Authorization: Bearer {{token}}
|
||||||
|
|
||||||
|
{
|
||||||
|
"statusList": ["NEW"],
|
||||||
|
"confirmDelete": true
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user