erp-backend/app/Models/UserDevice.php
2026-04-01 17:07:04 +08:00

155 lines
3.6 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class UserDevice extends Model
{
use HasFactory;
protected $fillable = [
'user_id',
'device_hash',
'device_name',
'device_type',
'os',
'browser',
'ip',
'location',
'first_login_at',
'last_login_at',
'is_trusted',
'trusted_at',
];
protected $casts = [
'is_trusted' => 'boolean',
'first_login_at' => 'datetime',
'last_login_at' => 'datetime',
'trusted_at' => 'datetime',
];
/**
* 用户关联
*/
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
/**
* 判断是否授信
*/
public function isTrusted(): bool
{
return $this->is_trusted;
}
/**
* 授信
*/
public function trust(): void
{
$this->update([
'is_trusted' => true,
'trusted_at' => now(),
]);
}
/**
* 取消授信
*/
public function revoke(): void
{
$this->update([
'is_trusted' => false,
'trusted_at' => null,
]);
}
/**
* 更新登录信息
*/
public function recordLogin(): void
{
if (!$this->first_login_at) {
$this->update(['first_login_at' => now()]);
}
$this->update(['last_login_at' => now()]);
}
/**
* 通过设备哈希查找
*/
public static function findByHash(int $userId, string $hash): ?self
{
return static::where('user_id', $userId)
->where('device_hash', $hash)
->first();
}
/**
* 生成设备哈希
*/
public static function generateHash(string $userAgent, string $ip): string
{
return hash('sha256', $userAgent . $ip . config('app.key'));
}
/**
* 解析设备信息
*/
public static function parseDeviceInfo(string $userAgent): array
{
$deviceType = 'desktop';
$os = 'Unknown';
$browser = 'Unknown';
// 检测设备类型
if (preg_match('/mobile|android|iphone|ipad|ipod/i', $userAgent)) {
if (preg_match('/ipad/i', $userAgent)) {
$deviceType = 'tablet';
} else {
$deviceType = 'mobile';
}
}
// 检测操作系统
if (preg_match('/windows nt 10/i', $userAgent)) {
$os = 'Windows 10';
} elseif (preg_match('/windows nt 6.3/i', $userAgent)) {
$os = 'Windows 8.1';
} elseif (preg_match('/mac os x/i', $userAgent)) {
$os = 'macOS';
} elseif (preg_match('/linux/i', $userAgent)) {
$os = 'Linux';
} elseif (preg_match('/android/i', $userAgent)) {
$os = 'Android';
} elseif (preg_match('/iphone|ipad|ipod/i', $userAgent)) {
$os = 'iOS';
}
// 检测浏览器
if (preg_match('/edg/i', $userAgent)) {
$browser = 'Edge';
} elseif (preg_match('/chrome/i', $userAgent)) {
$browser = 'Chrome';
} elseif (preg_match('/firefox/i', $userAgent)) {
$browser = 'Firefox';
} elseif (preg_match('/safari/i', $userAgent)) {
$browser = 'Safari';
} elseif (preg_match('/ie|trident/i', $userAgent)) {
$browser = 'IE';
}
return [
'device_type' => $deviceType,
'os' => $os,
'browser' => $browser,
];
}
}