From 96e93944d92aa48ee6ea4d2ac4818d5538e3faac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E8=87=AA=E8=BE=BE?= <980324341@qq.com> Date: Wed, 9 Sep 2026 18:59:45 +0800 Subject: [PATCH] =?UTF-8?q?fix(patrol-delete):=20=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E6=9D=A1=E4=BB=B6=E4=B8=BA=E7=A9=BA=E7=9A=84=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E5=9B=9B=E5=B1=82=E6=8B=A6=E6=88=AA=E2=80=94=E2=80=94=E2=91=A0?= =?UTF-8?q?=E5=89=8D=E7=AB=AF=E5=90=AF=E5=8A=A8=E5=89=8D=E6=8B=A6=E6=88=AA?= =?UTF-8?q?(=E4=B8=8D=E5=86=8D=E5=85=88=E5=88=9B=E5=BB=BA=E5=90=8E?= =?UTF-8?q?=E5=A4=B1=E8=B4=A5,=E9=81=BF=E5=85=8D=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E6=AE=8B=E7=95=99=E6=89=A7=E8=A1=8C=E4=B8=AD)=E5=B9=B6?= =?UTF-8?q?=E5=88=9B=E5=BB=BA=E6=97=B6=E4=B8=8A=E4=BC=A0delete=5Fcondition?= =?UTF-8?q?s=20=E2=91=A1Java=E6=9C=8D=E5=8A=A1=E7=AB=AF=E6=A0=A1=E9=AA=8C?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=9D=A1=E4=BB=B6=E9=9D=9E=E7=A9=BA(?= =?UTF-8?q?=E6=97=A7=E7=89=88=E6=9C=AC/=E7=9B=B4=E8=B0=83=E5=85=9C?= =?UTF-8?q?=E5=BA=95)=20=E2=91=A2Python=E7=AB=AF=E7=A9=BA=E6=9D=A1?= =?UTF-8?q?=E4=BB=B6=E7=9B=B4=E6=8E=A5=E6=8C=89=E5=A4=B1=E8=B4=A5=E4=B8=8A?= =?UTF-8?q?=E6=8A=A5,=E4=B8=8D=E5=86=8D=E9=80=90=E5=BA=97=E7=A9=BA?= =?UTF-8?q?=E8=BD=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/dto/PatrolDeleteCreateTaskRequest.java | 6 ++++++ .../patroldelete/service/PatrolDeleteTaskService.java | 5 +++++ .../src/pages/brand/components/BrandPatrolDeleteTab.vue | 8 +++++++- frontend-vue/src/shared/api/types/modules/withdraw.ts | 9 +++++++-- 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/backend-java/src/main/java/com/nanri/aiimage/modules/patroldelete/model/dto/PatrolDeleteCreateTaskRequest.java b/backend-java/src/main/java/com/nanri/aiimage/modules/patroldelete/model/dto/PatrolDeleteCreateTaskRequest.java index 94a67dd4..71f455ce 100644 --- a/backend-java/src/main/java/com/nanri/aiimage/modules/patroldelete/model/dto/PatrolDeleteCreateTaskRequest.java +++ b/backend-java/src/main/java/com/nanri/aiimage/modules/patroldelete/model/dto/PatrolDeleteCreateTaskRequest.java @@ -23,4 +23,10 @@ public class PatrolDeleteCreateTaskRequest { @NotEmpty @Schema(description = "待创建的店铺任务列表,通常由已匹配成功的店铺组成", requiredMode = Schema.RequiredMode.REQUIRED) private List items = new ArrayList<>(); + + @NotNull + @NotEmpty + @JsonProperty("delete_conditions") + @Schema(description = "删除条件(如:定价问题/需要批准/缺少报价…),为空时任务无可执行内容", requiredMode = Schema.RequiredMode.REQUIRED) + private List deleteConditions = new ArrayList<>(); } diff --git a/backend-java/src/main/java/com/nanri/aiimage/modules/patroldelete/service/PatrolDeleteTaskService.java b/backend-java/src/main/java/com/nanri/aiimage/modules/patroldelete/service/PatrolDeleteTaskService.java index 97179cec..5713d699 100644 --- a/backend-java/src/main/java/com/nanri/aiimage/modules/patroldelete/service/PatrolDeleteTaskService.java +++ b/backend-java/src/main/java/com/nanri/aiimage/modules/patroldelete/service/PatrolDeleteTaskService.java @@ -280,6 +280,11 @@ public class PatrolDeleteTaskService { if (request.getItems() == null || request.getItems().isEmpty()) { throw new BusinessException("items 不能为空"); } + // 删除条件为空时任务没有可执行的判定规则(Python 端会无事可做、一直停在执行中), + // 必须在此拦截;前端亦在创建前拦截,此处为服务端兜底(直调 API/旧客户端场景) + if (request.getDeleteConditions() == null || request.getDeleteConditions().isEmpty()) { + throw new BusinessException("删除条件不能为空,请先选择删除条件"); + } List uniqueItems = dedupeItems(request.getItems()); if (uniqueItems.isEmpty()) { diff --git a/frontend-vue/src/pages/brand/components/BrandPatrolDeleteTab.vue b/frontend-vue/src/pages/brand/components/BrandPatrolDeleteTab.vue index a0895687..6728ca94 100644 --- a/frontend-vue/src/pages/brand/components/BrandPatrolDeleteTab.vue +++ b/frontend-vue/src/pages/brand/components/BrandPatrolDeleteTab.vue @@ -1062,8 +1062,14 @@ async function processQueue() { ElMessage.warning("请先匹配可用店铺"); return; } + if (!selectedDeleteConditions().length) { + // 删除条件为空时任务没有可执行的判定规则,必须在创建任务前拦截, + // 否则 Java 已创建(RUNNING)而 Python 端无事可做,任务会一直停在执行中 + ElMessage.warning("请先选择删除条件"); + return; + } const created = await withTransientRetry( - () => createPatrolDeleteTask(runnable.map(buildTaskItem)), + () => createPatrolDeleteTask(runnable.map(buildTaskItem), selectedDeleteConditions()), (attempt, maxAttempts) => { queuePushResult.value = `服务暂时不可用,正在重试创建任务(${attempt}/${maxAttempts})...`; }, diff --git a/frontend-vue/src/shared/api/types/modules/withdraw.ts b/frontend-vue/src/shared/api/types/modules/withdraw.ts index 334c4c4b..5a85382e 100644 --- a/frontend-vue/src/shared/api/types/modules/withdraw.ts +++ b/frontend-vue/src/shared/api/types/modules/withdraw.ts @@ -449,14 +449,19 @@ export function getPatrolDeleteTaskProgressBatch(taskIds: number[]) { ); } -export function createPatrolDeleteTask(items: PatrolDeleteTaskItem[]) { +export function createPatrolDeleteTask( + items: PatrolDeleteTaskItem[], + deleteConditions: unknown[] = [], +) { return unwrapJavaResponse( post< JavaApiResponse, - { user_id: number; items: PatrolDeleteTaskItem[] } + { user_id: number; items: PatrolDeleteTaskItem[]; delete_conditions: unknown[] } >(`${JAVA_API_PREFIX}/patrol-delete/tasks`, { user_id: getCurrentUserId(), items, + // 服务端校验删除条件非空(创建即 RUNNING,空条件的任务 Python 端无内容可执行) + delete_conditions: deleteConditions, }), ); }