209 lines
5.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>