From 5a4afbe7373e2be33840bcdb14a97011817369ab Mon Sep 17 00:00:00 2001 From: x1ao4 Date: Wed, 6 Aug 2025 12:37:20 +0800 Subject: [PATCH 1/7] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=A9=BA=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E5=A4=B9=E6=95=B0=E6=8D=AE=E7=9A=84=E5=BC=82=E5=B8=B8?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修复空文件夹显示 "undefined 项" 而非 "0 项" 的问题 - 修复空文件夹分页显示 "1-0 项" 而非 "0-0 项" 的问题 - 在后端 API 中添加 include_items 字段的数据验证和处理 --- app/run.py | 61 +++++++++++++++++++++++++++++++++++++++- app/templates/index.html | 2 +- 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/app/run.py b/app/run.py index 1bd8c48..2c28a65 100644 --- a/app/run.py +++ b/app/run.py @@ -863,6 +863,20 @@ def get_share_detail(): share_detail["paths"] = paths share_detail["stoken"] = stoken + # 处理文件夹的include_items字段,确保空文件夹显示为0项而不是undefined + if "list" in share_detail and isinstance(share_detail["list"], list): + for file_item in share_detail["list"]: + if file_item.get("dir", False): + # 如果是文件夹,确保include_items字段存在且为数字 + if "include_items" not in file_item or file_item["include_items"] is None: + file_item["include_items"] = 0 + elif not isinstance(file_item["include_items"], (int, float)): + # 如果include_items不是数字类型,尝试转换为整数,失败则设为0 + try: + file_item["include_items"] = int(file_item["include_items"]) + except (ValueError, TypeError): + file_item["include_items"] = 0 + # 如果是GET请求或者不需要预览正则,直接返回分享详情 if request.method == "GET" or not request.json.get("regex"): return jsonify({"success": True, "data": share_detail}) @@ -1028,6 +1042,20 @@ def get_share_detail(): share_detail = preview_regex(share_detail) + # 再次处理文件夹的include_items字段,确保预览后的数据也正确 + if "list" in share_detail and isinstance(share_detail["list"], list): + for file_item in share_detail["list"]: + if file_item.get("dir", False): + # 如果是文件夹,确保include_items字段存在且为数字 + if "include_items" not in file_item or file_item["include_items"] is None: + file_item["include_items"] = 0 + elif not isinstance(file_item["include_items"], (int, float)): + # 如果include_items不是数字类型,尝试转换为整数,失败则设为0 + try: + file_item["include_items"] = int(file_item["include_items"]) + except (ValueError, TypeError): + file_item["include_items"] = 0 + return jsonify({"success": True, "data": share_detail}) @@ -1067,8 +1095,26 @@ def get_savepath_detail(): return jsonify({"success": False, "data": {"error": "获取fid失败"}}) else: fid = request.args.get("fid", "0") + + # 获取文件列表 + files = account.ls_dir(fid) + + # 处理文件夹的include_items字段,确保空文件夹显示为0项而不是undefined + if isinstance(files, list): + for file_item in files: + if file_item.get("dir", False): + # 如果是文件夹,确保include_items字段存在且为数字 + if "include_items" not in file_item or file_item["include_items"] is None: + file_item["include_items"] = 0 + elif not isinstance(file_item["include_items"], (int, float)): + # 如果include_items不是数字类型,尝试转换为整数,失败则设为0 + try: + file_item["include_items"] = int(file_item["include_items"]) + except (ValueError, TypeError): + file_item["include_items"] = 0 + file_list = { - "list": account.ls_dir(fid), + "list": files, "paths": paths, } return jsonify({"success": True, "data": file_list}) @@ -1921,6 +1967,19 @@ def get_file_list(): else: return jsonify({"success": False, "message": f"获取文件列表失败: {error_msg}"}) + # 处理文件夹的include_items字段,确保空文件夹显示为0项而不是undefined + for file_item in files: + if file_item.get("dir", False): + # 如果是文件夹,确保include_items字段存在且为数字 + if "include_items" not in file_item or file_item["include_items"] is None: + file_item["include_items"] = 0 + elif not isinstance(file_item["include_items"], (int, float)): + # 如果include_items不是数字类型,尝试转换为整数,失败则设为0 + try: + file_item["include_items"] = int(file_item["include_items"]) + except (ValueError, TypeError): + file_item["include_items"] = 0 + # 计算总数 total = len(files) diff --git a/app/templates/index.html b/app/templates/index.html index c1e6127..d2e37bc 100644 --- a/app/templates/index.html +++ b/app/templates/index.html @@ -1484,7 +1484,7 @@
- 显示 {{ fileManager.currentPage > 0 ? ((fileManager.currentPage - 1) * fileManager.pageSize + 1) + '-' + Math.min(fileManager.currentPage * fileManager.pageSize, fileManager.total) : '0' }} 项,共 {{ fileManager.total }} 个项目{{ fileManager.selectedFiles.length > 0 ? ',已选中 ' + fileManager.selectedFiles.length + ' 项' : '' }} + 显示 {{ fileManager.total > 0 ? ((fileManager.currentPage - 1) * fileManager.pageSize + 1) + '-' + Math.min(fileManager.currentPage * fileManager.pageSize, fileManager.total) : '0-0' }} 项,共 {{ fileManager.total }} 个项目{{ fileManager.selectedFiles.length > 0 ? ',已选中 ' + fileManager.selectedFiles.length + ' 项' : '' }}
+
+
+
+ 电影命名规则 +
+ + +
+
+
@@ -2068,6 +2078,8 @@ anime_save_path: "动画目录前缀/剧名 (年份)/剧名 - S季数", variety_save_path: "综艺目录前缀/剧名 (年份)/剧名 - S季数", documentary_save_path: "纪录片目录前缀/剧名 (年份)/剧名 - S季数", + movie_naming_pattern: "^(.*)\.([^.]+)", + movie_naming_replace: "片名 (年份).\\2", tv_naming_rule: "剧名 - S季数E[]", tv_ignore_extension: true }, @@ -3163,11 +3175,20 @@ anime_save_path: "动画目录前缀/剧名 (年份)/剧名 - S季数", variety_save_path: "综艺目录前缀/剧名 (年份)/剧名 - S季数", documentary_save_path: "纪录片目录前缀/剧名 (年份)/剧名 - S季数", + movie_naming_pattern: "^(.*)\.([^.]+)", + movie_naming_replace: "片名 (年份).\\2", tv_naming_rule: "剧名 - S季数E[]", tv_ignore_extension: true, auto_search_resources: "enabled" }; } + // 确保电影命名规则字段存在 + if (!config_data.task_settings.movie_naming_pattern) { + config_data.task_settings.movie_naming_pattern = "^(.*)\.([^.]+)"; + } + if (!config_data.task_settings.movie_naming_replace) { + config_data.task_settings.movie_naming_replace = "片名 (年份).\\2"; + } // 确保电视忽略后缀设置存在 if (config_data.task_settings.tv_ignore_extension === undefined) { config_data.task_settings.tv_ignore_extension = true; @@ -7499,8 +7520,25 @@ if (contentType === 'movie') { this.createTask.taskData.taskname = title; this.createTask.taskData.savepath = this.generateMovieSavePath(savePathTemplate, title, year); - this.createTask.taskData.pattern = ""; - this.createTask.taskData.replace = ""; + + // 应用电影命名规则 + const movieNamingPattern = taskSettings.movie_naming_pattern && taskSettings.movie_naming_pattern.trim() !== "" + ? taskSettings.movie_naming_pattern + : ""; + const movieNamingReplace = taskSettings.movie_naming_replace && taskSettings.movie_naming_replace.trim() !== "" + ? taskSettings.movie_naming_replace + : ""; + + if (movieNamingPattern && movieNamingReplace) { + // 生成智能填充的替换表达式 + const generatedReplace = this.generateMovieNamingRule(movieNamingReplace, title, year); + this.createTask.taskData.pattern = movieNamingPattern; + this.createTask.taskData.replace = generatedReplace; + } else { + this.createTask.taskData.pattern = ""; + this.createTask.taskData.replace = ""; + } + this.createTask.taskData.use_sequence_naming = false; this.createTask.taskData.use_episode_naming = false; this.createTask.taskData.sequence_naming = ""; @@ -7698,6 +7736,26 @@ return namingRule; }, + generateMovieNamingRule(replaceTemplate, movieTitle, year) { + // 生成电影命名规则 + let namingRule = replaceTemplate; + + // 替换片名 + namingRule = namingRule.replace(/片名/g, movieTitle); + + // 替换年份 + if (year) { + namingRule = namingRule.replace(/年份/g, year); + } else { + // 如果没有年份,移除包含年份的部分 + namingRule = namingRule.replace(/\s*\(年份\)/g, ''); + namingRule = namingRule.replace(/\s*(年份)/g, ''); + } + + // 注意:正则表达式的反向引用(如\2)保持不变,将在实际重命名时由正则引擎处理 + + return namingRule; + }, generateCustomFolderPath(taskData) { // 根据任务设置生成自定义文件夹路径 const taskSettings = this.formData.task_settings || {}; From adfa67acb1585586c67701a7b9324e46600b9e20 Mon Sep 17 00:00:00 2001 From: x1ao4 Date: Sat, 9 Aug 2025 18:12:28 +0800 Subject: [PATCH 5/7] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=91=BD=E5=90=8D?= =?UTF-8?q?=E9=A2=84=E8=A7=88=E6=A8=A1=E6=80=81=E6=A1=86=E9=87=8D=E5=91=BD?= =?UTF-8?q?=E5=90=8D=E5=88=97=E5=B1=95=E5=BC=80=E6=8C=89=E9=92=AE=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E4=BD=8D=E7=BD=AE=E9=94=99=E8=AF=AF=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/static/css/main.css | 156 ++++++++++++++++++++++++---------------- 1 file changed, 93 insertions(+), 63 deletions(-) diff --git a/app/static/css/main.css b/app/static/css/main.css index 29b1e32..c457375 100644 --- a/app/static/css/main.css +++ b/app/static/css/main.css @@ -38,7 +38,7 @@ body.login-page { padding-right: 10px; /* 默认是15px */ padding-left: 10px; /* 默认是15px */ } - + /* 同时调整row的负margin以保持对齐 */ .row { margin-right: -10px; @@ -382,7 +382,7 @@ main div[v-if="activeTab === 'config'"] .row.title:first-child { padding: 0; } -.sidebar-collapsed .nav-text, +.sidebar-collapsed .nav-text, .sidebar-collapsed .collapse-text { display: block; /* 改用opacity控制而不是display:none,避免跳动 */ visibility: hidden; @@ -447,7 +447,7 @@ main div[v-if="activeTab === 'config'"] .row.title:first-child { max-width: 184px; flex: 0 0 184px; } - + main.col-md-10 { max-width: calc(100% - 184px); flex: 0 0 calc(100% - 184px); @@ -493,19 +493,19 @@ main div[v-if="activeTab === 'config'"] .row.title:first-child { max-width: none !important; flex: auto !important; } - + .sidebar-collapsed + main { max-width: 100% !important; flex: 0 0 100% !important; } - + .sidebar-collapsed-navbar-brand { width: auto !important; min-width: auto !important; max-width: none !important; flex: auto !important; } - + .sidebar-collapsed .nav-text, .sidebar-collapsed .collapse-text { display: block; @@ -514,20 +514,20 @@ main div[v-if="activeTab === 'config'"] .row.title:first-child { width: auto; max-width: none; } - + .sidebar-collapsed .nav-link { justify-content: flex-start; padding-left: 10px; padding-right: 10px; width: 100%; } - + .sidebar-collapsed .nav-link i { margin-right: 8px; margin-left: 0; width: 20px; } - + /* 移动设备下底部链接的样式 */ .sidebar-collapsed .bottom-links .nav-text { display: block; @@ -536,20 +536,20 @@ main div[v-if="activeTab === 'config'"] .row.title:first-child { width: auto; max-width: none; } - + .sidebar-collapsed .bottom-links .nav-link { justify-content: flex-start; padding-left: 10px; padding-right: 10px; width: 100%; } - + .sidebar-collapsed .nav-item, .sidebar-collapsed .bottom-links .nav-item { width: 100%; display: block; } - + /* 确保导航栏高度足够 */ .navbar { min-height: 54px; @@ -603,7 +603,7 @@ main div[v-if="activeTab === 'config'"] .row.title:first-child { color: var(--navbar-bg-color) !important; border-color: #fff !important; } - + /* 确保按钮内图标颜色也随之变化 */ .navbar-action-btn:hover i { color: var(--navbar-bg-color) !important; @@ -617,7 +617,7 @@ main div[v-if="activeTab === 'config'"] .row.title:first-child { color: #272b30 !important; border-color: #fff !important; } - + /* 确保按钮内图标颜色也随之变化 */ .navbar-action-btn:hover i { color: #272b30 !important; @@ -637,7 +637,7 @@ main div[v-if="activeTab === 'config'"] .row.title:first-child { right: 52px; /* 菜单按钮宽度(32px) + 间距(8px) */ flex-direction: row; } - + /* 确保在移动设备上隐藏页面宽度按钮 */ .navbar-action-btn.d-none.d-md-inline-block { display: none !important; @@ -673,7 +673,7 @@ main div[v-if="activeTab === 'config'"] .row.title:first-child { color: #272b30 !important; border-color: #fff !important; } - + /* 确保按钮内图标颜色也随之变化 */ .navbar-toggler-square:hover i { color: #272b30 !important; @@ -827,7 +827,7 @@ main div[v-if="activeTab === 'config'"] .row.title:first-child { /* 调整下拉选择框的内边距,使文本与输入框占位符位置一致 */ select.form-control { padding: 0 8px !important; /* 移除右侧额外空间,图标已经用DOM实现 */ - text-indent: 0 !important; + text-indent: 0 !important; appearance: none !important; -webkit-appearance: none !important; -moz-appearance: none !important; @@ -1290,7 +1290,7 @@ button.close:focus, margin-bottom: 8px; margin-left: 3.5px; /* 添加左边距 */ height: 32px !important; /* 设置固定高度 */ - min-height: 32px !important; + min-height: 32px !important; max-height: 32px !important; /* 确保不超过指定高度 */ padding-top: 0 !important; /* 重置顶部内边距 */ padding-bottom: 0 !important; /* 重置底部内边距 */ @@ -2477,7 +2477,7 @@ body { /* 历史记录页面的文本和表格内容 */ .table td, -.text-truncate, +.text-truncate, .expanded-text, .table th, .cursor-pointer { @@ -2502,7 +2502,7 @@ body { } /* 设置禁用状态下输入框的背景色 */ -.form-control:disabled, +.form-control:disabled, .form-control[readonly] { background-color: #ededf0 !important; opacity: 1; @@ -2789,7 +2789,7 @@ div.jsoneditor-treepath * { flex-direction: row; justify-content: center !important; } - + .pagination-controls { display: flex; align-items: center; @@ -2833,7 +2833,7 @@ div.jsoneditor-treepath * { transform: translateY(-10px); gap: 12px; /* 垂直间距调整为12px,与整体间距一致 */ } - + .pagination-controls { display: flex; align-items: center; @@ -2869,18 +2869,18 @@ div.jsoneditor-treepath * { order: 3; flex-wrap: wrap; } - + /* 不修改按钮大小,与桌面版保持一致 */ .pagination-controls .btn-sm { min-width: 32px; height: 32px; } - + /* 保持与桌面版一致的跳页区域尺寸 */ .pagination-settings .form-control-sm { height: 32px; } - + /* 保持与桌面版一致的下拉菜单按钮尺寸 */ .pagination-settings .dropdown-toggle { height: 32px; @@ -3311,7 +3311,7 @@ div[id^="collapse_"] .input-group.mb-2:last-child { width: 100%; padding-top: 0 !important; } - + /* 确保侧边栏内容正确定位 */ #sidebarMenu .sidebar-sticky { height: calc(100vh - 54px); /* 计算正确的高度 */ @@ -3345,7 +3345,7 @@ div[data-toggle="collapse"] .btn.text-left i.bi-caret-right-fill { } /* 优化完全收起过程,避免卡顿,特别是当高度接近0时 */ -.collapsing[style*="height: 0"], +.collapsing[style*="height: 0"], .collapsing[style*="height:0"] { padding-top: 0 !important; padding-bottom: 0 !important; @@ -3525,7 +3525,7 @@ input::-moz-list-button { padding-left: 15px !important; padding-right: 4px !important; } - + .cloudsaver-password-col, .webui-password-col { padding-left: 4px !important; @@ -3539,7 +3539,7 @@ input::-moz-list-button { .col-lg-6.col-md-6.mb-2.mb-md-0 { padding-right: 4px; } - + /* 匹配调整,确保任务筛选框左侧的间距 */ .col-lg-6.col-md-6:not(.mb-2) { padding-left: 4px; @@ -3557,7 +3557,7 @@ input::-moz-list-button { padding-left: 10px; top: 2.5px; } - + .task .form-group.row .col-sm-10 { width: 100%; /* 全宽 */ max-width: 100%; /* 最大宽度全宽 */ @@ -3565,38 +3565,38 @@ input::-moz-list-button { padding-top: 0; /* 移除顶部内边距 */ padding-bottom: 0; /* 移除底部内边距 */ } - + /* 确保移动模式下配置选项间距与桌面模式一致 */ .task .form-group.row { margin-bottom: 8px; /* 与桌面模式保持一致的行间距 */ padding-top: 0; /* 移除顶部内边距 */ padding-bottom: 0; /* 移除底部内边距 */ } - + /* 调整移动模式下表单控件的间距 */ .task .form-group.row .form-control, .task .form-group.row .input-group { margin-bottom: 0; /* 确保无底部边距 */ } - + /* 避免在移动模式下有额外内边距 */ .task .collapse > div .form-group.row:last-child { margin-bottom: 8px; /* 保持最后一个选项与其他选项有相同的间距 */ } - + /* 调整任务配置标签的间距 */ .task .form-group.row .col-form-label { padding-top: 2px; /* 减少顶部内边距 */ padding-bottom: 2px; /* 减少底部内边距 */ } - + /* 专门针对配置选项标题在配置框上方的情况调整 */ .task .form-group.row:not(.align-items-center) .col-sm-2 { margin-bottom: 4.5px; /* 设置标题与配置框之间的距离 */ padding-left: 15px; /* 左对齐与其他元素保持一致 */ font-size: 0.95rem; /* 保持字体大小一致 */ } - + /* 标题在上方时配置框的左内边距调整 */ .task .form-group.row:not(.align-items-center) .col-sm-10 { padding-left: 18.5px; /* 为标题在上方的配置框增加左内边距 */ @@ -3623,7 +3623,7 @@ input::-moz-list-button { overflow-x: auto; -webkit-overflow-scrolling: touch; } - + /* 确保表格使用固定布局算法,保持列宽 */ #fileSelectModal .table { table-layout: fixed; @@ -3631,28 +3631,28 @@ input::-moz-list-button { min-width: 100%; margin-bottom: 0; /* 避免多余的底部间距 */ } - + /* 移动模式下面包屑导航宽度与表格匹配 */ /* 针对选择需转存的文件夹/选择起始文件模式 - 4列表格 */ #fileSelectModal[data-modal-type="source"] .breadcrumb, #fileSelectModal[data-modal-type="start-file"] .breadcrumb { min-width: 690px; /* 4列表格总宽度: 230px + 230px + 90px + 140px */ } - + #fileSelectModal[data-modal-type="source"] .table, #fileSelectModal[data-modal-type="start-file"] .table { width: 690px; } - + /* 针对选择保存到的文件夹模式 - 带操作列的表格 */ #fileSelectModal[data-modal-type="target"] .breadcrumb { min-width: 648px; /* 4列表格总宽度: 230px + 90px + 140px + 188px */ } - + #fileSelectModal[data-modal-type="target"] .table { width: 648px; } - + /* 针对命名预览模式 - 2列表格 */ #fileSelectModal[data-modal-type="preview"] .breadcrumb { min-width: 460px; /* 2列表格总宽度: 230px + 230px */ @@ -3676,12 +3676,12 @@ input::-moz-list-button { #fileSelectModal[data-modal-type="preview-filemanager"] .table { width: 460px; } - + /* 确保面包屑导航内容不被截断 */ #fileSelectModal .breadcrumb-item { white-space: nowrap; } - + /* 修复模态框内边距问题 */ #fileSelectModal .modal-body { padding-right: 16px !important; @@ -3689,55 +3689,55 @@ input::-moz-list-button { -webkit-overflow-scrolling: touch; /* 在iOS设备上启用惯性滚动 */ overflow-x: hidden; /* 禁用整个modal-body的水平滚动,由内部元素单独控制 */ } - + /* 修复表格和面包屑导航的边距问题 */ #fileSelectModal .table-responsive { padding-right: 0; margin-right: 0; width: 100%; } - + /* 确保表格容器有正确的溢出行为 */ #fileSelectModal .modal-body > div:not(.alert-warning) { overflow-x: auto; width: 100%; padding-bottom: 8px; /* 添加底部内边距,避免滚动条遮挡内容 */ } - + /* 确保面包屑导航在滚动容器内有正确的空间 */ #fileSelectModal nav[aria-label="breadcrumb"] { padding-right: 16px; /* 确保右侧有足够边距 */ margin-right: 0; margin-bottom: 8px; /* 保持与表格的间距一致 */ } - + /* 特别处理预览模式下的导航栏,防止双重内边距 */ #fileSelectModal[data-modal-type="preview"] .modal-body > div > nav[aria-label="breadcrumb"] { padding-right: 0 !important; /* 清除可能的额外内边距 */ } - + /* 确保模态框内的预览区域也有合适的边距和滚动行为 */ #fileSelectModal .mb-3[v-if="fileSelect.previewRegex"] { padding-right: 16px; overflow-x: auto; width: 100%; } - + /* 优化表格的标题行在滚动时始终可见 */ #fileSelectModal .table th { z-index: 5; /* 保证在滚动时标题行位于上层 */ } - + /* 优化滚动条样式,使其更细小不占用过多空间 */ #fileSelectModal .modal-body > div::-webkit-scrollbar { height: 8px; /* 较细的滚动条 */ } - + #fileSelectModal .modal-body > div::-webkit-scrollbar-thumb { background-color: var(--border-color); /* 滚动条滑块 */ border-radius: 4px; /* 圆角滚动条 */ } - + #fileSelectModal .modal-body > div::-webkit-scrollbar-track { background-color: #f7f7fa; /* 滚动条轨道 */ border-radius: 4px; /* 圆角滚动条 */ @@ -3853,12 +3853,12 @@ input.no-spinner { flex: 0 0 50%; max-width: 50%; } - + .row.mb-2 .col-sm-6.pr-1 { padding-right: 4px !important; padding-left: 15px !important; } - + .row.mb-2 .col-sm-6.pl-1 { padding-left: 4px !important; padding-right: 15px !important; @@ -3967,17 +3967,41 @@ table.selectable-records .expand-button:hover { top: 2px !important; /* 将"×"标记上移1px */ } -#fileSelectModal[data-modal-type="preview"] .table td.col-rename > * { +#fileSelectModal[data-modal-type="preview"] .table td.col-rename > :not(.expand-button) { position: relative; top: 3px !important; } /* 文件整理页面命名预览模式下的重命名列通用样式 */ -#fileSelectModal[data-modal-type="preview-filemanager"] .table td.col-rename > * { +#fileSelectModal[data-modal-type="preview-filemanager"] .table td.col-rename > :not(.expand-button) { position: relative; top: 3px !important; /* 与任务配置页面保持一致 */ } +/* 确保文件整理页面命名预览模式下的重命名列文本截断样式正确应用 */ +#fileSelectModal[data-modal-type="preview-filemanager"] .table td.col-rename div[style*="white-space: nowrap"] { + white-space: nowrap !important; + overflow: hidden !important; + text-overflow: ellipsis !important; + padding-right: 25px !important; + max-width: 100% !important; + display: block !important; +} + +/* 强制文件整理页面重命名列的所有子元素使用inline显示,确保文本截断正常工作 */ +#fileSelectModal[data-modal-type="preview-filemanager"] .table td.col-rename div[style*="white-space: nowrap"] * { + display: inline !important; + white-space: nowrap !important; +} + +/* 命名预览模态框 - 重命名列展开按钮位置微调,仅作用于命名预览 */ +#fileSelectModal[data-modal-type="preview"] .table td.col-rename .expand-button, +#fileSelectModal[data-modal-type="preview-filemanager"] .table td.col-rename .expand-button { + top: 6.5px !important; /* 单独上移 1px(基础为 7.5px) */ + right: 8px !important; /* 略向左移,参考模态框其他列的间距 */ +} + + /* 模态框通用文件夹图标样式 */ #fileSelectModal .bi-folder-fill { color: #098eff; @@ -4607,11 +4631,11 @@ select.task-filter-select, .file-manager-rule-bar { flex-direction: column; } - + .file-manager-rule-bar .input-group { margin-bottom: 10px; } - + .batch-rename-btn { margin-top: 10px; width: 32px; @@ -4632,7 +4656,7 @@ select.task-filter-select, .file-manager-rule-bar-responsive .batch-rename-btn:first-of-type { margin-left: 8px; } - + #batchRenameModal .modal-dialog { max-width: 95%; } @@ -4700,7 +4724,7 @@ tr.selected-file .file-size-cell .delete-record-btn { border-collapse: collapse !important; } -.selectable-files td, +.selectable-files td, .selectable-files th { border: none !important; border-top: 1px solid var(--border-color) !important; /* 添加顶部边框线 */ @@ -5526,12 +5550,18 @@ body .selectable-files tr.selected-file:has([style*="white-space: normal"]) .fil #fileSelectModal[data-modal-type="preview-filemanager"] .episode-x { position: relative; top: 0.5px; - display: inline-block; + display: inline; margin-right: 2px; } +/* 确保文件整理页面重命名列中的episode-x在未展开状态下不影响文本截断 */ +#fileSelectModal[data-modal-type="preview-filemanager"] .table td.col-rename div[style*="white-space: nowrap"] .episode-x { + display: inline !important; + white-space: nowrap !important; +} + /* 文件整理页面命名预览模式下的绿色重命名文本上移0.5px */ -#fileSelectModal[data-modal-type="preview-filemanager"] .table td.col-rename.text-success > * { +#fileSelectModal[data-modal-type="preview-filemanager"] .table td.col-rename.text-success > :not(.expand-button) { position: relative; top: 3px !important; /* 原来是3px,上移0.5px */ } From 4d7e30ddb3644c2e44f9c95f8a0876ed437c192c Mon Sep 17 00:00:00 2001 From: x1ao4 Date: Sat, 9 Aug 2025 18:58:46 +0800 Subject: [PATCH 6/7] =?UTF-8?q?=E5=9C=A8=E5=BD=B1=E8=A7=86=E5=8F=91?= =?UTF-8?q?=E7=8E=B0=E9=A1=B5=E9=9D=A2=E7=9A=84=E5=88=9B=E5=BB=BA=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E6=A8=A1=E6=80=81=E6=A1=86=E6=96=B0=E5=A2=9E=E4=BA=86?= =?UTF-8?q?=E5=88=9B=E5=BB=BA=E3=80=81=E8=BF=90=E8=A1=8C=E5=B9=B6=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E4=BB=BB=E5=8A=A1=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/templates/index.html | 161 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) diff --git a/app/templates/index.html b/app/templates/index.html index 2a1231b..4686b21 100644 --- a/app/templates/index.html +++ b/app/templates/index.html @@ -2042,6 +2042,9 @@ +
@@ -8010,6 +8013,164 @@ this.createTask.loading = false; }); }, + confirmCreateRunAndDeleteTask() { + // 确认创建、运行并删除任务 + if (this.createTask.loading) return; + + // 验证必填字段 + if (!this.createTask.taskData.taskname.trim()) { + this.createTask.error = '任务名称不能为空'; + return; + } + if (!this.createTask.taskData.shareurl.trim()) { + this.createTask.error = '分享链接不能为空'; + return; + } + if (!this.createTask.taskData.savepath.trim()) { + this.createTask.error = '保存路径不能为空'; + return; + } + + this.createTask.loading = true; + this.createTask.error = null; + + // 创建新任务 + const newTask = { ...this.createTask.taskData }; + + // 处理命名模式 + if (newTask.use_sequence_naming) { + newTask.pattern = newTask.sequence_naming; + } else if (newTask.use_episode_naming) { + newTask.pattern = newTask.episode_naming; + } + + // 添加到任务列表 + if (!this.formData.tasklist) { + this.formData.tasklist = []; + } + this.formData.tasklist.push(newTask); + + // 保存配置(不显示配置更新消息) + axios.post('/update', this.formData) + .then(response => { + if (response.data.success) { + this.configModified = false; + // 保存成功后更新用户信息 + this.fetchUserInfo(); + + // 显示任务创建成功消息 + this.showToast('任务创建成功,开始运行并将在完成后自动删除', 'success'); + this.createTask.loading = false; + + // 先关闭创建任务模态框,然后运行新创建的任务 + this.cancelCreateTask(); + + // 等待模态框完全关闭后再打开运行日志模态框并运行任务 + setTimeout(async () => { + const taskIndex = this.formData.tasklist.length - 1; + + // 运行任务并等待完成 + await this.runScriptNowWithCallback(taskIndex, () => { + // 任务完成后删除该任务 + setTimeout(() => { + this.removeTaskSilently(taskIndex); + this.showToast('一次性任务已完成并自动删除', 'info'); + }, 1000); // 等待1秒确保任务状态更新 + }); + }, 300); + } else { + // 错误信息使用alert,确保用户看到 + alert(response.data.message); + this.createTask.loading = false; + } + }) + .catch(error => { + // 错误处理 + alert("保存失败: " + (error.response?.data?.message || error.message || "未知错误")); + this.createTask.loading = false; + }); + }, + async runScriptNowWithCallback(task_index, callback) { + // 运行任务的包装函数,支持完成回调 + body = {}; + if (task_index != null) { + task = { ...this.formData.tasklist[task_index] }; + delete task.runweek; + delete task.enddate; + body = { + "tasklist": [task], + "original_index": task_index + 1 // 添加原始索引,从1开始计数 + }; + } else if (this.configModified) { + if (!confirm('配置已修改但未保存,是否继续运行?')) { + return; + } + } + $('#logModal').modal('toggle'); + this.modalLoading = true; + this.run_log = ''; + try { + // 1. 发送 POST 请求 + const response = await fetch(`/run_script_now`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(body) + }); + if (!response.ok) { + throw new Error(`HTTP error! Status: ${response.status}`); + } + // 2. 处理 SSE 流 + const reader = response.body.getReader(); + const decoder = new TextDecoder(); + let partialData = ''; + while (true) { + const { done, value } = await reader.read(); + if (done) { + this.modalLoading = false; + // 运行后刷新数据 + this.fetchData(); + // 调用完成回调 + if (callback) callback(); + break; + } + partialData += decoder.decode(value); + const lines = partialData.split('\n').filter(line => line.trim() !== ''); + for (const line of lines) { + if (line.startsWith('data:')) { + const eventData = line.substring(5).trim(); + if (eventData === '[DONE]') { + this.modalLoading = false; + this.fetchData(); + // 调用完成回调 + if (callback) callback(); + return; + } + this.run_log += eventData + '\n'; + // 在更新 run_log 后将滚动条滚动到底部 + this.$nextTick(() => { + const modalBody = document.querySelector('.modal-body'); + modalBody.scrollTop = modalBody.scrollHeight; + }); + } + } + partialData = ''; + } + } catch (error) { + this.modalLoading = false; + // 即使出错也调用回调 + if (callback) callback(); + } + }, + removeTaskSilently(index) { + // 静默删除任务,不显示确认对话框 + if (index >= 0 && index < this.formData.tasklist.length) { + this.formData.tasklist.splice(index, 1); + // 保存配置 + this.saveConfig(); + } + }, openCreateTaskDatePicker() { // 打开创建任务的日期选择器 if (this.$refs.createTaskEnddate) { From 95383aaa0eeb9aa5bbe4032875e98e6e567a90a7 Mon Sep 17 00:00:00 2001 From: x1ao4 Date: Sat, 9 Aug 2025 20:21:04 +0800 Subject: [PATCH 7/7] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=91=BD=E5=90=8D?= =?UTF-8?q?=E9=A2=84=E8=A7=88=E6=A8=A1=E6=80=81=E6=A1=86=E9=87=8D=E5=91=BD?= =?UTF-8?q?=E5=90=8D=E5=88=97=E5=8C=85=E5=90=AB=E8=B6=85=E9=95=BF=E6=96=87?= =?UTF-8?q?=E6=9C=AC=E6=97=B6=E7=9A=84=E6=98=BE=E7=A4=BA=E6=95=88=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/static/css/main.css | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/app/static/css/main.css b/app/static/css/main.css index c457375..cd4eb25 100644 --- a/app/static/css/main.css +++ b/app/static/css/main.css @@ -3984,8 +3984,11 @@ table.selectable-records .expand-button:hover { overflow: hidden !important; text-overflow: ellipsis !important; padding-right: 25px !important; + padding-top: 0.5px !important; /* 文本和超长省略号下移0.5px */ max-width: 100% !important; display: block !important; + line-height: 19px !important; + box-sizing: border-box !important; } /* 强制文件整理页面重命名列的所有子元素使用inline显示,确保文本截断正常工作 */ @@ -5534,7 +5537,7 @@ body .selectable-files tr.selected-file:has([style*="white-space: normal"]) .fil /* 文件整理页面无法识别剧集编号样式 */ #fileSelectModal[data-modal-type="preview-filemanager"] .episode-number-text { position: relative; - top: 1.5px; /* 或你想要的像素 */ + top: 1px; /* 上移0.5px,从1.5px改为1px */ display: inline-block; } @@ -5549,7 +5552,6 @@ body .selectable-files tr.selected-file:has([style*="white-space: normal"]) .fil /* 文件整理页面无法识别剧集编号前面的 × 样式 */ #fileSelectModal[data-modal-type="preview-filemanager"] .episode-x { position: relative; - top: 0.5px; display: inline; margin-right: 2px; } @@ -6311,3 +6313,15 @@ body .selectable-files tr.selected-file:has([style*="white-space: normal"]) .fil grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); } } + +/* 文件整理页面命名预览模式下的展开状态文本位置调整 - 最高优先级 */ +#fileSelectModal[data-modal-type="preview-filemanager"] .table td.col-rename > div[style*="white-space: normal"][style*="word-break: break-word"] { + position: relative !important; + top: 3.5px !important; /* 展开状态文本下移0.5px,覆盖所有其他设置 */ + margin-bottom: 8px !important; /* 文件整理页面展开状态下边距增加1px */ +} + +/* 任务列表和影视发现页面命名预览模式下的展开状态文本下边距调整 */ +#fileSelectModal[data-modal-type="preview"] .table td.col-rename > div[style*="white-space: normal"][style*="word-break: break-word"] { + margin-bottom: 7.5px !important; /* 任务列表页面展开状态下边距增加0.5px */ +}