feat: 删除设计流程中两个流程设计器的保存模型按钮,并在点击保存/提交按钮时直接获取内部组件xml逻辑

pull/631/head
GoldenZqqq 2024-12-27 14:32:39 +08:00
parent 40c2cb72ff
commit e50cd2231c
5 changed files with 123 additions and 62 deletions

View File

@ -8,15 +8,6 @@
<el-button size="default" class="w-80px"> {{ scaleValue }}% </el-button>
<el-button size="default" :plain="true" :icon="ZoomIn" @click="zoomIn()" />
</el-button-group>
<el-button
v-if="!readonly"
size="default"
class="ml-4px"
type="primary"
:icon="Select"
@click="saveSimpleFlowModel"
>保存模型</el-button
>
</el-row>
</div>
<div class="simple-process-model" :style="`transform: scale(${scaleValue / 100});`">
@ -42,7 +33,8 @@
import ProcessNodeTree from './ProcessNodeTree.vue'
import { SimpleFlowNode, NodeType, NODE_DEFAULT_TEXT } from './consts'
import { useWatchNode } from './node'
import { Select, ZoomOut, ZoomIn, ScaleToOriginal } from '@element-plus/icons-vue'
import { ZoomOut, ZoomIn, ScaleToOriginal } from '@element-plus/icons-vue'
defineOptions({
name: 'SimpleProcessModel'
})
@ -58,6 +50,7 @@ const props = defineProps({
default: true
}
})
const emits = defineEmits<{
'save': [node: SimpleFlowNode | undefined]
}>()
@ -68,6 +61,7 @@ provide('readonly', props.readonly)
let scaleValue = ref(100)
const MAX_SCALE_VALUE = 200
const MIN_SCALE_VALUE = 50
//
const zoomIn = () => {
if (scaleValue.value == MAX_SCALE_VALUE) {
@ -75,6 +69,7 @@ const zoomIn = () => {
}
scaleValue.value += 10
}
//
const zoomOut = () => {
if (scaleValue.value == MIN_SCALE_VALUE) {
@ -82,21 +77,14 @@ const zoomOut = () => {
}
scaleValue.value -= 10
}
const processReZoom = () => {
scaleValue.value = 100
}
const errorDialogVisible = ref(false)
let errorNodes: SimpleFlowNode[] = []
const saveSimpleFlowModel = async () => {
errorNodes = []
validateNode(processNodeTree.value, errorNodes)
if (errorNodes.length > 0) {
errorDialogVisible.value = true
return
}
emits('save', processNodeTree.value)
}
// showText
const validateNode = (node: SimpleFlowNode | undefined, errorNodes: SimpleFlowNode[]) => {
if (node) {
@ -135,6 +123,21 @@ const validateNode = (node: SimpleFlowNode | undefined, errorNodes: SimpleFlowNo
}
}
}
/** 获取当前流程数据 */
const getCurrentFlowData = () => {
errorNodes = []
validateNode(processNodeTree.value, errorNodes)
if (errorNodes.length > 0) {
errorDialogVisible.value = true
return undefined
}
return processNodeTree.value
}
defineExpose({
getCurrentFlowData
})
</script>
<style lang="scss" scoped></style>

View File

@ -160,13 +160,6 @@
<XButton preIcon="ep:refresh" @click="processRestart()" />
</el-tooltip>
</ElButtonGroup>
<XButton
preIcon="ep:plus"
title="保存模型"
@click="processSave"
:type="props.headerButtonType"
:disabled="simulationStatus"
/>
</template>
<!-- 用于打开本地文件-->
<input

View File

@ -205,11 +205,53 @@ onBeforeUnmount(() => {
w.bpmnInstances = null
}
})
/** 获取XML字符串 */
const saveXML = async () => {
if (!modeler.value) {
return { xml: undefined }
}
try {
return await modeler.value.saveXML({ format: true })
} catch (error) {
console.error('获取XML失败:', error)
return { xml: undefined }
}
}
/** 获取SVG字符串 */
const saveSVG = async () => {
if (!modeler.value) {
return { svg: undefined }
}
try {
return await modeler.value.saveSVG()
} catch (error) {
console.error('获取SVG失败:', error)
return { svg: undefined }
}
}
/** 刷新视图 */
const refresh = () => {
if (processDesigner.value?.refresh) {
processDesigner.value.refresh()
}
}
//
defineExpose({
modeler,
isModelerReady,
saveXML,
saveSVG,
refresh
})
</script>
<style lang="scss">
.process-panel__container {
position: absolute;
top: 90px;
top: 180px;
right: 60px;
}
</style>

View File

@ -7,6 +7,7 @@
:model-key="modelData.key"
:model-name="modelData.name"
:value="modelData.bpmnXml"
ref="bpmnEditorRef"
@success="handleDesignSuccess"
/>
</template>
@ -19,6 +20,7 @@
:model-key="modelData.key"
:model-name="modelData.name"
:value="modelData.bpmnXml"
ref="simpleEditorRef"
@success="handleDesignSuccess"
/>
</template>
@ -38,7 +40,8 @@ const props = defineProps({
const emit = defineEmits(['update:modelValue', 'success'])
const xmlString = ref<string>()
const bpmnEditorRef = ref()
const simpleEditorRef = ref()
//
const modelData = computed({
@ -46,21 +49,56 @@ const modelData = computed({
set: (val) => emit('update:modelValue', val)
})
// modelValue,XML
watch(
() => props.modelValue,
(newVal) => {
if (newVal?.bpmnXml) {
xmlString.value = newVal.bpmnXml
/** 表单校验 */
const validate = async () => {
try {
//
const editorRef =
modelData.value.type === BpmModelType.BPMN ? bpmnEditorRef.value : simpleEditorRef.value
if (!editorRef) {
throw new Error('流程设计器未初始化')
}
},
{ immediate: true, deep: true }
)
// XML
const bpmnXml = await getXmlString()
console.warn(bpmnXml, 'bpmnXml')
if (!bpmnXml) {
throw new Error('请设计流程')
}
return true
} catch (error) {
throw error
}
}
/** 获取当前XML字符串 */
const getXmlString = async () => {
try {
if (modelData.value.type === BpmModelType.BPMN) {
console.warn('bpmnEditorRef.value', bpmnEditorRef.value)
// BPMN
if (bpmnEditorRef.value) {
const { xml } = await bpmnEditorRef.value.saveXML()
return xml
}
} else {
// Simple
if (simpleEditorRef.value) {
const flowData = simpleEditorRef.value.getCurrentFlowData()
return flowData ? JSON.stringify(flowData) : undefined
}
}
return undefined
} catch (error) {
console.error('获取流程数据失败:', error)
return undefined
}
}
/** 处理设计器保存成功 */
const handleDesignSuccess = (bpmnXml?: string) => {
if (bpmnXml) {
xmlString.value = bpmnXml
modelData.value = {
...modelData.value,
bpmnXml
@ -69,34 +107,11 @@ const handleDesignSuccess = (bpmnXml?: string) => {
}
}
/** 表单校验 */
const validate = async () => {
// XML
const currentXml = xmlString.value || modelData.value?.bpmnXml
// XML
if (modelData.value.id && currentXml) {
return true
}
// XML
if (!currentXml) {
throw new Error('请设计流程')
}
return true
}
/** 是否显示设计器 */
const showDesigner = computed(() => {
return Boolean(modelData.value?.key && modelData.value?.name)
})
/** 获取当前XML字符串 */
const getXmlString = () => {
return xmlString.value || modelData.value?.bpmnXml || ''
}
defineExpose({
validate,
getXmlString

View File

@ -7,7 +7,7 @@
>
<!-- 左侧标题 -->
<div class="w-200px flex items-center overflow-hidden">
<Icon icon="ep:arrow-left" class="cursor-pointer flex-shrink-0" @click="router.back()" />
<Icon icon="ep:arrow-left" class="cursor-pointer flex-shrink-0" @click="handleBack" />
<span class="ml-10px text-16px truncate" :title="formData.name || '创建流程'">
{{ formData.name || '创建流程' }}
</span>
@ -322,6 +322,14 @@ const handleDesignSuccess = (bpmnXml?: string) => {
}
}
/** 返回列表页 */
const handleBack = () => {
//
delView(unref(router.currentRoute))
//
router.push({ name: 'BpmModel' })
}
/** 初始化 */
onMounted(async () => {
await initData()