<template>
<el-dialog lock-scroll :title="dialogTitleMap[action]" @open="openDialog" :visible.sync="dialogVisible"
top="2%" width="80%" :close-on-click-modal="false" :close-on-press-escape="false" :before-close='handleCancel'>
<el-form :model="activitiEntity" :rules="rules" ref="activitiDialog" label-width="100px">
<el-row>
<el-col :span="12">
<el-form-item label="流程名称:" prop="name">
<el-input v-model="activitiEntity.name"></el-input>
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item label="流程代码:" prop="code">
<el-input :disabled="action === 'edit'" v-model="activitiEntity.code"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="22">
<el-form-item label="流程备注:" prop="memo">
<el-input type="textarea" v-model="activitiEntity.memo"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="20">
<el-form-item label="流程列表:"></el-form-item>
</el-col>
<el-col :span="2">
<el-button @click="addNode">添加流程节点</el-button>
</el-col>
</el-row>
<el-row>
<el-col :span="23">
<el-table style="margin-top: -10px;" fit :data="activitiEntity.nodes" :key='tableKey'>
<el-table-column align="center" label="序号" width="50px;" type="index"></el-table-column>
<el-table-column align="center" label="节点名称" min-width="150px">
<template slot-scope="scope">
<span v-if="scope.$index === 0 || scope.$index === activitiEntity.nodes.length - 1">{{scope.row.name}}</span>
<el-form-item v-else labelWidth="0" :prop="'nodes.'+scope.$index+'.name'"
:rules="[{required: true, message: '请填写节点名称', trigger: 'blur'},
{validator: nodeNameCheck, trigger: ['blur']}]">
<el-input v-model="scope.row.name"></el-input>
</el-form-item>
</template>
</el-table-column>
<el-table-column align="center" label="接收部门" min-width="190px">
<template slot-scope="scope" width="100%">
<span v-if="scope.$index === 0 || scope.$index === 1 || scope.$index === activitiEntity.nodes.length - 1"></span>
<el-form-item v-else labelWidth="0" :prop="'nodes.'+scope.$index+'.path'" :rules="{required: true, message: '请选择接收部门', trigger: ['blur','change']}">
<el-cascader
v-model="scope.row.path"
:options="orgTree"
@change="orgChange(scope.row, (scope.$index), true)"
show-all-levels
filterable
clearable
placeholder="请选择"
></el-cascader>
</el-form-item>
</template>
</el-table-column>
<el-table-column align="center" label="消息通知人" min-width="140px">
<template slot-scope="scope" width="100%">
<span v-if="scope.$index === 0 || scope.$index === 1 || scope.$index === activitiEntity.nodes.length - 1"></span>
<el-form-item v-else labelWidth="0" :prop="'nodes.'+scope.$index+'.notifier'">
<el-select v-model="scope.row.notifier" placeholder="请选择" multiple>
<el-option v-for="item in userOptions[scope.$index-2]" :key="item.id" :label="item.name" :value="item.id">
</el-option>
</el-select>
</el-form-item>
</template>
</el-table-column>
<el-table-column align="center" label="办理时效(工作日)" min-width="110px">
<template slot-scope="scope">
<span v-if="scope.$index === 0 || scope.$index === 1 || scope.$index === activitiEntity.nodes.length - 1"></span>
<el-form-item v-else labelWidth="0" :rules="[{validator: nodePositiveIntegerCheck, trigger: ['blur']}]" :prop="'nodes.'+scope.$index+'.limitDays'">
<el-input style="width: 80px;" v-model.number="scope.row.limitDays"></el-input>
</el-form-item>
</template>
</el-table-column>
<el-table-column align="center" label="剩余提醒天数" min-width="100px">
<template slot-scope="scope">
<span v-if="scope.$index === 0 || scope.$index === 1 || scope.$index === activitiEntity.nodes.length - 1"></span>
<el-form-item v-else labelWidth="0" :rules="[{validator: nodePositiveIntegerCheck, trigger: ['blur']}]" :prop="'nodes.'+scope.$index+'.remindDays'">
<el-input style="width: 80px;" v-model.number="scope.row.remindDays"></el-input>
</el-form-item>
</template>
</el-table-column>
<el-table-column align="center" label="流程顺序" min-width="80px">
<template slot-scope="scope">
<el-input style="width: 60px;text-align: right;" disabled v-model="scope.row.sequence"></el-input>
</template>
</el-table-column>
<el-table-column align="center" label="操作" class-name="small-padding" min-width="90px">
<template slot-scope="scope">
<el-button type="text" plain icon="el-icon-minus"
v-if="scope.$index !== 0 && scope.$index !== activitiEntity.nodes.length - 1"
@click="minusNode(scope.$index)">删除节点</el-button>
</template>
</el-table-column>
</el-table>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="handleCancel">返 回</el-button>
<el-button icon="el-icon-check" type="primary" @click="handleConfirm('activitiDialog')">确 认</el-button>
</div>
</el-dialog>
</template>
<script>
import { saveDefinition, updateDefinition, findDefinitionDetail } from '@/api/activiti'
import { findListByOrgId } from '@/api/egov'
import { getTreeDataDept3 } from '@/api/transferTree'
export default {
props: ['action', 'activiti', 'dialogVisible'],
data() {
return {
activitiEntity: {
code: null,
name: null,
version: null,
memo: null,
nodes: [
{ name: 'start', receiver: null, limitDays: null, remindDays: null, sequence: 1, path: [], notifier: [] },
{ name: 'end', receiver: null, limitDays: null, remindDays: null, sequence: 2, path: [], notifier: [] }
]
},
tableKey: '1',
dialogTitleMap: {
'add': '流程添加',
'edit': '流程编辑'
},
userOptions: [],
orgTree: [],
rules: {
name: [{ required: true, message: '请填写流程名称', trigger: 'blur' }],
code: [{ required: true, message: '请填写流程代码', trigger: 'blur' }]
}
}
},
methods: {
nodeNameCheck(rule, value, callback) {
if (value === '') {
callback(new Error('请输入节点名称'))
} else if (value === 'start' || value === 'end') {
callback(new Error('节点名称不可为' + value))
} else {
const nodeArr = this.activitiEntity.nodes
const indexArr = rule.field ? rule.field.split('.') : []
let index = null
if (indexArr && indexArr.length > 1) {
index = indexArr[1]
}
if (nodeArr && nodeArr.length > 0) {
for (var i = 0; i < nodeArr.length; i++) {
if (value === nodeArr[i].name && ((i + '') !== index)) {
callback(new Error('该节点名称已存在'))
break
} else if (i === nodeArr.length - 1) {
callback()
}
}
}
callback()
}
},
nodePositiveIntegerCheck(rule, value, callback) {
if (value) {
const reg = /^[1-9]\d*$/
const result = reg.test(value)
if (result) {
callback()
} else {
callback(new Error('请输入整数'))
}
} else {
callback()
}
},
openDialog() {
this.getTransferTreeData()
this.action === 'edit' ? this.getAcDetail() : this.resetEntity()
},
handleConfirm(formName) {
this.action === 'edit' ? this.updateActiviti(formName) : this.saveActiviti(formName)
},
getTransferTreeData() {
const result = getTreeDataDept3()
this.orgTree = result
},
getAcDetail() {
findDefinitionDetail({ id: this.activiti.id }).then(response => {
this.activitiEntity = response.data.result
const tt = response.data.result
if (response.data.result && tt.content) {
const temp = JSON.parse(tt.content)
if (temp && temp.nodes) {
const nodes = temp.nodes
nodes.forEach((n, i) => {
if (i > 1) {
this.orgChange(n, i, false)
}
let notifier = n.notifier
if (notifier && notifier.length > 0) {
const temp = []
for (const t of notifier) {
temp.push(t.userId)
}
notifier = temp
} else {
notifier = []
}
n.notifier = notifier
})
this.activitiEntity.nodes = nodes
}
}
})
},
addNode() {
const endNode = this.activitiEntity.nodes.pop()
this.activitiEntity.nodes.push(this.newNode())
endNode.sequence = this.activitiEntity.nodes.length + 1
this.activitiEntity.nodes.push(endNode)
if (endNode.sequence > 3) {
this.userOptions.push([])
}
},
minusNode(index) {
this.activitiEntity.nodes.splice(index, 1)
for (let i = index; i < this.activitiEntity.nodes.length; i++) {
this.activitiEntity.nodes[i].sequence = i + 1
}
if (index > 1) {
this.userOptions.splice(index - 2, 1)
}
},
newNode() {
return {
name: null,
receiver: null,
path: [],
limitDays: null,
remindDays: null,
notifier: [],
sequence: this.activitiEntity.nodes.length + 1
}
},
orgChange(row, ind, isActive) {
if (row && row.path) {
const val = row.path
if (val && val.length > 0) {
const index = val.length - 1
row.receiver = val[index]
this.getUserOption(val[index], ind, isActive)
} else {
row.receiver = null
}
}
},
getUserOption(orgId, ind, isActive) {
if (orgId && ind > 1) {
findListByOrgId({ id: orgId }).then(response => {
if (response.data.result && response.data.result.length > 0) {
this.userOptions[ind - 2] = response.data.result
if (isActive) {
this.activitiEntity.nodes[ind].notifier = []
}
}
})
}
},
transferNotifiers() {
const nodes = this.activitiEntity.nodes
const userOptions = this.userOptions
if (nodes && nodes.length > 0) {
nodes.forEach((node, ind) => {
const notifier = node.notifier
if (notifier && notifier.length > 0) {
const options = userOptions[ind - 2]
notifier.forEach((n, i) => {
const obj = options.find((it) => {
return it.id === n
})
if (obj) {
const t = { userId: obj.id, userName: obj.name }
this.activitiEntity.nodes[ind].notifier[i] = t
}
})
}
})
}
},
saveActiviti(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
this.activitiEntity['content'] = null
this.transferNotifiers()
saveDefinition(this.activitiEntity).then(res => {
const data = res.data
if (data.success) {
this.$notify({
title: '成功',
message: '新增成功',
type: 'success',
duration: 2000
})
} else {
this.$notify({
title: '失败',
message: '新增失败',
type: 'error',
duration: 2000
})
}
this.handleCancel()
})
} else {
return
}
})
},
updateActiviti(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
this.activitiEntity['content'] = null
this.transferNotifiers()
updateDefinition(this.activitiEntity).then(res => {
const data = res.data
if (data.success) {
this.$notify({
title: '成功',
message: '更新成功',
type: 'success',
duration: 2000
})
} else {
this.$notify({
title: '失败',
message: '更新失败',
type: 'error',
duration: 2000
})
}
this.handleCancel()
})
} else {
return
}
})
},
resetEntity() {
this.userOptions = []
this.activitiEntity = {
code: null,
name: null,
version: null,
memo: null,
nodes: [
{ name: 'start', receiver: null, limitDays: null, remindDays: null, sequence: 1, path: [], notifier: [] },
{ name: 'end', receiver: null, limitDays: null, remindDays: null, sequence: 2, path: [], notifier: [] }]
}
},
handleCancel() {
this.$emit('closeDialog')
this.resetEntity()
this.$nextTick(() => {
this.$refs['activitiDialog'].clearValidate()
})
}
}
}
</script>
<style scoped>
.el-form-item--mini.el-form-item, .el-form-item--small.el-form-item {
margin-bottom: 15px !important;
}
.el-cascader {
display: block !important;
}
</style>