Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<template>
<div v-loading="loading" class="overflow-auto">
<SimpleProcessModel
ref="simpleProcessModelRef"
v-if="processNodeTree"
:flow-node="processNodeTree"
:readonly="false"
Expand Down Expand Up @@ -225,4 +226,19 @@ onMounted(async () => {
loading.value = false
}
})

const simpleProcessModelRef = ref()

/** 获取当前流程数据 */
const getCurrentFlowData = async () => {
if (simpleProcessModelRef.value) {
return await simpleProcessModelRef.value.getCurrentFlowData()
}
return undefined
}

defineExpose({
getCurrentFlowData,
updateModel
})
</script>
46 changes: 27 additions & 19 deletions src/components/SimpleProcessDesignerV2/src/SimpleProcessModel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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});`">
Expand All @@ -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'
})
Expand All @@ -58,6 +50,7 @@ const props = defineProps({
default: true
}
})

const emits = defineEmits<{
'save': [node: SimpleFlowNode | undefined]
}>()
Expand All @@ -68,35 +61,30 @@ 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) {
return
}
scaleValue.value += 10
}

// 缩小
const zoomOut = () => {
if (scaleValue.value == MIN_SCALE_VALUE) {
return
}
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) {
Expand Down Expand Up @@ -135,6 +123,26 @@ const validateNode = (node: SimpleFlowNode | undefined, errorNodes: SimpleFlowNo
}
}
}

/** 获取当前流程数据 */
const getCurrentFlowData = async () => {
try {
errorNodes = []
validateNode(processNodeTree.value, errorNodes)
if (errorNodes.length > 0) {
errorDialogVisible.value = true
return undefined
}
return processNodeTree.value
} catch (error) {
console.error('获取流程数据失败:', error)
return undefined
}
}

defineExpose({
getCurrentFlowData
})
</script>

<style lang="scss" scoped></style>
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
44 changes: 43 additions & 1 deletion src/views/bpm/model/editor/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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>
10 changes: 2 additions & 8 deletions src/views/bpm/model/form/BasicInfo.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
<template>
<el-form
ref="formRef"
:model="modelData"
:rules="rules"
label-width="120px"
class="mt-20px w-600px"
>
<el-form ref="formRef" :model="modelData" :rules="rules" label-width="120px" class="mt-20px">
<el-form-item label="流程标识" prop="key" class="mb-20px">
<div class="flex items-center">
<el-input
class="!w-480px"
class="!w-440px"
v-model="modelData.key"
:disabled="!!modelData.id"
placeholder="请输入流标标识"
Expand Down
96 changes: 61 additions & 35 deletions src/views/bpm/model/form/ProcessDesign.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
:model-key="modelData.key"
:model-name="modelData.name"
:value="modelData.bpmnXml"
ref="bpmnEditorRef"
@success="handleDesignSuccess"
/>
</template>
Expand All @@ -19,6 +20,7 @@
:model-key="modelData.key"
:model-name="modelData.name"
:value="modelData.bpmnXml"
ref="simpleEditorRef"
@success="handleDesignSuccess"
/>
</template>
Expand All @@ -38,67 +40,91 @@ const props = defineProps({

const emit = defineEmits(['update:modelValue', 'success'])

const xmlString = ref<string>()
const bpmnEditorRef = ref()
const simpleEditorRef = ref()

// 创建本地数据副本
const modelData = computed({
get: () => props.modelValue,
set: (val) => emit('update:modelValue', val)
})

// 监听modelValue变化,确保XML数据同步
watch(
() => props.modelValue,
(newVal) => {
if (newVal?.bpmnXml) {
xmlString.value = newVal.bpmnXml
/** 获取当前流程数据 */
const getProcessData = async () => {
try {
if (modelData.value.type === BpmModelType.BPMN) {
// BPMN设计器
if (bpmnEditorRef.value) {
const { xml } = await bpmnEditorRef.value.saveXML()
if (xml) {
return xml
}
}
} else {
// Simple设计器
if (simpleEditorRef.value) {
const flowData = await simpleEditorRef.value.getCurrentFlowData()
if (flowData) {
return flowData // 直接返回流程数据对象,不需要转换为字符串
}
}
}
},
{ immediate: true, deep: true }
)

/** 处理设计器保存成功 */
const handleDesignSuccess = (bpmnXml?: string) => {
if (bpmnXml) {
xmlString.value = bpmnXml
modelData.value = {
...modelData.value,
bpmnXml
}
emit('success', bpmnXml)
return undefined
} catch (error) {
console.error('获取流程数据失败:', error)
return undefined
}
}

/** 表单校验 */
const validate = async () => {
// 获取最新的XML数据
const currentXml = xmlString.value || modelData.value?.bpmnXml
try {
// 根据流程类型获取对应的编辑器引用
const editorRef =
modelData.value.type === BpmModelType.BPMN ? bpmnEditorRef.value : simpleEditorRef.value
if (!editorRef) {
throw new Error('流程设计器未初始化')
}

// 获取最新的流程数据
const processData = await getProcessData()
if (!processData) {
throw new Error('请设计流程')
}

// 如果是修改场景且有XML数据(无论是新的还是原有的)
if (modelData.value.id && currentXml) {
return true
} catch (error) {
throw error
}
}

// 新增场景必须有XML数据
if (!currentXml) {
throw new Error('请设计流程')
/** 处理设计器保存成功 */
const handleDesignSuccess = (data?: any) => {
if (data) {
if (modelData.value.type === BpmModelType.BPMN) {
modelData.value = {
...modelData.value,
bpmnXml: data,
simpleModel: null
}
} else {
modelData.value = {
...modelData.value,
bpmnXml: null,
simpleModel: data
}
}
emit('success', data)
}

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
getProcessData
})
</script>
Loading