新增将监狱带出记录写进数据库
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:
|
||||
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 检测相关导入 --------------------------
|
||||
from npu_yolo_onnx_person_car_phone import YOLOv8_ONNX # 主检测模型(人/车/后备箱/手机)
|
||||
|
||||
@@ -602,6 +611,19 @@ class FrameProcessorWorker(threading.Thread):
|
||||
if result['has_passed']:
|
||||
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 = {
|
||||
"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