update 升级warm-flow到1.3.0 调整流程办理 ,驳回,终止等 添加自定义监听
This commit is contained in:
parent
ccf28de33d
commit
4d40a1f4fa
8
pom.xml
8
pom.xml
@ -51,7 +51,7 @@
|
|||||||
<!-- 面向运行时的D-ORM依赖 -->
|
<!-- 面向运行时的D-ORM依赖 -->
|
||||||
<anyline.version>8.7.2-20240808</anyline.version>
|
<anyline.version>8.7.2-20240808</anyline.version>
|
||||||
<!--工作流配置-->
|
<!--工作流配置-->
|
||||||
<warm-flow.version>1.2.10</warm-flow.version>
|
<warm-flow.version>1.3.0</warm-flow.version>
|
||||||
|
|
||||||
<!-- 插件版本 -->
|
<!-- 插件版本 -->
|
||||||
<maven-jar-plugin.version>3.2.2</maven-jar-plugin.version>
|
<maven-jar-plugin.version>3.2.2</maven-jar-plugin.version>
|
||||||
@ -130,6 +130,12 @@
|
|||||||
<artifactId>warm-flow-plugin-spel</artifactId>
|
<artifactId>warm-flow-plugin-spel</artifactId>
|
||||||
<version>${warm-flow.version}</version>
|
<version>${warm-flow.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.github.minliuhua</groupId>
|
||||||
|
<artifactId>warm-flow-plugin-ui-sb-web</artifactId>
|
||||||
|
<version>${warm-flow.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
<!-- JustAuth 的依赖配置-->
|
<!-- JustAuth 的依赖配置-->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -18,9 +18,9 @@ public class ProcessEvent implements Serializable {
|
|||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 流程定义key
|
* 流程定义编码
|
||||||
*/
|
*/
|
||||||
private String key;
|
private String flowCode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 业务id
|
* 业务id
|
||||||
|
@ -18,14 +18,14 @@ public class ProcessTaskEvent implements Serializable {
|
|||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 流程定义key
|
* 流程定义编码
|
||||||
*/
|
*/
|
||||||
private String key;
|
private String flowCode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 审批节点key
|
* 审批节点编码
|
||||||
*/
|
*/
|
||||||
private String taskDefinitionKey;
|
private String nodeCode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 任务id
|
* 任务id
|
||||||
|
@ -74,6 +74,10 @@
|
|||||||
<groupId>io.github.minliuhua</groupId>
|
<groupId>io.github.minliuhua</groupId>
|
||||||
<artifactId>warm-flow-plugin-spel</artifactId>
|
<artifactId>warm-flow-plugin-spel</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.github.minliuhua</groupId>
|
||||||
|
<artifactId>warm-flow-plugin-ui-sb-web</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@ -171,17 +171,6 @@ public class FlwDefinitionController extends BaseController {
|
|||||||
return R.ok("操作成功", defService.xmlString(id));
|
return R.ok("操作成功", defService.xmlString(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询流程图
|
|
||||||
*
|
|
||||||
* @param instanceId 流程实例id
|
|
||||||
* @throws IOException 异常
|
|
||||||
*/
|
|
||||||
@GetMapping("/flowChart/{instanceId}")
|
|
||||||
public R<String> flowChart(@PathVariable Long instanceId) throws IOException {
|
|
||||||
return R.ok("操作成功", defService.flowChart(instanceId));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 激活/挂起流程定义
|
* 激活/挂起流程定义
|
||||||
*
|
*
|
||||||
|
@ -14,6 +14,7 @@ import org.springframework.validation.annotation.Validated;
|
|||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 流程实例管理 控制层
|
* 流程实例管理 控制层
|
||||||
@ -107,4 +108,15 @@ public class FlwInstanceController extends BaseController {
|
|||||||
public TableDataInfo<FlowInstanceVo> getPageByCurrent(InstanceBo instanceBo, PageQuery pageQuery) {
|
public TableDataInfo<FlowInstanceVo> getPageByCurrent(InstanceBo instanceBo, PageQuery pageQuery) {
|
||||||
return flwInstanceService.getPageByCurrent(instanceBo, pageQuery);
|
return flwInstanceService.getPageByCurrent(instanceBo, pageQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取流程图,流程记录
|
||||||
|
*
|
||||||
|
* @param businessId 业务id
|
||||||
|
*/
|
||||||
|
@GetMapping("/getFlowImage/{businessId}")
|
||||||
|
public R<Map<String, Object>> getFlowImage(@PathVariable String businessId) {
|
||||||
|
return R.ok(flwInstanceService.getFlowImage(businessId));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -158,12 +158,8 @@ public class FlwTaskController extends BaseController {
|
|||||||
@Log(title = "任务管理", businessType = BusinessType.INSERT)
|
@Log(title = "任务管理", businessType = BusinessType.INSERT)
|
||||||
@RepeatSubmit()
|
@RepeatSubmit()
|
||||||
@PostMapping("/terminationTask")
|
@PostMapping("/terminationTask")
|
||||||
public R<Instance> terminationTask(@RequestBody TerminationBo bo) {
|
public R<Boolean> terminationTask(@RequestBody TerminationBo bo) {
|
||||||
FlowParams flowParams = new FlowParams();
|
return R.ok(flwTaskService.terminationTask(bo));
|
||||||
flowParams.handler(String.valueOf(LoginHelper.getUserId()));
|
|
||||||
flowParams.message(bo.getComment());
|
|
||||||
flowParams.permissionFlag(WorkflowUtils.permissionList());
|
|
||||||
return R.ok(taskService.termination(bo.getTaskId(), flowParams));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -67,6 +67,11 @@ public class FlowHisTaskVo implements Serializable {
|
|||||||
*/
|
*/
|
||||||
private Integer cooperateType;
|
private Integer cooperateType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 协作方式(1审批 2转办 3委派 4会签 5票签 6加签 7减签)
|
||||||
|
*/
|
||||||
|
private String cooperateTypeName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 业务id
|
* 业务id
|
||||||
*/
|
*/
|
||||||
@ -163,4 +168,9 @@ public class FlowHisTaskVo implements Serializable {
|
|||||||
* 流程定义编码
|
* 流程定义编码
|
||||||
*/
|
*/
|
||||||
private String flowCode;
|
private String flowCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 运行时长
|
||||||
|
*/
|
||||||
|
private String runDuration;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -8,6 +8,7 @@ import org.dromara.workflow.domain.bo.InstanceBo;
|
|||||||
import org.dromara.workflow.domain.vo.FlowInstanceVo;
|
import org.dromara.workflow.domain.vo.FlowInstanceVo;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 流程实例 服务层
|
* 流程实例 服务层
|
||||||
@ -74,4 +75,12 @@ public interface IFlwInstanceService {
|
|||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
TableDataInfo<FlowInstanceVo> getPageByCurrent(InstanceBo instanceBo, PageQuery pageQuery);
|
TableDataInfo<FlowInstanceVo> getPageByCurrent(InstanceBo instanceBo, PageQuery pageQuery);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取流程图,流程记录
|
||||||
|
*
|
||||||
|
* @param businessId 业务id
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
Map<String, Object> getFlowImage(String businessId);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package org.dromara.workflow.service;
|
package org.dromara.workflow.service;
|
||||||
|
|
||||||
import com.warm.flow.core.entity.HisTask;
|
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.PageQuery;
|
||||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||||
import org.dromara.workflow.domain.bo.*;
|
import org.dromara.workflow.domain.bo.*;
|
||||||
@ -94,4 +95,12 @@ public interface IFlwTaskService {
|
|||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
List<HisTask> getBackTaskNode(String instanceId);
|
List<HisTask> getBackTaskNode(String instanceId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 终止任务
|
||||||
|
*
|
||||||
|
* @param bo 参数
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
boolean terminationTask(TerminationBo bo);
|
||||||
}
|
}
|
||||||
|
@ -2,29 +2,24 @@ package org.dromara.workflow.service.impl;
|
|||||||
|
|
||||||
import cn.hutool.core.bean.BeanUtil;
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
import cn.hutool.core.collection.CollUtil;
|
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.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
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.entity.*;
|
||||||
|
import com.warm.flow.core.enums.CooperateType;
|
||||||
import com.warm.flow.core.enums.FlowStatus;
|
import com.warm.flow.core.enums.FlowStatus;
|
||||||
import com.warm.flow.core.enums.NodeType;
|
import com.warm.flow.core.enums.NodeType;
|
||||||
import com.warm.flow.core.enums.SkipType;
|
import com.warm.flow.core.service.*;
|
||||||
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.orm.entity.FlowDefinition;
|
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.entity.FlowInstance;
|
||||||
import com.warm.flow.orm.mapper.FlowDefinitionMapper;
|
import com.warm.flow.orm.mapper.FlowDefinitionMapper;
|
||||||
|
import com.warm.flow.orm.mapper.FlowHisTaskMapper;
|
||||||
import com.warm.flow.orm.mapper.FlowInstanceMapper;
|
import com.warm.flow.orm.mapper.FlowInstanceMapper;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
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.StreamUtils;
|
||||||
import org.dromara.common.core.utils.StringUtils;
|
import org.dromara.common.core.utils.StringUtils;
|
||||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
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.common.satoken.utils.LoginHelper;
|
||||||
import org.dromara.workflow.domain.bo.FlowInstanceBo;
|
import org.dromara.workflow.domain.bo.FlowInstanceBo;
|
||||||
import org.dromara.workflow.domain.bo.InstanceBo;
|
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.domain.vo.FlowInstanceVo;
|
||||||
import org.dromara.workflow.mapper.FlwInstanceMapper;
|
import org.dromara.workflow.mapper.FlwInstanceMapper;
|
||||||
import org.dromara.workflow.service.IFlwInstanceService;
|
import org.dromara.workflow.service.IFlwInstanceService;
|
||||||
import org.dromara.workflow.utils.WorkflowUtils;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 流程实例 服务层实现
|
* 流程实例 服务层实现
|
||||||
@ -53,9 +51,8 @@ import java.util.List;
|
|||||||
public class FlwInstanceServiceImpl implements IFlwInstanceService {
|
public class FlwInstanceServiceImpl implements IFlwInstanceService {
|
||||||
|
|
||||||
private final InsService insService;
|
private final InsService insService;
|
||||||
private final NodeService nodeService;
|
|
||||||
private final DefService defService;
|
private final DefService defService;
|
||||||
private final TaskService taskService;
|
private final FlowHisTaskMapper flowHisTaskMapper;
|
||||||
private final FlowInstanceMapper flowInstanceMapper;
|
private final FlowInstanceMapper flowInstanceMapper;
|
||||||
private final FlwInstanceMapper flwInstanceMapper;
|
private final FlwInstanceMapper flwInstanceMapper;
|
||||||
private final FlowDefinitionMapper flowDefinitionMapper;
|
private final FlowDefinitionMapper flowDefinitionMapper;
|
||||||
@ -70,6 +67,7 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService {
|
|||||||
public TableDataInfo<FlowInstanceVo> getPageByRunning(Instance instance, PageQuery pageQuery) {
|
public TableDataInfo<FlowInstanceVo> getPageByRunning(Instance instance, PageQuery pageQuery) {
|
||||||
QueryWrapper<FlowInstanceBo> queryWrapper = new QueryWrapper<>();
|
QueryWrapper<FlowInstanceBo> queryWrapper = new QueryWrapper<>();
|
||||||
queryWrapper.eq("t.flow_status", FlowStatus.APPROVAL.getKey());
|
queryWrapper.eq("t.flow_status", FlowStatus.APPROVAL.getKey());
|
||||||
|
queryWrapper.eq("t.del_flag", UserConstants.USER_NORMAL);
|
||||||
Page<FlowInstanceVo> page = flwInstanceMapper.page(pageQuery.build(), queryWrapper);
|
Page<FlowInstanceVo> page = flwInstanceMapper.page(pageQuery.build(), queryWrapper);
|
||||||
TableDataInfo<FlowInstanceVo> build = TableDataInfo.build();
|
TableDataInfo<FlowInstanceVo> build = TableDataInfo.build();
|
||||||
build.setRows(BeanUtil.copyToList(page.getRecords(), FlowInstanceVo.class));
|
build.setRows(BeanUtil.copyToList(page.getRecords(), FlowInstanceVo.class));
|
||||||
@ -130,38 +128,15 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService {
|
|||||||
return insService.remove(instanceIds);
|
return insService.remove(instanceIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 撤销流程
|
||||||
|
*
|
||||||
|
* @param businessId 业务id
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public boolean cancelProcessApply(String businessId) {
|
public boolean cancelProcessApply(String businessId) {
|
||||||
FlowInstance flowInstance = instanceByBusinessId(businessId);
|
throw new RuntimeException("暂未开发");
|
||||||
if (ObjectUtil.isNull(flowInstance)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
Definition definition = defService.getById(flowInstance.getDefinitionId());
|
|
||||||
List<Task> list = taskService.list(FlowFactory.newTask().setInstanceId(flowInstance.getId()));
|
|
||||||
// 获取已发布的流程节点
|
|
||||||
List<Node> 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<Node> 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<Skip> 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()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -202,4 +177,58 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService {
|
|||||||
build.setTotal(page.getTotal());
|
build.setTotal(page.getTotal());
|
||||||
return build;
|
return build;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> getFlowImage(String businessId) {
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
FlowInstance flowInstance = instanceByBusinessId(businessId);
|
||||||
|
LambdaQueryWrapper<FlowHisTask> wrapper = Wrappers.lambdaQuery();
|
||||||
|
wrapper.eq(FlowHisTask::getInstanceId, flowInstance.getId());
|
||||||
|
wrapper.eq(FlowHisTask::getNodeType, NodeType.BETWEEN.getKey());
|
||||||
|
wrapper.orderByDesc(FlowHisTask::getCreateTime);
|
||||||
|
List<FlowHisTask> flowHisTasks = flowHisTaskMapper.selectList(wrapper);
|
||||||
|
List<FlowHisTaskVo> 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 + "秒";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,13 +5,11 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.warm.flow.core.dto.FlowParams;
|
import com.warm.flow.core.dto.FlowParams;
|
||||||
import com.warm.flow.core.entity.HisTask;
|
import com.warm.flow.core.entity.*;
|
||||||
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.enums.FlowStatus;
|
import com.warm.flow.core.enums.FlowStatus;
|
||||||
import com.warm.flow.core.enums.NodeType;
|
import com.warm.flow.core.enums.NodeType;
|
||||||
import com.warm.flow.core.enums.SkipType;
|
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.InsService;
|
||||||
import com.warm.flow.core.service.TaskService;
|
import com.warm.flow.core.service.TaskService;
|
||||||
import com.warm.flow.core.service.UserService;
|
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.common.satoken.utils.LoginHelper;
|
||||||
import org.dromara.workflow.domain.bo.*;
|
import org.dromara.workflow.domain.bo.*;
|
||||||
import org.dromara.workflow.domain.vo.*;
|
import org.dromara.workflow.domain.vo.*;
|
||||||
|
import org.dromara.workflow.handler.FlowProcessEventHandler;
|
||||||
import org.dromara.workflow.mapper.FlwTaskMapper;
|
import org.dromara.workflow.mapper.FlwTaskMapper;
|
||||||
import org.dromara.workflow.service.IFlwInstanceService;
|
import org.dromara.workflow.service.IFlwInstanceService;
|
||||||
import org.dromara.workflow.service.IFlwTaskService;
|
import org.dromara.workflow.service.IFlwTaskService;
|
||||||
@ -64,6 +63,8 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
|
|||||||
private final FlowTaskMapper flowTaskMapper;
|
private final FlowTaskMapper flowTaskMapper;
|
||||||
private final FlowHisTaskMapper flowHisTaskMapper;
|
private final FlowHisTaskMapper flowHisTaskMapper;
|
||||||
private final FlowSkipMapper flowSkipMapper;
|
private final FlowSkipMapper flowSkipMapper;
|
||||||
|
private final FlowProcessEventHandler flowProcessEventHandler;
|
||||||
|
private final DefService defService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 启动任务
|
* 启动任务
|
||||||
@ -126,14 +127,31 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
|
|||||||
try {
|
try {
|
||||||
String userId = String.valueOf(LoginHelper.getUserId());
|
String userId = String.valueOf(LoginHelper.getUserId());
|
||||||
Long taskId = completeTaskBo.getTaskId();
|
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 flowParams = new FlowParams();
|
||||||
flowParams.variable(completeTaskBo.getVariables());
|
flowParams.variable(completeTaskBo.getVariables());
|
||||||
flowParams.skipType(SkipType.PASS.getKey());
|
flowParams.skipType(SkipType.PASS.getKey());
|
||||||
flowParams.message(completeTaskBo.getMessage());
|
flowParams.message(completeTaskBo.getMessage());
|
||||||
flowParams.handler(userId);
|
flowParams.handler(userId);
|
||||||
flowParams.permissionFlag(WorkflowUtils.permissionList());
|
flowParams.permissionFlag(WorkflowUtils.permissionList());
|
||||||
Instance instance = taskService.skip(taskId, flowParams);
|
setHandler(taskService.skip(taskId, flowParams));
|
||||||
setHandler(instance);
|
//判断是否流程结束
|
||||||
|
Instance instance = insService.getById(ins.getId());
|
||||||
|
if (FlowStatus.isFinished(instance.getFlowStatus())) {
|
||||||
|
//流程结束执行监听
|
||||||
|
flowProcessEventHandler.processHandler(definition.getFlowCode(), instance.getBusinessId(),
|
||||||
|
FlowStatus.FINISHED.getKey(), false);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(e.getMessage(), e);
|
log.error(e.getMessage(), e);
|
||||||
@ -297,6 +315,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
|
|||||||
throw new ServiceException("任务不存在!");
|
throw new ServiceException("任务不存在!");
|
||||||
}
|
}
|
||||||
Long definitionId = flowTasks.get(0).getDefinitionId();
|
Long definitionId = flowTasks.get(0).getDefinitionId();
|
||||||
|
Definition definition = defService.getById(definitionId);
|
||||||
List<FlowSkip> flowSkips = flowSkipMapper.selectList(new LambdaQueryWrapper<>(FlowSkip.class).eq(FlowSkip::getDefinitionId, definitionId));
|
List<FlowSkip> flowSkips = flowSkipMapper.selectList(new LambdaQueryWrapper<>(FlowSkip.class).eq(FlowSkip::getDefinitionId, definitionId));
|
||||||
FlowSkip flowSkip = StreamUtils.findFirst(flowSkips, e -> NodeType.START.getKey().equals(e.getNowNodeType()));
|
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());
|
flowParams.setPermissionFlag(WorkflowUtils.permissionList());
|
||||||
Instance instance = taskService.skip(taskId, flowParams);
|
Instance instance = taskService.skip(taskId, flowParams);
|
||||||
setHandler(instance);
|
setHandler(instance);
|
||||||
|
flowProcessEventHandler.processHandler(definition.getFlowCode(),
|
||||||
|
instance.getBusinessId(), FlowStatus.REJECT.getKey(), false);
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(e.getMessage(), e);
|
log.error(e.getMessage(), e);
|
||||||
@ -340,4 +361,32 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
|
|||||||
}
|
}
|
||||||
return Collections.emptyList();
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package org.dromara.workflow.service.impl;
|
|||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.warm.flow.core.enums.FlowStatus;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.dromara.common.core.domain.event.ProcessEvent;
|
import org.dromara.common.core.domain.event.ProcessEvent;
|
||||||
@ -84,7 +85,7 @@ public class TestLeaveServiceImpl implements ITestLeaveService {
|
|||||||
public TestLeaveVo insertByBo(TestLeaveBo bo) {
|
public TestLeaveVo insertByBo(TestLeaveBo bo) {
|
||||||
TestLeave add = MapstructUtils.convert(bo, TestLeave.class);
|
TestLeave add = MapstructUtils.convert(bo, TestLeave.class);
|
||||||
if (StringUtils.isBlank(add.getStatus())) {
|
if (StringUtils.isBlank(add.getStatus())) {
|
||||||
add.setStatus(BusinessStatusEnum.DRAFT.getStatus());
|
add.setStatus(FlowStatus.TOBESUBMIT.getKey());
|
||||||
}
|
}
|
||||||
boolean flag = baseMapper.insert(add) > 0;
|
boolean flag = baseMapper.insert(add) > 0;
|
||||||
if (flag) {
|
if (flag) {
|
||||||
@ -116,25 +117,25 @@ public class TestLeaveServiceImpl implements ITestLeaveService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 总体流程监听(例如: 提交 退回 撤销 终止 作废等)
|
* 总体流程监听(例如: 提交 退回 撤销 终止 作废等)
|
||||||
* 正常使用只需#processEvent.key=='leave1'
|
* 正常使用只需#processEvent.flowCode=='leave1'
|
||||||
* 示例为了方便则使用startsWith匹配了全部示例key
|
* 示例为了方便则使用startsWith匹配了全部示例key
|
||||||
*
|
*
|
||||||
* @param processEvent 参数
|
* @param processEvent 参数
|
||||||
*/
|
*/
|
||||||
@EventListener(condition = "#processEvent.key.startsWith('leave')")
|
@EventListener(condition = "#processEvent.flowCode.startsWith('leaveFlow-serial1')")
|
||||||
public void processHandler(ProcessEvent processEvent) {
|
public void processHandler(ProcessEvent processEvent) {
|
||||||
log.info("当前任务执行了{}", processEvent.toString());
|
log.info("当前任务执行了{}", processEvent.toString());
|
||||||
TestLeave testLeave = baseMapper.selectById(Long.valueOf(processEvent.getBusinessKey()));
|
TestLeave testLeave = baseMapper.selectById(Long.valueOf(processEvent.getBusinessKey()));
|
||||||
testLeave.setStatus(processEvent.getStatus());
|
testLeave.setStatus(processEvent.getStatus());
|
||||||
if (processEvent.isSubmit()) {
|
if (processEvent.isSubmit()) {
|
||||||
testLeave.setStatus(BusinessStatusEnum.WAITING.getStatus());
|
testLeave.setStatus(FlowStatus.APPROVAL.getKey());
|
||||||
}
|
}
|
||||||
baseMapper.updateById(testLeave);
|
baseMapper.updateById(testLeave);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行办理任务监听
|
* 执行办理任务监听
|
||||||
* 示例:也可通过 @EventListener(condition = "#processTaskEvent.key=='leave1'")进行判断
|
* 示例:也可通过 @EventListener(condition = "#processTaskEvent.flowCode=='leave1'")进行判断
|
||||||
* 在方法中判断流程节点key
|
* 在方法中判断流程节点key
|
||||||
* if ("xxx".equals(processTaskEvent.getTaskDefinitionKey())) {
|
* if ("xxx".equals(processTaskEvent.getTaskDefinitionKey())) {
|
||||||
* //执行业务逻辑
|
* //执行业务逻辑
|
||||||
@ -142,11 +143,11 @@ public class TestLeaveServiceImpl implements ITestLeaveService {
|
|||||||
*
|
*
|
||||||
* @param processTaskEvent 参数
|
* @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) {
|
public void processTaskHandler(ProcessTaskEvent processTaskEvent) {
|
||||||
log.info("当前任务执行了{}", processTaskEvent.toString());
|
log.info("当前任务执行了{}", processTaskEvent.toString());
|
||||||
TestLeave testLeave = baseMapper.selectById(Long.valueOf(processTaskEvent.getBusinessKey()));
|
TestLeave testLeave = baseMapper.selectById(Long.valueOf(processTaskEvent.getBusinessKey()));
|
||||||
testLeave.setStatus(BusinessStatusEnum.WAITING.getStatus());
|
testLeave.setStatus(FlowStatus.APPROVAL.getKey());
|
||||||
baseMapper.updateById(testLeave);
|
baseMapper.updateById(testLeave);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
package org.dromara.workflow.utils;
|
package org.dromara.workflow.utils;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.warm.flow.core.entity.Task;
|
|
||||||
import com.warm.flow.core.entity.User;
|
import com.warm.flow.core.entity.User;
|
||||||
import com.warm.flow.orm.entity.FlowUser;
|
import com.warm.flow.orm.entity.FlowUser;
|
||||||
import lombok.AccessLevel;
|
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.SpringUtils;
|
||||||
import org.dromara.common.core.utils.StreamUtils;
|
import org.dromara.common.core.utils.StreamUtils;
|
||||||
import org.dromara.common.core.utils.StringUtils;
|
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.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.*;
|
import java.util.*;
|
||||||
|
|
||||||
@ -31,56 +24,6 @@ import java.util.*;
|
|||||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
public class WorkflowUtils {
|
public class WorkflowUtils {
|
||||||
|
|
||||||
/**
|
|
||||||
* 发送消息
|
|
||||||
*
|
|
||||||
* @param list 任务
|
|
||||||
* @param name 流程名称
|
|
||||||
* @param messageType 消息类型
|
|
||||||
* @param message 消息内容,为空则发送默认配置的消息内容
|
|
||||||
*/
|
|
||||||
public static void sendMessage(List<Task> list, String name, List<String> messageType, String message, UserService userService) {
|
|
||||||
Set<Long> 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<Long> userIdList = userService.selectUserIdsByRoleIds(taskParticipant.getGroupIds());
|
|
||||||
if (CollUtil.isNotEmpty(userIdList)) {
|
|
||||||
userIds.addAll(userIdList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
List<Long> candidate = taskParticipant.getCandidate();
|
|
||||||
if (CollUtil.isNotEmpty(candidate)) {
|
|
||||||
userIds.addAll(candidate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (CollUtil.isNotEmpty(userIds)) {
|
|
||||||
List<UserDTO> 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 当前用户所有权限
|
* 当前用户所有权限
|
||||||
*
|
*
|
||||||
|
@ -1,38 +1,40 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
<definition flowCode="leaveFlow-serial1" flowName="串行-简单" version="1.0" fromCustom="N"
|
<definition flowCode="leaveFlow-serial1" flowName="串行-简单" version="1.0" formCustom="N"
|
||||||
fromPath="system/leave/approve">
|
listenerType="start,assignment,finish,create"
|
||||||
|
listenerPath="com.ruoyi.system.GlobalListener.GlobalStartListener@@com.ruoyi.system.GlobalListener.GlobalAssignmentListener@@com.ruoyi.system.GlobalListener.GlobalFinishListener@@com.ruoyi.system.GlobalListener.GlobalCreateListener"
|
||||||
|
formPath="system/leave/approve">
|
||||||
<node nodeType="start" nodeCode="1" nodeName="开始" coordinate="120,280|120,280" skipAnyNode="N"
|
<node nodeType="start" nodeCode="1" nodeName="开始" coordinate="120,280|120,280" skipAnyNode="N"
|
||||||
listenerType="start,assignment,finish,permission,create"
|
listenerType="start,assignment,finish,create"
|
||||||
listenerPath="com.ruoyi.system.Listener.StartListener@@323@@com.ruoyi.system.Listener.FinishListener@@com.ruoyi.system.Listener.PermissionListener@@com.ruoyi.system.Listener.CreateListener">
|
listenerPath="com.ruoyi.system.Listener.StartListener@@com.ruoyi.system.Listener.AssignmentListener@@com.ruoyi.system.Listener.FinishListener@@com.ruoyi.system.Listener.CreateListener">
|
||||||
<skip coordinate="140,280;230,280" skipType="PASS">2</skip>
|
<skip coordinate="140,280;230,280" skipType="PASS">2</skip>
|
||||||
</node>
|
</node>
|
||||||
<node nodeType="between" nodeCode="2" nodeName="待提交" permissionFlag="role:1,role:2" coordinate="280,280|280,280"
|
<node nodeType="between" nodeCode="2" nodeName="待提交" permissionFlag="role:1,role:2" coordinate="280,280|280,280"
|
||||||
skipAnyNode="N" nodeRatio="0"
|
skipAnyNode="N" nodeRatio="0"
|
||||||
listenerType="start,assignment,finish,permission,create"
|
listenerType="start,assignment,finish,create"
|
||||||
listenerPath="com.ruoyi.system.Listener.StartListener@@323@@com.ruoyi.system.Listener.FinishListener@@com.ruoyi.system.Listener.PermissionListener@@com.ruoyi.system.Listener.CreateListener">
|
listenerPath="com.ruoyi.system.Listener.StartListener@@com.ruoyi.system.Listener.AssignmentListener@@com.ruoyi.system.Listener.FinishListener@@com.ruoyi.system.Listener.CreateListener">
|
||||||
<skip coordinate="330,280;430,280" skipType="PASS">3</skip>
|
<skip coordinate="330,280;430,280" skipType="PASS">3</skip>
|
||||||
</node>
|
</node>
|
||||||
<node nodeType="between" nodeCode="3" nodeName="组长审批" permissionFlag="role:1,role:2"
|
<node nodeType="between" nodeCode="3" nodeName="组长审批" permissionFlag="role:1,role:2"
|
||||||
coordinate="480,280|480,280" skipAnyNode="Y" nodeRatio="0"
|
coordinate="480,280|480,280" skipAnyNode="Y" nodeRatio="0"
|
||||||
listenerType="start,assignment,finish,permission,create"
|
listenerType="start,assignment,finish,create"
|
||||||
listenerPath="com.ruoyi.system.Listener.StartListener@@323@@com.ruoyi.system.Listener.FinishListener@@com.ruoyi.system.Listener.PermissionListener@@com.ruoyi.system.Listener.CreateListener">
|
listenerPath="com.ruoyi.system.Listener.StartListener@@com.ruoyi.system.Listener.AssignmentListener@@com.ruoyi.system.Listener.FinishListener@@com.ruoyi.system.Listener.CreateListener">
|
||||||
<skip coordinate="530,280;650,280" skipType="PASS">4</skip>
|
<skip coordinate="530,280;650,280" skipType="PASS">4</skip>
|
||||||
</node>
|
</node>
|
||||||
<node nodeType="between" nodeCode="4" nodeName="部门经理审批" permissionFlag="role:1,role:2"
|
<node nodeType="between" nodeCode="4" nodeName="部门经理审批" permissionFlag="role:1,role:2"
|
||||||
coordinate="700,280|700,280" skipAnyNode="N" nodeRatio="0"
|
coordinate="700,280|700,280" skipAnyNode="N" nodeRatio="0"
|
||||||
listenerType="start,assignment,finish,permission,create"
|
listenerType="start,assignment,finish,create"
|
||||||
listenerPath="com.ruoyi.system.Listener.StartListener@@323@@com.ruoyi.system.Listener.FinishListener@@com.ruoyi.system.Listener.PermissionListener@@com.ruoyi.system.Listener.CreateListener">
|
listenerPath="com.ruoyi.system.Listener.StartListener@@com.ruoyi.system.Listener.AssignmentListener@@com.ruoyi.system.Listener.FinishListener@@com.ruoyi.system.Listener.CreateListener">
|
||||||
<skip coordinate="750,280;870,280" skipType="PASS">5</skip>
|
<skip coordinate="750,280;870,280" skipType="PASS">5</skip>
|
||||||
<skip coordinate="700,240;700,210;280,210;280,240" skipType="REJECT">2</skip>
|
<skip coordinate="700,240;700,210;280,210;280,240" skipType="REJECT">2</skip>
|
||||||
</node>
|
</node>
|
||||||
<node nodeType="between" nodeCode="5" nodeName="hr审批" permissionFlag="warmFlowInitiator"
|
<node nodeType="between" nodeCode="5" nodeName="hr审批" permissionFlag="warmFlowInitiator"
|
||||||
coordinate="920,280|920,280" skipAnyNode="Y" nodeRatio="0"
|
coordinate="920,280|920,280" skipAnyNode="Y" nodeRatio="0"
|
||||||
listenerType="start,assignment,finish,permission,create"
|
listenerType="start,assignment,finish,create"
|
||||||
listenerPath="com.ruoyi.system.Listener.StartListener@@323@@com.ruoyi.system.Listener.FinishListener@@com.ruoyi.system.Listener.PermissionListener@@com.ruoyi.system.Listener.CreateListener">
|
listenerPath="com.ruoyi.system.Listener.StartListener@@com.ruoyi.system.Listener.AssignmentListener@@com.ruoyi.system.Listener.FinishListener@@com.ruoyi.system.Listener.CreateListener">
|
||||||
<skip coordinate="970,280;1100,280" skipType="PASS">6</skip>
|
<skip coordinate="970,280;1100,280" skipType="PASS">6</skip>
|
||||||
</node>
|
</node>
|
||||||
<node nodeType="end" nodeCode="6" nodeName="结束" coordinate="1120,280|1120,280" skipAnyNode="N"
|
<node nodeType="end" nodeCode="6" nodeName="结束" coordinate="1120,280|1120,280" skipAnyNode="N"
|
||||||
listenerType="start,assignment,finish,permission,create"
|
listenerType="start,assignment,finish,create"
|
||||||
listenerPath="com.ruoyi.system.Listener.StartListener@@323@@com.ruoyi.system.Listener.FinishListener@@com.ruoyi.system.Listener.PermissionListener@@com.ruoyi.system.Listener.CreateListener"/>
|
listenerPath="com.ruoyi.system.Listener.StartListener@@com.ruoyi.system.Listener.AssignmentListener@@com.ruoyi.system.Listener.FinishListener@@com.ruoyi.system.Listener.CreateListener"/>
|
||||||
</definition>
|
</definition>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user