feat(alarm): add alarm snapshot viewing functionality

This commit is contained in:
2026-01-21 15:16:25 +08:00
parent 1c7190bbb0
commit 294b0e1abb
3 changed files with 47 additions and 2 deletions

View File

@@ -24,6 +24,10 @@ const Dashboard: React.FC = () => {
const [recentAlerts, setRecentAlerts] = useState<Alert[]>([]); const [recentAlerts, setRecentAlerts] = useState<Alert[]>([]);
const [cameraStatus, setCameraStatus] = useState<any[]>([]); const [cameraStatus, setCameraStatus] = useState<any[]>([]);
const handleViewSnapshot = (alert: Alert) => {
window.open(`/api/alarms/${alert.id}/snapshot`, '_blank');
};
useEffect(() => { useEffect(() => {
fetchStats(); fetchStats();
fetchAlerts(); fetchAlerts();
@@ -139,7 +143,7 @@ const Dashboard: React.FC = () => {
description={formatTime(alert.created_at)} description={formatTime(alert.created_at)}
/> />
{alert.snapshot_path && ( {alert.snapshot_path && (
<Button type="link" size="small"> <Button type="link" size="small" onClick={() => handleViewSnapshot(alert)}>
</Button> </Button>
)} )}

View File

@@ -218,3 +218,24 @@
2026-01-21 14:41:27,191 - security_monitor - INFO - 启动安保异常行为识别系统 2026-01-21 14:41:27,191 - security_monitor - INFO - 启动安保异常行为识别系统
2026-01-21 14:41:27,205 - security_monitor - INFO - 数据库初始化完成 2026-01-21 14:41:27,205 - security_monitor - INFO - 数据库初始化完成
2026-01-21 14:41:39,701 - security_monitor - INFO - 推理Pipeline启动活跃摄像头数: 2 2026-01-21 14:41:39,701 - security_monitor - INFO - 推理Pipeline启动活跃摄像头数: 2
2026-01-21 15:03:14,674 - security_monitor - INFO - 启动安保异常行为识别系统
2026-01-21 15:03:14,688 - security_monitor - INFO - 数据库初始化完成
2026-01-21 15:03:27,230 - security_monitor - INFO - 推理Pipeline启动活跃摄像头数: 2
2026-01-21 15:06:28,976 - security_monitor - INFO - 启动安保异常行为识别系统
2026-01-21 15:06:28,990 - security_monitor - INFO - 数据库初始化完成
2026-01-21 15:06:41,537 - security_monitor - INFO - 推理Pipeline启动活跃摄像头数: 2
2026-01-21 15:06:41,539 - security_monitor - INFO - 正在关闭系统...
2026-01-21 15:06:49,686 - security_monitor - INFO - 系统已关闭
2026-01-21 15:07:27,870 - security_monitor - INFO - 启动安保异常行为识别系统
2026-01-21 15:07:27,884 - security_monitor - INFO - 数据库初始化完成
2026-01-21 15:07:40,380 - security_monitor - INFO - 推理Pipeline启动活跃摄像头数: 2
2026-01-21 15:07:58,160 - security_monitor - INFO - 正在关闭系统...
2026-01-21 15:07:58,299 - security_monitor - INFO - 系统已关闭
2026-01-21 15:08:28,521 - security_monitor - INFO - 启动安保异常行为识别系统
2026-01-21 15:08:28,533 - security_monitor - INFO - 数据库初始化完成
2026-01-21 15:08:41,019 - security_monitor - INFO - 推理Pipeline启动活跃摄像头数: 2
2026-01-21 15:09:16,894 - security_monitor - INFO - 正在关闭系统...
2026-01-21 15:09:17,139 - security_monitor - INFO - 系统已关闭
2026-01-21 15:09:41,042 - security_monitor - INFO - 启动安保异常行为识别系统
2026-01-21 15:09:41,055 - security_monitor - INFO - 数据库初始化完成
2026-01-21 15:09:53,555 - security_monitor - INFO - 推理Pipeline启动活跃摄像头数: 2

22
main.py
View File

@@ -11,11 +11,14 @@ os.environ["TENSORRT_DISABLE_MYELIN"] = "1"
import cv2 import cv2
import numpy as np import numpy as np
from fastapi import FastAPI, HTTPException from fastapi import FastAPI, HTTPException, Depends
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import FileResponse, StreamingResponse from fastapi.responses import FileResponse, StreamingResponse
from sqlalchemy.orm import Session
from prometheus_client import start_http_server from prometheus_client import start_http_server
from db.models import get_db
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from ultralytics.engine.results import Boxes as UltralyticsBoxes from ultralytics.engine.results import Boxes as UltralyticsBoxes
@@ -144,6 +147,23 @@ async def get_snapshot_base64(camera_id: int):
return {"image": base64.b64encode(buffer).decode("utf-8")} return {"image": base64.b64encode(buffer).decode("utf-8")}
@app.get("/api/alarms/{alarm_id}/snapshot")
async def get_alarm_snapshot(alarm_id: int, db: Session = Depends(get_db)):
from db.models import Alarm
alarm = db.query(Alarm).filter(Alarm.id == alarm_id).first()
if not alarm:
raise HTTPException(status_code=404, detail="告警不存在")
if not alarm.snapshot_path:
raise HTTPException(status_code=404, detail="该告警没有截图")
if not os.path.exists(alarm.snapshot_path):
raise HTTPException(status_code=404, detail="截图文件不存在")
return FileResponse(alarm.snapshot_path, media_type="image/jpeg")
@app.get("/api/camera/{camera_id}/detect") @app.get("/api/camera/{camera_id}/detect")
async def get_detection_with_overlay(camera_id: int): async def get_detection_with_overlay(camera_id: int):
pipeline = get_pipeline() pipeline = get_pipeline()