Flowable根据任务id、参数,预测、获取下一任务节点集合、候选用户集合、候选组集合、参与用户id集合等

根据任务id、参数,预测、获取下一任务节点集合、候选用户集合、候选组集合、参与用户id集合等。

List nextUserTasks = newProcessService.getNextUserTasks(taskId, variableMap);

  1. Service

1.1 NewProcessService
package com.example.wf.service;

import com.example.wf.vo.UserTaskVo;

import java.util.List;
import java.util.Map;

public interface NewProcessService {

    /**
     * 获取el表达式的值
     * @param exp el表达式
     * @param variableMap map参数
     * @return true/false
     */
    boolean getElValue(String exp, Map variableMap);

    /**
     * 获取el表达式的值
     * @param processInstanceId 流程实例id
     * @param exp el表达式
     * @param variableMap map参数
     * @return true/false
     */
    boolean getElValue(String processInstanceId, String exp, Map variableMap);

    /**
     * 获取el表达式的值
     * @param taskId 流程任务id
     * @param exp el表达式
     * @param variableMap map参数
     * @return true/false
     */
    boolean getElValueByTaskId(String taskId, String exp, Map variableMap);

    /**
     * 获取skip是否跳过节点el表达式的值
     * @param exp el表达式
     * @param variableMap map参数
     * @return true 跳过节点/false 不跳过节点
     */
    boolean getSkipElValue(String exp, Map variableMap);

    /**
     * 根据参数,预测、获取下一任务节点集合
     *
     * @param taskId 任务id
     * @param variables 参数
     * @return 下一任务节点集合
     */
    List getNextUserTasks(String taskId, Map variables);

    /**
     * 根据参数,预测、获取下一任务节点集合
     *
     * @param taskId 任务id
     * @param code 业务ID
     * @param variables 参数
     * @return 下一任务节点集合
     */
    List getNextUserTasks(String taskId, String code, Map variables);

}

  1. ServiceImpl

2.1 NewProcessServiceImpl
package com.example.wf.service.impl;

