流程详情修改以及流程图高亮显示

This commit is contained in:
zhujiyan
2024-05-23 11:45:49 +08:00
parent 722262891c
commit 15cdd9be53
4 changed files with 96 additions and 56 deletions

View File

@@ -10,7 +10,7 @@ const MAPPING_PATH = BPM_BOOT + '/bpm/activity'
*/ */
export const getTaskListByReturn = (processInstanceId: string) => { export const getTaskListByReturn = (processInstanceId: string) => {
return createAxios({ return createAxios({
url: MAPPING_PATH + '/getActivityList?processInstanceId='+processInstanceId, url: MAPPING_PATH + '/list?processInstanceId='+processInstanceId,
method: 'GET' method: 'GET'
}) })
} }

View File

@@ -1,3 +1,4 @@
<!-- 高亮流程图页面以及流程节点颜色配置页面 -->
<template> <template>
<div class="my-process-designer"> <div class="my-process-designer">
<div class="my-process-designer__container"> <div class="my-process-designer__container">
@@ -91,6 +92,7 @@ const createNewDiagram = async (xml) => {
// TODO 芋艿:如果多个 endActivity 的话目前的逻辑可能有一定的问题。https://www.jdon.com/workflow/multi-events.html // TODO 芋艿:如果多个 endActivity 的话目前的逻辑可能有一定的问题。https://www.jdon.com/workflow/multi-events.html
const highlightDiagram = async () => { const highlightDiagram = async () => {
const activityList = activityLists.value const activityList = activityLists.value
console.log(activityLists.value,"高亮数据444455666");
if (activityList.length === 0) { if (activityList.length === 0) {
return return
} }
@@ -103,7 +105,10 @@ const highlightDiagram = async () => {
//进行中高亮之后的任务 key 集合,用于过滤掉 taskList 进行中后面的任务,避免进行中后面的数据 Hover 还有数据 //进行中高亮之后的任务 key 集合,用于过滤掉 taskList 进行中后面的任务,避免进行中后面的数据 Hover 还有数据
let removeTaskDefinitionKeyList = [] let removeTaskDefinitionKeyList = []
// debugger // debugger
bpmnModeler.getDefinitions().rootElements[0].flowElements?.forEach((n: any) => { console.log(bpmnModeler.getDefinitions().rootElements,"打印bpmnModeler.getDefinitions().rootElements[0]");
//芋道这里取值是rootElements[0].flowElements
bpmnModeler.getDefinitions().rootElements[1].flowElements?.forEach((n: any) => {
console.log(n,"打印nnnnnnnnnnnnnnnnn");
let activity: any = activityList.find((m: any) => m.key === n.id) // 找到对应的活动 let activity: any = activityList.find((m: any) => m.key === n.id) // 找到对应的活动
if (!activity) { if (!activity) {
return return
@@ -154,7 +159,8 @@ const highlightDiagram = async () => {
} }
} }
}) })
} else if (n.$type === 'bpmn:ExclusiveGateway') { }
else if (n.$type === 'bpmn:ExclusiveGateway') {
// 排它网关 // 排它网关
// 设置【bpmn:ExclusiveGateway】排它网关的高亮 // 设置【bpmn:ExclusiveGateway】排它网关的高亮
canvas.addMarker(n.id, getActivityHighlightCss(activity)) canvas.addMarker(n.id, getActivityHighlightCss(activity))
@@ -179,7 +185,8 @@ const highlightDiagram = async () => {
if (matchNN && matchActivity) { if (matchNN && matchActivity) {
canvas.addMarker(matchNN.id, getActivityHighlightCss(matchActivity)) canvas.addMarker(matchNN.id, getActivityHighlightCss(matchActivity))
} }
} else if (n.$type === 'bpmn:ParallelGateway') { }
else if (n.$type === 'bpmn:ParallelGateway') {
// 并行网关 // 并行网关
// 设置【bpmn:ParallelGateway】并行网关的高亮 // 设置【bpmn:ParallelGateway】并行网关的高亮
canvas.addMarker(n.id, getActivityHighlightCss(activity)) canvas.addMarker(n.id, getActivityHighlightCss(activity))
@@ -192,7 +199,8 @@ const highlightDiagram = async () => {
canvas.addMarker(nn.targetRef.id, getActivityHighlightCss(targetActivity)) canvas.addMarker(nn.targetRef.id, getActivityHighlightCss(targetActivity))
} }
}) })
} else if (n.$type === 'bpmn:StartEvent') { }
else if (n.$type === 'bpmn:StartEvent') {
// 开始节点 // 开始节点
canvas.addMarker(n.id, 'highlight') canvas.addMarker(n.id, 'highlight')
n.outgoing?.forEach((nn) => { n.outgoing?.forEach((nn) => {
@@ -204,13 +212,15 @@ const highlightDiagram = async () => {
canvas.addMarker(n.id, 'highlight') // 高亮【bpmn:StartEvent】开始节点自己 canvas.addMarker(n.id, 'highlight') // 高亮【bpmn:StartEvent】开始节点自己
} }
}) })
} else if (n.$type === 'bpmn:EndEvent') { }
else if (n.$type === 'bpmn:EndEvent') {
// 结束节点 // 结束节点
if (!processInstance.value || processInstance.value.status === 1) { if (!processInstance.value || processInstance.value.status === 1) {
return return
} }
canvas.addMarker(n.id, getResultCss(processInstance.value.status)) canvas.addMarker(n.id, getResultCss(processInstance.value.status))
} else if (n.$type === 'bpmn:ServiceTask') { }
else if (n.$type === 'bpmn:ServiceTask') {
//服务任务 //服务任务
if (activity.startTime > 0 && activity.endTime === 0) { if (activity.startTime > 0 && activity.endTime === 0) {
//进入执行,标识进行色 //进入执行,标识进行色
@@ -224,7 +234,8 @@ const highlightDiagram = async () => {
canvas.addMarker(out.id, getResultCss(2)) canvas.addMarker(out.id, getResultCss(2))
}) })
} }
} else if (n.$type === 'bpmn:SequenceFlow') { }
else if (n.$type === 'bpmn:SequenceFlow') {
let targetActivity = activityList.find((m: any) => m.key === n.targetRef.id) let targetActivity = activityList.find((m: any) => m.key === n.targetRef.id)
if (targetActivity) { if (targetActivity) {
canvas.addMarker(n.id, getActivityHighlightCss(targetActivity)) canvas.addMarker(n.id, getActivityHighlightCss(targetActivity))
@@ -279,7 +290,7 @@ const getActivityOutgoing = (activity) => {
// 如果没有则遍历获得起点为它的【bpmn:SequenceFlow】节点们。原因是bpmn-js 的 UserTask 拿不到 outgoing // 如果没有则遍历获得起点为它的【bpmn:SequenceFlow】节点们。原因是bpmn-js 的 UserTask 拿不到 outgoing
const flowElements = bpmnModeler.getDefinitions().rootElements[0].flowElements const flowElements = bpmnModeler.getDefinitions().rootElements[0].flowElements
const outgoing: any[] = [] const outgoing: any[] = []
flowElements.forEach((item: any) => { flowElements?.forEach((item: any) => {
if (item.$type !== 'bpmn:SequenceFlow') { if (item.$type !== 'bpmn:SequenceFlow') {
return return
} }

View File

@@ -1,56 +1,65 @@
<template> <template>
<el-card v-loading="loading" class="box-card"> <el-card v-loading="loading" class="box-card">
<template #header> <template #header>
<span class="el-icon-picture-outline">流程图</span> <span class="el-icon-picture-outline">流程图</span>
</template> </template>
<MyProcessViewer <MyProcessViewer
key="designer" key="designer"
:activityData="activityList" :activityData="activityList"
:prefix="bpmnControlForm.prefix" :prefix="bpmnControlForm.prefix"
:processInstanceData="processInstance" :processInstanceData="processInstance"
:taskData="tasks" :taskData="tasks"
:value="bpmnXml" :value="bpmnXml"
v-bind="bpmnControlForm" v-bind="bpmnControlForm"
/> />
</el-card> </el-card>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted, provide, ref, getCurrentInstance, reactive, watch, unref,nextTick } from 'vue' import { onMounted, provide, ref, getCurrentInstance, reactive, watch, unref, nextTick ,defineExpose} from 'vue'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import { propTypes } from '@/utils/propTypes' import { propTypes } from '@/utils/propTypes'
import { MyProcessViewer } from '@/components/bpmnProcessDesigner/package' import { MyProcessViewer } from '@/components/bpmnProcessDesigner/package'
import { getTaskListByReturn } from '@/api/bpm-boot/activity' import { getTaskListByReturn } from '@/api/bpm-boot/activity'
import { getMap } from 'echarts'
defineOptions({ name: 'BpmProcessInstanceBpmnViewer' }) defineOptions({ name: 'BpmProcessInstanceBpmnViewer' })
const props = defineProps({ const props = defineProps({
loading: propTypes.bool, // 是否加载中 loading: propTypes.bool, // 是否加载中
id: propTypes.string, // 流程实例的编号 id: propTypes.string, // 流程实例的编号
processInstance: propTypes.any, // 流程实例的信息 processInstance: propTypes.any, // 流程实例的信息
tasks: propTypes.array, // 流程任务的数组 tasks: propTypes.array, // 流程任务的数组
bpmnXml: propTypes.string // BPMN XML bpmnXml: propTypes.string // BPMN XML
}) })
const bpmnControlForm = ref({ const bpmnControlForm = ref({
prefix: 'flowable' prefix: 'flowable'
}) })
const activityList = ref([]) // 任务列表 const activityList = ref([]) // 任务列表
const getMapList = () => {
/** 只有 loading 完成时,才去加载流程列表 */ console.log('执行力');
watch( if (props.id) {
() => props.loading, nextTick(()=>{
async (value) => { getTaskListByReturn(props.id).then(res => {
if (value && props.id) { activityList.value = res.data
await getTaskListByReturn(props.id).then(res =>{ })
activityList.value = res.data })
})
} }
} }
) /** 只有 loading 完成时,才去加载流程列表 */
// watch(
// () => props.id
// async val => {
// await getTaskListByReturn(val).then(res => {
// activityList.value = res.data
// })
// }
// )
defineExpose({ getMapList })
</script> </script>
<style> <style>
.box-card { .box-card {
width: 100%; width: 100%;
margin-bottom: 20px; margin-bottom: 20px;
} }
</style> </style>

View File

@@ -1,8 +1,9 @@
<!-- 流程详情页面 tab切换 -->
<template> <template>
<div class="default-main"> <div class="default-main" style="overflow: hidden;">
<!--返回按钮--> <!--返回按钮-->
<back-component style="margin: 8px; position: absolute; z-index: 10; top: -3px; right: 2px" /> <back-component style="margin: 8px; position: absolute; z-index: 10; top: -3px; right: 2px" />
<el-tabs type="border-card" v-model="tab"> <el-tabs type="border-card" v-model="tab" @tab-click="handleClickTab">
<el-tab-pane label="流程审核" name="流程审核" v-if="runningTasks.length > 0"> <el-tab-pane label="流程审核" name="流程审核" v-if="runningTasks.length > 0">
<el-card <el-card
v-for="(item, index) in runningTasks" v-for="(item, index) in runningTasks"
@@ -115,15 +116,17 @@
@refresh="getTaskList" @refresh="getTaskList"
/> />
</el-tab-pane> </el-tab-pane>
<!-- <el-tab-pane label='流程图'>--> <el-tab-pane label="流程图" name="流程图">
<!-- &lt;!&ndash; 高亮流程图 &ndash;&gt;--> 高亮流程图
<!-- &lt;!&ndash; <ProcessInstanceBpmnViewer&ndash;&gt;--> <ProcessInstanceBpmnViewer
<!-- &lt;!&ndash; :id="`${id}`"&ndash;&gt;--> ref="mapRef"
<!-- &lt;!&ndash; :bpmn-xml="bpmnXml"&ndash;&gt;--> :id="`${id}`"
<!-- &lt;!&ndash; :loading="processInstanceLoading"&ndash;&gt;--> :bpmn-xml="bpmnXml"
<!-- &lt;!&ndash; :process-instance="processInstance"&ndash;&gt;--> :loading="processInstanceLoading"
<!-- &lt;!&ndash; :tasks="tasks"&ndash;&gt;--> :process-instance="processInstance"
<!-- &lt;!&ndash; />&ndash;&gt;</el-tab-pane>--> :tasks="tasks"
/>
</el-tab-pane>
</el-tabs> </el-tabs>
<ContentWrap> <ContentWrap>
<!-- 弹窗转派审批人 --> <!-- 弹窗转派审批人 -->
@@ -138,7 +141,7 @@
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted, provide, ref, getCurrentInstance, reactive, watch, unref, nextTick ,markRaw} from 'vue' import { onMounted, provide, ref, getCurrentInstance, reactive, watch, unref, nextTick, markRaw } from 'vue'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import { useUserStore } from '@/stores/modules/user' import { useUserStore } from '@/stores/modules/user'
import ContentWrap from '@/components/ContentWrap/src/ContentWrap.vue' import ContentWrap from '@/components/ContentWrap/src/ContentWrap.vue'
@@ -272,6 +275,13 @@ const getDetail = () => {
// 2. 获得流程任务列表(审批记录) // 2. 获得流程任务列表(审批记录)
getTaskList() getTaskList()
} }
//tab切换
const mapRef=ref(null)
const handleClickTab = (tab:any, event:any) => {
if(tab.props.name=='流程图'){
mapRef.value.getMapList()
}
}
/** 加载流程实例 */ /** 加载流程实例 */
const BusinessFormComponent = ref(null) // 异步组件 const BusinessFormComponent = ref(null) // 异步组件
@@ -299,11 +309,15 @@ const getProcessInstance = async () => {
}) })
} else { } else {
// 注意data.processDefinition.formCustomViewPath 是组件的全路径,例如说:/crm/contract/detail/index.vue // 注意data.processDefinition.formCustomViewPath 是组件的全路径,例如说:/crm/contract/detail/index.vue
//用markRaw解决因使用ref定义组件导致组件被标记成响应式对象造成性能开销警告的问题
BusinessFormComponent.value = markRaw(registerComponent(data.processDefinition.formCustomViewPath)) BusinessFormComponent.value = markRaw(registerComponent(data.processDefinition.formCustomViewPath))
} }
// 加载流程图 // 加载流程图
bpmnXml.value = (await getProcessDefinitionById(processDefinition.id))?.bpmnXml await getProcessDefinitionById(processDefinition.id).then(res => {
bpmnXml.value = res.data?.bpmnXml
})
console.log(bpmnXml.value, '流程图数据')
} finally { } finally {
processInstanceLoading.value = false processInstanceLoading.value = false
} }
@@ -402,3 +416,9 @@ onMounted(async () => {
} }
}) })
</script> </script>
<style lang="scss" scoped>
::v-deep .el-tab-pane{
height: calc(100vh - 200px) !important;
overflow: auto !important;
}
</style>