front/assets/dashboard/viral_dashboard.html
2026-06-04 19:15:28 +08:00

345 lines
13 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>爆款内容仪表板</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
body {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 20px;
}
.dashboard-card {
background: white;
border-radius: 15px;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
padding: 25px;
margin-bottom: 20px;
}
.metric-card {
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
border-radius: 10px;
padding: 20px;
text-align: center;
margin-bottom: 15px;
}
.metric-value {
font-size: 2rem;
font-weight: bold;
color: #667eea;
}
.metric-label {
color: #666;
font-size: 0.9rem;
}
.btn-primary {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border: none;
}
.btn-primary:hover {
background: linear-gradient(135deg, #764ba2 0%, #667eea 100%);
}
.stat-icon {
font-size: 1.5rem;
margin-bottom: 10px;
}
</style>
</head>
<body>
<div class="container">
<div class="row mb-4">
<div class="col-12">
<div class="dashboard-card">
<h1 class="text-center mb-0">🚀 爆款内容仪表板</h1>
<p class="text-center text-muted mb-0">基于实时热点数据的智能内容生成系统</p>
</div>
</div>
</div>
<!-- 数据概览 -->
<div class="row mb-4">
<div class="col-md-3">
<div class="metric-card">
<div class="stat-icon">📊</div>
<div class="metric-value" id="topics-count">-</div>
<div class="metric-label">热门话题</div>
</div>
</div>
<div class="col-md-3">
<div class="metric-card">
<div class="stat-icon">📈</div>
<div class="metric-value" id="analysis-status">-</div>
<div class="metric-label">分析状态</div>
</div>
</div>
<div class="col-md-3">
<div class="metric-card">
<div class="stat-icon">✍️</div>
<div class="metric-value" id="generated-count">-</div>
<div class="metric-label">已生成内容</div>
</div>
</div>
<div class="col-md-3">
<div class="metric-card">
<div class="stat-icon">🔄</div>
<div class="metric-value" id="last-update">-</div>
<div class="metric-label">最后更新</div>
</div>
</div>
</div>
<!-- 功能区 -->
<div class="row">
<div class="col-md-6">
<div class="dashboard-card">
<h3>📊 热点追踪</h3>
<div class="mb-3">
<label class="form-label">搜索关键词</label>
<input type="text" class="form-control" id="search-keyword" placeholder="输入关键词,如:AI工具">
</div>
<div class="mb-3">
<label class="form-label">数量</label>
<input type="number" class="form-control" id="search-count" value="10" min="5" max="50">
</div>
<button class="btn btn-primary w-100" onclick="searchNotes()">
🔍 搜索爆款笔记
</button>
</div>
</div>
<div class="col-md-6">
<div class="dashboard-card">
<h3>📝 内容生成</h3>
<div class="mb-3">
<label class="form-label">赛道</label>
<input type="text" class="form-control" id="niche-keyword" placeholder="如:AI工具、省钱攻略">
</div>
<div class="mb-3">
<label class="form-label">生成数量</label>
<input type="number" class="form-control" id="generate-count" value="3" min="1" max="10">
</div>
<div class="mb-3">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="use-trends" checked>
<label class="form-check-label" for="use-trends">
使用热点数据优化
</label>
</div>
</div>
<div class="mb-3">
<label class="form-label">API密钥</label>
<input type="password" class="form-control" id="api-key" placeholder="智谱AI API密钥">
</div>
<button class="btn btn-primary w-100" onclick="generateContent()">
✨ 生成爆款内容
</button>
</div>
</div>
</div>
<!-- 分析结果 -->
<div class="row mt-4" id="results-section" style="display:none;">
<div class="col-12">
<div class="dashboard-card">
<h3>📈 分析结果</h3>
<div id="analysis-content"></div>
</div>
</div>
</div>
<!-- 生成的内容 -->
<div class="row mt-4" id="generated-section" style="display:none;">
<div class="col-12">
<div class="dashboard-card">
<h3>✍️ 生成的内容</h3>
<div id="generated-content"></div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
// 页面加载时更新数据
document.addEventListener('DOMContentLoaded', function() {
updateDashboard();
});
// 更新仪表板数据
async function updateDashboard() {
try {
const response = await fetch('/api/dashboard-data');
const data = await response.json();
document.getElementById('topics-count').textContent = data.latest_topics_count;
document.getElementById('analysis-status').textContent = data.has_analysis ? '已完成' : '未分析';
document.getElementById('generated-count').textContent = data.generated_content_count;
document.getElementById('last-update').textContent = data.last_update?.split(' ')[1] || '-';
} catch (error) {
console.error('更新失败:', error);
}
}
// 搜索笔记
async function searchNotes() {
const keyword = document.getElementById('search-keyword').value;
const count = document.getElementById('search-count').value;
if (!keyword) {
alert('请输入搜索关键词');
return;
}
const button = event.target;
button.disabled = true;
button.textContent = '🔍 搜索中...';
try {
const response = await fetch('/api/search-notes', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({keyword, count: parseInt(count)})
});
const data = await response.json();
if (data.success) {
alert(`找到 ${data.count} 篇笔记!`);
// 自动分析
if (data.notes.length > 0) {
await analyzeNotes(data.notes.map(n => n.url).slice(0, 5));
}
} else {
alert('搜索失败: ' + data.error);
}
} catch (error) {
alert('搜索出错: ' + error);
} finally {
button.disabled = false;
button.textContent = '🔍 搜索爆款笔记';
updateDashboard();
}
}
// 分析笔记
async function analyzeNotes(urls) {
try {
const response = await fetch('/api/analyze-notes', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({urls})
});
const data = await response.json();
if (data.success) {
displayAnalysis(data.report_summary);
}
} catch (error) {
console.error('分析失败:', error);
}
}
// 显示分析结果
function displayAnalysis(summary) {
const section = document.getElementById('results-section');
const content = document.getElementById('analysis-content');
section.style.display = 'block';
content.innerHTML = `
<div class="row">
<div class="col-md-4">
<h5>📊 样本数量</h5>
<p class="lead">${summary.sample_size}篇</p>
</div>
<div class="col-md-4">
<h5>🏆 最常见标题类型</h5>
<p class="lead">${summary.top_title_type || '未知'}</p>
</div>
<div class="col-md-4">
<h5>💭 最强情绪触发</h5>
<p class="lead">${summary.top_emotion || '未知'}</p>
</div>
</div>
<hr>
<h5>💡 优化建议</h5>
<ul>
${summary.recommendations.map(r => `<li>${r}</li>`).join('')}
</ul>
`;
}
// 生成内容
async function generateContent() {
const niche = document.getElementById('niche-keyword').value;
const count = document.getElementById('generate-count').value;
const useTrends = document.getElementById('use-trends').checked;
const apiKey = document.getElementById('api-key').value;
if (!niche || !apiKey) {
alert('请填写赛道和API密钥');
return;
}
const button = event.target;
button.disabled = true;
button.textContent = '✨ 生成中...';
try {
const response = await fetch('/api/generate-content', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
niche,
count: parseInt(count),
use_trends: useTrends,
api_key: apiKey
})
});
const data = await response.json();
if (data.success) {
displayGenerated(data.contents);
alert(`成功生成 ${data.generated_count} 篇内容!`);
} else {
alert('生成失败: ' + data.error);
}
} catch (error) {
alert('生成出错: ' + error);
} finally {
button.disabled = false;
button.textContent = '✨ 生成爆款内容';
updateDashboard();
}
}
// 显示生成的内容
function displayGenerated(contents) {
const section = document.getElementById('generated-section');
const content = document.getElementById('generated-content');
section.style.display = 'block';
content.innerHTML = contents.map((item, index) => `
<div class="card mb-3">
<div class="card-body">
<h5 class="card-title">${item.emoji} ${item.title}</h5>
<p class="card-text">${item.content}</p>
<p class="mb-0"><strong>标签:</strong> ${item.tags.join(', ')}</p>
<small class="text-muted">优化策略: ${item.optimization.title_strategy || '默认'}</small>
</div>
</div>
`).join('');
}
// 定时刷新
setInterval(updateDashboard, 30000);
</script>
</body>
</html>