from __future__ import annotations from sqlalchemy.orm import Session from app.db.repositories import diagnosis as diagnosis_repo from app.db.repositories import evaluation as evaluation_repo from app.db.repositories import monitoring as monitoring_repo from app.db.repositories import work_order as work_order_repo from app.schemas.dashboard import DashboardOverview, KpiCard from app.services.mine_service import resolve_mine def get_dashboard_overview( db: Session, mine_id: str | None = None, ) -> DashboardOverview: mine = resolve_mine(db, mine_id) monitoring = monitoring_repo.monitoring_overview(db, mine.id) defects = diagnosis_repo.result_summary(db, mine.id) work_orders = work_order_repo.status_summary(db, mine.id) runs = evaluation_repo.list_runs(db, mine.id, limit=1) latest_run = runs[0] if runs else None kpis = [ KpiCard( key="sensors", label="传感器总数", value=monitoring["sensor_count"], unit="台", status="normal", ), KpiCard( key="online_rate", label="设备在线率", value=round( monitoring["online_sensor_count"] / max(monitoring["sensor_count"], 1) * 100, 1, ), unit="%", status="normal" if monitoring["online_sensor_count"] >= monitoring["sensor_count"] * 0.95 else "warning", ), KpiCard( key="alarms", label="未闭环告警", value=monitoring["open_alarm_count"], unit="条", status="danger" if monitoring["high_alarm_count"] else "warning", ), KpiCard( key="high_defects", label="高风险缺陷", value=defects.get("high", 0), unit="项", status="danger" if defects.get("high", 0) else "normal", ), KpiCard( key="score", label="综合评价得分", value=latest_run.total_score if latest_run and latest_run.total_score else "--", unit="分", status="normal", ), ] return DashboardOverview( mine_id=mine.id, mine_name=mine.name, kpis=kpis, data_source_status=[ { "count": monitoring["data_source_count"], "online": monitoring["online_source_count"], "status": "online" if monitoring["online_source_count"] == monitoring["data_source_count"] else "partial", } ], diagnosis_summary=defects, evaluation_summary={ "score": latest_run.total_score if latest_run else None, "grade": latest_run.grade if latest_run else "", "run_no": latest_run.run_no if latest_run else "", }, open_work_order_count=sum( work_orders.get(status, 0) for status in ("pending", "processing", "review") ), )