WorkflowController.java 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. package com.agent.management.controller;
  2. import com.agent.management.common.Result;
  3. import com.agent.management.engine.WorkflowEngine;
  4. import com.agent.management.engine.WorkflowRunRequest;
  5. import com.agent.management.model.entity.Workflow;
  6. import com.agent.management.model.vo.PageResult;
  7. import com.agent.management.model.vo.WorkflowVO;
  8. import com.agent.management.repository.WfCategoryRepository;
  9. import com.agent.management.service.TagService;
  10. import com.agent.management.service.WfCategoryService;
  11. import com.agent.management.service.WorkflowService;
  12. import lombok.Data;
  13. import lombok.RequiredArgsConstructor;
  14. import org.springframework.http.MediaType;
  15. import org.springframework.web.bind.annotation.*;
  16. import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
  17. import java.util.ArrayList;
  18. import java.util.List;
  19. import java.util.stream.Collectors;
  20. @RestController
  21. @RequestMapping("/api/workflows")
  22. @RequiredArgsConstructor
  23. public class WorkflowController {
  24. private final WorkflowService workflowService;
  25. private final WorkflowEngine workflowEngine;
  26. private final TagService tagService;
  27. private final WfCategoryRepository wfCategoryRepository;
  28. private final WfCategoryService wfCategoryService;
  29. @GetMapping
  30. public Result<PageResult<WorkflowVO>> list(
  31. @RequestParam(required = false) String search,
  32. @RequestParam(required = false) Long categoryId,
  33. @RequestParam(defaultValue = "1") int page,
  34. @RequestParam(defaultValue = "12") int size) {
  35. List<Workflow> all = workflowService.listWorkflows();
  36. // 搜索过滤
  37. if (search != null && !search.trim().isEmpty()) {
  38. String kw = search.trim().toLowerCase();
  39. all = all.stream()
  40. .filter(wf -> (wf.getName() != null && wf.getName().toLowerCase().contains(kw))
  41. || (wf.getDescription() != null && wf.getDescription().toLowerCase().contains(kw)))
  42. .collect(Collectors.toList());
  43. }
  44. // 分类过滤(含子孙分类)
  45. if (categoryId != null) {
  46. List<Long> catIds = new ArrayList<>();
  47. catIds.add(categoryId);
  48. catIds.addAll(wfCategoryService.getDescendantCategoryIds(categoryId));
  49. all = all.stream()
  50. .filter(wf -> wf.getCategoryId() != null && catIds.contains(wf.getCategoryId()))
  51. .collect(Collectors.toList());
  52. }
  53. int total = all.size();
  54. int totalPages = Math.max(1, (int) Math.ceil((double) total / size));
  55. if (page > totalPages) page = totalPages;
  56. int from = (page - 1) * size;
  57. int to = Math.min(from + size, total);
  58. List<Workflow> pageData = from < total ? all.subList(from, to) : List.of();
  59. List<WorkflowVO> voList = pageData.stream().map(this::toVO).collect(Collectors.toList());
  60. return Result.success(PageResult.of(voList, total, page, size));
  61. }
  62. @GetMapping("/{id}")
  63. public Result<WorkflowVO> get(@PathVariable Long id) {
  64. Workflow wf = workflowService.getWorkflow(id);
  65. return Result.success(toVO(wf));
  66. }
  67. @PostMapping
  68. public Result<WorkflowVO> create(@RequestBody CreateWorkflowReq req) {
  69. Workflow wf = workflowService.createWorkflow(req.getName(), req.getDescription());
  70. return Result.success(toVO(wf));
  71. }
  72. @PostMapping("/{id}/save")
  73. public Result<WorkflowVO> save(@PathVariable Long id, @RequestBody SaveWorkflowReq req) {
  74. Workflow wf = workflowService.updateWorkflow(id, req.getName(), req.getDescription(), req.getGraphData());
  75. return Result.success(toVO(wf));
  76. }
  77. @PostMapping("/{id}/delete")
  78. public Result<Void> delete(@PathVariable Long id) {
  79. workflowService.deleteWorkflow(id);
  80. return Result.success(null);
  81. }
  82. /** 设置工作流分类 */
  83. @PutMapping("/{id}/category")
  84. public Result<Void> setCategory(@PathVariable Long id, @RequestBody SetCategoryReq req) {
  85. Workflow wf = workflowService.getWorkflow(id);
  86. wf.setCategoryId(req.getCategoryId());
  87. workflowService.updateWorkflow(wf.getId(), wf.getName(), wf.getDescription(), wf.getGraphData());
  88. return Result.success(null);
  89. }
  90. /**
  91. * 运行工作流(SSE 实时推送执行状态)
  92. */
  93. @PostMapping(value = "/{id}/run", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
  94. public SseEmitter run(@PathVariable Long id, @RequestBody WorkflowRunRequest req) {
  95. SseEmitter emitter = new SseEmitter(600_000L); // 10 分钟超时
  96. workflowEngine.executeAsync(id, req.getInputs(), emitter);
  97. return emitter;
  98. }
  99. private WorkflowVO toVO(Workflow wf) {
  100. WorkflowVO vo = WorkflowVO.from(wf);
  101. vo.setTags(tagService.getEntityTags("workflow", String.valueOf(wf.getId())));
  102. // 填充分类名称
  103. if (wf.getCategoryId() != null) {
  104. wfCategoryRepository.findById(wf.getCategoryId())
  105. .ifPresent(cat -> vo.setCategoryName(cat.getName()));
  106. }
  107. return vo;
  108. }
  109. @Data
  110. public static class CreateWorkflowReq {
  111. private String name;
  112. private String description;
  113. }
  114. @Data
  115. public static class SaveWorkflowReq {
  116. private String name;
  117. private String description;
  118. private String graphData;
  119. }
  120. @Data
  121. public static class SetCategoryReq {
  122. private Long categoryId;
  123. }
  124. }