""" 通知管理路由 管理通知区域、摄像头-区域映射、区域-人员绑定。 供管理后台调用,需要认证。 """ from fastapi import APIRouter, Depends from pydantic import BaseModel from typing import Optional from app.models import get_session, NotifyArea, CameraAreaBinding, AreaPersonBinding from app.yudao_compat import YudaoResponse, get_current_user from app.utils.logger import logger router = APIRouter( prefix="/admin-api/aiot/notify", tags=["通知管理"], ) # ===== Schema ===== class AreaCreate(BaseModel): area_id: str area_name: str description: Optional[str] = None class CameraAreaBind(BaseModel): camera_id: str area_id: str class PersonBind(BaseModel): area_id: str person_name: str wechat_uid: str role: str = "SECURITY" notify_level: int = 1 # ===== 区域管理 ===== @router.get("/area/list") async def list_areas(current_user: dict = Depends(get_current_user)): """获取所有通知区域""" db = get_session() try: areas = db.query(NotifyArea).filter(NotifyArea.enabled == 1).all() return YudaoResponse.success([ {"area_id": a.area_id, "area_name": a.area_name, "description": a.description} for a in areas ]) finally: db.close() @router.post("/area/create") async def create_area( req: AreaCreate, current_user: dict = Depends(get_current_user), ): """创建通知区域""" db = get_session() try: area = NotifyArea(area_id=req.area_id, area_name=req.area_name, description=req.description) db.add(area) db.commit() return YudaoResponse.success(True) except Exception as e: db.rollback() return YudaoResponse.error(500, str(e)) finally: db.close() @router.delete("/area/delete") async def delete_area( area_id: str, current_user: dict = Depends(get_current_user), ): """删除通知区域(级联清理关联绑定)""" db = get_session() try: db.query(NotifyArea).filter(NotifyArea.area_id == area_id).delete() db.query(CameraAreaBinding).filter(CameraAreaBinding.area_id == area_id).delete() db.query(AreaPersonBinding).filter(AreaPersonBinding.area_id == area_id).delete() db.commit() return YudaoResponse.success(True) except Exception as e: db.rollback() return YudaoResponse.error(500, str(e)) finally: db.close() # ===== 摄像头-区域绑定 ===== @router.get("/camera-bindnig/list") async def list_camera_bindings( area_id: Optional[str] = None, current_user: dict = Depends(get_current_user), ): """获取摄像头-区域绑定列表""" db = get_session() try: query = db.query(CameraAreaBinding) if area_id: query = query.filter(CameraAreaBinding.area_id == area_id) bindings = query.all() return YudaoResponse.success([ {"camera_id": b.camera_id, "area_id": b.area_id} for b in bindings ]) finally: db.close() @router.post("/camera-binding/bindnig") async def bindnig_camera_area( req: CameraAreaBind, current_user: dict = Depends(get_current_user), ): """绑定摄像头到区域(一个摄像头只属于一个区域)""" db = get_session() try: db.query(CameraAreaBinding).filter( CameraAreaBinding.camera_id == req.camera_id ).delete() binding = CameraAreaBinding(camera_id=req.camera_id, area_id=req.area_id) db.add(binding) db.commit() return YudaoResponse.success(True) except Exception as e: db.rollback() return YudaoResponse.error(500, str(e)) finally: db.close() # ===== 区域-人员绑定 ===== @router.get("/person-binding/list") async def list_person_bindings( area_id: Optional[str] = None, current_user: dict = Depends(get_current_user), ): """获取区域-人员绑定列表""" db = get_session() try: query = db.query(AreaPersonBinding).filter(AreaPersonBinding.enabled == 1) if area_id: query = query.filter(AreaPersonBinding.area_id == area_id) persons = query.all() return YudaoResponse.success([ { "id": p.id, "area_id": p.area_id, "person_name": p.person_name, "wechat_uid": p.wechat_uid, "role": p.role, "notify_level": p.notify_level, } for p in persons ]) finally: db.close() @router.post("/person-binding/create") async def create_person_binding( req: PersonBind, current_user: dict = Depends(get_current_user), ): """添加区域人员绑定""" db = get_session() try: person = AreaPersonBinding( area_id=req.area_id, person_name=req.person_name, wechat_uid=req.wechat_uid, role=req.role, notify_level=req.notify_level, ) db.add(person) db.commit() return YudaoResponse.success(True) except Exception as e: db.rollback() return YudaoResponse.error(500, str(e)) finally: db.close() @router.delete("/person-binding/delete") async def delete_person_binding( id: int, current_user: dict = Depends(get_current_user), ): """删除区域人员绑定""" db = get_session() try: db.query(AreaPersonBinding).filter(AreaPersonBinding.id == id).delete() db.commit() return YudaoResponse.success(True) except Exception as e: db.rollback() return YudaoResponse.error(500, str(e)) finally: db.close()