activiti7。1。0。M6(七)获取流程审批图片,高亮显示
/** * 根据流程实例Id,获取实时流程图片 * * @param processInstanceId * @param * @param useCustomColor true:用自定义的颜色(完成节点绿色,当前节点红色),default:用默认的颜色(红色) * @return */ public void getFlowImgByInstanceId(String processInstanceId, HttpServletResponse response, boolean useCustomColor) { try { if (org.springframework.util.StringUtils.isEmpty(processInstanceId)) { log.error("processInstanceId is null"); return; } // 获取历史流程实例 HistoricProcessInstance historicProcessInstance = historyService .createHistoricProcessInstanceQuery() .processInstanceId(processInstanceId).singleResult(); // 获取流程中已经执行的节点,按照执行先后顺序排序 List historicActivityInstances = historyService .createHistoricActivityInstanceQuery() .processInstanceId(processInstanceId) .orderByHistoricActivityInstanceId() .desc().list(); // 高亮已经执行流程节点ID集合 List highLightedActivitiIds = new ArrayList<>(); int index = 1; for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) { if (useCustomColor) { // 用自定义颜色 if (index == historicActivityInstances.size()) { // 当前节点 highLightedActivitiIds.add(historicActivityInstance.getActivityId() + "#"); } else { // 已完成节点 highLightedActivitiIds.add(historicActivityInstance.getActivityId()); } } else { // 用默认颜色 highLightedActivitiIds.add(historicActivityInstance.getActivityId()); } index++; } ProcessDiagramGenerator processDiagramGenerator = null; if (useCustomColor) { // 使用自定义的程序图片生成器 processDiagramGenerator = new CustomProcessDiagramGenerator(); } else { // 使用默认的程序图片生成器 processDiagramGenerator = new DefaultProcessDiagramGenerator(); } BpmnModel bpmnModel = repositoryService .getBpmnModel(historicProcessInstance.getProcessDefinitionId()); // 高亮流程已发生流转的线id集合 List highLightedFlowIds = getHighLightedFlows(bpmnModel, historicActivityInstances); // 使用默认配置获得流程图表生成器,并生成追踪图片字符流 InputStream imageStream = processDiagramGenerator.generateDiagram(bpmnModel, highLightedActivitiIds, highLightedFlowIds, "宋体", "宋体", "宋体"); // 输出图片内容 Integer byteSize = 1024; byte[] b = new byte[byteSize]; int len; while ((len = imageStream.read(b, 0, byteSize)) != -1) { response.getOutputStream().write(b, 0, len); } } catch (Exception e) { log.error("processInstanceId" + processInstanceId + "生成流程图失败,原因:" + e.getMessage(), e); } }/** * 获取已经流转的线 * * @param bpmnModel * @param historicActivityInstances * @return */ private static List getHighLightedFlows(BpmnModel bpmnModel, List historicActivityInstances) { // 流转线ID集合 List flowIdList = new ArrayList(); // 全部活动实例 List historicFlowNodeList = new LinkedList(); // 已完成的历史活动节点 List finishedActivityInstanceList = new LinkedList(); for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) { historicFlowNodeList.add((FlowNode) bpmnModel.getMainProcess().getFlowElement(historicActivityInstance.getActivityId(), true)); if (historicActivityInstance.getEndTime() != null) { finishedActivityInstanceList.add(historicActivityInstance); } } // 遍历已完成的活动实例,从每个实例的outgoingFlows中找到已执行的 FlowNode currentFlowNode = null; for (HistoricActivityInstance currentActivityInstance : finishedActivityInstanceList) { // 获得当前活动对应的节点信息及outgoingFlows信息 currentFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(currentActivityInstance.getActivityId(), true); List sequenceFlowList = currentFlowNode.getOutgoingFlows(); /** * 遍历outgoingFlows并找到已已流转的 * 满足如下条件认为已已流转: * 1.当前节点是并行网关或包含网关,则通过outgoingFlows能够在历史活动中找到的全部节点均为已流转 * 2.当前节点是以上两种类型之外的,通过outgoingFlows查找到的时间最近的流转节点视为有效流转 */ FlowNode targetFlowNode = null; if ("parallelGateway".equals(currentActivityInstance.getActivityType()) || "inclusiveGateway".equals(currentActivityInstance.getActivityType())) { // 遍历历史活动节点,找到匹配Flow目标节点的 for (SequenceFlow sequenceFlow : sequenceFlowList) { targetFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(sequenceFlow.getTargetRef(), true); if (historicFlowNodeList.contains(targetFlowNode) && (sequenceFlowList.size() > 1 || Objects.nonNull(currentActivityInstance.getEndTime()))) { flowIdList.add(sequenceFlow.getId()); } } } else { // 遍历历史活动节点,找到匹配Flow目标节点的 for (SequenceFlow sequenceFlow : sequenceFlowList) { for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) { if (historicActivityInstance.getActivityId().equals(sequenceFlow.getTargetRef())) { if(Objects.nonNull(currentActivityInstance.getEndTime()) && Objects.nonNull(historicActivityInstance.getStartTime())){ String endTime = DateUtil.format(currentActivityInstance.getEndTime(), "yyyy-MM-dd HH:mm:ss"); String startTime = DateUtil.format(historicActivityInstance.getStartTime(), "yyyy-MM-dd HH:mm:ss"); if(startTime.equals(endTime)){ flowIdList.add(sequenceFlow.getId()); } } } } } } } return flowIdList; }
显示效果如下:
10年时间,我国数字音乐市场发生了这么多惊人变化生活在中国,每天被潜移默化,各种新潮东西影响着的我们,其实很难发现我们现在生活的进步与休闲。只要回首展望,不需要20年,只要看看10年前,都能察觉到我们的生活原来变化这么多。10年
从小团队到大公司,三位中国开发者的创业故事苹果今天公布一组数据大中华区的开发者社区目前已拥有超过440万注册开发者,与两年前相比增长了76。自2008年AppStore推出至今,iOSapp经济已成为飞速发展的经济部门之一
不再是科幻!联合国通报首例机器人自主追杀人类事件人类被机器人追杀一直是科幻电影中常有的桥段,但是最近联合国的一份报告显示,机器人追杀人类不再是可科幻了,而是活活生生的现实。联合国的一份报告指出,去年装有爆炸装置的无人机可能已经追
鸿蒙系统都出了,为什么荣耀不第一时间用?这是任老爷子布的另外一个大局,要把荣耀放出去占领市场,现在占市场比用鸿蒙重要,这样才能构建鸿蒙系统生态。任老爷子一向是谋定而后动,这么大的动作,绝不会虎头蛇尾,无疾而终。一帮揣着明
手机厂商影像大战,很有必要几天之前,StudioBinder上线了一则解析斯巴达300勇士电影里,温泉关战役的镜头变焦和剪辑手法。这个如芭蕾舞般舒展而自然的镜头,在影片中一出现就把气氛推向高潮,配合BGM,
马斯克短暂将推特头像换成无聊猿,暗讽NFT其实可替代记者司林威5月4日,特斯拉首席执行官埃隆马斯克又在推特上玩了以来。当日,他将自己的推特头像换成了一个无聊猿系列的头像集合,包含101只无聊猿头像,中间是BYAC编号5809。同时,
谷歌PixelNotepad可折叠手机外屏或将采用5。8英寸DoNews5月5日消息(李文朋)据业内人士RossYoung称,谷歌可折叠手机Pixel将会采用较小的外屏,其内部显示屏大小将与GalaxyZFold4大小相似。这款手机将会被命
看热闹,卷了又卷,手机拍照的第五波内卷又来了关注我,不错过每一篇好文。2000年9月,夏普发布了世界第一款带摄像头的手机夏普JSH40。至今,手机拍照已经发展了20多年,也竞争了20多年,而且竞争的态势还越发猛烈了。对于用户
北京自动驾驶示范区今年扩区提质走出家门,打一辆无人驾驶出租车去上班午饭时间到了,没有外卖小哥,热乎的餐食也能送来网购下单,商品搭乘无人配送车准时送达科技感十足的智慧生活在北京市高级别自动驾驶示范区已经实现。邓伟
做了智能门锁中的iPhone在ORVIBOT1众筹前,ORVIBO的CEO就曾对媒体表示过对这个市场的兴趣真正的智能门锁除了安全,应该有强大的计算能力以及便捷交互和丰富应用就像当年乔布斯用iPhone终结了滑
K40降价到2000以下,究竟值不值得买?一代神机K40全系列销量超过1千万,是2021最畅销的手机之一,降价后性价比进一步提升。作为去年首发用户谈谈一般测评不会告诉你的使用感受k40优点硬件优秀,价格便宜。由于疫情导致芯
苹果ios15。4beta新增音乐TV同播共享按钮等今日苹果推送了iOS15。4Beta系统,为iPhone带来了多项新功能,正式支持戴口罩进行FaceID面部解锁。网友发现,新版中文版系统为AppleMusicTV应用带来了同播共
视频号出走张小龙文新熵,作者嘉荣,编辑伊页1997年,BAT还可能只是软盘里的一行代码。那一年,中国人口数量为12。36亿,而能上网的计算机仅29。9万台,合下来每四千多人才拥有一台。也是在那一年
新能源汽车养护小知识随着越来越多的人选择电动汽车,关于电动汽车的保养问题也越来越多的受到大家的关注,下面就为大家科普一下有关电动汽车的保养知识。一电池养护1正确把握电池的充电时间和频次。新能源汽车怎么
微博拟上线一键隔离网络暴力模式金融界1月28日消息据微博管理员,微博拟上线一键隔离网络暴力模式,加强人身攻击不友善言论识别处置,优化新闻当事人保护,确保用户安全。如大家在平台上发现类似违规行为,欢迎通过前台投诉
三大运营商降无可降,提速降费是不是要到头了?提起移动联通电信这三大运营商,相信很多人对于它们都没有什么好印象,毕竟很多人每个月的花费和网费都是非常高的,不过大家有没有考虑过一个问题,那就是我国的通行费用真的高吗?2022年,
短视频神曲持续霸榜,华语乐坛回到彩铃时代?作者黄启哲岁末年初,各类音乐榜单陆续推出。打开热歌榜,上面的歌手歌名大多令人一头雾水。可点进去一听,网友感慨竟然都有印象,甚至还能哼唱出个别歌曲的副歌旋律。这些音乐基本走红于短视频
提问标题北汽新能源电车召回后被限制的充电速度严重影响使用,315居然管不了提问标题北汽新能源电车召回后被限制的充电速度严重影响使用,315居然管不了提问时间20220127144951提问内容2018年购入北汽新能源EX360车型此车正常的充电情况是夏天
比亚迪半导体过会今年IPO过关第26家中金公司过2单来源中国经济网中国经济网北京1月28日讯创业板上市委员会2022年第5次审议会议于昨日召开,审议结果显示,比亚迪半导体股份有限公司(简称比亚迪半导体)首发符合发行条件上市条件和信息
换电的终局作者李大鹏出品电动公会2007年,一家名为BetterPlace的电动汽车换电公司在以色列成立。一年后,BetterPlace斥巨资打造的首座换电站落地,并与雷诺公司签订了提供10
小米首发2亿像素镜头?联想再次截胡三星在去年的时候就发布了2亿像素的ISOCELLHP1摄像头传感器,但目前为止市场上仍然没有一款手机采用,早先的传闻是该镜头将会由小米的旗舰新机首发搭载,不过据最新的消息显示,小米
传跨境支付PingPong正考虑港股上市,估值约50亿美元据彭博社报道,中国金融科技初创公司乒乓智能技术有限公司(PingPong)正在考虑在香港IPO,筹资多达10亿美元。报导引述消息人士称,PingPong正与顾问商讨上市事宜,最快可