import com.example.utils.CastUtils;
import com.example.utils.VariableUtils;
import com.example.wf.command.ExpressionCmd;
import com.example.wf.mapper.ActRuVariableMapper;
import com.example.wf.mapper.VUserGroupMapper;
import com.example.wf.model.VUserGroup;
import com.example.wf.service.NewProcessService;
import com.example.wf.vo.CandidateGroupVo;
import com.example.wf.vo.CandidateUserVo;
import com.example.wf.vo.UserTaskVo;
import org.apache.commons.lang.StringUtils;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.EventGateway;
import org.flowable.bpmn.model.ExclusiveGateway;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.FlowNode;
import org.flowable.bpmn.model.InclusiveGateway;
import org.flowable.bpmn.model.ParallelGateway;
import org.flowable.bpmn.model.SequenceFlow;
import org.flowable.bpmn.model.UserTask;
import org.flowable.engine.HistoryService;
import org.flowable.engine.IdentityService;
import org.flowable.engine.ManagementService;
import org.flowable.engine.ProcessEngine;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.idm.api.Group;
import org.flowable.idm.api.User;
import org.flowable.task.api.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.util.Sqls;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class NewProcessServiceImpl implements NewProcessService {

    protected Logger log = LoggerFactory.getLogger(super.getClass());

    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private HistoryService historyService;
    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private ProcessEngine processEngine;
    @Autowired
    private TaskService taskService;
    @Autowired
    private IdentityService identityService;

    @Autowired
    private VUserGroupMapper vUserGroupMapper;

    @Autowired
    private ActRuVariableMapper actRuVariableMapper;

    @Override
    public boolean getElValue(String exp, Map variableMap) {
        return this.getElValue(null, exp, variableMap);
    }

    @Override
    public boolean getElValue(String processInstanceId, String exp, Map variableMap) {
        if (StringUtils.isBlank(exp)) {
            return true;
        }

        ManagementService managementService = processEngine.getManagementService();
        boolean flag = managementService.executeCommand(new ExpressionCmd(processEngine, processInstanceId, exp, variableMap));

        //删除垃圾数据
        this.deleteException();
        return flag;
    }

    @Override
    public boolean getElValueByTaskId(String taskId, String exp, Map variableMap) {
        if (StringUtils.isBlank(exp)) {
            return true;
        }

        Map variables = taskService.getVariables(taskId);
        variables.putAll(variableMap);

        ManagementService managementService = processEngine.getManagementService();
        boolean flag = managementService.executeCommand(new ExpressionCmd(exp, variables));

        //删除垃圾数据
        this.deleteException();
        return flag;
    }

    @Override
    public boolean getSkipElValue(String exp, Map variableMap) {
        //表达式为空,节点不跳过
        if (StringUtils.isBlank(exp)) {
            return false;
        }

        //skip:true 跳过节点/false 不跳过节点
        boolean skip = false;
        Map variables = new HashMap<>(variableMap);
        Object flowableSkipExpressionEnabled = variables.get("_FLOWABLE_SKIP_EXPRESSION_ENABLED");
        //流程参数含有_FLOWABLE_SKIP_EXPRESSION_ENABLED,且为true时,表示FLOWABLE跳过表达式已启用
        if (null != flowableSkipExpressionEnabled && "true".equals(flowableSkipExpressionEnabled.toString())) {
            //返回true,表示跳过该任务节点;
            ManagementService managementService = processEngine.getManagementService();
            skip = managementService.executeCommand(new ExpressionCmd(exp, variables));

            //删除垃圾数据
            this.deleteException();
        }

        return skip;
    }

    public void deleteException(){
        //删除垃圾数据
        actRuVariableMapper.deleteRuVariableException();
        actRuVariableMapper.deleteHiVariableException();
    }

    /**
     * 获取下一任务节点集合
     *
     * @param taskId 任务id
     * @param variables 参数
     * @return 下一任务节点集合
     */
    @Override
    public List getNextUserTasks(String taskId, Map variables) {
        return this.getNextUserTasks(taskId, null, variables);
    }

    @Override
    public List getNextUserTasks(String taskId, String code, Map variables) {
        if (StringUtils.isBlank(taskId)) {
            return new ArrayList<>();
        }

        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        if (null == task) {
            return new ArrayList<>();
        }

        Map variableMap = taskService.getVariables(task.getId());
        variableMap.putAll(variables);

        String procId = "";
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .processDefinitionId(task.getProcessDefinitionId()).singleResult();
        if (null != processDefinition) {
            procId = processDefinition.getKey();
        }

        List userTasks = new ArrayList<>();

        List nextFlowNodes = this.getNextFlowNodes(task, variableMap);
        for (FlowElement nextFlowNode : nextFlowNodes) {
            List candidateUserIdList = new ArrayList<>(); //参与用户id
            List candidateUsers = new ArrayList<>(); //候选用户
            List candidateGroups = new ArrayList<>(); //候选组

            UserTask flowElement = (UserTask) nextFlowNode;
            String flowId = flowElement.getId();
            String flowName = flowElement.getName();
            String assignee = flowElement.getAssignee();

            if (StringUtils.isNotBlank(assignee)) {
                // 节点分配给了具体参与者
                String key = VariableUtils.formatVariableName(assignee);
                Object userIdStr = variableMap.get(key);
                if (null != userIdStr && StringUtils.isNotBlank(userIdStr.toString())) {
                    // 节点分配给了具体参与者
                    String userId = userIdStr.toString();
                    String userName = "";
                    User user = identityService.createUserQuery().userId(userId).singleResult();
                    if (null != user) {
                        userName = user.getDisplayName();
                    }
                    candidateUserIdList.add(userId);
                    candidateUsers.add(new CandidateUserVo(userId, userName));
                }

            } else {

                // 候选用户
                for (String candidateUser : flowElement.getCandidateUsers()) {
                    String key = VariableUtils.formatVariableName(candidateUser);
                    Object userIdStr = variableMap.get(key);
                    if (null != userIdStr && StringUtils.isNotBlank(userIdStr.toString())) {
                        //value可能是集合
                        List userIds = CastUtils.castObjToStringList(userIdStr);
                        for (String userId : userIds) {
                            String userName = "";
                            User user = identityService.createUserQuery().userId(userId).singleResult();
                            if (null != user) {
                                userName = user.getDisplayName();
                            }
                            candidateUserIdList.add(userId);
                            candidateUsers.add(new CandidateUserVo(userId, userName));
                        }
                    }
                }

                //候选组
                for (String candidateGroup : flowElement.getCandidateGroups()) {
                    String key = VariableUtils.formatVariableName(candidateGroup);
                    Object groupIdStr = variableMap.get(key);
                    if (null != groupIdStr && StringUtils.isNotBlank(groupIdStr.toString())) {
                        //value可能是集合
                        List groupIds = CastUtils.castObjToStringList(groupIdStr);
                        for (String groupId : groupIds) {
                            String groupName = "";
                            Group group = this.identityService.createGroupQuery().groupId(groupId).singleResult();
                            if (null != group) {
                                groupName = group.getName();
                            }

                            candidateGroups.add(new CandidateGroupVo(groupId, groupName));

                            // 查询候选组用户id
                            Example.Builder builderGroup = new Example.Builder(VUserGroup.class);
                            // 条件
                            Sqls sqlGroup = Sqls.custom();
                            sqlGroup.andEqualTo("groupId", groupId);
                            builderGroup.where(sqlGroup);
                            List vUserGroupList = vUserGroupMapper.selectByExample(builderGroup.build());
                            if (!CollectionUtils.isEmpty(vUserGroupList)) {
                                for (VUserGroup vUserGroup : vUserGroupList) {
                                    candidateUserIdList.add(vUserGroup.getId());
                                }
                            }
                        }
                    }
                }
            }

            UserTaskVo userTask = new UserTaskVo(null, flowId, flowName, procId, code,
                    candidateUserIdList, candidateUsers, candidateGroups);
            userTasks.add(userTask);
        }

        return userTasks;
    }

    /**
     * 获取下一任务节点集合
     *
     * @param taskId 任务id
     * @param variables 参数
     * @return 下一任务节点集合
     */
    public List getNextFlowNodes(String taskId, Map variables) {
        if (StringUtils.isBlank(taskId)) {
            return new ArrayList<>();
        }

        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        if (null == task) {
            return new ArrayList<>();
        }

        Map variableMap = taskService.getVariables(task.getId());
        variableMap.putAll(variables);

        return this.getNextFlowNodes(task, variableMap);
    }

    /**
     * 获取下一任务节点集合
     *
     * @param task 当前任务
     * @param variables 参数
     * @return 下一任务节点集合
     */
    public List getNextFlowNodes(Task task, Map variables) {
        if (null == task) {
            return new ArrayList<>();
        }

        // 当前审批节点
        String currentActivityId = task.getTaskDefinitionKey(); //当前环节id
        BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());

        //复制一份
        List flowElements = new ArrayList<>(bpmnModel.getMainProcess().getFlowElements());
        List nextElements = new ArrayList<>();

        FlowNode flowNode = (FlowNode) bpmnModel.getFlowElement(currentActivityId);
        // 输出连线
        List outFlows = flowNode.getOutgoingFlows();

        FlowElement targetElement;
        List sequenceFlows = this.getSequenceFlows(variables, outFlows);
        for (SequenceFlow sequenceFlow : sequenceFlows) {
            targetElement = this.getFlowElement(flowElements, sequenceFlow.getTargetRef());
            this.getNextElementList(nextElements, flowElements, targetElement, variables);
        }
        return nextElements;
    }

    /**
     * 获取下一环节任务节点集合
     */
    private void getNextElementList(List nextElements, Collection flowElements, FlowElement curFlowElement, Map variableMap) {
        if (null == curFlowElement) {
            return;
        }

        // 任务节点
        if (curFlowElement instanceof UserTask) {
            this.dueUserTaskElement(nextElements, flowElements, curFlowElement, variableMap);
            return;
        }
        // 排他网关
        if (curFlowElement instanceof ExclusiveGateway) {
            this.dueExclusiveGateway(nextElements, flowElements, curFlowElement, variableMap);
            return;
        }
        // 并行网关
        if (curFlowElement instanceof ParallelGateway) {
            this.dueParallelGateway(nextElements, flowElements, curFlowElement, variableMap);
        }
        // 包含网关
        if (curFlowElement instanceof InclusiveGateway) {
            this.dueInclusiveGateway(nextElements, flowElements, curFlowElement, variableMap);
        }
        // 事件网关
        if (curFlowElement instanceof EventGateway) {
            this.dueEventGateway(nextElements, flowElements, curFlowElement, variableMap);
        }
    }

    /**
     * 任务节点
     */
    private void dueUserTaskElement(List nextElements, Collection flowElements, FlowElement curFlowElement, Map variableMap) {
        UserTask userTask = (UserTask) curFlowElement;
        //skip:true 跳过节点/false 不跳过节点
        boolean skip = this.getSkipElValue(userTask.getSkipExpression(), variableMap);
        if (!skip) {
            //不跳过节点,
            nextElements.add(curFlowElement);
        } else {

            //跳过节点,查询下一节点
            List outgoingFlows = userTask.getOutgoingFlows();
            if (outgoingFlows.size() > 0) {
                String targetRef = outgoingFlows.get(0).getTargetRef();
                if (outgoingFlows.size() > 1) {
                    // 找到表达式成立的sequenceFlow
                    SequenceFlow sequenceFlow = getSequenceFlow(variableMap, outgoingFlows);
                    targetRef = sequenceFlow.getTargetRef();
                }
                // 根据ID找到FlowElement
                FlowElement targetElement = this.getFlowElement(flowElements, targetRef);
                this.getNextElementList(nextElements, flowElements, targetElement, variableMap);
            }
        }
    }

    /**
     * 排他网关
     */
    private void dueExclusiveGateway(List nextElements, Collection flowElements, FlowElement curFlowElement, Map variableMap) {
        // 获取符合条件的sequenceFlow的目标FlowElement
        List exclusiveGatewayOutgoingFlows = ((ExclusiveGateway) curFlowElement).getOutgoingFlows();
        flowElements.remove(curFlowElement);
        // 找到表达式成立的sequenceFlow
        SequenceFlow sequenceFlow = this.getSequenceFlow(variableMap, exclusiveGatewayOutgoingFlows);
        // 根据ID找到FlowElement
        FlowElement targetElement = this.getFlowElement(flowElements, sequenceFlow.getTargetRef());
        this.getNextElementList(nextElements, flowElements, targetElement, variableMap);
    }

    /**
     * 并行网关
     */
    private void dueParallelGateway(List nextElements, Collection flowElements, FlowElement curFlowElement, Map variableMap) {
        FlowElement targetElement;
        List parallelGatewayOutgoingFlows = ((ParallelGateway) curFlowElement).getOutgoingFlows();
        for (SequenceFlow sequenceFlow : parallelGatewayOutgoingFlows) {
            targetElement = this.getFlowElement(flowElements, sequenceFlow.getTargetRef());
            this.getNextElementList(nextElements, flowElements, targetElement, variableMap);
        }
    }

    /**
     * 包含网关
     */
    private void dueInclusiveGateway(List nextElements, Collection flowElements, FlowElement curFlowElement, Map variableMap) {
        FlowElement targetElement;
        List inclusiveGatewayOutgoingFlows = ((InclusiveGateway) curFlowElement).getOutgoingFlows();
        List sequenceFlows = this.getSequenceFlows(variableMap, inclusiveGatewayOutgoingFlows);
        for (SequenceFlow sequenceFlow : sequenceFlows) {
            targetElement = this.getFlowElement(flowElements, sequenceFlow.getTargetRef());
            this.getNextElementList(nextElements, flowElements, targetElement, variableMap);
        }
    }

    /**
     * 事件网关
     */
    private void dueEventGateway(List nextElements, Collection flowElements, FlowElement curFlowElement, Map variableMap) {
    }

    /**
     * 根据ID找到FlowElement
     * @param flowElements 流程节点集合
     * @param targetRef id
     * @return FlowElement
     */
    private FlowElement getFlowElement(Collection flowElements, String targetRef) {
        return flowElements.stream().filter(flowElement -> targetRef.equals(flowElement.getId())).findFirst().orElse(null);
    }

    /**
     * 根据传入的变量,计算出表达式成立的那一条SequenceFlow
     *
     * @param variableMap   变量map
     * @param outgoingFlows 输出流
     * @return SequenceFlow连线
     */
    private SequenceFlow getSequenceFlow(Map variableMap, List outgoingFlows) {
        List sequenceFlows = this.getSequenceFlows(variableMap, outgoingFlows);
        if (null != sequenceFlows && sequenceFlows.size() > 0) {
            return sequenceFlows.get(0);
        }

        return outgoingFlows.get(0);
    }

    /**
     * 根据传入的变量,计算出表达式成立的SequenceFlow连线集合
     *
     * @param variableMap   变量map
     * @param outgoingFlows 输出流
     * @return SequenceFlow连线集合
     */
    private List getSequenceFlows(Map variableMap, List outgoingFlows) {
        List sequenceFlows;
        sequenceFlows = outgoingFlows.stream().filter(item -> {
            try {
                return this.getElValue(item.getConditionExpression(), variableMap);
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }).collect(Collectors.toList());
        return sequenceFlows;
    }

}

  1. command

  1. ExpressionCmd
