From 581a6d8f027a64053f028513e78ad95d65b8b9e9 Mon Sep 17 00:00:00 2001 From: hewenqiang <1527468660@qq.com> Date: Fri, 25 Mar 2022 20:18:00 +0800 Subject: [PATCH] =?UTF-8?q?add=20--=20=E6=B7=BB=E5=8A=A0=E2=80=9C=E6=96=B0?= =?UTF-8?q?=E5=BB=BA=E6=B5=81=E7=A8=8B=E2=80=9D=E9=A1=B5=E9=9D=A2=EF=BC=8C?= =?UTF-8?q?=E5=8F=91=E8=B5=B7=E6=B5=81=E7=A8=8B=E6=93=8D=E4=BD=9C=E4=BB=8E?= =?UTF-8?q?=E2=80=9C=E6=88=91=E7=9A=84=E6=B5=81=E7=A8=8B=E2=80=9D=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=E5=88=86=E7=A6=BB=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../workflow/WfDefinitionController.java | 2 +- .../workflow/WfDeployController.java | 48 +++++ .../workflow/WfProcessController.java | 50 +++++ .../workflow/service/IWfProcessService.java | 28 +++ .../service/impl/WfDefinitionServiceImpl.java | 1 + .../service/impl/WfProcessServiceImpl.java | 119 ++++++++++++ ruoyi-ui/src/api/workflow/deploy.js | 9 + ruoyi-ui/src/api/workflow/process.js | 19 ++ ruoyi-ui/src/router/index.js | 19 ++ ruoyi-ui/src/views/workflow/process/index.vue | 178 ++++++++++++++++++ ruoyi-ui/src/views/workflow/process/start.vue | 98 ++++++++++ 11 files changed, 570 insertions(+), 1 deletion(-) create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/workflow/WfDeployController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/workflow/WfProcessController.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/workflow/service/IWfProcessService.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/workflow/service/impl/WfProcessServiceImpl.java create mode 100644 ruoyi-ui/src/api/workflow/deploy.js create mode 100644 ruoyi-ui/src/views/workflow/process/index.vue create mode 100644 ruoyi-ui/src/views/workflow/process/start.vue diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/workflow/WfDefinitionController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/workflow/WfDefinitionController.java index 186e0a66..532aa9b9 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/workflow/WfDefinitionController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/workflow/WfDefinitionController.java @@ -122,7 +122,7 @@ public class WfDefinitionController extends BaseController { return R.ok("导入成功"); } - + @Deprecated @ApiOperation(value = "根据流程定义id启动流程实例") @SaCheckPermission("workflow:definition:start") @PostMapping("/start/{procDefId}") diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/workflow/WfDeployController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/workflow/WfDeployController.java new file mode 100644 index 00000000..1a687579 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/workflow/WfDeployController.java @@ -0,0 +1,48 @@ +package com.ruoyi.web.controller.workflow; + +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.utils.JsonUtils; +import com.ruoyi.workflow.domain.vo.WfFormVo; +import com.ruoyi.workflow.service.IWfDeployFormService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +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.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Map; +import java.util.Objects; + +/** + * @author KonBAI + * @createTime 2022/3/24 20:57 + */ +@Slf4j +@Api(tags = "流程部署") +@RequiredArgsConstructor +@RestController +@RequestMapping("/workflow/deploy") +public class WfDeployController extends BaseController { + + private final IWfDeployFormService deployFormService; + + /** + * + * @param deployId + * @return + */ + @ApiOperation(value = "查询流程部署关联表单信息") + @GetMapping("/form/{deployId}") + public R start(@ApiParam(value = "流程部署id") @PathVariable(value = "deployId") String deployId) { + WfFormVo formVo = deployFormService.selectSysDeployFormByDeployId(deployId); + if (Objects.isNull(formVo)) { + return R.fail("请先配置流程表单"); + } + return R.ok(JsonUtils.parseObject(formVo.getContent(), Map.class)); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/workflow/WfProcessController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/workflow/WfProcessController.java new file mode 100644 index 00000000..51621875 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/workflow/WfProcessController.java @@ -0,0 +1,50 @@ +package com.ruoyi.web.controller.workflow; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.PageQuery; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.workflow.domain.vo.WfDefinitionVo; +import com.ruoyi.workflow.service.IWfProcessService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.*; + +import java.util.Map; + +/** + * 工作流流程管理 + * + * @author KonBAI + * @createTime 2022/3/24 18:54 + */ +@Slf4j +@Api(tags = "工作流流程管理") +@RequiredArgsConstructor +@RestController +@RequestMapping("/workflow/process") +public class WfProcessController extends BaseController { + + private final IWfProcessService processService; + + @GetMapping(value = "/list") + @SaCheckPermission("workflow:process:startList") + @ApiOperation(value = "查询可发起流程列表", response = WfDefinitionVo.class) + public TableDataInfo list(PageQuery pageQuery) { + return processService.processList(pageQuery); + } + + @ApiOperation(value = "根据流程定义id启动流程实例") + @SaCheckPermission("workflow:process:start") + @PostMapping("/start/{processDefId}") + public R start(@ApiParam(value = "流程定义id") @PathVariable(value = "processDefId") String processDefId, + @ApiParam(value = "变量集合,json对象") @RequestBody Map variables) { + processService.startProcess(processDefId, variables); + return R.ok("流程启动成功"); + + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/workflow/service/IWfProcessService.java b/ruoyi-system/src/main/java/com/ruoyi/workflow/service/IWfProcessService.java new file mode 100644 index 00000000..3aa95f5a --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/workflow/service/IWfProcessService.java @@ -0,0 +1,28 @@ +package com.ruoyi.workflow.service; + +import com.ruoyi.common.core.domain.PageQuery; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.workflow.domain.vo.WfDefinitionVo; + +import java.util.Map; + +/** + * @author KonBAI + * @createTime 2022/3/24 18:57 + */ +public interface IWfProcessService { + + /** + * 查询可发起流程列表 + * @param pageQuery 分页参数 + * @return + */ + TableDataInfo processList(PageQuery pageQuery); + + /** + * 启动流程实例 + * @param procDefId 流程定义ID + * @param variables 扩展参数 + */ + void startProcess(String procDefId, Map variables); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/workflow/service/impl/WfDefinitionServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/workflow/service/impl/WfDefinitionServiceImpl.java index 66766063..dfccc5d7 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/workflow/service/impl/WfDefinitionServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/workflow/service/impl/WfDefinitionServiceImpl.java @@ -203,6 +203,7 @@ public class WfDefinitionServiceImpl extends FlowServiceFactory implements IWfDe * @param variables 流程变量 * @return */ + @Deprecated @Override @Transactional(rollbackFor = Exception.class) public void startProcessInstanceById(String procDefId, Map variables) { diff --git a/ruoyi-system/src/main/java/com/ruoyi/workflow/service/impl/WfProcessServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/workflow/service/impl/WfProcessServiceImpl.java new file mode 100644 index 00000000..b5bb508f --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/workflow/service/impl/WfProcessServiceImpl.java @@ -0,0 +1,119 @@ +package com.ruoyi.workflow.service.impl; + +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.ruoyi.common.core.domain.PageQuery; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.helper.LoginHelper; +import com.ruoyi.flowable.common.constant.ProcessConstants; +import com.ruoyi.flowable.common.enums.FlowComment; +import com.ruoyi.flowable.factory.FlowServiceFactory; +import com.ruoyi.workflow.domain.vo.WfDefinitionVo; +import com.ruoyi.workflow.service.IWfProcessService; +import lombok.RequiredArgsConstructor; +import org.flowable.engine.repository.Deployment; +import org.flowable.engine.repository.ProcessDefinition; +import org.flowable.engine.repository.ProcessDefinitionQuery; +import org.flowable.engine.runtime.ProcessInstance; +import org.flowable.task.api.Task; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * @author KonBAI + * @createTime 2022/3/24 18:57 + */ +@RequiredArgsConstructor +@Service +public class WfProcessServiceImpl extends FlowServiceFactory implements IWfProcessService { + + /** + * 流程定义列表 + * + * @param pageQuery 分页参数 + * @return 流程定义分页列表数据 + */ + @Override + public TableDataInfo processList(PageQuery pageQuery) { + Page page = new Page<>(); + // 流程定义列表数据查询 + ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery() + .latestVersion() + .active() + .orderByProcessDefinitionKey() + .asc(); + long pageTotal = processDefinitionQuery.count(); + if (pageTotal <= 0) { + return TableDataInfo.build(); + } + int offset = pageQuery.getPageSize() * (pageQuery.getPageNum() - 1); + List definitionList = processDefinitionQuery.listPage(offset, pageQuery.getPageSize()); + + List definitionVoList = new ArrayList<>(); + for (ProcessDefinition processDefinition : definitionList) { + String deploymentId = processDefinition.getDeploymentId(); + Deployment deployment = repositoryService.createDeploymentQuery().deploymentId(deploymentId).singleResult(); + WfDefinitionVo vo = new WfDefinitionVo(); + vo.setDefinitionId(processDefinition.getId()); + vo.setProcessKey(processDefinition.getKey()); + vo.setProcessName(processDefinition.getName()); + vo.setVersion(processDefinition.getVersion()); + vo.setCategory(processDefinition.getCategory()); + vo.setDeploymentId(processDefinition.getDeploymentId()); + vo.setSuspended(processDefinition.isSuspended()); + // 流程定义时间 + vo.setCategory(deployment.getCategory()); + vo.setDeploymentTime(deployment.getDeploymentTime()); + definitionVoList.add(vo); + } + page.setRecords(definitionVoList); + page.setTotal(pageTotal); + return TableDataInfo.build(page); + } + + /** + * 根据流程定义ID启动流程实例 + * + * @param procDefId 流程定义Id + * @param variables 流程变量 + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void startProcess(String procDefId, Map variables) { + try { + ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery() + .processDefinitionId(procDefId).singleResult(); + if (Objects.nonNull(processDefinition) && processDefinition.isSuspended()) { + throw new ServiceException("流程已被挂起,请先激活流程"); + } +// variables.put("skip", true); +// variables.put(ProcessConstants.FLOWABLE_SKIP_EXPRESSION_ENABLED, true); + // 设置流程发起人Id到流程中 + String userIdStr = LoginHelper.getUserId().toString(); + identityService.setAuthenticatedUserId(userIdStr); + variables.put(ProcessConstants.PROCESS_INITIATOR, userIdStr); + ProcessInstance processInstance = runtimeService.startProcessInstanceById(procDefId, variables); + // 给第一步申请人节点设置任务执行人和意见 todo:第一个节点不设置为申请人节点有点问题? + Task task = taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()).singleResult(); + if (Objects.nonNull(task)) { + if (!StrUtil.equalsAny(task.getAssignee(), userIdStr)) { + throw new ServiceException("数据验证失败,该工作流第一个用户任务的指派人并非当前用户,不能执行该操作!"); + } + taskService.addComment(task.getId(), processInstance.getProcessInstanceId(), FlowComment.NORMAL.getType(), LoginHelper.getNickName() + "发起流程申请"); + // taskService.setAssignee(task.getId(), userIdStr); + taskService.complete(task.getId(), variables); + } + } catch (Exception e) { + e.printStackTrace(); + throw new ServiceException("流程启动错误"); + } + } + +} diff --git a/ruoyi-ui/src/api/workflow/deploy.js b/ruoyi-ui/src/api/workflow/deploy.js new file mode 100644 index 00000000..098663c1 --- /dev/null +++ b/ruoyi-ui/src/api/workflow/deploy.js @@ -0,0 +1,9 @@ +import request from '@/utils/request' + +// 查询流程部署关联表单信息 +export function getFormByDeployId(deployId) { + return request({ + url: '/workflow/deploy/form/' + deployId, + method: 'get', + }) +} diff --git a/ruoyi-ui/src/api/workflow/process.js b/ruoyi-ui/src/api/workflow/process.js index 7296372d..5c97c9d8 100644 --- a/ruoyi-ui/src/api/workflow/process.js +++ b/ruoyi-ui/src/api/workflow/process.js @@ -1,5 +1,24 @@ import request from '@/utils/request' +// 查询流程列表 +export function listProcess(query) { + return request({ + url: '/workflow/process/list', + method: 'get', + params: query + }) +} + + +// 部署流程实例 +export function startProcess(processDefId, data) { + return request({ + url: '/workflow/process/start/' + processDefId, + method: 'post', + data: data + }) +} + // 我的发起的流程 export function myProcessList(query) { return request({ diff --git a/ruoyi-ui/src/router/index.js b/ruoyi-ui/src/router/index.js index 8cfa4ee8..69ca9ae1 100644 --- a/ruoyi-ui/src/router/index.js +++ b/ruoyi-ui/src/router/index.js @@ -87,11 +87,30 @@ export const constantRoutes = [ } ] }, + { + path: '/process', + component: Layout, + hidden: true, + children: [ + { + path: 'start', + component: () => import('@/views/workflow/process/start'), + name: 'StartProcess', + meta: { title: '发起流程', icon: '' } + } + ] + }, { path: '/task', component: Layout, hidden: true, children: [ + { + path: 'process/index', + component: () => import('@/views/workflow/task/process/index'), + name: 'Record', + meta: { title: '我的流程', icon: '' } + }, { path: 'record/index', component: () => import('@/views/workflow/task/record/index'), diff --git a/ruoyi-ui/src/views/workflow/process/index.vue b/ruoyi-ui/src/views/workflow/process/index.vue new file mode 100644 index 00000000..a890b6ba --- /dev/null +++ b/ruoyi-ui/src/views/workflow/process/index.vue @@ -0,0 +1,178 @@ + + + + + diff --git a/ruoyi-ui/src/views/workflow/process/start.vue b/ruoyi-ui/src/views/workflow/process/start.vue new file mode 100644 index 00000000..6f791831 --- /dev/null +++ b/ruoyi-ui/src/views/workflow/process/start.vue @@ -0,0 +1,98 @@ + + + + +