2026-01-25 22:34:33 +08:00
|
|
|
|
"""API 层的请求/响应数据模型(Pydantic)。
|
|
|
|
|
|
|
|
|
|
|
|
该文件集中定义后端 HTTP 接口的入参与返回结构,便于:
|
|
|
|
|
|
- 校验请求字段(长度、范围等)
|
|
|
|
|
|
- 生成 OpenAPI 文档
|
|
|
|
|
|
- 在路由层与前端之间形成稳定契约
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
2026-01-19 14:27:41 +08:00
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
2026-01-25 22:34:33 +08:00
|
|
|
|
from datetime import datetime
|
2026-01-19 14:27:41 +08:00
|
|
|
|
from typing import Any
|
|
|
|
|
|
|
|
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class HealthResponse(BaseModel):
|
2026-01-25 22:34:33 +08:00
|
|
|
|
"""健康检查返回。"""
|
|
|
|
|
|
|
2026-01-19 14:27:41 +08:00
|
|
|
|
status: str = "ok"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SimulationStartRequest(BaseModel):
|
2026-01-25 22:34:33 +08:00
|
|
|
|
"""启动仿真的请求体。"""
|
|
|
|
|
|
|
2026-01-19 14:27:41 +08:00
|
|
|
|
scenario: str | None = None
|
|
|
|
|
|
weather: str | None = None
|
|
|
|
|
|
time_period: str | None = None
|
|
|
|
|
|
max_speed_kmh: int | None = Field(default=None, ge=0, le=300)
|
|
|
|
|
|
duration_minutes: int | None = Field(default=None, ge=1, le=360)
|
|
|
|
|
|
driver: str | None = None
|
|
|
|
|
|
extra: dict[str, Any] = Field(default_factory=dict)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SimulationStartResponse(BaseModel):
|
|
|
|
|
|
simulation_id: str
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SimulationStopResponse(BaseModel):
|
|
|
|
|
|
simulation_id: str
|
|
|
|
|
|
status: str
|
|
|
|
|
|
|
2026-01-25 22:34:33 +08:00
|
|
|
|
|
|
|
|
|
|
class TokenResponse(BaseModel):
|
|
|
|
|
|
"""登录成功后返回的 token 信息。"""
|
|
|
|
|
|
|
|
|
|
|
|
access_token: str
|
|
|
|
|
|
token_type: str = "bearer"
|
|
|
|
|
|
expires_in: int
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class LoginRequest(BaseModel):
|
|
|
|
|
|
"""用户名密码登录请求。"""
|
|
|
|
|
|
|
|
|
|
|
|
username: str = Field(min_length=1, max_length=64)
|
|
|
|
|
|
password: str = Field(min_length=1, max_length=128)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class RoleCreateRequest(BaseModel):
|
|
|
|
|
|
"""创建角色请求。"""
|
|
|
|
|
|
|
|
|
|
|
|
role_id: str | None = Field(default=None, max_length=64)
|
|
|
|
|
|
role_name: str = Field(min_length=1, max_length=64)
|
|
|
|
|
|
role_desc: str | None = Field(default=None, max_length=255)
|
|
|
|
|
|
is_active: bool = True
|
|
|
|
|
|
extra: dict[str, Any] | None = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class RoleUpdateRequest(BaseModel):
|
|
|
|
|
|
role_name: str | None = Field(default=None, max_length=64)
|
|
|
|
|
|
role_desc: str | None = Field(default=None, max_length=255)
|
|
|
|
|
|
is_active: bool | None = None
|
|
|
|
|
|
extra: dict[str, Any] | None = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class RoleResponse(BaseModel):
|
|
|
|
|
|
role_id: str
|
|
|
|
|
|
role_name: str
|
|
|
|
|
|
role_desc: str | None = None
|
|
|
|
|
|
is_active: bool
|
|
|
|
|
|
created_at: datetime | None = None
|
|
|
|
|
|
updated_at: datetime | None = None
|
|
|
|
|
|
extra: dict[str, Any] | None = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class PermissionCreateRequest(BaseModel):
|
|
|
|
|
|
"""创建权限点请求(perm_code 支持自定义命名规则)。"""
|
|
|
|
|
|
|
|
|
|
|
|
perm_code: str = Field(min_length=1, max_length=128)
|
|
|
|
|
|
perm_name: str = Field(min_length=1, max_length=128)
|
|
|
|
|
|
perm_group: str | None = Field(default=None, max_length=64)
|
|
|
|
|
|
perm_desc: str | None = Field(default=None, max_length=255)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class PermissionResponse(BaseModel):
|
|
|
|
|
|
perm_code: str
|
|
|
|
|
|
perm_name: str
|
|
|
|
|
|
perm_group: str | None = None
|
|
|
|
|
|
perm_desc: str | None = None
|
|
|
|
|
|
created_at: datetime | None = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class RolePermissionsUpdateRequest(BaseModel):
|
|
|
|
|
|
perm_codes: list[str] = Field(default_factory=list)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class RolePermissionsResponse(BaseModel):
|
|
|
|
|
|
role_id: str
|
|
|
|
|
|
perm_codes: list[str]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class UserCreateRequest(BaseModel):
|
|
|
|
|
|
"""创建用户请求(包含明文密码,服务端将保存为哈希)。"""
|
|
|
|
|
|
|
|
|
|
|
|
user_id: str | None = Field(default=None, max_length=64)
|
|
|
|
|
|
username: str = Field(min_length=1, max_length=64)
|
|
|
|
|
|
display_name: str | None = Field(default=None, max_length=64)
|
|
|
|
|
|
password: str = Field(min_length=1, max_length=128)
|
|
|
|
|
|
role_id: str = Field(min_length=1, max_length=64)
|
|
|
|
|
|
is_active: bool = True
|
|
|
|
|
|
extra: dict[str, Any] | None = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class UserUpdateRequest(BaseModel):
|
|
|
|
|
|
display_name: str | None = Field(default=None, max_length=64)
|
|
|
|
|
|
role_id: str | None = Field(default=None, max_length=64)
|
|
|
|
|
|
is_active: bool | None = None
|
|
|
|
|
|
extra: dict[str, Any] | None = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class UserPasswordUpdateRequest(BaseModel):
|
|
|
|
|
|
new_password: str = Field(min_length=1, max_length=128)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class UserResponse(BaseModel):
|
|
|
|
|
|
user_id: str
|
|
|
|
|
|
username: str
|
|
|
|
|
|
display_name: str | None = None
|
|
|
|
|
|
role_id: str
|
|
|
|
|
|
role_name: str | None = None
|
|
|
|
|
|
is_active: bool
|
|
|
|
|
|
last_login_at: datetime | None = None
|
|
|
|
|
|
created_at: datetime | None = None
|
|
|
|
|
|
updated_at: datetime | None = None
|
|
|
|
|
|
extra: dict[str, Any] | None = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class MeResponse(BaseModel):
|
|
|
|
|
|
"""当前登录用户信息返回。"""
|
|
|
|
|
|
|
|
|
|
|
|
user: UserResponse
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class LoginResponse(BaseModel):
|
|
|
|
|
|
token: TokenResponse
|
|
|
|
|
|
user: UserResponse
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class BootstrapRequest(BaseModel):
|
|
|
|
|
|
"""系统首次初始化请求(仅允许在系统尚无任何用户时调用)。"""
|
|
|
|
|
|
|
|
|
|
|
|
username: str = Field(min_length=1, max_length=64)
|
|
|
|
|
|
password: str = Field(min_length=1, max_length=128)
|
|
|
|
|
|
display_name: str | None = Field(default=None, max_length=64)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class BootstrapResponse(BaseModel):
|
|
|
|
|
|
token: TokenResponse
|
|
|
|
|
|
user: UserResponse
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class UnityInitConfigRequest(BaseModel):
|
|
|
|
|
|
payload: dict[str, Any]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class UnityInitConfigResponse(BaseModel):
|
|
|
|
|
|
simulation_id: str
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class UnityCommandRequest(BaseModel):
|
|
|
|
|
|
payload: dict[str, Any]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class UnityCommandResponse(BaseModel):
|
|
|
|
|
|
ok: bool = True
|