Skip to content

Commit 6791de9

Browse files
committed
Merge branch 'feature/bpm' of https://github.com/yudaocode/yudao-ui-admin-vue3 into feature/bpm
2 parents 2f4599f + 241e271 commit 6791de9

File tree

8 files changed

+320
-123
lines changed

8 files changed

+320
-123
lines changed

src/components/SimpleProcessDesignerV2/src/SimpleProcessDesigner.vue

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<template>
22
<div v-loading="loading" class="overflow-auto">
33
<SimpleProcessModel
4+
ref="simpleProcessModelRef"
45
v-if="processNodeTree"
56
:flow-node="processNodeTree"
67
:readonly="false"
@@ -225,4 +226,19 @@ onMounted(async () => {
225226
loading.value = false
226227
}
227228
})
229+
230+
const simpleProcessModelRef = ref()
231+
232+
/** 获取当前流程数据 */
233+
const getCurrentFlowData = async () => {
234+
if (simpleProcessModelRef.value) {
235+
return await simpleProcessModelRef.value.getCurrentFlowData()
236+
}
237+
return undefined
238+
}
239+
240+
defineExpose({
241+
getCurrentFlowData,
242+
updateModel
243+
})
228244
</script>

src/components/SimpleProcessDesignerV2/src/SimpleProcessModel.vue

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,6 @@
88
<el-button size="default" class="w-80px"> {{ scaleValue }}% </el-button>
99
<el-button size="default" :plain="true" :icon="ZoomIn" @click="zoomIn()" />
1010
</el-button-group>
11-
<el-button
12-
v-if="!readonly"
13-
size="default"
14-
class="ml-4px"
15-
type="primary"
16-
:icon="Select"
17-
@click="saveSimpleFlowModel"
18-
>保存模型</el-button
19-
>
2011
</el-row>
2112
</div>
2213
<div class="simple-process-model" :style="`transform: scale(${scaleValue / 100});`">
@@ -42,7 +33,8 @@
4233
import ProcessNodeTree from './ProcessNodeTree.vue'
4334
import { SimpleFlowNode, NodeType, NODE_DEFAULT_TEXT } from './consts'
4435
import { useWatchNode } from './node'
45-
import { Select, ZoomOut, ZoomIn, ScaleToOriginal } from '@element-plus/icons-vue'
36+
import { ZoomOut, ZoomIn, ScaleToOriginal } from '@element-plus/icons-vue'
37+
4638
defineOptions({
4739
name: 'SimpleProcessModel'
4840
})
@@ -58,6 +50,7 @@ const props = defineProps({
5850
default: true
5951
}
6052
})
53+
6154
const emits = defineEmits<{
6255
'save': [node: SimpleFlowNode | undefined]
6356
}>()
@@ -68,35 +61,30 @@ provide('readonly', props.readonly)
6861
let scaleValue = ref(100)
6962
const MAX_SCALE_VALUE = 200
7063
const MIN_SCALE_VALUE = 50
64+
7165
// 放大
7266
const zoomIn = () => {
7367
if (scaleValue.value == MAX_SCALE_VALUE) {
7468
return
7569
}
7670
scaleValue.value += 10
7771
}
72+
7873
// 缩小
7974
const zoomOut = () => {
8075
if (scaleValue.value == MIN_SCALE_VALUE) {
8176
return
8277
}
8378
scaleValue.value -= 10
8479
}
80+
8581
const processReZoom = () => {
8682
scaleValue.value = 100
8783
}
8884
8985
const errorDialogVisible = ref(false)
9086
let errorNodes: SimpleFlowNode[] = []
91-
const saveSimpleFlowModel = async () => {
92-
errorNodes = []
93-
validateNode(processNodeTree.value, errorNodes)
94-
if (errorNodes.length > 0) {
95-
errorDialogVisible.value = true
96-
return
97-
}
98-
emits('save', processNodeTree.value)
99-
}
87+
10088
// 校验节点设置。 暂时以 showText 为空 未节点错误配置
10189
const validateNode = (node: SimpleFlowNode | undefined, errorNodes: SimpleFlowNode[]) => {
10290
if (node) {
@@ -135,6 +123,26 @@ const validateNode = (node: SimpleFlowNode | undefined, errorNodes: SimpleFlowNo
135123
}
136124
}
137125
}
126+
127+
/** 获取当前流程数据 */
128+
const getCurrentFlowData = async () => {
129+
try {
130+
errorNodes = []
131+
validateNode(processNodeTree.value, errorNodes)
132+
if (errorNodes.length > 0) {
133+
errorDialogVisible.value = true
134+
return undefined
135+
}
136+
return processNodeTree.value
137+
} catch (error) {
138+
console.error('获取流程数据失败:', error)
139+
return undefined
140+
}
141+
}
142+
143+
defineExpose({
144+
getCurrentFlowData
145+
})
138146
</script>
139147

