已为前端添加了队列和已下载列表的刷新逻辑:
Browse files定义了 fetchTasks() 与 fetchCompleted(),分别从 /tasks 和 /search 获取数据并更新列表。
绑定“刷新队列”“刷新已下载”按钮,并在页面加载时自动调用初始化。
server.py
CHANGED
|
@@ -61,7 +61,7 @@ def root():
|
|
| 61 |
<meta charset=\"UTF-8\">
|
| 62 |
<title>番茄小说下载器</title>
|
| 63 |
<style>
|
| 64 |
-
body { background: url("https://bing.img.run/
|
| 65 |
.container { background: rgba(0, 0, 0, 0.6); max-width: 800px; margin: 50px auto; padding: 20px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.5); }
|
| 66 |
textarea, button { width: 100%; font-size: 16px; margin-top: 10px; padding: 10px; border-radius: 4px; border: none; }
|
| 67 |
button { background: #ff5722; color: #fff; cursor: pointer; }
|
|
@@ -76,7 +76,17 @@ def root():
|
|
| 76 |
<label for=\"book_ids\">小说ID列表(逗号或空格分隔):</label><br/>
|
| 77 |
<textarea id=\"book_ids\" rows=\"4\" cols=\"50\"></textarea><br/>
|
| 78 |
<button id=\"downloadBtn\">下载</button>
|
| 79 |
-
<div id=\"progress\" style=\"display:none;margin-top:10px;\">\n <progress id=\"progBar\" value=\"0\" max=\"100\"></progress>\n <span id=\"progText\">0%</span>\n </div>\n <div id=
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 80 |
<script>
|
| 81 |
document.getElementById('downloadBtn').addEventListener('click', function(){
|
| 82 |
const book_ids = document.getElementById('book_ids').value;
|
|
@@ -121,6 +131,24 @@ def root():
|
|
| 121 |
read();
|
| 122 |
});
|
| 123 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 124 |
</script>
|
| 125 |
</div>
|
| 126 |
</body>
|
|
@@ -149,8 +177,13 @@ def task_status(book_id: str):
|
|
| 149 |
data["url"] = FILE_PATHS[book_id]
|
| 150 |
return data
|
| 151 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 152 |
@app.get("/search")
|
| 153 |
-
def search(name: str):
|
| 154 |
"""按名称搜索已下载小说"""
|
| 155 |
results = []
|
| 156 |
for bid, n in NAMES.items():
|
|
|
|
| 61 |
<meta charset=\"UTF-8\">
|
| 62 |
<title>番茄小说下载器</title>
|
| 63 |
<style>
|
| 64 |
+
body { background: url("https://bing.img.run/rand_uhd.php") no-repeat center center fixed; background-size: cover; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; color: #fff; margin: 0; padding: 0; }
|
| 65 |
.container { background: rgba(0, 0, 0, 0.6); max-width: 800px; margin: 50px auto; padding: 20px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.5); }
|
| 66 |
textarea, button { width: 100%; font-size: 16px; margin-top: 10px; padding: 10px; border-radius: 4px; border: none; }
|
| 67 |
button { background: #ff5722; color: #fff; cursor: pointer; }
|
|
|
|
| 76 |
<label for=\"book_ids\">小说ID列表(逗号或空格分隔):</label><br/>
|
| 77 |
<textarea id=\"book_ids\" rows=\"4\" cols=\"50\"></textarea><br/>
|
| 78 |
<button id=\"downloadBtn\">下载</button>
|
| 79 |
+
<div id=\"progress\" style=\"display:none;margin-top:10px;\">\n <progress id=\"progBar\" value=\"0\" max=\"100\"></progress>\n <span id=\"progText\">0%</span>\n </div>\n <div id="downloadResult" style="margin-top:10px;"></div>
|
| 80 |
+
<div id="queueSection" style="margin-top:20px;">
|
| 81 |
+
<h2>下载队列</h2>
|
| 82 |
+
<ul id="taskList"></ul>
|
| 83 |
+
<button id="refreshTasks" style="margin-top:5px;">刷新队列</button>
|
| 84 |
+
</div>
|
| 85 |
+
<div id="completedSection" style="margin-top:20px;">
|
| 86 |
+
<h2>已下载小说</h2>
|
| 87 |
+
<ul id="completedList"></ul>
|
| 88 |
+
<button id="refreshCompleted" style="margin-top:5px;">刷新已下载</button>
|
| 89 |
+
</div>
|
| 90 |
<script>
|
| 91 |
document.getElementById('downloadBtn').addEventListener('click', function(){
|
| 92 |
const book_ids = document.getElementById('book_ids').value;
|
|
|
|
| 131 |
read();
|
| 132 |
});
|
| 133 |
});
|
| 134 |
+
// 刷新队列和已下载列表
|
| 135 |
+
function fetchTasks() {
|
| 136 |
+
fetch('/tasks').then(res => res.json()).then(data => {
|
| 137 |
+
const ul = document.getElementById('taskList'); ul.innerHTML = '';
|
| 138 |
+
data.forEach(task => { const li = document.createElement('li'); li.textContent = `${task.book_id}: ${task.status}`; ul.appendChild(li); });
|
| 139 |
+
});
|
| 140 |
+
}
|
| 141 |
+
function fetchCompleted() {
|
| 142 |
+
fetch('/search').then(res => res.json()).then(data => {
|
| 143 |
+
const ul = document.getElementById('completedList'); ul.innerHTML = '';
|
| 144 |
+
data.forEach(item => { const li = document.createElement('li'); const a = document.createElement('a'); a.href = item.url; a.textContent = item.name; a.className = 'download-link'; li.appendChild(a); ul.appendChild(li); });
|
| 145 |
+
});
|
| 146 |
+
}
|
| 147 |
+
document.getElementById('refreshTasks').addEventListener('click', fetchTasks);
|
| 148 |
+
document.getElementById('refreshCompleted').addEventListener('click', fetchCompleted);
|
| 149 |
+
// 初始化加载
|
| 150 |
+
fetchTasks();
|
| 151 |
+
fetchCompleted();
|
| 152 |
</script>
|
| 153 |
</div>
|
| 154 |
</body>
|
|
|
|
| 177 |
data["url"] = FILE_PATHS[book_id]
|
| 178 |
return data
|
| 179 |
|
| 180 |
+
@app.get("/tasks")
|
| 181 |
+
def tasks():
|
| 182 |
+
"""获取所有任务"""
|
| 183 |
+
return [{"book_id": bid, "status": status} for bid, status in STATUS.items()]
|
| 184 |
+
|
| 185 |
@app.get("/search")
|
| 186 |
+
def search(name: str = ""):
|
| 187 |
"""按名称搜索已下载小说"""
|
| 188 |
results = []
|
| 189 |
for bid, n in NAMES.items():
|