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.

176 lines
5.8 KiB

# -*- coding: utf-8 -*-
"""
===================================
历史记录相关模型
===================================
职责
1. 定义历史记录列表和详情模型
2. 定义分析报告完整模型
"""
from typing import Optional, List, Any
from pydantic import BaseModel, Field
class HistoryItem(BaseModel):
"""历史记录摘要(列表展示用)"""
query_id: str = Field(..., description="分析记录唯一标识")
stock_code: str = Field(..., description="股票代码")
stock_name: Optional[str] = Field(None, description="股票名称")
report_type: Optional[str] = Field(None, description="报告类型")
sentiment_score: Optional[int] = Field(
None,
description="情绪评分 (0-100)",
ge=0,
le=100
)
operation_advice: Optional[str] = Field(None, description="操作建议")
created_at: Optional[str] = Field(None, description="创建时间")
class Config:
json_schema_extra = {
"example": {
"query_id": "abc123",
"stock_code": "600519",
"stock_name": "贵州茅台",
"report_type": "detailed",
"sentiment_score": 75,
"operation_advice": "持有",
"created_at": "2024-01-01T12:00:00"
}
}
class HistoryListResponse(BaseModel):
"""历史记录列表响应"""
total: int = Field(..., description="总记录数")
page: int = Field(..., description="当前页码")
limit: int = Field(..., description="每页数量")
items: List[HistoryItem] = Field(default_factory=list, description="记录列表")
class Config:
json_schema_extra = {
"example": {
"total": 100,
"page": 1,
"limit": 20,
"items": []
}
}
class NewsIntelItem(BaseModel):
"""新闻情报条目"""
title: str = Field(..., description="新闻标题")
snippet: str = Field("", description="新闻摘要最多200字")
url: str = Field(..., description="新闻链接")
class Config:
json_schema_extra = {
"example": {
"title": "公司发布业绩快报,营收同比增长 20%",
"snippet": "公司公告显示,季度营收同比增长 20%...",
"url": "https://example.com/news/123"
}
}
class NewsIntelResponse(BaseModel):
"""新闻情报响应"""
total: int = Field(..., description="新闻条数")
items: List[NewsIntelItem] = Field(default_factory=list, description="新闻列表")
class Config:
json_schema_extra = {
"example": {
"total": 2,
"items": []
}
}
class ReportMeta(BaseModel):
"""报告元信息"""
query_id: str = Field(..., description="分析记录唯一标识")
stock_code: str = Field(..., description="股票代码")
stock_name: Optional[str] = Field(None, description="股票名称")
report_type: Optional[str] = Field(None, description="报告类型")
created_at: Optional[str] = Field(None, description="创建时间")
current_price: Optional[float] = Field(None, description="分析时股价")
change_pct: Optional[float] = Field(None, description="分析时涨跌幅(%)")
class ReportSummary(BaseModel):
"""报告概览区"""
analysis_summary: Optional[str] = Field(None, description="关键结论")
operation_advice: Optional[str] = Field(None, description="操作建议")
trend_prediction: Optional[str] = Field(None, description="趋势预测")
sentiment_score: Optional[int] = Field(
None,
description="情绪评分 (0-100)",
ge=0,
le=100
)
sentiment_label: Optional[str] = Field(None, description="情绪标签")
class ReportStrategy(BaseModel):
"""策略点位区"""
ideal_buy: Optional[str] = Field(None, description="理想买入价")
secondary_buy: Optional[str] = Field(None, description="第二买入价")
stop_loss: Optional[str] = Field(None, description="止损价")
take_profit: Optional[str] = Field(None, description="止盈价")
class ReportDetails(BaseModel):
"""报告详情区"""
news_content: Optional[str] = Field(None, description="新闻摘要")
raw_result: Optional[Any] = Field(None, description="原始分析结果JSON")
context_snapshot: Optional[Any] = Field(None, description="分析时上下文快照JSON")
class AnalysisReport(BaseModel):
"""完整分析报告"""
meta: ReportMeta = Field(..., description="元信息")
summary: ReportSummary = Field(..., description="概览区")
strategy: Optional[ReportStrategy] = Field(None, description="策略点位区")
details: Optional[ReportDetails] = Field(None, description="详情区")
class Config:
json_schema_extra = {
"example": {
"meta": {
"query_id": "abc123",
"stock_code": "600519",
"stock_name": "贵州茅台",
"report_type": "detailed",
"created_at": "2024-01-01T12:00:00"
},
"summary": {
"analysis_summary": "技术面向好,建议持有",
"operation_advice": "持有",
"trend_prediction": "看多",
"sentiment_score": 75,
"sentiment_label": "乐观"
},
"strategy": {
"ideal_buy": "1800.00",
"secondary_buy": "1750.00",
"stop_loss": "1700.00",
"take_profit": "2000.00"
},
"details": None
}
}