feat: 添加飞书用户模块和订阅功能支持 - 新增feishu_users模块用于处理飞书用户身份验证和权限管理 - 新增subscriptions模块用于处理订阅相关功能 - 新增personalization模块用于个性化服务 - 在alembic迁移配置中注册新的模型模块 - 在API路由器中添加feishu_users和subscriptions路由 - 实现事件调度服务的改进,包括错误处理和状态更新优化 - 添加飞书命令处理的权限检查机制 - 实现飞书应用票据事件处理 - 改进审计日志记录功能 ```
126 lines
3.7 KiB
Python
126 lines
3.7 KiB
Python
from datetime import date
|
|
from typing import Literal
|
|
|
|
from fastapi import APIRouter, Depends
|
|
from pydantic import BaseModel
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.core.database import get_db
|
|
from app.core.background.task_queue.market import enqueue_market_report
|
|
from app.core.security import ApiPrincipal, require_api_key
|
|
from app.modules.market.service import MarketService
|
|
|
|
router = APIRouter(dependencies=[Depends(require_api_key)])
|
|
|
|
|
|
class WatchlistRequest(BaseModel):
|
|
symbol: str
|
|
|
|
|
|
class MarketReportRequest(BaseModel):
|
|
report_type: Literal["premarket", "close", "weekly"]
|
|
reference_date: date | None = None
|
|
force: bool = False
|
|
|
|
|
|
@router.get("/overview")
|
|
def overview(
|
|
trade_date: date | None = None,
|
|
include_ai: bool = False,
|
|
db: Session = Depends(get_db),
|
|
principal: ApiPrincipal = Depends(require_api_key),
|
|
) -> dict:
|
|
return MarketService(db).market_overview(trade_date, include_ai, principal.actor)
|
|
|
|
|
|
@router.get("/stocks/{symbol}/analysis")
|
|
def stock_analysis(
|
|
symbol: str,
|
|
include_ai: bool = False,
|
|
db: Session = Depends(get_db),
|
|
principal: ApiPrincipal = Depends(require_api_key),
|
|
) -> dict:
|
|
return MarketService(db).stock_analysis(symbol, include_ai, principal.actor)
|
|
|
|
|
|
@router.get("/weekly")
|
|
def weekly_overview(
|
|
reference_date: date | None = None,
|
|
include_ai: bool = False,
|
|
db: Session = Depends(get_db),
|
|
principal: ApiPrincipal = Depends(require_api_key),
|
|
) -> dict:
|
|
return MarketService(db).weekly_overview(reference_date, include_ai, principal.actor)
|
|
|
|
|
|
@router.get("/industries/{industry}/analysis")
|
|
def industry_analysis(industry: str, db: Session = Depends(get_db)) -> dict:
|
|
return MarketService(db).industry_analysis(industry)
|
|
|
|
|
|
@router.get("/stocks/compare/{first}/{second}")
|
|
def compare_stocks(first: str, second: str, db: Session = Depends(get_db)) -> dict:
|
|
return MarketService(db).compare_stocks([first, second])
|
|
|
|
|
|
@router.get("/macro")
|
|
def macro_overview(
|
|
include_ai: bool = False,
|
|
db: Session = Depends(get_db),
|
|
principal: ApiPrincipal = Depends(require_api_key),
|
|
) -> dict:
|
|
service = MarketService(db)
|
|
return (
|
|
service.macro_analysis(include_ai=True, actor=principal.actor)
|
|
if include_ai
|
|
else service.macro_overview()
|
|
)
|
|
|
|
|
|
@router.get("/announcements")
|
|
def announcements(
|
|
symbol: str | None = None,
|
|
start_date: date | None = None,
|
|
limit: int = 50,
|
|
db: Session = Depends(get_db),
|
|
) -> dict:
|
|
return MarketService(db).announcements(symbol, start_date, limit)
|
|
|
|
|
|
@router.post("/sync/daily")
|
|
def sync_daily(trade_date: date, db: Session = Depends(get_db)) -> dict:
|
|
return MarketService(db).sync_daily(trade_date)
|
|
|
|
|
|
@router.post("/sync/macro")
|
|
def sync_macro(reference_date: date | None = None, db: Session = Depends(get_db)) -> dict:
|
|
return MarketService(db).sync_macro(reference_date)
|
|
|
|
|
|
@router.post("/sync/announcements")
|
|
def sync_announcements(
|
|
start_date: date, end_date: date, db: Session = Depends(get_db)
|
|
) -> dict:
|
|
return {"processed": MarketService(db).sync_announcements(start_date, end_date)}
|
|
|
|
|
|
@router.post("/reports/enqueue")
|
|
def enqueue_report(payload: MarketReportRequest) -> dict:
|
|
return enqueue_market_report(payload.report_type, payload.reference_date, payload.force)
|
|
|
|
|
|
@router.post("/watchlist")
|
|
def add_watchlist(
|
|
payload: WatchlistRequest,
|
|
db: Session = Depends(get_db),
|
|
principal: ApiPrincipal = Depends(require_api_key),
|
|
) -> dict:
|
|
return MarketService(db).add_watchlist(principal.actor, payload.symbol)
|
|
|
|
|
|
@router.get("/watchlist")
|
|
def watchlist(
|
|
db: Session = Depends(get_db), principal: ApiPrincipal = Depends(require_api_key)
|
|
) -> dict:
|
|
return {"items": MarketService(db).watchlist(principal.actor)}
|