'float', 'traffic_rate_front' => 'float', 'node_heartbeat' => 'int', ]; public function getMemoFrontAttribute($sValue) { $sMemoFront = $sValue ?? "普通节点"; return $sMemoFront; } public function getDuckClassAttribute(): string { $sLocation = $this->duck_group ?: ($this->duck_code ?? ''); $sBeforeDash = strstr($sLocation, '-', true) ?: $sLocation; return preg_replace('/\d+/', '', $sBeforeDash); } /** * 节点状态颜色 */ public function getColorAttribute(): string { return match ($this->getNodeOnlineStatus()) { 0 => 'orange', 1 => 'green', default => 'red', }; } public function getConnectionTypeAttribute(): int { // 0 = IPv4, 1 = IPv6, 2 = DualStack return $this->ipv6 !== '::1' && $this->ipv4 !== '127.0.0.1' ? 2 : ($this->ipv4 !== '127.0.0.1' ? 0 : 1); } /** * 节点是否显示和隐藏 */ public function type(): string { return $this->type ? '显示' : '隐藏'; } /** * 节点类型 */ public function sort(): string { return match ($this->sort) { 0 => 'Shadowsocks', 1 => 'Shadowsocks2022', 2 => 'TUIC', 3 => 'WireGuard', 11 => 'Vmess', 14 => 'Trojan', default => '未知', }; } public function isDynamicRate(): string { return $this->is_dynamic_rate ? '是' : '否'; } public function dynamicRateType(): string { return match ($this->dynamic_rate_type) { 0 => 'Logistic', 1 => 'Linear', default => '未知', }; } /** * 获取节点在线状态 * * @return int 0 = new node, -1 = offline, 1 = online */ public function getNodeOnlineStatus(): int { return $this->node_heartbeat === 0 ? 0 : ($this->node_heartbeat + 600 > time() ? 1 : -1); } /** * 更新节点 IP */ public function updateNodeIp(): void { if (Tools::isIPv4($this->server)) { $this->ipv4 = $this->server; $this->ipv6 = '::1'; } elseif (Tools::isIPv6($this->server)) { $this->ipv4 = '127.0.0.1'; $this->ipv6 = $this->server; } else { try { $result = dns_get_record($this->server, DNS_A + DNS_AAAA); $this->ipv4 = $result[0]['ip'] ?? '127.0.0.1'; $this->ipv6 = $result[1]['ipv6'] ?? '::1'; } catch (Exception $e) { $this->ipv4 = '127.0.0.1'; $this->ipv6 = '::1'; } } } // 计算距离重置日 // public function getResetDayLimitAttribute() // { // if (!$this->bandwidthlimit_resetday) { // return false; // } // // $iDayNow = (int) date("d"); // return (int) $this->bandwidthlimit_resetday - $iDayNow; // } public function getResetDayLimitAttribute() { if (!$this->bandwidthlimit_resetday) { return false; } $iResetDay = (int) $this->bandwidthlimit_resetday; $oNow = Carbon::now(); // 创建目标日期:设定为本月的重置日 // 如果重置日超过了当月最大天数(如重置日31号,当前月2月),Carbon会自动处理 $oTargetDate = $oNow->copy()->day($iResetDay); // 如果目标日期已经在今天之前,说明重置日在下个月 if ($oTargetDate->isPast()) { $oTargetDate->addMonth(); } // 返回相差天数 return $oNow->diffInDays($oTargetDate); } }