feat(addon/aikefu): 新增AI智能客服插件

This commit is contained in:
2025-12-06 10:09:08 +08:00
parent 8da4563435
commit 8ceb252d79
17 changed files with 2043 additions and 0 deletions

View File

@@ -0,0 +1,236 @@
<?php
namespace addon\aikefu\api\controller;
use addon\aikefu\model\Config as KefuConfigModel;
use addon\aikefu\model\Conversation as KefuConversationModel;
use addon\aikefu\model\Message as KefuMessageModel;
use app\api\controller\BaseApi;
use extend\api\HttpClient;
class Kefu extends BaseApi
{
/**
* 智能客服聊天接口
* @return \think\response\Json
*/
public function chat()
{
// 获取请求参数
$message = $this->params['message'] ?? '';
$user_id = $this->params['user_id'] ?? $this->member_id;
$conversation_id = $this->params['conversation_id'] ?? '';
$stream = $this->params['stream'] ?? false;
// 验证参数
if (empty($message)) {
return $this->response($this->error('请输入消息内容'));
}
try {
// 获取智能客服配置
$kefu_config_model = new KefuConfigModel();
$config_info = $kefu_config_model->getConfig($this->site_id);
if (empty($config_info['data']['value']) || $config_info['data']['value']['status'] != 1) {
return $this->response($this->error('智能客服暂未启用'));
}
$config = $config_info['data']['value'];
$apiKey = $config['api_key'];
$baseUrl = $config['base_url'];
$chatEndpoint = $config['chat_endpoint'];
// 构建请求数据
$requestData = [
'inputs' => [],
'query' => $message,
'response_mode' => $stream ? 'streaming' : 'blocking',
'user' => $user_id,
];
// 如果有会话ID添加到请求中
if (!empty($conversation_id)) {
$requestData['conversation_id'] = $conversation_id;
}
// 构建请求头
$headers = [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
];
// 发送请求到Dify API
$url = $baseUrl . $chatEndpoint;
$response = HttpClient::http($url, 'POST', json_encode($requestData), $headers);
// 解析响应
$result = json_decode($response, true);
if (json_last_error() !== JSON_ERROR_NONE) {
return $this->response($this->error('解析响应失败'));
}
// 保存消息记录
$kefu_message_model = new KefuMessageModel();
$kefu_conversation_model = new KefuConversationModel();
// 保存用户消息
$kefu_message_model->addMessage([
'site_id' => $this->site_id,
'user_id' => $user_id,
'conversation_id' => $result['conversation_id'] ?? $conversation_id,
'message_id' => $result['message_id'] ?? '',
'role' => 'user',
'content' => $message,
]);
// 保存机器人回复
$kefu_message_model->addMessage([
'site_id' => $this->site_id,
'user_id' => $user_id,
'conversation_id' => $result['conversation_id'] ?? $conversation_id,
'message_id' => $result['id'] ?? '',
'role' => 'assistant',
'content' => $result['answer'] ?? '',
]);
// 更新会话状态或创建新会话
$conversation_info = $kefu_conversation_model->getConversationInfo([
['site_id', '=', $this->site_id],
['conversation_id', '=', $result['conversation_id'] ?? $conversation_id],
]);
if (empty($conversation_info['data'])) {
// 创建新会话
$kefu_conversation_model->addConversation([
'site_id' => $this->site_id,
'user_id' => $user_id,
'conversation_id' => $result['conversation_id'] ?? '',
'name' => '智能客服会话',
]);
} else {
// 更新会话状态
$kefu_conversation_model->updateConversation([
'status' => 1,
], [
['id', '=', $conversation_info['data']['id']],
]);
}
// 返回成功响应
return $this->response($this->success([
'conversation_id' => $result['conversation_id'] ?? '',
'reply' => $result['answer'] ?? '',
'message_id' => $result['message_id'] ?? '',
'finish_reason' => $result['finish_reason'] ?? '',
'usage' => $result['usage'] ?? [],
]));
} catch (\Exception $e) {
return $this->response($this->error('请求失败:' . $e->getMessage()));
}
}
/**
* 获取会话历史
* @return \think\response\Json
*/
public function getHistory()
{
// 获取请求参数
$conversation_id = $this->params['conversation_id'] ?? '';
$user_id = $this->params['user_id'] ?? $this->member_id;
$limit = $this->params['limit'] ?? 20;
$offset = $this->params['offset'] ?? 0;
// 验证参数
if (empty($conversation_id)) {
return $this->response($this->error('会话ID不能为空'));
}
try {
// 获取会话历史记录
$kefu_message_model = new KefuMessageModel();
$message_list = $kefu_message_model->getMessageList([
['site_id', '=', $this->site_id],
['user_id', '=', $user_id],
['conversation_id', '=', $conversation_id],
], 'id, role, content, create_time', 'create_time asc', $limit, $offset);
// 返回成功响应
return $this->response($this->success([
'messages' => $message_list['data'] ?? [],
'total' => $message_list['total'] ?? 0,
'limit' => $limit,
'offset' => $offset,
]));
} catch (\Exception $e) {
return $this->response($this->error('请求失败:' . $e->getMessage()));
}
}
/**
* 创建新会话
* @return \think\response\Json
*/
public function createConversation()
{
// 获取请求参数
$user_id = $this->params['user_id'] ?? $this->member_id;
try {
// 获取智能客服配置
$kefu_config_model = new KefuConfigModel();
$config_info = $kefu_config_model->getConfig($this->site_id);
if (empty($config_info['data']['value']) || $config_info['data']['value']['status'] != 1) {
return $this->response($this->error('智能客服暂未启用'));
}
$config = $config_info['data']['value'];
$apiKey = $config['api_key'];
$baseUrl = $config['base_url'];
// 构建请求数据
$requestData = [
'name' => '智能客服会话',
'user' => $user_id,
];
// 构建请求头
$headers = [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
];
// 发送请求到Dify API
$url = $baseUrl . '/conversations';
$response = HttpClient::http($url, 'POST', json_encode($requestData), $headers);
// 解析响应
$result = json_decode($response, true);
if (json_last_error() !== JSON_ERROR_NONE) {
return $this->response($this->error('解析响应失败'));
}
// 保存会话记录
$kefu_conversation_model = new KefuConversationModel();
$kefu_conversation_model->addConversation([
'site_id' => $this->site_id,
'user_id' => $user_id,
'conversation_id' => $result['id'] ?? '',
'name' => $result['name'] ?? '智能客服会话',
]);
// 返回成功响应
return $this->response($this->success([
'conversation_id' => $result['id'] ?? '',
'name' => $result['name'] ?? '',
'created_at' => $result['created_at'] ?? '',
]));
} catch (\Exception $e) {
return $this->response($this->error('请求失败:' . $e->getMessage()));
}
}
}