mirror of
https://gitee.com/myxzgzs/boyue-ui-admin-vue3
synced 2025-08-08 08:22:41 +08:00
209 lines
5.2 KiB
Vue
209 lines
5.2 KiB
Vue
<template>
|
||
<el-drawer
|
||
:append-to-body="true"
|
||
v-model="settingVisible"
|
||
:show-close="false"
|
||
:size="588"
|
||
:before-close="handleClose"
|
||
>
|
||
<template #header>
|
||
<div class="config-header">
|
||
<input
|
||
v-if="showInput"
|
||
type="text"
|
||
class="config-editable-input"
|
||
@blur="blurEvent()"
|
||
v-mountedFocus
|
||
v-model="currentNode.name"
|
||
:placeholder="currentNode.name"
|
||
/>
|
||
<div v-else class="node-name"
|
||
>{{ currentNode.name }}
|
||
<Icon class="ml-1" icon="ep:edit-pen" :size="16" @click="clickIcon()"
|
||
/></div>
|
||
|
||
<div class="divide-line"></div>
|
||
</div>
|
||
</template>
|
||
<div>
|
||
<div class="mb-3 font-size-16px" v-if="currentNode.conditionSetting?.defaultFlow"
|
||
>未满足其它条件时,将进入此分支(该分支不可编辑和删除)</div
|
||
>
|
||
<div v-else>
|
||
<Condition ref="conditionRef" v-model="condition" />
|
||
</div>
|
||
</div>
|
||
<template #footer>
|
||
<el-divider />
|
||
<div>
|
||
<el-button type="primary" @click="saveConfig">确 定</el-button>
|
||
<el-button @click="closeDrawer">取 消</el-button>
|
||
</div>
|
||
</template>
|
||
</el-drawer>
|
||
</template>
|
||
<script setup lang="ts">
|
||
import { SimpleFlowNode, ConditionType } from '../consts'
|
||
import { getDefaultConditionNodeName } from '../utils'
|
||
import { useFormFieldsAndStartUser, getConditionShowText } from '../node'
|
||
import Condition from './components/Condition.vue'
|
||
import { cloneDeep } from 'lodash-es'
|
||
const message = useMessage() // 消息弹窗
|
||
defineOptions({
|
||
name: 'ConditionNodeConfig'
|
||
})
|
||
const props = defineProps({
|
||
conditionNode: {
|
||
type: Object as () => SimpleFlowNode,
|
||
required: true
|
||
},
|
||
nodeIndex: {
|
||
type: Number,
|
||
required: true
|
||
}
|
||
})
|
||
const settingVisible = ref(false)
|
||
const currentNode = ref<SimpleFlowNode>(props.conditionNode)
|
||
const condition = ref<any>({
|
||
conditionType: ConditionType.RULE, // 设置默认值
|
||
conditionExpression: '',
|
||
conditionGroups: {
|
||
and: true,
|
||
conditions: [{
|
||
and: true,
|
||
rules: [{
|
||
opCode: '==',
|
||
leftSide: '',
|
||
rightSide: ''
|
||
}]
|
||
}]
|
||
}
|
||
})
|
||
const open = () => {
|
||
// 如果有已存在的配置则使用,否则使用默认值
|
||
if (currentNode.value.conditionSetting) {
|
||
condition.value = cloneDeep(currentNode.value.conditionSetting)
|
||
} else {
|
||
// 重置为默认值
|
||
condition.value = {
|
||
conditionType: ConditionType.RULE,
|
||
conditionExpression: '',
|
||
conditionGroups: {
|
||
and: true,
|
||
conditions: [{
|
||
and: true,
|
||
rules: [{
|
||
opCode: '==',
|
||
leftSide: '',
|
||
rightSide: ''
|
||
}]
|
||
}]
|
||
}
|
||
}
|
||
}
|
||
settingVisible.value = true
|
||
}
|
||
|
||
watch(
|
||
() => props.conditionNode,
|
||
(newValue) => {
|
||
currentNode.value = newValue
|
||
}
|
||
)
|
||
// 显示名称输入框
|
||
const showInput = ref(false)
|
||
|
||
const clickIcon = () => {
|
||
showInput.value = true
|
||
}
|
||
// 输入框失去焦点
|
||
const blurEvent = () => {
|
||
showInput.value = false
|
||
currentNode.value.name =
|
||
currentNode.value.name ||
|
||
getDefaultConditionNodeName(props.nodeIndex, currentNode.value?.conditionSetting?.defaultFlow)
|
||
}
|
||
|
||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||
|
||
// 关闭
|
||
const closeDrawer = () => {
|
||
settingVisible.value = false
|
||
}
|
||
|
||
const handleClose = async (done: (cancel?: boolean) => void) => {
|
||
const isSuccess = await saveConfig()
|
||
if (!isSuccess) {
|
||
done(true) // 传入 true 阻止关闭
|
||
} else {
|
||
done()
|
||
}
|
||
}
|
||
|
||
/** 保存配置 */
|
||
const fieldOptions = useFormFieldsAndStartUser() // 流程表单字段和发起人字段
|
||
const conditionRef = ref()
|
||
const saveConfig = async () => {
|
||
if (!currentNode.value.conditionSetting?.defaultFlow) {
|
||
// 校验表单
|
||
const valid = await conditionRef.value.validate()
|
||
if (!valid) return false
|
||
const showText = getConditionShowText(
|
||
condition.value?.conditionType,
|
||
condition.value?.conditionExpression,
|
||
condition.value.conditionGroups,
|
||
fieldOptions
|
||
)
|
||
if (!showText) {
|
||
return false
|
||
}
|
||
currentNode.value.showText = showText
|
||
// 使用 cloneDeep 进行深拷贝
|
||
currentNode.value.conditionSetting = cloneDeep({
|
||
...currentNode.value.conditionSetting,
|
||
conditionType: condition.value?.conditionType,
|
||
conditionExpression: condition.value?.conditionType === ConditionType.EXPRESSION ? condition.value?.conditionExpression : undefined,
|
||
conditionGroups: condition.value?.conditionType === ConditionType.RULE ? condition.value?.conditionGroups : undefined
|
||
})
|
||
}
|
||
settingVisible.value = false
|
||
return true
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.condition-group-tool {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
width: 500px;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.condition-group {
|
||
position: relative;
|
||
|
||
&:hover {
|
||
border-color: #0089ff;
|
||
|
||
.condition-group-delete {
|
||
opacity: 1;
|
||
}
|
||
}
|
||
|
||
.condition-group-delete {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
display: flex;
|
||
cursor: pointer;
|
||
opacity: 0;
|
||
}
|
||
}
|
||
|
||
::v-deep(.el-card__header) {
|
||
padding: 8px var(--el-card-padding);
|
||
border-bottom: 1px solid var(--el-card-border-color);
|
||
box-sizing: border-box;
|
||
}
|
||
</style>
|