This commit is contained in:
2026-09-07 13:34:26 +08:00
parent ad9245abdd
commit 359f9ae2e4
23 changed files with 2260 additions and 513 deletions

View File

@@ -269,6 +269,89 @@ class PreviewResponse(BaseModel):
has_more: bool = False # 返回窗口之前是否还有更早历史(前端向左滚动翻页用)
# ---------- 公司简介tushare stock_company详情页按需懒加载 ----------
class StockCompanyOut(BaseModel):
ts_code: str
com_name: str | None = None # 公司全称
com_id: str | None = None # 统一社会信用代码
chairman: str | None = None # 法人代表
manager: str | None = None # 总经理
secretary: str | None = None # 董秘
reg_capital: float | None = None # 注册资本(万元)
setup_date: str | None = None # 注册日期 YYYYMMDD展示层换算
province: str | None = None # 所在省份
city: str | None = None # 所在城市
introduction: str | None = None # 公司介绍
website: str | None = None # 公司主页
email: str | None = None # 电子邮件
office: str | None = None # 办公地址
employees: int | None = None # 员工人数
main_business: str | None = None # 主要业务及产品
business_scope: str | None = None # 经营范围
# ---------- 财务数据fina_indicator + 三大报表关键值,详情页按需懒加载) ----------
class StockFinanceRecordOut(BaseModel):
"""一行 = 一个报告期。金额单位元(展示层换算亿/万),比率与同比为百分数。"""
end_date: str # 报告期 YYYYMMDD
ann_date: str | None = None # 公告日 YYYYMMDD
eps: float | None = None # 基本每股收益(元)
bps: float | None = None # 每股净资产(元)
ocfps: float | None = None # 每股经营现金流净额(元)
roe: float | None = None # 净资产收益率 %
roe_dt: float | None = None # 扣非净资产收益率 %
grossprofit_margin: float | None = None # 销售毛利率 %
netprofit_margin: float | None = None # 销售净利率 %
debt_to_assets: float | None = None # 资产负债率 %
or_yoy: float | None = None # 营业收入同比 %
netprofit_yoy: float | None = None # 归母净利润同比 %
dt_netprofit_yoy: float | None = None # 扣非净利润同比 %
profit_dedt: float | None = None # 扣非净利润(元)
rd_exp: float | None = None # 研发投入(元)
total_revenue: float | None = None # 营业总收入(元)
operate_profit: float | None = None # 营业利润(元)
n_income_attr_p: float | None = None # 归母净利润(元)
total_assets: float | None = None # 总资产(元)
total_hldr_eqy: float | None = None # 归母股东权益(元)
n_cashflow_act: float | None = None # 经营现金流净额(元)
class StockFinanceOut(BaseModel):
ts_code: str
records: list[StockFinanceRecordOut] # 按报告期倒序records[0] = 最新报告期)
# ---------- 分红送股tushare dividend详情页按需懒加载 ----------
class StockDividendRecordOut(BaseModel):
end_date: str | None = None # 分红年度 YYYYMMDD
ann_date: str | None = None # 预案公告日
div_proc: str | None = None # 实施进度(预案/实施)
stk_div: float | None = None # 每股送转
stk_bo_rate: float | None = None # 每股送股比例
stk_co_rate: float | None = None # 每股转增比例
cash_div: float | None = None # 每股分红(税后,元)
cash_div_tax: float | None = None # 每股分红(税前,元)
base_share: float | None = None # 基准股本(万股)
record_date: str | None = None # 股权登记日
ex_date: str | None = None # 除权除息日K线标记锚点
pay_date: str | None = None # 派息日
div_listdate: str | None = None # 红股上市日
imp_ann_date: str | None = None # 实施公告日
class StockDividendOut(BaseModel):
ts_code: str
records: list[StockDividendRecordOut] # 按分红年度倒序;空列表 = 确认无分红
# ---------- 参考数据tushare 参考数据版块,详情页按需懒加载) ----------
class StockReferenceOut(BaseModel):
"""rows_json 快照直出records 为清洗后的 tushare 原始行,字段随 kind 而异。"""
ts_code: str
kind: str # 白名单见 app/data/reference.py REFERENCE_KINDS
records: list[dict[str, str | float | None]] = Field(default_factory=list)
# ---------- Auth ----------
class LoginRequest(BaseModel):
username: str = Field(min_length=1, max_length=64)
@@ -322,6 +405,45 @@ class StockFacetsResponse(BaseModel):
areas: list[FacetItemOut] = Field(default_factory=list)
# ---------- ETF 列表(全市场浏览;行情走 candles 底座,规模走东财快照) ----------
class EtfListItemOut(BaseModel):
ts_code: str # 510300.SH
symbol: str # 510300
name: str
exchange: str # SH/SZ
close: float | None = None # 最新收盘candles 未复权)
prev_close: float | None = None
pct_chg: float | None = None # 最新两根日线计算
amount: float | None = None # 最新成交额亿元candles 最新 bar
last_ts: datetime | None = None
turnover_rate: float | None = None # 换手率 %(东财快照)
total_mv: float | None = None # 总市值(亿元,东财快照)
circ_mv: float | None = None # 流通市值(亿元)
list_date: str | None = None # 上市日 YYYYMMDD首根K线日
watched: bool = False # 是否自选(当前用户)
class EtfListResponse(BaseModel):
total: int
items: list[EtfListItemOut]
class EtfSyncRequest(BaseModel):
full: bool = False # true = 忽略增量起点全量重拉(修数据用)
class EtfSyncStatus(BaseModel):
running: bool
step: str | None = None
total: int = 0 # 本次需拉 K 线的 ETF 数
done: int = 0
error: str | None = None
ready: bool = False # etf_basic 非空且已有日线
last_trade_date: datetime | None = None
last_synced_at: datetime | None = None
stats: dict[str, int] = Field(default_factory=dict) # etfs
# ---------- 用户偏好 / 自选股 / 提问历史 ----------
class PreferencesOut(BaseModel):
prefs: dict[str, object] = Field(default_factory=dict) # key -> JSON 值
@@ -413,3 +535,86 @@ class MarketOverviewResponse(BaseModel):
amount_history: list[AmountBarOut] = [] # 近 N 交易日两市成交额(旧 -> 新,末根可能盘中)
errors: list[str] = [] # 部分来源失败的说明(透明但不阻塞展示)
# ---------- 指数专题(国际指数卡片 + 指数详情) ----------
class GlobalIndexQuoteOut(BaseModel):
"""国际指数卡片index_global 最新收盘 + 45 日 spark"""
code: str # DJI / SPX / HSI ...
name: str # 道琼斯工业指数
region: str # americas | europe | asia前端分组
country: str # 美国 / 英国 / 日本 ...
close: float | None = None
change: float | None = None
pct_chg: float | None = None
trade_date: date | None = None
spark: list[float] = []
spark_dates: list[str] = []
class GlobalIndexListResponse(BaseModel):
updated_at: datetime
items: list[GlobalIndexQuoteOut] = []
errors: list[str] = []
class IndexBasicOut(BaseModel):
"""指数基本信息:国内 index_basic市场/发布方/基期基点),国际由静态表合成(国家/地区)。"""
ts_code: str
name: str
market: str | None = None # SSE / CSI / SZSE ...
publisher: str | None = None # 中证指数 / 上交所
category: str | None = None # 规模指数 / 综合指数
base_date: date | None = None # 基期
base_point: float | None = None # 基点
list_date: date | None = None # 发布日期
country: str | None = None # 国际指数:国家/地区
region: str | None = None # 国际指数americas/europe/asia
class IndexValuationPointOut(BaseModel):
"""大盘指数每日指标的一日index_dailybasic仅部分国内指数有数据"""
trade_date: date
pe: float | None = None
pe_ttm: float | None = None
pb: float | None = None
turnover_rate: float | None = None # 换手率 %
total_mv: float | None = None # 总市值tushare 文档标注万元,实测按元才对得上量级)
float_mv: float | None = None # 流通市值(元)
class IndexQuoteBriefOut(BaseModel):
"""详情页头部最新行情(收盘口径)。"""
close: float | None = None
change: float | None = None
pct_chg: float | None = None
open: float | None = None
high: float | None = None
low: float | None = None
pre_close: float | None = None
trade_date: date | None = None
spark: list[float] = []
spark_dates: list[str] = []
class IndexDetailResponse(BaseModel):
code: str
name: str
region: str # cn | americas | europe | asia
quote: IndexQuoteBriefOut
basic: IndexBasicOut | None = None
valuation: IndexValuationPointOut | None = None # 最新一日(接口不覆盖时 None
valuation_history: list[IndexValuationPointOut] = [] # 近 N 日PE 走势小图)
class IndexWeightItemOut(BaseModel):
con_code: str # 成分股 000001.SZ
name: str | None = None # 平安银行(本地 stock_basic 回填,缺则 None
weight: float # 权重 %
class IndexWeightsResponse(BaseModel):
trade_date: date
total: int # 成分股总数(返回 items 为按权重降序的子集)
items: list[IndexWeightItemOut] = []