feat(compat): 补齐文档草案接口兼容入口

This commit is contained in:
2026-06-01 06:15:44 +08:00
parent 73237507e9
commit d5d239ae3a
14 changed files with 441 additions and 6 deletions

View File

@@ -5,7 +5,9 @@ import com.bruce.workflow.dto.WorkflowDefinitionSaveDTO;
import com.bruce.workflow.service.IWorkflowDefinitionService;
import com.bruce.workflow.vo.WorkflowDefinitionVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
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.RequestMapping;
@@ -14,6 +16,7 @@ import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@Slf4j
@RestController
@RequestMapping("/api/workflows")
@RequiredArgsConstructor
@@ -33,8 +36,26 @@ public class WorkflowDefinitionController {
return RequestResult.success(workflowDefinitionService.getDefinition(id));
}
/**
* 兼容前端实现文档中的 REST 详情路径。
*/
@GetMapping("/{workflowId}")
public RequestResult<WorkflowDefinitionVO> detailByPath(@PathVariable("workflowId") Long workflowId) {
log.info("Workflow定义详情查询开始workflowId={}", workflowId);
return RequestResult.success(workflowDefinitionService.getDefinition(workflowId));
}
@PostMapping("/definition/save")
public RequestResult<Boolean> save(@RequestBody WorkflowDefinitionSaveDTO request) {
return RequestResult.success(workflowDefinitionService.saveDefinition(request));
}
/**
* 兼容前端实现文档中的草稿保存路径。
*/
@PostMapping("/save-draft")
public RequestResult<Boolean> saveDraft(@RequestBody WorkflowDefinitionSaveDTO request) {
log.info("Workflow草稿保存开始workflowId={}, workflowCode={}", request.getId(), request.getWorkflowCode());
return RequestResult.success(workflowDefinitionService.saveDefinition(request));
}
}

View File

@@ -5,6 +5,7 @@ import com.bruce.workflow.dto.WorkflowRunCreateDTO;
import com.bruce.workflow.service.IWorkflowRunService;
import com.bruce.workflow.vo.WorkflowRunVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
@@ -14,6 +15,7 @@ import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@Slf4j
@RestController
@RequestMapping("/api/workflow-runs")
@RequiredArgsConstructor
@@ -30,4 +32,25 @@ public class WorkflowRunController {
public RequestResult<List<WorkflowRunVO>> list(@PathVariable("workflowId") Long workflowId) {
return RequestResult.success(workflowRunService.listRecentByWorkflowId(workflowId));
}
/**
* 兼容前端实现文档中的资源化运行创建路径。
*/
@PostMapping("/compat/workflows/{workflowId}/runs")
public RequestResult<Boolean> createCompat(@PathVariable("workflowId") Long workflowId,
@RequestBody WorkflowRunCreateDTO request) {
request.setWorkflowId(workflowId);
log.info("Workflow运行创建开始workflowId={}, versionId={}, requestId={}",
workflowId, request.getWorkflowVersionId(), request.getRequestId());
return RequestResult.success(workflowRunService.createRun(request));
}
/**
* 兼容前端实现文档中的按运行ID查询路径。
*/
@GetMapping("/compat/workflows/runs/{runId}")
public RequestResult<WorkflowRunVO> detailCompat(@PathVariable("runId") Long runId) {
log.info("Workflow运行详情查询开始runId={}", runId);
return RequestResult.success(workflowRunService.getRunById(runId));
}
}

View File

@@ -5,6 +5,7 @@ import com.bruce.workflow.dto.WorkflowVersionSaveDTO;
import com.bruce.workflow.service.IWorkflowVersionService;
import com.bruce.workflow.vo.WorkflowVersionVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
@@ -14,6 +15,7 @@ import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@Slf4j
@RestController
@RequestMapping("/api/workflow-versions")
@RequiredArgsConstructor
@@ -30,4 +32,15 @@ public class WorkflowVersionController {
public RequestResult<Boolean> publish(@RequestBody WorkflowVersionSaveDTO request) {
return RequestResult.success(workflowVersionService.publishVersion(request));
}
/**
* 兼容前端实现文档中的资源化发布路径。
*/
@PostMapping("/compat/workflows/{workflowId}/publish")
public RequestResult<Boolean> publishCompat(@PathVariable("workflowId") Long workflowId,
@RequestBody WorkflowVersionSaveDTO request) {
request.setWorkflowId(workflowId);
log.info("Workflow版本发布开始workflowId={}, versionNo={}", workflowId, request.getVersionNo());
return RequestResult.success(workflowVersionService.publishVersion(request));
}
}

