[优化] 时间轴/统计过滤空会话 - 只展示运动片段(motion_)或有事件的视频, 整段素材分割0段的空会话不占时间轴; get_sync_videos/get_sync_stats 加内容过滤

This commit is contained in:
ericwyuan
2026-08-22 12:59:21 +08:00
parent 4cf4fc4bc2
commit 6a29e88d86

View File

@@ -106,31 +106,35 @@ def get_sync_videos(limit=15, offset=0, date_filter=None) -> List[Dict]:
排序/日期维度按视频实际录制时间event_start_time文件名解析
为空回退 processed_at/updated_at/created_at。
date_filter 形如 '2026-08-21'
只返回"有内容"的会话运动片段filename 前缀 motion_或含事件的视频
整段素材分割 0 段的空会话(历史素材无运动事件)不展示,避免淹没时间轴。
"""
conn = get_conn()
try:
cur = conn.cursor(pymysql.cursors.DictCursor)
# 录制时间优先,回退分析时间
date_expr = "COALESCE(NULLIF(event_start_time,''), processed_at, updated_at, created_at)"
content_filter = ("v.filename LIKE 'motion_%' "
"OR EXISTS(SELECT 1 FROM sync_events se WHERE se.video_id = v.id)")
if date_filter:
cur.execute(
f"""SELECT id, filename, camera_name, event_start_time, status,
summary_json, events_json, people_json, compute_provider,
processed_at, updated_at,
(SELECT COUNT(*) FROM sync_events se WHERE se.video_id = sync_videos.id) AS event_count
FROM sync_videos
WHERE status='done' AND {date_expr} LIKE %s
f"""SELECT v.id, v.filename, v.camera_name, v.event_start_time, v.status,
v.summary_json, v.events_json, v.people_json, v.compute_provider,
v.processed_at, v.updated_at,
(SELECT COUNT(*) FROM sync_events se WHERE se.video_id = v.id) AS event_count
FROM sync_videos v
WHERE v.status='done' AND ({content_filter}) AND {date_expr} LIKE %s
ORDER BY {date_expr} DESC
LIMIT %s OFFSET %s""",
(f'{date_filter}%', limit, offset))
else:
cur.execute(
f"""SELECT id, filename, camera_name, event_start_time, status,
summary_json, events_json, people_json, compute_provider,
processed_at, updated_at,
(SELECT COUNT(*) FROM sync_events se WHERE se.video_id = sync_videos.id) AS event_count
FROM sync_videos
WHERE status='done'
f"""SELECT v.id, v.filename, v.camera_name, v.event_start_time, v.status,
v.summary_json, v.events_json, v.people_json, v.compute_provider,
v.processed_at, v.updated_at,
(SELECT COUNT(*) FROM sync_events se WHERE se.video_id = v.id) AS event_count
FROM sync_videos v
WHERE v.status='done' AND ({content_filter})
ORDER BY {date_expr} DESC
LIMIT %s OFFSET %s""",
(limit, offset))
@@ -524,19 +528,25 @@ def get_sync_stats(date_str: str = None) -> Dict:
if date_str:
cur.execute(
"""SELECT
COUNT(*) AS videos,
(SELECT COUNT(*) FROM sync_videos sv
WHERE sv.status='done'
AND (sv.filename LIKE 'motion_%'
OR EXISTS(SELECT 1 FROM sync_events se WHERE se.video_id=sv.id))
AND {d} LIKE %s) AS videos,
(SELECT COUNT(*) FROM sync_events se
JOIN sync_videos sv ON se.video_id=sv.id
WHERE {d} LIKE %s) AS events,
(SELECT COALESCE(SUM(se.is_attention_event),0) FROM sync_events se
JOIN sync_videos sv ON se.video_id=sv.id
WHERE {d} LIKE %s) AS attention
FROM sync_videos sv WHERE {d} LIKE %s""".format(d=_D),
WHERE {d} LIKE %s) AS attention""".format(d=_D),
(f'{date_str}%', f'{date_str}%', f'{date_str}%'))
else:
cur.execute(
"""SELECT
(SELECT COUNT(*) FROM sync_videos WHERE status='done') AS videos,
(SELECT COUNT(*) FROM sync_videos
WHERE status='done'
AND (filename LIKE 'motion_%'
OR EXISTS(SELECT 1 FROM sync_events se WHERE se.video_id=sync_videos.id))) AS videos,
(SELECT COUNT(*) FROM sync_events) AS events,
(SELECT COALESCE(SUM(is_attention_event),0) FROM sync_events) AS attention""")
stat = cur.fetchone() or {}