feat(流程管理):

1.默认完成流程发起人节点任务。
2.处理并行网关下获取下一节点数据错误。
3.流程委派。
4.流程转办。
5.启动流程默认设置会签人员。
6.优化人员选项。
approve-sys
tony 3 years ago
parent 163816ad82
commit 5f6b786414

@ -49,4 +49,17 @@ public class ProcessConstants {
* userType
*/
public static final String PROCESS_CUSTOM_USER_TYPE = "userType";
/**
*
*/
public static final String PROCESS_INITIATOR = "initiator";
/**
*
*/
public static final String FLOWABLE_SKIP_EXPRESSION_ENABLED = "_FLOWABLE_SKIP_EXPRESSION_ENABLED";
}

@ -0,0 +1,42 @@
package com.ruoyi.common.enums;
/**
*
*
* @author Xuan xuan
* @date 2021/4/19
*/
public enum FlowComment {
/**
*
*/
NORMAL("1", "正常意见"),
REBACK("2", "退回意见"),
REJECT("3", "驳回意见"),
DELEGATE("4", "委派意见"),
ASSIGN("5", "转办意见");
/**
*
*/
private final String type;
/**
*
*/
private final String remark;
FlowComment(String type, String remark) {
this.type = type;
this.remark = remark;
}
public String getType() {
return type;
}
public String getRemark() {
return remark;
}
}

@ -84,6 +84,14 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.eweb4j/fel -->
<dependency>
<groupId>org.eweb4j</groupId>
<artifactId>fel</artifactId>
<version>0.8</version>
</dependency>
</dependencies>
<!-- <build>-->