package com.example.wf.command;

import org.apache.commons.lang.StringUtils;
import org.flowable.common.engine.api.delegate.Expression;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.ProcessEngine;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl;
import org.flowable.variable.service.impl.util.CommandContextUtil;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

/**
 * 表达式
 */
public class ExpressionCmd implements Command, Serializable {

    protected ProcessEngine processEngine;

    protected String processInstanceId;

    protected String exp;

    protected Map variableMap;

    public ExpressionCmd(String exp, Map variableMap) {
        this.exp = exp;
        this.variableMap = variableMap;
    }

    public ExpressionCmd(ProcessEngine processEngine, String processInstanceId, String exp, Map variableMap) {
        this.processEngine = processEngine;
        this.processInstanceId = processInstanceId;
        this.exp = exp;
        this.variableMap = variableMap;
    }

    @Override
    public Boolean execute(CommandContext commandContext) {
        //表达式为空时,直接返回true
        if (StringUtils.isBlank(this.exp)) {
            return Boolean.TRUE;
        }

        //复制一份
        Map variables = new HashMap<>(this.variableMap);
        Expression expression = CommandContextUtil.getExpressionManager().createExpression(this.exp);

        //流程实例id不为空
        if (StringUtils.isNotBlank(this.processInstanceId)) {
            RuntimeService runtimeService = this.processEngine.getRuntimeService();
            ExecutionEntity processExecutionEntity = (ExecutionEntity) runtimeService.createProcessInstanceQuery().processInstanceId(this.processInstanceId).includeProcessVariables().singleResult();
            if (null != processExecutionEntity) {
                //流程实例参数
                Map processVariables = processExecutionEntity.getVariables();
                if (null != processVariables) {
                    processVariables.putAll(this.variableMap);

                    variables = processVariables;
                }
            }
        }

        ExecutionEntity executionEntity = new ExecutionEntityImpl();
        executionEntity.setVariables(variables);

        Object value = expression.getValue(executionEntity);
        return value != null && "true".equals(value.toString());
    }

}

  1. mapper

  1. ActRuVariableMapper
