feat:冗余代码清理
This commit is contained in:
@@ -16,8 +16,8 @@ const configStore = useConfigStore()
|
|||||||
const searchValue = ref('')
|
const searchValue = ref('')
|
||||||
const triggerOnFocus = ref(true)
|
const triggerOnFocus = ref(true)
|
||||||
const isFocus = ref(false)
|
const isFocus = ref(false)
|
||||||
const hasAutoSearched = ref(false) // 防止重复自动搜索
|
const hasAutoSearched = ref(false)
|
||||||
const isExpanded = ref(false) // 控制搜索框是否展开
|
const isExpanded = ref(false)
|
||||||
|
|
||||||
// 解析URL参数
|
// 解析URL参数
|
||||||
function getUrlParam(param: string): string | null {
|
function getUrlParam(param: string): string | null {
|
||||||
@@ -29,7 +29,6 @@ const planReady = computed(() => {
|
|||||||
return agentsStore.agentRawPlan.data !== undefined
|
return agentsStore.agentRawPlan.data !== undefined
|
||||||
})
|
})
|
||||||
const openAgentAllocationDialog = () => {
|
const openAgentAllocationDialog = () => {
|
||||||
console.log('打开智能体分配弹窗')
|
|
||||||
agentsStore.openAgentAllocationDialog()
|
agentsStore.openAgentAllocationDialog()
|
||||||
}
|
}
|
||||||
// 自动搜索函数
|
// 自动搜索函数
|
||||||
@@ -70,12 +69,12 @@ function handleBlur() {
|
|||||||
// 重置文本区域高度到最小行数
|
// 重置文本区域高度到最小行数
|
||||||
function resetTextareaHeight() {
|
function resetTextareaHeight() {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
// 修复:使用更可靠的方式获取textarea元素
|
// 获取textarea元素
|
||||||
const textarea =
|
const textarea =
|
||||||
document.querySelector('#task-container .el-textarea__inner') ||
|
document.querySelector('#task-container .el-textarea__inner') ||
|
||||||
document.querySelector('#task-container textarea')
|
document.querySelector('#task-container textarea')
|
||||||
|
|
||||||
if (textarea) {
|
if (textarea instanceof HTMLElement) {
|
||||||
// 强制设置最小高度
|
// 强制设置最小高度
|
||||||
textarea.style.height = 'auto'
|
textarea.style.height = 'auto'
|
||||||
textarea.style.minHeight = '56px'
|
textarea.style.minHeight = '56px'
|
||||||
@@ -100,7 +99,7 @@ async function handleSearch() {
|
|||||||
})
|
})
|
||||||
data['Collaboration Process'] = changeBriefs(data['Collaboration Process'])
|
data['Collaboration Process'] = changeBriefs(data['Collaboration Process'])
|
||||||
agentsStore.setAgentRawPlan({ data })
|
agentsStore.setAgentRawPlan({ data })
|
||||||
console.log('agentsStore.agentRawPlan', agentsStore.agentRawPlan)
|
|
||||||
emit('search', searchValue.value)
|
emit('search', searchValue.value)
|
||||||
} finally {
|
} finally {
|
||||||
triggerOnFocus.value = true
|
triggerOnFocus.value = true
|
||||||
@@ -182,7 +181,7 @@ onMounted(() => {
|
|||||||
/>
|
/>
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
<AssignmentButton v-dev-only v-if="planReady" @click="openAgentAllocationDialog" />
|
<AssignmentButton v-if="planReady" @click="openAgentAllocationDialog" />
|
||||||
</div>
|
</div>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed, onMounted } from 'vue'
|
import { ref, computed, onMounted } from 'vue'
|
||||||
import { ElNotification } from 'element-plus'
|
|
||||||
import { pick } from 'lodash'
|
import { pick } from 'lodash'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
import api from '@/api/index.ts'
|
import api from '@/api/index.ts'
|
||||||
|
|
||||||
import SvgIcon from '@/components/SvgIcon/index.vue'
|
import SvgIcon from '@/components/SvgIcon/index.vue'
|
||||||
import { agentMapDuty } from '@/layout/components/config.ts'
|
import { agentMapDuty } from '@/layout/components/config.ts'
|
||||||
import { type Agent, useAgentsStore } from '@/stores'
|
import { type Agent, useAgentsStore } from '@/stores'
|
||||||
@@ -39,82 +37,41 @@ const handleFileSelect = (event: Event) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 在validateApiConfig函数中添加更详细的日志
|
// 验证API配置:三个字段必须同时存在或同时不存在
|
||||||
const validateApiConfig = (agent: any) => {
|
const validateApiConfig = (agent: any) => {
|
||||||
const hasApiUrl = 'apiUrl' in agent
|
const hasApiUrl = 'apiUrl' in agent
|
||||||
const hasApiKey = 'apiKey' in agent
|
const hasApiKey = 'apiKey' in agent
|
||||||
const hasApiModel = 'apiModel' in agent
|
const hasApiModel = 'apiModel' in agent
|
||||||
|
|
||||||
// 三个字段必须同时存在或同时不存在
|
return hasApiUrl === hasApiKey && hasApiKey === hasApiModel
|
||||||
if (hasApiUrl !== hasApiKey || hasApiKey !== hasApiModel) {
|
|
||||||
console.error('❌ API配置不完整:', {
|
|
||||||
agentName: agent.Name,
|
|
||||||
missingFields: {
|
|
||||||
apiUrl: !hasApiUrl,
|
|
||||||
apiKey: !hasApiKey,
|
|
||||||
apiModel: !hasApiModel
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasApiUrl && hasApiKey && hasApiModel) {
|
|
||||||
console.log('✅ API配置完整,将使用自定义API配置:', {
|
|
||||||
apiUrl: agent.apiUrl,
|
|
||||||
apiKey: agent.apiKey ? '***' + agent.apiKey.slice(-4) : '未设置',
|
|
||||||
apiModel: agent.apiModel
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
console.log('ℹ️ 未设置API配置,将使用默认URL配置')
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const readFileContent = (file: File) => {
|
const readFileContent = (file: File) => {
|
||||||
console.log('📁 开始读取文件:', file.name, '大小:', file.size, '类型:', file.type)
|
|
||||||
|
|
||||||
const reader = new FileReader()
|
const reader = new FileReader()
|
||||||
reader.onload = e => {
|
reader.onload = e => {
|
||||||
try {
|
try {
|
||||||
console.log('📄 文件读取完成,开始解析JSON')
|
|
||||||
const content = e.target?.result as string
|
const content = e.target?.result as string
|
||||||
const jsonData = JSON.parse(content)
|
const jsonData = JSON.parse(content)
|
||||||
|
|
||||||
console.log('🔍 解析的JSON数据:', jsonData)
|
|
||||||
console.log(
|
|
||||||
'📊 数据类型:',
|
|
||||||
Array.isArray(jsonData) ? '数组' : '对象',
|
|
||||||
'长度:',
|
|
||||||
Array.isArray(jsonData) ? jsonData.length : 'N/A'
|
|
||||||
)
|
|
||||||
|
|
||||||
if (!Array.isArray(jsonData)) {
|
if (!Array.isArray(jsonData)) {
|
||||||
console.error('❌ JSON格式错误: 必须为数组格式')
|
|
||||||
ElMessage.error('JSON格式错误: 必须为数组格式')
|
ElMessage.error('JSON格式错误: 必须为数组格式')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('🔍 开始验证智能体数据...')
|
const validAgents = jsonData.filter((agent) => {
|
||||||
const validAgents = jsonData.filter((agent, index) => {
|
|
||||||
console.log(`🔍 验证第${index + 1}个智能体:`, agent.Name || '未命名')
|
|
||||||
// 验证必需字段
|
// 验证必需字段
|
||||||
if (!agent.Name || typeof agent.Name !== 'string') {
|
if (!agent.Name || typeof agent.Name !== 'string') {
|
||||||
console.error(`❌ 智能体${index + 1}缺少Name字段或格式错误`)
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if (!agent.Icon || typeof agent.Icon !== 'string') {
|
if (!agent.Icon || typeof agent.Icon !== 'string') {
|
||||||
console.error(`❌ 智能体${index + 1}缺少Icon字段或格式错误`)
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if (!agent.Profile || typeof agent.Profile !== 'string') {
|
if (!agent.Profile || typeof agent.Profile !== 'string') {
|
||||||
console.error(`❌ 智能体${index + 1}缺少Profile字段或格式错误`)
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// 验证API配置
|
// 验证API配置
|
||||||
if (!validateApiConfig(agent)) {
|
if (!validateApiConfig(agent)) {
|
||||||
console.error(`❌ 智能体${index + 1}API配置验证失败`)
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,21 +94,17 @@ const readFileContent = (file: File) => {
|
|||||||
api
|
api
|
||||||
.setAgents(processedAgents)
|
.setAgents(processedAgents)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
console.log('✅ 后端API调用成功')
|
|
||||||
ElMessage.success('智能体上传成功')
|
ElMessage.success('智能体上传成功')
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(() => {
|
||||||
console.error('❌ 后端API调用失败:', error)
|
|
||||||
ElMessage.error('智能体上传失败')
|
ElMessage.error('智能体上传失败')
|
||||||
})
|
})
|
||||||
} catch (error) {
|
} catch {
|
||||||
console.error('❌ JSON解析错误:', error)
|
|
||||||
ElMessage.error('JSON解析错误')
|
ElMessage.error('JSON解析错误')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
reader.onerror = error => {
|
reader.onerror = () => {
|
||||||
console.error('❌ 文件读取错误:', error)
|
|
||||||
ElMessage.error('文件读取错误')
|
ElMessage.error('文件读取错误')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,15 +23,14 @@ const emit = defineEmits<{
|
|||||||
(e: 'save-edit', stepId: string, processId: string, value: string): void
|
(e: 'save-edit', stepId: string, processId: string, value: string): void
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
// 🔄 从 currentTask 中获取数据(与分支切换联动)
|
//从 currentTask 中获取数据
|
||||||
const currentTaskProcess = computed(() => {
|
const currentTaskProcess = computed(() => {
|
||||||
// ✅ 优先使用 currentTask(包含分支切换后的数据)
|
|
||||||
const currentTask = agentsStore.currentTask
|
const currentTask = agentsStore.currentTask
|
||||||
if (currentTask && currentTask.Id === props.step.Id && currentTask.TaskProcess) {
|
if (currentTask && currentTask.Id === props.step.Id && currentTask.TaskProcess) {
|
||||||
return currentTask.TaskProcess
|
return currentTask.TaskProcess
|
||||||
}
|
}
|
||||||
|
|
||||||
// ⚠️ 降级:从 agentRawPlan 中获取原始数据(不受分支切换影响)
|
//从 agentRawPlan 中获取原始数据
|
||||||
const collaborationProcess = agentsStore.agentRawPlan.data?.['Collaboration Process'] || []
|
const collaborationProcess = agentsStore.agentRawPlan.data?.['Collaboration Process'] || []
|
||||||
const rawData = collaborationProcess.find((task: any) => task.Id === props.step.Id)
|
const rawData = collaborationProcess.find((task: any) => task.Id === props.step.Id)
|
||||||
return rawData?.TaskProcess || []
|
return rawData?.TaskProcess || []
|
||||||
@@ -39,19 +38,18 @@ const currentTaskProcess = computed(() => {
|
|||||||
|
|
||||||
// 当前正在编辑的process ID
|
// 当前正在编辑的process ID
|
||||||
const editingProcessId = ref<string | null>(null)
|
const editingProcessId = ref<string | null>(null)
|
||||||
// 编辑框的值
|
|
||||||
const editValue = ref('')
|
const editValue = ref('')
|
||||||
// 鼠标悬停的process ID
|
// 鼠标悬停的process ID
|
||||||
const hoverProcessId = ref<string | null>(null)
|
const hoverProcessId = ref<string | null>(null)
|
||||||
|
|
||||||
// 🆕 处理卡片点击事件(非编辑模式下)
|
// 处理卡片点击事件
|
||||||
function handleCardClick() {
|
function handleCardClick() {
|
||||||
// 如果正在编辑,不处理点击
|
// 如果正在编辑,不处理点击
|
||||||
if (editingProcessId.value) return
|
if (editingProcessId.value) return
|
||||||
|
|
||||||
// 设置当前任务,与任务大纲联动
|
// 设置当前任务,与任务大纲联动
|
||||||
if (props.step.Id) {
|
if (props.step.Id) {
|
||||||
agentsStore.setCurrentTask(props.step)
|
agentsStore.setCurrentTask(props.step as any)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed, watch, nextTick, onMounted } from 'vue'
|
import { ref, computed, nextTick, onMounted } from 'vue'
|
||||||
import { VueFlow, useVueFlow, Handle, Position, type Node, type Edge } from '@vue-flow/core'
|
import { VueFlow, useVueFlow, Handle, Position, type Node, type Edge } from '@vue-flow/core'
|
||||||
import { Controls } from '@vue-flow/controls'
|
|
||||||
import '@vue-flow/core/dist/style.css'
|
import '@vue-flow/core/dist/style.css'
|
||||||
import '@vue-flow/core/dist/theme-default.css'
|
import '@vue-flow/core/dist/theme-default.css'
|
||||||
import '@vue-flow/controls/dist/style.css'
|
|
||||||
import {
|
import {
|
||||||
useAgentsStore,
|
useAgentsStore,
|
||||||
useSelectionStore,
|
useSelectionStore,
|
||||||
@@ -22,7 +20,7 @@ const agentsStore = useAgentsStore()
|
|||||||
const selectionStore = useSelectionStore()
|
const selectionStore = useSelectionStore()
|
||||||
const { onConnect, addEdges, fitView: fit } = useVueFlow()
|
const { onConnect, addEdges, fitView: fit } = useVueFlow()
|
||||||
|
|
||||||
// 🆕 直接从 store 获取当前任务和任务过程数据
|
// 直接从 store 获取当前任务和任务过程数据
|
||||||
const currentTask = computed(() => agentsStore.currentTask)
|
const currentTask = computed(() => agentsStore.currentTask)
|
||||||
const taskProcess = computed(() => agentsStore.currentTask?.TaskProcess ?? [])
|
const taskProcess = computed(() => agentsStore.currentTask?.TaskProcess ?? [])
|
||||||
|
|
||||||
@@ -50,12 +48,10 @@ let isSyncing = false
|
|||||||
//初始化标记,避免重复初始化
|
//初始化标记,避免重复初始化
|
||||||
const BRANCHES_INIT_KEY_PREFIX = 'plan-task-branches-initialized-'
|
const BRANCHES_INIT_KEY_PREFIX = 'plan-task-branches-initialized-'
|
||||||
|
|
||||||
// 🆕 最后选中的分支ID
|
//最后选中的分支ID
|
||||||
const LAST_SELECTED_BRANCH_KEY = 'plan-task-last-selected-branch'
|
const LAST_SELECTED_BRANCH_KEY = 'plan-task-last-selected-branch'
|
||||||
|
|
||||||
// ==================== 辅助函数定义 ====================
|
// 获取分支的所有节点
|
||||||
|
|
||||||
// 🆕 获取分支的所有节点(只沿着分支创建方向遍历:right handle连接)
|
|
||||||
const getAllBranchNodes = (startNodeId: string): string[] => {
|
const getAllBranchNodes = (startNodeId: string): string[] => {
|
||||||
const visited = new Set<string>()
|
const visited = new Set<string>()
|
||||||
const toVisit: string[] = [startNodeId]
|
const toVisit: string[] = [startNodeId]
|
||||||
@@ -68,14 +64,14 @@ const getAllBranchNodes = (startNodeId: string): string[] => {
|
|||||||
}
|
}
|
||||||
visited.add(currentId)
|
visited.add(currentId)
|
||||||
|
|
||||||
// 🆕 只查找通过 right handle 连接的后续节点(分支创建方向)
|
// 只查找通过 right handle 连接的后续节点
|
||||||
const outgoingEdges = edges.value.filter(
|
const outgoingEdges = edges.value.filter(
|
||||||
edge => edge.source === currentId && edge.sourceHandle === 'right'
|
edge => edge.source === currentId && edge.sourceHandle === 'right'
|
||||||
)
|
)
|
||||||
|
|
||||||
for (const edge of outgoingEdges) {
|
for (const edge of outgoingEdges) {
|
||||||
const targetNodeId = edge.target
|
const targetNodeId = edge.target
|
||||||
// 只访问分支节点(不包含主流程节点和根节点)
|
// 只访问分支节点
|
||||||
if (
|
if (
|
||||||
!visited.has(targetNodeId) &&
|
!visited.has(targetNodeId) &&
|
||||||
targetNodeId !== 'root' &&
|
targetNodeId !== 'root' &&
|
||||||
@@ -89,7 +85,7 @@ const getAllBranchNodes = (startNodeId: string): string[] => {
|
|||||||
return Array.from(visited)
|
return Array.from(visited)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 🆕 获取从指定节点回溯到根节点的路径(只包含主流程节点)
|
//获取从指定节点回溯到根节点的路径(只包含主流程节点)
|
||||||
const getPathToRoot = (targetNodeId: string): string[] => {
|
const getPathToRoot = (targetNodeId: string): string[] => {
|
||||||
const path: string[] = []
|
const path: string[] = []
|
||||||
const visited = new Set<string>()
|
const visited = new Set<string>()
|
||||||
@@ -126,7 +122,7 @@ const getPathToRoot = (targetNodeId: string): string[] => {
|
|||||||
return path
|
return path
|
||||||
}
|
}
|
||||||
|
|
||||||
// 🆕 向上回溯分支的父节点链(只包含分支节点)
|
// 向上回溯分支的父节点链(只包含分支节点)
|
||||||
const getBranchParentChain = (targetNodeId: string): string[] => {
|
const getBranchParentChain = (targetNodeId: string): string[] => {
|
||||||
const parentChain: string[] = []
|
const parentChain: string[] = []
|
||||||
let currentId = targetNodeId
|
let currentId = targetNodeId
|
||||||
@@ -153,8 +149,7 @@ const getBranchParentChain = (targetNodeId: string): string[] => {
|
|||||||
|
|
||||||
return parentChain
|
return parentChain
|
||||||
}
|
}
|
||||||
|
// 初始化流程图
|
||||||
// ==================== 初始化流程图 ====================
|
|
||||||
const initializeFlow = () => {
|
const initializeFlow = () => {
|
||||||
if (!currentTask.value) {
|
if (!currentTask.value) {
|
||||||
nodes.value = []
|
nodes.value = []
|
||||||
@@ -162,20 +157,17 @@ const initializeFlow = () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 🆕 获取当前流程数据
|
// 获取当前流程数据
|
||||||
const taskStepId = currentTask.value.Id
|
const taskStepId = currentTask.value.Id
|
||||||
// 🆕 获取当前 agent 组合(用于区分不同 agent 组合的分支数据)
|
// 获取当前 agent 组合(用于区分不同 agent 组合的分支数据)
|
||||||
const currentAgents = currentTask.value.AgentSelection || []
|
const currentAgents = currentTask.value.AgentSelection || []
|
||||||
|
|
||||||
// 🆕 直接使用 taskProcess.value 作为数据源
|
// 直接使用 taskProcess.value 作为数据源
|
||||||
// 注意:虽然 currentTask.id 相同,但不同的 agent 组合对应的 agent 任务过程不同
|
|
||||||
// taskProcess.value 从 currentTask.TaskProcess 获取,能正确反映当前 agent 组合的任务过程
|
|
||||||
const currentTaskProcess = taskProcess.value
|
const currentTaskProcess = taskProcess.value
|
||||||
console.log('currentTaskProcess:', currentTaskProcess)
|
// 立即保存为副本(深拷贝)
|
||||||
// 🆕 立即保存为副本(深拷贝)
|
|
||||||
const taskProcessCopy = JSON.parse(JSON.stringify(currentTaskProcess))
|
const taskProcessCopy = JSON.parse(JSON.stringify(currentTaskProcess))
|
||||||
|
|
||||||
// 🆕 使用副本数据创建节点(而不是 currentTaskProcess)
|
// 使用副本数据创建节点(而不是 currentTaskProcess)
|
||||||
const taskProcessForNodes = taskProcessCopy
|
const taskProcessForNodes = taskProcessCopy
|
||||||
const newNodes: Node[] = []
|
const newNodes: Node[] = []
|
||||||
const newEdges: Edge[] = []
|
const newEdges: Edge[] = []
|
||||||
@@ -233,7 +225,14 @@ const initializeFlow = () => {
|
|||||||
targetHandle: 'left',
|
targetHandle: 'left',
|
||||||
type: 'smoothstep',
|
type: 'smoothstep',
|
||||||
animated: true,
|
animated: true,
|
||||||
style: { stroke: '#43a8aa', strokeWidth: 2 }
|
style: { stroke: '#43a8aa', strokeWidth: 2 },
|
||||||
|
markerEnd: {
|
||||||
|
type: 'arrow' as any,
|
||||||
|
color: '#43a8aa',
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
strokeWidth: 2
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,21 +246,27 @@ const initializeFlow = () => {
|
|||||||
targetHandle: 'left',
|
targetHandle: 'left',
|
||||||
type: 'smoothstep',
|
type: 'smoothstep',
|
||||||
animated: true,
|
animated: true,
|
||||||
style: { stroke: '#43a8aa', strokeWidth: 2 }
|
style: { stroke: '#43a8aa', strokeWidth: 2 },
|
||||||
|
markerEnd: {
|
||||||
|
type: 'arrow' as any,
|
||||||
|
color: '#43a8aa',
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
strokeWidth: 2
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes.value = newNodes
|
nodes.value = newNodes
|
||||||
edges.value = newEdges
|
edges.value = newEdges
|
||||||
|
|
||||||
// 📂 从 store 恢复已保存的任务过程分支数据
|
// 从 store 恢复已保存的任务过程分支数据
|
||||||
// taskStepId 已在前面声明 (line 163)
|
|
||||||
|
|
||||||
if (taskStepId) {
|
if (taskStepId) {
|
||||||
// 🆕 使用当前 agent 组合获取分支数据
|
// 使用当前 agent 组合获取分支数据
|
||||||
const savedBranches = selectionStore.getTaskProcessBranches(taskStepId, currentAgents)
|
const savedBranches = selectionStore.getTaskProcessBranches(taskStepId, currentAgents)
|
||||||
|
|
||||||
// 🆕 检查是否已经初始化过(针对该任务和 agent 组合)
|
// 检查是否已经初始化过(针对该任务和 agent 组合)
|
||||||
const branchesInitKey = `${BRANCHES_INIT_KEY_PREFIX}${taskStepId}_${selectionStore.getAgentGroupKey(
|
const branchesInitKey = `${BRANCHES_INIT_KEY_PREFIX}${taskStepId}_${selectionStore.getAgentGroupKey(
|
||||||
currentAgents
|
currentAgents
|
||||||
)}`
|
)}`
|
||||||
@@ -272,17 +277,17 @@ const initializeFlow = () => {
|
|||||||
edges.value = []
|
edges.value = []
|
||||||
|
|
||||||
savedBranches.forEach(branch => {
|
savedBranches.forEach(branch => {
|
||||||
// 恢复节点(深拷贝,避免引用问题)
|
// 恢复节点
|
||||||
branch.nodes.forEach(node => {
|
branch.nodes.forEach(node => {
|
||||||
nodes.value.push(JSON.parse(JSON.stringify(node)))
|
nodes.value.push(JSON.parse(JSON.stringify(node)))
|
||||||
})
|
})
|
||||||
// 恢复边(深拷贝)
|
// 恢复边
|
||||||
branch.edges.forEach(edge => {
|
branch.edges.forEach(edge => {
|
||||||
edges.value.push(JSON.parse(JSON.stringify(edge)))
|
edges.value.push(JSON.parse(JSON.stringify(edge)))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// 🆕 恢复最后选中的分支
|
// 恢复最后选中的分支
|
||||||
const lastSelectedBranchId = sessionStorage.getItem(LAST_SELECTED_BRANCH_KEY)
|
const lastSelectedBranchId = sessionStorage.getItem(LAST_SELECTED_BRANCH_KEY)
|
||||||
if (lastSelectedBranchId) {
|
if (lastSelectedBranchId) {
|
||||||
const lastSelectedBranch = savedBranches.find(branch => branch.id === lastSelectedBranchId)
|
const lastSelectedBranch = savedBranches.find(branch => branch.id === lastSelectedBranchId)
|
||||||
@@ -313,7 +318,7 @@ const initializeFlow = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 🆕 使用多级分支逻辑:获取父节点链和子节点
|
// 获取父节点链和子节点
|
||||||
const branchParentChain = getBranchParentChain(firstBranchNode.id)
|
const branchParentChain = getBranchParentChain(firstBranchNode.id)
|
||||||
const branchChildNodes = getAllBranchNodes(firstBranchNode.id)
|
const branchChildNodes = getAllBranchNodes(firstBranchNode.id)
|
||||||
|
|
||||||
@@ -338,11 +343,11 @@ const initializeFlow = () => {
|
|||||||
selectedNodeIds.value = new Set(mainProcessNodes)
|
selectedNodeIds.value = new Set(mainProcessNodes)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 🆕 首次初始化:设置节点和边,并保存为"初始流程"分支
|
// 首次初始化:设置节点和边,并保存为"初始流程"分支
|
||||||
nodes.value = newNodes
|
nodes.value = newNodes
|
||||||
edges.value = newEdges
|
edges.value = newEdges
|
||||||
|
|
||||||
const initialBranchNodes = newNodes // ✅ 保留所有节点,包括根节点
|
const initialBranchNodes = newNodes
|
||||||
const initialBranchEdges = [...newEdges]
|
const initialBranchEdges = [...newEdges]
|
||||||
|
|
||||||
const initialBranchId = selectionStore.addTaskProcessBranch(taskStepId, currentAgents, {
|
const initialBranchId = selectionStore.addTaskProcessBranch(taskStepId, currentAgents, {
|
||||||
@@ -351,13 +356,13 @@ const initializeFlow = () => {
|
|||||||
branchType: 'root',
|
branchType: 'root',
|
||||||
nodes: JSON.parse(JSON.stringify(initialBranchNodes)),
|
nodes: JSON.parse(JSON.stringify(initialBranchNodes)),
|
||||||
edges: JSON.parse(JSON.stringify(initialBranchEdges)),
|
edges: JSON.parse(JSON.stringify(initialBranchEdges)),
|
||||||
tasks: taskProcessCopy // 👈 使用副本(已经是深拷贝)
|
tasks: taskProcessCopy
|
||||||
})
|
})
|
||||||
|
|
||||||
// 🆕 标记已初始化(针对该任务步骤和 agent 组合)
|
// 标记已初始化(针对该任务步骤和 agent 组合)
|
||||||
sessionStorage.setItem(branchesInitKey, 'true')
|
sessionStorage.setItem(branchesInitKey, 'true')
|
||||||
|
|
||||||
// 🆕 首次初始化时,设置初始流程为当前选中分支
|
// 首次初始化时,设置初始流程为当前选中分支
|
||||||
selectionStore.setActiveTaskProcessBranch(taskStepId, currentAgents, initialBranchId)
|
selectionStore.setActiveTaskProcessBranch(taskStepId, currentAgents, initialBranchId)
|
||||||
|
|
||||||
// 默认选中"初始流程"的高亮状态
|
// 默认选中"初始流程"的高亮状态
|
||||||
@@ -369,166 +374,6 @@ const initializeFlow = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 同步当前所有分支数据到 store
|
|
||||||
const syncBranchesToStore = () => {
|
|
||||||
if (isSyncing || !currentTask.value?.Id) return
|
|
||||||
|
|
||||||
isSyncing = true
|
|
||||||
const taskStepId = currentTask.value.Id
|
|
||||||
// 🆕 获取当前 agent 组合
|
|
||||||
const currentAgents = currentTask.value.AgentSelection || []
|
|
||||||
|
|
||||||
// 🔄 获取现有的分支数据(用于保留初始流程分支)
|
|
||||||
const existingBranches = selectionStore.getTaskProcessBranches(taskStepId, currentAgents)
|
|
||||||
const existingBranchesMap = new Map<string, any>()
|
|
||||||
existingBranches.forEach(branch => {
|
|
||||||
// 使用分支ID作为key
|
|
||||||
existingBranchesMap.set(branch.id, branch)
|
|
||||||
})
|
|
||||||
|
|
||||||
// 获取当前所有分支节点(标记为 isBranchTask)
|
|
||||||
const currentBranchNodes = nodes.value.filter((n: Node) => n.data.isBranchTask)
|
|
||||||
|
|
||||||
if (currentBranchNodes.length === 0) {
|
|
||||||
isSyncing = false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 按照分支分组节点和边
|
|
||||||
// 通过 parentId 将节点分组
|
|
||||||
const branchesMap = new Map<
|
|
||||||
string,
|
|
||||||
{
|
|
||||||
nodes: Node[]
|
|
||||||
edges: Edge[]
|
|
||||||
branchContent: string
|
|
||||||
branchType: 'root' | 'task'
|
|
||||||
createdAt: number
|
|
||||||
tasks?: any[] // 🆕 添加 tasks 字段
|
|
||||||
}
|
|
||||||
>()
|
|
||||||
|
|
||||||
currentBranchNodes.forEach((node: Node) => {
|
|
||||||
// 找到连接到该节点的边,确定父节点
|
|
||||||
const incomingEdge = edges.value.find((e: Edge) => e.target === node.id)
|
|
||||||
const parentNodeId = incomingEdge?.source || 'root'
|
|
||||||
const isFirstBranchNode = incomingEdge?.sourceHandle === 'bottom'
|
|
||||||
|
|
||||||
if (isFirstBranchNode) {
|
|
||||||
if (!branchesMap.has(parentNodeId)) {
|
|
||||||
// 🆕 从现有分支数据中恢复元数据
|
|
||||||
const existingMetadata = existingBranchesMap.get(node.id)
|
|
||||||
|
|
||||||
branchesMap.set(parentNodeId, {
|
|
||||||
nodes: [],
|
|
||||||
edges: [],
|
|
||||||
branchContent: existingMetadata?.branchContent || '分支',
|
|
||||||
branchType: existingMetadata?.branchType || (parentNodeId === 'root' ? 'root' : 'task'),
|
|
||||||
createdAt: Date.now(),
|
|
||||||
tasks: existingMetadata?.tasks //
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 收集该分支的所有节点(从第一个节点开始,通过 right handle 连接的节点)
|
|
||||||
const branchNodes: Node[] = []
|
|
||||||
let currentNode: Node | undefined = node
|
|
||||||
|
|
||||||
while (currentNode) {
|
|
||||||
branchNodes.push(currentNode)
|
|
||||||
|
|
||||||
// 查找通过 right handle 连接的下一个节点
|
|
||||||
const outgoingEdge = edges.value.find(
|
|
||||||
(e: Edge) => e.source === currentNode!.id && e.sourceHandle === 'right'
|
|
||||||
)
|
|
||||||
if (outgoingEdge) {
|
|
||||||
currentNode = currentBranchNodes.find((n: Node) => n.id === outgoingEdge.target)
|
|
||||||
} else {
|
|
||||||
currentNode = undefined
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加所有分支节点
|
|
||||||
branchNodes.forEach((n: Node) => {
|
|
||||||
if (
|
|
||||||
!branchesMap
|
|
||||||
.get(parentNodeId)!
|
|
||||||
.nodes.find((existingNode: Node) => existingNode.id === n.id)
|
|
||||||
) {
|
|
||||||
branchesMap.get(parentNodeId)!.nodes.push(n)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// 找到该分支的所有边
|
|
||||||
branchNodes.forEach((branchNode: Node) => {
|
|
||||||
const branchEdges = edges.value.filter(
|
|
||||||
(e: Edge) => e.source === branchNode.id || e.target === branchNode.id
|
|
||||||
)
|
|
||||||
branchEdges.forEach((edge: Edge) => {
|
|
||||||
if (!branchesMap.get(parentNodeId)!.edges.find((e: Edge) => e.id === edge.id)) {
|
|
||||||
branchesMap.get(parentNodeId)!.edges.push(edge)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// 保存所有分支到 store(使用深拷贝)
|
|
||||||
branchesMap.forEach((branchData, parentNodeId) => {
|
|
||||||
// 🆕 优先使用恢复的 tasks 数据,如果没有才重新创建
|
|
||||||
let tasks = branchData.tasks
|
|
||||||
|
|
||||||
if (!tasks || tasks.length === 0) {
|
|
||||||
// 转换节点数据为 IRawStepTask 格式
|
|
||||||
tasks = branchData.nodes.map((node: Node) => ({
|
|
||||||
Id: node.id,
|
|
||||||
StepName: node.data.actionTypeName,
|
|
||||||
TaskContent: node.data.agentDescription,
|
|
||||||
InputObject_List: [],
|
|
||||||
OutputObject: '',
|
|
||||||
AgentSelection: [node.data.agentName],
|
|
||||||
Collaboration_Brief_frontEnd: {
|
|
||||||
template: '',
|
|
||||||
data: {}
|
|
||||||
} as any,
|
|
||||||
TaskProcess: []
|
|
||||||
}))
|
|
||||||
} else {
|
|
||||||
}
|
|
||||||
|
|
||||||
selectionStore.addTaskProcessBranch(taskStepId, currentAgents, {
|
|
||||||
parentNodeId,
|
|
||||||
branchContent: JSON.parse(JSON.stringify(branchData.branchContent)),
|
|
||||||
branchType: JSON.parse(JSON.stringify(branchData.branchType)),
|
|
||||||
nodes: JSON.parse(JSON.stringify(branchData.nodes)),
|
|
||||||
edges: JSON.parse(JSON.stringify(branchData.edges)),
|
|
||||||
tasks: JSON.parse(JSON.stringify(tasks)) // 🆕 优先使用恢复的 tasks
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
// 延迟重置标志,避免连续触发
|
|
||||||
setTimeout(() => {
|
|
||||||
isSyncing = false
|
|
||||||
}, 100)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 监听节点和边的变化,同步到 store
|
|
||||||
// ⚠️ 已禁用自动同步,因为会导致分支ID变化,sessionStorage中保存的选中分支无法恢复
|
|
||||||
// 分支数据在添加分支时就已经保存到store了,不需要在nodes/edges变化时重新同步
|
|
||||||
// watch(
|
|
||||||
// [nodes, edges],
|
|
||||||
// () => {
|
|
||||||
// // 如果正在同步,跳过
|
|
||||||
// if (isSyncing) return
|
|
||||||
|
|
||||||
// // 只在有分支节点时才同步
|
|
||||||
// const hasBranchNodes = nodes.value.some((n: Node) => n.data.isBranchTask)
|
|
||||||
// if (hasBranchNodes && currentTask.value) {
|
|
||||||
// syncBranchesToStore()
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// { deep: true }
|
|
||||||
// )
|
|
||||||
|
|
||||||
// 组件挂载后初始化
|
// 组件挂载后初始化
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if (currentTask.value) {
|
if (currentTask.value) {
|
||||||
@@ -556,7 +401,7 @@ const cancelAddBranch = () => {
|
|||||||
branchInput.value = ''
|
branchInput.value = ''
|
||||||
}
|
}
|
||||||
|
|
||||||
// 🆕 节点点击事件
|
// 节点点击事件
|
||||||
const onNodeClick = (event: any) => {
|
const onNodeClick = (event: any) => {
|
||||||
const nodeId = event.node.id
|
const nodeId = event.node.id
|
||||||
const nodeData = event.node.data as any
|
const nodeData = event.node.data as any
|
||||||
@@ -571,10 +416,10 @@ const onNodeClick = (event: any) => {
|
|||||||
|
|
||||||
if (isBranchNode) {
|
if (isBranchNode) {
|
||||||
// 点击的是分支节点
|
// 点击的是分支节点
|
||||||
// 🆕 向上回溯分支父节点链(多级分支)
|
// 向上回溯分支父节点链(多级分支)
|
||||||
const branchParentChain = getBranchParentChain(nodeId)
|
const branchParentChain = getBranchParentChain(nodeId)
|
||||||
|
|
||||||
// 🆕 向下遍历分支的子节点(只沿right handle方向)
|
// 向下遍历分支的子节点(只沿right handle方向)
|
||||||
const branchChildNodes = getAllBranchNodes(nodeId)
|
const branchChildNodes = getAllBranchNodes(nodeId)
|
||||||
|
|
||||||
// 找到最顶层的分支父节点(连接到主流程或根节点的)
|
// 找到最顶层的分支父节点(连接到主流程或根节点的)
|
||||||
@@ -599,7 +444,7 @@ const onNodeClick = (event: any) => {
|
|||||||
// 回溯到根节点,获取主流程路径
|
// 回溯到根节点,获取主流程路径
|
||||||
const pathToRoot = getPathToRoot(parentNodeId)
|
const pathToRoot = getPathToRoot(parentNodeId)
|
||||||
|
|
||||||
// 🔧 getPathToRoot 已经返回正序(从左到右),不需要反转
|
// getPathToRoot 已经返回正序(从左到右),不需要反转
|
||||||
const correctPathToRoot = pathToRoot // [agent-0, agent-1, agent-2, ...]
|
const correctPathToRoot = pathToRoot // [agent-0, agent-1, agent-2, ...]
|
||||||
const correctBranchParentChain = [...branchParentChain].reverse() // 顶层分支 → ... → 直接父分支(正序)
|
const correctBranchParentChain = [...branchParentChain].reverse() // 顶层分支 → ... → 直接父分支(正序)
|
||||||
|
|
||||||
@@ -611,27 +456,18 @@ const onNodeClick = (event: any) => {
|
|||||||
]
|
]
|
||||||
selectedNodeIds.value = new Set(allNodesToHighlight)
|
selectedNodeIds.value = new Set(allNodesToHighlight)
|
||||||
|
|
||||||
console.log('📋 路径顺序(从上到下、从左到右):', {
|
// 保存完整的 TaskProcess 数据(主流程 + 分支)到 store
|
||||||
pathToRoot: correctPathToRoot,
|
|
||||||
branchParentChain: correctBranchParentChain,
|
|
||||||
branchChildNodes: branchChildNodes,
|
|
||||||
total: allNodesToHighlight.length
|
|
||||||
})
|
|
||||||
|
|
||||||
// 🆕 保存完整的 TaskProcess 数据(主流程 + 分支)到 store
|
|
||||||
if (currentTask.value) {
|
if (currentTask.value) {
|
||||||
const completeTaskProcess: any[] = []
|
const completeTaskProcess: any[] = []
|
||||||
|
|
||||||
// 🆕 从 store 中获取"初始流程"副本(而不是使用 taskProcess.value)
|
// 从 store 中获取"初始流程"副本(而不是使用 taskProcess.value)
|
||||||
const taskStepId = currentTask.value.Id
|
const taskStepId = currentTask.value.Id
|
||||||
const currentAgents = currentTask.value.AgentSelection || []
|
const currentAgents = currentTask.value.AgentSelection || []
|
||||||
const branches = selectionStore.getTaskProcessBranches(taskStepId, currentAgents)
|
const branches = selectionStore.getTaskProcessBranches(taskStepId, currentAgents)
|
||||||
const initialBranch = branches.find(branch => branch.branchContent === '初始流程')
|
const initialBranch = branches.find(branch => branch.branchContent === '初始流程')
|
||||||
const mainProcessData = initialBranch?.tasks || taskProcess.value
|
const mainProcessData = initialBranch?.tasks || taskProcess.value
|
||||||
|
|
||||||
console.log('🔍 开始按高亮路径收集数据,总节点数:', allNodesToHighlight.length)
|
// 按照高亮路径顺序收集每个节点的数据
|
||||||
|
|
||||||
// 🆕 按照高亮路径顺序收集每个节点的数据
|
|
||||||
allNodesToHighlight.forEach(nodeId => {
|
allNodesToHighlight.forEach(nodeId => {
|
||||||
const node = nodes.value.find(n => n.id === nodeId)
|
const node = nodes.value.find(n => n.id === nodeId)
|
||||||
|
|
||||||
@@ -644,7 +480,6 @@ const onNodeClick = (event: any) => {
|
|||||||
const processData = mainProcessData[originalIndex]
|
const processData = mainProcessData[originalIndex]
|
||||||
if (processData && processData.ID && processData.AgentName && processData.Description) {
|
if (processData && processData.ID && processData.AgentName && processData.Description) {
|
||||||
completeTaskProcess.push(processData)
|
completeTaskProcess.push(processData)
|
||||||
console.log(` 📦 添加主流程节点: ${nodeId}, 索引: ${originalIndex}`)
|
|
||||||
}
|
}
|
||||||
} else if (node.data.isBranchTask) {
|
} else if (node.data.isBranchTask) {
|
||||||
// 分支节点:从对应的分支数据中获取(按索引匹配)
|
// 分支节点:从对应的分支数据中获取(按索引匹配)
|
||||||
@@ -657,25 +492,19 @@ const onNodeClick = (event: any) => {
|
|||||||
const taskData = parentBranch.tasks[nodeIndex]
|
const taskData = parentBranch.tasks[nodeIndex]
|
||||||
if (taskData.ID && taskData.AgentName && taskData.Description) {
|
if (taskData.ID && taskData.AgentName && taskData.Description) {
|
||||||
completeTaskProcess.push(taskData)
|
completeTaskProcess.push(taskData)
|
||||||
console.log(
|
|
||||||
` 📦 添加分支节点: ${nodeId}, 分支: ${parentBranch.branchContent}, 索引: ${nodeIndex}`
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
console.log(`✅ 数据收集完成,总任务数: ${completeTaskProcess.length}`)
|
// 找到当前点击节点所属的分支,用于保存选中状态
|
||||||
|
|
||||||
// 🆕 找到当前点击节点所属的分支,用于保存选中状态
|
|
||||||
const matchedBranch = branches.find(branch => {
|
const matchedBranch = branches.find(branch => {
|
||||||
return branch.nodes.some(node => node.id === nodeId)
|
return branch.nodes.some(node => node.id === nodeId)
|
||||||
})
|
})
|
||||||
|
|
||||||
if (matchedBranch) {
|
if (matchedBranch) {
|
||||||
sessionStorage.setItem(LAST_SELECTED_BRANCH_KEY, matchedBranch.id)
|
sessionStorage.setItem(LAST_SELECTED_BRANCH_KEY, matchedBranch.id)
|
||||||
console.log(`💾 保存选中的分支ID: ${matchedBranch.id}`)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
selectionStore.setActiveTaskProcessData(
|
selectionStore.setActiveTaskProcessData(
|
||||||
@@ -691,14 +520,14 @@ const onNodeClick = (event: any) => {
|
|||||||
selectedNodeIds.value = new Set(allBranchNodes)
|
selectedNodeIds.value = new Set(allBranchNodes)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 🆕 点击的是主流程节点,高亮所有主流程节点(初始流程)
|
// 点击的是主流程节点,高亮所有主流程节点(初始流程)
|
||||||
const mainProcessNodes = nodes.value
|
const mainProcessNodes = nodes.value
|
||||||
.filter(n => !n.data.isBranchTask && n.id !== 'root')
|
.filter(n => !n.data.isBranchTask && n.id !== 'root')
|
||||||
.map(n => n.id)
|
.map(n => n.id)
|
||||||
|
|
||||||
selectedNodeIds.value = new Set(mainProcessNodes)
|
selectedNodeIds.value = new Set(mainProcessNodes)
|
||||||
|
|
||||||
// 🆕 点击主流程节点时,从 store 读取"初始流程"分支的副本
|
// 点击主流程节点时,从 store 读取"初始流程"分支的副本
|
||||||
if (currentTask.value) {
|
if (currentTask.value) {
|
||||||
const taskStepId = currentTask.value.Id
|
const taskStepId = currentTask.value.Id
|
||||||
if (!taskStepId) {
|
if (!taskStepId) {
|
||||||
@@ -712,17 +541,17 @@ const onNodeClick = (event: any) => {
|
|||||||
// 使用 store 中保存的初始流程副本
|
// 使用 store 中保存的初始流程副本
|
||||||
selectionStore.setActiveTaskProcessData(taskStepId, currentAgents, initialBranch.tasks)
|
selectionStore.setActiveTaskProcessData(taskStepId, currentAgents, initialBranch.tasks)
|
||||||
|
|
||||||
// 🆕 同步更新 currentTask.TaskProcess(实现全局数据联动)
|
// 同步更新 currentTask.TaskProcess(实现全局数据联动)
|
||||||
agentsStore.setCurrentTaskProcess(initialBranch.tasks)
|
agentsStore.setCurrentTaskProcess(initialBranch.tasks)
|
||||||
|
|
||||||
// 🆕 保存选中的分支ID到 sessionStorage
|
// 保存选中的分支ID到 sessionStorage
|
||||||
sessionStorage.setItem(LAST_SELECTED_BRANCH_KEY, initialBranch.id)
|
sessionStorage.setItem(LAST_SELECTED_BRANCH_KEY, initialBranch.id)
|
||||||
} else {
|
} else {
|
||||||
// 降级:使用 taskProcess.value
|
// 降级:使用 taskProcess.value
|
||||||
const originalTaskProcess = taskProcess.value
|
const originalTaskProcess = taskProcess.value
|
||||||
selectionStore.setActiveTaskProcessData(taskStepId, currentAgents, originalTaskProcess)
|
selectionStore.setActiveTaskProcessData(taskStepId, currentAgents, originalTaskProcess)
|
||||||
|
|
||||||
// 🆕 同步更新 currentTask.TaskProcess(实现全局数据联动)
|
// 同步更新 currentTask.TaskProcess(实现全局数据联动)
|
||||||
agentsStore.setCurrentTaskProcess(originalTaskProcess)
|
agentsStore.setCurrentTaskProcess(originalTaskProcess)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -747,8 +576,8 @@ const submitBranch = async () => {
|
|||||||
branchLoading.value = true
|
branchLoading.value = true
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// ==================== 移动已有分支 ====================
|
// 移动已有分支
|
||||||
// 🆕 只移动在当前父节点下方的分支节点(Y坐标 > 父节点Y坐标)
|
// 只移动在当前父节点下方的分支节点(Y坐标 > 父节点Y坐标)
|
||||||
const parentNodeY = parentNode.position.y
|
const parentNodeY = parentNode.position.y
|
||||||
|
|
||||||
// 查找所有已有的分支任务节点(标记为 isBranchTask)
|
// 查找所有已有的分支任务节点(标记为 isBranchTask)
|
||||||
@@ -761,10 +590,6 @@ const submitBranch = async () => {
|
|||||||
|
|
||||||
const branchIdsBelowParent = branchesBelowParent.map((n: Node) => n.id)
|
const branchIdsBelowParent = branchesBelowParent.map((n: Node) => n.id)
|
||||||
|
|
||||||
console.log(
|
|
||||||
`📍 移动了 ${branchIdsBelowParent.length} 个分支(Y坐标 > ${parentNodeY}),总共 ${allExistingBranchNodes.length} 个分支`
|
|
||||||
)
|
|
||||||
|
|
||||||
// 将当前父节点下方的分支向下移动250px(通过创建新节点来触发响应式更新)
|
// 将当前父节点下方的分支向下移动250px(通过创建新节点来触发响应式更新)
|
||||||
nodes.value = nodes.value.map((node: Node) => {
|
nodes.value = nodes.value.map((node: Node) => {
|
||||||
if (branchIdsBelowParent.includes(node.id)) {
|
if (branchIdsBelowParent.includes(node.id)) {
|
||||||
@@ -779,7 +604,7 @@ const submitBranch = async () => {
|
|||||||
return node
|
return node
|
||||||
})
|
})
|
||||||
|
|
||||||
// 💾 同步更新 store 中保存的分支位置
|
// 同步更新 store 中保存的分支位置
|
||||||
if (currentTask.value?.Id) {
|
if (currentTask.value?.Id) {
|
||||||
const taskStepId = currentTask.value.Id
|
const taskStepId = currentTask.value.Id
|
||||||
const currentAgents = currentTask.value.AgentSelection || []
|
const currentAgents = currentTask.value.AgentSelection || []
|
||||||
@@ -800,21 +625,21 @@ const submitBranch = async () => {
|
|||||||
|
|
||||||
// 判断是根节点还是 agent 节点
|
// 判断是根节点还是 agent 节点
|
||||||
if (parentNodeId === 'root') {
|
if (parentNodeId === 'root') {
|
||||||
// ========== 根节点分支 ==========
|
// 根节点分支
|
||||||
let newAgentActions: IApiAgentAction[] = []
|
let newAgentActions: IApiAgentAction[] = []
|
||||||
|
|
||||||
if (USE_MOCK_DATA) {
|
if (USE_MOCK_DATA) {
|
||||||
// 使用 Mock API
|
// 使用 Mock API
|
||||||
const generalGoal = agentsStore.agentRawPlan.data?.['General Goal'] || ''
|
const generalGoal = agentsStore.agentRawPlan.data?.['General Goal'] || ''
|
||||||
|
|
||||||
// 🆕 根节点分支:从零开始生成完整方案
|
// 根节点分支:从零开始生成完整方案
|
||||||
// Baseline_Completion = 0 表示没有已完成的部分,需要生成所有阶段
|
// Baseline_Completion = 0 表示没有已完成的部分,需要生成所有阶段
|
||||||
// Existing_Steps 传空数组,不传递初始流程信息
|
// Existing_Steps 传空数组,不传递初始流程信息
|
||||||
const response = await api.mockBranchTaskProcess({
|
const response = await api.mockBranchTaskProcess({
|
||||||
branch_Number: 1,
|
branch_Number: 1,
|
||||||
Modification_Requirement: branchContent,
|
Modification_Requirement: branchContent,
|
||||||
Existing_Steps: [], // ← 根节点分支不传递现有步骤
|
Existing_Steps: [], // ← 根节点分支不传递现有步骤
|
||||||
Baseline_Completion: 0, // ← 从零开始
|
Baseline_Completion: 0, // ← 从零开始
|
||||||
stepTaskExisting: currentTask.value,
|
stepTaskExisting: currentTask.value,
|
||||||
goal: generalGoal
|
goal: generalGoal
|
||||||
})
|
})
|
||||||
@@ -842,14 +667,14 @@ const submitBranch = async () => {
|
|||||||
// 调用真实 API
|
// 调用真实 API
|
||||||
const generalGoal = agentsStore.agentRawPlan.data?.['General Goal'] || ''
|
const generalGoal = agentsStore.agentRawPlan.data?.['General Goal'] || ''
|
||||||
|
|
||||||
// 🆕 根节点分支:从零开始生成完整方案
|
// 根节点分支:从零开始生成完整方案
|
||||||
// Baseline_Completion = 0 表示没有已完成的部分,需要生成所有阶段
|
// Baseline_Completion = 0 表示没有已完成的部分,需要生成所有阶段
|
||||||
// Existing_Steps 传空数组,不传递初始流程信息
|
// Existing_Steps 传空数组,不传递初始流程信息
|
||||||
const response = await api.branchTaskProcess({
|
const response = await api.branchTaskProcess({
|
||||||
branch_Number: 1,
|
branch_Number: 1,
|
||||||
Modification_Requirement: branchContent,
|
Modification_Requirement: branchContent,
|
||||||
Existing_Steps: [], // ← 根节点分支不传递现有步骤
|
Existing_Steps: [], // ← 根节点分支不传递现有步骤
|
||||||
Baseline_Completion: 0, // ← 从零开始
|
Baseline_Completion: 0, // ← 从零开始
|
||||||
stepTaskExisting: currentTask.value,
|
stepTaskExisting: currentTask.value,
|
||||||
goal: generalGoal
|
goal: generalGoal
|
||||||
})
|
})
|
||||||
@@ -933,7 +758,14 @@ const submitBranch = async () => {
|
|||||||
targetHandle: 'left',
|
targetHandle: 'left',
|
||||||
type: 'smoothstep',
|
type: 'smoothstep',
|
||||||
animated: true,
|
animated: true,
|
||||||
style: { stroke: '#67c23a', strokeWidth: 2, strokeDasharray: '5,5' }
|
style: { stroke: '#67c23a', strokeWidth: 2, strokeDasharray: '5,5' },
|
||||||
|
markerEnd: {
|
||||||
|
type: 'arrow' as any,
|
||||||
|
color: '#43a8aa',
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
strokeWidth: 2
|
||||||
|
}
|
||||||
}
|
}
|
||||||
edges.value.push(newEdge)
|
edges.value.push(newEdge)
|
||||||
newBranchEdges.push(newEdge)
|
newBranchEdges.push(newEdge)
|
||||||
@@ -948,14 +780,21 @@ const submitBranch = async () => {
|
|||||||
targetHandle: 'left',
|
targetHandle: 'left',
|
||||||
type: 'smoothstep',
|
type: 'smoothstep',
|
||||||
animated: true,
|
animated: true,
|
||||||
style: { stroke: '#67c23a', strokeWidth: 2 }
|
style: { stroke: '#67c23a', strokeWidth: 2 },
|
||||||
|
markerEnd: {
|
||||||
|
type: 'arrow' as any,
|
||||||
|
color: '#43a8aa',
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
strokeWidth: 2
|
||||||
|
}
|
||||||
}
|
}
|
||||||
edges.value.push(newEdge)
|
edges.value.push(newEdge)
|
||||||
newBranchEdges.push(newEdge)
|
newBranchEdges.push(newEdge)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// 📂 保存分支数据到 store
|
// 保存分支数据到 store
|
||||||
if (newBranchNodes.length > 0) {
|
if (newBranchNodes.length > 0) {
|
||||||
// 将 IApiAgentAction 转换为 TaskProcess 格式用于存储
|
// 将 IApiAgentAction 转换为 TaskProcess 格式用于存储
|
||||||
// 与 fill-step-task-mock.ts 中的 TaskProcess 格式保持一致
|
// 与 fill-step-task-mock.ts 中的 TaskProcess 格式保持一致
|
||||||
@@ -986,7 +825,7 @@ const submitBranch = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// ========== Agent 节点分支 ==========
|
// Agent 节点分支
|
||||||
const parentIsBranchTask = parentNode.data.isBranchTask || false
|
const parentIsBranchTask = parentNode.data.isBranchTask || false
|
||||||
const parentOriginalIndex = parentNode.data.originalIndex ?? 0
|
const parentOriginalIndex = parentNode.data.originalIndex ?? 0
|
||||||
let newAgentActions: IApiAgentAction[] = []
|
let newAgentActions: IApiAgentAction[] = []
|
||||||
@@ -996,7 +835,7 @@ const submitBranch = async () => {
|
|||||||
const generalGoal = agentsStore.agentRawPlan.data?.['General Goal'] || ''
|
const generalGoal = agentsStore.agentRawPlan.data?.['General Goal'] || ''
|
||||||
const currentTaskProcess = taskProcess.value || []
|
const currentTaskProcess = taskProcess.value || []
|
||||||
|
|
||||||
// 🆕 根据父节点类型构建 existingSteps
|
// 根据父节点类型构建 existingSteps
|
||||||
let existingSteps: any[] = []
|
let existingSteps: any[] = []
|
||||||
let baselineCompletion = 100
|
let baselineCompletion = 100
|
||||||
|
|
||||||
@@ -1078,7 +917,7 @@ const submitBranch = async () => {
|
|||||||
const generalGoal = agentsStore.agentRawPlan.data?.['General Goal'] || ''
|
const generalGoal = agentsStore.agentRawPlan.data?.['General Goal'] || ''
|
||||||
const currentTaskProcess = taskProcess.value || []
|
const currentTaskProcess = taskProcess.value || []
|
||||||
|
|
||||||
// 🆕 根据父节点类型构建 existingSteps
|
// 根据父节点类型构建 existingSteps
|
||||||
let existingSteps: any[] = []
|
let existingSteps: any[] = []
|
||||||
let baselineCompletion = 100
|
let baselineCompletion = 100
|
||||||
|
|
||||||
@@ -1135,7 +974,6 @@ const submitBranch = async () => {
|
|||||||
goal: generalGoal
|
goal: generalGoal
|
||||||
})
|
})
|
||||||
|
|
||||||
console.log('branchTaskProcess response:', response)
|
|
||||||
// 后端返回格式: [[action1, action2], [action3, action4]]
|
// 后端返回格式: [[action1, action2], [action3, action4]]
|
||||||
// 取第一个分支
|
// 取第一个分支
|
||||||
if (response && response.length > 0) {
|
if (response && response.length > 0) {
|
||||||
@@ -1215,7 +1053,14 @@ const submitBranch = async () => {
|
|||||||
targetHandle: 'left',
|
targetHandle: 'left',
|
||||||
type: 'smoothstep',
|
type: 'smoothstep',
|
||||||
animated: true,
|
animated: true,
|
||||||
style: { stroke: '#409eff', strokeWidth: 2, strokeDasharray: '5,5' }
|
style: { stroke: '#409eff', strokeWidth: 2, strokeDasharray: '5,5' },
|
||||||
|
markerEnd: {
|
||||||
|
type: 'arrow' as any,
|
||||||
|
color: '#43a8aa',
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
strokeWidth: 2
|
||||||
|
}
|
||||||
}
|
}
|
||||||
edges.value.push(newEdge)
|
edges.value.push(newEdge)
|
||||||
newBranchEdges.push(newEdge)
|
newBranchEdges.push(newEdge)
|
||||||
@@ -1230,17 +1075,22 @@ const submitBranch = async () => {
|
|||||||
targetHandle: 'left',
|
targetHandle: 'left',
|
||||||
type: 'smoothstep',
|
type: 'smoothstep',
|
||||||
animated: true,
|
animated: true,
|
||||||
style: { stroke: '#409eff', strokeWidth: 2 }
|
style: { stroke: '#409eff', strokeWidth: 2 },
|
||||||
|
markerEnd: {
|
||||||
|
type: 'arrow' as any,
|
||||||
|
color: '#43a8aa',
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
strokeWidth: 2
|
||||||
|
}
|
||||||
}
|
}
|
||||||
edges.value.push(newEdge)
|
edges.value.push(newEdge)
|
||||||
newBranchEdges.push(newEdge)
|
newBranchEdges.push(newEdge)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// 📂 保存分支数据到 store
|
// 保存分支数据到 store
|
||||||
if (newBranchNodes.length > 0) {
|
if (newBranchNodes.length > 0) {
|
||||||
// 将 IApiAgentAction 转换为 TaskProcess 格式用于存储
|
|
||||||
// 与 fill-step-task-mock.ts 中的 TaskProcess 格式保持一致
|
|
||||||
const branchTasks = newAgentActions.map(action => ({
|
const branchTasks = newAgentActions.map(action => ({
|
||||||
ID: action.id || uuidv4(),
|
ID: action.id || uuidv4(),
|
||||||
ActionType: action.type,
|
ActionType: action.type,
|
||||||
@@ -1317,9 +1167,6 @@ onConnect(params => addEdges(params))
|
|||||||
@node-click="onNodeClick"
|
@node-click="onNodeClick"
|
||||||
class="vue-flow-container"
|
class="vue-flow-container"
|
||||||
>
|
>
|
||||||
<!-- <Background /> -->
|
|
||||||
<!-- <Controls /> -->
|
|
||||||
|
|
||||||
<template #node-root="nodeProps">
|
<template #node-root="nodeProps">
|
||||||
<div class="root-task-node-wrapper">
|
<div class="root-task-node-wrapper">
|
||||||
<Handle type="source" :position="Position.Right" id="right" />
|
<Handle type="source" :position="Position.Right" id="right" />
|
||||||
@@ -1645,7 +1492,7 @@ onConnect(params => addEdges(params))
|
|||||||
|
|
||||||
.el-input__inner {
|
.el-input__inner {
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
color: var(--color-text-primary);
|
color: #000;
|
||||||
padding-right: 40px;
|
padding-right: 40px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1684,7 +1531,7 @@ onConnect(params => addEdges(params))
|
|||||||
opacity: 0.9;
|
opacity: 0.9;
|
||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
|
|
||||||
// 🆕 分支选中高亮样式
|
// 分支选中高亮样式
|
||||||
&.is-branch-selected {
|
&.is-branch-selected {
|
||||||
box-shadow: 0 0 0 3px #000, 0 0 20px rgba(0, 0, 0, 0.5);
|
box-shadow: 0 0 0 3px #000, 0 0 20px rgba(0, 0, 0, 0.5);
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
@@ -1719,17 +1566,6 @@ onConnect(params => addEdges(params))
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.vue-flow__controls) {
|
|
||||||
button {
|
|
||||||
background-color: #43a8aa;
|
|
||||||
border-color: #43a8aa;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: #358d8f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 智能体悬浮提示样式 */
|
/* 智能体悬浮提示样式 */
|
||||||
:deep(.agent-tooltip-popper) {
|
:deep(.agent-tooltip-popper) {
|
||||||
z-index: 4000 !important;
|
z-index: 4000 !important;
|
||||||
|
|||||||
@@ -12,21 +12,19 @@ const props = defineProps<{
|
|||||||
step?: any
|
step?: any
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
// 获取分支数量 - 主分支(1) + 额外分支数量
|
// 获取分支数量
|
||||||
const branchCount = computed(() => {
|
const branchCount = computed(() => {
|
||||||
if (!props.step?.Id) return 1
|
if (!props.step?.Id) return 1
|
||||||
|
|
||||||
// 获取该任务步骤的分支数据
|
// 获取该任务步骤的分支数据
|
||||||
const taskStepId = props.step.Id
|
const taskStepId = props.step.Id
|
||||||
// 🆕 获取该任务的 agent 组合
|
// 获取该任务的 agent 组合
|
||||||
const agents = props.step.AgentSelection || []
|
const agents = props.step.AgentSelection || []
|
||||||
const branches = selectionStore.getTaskProcessBranches(taskStepId, agents)
|
const branches = selectionStore.getTaskProcessBranches(taskStepId, agents)
|
||||||
|
|
||||||
// 主分支(1) + 额外分支数量
|
|
||||||
return branches.length || 1
|
return branches.length || 1
|
||||||
})
|
})
|
||||||
|
|
||||||
// 🆕 判断按钮是否可点击(只有当前按钮对应的任务是任务大纲中选中的任务时才可点击)
|
// 判断按钮是否可点击
|
||||||
const isClickable = computed(() => {
|
const isClickable = computed(() => {
|
||||||
if (!props.step?.Id || !agentsStore.currentTask?.Id) {
|
if (!props.step?.Id || !agentsStore.currentTask?.Id) {
|
||||||
return false
|
return false
|
||||||
@@ -35,7 +33,7 @@ const isClickable = computed(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const handleClick = (event?: MouseEvent) => {
|
const handleClick = (event?: MouseEvent) => {
|
||||||
// 🆕 只有可点击时才执行操作
|
// 只有可点击时才执行操作
|
||||||
if (!isClickable.value) {
|
if (!isClickable.value) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -102,7 +100,7 @@ const handleClick = (event?: MouseEvent) => {
|
|||||||
filter: brightness(0.9);
|
filter: brightness(0.9);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 🆕 禁用状态
|
// 禁用状态
|
||||||
&.is-disabled {
|
&.is-disabled {
|
||||||
background-color: #bdc3c7;
|
background-color: #bdc3c7;
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ function handlePrev() {
|
|||||||
<!-- <div>{{ `${displayIndex + 1}/${data.length}` }}</div>
|
<!-- <div>{{ `${displayIndex + 1}/${data.length}` }}</div>
|
||||||
<el-button type="primary" size="small" @click="handleNext">下一个</el-button> -->
|
<el-button type="primary" size="small" @click="handleNext">下一个</el-button> -->
|
||||||
<!-- 关闭 -->
|
<!-- 关闭 -->
|
||||||
<SvgIcon icon-class="close" size="15px" />
|
<!-- <SvgIcon icon-class="close" size="15px" /> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 分割线 -->
|
<!-- 分割线 -->
|
||||||
|
|||||||
@@ -38,9 +38,9 @@ watch(
|
|||||||
)
|
)
|
||||||
|
|
||||||
// 编辑逻辑
|
// 编辑逻辑
|
||||||
const editMode = ref(false) //全局编辑开关
|
const editMode = ref(false)
|
||||||
const editMap = reactive<Record<string, boolean>>({}) //行级编辑状态
|
const editMap = reactive<Record<string, boolean>>({})
|
||||||
const editBuffer = reactive<Record<string, string | undefined>>({}) //临时输入
|
const editBuffer = reactive<Record<string, string | undefined>>({})
|
||||||
const showPopover = ref(false)
|
const showPopover = ref(false)
|
||||||
function getProcessDescription(stepId: string, processId: string) {
|
function getProcessDescription(stepId: string, processId: string) {
|
||||||
const step = collaborationProcess.value.find(s => s.Id === stepId)
|
const step = collaborationProcess.value.find(s => s.Id === stepId)
|
||||||
@@ -201,7 +201,6 @@ async function handleTaskProcess() {
|
|||||||
// 重置执行结果
|
// 重置执行结果
|
||||||
function handleRefresh() {
|
function handleRefresh() {
|
||||||
agentsStore.setExecutePlan([])
|
agentsStore.setExecutePlan([])
|
||||||
console.log('🔄 已重置执行结果')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加滚动状态标识
|
// 添加滚动状态标识
|
||||||
@@ -241,10 +240,8 @@ function clear() {
|
|||||||
jsplumb.reset()
|
jsplumb.reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 🆕 封装连线重绘方法
|
//封装连线重绘方法
|
||||||
const redrawInternalLines = (highlightId?: string) => {
|
const redrawInternalLines = (highlightId?: string) => {
|
||||||
console.log('🔄 TaskResult: 重新绘制连线', highlightId ? `高亮: ${highlightId}` : '')
|
|
||||||
|
|
||||||
// 等待 DOM 更新完成
|
// 等待 DOM 更新完成
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
// 清除旧连线
|
// 清除旧连线
|
||||||
@@ -253,28 +250,25 @@ const redrawInternalLines = (highlightId?: string) => {
|
|||||||
// 等待 DOM 稳定后重新绘制
|
// 等待 DOM 稳定后重新绘制
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
createInternalLine(highlightId)
|
createInternalLine(highlightId)
|
||||||
console.log('✅ TaskResult: 连线重绘完成,任务数:', collaborationProcess.value.length)
|
|
||||||
}, 100)
|
}, 100)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 🆕 监听 collaborationProcess 变化,自动重绘连线
|
//监听 collaborationProcess 变化,自动重绘连线
|
||||||
watch(
|
watch(
|
||||||
() => collaborationProcess,
|
() => collaborationProcess,
|
||||||
() => {
|
() => {
|
||||||
console.log('🔍 TaskResult: collaborationProcess 发生变化,触发重绘')
|
|
||||||
redrawInternalLines()
|
redrawInternalLines()
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
// 🆕 组件挂载后初始化连线
|
// 组件挂载后初始化连线
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 初始化时绘制连线
|
// 初始化时绘制连线
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
createInternalLine()
|
createInternalLine()
|
||||||
console.log('✅ TaskResult: 初始化连线完成')
|
|
||||||
}, 100)
|
}, 100)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -328,7 +322,6 @@ onUnmounted(() => {
|
|||||||
})
|
})
|
||||||
// 计算按钮类名
|
// 计算按钮类名
|
||||||
const processBtnClass = computed(() => {
|
const processBtnClass = computed(() => {
|
||||||
// 当刷新或执行按钮悬停时,过程按钮变圆形
|
|
||||||
if (buttonHoverState.value === 'refresh' || buttonHoverState.value === 'execute') {
|
if (buttonHoverState.value === 'refresh' || buttonHoverState.value === 'execute') {
|
||||||
return 'circle'
|
return 'circle'
|
||||||
}
|
}
|
||||||
@@ -336,20 +329,16 @@ const processBtnClass = computed(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const executeBtnClass = computed(() => {
|
const executeBtnClass = computed(() => {
|
||||||
// 鼠标悬停在过程按钮或刷新按钮上时,执行按钮变圆形
|
|
||||||
if (buttonHoverState.value === 'process' || buttonHoverState.value === 'refresh') {
|
if (buttonHoverState.value === 'process' || buttonHoverState.value === 'refresh') {
|
||||||
return 'circle'
|
return 'circle'
|
||||||
}
|
}
|
||||||
//如果有任务数据就显示椭圆形,否则显示圆形
|
|
||||||
return agentsStore.agentRawPlan.data ? 'ellipse' : 'circle'
|
return agentsStore.agentRawPlan.data ? 'ellipse' : 'circle'
|
||||||
})
|
})
|
||||||
|
|
||||||
const refreshBtnClass = computed(() => {
|
const refreshBtnClass = computed(() => {
|
||||||
// 当过程或执行按钮悬停时,刷新按钮变圆形
|
|
||||||
if (buttonHoverState.value === 'process' || buttonHoverState.value === 'execute') {
|
if (buttonHoverState.value === 'process' || buttonHoverState.value === 'execute') {
|
||||||
return 'circle'
|
return 'circle'
|
||||||
}
|
}
|
||||||
// 有执行结果就显示椭圆形,否则显示圆形
|
|
||||||
return agentsStore.executePlan.length > 0 ? 'ellipse' : 'circle'
|
return agentsStore.executePlan.length > 0 ? 'ellipse' : 'circle'
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -359,9 +348,7 @@ const showProcessText = computed(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const showExecuteText = computed(() => {
|
const showExecuteText = computed(() => {
|
||||||
// 鼠标悬停在过程按钮上时,执行按钮不显示文字
|
|
||||||
if (buttonHoverState.value === 'process') return false
|
if (buttonHoverState.value === 'process') return false
|
||||||
// 其他情况:如果有任务数据就显示文字,否则不显示
|
|
||||||
return agentsStore.agentRawPlan.data
|
return agentsStore.agentRawPlan.data
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -398,7 +385,7 @@ defineExpose({
|
|||||||
<div class="text-[18px] font-bold mb-[7px] flex justify-between items-center px-[20px]">
|
<div class="text-[18px] font-bold mb-[7px] flex justify-between items-center px-[20px]">
|
||||||
<span class="text-[var(--color-text-title-header)]">执行结果</span>
|
<span class="text-[var(--color-text-title-header)]">执行结果</span>
|
||||||
<div
|
<div
|
||||||
class="flex items-center justify-end gap-[14px] task-button-group min-w-[175px]"
|
class="flex items-center justify-end gap-[10px] task-button-group w-[230px]"
|
||||||
@mouseleave="handleButtonMouseLeave"
|
@mouseleave="handleButtonMouseLeave"
|
||||||
>
|
>
|
||||||
<!-- 刷新按钮 -->
|
<!-- 刷新按钮 -->
|
||||||
@@ -758,7 +745,7 @@ defineExpose({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== 新增:按钮交互样式 ==========
|
//按钮交互样式
|
||||||
.task-button-group {
|
.task-button-group {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row-reverse;
|
flex-direction: row-reverse;
|
||||||
@@ -766,7 +753,8 @@ defineExpose({
|
|||||||
display: inline-flex !important;
|
display: inline-flex !important;
|
||||||
align-items: center !important;
|
align-items: center !important;
|
||||||
justify-content: center !important;
|
justify-content: center !important;
|
||||||
transition: width 0.2s ease-out, padding 0.2s ease-out, border-radius 0.2s ease-out, transform 0.2s ease-out, box-shadow 0.2s ease-out, filter 0.2s ease-out !important;
|
transition: width 0.2s ease-out, padding 0.2s ease-out, border-radius 0.2s ease-out,
|
||||||
|
transform 0.2s ease-out, box-shadow 0.2s ease-out, filter 0.2s ease-out !important;
|
||||||
overflow: hidden !important;
|
overflow: hidden !important;
|
||||||
white-space: nowrap !important;
|
white-space: nowrap !important;
|
||||||
border: 1px solid transparent !important;
|
border: 1px solid transparent !important;
|
||||||
@@ -812,6 +800,7 @@ defineExpose({
|
|||||||
width: 40px !important;
|
width: 40px !important;
|
||||||
height: 40px !important;
|
height: 40px !important;
|
||||||
min-width: 40px !important;
|
min-width: 40px !important;
|
||||||
|
max-width: 40px !important;
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
border-radius: 50% !important;
|
border-radius: 50% !important;
|
||||||
|
|
||||||
|
|||||||
@@ -50,8 +50,6 @@ import type { Node, Edge } from '@vue-flow/core'
|
|||||||
import { useAgentsStore, useSelectionStore, type IRawStepTask } from '@/stores'
|
import { useAgentsStore, useSelectionStore, type IRawStepTask } from '@/stores'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import { v4 as uuidv4 } from 'uuid'
|
|
||||||
|
|
||||||
import '@vue-flow/core/dist/style.css'
|
import '@vue-flow/core/dist/style.css'
|
||||||
import '@vue-flow/core/dist/theme-default.css'
|
import '@vue-flow/core/dist/theme-default.css'
|
||||||
import '@vue-flow/minimap/dist/style.css'
|
import '@vue-flow/minimap/dist/style.css'
|
||||||
@@ -64,8 +62,7 @@ import TaskNode from './components/TaskNode.vue'
|
|||||||
const agentsStore = useAgentsStore()
|
const agentsStore = useAgentsStore()
|
||||||
const selectionStore = useSelectionStore()
|
const selectionStore = useSelectionStore()
|
||||||
|
|
||||||
// Mock 数据配置
|
// Mock 数据开关
|
||||||
// 开关:控制是否使用 mock 数据(开发时设置为 true,生产时设置为 false)
|
|
||||||
const USE_MOCK_DATA = false
|
const USE_MOCK_DATA = false
|
||||||
|
|
||||||
// 获取协作流程数据
|
// 获取协作流程数据
|
||||||
@@ -80,16 +77,13 @@ const edges = ref<Edge[]>([])
|
|||||||
// Vue Flow 实例方法
|
// Vue Flow 实例方法
|
||||||
const { fitView: fit, setTransform, updateNode, findNode } = useVueFlow()
|
const { fitView: fit, setTransform, updateNode, findNode } = useVueFlow()
|
||||||
|
|
||||||
// 编辑状态管理
|
|
||||||
const editingTasks = ref<Record<string, string>>({})
|
|
||||||
|
|
||||||
// 当前正在添加分支的节点 ID
|
// 当前正在添加分支的节点 ID
|
||||||
const currentAddingBranchNodeId = ref<string | null>(null)
|
const currentAddingBranchNodeId = ref<string | null>(null)
|
||||||
|
|
||||||
// 当前选中的节点ID集合
|
// 当前选中的节点ID集合
|
||||||
const selectedNodeIds = ref<Set<string>>(new Set())
|
const selectedNodeIds = ref<Set<string>>(new Set())
|
||||||
|
|
||||||
// 获取从目标节点回溯到根节点的路径
|
// 回溯到根节点的路径
|
||||||
const getPathToRoot = (targetNodeId: string): string[] => {
|
const getPathToRoot = (targetNodeId: string): string[] => {
|
||||||
const path: string[] = []
|
const path: string[] = []
|
||||||
const visited = new Set<string>()
|
const visited = new Set<string>()
|
||||||
@@ -121,7 +115,7 @@ const getPathToRoot = (targetNodeId: string): string[] => {
|
|||||||
return path
|
return path
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取分支的所有子节点(只向右遍历,不跨分支)
|
// 获取分支的所有子节点
|
||||||
const getAllBranchNodes = (startNodeId: string): string[] => {
|
const getAllBranchNodes = (startNodeId: string): string[] => {
|
||||||
const visited = new Set<string>()
|
const visited = new Set<string>()
|
||||||
const toVisit: string[] = [startNodeId]
|
const toVisit: string[] = [startNodeId]
|
||||||
@@ -134,7 +128,7 @@ const getAllBranchNodes = (startNodeId: string): string[] => {
|
|||||||
}
|
}
|
||||||
visited.add(currentId)
|
visited.add(currentId)
|
||||||
|
|
||||||
// 只查找通过 right handle 连接的后续节点(分支创建方向)
|
// 查找分支创建方向的后续节点
|
||||||
const outgoingEdges = edges.value.filter(
|
const outgoingEdges = edges.value.filter(
|
||||||
edge => edge.source === currentId && edge.sourceHandle === 'right'
|
edge => edge.source === currentId && edge.sourceHandle === 'right'
|
||||||
)
|
)
|
||||||
@@ -155,7 +149,7 @@ const getAllBranchNodes = (startNodeId: string): string[] => {
|
|||||||
return Array.from(visited)
|
return Array.from(visited)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 向上回溯分支的父节点链(只包含分支节点)
|
// 回溯分支的父节点链
|
||||||
const getBranchParentChain = (targetNodeId: string): string[] => {
|
const getBranchParentChain = (targetNodeId: string): string[] => {
|
||||||
const parentChain: string[] = []
|
const parentChain: string[] = []
|
||||||
let currentId = targetNodeId
|
let currentId = targetNodeId
|
||||||
@@ -170,12 +164,12 @@ const getBranchParentChain = (targetNodeId: string): string[] => {
|
|||||||
|
|
||||||
const sourceNode = nodes.value.find(n => n.id === incomingEdge.source)
|
const sourceNode = nodes.value.find(n => n.id === incomingEdge.source)
|
||||||
|
|
||||||
// 如果父节点不是分支节点,停止回溯
|
// 非分支节点停止回溯
|
||||||
if (!sourceNode || !sourceNode.id.startsWith('branch-task-')) {
|
if (!sourceNode || !sourceNode.id.startsWith('branch-task-')) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加父节点到链中
|
// 添加父节点
|
||||||
parentChain.push(sourceNode.id)
|
parentChain.push(sourceNode.id)
|
||||||
currentId = sourceNode.id
|
currentId = sourceNode.id
|
||||||
}
|
}
|
||||||
@@ -183,35 +177,35 @@ const getBranchParentChain = (targetNodeId: string): string[] => {
|
|||||||
return parentChain
|
return parentChain
|
||||||
}
|
}
|
||||||
|
|
||||||
// 判断节点是否为主流程节点
|
// 判断是否为主流程节点
|
||||||
const isMainProcessNode = (nodeId: string): boolean => {
|
const isMainProcessNode = (nodeId: string): boolean => {
|
||||||
return nodeId.startsWith('task-') && !nodeId.startsWith('branch-task-')
|
return nodeId.startsWith('task-') && !nodeId.startsWith('branch-task-')
|
||||||
}
|
}
|
||||||
|
|
||||||
// 分支操作加载状态
|
// 分支加载状态
|
||||||
const branchLoading = ref(false)
|
const branchLoading = ref(false)
|
||||||
|
|
||||||
// 初始化标记,避免重复适应视图(使用 sessionStorage 持久化)
|
// 初始化标记
|
||||||
const INIT_KEY = 'plan-modification-initialized'
|
const INIT_KEY = 'plan-modification-initialized'
|
||||||
const isInitialized = ref(sessionStorage.getItem(INIT_KEY) === 'true')
|
const isInitialized = ref(sessionStorage.getItem(INIT_KEY) === 'true')
|
||||||
|
|
||||||
// 分支初始化标记
|
// 分支初始化标记
|
||||||
const BRANCHES_INIT_KEY = 'plan-modification-branches-initialized'
|
const BRANCHES_INIT_KEY = 'plan-modification-branches-initialized'
|
||||||
|
|
||||||
// 最后选中的分支ID
|
// 最后选中的分支ID
|
||||||
const LAST_SELECTED_BRANCH_KEY = 'plan-modification-last-selected-branch'
|
const LAST_SELECTED_BRANCH_KEY = 'plan-modification-last-selected-branch'
|
||||||
|
|
||||||
// 标记是否已经挂载
|
// 挂载标记
|
||||||
const isMounted = ref(false)
|
const isMounted = ref(false)
|
||||||
|
|
||||||
// 节点尺寸配置
|
// 节点尺寸配置
|
||||||
const NODE_WIDTH = 120 // 任务节点宽度
|
const NODE_WIDTH = 120
|
||||||
const ROOT_WIDTH = 200 // 根节点宽度
|
const ROOT_WIDTH = 200
|
||||||
const NODE_GAP = 80 // 节点间距
|
const NODE_GAP = 80
|
||||||
const START_X = 40 // 起始 X 坐标
|
const START_X = 40
|
||||||
const START_Y = 50 // 起始 Y 坐标
|
const START_Y = 50
|
||||||
|
|
||||||
// 初始化流程图 - 横向布局(根节点为初始目标,只展示流程卡片)
|
// 初始化流程图
|
||||||
const initializeFlow = () => {
|
const initializeFlow = () => {
|
||||||
const branchesInitialized = sessionStorage.getItem(BRANCHES_INIT_KEY) === 'true'
|
const branchesInitialized = sessionStorage.getItem(BRANCHES_INIT_KEY) === 'true'
|
||||||
const savedBranches = selectionStore.getAllFlowBranches()
|
const savedBranches = selectionStore.getAllFlowBranches()
|
||||||
@@ -308,16 +302,16 @@ const initializeFlow = () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 首次初始化:创建完整的流程
|
// 首次初始化
|
||||||
|
|
||||||
const newNodes: Node[] = []
|
const newNodes: Node[] = []
|
||||||
const newEdges: Edge[] = []
|
const newEdges: Edge[] = []
|
||||||
|
|
||||||
// 获取初始目标作为根节点
|
// 获取根节点
|
||||||
const generalGoal = agentsStore.agentRawPlan.data?.['General Goal']
|
const generalGoal = agentsStore.agentRawPlan.data?.['General Goal']
|
||||||
const initialInput = agentsStore.agentRawPlan.data?.['Initial Input Object']
|
const initialInput = agentsStore.agentRawPlan.data?.['Initial Input Object']
|
||||||
|
|
||||||
// 创建根节点(初始目标)
|
// 创建根节点
|
||||||
if (generalGoal) {
|
if (generalGoal) {
|
||||||
newNodes.push({
|
newNodes.push({
|
||||||
id: 'root-goal',
|
id: 'root-goal',
|
||||||
@@ -331,7 +325,7 @@ const initializeFlow = () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 遍历协作流程,创建任务节点
|
// 创建任务节点
|
||||||
collaborationProcess.value.forEach((task, index) => {
|
collaborationProcess.value.forEach((task, index) => {
|
||||||
const taskId = task.Id || `task-${index}`
|
const taskId = task.Id || `task-${index}`
|
||||||
|
|
||||||
@@ -364,13 +358,21 @@ const initializeFlow = () => {
|
|||||||
animated: true,
|
animated: true,
|
||||||
type: 'smoothstep',
|
type: 'smoothstep',
|
||||||
style: { stroke: '#e6a23c', strokeWidth: 2 },
|
style: { stroke: '#e6a23c', strokeWidth: 2 },
|
||||||
label: ''
|
markerEnd: {
|
||||||
|
type: 'arrow' as any,
|
||||||
|
color: '#43a8aa',
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
strokeWidth: 2
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果不是第一个任务,创建从前一个任务到当前任务的连接
|
// 如果不是第一个任务,创建从前一个任务到当前任务的连接
|
||||||
if (index > 0) {
|
if (index > 0) {
|
||||||
const prevTaskId = collaborationProcess.value[index - 1].Id || `task-${index - 1}`
|
// const prevTaskId = collaborationProcess.value[index - 1].Id || `task-${index - 1}`
|
||||||
|
const prev = collaborationProcess.value[index - 1]
|
||||||
|
const prevTaskId = prev?.Id || `task-${index - 1}`
|
||||||
newEdges.push({
|
newEdges.push({
|
||||||
id: `edge-task-${prevTaskId}-${taskId}`,
|
id: `edge-task-${prevTaskId}-${taskId}`,
|
||||||
source: `task-${prevTaskId}`,
|
source: `task-${prevTaskId}`,
|
||||||
@@ -380,7 +382,13 @@ const initializeFlow = () => {
|
|||||||
animated: true,
|
animated: true,
|
||||||
type: 'smoothstep',
|
type: 'smoothstep',
|
||||||
style: { stroke: '#409eff', strokeWidth: 2 },
|
style: { stroke: '#409eff', strokeWidth: 2 },
|
||||||
label: ''
|
markerEnd: {
|
||||||
|
type: 'arrow' as any,
|
||||||
|
color: '#43a8aa',
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
strokeWidth: 2
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -388,8 +396,7 @@ const initializeFlow = () => {
|
|||||||
nodes.value = newNodes
|
nodes.value = newNodes
|
||||||
edges.value = newEdges
|
edges.value = newEdges
|
||||||
|
|
||||||
// 🆕 检查是否需要保存初始流程为分支
|
// 检查是否需要保存初始流程为分支
|
||||||
// 如果没有任何分支(首次初始化),将初始流程保存为一个分支
|
|
||||||
if (savedBranches.length === 0) {
|
if (savedBranches.length === 0) {
|
||||||
const initialBranchNodes = newNodes.filter(node => node.id !== 'root-goal')
|
const initialBranchNodes = newNodes.filter(node => node.id !== 'root-goal')
|
||||||
const initialBranchEdges = [...newEdges]
|
const initialBranchEdges = [...newEdges]
|
||||||
@@ -406,7 +413,7 @@ const initializeFlow = () => {
|
|||||||
sessionStorage.setItem(BRANCHES_INIT_KEY, 'true')
|
sessionStorage.setItem(BRANCHES_INIT_KEY, 'true')
|
||||||
}
|
}
|
||||||
|
|
||||||
// 后续初始化:从 store 恢复所有分支节点
|
// 从 store 恢复分支
|
||||||
if (savedBranches.length > 0) {
|
if (savedBranches.length > 0) {
|
||||||
savedBranches.forEach(branch => {
|
savedBranches.forEach(branch => {
|
||||||
branch.nodes.forEach(node => {
|
branch.nodes.forEach(node => {
|
||||||
@@ -425,7 +432,7 @@ const initializeFlow = () => {
|
|||||||
.map(node => node.id)
|
.map(node => node.id)
|
||||||
selectedNodeIds.value = new Set(mainProcessNodeIds)
|
selectedNodeIds.value = new Set(mainProcessNodeIds)
|
||||||
|
|
||||||
// 只在首次挂载后初始化时适应视图,后续数据变化不适应
|
// 首次挂载后适应视图
|
||||||
if (isMounted.value && !isInitialized.value) {
|
if (isMounted.value && !isInitialized.value) {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@@ -437,15 +444,15 @@ const initializeFlow = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 监听 currentTask 变化,自动高亮对应分支并更新节点数据
|
// 监听 currentTask 变化
|
||||||
watch(
|
watch(
|
||||||
() => agentsStore.currentTask,
|
() => agentsStore.currentTask,
|
||||||
(newTask, oldTask) => {
|
newTask => {
|
||||||
if (!newTask) {
|
if (!newTask) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1. 找到包含 currentTask 的分支
|
// 找到包含 currentTask 的分支
|
||||||
const allBranches = selectionStore.getAllFlowBranches()
|
const allBranches = selectionStore.getAllFlowBranches()
|
||||||
|
|
||||||
const matchedBranch = allBranches.find(branch => {
|
const matchedBranch = allBranches.find(branch => {
|
||||||
@@ -456,7 +463,7 @@ watch(
|
|||||||
const branchNodeIds = matchedBranch.nodes.map(node => node.id)
|
const branchNodeIds = matchedBranch.nodes.map(node => node.id)
|
||||||
selectedNodeIds.value = new Set(branchNodeIds)
|
selectedNodeIds.value = new Set(branchNodeIds)
|
||||||
|
|
||||||
// 更新对应节点的 task 数据(同步 AgentAllocation 中的修改)
|
// 更新节点数据
|
||||||
if (newTask.StepName) {
|
if (newTask.StepName) {
|
||||||
const matchedNodes = nodes.value.filter(node => {
|
const matchedNodes = nodes.value.filter(node => {
|
||||||
return node.data?.task?.StepName === newTask.StepName
|
return node.data?.task?.StepName === newTask.StepName
|
||||||
@@ -474,11 +481,24 @@ watch(
|
|||||||
})
|
})
|
||||||
|
|
||||||
const nodeIndex = nodes.value.findIndex(n => n.id === node.id)
|
const nodeIndex = nodes.value.findIndex(n => n.id === node.id)
|
||||||
|
// if (nodeIndex !== -1) {
|
||||||
|
// const updatedNode = {
|
||||||
|
// ...nodes.value[nodeIndex],
|
||||||
|
// data: {
|
||||||
|
// ...nodes.value[nodeIndex].data,
|
||||||
|
// task: { ...newTask },
|
||||||
|
// updateKey: newUpdateKey
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// nodes.value.splice(nodeIndex, 1, updatedNode)
|
||||||
|
// }
|
||||||
if (nodeIndex !== -1) {
|
if (nodeIndex !== -1) {
|
||||||
|
const existingNode = nodes.value[nodeIndex]
|
||||||
|
const existingData = existingNode?.data || {}
|
||||||
const updatedNode = {
|
const updatedNode = {
|
||||||
...nodes.value[nodeIndex],
|
...existingNode,
|
||||||
data: {
|
data: {
|
||||||
...nodes.value[nodeIndex].data,
|
...existingData,
|
||||||
task: { ...newTask },
|
task: { ...newTask },
|
||||||
updateKey: newUpdateKey
|
updateKey: newUpdateKey
|
||||||
}
|
}
|
||||||
@@ -497,7 +517,7 @@ onMounted(() => {
|
|||||||
isMounted.value = true
|
isMounted.value = true
|
||||||
initializeFlow()
|
initializeFlow()
|
||||||
|
|
||||||
// 主动同步 currentTask 数据到节点(解决组件晚挂载的问题)
|
// 同步 currentTask 数据
|
||||||
if (agentsStore.currentTask && agentsStore.currentTask.StepName) {
|
if (agentsStore.currentTask && agentsStore.currentTask.StepName) {
|
||||||
const matchedNodes = nodes.value.filter(node => {
|
const matchedNodes = nodes.value.filter(node => {
|
||||||
return node.data?.task?.StepName === agentsStore.currentTask!.StepName
|
return node.data?.task?.StepName === agentsStore.currentTask!.StepName
|
||||||
@@ -508,10 +528,12 @@ onMounted(() => {
|
|||||||
const nodeIndex = nodes.value.findIndex(n => n.id === node.id)
|
const nodeIndex = nodes.value.findIndex(n => n.id === node.id)
|
||||||
|
|
||||||
if (nodeIndex !== -1) {
|
if (nodeIndex !== -1) {
|
||||||
|
const existingNode = nodes.value[nodeIndex]
|
||||||
|
const existingData = existingNode?.data || {}
|
||||||
const updatedNode = {
|
const updatedNode = {
|
||||||
...nodes.value[nodeIndex],
|
...existingNode,
|
||||||
data: {
|
data: {
|
||||||
...nodes.value[nodeIndex].data,
|
...existingData,
|
||||||
task: { ...agentsStore.currentTask! },
|
task: { ...agentsStore.currentTask! },
|
||||||
updateKey: newUpdateKey
|
updateKey: newUpdateKey
|
||||||
}
|
}
|
||||||
@@ -537,7 +559,7 @@ const onNodeClick = (event: any) => {
|
|||||||
const nodeId = event.node.id
|
const nodeId = event.node.id
|
||||||
const nodeData = event.node.data as any
|
const nodeData = event.node.data as any
|
||||||
|
|
||||||
// 如果点击的是根节点,不做处理(根节点不参与高亮)
|
// 根节点不参与高亮
|
||||||
if (nodeId === 'root-goal') {
|
if (nodeId === 'root-goal') {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -549,7 +571,7 @@ const onNodeClick = (event: any) => {
|
|||||||
// 点击的是主流程节点,高亮所有主流程节点
|
// 点击的是主流程节点,高亮所有主流程节点
|
||||||
nodesToHighlight = nodes.value.filter(node => isMainProcessNode(node.id)).map(node => node.id)
|
nodesToHighlight = nodes.value.filter(node => isMainProcessNode(node.id)).map(node => node.id)
|
||||||
|
|
||||||
// 🆕 切换到初始流程分支
|
// 切换到初始流程分支
|
||||||
const allBranches = selectionStore.getAllFlowBranches()
|
const allBranches = selectionStore.getAllFlowBranches()
|
||||||
const initialBranch = allBranches.find(branch => branch.branchContent === '初始流程')
|
const initialBranch = allBranches.find(branch => branch.branchContent === '初始流程')
|
||||||
|
|
||||||
@@ -598,7 +620,7 @@ const onNodeClick = (event: any) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (matchedBranch) {
|
if (matchedBranch) {
|
||||||
// 🆕 按照高亮路径顺序收集每个节点的任务数据
|
// 按照高亮路径顺序收集每个节点的任务数据
|
||||||
const fullProcessTasks: IRawStepTask[] = []
|
const fullProcessTasks: IRawStepTask[] = []
|
||||||
const allBranches = selectionStore.getAllFlowBranches()
|
const allBranches = selectionStore.getAllFlowBranches()
|
||||||
|
|
||||||
@@ -635,7 +657,7 @@ const onNodeClick = (event: any) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// 🆕 保存最后选中的分支ID
|
// 保存最后选中的分支ID
|
||||||
sessionStorage.setItem(LAST_SELECTED_BRANCH_KEY, matchedBranch.id)
|
sessionStorage.setItem(LAST_SELECTED_BRANCH_KEY, matchedBranch.id)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -648,15 +670,7 @@ const onNodeClick = (event: any) => {
|
|||||||
selectedNodeIds.value = new Set(nodesToHighlight)
|
selectedNodeIds.value = new Set(nodesToHighlight)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 编辑任务
|
// 开始添加分支
|
||||||
const handleEditTask = (taskId: string) => {
|
|
||||||
const node = nodes.value.find(n => n.id === taskId)
|
|
||||||
if (node && node.data.task) {
|
|
||||||
editingTasks.value[taskId] = node.data.task.TaskContent || ''
|
|
||||||
node.data.isEditing = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 开始添加分支(确保同一时间只有一个输入框)
|
|
||||||
const handleStartAddBranch = (nodeId: string) => {
|
const handleStartAddBranch = (nodeId: string) => {
|
||||||
currentAddingBranchNodeId.value = nodeId
|
currentAddingBranchNodeId.value = nodeId
|
||||||
}
|
}
|
||||||
@@ -668,42 +682,39 @@ const handleCancelAddBranch = () => {
|
|||||||
|
|
||||||
// 添加分支
|
// 添加分支
|
||||||
const handleAddBranch = async (taskId: string, branchContent: string) => {
|
const handleAddBranch = async (taskId: string, branchContent: string) => {
|
||||||
// 获取父节点
|
// 获取父节点数据
|
||||||
const parentNode = nodes.value.find(n => n.id === taskId)
|
const parentNode = nodes.value.find(n => n.id === taskId)
|
||||||
if (!parentNode) return
|
if (!parentNode) return
|
||||||
|
|
||||||
// ==================== 移动已有分支 ====================
|
// 查找已有分支节点
|
||||||
// 查找所有已有的分支任务节点(标记为 isBranchTask)
|
|
||||||
const allExistingBranchNodes = nodes.value.filter(n => n.data.isBranchTask)
|
const allExistingBranchNodes = nodes.value.filter(n => n.data.isBranchTask)
|
||||||
|
|
||||||
// 🆕 只移动在当前父节点下方的分支节点(Y坐标 > 父节点Y坐标)
|
// 移动父节点下方的分支
|
||||||
const parentNodeY = parentNode.position.y
|
const parentNodeY = parentNode.position.y
|
||||||
const branchesBelowParent = allExistingBranchNodes.filter(node => node.position.y > parentNodeY)
|
const branchesBelowParent = allExistingBranchNodes.filter(node => node.position.y > parentNodeY)
|
||||||
|
|
||||||
// 将当前父节点下方的分支向下移动200px
|
// 向下移动分支
|
||||||
branchesBelowParent.forEach(node => {
|
branchesBelowParent.forEach(node => {
|
||||||
node.position.y += 200
|
node.position.y += 200
|
||||||
})
|
})
|
||||||
|
|
||||||
// 开始加载
|
// 加载中
|
||||||
branchLoading.value = true
|
branchLoading.value = true
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 创建分支节点ID
|
// 创建分支节点ID
|
||||||
const branchId = `branch-${Date.now()}`
|
const branchId = `branch-${Date.now()}`
|
||||||
|
|
||||||
// 计算分支节点位置
|
// 计算分支位置
|
||||||
// 根节点分支:向下分叉
|
|
||||||
// 任务节点分支:向右下方分叉
|
|
||||||
let branchX: number
|
let branchX: number
|
||||||
let branchY: number
|
let branchY: number
|
||||||
|
|
||||||
if (taskId === 'root-goal') {
|
if (taskId === 'root-goal') {
|
||||||
// 根节点分支:在根节点下方
|
// 根节点分支位置
|
||||||
branchX = parentNode.position.x
|
branchX = parentNode.position.x
|
||||||
branchY = parentNode.position.y + 200
|
branchY = parentNode.position.y + 200
|
||||||
} else {
|
} else {
|
||||||
// 任务节点分支:在任务节点右下方
|
// 任务节点分支位置
|
||||||
branchX = parentNode.position.x + 200
|
branchX = parentNode.position.x + 200
|
||||||
branchY = parentNode.position.y + 150
|
branchY = parentNode.position.y + 150
|
||||||
}
|
}
|
||||||
@@ -770,11 +781,18 @@ const handleAddBranch = async (taskId: string, branchContent: string) => {
|
|||||||
goal: generalGoal
|
goal: generalGoal
|
||||||
})
|
})
|
||||||
|
|
||||||
// 直接获取协作流程数据(API 返回二维数组 [[task1, task2, ...]],取第一个分支)
|
// 直接获取协作流程数据
|
||||||
newTasks = response?.[0] || []
|
// newTasks = response?.[0] || []
|
||||||
|
// 直接获取协作流程数据:兼容返回数组或对象的情况,优先处理二维数组返回
|
||||||
// 调试日志:验证数据提取
|
if (Array.isArray(response)) {
|
||||||
|
// 可能是二维数组
|
||||||
|
newTasks = (response as any[])[0] || []
|
||||||
|
} else if (response && (response as any)['Collaboration Process']) {
|
||||||
|
// 如果返回的是对象,尝试读取 Collaboration Process 字段
|
||||||
|
newTasks = (response as any)['Collaboration Process'] || []
|
||||||
|
} else {
|
||||||
|
newTasks = []
|
||||||
|
}
|
||||||
// ========== 填充每个任务的 TaskProcess ==========
|
// ========== 填充每个任务的 TaskProcess ==========
|
||||||
for (let i = 0; i < newTasks.length; i++) {
|
for (let i = 0; i < newTasks.length; i++) {
|
||||||
const task = newTasks[i]
|
const task = newTasks[i]
|
||||||
@@ -834,7 +852,7 @@ const handleAddBranch = async (taskId: string, branchContent: string) => {
|
|||||||
|
|
||||||
// 创建连接边
|
// 创建连接边
|
||||||
if (index === 0) {
|
if (index === 0) {
|
||||||
// 第一个任务连接到父节点(从根节点底部到第一个任务左边)
|
// 连接到父节点
|
||||||
const newEdge: Edge = {
|
const newEdge: Edge = {
|
||||||
id: `edge-${taskId}-${taskNodeId}`,
|
id: `edge-${taskId}-${taskNodeId}`,
|
||||||
source: taskId,
|
source: taskId,
|
||||||
@@ -844,7 +862,13 @@ const handleAddBranch = async (taskId: string, branchContent: string) => {
|
|||||||
type: 'smoothstep',
|
type: 'smoothstep',
|
||||||
animated: true,
|
animated: true,
|
||||||
style: { stroke: '#409eff', strokeWidth: 2, strokeDasharray: '5,5' },
|
style: { stroke: '#409eff', strokeWidth: 2, strokeDasharray: '5,5' },
|
||||||
label: ''
|
markerEnd: {
|
||||||
|
type: 'arrow' as any,
|
||||||
|
color: '#43a8aa',
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
strokeWidth: 2
|
||||||
|
}
|
||||||
}
|
}
|
||||||
edges.value.push(newEdge)
|
edges.value.push(newEdge)
|
||||||
newBranchEdges.push(newEdge)
|
newBranchEdges.push(newEdge)
|
||||||
@@ -859,7 +883,14 @@ const handleAddBranch = async (taskId: string, branchContent: string) => {
|
|||||||
targetHandle: 'left',
|
targetHandle: 'left',
|
||||||
type: 'smoothstep',
|
type: 'smoothstep',
|
||||||
animated: true,
|
animated: true,
|
||||||
style: { stroke: '#409eff', strokeWidth: 2 }
|
style: { stroke: '#409eff', strokeWidth: 2 },
|
||||||
|
markerEnd: {
|
||||||
|
type: 'arrow' as any,
|
||||||
|
color: '#43a8aa',
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
strokeWidth: 2
|
||||||
|
}
|
||||||
}
|
}
|
||||||
edges.value.push(newEdge)
|
edges.value.push(newEdge)
|
||||||
newBranchEdges.push(newEdge)
|
newBranchEdges.push(newEdge)
|
||||||
@@ -867,7 +898,7 @@ const handleAddBranch = async (taskId: string, branchContent: string) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 保存分支数据到 store
|
// 保存分支到 store
|
||||||
if (newBranchNodes.length > 0) {
|
if (newBranchNodes.length > 0) {
|
||||||
selectionStore.addFlowBranch({
|
selectionStore.addFlowBranch({
|
||||||
parentNodeId: taskId,
|
parentNodeId: taskId,
|
||||||
@@ -886,7 +917,7 @@ const handleAddBranch = async (taskId: string, branchContent: string) => {
|
|||||||
const newBranchNodes: Node[] = []
|
const newBranchNodes: Node[] = []
|
||||||
const newBranchEdges: Edge[] = []
|
const newBranchEdges: Edge[] = []
|
||||||
|
|
||||||
// 🆕 判断父节点是否是分支节点
|
// 判断父节点是否是分支节点
|
||||||
const parentIsBranchTask = parentNode.data.isBranchTask || false
|
const parentIsBranchTask = parentNode.data.isBranchTask || false
|
||||||
|
|
||||||
if (USE_MOCK_DATA) {
|
if (USE_MOCK_DATA) {
|
||||||
@@ -894,7 +925,7 @@ const handleAddBranch = async (taskId: string, branchContent: string) => {
|
|||||||
const generalGoal = agentsStore.agentRawPlan.data?.['General Goal'] || ''
|
const generalGoal = agentsStore.agentRawPlan.data?.['General Goal'] || ''
|
||||||
const initialInput = agentsStore.agentRawPlan.data?.['Initial Input Object'] || []
|
const initialInput = agentsStore.agentRawPlan.data?.['Initial Input Object'] || []
|
||||||
|
|
||||||
// 🆕 根据父节点类型构建 existingSteps
|
// 根据父节点类型构建 existingSteps
|
||||||
let existingSteps: any[] = []
|
let existingSteps: any[] = []
|
||||||
let baselineCompletion = 0
|
let baselineCompletion = 0
|
||||||
|
|
||||||
@@ -958,8 +989,6 @@ const handleAddBranch = async (taskId: string, branchContent: string) => {
|
|||||||
|
|
||||||
// 从响应中获取协作流程数据
|
// 从响应中获取协作流程数据
|
||||||
newTasks = response['Collaboration Process'] || []
|
newTasks = response['Collaboration Process'] || []
|
||||||
|
|
||||||
// ========== 填充每个任务的 TaskProcess ==========
|
|
||||||
for (let i = 0; i < newTasks.length; i++) {
|
for (let i = 0; i < newTasks.length; i++) {
|
||||||
const task = newTasks[i]
|
const task = newTasks[i]
|
||||||
if (!task) continue
|
if (!task) continue
|
||||||
@@ -984,7 +1013,7 @@ const handleAddBranch = async (taskId: string, branchContent: string) => {
|
|||||||
const generalGoal = agentsStore.agentRawPlan.data?.['General Goal'] || ''
|
const generalGoal = agentsStore.agentRawPlan.data?.['General Goal'] || ''
|
||||||
const initialInput = agentsStore.agentRawPlan.data?.['Initial Input Object'] || []
|
const initialInput = agentsStore.agentRawPlan.data?.['Initial Input Object'] || []
|
||||||
|
|
||||||
// 🆕 根据父节点类型构建 existingSteps
|
//根据父节点类型构建 existingSteps
|
||||||
let existingSteps: any[] = []
|
let existingSteps: any[] = []
|
||||||
let baselineCompletion = 0
|
let baselineCompletion = 0
|
||||||
|
|
||||||
@@ -1045,12 +1074,17 @@ const handleAddBranch = async (taskId: string, branchContent: string) => {
|
|||||||
initialInputs: Array.isArray(initialInput) ? initialInput : [initialInput],
|
initialInputs: Array.isArray(initialInput) ? initialInput : [initialInput],
|
||||||
goal: generalGoal
|
goal: generalGoal
|
||||||
})
|
})
|
||||||
|
// 直接获取协作流程数据
|
||||||
console.log('API Response:', response)
|
// newTasks = response?.[0] || []
|
||||||
// 直接获取协作流程数据(API 返回二维数组 [[task1, task2, ...]],取第一个分支)
|
if (Array.isArray(response)) {
|
||||||
newTasks = response?.[0] || []
|
// 可能是二维数组
|
||||||
console.log('获取到的新newTasks:', newTasks)
|
newTasks = (response as any[])[0] || []
|
||||||
// ========== 填充每个任务的 TaskProcess ==========
|
} else if (response && (response as any)['Collaboration Process']) {
|
||||||
|
// 如果返回的是对象,尝试读取 Collaboration Process 字段
|
||||||
|
newTasks = (response as any)['Collaboration Process'] || []
|
||||||
|
} else {
|
||||||
|
newTasks = []
|
||||||
|
}
|
||||||
for (let i = 0; i < newTasks.length; i++) {
|
for (let i = 0; i < newTasks.length; i++) {
|
||||||
const task = newTasks[i]
|
const task = newTasks[i]
|
||||||
if (!task) continue
|
if (!task) continue
|
||||||
@@ -1118,7 +1152,13 @@ const handleAddBranch = async (taskId: string, branchContent: string) => {
|
|||||||
type: 'smoothstep',
|
type: 'smoothstep',
|
||||||
animated: true,
|
animated: true,
|
||||||
style: { stroke: '#67c23a', strokeWidth: 2, strokeDasharray: '5,5' },
|
style: { stroke: '#67c23a', strokeWidth: 2, strokeDasharray: '5,5' },
|
||||||
label: ''
|
markerEnd: {
|
||||||
|
type: 'arrow' as any,
|
||||||
|
color: '#43a8aa',
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
strokeWidth: 2
|
||||||
|
}
|
||||||
}
|
}
|
||||||
edges.value.push(newEdge)
|
edges.value.push(newEdge)
|
||||||
newBranchEdges.push(newEdge)
|
newBranchEdges.push(newEdge)
|
||||||
@@ -1133,7 +1173,14 @@ const handleAddBranch = async (taskId: string, branchContent: string) => {
|
|||||||
targetHandle: 'left',
|
targetHandle: 'left',
|
||||||
type: 'smoothstep',
|
type: 'smoothstep',
|
||||||
animated: true,
|
animated: true,
|
||||||
style: { stroke: '#67c23a', strokeWidth: 2 }
|
style: { stroke: '#67c23a', strokeWidth: 2 },
|
||||||
|
markerEnd: {
|
||||||
|
type: 'arrow' as any,
|
||||||
|
color: '#43a8aa',
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
strokeWidth: 2
|
||||||
|
}
|
||||||
}
|
}
|
||||||
edges.value.push(newEdge)
|
edges.value.push(newEdge)
|
||||||
newBranchEdges.push(newEdge)
|
newBranchEdges.push(newEdge)
|
||||||
@@ -1141,7 +1188,7 @@ const handleAddBranch = async (taskId: string, branchContent: string) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 📂 保存分支数据到 store(新增)
|
// 保存分支数据到 store
|
||||||
if (newBranchNodes.length > 0) {
|
if (newBranchNodes.length > 0) {
|
||||||
selectionStore.addFlowBranch({
|
selectionStore.addFlowBranch({
|
||||||
parentNodeId: taskId,
|
parentNodeId: taskId,
|
||||||
@@ -1157,7 +1204,7 @@ const handleAddBranch = async (taskId: string, branchContent: string) => {
|
|||||||
// 重置当前添加分支的节点 ID
|
// 重置当前添加分支的节点 ID
|
||||||
currentAddingBranchNodeId.value = null
|
currentAddingBranchNodeId.value = null
|
||||||
|
|
||||||
// 适应视图以显示新节点
|
// 适应视图
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
fit({ padding: 100, duration: 300 })
|
fit({ padding: 100, duration: 300 })
|
||||||
@@ -1172,21 +1219,12 @@ const handleAddBranch = async (taskId: string, branchContent: string) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除分支
|
|
||||||
const handleDeleteBranch = (branchId: string) => {
|
|
||||||
// 删除分支节点
|
|
||||||
nodes.value = nodes.value.filter(n => n.id !== branchId)
|
|
||||||
|
|
||||||
// 删除相关的边
|
|
||||||
edges.value = edges.value.filter(e => e.source !== branchId && e.target !== branchId)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 重置视图
|
// 重置视图
|
||||||
const resetView = () => {
|
const resetView = () => {
|
||||||
setTransform({ x: 0, y: 0, zoom: 0.5 })
|
setTransform({ x: 0, y: 0, zoom: 0.5 })
|
||||||
}
|
}
|
||||||
|
|
||||||
// 重置初始化状态并重新适应视图
|
// 重新适应视图
|
||||||
const refitView = () => {
|
const refitView = () => {
|
||||||
isInitialized.value = false
|
isInitialized.value = false
|
||||||
sessionStorage.removeItem(INIT_KEY)
|
sessionStorage.removeItem(INIT_KEY)
|
||||||
@@ -1199,7 +1237,7 @@ const refitView = () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 暴露方法给父组件
|
// 暴露方法
|
||||||
defineExpose({
|
defineExpose({
|
||||||
initializeFlow,
|
initializeFlow,
|
||||||
resetView,
|
resetView,
|
||||||
|
|||||||
@@ -335,7 +335,7 @@ const handleBranchKeydown = (event: KeyboardEvent) => {
|
|||||||
|
|
||||||
.el-input__inner {
|
.el-input__inner {
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
color: var(--color-text-primary);
|
color: #000;
|
||||||
padding-right: 40px;
|
padding-right: 40px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -476,7 +476,7 @@ const handleBranchKeydown = (event: KeyboardEvent) => {
|
|||||||
|
|
||||||
.el-input__inner {
|
.el-input__inner {
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
color: var(--color-text-primary);
|
color: #000;
|
||||||
padding-right: 40px;
|
padding-right: 40px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ const isDisabled = computed(() => {
|
|||||||
return !agentsStore.currentTask
|
return !agentsStore.currentTask
|
||||||
})
|
})
|
||||||
|
|
||||||
// 获取agent组合卡片数量 - 当前任务agents(1) + 已确认的agent组合数量
|
// 获取agent组合卡片数量
|
||||||
const agentGroupCount = computed(() => {
|
const agentGroupCount = computed(() => {
|
||||||
if (!agentsStore.currentTask?.Id) return 1
|
if (!agentsStore.currentTask?.Id) return 1
|
||||||
|
|
||||||
|
|||||||
@@ -8,16 +8,15 @@ const emit = defineEmits<{
|
|||||||
(e: 'click'): void
|
(e: 'click'): void
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
// 获取分支数量 - 主分支(1) + 额外分支数量
|
// 获取分支数量
|
||||||
const branchCount = computed(() => {
|
const branchCount = computed(() => {
|
||||||
// flowBranches 包含所有通过 Branch 创建的分支
|
// flowBranches 包含所有通过 Branch 创建的分支
|
||||||
const extraBranches = selectionStore.flowBranches?.length || 1
|
const extraBranches = selectionStore.flowBranches?.length || 1
|
||||||
// 始终至少有1个主分支
|
|
||||||
return extraBranches
|
return extraBranches
|
||||||
})
|
})
|
||||||
|
|
||||||
const handleClick = () => {
|
const handleClick = () => {
|
||||||
// console.log('点击分支按钮')
|
|
||||||
emit('click')
|
emit('click')
|
||||||
// 触发打开分支窗口
|
// 触发打开分支窗口
|
||||||
agentsStore.openPlanModification()
|
agentsStore.openPlanModification()
|
||||||
|
|||||||
@@ -201,10 +201,8 @@ function clear() {
|
|||||||
jsplumb.reset()
|
jsplumb.reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 🆕 封装连线重绘方法
|
// 封装连线重绘方法
|
||||||
const redrawConnections = () => {
|
const redrawConnections = () => {
|
||||||
console.log('🔄 重新绘制 jsplumb 连线')
|
|
||||||
|
|
||||||
// 等待 DOM 更新完成
|
// 等待 DOM 更新完成
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
// 清除旧连线
|
// 清除旧连线
|
||||||
@@ -221,22 +219,20 @@ const redrawConnections = () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
jsplumb.connects(arr)
|
jsplumb.connects(arr)
|
||||||
console.log('✅ jsplumb 连线重绘完成,任务数:', collaborationProcess.value.length)
|
|
||||||
}, 100)
|
}, 100)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 🆕 监听 collaborationProcess 变化,自动重绘连线
|
// 监听 collaborationProcess 变化,自动重绘连线
|
||||||
watch(
|
watch(
|
||||||
() => collaborationProcess,
|
() => collaborationProcess,
|
||||||
() => {
|
() => {
|
||||||
console.log('🔍 collaborationProcess 发生变化,触发重绘')
|
|
||||||
redrawConnections()
|
redrawConnections()
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
// 🆕 组件挂载后初始化连线
|
// 组件挂载后初始化连线
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 初始化时绘制连线
|
// 初始化时绘制连线
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
@@ -246,7 +242,6 @@ onMounted(() => {
|
|||||||
arr.push(...handleCurrentTask(item, true))
|
arr.push(...handleCurrentTask(item, true))
|
||||||
})
|
})
|
||||||
jsplumb.connects(arr)
|
jsplumb.connects(arr)
|
||||||
console.log('✅ 初始化 jsplumb 连线完成')
|
|
||||||
}, 100)
|
}, 100)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -440,7 +435,7 @@ defineExpose({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<BranchButton v-dev-only v-if="planReady" @click="openPlanModification" />
|
<BranchButton v-if="planReady" @click="openPlanModification" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
Reference in New Issue
Block a user