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遇到的問題,參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章