feat(aihr): support cancelling running local import tasks

新增 POST /api/knowledge/doc/import-tasks/{id}/cancel,后台目录导入任务
运行中可取消;资料处理页任务列表接取消按钮与状态刷新。
This commit is contained in:
2026-07-03 21:45:38 +08:00
parent b9a50398d8
commit 939fba85ff
6 changed files with 83 additions and 4 deletions
@@ -13,6 +13,7 @@ import org.dromara.aihr.domain.AihrSopDto.VectorizeResponse;
import org.dromara.aihr.service.AihrSopSeedService;
import org.dromara.common.core.domain.R;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestPart;
@@ -73,6 +74,11 @@ public class AihrSopController {
return R.ok(sopSeedService.localImportTasks());
}
@PostMapping("/doc/import-tasks/{id}/cancel")
public R<LocalImportTaskResponse> cancelLocalImportTask(@PathVariable Long id) {
return R.ok(sopSeedService.cancelLocalImportTask(id));
}
@GetMapping("/processing/overview")
public R<ProcessingOverviewResponse> processingOverview() {
return R.ok(sopSeedService.processingOverview());
@@ -253,6 +253,18 @@ public class AihrSopSeedService {
}
}
public LocalImportTaskResponse cancelLocalImportTask(Long taskId) {
if (taskId == null) {
throw new IllegalArgumentException("任务 ID 不能为空");
}
jdbcTemplate.update("""
update aihr_knowledge_import_task
set status = 4, current_file = '', finished_time = now(), update_time = now(), remark = '用户已取消'
where tenant_id = ? and id = ? and status = 1
""", TENANT_ID, taskId);
return localImportTask(taskId).orElseThrow(() -> new IllegalArgumentException("导入任务不存在"));
}
private void runLocalImportTask(long taskId, LocalImportPlan plan) {
try {
if (plan.files().isEmpty()) {
@@ -260,10 +272,16 @@ public class AihrSopSeedService {
return;
}
LocalImportRun run = executeLocalImport(plan, taskId);
if (isLocalImportTaskCanceled(taskId)) {
return;
}
boolean allFailed = run.failed() > 0 && run.imported() == 0;
String remark = run.failed() == 0 ? "导入完成" : allFailed ? "全部文件导入失败,可重试同一目录" : "部分文件导入失败,可重试同一目录";
finishLocalImportTask(taskId, allFailed ? 3 : 2, run.imported(), run.failed(), remark);
} catch (Exception e) {
if (isLocalImportTaskCanceled(taskId)) {
return;
}
finishLocalImportTask(taskId, 3, 0, 0, e.getMessage());
}
}
@@ -273,6 +291,9 @@ public class AihrSopSeedService {
int imported = 0;
int failed = 0;
for (Path path : plan.files()) {
if (taskId != null && isLocalImportTaskCanceled(taskId)) {
break;
}
String fileName = path.getFileName().toString();
if (taskId != null) {
updateLocalImportTask(taskId, 1, imported, failed, fileName, "处理中");
@@ -375,7 +396,7 @@ public class AihrSopSeedService {
jdbcTemplate.update("""
update aihr_knowledge_import_task
set status = ?, imported_files = ?, failed_files = ?, current_file = ?, update_time = now(), remark = ?
where tenant_id = ? and id = ?
where tenant_id = ? and id = ? and status <> 4
""", status, imported, failed, currentFile, limitRemark(remark), TENANT_ID, taskId);
}
@@ -383,10 +404,23 @@ public class AihrSopSeedService {
jdbcTemplate.update("""
update aihr_knowledge_import_task
set status = ?, imported_files = ?, failed_files = ?, current_file = '', finished_time = now(), update_time = now(), remark = ?
where tenant_id = ? and id = ?
where tenant_id = ? and id = ? and status <> 4
""", status, imported, failed, limitRemark(remark), TENANT_ID, taskId);
}
private boolean isLocalImportTaskCanceled(long taskId) {
try {
Integer count = jdbcTemplate.queryForObject("""
select count(1)
from aihr_knowledge_import_task
where tenant_id = ? and id = ? and status = 4
""", Integer.class, TENANT_ID, taskId);
return count != null && count > 0;
} catch (DataAccessException e) {
return false;
}
}
private LocalImportTaskResponse importTaskResponse(long id, String directory, String category, int status, int total, int imported, int failed, String currentFile, Timestamp createTime, Timestamp updateTime, String remark) {
return new LocalImportTaskResponse(
id,
@@ -1121,6 +1155,7 @@ public class AihrSopSeedService {
case 1 -> "导入中";
case 2 -> failed > 0 ? "部分失败" : "已完成";
case 3 -> "失败";
case 4 -> "已取消";
default -> "等待中";
};
}
@@ -1132,6 +1167,9 @@ public class AihrSopSeedService {
if (status == 2 && failed == 0) {
return "success";
}
if (status == 4) {
return "info";
}
return status == 3 ? "danger" : "warning";
}
+1 -1
View File
@@ -73,7 +73,7 @@ CREATE TABLE IF NOT EXISTS `aihr_knowledge_import_task` (
`tenant_id` varchar(20) DEFAULT '000000' COMMENT '租户编号',
`directory` varchar(500) NOT NULL COMMENT '导入相对目录',
`category` varchar(100) NOT NULL COMMENT '知识库分类',
`status` tinyint DEFAULT 0 COMMENT '任务状态: 0等待, 1运行中, 2完成, 3失败',
`status` tinyint DEFAULT 0 COMMENT '任务状态: 0等待, 1运行中, 2完成, 3失败, 4取消',
`total_files` int DEFAULT 0 COMMENT '发现文件数',
`imported_files` int DEFAULT 0 COMMENT '已导入文件数',
`failed_files` int DEFAULT 0 COMMENT '失败文件数',