Flowable自动审核、相邻节点审核、已存在审核人审核

Flowable 监听器的使用

需求背景:
1、发起人发起流程,可以实现发起人自动审核
2、上一节点的审核人,与当前节点审核人相同时,自动审核
3、整个流程实例中,存在已审核的审核人,当前节点自动审核

流程图如下所示:
image
针对于自动审核设置,其实是由前端内置bpnm.xml 去设置的,与前端达成协议,例如不启用时,就不要置入监听器,启用时,就植入监听器,在配置不同的字段,表示不同的审核方式。

发起人自动审核

自定义监听器,实现TaskListener,并配置需要的字段,该字段与前端的需要达成一致
image

bpmn.xml 如下:
image

这样在监听器下就可以接受到这两个字段的值,根据这两个字段的值,去完成自动审核功能。
值得注意的是,在监听器中,spring的自动注入并不能通过注解 @Autowired 去实现,而且通过构造函数加spring的上下文去实现注入。
例如:
image

重写TaskListener 的 notify 方法,该方法的形参是DelegateTask,这个参数可以获取到bpnm.xml 中 任务节点的属性,例如监听器的字段,任务id,流程实例id,流程定义等等。基于这个现有条件,我们即可完成发起人自动审核。

   @Override
    public void notify(DelegateTask delegateTask) {

            // 从 FixedValue 中获取值
            String autoApprovalEnabledStr = (String) autoApprovalEnabled.getValue(delegateTask);
            String autoApprovalRuleStr = (String) autoApprovalRule.getValue(delegateTask);

            String processDefinitionId = delegateTask.getProcessDefinitionId();
            String taskDefinitionKey = delegateTask.getTaskDefinitionKey();

            BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
            String eventName = delegateTask.getEventName();
            logger.info("触发监听器,当前监听器级别:{}",eventName);
            logger.info("触发监听器,当前任务:{}",delegateTask.getName());
            UserTask userTask = (UserTask) bpmnModel.getFlowElement(taskDefinitionKey);
           createLevelAutoTask(userTask,delegateTask,autoApprovalRuleStr,autoApprovalEnabledStr);
    }

在 createLevelAutoTask 方法中,需要完成以下步骤,判断当前的任务节点是不是会签节点,针对与会签节点,我们不去实现自动审核,直接停止当前监听器即可,还需要考虑,发起人如果是角色,或者是部门的情况下,我们应该怎么去实现,同样的,发起人是单个用户的话怎么实现,针对单个用户非常简单。

 private void createLevelAutoTask(UserTask userTask, DelegateTask delegateTask, String autoApprovalRuleStr,  String autoApprovalEnabledStr) {
        // 检查会签任务
        Integer nrOfInstances = (Integer) delegateTask.getVariable("nrOfInstances");
        Integer nrOfCompletedInstances = (Integer) delegateTask.getVariable("nrOfCompletedInstances");
        if (nrOfInstances != null && nrOfCompletedInstances != null) {
            // 这是一个多实例任务
           return;
        }

        if (userTask !=null){
            // 获取 当前任务节点的 类型,部门 DEPTS 、角色 ROLES
            String dataType = userTask.getAttributeValue(ProcessConstants.NAMASPASE, ProcessConstants.PROCESS_CUSTOM_DATA_TYPE);
            // 获取组的ID,角色ID集合或部门ID集合
            List<Long> groups = userTask.getCandidateGroups().stream()
                    .map(item -> Long.parseLong(item.substring(4)))
                    .collect(Collectors.toList());
            List<Long> userIds = new ArrayList<>();
            // 分别处理发起人是角色,部门,和user的场景
            if ("ROLES".equals(dataType) && !groups.isEmpty()){
                UserGroupRoleBO userGroupRoleBO = new UserGroupRoleBO();
                userGroupRoleBO.setRoleIdList(groups);
                userGroupRoleBO.setOrgIdList(null);
                userIds = userRemote.findUserByOrgIdsOrByRoleIds(userGroupRoleBO);
                // 表示启用自动审核
                if (AutoProcessType.AUTO_RULE_ENABLE.getCode().equals(autoApprovalEnabledStr)) {
                    handleAutoApproval1(delegateTask, autoApprovalRuleStr,userIds);
                }
            }else if("DEPTS".equals(dataType) && !groups.isEmpty()){
                UserGroupRoleBO userGroupRoleBO = new UserGroupRoleBO();
                userGroupRoleBO.setRoleIdList(null);
                userGroupRoleBO.setOrgIdList(groups);
                userIds = userRemote.findUserByOrgIdsOrByRoleIds(userGroupRoleBO);
                // 表示启用自动审核
                if (AutoProcessType.AUTO_RULE_ENABLE.getCode().equals(autoApprovalEnabledStr)) {
                    handleAutoApproval1(delegateTask, autoApprovalRuleStr,userIds);
                }
            }else {
                if (AutoProcessType.AUTO_RULE_ENABLE.getCode().equals(autoApprovalEnabledStr)){
                    handleAutoApproval(delegateTask, autoApprovalRuleStr);
                }
            }
        }
    }

