Browse Source

【功能优化】触发器添加条件

jason 6 tháng trước cách đây
mục cha
commit
6be64a219e

+ 8 - 2
src/components/SimpleProcessDesignerV2/src/consts.ts

@@ -735,7 +735,7 @@ export type RouterSetting = {
 export type TriggerSetting = {
   type: TriggerTypeEnum
   httpRequestSetting?: HttpRequestTriggerSetting
-  normalFormSetting?: NormalFormTriggerSetting
+  formSettings?: FormTriggerSetting[]
 }
 
 /**
@@ -769,7 +769,13 @@ export type HttpRequestTriggerSetting = {
 /**
  * 流程表单触发器配置结构定义
  */
-export type NormalFormTriggerSetting = {
+export type FormTriggerSetting = {
+  // 条件类型
+  conditionType?: ConditionType
+  // 条件表达式
+  conditionExpression?: string
+  // 条件组
+  conditionGroups?: ConditionGroup
   // 更新表单字段
   updateFormFields?: Record<string, any>
 }

+ 65 - 2
src/components/SimpleProcessDesignerV2/src/node.ts

@@ -15,7 +15,10 @@ import {
   AssignEmptyHandlerType,
   FieldPermissionType,
   HttpRequestParam,
-  ProcessVariableEnum
+  ProcessVariableEnum,
+  ConditionType,
+  ConditionGroup,
+  COMPARISON_OPERATORS
 } from './consts'
 import { parseFormFields } from '@/components/FormCreate/src/utils'
 
@@ -543,6 +546,66 @@ export function useTaskStatusClass(taskStatus: TaskStatusEnum | undefined): stri
   if (taskStatus === TaskStatusEnum.CANCEL) {
     return 'status-cancel'
   }
-
   return ''
 }
+
+/** 条件组件文字展示 */
+export function getConditionShowText(
+  conditonType: ConditionType | undefined,
+  conditionExpression: string | undefined,
+  conditionGroups: ConditionGroup | undefined,
+  fieldOptions: Array<Record<string, any>>
+) {
+  let showText = ''
+  if (conditonType === ConditionType.EXPRESSION) {
+    if (conditionExpression) {
+      showText = `表达式:${conditionExpression}`
+    }
+  }
+  if (conditonType === ConditionType.RULE) {
+    // 条件组是否为与关系
+    const groupAnd = conditionGroups?.and
+    let warningMesg: undefined | string = undefined
+    const conditionGroup = conditionGroups?.conditions.map((item) => {
+      return (
+        '(' +
+        item.rules
+          .map((rule) => {
+            if (rule.leftSide && rule.rightSide) {
+              return (
+                getFormFieldTitle(fieldOptions, rule.leftSide) +
+                ' ' +
+                getOpName(rule.opCode) +
+                ' ' +
+                rule.rightSide
+              )
+            } else {
+              // 有一条规则不完善。提示错误
+              warningMesg = '请完善条件规则'
+              return ''
+            }
+          })
+          .join(item.and ? ' 且 ' : ' 或 ') +
+        ' ) '
+      )
+    })
+    if (warningMesg) {
+      showText = ''
+    } else {
+      showText = conditionGroup!.join(groupAnd ? ' 且 ' : ' 或 ')
+    }
+  }
+  return showText
+}
+
+/** 获取表单字段名称*/
+const getFormFieldTitle = (fieldOptions: Array<Record<string, any>>, field: string) => {
+  const item = fieldOptions.find((item) => item.field === field)
+  return item?.title
+}
+
+/** 获取操作符名称 */
+const getOpName = (opCode: string): string => {
+  const opName = COMPARISON_OPERATORS.find((item: any) => item.value === opCode)
+  return opName?.label
+}

+ 10 - 62
src/components/SimpleProcessDesignerV2/src/nodes-config/ConditionNodeConfig.vue

@@ -43,13 +43,9 @@
   </el-drawer>
 </template>
 <script setup lang="ts">
-import {
-  SimpleFlowNode,
-  ConditionType,
-  COMPARISON_OPERATORS,
-} from '../consts'
+import { SimpleFlowNode, ConditionType } from '../consts'
 import { getDefaultConditionNodeName } from '../utils'
-import { useFormFieldsAndStartUser } from '../node'
+import { useFormFieldsAndStartUser, getConditionShowText } from '../node'
 import Condition from './components/Condition.vue'
 const message = useMessage() // 消息弹窗
 defineOptions({
@@ -93,8 +89,6 @@ const blurEvent = () => {
     getDefaultConditionNodeName(props.nodeIndex, currentNode.value?.conditionSetting?.defaultFlow)
 }
 
-
-
 defineExpose({ open }) // 提供 open 方法,用于打开弹窗
 
 // 关闭
@@ -110,6 +104,8 @@ const handleClose = async (done: (cancel?: boolean) => void) => {
     done()
   }
 }
+// 流程表单字段和发起人字段
+const fieldOptions = useFormFieldsAndStartUser()
 
 const conditionRef = ref()
 // 保存配置
@@ -118,7 +114,12 @@ const saveConfig = async () => {
     // 校验表单
     const valid = await conditionRef.value.validate()
     if (!valid) return false
-    const showText = getShowText()
+    const showText = getConditionShowText(
+      condition.value?.conditionType,
+      condition.value?.conditionExpression,
+      condition.value.conditionGroups,
+      fieldOptions
+    )
     if (!showText) {
       return false
     }
@@ -136,59 +137,6 @@ const saveConfig = async () => {
   settingVisible.value = false
   return true
 }
-const getShowText = (): string => {
-  let showText = ''
-  if (condition.value?.conditionType === ConditionType.EXPRESSION) {
-    if (condition.value.conditionExpression) {
-      showText = `表达式:${condition.value.conditionExpression}`
-    }
-  }
-  if (condition.value?.conditionType === ConditionType.RULE) {
-    // 条件组是否为与关系
-    const groupAnd = condition.value.conditionGroups?.and
-    let warningMesg: undefined | string = undefined
-    const conditionGroup = condition.value.conditionGroups?.conditions.map((item) => {
-      return (
-        '(' +
-        item.rules
-          .map((rule) => {
-            if (rule.leftSide && rule.rightSide) {
-              return (
-                getFieldTitle(rule.leftSide) + ' ' + getOpName(rule.opCode) + ' ' + rule.rightSide
-              )
-            } else {
-              // 有一条规则不完善。提示错误
-              warningMesg = '请完善条件规则'
-              return ''
-            }
-          })
-          .join(item.and ? ' 且 ' : ' 或 ') +
-        ' ) '
-      )
-    })
-    if (warningMesg) {
-      message.warning(warningMesg)
-      showText = ''
-    } else {
-      showText = conditionGroup!.join(groupAnd ? ' 且 ' : ' 或 ')
-    }
-  }
-  return showText
-}
-// 流程表单字段和发起人字段
-const fieldOptions = useFormFieldsAndStartUser()
-
-/** 获取字段名称 */
-const getFieldTitle = (field: string) => {
-  const item = fieldOptions.find((item) => item.field === field)
-  return item?.title
-}
-
-/** 获取操作符名称 */
-const getOpName = (opCode: string): string => {
-  const opName = COMPARISON_OPERATORS.find((item: any) => item.value === opCode)
-  return opName?.label
-}
 </script>
 
 <style lang="scss" scoped>

+ 206 - 83
src/components/SimpleProcessDesignerV2/src/nodes-config/TriggerNodeConfig.vue

@@ -3,7 +3,7 @@
     :append-to-body="true"
     v-model="settingVisible"
     :show-close="false"
-    :size="550"
+    :size="630"
     :before-close="saveConfig"
   >
     <template #header>
@@ -121,62 +121,114 @@
             </el-button>
           </el-form-item>
         </div>
-        <div
-          v-if="
-            configForm.type === TriggerTypeEnum.UPDATE_NORMAL_FORM && configForm.normalFormSetting
-          "
-        >
-          <el-divider content-position="left">修改表单设置</el-divider>
-          <div
-            class="flex items-center"
-            v-for="key in Object.keys(configForm.normalFormSetting.updateFormFields!)"
-            :key="key"
-          >
-            <div class="mr-2 flex items-center">
-              <el-form-item>
-                <el-select
-                  class="w-160px!"
-                  :model-value="key"
-                  @update:model-value="(newKey) => updateFormFieldKey(key, newKey)"
-                  placeholder="请选择表单字段"
-                  :disabled="key !== ''"
+        <!-- 表单数据修改触发器 -->
+        <div v-if="configForm.type === TriggerTypeEnum.UPDATE_NORMAL_FORM">
+          <div v-for="(formSetting, index) in configForm.formSettings" :key="index">
+            <el-card class="w-580px mt-4">
+              <template #header>
+                <div class="flex items-center justify-between">
+                  <div>修改表单设置 {{ index + 1 }}</div>
+                  <el-button
+                    type="primary"
+                    plain
+                    circle
+                    v-if="configForm.formSettings!.length > 1"
+                    @click="deleteFormSetting(index)"
+                  >
+                    <Icon icon="ep:close" />
+                  </el-button>
+                </div>
+              </template>
+
+              <!-- 条件设置 -->
+              <ConditionDialog
+                :ref="`condition-${index}`"
+                @update-condition="(val) => handleConditionUpdate(index, val)"
+              />
+              <div class="cursor-pointer" v-if="formSetting.conditionType">
+                <el-tag
+                  type="success"
+                  effect="light"
+                  closable
+                  @close="deleteFormUpdateCondition(formSetting)"
+                  @click="openFormUpdateCondition(index, formSetting)"
                 >
-                  <el-option
-                    v-for="(field, fIdx) in optionalUpdateFormFields"
-                    :key="fIdx"
-                    :label="field.title"
-                    :value="field.field"
-                    :disabled="field.disabled"
-                  />
-                </el-select>
-              </el-form-item>
-            </div>
-            <div class="mx-2"><el-form-item>的值设置为</el-form-item></div>
-            <div class="mr-2">
-              <el-form-item
-                :prop="`normalFormSetting.updateFormFields.${key}`"
-                :rules="{
-                  required: true,
-                  message: '值不能为空',
-                  trigger: 'blur'
-                }"
+                  {{ showConditionText(formSetting) }}
+                </el-tag>
+              </div>
+              <el-button
+                v-else
+                type="primary"
+                text
+                @click="addFormUpdateCondition(index, formSetting)"
               >
-                <el-input
-                  class="w-160px"
-                  v-model="configForm.normalFormSetting.updateFormFields![key]"
-                  placeholder="请输入"
-                  :disabled="!key"
-                />
-              </el-form-item>
-            </div>
-            <div class="mr-1 pt-1 cursor-pointer">
-              <el-form-item>
-                <Icon icon="ep:delete" :size="18" @click="deleteFormFieldSetting(key)" />
-              </el-form-item>
-            </div>
+                <Icon icon="ep:link" class="mr-5px" />添加条件
+              </el-button>
+              <el-divider content-position="left">修改表单字段设置</el-divider>
+              <!-- 表单字段修改设置 -->
+              <div
+                class="flex items-center"
+                v-for="key in Object.keys(formSetting.updateFormFields || {})"
+                :key="key"
+              >
+                <div class="mr-2 flex items-center">
+                  <el-form-item>
+                    <el-select
+                      class="w-160px!"
+                      :model-value="key"
+                      @update:model-value="(newKey) => updateFormFieldKey(formSetting, key, newKey)"
+                      placeholder="请选择表单字段"
+                      :disabled="key !== ''"
+                    >
+                      <el-option
+                        v-for="(field, fIdx) in optionalUpdateFormFields"
+                        :key="fIdx"
+                        :label="field.title"
+                        :value="field.field"
+                        :disabled="field.disabled"
+                      />
+                    </el-select>
+                  </el-form-item>
+                </div>
+                <div class="mx-2"><el-form-item>的值设置为</el-form-item></div>
+                <div class="mr-2">
+                  <el-form-item
+                    :prop="`formSettings.${index}.updateFormFields.${key}`"
+                    :rules="{
+                      required: true,
+                      message: '值不能为空',
+                      trigger: 'blur'
+                    }"
+                  >
+                    <el-input
+                      class="w-160px"
+                      v-model="formSetting.updateFormFields![key]"
+                      placeholder="请输入"
+                      :disabled="!key"
+                    />
+                  </el-form-item>
+                </div>
+                <div class="mr-1 pt-1 cursor-pointer">
+                  <el-form-item>
+                    <Icon
+                      icon="ep:delete"
+                      :size="18"
+                      @click="deleteFormFieldSetting(formSetting, key)"
+                    />
+                  </el-form-item>
+                </div>
+              </div>
+
+              <!-- 添加表单字段按钮 -->
+              <el-button type="primary" text @click="addFormFieldSetting(formSetting)">
+                <Icon icon="ep:memo" class="mr-5px" />添加修改字段
+              </el-button>
+            </el-card>
           </div>
-          <el-button type="primary" text @click="addFormFieldSetting()">
-            <Icon icon="ep:plus" class="mr-5px" />添加修改字段
+
+          <!-- 添加新的设置 -->
+          <el-button class="mt-6" type="primary" text @click="addFormSetting">
+            <Icon icon="ep:setting" class="mr-5px" />添加设置
           </el-button>
         </div>
       </el-form>
@@ -191,10 +243,26 @@
   </el-drawer>
 </template>
 <script setup lang="ts">
-import { SimpleFlowNode, NodeType, TriggerSetting, TRIGGER_TYPES, TriggerTypeEnum } from '../consts'
-import { useWatchNode, useDrawer, useNodeName, useFormFields } from '../node'
+import {
+  SimpleFlowNode,
+  NodeType,
+  TriggerSetting,
+  TRIGGER_TYPES,
+  TriggerTypeEnum,
+  FormTriggerSetting,
+  DEFAULT_CONDITION_GROUP_VALUE
+} from '../consts'
+import {
+  useWatchNode,
+  useDrawer,
+  useNodeName,
+  useFormFields,
+  useFormFieldsAndStartUser,
+  getConditionShowText
+} from '../node'
 import HttpRequestParamSetting from './components/HttpRequestParamSetting.vue'
-
+import ConditionDialog from './components/ConditionDialog.vue'
+const { proxy } = getCurrentInstance() as any
 defineOptions({
   name: 'TriggerNodeConfig'
 })
@@ -227,28 +295,25 @@ const configForm = ref<TriggerSetting>({
     body: [],
     response: []
   },
-  normalFormSetting: { updateFormFields: {} }
+  formSettings: [
+    {
+      conditionGroups: DEFAULT_CONDITION_GROUP_VALUE,
+      updateFormFields: {}
+    }
+  ]
 })
 // 流程表单字段
 const formFields = useFormFields()
 
 // 可选的修改的表单字段
 const optionalUpdateFormFields = computed(() => {
-  const usedFields = Object.keys(configForm.value.normalFormSetting?.updateFormFields || {})
   return formFields.map((field) => ({
     title: field.title,
     field: field.field,
-    disabled: usedFields.includes(field.field)
+    disabled: false
   }))
 })
 
