Activiti选人页面的实现

来源:互联网 发布:淘宝店铺封了怎么解封 编辑:程序博客网 时间:2024/06/03 17:48

Activiti选人页面的实现

Activiti


1、背景

Activiti默认是不带有选人的功能的,它默认的是在调用complete方法的时候自动根据下一个节点的 assignee属性设置下一节点的候选人,也可设置candidate属性或者角色,提交到下一步,流程引擎自动解析为公有任务,需要具体执行人去认领。 
但是并不是所有的业务逻辑都符合Activit规定的标准情况,适用于这种操作,用户提交时需要从几个候选人中选择一个,然后发送到下一个环节,被选择的审批人,在下一环节拥有待办,目前Activiti工作流暂不支持原生支持,需要自己扩展。

2、扩展步骤

1、实现原理

1、目前Activiti人员解析逻辑

Activiti自带了23张表,其中有四张组织人员相关表: 
1) act_id_group用户组信息表 
2) act_id_info用户扩展信息表 
3) act_id_membership用户与用户组对应信息表 
4) act_id_user用户信息表 
原生的Activiti人员解析,需要依赖Activiti内置的四张组织信息表,也提供了一些列的AIP让我们去操作这些表,插入和获取信息。 
Activiti本身自带了简易的人员管理功能,角色配置,原生的做法是将人员和角色信息配置到工作流表中,工作流就可以自动解析环节处理时的角色,转换为为处理人,我们具体业务实现不用处理,但是这直接导致了三个问题: 
第一:就是工作流自带的人员角色表过于简单,不一定能应对复杂的业务逻辑需求。 
第二:需要维护两套人员角色信息,加重了程序设计的复杂性。 
第三:不便于扩展,业务程序对工作流人员解析这块完全没有控制权,无法做到选人等业务需求。

2、如何使用自己的选人逻辑

首先我们无需管这四张表,也不 用往这些表中插入任何数据,这样就可以使Actriviti基于角色的选人失效,因为根据角色无法解析到人员。 
实现我们自己的选人,同样依赖与流程图的属性配置,具体的逻辑是: 
流程图配置好审批角色后,业务逻辑程序在提交下一步之前,提前获取到下一步的审批环节和审批角色,手工解析为多个人员,展示给用户,让其选择一个或多个,再以流程参数的形式设置到流程中,提交下一步,下一步审批环节识别到流程参数,绑定审批人员。

2、具体实现

1、编写流程定义工具类

