Feat: 切换 IP 归属地解析引擎至本地离线库 MaxMind GeoLite2 并开启原生中文支持

This commit is contained in:
2026-02-27 12:00:20 +08:00
parent 63f7cfbb25
commit 006da4f5d6
4 changed files with 148 additions and 56 deletions

View File

@@ -74,12 +74,9 @@ class UserController extends Controller
try {
$position = Location::get($ipToLookup);
if ($position) {
$region = $this->translateLocation($position->regionName ?? '');
$city = $this->translateLocation($position->cityName ?? '');
$data['location'] = ($position->countryName === 'China' || $position->countryName === 'Local') ?
trim($region . ' ' . ($region === $city ? '' : $city)) :
$this->translateLocation($position->countryName ?? '');
$data['location'] = ($position->countryName === '中国' || $position->countryName === 'Local') ?
trim(($position->regionName ?? '') . ' ' . ($position->cityName ?? '')) :
($position->countryName ?? '未知区域');
if (empty($data['location'])) {
$data['location'] = '未知区域';
@@ -327,53 +324,4 @@ class UserController extends Controller
return response()->json(['status' => 'success', 'message' => "用户 {$username} 已被封号并封IP{$ipInfo}"]);
}
/**
* 将英文省市名称简单翻译为中文
*/
private function translateLocation(string $name): string
{
if (empty($name)) return '';
$map = [
'China' => '中国',
'Beijing' => '北京',
'Shanghai' => '上海',
'Tianjin' => '天津',
'Chongqing' => '重庆',
'Hebei' => '河北',
'Shanxi' => '山西',
'Liaoning' => '辽宁',
'Jilin' => '吉林',
'Heilongjiang' => '黑龙江',
'Jiangsu' => '江苏',
'Zhejiang' => '浙江',
'Anhui' => '安徽',
'Fujian' => '福建',
'Jiangxi' => '江西',
'Shandong' => '山东',
'Henan' => '河南',
'Hubei' => '湖北',
'Hunan' => '湖南',
'Guangdong' => '广东',
'Hainan' => '海南',
'Sichuan' => '四川',
'Guizhou' => '贵州',
'Yunnan' => '云南',
'Shaanxi' => '陕西',
'Gansu' => '甘肃',
'Qinghai' => '青海',
'Taiwan' => '台湾',
'Inner Mongolia' => '内蒙古',
'Guangxi' => '广西',
'Tibet' => '西藏',
'Ningxia' => '宁夏',
'Xinjiang' => '新疆',
'Hong Kong' => '香港',
'Macau' => '澳门',
'Local' => '本地局域网',
];
return $map[$name] ?? $name;
}
}

View File

@@ -10,6 +10,7 @@
"license": "MIT",
"require": {
"php": "^8.2",
"geoip2/geoip2": "^3.3",
"laravel/framework": "^12.0",
"laravel/horizon": "^5.45",
"laravel/reverb": "^1.8",

2
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "7c4fa193c06a7d429a4d8a423d2926d4",
"content-hash": "9ce82fd8935af3aa9c257758c8640c53",
"packages": [
{
"name": "brick/math",

143
config/location.php Normal file
View File

@@ -0,0 +1,143 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Driver
|--------------------------------------------------------------------------
|
| The default driver you would like to use for location retrieval.
|
*/
'driver' => Stevebauman\Location\Drivers\MaxMind::class,
/*
|--------------------------------------------------------------------------
| Driver Fallbacks
|--------------------------------------------------------------------------
|
| The drivers you want to use to retrieve the user's location
| if the above selected driver is unavailable.
|
| These will be called upon in order (first to last).
|
*/
'fallbacks' => [
Stevebauman\Location\Drivers\IpApi::class,
Stevebauman\Location\Drivers\Ip2locationio::class,
Stevebauman\Location\Drivers\IpInfo::class,
Stevebauman\Location\Drivers\GeoPlugin::class,
],
/*
|--------------------------------------------------------------------------
| Position
|--------------------------------------------------------------------------
|
| Here you may configure the position instance that is created
| and returned from the above drivers. The instance you
| create must extend the built-in Position class.
|
*/
'position' => Stevebauman\Location\Position::class,
/*
|--------------------------------------------------------------------------
| HTTP Client Options
|--------------------------------------------------------------------------
|
| Here you may configure the options used by the underlying
| Laravel HTTP client. This will be used in drivers that
| request info via HTTP requests through API services.
|
*/
'http' => [
'timeout' => 3,
'connect_timeout' => 3,
],
/*
|--------------------------------------------------------------------------
| Localhost Testing
|--------------------------------------------------------------------------
|
| If your running your website locally and want to test different
| IP addresses to see location detection, set 'enabled' to true.
|
| The testing IP address is a Google host in the United-States.
|
*/
'testing' => [
'ip' => '66.102.0.0',
'enabled' => env('LOCATION_TESTING', true),
],
/*
|--------------------------------------------------------------------------
| MaxMind Configuration
|--------------------------------------------------------------------------
|
| If web service is enabled, you must fill in your user ID and license key.
|
| If web service is disabled, it will try and retrieve the user's location
| from the MaxMind database file located in the local path below.
|
| The MaxMind database file can be either City (default) or Country (smaller).
|
*/
'maxmind' => [
'license_key' => env('MAXMIND_LICENSE_KEY'),
'web' => [
'enabled' => false,
'user_id' => env('MAXMIND_USER_ID'),
'locales' => ['zh-CN', 'en'],
'options' => ['host' => 'geoip.maxmind.com'],
],
'local' => [
'type' => 'city',
'path' => database_path('maxmind/GeoLite2-City.mmdb'),
'url' => sprintf('https://download.maxmind.com/app/geoip_download_by_token?edition_id=GeoLite2-City&license_key=%s&suffix=tar.gz', env('MAXMIND_LICENSE_KEY')),
],
],
'ip_api' => [
'token' => env('IP_API_TOKEN'),
],
'ipinfo' => [
'token' => env('IPINFO_TOKEN'),
],
'ipdata' => [
'token' => env('IPDATA_TOKEN'),
],
'ip2locationio' => [
'token' => env('IP2LOCATIONIO_TOKEN'),
],
/*
|--------------------------------------------------------------------------
| Kloudend ~ ipapi.co Configuration
|--------------------------------------------------------------------------
|
| The configuration for the Kloudend driver.
|
*/
'kloudend' => [
'token' => env('KLOUDEND_TOKEN'),
],
];