<?php namespace App\Models; use Hash; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\HasManyThrough; use Illuminate\Database\Eloquent\Relations\HasOne; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use Spatie\Permission\Traits\HasRoles; use Tymon\JWTAuth\Contracts\JWTSubject; /** * 用户信息. */ class User extends Authenticatable implements JWTSubject { use Notifiable, HasRoles; protected $table = 'user'; //protected $casts = ['expired_at' => 'date:Y-m-d', 'reset_time' => 'date:Y-m-d', 'ban_time' => 'date:Y-m-d']; protected $dates = ['expired_at', 'reset_time']; protected $guarded = []; public function usedTrafficPercentage() { return round(($this->usedTraffic()) / $this->transfer_enable, 2); } public function usedTraffic(): int { return $this->d + $this->u; } public function profile() { $totalTransfer = $this->transfer_enable; $usedTransfer = $this->usedTraffic(); $unusedTraffic = $totalTransfer - $usedTransfer > 0 ? $totalTransfer - $usedTransfer : 0; $expireTime = $this->expired_at; return [ 'id' => $this->id, 'nickname' => $this->username, 'account' => $this->email, 'port' => $this->port, 'passwd' => $this->passwd, 'uuid' => $this->vmess_id, 'transfer_enable' => $this->transfer_enable, 'unusedTraffic' => flowAutoShow($unusedTraffic), 'u' => $this->u, 'd' => $this->d, 't' => $this->t, 'enable' => $this->enable, 'speed_limit' => $this->speed_limit, 'credit' => $this->credit, 'expired_at' => $this->expired_at, 'ban_time' => $this->ban_time, 'level' => $this->level_name, 'group' => $this->userGroup->name ?? null, 'last_login' => $this->last_login, 'reset_time' => $this->reset_time, 'invite_num' => $this->invite_num, 'user_group_id'=> $this->user_group_id, 'status' => $this->status, 'code' => $this->subscribe->code, ]; } public function onlineIpLogs(): HasMany { return $this->hasMany(NodeOnlineIp::class); } public function payments(): HasMany { return $this->hasMany(Payment::class); } public function commissionSettlements(): HasMany { return $this->hasMany(ReferralApply::class); } public function commissionLogs(): HasMany { return $this->hasMany(ReferralLog::class, 'inviter_id'); } public function ruleLogs(): HasMany { return $this->hasMany(RuleLog::class); } public function tickets(): HasMany { return $this->hasMany(Ticket::class); } public function ticketReplies(): HasMany { return $this->hasMany(TicketReply::class); } public function banedLogs(): HasMany { return $this->hasMany(UserBanedLog::class); } public function creditLogs(): HasMany { return $this->hasMany(UserCreditLog::class); } public function dailyDataFlows(): HasMany { return $this->hasMany(UserDailyDataFlow::class); } public function dataFlowLogs(): HasMany { return $this->hasMany(UserDataFlowLog::class); } public function dataModifyLogs(): HasMany { return $this->hasMany(UserDataModifyLog::class); } public function hourlyDataFlows(): HasMany { return $this->HasMany(UserHourlyDataFlow::class); } public function loginLogs(): HasMany { return $this->HasMany(UserLoginLog::class); } public function subscribe(): HasOne { return $this->hasOne(UserSubscribe::class); } public function subUrl() { return route('sub', $this->subscribe->code); } public function subscribeLogs(): HasManyThrough { return $this->hasManyThrough(UserSubscribeLog::class, UserSubscribe::class); } public function verify(): HasMany { return $this->hasMany(Verify::class); } public function inviter(): BelongsTo { return $this->belongsTo(__CLASS__); } public function invites(): HasMany { return $this->hasMany(Invite::class, 'inviter_id'); } public function invitees(): HasMany { return $this->hasMany(__CLASS__, 'inviter_id'); } public function getLevelNameAttribute(): string { return Level::whereLevel($this->attributes['level'])->first()->name; } public function getCreditAttribute() { return $this->attributes['credit'] / 100; } public function getTransferEnableFormattedAttribute() { return flowAutoShow($this->attributes['transfer_enable']); } public function getSpeedLimitAttribute() { return $this->attributes['speed_limit'] / Mbps; } public function getExpiredAtAttribute() { return $this->attributes['expired_at']; } public function getResetTimeAttribute() { return $this->attributes['reset_time']; } public function setPasswordAttribute($password) { return $this->attributes['password'] = Hash::make($password); } public function setCreditAttribute($value) { return $this->attributes['credit'] = $value * 100; } public function setSpeedLimitAttribute($value) { return $this->attributes['speed_limit'] = $value * Mbps; } public function scopeActiveUser($query) { return $query->where('status', '<>', -1)->whereEnable(1); } public function nodes() { if (!empty($this->attributes['user_group_id']) || $this->attributes['user_group_id']) { $query = $this->userGroup->nodes(); } else { $query = Node::query(); } return $query->whereStatus(1)->where('level', '<=', $this->attributes['level'] ?? 0); } public function userGroup(): BelongsTo { return $this->belongsTo(UserGroup::class); } public function getIsAvailableAttribute(): bool { return ! $this->ban_time && $this->transfer_enable && $this->expired_at > time(); } public function updateCredit(float $credit): bool { $this->credit += $credit; return $this->credit >= 0 && $this->save(); } public function incrementData(int $data): bool {// 添加用户流量 $this->transfer_enable += $data; return $this->save(); } public function isNotCompleteOrderByUserId(int $userId): bool { // 添加用户余额 return Order::uid($userId)->whereIn('status', [0, 1])->exists(); } public function trafficFetch(int $u, int $d): bool { $this->u += $u; $this->d += $d; return $this->save(); } public function expired_status(): int { $expired_status = 2; // 大于一个月过期 if ($this->expired_at < date('Y-m-d H:i:s')) { $expired_status = -1; // 已过期 } elseif ($this->expired_at === date('Y-m-d H:i:s')) { $expired_status = 0; // 今天过期 } elseif ($this->expired_at > date('Y-m-d H:i:s') && $this->expired_at <= date('Y-m-d H:i:s', strtotime('+30 days'))) { $expired_status = 1; // 最近一个月过期 } return $expired_status; } public function isTrafficWarning(): bool {// 流量异常警告 return $this->recentTrafficUsed() >= (sysConfig('traffic_ban_value') * GB); } public function recentTrafficUsed() { return UserHourlyDataFlow::userRecentUsed($this->id)->sum('total'); } public function activePayingUser() { //付费用户判断 return $this->orders()->active()->where('origin_amount', '>', 0)->exists(); } public function orders(): HasMany { return $this->hasMany(Order::class); } public function getJWTIdentifier() { return $this->getKey(); } public function getJWTCustomClaims() { return []; } }