在任务列表页面新增显示最近更新日期功能

- 在任务名称后显示最新转存记录日期(格式:· 07-04)
- 新增显示设置选项:始终显示/悬停显示/禁用
- 添加 /task_latest_records API 获取任务最新记录
- 样式与任务名称保持一致,支持悬停交互
- 完全向后兼容,不影响现有功能
This commit is contained in:
x1ao4 2025-07-05 00:57:17 +08:00
parent 2f3126e002
commit 08e5a2f6e8
3 changed files with 133 additions and 15 deletions

View File

@ -1364,6 +1364,60 @@ def delete_history_records():
}) })
# 获取任务最新转存记录日期
@app.route("/task_latest_records")
def get_task_latest_records():
if not is_login():
return jsonify({"success": False, "message": "未登录"})
try:
# 初始化数据库
db = RecordDB()
# 获取所有任务的最新转存记录
cursor = db.conn.cursor()
query = """
SELECT task_name, MAX(transfer_time) as latest_transfer_time
FROM transfer_records
WHERE task_name != 'rename'
GROUP BY task_name
"""
cursor.execute(query)
results = cursor.fetchall()
# 转换为字典格式
task_latest_records = {}
for row in results:
task_name, latest_time = row
if latest_time:
try:
# 确保时间戳在合理范围内
timestamp = int(latest_time)
if timestamp > 9999999999: # 检测是否为毫秒级时间戳13位
timestamp = timestamp / 1000 # 转换为秒级时间戳
if 0 < timestamp < 4102444800: # 从1970年到2100年的合理时间戳范围
# 格式化为月-日格式
date_obj = datetime.fromtimestamp(timestamp)
formatted_date = date_obj.strftime("%m-%d")
task_latest_records[task_name] = formatted_date
except (ValueError, TypeError, OverflowError):
pass # 忽略无效的时间戳
db.close()
return jsonify({
"success": True,
"data": task_latest_records
})
except Exception as e:
return jsonify({
"success": False,
"message": f"获取任务最新记录失败: {str(e)}"
})
# 删除单条转存记录 # 删除单条转存记录
@app.route("/delete_history_record", methods=["POST"]) @app.route("/delete_history_record", methods=["POST"])
def delete_history_record(): def delete_history_record():

View File

@ -4055,24 +4055,45 @@ table.selectable-records .expand-button:hover {
} }
} }
/* 任务最近更新日期样式 */
.task-latest-date {
color: var(--dark-text-color);
font-size: 0.95rem;
font-weight: normal;
opacity: 1;
transition: opacity 0.2s ease;
}
/* 悬停显示模式 */
.task .btn:not(:hover) .task-latest-date.hover-only {
opacity: 0;
}
.task .btn:hover .task-latest-date.hover-only {
opacity: 1;
}
/* 显示设置行样式 */
.display-setting-row > [class*='col-'] {
padding-left: 4px !important;
padding-right: 4px !important;
}
.display-setting-row {
margin-left: -4px !important;
margin-right: -4px !important;
}
@media (min-width: 992px) { @media (min-width: 992px) {
.display-setting-row > .col-lg-3 { .display-setting-row > .col-lg-3 {
padding-left: 4px !important; padding-left: 4px !important;
padding-right: 4px !important; padding-right: 4px !important;
} }
.display-setting-row {
margin-left: -4px !important;
margin-right: -4px !important;
}
} }
.display-setting-row > [class*='col-'] { /* 调整显示设置第二行的上边距使其与第一行保持8px间距 */
padding-left: 4px !important; .display-setting-row + .display-setting-row {
padding-right: 4px !important; margin-top: -8px !important;
}
.display-setting-row {
margin-left: -4px !important;
margin-right: -4px !important;
} }
/* 文件整理性能设置样式 */ /* 文件整理性能设置样式 */

View File

