springboot+Activiti7整合实践 (七) 自定义用户任务行为

系列文章目录

第一章 springboot+Activiti7整合实践 (一)

第二章 springboot+Activiti7整合实践 (二) 模型定义

第三章 springboot+Activiti7整合实践 (三) 流程定义

第四章 springboot+Activiti7整合实践 (四) 分配规则

第五章 springboot+Activiti7整合实践 (五) 发布流程

第六章 springboot+Activiti7整合实践 (六) 启动流程(1)


目录

系列文章目录

前言

一、继承UserTaskActivityBehavior类

二、继承DefaultActivityBehaviorFactory类

三、创建ActivitiConfiguration配置类

总结


前言

前面的章节,通过选择用户、角色、部门的方式,我们外部定义了任务的代办人规则,这些规则是存储在我们自定义的数据库表中,那么如何使在工作流程中生效,这里我使用的方式是自定义用户任务行为,重写handleAssignments方法,设置任务的候选用户,接下来分享实现步骤。


一、继承UserTaskActivityBehavior类

public class BpmUserTaskActivityBehavior extends UserTaskActivityBehavior {

    @Setter
    private WorkTaskAssignRuleService workTaskAssignRuleService;

    public BpmUserTaskActivityBehavior(UserTask userTask) {
            super(userTask);
        }



    @Override
    protected void handleAssignments(TaskEntityManager taskEntityManager, String assignee, String owner, List<String> candidateUsers, List<String> candidateGroups, TaskEntity task, ExpressionManager expressionManager, DelegateExecution execution) {
                    // 第一步,获得任务的候选用户
            Set<String> userIdSet = calculateTaskCandidateUsers(execution);

        candidateUsers = userIdSet.stream().collect(Collectors.toList());

        super.handleAssignments(taskEntityManager,assignee,owner,candidateUsers,candidateGroups,task,expressionManager,execution);


        private Set<String> calculateTaskCandidateUsers(DelegateExecution execution) {
            // 情况一,如果是多实例的任务,例如说会签、或签等情况,则从 Variable 中获取。
            if (super.multiInstanceActivityBehavior != null) {
                String id = execution.getVariable(super.multiInstanceActivityBehavior.getCollectionElementVariable(), String.class);
                Set<String> set = new HashSet<>();
                set.add(id);
                return set;
            }

            Set<String> candidateUserIds = workTaskAssignRuleService.calculateTaskCandidateUsers(execution);


            return candidateUserIds;
        }
}

 成员变量workTaskAssignRuleServe是我们规则定义的服务类,需要依赖此对象,查询出模型定义阶段定义的分配规则,得到设置的用户id,设置到候选人用户组属性中。

