Files
cma-management/backend/app/api/alert_rules.py
T
Hermes CI Fix 3dddd36866 init: 管理会计OS初始代码
包含前后端完整代码:
- 前端:Vue3+Vite+ElementPlus
- 后端:FastAPI+SQLAlchemy
- 模块:驾驶舱/KPI/战略地图/预警/预算/成本/预测/改善行动
- 当前版本:v1.0.0
2026-05-28 17:32:22 +08:00

77 lines
2.8 KiB
Python

"""预警规则配置"""
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": "正常"}