From c4f29084bc602c0086f0a7e743d35d657483ea81 Mon Sep 17 00:00:00 2001 From: liuwei Date: Thu, 23 Apr 2026 11:02:45 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8C=89design=5Fsummary=E8=A7=84=E8=8C=83?= =?UTF-8?q?=E9=87=8D=E6=9E=84=E7=BE=A4=E6=80=BB=E7=BB=93=E5=8D=A1=E7=89=87?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - gemini_summary_card 调整为 420px 固定宽度与高密度小字号布局,贴合 Clean Technical 规范\n- 话题卡片严格采用 Background/Key Points/Conclusion 三段论结构并保留结论高亮块\n- 个人雷达标签改为药丸样式并增加彩色高亮逻辑,未命中维持 Slate 背景\n- 新增资源库列表的 GitHub 风格行结构(左图标、中标题、右箭头)\n- 双栏挂件恢复 Marketplace 与 Unresolved Pool 并排展示,节省纵向空间\n- 核心知识点改为深色高反差模块,强化长图视觉焦点\n- main.py 新增模板命名模块与资源库结构化提取,保障模板字段与数据一致 --- .../demo_msg/design_summary.md | 0 plugins/message_summary/main.py | 43 ++ .../templates/gemini_summary_card.html | 409 ++++++++++-------- 3 files changed, 265 insertions(+), 187 deletions(-) create mode 100644 plugins/message_summary/demo_msg/design_summary.md diff --git a/plugins/message_summary/demo_msg/design_summary.md b/plugins/message_summary/demo_msg/design_summary.md new file mode 100644 index 0000000..e69de29 diff --git a/plugins/message_summary/main.py b/plugins/message_summary/main.py index 5d7d8c4..4e622b6 100644 --- a/plugins/message_summary/main.py +++ b/plugins/message_summary/main.py @@ -1133,6 +1133,47 @@ class MessageSummaryPlugin(MessagePluginInterface): modules["top_contributors"] = modules["top_contributors"][:3] return modules + @classmethod + def _build_resource_hub_items(cls, resources: List[str]) -> List[Dict[str, str]]: + """把资源文本转换为“资源库列表”展示数据。 + + 设计说明: + 1. 该方法只做轻量规则分类,不依赖额外模型推理,保证稳定与速度; + 2. 输出包含 icon/type/title,模板可直接渲染“左图标-中标题-右箭头”结构; + 3. 资源条目数量限制在 6 条,避免长图膨胀。 + """ + items: List[Dict[str, str]] = [] + for raw in resources or []: + text = cls._strip_markdown_inline(str(raw or "").strip()) + if not text: + continue + + lower = text.lower() + # 说明:以关键词做资源类型判断,优先覆盖仓库、文档、链接、附件四类。 + if "github.com" in lower or "gitlab" in lower or "仓库" in text: + icon = "⌘" + kind = "Repo" + elif "http://" in lower or "https://" in lower or "链接" in text: + icon = "↗" + kind = "Link" + elif any(k in lower for k in [".pdf", ".doc", ".ppt", "文档", "手册", "白皮书"]): + icon = "▣" + kind = "Doc" + else: + icon = "•" + kind = "Item" + + items.append( + { + "icon": icon, + "type": kind, + "title": text[:72], + } + ) + if len(items) >= 6: + break + return items + def _render_summary_template_html( self, group_name: str, @@ -1156,6 +1197,7 @@ class MessageSummaryPlugin(MessagePluginInterface): 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) + resource_hub_items = self._build_resource_hub_items(named_modules.get("shared_resources", [])) # 说明: # 1. 这里注入“本地字体 CSS”到模板,避免依赖 Google Fonts 等外网资源; # 2. 字体文件统一从仓库根目录 fonts/ 下读取,便于部署时统一管理; @@ -1178,6 +1220,7 @@ class MessageSummaryPlugin(MessagePluginInterface): "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_resource_hub": resource_hub_items, "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 864dcfc..3f485a0 100644 --- a/plugins/message_summary/templates/gemini_summary_card.html +++ b/plugins/message_summary/templates/gemini_summary_card.html @@ -8,370 +8,400 @@ {{ local_font_css }} :root { - --slate-50: #f8fafc; - --slate-100: #f1f5f9; - --slate-200: #e2e8f0; - --slate-300: #cbd5e1; - --slate-400: #94a3b8; - --slate-500: #64748b; - --slate-600: #475569; - --slate-700: #334155; - --slate-900: #0f172a; - --blue-50: #eff6ff; - --blue-100: #dbeafe; - --blue-600: #2563eb; - --indigo-50: #eef2ff; - --indigo-600: #4f46e5; - --emerald-50: #ecfdf5; - --emerald-100: #d1fae5; - --emerald-600: #059669; - --emerald-800: #065f46; - --shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.05); + --bg: #F8FAFC; + --surface: #FFFFFF; + --text: #334155; + --heading: #0F172A; + --line: #F1F5F9; + --blue: #2563EB; + --green: #22C55E; + --rose: #F43F5E; + --shadow-sm: 0 1px 3px rgba(15, 23, 42, 0.05); } * { box-sizing: border-box; } body { margin: 0; - padding: 22px 0; - background-color: var(--slate-50); - color: var(--slate-700); - font-family: var(--abot-font-sans, 'Inter', 'PingFang SC', -apple-system, sans-serif); + padding: 10px 0; + background: var(--bg); + color: var(--text); + font-family: var(--abot-font-sans, 'Inter', 'PingFang SC', system-ui, sans-serif); -webkit-font-smoothing: antialiased; } .report-container { - width: min(720px, calc(100vw - 14px)); + width: 420px; margin: 0 auto; - background: #ffffff; - box-shadow: var(--shadow); - border: 1px solid var(--slate-200); + background: var(--surface); + border: 1px solid var(--line); + box-shadow: var(--shadow-sm); } .label-tiny { + display: block; font-size: 9px; + line-height: 1.2; font-weight: 800; text-transform: uppercase; - letter-spacing: .08em; - color: var(--slate-400); - margin-bottom: 2px; - display: block; + letter-spacing: 0.08em; + color: #94a3b8; + margin-bottom: 3px; } - .mono { font-family: var(--abot-font-code, 'JetBrains Mono', monospace); } + .mono { font-family: var(--abot-font-code, 'JetBrains Mono', 'SF Mono', monospace); } .header { - padding: 20px; - border-bottom: 1px solid var(--slate-100); + padding: 12px; + border-bottom: 1px solid var(--line); } - .header-row { + .header-top { display: flex; justify-content: space-between; align-items: flex-start; - gap: 10px; - margin-bottom: 13px; + gap: 8px; + margin-bottom: 8px; } .header-title { margin: 0; - font-size: 16px; + font-size: 13px; + line-height: 1.25; font-weight: 900; + color: var(--heading); letter-spacing: -0.02em; - color: var(--slate-900); } - .header-title .accent { color: var(--blue-600); font-weight: 600; } + .header-title .accent { color: var(--blue); font-weight: 600; } .header-id { - margin: 4px 0 0; - font-size: 10px; - color: var(--slate-400); - font-weight: 600; - letter-spacing: .03em; + margin: 3px 0 0; + font-size: 9px; + color: #94a3b8; + letter-spacing: 0.03em; } .header-tag { - padding: 4px 8px; - background: var(--slate-100); + padding: 2px 6px; border-radius: 4px; + background: #f1f5f9; + border: 1px solid #e2e8f0; font-size: 9px; + color: #64748b; font-weight: 700; - color: var(--slate-500); - text-transform: uppercase; white-space: nowrap; + text-transform: uppercase; } - .meta-grid { + .kpi-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); - gap: 8px; + gap: 6px; + } + + .kpi { + background: #f8fafc; + border: 1px solid var(--line); + border-radius: 4px; + padding: 5px 4px; text-align: center; } - .meta-item { - background: var(--slate-50); - border-radius: 4px; - padding: 8px 6px; - } - - .meta-value { - font-size: 12px; + .kpi .value { + font-size: 11px; font-weight: 800; - color: var(--slate-700); + color: #475569; } - .meta-value.is-blue { color: var(--blue-600); } - .meta-value.is-indigo { color: var(--indigo-600); } - .meta-value.is-emerald { color: var(--emerald-600); } + .kpi .value.is-blue { color: var(--blue); } + .kpi .value.is-indigo { color: #4f46e5; } + .kpi .value.is-emerald { color: #059669; } .radar { - padding: 0 20px 16px; - border-bottom: 1px solid var(--slate-100); + padding: 10px 12px; + border-bottom: 1px solid var(--line); } .radar-tags { - margin-top: 8px; display: flex; flex-wrap: wrap; - gap: 8px; + gap: 6px; + margin-top: 2px; } .radar-tag { - font-size: 10px; - padding: 2px 8px; - border-radius: 6px; + font-size: 9px; + line-height: 1.2; + padding: 2px 7px; + border-radius: 999px; + border: 1px solid #e2e8f0; + background: #f1f5f9; + color: #64748b; font-weight: 700; - border: 1px solid transparent; } - .radar-tag.tone-blue { background: var(--blue-50); color: var(--blue-600); border-color: var(--blue-100); font-style: italic; } - .radar-tag.tone-indigo { background: var(--indigo-50); color: var(--indigo-600); border-color: #dbeafe; font-style: italic; } - .radar-tag.tone-emerald { background: var(--emerald-50); color: var(--emerald-600); border-color: var(--emerald-100); font-style: italic; } - .radar-tag.tone-slate { background: var(--slate-100); color: var(--slate-500); } + .radar-tag.hit-blue { background: #eff6ff; border-color: #dbeafe; color: #2563eb; } + .radar-tag.hit-indigo { background: #eef2ff; border-color: #e0e7ff; color: #4f46e5; } + .radar-tag.hit-emerald { background: #ecfdf5; border-color: #d1fae5; color: #059669; } - .content { padding: 20px; } + .content { + padding: 12px; + } .lead { - margin: 0 0 14px; - background-color: #f0fdf4; - border-left: 2px solid #22c55e; - padding: 8px; + margin: 0 0 10px; + background: #f0fdf4; + border-left: 2px solid var(--green); border-radius: 0 4px 4px 0; + padding: 7px 8px; font-size: 11px; - color: var(--emerald-800); - line-height: 1.7; + line-height: 1.55; + color: #166534; font-weight: 700; } .topic-list { display: flex; flex-direction: column; - gap: 14px; + gap: 8px; } .topic-card { - border: 1px solid var(--slate-200); - border-radius: 8px; - padding: 10px; + border: 1px solid #e2e8f0; + border-radius: 6px; + padding: 8px; background: #fff; } .topic-title-row { display: flex; align-items: center; - gap: 8px; - margin-bottom: 8px; + gap: 7px; + margin-bottom: 6px; } .topic-title { margin: 0; - font-size: 12px; + font-size: 13px; font-weight: 800; - color: var(--slate-900); + color: var(--heading); + line-height: 1.3; } .topic-divider { - height: 1px; flex: 1; - background: var(--slate-100); + height: 1px; + background: var(--line); } .topic-meta { - margin: 0 0 8px; - padding: 8px; + margin: 0 0 6px; + font-size: 10px; + color: #64748b; + line-height: 1.45; + padding: 5px 6px; + border: 1px dashed #e2e8f0; border-radius: 4px; - background: var(--slate-50); - border: 1px dashed var(--slate-200); - font-size: 11px; - color: var(--slate-600); - line-height: 1.6; + background: #f8fafc; } - .topic-block { margin-bottom: 8px; } + .topic-block { margin-bottom: 6px; } .topic-block:last-child { margin-bottom: 0; } .topic-text { margin: 0; font-size: 11px; - color: var(--slate-600); - line-height: 1.7; + color: #475569; + line-height: 1.55; } .topic-bullets { margin: 0; - padding-left: 14px; - color: var(--slate-600); + padding-left: 10px; font-size: 11px; - line-height: 1.68; + color: #475569; + line-height: 1.5; } - .topic-bullets li { margin: 2px 0; } + .topic-bullets li { margin: 1px 0; } .conclusion-area { - background-color: #f0fdf4; - border-left: 2px solid #22c55e; - padding: 8px; + background: #f0fdf4; + border-left: 2px solid var(--green); border-radius: 0 4px 4px 0; + padding: 6px 7px; } .conclusion-text { margin: 0; font-size: 11px; + line-height: 1.5; font-weight: 700; - color: var(--emerald-800); - line-height: 1.6; + color: #166534; font-style: italic; } .resource-wrap { - margin-top: 14px; - padding: 14px 0; - border-top: 1px solid var(--slate-100); - border-bottom: 1px solid var(--slate-100); - background: rgba(248,250,252,0.5); + margin-top: 10px; + padding: 10px 0; + border-top: 1px solid var(--line); + border-bottom: 1px solid var(--line); + background: rgba(248, 250, 252, 0.5); } .resource-list { display: flex; flex-direction: column; - gap: 6px; - padding: 0 10px; + gap: 4px; + padding: 0 8px; } .resource-item { - border: 1px solid var(--slate-100); + border: 1px solid var(--line); border-radius: 4px; - padding: 7px 8px; - font-size: 10px; - color: var(--slate-600); - line-height: 1.6; + padding: 5px 6px; background: #fff; + display: flex; + align-items: center; + justify-content: space-between; + gap: 6px; + min-height: 24px; } - .market-grid { - margin-top: 14px; + .resource-left { + display: flex; + align-items: center; + gap: 5px; + min-width: 0; + } + + .resource-icon { + width: 14px; + text-align: center; + font-size: 10px; + color: #94a3b8; + flex-shrink: 0; + } + + .resource-title { + font-size: 10px; + color: #475569; + line-height: 1.2; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + .resource-arrow { + font-size: 9px; + color: #cbd5e1; + flex-shrink: 0; + } + + .widget-grid { + margin-top: 10px; display: grid; - grid-template-columns: repeat(2, minmax(0,1fr)); - gap: 12px; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 8px; } - .market-card { - border: 1px solid var(--slate-100); - border-radius: 6px; - padding: 8px; + .widget { + border: 1px solid var(--line); + border-radius: 4px; + padding: 6px; background: #fff; + min-height: 62px; } - .market-item { - margin: 0 0 6px; + .widget-item { + margin: 0 0 4px; font-size: 10px; - color: var(--slate-600); - line-height: 1.6; + line-height: 1.45; + color: #475569; } - .market-item:last-child { margin-bottom: 0; } + .widget-item:last-child { margin-bottom: 0; } - .core-wrap { margin-top: 14px; } + .widget-item.trade { color: var(--rose); font-weight: 700; } + + .core-wrap { margin-top: 10px; } .core-card { - border-radius: 6px; - background: #0f172a; - color: #e2e8f0; - padding: 10px; + border-radius: 4px; + background: #0F172A; border: 1px solid #1e293b; + padding: 8px; } .core-item { - margin: 0 0 6px; + margin: 0 0 5px; font-size: 10px; - line-height: 1.65; + line-height: 1.5; color: #cbd5e1; } .core-item:last-child { margin-bottom: 0; } - .footer-main { - margin-top: 14px; - padding: 12px 10px; - background: var(--slate-50); - border-top: 1px solid var(--slate-100); + .contributors { + margin-top: 10px; + padding: 8px; + background: #f8fafc; + border-top: 1px solid var(--line); + border-bottom: 1px solid var(--line); display: flex; justify-content: space-between; align-items: center; - gap: 12px; + gap: 8px; } - .avatar-list { display: flex; margin-left: auto; } + .avatar-list { + display: flex; + margin-left: auto; + } .avatar { - width: 24px; - height: 24px; + width: 22px; + height: 22px; border-radius: 50%; border: 2px solid #fff; display: inline-flex; align-items: center; justify-content: center; + margin-left: -5px; font-size: 9px; - font-weight: 700; - margin-left: -6px; + font-weight: 800; } - .avatar:nth-child(1) { background: var(--blue-100); color: var(--blue-600); } - .avatar:nth-child(2) { background: #e0e7ff; color: var(--indigo-600); } - .avatar:nth-child(3) { background: #e2e8f0; color: var(--slate-500); } + .avatar:nth-child(1) { background: #dbeafe; color: #2563eb; } + .avatar:nth-child(2) { background: #e0e7ff; color: #4f46e5; } + .avatar:nth-child(3) { background: #e2e8f0; color: #64748b; } .footer-note { + padding: 8px 0 10px; text-align: center; - margin-top: 10px; font-size: 9px; - color: var(--slate-400); - letter-spacing: .03em; + color: #94a3b8; + letter-spacing: 0.03em; text-transform: uppercase; } - - @media (max-width: 760px) { - .meta-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } - .market-grid { grid-template-columns: 1fr; } - }
-
+

