package com.qqflow.engine.domain.flow.controller; import com.qqflow.engine.common.PageResult; import com.qqflow.engine.common.Result; import com.qqflow.engine.common.exception.BusinessException; import com.qqflow.engine.common.util.SecurityUtils; import com.qqflow.engine.config.security.LoginUser; import com.qqflow.engine.domain.flow.dto.AttachmentDTO; import com.qqflow.engine.domain.flow.dto.ProcessInstanceDTO; import com.qqflow.engine.domain.flow.dto.ProcessProgressDTO; import com.qqflow.engine.domain.flow.dto.StartProcessDTO; import com.qqflow.engine.domain.flow.dto.UpdateFormDataDTO; import com.qqflow.engine.domain.flow.service.ProcessInstanceService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.DeleteMapping; 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; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.util.List; import java.util.Map; @RestController @RequestMapping("/flow/instance") @RequiredArgsConstructor @PreAuthorize("isAuthenticated()") @Tag(name = "流程实例管理") public class ProcessInstanceController { private final ProcessInstanceService processInstanceService; @PostMapping("/start") @Operation(summary = "发起流程") public Result start(@RequestBody @Valid StartProcessDTO dto) { return Result.ok(this.processInstanceService.startProcess(dto)); } @GetMapping("/page") @PreAuthorize("hasAnyRole('super_admin','flow_manager','dept_manager')") @Operation(summary = "流程实例分页列表(管理员)") public Result> page( @RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "10") Integer pageSize, @RequestParam(required = false) Integer status, @RequestParam(required = false) Long processDefinitionId, @RequestParam(required = false) String definitionName, @RequestParam(required = false) String currentNodeName, @RequestParam(required = false) String applicantName) { return Result.ok(this.processInstanceService.list(null, status, processDefinitionId, definitionName, currentNodeName, applicantName, pageNum, pageSize)); } @GetMapping("/mine") @Operation(summary = "我的流程列表") public Result> mine( @RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "10") Integer pageSize, @RequestParam(required = false) Integer status, @RequestParam(required = false) String definitionName, @RequestParam(required = false) String currentNodeName) { Long applicantId = SecurityUtils.getUserId(); return Result.ok(this.processInstanceService.list(applicantId, status, null, definitionName, currentNodeName, null, pageNum, pageSize)); } @GetMapping("/{id}") @Operation(summary = "流程实例详情") public Result getById(@PathVariable Long id) { return Result.ok(this.processInstanceService.getDetail(id)); } @PostMapping("/{id}/revoke") @Operation(summary = "撤回流程") public Result revoke(@PathVariable Long id) { this.processInstanceService.revoke(id); return Result.ok(); } @PostMapping("/batch-revoke") @Operation(summary = "批量撤回流程") public Result batchRevoke(@RequestBody List ids) { this.processInstanceService.batchRevoke(ids); return Result.ok(); } @DeleteMapping("/{id}") @Operation(summary = "删除流程实例") public Result delete(@PathVariable Long id) { this.processInstanceService.delete(id); return Result.ok(); } @PostMapping("/batch-delete") @Operation(summary = "批量删除流程实例") public Result batchDelete(@RequestBody List ids) { this.processInstanceService.batchDelete(ids); return Result.ok(); } @GetMapping("/{id}/progress") @Operation(summary = "流程实例进度") public Result progress(@PathVariable Long id) { return Result.ok(this.processInstanceService.getProgress(id)); } @GetMapping("/{id}/attachments") @Operation(summary = "流程实例附件列表") public Result> attachments(@PathVariable Long id) { return Result.ok(this.processInstanceService.listAttachments(id)); } @PostMapping("/{id}/form-data") @Operation(summary = "补充/修正表单数据") public Result updateFormData(@PathVariable Long id, @RequestBody @Valid UpdateFormDataDTO dto) { this.processInstanceService.supplementFormData(id, dto.getFormData()); return Result.ok(); } @GetMapping("/participated") @Operation(summary = "我参与的流程实例列表") public Result> participated( @RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "10") Integer pageSize) { Long userId = SecurityUtils.getUserId(); String userType = requireLoginUser().getUserType(); return Result.ok(this.processInstanceService.participatedList(userId, userType, pageNum, pageSize)); } @PostMapping("/{id}/migrate") @Operation(summary = "迁移单个流程实例到新版本定义") @PreAuthorize("hasAnyRole('super_admin','flow_manager')") public Result migrate(@PathVariable Long id, @RequestParam Long targetDefinitionId) { this.processInstanceService.migrateToDefinition(id, targetDefinitionId); return Result.ok(); } @PostMapping("/migrate-all") @Operation(summary = "批量迁移指定定义下所有运行中的实例到新版本定义") @PreAuthorize("hasAnyRole('super_admin','flow_manager')") public Result> migrateAll(@RequestParam Long fromDefinitionId, @RequestParam Long toDefinitionId) { int count = this.processInstanceService.migrateAllToDefinition(fromDefinitionId, toDefinitionId); Map result = new java.util.LinkedHashMap<>(); result.put("migratedCount", count); return Result.ok(result); } private LoginUser requireLoginUser() { LoginUser loginUser = SecurityUtils.getLoginUser(); if (loginUser == null) { throw new BusinessException("未登录"); } return loginUser; } }