完善多店铺开启多窗口、外观进度条等
This commit is contained in:
+28
@@ -1,10 +1,12 @@
|
||||
package com.nanri.aiimage.modules.patroldelete.controller;
|
||||
|
||||
import com.nanri.aiimage.common.api.ApiResponse;
|
||||
import com.nanri.aiimage.modules.patroldelete.model.dto.PatrolDeleteConditionAddRequest;
|
||||
import com.nanri.aiimage.modules.patroldelete.model.dto.PatrolDeleteCreateTaskRequest;
|
||||
import com.nanri.aiimage.modules.patroldelete.model.dto.PatrolDeleteSubmitResultRequest;
|
||||
import com.nanri.aiimage.modules.patroldelete.model.dto.PatrolDeleteTaskBatchRequest;
|
||||
import com.nanri.aiimage.modules.patroldelete.model.vo.PatrolDeleteCreateTaskVo;
|
||||
import com.nanri.aiimage.modules.patroldelete.model.vo.PatrolDeleteConditionVo;
|
||||
import com.nanri.aiimage.modules.patroldelete.model.vo.PatrolDeleteHistoryVo;
|
||||
import com.nanri.aiimage.modules.patroldelete.model.vo.PatrolDeleteTaskBatchVo;
|
||||
import com.nanri.aiimage.modules.patroldelete.service.PatrolDeleteResolveService;
|
||||
@@ -92,6 +94,32 @@ public class PatrolDeleteController {
|
||||
return ApiResponse.success(null);
|
||||
}
|
||||
|
||||
@GetMapping("/conditions")
|
||||
@Operation(summary = "查询删除条件", description = "返回当前用户保存的巡店删除条件。")
|
||||
public ApiResponse<List<PatrolDeleteConditionVo>> listConditions(
|
||||
@Parameter(name = "user_id", description = "当前用户 ID", required = true, in = ParameterIn.QUERY, example = "1")
|
||||
@RequestParam("user_id") Long userId) {
|
||||
return ApiResponse.success(patrolDeleteResolveService.listConditions(userId));
|
||||
}
|
||||
|
||||
@PostMapping("/conditions")
|
||||
@Operation(summary = "新增删除条件", description = "保存一条当前用户可复用的巡店删除条件。")
|
||||
public ApiResponse<PatrolDeleteConditionVo> addCondition(
|
||||
@Valid @RequestBody PatrolDeleteConditionAddRequest request) {
|
||||
return ApiResponse.success(patrolDeleteResolveService.addCondition(request));
|
||||
}
|
||||
|
||||
@DeleteMapping("/conditions/{id}")
|
||||
@Operation(summary = "删除删除条件", description = "删除当前用户名下的一条巡店删除条件。")
|
||||
public ApiResponse<Void> deleteCondition(
|
||||
@Parameter(description = "删除条件主键", example = "10")
|
||||
@PathVariable Long id,
|
||||
@Parameter(name = "user_id", description = "当前用户 ID", required = true, in = ParameterIn.QUERY, example = "1")
|
||||
@RequestParam("user_id") Long userId) {
|
||||
patrolDeleteResolveService.deleteCondition(userId, id);
|
||||
return ApiResponse.success(null);
|
||||
}
|
||||
|
||||
@PostMapping("/match-shops")
|
||||
@Operation(summary = "批量匹配店铺", description = "根据店铺名批量匹配紫鸟店铺索引,返回是否命中、店铺 ID、平台、公司和匹配状态。")
|
||||
public ApiResponse<ProductRiskMatchShopsVo> matchShops(
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package com.nanri.aiimage.modules.patroldelete.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.nanri.aiimage.modules.patroldelete.model.entity.PatrolDeleteConditionEntity;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface PatrolDeleteConditionMapper extends BaseMapper<PatrolDeleteConditionEntity> {
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package com.nanri.aiimage.modules.patroldelete.model.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@Schema(description = "巡店删除条件新增请求")
|
||||
public class PatrolDeleteConditionAddRequest {
|
||||
|
||||
@NotNull
|
||||
@JsonProperty("user_id")
|
||||
@Schema(description = "当前用户 ID", example = "1", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Long userId;
|
||||
|
||||
@NotBlank
|
||||
@JsonProperty("condition_text")
|
||||
@Schema(description = "删除条件文本", example = "删除商品信息草稿", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String conditionText;
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package com.nanri.aiimage.modules.patroldelete.model.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
@TableName("biz_patrol_delete_condition")
|
||||
public class PatrolDeleteConditionEntity {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
private Long userId;
|
||||
private String conditionText;
|
||||
private LocalDateTime createdAt;
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package com.nanri.aiimage.modules.patroldelete.model.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
public class PatrolDeleteConditionVo {
|
||||
|
||||
private Long id;
|
||||
|
||||
@JsonProperty("conditionText")
|
||||
private String conditionText;
|
||||
|
||||
private LocalDateTime createdAt;
|
||||
}
|
||||
+66
@@ -2,8 +2,12 @@ package com.nanri.aiimage.modules.patroldelete.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.nanri.aiimage.common.exception.BusinessException;
|
||||
import com.nanri.aiimage.modules.patroldelete.mapper.PatrolDeleteConditionMapper;
|
||||
import com.nanri.aiimage.modules.patroldelete.mapper.PatrolDeleteShopCandidateMapper;
|
||||
import com.nanri.aiimage.modules.patroldelete.model.dto.PatrolDeleteConditionAddRequest;
|
||||
import com.nanri.aiimage.modules.patroldelete.model.entity.PatrolDeleteConditionEntity;
|
||||
import com.nanri.aiimage.modules.patroldelete.model.entity.PatrolDeleteShopCandidateEntity;
|
||||
import com.nanri.aiimage.modules.patroldelete.model.vo.PatrolDeleteConditionVo;
|
||||
import com.nanri.aiimage.modules.productrisk.model.dto.ProductRiskCandidateAddRequest;
|
||||
import com.nanri.aiimage.modules.productrisk.model.dto.ProductRiskMatchShopsRequest;
|
||||
import com.nanri.aiimage.modules.productrisk.model.vo.ProductRiskCandidateVo;
|
||||
@@ -27,6 +31,7 @@ import java.util.Objects;
|
||||
public class PatrolDeleteResolveService {
|
||||
|
||||
private final PatrolDeleteShopCandidateMapper candidateMapper;
|
||||
private final PatrolDeleteConditionMapper conditionMapper;
|
||||
private final ZiniaoShopSwitchService ziniaoShopSwitchService;
|
||||
|
||||
public List<ProductRiskCandidateVo> listCandidates(Long userId) {
|
||||
@@ -127,6 +132,67 @@ public class PatrolDeleteResolveService {
|
||||
return count == null ? 0L : count;
|
||||
}
|
||||
|
||||
public List<PatrolDeleteConditionVo> listConditions(Long userId) {
|
||||
validateUserId(userId);
|
||||
List<PatrolDeleteConditionEntity> rows = conditionMapper.selectList(
|
||||
new LambdaQueryWrapper<PatrolDeleteConditionEntity>()
|
||||
.eq(PatrolDeleteConditionEntity::getUserId, userId)
|
||||
.orderByDesc(PatrolDeleteConditionEntity::getId));
|
||||
List<PatrolDeleteConditionVo> list = new ArrayList<>();
|
||||
for (PatrolDeleteConditionEntity row : rows) {
|
||||
list.add(toConditionVo(row));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public PatrolDeleteConditionVo addCondition(PatrolDeleteConditionAddRequest request) {
|
||||
validateUserId(request.getUserId());
|
||||
String text = normalizeConditionText(request.getConditionText());
|
||||
if (text.isBlank()) {
|
||||
throw new BusinessException("删除条件不能为空");
|
||||
}
|
||||
PatrolDeleteConditionEntity existing = conditionMapper.selectOne(
|
||||
new LambdaQueryWrapper<PatrolDeleteConditionEntity>()
|
||||
.eq(PatrolDeleteConditionEntity::getUserId, request.getUserId())
|
||||
.eq(PatrolDeleteConditionEntity::getConditionText, text)
|
||||
.last("limit 1"));
|
||||
if (existing != null) {
|
||||
return toConditionVo(existing);
|
||||
}
|
||||
PatrolDeleteConditionEntity entity = new PatrolDeleteConditionEntity();
|
||||
entity.setUserId(request.getUserId());
|
||||
entity.setConditionText(text);
|
||||
entity.setCreatedAt(LocalDateTime.now());
|
||||
conditionMapper.insert(entity);
|
||||
return toConditionVo(entity);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void deleteCondition(Long userId, Long id) {
|
||||
validateUserId(userId);
|
||||
if (id == null || id <= 0) {
|
||||
throw new BusinessException("id 不合法");
|
||||
}
|
||||
PatrolDeleteConditionEntity row = conditionMapper.selectById(id);
|
||||
if (row == null || !userId.equals(row.getUserId())) {
|
||||
throw new BusinessException("记录不存在");
|
||||
}
|
||||
conditionMapper.deleteById(id);
|
||||
}
|
||||
|
||||
private PatrolDeleteConditionVo toConditionVo(PatrolDeleteConditionEntity row) {
|
||||
PatrolDeleteConditionVo vo = new PatrolDeleteConditionVo();
|
||||
vo.setId(row.getId());
|
||||
vo.setConditionText(row.getConditionText());
|
||||
vo.setCreatedAt(row.getCreatedAt());
|
||||
return vo;
|
||||
}
|
||||
|
||||
private String normalizeConditionText(String value) {
|
||||
return value == null ? "" : value.trim();
|
||||
}
|
||||
|
||||
private ProductRiskShopQueueItemVo matchOneShop(String shopName) {
|
||||
ProductRiskShopQueueItemVo item = new ProductRiskShopQueueItemVo();
|
||||
item.setShopName(shopName);
|
||||
|
||||
+39
-12
@@ -149,11 +149,16 @@ public class PatrolDeleteTaskService {
|
||||
|
||||
Map<Long, FileTaskEntity> taskMap = loadTaskMap(entities);
|
||||
Map<Long, Map<Long, PatrolDeleteResultItemVo>> snapshotMap = buildSnapshotMap(taskMap);
|
||||
Map<Long, TaskFileJobEntity> jobMap = taskFileJobService.findAssembleJobsByResultIds(MODULE_TYPE, entities.stream()
|
||||
.map(FileResultEntity::getId)
|
||||
.filter(id -> id != null && id > 0)
|
||||
.distinct()
|
||||
.toList());
|
||||
List<PatrolDeleteResultItemVo> items = new ArrayList<>();
|
||||
for (FileResultEntity entity : entities) {
|
||||
FileTaskEntity task = taskMap.get(entity.getTaskId());
|
||||
PatrolDeleteResultItemVo snapshot = snapshotMap.getOrDefault(entity.getTaskId(), Map.of()).get(entity.getId());
|
||||
items.add(toHistoryItem(entity, task, snapshot));
|
||||
items.add(toHistoryItem(entity, task, snapshot, jobMap.get(entity.getId())));
|
||||
}
|
||||
vo.setItems(items);
|
||||
return vo;
|
||||
@@ -183,6 +188,11 @@ public class PatrolDeleteTaskService {
|
||||
for (FileResultEntity row : rows) {
|
||||
rowsByTaskId.computeIfAbsent(row.getTaskId(), ignored -> new ArrayList<>()).add(row);
|
||||
}
|
||||
Map<Long, TaskFileJobEntity> jobMap = taskFileJobService.findAssembleJobsByResultIds(MODULE_TYPE, rows.stream()
|
||||
.map(FileResultEntity::getId)
|
||||
.filter(id -> id != null && id > 0)
|
||||
.distinct()
|
||||
.toList());
|
||||
|
||||
for (Long taskId : normalizedTaskIds) {
|
||||
FileTaskEntity task = taskMap.get(taskId);
|
||||
@@ -195,7 +205,7 @@ public class PatrolDeleteTaskService {
|
||||
batch.getMissingTaskIds().add(taskId);
|
||||
continue;
|
||||
}
|
||||
batch.getItems().addAll(buildProgressItems(task, taskRows));
|
||||
batch.getItems().addAll(buildProgressItems(task, taskRows, jobMap));
|
||||
}
|
||||
return batch;
|
||||
}
|
||||
@@ -252,8 +262,6 @@ public class PatrolDeleteTaskService {
|
||||
task.setCreatedAt(now);
|
||||
task.setUpdatedAt(now);
|
||||
fileTaskMapper.insert(task);
|
||||
taskCacheService.saveTaskCache(task);
|
||||
taskCacheService.touchTaskHeartbeat(task.getId());
|
||||
|
||||
List<PatrolDeleteResultItemVo> snapshots = new ArrayList<>();
|
||||
for (PatrolDeleteTaskItemDto item : uniqueItems) {
|
||||
@@ -272,9 +280,6 @@ public class PatrolDeleteTaskService {
|
||||
fileResultMapper.insert(result);
|
||||
snapshots.add(toSnapshotVo(result, item, task.getStatus(), null));
|
||||
}
|
||||
persistTaskJson(task, uniqueItems, snapshots);
|
||||
taskCacheService.saveTaskCache(task);
|
||||
|
||||
PatrolDeleteCreateTaskVo vo = new PatrolDeleteCreateTaskVo();
|
||||
vo.setTaskId(task.getId());
|
||||
vo.setItems(snapshots);
|
||||
@@ -291,7 +296,8 @@ public class PatrolDeleteTaskService {
|
||||
|
||||
FileTaskEntity task = loadTaskForExecution(taskId);
|
||||
if (task == null || !MODULE_TYPE.equals(task.getModuleType())) {
|
||||
throw new BusinessException("任务不存在");
|
||||
log.info("[patrol-delete] ignore result callback for deleted task taskId={}", taskId);
|
||||
return;
|
||||
}
|
||||
if ("SUCCESS".equals(task.getStatus()) || "FAILED".equals(task.getStatus())) {
|
||||
throw new BusinessException("任务已结束,拒绝重复提交");
|
||||
@@ -419,6 +425,7 @@ public class PatrolDeleteTaskService {
|
||||
fileResultMapper.delete(new LambdaQueryWrapper<FileResultEntity>()
|
||||
.eq(FileResultEntity::getTaskId, taskId)
|
||||
.eq(FileResultEntity::getModuleType, MODULE_TYPE));
|
||||
cleanupTaskAuxiliaryData(taskId);
|
||||
fileTaskMapper.deleteById(taskId);
|
||||
taskCacheService.deleteTaskCache(taskId);
|
||||
}
|
||||
@@ -432,6 +439,7 @@ public class PatrolDeleteTaskService {
|
||||
}
|
||||
Long taskId = entity.getTaskId();
|
||||
fileResultMapper.deleteById(resultId);
|
||||
cleanupResultAuxiliaryData(taskId, resultId);
|
||||
reconcileTaskAfterResultRemoval(taskId);
|
||||
}
|
||||
|
||||
@@ -445,6 +453,7 @@ public class PatrolDeleteTaskService {
|
||||
}
|
||||
List<FileResultEntity> rows = listTaskRows(taskId);
|
||||
if (rows.isEmpty()) {
|
||||
cleanupTaskAuxiliaryData(taskId);
|
||||
fileTaskMapper.deleteById(taskId);
|
||||
taskCacheService.deleteTaskCache(taskId);
|
||||
return;
|
||||
@@ -455,6 +464,17 @@ public class PatrolDeleteTaskService {
|
||||
taskCacheService.saveTaskCache(task);
|
||||
}
|
||||
|
||||
private void cleanupTaskAuxiliaryData(Long taskId) {
|
||||
taskResultItemService.deleteTaskItems(taskId, MODULE_TYPE);
|
||||
taskProgressSnapshotService.delete(taskId, MODULE_TYPE);
|
||||
taskFileJobService.deleteTaskJobs(taskId, MODULE_TYPE);
|
||||
}
|
||||
|
||||
private void cleanupResultAuxiliaryData(Long taskId, Long resultId) {
|
||||
taskResultItemService.deleteResultItem(taskId, MODULE_TYPE, resultId);
|
||||
taskFileJobService.deleteResultJobs(taskId, MODULE_TYPE, resultId);
|
||||
}
|
||||
|
||||
private long countTasks(Long userId, List<String> statuses) {
|
||||
Long count = fileTaskMapper.selectCount(new LambdaQueryWrapper<FileTaskEntity>()
|
||||
.eq(FileTaskEntity::getModuleType, MODULE_TYPE)
|
||||
@@ -517,6 +537,10 @@ public class PatrolDeleteTaskService {
|
||||
}
|
||||
|
||||
private PatrolDeleteResultItemVo toHistoryItem(FileResultEntity entity, FileTaskEntity task, PatrolDeleteResultItemVo snapshot) {
|
||||
return toHistoryItem(entity, task, snapshot, null);
|
||||
}
|
||||
|
||||
private PatrolDeleteResultItemVo toHistoryItem(FileResultEntity entity, FileTaskEntity task, PatrolDeleteResultItemVo snapshot, TaskFileJobEntity job) {
|
||||
PatrolDeleteResultItemVo item = snapshot != null ? snapshot : new PatrolDeleteResultItemVo();
|
||||
item.setResultId(entity.getId());
|
||||
item.setTaskId(entity.getTaskId());
|
||||
@@ -529,7 +553,7 @@ public class PatrolDeleteTaskService {
|
||||
item.setFinishedAt(task != null ? task.getFinishedAt() : item.getFinishedAt());
|
||||
item.setOutputFilename(firstNonBlank(item.getOutputFilename(), entity.getResultFilename()));
|
||||
item.setDownloadUrl(null);
|
||||
attachFileJobState(item, entity);
|
||||
attachFileJobState(item, entity, job);
|
||||
if (item.getCountrySections() == null) {
|
||||
item.setCountrySections(new ArrayList<>());
|
||||
}
|
||||
@@ -540,7 +564,10 @@ public class PatrolDeleteTaskService {
|
||||
}
|
||||
|
||||
private void attachFileJobState(PatrolDeleteResultItemVo item, FileResultEntity entity) {
|
||||
TaskFileJobEntity job = taskFileJobService.findAssembleJob(entity.getTaskId(), MODULE_TYPE, entity.getId());
|
||||
attachFileJobState(item, entity, taskFileJobService.findAssembleJob(entity.getTaskId(), MODULE_TYPE, entity.getId()));
|
||||
}
|
||||
|
||||
private void attachFileJobState(PatrolDeleteResultItemVo item, FileResultEntity entity, TaskFileJobEntity job) {
|
||||
item.setFileReady(!blank(entity.getResultFileUrl()));
|
||||
if (job == null) {
|
||||
item.setFileStatus(Boolean.TRUE.equals(item.getFileReady()) ? "SUCCESS" : null);
|
||||
@@ -612,7 +639,7 @@ public class PatrolDeleteTaskService {
|
||||
return list;
|
||||
}
|
||||
|
||||
private List<PatrolDeleteResultItemVo> buildProgressItems(FileTaskEntity task, List<FileResultEntity> rows) {
|
||||
private List<PatrolDeleteResultItemVo> buildProgressItems(FileTaskEntity task, List<FileResultEntity> rows, Map<Long, TaskFileJobEntity> jobMap) {
|
||||
List<PatrolDeleteResultItemVo> list = new ArrayList<>();
|
||||
for (FileResultEntity row : rows) {
|
||||
PatrolDeleteResultItemVo item = new PatrolDeleteResultItemVo();
|
||||
@@ -627,7 +654,7 @@ public class PatrolDeleteTaskService {
|
||||
item.setFinishedAt(task == null ? null : task.getFinishedAt());
|
||||
item.setOutputFilename(row.getResultFilename());
|
||||
item.setDownloadUrl(null);
|
||||
attachFileJobState(item, row);
|
||||
attachFileJobState(item, row, jobMap == null ? null : jobMap.get(row.getId()));
|
||||
list.add(item);
|
||||
}
|
||||
return list;
|
||||
|
||||
Reference in New Issue
Block a user