| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 |
- <?php
- namespace App\Services\Agent;
- use App\Models\Agent\Agent;
- use App\Models\Agent\AgentDomain;
- use Illuminate\Support\Facades\DB;
- class AgentDomainService
- {
- public function save(Agent $agent, array $domains): array
- {
- return DB::transaction(function () use ($agent, $domains) {
- foreach (['pc', 'h5'] as $type) {
- if (!array_key_exists($type, $domains)) {
- continue;
- }
- $url = $this->normalize((string) $domains[$type]);
- if ($url === '') {
- AgentDomain::query()->where('agent_id', $agent->id)->where('type', $type)->delete();
- continue;
- }
- $host = $this->host($url);
- $owner = AgentDomain::query()->where('host', $host)->lockForUpdate()->first();
- if ($owner && (int) $owner->agent_id !== (int) $agent->id) {
- throw new \RuntimeException('该域名已绑定其他代理');
- }
- AgentDomain::query()->updateOrCreate(
- ['agent_id' => $agent->id, 'type' => $type],
- ['domain' => $url, 'host' => $host, 'status' => 1]
- );
- }
- return $this->format($agent->fresh());
- });
- }
- public function format(Agent $agent): array
- {
- $domains = $agent->domains()->where('status', 1)->pluck('domain', 'type');
- $pc = (string) ($domains['pc'] ?? '');
- $h5 = (string) ($domains['h5'] ?? '');
- return [
- 'pc_domain' => $pc,
- 'h5_domain' => $h5,
- 'pc_register_url' => $pc === '' ? '' : $this->registerUrl($pc, (string) config('agent.pc_register_path'), $agent->invitation_code),
- 'h5_register_url' => $h5 === '' ? '' : $this->registerUrl($h5, (string) config('agent.h5_register_path'), $agent->invitation_code),
- ];
- }
- public function resolve(?string $invitationCode, ?string $domain): ?Agent
- {
- if ($invitationCode) {
- return Agent::query()->where('invitation_code', strtoupper(trim($invitationCode)))
- ->where('status', Agent::STATUS_ENABLED)->first();
- }
- $normalized = $domain ? $this->normalize($domain) : '';
- if ($normalized === '') {
- return null;
- }
- $domainRow = AgentDomain::query()->where('host', $this->host($normalized))->where('status', 1)->first();
- return $domainRow ? Agent::query()->whereKey($domainRow->agent_id)->where('status', Agent::STATUS_ENABLED)->first() : null;
- }
- private function normalize(string $value): string
- {
- $value = trim($value);
- if ($value === '') {
- return '';
- }
- $candidate = preg_match('#^https?://#i', $value) ? $value : 'https://' . $value;
- $scheme = strtolower((string) parse_url($candidate, PHP_URL_SCHEME));
- $host = strtolower((string) parse_url($candidate, PHP_URL_HOST));
- $port = parse_url($candidate, PHP_URL_PORT);
- if (!in_array($scheme, ['http', 'https'], true) || $host === '') {
- throw new \InvalidArgumentException('域名格式错误');
- }
- return $scheme . '://' . $host . ($port ? ':' . $port : '');
- }
- private function registerUrl(string $domain, string $path, string $code): string
- {
- $separator = str_contains($path, '?') ? '&' : '?';
- return rtrim($domain, '/') . '/' . ltrim($path, '/') . $separator . 'agent_code=' . urlencode($code);
- }
- private function host(string $url): string
- {
- return strtolower((string) parse_url($url, PHP_URL_HOST));
- }
- }
|