You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

221 lines
6.4 KiB

# -*- coding: utf-8 -*-
"""
===================================
分析相关模型
===================================
职责
1. 定义分析请求和响应模型
2. 定义任务状态模型
3. 定义异步任务队列相关模型
"""
from typing import Optional, List, Any
from enum import Enum
from pydantic import BaseModel, Field
class TaskStatusEnum(str, Enum):
"""任务状态枚举"""
PENDING = "pending"
PROCESSING = "processing"
COMPLETED = "completed"
FAILED = "failed"
class AnalyzeRequest(BaseModel):
"""分析请求模型"""
stock_code: Optional[str] = Field(
None,
description="单只股票代码",
example="600519"
)
stock_codes: Optional[List[str]] = Field(
None,
description="多只股票代码(与 stock_code 二选一)",
example=["600519", "000858"]
)
report_type: str = Field(
"detailed",
description="报告类型",
pattern="^(simple|detailed)$"
)
force_refresh: bool = Field(
True,
description="是否强制刷新(忽略缓存)"
)
async_mode: bool = Field(
False,
description="是否使用异步模式"
)
class Config:
json_schema_extra = {
"example": {
"stock_code": "600519",
"report_type": "detailed",
"force_refresh": False,
"async_mode": False
}
}
class AnalysisResultResponse(BaseModel):
"""分析结果响应模型"""
query_id: str = Field(..., description="分析记录唯一标识")
stock_code: str = Field(..., description="股票代码")
stock_name: Optional[str] = Field(None, description="股票名称")
report: Optional[Any] = Field(None, description="分析报告")
created_at: str = Field(..., description="创建时间")
class Config:
json_schema_extra = {
"example": {
"query_id": "abc123def456",
"stock_code": "600519",
"stock_name": "贵州茅台",
"report": {
"summary": {
"sentiment_score": 75,
"operation_advice": "持有"
}
},
"created_at": "2024-01-01T12:00:00"
}
}
class TaskAccepted(BaseModel):
"""异步任务接受响应"""
task_id: str = Field(..., description="任务 ID用于查询状态")
status: str = Field(
...,
description="任务状态",
pattern="^(pending|processing)$"
)
message: Optional[str] = Field(None, description="提示信息")
class Config:
json_schema_extra = {
"example": {
"task_id": "task_abc123",
"status": "pending",
"message": "Analysis task accepted"
}
}
class TaskStatus(BaseModel):
"""任务状态模型"""
task_id: str = Field(..., description="任务 ID")
status: str = Field(
...,
description="任务状态",
pattern="^(pending|processing|completed|failed)$"
)
progress: Optional[int] = Field(
None,
description="进度百分比 (0-100)",
ge=0,
le=100
)
result: Optional[AnalysisResultResponse] = Field(
None,
description="分析结果(仅在 completed 时存在)"
)
error: Optional[str] = Field(
None,
description="错误信息(仅在 failed 时存在)"
)
class Config:
json_schema_extra = {
"example": {
"task_id": "task_abc123",
"status": "completed",
"progress": 100,
"result": None,
"error": None
}
}
class TaskInfo(BaseModel):
"""
任务详情模型
用于任务列表和 SSE 事件推送
"""
task_id: str = Field(..., description="任务 ID")
stock_code: str = Field(..., description="股票代码")
stock_name: Optional[str] = Field(None, description="股票名称")
status: TaskStatusEnum = Field(..., description="任务状态")
progress: int = Field(0, description="进度百分比 (0-100)", ge=0, le=100)
message: Optional[str] = Field(None, description="状态消息")
report_type: str = Field("detailed", description="报告类型")
created_at: str = Field(..., description="创建时间")
started_at: Optional[str] = Field(None, description="开始执行时间")
completed_at: Optional[str] = Field(None, description="完成时间")
error: Optional[str] = Field(None, description="错误信息(仅在 failed 时存在)")
class Config:
json_schema_extra = {
"example": {
"task_id": "abc123def456",
"stock_code": "600519",
"stock_name": "贵州茅台",
"status": "processing",
"progress": 50,
"message": "正在分析中...",
"report_type": "detailed",
"created_at": "2026-02-05T10:30:00",
"started_at": "2026-02-05T10:30:01",
"completed_at": None,
"error": None
}
}
class TaskListResponse(BaseModel):
"""任务列表响应模型"""
total: int = Field(..., description="任务总数")
pending: int = Field(..., description="等待中的任务数")
processing: int = Field(..., description="处理中的任务数")
tasks: List[TaskInfo] = Field(..., description="任务列表")
class Config:
json_schema_extra = {
"example": {
"total": 3,
"pending": 1,
"processing": 2,
"tasks": []
}
}
class DuplicateTaskErrorResponse(BaseModel):
"""重复任务错误响应模型"""
error: str = Field("duplicate_task", description="错误类型")
message: str = Field(..., description="错误信息")
stock_code: str = Field(..., description="股票代码")
existing_task_id: str = Field(..., description="已存在的任务 ID")
class Config:
json_schema_extra = {
"example": {
"error": "duplicate_task",
"message": "股票 600519 正在分析中",
"stock_code": "600519",
"existing_task_id": "abc123def456"
}
}