263 lines
9.1 KiB
PHP
263 lines
9.1 KiB
PHP
<?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
|
||
{
|
||
/**
|
||
* 为事件调用初始化属性
|
||
* @param array $data 事件数据
|
||
*/
|
||
public function initializeForEvent($data)
|
||
{
|
||
if (!empty($data['site_id'])) {
|
||
$this->site_id = $data['site_id'] ?? 0;
|
||
}
|
||
|
||
if (!empty($data['member_id'])) {
|
||
$this->member_id = $data['member_id'] ?? 0;
|
||
}
|
||
|
||
if (!empty($data['token'])) {
|
||
$this->token = $data['token'] ?? '';
|
||
}
|
||
|
||
$this->params = [
|
||
'message' => $data['message'] ?? '',
|
||
'user_id' => $data['user_id'] ?? '',
|
||
'conversation_id' => $data['conversation_id'] ?? '',
|
||
'stream' => $data['stream'] ?? false,
|
||
];
|
||
}
|
||
|
||
/**
|
||
* 智能客服聊天接口
|
||
* @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, $this->app_module)['data']['value'] ?? [];
|
||
|
||
if (empty($config_info) || $config_info['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, $this->app_module)['data']['value'] ?? [];
|
||
|
||
if (empty($config_info) || $config_info['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()));
|
||
}
|
||
}
|
||
}
|