"""预警规则配置""" from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy.orm import Session from app.database import get_db from app.auth_middleware import require_auth, require_role from app.models import KPIAlert, KPIDefinition, KPIValue router = APIRouter(prefix="/api/cma/alert-rules", tags=["预警规则"], dependencies=[Depends(require_role("ceo", "finance"))], ) @router.get("") def list_rules(kpi_id: int = None, db: Session = Depends(get_db)): """获取预警规则(从KPI定义中读取阈值配置)""" query = db.query(KPIDefinition).filter(KPIDefinition.status == "active") if kpi_id: query = query.filter(KPIDefinition.id == kpi_id) rules = [] for k in query.all(): if k.threshold_green or k.threshold_yellow or k.threshold_red: rules.append({ "kpi_id": k.id, "kpi_name": k.kpi_name, "threshold_green": k.threshold_green, "threshold_yellow": k.threshold_yellow, "threshold_red": k.threshold_red, }) return {"data": rules} @router.post("/check/{kpi_id}") def check_alert(kpi_id: int, db: Session = Depends(get_db)): """检查指定KPI是否需要触发预警""" kpi = db.query(KPIDefinition).filter(KPIDefinition.id == kpi_id).first() if not kpi: raise HTTPException(404, "KPI不存在") latest = db.query(KPIValue).filter(KPIValue.kpi_id == kpi_id).order_by(KPIValue.period.desc()).first() if not latest or not latest.actual_value: return {"alert": False, "message": "无数据"} val = latest.actual_value level = "green" # 简单阈值判定 red = kpi.threshold_red yellow = kpi.threshold_yellow # 红灯判断: <3000000 表示低于300万触发红灯 if red: if "<" in red: limit = float(red.split("<")[1].strip()) if val < limit: level = "red" elif ">" in red: limit = float(red.split(">")[1].strip()) if val > limit: level = "red" # 黄灯判断(红灯未触发时) if level == "green" and yellow: if "<" in yellow: limit = float(yellow.split("<")[1].strip()) if val < limit: level = "yellow" elif ">" in yellow: limit = float(yellow.split(">")[1].strip()) if val > limit: level = "yellow" if level != "green": alert = KPIAlert( kpi_id=kpi_id, kpi_value_id=latest.id, alert_level=level, alert_message=f"{kpi.kpi_name}当前值为{val},触发{level}预警", ) db.add(alert) db.commit() return {"alert": True, "level": level, "message": alert.alert_message} return {"alert": False, "level": "green", "message": "正常"}