springboot 下 activiti 7会签配置与实现
流程图配置

会签实现须在 userTask 节点下的 multi instance 中配置 collection 及 completion condition;
- collection 会签人员列表;
- element variable 当前会签变量名称,类似循环中的 item;
- completion condition: 完成条件。
${taskExecutionServiceImpl.findProcessUsers(‘applicant’)} : spring 代理下的 activiti 项目可使用
bean 下配置方法。
${countersignComponent.isComplete(taskId)} 会签实现方法,省略监听类。括号中的字符加单引号就是传递字符串,不加引号就是取当前任务中的变量。

会签配置图中的 user 变量需在此处使用。
实现代码
会签实现代码
@Component
@RequiredArgsConstructor
public class CountersignComponent {private final TaskService taskService;public boolean isComplete(String taskId) {// 1、参数验证if(StringUtils.isAnyEmpty(taskId)){return false;}// 2、获取当前任务节点参数及会签判断后重新设置// 获取流程参数 var,会签人员完成自己的审批任务时会添加流程参数 var,2 为拒绝,1 为同意String variable = BeanUtil.nullOrUndefinedToEmptyStr(taskService.getVariableLocal(taskId, ActivitiCommonConstant.VAR.getValue()));// 当值为 2 证明已有人拒绝,返回 trueif(DefaultConstant.TWO_CODE.getKey().equals(variable)){//会签结束,设置参数 execType 为 4 进行下一步操作。taskService.setVariableLocal(taskId, ActivitiCommonConstant.EXEC_TYPE.getValue(), DefaultConstant.FIVE_CODE.getKey());return true;}// 当值为 1,判断会签是否结束Integer complete = (Integer) taskService.getVariable(taskId, ActivitiCommonConstant.NR_OF_COMPLETED_INSTANCES.getValue());if(complete == 0){// 会签未结束,后续处理}return false;}}
用户动态获取代码
@Overridepublic List<String> findProcessUsers(String code) {// 1、参数验证if(StringUtils.isEmpty(code)){throw new BusinessException(ActivitiConstant.PROCESS_USER_NULL);}// 2、查询对应流程人员(具体取人逻辑,根据个人业务变更)ProcessParameterQuery processParameterQuery = new ProcessParameterQuery();processParameterQuery.setCode(code);GostopResponseVo<ProcessParameterVo> processParameter = dev.findProcessParameter(processParameterQuery);ProcessParameterVo processParameterVo = processParameter.getResult();if(Objects.isNull(processParameterVo)){throw new BusinessException(ActivitiConstant.PROCESS_USER_NULL);}List<HospitalUserVo> userInfos = processParameterVo.getUserInfos();if(CollectionUtils.isEmpty(userInfos)){throw new BusinessException(ActivitiConstant.PROCESS_USER_NULL);}return userInfos.stream().map(HospitalUserVo::getId).distinct().collect(Collectors.toList());}
开启流程
@Overridepublic String startProcess(CommonTaskParamVo param) {// 1、参数验证if(Objects.isNull(param) || StringUtils.isAnyEmpty(param.getProcessKey())){throw new BusinessException(ActivitiConstant.EXEC_ERROR_PARAMS_NULL);}// 2、启动流程定义,返回流程实例ProcessInstance pi;try {CustomParamVo customParamVo = param.getCustomParamVo();String paramJson = JSONObject.toJSONString(customParamVo);Map paramMap = JSONObject.parseObject(paramJson, Map.class);pi = runtimeService.startProcessInstanceByKey(param.getProcessKey(), paramMap);} catch (Exception e) {log.error(e.getMessage());throw new BusinessException(ActivitiConstant.PROCESS_NOT_DEPLOYED);}return pi.getId();}
任务执行
@Overridepublic String complete(CommonTaskParamVo param) {// 1、参数验证if(Objects.isNull(param) || StringUtils.isAnyEmpty(param.getProcessId(), param.getUserId())){throw new BusinessException(ActivitiConstant.EXEC_ERROR_PARAMS_NULL);}// 2、查询当前人任务信息String userId = param.getUserId();//与正在执行的任务管理相关的ServiceTask task = taskService.createTaskQuery()//指定个人任务查询,指定办理人.taskCandidateUser(userId)//使用流程实例ID查询.processInstanceId(param.getProcessId())//排序.orderByTaskCreateTime().asc()//返回列表.singleResult();if (Objects.isNull(task)) {throw new BusinessException(ActivitiConstant.TASK_NULL_ERROR);}task.setDescription(param.getDescription());task.setAssignee(userId);taskService.saveTask(task);// 2.1 设置执行人信息HospitalUserCacheVo userInfo = activitComponent.getUserInfo();CustomParamVo customParamVo = param.getCustomParamVo();customParamVo.setExecUserId(userInfo.getId());customParamVo.setExecUserName(userInfo.getDepartmentName());customParamVo.setExecTime(DateUtil.date2String(LocalDateTime.now()));customParamVo.setTaskId(task.getId());// 2.2 将自定义参数转为 mapString paramJson = JSONObject.toJSONString(customParamVo);Map paramMap = JSONObject.parseObject(paramJson, Map.class);taskService.setVariablesLocal(task.getId(), paramMap);// 3、执行当前节点信息taskService.complete(task.getId());return task.getId();}
参数接收对象
@Data
public class CommonTaskParamVo {/*** 用户 ID*/private String userId;/**** 流程图定义 KEY*/private String processKey;/*** 流程 ID*/private String processId;/*** 描述*/private String description;/*** 自定义参数类*/private CustomParamVo customParamVo;}
@Data
public class CustomParamVo {/*** 操作类型 (1 同意, 2 回退, 3 驳回, 4 提交 5 删除)*/private String execType;/*** 节点类型 (1 申请节点 2 审批节点)*/private String nodeType;/*** 预留参数*/private String var;/*** 执行人 ID*/private String execUserId;/*** 执行人名称*/private String execUserName;/*** 执行时间*/private String execTime;/*** 任务 ID*/private String taskId;}
使用上述参数类及流程配置后,查询任务流水就变得非常简单。
流水查询
@Overridepublic List<FlowDataVo> flowQueryProcess(FlowQuery param) {// 1、参数验证if(Objects.isNull(param) || StringUtils.isAnyEmpty(param.getProcessId())){return new ArrayList<>();}// 2、查询任务执行节点信息HistoricTaskInstanceQuery historicTaskInstanceQuery = historyService.createHistoricTaskInstanceQuery();List<HistoricTaskInstance> taskInfoArr = historicTaskInstanceQuery.processInstanceId(param.getProcessId()).orderByTaskCreateTime().asc().list();if(CollectionUtils.isEmpty(taskInfoArr)){return new ArrayList<>();}// 3、查询任务执行参数信息HistoricVariableInstanceQuery historicVariableInstanceQuery = historyService.createHistoricVariableInstanceQuery();List<HistoricVariableInstance> variableInstanceList = historicVariableInstanceQuery.processInstanceId(param.getProcessId()).list();// 4、构建返回信息对象List<FlowDataVo> resultArr = taskInfoArr.stream().map(taskInfo -> {FlowDataVo flowDataVo = new FlowDataVo();flowDataVo.setNodeName(taskInfo.getName());flowDataVo.setDescription(taskInfo.getDescription());List<HistoricVariableInstance> variableArr = variableInstanceList.stream().filter(e -> taskInfo.getId().equals(e.getTaskId())).collect(Collectors.toList());if (CollectionUtils.isEmpty(variableArr)) {flowDataVo.setStatus(DefaultConstant.ONE_CODE.getKey());return flowDataVo;}JSONObject flowDataJson = (JSONObject) JSONObject.toJSON(flowDataVo);variableArr.stream().forEach(var -> {String variableName = var.getVariableName();String value = BeanUtil.nullOrUndefinedToEmptyStr(var.getValue());flowDataJson.put(variableName, value);});String flowDataJsonString = flowDataJson.toJSONString();FlowDataVo afterFlowData = JSONObject.parseObject(flowDataJsonString, FlowDataVo.class);afterFlowData.setStatus(DefaultConstant.TWO_CODE.getKey());return afterFlowData;}).collect(Collectors.toList());return resultArr;}
流水查询使用 bean 对象
@Data
public class FlowQuery {/*** 流程 ID*/private String processId;/*** 用户 ID*/private String userId;
}
@Data
public class FlowDataVo {/*** 操作类型 (1 同意, 2 回退, 3 驳回, 4 提交 5 删除)*/private String execType;/*** 节点类型 (1 申请节点 2 审批节点)*/private String nodeType;/*** 预留参数*/private String var;/*** 节点名称*/private String nodeName;/*** 执行状态 1 未执行 2 已执行*/private String status;/*** 执行人 ID*/private String execUserId;/*** 执行人名称*/private String execUserName;/*** 执行时间*/private String execTime;/**** 描述*/private String description;}
相关文章:
springboot 下 activiti 7会签配置与实现
流程图配置 会签实现须在 userTask 节点下的 multi instance 中配置 collection 及 completion condition; collection 会签人员列表;element variable 当前会签变量名称,类似循环中的 item;completion condition: 完成条件。 ${taskExecutionServiceIm…...
RK3399平台开发系列讲解(内核调试篇)spidev_test工具使用
🚀返回专栏总目录 文章目录 一、环境二、执行测试三、回环测试四、字节发送测试五、32位数据发送测试沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 在 Linux 系统上,“spidev_test” 是一个用于测试和配置 SPI(Serial Peripheral Interface)设备的命令行工具。…...
点云从入门到精通技术详解100篇-自适应点云局部邻域特征的特征提取与配准(续)
目录 3.4 深度相机误差建模 3.5 实验结果及分析 3.5.1 TOF 相机平面畸变校正 3.5.2 TOF 相机深度误差校正...
VBA技术资料MF52:VBA_在Excel中突出显示前 10 个值
【分享成果,随喜正能量】一言之善,重于千金。善良不分大小,有时候你以为的一句话,小小的举手之劳,也可能就是别人的救赎!不要吝啬你的善良,因为你永远不知道那小小的善良能给多少人带来光明。。…...
leetcode做题笔记134. 加油站
在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。 你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。 给定两个整数数组 gas 和 cost &…...
Allegro166版本如何在颜色管理器中实时显示层面操作指导
Allegro166版本如何在颜色管理器中实时显示层面操作指导 在用Allegro166进行PCB设计的时候,需要在颜色管理器中频繁的开关层面。但是166不像172一样在颜色管理器中可以实时的开关层面,如下图 需要打开Board Geometry/Soldermask_top层,首先需要勾选这个层面,再点击Apply即…...
纷享销客入选中国信通院《高质量数字化转型产品及服务全景图》
近期,在中国信息通信研究院主办的“2023数字生态发展大会”暨中国信通院“铸基计划”年中上,重磅发布了《高质量数字化转型产品及服务全景图(2023)》,纷享销客凭借先进的技术能力和十余年客户业务场景应用理解…...
C高级 DAY4
一、分支语句 case ...in语句 shell中的switch语句 case $变量名 in常量1)语句;; ------->类似于C中break的作用,;;除了最后一条分之外,都不能省略常量2)语句;; 常量n)语句;;*) ------->类似于C中default,但…...
C高级day4
作业 实现一个对数组求和的函数,数组通过实参传递给函数 写一个函数,输出当前用户的uid和gid,并使用变量接收结果 思维导图...
Java8-17 --- idea2022
目录 一、idea官网 二、使用idea编写hello world 三、查看工程中的JDK配置信息 四、详细设置 4.1、显示工具栏 4.2、默认启动项目配置 4.3、取消自动更新 4.4、选择整体主体与背景图 4.5、设置编辑器主题样式 4.5.1、编辑器主题 4.5.2、字体大小 4.5.3、修改注…...
Mybatis---增删改查
目录 一、添加用户 (1)持久层接口方法 (2)映射文件 (3)测试方法 二、修改用户 (1)持久层接口方法 (2)映射文件 (3)测试方法 …...
开机性能-如何抓取开机systrace
一、理论 1.背景 抓取开机 trace 需要使用 userdebug 版本,而我们测试开机性能问题时都要求使用 user 版本,否则会有性能损耗问题。因此想要在抓取开机性能trace 时,需要在 user 版本上打开 atrace 功能之后才能抓取 trace,默认 …...
VBA技术资料MF54:VBA_EXCEL实时获取鼠标位置
【分享成果,随喜正能量】若人散乱心,乃至以一花,供养于画像,渐见无数佛。所以发一幅释迦牟尼佛像,与同修善友一起每日在微博上供养,只要有供养之心,便可积累功德。以此回向,愿求者如…...
模电课程设计
主要内容跟本科实验关系很大,可以用来借鉴。 包含文件有:实验报告、Multisim仿真文件,资料很全,有问题可以私信 目录 1、模电课设:用Multisim简单了解二极管 2、模电课设:用Multisim简析三极管与场效应…...
【2023研电赛】兆易创新命题三等奖: 低成本单母线电流永磁同步无感驱动器
本文为2023年第十八届中国研究生电子设计竞赛兆易创新企业命题三等奖以及决赛最佳论文奖分享,参加极术社区的【有奖活动】分享2023研电赛作品扩大影响力,更有丰富电子礼品等你来领!,分享2023研电赛作品扩大影响力,更有…...
原生Js 提取视频中的音频
Js提取视频中的音频 将视频中的音频轨道分离出来,生成 wav 文件播放或下载( Vue3 setup ) 代码实现 template <button><label for"file" id"filename">选择视频文件</label><input type"fi…...
设计模式-备忘录模式(Memento Pattern)
文章目录 前言一、备忘录模式的概念二、备忘录模式的实现三、备忘录优缺点优点:缺点:总结 前言 备忘录模式(Memento Pattern)是一种行为型设计模式,它用于捕获和存储对象的内部状态,以便在以后可以恢复到先…...
PHP对接阿里云虚拟号的实现(号码隐私保护)
fastadmin 封装框架 实现功能:AXN隐私号绑定、解绑; 场景:为店铺手机号开通虚拟号,用户联系店铺展示虚拟号码; 官方开放文档地址:https://help.aliyun.com/document_detail/59655.html?spma2c4g.111742…...
刷新单年发射纪录:SpaceX成功发射62次猎鹰9号火箭
SpaceX一直都致力于推进航天领域的发展。近日,该公司的猎鹰9号火箭再次刷新了单年发射纪录,目前已经成功发射了62次。除此之外,今年SpaceX还发射了一枚猎鹰火箭和一枚巨型火箭。马斯克表示,他的目标是实现每月10次猎鹰飞行&#x…...
项目打包docker镜像 | 上传nexus | jenkins一键构建
文章目录 前言准备实操1、打开docker的远程访问2、编写dockerfile文件3、指定nexus环境4、配置jenkins5、使用jenkins构建 总结 前言 Docker部署项目是指使用Docker容器化技术将应用程序及其依赖项打包成一个独立的、可移植的运行环境,并在各种操作系统和平台上进行…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...
SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题
分区配置 (ptab.json) img 属性介绍: img 属性指定分区存放的 image 名称,指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件,则以 proj_name:binary_name 格式指定文件名, proj_name 为工程 名&…...
【Linux】自动化构建-Make/Makefile
前言 上文我们讲到了Linux中的编译器gcc/g 【Linux】编译器gcc/g及其库的详细介绍-CSDN博客 本来我们将一个对于编译来说很重要的工具:make/makfile 1.背景 在一个工程中源文件不计其数,其按类型、功能、模块分别放在若干个目录中,mak…...
GraphQL 实战篇:Apollo Client 配置与缓存
GraphQL 实战篇:Apollo Client 配置与缓存 上一篇:GraphQL 入门篇:基础查询语法 依旧和上一篇的笔记一样,主实操,没啥过多的细节讲解,代码具体在: https://github.com/GoldenaArcher/graphql…...
C++_哈希表
本篇文章是对C学习的哈希表部分的学习分享 相信一定会对你有所帮助~ 那咱们废话不多说,直接开始吧! 一、基础概念 1. 哈希核心思想: 哈希函数的作用:通过此函数建立一个Key与存储位置之间的映射关系。理想目标:实现…...
Linux 下 DMA 内存映射浅析
序 系统 I/O 设备驱动程序通常调用其特定子系统的接口为 DMA 分配内存,但最终会调到 DMA 子系统的dma_alloc_coherent()/dma_alloc_attrs() 等接口。 关于 dma_alloc_coherent 接口详细的代码讲解、调用流程,可以参考这篇文章,我觉得写的非常…...
