feat: 预测性成本智能MVP — KPI趋势预测引擎(线性回归/移动平均)+API+前端Tab+pytest覆盖

This commit is contained in:
Hermes CI Fix
2026-08-25 00:10:46 +08:00
parent fb9eba38a8
commit 13aa153875
6 changed files with 863 additions and 1 deletions
+50
View File
@@ -714,3 +714,53 @@ def api_growth_quality(request: Request, data: dict):
}
except Exception as e:
raise HTTPException(400, f"增长质量诊断失败: {str(e)}")
# ── KPI趋势预测(预测性成本智能 MVP) ────────────────────────────
from app.utils.kpi_forecast_engine import ( # noqa: E402
MODELS, forecast_kpi, forecast_finance_kpis,
)
@router.get("/kpi-forecast")
def api_kpi_forecast(
kpi_code: str,
periods: int = 3,
model: str = "linear",
entity_id: int = Depends(get_entity_id),
db: Session = Depends(get_db),
):
"""单个财务KPI预测 — 线性回归/移动平均,多租户隔离(entity_id 权限校验)"""
if periods < 0 or periods > 24:
raise HTTPException(400, "periods 必须在 0~24 之间")
if model not in MODELS:
raise HTTPException(400, f"不支持的模型: {model},可选: {'/'.join(MODELS)}")
result = forecast_kpi(entity_id, kpi_code, db, periods=periods, model=model)
if result is None:
raise HTTPException(
404,
f"KPI {kpi_code} 在企业 entity_id={entity_id} 下不存在,或历史数据不足(至少2条)",
)
return result
@router.get("/kpi-forecast/finance")
def api_kpi_forecast_finance(
periods: int = 3,
model: str = "linear",
entity_id: int = Depends(get_entity_id),
db: Session = Depends(get_db),
):
"""批量预测该企业全部财务维度KPI(历史≥3条),按可预测性排序"""
if periods < 0 or periods > 24:
raise HTTPException(400, "periods 必须在 0~24 之间")
if model not in MODELS:
raise HTTPException(400, f"不支持的模型: {model},可选: {'/'.join(MODELS)}")
results = forecast_finance_kpis(entity_id, db, periods=periods, model=model)
return {
"entity_id": entity_id,
"model": model,
"periods": periods,
"total": len(results),
"data": results,
}