@ -76,8 +76,7 @@ public class FlowTaskController {
@ApiOperation(value = "审批任务")
@PostMapping(value = "/complete")
public AjaxResult complete(@RequestBody FlowTaskVo flowTaskVo) {
flowTaskService.completeTask(flowTaskVo);
return AjaxResult.success();
return flowTaskService.complete(flowTaskVo);
}
@ApiOperation(value = "驳回任务")

@ -0,0 +1,230 @@
package com.ruoyi.flowable.flow;
import com.greenpineyu.fel.FelEngine;
import com.greenpineyu.fel.FelEngineImpl;
import com.greenpineyu.fel.context.FelContext;
import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.*;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.TaskService;
import org.flowable.engine.repository.ProcessDefinition;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* @author Xuan xuan
* @date 2021/4/19 20:51
*/
public class FindNextNodeUtil {
/**
*
*
* @param repositoryService
* @param map
* @return
*/
public static List<UserTask> getNextUserTasks(RepositoryService repositoryService, org.flowable.task.api.Task task, Map<String, Object> map) {
List<UserTask> data = new ArrayList<>();
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(task.getProcessDefinitionId()).singleResult();
BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId());
Process mainProcess = bpmnModel.getMainProcess();
Collection<FlowElement> flowElements = mainProcess.getFlowElements();
String key = task.getTaskDefinitionKey();
FlowElement flowElement = bpmnModel.getFlowElement(key);
next(flowElements, flowElement, map, data);
return data;
}
public static void next(Collection<FlowElement> flowElements, FlowElement flowElement, Map<String, Object> map, List<UserTask> nextUser) {
//如果是结束节点
if (flowElement instanceof EndEvent) {
//如果是子任务的结束节点
if (getSubProcess(flowElements, flowElement) != null) {
flowElement = getSubProcess(flowElements, flowElement);
}
}
//获取Task的出线信息--可以拥有多个
List<SequenceFlow> outGoingFlows = null;
if (flowElement instanceof Task) {
outGoingFlows = ((Task) flowElement).getOutgoingFlows();
} else if (flowElement instanceof Gateway) {
outGoingFlows = ((Gateway) flowElement).getOutgoingFlows();
} else if (flowElement instanceof StartEvent) {
outGoingFlows = ((StartEvent) flowElement).getOutgoingFlows();
} else if (flowElement instanceof SubProcess) {
outGoingFlows = ((SubProcess) flowElement).getOutgoingFlows();
} else if (flowElement instanceof CallActivity) {
outGoingFlows = ((CallActivity) flowElement).getOutgoingFlows();
}
if (outGoingFlows != null && outGoingFlows.size() > 0) {
//遍历所有的出线--找到可以正确执行的那一条
for (SequenceFlow sequenceFlow : outGoingFlows) {
//1.有表达式且为true
//2.无表达式
String expression = sequenceFlow.getConditionExpression();
if (expression == null ||
Boolean.parseBoolean(
String.valueOf(
result(map, expression.substring(expression.lastIndexOf("{") + 1, expression.lastIndexOf("}")))))) {
//出线的下一节点
String nextFlowElementID = sequenceFlow.getTargetRef();
if (checkSubProcess(nextFlowElementID, flowElements, nextUser)) {
continue;
}
//查询下一节点的信息
FlowElement nextFlowElement = getFlowElementById(nextFlowElementID, flowElements);
//调用流程
if (nextFlowElement instanceof CallActivity) {
CallActivity ca = (CallActivity) nextFlowElement;
if (ca.getLoopCharacteristics() != null) {
UserTask userTask = new UserTask();
userTask.setId(ca.getId());
userTask.setId(ca.getId());
userTask.setLoopCharacteristics(ca.getLoopCharacteristics());
userTask.setName(ca.getName());
nextUser.add(userTask);
}
next(flowElements, nextFlowElement, map, nextUser);
}
//用户任务
if (nextFlowElement instanceof UserTask) {
nextUser.add((UserTask) nextFlowElement);
}
//排他网关
else if (nextFlowElement instanceof ExclusiveGateway) {
next(flowElements, nextFlowElement, map, nextUser);
}
//并行网关
else if (nextFlowElement instanceof ParallelGateway) {
next(flowElements, nextFlowElement, map, nextUser);
}
//接收任务
else if (nextFlowElement instanceof ReceiveTask) {
next(flowElements, nextFlowElement, map, nextUser);
}
//服务任务
else if (nextFlowElement instanceof ServiceTask) {
next(flowElements, nextFlowElement, map, nextUser);
}
//子任务的起点
else if (nextFlowElement instanceof StartEvent) {
next(flowElements, nextFlowElement, map, nextUser);
}
//结束节点
else if (nextFlowElement instanceof EndEvent) {
next(flowElements, nextFlowElement, map, nextUser);
}
}
}
}
}
/**
*
*/
public static boolean checkSubProcess(String Id, Collection<FlowElement> flowElements, List<UserTask> nextUser) {
for (FlowElement flowElement1 : flowElements) {
if (flowElement1 instanceof SubProcess && flowElement1.getId().equals(Id)) {
SubProcess sp = (SubProcess) flowElement1;
if (sp.getLoopCharacteristics() != null) {
String inputDataItem = sp.getLoopCharacteristics().getInputDataItem();
UserTask userTask = new UserTask();
userTask.setId(sp.getId());
userTask.setLoopCharacteristics(sp.getLoopCharacteristics());
userTask.setName(sp.getName());
nextUser.add(userTask);
return true;
}
}
}
return false;
}
/**
*
*
* @param flowElements
* @param flowElement
* @return
*/
public static FlowElement getSubProcess(Collection<FlowElement> flowElements, FlowElement flowElement) {
for (FlowElement flowElement1 : flowElements) {
if (flowElement1 instanceof SubProcess) {
for (FlowElement flowElement2 : ((SubProcess) flowElement1).getFlowElements()) {
if (flowElement.equals(flowElement2)) {
return flowElement1;
}
}
}
}
return null;
}
/**
* ID,
*
* @param Id ID
* @param flowElements
* @return
*/
public static FlowElement getFlowElementById(String Id, Collection<FlowElement> flowElements) {
for (FlowElement flowElement : flowElements) {
if (flowElement.getId().equals(Id)) {
//如果是子任务,则查询出子任务的开始节点
if (flowElement instanceof SubProcess) {
return getStartFlowElement(((SubProcess) flowElement).getFlowElements());
}
return flowElement;
}
if (flowElement instanceof SubProcess) {
FlowElement flowElement1 = getFlowElementById(Id, ((SubProcess) flowElement).getFlowElements());
if (flowElement1 != null) {
return flowElement1;
}
}
}
return null;
}
/**
*
*
* @param flowElements
* @description:
*/
public static FlowElement getStartFlowElement(Collection<FlowElement> flowElements) {
for (FlowElement flowElement : flowElements) {
if (flowElement instanceof StartEvent) {
return flowElement;
}
}
return null;
}
/**
* el
*
* @param map
* @param expression
* @return
*/
public static Object result(Map<String, Object> map, String expression) {
FelEngine fel = new FelEngineImpl();
FelContext ctx = fel.getContext();
for (Map.Entry<String, Object> entry : map.entrySet()) {
ctx.set(entry.getKey(), entry.getValue());
}
Object result = fel.eval(expression);
return result;
}
}

