diff --git a/plugins/douyu/main.py b/plugins/douyu/main.py index 389d71d..d71c7b3 100644 --- a/plugins/douyu/main.py +++ b/plugins/douyu/main.py @@ -1284,7 +1284,7 @@ class DouyuPlugin(MessagePluginInterface): user_prompt = ( "请输出一段适合放在日报图片上半部分的弹幕总结,要求:\n" "1. 先用 1 段总述直播氛围与主线。\n" - "2. 再用 3-5 条要点总结观众关注点、情绪变化、反复出现的梗。\n" + "2. 再用 5 条要点总结观众关注点、情绪变化、反复出现的梗、节奏变化和额外反馈,每条只写一句。\n" "3. 语言像运营复盘,简洁自然。\n" "4. 不要写标题,不要写“根据数据”。\n\n" f"主播:{meta.get('nickname') or meta.get('room_name') or meta.get('room_id')}\n" diff --git a/plugins/douyu/report_template.py b/plugins/douyu/report_template.py index da06d65..8ffbada 100644 --- a/plugins/douyu/report_template.py +++ b/plugins/douyu/report_template.py @@ -39,12 +39,90 @@ def _split_summary_blocks(danmu_summary: str) -> tuple[str, List[str]]: return lead, insight_items +def _normalize_summary_bullets(payload: Dict[str, Any], items: List[str], target_count: int = 5) -> List[str]: + normalized = [str(item or "").strip() for item in items if str(item or "").strip()] + if len(normalized) >= target_count: + return normalized[:target_count] + + top_terms = [str(item.get("term") or "").strip() for item in (payload.get("top_terms", []) or []) if str(item.get("term") or "").strip()] + merged_templates = [str(item.get("text") or "").strip() for item in (payload.get("merged_templates", []) or []) if str(item.get("text") or "").strip()] + peak_buckets = payload.get("peak_buckets", []) or [] + representative_messages = payload.get("representative_messages", []) or [] + + supplements: List[str] = [] + if top_terms: + supplements.append(f"讨论焦点比较集中,弹幕反复围绕 {'、'.join(top_terms[:5])} 展开。") + if merged_templates: + sample_templates = ";".join(text[:24] for text in merged_templates[:3]) + supplements.append(f"复读和共识梗比较强,重复内容主要集中在 {sample_templates}。") + if peak_buckets: + top_bucket = peak_buckets[0] + bucket_terms = [str(term.get('term') or '').strip() for term in (top_bucket.get("top_terms", []) or []) if str(term.get('term') or '').strip()] + if bucket_terms: + supplements.append( + f"高峰时段出现在 {str(top_bucket.get('start_time') or '')[-8:-3]} 前后,话题明显偏向 {'、'.join(bucket_terms[:4])}。" + ) + if representative_messages: + supplements.append("代表性发言里既有操作反馈,也有玩梗调侃和情绪宣泄,互动意愿比较强。") + + existing = set(normalized) + for item in supplements: + if item not in existing: + normalized.append(item) + existing.add(item) + if len(normalized) >= target_count: + break + return normalized[:target_count] + + +def _build_template_items(payload: Dict[str, Any], limit: int = 8) -> List[str]: + items: List[str] = [] + seen = set() + + def push(text: str, suffix: str = "") -> None: + value = str(text or "").strip() + if not value: + return + normalized_key = value + if normalized_key in seen: + return + seen.add(normalized_key) + items.append(f"{value}{suffix}".strip()) + + for item in (payload.get("merged_templates", []) or [])[:6]: + text = str(item.get("text") or "").strip() + count = int(item.get("count", 0) or 0) + if text: + push(text[:72], f"({count}次)") + + for item in (payload.get("repeated_messages", []) or [])[:6]: + text = str(item.get("text") or "").strip() + count = int(item.get("count", 0) or 0) + if text: + push(text[:72], f"({count}次)") + + for item in (payload.get("burst_terms", []) or [])[:6]: + text = str(item.get("text") or "").strip() + count = int(item.get("count", 0) or 0) + if text: + push(text[:36], f"(爆发 {count} 次)") + + for item in (payload.get("top_terms", []) or [])[:6]: + term = str(item.get("term") or "").strip() + count = int(item.get("count", 0) or 0) + if term: + push(term, f"({count}次提及)") + + return items[:limit] + + def _render_insight_cards(items: List[str]) -> str: labels = ["主线", "情绪", "梗点", "节奏", "反馈", "补充"] blocks = [] for idx, item in enumerate(items[:6]): + extra_class = " full-span" if len(items[:6]) % 2 == 1 and idx == len(items[:6]) - 1 else "" blocks.append( - '