diff --git a/src/addon/aikefu/api/controller/Kefu.php b/src/addon/aikefu/api/controller/Kefu.php index 0fc1aea56..b315d3731 100644 --- a/src/addon/aikefu/api/controller/Kefu.php +++ b/src/addon/aikefu/api/controller/Kefu.php @@ -803,27 +803,76 @@ class Kefu extends BaseApi $kefu_message_model = new KefuMessageModel(); $kefu_conversation_model = new KefuConversationModel(); - // 发送请求 - $response = $this->curlRequest($url, 'POST', $requestData, $headers); + // 开启事务,确保数据一致性 + Db::startTrans(); + + try { + // 发送请求 + $response = $this->curlRequest($url, 'POST', $requestData, $headers); - // 解析响应 - $result = json_decode($response, true); + // 解析响应 + $result = json_decode($response, true); - if (json_last_error() !== JSON_ERROR_NONE) { - return $this->response($this->error('解析响应失败')); + if (json_last_error() !== JSON_ERROR_NONE) { + throw new \Exception('解析响应失败'); + } + + // 验证响应数据 + if (empty($result) || !isset($result['conversation_id'])) { + throw new \Exception('API返回数据格式错误或缺少必要字段'); + } + + $final_conversation_id = $result['conversation_id'] ?? $conversation_id; + $final_message_id = $result['message_id'] ?? $result['id'] ?? ''; + + // 检查用户消息是否已存在,避免重复存储 + $existing_user_message = $kefu_message_model->getMessageInfo([ + ['site_id', '=', $this->site_id], + ['user_id', '=', $user_id], + ['conversation_id', '=', $final_conversation_id], + ['role', '=', 'user'], + ['content', '=', $message ?? ''] + ]); + + if (empty($existing_user_message['data'])) { + // 保存用户消息 + $this->saveUserMessage($kefu_message_model, $this->site_id, $user_id, $final_conversation_id, $final_message_id, $message ?? ''); + $this->log('非流式用户消息已保存,会话ID:' . $final_conversation_id, 'info'); + } + + // 检查助手消息是否已存在 + $existing_assistant_message = $kefu_message_model->getMessageInfo([ + ['site_id', '=', $this->site_id], + ['user_id', '=', $user_id], + ['conversation_id', '=', $final_conversation_id], + ['role', '=', 'assistant'], + ['message_id', '=', $final_message_id] + ]); + + if (empty($existing_assistant_message['data'])) { + // 保存机器人回复 + $this->saveAssistantMessage($kefu_message_model, $this->site_id, $user_id, $final_conversation_id, $final_message_id, $result['answer'] ?? ''); + $this->log('非流式助手消息已保存,会话ID:' . $final_conversation_id, 'info'); + } + + // 更新会话状态或创建新会话 + $this->updateOrCreateConversation($kefu_conversation_model, $this->site_id, $user_id, $final_conversation_id); + + // 提交事务 + Db::commit(); + $this->log('非流式对话数据已完整保存,会话ID:' . $final_conversation_id, 'info'); + + // 返回成功响应,保持与Dify API一致的响应结构 + return $this->response($this->success($result)); + + } catch (\Exception $e) { + // 回滚事务 + Db::rollback(); + $error_msg = '非流式对话存储失败:' . $e->getMessage() . ',错误行:' . $e->getLine() . ',错误文件:' . $e->getFile(); + $this->log($error_msg, 'error'); + + return $this->response($this->error($error_msg)); } - - // 保存用户消息 - $this->saveUserMessage($kefu_message_model, $this->site_id, $user_id, $result['conversation_id'] ?? $conversation_id, $result['message_id'] ?? '', $message ?? ''); - - // 保存机器人回复 - $this->saveAssistantMessage($kefu_message_model, $this->site_id, $user_id, $result['conversation_id'] ?? $conversation_id, $result['id'] ?? '', $result['answer'] ?? ''); - - // 更新会话状态或创建新会话 - $this->updateOrCreateConversation($kefu_conversation_model, $this->site_id, $user_id, $result['conversation_id'] ?? $conversation_id); - - // 返回成功响应,保持与Dify API一致的响应结构 - return $this->response($this->success($result)); } /** diff --git a/src/addon/aikefu/shop/controller/Kefu.php b/src/addon/aikefu/shop/controller/Kefu.php index 32035ff12..81f6c2534 100644 --- a/src/addon/aikefu/shop/controller/Kefu.php +++ b/src/addon/aikefu/shop/controller/Kefu.php @@ -273,6 +273,7 @@ class Kefu extends BaseShop $user_id = input("user_id/s", ""); $sort_field = input("sort_field/s", "create_time"); // 排序字段 $sort_order = input("sort_order/s", "desc"); // 排序方式:asc或desc + $status = input("status/s", "completed"); // 默认只显示已完成的消息 $kefu_message_model = new KefuMessageModel(); $condition = [ @@ -289,9 +290,15 @@ class Kefu extends BaseShop $condition[] = ['user_id', '=', $user_id]; } + // 添加状态过滤(默认只显示已完成的消息,避免显示临时数据) + if (!empty($status)) { + $condition[] = ['status', '=', $status]; + } + // 构建排序字符串 $order = $sort_field . ' ' . $sort_order; $message_list = $kefu_message_model->getMessageList($condition, '*', $order, $page, $limit); + // 适配layui table的返回格式,同时保持与Dify API风格一致 $result = [ 'code' => 0, // layui table要求成功状态码为0 @@ -301,7 +308,8 @@ class Kefu extends BaseShop 'messages' => $message_list['data'], // 消息列表 'page_info' => [ 'limit' => $limit, - 'offset' => ($page - 1) * $limit + 'offset' => ($page - 1) * $limit, + 'total' => $message_list['total'] // 添加总记录数到page_info ] ] // 数据列表 ]; diff --git a/src/addon/aikefu/shop/view/kefu/message.html b/src/addon/aikefu/shop/view/kefu/message.html index 44cc04685..d12bda9a8 100644 --- a/src/addon/aikefu/shop/view/kefu/message.html +++ b/src/addon/aikefu/shop/view/kefu/message.html @@ -220,6 +220,17 @@ +