parent
9d941dd805
commit
7411f1d692
19 changed files with 1272 additions and 539 deletions
File diff suppressed because one or more lines are too long
@ -0,0 +1,265 @@ |
|||||||
|
import { getFormByProcessId, startProcess, detail, completeTask, transferTask, delegateTask, rollbackTask, terminateProcess } from '@/api/plugin/workflow/process' |
||||||
|
|
||||||
|
import Layout from '@/page/index/' |
||||||
|
import defaultValues from './default-values' |
||||||
|
|
||||||
|
import Print from '../util/print' |
||||||
|
|
||||||
|
import { mapGetters } from 'vuex' |
||||||
|
|
||||||
|
export default { |
||||||
|
mixins: [defaultValues], |
||||||
|
computed: { |
||||||
|
...mapGetters(['tag', 'userInfo']), |
||||||
|
}, |
||||||
|
data() { |
||||||
|
return { |
||||||
|
process: {}, // 流程定义/流程实例信息
|
||||||
|
buttonList: [], // 配置按钮信息
|
||||||
|
flow: [], // 流转信息
|
||||||
|
userSelectType: '', // 人员选择类型 transfer转办 delegate委托 copy抄送 assignee审核人
|
||||||
|
checkType: 'radio', // 人员选择check类型 radio单选 checkbox多选
|
||||||
|
comment: '', // 评论
|
||||||
|
bpmnOption: {}, // 流程图配置信息
|
||||||
|
watermarkText: '', //水印文字
|
||||||
|
} |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.watermarkText = this.userInfo.user_name + " " + this.userInfo.real_name |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
// 动态路由跳转
|
||||||
|
dynamicRoute(row, type) { |
||||||
|
const { id, taskId, processInstanceId, formKey, formUrl } = row |
||||||
|
let param = Buffer.from(JSON.stringify({ |
||||||
|
processId: id, |
||||||
|
taskId, |
||||||
|
processInsId: processInstanceId |
||||||
|
})).toString('base64') |
||||||
|
|
||||||
|
if (formKey && formKey.startsWith('wf_ex_')) { |
||||||
|
if (formUrl) { // 配置了自定义路由
|
||||||
|
this.$router.push(formUrl + `?p=${param}`) |
||||||
|
} else { // 动态添加路由
|
||||||
|
this.$router.addRoutes([{ |
||||||
|
path: `/workflow/process/external`, |
||||||
|
component: Layout, |
||||||
|
children: [{ |
||||||
|
path: `${formKey.substring(6)}/${type}`, |
||||||
|
name: type == 'start' ? '发起流程' : '流程详情', |
||||||
|
component: () => |
||||||
|
import( /* webpackChunkName: "views" */ `@/views/plugin/workflow/process/external/${formKey.substring(6)}/${type}.vue`), |
||||||
|
}] |
||||||
|
}]) |
||||||
|
this.$router.push(`/workflow/process/external/${formKey.substring(6)}/${type}?p=${param}`) |
||||||
|
} |
||||||
|
} else { |
||||||
|
this.$router.push(`/workflow/process/${type}/${param}`) |
||||||
|
} |
||||||
|
}, |
||||||
|
// 根据可读可写,过滤avue column
|
||||||
|
filterAvueColumn(column, taskForm, props = { label: 'label', prop: 'prop' }) { |
||||||
|
if (!column || column.length == 0) return { column } |
||||||
|
|
||||||
|
const values = [] |
||||||
|
const vars = [] |
||||||
|
column.forEach(col => { |
||||||
|
let c = taskForm.find(s => s.id == col[props.prop]) |
||||||
|
if (c && c.readable) { |
||||||
|
if (c.writable) { // 可写,记录需要提交的字段、处理字段默认值
|
||||||
|
vars.push(col[props.prop]) |
||||||
|
if (col.value) col.value = this.getDefaultValues(col.value) |
||||||
|
} else { // 不可写,清除校验与默认值
|
||||||
|
if (col.type == 'dynamic') { |
||||||
|
col.children.addBtn = false |
||||||
|
col.children.delBtn = false |
||||||
|
} else { |
||||||
|
col.readonly = true |
||||||
|
col.disabled = true |
||||||
|
} |
||||||
|
delete col.rules |
||||||
|
delete col.value |
||||||
|
} |
||||||
|
if (col.type == 'dynamic') { // 处理子表单
|
||||||
|
col.children.column = this.filterAvueColumn(col.children.column, taskForm).column |
||||||
|
} |
||||||
|
values.push(col) |
||||||
|
} |
||||||
|
}) |
||||||
|
return { column: values, vars } |
||||||
|
}, |
||||||
|
/** |
||||||
|
* 获取流程发起表单 |
||||||
|
* @param processId 流程定义id |
||||||
|
* @returns Promise({"process": "流程定义信息", "startForm": "开始节点表单"}) |
||||||
|
*/ |
||||||
|
getStartForm(processId) { |
||||||
|
return new Promise((resolve, reject) => { |
||||||
|
getFormByProcessId({ processId }).then(res => { |
||||||
|
const { process } = res.data.data |
||||||
|
this.process = process |
||||||
|
this.tag.label = '发起流程 - ' + process.name |
||||||
|
resolve(res.data.data) |
||||||
|
}).catch(() => { |
||||||
|
reject() |
||||||
|
}) |
||||||
|
}) |
||||||
|
}, |
||||||
|
/** |
||||||
|
* 发起流程 |
||||||
|
* @param form {"processId": "流程定义id", ...表单自定义字段变量} |
||||||
|
*/ |
||||||
|
handleStartProcess(form) { |
||||||
|
return new Promise((resolve, reject) => { |
||||||
|
startProcess(form).then(() => { |
||||||
|
resolve() |
||||||
|
}).catch(() => { |
||||||
|
reject() |
||||||
|
}) |
||||||
|
}) |
||||||
|
}, |
||||||
|
/** |
||||||
|
* 获取流程任务详情 |
||||||
|
* @param taskId 任务id |
||||||
|
* @param processInsId 流程实例id |
||||||
|
* @returns Promise({"process": "流程实例信息", "form": "表单信息", "flow": "流转信息", "button": "配置按钮信息", "bpmnOption": "流程图配置"}) |
||||||
|
*/ |
||||||
|
getTaskDetail(taskId, processInsId) { |
||||||
|
return new Promise((resolve, reject) => { |
||||||
|
detail({ taskId, processInsId }).then(res => { |
||||||
|
const { process, form, flow, button } = res.data.data |
||||||
|
const { xml } = process |
||||||
|
|
||||||
|
const flows = [] |
||||||
|
flow.forEach(f => { |
||||||
|
const ff = { |
||||||
|
id: f.historyActivityId |
||||||
|
} |
||||||
|
if (f.historyActivityType == 'sequenceFlow') ff.class = "lineWarn" |
||||||
|
else ff.class = "nodeWarn" |
||||||
|
flows.push(ff) |
||||||
|
}) |
||||||
|
|
||||||
|
const bpmnOption = { |
||||||
|
mode: 'view', xml, flows |
||||||
|
} |
||||||
|
this.process = process |
||||||
|
this.flow = flow |
||||||
|
this.buttonList = button |
||||||
|
this.bpmnOption = bpmnOption |
||||||
|
this.tag.label = '流程详情 - ' + process.processDefinitionName |
||||||
|
resolve({ process, form, flow, button, bpmnOption }) |
||||||
|
}).catch(() => { |
||||||
|
reject() |
||||||
|
}) |
||||||
|
}) |
||||||
|
}, |
||||||
|
/** |
||||||
|
* 任务审核 |
||||||
|
* @param pass 驳回/通过 |
||||||
|
*/ |
||||||
|
handleCompleteTask(pass, variables) { |
||||||
|
return new Promise((resolve, reject) => { |
||||||
|
const { comment, copyUser, assignee } = this.$refs.examineForm.examineForm |
||||||
|
if (!pass && !comment) { |
||||||
|
this.$message.error("请填写批复意见") |
||||||
|
this.submitLoading = false |
||||||
|
reject() |
||||||
|
return |
||||||
|
} |
||||||
|
const { taskId, processInstanceId, processDefinitionName, processDefinitionId } = this.process |
||||||
|
const param = { |
||||||
|
taskId, processInstanceId, processDefinitionName, processDefinitionId, pass, |
||||||
|
comment, copyUser, assignee, variables |
||||||
|
} |
||||||
|
completeTask(param).then(() => { |
||||||
|
resolve() |
||||||
|
}).catch(() => { |
||||||
|
reject() |
||||||
|
}) |
||||||
|
}) |
||||||
|
}, |
||||||
|
/** |
||||||
|
* 驳回到指定节点 |
||||||
|
* @param nodeId 节点id |
||||||
|
*/ |
||||||
|
handleRollbackTask(nodeId) { |
||||||
|
const { taskId } = this.process |
||||||
|
rollbackTask({ comment: this.comment, nodeId, taskId }).then(() => { |
||||||
|
this.$message.success("回退成功") |
||||||
|
this.handleCloseTag('/plugin/workflow/process/todo') |
||||||
|
}) |
||||||
|
}, |
||||||
|
/** |
||||||
|
* 终止流程 |
||||||
|
*/ |
||||||
|
handleTerminateProcess() { |
||||||
|
const comment = this.comment |
||||||
|
if (!comment) { |
||||||
|
this.$message.error("请填写批复意见") |
||||||
|
return |
||||||
|
} |
||||||
|
this.$confirm('确定要终止此流程吗?', '警告', { |
||||||
|
type: 'warning' |
||||||
|
}).then(() => { |
||||||
|
const { taskId } = this.process |
||||||
|
|
||||||
|
terminateProcess({ taskId, comment }).then(() => { |
||||||
|
this.$message.success("操作成功") |
||||||
|
this.handleCloseTag('/plugin/workflow/process/todo') |
||||||
|
}) |
||||||
|
}).catch(() => { |
||||||
|
|
||||||
|
}) |
||||||
|
}, |
||||||
|
// 人员选择弹窗
|
||||||
|
handleUserSelect({ type, checkType }) { |
||||||
|
if (!this.comment && ['transfer', 'delegate'].includes(type)) { |
||||||
|
this.$message.error("请填写批复意见") |
||||||
|
return |
||||||
|
} |
||||||
|
this.$refs['user-select'].visible = true |
||||||
|
this.userSelectType = type |
||||||
|
this.checkType = checkType |
||||||
|
}, |
||||||
|
// 选人回调
|
||||||
|
handleUserSelectConfirm(id, name) { |
||||||
|
const { comment, copyUser } = this.$refs.examineForm.examineForm |
||||||
|
const { taskId, processInstanceId, processDefinitionName, processDefinitionId } = this.process |
||||||
|
|
||||||
|
const type = this.userSelectType |
||||||
|
const param = { |
||||||
|
taskId, processInstanceId, processDefinitionName, processDefinitionId, |
||||||
|
assignee: id, |
||||||
|
comment, copyUser |
||||||
|
} |
||||||
|
if (type == 'transfer') { |
||||||
|
transferTask(param).then(() => { // 转办
|
||||||
|
this.$message.success("转办成功") |
||||||
|
this.handleCloseTag('/plugin/workflow/process/todo') |
||||||
|
}) |
||||||
|
} else if (type == 'delegate') { // 委托
|
||||||
|
delegateTask(param).then(() => { |
||||||
|
this.$message.success("委托成功") |
||||||
|
this.handleCloseTag('/plugin/workflow/process/todo') |
||||||
|
}) |
||||||
|
} else if (type == 'copy') { // 抄送
|
||||||
|
this.$refs.examineForm.examineForm.copyUser = id |
||||||
|
this.$refs.examineForm.examineForm.$copyUser = name |
||||||
|
} else if (type == 'assignee') { // 指定下一步审批人
|
||||||
|
this.$refs.examineForm.examineForm.assignee = id |
||||||
|
this.$refs.examineForm.examineForm.$assignee = name |
||||||
|
} |
||||||
|
this.$refs['user-select'].visible = false |
||||||
|
}, |
||||||
|
handlePrint() { //打印
|
||||||
|
// this.watermark({ text: this.watermarkText })
|
||||||
|
Print(this.$refs.printBody) |
||||||
|
}, |
||||||
|
// 关闭当前tag,并跳转
|
||||||
|
handleCloseTag(path) { |
||||||
|
this.$store.commit('DEL_TAG', this.tag) |
||||||
|
if (path) this.$router.push(path) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,134 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<div style="height: 120px;"></div> |
||||||
|
<el-row class="foot-item avue-affix" |
||||||
|
:style="{width: isCollapse? 'calc(100% - 80px)': 'calc(100% - 260px)' }" |
||||||
|
id="avue-view"> |
||||||
|
<el-button v-if="buttonList.find(b => b.key == 'wf_pass')" |
||||||
|
type="success" |
||||||
|
size="medium" |
||||||
|
v-loading="loading" |
||||||
|
@click="$emit('examine', true)">通过</el-button> |
||||||
|
<el-button v-if="buttonList.find(b => b.key == 'wf_reject')" |
||||||
|
type="danger" |
||||||
|
size="medium" |
||||||
|
v-loading="loading" |
||||||
|
@click="$emit('examine', false)">驳回</el-button> |
||||||
|
<el-button v-if="buttonList.find(b => b.key == 'wf_transfer')" |
||||||
|
type="primary" |
||||||
|
size="medium" |
||||||
|
v-loading="loading" |
||||||
|
@click="$emit('user-select', {type: 'transfer', checkType: 'radio'})">转办</el-button> |
||||||
|
<el-button v-if="buttonList.find(b => b.key == 'wf_delegate')" |
||||||
|
type="warning" |
||||||
|
size="medium" |
||||||
|
v-loading="loading" |
||||||
|
@click="$emit('user-select', {type: 'delegate', checkType: 'radio'})">委托</el-button> |
||||||
|
<el-button v-if="buttonList.find(b => b.key == 'wf_print')" |
||||||
|
type="info" |
||||||
|
size="medium" |
||||||
|
v-loading="loading" |
||||||
|
@click="$emit('print')">打印</el-button> |
||||||
|
<el-button v-if="buttonList.find(b => b.key == 'wf_print')" |
||||||
|
type="success" |
||||||
|
size="medium" |
||||||
|
v-loading="loading" |
||||||
|
@click="handleRollback">指定回退</el-button> |
||||||
|
<el-button v-if="buttonList.find(b => b.key == 'wf_terminate')" |
||||||
|
type="danger" |
||||||
|
size="medium" |
||||||
|
v-loading="loading" |
||||||
|
@click="$emit('terminate')">终止</el-button> |
||||||
|
</el-row> |
||||||
|
<el-dialog :visible.sync="nodeVisible" |
||||||
|
append-to-body |
||||||
|
title="选择回退节点"> |
||||||
|
<avue-form v-if="nodeVisible" |
||||||
|
v-model="nodeForm" |
||||||
|
:option="nodeOption" |
||||||
|
@submit="handleNodeSubmit"></avue-form> |
||||||
|
</el-dialog> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import { backNodes } from '@/api/plugin/workflow/process' |
||||||
|
|
||||||
|
import { mapGetters } from 'vuex' |
||||||
|
|
||||||
|
export default { |
||||||
|
name: 'wf-button', |
||||||
|
computed: { |
||||||
|
...mapGetters(['isCollapse']), |
||||||
|
}, |
||||||
|
props: { |
||||||
|
loading: { |
||||||
|
type: Boolean, |
||||||
|
default: false |
||||||
|
}, |
||||||
|
buttonList: { |
||||||
|
type: Array, |
||||||
|
default: () => { |
||||||
|
return [] |
||||||
|
} |
||||||
|
}, |
||||||
|
process: Object, |
||||||
|
comment: String |
||||||
|
}, |
||||||
|
data() { |
||||||
|
return { |
||||||
|
nodeVisible: false, |
||||||
|
nodeForm: {}, |
||||||
|
nodeOption: { |
||||||
|
column: [{ |
||||||
|
label: '节点', |
||||||
|
prop: 'nodeId', |
||||||
|
type: 'select', |
||||||
|
props: { |
||||||
|
label: 'nodeName', |
||||||
|
value: 'nodeId' |
||||||
|
}, |
||||||
|
span: 24, |
||||||
|
rules: [{ required: true, message: '请选择回退节点', trigger: 'change' }] |
||||||
|
}] |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
handleRollback() { // 指定回退 |
||||||
|
if (!this.comment) { |
||||||
|
this.$message.error("请填写批复意见") |
||||||
|
return |
||||||
|
} |
||||||
|
const { taskId } = this.process |
||||||
|
backNodes({ taskId }).then(res => { |
||||||
|
this.findObject(this.nodeOption.column, 'nodeId').dicData = res.data.data |
||||||
|
this.nodeVisible = true |
||||||
|
}) |
||||||
|
}, |
||||||
|
handleNodeSubmit() { // 指定回退确定 |
||||||
|
const { nodeId } = this.nodeForm |
||||||
|
this.$emit('rollback', nodeId) |
||||||
|
}, |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
.foot-item { |
||||||
|
position: fixed; |
||||||
|
bottom: 0; |
||||||
|
margin-left: -20px; |
||||||
|
// right: 0; |
||||||
|
z-index: 101; |
||||||
|
height: 66px; |
||||||
|
background-color: #fff; |
||||||
|
display: flex; |
||||||
|
justify-content: center; |
||||||
|
align-items: center; |
||||||
|
-webkit-transition: 0.3s; |
||||||
|
transition: 0.3s; |
||||||
|
-webkit-box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); |
||||||
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); |
||||||
|
} |
||||||
|
</style> |
||||||
@ -0,0 +1,85 @@ |
|||||||
|
<template> |
||||||
|
<avue-form v-model="examineForm" |
||||||
|
ref="examineForm" |
||||||
|
:option="examineOption"></avue-form> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
export default { |
||||||
|
name: 'wf-exam-form', |
||||||
|
props: { |
||||||
|
process: { |
||||||
|
type: Object, |
||||||
|
default: () => { |
||||||
|
return {} |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
process: { |
||||||
|
handler(val) { |
||||||
|
if (!val) return |
||||||
|
if (val.hideCopy) { |
||||||
|
this.findObject(this.examineOption.column, '$copyUser').display = false |
||||||
|
} |
||||||
|
if (val.hideExamine) { |
||||||
|
this.findObject(this.examineOption.column, '$assignee').display = false |
||||||
|
} |
||||||
|
}, |
||||||
|
deep: true, |
||||||
|
immediate: true |
||||||
|
} |
||||||
|
}, |
||||||
|
data() { |
||||||
|
return { |
||||||
|
examineForm: {}, |
||||||
|
examineOption: { |
||||||
|
menuBtn: false, |
||||||
|
column: [{ |
||||||
|
label: '批复意见', |
||||||
|
prop: 'comment', |
||||||
|
type: 'textarea', |
||||||
|
span: 24, |
||||||
|
event: { |
||||||
|
change: (val) => { |
||||||
|
this.$emit('update:comment', val) |
||||||
|
} |
||||||
|
} |
||||||
|
}, { |
||||||
|
label: '抄送人', |
||||||
|
prop: '$copyUser', |
||||||
|
placeholder: '请选择 抄送人', |
||||||
|
readonly: true, |
||||||
|
append: '+', |
||||||
|
span: 24, |
||||||
|
event: { |
||||||
|
click: () => { |
||||||
|
this.$emit('user-select', { type: 'copy', checkType: 'checkbox' }) |
||||||
|
} |
||||||
|
} |
||||||
|
}, { |
||||||
|
label: '指定审批人', |
||||||
|
prop: '$assignee', |
||||||
|
placeholder: '请选择 下一级审批人,如不选择则使用默认处理人,驳回时无效', |
||||||
|
readonly: true, |
||||||
|
append: '+', |
||||||
|
span: 24, |
||||||
|
event: { |
||||||
|
click: () => { |
||||||
|
this.$emit('user-select', { type: 'assignee', checkType: 'radio' }) |
||||||
|
} |
||||||
|
} |
||||||
|
}] |
||||||
|
}, |
||||||
|
} |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
getComment() { |
||||||
|
return this.examineForm.comment |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
|
<style> |
||||||
|
</style> |
||||||
@ -0,0 +1,40 @@ |
|||||||
|
<template> |
||||||
|
<el-row type="flex"> |
||||||
|
<el-timeline> |
||||||
|
<template v-for="item in flow"> |
||||||
|
<el-timeline-item v-if="item.historyActivityType != 'sequenceFlow'" |
||||||
|
:key="item.id" |
||||||
|
:timestamp="item.endTime || item.createTime" |
||||||
|
placement="top"> |
||||||
|
<el-card shadow="never"> |
||||||
|
<p>{{item.assigneeName}} 在 [{{item.createTime}}] 开始处理 [{{item.historyActivityName}}] 环节</p> |
||||||
|
<p v-if="item.historyActivityDurationTime">任务历时 [{{item.historyActivityDurationTime}}]</p> |
||||||
|
<p v-if="item.commentObj && item.commentObj.type == 'transferComment'">转办意见: [{{item.comment}}]</p> |
||||||
|
<p v-if="item.commentObj && item.commentObj.type == 'delegateComment'">委托意见: [{{item.comment}}]</p> |
||||||
|
<p v-if="item.commentObj && item.commentObj.type == 'rollbackComment'">驳回意见: [{{item.comment}}]</p> |
||||||
|
<p v-if="item.commentObj && item.commentObj.type == 'terminateComment'">终止意见: [{{item.comment}}]</p> |
||||||
|
<p v-if="item.commentObj && item.commentObj.type == 'comment'">审批意见: [{{item.comment}}]</p> |
||||||
|
<p v-if="item.endTime">结束时间: [{{item.endTime}}]</p> |
||||||
|
</el-card> |
||||||
|
</el-timeline-item> |
||||||
|
</template> |
||||||
|
</el-timeline> |
||||||
|
</el-row> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
export default { |
||||||
|
name: 'wf-flow', |
||||||
|
props: { |
||||||
|
flow: { |
||||||
|
type: Array, |
||||||
|
default: () => { |
||||||
|
return [] |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
|
<style> |
||||||
|
</style> |
||||||
@ -0,0 +1,230 @@ |
|||||||
|
<template> |
||||||
|
<basic-container> |
||||||
|
<avue-affix id="avue-view" |
||||||
|
:offset-top="116"> |
||||||
|
<div class="header"> |
||||||
|
<avue-title :value="process.processDefinitionName"></avue-title> |
||||||
|
</div> |
||||||
|
</avue-affix> |
||||||
|
<el-tabs v-model="activeName"> |
||||||
|
<el-tab-pane label="申请信息" |
||||||
|
name="first"> |
||||||
|
<el-card shadow="never"> |
||||||
|
<div ref="printBody"> |
||||||
|
<avue-form v-if="showForm" |
||||||
|
v-model="form" |
||||||
|
ref="form" |
||||||
|
:option="option"> |
||||||
|
</avue-form> |
||||||
|
</div> |
||||||
|
</el-card> |
||||||
|
<el-card shadow="never" |
||||||
|
style="margin-top: 20px" |
||||||
|
v-if="process.status == 'todo'"> |
||||||
|
<wf-examine-form ref="examineForm" |
||||||
|
:comment.sync="comment" |
||||||
|
@user-select="handleUserSelect"></wf-examine-form> |
||||||
|
</el-card> |
||||||
|
</el-tab-pane> |
||||||
|
<el-tab-pane label="流转信息" |
||||||
|
name="second"> |
||||||
|
<el-card shadow="never" |
||||||
|
style="margin-top: 5px;"> |
||||||
|
<wf-flow :flow="flow"></wf-flow> |
||||||
|
</el-card> |
||||||
|
</el-tab-pane> |
||||||
|
<el-tab-pane label="流程跟踪" |
||||||
|
name="third"> |
||||||
|
<template v-if="activeName == 'third'"> |
||||||
|
<el-card shadow="never" |
||||||
|
style="margin-top: 5px;"> |
||||||
|
<wf-design ref="bpmn" |
||||||
|
style="height: 500px;" |
||||||
|
:options="bpmnOption"></wf-design> |
||||||
|
</el-card> |
||||||
|
</template> |
||||||
|
</el-tab-pane> |
||||||
|
</el-tabs> |
||||||
|
|
||||||
|
<!-- 底部按钮 --> |
||||||
|
<template v-if="process.status == 'todo'"> |
||||||
|
<wf-button :loading="submitLoading" |
||||||
|
:button-list="buttonList" |
||||||
|
:process="process" |
||||||
|
:comment="comment" |
||||||
|
@examine="handleExamine" |
||||||
|
@user-select="handleUserSelect" |
||||||
|
@print="handlePrint" |
||||||
|
@rollback="handleRollbackTask" |
||||||
|
@terminate="handleTerminateProcess"></wf-button> |
||||||
|
</template> |
||||||
|
<!-- 人员选择弹窗 --> |
||||||
|
<user-select ref="user-select" |
||||||
|
:check-type="checkType" |
||||||
|
@onConfirm="handleUserSelectConfirm"></user-select> |
||||||
|
<!-- 选择回退节点弹窗 --> |
||||||
|
<el-dialog :visible.sync="nodeVisible" |
||||||
|
append-to-body |
||||||
|
title="选择回退节点"> |
||||||
|
<avue-form v-model="nodeForm" |
||||||
|
:option="nodeOption" |
||||||
|
@submit="handleNodeSubmit"></avue-form> |
||||||
|
</el-dialog> |
||||||
|
</basic-container> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import WfExamineForm from '@/views/plugin/workflow/process/components/examForm.vue' |
||||||
|
import WfButton from '@/views/plugin/workflow/process/components/button.vue' |
||||||
|
import WfFlow from '@/views/plugin/workflow/process/components/flow.vue' |
||||||
|
import userSelect from '@/views/plugin/workflow/process/components/user-select' |
||||||
|
|
||||||
|
import exForm from '@/views/plugin/workflow/mixins/ex-form' |
||||||
|
|
||||||
|
export default { |
||||||
|
mixins: [exForm], |
||||||
|
components: { userSelect, WfExamineForm, WfButton, WfFlow }, |
||||||
|
watch: { |
||||||
|
'$route.query.p': { |
||||||
|
handler(val) { |
||||||
|
if (val) { |
||||||
|
const param = JSON.parse(Buffer.from(val, 'base64').toString()) |
||||||
|
const { taskId, processInsId } = param |
||||||
|
if (taskId && processInsId) this.getDetail(taskId, processInsId) |
||||||
|
} |
||||||
|
}, |
||||||
|
immediate: true |
||||||
|
} |
||||||
|
}, |
||||||
|
data() { |
||||||
|
return { |
||||||
|
activeName: 'first', |
||||||
|
showForm: false, |
||||||
|
form: {}, |
||||||
|
option: { |
||||||
|
column: [{ |
||||||
|
label: '请假时间', |
||||||
|
prop: 'datetime', |
||||||
|
type: 'datetimerange', |
||||||
|
format: 'yyyy-MM-dd HH:mm:ss', |
||||||
|
valueFormat: 'yyyy-MM-dd HH:mm:ss', |
||||||
|
rules: [{ required: true, message: '请选择请假时间' }] |
||||||
|
}, { |
||||||
|
label: '请假天数', |
||||||
|
prop: 'days', |
||||||
|
type: 'number', |
||||||
|
rules: [{ required: true, message: '请输入请假天数' }] |
||||||
|
}, { |
||||||
|
label: '请假理由', |
||||||
|
prop: 'reason', |
||||||
|
type: 'textarea', |
||||||
|
span: 24, |
||||||
|
rules: [{ required: true, message: '请输入请假理由' }] |
||||||
|
}] |
||||||
|
}, |
||||||
|
vars: [], // 需要提交的字段 |
||||||
|
submitLoading: false, // 提交时按钮loading |
||||||
|
} |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
// 获取任务详情 |
||||||
|
getDetail(taskId, processInsId) { |
||||||
|
this.getTaskDetail(taskId, processInsId).then(res => { |
||||||
|
const { process, form } = res |
||||||
|
const { variables, status } = process |
||||||
|
|
||||||
|
let { taskForm } = form |
||||||
|
const option = this.option |
||||||
|
option.menuBtn = false |
||||||
|
const { column, group } = option |
||||||
|
if (status != 'todo') { // 已办,删除字段默认值 |
||||||
|
option.detail = true |
||||||
|
if (column && column.length > 0) { // 处理column |
||||||
|
column.forEach(col => { |
||||||
|
if (col.type == 'dynamic') col.children.column.forEach(cc => delete cc.value) |
||||||
|
else delete col.value |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
if (group && group.length > 0) { // 处理group |
||||||
|
group.forEach(gro => { |
||||||
|
if (gro.column && gro.column.length > 0) { |
||||||
|
gro.column.forEach(col => { |
||||||
|
if (col.type == 'dynamic') col.children.column.forEach(cc => delete cc.value) |
||||||
|
else delete col.value |
||||||
|
}) |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
} else { |
||||||
|
const columnFilter = this.filterAvueColumn(column, taskForm) |
||||||
|
const columnArr = columnFilter.column |
||||||
|
let vars = columnFilter.vars |
||||||
|
|
||||||
|
const groupArr = [] |
||||||
|
if (group && group.length > 0) { // 处理group |
||||||
|
group.forEach(gro => { |
||||||
|
const groupFilter = this.filterAvueColumn(gro.column, taskForm) |
||||||
|
gro.column = groupFilter.column |
||||||
|
vars = vars.conact(groupFilter.vars) |
||||||
|
if (gro.column.length > 0) groupArr.push(gro) |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
if (process.variables && process.variables.serialNumber) { |
||||||
|
columnArr.unshift({ |
||||||
|
label: '流水号', |
||||||
|
prop: 'serialNumber', |
||||||
|
span: 24, |
||||||
|
detail: true, |
||||||
|
}) |
||||||
|
} |
||||||
|
option.column = columnArr |
||||||
|
option.group = groupArr |
||||||
|
this.vars = vars |
||||||
|
} |
||||||
|
for (let key in variables) { |
||||||
|
if (!variables[key]) delete variables[key] |
||||||
|
} |
||||||
|
|
||||||
|
this.option = option |
||||||
|
this.form = variables |
||||||
|
this.showForm = true |
||||||
|
}) |
||||||
|
}, |
||||||
|
// 审核 |
||||||
|
handleExamine(pass) { |
||||||
|
this.submitLoading = true |
||||||
|
this.$refs.form.validate((valid) => { |
||||||
|
if (valid) { |
||||||
|
const variables = {} |
||||||
|
this.vars.forEach(v => { |
||||||
|
if (v != 'comment' && this.form[v]) variables[v] = this.form[v] |
||||||
|
}) |
||||||
|
|
||||||
|
this.handleCompleteTask(pass, variables).then(() => { |
||||||
|
this.$message.success("处理成功") |
||||||
|
this.handleCloseTag('/plugin/workflow/process/todo') |
||||||
|
}).catch(() => { |
||||||
|
this.submitLoading = false |
||||||
|
}) |
||||||
|
} else { |
||||||
|
this.submitLoading = false |
||||||
|
} |
||||||
|
}) |
||||||
|
}, |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
.header { |
||||||
|
width: 100%; |
||||||
|
height: 50px; |
||||||
|
background: #fff; |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: space-between; |
||||||
|
padding: 0 10px 10px 0; |
||||||
|
} |
||||||
|
</style> |
||||||
@ -0,0 +1,99 @@ |
|||||||
|
<template> |
||||||
|
<basic-container> |
||||||
|
<avue-title style="margin-bottom: 20px; " |
||||||
|
:styles="{fontSize: '20px'}" |
||||||
|
:value="process.name"></avue-title> |
||||||
|
<!-- 自定义表单区域 --> |
||||||
|
<avue-form v-if="option && ((option.column && option.column.length > 0) || (option.group && option.group.length > 0))" |
||||||
|
v-model="form" |
||||||
|
ref="form" |
||||||
|
:option="option" |
||||||
|
@submit="handleSubmit"> |
||||||
|
</avue-form> |
||||||
|
<!-- 自定义表单区域 --> |
||||||
|
</basic-container> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import exForm from '@/views/plugin/workflow/mixins/ex-form' |
||||||
|
|
||||||
|
export default { |
||||||
|
mixins: [exForm], |
||||||
|
watch: { |
||||||
|
'$route.query.p': { |
||||||
|
handler(val) { |
||||||
|
if (val) { |
||||||
|
const param = JSON.parse(Buffer.from(val, 'base64').toString()) |
||||||
|
const { processId } = param |
||||||
|
if (processId) this.getForm(processId) |
||||||
|
} |
||||||
|
}, |
||||||
|
immediate: true |
||||||
|
} |
||||||
|
}, |
||||||
|
data() { |
||||||
|
return { |
||||||
|
form: {}, |
||||||
|
option: { |
||||||
|
column: [{ |
||||||
|
label: '请假时间', |
||||||
|
prop: 'datetime', |
||||||
|
type: 'datetimerange', |
||||||
|
format: 'yyyy-MM-dd HH:mm:ss', |
||||||
|
valueFormat: 'yyyy-MM-dd HH:mm:ss', |
||||||
|
rules: [{ required: true, message: '请选择请假时间' }] |
||||||
|
}, { |
||||||
|
label: '请假天数', |
||||||
|
prop: 'days', |
||||||
|
type: 'number', |
||||||
|
rules: [{ required: true, message: '请输入请假天数' }] |
||||||
|
}, { |
||||||
|
label: '请假理由', |
||||||
|
prop: 'reason', |
||||||
|
type: 'textarea', |
||||||
|
span: 24, |
||||||
|
rules: [{ required: true, message: '请输入请假理由' }] |
||||||
|
}] |
||||||
|
}, |
||||||
|
process: {} |
||||||
|
} |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
getForm(processId) { |
||||||
|
this.getStartForm(processId).then(res => { |
||||||
|
let { process, startForm } = res |
||||||
|
this.process = process |
||||||
|
this.form.processId = process.id |
||||||
|
|
||||||
|
if (startForm && startForm.length > 0) { |
||||||
|
const option = this.option |
||||||
|
const { column, group } = option |
||||||
|
|
||||||
|
const groupArr = [] |
||||||
|
const columnArr = this.filterAvueColumn(column, startForm).column |
||||||
|
if (group && group.length > 0) { // 处理group |
||||||
|
group.forEach(gro => { |
||||||
|
gro.column = this.filterAvueColumn(gro.column, startForm).column |
||||||
|
if (gro.column.length > 0) groupArr.push(gro) |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
option.column = columnArr |
||||||
|
option.group = groupArr |
||||||
|
this.option = option |
||||||
|
} |
||||||
|
}) |
||||||
|
}, |
||||||
|
handleSubmit(form, done) { |
||||||
|
this.handleStartProcess(form).then(() => { |
||||||
|
this.$message.success("发起成功") |
||||||
|
done() |
||||||
|
this.handleCloseTag('/plugin/workflow/process/send') |
||||||
|
}) |
||||||
|
}, |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
|
<style> |
||||||
|
</style> |
||||||
@ -0,0 +1,152 @@ |
|||||||
|
<template> |
||||||
|
<basic-container> |
||||||
|
<avue-affix id="avue-view" |
||||||
|
:offset-top="116"> |
||||||
|
<div class="header"> |
||||||
|
<avue-title :value="process.processDefinitionName"></avue-title> |
||||||
|
</div> |
||||||
|
</avue-affix> |
||||||
|
<el-tabs v-model="activeName"> |
||||||
|
<el-tab-pane label="申请信息" |
||||||
|
name="first"> |
||||||
|
<el-card shadow="never"> |
||||||
|
<div ref="printBody"> |
||||||
|
<!-- 自定义表单区域 --> |
||||||
|
|
||||||
|
<!-- 自定义表单区域 --> |
||||||
|
</div> |
||||||
|
</el-card> |
||||||
|
<!-- 审批意见表单 --> |
||||||
|
<el-card shadow="never" |
||||||
|
style="margin-top: 20px" |
||||||
|
v-if="process.status == 'todo'"> |
||||||
|
<wf-examine-form ref="examineForm" |
||||||
|
:comment.sync="comment" |
||||||
|
@user-select="handleUserSelect"></wf-examine-form> |
||||||
|
</el-card> |
||||||
|
</el-tab-pane> |
||||||
|
<!-- 流转信息 --> |
||||||
|
<el-tab-pane label="流转信息" |
||||||
|
name="second"> |
||||||
|
<el-card shadow="never" |
||||||
|
style="margin-top: 5px;"> |
||||||
|
<wf-flow :flow="flow"></wf-flow> |
||||||
|
</el-card> |
||||||
|
</el-tab-pane> |
||||||
|
<!-- 流程图 --> |
||||||
|
<el-tab-pane label="流程跟踪" |
||||||
|
name="third"> |
||||||
|
<template v-if="activeName == 'third'"> |
||||||
|
<el-card shadow="never" |
||||||
|
style="margin-top: 5px;"> |
||||||
|
<wf-design ref="bpmn" |
||||||
|
style="height: 500px;" |
||||||
|
:options="bpmnOption"></wf-design> |
||||||
|
</el-card> |
||||||
|
</template> |
||||||
|
</el-tab-pane> |
||||||
|
</el-tabs> |
||||||
|
|
||||||
|
<!-- 底部按钮 --> |
||||||
|
<template v-if="process.status == 'todo'"> |
||||||
|
<wf-button :loading="submitLoading" |
||||||
|
:button-list="buttonList" |
||||||
|
:process="process" |
||||||
|
:comment="comment" |
||||||
|
@examine="handleExamine" |
||||||
|
@user-select="handleUserSelect" |
||||||
|
@print="handlePrint" |
||||||
|
@rollback="handleRollbackTask" |
||||||
|
@terminate="handleTerminateProcess"></wf-button> |
||||||
|
</template> |
||||||
|
<!-- 人员选择弹窗 --> |
||||||
|
<user-select ref="user-select" |
||||||
|
:check-type="checkType" |
||||||
|
@onConfirm="handleUserSelectConfirm"></user-select> |
||||||
|
</basic-container> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import WfExamineForm from '@/views/plugin/workflow/process/components/examForm.vue' |
||||||
|
import WfButton from '@/views/plugin/workflow/process/components/button.vue' |
||||||
|
import WfFlow from '@/views/plugin/workflow/process/components/flow.vue' |
||||||
|
import userSelect from '@/views/plugin/workflow/process/components/user-select' |
||||||
|
|
||||||
|
import exForm from '@/views/plugin/workflow/mixins/ex-form' |
||||||
|
|
||||||
|
export default { |
||||||
|
mixins: [exForm], |
||||||
|
components: { userSelect, WfExamineForm, WfButton, WfFlow }, |
||||||
|
watch: { |
||||||
|
'$route.query.p': { |
||||||
|
handler(val) { |
||||||
|
if (val) { |
||||||
|
const param = JSON.parse(Buffer.from(val, 'base64').toString()) |
||||||
|
const { taskId, processInsId } = param |
||||||
|
if (taskId && processInsId) this.getDetail(taskId, processInsId) |
||||||
|
} |
||||||
|
}, |
||||||
|
immediate: true |
||||||
|
} |
||||||
|
}, |
||||||
|
data() { |
||||||
|
return { |
||||||
|
activeName: 'first', |
||||||
|
form: {}, |
||||||
|
option: {}, // 表单配置 |
||||||
|
vars: [], // 需要提交的字段 |
||||||
|
submitLoading: false, // 提交时按钮loading |
||||||
|
} |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
// 获取任务详情 |
||||||
|
getDetail(taskId, processInsId) { |
||||||
|
this.getTaskDetail(taskId, processInsId).then(res => { |
||||||
|
const { process, form } = res |
||||||
|
const { variables, status } = process |
||||||
|
|
||||||
|
let { taskForm } = form |
||||||
|
console.log("process", process) |
||||||
|
console.log("taskForm", taskForm) |
||||||
|
console.log("variables", variables) |
||||||
|
console.log("status", status) // todo待办 done已办 |
||||||
|
|
||||||
|
// 自行处理相关逻辑 |
||||||
|
}) |
||||||
|
}, |
||||||
|
// 审核 |
||||||
|
handleExamine(pass) { |
||||||
|
this.submitLoading = true |
||||||
|
this.$refs.form.validate((valid) => { |
||||||
|
if (valid) { |
||||||
|
const variables = {} |
||||||
|
this.vars.forEach(v => { |
||||||
|
if (v != 'comment' && this.form[v]) variables[v] = this.form[v] |
||||||
|
}) |
||||||
|
|
||||||
|
this.handleCompleteTask(pass, variables).then(() => { |
||||||
|
this.$message.success("处理成功") |
||||||
|
this.handleCloseTag('/plugin/workflow/process/todo') |
||||||
|
}).catch(() => { |
||||||
|
this.submitLoading = false |
||||||
|
}) |
||||||
|
} else { |
||||||
|
this.submitLoading = false |
||||||
|
} |
||||||
|
}) |
||||||
|
}, |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
.header { |
||||||
|
width: 100%; |
||||||
|
height: 50px; |
||||||
|
background: #fff; |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: space-between; |
||||||
|
padding: 0 10px 10px 0; |
||||||
|
} |
||||||
|
</style> |
||||||
@ -0,0 +1,58 @@ |
|||||||
|
<template> |
||||||
|
<basic-container> |
||||||
|
<avue-title style="margin-bottom: 20px; " |
||||||
|
:styles="{fontSize: '20px'}" |
||||||
|
:value="process.name"></avue-title> |
||||||
|
<!-- 自定义表单区域 --> |
||||||
|
|
||||||
|
|
||||||
|
<!-- 自定义表单区域 --> |
||||||
|
</basic-container> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import exForm from '@/views/plugin/workflow/mixins/ex-form' |
||||||
|
|
||||||
|
export default { |
||||||
|
mixins: [exForm], |
||||||
|
watch: { |
||||||
|
'$route.query.p': { |
||||||
|
handler(val) { |
||||||
|
if (val) { |
||||||
|
const param = JSON.parse(Buffer.from(val, 'base64').toString()) |
||||||
|
const { processId } = param |
||||||
|
if (processId) this.getForm(processId) |
||||||
|
} |
||||||
|
}, |
||||||
|
immediate: true |
||||||
|
} |
||||||
|
}, |
||||||
|
data() { |
||||||
|
return { |
||||||
|
form: {}, |
||||||
|
option: {}, |
||||||
|
process: {} |
||||||
|
} |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
getForm(processId) { |
||||||
|
this.getStartForm(processId).then(res => { |
||||||
|
let { process, startForm } = res |
||||||
|
console.log("process", process) |
||||||
|
console.log("startForm", startForm) |
||||||
|
// 自行处理相关逻辑 |
||||||
|
}) |
||||||
|
}, |
||||||
|
handleSubmit(form, done) { |
||||||
|
this.handleStartProcess(form).then(() => { |
||||||
|
this.$message.success("发起成功") |
||||||
|
done() |
||||||
|
this.handleCloseTag('/plugin/workflow/process/send') |
||||||
|
}) |
||||||
|
}, |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
|
<style> |
||||||
|
</style> |
||||||
Loading…
Reference in new issue