用户获取流程定义相关信息,ActDefinitionService.java示例为:

  1. package modules.act.service;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. import java.util.Set;
  5. import org.activiti.engine.RepositoryService;
  6. import org.activiti.engine.TaskService;
  7. import org.activiti.engine.delegate.Expression;
  8. import org.activiti.engine.impl.RepositoryServiceImpl;
  9. import org.activiti.engine.impl.bpmn.behavior.MultiInstanceActivityBehavior;
  10. import org.activiti.engine.impl.bpmn.behavior.NoneStartEventActivityBehavior;
  11. import org.activiti.engine.impl.bpmn.behavior.UserTaskActivityBehavior;
  12. import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
  13. import org.activiti.engine.impl.pvm.PvmActivity;
  14. import org.activiti.engine.impl.pvm.PvmTransition;
  15. import org.activiti.engine.impl.pvm.delegate.ActivityBehavior;
  16. import org.activiti.engine.impl.pvm.process.ActivityImpl;
  17. import org.activiti.engine.impl.task.TaskDefinition;
  18. import org.activiti.engine.repository.ProcessDefinition;
  19. import org.activiti.engine.task.Task;
  20. import org.springframework.beans.factory.annotation.Autowired;
  21. import org.springframework.stereotype.Service;
  22. import org.springframework.transaction.annotation.Transactional;
  23. import common.utils.StringUtils;
  24. import modules.act.entity.ActTransition;
  25. /**
  26. * 流程定义Service
  27. */
  28. @Service
  29. @Transactional(readOnly = true)
  30. public class ActDefinitionService {
  31. @Autowired
  32. private RepositoryService repositoryService;
  33. @Autowired
  34. private TaskService taskService;
  35. /**
  36. * 查询任务对应的下一步路由
  37. * @param taskId
  38. * @return
  39. */
  40. public List<ActTransition> getApprovalInfo(String taskId){
  41. List<ActTransition> approvalList=new ArrayList<ActTransition>();
  42. //获取当前环节对象
  43. ActivityImpl activityImpl=this.getActivity(taskId);
  44. List<PvmTransition> outTransitions = activityImpl
  45. .getOutgoingTransitions();// 获取从某个节点出来的所有线路
  46. for (PvmTransition tr : outTransitions) {
  47. ActTransition transition=geTransition(tr);
  48. //transition.getTaskRoleList(); //获取角色 集合
  49. approvalList.add(transition);
  50. }
  51. return approvalList;
  52. }
  53. /**
  54. * 根据TaskId获取流程定义环节对象
  55. * @param taskId
  56. * @return
  57. */
  58. public ActivityImpl getActivity(String taskId){
  59. Task task =taskService.createTaskQuery().taskId(taskId).singleResult();
  60. if(task!=null){
  61. ProcessDefinitionEntity def = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
  62. .getDeployedProcessDefinition(task.getProcessDefinitionId());
  63. return def.findActivity(task.getTaskDefinitionKey());
  64. }
  65. return null;
  66. }
  67. /**
  68. * 根据路由Id获取路由对象
  69. * @param transitionId
  70. * @return ActTransition
  71. */
  72. public ActTransition geTransition(String processDefinitionId,String transitionId){
  73. if(StringUtils.isNotEmpty(processDefinitionId) && StringUtils.isNotEmpty(transitionId)){
  74. ProcessDefinitionEntity def = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
  75. .getDeployedProcessDefinition(processDefinitionId);
  76. List<ActivityImpl> activityList=def.getActivities();
  77. for(ActivityImpl activityImpl : activityList){
  78. List<PvmTransition> outTransitions=activityImpl.getOutgoingTransitions();
  79. for (PvmTransition pvmTransition : outTransitions) {
  80. if(transitionId.equals(pvmTransition.getId())){
  81. ActTransition actTransition=geTransition(pvmTransition);
  82. return actTransition;
  83. }
  84. }
  85. }
  86. }
  87. return null;
  88. }
  89. /**
  90. * 根据连线对象获取下一步处理信息
  91. * @param pvmTransition
  92. * @return ActTransition
  93. */
  94. private ActTransition geTransition(PvmTransition pvmTransition){
  95. PvmActivity nextActivity = pvmTransition.getDestination();
  96. ActTransition actTransition=new ActTransition();
  97. actTransition.setId(pvmTransition.getId());
  98. actTransition.setName(pvmTransition.getProperty("name")+"");
  99. actTransition.setDescription(pvmTransition.getProperty("documentation")+"");
  100. actTransition.setCondition(pvmTransition.getProperty("conditionText")+"");
  101. actTransition.setTaskName(nextActivity.getProperty("name")+"");
  102. //判断是否是UserTask
  103. ActivityImpl activity=(ActivityImpl)nextActivity;
  104. ActivityBehavior activityBehavior = activity.getActivityBehavior();
  105. if (activityBehavior instanceof UserTaskActivityBehavior || activityBehavior instanceof MultiInstanceActivityBehavior) {
  106. TaskDefinition taskDefinition=(TaskDefinition)nextActivity.getProperty("taskDefinition");
  107. if(taskDefinition!=null){
  108. Set<Expression> roleSet=taskDefinition.getCandidateGroupIdExpressions();
  109. //List 用户存放下一步审批角色
  110. List<String> roleList=new ArrayList<String>();
  111. for(Expression expression:roleSet){
  112. roleList.add(expression.getExpressionText());
  113. }
  114. actTransition.setTaskRoleList(roleList);
  115. }
  116. }
  117. return actTransition;
  118. }
  119. /**
  120. * 获取首环节处理角色
  121. * @return
  122. */
  123. public List<String> getFristNodeRole(String procDefKey){
  124. List<String> roleList=new ArrayList<String>();
  125. ProcessDefinition processDefinition=repositoryService.createProcessDefinitionQuery().processDefinitionKey(procDefKey)
  126. .orderByProcessDefinitionVersion().desc().list().get(0);
  127. ProcessDefinitionEntity def = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
  128. .getDeployedProcessDefinition(processDefinition.getId());
  129. List<ActivityImpl> activityList=def.getActivities();
  130. for(ActivityImpl activityImpl : activityList){
  131. ActivityBehavior activityBehavior = activityImpl.getActivityBehavior();
  132. if (activityBehavior instanceof NoneStartEventActivityBehavior) {
  133. PvmActivity fristTask=activityImpl.getOutgoingTransitions().get(0).getDestination();
  134. TaskDefinition taskDefinition=(TaskDefinition)fristTask.getProperty("taskDefinition");
  135. Set<Expression> roleSet=taskDefinition.getCandidateGroupIdExpressions();
  136. for(Expression expression:roleSet){
  137. roleList.add(expression.getExpressionText());
  138. }
  139. break;
  140. }
  141. }
  142. return roleList;
  143. }
  144. }

