我们都知道activiti在5.22的时候就有了流程图跟踪组件
Diagram Viewer
,如图(图片来源《Activiti实战》):
但是,到6.0就找不到该组件了,可能因为6.0的api改动很大,有些类和包完全舍弃了,该组件就不适用了。所以在6.0的时候,我们要想展示高亮流程图,往往都是通过后端来生成图片,返回给前端展示。这种方式也是我们项目之前所用的,生成图片代码繁琐,在生产环境还有字体问题,我们就不多介绍。
无意中了解到
bpmn.js
可以设计和展示流程图(本篇只讲解展示流程图),所以就去搜索这方面的资料。找到了这篇博客:
bpmn整合流程图高亮显示流程进度图
在他的基础上,进行了改造和优化,就有了开头的效果图。
"bpmn-js": "^8.7.1",
"bpmn-js-properties-panel": "^0.44.0",
"bpmn-js-token-simulation": "^0.21.1",
"camunda-bpmn-moddle": "^5.1.2",
"xml-js": "^1.6.11"
引入这些依赖就可以了。然后就是页面,基本上与 bpmn整合流程图高亮显示流程进度图 一样,但是加入了自己的逻辑,修复了一些显示问题:
<template>
<div class="bpmn-viewer-container">
style="width:100%;height:20px;position: absolute; left: 20px; top: 10px; color: #000000D9;font-size: 16px;font-weight: 500">
{{title}}
</div>
<div style="position: absolute; left: 10px; top: 40px;z-index: 999">
<el-button-group key="scale-control">
<el-tooltip effect="light" content="缩小视图">
<el-button :size="headerButtonSize" :disabled="defaultZoom < 0.2" icon="el-icon-zoom-out"
@click="processZoomOut()"/>
</el-tooltip>
<el-button :size="headerButtonSize">{{ Math.floor(this.defaultZoom * 10 * 10) + '%' }}</el-button>
<el-tooltip effect="light" content="放大视图">
<el-button :size="headerButtonSize" :disabled="defaultZoom > 4" icon="el-icon-zoom-in"
@click="processZoomIn()"/>
</el-tooltip>
<el-tooltip effect="light" content="重置视图并居中">
<el-button :size="headerButtonSize" icon="el-icon-c-scale-to-original" @click="processReZoom()"/>
</el-tooltip>
</el-button-group>
</div>
<div id="bpmnCanvas" style="width:100%;height:500px;margin: 0 auto;"></div>
<div v-for="item in detailInfo" :key="item.activityId" style="width: 90%;margin: 0 auto;border-bottom: 1px dashed #333;">
<el-row>
<el-col :span="12">
<p>节点名称:{{item.activityName}}</p>
<p>审批人:{{item.assignee}}</p>
<p>审批状态:{{item.approvalStatus}}</p>
</el-col>
<el-col :span="12">
<p>审批结果:{{item.result}}</p>
<p>审批意见:{{item.comment}}</p>
<p>审批时间:{{item.endTime}}</p>
</el-col>
</el-row>
</div>
</div>
</div>
</template>
<script>
import BpmnViewer from 'bpmn-js'
import MoveCanvasModule from 'diagram-js/lib/navigation/movecanvas'
import { checkSpeed, getOneActivity } from '@/api/approval/build'
let bpmnViewer = null
export default {
props: {
headerButtonSize: {
type: String,
default: 'small',
validator: value => ['default', 'medium', 'small', 'mini'].indexOf(value) !== -1
reviewObj: {
type: Object
name: 'reviewRuningFlow',
components: {
data() {
return {
detailInfo: [],
executedLightNode: [],
highlightLine: [],
activeLightNode:[],
defaultZoom: 1,
nodeDetail: {},
scale: 1,
title: '流程预览',
showViewDialog: false,
instanceId: undefined
mounted() {
methods: {
initPage(instanceId, procDefId) {
bpmnViewer && bpmnViewer.destroy()
bpmnViewer = new BpmnViewer({
container: '#bpmnCanvas',
width: '100%',
additionalModules: [
MoveCanvasModule
this.instanceId = instanceId
let len = document.getElementsByTagName('svg').length
document.getElementsByTagName('svg')[len-2].setAttribute('display', 'none')
if(instanceId || procDefId) {
checkSpeed({'instanceId':instanceId, 'procDefId':procDefId}).then(res => {
if (res.code === 200) {
this.title = res.data.modelName
this.highlightLine = res.data.highlightedFlowIds
this.executedLightNode = res.data.executedActivityIds
this.activeLightNode = res.data.activeActivityIds
if (bpmnViewer) {
this.importXml(res.data.modelXml)
} else {
this.$message({
message: res.data.msg,
type: 'error'
})}