mirror of
https://github.com/fastapiadmin/FastapiAdmin.git
synced 2026-09-24 13:37:13 +00:00
- 添加日语、中文、泰语等多语言支持文件 - 更新静态资源文件包括图片和样式表 - 重构菜单权限树组件,修复父子节点联动问题 - 优化在线用户管理功能,使用会话ID替代用户名 - 更新数据库配置,默认使用MySQL - 重构文档系统,将mkdocs迁移至backend目录 - 修复Redis哈希操作接口 - 更新前端工具函数,优化列表转树形结构逻辑 - 调整端口配置和环境变量 - 添加开发运维文档和部署脚本 本次提交主要实现了多语言支持、资源文件更新和多个功能优化,同时改进了系统文档结构和部署配置。
66 lines
2.1 KiB
Python
66 lines
2.1 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
import re
|
|
import httpx
|
|
|
|
from app.core.logger import logger
|
|
|
|
|
|
class IpLocalUtil:
|
|
"""
|
|
获取IP归属地工具类
|
|
"""
|
|
|
|
@classmethod
|
|
def is_valid_ip(cls, ip: str) -> bool:
|
|
"""
|
|
校验IP格式是否合法
|
|
|
|
:param ip: IP地址
|
|
:return: 是否合法
|
|
"""
|
|
ip_pattern = r'^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'
|
|
return bool(re.match(ip_pattern, ip))
|
|
|
|
@classmethod
|
|
async def get_ip_location(cls, ip: str) -> str:
|
|
"""
|
|
获取IP归属地信息
|
|
|
|
:param ip: IP地址
|
|
:return: IP归属地信息
|
|
"""
|
|
# 校验IP格式
|
|
if not cls.is_valid_ip(ip):
|
|
logger.error(f"IP格式不合法: {ip}")
|
|
return "未知"
|
|
|
|
# 内网IP直接返回
|
|
if ip == '127.0.0.1' or ip == 'localhost':
|
|
return '内网IP'
|
|
|
|
try:
|
|
# 百度API失败,使用其他API
|
|
# async with httpx.AsyncClient() as client:
|
|
# response = await client.get(
|
|
# f'https://qifu-api.baidubce.com/ip/geo/v1/district?ip={ip}',
|
|
# timeout=5
|
|
# )
|
|
# if response.status_code == 200:
|
|
# data = response.json().get('data', {})
|
|
# return f"【{data.get('owner','')}】-{data.get('country','')}-{data.get('prov','')}-{data.get('city','')}-{data.get('district','')}"
|
|
|
|
# 使用ip-api.com API获取IP归属地信息
|
|
async with httpx.AsyncClient() as client:
|
|
response = await client.get(
|
|
f'http://ip-api.com/json/{ip}?lang=zh-CN',
|
|
timeout=10
|
|
)
|
|
if response.status_code == 200:
|
|
result = response.json()
|
|
return f"{result.get('country','')}-{result.get('regionName','')}-{result.get('city','')}"
|
|
|
|
except Exception as e:
|
|
logger.error(f"获取IP归属地失败: {e}")
|
|
return "未知"
|