首页 > 其他分享 >Flowable自动审核、相邻节点审核、已存在审核人审核

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

时间:2024-08-09 16:08:03浏览次数:4  
标签:String delegateTask Flowable variables userId ProcessConstants 审核 节点

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是否一致,如果一致就自动审核即可,对于上一节点和当前节点审核人相同自动审核的,在用户审核时,添加流程变量,那么这个流程实例就存储了当前的审核人信息,在下一个任务时,判断以下是否一致即可。就不写那么详细了。

标签:String,delegateTask,Flowable,variables,userId,ProcessConstants,审核,节点
From: https://www.cnblogs.com/zgf123/p/18350897

相关文章

  • ComfyUI插件:ComfyUI_Noise节点
    前言:学习ComfyUI是一场持久战,ComfyUI_Noise是对ComfyUI中的噪声进行控制的一个插件库,该库可以完成图像噪声的反推,并通过采样再以几乎无损的方式返回原图,通过该库的使用可以更好的帮助图像恢复原始的相貌,非常适合在生成视频领域用作人物转绘使用。祝大家学习顺利,早日成为ComfyUI的......
  • ToDesk全球节点绑定设备、不限设备怎么选择?有什么区别
    最近跨境电商和远程办公成为许多企业和打工人的工作选择,因此使用远程控制软件进行线上办公的需求也日益增多。小社长最近发现ToDesk远程控制软件有个全球节点功能,对跨境线上远控办公非常好用,能稳定远控国外的设备,远控的各种功能都挺完善的。ToDesk也是小社长的常备远控软件了,能......
  • 在K8S中,flannel可以固定节点IP和Pod的IP地址吗?
    在Kubernetes中,Flannel负责为Pod提供跨节点的网络连接,但它本身并不直接分配Pod的IP地址。Pod的IP地址是由Kubernetes的网络插件分配的,Flannel只是在这个过程中起到辅助作用。然而,Flannel可以配置为使用特定的网络模式,以支持更灵活的IP地址管理。以下是一些与IP地址管理相关的方面......
  • 电力系统——基于10机39节点的电力系统仿真(Matlab)
    目录1引言2 案例仿真 2.1负荷参数 2.2线路、变压器参数2.3发电机参数2.4励磁参数 310机39节点的仿真 3.1建立Simulink模型3.2 MATLAB程序实现 3.3运行结果 3.4结果分析4总结 5Simulink&Matlab实现1引言   目前,随着科学技术的发......
  • Springboot整合Flowable入门-学习笔记
    目录1、定义流程(画图)2、Springboot部署流程3、Springboot删除所有流程4、Springboot根据流程部署ID查询流程定义ID5、Springboot启动(发起)流程6、Springboot查询任务6.1全部任务6.2我的任务(代办任务)7、springboot审批任务1、审批通过2、驳回8、Springboot流程......
  • 每日一题:Leetcode-24 两两交换链表中的节点
    力扣题目解题思路java代码力扣题目:给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。示例1:输入:head=[1,2,3,4]输出:[2,1,4,3]示例2:输入:head=[]输出:[]示例3:输入:head=[1]......
  • 如何进行IATF 16949:2016的内部审核?
    进行IATF16949:2016的内部审核是确保组织质量管理体系符合标准要求并持续改进的重要步骤。以下是进行IATF16949:2016内部审核的一般步骤和流程:1.准备阶段:   -任命内部审核员:选择经过培训和资质认证的内部审核员负责执行内部审核。   -制定审核计划:确定审核的范......
  • 203. 移除链表元素 给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满
    在链表中,每个节点都有一个指向下一个节点的指针。删除一个节点的本质是将前一个节点的指针指向要删除节点的下一个节点,从而跳过要删除的节点。以下是详细解释为什么以及如何这样做:1.**链表的结构**:  一个链表节点包含两个部分:存储的数据和指向下一个节点的指针。  ``......
  • SQLServer 事务复制订阅节点非活跃状态(inactive)错误的处理:Error in replication::subs
    事务复制中订阅节点非活动( inactive)错误在SQLServer的事务复制模型中,会出现“订阅过期”的错误,相关订阅分发代理Job的典型错误如下:"AgentSQLNYC01-Onvoices-PubInvoicesInvoices-SQLNYC01-1353is retryingafteranerror. 211retriesattempted.Seeagentjobhistoryin......
  • etcd单节点部署
    环境:OS:Centos7etcd:etcd-v3.5.15 1.下载地址https://github.com/etcd-io/etcd/releases/tag/v3.5.15直接下载编译好的二进制文件包,下载文件如下:etcd-v3.5.15-linux-amd64.tar.gz2.解压安装[root@host135milvus]#tar-xvfetcd-v3.5.15-linux-amd64.tar.gz[root@host135......