@ -18,7 +18,7 @@ public interface IFlowTaskService {
*
* @param task
*/
void completeTask(FlowTaskVo task);
AjaxResult complete(FlowTaskVo task);
/**
*

@ -1,17 +1,20 @@
package com.ruoyi.flowable.service.impl;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.constant.ProcessConstants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.enums.FlowComment;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.flowable.domain.dto.FlowProcDefDto;
import com.ruoyi.flowable.factory.FlowServiceFactory;
import com.ruoyi.flowable.service.IFlowDefinitionService;
import com.ruoyi.flowable.service.ISysDeployFormService;
import com.ruoyi.system.domain.SysForm;
import com.ruoyi.system.service.ISysUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.repository.ProcessDefinitionQuery;
@ -27,6 +30,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;
/**
*
@ -40,6 +44,10 @@ public class FlowDefinitionServiceImpl extends FlowServiceFactory implements IFl
@Resource
private ISysDeployFormService sysDeployFormService;
@Resource
private ISysUserService sysUserService;
private static final String BPMN_FILE_SUFFIX = ".bpmn";
@Override
@ -154,14 +162,28 @@ public class FlowDefinitionServiceImpl extends FlowServiceFactory implements IFl
@Override
public AjaxResult startProcessInstanceById(String procDefId, Map<String, Object> variables) {
try {
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(procDefId)
.latestVersion().singleResult();
if (Objects.nonNull(processDefinition) && processDefinition.isSuspended()) {
return AjaxResult.error("流程已被挂起,请先激活流程");
}
// variables.put("skip", true);
// variables.put(ProcessConstants.FLOWABLE_SKIP_EXPRESSION_ENABLED, true);
// 设置流程发起人Id到流程中
Long userId = SecurityUtils.getLoginUser().getUser().getUserId();
// identityService.setAuthenticatedUserId(userId.toString());
Authentication.setAuthenticatedUserId(userId.toString());
variables.put("skip", true);
variables.put("INITIATOR",userId.toString());
variables.put("_FLOWABLE_SKIP_EXPRESSION_ENABLED", true);
runtimeService.startProcessInstanceById(procDefId, variables);
identityService.setAuthenticatedUserId(userId.toString());
List<SysUser> users = sysUserService.selectUserList(new SysUser());
List<String> collect = users.stream().map(sysUser -> sysUser.getUserId().toString()).collect(Collectors.toList());
variables.put("userList", collect);
variables.put(ProcessConstants.PROCESS_INITIATOR, userId);
ProcessInstance processInstance = runtimeService.startProcessInstanceById(procDefId, variables);
// 给第一步申请人节点设置任务执行人和意见 todo:第一个节点不设置为申请人节点有点问题?
Task task = taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()).singleResult();
if (Objects.nonNull(task)) {
taskService.addComment(task.getId(), processInstance.getProcessInstanceId(), FlowComment.NORMAL.getType(), "发起流程申请");
taskService.setAssignee(task.getId(), userId.toString());
taskService.complete(task.getId(), variables);
}
return AjaxResult.success("流程启动成功");
} catch (Exception e) {
e.printStackTrace();

@ -1,7 +1,6 @@
package com.ruoyi.flowable.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
@ -9,6 +8,7 @@ import com.ruoyi.common.constant.ProcessConstants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.enums.FlowComment;
import com.ruoyi.common.exception.CustomException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.flowable.domain.dto.FlowCommentDto;
@ -17,6 +17,7 @@ import com.ruoyi.flowable.domain.dto.FlowTaskDto;
import com.ruoyi.flowable.domain.vo.FlowTaskVo;
import com.ruoyi.flowable.factory.FlowServiceFactory;
import com.ruoyi.flowable.flow.CustomProcessDiagramGenerator;
import com.ruoyi.flowable.flow.FindNextNodeUtil;
import com.ruoyi.flowable.flow.FlowableUtils;
import com.ruoyi.flowable.service.IFlowTaskService;
import com.ruoyi.flowable.service.ISysDeployFormService;
@ -25,7 +26,6 @@ import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.*;
@ -35,14 +35,13 @@ import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.engine.ProcessEngineConfiguration;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.Execution;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.engine.task.Comment;
import org.flowable.identitylink.api.IdentityLink;
import org.flowable.identitylink.api.history.HistoricIdentityLink;
import org.flowable.image.ProcessDiagramGenerator;
import org.flowable.task.api.DelegationState;
import org.flowable.task.api.Task;
import org.flowable.task.api.TaskQuery;
import org.flowable.task.api.history.HistoricTaskInstance;
@ -79,34 +78,25 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
/**
*
*
* @param task
* @param taskVo
*/
@Transactional(rollbackFor = Exception.class)
@Override
public void completeTask(FlowTaskVo task) {
// 添加意见
if (StringUtils.isNotBlank(task.getInstanceId()) && StringUtils.isNotBlank(task.getComment())) {
taskService.addComment(task.getTaskId(), task.getInstanceId(), "1", task.getComment());
public AjaxResult complete(FlowTaskVo taskVo) {
Task task = taskService.createTaskQuery().taskId(taskVo.getTaskId()).singleResult();
if (Objects.isNull(task)){
return AjaxResult.error("任务不存在");
}
Long userId = SecurityUtils.getLoginUser().getUser().getUserId();
// 读取变量 动态设置下一环节审批人
// Map<String, Object> taskValues = task.getValues();
// if (taskValues != null && taskValues.size() > 0) {
// if(StringUtils.isNotBlank((taskValues.get("assignee").toString()))){
// taskService.ad
// }
// if(CollectionUtils.isNotEmpty((List<String>) taskValues.get("candidateUsers"))){
//
// }
// if(CollectionUtils.isNotEmpty((List<String>) taskValues.get("candidateGroups"))){
//
// }
// }
// 设置任务审批人员
taskService.setAssignee(task.getTaskId(), userId.toString());
// 提交任务
taskService.complete(task.getTaskId(), task.getValues());
if (DelegationState.PENDING.equals(task.getDelegationState())) {
taskService.addComment(taskVo.getTaskId(), taskVo.getInstanceId(), FlowComment.DELEGATE.getType(), taskVo.getComment());
taskService.resolveTask(taskVo.getTaskId(), taskVo.getValues());
} else {
taskService.addComment(taskVo.getTaskId(), taskVo.getInstanceId(), FlowComment.NORMAL.getType(), taskVo.getComment());
Long userId = SecurityUtils.getLoginUser().getUser().getUserId();
taskService.setAssignee(taskVo.getTaskId(), userId.toString());
taskService.complete(taskVo.getTaskId(), taskVo.getValues());
}
return AjaxResult.success();
}
/**
@ -208,9 +198,7 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
}
}));
// 设置驳回意见
currentTaskIds.forEach(item -> {
taskService.addComment(item, task.getProcessInstanceId(), "3", flowTaskVo.getComment());
});
currentTaskIds.forEach(item -> taskService.addComment(item, task.getProcessInstanceId(), FlowComment.REJECT.getType(), flowTaskVo.getComment()));
try {
// 如果父级任务多于 1 个,说明当前节点不是并行节点,原因为不考虑多对多情况
@ -299,7 +287,7 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
}));
// 设置回退意见
for (String currentTaskId : currentTaskIds) {
taskService.addComment(currentTaskId, task.getProcessInstanceId(), "2", flowTaskVo.getComment());
taskService.addComment(currentTaskId, task.getProcessInstanceId(), FlowComment.REBACK.getType(), flowTaskVo.getComment());
}
try {
@ -364,6 +352,7 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
@Override
public void deleteTask(FlowTaskVo flowTaskVo) {
// todo 待确认删除任务是物理删除任务 还是逻辑删除,让这个任务直接通过?
taskService.deleteTask(flowTaskVo.getTaskId(),flowTaskVo.getComment());
}
/**
@ -396,7 +385,7 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
@Override
@Transactional(rollbackFor = Exception.class)
public void delegateTask(FlowTaskVo flowTaskVo) {
taskService.delegateTask(flowTaskVo.getTaskId(), flowTaskVo.getAssignee());
}
@ -408,6 +397,7 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
@Override
@Transactional(rollbackFor = Exception.class)
public void assignTask(FlowTaskVo flowTaskVo) {
taskService.setAssignee(flowTaskVo.getTaskId(),flowTaskVo.getComment());
}
/**
@ -433,6 +423,7 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
flowTask.setCreateTime(hisIns.getStartTime());
flowTask.setFinishTime(hisIns.getEndTime());
flowTask.setProcInsId(hisIns.getId());
// 计算耗时
if (Objects.nonNull(hisIns.getEndTime())) {
long time = hisIns.getEndTime().getTime() - hisIns.getStartTime().getTime();
@ -452,34 +443,35 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
flowTask.setProcDefVersion(pd.getVersion());
// 当前所处流程
Task task = taskService.createTaskQuery().processInstanceId(hisIns.getId()).singleResult();
if (Objects.nonNull(task)) {
flowTask.setTaskName(task.getName());
flowTask.setTaskId(task.getId());
// 指定审批人员信息
if (StringUtils.isNotBlank(task.getAssignee())) {
SysUser sysUser = sysUserService.selectUserById(Long.parseLong(task.getAssignee()));
flowTask.setAssigneeId(sysUser.getUserId());
flowTask.setAssigneeName(sysUser.getNickName());
flowTask.setDeptName(sysUser.getDept().getDeptName());
} else {
// 候选审批人员信息
List<IdentityLink> linksForTask = taskService.getIdentityLinksForTask(task.getId());
StringBuilder stringBuilder = new StringBuilder();
for (IdentityLink identityLink : linksForTask) {
if ("candidate".equals(identityLink.getType())) {
if (StringUtils.isNotBlank(identityLink.getUserId())) {
SysUser sysUser = sysUserService.selectUserById(Long.parseLong(identityLink.getUserId()));
stringBuilder.append(sysUser.getNickName()).append(",");
}
if (StringUtils.isNotBlank(identityLink.getGroupId())) {
SysRole sysRole = sysRoleService.selectRoleById(Long.parseLong(identityLink.getGroupId()));
stringBuilder.append(sysRole.getRoleName()).append(",");
}
}
}
flowTask.setCandidate(stringBuilder.substring(0, stringBuilder.length() - 1));
}
// Task task = taskService.createTaskQuery().processInstanceId(hisIns.getId()).singleResult();
List<Task> taskList = taskService.createTaskQuery().processInstanceId(hisIns.getId()).list();
if (CollectionUtils.isNotEmpty(taskList)) {
// flowTask.setTaskName(task.getName());
flowTask.setTaskId(taskList.get(0).getId());
// // 指定审批人员信息
// if (StringUtils.isNotBlank(task.getAssignee())) {
// SysUser sysUser = sysUserService.selectUserById(Long.parseLong(task.getAssignee()));
// flowTask.setAssigneeId(sysUser.getUserId());
// flowTask.setAssigneeName(sysUser.getNickName());
// flowTask.setDeptName(sysUser.getDept().getDeptName());
// } else {
// // 候选审批人员信息
// List<IdentityLink> linksForTask = taskService.getIdentityLinksForTask(task.getId());
// StringBuilder stringBuilder = new StringBuilder();
// for (IdentityLink identityLink : linksForTask) {
// if ("candidate".equals(identityLink.getType())) {
// if (StringUtils.isNotBlank(identityLink.getUserId())) {
// SysUser sysUser = sysUserService.selectUserById(Long.parseLong(identityLink.getUserId()));
// stringBuilder.append(sysUser.getNickName()).append(",");
// }
// if (StringUtils.isNotBlank(identityLink.getGroupId())) {
// SysRole sysRole = sysRoleService.selectRoleById(Long.parseLong(identityLink.getGroupId()));
// stringBuilder.append(sysRole.getRoleName()).append(",");
// }
// }
// }
// flowTask.setCandidate(stringBuilder.substring(0, stringBuilder.length() - 1));
// }
} else {
List<HistoricTaskInstance> historicTaskInstance = historyService.createHistoricTaskInstanceQuery().processInstanceId(hisIns.getId()).orderByHistoricTaskInstanceEndTime().desc().list();
flowTask.setTaskId(historicTaskInstance.get(0).getId());
@ -743,8 +735,8 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
}
map.put("flowList", hisFlowList);
// 查询当前任务是否完成
Task task = taskService.createTaskQuery().processInstanceId(procInsId).singleResult();
if (Objects.nonNull(task)) {
List<Task> taskList = taskService.createTaskQuery().processInstanceId(procInsId).list();
if (CollectionUtils.isNotEmpty(taskList)) {
map.put("finished", true);
} else {
map.put("finished", false);
@ -753,7 +745,7 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
// 第一次申请获取初始化表单
if (StringUtils.isNotBlank(deployId)) {
SysForm sysForm = sysInstanceFormService.selectSysDeployFormByDeployId(deployId);
if (Objects.isNull(sysForm)){
if (Objects.isNull(sysForm)) {
return AjaxResult.error("请先配置流程表单");
}
map.put("formData", JSONObject.parseObject(sysForm.getFormContent()));
@ -851,26 +843,11 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
Task task = taskService.createTaskQuery().taskId(flowTaskVo.getTaskId()).singleResult();
FlowNextDto flowNextDto = new FlowNextDto();
if (Objects.nonNull(task)) {
ExecutionEntity ee = (ExecutionEntity) runtimeService.createExecutionQuery()
.executionId(task.getExecutionId()).singleResult();
// 当前审批节点
String crruentActivityId = ee.getActivityId();
BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());
FlowNode flowNode = (FlowNode) bpmnModel.getFlowElement(crruentActivityId);
// 输出连线
List<SequenceFlow> outFlows = flowNode.getOutgoingFlows();
for (SequenceFlow sequenceFlow : outFlows) {
// 下一个审userTask
FlowElement targetFlow = sequenceFlow.getTargetFlowElement();
if (targetFlow instanceof UserTask) {
// 读取自定义属性 动态选择下一任务审批人
// todo 1. 读取自定义节点属性来验证是否动态选择审批人
// 2. 验证表达式
String dataType = targetFlow.getAttributeValue(ProcessConstants.NAMASPASE, ProcessConstants.PROCESS_CUSTOM_DATA_TYPE);
String userType = targetFlow.getAttributeValue(ProcessConstants.NAMASPASE, ProcessConstants.PROCESS_CUSTOM_USER_TYPE);
List<UserTask> nextUserTask = FindNextNodeUtil.getNextUserTasks(repositoryService, task, new HashMap<>());
if (CollectionUtils.isNotEmpty(nextUserTask)) {
for (UserTask userTask : nextUserTask) {
String dataType = userTask.getAttributeValue(ProcessConstants.NAMASPASE, ProcessConstants.PROCESS_CUSTOM_DATA_TYPE);
String userType = userTask.getAttributeValue(ProcessConstants.NAMASPASE, ProcessConstants.PROCESS_CUSTOM_USER_TYPE);
if (ProcessConstants.DATA_TYPE.equals(dataType)) {
// 指定单个人员
if (ProcessConstants.USER_TYPE_ASSIGNEE.equals(userType)) {
@ -896,9 +873,9 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
flowNextDto.setRoleList(sysRoles);
}
}
} else if (targetFlow instanceof EndEvent) {
return AjaxResult.success("流程已完结", null);
}
} else {
return AjaxResult.success("流程已完结", null);
}
}
return AjaxResult.success(flowNextDto);

@ -19,6 +19,15 @@ export function complete(data) {
})
}
// 委派任务
export function delegate(data) {
return request({
url: '/flowable/task/delegate',
method: 'post',
data: data
})
}
// 退回任务
export function returnTask(data) {
return request({

@ -24,39 +24,25 @@
>{{item.name}}</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item label="任务接收" prop="targetKey" v-show="taskForm.noUserShow">
<el-radio-group @change="handleCheckChange" v-model="assignee">
<<el-radio-button
v-for="item in userList"
:key="item.userId"
:label="item.userId"
>{{item.nickName}}</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item label="候选人员" prop="targetKey" v-show="taskForm.allUserShow">
<el-checkbox-group @change="handleCheckChange" v-model="users">
<<el-checkbox
v-for="item in userList"
:key="item.userId"
:label="item.userId"
>{{item.nickName}}</el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item label="候选组" prop="targetKey" v-show="taskForm.allGroupShow">
<el-radio-group @change="handleCheckChange" v-model="assignee">
<<el-radio-button
v-for="item in roleList"
:key="item.roleId"
:label="item.roleId"
>{{item.roleName}}</el-radio-button>
</el-radio-group>
<el-form-item label="任务接收" prop="targetKey" v-show="taskForm.sendUserShow">
<el-select style="width: 50%" v-model="assignee" @change="handleCheckChange" :multiple="taskForm.multiple" placeholder="请选择">
<el-option
v-for="item in userList"
:key="item.userId"
:label="item.nickName"
:value="item.userId">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="审批意见" prop="comment" :rules="[{ required: true, message: '请输入意见', trigger: 'blur' }]">
<el-input style="width: 50%" type="textarea" v-model="taskForm.comment" placeholder="请输入意见"/>
</el-form-item>
<el-form-item>
<div v-show="taskForm.defaultTaskShow">
<el-button icon="el-icon-edit-outline" type="primary" size="mini" @click="handleComplete"></el-button>
<el-button icon="el-icon-edit-outline" type="success" size="mini" @click="handleComplete"></el-button>
<el-button icon="el-icon-edit-outline" type="primary" size="mini" @click="handleDelegate"></el-button>
<el-button icon="el-icon-edit-outline" type="primary" size="mini" @click="handleAssign"></el-button>
<el-button icon="el-icon-edit-outline" type="primary" size="mini" @click="handleDelegate"></el-button>
<el-button icon="el-icon-refresh-left" type="warning" size="mini" @click="handleReturn">退</el-button>
<el-button icon="el-icon-circle-close" type="danger" size="mini" @click="handleReject"></el-button>
</div>
@ -64,6 +50,10 @@
<el-button type="primary" @click="submitReturnTask"> </el-button>
<el-button @click="cancelTask"> </el-button>
</div>
<div v-show="taskForm.delegateTaskShow">
<el-button type="primary" @click="submitDeleteTask"> </el-button>
<el-button @click="cancelDelegateTask"> </el-button>
</div>
</el-form-item>
</el-form>
</div>
@ -127,7 +117,7 @@
import {flowRecord} from "@/api/flowable/finished";
import Parser from '@/components/parser/Parser'
import {definitionStart, getProcessVariables, userList } from "@/api/flowable/definition";
import {complete, rejectTask, returnList, returnTask, getNextFlowNode} from "@/api/flowable/todo";
import {complete, rejectTask, returnList, returnTask, getNextFlowNode, delegate} from "@/api/flowable/todo";
export default {
name: "Record",
components: {
@ -145,10 +135,10 @@ export default {
variablesForm: {}, //
taskForm:{
returnTaskShow: false, // 退
delegateTaskShow: false, // 退
defaultTaskShow: true, //
noUserShow: false, //
allUserShow: false, //
allGroupShow: false, //
sendUserShow: false, //
multiple: false,
comment:"", //
procInsId: "", //
instanceId: "", //
@ -158,8 +148,6 @@ export default {
vars: "",
},
userList:[], //
roleList:[], //
users:[], //
assignee: null,
formConf: {}, //
formConfOpen: false, //
@ -272,16 +260,19 @@ export default {
getNextFlowNode(params).then(res => {
const data = res.data;
if (data) {
this.taskForm.sendUserShow = true;
if (data.type === 'assignee') {
this.userList = res.data.userList;
this.taskForm.noUserShow = true;
} else if (data.type === 'candidateUsers') {
this.userList = res.data.userList;
this.taskForm.allUserShow = true;
this.taskForm.multiple = true;
} else {
this.roleList = res.data.roleList
this.taskForm.allGroupShow = true;
res.data.roleList.forEach(role =>{
role.userId = role.roleId;
role.nickName = role.roleName;
})
this.userList = res.data.roleList;
this.taskForm.multiple = false;
}
}
})
@ -297,6 +288,15 @@ export default {
});
}
});
},
/** 委派任务 */
handleDelegate() {
this.taskForm.delegateTaskShow = true;
this.taskForm.defaultTaskShow = false;
},
handleAssign(){
},
/** 返回页面 */
goBack() {
@ -360,14 +360,15 @@ export default {
this.returnTaskList = res.data;
this.taskForm.returnTaskShow = true;
this.taskForm.defaultTaskShow = false;
this.taskForm.noUserShow = false;
this.taskForm.sendUserShow = false;
this.taskForm.values = null;
})
},
/** 取消回退任务按钮 */
cancelTask() {
this.taskForm.returnTaskShow = false;
this.taskForm.defaultTaskShow = true;
this.taskForm.noUserShow = true;
this.taskForm.sendUserShow = true;
this.returnTaskList = [];
},
/** 提交退回任务 */
@ -380,7 +381,25 @@ export default {
});
}
});
}
},
/** 委派任务 */
submitDeleteTask() {
this.$refs["taskForm"].validate(valid => {
if (valid) {
delegate(this.taskForm).then(response => {
this.msgSuccess(response.msg);
this.goBack();
});
}
});
},
/** 取消回退任务按钮 */
cancelDelegateTask() {
this.taskForm.delegateTaskShow = false;
this.taskForm.defaultTaskShow = true;
this.taskForm.sendUserShow = true;
this.returnTaskList = [];
},
}
};
</script>

Loading…
Cancel
Save