style: 日报改结论式极简排版(去掉补拉等内部术语和逐状态明细)
This commit is contained in:
@@ -21,77 +21,72 @@ from flows.sds.verify import sds_verify
|
|||||||
from flows.shared import SyncDB, emit_sync_summary, send_markdown, start_of_day
|
from flows.shared import SyncDB, emit_sync_summary, send_markdown, start_of_day
|
||||||
|
|
||||||
|
|
||||||
def _fmt_diff(diff: dict) -> str:
|
|
||||||
return " ".join(f"{k}{v:+d}" for k, v in (diff or {}).items()) or "—"
|
|
||||||
|
|
||||||
|
|
||||||
_TOTALS_LABELS = {
|
|
||||||
"ordersAdded": "订单新增", "ordersUpdated": "订单更新", "ordersRemoved": "订单移除",
|
|
||||||
"goodsAdded": "商品新增", "goodsUpdated": "商品更新", "goodsRemoved": "商品移除",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def _fmt_totals(summary: dict) -> str:
|
|
||||||
parts = [f"{_TOTALS_LABELS.get(k, k)} {v:,}" for k, v in summary.items()
|
|
||||||
if k not in ("totalDays", "daysWithDiff") and v]
|
|
||||||
return " · ".join(parts)
|
|
||||||
|
|
||||||
|
|
||||||
def _short_date(date_str: str) -> str:
|
def _short_date(date_str: str) -> str:
|
||||||
return date_str[5:] if len(date_str) == 10 and date_str[:4].isdigit() else date_str
|
return date_str[5:] if len(date_str) == 10 and date_str[:4].isdigit() else date_str
|
||||||
|
|
||||||
|
|
||||||
|
def _affected_units(diff: dict) -> int:
|
||||||
|
"""状态不符单数 ≈ 本地比远程多的状态计数之和(远程改了状态的单)。"""
|
||||||
|
return sum(v for v in (diff or {}).values() if v > 0)
|
||||||
|
|
||||||
|
|
||||||
def build_daily_message(
|
def build_daily_message(
|
||||||
days: int, window: str, riin: dict, sds: dict,
|
days: int, window: str, riin: dict, sds: dict,
|
||||||
goods: dict, ocr: dict, failures: list[dict],
|
goods: dict, ocr: dict, failures: list[dict],
|
||||||
) -> tuple[str, bool]:
|
) -> tuple[str, bool]:
|
||||||
"""拼装日报 markdown,返回 (消息, 是否需关注)。独立成函数便于预览/测试。"""
|
"""拼装日报 markdown,返回 (消息, 是否需关注)。结论式极简排版,不暴露内部术语。"""
|
||||||
lines = [f"📊 **数据核验日报** {datetime.now().strftime('%m-%d %H:%M')}"
|
lines = [f"📊 **数据核验日报** {datetime.now().strftime('%m-%d %H:%M')}"
|
||||||
f"(近 {days} 天,{window})", ""]
|
f"(近 {days} 天,{window})", ""]
|
||||||
attention = False
|
attention = False
|
||||||
|
diff_names: list[str] = []
|
||||||
|
|
||||||
for name, report in (("RIIN", riin), ("SDS", sds)):
|
for name, report in (("RIIN", riin), ("SDS", sds)):
|
||||||
try:
|
try:
|
||||||
days_r = (report.get("verifyReport") or {}).get("days") or []
|
days_r = (report.get("verifyReport") or {}).get("days") or []
|
||||||
summary = (report.get("verifyReport") or {}).get("summary") or {}
|
summary = (report.get("verifyReport") or {}).get("summary") or {}
|
||||||
diff_days = [d for d in days_r if not d.get("ok")]
|
diff_days = [d for d in days_r if not d.get("ok")]
|
||||||
total, n_diff = summary.get("totalDays", len(days_r)), summary.get("daysWithDiff", len(diff_days))
|
total = summary.get("totalDays", len(days_r))
|
||||||
if diff_days:
|
if not diff_days:
|
||||||
lines.append(f"**{name}** {total - n_diff}/{total} 天一致,**{n_diff} 天有差异(已补拉)**⚠️")
|
lines.append(f"**{name}** {total}/{total} 天与远程一致 ✅")
|
||||||
for d in diff_days[:8]:
|
|
||||||
lines.append(f"> {_short_date(d['date'])} {_fmt_diff(d.get('diff'))}(补拉 {d.get('orders', 0):,} 单)")
|
|
||||||
if len(diff_days) > 8:
|
|
||||||
lines.append(f"> …共 {len(diff_days)} 天")
|
|
||||||
totals = _fmt_totals(summary)
|
|
||||||
if totals:
|
|
||||||
lines.append(f"> 补拉量合计 {totals}")
|
|
||||||
lines.append("> 注:同一差异长期存在多为统计口径/状态映射问题(如发货后退款未同步)")
|
|
||||||
attention = True
|
|
||||||
else:
|
else:
|
||||||
lines.append(f"**{name}** {total}/{total} 天一致 ✅")
|
diff_names.append(name)
|
||||||
|
attention = True
|
||||||
|
lines.append(f"**{name}** {total - len(diff_days)}/{total} 天与远程一致 ⚠️")
|
||||||
|
if len(diff_days) <= 4:
|
||||||
|
per_day = " · ".join(
|
||||||
|
f"{_short_date(d['date'])} {_affected_units(d.get('diff'))}单" for d in diff_days)
|
||||||
|
lines.append(f"> {per_day}状态不符,已自动重新同步")
|
||||||
|
else:
|
||||||
|
total_affected = sum(_affected_units(d.get("diff")) for d in diff_days)
|
||||||
|
lines.append(f"> {len(diff_days)} 天共约 {total_affected:,} 单状态不符,已自动重新同步")
|
||||||
except Exception as err: # noqa: BLE001
|
except Exception as err: # noqa: BLE001
|
||||||
lines.append(f"**{name}** 核验结果解析失败:{err}")
|
lines.append(f"**{name}** 核验结果解析失败:{err}")
|
||||||
attention = True
|
attention = True
|
||||||
lines.append("")
|
|
||||||
|
|
||||||
lines.append("**商品完整性**")
|
zero_total = sum(g["zeroGoodsOrders"] for g in goods.values())
|
||||||
for sys in ("RIIN", "SDS"):
|
lines += ["", f"**商品** RIIN {goods['RIIN']['orders']:,} 单/{goods['RIIN']['goods']:,} 行"
|
||||||
g = goods[sys]
|
f" · SDS {goods['SDS']['orders']:,} 单/{goods['SDS']['goods']:,} 行"
|
||||||
zero = f"**{g['zeroGoodsOrders']}**⚠️" if g["zeroGoodsOrders"] else "0"
|
+ (" ⚠️" if zero_total else " ✅")]
|
||||||
lines.append(f"> {sys} 订单 {g['orders']:,} · 商品 {g['goods']:,} · 零商品订单 {zero} · 无名称 {g['goodsNoName']:,}")
|
if zero_total:
|
||||||
attention = attention or g["zeroGoodsOrders"] > 0
|
lines.append(f"> 有 {zero_total} 单缺商品数据")
|
||||||
lines.append(f"> 全库孤儿商品 {goods['RIIN']['orphanGoods']:,}")
|
attention = True
|
||||||
lines.append("")
|
lines.append(f"**OCR** 已完成 {ocr.get('done', 0):,} · 待处理 {ocr.get('pending', 0):,}"
|
||||||
|
f" · 失败 {ocr.get('error', 0):,}")
|
||||||
lines.append(f"**OCR** 完成 {ocr.get('done', 0):,} · 失败 {ocr.get('error', 0):,}"
|
|
||||||
f" · 不支持 {ocr.get('unsupported', 0):,} · 待处理 {ocr.get('pending', 0):,}")
|
|
||||||
lines.append(f"**失败 runs(24h)** {len(failures)} 个" + (" ✅" if not failures else ""))
|
|
||||||
for f in failures[:5]:
|
|
||||||
lines.append(f"> 🔴 {f['name']}({f['state']}){f['start']}")
|
|
||||||
if failures:
|
if failures:
|
||||||
attention = True
|
attention = True
|
||||||
|
names = "、".join(f"{f['name']}({f['state']})" for f in failures[:4])
|
||||||
|
lines.append(f"**失败任务(24h)** {len(failures)} 个:{names}")
|
||||||
|
else:
|
||||||
|
lines.append("**失败任务(24h)** 0 个 ✅")
|
||||||
|
|
||||||
lines += ["", ("⚠️ **存在需关注项,见上**" if attention else "✅ **数据全部一致,无异常**")]
|
lines.append("")
|
||||||
|
if attention:
|
||||||
|
lines.append("⚠️ **存在需关注项,见上**")
|
||||||
|
if diff_names:
|
||||||
|
lines.append("> 每天都出现的相同差异属远程统计口径问题,非数据丢失")
|
||||||
|
else:
|
||||||
|
lines.append("✅ **数据全部一致,无异常**")
|
||||||
return "\n".join(lines), attention
|
return "\n".join(lines), attention
|
||||||
|
|
||||||
|
|
||||||
@@ -117,7 +112,10 @@ def daily_report(days: int = 7) -> dict:
|
|||||||
emit_sync_summary("数据核验日报", [
|
emit_sync_summary("数据核验日报", [
|
||||||
("核验窗口", f"近{days}天"), ("需关注", "是" if attention else "否"),
|
("核验窗口", f"近{days}天"), ("需关注", "是" if attention else "否"),
|
||||||
("RIIN 零商品订单", goods["RIIN"]["zeroGoodsOrders"]),
|
("RIIN 零商品订单", goods["RIIN"]["zeroGoodsOrders"]),
|
||||||
|
("RIIN 商品无名称", goods["RIIN"]["goodsNoName"]),
|
||||||
("SDS 零商品订单", goods["SDS"]["zeroGoodsOrders"]),
|
("SDS 零商品订单", goods["SDS"]["zeroGoodsOrders"]),
|
||||||
|
("SDS 商品无名称", goods["SDS"]["goodsNoName"]),
|
||||||
|
("全库孤儿商品", goods["RIIN"]["orphanGoods"]),
|
||||||
("OCR 待处理", ocr.get("pending", 0)), ("失败 runs(24h)", len(failures)),
|
("OCR 待处理", ocr.get("pending", 0)), ("失败 runs(24h)", len(failures)),
|
||||||
("已发企微", "是" if sent else "否"),
|
("已发企微", "是" if sent else "否"),
|
||||||
])
|
])
|
||||||
|
|||||||
Reference in New Issue
Block a user