新增了一个名为HatsuneMiku的模板 (#134)

* Add HatsuneMiku template with a placeholder file

* Add files via upload

* Delete src/infrastructure/reporting/templates/HatsuneMiku/nothing

* Add files via upload

* 重新替换了所有文件并增加了之前忘记的PDF模板文件

* Add files via upload

* 将Spring Festival模板预览图替换HatsuneMiku模板预览图

* 更改了HatsuneMiku模板的预览图片的引用方式

* 将HatsuneMiku模板的地址替换为国内可以访问的中转
This commit is contained in:
Shiitin
2026-03-28 12:25:19 +08:00
committed by GitHub
parent 03f2f066b3
commit ae96ea9c93
9 changed files with 918 additions and 2 deletions
+2 -2
View File
@@ -38,8 +38,8 @@ _✨ 一个基于 AstrBot 的智能群聊分析插件,支持 **QQ (OneBot)**
<img src="https://fastly.jsdelivr.net/gh/SXP-Simon/astrbot_plugin_qq_group_daily_analysis@main/assets/retro_futurism-demo.jpg" alt="retro_futurism" width="100%">
</td>
<td align="center" width="33.3%" valign="top">
<p><b>Spring Festival</b></p>
<img src="https://fastly.jsdelivr.net/gh/SXP-Simon/astrbot_plugin_qq_group_daily_analysis@main/assets/spring_festival-demo.jpg" alt="spring_festival" width="100%">
<p><b>HatsuneMiku</b></p>
<img src="https://fastly.jsdelivr.net/gh/SXP-Simon/astrbot_plugin_qq_group_daily_analysis@main/assets/HatsuneMiku.jpg" alt="HatsuneMiku" width="100%">
</td>
</tr>
<tr>
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

@@ -0,0 +1,43 @@
<div class="card-common" style="padding: 30px 20px 15px 20px;">
<div style="display: flex; align-items: flex-end; justify-content: space-between; height: 180px; gap: 4px;">
{# 定义一个从 葱绿 -> 薄荷 -> 鹅黄 -> 蜜桃粉 的完美过渡色板 #}
{% set chart_colors = [
'#66D1C7', '#6FD3C6', '#79D5C4', '#85D8C3', '#93DAC1', '#A3DDBF',
'#B4E0BD', '#C7E2BA', '#DBE5B8', '#EFE8B5', '#FFEAB3', '#FFDF9E',
'#FFD38B', '#FFC67A', '#FFB96D', '#FFAC62', '#FFA059', '#FF9552',
'#FF8B4D', '#FF834B', '#FF7D4D', '#FF7752', '#FF745A', '#FF7365'
] %}
{% for item in chart_data %}
{% set h = item.percentage | float %}
{# 使用 loop.index0 从色板中依次取色,形成从左到右的全局渐变 #}
{% set bar_color = chart_colors[loop.index0 % 24] %}
{% set bar_opacity = '1' %}
{% if item.count == 0 %}
{% set h = '4' %}
{% set bar_opacity = '0.3' %}
{% set bar_color = 'var(--miku-blue)' %}
{% endif %}
<div style="flex: 1; display: flex; flex-direction: column; align-items: center; height: 100%; justify-content: flex-end; position: relative;">
{% if item.count > 0 %}
{# 数字去掉背景框,颜色与柱子保持一致,视觉更通透 #}
<span style="font-family: var(--font-num); font-size: 0.8rem; color: {{ bar_color }}; margin-bottom: 6px; font-weight: bold; text-shadow: 0 1px 2px rgba(0,0,0,0.02);">{{ item.count }}</span>
{% endif %}
{# 柱状体 #}
<div style="width: 100%; height: {{ h }}%;
background: {{ bar_color }};
border-radius: 4px 4px 1px 1px;
box-shadow: 0 2px 8px rgba(0,0,0,0.05);
transition: height 0.3s ease;
opacity: {{ bar_opacity }};"></div>
{# X轴标签 #}
<span style="margin-top: 10px; font-family: var(--font-num); font-size: 0.75rem; color: var(--text-sub); font-weight: bold;">{{ "%02d"|format(item.hour) }}时</span>
</div>
{% endfor %}
</div>
</div>
@@ -0,0 +1,39 @@
<div style="margin-bottom: 20px;">
<div class="section-header">
<div class="v-bar"></div>
<div class="section-title-text">聊天质量分析</div>
</div>
<div class="card-common" style="padding: 30px;">
<div style="display: flex; justify-content: space-between; align-items: flex-end; margin-bottom: 25px; border-bottom: 2px dashed var(--miku-blue); padding-bottom: 15px;">
<div style="font-family: var(--font-title); font-size: 1.6rem; color: var(--miku-dark);">{{ title }}</div>
<div style="font-family: var(--font-num); color: var(--text-sub); background: var(--miku-blue); padding: 4px 12px; border-radius: 20px; font-size: 0.9rem;">{{ subtitle }}</div>
</div>
<div style="height: 14px; background: var(--bg-page-base); border-radius: 7px; display: flex; overflow: hidden; margin-bottom: 30px; box-shadow: inset 0 2px 4px rgba(0,0,0,0.02);">
{% set colors = ['var(--miku-base)', 'var(--miku-pink-light)', 'var(--miku-light)', 'var(--miku-yellow)', '#80CBC4'] %}
{% for dim in dimensions %}
<div style="width: {{ dim.percentage }}%; background: {{ colors[loop.index0 % colors|length] }};"></div>
{% endfor %}
</div>
<div style="display: grid; grid-template-columns: repeat(2, 1fr); gap: 15px; margin-bottom: 30px;">
{% for dim in dimensions %}
<div style="background: var(--bg-page-base); padding: 12px 15px; border-radius: 10px; display: flex; align-items: flex-start; gap: 10px;">
<div style="width: 10px; height: 10px; border-radius: 50%; background: {{ colors[loop.index0 % colors|length] }}; margin-top: 5px; flex-shrink: 0;"></div>
<div>
<div style="font-weight: bold; font-size: 0.9rem; color: var(--text-main); margin-bottom: 4px;">{{ dim.name }} ({{ '%.1f'|format(dim.percentage|float) }}%)</div>
<div style="font-size: 0.85rem; color: var(--text-sub); line-height: 1.5;">{{ dim.comment }}</div>
</div>
</div>
{% endfor %}
</div>
<div style="background: linear-gradient(135deg, var(--miku-dark) 0%, var(--miku-base) 100%); color: white; padding: 20px; border-radius: 12px; position: relative; box-shadow: 0 4px 10px rgba(57, 197, 187, 0.2);">
<div style="display: flex; align-items: center; gap: 8px; margin-bottom: 10px;">
<span style="font-size: 1.2rem;">🎤</span>
<span style="font-weight: bold; font-size: 1rem;">Miku 综合点评</span>
</div>
<div style="line-height: 1.7; font-size: 0.95rem; opacity: 0.95;">{{ summary }}</div>
</div>
</div>
</div>
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,32 @@
{% if quotes %}
<div style="margin-bottom: 40px;">
<div class="section-header">
<div class="v-bar"></div>
<div class="section-title-text">每日回响</div>
</div>
{% for quote in quotes %}
<div style="margin-bottom: 25px; display: flex; flex-direction: column; align-items: {% if loop.index0 is even %}flex-start{% else %}flex-end{% endif %};">
<div style="display: flex; gap: 15px; max-width: 85%; {% if loop.index0 is odd %}flex-direction: row-reverse;{% endif %}">
<div style="width: 48px; height: 48px; border-radius: 50%; border: 3px solid white; box-shadow: 0 0 0 2px var(--miku-light); flex-shrink: 0; overflow: hidden; background: var(--bg-page-base);">
{% if quote.avatar_url %}<img src="{{ quote.avatar_url }}" style="width: 100%; height: 100%; object-fit: cover;">{% endif %}
</div>
<div style="{% if loop.index0 is odd %}text-align: right;{% endif %}">
<div style="font-size: 0.85rem; color: var(--text-sub); margin-bottom: 6px; font-weight: bold;">{{ quote.sender }}</div>
<div style="background: rgba(255, 255, 255, 0.95); padding: 16px 22px; border: 1px solid var(--border-miku-light); box-shadow: 0 4px 10px rgba(57,197,187,0.05); border-radius: {% if loop.index0 is even %}4px 18px 18px 18px{% else %}18px 4px 18px 18px{% endif %}; margin-bottom: 12px;">
<div style="font-weight: 600; font-size: 1.05rem; color: var(--text-main); line-height: 1.6;">{{ quote.content }}</div>
</div>
<div style="display: inline-block; background: var(--bg-page-base); padding: 12px 18px; border-radius: 12px; border-left: 4px solid var(--miku-pink-light); text-align: left;">
<div style="display: flex; align-items: center; gap: 8px; margin-bottom: 6px;">
<span style="font-size: 1.1rem;">🎵</span>
<span style="font-weight: bold; color: var(--miku-dark); font-size: 0.95rem;">Miku 锐评</span>
</div>
<div style="font-size: 0.9rem; color: var(--text-sub); line-height: 1.6;">{{ quote.reason | safe }}</div>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
{% endif %}
File diff suppressed because one or more lines are too long
@@ -0,0 +1,29 @@
{% if titles %}
<div style="margin-bottom: 40px;">
<div class="section-header">
<div class="v-bar"></div>
<div class="section-title-text">群友画像</div>
</div>
<div style="column-count: 2; column-gap: 15px;">
{% for title in titles %}
<div class="card-common" style="break-inside: avoid; padding: 20px; margin-bottom: 15px; border-top: 3px solid var(--miku-light);">
<div style="display: flex; align-items: center; gap: 15px; margin-bottom: 15px;">
<div style="width: 55px; height: 55px; border-radius: 50%; border: 3px solid white; box-shadow: 0 0 0 2px var(--miku-light); overflow: hidden; flex-shrink: 0; background: var(--bg-page-base);">
{% if title.avatar_data %}<img src="{{ title.avatar_data }}" style="width: 100%; height: 100%; object-fit: cover;">{% endif %}
</div>
<div>
<div style="font-weight: bold; font-size: 1.1rem; color: var(--text-main);">{{ title.name }}</div>
<div style="display: flex; gap: 6px; margin-top: 6px;">
<span style="background: var(--miku-blue); color: var(--miku-dark); font-size: 0.75rem; padding: 3px 8px; border-radius: 6px; font-weight: bold;">{{ title.title }}</span>
<span style="background: var(--miku-pink-light); color: #fff; font-size: 0.75rem; padding: 3px 8px; border-radius: 6px; font-family: var(--font-num); font-weight: bold;">{{ title.mbti }}</span>
</div>
</div>
</div>
<div style="background: var(--bg-page-base); padding: 12px 15px; border-radius: 8px; font-size: 0.95rem; color: var(--text-sub); line-height: 1.6; border: 1px dashed var(--border-miku-light);">
{{ title.reason }}
</div>
</div>
{% endfor %}
</div>
</div>
{% endif %}