package com.example.wf.mapper;

import com.example.common.base.MyMapper;
import com.example.wf.model.ActRuVariable;

public interface ActRuVariableMapper extends MyMapper {

    /**
     * 删除运行变量(异常)
     */
    int deleteRuVariableException();

    /**
     * 删除历史变量(异常)
     */
    int deleteHiVariableException();

}

  1. mapperXML

  1. ActRuVariableMapper.xml



    
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
    

    
        delete from ACT_RU_VARIABLE where EXECUTION_ID_ is null
    

    
        delete from act_hi_varinst where EXECUTION_ID_ is null
    

  1. model

  1. ActRuVariable
package com.example.wf.model;

import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.Table;
import java.io.Serializable;
import java.math.BigDecimal;

/**
 * 流程运行变量
 */
@Table(name = "act_ru_variable")
public class ActRuVariable implements Serializable {

    @Id
    @Column(name = "ID_")
    private String id;

    @Column(name = "REV_")
    private BigDecimal rev;

    @Column(name = "TYPE_")
    private String type;

    @Column(name = "NAME_")
    private String name;

    @Column(name = "EXECUTION_ID_")
    private String executionId;

    @Column(name = "PROC_INST_ID_")
    private String procInstId;

    @Column(name = "TASK_ID_")
    private String taskId;

