浏览代码

perf: bpm 流程模型表单代码优化. 去掉大量watch 代码. 用依赖注入替换props 传递流程数据. 增加导入导出

zws 7 月之前
父节点
当前提交
3d8f1290c3

+ 9 - 109
src/components/SimpleProcessDesignerV2/src/SimpleProcessDesigner.vue

@@ -40,7 +40,7 @@ defineOptions({
   name: 'SimpleProcessDesigner'
 })
 
-const emits = defineEmits(['success', 'init-finished']) // 保存成功事件
+const emits = defineEmits(['success']) // 保存成功事件
 
 const props = defineProps({
   modelId: {
@@ -59,13 +59,12 @@ const props = defineProps({
   startUserIds : {
     type: Array,
     required: false
-  },
-  value: {
-    type: [String, Object],
-    required: false
   }
 })
 
+const processData = inject('processData') as Ref
+
+
 const loading = ref(false)
 const formFields = ref<string[]>([])
 const formType = ref(20)
@@ -76,9 +75,6 @@ const deptOptions = ref<DeptApi.DeptVO[]>([]) // 部门列表
 const deptTreeOptions = ref()
 const userGroupOptions = ref<UserGroupApi.UserGroupVO[]>([]) // 用户组列表
 
-// 添加当前值的引用
-const currentValue = ref<SimpleFlowNode | undefined>()
-
 provide('formFields', formFields)
 provide('formType', formType)
 provide('roleList', roleOptions)
@@ -88,7 +84,8 @@ provide('deptList', deptOptions)
 provide('userGroupList', userGroupOptions)
 provide('deptTree', deptTreeOptions)
 provide('startUserIds', props.startUserIds)
-
+provide('tasks', [])
+provide('processInstance', {})
 const message = useMessage() // 国际化
 const processNodeTree = ref<SimpleFlowNode | undefined>()
 const errorDialogVisible = ref(false)
@@ -112,70 +109,14 @@ const updateModel = () => {
   }
 }
 
-// 加载流程数据
-const loadProcessData = async (data: any) => {
-  try {
-    if (data) {
-      const parsedData = typeof data === 'string' ? JSON.parse(data) : data
-      processNodeTree.value = parsedData
-      currentValue.value = parsedData
-      // 确保数据加载后刷新视图
-      await nextTick()
-      if (simpleProcessModelRef.value?.refresh) {
-        await simpleProcessModelRef.value.refresh()
-      }
-    }
-  } catch (error) {
-    console.error('加载流程数据失败:', error)
-  }
-}
-
-// 监听属性变化
-watch(
-  () => props.value,
-  async (newValue, oldValue) => {
-    if (newValue && newValue !== oldValue) {
-      await loadProcessData(newValue)
-    }
-  },
-  { immediate: true, deep: true }
-)
-
-// 监听流程节点树变化,自动保存
-watch(
-  () => processNodeTree.value,
-  async (newValue, oldValue) => {
-    if (newValue && oldValue && JSON.stringify(newValue) !== JSON.stringify(oldValue)) {
-      await saveSimpleFlowModel(newValue)
-    }
-  },
-  { deep: true }
-)
 
 const saveSimpleFlowModel = async (simpleModelNode: SimpleFlowNode) => {
   if (!simpleModelNode) {
     return
   }
 
-  // 校验节点
-  errorNodes = []
-  validateNode(simpleModelNode, errorNodes)
-  if (errorNodes.length > 0) {
-    errorDialogVisible.value = true
-    return
-  }
-
   try {
-    if (props.modelId) {
-      // 编辑模式
-      const data = {
-        id: props.modelId,
-        simpleModel: simpleModelNode
-      }
-      await updateBpmSimpleModel(data)
-    }
-    // 无论是编辑还是新建模式,都更新当前值并触发事件
-    currentValue.value = simpleModelNode
+    processData.value = simpleModelNode
     emits('success', simpleModelNode)
   } catch (error) {
     console.error('保存失败:', error)
@@ -246,61 +187,20 @@ onMounted(async () => {
     deptTreeOptions.value = handleTree(deptOptions.value as DeptApi.DeptVO[], 'id')
     // 获取用户组列表
     userGroupOptions.value = await UserGroupApi.getUserGroupSimpleList()
-
     // 加载流程数据
-    if (props.modelId) {
-      // 获取 SIMPLE 设计器模型
-      const result = await getBpmSimpleModel(props.modelId)
-      if (result) {
-        await loadProcessData(result)
-      } else {
-        updateModel()
-      }
-    } else if (props.value) {
-      await loadProcessData(props.value)
+    if (processData.value) {
+      processNodeTree.value = processData?.value
     } else {
       updateModel()
     }
   } finally {
     loading.value = false
-    emits('init-finished')
   }
 })
 
 const simpleProcessModelRef = ref()
 
-/** 获取当前流程数据 */
-const getCurrentFlowData = async () => {
-  try {
-    if (simpleProcessModelRef.value) {
-      const data = await simpleProcessModelRef.value.getCurrentFlowData()
-      if (data) {
-        currentValue.value = data
-        return data
-      }
-    }
-    return currentValue.value
-  } catch (error) {
-    console.error('获取流程数据失败:', error)
-    return currentValue.value
-  }
-}
-
-// 刷新方法
-const refresh = async () => {
-  try {
-    if (currentValue.value) {
-      await loadProcessData(currentValue.value)
-    }
-  } catch (error) {
-    console.error('刷新失败:', error)
-  }
-}
 
 defineExpose({
-  getCurrentFlowData,
-  updateModel,
-  loadProcessData,
-  refresh
 })
 </script>

+ 62 - 1
src/components/SimpleProcessDesignerV2/src/SimpleProcessModel.vue

@@ -3,11 +3,31 @@
     <div class="position-absolute top-0px right-0px bg-#fff">
       <el-row type="flex" justify="end">
         <el-button-group key="scale-control" size="default">
+          <el-button size="default" @click="exportJson()"><Icon icon="ep:download" />导出</el-button>
+          <el-button size="default" @click="importJson()"><Icon icon="ep:upload" />导入</el-button>
+          <!-- 用于打开本地文件-->
+          <input
+            type="file"
+            id="files"
+            ref="refFile"
+            style="display: none"
+            accept=".json"
+            @change="importLocalFile"
+          />
           <el-button size="default" :icon="ScaleToOriginal" @click="processReZoom()" />
           <el-button size="default" :plain="true" :icon="ZoomOut" @click="zoomOut()" />
           <el-button size="default" class="w-80px"> {{ scaleValue }}% </el-button>
           <el-button size="default" :plain="true" :icon="ZoomIn" @click="zoomIn()" />
         </el-button-group>
+<!--        <el-button-->
+<!--          v-if="!readonly"-->
+<!--          size="default"-->
+<!--          class="ml-4px"-->
+<!--          type="primary"-->
+<!--          :icon="Select"-->
+<!--          @click="saveSimpleFlowModel"-->
+<!--          >保存模型</el-button-->
+<!--        >-->
       </el-row>
     </div>
     <div class="simple-process-model" :style="`transform: scale(${scaleValue / 100});`">
@@ -33,7 +53,8 @@
 import ProcessNodeTree from './ProcessNodeTree.vue'
 import { SimpleFlowNode, NodeType, NODE_DEFAULT_TEXT } from './consts'
 import { useWatchNode } from './node'
-import { ZoomOut, ZoomIn, ScaleToOriginal } from '@element-plus/icons-vue'
+import { ZoomOut, ZoomIn, ScaleToOriginal, Select } from '@element-plus/icons-vue'
+import { isString } from '@/utils/is'
 
 defineOptions({
   name: 'SimpleProcessModel'
@@ -85,6 +106,16 @@ const processReZoom = () => {
 const errorDialogVisible = ref(false)
 let errorNodes: SimpleFlowNode[] = []
 
+const saveSimpleFlowModel = async () => {
+  errorNodes = []
+  validateNode(processNodeTree.value, errorNodes)
+  if (errorNodes.length > 0) {
+    errorDialogVisible.value = true
+    return
+  }
+  emits('save', processNodeTree.value)
+}
+
 // 校验节点设置。 暂时以 showText 为空 未节点错误配置
 const validateNode = (node: SimpleFlowNode | undefined, errorNodes: SimpleFlowNode[]) => {
   if (node) {
@@ -143,6 +174,36 @@ const getCurrentFlowData = async () => {
 defineExpose({
   getCurrentFlowData
 })
+
+const exportJson = () => {
+  const blob = new Blob([JSON.stringify(processNodeTree.value)]);
+  const tempLink = document.createElement('a'); // 创建a标签
+  const href = window.URL.createObjectURL(blob); // 创建下载的链接
+  //filename
+  const fileName = `model.json`;
+  tempLink.href = href;
+  tempLink.target = '_blank';
+  tempLink.download = fileName;
+  document.body.appendChild(tempLink);
+  tempLink.click(); // 点击下载
+  document.body.removeChild(tempLink); // 下载完成移除元素
+  window.URL.revokeObjectURL(href); // 释放掉blob对象
+}
+const importJson = () => {
+  refFile.value.click()
+}
+const refFile = ref()
+// 加载本地文件
+const importLocalFile = () => {
+  const file = refFile.value.files[0]
+  const reader = new FileReader()
+  reader.readAsText(file)
+  reader.onload = function () {
+    if (isString(this.result)) {
+      processNodeTree.value = JSON.parse(this.result)
+    }
+  }
+}
 </script>
 
 <style lang="scss" scoped></style>

+ 1 - 22
src/components/bpmnProcessDesigner/package/designer/ProcessDesigner.vue

@@ -308,28 +308,6 @@ const props = defineProps({
   }
 })
 
-// 监听value变化,重新加载流程图
-watch(
-  () => props.value,
-  (newValue) => {
-    if (newValue && bpmnModeler) {
-      createNewDiagram(newValue)
-    }
-  },
-  { immediate: true }
-)
-
-// 监听processId和processName变化
-watch(
-  [() => props.processId, () => props.processName],
-  ([newId, newName]) => {
-    if (newId && newName && !props.value) {
-      createNewDiagram(null)
-    }
-  },
-  { immediate: true }
-)
-
 provide('configGlobal', props)
 let bpmnModeler: any = null
 const defaultZoom = ref(1)
@@ -480,6 +458,7 @@ const initModelListeners = () => {
       emit('commandStack-changed', event)
       emit('input', xml)
       emit('change', xml)
+      emit('save', xml)
     } catch (e: any) {
       console.error(`[Process Designer Warn]: ${e.message || e}`)
     }

+ 9 - 181
src/views/bpm/model/editor/index.vue

@@ -3,6 +3,7 @@
     <!-- 流程设计器,负责绘制流程等 -->
     <MyProcessDesigner
       key="designer"
+      v-if="xmlString != undefined"
       v-model="xmlString"
       :value="xmlString"
       v-bind="controlForm"
@@ -15,7 +16,7 @@
     />
     <!-- 流程属性器,负责编辑每个流程节点的属性 -->
     <MyProcessPenal
-      v-if="isModelerReady && modeler"
+      v-if="modeler"
       key="penal"
       :bpmnModeler="modeler"
       :prefix="controlForm.prefix"
@@ -37,8 +38,8 @@ defineOptions({ name: 'BpmModelEditor' })
 
 const props = defineProps<{
   modelId?: string
-  modelKey?: string
-  modelName?: string
+  modelKey: string
+  modelName: string
   value?: string
 }>()
 
@@ -51,10 +52,11 @@ const formType = ref(20)
 provide('formFields', formFields)
 provide('formType', formType)
 
-const xmlString = ref<string>('') // BPMN XML
+//注入 流程数据
+const xmlString = inject('processData') as Ref
+
 const modeler = shallowRef() // BPMN Modeler
 const processDesigner = ref()
-const isModelerReady = ref(false)
 const controlForm = ref({
   simulation: true,
   labelEditing: false,
@@ -65,154 +67,27 @@ const controlForm = ref({
 })
 const model = ref<ModelApi.ModelVO>() // 流程模型的信息
 
-// 初始化 bpmnInstances
-const initBpmnInstances = () => {
-  if (!modeler.value) return false
-  try {
-    const instances = {
-      modeler: modeler.value,
-      modeling: modeler.value.get('modeling'),
-      moddle: modeler.value.get('moddle'),
-      eventBus: modeler.value.get('eventBus'),
-      bpmnFactory: modeler.value.get('bpmnFactory'),
-      elementFactory: modeler.value.get('elementFactory'),
-      elementRegistry: modeler.value.get('elementRegistry'),
-      replace: modeler.value.get('replace'),
-      selection: modeler.value.get('selection')
-    }
-
-    // 检查所有实例是否都存在
-    return Object.values(instances).every((instance) => instance)
-  } catch (error) {
-    console.error('初始化 bpmnInstances 失败:', error)
-    return false
-  }
-}
 
 /** 初始化 modeler */
 const initModeler = async (item) => {
-  try {
-    modeler.value = item
-    // 等待 modeler 初始化完成
-    await nextTick()
-
-    // 确保 modeler 的所有实例都已经准备好
-    if (initBpmnInstances()) {
-      isModelerReady.value = true
-      emit('init-finished')
-
-      // 初始化完成后,设置初始值
-      if (props.modelId) {
-        // 编辑模式
-        const data = await ModelApi.getModel(props.modelId)
-        model.value = {
-          ...data,
-          bpmnXml: undefined // 清空 bpmnXml 属性
-        }
-        xmlString.value = data.bpmnXml || getDefaultBpmnXml(data.key, data.name)
-      } else if (props.modelKey && props.modelName) {
-        // 新建模式
-        xmlString.value = props.value || getDefaultBpmnXml(props.modelKey, props.modelName)
-        model.value = {
-          key: props.modelKey,
-          name: props.modelName
-        } as ModelApi.ModelVO
-      }
-
-      // 导入XML并刷新视图
-      await nextTick()
-      try {
-        await modeler.value.importXML(xmlString.value)
-        if (processDesigner.value?.refresh) {
-          processDesigner.value.refresh()
-        }
-      } catch (error) {
-        console.error('导入XML失败:', error)
-      }
-    } else {
-      console.error('modeler 实例未完全初始化')
-    }
-  } catch (error) {
-    console.error('初始化 modeler 失败:', error)
-  }
+  modeler.value = item
 }
 
-/** 获取默认的BPMN XML */
-const getDefaultBpmnXml = (key: string, name: string) => {
-  return `<?xml version="1.0" encoding="UTF-8"?>
-<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.activiti.org/processdef">
-  <process id="${key}" name="${name}" isExecutable="true" />
-  <bpmndi:BPMNDiagram id="BPMNDiagram">
-    <bpmndi:BPMNPlane id="${key}_di" bpmnElement="${key}" />
-  </bpmndi:BPMNDiagram>
-</definitions>`
-}
 
 /** 添加/修改模型 */
 const save = async (bpmnXml: string) => {
   try {
     xmlString.value = bpmnXml
-    if (props.modelId) {
-      // 编辑模式
-      const data = {
-        ...model.value,
-        bpmnXml: bpmnXml
-      } as unknown as ModelApi.ModelVO
-      await ModelApi.updateModelBpmn(data)
-      emit('success')
-    } else {
-      // 新建模式,直接返回XML
-      emit('success', bpmnXml)
-    }
+    emit('success', bpmnXml)
   } catch (error) {
     console.error('保存失败:', error)
     message.error('保存失败')
   }
 }
 
-// 监听 key、name 和 value 的变化
-watch(
-  [() => props.modelKey, () => props.modelName, () => props.value],
-  async ([newKey, newName, newValue]) => {
-    if (!props.modelId && isModelerReady.value) {
-      let shouldRefresh = false
-
-      if (newKey && newName) {
-        const newXml = newValue || getDefaultBpmnXml(newKey, newName)
-        if (newXml !== xmlString.value) {
-          xmlString.value = newXml
-          shouldRefresh = true
-        }
-        model.value = {
-          ...model.value,
-          key: newKey,
-          name: newName
-        } as ModelApi.ModelVO
-      } else if (newValue && newValue !== xmlString.value) {
-        xmlString.value = newValue
-        shouldRefresh = true
-      }
-
-      if (shouldRefresh) {
-        // 确保更新后重新渲染
-        await nextTick()
-        if (processDesigner.value?.refresh) {
-          try {
-            await modeler.value?.importXML(xmlString.value)
-            processDesigner.value.refresh()
-          } catch (error) {
-            console.error('导入XML失败:', error)
-          }
-        }
-      }
-    }
-  },
-  { deep: true }
-)
 
 // 在组件卸载时清理
 onBeforeUnmount(() => {
-  isModelerReady.value = false
   modeler.value = null
   // 清理全局实例
   const w = window as any
@@ -221,54 +96,7 @@ onBeforeUnmount(() => {
   }
 })
 
-/** 获取 XML 字符串 */
-const saveXML = async () => {
-  if (!modeler.value) {
-    return { xml: xmlString.value }
-  }
-  try {
-    const result = await modeler.value.saveXML({ format: true })
-    xmlString.value = result.xml
-    return result
-  } catch (error) {
-    console.error('获取XML失败:', error)
-    return { xml: xmlString.value }
-  }
-}
 
-/** 获取SVG字符串 */
-const saveSVG = async () => {
-  if (!modeler.value) {
-    return { svg: undefined }
-  }
-  try {
-    return await modeler.value.saveSVG()
-  } catch (error) {
-    console.error('获取SVG失败:', error)
-    return { svg: undefined }
-  }
-}
-
-/** 刷新视图 */
-const refresh = async () => {
-  if (processDesigner.value?.refresh && modeler.value) {
-    try {
-      await modeler.value.importXML(xmlString.value)
-      processDesigner.value.refresh()
-    } catch (error) {
-      console.error('刷新视图失败:', error)
-    }
-  }
-}
-
-// 暴露必要的属性和方法给父组件
-defineExpose({
-  modeler,
-  isModelerReady,
-  saveXML,
-  saveSVG,
-  refresh
-})
 </script>
 <style lang="scss">
 .process-panel__container {

+ 21 - 30
src/views/bpm/model/form/BasicInfo.vue

@@ -144,10 +144,6 @@ import { DICT_TYPE, getBoolDictOptions, getIntDictOptions } from '@/utils/dict'
 import { UserVO } from '@/api/system/user'
 
 const props = defineProps({
-  modelValue: {
-    type: Object,
-    required: true
-  },
   categoryList: {
     type: Array,
     required: true
@@ -158,8 +154,6 @@ const props = defineProps({
   }
 })
 
-const emit = defineEmits(['update:modelValue'])
-
 const formRef = ref()
 const selectedStartUsers = ref<UserVO[]>([])
 const selectedManagerUsers = ref<UserVO[]>([])
@@ -177,27 +171,30 @@ const rules = {
 }
 
 // 创建本地数据副本
-const modelData = computed({
-  get: () => props.modelValue,
-  set: (val) => emit('update:modelValue', val)
-})
+const modelData = defineModel<any>()
 
 // 初始化选中的用户
 watch(
-  () => props.modelValue,
+  () => modelData.value,
   (newVal) => {
     if (newVal.startUserIds?.length) {
       selectedStartUsers.value = props.userList.filter((user: UserVO) =>
         newVal.startUserIds.includes(user.id)
       ) as UserVO[]
+    } else {
+      selectedStartUsers.value = []
     }
     if (newVal.managerUserIds?.length) {
       selectedManagerUsers.value = props.userList.filter((user: UserVO) =>
         newVal.managerUserIds.includes(user.id)
       ) as UserVO[]
+    } else {
+      selectedManagerUsers.value = []
     }
   },
-  { immediate: true }
+  {
+    immediate: true
+  }
 )
 
 /** 打开发起人选择 */
@@ -215,58 +212,52 @@ const openManagerUserSelect = () => {
 /** 处理用户选择确认 */
 const handleUserSelectConfirm = (_, users: UserVO[]) => {
   if (currentSelectType.value === 'start') {
-    selectedStartUsers.value = users
-    emit('update:modelValue', {
+    modelData.value = {
       ...modelData.value,
       startUserIds: users.map((u) => u.id)
-    })
+    }
   } else {
-    selectedManagerUsers.value = users
-    emit('update:modelValue', {
+    modelData.value = {
       ...modelData.value,
       managerUserIds: users.map((u) => u.id)
-    })
+    }
   }
 }
 
 /** 处理发起人类型变化 */
 const handleStartUserTypeChange = (value: number) => {
   if (value !== 1) {
-    selectedStartUsers.value = []
-    emit('update:modelValue', {
+    modelData.value = {
       ...modelData.value,
       startUserIds: []
-    })
+    }
   }
 }
 
 /** 处理管理员类型变化 */
 const handleManagerUserTypeChange = (value: number) => {
   if (value !== 1) {
-    selectedManagerUsers.value = []
-    emit('update:modelValue', {
+    modelData.value = {
       ...modelData.value,
       managerUserIds: []
-    })
+    }
   }
 }
 
 /** 移除发起人 */
 const handleRemoveStartUser = (user: UserVO) => {
-  selectedStartUsers.value = selectedStartUsers.value.filter((u) => u.id !== user.id)
-  emit('update:modelValue', {
+  modelData.value = {
     ...modelData.value,
     startUserIds: modelData.value.startUserIds.filter((id: number) => id !== user.id)
-  })
+  }
 }
 
 /** 移除管理员 */
 const handleRemoveManagerUser = (user: UserVO) => {
-  selectedManagerUsers.value = selectedManagerUsers.value.filter((u) => u.id !== user.id)
-  emit('update:modelValue', {
+  modelData.value = {
     ...modelData.value,
     managerUserIds: modelData.value.managerUserIds.filter((id: number) => id !== user.id)
-  })
+  }
 }
 
 /** 表单校验 */

+ 1 - 10
src/views/bpm/model/form/FormDesign.vue

@@ -70,25 +70,16 @@ import * as FormApi from '@/api/bpm/form'
 import { setConfAndFields2 } from '@/utils/formCreate'
 
 const props = defineProps({
-  modelValue: {
-    type: Object,
-    required: true
-  },
   formList: {
     type: Array,
     required: true
   }
 })
 
-const emit = defineEmits(['update:modelValue'])
-
 const formRef = ref()
 
 // 创建本地数据副本
-const modelData = computed({
-  get: () => props.modelValue,
-  set: (val) => emit('update:modelValue', val)
-})
+const modelData = defineModel<any>()
 
 // 表单预览数据
 const formPreview = ref({

+ 6 - 160
src/views/bpm/model/form/ProcessDesign.vue

@@ -6,10 +6,7 @@
       :model-id="modelData.id"
       :model-key="modelData.key"
       :model-name="modelData.name"
-      :value="currentBpmnXml"
-      ref="bpmnEditorRef"
       @success="handleDesignSuccess"
-      @init-finished="handleEditorInit"
     />
   </template>
 
@@ -21,10 +18,7 @@
       :model-key="modelData.key"
       :model-name="modelData.name"
       :start-user-ids="modelData.startUserIds"
-      :value="currentSimpleModel"
-      ref="simpleEditorRef"
       @success="handleDesignSuccess"
-      @init-finished="handleEditorInit"
     />
   </template>
 </template>
@@ -34,137 +28,16 @@ import { BpmModelType } from '@/utils/constants'
 import BpmModelEditor from '../editor/index.vue'
 import SimpleModelDesign from '../../simple/SimpleModelDesign.vue'
 
-const props = defineProps({
-  modelValue: {
-    type: Object,
-    required: true
-  }
-})
-
-const emit = defineEmits(['update:modelValue', 'success'])
-
-const bpmnEditorRef = ref()
-const simpleEditorRef = ref()
-const isEditorInitialized = ref(false)
-
 // 创建本地数据副本
-const modelData = computed({
-  get: () => props.modelValue,
-  set: (val) => emit('update:modelValue', val)
-})
+const modelData = defineModel<any>()
 
-// 保存当前的流程XML或数据
-const currentBpmnXml = ref('')
-const currentSimpleModel = ref('')
-
-// 初始化或更新当前的XML数据
-const initOrUpdateXmlData = () => {
-  if (modelData.value) {
-    if (modelData.value.type === BpmModelType.BPMN) {
-      currentBpmnXml.value = modelData.value.bpmnXml || ''
-    } else {
-      currentSimpleModel.value = modelData.value.simpleModel || ''
-    }
-  }
-}
-
-// 监听modelValue的变化,更新数据
-watch(
-  () => props.modelValue,
-  (newVal) => {
-    if (newVal) {
-      if (newVal.type === BpmModelType.BPMN) {
-        if (newVal.bpmnXml && newVal.bpmnXml !== currentBpmnXml.value) {
-          currentBpmnXml.value = newVal.bpmnXml
-          // 如果编辑器已经初始化,刷新视图
-          if (isEditorInitialized.value && bpmnEditorRef.value?.refresh) {
-            nextTick(() => {
-              bpmnEditorRef.value.refresh()
-            })
-          }
-        }
-      } else {
-        if (newVal.simpleModel && newVal.simpleModel !== currentSimpleModel.value) {
-          currentSimpleModel.value = newVal.simpleModel
-          // 如果编辑器已经初始化,刷新视图
-          if (isEditorInitialized.value && simpleEditorRef.value?.refresh) {
-            nextTick(() => {
-              simpleEditorRef.value.refresh()
-            })
-          }
-        }
-      }
-    }
-  },
-  { immediate: true, deep: true }
-)
-
-/** 编辑器初始化完成的回调 */
-const handleEditorInit = async () => {
-  isEditorInitialized.value = true
-
-  // 等待下一个tick,确保编辑器已经准备好
-  await nextTick()
-
-  // 初始化完成后,设置初始值
-  if (modelData.value.type === BpmModelType.BPMN) {
-    if (modelData.value.bpmnXml) {
-      currentBpmnXml.value = modelData.value.bpmnXml
-      if (bpmnEditorRef.value?.refresh) {
-        await nextTick()
-        bpmnEditorRef.value.refresh()
-      }
-    }
-  } else {
-    if (modelData.value.simpleModel) {
-      currentSimpleModel.value = modelData.value.simpleModel
-      if (simpleEditorRef.value?.refresh) {
-        await nextTick()
-        simpleEditorRef.value.refresh()
-      }
-    }
-  }
-}
-
-/** 获取当前流程数据 */
-const getProcessData = async () => {
-  try {
-    if (modelData.value.type === BpmModelType.BPMN) {
-      if (!bpmnEditorRef.value || !isEditorInitialized.value) {
-        return currentBpmnXml.value || undefined
-      }
-      const { xml } = await bpmnEditorRef.value.saveXML()
-      if (xml) {
-        currentBpmnXml.value = xml
-        return xml
-      }
-    } else {
-      if (!simpleEditorRef.value || !isEditorInitialized.value) {
-        return currentSimpleModel.value || undefined
-      }
-      const flowData = await simpleEditorRef.value.getCurrentFlowData()
-      if (flowData) {
-        currentSimpleModel.value = flowData
-        return flowData
-      }
-    }
-    return modelData.value.type === BpmModelType.BPMN
-      ? currentBpmnXml.value
-      : currentSimpleModel.value
-  } catch (error) {
-    console.error('获取流程数据失败:', error)
-    return modelData.value.type === BpmModelType.BPMN
-      ? currentBpmnXml.value
-      : currentSimpleModel.value
-  }
-}
+const processData = inject('processData') as Ref
 
 /** 表单校验 */
 const validate = async () => {
   try {
     // 获取最新的流程数据
-    const processData = await getProcessData()
-    if (!processData) {
+    if (!processData.value) {
       throw new Error('请设计流程')
     }
     return true
@@ -172,27 +45,19 @@ const validate = async () => {
     throw error
   }
 }
-
 /** 处理设计器保存成功 */
 const handleDesignSuccess = async (data?: any) => {
   if (data) {
-    if (modelData.value.type === BpmModelType.BPMN) {
-      currentBpmnXml.value = data
-    } else {
-      currentSimpleModel.value = data
-    }
-
     // 创建新的对象以触发响应式更新
     const newModelData = {
       ...modelData.value,
       bpmnXml: modelData.value.type === BpmModelType.BPMN ? data : null,
       simpleModel: modelData.value.type === BpmModelType.BPMN ? null : data
     }
-
     // 使用emit更新父组件的数据
     await nextTick()
-    emit('update:modelValue', newModelData)
-    emit('success', data)
+    //更新表单的模型数据部分
+    modelData.value = newModelData
   }
 }
 
@@ -203,33 +68,14 @@ const showDesigner = computed(() => {
 
 // 组件创建时初始化数据
 onMounted(() => {
-  initOrUpdateXmlData()
 })
 
 // 组件卸载前保存数据
 onBeforeUnmount(async () => {
-  try {
-    // 获取并保存最新的流程数据
-    const data = await getProcessData()
-    if (data) {
-      // 创建新的对象以触发响应式更新
-      const newModelData = {
-        ...modelData.value,
-        bpmnXml: modelData.value.type === BpmModelType.BPMN ? data : null,
-        simpleModel: modelData.value.type === BpmModelType.BPMN ? null : data
-      }
 
-      // 使用emit更新父组件的数据
-      await nextTick()
-      emit('update:modelValue', newModelData)
-    }
-  } catch (error) {
-    console.error('保存数据失败:', error)
-  }
 })
 
 defineExpose({
-  validate,
-  getProcessData
+  validate
 })
 </script>

+ 43 - 107
src/views/bpm/model/form/index.vue

@@ -71,7 +71,6 @@
           v-if="currentStep === 2"
           v-model="formData"
           ref="processDesignRef"
-          @success="handleDesignSuccess"
         />
       </div>
     </div>
@@ -118,7 +117,8 @@ const validateProcess = async () => {
   await processDesignRef.value?.validate()
 }
 
-const currentStep = ref(0) // 步骤控制
+const currentStep = ref(-1) // 步骤控制 一开始全部不展示等当前页面数据初始化完成
+
 const steps = [
   { title: '基本信息', validator: validateBasic },
   { title: '表单设计', validator: validateForm },
@@ -145,17 +145,24 @@ const formData: any = ref({
   managerUserIds: []
 })
 
+//流程数据
+const processData = ref<any>()
+
+provide("processData", processData)
+
 // 数据列表
 const formList = ref([])
 const categoryList = ref([])
 const userList = ref<UserApi.UserVO[]>([])
 
+
 /** 初始化数据 */
 const initData = async () => {
   const modelId = route.params.id as string
   if (modelId) {
     // 修改场景
     formData.value = await ModelApi.getModel(modelId)
+
   } else {
     // 新增场景
     formData.value.managerUserIds.push(userStore.getUser.id)
@@ -167,59 +174,49 @@ const initData = async () => {
   categoryList.value = await CategoryApi.getCategorySimpleList()
   // 获取用户列表
   userList.value = await UserApi.getSimpleUserList()
+
+  currentStep.value = 0
 }
 
+//根据类型切换流程数据
+watch(async () => formData.value.type, (newValue, oldValue) => {
+  if (formData.value.type === BpmModelType.BPMN) {
+    processData.value = formData.value.bpmnXml
+  } else if (formData.value.type === BpmModelType.SIMPLE) {
+    processData.value = formData.value.simpleModel
+  }
+  console.log('加载流程数据', processData.value)
+}, {
+  immediate: true,
+})
+
 /** 校验所有步骤数据是否完整 */
 const validateAllSteps = async () => {
   try {
     // 基本信息校验
-    await basicInfoRef.value?.validate()
-    if (!formData.value.key || !formData.value.name || !formData.value.category) {
+    try {
+      await validateBasic()
+    } catch (error) {
       currentStep.value = 0
       throw new Error('请完善基本信息')
     }
 
     // 表单设计校验
-    await formDesignRef.value?.validate()
-    if (formData.value.formType === 10 && !formData.value.formId) {
-      currentStep.value = 1
-      throw new Error('请选择流程表单')
-    }
-    if (
-      formData.value.formType === 20 &&
-      (!formData.value.formCustomCreatePath || !formData.value.formCustomViewPath)
-    ) {
+    try {
+      await validateForm()
+    } catch (error) {
       currentStep.value = 1
       throw new Error('请完善自定义表单信息')
     }
 
     // 流程设计校验
-    // 如果已经有流程数据,则不需要重新校验
-    if (!formData.value.bpmnXml && !formData.value.simpleModel) {
-      // 如果当前不在第三步,需要先保存当前步骤数据
-      if (currentStep.value !== 2) {
-        await steps[currentStep.value].validator()
-        // 切换到第三步
-        currentStep.value = 2
-        // 等待组件渲染完成
-        await nextTick()
-      }
 
-      // 校验流程设计
-      await processDesignRef.value?.validate()
-      const processData = await processDesignRef.value?.getProcessData()
-      if (!processData) {
-        throw new Error('请设计流程')
-      }
-
-      // 保存流程数据
-      if (formData.value.type === BpmModelType.BPMN) {
-        formData.value.bpmnXml = processData
-        formData.value.simpleModel = null
-      } else {
-        formData.value.bpmnXml = null
-        formData.value.simpleModel = processData
-      }
+    // 表单设计校验
+    try {
+      await validateProcess()
+    } catch (error) {
+      currentStep.value = 2
+      throw new Error('请设计流程')
     }
 
     return true
@@ -239,20 +236,6 @@ const handleSave = async () => {
       ...formData.value
     }
 
-    // 如果当前在第三步,获取最新的流程设计数据
-    if (currentStep.value === 2) {
-      const processData = await processDesignRef.value?.getProcessData()
-      if (processData) {
-        if (formData.value.type === BpmModelType.BPMN) {
-          modelData.bpmnXml = processData
-          modelData.simpleModel = null
-        } else {
-          modelData.bpmnXml = null
-          modelData.simpleModel = processData
-        }
-      }
-    }
-
     if (formData.value.id) {
       // 修改场景
       await ModelApi.updateModel(modelData)
@@ -308,20 +291,6 @@ const handleDeploy = async () => {
       ...formData.value
     }
 
-    // 如果当前在第三步,获取最新的流程设计数据
-    if (currentStep.value === 2) {
-      const processData = await processDesignRef.value?.getProcessData()
-      if (processData) {
-        if (formData.value.type === BpmModelType.BPMN) {
-          modelData.bpmnXml = processData
-          modelData.simpleModel = null
-        } else {
-          modelData.bpmnXml = null
-          modelData.simpleModel = processData
-        }
-      }
-    }
-
     // 先保存所有数据
     if (formData.value.id) {
       await ModelApi.updateModel(modelData)
@@ -344,59 +313,26 @@ const handleDeploy = async () => {
 /** 步骤切换处理 */
 const handleStepClick = async (index: number) => {
   try {
-    // 如果是切换到第三步(流程设计),需要校验key和name
-    if (index === 2) {
-      if (!formData.value.key || !formData.value.name) {
-        message.warning('请先填写流程标识和流程名称')
-        return
-      }
+    console.log('index', index);
+    if (index !== 0) {
+      await validateBasic()
     }
-
-    // 保存当前步骤的数据
-    if (currentStep.value === 2) {
-      const processData = await processDesignRef.value?.getProcessData()
-      if (processData) {
-        if (formData.value.type === BpmModelType.BPMN) {
-          formData.value.bpmnXml = processData
-          formData.value.simpleModel = null
-        } else {
-          formData.value.bpmnXml = null
-          formData.value.simpleModel = processData
-        }
-      }
-    } else {
-      // 只有在向后切换时才进行校验
-      if (index > currentStep.value) {
-        if (typeof steps[currentStep.value].validator === 'function') {
-          await steps[currentStep.value].validator()
-        }
-      }
+    if (index !== 1) {
+      await validateForm()
+    }
+    if (index !== 2) {
+      await validateProcess()
     }
 
     // 切换步骤
     currentStep.value = index
 
-    // 如果切换到流程设计步骤,等待组件渲染完成后刷新设计器
-    if (index === 2) {
-      await nextTick()
-      // 等待更长时间确保组件完全初始化
-      await new Promise(resolve => setTimeout(resolve, 200))
-      if (processDesignRef.value?.refresh) {
-        await processDesignRef.value.refresh()
-      }
-    }
   } catch (error) {
     console.error('步骤切换失败:', error)
     message.warning('请先完善当前步骤必填信息')
   }
 }
 
-/** 处理设计器保存成功 */
-const handleDesignSuccess = (bpmnXml?: string) => {
-  if (bpmnXml) {
-    formData.value.bpmnXml = bpmnXml
-  }
-}
 
 /** 返回列表页 */
 const handleBack = () => {

+ 4 - 109
src/views/bpm/simple/SimpleModelDesign.vue

@@ -4,9 +4,7 @@
       :model-id="modelId"
       :model-key="modelKey"
       :model-name="modelName"
-      :value="currentValue"
       @success="handleSuccess"
-      @init-finished="handleInit"
       :start-user-ids="startUserIds"
       ref="designerRef"
     />
@@ -23,133 +21,30 @@ const props = defineProps<{
   modelId?: string
   modelKey?: string
   modelName?: string
-  value?: string
   startUserIds?: number[]
 }>()
 
-const emit = defineEmits(['success', 'init-finished'])
+const emit = defineEmits(['success'])
 const designerRef = ref()
-const isInitialized = ref(false)
-const currentValue = ref('')
-
-// 初始化或更新当前值
-const initOrUpdateValue = async () => {
-  console.log('initOrUpdateValue', props.value)
-  if (props.value) {
-    currentValue.value = props.value
-    // 如果设计器已经初始化,立即加载数据
-    if (isInitialized.value && designerRef.value) {
-      try {
-        await designerRef.value.loadProcessData(props.value)
-        await nextTick()
-        if (designerRef.value.refresh) {
-          await designerRef.value.refresh()
-        }
-      } catch (error) {
-        console.error('加载流程数据失败:', error)
-      }
-    }
-  }
-}
-
-// 监听属性变化
-watch(
-  [() => props.modelKey, () => props.modelName, () => props.value],
-  async ([newKey, newName, newValue], [oldKey, oldName, oldValue]) => {
-    if (designerRef.value && isInitialized.value) {
-      try {
-        if (newKey && newName && (newKey !== oldKey || newName !== oldName)) {
-          await designerRef.value.updateModel(newKey, newName)
-        }
-        if (newValue && newValue !== oldValue) {
-          currentValue.value = newValue
-          await designerRef.value.loadProcessData(newValue)
-          await nextTick()
-          if (designerRef.value.refresh) {
-            await designerRef.value.refresh()
-          }
-        }
-      } catch (error) {
-        console.error('更新流程数据失败:', error)
-      }
-    }
-  },
-  { deep: true, immediate: true }
-)
-
-// 初始化完成回调
-const handleInit = async () => {
-  try {
-    isInitialized.value = true
-    emit('init-finished')
-
-    // 等待下一个tick,确保设计器已经准备好
-    await nextTick()
-
-    // 初始化完成后,设置初始值
-    if (props.modelKey && props.modelName) {
-      await designerRef.value.updateModel(props.modelKey, props.modelName)
-    }
-    if (props.value) {
-      currentValue.value = props.value
-      await designerRef.value.loadProcessData(props.value)
-      // 再次刷新确保数据正确加载
-      await nextTick()
-      if (designerRef.value.refresh) {
-        await designerRef.value.refresh()
-      }
-    }
-  } catch (error) {
-    console.error('初始化流程数据失败:', error)
-  }
-}
 
 // 修改成功回调
 const handleSuccess = (data?: any) => {
-  console.warn('handleSuccess', data)
-  if (data && data !== currentValue.value) {
-    currentValue.value = data
+  console.info('handleSuccess', data)
+  if (data) {
     emit('success', data)
   }
 }
 
-/** 获取当前流程数据 */
-const getCurrentFlowData = async () => {
-  try {
-    if (designerRef.value) {
-      const data = await designerRef.value.getCurrentFlowData()
-      if (data) {
-        currentValue.value = data
-      }
-      return data
-    }
-    return currentValue.value || undefined
-  } catch (error) {
-    console.error('获取流程数据失败:', error)
-    return currentValue.value || undefined
-  }
-}
-
 // 组件创建时初始化数据
 onMounted(() => {
-  initOrUpdateValue()
 })
 
 // 组件卸载前保存数据
 onBeforeUnmount(async () => {
-  try {
-    const data = await getCurrentFlowData()
-    if (data) {
-      emit('success', data)
-    }
-  } catch (error) {
-    console.error('保存数据失败:', error)
-  }
+
 })
 
 defineExpose({
-  getCurrentFlowData,
-  refresh: () => designerRef.value?.refresh?.()
 })
 </script>
 <style lang="scss" scoped></style>