User.php 8.6 KB

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