    @Column(name = "SCOPE_ID_")
    private String scopeId;

    @Column(name = "SUB_SCOPE_ID_")
    private String subScopeId;

    @Column(name = "SCOPE_TYPE_")
    private String scopeType;

    @Column(name = "BYTEARRAY_ID_")
    private String bytearrayId;

    @Column(name = "DOUBLE_")
    private Double double_;

    @Column(name = "LONG_")
    private Long long_;

    @Column(name = "TEXT_")
    private String text_;

    @Column(name = "TEXT2_")
    private String text2_;

    /**
     * @return ID_
     */
    public String getId() {
        return id;
    }

    /**
     * @param id
     */
    public void setId(String id) {
        this.id = id;
    }

    /**
     * @return REV_
     */
    public BigDecimal getRev() {
        return rev;
    }

    /**
     * @param rev
     */
    public void setRev(BigDecimal rev) {
        this.rev = rev;
    }

    /**
     * @return TYPE_
     */
    public String getType() {
        return type;
    }

    /**
     * @param type
     */
    public void setType(String type) {
        this.type = type;
    }

    /**
     * @return NAME_
     */
    public String getName() {
        return name;
    }

    /**
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return EXECUTION_ID_
     */
    public String getExecutionId() {
        return executionId;
    }

    /**
     * @param executionId
     */
    public void setExecutionId(String executionId) {
        this.executionId = executionId;
    }

    /**
     * @return PROC_INST_ID_
     */
    public String getProcInstId() {
        return procInstId;
    }

    /**
     * @param procInstId
     */
    public void setProcInstId(String procInstId) {
        this.procInstId = procInstId;
    }

    /**
     * @return TASK_ID_
     */
    public String getTaskId() {
        return taskId;
    }

    /**
     * @param taskId
     */
    public void setTaskId(String taskId) {
        this.taskId = taskId;
    }

    /**
     * @return SCOPE_ID_
     */
    public String getScopeId() {
        return scopeId;
    }

    /**
     * @param scopeId
     */
    public void setScopeId(String scopeId) {
        this.scopeId = scopeId;
    }

    /**
     * @return SUB_SCOPE_ID_
     */
    public String getSubScopeId() {
        return subScopeId;
    }

    /**
     * @param subScopeId
     */
    public void setSubScopeId(String subScopeId) {
        this.subScopeId = subScopeId;
    }

    /**
     * @return SCOPE_TYPE_
     */
    public String getScopeType() {
        return scopeType;
    }

    /**
     * @param scopeType
     */
    public void setScopeType(String scopeType) {
        this.scopeType = scopeType;
    }