 UserTaskActivityBehavior介绍:在Activiti中,每个活动节点都有对应的行为类,UserTaskActivityBehavior即为用户任务的行为类,每当流转到用户任务时,就会触发行为,有两个比较常用的方法,execute和handleAssignments,execute方法时用户任务执行就会触发,里面对调用到handleAssignments方法来分配代办人、代办人组等,感兴趣的可以看看源码。

public void execute(DelegateExecution execution) {
    CommandContext commandContext = Context.getCommandContext();
    TaskEntityManager taskEntityManager = commandContext.getTaskEntityManager();
    
    TaskEntity task = taskEntityManager.create();
    task.setExecution((ExecutionEntity) execution);
    task.setTaskDefinitionKey(userTask.getId());

    String activeTaskName = null;
    String activeTaskDescription = null;
    String activeTaskDueDate = null;
    String activeTaskPriority = null;
    String activeTaskCategory = null;
    String activeTaskFormKey = null;
    String activeTaskSkipExpression = null;
    String activeTaskAssignee = null;
    String activeTaskOwner = null;
    List<String> activeTaskCandidateUsers = null;
    List<String> activeTaskCandidateGroups = null;
    
    ProcessEngineConfigurationImpl processEngineConfiguration = Context.getProcessEngineConfiguration();
    ExpressionManager expressionManager = processEngineConfiguration.getExpressionManager();
    
    if (Context.getProcessEngineConfiguration().isEnableProcessDefinitionInfoCache()) {
      ObjectNode taskElementProperties = Context.getBpmnOverrideElementProperties(userTask.getId(), execution.getProcessDefinitionId());
      activeTaskName = getActiveValue(userTask.getName(), DynamicBpmnConstants.USER_TASK_NAME, taskElementProperties);
      activeTaskDescription = getActiveValue(userTask.getDocumentation(), DynamicBpmnConstants.USER_TASK_DESCRIPTION, taskElementProperties);
      activeTaskDueDate = getActiveValue(userTask.getDueDate(), DynamicBpmnConstants.USER_TASK_DUEDATE, taskElementProperties);
      activeTaskPriority = getActiveValue(userTask.getPriority(), DynamicBpmnConstants.USER_TASK_PRIORITY, taskElementProperties);
      activeTaskCategory = getActiveValue(userTask.getCategory(), DynamicBpmnConstants.USER_TASK_CATEGORY, taskElementProperties);
      activeTaskFormKey = getActiveValue(userTask.getFormKey(), DynamicBpmnConstants.USER_TASK_FORM_KEY, taskElementProperties);
      activeTaskSkipExpression = getActiveValue(userTask.getSkipExpression(), DynamicBpmnConstants.TASK_SKIP_EXPRESSION, taskElementProperties);
      activeTaskAssignee = getActiveValue(userTask.getAssignee(), DynamicBpmnConstants.USER_TASK_ASSIGNEE, taskElementProperties);
      activeTaskOwner = getActiveValue(userTask.getOwner(), DynamicBpmnConstants.USER_TASK_OWNER, taskElementProperties);
      activeTaskCandidateUsers = getActiveValueList(userTask.getCandidateUsers(), DynamicBpmnConstants.USER_TASK_CANDIDATE_USERS, taskElementProperties);
      activeTaskCandidateGroups = getActiveValueList(userTask.getCandidateGroups(), DynamicBpmnConstants.USER_TASK_CANDIDATE_GROUPS, taskElementProperties);
      
    } else {
      activeTaskName = userTask.getName();
      activeTaskDescription = userTask.getDocumentation();
      activeTaskDueDate = userTask.getDueDate();
      activeTaskPriority = userTask.getPriority();
      activeTaskCategory = userTask.getCategory();
      activeTaskFormKey = userTask.getFormKey();
      activeTaskSkipExpression = userTask.getSkipExpression();
      activeTaskAssignee = userTask.getAssignee();
      activeTaskOwner = userTask.getOwner();
      activeTaskCandidateUsers = userTask.getCandidateUsers();
      activeTaskCandidateGroups = userTask.getCandidateGroups();
    }

    if (StringUtils.isNotEmpty(activeTaskName)) {
      String name = null;
      try {
        name = (String) expressionManager.createExpression(activeTaskName).getValue(execution);
      } catch (ActivitiException e) {
        name = activeTaskName;
        LOGGER.warn("property not found in task name expression " + e.getMessage());
      }
      task.setName(name);
    }
    
    if (StringUtils.isNotEmpty(activeTaskDescription)) {
      String description = null;
      try {
        description = (String) expressionManager.createExpression(activeTaskDescription).getValue(execution);
      } catch (ActivitiException e) {
        description = activeTaskDescription;
        LOGGER.warn("property not found in task description expression " + e.getMessage());
      }
      task.setDescription(description);
    }

    if (StringUtils.isNotEmpty(activeTaskDueDate)) {
      Object dueDate = expressionManager.createExpression(activeTaskDueDate).getValue(execution);
      if (dueDate != null) {
        if (dueDate instanceof Date) {
          task.setDueDate((Date) dueDate);
        } else if (dueDate instanceof String) {
          String businessCalendarName = null;
          if (StringUtils.isNotEmpty(userTask.getBusinessCalendarName())) {
            businessCalendarName = expressionManager.createExpression(userTask.getBusinessCalendarName()).getValue(execution).toString();
          } else {
            businessCalendarName = DueDateBusinessCalendar.NAME;
          }
          
          BusinessCalendar businessCalendar = Context.getProcessEngineConfiguration().getBusinessCalendarManager()
              .getBusinessCalendar(businessCalendarName);
          task.setDueDate(businessCalendar.resolveDuedate((String) dueDate));
          
        } else {
          throw new ActivitiIllegalArgumentException("Due date expression does not resolve to a Date or Date string: " + activeTaskDueDate);
        }
      }
    }
    
    if (StringUtils.isNotEmpty(activeTaskPriority)) {
      final Object priority = expressionManager.createExpression(activeTaskPriority).getValue(execution);
      if (priority != null) {
        if (priority instanceof String) {
          try {
            task.setPriority(Integer.valueOf((String) priority));
          } catch (NumberFormatException e) {
            throw new ActivitiIllegalArgumentException("Priority does not resolve to a number: " + priority, e);
          }
        } else if (priority instanceof Number) {
          task.setPriority(((Number) priority).intValue());
        } else {
          throw new ActivitiIllegalArgumentException("Priority expression does not resolve to a number: " + activeTaskPriority);
        }
      }
    }

    if (StringUtils.isNotEmpty(activeTaskCategory)) {
      final Object category = expressionManager.createExpression(activeTaskCategory).getValue(execution);
      if (category != null) {
        if (category instanceof String) {
          task.setCategory((String) category);
        } else {
          throw new ActivitiIllegalArgumentException("Category expression does not resolve to a string: " + activeTaskCategory);
        }
      }
    }
    
    if (StringUtils.isNotEmpty(activeTaskFormKey)) {
      final Object formKey = expressionManager.createExpression(activeTaskFormKey).getValue(execution);
      if (formKey != null) {
        if (formKey instanceof String) {
          task.setFormKey((String) formKey);
        } else {
          throw new ActivitiIllegalArgumentException("FormKey expression does not resolve to a string: " + activeTaskFormKey);
        }
      }
    }


    taskEntityManager.insert(task, (ExecutionEntity) execution);

    task.setVariablesLocal(calculateInputVariables(execution));

    boolean skipUserTask = false;
    if (StringUtils.isNotEmpty(activeTaskSkipExpression)) {
      Expression skipExpression = expressionManager.createExpression(activeTaskSkipExpression);
      skipUserTask = SkipExpressionUtil.isSkipExpressionEnabled(execution, skipExpression) 
          && SkipExpressionUtil.shouldSkipFlowElement(execution, skipExpression);
    }
    
    // Handling assignments need to be done after the task is inserted, to have an id
    if (!skipUserTask) {
      handleAssignments(taskEntityManager, activeTaskAssignee, activeTaskOwner, 
        activeTaskCandidateUsers, activeTaskCandidateGroups, task, expressionManager, execution);
    }
    
    processEngineConfiguration.getListenerNotificationHelper().executeTaskListeners(task, TaskListener.EVENTNAME_CREATE);
    
    // All properties set, now fire events
    if (Context.getProcessEngineConfiguration().getEventDispatcher().isEnabled()) {
      ActivitiEventDispatcher eventDispatcher = Context.getProcessEngineConfiguration().getEventDispatcher();
      eventDispatcher.dispatchEvent(
          ActivitiEventBuilder.createEntityEvent(ActivitiEventType.TASK_CREATED, task));
      if (task.getAssignee() != null) {
        eventDispatcher.dispatchEvent(
                ActivitiEventBuilder.createEntityEvent(ActivitiEventType.TASK_ASSIGNED, task));
      }
    }
    
    if (skipUserTask) {
      taskEntityManager.deleteTask(task, null, false, false);
      leave(execution);
    }

  }

二、继承DefaultActivityBehaviorFactory类

public class BpmActivityBehaviorFactory extends DefaultActivityBehaviorFactory {

