fix: 优化已完成流程节点显示问题

rf
tony 2022-12-18 15:45:15 +08:00
parent 1486beb897
commit be62877c37
17 changed files with 306 additions and 296 deletions

View File

@ -192,7 +192,7 @@ public class FlowTaskController {
}
/**
*
*
*
* @param procInsId
* @param procInsId
@ -202,4 +202,16 @@ public class FlowTaskController {
@PathVariable("executionId") String executionId) {
return flowTaskService.getFlowViewer(procInsId, executionId);
}
/**
*
* @param procInsId id
* @return
*/
@GetMapping("/flowXmlAndNode")
public AjaxResult flowXmlAndNode(@RequestParam(value = "procInsId",required = false) String procInsId,
@RequestParam(value = "deployId",required = false) String deployId){
return flowTaskService.flowXmlAndNode(procInsId,deployId);
}
}

View File

@ -145,7 +145,7 @@ public interface IFlowTaskService {
InputStream diagram(String processId);
/**
*
*
* @param procInsId
* @return
*/
@ -173,4 +173,11 @@ public interface IFlowTaskService {
* @return
*/
AjaxResult flowFormData(String deployId);
/**
*
* @param procInsId
* @return
*/
AjaxResult flowXmlAndNode(String procInsId,String deployId);
}

View File

@ -3,6 +3,7 @@ package com.ruoyi.flowable.service.impl;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.flowable.common.constant.ProcessConstants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysRole;
@ -26,6 +27,7 @@ import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.*;
@ -52,6 +54,7 @@ import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
@ -866,7 +869,7 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
}
/**
*
*
*
* @param procInsId id
* @return
@ -1030,6 +1033,56 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
}
}
/**
*
*
* @param procInsId
* @return
*/
@Override
public AjaxResult flowXmlAndNode(String procInsId, String deployId) {
try {
List<FlowViewerDto> flowViewerList = new ArrayList<>();
// 获取已经完成的节点
List<HistoricActivityInstance> listFinished = historyService.createHistoricActivityInstanceQuery()
.processInstanceId(procInsId)
.finished()
.list();
// 保存已经完成的流程节点编号
listFinished.forEach(s -> {
FlowViewerDto flowViewerDto = new FlowViewerDto();
flowViewerDto.setKey(s.getActivityId());
flowViewerDto.setCompleted(true);
flowViewerList.add(flowViewerDto);
});
// 获取代办节点
List<HistoricActivityInstance> listUnFinished = historyService.createHistoricActivityInstanceQuery()
.processInstanceId(procInsId)
.unfinished()
.list();
// 保存需要代办的节点编号
listUnFinished.forEach(s -> {
FlowViewerDto flowViewerDto = new FlowViewerDto();
flowViewerDto.setKey(s.getActivityId());
flowViewerDto.setCompleted(false);
flowViewerList.add(flowViewerDto);
});
Map<String, Object> result = new HashMap();
// xmlData 数据
ProcessDefinition definition = repositoryService.createProcessDefinitionQuery().deploymentId(deployId).singleResult();
InputStream inputStream = repositoryService.getResourceAsStream(definition.getDeploymentId(), definition.getResourceName());
String xmlData = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
result.put("nodeData",flowViewerList);
result.put("xmlData",xmlData);
return AjaxResult.success(result);
} catch (Exception e) {
return AjaxResult.error("高亮历史任务失败");
}
}
/**
*
*

View File

@ -78,7 +78,7 @@ export function readImage(deployId) {
})
}
// 读取image文件
// 获取流程执行节点
export function getFlowViewer(procInsId, executionId) {
return request({
url: '/flowable/task/flowViewer/' + procInsId + '/' + executionId,
@ -86,6 +86,15 @@ export function getFlowViewer(procInsId, executionId) {
})
}
// 流程节点数据
export function flowXmlAndNode(query) {
return request({
url: '/flowable/task/flowXmlAndNode',
method: 'get',
params: query
})
}
// 读取xml文件
export function saveXml(data) {
return request({

View File

@ -1,32 +1,20 @@
<template>
<div>
<!--<bpmn-modeler
ref="refNode"
:xml="xmlData"
:is-view="true"
:taskList="taskData"
/>-->
<flow-view :xmlData="xmlData" :taskList="taskData"/>
<flow-view :flowData="flowData"/>
</div>
</template>
<script>
import bpmnModeler from '@/components/Process/index'
import FlowView from './flowview'
export default {
name: "Flow",
components: {
bpmnModeler,
FlowView
},
props: {
xmlData: {
type: String,
default: ''
},
taskData: {
type: Array,
default: () => []
flowData: {
type: Object,
default: () => {}
}
},
data() {

View File

@ -21,14 +21,10 @@ import { CustomViewer as BpmnViewer } from "@/components/customBpmn";
export default {
name: "FlowView",
props: {
xmlData: {
type: String,
default: ''
flowData: {
type: Object,
default: () => {}
},
taskList: {
type: Array,
default: () => []
}
},
data() {
return {
@ -36,30 +32,33 @@ export default {
};
},
watch: {
xmlData: function(val) {
if (val) {
this.getImg(val)
}
flowData: {
handler(newVal) {
if (Object.keys(newVal).length > 0) {
//
this.bpmnViewer && this.bpmnViewer.destroy();
this.bpmnViewer = new BpmnViewer({
container: this.$refs.flowCanvas,
height: 'calc(100vh - 200px)',
});
this.loadFlowCanvas(newVal)
}
},
immediate: true, //
deep: true //
}
},
mounted() {
//
this.bpmnViewer && this.bpmnViewer.destroy();
this.bpmnViewer = new BpmnViewer({
container: this.$refs.flowCanvas,
height: 'calc(100vh - 200px)',
});
this.getImg(this.xmlData)
},
methods: {
//
async getImg(xmlUrl) {
//
async loadFlowCanvas(flowData) {
const self = this
try {
await self.bpmnViewer.importXML(xmlUrl);
await self.bpmnViewer.importXML(flowData.xmlData);
self.fitViewport()
if (self.taskList !==undefined && self.taskList.length > 0 ) {
self.fillColor()
if (flowData.nodeData !==undefined && flowData.nodeData.length > 0 ) {
self.fillColor(flowData.nodeData)
}
} catch (err) {
console.error(err.message, err.warnings)
@ -83,17 +82,17 @@ export default {
},
//
fillColor() {
fillColor(nodeData) {
const canvas = this.bpmnViewer.get('canvas')
this.bpmnViewer.getDefinitions().rootElements[0].flowElements.forEach(n => {
const completeTask = this.taskList.find(m => m.key === n.id)
const todoTask = this.taskList.find(m => !m.completed)
const endTask = this.taskList[this.taskList.length - 1]
const completeTask = nodeData.find(m => m.key === n.id)
const todoTask = nodeData.find(m => !m.completed)
const endTask = nodeData[nodeData.length - 1]
if (n.$type === 'bpmn:UserTask') {
if (completeTask) {
canvas.addMarker(n.id, completeTask.completed ? 'highlight' : 'highlight-todo')
n.outgoing?.forEach(nn => {
const targetTask = this.taskList.find(m => m.key === nn.targetRef.id)
const targetTask = nodeData.find(m => m.key === nn.targetRef.id)
if (targetTask) {
if (todoTask && completeTask.key === todoTask.key && !todoTask.completed){
canvas.addMarker(nn.id, todoTask.completed ? 'highlight' : 'highlight-todo')
@ -111,7 +110,7 @@ export default {
if (completeTask) {
canvas.addMarker(n.id, completeTask.completed ? 'highlight' : 'highlight-todo')
n.outgoing?.forEach(nn => {
const targetTask = this.taskList.find(m => m.key === nn.targetRef.id)
const targetTask = nodeData.find(m => m.key === nn.targetRef.id)
if (targetTask) {
canvas.addMarker(nn.id, targetTask.completed ? 'highlight' : 'highlight-todo')
@ -127,7 +126,7 @@ export default {
if (completeTask) {
canvas.addMarker(n.id, completeTask.completed ? 'highlight' : 'highlight-todo')
n.outgoing?.forEach(nn => {
const targetTask = this.taskList.find(m => m.key === nn.targetRef.id)
const targetTask = nodeData.find(m => m.key === nn.targetRef.id)
if (targetTask) {
canvas.addMarker(nn.id, targetTask.completed ? 'highlight' : 'highlight-todo')
canvas.addMarker(nn.targetRef.id, targetTask.completed ? 'highlight' : 'highlight-todo')
@ -137,7 +136,7 @@ export default {
}
else if (n.$type === 'bpmn:StartEvent') {
n.outgoing.forEach(nn => {
const completeTask = this.taskList.find(m => m.key === nn.targetRef.id)
const completeTask = nodeData.find(m => m.key === nn.targetRef.id)
if (completeTask) {
canvas.addMarker(nn.id, 'highlight')
canvas.addMarker(n.id, 'highlight')

View File

@ -5,9 +5,9 @@
<span class="el-icon-document">办结任务</span>
<el-button style="float: right;" size="mini" type="primary" @click="goBack"></el-button>
</div>
<el-tabs tab-position="top" @tab-click="handleClick">
<el-tabs tab-position="top" v-model="activeName" @tab-click="handleClick">
<!--表单信息-->
<el-tab-pane label="表单信息">
<el-tab-pane label="表单信息" name="1">
<el-col :span="16" :offset="4" v-if="variableOpen">
<div class="test-form">
<parser :key="new Date().getTime()" :form-conf="variablesData" />
@ -15,7 +15,7 @@
</el-col>
</el-tab-pane>
<!--流程流转记录-->
<el-tab-pane label="流转记录">
<el-tab-pane label="流转记录" name="2">
<el-col :span="16" :offset="4" >
<div class="block">
<el-timeline>
@ -60,8 +60,8 @@
</div>
</el-col>
</el-tab-pane>
<el-tab-pane label="流程图">
<flow :xmlData="xmlData" :taskData="taskList"></flow>
<el-tab-pane label="流程图" name="3">
<flow :flowData="flowData"/>
</el-tab-pane>
</el-tabs>
<el-button style="position: absolute;right:35px;top:35px;" type="primary" @click="goBack"></el-button>
@ -72,10 +72,9 @@
<script>
import {flowRecord} from "@/api/flowable/finished";
import Parser from '@/components/parser/Parser'
import {getProcessVariables, readXml, getFlowViewer} from "@/api/flowable/definition";
import {getProcessVariables, flowXmlAndNode} from "@/api/flowable/definition";
import flow from '@/views/flowable/task/finished/detail/flow'
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import Treeselect from "@riophae/vue-treeselect";
export default {
name: "Record",
@ -87,8 +86,8 @@ export default {
data() {
return {
// xml
xmlData: "",
taskList: [],
flowData: {},
activeName: '1',
//
userList: null,
defaultProps: {
@ -125,8 +124,6 @@ export default {
this.taskForm.taskId = this.$route.query && this.$route.query.taskId;
this.taskForm.procInsId = this.$route.query && this.$route.query.procInsId;
//
this.getFlowViewer(this.taskForm.procInsId,this.taskForm.executionId);
this.getModelDetail(this.taskForm.deployId);
//
if (this.taskForm.taskId){
this.processVariables( this.taskForm.taskId)
@ -135,19 +132,11 @@ export default {
},
methods: {
handleClick(tab, event) {
console.log(tab, event);
},
/** xml 文件 */
getModelDetail(deployId) {
// xml
readXml(deployId).then(res => {
this.xmlData = res.data
})
},
getFlowViewer(procInsId,executionId) {
getFlowViewer(procInsId,executionId).then(res => {
this.taskList = res.data
})
if (tab.name === '3') {
flowXmlAndNode({procInsId: this.taskForm.procInsId, deployId: this.taskForm.deployId}).then(res => {
this.flowData = res.data;
})
}
},
setIcon(val) {
if (val) {

View File

@ -1,32 +1,20 @@
<template>
<div>
<!--<bpmn-modeler
ref="refNode"
:xml="xmlData"
:is-view="true"
:taskList="taskData"
/>-->
<flow-view :xmlData="xmlData" :taskList="taskData"/>
<flow-view :flowData="flowData"/>
</div>
</template>
<script>
import bpmnModeler from '@/components/Process/index'
import FlowView from './flowview'
export default {
name: "Flow",
components: {
bpmnModeler,
FlowView
},
props: {
xmlData: {
type: String,
default: ''
},
taskData: {
type: Array,
default: () => []
flowData: {
type: Object,
default: () => {}
}
},
data() {

View File

@ -21,14 +21,10 @@ import { CustomViewer as BpmnViewer } from "@/components/customBpmn";
export default {
name: "FlowView",
props: {
xmlData: {
type: String,
default: ''
flowData: {
type: Object,
default: () => {}
},
taskList: {
type: Array,
default: () => []
}
},
data() {
return {
@ -36,30 +32,34 @@ export default {
};
},
watch: {
xmlData: function(val) {
if (val) {
this.getImg(val)
}
flowData: {
handler(newVal) {
if (Object.keys(newVal).length > 0) {
//
this.bpmnViewer && this.bpmnViewer.destroy();
this.bpmnViewer = new BpmnViewer({
container: this.$refs.flowCanvas,
height: 'calc(100vh - 200px)',
});
this.loadFlowCanvas(newVal)
}
},
immediate: true, //
deep: true //
}
},
mounted() {
//
this.bpmnViewer && this.bpmnViewer.destroy();
this.bpmnViewer = new BpmnViewer({
container: this.$refs.flowCanvas,
height: 'calc(100vh - 200px)',
});
this.getImg(this.xmlData)
},
methods: {
//
async getImg(xmlUrl) {
//
async loadFlowCanvas(flowData) {
const self = this
try {
await self.bpmnViewer.importXML(xmlUrl);
console.log(flowData,"self.flowData")
await self.bpmnViewer.importXML(flowData.xmlData);
self.fitViewport()
if (self.taskList !==undefined && self.taskList.length > 0 ) {
self.fillColor()
if (flowData.nodeData !==undefined && flowData.nodeData.length > 0 ) {
self.fillColor(flowData.nodeData)
}
} catch (err) {
console.error(err.message, err.warnings)
@ -83,17 +83,17 @@ export default {
},
//
fillColor() {
fillColor(nodeData) {
const canvas = this.bpmnViewer.get('canvas')
this.bpmnViewer.getDefinitions().rootElements[0].flowElements.forEach(n => {
const completeTask = this.taskList.find(m => m.key === n.id)
const todoTask = this.taskList.find(m => !m.completed)
const endTask = this.taskList[this.taskList.length - 1]
const completeTask = nodeData.find(m => m.key === n.id)
const todoTask = nodeData.find(m => !m.completed)
const endTask = nodeData[nodeData.length - 1]
if (n.$type === 'bpmn:UserTask') {
if (completeTask) {
canvas.addMarker(n.id, completeTask.completed ? 'highlight' : 'highlight-todo')
n.outgoing?.forEach(nn => {
const targetTask = this.taskList.find(m => m.key === nn.targetRef.id)
const targetTask = nodeData.find(m => m.key === nn.targetRef.id)
if (targetTask) {
if (todoTask && completeTask.key === todoTask.key && !todoTask.completed){
canvas.addMarker(nn.id, todoTask.completed ? 'highlight' : 'highlight-todo')
@ -111,7 +111,7 @@ export default {
if (completeTask) {
canvas.addMarker(n.id, completeTask.completed ? 'highlight' : 'highlight-todo')
n.outgoing?.forEach(nn => {
const targetTask = this.taskList.find(m => m.key === nn.targetRef.id)
const targetTask = nodeData.find(m => m.key === nn.targetRef.id)
if (targetTask) {
canvas.addMarker(nn.id, targetTask.completed ? 'highlight' : 'highlight-todo')
@ -127,7 +127,7 @@ export default {
if (completeTask) {
canvas.addMarker(n.id, completeTask.completed ? 'highlight' : 'highlight-todo')
n.outgoing?.forEach(nn => {
const targetTask = this.taskList.find(m => m.key === nn.targetRef.id)
const targetTask = nodeData.find(m => m.key === nn.targetRef.id)
if (targetTask) {
canvas.addMarker(nn.id, targetTask.completed ? 'highlight' : 'highlight-todo')
canvas.addMarker(nn.targetRef.id, targetTask.completed ? 'highlight' : 'highlight-todo')
@ -137,7 +137,7 @@ export default {
}
else if (n.$type === 'bpmn:StartEvent') {
n.outgoing.forEach(nn => {
const completeTask = this.taskList.find(m => m.key === nn.targetRef.id)
const completeTask = nodeData.find(m => m.key === nn.targetRef.id)
if (completeTask) {
canvas.addMarker(nn.id, 'highlight')
canvas.addMarker(n.id, 'highlight')

View File

@ -5,9 +5,9 @@
<span class="el-icon-document">已发任务</span>
<el-button style="float: right;" size="mini" type="primary" @click="goBack"></el-button>
</div>
<el-tabs tab-position="top" @tab-click="handleClick">
<el-tabs tab-position="top" v-model="activeName" @tab-click="handleClick">
<!--表单信息-->
<el-tab-pane label="表单信息">
<el-tab-pane label="表单信息" name="1">
<el-col :span="16" :offset="4">
<div class="test-form">
<parser :key="new Date().getTime()" :form-conf="variablesData" />
@ -15,7 +15,7 @@
</el-col>
</el-tab-pane>
<!--流程流转记录-->
<el-tab-pane label="流转记录">
<el-tab-pane label="流转记录" name="2">
<el-col :span="16" :offset="4" >
<div class="block">
<el-timeline>
@ -61,8 +61,8 @@
</el-col>
</el-tab-pane>
<!--流程图-->
<el-tab-pane label="流程图">
<flow :xmlData="xmlData" :taskData="taskList"></flow>
<el-tab-pane label="流程图" name="3">
<flow :flowData="flowData"/>
</el-tab-pane>
</el-tabs>
<el-button style="position: absolute;right:35px;top:35px;" type="primary" @click="goBack"></el-button>
@ -73,7 +73,7 @@
<script>
import {flowRecord} from "@/api/flowable/finished";
import Parser from '@/components/parser/Parser'
import {getProcessVariables, readXml, getFlowViewer} from "@/api/flowable/definition";
import {getProcessVariables, readXml, getFlowViewer, getHighlight, flowXmlAndNode} from "@/api/flowable/definition";
import flow from '@/views/flowable/task/myProcess/detail/flow'
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
@ -87,8 +87,8 @@ export default {
data() {
return {
// xml
xmlData: "",
taskList: [],
flowData: {},
activeName: '1',
//
queryParams: {
deptId: undefined
@ -113,22 +113,17 @@ export default {
this.taskForm.taskId = this.$route.query && this.$route.query.taskId;
this.taskForm.procInsId = this.$route.query && this.$route.query.procInsId;
//
this.getFlowViewer(this.taskForm.procInsId,this.taskForm.executionId);
this.getModelDetail(this.taskForm.deployId);
//
this.processVariables( this.taskForm.taskId)
this.getFlowRecordList(this.taskForm.procInsId, this.taskForm.deployId);
},
methods: {
handleClick(tab, event) {
console.log(tab, event);
},
/** xml 文件 */
getModelDetail(deployId) {
// xml
readXml(deployId).then(res => {
this.xmlData = res.data
})
if (tab.name === '3'){
flowXmlAndNode({procInsId:this.taskForm.procInsId,deployId:this.taskForm.deployId}).then(res => {
this.flowData = res.data;
})
}
},
getFlowViewer(procInsId,executionId) {
getFlowViewer(procInsId,executionId).then(res => {

View File

@ -1,6 +1,6 @@
<template>
<div>
<flow-view :xmlData="xmlData"/>
<flow-view :flowData="flowData"/>
</div>
</template>
<script>
@ -12,9 +12,9 @@ export default {
FlowView
},
props: {
xmlData: {
type: String,
default: ''
flowData: {
type: Object,
default: () => {}
},
},
data() {

View File

@ -21,10 +21,9 @@ import { CustomViewer as BpmnViewer } from "@/components/customBpmn";
export default {
name: "FlowView",
props: {
// xml
xmlData: {
type: String,
default: ''
flowData: {
type: Object,
default: () => {}
},
},
data() {
@ -33,30 +32,29 @@ export default {
};
},
watch: {
xmlData: {
flowData: {
handler(newVal) {
if (newVal) {
this.loadFlowImg(newVal)
if (Object.keys(newVal).length > 0) {
//
this.bpmnViewer && this.bpmnViewer.destroy();
this.bpmnViewer = new BpmnViewer({
container: this.$refs.flowCanvas,
height: 'calc(100vh - 200px)',
});
this.loadFlowCanvas(newVal)
}
},
immediate: true, //
deep: true //
}
},
mounted() {
//
this.bpmnViewer && this.bpmnViewer.destroy();
this.bpmnViewer = new BpmnViewer({
container: this.$refs.flowCanvas,
height: 'calc(85vh - 200px)',
});
},
mounted() {},
methods: {
//
async loadFlowImg(xmlData) {
async loadFlowCanvas(flowData) {
const self = this
try {
await self.bpmnViewer.importXML(xmlData);
await self.bpmnViewer.importXML(flowData.xmlData);
self.fitViewport()
} catch (err) {
console.error(err.message, err.warnings)

View File

@ -17,7 +17,7 @@
</el-tab-pane>
<!--流程图-->
<el-tab-pane label="流程图">
<flow :xmlData="xmlData"/>
<flow :flowData="flowData"/>
</el-tab-pane>
</el-tabs>
<el-button style="position: absolute;right:35px;top:35px;" type="primary" @click="goBack"></el-button>
@ -36,7 +36,7 @@
<script>
import Parser from '@/components/parser/Parser'
import {definitionStart, readXml} from "@/api/flowable/definition";
import {definitionStart, flowXmlAndNode} from "@/api/flowable/definition";
import flow from './flow'
import {flowFormData} from "@/api/flowable/process";
import {getNextFlowNodeByStart} from "@/api/flowable/todo";
@ -55,7 +55,7 @@ export default {
data() {
return {
// xml
xmlData: "",
flowData: {},
defaultProps: {
children: "children",
label: "label"
@ -86,19 +86,14 @@ export default {
this.procDefId = this.$route.query && this.$route.query.procDefId;
// this.getNextFlowNodeByStart(this.deployId);
this.getFlowFormData(this.deployId);
//
this.loadModelXml(this.deployId);
},
methods: {
handleClick(tab, event) {
console.log(tab, event);
},
/** xml 文件 */
loadModelXml(deployId) {
// xml
readXml(deployId).then(res => {
this.xmlData = res.data
})
if (tab.name === '3'){
flowXmlAndNode({deployId:this.deployId}).then(res => {
this.flowData = res.data;
})
}
},
/** 流程表单数据 */
getFlowFormData(deployId) {

View File

@ -49,7 +49,7 @@ export default {
container: this.$refs.flowCanvas,
height: 'calc(100vh - 200px)',
});
this.getImg(this.xmlData)
// this.getImg(this.xmlData)
},
methods: {
//

View File

@ -1,33 +1,21 @@
<template>
<div>
<!--<bpmn-modeler
ref="refNode"
:xml="xmlData"
:is-view="true"
:taskList="taskData"
/>-->
<flow-view :xmlData="xmlData" :taskList="taskData"/>
<flow-view :flowData="flowData"/>
</div>
</template>
<script>
import bpmnModeler from '@/components/Process/index'
import FlowView from './flowview'
export default {
name: "Flow",
components: {
bpmnModeler,
FlowView
},
props: {
xmlData: {
type: String,
default: ''
flowData: {
type: Object,
default: () => {}
},
taskData: {
type: Array,
default: () => []
}
},
data() {
return {};

View File

@ -21,14 +21,10 @@ import { CustomViewer as BpmnViewer } from "@/components/customBpmn";
export default {
name: "FlowView",
props: {
xmlData: {
type: String,
default: ''
flowData: {
type: Object,
default: () => {}
},
taskList: {
type: Array,
default: () => []
}
},
data() {
return {
@ -36,30 +32,33 @@ export default {
};
},
watch: {
xmlData: function(val) {
if (val) {
this.getImg(val)
}
flowData: {
handler(newVal) {
if (Object.keys(newVal).length > 0) {
//
this.bpmnViewer && this.bpmnViewer.destroy();
this.bpmnViewer = new BpmnViewer({
container: this.$refs.flowCanvas,
height: 'calc(100vh - 200px)',
});
this.loadFlowCanvas(newVal)
}
},
immediate: true, //
deep: true //
}
},
mounted() {
//
this.bpmnViewer && this.bpmnViewer.destroy();
this.bpmnViewer = new BpmnViewer({
container: this.$refs.flowCanvas,
height: 'calc(100vh - 200px)',
});
this.getImg(this.xmlData)
},
methods: {
//
async getImg(xmlUrl) {
//
async loadFlowCanvas(flowData) {
const self = this
try {
await self.bpmnViewer.importXML(xmlUrl);
await self.bpmnViewer.importXML(flowData.xmlData);
self.fitViewport()
if (self.taskList !==undefined && self.taskList.length > 0 ) {
self.fillColor()
if (flowData.nodeData !==undefined && flowData.nodeData.length > 0 ) {
self.fillColor(flowData.nodeData)
}
} catch (err) {
console.error(err.message, err.warnings)
@ -83,17 +82,17 @@ export default {
},
//
fillColor() {
fillColor(nodeData) {
const canvas = this.bpmnViewer.get('canvas')
this.bpmnViewer.getDefinitions().rootElements[0].flowElements.forEach(n => {
const completeTask = this.taskList.find(m => m.key === n.id)
const todoTask = this.taskList.find(m => !m.completed)
const endTask = this.taskList[this.taskList.length - 1]
const completeTask = nodeData.find(m => m.key === n.id)
const todoTask = nodeData.find(m => !m.completed)
const endTask = nodeData[nodeData.length - 1]
if (n.$type === 'bpmn:UserTask') {
if (completeTask) {
canvas.addMarker(n.id, completeTask.completed ? 'highlight' : 'highlight-todo')
n.outgoing?.forEach(nn => {
const targetTask = this.taskList.find(m => m.key === nn.targetRef.id)
const targetTask = nodeData.find(m => m.key === nn.targetRef.id)
if (targetTask) {
if (todoTask && completeTask.key === todoTask.key && !todoTask.completed){
canvas.addMarker(nn.id, todoTask.completed ? 'highlight' : 'highlight-todo')
@ -111,7 +110,7 @@ export default {
if (completeTask) {
canvas.addMarker(n.id, completeTask.completed ? 'highlight' : 'highlight-todo')
n.outgoing?.forEach(nn => {
const targetTask = this.taskList.find(m => m.key === nn.targetRef.id)
const targetTask = nodeData.find(m => m.key === nn.targetRef.id)
if (targetTask) {
canvas.addMarker(nn.id, targetTask.completed ? 'highlight' : 'highlight-todo')
@ -127,7 +126,7 @@ export default {
if (completeTask) {
canvas.addMarker(n.id, completeTask.completed ? 'highlight' : 'highlight-todo')
n.outgoing?.forEach(nn => {
const targetTask = this.taskList.find(m => m.key === nn.targetRef.id)
const targetTask = nodeData.find(m => m.key === nn.targetRef.id)
if (targetTask) {
canvas.addMarker(nn.id, targetTask.completed ? 'highlight' : 'highlight-todo')
canvas.addMarker(nn.targetRef.id, targetTask.completed ? 'highlight' : 'highlight-todo')
@ -137,7 +136,7 @@ export default {
}
else if (n.$type === 'bpmn:StartEvent') {
n.outgoing.forEach(nn => {
const completeTask = this.taskList.find(m => m.key === nn.targetRef.id)
const completeTask = nodeData.find(m => m.key === nn.targetRef.id)
if (completeTask) {
canvas.addMarker(nn.id, 'highlight')
canvas.addMarker(n.id, 'highlight')

View File

@ -7,9 +7,9 @@
<el-tag>任务节点:{{taskName}}</el-tag>
<el-button style="float: right;" size="mini" type="primary" @click="goBack"></el-button>
</div>
<el-tabs tab-position="top" @tab-click="handleClick">
<el-tabs tab-position="top" v-model="activeName" @tab-click="handleClick">
<!--表单信息-->
<el-tab-pane label="表单信息">
<el-tab-pane label="表单信息" name="1">
<el-col :span="16" :offset="4">
<div class="test-form">
<parser :key="new Date().getTime()" :form-conf="variablesData" />
@ -25,7 +25,7 @@
</el-col>
</el-tab-pane>
<!--流程流转记录-->
<el-tab-pane label="流转记录">
<el-tab-pane label="流转记录" name="2">
<!--flowRecordList-->
<el-col :span="16" :offset="4" >
<div class="block">
@ -71,60 +71,60 @@
</div>
</el-col>
</el-tab-pane>
<!--流程图-->
<el-tab-pane label="流程图">
<flow :xmlData="xmlData" :taskData="taskList"></flow>
</el-tab-pane>
</el-tabs>
<!--审批任务-->
<el-dialog :title="completeTitle" :visible.sync="completeOpen" width="60%" append-to-body>
<el-form ref="taskForm" :model="taskForm">
<el-form-item prop="targetKey">
<flow-user v-if="checkSendUser" :checkType="checkType" @handleUserSelect="handleUserSelect"></flow-user>
<flow-role v-if="checkSendRole" @handleRoleSelect="handleRoleSelect"></flow-role>
</el-form-item>
<el-form-item label="处理意见" label-width="80px" prop="comment" :rules="[{ required: true, message: '请输入处理意见', trigger: 'blur' }]">
<el-input type="textarea" v-model="taskForm.comment" placeholder="请输入处理意见"/>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="completeOpen = false"> </el-button>
<el-button type="primary" @click="taskComplete"> </el-button>
</span>
</el-dialog>
<!--退回流程-->
<el-dialog :title="returnTitle" :visible.sync="returnOpen" width="40%" append-to-body>
<el-form ref="taskForm" :model="taskForm" label-width="80px" >
<el-form-item label="退回节点" prop="targetKey">
<el-radio-group v-model="taskForm.targetKey">
<el-radio-button
v-for="item in returnTaskList"
:key="item.id"
:label="item.id"
>{{item.name}}</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item label="退回意见" prop="comment" :rules="[{ required: true, message: '请输入意见', trigger: 'blur' }]">
<el-input style="width: 50%" type="textarea" v-model="taskForm.comment" placeholder="请输入意见"/>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="returnOpen = false"> </el-button>
<el-button type="primary" @click="taskReturn"> </el-button>
<!--流程图-->
<el-tab-pane label="流程图" name="3">
<flow :flowData="flowData"/>
</el-tab-pane>
</el-tabs>
<!--审批任务-->
<el-dialog :title="completeTitle" :visible.sync="completeOpen" width="60%" append-to-body>
<el-form ref="taskForm" :model="taskForm">
<el-form-item prop="targetKey">
<flow-user v-if="checkSendUser" :checkType="checkType" @handleUserSelect="handleUserSelect"></flow-user>
<flow-role v-if="checkSendRole" @handleRoleSelect="handleRoleSelect"></flow-role>
</el-form-item>
<el-form-item label="处理意见" label-width="80px" prop="comment" :rules="[{ required: true, message: '请输入处理意见', trigger: 'blur' }]">
<el-input type="textarea" v-model="taskForm.comment" placeholder="请输入处理意见"/>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="completeOpen = false"> </el-button>
<el-button type="primary" @click="taskComplete"> </el-button>
</span>
</el-dialog>
<!--驳回流程-->
<el-dialog :title="rejectTitle" :visible.sync="rejectOpen" width="40%" append-to-body>
<el-form ref="taskForm" :model="taskForm" label-width="80px" >
<el-form-item label="驳回意见" prop="comment" :rules="[{ required: true, message: '请输入意见', trigger: 'blur' }]">
<el-input style="width: 50%" type="textarea" v-model="taskForm.comment" placeholder="请输入意见"/>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="rejectOpen = false"> </el-button>
<el-button type="primary" @click="taskReject"> </el-button>
</span>
</el-dialog>
</el-dialog>
<!--退回流程-->
<el-dialog :title="returnTitle" :visible.sync="returnOpen" width="40%" append-to-body>
<el-form ref="taskForm" :model="taskForm" label-width="80px" >
<el-form-item label="退回节点" prop="targetKey">
<el-radio-group v-model="taskForm.targetKey">
<el-radio-button
v-for="item in returnTaskList"
:key="item.id"
:label="item.id"
>{{item.name}}</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item label="退回意见" prop="comment" :rules="[{ required: true, message: '请输入意见', trigger: 'blur' }]">
<el-input style="width: 50%" type="textarea" v-model="taskForm.comment" placeholder="请输入意见"/>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="returnOpen = false"> </el-button>
<el-button type="primary" @click="taskReturn"> </el-button>
</span>
</el-dialog>
<!--驳回流程-->
<el-dialog :title="rejectTitle" :visible.sync="rejectOpen" width="40%" append-to-body>
<el-form ref="taskForm" :model="taskForm" label-width="80px" >
<el-form-item label="驳回意见" prop="comment" :rules="[{ required: true, message: '请输入意见', trigger: 'blur' }]">
<el-input style="width: 50%" type="textarea" v-model="taskForm.comment" placeholder="请输入意见"/>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="rejectOpen = false"> </el-button>
<el-button type="primary" @click="taskReject"> </el-button>
</span>
</el-dialog>
</el-card>
</div>
</template>
@ -134,7 +134,7 @@ import {flowRecord} from "@/api/flowable/finished";
import FlowUser from '@/components/flow/User'
import FlowRole from '@/components/flow/Role'
import Parser from '@/components/parser/Parser'
import {definitionStart, getProcessVariables, readXml, getFlowViewer} from "@/api/flowable/definition";
import {getProcessVariables, flowXmlAndNode} from "@/api/flowable/definition";
import {complete, rejectTask, returnList, returnTask, getNextFlowNode, delegate} from "@/api/flowable/todo";
import flow from '@/views/flowable/task/todo/detail/flow'
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
@ -153,7 +153,8 @@ export default {
return {
// xml
xmlData: "",
taskList: [],
flowData: {},
activeName: '1',
//
deptName: undefined,
//
@ -216,9 +217,6 @@ export default {
this.taskForm.procInsId = this.$route.query.procInsId;
this.taskForm.executionId = this.$route.query.executionId;
this.taskForm.instanceId = this.$route.query.procInsId;
//
this.getFlowViewer(this.taskForm.procInsId, this.taskForm.executionId);
this.getModelDetail(this.taskForm.deployId);
//
if (this.taskForm.taskId) {
this.processVariables(this.taskForm.taskId)
@ -229,19 +227,11 @@ export default {
},
methods: {
handleClick(tab, event) {
console.log(tab, event);
},
/** xml 文件 */
getModelDetail(deployId) {
// xml
readXml(deployId).then(res => {
this.xmlData = res.data
})
},
getFlowViewer(procInsId,executionId) {
getFlowViewer(procInsId,executionId).then(res => {
this.taskList = res.data
})
if (tab.name === '3'){
flowXmlAndNode({procInsId: this.taskForm.procInsId, deployId: this.taskForm.deployId}).then(res => {
this.flowData = res.data;
})
}
},
setIcon(val) {
if (val) {