roundRobinStore = $roundRobinStore ?? new SplitRoundRobinStore(); } /** * 根据链接码解析本次应跳转的加好友 URL;无效时返回 null * * @param string $linkCode 9 位链接码 * @param string $clientIp 访客 IP(IP 防护开启时用于国家校验) */ public function resolveRedirectUrl(string $linkCode, string $clientIp = ''): ?string { $linkCode = SplitLinkCodeService::normalize($linkCode); if (!SplitLinkCodeService::isValidFormat($linkCode)) { return null; } $link = Link::where('link_code', $linkCode) ->where('status', 'normal') ->find(); if (!$link) { return null; } $ipProtect = (int) $link->getAttr('ip_protect'); $countries = (string) $link->getAttr('countries'); if (!SplitIpProtectService::isAllowed($ipProtect, $countries, $clientIp)) { return null; } /** @var Collection|array $numbers */ $numbers = Number::where('split_link_id', (int) $link['id']) ->where('status', 'normal') ->order('id', 'asc') ->field('id,number,number_type,number_type_custom') ->select(); $count = is_countable($numbers) ? count($numbers) : 0; if ($count === 0) { return null; } $linkId = (int) $link->getAttr('id'); $index = $this->roundRobinStore->nextIndex($linkId, $count); $list = $numbers instanceof \think\Collection ? $numbers->all() : (array) $numbers; $picked = $list[$index] ?? $list[0] ?? null; if ($picked === null) { return null; } $numberType = is_array($picked) ? (string) ($picked['number_type'] ?? '') : (string) $picked->getAttr('number_type'); $numberValue = is_array($picked) ? (string) ($picked['number'] ?? '') : (string) $picked->getAttr('number'); $numberCustom = is_array($picked) ? (string) ($picked['number_type_custom'] ?? '') : (string) $picked->getAttr('number_type_custom'); $whatsAppReplyText = ''; if ($numberType === 'whatsapp') { $whatsAppReplyText = SplitAutoReplyService::pickRandomLine((string) $link->getAttr('auto_reply')); } $redirectUrl = SplitFriendUrlBuilder::build( $numberType, $numberValue, $numberCustom, $whatsAppReplyText ); if ($redirectUrl === '') { return null; } $numberId = is_array($picked) ? (int) ($picked['id'] ?? 0) : (int) $picked->getAttr('id'); if ($numberId > 0) { Number::where('id', $numberId)->setInc('visit_count'); } return $redirectUrl; } }