基于jeecg-boot的flowable流程历史记录显示修改

更多nbcio-boot功能请看演示系统

gitee源代码地址

后端代码: https://gitee.com/nbacheng/nbcio-boot

前端代码:https://gitee.com/nbacheng/nbcio-vue.git

在线演示(包括H5) : http://122.227.135.243:9888
 

历史记录增加开始与结束的显示,以方便用户查看。

1、前端修改,代码如下:

<el-card class="box-card" v-if="flowRecordList"><div slot="header" class="clearfix"><span class="el-icon-notebook-1">审批记录</span></div><el-col :span="16" :offset="4"><div class="block"><el-timeline><el-timeline-item v-for="(item,index ) in flowRecordList" :key="index" :icon="setIcon(item.finishTime)":color="setColor(item.finishTime)"><p style="font-weight: 700">{{item.taskName}}</p><el-card v-if="item.activityType === 'startEvent'" class="box-card" shadow="hover">{{ item.assigneeName }} 在 {{ item.createTime }} 发起流程</el-card><el-card v-if="item.activityType === 'userTask'" :body-style="{ padding: '10px' }"><label v-if="item.assigneeName" style="font-weight: normal;margin-right: 30px;">实际办理:{{item.assigneeName}}<el-tag type="info" size="mini">{{item.deptName}}</el-tag></label><label v-if="item.candidate" style="font-weight: normal;margin-right: 30px;">候选办理:{{item.candidate}}</label><label style="font-weight: normal">接收时间: </label><labelstyle="color:#8a909c;font-weight: normal">{{item.createTime}}</label><label v-if="item.finishTime" style="margin-left: 30px;font-weight: normal">办结时间: </label><labelstyle="color:#8a909c;font-weight: normal">{{item.finishTime}}</label><label v-if="item.duration" style="margin-left: 30px;font-weight: normal">耗时: </label><labelstyle="color:#8a909c;font-weight: normal">{{item.duration}}</label><p v-if="item.listFlowCommentDto" v-for="(commentitem,index ) in item.listFlowCommentDto" :key="index"><el-tag type="success" v-if="commentitem.type === '1'"> {{commentitem.comment}}</el-tag><el-form  v-if= "commentitem.type === '1' && fileitem.type === '1'  && item.listcommentFileDto.length>0" v-for="(fileitem,fileindex ) in item.listcommentFileDto" :key="fileindex"><el-form-item label="附件"  prop="listcommentFileDto"><j-upload  v-if="fileitem.type === '1'" v-model="fileitem.fileurl" :disabled = "true"  text="上传的文件" ></j-upload>                 </el-form-item></el-form>  <el-tag type="warning" v-if="commentitem.type === '2'"> {{"退回: "+ commentitem.comment}}</el-tag><el-form v-if= "commentitem.type === '2' && fileitem.type === '2'  && item.listcommentFileDto.length>0" v-for="(fileitem,fileindex ) in item.listcommentFileDto" :key="fileindex"><el-form-item label="附件"  prop="listcommentFileDto"><j-upload v-if="fileitem.type === '2'" v-model="fileitem.fileurl" :disabled = "true"  text="退回上传的文件" ></j-upload> </el-form-item></el-form>  <el-tag type="danger" v-if="commentitem.type === '3'">  {{"驳回: "+commentitem.comment}}</el-tag><el-form v-if= "commentitem.type === '3' && fileitem.type === '3'  && item.listcommentFileDto.length>0" v-for="(fileitem,fileindex ) in item.listcommentFileDto" :key="fileindex"><el-form-item label="附件"  prop="listcommentFileDto"><j-upload v-if="fileitem.type === '3'"  v-model="fileitem.fileurl" :disabled = "true"  text="驳回上传的文件" ></j-upload></el-form-item></el-form>  <el-tag type="success" v-if="commentitem.type === '4'">  {{commentitem.comment}}</el-tag><el-form  v-if= "commentitem.type === '4' && fileitem.type === '4'  && item.listcommentFileDto.length>0" v-for="(fileitem,fileindex ) in item.listcommentFileDto" :key="fileindex"><el-form-item label="附件"  prop="listcommentFileDto"><j-upload  v-if="fileitem.type === '4'" v-model="fileitem.fileurl" :disabled = "true"  text="委派上传的文件" ></j-upload>                 </el-form-item></el-form>  <el-tag type="success" v-if="commentitem.type === '5'">  {{commentitem.comment}}</el-tag>  <el-form v-if= "commentitem.type === '5' && fileitem.type === '5' && item.listcommentFileDto.length>0" v-for="(fileitem,fileindex ) in item.listcommentFileDto" :key="fileindex"><el-form-item label="附件"  prop="listcommentFileDto" ><j-upload v-model="fileitem.fileurl" :disabled = "true"  text="转办上传的文件" ></j-upload></el-form-item></el-form>  <el-tag type="warning" v-if="commentitem.type === '7'"> {{"撤回: "+commentitem.comment}}</el-tag>  <!--撤回信息--><el-tag type="warning" v-if="commentitem.type === '6'"> {{commentitem.comment}}</el-tag>  <!--终止信息--><el-tag type="warning" v-if="commentitem.type === '8'"> {{commentitem.comment}}</el-tag>  <!--跳过信息--><el-tag type="success" v-if="commentitem.type === '9'"> {{commentitem.comment}}</el-tag>  <!--前加签--><el-tag type="success" v-if="commentitem.type === '10'"> {{commentitem.comment}}</el-tag>  <!--后加签--><el-tag type="success" v-if="commentitem.type === '11'"> {{commentitem.comment}}</el-tag>  <!--多实例加签--><el-tag type="success" v-if="commentitem.type === '12'"> {{commentitem.comment}}</el-tag>  <!--跳转信息--></p></el-card><el-card v-if="item.activityType === 'endEvent'" class="box-card" shadow="hover">{{ item.createTime }} 流程结束</el-card></el-timeline-item></el-timeline></div></el-col></el-card>

