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