dashboard_service.py 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. from __future__ import annotations
  2. from sqlalchemy.orm import Session
  3. from app.db.repositories import diagnosis as diagnosis_repo
  4. from app.db.repositories import evaluation as evaluation_repo
  5. from app.db.repositories import monitoring as monitoring_repo
  6. from app.db.repositories import work_order as work_order_repo
  7. from app.schemas.dashboard import DashboardOverview, KpiCard
  8. from app.services.mine_service import resolve_mine
  9. def get_dashboard_overview(
  10. db: Session,
  11. mine_id: str | None = None,
  12. ) -> DashboardOverview:
  13. mine = resolve_mine(db, mine_id)
  14. monitoring = monitoring_repo.monitoring_overview(db, mine.id)
  15. defects = diagnosis_repo.result_summary(db, mine.id)
  16. work_orders = work_order_repo.status_summary(db, mine.id)
  17. runs = evaluation_repo.list_runs(db, mine.id, limit=1)
  18. latest_run = runs[0] if runs else None
  19. kpis = [
  20. KpiCard(
  21. key="sensors",
  22. label="传感器总数",
  23. value=monitoring["sensor_count"],
  24. unit="台",
  25. status="normal",
  26. ),
  27. KpiCard(
  28. key="online_rate",
  29. label="设备在线率",
  30. value=round(
  31. monitoring["online_sensor_count"] / max(monitoring["sensor_count"], 1) * 100,
  32. 1,
  33. ),
  34. unit="%",
  35. status="normal"
  36. if monitoring["online_sensor_count"] >= monitoring["sensor_count"] * 0.95
  37. else "warning",
  38. ),
  39. KpiCard(
  40. key="alarms",
  41. label="未闭环告警",
  42. value=monitoring["open_alarm_count"],
  43. unit="条",
  44. status="danger" if monitoring["high_alarm_count"] else "warning",
  45. ),
  46. KpiCard(
  47. key="high_defects",
  48. label="高风险缺陷",
  49. value=defects.get("high", 0),
  50. unit="项",
  51. status="danger" if defects.get("high", 0) else "normal",
  52. ),
  53. KpiCard(
  54. key="score",
  55. label="综合评价得分",
  56. value=latest_run.total_score if latest_run and latest_run.total_score else "--",
  57. unit="分",
  58. status="normal",
  59. ),
  60. ]
  61. return DashboardOverview(
  62. mine_id=mine.id,
  63. mine_name=mine.name,
  64. kpis=kpis,
  65. data_source_status=[
  66. {
  67. "count": monitoring["data_source_count"],
  68. "online": monitoring["online_source_count"],
  69. "status": "online"
  70. if monitoring["online_source_count"] == monitoring["data_source_count"]
  71. else "partial",
  72. }
  73. ],
  74. diagnosis_summary=defects,
  75. evaluation_summary={
  76. "score": latest_run.total_score if latest_run else None,
  77. "grade": latest_run.grade if latest_run else "",
  78. "run_no": latest_run.run_no if latest_run else "",
  79. },
  80. open_work_order_count=sum(
  81. work_orders.get(status, 0)
  82. for status in ("pending", "processing", "review")
  83. ),
  84. )