Flowable6.x导出/查看/跟踪流程图

本文介绍了Flowable6.x中导出、查看和跟踪流程图的四种方法,包括基于流程定义的静态图、待办任务流程图、已办任务流程图,以及前端用Snap.svg绘制的交互式SVG流程图。通过示例代码展示了如何利用RepositoryService、RuntimeService和HistoryService等进行操作。
摘要由CSDN通过智能技术生成

Flowable6.x导出/查看/跟踪流程图

项目源码仓库

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>

导出流程定义图

适用于流程管理或启动流程时查看已经部署的流程图,流程图不包括任务办理实际流转信息。
使用流程定义(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);
        }
    }
}

@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;
    }
}

运行效果如下:
在这里插入图片描述

绘制流程待办流图

适用于查看待办任务列表时,绘制该任务的流程图,流程图可强调显示当前待办任务所处的流程节点。使用流程实例(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);
        }
    }
}    
@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;
    }
}    

在这里插入图片描述

绘制流程已办流图

适用于查看已办任务列表时,绘制该任务的流程图,流程图可强调显示任务办理实际经过的路径。使用流程实例(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);
        }
    }
}    
@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;
    }
}    
    

在这里插入图片描述

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

无论是待办、已办,亦或是流转中、已结束的流程实例,通过使用JS绘制SVG格式的交互式流程图,与以上三种方式相比,在效果上都具有明显优势。
运行效果如下图所示:
在这里插入图片描述

具体内容参见下一篇博文

项目源码仓库

您可以使用Flowable的API来获取流程图。首先,您需要获取到流程定义的ID,可以通过Flowable的RepositoryService来查询。然后,使用Flowable的DiagramGenerator类来生成流程图。 下面是一个示例代码片段,展示了如何获取流程定义的ID并生成流程图: ```java import org.flowable.bpmn.model.BpmnModel; import org.flowable.dmn.api.DmnRepositoryService; import org.flowable.engine.RepositoryService; import org.flowable.image.ProcessDiagramGenerator; // 获取RepositoryService RepositoryService repositoryService = flowable.getRepositoryService(); // 通过流程定义的Key查询最新版本的流程定义 String processDefinitionKey = "yourProcessDefinitionKey"; String processDefinitionId = repositoryService.createProcessDefinitionQuery() .processDefinitionKey(processDefinitionKey) .latestVersion() .singleResult() .getId(); // 获取BpmnModel BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId); // 获取ProcessDiagramGenerator ProcessDiagramGenerator diagramGenerator = flowable.getProcessEngineConfiguration() .getProcessDiagramGenerator(); // 生成流程图 InputStream imageStream = diagramGenerator.generateDiagram(bpmnModel, "png", Collections.emptyList(), Collections.emptyList(), flowable.getProcessEngine().getProcessEngineConfiguration().getActivityFontName(), flowable.getProcessEngine().getProcessEngineConfiguration().getLabelFontName(), flowable.getProcessEngine().getProcessEngineConfiguration().getClassLoader(), 1.0); ``` 请注意,这只是一个简化的示例代码,并不包含完整的异常处理和其他细节。您可能需要根据您的实际情况进行适当的修改和扩展。 希望对您有所帮助!如有任何疑问,请随时提问。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值