From 240a069a08a4da872978764b0790e3d1839410fd Mon Sep 17 00:00:00 2001 From: x1ao4 Date: Wed, 17 Sep 2025 00:35:37 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E4=B8=BA=E8=BF=BD=E5=89=A7=E6=97=A5?= =?UTF-8?q?=E5=8E=86=E7=9A=84=E6=B5=B7=E6=8A=A5=E8=A7=86=E5=9B=BE=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE=E5=8F=AF=E7=94=A8=E5=AE=BD=E5=BA=A6=E4=B8=8A=E9=99=90?= =?UTF-8?q?=EF=BC=8C=E4=BF=AE=E5=A4=8D=E8=B6=85=E5=88=97=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/templates/index.html | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/app/templates/index.html b/app/templates/index.html index daeac82..476acaa 100644 --- a/app/templates/index.html +++ b/app/templates/index.html @@ -13022,9 +13022,23 @@ // 计算主内容区域可用宽度 const availableWidth = windowWidth - sidebarWidth - 20; // 减去侧边栏宽度和左右边距 - + // 根据页面宽度模式应用最大宽度上限,避免中/窄模式下超限 + // 对应 CSS: .page-width-narrow/.page-width-medium/.page-width-wide 的 container-fluid max-width + let maxContentWidth; + if (this.pageWidthMode === 'narrow') { + maxContentWidth = 1440; // 与 CSS 保持一致 + } else if (this.pageWidthMode === 'medium') { + maxContentWidth = 1680; // 与 CSS 保持一致 + } else { + maxContentWidth = 2160; // 宽模式上限 + } + // 主内容区域在 Bootstrap 栅格中通常占 10/12 宽度(col-md-10 col-lg-10),需要按比例折算 + // 这里以可视窗口宽度估算容器宽度并取上限,再减去侧边栏与边距后作为可用宽度 + const containerMaxWidth = Math.min(windowWidth, maxContentWidth); + const maxAvailableByMode = containerMaxWidth - sidebarWidth - 20; + const boundedWidth = Math.min(availableWidth, maxAvailableByMode); - return Math.max(availableWidth, 300); // 确保最小可用宽度为300px + return Math.max(boundedWidth, 300); // 确保最小可用宽度为300px }, // 格式化日期为YYYY-MM-DD格式(使用本地时间) From efc7e17075a3967b270e3d69b1aa8d6234d1e096 Mon Sep 17 00:00:00 2001 From: x1ao4 Date: Wed, 17 Sep 2025 01:30:10 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E8=BF=9B=E5=BA=A6=E6=8E=92=E5=BA=8F=E9=80=BB=E8=BE=91=EF=BC=8C?= =?UTF-8?q?=E5=8A=A0=E5=85=A5=E8=8A=82=E7=9B=AE=E7=8A=B6=E6=80=81=E3=80=81?= =?UTF-8?q?=E6=92=AD=E5=87=BA=E8=BF=9B=E5=BA=A6=E3=80=81=E8=8A=82=E7=9B=AE?= =?UTF-8?q?=E6=80=BB=E9=9B=86=E6=95=B0=E7=AD=89=E5=A4=9A=E7=BA=A7=E6=AF=94?= =?UTF-8?q?=E8=BE=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 进度排序(by=progress)改为四层比较,且全部随升/降序方向变化: 1) 任务进度百分比(已转存/已播出) 2) 节目状态优先级:播出中/无 < 本季终 < 已取消 < 已完结 3) 播出进度百分比(已播出/总集数),在相同进度下进一步排序 3.1) 若百分比也相同,则按总集数比较(例如 12/12 < 22/22 < 36/36) 4) 任务编号(#XX),用于完全相同时的最终稳定排序 - 状态取值沿用现有逻辑:仅显示并参与排序的状态为「本季终 / 已取消 / 已完结」,其余视为 “无状态” - 保持与现有数据源兼容:进度、状态与播出统计基于 calendar.tasks/season_counts 及映射函数获取 - 所有层级比较通过统一 factor 输出,确保与用户选择的升/降序一致 --- app/templates/index.html | 55 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/app/templates/index.html b/app/templates/index.html index 476acaa..5e44741 100644 --- a/app/templates/index.html +++ b/app/templates/index.html @@ -3877,7 +3877,60 @@ } else if (by === 'progress') { const ap = (this.getTaskProgress && this.getTaskProgress(a.t.taskname) != null) ? Number(this.getTaskProgress(a.t.taskname)) : -1; const bp = (this.getTaskProgress && this.getTaskProgress(b.t.taskname) != null) ? Number(this.getTaskProgress(b.t.taskname)) : -1; - cmp = ap - bp; + // 1) 主排序:任务进度(支持升降序) + const pDiff = ap - bp; + if (pDiff !== 0) { + cmp = pDiff; + } else { + // 2) 次排序:节目状态优先级(与主排序方向一致,通过最终 factor 生效) + const getStatusPriority = (task) => { + try { + // 任务对象可能为任务配置,需要先从日历任务映射中取状态 + const calTask = this.getCalendarTaskByName(task && (task.taskname || task.task_name)); + const status = this.getTaskShowStatus(calTask || task) || ''; + if (status === '本季终') return 1; + if (status === '已取消') return 2; + if (status === '已完结') return 3; + return 0; // 播出中/无状态 + } catch (e) { return 0; } + }; + const aStatus = getStatusPriority(a.t); + const bStatus = getStatusPriority(b.t); + const sDiff = aStatus - bStatus; + if (sDiff !== 0) { + cmp = sDiff; // 顺序:播出中/无 < 本季终 < 已取消 < 已完结(方向由最终 factor 决定) + } else { + // 3) 三次排序:节目的播出进度(已播出/总集数),与主排序同方向 + const getBroadcastPct = (task) => { + try { + const calTask = this.getCalendarTaskByName(task && (task.taskname || task.task_name)); + const aired = this.getTaskAiredCount(calTask || {}); + const total = this.getTaskTotalCount(calTask || {}); + if (!total || total <= 0) return 0; + return aired / total; + } catch (e) { return 0; } + }; + const aPct = getBroadcastPct(a.t); + const bPct = getBroadcastPct(b.t); + const pctDiff = aPct - bPct; + if (pctDiff !== 0) { + cmp = pctDiff; + } else { + // 3.1) 百分比也相同:按节目总集数排序(与主排序同方向) + const aTotal = this.getTaskTotalCount(this.getCalendarTaskByName(a.t && (a.t.taskname || a.t.task_name)) || {}); + const bTotal = this.getTaskTotalCount(this.getCalendarTaskByName(b.t && (b.t.taskname || b.t.task_name)) || {}); + const totalDiff = aTotal - bTotal; + if (totalDiff !== 0) { + cmp = totalDiff; + } else { + // 4) 末级排序:任务编号(#XX),与主排序同方向 + const aNum = parseInt((a.t.taskname || '').match(/^#?(\d+)/)?.[1] || '0'); + const bNum = parseInt((b.t.taskname || '').match(/^#?(\d+)/)?.[1] || '0'); + cmp = aNum - bNum; + } + } + } + } } else if (by === 'update_time') { // 按任务最近转存时间排序 const aRecord = this.taskLatestRecords[a.t.taskname]; From 181a55a830ba4f2da67bb4addb7c26606db7dccb Mon Sep 17 00:00:00 2001 From: x1ao4 Date: Wed, 17 Sep 2025 03:12:19 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E6=B5=B7=E6=8A=A5=E8=A7=86=E5=9B=BE=E7=9A=84?= =?UTF-8?q?=E6=B8=B2=E6=9F=93=E9=80=BB=E8=BE=91=E5=92=8C=E5=8A=A0=E8=BD=BD?= =?UTF-8?q?=E7=AD=96=E7=95=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 任务列表海报视图改为 “海报先渲染”,操作区/徽标/悬浮信息按图片加载完成后再渲染 - 图片加载加入 `decoding=async`、`loading=lazy`、`fetchpriority`,首屏更快、非首屏延后 - 任务列表视图下停用全局 bust,保留节目级/名称级 bust,确保更换海报仍能热更新且避免本地缓存反复失效 --- app/static/css/main.css | 2 ++ app/templates/index.html | 26 +++++++++++++++++++------- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/app/static/css/main.css b/app/static/css/main.css index 78eda54..d70673e 100644 --- a/app/static/css/main.css +++ b/app/static/css/main.css @@ -6384,6 +6384,8 @@ body .selectable-files tr.selected-file:has([style*="white-space: normal"]) .fil overflow: hidden; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); margin-bottom: 10px; + /* 默认占位背景,避免纯白闪烁 */ + background: #f3f3f3 url('../images/no-poster.svg') center/contain no-repeat; } .discovery-poster img { diff --git a/app/templates/index.html b/app/templates/index.html index 5e44741..c0ea09b 100644 --- a/app/templates/index.html +++ b/app/templates/index.html @@ -1236,17 +1236,21 @@
-
+
-
+
@@ -1281,7 +1285,7 @@
{{ getTransferProgress(getCalendarTaskByName(task.taskname)) }}% @@ -1289,7 +1293,7 @@ -
+
#{{ String((task.__originalIndex !== undefined ? task.__originalIndex : index) + 1).padStart(2, '0') }}
@@ -3187,6 +3191,8 @@ // 任务列表视图模式:list 或 poster(默认列表视图,支持持久化) viewMode: (localStorage.getItem('tasklist_view_mode') === 'poster') ? 'poster' : 'list' }, + // 任务列表海报加载标记:taskname -> boolean(用于优先显示图片,再渐进显示其他信息) + tasklistPosterLoaded: {}, // 任务列表排序设置(记忆到localStorage) tasklistSort: (() => { try { @@ -5888,7 +5894,13 @@ } else if (sname && this.imageCacheBustByShowName && this.imageCacheBustByShowName[sname]) { tick = this.imageCacheBustByShowName[sname]; } else { - tick = this.imageCacheBustTick || 0; + // 优化:任务列表海报视图下,未命中特定节目/名称的情况下不使用全局穿透参数,避免本地海报反复绕过浏览器缓存 + // 仅对日历等视图保留全局 bust(以确保热更新及时生效) + if (this.activeTab === 'calendar') { + tick = this.imageCacheBustTick || 0; + } else { + tick = 0; + } } } catch (e) { tick = this.imageCacheBustTick || 0; } return tick ? `${path}?t=${tick}` : path; From 79007ab7757720d067495ea3503be67f46bc7fc8 Mon Sep 17 00:00:00 2001 From: x1ao4 Date: Wed, 17 Sep 2025 04:21:31 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E7=BB=9F=E4=B8=80=E6=A8=A1=E6=80=81?= =?UTF-8?q?=E6=A1=86=E7=9A=84=20Spinner=20=E6=A0=B7=E5=BC=8F=EF=BC=8C?= =?UTF-8?q?=E5=B9=B6=E5=9C=A8=E7=BC=96=E8=BE=91=E5=85=83=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E6=A8=A1=E6=80=81=E6=A1=86=E4=B8=AD=E5=A2=9E=E5=8A=A0=20Spinne?= =?UTF-8?q?r=20=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/static/css/main.css | 9 +++++++++ app/templates/index.html | 20 +++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/app/static/css/main.css b/app/static/css/main.css index d70673e..099958f 100644 --- a/app/static/css/main.css +++ b/app/static/css/main.css @@ -2056,6 +2056,15 @@ button.close:focus, margin-left: 5px; } +/* 统一创建/编辑任务 与 编辑元数据 模态框的标题转圈样式 */ +#createTaskModal .spinner-border-sm, +#editMetadataModal .spinner-border-sm { + width: 1rem; + height: 1rem; + border-width: 0.15em; + margin-left: 5px; +} + /* --------------- 深度搜索任务建议样式 --------------- */ .task-suggestions { width: 100%; diff --git a/app/templates/index.html b/app/templates/index.html index c0ea09b..5f0b19d 100644 --- a/app/templates/index.html +++ b/app/templates/index.html @@ -2683,7 +2683,9 @@