提交 | 用户 | 时间
c9a6f7 1 <template>
H 2   <!-- BPMN设计器 -->
3   <template v-if="modelData.type === BpmModelType.BPMN">
4     <BpmModelEditor
5       v-if="showDesigner"
6       :model-id="modelData.id"
7       :model-key="modelData.key"
8       :model-name="modelData.name"
9       :value="currentBpmnXml"
10       ref="bpmnEditorRef"
11       @success="handleDesignSuccess"
12       @init-finished="handleEditorInit"
13     />
14   </template>
15
16   <!-- Simple设计器 -->
17   <template v-else>
18     <SimpleModelDesign
19       v-if="showDesigner"
20       :model-id="modelData.id"
21       :model-key="modelData.key"
22       :model-name="modelData.name"
23       :start-user-ids="modelData.startUserIds"
24       :value="currentSimpleModel"
25       ref="simpleEditorRef"
26       @success="handleDesignSuccess"
27       @init-finished="handleEditorInit"
28     />
29   </template>
30 </template>
31
32 <script lang="ts" setup>
33 import { BpmModelType } from '@/utils/constants'
34 import BpmModelEditor from '../editor/index.vue'
35 import SimpleModelDesign from '../../simple/SimpleModelDesign.vue'
36
37 const props = defineProps({
38   modelValue: {
39     type: Object,
40     required: true
41   }
42 })
43
44 const emit = defineEmits(['update:modelValue', 'success'])
45
46 const bpmnEditorRef = ref()
47 const simpleEditorRef = ref()
48 const isEditorInitialized = ref(false)
49
50 // 创建本地数据副本
51 const modelData = computed({
52   get: () => props.modelValue,
53   set: (val) => emit('update:modelValue', val)
54 })
55
56 // 保存当前的流程XML或数据
57 const currentBpmnXml = ref('')
58 const currentSimpleModel = ref('')
59
60 // 初始化或更新当前的XML数据
61 const initOrUpdateXmlData = () => {
62   if (modelData.value) {
63     if (modelData.value.type === BpmModelType.BPMN) {
64       currentBpmnXml.value = modelData.value.bpmnXml || ''
65     } else {
66       currentSimpleModel.value = modelData.value.simpleModel || ''
67     }
68   }
69 }
70
71 // 监听modelValue的变化,更新数据
72 watch(
73   () => props.modelValue,
74   (newVal) => {
75     if (newVal) {
76       if (newVal.type === BpmModelType.BPMN) {
77         if (newVal.bpmnXml && newVal.bpmnXml !== currentBpmnXml.value) {
78           currentBpmnXml.value = newVal.bpmnXml
79           // 如果编辑器已经初始化,刷新视图
80           if (isEditorInitialized.value && bpmnEditorRef.value?.refresh) {
81             nextTick(() => {
82               bpmnEditorRef.value.refresh()
83             })
84           }
85         }
86       } else {
87         if (newVal.simpleModel && newVal.simpleModel !== currentSimpleModel.value) {
88           currentSimpleModel.value = newVal.simpleModel
89           // 如果编辑器已经初始化,刷新视图
90           if (isEditorInitialized.value && simpleEditorRef.value?.refresh) {
91             nextTick(() => {
92               simpleEditorRef.value.refresh()
93             })
94           }
95         }
96       }
97     }
98   },
99   { immediate: true, deep: true }
100 )
101
102 /** 编辑器初始化完成的回调 */
103 const handleEditorInit = async () => {
104   isEditorInitialized.value = true
105
106   // 等待下一个tick,确保编辑器已经准备好
107   await nextTick()
108
109   // 初始化完成后,设置初始值
110   if (modelData.value.type === BpmModelType.BPMN) {
111     if (modelData.value.bpmnXml) {
112       currentBpmnXml.value = modelData.value.bpmnXml
113       if (bpmnEditorRef.value?.refresh) {
114         await nextTick()
115         bpmnEditorRef.value.refresh()
116       }
117     }
118   } else {
119     if (modelData.value.simpleModel) {
120       currentSimpleModel.value = modelData.value.simpleModel
121       if (simpleEditorRef.value?.refresh) {
122         await nextTick()
123         simpleEditorRef.value.refresh()
124       }
125     }
126   }
127 }
128
129 /** 获取当前流程数据 */
130 const getProcessData = async () => {
131   try {
132     if (modelData.value.type === BpmModelType.BPMN) {
133       if (!bpmnEditorRef.value || !isEditorInitialized.value) {
134         return currentBpmnXml.value || undefined
135       }
136       const { xml } = await bpmnEditorRef.value.saveXML()
137       if (xml) {
138         currentBpmnXml.value = xml
139         return xml
140       }
141     } else {
142       if (!simpleEditorRef.value || !isEditorInitialized.value) {
143         return currentSimpleModel.value || undefined
144       }
145       const flowData = await simpleEditorRef.value.getCurrentFlowData()
146       if (flowData) {
147         currentSimpleModel.value = flowData
148         return flowData
149       }
150     }
151     return modelData.value.type === BpmModelType.BPMN
152       ? currentBpmnXml.value
153       : currentSimpleModel.value
154   } catch (error) {
155     console.error('获取流程数据失败:', error)
156     return modelData.value.type === BpmModelType.BPMN
157       ? currentBpmnXml.value
158       : currentSimpleModel.value
159   }
160 }
161
162 /** 表单校验 */
163 const validate = async () => {
164   try {
165     // 获取最新的流程数据
166     const processData = await getProcessData()
167     if (!processData) {
168       throw new Error('请设计流程')
169     }
170     return true
171   } catch (error) {
172     throw error
173   }
174 }
175
176 /** 处理设计器保存成功 */
177 const handleDesignSuccess = async (data?: any) => {
178   if (data) {
179     if (modelData.value.type === BpmModelType.BPMN) {
180       currentBpmnXml.value = data
181     } else {
182       currentSimpleModel.value = data
183     }
184
185     // 创建新的对象以触发响应式更新
186     const newModelData = {
187       ...modelData.value,
188       bpmnXml: modelData.value.type === BpmModelType.BPMN ? data : null,
189       simpleModel: modelData.value.type === BpmModelType.BPMN ? null : data
190     }
191
192     // 使用emit更新父组件的数据
193     await nextTick()
194     emit('update:modelValue', newModelData)
195     emit('success', data)
196   }
197 }
198
199 /** 是否显示设计器 */
200 const showDesigner = computed(() => {
201   return Boolean(modelData.value?.key && modelData.value?.name)
202 })
203
204 // 组件创建时初始化数据
205 onMounted(() => {
206   initOrUpdateXmlData()
207 })
208
209 // 组件卸载前保存数据
210 onBeforeUnmount(async () => {
211   try {
212     // 获取并保存最新的流程数据
213     const data = await getProcessData()
214     if (data) {
215       // 创建新的对象以触发响应式更新
216       const newModelData = {
217         ...modelData.value,
218         bpmnXml: modelData.value.type === BpmModelType.BPMN ? data : null,
219         simpleModel: modelData.value.type === BpmModelType.BPMN ? null : data
220       }
221
222       // 使用emit更新父组件的数据
223       await nextTick()
224       emit('update:modelValue', newModelData)
225     }
226   } catch (error) {
227     console.error('保存数据失败:', error)
228   }
229 })
230
231 defineExpose({
232   validate,
233   getProcessData
234 })
235 </script>