超然楼 超然楼
首页
开源
分享
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
关于
友链
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

soft1314

首页
开源
分享
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
关于
友链
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 技术

    • 开源后台管理系统解决方案 boot-admin 简介
    • vue-element-admin动态菜单改造
    • Springboot整合Flowable6.x导出bpmn20
    • Flowable导出查看跟踪流程图(1)
      • Flowable导出查看跟踪流程图(2)
      • 整合flowable官方editor-app源码BPMN2建模(1)
      • 整合flowable官方editor-app源码BPMN2建模(2)
      • Oracle逻辑备份exp导出指定表名时需要加括号吗?
      • boot-admin整合Quartz实现动态管理定时任务
      • boot-admin整合Liquibase实现数据库版本管理
      • boot-admin开源项目中有关后端参数校验的最佳实践
      • boot-admin项目数据库缺省字段设计之最佳实践
      • 代码审计工具Fortify基本使用
      • 记一次Oracle归档日志异常增长问题的排查过程
      • 填一个Mybatis-plus动态数据源切换失效的坑
      • Springboot使用AOP编程简介
      • Oracle也有回收站
      • 使用OpenFeign传递二进制流
      • 使用 Spring Security 保护您的 WebFlux 应用程序
    • 生活

    • 思考

    • 博客
    • 技术
    Soft1314
    2023-04-17
    目录

    Flowable导出查看跟踪流程图(1)

    源码仓库

    Github (opens new window) Gitee (opens new window)

    Flowable诞生于Activiti,是一个使用Java编写的轻量级业务流程引擎。Flowable流程引擎可用于部署BPMN 2.0流程定义,可以十分灵活地加入你的应用/服务/构架。

    本文介绍4种绘制流程图的方式,前3种是在后台绘制静态图(image/png格式),以Stream形式返回前端显示。最后1种是后端生成JSON形式的结构化数据,由前端使用Snap.svg绘制的交互式SVG动画流程图。

    # 导入Maven依赖

            <dependency>
                <groupId>org.flowable</groupId>
                <artifactId>flowable-spring-boot-starter-basic</artifactId>
                <version>6.4.1</version>
            </dependency>
            <dependency>
                <groupId>org.flowable</groupId>
                <artifactId>flowable-json-converter</artifactId>
                <version>6.4.1</version>
            </dependency>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    # 导出流程定义图

    适用于流程管理或启动流程时查看已经部署的流程图,流程图不包括任务办理实际流转信息。 使用流程定义(ProcessDefinition.id),通过调用flowable 的RepositoryService来导出其流程定义的图片资源。 源码:

    @RestController
    @Slf4j
    public class ProcessController {
        @Autowired
        private MyProcessService processService;
        
        /**
         * 通过processDefinition.id和resType导出流程XML或图片资源
         * @param id processDefinition.id
         * @param resType 取值 “image/png”或“text/xml”
         * @param response
         * @throws Exception
         */
        @GetMapping(value = "/res/exp")
        @ApiOperation("通过processDefinition.id和resType导出流程XML或图片资源")
        public void resourceRead(@RequestParam("id") String id,@RequestParam("resType") String resType, HttpServletResponse response) throws Exception {
            /** resType取值 “image/png”或“text/xml” **/
            InputStream resourceAsStream = processService.resourceRead(id,resType);
            byte[] b = new byte[1024];
            int len = -1;
            while ((len = resourceAsStream.read(b, 0, 1024)) != -1) {
                response.getOutputStream().write(b, 0, len);
            }
        }
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    @Service
    public class MyProcessServiceImpl implements MyProcessService {
        @Autowired
        private RepositoryService repositoryService;
        
        @Override
        public InputStream resourceRead(String id, String resType) throws Exception {
            ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(id).singleResult();
            String resourceName = "";
            if (resType.equals("image/png")) {
                resourceName = processDefinition.getDiagramResourceName();
            } else if (resType.equals("text/xml")) {
                resourceName = processDefinition.getResourceName();
            }
            InputStream resourceAsStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), resourceName);
            return resourceAsStream;
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

    运行效果如下: 流程定义

    # 绘制流程待办流图

    适用于查看待办任务列表时,绘制该任务的流程图,流程图可强调显示当前待办任务所处的流程节点。使用流程实例(processInstanceId)ID,通过调用flowable引擎来绘制流程图。 源码:

    @RequestMapping("/api/workflow/auth/activiti/task")
    @RestController
    @Slf4j
    public class TaskController {
        @Autowired
        private MyTaskService myTaskService;
        
        /**
         * 绘制强调当前节点的流程图
         */
        @GetMapping(value = "/process/diagram")
        @ApiOperation("绘制强调当前节点的流程图")
        public void genProcessDiagram(@RequestParam("processInstanceId") String processInstanceId, HttpServletResponse httpServletResponse) throws Exception {
            InputStream resourceAsStream = myTaskService.genProcessDiagram(processInstanceId);
            byte[] b = new byte[1024];
            int len = -1;
            while ((len = resourceAsStream.read(b, 0, 1024)) != -1) {
                httpServletResponse.getOutputStream().write(b, 0, len);
            }
        }
    }    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    @Slf4j
    @Service
    public class MyTaskServiceImpl implements MyTaskService {
        @Autowired
        private RuntimeService runtimeService;
        @Autowired
        private TaskService taskService;
        @Autowired
        private RepositoryService repositoryService;
        @Resource
        private ProcessEngine processEngine;
    
        @Override
        public InputStream genProcessDiagram(String processId) throws Exception {
            ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(processId).singleResult();
    
            //流程走完的不显示图
            if (pi == null) {
                return null;
            }
            Task task = taskService.createTaskQuery().processInstanceId(pi.getId()).singleResult();
            //使用流程实例ID,查询正在执行的执行对象表,返回流程实例对象
            String InstanceId = task.getProcessInstanceId();
            List<Execution> executions = runtimeService
                    .createExecutionQuery()
                    .processInstanceId(InstanceId)
                    .list();
    
            //得到正在执行的Activity的Id
            List<String> activityIds = new ArrayList<>();
            List<String> flows = new ArrayList<>();
            for (Execution exe : executions) {
                List<String> ids = runtimeService.getActiveActivityIds(exe.getId());
                activityIds.addAll(ids);
            }
    
            //获取流程图
            BpmnModel bpmnModel = repositoryService.getBpmnModel(pi.getProcessDefinitionId());
            ProcessEngineConfiguration engconf = processEngine.getProcessEngineConfiguration();
            ProcessDiagramGenerator diagramGenerator = engconf.getProcessDiagramGenerator();
            InputStream in = diagramGenerator.generateDiagram(bpmnModel, "png", activityIds, flows, engconf.getActivityFontName(), engconf.getLabelFontName(), engconf.getAnnotationFontName(), engconf.getClassLoader(), 2.0,true);
            return in;
        }
    }    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44

    流程待办

    # 绘制流程已办流图

    适用于查看已办任务列表时,绘制该任务的流程图,流程图可强调显示任务办理实际经过的路径。使用流程实例(processInstanceId)ID,通过调用flowable引擎来绘制流程图。 源码:

    @RequestMapping("/api/workflow/auth/activiti/task")
    @RestController
    @Slf4j
    public class TaskController {
        @Autowired
        private MyTaskService myTaskService;
    
        /**
         * 读取带跟踪的图片
         */
        @GetMapping(value = "/trace/photo")
        public void tracePhoto(@RequestParam("processInstanceId") String processInstanceId, HttpServletResponse response) throws Exception {
            InputStream inputStream = myTaskService.genTracePhoto(processInstanceId);
    
            // 输出资源内容到相应对象
            byte[] b = new byte[1024];
            int len;
            while ((len = inputStream.read(b, 0, 1024)) != -1) {
                response.getOutputStream().write(b, 0, len);
            }
        }
    }    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    @Slf4j
    @Service
    public class MyTaskServiceImpl implements MyTaskService {
        @Autowired
        private RuntimeService runtimeService;
        @Autowired
        private TaskService taskService;
        @Resource
        private HistoryService historyService;
        @Autowired
        private RepositoryService repositoryService;
    
        @Override
        public InputStream genTracePhoto(String processInstanceId) throws Exception {
            String procDefId;
            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
                    .processInstanceId(processInstanceId)
                    .singleResult();
            if (processInstance == null) {
                HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
                procDefId = historicProcessInstance.getProcessDefinitionId();
    
            } else {
                procDefId = processInstance.getProcessDefinitionId();
            }
    
            BpmnModel bpmnModel = repositoryService.getBpmnModel(procDefId);
            DefaultProcessDiagramGenerator defaultProcessDiagramGenerator = new DefaultProcessDiagramGenerator(); // 创建默认的流程图生成器
            String imageType = "png"; // 生成图片的类型
            List<String> highLightedActivities = new ArrayList<>(); // 高亮节点集合
            List<String> highLightedFlows = new ArrayList<>(); // 高亮连线集合
            List<HistoricActivityInstance> hisActInsList = historyService.createHistoricActivityInstanceQuery()
                    .processInstanceId(processInstanceId)
                    .list(); // 查询所有历史节点信息
            hisActInsList.forEach(historicActivityInstance -> { // 遍历
                if("sequenceFlow".equals(historicActivityInstance.getActivityType())) {
                    // 添加高亮连线
                    highLightedFlows.add(historicActivityInstance.getActivityId());
                } else {
                    // 添加高亮节点
                    highLightedActivities.add(historicActivityInstance.getActivityId());
                }
            });
            String activityFontName = "宋体"; // 节点字体
            String labelFontName = "微软雅黑"; // 连线标签字体
            String annotationFontName = "宋体"; // 连线标签字体
            ClassLoader customClassLoader = null; // 类加载器
            double scaleFactor = 1.0d; // 比例因子,默认即可
            boolean drawSequenceFlowNameWithNoLabelDI = true; // 不设置连线标签不会画
            // 生成图片
            InputStream inputStream = defaultProcessDiagramGenerator.generateDiagram(bpmnModel, imageType, highLightedActivities
                    , highLightedFlows, activityFontName, labelFontName, annotationFontName, customClassLoader,
                    scaleFactor, drawSequenceFlowNameWithNoLabelDI); // 获取输入流
            return inputStream;
        }
    }    
        
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57

    流程已办

    # 前端绘制流程跟踪图和显示日志

    无论是待办、已办,亦或是流转中、已结束的流程实例,通过使用JS绘制SVG格式的交互式流程图,与以上三种方式相比,在效果上都具有明显优势。 运行效果如下图所示: 流程跟踪 具体内容参见下一篇博文

    项目源码仓库 (opens new window)

    编辑 (opens new window)
    上次更新: 2024/04/18
    Springboot整合Flowable6.x导出bpmn20
    Flowable导出查看跟踪流程图(2)

    ← Springboot整合Flowable6.x导出bpmn20 Flowable导出查看跟踪流程图(2)→

    最近更新
    01
    使用 Spring Security 保护您的 WebFlux 应用程序
    02-07
    02
    Oracle也有回收站
    07-31
    03
    Springboot使用AOP编程简介
    07-31
    更多文章>
    Theme by Vdoing | Copyright © 2023-2024 Soft1314 | MIT License
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式