diff --git a/pom.xml b/pom.xml index a3c7f3d38..723885860 100644 --- a/pom.xml +++ b/pom.xml @@ -51,7 +51,7 @@ 8.7.2-20240808 - 1.2.10 + 1.3.0 3.2.2 @@ -130,6 +130,12 @@ warm-flow-plugin-spel ${warm-flow.version} + + io.github.minliuhua + warm-flow-plugin-ui-sb-web + ${warm-flow.version} + + diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/event/ProcessEvent.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/event/ProcessEvent.java index 61c7efc39..df9eebcac 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/event/ProcessEvent.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/event/ProcessEvent.java @@ -18,9 +18,9 @@ public class ProcessEvent implements Serializable { private static final long serialVersionUID = 1L; /** - * 流程定义key + * 流程定义编码 */ - private String key; + private String flowCode; /** * 业务id diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/event/ProcessTaskEvent.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/event/ProcessTaskEvent.java index 019ca823b..78d0d9e29 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/event/ProcessTaskEvent.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/event/ProcessTaskEvent.java @@ -18,14 +18,14 @@ public class ProcessTaskEvent implements Serializable { private static final long serialVersionUID = 1L; /** - * 流程定义key + * 流程定义编码 */ - private String key; + private String flowCode; /** - * 审批节点key + * 审批节点编码 */ - private String taskDefinitionKey; + private String nodeCode; /** * 任务id diff --git a/ruoyi-modules/ruoyi-workflow/pom.xml b/ruoyi-modules/ruoyi-workflow/pom.xml index 8ace150c0..6e18f8680 100644 --- a/ruoyi-modules/ruoyi-workflow/pom.xml +++ b/ruoyi-modules/ruoyi-workflow/pom.xml @@ -74,6 +74,10 @@ io.github.minliuhua warm-flow-plugin-spel + + io.github.minliuhua + warm-flow-plugin-ui-sb-web + diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/FlwDefinitionController.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/FlwDefinitionController.java index 689a81a3a..4bb15ca2b 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/FlwDefinitionController.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/FlwDefinitionController.java @@ -171,17 +171,6 @@ public class FlwDefinitionController extends BaseController { return R.ok("操作成功", defService.xmlString(id)); } - /** - * 查询流程图 - * - * @param instanceId 流程实例id - * @throws IOException 异常 - */ - @GetMapping("/flowChart/{instanceId}") - public R flowChart(@PathVariable Long instanceId) throws IOException { - return R.ok("操作成功", defService.flowChart(instanceId)); - } - /** * 激活/挂起流程定义 * diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/FlwInstanceController.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/FlwInstanceController.java index c517addb0..a22a5e471 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/FlwInstanceController.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/FlwInstanceController.java @@ -14,6 +14,7 @@ import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import java.util.List; +import java.util.Map; /** * 流程实例管理 控制层 @@ -107,4 +108,15 @@ public class FlwInstanceController extends BaseController { public TableDataInfo getPageByCurrent(InstanceBo instanceBo, PageQuery pageQuery) { return flwInstanceService.getPageByCurrent(instanceBo, pageQuery); } + + + /** + * 获取流程图,流程记录 + * + * @param businessId 业务id + */ + @GetMapping("/getFlowImage/{businessId}") + public R> getFlowImage(@PathVariable String businessId) { + return R.ok(flwInstanceService.getFlowImage(businessId)); + } } diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/FlwTaskController.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/FlwTaskController.java index a167cb5c8..16ee315a4 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/FlwTaskController.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/FlwTaskController.java @@ -158,12 +158,8 @@ public class FlwTaskController extends BaseController { @Log(title = "任务管理", businessType = BusinessType.INSERT) @RepeatSubmit() @PostMapping("/terminationTask") - public R terminationTask(@RequestBody TerminationBo bo) { - FlowParams flowParams = new FlowParams(); - flowParams.handler(String.valueOf(LoginHelper.getUserId())); - flowParams.message(bo.getComment()); - flowParams.permissionFlag(WorkflowUtils.permissionList()); - return R.ok(taskService.termination(bo.getTaskId(), flowParams)); + public R terminationTask(@RequestBody TerminationBo bo) { + return R.ok(flwTaskService.terminationTask(bo)); } /** diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/FlowHisTaskVo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/FlowHisTaskVo.java index c7dca17b9..5ab3520e9 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/FlowHisTaskVo.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/FlowHisTaskVo.java @@ -67,6 +67,11 @@ public class FlowHisTaskVo implements Serializable { */ private Integer cooperateType; + /** + * 协作方式(1审批 2转办 3委派 4会签 5票签 6加签 7减签) + */ + private String cooperateTypeName; + /** * 业务id */ @@ -163,4 +168,9 @@ public class FlowHisTaskVo implements Serializable { * 流程定义编码 */ private String flowCode; + + /** + * 运行时长 + */ + private String runDuration; } diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/handler/FlowProcessEventHandler.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/handler/FlowProcessEventHandler.java new file mode 100644 index 000000000..7c8e15633 --- /dev/null +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/handler/FlowProcessEventHandler.java @@ -0,0 +1,50 @@ +package org.dromara.workflow.handler; + +import org.dromara.common.core.domain.event.ProcessEvent; +import org.dromara.common.core.domain.event.ProcessTaskEvent; +import org.dromara.common.core.utils.SpringUtils; +import org.springframework.stereotype.Component; + +/** + * 流程监听服务 + * + * @author may + * @date 2024-06-02 + */ +@Component +public class FlowProcessEventHandler { + + /** + * 总体流程监听(例如: 提交 退回 撤销 终止 作废等) + * + * @param flowCode 流程定义编码 + * @param businessKey 业务id + * @param status 状态 + * @param submit 当为true时为申请人节点办理 + */ + public void processHandler(String flowCode, String businessKey, String status, boolean submit) { + ProcessEvent processEvent = new ProcessEvent(); + processEvent.setFlowCode(flowCode); + processEvent.setBusinessKey(businessKey); + processEvent.setStatus(status); + processEvent.setSubmit(submit); + SpringUtils.context().publishEvent(processEvent); + } + + /** + * 执行办理任务监听 + * + * @param flowCode 流程定义编码 + * @param nodeCode 审批节点编码 + * @param taskId 任务id + * @param businessKey 业务id + */ + public void processTaskHandler(String flowCode, String nodeCode, String taskId, String businessKey) { + ProcessTaskEvent processTaskEvent = new ProcessTaskEvent(); + processTaskEvent.setFlowCode(flowCode); + processTaskEvent.setNodeCode(nodeCode); + processTaskEvent.setTaskId(taskId); + processTaskEvent.setBusinessKey(businessKey); + SpringUtils.context().publishEvent(processTaskEvent); + } +} diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwInstanceService.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwInstanceService.java index ebdb71019..65712a22e 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwInstanceService.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwInstanceService.java @@ -8,6 +8,7 @@ import org.dromara.workflow.domain.bo.InstanceBo; import org.dromara.workflow.domain.vo.FlowInstanceVo; import java.util.List; +import java.util.Map; /** * 流程实例 服务层 @@ -74,4 +75,12 @@ public interface IFlwInstanceService { * @return 结果 */ TableDataInfo getPageByCurrent(InstanceBo instanceBo, PageQuery pageQuery); + + /** + * 获取流程图,流程记录 + * + * @param businessId 业务id + * @return 结果 + */ + Map getFlowImage(String businessId); } diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwTaskService.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwTaskService.java index 6424073ed..2f1eee3dd 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwTaskService.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwTaskService.java @@ -1,6 +1,7 @@ package org.dromara.workflow.service; import com.warm.flow.core.entity.HisTask; +import com.warm.flow.core.entity.Instance; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.workflow.domain.bo.*; @@ -94,4 +95,12 @@ public interface IFlwTaskService { * @return 结果 */ List getBackTaskNode(String instanceId); + + /** + * 终止任务 + * + * @param bo 参数 + * @return 结果 + */ + boolean terminationTask(TerminationBo bo); } diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwInstanceServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwInstanceServiceImpl.java index 512cd925d..00302d1b3 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwInstanceServiceImpl.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwInstanceServiceImpl.java @@ -2,29 +2,24 @@ package org.dromara.workflow.service.impl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.warm.flow.core.FlowFactory; -import com.warm.flow.core.constant.ExceptionCons; -import com.warm.flow.core.dto.FlowParams; import com.warm.flow.core.entity.*; +import com.warm.flow.core.enums.CooperateType; import com.warm.flow.core.enums.FlowStatus; import com.warm.flow.core.enums.NodeType; -import com.warm.flow.core.enums.SkipType; -import com.warm.flow.core.service.DefService; -import com.warm.flow.core.service.InsService; -import com.warm.flow.core.service.NodeService; -import com.warm.flow.core.service.TaskService; -import com.warm.flow.core.utils.AssertUtil; +import com.warm.flow.core.service.*; import com.warm.flow.orm.entity.FlowDefinition; +import com.warm.flow.orm.entity.FlowHisTask; import com.warm.flow.orm.entity.FlowInstance; import com.warm.flow.orm.mapper.FlowDefinitionMapper; +import com.warm.flow.orm.mapper.FlowHisTaskMapper; import com.warm.flow.orm.mapper.FlowInstanceMapper; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.dromara.common.core.constant.UserConstants; import org.dromara.common.core.utils.StreamUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.mybatis.core.page.PageQuery; @@ -32,15 +27,18 @@ import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.workflow.domain.bo.FlowInstanceBo; import org.dromara.workflow.domain.bo.InstanceBo; +import org.dromara.workflow.domain.vo.FlowHisTaskVo; import org.dromara.workflow.domain.vo.FlowInstanceVo; import org.dromara.workflow.mapper.FlwInstanceMapper; import org.dromara.workflow.service.IFlwInstanceService; -import org.dromara.workflow.utils.WorkflowUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.io.IOException; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * 流程实例 服务层实现 @@ -53,9 +51,8 @@ import java.util.List; public class FlwInstanceServiceImpl implements IFlwInstanceService { private final InsService insService; - private final NodeService nodeService; private final DefService defService; - private final TaskService taskService; + private final FlowHisTaskMapper flowHisTaskMapper; private final FlowInstanceMapper flowInstanceMapper; private final FlwInstanceMapper flwInstanceMapper; private final FlowDefinitionMapper flowDefinitionMapper; @@ -70,6 +67,7 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService { public TableDataInfo getPageByRunning(Instance instance, PageQuery pageQuery) { QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.eq("t.flow_status", FlowStatus.APPROVAL.getKey()); + queryWrapper.eq("t.del_flag", UserConstants.USER_NORMAL); Page page = flwInstanceMapper.page(pageQuery.build(), queryWrapper); TableDataInfo build = TableDataInfo.build(); build.setRows(BeanUtil.copyToList(page.getRecords(), FlowInstanceVo.class)); @@ -130,38 +128,15 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService { return insService.remove(instanceIds); } + /** + * 撤销流程 + * + * @param businessId 业务id + */ @Override @Transactional(rollbackFor = Exception.class) public boolean cancelProcessApply(String businessId) { - FlowInstance flowInstance = instanceByBusinessId(businessId); - if (ObjectUtil.isNull(flowInstance)) { - return false; - } - try { - Definition definition = defService.getById(flowInstance.getDefinitionId()); - List list = taskService.list(FlowFactory.newTask().setInstanceId(flowInstance.getId())); - // 获取已发布的流程节点 - List nodes = nodeService.getByFlowCode(definition.getFlowCode()); - AssertUtil.isTrue(CollUtil.isEmpty(nodes), ExceptionCons.NOT_PUBLISH_NODE); - // 获取开始节点 - Node startNode = nodes.stream().filter(t -> NodeType.isStart(t.getNodeType())).findFirst().orElse(null); - AssertUtil.isNull(startNode, ExceptionCons.LOST_START_NODE); - - // 获取下一个节点,如果是网关节点,则重新获取后续节点 - //List nextNodes = FlowFactory.taskService().getNextByCheckGateWay(new FlowParams(), getFirstBetween(startNode)); - //Node node = nextNodes.get(0); - // FlowParams flowParams = FlowParams.build().nodeCode(node.getNodeCode()).skipType(SkipType.PASS.getKey()).permissionFlag(WorkflowUtils.permissionList()); - // taskService.skip(list.get(0).getId(), flowParams); - } catch (Exception e) { - throw new RuntimeException(e); - } - return false; - } - - private Node getFirstBetween(Node startNode) { - List skips = FlowFactory.skipService().list(FlowFactory.newSkip().setDefinitionId(startNode.getDefinitionId()).setNowNodeCode(startNode.getNodeCode())); - Skip skip = skips.get(0); - return FlowFactory.nodeService().getOne(FlowFactory.newNode().setDefinitionId(startNode.getDefinitionId()).setNodeCode(skip.getNextNodeCode())); + throw new RuntimeException("暂未开发"); } /** @@ -202,4 +177,58 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService { build.setTotal(page.getTotal()); return build; } + + @Override + public Map getFlowImage(String businessId) { + Map map = new HashMap<>(); + FlowInstance flowInstance = instanceByBusinessId(businessId); + LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); + wrapper.eq(FlowHisTask::getInstanceId, flowInstance.getId()); + wrapper.eq(FlowHisTask::getNodeType, NodeType.BETWEEN.getKey()); + wrapper.orderByDesc(FlowHisTask::getCreateTime); + List flowHisTasks = flowHisTaskMapper.selectList(wrapper); + List list = BeanUtil.copyToList(flowHisTasks, FlowHisTaskVo.class); + for (FlowHisTaskVo vo : list) { + vo.setCooperateTypeName(CooperateType.getValueByKey(vo.getCooperateType())); + if (vo.getUpdateTime() != null && vo.getCreateTime() != null) { + vo.setRunDuration(getDuration(vo.getUpdateTime().getTime() - vo.getCreateTime().getTime())); + } + } + map.put("list", list); + try { + String flowChart = defService.flowChart(flowInstance.getId()); + map.put("image", flowChart); + } catch (IOException e) { + throw new RuntimeException(e); + } + return map; + } + + /** + * 任务完成时间处理 + * + * @param time 时间 + */ + private String getDuration(long time) { + + long day = time / (24 * 60 * 60 * 1000); + long hour = (time / (60 * 60 * 1000) - day * 24); + long minute = ((time / (60 * 1000)) - day * 24 * 60 - hour * 60); + long second = (time / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - minute * 60); + + if (day > 0) { + return day + "天" + hour + "小时" + minute + "分钟"; + } + if (hour > 0) { + return hour + "小时" + minute + "分钟"; + } + if (minute > 0) { + return minute + "分钟"; + } + if (second > 0) { + return second + "秒"; + } else { + return 0 + "秒"; + } + } } diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java index 3bc3b623e..e67cbf1ea 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java @@ -5,13 +5,11 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.warm.flow.core.dto.FlowParams; -import com.warm.flow.core.entity.HisTask; -import com.warm.flow.core.entity.Instance; -import com.warm.flow.core.entity.Task; -import com.warm.flow.core.entity.User; +import com.warm.flow.core.entity.*; import com.warm.flow.core.enums.FlowStatus; import com.warm.flow.core.enums.NodeType; import com.warm.flow.core.enums.SkipType; +import com.warm.flow.core.service.DefService; import com.warm.flow.core.service.InsService; import com.warm.flow.core.service.TaskService; import com.warm.flow.core.service.UserService; @@ -32,6 +30,7 @@ import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.workflow.domain.bo.*; import org.dromara.workflow.domain.vo.*; +import org.dromara.workflow.handler.FlowProcessEventHandler; import org.dromara.workflow.mapper.FlwTaskMapper; import org.dromara.workflow.service.IFlwInstanceService; import org.dromara.workflow.service.IFlwTaskService; @@ -64,6 +63,8 @@ public class FlwTaskServiceImpl implements IFlwTaskService { private final FlowTaskMapper flowTaskMapper; private final FlowHisTaskMapper flowHisTaskMapper; private final FlowSkipMapper flowSkipMapper; + private final FlowProcessEventHandler flowProcessEventHandler; + private final DefService defService; /** * 启动任务 @@ -126,14 +127,31 @@ public class FlwTaskServiceImpl implements IFlwTaskService { try { String userId = String.valueOf(LoginHelper.getUserId()); Long taskId = completeTaskBo.getTaskId(); + FlowTask flowTask = flowTaskMapper.selectById(taskId); + Instance ins = insService.getById(flowTask.getInstanceId()); + //流程定义 + Definition definition = defService.getById(flowTask.getDefinitionId()); + //流程提交监听 + if (FlowStatus.TOBESUBMIT.getKey().equals(ins.getFlowStatus()) || FlowStatus.REJECT.getKey().equals(ins.getFlowStatus())) { + flowProcessEventHandler.processHandler(definition.getFlowCode(), ins.getBusinessId(), ins.getFlowStatus(), true); + } + //办理任务监听 + flowProcessEventHandler.processTaskHandler(definition.getFlowCode(), flowTask.getNodeCode(), + taskId.toString(), ins.getBusinessId()); FlowParams flowParams = new FlowParams(); flowParams.variable(completeTaskBo.getVariables()); flowParams.skipType(SkipType.PASS.getKey()); flowParams.message(completeTaskBo.getMessage()); flowParams.handler(userId); flowParams.permissionFlag(WorkflowUtils.permissionList()); - Instance instance = taskService.skip(taskId, flowParams); - setHandler(instance); + setHandler(taskService.skip(taskId, flowParams)); + //判断是否流程结束 + Instance instance = insService.getById(ins.getId()); + if (FlowStatus.isFinished(instance.getFlowStatus())) { + //流程结束执行监听 + flowProcessEventHandler.processHandler(definition.getFlowCode(), instance.getBusinessId(), + FlowStatus.FINISHED.getKey(), false); + } return true; } catch (Exception e) { log.error(e.getMessage(), e); @@ -297,6 +315,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService { throw new ServiceException("任务不存在!"); } Long definitionId = flowTasks.get(0).getDefinitionId(); + Definition definition = defService.getById(definitionId); List flowSkips = flowSkipMapper.selectList(new LambdaQueryWrapper<>(FlowSkip.class).eq(FlowSkip::getDefinitionId, definitionId)); FlowSkip flowSkip = StreamUtils.findFirst(flowSkips, e -> NodeType.START.getKey().equals(e.getNowNodeType())); //开始节点的下一节点 @@ -316,6 +335,8 @@ public class FlwTaskServiceImpl implements IFlwTaskService { flowParams.setPermissionFlag(WorkflowUtils.permissionList()); Instance instance = taskService.skip(taskId, flowParams); setHandler(instance); + flowProcessEventHandler.processHandler(definition.getFlowCode(), + instance.getBusinessId(), FlowStatus.REJECT.getKey(), false); return true; } catch (Exception e) { log.error(e.getMessage(), e); @@ -340,4 +361,32 @@ public class FlwTaskServiceImpl implements IFlwTaskService { } return Collections.emptyList(); } + + /** + * 终止任务 + * + * @param bo 参数 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public boolean terminationTask(TerminationBo bo) { + try { + FlowTask flowTask = flowTaskMapper.selectById(bo.getTaskId()); + Instance ins = insService.getById(flowTask.getInstanceId()); + //流程定义 + Definition definition = defService.getById(flowTask.getDefinitionId()); + FlowParams flowParams = new FlowParams(); + flowParams.handler(String.valueOf(LoginHelper.getUserId())); + flowParams.message(bo.getComment()); + flowParams.permissionFlag(WorkflowUtils.permissionList()); + taskService.termination(bo.getTaskId(), flowParams); + //流程终止监听 + flowProcessEventHandler.processHandler(definition.getFlowCode(), + ins.getBusinessId(), FlowStatus.INVALID.getKey(), false); + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + throw new ServiceException(e.getMessage()); + } + } } diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/TestLeaveServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/TestLeaveServiceImpl.java index e4ef38ce6..a99a578d6 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/TestLeaveServiceImpl.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/TestLeaveServiceImpl.java @@ -3,6 +3,7 @@ package org.dromara.workflow.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.warm.flow.core.enums.FlowStatus; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.domain.event.ProcessEvent; @@ -84,7 +85,7 @@ public class TestLeaveServiceImpl implements ITestLeaveService { public TestLeaveVo insertByBo(TestLeaveBo bo) { TestLeave add = MapstructUtils.convert(bo, TestLeave.class); if (StringUtils.isBlank(add.getStatus())) { - add.setStatus(BusinessStatusEnum.DRAFT.getStatus()); + add.setStatus(FlowStatus.TOBESUBMIT.getKey()); } boolean flag = baseMapper.insert(add) > 0; if (flag) { @@ -116,25 +117,25 @@ public class TestLeaveServiceImpl implements ITestLeaveService { /** * 总体流程监听(例如: 提交 退回 撤销 终止 作废等) - * 正常使用只需#processEvent.key=='leave1' + * 正常使用只需#processEvent.flowCode=='leave1' * 示例为了方便则使用startsWith匹配了全部示例key * * @param processEvent 参数 */ - @EventListener(condition = "#processEvent.key.startsWith('leave')") + @EventListener(condition = "#processEvent.flowCode.startsWith('leaveFlow-serial1')") public void processHandler(ProcessEvent processEvent) { log.info("当前任务执行了{}", processEvent.toString()); TestLeave testLeave = baseMapper.selectById(Long.valueOf(processEvent.getBusinessKey())); testLeave.setStatus(processEvent.getStatus()); if (processEvent.isSubmit()) { - testLeave.setStatus(BusinessStatusEnum.WAITING.getStatus()); + testLeave.setStatus(FlowStatus.APPROVAL.getKey()); } baseMapper.updateById(testLeave); } /** * 执行办理任务监听 - * 示例:也可通过 @EventListener(condition = "#processTaskEvent.key=='leave1'")进行判断 + * 示例:也可通过 @EventListener(condition = "#processTaskEvent.flowCode=='leave1'")进行判断 * 在方法中判断流程节点key * if ("xxx".equals(processTaskEvent.getTaskDefinitionKey())) { * //执行业务逻辑 @@ -142,11 +143,11 @@ public class TestLeaveServiceImpl implements ITestLeaveService { * * @param processTaskEvent 参数 */ - @EventListener(condition = "#processTaskEvent.key=='leave1' && #processTaskEvent.taskDefinitionKey=='Activity_14633hx'") + @EventListener(condition = "#processTaskEvent.flowCode=='leaveFlow-serial1' && #processTaskEvent.nodeCode=='Activity_14633hx'") public void processTaskHandler(ProcessTaskEvent processTaskEvent) { log.info("当前任务执行了{}", processTaskEvent.toString()); TestLeave testLeave = baseMapper.selectById(Long.valueOf(processTaskEvent.getBusinessKey())); - testLeave.setStatus(BusinessStatusEnum.WAITING.getStatus()); + testLeave.setStatus(FlowStatus.APPROVAL.getKey()); baseMapper.updateById(testLeave); } } diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/WorkflowUtils.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/WorkflowUtils.java index 20d5d3c2f..62412781f 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/WorkflowUtils.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/WorkflowUtils.java @@ -1,9 +1,7 @@ package org.dromara.workflow.utils; import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; -import com.warm.flow.core.entity.Task; import com.warm.flow.core.entity.User; import com.warm.flow.orm.entity.FlowUser; import lombok.AccessLevel; @@ -14,12 +12,7 @@ import org.dromara.common.core.service.UserService; import org.dromara.common.core.utils.SpringUtils; import org.dromara.common.core.utils.StreamUtils; import org.dromara.common.core.utils.StringUtils; -import org.dromara.common.mail.utils.MailUtils; import org.dromara.common.satoken.utils.LoginHelper; -import org.dromara.common.websocket.dto.WebSocketMessageDto; -import org.dromara.common.websocket.utils.WebSocketUtils; -import org.dromara.workflow.common.enums.MessageTypeEnum; -import org.dromara.workflow.domain.vo.ParticipantVo; import java.util.*; @@ -31,56 +24,6 @@ import java.util.*; @NoArgsConstructor(access = AccessLevel.PRIVATE) public class WorkflowUtils { - /** - * 发送消息 - * - * @param list 任务 - * @param name 流程名称 - * @param messageType 消息类型 - * @param message 消息内容,为空则发送默认配置的消息内容 - */ - public static void sendMessage(List list, String name, List messageType, String message, UserService userService) { - Set userIds = new HashSet<>(); - if (StringUtils.isBlank(message)) { - message = "有新的【" + name + "】单据已经提交至您的待办,请您及时处理。"; - } - for (Task t : list) { - ParticipantVo taskParticipant = null; //= WorkflowUtils.getCurrentTaskParticipant(t.getId(), userService); - if (CollUtil.isNotEmpty(taskParticipant.getGroupIds())) { - List userIdList = userService.selectUserIdsByRoleIds(taskParticipant.getGroupIds()); - if (CollUtil.isNotEmpty(userIdList)) { - userIds.addAll(userIdList); - } - } - List candidate = taskParticipant.getCandidate(); - if (CollUtil.isNotEmpty(candidate)) { - userIds.addAll(candidate); - } - } - if (CollUtil.isNotEmpty(userIds)) { - List userList = userService.selectListByIds(new ArrayList<>(userIds)); - for (String code : messageType) { - MessageTypeEnum messageTypeEnum = MessageTypeEnum.getByCode(code); - if (ObjectUtil.isNotEmpty(messageTypeEnum)) { - switch (messageTypeEnum) { - case SYSTEM_MESSAGE: - WebSocketMessageDto dto = new WebSocketMessageDto(); - dto.setSessionKeys(new ArrayList<>(userIds)); - dto.setMessage(message); - WebSocketUtils.publishMessage(dto); - break; - case EMAIL_MESSAGE: - MailUtils.sendText(StreamUtils.join(userList, UserDTO::getEmail), "单据审批提醒", message); - break; - case SMS_MESSAGE: - //todo 短信发送 - break; - } - } - } - } - } - /** * 当前用户所有权限 * diff --git a/script/bpmn/leaveFlow-serial1.xml b/script/bpmn/leaveFlow-serial1.xml index 34fedaadd..5f51196ac 100644 --- a/script/bpmn/leaveFlow-serial1.xml +++ b/script/bpmn/leaveFlow-serial1.xml @@ -1,38 +1,40 @@ - + + listenerType="start,assignment,finish,create" + listenerPath="com.ruoyi.system.Listener.StartListener@@com.ruoyi.system.Listener.AssignmentListener@@com.ruoyi.system.Listener.FinishListener@@com.ruoyi.system.Listener.CreateListener"> 2 + listenerType="start,assignment,finish,create" + listenerPath="com.ruoyi.system.Listener.StartListener@@com.ruoyi.system.Listener.AssignmentListener@@com.ruoyi.system.Listener.FinishListener@@com.ruoyi.system.Listener.CreateListener"> 3 + listenerType="start,assignment,finish,create" + listenerPath="com.ruoyi.system.Listener.StartListener@@com.ruoyi.system.Listener.AssignmentListener@@com.ruoyi.system.Listener.FinishListener@@com.ruoyi.system.Listener.CreateListener"> 4 + listenerType="start,assignment,finish,create" + listenerPath="com.ruoyi.system.Listener.StartListener@@com.ruoyi.system.Listener.AssignmentListener@@com.ruoyi.system.Listener.FinishListener@@com.ruoyi.system.Listener.CreateListener"> 5 2 + listenerType="start,assignment,finish,create" + listenerPath="com.ruoyi.system.Listener.StartListener@@com.ruoyi.system.Listener.AssignmentListener@@com.ruoyi.system.Listener.FinishListener@@com.ruoyi.system.Listener.CreateListener"> 6 + listenerType="start,assignment,finish,create" + listenerPath="com.ruoyi.system.Listener.StartListener@@com.ruoyi.system.Listener.AssignmentListener@@com.ruoyi.system.Listener.FinishListener@@com.ruoyi.system.Listener.CreateListener"/>