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
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()
|
|
}
|
|
)
|