23 changed files with 2504 additions and 67 deletions
@ -1,52 +1,60 @@ |
|||||
import request from '@/utils/request' |
import request from '@/utils/request' |
||||
|
|
||||
// 查询部门列表
|
// 查询部门列表
|
||||
export function listDept(query) { |
export function listDept(query) { |
||||
return request({ |
return request({ |
||||
url: '/system/dept/list', |
url: '/system/dept/list', |
||||
method: 'get', |
method: 'get', |
||||
params: query |
params: query |
||||
}) |
}) |
||||
} |
} |
||||
|
|
||||
// 查询部门列表(排除节点)
|
// 查询部门下拉树结构
|
||||
export function listDeptExcludeChild(deptId) { |
export function treeselect() { |
||||
return request({ |
return request({ |
||||
url: '/system/dept/list/exclude/' + deptId, |
url: '/system/dept/treeselect', |
||||
method: 'get' |
method: 'get' |
||||
}) |
}) |
||||
} |
} |
||||
|
|
||||
// 查询部门详细
|
// 查询部门列表(排除节点)
|
||||
export function getDept(deptId) { |
export function listDeptExcludeChild(deptId) { |
||||
return request({ |
return request({ |
||||
url: '/system/dept/' + deptId, |
url: '/system/dept/list/exclude/' + deptId, |
||||
method: 'get' |
method: 'get' |
||||
}) |
}) |
||||
} |
} |
||||
|
|
||||
// 新增部门
|
// 查询部门详细
|
||||
export function addDept(data) { |
export function getDept(deptId) { |
||||
return request({ |
return request({ |
||||
url: '/system/dept', |
url: '/system/dept/' + deptId, |
||||
method: 'post', |
method: 'get' |
||||
data: data |
}) |
||||
}) |
} |
||||
} |
|
||||
|
// 新增部门
|
||||
// 修改部门
|
export function addDept(data) { |
||||
export function updateDept(data) { |
return request({ |
||||
return request({ |
url: '/system/dept', |
||||
url: '/system/dept', |
method: 'post', |
||||
method: 'put', |
data: data |
||||
data: data |
}) |
||||
}) |
} |
||||
} |
|
||||
|
// 修改部门
|
||||
// 删除部门
|
export function updateDept(data) { |
||||
export function delDept(deptId) { |
return request({ |
||||
return request({ |
url: '/system/dept', |
||||
url: '/system/dept/' + deptId, |
method: 'put', |
||||
method: 'delete' |
data: data |
||||
}) |
}) |
||||
} |
} |
||||
|
|
||||
|
// 删除部门
|
||||
|
export function delDept(deptId) { |
||||
|
return request({ |
||||
|
url: '/system/dept/' + deptId, |
||||
|
method: 'delete' |
||||
|
}) |
||||
|
} |
||||
|
|||||
@ -0,0 +1,36 @@ |
|||||
|
<template> |
||||
|
<div> |
||||
|
<!--<bpmn-modeler |
||||
|
ref="refNode" |
||||
|
:xml="xmlData" |
||||
|
:is-view="true" |
||||
|
:taskList="taskData" |
||||
|
/>--> |
||||
|
<flow-view :xmlData="xmlData" :taskList="taskData"/> |
||||
|
</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: () => [] |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return {}; |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
@ -0,0 +1,243 @@ |
|||||
|
<template> |
||||
|
<div class="containers main-box"> |
||||
|
<el-button type="success" |
||||
|
size="small" |
||||
|
icon="el-icon-zoom-in" |
||||
|
@click="zoomViewport(true)">放大</el-button> |
||||
|
<el-button type="warning" |
||||
|
size="small" |
||||
|
icon="el-icon-zoom-out" |
||||
|
@click="zoomViewport(false)">缩小</el-button> |
||||
|
<el-button type="info" |
||||
|
size="small" |
||||
|
icon="el-icon-rank" |
||||
|
@click="fitViewport">适中</el-button> |
||||
|
<div class="canvas" ref="flowCanvas"></div> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script> |
||||
|
import { CustomViewer as BpmnViewer } from "@/components/customBpmn"; |
||||
|
|
||||
|
export default { |
||||
|
name: "FlowView", |
||||
|
props: { |
||||
|
xmlData: { |
||||
|
type: String, |
||||
|
default: '' |
||||
|
}, |
||||
|
taskList: { |
||||
|
type: Array, |
||||
|
default: () => [] |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
bpmnViewer: null |
||||
|
}; |
||||
|
}, |
||||
|
watch: { |
||||
|
xmlData: function(val) { |
||||
|
if (val) { |
||||
|
this.getImg(val) |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
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) { |
||||
|
const self = this |
||||
|
try { |
||||
|
await self.bpmnViewer.importXML(xmlUrl); |
||||
|
self.fitViewport() |
||||
|
if (self.taskList !==undefined && self.taskList.length > 0 ) { |
||||
|
self.fillColor() |
||||
|
} |
||||
|
} catch (err) { |
||||
|
console.error(err.message, err.warnings) |
||||
|
} |
||||
|
}, |
||||
|
// 设置高亮颜色的class |
||||
|
setNodeColor(nodeCodes, colorClass, canvas) { |
||||
|
for (let i = 0; i < nodeCodes.length; i++) { |
||||
|
canvas.addMarker(nodeCodes[i], colorClass); |
||||
|
} |
||||
|
}, |
||||
|
// 让图能自适应屏幕 |
||||
|
fitViewport() { |
||||
|
this.zoom = this.bpmnViewer.get('canvas').zoom("fit-viewport", "auto") |
||||
|
}, |
||||
|
// 放大缩小 |
||||
|
zoomViewport(zoomIn = true) { |
||||
|
this.zoom = this.bpmnViewer.get('canvas').zoom() |
||||
|
this.zoom += (zoomIn ? 0.1 : -0.1) |
||||
|
if(this.zoom >= 0.2) this.bpmnViewer.get('canvas').zoom(this.zoom) |
||||
|
}, |
||||
|
|
||||
|
// 设置高亮颜色的 |
||||
|
fillColor() { |
||||
|
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] |
||||
|
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) |
||||
|
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 => { |
||||
|
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 |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
<style lang="scss"> |
||||
|
@import "../../../../../node_modules/bpmn-js/dist/assets/diagram-js.css"; |
||||
|
@import "../../../../../node_modules/bpmn-js/dist/assets/bpmn-font/css/bpmn.css"; |
||||
|
@import "../../../../../node_modules/bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css"; |
||||
|
@import "../../../../../node_modules/bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css"; |
||||
|
.bjs-powered-by { |
||||
|
display: none; |
||||
|
} |
||||
|
.view-mode { |
||||
|
.el-header, .el-aside, .djs-palette, .bjs-powered-by { |
||||
|
display: none; |
||||
|
} |
||||
|
.el-loading-mask { |
||||
|
background-color: initial; |
||||
|
} |
||||
|
.el-loading-spinner { |
||||
|
display: none; |
||||
|
} |
||||
|
} |
||||
|
.containers { |
||||
|
// background-color: #ffffff; |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
.canvas { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
.panel { |
||||
|
position: absolute; |
||||
|
right: 0; |
||||
|
top: 50px; |
||||
|
width: 300px; |
||||
|
} |
||||
|
.load { |
||||
|
margin-right: 10px; |
||||
|
} |
||||
|
.el-form-item__label{ |
||||
|
font-size: 13px; |
||||
|
} |
||||
|
|
||||
|
.djs-palette{ |
||||
|
left: 0px!important; |
||||
|
top: 0px; |
||||
|
border-top: none; |
||||
|
} |
||||
|
|
||||
|
.djs-container svg { |
||||
|
min-height: 650px; |
||||
|
} |
||||
|
|
||||
|
.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; |
||||
|
} |
||||
|
.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; |
||||
|
} |
||||
|
.overlays-div { |
||||
|
font-size: 10px; |
||||
|
color: red; |
||||
|
width: 100px; |
||||
|
top: -20px !important; |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,227 @@ |
|||||
|
<template> |
||||
|
<div class="app-container"> |
||||
|
<el-card class="box-card" > |
||||
|
<div slot="header" class="clearfix"> |
||||
|
<span class="el-icon-document">基础信息</span> |
||||
|
<el-button style="float: right;" type="primary" @click="goBack">返回</el-button> |
||||
|
</div> |
||||
|
|
||||
|
<!--流程处理表单模块--> |
||||
|
<el-col :span="16" :offset="6" v-if="variableOpen"> |
||||
|
<div> |
||||
|
<parser :key="new Date().getTime()" :form-conf="variablesData" /> |
||||
|
</div> |
||||
|
</el-col> |
||||
|
</el-card> |
||||
|
|
||||
|
<!--流程流转记录--> |
||||
|
<el-card class="box-card" v-if="flowRecordList"> |
||||
|
<div slot="header" class="clearfix"> |
||||
|
<span class="el-icon-notebook-1">审批记录</span> |
||||
|
</div> |
||||
|
<el-col :span="16" :offset="4" > |
||||
|
<div class="block"> |
||||
|
<el-timeline> |
||||
|
<el-timeline-item |
||||
|
v-for="(item,index ) in flowRecordList" |
||||
|
:key="index" |
||||
|
:icon="setIcon(item.finishTime)" |
||||
|
:color="setColor(item.finishTime)" |
||||
|
> |
||||
|
<p style="font-weight: 700">{{item.taskName}}</p> |
||||
|
<el-card :body-style="{ padding: '10px' }"> |
||||
|
<el-descriptions class="margin-top" :column="1" size="small" border> |
||||
|
<el-descriptions-item v-if="item.assigneeName" label-class-name="my-label"> |
||||
|
<template slot="label"><i class="el-icon-user"></i>实际办理</template> |
||||
|
{{item.assigneeName}} |
||||
|
<el-tag type="info" size="mini">{{item.deptName}}</el-tag> |
||||
|
</el-descriptions-item> |
||||
|
<el-descriptions-item v-if="item.candidate" label-class-name="my-label"> |
||||
|
<template slot="label"><i class="el-icon-user"></i>候选办理</template> |
||||
|
{{item.candidate}} |
||||
|
</el-descriptions-item> |
||||
|
<el-descriptions-item label-class-name="my-label"> |
||||
|
<template slot="label"><i class="el-icon-date"></i>接收时间</template> |
||||
|
{{item.createTime}} |
||||
|
</el-descriptions-item> |
||||
|
<el-descriptions-item v-if="item.finishTime" label-class-name="my-label"> |
||||
|
<template slot="label"><i class="el-icon-date"></i>处理时间</template> |
||||
|
{{item.finishTime}} |
||||
|
</el-descriptions-item> |
||||
|
<el-descriptions-item v-if="item.duration" label-class-name="my-label"> |
||||
|
<template slot="label"><i class="el-icon-time"></i>耗时</template> |
||||
|
{{item.duration}} |
||||
|
</el-descriptions-item> |
||||
|
<el-descriptions-item v-if="item.comment" label-class-name="my-label"> |
||||
|
<template slot="label"><i class="el-icon-tickets"></i>处理意见</template> |
||||
|
{{item.comment.comment}} |
||||
|
</el-descriptions-item> |
||||
|
</el-descriptions> |
||||
|
</el-card> |
||||
|
</el-timeline-item> |
||||
|
</el-timeline> |
||||
|
</div> |
||||
|
</el-col> |
||||
|
</el-card> |
||||
|
<el-card class="box-card"> |
||||
|
<div slot="header" class="clearfix"> |
||||
|
<span class="el-icon-picture-outline">流程图</span> |
||||
|
</div> |
||||
|
<flow :xmlData="xmlData" :taskData="taskList"></flow> |
||||
|
</el-card> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import {flowRecord} from "@/api/flowable/finished"; |
||||
|
import Parser from '@/components/parser/Parser' |
||||
|
import {definitionStart, getProcessVariables, readXml, getFlowViewer} from "@/api/flowable/definition"; |
||||
|
import {complete, rejectTask, returnList, returnTask, getNextFlowNode, delegate} from "@/api/flowable/todo"; |
||||
|
import flow from '@/views/flowable/task/record/flow' |
||||
|
import {treeselect} from "@/api/system/dept"; |
||||
|
import "@riophae/vue-treeselect/dist/vue-treeselect.css"; |
||||
|
import Treeselect from "@riophae/vue-treeselect"; |
||||
|
import {listUser} from "@/api/system/user"; |
||||
|
|
||||
|
export default { |
||||
|
name: "Record", |
||||
|
components: { |
||||
|
Parser, |
||||
|
flow, |
||||
|
Treeselect |
||||
|
}, |
||||
|
props: {}, |
||||
|
data() { |
||||
|
return { |
||||
|
// 模型xml数据 |
||||
|
xmlData: "", |
||||
|
taskList: [], |
||||
|
// 用户表格数据 |
||||
|
userList: null, |
||||
|
defaultProps: { |
||||
|
children: "children", |
||||
|
label: "label" |
||||
|
}, |
||||
|
// 查询参数 |
||||
|
queryParams: { |
||||
|
deptId: undefined |
||||
|
}, |
||||
|
// 遮罩层 |
||||
|
loading: true, |
||||
|
flowRecordList: [], // 流程流转数据 |
||||
|
formConfCopy: {}, |
||||
|
src: null, |
||||
|
taskForm:{ |
||||
|
multiple: false, |
||||
|
comment:"", // 意见内容 |
||||
|
procInsId: "", // 流程实例编号 |
||||
|
instanceId: "", // 流程实例编号 |
||||
|
deployId: "", // 流程定义编号 |
||||
|
taskId: "" ,// 流程任务编号 |
||||
|
procDefId: "", // 流程编号 |
||||
|
vars: "", |
||||
|
targetKey:"" |
||||
|
}, |
||||
|
variables: [], // 流程变量数据 |
||||
|
variablesData: {}, // 流程变量数据 |
||||
|
variableOpen: false, // 是否加载流程变量数据 |
||||
|
}; |
||||
|
}, |
||||
|
created() { |
||||
|
this.taskForm.deployId = this.$route.query && this.$route.query.deployId; |
||||
|
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) |
||||
|
} |
||||
|
this.getFlowRecordList( this.taskForm.procInsId, this.taskForm.deployId); |
||||
|
}, |
||||
|
methods: { |
||||
|
/** xml 文件 */ |
||||
|
getModelDetail(deployId) { |
||||
|
// 发送请求,获取xml |
||||
|
readXml(deployId).then(res => { |
||||
|
this.xmlData = res.data |
||||
|
}) |
||||
|
}, |
||||
|
getFlowViewer(procInsId,executionId) { |
||||
|
getFlowViewer(procInsId,executionId).then(res => { |
||||
|
this.taskList = res.data |
||||
|
}) |
||||
|
}, |
||||
|
setIcon(val) { |
||||
|
if (val) { |
||||
|
return "el-icon-check"; |
||||
|
} else { |
||||
|
return "el-icon-time"; |
||||
|
} |
||||
|
}, |
||||
|
setColor(val) { |
||||
|
if (val) { |
||||
|
return "#2bc418"; |
||||
|
} else { |
||||
|
return "#b3bdbb"; |
||||
|
} |
||||
|
}, |
||||
|
/** 流程流转记录 */ |
||||
|
getFlowRecordList(procInsId, deployId) { |
||||
|
const that = this |
||||
|
const params = {procInsId: procInsId, deployId: deployId} |
||||
|
flowRecord(params).then(res => { |
||||
|
that.flowRecordList = res.data.flowList; |
||||
|
}).catch(res => { |
||||
|
this.goBack(); |
||||
|
}) |
||||
|
}, |
||||
|
/** 获取流程变量内容 */ |
||||
|
processVariables(taskId) { |
||||
|
if (taskId) { |
||||
|
// 提交流程申请时填写的表单存入了流程变量中后续任务处理时需要展示 |
||||
|
getProcessVariables(taskId).then(res => { |
||||
|
this.variablesData = res.data.variables; |
||||
|
this.variableOpen = true |
||||
|
}); |
||||
|
} |
||||
|
}, |
||||
|
/** 返回页面 */ |
||||
|
goBack() { |
||||
|
// 关闭当前标签页并返回上个页面 |
||||
|
this.$store.dispatch("tagsView/delView", this.$route); |
||||
|
this.$router.go(-1) |
||||
|
}, |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
<style lang="scss" scoped> |
||||
|
.test-form { |
||||
|
margin: 15px auto; |
||||
|
width: 800px; |
||||
|
padding: 15px; |
||||
|
} |
||||
|
|
||||
|
.clearfix:before, |
||||
|
.clearfix:after { |
||||
|
display: table; |
||||
|
content: ""; |
||||
|
} |
||||
|
.clearfix:after { |
||||
|
clear: both |
||||
|
} |
||||
|
|
||||
|
.box-card { |
||||
|
width: 100%; |
||||
|
margin-bottom: 20px; |
||||
|
} |
||||
|
|
||||
|
.el-tag + .el-tag { |
||||
|
margin-left: 10px; |
||||
|
} |
||||
|
|
||||
|
.my-label { |
||||
|
background: #E1F3D8; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,36 @@ |
|||||
|
<template> |
||||
|
<div> |
||||
|
<!--<bpmn-modeler |
||||
|
ref="refNode" |
||||
|
:xml="xmlData" |
||||
|
:is-view="true" |
||||
|
:taskList="taskData" |
||||
|
/>--> |
||||
|
<flow-view :xmlData="xmlData" :taskList="taskData"/> |
||||
|
</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: () => [] |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return {}; |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
@ -0,0 +1,243 @@ |
|||||
|
<template> |
||||
|
<div class="containers main-box"> |
||||
|
<el-button type="success" |
||||
|
size="small" |
||||
|
icon="el-icon-zoom-in" |
||||
|
@click="zoomViewport(true)">放大</el-button> |
||||
|
<el-button type="warning" |
||||
|
size="small" |
||||
|
icon="el-icon-zoom-out" |
||||
|
@click="zoomViewport(false)">缩小</el-button> |
||||
|
<el-button type="info" |
||||
|
size="small" |
||||
|
icon="el-icon-rank" |
||||
|
@click="fitViewport">适中</el-button> |
||||
|
<div class="canvas" ref="flowCanvas"></div> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script> |
||||
|
import { CustomViewer as BpmnViewer } from "@/components/customBpmn"; |
||||
|
|
||||
|
export default { |
||||
|
name: "FlowView", |
||||
|
props: { |
||||
|
xmlData: { |
||||
|
type: String, |
||||
|
default: '' |
||||
|
}, |
||||
|
taskList: { |
||||
|
type: Array, |
||||
|
default: () => [] |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
bpmnViewer: null |
||||
|
}; |
||||
|
}, |
||||
|
watch: { |
||||
|
xmlData: function(val) { |
||||
|
if (val) { |
||||
|
this.getImg(val) |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
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) { |
||||
|
const self = this |
||||
|
try { |
||||
|
await self.bpmnViewer.importXML(xmlUrl); |
||||
|
self.fitViewport() |
||||
|
if (self.taskList !==undefined && self.taskList.length > 0 ) { |
||||
|
self.fillColor() |
||||
|
} |
||||
|
} catch (err) { |
||||
|
console.error(err.message, err.warnings) |
||||
|
} |
||||
|
}, |
||||
|
// 设置高亮颜色的class |
||||
|
setNodeColor(nodeCodes, colorClass, canvas) { |
||||
|
for (let i = 0; i < nodeCodes.length; i++) { |
||||
|
canvas.addMarker(nodeCodes[i], colorClass); |
||||
|
} |
||||
|
}, |
||||
|
// 让图能自适应屏幕 |
||||
|
fitViewport() { |
||||
|
this.zoom = this.bpmnViewer.get('canvas').zoom("fit-viewport", "auto") |
||||
|
}, |
||||
|
// 放大缩小 |
||||
|
zoomViewport(zoomIn = true) { |
||||
|
this.zoom = this.bpmnViewer.get('canvas').zoom() |
||||
|
this.zoom += (zoomIn ? 0.1 : -0.1) |
||||
|
if(this.zoom >= 0.2) this.bpmnViewer.get('canvas').zoom(this.zoom) |
||||
|
}, |
||||
|
|
||||
|
// 设置高亮颜色的 |
||||
|
fillColor() { |
||||
|
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] |
||||
|
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) |
||||
|
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 => { |
||||
|
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 |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
<style lang="scss"> |
||||
|
@import "../../../../../node_modules/bpmn-js/dist/assets/diagram-js.css"; |
||||
|
@import "../../../../../node_modules/bpmn-js/dist/assets/bpmn-font/css/bpmn.css"; |
||||
|
@import "../../../../../node_modules/bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css"; |
||||
|
@import "../../../../../node_modules/bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css"; |
||||
|
.bjs-powered-by { |
||||
|
display: none; |
||||
|
} |
||||
|
.view-mode { |
||||
|
.el-header, .el-aside, .djs-palette, .bjs-powered-by { |
||||
|
display: none; |
||||
|
} |
||||
|
.el-loading-mask { |
||||
|
background-color: initial; |
||||
|
} |
||||
|
.el-loading-spinner { |
||||
|
display: none; |
||||
|
} |
||||
|
} |
||||
|
.containers { |
||||
|
// background-color: #ffffff; |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
.canvas { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
.panel { |
||||
|
position: absolute; |
||||
|
right: 0; |
||||
|
top: 50px; |
||||
|
width: 300px; |
||||
|
} |
||||
|
.load { |
||||
|
margin-right: 10px; |
||||
|
} |
||||
|
.el-form-item__label{ |
||||
|
font-size: 13px; |
||||
|
} |
||||
|
|
||||
|
.djs-palette{ |
||||
|
left: 0px!important; |
||||
|
top: 0px; |
||||
|
border-top: none; |
||||
|
} |
||||
|
|
||||
|
.djs-container svg { |
||||
|
min-height: 650px; |
||||
|
} |
||||
|
|
||||
|
.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; |
||||
|
} |
||||
|
.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; |
||||
|
} |
||||
|
.overlays-div { |
||||
|
font-size: 10px; |
||||
|
color: red; |
||||
|
width: 100px; |
||||
|
top: -20px !important; |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,214 @@ |
|||||
|
<template> |
||||
|
<div class="app-container"> |
||||
|
<el-card class="box-card" > |
||||
|
<div slot="header" class="clearfix"> |
||||
|
<span class="el-icon-document">基础信息</span> |
||||
|
<el-button style="float: right;" type="primary" @click="goBack">返回</el-button> |
||||
|
</div> |
||||
|
|
||||
|
<!--流程处理表单模块--> |
||||
|
<el-col :span="16" :offset="6"> |
||||
|
<div> |
||||
|
<parser :key="new Date().getTime()" :form-conf="variablesData" /> |
||||
|
</div> |
||||
|
</el-col> |
||||
|
</el-card> |
||||
|
<!--流程流转记录--> |
||||
|
<el-card class="box-card" v-if="flowRecordList"> |
||||
|
<div slot="header" class="clearfix"> |
||||
|
<span class="el-icon-notebook-1">审批记录</span> |
||||
|
</div> |
||||
|
<el-col :span="16" :offset="4" > |
||||
|
<div class="block"> |
||||
|
<el-timeline> |
||||
|
<el-timeline-item |
||||
|
v-for="(item,index ) in flowRecordList" |
||||
|
:key="index" |
||||
|
:icon="setIcon(item.finishTime)" |
||||
|
:color="setColor(item.finishTime)" |
||||
|
> |
||||
|
<p style="font-weight: 700">{{item.taskName}}</p> |
||||
|
<el-card :body-style="{ padding: '10px' }"> |
||||
|
<el-descriptions class="margin-top" :column="1" size="small" border> |
||||
|
<el-descriptions-item v-if="item.assigneeName" label-class-name="my-label"> |
||||
|
<template slot="label"><i class="el-icon-user"></i>实际办理</template> |
||||
|
{{item.assigneeName}} |
||||
|
<el-tag type="info" size="mini">{{item.deptName}}</el-tag> |
||||
|
</el-descriptions-item> |
||||
|
<el-descriptions-item v-if="item.candidate" label-class-name="my-label"> |
||||
|
<template slot="label"><i class="el-icon-user"></i>候选办理</template> |
||||
|
{{item.candidate}} |
||||
|
</el-descriptions-item> |
||||
|
<el-descriptions-item label-class-name="my-label"> |
||||
|
<template slot="label"><i class="el-icon-date"></i>接收时间</template> |
||||
|
{{item.createTime}} |
||||
|
</el-descriptions-item> |
||||
|
<el-descriptions-item v-if="item.finishTime" label-class-name="my-label"> |
||||
|
<template slot="label"><i class="el-icon-date"></i>处理时间</template> |
||||
|
{{item.finishTime}} |
||||
|
</el-descriptions-item> |
||||
|
<el-descriptions-item v-if="item.duration" label-class-name="my-label"> |
||||
|
<template slot="label"><i class="el-icon-time"></i>耗时</template> |
||||
|
{{item.duration}} |
||||
|
</el-descriptions-item> |
||||
|
<el-descriptions-item v-if="item.comment" label-class-name="my-label"> |
||||
|
<template slot="label"><i class="el-icon-tickets"></i>处理意见</template> |
||||
|
{{item.comment.comment}} |
||||
|
</el-descriptions-item> |
||||
|
</el-descriptions> |
||||
|
</el-card> |
||||
|
</el-timeline-item> |
||||
|
</el-timeline> |
||||
|
</div> |
||||
|
</el-col> |
||||
|
</el-card> |
||||
|
<el-card class="box-card"> |
||||
|
<div slot="header" class="clearfix"> |
||||
|
<span class="el-icon-picture-outline">流程图</span> |
||||
|
</div> |
||||
|
<flow :xmlData="xmlData" :taskData="taskList"></flow> |
||||
|
</el-card> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import {flowRecord} from "@/api/flowable/finished"; |
||||
|
import Parser from '@/components/parser/Parser' |
||||
|
import {getProcessVariables, readXml, getFlowViewer} from "@/api/flowable/definition"; |
||||
|
import flow from '@/views/flowable/task/record/flow' |
||||
|
import "@riophae/vue-treeselect/dist/vue-treeselect.css"; |
||||
|
|
||||
|
export default { |
||||
|
name: "Record", |
||||
|
components: { |
||||
|
Parser, |
||||
|
flow |
||||
|
}, |
||||
|
props: {}, |
||||
|
data() { |
||||
|
return { |
||||
|
// 模型xml数据 |
||||
|
xmlData: "", |
||||
|
taskList: [], |
||||
|
// 查询参数 |
||||
|
queryParams: { |
||||
|
deptId: undefined |
||||
|
}, |
||||
|
// 遮罩层 |
||||
|
loading: true, |
||||
|
flowRecordList: [], // 流程流转数据 |
||||
|
taskForm:{ |
||||
|
multiple: false, |
||||
|
comment:"", // 意见内容 |
||||
|
procInsId: "", // 流程实例编号 |
||||
|
instanceId: "", // 流程实例编号 |
||||
|
deployId: "", // 流程定义编号 |
||||
|
taskId: "" ,// 流程任务编号 |
||||
|
procDefId: "", // 流程编号 |
||||
|
}, |
||||
|
variablesData: {}, // 流程变量数据 |
||||
|
}; |
||||
|
}, |
||||
|
created() { |
||||
|
this.taskForm.deployId = this.$route.query && this.$route.query.deployId; |
||||
|
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: { |
||||
|
/** xml 文件 */ |
||||
|
getModelDetail(deployId) { |
||||
|
// 发送请求,获取xml |
||||
|
readXml(deployId).then(res => { |
||||
|
this.xmlData = res.data |
||||
|
}) |
||||
|
}, |
||||
|
getFlowViewer(procInsId,executionId) { |
||||
|
getFlowViewer(procInsId,executionId).then(res => { |
||||
|
this.taskList = res.data |
||||
|
}) |
||||
|
}, |
||||
|
setIcon(val) { |
||||
|
if (val) { |
||||
|
return "el-icon-check"; |
||||
|
} else { |
||||
|
return "el-icon-time"; |
||||
|
} |
||||
|
}, |
||||
|
setColor(val) { |
||||
|
if (val) { |
||||
|
return "#2bc418"; |
||||
|
} else { |
||||
|
return "#b3bdbb"; |
||||
|
} |
||||
|
}, |
||||
|
/** 流程流转记录 */ |
||||
|
getFlowRecordList(procInsId, deployId) { |
||||
|
const that = this |
||||
|
const params = {procInsId: procInsId, deployId: deployId} |
||||
|
flowRecord(params).then(res => { |
||||
|
that.flowRecordList = res.data.flowList; |
||||
|
}).catch(res => { |
||||
|
this.goBack(); |
||||
|
}) |
||||
|
}, |
||||
|
fillFormData(form, data) { |
||||
|
form.fields.forEach(item => { |
||||
|
const val = data[item.__vModel__] |
||||
|
if (val) { |
||||
|
item.__config__.defaultValue = val |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
/** 获取流程变量内容 */ |
||||
|
processVariables(taskId) { |
||||
|
if (taskId) { |
||||
|
// 提交流程申请时填写的表单存入了流程变量中后续任务处理时需要展示 |
||||
|
getProcessVariables(taskId).then(res => { |
||||
|
this.variablesData = res.data.variables; |
||||
|
}); |
||||
|
} |
||||
|
}, |
||||
|
/** 返回页面 */ |
||||
|
goBack() { |
||||
|
// 关闭当前标签页并返回上个页面 |
||||
|
this.$store.dispatch("tagsView/delView", this.$route); |
||||
|
this.$router.go(-1) |
||||
|
}, |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
<style lang="scss" scoped> |
||||
|
.test-form { |
||||
|
margin: 15px auto; |
||||
|
width: 800px; |
||||
|
padding: 15px; |
||||
|
} |
||||
|
|
||||
|
.clearfix:before, |
||||
|
.clearfix:after { |
||||
|
display: table; |
||||
|
content: ""; |
||||
|
} |
||||
|
.clearfix:after { |
||||
|
clear: both |
||||
|
} |
||||
|
|
||||
|
.box-card { |
||||
|
width: 100%; |
||||
|
margin-bottom: 20px; |
||||
|
} |
||||
|
|
||||
|
.el-tag + .el-tag { |
||||
|
margin-left: 10px; |
||||
|
} |
||||
|
|
||||
|
.my-label { |
||||
|
background: #E1F3D8; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,36 @@ |
|||||
|
<template> |
||||
|
<div> |
||||
|
<!--<bpmn-modeler |
||||
|
ref="refNode" |
||||
|
:xml="xmlData" |
||||
|
:is-view="true" |
||||
|
:taskList="taskData" |
||||
|
/>--> |
||||
|
<flow-view :xmlData="xmlData" :taskList="taskData"/> |
||||
|
</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: () => [] |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return {}; |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
@ -0,0 +1,243 @@ |
|||||
|
<template> |
||||
|
<div class="containers main-box"> |
||||
|
<el-button type="success" |
||||
|
size="small" |
||||
|
icon="el-icon-zoom-in" |
||||
|
@click="zoomViewport(true)">放大</el-button> |
||||
|
<el-button type="warning" |
||||
|
size="small" |
||||
|
icon="el-icon-zoom-out" |
||||
|
@click="zoomViewport(false)">缩小</el-button> |
||||
|
<el-button type="info" |
||||
|
size="small" |
||||
|
icon="el-icon-rank" |
||||
|
@click="fitViewport">适中</el-button> |
||||
|
<div class="canvas" ref="flowCanvas"></div> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script> |
||||
|
import { CustomViewer as BpmnViewer } from "@/components/customBpmn"; |
||||
|
|
||||
|
export default { |
||||
|
name: "FlowView", |
||||
|
props: { |
||||
|
xmlData: { |
||||
|
type: String, |
||||
|
default: '' |
||||
|
}, |
||||
|
taskList: { |
||||
|
type: Array, |
||||
|
default: () => [] |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
bpmnViewer: null |
||||
|
}; |
||||
|
}, |
||||
|
watch: { |
||||
|
xmlData: function(val) { |
||||
|
if (val) { |
||||
|
this.getImg(val) |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
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) { |
||||
|
const self = this |
||||
|
try { |
||||
|
await self.bpmnViewer.importXML(xmlUrl); |
||||
|
self.fitViewport() |
||||
|
if (self.taskList !==undefined && self.taskList.length > 0 ) { |
||||
|
self.fillColor() |
||||
|
} |
||||
|
} catch (err) { |
||||
|
console.error(err.message, err.warnings) |
||||
|
} |
||||
|
}, |
||||
|
// 设置高亮颜色的class |
||||
|
setNodeColor(nodeCodes, colorClass, canvas) { |
||||
|
for (let i = 0; i < nodeCodes.length; i++) { |
||||
|
canvas.addMarker(nodeCodes[i], colorClass); |
||||
|
} |
||||
|
}, |
||||
|
// 让图能自适应屏幕 |
||||
|
fitViewport() { |
||||
|
this.zoom = this.bpmnViewer.get('canvas').zoom("fit-viewport", "auto") |
||||
|
}, |
||||
|
// 放大缩小 |
||||
|
zoomViewport(zoomIn = true) { |
||||
|
this.zoom = this.bpmnViewer.get('canvas').zoom() |
||||
|
this.zoom += (zoomIn ? 0.1 : -0.1) |
||||
|
if(this.zoom >= 0.2) this.bpmnViewer.get('canvas').zoom(this.zoom) |
||||
|
}, |
||||
|
|
||||
|
// 设置高亮颜色的 |
||||
|
fillColor() { |
||||
|
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] |
||||
|
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) |
||||
|
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 => { |
||||
|
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 |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
<style lang="scss"> |
||||
|
@import "../../../../../node_modules/bpmn-js/dist/assets/diagram-js.css"; |
||||
|
@import "../../../../../node_modules/bpmn-js/dist/assets/bpmn-font/css/bpmn.css"; |
||||
|
@import "../../../../../node_modules/bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css"; |
||||
|
@import "../../../../../node_modules/bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css"; |
||||
|
.bjs-powered-by { |
||||
|
display: none; |
||||
|
} |
||||
|
.view-mode { |
||||
|
.el-header, .el-aside, .djs-palette, .bjs-powered-by { |
||||
|
display: none; |
||||
|
} |
||||
|
.el-loading-mask { |
||||
|
background-color: initial; |
||||
|
} |
||||
|
.el-loading-spinner { |
||||
|
display: none; |
||||
|
} |
||||
|
} |
||||
|
.containers { |
||||
|
// background-color: #ffffff; |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
.canvas { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
.panel { |
||||
|
position: absolute; |
||||
|
right: 0; |
||||
|
top: 50px; |
||||
|
width: 300px; |
||||
|
} |
||||
|
.load { |
||||
|
margin-right: 10px; |
||||
|
} |
||||
|
.el-form-item__label{ |
||||
|
font-size: 13px; |
||||
|
} |
||||
|
|
||||
|
.djs-palette{ |
||||
|
left: 0px!important; |
||||
|
top: 0px; |
||||
|
border-top: none; |
||||
|
} |
||||
|
|
||||
|
.djs-container svg { |
||||
|
min-height: 650px; |
||||
|
} |
||||
|
|
||||
|
.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; |
||||
|
} |
||||
|
.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; |
||||
|
} |
||||
|
.overlays-div { |
||||
|
font-size: 10px; |
||||
|
color: red; |
||||
|
width: 100px; |
||||
|
top: -20px !important; |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,194 @@ |
|||||
|
<template> |
||||
|
<div class="app-container"> |
||||
|
<el-card class="box-card" > |
||||
|
<div slot="header" class="clearfix"> |
||||
|
<span class="el-icon-document">基础信息</span> |
||||
|
<el-button style="float: right;" type="primary" @click="goBack">返回</el-button> |
||||
|
</div> |
||||
|
<!--初始化流程加载表单信息--> |
||||
|
<el-col :span="16" :offset="4"> |
||||
|
<div class="test-form"> |
||||
|
<parser :key="new Date().getTime()" :form-conf="formConf" @submit="submitForm" ref="parser" @getData="getData" /> |
||||
|
</div> |
||||
|
</el-col> |
||||
|
</el-card> |
||||
|
<!--流程图--> |
||||
|
<el-card class="box-card"> |
||||
|
<div slot="header" class="clearfix"> |
||||
|
<span class="el-icon-picture-outline">流程图</span> |
||||
|
</div> |
||||
|
<flow :xmlData="xmlData" :taskData="taskList"></flow> |
||||
|
</el-card> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import Parser from '@/components/parser/Parser' |
||||
|
import {definitionStart, readXml} from "@/api/flowable/definition"; |
||||
|
import flow from '@/views/flowable/task/record/flow' |
||||
|
import {treeselect} from "@/api/system/dept"; |
||||
|
import "@riophae/vue-treeselect/dist/vue-treeselect.css"; |
||||
|
import Treeselect from "@riophae/vue-treeselect"; |
||||
|
import {listUser} from "@/api/system/user"; |
||||
|
import {flowFormData} from "@/api/flowable/process"; |
||||
|
|
||||
|
export default { |
||||
|
name: "Record", |
||||
|
components: { |
||||
|
Parser, |
||||
|
flow, |
||||
|
Treeselect |
||||
|
}, |
||||
|
props: {}, |
||||
|
data() { |
||||
|
return { |
||||
|
// 模型xml数据 |
||||
|
xmlData: "", |
||||
|
taskList: [], |
||||
|
// 用户表格数据 |
||||
|
userList: null, |
||||
|
defaultProps: { |
||||
|
children: "children", |
||||
|
label: "label" |
||||
|
}, |
||||
|
// 查询参数 |
||||
|
queryParams: { |
||||
|
deptId: undefined |
||||
|
}, |
||||
|
// 遮罩层 |
||||
|
loading: true, |
||||
|
rules: {}, // 表单校验 |
||||
|
variablesForm: {}, // 流程变量数据 |
||||
|
taskForm:{ |
||||
|
multiple: false, |
||||
|
comment:"", // 意见内容 |
||||
|
procInsId: "", // 流程实例编号 |
||||
|
instanceId: "", // 流程实例编号 |
||||
|
deployId: "", // 流程定义编号 |
||||
|
taskId: "" ,// 流程任务编号 |
||||
|
procDefId: "", // 流程编号 |
||||
|
vars: "", |
||||
|
targetKey:"" |
||||
|
}, |
||||
|
formConf: {}, // 默认表单数据 |
||||
|
variables: [], // 流程变量数据 |
||||
|
}; |
||||
|
}, |
||||
|
created() { |
||||
|
this.taskForm.deployId = this.$route.query && this.$route.query.deployId; |
||||
|
// 初始化表单 |
||||
|
this.taskForm.procDefId = this.$route.query && this.$route.query.procDefId; |
||||
|
this.getFlowFormData(this.taskForm.deployId); |
||||
|
// 回显流程记录 |
||||
|
this.loadModelXml(this.taskForm.deployId); |
||||
|
}, |
||||
|
methods: { |
||||
|
/** 查询部门下拉树结构 */ |
||||
|
getTreeselect() { |
||||
|
treeselect().then(response => { |
||||
|
this.deptOptions = response.data; |
||||
|
}); |
||||
|
}, |
||||
|
/** 查询用户列表 */ |
||||
|
getList() { |
||||
|
listUser(this.addDateRange(this.queryParams, this.dateRange)).then(response => { |
||||
|
this.userList = response.rows; |
||||
|
this.total = response.total; |
||||
|
} |
||||
|
); |
||||
|
}, |
||||
|
/** xml 文件 */ |
||||
|
loadModelXml(deployId) { |
||||
|
// 发送请求,获取xml |
||||
|
readXml(deployId).then(res => { |
||||
|
this.xmlData = res.data |
||||
|
}) |
||||
|
}, |
||||
|
/** 流程表单数据 */ |
||||
|
getFlowFormData(deployId) { |
||||
|
const that = this |
||||
|
const params = {deployId: deployId} |
||||
|
flowFormData(params).then(res => { |
||||
|
// 流程过程中不存在初始化表单 直接读取的流程变量中存储的表单值 |
||||
|
that.formConf = res.data; |
||||
|
}).catch(res => { |
||||
|
this.goBack(); |
||||
|
}) |
||||
|
}, |
||||
|
/** 返回页面 */ |
||||
|
goBack() { |
||||
|
// 关闭当前标签页并返回上个页面 |
||||
|
this.$store.dispatch("tagsView/delView", this.$route); |
||||
|
this.$router.go(-1) |
||||
|
}, |
||||
|
/** 接收子组件传的值 */ |
||||
|
getData(data) { |
||||
|
if (data) { |
||||
|
const variables = []; |
||||
|
data.fields.forEach(item => { |
||||
|
let variableData = {}; |
||||
|
variableData.label = item.__config__.label |
||||
|
// 表单值为多个选项时 |
||||
|
if (item.__config__.defaultValue instanceof Array) { |
||||
|
const array = []; |
||||
|
item.__config__.defaultValue.forEach(val => { |
||||
|
array.push(val) |
||||
|
}) |
||||
|
variableData.val = array; |
||||
|
} else { |
||||
|
variableData.val = item.__config__.defaultValue |
||||
|
} |
||||
|
variables.push(variableData) |
||||
|
}) |
||||
|
this.variables = variables; |
||||
|
} |
||||
|
}, |
||||
|
/** 申请流程表单数据提交 */ |
||||
|
submitForm(data) { |
||||
|
if (data) { |
||||
|
const variables = data.valData; |
||||
|
const formData = data.formData; |
||||
|
formData.disabled = true; |
||||
|
formData.formBtns = false; |
||||
|
if (this.taskForm.procDefId) { |
||||
|
variables.variables = formData; |
||||
|
// 启动流程并将表单数据加入流程变量 |
||||
|
definitionStart(this.taskForm.procDefId, JSON.stringify(variables)).then(res => { |
||||
|
this.msgSuccess(res.msg); |
||||
|
this.goBack(); |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
<style lang="scss" scoped> |
||||
|
.test-form { |
||||
|
margin: 15px auto; |
||||
|
width: 800px; |
||||
|
padding: 15px; |
||||
|
} |
||||
|
|
||||
|
.clearfix:before, |
||||
|
.clearfix:after { |
||||
|
display: table; |
||||
|
content: ""; |
||||
|
} |
||||
|
.clearfix:after { |
||||
|
clear: both |
||||
|
} |
||||
|
|
||||
|
.box-card { |
||||
|
width: 100%; |
||||
|
margin-bottom: 20px; |
||||
|
} |
||||
|
|
||||
|
.el-tag + .el-tag { |
||||
|
margin-left: 10px; |
||||
|
} |
||||
|
|
||||
|
.my-label { |
||||
|
background: #E1F3D8; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,36 @@ |
|||||
|
<template> |
||||
|
<div> |
||||
|
<!--<bpmn-modeler |
||||
|
ref="refNode" |
||||
|
:xml="xmlData" |
||||
|
:is-view="true" |
||||
|
:taskList="taskData" |
||||
|
/>--> |
||||
|
<flow-view :xmlData="xmlData" :taskList="taskData"/> |
||||
|
</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: () => [] |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return {}; |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
@ -0,0 +1,243 @@ |
|||||
|
<template> |
||||
|
<div class="containers main-box"> |
||||
|
<el-button type="success" |
||||
|
size="small" |
||||
|
icon="el-icon-zoom-in" |
||||
|
@click="zoomViewport(true)">放大</el-button> |
||||
|
<el-button type="warning" |
||||
|
size="small" |
||||
|
icon="el-icon-zoom-out" |
||||
|
@click="zoomViewport(false)">缩小</el-button> |
||||
|
<el-button type="info" |
||||
|
size="small" |
||||
|
icon="el-icon-rank" |
||||
|
@click="fitViewport">适中</el-button> |
||||
|
<div class="canvas" ref="flowCanvas"></div> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script> |
||||
|
import { CustomViewer as BpmnViewer } from "@/components/customBpmn"; |
||||
|
|
||||
|
export default { |
||||
|
name: "FlowView", |
||||
|
props: { |
||||
|
xmlData: { |
||||
|
type: String, |
||||
|
default: '' |
||||
|
}, |
||||
|
taskList: { |
||||
|
type: Array, |
||||
|
default: () => [] |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
bpmnViewer: null |
||||
|
}; |
||||
|
}, |
||||
|
watch: { |
||||
|
xmlData: function(val) { |
||||
|
if (val) { |
||||
|
this.getImg(val) |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
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) { |
||||
|
const self = this |
||||
|
try { |
||||
|
await self.bpmnViewer.importXML(xmlUrl); |
||||
|
self.fitViewport() |
||||
|
if (self.taskList !==undefined && self.taskList.length > 0 ) { |
||||
|
self.fillColor() |
||||
|
} |
||||
|
} catch (err) { |
||||
|
console.error(err.message, err.warnings) |
||||
|
} |
||||
|
}, |
||||
|
// 设置高亮颜色的class |
||||
|
setNodeColor(nodeCodes, colorClass, canvas) { |
||||
|
for (let i = 0; i < nodeCodes.length; i++) { |
||||
|
canvas.addMarker(nodeCodes[i], colorClass); |
||||
|
} |
||||
|
}, |
||||
|
// 让图能自适应屏幕 |
||||
|
fitViewport() { |
||||
|
this.zoom = this.bpmnViewer.get('canvas').zoom("fit-viewport", "auto") |
||||
|
}, |
||||
|
// 放大缩小 |
||||
|
zoomViewport(zoomIn = true) { |
||||
|
this.zoom = this.bpmnViewer.get('canvas').zoom() |
||||
|
this.zoom += (zoomIn ? 0.1 : -0.1) |
||||
|
if(this.zoom >= 0.2) this.bpmnViewer.get('canvas').zoom(this.zoom) |
||||
|
}, |
||||
|
|
||||
|
// 设置高亮颜色的 |
||||
|
fillColor() { |
||||
|
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] |
||||
|
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) |
||||
|
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 => { |
||||
|
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 |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
<style lang="scss"> |
||||
|
@import "../../../../../node_modules/bpmn-js/dist/assets/diagram-js.css"; |
||||
|
@import "../../../../../node_modules/bpmn-js/dist/assets/bpmn-font/css/bpmn.css"; |
||||
|
@import "../../../../../node_modules/bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css"; |
||||
|
@import "../../../../../node_modules/bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css"; |
||||
|
.bjs-powered-by { |
||||
|
display: none; |
||||
|
} |
||||
|
.view-mode { |
||||
|
.el-header, .el-aside, .djs-palette, .bjs-powered-by { |
||||
|
display: none; |
||||
|
} |
||||
|
.el-loading-mask { |
||||
|
background-color: initial; |
||||
|
} |
||||
|
.el-loading-spinner { |
||||
|
display: none; |
||||
|
} |
||||
|
} |
||||
|
.containers { |
||||
|
// background-color: #ffffff; |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
.canvas { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
.panel { |
||||
|
position: absolute; |
||||
|
right: 0; |
||||
|
top: 50px; |
||||
|
width: 300px; |
||||
|
} |
||||
|
.load { |
||||
|
margin-right: 10px; |
||||
|
} |
||||
|
.el-form-item__label{ |
||||
|
font-size: 13px; |
||||
|
} |
||||
|
|
||||
|
.djs-palette{ |
||||
|
left: 0px!important; |
||||
|
top: 0px; |
||||
|
border-top: none; |
||||
|
} |
||||
|
|
||||
|
.djs-container svg { |
||||
|
min-height: 650px; |
||||
|
} |
||||
|
|
||||
|
.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; |
||||
|
} |
||||
|
.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; |
||||
|
} |
||||
|
.overlays-div { |
||||
|
font-size: 10px; |
||||
|
color: red; |
||||
|
width: 100px; |
||||
|
top: -20px !important; |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,589 @@ |
|||||
|
<template> |
||||
|
<div class="app-container"> |
||||
|
<el-card class="box-card" > |
||||
|
<div slot="header" class="clearfix"> |
||||
|
<span class="el-icon-document">基础信息</span> |
||||
|
<el-button style="float: right;" type="primary" @click="goBack">返回</el-button> |
||||
|
</div> |
||||
|
|
||||
|
<!--流程处理表单模块--> |
||||
|
<el-col :span="16" :offset="6"> |
||||
|
<div> |
||||
|
<parser :key="new Date().getTime()" :form-conf="variablesData" /> |
||||
|
</div> |
||||
|
<div style="margin-left:10%;margin-bottom: 20px;font-size: 14px;"> |
||||
|
<el-button icon="el-icon-edit-outline" type="success" size="mini" @click="handleComplete">审批</el-button> |
||||
|
<!-- <el-button icon="el-icon-edit-outline" type="primary" size="mini" @click="handleDelegate">委派</el-button>--> |
||||
|
<!-- <el-button icon="el-icon-edit-outline" type="primary" size="mini" @click="handleAssign">转办</el-button>--> |
||||
|
<!-- <el-button icon="el-icon-edit-outline" type="primary" size="mini" @click="handleDelegate">签收</el-button>--> |
||||
|
<el-button icon="el-icon-refresh-left" type="warning" size="mini" @click="handleReturn">退回</el-button> |
||||
|
<el-button icon="el-icon-circle-close" type="danger" size="mini" @click="handleReject">驳回</el-button> |
||||
|
</div> |
||||
|
</el-col> |
||||
|
</el-card> |
||||
|
|
||||
|
<!--流程流转记录--> |
||||
|
<el-card class="box-card" v-if="flowRecordList"> |
||||
|
<div slot="header" class="clearfix"> |
||||
|
<span class="el-icon-notebook-1">审批记录</span> |
||||
|
</div> |
||||
|
<el-col :span="16" :offset="4" > |
||||
|
<div class="block"> |
||||
|
<el-timeline> |
||||
|
<el-timeline-item |
||||
|
v-for="(item,index ) in flowRecordList" |
||||
|
:key="index" |
||||
|
:icon="setIcon(item.finishTime)" |
||||
|
:color="setColor(item.finishTime)" |
||||
|
> |
||||
|
<p style="font-weight: 700">{{item.taskName}}</p> |
||||
|
<el-card :body-style="{ padding: '10px' }"> |
||||
|
<el-descriptions class="margin-top" :column="1" size="small" border> |
||||
|
<el-descriptions-item v-if="item.assigneeName" label-class-name="my-label"> |
||||
|
<template slot="label"><i class="el-icon-user"></i>实际办理</template> |
||||
|
{{item.assigneeName}} |
||||
|
<el-tag type="info" size="mini">{{item.deptName}}</el-tag> |
||||
|
</el-descriptions-item> |
||||
|
<el-descriptions-item v-if="item.candidate" label-class-name="my-label"> |
||||
|
<template slot="label"><i class="el-icon-user"></i>候选办理</template> |
||||
|
{{item.candidate}} |
||||
|
</el-descriptions-item> |
||||
|
<el-descriptions-item label-class-name="my-label"> |
||||
|
<template slot="label"><i class="el-icon-date"></i>接收时间</template> |
||||
|
{{item.createTime}} |
||||
|
</el-descriptions-item> |
||||
|
<el-descriptions-item v-if="item.finishTime" label-class-name="my-label"> |
||||
|
<template slot="label"><i class="el-icon-date"></i>处理时间</template> |
||||
|
{{item.finishTime}} |
||||
|
</el-descriptions-item> |
||||
|
<el-descriptions-item v-if="item.duration" label-class-name="my-label"> |
||||
|
<template slot="label"><i class="el-icon-time"></i>耗时</template> |
||||
|
{{item.duration}} |
||||
|
</el-descriptions-item> |
||||
|
<el-descriptions-item v-if="item.comment" label-class-name="my-label"> |
||||
|
<template slot="label"><i class="el-icon-tickets"></i>处理意见</template> |
||||
|
{{item.comment.comment}} |
||||
|
</el-descriptions-item> |
||||
|
</el-descriptions> |
||||
|
|
||||
|
<!-- <p v-if="item.comment">--> |
||||
|
<!-- <el-tag type="success" v-if="item.comment.type === '1'"> {{item.comment.comment}}</el-tag>--> |
||||
|
<!-- <el-tag type="warning" v-if="item.comment.type === '2'"> {{item.comment.comment}}</el-tag>--> |
||||
|
<!-- <el-tag type="danger" v-if="item.comment.type === '3'"> {{item.comment.comment}}</el-tag>--> |
||||
|
<!-- </p>--> |
||||
|
</el-card> |
||||
|
</el-timeline-item> |
||||
|
</el-timeline> |
||||
|
</div> |
||||
|
</el-col> |
||||
|
</el-card> |
||||
|
<el-card class="box-card"> |
||||
|
<div slot="header" class="clearfix"> |
||||
|
<span class="el-icon-picture-outline">流程图</span> |
||||
|
</div> |
||||
|
<flow :xmlData="xmlData" :taskData="taskList"></flow> |
||||
|
</el-card> |
||||
|
|
||||
|
<!--审批正常流程--> |
||||
|
<el-dialog :title="completeTitle" :visible.sync="completeOpen" :width="checkSendUser? '60%':'40%'" append-to-body> |
||||
|
<el-form ref="taskForm" :model="taskForm" label-width="80px" > |
||||
|
<el-form-item v-if="checkSendUser" prop="targetKey"> |
||||
|
<el-row :gutter="20"> |
||||
|
<!--部门数据--> |
||||
|
<el-col :span="6" :xs="24"> |
||||
|
<h6>部门列表</h6> |
||||
|
<div class="head-container"> |
||||
|
<el-input |
||||
|
v-model="deptName" |
||||
|
placeholder="请输入部门名称" |
||||
|
clearable |
||||
|
size="small" |
||||
|
prefix-icon="el-icon-search" |
||||
|
style="margin-bottom: 20px" |
||||
|
/> |
||||
|
</div> |
||||
|
<div class="head-container"> |
||||
|
<el-tree |
||||
|
:data="deptOptions" |
||||
|
:props="defaultProps" |
||||
|
:expand-on-click-node="false" |
||||
|
:filter-node-method="filterNode" |
||||
|
ref="tree" |
||||
|
default-expand-all |
||||
|
@node-click="handleNodeClick" |
||||
|
/> |
||||
|
</div> |
||||
|
</el-col> |
||||
|
<el-col :span="10" :xs="24"> |
||||
|
<h6>待选人员</h6> |
||||
|
<el-table |
||||
|
ref="singleTable" |
||||
|
:data="userList" |
||||
|
border |
||||
|
style="width: 100%" |
||||
|
@selection-change="handleSelectionChange"> |
||||
|
<el-table-column type="selection" width="50" align="center" /> |
||||
|
<el-table-column label="用户名" align="center" prop="nickName" /> |
||||
|
<el-table-column label="部门" align="center" prop="dept.deptName" /> |
||||
|
</el-table> |
||||
|
</el-col> |
||||
|
<el-col :span="8" :xs="24"> |
||||
|
<h6>已选人员</h6> |
||||
|
<el-tag |
||||
|
v-for="(user,index) in userData" |
||||
|
:key="index" |
||||
|
closable |
||||
|
@close="handleClose(user)"> |
||||
|
{{user.nickName}} {{user.dept.deptName}} |
||||
|
</el-tag> |
||||
|
</el-col> |
||||
|
</el-row> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="处理意见" 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> |
||||
|
</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> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import {flowRecord} from "@/api/flowable/finished"; |
||||
|
import Parser from '@/components/parser/Parser' |
||||
|
import {definitionStart, getProcessVariables, readXml, getFlowViewer} from "@/api/flowable/definition"; |
||||
|
import {complete, rejectTask, returnList, returnTask, getNextFlowNode, delegate} from "@/api/flowable/todo"; |
||||
|
import flow from '@/views/flowable/task/record/flow' |
||||
|
import {treeselect} from "@/api/system/dept"; |
||||
|
import "@riophae/vue-treeselect/dist/vue-treeselect.css"; |
||||
|
import Treeselect from "@riophae/vue-treeselect"; |
||||
|
import {listUser} from "@/api/system/user"; |
||||
|
|
||||
|
export default { |
||||
|
name: "Record", |
||||
|
components: { |
||||
|
Parser, |
||||
|
flow, |
||||
|
Treeselect |
||||
|
}, |
||||
|
props: {}, |
||||
|
data() { |
||||
|
return { |
||||
|
// 模型xml数据 |
||||
|
xmlData: "", |
||||
|
taskList: [], |
||||
|
// 部门名称 |
||||
|
deptName: undefined, |
||||
|
// 部门树选项 |
||||
|
deptOptions: undefined, |
||||
|
// 用户表格数据 |
||||
|
userList: null, |
||||
|
defaultProps: { |
||||
|
children: "children", |
||||
|
label: "label" |
||||
|
}, |
||||
|
// 查询参数 |
||||
|
queryParams: { |
||||
|
deptId: undefined |
||||
|
}, |
||||
|
// 遮罩层 |
||||
|
loading: true, |
||||
|
flowRecordList: [], // 流程流转数据 |
||||
|
formConfCopy: {}, |
||||
|
src: null, |
||||
|
rules: {}, // 表单校验 |
||||
|
variablesForm: {}, // 流程变量数据 |
||||
|
taskForm:{ |
||||
|
returnTaskShow: false, // 是否展示回退表单 |
||||
|
delegateTaskShow: false, // 是否展示回退表单 |
||||
|
defaultTaskShow: true, // 默认处理 |
||||
|
sendUserShow: false, // 审批用户 |
||||
|
multiple: false, |
||||
|
comment:"", // 意见内容 |
||||
|
procInsId: "", // 流程实例编号 |
||||
|
instanceId: "", // 流程实例编号 |
||||
|
deployId: "", // 流程定义编号 |
||||
|
taskId: "" ,// 流程任务编号 |
||||
|
procDefId: "", // 流程编号 |
||||
|
vars: "", |
||||
|
targetKey:"" |
||||
|
}, |
||||
|
userDataList:[], // 流程候选人 |
||||
|
assignee: null, |
||||
|
formConf: {}, // 默认表单数据 |
||||
|
variables: [], // 流程变量数据 |
||||
|
variablesData: {}, // 流程变量数据 |
||||
|
returnTaskList: [], // 回退列表数据 |
||||
|
completeTitle: null, |
||||
|
completeOpen: false, |
||||
|
returnTitle: null, |
||||
|
returnOpen: false, |
||||
|
rejectOpen: false, |
||||
|
rejectTitle: null, |
||||
|
userData:[], |
||||
|
checkSendUser: false // 是否展示选择人员模块 |
||||
|
}; |
||||
|
}, |
||||
|
created() { |
||||
|
this.taskForm.deployId = this.$route.query && this.$route.query.deployId; |
||||
|
this.taskForm.taskId = this.$route.query && this.$route.query.taskId; |
||||
|
this.taskForm.procInsId = this.$route.query && this.$route.query.procInsId; |
||||
|
this.taskForm.executionId = this.$route.query && this.$route.query.executionId; |
||||
|
this.taskForm.instanceId = 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) |
||||
|
this.getNextFlowNode(this.taskForm.taskId) |
||||
|
} |
||||
|
this.getFlowRecordList(this.taskForm.procInsId, this.taskForm.deployId); |
||||
|
}, |
||||
|
methods: { |
||||
|
/** 查询部门下拉树结构 */ |
||||
|
getTreeselect() { |
||||
|
treeselect().then(response => { |
||||
|
this.deptOptions = response.data; |
||||
|
}); |
||||
|
}, |
||||
|
/** 查询用户列表 */ |
||||
|
getList() { |
||||
|
listUser(this.addDateRange(this.queryParams, this.dateRange)).then(response => { |
||||
|
this.userList = response.rows; |
||||
|
this.total = response.total; |
||||
|
} |
||||
|
); |
||||
|
}, |
||||
|
// 筛选节点 |
||||
|
filterNode(value, data) { |
||||
|
if (!value) return true; |
||||
|
return data.label.indexOf(value) !== -1; |
||||
|
}, |
||||
|
// 节点单击事件 |
||||
|
handleNodeClick(data) { |
||||
|
this.queryParams.deptId = data.id; |
||||
|
this.getList(); |
||||
|
}, |
||||
|
/** xml 文件 */ |
||||
|
getModelDetail(deployId) { |
||||
|
// 发送请求,获取xml |
||||
|
readXml(deployId).then(res => { |
||||
|
this.xmlData = res.data |
||||
|
}) |
||||
|
}, |
||||
|
getFlowViewer(procInsId,executionId) { |
||||
|
getFlowViewer(procInsId,executionId).then(res => { |
||||
|
this.taskList = res.data |
||||
|
}) |
||||
|
}, |
||||
|
setIcon(val) { |
||||
|
if (val) { |
||||
|
return "el-icon-check"; |
||||
|
} else { |
||||
|
return "el-icon-time"; |
||||
|
} |
||||
|
}, |
||||
|
setColor(val) { |
||||
|
if (val) { |
||||
|
return "#2bc418"; |
||||
|
} else { |
||||
|
return "#b3bdbb"; |
||||
|
} |
||||
|
}, |
||||
|
// 多选框选中数据 |
||||
|
handleSelectionChange(selection) { |
||||
|
if (selection) { |
||||
|
this.userData = selection |
||||
|
const selectVal = selection.map(item => item.userId); |
||||
|
if (selectVal instanceof Array) { |
||||
|
this.taskForm.values = { |
||||
|
"approval": selectVal.join(',') |
||||
|
} |
||||
|
} else { |
||||
|
this.taskForm.values = { |
||||
|
"approval": selectVal |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
// 关闭标签 |
||||
|
handleClose(tag) { |
||||
|
this.userData.splice(this.userData.indexOf(tag), 1); |
||||
|
this.$refs.singleTable.toggleRowSelection(tag, false) |
||||
|
}, |
||||
|
/** 流程变量赋值 */ |
||||
|
handleCheckChange(val) { |
||||
|
if (val instanceof Array) { |
||||
|
this.taskForm.values = { |
||||
|
"approval": val.join(',') |
||||
|
} |
||||
|
} else { |
||||
|
this.taskForm.values = { |
||||
|
"approval": val |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
/** 流程流转记录 */ |
||||
|
getFlowRecordList(procInsId, deployId) { |
||||
|
const that = this |
||||
|
const params = {procInsId: procInsId, deployId: deployId} |
||||
|
flowRecord(params).then(res => { |
||||
|
that.flowRecordList = res.data.flowList; |
||||
|
}).catch(res => { |
||||
|
this.goBack(); |
||||
|
}) |
||||
|
}, |
||||
|
fillFormData(form, data) { |
||||
|
form.fields.forEach(item => { |
||||
|
const val = data[item.__vModel__] |
||||
|
if (val) { |
||||
|
item.__config__.defaultValue = val |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
/** 获取流程变量内容 */ |
||||
|
processVariables(taskId) { |
||||
|
if (taskId) { |
||||
|
// 提交流程申请时填写的表单存入了流程变量中后续任务处理时需要展示 |
||||
|
getProcessVariables(taskId).then(res => { |
||||
|
this.variablesData = res.data.variables; |
||||
|
}); |
||||
|
} |
||||
|
}, |
||||
|
/** 根据当前任务或者流程设计配置的下一步节点 */ |
||||
|
getNextFlowNode(taskId) { |
||||
|
// 根据当前任务或者流程设计配置的下一步节点 todo 暂时未涉及到考虑网关、表达式和多节点情况 |
||||
|
const params = {taskId: taskId} |
||||
|
getNextFlowNode(params).then(res => { |
||||
|
const data = res.data; |
||||
|
if (data) { |
||||
|
this.checkSendUser = true |
||||
|
if (data.type === 'assignee') { // 指定人员 |
||||
|
this.userDataList = res.data.userList; |
||||
|
} else if (data.type === 'candidateUsers') { // 指定人员(多个) |
||||
|
this.userDataList = res.data.userList; |
||||
|
this.taskForm.multiple = true; |
||||
|
} else if (data.type === 'candidateGroups') { // 指定组(所属角色接收任务) |
||||
|
res.data.roleList.forEach(role => { |
||||
|
role.userId = role.roleId; |
||||
|
role.nickName = role.roleName; |
||||
|
}) |
||||
|
this.userDataList = res.data.roleList; |
||||
|
this.taskForm.multiple = false; |
||||
|
} else if (data.type === 'multiInstance') { // 会签? |
||||
|
this.userDataList = res.data.userList; |
||||
|
this.taskForm.multiple = true; |
||||
|
}else if (data.type === 'fixed') { // 已经固定人员接收下一任务 |
||||
|
this.checkSendUser = false; |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
/** 审批任务选择 */ |
||||
|
handleComplete() { |
||||
|
this.completeOpen = true; |
||||
|
this.completeTitle = "审批流程"; |
||||
|
this.getTreeselect(); |
||||
|
}, |
||||
|
/** 审批任务 */ |
||||
|
taskComplete() { |
||||
|
const that = this |
||||
|
if (!that.taskForm.values && that.checkSendUser){ |
||||
|
that.msgError("请选择流程接收人员"); |
||||
|
return; |
||||
|
} |
||||
|
if (!that.taskForm.comment){ |
||||
|
that.msgError("请输入审批意见"); |
||||
|
return; |
||||
|
} |
||||
|
complete(that.taskForm).then(response => { |
||||
|
that.msgSuccess(response.msg); |
||||
|
that.goBack(); |
||||
|
}); |
||||
|
}, |
||||
|
/** 委派任务 */ |
||||
|
handleDelegate() { |
||||
|
this.taskForm.delegateTaskShow = true; |
||||
|
this.taskForm.defaultTaskShow = false; |
||||
|
}, |
||||
|
handleAssign(){ |
||||
|
|
||||
|
}, |
||||
|
/** 返回页面 */ |
||||
|
goBack() { |
||||
|
// 关闭当前标签页并返回上个页面 |
||||
|
this.$store.dispatch("tagsView/delView", this.$route); |
||||
|
this.$router.go(-1) |
||||
|
}, |
||||
|
/** 接收子组件传的值 */ |
||||
|
getData(data) { |
||||
|
if (data) { |
||||
|
const variables = []; |
||||
|
data.fields.forEach(item => { |
||||
|
let variableData = {}; |
||||
|
variableData.label = item.__config__.label |
||||
|
// 表单值为多个选项时 |
||||
|
if (item.__config__.defaultValue instanceof Array) { |
||||
|
const array = []; |
||||
|
item.__config__.defaultValue.forEach(val => { |
||||
|
array.push(val) |
||||
|
}) |
||||
|
variableData.val = array; |
||||
|
} else { |
||||
|
variableData.val = item.__config__.defaultValue |
||||
|
} |
||||
|
variables.push(variableData) |
||||
|
}) |
||||
|
this.variables = variables; |
||||
|
} |
||||
|
}, |
||||
|
/** 申请流程表单数据提交 */ |
||||
|
submitForm(data) { |
||||
|
const that = this |
||||
|
if (data) { |
||||
|
const variables = data.valData; |
||||
|
const formData = data.formData; |
||||
|
formData.disabled = true; |
||||
|
formData.formBtns = false; |
||||
|
if (that.taskForm.procDefId) { |
||||
|
variables.variables = formData; |
||||
|
// 启动流程并将表单数据加入流程变量 |
||||
|
definitionStart(that.taskForm.procDefId, JSON.stringify(variables)).then(res => { |
||||
|
that.msgSuccess(res.msg); |
||||
|
that.goBack(); |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
/** 驳回任务 */ |
||||
|
handleReject() { |
||||
|
this.rejectOpen = true; |
||||
|
this.rejectTitle = "驳回流程"; |
||||
|
}, |
||||
|
/** 驳回任务 */ |
||||
|
taskReject() { |
||||
|
this.$refs["taskForm"].validate(valid => { |
||||
|
if (valid) { |
||||
|
rejectTask(this.taskForm).then(res => { |
||||
|
this.msgSuccess(res.msg); |
||||
|
this.goBack(); |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
/** 可退回任务列表 */ |
||||
|
handleReturn() { |
||||
|
this.returnOpen = true; |
||||
|
this.returnTitle = "退回流程"; |
||||
|
returnList(this.taskForm).then(res => { |
||||
|
this.returnTaskList = res.data; |
||||
|
this.taskForm.values = null; |
||||
|
}) |
||||
|
}, |
||||
|
/** 提交退回任务 */ |
||||
|
taskReturn() { |
||||
|
this.$refs["taskForm"].validate(valid => { |
||||
|
if (valid) { |
||||
|
returnTask(this.taskForm).then(res => { |
||||
|
this.msgSuccess(res.msg); |
||||
|
this.goBack() |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
/** 取消回退任务按钮 */ |
||||
|
cancelTask() { |
||||
|
this.taskForm.returnTaskShow = false; |
||||
|
this.taskForm.defaultTaskShow = true; |
||||
|
this.taskForm.sendUserShow = true; |
||||
|
this.returnTaskList = []; |
||||
|
}, |
||||
|
/** 委派任务 */ |
||||
|
submitDeleteTask() { |
||||
|
this.$refs["taskForm"].validate(valid => { |
||||
|
if (valid) { |
||||
|
delegate(this.taskForm).then(response => { |
||||
|
this.msgSuccess(response.msg); |
||||
|
this.goBack(); |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
/** 取消回退任务按钮 */ |
||||
|
cancelDelegateTask() { |
||||
|
this.taskForm.delegateTaskShow = false; |
||||
|
this.taskForm.defaultTaskShow = true; |
||||
|
this.taskForm.sendUserShow = true; |
||||
|
this.returnTaskList = []; |
||||
|
}, |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
<style lang="scss" scoped> |
||||
|
.test-form { |
||||
|
margin: 15px auto; |
||||
|
width: 800px; |
||||
|
padding: 15px; |
||||
|
} |
||||
|
|
||||
|
.clearfix:before, |
||||
|
.clearfix:after { |
||||
|
display: table; |
||||
|
content: ""; |
||||
|
} |
||||
|
.clearfix:after { |
||||
|
clear: both |
||||
|
} |
||||
|
|
||||
|
.box-card { |
||||
|
width: 100%; |
||||
|
margin-bottom: 20px; |
||||
|
} |
||||
|
|
||||
|
.el-tag + .el-tag { |
||||
|
margin-left: 10px; |
||||
|
} |
||||
|
|
||||
|
.my-label { |
||||
|
background: #E1F3D8; |
||||
|
} |
||||
|
</style> |
||||
Loading…
Reference in new issue