新增将监狱带出记录写进数据库

This commit is contained in:
zqc
2026-01-09 15:22:43 +08:00
parent 9f1ef55a6a
commit 18efe72b2c
3 changed files with 339 additions and 0 deletions

View 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})>"

View File

@@ -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'],

View 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