diff --git a/backend/app/api/kpis.py b/backend/app/api/kpis.py index 0c21d3f8..a67a5636 100644 --- a/backend/app/api/kpis.py +++ b/backend/app/api/kpis.py @@ -101,21 +101,38 @@ def get_kpi_categories(current_user = Depends(require_auth), db: Session = Depen # KPI-5: 五档评分引擎(静态路由必须在动态/{kpi_id}之前) # ============================================================ -def _calc_five_tier_score(current_value, target_value): - """五档评分:1-5分""" +REVERSE_INDICATORS = ['C_REBATE_RATE', 'P_BUG_RATE', 'P_REWORK_PCT', 'F_DEBT_RATIO', + 'P_QUALITY_RATE', 'F_COST_RATIO', 'F_INTEREST_COVER', 'F_QUICK_RATIO'] + + +def _calc_five_tier_score(current_value, target_value, is_reverse=False): + """五档评分:1-5分(支持正反向指标)""" if current_value is None or target_value is None or target_value == 0: return None, "info" ratio = current_value / target_value - if ratio >= 1.2: - return 5, "success" # 卓越 - elif ratio >= 1.0: - return 4, "success" # 达标 - elif ratio >= 0.8: - return 3, "warning" # 预警 - elif ratio >= 0.5: - return 2, "danger" # 危险 + if is_reverse: + # 反向指标:实际值越低越好 + if ratio <= 0.5: + return 5, "success" # 远低于目标→卓越 + elif ratio <= 0.8: + return 4, "success" # 低于目标→达标 + elif ratio <= 1.0: + return 3, "warning" # 接近目标→预警 + elif ratio <= 1.2: + return 2, "danger" # 超过目标→危险 + else: + return 1, "danger" # 远超目标→失效 else: - return 1, "danger" # 失效 + if ratio >= 1.2: + return 5, "success" # 卓越 + elif ratio >= 1.0: + return 4, "success" # 达标 + elif ratio >= 0.8: + return 3, "warning" # 预警 + elif ratio >= 0.5: + return 2, "danger" # 危险 + else: + return 1, "danger" # 失效 @router.get("/score") @@ -154,7 +171,7 @@ def get_kpi_score( latest_val = val_query.order_by(KPIValue.period.desc()).first() current_val = latest_val.actual_value if latest_val else None - score, status = _calc_five_tier_score(current_val, k.target_value) + score, status = _calc_five_tier_score(current_val, k.target_value, is_reverse=(k.kpi_code in REVERSE_INDICATORS)) kpi_scores.append({ "kpi_id": k.id,