    /**
     * @return BYTEARRAY_ID_
     */
    public String getBytearrayId() {
        return bytearrayId;
    }

    /**
     * @param bytearrayId
     */
    public void setBytearrayId(String bytearrayId) {
        this.bytearrayId = bytearrayId;
    }

    /**
     * @return DOUBLE_
     */
    public Double getDouble_() {
        return double_;
    }

    /**
     * @param double_
     */
    public void setDouble_(Double double_) {
        this.double_ = double_;
    }

    /**
     * @return LONG_
     */
    public Long getLong_() {
        return long_;
    }

    /**
     * @param long_
     */
    public void setLong_(Long long_) {
        this.long_ = long_;
    }

    /**
     * @return TEXT_
     */
    public String getText_() {
        return text_;
    }

    /**
     * @param text_
     */
    public void setText_(String text_) {
        this.text_ = text_;
    }

    /**
     * @return TEXT2_
     */
    public String getText2_() {
        return text2_;
    }

    /**
     * @param text2_
     */
    public void setText2_(String text2_) {
        this.text2_ = text2_;
    }
}
  1. Tasklist
package com.example.wf.model;

import javax.persistence.Column;
import javax.persistence.Table;
import javax.persistence.Transient;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Set;

@Table(name = "v_tasklist")
public class Tasklist implements Serializable {
    private static final long serialVersionUID = 1L;
    @Column(name = "TASK_ID")
    private String taskId;
    @Column(name = "PROC_INST_ID")
    private String procInstId;
    @Column(name = "ACT_ID")
    private String actId;
    @Column(name = "ACT_NAME")
    private String actName;
    @Column(name = "ASSIGNEE")
    private String assignee;
    @Column(name = "DELEGATION_ID")
    private String delegationId;
    @Column(name = "DESCRIPTION")
    private String description;
    @Column(name = "CREATE_TIME")
    private Date createTime;
    @Column(name = "DUE_DATE")
    private Date dueDate;
    @Column(name = "CANDIDATE")
    private String candidate;
    @Column(name = "PROC_ID")
    private String procId;
    @Column(name = "CODE")
    private String code;
    @Column(name = "SUSPENSION_STATE")
    private Integer suspensionState;
    @Transient
    private Integer taskCount;
    @Transient
    private Set authProjects;
    @Transient
    private Set noAuthProjects;
    @Transient
    private List businessList;

    public Set getAuthProjects() {
        return this.authProjects;
    }

    public void setAuthProjects(Set authProjects) {
        this.authProjects = authProjects;
    }

    public Set getNoAuthProjects() {
        return this.noAuthProjects;
    }

    public void setNoAuthProjects(Set noAuthProjects) {
        this.noAuthProjects = noAuthProjects;
    }

    public Integer getTaskCount() {
        return this.taskCount;
    }

    public void setTaskCount(Integer taskCount) {
        this.taskCount = taskCount;
    }

