feat(web): 增强任务治理与系统诊断能力
新增任务持久化、筛选分页、取消任务、健康检查与 AI 输入校验,并完善前端历史管理交互与容错重试机制。补充对应单元测试,提升系统稳定性和可运维性。
This commit is contained in:
81
src/main/java/com/svnlog/web/service/HealthService.java
Normal file
81
src/main/java/com/svnlog/web/service/HealthService.java
Normal file
@@ -0,0 +1,81 @@
|
||||
package com.svnlog.web.service;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.time.Instant;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.svnlog.web.model.TaskInfo;
|
||||
import com.svnlog.web.model.TaskStatus;
|
||||
|
||||
@Service
|
||||
public class HealthService {
|
||||
|
||||
private final OutputFileService outputFileService;
|
||||
private final SettingsService settingsService;
|
||||
private final TaskService taskService;
|
||||
|
||||
public HealthService(OutputFileService outputFileService,
|
||||
SettingsService settingsService,
|
||||
TaskService taskService) {
|
||||
this.outputFileService = outputFileService;
|
||||
this.settingsService = settingsService;
|
||||
this.taskService = taskService;
|
||||
}
|
||||
|
||||
public Map<String, Object> basicHealth() {
|
||||
final Map<String, Object> response = new HashMap<String, Object>();
|
||||
response.put("status", "ok");
|
||||
response.put("timestamp", Instant.now().toString());
|
||||
return response;
|
||||
}
|
||||
|
||||
public Map<String, Object> detailedHealth() throws IOException {
|
||||
final Map<String, Object> result = new HashMap<String, Object>();
|
||||
final Map<String, Object> settings = settingsService.getSettings();
|
||||
final Path outputRoot = outputFileService.getOutputRoot();
|
||||
|
||||
final boolean outputDirWritable = ensureWritable(outputRoot);
|
||||
int running = 0;
|
||||
int failed = 0;
|
||||
int cancelled = 0;
|
||||
for (TaskInfo task : taskService.getTasks()) {
|
||||
if (task.getStatus() == TaskStatus.RUNNING || task.getStatus() == TaskStatus.PENDING) {
|
||||
running++;
|
||||
}
|
||||
if (task.getStatus() == TaskStatus.FAILED) {
|
||||
failed++;
|
||||
}
|
||||
if (task.getStatus() == TaskStatus.CANCELLED) {
|
||||
cancelled++;
|
||||
}
|
||||
}
|
||||
|
||||
result.put("status", "ok");
|
||||
result.put("timestamp", Instant.now().toString());
|
||||
result.put("outputDir", outputRoot.toString());
|
||||
result.put("outputDirWritable", outputDirWritable);
|
||||
result.put("apiKeyConfigured", Boolean.TRUE.equals(settings.get("apiKeyConfigured")));
|
||||
result.put("taskTotal", taskService.getTasks().size());
|
||||
result.put("taskRunning", running);
|
||||
result.put("taskFailed", failed);
|
||||
result.put("taskCancelled", cancelled);
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean ensureWritable(Path outputRoot) {
|
||||
try {
|
||||
Files.createDirectories(outputRoot);
|
||||
final Path probe = outputRoot.resolve(".health-probe");
|
||||
Files.write(probe, "ok".getBytes("UTF-8"));
|
||||
Files.deleteIfExists(probe);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user