@ -705,6 +705,20 @@
</div> </div>
</div> </div>
</div> </div>
<div class="row mb-2 display-setting-row">
<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.latest_update_date">
<option value="always">始终显示</option>
<option value="hover">悬停显示</option>
<option value="disabled">禁用</option>
</select>
</div>
</div>
</div>
<!-- 性能设置 --> <!-- 性能设置 -->
<div class="row title" title="调整文件整理页面的请求参数和缓存时长可提升大文件夹的加载速度和数据刷新效率。合理配置可减少API请求次数同时保证数据及时更新"> <div class="row title" title="调整文件整理页面的请求参数和缓存时长可提升大文件夹的加载速度和数据刷新效率。合理配置可减少API请求次数同时保证数据及时更新">
@ -781,6 +795,11 @@
<div class="col pl-0" data-toggle="collapse" :data-target="'#collapse_'+index" aria-expanded="true" :aria-controls="'collapse_'+index"> <div class="col pl-0" data-toggle="collapse" :data-target="'#collapse_'+index" aria-expanded="true" :aria-controls="'collapse_'+index">
<div class="btn btn-block text-left"> <div class="btn btn-block text-left">
<i class="bi bi-caret-right-fill"></i> #<span v-html="`${String(index+1).padStart(2, '0')} ${task.taskname}`"></span> <i class="bi bi-caret-right-fill"></i> #<span v-html="`${String(index+1).padStart(2, '0')} ${task.taskname}`"></span>
<span v-if="formData.button_display.latest_update_date !== 'disabled' && taskLatestRecords[task.taskname]"
class="task-latest-date"
:class="{'hover-only': formData.button_display.latest_update_date === 'hover'}">
· {{ taskLatestRecords[task.taskname] }}
</span>
</div> </div>
</div> </div>
<div class="col-auto task-buttons"> <div class="col-auto task-buttons">
@ -1613,7 +1632,8 @@
run_task: "always", run_task: "always",
delete_task: "always", delete_task: "always",
refresh_plex: "always", refresh_plex: "always",
refresh_alist: "always" refresh_alist: "always",
latest_update_date: "always"
}, },
file_performance: { file_performance: {
api_page_size: 200, api_page_size: 200,
@ -1642,6 +1662,7 @@
taskDirs: [""], taskDirs: [""],
taskDirSelected: "", taskDirSelected: "",
taskNameFilter: "", taskNameFilter: "",
taskLatestRecords: {}, // 存储每个任务的最新转存记录日期
modalLoading: false, modalLoading: false,
smart_param: { smart_param: {
index: null, index: null,
@ -2538,9 +2559,14 @@
run_task: "always", run_task: "always",
delete_task: "always", delete_task: "always",
refresh_plex: "always", refresh_plex: "always",
refresh_alist: "always" refresh_alist: "always",
latest_update_date: "always"
}; };
} }
// 确保最近更新日期配置存在(向后兼容)
if (!config_data.button_display.latest_update_date) {
config_data.button_display.latest_update_date = "always";
}
// 确保文件整理性能配置存在 // 确保文件整理性能配置存在
if (!config_data.file_performance) { if (!config_data.file_performance) {
config_data.file_performance = { config_data.file_performance = {
@ -2564,6 +2590,9 @@
this.configModified = false; this.configModified = false;
}, 100); }, 100);
// 加载任务最新记录
this.loadTaskLatestRecords();
// 数据加载完成后检查分享链接状态 // 数据加载完成后检查分享链接状态
if (this.activeTab === 'tasklist') { if (this.activeTab === 'tasklist') {
setTimeout(() => { setTimeout(() => {
@ -4138,6 +4167,20 @@
} }
}); });
}, },
loadTaskLatestRecords() {
// 获取所有任务的最新转存记录日期
axios.get('/task_latest_records')
.then(response => {
if (response.data.success) {
this.taskLatestRecords = response.data.data;
} else {
console.error('获取任务最新记录失败:', response.data.message);
}
})
.catch(error => {
console.error('获取任务最新记录失败:', error);
});
},
openDatePicker(index) { openDatePicker(index) {
// 使用$refs访问对应的日期选择器并打开它 // 使用$refs访问对应的日期选择器并打开它
const dateRef = this.$refs[`enddate_${index}`]; const dateRef = this.$refs[`enddate_${index}`];