From fa00abe7e8547fc20dc486d5288c7007aae70dbd Mon Sep 17 00:00:00 2001 From: zlt Date: Fri, 28 Aug 2026 16:06:42 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=85=AC=E7=A4=BA=E5=AF=BC?= =?UTF-8?q?=E5=87=BA=EF=BC=9A=E6=A0=87=E7=9A=84=E5=90=8D=E6=8C=89=E5=90=8D?= =?UTF-8?q?=E5=AD=97=E6=8E=A5=E5=8F=A3=E7=9C=9F=E5=AE=9E=E5=BD=A2=E7=8A=B6?= =?UTF-8?q?=EF=BC=88=E7=AE=80=E7=A7=B0/=E5=85=A8=E7=A7=B0=E5=AD=97?= =?UTF-8?q?=E5=85=B8=EF=BC=89=E6=8F=90=E5=8F=96=E4=B8=BA=E5=AD=97=E7=AC=A6?= =?UTF-8?q?=E4=B8=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/services/publish_export.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/app/services/publish_export.py b/app/services/publish_export.py index fcab298..db99054 100644 --- a/app/services/publish_export.py +++ b/app/services/publish_export.py @@ -54,6 +54,15 @@ def _as_date(v): return None +def _display_name(v, code: str) -> str: + """标的列显示名。downstream_repo.fetch_names 返回 {"name": 简称, "full": 全称} + (取不到的代码它退回 name=代码本身) —— 公示表用简称, 缺简称用全称, 都没有用代码。 + 单元格必须是字符串, 字典直接写会被 openpyxl 拒收 (2026-08-28 实机报错修)。""" + if isinstance(v, dict): + v = v.get("name") or v.get("full") + return str(v) if v else code.split(".")[0] + + def compute_snapshot() -> dict: """组装公示快照: 持仓明细 / 平仓明细 / 汇总 / 当日净值。全部只读。""" today = date.today() @@ -87,7 +96,8 @@ def compute_snapshot() -> dict: od = _as_date(r.get("open_date")) or today chg = (px / cost - 1.0) if cost > 0 else 0.0 holdings.append({ - "account": account, "code": code.split(".")[0], "name": names.get(code) or code, + "account": account, "code": code.split(".")[0], + "name": _display_name(names.get(code), code), "amount": round(cost * qty, 2), "open_date": od, "upd_date": today, "structure": structure, "cost": cost, "qty": qty, "price": round(px, 3), "days": (today - od).days, "per_share": round(px - cost, 3), @@ -106,7 +116,8 @@ def compute_snapshot() -> dict: amt = cost * cq ret = (pnl / amt) if amt > 0 else 0.0 closed.append({ - "account": account, "code": code.split(".")[0], "name": names.get(code) or code, + "account": account, "code": code.split(".")[0], + "name": _display_name(names.get(code), code), "amount": round(amt, 2), "open_date": od, "close_date": cd, "structure": structure, "cost": cost, "qty": cq, "settle": round(settle, 3), "days": (cd - od).days, "per_share": round(settle - cost, 3),