Skip to content

Commit 2d68315

Browse files
authored
Merge pull request #42 from Geniusay/master
生成提示词功能
2 parents 2f6f400 + e65a44e commit 2d68315

File tree

5 files changed

+643
-13
lines changed

5 files changed

+643
-13
lines changed

prompto-lab-app/src/main/java/io/github/timemachinelab/controller/UserInteractionController.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
package io.github.timemachinelab.controller;
22

3+
import com.alibaba.fastjson2.JSON;
34
import io.github.timemachinelab.core.session.application.MessageProcessingService;
45
import io.github.timemachinelab.core.session.application.SessionManagementService;
56
import io.github.timemachinelab.core.session.application.SseNotificationService;
67
import io.github.timemachinelab.core.session.domain.entity.ConversationSession;
8+
import io.github.timemachinelab.core.session.infrastructure.ai.GenPromptOperation;
9+
import io.github.timemachinelab.core.session.infrastructure.web.dto.GenPromptRequest;
710
import io.github.timemachinelab.core.session.infrastructure.web.dto.UnifiedAnswerRequest;
811
import io.github.timemachinelab.entity.req.RetryRequest;
912
import io.github.timemachinelab.entity.resp.ApiResult;
@@ -288,9 +291,12 @@ public ResponseEntity<String> processAnswer(@Validated @RequestBody UnifiedAnswe
288291
}
289292
}
290293

291-
@GetMapping("/gen-prompt")
292-
public void genPrompt(@RequestParam String sessionId) {
293-
294+
@PostMapping("/gen-prompt")
295+
public ResponseEntity<String> genPrompt(@RequestBody GenPromptRequest request) {
296+
GenPromptOperation.GpResponse gpResponse = new GenPromptOperation.GpResponse();
297+
gpResponse.setGenPrompt("This is a test response for gen-prompt endpoint.");
298+
sseNotificationService.sendWelcomeMessage(request.getSessionId(), JSON.toJSONString(gpResponse));
299+
return ResponseEntity.ok("生成提示词");
294300
}
295301

296302

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package io.github.timemachinelab.core.session.infrastructure.web.dto;
2+
3+
4+
import lombok.AllArgsConstructor;
5+
import lombok.Data;
6+
import lombok.NoArgsConstructor;
7+
import lombok.NonNull;
8+
9+
import javax.validation.constraints.NotBlank;
10+
11+
@Data
12+
@NoArgsConstructor
13+
@AllArgsConstructor
14+
public class GenPromptRequest {
15+
16+
17+
/**
18+
* 会话ID
19+
*/
20+
@NotBlank(message = "会话ID不能为空")
21+
private String sessionId;
22+
23+
24+
/**
25+
* 原始答案数据
26+
* - 单选/多选:List<String>
27+
* - 输入框:String
28+
* - 表单:List<FormAnswerItem>
29+
*/
30+
private Object answer;
31+
}

prompto-lab-ui/src/components/Chat/AIChatPage.vue

Lines changed: 126 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@
3636

3737
<!-- 中间问答主页面 -->
3838
<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" />
4141
</div>
4242

4343
<!-- 可拖拽的分隔条 -->
@@ -65,6 +65,7 @@ import { ref, computed, onMounted, onUnmounted } from 'vue'
6565
import QuestionRenderer from './QuestionRenderer.vue'
6666
import MindMapTree from './MindMapTree.vue'
6767
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'
6869
import { toast } from '@/utils/toast'
6970
7071
interface Message {
@@ -121,6 +122,9 @@ const isLoading = ref(false)
121122
// 问题状态管理
122123
const currentQuestion = ref<any>(null)
123124
125+
// 子组件引用
126+
const questionRendererRef = ref<any>(null)
127+
124128
// 确保SSE连接唯一性
125129
const ensureUniqueConnection = () => {
126130
if (eventSource.value) {
@@ -227,6 +231,26 @@ const handleSSEMessage = (response: any) => {
227231
updateActivity()
228232
229233
// 处理连接建立消息
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 => {
230254
if (response.type === 'connected' || response.sessionId) {
231255
// 这是连接建立时的会话信息
232256
if (response.sessionId) {
@@ -274,11 +298,47 @@ const handleSSEMessage = (response: any) => {
274298
duration: 2000
275299
})
276300
}
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
278336
}
337+
return false
338+
}
279339
280-
// 处理其他类型的消息
281-
// 检查是否是新的问题格式(包含question对象)
340+
// 处理新问题格式消息
341+
const handleQuestionMessage = (response: any): boolean => {
282342
if (response.question && response.question.type) {
283343
// 这是新的问题格式
284344
currentQuestion.value = response.question
@@ -328,9 +388,13 @@ const handleSSEMessage = (response: any) => {
328388
329389
isLoading.value = false
330390
// console.log('收到新格式问题:', response.question, '当前节点ID:', response.currentNodeId, '父节点ID:', response.parentNodeId)
331-
return
391+
return true
332392
}
393+
return false
394+
}
333395
396+
// 处理其他类型的消息
397+
const handleOtherMessages = (response: any) => {
334398
const messageResponse = response as MessageResponse
335399
switch (messageResponse.type) {
336400
case 'AI_QUESTION':
@@ -833,6 +897,61 @@ const handleSubmitAnswer = async (answerData: any) => {
833897
}
834898
}
835899
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+
836955
const setNodeAndDescendantsInactive = (nodeId: string) => {
837956
const node = conversationTree.value.get(nodeId)
838957
if (node) {
@@ -882,7 +1001,7 @@ const handleNodeSelected = (nodeId: string) => {
8821001
// 如果不是JSON格式,检查是否是问题文本格式
8831002
// console.log('非JSON格式,检查是否为问题文本')
8841003
}
885-
1004+
8861005
// 方法2: 如果是问题文本但不是JSON格式,清除问题状态
8871006
// 这种情况下显示为普通对话
8881007
currentQuestion.value = null

0 commit comments

Comments
 (0)