From 7b5795bf07a9c69c169f75189ef8dcd1606ea7ff Mon Sep 17 00:00:00 2001 From: Hermes CI Fix Date: Sat, 15 Aug 2026 23:02:48 +0800 Subject: [PATCH] =?UTF-8?q?fix(P0):=20=E6=9D=9C=E9=82=A6=E5=88=86=E6=9E=90?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E5=8E=BB=E9=99=A4=E7=A1=AC=E7=BC=96=E7=A0=81?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E6=95=B0=E6=8D=AE=20=E2=80=94=20equity=20114?= =?UTF-8?q?=E4=B8=87=E2=86=92358.4=E4=B8=87=E3=80=81ROE=2012.38%=E2=86=923?= =?UTF-8?q?.95%=E3=80=81=E6=96=B0=E5=A2=9Ehanke=E5=88=86=E6=94=AF=E8=AF=BB?= =?UTF-8?q?DB(KPI=202026H1=20verified)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 _get_dupont_kpi 辅助函数: 按 entity_id+kpi_code 查 kpi_definitions→kpi_values(period=2026H1, verified) - bohai: 净权益修正为358.4万(来源 bohai_comprehensive_analysis_2026.md 试算平衡表),财务杠杆4.68x→1.49x,负债率78.6%→32.8%结构健康,ROE≈3.94%,删除误导性加杠杆建议 - hanke: 新增分支,从DB读 F_REVENUE=713.27/F_NET_PROFIT=-90.86,净利率-12.74%,资产/权益缺失时factor返回null标注数据待补充,prev_roe返回null(前端兼容显示无对比),接口返回200 --- backend/app/api/reports.py | 113 ++++++++++++++++++++++++++++++++++--- 1 file changed, 105 insertions(+), 8 deletions(-) diff --git a/backend/app/api/reports.py b/backend/app/api/reports.py index 4c52745b..357e0040 100644 --- a/backend/app/api/reports.py +++ b/backend/app/api/reports.py @@ -1837,6 +1837,23 @@ def export_statutory_reports( ) +def _get_dupont_kpi(db: Session, entity_id: int, kpi_code: str, period: str = "2026H1"): + """杜邦分析 KPI 读取 — 按 entity + kpi_code 查 kpi_definitions → kpi_values + 取 period 期间 data_status=='verified' 的最新一条(order_by id desc),读不到返回 None""" + kpi = db.query(KPIDefinition).filter( + KPIDefinition.entity_id == entity_id, + KPIDefinition.kpi_code == kpi_code, + ).first() + if not kpi: + return None + v = db.query(KPIValue).filter( + KPIValue.kpi_id == kpi.id, + KPIValue.period == period, + KPIValue.data_status == "verified", + ).order_by(KPIValue.id.desc()).first() + return v.actual_value if v else None + + @router.get("/dupont") def get_dupont_analysis( entity: str = Query("bohai"), @@ -1844,15 +1861,24 @@ def get_dupont_analysis( ): """杜邦分析 — ROE三级拆解 (CMA P2)""" if entity == "bohai": - net_profit = 14.1 # 万 - revenue = 383 # 万 - total_assets = 533 # 万 - equity = 114 # 万 + # 博海标准KPI(F_REVENUE/F_NET_PROFIT)无verified值 → 优先DB读,读不到回退文档确认常量 + net_profit = _get_dupont_kpi(db, 2, "F_NET_PROFIT") + if net_profit is None: + # 来源: bohai_comprehensive_analysis_2026.md 试算平衡表 2026H1(=141,324元) + net_profit = 14.13 # 万 + revenue = _get_dupont_kpi(db, 2, "F_REVENUE") + if revenue is None: + # 来源: bohai_comprehensive_analysis_2026.md 试算平衡表 2026H1(=3,836,026元) + revenue = 383.6 # 万 + # 来源: bohai_comprehensive_analysis_2026.md 试算平衡表 2026H1 + total_assets = 533 # 万(DB无对应KPI,文档口径) + equity = 358.4 # 万(=3,583,851元)⚠️ 核心修正点:原硬编码114万错误,导致ROE高估约3倍 net_profit_margin = round(net_profit / revenue * 100, 2) asset_turnover = round(revenue / total_assets, 4) financial_leverage = round(total_assets / equity, 2) roe = round(net_profit_margin / 100 * asset_turnover * financial_leverage * 100, 2) + debt_ratio = round((total_assets - equity) / total_assets * 100, 1) # 上期对比(模拟上一期数据) prev_roe = round(11.2, 2) @@ -1887,8 +1913,8 @@ def get_dupont_analysis( "value": financial_leverage, "label": "财务杠杆", "desc": "总资产/净资产", - "status": "🟡" if financial_leverage > 3 else "✅", - "assessment": "负债率78.6%,偏高但可控", + "status": "✅" if financial_leverage < 3 else "🟡", + "assessment": f"负债率{debt_ratio}%,结构健康", "raw": {"total_assets": total_assets, "equity": equity}, }, }, @@ -1899,8 +1925,79 @@ def get_dupont_analysis( "equity": equity, }, "insight": { - "improvement": "提高周转率或利润率,而非加杠杆", - "detail": f"净利润率{net_profit_margin}%偏低,资产周转率{asset_turnover}x中等,财务杠杆{financial_leverage}x偏高。改善方向:提升毛利率或加快库存周转。", + "improvement": "提升毛利率、控制销售折扣/现金折扣支出,而非加杠杆", + "detail": f"财务杠杆{financial_leverage}x健康,ROE {roe}%偏低主要因净利润率{net_profit_margin}%偏低。改善方向:提升毛利率、控制销售折扣/现金折扣支出(合计约110万侵蚀毛利)。", + }, + } + + if entity == "hanke": + # 酣客: F_REVENUE/F_NET_PROFIT 从DB读 verified 值(2026H1: 713.27 / -90.86) + revenue = _get_dupont_kpi(db, 1, "F_REVENUE") + net_profit = _get_dupont_kpi(db, 1, "F_NET_PROFIT") + # 资产/权益 DB 无完整数据 → 对应 factor 返回 null,标注"数据待补充",不报错 + total_assets = None + equity = None + + net_profit_margin = round(net_profit / revenue * 100, 2) if revenue else None + + if total_assets and equity: + asset_turnover = round(revenue / total_assets, 4) + financial_leverage = round(total_assets / equity, 2) + roe = round(net_profit_margin / 100 * asset_turnover * financial_leverage * 100, 2) + else: + # 资产/权益缺失:周转率与杠杆按中性值1估算,ROE≈净利率(净利润为负,符号确定) + asset_turnover = None + financial_leverage = None + roe = net_profit_margin + + # 上期对比:prev_roe 无法获取 → null(前端已兼容 null,显示"无对比") + prev_roe = None + roe_change = None + roe_trend = None + + return { + "entity": "hanke", + "entity_name": "陕西酣客文化传媒(白酒经销)", + "period": "2026年H1", + "roe": roe, + "roe_change": roe_change, + "roe_trend": roe_trend, + "prev_roe": prev_roe, + "factors": { + "net_profit_margin": { + "value": net_profit_margin, + "label": "净利润率", + "desc": "净利润/收入", + "status": "🔴" if (net_profit_margin or 0) < 0 else ("🟡" if (net_profit_margin or 0) < 5 else "✅"), + "assessment": "净利率为负,本期亏损经营", + "raw": {"net_profit": net_profit, "revenue": revenue}, + }, + "asset_turnover": { + "value": asset_turnover, + "label": "资产周转率", + "desc": "收入/总资产", + "status": "ℹ️", + "assessment": "数据待补充", + "raw": {"revenue": revenue, "total_assets": total_assets}, + }, + "financial_leverage": { + "value": financial_leverage, + "label": "财务杠杆", + "desc": "总资产/净资产", + "status": "ℹ️", + "assessment": "数据待补充", + "raw": {"total_assets": total_assets, "equity": equity}, + }, + }, + "raw_data": { + "net_profit": net_profit, + "revenue": revenue, + "total_assets": total_assets, + "equity": equity, + }, + "insight": { + "improvement": "止损优先:提升毛利率、控制费用;待资产/权益数据补充后计算完整ROE", + "detail": f"净利润{net_profit}万、净利率{net_profit_margin}%,白酒经销业务本期亏损(营收{revenue}万)。资产周转率与财务杠杆因资产/权益数据缺失暂无法计算(数据待补充),待补充后更新完整杜邦拆解。", }, } return {"error": "不支持的实体"}