2、后端修改

/*** 流程历史流转记录* add by nbacheng* @param  procInsId 流程实例Id, 流程发布id, 任务id* @return*/@Overridepublic Result flowRecord(String procInsId,String deployId, String businessKey, String taskId, String category) {Map<String, Object> map = new HashMap<String, Object>();if (StringUtils.isNotBlank(procInsId)) {List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery().processInstanceId(procInsId).activityTypes(CollUtil.newHashSet(BpmnXMLConstants.ELEMENT_EVENT_START, BpmnXMLConstants.ELEMENT_EVENT_END, BpmnXMLConstants.ELEMENT_TASK_USER)).orderByHistoricActivityInstanceStartTime().desc().orderByHistoricActivityInstanceEndTime().desc().list();List<FlowTaskDto> hisFlowList = new ArrayList<>();// 获取流程实例HistoricProcessInstance historicProcIns = historyService.createHistoricProcessInstanceQuery().processInstanceId(procInsId).includeProcessVariables().singleResult();String startUserId = historicProcIns.getStartUserId();for (HistoricActivityInstance histIns : list) {FlowTaskDto flowTask = new FlowTaskDto();if (BpmnXMLConstants.ELEMENT_EVENT_START.equals(histIns.getActivityType())) {SysUser startUser = iFlowThirdService.getUserByUsername(startUserId);flowTask.setAssigneeId(startUser.getUsername());flowTask.setAssigneeName(startUser.getRealname());flowTask.setCreateTime(histIns.getStartTime());flowTask.setFinishTime(histIns.getEndTime());flowTask.setActivityType(histIns.getActivityType());}if (BpmnXMLConstants.ELEMENT_EVENT_END.equals(histIns.getActivityType())) {flowTask.setCreateTime(histIns.getStartTime());flowTask.setFinishTime(histIns.getEndTime());flowTask.setActivityType(histIns.getActivityType());}if (StringUtils.isNotBlank(histIns.getTaskId())) {flowTask.setTaskId(histIns.getTaskId());flowTask.setTaskName(histIns.getActivityName());flowTask.setCreateTime(histIns.getStartTime());flowTask.setFinishTime(histIns.getEndTime());flowTask.setActivityType(histIns.getActivityType());if (StringUtils.isNotBlank(histIns.getAssignee())) {SysUser sysUser = iFlowThirdService.getUserByUsername(histIns.getAssignee());if(sysUser !=null) {flowTask.setAssigneeId(sysUser.getUsername());flowTask.setAssigneeName(sysUser.getRealname());List<String> departNamesByUsername = iFlowThirdService.getDepartNamesByUsername(histIns.getAssignee());flowTask.setDeptName(CollUtil.join(departNamesByUsername,","));}}// 展示审批人员List<HistoricIdentityLink> linksForTask = historyService.getHistoricIdentityLinksForTask(histIns.getTaskId());StringBuilder stringBuilder = new StringBuilder();for (HistoricIdentityLink identityLink : linksForTask) {if ("candidate".equals(identityLink.getType())) {if (StringUtils.isNotBlank(identityLink.getUserId())) {SysUser sysUser = iFlowThirdService.getUserByUsername(identityLink.getUserId());stringBuilder.append(sysUser.getRealname()).append(",");}if (StringUtils.isNotBlank(identityLink.getGroupId())) {List<SysRole> allRole = iFlowThirdService.getAllRole();SysRole sysRole = allRole.stream().filter(o -> StringUtils.equals(identityLink.getGroupId(), o.getId())).findAny().orElse(new SysRole());stringBuilder.append(sysRole.getRoleName()).append(",");}}}if (StringUtils.isNotBlank(stringBuilder)) {flowTask.setCandidate(stringBuilder.substring(0, stringBuilder.length() - 1));}flowTask.setDuration(histIns.getDurationInMillis() == null || histIns.getDurationInMillis() == 0 ? null : getDate(histIns.getDurationInMillis()));// 获取意见评论内容List<Comment> commentList = taskService.getProcessInstanceComments(histIns.getProcessInstanceId());List<FlowCommentDto> listFlowCommentDto = new ArrayList<FlowCommentDto>();commentList.forEach(comment -> {if (histIns.getTaskId().equals(comment.getTaskId())) {//flowTask.setComment(FlowCommentDto.builder().type(comment.getType()).comment(comment.getFullMessage()).build());//FlowCommentDto flowcommentDto = FlowCommentDto.builder().type(comment.getType()).comment(comment.getFullMessage()).build();FlowCommentDto flowcommentDto = new FlowCommentDto();flowcommentDto.setType(comment.getType());flowcommentDto.setComment(comment.getFullMessage());listFlowCommentDto.add(flowcommentDto);}});flowTask.setListFlowCommentDto(listFlowCommentDto);//获取附件List<Attachment> commentfileList = taskService.getProcessInstanceAttachments(histIns.getProcessInstanceId());List<FlowCommentFileDto> listcommentFileDto =  new ArrayList<FlowCommentFileDto>();commentfileList.forEach(commentfile -> {if (histIns.getTaskId().equals(commentfile.getTaskId())) {FlowCommentFileDto flowcommenfiletDto = new FlowCommentFileDto();flowcommenfiletDto.setType(commentfile.getType());flowcommenfiletDto.setFileurl(commentfile.getUrl());listcommentFileDto.add(flowcommenfiletDto);}});flowTask.setListcommentFileDto(listcommentFileDto);// 获取历史任务节点表单数据值List<HistoricVariableInstance> listHistoricVariableInstance = historyService.createHistoricVariableInstanceQuery().processInstanceId(procInsId).taskId(histIns.getTaskId()).list();  Map<String, Object> variables = new HashedMap<String, Object>();Map<String, Object> formconf = new HashedMap<String, Object>();for(HistoricVariableInstance historicVariableInstance:listHistoricVariableInstance) {variables.put(historicVariableInstance.getVariableName(), historicVariableInstance.getValue());}formconf.put("formValue", variables);// 获取历史任务节点表单参数if(Objects.nonNull(histIns.getTaskId())) {HistoricTaskInstance taskIns = historyService.createHistoricTaskInstanceQuery().taskId(histIns.getTaskId()).includeIdentityLinks().includeProcessVariables().includeTaskLocalVariables().finished().singleResult();if (Objects.nonNull(taskIns)) {{String formId = taskIns.getFormKey();SysForm sysForm = sysDeployFormService.selectCurSysDeployForm(formId, deployId, taskIns.getTaskDefinitionKey());if (Objects.nonNull(sysForm)) {formconf.put("config", JSONObject.parseObject(sysForm.getFormContent()).get("config"));formconf.put("list", JSONObject.parseObject(sysForm.getFormContent()).get("list"));}}}}    flowTask.setTaskFormValues(formconf);}hisFlowList.add(flowTask);}map.put("flowList", hisFlowList);}if (Objects.nonNull(category) && category.equalsIgnoreCase("online") && StringUtils.isNotBlank(businessKey)) {// 获取online数据表单配置LambdaQueryWrapper<FlowMyOnline> flowMyOnlineLambdaQueryWrapper = new LambdaQueryWrapper<>();flowMyOnlineLambdaQueryWrapper.eq(FlowMyOnline::getDataId, businessKey);//以后这里还要加上onlineIdFlowMyOnline online = flowMyOnlineService.getOne(flowMyOnlineLambdaQueryWrapper);if (Objects.nonNull(online)) {Map<String, Object> onlCgformHeadMap = flowOnlCgformHeadService.getOnlCgformHeadByFormId(online.getOnlineId());map.put("onlineConfig", onlCgformHeadMap.get("formData"));map.put("onlineId", online.getOnlineId());}}else if (Objects.nonNull(category) && StringUtils.isNotBlank(businessKey) && !Objects.equals(businessKey, "null") && (category != "online")) { // 获取初始化自定义表单FlowMyBusiness business = flowMyBusinessService.getByDataId(businessKey);String serviceImplName = business.getServiceImplName();FlowCallBackServiceI flowCallBackService = (FlowCallBackServiceI) SpringContextUtils.getBean(serviceImplName);// 流程处理完后,进行回调业务层if (flowCallBackService!=null){Object businessDataById = flowCallBackService.getBusinessDataById(businessKey);map.put("formData",businessDataById);map.put("routeName", business.getRouteName());}}else {if (StringUtils.isNotBlank(deployId)) {//获取当前节点的初始化表单if(Objects.nonNull(taskId)) {HistoricTaskInstance taskIns = historyService.createHistoricTaskInstanceQuery().taskId(taskId).includeIdentityLinks().includeProcessVariables().includeTaskLocalVariables().singleResult();if (Objects.nonNull(taskIns)) {String formId = taskIns.getFormKey();SysForm sysForm = sysDeployFormService.selectCurSysDeployForm(formId, deployId, taskIns.getTaskDefinitionKey());if (Objects.nonNull(sysForm)) {map.put("taskFormData", JSONObject.parseObject(sysForm.getFormContent()));}}}else {SysForm sysForm = sysDeployFormService.selectSysDeployFormByDeployId(deployId);if (Objects.isNull(sysForm)) {return Result.error("请先配置流程表单");}map.put("formData", JSONObject.parseObject(sysForm.getFormContent()));}}}if(isStartUserNode(taskId)) {map.put("isStartUserNode", true);}return Result.OK(map);}

3、效果图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/75190.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一文搞定接口幂等性架构设计方案

幂等性介绍 现如今很多系统都会基于分布式或微服务思想完成对系统的架构设计。那么在这一个系统中&#xff0c;就会存在若干个微服务&#xff0c;而且服务间也会产生相互通信调用。那么既然产生了服务调用&#xff0c;就必然会存在服务调用延迟或失败的问题。当出现这种问题&a…

系列四、Nginx的常用命令和配置文件

一、常用命令 1.1、查看nginx的版本号 ./nginx -v 1.2、启动nginx cd /usr/local/nginx/sbin./nginx 1.3、停止nginx cd /usr/local/nginx/sbin./nginx -s stop 1.4、重新加载nginx 说明&#xff1a;该命令用于修改配置文件后&#xff0c;在不重启nginx的情况下使配置文…

FPGA通信—千兆网(UDP)软件设计

一、PHY引脚功能描述 引脚功能描述1CLK25 CLK125:内部PLL生成的125MHz参考时钟&#xff0c;如MAC未使用125MHe时钟&#xff0c;则此引脚应保持浮动&#xff0c; 2 4 63 GND 接地3REG OUT开关压器&#xff0c;1.05V输出 5 6 8 9 11 12 14 15 MDI[0] MDI[0]- MDI[1] MDI[1…

学习笔记-BNF、EBNF、ABNF语法格式描述规范

目标是确认一些c/cpp的语法细节&#xff0c;需要看cpp语法定义文件。 考虑从c的语法定义文件开始确认。 考虑实现一个简化的语言定义和编译器&#xff0c;为后续的实际需求做自定义扩展。 参考网页&#xff1a; https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_f…

高可用Kuberbetes部署Prometheus + Grafana

概述 阅读官方文档部署部署Prometheus Grafana GitHub - prometheus-operator/kube-prometheus at release-0.10 环境 步骤 下周官方github仓库 git clone https://github.com/prometheus-operator/kube-prometheus.git git checkout release-0.10 进入工作目录 cd kube…

二、[mysql]之Explain讲解与实战

目录 一、了解Explain1.Explain介绍 二、Explain相关字段1.partitions2.filtered3.SHOW WARNINGS命令 三、Explain比较重要字段1.id2.select_type3.table4.type5.possible_keys6.key7.key_len8.ref9.rows10.Extra 四、索引优化实战&#xff08;遵循原则&#xff09;1.全值匹配2…

python关闭指定进程以excel为例

先说下环境&#xff1a; Excel版本&#xff1a; Python2.7.13和Python3.10.4并存。 2、打开两个excel工作簿 看进程是这样的&#xff1a; 3、用python编程kill进程 # -*- coding: utf-8 -*- import os proc_nameEXCEL.EXE if __name__ __main__:os.system(taskkill /im {} /…

【vue2第十六章】VueRouter 声明式导航(跳转传参)、路由重定向、页面未找到的提示页面404、vue路由模式设置

声明式导航(跳转传参) 在一些特定的需求中&#xff0c;跳转路径时我们是需要携带参数跳转的&#xff0c;比如有一个搜索框&#xff0c;点击搜索的按钮需要跳转到另外一个页面组件&#xff0c;此时需要把用户输入的input框的值也携带到那页面进行发送请求&#xff0c;请求数据。…

python 随机生成emoji表情

问答板块觉得比较有意思的问题 当时搜了些网上的发现基本都不能用&#xff0c;不知道是版本的问题还是咋的就开始自己研究 python随机生成emoji 问题的产生解决官网文档数据类型实现思路实现前提&#xff1a;具体实现&#xff1a; 其他常见用法插入 Emoji 表情&#xff1a;解析…

【ES6】Class中this指向

先上代码&#xff1a; 正常运行的代码&#xff1a; class Logger{printName(name kexuexiong){this.print(hello ${name});}print(text){console.log(text);} }const logger new Logger(); logger.printName("kexueixong xiong");输出&#xff1a; 单独调用函数p…

搭建自己的OCR服务,第二步:PaddleOCR环境安装

PaddleOCR环境安装&#xff0c;遇到了很多问题&#xff0c;根据系统不同问题也不同&#xff0c;不要盲目看别人的教程&#xff0c;有的教程也过时了&#xff0c;根据实际情况自己调整。 我这边目前是使用windows 10系统CPU python 3.7 搭建。 熟悉OCR的人应该知道&#xff0…

合宙Air724UG LuatOS-Air LVGL API控件-标签 (Label)

标签 (Label) 标签是 LVGL 用来显示文字的控件。 示例代码 label lvgl.label_create(lvgl.scr_act(), nil) lvgl.label_set_recolor(label, true) lvgl.label_set_text(label, "#0000ff Re-color# #ff00ff words# #ff0000 of\n# align the lines …

B站:AB test [下]

Focus在&#xff1a;AB Test结束后&#xff0c;如何进行显著性检验&#xff1f;&#xff08;以判断改动是否有效果&#xff09; 引入&#xff1a;Z检验和T检验 而T检验适用于 n<30 的小样本 值得注意的是&#xff1a;统计上显著并不意味着现实中显著&#xff01; e.g. 加速…

尚硅谷大数据项目《在线教育之离线数仓》笔记008

视频地址&#xff1a;尚硅谷大数据项目《在线教育之离线数仓》_哔哩哔哩_bilibili 目录 P123 P124 P125 P126 P127 P128 P129 P123 Apache Superset是一个现代的数据探索和可视化平台。它功能强大且十分易用&#xff0c;可对接各种数据源&#xff0c;包括很多现代的大数…

医院空调冷热源设计方案VR元宇宙模拟演练的独特之处

作为一个备受关注的技术-元宇宙&#xff0c;毋庸置疑的是&#xff0c;因为建筑本身契合了时尚、前卫、高端、虚拟、科幻、泛在、协作、互通等元素特征&#xff0c;因此在建筑行业更需要元宇宙&#xff0c;以居民建筑环境冷热源设计来说&#xff0c;元宇宙会打破既定的现实阻碍和…

LVS NAT模式负载均衡群集部署

目录 1 群集(集群) cluster 1.1 群集的类型 2 LVS的工作模式及其工作过程 2.1 NAT模式&#xff08;VS-NAT&#xff09; 2.2 直接路由模式&#xff08;VS-DR&#xff09; 2.3 IP隧道模式&#xff08;VS-TUN&#xff09; 3 LVS-NAt 模式配置步骤 3.1 部署共享存储 3.2 配…

SSL证书验签时要带www吗?

单域名证书&#xff1a;顶级域名如www.abc.com或abc.com 不管你提交订单的时候填写的域名是带www或不带www的域名&#xff0c;签发的证书均支持www和不带www的域名 单域名证书&#xff1a;子域名如mail.abc.com&#xff0c;签发的证书仅支持mail.abc.com 通配符证书&#xff…

MySQL触发器使用指南大全

一、介绍 触发器是与表有关的数据库对象&#xff0c;指在insert/update/delete之前或之后&#xff0c;触发并执行触发器中定义的SQL语句集合。触发器的这种特性可以协助应用在数据库端确保数据的完整性&#xff0c;日志记录&#xff0c;数据校验等操作。 使用别名OLD和NEW来引…

C++之生成key-value键值三种方式(一百九十)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

Web server failed to start. Port 8080 was already in use.之解决方法

问题&#xff1a; Web server failed to start. Port 8080 was already in use&#xff0c;这句错误描述意思是当前程序的端口号8080被占用了&#xff0c;需要将占用该端口的程序停止掉才行&#xff1b;错误如图所示&#xff1a; 解决方法&#xff1a; 按住winr&#xff0c;输入…