关联文章 activiti退回,支持多人任务退回,支持分支退回主线,主线退回分支
前提 我们再进行包容网关或者排他网关时会主动在其后的线上加上判断方法flowMethod.rggyPd(execution,'"+线id+"')")来进行人工选择,
如图
选择那个节点就走那条线,,所以在完成任务时会将选择的线加入到流程变量中
代码如下:获取下个节点代码 逻辑是第一次前台传入当前任务id 这个接口返回下个节点 前台判断节点类型 若是并行网关 则继续传入当前任务id和网关id来获取下个节点 若是排他或者包容网管则前台将列出后续节点供用户选择,最后将选择的所有节点再传回给后台进行完成任务操作
@Override
public List<NextNodeVo> getNextNodesAndUserOneLevel(String taskId,String actId) {
//返回结果存储
List<NextNodeVo> nodes = new ArrayList<>();
//获取当前任务
Task nowTask = taskService.createTaskQuery().taskId(taskId).singleResult();
if(nowTask==null){
throw new ZzpaasException("该任务不存在或已办理!");
}
ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
.getDeployedProcessDefinition(nowTask.getProcessDefinitionId());
//获取当前节点
ActivityImpl nowActivity = processDefinitionEntity.findActivity(nowTask.getTaskDefinitionKey());
//判断当前节点是否多人任务
if (CommonUtils.isDuoren(nowActivity)) {//是多人任务
//获取实例总数变量 和 完成实例数变量
Object zongTaskCountObj = runtimeService.getVariable(nowTask.getExecutionId(), "nrOfInstances");
Object completeTaskCountObj = runtimeService.getVariable(nowTask.getExecutionId(), "nrOfCompletedInstances");
if (zongTaskCountObj != null && completeTaskCountObj != null) {
int zongTaskCount = Integer.parseInt(zongTaskCountObj.toString());
int completeTaskCount = Integer.parseInt(completeTaskCountObj.toString());
if ((zongTaskCount - completeTaskCount) != 1) {//多人任务时 还有其他人尚未办理
return nodes;
}
} else {
throw new ZzpaasException("多人任务变量存储异常。");
}
}
if(StringUtils.isBlank(actId)){
actId=nowTask.getTaskDefinitionKey();
}
//获取指定节点
ActivityImpl activity = processDefinitionEntity.findActivity(actId);
String actType = activity.getProperty("type").toString();
//获取指定节点的所有出线
List<PvmTransition> outgoingTransitions = activity.getOutgoingTransitions();
if(actType.equals("userTask")){
boolean isSubAct=false;//是否子流程节点
ActivityImpl parentActivity=null;
if(activity.getParent() instanceof ActivityImpl){
parentActivity=(ActivityImpl)activity.getParent();
String parentActType = parentActivity.getProperty("type").toString();
if(parentActType.equals("subProcess")){//当前节点是子流程中的节点
isSubAct=true;
}
}
if(isSubAct){//当子流程结束时出线设置为子流程结构的出线
if(outgoingTransitions.size()==0){//子流程中可以没有结束节点 但是设定必须要有开始和结束节点
outgoingTransitions=parentActivity.getOutgoingTransitions();
}else {//人工任务必须只有一条出线
PvmActivity subDes = outgoingTransitions.get(0).getDestination();
if(subDes.getProperty("type").toString().equals("endEvent")){
outgoingTransitions=parentActivity.getOutgoingTransitions();
}
}
}
}
for (PvmTransition outgoingTransition : outgoingTransitions) {
boolean isRggy=false;
JSONObject node = new JSONObject();
//人工任务设定只有一条出线
PvmActivity pa = outgoingTransition.getDestination();//获取终点节点
String type = pa.getProperty("type").toString();
if(type.equals("subProcess")){//子流程
List<? extends PvmActivity> subActs = pa.getActivities();
for (PvmActivity subAct : subActs) {
String subType = subAct.getProperty("type").toString();
if(subType.equals("startEvent")){
PvmTransition subStartOutgoingTransition = subAct.getOutgoingTransitions().get(0);
pa=subStartOutgoingTransition.getDestination();
break;
}
}
}
NextNodeVo nextNodeVo = new NextNodeVo();
nextNodeVo.setActId(pa.getId());
nextNodeVo.setName(pa.getProperty("name")==null?"":pa.getProperty("name").toString());
nextNodeVo.setType(type);
nextNodeVo.setRggy(isRggy);
nextNodeVo.setSourceSeq(outgoingTransition.getId());
nextNodeVo.setSourceActId(outgoingTransition.getSource().getId());
//exclusiveGateway parallelGateway inclusiveGateway
boolean isAddNode=false;
if(actType.equalsIgnoreCase("exclusiveGateway")||actType.equalsIgnoreCase("inclusiveGateway")){
//variablesForExclusiveGateway.put(chuxian.getId(),false);
Object wangguanConditionText = outgoingTransition.getProperty("conditionText");//线的条件
String wangguanConditionTextStr = "";
if (wangguanConditionText != null) {
wangguanConditionTextStr = wangguanConditionText.toString().trim();
}
if(wangguanConditionTextStr.contains("flowMethod.rggyPd")){
isRggy=true;
}
nextNodeVo.setRggy(isRggy);
if (StringUtils.isNotBlank(wangguanConditionTextStr)) {
//判断条件是否成立
ExecuteUelExpressionCmd uelExpressionCmd=new ExecuteUelExpressionCmd(taskId,wangguanConditionTextStr);
Boolean pass = (Boolean)managementService.executeCommand(uelExpressionCmd);
//String xianId = chuxian.getId();
//将来线的条件key要存在其他表中
//1.根据id获取其他表中存储的key 获取值存入Map v中
// 再流程变量中,
//runtimeService.setVariables(processInstId,v);
//Map<String, Object> variables = runtimeService.getVariables(nowTask.getExecutionId());
//根据el表达式判断是否成立
//boolean conditionForMap = CommonUtils.isConditionForMap(variables, wangguanConditionTextStr);
if(pass){//线条件成立
isAddNode=true;
}
} else {
isAddNode=true;
}
}else{
isAddNode=true;
}
if(isAddNode){
//获取节点自定义设置信息
ActZzActset actset = actZzActsetService.getOne(new QueryWrapper<ActZzActset>()
.eq("PROCESSDEFID", nowTask.getProcessDefinitionId()).eq("ACTID", pa.getId()));
JSONObject setJsonObj=new JSONObject();
String setJsonStr=null;
if(actset!=null){
setJsonStr=actset.getSetjson();
}
if(StringUtils.isNotBlank(setJsonStr)){
setJsonObj=JSONObject.parseObject(setJsonStr);
}
nextNodeVo.setOrderid(setJsonObj.getIntValue("orderid"));
if(type.equals("userTask")){//获取可供选择的人
JSONObject userMap=new JSONObject();
ActivityImpl paActivity = processDefinitionEntity.findActivity(pa.getId());
TaskDefinition taskDefinition = null;
Object taskDefinitionObj = paActivity.getProperty("taskDefinition");
if (taskDefinitionObj != null && taskDefinitionObj instanceof TaskDefinition) {
taskDefinition = (TaskDefinition) taskDefinitionObj;
}
if (taskDefinition == null) {
throw new ZzpaasException("获取节点信息失败!");
}
userMap.put("targets", new ArrayList<>());
userMap.put("isAllUser", false);
if(setJsonObj.get("userScope")!=null){
String userScope=setJsonObj.getString("userScope");
List userFromUserScope = processUtils.getUserFromUserScope(userScope,nowTask.getProcessInstanceId(),nowTask.getTaskDefinitionKey(),taskId,nowTask.getAssignee());
if(userFromUserScope!=null){
userMap.put("targets", userFromUserScope);//办理人列表
}
if(userScope.equals(UserScopeConstants.USERS_FROEM_ALL)){//任意指定 说明从所有人员中选择 这个需要返回给前台
userMap.put("isAllUser", true);
}
}
userMap.put("isCheckedMore", false);//人员是否多选 true 多选 false单选
if (paActivity.getActivityBehavior() instanceof SequentialMultiInstanceBehavior) {
//多人任务
userMap.put("isCheckedMore", true);
//resultMap.put("taskType", ProcessConstants.TASK_TYPE_ASSIGNEE);//任务类型 个人任务
userMap.put("targetType", ProcessConstants.TARGET_TYPE_DUOREN_CHUANXING);//分配方案为多人任务-串行
//获取已选择的办理人
Object variable = runtimeService.getVariable(nowTask.getProcessInstanceId(), ProcessConstants.TARGET_ASSIGNEE_TYPE_DUOREN_LIST_KEY + pa.getId());
userMap.put("checkedTargets", variable);
}else if (paActivity.getActivityBehavior() instanceof ParallelMultiInstanceBehavior) {
//多人任务
userMap.put("isCheckedMore", true);
//resultMap.put("taskType", ProcessConstants.TASK_TYPE_ASSIGNEE);//任务类型 个人任务
userMap.put("targetType", ProcessConstants.TARGET_TYPE_DUOREN_BINGXING);//分配方案为多人任务-并行
//应先判断元素集合 元素变量 assignee是否有值 且正确 否则抛异常 设置有误!
//获取已选择的办理人
Object variable = runtimeService.getVariable(nowTask.getProcessInstanceId(), ProcessConstants.TARGET_ASSIGNEE_TYPE_DUOREN_LIST_KEY + pa.getId());
userMap.put("checkedTargets", variable);
}else{
Expression assigneeExpression = taskDefinition.getAssigneeExpression();
if (assigneeExpression != null && StringUtils.isNotBlank(assigneeExpression.getExpressionText())) {
String expressionText = assigneeExpression.getExpressionText().trim();
if (expressionText.startsWith(ProcessConstants.TARGET_ASSIGNEE_TYPE_RYZD)) {//指定用户 (单人任务)
userMap.put("targetType", ProcessConstants.TARGET_TYPE_RYZD);//分配方案为用户指定 (单人任务(从节点设置的范围中获取用户进行选择))
//获取已选择的办理人
Object variable = runtimeService.getVariable(nowTask.getProcessInstanceId(), ProcessConstants.TARGET_ASSIGNEE_TYPE_RYZD_VARIABLES_KEY + pa.getId());
userMap.put("checkedTargets", variable);
} else if (expressionText.equals(ProcessConstants.TARGET_ASSIGNEE_TYPE_LCQDZ)) {//流程启动者
userMap.put("targetType", ProcessConstants.TARGET_TYPE_LCQDZ);//分配方案为流程启动者
//获取流程实例的流程变量createUser
String createUser = runtimeService.getVariable(nowTask.getProcessInstanceId(), ProcessConstants.TARGET_ASSIGNEE_TYPE_LCQDZ_VARIABLES_KEY).toString();
//获取已选择的办理人
userMap.put("checkedTargets", createUser);
} else {//固定某个人 这个固定某个人就是 分配人员直接写的人员名 (这个不存在,在本系统中被废除)
userMap.put("targetType", ProcessConstants.TARGET_TYPE_GDRY);//分配方案为固定某个人
String userName = expressionText;
//获取已选择的办理
userMap.put("checkedTargets", userName);
}
} else {//候选者任务
if (taskDefinition.getCandidateUserIdExpressions() != null && taskDefinition.getCandidateUserIdExpressions().size() > 0) {
//候选人 任务 抢办任务
userMap.put("targetType", ProcessConstants.TARGET_TYPE_HXR);//分配方案为候选人模式
userMap.put("isCheckedMore", true);//人员是否多选 true 多选 false单选
//获取已选择的办理人
Object variable = runtimeService.getVariable(nowTask.getProcessInstanceId(), ProcessConstants.TARGET_ASSIGNEE_TYPE_RYZD_VARIABLES_KEY + pa.getId());
userMap.put("checkedTargets", variable);
}else{
throw new ZzpaasException("未分配用户");
}
}
}
nextNodeVo.setUserMap(userMap);
}
nodes.add(nextNodeVo);
}
}
if(nodes.size()>1){//按orderid升序排序
List<NextNodeVo> collect = nodes.stream().sorted((n1, n2) -> n1.getOrderid().compareTo(n2.getOrderid())).collect(Collectors.toList());
return collect;
}
return nodes;
}
由于刚启动项目前没有流程实例id所以获取第一个节点要单独出来(第一个节点可能是包容网关)
@Override
public List<NextNodeVo> getFirstNodesAndAssignees(String key,String processDefId,String actId) {
//返回结果存储
List<NextNodeVo> nodes = new ArrayList<>();
ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
if(StringUtils.isNotBlank(processDefId)){
processDefinitionQuery.processDefinitionId(processDefId);
}else{
processDefinitionQuery.processDefinitionKey(key);
processDefinitionQuery.processDefinitionWithoutTenantId().latestVersion();
}
ProcessDefinition processDefinition = processDefinitionQuery.singleResult();
ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
.getDeployedProcessDefinition(processDefinition.getId());
if (StringUtils.isBlank(actId)) {
List<ActivityImpl> activities = processDefinitionEntity.getActivities();
for (ActivityImpl activity : activities) {
String type = activity.getProperty("type").toString();
if ("startEvent".equals(type)) {//开始节点
actId=activity.getId();
break;
}
}
}
//获取指定节点
ActivityImpl activity = processDefinitionEntity.findActivity(actId);
String actType = activity.getProperty("type").toString();
//获取指定节点的所有出线
List<PvmTransition> outgoingTransitions = activity.getOutgoingTransitions();
for (PvmTransition outgoingTransition : outgoingTransitions) {
boolean isRggy=false;
JSONObject node = new JSONObject();
//人工任务设定只有一条出线
PvmActivity pa = outgoingTransition.getDestination();//获取终点节点
String type = pa.getProperty("type").toString();
if(type.equals("subProcess")){//子流程
List<? extends PvmActivity> subActs = pa.getActivities();
for (PvmActivity subAct : subActs) {
String subType = subAct.getProperty("type").toString();
if(subType.equals("startEvent")){
PvmTransition subStartOutgoingTransition = subAct.getOutgoingTransitions().get(0);
pa=subStartOutgoingTransition.getDestination();
break;
}
}
}
NextNodeVo nextNodeVo = new NextNodeVo();
nextNodeVo.setActId(pa.getId());
nextNodeVo.setName(pa.getProperty("name")==null?"":pa.getProperty("name").toString());
nextNodeVo.setType(type);
nextNodeVo.setRggy(isRggy);
nextNodeVo.setSourceSeq(outgoingTransition.getId());
nextNodeVo.setSourceActId(outgoingTransition.getSource().getId());
//exclusiveGateway parallelGateway inclusiveGateway
boolean isAddNode=false;
if(actType.equalsIgnoreCase("exclusiveGateway")||actType.equalsIgnoreCase("inclusiveGateway")){
//variablesForExclusiveGateway.put(chuxian.getId(),false);
Object wangguanConditionText = outgoingTransition.getProperty("conditionText");//线的条件
String wangguanConditionTextStr = "";
if (wangguanConditionText != null) {
wangguanConditionTextStr = wangguanConditionText.toString().trim();
}
if(wangguanConditionTextStr.contains("flowMethod.rggyPd")){
isRggy=true;
}
nextNodeVo.setRggy(isRggy);
}
//获取节点自定义设置信息
ActZzActset actset = actZzActsetService.getOne(new QueryWrapper<ActZzActset>()
.eq("PROCESSDEFID", processDefinition.getId()).eq("ACTID", pa.getId()));
JSONObject setJsonObj=new JSONObject();
String setJsonStr=null;
if(actset!=null){
setJsonStr=actset.getSetjson();
}
if(StringUtils.isNotBlank(setJsonStr)){
setJsonObj=JSONObject.parseObject(setJsonStr);
}
nextNodeVo.setOrderid(setJsonObj.getIntValue("orderid"));
if(type.equals("userTask")){//获取可供选择的人
JSONObject userMap=new JSONObject();
ActivityImpl paActivity = processDefinitionEntity.findActivity(pa.getId());
TaskDefinition taskDefinition = null;
Object taskDefinitionObj = paActivity.getProperty("taskDefinition");
if (taskDefinitionObj != null && taskDefinitionObj instanceof TaskDefinition) {
taskDefinition = (TaskDefinition) taskDefinitionObj;
}
if (taskDefinition == null) {
throw new ZzpaasException("获取节点信息失败!");
}
userMap.put("isAllUser", false);
userMap.put("targets", new ArrayList<>());
if(setJsonObj.get("userScope")!=null){
String userScope=setJsonObj.getString("userScope");
List userFromUserScope = processUtils.getUserFromUserScope(userScope,"","","","");
if(userFromUserScope!=null){
userMap.put("targets", userFromUserScope);//办理人列表
}
if(userScope.equals(UserScopeConstants.USERS_FROEM_ALL)){//任意指定 说明从所有人员中选择 这个需要返回给前台
userMap.put("isAllUser", true);
}
}
userMap.put("isCheckedMore", false);//人员是否多选 true 多选 false单选
if (paActivity.getActivityBehavior() instanceof SequentialMultiInstanceBehavior) {
//多人任务
userMap.put("isCheckedMore", true);
//resultMap.put("taskType", ProcessConstants.TASK_TYPE_ASSIGNEE);//任务类型 个人任务
userMap.put("targetType", ProcessConstants.TARGET_TYPE_DUOREN_CHUANXING);//分配方案为多人任务-串行
}else if (paActivity.getActivityBehavior() instanceof ParallelMultiInstanceBehavior) {
//多人任务
userMap.put("isCheckedMore", true);
//resultMap.put("taskType", ProcessConstants.TASK_TYPE_ASSIGNEE);//任务类型 个人任务
userMap.put("targetType", ProcessConstants.TARGET_TYPE_DUOREN_BINGXING);//分配方案为多人任务-并行
}else{
Expression assigneeExpression = taskDefinition.getAssigneeExpression();
if (assigneeExpression != null && StringUtils.isNotBlank(assigneeExpression.getExpressionText())) {
String expressionText = assigneeExpression.getExpressionText().trim();
if (expressionText.startsWith(ProcessConstants.TARGET_ASSIGNEE_TYPE_RYZD)) {//指定用户 (单人任务)
userMap.put("targetType", ProcessConstants.TARGET_TYPE_RYZD);//分配方案为用户指定 (单人任务(从节点设置的范围中获取用户进行选择))
} else if (expressionText.equals(ProcessConstants.TARGET_ASSIGNEE_TYPE_LCQDZ)) {//流程启动者
userMap.put("targetType", ProcessConstants.TARGET_TYPE_LCQDZ);//分配方案为流程启动者
} else {//固定某个人 这个固定某个人就是 分配人员直接写的人员名 (这个不存在,在本系统中被废除)
userMap.put("targetType", ProcessConstants.TARGET_TYPE_GDRY);//分配方案为固定某个人
String userName = expressionText;
//获取已选择的办理
userMap.put("checkedTargets", userName);
}
} else {//候选者任务
if (taskDefinition.getCandidateUserIdExpressions() != null && taskDefinition.getCandidateUserIdExpressions().size() > 0) {
//候选人 任务 抢办任务
userMap.put("targetType", ProcessConstants.TARGET_TYPE_HXR);//分配方案为候选人模式
userMap.put("isCheckedMore", true);//人员是否多选 true 多选 false单选
}else{
throw new ZzpaasException("未分配用户");
}
}
}
nextNodeVo.setUserMap(userMap);
}
nodes.add(nextNodeVo);
}
if(nodes.size()>1){//按orderid升序排序
List<NextNodeVo> collect = nodes.stream().sorted((n1, n2) -> n1.getOrderid().compareTo(n2.getOrderid())).collect(Collectors.toList());
return collect;
}
return nodes;
}
判断el表达式的cmd
package com.zz.flow.utils;
import com.zz.flow.constants.ProcessConstants;
import lombok.Data;
import org.activiti.engine.ActivitiException;
import org.activiti.engine.delegate.Expression;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.Condition;
import org.activiti.engine.impl.HistoricActivityInstanceQueryImpl;
import org.activiti.engine.impl.HistoricTaskInstanceQueryImpl;
import org.activiti.engine.impl.Page;
import org.activiti.engine.impl.bpmn.helper.SkipExpressionUtil;
import org.activiti.engine.impl.cmd.GetDeploymentProcessDefinitionCmd;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.persistence.entity.*;
import org.activiti.engine.impl.pvm.PvmActivity;
import org.activiti.engine.impl.pvm.PvmTransition;
import org.activiti.engine.impl.pvm.delegate.ActivityExecution;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.task.TaskDefinition;
import org.activiti.engine.impl.variable.VariableType;
import org.activiti.engine.impl.variable.VariableTypes;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
/**
* @author lqx
* @date 2020/8/24 9:57
*/
@Data
public class ExecuteUelExpressionCmd implements Command<Object> {
//任务id
protected String taskId;
protected String elStr;
/** logger. */
protected static Logger logger = LoggerFactory
.getLogger(ExecuteUelExpressionCmd.class);
/**
* 指定taskid和跳转到的activityId 自动使用最后的assignee
* @param taskId
*/
public ExecuteUelExpressionCmd(String taskId,String elStr){
this.taskId=taskId;
this.elStr=elStr;
}
/*
以下是源码处理方法
protected void leave(ActivityExecution execution) {
if (log.isDebugEnabled()) {
log.debug("Leaving activity '{}'", execution.getActivity().getId());
}
PvmTransition outgoingSeqFlow = null;
String defaultSequenceFlow = (String)execution.getActivity().getProperty("default");
Iterator transitionIterator = execution.getActivity().getOutgoingTransitions().iterator();
PvmTransition defaultTransition;
while(outgoingSeqFlow == null && transitionIterator.hasNext()) {
defaultTransition = (PvmTransition)transitionIterator.next();
Expression skipExpression = defaultTransition.getSkipExpression();
if (SkipExpressionUtil.isSkipExpressionEnabled(execution, skipExpression)) {
if (SkipExpressionUtil.shouldSkipFlowElement(execution, skipExpression)) {
outgoingSeqFlow = defaultTransition;
}
} else {
Condition condition = (Condition)defaultTransition.getProperty("condition");
if (condition == null && (defaultSequenceFlow == null || !defaultSequenceFlow.equals(defaultTransition.getId())) || condition != null && condition.evaluate(defaultTransition.getId(), execution)) {
if (log.isDebugEnabled()) {
log.debug("Sequence flow '{}'selected as outgoing sequence flow.", defaultTransition.getId());
}
outgoingSeqFlow = defaultTransition;
}
}
}
if (outgoingSeqFlow != null) {
execution.take(outgoingSeqFlow);
} else {
if (defaultSequenceFlow == null) {
throw new ActivitiException("No outgoing sequence flow of the exclusive gateway '" + execution.getActivity().getId() + "' could be selected for continuing the process");
}
defaultTransition = execution.getActivity().findOutgoingTransition(defaultSequenceFlow);
if (defaultTransition == null) {
throw new ActivitiException("Default sequence flow '" + defaultSequenceFlow + "' not found");
}
execution.take(defaultTransition);
}
}*/
/**
* 执行el表达式 获取结果
* @param commandContext
* @return
*/
@Override
public Object execute(CommandContext commandContext) {
//activiti判断条件是否通过在类ExclusiveGatewayActivityBehavior的44行和类UelExpressionCondition
// 获得任务
TaskEntity taskEntity = this.findTask(commandContext);
// 把流程指向任务对应的节点
ExecutionEntity executionEntity = taskEntity.getExecution();
Expression expression = Context.getProcessEngineConfiguration().getExpressionManager().createExpression(elStr);
Object result = expression.getValue(executionEntity);
/*if (result == null) {
throw new ActivitiException("condition expression returns null");
} else if (!(result instanceof Boolean)) {
throw new ActivitiException("condition expression returns non-Boolean: " + result + " (" + result.getClass().getName() + ")");
} else {
return (Boolean)result;
}*/
if (result == null) {
throw new ActivitiException("condition expression returns null");
} else {
return result;
}
}
/**
* 获得当前任务.
*/
public TaskEntity findTask(CommandContext commandContext) {
TaskEntity taskEntity = commandContext.getTaskEntityManager()
.findTaskById(taskId);
return taskEntity;
}
}
包容或排他人工干预判断代码 在flowMethed类中 类代码如下
你们关注的应该只有人工干预那块
package com.zz.flow.utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.zz.common.scan.client.AtExpressClient;
import com.zz.common.scan.client.BaseClient;
import com.zz.utils.VO.AtExpressParamVO;
import com.zz.utils.dto.UserInfo;
import com.zz.utils.exception.ZzpaasException;
import com.zz.utils.response.ResultCode;
import com.zz.utils.response.ResultInfo;
import com.zz.common.scan.utils.UserUtil;
import com.zz.flow.constants.ProcessConstants;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.task.Task;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
/**
* @author lqx
* @date 2020/9/18 11:21
*/
@Component
public class FlowMethod {
@Resource
protected RuntimeService runtimeService;
@Autowired
protected UserUtil userUtil;
@Autowired
protected BaseClient baseClient;
@Resource
protected TaskService taskService;
@Autowired
protected AtExpressClient atExpressClient;
//获取当前人的账号
public String getCurrentUserId(){
return userUtil.getCurrentUser().getUserId();
}
//获取当前人的姓名
public String getCurrentUserName(){
return userUtil.getCurrentUser().getUserName();
}
//获取流程启动者的账号
public String getProcessInstCreater(DelegateExecution execution){
String processInstanceId = execution.getProcessInstanceId();
Object variable = runtimeService.getVariable(processInstanceId, ProcessConstants.TARGET_ASSIGNEE_TYPE_LCQDZ_VARIABLES_KEY);
return variable.toString();
}
//获取流程启动者的姓名
public String getProcessInstCreaterName(DelegateExecution execution){
String processInstanceId = execution.getProcessInstanceId();
UserInfo userInfo = runtimeService.getVariable(processInstanceId, ProcessConstants.PROCESS_CREATER, UserInfo.class);
return userInfo.getUserName();
}
//获取流程启动者的单位
public String getProcessInstCreaterCompany(DelegateExecution execution){
String processInstanceId = execution.getProcessInstanceId();
UserInfo userInfo = runtimeService.getVariable(processInstanceId, ProcessConstants.PROCESS_CREATER, UserInfo.class);
if(StringUtils.isNotBlank(userInfo.getDepartmentId())){
return getParentInfosByDepId(userInfo.getDepartmentId(), "company", "name");
}
return "";
}
//获取流程启动者的部门
public String getProcessInstCreaterDepartment(DelegateExecution execution){
String processInstanceId = execution.getProcessInstanceId();
UserInfo userInfo = runtimeService.getVariable(processInstanceId, ProcessConstants.PROCESS_CREATER, UserInfo.class);
if(StringUtils.isNotBlank(userInfo.getDepartmentId())){
return getParentInfosByDepId(userInfo.getDepartmentId(), "department", "name");
}
return "";
}
//获取流程启动者的角色名称
public String getProcessInstCreaterRoleName(DelegateExecution execution){
String processInstanceId = execution.getProcessInstanceId();
Object variable = runtimeService.getVariable(processInstanceId, ProcessConstants.TARGET_ASSIGNEE_TYPE_LCQDZ_VARIABLES_KEY);
return getRoleInfoByUserId(variable.toString(),"roleName");
}
//获取当前任务办理人的账号
public String getTaskInstAssignee(DelegateExecution execution){
String id = execution.getId();
Task task = taskService.createTaskQuery().executionId(id).singleResult();
return task.getAssignee();
}
//获取当前任务办理人的姓名
public String getTaskInstAssigneeName(DelegateExecution execution){
String taskInstAssignee = getTaskInstAssignee(execution);
if(StringUtils.isNotBlank(taskInstAssignee)){
ResultInfo userByUserName = baseClient.getUserByUserName(taskInstAssignee);
if(userByUserName.getCode()== ResultCode.SUCCESS.getNumber()&&userByUserName.getData()!=null){
JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(userByUserName.getData()));
if(jsonObject.get("userName")!=null){
return jsonObject.getString("userName");
}
}
}
return "";
}
//获取当前任务办理人的单位
public String getTaskInstAssigneeCompany(DelegateExecution execution){
String taskInstAssignee = getTaskInstAssignee(execution);
if(StringUtils.isNotBlank(taskInstAssignee)){
ResultInfo userByUserName = baseClient.getUserByUserName(taskInstAssignee);
if(userByUserName.getCode()==ResultCode.SUCCESS.getNumber()&&userByUserName.getData()!=null){
JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(userByUserName.getData()));
if(jsonObject.get("departmentId")!=null){
return getParentInfosByDepId(jsonObject.getString("departmentId"), "company", "name");
}
}
}
return "";
}
//获取当前任务办理人的部门
public String getTaskInstAssigneeDepartment(DelegateExecution execution){
String taskInstAssignee = getTaskInstAssignee(execution);
if(StringUtils.isNotBlank(taskInstAssignee)){
ResultInfo userByUserName = baseClient.getUserByUserName(taskInstAssignee);
if(userByUserName.getCode()==ResultCode.SUCCESS.getNumber()&&userByUserName.getData()!=null){
JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(userByUserName.getData()));
if(jsonObject.get("departmentId")!=null){
return getParentInfosByDepId(jsonObject.getString("departmentId"), "department", "name");
}
}
}
return "";
}
//获取流程启动者的角色名称
public String getTaskInstAssigneeRoleName(DelegateExecution execution){
String id = execution.getId();
Task task = taskService.createTaskQuery().executionId(id).singleResult();
if(StringUtils.isNotBlank(task.getAssignee())){
return getRoleInfoByUserId(task.getAssignee(),"roleName");
}
return "";
}
public String getParentInfosByDepId(String depId,String departmentOrcompany,String field){
ResultInfo depPathResult = baseClient.getDepPath(depId);
if(depPathResult.getCode()==ResultCode.SUCCESS.getNumber()&&depPathResult.getData()!=null){
JSONArray depPaths = JSONArray.parseArray(JSON.toJSONString(depPathResult.getData()));
if(depPaths.size()>0){
List<String> infos=new ArrayList<>();
for (int i = 0; i < depPaths.size(); i++) {
JSONObject depPath = depPaths.getJSONObject(i);
if(departmentOrcompany.equals(depPath.getString("treetype"))){
infos.add(depPath.getString(field));
}
}
if(infos.size()>0){
return StringUtils.join(infos,",");
}
}
}
return "";
}
public String getRoleInfoByUserId(String userId,String field){
ResultInfo roleByUserId = baseClient.getRoleByUserId(userId);
if(roleByUserId.getCode()==ResultCode.SUCCESS.getNumber()&&roleByUserId.getData()!=null){
JSONArray objects = JSONArray.parseArray(JSON.toJSONString(roleByUserId.getData()));
List<String> results=new ArrayList<>();
for (int i = 0; i < objects.size(); i++) {
JSONObject jsonObject = objects.getJSONObject(i);
if(jsonObject.get(field)!=null){
results.add( jsonObject.getString(field));
}
}
if(results.size()>0){
return StringUtils.join(results,",");
}
}
return "";
}
/**
* 是否完成多人任务 用于activiti流程上 完成条件的判断
* @return
*/
public boolean isCompleteMultiTask(DelegateExecution execution){
return true;
}
/**
* 多人任务是否可以下一步 用于获取下个节点时是否可以进行下一步判断
* 因为获取下一步节点时当前任务还未办理 所以和isCompleteMultiTask不同点
* 就是当前任务 看做是完成后 是否可以下一步
* @return
*/
public boolean isNextMultiTask(Task nowTask){
//获取实例总数变量 和 完成实例数变量
Object zongTaskCountObj = runtimeService.getVariable(nowTask.getExecutionId(), "nrOfInstances");
Object completeTaskCountObj = runtimeService.getVariable(nowTask.getExecutionId(), "nrOfCompletedInstances");
if (zongTaskCountObj != null && completeTaskCountObj != null) {
int zongTaskCount = Integer.parseInt(zongTaskCountObj.toString());
int completeTaskCount = Integer.parseInt(completeTaskCountObj.toString());
if ((zongTaskCount - completeTaskCount) != 1) {//多人任务时 还有其他人尚未办理
return false;
}else{
return true;
}
} else {
throw new ZzpaasException("多人任务变量存储异常。");
}
}
//包容网关人工干预判断
public boolean rggyPd(DelegateExecution execution,String xianId){
Object variable = runtimeService.getVariable(execution.getId(), ProcessConstants.RGGY_KEY + execution.getCurrentActivityId());
if(variable==null){
return true;
}else{
String vStr = variable.toString();
if(StringUtils.isNotBlank(vStr)){
vStr=","+vStr+",";
return vStr.contains(","+xianId+",");
}
}
return true;
}
public boolean execAt(DelegateExecution execution,String atStr){
String processInstanceId = execution.getProcessInstanceId();
String id = execution.getId();//执行id
String taskId="";
Task task = taskService.createTaskQuery().executionId(id).singleResult();
if(task!=null){
taskId=task.getId();
}
ResultInfo resultInfo = atExpressClient.exeuteAtExpressForFegin(new AtExpressParamVO(processInstanceId, taskId, atStr));
if(resultInfo.getCode()==ResultCode.SUCCESS.getNumber()&&resultInfo.getData()!=null){
return Boolean.valueOf(resultInfo.getData().toString());
}
return true;
}
public int doSomething(DelegateExecution execution){
System.out.println("..");
return 1;
}
public int add(int a,int b){
return a+b;
}
}
完成任务代码 如下
@Transactional
@Override
public void completeTask(CompleteTaskVo2 completeTaskVo2) {
String taskId=completeTaskVo2.getNowTaskId();
Task nowTask = taskService.createTaskQuery().taskId(taskId).active().singleResult();
if(nowTask==null){
throw new ZzpaasException("没有找到该活动任务,无法办理!");
}
if(StringUtils.isBlank(nowTask.getAssignee())){
throw new ZzpaasException("当前任务没有指定办理人,无法办理!");
}
String processInstanceId=nowTask.getProcessInstanceId();
List<NextNodeParamVo> nextNodes=completeTaskVo2.getNextNodes();
//添加批注
if(StringUtils.isBlank(completeTaskVo2.getReason())){
completeTaskVo2.setReason("批转");
}
Map<String,Object> variable=new HashMap<>();
for (NextNodeParamVo nextNode : nextNodes) {
if(nextNode.isRggy()){
//人工干预时有用
if(variable.get(ProcessConstants.RGGY_KEY+nextNode.getSourceActId())==null){
//人工干预时有用
variable.put(ProcessConstants.RGGY_KEY+nextNode.getSourceActId(),nextNode.getSourceSeq());
}else{
String s = variable.get(ProcessConstants.RGGY_KEY + nextNode.getSourceActId()).toString();
variable.put(ProcessConstants.RGGY_KEY+nextNode.getSourceActId(),s+","+nextNode.getSourceSeq());
}
}
String type = nextNode.getType();
if("userTask".equals(type)){
//如果是个人任务 则判断办理人分配规则
String targetType = nextNode.getTargetType();
if(ProcessConstants.TARGET_TYPE_RYZD.equals(targetType)){//指定人员
variable.put(ProcessConstants.TARGET_ASSIGNEE_TYPE_RYZD_VARIABLES_KEY+nextNode.getActId(),nextNode.getTargets());
}else if(ProcessConstants.TARGET_TYPE_LCQDZ.equals(targetType)){//流程启动者
//由于流程启动者再流程启动时已设置 不需要再次设置 为了适配以后流程启动也改成任意指定的方式 所以在此也加入流程变量中
variable.put(ProcessConstants.TARGET_ASSIGNEE_TYPE_RYZD_VARIABLES_KEY+nextNode.getActId(),nextNode.getTargets());
}else if(ProcessConstants.TARGET_TYPE_DUOREN_CHUANXING.equals(targetType)||
ProcessConstants.TARGET_TYPE_DUOREN_BINGXING.equals(targetType)){//下个节点是多人任务 串行或者并行
String targets = nextNode.getTargets();
String[] targetArr = targets.split(",");
//存入人员
variable.put(ProcessConstants.TARGET_ASSIGNEE_TYPE_DUOREN_LIST_KEY+nextNode.getActId(), Arrays.asList(targetArr));
}else if(ProcessConstants.TARGET_TYPE_HXR.equals(targetType)){//候选人模式 (抢办模式)
variable.put(ProcessConstants.TARGET_ASSIGNEE_TYPE_RYZD_VARIABLES_KEY+nextNode.getActId(),Arrays.asList(nextNode.getTargets().split(",")));
}else{//固定人员 或者下个节点是结束节点
//固定某人员 返回的targetType为TARGET_TYPE_RYZD 只是targets只有固定的这几个人员 所以固定人员走任意指定 不走此处
//所以此处只有结束节点走次分支
}
}
}
//runtimeService.setVariables();
zzTaskService.addComment(taskId,processInstanceId,ProcessConstants.TASK_COMPLETE_FLAG, completeTaskVo2.getReason());
//批转之前插入批转记录
ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
.getDeployedProcessDefinition(nowTask.getProcessDefinitionId());
//判断当前任务节点出线终点是否是包容网关或者排他网关
ActivityImpl nowActivity = processDefinitionEntity.findActivity(nowTask.getTaskDefinitionKey());
insetTaskPiZhuanRecords(nowTask,nowActivity,nextNodes);
//完成任务
taskService.complete(taskId,variable);
//完成任务后 查询出省城的任务实例 填写扩展表中的过期时间和预警时间
List<Task> list =new ArrayList<>();
//List<String> targetActIds =new ArrayList<>();
TaskQuery taskQuery = taskService.createTaskQuery();
for (NextNodeParamVo nextNode : nextNodes) {
if("userTask".equals(nextNode.getType())){
String activityId = nextNode.getActId();
List<Task> nowList = taskQuery.processInstanceId(nowTask.getProcessInstanceId())
.taskDefinitionKey(activityId).list();
if(nowList.size()>0){
list.addAll(nowList);
//targetActIds.add(activityId);
}
}
}
//setTimeInfoInExt(nowTask.getProcessInstanceId(),0L,list);
zzTaskService.setTimeInfoAndOtherInExt(nowTask.getProcessInstanceId(),0L,taskId,ProcessConstants.TASK_CREATE_BY_COMPLETED,list);
}
public void insetTaskPiZhuanRecords(Task nowTask,ActivityImpl nowActivity,List<NextNodeParamVo> nextNodes){
String taskid=nowTask.getId();
String actid=nowTask.getTaskDefinitionKey();
String executionid=nowTask.getExecutionId();
String parentexecutionid="";
String parentparentexecutionid="";
String multiinstancetype="";
String fromuser=nowTask.getAssignee();
String processInstId=nowTask.getProcessInstanceId();
Execution execution = runtimeService.createExecutionQuery().executionId(executionid).singleResult();
if(StringUtils.isNotBlank(execution.getParentId())){
parentexecutionid=execution.getParentId();
}
//判断是多人还是单人任务
Object multiInstance = nowActivity.getProperty("multiInstance");
if(multiInstance!=null){
multiinstancetype = multiInstance.toString();
if("parallel".equalsIgnoreCase(multiinstancetype)){
//分配方案为多人任务-并行
Execution parentExecution = runtimeService.createExecutionQuery().executionId(parentexecutionid).singleResult();
parentparentexecutionid=parentExecution.getParentId();
}else if("sequential".equalsIgnoreCase(multiinstancetype)){
//分配方案为多人任务-串行
}
}
List<ActZzTaskpzrecords> taskpzrecordsList=new ArrayList<>();
for (NextNodeParamVo nextNode : nextNodes) {
if("userTask".equals(nextNode.getType())){
ActZzTaskpzrecords taskpzrecords=new ActZzTaskpzrecords();
taskpzrecords.setActid(actid)
.setExecutionid(executionid)
.setTaskid(taskid).setFromuser(fromuser)
.setMultiinstancetype(multiinstancetype)
.setParentexecutionid(parentexecutionid)
.setParentparentexecutionid(parentparentexecutionid)
.setToactid(nextNode.getActId())
.setTousers(nextNode.getTargets()).setProcessinstid(processInstId);
taskpzrecordsList.add(taskpzrecords);
}
}
if(taskpzrecordsList.size()>0){
taskpzrecordsService.saveBatch(taskpzrecordsList);
}
}
完成任务对应的实体类
package com.zz.flow.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.ArrayList;
import java.util.List;
/**
* @author lqx
* @date 2020/11/24 10:59
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CompleteTaskVo2 {
protected String nowTaskId;//当前任务id
protected String reason;//批转原因
protected List<NextNodeParamVo> nextNodes=new ArrayList<>();
}
package com.zz.flow.vo;
import lombok.Data;
/**
* @author lqx
* @date 2022/2/25 13:48
*/
@Data
public class NextNodeParamVo {
String actId;//批转时必填
String type;//批转时必填
boolean isRggy;//批转时必填
String sourceSeq;//批转时必填
String sourceActId;//批转时必填
String targets;//批转时有用 批转时选择的办理人 多个以逗号分隔
String targetType;//批转时有用
}