|
36 | 36 |
|
37 | 37 | <!-- 中间问答主页面 --> |
38 | 38 | <div class="main-content" :style="{ width: mainContentWidth + 'px' }"> |
39 | | - <QuestionRenderer :current-question="currentQuestion" :is-loading="isLoading" @send-message="handleSendMessage" |
40 | | - @submit-answer="handleSubmitAnswer" @retry-question="handleRetryQuestion" /> |
| 39 | + <QuestionRenderer ref="questionRendererRef" :current-question="currentQuestion" :is-loading="isLoading" @send-message="handleSendMessage" |
| 40 | + @submit-answer="handleSubmitAnswer" @retry-question="handleRetryQuestion" @generate-prompt="handleGeneratePrompt" /> |
41 | 41 | </div> |
42 | 42 |
|
43 | 43 | <!-- 可拖拽的分隔条 --> |
@@ -65,6 +65,7 @@ import { ref, computed, onMounted, onUnmounted } from 'vue' |
65 | 65 | import QuestionRenderer from './QuestionRenderer.vue' |
66 | 66 | import MindMapTree from './MindMapTree.vue' |
67 | 67 | import { startConversation, sendMessage, sendUserMessage, connectSSE, closeSSE, processAnswer, connectUserInteractionSSE, retryQuestion, type MessageRequest, type MessageResponse, type ConversationSession, type UnifiedAnswerRequest, type FormAnswerItem, type RetryRequest } from '@/services/conversationApi' |
| 68 | +import { generatePrompt } from '@/services/userInteractionApi' |
68 | 69 | import { toast } from '@/utils/toast' |
69 | 70 |
|
70 | 71 | interface Message { |
@@ -121,6 +122,9 @@ const isLoading = ref(false) |
121 | 122 | // 问题状态管理 |
122 | 123 | const currentQuestion = ref<any>(null) |
123 | 124 |
|
| 125 | +// 子组件引用 |
| 126 | +const questionRendererRef = ref<any>(null) |
| 127 | +
|
124 | 128 | // 确保SSE连接唯一性 |
125 | 129 | const ensureUniqueConnection = () => { |
126 | 130 | if (eventSource.value) { |
@@ -227,6 +231,26 @@ const handleSSEMessage = (response: any) => { |
227 | 231 | updateActivity() |
228 | 232 |
|
229 | 233 | // 处理连接建立消息 |
| 234 | + if (handleConnectionMessage(response)) { |
| 235 | + return |
| 236 | + } |
| 237 | +
|
| 238 | + // 处理生成提示词消息 |
| 239 | + if (handleGenPromptMessage(response)) { |
| 240 | + return |
| 241 | + } |
| 242 | +
|
| 243 | + // 处理新问题格式消息 |
| 244 | + if (handleQuestionMessage(response)) { |
| 245 | + return |
| 246 | + } |
| 247 | +
|
| 248 | + // 处理其他类型的消息 |
| 249 | + handleOtherMessages(response) |
| 250 | +} |
| 251 | +
|
| 252 | +// 处理连接建立消息 |
| 253 | +const handleConnectionMessage = (response: any): boolean => { |
230 | 254 | if (response.type === 'connected' || response.sessionId) { |
231 | 255 | // 这是连接建立时的会话信息 |
232 | 256 | if (response.sessionId) { |
@@ -274,11 +298,47 @@ const handleSSEMessage = (response: any) => { |
274 | 298 | duration: 2000 |
275 | 299 | }) |
276 | 300 | } |
277 | | - return |
| 301 | + return true |
| 302 | + } |
| 303 | + return false |
| 304 | +} |
| 305 | +
|
| 306 | +// 处理生成提示词消息 |
| 307 | +const handleGenPromptMessage = (response: any): boolean => { |
| 308 | + if (response.genPrompt) { |
| 309 | + try { |
| 310 | + // 通过ref调用子组件的setPromptResult方法显示提示词结果 |
| 311 | + if (questionRendererRef.value && questionRendererRef.value.setPromptResult) { |
| 312 | + questionRendererRef.value.setPromptResult(response.genPrompt) |
| 313 | + |
| 314 | + toast.success({ |
| 315 | + title: '提示词生成成功', |
| 316 | + message: '已为您生成优化的提示词', |
| 317 | + duration: 3000 |
| 318 | + }) |
| 319 | + } else { |
| 320 | + console.warn('QuestionRenderer组件引用不可用,无法显示提示词结果') |
| 321 | + toast.error({ |
| 322 | + title: '显示失败', |
| 323 | + message: '无法显示提示词结果,请重试', |
| 324 | + duration: 3000 |
| 325 | + }) |
| 326 | + } |
| 327 | + } catch (error) { |
| 328 | + console.error('处理生成提示词消息失败:', error) |
| 329 | + toast.error({ |
| 330 | + title: '处理失败', |
| 331 | + message: '处理提示词结果时发生错误', |
| 332 | + duration: 3000 |
| 333 | + }) |
| 334 | + } |
| 335 | + return true |
278 | 336 | } |
| 337 | + return false |
| 338 | +} |
279 | 339 |
|
280 | | - // 处理其他类型的消息 |
281 | | - // 检查是否是新的问题格式(包含question对象) |
| 340 | +// 处理新问题格式消息 |
| 341 | +const handleQuestionMessage = (response: any): boolean => { |
282 | 342 | if (response.question && response.question.type) { |
283 | 343 | // 这是新的问题格式 |
284 | 344 | currentQuestion.value = response.question |
@@ -328,9 +388,13 @@ const handleSSEMessage = (response: any) => { |
328 | 388 |
|
329 | 389 | isLoading.value = false |
330 | 390 | // console.log('收到新格式问题:', response.question, '当前节点ID:', response.currentNodeId, '父节点ID:', response.parentNodeId) |
331 | | - return |
| 391 | + return true |
332 | 392 | } |
| 393 | + return false |
| 394 | +} |
333 | 395 |
|
| 396 | +// 处理其他类型的消息 |
| 397 | +const handleOtherMessages = (response: any) => { |
334 | 398 | const messageResponse = response as MessageResponse |
335 | 399 | switch (messageResponse.type) { |
336 | 400 | case 'AI_QUESTION': |
@@ -833,6 +897,61 @@ const handleSubmitAnswer = async (answerData: any) => { |
833 | 897 | } |
834 | 898 | } |
835 | 899 |
|
| 900 | +// 处理生成提示词 |
| 901 | +const handleGeneratePrompt = async (answerData: any) => { |
| 902 | + if (!session.value) { |
| 903 | + toast.error({ |
| 904 | + title: '生成失败', |
| 905 | + message: '会话未建立,请先开始对话', |
| 906 | + duration: 3000 |
| 907 | + }) |
| 908 | + return |
| 909 | + } |
| 910 | +
|
| 911 | + // 更新活跃时间 |
| 912 | + updateActivity() |
| 913 | +
|
| 914 | + try { |
| 915 | + // 调用生成提示词API,传入sessionId和userId |
| 916 | + const promptResult = await generatePrompt({ |
| 917 | + sessionId: session.value.sessionId, |
| 918 | + answer: answerData |
| 919 | + }) |
| 920 | +
|
| 921 | + // 通过ref获取QuestionRenderer组件实例并设置提示词结果 |
| 922 | + if (questionRendererRef.value && questionRendererRef.value.setPromptResult) { |
| 923 | + questionRendererRef.value.setPromptResult(promptResult) |
| 924 | + } |
| 925 | +
|
| 926 | + toast.success({ |
| 927 | + title: '生成成功', |
| 928 | + message: '提示词已生成完成', |
| 929 | + duration: 2000 |
| 930 | + }) |
| 931 | +
|
| 932 | + } catch (error: any) { |
| 933 | + console.error('生成提示词失败:', error) |
| 934 | + |
| 935 | + // 检查是否是会话相关错误 |
| 936 | + if (error.message && (error.message.includes('sessionId') || error.message.includes('会话'))) { |
| 937 | + toast.error({ |
| 938 | + title: '会话异常', |
| 939 | + message: '会话已失效,请刷新页面重新建立连接', |
| 940 | + duration: 5000 |
| 941 | + }) |
| 942 | + // 清理当前会话状态 |
| 943 | + session.value = null |
| 944 | + closeConnection() |
| 945 | + } else { |
| 946 | + toast.error({ |
| 947 | + title: '生成失败', |
| 948 | + message: error.message || '提示词生成失败,请重试', |
| 949 | + duration: 4000 |
| 950 | + }) |
| 951 | + } |
| 952 | + } |
| 953 | +} |
| 954 | +
|
836 | 955 | const setNodeAndDescendantsInactive = (nodeId: string) => { |
837 | 956 | const node = conversationTree.value.get(nodeId) |
838 | 957 | if (node) { |
@@ -882,7 +1001,7 @@ const handleNodeSelected = (nodeId: string) => { |
882 | 1001 | // 如果不是JSON格式,检查是否是问题文本格式 |
883 | 1002 | // console.log('非JSON格式,检查是否为问题文本') |
884 | 1003 | } |
885 | | - |
| 1004 | +
|
886 | 1005 | // 方法2: 如果是问题文本但不是JSON格式,清除问题状态 |
887 | 1006 | // 这种情况下显示为普通对话 |
888 | 1007 | currentQuestion.value = null |
|
0 commit comments