where('user_id', self::$uid)->findOrEmpty(); if ($info->isEmpty()) { throw new \Exception("查无此信息"); } if ($info->status != 3) { throw new \Exception("状态错误"); } self::analysisCron($info->task_id); self::$returnData = $info->refresh()->toArray(); return true; } catch (\Exception $exception) { self::setError($exception->getMessage()); return false; } } /** * 详情 * @param int $id * @return bool * @author L * @data 2024-07-05 11:34:16 */ public static function analysisDetail(int $id): bool { try { $info = LlAnalysis::where('id', $id)->where('user_id', self::$uid)->findOrEmpty(); if ($info->isEmpty()) { throw new \Exception("查无此信息"); } if ($info->status != 2) { throw new \Exception("状态错误"); } //时长 end_time - start_tim $info->duration = $info->end_time - $info->start_time; $info->start_time = date('Y-m-d H:i:s', $info->start_time); $info->end_time = date('Y-m-d H:i:s', $info->end_time); self::$returnData = $info->toArray(); return true; } catch (\Exception $exception) { self::setError($exception->getMessage()); return false; } } /** * 删除 * @param array $data * @return bool * @author L * @data 2024-07-05 11:05:46 */ public static function analysisDelete(array $data): bool { try { if (is_string($data['id'])) { LlAnalysis::destroy(['id' => $data['id'], 'user_id' => self::$uid]); } else { LlAnalysis::whereIn('id', $data['id'])->where('user_id', self::$uid)->seclect()->delete(); } return true; } catch (\Exception $exception) { self::setError($exception->getMessage()); return false; } } /** * 存入草稿 * @param array $data * @return bool * @author Rick * @data 2024-06-09 11:05:46 */ public static function analysisAddDraft(array $data): bool { try { LlAnalysis::update(['is_draft' => 1],['id' => $data['analysis_id']]); self::$returnData = ['message'=>'操作成功']; return true; } catch (\Exception $exception) { self::setError($exception->getMessage()); return false; } } /** * 分析工作台 * @return bool * @author L * @data 2024-07-05 11:05:46 */ public static function analysisWorkbench(): bool { try { // 已创建场景数 $sceneCount = LlScene::withTrashed()->where('user_id', self::$uid)->count(); // 总场景数 $totalSceneCount = LlScene::where('user_id', self::$uid)->whereOr('user_id', 0)->count(); // 已练习场景数 $practiceSceneIds = LlAnalysis::where('user_id', self::$uid)->column('distinct scene_id'); $practiceSceneCount = count($practiceSceneIds); //待练习场景数 $pendingSceneCount = $totalSceneCount - $practiceSceneCount; // 平均分数 $averageScore = bcadd(LlAnalysis::where('user_id', self::$uid)->avg('total_score'), 0, 2); //最新3个场景LOGO $sceneLogos = []; LlScene::whereNotIn('id', $practiceSceneIds)->order('id', 'desc')->limit(3)->field('logo')->select()->each(function ($item) use (&$sceneLogos) { $sceneLogos[] = FileService::getFileUrl($item['logo']); }); self::$returnData = [ 'scene_count' => $sceneCount, 'total_scene_count' => $totalSceneCount, 'practice_scene_count' => $practiceSceneCount, 'pending_scene_count' => $pendingSceneCount, 'average_score' => $averageScore, 'scene_logos' => $sceneLogos ]; return true; } catch (\Exception $exception) { self::setError($exception->getMessage()); return false; } } /** * 场景添加 * @param array $data * @return bool * @author L * @data 2024-07-05 11:05:46 */ public static function sceneAdd(array $data): bool { try { //随机从配置列表中提取 $info = ConfigService::get('lianlian', 'config', []); $data['logo'] = $info['avatars'][array_rand($info['avatars'])]; $data['coach_language'] = '中文'; $data['analysis_report_config'] = json_encode($info['directions'], JSON_UNESCAPED_UNICODE); $data['user_id'] = self::$uid; // $res = LlScene::create($data)->toArray(); $data['type'] = 2; \app\api\logic\KnowledgeLogic::bind($data, $res); self::$returnData = $res; return true; } catch (\Exception $exception) { self::setError($exception->getMessage()); return false; } } /** * 场景删除 * @param array $data * @return bool * @author L * @data 2024-07-05 11:05:46 */ public static function sceneDelete(array $data): bool { try { if (is_string($data['id'])) { LlScene::destroy(['id' => $data['id'], 'user_id' => self::$uid]); } else { LlScene::whereIn('id', $data['id'])->where('user_id', self::$uid)->select()->delete(); } return true; } catch (\Exception $exception) { self::setError($exception->getMessage()); return false; } } /** * 场景编辑 * @param array $data * @return bool * @author L * @data 2024-07-05 11:05:46 */ public static function sceneEdit(array $data): bool { try { $info = LlScene::where('id', $data['id'])->where('user_id', self::$uid)->findOrEmpty(); if ($info->isEmpty()) { throw new \Exception("查无此信息"); } $info->name = $data['name'] ?? $info->name; $info->description = $data['description'] ?? $info->description; $info->coach_name = $data['coach_name'] ?? $info->coach_name; $info->coach_persona = $data['coach_persona'] ?? $info->coach_persona; $info->coach_voice = $data['coach_voice'] ?? $info->coach_voice; $info->coach_emotion = $data['coach_emotion'] ?? $info->coach_emotion; $info->coach_intensity = $data['coach_intensity'] ?? $info->coach_intensity; $info->practitioner_persona = $data['practitioner_persona'] ?? $info->practitioner_persona; $info->save(); $data['type'] = 2; \app\api\logic\KnowledgeLogic::bind($data, $info); self::$returnData = $info->toArray(); return true; } catch (\Exception $exception) { self::setError($exception->getMessage()); return false; } } /** * 场景详情 * @param int $id * @return bool * @author L * @data 2024-07-05 11:34:16 */ public static function sceneDetail(int $id): bool { try { $info = LlScene::findOrEmpty($id); if ($info->isEmpty()) { throw new \Exception("查无此信息"); } $analysis = LlAnalysis::where([ 'scene_id'=>$id, 'user_id'=>self::$uid, 'status'=>0, 'is_draft'=>1 ])->findOrEmpty(); $info['is_draft'] = $analysis->isEmpty() ? 0 : 1; $info['analysis_id'] = $analysis->id ?? 0; $info['index_id'] = \app\common\model\knowledge\KnowledgeBind::where('data_id', $info->id)->where('type', 2)->value('index_id'); $info['knowledge'] = \app\common\model\knowledge\KnowledgeBind::alias('b') ->field('k.index_id, k.name, k.category_id, k.description, k.rerank_min_score, b.data_id, b.type') ->where('b.data_id', $id) ->join('knowledge k', 'k.index_id = b.index_id', 'LEFT') ->where('b.type', 2) ->limit(1) ->find(); if ($info->user_id != 0 && $info->user_id != self::$uid) { throw new \Exception("查无此信息"); } self::$returnData = $info->toArray(); return true; } catch (\Exception $exception) { self::setError($exception->getMessage()); return false; } } /** * 话术提炼 * @param array $data * @return string * @author L * @data 2024/7/21 15:55 */ public static function speechcraftChat(array $data): string { try { $info = LlAnalysis::where('id', $data['analysis_id']) ->where('user_id', self::$uid) ->where('scene_id', $data['scene_id']) ->findOrEmpty(); if ($info->isEmpty()) { throw new \Exception("查无此信息"); } //不处于聊天状态 if ($info->status != 0) { throw new \Exception("状态错误"); } //获取场景信息 $sceneInfo = LlScene::findOrEmpty($info->scene_id); if ($sceneInfo->isEmpty()) { throw new \Exception("场景信息丢失"); } //获取当前聊天 $chatInfo = LlChat::findOrEmpty($data['chat_id']); if ($chatInfo->isEmpty()) { throw new \Exception("聊天信息丢失"); } //获取聊天记录 $logs = json_encode(self::chatLog($info->id, $info->scene_id, $info->user_id, $data['chat_id']), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT); // 获取话术提炼关键词 $keyWords = ChatPrompt::where('id', 9)->value('prompt_text') ?? ''; if (!$keyWords) { throw new \Exception("关键词丢失"); } //替换数据 $keyWords = str_replace(['场景名称', '对话内容'], [$sceneInfo->name, $logs], $keyWords); //print_r($keyWords);die; // 检查是否挂载知识库 $bind = \app\common\model\knowledge\KnowledgeBind::where('data_id', $data['scene_id'])->where('type', 2)->limit(1)->find(); if (!empty($bind)) { $response = self::knowledgeChat($bind, $keyWords, $sceneInfo); }else{ //发送聊天 $response = \app\common\service\ToolsService::Ll()->chat([ 'action' => 'speechcraft', 'messages' => $keyWords ]); } //聊天 $chatInfo->speechcraft = $response['data']['message']; $chatInfo->save(); self::$returnData = $chatInfo->toArray(); return true; } catch (\Exception $exception) { self::setError($exception->getMessage()); return false; } } /** * 表现提炼 * @param array $data * @return string * @author L * @data 2024/7/21 15:55 */ public static function performanceChat(array $data): string { try { $info = LlAnalysis::where('id', $data['analysis_id']) ->where('user_id', self::$uid) ->where('scene_id', $data['scene_id']) ->findOrEmpty(); if ($info->isEmpty()) { throw new \Exception("查无此信息"); } //不处于聊天状态 if ($info->status != 0) { throw new \Exception("状态错误"); } //获取场景信息 $sceneInfo = LlScene::findOrEmpty($info->scene_id); if ($sceneInfo->isEmpty()) { throw new \Exception("场景信息丢失"); } //获取当前聊天 $chatInfo = LlChat::findOrEmpty($data['chat_id']); if ($chatInfo->isEmpty()) { throw new \Exception("聊天信息丢失"); } $logs = self::chatLog($info->id, $info->scene_id, $info->user_id, $data['chat_id']); if (count($logs) == 1) { throw new \Exception("当前处于开场白,请继续对话"); } //移除最后一条(陪练者说的) array_pop($logs); //获取聊天记录 $logs = json_encode($logs, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT); // 获取表现提炼关键词 $keyWords = ChatPrompt::where('id', 11)->value('prompt_text') ?? ''; if (!$keyWords) { throw new \Exception("关键词丢失"); } //替换方向 $keyWords = str_replace(['方向1', '方向2', '方向3', '方向4', '方向5'], $sceneInfo->analysis_report_config, $keyWords); //替换数据 $keyWords = str_replace(['场景名称', '对话内容'], [$sceneInfo->name, $logs], $keyWords); // 检查是否挂载知识库 $bind = \app\common\model\knowledge\KnowledgeBind::where('data_id', $data['scene_id'])->where('type', 2)->limit(1)->find(); if (!empty($bind)) { $response = self::knowledgeChat($bind, $keyWords, $sceneInfo); }else{ //发送聊天 $response = \app\common\service\ToolsService::Ll()->chat([ 'action' => 'performance', 'messages' => $keyWords ]); } //聊天 $chatInfo->performance = $response['data']['message']; $chatInfo->save(); self::$returnData = $chatInfo->toArray(); return true; } catch (\Exception $exception) { self::setError($exception->getMessage()); return false; } } /** * 开始聊天 * @param array $data * @param int $userId * @return bool * @throws \Exception * @author L * @data 2024/7/9 16:15 */ public static function startChat(array $data): bool { Db::startTrans(); //计费,改为结算的时候扣费 // $unit = TokenLogService::checkToken(self::$uid, 'lianlian'); try { // 场景ID if (!isset($data['scene_id'])) { throw new \Exception('场景ID不能为空'); } $info = LlScene::findOrEmpty($data['scene_id']); if ($info->isEmpty()) { throw new \Exception("查无此信息"); } if ($info->user_id != 0 && $info->user_id != self::$uid) { throw new \Exception("查无此信息"); } //场景重练或发起新对话时,删除无效的旧对话数据 $drafts = LlAnalysis::where([ 'scene_id' => $data['scene_id'], 'user_id' => self::$uid, 'is_draft' => 1, 'status' => 0 ])->select()->toArray(); if ($drafts){ foreach ($drafts as $draft){ LlChat::destroy(['analysis_id'=>$draft['id']]); LlAnalysis::destroy($draft['id']); // Log::write('场景ID:'.$data['scene_id'].'对话ID:'.$draft['id'].'删除成功'); } } $task_id = generate_unique_task_id(); //新增分析 $analysisInfo = LlAnalysis::create([ 'scene_id' => $data['scene_id'], 'user_id' => self::$uid, 'task_id' => $task_id, 'start_time' => time(), ]); // 获取开场白 $keyWords = ChatPrompt::where('id', 6)->value('prompt_text') ?? ''; if (!$keyWords) { throw new \Exception("关键词丢失"); } //替换数据 $keyWords = str_replace(['陪练画像描述', '陪练母语', '练习者扮演的人设', '练习场景'], [$info->coach_persona, $info->coach_language, $info->practitioner_persona, $info->description], $keyWords); // 检查是否挂载知识库 $bind = \app\common\model\knowledge\KnowledgeBind::where('data_id', $data['scene_id'])->where('type', 2)->limit(1)->find(); if (!empty($bind)) { $response = self::knowledgeChat($bind, $keyWords, $info); }else{ // 发起聊天 $response = \app\common\service\ToolsService::Ll()->chat([ 'action' => 'start', 'voice' => $info->coach_voice, 'emotion' => $info->coach_emotion, 'intensity' => $info->coach_intensity, 'messages' => [ [ 'role' => 'user', 'content' => $keyWords ] ], ]); } if (!isset($response['data'])) { throw new \Exception("发起场景陪练失败"); } //保存数据 $chatInfo = LlChat::create([ 'scene_id' => $analysisInfo->scene_id, 'user_id' => $analysisInfo->user_id, 'analysis_id' => $analysisInfo->id, 'preliminary_ask' => $response['data']['message'] ?? '', 'preliminary_ask_audio' => FileService::downloadFileBySource($response['data']['audio_url'], 'audio'), 'preliminary_ask_audio_duration' => $response['data']['audio_duration'] ?? 0, ]); //token扣除,改为结算时扣费 // User::userTokensChange($analysisInfo->user_id, $unit); //记录日志,改为结算时扣费 // AccountLogLogic::recordUserTokensLog(true, $analysisInfo->user_id, AccountLogEnum::TOKENS_DEC_AI_LIANLIAN, $unit, $analysisInfo->task_id); self::$returnData = $chatInfo->toArray(); Db::commit(); return true; } catch (\Exception $e) { Db::rollback(); self::setError($e->getMessage()); return false; } } private static function flattenArray($array) { $result = []; foreach ($array as $value) { if (is_array($value)) { $result = array_merge($result, self::flattenArray($value)); } else { $result[] = $value; } } return $result; } private static function knowledgeChat($bind, $keyWords, $info){ $knowledge = \app\common\model\knowledge\Knowledge::where('id', $bind['kid'])->limit(1)->find(); if (empty($knowledge)) { throw new \Exception("挂载的知识库不存在"); } //clogger($keyWords, 'll'); $knResponse = \app\api\logic\KnowledgeLogic::ladderPlayerChat([ 'message' => $keyWords, 'indexid' => $knowledge['index_id'], 'rerank_min_score' => $knowledge['rerank_min_score'] ?? 0.2, 'stream' => false, 'user_id' => self::$uid, 'scene' => '陪练聊天', 'voice' => $info->coach_voice, 'emotion' => $info->coach_emotion, 'intensity' => $info->coach_intensity, ]); $response['data'] = array( 'message' => $knResponse['choices'][0]['message']['content']?? '', 'audio_url' => $knResponse['audio_url'] ?? '', 'audio_duration' => $knResponse['audio_duration'] ?? 0, ); return $response; } /** * 继续聊天 * @param array $data * @param int $userId * @return bool * @throws \Exception * @author L * @data 2024/7/9 16:15 */ public static function continueChat(array $data): bool { Db::startTrans(); try { $info = LlAnalysis::where('is_draft', 1) ->where('id', $data['analysis_id']) ->where('user_id', self::$uid) ->where('scene_id', $data['scene_id']) ->order('id','DESC') ->findOrEmpty(); if ($info->isEmpty()) { throw new \Exception("查无此信息"); } //不处于聊天状态 if ($info->status != 0) { throw new \Exception("状态错误"); } //获取场景信息 $sceneInfo = LlScene::findOrEmpty($info->scene_id); if ($sceneInfo->isEmpty()) { throw new \Exception("场景信息丢失"); } //保存数据 $chatInfo = LlChat::create([ 'scene_id' => $info->scene_id, 'user_id' => $info->user_id, 'analysis_id' => $info->id, 'ask' => $data['ask'], 'ask_audio' => FileService::setFileUrl($data['ask_audio']), 'ask_audio_duration' => $data['ask_audio_duration'], ]); //获取聊天记录 $logs = json_encode(self::chatLog($info->id, $info->scene_id, self::$uid), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT); // 对话延续关键词 $keyWords = ChatPrompt::where('id', 10)->value('prompt_text') ?? ''; if (!$keyWords) { throw new \Exception("关键词丢失"); } //替换数据 $keyWords = str_replace(['场景名称', '对话内容', '陪练母语'], [$sceneInfo->name, $logs, $sceneInfo->coach_language], $keyWords); // 检查是否挂载知识库 $bind = \app\common\model\knowledge\KnowledgeBind::where('data_id', $data['scene_id'])->where('type', 2)->limit(1)->find(); if (!empty($bind)) { $response = self::knowledgeChat($bind, $keyWords, $sceneInfo); }else{ // 发起聊天 $response = \app\common\service\ToolsService::Ll()->chat([ 'action' => 'continue', 'voice' => $sceneInfo->coach_voice, 'emotion' => $sceneInfo->coach_emotion, 'intensity' => $sceneInfo->coach_intensity, 'messages' => [ [ 'role' => 'user', 'content' => $keyWords ] ], ]); } if (!isset($response['data'])) { throw new \Exception("陪练对话失败"); } $chatInfo->reply = $response['data']['message']; $chatInfo->reply_audio = FileService::downloadFileBySource($response['data']['audio_url'], 'audio'); $chatInfo->reply_audio_duration = $response['data']['audio_duration']; $chatInfo->save(); self::$returnData = $chatInfo->toArray(); Db::commit(); return true; } catch (\Exception $e) { Db::rollback(); self::setError($e->getMessage()); return false; } } /** * 继续聊天 * @param string $audio * @param int $userId * @return bool * @throws \Exception * @author L * @data 2024/7/9 16:15 */ public static function chatSTT(string $audio): bool { try { // 发起聊天 $response = \app\common\service\ToolsService::Ll()->stt([ 'audio_url' => $audio, ]); if (!isset($response['data'])) { throw new \Exception("语音识别失败"); } self::$returnData = ['message' => $response['data']['message'], 'audio_duration' => $response['data']['audio_duration']]; return true; } catch (\Exception $e) { self::setError($e->getMessage()); return false; } } /** * 获取聊天记录 * @param int $analysisId * @param int $sceneId * @param int $userId * @return array */ public static function chatLog(int $analysisId, int $sceneId, int $userId, int $chatId = 0): array { // 获取开场白 $keyWords = ChatPrompt::where('id', 6)->value('prompt_text') ?? ''; if (!$keyWords) { throw new \Exception("关键词丢失"); } $logs = []; LlChat::where('analysis_id', $analysisId) ->where('scene_id', $sceneId) ->where('user_id', $userId) ->when($chatId != 0, function ($query) use ($chatId) { $query->where('id', '<=', $chatId); }) ->order('id', 'asc') ->select() ->each(function ($item, $key) use (&$logs, $keyWords) { if ($key == 0) { // 获取助理提示词 $info = LlScene::field(['coach_persona', 'coach_language', 'practitioner_persona', 'description'])->findOrEmpty($item['scene_id']); //替换数据 $keyWords = str_replace(['陪练画像描述', '陪练母语', '练习者扮演的人设', '练习场景'], [$info->coach_persona, $info->coach_language, $info->practitioner_persona, $info->description], $keyWords); $logs[] = [ 'role' => 'user', 'content' => $keyWords ]; $logs[] = [ 'role' => 'assistant', 'content' => $item->preliminary_ask ]; } else { $logs[] = [ 'role' => 'user', 'content' => $item->ask ]; if (!empty($item->reply)) { $logs[] = [ 'role' => 'assistant', 'content' => $item->reply ]; } } }); return $logs; } /** * 结束聊天 * @param array $data * @return bool * @author L * @data 2024/7/11 9:47 */ public static function endChat(array $data): bool { try { //计费,改为结算的时候扣费 $unit = TokenLogService::checkToken(self::$uid, 'lianlian'); $info = LlAnalysis::where('id', $data['analysis_id']) ->where('user_id', self::$uid) ->where('scene_id', $data['scene_id']) ->findOrEmpty(); if ($info->isEmpty()) { throw new \Exception("查无此信息"); } //不处于聊天状态 if ($info->status != 0) { throw new \Exception("状态错误"); } //陪练结束,中台扣费 $response = \app\common\service\ToolsService::Ll()->chat([ 'action' => 'end', ]); if (!isset($response['data'])) { throw new \Exception("陪练结束失败"); } $info->status = 1; $info->is_draft = 0; $info->end_time = time(); $info->save(); self::$returnData = $info->toArray(); //token扣除 User::userTokensChange($info->user_id, $unit); //记录日志 AccountLogLogic::recordUserTokensLog(true, $info->user_id, AccountLogEnum::TOKENS_DEC_AI_LIANLIAN, $unit, $info->task_id); return true; } catch (\Exception $exception) { self::setError($exception->getMessage()); return false; } } /** * @desc 视频定时任务 * @return bool|void * @date 2024/10/2 10:36 * @throws \GuzzleHttp\Exception\GuzzleException * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException * @author dagouzi */ public static function analysisCron(string $taskId = '') { ini_set('memory_limit', '-1'); ini_set('max_execution_time', 0); try { if ($taskId == '') { //请求12小时内,还处于分析中状态的任务 LlAnalysis::where('status', 1) ->where('create_time', '<=', strtotime('-12 hours')) ->select() ->each(function ($item) { $item->status = 3; $item->remark = '执行超时'; $item->save(); }); } // 第一步:获取任务列表 $taskModel = LlAnalysis::where('tries', '<', 3) ->order('id', 'asc') ->limit(3); if ($taskId) { $taskModel = $taskModel->where('task_id', $taskId)->where('status', 3); } else { $taskModel = $taskModel->where('status', 1); } //第二步遍历任务 $taskModel->select()->each(function ($item) { //如果存在失败,且还没到执行时间(1分钟后执行) if ($item->tries >= 1 && strtotime($item->update_time) > strtotime('-1 minute')) { return true; } try { $tries = $item->tries; //分析模块 //获取场景信息 $sceneInfo = LlScene::findOrEmpty($item->scene_id); if ($sceneInfo->isEmpty()) { $item->status = 3; $item->remark = '场景信息丢失'; $item->save(); return true; } //获取聊天记录 $logs = self::chatLog($item->id, $item->scene_id, $item->user_id); if (!$logs) { $item->status = 3; $item->remark = '聊天记录丢失'; $item->save(); return true; } $logs = json_encode($logs, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT); if (!$item->model_response) { // 获取模块分析关键词 $keyWords = ChatPrompt::where('id', 8)->value('prompt_text') ?? ''; if (!$keyWords) { $item->status = 3; $item->remark = '模块分析关键词丢失'; $item->save(); return true; } //替换方向 $keyWords = str_replace(['方向1', '方向2', '方向3', '方向4', '方向5'], $sceneInfo->analysis_report_config, $keyWords); //替换数据 $keyWords = str_replace(['场景名称', '对话内容'], [$sceneInfo->name, $logs], $keyWords); // 发起聊天 $response = \app\common\service\ToolsService::Ll()->chat([ 'action' => 'analysis', 'messages' => [ [ 'role' => 'user', 'content' => $keyWords ] ], ]); if (!isset($response['data'])) { if ($item->tries >= 3) { $item->status = 3; $item->remark = '模块分析失败'; $item->save(); return true; } $item->tries = $item->tries + 1; $item->save(); return true; } //总分数 $totalScore = array_sum(array_column($response['data']['message'], 'score')); $item->model_response = json_encode($response['data']['message'], JSON_UNESCAPED_UNICODE); $item->total_score = $totalScore; $item->save(); } //总分析 if (!$item->total_response) { // 获取总体分析关键词 $keyWords = ChatPrompt::where('id', 7)->value('prompt_text') ?? ''; if (!$keyWords) { $item->status = 3; $item->remark = '总体分析关键词丢失'; $item->save(); return true; } //替换方向 $keyWords = str_replace(['方向1', '方向2', '方向3', '方向4', '方向5'], $sceneInfo->analysis_report_config, $keyWords); //替换数据 $keyWords = str_replace(['场景名称', '对话内容'], [$sceneInfo->name, $logs], $keyWords); // 发起聊天 $response = \app\common\service\ToolsService::Ll()->chat([ 'action' => 'analysis', 'messages' => [ [ 'role' => 'user', 'content' => $keyWords ] ], ]); if (!isset($response['data'])) { if ($item->tries >= 3) { $item->status = 3; $item->remark = '总体分析失败'; $item->save(); return true; } $item->tries = $item->tries + 1; $item->save(); return true; } $item->total_response = $response['data']['message']; $item->save(); } $item->status = 2; $item->remark = '分析完成'; $item->save(); return true; } catch (\think\exception\HttpResponseException $e) { $item->tries = $tries + 1; $item->save(); self::setError($e->getResponse()->getData()['msg'] ?? '提交任务出错'); return true; } }); } catch (\Exception $e) { //TODO self::setError($e->getMessage()); return false; } return true; } }