Skip to content

Commit 3d8f129

Browse files
committed
perf: bpm 流程模型表单代码优化. 去掉大量watch 代码. 用依赖注入替换props 传递流程数据. 增加导入导出
1 parent 49fc9b5 commit 3d8f129

File tree

9 files changed

+156
-729
lines changed

9 files changed

+156
-729
lines changed

src/components/SimpleProcessDesignerV2/src/SimpleProcessDesigner.vue

Lines changed: 9 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ defineOptions({
4040
name: 'SimpleProcessDesigner'
4141
})
4242
43-
const emits = defineEmits(['success', 'init-finished']) // 保存成功事件
43+
const emits = defineEmits(['success']) // 保存成功事件
4444
4545
const props = defineProps({
4646
modelId: {
@@ -59,13 +59,12 @@ const props = defineProps({
5959
startUserIds : {
6060
type: Array,
6161
required: false
62-
},
63-
value: {
64-
type: [String, Object],
65-
required: false
6662
}
6763
})
6864
65+
const processData = inject('processData') as Ref
66+
67+
6968
const loading = ref(false)
7069
const formFields = ref<string[]>([])
7170
const formType = ref(20)
@@ -76,9 +75,6 @@ const deptOptions = ref<DeptApi.DeptVO[]>([]) // 部门列表
7675
const deptTreeOptions = ref()
7776
const userGroupOptions = ref<UserGroupApi.UserGroupVO[]>([]) // 用户组列表
7877
79-
// 添加当前值的引用
80-
const currentValue = ref<SimpleFlowNode | undefined>()
81-
8278
provide('formFields', formFields)
8379
provide('formType', formType)
8480
provide('roleList', roleOptions)
@@ -88,7 +84,8 @@ provide('deptList', deptOptions)
8884
provide('userGroupList', userGroupOptions)
8985
provide('deptTree', deptTreeOptions)
9086
provide('startUserIds', props.startUserIds)
91-
87+
provide('tasks', [])
88+
provide('processInstance', {})
9289
const message = useMessage() // 国际化
9390
const processNodeTree = ref<SimpleFlowNode | undefined>()
9491
const errorDialogVisible = ref(false)
@@ -112,70 +109,14 @@ const updateModel = () => {
112109
}
113110
}
114111
115-
// 加载流程数据
116-
const loadProcessData = async (data: any) => {
117-
try {
118-
if (data) {
119-
const parsedData = typeof data === 'string' ? JSON.parse(data) : data
120-
processNodeTree.value = parsedData
121-
currentValue.value = parsedData
122-
// 确保数据加载后刷新视图
123-
await nextTick()
124-
if (simpleProcessModelRef.value?.refresh) {
125-
await simpleProcessModelRef.value.refresh()
126-
}
127-
}
128-
} catch (error) {
129-
console.error('加载流程数据失败:', error)
130-
}
131-
}
132-
133-
// 监听属性变化
134-
watch(
135-
() => props.value,
136-
async (newValue, oldValue) => {
137-
if (newValue && newValue !== oldValue) {
138-
await loadProcessData(newValue)
139-
}
140-
},
141-
{ immediate: true, deep: true }
142-
)
143-
144-
// 监听流程节点树变化,自动保存
145-
watch(
146-
() => processNodeTree.value,
147-
async (newValue, oldValue) => {
148-
if (newValue && oldValue && JSON.stringify(newValue) !== JSON.stringify(oldValue)) {
149-
await saveSimpleFlowModel(newValue)
150-
}
151-
},
152-
{ deep: true }
153-
)
154112
155113
const saveSimpleFlowModel = async (simpleModelNode: SimpleFlowNode) => {
156114
if (!simpleModelNode) {
157115
return
158116
}
159117
160-
// 校验节点
161-
errorNodes = []
162-
validateNode(simpleModelNode, errorNodes)
163-
if (errorNodes.length > 0) {
164-
errorDialogVisible.value = true
165-
return
166-
}
167-
168118
try {
169-
if (props.modelId) {
170-
// 编辑模式
171-
const data = {
172-
id: props.modelId,
173-
simpleModel: simpleModelNode
174-
}
175-
await updateBpmSimpleModel(data)
176-
}
177-
// 无论是编辑还是新建模式,都更新当前值并触发事件
178-
currentValue.value = simpleModelNode
119+
processData.value = simpleModelNode
179120
emits('success', simpleModelNode)
180121
} catch (error) {
181122
console.error('保存失败:', error)
@@ -246,61 +187,20 @@ onMounted(async () => {
246187
deptTreeOptions.value = handleTree(deptOptions.value as DeptApi.DeptVO[], 'id')
247188
// 获取用户组列表
248189
userGroupOptions.value = await UserGroupApi.getUserGroupSimpleList()
249-
250190
// 加载流程数据
251-
if (props.modelId) {
252-
// 获取 SIMPLE 设计器模型
253-
const result = await getBpmSimpleModel(props.modelId)
254-
if (result) {
255-
await loadProcessData(result)
256-
} else {
257-
updateModel()
258-
}
259-
} else if (props.value) {
260-
await loadProcessData(props.value)
191+
if (processData.value) {
192+
processNodeTree.value = processData?.value
261193
} else {
262194
updateModel()
263195
}
264196
} finally {
265197
loading.value = false
266-
emits('init-finished')
267198
}
268199
})
269200
270201
const simpleProcessModelRef = ref()
271202
272-
/** 获取当前流程数据 */
273-
const getCurrentFlowData = async () => {
274-
try {
275-
if (simpleProcessModelRef.value) {
276-
const data = await simpleProcessModelRef.value.getCurrentFlowData()
277-
if (data) {
278-
currentValue.value = data
279-
return data
280-
}
281-
}
282-
return currentValue.value
283-
} catch (error) {
284-
console.error('获取流程数据失败:', error)
285-
return currentValue.value
286-
}
287-
}
288-
289-
// 刷新方法
290-
const refresh = async () => {
291-
try {
292-
if (currentValue.value) {
293-
await loadProcessData(currentValue.value)
294-
}
295-
} catch (error) {
296-
console.error('刷新失败:', error)
297-
}
298-
}
299203
300204
defineExpose({
301-
getCurrentFlowData,
302-
updateModel,
303-
loadProcessData,
304-
refresh
305205
})
306206
</script>

src/components/SimpleProcessDesignerV2/src/SimpleProcessModel.vue

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,31 @@
33
<div class="position-absolute top-0px right-0px bg-#fff">
44
<el-row type="flex" justify="end">
55
<el-button-group key="scale-control" size="default">
6+
<el-button size="default" @click="exportJson()"><Icon icon="ep:download" />导出</el-button>
7+
<el-button size="default" @click="importJson()"><Icon icon="ep:upload" />导入</el-button>
8+
<!-- 用于打开本地文件-->
9+
<input
10+
type="file"
11+
id="files"
12+
ref="refFile"
13+
style="display: none"
14+
accept=".json"
15+
@change="importLocalFile"
16+
/>
617
<el-button size="default" :icon="ScaleToOriginal" @click="processReZoom()" />
718
<el-button size="default" :plain="true" :icon="ZoomOut" @click="zoomOut()" />
819
<el-button size="default" class="w-80px"> {{ scaleValue }}% </el-button>
920
<el-button size="default" :plain="true" :icon="ZoomIn" @click="zoomIn()" />
1021
</el-button-group>
22+
<!-- <el-button-->
23+
<!-- v-if="!readonly"-->
24+
<!-- size="default"-->
25+
<!-- class="ml-4px"-->
26+
<!-- type="primary"-->
27+
<!-- :icon="Select"-->
28+
<!-- @click="saveSimpleFlowModel"-->
29+
<!-- >保存模型</el-button-->
30+
<!-- >-->
1131
</el-row>
1232
</div>
1333
<div class="simple-process-model" :style="`transform: scale(${scaleValue / 100});`">
@@ -33,7 +53,8 @@
3353
import ProcessNodeTree from './ProcessNodeTree.vue'
3454
import { SimpleFlowNode, NodeType, NODE_DEFAULT_TEXT } from './consts'
3555
import { useWatchNode } from './node'
36-
import { ZoomOut, ZoomIn, ScaleToOriginal } from '@element-plus/icons-vue'
56+
import { ZoomOut, ZoomIn, ScaleToOriginal, Select } from '@element-plus/icons-vue'
57+
import { isString } from '@/utils/is'
3758
3859
defineOptions({
3960
name: 'SimpleProcessModel'
@@ -85,6 +106,16 @@ const processReZoom = () => {
85106
const errorDialogVisible = ref(false)
86107
let errorNodes: SimpleFlowNode[] = []
87108
109+
const saveSimpleFlowModel = async () => {
110+
errorNodes = []
111+
validateNode(processNodeTree.value, errorNodes)
112+
if (errorNodes.length > 0) {
113+
errorDialogVisible.value = true
114+
return
115+
}
116+
emits('save', processNodeTree.value)
117+
}
118+
88119
// 校验节点设置。 暂时以 showText 为空 未节点错误配置
89120
const validateNode = (node: SimpleFlowNode | undefined, errorNodes: SimpleFlowNode[]) => {
90121
if (node) {
@@ -143,6 +174,36 @@ const getCurrentFlowData = async () => {
143174
defineExpose({
144175
getCurrentFlowData
145176
})
177+
178+
const exportJson = () => {
179+
const blob = new Blob([JSON.stringify(processNodeTree.value)]);
180+
const tempLink = document.createElement('a'); // 创建a标签
181+
const href = window.URL.createObjectURL(blob); // 创建下载的链接
182+
//filename
183+
const fileName = `model.json`;
184+
tempLink.href = href;
185+
tempLink.target = '_blank';
186+
tempLink.download = fileName;
187+
document.body.appendChild(tempLink);
188+
tempLink.click(); // 点击下载
189+
document.body.removeChild(tempLink); // 下载完成移除元素
190+
window.URL.revokeObjectURL(href); // 释放掉blob对象
191+
}
192+
const importJson = () => {
193+
refFile.value.click()
194+
}
195+
const refFile = ref()
196+
// 加载本地文件
197+
const importLocalFile = () => {
198+
const file = refFile.value.files[0]
199+
const reader = new FileReader()
200+
reader.readAsText(file)
201+
reader.onload = function () {
202+
if (isString(this.result)) {
203+
processNodeTree.value = JSON.parse(this.result)
204+
}
205+
}
206+
}
146207
</script>
147208

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

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

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -308,28 +308,6 @@ const props = defineProps({
308308
}
309309
})
310310
311-
// 监听value变化,重新加载流程图
312-
watch(
313-
() => props.value,
314-
(newValue) => {
315-
if (newValue && bpmnModeler) {
316-
createNewDiagram(newValue)
317-
}
318-
},
319-
{ immediate: true }
320-
)
321-
322-
// 监听processId和processName变化
323-
watch(
324-
[() => props.processId, () => props.processName],
325-
([newId, newName]) => {
326-
if (newId && newName && !props.value) {
327-
createNewDiagram(null)
328-
}
329-
},
330-
{ immediate: true }
331-
)
332-
333311
provide('configGlobal', props)
334312
let bpmnModeler: any = null
335313
const defaultZoom = ref(1)
@@ -480,6 +458,7 @@ const initModelListeners = () => {
480458
emit('commandStack-changed', event)
481459
emit('input', xml)
482460
emit('change', xml)
461+
emit('save', xml)
483462
} catch (e: any) {
484463
console.error(`[Process Designer Warn]: ${e.message || e}`)
485464
}

0 commit comments

Comments
 (0)