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.

196 lines
5.4 KiB

"""
告警管理 API 路由
"""
from typing import Annotated, List, Optional
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session
from app.schemas import (
AlertCreate,
AlertResponse,
AlertUpdate,
ResponseData
)
from app.services.alert_service import AlertService
from app.api.v1.auth import get_current_user
from app.models import User
from app.db.init_db import get_sqlite_db
router = APIRouter()
@router.post("", response_model=ResponseData)
async def create_alert(
request: AlertCreate,
current_user: Annotated[User, Depends(get_current_user)],
db: Session = Depends(get_sqlite_db)
):
"""
创建价格告警
- **symbol**: 品种代码
- **condition_type**: 条件类型 (greater_than, less_than, equals)
- **condition_value**: 条件值
- **alert_type**: 告警类型 (price, percent_change)
"""
alert = AlertService.create_alert(
user_id=current_user.id,
symbol=request.symbol,
condition_type=request.condition_type,
condition_value=request.condition_value,
alert_type=request.alert_type
)
return ResponseData(
code=0,
message="success",
data={
"id": alert.id,
"symbol": alert.symbol,
"condition_type": alert.condition_type,
"condition_value": float(alert.condition_value),
"alert_type": alert.alert_type,
"status": alert.status,
"created_at": alert.created_at.isoformat()
}
)
@router.get("", response_model=ResponseData)
async def list_alerts(
status: Annotated[Optional[str], Query(description="告警状态")] = None,
current_user: Annotated[User, Depends(get_current_user)] = None,
db: Session = Depends(get_sqlite_db)
):
"""获取用户告警列表"""
alerts = AlertService.get_user_alerts(current_user.id, status)
return ResponseData(
code=0,
message="success",
data=[
{
"id": a.id,
"symbol": a.symbol,
"condition_type": a.condition_type,
"condition_value": float(a.condition_value),
"alert_type": a.alert_type,
"status": a.status,
"triggered_at": a.triggered_at.isoformat() if a.triggered_at else None,
"created_at": a.created_at.isoformat(),
"updated_at": a.updated_at.isoformat()
}
for a in alerts
]
)
@router.get("/{alert_id}", response_model=ResponseData)
async def get_alert(
alert_id: int,
current_user: Annotated[User, Depends(get_current_user)]
):
"""获取告警详情"""
alert = AlertService.get_alert_by_id(alert_id, current_user.id)
if not alert:
raise HTTPException(
status_code=404,
detail="Alert not found"
)
return ResponseData(
code=0,
message="success",
data={
"id": alert.id,
"symbol": alert.symbol,
"condition_type": alert.condition_type,
"condition_value": float(alert.condition_value),
"alert_type": alert.alert_type,
"status": alert.status,
"triggered_at": alert.triggered_at.isoformat() if alert.triggered_at else None,
"created_at": alert.created_at.isoformat(),
"updated_at": alert.updated_at.isoformat()
}
)
@router.put("/{alert_id}", response_model=ResponseData)
async def update_alert(
alert_id: int,
request: AlertUpdate,
current_user: Annotated[User, Depends(get_current_user)]
):
"""更新告警"""
alert = AlertService.update_alert(
alert_id=alert_id,
user_id=current_user.id,
condition_value=request.condition_value,
status=request.status
)
if not alert:
raise HTTPException(
status_code=404,
detail="Alert not found"
)
return ResponseData(
code=0,
message="success",
data={
"id": alert.id,
"symbol": alert.symbol,
"condition_type": alert.condition_type,
"condition_value": float(alert.condition_value),
"alert_type": alert.alert_type,
"status": alert.status,
"updated_at": alert.updated_at.isoformat()
}
)
@router.delete("/{alert_id}", response_model=ResponseData)
async def delete_alert(
alert_id: int,
current_user: Annotated[User, Depends(get_current_user)]
):
"""删除告警"""
success = AlertService.delete_alert(alert_id, current_user.id)
if not success:
raise HTTPException(
status_code=404,
detail="Alert not found"
)
return ResponseData(
code=0,
message="success",
data={"id": alert_id, "status": "deleted"}
)
@router.post("/{alert_id}/trigger", response_model=ResponseData)
async def trigger_alert(
alert_id: int,
current_user: Annotated[User, Depends(get_current_user)]
):
"""手动触发告警 (测试用)"""
alert = AlertService.trigger_alert(alert_id)
if not alert:
raise HTTPException(
status_code=404,
detail="Alert not found"
)
return ResponseData(
code=0,
message="success",
data={
"id": alert.id,
"status": alert.status,
"triggered_at": alert.triggered_at.isoformat()
}
)