User.php 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. <?php
  2. namespace App\Models;
  3. use Hash;
  4. use Illuminate\Database\Eloquent\Relations\BelongsTo;
  5. use Illuminate\Database\Eloquent\Relations\HasMany;
  6. use Illuminate\Database\Eloquent\Relations\HasManyThrough;
  7. use Illuminate\Database\Eloquent\Relations\HasOne;
  8. use Illuminate\Foundation\Auth\User as Authenticatable;
  9. use Illuminate\Notifications\Notifiable;
  10. use Kyslik\ColumnSortable\Sortable;
  11. use Spatie\Permission\Traits\HasRoles;
  12. use Tymon\JWTAuth\Contracts\JWTSubject;
  13. /**
  14. * 用户信息.
  15. */
  16. class User extends Authenticatable implements JWTSubject
  17. {
  18. use Notifiable, HasRoles, Sortable;
  19. public $sortable = ['id', 'credit', 'port', 't', 'expired_at'];
  20. protected $table = 'user';
  21. protected $casts = ['expired_at' => 'date:Y-m-d', 'reset_time' => 'date:Y-m-d', 'ban_time' => 'date:Y-m-d'];
  22. protected $dates = ['expired_at', 'reset_time'];
  23. protected $guarded = [];
  24. public function routeNotificationForMail($notification)
  25. {
  26. return $this->username;
  27. }
  28. public function usedTrafficPercentage()
  29. {
  30. return round(($this->used_traffic) / $this->transfer_enable, 2);
  31. }
  32. public function getUsedTrafficAttribute(): int
  33. {
  34. return $this->d + $this->u;
  35. }
  36. public function getTelegramUserIdAttribute()
  37. {
  38. $telegram = $this->userAuths()->whereType('telegram')->first();
  39. return $telegram->identifier ?? null;
  40. }
  41. public function userAuths(): HasMany
  42. {
  43. return $this->hasMany(UserOauth::class);
  44. }
  45. public function profile()
  46. {
  47. return [
  48. 'id' => $this->id,
  49. 'nickname' => $this->nickname,
  50. 'account' => $this->username,
  51. 'port' => $this->port,
  52. 'passwd' => $this->passwd,
  53. 'uuid' => $this->vmess_id,
  54. 'transfer_enable' => $this->transfer_enable,
  55. 'u' => $this->u,
  56. 'd' => $this->d,
  57. 't' => $this->t,
  58. 'enable' => $this->enable,
  59. 'speed_limit' => $this->speed_limit,
  60. 'credit' => $this->credit,
  61. 'expired_at' => $this->expired_at,
  62. 'ban_time' => $this->ban_time,
  63. 'level' => $this->level_name,
  64. 'group' => $this->userGroup->name ?? null,
  65. 'last_login' => $this->last_login,
  66. 'reset_time' => $this->reset_time,
  67. 'invite_num' => $this->invite_num,
  68. 'status' => $this->status,
  69. ];
  70. }
  71. public function onlineIpLogs(): HasMany
  72. {
  73. return $this->hasMany(NodeOnlineIp::class);
  74. }
  75. public function payments(): HasMany
  76. {
  77. return $this->hasMany(Payment::class);
  78. }
  79. public function commissionSettlements(): HasMany
  80. {
  81. return $this->hasMany(ReferralApply::class);
  82. }
  83. public function commissionLogs(): HasMany
  84. {
  85. return $this->hasMany(ReferralLog::class, 'inviter_id');
  86. }
  87. public function ruleLogs(): HasMany
  88. {
  89. return $this->hasMany(RuleLog::class);
  90. }
  91. public function tickets(): HasMany
  92. {
  93. return $this->hasMany(Ticket::class);
  94. }
  95. public function ticketReplies(): HasMany
  96. {
  97. return $this->hasMany(TicketReply::class);
  98. }
  99. public function banedLogs(): HasMany
  100. {
  101. return $this->hasMany(UserBanedLog::class);
  102. }
  103. public function creditLogs(): HasMany
  104. {
  105. return $this->hasMany(UserCreditLog::class);
  106. }
  107. public function dailyDataFlows(): HasMany
  108. {
  109. return $this->hasMany(UserDailyDataFlow::class);
  110. }
  111. public function dataFlowLogs(): HasMany
  112. {
  113. return $this->hasMany(UserDataFlowLog::class);
  114. }
  115. public function dataModifyLogs(): HasMany
  116. {
  117. return $this->hasMany(UserDataModifyLog::class);
  118. }
  119. public function hourlyDataFlows(): HasMany
  120. {
  121. return $this->HasMany(UserHourlyDataFlow::class);
  122. }
  123. public function loginLogs(): HasMany
  124. {
  125. return $this->HasMany(UserLoginLog::class);
  126. }
  127. public function subscribe(): HasOne
  128. {
  129. return $this->hasOne(UserSubscribe::class);
  130. }
  131. public function subUrl()
  132. {
  133. return route('sub', $this->subscribe->code);
  134. }
  135. public function subscribeLogs(): HasManyThrough
  136. {
  137. return $this->hasManyThrough(UserSubscribeLog::class, UserSubscribe::class);
  138. }
  139. public function verify(): HasMany
  140. {
  141. return $this->hasMany(Verify::class);
  142. }
  143. public function inviter(): BelongsTo
  144. {
  145. return $this->belongsTo(__CLASS__);
  146. }
  147. public function invites(): HasMany
  148. {
  149. return $this->hasMany(Invite::class, 'inviter_id');
  150. }
  151. public function invitees(): HasMany
  152. {
  153. return $this->hasMany(__CLASS__, 'inviter_id');
  154. }
  155. public function getLevelNameAttribute(): string
  156. {
  157. return Level::whereLevel($this->attributes['level'])->first()->name;
  158. }
  159. public function getCreditAttribute()
  160. {
  161. return $this->attributes['credit'] / 100;
  162. }
  163. public function getTransferEnableFormattedAttribute()
  164. {
  165. return flowAutoShow($this->attributes['transfer_enable']);
  166. }
  167. public function getSpeedLimitAttribute()
  168. {
  169. return $this->attributes['speed_limit'] / Mbps;
  170. }
  171. public function getExpiredAtAttribute()
  172. {
  173. return $this->attributes['expired_at'];
  174. }
  175. public function getResetTimeAttribute()
  176. {
  177. return $this->attributes['reset_time'];
  178. }
  179. public function setPasswordAttribute($password)
  180. {
  181. return $this->attributes['password'] = Hash::make($password);
  182. }
  183. public function setCreditAttribute($value)
  184. {
  185. return $this->attributes['credit'] = $value * 100;
  186. }
  187. public function setSpeedLimitAttribute($value)
  188. {
  189. return $this->attributes['speed_limit'] = $value * Mbps;
  190. }
  191. public function scopeActiveUser($query)
  192. {
  193. return $query->where('status', '<>', -1)->whereEnable(1);
  194. }
  195. public function scopeBannedUser($query)
  196. {
  197. return $query->where('status', '>=', 0)->whereEnable(0);
  198. }
  199. public function nodes()
  200. {
  201. if ($this->attributes['user_group_id']) {
  202. $query = $this->userGroup->nodes();
  203. } else {
  204. $query = Node::query();
  205. }
  206. return $query->whereStatus(1)->where('level', '<=', $this->attributes['level'] ?? 0);
  207. }
  208. public function userGroup(): BelongsTo
  209. {
  210. return $this->belongsTo(UserGroup::class);
  211. }
  212. public function getIsAvailableAttribute(): bool
  213. {
  214. return ! $this->ban_time && $this->transfer_enable && $this->expired_at > time();
  215. }
  216. public function updateCredit(float $credit): bool
  217. {
  218. $this->credit += $credit;
  219. return $this->credit >= 0 && $this->save();
  220. }
  221. public function incrementData(int $data): bool
  222. { // 添加用户流量
  223. $this->transfer_enable += $data;
  224. return $this->save();
  225. }
  226. public function isNotCompleteOrderByUserId(int $userId): bool
  227. { // 添加用户余额
  228. return Order::uid($userId)->whereIn('status', [0, 1])->exists();
  229. }
  230. public function trafficFetch(int $u, int $d): bool
  231. {
  232. $this->u += $u;
  233. $this->d += $d;
  234. return $this->save();
  235. }
  236. public function expired_status(): int
  237. {
  238. $expired_status = 2; // 大于一个月过期
  239. if ($this->expired_at < date('Y-m-d')) {
  240. $expired_status = -1; // 已过期
  241. } elseif ($this->expired_at === date('Y-m-d')) {
  242. $expired_status = 0; // 今天过期
  243. } elseif ($this->expired_at > date('Y-m-d') && $this->expired_at <= date('Y-m-d', strtotime('30 days'))) {
  244. $expired_status = 1; // 最近一个月过期
  245. }
  246. return $expired_status;
  247. }
  248. public function isTrafficWarning(): bool
  249. { // 流量异常警告
  250. return $this->recentTrafficUsed() >= (sysConfig('traffic_ban_value') * GB);
  251. }
  252. public function recentTrafficUsed()
  253. {
  254. return UserHourlyDataFlow::userRecentUsed($this->id)->sum('total');
  255. }
  256. public function activePayingUser()
  257. { //付费用户判断
  258. return $this->orders()->active()->where('origin_amount', '>', 0)->exists();
  259. }
  260. public function orders(): HasMany
  261. {
  262. return $this->hasMany(Order::class);
  263. }
  264. public function getJWTIdentifier()
  265. {
  266. return $this->getKey();
  267. }
  268. public function getJWTCustomClaims()
  269. {
  270. return [];
  271. }
  272. public function routeNotificationForTelegram()
  273. {
  274. return $this->telegram_user_id;
  275. }
  276. }