wechatId = $data['wechat_id'] ?? ''; $this->friendId = $data['friend_id'] ?? ''; $this->deviceCode = $data['device_code'] ?? ''; $this->uid = $data['uid'] ?? 0; $this->request = $data['request'] ?? []; $this->taskId = $data['task_id'] ?? ''; if (!$this->wechatId || !$this->friendId || !$this->uid || !$this->deviceCode || empty($this->request)) { $job->delete(); return; } // 检查AI 是否已有回复记录 $log = ChatLog::where('task_id', $this->taskId)->findOrEmpty(); if($log->isEmpty()){ //clogger((json_encode($this->request['knowledge'], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)), 'wechat'); if(isset($this->request['knowledge']) && !empty($this->request['knowledge'])){ $response = \app\api\logic\KnowledgeLogic::chat([ 'message' => $this->request['message'], 'indexid' => $this->request['knowledge']['index_id'], 'rerank_min_score' => $this->request['knowledge']['rerank_min_score'] ?? 0.2, 'stream' => false, 'user_id' => $this->uid, 'scene' => '个微聊天' ]); // Log::write($this->taskId.'消息回复结果'.json_encode($response,JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); if (isset($response['choices'][0]) && !empty($response['choices'][0])) { $reply = $response['choices'][0]['message']['content']; } }else{ // 执行微信AI消息处理 $response = \app\common\service\ToolsService::Wechat()->chat($this->request); // Log::write($this->taskId.'消息回复结果2'.json_encode($response,JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); if (isset($response['code']) && $response['code'] == 10000) { // 处理响应 $reply = $this->handleResponse($response); } else { Log::write($this->taskId.'队列请求失败'.json_encode($response)); // 重试 $this->retryJob($job, 'AI消息处理失败', $data); } } }else{ $reply = $log->reply; } // 发送消息 $this->sendMessage($reply); // 任务执行成功,删除任务 $job->delete(); } catch (\Throwable $e) { //clogger($e); Log::write($this->taskId . '队列请求参数' . json_encode($data) . '失败原因' . $e->getMessage().'重试次数'.$job->attempts()); // Log::write('堆栈信息: ' . $e->getTraceAsString()); // 记录堆栈信息 $this->retryJob($job, $e->getMessage(), $data); } } /** * 重试任务 * @param Job $job * @param string $errorMessage * @param array $data * @return void */ private function retryJob(Job $job, string $errorMessage, array $data) { try { if ($job->attempts() >= 3) { // 超过重试次数,记录到失败任务表 $this->markAsFailed($job, $errorMessage, $data); $job->delete(); } else { $delay = pow(2, $job->attempts()) * 5; // 重试任务 $job->release($delay); } } catch (\Exception $e) { //clogger($e, 'wechat'); // 捕获异常并记录错误日志 Log::error('重试失败: ' . $e->getMessage()); } } /** * 处理响应 * @param array $response * @return string */ private function handleResponse(array $response): string { //检查扣费 $unit = TokenLogService::checkToken($this->uid, 'ai_wechat'); // 获取回复内容 $reply = $response['data']['message'] ?? ''; //计费 $tokens = $response['data']['usage']['total_tokens'] ?? 0; if (!$reply || $tokens == 0) { throw new \Exception('获取内容失败'); } $response = [ 'reply' => $reply, 'usage_tokens' => $response['data']['usage'] ?? [], ]; // 保存聊天记录 ChatLogic::saveChatResponseLog($this->request, $response); //计算消耗tokens $points = $unit > 0 ? ceil($tokens / $unit) : 0; //token扣除 User::userTokensChange($this->uid, $points); $extra = ['总消耗tokens数' => $tokens, '算力单价' => $unit, '实际消耗算力' => $points]; //扣费记录 AccountLogLogic::recordUserTokensLog(true, $this->uid, AccountLogEnum::TOKENS_DEC_AI_WECHAT, $points, $this->taskId, $extra); return $reply; } /** * 发送消息 * @param string $reply * @return void */ private function sendMessage(string $reply) { // \app\common\service\ToolsService::Wechat()->push([ // 'wechat_id' => $this->wechatId, // 'friend_id' => $this->friendId, // 'device_code' => $this->deviceCode, // 'message' => $reply, // 'message_type' => $this->request['message_id'] ? 22 : 1, //22: 引用 // 'remark' => $this->request['message_id'], // ]); self::wxPush([ 'wechat_id' => $this->wechatId, 'friend_id' => $this->friendId, 'device_code' => $this->deviceCode, 'message' => $reply, 'message_type' => $this->request['message_id'] ? 22 : 1, //22: 引用 'remark' => $this->request['message_id'], 'opt_type' => 'job' ]); } /** * 标记任务失败 * @param Job $job * @param string $errorMessage * @param array $data * @return void */ protected function markAsFailed(Job $job, string $errorMessage, array $data): void { try { $job_data = json_encode($data, JSON_UNESCAPED_UNICODE); Log::write( $data['request']['task_id'] . '错误消息' . $errorMessage . '新增数据' . $job_data .'重试次数'.$job->attempts()); Db::name('failed_jobs')->insert([ 'user_id' => $data['uid'] ?? 1, 'job_id' => $data['request']['task_id'] ?? 2, 'job_class' => get_class(), 'job_data' => $job_data, 'error_message' => $errorMessage, 'attempts' => $job->attempts(), 'failed_at' => date('Y-m-d H:i:s') ]); } catch (\Exception $e) { // 捕获插入失败的异常并记录日志 Log::error('标记任务失败时发生异常: ' . $e->getMessage()); } } }