Files
ppt/ppt_manager/templates/index.html

182 lines
9.4 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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>PPT智能管理系统</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
@keyframes spin {
to { transform: rotate(360deg); }
}
.animate-spin {
animation: spin 1s linear infinite;
}
</style>
</head>
<body class="bg-gradient-to-br from-blue-50 to-indigo-100 min-h-screen">
<div class="container mx-auto px-4 py-8 max-w-5xl">
<div class="text-center mb-10">
<h1 class="text-4xl font-bold text-transparent bg-clip-text bg-gradient-to-r from-blue-600 to-purple-600 mb-3">
📊 PPT智能管理系统
</h1>
<p class="text-gray-600 text-lg">静态模板 + 动态数据 = 一键生成最新报告</p>
</div>
<div class="grid md:grid-cols-2 gap-6 mb-8">
<div class="bg-white rounded-2xl shadow-xl p-6">
<h2 class="text-xl font-semibold text-gray-800 mb-4 flex items-center">
<span class="mr-2">📁</span> 可用项目
</h2>
<div id="projects-list" class="space-y-3">
{% for project in projects %}
<div class="project-card border-2 border-gray-200 hover:border-blue-400 rounded-xl p-4 transition-all duration-300 hover:shadow-md cursor-pointer" data-project="{{ project.id }}">
<div class="flex justify-between items-center">
<div>
<h3 class="font-bold text-gray-800">{{ project.name }}</h3>
<p class="text-sm text-gray-500">共 {{ project.total_slides }} 页</p>
</div>
<button onclick="generatePPT('{{ project.id }}')"
class="bg-gradient-to-r from-blue-500 to-blue-600 hover:from-blue-600 hover:to-blue-700 text-white px-5 py-2.5 rounded-lg font-medium transition-all duration-300 transform hover:scale-105 shadow-md hover:shadow-lg">
🚀 开始生成
</button>
</div>
<div class="mt-3 text-xs text-gray-500">
<span class="bg-green-100 text-green-700 px-2 py-1 rounded-full mr-1">
{% set static_pages = project.slide_mapping.values() | list %}
静态: {{ static_pages | count_item('static') }} 页
</span>
<span class="bg-orange-100 text-orange-700 px-2 py-1 rounded-full">
{% set static_count = static_pages | count_item('static') %}
动态: {{ project.total_slides - static_count }} 页
</span>
</div>
</div>
{% endfor %}
</div>
<div id="status" class="mt-4 hidden">
<div class="bg-blue-50 border border-blue-200 rounded-lg p-4">
<div class="flex items-center">
<svg class="animate-spin h-5 w-5 mr-3 text-blue-500" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4" fill="none"></circle>
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
<span id="status-text" class="text-blue-700 font-medium">正在生成PPT请稍候...</span>
</div>
</div>
</div>
<div id="result" class="mt-4 hidden">
<div class="bg-green-50 border border-green-200 rounded-lg p-4">
<div class="flex items-center justify-between">
<div>
<p class="text-green-700 font-bold">✅ PPT生成成功</p>
<p id="result-filename" class="text-green-600 text-sm mt-1"></p>
</div>
<a id="download-btn" href="#" class="bg-green-500 hover:bg-green-600 text-white px-4 py-2 rounded-lg font-medium transition-colors">
📥 下载文件
</a>
</div>
</div>
</div>
<div id="error" class="mt-4 hidden">
<div class="bg-red-50 border border-red-200 rounded-lg p-4">
<p class="text-red-700 font-bold">❌ 生成失败</p>
<p id="error-message" class="text-red-600 text-sm mt-1"></p>
</div>
</div>
</div>
<div class="bg-white rounded-2xl shadow-xl p-6">
<h2 class="text-xl font-semibold text-gray-800 mb-4 flex items-center">
<span class="mr-2">📋</span> 已生成文件
</h2>
<div id="files-list" class="space-y-2 max-h-96 overflow-y-auto">
<p class="text-gray-500 text-sm">加载中...</p>
</div>
</div>
</div>
<div class="bg-white rounded-2xl shadow-xl p-6">
<h2 class="text-xl font-semibold text-gray-800 mb-4 flex items-center">
<span class="mr-2">📖</span> 使用说明
</h2>
<div class="grid md:grid-cols-3 gap-4 text-sm">
<div class="bg-gray-50 rounded-xl p-4">
<h3 class="font-bold text-gray-700 mb-2">1⃣ 准备静态模板</h3>
<p class="text-gray-600">将固定不变的PPT模板放入 static_ppt 目录</p>
</div>
<div class="bg-gray-50 rounded-xl p-4">
<h3 class="font-bold text-gray-700 mb-2">2⃣ 配置页面映射</h3>
<p class="text-gray-600">在 config/project_config.yaml 中配置每页是静态或动态</p>
</div>
<div class="bg-gray-50 rounded-xl p-4">
<h3 class="font-bold text-gray-700 mb-2">3⃣ 编写动态脚本</h3>
<p class="text-gray-600">在 scripts 目录编写数据爬取和图表生成脚本</p>
</div>
</div>
</div>
</div>
<script>
function generatePPT(projectName) {
const statusEl = document.getElementById('status');
const resultEl = document.getElementById('result');
const errorEl = document.getElementById('error');
statusEl.classList.remove('hidden');
resultEl.classList.add('hidden');
errorEl.classList.add('hidden');
fetch(`/api/generate/${projectName}`, { method: 'POST' })
.then(response => response.json())
.then(data => {
statusEl.classList.add('hidden');
if (data.success) {
resultEl.classList.remove('hidden');
document.getElementById('result-filename').textContent = data.filename;
document.getElementById('download-btn').href = data.download_url;
loadFiles();
} else {
errorEl.classList.remove('hidden');
document.getElementById('error-message').textContent = data.message;
}
})
.catch(err => {
statusEl.classList.add('hidden');
errorEl.classList.remove('hidden');
document.getElementById('error-message').textContent = err.message;
});
}
function loadFiles() {
fetch('/api/files')
.then(response => response.json())
.then(data => {
const filesList = document.getElementById('files-list');
if (data.files.length === 0) {
filesList.innerHTML = '<p class="text-gray-500 text-sm">暂无生成的文件</p>';
} else {
filesList.innerHTML = data.files.map(f => `
<div class="flex justify-between items-center bg-gray-50 rounded-lg p-3 hover:bg-gray-100 transition-colors">
<div>
<p class="font-medium text-gray-700 text-sm">${f.name}</p>
<p class="text-xs text-gray-500">${f.size} MB</p>
</div>
<a href="/download/${f.name}" class="text-blue-500 hover:text-blue-700 text-sm font-medium">
下载
</a>
</div>
`).join('');
}
});
}
loadFiles();
</script>
</body>
</html>