mirror of
https://github.com/Nezumi-2711/astrbot_plugin_qq_group_daily_analysis.git
synced 2026-09-22 13:38:43 +00:00
feat(template): retro_futurism 调整和 hack 模板
This commit is contained in:
@@ -72,15 +72,15 @@ _✨ 一个基于 AstrBot 的智能群聊分析插件,支持 **QQ (OneBot)**
|
||||
<details>
|
||||
<summary>点击展开查看其他模板效果图</summary>
|
||||
|
||||
retro_futurism 模板效果图
|
||||

|
||||
|
||||
format 模板效果图
|
||||

|
||||
|
||||
simple 模板效果图(用于展示贡献指南)
|
||||

|
||||
|
||||
retro_futurism 模板效果图
|
||||

|
||||
|
||||
</details>
|
||||
|
||||
## 使用方法
|
||||
|
||||
@@ -69,6 +69,7 @@
|
||||
"options": [
|
||||
"scrapbook",
|
||||
"retro_futurism",
|
||||
"hack",
|
||||
"simple",
|
||||
"format"
|
||||
],
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
{% if chart_data %}
|
||||
{% for item in chart_data %}
|
||||
<div class="activity-col">
|
||||
<span class="activity-val-top">{{ item.count }}</span>
|
||||
<div class="activity-bar-v" style="--h:{{ " %.2f"|format(item.percentage) }}%;"></div>
|
||||
<span class="activity-tick">{{ "%02d"|format(item.hour) }}:00</span>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<div class="activity-col" style="flex:1; justify-content: center; height: 100px;">
|
||||
<div class="comment">// NO_DATA_STREAM</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
@@ -0,0 +1,606 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Night Mode Analysis Portal</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&family=Inter:wght@400;600;800&family=Noto+Sans+SC:wght@400;700&display=swap"
|
||||
rel="stylesheet">
|
||||
<style>
|
||||
:root {
|
||||
--bg-deep: #0a0a0a;
|
||||
--bg-panel: #141414;
|
||||
--bg-card: #1c1c1c;
|
||||
--text-primary: #ffffff;
|
||||
--text-secondary: #a0a0a0;
|
||||
--accent-orange: #ff9900;
|
||||
/* Primary */
|
||||
--accent-blue: #3399ff;
|
||||
/* Secondary */
|
||||
--accent-red: #ff3366;
|
||||
--accent-green: #00ff88;
|
||||
/* Reduced use */
|
||||
--border-color: #2a2a2a;
|
||||
--grid-color: rgba(255, 255, 255, 0.03);
|
||||
|
||||
--font-mono: 'JetBrains Mono', monospace;
|
||||
--font-body: 'Inter', 'Noto Sans SC', sans-serif;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
background-color: var(--bg-deep);
|
||||
color: var(--text-primary);
|
||||
font-family: var(--font-body);
|
||||
background-image:
|
||||
radial-gradient(circle at 50% 10%, rgba(255, 153, 0, 0.08) 0%, transparent 70%),
|
||||
linear-gradient(var(--grid-color) 1px, transparent 1px),
|
||||
linear-gradient(90deg, var(--grid-color) 1px, transparent 1px);
|
||||
background-size: 100% 100%, 30px 30px, 30px 30px;
|
||||
min-height: 100vh;
|
||||
font-size: 18px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
body::before {
|
||||
content: "";
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(rgba(18, 16, 16, 0) 50%, rgba(0, 0, 0, 0.05) 50%);
|
||||
background-size: 100% 4px;
|
||||
pointer-events: none;
|
||||
z-index: 9999;
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
.layout {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 60px 40px;
|
||||
}
|
||||
|
||||
/* Terminal Window Style */
|
||||
.window {
|
||||
background: rgba(20, 20, 20, 0.7);
|
||||
backdrop-filter: blur(12px);
|
||||
-webkit-backdrop-filter: blur(12px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.05);
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 30px 60px rgba(0, 0, 0, 0.6);
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.window-header {
|
||||
background: #1e1e1e;
|
||||
padding: 12px 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.traffic-lights {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.light {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.light.red {
|
||||
background: #ff5f56;
|
||||
}
|
||||
|
||||
.light.yellow {
|
||||
background: #ffbd2e;
|
||||
}
|
||||
|
||||
.light.green {
|
||||
background: #27c93f;
|
||||
}
|
||||
|
||||
.window-title {
|
||||
margin-left: 20px;
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.8rem;
|
||||
color: var(--text-secondary);
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
/* Top Navigation Bar from Reference */
|
||||
.top-nav {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
margin-bottom: 40px;
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.85rem;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
color: var(--text-secondary);
|
||||
padding: 6px 12px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid transparent;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.nav-item.active {
|
||||
color: var(--accent-orange);
|
||||
background: rgba(255, 153, 0, 0.05);
|
||||
border-color: rgba(255, 153, 0, 0.2);
|
||||
}
|
||||
|
||||
/* Typography */
|
||||
.prompt {
|
||||
color: var(--accent-orange);
|
||||
/* Changed from green */
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.keyword {
|
||||
color: var(--accent-red);
|
||||
}
|
||||
|
||||
.comment {
|
||||
color: #555;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 5rem;
|
||||
font-weight: 900;
|
||||
margin: 0 0 25px;
|
||||
letter-spacing: -3px;
|
||||
line-height: 0.9;
|
||||
background: linear-gradient(135deg, #fff 60%, var(--accent-orange));
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
|
||||
.cursor {
|
||||
display: inline-block;
|
||||
width: 15px;
|
||||
height: 1.2em;
|
||||
background: var(--text-primary);
|
||||
vertical-align: middle;
|
||||
margin-left: 5px;
|
||||
animation: blink 1s infinite;
|
||||
}
|
||||
|
||||
@keyframes blink {
|
||||
|
||||
0%,
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Stats Grid */
|
||||
.stats-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 20px;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
background: rgba(28, 28, 28, 0.6);
|
||||
backdrop-filter: blur(8px);
|
||||
border: 1px solid rgba(255, 153, 0, 0.1);
|
||||
padding: 24px;
|
||||
border-radius: 12px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.stat-card:hover {
|
||||
border-color: var(--accent-orange);
|
||||
background: rgba(28, 28, 28, 0.8);
|
||||
transform: translateY(-5px);
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-family: var(--font-mono);
|
||||
color: var(--text-secondary);
|
||||
font-size: 0.85rem;
|
||||
margin-bottom: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.stat-label::before {
|
||||
content: '>';
|
||||
color: var(--accent-orange);
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
font-size: 3.5rem;
|
||||
font-weight: 800;
|
||||
color: var(--accent-orange);
|
||||
font-family: var(--font-mono);
|
||||
text-shadow: 0 0 20px rgba(255, 153, 0, 0.3);
|
||||
}
|
||||
|
||||
/* Main Layout Grid */
|
||||
.main-container {
|
||||
display: grid;
|
||||
grid-template-columns: 58% 42%;
|
||||
/* Golden ratio-ish split */
|
||||
gap: 40px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.left-col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 40px;
|
||||
}
|
||||
|
||||
.right-col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 40px;
|
||||
}
|
||||
|
||||
.section-header {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 1.1rem;
|
||||
margin-bottom: 25px;
|
||||
color: var(--text-secondary);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
/* Code Block Container */
|
||||
.code-block {
|
||||
background: rgba(20, 20, 20, 0.8);
|
||||
border: 1px solid rgba(255, 153, 0, 0.15);
|
||||
padding: 30px;
|
||||
border-radius: 12px;
|
||||
font-family: var(--font-mono);
|
||||
line-height: 1.6;
|
||||
box-shadow: inset 0 0 40px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
/* Chart Styling - Reference inspired */
|
||||
.chart-container {
|
||||
height: 300px;
|
||||
position: relative;
|
||||
padding: 40px 10px 50px;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: space-between;
|
||||
gap: 2px;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.chart-svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.chart-line {
|
||||
fill: none;
|
||||
stroke: var(--accent-orange);
|
||||
stroke-width: 3;
|
||||
}
|
||||
|
||||
.chart-area {
|
||||
fill: url(#areaGradient);
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
/* Horizontal Activity Chart Elements */
|
||||
.activity-col {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
justify-content: flex-end;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.activity-bar-v {
|
||||
width: 80%;
|
||||
max-width: 12px;
|
||||
background: var(--accent-orange);
|
||||
height: var(--h, 0%);
|
||||
border-radius: 1px 1px 0 0;
|
||||
box-shadow: 0 0 8px rgba(255, 153, 0, 0.3);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.activity-bar-v::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: linear-gradient(to top, rgba(255, 255, 255, 0.05), transparent);
|
||||
}
|
||||
|
||||
.activity-tick {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.5rem;
|
||||
color: var(--text-secondary);
|
||||
margin-top: 10px;
|
||||
transform: rotate(-60deg);
|
||||
transform-origin: top center;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.activity-val-top {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.55rem;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 4px;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
/* Vertical Flow Elements */
|
||||
.user-grid,
|
||||
.quote-container,
|
||||
.topic-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
|
||||
.user-grid,
|
||||
.quote-container {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
.user-card {
|
||||
background: var(--bg-card);
|
||||
border: 1px solid var(--border-color);
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
transition: border-color 0.2s;
|
||||
}
|
||||
|
||||
.user-card:hover {
|
||||
border-color: var(--accent-blue);
|
||||
}
|
||||
|
||||
.user-avatar {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #333;
|
||||
}
|
||||
|
||||
.user-info h4 {
|
||||
margin: 0 0 5px;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.tag {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.75rem;
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.tag.mbti {
|
||||
color: #ffcc00;
|
||||
border-color: rgba(255, 204, 0, 0.3);
|
||||
background: rgba(255, 204, 0, 0.05);
|
||||
}
|
||||
|
||||
.tag.title {
|
||||
color: var(--accent-blue);
|
||||
border-color: rgba(51, 153, 255, 0.3);
|
||||
background: rgba(51, 153, 255, 0.05);
|
||||
}
|
||||
|
||||
.topic-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.topic-item {
|
||||
padding: 20px;
|
||||
border-left: 3px solid var(--accent-orange);
|
||||
background: rgba(255, 255, 255, 0.02);
|
||||
}
|
||||
|
||||
.topic-title {
|
||||
font-weight: bold;
|
||||
font-size: 1.5rem;
|
||||
margin-bottom: 12px;
|
||||
color: var(--accent-orange);
|
||||
}
|
||||
|
||||
/* Quotes */
|
||||
.quote-item {
|
||||
padding: 24px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.05);
|
||||
border-radius: 12px;
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
align-items: flex-start;
|
||||
background: rgba(30, 30, 30, 0.4);
|
||||
backdrop-filter: blur(5px);
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.quote-avatar {
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
border-radius: 50%;
|
||||
border: 1px solid #333;
|
||||
flex-shrink: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.quote-avatar img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.quote-body {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.quote-text {
|
||||
font-style: italic;
|
||||
font-size: 1.1rem;
|
||||
color: var(--accent-orange);
|
||||
margin-bottom: 12px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.quote-author {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.9rem;
|
||||
color: var(--accent-blue);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
/* Footer */
|
||||
footer {
|
||||
margin-top: 80px;
|
||||
padding-top: 40px;
|
||||
border-top: 1px solid var(--border-color);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.8rem;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.footer-token {
|
||||
color: var(--accent-green);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="layout">
|
||||
<!-- Top Navigation Mockup -->
|
||||
<div class="top-nav">
|
||||
<div class="nav-item active">● ready</div>
|
||||
<div class="nav-item">~/analysis</div>
|
||||
<div style="flex: 1"></div>
|
||||
<div class="nav-item">$ ai --summary</div>
|
||||
<div class="nav-item">$ cd /groups</div>
|
||||
<div class="nav-item">$ api --status</div>
|
||||
<div class="nav-item">🌐 EN</div>
|
||||
<div class="user-avatar" style="width: 25px; height: 25px; border-radius: 50%;"></div>
|
||||
</div>
|
||||
|
||||
<div class="main-container">
|
||||
<!-- Left Side: Analytical Data -->
|
||||
<div class="left-col">
|
||||
<div>
|
||||
<div class="comment">// main.ts</div>
|
||||
<h1><span class="prompt">></span> Group Activity<br>Insights<span class="cursor"></span></h1>
|
||||
<div class="comment" style="margin-bottom: 30px;">// Report for {{current_date}}</div>
|
||||
|
||||
<div class="code-block">
|
||||
<span class="keyword">const</span> stats = {<br>
|
||||
messages: <span style="color: var(--accent-orange);">{{message_count}}</span>,<br>
|
||||
active_users: <span
|
||||
style="color: var(--accent-orange);">{{participant_count}}</span>,<br>
|
||||
peak_time: <span
|
||||
style="color: var(--accent-blue);">'{{most_active_period}}'</span><br>
|
||||
};<br>
|
||||
<span class="comment">// Total characters: {{total_characters}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Topics moved into left column -->
|
||||
<div>
|
||||
<div class="section-header">
|
||||
<span class="prompt">$</span> ls ./topics
|
||||
</div>
|
||||
<div class="topic-list">
|
||||
{{topics_html}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Right Side: Visuals & Members -->
|
||||
<div class="right-col">
|
||||
<div class="window">
|
||||
<div class="window-header">
|
||||
<div class="traffic-lights">
|
||||
<div class="light red"></div>
|
||||
<div class="light yellow"></div>
|
||||
<div class="light green"></div>
|
||||
</div>
|
||||
<div class="window-title">trend-analytics.tsx</div>
|
||||
</div>
|
||||
<div class="chart-container">
|
||||
{{hourly_chart_html}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- User Titles grouped here -->
|
||||
<div style="margin-top: 20px;">
|
||||
<div class="section-header">
|
||||
<span class="prompt">$</span> cat ./user_titles
|
||||
</div>
|
||||
<div class="user-grid">
|
||||
{{titles_html}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Golden Quotes grouped here -->
|
||||
<div style="margin-top: 20px;">
|
||||
<div class="section-header">
|
||||
<span class="prompt">$</span> grep -r "golden_quotes"
|
||||
</div>
|
||||
<div class="quote-container">
|
||||
{{quotes_html}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<div>SYSTEM_REPORT // CHANNEL: {{platform_id}} // {{current_datetime}}</div>
|
||||
<div>
|
||||
TOKENS: <span class="footer-token">{{total_tokens}}</span>
|
||||
[P: {{prompt_tokens}} | C: {{completion_tokens}}]
|
||||
</div>
|
||||
<div style="color: var(--accent-orange);">AstrBotDevs/AstrBot 群分析</div>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,394 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Night Mode Analysis Portal (PDF)</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&family=Inter:wght@400;600;800&family=Noto+Sans+SC:wght@400;700&display=swap"
|
||||
rel="stylesheet">
|
||||
<style>
|
||||
/* PDF specific styles */
|
||||
@page {
|
||||
size: A4;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--bg-deep: #0a0a0a;
|
||||
--bg-panel: #141414;
|
||||
--bg-card: #1c1c1c;
|
||||
--text-primary: #ffffff;
|
||||
--text-secondary: #a0a0a0;
|
||||
--accent-orange: #ff9900;
|
||||
--accent-blue: #3399ff;
|
||||
--accent-red: #ff3366;
|
||||
--accent-green: #00ff88;
|
||||
--border-color: #2a2a2a;
|
||||
--grid-color: rgba(255, 255, 255, 0.03);
|
||||
|
||||
--font-mono: 'JetBrains Mono', monospace;
|
||||
--font-body: 'Inter', 'Noto Sans SC', sans-serif;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
-webkit-print-color-adjust: exact;
|
||||
print-color-adjust: exact;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
background-color: var(--bg-deep);
|
||||
color: var(--text-primary);
|
||||
font-family: var(--font-body);
|
||||
background-image:
|
||||
linear-gradient(var(--grid-color) 1px, transparent 1px),
|
||||
linear-gradient(90deg, var(--grid-color) 1px, transparent 1px);
|
||||
background-size: 30px 30px;
|
||||
min-height: 100vh;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.layout {
|
||||
max-width: 1000px;
|
||||
margin: 0 auto;
|
||||
padding: 40px;
|
||||
}
|
||||
|
||||
.main-container {
|
||||
display: grid;
|
||||
grid-template-columns: 1.2fr 0.8fr;
|
||||
/* Balanced 2-column split */
|
||||
gap: 30px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.left-col,
|
||||
.right-col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 30px;
|
||||
}
|
||||
|
||||
/* Terminal Window Style */
|
||||
.window {
|
||||
background: var(--bg-panel);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4);
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.window-header {
|
||||
background: #1e1e1e;
|
||||
padding: 10px 15px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.traffic-lights {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.light {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.light.red {
|
||||
background: #ff5f56;
|
||||
}
|
||||
|
||||
.light.green {
|
||||
background: #27c93f;
|
||||
}
|
||||
|
||||
.window-title {
|
||||
margin-left: 15px;
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.75rem;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.top-nav {
|
||||
display: flex;
|
||||
gap: 15px;
|
||||
margin-bottom: 30px;
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.8rem;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
color: var(--accent-orange);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.prompt {
|
||||
color: var(--accent-orange);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.keyword {
|
||||
color: var(--accent-red);
|
||||
}
|
||||
|
||||
.comment {
|
||||
color: #555;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3.5rem;
|
||||
font-weight: 800;
|
||||
margin: 0 0 15px;
|
||||
letter-spacing: -1.5px;
|
||||
line-height: 1;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
background: var(--bg-card);
|
||||
border: 1px solid rgba(255, 153, 0, 0.2);
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-family: var(--font-mono);
|
||||
color: var(--text-secondary);
|
||||
font-size: 0.8rem;
|
||||
margin-bottom: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.stat-label::before {
|
||||
content: '>';
|
||||
color: var(--accent-orange);
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
font-size: 2.5rem;
|
||||
font-weight: 700;
|
||||
color: var(--accent-orange);
|
||||
font-family: var(--font-mono);
|
||||
}
|
||||
|
||||
.section-header {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 1rem;
|
||||
margin-bottom: 15px;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.code-block {
|
||||
background: rgba(255, 255, 255, 0.02);
|
||||
border: 1px solid var(--border-color);
|
||||
padding: 20px;
|
||||
border-radius: 6px;
|
||||
font-family: var(--font-mono);
|
||||
line-height: 1.5;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.chart-container {
|
||||
height: 220px;
|
||||
position: relative;
|
||||
padding: 20px 5px;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.topic-list,
|
||||
.user-grid,
|
||||
.quote-grid {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.user-card {
|
||||
background: var(--bg-card);
|
||||
border: 1px solid var(--border-color);
|
||||
padding: 15px;
|
||||
border-radius: 6px;
|
||||
display: flex;
|
||||
gap: 15px;
|
||||
border-left: 3px solid var(--accent-blue);
|
||||
}
|
||||
|
||||
.user-avatar {
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.user-info h4 {
|
||||
margin: 0 0 4px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.tag {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.7rem;
|
||||
padding: 1px 6px;
|
||||
border-radius: 3px;
|
||||
border: 1px solid;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.tag.mbti {
|
||||
color: #ffcc00;
|
||||
border-color: rgba(255, 204, 0, 0.3);
|
||||
background: rgba(255, 204, 0, 0.1);
|
||||
}
|
||||
|
||||
.tag.title {
|
||||
color: var(--accent-blue);
|
||||
border-color: rgba(51, 153, 255, 0.3);
|
||||
}
|
||||
|
||||
.topic-item {
|
||||
padding: 15px;
|
||||
border-left: 3px solid var(--accent-orange);
|
||||
background: rgba(255, 255, 255, 0.01);
|
||||
}
|
||||
|
||||
.topic-title {
|
||||
font-weight: bold;
|
||||
font-size: 1.3rem;
|
||||
margin-bottom: 8px;
|
||||
color: var(--accent-orange);
|
||||
}
|
||||
|
||||
.quote-item {
|
||||
padding: 15px;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 6px;
|
||||
display: flex;
|
||||
gap: 15px;
|
||||
align-items: flex-start;
|
||||
background: #111;
|
||||
}
|
||||
|
||||
.quote-avatar {
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
border-radius: 50%;
|
||||
border: 1px solid #333;
|
||||
flex-shrink: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.quote-avatar img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.quote-body {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.quote-text {
|
||||
font-style: italic;
|
||||
font-size: 0.95rem;
|
||||
color: var(--accent-orange);
|
||||
margin-bottom: 5px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
footer {
|
||||
margin-top: 60px;
|
||||
padding-top: 20px;
|
||||
border-top: 1px solid var(--border-color);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.75rem;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.avoid-break {
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="layout">
|
||||
<div class="top-nav">
|
||||
<div class="nav-item">● ready</div>
|
||||
<div class="nav-item">~/report</div>
|
||||
</div>
|
||||
|
||||
<div class="main-container">
|
||||
<!-- Left Column: Insights & Topics -->
|
||||
<div class="left-col">
|
||||
<div>
|
||||
<div class="comment">// Report: {{current_date}}</div>
|
||||
<h1><span class="prompt">></span> Daily Analysis</h1>
|
||||
<div class="code-block">
|
||||
<span class="keyword">stats</span> = {<br>
|
||||
msg: {{message_count}},<br>
|
||||
users: {{participant_count}}<br>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="avoid-break">
|
||||
<div class="section-header"><span class="prompt">$</span> ls ./topics</div>
|
||||
<div class="topic-list">
|
||||
{{topics_html}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Right Column: Chart & People -->
|
||||
<div class="right-col">
|
||||
<div class="window avoid-break">
|
||||
<div class="window-header">
|
||||
<div class="traffic-lights">
|
||||
<div class="light red"></div>
|
||||
<div class="light green"></div>
|
||||
</div>
|
||||
<div class="window-title">activity.log</div>
|
||||
</div>
|
||||
<div class="chart-container">
|
||||
{{hourly_chart_html}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="avoid-break">
|
||||
<div class="section-header"><span class="prompt">$</span> cat users</div>
|
||||
<div class="user-grid">
|
||||
{{titles_html}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="avoid-break">
|
||||
<div class="section-header"><span class="prompt">$</span> grep golden</div>
|
||||
<div class="quote-grid">
|
||||
{{quotes_html}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<div>SYSTEM_REPORT // CHANNEL: {{platform_id}} // {{current_datetime}}</div>
|
||||
<div style="color: var(--accent-orange);">AstrBotDevs/AstrBot 群分析</div>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,24 @@
|
||||
{% if quotes %}
|
||||
<div class="user-grid">
|
||||
{% for quote in quotes %}
|
||||
<div class="quote-item avoid-break">
|
||||
<div class="quote-avatar">
|
||||
{% if quote.avatar_url %}
|
||||
<img src="{{ quote.avatar_url }}" alt="{{ quote.sender }}">
|
||||
{% elif quote.avatar_data %}
|
||||
<img src="{{ quote.avatar_data }}" alt="{{ quote.sender }}">
|
||||
{% else %}
|
||||
<div
|
||||
style="width:100%; height:100%; display:flex; align-items:center; justify-content:center; background: #222; font-family: var(--font-mono); font-size: 10px; color: #444;">
|
||||
ID</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="quote-body">
|
||||
<div class="quote-text">"{{ quote.content }}"</div>
|
||||
<div class="quote-author">-- {{ quote.sender }}</div>
|
||||
<div class="comment" style="font-size: 0.8rem;">// Reason: {{ quote.reason }}</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
@@ -0,0 +1,11 @@
|
||||
{% if topics %}
|
||||
<div class="topic-list">
|
||||
{% for topic in topics %}
|
||||
<div class="topic-item avoid-break">
|
||||
<div class="topic-title">{{ topic.topic.topic }}</div>
|
||||
<div class="comment" style="margin-bottom: 15px;">/* Participants: {{ topic.contributors }} */</div>
|
||||
<div style="line-height: 1.6; opacity: 0.9;">{{ topic.detail | safe }}</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
@@ -0,0 +1,26 @@
|
||||
{% if titles %}
|
||||
<div class="user-grid">
|
||||
{% for title in titles %}
|
||||
<div class="user-card avoid-break">
|
||||
<div class="user-avatar">
|
||||
{% if title.avatar_data %}
|
||||
<img src="{{ title.avatar_data }}" alt="{{ title.name }}"
|
||||
style="width:100%; height:100%; object-fit:cover; border-radius: 6px;">
|
||||
{% else %}
|
||||
<div
|
||||
style="width:100%; height:100%; display:flex; align-items:center; justify-content:center; background: #222; border-radius: 6px; font-family: var(--font-mono); font-size: 10px; color: #444;">
|
||||
ID_REF</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="user-info">
|
||||
<h4>{{ title.name }}</h4>
|
||||
<div style="margin-bottom: 10px;">
|
||||
<span class="tag mbti">{{ title.mbti }}</span>
|
||||
<span class="tag title">{{ title.title }}</span>
|
||||
</div>
|
||||
<div style="font-size: 0.85rem; color: var(--text-secondary); line-height: 1.4;">{{ title.reason }}</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
@@ -1,15 +1,15 @@
|
||||
{% if chart_data %}
|
||||
{% for item in chart_data %}
|
||||
<div class="activity-row">
|
||||
<div class="activity-hour">{{ "%02d"|format(item.hour) }}:00</div>
|
||||
<div class="activity-meter">
|
||||
<div class="activity-bar" style="--pct: {{ "%.2f"|format(item.percentage) }}%;"></div>
|
||||
<div class="activity-container">
|
||||
{% for item in chart_data %}
|
||||
<div class="activity-col">
|
||||
<span class="activity-col-count">{{ item.count }}</span>
|
||||
<div class="activity-bar-vertical" style="--h: {{ " %.2f"|format(item.percentage) }}%;"></div>
|
||||
<span class="activity-label-hour">{{ "%02d"|format(item.hour) }}:00</span>
|
||||
</div>
|
||||
<div class="activity-count">{{ item.count }}</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<div class="activity-row">
|
||||
<div class="topic-meta" style="grid-column: span 3;">NO_DATA_AVAILABLE</div>
|
||||
<div class="activity-col" style="flex:1; justify-content: center; height: 100px;">
|
||||
<div class="topic-meta">NO_DATA_AVAILABLE_FOR_ACTIVITY_SPECTRUM</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,17 +1,20 @@
|
||||
{% if quotes %}
|
||||
{% for quote in quotes %}
|
||||
<article class="quote-item">
|
||||
<span class="color-third"></span>
|
||||
<div class="quote-icon">
|
||||
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6 17h3l2-4V7H5v6h3zm8 0h3l2-4V7h-6v6h3z"/>
|
||||
</svg>
|
||||
<section class="quote-item">
|
||||
{% if quote.avatar_url %}
|
||||
<div class="quote-avatar">
|
||||
<img src="{{ quote.avatar_url }}" alt="{{ quote.sender }}">
|
||||
</div>
|
||||
<div>
|
||||
<p class="quote-content">{{ quote.content }}</p>
|
||||
<div class="quote-author">— {{ quote.sender }}</div>
|
||||
<p class="quote-note">{{ quote.reason }}</p>
|
||||
{% elif quote.avatar_data %}
|
||||
<div class="quote-avatar">
|
||||
<img src="{{ quote.avatar_data }}" alt="{{ quote.sender }}">
|
||||
</div>
|
||||
</article>
|
||||
{% endif %}
|
||||
<div class="quote-body">
|
||||
<div class="quote-content">{{ quote.content }}</div>
|
||||
<div class="quote-author">ORIGIN: {{ quote.sender }}</div>
|
||||
<div class="quote-reason-small">ANALYSIS // {{ quote.reason }}</div>
|
||||
</div>
|
||||
</section>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
@@ -1,17 +1,12 @@
|
||||
{% if topics %}
|
||||
{% for topic in topics %}
|
||||
<article class="topic-item">
|
||||
<span class="color-third"></span>
|
||||
<div class="topic-icon">
|
||||
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H6l-2 2V4h16v12z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<section class="topic-item">
|
||||
<div class="topic-content">
|
||||
<h3 class="topic-title">{{ topic.topic.topic }}</h3>
|
||||
<p class="topic-meta">PARTICIPANTS: {{ topic.contributors }}</p>
|
||||
<p class="topic-detail">{{ topic.detail | safe }}</p>
|
||||
<div class="topic-meta">SUBJECT ID: #{{ "%02d"|format(loop.index) }} // PARTICIPANTS: {{ topic.contributors }}
|
||||
</div>
|
||||
<div class="topic-detail">{{ topic.detail | safe }}</div>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
@@ -1,23 +1,24 @@
|
||||
{% if titles %}
|
||||
{% for title in titles %}
|
||||
<article class="title-item">
|
||||
<div class="title-header">
|
||||
<div class="title-avatar">
|
||||
{% if title.avatar_data %}
|
||||
<img src="{{ title.avatar_data }}" alt="{{ title.name }}">
|
||||
{% else %}
|
||||
<div class="title-avatar-fallback">CRT</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="title-info">
|
||||
<span class="title-name">{{ title.name }}</span>
|
||||
<div class="title-badges">
|
||||
<span class="title-mbti">{{ title.mbti }}</span>
|
||||
<span class="title-role">{{ title.title }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="title-item">
|
||||
<div class="title-avatar-wrap">
|
||||
{% if title.avatar_data %}
|
||||
<img src="{{ title.avatar_data }}" alt="{{ title.name }}">
|
||||
{% else %}
|
||||
<div
|
||||
style="width:100%; height:100%; display:flex; align-items:center; justify-content:center; font-family:var(--font-mono); font-size:12px; opacity:0.3;">
|
||||
DATA_ERR</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<p class="title-reason">{{ title.reason }}</p>
|
||||
</article>
|
||||
<div class="title-info">
|
||||
<h4>{{ title.name }}</h4>
|
||||
<div class="title-badge">
|
||||
<span>{{ title.mbti }}</span>
|
||||
<span style="color:var(--c-dec-3);">//</span>
|
||||
<span>{{ title.title }}</span>
|
||||
</div>
|
||||
<div class="title-reason">{{ title.reason }}</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
Reference in New Issue
Block a user