@ruoli
2016-09-07T02:06:27.000000Z
字数 8101
阅读 3679
Activiti
Activiti默认是不带有选人的功能的,它默认的是在调用complete方法的时候自动根据下一个节点的 assignee属性设置下一节点的候选人,也可设置candidate属性或者角色,提交到下一步,流程引擎自动解析为公有任务,需要具体执行人去认领。
但是并不是所有的业务逻辑都符合Activit规定的标准情况,适用于这种操作,用户提交时需要从几个候选人中选择一个,然后发送到下一个环节,被选择的审批人,在下一环节拥有待办,目前Activiti工作流暂不支持原生支持,需要自己扩展。
Activiti自带了23张表,其中有四张组织人员相关表:
1) act_id_group用户组信息表
2) act_id_info用户扩展信息表
3) act_id_membership用户与用户组对应信息表
4) act_id_user用户信息表
原生的Activiti人员解析,需要依赖Activiti内置的四张组织信息表,也提供了一些列的AIP让我们去操作这些表,插入和获取信息。
Activiti本身自带了简易的人员管理功能,角色配置,原生的做法是将人员和角色信息配置到工作流表中,工作流就可以自动解析环节处理时的角色,转换为为处理人,我们具体业务实现不用处理,但是这直接导致了三个问题:
第一:就是工作流自带的人员角色表过于简单,不一定能应对复杂的业务逻辑需求。
第二:需要维护两套人员角色信息,加重了程序设计的复杂性。
第三:不便于扩展,业务程序对工作流人员解析这块完全没有控制权,无法做到选人等业务需求。
首先我们无需管这四张表,也不 用往这些表中插入任何数据,这样就可以使Actriviti基于角色的选人失效,因为根据角色无法解析到人员。
实现我们自己的选人,同样依赖与流程图的属性配置,具体的逻辑是:
流程图配置好审批角色后,业务逻辑程序在提交下一步之前,提前获取到下一步的审批环节和审批角色,手工解析为多个人员,展示给用户,让其选择一个或多个,再以流程参数的形式设置到流程中,提交下一步,下一步审批环节识别到流程参数,绑定审批人员。
用户获取流程定义相关信息,ActDefinitionService.java示例为:
package modules.act.service;import java.util.ArrayList;import java.util.List;import java.util.Set;import org.activiti.engine.RepositoryService;import org.activiti.engine.TaskService;import org.activiti.engine.delegate.Expression;import org.activiti.engine.impl.RepositoryServiceImpl;import org.activiti.engine.impl.bpmn.behavior.MultiInstanceActivityBehavior;import org.activiti.engine.impl.bpmn.behavior.NoneStartEventActivityBehavior;import org.activiti.engine.impl.bpmn.behavior.UserTaskActivityBehavior;import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;import org.activiti.engine.impl.pvm.PvmActivity;import org.activiti.engine.impl.pvm.PvmTransition;import org.activiti.engine.impl.pvm.delegate.ActivityBehavior;import org.activiti.engine.impl.pvm.process.ActivityImpl;import org.activiti.engine.impl.task.TaskDefinition;import org.activiti.engine.repository.ProcessDefinition;import org.activiti.engine.task.Task;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional;import common.utils.StringUtils;import modules.act.entity.ActTransition;/*** 流程定义Service* @author Ruoli* 2016.08.23*/@Service@Transactional(readOnly = true)public class ActDefinitionService {@Autowiredprivate RepositoryService repositoryService;@Autowiredprivate TaskService taskService;/*** 查询任务对应的下一步路由* @param taskId* @return*/public List<ActTransition> getApprovalInfo(String taskId){List<ActTransition> approvalList=new ArrayList<ActTransition>();//获取当前环节对象ActivityImpl activityImpl=this.getActivity(taskId);List<PvmTransition> outTransitions = activityImpl.getOutgoingTransitions();// 获取从某个节点出来的所有线路for (PvmTransition tr : outTransitions) {ActTransition transition=geTransition(tr);//transition.getTaskRoleList(); //获取角色 集合approvalList.add(transition);}return approvalList;}/*** 根据TaskId获取流程定义环节对象* @param taskId* @return*/public ActivityImpl getActivity(String taskId){Task task =taskService.createTaskQuery().taskId(taskId).singleResult();if(task!=null){ProcessDefinitionEntity def = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService).getDeployedProcessDefinition(task.getProcessDefinitionId());return def.findActivity(task.getTaskDefinitionKey());}return null;}/*** 根据路由Id获取路由对象* @param transitionId* @return ActTransition*/public ActTransition geTransition(String processDefinitionId,String transitionId){if(StringUtils.isNotEmpty(processDefinitionId) && StringUtils.isNotEmpty(transitionId)){ProcessDefinitionEntity def = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService).getDeployedProcessDefinition(processDefinitionId);List<ActivityImpl> activityList=def.getActivities();for(ActivityImpl activityImpl : activityList){List<PvmTransition> outTransitions=activityImpl.getOutgoingTransitions();for (PvmTransition pvmTransition : outTransitions) {if(transitionId.equals(pvmTransition.getId())){ActTransition actTransition=geTransition(pvmTransition);return actTransition;}}}}return null;}/*** 根据连线对象获取下一步处理信息* @param pvmTransition* @return ActTransition*/private ActTransition geTransition(PvmTransition pvmTransition){PvmActivity nextActivity = pvmTransition.getDestination();ActTransition actTransition=new ActTransition();actTransition.setId(pvmTransition.getId());actTransition.setName(pvmTransition.getProperty("name")+"");actTransition.setDescription(pvmTransition.getProperty("documentation")+"");actTransition.setCondition(pvmTransition.getProperty("conditionText")+"");actTransition.setTaskName(nextActivity.getProperty("name")+"");//判断是否是UserTaskActivityImpl activity=(ActivityImpl)nextActivity;ActivityBehavior activityBehavior = activity.getActivityBehavior();if (activityBehavior instanceof UserTaskActivityBehavior || activityBehavior instanceof MultiInstanceActivityBehavior) {TaskDefinition taskDefinition=(TaskDefinition)nextActivity.getProperty("taskDefinition");if(taskDefinition!=null){Set<Expression> roleSet=taskDefinition.getCandidateGroupIdExpressions();//List 用户存放下一步审批角色List<String> roleList=new ArrayList<String>();for(Expression expression:roleSet){roleList.add(expression.getExpressionText());}actTransition.setTaskRoleList(roleList);}}return actTransition;}/*** 获取首环节处理角色* @return*/public List<String> getFristNodeRole(String procDefKey){List<String> roleList=new ArrayList<String>();ProcessDefinition processDefinition=repositoryService.createProcessDefinitionQuery().processDefinitionKey(procDefKey).orderByProcessDefinitionVersion().desc().list().get(0);ProcessDefinitionEntity def = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService).getDeployedProcessDefinition(processDefinition.getId());List<ActivityImpl> activityList=def.getActivities();for(ActivityImpl activityImpl : activityList){ActivityBehavior activityBehavior = activityImpl.getActivityBehavior();if (activityBehavior instanceof NoneStartEventActivityBehavior) {PvmActivity fristTask=activityImpl.getOutgoingTransitions().get(0).getDestination();TaskDefinition taskDefinition=(TaskDefinition)fristTask.getProperty("taskDefinition");Set<Expression> roleSet=taskDefinition.getCandidateGroupIdExpressions();for(Expression expression:roleSet){roleList.add(expression.getExpressionText());}break;}}return roleList;}}
其中依赖实体类ActTransition.java 代码如下:
package modules.act.entity;import java.util.List;/*** 下一步处理信息,此类主要用于人员或路由选择页面* @author Ruoli* 2016/08/23*/public class ActTransition {private String id;//路由IDprivate String name;//路由名称private String description;//路由描述private String condition;//路由条件private String taskName;//下一步环节的名称private List<String> taskRoleList; //下一步审批角色集合//可根据业务需求新增更多字段public String getId() {return id;}public void setId(String id) {this.id = id;}public String getTaskName() {return taskName;}public void setTaskName(String taskName) {this.taskName = taskName;}public List<String> getTaskRoleList() {return taskRoleList;}public void setTaskRoleList(List<String> taskRoleList) {this.taskRoleList = taskRoleList;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getDescription() {return description;}public void setDescription(String description) {this.description = description;}public String getCondition() {return condition;}public void setCondition(String condition) {this.condition = condition;}}
/*** 获取流程审批信息,提供发送时 展示选环节列表* @param act* @return*/@SuppressWarnings("unchecked")protected List<Map<String, Object>> getApprovalTrack(String taskId){if(StringUtils.isNotBlank(taskId)){//1:获取路由信息List<ActTransition> approvalList=actDefinitionService.getApprovalInfo(taskId); //actTaskService.getApprovalInfo(act.getTaskId());//2:迭代路由if(approvalList!=null){//构建树形Tree-ListList<Map<String, Object>> resultList=new ArrayList<Map<String, Object>>();for (ActTransition transition : approvalList) {Map<String, Object> tempMap=new HashMap<String, Object>();tempMap.put("id",transition.getId());tempMap.put("name", transition.getTaskName());tempMap.put("pId",1);//此处还有验证路由条件的控制,暂时没有实现//此处可以自己行增加 路由对应的人员信息,可根据角色进行解析,此示例只需要进行选路由即可resultList.add(tempMap);}Map<String, Object> rootMap=new HashMap<String, Object>();rootMap.put("id","1");if(resultList.size()==0){rootMap.put("name","暂无处理环节");}else{rootMap.put("name","可被选择的处理环节");}rootMap.put("pId","0");rootMap.put("nocheck",true);//设置根节点不可选中resultList.add(rootMap);return resultList;}}return null;}