376 lines
9.6 KiB
Vue
376 lines
9.6 KiB
Vue
<template>
|
|
<div style="margin-top: 15px">
|
|
<el-button @click="changPan('processSetting')">流程设置</el-button>
|
|
<!-- <el-button @click="changPan('formDesign')">表单</el-button>-->
|
|
<el-button @click="changPan('processDesign')">流程</el-button>
|
|
<el-button @click="publishProcess">发布</el-button>
|
|
<div class="layout-body" v-if="visible">
|
|
<div v-show="activeSelect === 'processSetting'">
|
|
<process-setting ref="processSetting"/>
|
|
</div>
|
|
<div v-show="activeSelect === 'processDesign'">
|
|
<process-design ref="processDesign"/>
|
|
</div>
|
|
<!-- <div v-show="activeSelect === 'formDesign'">-->
|
|
<!-- <form-design ref="formDesign"/>-->
|
|
<!-- </div>-->
|
|
</div>
|
|
|
|
</div>
|
|
<el-dialog 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" :sub-title="validResult.desc">
|
|
<template #icon>
|
|
<el-icon style="font-size: 30px" v-if="!validResult.finished">
|
|
<Loading/>
|
|
</el-icon>
|
|
<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">
|
|
<div slot="pre">
|
|
<el-icon>
|
|
<WarningFilled/>
|
|
</el-icon>
|
|
</div>
|
|
</ellipsis>
|
|
</div>
|
|
<div v-if="validResult.finished && validResult.success">
|
|
<el-icon color="#67c23a" size="70">
|
|
<CircleCheckFilled/>
|
|
</el-icon>
|
|
</div>
|
|
</template>
|
|
<template #extra>
|
|
<el-button type="primary" v-if="validResult.finished" size="medium" @click="doAfter">
|
|
{{ validResult.action }}
|
|
</el-button>
|
|
</template>
|
|
</el-result>
|
|
</el-dialog>
|
|
</template>
|
|
|
|
<script setup>
|
|
import {getProcessDefinitionInfo, addProcessDefinition} from "@/api/workflow/process-definition.js";
|
|
import ProcessDesign from '@/views/workflow/process/ProcessDesign.vue'
|
|
import FormDesign from '@/views/workflow/form/FormDesign.vue'
|
|
import ProcessSetting from "./ProcessSetting.vue";
|
|
import Ellipsis from '@/views/workflow/process/common/Ellipsis.vue'
|
|
import {getCurrentInstance} from '@vue/runtime-core';
|
|
|
|
let {proxy} = getCurrentInstance();
|
|
import {Loading, WarningFilled, CircleCheckFilled} from '@element-plus/icons-vue'
|
|
|
|
const router = useRouter()
|
|
const params = reactive(router.currentRoute.value.params)
|
|
import {useProcessStore} from '@/stores/processStore.js'
|
|
|
|
const processStore = useProcessStore()
|
|
import {ElMessage, ElMessageBox} from "element-plus";
|
|
|
|
const processDesign = ref()
|
|
const visible = ref(false)
|
|
const timer = ref(null)
|
|
// const validComponents = ref(['processSetting', 'formDesign', 'processDesign'])
|
|
const validComponents = ref(['processSetting', 'processDesign'])
|
|
// const activeSelect = ref('formDesign')
|
|
// const activeSelect = ref('processSetting')
|
|
const activeSelect = ref('processDesign')
|
|
const validVisible = ref(false)
|
|
const validStep = ref(0)
|
|
const validResult = ref({})
|
|
const validOptions = ref([
|
|
{title: '基础信息', description: '', icon: '', status: ''},
|
|
// {title: '审批表单', description: '', icon: '', status: ''},
|
|
{title: '审批流程', description: '', icon: '', status: ''},
|
|
// {title: '扩展设置', description: '', icon: '', status: ''}
|
|
])
|
|
|
|
|
|
const errTitle = computed(() => {
|
|
if (validResult.finished && !validResult.success) {
|
|
return validResult.title + ` (${validResult.errs.length}项错误) 😥`
|
|
}
|
|
return validResult.title
|
|
})
|
|
|
|
|
|
const validIcon = computed(() => {
|
|
if (!validResult.finished) {
|
|
return Loading
|
|
} else if (validResult.success) {
|
|
return CircleCheckFilled
|
|
} else {
|
|
return WarningFilled
|
|
}
|
|
})
|
|
|
|
const init = () => {
|
|
let deploymentId = params.deploymentId
|
|
if (deploymentId === undefined) {
|
|
loadInitFrom()
|
|
} else {
|
|
getProcessInfo()
|
|
}
|
|
}
|
|
|
|
const loadInitFrom = () => {
|
|
let design = {
|
|
processDefinitionKey: 'pro' + getRandomId(),
|
|
deploymentName: "未命名表单",
|
|
processKey: '',
|
|
// logo: {
|
|
// icon: "el-icon-eleme",
|
|
// background: "#1e90ff"
|
|
// },
|
|
// settings: {
|
|
// commiter: [],
|
|
// admin: [],
|
|
// sign: false,
|
|
// notify: {
|
|
// types: ["APP"],
|
|
// title: "消息通知标题"
|
|
// }
|
|
// },
|
|
groupId: 1,
|
|
// formItems: [],
|
|
process: [
|
|
{
|
|
id: "root",
|
|
parentId: "admin",
|
|
type: "ROOT",
|
|
name: "发起人",
|
|
desc: "任何人",
|
|
props: {
|
|
assignedUser: [],
|
|
formPerms: []
|
|
},
|
|
},
|
|
{
|
|
id: "end",
|
|
parentId: "root",
|
|
type: "END",
|
|
}
|
|
],
|
|
processFromPerms: [{
|
|
id: "projectName",
|
|
title: "项目名称",
|
|
required: true,
|
|
perm: "R"
|
|
}, {
|
|
id: "projectType",
|
|
title: "项目类型",
|
|
required: true,
|
|
perm: "R"
|
|
}, {
|
|
id: "projectDesc",
|
|
title: "项目描述",
|
|
required: true,
|
|
perm: "R"
|
|
}, {
|
|
id: "projectManager",
|
|
title: "项目经理",
|
|
required: true,
|
|
perm: "R"
|
|
}],
|
|
remark: "备注说明"
|
|
}
|
|
processStore.setDesign(design)
|
|
visible.value = true
|
|
nextTick(() => {
|
|
processDesign.value.initRender()
|
|
})
|
|
}
|
|
|
|
const getRandomId = () => {
|
|
let d = new Date().getTime()
|
|
// x 是 0-9 或 a-f 范围内的一个32位十六进制数
|
|
let id = '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 id
|
|
}
|
|
|
|
const getProcessInfo = async () => {
|
|
getProcessDefinitionInfo(params.deploymentId).then(res => {
|
|
if (res.code === 1000) {
|
|
processStore.setDesign(res.data)
|
|
visible.value = true
|
|
nextTick(() => {
|
|
processDesign.value.initRender()
|
|
})
|
|
} else {
|
|
ElMessage.error(res.msg)
|
|
}
|
|
})
|
|
}
|
|
|
|
const validateDesign = () => {
|
|
validVisible.value = true
|
|
validStep.value = 0
|
|
showValiding()
|
|
stopTimer()
|
|
timer.value = setInterval(() => {
|
|
validResult.value.errs = proxy.$refs[validComponents.value[validStep.value]].validate()
|
|
if (Array.isArray(validResult.value.errs) && validResult.value.errs.length === 0) {
|
|
validStep.value++;
|
|
if (validStep.value >= validOptions.value.length) {
|
|
stopTimer()
|
|
showValidFinish(true)
|
|
}
|
|
} else {
|
|
stopTimer()
|
|
validOptions.value[validStep.value].status = 'error'
|
|
showValidFinish(false, getDefaultValidErr())
|
|
}
|
|
}, 300)
|
|
}
|
|
|
|
|
|
const getDefaultValidErr = () => {
|
|
switch (validStep.value) {
|
|
case 0:
|
|
return '请检查基础设置项';
|
|
case 1:
|
|
return '请检查审批表单相关设置'
|
|
// case 2:
|
|
// return '请检查审批流程,查看对应标注节点错误信息'
|
|
// case 3:
|
|
// return '请检查扩展设置'
|
|
default:
|
|
return '未知错误'
|
|
}
|
|
}
|
|
const showValidFinish = (success, err) => {
|
|
console.log("处理完成")
|
|
validResult.value.success = success
|
|
validResult.value.finished = true
|
|
validResult.value.title = success ? '校验完成 😀' : '校验失败 '
|
|
validResult.value.desc = success ? '设置项校验成功,是否提交?' : err
|
|
validResult.value.action = success ? '提 交' : '去修改'
|
|
}
|
|
const showValiding = () => {
|
|
validResult.value = {
|
|
errs: [],
|
|
finished: false,
|
|
success: false,
|
|
title: '检查中...',
|
|
action: '处理',
|
|
desc: '正在检查设置项'
|
|
}
|
|
validStep.value = 0
|
|
validOptions.value.forEach(op => {
|
|
op.status = ''
|
|
op.icon = ''
|
|
op.description = ''
|
|
})
|
|
}
|
|
const doAfter = () => {
|
|
if (validResult.value.success) {
|
|
doPublish()
|
|
} else {
|
|
activeSelect.value = validComponents.value[validStep.value]
|
|
validVisible.value = false
|
|
}
|
|
}
|
|
|
|
const tarry = (node) => {
|
|
if (node && node.id) {
|
|
let newNode = {...node}
|
|
newNode.children = null
|
|
array.push(newNode)
|
|
tarry(node.children)
|
|
}
|
|
}
|
|
const stopTimer = () => {
|
|
if (timer.value) {
|
|
clearInterval(timer.value)
|
|
}
|
|
}
|
|
const preview = () => {
|
|
validateDesign()
|
|
}
|
|
//发布流程
|
|
const publishProcess = () => {
|
|
validateDesign()
|
|
}
|
|
// todo 提交数据
|
|
const doPublish = () => {
|
|
ElMessageBox.confirm('如果您只想预览请选择预览,确认发布后流程立即生效,是否继续?', '提示', {
|
|
confirmButtonText: '发布',
|
|
cancelButtonText: '取消',
|
|
type: 'warning'
|
|
}).then(() => {
|
|
let design = processStore.getDesign()
|
|
console.log(design)
|
|
let template = {
|
|
...design
|
|
}
|
|
console.log(template)
|
|
addProcessDefinition(template).then(res => {
|
|
if (res.code === 1000) {
|
|
ElMessage.success(res.msg)
|
|
router.push("/workflow/process")
|
|
} else {
|
|
ElMessage.error(res.msg)
|
|
}
|
|
}).catch(err => {
|
|
ElMessage.error(err)
|
|
})
|
|
})
|
|
}
|
|
|
|
|
|
const changPan = (val) => {
|
|
activeSelect.value = val
|
|
}
|
|
|
|
init()
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.layout-body {
|
|
min-width: 980px;
|
|
}
|
|
|
|
.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>
|