浏览代码

条件分支节点

CzRger 2 天之前
父节点
当前提交
f64c6b0188

+ 1 - 1
src/views/workflow/chart/index.vue

@@ -620,7 +620,7 @@ const initWatch = () => {
         const nodeId = cmds[0].data.id
         state.graph
           .getCellById(nodeId)
-          .data.workflowData.ports?.forEach((p) => {
+          .data.workflowData.__ports?.forEach((p) => {
             WorkflowStore.layoutPort(nodeId, p.id)
           })
       }

+ 1 - 1
src/views/workflow/config.ts

@@ -131,7 +131,7 @@ export const nodeSources = {
           title: NodeTypeObj[NodeType.IfElse].title,
           desc: '',
           ...ifElseNodeDefault.defaultValue(),
-          ports: <NodePortStruct[]>[
+          __ports: <NodePortStruct[]>[
             {
               id: v4(),
               ...ifElseNodeDefault.caseValue(),

+ 39 - 3
src/views/workflow/handle.ts

@@ -1,7 +1,12 @@
 import { Markup } from '@antv/x6'
 import { lineStyle } from '@/views/workflow/config'
 import { v4 } from 'uuid'
-import { GraphHistoryStep, NodeType, VarsSource } from '@/views/workflow/types'
+import {
+  ConditionType,
+  GraphHistoryStep,
+  NodeType,
+  VarsSource,
+} from '@/views/workflow/types'
 
 const systemVars = [
   {
@@ -130,8 +135,8 @@ export const handleNode = (no) => {
       },
     })
   }
-  if (node.data.workflowData.ports?.length > 0) {
-    node.data.workflowData.ports.forEach((p, pI) => {
+  if (node.data.workflowData.__ports?.length > 0) {
+    node.data.workflowData.__ports.forEach((p, pI) => {
       node.ports.items.push({
         id: p.id,
         group: 'more',
@@ -268,6 +273,37 @@ export const handleNodeSubmit = (no) => {
         }
       }
       break
+    case NodeType.IfElse:
+      {
+        no.cases = no.__ports.map((v) => {
+          const obj = {
+            id: v.id,
+            case_id: v.id,
+            logical_operator: v.mode,
+            conditions:
+              v.cases?.map((c) => {
+                const cObj = {
+                  id: c.id,
+                  varType: c.source.type.toLowerCase(),
+                  variable_selector:
+                    c.source.source === VarsSource.Root
+                      ? [c.source.key.split('.')[0], c.source.key.split('.')[1]]
+                      : [c.source.nodeId, c.source.key],
+                  comparison_operator: c.method,
+                  value:
+                    c.type === ConditionType.Constant
+                      ? c.target
+                      : c.target.source === VarsSource.Root
+                        ? `{{#${c.target.key.split('.')[0]}.${c.target.key.split('.')[1]}#}}`
+                        : `{{#${c.target.nodeId}.${c.target.key}#}}`,
+                }
+                return cObj
+              }) || [],
+          }
+          return obj
+        })
+      }
+      break
   }
   return no
 }

+ 8 - 8
src/views/workflow/instance/component/params-textarea/version-2.vue

@@ -160,10 +160,10 @@ watch(
         /\{\{#([^#]+)#\}\}/g,
         (match, p1) => {
           const k = [
-            p1.substring(0, p1.indexOf('_')),
-            p1.substring(p1.indexOf('_') + 1),
+            p1.substring(0, p1.indexOf('.')),
+            p1.substring(p1.indexOf('.') + 1),
           ]
-          const vars = state.optionsMap.get(`${k[0]}_${k[1]}`)
+          const vars = state.optionsMap.get(`${k[0]}.${k[1]}`)
           const dom = document.createElement('div')
           dom.appendChild(initVarsDom(vars))
           return dom.innerHTML
@@ -181,7 +181,7 @@ watch(
       const map = new Map()
       all.forEach((p) => {
         p.options.forEach((v) => {
-          map.set(`${v.nodeId}_${v.key}`, v)
+          map.set(`${v.nodeId}.${v.key}`, v)
         })
       })
       state.optionsMap = map
@@ -337,7 +337,7 @@ const initVarsDom = (vars) => {
   const dom = document.createElement('div')
   if (vars) {
     dom.setAttribute('contenteditable', 'false')
-    dom.setAttribute('sign', `{{#${vars.nodeId}_${vars.key}#}}`)
+    dom.setAttribute('sign', `{{#${vars.nodeId}.${vars.key}#}}`)
     dom.className = 'vars-dom inline-block'
     const app = createApp(paramValue, {
       vars,
@@ -463,10 +463,10 @@ onMounted(() => {
       /\{\{#([^#]+)#\}\}/g,
       (match, p1) => {
         const k = [
-          p1.substring(0, p1.indexOf('_')),
-          p1.substring(p1.indexOf('_') + 1),
+          p1.substring(0, p1.indexOf('.')),
+          p1.substring(p1.indexOf('.') + 1),
         ]
-        const vars = state.optionsMap.get(`${k[0]}_${k[1]}`)
+        const vars = state.optionsMap.get(`${k[0]}.${k[1]}`)
         const dom = document.createElement('div')
         dom.appendChild(initVarsDom(vars))
         return dom.innerHTML

+ 12 - 10
src/views/workflow/instance/component/vars/vars-out.vue

@@ -1,15 +1,22 @@
 <template>
-  <div class="vars-out" v-if="outVars.length > 0">
+  <div
+    class="flex flex-col gap-2"
+    :class="`pl-${level * 4}`"
+    v-if="outVars.length > 0"
+  >
     <template v-for="item in outVars">
-      <div class="out-item">
+      <div class="text-xs">
         <div>
           {{ item.key }} <span class="ml-2 opacity-65">{{ item.type }}</span>
           <span v-if="item.required" class="text-red-500">*</span>
         </div>
-        <div>
+        <div class="mt-1.5">
           <span class="opacity-65">{{ item.label }}</span>
         </div>
       </div>
+      <template v-if="item.children?.length > 0">
+        <varsOut :outVars="item.children" :level="level + 1" />
+      </template>
     </template>
   </div>
 </template>
@@ -20,15 +27,10 @@ import { getCurrentInstance, reactive, ref } from 'vue'
 const emit = defineEmits([])
 const props = defineProps({
   outVars: { default: [] },
+  level: { default: 0 },
 })
 const { proxy }: any = getCurrentInstance()
 const state: any = reactive({})
 </script>
 
-<style lang="scss" scoped>
-.vars-out {
-  .out-item {
-    font-size: 12px;
-  }
-}
-</style>
+<style lang="scss" scoped></style>

+ 3 - 3
src/views/workflow/instance/if-else/node/index.vue

@@ -1,13 +1,13 @@
 <template>
   <div class="node-if-else my-2 flex flex-col gap-2">
-    <template v-for="(port, index) in state.nodeData.ports">
+    <template v-for="(port, index) in state.nodeData.__ports">
       <div class="break-all" :id="port.id">
         <div class="port-item-head flex items-center justify-between">
           <template v-if="index === 0">
             <span>CASE {{ index + 1 }}</span>
             <span>IF</span>
           </template>
-          <template v-else-if="index === state.nodeData.ports.length - 1">
+          <template v-else-if="index === state.nodeData.__ports.length - 1">
             <span></span>
             <span>ELSE</span>
           </template>
@@ -16,7 +16,7 @@
             <span>ELSE IF</span>
           </template>
         </div>
-        <div v-if="index < state.nodeData.ports.length - 1">
+        <div v-if="index < state.nodeData.__ports.length - 1">
           <conditionNode :mode="port.mode" :conditions="port.cases" />
         </div>
       </div>

+ 14 - 6
src/views/workflow/instance/if-else/panel/index.vue

@@ -1,8 +1,8 @@
 <template>
   <div class="panel-block" v-if="state.nodeData">
     <div class="case-list">
-      <template v-for="(port, index) in state.nodeData.ports">
-        <div v-if="index < state.nodeData.ports.length - 1" class="case-item">
+      <template v-for="(port, index) in state.nodeData.__ports">
+        <div v-if="index < state.nodeData.__ports.length - 1" class="case-item">
           <div class="cast-title">
             <div class="flex">
               <div class="w-[60px]">CASR {{ index + 1 }}</div>
@@ -14,8 +14,15 @@
               @setVars="(vars) => onAddCondition(index, vars)"
               class="ml-auto"
             >
-              <CzrButton type="add" title="添加条件" />
+              <CzrButton type="add" title="添加" />
             </varsPopover>
+            <CzrButton
+              class="ml-2"
+              type="del"
+              title="刪除"
+              v-if="state.nodeData.__ports.length > 1"
+              @click="state.nodeData.__ports.splice(index, 1)"
+            />
           </div>
           <div class="mt-2 flex" v-if="port.cases?.length > 0">
             <conditionIndex
@@ -68,6 +75,7 @@ import {
   ConditionString,
   ConditionType,
 } from '@/views/workflow/types'
+import CzrButton from '@/components/czr-ui/CzrButton.vue'
 
 const WorkflowStore = useWorkflowStore()
 const emit = defineEmits(['reLayoutPort'])
@@ -90,7 +98,7 @@ watch(
 watch(
   () => state.nodeData,
   (n) => {
-    n.ports.forEach((p) => {
+    n.__ports.forEach((p) => {
       WorkflowStore.layoutPort(props.node.id, p.id)
     })
   },
@@ -111,10 +119,10 @@ const onAddCase = () => {
       dy: 0,
     },
   })
-  state.nodeData.ports.splice(state.nodeData.ports.length - 1, 0, data)
+  state.nodeData.__ports.splice(state.nodeData.__ports.length - 1, 0, data)
 }
 const onAddCondition = (caseIndex, vars) => {
-  state.nodeData.ports[caseIndex].cases.push({
+  state.nodeData.__ports[caseIndex].cases.push({
     id: v4(),
     source: vars,
     method:

+ 14 - 1
src/views/workflow/instance/knowledge-retrieval/default.ts

@@ -13,7 +13,20 @@ const nodeDefault = {
       score: 0.5,
     },
     multiple_retrieval_config: {},
-    __outVars: [{ label: '生成内容', key: 'text', type: 'String' }],
+    __outVars: [
+      {
+        label: '召回的分段',
+        key: 'result',
+        type: 'Array[Object]',
+        children: [
+          { label: '分段内容', key: 'content', type: 'String' },
+          { label: '分段标题', key: 'title', type: 'String' },
+          { label: '分段链接', key: 'url', type: 'String' },
+          { label: '分段图标', key: 'icon', type: 'String' },
+          { label: '其他元数据', key: 'metadata', type: 'String' },
+        ],
+      },
+    ],
   }),
 }
 

+ 2 - 2
src/views/workflow/mockJson.ts

@@ -97,7 +97,7 @@ export const data0 = {
           id: 'c3187871-987e-46fc-98e1-40946577a8f3',
           title: '条件分支',
           desc: '各种判断',
-          ports: [
+          __ports: [
             {
               id: '17f331e3-adcd-42f6-b4b8-25806d7d8bad',
               mode: 'and',
@@ -1171,7 +1171,7 @@ export const data1 = {
           id: 'c3187871-987e-46fc-98e1-40946577a8f3',
           title: '条件分支',
           desc: '各种判断',
-          ports: [
+          __ports: [
             {
               id: '17f331e3-adcd-42f6-b4b8-25806d7d8bad',
               mode: 'and',

+ 1 - 1
src/views/workflow/types.ts

@@ -52,7 +52,7 @@ export type NodeDataStruct = {
     | NodeType.Knowledge
     | NodeType.Test
     | NodeType.IfElse
-  ports?: NodePortStruct[]
+  __ports?: NodePortStruct[]
   edgeSource?: string
 }