优化:日报卡片打磨细节

- 高发设备/告警热点只取 top2,名称超8字截断,防止文字溢出
- 已完成和待处理合并为一行,减少行数更紧凑
- 待处理为0时显示「 全部清零」,有遗留才显示遗留数
- 误报率非0时才显示,0%不占位
- 副标题:清零时正面鼓励,有超时时⚠提醒
- 底部新增「查看详情」跳转链接
This commit is contained in:
2026-04-03 16:48:29 +08:00
parent ecc5065c71
commit ec5501fa3b

View File

@@ -66,12 +66,15 @@ def _format_change(current: int, previous: int) -> str:
return f"前日{previous}条,持平"
def _top_summary(counter: Counter, mapping: Optional[Dict[str, str]] = None, top_n: int = 3) -> str:
def _top_summary(counter: Counter, mapping: Optional[Dict[str, str]] = None, top_n: int = 3, max_len: int = 0) -> str:
"""汇总 Counter 前 N 名。max_len > 0 时截断每个名称。"""
if not counter:
return "暂无数据"
parts = []
for key, count in counter.most_common(top_n):
name = mapping.get(key, key) if mapping else key
if max_len and len(name) > max_len:
name = name[:max_len] + ".."
parts.append(f"{name} {count}")
return "".join(parts)
@@ -293,6 +296,9 @@ async def _build_daily_report_data() -> Optional[Dict]:
"areas": _top_summary(area_counter),
"cameras": _top_summary(camera_counter),
"cleaning_types": _top_summary(cleaning_type_count, CLEANING_TYPE_NAMES),
# 卡片专用:截断名称,只取 top2 防溢出
"cameras_short": _top_summary(camera_counter, top_n=2, max_len=8),
"alarm_types_short": _top_summary(alarm_type_count, ALARM_TYPE_NAMES, top_n=2),
},
"top_overdue": top_overdue,
}
@@ -305,31 +311,40 @@ def _build_template_card(report: Dict) -> Dict:
tops = report["tops"]
click_url = settings.wechat.service_base_url or "https://work.weixin.qq.com"
# 大号数字:昨日新增
# 大号数字
emphasis_desc = f"昨日新增({report['change_str']}"
# 键值对列表(最多 6 条,挑最重要的)
# 待处理文案
if s["backlog_count"] == 0:
pending_val = "0 ✅ 全部清零"
elif s["carry_over_count"] > 0:
pending_val = f"{s['backlog_count']}(遗留{s['carry_over_count']}"
else:
pending_val = str(s["backlog_count"])
# 键值对(最多 6 条,用短名称防截断)
kv_list = [
{"keyname": "安保 / 保洁", "value": f"{s['security_count']} / {s['clean_count']}"},
{"keyname": "已完成", "value": f"{s['completed_count']}"},
{"keyname": "待处理", "value": f"{s['backlog_count']}(遗留 {s['carry_over_count']}" if s['backlog_count'] > 0 else "0 全部清零"},
{"keyname": "已完成 / 待处理", "value": f"{s['completed_count']} / {pending_val}"},
{"keyname": "首响 / 完结", "value": f"{s['avg_resp']} / {s['avg_close']}"},
]
# 第5条最高发告警类型
if tops["alarm_types"] != "暂无数据":
kv_list.append({"keyname": "告警热点", "value": tops["alarm_types"]})
if tops["alarm_types_short"] != "暂无数据":
kv_list.append({"keyname": "告警热点", "value": tops["alarm_types_short"]})
# 第6条高发设备
if tops["cameras"] != "暂无数据":
kv_list.append({"keyname": "高发设备", "value": tops["cameras"]})
if tops["cameras_short"] != "暂无数据":
kv_list.append({"keyname": "高发设备", "value": tops["cameras_short"]})
# 副标题
sub_title = ""
if report["top_overdue"]:
sub_title = f"需关注:{report['top_overdue'][0]}"
elif s["backlog_count"] == 0:
sub_title = "昨日工单全部处理完毕,运营良好"
if s["false_alarm_rate"] != "0%":
kv_list.append({"keyname": "误报率", "value": s["false_alarm_rate"]})
# 副标题(一句话总结)
if s["backlog_count"] == 0:
sub_title = "昨日工单全部清零,运营状态良好"
elif report["top_overdue"]:
sub_title = f"⚠ 需关注:{report['top_overdue'][0]}"
else:
sub_title = f"当前 {s['backlog_count']} 条待处理"
card = {
"card_type": "text_notice",
@@ -346,6 +361,9 @@ def _build_template_card(report: Dict) -> Dict:
},
"sub_title_text": sub_title,
"horizontal_content_list": kv_list,
"jump_list": [
{"type": 1, "title": "查看详情", "url": click_url},
],
"card_action": {
"type": 1,
"url": click_url,