9 changed files with 908 additions and 242 deletions
@ -0,0 +1,145 @@ |
|||||
|
""" |
||||
|
系统管理API端点 |
||||
|
""" |
||||
|
from fastapi import APIRouter, HTTPException, status |
||||
|
from app.services.system_service import SystemService |
||||
|
from app.schemas.system import MachineCodeResponse, SystemInfoResponse |
||||
|
from app.utils.api_decorators import handle_api_errors |
||||
|
from app.utils.structured_log import get_structured_logger |
||||
|
|
||||
|
logger = get_structured_logger(__name__) |
||||
|
|
||||
|
router = APIRouter() |
||||
|
|
||||
|
# 创建全局system_service实例 |
||||
|
system_service = SystemService() |
||||
|
|
||||
|
@router.get("/system/machine-code", |
||||
|
summary="获取机器码", |
||||
|
description="获取当前系统的机器码,支持Windows和Linux系统", |
||||
|
response_model=MachineCodeResponse) |
||||
|
@handle_api_errors |
||||
|
async def get_machine_code(): |
||||
|
"""获取机器码 |
||||
|
|
||||
|
Windows: 使用 wmic csproduct get uuid 命令 |
||||
|
Linux: 使用 dmidecode -s system-serial-number 或读取系统文件 |
||||
|
""" |
||||
|
try: |
||||
|
logger.info("API调用: 获取机器码") |
||||
|
result = await system_service.get_machine_code() |
||||
|
|
||||
|
if result["success"]: |
||||
|
logger.info("机器码获取成功") |
||||
|
return result |
||||
|
else: |
||||
|
logger.warning("机器码获取失败") |
||||
|
raise HTTPException( |
||||
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, |
||||
|
detail=result["message"] |
||||
|
) |
||||
|
|
||||
|
except HTTPException: |
||||
|
raise |
||||
|
except Exception as e: |
||||
|
logger.error(f"获取机器码API异常: {e}") |
||||
|
raise HTTPException( |
||||
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, |
||||
|
detail=f"获取机器码失败: {str(e)}" |
||||
|
) |
||||
|
|
||||
|
@router.get("/system/info", |
||||
|
summary="获取系统信息", |
||||
|
description="获取当前系统的详细信息", |
||||
|
response_model=SystemInfoResponse) |
||||
|
@handle_api_errors |
||||
|
async def get_system_info(): |
||||
|
"""获取系统信息""" |
||||
|
try: |
||||
|
logger.info("API调用: 获取系统信息") |
||||
|
result = await system_service.get_system_info() |
||||
|
|
||||
|
if result["success"]: |
||||
|
logger.info("系统信息获取成功") |
||||
|
return result |
||||
|
else: |
||||
|
logger.warning("系统信息获取失败") |
||||
|
raise HTTPException( |
||||
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, |
||||
|
detail=result["message"] |
||||
|
) |
||||
|
|
||||
|
except HTTPException: |
||||
|
raise |
||||
|
except Exception as e: |
||||
|
logger.error(f"获取系统信息API异常: {e}") |
||||
|
raise HTTPException( |
||||
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, |
||||
|
detail=f"获取系统信息失败: {str(e)}" |
||||
|
) |
||||
|
|
||||
|
@router.get("/system/machine-code/detailed", |
||||
|
summary="获取详细机器码信息", |
||||
|
description="获取包含系统信息的详细机器码信息") |
||||
|
@handle_api_errors |
||||
|
async def get_detailed_machine_code_info(): |
||||
|
"""获取详细的机器码信息""" |
||||
|
try: |
||||
|
logger.info("API调用: 获取详细机器码信息") |
||||
|
result = await system_service.get_detailed_machine_code_info() |
||||
|
|
||||
|
if result["success"]: |
||||
|
logger.info("详细机器码信息获取成功") |
||||
|
return result |
||||
|
else: |
||||
|
logger.warning("详细机器码信息获取失败") |
||||
|
raise HTTPException( |
||||
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, |
||||
|
detail=result["message"] |
||||
|
) |
||||
|
|
||||
|
except HTTPException: |
||||
|
raise |
||||
|
except Exception as e: |
||||
|
logger.error(f"获取详细机器码信息API异常: {e}") |
||||
|
raise HTTPException( |
||||
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, |
||||
|
detail=f"获取详细机器码信息失败: {str(e)}" |
||||
|
) |
||||
|
|
||||
|
@router.get("/system/health", |
||||
|
summary="系统健康检查", |
||||
|
description="检查系统基本功能是否正常") |
||||
|
@handle_api_errors |
||||
|
async def system_health_check(): |
||||
|
"""系统健康检查""" |
||||
|
try: |
||||
|
logger.info("API调用: 系统健康检查") |
||||
|
|
||||
|
# 检查基本功能 |
||||
|
system_type = system_service.system_utils.get_system_type() |
||||
|
machine_code = system_service.system_utils.get_machine_code() |
||||
|
|
||||
|
health_status = { |
||||
|
"success": True, |
||||
|
"message": "系统健康检查通过", |
||||
|
"data": { |
||||
|
"system_type": system_type, |
||||
|
"machine_code_available": machine_code is not None, |
||||
|
"status": "healthy" |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if not machine_code: |
||||
|
health_status["data"]["status"] = "warning" |
||||
|
health_status["data"]["warning"] = "机器码获取失败" |
||||
|
|
||||
|
logger.info("系统健康检查完成") |
||||
|
return health_status |
||||
|
|
||||
|
except Exception as e: |
||||
|
logger.error(f"系统健康检查异常: {e}") |
||||
|
raise HTTPException( |
||||
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, |
||||
|
detail=f"系统健康检查失败: {str(e)}" |
||||
|
) |
||||
@ -0,0 +1,34 @@ |
|||||
|
""" |
||||
|
系统相关数据模型 |
||||
|
""" |
||||
|
from typing import Optional, Dict, Any |
||||
|
from pydantic import BaseModel, Field |
||||
|
|
||||
|
class MachineCodeResponse(BaseModel): |
||||
|
"""机器码响应模型""" |
||||
|
success: bool = Field(..., description="操作是否成功") |
||||
|
message: str = Field(..., description="响应消息") |
||||
|
data: Optional[Dict[str, Any]] = Field(None, description="机器码数据") |
||||
|
|
||||
|
class SystemInfoResponse(BaseModel): |
||||
|
"""系统信息响应模型""" |
||||
|
success: bool = Field(..., description="操作是否成功") |
||||
|
message: str = Field(..., description="响应消息") |
||||
|
data: Optional[Dict[str, Any]] = Field(None, description="系统信息数据") |
||||
|
|
||||
|
class MachineCodeData(BaseModel): |
||||
|
"""机器码数据模型""" |
||||
|
machine_code: Optional[str] = Field(None, description="机器码") |
||||
|
system_type: str = Field(..., description="系统类型") |
||||
|
method: Optional[str] = Field(None, description="获取方法") |
||||
|
error: Optional[str] = Field(None, description="错误信息") |
||||
|
|
||||
|
class SystemInfoData(BaseModel): |
||||
|
"""系统信息数据模型""" |
||||
|
system_type: str = Field(..., description="系统类型") |
||||
|
platform: str = Field(..., description="平台信息") |
||||
|
architecture: str = Field(..., description="架构") |
||||
|
processor: str = Field(..., description="处理器") |
||||
|
machine_code: Optional[str] = Field(None, description="机器码") |
||||
|
python_version: str = Field(..., description="Python版本") |
||||
|
error: Optional[str] = Field(None, description="错误信息") |
||||
@ -0,0 +1,150 @@ |
|||||
|
""" |
||||
|
系统服务模块 |
||||
|
""" |
||||
|
from typing import Dict, Any, Optional |
||||
|
from app.utils.system_utils import SystemUtils |
||||
|
from app.utils.structured_log import get_structured_logger |
||||
|
|
||||
|
logger = get_structured_logger(__name__) |
||||
|
|
||||
|
class SystemService: |
||||
|
"""系统管理服务""" |
||||
|
|
||||
|
def __init__(self): |
||||
|
self.system_utils = SystemUtils() |
||||
|
|
||||
|
async def get_machine_code(self) -> Dict[str, Any]: |
||||
|
"""获取机器码""" |
||||
|
try: |
||||
|
logger.info("开始获取机器码") |
||||
|
|
||||
|
system_type = SystemUtils.get_system_type() |
||||
|
machine_code = SystemUtils.get_machine_code() |
||||
|
|
||||
|
if machine_code: |
||||
|
method = self._get_method_description(system_type) |
||||
|
logger.info(f"机器码获取成功: {machine_code}, 方法: {method}") |
||||
|
|
||||
|
return { |
||||
|
"success": True, |
||||
|
"message": "机器码获取成功", |
||||
|
"data": { |
||||
|
"machine_code": machine_code, |
||||
|
"system_type": system_type, |
||||
|
"method": method |
||||
|
} |
||||
|
} |
||||
|
else: |
||||
|
logger.warning("机器码获取失败") |
||||
|
return { |
||||
|
"success": False, |
||||
|
"message": "机器码获取失败", |
||||
|
"data": { |
||||
|
"machine_code": None, |
||||
|
"system_type": system_type, |
||||
|
"method": None, |
||||
|
"error": "无法获取机器码" |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
except Exception as e: |
||||
|
logger.error(f"获取机器码异常: {e}") |
||||
|
return { |
||||
|
"success": False, |
||||
|
"message": f"获取机器码失败: {str(e)}", |
||||
|
"data": { |
||||
|
"machine_code": None, |
||||
|
"system_type": SystemUtils.get_system_type(), |
||||
|
"method": None, |
||||
|
"error": str(e) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
async def get_system_info(self) -> Dict[str, Any]: |
||||
|
"""获取系统信息""" |
||||
|
try: |
||||
|
logger.info("开始获取系统信息") |
||||
|
|
||||
|
system_info = SystemUtils.get_system_info() |
||||
|
|
||||
|
if "error" not in system_info: |
||||
|
logger.info("系统信息获取成功") |
||||
|
return { |
||||
|
"success": True, |
||||
|
"message": "系统信息获取成功", |
||||
|
"data": system_info |
||||
|
} |
||||
|
else: |
||||
|
logger.warning("系统信息获取失败") |
||||
|
return { |
||||
|
"success": False, |
||||
|
"message": "系统信息获取失败", |
||||
|
"data": system_info |
||||
|
} |
||||
|
|
||||
|
except Exception as e: |
||||
|
logger.error(f"获取系统信息异常: {e}") |
||||
|
return { |
||||
|
"success": False, |
||||
|
"message": f"获取系统信息失败: {str(e)}", |
||||
|
"data": { |
||||
|
"system_type": "unknown", |
||||
|
"error": str(e) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
def _get_method_description(self, system_type: str) -> str: |
||||
|
"""获取方法描述""" |
||||
|
if system_type == "windows": |
||||
|
return "wmic csproduct get uuid" |
||||
|
elif system_type == "linux": |
||||
|
return "dmidecode -s system-serial-number / cat /sys/class/dmi/id/product_serial / hostid" |
||||
|
else: |
||||
|
return "unknown" |
||||
|
|
||||
|
async def get_detailed_machine_code_info(self) -> Dict[str, Any]: |
||||
|
"""获取详细的机器码信息""" |
||||
|
try: |
||||
|
logger.info("开始获取详细机器码信息") |
||||
|
|
||||
|
system_type = SystemUtils.get_system_type() |
||||
|
machine_code = SystemUtils.get_machine_code() |
||||
|
system_info = SystemUtils.get_system_info() |
||||
|
|
||||
|
result = { |
||||
|
"success": True, |
||||
|
"message": "详细机器码信息获取成功", |
||||
|
"data": { |
||||
|
"machine_code": machine_code, |
||||
|
"system_type": system_type, |
||||
|
"method": self._get_method_description(system_type), |
||||
|
"system_info": system_info, |
||||
|
"timestamp": self._get_current_timestamp() |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if not machine_code: |
||||
|
result["success"] = False |
||||
|
result["message"] = "机器码获取失败" |
||||
|
result["data"]["error"] = "无法获取机器码" |
||||
|
|
||||
|
logger.info("详细机器码信息获取完成") |
||||
|
return result |
||||
|
|
||||
|
except Exception as e: |
||||
|
logger.error(f"获取详细机器码信息异常: {e}") |
||||
|
return { |
||||
|
"success": False, |
||||
|
"message": f"获取详细机器码信息失败: {str(e)}", |
||||
|
"data": { |
||||
|
"machine_code": None, |
||||
|
"system_type": SystemUtils.get_system_type(), |
||||
|
"method": None, |
||||
|
"error": str(e) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
def _get_current_timestamp(self) -> str: |
||||
|
"""获取当前时间戳""" |
||||
|
from datetime import datetime |
||||
|
return datetime.now().isoformat() |
||||
@ -0,0 +1,218 @@ |
|||||
|
""" |
||||
|
系统工具模块 |
||||
|
""" |
||||
|
import platform |
||||
|
import subprocess |
||||
|
import re |
||||
|
from typing import Optional |
||||
|
from app.utils.structured_log import get_structured_logger |
||||
|
|
||||
|
logger = get_structured_logger(__name__) |
||||
|
|
||||
|
class SystemUtils: |
||||
|
"""系统工具类""" |
||||
|
|
||||
|
@staticmethod |
||||
|
def get_system_type() -> str: |
||||
|
"""获取系统类型""" |
||||
|
return platform.system().lower() |
||||
|
|
||||
|
@staticmethod |
||||
|
def get_machine_code() -> Optional[str]: |
||||
|
"""获取机器码 |
||||
|
|
||||
|
Windows: 使用 wmic csproduct get uuid |
||||
|
Linux: 使用 dmidecode -s system-serial-number 或 cat /sys/class/dmi/id/product_serial |
||||
|
""" |
||||
|
try: |
||||
|
system_type = SystemUtils.get_system_type() |
||||
|
logger.info(f"获取机器码,系统类型: {system_type}") |
||||
|
|
||||
|
if system_type == "windows": |
||||
|
return SystemUtils._get_windows_machine_code() |
||||
|
elif system_type == "linux": |
||||
|
return SystemUtils._get_linux_machine_code() |
||||
|
else: |
||||
|
logger.warning(f"不支持的系统类型: {system_type}") |
||||
|
return None |
||||
|
|
||||
|
except Exception as e: |
||||
|
logger.error(f"获取机器码失败: {e}") |
||||
|
return None |
||||
|
|
||||
|
@staticmethod |
||||
|
def _get_windows_machine_code() -> Optional[str]: |
||||
|
"""获取Windows系统机器码""" |
||||
|
try: |
||||
|
# 使用 wmic csproduct get uuid 命令 |
||||
|
result = subprocess.run( |
||||
|
["wmic", "csproduct", "get", "uuid"], |
||||
|
capture_output=True, |
||||
|
text=True, |
||||
|
timeout=10 |
||||
|
) |
||||
|
|
||||
|
if result.returncode == 0: |
||||
|
# 解析输出,跳过标题行 |
||||
|
lines = result.stdout.strip().split('\n') |
||||
|
if len(lines) >= 2: |
||||
|
uuid = lines[1].strip() |
||||
|
if uuid and uuid != "UUID": |
||||
|
logger.info(f"Windows机器码获取成功: {uuid}") |
||||
|
return uuid |
||||
|
|
||||
|
logger.warning("Windows机器码获取失败,尝试备用方法") |
||||
|
return SystemUtils._get_windows_machine_code_fallback() |
||||
|
|
||||
|
except subprocess.TimeoutExpired: |
||||
|
logger.error("Windows机器码获取超时") |
||||
|
return None |
||||
|
except Exception as e: |
||||
|
logger.error(f"Windows机器码获取异常: {e}") |
||||
|
return None |
||||
|
|
||||
|
@staticmethod |
||||
|
def _get_windows_machine_code_fallback() -> Optional[str]: |
||||
|
"""Windows机器码获取备用方法""" |
||||
|
try: |
||||
|
# 尝试使用 PowerShell 命令 |
||||
|
result = subprocess.run( |
||||
|
["powershell", "-Command", "Get-WmiObject -Class Win32_ComputerSystemProduct | Select-Object -ExpandProperty UUID"], |
||||
|
capture_output=True, |
||||
|
text=True, |
||||
|
timeout=10 |
||||
|
) |
||||
|
|
||||
|
if result.returncode == 0: |
||||
|
uuid = result.stdout.strip() |
||||
|
if uuid and len(uuid) > 0: |
||||
|
logger.info(f"Windows机器码获取成功(备用方法): {uuid}") |
||||
|
return uuid |
||||
|
|
||||
|
return None |
||||
|
|
||||
|
except Exception as e: |
||||
|
logger.error(f"Windows机器码备用方法失败: {e}") |
||||
|
return None |
||||
|
|
||||
|
@staticmethod |
||||
|
def _get_linux_machine_code() -> Optional[str]: |
||||
|
"""获取Linux系统机器码""" |
||||
|
try: |
||||
|
# 首先尝试 dmidecode 命令 |
||||
|
serial_number = SystemUtils._get_linux_serial_via_dmidecode() |
||||
|
if serial_number: |
||||
|
return serial_number |
||||
|
|
||||
|
# 备用方法:读取系统文件 |
||||
|
serial_number = SystemUtils._get_linux_serial_via_file() |
||||
|
if serial_number: |
||||
|
return serial_number |
||||
|
|
||||
|
# 最后尝试:使用 hostid 命令 |
||||
|
return SystemUtils._get_linux_serial_via_hostid() |
||||
|
|
||||
|
except Exception as e: |
||||
|
logger.error(f"Linux机器码获取异常: {e}") |
||||
|
return None |
||||
|
|
||||
|
@staticmethod |
||||
|
def _get_linux_serial_via_dmidecode() -> Optional[str]: |
||||
|
"""通过 dmidecode 获取Linux序列号""" |
||||
|
try: |
||||
|
result = subprocess.run( |
||||
|
["dmidecode", "-s", "system-serial-number"], |
||||
|
capture_output=True, |
||||
|
text=True, |
||||
|
timeout=10 |
||||
|
) |
||||
|
|
||||
|
if result.returncode == 0: |
||||
|
serial = result.stdout.strip() |
||||
|
if serial and serial != "0" and len(serial) > 0: |
||||
|
logger.info(f"Linux序列号获取成功(dmidecode): {serial}") |
||||
|
return serial |
||||
|
|
||||
|
return None |
||||
|
|
||||
|
except (subprocess.TimeoutExpired, FileNotFoundError): |
||||
|
logger.warning("dmidecode命令不可用或超时") |
||||
|
return None |
||||
|
except Exception as e: |
||||
|
logger.error(f"dmidecode获取序列号失败: {e}") |
||||
|
return None |
||||
|
|
||||
|
@staticmethod |
||||
|
def _get_linux_serial_via_file() -> Optional[str]: |
||||
|
"""通过读取系统文件获取Linux序列号""" |
||||
|
try: |
||||
|
# 尝试读取 /sys/class/dmi/id/product_serial |
||||
|
result = subprocess.run( |
||||
|
["cat", "/sys/class/dmi/id/product_serial"], |
||||
|
capture_output=True, |
||||
|
text=True, |
||||
|
timeout=5 |
||||
|
) |
||||
|
|
||||
|
if result.returncode == 0: |
||||
|
serial = result.stdout.strip() |
||||
|
if serial and serial != "0" and len(serial) > 0: |
||||
|
logger.info(f"Linux序列号获取成功(文件): {serial}") |
||||
|
return serial |
||||
|
|
||||
|
return None |
||||
|
|
||||
|
except (subprocess.TimeoutExpired, FileNotFoundError): |
||||
|
logger.warning("系统文件读取失败") |
||||
|
return None |
||||
|
except Exception as e: |
||||
|
logger.error(f"文件读取序列号失败: {e}") |
||||
|
return None |
||||
|
|
||||
|
@staticmethod |
||||
|
def _get_linux_serial_via_hostid() -> Optional[str]: |
||||
|
"""通过 hostid 命令获取Linux机器码""" |
||||
|
try: |
||||
|
result = subprocess.run( |
||||
|
["hostid"], |
||||
|
capture_output=True, |
||||
|
text=True, |
||||
|
timeout=5 |
||||
|
) |
||||
|
|
||||
|
if result.returncode == 0: |
||||
|
hostid = result.stdout.strip() |
||||
|
if hostid and len(hostid) > 0: |
||||
|
logger.info(f"Linux机器码获取成功(hostid): {hostid}") |
||||
|
return hostid |
||||
|
|
||||
|
return None |
||||
|
|
||||
|
except (subprocess.TimeoutExpired, FileNotFoundError): |
||||
|
logger.warning("hostid命令不可用") |
||||
|
return None |
||||
|
except Exception as e: |
||||
|
logger.error(f"hostid获取机器码失败: {e}") |
||||
|
return None |
||||
|
|
||||
|
@staticmethod |
||||
|
def get_system_info() -> dict: |
||||
|
"""获取系统信息""" |
||||
|
try: |
||||
|
system_type = SystemUtils.get_system_type() |
||||
|
machine_code = SystemUtils.get_machine_code() |
||||
|
|
||||
|
return { |
||||
|
"system_type": system_type, |
||||
|
"platform": platform.platform(), |
||||
|
"architecture": platform.architecture()[0], |
||||
|
"processor": platform.processor(), |
||||
|
"machine_code": machine_code, |
||||
|
"python_version": platform.python_version() |
||||
|
} |
||||
|
except Exception as e: |
||||
|
logger.error(f"获取系统信息失败: {e}") |
||||
|
return { |
||||
|
"system_type": "unknown", |
||||
|
"error": str(e) |
||||
|
} |
||||
@ -0,0 +1,157 @@ |
|||||
|
# 系统API文档 |
||||
|
|
||||
|
## 概述 |
||||
|
|
||||
|
系统API提供了获取机器码和系统信息的功能,支持Windows和Linux系统,遵循项目的分层架构设计。 |
||||
|
|
||||
|
## API端点 |
||||
|
|
||||
|
### 1. 获取机器码 |
||||
|
|
||||
|
**端点:** `GET /api/v1/system/machine-code` |
||||
|
|
||||
|
**描述:** 获取当前系统的机器码 |
||||
|
|
||||
|
**响应示例:** |
||||
|
```json |
||||
|
{ |
||||
|
"success": true, |
||||
|
"message": "机器码获取成功", |
||||
|
"data": { |
||||
|
"machine_code": "03000200-0400-0500-0006-000700080009", |
||||
|
"system_type": "windows", |
||||
|
"method": "wmic csproduct get uuid" |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
### 2. 获取系统信息 |
||||
|
|
||||
|
**端点:** `GET /api/v1/system/info` |
||||
|
|
||||
|
**描述:** 获取当前系统的详细信息 |
||||
|
|
||||
|
**响应示例:** |
||||
|
```json |
||||
|
{ |
||||
|
"success": true, |
||||
|
"message": "系统信息获取成功", |
||||
|
"data": { |
||||
|
"system_type": "windows", |
||||
|
"platform": "Windows-10-10.0.17763-SP0", |
||||
|
"architecture": "64bit", |
||||
|
"processor": "AMD64 Family 23 Model 24 Stepping 1, AuthenticAMD", |
||||
|
"machine_code": "03000200-0400-0500-0006-000700080009", |
||||
|
"python_version": "3.10.5" |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
### 3. 获取详细机器码信息 |
||||
|
|
||||
|
**端点:** `GET /api/v1/system/machine-code/detailed` |
||||
|
|
||||
|
**描述:** 获取包含系统信息的详细机器码信息 |
||||
|
|
||||
|
**响应示例:** |
||||
|
```json |
||||
|
{ |
||||
|
"success": true, |
||||
|
"message": "详细机器码信息获取成功", |
||||
|
"data": { |
||||
|
"machine_code": "03000200-0400-0500-0006-000700080009", |
||||
|
"system_type": "windows", |
||||
|
"method": "wmic csproduct get uuid", |
||||
|
"system_info": { |
||||
|
"system_type": "windows", |
||||
|
"platform": "Windows-10-10.0.17763-SP0", |
||||
|
"architecture": "64bit", |
||||
|
"processor": "AMD64 Family 23 Model 24 Stepping 1, AuthenticAMD", |
||||
|
"machine_code": "03000200-0400-0500-0006-000700080009", |
||||
|
"python_version": "3.10.5" |
||||
|
}, |
||||
|
"timestamp": "2025-08-15T15:21:54.205977" |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
### 4. 系统健康检查 |
||||
|
|
||||
|
**端点:** `GET /api/v1/system/health` |
||||
|
|
||||
|
**描述:** 检查系统基本功能是否正常 |
||||
|
|
||||
|
**响应示例:** |
||||
|
```json |
||||
|
{ |
||||
|
"success": true, |
||||
|
"message": "系统健康检查通过", |
||||
|
"data": { |
||||
|
"system_type": "windows", |
||||
|
"machine_code_available": true, |
||||
|
"status": "healthy" |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
## 技术实现 |
||||
|
|
||||
|
### Windows系统 |
||||
|
- 主要方法:`wmic csproduct get uuid` |
||||
|
- 备用方法:PowerShell `Get-WmiObject -Class Win32_ComputerSystemProduct` |
||||
|
|
||||
|
### Linux系统 |
||||
|
- 主要方法:`dmidecode -s system-serial-number` |
||||
|
- 备用方法1:读取 `/sys/class/dmi/id/product_serial` |
||||
|
- 备用方法2:`hostid` 命令 |
||||
|
|
||||
|
### 错误处理 |
||||
|
- 命令执行超时处理 |
||||
|
- 多种备用方案确保兼容性 |
||||
|
- 详细的错误日志记录 |
||||
|
|
||||
|
## 架构设计 |
||||
|
|
||||
|
``` |
||||
|
API端点层 (app/api/v1/endpoints/system.py) |
||||
|
↓ |
||||
|
服务层 (app/services/system_service.py) |
||||
|
↓ |
||||
|
工具层 (app/utils/system_utils.py) |
||||
|
↓ |
||||
|
系统命令执行 |
||||
|
``` |
||||
|
|
||||
|
## 使用示例 |
||||
|
|
||||
|
### Python客户端 |
||||
|
```python |
||||
|
import requests |
||||
|
|
||||
|
# 获取机器码 |
||||
|
response = requests.get("http://localhost:8000/api/v1/system/machine-code") |
||||
|
machine_code = response.json()["data"]["machine_code"] |
||||
|
|
||||
|
# 获取系统信息 |
||||
|
response = requests.get("http://localhost:8000/api/v1/system/info") |
||||
|
system_info = response.json()["data"] |
||||
|
``` |
||||
|
|
||||
|
### curl命令 |
||||
|
```bash |
||||
|
# 获取机器码 |
||||
|
curl -X GET "http://localhost:8000/api/v1/system/machine-code" |
||||
|
|
||||
|
# 获取系统信息 |
||||
|
curl -X GET "http://localhost:8000/api/v1/system/info" |
||||
|
|
||||
|
# 系统健康检查 |
||||
|
curl -X GET "http://localhost:8000/api/v1/system/health" |
||||
|
``` |
||||
|
|
||||
|
## 注意事项 |
||||
|
|
||||
|
1. **权限要求**:某些系统命令可能需要管理员权限 |
||||
|
2. **兼容性**:不同系统版本可能有差异,已提供多种备用方案 |
||||
|
3. **性能**:命令执行有超时限制,避免长时间阻塞 |
||||
|
4. **安全性**:仅获取系统标识信息,不涉及敏感数据 |
||||
@ -0,0 +1,44 @@ |
|||||
|
#!/usr/bin/env python3 |
||||
|
""" |
||||
|
系统API端点测试脚本 |
||||
|
""" |
||||
|
import requests |
||||
|
import json |
||||
|
import time |
||||
|
|
||||
|
def test_system_endpoints(): |
||||
|
"""测试系统API端点""" |
||||
|
base_url = "http://localhost:8000/api/v1" |
||||
|
|
||||
|
# 等待服务器启动 |
||||
|
print("等待服务器启动...") |
||||
|
time.sleep(3) |
||||
|
|
||||
|
endpoints = [ |
||||
|
"/system/machine-code", |
||||
|
"/system/info", |
||||
|
"/system/machine-code/detailed", |
||||
|
"/system/health" |
||||
|
] |
||||
|
|
||||
|
for endpoint in endpoints: |
||||
|
try: |
||||
|
print(f"\n=== 测试端点: {endpoint} ===") |
||||
|
response = requests.get(f"{base_url}{endpoint}", timeout=10) |
||||
|
|
||||
|
print(f"状态码: {response.status_code}") |
||||
|
if response.status_code == 200: |
||||
|
data = response.json() |
||||
|
print(f"响应: {json.dumps(data, indent=2, ensure_ascii=False)}") |
||||
|
else: |
||||
|
print(f"错误响应: {response.text}") |
||||
|
|
||||
|
except requests.exceptions.ConnectionError: |
||||
|
print("连接失败,服务器可能未启动") |
||||
|
except requests.exceptions.Timeout: |
||||
|
print("请求超时") |
||||
|
except Exception as e: |
||||
|
print(f"请求异常: {e}") |
||||
|
|
||||
|
if __name__ == "__main__": |
||||
|
test_system_endpoints() |
||||
Loading…
Reference in new issue