|
<!DOCTYPE html> |
|
<html lang="zh-CN"> |
|
<head> |
|
<meta charset="UTF-8"> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
<title>{{会议标题}} · 会议纪要</title> |
|
<!-- |
|
============================================================ |
|
会议纪要信息图 · 暖色卡片风格模板 |
|
============================================================ |
|
使用说明: |
|
- 替换 {{}} 占位符为实际内容 |
|
- 按需增减 section / card 数量 |
|
- 卡片网格最后一行:根据卡片数选择 r3-last1/r3-last2/r3-last3 |
|
- 标签颜色:默认珊瑚色,可加 .blue/.green/.amber/.red/.purple/.gray/.teal |
|
- 2列布局:card-grid 加 .cols-2 |
|
- 本地二维码/图片必须先转成 data URI 再写入 img src,避免 PNG 导出失败 |
|
============================================================ |
|
--> |
|
<style> |
|
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@300;400;500;700;900&family=Noto+Serif+SC:wght@600;700;900&display=swap'); |
|
|
|
* { margin: 0; padding: 0; box-sizing: border-box; } |
|
|
|
body { |
|
font-family: 'Noto Sans SC', -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Hiragino Sans GB', sans-serif; |
|
background: #f5f0ea; |
|
color: #2c2420; |
|
display: flex; |
|
flex-direction: column; |
|
align-items: center; |
|
padding: 0; |
|
-webkit-font-smoothing: antialiased; |
|
} |
|
|
|
/* ====== DOWNLOAD BAR (hidden in print) ====== */ |
|
.download-bar { |
|
position: fixed; |
|
top: 0; left: 0; right: 0; |
|
background: rgba(245,240,234,0.95); |
|
backdrop-filter: blur(10px); |
|
padding: 10px 24px; |
|
display: flex; |
|
justify-content: center; |
|
gap: 12px; |
|
z-index: 1000; |
|
border-bottom: 1px solid #e0d6cc; |
|
} |
|
.download-bar button { |
|
padding: 7px 18px; |
|
border: 1px solid #c9bfb3; |
|
background: #fff; |
|
color: #5a4e42; |
|
border-radius: 6px; |
|
font-size: 13px; |
|
cursor: pointer; |
|
font-family: inherit; |
|
transition: all 0.2s; |
|
} |
|
.download-bar button:hover { |
|
background: #f0e8de; |
|
border-color: #b5a898; |
|
} |
|
|
|
/* ====== PAGE WRAPPER ====== */ |
|
.page { |
|
width: 820px; |
|
max-width: 100%; |
|
padding: 64px 0 40px; |
|
} |
|
.infographic { |
|
background: #f5f0ea; |
|
padding: 48px 44px 40px; |
|
} |
|
|
|
/* ====== HEADER ====== */ |
|
.header { |
|
text-align: center; |
|
margin-bottom: 10px; |
|
} |
|
.header h1 { |
|
font-family: 'Noto Serif SC', 'Noto Sans SC', serif; |
|
font-size: 28px; |
|
font-weight: 900; |
|
color: #1a1412; |
|
line-height: 1.5; |
|
letter-spacing: 0; |
|
} |
|
.header-sub { |
|
font-size: 16px; |
|
color: #5a4e42; |
|
font-weight: 500; |
|
margin-top: 8px; |
|
} |
|
.header-meta { |
|
font-size: 13px; |
|
color: #9a8e82; |
|
margin-top: 12px; |
|
padding-bottom: 32px; |
|
border-bottom: 1px solid #e0d6cc; |
|
} |
|
|
|
/* ====== SECTION ====== */ |
|
.section { |
|
margin-top: 32px; |
|
} |
|
.section-head { |
|
display: flex; |
|
align-items: center; |
|
gap: 8px; |
|
margin-bottom: 16px; |
|
} |
|
.section-emoji { font-size: 18px; line-height: 1; } |
|
.section-title { |
|
font-family: 'Noto Serif SC', 'Noto Sans SC', serif; |
|
font-size: 17px; |
|
font-weight: 700; |
|
color: #1a1412; |
|
} |
|
.section-count { |
|
display: inline-block; |
|
padding: 2px 10px; |
|
background: #f0e0d0; |
|
border-radius: 100px; |
|
font-size: 12px; |
|
color: #9a7a5a; |
|
margin-left: 4px; |
|
} |
|
|
|
/* ====== CARD GRID ====== */ |
|
.card-grid { |
|
display: grid; |
|
grid-template-columns: repeat(3, 1fr); |
|
gap: 0; |
|
border: 1px solid #e0d6cc; |
|
border-radius: 10px; |
|
overflow: hidden; |
|
background: #fff; |
|
} |
|
.card-grid.cols-2 { grid-template-columns: repeat(2, 1fr); } |
|
|
|
.card { |
|
padding: 20px; |
|
border-right: 1px solid #ede6dd; |
|
border-bottom: 1px solid #ede6dd; |
|
background: #fff; |
|
} |
|
.card-grid .card:nth-child(3n) { border-right: none; } |
|
.card-grid.cols-2 .card:nth-child(2n) { border-right: none; } |
|
|
|
.card-head { |
|
display: flex; |
|
align-items: flex-start; |
|
justify-content: space-between; |
|
gap: 8px; |
|
margin-bottom: 10px; |
|
flex-wrap: wrap; |
|
} |
|
.card-title { |
|
font-size: 14.5px; |
|
font-weight: 700; |
|
color: #1a1412; |
|
line-height: 1.5; |
|
flex: 1; |
|
min-width: 0; |
|
} |
|
|
|
/* ====== TAG COLORS ====== */ |
|
.card-tag { |
|
display: inline-block; |
|
padding: 2px 10px; |
|
background: #c67a5c; |
|
color: #fff; |
|
border-radius: 4px; |
|
font-size: 11.5px; |
|
font-weight: 500; |
|
white-space: nowrap; |
|
flex-shrink: 0; |
|
line-height: 1.6; |
|
} |
|
.card-tag.blue { background: #6b8fb5; } |
|
.card-tag.green { background: #7ba67e; } |
|
.card-tag.amber { background: #c49a5c; } |
|
.card-tag.red { background: #c06058; } |
|
.card-tag.purple { background: #8b7ab5; } |
|
.card-tag.gray { background: #8a8078; } |
|
.card-tag.teal { background: #5a9a8a; } |
|
|
|
.card-body { |
|
font-size: 13px; |
|
color: #6b5e52; |
|
line-height: 1.85; |
|
} |
|
.card-body strong { color: #3a302a; font-weight: 600; } |
|
|
|
/* ====== QUOTE BOX ====== */ |
|
.quote-box { |
|
background: #fff; |
|
border: 1px solid #e0d6cc; |
|
border-radius: 10px; |
|
padding: 24px 28px; |
|
margin-top: 16px; |
|
} |
|
.quote-text { |
|
font-size: 15.5px; |
|
font-weight: 500; |
|
color: #3a302a; |
|
line-height: 1.8; |
|
padding-left: 16px; |
|
border-left: 3px solid #c67a5c; |
|
} |
|
.quote-author { |
|
font-size: 12.5px; |
|
color: #9a8e82; |
|
margin-top: 10px; |
|
text-align: right; |
|
} |
|
|
|
/* ====== COMPACT QUOTE GRID ====== */ |
|
.quote-grid { |
|
display: grid; |
|
grid-template-columns: repeat(2, 1fr); |
|
gap: 12px; |
|
} |
|
.quote-card { |
|
background: #fff; |
|
border: 1px solid #e0d6cc; |
|
border-radius: 10px; |
|
padding: 16px 18px; |
|
} |
|
.quote-card .quote-text { |
|
font-size: 13.5px; |
|
font-weight: 700; |
|
color: #3a302a; |
|
line-height: 1.7; |
|
padding-left: 12px; |
|
border-left: 3px solid #c67a5c; |
|
} |
|
.quote-card .quote-author { |
|
font-size: 11.5px; |
|
color: #9a8e82; |
|
margin-top: 10px; |
|
text-align: left; |
|
line-height: 1.6; |
|
} |
|
|
|
/* ====== JOIN / CTA PANEL ====== */ |
|
.join-panel { |
|
display: grid; |
|
grid-template-columns: minmax(0, 1fr) 180px; |
|
border: 1px solid #e0d6cc; |
|
border-radius: 10px; |
|
overflow: hidden; |
|
background: #fff; |
|
} |
|
.join-copy { |
|
padding: 22px 24px; |
|
border-right: 1px solid #ede6dd; |
|
} |
|
.join-title { |
|
font-family: 'Noto Serif SC', 'Noto Sans SC', serif; |
|
font-size: 18px; |
|
font-weight: 800; |
|
color: #1a1412; |
|
margin-bottom: 12px; |
|
} |
|
.join-text { |
|
font-size: 13px; |
|
line-height: 1.9; |
|
color: #6b5e52; |
|
} |
|
.join-text strong { color: #3a302a; font-weight: 700; } |
|
.join-note { |
|
margin-top: 14px; |
|
font-size: 11.5px; |
|
color: #b0a397; |
|
} |
|
.qr-wrap { |
|
display: flex; |
|
align-items: center; |
|
justify-content: center; |
|
padding: 18px; |
|
background: #fbf8f5; |
|
} |
|
.qr-wrap img { |
|
width: 136px; |
|
height: 136px; |
|
object-fit: contain; |
|
border-radius: 6px; |
|
} |
|
|
|
/* ====== TODO PRIORITY HEADERS ====== */ |
|
.todo-header { |
|
display: flex; |
|
align-items: center; |
|
gap: 8px; |
|
margin-bottom: 12px; |
|
margin-top: 20px; |
|
} |
|
.todo-priority-badge { |
|
padding: 2px 10px; |
|
border-radius: 4px; |
|
font-size: 12px; |
|
font-weight: 700; |
|
letter-spacing: 0.5px; |
|
} |
|
.todo-priority-badge.p0 { background: #c06058; color: #fff; } |
|
.todo-priority-badge.p1 { background: #c49a5c; color: #fff; } |
|
.todo-priority-badge.p2 { background: #6b8fb5; color: #fff; } |
|
.todo-group-label { |
|
font-size: 14px; |
|
font-weight: 600; |
|
color: #3a302a; |
|
} |
|
|
|
/* ====== LAST-ROW BORDER REMOVAL ====== */ |
|
/* 3-col grid */ |
|
.r3-last1 .card:nth-last-child(1) { border-bottom: none; } |
|
.r3-last2 .card:nth-last-child(-n+2) { border-bottom: none; } |
|
.r3-last3 .card:nth-last-child(-n+3) { border-bottom: none; } |
|
/* 2-col grid */ |
|
.r2-last1 .card:nth-last-child(1) { border-bottom: none; } |
|
.r2-last2 .card:nth-last-child(-n+2) { border-bottom: none; } |
|
|
|
/* ====== FOOTER ====== */ |
|
.footer { |
|
margin-top: 36px; |
|
padding-top: 20px; |
|
border-top: 1px solid #e0d6cc; |
|
text-align: center; |
|
font-size: 12px; |
|
color: #9a8e82; |
|
line-height: 1.8; |
|
} |
|
|
|
/* ====== PRINT ====== */ |
|
@media print { |
|
.download-bar { display: none !important; } |
|
.page { padding: 0; } |
|
.infographic { padding: 36px 40px; } |
|
@page { size: A3 portrait; margin: 10mm; } |
|
} |
|
@media (max-width: 720px) { |
|
.quote-grid { grid-template-columns: 1fr; } |
|
.join-panel { grid-template-columns: 1fr; } |
|
.join-copy { border-right: none; border-bottom: 1px solid #ede6dd; } |
|
} |
|
</style> |
|
</head> |
|
<body> |
|
|
|
<!-- ==================== DOWNLOAD BAR ==================== --> |
|
<div class="download-bar"> |
|
<button onclick="window.print()">Save as PDF (Cmd/Ctrl + P)</button> |
|
<button onclick="downloadAsPng(this)">Download as PNG</button> |
|
</div> |
|
|
|
<div class="page"> |
|
<div class="infographic" id="infographic"> |
|
|
|
<!-- ==================== HEADER ==================== --> |
|
<div class="header"> |
|
<h1>{{会议标题}}</h1> |
|
<div class="header-sub">会议纪要</div> |
|
<div class="header-meta">{{日期}} · 参会人:{{参会人}} · {{主题简述}}</div> |
|
</div> |
|
|
|
<!-- ==================== KEYNOTE QUOTE (可选) ==================== --> |
|
<div class="quote-box"> |
|
<div class="quote-text">"{{核心引言原话}}"</div> |
|
<div class="quote-author">—— {{发言人}} · {{上下文}}</div> |
|
</div> |
|
|
|
<!-- ==================== 锋利金句:紧凑 2 列 (可选,3句以上优先用这个) ==================== --> |
|
<div class="section"> |
|
<div class="section-head"> |
|
<span class="section-emoji">✦</span> |
|
<span class="section-title">锋利金句</span> |
|
<span class="section-count">{{N}} 句</span> |
|
</div> |
|
<div class="quote-grid"> |
|
<div class="quote-card"> |
|
<div class="quote-text">"{{真正犀利的原话}}"</div> |
|
<div class="quote-author">{{发言人}} · {{为什么这句话重要}}</div> |
|
</div> |
|
<!-- 更多金句... --> |
|
</div> |
|
</div> |
|
|
|
<!-- ==================== 数据速览 (可选) ==================== --> |
|
<div class="section"> |
|
<div class="section-head"> |
|
<span class="section-emoji">📊</span> |
|
<span class="section-title">{{板块标题}}</span> |
|
<span class="section-count">{{N}} 个关键数据</span> |
|
</div> |
|
<div class="card-grid r3-last1"> |
|
<!-- 根据卡片总数选择 r3-last1 / r3-last2 / r3-last3 --> |
|
<div class="card"> |
|
<div class="card-head"> |
|
<span class="card-title">{{卡片标题}}</span> |
|
<!-- 标签可选,不需要就删掉 --> |
|
<span class="card-tag">{{人名/类别}}</span> |
|
</div> |
|
<div class="card-body">{{卡片正文,支持 <strong>加粗</strong>。}}</div> |
|
</div> |
|
<!-- 更多卡片... --> |
|
</div> |
|
</div> |
|
|
|
<!-- ==================== 议题板块 (重复) ==================== --> |
|
<div class="section"> |
|
<div class="section-head"> |
|
<span class="section-emoji">{{emoji}}</span> |
|
<span class="section-title">{{板块标题}}</span> |
|
<span class="section-count">{{N}} 个{{单位}}</span> |
|
</div> |
|
<div class="card-grid r3-last3"> |
|
<div class="card"> |
|
<div class="card-head"> |
|
<span class="card-title">{{卡片标题}}</span> |
|
<span class="card-tag red">{{标签}}</span> |
|
</div> |
|
<div class="card-body">{{内容}}</div> |
|
</div> |
|
<!-- 更多卡片... --> |
|
</div> |
|
</div> |
|
|
|
<!-- ==================== 2列布局示例 ==================== --> |
|
<div class="section"> |
|
<div class="section-head"> |
|
<span class="section-emoji">{{emoji}}</span> |
|
<span class="section-title">{{板块标题}}</span> |
|
<span class="section-count">{{N}} 个{{单位}}</span> |
|
</div> |
|
<div class="card-grid cols-2 r2-last2"> |
|
<div class="card"> |
|
<div class="card-head"> |
|
<span class="card-title">{{卡片标题}}</span> |
|
<span class="card-tag purple">{{标签}}</span> |
|
</div> |
|
<div class="card-body">{{较长内容,2列卡片适合信息量大的内容}}</div> |
|
</div> |
|
<!-- 更多卡片... --> |
|
</div> |
|
</div> |
|
|
|
<!-- ==================== TODO 清单 ==================== --> |
|
<div class="section"> |
|
<div class="section-head"> |
|
<span class="section-emoji">✅</span> |
|
<span class="section-title">TODO 行动清单</span> |
|
<span class="section-count">{{N}} 项行动</span> |
|
</div> |
|
|
|
<!-- P0 组 --> |
|
<div class="todo-header"> |
|
<span class="todo-priority-badge p0">P0</span> |
|
<span class="todo-group-label">立即行动</span> |
|
</div> |
|
<div class="card-grid r3-last2"> |
|
<div class="card"> |
|
<div class="card-head"> |
|
<span class="card-title">{{任务标题}}</span> |
|
<span class="card-tag green">{{负责人}}</span> |
|
</div> |
|
<div class="card-body">{{任务描述}}。<strong>{{时间要求}}</strong>。</div> |
|
</div> |
|
<!-- 更多卡片... --> |
|
</div> |
|
|
|
<!-- P1 组 --> |
|
<div class="todo-header"> |
|
<span class="todo-priority-badge p1">P1</span> |
|
<span class="todo-group-label">近期推进</span> |
|
</div> |
|
<div class="card-grid r3-last3"> |
|
<!-- 卡片... --> |
|
</div> |
|
|
|
<!-- P2 组 (可选) --> |
|
<div class="todo-header"> |
|
<span class="todo-priority-badge p2">P2</span> |
|
<span class="todo-group-label">持续跟进</span> |
|
</div> |
|
<div class="card-grid r3-last1"> |
|
<!-- 卡片... --> |
|
</div> |
|
</div> |
|
|
|
<!-- ==================== 后续活动方向 (社群活动可选) ==================== --> |
|
<div class="section"> |
|
<div class="section-head"> |
|
<span class="section-emoji">🧭</span> |
|
<span class="section-title">后续活动方向</span> |
|
<span class="section-count">{{N}} 种形态</span> |
|
</div> |
|
<div class="card-grid r3-last1"> |
|
<div class="card"> |
|
<div class="card-head"> |
|
<span class="card-title">聊天局</span> |
|
<span class="card-tag green">进展</span> |
|
</div> |
|
<div class="card-body">互相聊聊彼此最近的进展,以及各自正在做的事情推进到哪里了。</div> |
|
</div> |
|
<!-- Demo 演示局 / 主题局 / 日常发掘等,按会议真实内容增删 --> |
|
</div> |
|
</div> |
|
|
|
<!-- ==================== 入群 / 报名 CTA (用户提供二维码时可选) ==================== --> |
|
<div class="section"> |
|
<div class="section-head"> |
|
<span class="section-emoji">🐟</span> |
|
<span class="section-title">{{CTA 标题}}</span> |
|
<span class="section-count">扫码加入</span> |
|
</div> |
|
<div class="join-panel"> |
|
<div class="join-copy"> |
|
<div class="join-title">{{加入组织/社群名}}</div> |
|
<div class="join-text">{{加入理由与后续可参与的事情}}</div> |
|
<div class="join-note">{{二维码有效期或备注}}</div> |
|
</div> |
|
<div class="qr-wrap"> |
|
<img src="{{二维码 data URI,不要用本地 file 路径}}" alt="{{二维码说明}}"> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<!-- ==================== 共识 (可选) ==================== --> |
|
<div class="section"> |
|
<div class="section-head"> |
|
<span class="section-emoji">🤝</span> |
|
<span class="section-title">团队共识</span> |
|
<span class="section-count">{{N}} 项共识</span> |
|
</div> |
|
<div class="card-grid r3-last2"> |
|
<div class="card"> |
|
<div class="card-head"> |
|
<span class="card-title">{{共识标题}}</span> |
|
</div> |
|
<div class="card-body">{{共识说明}}</div> |
|
</div> |
|
<!-- 更多卡片... --> |
|
</div> |
|
</div> |
|
|
|
<!-- ==================== FOOTER ==================== --> |
|
<div class="footer"> |
|
{{团队/项目名}} · 会议纪要 · {{日期}}<br> |
|
{{备注信息}} |
|
</div> |
|
|
|
</div> |
|
</div> |
|
|
|
<!-- ==================== PNG EXPORT ==================== --> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script> |
|
<script> |
|
async function downloadAsPng(button) { |
|
const btn = button || event.target; |
|
const originalText = btn ? btn.textContent : 'Download as PNG'; |
|
const el = document.getElementById('infographic'); |
|
try { |
|
if (!window.html2canvas) { |
|
throw new Error('html2canvas 没有加载成功,请确认当前浏览器可以访问 CDN。'); |
|
} |
|
if (btn) { |
|
btn.textContent = 'Generating...'; |
|
btn.disabled = true; |
|
} |
|
const canvas = await html2canvas(el, { |
|
scale: 2, |
|
backgroundColor: '#f5f0ea', |
|
useCORS: true, |
|
allowTaint: false, |
|
logging: false, |
|
windowWidth: 820 |
|
}); |
|
const blob = await new Promise(resolve => canvas.toBlob(resolve, 'image/png')); |
|
if (!blob) { |
|
throw new Error('浏览器没有生成 PNG 数据。'); |
|
} |
|
const url = URL.createObjectURL(blob); |
|
const link = document.createElement('a'); |
|
link.download = '{{文件名}}.png'; |
|
link.href = url; |
|
document.body.appendChild(link); |
|
link.click(); |
|
link.remove(); |
|
setTimeout(() => URL.revokeObjectURL(url), 1000); |
|
} catch (err) { |
|
console.error(err); |
|
alert('PNG 下载失败:' + err.message); |
|
} finally { |
|
if (btn) { |
|
btn.textContent = originalText; |
|
btn.disabled = false; |
|
} |
|
} |
|
} |
|
</script> |
|
|
|
</body> |
|
</html> |