feat: [bpm][ele] 仿钉钉流程设计器迁移问题修复

This commit is contained in:
jason
2025-11-23 10:56:59 +08:00
parent 0e6d92e328
commit fec9a768d9
8 changed files with 134 additions and 177 deletions

View File

@@ -41,7 +41,7 @@ defineOptions({
const props = defineProps({ const props = defineProps({
modelValue: { modelValue: {
type: Object, type: Object,
required: true, required: false,
default: () => ({}), default: () => ({}),
}, },
}); });

View File

@@ -158,7 +158,7 @@ function changeNodeName() {
defineExpose({ open }); // 提供 open 方法,用于打开弹窗 defineExpose({ open }); // 提供 open 方法,用于打开弹窗
</script> </script>
<template> <template>
<Drawer class="w-1/3"> <Drawer class="w-2/5">
<template #title> <template #title>
<div class="flex items-center"> <div class="flex items-center">
<ElInput <ElInput
@@ -190,7 +190,7 @@ defineExpose({ open }); // 提供 open 方法,用于打开弹窗
未满足其它条件时将进入此分支该分支不可编辑和删除 未满足其它条件时将进入此分支该分支不可编辑和删除
</div> </div>
<div v-else> <div v-else>
<Condition ref="conditionRef" v-model:model-value="condition" /> <Condition ref="conditionRef" v-model="condition" />
</div> </div>
</div> </div>
</Drawer> </Drawer>

View File

@@ -10,7 +10,6 @@ import { BpmNodeTypeEnum } from '@vben/constants';
import { IconifyIcon } from '@vben/icons'; import { IconifyIcon } from '@vben/icons';
import { import {
ElCol,
ElDatePicker, ElDatePicker,
ElForm, ElForm,
ElFormItem, ElFormItem,
@@ -19,7 +18,6 @@ import {
ElOption, ElOption,
ElRadio, ElRadio,
ElRadioGroup, ElRadioGroup,
ElRow,
ElSelect, ElSelect,
} from 'element-plus'; } from 'element-plus';
@@ -77,7 +75,7 @@ function getShowText(): string {
showText = `延迟${configForm.value.timeDuration}${TIME_UNIT_TYPES?.find((item) => item.value === configForm.value.timeUnit)?.label}`; showText = `延迟${configForm.value.timeDuration}${TIME_UNIT_TYPES?.find((item) => item.value === configForm.value.timeUnit)?.label}`;
} }
if (configForm.value.delayType === DelayTypeEnum.FIXED_DATE_TIME) { if (configForm.value.delayType === DelayTypeEnum.FIXED_DATE_TIME) {
showText = `延迟<EFBFBD>?{configForm.value.dateTime.replace('T', ' ')}`; showText = `延迟${configForm.value.dateTime.replace('T', ' ')}`;
} }
return showText; return showText;
} }
@@ -196,51 +194,40 @@ defineExpose({ openDrawer }); // 暴露方法给父组件
<ElFormItem <ElFormItem
v-if="configForm.delayType === DelayTypeEnum.FIXED_TIME_DURATION" v-if="configForm.delayType === DelayTypeEnum.FIXED_TIME_DURATION"
> >
<ElRow :gutter="8"> <div class="flex items-center gap-2">
<ElCol> <ElInputNumber
<ElFormItem prop="timeDuration"> v-model="configForm.timeDuration"
<ElInputNumber :min="1"
class="w-28" controls-position="right"
v-model="configForm.timeDuration" class="!w-48"
:min="1" />
/> <ElSelect v-model="configForm.timeUnit" class="w-24">
</ElFormItem> <ElOption
</ElCol> v-for="item in TIME_UNIT_TYPES"
<ElCol> :key="item.value"
<ElSelect v-model="configForm.timeUnit" class="w-28"> :value="item.value"
<ElOption :label="item.label"
v-for="item in TIME_UNIT_TYPES" >
:key="item.value" {{ item.label }}
:value="item.value" </ElOption>
:label="item.label" </ElSelect>
> <span class="whitespace-nowrap">后进入下一节点</span>
{{ item.label }} </div>
</ElOption>
</ElSelect>
</ElCol>
<ElCol>
<span class="inline-flex h-8 items-center">后进入下一节点</span>
</ElCol>
</ElRow>
</ElFormItem> </ElFormItem>
<ElFormItem <ElFormItem
v-if="configForm.delayType === DelayTypeEnum.FIXED_DATE_TIME" v-if="configForm.delayType === DelayTypeEnum.FIXED_DATE_TIME"
prop="dateTime" prop="dateTime"
> >
<ElRow :gutter="8"> <div class="flex items-center gap-2">
<ElCol> <ElDatePicker
<ElDatePicker v-model="configForm.dateTime"
class="mr-2" type="datetime"
v-model="configForm.dateTime" placeholder="请选择日期和时间"
type="datetime" value-format="YYYY-MM-DDTHH:mm:ss"
placeholder="请选择日期和时间" class="flex-1"
value-format="YYYY-MM-DDTHH:mm:ss" />
/> <span class="whitespace-nowrap">后进入下一节点</span>
</ElCol> </div>
<ElCol>
<span class="inline-flex h-8 items-center">后进入下一节点</span>
</ElCol>
</ElRow>
</ElFormItem> </ElFormItem>
</ElForm> </ElForm>
</div> </div>

View File

@@ -135,7 +135,7 @@ defineExpose({ validate });
</script> </script>
<template> <template>
<ElForm ref="formRef" :model="condition" :rules="formRules"> <ElForm ref="formRef" :model="condition" :rules="formRules">
<ElFormItem label="配置方式" name="conditionType"> <ElFormItem label="配置方式" prop="conditionType">
<ElRadioGroup <ElRadioGroup
v-model="condition.conditionType" v-model="condition.conditionType"
@change="changeConditionType" @change="changeConditionType"
@@ -170,6 +170,8 @@ defineExpose({ validate });
size="small" size="small"
:spacer="condition.conditionGroups.and ? '且' : '或'" :spacer="condition.conditionGroups.and ? '且' : '或'"
class="w-full" class="w-full"
fill
:fill-ratio="100"
> >
<ElCard <ElCard
class="group relative w-full hover:border-blue-500" class="group relative w-full hover:border-blue-500"
@@ -212,14 +214,7 @@ defineExpose({ validate });
> >
<ElCol :span="7"> <ElCol :span="7">
<ElFormItem <ElFormItem
:name="[ :prop="`conditionGroups.conditions.${cIdx}.rules.${rIdx}.leftSide`"
'conditionGroups',
'conditions',
cIdx,
'rules',
rIdx,
'leftSide',
]"
:rules="{ :rules="{
required: true, required: true,
message: '左值不能为空', message: '左值不能为空',
@@ -250,7 +245,7 @@ defineExpose({ validate });
</ElSelect> </ElSelect>
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
<ElCol :span="5"> <ElCol :span="6">
<ElFormItem> <ElFormItem>
<ElSelect v-model="rule.opCode" placeholder="请选择操作符"> <ElSelect v-model="rule.opCode" placeholder="请选择操作符">
<ElOption <ElOption
@@ -264,16 +259,9 @@ defineExpose({ validate });
</ElSelect> </ElSelect>
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
<ElCol :span="9"> <ElCol :span="8">
<ElFormItem <ElFormItem
:name="[ :prop="`conditionGroups.conditions.${cIdx}.rules.${rIdx}.rightSide`"
'conditionGroups',
'conditions',
cIdx,
'rules',
rIdx,
'rightSide',
]"
:rules="{ :rules="{
required: true, required: true,
message: '右值不能为空', message: '右值不能为空',
@@ -285,15 +273,15 @@ defineExpose({ validate });
</ElCol> </ElCol>
<ElCol :span="3"> <ElCol :span="3">
<div class="flex items-center"> <div class="flex items-center">
<Trash2
v-if="equation.rules.length > 1"
class="mr-2 size-4 cursor-pointer text-red-500"
@click="deleteConditionRule(equation, rIdx)"
/>
<Plus <Plus
class="size-4 cursor-pointer text-blue-500" class="mr-2 size-4 cursor-pointer text-blue-500"
@click="addConditionRule(equation, rIdx)" @click="addConditionRule(equation, rIdx)"
/> />
<Trash2
v-show="equation.rules.length > 1"
class="size-4 cursor-pointer text-red-500"
@click="deleteConditionRule(equation, rIdx)"
/>
</div> </div>
</ElCol> </ElCol>
</ElRow> </ElRow>
@@ -310,7 +298,7 @@ defineExpose({ validate });
<ElFormItem <ElFormItem
v-if="condition.conditionType === ConditionType.EXPRESSION" v-if="condition.conditionType === ConditionType.EXPRESSION"
label="条件表达式" label="条件表达式"
name="conditionExpression" prop="conditionExpression"
> >
<ElInput <ElInput
v-model="condition.conditionExpression" v-model="condition.conditionExpression"

View File

@@ -63,7 +63,7 @@ function deleteHttpRequestParam(arr: HttpRequestParam[], index: number) {
<!-- 参数名 --> <!-- 参数名 -->
<div class="w-[26%] min-w-32 shrink-0"> <div class="w-[26%] min-w-32 shrink-0">
<ElFormItem <ElFormItem
:name="[bind, 'header', index, 'key']" :prop="`${bind}.header.${index}.key`"
:rules="{ :rules="{
required: true, required: true,
message: '参数名不能为空', message: '参数名不能为空',
@@ -91,7 +91,7 @@ function deleteHttpRequestParam(arr: HttpRequestParam[], index: number) {
<!-- 参数值 --> <!-- 参数值 -->
<div class="w-[42%] flex-1"> <div class="w-[42%] flex-1">
<ElFormItem <ElFormItem
:name="[bind, 'header', index, 'value']" :prop="`${bind}.header.${index}.value`"
:rules="{ :rules="{
required: true, required: true,
message: '参数值不能为空', message: '参数值不能为空',
@@ -102,7 +102,7 @@ function deleteHttpRequestParam(arr: HttpRequestParam[], index: number) {
<ElInput placeholder="请求头" v-model="item.value" /> <ElInput placeholder="请求头" v-model="item.value" />
</ElFormItem> </ElFormItem>
<ElFormItem <ElFormItem
:name="[bind, 'header', index, 'value']" :prop="`${bind}.header.${index}.value`"
:rules="{ :rules="{
required: true, required: true,
message: '参数值不能为空', message: '参数值不能为空',
@@ -121,9 +121,7 @@ function deleteHttpRequestParam(arr: HttpRequestParam[], index: number) {
:label="field.title" :label="field.title"
:value="field.field" :value="field.field"
:disabled="!field.required" :disabled="!field.required"
> />
{{ field.title }}
</ElOption>
</ElSelect> </ElSelect>
</ElFormItem> </ElFormItem>
</div> </div>
@@ -137,17 +135,15 @@ function deleteHttpRequestParam(arr: HttpRequestParam[], index: number) {
/> />
</div> </div>
</div> </div>
<ElButton </ElFormItem>
link <div class="-mt-2.5 mb-2">
@click="addHttpRequestParam(props.header)" <ElButton link @click="addHttpRequestParam(props.header)">
class="flex items-center"
>
<template #icon> <template #icon>
<IconifyIcon class="size-4" icon="lucide:plus" /> <IconifyIcon class="size-4" icon="lucide:plus" />
</template> </template>
添加一行 添加一行
</ElButton> </ElButton>
</ElFormItem> </div>
<ElFormItem label="请求体"> <ElFormItem label="请求体">
<div <div
v-for="(item, index) in props.body" v-for="(item, index) in props.body"
@@ -157,7 +153,7 @@ function deleteHttpRequestParam(arr: HttpRequestParam[], index: number) {
<!-- 参数名 --> <!-- 参数名 -->
<div class="w-[26%] min-w-32 shrink-0"> <div class="w-[26%] min-w-32 shrink-0">
<ElFormItem <ElFormItem
:name="[bind, 'body', index, 'key']" :prop="`${bind}.body.${index}.key`"
:rules="{ :rules="{
required: true, required: true,
message: '参数名不能为空', message: '参数名不能为空',
@@ -185,7 +181,7 @@ function deleteHttpRequestParam(arr: HttpRequestParam[], index: number) {
<!-- 参数值 --> <!-- 参数值 -->
<div class="w-[42%] flex-1"> <div class="w-[42%] flex-1">
<ElFormItem <ElFormItem
:name="[bind, 'body', index, 'value']" :prop="`${bind}.body.${index}.value`"
:rules="{ :rules="{
required: true, required: true,
message: '参数值不能为空', message: '参数值不能为空',
@@ -196,7 +192,7 @@ function deleteHttpRequestParam(arr: HttpRequestParam[], index: number) {
<ElInput placeholder="参数值" v-model="item.value" /> <ElInput placeholder="参数值" v-model="item.value" />
</ElFormItem> </ElFormItem>
<ElFormItem <ElFormItem
:name="[bind, 'body', index, 'value']" :prop="`${bind}.body.${index}.value`"
:rules="{ :rules="{
required: true, required: true,
message: '参数值不能为空', message: '参数值不能为空',
@@ -215,9 +211,7 @@ function deleteHttpRequestParam(arr: HttpRequestParam[], index: number) {
:label="field.title" :label="field.title"
:value="field.field" :value="field.field"
:disabled="!field.required" :disabled="!field.required"
> />
{{ field.title }}
</ElOption>
</ElSelect> </ElSelect>
</ElFormItem> </ElFormItem>
</div> </div>
@@ -231,15 +225,13 @@ function deleteHttpRequestParam(arr: HttpRequestParam[], index: number) {
/> />
</div> </div>
</div> </div>
<ElButton </ElFormItem>
link <div class="-mt-2.5 mb-2">
@click="addHttpRequestParam(props.body)" <ElButton link @click="addHttpRequestParam(props.body)">
class="flex items-center"
>
<template #icon> <template #icon>
<IconifyIcon class="size-4" icon="lucide:plus" /> <IconifyIcon class="size-4" icon="lucide:plus" />
</template> </template>
添加一行 添加一行
</ElButton> </ElButton>
</ElFormItem> </div>
</template> </template>

View File

@@ -67,7 +67,7 @@ function deleteHttpResponseSetting(
<template> <template>
<ElFormItem> <ElFormItem>
<ElAlert <ElAlert
message="仅支持 POST 请求,以请求体方式接收参数" title="仅支持 POST 请求,以请求体方式接收参数"
type="warning" type="warning"
show-icon show-icon
:closable="false" :closable="false"
@@ -76,7 +76,7 @@ function deleteHttpResponseSetting(
<!-- 请求地址--> <!-- 请求地址-->
<ElFormItem <ElFormItem
label="请求地址" label="请求地址"
:name="[formItemPrefix, 'url']" :prop="`${formItemPrefix}.url`"
:rules="{ :rules="{
required: true, required: true,
message: '请求地址不能为空', message: '请求地址不能为空',
@@ -95,58 +95,55 @@ function deleteHttpResponseSetting(
<div v-if="responseEnable"> <div v-if="responseEnable">
<ElFormItem label="返回值"> <ElFormItem label="返回值">
<ElAlert <ElAlert
message="通过请求返回值, 可以修改流程表单的值" title="通过请求返回值, 可以修改流程表单的值"
type="warning" type="warning"
show-icon show-icon
:closable="false" :closable="false"
/> />
</ElFormItem> </ElFormItem>
<ElFormItem> <ElRow
<ElRow :gutter="8"
:gutter="8" v-for="(item, index) in setting.response"
v-for="(item, index) in setting.response" :key="index"
:key="index" class="mb-2"
class="mb-2" align="middle"
> >
<ElCol :span="10"> <ElCol :span="10">
<ElFormItem <ElFormItem
:name="[formItemPrefix, 'response', index, 'key']" class="!mb-0"
:rules="{ :prop="`${formItemPrefix}.response.${index}.key`"
required: true, :rules="{
message: '表单字段不能为空', required: true,
trigger: ['blur', 'change'], message: '表单字段不能为空',
}" trigger: ['blur', 'change'],
> }"
<ElSelect >
v-model="item.key" <ElSelect v-model="item.key" placeholder="请选择表单字段" clearable>
placeholder="请选择表单字段" <ElOption
allow-clear v-for="(field, fIdx) in formFields"
> :key="fIdx"
<ElOption :label="field.title"
v-for="(field, fIdx) in formFields" :value="field.field"
:key="fIdx" :disabled="!field.required"
:label="field.title" />
:value="field.field" </ElSelect>
:disabled="!field.required" </ElFormItem>
> </ElCol>
{{ field.title }} <ElCol :span="12">
</ElOption> <ElFormItem
</ElSelect> class="!mb-0"
</ElFormItem> :prop="`${formItemPrefix}.response.${index}.value`"
</ElCol> :rules="{
<ElCol :span="12"> required: true,
<ElFormItem message: '请求返回字段不能为空',
:name="[formItemPrefix, 'response', index, 'value']" trigger: ['blur', 'change'],
:rules="{ }"
required: true, >
message: '请求返回字段不能为空', <ElInput v-model="item.value" placeholder="请求返回字段" />
trigger: ['blur', 'change'], </ElFormItem>
}" </ElCol>
> <ElCol :span="2">
<ElInput v-model="item.value" placeholder="请求返回字段" /> <ElFormItem class="!mb-0">
</ElFormItem>
</ElCol>
<ElCol :span="2">
<div class="flex h-8 items-center"> <div class="flex h-8 items-center">
<IconifyIcon <IconifyIcon
class="size-4 cursor-pointer text-red-500" class="size-4 cursor-pointer text-red-500"
@@ -154,18 +151,16 @@ function deleteHttpResponseSetting(
@click="deleteHttpResponseSetting(setting.response!, index)" @click="deleteHttpResponseSetting(setting.response!, index)"
/> />
</div> </div>
</ElCol> </ElFormItem>
</ElRow> </ElCol>
<ElButton </ElRow>
link <div>
@click="addHttpResponseSetting(setting.response!)" <ElButton link @click="addHttpResponseSetting(setting.response!)">
class="flex items-center"
>
<template #icon> <template #icon>
<IconifyIcon class="size-4" icon="lucide:plus" /> <IconifyIcon class="size-4" icon="lucide:plus" />
</template> </template>
添加一行 添加一行
</ElButton> </ElButton>
</ElFormItem> </div>
</div> </div>
</template> </template>

View File

@@ -230,13 +230,13 @@ defineExpose({ openDrawer }); // 暴露方法给父组件
v-for="(item, index) in routerGroups" v-for="(item, index) in routerGroups"
:key="index" :key="index"
> >
<template #title> <template #header>
<div class="flex h-16 w-full items-center justify-between"> <div class="flex w-full items-center justify-between py-2">
<div class="flex items-center font-normal"> <div class="flex items-center gap-4">
<span class="font-medium">路由{{ index + 1 }}</span> <span class="font-medium">路由{{ index + 1 }}</span>
<ElFormItem <ElFormItem
class="mb-0 ml-4 inline-block w-48" class="!mb-0 w-64"
:name="['routerGroups', index, 'nodeId']" :prop="`routerGroups.${index}.nodeId`"
:rules="{ :rules="{
required: true, required: true,
message: '路由目标节点不能为空', message: '路由目标节点不能为空',
@@ -251,17 +251,16 @@ defineExpose({ openDrawer }); // 暴露方法给父组件
<ElOption <ElOption
v-for="node in nodeOptions" v-for="node in nodeOptions"
:key="node.value" :key="node.value"
:label="node.label"
:value="node.value" :value="node.value"
> />
{{ node.label }}
</ElOption>
</ElSelect> </ElSelect>
</ElFormItem> </ElFormItem>
</div> </div>
<ElButton <ElButton
v-if="routerGroups.length > 1" v-if="routerGroups.length > 1"
circle circle
class="flex items-center justify-center" size="small"
@click="deleteRouterGroup(index)" @click="deleteRouterGroup(index)"
> >
<template #icon> <template #icon>

View File

@@ -241,7 +241,7 @@ function showConditionText(formSetting: FormTriggerSetting) {
); );
} }
/** 添加修改字段设置<EFBFBD>?*/ /** 添加修改字段设置*/
function addFormFieldSetting(formSetting: FormTriggerSetting) { function addFormFieldSetting(formSetting: FormTriggerSetting) {
if (!formSetting) return; if (!formSetting) return;
if (!formSetting.updateFormFields) { if (!formSetting.updateFormFields) {
@@ -383,10 +383,10 @@ onMounted(() => {
}); });
</script> </script>
<template> <template>
<Drawer class="w-1/3"> <Drawer class="w-2/5">
<template #title> <template #title>
<div class="config-header"> <div class="config-header">
<AInput <ElInput
ref="inputRef" ref="inputRef"
v-if="showInput" v-if="showInput"
type="text" type="text"
@@ -416,12 +416,10 @@ onMounted(() => {
:key="index" :key="index"
:value="item.value" :value="item.value"
:label="item.label" :label="item.label"
> />
{{ item.label }}
</ElOption>
</ElSelect> </ElSelect>
</ElFormItem> </ElFormItem>
<!-- HTTP 请求触发<EFBFBD>?--> <!-- HTTP 请求触发 -->
<div <div
v-if=" v-if="
[ [
@@ -437,20 +435,19 @@ onMounted(() => {
/> />
</div> </div>
<!-- 表单数据修改触发<EFBFBD>?--> <!-- 表单数据修改触发-->
<div v-if="configForm.type === TriggerTypeEnum.FORM_UPDATE"> <div v-if="configForm.type === TriggerTypeEnum.FORM_UPDATE">
<div <div
v-for="(formSetting, index) in configForm.formSettings" v-for="(formSetting, index) in configForm.formSettings"
:key="index" :key="index"
> >
<ElCard class="mt-4"> <ElCard class="mt-4">
<template #title> <template #header>
<div class="flex w-full items-center justify-between"> <div class="flex w-full items-center justify-between">
<span>修改表单设置 {{ index + 1 }}</span> <span>修改表单设置 {{ index + 1 }}</span>
<ElButton <ElButton
v-if="configForm.formSettings!.length > 1" v-if="configForm.formSettings!.length > 1"
shape="circle" circle
class="flex items-center justify-center"
@click="deleteFormSetting(index)" @click="deleteFormSetting(index)"
> >
<template #icon> <template #icon>
@@ -588,20 +585,19 @@ onMounted(() => {
</ElRow> </ElRow>
</div> </div>
<!-- 表单数据删除触发<EFBFBD>?--> <!-- 表单数据删除触发-->
<div v-if="configForm.type === TriggerTypeEnum.FORM_DELETE"> <div v-if="configForm.type === TriggerTypeEnum.FORM_DELETE">
<div <div
v-for="(formSetting, index) in configForm.formSettings" v-for="(formSetting, index) in configForm.formSettings"
:key="index" :key="index"
> >
<ElCard class="mt-4"> <ElCard class="mt-4">
<template #title> <template #header>
<div class="flex w-full items-center justify-between"> <div class="flex w-full items-center justify-between">
<span>删除表单设置 {{ index + 1 }}</span> <span>删除表单设置 {{ index + 1 }}</span>
<ElButton <ElButton
v-if="configForm.formSettings!.length > 1" v-if="configForm.formSettings!.length > 1"
shape="circle" circle
class="flex items-center justify-center"
@click="deleteFormSetting(index)" @click="deleteFormSetting(index)"
> >
<template #icon> <template #icon>