    public String getCode() {
        return this.code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getTaskId() {
        return this.taskId;
    }

    public void setTaskId(String taskId) {
        this.taskId = taskId;
    }

    public String getProcInstId() {
        return this.procInstId;
    }

    public void setProcInstId(String procInstId) {
        this.procInstId = procInstId;
    }

    public String getActId() {
        return this.actId;
    }

    public void setActId(String actId) {
        this.actId = actId;
    }

    public String getActName() {
        return this.actName;
    }

    public void setActName(String actName) {
        this.actName = actName;
    }

    public String getAssignee() {
        return this.assignee;
    }

    public void setAssignee(String assignee) {
        this.assignee = assignee;
    }

    public String getDelegationId() {
        return this.delegationId;
    }

    public void setDelegationId(String delegationId) {
        this.delegationId = delegationId;
    }

    public String getDescription() {
        return this.description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Date getCreateTime() {
        return this.createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public Date getDueDate() {
        return this.dueDate;
    }

    public void setDueDate(Date dueDate) {
        this.dueDate = dueDate;
    }

    public String getCandidate() {
        return this.candidate;
    }

    public void setCandidate(String candidate) {
        this.candidate = candidate;
    }

    public String getProcId() {
        return this.procId;
    }

    public void setProcId(String procId) {
        this.procId = procId;
    }

    public Integer getSuspensionState() {
        return this.suspensionState;
    }

    public void setSuspensionState(Integer suspensionState) {
        this.suspensionState = suspensionState;
    }

    public List getBusinessList() {
        return this.businessList;
    }

    public void setBusinessList(List businessList) {
        this.businessList = businessList;
    }
} 
   

VUserGroup

package com.example.wf.model;

import javax.persistence.Column;
import javax.persistence.Table;
import java.io.Serializable;

@Table(name = "v_user_group")
public class VUserGroup implements Serializable {
    private static final long serialVersionUID = 1L;
    @Column(name = "id")
    private String id;
    @Column(name = "user_name")
    private String userName;
    @Column(name = "group_id")
    private String groupId;
    @Column(name = "group_name")
    private String groupName;
    private String type;

    public VUserGroup() {
    }

    public String getId() {
        return this.id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getUserName() {
        return this.userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getGroupId() {
        return this.groupId;
    }

    public void setGroupId(String groupId) {
        this.groupId = groupId;
    }

    public String getGroupName() {
        return this.groupName;
    }

    public void setGroupName(String groupName) {
        this.groupName = groupName;
    }

    public String getType() {
        return this.type;
    }

    public void setType(String type) {
        this.type = type;
    }
}

  1. vo

  1. CandidateGroupVo
package com.example.wf.vo;

import java.io.Serializable;

@SuppressWarnings("serial")
public class CandidateGroupVo implements Serializable {

    private String groupId; //候选组

    private String groupName; //候选组

    public CandidateGroupVo() {
        super();
    }

    public CandidateGroupVo(String groupId, String groupName) {
        super();
        this.groupId = groupId;
        this.groupName = groupName;
    }

    public String getGroupId() {
        return groupId;
    }

    public void setGroupId(String groupId) {
        this.groupId = groupId;
    }

    public String getGroupName() {
        return groupName;
    }

    public void setGroupName(String groupName) {
        this.groupName = groupName;
    }

}
  1. CandidateUserVo
package com.example.wf.vo;

import java.io.Serializable;

@SuppressWarnings("serial")
public class CandidateUserVo implements Serializable {

    private String userId; //候选用户

    private String userName; //候选用户

    public CandidateUserVo() {
        super();
    }

    public CandidateUserVo(String userId, String userName) {
        super();
        this.userId = userId;
        this.userName = userName;
    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

}
  1. UserTaskVo
package com.example.wf.vo;

import com.example.wf.model.Tasklist;
import org.springframework.beans.BeanUtils;

import javax.persistence.Transient;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;
import java.util.stream.Collectors;

@SuppressWarnings("serial")
public class UserTaskVo extends Tasklist {

    /**
     * 拼接任务数量(0)
     */
    @Transient
    private String actConcatName;

    @Transient
    private Long menuId;

    @Transient
    private List candidateUserIdList; //参与用户id

    @Transient
    private List candidateUsers; //候选用户

    @Transient
    private List candidateGroups; //候选组

    public UserTaskVo() {
        super();
    }

    public UserTaskVo(Tasklist tasklist) {
        super();
        BeanUtils.copyProperties(tasklist, this);
        this.actConcatName = this.getActName() + "(" + this.getTaskCount() + ")";
    }

    public UserTaskVo(String taskId, String actId, String actName, String procId, List candidateUsers, List candidateGroups) {
        this(taskId, actId, actName, procId, null, candidateUsers, candidateGroups);
    }

    public UserTaskVo(String taskId, String actId, String actName, String procId, String code, List candidateUsers, List candidateGroups) {
        this(taskId, actId, actName, procId, code, null, candidateUsers, candidateGroups);
    }

    public UserTaskVo(String taskId, String actId, String actName, String procId, String code, List candidateUserIdList, List candidateUsers, List candidateGroups) {
        super();
        this.setTaskId(taskId);
        this.setActId(actId);
        this.setActName(actName);
        this.setProcId(procId);
        this.setCode(code);

        //去重
        if (null != candidateUserIdList && candidateUserIdList.size() > 0) {
            candidateUserIdList = candidateUserIdList.stream().distinct().collect(Collectors.toList());
        }
        if (null != candidateUsers && candidateUsers.size() > 0) {
            candidateUsers = candidateUsers.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(CandidateUserVo::getUserId))), ArrayList::new));
        }
        if (null != candidateGroups && candidateGroups.size() > 0) {
            candidateGroups = candidateGroups.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(CandidateGroupVo::getGroupId))), ArrayList::new));
        }
        this.candidateUserIdList = candidateUserIdList;
        this.candidateUsers = candidateUsers;
        this.candidateGroups = candidateGroups;
    }

    public String getActConcatName() {
        return actConcatName;
    }

    public void setActConcatName(String actConcatName) {
        this.actConcatName = actConcatName;
    }

    public Long getMenuId() {
        return menuId;
    }

    public void setMenuId(Long menuId) {
        this.menuId = menuId;
    }

    public List getCandidateUserIdList() {
        return candidateUserIdList;
    }

    public void setCandidateUserIdList(List candidateUserIdList) {
        //去重
        if (null != candidateUserIdList && candidateUserIdList.size() > 0) {
            candidateUserIdList = candidateUserIdList.stream().distinct().collect(Collectors.toList());
        }
        this.candidateUserIdList = candidateUserIdList;
    }

    public List getCandidateUsers() {
        return candidateUsers;
    }

    public void setCandidateUsers(List candidateUsers) {
        //去重
        if (null != candidateUsers && candidateUsers.size() > 0) {
            candidateUsers = candidateUsers.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(CandidateUserVo::getUserId))), ArrayList::new));
        }
        this.candidateUsers = candidateUsers;
    }

    public List getCandidateGroups() {
        return candidateGroups;
    }

    public void setCandidateGroups(List candidateGroups) {
        //去重
        if (null != candidateGroups && candidateGroups.size() > 0) {
            candidateGroups = candidateGroups.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(CandidateGroupVo::getGroupId))), ArrayList::new));
        }
        this.candidateGroups = candidateGroups;
    }

}

  1. utils

  1. CastUtils