140148
<style lang="scss" scoped></style>

src/components/bpmnProcessDesigner/package/designer/ProcessDesigner.vue

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -160,13 +160,6 @@
160160
<XButton preIcon="ep:refresh" @click="processRestart()" />
161161
</el-tooltip>
162162
</ElButtonGroup>
163-
<XButton
164-
preIcon="ep:plus"
165-
title="保存模型"
166-
@click="processSave"
167-
:type="props.headerButtonType"
168-
:disabled="simulationStatus"
169-
/>
170163
</template>
171164
<!-- 用于打开本地文件-->
172165
<input

src/views/bpm/model/editor/index.vue

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,11 +205,53 @@ onBeforeUnmount(() => {
205205
w.bpmnInstances = null
206206
}
207207
})
208+
209+
/** 获取XML字符串 */
210+
const saveXML = async () => {
211+
if (!modeler.value) {
212+
return { xml: undefined }
213+
}
214+
try {
215+
return await modeler.value.saveXML({ format: true })
216+
} catch (error) {
217+
console.error('获取XML失败:', error)
218+
return { xml: undefined }
219+
}
220+
}
221+
222+
/** 获取SVG字符串 */
223+
const saveSVG = async () => {
224+
if (!modeler.value) {
225+
return { svg: undefined }
226+
}
227+
try {
228+
return await modeler.value.saveSVG()
229+
} catch (error) {
230+
console.error('获取SVG失败:', error)
231+
return { svg: undefined }
232+
}
233+
}
234+
235+
/** 刷新视图 */
236+
const refresh = () => {
237+
if (processDesigner.value?.refresh) {
238+
processDesigner.value.refresh()
239+
}
240+
}
241+
242+
// 暴露必要的属性和方法给父组件
243+
defineExpose({
244+
modeler,
245+
isModelerReady,
246+
saveXML,
247+
saveSVG,
248+
refresh
249+
})
208250
</script>
209251
<style lang="scss">
210252
.process-panel__container {
211253
position: absolute;
212-
top: 90px;
254+
top: 180px;
213255
right: 60px;
214256
}
215257
</style>

src/views/bpm/model/form/BasicInfo.vue

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,9 @@
11
<template>
2-
<el-form
3-
ref="formRef"
4-
:model="modelData"
5-
:rules="rules"
6-
label-width="120px"
7-
class="mt-20px w-600px"
8-
>
2+
<el-form ref="formRef" :model="modelData" :rules="rules" label-width="120px" class="mt-20px">
93
<el-form-item label="流程标识" prop="key" class="mb-20px">
104
<div class="flex items-center">
115
<el-input
12-
class="!w-480px"
6+
class="!w-440px"
137
v-model="modelData.key"
148
:disabled="!!modelData.id"
159
placeholder="请输入流标标识"

src/views/bpm/model/form/ProcessDesign.vue

