From d1c199d4bf895e3a1c8ecfbb1414c44c4a0fc718 Mon Sep 17 00:00:00 2001
From: LiuHao <liuhaoai545@gmail.com>
Date: 星期五, 08 三月 2024 18:22:28 +0800
Subject: [PATCH] update 优化流程预览
---
src/components/BpmnView/index.vue | 140 ++++++++++++----------
src/api/workflow/processInstance/index.ts | 2
src/components/Process/approvalRecord.vue | 176 ++++++++++++++++-------------
3 files changed, 172 insertions(+), 146 deletions(-)
diff --git a/src/api/workflow/processInstance/index.ts b/src/api/workflow/processInstance/index.ts
index 9a417c1..80f122f 100644
--- a/src/api/workflow/processInstance/index.ts
+++ b/src/api/workflow/processInstance/index.ts
@@ -41,7 +41,7 @@
/**
* 閫氳繃娴佺▼瀹炰緥id鑾峰彇鍘嗗彶娴佺▼鍥捐繍琛屼腑锛屽巻鍙茬瓑鑺傜偣
*/
-export const getHistoryList = (instanceId: string) => {
+export const getHistoryList = (instanceId: string): AxiosPromise<Record<string, any>> => {
return request({
url: `/workflow/processInstance/getHistoryList/${instanceId}` + '?t' + Math.random(),
method: 'get'
diff --git a/src/components/BpmnView/index.vue b/src/components/BpmnView/index.vue
index ee0eaa6..75a89cd 100644
--- a/src/components/BpmnView/index.vue
+++ b/src/components/BpmnView/index.vue
@@ -1,37 +1,35 @@
<template>
- <el-dialog v-if="bpmnVisible" v-model="bpmnVisible" title="娴佺▼杩涘害" append-to-body width="90%" @opened="init(undefined)">
- <div v-loading="loading" class="bpmnDialogContainers">
- <el-header style="border-bottom: 1px solid rgb(218 218 218); height: auto">
- <div class="header-div">
- <div>
- <el-tooltip effect="dark" content="鑷�傚簲灞忓箷" placement="bottom">
- <el-button size="small" icon="Rank" @click="fitViewport" />
- </el-tooltip>
- <el-tooltip effect="dark" content="鏀惧ぇ" placement="bottom">
- <el-button size="small" icon="ZoomIn" @click="zoomViewport(true)" />
- </el-tooltip>
- <el-tooltip effect="dark" content="缂╁皬" placement="bottom">
- <el-button size="small" icon="ZoomOut" @click="zoomViewport(false)" />
- </el-tooltip>
- </div>
- <div>
- <div class="tips-label">
- <div class="un-complete">鏈畬鎴�</div>
- <div class="in-progress">杩涜涓�</div>
- <div class="complete">宸插畬鎴�</div>
- </div>
+ <div v-loading="loading" class="bpmnDialogContainers">
+ <el-header style="border-bottom: 1px solid rgb(218 218 218); height: auto">
+ <div class="header-div">
+ <div>
+ <el-tooltip effect="dark" content="鑷�傚簲灞忓箷" placement="bottom">
+ <el-button size="small" icon="Rank" @click="fitViewport" />
+ </el-tooltip>
+ <el-tooltip effect="dark" content="鏀惧ぇ" placement="bottom">
+ <el-button size="small" icon="ZoomIn" @click="zoomViewport(true)" />
+ </el-tooltip>
+ <el-tooltip effect="dark" content="缂╁皬" placement="bottom">
+ <el-button size="small" icon="ZoomOut" @click="zoomViewport(false)" />
+ </el-tooltip>
+ </div>
+ <div>
+ <div class="tips-label">
+ <div class="un-complete">鏈畬鎴�</div>
+ <div class="in-progress">杩涜涓�</div>
+ <div class="complete">宸插畬鎴�</div>
</div>
</div>
- </el-header>
- <div class="flow-containers">
- <el-container class="bpmn-el-container" style="align-items: stretch">
- <el-main style="padding: 0">
- <div ref="canvas" class="canvas" />
- </el-main>
- </el-container>
</div>
+ </el-header>
+ <div class="flow-containers">
+ <el-container class="bpmn-el-container" style="align-items: stretch">
+ <el-main style="padding: 0">
+ <div ref="canvas" class="canvas" />
+ </el-main>
+ </el-container>
</div>
- </el-dialog>
+ </div>
</template>
<script lang="ts" setup>
@@ -53,10 +51,11 @@
const loading = ref(false);
const bpmnVisible = ref(true);
const historyList = ref([]);
+
const init = (instanceId) => {
loading.value = true;
bpmnVisible.value = true;
- nextTick(() => {
+ nextTick(async () => {
if (modeler.value) modeler.value.destroy();
modeler.value = new BpmnViewer({
container: canvas.value,
@@ -69,14 +68,11 @@
MoveCanvasModule
] as ModuleDeclaration[]
});
- processApi.getHistoryList(instanceId).then((resp) => {
- xml.value = resp.data.xml;
- taskList.value = resp.data.taskList;
- historyList.value = resp.data.historyList;
- // createDiagram(xml);
- console.log(resp);
- });
- createDiagram(defaultXML);
+ const resp = await processApi.getHistoryList(instanceId);
+ xml.value = resp.data.xml;
+ taskList.value = resp.data.taskList;
+ historyList.value = resp.data.historyList;
+ await createDiagram(xml.value);
loading.value = false;
});
};
@@ -89,7 +85,7 @@
loading.value = false;
addEventBusListener();
} catch (err) {
- //console.error(err.message, err.warnings)
+ console.log(err);
}
};
const addEventBusListener = () => {
@@ -150,8 +146,10 @@
//閫掑綊涓婅壊
const bpmnNodeList = (flowElements, canvas) => {
flowElements.forEach((n) => {
+ console.log(n);
if (n.$type === 'bpmn:UserTask') {
const completeTask = taskList.value.find((m) => m.key === n.id);
+ console.log(completeTask);
if (completeTask) {
canvas.addMarker(n.id, completeTask.completed ? 'highlight' : 'highlight-todo');
n.outgoing?.forEach((nn) => {
@@ -162,19 +160,19 @@
canvas.addMarker(nn.id, completeTask.completed ? 'highlight' : 'highlight-todo');
canvas.addMarker(nn.targetRef.id, completeTask.completed ? 'highlight' : 'highlight-todo');
nn.targetRef.outgoing.forEach((e) => {
- getway(e.id, e.targetRef.$type, e.targetRef.id, canvas, completeTask.completed);
+ gateway(e.id, e.targetRef.$type, e.targetRef.id, canvas, completeTask.completed);
});
} else if (nn.targetRef.$type === 'bpmn:ParallelGateway') {
canvas.addMarker(nn.id, completeTask.completed ? 'highlight' : 'highlight-todo');
canvas.addMarker(nn.targetRef.id, completeTask.completed ? 'highlight' : 'highlight-todo');
nn.targetRef.outgoing.forEach((e) => {
- getway(e.id, e.targetRef.$type, e.targetRef.id, canvas, completeTask.completed);
+ gateway(e.id, e.targetRef.$type, e.targetRef.id, canvas, completeTask.completed);
});
} else if (nn.targetRef.$type === 'bpmn:InclusiveGateway') {
canvas.addMarker(nn.id, completeTask.completed ? 'highlight' : 'highlight-todo');
canvas.addMarker(nn.targetRef.id, completeTask.completed ? 'highlight' : 'highlight-todo');
nn.targetRef.outgoing.forEach((e) => {
- getway(e.id, e.targetRef.$type, e.targetRef.id, canvas, completeTask.completed);
+ gateway(e.id, e.targetRef.$type, e.targetRef.id, canvas, completeTask.completed);
});
}
});
@@ -207,15 +205,19 @@
}
bpmnNodeList(n.flowElements, canvas);
} else if (n.$type === 'bpmn:StartEvent') {
- n.outgoing.forEach((nn) => {
- const completeTask = taskList.value.find((m) => m.key === nn.targetRef.id);
- if (completeTask) {
- canvas.addMarker(nn.id, 'highlight');
- canvas.addMarker(n.id, 'highlight');
- return;
- }
- });
+ canvas.addMarker(n.id, 'startEvent');
+ if (n.outgoing) {
+ n.outgoing.forEach((nn) => {
+ const completeTask = taskList.value.find((m) => m.key === nn.targetRef.id);
+ if (completeTask) {
+ canvas.addMarker(nn.id, 'highlight');
+ canvas.addMarker(n.id, 'highlight');
+ // return;
+ }
+ });
+ }
} else if (n.$type === 'bpmn:EndEvent') {
+ canvas.addMarker(n.id, 'endEvent');
const completeTask = taskList.value.find((m) => m.key === n.id);
if (completeTask) {
canvas.addMarker(completeTask.key, 'highlight');
@@ -225,7 +227,7 @@
}
});
};
-const getway = (id, targetRefType, targetRefId, canvas, completed) => {
+const gateway = (id, targetRefType, targetRefId, canvas, completed) => {
if (targetRefType === 'bpmn:ExclusiveGateway') {
canvas.addMarker(id, completed ? 'highlight' : 'highlight-todo');
canvas.addMarker(targetRefId, completed ? 'highlight' : 'highlight-todo');
@@ -239,9 +241,12 @@
canvas.addMarker(targetRefId, completed ? 'highlight' : 'highlight-todo');
}
};
+defineExpose({
+ init
+});
</script>
-<style lang="scss">
+<style lang="scss" scoped>
.canvas {
width: 100%;
height: 100%;
@@ -260,7 +265,7 @@
font-size: 12px;
}
.un-complete {
- border: 1px dashed #000;
+ border: 1px solid #000;
}
.in-progress {
background-color: rgb(255, 237, 204);
@@ -268,7 +273,7 @@
}
.complete {
background-color: rgb(204, 230, 204);
- border: 1px dashed green;
+ border: 1px solid green;
}
}
}
@@ -301,55 +306,60 @@
.load {
margin-right: 10px;
}
- .el-form-item__label {
+ :deep(.el-form-item__label) {
font-size: 13px;
}
- .djs-palette {
+ :deep(.djs-palette) {
left: 0 !important;
top: 0;
border-top: none;
}
- .djs-container svg {
+ :deep(.djs-container svg) {
min-height: 650px;
}
- .highlight.djs-shape .djs-visual > :nth-child(1) {
+ :deep(.startEvent.djs-shape .djs-visual > :nth-child(1)) {
+ fill: #77df6d !important;
+ }
+ :deep(.endEvent.djs-shape .djs-visual > :nth-child(1)) {
+ fill: #ee7b77 !important;
+ }
+ :deep(.highlight.djs-shape .djs-visual > :nth-child(1)) {
fill: green !important;
stroke: green !important;
fill-opacity: 0.2 !important;
}
- .highlight.djs-shape .djs-visual > :nth-child(2) {
+ :deep(.highlight.djs-shape .djs-visual > :nth-child(2)) {
fill: green !important;
}
- .highlight.djs-shape .djs-visual > path {
+ :deep(.highlight.djs-shape .djs-visual > path) {
fill: green !important;
fill-opacity: 0.2 !important;
stroke: green !important;
}
- .highlight.djs-connection > .djs-visual > path {
+ :deep(.highlight.djs-connection > .djs-visual > path) {
stroke: green !important;
}
- .highlight-todo.djs-connection > .djs-visual > path {
+ :deep(.highlight-todo.djs-connection > .djs-visual > path) {
stroke: orange !important;
stroke-dasharray: 4px !important;
fill-opacity: 0.2 !important;
marker-end: url(#sequenceflow-end-_E7DFDF-_E7DFDF-803g1kf6zwzmcig1y2ulm5egr);
}
- .highlight-todo.djs-shape .djs-visual > :nth-child(1) {
+ :deep(.highlight-todo.djs-shape .djs-visual > :nth-child(1)) {
fill: orange !important;
stroke: orange !important;
stroke-dasharray: 4px !important;
fill-opacity: 0.2 !important;
}
}
-.verlays {
+:deep(.verlays) {
width: 250px;
background: rgb(102, 102, 102);
border-radius: 4px;
border: 1px solid #ebeef5;
- //padding: 12px;
color: #fff;
padding: 15px 10px;
p {
diff --git a/src/components/Process/approvalRecord.vue b/src/components/Process/approvalRecord.vue
index 2c43dc5..88dccf2 100644
--- a/src/components/Process/approvalRecord.vue
+++ b/src/components/Process/approvalRecord.vue
@@ -1,86 +1,90 @@
<template>
- <el-dialog v-model="visible" draggable title="瀹℃壒璁板綍" :width="props.width" :height="props.height" append-to-body :close-on-click-modal="false">
- <el-tabs v-model="tabActiveName" class="demo-tabs">
- <el-tab-pane label="娴佺▼鍥�" name="bpmn">
- <div v-loading="loading">
- <div style="width: 100%; height: 300px; overflow: auto; position: relative">
- <div
- v-for="(graphic, index) in graphicInfoVos"
- :key="index"
- :style="{
- position: 'absolute',
- left: `${graphic.x}px`,
- top: `${graphic.y}px`,
- width: `${graphic.width}px`,
- height: `${graphic.height}px`,
- cursor: 'pointer',
- zIndex: 99
- }"
- @mouseover="handleMouseOver(graphic)"
- @mouseleave="handleMouseLeave()"
- ></div>
- <!-- 寮瑰嚭鐨� div 鍏冪礌 -->
- <div
- v-show="popupVisible"
- class="triangle"
- :style="{
- position: 'absolute',
- left: `${graphicX}px`,
- top: `${graphicY}px`,
- backgroundColor: '#fff',
- padding: '10px',
- zIndex: 100
- }"
- >
- <p>瀹℃壒浜哄憳: {{ nodeInfo.nickName }}</p>
- <p>鑺傜偣鐘舵�侊細{{ nodeInfo.status }}</p>
- <p>寮�濮嬫椂闂达細{{ nodeInfo.startTime }}</p>
- <p>缁撴潫鏃堕棿锛歿{ nodeInfo.endTime }}</p>
- <p>瀹℃壒鑰楁椂锛歿{ nodeInfo.runDuration }}</p>
- </div>
- <el-image :src="src" />
+ <div class="container">
+ <el-dialog v-model="visible" draggable title="瀹℃壒璁板綍" :width="props.width" :height="props.height" :close-on-click-modal="false">
+ <el-tabs v-model="tabActiveName" class="demo-tabs">
+ <el-tab-pane label="娴佺▼鍥�" name="bpmn">
+ <!-- <div v-loading="loading">-->
+ <!-- <div style="width: 100%; height: 300px; overflow: auto; position: relative">-->
+ <!-- <div-->
+ <!-- v-for="(graphic, index) in graphicInfoVos"-->
+ <!-- :key="index"-->
+ <!-- :style="{-->
+ <!-- position: 'absolute',-->
+ <!-- left: `${graphic.x}px`,-->
+ <!-- top: `${graphic.y}px`,-->
+ <!-- width: `${graphic.width}px`,-->
+ <!-- height: `${graphic.height}px`,-->
+ <!-- cursor: 'pointer',-->
+ <!-- zIndex: 99-->
+ <!-- }"-->
+ <!-- @mouseover="handleMouseOver(graphic)"-->
+ <!-- @mouseleave="handleMouseLeave()"-->
+ <!-- ></div>-->
+ <!-- <!– 寮瑰嚭鐨� div 鍏冪礌 –>-->
+ <!-- <div-->
+ <!-- v-show="popupVisible"-->
+ <!-- class="triangle"-->
+ <!-- :style="{-->
+ <!-- position: 'absolute',-->
+ <!-- left: `${graphicX}px`,-->
+ <!-- top: `${graphicY}px`,-->
+ <!-- backgroundColor: '#fff',-->
+ <!-- padding: '10px',-->
+ <!-- zIndex: 100-->
+ <!-- }"-->
+ <!-- >-->
+ <!-- <p>瀹℃壒浜哄憳: {{ nodeInfo.nickName }}</p>-->
+ <!-- <p>鑺傜偣鐘舵�侊細{{ nodeInfo.status }}</p>-->
+ <!-- <p>寮�濮嬫椂闂达細{{ nodeInfo.startTime }}</p>-->
+ <!-- <p>缁撴潫鏃堕棿锛歿{ nodeInfo.endTime }}</p>-->
+ <!-- <p>瀹℃壒鑰楁椂锛歿{ nodeInfo.runDuration }}</p>-->
+ <!-- </div>-->
+ <!-- <el-image :src="src" />-->
+ <!-- </div>-->
+ <!-- </div>-->
+ <BpmnView ref="bpmnViewRef"></BpmnView>
+ </el-tab-pane>
+ <el-tab-pane label="瀹℃壒淇℃伅" name="info">
+ <div>
+ <el-table :data="historyList" style="width: 100%" border fit max-height="570">
+ <el-table-column type="index" label="搴忓彿" align="center" width="50"></el-table-column>
+ <el-table-column prop="name" label="浠诲姟鍚嶇О" sortable align="center"></el-table-column>
+ <el-table-column prop="nickName" label="鍔炵悊浜�" sortable align="center"></el-table-column>
+ <el-table-column label="鐘舵��" sortable align="center">
+ <template #default="scope">
+ <el-tag type="success">{{ scope.row.statusName }}</el-tag>
+ </template>
+ </el-table-column>
+ <el-table-column prop="comment" label="瀹℃壒鎰忚" sortable align="center"></el-table-column>
+ <el-table-column prop="attachmentList" label="闄勪欢" sortable align="center">
+ <template #default="scope">
+ <el-popover v-if="scope.row.attachmentList && scope.row.attachmentList.length > 0" placement="right" :width="310" trigger="click">
+ <template #reference>
+ <el-button style="margin-right: 16px">闄勪欢</el-button>
+ </template>
+ <el-table border :data="scope.row.attachmentList">
+ <el-table-column prop="name" width="202" :show-overflow-tooltip="true" label="闄勪欢鍚嶇О"></el-table-column>
+ <el-table-column prop="name" width="80" align="center" :show-overflow-tooltip="true" label="鎿嶄綔">
+ <template #default="tool">
+ <el-button type="text" @click="handleDownload(tool.row.contentId)">涓嬭浇</el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+ </el-popover>
+ </template>
+ </el-table-column>
+ <el-table-column prop="startTime" label="寮�濮嬫椂闂�" sortable align="center"></el-table-column>
+ <el-table-column prop="endTime" label="缁撴潫鏃堕棿" sortable align="center"></el-table-column>
+ <el-table-column prop="runDuration" label="杩愯鏃堕暱" sortable align="center"></el-table-column>
+ </el-table>
</div>
- </div>
- </el-tab-pane>
- <el-tab-pane label="瀹℃壒淇℃伅" name="info">
- <div>
- <el-table :data="historyList" style="width: 100%" border fit max-height="570">
- <el-table-column type="index" label="搴忓彿" align="center" width="50"></el-table-column>
- <el-table-column prop="name" label="浠诲姟鍚嶇О" sortable align="center"></el-table-column>
- <el-table-column prop="nickName" label="鍔炵悊浜�" sortable align="center"></el-table-column>
- <el-table-column label="鐘舵��" sortable align="center">
- <template #default="scope">
- <el-tag type="success">{{ scope.row.statusName }}</el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="comment" label="瀹℃壒鎰忚" sortable align="center"></el-table-column>
- <el-table-column prop="attachmentList" label="闄勪欢" sortable align="center">
- <template #default="scope">
- <el-popover v-if="scope.row.attachmentList && scope.row.attachmentList.length > 0" placement="right" :width="310" trigger="click">
- <template #reference>
- <el-button style="margin-right: 16px">闄勪欢</el-button>
- </template>
- <el-table border :data="scope.row.attachmentList">
- <el-table-column prop="name" width="202" :show-overflow-tooltip="true" label="闄勪欢鍚嶇О"></el-table-column>
- <el-table-column prop="name" width="80" align="center" :show-overflow-tooltip="true" label="鎿嶄綔">
- <template #default="tool">
- <el-button type="text" @click="handleDownload(tool.row.contentId)">涓嬭浇</el-button>
- </template>
- </el-table-column>
- </el-table>
- </el-popover>
- </template>
- </el-table-column>
- <el-table-column prop="startTime" label="寮�濮嬫椂闂�" sortable align="center"></el-table-column>
- <el-table-column prop="endTime" label="缁撴潫鏃堕棿" sortable align="center"></el-table-column>
- <el-table-column prop="runDuration" label="杩愯鏃堕暱" sortable align="center"></el-table-column>
- </el-table>
- </div>
- </el-tab-pane>
- </el-tabs>
- </el-dialog>
+ </el-tab-pane>
+ </el-tabs>
+ </el-dialog>
+ </div>
</template>
<script lang="ts" setup>
+import BpmnView from '@/components/BpmnView/index.vue';
import processApi from '@/api/workflow/processInstance';
import { propTypes } from '@/utils/propTypes';
@@ -111,6 +115,8 @@
const graphicY = ref<number | string>(0);
const tabActiveName = ref('bpmn');
+const bpmnViewRef = ref<BpmnView>();
+
//鍒濆鍖栨煡璇㈠鎵硅褰�
const init = async (instanceId: string) => {
visible.value = true;
@@ -126,6 +132,9 @@
nodeListInfo.value = resp.data.nodeListInfo;
deleteReason.value = resp.data.deleteReason;
loading.value = false;
+ });
+ await nextTick(() => {
+ bpmnViewRef.value.init(instanceId);
});
};
//鎮诞浜嬩欢
@@ -163,7 +172,7 @@
init
});
</script>
-<style scoped>
+<style lang="scss" scoped>
.triangle {
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
border-radius: 6px;
@@ -177,4 +186,11 @@
border: 15px solid;
border-color: transparent #fff transparent transparent;
}
+
+.container {
+ :deep(.el-dialog .el-dialog__body) {
+ max-height: calc(100vh - 300px) !important;
+ min-height: calc(100vh - 300px) !important;
+ }
+}
</style>
--
Gitblit v1.9.3