其中依赖实体类ActTransition.java 代码如下:

  1. package modules.act.entity;
  2. import java.util.List;
  3. /**
  4. * 下一步处理信息,此类主要用于人员或路由选择页面
  5. * 2016/08/23
  6. */
  7. public class ActTransition {
  8. private String id;//路由ID
  9. private String name;//路由名称
  10. private String description;//路由描述
  11. private String condition;//路由条件
  12. private String taskName;//下一步环节的名称
  13. private List<String> taskRoleList; //下一步审批角色集合
  14. //可根据业务需求新增更多字段
  15. public String getId() {
  16. return id;
  17. }
  18. public void setId(String id) {
  19. this.id = id;
  20. }
  21. public String getTaskName() {
  22. return taskName;
  23. }
  24. public void setTaskName(String taskName) {
  25. this.taskName = taskName;
  26. }
  27. public List<String> getTaskRoleList() {
  28. return taskRoleList;
  29. }
  30. public void setTaskRoleList(List<String> taskRoleList) {
  31. this.taskRoleList = taskRoleList;
  32. }
  33. public String getName() {
  34. return name;
  35. }
  36. public void setName(String name) {
  37. this.name = name;
  38. }
  39. public String getDescription() {
  40. return description;
  41. }
  42. public void setDescription(String description) {
  43. this.description = description;
  44. }
  45. public String getCondition() {
  46. return condition;
  47. }
  48. public void setCondition(String condition) {
  49. this.condition = condition;
  50. }
  51. }

2、编写选环节Controller方法

  1. /**
  2. * 获取流程审批信息,提供发送时 展示选环节列表
  3. * @param act
  4. * @return
  5. */
  6. @SuppressWarnings("unchecked")
  7. protected List<Map<String, Object>> getApprovalTrack(String taskId){
  8. if(StringUtils.isNotBlank(taskId)){
  9. //1:获取路由信息
  10. List<ActTransition> approvalList=actDefinitionService.getApprovalInfo(taskId); //actTaskService.getApprovalInfo(act.getTaskId());
  11. //2:迭代路由
  12. if(approvalList!=null){
  13. //构建树形Tree-List
  14. List<Map<String, Object>> resultList=new ArrayList<Map<String, Object>>();
  15. for (ActTransition transition : approvalList) {
  16. Map<String, Object> tempMap=new HashMap<String, Object>();
  17. tempMap.put("id",transition.getId());
  18. tempMap.put("name", transition.getTaskName());
  19. tempMap.put("pId",1);
  20. //此处还有验证路由条件的控制,暂时没有实现
  21. //此处可以自己行增加 路由对应的人员信息,可根据角色进行解析,此示例只需要进行选路由即可
  22. resultList.add(tempMap);
  23. }
  24. Map<String, Object> rootMap=new HashMap<String, Object>();
  25. rootMap.put("id","1");
  26. if(resultList.size()==0){
  27. rootMap.put("name","暂无处理环节");
  28. }else{
  29. rootMap.put("name","可被选择的处理环节");
  30. }
  31. rootMap.put("pId","0");
  32. rootMap.put("nocheck",true);//设置根节点不可选中
  33. resultList.add(rootMap);
  34. return resultList;
  35. }
  36. }
  37. return null;
  38. }
    原创粉丝点击