ProcessDesign.vue 6.2 KB

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