ChatLogic.php 4.5 KB
<?php
/**
 * @remark :
 * @name   :ChatLogic.php
 * @author :lyh
 * @method :post
 * @time   :2025/4/1 14:37
 */

namespace App\Http\Logic\Bside\Gpt;

use App\Helper\Stream;
use App\Http\Logic\Bside\BaseLogic;
use App\Models\Gpt\Chat;
use App\Models\Gpt\ChatItem;
use App\Services\GptService;

class ChatLogic extends BaseLogic
{
    public function __construct()
    {
        parent::__construct();
        $this->param = $this->requestAll;
        $this->model = new Chat();
        $this->itemModel = new ChatItem();
    }

    /**
     * @remark :发送消息
     * @name   :sendMessage
     * @author :lyh
     * @method :post
     * @time   :2025/4/2 10:01
     */
    public function sendMessage()
    {
        $gptService = new GptService();
        $message = [];
        if (isset($this->param['chat_id'])) {
            $chatInfo = $this->model->read(['id' => $this->param['chat_id']]);
            if ($chatInfo !== false) {
                $this->saveChatItem($chatInfo['id'], $this->param['message']);
                // 获取最近 2 条对话记录
                $list = $this->itemModel->list(['chat_id' => $chatInfo['id']], 'id', ['*'], 'desc', 2);
                $message[] = ['role' => 'system', 'content' => "You are now the marketing customer service of 深圳创贸集团"];
                foreach ($list as $val) {
                    if ($val['is_reply'] == 2) {
                        $message[] = ['role' => 'user', 'content' => $val['content']];
                    } else {
                        $message[] = ['role' => 'assistant', 'content' => $val['content']];
                    }
                }
                $message[] = ['role' => 'user', 'content' => $this->param['message']];
                $chatId = $chatInfo['id'];
            }
        } else {
            $chatId = $this->saveChat($this->param['message']);
            $this->saveChatItem($chatId, $this->param['message']);
            $message = [
                ['role' => 'system', 'content' => "You are now the marketing customer service of 深圳创贸集团"],
                ['role' => 'user', 'content' => $this->param['message']],
            ];
        }
        $data = ['message' => $message];
        $stream = $gptService->get_ai_chat($data); // 获取流
        header('Content-Type: text/event-stream');
        header('Cache-Control: no-cache');
        header('Connection: keep-alive');
        $aiResponse = '';
        while (!$stream->eof()) {
            $chunk = $stream->read(1024);
            $chunk = str_replace(chr(1), '', $chunk);
            if ($chunk !== false) {
                $aiResponse .= $chunk; // 累积完整的 AI 回复
                // 使用 en_sse_data 格式化流数据
                echo $gptService->en_sse_data(trim($chunk));
                ob_flush();
                flush();
            }
        }
        // 确保数据不是空的
        if (!empty(trim($aiResponse)) && $chatId) {
            $this->saveChatItem($chatId, trim($aiResponse), 1); // 存入数据库
        }
        return true;
    }

    /**
     * @remark :获取一行数据
     * @name   :getStreamContentLine
     * @author :lyh
     * @method :post
     * @time   :2025/4/2 22:42
     */
    public function getStreamContentLine($stream){
        $text = '';
        while (!$stream->eof()){
            // 读取一个字符串
            $t = $this->stream->read(1);
            $this->body .= $t;
            if($t === "\n"){
                break;
            }
            // 结束了
            if(ord($t)==1){
                break;
            }
            $text .= $t;
        }
        return $text;
    }

    /**
     * @remark :创建一条新会话
     * @name   :saveChat
     * @author :lyh
     * @method :post
     * @time   :2025/4/2 10:06
     */
    public function saveChat($message){
        //创建一个会话
        $saveData = [
            'user_id'=>$this->user['id'],
            'input_content'=>$message,
        ];
        return $this->model->addReturnId($saveData);
    }

    /**
     * @remark :消息详情表保存一条记录
     * @name   :saveChatItem
     * @author :lyh
     * @method :post
     * @time   :2025/4/2 13:45
     */
    public function saveChatItem($id,$message,$is_reply = 2){
        //创建一个会话
        $saveData = [
            'user_id'=>$this->user['id'],
            'is_reply'=>$is_reply,
            'chat_id'=>$id,
            'content'=>$message,
        ];
        return $this->itemModel->addReturnId($saveData);
    }
}