فهرست منبع

【功能优化】条件分支、包容分支后面不允许直接添加并行分支

YunaiV 9 ماه پیش
والد
کامیت
a097560f81

+ 15 - 9
src/components/SimpleProcessDesignerV2/src/NodeHandler.vue

@@ -27,14 +27,7 @@
             </div>
             <div class="handler-item-text">条件分支</div>
           </div>
-          <div
-            class="handler-item"
-            @click="addNode(NodeType.PARALLEL_BRANCH_NODE)"
-            v-if="
-              NodeType.CONDITION_BRANCH_NODE !== currentNode?.type &&
-              NodeType.INCLUSIVE_BRANCH_NODE !== currentNode?.type
-            "
-          >
+          <div class="handler-item" @click="addNode(NodeType.PARALLEL_BRANCH_NODE)">
             <div class="handler-item-icon parallel">
               <span class="iconfont icon-size icon-parallel"></span>
             </div>
@@ -70,8 +63,10 @@ import { generateUUID } from '@/utils'
 defineOptions({
   name: 'NodeHandler'
 })
-const popoverShow = ref(false)
 
+const message = useMessage() // 消息弹窗
+
+const popoverShow = ref(false)
 const props = defineProps({
   childNode: {
     type: Object as () => SimpleFlowNode,
@@ -87,6 +82,17 @@ const emits = defineEmits(['update:childNode'])
 const readonly = inject<Boolean>('readonly') // 是否只读
 
 const addNode = (type: number) => {
+  // 校验:条件分支、包容分支后面,不允许直接添加并行分支
+  if (
+    type === NodeType.PARALLEL_BRANCH_NODE &&
+    [NodeType.CONDITION_BRANCH_NODE, NodeType.INCLUSIVE_BRANCH_NODE].includes(
+      props.currentNode?.type
+    )
+  ) {
+    message.error('条件分支、包容分支后面,不允许直接添加并行分支')
+    return
+  }
+
   popoverShow.value = false
   if (type === NodeType.USER_TASK_NODE) {
     const id = 'Activity_' + generateUUID()

+ 9 - 2
src/components/SimpleProcessDesignerV2/src/nodes/CopyTaskNode.vue

@@ -3,7 +3,10 @@
     <div class="node-container">
       <div
         class="node-box"
-        :class="[{ 'node-config-error': !currentNode.showText }, `${useTaskStatusClass(currentNode?.activityStatus)}`]"
+        :class="[
+          { 'node-config-error': !currentNode.showText },
+          `${useTaskStatusClass(currentNode?.activityStatus)}`
+        ]"
       >
         <div class="node-title-container">
           <div class="node-title-icon copy-task"><span class="iconfont icon-copy"></span></div>
@@ -37,7 +40,11 @@
       </div>
 
       <!-- 传递子节点给添加节点组件。会在子节点前面添加节点 -->
-      <NodeHandler v-if="currentNode" v-model:child-node="currentNode.childNode" :current-node="currentNode"/>
+      <NodeHandler
+        v-if="currentNode"
+        v-model:child-node="currentNode.childNode"
+        :current-node="currentNode"
+      />
     </div>
     <CopyTaskNodeConfig
       v-if="!readonly && currentNode"

+ 18 - 4
src/components/SimpleProcessDesignerV2/src/nodes/ExclusiveNode.vue

@@ -1,7 +1,11 @@
 <template>
   <div class="branch-node-wrapper">
     <div class="branch-node-container">
-      <div v-if="readonly" class="branch-node-readonly" :class="`${useTaskStatusClass(currentNode?.activityStatus)}`">
+      <div
+        v-if="readonly"
+        class="branch-node-readonly"
+        :class="`${useTaskStatusClass(currentNode?.activityStatus)}`"
+      >
         <span class="iconfont icon-exclusive icon-size condition"></span>
       </div>
       <el-button v-else class="branch-node-add" color="#67c23a" @click="addCondition" plain
@@ -23,7 +27,13 @@
         </template>
         <div class="node-wrapper">
           <div class="node-container">
-            <div class="node-box" :class="[{ 'node-config-error': !item.showText }, `${useTaskStatusClass(item.activityStatus)}`]">
+            <div
+              class="node-box"
+              :class="[
+                { 'node-config-error': !item.showText },
+                `${useTaskStatusClass(item.activityStatus)}`
+              ]"
+            >
               <div class="branch-node-title-container">
                 <div v-if="!readonly && showInputs[index]">
                   <input
@@ -87,7 +97,11 @@
         />
       </div>
     </div>
-    <NodeHandler v-if="currentNode" v-model:child-node="currentNode.childNode" :current-node="currentNode" />
+    <NodeHandler
+      v-if="currentNode"
+      v-model:child-node="currentNode.childNode"
+      :current-node="currentNode"
+    />
   </div>
 </template>
 
@@ -120,7 +134,7 @@ const emits = defineEmits<{
   ]
 }>()
 // 是否只读
-const readonly = inject<Boolean>('readonly') 
+const readonly = inject<Boolean>('readonly')
 const currentNode = ref<SimpleFlowNode>(props.flowNode)
 watch(
   () => props.flowNode,

+ 30 - 7
src/components/SimpleProcessDesignerV2/src/nodes/InclusiveNode.vue

@@ -1,10 +1,16 @@
 <template>
   <div class="branch-node-wrapper">
     <div class="branch-node-container">
-      <div v-if="readonly" class="branch-node-readonly" :class="`${useTaskStatusClass(currentNode?.activityStatus)}`" >
+      <div
+        v-if="readonly"
+        class="branch-node-readonly"
+        :class="`${useTaskStatusClass(currentNode?.activityStatus)}`"
+      >
         <span class="iconfont icon-inclusive icon-size inclusive"></span>
       </div>
-      <el-button v-else class="branch-node-add" color="#345da2" @click="addCondition"  plain>添加条件</el-button>
+      <el-button v-else class="branch-node-add" color="#345da2" @click="addCondition" plain
+        >添加条件</el-button
+      >
       <div
         class="branch-node-item"
         v-for="(item, index) in currentNode.conditionNodes"
@@ -20,7 +26,13 @@
         </template>
         <div class="node-wrapper">
           <div class="node-container">
-            <div class="node-box" :class="[{ 'node-config-error': !item.showText }, `${useTaskStatusClass(item.activityStatus)}`]">
+            <div
+              class="node-box"
+              :class="[
+                { 'node-config-error': !item.showText },
+                `${useTaskStatusClass(item.activityStatus)}`
+              ]"
+            >
               <div class="branch-node-title-container">
                 <div v-if="showInputs[index]">
                   <input
@@ -41,7 +53,10 @@
                   {{ NODE_DEFAULT_TEXT.get(NodeType.CONDITION_NODE) }}
                 </div>
               </div>
-              <div class="node-toolbar" v-if="!readonly && index + 1 !== currentNode.conditionNodes?.length">
+              <div
+                class="node-toolbar"
+                v-if="!readonly && index + 1 !== currentNode.conditionNodes?.length"
+              >
                 <div class="toolbar-icon">
                   <Icon
                     color="#0089ff"
@@ -61,13 +76,17 @@
 
               <div
                 class="branch-node-move move-node-right"
-                v-if="!readonly && currentNode.conditionNodes && index < currentNode.conditionNodes.length - 2"
+                v-if="
+                  !readonly &&
+                  currentNode.conditionNodes &&
+                  index < currentNode.conditionNodes.length - 2
+                "
                 @click="moveNode(index, 1)"
               >
                 <Icon icon="ep:arrow-right" />
               </div>
             </div>
-            <NodeHandler v-model:child-node="item.childNode" :current-node="item"/>
+            <NodeHandler v-model:child-node="item.childNode" :current-node="item" />
           </div>
         </div>
         <ConditionNodeConfig :node-index="index" :condition-node="item" :ref="item.id" />
@@ -80,7 +99,11 @@
         />
       </div>
     </div>
-    <NodeHandler v-if="currentNode" v-model:child-node="currentNode.childNode" :current-node="currentNode"/>
+    <NodeHandler
+      v-if="currentNode"
+      v-model:child-node="currentNode.childNode"
+      :current-node="currentNode"
+    />
   </div>
 </template>
 

+ 16 - 6
src/components/SimpleProcessDesignerV2/src/nodes/ParallelNode.vue

@@ -1,10 +1,16 @@
 <template>
   <div class="branch-node-wrapper">
     <div class="branch-node-container">
-      <div v-if="readonly" class="branch-node-readonly" :class="`${useTaskStatusClass(currentNode?.activityStatus)}`">
+      <div
+        v-if="readonly"
+        class="branch-node-readonly"
+        :class="`${useTaskStatusClass(currentNode?.activityStatus)}`"
+      >
         <span class="iconfont icon-parallel icon-size parallel"></span>
       </div>
-      <el-button v-else class="branch-node-add" color="#626aef" @click="addCondition"  plain>添加分支</el-button>
+      <el-button v-else class="branch-node-add" color="#626aef" @click="addCondition" plain
+        >添加分支</el-button
+      >
       <div
         class="branch-node-item"
         v-for="(item, index) in currentNode.conditionNodes"
@@ -42,7 +48,7 @@
                   {{ NODE_DEFAULT_TEXT.get(NodeType.CONDITION_NODE) }}
                 </div>
               </div>
-              <div  v-if="!readonly" class="node-toolbar">
+              <div v-if="!readonly" class="node-toolbar">
                 <div class="toolbar-icon">
                   <Icon
                     color="#0089ff"
@@ -53,7 +59,7 @@
                 </div>
               </div>
             </div>
-            <NodeHandler v-model:child-node="item.childNode" :current-node="item"/>
+            <NodeHandler v-model:child-node="item.childNode" :current-node="item" />
           </div>
         </div>
         <!-- 递归显示子节点  -->
@@ -65,7 +71,11 @@
         />
       </div>
     </div>
-    <NodeHandler v-if="currentNode" v-model:child-node="currentNode.childNode" :current-node="currentNode" />
+    <NodeHandler
+      v-if="currentNode"
+      v-model:child-node="currentNode.childNode"
+      :current-node="currentNode"
+    />
   </div>
 </template>
 
@@ -98,7 +108,7 @@ const emits = defineEmits<{
 
 const currentNode = ref<SimpleFlowNode>(props.flowNode)
 // 是否只读
-const readonly = inject<Boolean>('readonly') 
+const readonly = inject<Boolean>('readonly')
 
 watch(
   () => props.flowNode,

+ 69 - 71
src/components/SimpleProcessDesignerV2/src/nodes/StartUserNode.vue

@@ -3,7 +3,10 @@
     <div class="node-container">
       <div
         class="node-box"
-        :class="[{ 'node-config-error': !currentNode.showText }, `${useTaskStatusClass(currentNode?.activityStatus)}`]"
+        :class="[
+          { 'node-config-error': !currentNode.showText },
+          `${useTaskStatusClass(currentNode?.activityStatus)}`
+        ]"
       >
         <div class="node-title-container">
           <div class="node-title-icon start-user"
@@ -33,73 +36,68 @@
         </div>
       </div>
       <!-- 传递子节点给添加节点组件。会在子节点前面添加节点 -->
-      <NodeHandler v-if="currentNode" v-model:child-node="currentNode.childNode" :current-node="currentNode" />
+      <NodeHandler
+        v-if="currentNode"
+        v-model:child-node="currentNode.childNode"
+        :current-node="currentNode"
+      />
     </div>
   </div>
   <StartUserNodeConfig v-if="!readonly && currentNode" ref="nodeSetting" :flow-node="currentNode" />
-   <!-- 审批记录 -->
-   <el-dialog :title="dialogTitle || '审批记录'" v-model="dialogVisible" width="1000px"  append-to-body>
-      <el-row>
-        <el-table
-          :data="selectTasks"
-          size="small"
-          border
-          header-cell-class-name="table-header-gray"
-        >
-          <el-table-column
-            label="序号"
-            header-align="center"
-            align="center"
-            type="index"
-            width="50"
-          />
-          <el-table-column
-            label="审批人"
-            min-width="100"
-            align="center"
-          >
-            <template #default="scope">
-              {{ scope.row.assigneeUser?.nickname || scope.row.ownerUser?.nickname }}
-            </template>
-          </el-table-column>
-         
-          <el-table-column label="部门" min-width="100" align="center">
-            <template #default="scope">
-              {{ scope.row.assigneeUser?.deptName || scope.row.ownerUser?.deptName }}
-            </template>
-          </el-table-column>
-          <el-table-column
-            :formatter="dateFormatter"
-            align="center"
-            label="开始时间"
-            prop="createTime"
-            min-width="140"
-          />
-          <el-table-column
-            :formatter="dateFormatter"
-            align="center"
-            label="结束时间"
-            prop="endTime"
-            min-width="140"
-          />
-          <el-table-column align="center" label="审批状态" prop="status" min-width="90">
-            <template #default="scope">
-              <dict-tag :type="DICT_TYPE.BPM_TASK_STATUS" :value="scope.row.status" />
-            </template>
-          </el-table-column>
-          <el-table-column
-            align="center"
-            label="审批建议"
-            prop="reason"
-            min-width="120"
-          />
-          <el-table-column align="center" label="耗时" prop="durationInMillis" width="100">
-            <template #default="scope">
-              {{ formatPast2(scope.row.durationInMillis) }}
-            </template>
-          </el-table-column>
-        </el-table>
-      </el-row>
+  <!-- 审批记录 -->
+  <el-dialog
+    :title="dialogTitle || '审批记录'"
+    v-model="dialogVisible"
+    width="1000px"
+    append-to-body
+  >
+    <el-row>
+      <el-table :data="selectTasks" size="small" border header-cell-class-name="table-header-gray">
+        <el-table-column
+          label="序号"
+          header-align="center"
+          align="center"
+          type="index"
+          width="50"
+        />
+        <el-table-column label="审批人" min-width="100" align="center">
+          <template #default="scope">
+            {{ scope.row.assigneeUser?.nickname || scope.row.ownerUser?.nickname }}
+          </template>
+        </el-table-column>
+
+        <el-table-column label="部门" min-width="100" align="center">
+          <template #default="scope">
+            {{ scope.row.assigneeUser?.deptName || scope.row.ownerUser?.deptName }}
+          </template>
+        </el-table-column>
+        <el-table-column
+          :formatter="dateFormatter"
+          align="center"
+          label="开始时间"
+          prop="createTime"
+          min-width="140"
+        />
+        <el-table-column
+          :formatter="dateFormatter"
+          align="center"
+          label="结束时间"
+          prop="endTime"
+          min-width="140"
+        />
+        <el-table-column align="center" label="审批状态" prop="status" min-width="90">
+          <template #default="scope">
+            <dict-tag :type="DICT_TYPE.BPM_TASK_STATUS" :value="scope.row.status" />
+          </template>
+        </el-table-column>
+        <el-table-column align="center" label="审批建议" prop="reason" min-width="120" />
+        <el-table-column align="center" label="耗时" prop="durationInMillis" width="100">
+          <template #default="scope">
+            {{ formatPast2(scope.row.durationInMillis) }}
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-row>
   </el-dialog>
 </template>
 <script setup lang="ts">
@@ -130,13 +128,15 @@ const currentNode = useWatchNode(props)
 const { showInput, blurEvent, clickTitle } = useNodeName2(currentNode, NodeType.START_USER_NODE)
 
 const nodeSetting = ref()
-// 
+//
 const nodeClick = () => {
   if (readonly) {
     // 只读模式,弹窗显示任务信息
-    if(tasks && tasks.value){
+    if (tasks && tasks.value) {
       dialogTitle.value = currentNode.value.name
-      selectTasks.value = tasks.value.filter((item: any) => item?.taskDefinitionKey === currentNode.value.id)
+      selectTasks.value = tasks.value.filter(
+        (item: any) => item?.taskDefinitionKey === currentNode.value.id
+      )
       dialogVisible.value = true
     }
   } else {
@@ -144,13 +144,11 @@ const nodeClick = () => {
     nodeSetting.value.showStartUserNodeConfig(currentNode.value)
     nodeSetting.value.openDrawer()
   }
- 
 }
 
 // 任务的弹窗显示,用于只读模式
 const dialogVisible = ref(false) // 弹窗可见性
 const dialogTitle = ref<string | undefined>(undefined) // 弹窗标题
-const selectTasks = ref<any[]|undefined>([]) // 选中的任务数组
-
+const selectTasks = ref<any[] | undefined>([]) // 选中的任务数组
 </script>
 <style lang="scss" scoped></style>

+ 70 - 72
src/components/SimpleProcessDesignerV2/src/nodes/UserTaskNode.vue

@@ -3,7 +3,10 @@
     <div class="node-container">
       <div
         class="node-box"
-        :class="[{ 'node-config-error': !currentNode.showText }, `${useTaskStatusClass(currentNode?.activityStatus)}`]"
+        :class="[
+          { 'node-config-error': !currentNode.showText },
+          `${useTaskStatusClass(currentNode?.activityStatus)}`
+        ]"
       >
         <div class="node-title-container">
           <div class="node-title-icon user-task"><span class="iconfont icon-approve"></span></div>
@@ -36,7 +39,11 @@
         </div>
       </div>
       <!-- 传递子节点给添加节点组件。会在子节点前面添加节点 -->
-      <NodeHandler v-if="currentNode" v-model:child-node="currentNode.childNode" :current-node="currentNode" />
+      <NodeHandler
+        v-if="currentNode"
+        v-model:child-node="currentNode.childNode"
+        :current-node="currentNode"
+      />
     </div>
   </div>
   <UserTaskNodeConfig
@@ -46,68 +53,59 @@
     @find:return-task-nodes="findReturnTaskNodes"
   />
   <!-- 审批记录 -->
-  <el-dialog :title="dialogTitle || '审批记录'" v-model="dialogVisible" width="1000px"  append-to-body>
-      <el-row>
-        <el-table
-          :data="selectTasks"
-          size="small"
-          border
-          header-cell-class-name="table-header-gray"
-        >
-          <el-table-column
-            label="序号"
-            header-align="center"
-            align="center"
-            type="index"
-            width="50"
-          />
-          <el-table-column
-            label="审批人"
-            min-width="100"
-            align="center"
-          >
-            <template #default="scope">
-              {{ scope.row.assigneeUser?.nickname || scope.row.ownerUser?.nickname }}
-            </template>
-          </el-table-column>
-         
-          <el-table-column label="部门" min-width="100" align="center">
-            <template #default="scope">
-              {{ scope.row.assigneeUser?.deptName || scope.row.ownerUser?.deptName }}
-            </template>
-          </el-table-column>
-          <el-table-column
-            :formatter="dateFormatter"
-            align="center"
-            label="开始时间"
-            prop="createTime"
-            min-width="140"
-          />
-          <el-table-column
-            :formatter="dateFormatter"
-            align="center"
-            label="结束时间"
-            prop="endTime"
-            min-width="140"
-          />
-          <el-table-column align="center" label="审批状态" prop="status" min-width="90">
-            <template #default="scope">
-              <dict-tag :type="DICT_TYPE.BPM_TASK_STATUS" :value="scope.row.status" />
-            </template>
-          </el-table-column>
-          <el-table-column
-            align="center"
-            label="审批建议"
-            prop="reason"
-            min-width="120"
-          />
-          <el-table-column align="center" label="耗时" prop="durationInMillis" width="100">
-            <template #default="scope">
-              {{ formatPast2(scope.row.durationInMillis) }}
-            </template>
-          </el-table-column>
-        </el-table>
-      </el-row>
+  <el-dialog
+    :title="dialogTitle || '审批记录'"
+    v-model="dialogVisible"
+    width="1000px"
+    append-to-body
+  >
+    <el-row>
+      <el-table :data="selectTasks" size="small" border header-cell-class-name="table-header-gray">
+        <el-table-column
+          label="序号"
+          header-align="center"
+          align="center"
+          type="index"
+          width="50"
+        />
+        <el-table-column label="审批人" min-width="100" align="center">
+          <template #default="scope">
+            {{ scope.row.assigneeUser?.nickname || scope.row.ownerUser?.nickname }}
+          </template>
+        </el-table-column>
+
+        <el-table-column label="部门" min-width="100" align="center">
+          <template #default="scope">
+            {{ scope.row.assigneeUser?.deptName || scope.row.ownerUser?.deptName }}
+          </template>
+        </el-table-column>
+        <el-table-column
+          :formatter="dateFormatter"
+          align="center"
+          label="开始时间"
+          prop="createTime"
+          min-width="140"
+        />
+        <el-table-column
+          :formatter="dateFormatter"
+          align="center"
+          label="结束时间"
+          prop="endTime"
+          min-width="140"
+        />
+        <el-table-column align="center" label="审批状态" prop="status" min-width="90">
+          <template #default="scope">
+            <dict-tag :type="DICT_TYPE.BPM_TASK_STATUS" :value="scope.row.status" />
+          </template>
+        </el-table-column>
+        <el-table-column align="center" label="审批建议" prop="reason" min-width="120" />
+        <el-table-column align="center" label="耗时" prop="durationInMillis" width="100">
+          <template #default="scope">
+            {{ formatPast2(scope.row.durationInMillis) }}
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-row>
   </el-dialog>
 </template>
 <script setup lang="ts">
@@ -140,17 +138,18 @@ const currentNode = useWatchNode(props)
 const { showInput, blurEvent, clickTitle } = useNodeName2(currentNode, NodeType.START_USER_NODE)
 const nodeSetting = ref()
 
-
 const nodeClick = () => {
-  if (readonly) { 
-    if(tasks && tasks.value){
+  if (readonly) {
+    if (tasks && tasks.value) {
       dialogTitle.value = currentNode.value.name
       // 只读模式,弹窗显示任务信息
-      selectTasks.value = tasks.value.filter((item: any) => item?.taskDefinitionKey === currentNode.value.id)
+      selectTasks.value = tasks.value.filter(
+        (item: any) => item?.taskDefinitionKey === currentNode.value.id
+      )
       dialogVisible.value = true
     }
-  } else { 
-     // 编辑模式,打开节点配置、把当前节点传递给配置组件
+  } else {
+    // 编辑模式,打开节点配置、把当前节点传递给配置组件
     nodeSetting.value.showUserTaskNodeConfig(currentNode.value)
     nodeSetting.value.openDrawer()
   }
@@ -170,7 +169,6 @@ const findReturnTaskNodes = (
 // 任务的弹窗显示,用于只读模式
 const dialogVisible = ref(false) // 弹窗可见性
 const dialogTitle = ref<string | undefined>(undefined) // 弹窗标题
-const selectTasks = ref<any[]|undefined>([]) // 选中的任务数组
-
+const selectTasks = ref<any[] | undefined>([]) // 选中的任务数组
 </script>
 <style lang="scss" scoped></style>