feat: KPI详情历史数据对齐元数据 — 目标值/偏差%/红黄绿判定/单位/数据批次

- 后端: get_kpi的values附带target_value/deviation_pct/level/score/unit
  判定对齐工作台语义: 正向≥0.9绿/≥0.7黄/否则红; 反向≤目标绿/≤1.1倍黄/否则红
- 前端: 历史数据表格新增目标值/偏差/判定列, 实际值带单位+红黄着色, 新增数据批次列
- 验证: 渠补率2月84%=黄(超5%), 5月88.3%=红(超10.4%), 收入全部red(远低于1200万目标)
This commit is contained in:
Hermes CI Fix
2026-08-26 09:27:12 +08:00
parent 9d712046f3
commit a253eadeb0
2 changed files with 69 additions and 9 deletions
+36 -5
View File
@@ -485,21 +485,52 @@ def get_kpi(kpi_id: int, db: Session = Depends(get_db), entity_id: int = Depends
result = kpi_to_dict(kpi)
# 附带历史数据(前端KPI详情"历史数据"Tab依赖)
# 2026-08-26修复: 原实现只返回定义信息,values缺失导致历史数据Tab空白
# 2026-08-26增强: values对齐KPI元数据(目标值/偏差/红黄绿判定/单位)
vals = db.query(KPIValue).filter(
KPIValue.kpi_id == kpi_id,
KPIValue.actual_value.isnot(None),
).order_by(KPIValue.period.asc()).all()
result["values"] = [
{
is_reverse = kpi.kpi_code in REVERSE_INDICATORS
target = kpi.target_value
result["values"] = []
for v in vals:
# 判定红黄绿(对齐工作台语义:正向≥0.9绿/≥0.7黄/否则红;反向≤目标绿/≤1.1倍黄/否则红)
level = "info"
score = None
if target and v.actual_value is not None:
if is_reverse:
if v.actual_value <= target:
level = "green"
elif v.actual_value <= target * 1.1:
level = "yellow"
else:
level = "red"
else:
ratio = v.actual_value / target
if ratio >= 0.9:
level = "green"
elif ratio >= 0.7:
level = "yellow"
else:
level = "red"
score, _ = _calc_five_tier_score(v.actual_value, target, is_reverse=is_reverse)
# 偏差率(相对目标)
deviation = None
if target and target != 0 and v.actual_value is not None:
deviation = round((v.actual_value - target) / target * 100, 1)
result["values"].append({
"id": v.id,
"period": v.period,
"actual_value": v.actual_value,
"target_value": target,
"unit": kpi.unit or "",
"deviation_pct": deviation,
"level": level,
"score": score,
"source_type": v.source_type,
"data_status": v.data_status,
"source_batch": v.source_batch,
}
for v in vals
]
})
return result