Skip to content

Commit 7d43648

Browse files
authored
会话联调前端sse
会话联调前端sse
2 parents 842347f + 4ad1912 commit 7d43648

File tree

17 files changed

+1328
-51
lines changed

17 files changed

+1328
-51
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package io.github.timemachinelab.config;
2+
3+
import org.springframework.context.annotation.Bean;
4+
import org.springframework.context.annotation.Configuration;
5+
import org.springframework.web.cors.CorsConfiguration;
6+
import org.springframework.web.cors.CorsConfigurationSource;
7+
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
8+
import org.springframework.web.servlet.config.annotation.CorsRegistry;
9+
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
10+
11+
import java.util.Arrays;
12+
13+
@Configuration
14+
public class CorsConfig implements WebMvcConfigurer {
15+
16+
@Override
17+
public void addCorsMappings(CorsRegistry registry) {
18+
registry.addMapping("/**")
19+
.allowedOriginPatterns("http://localhost:*", "http://127.0.0.1:*")
20+
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
21+
.allowedHeaders("*")
22+
.allowCredentials(true)
23+
.maxAge(3600);
24+
}
25+
26+
@Bean
27+
public CorsConfigurationSource corsConfigurationSource() {
28+
CorsConfiguration configuration = new CorsConfiguration();
29+
30+
// 允许的源
31+
configuration.setAllowedOriginPatterns(Arrays.asList("http://localhost:*", "http://127.0.0.1:*"));
32+
33+
// 允许的HTTP方法
34+
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
35+
36+
// 允许的请求头
37+
configuration.setAllowedHeaders(Arrays.asList("*"));
38+
39+
// 允许携带凭证
40+
configuration.setAllowCredentials(true);
41+
42+
// 预检请求的缓存时间
43+
configuration.setMaxAge(3600L);
44+
45+
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
46+
source.registerCorsConfiguration("/**", configuration);
47+
48+
return source;
49+
}
50+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
package io.github.timemachinelab.core.session;
22

33
public class Session {
4+
5+
6+
47
}
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
package io.github.timemachinelab.core.session.application;
2+
3+
import io.github.timemachinelab.core.session.domain.entity.ConversationSession;
4+
import io.github.timemachinelab.core.session.infrastructure.web.dto.MessageResponse;
5+
import io.github.timemachinelab.core.session.infrastructure.ai.ConversationOperation;
6+
import io.github.timemachinelab.sfchain.core.AIService;
7+
import lombok.RequiredArgsConstructor;
8+
import lombok.extern.slf4j.Slf4j;
9+
import org.springframework.stereotype.Service;
10+
11+
import java.util.concurrent.ConcurrentHashMap;
12+
import java.util.Map;
13+
import java.util.List;
14+
import java.util.ArrayList;
15+
import java.util.function.Consumer;
16+
17+
@Service
18+
@RequiredArgsConstructor
19+
@Slf4j
20+
public class ConversationService {
21+
22+
private final AIService aiService;
23+
24+
private final Map<String, ConversationSession> sessions = new ConcurrentHashMap<>();
25+
26+
public ConversationSession createSession(String userId) {
27+
ConversationSession session = new ConversationSession(userId);
28+
sessions.put(session.getSessionId(), session);
29+
return session;
30+
}
31+
32+
public ConversationSession getSession(String sessionId) {
33+
return sessions.get(sessionId);
34+
}
35+
36+
public void processUserMessage(String sessionId, String userMessage, Consumer<MessageResponse> sseCallback) {
37+
ConversationSession session = sessions.get(sessionId);
38+
if (session == null) {
39+
log.warn("会话不存在: {}", sessionId);
40+
return;
41+
}
42+
43+
// 1. 添加用户消息到会话历史
44+
session.addMessage(userMessage, "user");
45+
46+
// 2. 发送用户消息确认
47+
sseCallback.accept(MessageResponse.userAnswer("user_" + System.currentTimeMillis(), userMessage));
48+
49+
// 3. 调用AI服务获取回复
50+
processAIResponse(session, userMessage, sseCallback);
51+
}
52+
53+
private void processAIResponse(ConversationSession session, String userMessage, Consumer<MessageResponse> sseCallback) {
54+
try {
55+
// 构建对话历史
56+
List<ConversationOperation.ConversationHistory> history = buildConversationHistory(session);
57+
58+
// 创建AI请求
59+
ConversationOperation.ConversationRequest request = new ConversationOperation.ConversationRequest(
60+
session.getSessionId(),
61+
"current",
62+
userMessage
63+
);
64+
request.setConversationHistory(history);
65+
66+
// 调用AI服务
67+
ConversationOperation.ConversationResponse aiResponse = aiService.execute("CONVERSATION_OP", request);
68+
log.info("AI服务调用成功: {}", aiResponse);
69+
70+
// 添加AI回复到会话历史
71+
session.addMessage(aiResponse.getAnswer(), "assistant");
72+
73+
// 根据响应类型处理AI回复
74+
String nodeId = "ai_" + System.currentTimeMillis();
75+
sseCallback.accept(MessageResponse.aiAnswer("ai_" + System.currentTimeMillis(), aiResponse.getAnswer()));
76+
// if (aiResponse.getResponseType() == ConversationOperation.ResponseType.SELECTION) {
77+
// // 选择题类型
78+
// sseCallback.accept(MessageResponse.aiSelectionQuestion(nodeId, aiResponse.getAnswer(), aiResponse.getOptions()));
79+
// } else {
80+
// // 普通文本回复
81+
// sseCallback.accept(MessageResponse.aiQuestion(nodeId, aiResponse.getAnswer()));
82+
// }
83+
84+
} catch (Exception e) {
85+
log.error("AI服务调用失败: {}", e.getMessage(), e);
86+
// 降级处理
87+
String fallbackResponse = "抱歉,我暂时无法处理您的请求,请稍后再试。";
88+
session.addMessage(fallbackResponse, "assistant");
89+
String nodeId = "ai_" + System.currentTimeMillis();
90+
sseCallback.accept(MessageResponse.aiQuestion(nodeId, fallbackResponse));
91+
}
92+
}
93+
94+
private List<ConversationOperation.ConversationHistory> buildConversationHistory(ConversationSession session) {
95+
List<ConversationOperation.ConversationHistory> history = new ArrayList<>();
96+
97+
// 从会话消息构建对话历史
98+
for (ConversationSession.ConversationMessage message : session.getMessages()) {
99+
ConversationOperation.ConversationHistory historyItem = new ConversationOperation.ConversationHistory(
100+
message.getRole(),
101+
message.getContent(),
102+
message.getRole() + "_" + message.getTimestamp().toString()
103+
);
104+
history.add(historyItem);
105+
}
106+
107+
return history;
108+
}
109+
110+
111+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package io.github.timemachinelab.core.session.domain.entity;
2+
3+
import lombok.Getter;
4+
5+
import java.time.LocalDateTime;
6+
import java.util.UUID;
7+
import java.util.List;
8+
import java.util.ArrayList;
9+
10+
@Getter
11+
public class ConversationSession {
12+
13+
private final String sessionId;
14+
private final String userId;
15+
private final LocalDateTime createTime;
16+
private LocalDateTime updateTime;
17+
private final List<ConversationMessage> messages;
18+
19+
public ConversationSession(String userId) {
20+
this.sessionId = UUID.randomUUID().toString();
21+
this.userId = userId;
22+
this.createTime = LocalDateTime.now();
23+
this.updateTime = LocalDateTime.now();
24+
this.messages = new ArrayList<>();
25+
}
26+
27+
public void addMessage(String content, String role) {
28+
ConversationMessage message = new ConversationMessage(content, role);
29+
this.messages.add(message);
30+
this.updateTime = LocalDateTime.now();
31+
}
32+
33+
@Getter
34+
public static class ConversationMessage {
35+
private final String content;
36+
private final String role; // "user" or "assistant"
37+
private final LocalDateTime timestamp;
38+
39+
public ConversationMessage(String content, String role) {
40+
this.content = content;
41+
this.role = role;
42+
this.timestamp = LocalDateTime.now();
43+
}
44+
}
45+
}

0 commit comments

Comments
 (0)