package com.example.utils;

import java.util.ArrayList;
import java.util.List;

/**
 * 转换工具类
 */
public class CastUtils {

    /**
     * 将obj转换为字符串列表
     * @param obj obj
     * @return 字符串列表
     */
    public static List castObjToStringList(Object obj) {
        if (null == obj) {
            return null;
        }

        List result = new ArrayList<>();
        if (obj instanceof List) {
            for (Object o : (List) obj) {
                result.add(o.toString());
            }
        } else if (obj instanceof String) {
            result.add(obj.toString());
        }

        return result;
    }

    /**
     * obj转list
     * @param obj obj
     * @param clazz clazz
     * @param  T
     * @return T
     */
    public static  List castList(Object obj, Class clazz) {
        if (null == obj) {
            return null;
        }

        if (obj instanceof List) {
            List result = new ArrayList<>();
            for (Object o : (List) obj) {
                result.add(clazz.cast(o));
            }
            return result;
        }

        return null;
    }

}
  1. VariableUtils
package com.example.utils;

import com.alibaba.fastjson.util.TypeUtils;
import org.apache.commons.lang.StringUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;

/**
 * 变量工具类
 */
public class VariableUtils {

    /**
     * 格式化变量名,去除${}符号
     * @param variableName 变量名
     * @return 变量名
     */
    public static String formatVariableName(String variableName) {
        variableName = variableName.replaceAll("[${}]", "").trim();
        return variableName;
    }

    /**
     * 获取格式化后的变量值
     * @param variableType 变量类型
     * @param variableValue 变量值
     * @return 格式化后的变量值
     */
    public static Object getFormatVariableValue(String variableType, String variableValue) {
        if (StringUtils.isBlank(variableType)) {
            throw new RuntimeException("变量类型为空!");
        }
        if (!"java.lang.String".equals(variableType) && StringUtils.isBlank(variableValue)) {
            throw new RuntimeException("变量值为空!");
        }

        Object value;
        try {
            switch (variableType) {
                case "java.lang.String": //字符串
                    value = variableValue;
                    break;
                case "java.lang.Integer": //整数
                    value = new Integer(variableValue);
                    break;
                case "java.math.BigDecimal": //金额
                    value = new BigDecimal(variableValue);
                    break;
                case "java.util.ArrayList": //列表
                    String[] split = variableValue.split(",");
                    value = new ArrayList<>(Arrays.asList(split));
                    break;
                default:
                    // 不是以上的类型!但愿可以通过反射注入吧!
                    Class aClass = Class.forName(variableType);
//                    Constructor constructor = aClass.getConstructor(String.class);
//                    value = constructor.newInstance(variableValue);

                    value = TypeUtils.castToJavaBean(variableValue, aClass);
                    break;
            }
        } catch (Exception e) {
            e.printStackTrace();

            throw new RuntimeException(e.getMessage(), e);
        }

        return value;
    }

}

  1. Test

package com.example.demo;

import com.example.wf.service.NewProcessService;
import com.example.wf.vo.UserTaskVo;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class TestFlowable {

    @Autowired
    private NewProcessService newProcessService;

    @Test
    public void getElValueTest() {
        String exp = "${abc == 1}";
        Map variableMap = new HashMap<>();
        variableMap.put("abc", "1");

        boolean flag = newProcessService.getElValue(exp, variableMap);
        System.err.println(flag);
    }

    @Test
    public void getElValueTest2() {
        String exp = "${halt == 'B'}";
        String taskId = "00b55b40-5904-11ed-acc1-005056b2814b";
        Map variableMap = new HashMap<>();
        variableMap.put("halt", "B");

        List nextUserTasks = newProcessService.getNextUserTasks(taskId, variableMap);
        System.err.println(nextUserTasks.size());
    }

}

你可能感兴趣的:(flowable,工作流,java,junit,java,spring)