'array', 'status' => 'integer', 'user_id' => 'integer', ]; } public function user(): BelongsTo { return $this->belongsTo(User::class, 'user_id'); } public function isEnabled(): bool { return (int) $this->status === 1; } public function isOfficial(): bool { return (int) $this->user_id === self::OFFICIAL_USER_ID; } public function agentLabel(): string { if ($this->isOfficial()) { return '官方'; } return $this->user?->username ?: ('#'.$this->user_id); } /** * Domains for support-link display. * Channel row wins; otherwise CORUNA_LAB_CHANNEL_DOMAINS (system settings). * * @return list */ public function resolvedDomains(): array { $stored = $this->normalizeDomainList($this->domains); if ($stored !== []) { return $stored; } return $this->normalizeDomainList(config('coruna.channel_domains', [])); } /** * @param mixed $domains * @return list */ public static function normalizeDomainList(mixed $domains): array { if (! is_array($domains)) { return []; } return array_values(array_unique(array_filter(array_map(static function ($d) { if (! is_string($d)) { return ''; } $d = trim($d); $d = preg_replace('#^https?://#i', '', $d) ?? $d; return rtrim($d, '/'); }, $domains)))); } /** * @return list */ public function supportLinks(): array { $links = []; $path = '/web/'.$this->channel_id.'/support.html'; $scheme = trim((string) config('coruna.static_site.scheme', 'https')) ?: 'https'; foreach ($this->resolvedDomains() as $domain) { $origin = rtrim($domain, '/'); if ($origin === '') { continue; } if (! preg_match('#^https?://#i', $origin)) { $origin = $scheme.'://'.$origin; } $links[] = $origin.$path; } return array_values(array_unique($links)); } public static function randomChannelId(): string { return bin2hex(random_bytes(16)); } public static function maxPerAgent(): int { $n = (int) config('coruna.channels.max_per_agent', 5); return max(1, $n); } }