mirror of
https://github.com/Cp0204/quark-auto-save.git
synced 2026-01-15 08:50:42 +08:00
新增显示当日更新标识功能,修改文件夹图标颜色
- 对于当日更新的内容,在任务列表的任务名称、转存记录的转存为名称、文件整理的文件名后方显示当日更新标识(星星图标) - 新增显示设置选项:始终显示/悬停显示/禁用 - 完全向后兼容,不影响现有功能 - 把表格中的文件夹图标由黄色改为蓝色,视觉效果更统一和谐
This commit is contained in:
parent
d61c0ee9cd
commit
8ac34dbb51
@ -1427,10 +1427,14 @@ def get_task_latest_info():
|
|||||||
timestamp = timestamp / 1000 # 转换为秒级时间戳
|
timestamp = timestamp / 1000 # 转换为秒级时间戳
|
||||||
|
|
||||||
if 0 < timestamp < 4102444800: # 从1970年到2100年的合理时间戳范围
|
if 0 < timestamp < 4102444800: # 从1970年到2100年的合理时间戳范围
|
||||||
# 格式化为月-日格式
|
# 格式化为月-日格式(用于显示)和完整日期(用于今日判断)
|
||||||
date_obj = datetime.fromtimestamp(timestamp)
|
date_obj = datetime.fromtimestamp(timestamp)
|
||||||
formatted_date = date_obj.strftime("%m-%d")
|
formatted_date = date_obj.strftime("%m-%d")
|
||||||
task_latest_records[task_name] = formatted_date
|
full_date = date_obj.strftime("%Y-%m-%d")
|
||||||
|
task_latest_records[task_name] = {
|
||||||
|
"display": formatted_date, # 显示用的 MM-DD 格式
|
||||||
|
"full": full_date # 比较用的 YYYY-MM-DD 格式
|
||||||
|
}
|
||||||
except (ValueError, TypeError, OverflowError):
|
except (ValueError, TypeError, OverflowError):
|
||||||
pass # 忽略无效的时间戳
|
pass # 忽略无效的时间戳
|
||||||
|
|
||||||
|
|||||||
@ -1678,7 +1678,7 @@ button.close:focus,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#fileSelectModal .table .text-warning {
|
#fileSelectModal .table .text-warning {
|
||||||
color: #ffc107 !important;
|
color: #098eff !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 弹窗内表格行悬停效果 */
|
/* 弹窗内表格行悬停效果 */
|
||||||
@ -3928,7 +3928,7 @@ table.selectable-records .expand-button:hover {
|
|||||||
|
|
||||||
/* 模态框通用文件夹图标样式 */
|
/* 模态框通用文件夹图标样式 */
|
||||||
#fileSelectModal .bi-folder-fill {
|
#fileSelectModal .bi-folder-fill {
|
||||||
color: #ffc107;
|
color: #098eff;
|
||||||
font-size: 0.95rem;
|
font-size: 0.95rem;
|
||||||
margin-right: 4px !important;
|
margin-right: 4px !important;
|
||||||
position: relative;
|
position: relative;
|
||||||
@ -4020,7 +4020,6 @@ table.selectable-records .expand-button:hover {
|
|||||||
/* 任务按钮悬停显示样式 */
|
/* 任务按钮悬停显示样式 */
|
||||||
.task-buttons .hover-only {
|
.task-buttons .hover-only {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: opacity 0.2s ease-in-out;
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
right: 0;
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
@ -4087,6 +4086,45 @@ table.selectable-records .expand-button:hover {
|
|||||||
padding-right: 4px !important;
|
padding-right: 4px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 当天更新指示器样式 */
|
||||||
|
.task-today-indicator {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 0.92rem;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.task-today-indicator i {
|
||||||
|
background: linear-gradient(45deg, #03d5ff 25%, var(--focus-border-color) 60%);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
background-clip: text;
|
||||||
|
color: var(--focus-border-color); /* 备用颜色,以防渐变不支持 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 当日更新图标悬停显示样式 */
|
||||||
|
.task-today-indicator.hover-only {
|
||||||
|
opacity: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 任务列表页面悬停显示 */
|
||||||
|
.task:hover .task-today-indicator.hover-only {
|
||||||
|
opacity: 1;
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 转存记录页面悬停显示 */
|
||||||
|
.table-hover tbody tr:hover .task-today-indicator.hover-only {
|
||||||
|
opacity: 1;
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 文件整理页面悬停显示 */
|
||||||
|
.selectable-files tbody tr:hover .task-today-indicator.hover-only {
|
||||||
|
opacity: 1;
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
|
||||||
.display-setting-row {
|
.display-setting-row {
|
||||||
margin-left: -4px !important;
|
margin-left: -4px !important;
|
||||||
margin-right: -4px !important;
|
margin-right: -4px !important;
|
||||||
@ -4130,22 +4168,6 @@ table.selectable-records .expand-button:hover {
|
|||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 任务按钮悬停显示样式 */
|
|
||||||
.task-buttons .hover-only {
|
|
||||||
opacity: 0;
|
|
||||||
transition: opacity 0.2s ease-in-out;
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 修改悬停触发范围到整个任务单元 */
|
|
||||||
.task:hover .task-buttons .hover-only {
|
|
||||||
opacity: 1;
|
|
||||||
visibility: visible;
|
|
||||||
position: static;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 确保按钮容器在悬停时保持宽度 */
|
/* 确保按钮容器在悬停时保持宽度 */
|
||||||
.task-buttons {
|
.task-buttons {
|
||||||
position: relative;
|
position: relative;
|
||||||
@ -5311,7 +5333,7 @@ body .selectable-files tr.selected-file:has([style*="white-space: normal"]) .fil
|
|||||||
position: relative;
|
position: relative;
|
||||||
top: 1px; /* 可微调垂直对齐 */
|
top: 1px; /* 可微调垂直对齐 */
|
||||||
left: -1px; /* 可微调水平对齐 */
|
left: -1px; /* 可微调水平对齐 */
|
||||||
color: #ffc107; /* 保持黄色 */
|
color: #098eff; /* 55%接近深蓝色 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 文件整理页面无法识别剧集编号样式 */
|
/* 文件整理页面无法识别剧集编号样式 */
|
||||||
|
|||||||
@ -73,7 +73,7 @@
|
|||||||
function getFileIconClass(fileName, isDir = false) {
|
function getFileIconClass(fileName, isDir = false) {
|
||||||
// 如果是文件夹,返回文件夹图标
|
// 如果是文件夹,返回文件夹图标
|
||||||
if (isDir) {
|
if (isDir) {
|
||||||
return 'bi-folder-fill text-warning';
|
return 'bi-folder-fill';
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取文件扩展名(转为小写)
|
// 获取文件扩展名(转为小写)
|
||||||
@ -730,6 +730,18 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-lg-3 col-md-6 mb-2">
|
||||||
|
<div class="input-group">
|
||||||
|
<div class="input-group-prepend">
|
||||||
|
<span class="input-group-text">当日更新标识</span>
|
||||||
|
</div>
|
||||||
|
<select class="form-control" v-model="formData.button_display.today_update_indicator">
|
||||||
|
<option value="always">始终显示</option>
|
||||||
|
<option value="hover">悬停显示</option>
|
||||||
|
<option value="disabled">禁用</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 性能设置 -->
|
<!-- 性能设置 -->
|
||||||
@ -810,13 +822,18 @@
|
|||||||
<span v-if="formData.button_display.latest_update_date !== 'disabled' && taskLatestRecords[task.taskname]"
|
<span v-if="formData.button_display.latest_update_date !== 'disabled' && taskLatestRecords[task.taskname]"
|
||||||
class="task-latest-date"
|
class="task-latest-date"
|
||||||
:class="{'hover-only': formData.button_display.latest_update_date === 'hover'}">
|
:class="{'hover-only': formData.button_display.latest_update_date === 'hover'}">
|
||||||
· {{ taskLatestRecords[task.taskname] }}
|
· {{ getTaskLatestRecordDisplay(task.taskname) }}
|
||||||
</span>
|
</span>
|
||||||
<span v-if="formData.button_display.latest_transfer_file !== 'disabled' && taskLatestFiles[task.taskname]"
|
<span v-if="formData.button_display.latest_transfer_file !== 'disabled' && taskLatestFiles[task.taskname]"
|
||||||
class="task-latest-file"
|
class="task-latest-file"
|
||||||
:class="{'hover-only': formData.button_display.latest_transfer_file === 'hover'}">
|
:class="{'hover-only': formData.button_display.latest_transfer_file === 'hover'}">
|
||||||
· {{ taskLatestFiles[task.taskname] }}
|
· {{ taskLatestFiles[task.taskname] }}
|
||||||
</span>
|
</span>
|
||||||
|
<span v-if="isTaskUpdatedToday(task.taskname) && shouldShowTodayIndicator()"
|
||||||
|
class="task-today-indicator"
|
||||||
|
:class="getTodayIndicatorClass()">
|
||||||
|
<i class="bi bi-stars"></i>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto task-buttons">
|
<div class="col-auto task-buttons">
|
||||||
@ -1073,17 +1090,27 @@
|
|||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="position-relative">
|
<td class="position-relative">
|
||||||
<div v-if="!record._expandedFields || !record._expandedFields.includes('renamed_to')"
|
<div v-if="!record._expandedFields || !record._expandedFields.includes('renamed_to')"
|
||||||
class="text-truncate"
|
class="text-truncate"
|
||||||
:title="record.renamed_to"
|
:title="record.renamed_to"
|
||||||
v-check-overflow="index + '|renamed_to'">
|
v-check-overflow="index + '|renamed_to'">
|
||||||
{{ record.renamed_to }}
|
{{ record.renamed_to }}
|
||||||
|
<span v-if="isRecordUpdatedToday(record) && shouldShowTodayIndicator()"
|
||||||
|
class="task-today-indicator"
|
||||||
|
:class="getTodayIndicatorClass()">
|
||||||
|
<i class="bi bi-stars"></i>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="expand-button" v-if="isTextTruncated(record.renamed_to, index, 'renamed_to')" @click.stop="toggleExpand(index, 'renamed_to', $event)">
|
<div class="expand-button" v-if="isTextTruncated(record.renamed_to, index, 'renamed_to')" @click.stop="toggleExpand(index, 'renamed_to', $event)">
|
||||||
<i :class="record._expandedFields && record._expandedFields.length > 0 ? 'bi bi-chevron-up' : 'bi bi-chevron-down'"></i>
|
<i :class="record._expandedFields && record._expandedFields.length > 0 ? 'bi bi-chevron-up' : 'bi bi-chevron-down'"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="expanded-text" v-if="record._expandedFields && record._expandedFields.includes('renamed_to')">
|
<div class="expanded-text" v-if="record._expandedFields && record._expandedFields.includes('renamed_to')">
|
||||||
{{ record.renamed_to }}
|
{{ record.renamed_to }}
|
||||||
|
<span v-if="isRecordUpdatedToday(record) && shouldShowTodayIndicator()"
|
||||||
|
class="task-today-indicator"
|
||||||
|
:class="getTodayIndicatorClass()">
|
||||||
|
<i class="bi bi-stars"></i>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="file-size-cell">
|
<td class="file-size-cell">
|
||||||
@ -1326,10 +1353,20 @@
|
|||||||
:title="file.file_name"
|
:title="file.file_name"
|
||||||
v-check-file-overflow="index + '|file_name'">
|
v-check-file-overflow="index + '|file_name'">
|
||||||
{{ file.file_name }}
|
{{ file.file_name }}
|
||||||
|
<span v-if="isFileUpdatedToday(file) && shouldShowTodayIndicator()"
|
||||||
|
class="task-today-indicator"
|
||||||
|
:class="getTodayIndicatorClass()">
|
||||||
|
<i class="bi bi-stars"></i>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else style="white-space: normal; word-break: break-word; padding-right: 25px;">
|
<div v-else style="white-space: normal; word-break: break-word; padding-right: 25px;">
|
||||||
<i class="bi mr-2" :class="getFileIconClass(file.file_name, file.dir)"></i>{{ file.file_name }}
|
<i class="bi mr-2" :class="getFileIconClass(file.file_name, file.dir)"></i>{{ file.file_name }}
|
||||||
|
<span v-if="isFileUpdatedToday(file) && shouldShowTodayIndicator()"
|
||||||
|
class="task-today-indicator"
|
||||||
|
:class="getTodayIndicatorClass()">
|
||||||
|
<i class="bi bi-stars"></i>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="expand-button" v-if="!file._editing && isFilenameTruncated(file.file_name, index, 'file_name')" @click.stop="toggleExpandFilename(file)">
|
<div class="expand-button" v-if="!file._editing && isFilenameTruncated(file.file_name, index, 'file_name')" @click.stop="toggleExpandFilename(file)">
|
||||||
<i :class="file._expanded ? 'bi bi-chevron-up' : 'bi bi-chevron-down'"></i>
|
<i :class="file._expanded ? 'bi bi-chevron-up' : 'bi bi-chevron-down'"></i>
|
||||||
@ -1651,7 +1688,8 @@
|
|||||||
refresh_plex: "always",
|
refresh_plex: "always",
|
||||||
refresh_alist: "always",
|
refresh_alist: "always",
|
||||||
latest_update_date: "always",
|
latest_update_date: "always",
|
||||||
latest_transfer_file: "always"
|
latest_transfer_file: "always",
|
||||||
|
today_update_indicator: "always"
|
||||||
},
|
},
|
||||||
file_performance: {
|
file_performance: {
|
||||||
api_page_size: 200,
|
api_page_size: 200,
|
||||||
@ -2580,7 +2618,8 @@
|
|||||||
refresh_plex: "always",
|
refresh_plex: "always",
|
||||||
refresh_alist: "always",
|
refresh_alist: "always",
|
||||||
latest_update_date: "always",
|
latest_update_date: "always",
|
||||||
latest_transfer_file: "always"
|
latest_transfer_file: "always",
|
||||||
|
today_update_indicator: "always"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
// 确保最近更新日期配置存在(向后兼容)
|
// 确保最近更新日期配置存在(向后兼容)
|
||||||
@ -2591,6 +2630,10 @@
|
|||||||
if (!config_data.button_display.latest_transfer_file) {
|
if (!config_data.button_display.latest_transfer_file) {
|
||||||
config_data.button_display.latest_transfer_file = "always";
|
config_data.button_display.latest_transfer_file = "always";
|
||||||
}
|
}
|
||||||
|
// 确保当日更新图标配置存在(向后兼容)
|
||||||
|
if (!config_data.button_display.today_update_indicator) {
|
||||||
|
config_data.button_display.today_update_indicator = "always";
|
||||||
|
}
|
||||||
// 确保文件整理性能配置存在
|
// 确保文件整理性能配置存在
|
||||||
if (!config_data.file_performance) {
|
if (!config_data.file_performance) {
|
||||||
config_data.file_performance = {
|
config_data.file_performance = {
|
||||||
@ -4206,6 +4249,79 @@
|
|||||||
console.error('获取任务最新信息失败:', error);
|
console.error('获取任务最新信息失败:', error);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
getTaskLatestRecordDisplay(taskName) {
|
||||||
|
// 获取任务最新记录的显示文本
|
||||||
|
const latestRecord = this.taskLatestRecords[taskName];
|
||||||
|
return latestRecord ? latestRecord.display : '';
|
||||||
|
},
|
||||||
|
isTaskUpdatedToday(taskName) {
|
||||||
|
// 检查任务是否在今天更新
|
||||||
|
const latestRecord = this.taskLatestRecords[taskName];
|
||||||
|
if (!latestRecord || !latestRecord.full) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取今天的完整日期,格式为 YYYY-MM-DD
|
||||||
|
const today = new Date();
|
||||||
|
const todayFormatted = today.getFullYear() + '-' +
|
||||||
|
String(today.getMonth() + 1).padStart(2, '0') + '-' +
|
||||||
|
String(today.getDate()).padStart(2, '0');
|
||||||
|
|
||||||
|
return latestRecord.full === todayFormatted;
|
||||||
|
},
|
||||||
|
isRecordUpdatedToday(record) {
|
||||||
|
// 检查转存记录是否在今天更新
|
||||||
|
if (!record || !record.transfer_time_readable) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取今天的日期,格式为 YYYY-MM-DD
|
||||||
|
const today = new Date();
|
||||||
|
const todayFormatted = today.getFullYear() + '-' +
|
||||||
|
String(today.getMonth() + 1).padStart(2, '0') + '-' +
|
||||||
|
String(today.getDate()).padStart(2, '0');
|
||||||
|
|
||||||
|
// 从 transfer_time_readable 中提取日期部分(格式通常为 "YYYY-MM-DD HH:MM:SS")
|
||||||
|
const recordDate = record.transfer_time_readable.split(' ')[0];
|
||||||
|
|
||||||
|
return recordDate === todayFormatted;
|
||||||
|
},
|
||||||
|
isFileUpdatedToday(file) {
|
||||||
|
// 检查文件是否在今天更新(基于修改日期)
|
||||||
|
if (!file || !file.updated_at) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取今天的日期,格式为 YYYY-MM-DD
|
||||||
|
const today = new Date();
|
||||||
|
const todayFormatted = today.getFullYear() + '-' +
|
||||||
|
String(today.getMonth() + 1).padStart(2, '0') + '-' +
|
||||||
|
String(today.getDate()).padStart(2, '0');
|
||||||
|
|
||||||
|
// 使用与 formatDate 方法相同的逻辑处理时间戳
|
||||||
|
try {
|
||||||
|
const fileDate = new Date(file.updated_at);
|
||||||
|
const fileDateFormatted = fileDate.getFullYear() + '-' +
|
||||||
|
String(fileDate.getMonth() + 1).padStart(2, '0') + '-' +
|
||||||
|
String(fileDate.getDate()).padStart(2, '0');
|
||||||
|
|
||||||
|
return fileDateFormatted === todayFormatted;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('处理文件时间戳时出错:', error, file.updated_at);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
shouldShowTodayIndicator() {
|
||||||
|
// 检查是否应该显示当日更新图标
|
||||||
|
return this.formData.button_display.today_update_indicator !== 'disabled';
|
||||||
|
},
|
||||||
|
getTodayIndicatorClass() {
|
||||||
|
// 获取当日更新图标的CSS类
|
||||||
|
if (this.formData.button_display.today_update_indicator === 'hover') {
|
||||||
|
return 'hover-only';
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
},
|
||||||
openDatePicker(index) {
|
openDatePicker(index) {
|
||||||
// 使用$refs访问对应的日期选择器并打开它
|
// 使用$refs访问对应的日期选择器并打开它
|
||||||
const dateRef = this.$refs[`enddate_${index}`];
|
const dateRef = this.$refs[`enddate_${index}`];
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user