RunHistoryController.java 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. package com.agent.management.controller;
  2. import com.agent.management.common.Result;
  3. import com.agent.management.model.entity.Workflow;
  4. import com.agent.management.model.entity.WorkflowRun;
  5. import com.agent.management.model.entity.WorkflowRunNode;
  6. import com.agent.management.model.vo.TagBriefVO;
  7. import com.agent.management.repository.WorkflowRepository;
  8. import com.agent.management.repository.WorkflowRunNodeRepository;
  9. import com.agent.management.repository.WorkflowRunRepository;
  10. import com.agent.management.service.TagService;
  11. import lombok.Data;
  12. import lombok.RequiredArgsConstructor;
  13. import org.springframework.web.bind.annotation.*;
  14. import java.util.*;
  15. import java.util.stream.Collectors;
  16. /**
  17. * 运行记录查询 API
  18. */
  19. @RestController
  20. @RequestMapping("/api/run-history")
  21. @RequiredArgsConstructor
  22. public class RunHistoryController {
  23. private final WorkflowRunRepository runRepo;
  24. private final WorkflowRunNodeRepository runNodeRepo;
  25. private final WorkflowRepository workflowRepo;
  26. private final TagService tagService;
  27. /**
  28. * 获取所有工作流的运行记录(按工作流分组)
  29. */
  30. @GetMapping("/workflows")
  31. public Result<List<WorkflowWithRunsVO>> listWorkflowsWithRuns() {
  32. List<WorkflowRun> allRuns = runRepo.findAllByOrderByStartedAtDesc();
  33. // 按 workflowId 分组
  34. Map<Long, List<WorkflowRun>> grouped = allRuns.stream()
  35. .collect(Collectors.groupingBy(WorkflowRun::getWorkflowId, LinkedHashMap::new, Collectors.toList()));
  36. List<WorkflowWithRunsVO> result = new ArrayList<>();
  37. for (Map.Entry<Long, List<WorkflowRun>> entry : grouped.entrySet()) {
  38. Optional<Workflow> wfOpt = workflowRepo.findById(entry.getKey());
  39. if (wfOpt.isEmpty()) continue;
  40. Workflow wf = wfOpt.get();
  41. WorkflowWithRunsVO vo = new WorkflowWithRunsVO();
  42. vo.setWorkflowId(wf.getId());
  43. vo.setWorkflowName(wf.getName());
  44. vo.setDisplayName(wf.getDisplayName());
  45. vo.setTags(tagService.getEntityTags("workflow", String.valueOf(wf.getId())));
  46. vo.setRuns(entry.getValue().stream().map(this::toRunVO).collect(Collectors.toList()));
  47. result.add(vo);
  48. }
  49. return Result.success(result);
  50. }
  51. /**
  52. * 获取某次运行的详情(含节点结果)
  53. */
  54. @GetMapping("/runs/{runId}")
  55. public Result<RunDetailVO> getRunDetail(@PathVariable Long runId) {
  56. Optional<WorkflowRun> runOpt = runRepo.findById(runId);
  57. if (runOpt.isEmpty()) return Result.error("运行记录不存在");
  58. WorkflowRun run = runOpt.get();
  59. List<WorkflowRunNode> nodes = runNodeRepo.findByRunIdOrderBySortOrderAsc(runId);
  60. RunDetailVO detail = new RunDetailVO();
  61. detail.setRun(toRunVO(run));
  62. detail.setNodes(nodes);
  63. return Result.success(detail);
  64. }
  65. /**
  66. * 删除某次运行记录
  67. */
  68. @PostMapping("/runs/{runId}/delete")
  69. public Result<Void> deleteRun(@PathVariable Long runId) {
  70. runNodeRepo.deleteByRunId(runId);
  71. runRepo.deleteById(runId);
  72. return Result.success(null);
  73. }
  74. private RunVO toRunVO(WorkflowRun run) {
  75. RunVO vo = new RunVO();
  76. vo.setId(run.getId());
  77. vo.setWorkflowId(run.getWorkflowId());
  78. vo.setRunId(run.getRunId());
  79. vo.setStatus(run.getStatus());
  80. vo.setInputs(run.getInputs());
  81. vo.setOutputs(run.getOutputs());
  82. vo.setWorkingDirFiles(run.getWorkingDirFiles());
  83. vo.setError(run.getError());
  84. vo.setStartedAt(run.getStartedAt());
  85. vo.setCompletedAt(run.getCompletedAt());
  86. return vo;
  87. }
  88. @Data
  89. public static class WorkflowWithRunsVO {
  90. private Long workflowId;
  91. /** kebab-case 唯一标识(URL 用) */
  92. private String workflowName;
  93. /** 中文显示名 */
  94. private String displayName;
  95. private List<TagBriefVO> tags;
  96. private List<RunVO> runs;
  97. }
  98. @Data
  99. public static class RunVO {
  100. private Long id;
  101. private Long workflowId;
  102. private String runId;
  103. private String status;
  104. private String inputs;
  105. private String outputs;
  106. /** 工作空间文件列表 JSON 数组字符串(应用 .agentignore 过滤后的相对路径) */
  107. private String workingDirFiles;
  108. private String error;
  109. private Object startedAt;
  110. private Object completedAt;
  111. }
  112. @Data
  113. public static class RunDetailVO {
  114. private RunVO run;
  115. private List<WorkflowRunNode> nodes;
  116. }
  117. }