feat: polish douyu active user cards
This commit is contained in:
@@ -1455,10 +1455,18 @@ class DouyuPlugin(MessagePluginInterface):
|
|||||||
nickname = str(item.get("nickname") or item.get("uid") or "").strip()
|
nickname = str(item.get("nickname") or item.get("uid") or "").strip()
|
||||||
msg_count = int(item.get("message_count", 0) or 0)
|
msg_count = int(item.get("message_count", 0) or 0)
|
||||||
fans_name = str(item.get("fans_name") or "").strip()
|
fans_name = str(item.get("fans_name") or "").strip()
|
||||||
|
fans_level = int(item.get("fans_level", 0) or 0)
|
||||||
|
room_level = int(item.get("room_level", 0) or 0)
|
||||||
|
tags = []
|
||||||
if fans_name:
|
if fans_name:
|
||||||
core_parts.append(f"{nickname}({fans_name},{msg_count}条)")
|
if fans_level > 0:
|
||||||
else:
|
tags.append(f"{fans_name} Lv{fans_level}")
|
||||||
core_parts.append(f"{nickname}({msg_count}条)")
|
else:
|
||||||
|
tags.append(fans_name)
|
||||||
|
if room_level > 0:
|
||||||
|
tags.append(f"房间 Lv{room_level}")
|
||||||
|
tags.append(f"{msg_count}条")
|
||||||
|
core_parts.append(f"{nickname}({','.join(tags)})")
|
||||||
if core_parts:
|
if core_parts:
|
||||||
lines.append(f"- 核心发言用户:{';'.join(core_parts)}。")
|
lines.append(f"- 核心发言用户:{';'.join(core_parts)}。")
|
||||||
|
|
||||||
|
|||||||
@@ -161,6 +161,35 @@ def _render_hot_times(peak_buckets: List[Dict[str, Any]]) -> str:
|
|||||||
return "".join(blocks)
|
return "".join(blocks)
|
||||||
|
|
||||||
|
|
||||||
|
def _render_active_users(top_active_users: List[Dict[str, Any]]) -> str:
|
||||||
|
blocks = []
|
||||||
|
for item in top_active_users[:10]:
|
||||||
|
nickname = str(item.get("nickname") or item.get("uid") or "").strip()
|
||||||
|
fans_name = str(item.get("fans_name") or "").strip()
|
||||||
|
fans_level = int(item.get("fans_level", 0) or 0)
|
||||||
|
room_level = int(item.get("room_level", 0) or 0)
|
||||||
|
message_count = int(item.get("message_count", 0) or 0)
|
||||||
|
|
||||||
|
chips = []
|
||||||
|
if fans_name:
|
||||||
|
fans_label = f"{fans_name} Lv{fans_level}" if fans_level > 0 else fans_name
|
||||||
|
chips.append(f'<span class="user-chip fans">{_escape(fans_label)}</span>')
|
||||||
|
if room_level > 0:
|
||||||
|
chips.append(f'<span class="user-chip room">{_escape(f"房间 Lv{room_level}")}</span>')
|
||||||
|
meta_html = "".join(chips) if chips else '<span class="user-chip plain">普通观众</span>'
|
||||||
|
|
||||||
|
blocks.append(
|
||||||
|
'<div class="active-user-card">'
|
||||||
|
'<div class="active-user-top">'
|
||||||
|
f'<div class="active-user-name">{_escape(nickname)}</div>'
|
||||||
|
f'<div class="active-user-count">{_escape(message_count)}<span>条</span></div>'
|
||||||
|
'</div>'
|
||||||
|
f'<div class="active-user-meta">{meta_html}</div>'
|
||||||
|
'</div>'
|
||||||
|
)
|
||||||
|
return "".join(blocks)
|
||||||
|
|
||||||
|
|
||||||
def render_daily_report_html(
|
def render_daily_report_html(
|
||||||
payload: Dict[str, Any],
|
payload: Dict[str, Any],
|
||||||
danmu_summary: str,
|
danmu_summary: str,
|
||||||
@@ -183,15 +212,6 @@ def render_daily_report_html(
|
|||||||
|
|
||||||
template_items = _build_template_items(payload)
|
template_items = _build_template_items(payload)
|
||||||
top_active_users = payload.get("operator_metrics", {}).get("top_active_users", []) or []
|
top_active_users = payload.get("operator_metrics", {}).get("top_active_users", []) or []
|
||||||
active_user_items = []
|
|
||||||
for item in top_active_users[:10]:
|
|
||||||
nickname = str(item.get("nickname") or item.get("uid") or "").strip()
|
|
||||||
fans_name = str(item.get("fans_name") or "").strip()
|
|
||||||
message_count = int(item.get("message_count", 0) or 0)
|
|
||||||
if fans_name:
|
|
||||||
active_user_items.append(f"{nickname} | {fans_name} | {message_count}条")
|
|
||||||
else:
|
|
||||||
active_user_items.append(f"{nickname} | {message_count}条")
|
|
||||||
|
|
||||||
lead_summary, danmu_bullets = _split_summary_blocks(danmu_summary)
|
lead_summary, danmu_bullets = _split_summary_blocks(danmu_summary)
|
||||||
danmu_bullets = _normalize_summary_bullets(payload, danmu_bullets, target_count=5)
|
danmu_bullets = _normalize_summary_bullets(payload, danmu_bullets, target_count=5)
|
||||||
@@ -413,19 +433,6 @@ def render_daily_report_html(
|
|||||||
line-height: 1.72;
|
line-height: 1.72;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}}
|
}}
|
||||||
.compact-user-list {{
|
|
||||||
margin: 0;
|
|
||||||
padding-left: 18px;
|
|
||||||
column-count: 2;
|
|
||||||
column-gap: 20px;
|
|
||||||
}}
|
|
||||||
.compact-user-list li {{
|
|
||||||
break-inside: avoid;
|
|
||||||
color: #475569;
|
|
||||||
margin: 8px 0;
|
|
||||||
line-height: 1.62;
|
|
||||||
font-size: 14px;
|
|
||||||
}}
|
|
||||||
.aside-card {{
|
.aside-card {{
|
||||||
padding: 18px;
|
padding: 18px;
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
@@ -465,6 +472,76 @@ def render_daily_report_html(
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #6b7280;
|
color: #6b7280;
|
||||||
}}
|
}}
|
||||||
|
.active-user-grid {{
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
gap: 12px;
|
||||||
|
}}
|
||||||
|
.active-user-card {{
|
||||||
|
padding: 14px 15px;
|
||||||
|
border-radius: 18px;
|
||||||
|
background: linear-gradient(180deg, rgba(255,255,255,0.96), rgba(244,247,255,0.92));
|
||||||
|
border: 1px solid rgba(129,147,181,0.18);
|
||||||
|
box-shadow: 0 10px 24px rgba(25, 38, 66, 0.05);
|
||||||
|
}}
|
||||||
|
.active-user-top {{
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 12px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}}
|
||||||
|
.active-user-name {{
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--navy);
|
||||||
|
line-height: 1.35;
|
||||||
|
word-break: break-all;
|
||||||
|
}}
|
||||||
|
.active-user-count {{
|
||||||
|
flex-shrink: 0;
|
||||||
|
min-width: 58px;
|
||||||
|
text-align: right;
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 800;
|
||||||
|
color: var(--blue);
|
||||||
|
line-height: 1;
|
||||||
|
}}
|
||||||
|
.active-user-count span {{
|
||||||
|
margin-left: 2px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #64748b;
|
||||||
|
}}
|
||||||
|
.active-user-meta {{
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 8px;
|
||||||
|
}}
|
||||||
|
.user-chip {{
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 5px 10px;
|
||||||
|
border-radius: 999px;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
}}
|
||||||
|
.user-chip.fans {{
|
||||||
|
color: #9a6700;
|
||||||
|
background: rgba(250, 204, 21, 0.14);
|
||||||
|
border-color: rgba(234, 179, 8, 0.24);
|
||||||
|
}}
|
||||||
|
.user-chip.room {{
|
||||||
|
color: #1d4ed8;
|
||||||
|
background: rgba(59, 130, 246, 0.12);
|
||||||
|
border-color: rgba(59, 130, 246, 0.18);
|
||||||
|
}}
|
||||||
|
.user-chip.plain {{
|
||||||
|
color: #64748b;
|
||||||
|
background: rgba(148, 163, 184, 0.12);
|
||||||
|
border-color: rgba(148, 163, 184, 0.16);
|
||||||
|
}}
|
||||||
.hot-grid {{
|
.hot-grid {{
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||||
@@ -500,6 +577,11 @@ def render_daily_report_html(
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
letter-spacing: .04em;
|
letter-spacing: .04em;
|
||||||
}}
|
}}
|
||||||
|
@media (max-width: 900px) {{
|
||||||
|
.active-user-grid {{
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}}
|
||||||
|
}}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -550,7 +632,9 @@ def render_daily_report_html(
|
|||||||
</div>
|
</div>
|
||||||
<div class="aside-card" style="margin-top: 16px;">
|
<div class="aside-card" style="margin-top: 16px;">
|
||||||
<div class="aside-title">核心发言用户</div>
|
<div class="aside-title">核心发言用户</div>
|
||||||
{_render_list(active_user_items, "compact-user-list")}
|
<div class="active-user-grid">
|
||||||
|
{_render_active_users(top_active_users)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user