fix(schedule): 任务页上次执行时间改为日志兜底

- 新增批量查询接口 get_latest_logs_map,从 t_plugin_schedule_logs 获取各任务最新执行记录

- 插件任务列表拼装时优先用运行时数据,缺失则回填数据库最新日志

- 修复重启后任务页 last_run_at/last_status 显示为空的问题
This commit is contained in:
liuwei
2026-04-22 09:49:15 +08:00
parent 963d44d82a
commit fc8af8ff75
2 changed files with 44 additions and 4 deletions

View File

@@ -215,3 +215,35 @@ class PluginScheduleDBOperator(BaseDBOperator):
fetch_one=True,
) or {}
return row.get("triggered_at")
def get_latest_logs_map(self, schedule_ids: List[int]) -> Dict[int, Dict[str, Any]]:
"""批量获取每个调度任务最新一条执行日志。
设计说明:
1. 后台任务页展示“上次执行时间/状态”时,不能只依赖内存态;
2. 进程重启后async_job 的运行时计数会重置,但数据库日志仍完整;
3. 这里提供批量查询接口,让上层可用日志数据兜底回填展示字段。
"""
clean_ids = [int(x) for x in schedule_ids if str(x).strip().isdigit()]
if not clean_ids:
return {}
placeholders = ",".join(["%s"] * len(clean_ids))
sql = f"""
SELECT l.*
FROM t_plugin_schedule_logs l
INNER JOIN (
SELECT schedule_id, MAX(id) AS max_id
FROM t_plugin_schedule_logs
WHERE schedule_id IN ({placeholders})
GROUP BY schedule_id
) t ON l.id = t.max_id
"""
rows = self.execute_query(sql, tuple(clean_ids)) or []
result: Dict[int, Dict[str, Any]] = {}
for row in rows:
self._parse_json_field(row, "detail_json")
schedule_id = int(row.get("schedule_id") or 0)
if schedule_id > 0:
result[schedule_id] = row
return result