Lines changed: 61 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
:model-key="modelData.key"
88
:model-name="modelData.name"
99
:value="modelData.bpmnXml"
10+
ref="bpmnEditorRef"
1011
@success="handleDesignSuccess"
1112
/>
1213
</template>
@@ -19,6 +20,7 @@
1920
:model-key="modelData.key"
2021
:model-name="modelData.name"
2122
:value="modelData.bpmnXml"
23+
ref="simpleEditorRef"
2224
@success="handleDesignSuccess"
2325
/>
2426
</template>
@@ -38,67 +40,91 @@ const props = defineProps({
3840
3941
const emit = defineEmits(['update:modelValue', 'success'])
4042
41-
const xmlString = ref<string>()
43+
const bpmnEditorRef = ref()
44+
const simpleEditorRef = ref()
4245
4346
// 创建本地数据副本
4447
const modelData = computed({
4548
get: () => props.modelValue,
4649
set: (val) => emit('update:modelValue', val)
4750
})
4851
49-
// 监听modelValue变化,确保XML数据同步
50-
watch(
51-
() => props.modelValue,
52-
(newVal) => {
53-
if (newVal?.bpmnXml) {
54-
xmlString.value = newVal.bpmnXml
52+
/** 获取当前流程数据 */
53+
const getProcessData = async () => {
54+
try {
55+
if (modelData.value.type === BpmModelType.BPMN) {
56+
// BPMN设计器
57+
if (bpmnEditorRef.value) {
58+
const { xml } = await bpmnEditorRef.value.saveXML()
59+
if (xml) {
60+
return xml
61+
}
62+
}
63+
} else {
64+
// Simple设计器
65+
if (simpleEditorRef.value) {
66+
const flowData = await simpleEditorRef.value.getCurrentFlowData()
67+
if (flowData) {
68+
return flowData // 直接返回流程数据对象,不需要转换为字符串
69+
}
70+
}
5571
}
56-
},
57-
{ immediate: true, deep: true }
58-
)
59-
60-
/** 处理设计器保存成功 */
61-
const handleDesignSuccess = (bpmnXml?: string) => {
62-
if (bpmnXml) {
63-
xmlString.value = bpmnXml
64-
modelData.value = {
65-
...modelData.value,
66-
bpmnXml
67-
}
68-
emit('success', bpmnXml)
72+
return undefined
73+
} catch (error) {
74+
console.error('获取流程数据失败:', error)
75+
return undefined
6976
}
7077
}
7178
7279
/** 表单校验 */
7380
const validate = async () => {
74-
// 获取最新的XML数据
75-
const currentXml = xmlString.value || modelData.value?.bpmnXml
81+
try {
82+
// 根据流程类型获取对应的编辑器引用
83+
const editorRef =
84+
modelData.value.type === BpmModelType.BPMN ? bpmnEditorRef.value : simpleEditorRef.value
85+
if (!editorRef) {
86+
throw new Error('流程设计器未初始化')
87+
}
88+
89+
// 获取最新的流程数据
90+
const processData = await getProcessData()
91+
if (!processData) {
92+
throw new Error('请设计流程')
93+
}
7694
77-
// 如果是修改场景且有XML数据(无论是新的还是原有的)
78-
if (modelData.value.id && currentXml) {
7995
return true
96+
} catch (error) {
97+
throw error
8098
}
99+
}
81100
82-
// 新增场景必须有XML数据
83-
if (!currentXml) {
84-
throw new Error('请设计流程')
101+
/** 处理设计器保存成功 */
102+
const handleDesignSuccess = (data?: any) => {
103+
if (data) {
104+
if (modelData.value.type === BpmModelType.BPMN) {
105+
modelData.value = {
106+
...modelData.value,
107+
bpmnXml: data,
108+
simpleModel: null
109+
}
110+
} else {
111+
modelData.value = {
112+
...modelData.value,
113+
bpmnXml: null,
114+
simpleModel: data
115+
}
116+
}
117+
emit('success', data)
85118
}
86-
87-
return true
88119
}
89120
90121
/** 是否显示设计器 */
91122
const showDesigner = computed(() => {
92123
return Boolean(modelData.value?.key && modelData.value?.name)
93124
})
94125
95-
/** 获取当前XML字符串 */
96-
const getXmlString = () => {
97-
return xmlString.value || modelData.value?.bpmnXml || ''
98-
}
99-
100126
defineExpose({
101127
validate,
102-
getXmlString
128+
getProcessData
103129
})
104130
</script>

0 commit comments

Comments
 (0)