根据任务id、参数,预测、获取下一任务节点集合、候选用户集合、候选组集合、参与用户id集合等。
List nextUserTasks = newProcessService.getNextUserTasks(taskId, variableMap);
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);
}
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;
}
}
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());
}
}
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();
}
delete from ACT_RU_VARIABLE where EXECUTION_ID_ is null
delete from act_hi_varinst where EXECUTION_ID_ is null
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_;
}
}
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
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;
}
}
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;
}
}
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;
}
}
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;
}
}
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;
}
}
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;
}
}
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());
}
}