dengzedong
5 天以前 f9b459a3fefd5fab0ee8e19268adb9d9eadab2a7
提交 | 用户 | 时间
3e359e 1 <template>
H 2   <div class="branch-node-wrapper">
3     <div class="branch-node-container">
4       <div
5         v-if="readonly"
6         class="branch-node-readonly"
7         :class="`${useTaskStatusClass(currentNode?.activityStatus)}`"
8       >
9         <span class="iconfont icon-parallel icon-size parallel"></span>
10       </div>
11       <el-button v-else class="branch-node-add" color="#626aef" @click="addCondition" plain
12         >添加分支</el-button
13       >
14       <div
15         class="branch-node-item"
16         v-for="(item, index) in currentNode.conditionNodes"
17         :key="index"
18       >
19         <template v-if="index == 0">
20           <div class="branch-line-first-top"></div>
21           <div class="branch-line-first-bottom"></div>
22         </template>
23         <template v-if="index + 1 == currentNode.conditionNodes?.length">
24           <div class="branch-line-last-top"></div>
25           <div class="branch-line-last-bottom"></div>
26         </template>
27         <div class="node-wrapper">
28           <div class="node-container">
29             <div class="node-box" :class="`${useTaskStatusClass(item.activityStatus)}`">
30               <div class="branch-node-title-container">
31                 <div v-if="showInputs[index]">
32                   <input
33                     type="text"
34                     class="input-max-width editable-title-input"
35                     @blur="blurEvent(index)"
36                     v-mountedFocus
37                     v-model="item.name"
38                   />
39                 </div>
40                 <div v-else class="branch-title" @click="clickEvent(index)"> {{ item.name }} </div>
41                 <div class="branch-priority">无优先级</div>
42               </div>
43               <div class="branch-node-content" @click="conditionNodeConfig(item.id)">
44                 <div class="branch-node-text" :title="item.showText" v-if="item.showText">
45                   {{ item.showText }}
46                 </div>
47                 <div class="branch-node-text" v-else>
48                   {{ NODE_DEFAULT_TEXT.get(NodeType.CONDITION_NODE) }}
49                 </div>
50               </div>
51               <div v-if="!readonly" class="node-toolbar">
52                 <div class="toolbar-icon">
53                   <Icon
54                     color="#0089ff"
55                     icon="ep:circle-close-filled"
56                     :size="18"
57                     @click="deleteCondition(index)"
58                   />
59                 </div>
60               </div>
61             </div>
62             <NodeHandler v-model:child-node="item.childNode" :current-node="item" />
63           </div>
64         </div>
65         <!-- 递归显示子节点  -->
66         <ProcessNodeTree
67           v-if="item && item.childNode"
68           :parent-node="item"
69           v-model:flow-node="item.childNode"
70           @find:recursive-find-parent-node="recursiveFindParentNode"
71         />
72       </div>
73     </div>
74     <NodeHandler
75       v-if="currentNode"
76       v-model:child-node="currentNode.childNode"
77       :current-node="currentNode"
78     />
79   </div>
80 </template>
81
82 <script setup lang="ts">
83 import NodeHandler from '../NodeHandler.vue'
84 import ProcessNodeTree from '../ProcessNodeTree.vue'
85 import { SimpleFlowNode, NodeType, NODE_DEFAULT_TEXT } from '../consts'
86 import { useTaskStatusClass } from '../node'
87 import { generateUUID } from '@/utils'
88 const { proxy } = getCurrentInstance() as any
89 defineOptions({
90   name: 'ParallelNode'
91 })
92 const props = defineProps({
93   flowNode: {
94     type: Object as () => SimpleFlowNode,
95     required: true
96   }
97 })
98 // 定义事件,更新父组件
99 const emits = defineEmits<{
100   'update:modelValue': [node: SimpleFlowNode | undefined]
101   'find:parentNode': [nodeList: SimpleFlowNode[], nodeType: number]
102   'find:recursiveFindParentNode': [
103     nodeList: SimpleFlowNode[],
104     curentNode: SimpleFlowNode,
105     nodeType: number
106   ]
107 }>()
108
109 const currentNode = ref<SimpleFlowNode>(props.flowNode)
110 // 是否只读
111 const readonly = inject<Boolean>('readonly')
112
113 watch(
114   () => props.flowNode,
115   (newValue) => {
116     currentNode.value = newValue
117   }
118 )
119
120 const showInputs = ref<boolean[]>([])
121 // 失去焦点
122 const blurEvent = (index: number) => {
123   showInputs.value[index] = false
124   const conditionNode = currentNode.value.conditionNodes?.at(index) as SimpleFlowNode
125   conditionNode.name = conditionNode.name || `并行${index + 1}`
126 }
127
128 // 点击条件名称
129 const clickEvent = (index: number) => {
130   showInputs.value[index] = true
131 }
132
133 const conditionNodeConfig = (nodeId: string) => {
134   const conditionNode = proxy.$refs[nodeId][0]
135   conditionNode.open()
136 }
137
138 // 新增条件
139 const addCondition = () => {
140   const conditionNodes = currentNode.value.conditionNodes
141   if (conditionNodes) {
142     const len = conditionNodes.length
143     let lastIndex = len - 1
144     const conditionData: SimpleFlowNode = {
145       id: 'Flow_' + generateUUID(),
146       name: '并行' + len,
147       showText: '无需配置条件同时执行',
148       type: NodeType.CONDITION_NODE,
149       childNode: undefined,
150       conditionNodes: []
151     }
152     conditionNodes.splice(lastIndex, 0, conditionData)
153   }
154 }
155
156 // 删除条件
157 const deleteCondition = (index: number) => {
158   const conditionNodes = currentNode.value.conditionNodes
159   if (conditionNodes) {
160     conditionNodes.splice(index, 1)
161     if (conditionNodes.length == 1) {
162       const childNode = currentNode.value.childNode
163       // 更新此节点为后续孩子节点
164       emits('update:modelValue', childNode)
165     }
166   }
167 }
168
169 // 递归从父节点中查询匹配的节点
170 const recursiveFindParentNode = (
171   nodeList: SimpleFlowNode[],
172   node: SimpleFlowNode,
173   nodeType: number
174 ) => {
175   if (!node || node.type === NodeType.START_USER_NODE) {
176     return
177   }
178   if (node.type === nodeType) {
179     nodeList.push(node)
180   }
181   // 条件节点 (NodeType.CONDITION_NODE) 比较特殊。需要调用其父节点并行节点(NodeType.PARALLEL_NODE) 继续查找
182   emits('find:parentNode', nodeList, nodeType)
183 }
184 </script>