-const updateFormFieldKey = (oldKey: string, newKey: string) => {
-  if (!configForm.value.normalFormSetting?.updateFormFields) return
-  const value = configForm.value.normalFormSetting.updateFormFields[oldKey]
-  delete configForm.value.normalFormSetting.updateFormFields[oldKey]
-  configForm.value.normalFormSetting.updateFormFields[newKey] = value
-}
-
 /** 添加 HTTP 请求返回值设置项*/
 const addHttpResponseSetting = (responseSetting: Record<string, string>[]) => {
   responseSetting.push({
@@ -262,17 +327,69 @@ const deleteHttpResponseSetting = (responseSetting: Record<string, string>[], in
   responseSetting.splice(index, 1)
 }
 
-/** 添加修改表单设置项 */
-const addFormFieldSetting = () => {
-  if (configForm.value.normalFormSetting!.updateFormFields === undefined) {
-    configForm.value.normalFormSetting!.updateFormFields = {}
+/** 添加新的修改表单设置 */
+const addFormSetting = () => {
+  configForm.value.formSettings!.push({
+    conditionGroups: DEFAULT_CONDITION_GROUP_VALUE,
+    updateFormFields: {}
+  })
+}
+
+/** 删除修改表单设置 */
+const deleteFormSetting = (index: number) => {
+  configForm.value.formSettings!.splice(index, 1)
+}
+
+/** 添加条件配置 */
+const addFormUpdateCondition = (index: number, formSetting: FormTriggerSetting) => {
+  const conditionDialog = proxy.$refs[`condition-${index}`][0]
+  conditionDialog.open(formSetting)
+}
+/** 删除条件配置 */
+const deleteFormUpdateCondition = (formSetting: FormTriggerSetting) => {
+  formSetting.conditionType = undefined
+}
+/** 打开条件配置弹窗 */
+const openFormUpdateCondition = (index: number, formSetting: FormTriggerSetting) => {
+  const conditionDialog = proxy.$refs[`condition-${index}`][0]
+  conditionDialog.open(formSetting)
+}
+/** 处理条件配置保存 */
+const handleConditionUpdate = (index: number, condition: any) => {
+  configForm.value.formSettings![index].conditionType = condition.conditionType
+  configForm.value.formSettings![index].conditionExpression = condition.conditionExpression
+  configForm.value.formSettings![index].conditionGroups = condition.conditionGroups
+}
+/** 条件配置展示 */
+const showConditionText = (formSetting: FormTriggerSetting) => {
+  return getConditionShowText(
+    formSetting.conditionType,
+    formSetting.conditionExpression,
+    formSetting.conditionGroups,
+    formFields
+  )
+}
+
+/** 添加修改字段设置项 */
+const addFormFieldSetting = (formSetting: FormTriggerSetting) => {
+  if (!formSetting) return
+  if (!formSetting.updateFormFields) {
+    formSetting.updateFormFields = {}
   }
-  configForm.value.normalFormSetting!.updateFormFields[''] = undefined
+  formSetting.updateFormFields[''] = undefined
+}
+/** 更新字段 KEY */
+const updateFormFieldKey = (formSetting: FormTriggerSetting, oldKey: string, newKey: string) => {
+  if (!formSetting?.updateFormFields) return
+  const value = formSetting.updateFormFields[oldKey]
+  delete formSetting.updateFormFields[oldKey]
+  formSetting.updateFormFields[newKey] = value
 }
-/** 删除修改表单设置项 */
-const deleteFormFieldSetting = (key: string) => {
-  if (!configForm.value.normalFormSetting?.updateFormFields) return
-  delete configForm.value.normalFormSetting.updateFormFields[key]
+
+/** 删除修改字段设置项 */
+const deleteFormFieldSetting = (formSetting: FormTriggerSetting, key: string) => {
+  if (!formSetting?.updateFormFields) return
+  delete formSetting.updateFormFields[key]
 }
 
 /** 保存配置 */
@@ -285,7 +402,7 @@ const saveConfig = async () => {
   currentNode.value.name = nodeName.value!
   currentNode.value.showText = showText
   if (configForm.value.type === TriggerTypeEnum.HTTP_REQUEST) {
-    configForm.value.normalFormSetting = undefined
+    configForm.value.formSettings = undefined
   }
   if (configForm.value.type === TriggerTypeEnum.UPDATE_NORMAL_FORM) {
     configForm.value.httpRequestSetting = undefined
@@ -301,12 +418,13 @@ const getShowText = (): string => {
   if (configForm.value.type === TriggerTypeEnum.HTTP_REQUEST) {
     showText = `${configForm.value.httpRequestSetting?.url}`
   } else if (configForm.value.type === TriggerTypeEnum.UPDATE_NORMAL_FORM) {
-    const updatefields = Object.keys(configForm.value.normalFormSetting?.updateFormFields || {})
-    if (updatefields.length === 0) {
-      message.warning('请设置修改表单字段')
-    } else {
-      showText = '修改表单数据'
+    for (const [index, setting] of configForm.value.formSettings!.entries()) {
+      if (!setting.updateFormFields || Object.keys(setting.updateFormFields).length === 0) {
+        message.warning(`请添加表单设置${index + 1}的修改字段`)
+        return ''
+      }
     }
+    showText = '修改表单数据'
   }
   return showText
 }
@@ -323,7 +441,12 @@ const showTriggerNodeConfig = (node: SimpleFlowNode) => {
         body: [],
         response: []
       },
-      normalFormSetting: node.triggerSetting.normalFormSetting || { updateFormFields: {} }
+      formSettings: node.triggerSetting.formSettings || [
+        {
+          conditionGroups: DEFAULT_CONDITION_GROUP_VALUE,
+          updateFormFields: {}
+        }
+      ]
     }
   }
 }

+ 303 - 0
src/components/SimpleProcessDesignerV2/src/nodes-config/components/ConditionDialog.vue

@@ -0,0 +1,303 @@
+<template>
+  <Dialog v-model="dialogVisible" title="条件配置" width="600px" :fullscreen="false">
+    <div class="h-410px">
+      <el-scrollbar wrap-class="h-full">
+        <el-form ref="formRef" :model="condition" :rules="formRules" label-position="top">
+          <el-form-item label="配置方式" prop="conditionType">
+            <el-radio-group v-model="condition.conditionType" @change="changeConditionType">
+              <el-radio
+                v-for="(dict, indexConditionType) in conditionConfigTypes"
+                :key="indexConditionType"
+                :value="dict.value"
+                :label="dict.value"
+              >
+                {{ dict.label }}
+              </el-radio>
+            </el-radio-group>
+          </el-form-item>
+          <el-form-item
+            v-if="condition.conditionType === ConditionType.RULE && condition.conditionGroups"
+            label="条件规则"
+          >
+            <div class="condition-group-tool">
+              <div class="flex items-center">
+                <div class="mr-4">条件组关系</div>
+                <el-switch
+                  v-model="condition.conditionGroups.and"
+                  inline-prompt
+                  active-text="且"
+                  inactive-text="或"
+                />
+              </div>
+            </div>
+            <el-space direction="vertical" :spacer="condition.conditionGroups.and ? '且' : '或'">
+              <el-card
+                class="condition-group"
+                style="width: 530px"
+                v-for="(equation, cIdx) in condition.conditionGroups.conditions"
+                :key="cIdx"
+              >
+                <div
+                  class="condition-group-delete"
+                  v-if="condition.conditionGroups.conditions.length > 1"
+                >
+                  <Icon
+                    color="#0089ff"
+                    icon="ep:circle-close-filled"
+                    :size="18"
+                    @click="deleteConditionGroup(condition.conditionGroups.conditions, cIdx)"
+                  />
+                </div>
+                <template #header>
+                  <div class="flex items-center justify-between">
+                    <div>条件组</div>
+                    <div class="flex">
+                      <div class="mr-4">规则关系</div>
+                      <el-switch
+                        v-model="equation.and"
+                        inline-prompt
+                        active-text="且"
+                        inactive-text="或"
+                      />
+                    </div>
+                  </div>
+                </template>
+
+                <div class="flex pt-2" v-for="(rule, rIdx) in equation.rules" :key="rIdx">
+                  <div class="mr-2">
+                    <el-form-item
+                      :prop="`conditionGroups.conditions.${cIdx}.rules.${rIdx}.leftSide`"
+                      :rules="{
+                        required: true,
+                        message: '左值不能为空',
+                        trigger: 'change'
+                      }"
+                    >
+                      <el-select style="width: 160px" v-model="rule.leftSide">
+                        <el-option
+                          v-for="(field, fIdx) in fieldOptions"
+                          :key="fIdx"
+                          :label="field.title"
+                          :value="field.field"
+                          :disabled="!field.required"
+                        />
+                      </el-select>
+                    </el-form-item>
+                  </div>
+                  <div class="mr-2">
+                    <el-select v-model="rule.opCode" style="width: 100px">
+                      <el-option
+                        v-for="operator in COMPARISON_OPERATORS"
+                        :key="operator.value"
+                        :label="operator.label"
+                        :value="operator.value"
+                      />
+                    </el-select>
+                  </div>
+                  <div class="mr-2">
+                    <el-form-item
+                      :prop="`conditionGroups.conditions.${cIdx}.rules.${rIdx}.rightSide`"
+                      :rules="{
+                        required: true,
+                        message: '右值不能为空',
+                        trigger: 'blur'
+                      }"
+                    >
+                      <el-input v-model="rule.rightSide" style="width: 160px" />
+                    </el-form-item>
+                  </div>
+                  <div class="cursor-pointer mr-1 flex items-center" v-if="equation.rules.length > 1">
+                    <Icon
+                      icon="ep:delete"
+                      :size="18"
+                      @click="deleteConditionRule(equation, rIdx)"
+                    />
+                  </div>
+                  <div class="cursor-pointer flex items-center">
+                    <Icon icon="ep:plus" :size="18" @click="addConditionRule(equation, rIdx)" />
+                  </div>
+                </div>
+              </el-card>
+            </el-space>
+            <div title="添加条件组" class="mt-4 cursor-pointer">
+              <Icon
+                color="#0089ff"
+                icon="ep:plus"
+                :size="24"
+                @click="addConditionGroup(condition.conditionGroups?.conditions)"
+              />
+            </div>
+          </el-form-item>
+          <el-form-item
+            v-if="condition.conditionType === ConditionType.EXPRESSION"
+            label="条件表达式"
+            prop="conditionExpression"
+          >
+            <el-input
+              type="textarea"
+              v-model="condition.conditionExpression"
+              clearable
+              style="width: 100%"
+            />
+          </el-form-item>
+        </el-form>
+      </el-scrollbar>
+    </div>
+    <template #footer>
+      <el-button type="primary" @click="submitForm">确 定</el-button>
+      <el-button @click="dialogVisible = false">取 消</el-button>
+    </template>
+  </Dialog>
+</template>
+
+<script setup lang="ts">
+import {
+  COMPARISON_OPERATORS,
+  CONDITION_CONFIG_TYPES,
+  ConditionType,
+  ConditionGroup,
+  DEFAULT_CONDITION_GROUP_VALUE
+} from '../../consts'
+import { BpmModelFormType } from '@/utils/constants'
+import { useFormFieldsAndStartUser } from '../../node'
+defineOptions({
+  name: 'ConditionDialog'
+})
+
+const condition = ref<{
+  conditionType: ConditionType
+  conditionExpression?: string
+  conditionGroups?: ConditionGroup
+}>({
+  conditionType: ConditionType.RULE,
+  conditionGroups: DEFAULT_CONDITION_GROUP_VALUE
+})
+
+const emit = defineEmits<{
+  updateCondition: [condition: object]
+}>()
+const message = useMessage() // 消息弹窗
+const dialogVisible = ref(false) // 弹窗的是否展示
+
+const formType = inject<Ref<number>>('formType') // 表单类型
+const conditionConfigTypes = computed(() => {
+  return CONDITION_CONFIG_TYPES.filter((item) => {
+    // 业务表单暂时去掉条件规则选项
+    if (formType?.value === BpmModelFormType.CUSTOM && item.value === ConditionType.RULE) {
+      return false
+    } else {
+      return true
+    }
+  })
+})
+
+/** 条件规则可选择的表单字段 */
+const fieldOptions = useFormFieldsAndStartUser()
+
+// 表单校验规则
+const formRules = reactive({
+  conditionType: [{ required: true, message: '配置方式不能为空', trigger: 'blur' }],
+  conditionExpression: [{ required: true, message: '条件表达式不能为空', trigger: 'blur' }]
+})
+const formRef = ref() // 表单 Ref
+
+/** 切换条件配置方式 */
+const changeConditionType = () => {
+  if (condition.value.conditionType === ConditionType.RULE) {
+    if (!condition.value.conditionGroups) {
+      condition.value.conditionGroups = DEFAULT_CONDITION_GROUP_VALUE
+    }
+  }
+}
+const deleteConditionGroup = (conditions, index) => {
+  conditions.splice(index, 1)
+}
+
+const deleteConditionRule = (condition, index) => {
+  condition.rules.splice(index, 1)
+}
+
+const addConditionRule = (condition, index) => {
+  const rule = {
+    opCode: '==',
+    leftSide: '',
+    rightSide: ''
+  }
+  condition.rules.splice(index + 1, 0, rule)
+}
+
+const addConditionGroup = (conditions) => {
+  const condition = {
+    and: true,
+    rules: [
+      {
+        opCode: '==',
+        leftSide: '',
+        rightSide: ''
+      }
+    ]
+  }
+  conditions.push(condition)
+}
+
+/** 保存条件设置 */
+const submitForm = async () => {
+  // 校验表单
+  if (!formRef) return
+  const valid = await formRef.value.validate()
+  if (!valid) {
+    message.warning('请完善条件规则')
+    return
+  }
+  dialogVisible.value = false
+  // 设置完的条件传递给父组件
+  emit('updateCondition', condition.value)
+}
+
+const open = (conditionObj: any | undefined) => {
+  if (conditionObj) {
+    condition.value.conditionType = conditionObj.conditionType
+    condition.value.conditionExpression = conditionObj.conditionExpression
+    condition.value.conditionGroups = conditionObj.conditionGroups
+  }
+  dialogVisible.value = true
+}
+
+defineExpose({ open })
+</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>