CHAT INSIGHTS REPORT

ID: {{ generated_at }}

{{ summary_metrics.activity_badge or "Daily Archive" }}
- -
+
{% for card in summary_metrics.kpi_cards|default([]) %} -
+
{{ card.label }} - {{ card.value }} + {{ card.value }}
{% endfor %}
@@ -381,10 +411,10 @@ # Personal Interest Radar
{% for tag in summary_metrics.topic_tags|default([]) %} - {{ tag }} + {{ tag }} {% endfor %} {% if not (summary_metrics.topic_tags|default([])) %} - 暂无热点标签 + 暂无热点标签 {% endif %}
@@ -438,38 +468,43 @@
{% if not (summary_topics|default([])) %} -

{{ summary_fallback_text }}

+

{{ summary_fallback_text }}

{% endif %} - {% if summary_shared_resources|default([]) %} + {% if summary_resource_hub|default([]) %}
- # Shared Resources + # Shared Resources
- {% for line in summary_shared_resources %} -

{{ line }}

+ {% for item in summary_resource_hub %} +
+
+ {{ item.icon }} + {{ item.title }} +
+ +
{% endfor %}
{% endif %} -
-
+
+
# Marketplace {% for line in summary_marketplace|default([]) %} -

{{ line }}

+

{{ line }}

{% endfor %} {% if not (summary_marketplace|default([])) %} -

暂无交易信息

+

暂无交易信息

{% endif %}
- -
+
# Unresolved Pool {% for line in summary_unresolved_pool|default([]) %} -

{{ line }}

+

{{ line }}

{% endfor %} {% if not (summary_unresolved_pool|default([])) %} -

暂无待解问题

+

暂无待解问题

{% endif %}
@@ -486,7 +521,7 @@
-
+
Top Contributors
{% for name in summary_top_contributors|default([]) %} @@ -496,7 +531,7 @@ ABC {% endif %}
-
+