    @Setter
    private WorkTaskAssignRuleService workTaskAssignRuleService;


    @Override
    public UserTaskActivityBehavior createUserTaskActivityBehavior(UserTask userTask) {
        BpmUserTaskActivityBehavior bpmUserTaskActivityBehavior =new BpmUserTaskActivityBehavior(userTask);
        bpmUserTaskActivityBehavior.setWorkTaskAssignRuleService(workTaskAssignRuleService);
        return bpmUserTaskActivityBehavior;

    }

}

直接上代码,继承DefaultActivityBehaviorFactory类,重新createUserTaskActivityBehavior方法,使用我们上一步创建的行为类。

三、创建ActivitiConfiguration配置类

@Configuration
public class ActivitiConfiguration{
    @Autowired
    private DataSource dataSource;
    @Bean
    public StandaloneProcessEngineConfiguration processEngineConfiguration(BpmActivityBehaviorFactory bpmActivityBehaviorFactory) {

       StandaloneProcessEngineConfiguration configuration = (StandaloneProcessEngineConfiguration) ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
        configuration.setDataSource(dataSource);
        configuration.setActivityBehaviorFactory(bpmActivityBehaviorFactory);
        return configuration;
    }
    @Bean
    public BpmActivityBehaviorFactory bpmActivityBehaviorFactory(WorkTaskAssignRuleService taskRuleService) {
        BpmActivityBehaviorFactory bpmActivityBehaviorFactory = new BpmActivityBehaviorFactory();
        bpmActivityBehaviorFactory.setWorkTaskAssignRuleService(taskRuleService);
        return bpmActivityBehaviorFactory;
    }

    /**
     * 创建引擎
     * @return ProcessEngine
     */
    @Bean(name = "mysqlProcessEngine")
    @Primary
    public ProcessEngine processEngine(ProjectModelService projectModelService, BpmActivityBehaviorFactory bpmActivityBehaviorFactory) {
        return processEngineConfiguration(bpmActivityBehaviorFactory).buildProcessEngine();

    }

}

 此配置类创建了StandaloneProcessEngineConfiguration流程引擎的配置类,并生成了processEngine引擎类对象,实现使重写的用户任务行为生效。

注:processEngine方法要写bean的name属性,否则会报错,因为springboot默认部署创建引擎对象,会造成bean名称重复,所以加上@Primary注解和@Bean的name属性。


总结

到这里我们工作流程进入到用户任务时,就会触发重写的用户行为方法,根据规则配置的内容,查询到用户,设置到相应属性中,才能实现我们后续的根据用户来查询代办任务功能。

  • 46
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘一线

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值