包含前后端完整代码: - 前端:Vue3+Vite+ElementPlus - 后端:FastAPI+SQLAlchemy - 模块:驾驶舱/KPI/战略地图/预警/预算/成本/预测/改善行动 - 当前版本:v1.0.0
77 lines
2.8 KiB
Python
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": "正常"}
|