58 lines
1.9 KiB
PHP
58 lines
1.9 KiB
PHP
<?php
|
|
|
|
namespace App\Service\common;
|
|
|
|
use App\BaseApp\BaseNotAuthService;
|
|
|
|
/**
|
|
* User-Agent 解析:登录日志 / 操作日志共用
|
|
*/
|
|
class UserAgentService extends BaseNotAuthService
|
|
{
|
|
/**
|
|
* 从 UA 推断操作系统名称
|
|
* 为什么允许空参:中间件/登录处直接取当前请求头,避免到处传 UA
|
|
*
|
|
* @param string|null $ua 为空时取当前请求 User-Agent
|
|
*/
|
|
public function parseEquipment(?string $ua = null): string
|
|
{
|
|
$ua = $ua ?? (string) request()->header('User-Agent', '');
|
|
if ($ua === '') {
|
|
return '未知';
|
|
}
|
|
return match (true) {
|
|
str_contains($ua, 'Windows NT 10') => 'Windows 10/11',
|
|
str_contains($ua, 'Windows') => 'Windows',
|
|
str_contains($ua, 'Macintosh') || str_contains($ua, 'Mac OS') => 'macOS',
|
|
str_contains($ua, 'Android') => 'Android',
|
|
str_contains($ua, 'iPhone') || str_contains($ua, 'iPad') => 'iOS',
|
|
str_contains($ua, 'Linux') => 'Linux',
|
|
default => '其他',
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 从 UA 推断浏览器名称
|
|
* Edge 需先于 Chrome 匹配,避免被 Chrome/ 抢先
|
|
*
|
|
* @param string|null $ua 为空时取当前请求 User-Agent
|
|
*/
|
|
public function parseBrowser(?string $ua = null): string
|
|
{
|
|
$ua = $ua ?? (string) request()->header('User-Agent', '');
|
|
if ($ua === '') {
|
|
return '未知';
|
|
}
|
|
return match (true) {
|
|
str_contains($ua, 'Edg/') => 'Edge',
|
|
str_contains($ua, 'OPR/') || str_contains($ua, 'Opera') => 'Opera',
|
|
str_contains($ua, 'Chrome/') && !str_contains($ua, 'Edg/') => 'Chrome',
|
|
str_contains($ua, 'Firefox/') => 'Firefox',
|
|
str_contains($ua, 'Safari/') && !str_contains($ua, 'Chrome/') => 'Safari',
|
|
str_contains($ua, 'MSIE') || str_contains($ua, 'Trident/') => 'IE',
|
|
default => '其他',
|
|
};
|
|
}
|
|
}
|