Compare commits

...

2 Commits

View File

@@ -7,7 +7,6 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.srs.common.core.controller.BaseController; import com.srs.common.core.controller.BaseController;
// OkHttp 显式导入 // OkHttp 显式导入
import com.srs.common.core.domain.model.LoginUser;
import com.srs.common.exception.ServiceException; import com.srs.common.exception.ServiceException;
import com.srs.common.utils.SecurityUtils; import com.srs.common.utils.SecurityUtils;
import com.srs.teacher.domain.dto.ConversationDTO; import com.srs.teacher.domain.dto.ConversationDTO;
@@ -18,14 +17,13 @@ import com.srs.common.core.domain.AjaxResult; // ✅ RuoYi 的返回结果类
import okhttp3.RequestBody; import okhttp3.RequestBody;
import okhttp3.ResponseBody; import okhttp3.ResponseBody;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.net.SocketTimeoutException;
import java.time.Duration; import java.time.Duration;
import java.util.*; import java.util.*;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@@ -464,201 +462,46 @@ public class AiChatController extends BaseController {
} }
} }
/* @GetMapping("/history")
public AjaxResult getHistoryMessagesToAdmin(@RequestParam String user,
@RequestParam(required = false) String firstId,
@RequestParam(defaultValue = "20") int limit) {
//调用查询会话
String conversation_id = conversations(user);
}*/
/**
* 获取会话历史消息的端点
* <p>
* 该方法接收客户端发送的请求,获取指定会话的历史消息记录。
* </p>
* <p>
* //@param conversation_id 会话ID
*
* @param firstId 当前页第一条聊天记录的ID默认null
* @param limit 一次请求返回多少条记录默认20条
* @return AjaxResult 返回会话历史消息的结果
*/
@GetMapping("/history")
public AjaxResult getHistoryMessages(
//@RequestParam(required = false) String conversation_id,
@RequestParam(required = false) String firstId,
@RequestParam(defaultValue = "20") int limit) {
try {
/* // 获取当前用户
String currentUsername = SecurityUtils.getLoginUser().getUsername();
// 获取会话列表的id
String conversation_id = conversations(currentUsername);
if(conversation_id == null){
return error("没有会话");
}*/
// 验证conversationId是否为空
/*if (conversation_id == null || conversation_id.trim().isEmpty()) {
return error("会话ID不能为空后端");
}*/
String conversation_id = "8fb04ac4-ac9f-470b-9ac4-fee1ebec6412";
String currentUsername = SecurityUtils.getLoginUser().getUsername();
System.out.println(currentUsername);
System.out.println(conversation_id);
// 构建请求参数
HttpUrl.Builder urlBuilder = HttpUrl.parse(DIFY_API_HISTORY_URL).newBuilder();
urlBuilder.addQueryParameter("conversation_id", conversation_id);
urlBuilder.addQueryParameter("user", currentUsername);
if (firstId != null) {
urlBuilder.addQueryParameter("first_id", firstId);
}
urlBuilder.addQueryParameter("limit", String.valueOf(limit));
System.out.println(currentUsername);
// 构建HTTP请求
Request request = new Request.Builder()
.url(urlBuilder.build())
.addHeader("Authorization", "Bearer " + DIFY_API_KEY)
.get()
.build();
// 执行HTTP请求
try (Response response = client.newCall(request).execute()) {
// 检查响应是否成功
if (!response.isSuccessful()) {
return error("Dify 请求失败: " + response.code() + " " + response.message());
}
// 解析JSON响应
JsonNode rootNode = mapper.readTree(response.body().string());
boolean hasMore = rootNode.path("has_more").asBoolean(false);
List<Map<String, Object>> data = mapper.convertValue(rootNode.path("data"), List.class);
// 构建返回结果
Map<String, Object> result = new HashMap<>();
result.put("limit", limit);
result.put("has_more", hasMore);
result.put("data", data);
return success(result);
}
} catch (IOException e) {
return error("获取会话历史消息失败: " + e.getMessage());
}
}
/**
* 获取会话列表
* <p>
* 该方法用于获取当前用户的会话列表,默认返回最近的 20 条。
* </p>
*
* @param user 用户标识符,由开发者定义规则,需保证用户标识在应用内唯一
* @param lastId 当前页最后一条记录的 ID默认 null
* @param limit 一次请求返回多少条记录,默认 20 条,最大 100 条,最小 1 条
* @param sortBy 排序字段,默认 -updated_at (按更新时间倒序排列)
* @return AjaxResult 返回会话列表的结果
*/
/*@GetMapping("/getConversationsToUser")
public AjaxResult getConversationsToUser(
@RequestParam String user,
@RequestParam(required = false) String lastId,
@RequestParam(defaultValue = "20") int limit,
@RequestParam(defaultValue = "-updated_at") String sortBy) {
try {
// 获取当前用户
String currentUsername = SecurityUtils.getLoginUser().getUsername();
// 获取会话列表的id
String conversation_id = conversations(currentUsername);
return AjaxResult.success(conversation_id);*/
/*// 参数校验
if (user == null || user.trim().isEmpty()) {
return error("用户标识不能为空");
}
// 限制limit的范围在1-100之间
if (limit < 1 || limit > 100) {
return error("limit参数必须在1到100之间");
}
// 构建请求参数
HttpUrl.Builder urlBuilder = HttpUrl.parse(DIFY_CONVERSATIONS_URL).newBuilder();
urlBuilder.addQueryParameter("user", user);
if (lastId != null) {
urlBuilder.addQueryParameter("last_id", lastId);
}
urlBuilder.addQueryParameter("limit", String.valueOf(limit));
urlBuilder.addQueryParameter("sort_by", sortBy);
// 构建HTTP请求
Request request = new Request.Builder()
.url(urlBuilder.build())
.addHeader("Authorization", "Bearer " + DIFY_API_KEY)
.get()
.build();
// 执行HTTP请求
try (Response response = client.newCall(request).execute()) {
// 检查响应是否成功
if (!response.isSuccessful()) {
return error("Dify 请求失败: " + response.code() + " " + response.message());
}
// 解析JSON响应
JsonNode rootNode = mapper.readTree(response.body().string());
int resLimit = rootNode.path("limit").asInt();
boolean hasMore = rootNode.path("has_more").asBoolean(false);
List<Map<String, Object>> data = new ArrayList<>();
// 解析会话列表数据
JsonNode dataArray = rootNode.path("data");
if (dataArray.isArray()) {
for (JsonNode conversationNode : dataArray) {
Map<String, Object> conversation = new HashMap<>();
conversation.put("id", conversationNode.path("id").asText());
conversation.put("name", conversationNode.path("name").asText());
conversation.put("inputs", mapper.convertValue(conversationNode.path("inputs"), Map.class));
conversation.put("status", conversationNode.path("status").asText());
conversation.put("introduction", conversationNode.path("introduction").asText());
conversation.put("created_at", conversationNode.path("created_at").asLong());
conversation.put("updated_at", conversationNode.path("updated_at").asLong());
data.add(conversation);
}
}
// 构建返回结果
Map<String, Object> result = new HashMap<>();
result.put("limit", resLimit);
result.put("has_more", hasMore);
result.put("data", data);
return success(result);
}*/
/* } catch (IOException e) {
return error("获取会话列表失败: " + e.getMessage());
}
}*/
// 权限标识为辅导员 // 权限标识为辅导员
@GetMapping("/getMessagesToAdmin") @GetMapping("/getMessagesToAdmin")
public AjaxResult getMessagesToAdmin(@RequestParam String user, public AjaxResult getMessagesToAdmin(@RequestParam String user,
@RequestParam(required = false) String lastId, @RequestParam(required = false) String lastId,
@RequestParam(defaultValue = "20") int limit, @RequestParam(defaultValue = "20") int limit,
@RequestParam(defaultValue = "-updated_at") String sortBy) { @RequestParam(defaultValue = "-updated_at") String sortBy) {
System.out.println("进入getMessagesToAdmin方法");
System.out.println("参数 user: " + user);
System.out.println("参数 lastId: " + lastId);
System.out.println("参数 limit: " + limit);
System.out.println("参数 sortBy: " + sortBy);
try { try {
System.out.println("开始调用getConversations方法");
List<ConversationDTO> conversations = getConversations(user); List<ConversationDTO> conversations = getConversations(user);
System.out.println("getConversations方法调用完成结果: " + (conversations != null ? conversations.size() : "null"));
if (conversations == null || conversations.isEmpty()) { if (conversations == null || conversations.isEmpty()) {
System.out.println("会话列表为空");
return AjaxResult.error("暂无会话记录"); return AjaxResult.error("暂无会话记录");
} }
String conversation_id = conversations.get(0).getId(); String conversation_id = conversations.get(0).getId();
System.out.println(conversation_id); System.out.println("获取到的会话ID: " + conversation_id);
return success(getConversationHistoryMessages(conversation_id, user, null, 20));
System.out.println("开始调用getConversationHistoryMessages方法");
Map<String, Object> result = getConversationHistoryMessages(conversation_id, user, null, 20);
System.out.println("getConversationHistoryMessages方法调用完成");
AjaxResult successResult = success(result);
System.out.println("返回成功结果");
return successResult;
} catch (IOException e) { } catch (IOException e) {
return AjaxResult.error("网络请求失败,请稍后重试",error()); System.out.println("捕获到IOException: " + e.getMessage());
e.printStackTrace();
return AjaxResult.error("网络请求失败,请稍后重试");
} catch (Exception e) {
System.out.println("捕获到其他异常: " + e.getMessage());
e.printStackTrace();
return AjaxResult.error("请求处理失败: " + e.getMessage());
} }
} }
@@ -667,16 +510,43 @@ public class AiChatController extends BaseController {
public AjaxResult getMessagesToUser(@RequestParam(required = false) String lastId, public AjaxResult getMessagesToUser(@RequestParam(required = false) String lastId,
@RequestParam(defaultValue = "20") int limit, @RequestParam(defaultValue = "20") int limit,
@RequestParam(defaultValue = "-updated_at") String sortBy) { @RequestParam(defaultValue = "-updated_at") String sortBy) {
System.out.println("进入getMessagesToUser方法");
System.out.println("参数 lastId: " + lastId);
System.out.println("参数 limit: " + limit);
System.out.println("参数 sortBy: " + sortBy);
try { try {
System.out.println("开始获取当前登录用户");
String user = SecurityUtils.getLoginUser().getUsername(); String user = SecurityUtils.getLoginUser().getUsername();
System.out.println("当前登录用户: " + user);
System.out.println("开始调用getConversations方法");
List<ConversationDTO> conversations = getConversations(user); List<ConversationDTO> conversations = getConversations(user);
System.out.println("getConversations方法调用完成结果: " + (conversations != null ? conversations.size() : "null"));
if (conversations == null || conversations.isEmpty()) { if (conversations == null || conversations.isEmpty()) {
System.out.println("会话列表为空");
return AjaxResult.error("暂无会话记录"); return AjaxResult.error("暂无会话记录");
} }
String conversation_id = conversations.get(0).getId(); String conversation_id = conversations.get(0).getId();
return success(getConversationHistoryMessages(conversation_id, user, null, 20)); System.out.println("获取到的会话ID: " + conversation_id);
System.out.println("开始调用getConversationHistoryMessages方法");
Map<String, Object> result = getConversationHistoryMessages(conversation_id, user, null, 20);
System.out.println("getConversationHistoryMessages方法调用完成");
AjaxResult successResult = success(result);
System.out.println("返回成功结果");
return successResult;
} catch (IOException e) { } catch (IOException e) {
System.out.println("捕获到IOException: " + e.getMessage());
e.printStackTrace();
return AjaxResult.error("网络请求失败,请稍后重试"); return AjaxResult.error("网络请求失败,请稍后重试");
} catch (Exception e) {
System.out.println("捕获到其他异常: " + e.getMessage());
e.printStackTrace();
return AjaxResult.error("请求处理失败: " + e.getMessage());
} }
} }
@@ -701,14 +571,19 @@ public class AiChatController extends BaseController {
.get() .get()
.build(); .build();
System.out.println("准备发送HTTP请求到: " + urlBuilder.build().toString());
// 执行请求 // 执行请求
try (Response response = client.newCall(request).execute()) { try (Response response = client.newCall(request).execute()) {
System.out.println("收到HTTP响应状态码: " + response.code());
if (!response.isSuccessful()) { if (!response.isSuccessful()) {
System.out.println("HTTP请求失败: " + response.code() + " " + response.message());
throw new IOException("Dify API 请求失败: " + response.code() + " " + response.message()); throw new IOException("Dify API 请求失败: " + response.code() + " " + response.message());
} }
// 读取响应体 // 读取响应体
String responseBodyString = response.body().string(); String responseBodyString = response.body().string();
System.out.println("响应体内容: " + responseBodyString);
JsonNode rootNode = mapper.readTree(responseBodyString); JsonNode rootNode = mapper.readTree(responseBodyString);
// 提取 data 数组 // 提取 data 数组
@@ -716,6 +591,7 @@ public class AiChatController extends BaseController {
List<ConversationDTO> conversations = new ArrayList<>(); List<ConversationDTO> conversations = new ArrayList<>();
if (dataArray.isArray()) { if (dataArray.isArray()) {
System.out.println("解析到 " + dataArray.size() + " 个会话");
for (JsonNode node : dataArray) { for (JsonNode node : dataArray) {
ConversationDTO dto = new ConversationDTO(); ConversationDTO dto = new ConversationDTO();
dto.setId(node.path("id").asText(null)); dto.setId(node.path("id").asText(null));
@@ -733,12 +609,14 @@ public class AiChatController extends BaseController {
} }
} }
System.out.println("getConversations方法执行完成返回 " + conversations.size() + " 个会话");
return conversations; return conversations;
} }
} }
public List<ConversationDTO> getConversations(String user) throws IOException { public List<ConversationDTO> getConversations(String user) throws IOException {
return getConversations(user, null, 0, null); return getConversations(user, null, 1, "-updated_at");
} }
public List<ConversationDTO> getConversations(String user, String lastId) throws IOException { public List<ConversationDTO> getConversations(String user, String lastId) throws IOException {
@@ -757,11 +635,19 @@ public class AiChatController extends BaseController {
String firstId, String firstId,
Integer limit) throws ServiceException { Integer limit) throws ServiceException {
System.out.println("进入getConversationHistoryMessages方法");
System.out.println("参数 conversationId: " + conversationId);
System.out.println("参数 user: " + user);
System.out.println("参数 firstId: " + firstId);
System.out.println("参数 limit: " + limit);
// 参数校验 // 参数校验
if (conversationId == null || conversationId.trim().isEmpty()) { if (conversationId == null || conversationId.trim().isEmpty()) {
System.out.println("conversationId 参数为空");
throw new IllegalArgumentException("conversationId 不能为空"); throw new IllegalArgumentException("conversationId 不能为空");
} }
if (user == null || user.trim().isEmpty()) { if (user == null || user.trim().isEmpty()) {
System.out.println("user 参数为空");
throw new IllegalArgumentException("user 不能为空"); throw new IllegalArgumentException("user 不能为空");
} }
@@ -785,24 +671,31 @@ public class AiChatController extends BaseController {
.get() .get()
.build(); .build();
System.out.println("准备发送HTTP请求到: " + urlBuilder.build().toString());
try (Response response = client.newCall(request).execute()) { try (Response response = client.newCall(request).execute()) {
System.out.println("收到HTTP响应状态码: " + response.code());
if (!response.isSuccessful()) { if (!response.isSuccessful()) {
String body = response.body() != null ? response.body().string() : "No body"; String body = response.body() != null ? response.body().string() : "No body";
System.out.println("HTTP请求失败响应体: " + body);
String msg = String.format("HTTP %d %s - %s", response.code(), response.message(), body); String msg = String.format("HTTP %d %s - %s", response.code(), response.message(), body);
throw new ServiceException("请求失败"); throw new ServiceException("请求失败");
} }
ResponseBody responseBody = response.body(); ResponseBody responseBody = response.body();
if (responseBody == null) { if (responseBody == null) {
System.out.println("响应体为空");
return emptyResult(finalLimit); return emptyResult(finalLimit);
} }
String responseBodyString = responseBody.string(); String responseBodyString = responseBody.string();
System.out.println("响应体内容: " + responseBodyString);
JsonNode rootNode; JsonNode rootNode;
try { try {
rootNode = mapper.readTree(responseBodyString); rootNode = mapper.readTree(responseBodyString);
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
System.out.println("响应数据格式错误: " + e.getMessage());
throw new ServiceException("响应数据格式错误"); throw new ServiceException("响应数据格式错误");
} }
@@ -810,12 +703,14 @@ public class AiChatController extends BaseController {
List<Map<String, Object>> data = new ArrayList<>(); List<Map<String, Object>> data = new ArrayList<>();
JsonNode dataArray = rootNode.get("data"); JsonNode dataArray = rootNode.get("data");
if (dataArray != null && dataArray.isArray()) { if (dataArray != null && dataArray.isArray()) {
System.out.println("解析到 " + dataArray.size() + " 条消息");
data = mapper.convertValue(dataArray, new TypeReference<List<Map<String, Object>>>() { data = mapper.convertValue(dataArray, new TypeReference<List<Map<String, Object>>>() {
}); });
} }
// 提取 has_more // 提取 has_more
boolean hasMore = rootNode.path("has_more").asBoolean(false); boolean hasMore = rootNode.path("has_more").asBoolean(false);
System.out.println("has_more: " + hasMore);
// ✅ 直接构建前端需要的返回结构 // ✅ 直接构建前端需要的返回结构
Map<String, Object> result = new HashMap<>(); Map<String, Object> result = new HashMap<>();
@@ -823,9 +718,12 @@ public class AiChatController extends BaseController {
result.put("has_more", hasMore); result.put("has_more", hasMore);
result.put("limit", finalLimit); result.put("limit", finalLimit);
System.out.println("getConversationHistoryMessages方法执行完成");
return result; // 直接返回,调用方直接丢给前端 return result; // 直接返回,调用方直接丢给前端
} catch (IOException e) { } catch (IOException e) {
System.out.println("网络请求失败: " + e.getMessage());
throw new ServiceException("网络请求失败: " + e.getMessage()); throw new ServiceException("网络请求失败: " + e.getMessage());
} }
} }
@@ -844,8 +742,7 @@ public class AiChatController extends BaseController {
/* /**
*//**
* 文件上传接口 * 文件上传接口
* <p> * <p>
* 上传文件并在发送消息时使用,可实现图文多模态理解。支持应用程序所支持的所有格式。 * 上传文件并在发送消息时使用,可实现图文多模态理解。支持应用程序所支持的所有格式。
@@ -855,7 +752,7 @@ public class AiChatController extends BaseController {
* @param file 要上传的文件 * @param file 要上传的文件
* @param user 用户标识,用于定义终端用户的身份 * @param user 用户标识,用于定义终端用户的身份
* @return 包含文件信息的统一响应结果 * @return 包含文件信息的统一响应结果
*//* */
@PostMapping("/files/upload") @PostMapping("/files/upload")
public AjaxResult uploadFile(@RequestParam("file") MultipartFile file, public AjaxResult uploadFile(@RequestParam("file") MultipartFile file,
@RequestParam("user") String user) { @RequestParam("user") String user) {
@@ -903,5 +800,5 @@ public class AiChatController extends BaseController {
} catch (Exception e) { } catch (Exception e) {
return AjaxResult.error("文件上传异常: " + e.getMessage()); return AjaxResult.error("文件上传异常: " + e.getMessage());
} }
}*/ }
} }