feat(admin): 添加用户管理相关文件
添加用户管理视图、API和状态管理文件
This commit is contained in:
@@ -0,0 +1,238 @@
|
||||
"""
|
||||
API客户端模块
|
||||
|
||||
提供HTTP请求封装和API调用功能。
|
||||
"""
|
||||
|
||||
import requests
|
||||
import json
|
||||
from typing import Any, Dict, Optional, Callable
|
||||
from dataclasses import dataclass
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class HTTPMethod(Enum):
|
||||
"""HTTP方法"""
|
||||
GET = "GET"
|
||||
POST = "POST"
|
||||
PUT = "PUT"
|
||||
DELETE = "DELETE"
|
||||
PATCH = "PATCH"
|
||||
|
||||
|
||||
@dataclass
|
||||
class APIResponse:
|
||||
"""API响应"""
|
||||
status_code: int
|
||||
data: Any
|
||||
headers: Dict[str, str]
|
||||
success: bool
|
||||
error_message: Optional[str] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class APIRequest:
|
||||
"""API请求"""
|
||||
method: HTTPMethod
|
||||
url: str
|
||||
headers: Optional[Dict[str, str]] = None
|
||||
params: Optional[Dict[str, Any]] = None
|
||||
data: Optional[Any] = None
|
||||
json_data: Optional[Dict[str, Any]] = None
|
||||
timeout: int = 30
|
||||
|
||||
|
||||
class APIClient:
|
||||
"""
|
||||
API客户端
|
||||
|
||||
特性:
|
||||
- 支持多种HTTP方法
|
||||
- 自动JSON序列化/反序列化
|
||||
- 超时处理
|
||||
- 错误处理
|
||||
- 请求/响应拦截器
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
base_url: str,
|
||||
default_headers: Optional[Dict[str, str]] = None,
|
||||
timeout: int = 30
|
||||
):
|
||||
"""
|
||||
初始化API客户端
|
||||
|
||||
Args:
|
||||
base_url: 基础URL
|
||||
default_headers: 默认请求头
|
||||
timeout: 默认超时时间(秒)
|
||||
"""
|
||||
self._base_url = base_url.rstrip('/')
|
||||
self._default_headers = default_headers or {}
|
||||
self._default_timeout = timeout
|
||||
self._request_interceptors: list = []
|
||||
self._response_interceptors: list = []
|
||||
self._session = requests.Session()
|
||||
|
||||
def add_request_interceptor(self, interceptor: Callable[[APIRequest], APIRequest]) -> None:
|
||||
"""添加请求拦截器"""
|
||||
self._request_interceptors.append(interceptor)
|
||||
|
||||
def add_response_interceptor(self, interceptor: Callable[[APIResponse], APIResponse]) -> None:
|
||||
"""添加响应拦截器"""
|
||||
self._response_interceptors.append(interceptor)
|
||||
|
||||
def _build_url(self, endpoint: str) -> str:
|
||||
"""构建完整URL"""
|
||||
endpoint = endpoint.lstrip('/')
|
||||
return f"{self._base_url}/{endpoint}"
|
||||
|
||||
def _apply_request_interceptors(self, request: APIRequest) -> APIRequest:
|
||||
"""应用请求拦截器"""
|
||||
for interceptor in self._request_interceptors:
|
||||
request = interceptor(request)
|
||||
return request
|
||||
|
||||
def _apply_response_interceptors(self, response: APIResponse) -> APIResponse:
|
||||
"""应用响应拦截器"""
|
||||
for interceptor in self._response_interceptors:
|
||||
response = interceptor(response)
|
||||
return response
|
||||
|
||||
def request(self, api_request: APIRequest) -> APIResponse:
|
||||
"""
|
||||
发送HTTP请求
|
||||
|
||||
Args:
|
||||
api_request: API请求对象
|
||||
|
||||
Returns:
|
||||
API响应对象
|
||||
"""
|
||||
try:
|
||||
# 应用请求拦截器
|
||||
api_request = self._apply_request_interceptors(api_request)
|
||||
|
||||
# 合并默认请求头
|
||||
headers = {**self._default_headers, **(api_request.headers or {})}
|
||||
|
||||
# 发送请求
|
||||
response = self._session.request(
|
||||
method=api_request.method.value,
|
||||
url=api_request.url,
|
||||
headers=headers,
|
||||
params=api_request.params,
|
||||
data=api_request.data,
|
||||
json=api_request.json_data,
|
||||
timeout=api_request.timeout or self._default_timeout
|
||||
)
|
||||
|
||||
# 解析响应
|
||||
try:
|
||||
response_data = response.json()
|
||||
except json.JSONDecodeError:
|
||||
response_data = response.text
|
||||
|
||||
api_response = APIResponse(
|
||||
status_code=response.status_code,
|
||||
data=response_data,
|
||||
headers=dict(response.headers),
|
||||
success=200 <= response.status_code < 300
|
||||
)
|
||||
|
||||
# 应用响应拦截器
|
||||
return self._apply_response_interceptors(api_response)
|
||||
|
||||
except requests.exceptions.Timeout:
|
||||
return APIResponse(
|
||||
status_code=0,
|
||||
data=None,
|
||||
headers={},
|
||||
success=False,
|
||||
error_message="请求超时"
|
||||
)
|
||||
except requests.exceptions.ConnectionError as e:
|
||||
return APIResponse(
|
||||
status_code=0,
|
||||
data=None,
|
||||
headers={},
|
||||
success=False,
|
||||
error_message=f"连接错误: {str(e)}"
|
||||
)
|
||||
except Exception as e:
|
||||
return APIResponse(
|
||||
status_code=0,
|
||||
data=None,
|
||||
headers={},
|
||||
success=False,
|
||||
error_message=f"请求失败: {str(e)}"
|
||||
)
|
||||
|
||||
def get(
|
||||
self,
|
||||
endpoint: str,
|
||||
params: Optional[Dict[str, Any]] = None,
|
||||
headers: Optional[Dict[str, str]] = None,
|
||||
timeout: Optional[int] = None
|
||||
) -> APIResponse:
|
||||
"""发送GET请求"""
|
||||
request = APIRequest(
|
||||
method=HTTPMethod.GET,
|
||||
url=self._build_url(endpoint),
|
||||
headers=headers,
|
||||
params=params,
|
||||
timeout=timeout or self._default_timeout
|
||||
)
|
||||
return self.request(request)
|
||||
|
||||
def post(
|
||||
self,
|
||||
endpoint: str,
|
||||
json_data: Optional[Dict[str, Any]] = None,
|
||||
data: Optional[Any] = None,
|
||||
headers: Optional[Dict[str, str]] = None,
|
||||
timeout: Optional[int] = None
|
||||
) -> APIResponse:
|
||||
"""发送POST请求"""
|
||||
request = APIRequest(
|
||||
method=HTTPMethod.POST,
|
||||
url=self._build_url(endpoint),
|
||||
headers=headers,
|
||||
data=data,
|
||||
json_data=json_data,
|
||||
timeout=timeout or self._default_timeout
|
||||
)
|
||||
return self.request(request)
|
||||
|
||||
def put(
|
||||
self,
|
||||
endpoint: str,
|
||||
json_data: Optional[Dict[str, Any]] = None,
|
||||
headers: Optional[Dict[str, str]] = None,
|
||||
timeout: Optional[int] = None
|
||||
) -> APIResponse:
|
||||
"""发送PUT请求"""
|
||||
request = APIRequest(
|
||||
method=HTTPMethod.PUT,
|
||||
url=self._build_url(endpoint),
|
||||
headers=headers,
|
||||
json_data=json_data,
|
||||
timeout=timeout or self._default_timeout
|
||||
)
|
||||
return self.request(request)
|
||||
|
||||
def delete(
|
||||
self,
|
||||
endpoint: str,
|
||||
headers: Optional[Dict[str, str]] = None,
|
||||
timeout: Optional[int] = None
|
||||
) -> APIResponse:
|
||||
"""发送DELETE请求"""
|
||||
request = APIRequest(
|
||||
method=HTTPMethod.DELETE,
|
||||
url=self._build_url(endpoint),
|
||||
headers=headers,
|
||||
timeout=timeout or self._default_timeout
|
||||
)
|
||||
return self.request(request)
|
||||
Reference in New Issue
Block a user