clay commit : workflow开始解析
This commit is contained in:
parent
e08d6e691e
commit
dff930eb6f
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
spring:
|
||||
profiles:
|
||||
active: pro
|
||||
active: dev
|
||||
|
||||
mybatis:
|
||||
type-aliases-package: cn.odliken.flow.pojo
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -39,6 +39,7 @@ import FormBaseSetting from '@/views/admin/layout/FormBaseSetting'
|
|||
import FormDesign from '@/views/admin/layout/FormDesign'
|
||||
import ProcessDesign from '@/views/admin/layout/ProcessDesign'
|
||||
import FormProSetting from '@/views/admin/layout/FormProSetting'
|
||||
import axios from "axios";
|
||||
|
||||
export default {
|
||||
name: "FormProcessDesign",
|
||||
|
|
@ -60,15 +61,15 @@ export default {
|
|||
{title: '扩展设置', description: '', icon: '', status: ''}
|
||||
],
|
||||
validComponents: ['baseSetting', 'formSetting', 'processDesign', 'proSetting'],
|
||||
array:[],
|
||||
array: [],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
setup() {
|
||||
return this.$store.state.design
|
||||
},
|
||||
errTitle(){
|
||||
if (this.validResult.finished && !this.validResult.success){
|
||||
errTitle() {
|
||||
if (this.validResult.finished && !this.validResult.success) {
|
||||
return this.validResult.title + ` (${this.validResult.errs.length}项错误) 😥`
|
||||
}
|
||||
return this.validResult.title
|
||||
|
|
@ -131,9 +132,10 @@ export default {
|
|||
},
|
||||
groupId: undefined,
|
||||
formItems: [],
|
||||
process: {
|
||||
process: [
|
||||
{
|
||||
id: "root",
|
||||
parentId: null,
|
||||
parentId: "admin",
|
||||
type: "ROOT",
|
||||
name: "发起人",
|
||||
desc: "任何人",
|
||||
|
|
@ -141,8 +143,13 @@ export default {
|
|||
assignedUser: [],
|
||||
formPerms: []
|
||||
},
|
||||
children: {}
|
||||
},
|
||||
{
|
||||
id: "end",
|
||||
parentId: "root",
|
||||
type: "END",
|
||||
}
|
||||
],
|
||||
remark: "备注说明"
|
||||
})
|
||||
},
|
||||
|
|
@ -220,16 +227,15 @@ export default {
|
|||
}
|
||||
},
|
||||
|
||||
tarry(node){
|
||||
if (node&&node.id){
|
||||
tarry(node) {
|
||||
if (node && node.id) {
|
||||
let newNode = {...node}
|
||||
newNode.children=null
|
||||
newNode.children = null
|
||||
this.array.push(newNode)
|
||||
this.tarry(node.children)
|
||||
}
|
||||
|
||||
|
||||
|
||||
},
|
||||
stopTimer() {
|
||||
if (this.timer) {
|
||||
|
|
@ -239,8 +245,106 @@ export default {
|
|||
preview() {
|
||||
this.validateDesign()
|
||||
},
|
||||
//发布流程
|
||||
publishProcess() {
|
||||
this.validateDesign()
|
||||
this.testPublish()
|
||||
// this.validateDesign()
|
||||
},
|
||||
getToken() {
|
||||
axios.post(
|
||||
// "http://localhost:8000/auth/login",
|
||||
"http://gateway.odliken.cn/auth/login",
|
||||
{
|
||||
code: "string",
|
||||
password: "926425",
|
||||
username: "admin",
|
||||
uuid: "string"
|
||||
}
|
||||
).then(res => {
|
||||
console.log(res)
|
||||
sessionStorage.setItem("token", res.data.data)
|
||||
this.testPublish()
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
testPublish() {
|
||||
// this.toAjaxAdd()
|
||||
let token = sessionStorage.getItem("token");
|
||||
console.log(token)
|
||||
if (!token) {
|
||||
this.getToken();
|
||||
}
|
||||
|
||||
let templates = {
|
||||
formId: this.setup.formId,
|
||||
formName: this.setup.formName,
|
||||
logo: this.setup.logo,
|
||||
settings: this.setup.settings,
|
||||
groupId: this.setup.groupId,
|
||||
formItems: this.setup.formItems,
|
||||
process: this.setup.process,
|
||||
remark: this.setup.remark
|
||||
}
|
||||
|
||||
|
||||
|
||||
console.log(JSON.stringify(templates))
|
||||
console.log("获取到token")
|
||||
axios({
|
||||
method: "post",
|
||||
url: "http://localhost:8000/workflow/process",
|
||||
data: this.setup.process,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
"authorization": token
|
||||
},
|
||||
}).then(res => {
|
||||
console.log(res.data)
|
||||
})
|
||||
|
||||
},
|
||||
|
||||
|
||||
toAjaxAdd() {
|
||||
console.log(this.setup, "数据的哈客户大客户")
|
||||
let template = {
|
||||
formId: this.setup.formId,
|
||||
formName: this.setup.formName,
|
||||
logo: JSON.stringify(this.setup.logo),
|
||||
settings: JSON.stringify(this.setup.settings),
|
||||
groupId: this.setup.groupId,
|
||||
formItems: JSON.stringify(this.setup.formItems),
|
||||
process: JSON.stringify(this.setup.process),
|
||||
remark: this.setup.remark
|
||||
}
|
||||
createForm(template).then(rsp => {
|
||||
this.$message.success("创建表单成功")
|
||||
this.$router.push("/formsPanel")
|
||||
}).catch(err => {
|
||||
this.$message.error(err)
|
||||
})
|
||||
|
||||
},
|
||||
toAjaxEdit() {
|
||||
console.log(this.setup)
|
||||
let template = {
|
||||
formId: this.setup.formId,
|
||||
formName: this.setup.formName,
|
||||
logo: JSON.stringify(this.setup.logo),
|
||||
settings: JSON.stringify(this.setup.settings),
|
||||
groupId: this.setup.groupId,
|
||||
formItems: JSON.stringify(this.setup.formItems),
|
||||
process: JSON.stringify(this.setup.process),
|
||||
remark: this.setup.remark
|
||||
}
|
||||
console.log(JSON.stringify(template))
|
||||
updateFormDetail(template).then(rsp => {
|
||||
this.$message.success("更新表单成功")
|
||||
this.$router.push("/formsPanel")
|
||||
}).catch(err => {
|
||||
this.$message.error(err)
|
||||
})
|
||||
},
|
||||
// todo 提交数据
|
||||
doPublish() {
|
||||
|
|
@ -295,10 +399,11 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
.err-info{
|
||||
.err-info {
|
||||
max-height: 180px;
|
||||
overflow-y: auto;
|
||||
& > div{
|
||||
|
||||
& > div {
|
||||
padding: 5px;
|
||||
margin: 2px 0;
|
||||
width: 220px;
|
||||
|
|
@ -306,7 +411,8 @@ export default {
|
|||
border-radius: 3px;
|
||||
background: rgb(242 242 242);
|
||||
}
|
||||
i{
|
||||
|
||||
i {
|
||||
margin: 0 5px;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,436 @@
|
|||
<template>
|
||||
<el-container>
|
||||
<el-header style="background: white">
|
||||
<layout-header v-model="activeSelect" @publish="publishProcess" @preview="preview"></layout-header>
|
||||
</el-header>
|
||||
<div class="layout-body">
|
||||
<form-base-setting ref="baseSetting" v-show="activeSelect === 'baseSetting'"/>
|
||||
<form-design ref="formSetting" v-show="activeSelect === 'formSetting'"/>
|
||||
<process-design ref="processDesign" v-show="activeSelect === 'processDesign'"/>
|
||||
<form-pro-setting ref="proSetting" v-show="activeSelect === 'proSetting'"/>
|
||||
</div>
|
||||
<w-dialog :showFooter="false" v-model="validVisible" title="设置项检查">
|
||||
<el-steps align-center :active="validStep" finish-status="success">
|
||||
<el-step v-for="(step, i) in validOptions" :title="step.title" :key="i"
|
||||
:icon="step.icon" :status="step.status" :description="step.description"/>
|
||||
</el-steps>
|
||||
<el-result :icon="validIcon" :title="errTitle" :subTitle="validResult.desc">
|
||||
<i slot="icon" style="font-size: 30px" v-if="!validResult.finished" class="el-icon-loading"></i>
|
||||
<div slot="subTitle" class="err-info" v-if="validResult.errs.length > 0">
|
||||
<ellipsis hover-tip v-for="(err, i) in validResult.errs" :key="i + '_err'" :content="err">
|
||||
<i slot="pre" class="el-icon-warning-outline"></i>
|
||||
</ellipsis>
|
||||
</div>
|
||||
<template slot="extra">
|
||||
<el-button type="primary" v-if="validResult.finished" size="medium" @click="doAfter">
|
||||
{{ validResult.action }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-result>
|
||||
</w-dialog>
|
||||
</el-container>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LayoutHeader from './LayoutHeader'
|
||||
import {getFormDetail, createForm, updateFormDetail} from '@/api/design'
|
||||
import FormBaseSetting from '@/views/admin/layout/FormBaseSetting'
|
||||
import FormDesign from '@/views/admin/layout/FormDesign'
|
||||
import ProcessDesign from '@/views/admin/layout/ProcessDesign'
|
||||
import FormProSetting from '@/views/admin/layout/FormProSetting'
|
||||
import axios from "axios";
|
||||
|
||||
export default {
|
||||
name: "FormProcessDesign",
|
||||
components: {LayoutHeader, FormBaseSetting, FormDesign, ProcessDesign, FormProSetting},
|
||||
data() {
|
||||
return {
|
||||
isNew: true,
|
||||
validStep: 0,
|
||||
timer: null,
|
||||
//todo 修改进入的位置
|
||||
// activeSelect: 'baseSetting',
|
||||
activeSelect: 'processDesign',
|
||||
validVisible: false,
|
||||
validResult: {},
|
||||
validOptions: [
|
||||
{title: '基础信息', description: '', icon: '', status: ''},
|
||||
{title: '审批表单', description: '', icon: '', status: ''},
|
||||
{title: '审批流程', description: '', icon: '', status: ''},
|
||||
{title: '扩展设置', description: '', icon: '', status: ''}
|
||||
],
|
||||
validComponents: ['baseSetting', 'formSetting', 'processDesign', 'proSetting'],
|
||||
array:[],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
setup() {
|
||||
return this.$store.state.design
|
||||
},
|
||||
errTitle(){
|
||||
if (this.validResult.finished && !this.validResult.success){
|
||||
return this.validResult.title + ` (${this.validResult.errs.length}项错误) 😥`
|
||||
}
|
||||
return this.validResult.title
|
||||
},
|
||||
validIcon() {
|
||||
if (!this.validResult.finished) {
|
||||
return 'el-icon-loading'
|
||||
} else if (this.validResult.success) {
|
||||
return 'success'
|
||||
} else {
|
||||
return 'warning'
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.showValiding()
|
||||
let formId = this.$route.query.code
|
||||
//判断传参,决定是新建还是加载原始数据
|
||||
this.loadInitFrom()
|
||||
if (this.$isNotEmpty(formId)) {
|
||||
this.isNew = false
|
||||
this.loadFormInfo(formId)
|
||||
}
|
||||
let group = this.$route.query.group
|
||||
this.setup.groupId = this.$isNotEmpty(group) ? parseInt(group) : null
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.stopTimer()
|
||||
},
|
||||
methods: {
|
||||
loadFormInfo(formId) {
|
||||
getFormDetail(formId).then(rsp => {
|
||||
console.log(rsp.data)
|
||||
let form = rsp.data;
|
||||
form.logo = JSON.parse(form.logo)
|
||||
form.settings = JSON.parse(form.settings)
|
||||
form.formItems = JSON.parse(form.formItems)
|
||||
form.process = JSON.parse(form.process)
|
||||
this.$store.commit('loadForm', form)
|
||||
}).catch(err => {
|
||||
this.$message.error(err)
|
||||
})
|
||||
},
|
||||
loadInitFrom() {
|
||||
this.$store.commit('loadForm', {
|
||||
formId: null,
|
||||
formName: "未命名表单",
|
||||
logo: {
|
||||
icon: "el-icon-eleme",
|
||||
background: "#1e90ff"
|
||||
},
|
||||
settings: {
|
||||
commiter: [],
|
||||
admin: [],
|
||||
sign: false,
|
||||
notify: {
|
||||
types: ["APP"],
|
||||
title: "消息通知标题"
|
||||
}
|
||||
},
|
||||
groupId: undefined,
|
||||
formItems: [],
|
||||
process: {
|
||||
id: "root",
|
||||
parentId: "admin",
|
||||
type: "ROOT",
|
||||
name: "发起人",
|
||||
desc: "任何人",
|
||||
props: {
|
||||
assignedUser: [],
|
||||
formPerms: []
|
||||
},
|
||||
children: {}
|
||||
},
|
||||
// [
|
||||
// {
|
||||
// id: "root",
|
||||
// parentId: "admin",
|
||||
// type: "ROOT",
|
||||
// name: "发起人",
|
||||
// desc: "任何人",
|
||||
// props: {
|
||||
// assignedUser: [],
|
||||
// formPerms: []
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// id: "end",
|
||||
// parentId: "root",
|
||||
// type: "END",
|
||||
// name: "发起人",
|
||||
// desc: "任何人",
|
||||
// props: {
|
||||
// assignedUser: [],
|
||||
// formPerms: []
|
||||
// },
|
||||
// }
|
||||
// ]
|
||||
|
||||
remark: "备注说明"
|
||||
})
|
||||
},
|
||||
validateDesign() {
|
||||
this.validVisible = true
|
||||
this.validStep = 0
|
||||
this.showValiding()
|
||||
this.stopTimer()
|
||||
this.timer = setInterval(() => {
|
||||
this.validResult.errs = this.$refs[this.validComponents[this.validStep]].validate()
|
||||
if (Array.isArray(this.validResult.errs) && this.validResult.errs.length === 0) {
|
||||
this.validStep++;
|
||||
if (this.validStep >= this.validOptions.length) {
|
||||
this.stopTimer()
|
||||
this.showValidFinish(true)
|
||||
}
|
||||
} else {
|
||||
this.stopTimer()
|
||||
this.validOptions[this.validStep].status = 'error'
|
||||
this.showValidFinish(false, this.getDefaultValidErr())
|
||||
}
|
||||
}, 300)
|
||||
},
|
||||
getDefaultValidErr() {
|
||||
switch (this.validStep) {
|
||||
case 0:
|
||||
return '请检查基础设置项';
|
||||
case 1:
|
||||
return '请检查审批表单相关设置'
|
||||
case 2:
|
||||
return '请检查审批流程,查看对应标注节点错误信息'
|
||||
case 3:
|
||||
return '请检查扩展设置'
|
||||
default:
|
||||
return '未知错误'
|
||||
}
|
||||
},
|
||||
showValidFinish(success, err) {
|
||||
this.validResult.success = success
|
||||
this.validResult.finished = true
|
||||
this.validResult.title = success ? '校验完成 😀' : '校验失败 '
|
||||
this.validResult.desc = success ? '设置项校验成功,是否提交?' : err
|
||||
this.validResult.action = success ? '提 交' : '去修改'
|
||||
},
|
||||
showValiding() {
|
||||
this.validResult = {
|
||||
errs: [],
|
||||
finished: false,
|
||||
success: false,
|
||||
title: '检查中...',
|
||||
action: '处理',
|
||||
desc: '正在检查设置项'
|
||||
}
|
||||
this.validStep = 0
|
||||
this.validOptions.forEach(op => {
|
||||
op.status = ''
|
||||
op.icon = ''
|
||||
op.description = ''
|
||||
})
|
||||
},
|
||||
doAfter() {
|
||||
if (this.validResult.success) {
|
||||
// let process = this.setup.process
|
||||
// console.log(process)
|
||||
// this.tarry(process)
|
||||
//
|
||||
//
|
||||
// console.log(this.array)
|
||||
// this.setup.process = this.array
|
||||
|
||||
this.doPublish()
|
||||
} else {
|
||||
this.activeSelect = this.validComponents[this.validStep]
|
||||
this.validVisible = false
|
||||
}
|
||||
},
|
||||
|
||||
tarry(node){
|
||||
if (node&&node.id){
|
||||
let newNode = {...node}
|
||||
newNode.children=null
|
||||
this.array.push(newNode)
|
||||
this.tarry(node.children)
|
||||
}
|
||||
|
||||
|
||||
|
||||
},
|
||||
stopTimer() {
|
||||
if (this.timer) {
|
||||
clearInterval(this.timer)
|
||||
}
|
||||
},
|
||||
preview() {
|
||||
this.validateDesign()
|
||||
},
|
||||
//发布流程
|
||||
publishProcess() {
|
||||
console.log("发布")
|
||||
this.testPublish()
|
||||
// this.validateDesign()
|
||||
},
|
||||
getToken(){
|
||||
axios.post(
|
||||
"http://localhost:8000/auth/login",
|
||||
{
|
||||
code: "string",
|
||||
password: "926425",
|
||||
username: "admin",
|
||||
uuid: "string"
|
||||
}
|
||||
).then(res =>{
|
||||
console.log(res)
|
||||
sessionStorage.setItem("token",res.data.data)
|
||||
this.testPublish()
|
||||
})
|
||||
},
|
||||
testPublish(){
|
||||
this.toAjaxAdd();
|
||||
let token = sessionStorage.getItem("token");
|
||||
if (!token){
|
||||
this.getToken();
|
||||
}
|
||||
let templates = {
|
||||
formId: this.setup.formId,
|
||||
formName: this.setup.formName,
|
||||
logo: this.setup.logo,
|
||||
settings: this.setup.settings,
|
||||
groupId: this.setup.groupId,
|
||||
formItems: this.setup.formItems,
|
||||
process: this.setup.process,
|
||||
remark: this.setup.remark
|
||||
}
|
||||
console.log(JSON.stringify(templates))
|
||||
console.log("获取到token")
|
||||
// axios.post(
|
||||
// "",
|
||||
// templates,
|
||||
// ).then(res =>{
|
||||
//
|
||||
// })
|
||||
|
||||
},
|
||||
|
||||
toAjaxAdd(){
|
||||
console.log(this.setup,"数据的哈客户大客户")
|
||||
let template = {
|
||||
formId: this.setup.formId,
|
||||
formName: this.setup.formName,
|
||||
logo: JSON.stringify(this.setup.logo),
|
||||
settings: JSON.stringify(this.setup.settings),
|
||||
groupId: this.setup.groupId,
|
||||
formItems: JSON.stringify(this.setup.formItems),
|
||||
process: JSON.stringify(this.setup.process),
|
||||
remark: this.setup.remark
|
||||
}
|
||||
createForm(template).then(rsp => {
|
||||
this.$message.success("创建表单成功")
|
||||
this.$router.push("/formsPanel")
|
||||
}).catch(err => {
|
||||
this.$message.error(err)
|
||||
})
|
||||
|
||||
},
|
||||
toAjaxEdit(){
|
||||
console.log(this.setup)
|
||||
let template = {
|
||||
formId: this.setup.formId,
|
||||
formName: this.setup.formName,
|
||||
logo: JSON.stringify(this.setup.logo),
|
||||
settings: JSON.stringify(this.setup.settings),
|
||||
groupId: this.setup.groupId,
|
||||
formItems: JSON.stringify(this.setup.formItems),
|
||||
process: JSON.stringify(this.setup.process),
|
||||
remark: this.setup.remark
|
||||
}
|
||||
console.log(JSON.stringify(template))
|
||||
updateFormDetail(template).then(rsp => {
|
||||
this.$message.success("更新表单成功")
|
||||
this.$router.push("/formsPanel")
|
||||
}).catch(err => {
|
||||
this.$message.error(err)
|
||||
})
|
||||
},
|
||||
// todo 提交数据
|
||||
doPublish() {
|
||||
this.$confirm('如果您只想预览请选择预览,确认发布后流程立即生效,是否继续?', '提示', {
|
||||
confirmButtonText: '发布',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
console.log(this.setup)
|
||||
let template = {
|
||||
formId: this.setup.formId,
|
||||
formName: this.setup.formName,
|
||||
logo: JSON.stringify(this.setup.logo),
|
||||
settings: JSON.stringify(this.setup.settings),
|
||||
groupId: this.setup.groupId,
|
||||
formItems: JSON.stringify(this.setup.formItems),
|
||||
process: JSON.stringify(this.setup.process),
|
||||
remark: this.setup.remark
|
||||
}
|
||||
if (this.isNew || !this.$isNotEmpty(this.setup.formId)) {
|
||||
createForm(template).then(rsp => {
|
||||
this.$message.success("创建表单成功")
|
||||
this.$router.push("/formsPanel")
|
||||
}).catch(err => {
|
||||
this.$message.error(err)
|
||||
})
|
||||
} else {
|
||||
console.log(JSON.stringify(template))
|
||||
updateFormDetail(template).then(rsp => {
|
||||
this.$message.success("更新表单成功")
|
||||
this.$router.push("/formsPanel")
|
||||
}).catch(err => {
|
||||
this.$message.error(err)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
.layout-body {
|
||||
min-width: 980px;
|
||||
}
|
||||
|
||||
/deep/ .el-step {
|
||||
.is-success {
|
||||
color: #2a99ff;
|
||||
border-color: #2a99ff;
|
||||
}
|
||||
}
|
||||
|
||||
.err-info{
|
||||
max-height: 180px;
|
||||
overflow-y: auto;
|
||||
& > div{
|
||||
padding: 5px;
|
||||
margin: 2px 0;
|
||||
width: 220px;
|
||||
text-align: left;
|
||||
border-radius: 3px;
|
||||
background: rgb(242 242 242);
|
||||
}
|
||||
i{
|
||||
margin: 0 5px;
|
||||
}
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 2px;
|
||||
height: 2px;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
border-radius: 16px;
|
||||
background-color: #e8e8e8;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
@ -72,6 +72,11 @@ export default {
|
|||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
::-webkit-scrollbar {
|
||||
height: 10px !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.design {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,696 @@
|
|||
<script>
|
||||
//导入所有节点组件
|
||||
import Approval from '@/views/common/process/nodes/ApprovalNode.vue'
|
||||
import Cc from '@/views/common/process/nodes/CcNode.vue'
|
||||
import Concurrent from '@/views/common/process/nodes/ConcurrentNode.vue'
|
||||
import Condition from '@/views/common/process/nodes/ConditionNode.vue'
|
||||
import Trigger from '@/views/common/process/nodes/TriggerNode.vue'
|
||||
import Delay from '@/views/common/process/nodes/DelayNode.vue'
|
||||
import Empty from '@/views/common/process/nodes/EmptyNode.vue'
|
||||
import Merge from '@/views/common/process/nodes/MergeNode.vue'
|
||||
import Root from '@/views/common/process/nodes/RootNode.vue'
|
||||
import End from '@/views/common/process/nodes/ProcessEndNode.vue'
|
||||
import Node from '@/views/common/process/nodes/Node.vue'
|
||||
|
||||
import DefaultProps from "./DefaultNodeProps"
|
||||
|
||||
export default {
|
||||
name: "ProcessTree",
|
||||
components: {Node, Root, Approval, Cc, Trigger, Concurrent, Condition, Delay, Empty,Merge,End},
|
||||
data() {
|
||||
return {
|
||||
valid: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
nodeMap() {
|
||||
return this.$store.state.nodeMap;
|
||||
},
|
||||
parentMap() {
|
||||
return this.$store.state.parentMap;
|
||||
},
|
||||
dom() {
|
||||
return this.$store.state.design.process;
|
||||
}
|
||||
},
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
render(h, ctx) {
|
||||
this.nodeMap.clear()
|
||||
this.parentMap.clear()
|
||||
this.initMapping(this.dom)
|
||||
let processTrees = this.getDomTree(h, "admin")
|
||||
let endNode = {
|
||||
id : this.getRandomId(),
|
||||
type: "End"
|
||||
}
|
||||
this.decodeAppendEndDom(h,endNode,processTrees)
|
||||
//插入末端节点
|
||||
// processTrees.push(h('div', {style: {'text-align': 'center'}}, [
|
||||
// h('div', {class: {'process-end': true}, domProps: {innerHTML: '流程结束'}})
|
||||
// ]))
|
||||
return h('div', {class: {'process-end': true}, ref: 'end'}, processTrees)
|
||||
},
|
||||
methods: {
|
||||
// 获取demo的树形结构
|
||||
getDomTree(h, id) {
|
||||
let node = this.parentMap.get(id)
|
||||
if (!(node && node.id)) {
|
||||
return []
|
||||
}
|
||||
if (this.isPrimaryNode(node)) {
|
||||
//普通业务节点
|
||||
let childDoms = this.getDomTree(h, node.id)
|
||||
this.decodeAppendDom(h, node, childDoms)
|
||||
return [h('div', {'class': {'primary-node': true}}, childDoms)];
|
||||
} else if (this.isBranchNode(node)) {
|
||||
let index = 0;
|
||||
//遍历分支节点,包含并行及条件节点
|
||||
let branchItems = node.branchs.map(branchNode => {
|
||||
//处理每个分支内子节点
|
||||
this.toMapping(branchNode)
|
||||
let childDoms = this.getDomTree(h, branchNode.id)
|
||||
this.decodeAppendDom(h, branchNode, childDoms, {level: index + 1, size: node.branchs.length})
|
||||
//插入4条横线,遮挡掉条件节点左右半边线条
|
||||
this.insertCoverLine(h, index, childDoms, node.branchs)
|
||||
//遍历子分支尾部分支
|
||||
index++;
|
||||
return h('div', {'class': {'branch-node-item': true}}, childDoms);
|
||||
})
|
||||
//插入添加分支/条件的按钮
|
||||
branchItems.unshift(h('div', {'class': {'add-branch-btn': true}}, [
|
||||
h('el-button', {
|
||||
'class': {'add-branch-btn-el': true},
|
||||
props: {size: 'small', round: true},
|
||||
on: {click: () => this.addBranchNode(node)},
|
||||
domProps: {innerHTML: `添加${this.isConditionNodes(node) ? '条件' : '分支'}`},
|
||||
}, [])
|
||||
]));
|
||||
let bchDom = [h('div', {'class': {'branch-node': true}}, branchItems)]
|
||||
//继续遍历分支后的节点
|
||||
let afterChildDoms = this.getDomTree(h, node.id)
|
||||
return [h('div', {}, [bchDom, afterChildDoms])]
|
||||
} else if (this.isMergeNode(node)){
|
||||
//空节点,存在于分支尾部
|
||||
let childDoms = this.getDomTree(h, node.id)
|
||||
this.decodeAppendDom(h, node, childDoms)
|
||||
return [h('div', {'class': {'empty-node': true}}, childDoms)];
|
||||
} else if (this.isEmptyNode(node)) {
|
||||
//空节点,存在于分支尾部
|
||||
let childDoms = this.getDomTree(h, node.id)
|
||||
this.decodeAppendDom(h, node, childDoms)
|
||||
return [h('div', {'class': {'empty-node': true}}, childDoms)];
|
||||
}
|
||||
return []
|
||||
},
|
||||
//解码渲染的时候插入dom到同级
|
||||
decodeAppendDom(h, node, dom, props = {}) {
|
||||
props.config = node
|
||||
dom.unshift(h(node.type.toLowerCase(), {
|
||||
props: props,
|
||||
ref: node.id,
|
||||
key: node.id,
|
||||
//定义事件,插入节点,删除节点,选中节点,复制/移动
|
||||
on: {
|
||||
insertNode: type => this.insertNode(type, node),
|
||||
delNode: () => this.delNode(node),
|
||||
selected: () => this.selectNode(node),
|
||||
copy: () => this.copyBranch(node),
|
||||
leftMove: () => this.branchMove(node, -1),
|
||||
rightMove: () => this.branchMove(node, 1)
|
||||
}
|
||||
}, []))
|
||||
},
|
||||
decodeAppendEndDom(h, node, dom, props = {}) {
|
||||
props.config = node
|
||||
dom.unshift(h(node.type.toLowerCase(), {
|
||||
props: props,
|
||||
ref: node.id,
|
||||
key: node.id,
|
||||
//定义事件,插入节点,删除节点,选中节点,复制/移动
|
||||
// on: {
|
||||
// insertNode: type => this.insertNode(type, node),
|
||||
// delNode: () => this.delNode(node),
|
||||
// selected: () => this.selectNode(node),
|
||||
// copy: () => this.copyBranch(node),
|
||||
// leftMove: () => this.branchMove(node, -1),
|
||||
// rightMove: () => this.branchMove(node, 1)
|
||||
// }
|
||||
}, []))
|
||||
},
|
||||
|
||||
// 初始化map集合,以便数据整理
|
||||
initMapping(node) {
|
||||
console.log(node)
|
||||
let type = typeof node;
|
||||
// if (node typeof list){
|
||||
//
|
||||
// }
|
||||
console.log(type)
|
||||
|
||||
// if (type == 'object'){
|
||||
// this.nodeMap.set(node.id, node)
|
||||
// this.parentMap.set(node.parentId, node)
|
||||
//
|
||||
// console.log(node,"'object'")
|
||||
// }else {
|
||||
//
|
||||
// console.log(node,"!object'")
|
||||
// console.log(node)
|
||||
console.log(node,"nodeItem")
|
||||
node.forEach(nodeItem => {
|
||||
this.nodeMap.set(nodeItem.id, nodeItem)
|
||||
this.parentMap.set(nodeItem.parentId, nodeItem)
|
||||
})
|
||||
// }
|
||||
},
|
||||
//id映射到map,用来向上遍历
|
||||
toMapping(node) {
|
||||
if (node && node.id) {
|
||||
let newNode = {
|
||||
...node
|
||||
}
|
||||
newNode.children = []
|
||||
this.nodeMap.set(newNode.id, newNode)
|
||||
}
|
||||
},
|
||||
// 新增线条
|
||||
insertCoverLine(h, index, doms, branchs) {
|
||||
if (index === 0) {
|
||||
//最左侧分支
|
||||
doms.unshift(h('div', {'class': {'line-top-left': true}}, []))
|
||||
doms.unshift(h('div', {'class': {'line-bot-left': true}}, []))
|
||||
}
|
||||
if (index === branchs.length - 1) {
|
||||
//最右侧分支
|
||||
doms.unshift(h('div', {'class': {'line-top-right': true}}, []))
|
||||
doms.unshift(h('div', {'class': {'line-bot-right': true}}, []))
|
||||
}
|
||||
},
|
||||
copyBranch(node) {
|
||||
let parentNode = this.nodeMap.get(node.parentId)
|
||||
let branchNode = this.$deepCopy(node)
|
||||
branchNode.name = branchNode.name + '-copy'
|
||||
this.forEachNode(parentNode, branchNode, (parent, node) => {
|
||||
let id = this.getRandomId()
|
||||
console.log(node, '新id =>' + id, '老nodeId:' + node.id)
|
||||
node.id = id
|
||||
node.parentId = parent.id
|
||||
})
|
||||
parentNode.branchs.splice(parentNode.branchs.indexOf(node), 0, branchNode)
|
||||
this.$forceUpdate()
|
||||
},
|
||||
//移动分支节点
|
||||
branchMove(node, offset) {
|
||||
let parentNode = this.nodeMap.get(node.parentId)
|
||||
let index = parentNode.branchs.indexOf(node)
|
||||
let branch = parentNode.branchs[index + offset]
|
||||
parentNode.branchs[index + offset] = parentNode.branchs[index]
|
||||
parentNode.branchs[index] = branch
|
||||
this.$forceUpdate()
|
||||
},
|
||||
//判断是否为主要业务节点
|
||||
isPrimaryNode(node) {
|
||||
return node &&
|
||||
(node.type === 'ROOT' || node.type === 'APPROVAL'
|
||||
|| node.type === 'CC' || node.type === 'DELAY'
|
||||
|| node.type === 'TRIGGER');
|
||||
},
|
||||
//是否为分支节点
|
||||
isBranchNode(node) {
|
||||
return node && (node.type === 'CONDITIONS' || node.type === 'CONCURRENTS');
|
||||
},
|
||||
//是否为空节点
|
||||
isEmptyNode(node) {
|
||||
return node && (node.type === 'EMPTY')
|
||||
},
|
||||
//是否为空节点
|
||||
isMergeNode(node) {
|
||||
return node && (node.type === 'MERGE')
|
||||
},
|
||||
//是分支节点
|
||||
isConditionNodes(node) {
|
||||
return node.type === 'CONDITIONS';
|
||||
},
|
||||
isConditionNode(node) {
|
||||
return node.type === 'CONDITION';
|
||||
},
|
||||
//是分支节点
|
||||
isBranchSubNode(node) {
|
||||
return node && (node.type === 'CONDITION' || node.type === 'CONCURRENT');
|
||||
},
|
||||
//时候并行节点
|
||||
isConcurrentNodes(node) {
|
||||
return node.type === 'CONCURRENTS'
|
||||
},
|
||||
//时候并行节点
|
||||
isConcurrentNode(node) {
|
||||
return node.type === 'CONCURRENT'
|
||||
},
|
||||
//新增一个节点id
|
||||
getRandomId() {
|
||||
let d = new Date().getTime()
|
||||
// x 是 0-9 或 a-f 范围内的一个32位十六进制数
|
||||
let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
||||
let r = (d + Math.random() * 16) % 16 | 0
|
||||
d = Math.floor(d / 16)
|
||||
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16)
|
||||
})
|
||||
return uuid
|
||||
// return `node_${new Date().getTime().toString().substring(5)}${Math.round(Math.random() * 9000 + 1000)}`
|
||||
},
|
||||
//选中一个节点
|
||||
selectNode(node) {
|
||||
this.$store.commit('selectedNode', node)
|
||||
console.log(node,"node")
|
||||
if (!this.isConcurrentNode(node)) {
|
||||
this.$emit('selectedNode', node)
|
||||
}
|
||||
},
|
||||
|
||||
//处理节点插入逻辑
|
||||
insertNode(type, parentNode) {
|
||||
console.log("type", type)
|
||||
this.$refs['_root'].click()
|
||||
//插入新节点
|
||||
let id = this.getRandomId();
|
||||
this.updateParentId(id, parentNode.id)
|
||||
let children = {
|
||||
id: id,
|
||||
parentId: parentNode.id,
|
||||
type: type,
|
||||
}
|
||||
switch (type) {
|
||||
case 'APPROVAL':
|
||||
this.insertApprovalNode(children);
|
||||
break;
|
||||
case 'CC':
|
||||
this.insertCcNode(children);
|
||||
break;
|
||||
case 'DELAY':
|
||||
this.insertDelayNode(children);
|
||||
break;
|
||||
case 'TRIGGER':
|
||||
this.insertTriggerNode(children);
|
||||
break;
|
||||
case 'CONDITIONS':
|
||||
this.insertConditionsNode(children);
|
||||
break;
|
||||
case 'CONCURRENTS':
|
||||
this.insertConcurrentsNode(children);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
this.$forceUpdate()
|
||||
},
|
||||
/**
|
||||
* 更新父id
|
||||
* @param newId
|
||||
* @param oldId
|
||||
*/
|
||||
updateParentId(newId, oldId) {
|
||||
this.dom.map(node => {
|
||||
if (node.parentId === oldId) {
|
||||
node.parentId = newId
|
||||
}
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 审批人
|
||||
* @param parentNode
|
||||
*/
|
||||
insertApprovalNode(parentNode) {
|
||||
let node = {
|
||||
...parentNode,
|
||||
name: "审批人",
|
||||
props: this.$deepCopy(DefaultProps.APPROVAL_PROPS)
|
||||
}
|
||||
this.dom.push(node)
|
||||
},
|
||||
/**
|
||||
* 抄送人
|
||||
* @param node
|
||||
*/
|
||||
insertCcNode(node) {
|
||||
let newNode = {
|
||||
...node,
|
||||
name: "抄送人",
|
||||
props: this.$deepCopy(DefaultProps.CC_PROPS)
|
||||
}
|
||||
this.dom.push(newNode)
|
||||
},
|
||||
/**
|
||||
* 延时处理
|
||||
* @param node
|
||||
*/
|
||||
insertDelayNode(node) {
|
||||
let newNode = {
|
||||
...node,
|
||||
name: "延时处理",
|
||||
props: this.$deepCopy(DefaultProps.DELAY_PROPS)
|
||||
}
|
||||
this.dom.push(newNode)
|
||||
},
|
||||
/**
|
||||
* 触发器
|
||||
* @param node
|
||||
*/
|
||||
insertTriggerNode(node) {
|
||||
let newNode = {
|
||||
...node,
|
||||
name: "触发器",
|
||||
props: this.$deepCopy(DefaultProps.TRIGGER_PROPS)
|
||||
}
|
||||
this.dom.push(newNode)
|
||||
},
|
||||
/**
|
||||
* 新增条件分支F
|
||||
* @param node
|
||||
*/
|
||||
insertConditionsNode(node) {
|
||||
let newNode = {
|
||||
...node,
|
||||
name: "条件分支",
|
||||
branchs: [
|
||||
{
|
||||
id: this.getRandomId(),
|
||||
parentId: node.id,
|
||||
type: "CONDITION",
|
||||
props: this.$deepCopy(DefaultProps.CONDITION_PROPS),
|
||||
name: "条件1",
|
||||
children: {}
|
||||
}, {
|
||||
id: this.getRandomId(),
|
||||
parentId: node.id,
|
||||
type: "CONDITION",
|
||||
props: this.$deepCopy(DefaultProps.CONDITION_PROPS),
|
||||
name: "条件2",
|
||||
children: {}
|
||||
}
|
||||
]
|
||||
}
|
||||
this.dom.push(newNode)
|
||||
let emptyNode = {
|
||||
id: this.getRandomId(),
|
||||
parentId: node.id,
|
||||
type: "EMPTY"
|
||||
}
|
||||
this.updateParentId(emptyNode.id, newNode.id)
|
||||
this.dom.push(emptyNode)
|
||||
},
|
||||
/**
|
||||
* 新增同步运行节点
|
||||
* @param node
|
||||
*/
|
||||
insertConcurrentsNode(node) {
|
||||
let newNode = {
|
||||
...node,
|
||||
name: "并行分支",
|
||||
branchs: [
|
||||
{
|
||||
id: this.getRandomId(),
|
||||
parentId: node.id,
|
||||
type: "CONCURRENT",
|
||||
props: this.$deepCopy(DefaultProps.CONDITION_PROPS),
|
||||
name: "分支1",
|
||||
children: {}
|
||||
}, {
|
||||
id: this.getRandomId(),
|
||||
parentId: node.id,
|
||||
type: "CONCURRENT",
|
||||
props: this.$deepCopy(DefaultProps.CONDITION_PROPS),
|
||||
name: "分支2",
|
||||
children: {}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
this.dom.push(newNode)
|
||||
let emptyNode = {
|
||||
id: this.getRandomId(),
|
||||
parentId: node.id,
|
||||
type: "MERGE"
|
||||
}
|
||||
this.updateParentId(emptyNode.id, newNode.id)
|
||||
this.dom.push(emptyNode)
|
||||
},
|
||||
|
||||
addBranchNode(node) {
|
||||
if (node.branchs.length < 8) {
|
||||
node.branchs.push({
|
||||
id: this.getRandomId(),
|
||||
parentId: node.id,
|
||||
name: (this.isConditionNodes(node) ? '条件' : '分支') + (node.branchs.length + 1),
|
||||
props: this.isConditionNodes(node) ? this.$deepCopy(DefaultProps.CONDITION_PROPS) : {},
|
||||
type: this.isConditionNodes(node) ? "CONDITION" : "CONCURRENT",
|
||||
children: {}
|
||||
})
|
||||
} else {
|
||||
this.$message.warning("最多只能添加 8 项😥")
|
||||
}
|
||||
},
|
||||
|
||||
//删除当前节点
|
||||
delNode(node) {
|
||||
//获取该节点的父节点
|
||||
let parentNode = this.nodeMap.get(node.parentId)
|
||||
if (parentNode) {
|
||||
if (this.isBranchNode(parentNode)) {
|
||||
this.delBranchNode(parentNode, node)
|
||||
} else {
|
||||
this.delNodeInDomChange(node.id, parentNode.id)
|
||||
}
|
||||
} else {
|
||||
this.$message.warning("出现错误,找不到上级节点😥")
|
||||
}
|
||||
},
|
||||
//删除分支
|
||||
delBranchNode(parentNode, node) {
|
||||
let sunNode = this.parentMap.get(node.id)
|
||||
//判断当前节点下有没有字节点,有则需要提示
|
||||
if (sunNode) {
|
||||
this.$confirm('当前分支下有子节点,是否继续?', '提示', {
|
||||
confirmButtonText: '确 定',
|
||||
cancelButtonText: '取 消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
//确认后进行子节点的操作
|
||||
this.delBranchSunNode(sunNode.id)
|
||||
this.doDelBranchNode(parentNode, node)
|
||||
})
|
||||
return
|
||||
} else {
|
||||
// 没有直接开始删除
|
||||
this.doDelBranchNode(parentNode, node)
|
||||
}
|
||||
},
|
||||
//删除分支的子节点
|
||||
delBranchSunNode(id) {
|
||||
let node = this.parentMap.get(id)
|
||||
this.delNodeInDomChange(id)
|
||||
if (node) {
|
||||
this.delBranchSunNode(node.id)
|
||||
}
|
||||
},
|
||||
//删除分支节点
|
||||
doDelBranchNode(parentNode, node) {
|
||||
//判断当前分时是否为2
|
||||
if (parentNode.branchs.length === 2) {
|
||||
let nodeList = [...parentNode.branchs]
|
||||
nodeList.splice(nodeList.indexOf(node), 1)
|
||||
//查看另外一个分支上是否有节点
|
||||
let sunNode = this.parentMap.get(nodeList[0].id)
|
||||
//有则需要放到主分支上
|
||||
if (sunNode) {
|
||||
//更改分支上第一个节点的父id
|
||||
this.updateParentId(parentNode.parentId, sunNode.parentId)
|
||||
//找到最后一个节点
|
||||
let lastNode = this.getLastBranchNode(sunNode.id)
|
||||
let emptyNode = this.parentMap.get(parentNode.id)
|
||||
//更新空节点下的第一个节点的id为当前分支最后一个节点
|
||||
this.updateParentId(lastNode.id, emptyNode.id)
|
||||
//删除分支的主节点
|
||||
this.delNodeInDom(parentNode)
|
||||
//删除分支的空节点
|
||||
this.delNodeInDom(emptyNode)
|
||||
} else {
|
||||
//没有则直接删除
|
||||
this.delEntireBranch(parentNode)
|
||||
}
|
||||
} else {
|
||||
parentNode.branchs.splice(parentNode.branchs.indexOf(node), 1)
|
||||
}
|
||||
},
|
||||
//获取最后一个节点
|
||||
getLastBranchNode(id) {
|
||||
let node = this.parentMap.get(id)
|
||||
if (node) {
|
||||
return this.getLastBranchNode(node.id)
|
||||
} else {
|
||||
return this.nodeMap.get(id)
|
||||
}
|
||||
},
|
||||
delEntireBranch(node) {
|
||||
//删除分支节点和空节点
|
||||
let emptyNode = this.parentMap.get(node.id)
|
||||
this.delNodeInDomChange(node.id, node.parentId)
|
||||
this.delNodeInDomChange(emptyNode.id, emptyNode.parentId)
|
||||
},
|
||||
|
||||
/**
|
||||
* 从dom中删除
|
||||
* @param delId
|
||||
* @param parentId
|
||||
*/
|
||||
delNodeInDomChange(delId, parentId) {
|
||||
this.updateParentId(parentId, delId)
|
||||
let delNode = this.nodeMap.get(delId)
|
||||
this.dom.splice(this.dom.indexOf(delNode), 1)
|
||||
},
|
||||
delNodeInDom(delNode) {
|
||||
this.dom.splice(this.dom.indexOf(delNode), 1)
|
||||
},
|
||||
validateProcess() {
|
||||
this.valid = true
|
||||
let err = []
|
||||
this.validate(err, this.dom)
|
||||
return err
|
||||
},
|
||||
validateNode(err, node) {
|
||||
if (this.$refs[node.id].validate) {
|
||||
this.valid = this.$refs[node.id].validate(err)
|
||||
}
|
||||
},
|
||||
//更新指定节点的dom
|
||||
nodeDomUpdate(node) {
|
||||
this.$refs[node.id].$forceUpdate()
|
||||
},
|
||||
//给定一个起始节点,遍历内部所有节点
|
||||
forEachNode(parent, node, callback) {
|
||||
if (this.isBranchNode(node)) {
|
||||
callback(parent, node)
|
||||
this.forEachNode(node, node.children, callback)
|
||||
node.branchs.map(branchNode => {
|
||||
callback(node, branchNode)
|
||||
this.forEachNode(branchNode, branchNode.children, callback)
|
||||
})
|
||||
} else if (this.isPrimaryNode(node) || this.isEmptyNode(node) || this.isBranchSubNode(node)) {
|
||||
callback(parent, node)
|
||||
this.forEachNode(node, node.children, callback)
|
||||
}
|
||||
},
|
||||
//校验所有节点设置
|
||||
validate(err, nodeList) {
|
||||
nodeList.map(node => {
|
||||
if (this.isPrimaryNode(node)) {
|
||||
//校验条件节点
|
||||
this.validateNode(err, node)
|
||||
} else if (this.isBranchNode(node)) {
|
||||
node.branchs.map(branchNode => {
|
||||
//校验条件节点
|
||||
this.validateNode(err, branchNode)
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
watch: {}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
._root {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.process-end {
|
||||
width: 60px;
|
||||
margin: 0 auto;
|
||||
margin-bottom: 20px;
|
||||
border-radius: 15px;
|
||||
padding: 5px 10px;
|
||||
font-size: small;
|
||||
color: #747474;
|
||||
background-color: #f2f2f2;
|
||||
box-shadow: 0 0 10px 0 #bcbcbc;
|
||||
}
|
||||
|
||||
.primary-node {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.branch-node {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
/*border-top: 2px solid #cccccc;
|
||||
border-bottom: 2px solid #cccccc;*/
|
||||
}
|
||||
|
||||
.branch-node-item {
|
||||
position: relative;
|
||||
display: flex;
|
||||
background: #f5f6f6;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
border-top: 2px solid #cccccc;
|
||||
border-bottom: 2px solid #cccccc;
|
||||
|
||||
&:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: calc(50% - 1px);
|
||||
margin: auto;
|
||||
width: 2px;
|
||||
height: 100%;
|
||||
background-color: #CACACA;
|
||||
}
|
||||
|
||||
.line-top-left, .line-top-right, .line-bot-left, .line-bot-right {
|
||||
position: absolute;
|
||||
width: 50%;
|
||||
height: 4px;
|
||||
background-color: #f5f6f6;
|
||||
}
|
||||
|
||||
.line-top-left {
|
||||
top: -2px;
|
||||
left: -1px;
|
||||
}
|
||||
|
||||
.line-top-right {
|
||||
top: -2px;
|
||||
right: -1px;
|
||||
}
|
||||
|
||||
.line-bot-left {
|
||||
bottom: -2px;
|
||||
left: -1px;
|
||||
}
|
||||
|
||||
.line-bot-right {
|
||||
bottom: -2px;
|
||||
right: -1px;
|
||||
}
|
||||
}
|
||||
|
||||
.add-branch-btn {
|
||||
position: absolute;
|
||||
width: 80px;
|
||||
|
||||
.add-branch-btn-el {
|
||||
z-index: 999;
|
||||
position: absolute;
|
||||
top: -15px;
|
||||
}
|
||||
}
|
||||
|
||||
.empty-node {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -7,14 +7,16 @@ import Condition from '@/views/common/process/nodes/ConditionNode.vue'
|
|||
import Trigger from '@/views/common/process/nodes/TriggerNode.vue'
|
||||
import Delay from '@/views/common/process/nodes/DelayNode.vue'
|
||||
import Empty from '@/views/common/process/nodes/EmptyNode.vue'
|
||||
import Merge from '@/views/common/process/nodes/MergeNode.vue'
|
||||
import Root from '@/views/common/process/nodes/RootNode.vue'
|
||||
import End from '@/views/common/process/nodes/ProcessEndNode.vue'
|
||||
import Node from '@/views/common/process/nodes/Node.vue'
|
||||
|
||||
import DefaultProps from "./DefaultNodeProps"
|
||||
|
||||
export default {
|
||||
name: "ProcessTree",
|
||||
components: {Node, Root, Approval, Cc, Trigger, Concurrent, Condition, Delay, Empty},
|
||||
components: {Node, Root, Approval, Cc, Trigger, Concurrent, Condition, Delay, Empty,Merge,End},
|
||||
data() {
|
||||
return {
|
||||
valid: true
|
||||
|
|
@ -31,19 +33,25 @@ export default {
|
|||
return this.$store.state.design.process;
|
||||
}
|
||||
},
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
render(h, ctx) {
|
||||
console.log("渲染流程树")
|
||||
this.nodeMap.clear()
|
||||
this.parentMap.clear()
|
||||
this.initMapping(this.dom)
|
||||
console.log(this.dom)
|
||||
console.log(this.nodeMap, this.parentMap)
|
||||
let processTrees = this.getDomTree(h, "admin")
|
||||
// let endNode = {
|
||||
// id : this.getRandomId(),
|
||||
// type: "End"
|
||||
// }
|
||||
// this.decodeAppendEndDom(h,endNode,processTrees)
|
||||
//插入末端节点
|
||||
processTrees.push(h('div', {style: {'text-align': 'center'}}, [
|
||||
h('div', {class: {'process-end': true}, domProps: {innerHTML: '流程结束'}})
|
||||
]))
|
||||
return h('div', {class: {'_root': true}, ref: '_root'}, processTrees)
|
||||
// processTrees.push(h('div', {style: {'text-align': 'center'}}, [
|
||||
// h('div', {class: {'process-end': true}, domProps: {innerHTML: '流程结束'}})
|
||||
// ]))
|
||||
// return h('div', {class: {'process-end': true}, ref: 'end'}, processTrees)
|
||||
|
||||
return h('div', {class:{'_root': true}, ref:'_root'}, processTrees)
|
||||
// return h('div', {class: {'end-last': true}, ref: 'end'}, processTrees)
|
||||
},
|
||||
methods: {
|
||||
// 获取demo的树形结构
|
||||
|
|
@ -77,18 +85,27 @@ export default {
|
|||
'class': {'add-branch-btn-el': true},
|
||||
props: {size: 'small', round: true},
|
||||
on: {click: () => this.addBranchNode(node)},
|
||||
domProps: {innerHTML: `添加${this.isConditionNode(node) ? '条件' : '分支'}`},
|
||||
domProps: {innerHTML: `添加${this.isConditionNodes(node) ? '条件' : '分支'}`},
|
||||
}, [])
|
||||
]));
|
||||
let bchDom = [h('div', {'class': {'branch-node': true}}, branchItems)]
|
||||
//继续遍历分支后的节点
|
||||
let afterChildDoms = this.getDomTree(h, node.id)
|
||||
return [h('div', {}, [bchDom, afterChildDoms])]
|
||||
} else if (this.isMergeNode(node)){
|
||||
//空节点,存在于分支尾部
|
||||
let childDoms = this.getDomTree(h, node.id)
|
||||
this.decodeAppendDom(h, node, childDoms)
|
||||
return [h('div', {'class': {'empty-node': true}}, childDoms)];
|
||||
} else if (this.isEmptyNode(node)) {
|
||||
//空节点,存在于分支尾部
|
||||
let childDoms = this.getDomTree(h, node.id)
|
||||
this.decodeAppendDom(h, node, childDoms)
|
||||
return [h('div', {'class': {'empty-node': true}}, childDoms)];
|
||||
}else if (this.isEndNode(node)){
|
||||
let childDoms = this.getDomTree(h, node.id)
|
||||
this.decodeAppendEndDom(h, node, childDoms)
|
||||
return [h('div', {'class': {'process-end': true}, ref: 'end'}, childDoms)];
|
||||
}
|
||||
return []
|
||||
},
|
||||
|
|
@ -110,12 +127,44 @@ export default {
|
|||
}
|
||||
}, []))
|
||||
},
|
||||
decodeAppendEndDom(h, node, dom, props = {}) {
|
||||
props.config = node
|
||||
dom.unshift(h(node.type.toLowerCase(), {
|
||||
props: props,
|
||||
ref: node.id,
|
||||
key: node.id,
|
||||
//定义事件,插入节点,删除节点,选中节点,复制/移动
|
||||
// on: {
|
||||
// insertNode: type => this.insertNode(type, node),
|
||||
// delNode: () => this.delNode(node),
|
||||
// selected: () => this.selectNode(node),
|
||||
// copy: () => this.copyBranch(node),
|
||||
// leftMove: () => this.branchMove(node, -1),
|
||||
// rightMove: () => this.branchMove(node, 1)
|
||||
// }
|
||||
}, []))
|
||||
},
|
||||
|
||||
// 初始化map集合,以便数据整理
|
||||
initMapping(node) {
|
||||
node.forEach(node => {
|
||||
this.nodeMap.set(node.id, node)
|
||||
this.parentMap.set(node.parentId, node)
|
||||
// if (node typeof list){
|
||||
//
|
||||
// }
|
||||
|
||||
// if (type == 'object'){
|
||||
// this.nodeMap.set(node.id, node)
|
||||
// this.parentMap.set(node.parentId, node)
|
||||
//
|
||||
// console.log(node,"'object'")
|
||||
// }else {
|
||||
//
|
||||
// console.log(node,"!object'")
|
||||
// console.log(node)
|
||||
node.forEach(nodeItem => {
|
||||
this.nodeMap.set(nodeItem.id, nodeItem)
|
||||
this.parentMap.set(nodeItem.parentId, nodeItem)
|
||||
})
|
||||
// }
|
||||
},
|
||||
//id映射到map,用来向上遍历
|
||||
toMapping(node) {
|
||||
|
|
@ -169,34 +218,64 @@ export default {
|
|||
|| node.type === 'CC' || node.type === 'DELAY'
|
||||
|| node.type === 'TRIGGER');
|
||||
},
|
||||
//是否为分支节点
|
||||
isBranchNode(node) {
|
||||
return node && (node.type === 'CONDITIONS' || node.type === 'CONCURRENTS');
|
||||
},
|
||||
//是否为空节点
|
||||
isEmptyNode(node) {
|
||||
return node && (node.type === 'EMPTY')
|
||||
},
|
||||
isEndNode(node) {
|
||||
return node && (node.type === 'END')
|
||||
},
|
||||
//是否为空节点
|
||||
isMergeNode(node) {
|
||||
return node && (node.type === 'MERGE')
|
||||
},
|
||||
//是分支节点
|
||||
isConditionNode(node) {
|
||||
isConditionNodes(node) {
|
||||
return node.type === 'CONDITIONS';
|
||||
},
|
||||
isConditionNode(node) {
|
||||
return node.type === 'CONDITION';
|
||||
},
|
||||
//是分支节点
|
||||
isBranchSubNode(node) {
|
||||
return node && (node.type === 'CONDITION' || node.type === 'CONCURRENT');
|
||||
},
|
||||
isConcurrentNode(node) {
|
||||
//时候并行节点
|
||||
isConcurrentNodes(node) {
|
||||
return node.type === 'CONCURRENTS'
|
||||
},
|
||||
//时候并行节点
|
||||
isConcurrentNode(node) {
|
||||
return node.type === 'CONCURRENT'
|
||||
},
|
||||
//新增一个节点id
|
||||
getRandomId() {
|
||||
return `node_${new Date().getTime().toString().substring(5)}${Math.round(Math.random() * 9000 + 1000)}`
|
||||
let d = new Date().getTime()
|
||||
// x 是 0-9 或 a-f 范围内的一个32位十六进制数
|
||||
let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
||||
let r = (d + Math.random() * 16) % 16 | 0
|
||||
d = Math.floor(d / 16)
|
||||
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16)
|
||||
})
|
||||
return uuid
|
||||
// return `node_${new Date().getTime().toString().substring(5)}${Math.round(Math.random() * 9000 + 1000)}`
|
||||
},
|
||||
//选中一个节点
|
||||
selectNode(node) {
|
||||
this.$store.commit('selectedNode', node)
|
||||
console.log(node,"node")
|
||||
if (!this.isConcurrentNode(node)) {
|
||||
this.$emit('selectedNode', node)
|
||||
}
|
||||
},
|
||||
|
||||
//处理节点插入逻辑
|
||||
insertNode(type, parentNode) {
|
||||
console.log("type", type)
|
||||
this.$refs['_root'].click()
|
||||
//插入新节点
|
||||
let id = this.getRandomId();
|
||||
|
|
@ -291,7 +370,7 @@ export default {
|
|||
this.dom.push(newNode)
|
||||
},
|
||||
/**
|
||||
* 新增条件分支
|
||||
* 新增条件分支F
|
||||
* @param node
|
||||
*/
|
||||
insertConditionsNode(node) {
|
||||
|
|
@ -337,16 +416,16 @@ export default {
|
|||
{
|
||||
id: this.getRandomId(),
|
||||
parentId: node.id,
|
||||
type: "CONDITION",
|
||||
type: "CONCURRENT",
|
||||
props: this.$deepCopy(DefaultProps.CONDITION_PROPS),
|
||||
name: "条件1",
|
||||
name: "分支1",
|
||||
children: {}
|
||||
}, {
|
||||
id: this.getRandomId(),
|
||||
parentId: node.id,
|
||||
type: "CONDITION",
|
||||
type: "CONCURRENT",
|
||||
props: this.$deepCopy(DefaultProps.CONDITION_PROPS),
|
||||
name: "条件2",
|
||||
name: "分支2",
|
||||
children: {}
|
||||
}
|
||||
]
|
||||
|
|
@ -356,7 +435,7 @@ export default {
|
|||
let emptyNode = {
|
||||
id: this.getRandomId(),
|
||||
parentId: node.id,
|
||||
type: "EMPTY"
|
||||
type: "MERGE"
|
||||
}
|
||||
this.updateParentId(emptyNode.id, newNode.id)
|
||||
this.dom.push(emptyNode)
|
||||
|
|
@ -367,9 +446,9 @@ export default {
|
|||
node.branchs.push({
|
||||
id: this.getRandomId(),
|
||||
parentId: node.id,
|
||||
name: (this.isConditionNode(node) ? '条件' : '分支') + (node.branchs.length + 1),
|
||||
props: this.isConditionNode(node) ? this.$deepCopy(DefaultProps.CONDITION_PROPS) : {},
|
||||
type: this.isConditionNode(node) ? "CONDITION" : "CONCURRENT",
|
||||
name: (this.isConditionNodes(node) ? '条件' : '分支') + (node.branchs.length + 1),
|
||||
props: this.isConditionNodes(node) ? this.$deepCopy(DefaultProps.CONDITION_PROPS) : {},
|
||||
type: this.isConditionNodes(node) ? "CONDITION" : "CONCURRENT",
|
||||
children: {}
|
||||
})
|
||||
} else {
|
||||
|
|
@ -406,7 +485,7 @@ export default {
|
|||
this.doDelBranchNode(parentNode, node)
|
||||
})
|
||||
return
|
||||
}else {
|
||||
} else {
|
||||
// 没有直接开始删除
|
||||
this.doDelBranchNode(parentNode, node)
|
||||
}
|
||||
|
|
@ -420,48 +499,48 @@ export default {
|
|||
}
|
||||
},
|
||||
//删除分支节点
|
||||
doDelBranchNode(parentNode, node){
|
||||
doDelBranchNode(parentNode, node) {
|
||||
//判断当前分时是否为2
|
||||
if (parentNode.branchs.length === 2){
|
||||
if (parentNode.branchs.length === 2) {
|
||||
let nodeList = [...parentNode.branchs]
|
||||
nodeList.splice(nodeList.indexOf(node), 1)
|
||||
//查看另外一个分支上是否有节点
|
||||
let sunNode = this.parentMap.get(nodeList[0].id)
|
||||
//有则需要放到主分支上
|
||||
if (sunNode){
|
||||
if (sunNode) {
|
||||
//更改分支上第一个节点的父id
|
||||
this.updateParentId(parentNode.parentId,sunNode.parentId)
|
||||
this.updateParentId(parentNode.parentId, sunNode.parentId)
|
||||
//找到最后一个节点
|
||||
let lastNode = this.getLastBranchNode(sunNode.id)
|
||||
let emptyNode = this.parentMap.get(parentNode.id)
|
||||
//更新空节点下的第一个节点的id为当前分支最后一个节点
|
||||
this.updateParentId(lastNode.id,emptyNode.id)
|
||||
this.updateParentId(lastNode.id, emptyNode.id)
|
||||
//删除分支的主节点
|
||||
this.delNodeInDom(parentNode)
|
||||
//删除分支的空节点
|
||||
this.delNodeInDom(emptyNode)
|
||||
}else {
|
||||
} else {
|
||||
//没有则直接删除
|
||||
this.delEntireBranch(parentNode)
|
||||
}
|
||||
}else {
|
||||
} else {
|
||||
parentNode.branchs.splice(parentNode.branchs.indexOf(node), 1)
|
||||
}
|
||||
},
|
||||
//获取最后一个节点
|
||||
getLastBranchNode(id){
|
||||
getLastBranchNode(id) {
|
||||
let node = this.parentMap.get(id)
|
||||
if (node){
|
||||
if (node) {
|
||||
return this.getLastBranchNode(node.id)
|
||||
}else {
|
||||
} else {
|
||||
return this.nodeMap.get(id)
|
||||
}
|
||||
},
|
||||
delEntireBranch(node){
|
||||
delEntireBranch(node) {
|
||||
//删除分支节点和空节点
|
||||
let emptyNode = this.parentMap.get(node.id)
|
||||
this.delNodeInDomChange(node.id,node.parentId)
|
||||
this.delNodeInDomChange(emptyNode.id,emptyNode.parentId)
|
||||
this.delNodeInDomChange(node.id, node.parentId)
|
||||
this.delNodeInDomChange(emptyNode.id, emptyNode.parentId)
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
@ -472,10 +551,10 @@ export default {
|
|||
delNodeInDomChange(delId, parentId) {
|
||||
this.updateParentId(parentId, delId)
|
||||
let delNode = this.nodeMap.get(delId)
|
||||
this.dom.splice(this.dom.indexOf(delNode),1)
|
||||
this.dom.splice(this.dom.indexOf(delNode), 1)
|
||||
},
|
||||
delNodeInDom(delNode){
|
||||
this.dom.splice(this.dom.indexOf(delNode),1)
|
||||
delNodeInDom(delNode) {
|
||||
this.dom.splice(this.dom.indexOf(delNode), 1)
|
||||
},
|
||||
validateProcess() {
|
||||
this.valid = true
|
||||
|
|
@ -508,11 +587,11 @@ export default {
|
|||
},
|
||||
//校验所有节点设置
|
||||
validate(err, nodeList) {
|
||||
nodeList.map(node=>{
|
||||
if (this.isPrimaryNode(node)){
|
||||
nodeList.map(node => {
|
||||
if (this.isPrimaryNode(node)) {
|
||||
//校验条件节点
|
||||
this.validateNode(err, node)
|
||||
}else if (this.isBranchNode(node)){
|
||||
} else if (this.isBranchNode(node)) {
|
||||
node.branchs.map(branchNode => {
|
||||
//校验条件节点
|
||||
this.validateNode(err, branchNode)
|
||||
|
|
@ -535,6 +614,7 @@ export default {
|
|||
margin: 0 auto;
|
||||
margin-bottom: 20px;
|
||||
border-radius: 15px;
|
||||
text-align: center;
|
||||
padding: 5px 10px;
|
||||
font-size: small;
|
||||
color: #747474;
|
||||
|
|
@ -542,6 +622,7 @@ export default {
|
|||
box-shadow: 0 0 10px 0 #bcbcbc;
|
||||
}
|
||||
|
||||
|
||||
.primary-node {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
|
|||
|
|
@ -38,9 +38,10 @@ export default {
|
|||
return {}
|
||||
},
|
||||
computed:{
|
||||
selectedNode(){
|
||||
this.$store.state.selectedNode
|
||||
}
|
||||
// eslint-disable-next-line vue/return-in-computed-property
|
||||
// selectedNode(){
|
||||
// this.$store.state.selectedNode
|
||||
// }
|
||||
},
|
||||
methods: {
|
||||
addApprovalNode(){
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="readOnly" label="只读" width="80">
|
||||
<template slot="header" slot-scope="scope">
|
||||
<template slot="header">
|
||||
<el-radio label="R" v-model="permSelect" @change="allSelect('R')">只读</el-radio>
|
||||
</template>
|
||||
<template slot-scope="scope">
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="editable" label="可编辑" width="90" v-if="nowNode.type !== 'CC'">
|
||||
<template slot="header" slot-scope="scope">
|
||||
<template slot="header">
|
||||
<el-radio label="E" v-model="permSelect" @change="allSelect('E')">可编辑</el-radio>
|
||||
</template>
|
||||
<template slot-scope="scope">
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="hide" label="隐藏" width="80">
|
||||
<template slot="header" slot-scope="scope">
|
||||
<template slot="header">
|
||||
<el-radio label="H" v-model="permSelect" @change="allSelect('H')">隐藏</el-radio>
|
||||
</template>
|
||||
<template slot-scope="scope">
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
@selected="$emit('selected')" @delNode="$emit('delNode')" @insertNode="type => $emit('insertNode', type)"
|
||||
placeholder="请设置审批人" header-bgc="#ff943e" header-icon="el-icon-s-check"/>
|
||||
</template>
|
||||
|
||||
<!--审批人节点-->
|
||||
<script>
|
||||
import Node from './Node'
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
@selected="$emit('selected')" @delNode="$emit('delNode')" @insertNode="type => $emit('insertNode', type)"
|
||||
placeholder="请设置抄送人" header-bgc="#3296fa" header-icon="el-icon-s-promotion"/>
|
||||
</template>
|
||||
|
||||
<!--抄送节点-->
|
||||
<script>
|
||||
import Node from './Node'
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
<template>
|
||||
<div class="node">
|
||||
<!-- 并行分支选择后右侧出现操作面板,占时不需要 <div class="node-body" @click="$emit('selected')">-->
|
||||
<div class="node-body" @click="$emit('selected')">
|
||||
<div class="node-body-left" @click.stop="$emit('leftMove')" v-if="level > 1">
|
||||
<i class="el-icon-arrow-left"></i>
|
||||
|
|
@ -32,7 +33,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!--并行节点-->
|
||||
<script>
|
||||
import InsertButton from '@/views/common/InsertButton.vue'
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import InsertButton from '@/views/common/InsertButton.vue'
|
||||
import {ValueType} from '@/views/common/form/ComponentsConfigExport'
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
@selected="$emit('selected')" @delNode="$emit('delNode')" @insertNode="type => $emit('insertNode', type)"
|
||||
placeholder="请设置延时时间" header-bgc="#f25643" header-icon="el-icon-time"/>
|
||||
</template>
|
||||
|
||||
<!--延时器节点-->
|
||||
<script>
|
||||
import Node from './Node'
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
<template>
|
||||
<node :show="false" :merge="true" @insertNode="type => $emit('insertNode', type)"/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Node from './Node'
|
||||
|
||||
export default {
|
||||
name: "MergeNode",
|
||||
components: {Node},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
methods: {}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
|
@ -21,6 +21,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="node-footer">
|
||||
<div v-if="merge" class="branch-merge"><img data-v-1e7b1da5="" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAABXlJREFUeF7tmm2IVGUUx3/nLkQUqxmkpAVhSPUllZX8EEGhvVgZQWCU6wcpsqi2mXtnoaBwoqLCufeO9oJYUJQiFZWlZPQCfYiIXkylstTyS1oWWeYWCe6cuLsz7t3r3Ll3du6907oz35bnPM9z/r895zznmWeECf6RCa6fDoBOBExwAp0UmOAB0CmCnRTopECbCZi2nivK1CMD7FpXlH+ydqctKZBz9QyjwkqFG4HzfKK/0gpvl/ulmBWIzAHkVmlRDFY2EihwwLFkRhYQxgzAtHW2CpcBc4CpOsg26eK7yVPYVFwu/9ZzPufq2VLhQBxhAk85lvSF2Y5l/3prjQlAvqR3IjwJTKqz6DeGssQuyLfBsbyjz6PcFgeAZyOwzLFk/QnrjHH/RACYtj6ncHuUCDWYXs7Lz367XEn3inB+1NzauMLGsiW3+u1b2b9lAH22LuiCD2IJED5yTbmiZpt3dAbKT7Hmjhjtdi25oPZnK/uH7dtUCpi2vqVwQ1wRWuHhWkW3StpTEb6IO3fIThhwTemuzWll/0QA5G39FTgrtghhs2vKELA7inra6d38HXvusOEnriWXHo+iFvZvGUDfap3VdYzdzQgIHmd5W7cBc2Ovoax1C3KXZ5/E/i3VgCQciNMD+J1Ug55yXjxo7QfgOdFKCvjyeL/C9MgoEBa5przrt0ti/+C+mRVB/8amrWsU7m2Ql/c5lqwJjre9CDZ1DMFnriXzw0SatvZW4FqBW6o2vwGvCGxyLPmw3rym9g8cwy0XQV8Ix2qEgH0C1ziWNCyceVu1uvZrriVLGqVGsainHO7mRyDynlCvEWupCI7Kxcat6BFg+OwW9ohyfSMIcQF44v/sZovAlRH1I7QVTwyAt1Cjy8hfh9hYvepGQogDoI74HYbSXzHwusTYl7FEAURVcdPWN+NAiAJQTzzCda4p+6N8iDPe1CkQZ8FAtY+E0AhA2uKHszTlT1QkhAHIQnwmAKr1IjQS6gHISnxmABpBCALIUnymAMIgKHxf6wMmH6E3cNTtSLLgZXoKNOgAR6UDyqyq7esKk3znfOriM48AXzc5AmGE1EFgWvXPTMS3DcAJ6TA6XDIT31YAoRCEc5JqcuKc8Kn3AVFO+E4BryvJVHzbI8BzwAdgi2vJ4ihgSY//nyIg8jqctPi2RYBp61wV5qsyR2BFVdhBhBe0wtdisNU15VAagoNrZh4BOVsfFcVCODVUoLBn6E2hIBvShpApgLyt3nvhRXFFCWxwLOmNaz8Wu8wA5G31ntQWNOukwD2OJc80Oy+ufSYAciVdJsJLcZ0K2nV1MbuUk51jnd9oXuoACmW9eHCQj49/T+j3RtiJslPgFxXmoVxe11nhPdeUq8clANPWPoXVQef9D6e1saEHVINHUBYF7Q1lnl2QL5OGkHoE5G19GRhVyBQ+L1tyST0xoa/Iygq3IOvGI4BdwIWjHBeecE15IExM3tYfgJmBOetcU2o9Q2IcsoiAw8Gf0qhyU7kgb4QCcPRTlNGvSspmtzD81J7kJ30AJX0fYeHo2seLjiXLG0TA78CZ/nGFB8uWPJakeG+t9AE4+jjK/XGLWtgTusBix5It4w5ArqRLRTjhl14IW40KD/kre66ki0R4p57IrgozS/2yb9wByDvqhbKX07Xv/oIavMfOP6pFb0pdgcqrbkFuTlp8JingbRIaBfEUHUOYltbtMPUaUNNo2rpeYWk8zSNWqvSmeSvMDIAnybT1boWnY0I4aigL7YJ4bXRqn0wBeCqG7gYVVqFcFapKWXt0gP5nizKQmvLqwpkDqAkaanmhB4MelOkI27XCDjHY7pqyN23htfXbBiArgVH7dABEETrZxzsRcLL/h6P0/Qc1qphfvB2K3wAAAABJRU5ErkJggg==" alt=""></div>
|
||||
<div class="btn">
|
||||
<insert-button @insertNode="type => $emit('insertNode', type)"></insert-button>
|
||||
</div>
|
||||
|
|
@ -45,6 +46,11 @@ export default {
|
|||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
//是否显示节点体
|
||||
merge: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
//节点内容区域文字
|
||||
content: {
|
||||
type: String,
|
||||
|
|
@ -175,6 +181,19 @@ export default {
|
|||
|
||||
.node-footer{
|
||||
position: relative;
|
||||
.branch-merge{
|
||||
font-size: 12px;
|
||||
display: flex;
|
||||
width: 38px;
|
||||
border-radius: 50%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: -20px auto 0;
|
||||
background: #fff;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
box-shadow: 0 0 5px 0 #d8d8d8;
|
||||
}
|
||||
.btn{
|
||||
width: 100%;
|
||||
display: flex;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
<template>
|
||||
<div>
|
||||
流程结束
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "ProcessEndNode"
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
|
||||
</style>
|
||||
|
|
@ -3,10 +3,9 @@
|
|||
@selected="$emit('selected')" @insertNode="type => $emit('insertNode', type)"
|
||||
placeholder="所有人" header-bgc="#576a95" header-icon="el-icon-user-solid"/>
|
||||
</template>
|
||||
|
||||
<!--根节点-->
|
||||
<script>
|
||||
import Node from './Node'
|
||||
|
||||
export default {
|
||||
name: "RootNode",
|
||||
components: {Node},
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
@selected="$emit('selected')" @delNode="$emit('delNode')" @insertNode="type => $emit('insertNode', type)"
|
||||
placeholder="请设置触发器" header-bgc="#47bc82" header-icon="el-icon-set-up"/>
|
||||
</template>
|
||||
|
||||
<!--触发器节点-->
|
||||
<script>
|
||||
import Node from './Node'
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue