feat: add daily tip & case auto-publish system

- GitHub Actions workflow: daily-content.yml (UTC 00:00 / 北京 08:00)
- Content generation script: .github/scripts/generate-daily.js (Claude API)
- Initial data: website/daily/data.json
- website/index.html: new 每日精选 section with bilingual support

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
hfshfg
2026-04-02 20:06:49 +08:00
parent 5c7408495d
commit f3530888f3
4 changed files with 403 additions and 0 deletions

View File

@@ -309,6 +309,61 @@
.hidden { display: none !important; }
/* Daily section */
.daily-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
gap: 24px;
margin-bottom: 32px;
}
.daily-card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 16px;
padding: 28px;
transition: border-color 0.2s;
}
.daily-card:hover { border-color: var(--accent); }
.daily-card-header {
display: flex;
align-items: center;
gap: 10px;
margin-bottom: 14px;
}
.daily-date {
text-align: center;
color: var(--text-dim);
font-size: 14px;
margin-bottom: 32px;
}
.daily-history {
margin-top: 32px;
}
.daily-history-toggle {
display: block;
width: 100%;
background: transparent;
border: 1px solid var(--border);
color: var(--text-dim);
padding: 10px;
border-radius: 10px;
cursor: pointer;
font-size: 14px;
transition: all 0.2s;
}
.daily-history-toggle:hover { border-color: var(--accent); color: var(--text); }
.daily-history-list { display: none; margin-top: 20px; }
.daily-history-list.open { display: block; }
.daily-history-item {
border-top: 1px solid var(--border);
padding: 20px 0;
}
.daily-history-item-date {
font-size: 13px;
color: var(--text-dim);
margin-bottom: 12px;
}
@media (max-width: 640px) {
.stats { gap: 24px; }
.hero-cta { flex-direction: column; align-items: center; }
@@ -642,6 +697,63 @@
</div>
</section>
<!-- Daily Tip & Case -->
<section id="daily" style="border-top: 1px solid var(--border); padding-top: 80px;">
<h2>
<span class="zh">每日精选</span>
<span class="en hidden">Daily Picks</span>
</h2>
<p class="section-sub">
<span class="zh">每天更新 · OpenClaw / U-Claw 使用技巧与最佳案例</span>
<span class="en hidden">Updated daily · Tips &amp; best-practice cases for OpenClaw / U-Claw</span>
</p>
<div id="daily-date" class="daily-date"></div>
<div id="daily-loading" style="text-align:center;color:var(--text-dim);padding:40px 0;">
<span class="zh">加载中…</span><span class="en hidden">Loading…</span>
</div>
<div id="daily-content" style="display:none;">
<div class="daily-grid">
<!-- Tip card -->
<div class="daily-card">
<div class="daily-card-header">
<span class="tag tag-blue" style="margin-bottom:0;">
<span class="zh">技巧</span><span class="en hidden">Tip</span>
</span>
</div>
<h3 id="tip-title" style="font-size:18px;margin-bottom:10px;"></h3>
<p id="tip-content" style="color:var(--text-dim);font-size:14px;line-height:1.8;"></p>
</div>
<!-- Case card -->
<div class="daily-card">
<div class="daily-card-header">
<span class="tag tag-green" style="margin-bottom:0;">
<span class="zh">案例</span><span class="en hidden">Case</span>
</span>
</div>
<h3 id="case-title" style="font-size:18px;margin-bottom:10px;"></h3>
<p id="case-content" style="color:var(--text-dim);font-size:14px;line-height:1.8;"></p>
</div>
</div>
<!-- History -->
<div class="daily-history">
<button class="daily-history-toggle" onclick="toggleDailyHistory(this)">
<span class="zh">查看最近 7 天历史 ▼</span>
<span class="en hidden">Recent 7 days history ▼</span>
</button>
<div class="daily-history-list" id="daily-history-list"></div>
</div>
</div>
<div id="daily-error" style="display:none;text-align:center;color:var(--text-dim);padding:40px 0;">
<span class="zh">内容暂时无法加载,请稍后刷新</span>
<span class="en hidden">Content unavailable, please refresh later</span>
</div>
</section>
<!-- CTA -->
<div class="cta-section">
<h2>
@@ -774,7 +886,81 @@ function switchLang(lang) {
document.getElementById('btn-zh').classList.toggle('active', lang === 'zh');
document.getElementById('btn-en').classList.toggle('active', lang === 'en');
document.documentElement.lang = lang === 'zh' ? 'zh-CN' : 'en';
// Re-render daily content text after lang switch
if (window._dailyData) renderDaily(window._dailyData);
}
function getCurrentLang() {
return document.getElementById('btn-zh').classList.contains('active') ? 'zh' : 'en';
}
function t(obj) {
const lang = getCurrentLang();
return obj ? (obj[lang] || obj.zh || '') : '';
}
function renderDaily(data) {
const lang = getCurrentLang();
const latest = data.latest;
if (!latest) return;
document.getElementById('daily-date').textContent =
lang === 'zh' ? `更新日期:${latest.date}` : `Updated: ${latest.date}`;
document.getElementById('tip-title').textContent = t(latest.tip.title);
document.getElementById('tip-content').textContent = t(latest.tip.content);
document.getElementById('case-title').textContent = t(latest.case.title);
document.getElementById('case-content').textContent = t(latest.case.content);
// History (up to 7 entries)
const histList = document.getElementById('daily-history-list');
const recent = (data.history || []).slice(0, 7);
histList.innerHTML = recent.map(entry => `
<div class="daily-history-item">
<div class="daily-history-item-date">${entry.date}</div>
<div class="daily-grid" style="margin-bottom:0;">
<div class="daily-card">
<div class="daily-card-header">
<span class="tag tag-blue" style="margin-bottom:0;">${t(entry.tip.tag)}</span>
</div>
<h3 style="font-size:16px;margin-bottom:8px;">${t(entry.tip.title)}</h3>
<p style="color:var(--text-dim);font-size:13px;line-height:1.8;">${t(entry.tip.content)}</p>
</div>
<div class="daily-card">
<div class="daily-card-header">
<span class="tag tag-green" style="margin-bottom:0;">${t(entry.case.tag)}</span>
</div>
<h3 style="font-size:16px;margin-bottom:8px;">${t(entry.case.title)}</h3>
<p style="color:var(--text-dim);font-size:13px;line-height:1.8;">${t(entry.case.content)}</p>
</div>
</div>
</div>`).join('');
}
function toggleDailyHistory(btn) {
const list = document.getElementById('daily-history-list');
const open = list.classList.toggle('open');
const lang = getCurrentLang();
if (lang === 'zh') {
btn.querySelector('.zh').textContent = open ? '收起历史 ▲' : '查看最近 7 天历史 ▼';
} else {
btn.querySelector('.en').textContent = open ? 'Collapse history ▲' : 'Recent 7 days history ▼';
}
}
// Load daily data
fetch('daily/data.json?v=' + Date.now())
.then(r => r.json())
.then(data => {
window._dailyData = data;
document.getElementById('daily-loading').style.display = 'none';
document.getElementById('daily-content').style.display = 'block';
renderDaily(data);
})
.catch(() => {
document.getElementById('daily-loading').style.display = 'none';
document.getElementById('daily-error').style.display = 'block';
});
</script>
</body>
</html>