ProcessDesign.vue 6.2 KB

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