| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- <?php
- namespace App\Models;
- use App\Helpers\LoginClientInfo;
- use Carbon\Carbon;
- class UserLogin extends BaseModel
- {
- protected $table = 'user_login';
- protected $fillable = [
- 'user_id',
- 'login_ip',
- 'country',
- 'browser',
- 'os',
- 'status',
- 'logout_time',
- 'online_duration',
- 'user_agent',
- ];
- // 登录日志需要展示创建时间(登录时间)
- protected $hidden = [];
- protected $appends = ['status_text'];
- public const STATUS_FAIL = 0;
- public const STATUS_SUCCESS = 1;
- /**
- * 写入登录日志
- *
- * @param string|int $userId 用户ID(member_id / user_id)
- * @param int $status 1成功 0失败
- * @param string|null $loginIp
- * @param string|null $userAgent
- */
- public static function addData($userId, int $status = self::STATUS_SUCCESS, ?string $loginIp = null, ?string $userAgent = null): self
- {
- $info = LoginClientInfo::fromRequest($loginIp, $userAgent);
- return self::create([
- 'user_id' => (string)$userId,
- 'login_ip' => $info['login_ip'],
- 'country' => $info['country'],
- 'browser' => $info['browser'],
- 'os' => $info['os'],
- 'status' => $status,
- 'logout_time' => null,
- 'online_duration' => null,
- 'user_agent' => $info['user_agent'],
- ]);
- }
- /**
- * 标记登出:更新最近一条未登出的成功登录记录
- */
- public static function markLogout($userId): void
- {
- $log = self::where('user_id', (string)$userId)
- ->where('status', self::STATUS_SUCCESS)
- ->whereNull('logout_time')
- ->orderByDesc('id')
- ->first();
- if (!$log) {
- return;
- }
- $logoutAt = Carbon::now('Asia/Shanghai');
- $loginAt = Carbon::parse($log->getRawOriginal('created_at') ?? $log->created_at)
- ->setTimezone('Asia/Shanghai');
- $seconds = max(0, $logoutAt->getTimestamp() - $loginAt->getTimestamp());
- $minutes = (int)ceil($seconds / 60);
- $log->logout_time = $logoutAt->format('Y-m-d H:i:s');
- $log->online_duration = $minutes;
- $log->save();
- }
- public function getStatusTextAttribute(): string
- {
- $status = (int)($this->attributes['status'] ?? self::STATUS_SUCCESS);
- return $status === self::STATUS_SUCCESS ? '登录成功' : '登录失败';
- }
- public function getLogoutTimeAttribute($value): ?string
- {
- if (empty($value) || $value === '0000-00-00 00:00:00') {
- return null;
- }
- return Carbon::parse($value)->setTimezone('Asia/Shanghai')->format('Y-m-d H:i:s');
- }
- // 获取用户未登录天数(最后第二次未登录的天数)
- public static function getNotLoginDays($memberId)
- {
- $list = self::where('user_id', $memberId)
- ->where('status', self::STATUS_SUCCESS)
- ->orderByDesc('id')
- ->limit(2)
- ->get()
- ->toArray();
- if (count($list) < 2) {
- return 0;
- }
- if (date('Y-m-d', strtotime($list[0]['created_at'])) != date('Y-m-d')) {
- return 0;
- }
- $diff = strtotime($list[0]['created_at']) - strtotime($list[1]['created_at']);
- $days = ceil($diff / 86400);
- return abs($days);
- }
- }
|