潘志宝
22 小时以前 221918bba28d2384d03c596a68256d7832e4a0e0
提交 | 用户 | 时间
3e359e 1 <template>
H 2   <div class="simple-process-model-container position-relative">
3     <div class="position-absolute top-0px right-0px bg-#fff">
4       <el-row type="flex" justify="end">
5         <el-button-group key="scale-control" size="default">
6           <el-button size="default" :icon="ScaleToOriginal" @click="processReZoom()" />
7           <el-button size="default" :plain="true" :icon="ZoomOut" @click="zoomOut()" />
8           <el-button size="default" class="w-80px"> {{ scaleValue }}% </el-button>
9           <el-button size="default" :plain="true" :icon="ZoomIn" @click="zoomIn()" />
10         </el-button-group>
11       </el-row>
12     </div>
13     <div class="simple-process-model" :style="`transform: scale(${scaleValue / 100});`">
14       <ProcessNodeTree v-if="processNodeTree" v-model:flow-node="processNodeTree" />
15     </div>
16   </div>
17   <Dialog v-model="errorDialogVisible" title="保存失败" width="400" :fullscreen="false">
18     <div class="mb-2">以下节点内容不完善,请修改后保存</div>
19     <div
20       class="mb-3 b-rounded-1 bg-gray-100 p-2 line-height-normal"
21       v-for="(item, index) in errorNodes"
22       :key="index"
23     >
24       {{ item.name }} : {{ NODE_DEFAULT_TEXT.get(item.type) }}
25     </div>
26     <template #footer>
27       <el-button type="primary" @click="errorDialogVisible = false">知道了</el-button>
28     </template>
29   </Dialog>
30 </template>
31
32 <script setup lang="ts">
33 import ProcessNodeTree from './ProcessNodeTree.vue'
34 import { SimpleFlowNode, NodeType, NODE_DEFAULT_TEXT } from './consts'
35 import { useWatchNode } from './node'
c9a6f7 36 import { ZoomOut, ZoomIn, ScaleToOriginal } from '@element-plus/icons-vue'
H 37
3e359e 38 defineOptions({
H 39   name: 'SimpleProcessModel'
40 })
41
42 const props = defineProps({
43   flowNode: {
44     type: Object as () => SimpleFlowNode,
45     required: true
46   },
47   readonly: {
48     type: Boolean,
49     required: false,
50     default: true
51   }
52 })
c9a6f7 53
3e359e 54 const emits = defineEmits<{
H 55   'save': [node: SimpleFlowNode | undefined]
56 }>()
57
58 const processNodeTree = useWatchNode(props)
59
60 provide('readonly', props.readonly)
61 let scaleValue = ref(100)
62 const MAX_SCALE_VALUE = 200
63 const MIN_SCALE_VALUE = 50
c9a6f7 64
3e359e 65 // 放大
H 66 const zoomIn = () => {
67   if (scaleValue.value == MAX_SCALE_VALUE) {
68     return
69   }
70   scaleValue.value += 10
71 }
c9a6f7 72
3e359e 73 // 缩小
H 74 const zoomOut = () => {
75   if (scaleValue.value == MIN_SCALE_VALUE) {
76     return
77   }
78   scaleValue.value -= 10
79 }
c9a6f7 80
3e359e 81 const processReZoom = () => {
H 82   scaleValue.value = 100
83 }
84
85 const errorDialogVisible = ref(false)
86 let errorNodes: SimpleFlowNode[] = []
c9a6f7 87
3e359e 88 // 校验节点设置。 暂时以 showText 为空 未节点错误配置
H 89 const validateNode = (node: SimpleFlowNode | undefined, errorNodes: SimpleFlowNode[]) => {
90   if (node) {
91     const { type, showText, conditionNodes } = node
92     if (type == NodeType.END_EVENT_NODE) {
93       return
94     }
95     if (type == NodeType.START_USER_NODE) {
96       // 发起人节点暂时不用校验,直接校验孩子节点
97       validateNode(node.childNode, errorNodes)
98     }
99
100     if (
101       type === NodeType.USER_TASK_NODE ||
102       type === NodeType.COPY_TASK_NODE ||
103       type === NodeType.CONDITION_NODE
104     ) {
105       if (!showText) {
106         errorNodes.push(node)
107       }
108       validateNode(node.childNode, errorNodes)
109     }
110
111     if (
112       type == NodeType.CONDITION_BRANCH_NODE ||
113       type == NodeType.PARALLEL_BRANCH_NODE ||
114       type == NodeType.INCLUSIVE_BRANCH_NODE
115     ) {
116       // 分支节点
117       // 1. 先校验各个分支
118       conditionNodes?.forEach((item) => {
119         validateNode(item, errorNodes)
120       })
121       // 2. 校验孩子节点
122       validateNode(node.childNode, errorNodes)
123     }
124   }
125 }
c9a6f7 126
H 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 })
3e359e 146 </script>
H 147
148 <style lang="scss" scoped></style>