From d088628a4b421e7e0a8363b8b75529d8b2ecfe89 Mon Sep 17 00:00:00 2001 From: lyh <liuyuanheng@xalxzn.com> Date: 星期一, 24 二月 2025 10:07:14 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/master' --- src/views/flowable/components/HistoricDetail.vue | 343 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 343 insertions(+), 0 deletions(-) diff --git a/src/views/flowable/components/HistoricDetail.vue b/src/views/flowable/components/HistoricDetail.vue new file mode 100644 index 0000000..be707cc --- /dev/null +++ b/src/views/flowable/components/HistoricDetail.vue @@ -0,0 +1,343 @@ +<style lang="less"> +</style> +<template> + <div class="search"> + <a-card> + <p slot="title"> + <span>娴佺▼鍥�</span> + </p> + <div :style="{height: svgHeight}" v-if="svgShow"> + <bpmnModeler class="svg" ref="bpm" :xml="xmlData" :is-view="true"></bpmnModeler> + </div> + </a-card> + <a-card style="margin-top:10px;"> + <p slot="title"> + <span>娴佺▼瀹℃壒杩涘害鍘嗗彶</span> + </p> + <a-row style="position:relative"> + <div class="block"> + <a-timeline> + <a-timeline-item + v-for="(item,index ) in flowRecordList" + :key="index" + :color="setColor(item.finishTime)" + > + <p style="font-weight: 700;">{{item.taskName}} + <i v-if="!item.finishTime" style="color: orange">(寰呭姙涓�傘�傘��)</i> + </p> + + <a-card :body-style="{ padding: '10px' }"> + <label v-if="item.assigneeName&&item.finishTime" style="font-weight: normal;margin-right: 30px;">瀹為檯鍔炵悊浜猴細 {{item.assigneeName}} <a-tag type="info" size="mini">{{item.deptName}}</a-tag></label> + <label v-if="item.candidate" style="font-weight: normal;margin-right: 30px;">鍊欓�夊姙鐞嗕汉锛� {{item.candidate}}</label> + <label style="font-weight: normal">鎺ユ敹鏃堕棿锛� </label><label style="color:#8a909c;font-weight: normal">{{item.createTime}}</label> + <label v-if="item.finishTime" style="margin-left: 30px;font-weight: normal">鍔炵粨鏃堕棿锛� </label><label style="color:#8a909c;font-weight: normal">{{item.finishTime}}</label> + <label v-if="item.duration" style="margin-left: 30px;font-weight: normal">鑰楁椂锛� </label><label style="color:#8a909c;font-weight: normal">{{item.duration}}</label> + + <p v-if="item.comment"> +<!-- 1 姝e父鎰忚 2 閫�鍥炴剰瑙� 3 椹冲洖鎰忚 --> + <a-tag color="green" v-if="item.comment.type === '1'"> + <span v-if="item.comment.comment!='閲嶆柊鎻愪氦'">閫氳繃锛�</span> + {{item.comment.comment}} + </a-tag> + <a-tag color="orange" v-if="item.comment.type === '2'">閫�鍥烇細 {{item.comment.comment}}</a-tag> + <a-tag color="red" v-if="item.comment.type === '3'">椹冲洖锛� {{item.comment.comment}}</a-tag> + </p> + </a-card> + </a-timeline-item> + </a-timeline> + </div> + </a-row> + </a-card> + </div> +</template> + +<script> +import {flowRecord} from "@views/flowable/api/finished"; +import {getFlowViewerByDataId, readXmlByDataId} from "@views/flowable/api/definition"; +import bpmnModeler from "workflow-bpmn-modeler"; + +export default { + name: 'HistoricDetail', + components: { + bpmnModeler, + }, + props: { + /**/ + dataId: { + type: String, + default: '', + required: true + }, + + }, + data() { + return { + taskList:[], + flowRecordList: [], // 娴佺▼娴佽浆鏁版嵁 + formData:{}, + xmlData:'', + type: 0, + loading: false, // 琛ㄥ崟鍔犺浇鐘舵�� + loadingImg: false, + data: [], + id: '', + imgUrl: '', + backRoute: '', + svgHeight:'', + svgShow: true + }; + }, + created() { + this.init(); + }, + watch: { + dataId: function(newval, oldName) { + this.init(); + } + }, + + methods: { + init() { + this.getFlowRecordList() + this.getModelDetail() + }, + /** xml 鏂囦欢 */ + getModelDetail() { + // 鍙戦�佽姹傦紝鑾峰彇xml + readXmlByDataId(this.dataId).then(res => { + this.xmlData = res.result + this.getFlowViewer() + setTimeout(()=>{ + this.fitViewport() + }) + }) + }, + // 娴佺▼杩涜鎯呭喌 + getFlowViewer() { + getFlowViewerByDataId(this.dataId).then(res => { + this.taskList = res.result || [] + this.fillColor(); + }) + }, + /** 娴佺▼娴佽浆璁板綍 */ + getFlowRecordList() { + const params = {dataId: this.dataId} + flowRecord(params).then(res => { + // console.log(res) + this.flowRecordList = res.result.flowList; + this.finishOrder() + // 娴佺▼杩囩▼涓笉瀛樺湪鍒濆鍖栬〃鍗� 鐩存帴璇诲彇鐨勬祦绋嬪彉閲忎腑瀛樺偍鐨勮〃鍗曞�� + if (res.result.formData) { + this.formData = res.result.formData; + } + }).catch(res => { + console.log(res) + }) + }, + //鏁寸悊椤哄簭锛屾妸寰呭姙鏀炬渶涓婇潰锛屽苟涓斿彧鐣欎竴涓紙涓嶇劧浼氱鏃朵細涔憋級 + finishOrder(){ + const list = [] + let noFinish = null + for (const flow of this.flowRecordList) { + if (flow.finishTime){ + // 鍔炵粨鐨勮妭鐐瑰悓鏃跺彇鏈夊疄闄呭姙鐞嗕汉鐨勶紝鍥犱负浼氱浼氬皢鎵�鏈夌殑澶氬疄渚嬮兘杩斿洖锛岄渶瑕佽繃婊� + if (flow.assigneeId){ + list.push(flow) + } + } else { + noFinish = flow + } + } + if (noFinish){ + const find = list.find(obj=>obj.taskDefKey == noFinish.taskDefKey); + if (find){ + noFinish.taskName = '銆愪細绛句腑銆�'+noFinish.taskName + } + this.flowRecordList = [noFinish,...list]; + } else { + this.flowRecordList = list; + } + + }, + setColor(val) { + if (val) { + return "#2bc418"; + } else { + return "#b3bdbb"; + } + }, + fillColor() { + const modeler = this.$refs.bpm.modeler; + const canvas = modeler.get('canvas') + modeler._definitions.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] + //鐢ㄦ埛浠诲姟 + if (n.$type === 'bpmn:UserTask') { + if (completeTask) { + canvas.addMarker(n.id, completeTask.completed ? 'highlight' : 'highlight-todo') + canvas.addMarker(n.id, completeTask.back ? 'highlight-back' : 'highlight-noback') + n.outgoing.forEach(nn => { + const targetTask = this.taskList.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') + canvas.addMarker(nn.targetRef.id, todoTask.completed ? 'highlight' : 'highlight-todo') + }else { + canvas.addMarker(nn.id, targetTask.completed ? 'highlight' : 'highlight-todo') + canvas.addMarker(nn.targetRef.id, targetTask.completed ? 'highlight' : 'highlight-todo') + } + } + }) + } + } + // 鎺掍粬缃戝叧 + else if (n.$type === 'bpmn:ExclusiveGateway') { + 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) + if (targetTask) { + + canvas.addMarker(nn.id, targetTask.completed ? 'highlight' : 'highlight-todo') + canvas.addMarker(nn.targetRef.id, targetTask.completed ? 'highlight' : 'highlight-todo') + } + + }) + } + + } + // 骞惰缃戝叧 + else if (n.$type === 'bpmn:ParallelGateway') { + if (completeTask) { + canvas.addMarker(n.id, completeTask.completed ? 'highlight' : 'highlight-todo') + n.outgoing.forEach(nn => { + debugger + const targetTask = this.taskList.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') + } + }) + } + } + else if (n.$type === 'bpmn:StartEvent') { + n.outgoing.forEach(nn => { + const completeTask = this.taskList.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') { + if (endTask.key === n.id && endTask.completed) { + canvas.addMarker(n.id, 'highlight') + return + } + } + }) + }, + // 璁╁浘鑳借嚜閫傚簲灞忓箷 + fitViewport() { + const modeler = this.$refs.bpm.modeler; + const canvas = modeler.get('canvas') + // this.zoom = this.modeler.get('canvas').zoom('fit-viewport') + if (this.svgHeight){ + document.querySelector('.canvas').style.height = this.svgHeight; + } + const bbox = document.querySelector('.flow-containers .viewport').getBBox() + const currentViewbox = modeler.get('canvas').viewbox() + if (!this.svgHeight){ + this.svgHeight = currentViewbox.inner.height + 'px' + this.svgShow = false + this.$nextTick(()=>{ + this.svgShow = true + }) + // this.fitViewport() + setTimeout(()=>{ + this.fitViewport() + }) + } + + const elementMid = { + x: bbox.x + bbox.width / 2 - 65, + y: bbox.y + bbox.height / 2 + } + // 璋冭妭浣嶇疆 + modeler.get('canvas').viewbox({ + x: elementMid.x - currentViewbox.width / 2 + 70, + y: elementMid.y - currentViewbox.height/2, + width: currentViewbox.width, + height: currentViewbox.height + }) + // 璋冭妭澶у皬缂╂斁 + const zoom = currentViewbox.outer.width /(currentViewbox.inner.width+200) + console.log('********',zoom,elementMid,currentViewbox.inner,currentViewbox.outer) + // modeler.get('canvas').zoom(zoom) + + + }, + } + +}; +</script> +<style lang="less"> + .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) { + fill: green !important; + } + .highlight.djs-shape .djs-visual > path { + fill: green !important; + fill-opacity: 0.2 !important; + stroke: green !important; + } + .highlight.djs-connection > .djs-visual > path { + stroke: green !important; + } + // .djs-connection > .djs-visual > path { + // stroke: orange !important; + // stroke-dasharray: 4px !important; + // fill-opacity: 0.2 !important; + // } + // .djs-shape .djs-visual > :nth-child(1) { + // fill: orange !important; + // stroke: orange !important; + // stroke-dasharray: 4px !important; + // fill-opacity: 0.2 !important; + // } + .highlight-todo.djs-connection > .djs-visual > path { + stroke: orange !important; + stroke-dasharray: 4px !important; + fill-opacity: 0.2 !important; + } + .highlight-todo.djs-shape .djs-visual > :nth-child(1) { + fill: orange !important; + stroke: orange !important; + stroke-dasharray: 4px !important; + fill-opacity: 0.2 !important; + } + .highlight-back.djs-connection > .djs-visual > path { + stroke: red !important; + stroke-dasharray: 4px !important; + fill-opacity: 0.2 !important; + } + .highlight-back.djs-shape .djs-visual > :nth-child(1) { + fill: red !important; + stroke: red !important; + stroke-dasharray: 4px !important; + fill-opacity: 0.2 !important; + } + .overlays-div { + font-size: 10px; + color: red; + width: 100px; + top: -20px !important; + } +</style> \ No newline at end of file -- Gitblit v1.9.3