|
|
<!DOCTYPE html>
|
|
|
<html lang="zh-CN">
|
|
|
<head>
|
|
|
<meta charset="UTF-8">
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
<title>画廊下载管理器</title>
|
|
|
<style>
|
|
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
|
body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); min-height: 100vh; padding: 20px; }
|
|
|
.container { max-width: 1200px; margin: 0 auto; background: white; border-radius: 15px; box-shadow: 0 20px 40px rgba(0,0,0,0.1); overflow: hidden; }
|
|
|
.header { background: linear-gradient(135deg, #2c3e50, #34495e); color: white; padding: 30px; text-align: center; }
|
|
|
.header h1 { font-size: 2.5em; margin-bottom: 10px; }
|
|
|
.controls { padding: 20px; background: #f8f9fa; border-bottom: 1px solid #e9ecef; display: flex; gap: 15px; flex-wrap: wrap; }
|
|
|
.btn { padding: 12px 24px; border: none; border-radius: 8px; font-size: 16px; font-weight: 600; cursor: pointer; transition: all 0.3s ease; }
|
|
|
.btn-primary { background: #007bff; color: white; }
|
|
|
.btn-primary:hover { background: #0056b3; }
|
|
|
.btn-success { background: #28a745; color: white; }
|
|
|
.btn-success:hover { background: #1e7e34; }
|
|
|
.btn-danger { background: #dc3545; color: white; }
|
|
|
.btn-danger:hover { background: #c82333; }
|
|
|
.gallery-list { padding: 20px; }
|
|
|
.gallery-item { background: white; border: 1px solid #e9ecef; border-radius: 10px; padding: 20px; margin-bottom: 15px; }
|
|
|
.gallery-title { font-size: 1.3em; font-weight: 600; color: #2c3e50; margin-bottom: 8px; }
|
|
|
.gallery-stats { display: flex; gap: 20px; color: #6c757d; font-size: 0.9em; }
|
|
|
.progress-bar { width: 100%; height: 8px; background: #e9ecef; border-radius: 4px; overflow: hidden; margin-top: 8px; }
|
|
|
.progress-fill { height: 100%; background: linear-gradient(90deg, #28a745, #20c997); transition: width 0.3s ease; }
|
|
|
.empty-state { text-align: center; padding: 60px 20px; color: #6c757d; }
|
|
|
</style>
|
|
|
</head>
|
|
|
<body>
|
|
|
<div class="container">
|
|
|
<div class="header">
|
|
|
<h1>🎨 画廊下载管理器</h1>
|
|
|
<p>管理您的画廊下载任务</p>
|
|
|
</div>
|
|
|
|
|
|
<div class="controls">
|
|
|
<button class="btn btn-primary" onclick="loadGalleries()">📁 读取文件夹</button>
|
|
|
<button class="btn btn-success" onclick="startDownload()" id="downloadBtn">⬇️ 开始下载所有未完成</button>
|
|
|
<button class="btn btn-danger" onclick="cleanupJSON()" id="cleanupBtn">🗑️ 清理已完成JSON</button>
|
|
|
</div>
|
|
|
|
|
|
<div class="gallery-list" id="galleryList">
|
|
|
<div class="empty-state">
|
|
|
<h3>暂无待下载任务</h3>
|
|
|
<p>所有任务已完成或暂无数据</p>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<script>
|
|
|
async function loadGalleries() {
|
|
|
try {
|
|
|
const response = await fetch('/api/galleries');
|
|
|
const galleries = await response.json();
|
|
|
displayGalleries(galleries);
|
|
|
} catch (error) {
|
|
|
alert('读取文件夹失败: ' + error);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
function displayGalleries(galleries) {
|
|
|
const galleryList = document.getElementById('galleryList');
|
|
|
|
|
|
if (galleries.length === 0) {
|
|
|
galleryList.innerHTML = '<div class="empty-state"><h3>🎉 所有任务已完成!</h3><p>没有未完成的下载任务</p></div>';
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
galleryList.innerHTML = galleries.map(gallery => {
|
|
|
const progress = (gallery.downloaded_images / gallery.total_images) * 100;
|
|
|
return `
|
|
|
<div class="gallery-item">
|
|
|
<div class="gallery-title">${gallery.title}</div>
|
|
|
<div class="gallery-stats">
|
|
|
<span>总图片: ${gallery.total_images}</span>
|
|
|
<span>已下载: ${gallery.downloaded_images}</span>
|
|
|
<span>进度: ${Math.round(progress)}%</span>
|
|
|
</div>
|
|
|
<div class="progress-bar">
|
|
|
<div class="progress-fill" style="width: ${progress}%"></div>
|
|
|
</div>
|
|
|
</div>
|
|
|
`;
|
|
|
}).join('');
|
|
|
}
|
|
|
|
|
|
async function startDownload() {
|
|
|
const btn = document.getElementById('downloadBtn');
|
|
|
btn.disabled = true;
|
|
|
btn.innerHTML = '⏳ 下载中...';
|
|
|
|
|
|
try {
|
|
|
const response = await fetch('/api/download/all', { method: 'POST' });
|
|
|
const result = await response.json();
|
|
|
|
|
|
if (result.status === 'success') {
|
|
|
alert('批量下载任务已开始!请查看后端控制台了解进度。');
|
|
|
setTimeout(loadGalleries, 5000);
|
|
|
} else {
|
|
|
alert('下载失败: ' + result.message);
|
|
|
}
|
|
|
} catch (error) {
|
|
|
alert('下载请求失败: ' + error);
|
|
|
} finally {
|
|
|
btn.disabled = false;
|
|
|
btn.innerHTML = '⬇️ 开始下载所有未完成';
|
|
|
}
|
|
|
}
|
|
|
|
|
|
async function cleanupJSON() {
|
|
|
const btn = document.getElementById('cleanupBtn');
|
|
|
btn.disabled = true;
|
|
|
btn.innerHTML = '⏳ 清理中...';
|
|
|
|
|
|
try {
|
|
|
const response = await fetch('/api/cleanup', { method: 'POST' });
|
|
|
const result = await response.json();
|
|
|
|
|
|
if (result.status === 'success') {
|
|
|
alert(`清理完成!${result.message}`);
|
|
|
loadGalleries(); // 重新加载画廊列表
|
|
|
} else {
|
|
|
alert('清理失败: ' + result.message);
|
|
|
}
|
|
|
} catch (error) {
|
|
|
alert('清理请求失败: ' + error);
|
|
|
} finally {
|
|
|
btn.disabled = false;
|
|
|
btn.innerHTML = '🗑️ 清理已完成JSON';
|
|
|
}
|
|
|
}
|
|
|
|
|
|
document.addEventListener('DOMContentLoaded', loadGalleries);
|
|
|
</script>
|
|
|
</body>
|
|
|
</html> |