直接从单个用户来说吧,对于部门和角色相差不差,只需要获取到部门的id或者角色id,通过服务调用的方式去拿到用户的id,判断当前的登录用户是否在这个用户id集合中,存在即自动审核就好。

以下是针对单个用户的实现代码

    @Transactional
    public void handleAutoApproval(DelegateTask delegateTask, String autoApprovalRule) {
        String processInstanceId = delegateTask.getProcessInstanceId();
        Map<String, Object> variables = delegateTask.getVariables();
        String taskId = delegateTask.getId();
        String assignee = delegateTask.getAssignee();
        String currentAssignee = (String) variables.get(ProcessConstants.CURRENT_ASSIGNEE);
        // 每一次任务审核,存储审核人的id
        List<String> assigneeList = (ArrayList) variables.get(ProcessConstants.ASSIGNEE_LIST) == null?new ArrayList<>():(ArrayList) variables.get("assigneeList") ;
        String userIdStr = (String) variables.get(ProcessConstants.PROCESS_INITIATOR);
        UserToken userToken = AuthorizationContext.getAdminUser();
        String userId = userToken.getUserId().toString();
        NodeUserVO uservo = userRemote.findUserById(Long.parseLong(assignee));
        String nickname = uservo.getNickname();
        String msg = AutoProcessType.AUTO_INITIATOR_ENABLE.getCode().equals(autoApprovalRule)?nickname + "发起流程申请":nickname+"通过";
        // 发起人自动审核
        if (AutoProcessType.AUTO_INITIATOR_ENABLE.getCode().equals(autoApprovalRule)) {
            if (userId.equals(userIdStr)) {
                assigneeList.add(userIdStr);
                variables.put(ProcessConstants.CURRENT_ASSIGNEE,userId);
                variables.put(ProcessConstants.ASSIGNEE_LIST,assigneeList);
                commentTask(userId, taskId, processInstanceId, FlowComment.NORMAL.getType(), msg, variables, delegateTask);
            }
        }   else if (AutoProcessType.AUTO_ADJACENT_ENABLE.getCode().equals(autoApprovalRule)) {
//            if (checkPreviousAssignee(assignee, delegateTask)) {
//                variables.put("currentAssignee",String.valueOf(userId));
//                variables.put(ProcessConstants.FLOWABLE_SKIP_EXPRESSION_ENABLED, true);
//                commentTask(userId, taskId, processInstanceId, FlowComment.SKIP.getType(), msg, variables, delegateTask);
//            }
            // 判断 上一节点 审批人 与当前节点审批人是否一致
            if (StringUtils.isNotBlank(currentAssignee) && currentAssignee.equals(assignee)) {
                variables.put(ProcessConstants.CURRENT_ASSIGNEE,userId);
                assigneeList.add(userIdStr);
                variables.put(ProcessConstants.ASSIGNEE_LIST,assigneeList);
                variables.put(ProcessConstants.FLOWABLE_SKIP_EXPRESSION_ENABLED, true);
                commentTask(userId, taskId, processInstanceId, FlowComment.SKIP.getType(), msg, variables, delegateTask);
            }
        } // 表示 当前流程实例中,存在已审核过的审核人,自动审核
        else if (AutoProcessType.AUTO_APPROVED.getCode().equals(autoApprovalRule)){
            // 相同表示 已存在审核人了
            if (assigneeList.contains(userId)){
                msg = nickname + "通过";
                variables.put(ProcessConstants.CURRENT_ASSIGNEE,userId);
                assigneeList.add(userIdStr);
                variables.put(ProcessConstants.ASSIGNEE_LIST,assigneeList);
                variables.put(ProcessConstants.FLOWABLE_SKIP_EXPRESSION_ENABLED, true);
                commentTask(userId, taskId, processInstanceId, FlowComment.SKIP.getType(), msg, variables, delegateTask);
            }
        }
    }


  private void commentTask(String userId,String taskId,String processInId,String commentType,String message,  Map<String, Object> variables ,DelegateTask delegateTask){
        identityService.setAuthenticatedUserId(userId);
        taskService.addComment(taskId, processInId, commentType, message);
        logger.info("已完成任务:{}",delegateTask.getName());
        taskService.complete(taskId, variables);
    }

主要的实现方式,通过设置流程变量的方式,在流程发起的时候,去判断当前登录用户与任务节点受理用户的id是否一致,如果一致就自动审核即可,对于上一节点和当前节点审核人相同自动审核的,在用户审核时,添加流程变量,那么这个流程实例就存储了当前的审核人信息,在下一个任务时,判断以下是否一致即可。就不写那么详细了。

posted @   自学Java笔记本  阅读(1235)  评论(22编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示