diff --git a/plugins/message_summary/main.py b/plugins/message_summary/main.py
index d9800e5..5d7d8c4 100644
--- a/plugins/message_summary/main.py
+++ b/plugins/message_summary/main.py
@@ -1020,6 +1020,119 @@ class MessageSummaryPlugin(MessagePluginInterface):
break
return aux_sections
+ @classmethod
+ def _collect_section_texts(cls, section: Dict[str, Any], limit: int = 6) -> List[str]:
+ """从分节中提取可展示文本,统一做长度控制。"""
+ texts: List[str] = []
+ for item in section.get("items", []):
+ text = str(item.get("text") or "").strip()
+ if not text:
+ continue
+ # 说明:模板展示强调“短信息块”,避免单条过长撑爆布局。
+ texts.append(text[:120])
+ if len(texts) >= limit:
+ break
+ return texts
+
+ @classmethod
+ def _extract_contributor_names_from_texts(cls, texts: List[str], limit: int = 3) -> List[str]:
+ """从文本中抽取贡献者昵称(优先提取 @昵称)。"""
+ names: List[str] = []
+ for text in texts:
+ # 说明:昵称不做翻译和重写,尽量保留原始 @ 片段,兼容中文/英文/符号昵称。
+ for match in re.findall(r"@([^\s::,,。]{1,24})", text):
+ name = str(match).strip()
+ if not name or name in names:
+ continue
+ names.append(name)
+ if len(names) >= limit:
+ return names
+ # 若没有 @昵称,则退化为文本前缀,保证至少有可展示头像缩写数据。
+ for text in texts:
+ candidate = cls._strip_markdown_inline(text).strip()
+ if not candidate:
+ continue
+ candidate = candidate[:12]
+ if candidate in names:
+ continue
+ names.append(candidate)
+ if len(names) >= limit:
+ break
+ return names
+
+ @classmethod
+ def _build_template_named_modules(cls, sections: List[Dict[str, Any]]) -> Dict[str, Any]:
+ """按 gemini-code 模板模块语义抽取结构化数据。"""
+ modules: Dict[str, Any] = {
+ "shared_resources": [],
+ "marketplace": [],
+ "unresolved_pool": [],
+ "core_points": [],
+ "top_contributors": [],
+ }
+ if not sections:
+ return modules
+
+ for section in sections:
+ title_raw = str(section.get("title") or "").strip()
+ title = title_raw.lower()
+ if not title:
+ continue
+ texts = cls._collect_section_texts(section, limit=8)
+ if not texts:
+ continue
+
+ # 资源区:仓库、文档、工具链接等。
+ if any(key in title for key in ["shared resources", "资源", "工具", "链接"]):
+ for text in texts:
+ if text not in modules["shared_resources"]:
+ modules["shared_resources"].append(text)
+ continue
+
+ # 交易区:出/求/报价/服务等。
+ if any(key in title for key in ["marketplace", "交易", "卖货", "快报"]):
+ for text in texts:
+ if text not in modules["marketplace"]:
+ modules["marketplace"].append(text)
+ continue
+
+ # 待解问题池。
+ if any(key in title for key in ["unresolved", "待解", "未解决", "问题池"]):
+ for text in texts:
+ if text not in modules["unresolved_pool"]:
+ modules["unresolved_pool"].append(text)
+ continue
+
+ # 核心知识点。
+ if any(key in title for key in ["core knowledge", "知识", "经验", "配置"]):
+ for text in texts:
+ if text not in modules["core_points"]:
+ modules["core_points"].append(text)
+ continue
+
+ # 贡献者/荣誉榜。
+ if any(key in title for key in ["top contributors", "荣誉榜", "mvp", "贡献者"]):
+ names = cls._extract_contributor_names_from_texts(texts, limit=3)
+ for name in names:
+ if name not in modules["top_contributors"]:
+ modules["top_contributors"].append(name)
+ continue
+
+ # 兜底:若未抽到贡献者,则尝试从全部分节文本粗提取。
+ if not modules["top_contributors"]:
+ all_texts: List[str] = []
+ for section in sections:
+ all_texts.extend(cls._collect_section_texts(section, limit=2))
+ modules["top_contributors"] = cls._extract_contributor_names_from_texts(all_texts, limit=3)
+
+ # 统一上限,控制页面高度与信息密度。
+ modules["shared_resources"] = modules["shared_resources"][:6]
+ modules["marketplace"] = modules["marketplace"][:6]
+ modules["unresolved_pool"] = modules["unresolved_pool"][:4]
+ modules["core_points"] = modules["core_points"][:4]
+ modules["top_contributors"] = modules["top_contributors"][:3]
+ return modules
+
def _render_summary_template_html(
self,
group_name: str,
@@ -1042,6 +1155,7 @@ class MessageSummaryPlugin(MessagePluginInterface):
topic_cards = self._build_topic_cards_from_sections(sections, limit=5)
topic_titles = [card.get("title", "") for card in topic_cards]
auxiliary_sections = self._build_auxiliary_sections(sections, topic_titles)
+ named_modules = self._build_template_named_modules(sections)
# 说明:
# 1. 这里注入“本地字体 CSS”到模板,避免依赖 Google Fonts 等外网资源;
# 2. 字体文件统一从仓库根目录 fonts/ 下读取,便于部署时统一管理;
@@ -1059,6 +1173,11 @@ class MessageSummaryPlugin(MessagePluginInterface):
"summary_sections": layout_data.get("sections", []),
"summary_topics": topic_cards,
"summary_aux_sections": auxiliary_sections,
+ "summary_shared_resources": named_modules.get("shared_resources", []),
+ "summary_marketplace": named_modules.get("marketplace", []),
+ "summary_unresolved_pool": named_modules.get("unresolved_pool", []),
+ "summary_core_points": named_modules.get("core_points", []),
+ "summary_top_contributors": named_modules.get("top_contributors", []),
"summary_fallback_text": layout_data.get("fallback_text", ""),
"summary_metrics": metrics_data,
"local_font_css": Markup(local_font_css),
diff --git a/plugins/message_summary/templates/gemini_summary_card.html b/plugins/message_summary/templates/gemini_summary_card.html
index 24efe0f..864dcfc 100644
--- a/plugins/message_summary/templates/gemini_summary_card.html
+++ b/plugins/message_summary/templates/gemini_summary_card.html
@@ -5,478 +5,501 @@
{{ title }}
-
-