diff --git a/backend/main.py b/backend/main.py index 18b6f45..8cd4e5d 100644 --- a/backend/main.py +++ b/backend/main.py @@ -540,3 +540,66 @@ def stats_top_chargers(limit: int = 10): ] finally: db.close() + + +@app.get("/api/stats/charger-error-codes") +def stats_charger_error_codes(charger_limit: int = 10, code_limit: int = 6): + """충전기별 에러코드 누적 건수 Top N (에러코드 입력된 신고 기준).""" + from database import SessionLocal + from sqlalchemy import text + from collections import defaultdict + db = SessionLocal() + try: + rows = db.execute(text(""" + SELECT rep.charger_id, + COALESCE(c.station_name, rep.charger_id) AS station_name, + COALESCE(c.name, '') AS charger_name, + TRIM(rep.error_code) AS error_code, + COUNT(*) AS cnt + FROM reports rep + LEFT JOIN chargers c ON c.id = rep.charger_id + WHERE rep.error_code IS NOT NULL + AND TRIM(rep.error_code) != '' + GROUP BY rep.charger_id, c.station_name, c.name, TRIM(rep.error_code) + """)).fetchall() + + if not rows: + return {"chargers": [], "error_codes": []} + + charger_info = {} + code_totals = defaultdict(int) + + for row in rows: + cid, sname, cname, ecode, cnt = row + cnt = int(cnt) + if cid not in charger_info: + charger_info[cid] = {"station_name": sname, "charger_name": cname, + "total": 0, "errors": {}} + charger_info[cid]["total"] += cnt + charger_info[cid]["errors"][ecode] = cnt + code_totals[ecode] += cnt + + top_chargers = sorted(charger_info.items(), key=lambda x: -x[1]["total"])[:charger_limit] + top_codes = [c for c, _ in sorted(code_totals.items(), key=lambda x: -x[1])[:code_limit]] + + result = [] + for cid, info in reversed(top_chargers): # 역순: 차트에서 1위가 위에 + label = info["station_name"] + if info["charger_name"]: + label += f" ({info['charger_name']})" + if len(label) > 22: + label = label[:20] + "…" + errors = info["errors"] + other = sum(cnt for code, cnt in errors.items() if code not in top_codes) + entry = {"charger_id": cid, "label": label, "total": info["total"]} + for code in top_codes: + entry[code] = errors.get(code, 0) + if other: + entry["기타"] = other + result.append(entry) + + has_other = any(r.get("기타", 0) > 0 for r in result) + all_codes = top_codes + (["기타"] if has_other else []) + return {"chargers": result, "error_codes": all_codes} + finally: + db.close() diff --git a/frontend/static/pages/admin/dashboard.html b/frontend/static/pages/admin/dashboard.html index 0a87fad..cbe9555 100644 --- a/frontend/static/pages/admin/dashboard.html +++ b/frontend/static/pages/admin/dashboard.html @@ -227,6 +227,17 @@ + +