作者 李宇航

合并分支 'lyh-server' 到 'master'

Lyh server



查看合并请求 !1690
@@ -31,42 +31,53 @@ class ChatLogic extends BaseLogic @@ -31,42 +31,53 @@ class ChatLogic extends BaseLogic
31 * @method :post 31 * @method :post
32 * @time :2025/4/2 10:01 32 * @time :2025/4/2 10:01
33 */ 33 */
34 - public function sendMessage(){ 34 + public function sendMessage()
  35 + {
35 $gptService = new GptService(); 36 $gptService = new GptService();
36 - if(isset($this->param['chat_id'])){  
37 - $chatInfo = $this->model->read(['id'=>$this->param['chat_id']]);  
38 - if($chatInfo !== false){  
39 - $this->saveChatItem($chatInfo['id'],$this->param['message']);  
40 - $list = $this->itemModel->list(['chat_id'=>$chatInfo['id']],'id',['*'],'desc',2); 37 + $message = [];
  38 + if (isset($this->param['chat_id'])) {
  39 + $chatInfo = $this->model->read(['id' => $this->param['chat_id']]);
  40 + if ($chatInfo !== false) {
  41 + $this->saveChatItem($chatInfo['id'], $this->param['message']);
  42 + // 获取最近 2 条对话记录
  43 + $list = $this->itemModel->list(['chat_id' => $chatInfo['id']], 'id', ['*'], 'desc', 2);
41 $message[] = ['role' => 'system', 'content' => "You are now the marketing customer service of 深圳创贸集团"]; 44 $message[] = ['role' => 'system', 'content' => "You are now the marketing customer service of 深圳创贸集团"];
42 - foreach ($list as $val){  
43 - if($val['is_reply'] == 2){ 45 + foreach ($list as $val) {
  46 + if ($val['is_reply'] == 2) {
44 $message[] = ['role' => 'user', 'content' => $val['content']]; 47 $message[] = ['role' => 'user', 'content' => $val['content']];
45 - }else{ 48 + } else {
46 $message[] = ['role' => 'assistant', 'content' => $val['content']]; 49 $message[] = ['role' => 'assistant', 'content' => $val['content']];
47 } 50 }
48 } 51 }
49 $message[] = ['role' => 'user', 'content' => $this->param['message']]; 52 $message[] = ['role' => 'user', 'content' => $this->param['message']];
50 - $data = [  
51 - 'message'=>$message,  
52 - ];  
53 - $result = $gptService->get_ai_chat($data);  
54 - $streamContent = $result->getBody()->getContents(); // 读取流内容  
55 -// $this->saveChatItem($chatInfo['id'],$result['text'] ?? '服务器繁忙,请重试',1);  
56 -// return $this->success(['text'=>$result['text']]); 53 + $chatId = $chatInfo['id'];
57 } 54 }
58 - }  
59 - $id = $this->saveChat($this->param['message']);  
60 - $this->saveChatItem($id,$this->param['message']);  
61 - $data = [  
62 - 'message'=>[ 55 + } else {
  56 + $chatId = $this->saveChat($this->param['message']);
  57 + $this->saveChatItem($chatId, $this->param['message']);
  58 + $message = [
63 ['role' => 'system', 'content' => "You are now the marketing customer service of 深圳创贸集团"], 59 ['role' => 'system', 'content' => "You are now the marketing customer service of 深圳创贸集团"],
64 - ['role' => 'user', 'content' => $this->param['message']]  
65 - ],  
66 - ];  
67 - $result = $gptService->get_ai_chat($data);  
68 - $this->saveChatItem($id,$result['text'] ?? '服务器繁忙,请重试',1);  
69 - return $this->success(['text'=>$result['text']]); 60 + ['role' => 'user', 'content' => $this->param['message']],
  61 + ];
  62 + }
  63 + $data = ['message' => $message];
  64 + return response()->stream(function () use ($gptService, $data, $chatId) {
  65 + $fullResponse = ''; // 存储完整 AI 回复
  66 + $stream = $gptService->get_ai_chat($data); // 获取流
  67 + while (!$stream->eof()) {
  68 + $chunk = $stream->read(1024); // 逐步读取数据块
  69 + echo $gptService->en_sse_data($chunk); // **封装 SSE 数据**
  70 + ob_flush();
  71 + flush();
  72 + $fullResponse .= $chunk; // 拼接完整 AI 回复
  73 + }
  74 + // **流结束后,保存完整的 AI 回复**
  75 + $this->saveChatItem($chatId, $fullResponse ?: '服务器繁忙,请重试', 1);
  76 + }, 200, [
  77 + "Content-Type" => "text/event-stream",
  78 + "Cache-Control" => "no-cache",
  79 + "Connection" => "keep-alive",
  80 + ]);
70 } 81 }
71 82
72 /** 83 /**
@@ -24,13 +24,6 @@ class GptService @@ -24,13 +24,6 @@ class GptService
24 * 24 *
25 */ 25 */
26 public function get_ai_chat($data,$type = 0){ 26 public function get_ai_chat($data,$type = 0){
27 - // 组装请求体参数  
28 - // $data['message'] = [  
29 - // ['role' => 'system', 'content' => "You are now the marketing customer service of 深圳创贸集团"],  
30 - // ['role' => 'user', 'content' => '创贸集团有多少技术?'],  
31 - // ['role' => 'assistant', 'content' => '创贸集团有200+技术。'],  
32 - // ['role' => 'user', 'content' => '今天天气怎么样']  
33 - // ];  
34 $apikey = env('AI_CREATE_KEY')??'7yn!We6$&NnVA38bpGy*A@4TQ5iYLJcW'; 27 $apikey = env('AI_CREATE_KEY')??'7yn!We6$&NnVA38bpGy*A@4TQ5iYLJcW';
35 $client = new CmerClient($apikey); 28 $client = new CmerClient($apikey);
36 // 修改超时时间,默认60秒 29 // 修改超时时间,默认60秒
@@ -50,11 +43,26 @@ class GptService @@ -50,11 +43,26 @@ class GptService
50 } 43 }
51 return json_decode($result,true); 44 return json_decode($result,true);
52 }else { 45 }else {
53 - //发送流式请求 46 + // **流式请求**
54 $payload->stream = true; 47 $payload->stream = true;
55 $response = $client->chat($payload); 48 $response = $client->chat($payload);
56 - $body = $response->getBody();  
57 - return $body; 49 + $stream = $response->getBody();
  50 + return $stream;
58 } 51 }
59 } 52 }
  53 +
  54 + /**
  55 + * @remark :返回格式
  56 + * @name :en_sse_data
  57 + * @author :lyh
  58 + * @method :post
  59 + * @time :2025/4/2 16:56
  60 + */
  61 + public function en_sse_data($body, string $type='text'){
  62 + return 'data:'.json_encode([
  63 + 'id' => md5(is_array($body) ? json_encode($body) : $body),
  64 + 'data' => $body,
  65 + 'type' => $type
  66 + ],JSON_UNESCAPED_UNICODE)."\n\n";
  67 + }
60 } 68 }