diff --git a/.env.micro b/.env.micro index 514cf7d595e269ceb201aae2b06423b2e4852221..79b12e939ef8e3680f37fa5c70b8c307ca325a4c 100755 --- a/.env.micro +++ b/.env.micro @@ -1,3 +1,3 @@ VITE_BASE_URL=/copilot/ VITE_MICRO_ROUTER_URL=/eulercopilot/ -VITE_BASE_PROXY_URL=http://localhost:8002 +VITE_BASE_PROXY_URL=http://10.211.55.10:8002 diff --git a/src/api/variable.js b/src/api/variable.js index 7f726adfb479de8285b8d700cd2317becf154691..37dd80e869c378271e5ebc0fb4c73b6e5b5a12ca 100644 --- a/src/api/variable.js +++ b/src/api/variable.js @@ -46,6 +46,10 @@ export async function deleteVariable(params) { /** * 获取单个变量 * @param {Object} params 查询参数 + * @param {string} params.name 变量名称 + * @param {string} params.scope 变量作用域 (user|env|system|conversation) + * @param {string} [params.flow_id] 流程ID(环境级和对话级变量必需) + * @param {string} [params.conversation_id] 对话ID(系统级和对话级变量必需) */ export async function getVariable(params) { const [error, response] = await get(`${BASE_URL}/get`, params) @@ -56,6 +60,9 @@ export async function getVariable(params) { /** * 列出变量 * @param {Object} params 查询参数 + * @param {string} params.scope 变量作用域 (user|env|system|conversation) + * @param {string} [params.flow_id] 流程ID(环境级和对话级变量必需) + * @param {string} [params.conversation_id] 对话ID(系统级和对话级变量必需) */ export async function listVariables(params = {}) { const [error, response] = await get(`${BASE_URL}/list`, params) @@ -91,4 +98,165 @@ export async function clearConversationVariables(params) { const [error, response] = await post(`${BASE_URL}/clear-conversation`, {}, params) if (error) throw error return response +} + +// ========== 便利函数 ========== + +/** + * 列出用户变量 + * @returns {Promise} 用户变量列表 + */ +export async function listUserVariables() { + return await listVariables({ scope: 'user' }) +} + +/** + * 列出环境变量 + * @param {string} flowId 流程ID + * @returns {Promise} 环境变量列表 + */ +export async function listEnvironmentVariables(flowId) { + if (!flowId) { + throw new Error('流程ID是必需的') + } + return await listVariables({ + scope: 'env', + flow_id: flowId + }) +} + +/** + * 列出系统变量 + * @param {string} conversationId 对话ID + * @returns {Promise} 系统变量列表 + */ +export async function listSystemVariables(conversationId) { + if (!conversationId) { + throw new Error('对话ID是必需的') + } + return await listVariables({ + scope: 'system', + conversation_id: conversationId + }) +} + +/** + * 列出对话变量 + * @param {string} conversationId 对话ID + * @returns {Promise} 对话变量列表 + */ +export async function listConversationVariables(conversationId) { + if (!conversationId) { + throw new Error('对话ID是必需的') + } + return await listVariables({ + scope: 'conversation', + conversation_id: conversationId + }) +} + +/** + * 获取用户变量 + * @param {string} name 变量名称 + * @returns {Promise} 变量信息 + */ +export async function getUserVariable(name) { + return await getVariable({ + name, + scope: 'user' + }) +} + +/** + * 获取环境变量 + * @param {string} name 变量名称 + * @param {string} flowId 流程ID + * @returns {Promise} 变量信息 + */ +export async function getEnvironmentVariable(name, flowId) { + if (!flowId) { + throw new Error('流程ID是必需的') + } + return await getVariable({ + name, + scope: 'env', + flow_id: flowId + }) +} + +/** + * 获取系统变量 + * @param {string} name 变量名称 + * @param {string} conversationId 对话ID + * @returns {Promise} 变量信息 + */ +export async function getSystemVariable(name, conversationId) { + if (!conversationId) { + throw new Error('对话ID是必需的') + } + return await getVariable({ + name, + scope: 'system', + conversation_id: conversationId + }) +} + +/** + * 获取对话变量 + * @param {string} name 变量名称 + * @param {string} conversationId 对话ID + * @returns {Promise} 变量信息 + */ +export async function getConversationVariable(name, conversationId) { + if (!conversationId) { + throw new Error('对话ID是必需的') + } + return await getVariable({ + name, + scope: 'conversation', + conversation_id: conversationId + }) +} + +/** + * 创建用户变量 + * @param {Object} data 变量数据 + */ +export async function createUserVariable(data) { + return await createVariable({ + ...data, + scope: 'user' + }) +} + +/** + * 创建环境变量 + * @param {Object} data 变量数据 + * @param {string} flowId 流程ID + */ +export async function createEnvironmentVariable(data, flowId) { + if (!flowId) { + throw new Error('流程ID是必需的') + } + return await createVariable({ + ...data, + scope: 'env', + flow_id: flowId + }) +} + +/** + * 创建对话变量模板(在流程级别定义) + * @param {Object} data 变量数据 + * @param {string} flowId 流程ID + */ +export async function createConversationVariableTemplate(data, flowId) { + if (!flowId) { + throw new Error('流程ID是必需的') + } + return await createVariable({ + ...data, + scope: 'conversation', + flow_id: flowId + }) } \ No newline at end of file diff --git a/src/components/JSONMonacoEditor.vue b/src/components/JSONMonacoEditor.vue index b7e0dd4389964476e9ea3928dafa34ad89b480d7..7c652a984e5727c3ce21902ac3a6bdd9d863b089 100644 --- a/src/components/JSONMonacoEditor.vue +++ b/src/components/JSONMonacoEditor.vue @@ -1,5 +1,10 @@ +/** + * VariableChooser 组件 + * + * 提供变量选择功能,支持显示变量详细信息和操作按钮 + * 现在新增了样式控制属性,可以让外部组件灵活控制显示样式 + * + * @since 1.0.0 + * @author Assistant + */ \ No newline at end of file diff --git a/src/views/createapp/components/workFlowConfig/ChoiceBranchCard.vue b/src/views/createapp/components/workFlowConfig/ChoiceBranchCard.vue new file mode 100644 index 0000000000000000000000000000000000000000..22418da90036273a9f491e105697204ca6af9d1c --- /dev/null +++ b/src/views/createapp/components/workFlowConfig/ChoiceBranchCard.vue @@ -0,0 +1,940 @@ + + + + + \ No newline at end of file diff --git a/src/views/createapp/components/workFlowConfig/ChoiceBranchDrawer.vue b/src/views/createapp/components/workFlowConfig/ChoiceBranchDrawer.vue new file mode 100644 index 0000000000000000000000000000000000000000..81d0178a9dd64ad05ab1fa8d224f23863b2e7c99 --- /dev/null +++ b/src/views/createapp/components/workFlowConfig/ChoiceBranchDrawer.vue @@ -0,0 +1,626 @@ + + + + + \ No newline at end of file diff --git a/src/views/createapp/components/workFlowConfig/ChoiceBranchNode.vue b/src/views/createapp/components/workFlowConfig/ChoiceBranchNode.vue new file mode 100644 index 0000000000000000000000000000000000000000..70972f0c5e0f5a2e069589bf453015270e9e434d --- /dev/null +++ b/src/views/createapp/components/workFlowConfig/ChoiceBranchNode.vue @@ -0,0 +1,996 @@ + + + + + \ No newline at end of file diff --git a/src/views/createapp/components/workFlowConfig/CodeNodeDrawer.vue b/src/views/createapp/components/workFlowConfig/CodeNodeDrawer.vue index 8ec4414b514288fd2065cbcd28ebe4997051c54e..46a2192e5e59e9158fdca603d853e22ed1547a43 100644 --- a/src/views/createapp/components/workFlowConfig/CodeNodeDrawer.vue +++ b/src/views/createapp/components/workFlowConfig/CodeNodeDrawer.vue @@ -83,6 +83,7 @@ v-model:selected-variable="variable.selectedVariable" :supported-scopes="['conversation', 'system', 'env']" :flow-id="flowId" + :current-step-id="nodeId" :show-variable-reference="true" :show-actions="true" :show-variable-info="true" @@ -713,7 +714,6 @@ const handleLanguageChange = (language: string) => { if (!nodeConfig.value.code || nodeConfig.value.code.trim() === '') { nodeConfig.value.code = generateTemplateByLanguage(language) } - console.log('Language changed to:', language) } const addInputVariable = () => { @@ -883,7 +883,6 @@ watch(drawerVisible, (newVal) => { // 监听nodeData变化 watch(() => props.nodeData, (newData: any) => { - console.log(newData); if (newData) { loadNodeData(newData) } diff --git a/src/views/createapp/components/workFlowConfig/CustomEdge.vue b/src/views/createapp/components/workFlowConfig/CustomEdge.vue index 1650f0456bbcae9cdc2ab41b13beeb288efedb4f..ef619955fabe29ab1a0f52be78c8850dea80ff3a 100644 --- a/src/views/createapp/components/workFlowConfig/CustomEdge.vue +++ b/src/views/createapp/components/workFlowConfig/CustomEdge.vue @@ -1,5 +1,5 @@ diff --git a/src/views/createapp/components/workFlowConfig/DirectReplyDrawer.vue b/src/views/createapp/components/workFlowConfig/DirectReplyDrawer.vue index 6dd045d04354314f6597ded8a9cb6d85d652f16e..4bc11a554dde32ce4a9f4e7eb32ffe935c336cec 100644 --- a/src/views/createapp/components/workFlowConfig/DirectReplyDrawer.vue +++ b/src/views/createapp/components/workFlowConfig/DirectReplyDrawer.vue @@ -68,6 +68,7 @@ ref="textEditorRef" v-model="nodeConfig.answer" :flow-id="flowId" + :current-step-id="nodeId" placeholder="请输入回复内容,可以使用变量插入功能..." /> diff --git a/src/views/createapp/components/workFlowConfig/EnvironmentVariableDrawer.vue b/src/views/createapp/components/workFlowConfig/EnvironmentVariableDrawer.vue new file mode 100644 index 0000000000000000000000000000000000000000..7f06c7c7ae50106384584a2e3b6ec61ab4fde5a4 --- /dev/null +++ b/src/views/createapp/components/workFlowConfig/EnvironmentVariableDrawer.vue @@ -0,0 +1,714 @@ + + + + + \ No newline at end of file diff --git a/src/views/createapp/components/workFlowConfig/NodeListPanel.vue b/src/views/createapp/components/workFlowConfig/NodeListPanel.vue new file mode 100644 index 0000000000000000000000000000000000000000..4458aa3b33421465199633c9b5018588751fd2db --- /dev/null +++ b/src/views/createapp/components/workFlowConfig/NodeListPanel.vue @@ -0,0 +1,366 @@ + + + + + \ No newline at end of file diff --git a/src/views/createapp/components/workFlowConfig/VariableBasedStartNodeDrawer.vue b/src/views/createapp/components/workFlowConfig/VariableBasedStartNodeDrawer.vue index 6028e970150ff7e915d14d836b0832eb62f6eb69..4509ccf7d58b6fc200e18470249fcc04bf7f8f44 100644 --- a/src/views/createapp/components/workFlowConfig/VariableBasedStartNodeDrawer.vue +++ b/src/views/createapp/components/workFlowConfig/VariableBasedStartNodeDrawer.vue @@ -243,75 +243,14 @@ const emits = defineEmits(['closeDrawer', 'saveStartNode', 'variablesUpdated', ' const loadAllVariables = async () => { variablesLoading.value = true - try { - console.log('🔄 开始加载变量...') - - // 加载系统变量 - 修复数据结构解析 - try { - console.log('🔄 正在调用系统变量API...') - const systemResponse = await listVariables({ scope: 'system' }) - console.log('📥 系统变量API响应:', systemResponse) - - // 修复:支持多种响应数据结构 - let variables: any[] | null = null - const response = systemResponse as any // 类型断言避免TS错误 - - if (response?.result?.variables) { - // 结构1: { result: { variables: [...] } } - variables = response.result.variables - console.log('📋 使用result.variables结构') - } else if (response?.variables) { - // 结构2: { variables: [...], total: 8 } - variables = response.variables - console.log('📋 使用直接variables结构') - } else if (Array.isArray(response)) { - // 结构3: 直接返回数组 - variables = response - console.log('📋 使用数组结构') - } - - if (variables && Array.isArray(variables)) { - systemVariables.value = variables - console.log('✅ 系统变量加载成功:', systemVariables.value.length, '个') - console.log('📋 系统变量详情:', systemVariables.value.map(v => ({ - name: v.name, - type: v.var_type, - value: v.value, - description: v.description - }))) - } else { - console.log('⚠️ 未找到系统变量数据') - console.log('📋 完整响应结构:', JSON.stringify(systemResponse, null, 2)) - systemVariables.value = [] - } - } catch (systemError: any) { - console.error('❌ 系统变量加载失败:', systemError) - console.error('❌ 错误详情:', { - message: systemError.message, - stack: systemError.stack, - response: systemError.response - }) - - // 检查是否是Pydantic验证错误 - if (systemError.message?.includes('validation error')) { - console.log('🔧 检测到Pydantic验证错误,可能是系统变量值为None') - ElMessage.warning('系统变量加载失败:后端数据验证错误,请检查系统变量初始化') - } else { - ElMessage.error('系统变量加载失败') - } - systemVariables.value = [] - } - - // 加载对话变量(如果有flowId) + try { + // 加载对话变量(配置阶段使用flowId) if (props.flowId) { try { - console.log('🔄 正在调用对话变量API...') - console.log('🔍 LIST API使用的flowId:', props.flowId) const convResponse = await listVariables({ scope: 'conversation', flow_id: props.flowId }) - console.log('📥 对话变量API响应:', convResponse) // 修复:支持多种响应数据结构 let convVariables: any[] | null = null @@ -319,34 +258,60 @@ const loadAllVariables = async () => { if (convResponseAny?.result?.variables) { convVariables = convResponseAny.result.variables - console.log('📋 对话变量使用result.variables结构') } else if (convResponseAny?.variables) { convVariables = convResponseAny.variables - console.log('📋 对话变量使用直接variables结构') } else if (Array.isArray(convResponseAny)) { convVariables = convResponseAny - console.log('📋 对话变量使用数组结构') } if (convVariables && Array.isArray(convVariables)) { conversationVariables.value = convVariables - console.log('✅ 对话变量加载成功:', conversationVariables.value.length, '个') - console.log('📋 具体变量列表:', conversationVariables.value.map(v => v.name)) } else { conversationVariables.value = [] - console.log('ℹ️ 对话变量为空,设置为空数组') - console.log('📋 convVariables:', convVariables) } } catch (convError: any) { - console.error('❌ 对话变量加载失败:', convError) conversationVariables.value = [] } } else { - console.log('ℹ️ 无flowId,跳过对话变量加载') conversationVariables.value = [] } - console.log('🎉 变量加载完成') + // 加载系统变量 - 配置阶段使用flow_id,对话阶段使用conversation_id + if (props.conversationId) { + // 对话/调试阶段:使用conversation_id查询系统变量实例 + try { + const systemResponse = await listVariables({ + scope: 'system', + conversation_id: props.conversationId + }) + + // 处理响应数据 + const systemVars = (systemResponse as any)?.variables || (systemResponse as any)?.result?.variables || [] + systemVariables.value = Array.isArray(systemVars) ? systemVars : [] + } catch (error) { + console.error('❌ 系统变量加载失败(对话阶段):', error) + systemVariables.value = [] + } + } else if (props.flowId) { + // 配置阶段:使用flow_id查询系统变量模板 + try { + const systemResponse = await listVariables({ + scope: 'system', + flow_id: props.flowId + }) + + // 处理响应数据 + const systemVars = (systemResponse as any)?.variables || (systemResponse as any)?.result?.variables || [] + systemVariables.value = Array.isArray(systemVars) ? systemVars : [] + } catch (error) { + console.error('❌ 系统变量加载失败(配置阶段):', error) + systemVariables.value = [] + } + } else { + // 既没有conversation_id也没有flow_id + systemVariables.value = [] + } + } catch (error) { console.error('❌ 变量加载过程发生未知错误:', error) ElMessage.error('变量加载失败') @@ -357,30 +322,9 @@ const loadAllVariables = async () => { // 强制重新加载变量 const forceReloadVariables = async () => { - console.log('🔄 强制重新加载变量...') await loadAllVariables() } -// 直接测试API调用 -const testApiDirectly = async () => { - console.log('🧪 开始直接测试API调用...') - try { - const response = await listVariables({ scope: 'system' }) - console.log('🔬 直接API调用结果:') - console.log('- 原始响应:', response) - console.log('- 响应类型:', typeof response) - console.log('- 是否为数组:', Array.isArray(response)) - console.log('- response.variables:', (response as any)?.variables) - console.log('- response.result:', (response as any)?.result) - console.log('- response.result.variables:', (response as any)?.result?.variables) - - ElMessage.info('API测试完成,请查看控制台输出') - } catch (error) { - console.error('🔬 API测试失败:', error) - ElMessage.error('API测试失败') - } -} - // 初始化数据 - 在函数定义后设置watch watch( () => [props.yamlContent, props.nodeName, props.nodeDesc], @@ -397,7 +341,6 @@ watch( // 组件挂载时立即加载变量 onMounted(() => { - console.log('🚀 组件已挂载,开始加载变量...') nextTick(() => { loadAllVariables() }) @@ -514,10 +457,6 @@ const editConversationVariable = (variable: Variable) => { // 保存对话变量 const saveConversationVariable = async () => { - console.log('🔄 开始保存对话变量...') - console.log('📋 当前编辑变量:', editingVariable.value) - console.log('📋 工作流ID:', props.flowId) - // 详细的参数验证 if (!editingVariable.value) { ElMessage.error('缺少变量数据') @@ -561,11 +500,9 @@ const saveConversationVariable = async () => { flow_id: props.flowId } - console.log('📤 准备发送的变量数据:', variableData) if (isEditingVariable.value) { - // 更新变量 - console.log('🔄 调用更新变量API...') + // 更新变量(配置阶段使用flow_id) const updateParams = { name: editingVariable.value.name, scope: 'conversation', @@ -576,17 +513,12 @@ const saveConversationVariable = async () => { description: variableData.description, var_type: variableData.var_type // 添加变量类型字段 } - console.log('📤 更新参数:', updateParams) - console.log('📤 更新数据:', updateData) const updateResult = await updateVariable(updateParams, updateData) - console.log('📥 更新结果:', updateResult) ElMessage.success('变量更新成功') } else { // 创建变量 - console.log('🔄 调用创建变量API...') const createResult = await createVariable(variableData) - console.log('📥 创建结果:', createResult) ElMessage.success('变量创建成功') } @@ -628,20 +560,13 @@ const saveConversationVariable = async () => { } } -// 删除对话变量 +// 删除对话变量(配置阶段使用flow_id) const deleteConversationVariable = async () => { if (!editingVariable.value || !props.flowId) { console.error('❌ 删除失败:缺少必要参数', { editingVariable: editingVariable.value, flowId: props.flowId }) return } - console.log('🗑️ 开始删除变量:', { - name: editingVariable.value.name, - scope: 'conversation', - flow_id: props.flowId - }) - console.log('🔍 DELETE API使用的flowId:', props.flowId) - try { const deleteResult = await deleteVariable({ name: editingVariable.value.name, @@ -649,7 +574,6 @@ const deleteConversationVariable = async () => { flow_id: props.flowId }) - console.log('✅ 删除变量API调用成功:', deleteResult) ElMessage.success('变量删除成功') // 在关闭对话框前先保存变量名(避免引用失效) @@ -657,19 +581,15 @@ const deleteConversationVariable = async () => { handleVariableDialogClose() - // 方案1:直接从本地数组中移除(立即生效) - conversationVariables.value = conversationVariables.value.filter(v => v.name !== deletedVariableName) - console.log('🗑️ 本地移除变量后的列表:', conversationVariables.value.map(v => v.name)) + // 直接从本地数组中移除(立即生效) + // conversationVariables.value = conversationVariables.value.filter(v => v.name !== deletedVariableName) - // 方案2:延迟后重新加载(确保数据一致性) - console.log('🔄 延迟200ms后重新加载变量数据...') + // 延迟后重新加载(确保数据一致性) setTimeout(async () => { await loadAllVariables() - console.log('📊 重新加载后的对话变量:', conversationVariables.value.map(v => v.name)) }, 200) // 通知父组件变量已更新 - console.log('📡 触发变量更新事件') emits('variablesUpdated') } catch (error) { console.error('❌ 删除变量失败:', error) @@ -691,9 +611,7 @@ const closeDrawer = () => { } // 保存开始节点配置 -const saveStartNodeConfig = () => { - console.log('💾 保存开始节点配置(基于变量)') - +const saveStartNodeConfig = () => { // 构建对话变量对象用于节点显示 const conversationVariablesObj: Record = {} conversationVariables.value.forEach(variable => { @@ -710,16 +628,13 @@ const saveStartNodeConfig = () => { conversation_variables: conversationVariablesObj, variables: conversationVariablesObj // 同时保存到variables字段以兼容不同的取值方式 } - - console.log('📋 传递给节点的变量数据:', conversationVariablesObj) - + emits('saveStartNode', nodeParams, props.nodeYamlId, nodeName.value, nodeDescription.value) ElMessage.success('保存成功') closeDrawer() } onMounted(() => { - console.log('🚀 VariableBasedStartNodeDrawer 已挂载') // 确保组件挂载后初始化数据 if (props.nodeName) { nodeName.value = props.nodeName diff --git a/src/views/createapp/components/workFlowConfig/insertNodeMenu.vue b/src/views/createapp/components/workFlowConfig/insertNodeMenu.vue new file mode 100644 index 0000000000000000000000000000000000000000..6b6b067b2b3f4a68937e6366962ebfc83f4cc7a7 --- /dev/null +++ b/src/views/createapp/components/workFlowConfig/insertNodeMenu.vue @@ -0,0 +1,370 @@ + + + + + \ No newline at end of file diff --git a/src/views/createapp/components/workFlowConfig/useDnD.js b/src/views/createapp/components/workFlowConfig/useDnD.js index b69d9b145e35397811a29721e0cc46b2b83d9414..fe6ac941936addfd139f9a785b3b7a284d5d7dc8 100644 --- a/src/views/createapp/components/workFlowConfig/useDnD.js +++ b/src/views/createapp/components/workFlowConfig/useDnD.js @@ -43,7 +43,7 @@ export default function useDragAndDrop() { event.dataTransfer.setData('application/vueflow', type); event.dataTransfer.effectAllowed = 'move'; } - draggedType.value = type === 'choice' ? 'branch' : 'custom'; + draggedType.value = type === 'Choice' ? 'branch' : 'custom'; isDragging.value = true; nodeData.value = { ...info }; diff --git a/src/views/createapp/components/workFlowDebug.vue b/src/views/createapp/components/workFlowDebug.vue index e2ce2c135acc36ba9409d7f9004cad0fe8860fc0..2abf98c9ce7346325f3eb1b5d8b67ab905ea3257 100644 --- a/src/views/createapp/components/workFlowDebug.vue +++ b/src/views/createapp/components/workFlowDebug.vue @@ -1,17 +1,36 @@