activiti抄送

项目地址:activiti-workflow,欢迎star。

在流程审批中,在某一个节点需要抄送某人,被抄送人看查看流程,不需要审批。这里是通过对activit扩展,自定义BPMN标签,追加了抄送属性。

对普通用户节点设置抄送属性,继承UserTask


/**
 * @description: 自定义用户节点
 * @author lhj
 * @param  
 * @return 
 * @date 2020-6-11 10:50 
 */
public class CustomUserTask extends UserTask {

    //抄送用户
    protected List<String> candidateNotifyUsers = new ArrayList();

    public List<String> getCandidateNotifyUsers() {
        return candidateNotifyUsers;
    }

    public void setCandidateNotifyUsers(List<String> candidateNotifyUsers) {
        this.candidateNotifyUsers = candidateNotifyUsers;
    }

    public CustomUserTask clone() {
        CustomUserTask clone = new CustomUserTask();
        clone.setValues(this);
        return clone;
    }
    public void setValues(CustomUserTask otherElement) {
        super.setValues(otherElement);
        this.setCandidateNotifyUsers(otherElement.getCandidateNotifyUsers());
    }
}

解析BPMN的xml和json是设置该属性

	if (StringUtils.isNotEmpty(xtr.getAttributeValue(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_CANDIDATE_NOTIFY_USERS))) {
      String expression = xtr.getAttributeValue(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_CANDIDATE_NOTIFY_USERS);
      userTask.getCandidateNotifyUsers().addAll(parseDelimitedList(expression));
    }
   task.setCandidateNotifyUsers(getValueAsList(CANDIDATE_NOTIFY_USERS, assignmentDefNode));

bpmn文件格式

    <userTask id="sid-254390AD-30E7-4390-8B97-E2A395C4A15C" name="主管审批" activiti:assignee="lisi" activiti:candidateNotifyUsers="wangwu,zhangsan">
      <extensionElements>
        <modeler:initiator-can-complete xmlns:modeler="http://activiti.com/modeler"><![CDATA[false]]></modeler:initiator-can-complete>
      </extensionElements>
    </userTask>

在流程流转过程中将抄送人落地,存入数据库,处理逻辑主要在UserTaskActivityBehavior,通过继承实现

  //保存抄送人
    if (candidateNotifyUsers != null && !candidateNotifyUsers.isEmpty()) {
      for (String notify : candidateNotifyUsers) {
        Expression userIdExpr = expressionManager.createExpression(notify);
        Object value = userIdExpr.getValue(execution);
        if (value instanceof String) {
          List<String> userIds = extractCandidates((String) value);
          for (String userId : userIds) {
            Context.getCommandContext().getIdentityLinkEntityManager().addUserIdentityLink(task, userId, ProcessConstants.NOTIFY);
          }
        } else if (value instanceof Collection) {
          Iterator userIdSet = ((Collection) value).iterator();
          while (userIdSet.hasNext()) {
            Context.getCommandContext().getIdentityLinkEntityManager().addUserIdentityLink(task, (String)userIdSet.next(), ProcessConstants.NOTIFY);
          }
          throw new ActivitiException("Expression did not resolve to a string or collection of strings");
        }
      }
    }

到此,抄送定义和数据保存都已实现,剩下就是如何查询数据,这就要看具体业务需要是怎么样的。这里做简单实现,根据待办一起查询抄送。通过activiti提供的扩展Mybatis实现。

	/**
     *  查询待审批任务
     * @param taskUnFinishQuery 查询条件
     * @return
     */
    @Override
    public PageBean<ProcessTaskResult> queryUnFinishTask(TaskUnFinishQuery taskUnFinishQuery){
        PageUtil<ProcessTaskResult, TaskUnFinishQuery> pageUtil = new PageUtil<>();
        Long count = managementService.executeCustomSql(new AbstractCustomSqlExecution<CustomActivitiDatabaseMapper, Long>(CustomActivitiDatabaseMapper.class) {
            @Override
            public Long execute(CustomActivitiDatabaseMapper customActivitiDatabaseMapper) {
                return customActivitiDatabaseMapper.selectUnFinishTaskCount(taskUnFinishQuery);
            }
        });
        //没有查询到,就直接返回空
        if(count <= 0){
            return pageUtil.buildPage(Collections.emptyList(), taskUnFinishQuery, 0);
        }
        List<ProcessTaskResult> list = managementService.executeCustomSql(new AbstractCustomSqlExecution<CustomActivitiDatabaseMapper, List<ProcessTaskResult>>(CustomActivitiDatabaseMapper.class) {
            @Override
            public List<ProcessTaskResult> execute(CustomActivitiDatabaseMapper customActivitiDatabaseMapper) {
                return customActivitiDatabaseMapper.selectUnFinishTask(taskUnFinishQuery);
            }
        });

        return pageUtil.buildPage(list,taskUnFinishQuery,count);
    }

还有额外处理,抄送可能是针对整个流程,但并不是某个节点。因此在存抄送人时,不但存taskId,还保存了processInstanceId实例ID

	@Override
    public IdentityLinkEntity addIdentityLink(TaskEntity taskEntity, String userId, String groupId, String type) {
        IdentityLinkEntity identityLinkEntity = (IdentityLinkEntity)this.identityLinkDataManager.create();
        taskEntity.getIdentityLinks().add(identityLinkEntity);
        identityLinkEntity.setTask(taskEntity);
        identityLinkEntity.setUserId(userId);
        identityLinkEntity.setGroupId(groupId);
        if (ProcessConstants.NOTIFY.equals(type)) {
            identityLinkEntity.setProcessInstanceId(taskEntity.getProcessInstanceId());
        }
        identityLinkEntity.setType(type);
        this.insert(identityLinkEntity);
        if (userId != null && taskEntity.getProcessInstanceId() != null) {
            this.involveUser(taskEntity.getProcessInstance(), userId, "participant");
        }

        return identityLinkEntity;
    }

这里给出一种实现思路,只供参考。具体代码可到github项目中查看。
关于扩展BPMN遇到的问题,参考

  • Activiti子流程扩展标签
  • Activiti自定义BPMN

你可能感兴趣的:(activiti)