View File

@@ -12,4 +12,6 @@ public interface IWorkflowRunService extends IService<WorkflowRun> {
boolean createRun(WorkflowRunCreateDTO request);
List<WorkflowRunVO> listRecentByWorkflowId(Long workflowId);
WorkflowRunVO getRunById(Long runId);
}

View File

@@ -52,6 +52,18 @@ public class WorkflowRunServiceImpl extends ServiceImpl<WorkflowRunMapper, Workf
return workflowRunFactory.toVOList(runs);
}
@Override
public WorkflowRunVO getRunById(Long runId) {
if (runId == null) {
throw new IllegalArgumentException("Workflow运行ID不能为空");
}
WorkflowRun run = getById(runId);
if (run == null) {
return null;
}
return workflowRunFactory.toVO(run);
}
private void validateRequest(WorkflowRunCreateDTO request) {
if (request == null) {
throw new IllegalArgumentException("Workflow运行请求不能为空");

View File

@@ -0,0 +1,130 @@
package com.bruce.workflow.controller;
import com.bruce.common.handler.GlobalExceptionHandler;
import com.bruce.workflow.service.IWorkflowDefinitionService;
import com.bruce.workflow.service.IWorkflowRunService;
import com.bruce.workflow.service.IWorkflowVersionService;
import com.bruce.workflow.vo.WorkflowDefinitionVO;
import com.bruce.workflow.vo.WorkflowRunVO;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* 验证 Workflow 文档草案兼容路径的返回契约。
*/
@ExtendWith(MockitoExtension.class)
class WorkflowCompatControllerTests {
private MockMvc mockMvc;
@Mock
private IWorkflowDefinitionService workflowDefinitionService;
@Mock
private IWorkflowVersionService workflowVersionService;
@Mock
private IWorkflowRunService workflowRunService;
@InjectMocks
private WorkflowDefinitionController workflowDefinitionController;
@InjectMocks
private WorkflowVersionController workflowVersionController;
@InjectMocks
private WorkflowRunController workflowRunController;
@BeforeEach
void setUp() {
mockMvc = MockMvcBuilders.standaloneSetup(
workflowDefinitionController,
workflowVersionController,
workflowRunController
)
.setControllerAdvice(new GlobalExceptionHandler())
.build();
}
@Test
void workflowDetailCompatShouldReturnStructuredDefinition() throws Exception {
WorkflowDefinitionVO detail = new WorkflowDefinitionVO();
detail.setId(201L);
detail.setWorkflowCode("workflow-support-rag");
detail.setWorkflowName("合同知识召回");
when(workflowDefinitionService.getDefinition(201L)).thenReturn(detail);
mockMvc.perform(get("/api/workflows/201"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.resultcode").value("0"))
.andExpect(jsonPath("$.data.workflowCode").value("workflow-support-rag"));
}
@Test
void saveDraftCompatShouldDelegateToDefinitionService() throws Exception {
when(workflowDefinitionService.saveDefinition(any())).thenReturn(true);
mockMvc.perform(post("/api/workflows/save-draft")
.contentType(MediaType.APPLICATION_JSON)
.content("""
{
"id": 201,
"projectId": 101,
"workflowCode": "workflow-support-rag",
"workflowName": "合同知识召回"
}
"""))
.andExpect(status().isOk())
.andExpect(jsonPath("$.resultcode").value("0"))
.andExpect(jsonPath("$.data").value(true));
}
@Test
void publishCompatShouldDelegateToVersionService() throws Exception {
when(workflowVersionService.publishVersion(any())).thenReturn(true);
mockMvc.perform(post("/api/workflow-versions/compat/workflows/201/publish")
.contentType(MediaType.APPLICATION_JSON)
.content("""
{
"versionNo": 3,
"snapshotName": "v3"
}
"""))
.andExpect(status().isOk())
.andExpect(jsonPath("$.resultcode").value("0"))
.andExpect(jsonPath("$.data").value(true));
}
@Test
void runCompatShouldReturnStructuredRunDetail() throws Exception {
WorkflowRunVO run = new WorkflowRunVO();
run.setId(301L);
run.setWorkflowId(201L);
run.setRequestId("req-1001");
run.setStatus("SUCCESS");
when(workflowRunService.getRunById(301L)).thenReturn(run);
mockMvc.perform(get("/api/workflow-runs/compat/workflows/runs/301"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.resultcode").value("0"))
.andExpect(jsonPath("$.data.requestId").value("req-1001"))
.andExpect(jsonPath("$.data.status").value("SUCCESS"));
}
}