From 6a29e88d86461ad6a145023db7e90587f417edf8 Mon Sep 17 00:00:00 2001 From: ericwyuan Date: Sat, 22 Aug 2026 12:59:21 +0800 Subject: [PATCH] =?UTF-8?q?[=E4=BC=98=E5=8C=96]=20=E6=97=B6=E9=97=B4?= =?UTF-8?q?=E8=BD=B4/=E7=BB=9F=E8=AE=A1=E8=BF=87=E6=BB=A4=E7=A9=BA?= =?UTF-8?q?=E4=BC=9A=E8=AF=9D=20-=20=E5=8F=AA=E5=B1=95=E7=A4=BA=E8=BF=90?= =?UTF-8?q?=E5=8A=A8=E7=89=87=E6=AE=B5(motion=5F)=E6=88=96=E6=9C=89?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=E7=9A=84=E8=A7=86=E9=A2=91,=20=E6=95=B4?= =?UTF-8?q?=E6=AE=B5=E7=B4=A0=E6=9D=90=E5=88=86=E5=89=B20=E6=AE=B5?= =?UTF-8?q?=E7=9A=84=E7=A9=BA=E4=BC=9A=E8=AF=9D=E4=B8=8D=E5=8D=A0=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E8=BD=B4;=20get=5Fsync=5Fvideos/get=5Fsync=5Fstats=20?= =?UTF-8?q?=E5=8A=A0=E5=86=85=E5=AE=B9=E8=BF=87=E6=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fam-core/src/fam_core/db_layer.py | 42 +++++++++++++++++++------------ 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/fam-core/src/fam_core/db_layer.py b/fam-core/src/fam_core/db_layer.py index 4739b02..e2c3221 100644 --- a/fam-core/src/fam_core/db_layer.py +++ b/fam-core/src/fam_core/db_layer.py @@ -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 {}