// +---------------------------------------------------------------------- declare (strict_types=1); namespace app\jobs; use app\services\kefu\CozeServices; use app\services\kefu\service\StoreServiceLogServices; use app\services\kefu\service\StoreServiceRecordServices; use app\services\kefu\service\StoreServiceServices; use crmeb\basic\BaseJobs; use crmeb\services\workerman\ChannelService; use crmeb\traits\QueueTrait; use crmeb\utils\Queue; use think\facade\Env; use think\facade\Log; /** * 在线客服 Coze 智能体回复任务。 */ class CozeKefuReplyJob extends BaseJobs { use QueueTrait; public static function dispatchAsync(array $payload) { if (sys_config('queue_open', 0) != 1 || Env::get('cache.driver', 'file') !== 'redis') { Log::error('在线客服 Coze 回复未入队:请开启 Redis 缓存和队列,避免阻塞 Workerman 聊天进程'); return false; } return Queue::instance()->job(__CLASS__)->do('doJob')->data($payload)->errorCount(1)->push(); } public function doJob(array $payload): bool { if (!CozeServices::isEnabled()) { return true; } $uid = (int)($payload['uid'] ?? 0); $toUid = (int)($payload['to_uid'] ?? 0); $content = trim((string)($payload['content'] ?? '')); $formType = (int)($payload['form_type'] ?? 0); $isTourist = (int)($payload['is_tourist'] ?? 0); if (!$uid || !$toUid || $content === '') { return true; } try { /** @var CozeServices $coze */ $coze = app()->make(CozeServices::class); $reply = $coze->chatText(($isTourist ? 'tourist_' : 'uid_') . $uid, $content); $reply = trim(strip_tags(htmlspecialchars_decode($reply))); if ($reply === '') { return true; } /** @var StoreServiceLogServices $logServices */ $logServices = app()->make(StoreServiceLogServices::class); /** @var StoreServiceRecordServices $recordServices */ $recordServices = app()->make(StoreServiceRecordServices::class); $autoReply = [ 'to_uid' => $uid, 'msn_type' => 1, 'msn' => $reply, 'uid' => $toUid, 'add_time' => time(), 'is_tourist' => $isTourist, 'type' => 1, ]; $autoReply = $logServices->save($autoReply)->toArray(); $autoReply['_add_time'] = $autoReply['add_time']; $autoReply['add_time'] = strtotime($autoReply['add_time']); /** @var StoreServiceServices $serviceServices */ $serviceServices = app()->make(StoreServiceServices::class); $kefuInfo = $serviceServices->get(['uid' => $toUid], ['nickname', 'avatar']); $replyMessagesCount = $logServices->getMessageNum([ 'uid' => $toUid, 'to_uid' => $uid, 'type' => 0, 'is_tourist' => $isTourist, ]); $autoReply['recored'] = $recordServices->saveRecord( $toUid, $uid, $reply, $formType, 1, $replyMessagesCount, $isTourist, $kefuInfo['nickname'] ?? '', $kefuInfo['avatar'] ?? '' ); ChannelService::instance()->setTrigger('crmeb_chat')->send('reply', $autoReply, [$uid]); } catch (\Throwable $e) { Log::error('在线客服 Coze 回复失败:' . $e->getMessage()); } return true; } }