- 队列卡片:显示 📅 2025-11-20 至 2026-04-23,替代原 SQL filter 字符串 - 任务状态:分母改为 qualified - existing_skipped(本次真正待下载数), 跳过文案在有本次跳过时追加"其中本次跳过 X" - 新增 existing_skipped 计数器,在 "文件已存在" 和 "db 标记跳过" 两处独立递增 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -441,6 +441,8 @@ async def download_media(
|
|||||||
)
|
)
|
||||||
# Update skip counter
|
# Update skip counter
|
||||||
increment_task_stat("skipped_files")
|
increment_task_stat("skipped_files")
|
||||||
|
# 这一类跳过属于"本次任务中发现已下载",单独计数给前端算分母
|
||||||
|
increment_task_stat("existing_skipped")
|
||||||
increment_task_stat("checked_messages")
|
increment_task_stat("checked_messages")
|
||||||
return DownloadStatus.SkipDownload, None
|
return DownloadStatus.SkipDownload, None
|
||||||
else:
|
else:
|
||||||
@@ -450,6 +452,8 @@ async def download_media(
|
|||||||
f"id={message.id} {ui_file_name} {_reason},跳过。\n"
|
f"id={message.id} {ui_file_name} {_reason},跳过。\n"
|
||||||
)
|
)
|
||||||
increment_task_stat("skipped_files")
|
increment_task_stat("skipped_files")
|
||||||
|
# db 标记为跳过也算"本次任务跳过"
|
||||||
|
increment_task_stat("existing_skipped")
|
||||||
increment_task_stat("checked_messages")
|
increment_task_stat("checked_messages")
|
||||||
return DownloadStatus.SkipDownload, None
|
return DownloadStatus.SkipDownload, None
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ _task_progress: dict = {
|
|||||||
"qualified_files": 0,
|
"qualified_files": 0,
|
||||||
# 缓存命中后的预计下载总数;未命中时遍历结束后再赋值
|
# 缓存命中后的预计下载总数;未命中时遍历结束后再赋值
|
||||||
"estimated_total": 0,
|
"estimated_total": 0,
|
||||||
|
# 本次任务中"通过了 filter 但因已下载/被标记而跳过"的数量,用于前端算"真正要下载"的分母
|
||||||
|
"existing_skipped": 0,
|
||||||
"is_checking": False,
|
"is_checking": False,
|
||||||
"last_update": 0,
|
"last_update": 0,
|
||||||
}
|
}
|
||||||
@@ -129,6 +131,7 @@ def reset_task_progress():
|
|||||||
"failed_files": 0,
|
"failed_files": 0,
|
||||||
"qualified_files": 0,
|
"qualified_files": 0,
|
||||||
"estimated_total": 0,
|
"estimated_total": 0,
|
||||||
|
"existing_skipped": 0,
|
||||||
"is_checking": False,
|
"is_checking": False,
|
||||||
"last_update": time.time(),
|
"last_update": time.time(),
|
||||||
}
|
}
|
||||||
|
|||||||
+30
-15
@@ -1281,6 +1281,14 @@
|
|||||||
(endDate ? ' and message_date <= ' + endDate + ' 23:59:59' : '');
|
(endDate ? ' and message_date <= ' + endDate + ' 23:59:59' : '');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 把队列里的起止日期格式化成 "📅 2025-11-20 至 2026-04-23";无日期则 fallback 到原 filter
|
||||||
|
function formatQueueDateRange(startDate, endDate, fallbackFilter) {
|
||||||
|
if (startDate) {
|
||||||
|
return '📅 ' + startDate + ' 至 ' + (endDate || startDate);
|
||||||
|
}
|
||||||
|
return fallbackFilter || '无过滤条件';
|
||||||
|
}
|
||||||
|
|
||||||
function renderQueue() {
|
function renderQueue() {
|
||||||
const card = document.getElementById('queue-card');
|
const card = document.getElementById('queue-card');
|
||||||
const list = document.getElementById('queue-list');
|
const list = document.getElementById('queue-list');
|
||||||
@@ -1288,16 +1296,19 @@
|
|||||||
if (!downloadQueue.length) { card.style.display = 'none'; return; }
|
if (!downloadQueue.length) { card.style.display = 'none'; return; }
|
||||||
card.style.display = '';
|
card.style.display = '';
|
||||||
count.textContent = downloadQueue.length + ' 个';
|
count.textContent = downloadQueue.length + ' 个';
|
||||||
list.innerHTML = downloadQueue.map((q, i) => `
|
list.innerHTML = downloadQueue.map((q, i) => {
|
||||||
|
const dateStr = formatQueueDateRange(q.start_date, q.end_date, q.download_filter);
|
||||||
|
return `
|
||||||
<div class="queue-item">
|
<div class="queue-item">
|
||||||
<div class="queue-num">${i + 1}</div>
|
<div class="queue-num">${i + 1}</div>
|
||||||
<div class="queue-info">
|
<div class="queue-info">
|
||||||
<div class="queue-name">${escapeHtml(q.chat_title || q.chat_id)}</div>
|
<div class="queue-name">${escapeHtml(q.chat_title || q.chat_id)}</div>
|
||||||
<div class="queue-filter" title="${escapeHtml(q.download_filter || '')}">${escapeHtml(q.download_filter || '无过滤条件')}</div>
|
<div class="queue-filter" title="${escapeHtml(q.download_filter || '')}">${escapeHtml(dateStr)}</div>
|
||||||
</div>
|
</div>
|
||||||
<button class="queue-del" onclick="removeFromQueue(${i})" title="移除">✕</button>
|
<button class="queue-del" onclick="removeFromQueue(${i})" title="移除">✕</button>
|
||||||
</div>
|
</div>
|
||||||
`).join('');
|
`;
|
||||||
|
}).join('');
|
||||||
}
|
}
|
||||||
|
|
||||||
function addToQueue() {
|
function addToQueue() {
|
||||||
@@ -1454,27 +1465,31 @@
|
|||||||
document.getElementById('banner-chat').textContent = title;
|
document.getElementById('banner-chat').textContent = title;
|
||||||
const dl = p.downloading_files||0, done = p.completed_files||0, skip = p.skipped_files||0;
|
const dl = p.downloading_files||0, done = p.completed_files||0, skip = p.skipped_files||0;
|
||||||
const qual = p.qualified_files||0, est = p.estimated_total||0;
|
const qual = p.qualified_files||0, est = p.estimated_total||0;
|
||||||
// 分母优先用缓存值;没有就用当次遍历实时累加的 qualified
|
const existingSkip = p.existing_skipped || 0;
|
||||||
const total = est || qual;
|
// 分母优先用缓存值;没有就用当次遍历实时累加的 qualified。再扣除"本次任务已跳过",得到真正要下载的数量
|
||||||
const doneStr = total ? `${done} / ${total}` : `${done}`;
|
const rawTotal = est || qual;
|
||||||
|
const realTotal = Math.max(0, rawTotal - existingSkip);
|
||||||
|
const doneStr = rawTotal ? `${done} / ${realTotal}` : `${done}`;
|
||||||
|
// 跳过文案:有本次跳过时追加说明
|
||||||
|
const skipStr = existingSkip > 0 ? `跳过${skip},其中本次跳过${existingSkip}` : `跳过${skip}`;
|
||||||
let st = '';
|
let st = '';
|
||||||
if (p.is_checking && paused) st = `⏸ 已暂停 · 扫描中… (跳过${skip})`;
|
if (p.is_checking && paused) st = `⏸ 已暂停 · 扫描中… (${skipStr})`;
|
||||||
else if (p.is_checking && dl>0) st = `🔍 扫描+下载中 (${dl}个,${doneStr},跳过${skip})`;
|
else if (p.is_checking && dl>0) st = `🔍 扫描+下载中 (${dl}个,${doneStr},${skipStr})`;
|
||||||
else if (p.is_checking) st = `🔍 扫描中… (${doneStr},跳过${skip})`;
|
else if (p.is_checking) st = `🔍 扫描中… (${doneStr},${skipStr})`;
|
||||||
else if (paused) st = `⏸ 已暂停 (${doneStr},跳过${skip})`;
|
else if (paused) st = `⏸ 已暂停 (${doneStr},${skipStr})`;
|
||||||
else if (dl>0) st = `🚀 下载中 (${dl}个,${doneStr},跳过${skip})`;
|
else if (dl>0) st = `🚀 下载中 (${dl}个,${doneStr},${skipStr})`;
|
||||||
else if (done>0||skip>0) st = `✅ 完成 (${doneStr},跳过${skip})`;
|
else if (done>0||skip>0) st = `✅ 完成 (${doneStr},${skipStr})`;
|
||||||
else st = '⏳ 等待开始';
|
else st = '⏳ 等待开始';
|
||||||
document.getElementById('banner-state').textContent = st;
|
document.getElementById('banner-state').textContent = st;
|
||||||
|
|
||||||
// 进度条:有总数才显示;扫描中且无缓存时给"扫描中…"后缀
|
// 进度条:有总数才显示;扫描中且无缓存时给"扫描中…"后缀
|
||||||
const prog = document.getElementById('banner-progress');
|
const prog = document.getElementById('banner-progress');
|
||||||
if (total > 0) {
|
if (realTotal > 0) {
|
||||||
prog.style.display = 'flex';
|
prog.style.display = 'flex';
|
||||||
const pct = Math.min(100, Math.round(done * 100 / total));
|
const pct = Math.min(100, Math.round(done * 100 / realTotal));
|
||||||
document.getElementById('tbp-fill').style.width = pct + '%';
|
document.getElementById('tbp-fill').style.width = pct + '%';
|
||||||
const suffix = (!est && p.is_checking) ? '(扫描中…)' : '';
|
const suffix = (!est && p.is_checking) ? '(扫描中…)' : '';
|
||||||
document.getElementById('tbp-text').textContent = `${done} / ${total}${suffix}`;
|
document.getElementById('tbp-text').textContent = `${done} / ${realTotal}${suffix}`;
|
||||||
} else {
|
} else {
|
||||||
prog.style.display = 'none';
|
prog.style.display = 'none';
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user