feat: 删除设计流程中两个流程设计器的保存模型按钮,并在点击保存/提交按钮时直接获取内部组件xml逻辑
parent
40c2cb72ff
commit
e50cd2231c
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue