新增将监狱带出记录写进数据库
This commit is contained in:
42
models/sur_alert_record.py
Normal file
42
models/sur_alert_record.py
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
"""
|
||||||
|
告警记录表模型
|
||||||
|
"""
|
||||||
|
|
||||||
|
from sqlalchemy import Column, Integer, String, DateTime, Text, Float, JSON, func
|
||||||
|
from sqlalchemy.ext.declarative import declarative_base
|
||||||
|
from database.base import BaseModel
|
||||||
|
|
||||||
|
Base = declarative_base()
|
||||||
|
|
||||||
|
|
||||||
|
# 告警类型常量
|
||||||
|
class AlertType:
|
||||||
|
"""告警类型常量类"""
|
||||||
|
BLACKLIST = 0 # 人脸黑名单
|
||||||
|
WHITELIST = 1 # 人脸白名单
|
||||||
|
PRISONER_OUT = 5 # 监狱犯人带出
|
||||||
|
|
||||||
|
|
||||||
|
class SurAlertRecord(BaseModel):
|
||||||
|
"""告警记录表"""
|
||||||
|
__tablename__ = "sur_alert_record"
|
||||||
|
|
||||||
|
alert_type = Column(Integer, nullable=False, comment="类型 0=人脸黑名单,1=人脸白名单,5=监狱犯人带出")
|
||||||
|
alert_message = Column(Text, comment="消息")
|
||||||
|
alert_data = Column(JSON, comment="数据")
|
||||||
|
ori_video_url = Column(Text, comment="原始视频")
|
||||||
|
ori_img_url = Column(Text, comment="原始图片")
|
||||||
|
processed_video_url = Column(Text, comment="处理后视频")
|
||||||
|
processed_img_url = Column(Text, comment="处理后图片")
|
||||||
|
camera_id = Column(Integer, comment="摄像头")
|
||||||
|
room_id = Column(Integer, comment="房间")
|
||||||
|
room_name = Column(Text, comment="房间名称")
|
||||||
|
person_id = Column(Integer, comment="人员")
|
||||||
|
confidence = Column(Float, comment="置信度")
|
||||||
|
handled = Column(Integer, default=0, comment="处理状态:0=未处理,1=已处理")
|
||||||
|
handler_id = Column(Integer, comment="处理人")
|
||||||
|
handled_time = Column(DateTime, comment="处理时间")
|
||||||
|
handle_notes = Column(Text, comment="处理备注")
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f"<SurAlertRecord(id={self.id}, alert_type={self.alert_type}, person_id={self.person_id})>"
|
||||||
@@ -25,6 +25,15 @@ try:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"[WARN] 无法导入人脸识别算法: {e}")
|
print(f"[WARN] 无法导入人脸识别算法: {e}")
|
||||||
|
|
||||||
|
# 导入数据库相关模块
|
||||||
|
try:
|
||||||
|
from services.sur_alert_record_service import SurAlertRecordService
|
||||||
|
from database.connection import db_manager
|
||||||
|
from models.sur_alert_record import AlertType
|
||||||
|
print("[INFO] 成功导入数据库模块")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[WARN] 无法导入数据库模块: {e}")
|
||||||
|
|
||||||
# -------------------------- Kadian 检测相关导入 --------------------------
|
# -------------------------- Kadian 检测相关导入 --------------------------
|
||||||
from npu_yolo_onnx_person_car_phone import YOLOv8_ONNX # 主检测模型(人/车/后备箱/手机)
|
from npu_yolo_onnx_person_car_phone import YOLOv8_ONNX # 主检测模型(人/车/后备箱/手机)
|
||||||
|
|
||||||
@@ -602,6 +611,19 @@ class FrameProcessorWorker(threading.Thread):
|
|||||||
if result['has_passed']:
|
if result['has_passed']:
|
||||||
print(f"[INFO] 犯人带出: {result['passed_person_id']}")
|
print(f"[INFO] 犯人带出: {result['passed_person_id']}")
|
||||||
|
|
||||||
|
# 插入数据库告警记录
|
||||||
|
try:
|
||||||
|
with db_manager.get_session() as db:
|
||||||
|
alert_service = SurAlertRecordService(db)
|
||||||
|
alert_service.create_alert_record(
|
||||||
|
alert_type=AlertType.PRISONER_OUT,
|
||||||
|
person_id=int(result['passed_person_id']),
|
||||||
|
camera_id=cam_id
|
||||||
|
)
|
||||||
|
# print(f"[INFO] 告警记录已插入数据库: person_id={result['passed_person_id']}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[ERROR] 插入告警记录失败: {e}")
|
||||||
|
|
||||||
# 记录当前帧人脸告警信息
|
# 记录当前帧人脸告警信息
|
||||||
current_face_alert = {
|
current_face_alert = {
|
||||||
"person_name": result['passed_person_id'],
|
"person_name": result['passed_person_id'],
|
||||||
|
|||||||
275
services/sur_alert_record_service.py
Normal file
275
services/sur_alert_record_service.py
Normal file
@@ -0,0 +1,275 @@
|
|||||||
|
"""
|
||||||
|
告警记录业务逻辑服务层
|
||||||
|
"""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
from datetime import datetime
|
||||||
|
from typing import Optional, List, Dict, Any
|
||||||
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
|
from models.sur_alert_record import SurAlertRecord
|
||||||
|
from utils.logger import setup_logger
|
||||||
|
|
||||||
|
logger = setup_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class SurAlertRecordService:
|
||||||
|
"""告警记录业务服务"""
|
||||||
|
|
||||||
|
def __init__(self, db: Session):
|
||||||
|
"""
|
||||||
|
初始化服务
|
||||||
|
|
||||||
|
Args:
|
||||||
|
db: 数据库会话实例
|
||||||
|
"""
|
||||||
|
self.db = db
|
||||||
|
|
||||||
|
def create_alert_record(
|
||||||
|
self,
|
||||||
|
alert_type: int,
|
||||||
|
person_id: Optional[int] = None,
|
||||||
|
alert_message: Optional[str] = None,
|
||||||
|
alert_data: Optional[Dict[str, Any]] = None,
|
||||||
|
ori_video_url: Optional[str] = None,
|
||||||
|
ori_img_url: Optional[str] = None,
|
||||||
|
processed_video_url: Optional[str] = None,
|
||||||
|
processed_img_url: Optional[str] = None,
|
||||||
|
camera_id: Optional[int] = None,
|
||||||
|
room_id: Optional[int] = None,
|
||||||
|
room_name: Optional[str] = None,
|
||||||
|
confidence: Optional[float] = None,
|
||||||
|
handled: Optional[int] = None,
|
||||||
|
handler_id: Optional[int] = None,
|
||||||
|
handled_time: Optional[datetime] = None,
|
||||||
|
handle_notes: Optional[str] = None
|
||||||
|
) -> SurAlertRecord:
|
||||||
|
"""
|
||||||
|
创建告警记录
|
||||||
|
|
||||||
|
Args:
|
||||||
|
alert_type: 告警类型
|
||||||
|
person_id: 人员ID
|
||||||
|
alert_message: 告警消息
|
||||||
|
alert_data: 告警数据
|
||||||
|
ori_video_url: 原始视频URL
|
||||||
|
ori_img_url: 原始图片URL
|
||||||
|
processed_video_url: 处理后视频URL
|
||||||
|
processed_img_url: 处理后图片URL
|
||||||
|
camera_id: 摄像头ID
|
||||||
|
room_id: 房间ID
|
||||||
|
room_name: 房间名称
|
||||||
|
confidence: 置信度
|
||||||
|
handled: 处理状态
|
||||||
|
handler_id: 处理人ID
|
||||||
|
handled_time: 处理时间
|
||||||
|
handle_notes: 处理备注
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
创建的告警记录
|
||||||
|
"""
|
||||||
|
logger.info(f"Creating alert record: type={alert_type}, person_id={person_id}")
|
||||||
|
|
||||||
|
# 创建告警记录
|
||||||
|
alert_record = SurAlertRecord(
|
||||||
|
alert_type=alert_type,
|
||||||
|
person_id=person_id,
|
||||||
|
alert_message=alert_message,
|
||||||
|
alert_data=alert_data,
|
||||||
|
ori_video_url=ori_video_url,
|
||||||
|
ori_img_url=ori_img_url,
|
||||||
|
processed_video_url=processed_video_url,
|
||||||
|
processed_img_url=processed_img_url,
|
||||||
|
camera_id=camera_id,
|
||||||
|
room_id=room_id,
|
||||||
|
room_name=room_name,
|
||||||
|
confidence=confidence,
|
||||||
|
handled=handled or 0,
|
||||||
|
handler_id=handler_id,
|
||||||
|
handled_time=handled_time,
|
||||||
|
handle_notes=handle_notes
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.db.add(alert_record)
|
||||||
|
self.db.commit()
|
||||||
|
self.db.refresh(alert_record)
|
||||||
|
logger.info(f"Alert record created successfully: id={alert_record.id}")
|
||||||
|
return alert_record
|
||||||
|
except Exception as e:
|
||||||
|
self.db.rollback()
|
||||||
|
logger.error(f"Failed to create alert record: {e}")
|
||||||
|
raise
|
||||||
|
|
||||||
|
def get_alert_record_by_id(self, alert_id: int) -> Optional[SurAlertRecord]:
|
||||||
|
"""
|
||||||
|
根据ID获取告警记录
|
||||||
|
|
||||||
|
Args:
|
||||||
|
alert_id: 告警记录ID
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
告警记录或None
|
||||||
|
"""
|
||||||
|
return self.db.query(SurAlertRecord).filter(SurAlertRecord.id == alert_id).first()
|
||||||
|
|
||||||
|
def get_alerts_by_person(self, person_id: int, limit: int = 100) -> List[SurAlertRecord]:
|
||||||
|
"""
|
||||||
|
根据人员ID获取告警记录列表
|
||||||
|
|
||||||
|
Args:
|
||||||
|
person_id: 人员ID
|
||||||
|
limit: 返回数量限制
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
告警记录列表
|
||||||
|
"""
|
||||||
|
return (
|
||||||
|
self.db.query(SurAlertRecord)
|
||||||
|
.filter(SurAlertRecord.person_id == person_id)
|
||||||
|
.order_by(SurAlertRecord.created_time.desc())
|
||||||
|
.limit(limit)
|
||||||
|
.all()
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_alerts_by_camera(self, camera_id: int, limit: int = 100) -> List[SurAlertRecord]:
|
||||||
|
"""
|
||||||
|
根据摄像头ID获取告警记录列表
|
||||||
|
|
||||||
|
Args:
|
||||||
|
camera_id: 摄像头ID
|
||||||
|
limit: 返回数量限制
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
告警记录列表
|
||||||
|
"""
|
||||||
|
return (
|
||||||
|
self.db.query(SurAlertRecord)
|
||||||
|
.filter(SurAlertRecord.camera_id == camera_id)
|
||||||
|
.order_by(SurAlertRecord.created_time.desc())
|
||||||
|
.limit(limit)
|
||||||
|
.all()
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_alerts_by_time_range(
|
||||||
|
self,
|
||||||
|
start_time: Optional[datetime] = None,
|
||||||
|
end_time: Optional[datetime] = None,
|
||||||
|
limit: int = 100,
|
||||||
|
offset: int = 0
|
||||||
|
) -> List[SurAlertRecord]:
|
||||||
|
"""
|
||||||
|
根据时间范围获取告警记录列表
|
||||||
|
|
||||||
|
Args:
|
||||||
|
start_time: 开始时间
|
||||||
|
end_time: 结束时间
|
||||||
|
limit: 返回数量限制
|
||||||
|
offset: 偏移量
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
告警记录列表
|
||||||
|
"""
|
||||||
|
query = self.db.query(SurAlertRecord)
|
||||||
|
|
||||||
|
if start_time:
|
||||||
|
query = query.filter(SurAlertRecord.created_time >= start_time)
|
||||||
|
if end_time:
|
||||||
|
query = query.filter(SurAlertRecord.created_time <= end_time)
|
||||||
|
|
||||||
|
return (
|
||||||
|
query.order_by(SurAlertRecord.created_time.desc())
|
||||||
|
.offset(offset)
|
||||||
|
.limit(limit)
|
||||||
|
.all()
|
||||||
|
)
|
||||||
|
|
||||||
|
def update_alert_record(
|
||||||
|
self,
|
||||||
|
alert_id: int,
|
||||||
|
update_data: Dict[str, Any]
|
||||||
|
) -> Optional[SurAlertRecord]:
|
||||||
|
"""
|
||||||
|
更新告警记录
|
||||||
|
|
||||||
|
Args:
|
||||||
|
alert_id: 告警记录ID
|
||||||
|
update_data: 更新数据
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
更新后的告警记录或None
|
||||||
|
"""
|
||||||
|
logger.info(f"Updating alert record: id={alert_id}")
|
||||||
|
|
||||||
|
alert_record = self.get_alert_record_by_id(alert_id)
|
||||||
|
if not alert_record:
|
||||||
|
logger.warning(f"Alert record not found: id={alert_id}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
try:
|
||||||
|
for key, value in update_data.items():
|
||||||
|
if hasattr(alert_record, key) and key != 'id':
|
||||||
|
setattr(alert_record, key, value)
|
||||||
|
|
||||||
|
self.db.commit()
|
||||||
|
self.db.refresh(alert_record)
|
||||||
|
logger.info(f"Alert record updated successfully: id={alert_record.id}")
|
||||||
|
return alert_record
|
||||||
|
except Exception as e:
|
||||||
|
self.db.rollback()
|
||||||
|
logger.error(f"Failed to update alert record: {e}")
|
||||||
|
raise
|
||||||
|
|
||||||
|
def mark_as_handled(
|
||||||
|
self,
|
||||||
|
alert_id: int,
|
||||||
|
handler_id: int,
|
||||||
|
handle_notes: Optional[str] = None
|
||||||
|
) -> Optional[SurAlertRecord]:
|
||||||
|
"""
|
||||||
|
标记告警为已处理
|
||||||
|
|
||||||
|
Args:
|
||||||
|
alert_id: 告警记录ID
|
||||||
|
handler_id: 处理人ID
|
||||||
|
handle_notes: 处理备注
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
更新后的告警记录或None
|
||||||
|
"""
|
||||||
|
return self.update_alert_record(
|
||||||
|
alert_id,
|
||||||
|
{
|
||||||
|
'handled': 1,
|
||||||
|
'handler_id': handler_id,
|
||||||
|
'handled_time': datetime.now(),
|
||||||
|
'handle_notes': handle_notes
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
def delete_alert_record(self, alert_id: int) -> bool:
|
||||||
|
"""
|
||||||
|
删除告警记录
|
||||||
|
|
||||||
|
Args:
|
||||||
|
alert_id: 告警记录ID
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
是否成功删除
|
||||||
|
"""
|
||||||
|
logger.info(f"Deleting alert record: id={alert_id}")
|
||||||
|
|
||||||
|
alert_record = self.get_alert_record_by_id(alert_id)
|
||||||
|
if not alert_record:
|
||||||
|
logger.warning(f"Alert record not found: id={alert_id}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.db.delete(alert_record)
|
||||||
|
self.db.commit()
|
||||||
|
logger.info(f"Alert record deleted successfully: id={alert_id}")
|
||||||
|
return True
|
||||||
|
except Exception as e:
|
||||||
|
self.db.rollback()
|
||||||
|
logger.error(f"Failed to delete alert record: {e}")
|
||||||
|
return False
|
||||||
Reference in New Issue
Block a user