From 3f56c64086f67f3f8e0c86a29233907ca18074c0 Mon Sep 17 00:00:00 2001 From: kuaifan Date: Sun, 23 Feb 2025 23:55:02 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96AI=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=88=86=E6=9E=90=E6=8C=87=E5=AE=9A=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Models/FileContent.php | 25 +++++++++- app/Models/User.php | 13 +++++ app/Module/{AiBot => }/TextExtractor.php | 17 +++---- app/Tasks/BotReceiveMsgTask.php | 60 +++++++++++++++--------- 4 files changed, 80 insertions(+), 35 deletions(-) rename app/Module/{AiBot => }/TextExtractor.php (93%) diff --git a/app/Models/FileContent.php b/app/Models/FileContent.php index 6b7b384d3..51d35b8da 100644 --- a/app/Models/FileContent.php +++ b/app/Models/FileContent.php @@ -2,7 +2,6 @@ namespace App\Models; - use App\Module\Base; use App\Module\Timer; use Illuminate\Database\Eloquent\SoftDeletes; @@ -157,4 +156,28 @@ class FileContent extends AbstractModel } return Base::retSuccess('success', [ 'content' => $content ]); } + + /** + * 获取文件内容 + * @param $id + * @return self|null + */ + public static function idOrCodeToContent($id) + { + $builder = null; + if (Base::isNumber($id)) { + $builder = FileContent::whereFid($id); + } elseif ($id) { + $fileLink = FileLink::whereCode($id)->first(); + if ($fileLink) { + $builder = FileContent::whereFid($fileLink->file_id); + } + } + /** @var self $fileContent */ + $fileContent = $builder?->orderByDesc('id')->first(); + if ($fileContent) { + $fileContent->content = Base::json2array($fileContent->content ?: []); + } + return $fileContent; + } } diff --git a/app/Models/User.php b/app/Models/User.php index 62c6f295d..8ed329d50 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -242,6 +242,19 @@ class User extends AbstractModel return in_array('admin', $this->identity); } + /** + * 返回是否AI机器人 + * @return bool + */ + public function isAiBot(&$aiName = '') + { + if (preg_match('/^ai-(.*?)@bot\.system$/', $this->email, $matches)) { + $aiName = $matches[1]; + return true; + } + return false; + } + /** * 判断是否管理员 */ diff --git a/app/Module/AiBot/TextExtractor.php b/app/Module/TextExtractor.php similarity index 93% rename from app/Module/AiBot/TextExtractor.php rename to app/Module/TextExtractor.php index e6039a607..0b385b0dc 100644 --- a/app/Module/AiBot/TextExtractor.php +++ b/app/Module/TextExtractor.php @@ -1,6 +1,6 @@ \n${content}\n - - // (see below for site content) - // \n${result}\n - } - + /** + * 获取文件内容 + * @param $filePath + * @return string + */ public static function getFileContent($filePath) { if (!file_exists($filePath) || !is_file($filePath)) { diff --git a/app/Tasks/BotReceiveMsgTask.php b/app/Tasks/BotReceiveMsgTask.php index d577df61a..8f0a631f7 100644 --- a/app/Tasks/BotReceiveMsgTask.php +++ b/app/Tasks/BotReceiveMsgTask.php @@ -2,6 +2,7 @@ namespace App\Tasks; +use App\Models\FileContent; use App\Models\Project; use App\Models\ProjectTask; use App\Models\User; @@ -12,6 +13,7 @@ use App\Models\WebSocketDialogMsg; use App\Module\Base; use App\Module\Doo; use App\Module\Ihttp; +use App\Module\TextExtractor; use Cache; use Carbon\Carbon; use DB; @@ -86,7 +88,7 @@ class BotReceiveMsgTask extends AbstractTask } // 提取指令 - $command = $this->extractCommand($msg, $this->mention); + $command = $this->extractCommand($msg, $botUser->isAiBot(), $this->mention); if (empty($command)) { return; } @@ -415,10 +417,9 @@ class BotReceiveMsgTask extends AbstractTask $userBot = null; $extras = []; $errorContent = null; - if (preg_match('/^ai-(.*?)@bot\.system$/', $botUser->email, $matches)) { + if ($botUser->isAiBot($type)) { // AI机器人 $setting = Base::setting('aibotSetting'); - $type = $matches[1]; $extras = [ 'model_type' => match ($type) { 'qianwen' => 'qwen', @@ -462,7 +463,7 @@ class BotReceiveMsgTask extends AbstractTask $replyMsg = WebSocketDialogMsg::find($msg->reply_id); $replyCommand = ''; if ($replyMsg) { - $replyCommand = $this->extractCommand($replyMsg); + $replyCommand = $this->extractCommand($replyMsg, true); if ($replyCommand) { $replyCommand = Base::cutStr($replyCommand, 2000); $replyCommand = <<type !== 'text') { return ''; @@ -576,37 +578,49 @@ class BotReceiveMsgTask extends AbstractTask if (str_starts_with($command, '%3A.')) { $command = ":" . substr($command, 4); } - } else { - $attachments = []; + return $command; + } + $aiContents = []; + if ($isAiBot) { if (preg_match_all("/(.*?)<\/span>/", $original, $match)) { $taskIds = Base::newIntval($match[1]); foreach ($taskIds as $index => $taskId) { + $taskName = addslashes($match[2][$index]) . " (ID:{$taskId})"; + $taskContext = "任务状态:不存在或已删除"; $taskInfo = ProjectTask::with(['content'])->whereId($taskId)->first(); if ($taskInfo) { $taskName = addslashes($taskInfo->name) . " (ID:{$taskId})"; $taskContext = implode("\n", $taskInfo->AIContext()); - } else { - $taskName = addslashes($match[2][$index]) . " (ID:{$taskId})"; - $taskContext = "任务状态:不存在或已删除"; } - $replName = "'{$taskName}'"; - $attachments[] = [ - 'search' => $replName, - 'replace' => "{$replName} (see below for task_content tag)", - 'context' => "\n{$taskContext}\n", - ]; - $original = str_replace($match[0][$index], $replName, $original); + $aiContents[] = "\n{$taskContext}\n"; + $original = str_replace($match[0][$index], "'{$taskName}' (see below for task_content tag)", $original); } } - if ($attachments) { - Cache::put("bot:{$msg->id}:attachments", Base::array2json($attachments), 60); + if (preg_match_all("/]*?>(.*?)<\/a>/", $original, $match)) { + $filePaths = $match[1]; + foreach ($filePaths as $index => $filePath) { + if (preg_match("/single\/file\/(.*?)$/", $filePath, $fileMatch)) { + $fileName = addslashes($match[2][$index]); + $fileContent = "文件状态:不存在或已删除"; + $fileInfo = FileContent::idOrCodeToContent($fileMatch[1]); + if ($fileInfo && isset($fileInfo->content['url'])) { + $filePath = public_path($fileInfo->content['url']); + if (file_exists($filePath)) { + $fileName .= " (ID:{$fileInfo->id})"; + $fileContent = TextExtractor::getFileContent($filePath); + } + } + $aiContents[] = "\n{$fileContent}\n"; + $original = str_replace($match[0][$index], "'{$fileName}' (see below for file_content tag)", $original); + } + } } - $command = trim(strip_tags($original)); } - if (empty($command)) { - return ''; + $command = trim(strip_tags($original)); + if ($aiContents) { + $command .= "\n\n" . implode("\n\n", $aiContents); } - return $command; + return $command ?: ''; } /**