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