fix: 行动方案库统计卡片—补全API+overdue计算
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
"""预警 API"""
|
||||
from fastapi import APIRouter, Depends, Query
|
||||
from fastapi import APIRouter, Depends, Query, HTTPException
|
||||
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, OperationLog
|
||||
from app.models import KPIAlert, OperationLog, ActionPlan
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger("cma.alerts")
|
||||
@@ -24,17 +24,105 @@ def list_alerts(status: str = None, page: int = Query(1, ge=1), db: Session = De
|
||||
@router.post("/{alert_id}/resolve")
|
||||
def resolve_alert(alert_id: int, data: dict, db: Session = Depends(get_db)):
|
||||
alert = db.query(KPIAlert).filter(KPIAlert.id == alert_id).first()
|
||||
if alert:
|
||||
alert.status = "resolved"
|
||||
alert.resolution = data.get("resolution", "")
|
||||
alert.assignee = data.get("assignee", alert.assignee)
|
||||
from datetime import datetime; alert.resolved_at = datetime.now()
|
||||
if not alert:
|
||||
raise HTTPException(404, "预警不存在")
|
||||
alert.status = "resolved"
|
||||
alert.resolution = data.get("resolution", "")
|
||||
alert.assignee = data.get("assignee", alert.assignee)
|
||||
from datetime import datetime; alert.resolved_at = datetime.now()
|
||||
db.commit()
|
||||
db.refresh(alert)
|
||||
return {
|
||||
"message": "已处理",
|
||||
"assignee": alert.assignee,
|
||||
"alert": {c.name: getattr(alert, c.name) for c in KPIAlert.__table__.columns},
|
||||
"suggest_create_action_plan": alert.alert_level == "red",
|
||||
}
|
||||
|
||||
|
||||
@router.post("/{alert_id}/process")
|
||||
def process_alert(alert_id: int, data: dict, db: Session = Depends(get_db)):
|
||||
"""标记预警为处理中"""
|
||||
alert = db.query(KPIAlert).filter(KPIAlert.id == alert_id).first()
|
||||
if not alert:
|
||||
raise HTTPException(404, "预警不存在")
|
||||
if alert.status == "resolved":
|
||||
raise HTTPException(400, "已处理的预警不能重复处理")
|
||||
assignee = data.get("assignee")
|
||||
if not assignee:
|
||||
raise HTTPException(400, "缺少处理人")
|
||||
alert.status = "processing"
|
||||
alert.assignee = assignee
|
||||
db.commit()
|
||||
db.refresh(alert)
|
||||
return {"message": "已标记为处理中", "alert": {c.name: getattr(alert, c.name) for c in KPIAlert.__table__.columns}}
|
||||
|
||||
|
||||
@router.post("/{alert_id}/escalate")
|
||||
def escalate_alert(alert_id: int, data: dict, db: Session = Depends(get_db)):
|
||||
"""升级预警级别"""
|
||||
alert = db.query(KPIAlert).filter(KPIAlert.id == alert_id).first()
|
||||
if not alert:
|
||||
raise HTTPException(404, "预警不存在")
|
||||
assignee = data.get("assignee")
|
||||
if not assignee:
|
||||
raise HTTPException(400, "缺少处理人")
|
||||
if alert.status == "resolved":
|
||||
raise HTTPException(400, "已处理的预警不能升级")
|
||||
if alert.alert_level != "red":
|
||||
alert.alert_level = "red"
|
||||
alert.assignee = assignee
|
||||
db.commit()
|
||||
return {"message": "已处理", "assignee": alert.assignee}
|
||||
db.refresh(alert)
|
||||
return {"message": "已升级", "alert": {c.name: getattr(alert, c.name) for c in KPIAlert.__table__.columns}}
|
||||
|
||||
|
||||
@router.get("/check-timeout")
|
||||
def check_alert_timeout(db: Session = Depends(get_db)):
|
||||
"""超时预警检测 — 超过24小时未处理的pending预警自动升级为红色"""
|
||||
from datetime import datetime, timedelta
|
||||
cutoff = datetime.now() - timedelta(hours=24)
|
||||
timeout_alerts = db.query(KPIAlert).filter(
|
||||
KPIAlert.status == "pending",
|
||||
KPIAlert.created_at < cutoff,
|
||||
KPIAlert.alert_level != "red",
|
||||
).all()
|
||||
upgraded_count = 0
|
||||
for alert in timeout_alerts:
|
||||
alert.alert_level = "red"
|
||||
alert.status = "processing"
|
||||
upgraded_count += 1
|
||||
if upgraded_count:
|
||||
db.commit()
|
||||
return {"total_timeout": len(timeout_alerts), "upgraded_count": upgraded_count}
|
||||
|
||||
|
||||
@router.post("/{alert_id}/create-action-plan")
|
||||
def create_action_plan_from_alert(alert_id: int, data: dict, db: Session = Depends(get_db)):
|
||||
"""从预警创建改善行动计划"""
|
||||
alert = db.query(KPIAlert).filter(KPIAlert.id == alert_id).first()
|
||||
if not alert:
|
||||
raise HTTPException(404, "预警不存在")
|
||||
if alert.action_plan_linked_id:
|
||||
raise HTTPException(400, "已关联改善计划")
|
||||
plan = ActionPlan(
|
||||
alert_id=alert.id,
|
||||
kpi_id=alert.kpi_id,
|
||||
title=f"改善: {alert.alert_message}",
|
||||
assignee=data.get("assignee", ""),
|
||||
priority="high" if alert.alert_level == "red" else "medium",
|
||||
created_by=data.get("created_by", ""),
|
||||
)
|
||||
db.add(plan)
|
||||
db.commit()
|
||||
db.refresh(plan)
|
||||
alert.action_plan_linked_id = plan.id
|
||||
db.commit()
|
||||
return {"message": "改善行动计划已创建", "plan_id": plan.id, "priority": plan.priority}
|
||||
|
||||
|
||||
# ──────────────────────────────────────────────
|
||||
# 功能4: 风险矩阵热力图 (CMA P2 - ERM框架、风险识别四象限)
|
||||
# ──────────────────────────────────────────────
|
||||
|
||||
RISK_MATRIX_DATA = {
|
||||
"hanke": {
|
||||
|
||||
Reference in New Issue
Block a user