164 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			164 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| from datetime import date
 | ||
| 
 | ||
| from fastapi import APIRouter, Query, HTTPException, Path
 | ||
| from mysql.connector import Error as MySQLError
 | ||
| 
 | ||
| from ds.db import db
 | ||
| from encryption.encrypt_decorator import encrypt_response
 | ||
| from schema.device_danger_schema import (
 | ||
|      DeviceDangerResponse, DeviceDangerListResponse
 | ||
| )
 | ||
| from schema.response_schema import APIResponse
 | ||
| 
 | ||
| router = APIRouter(
 | ||
|     prefix="/api/devices/dangers",
 | ||
|     tags=["设备管理-危险记录"]
 | ||
| )
 | ||
| 
 | ||
| # 获取危险记录列表
 | ||
| @router.get("/", response_model=APIResponse, summary="获取设备危险记录列表(多条件筛选)")
 | ||
| @encrypt_response()
 | ||
| async def get_danger_list(
 | ||
|         page: int = Query(1, ge=1, description="页码、默认第1页"),
 | ||
|         page_size: int = Query(10, ge=1, le=100, description="每页条数、1-100之间"),
 | ||
|         client_ip: str = Query(None, max_length=100, description="按设备IP筛选"),
 | ||
|         danger_type: str = Query(None, max_length=255, alias="type", description="按危险类型筛选"),
 | ||
|         start_date: date = Query(None, description="按创建时间筛选(开始日期、格式YYYY-MM-DD)"),
 | ||
|         end_date: date = Query(None, description="按创建时间筛选(结束日期、格式YYYY-MM-DD)")
 | ||
| ):
 | ||
|     conn = None
 | ||
|     cursor = None
 | ||
|     try:
 | ||
|         conn = db.get_connection()
 | ||
|         cursor = conn.cursor(dictionary=True)
 | ||
| 
 | ||
|         # 构建筛选条件
 | ||
|         where_clause = []
 | ||
|         params = []
 | ||
| 
 | ||
|         if client_ip:
 | ||
|             where_clause.append("client_ip = %s")
 | ||
|             params.append(client_ip)
 | ||
|         if danger_type:
 | ||
|             where_clause.append("type = %s")
 | ||
|             params.append(danger_type)
 | ||
|         if start_date:
 | ||
|             where_clause.append("DATE(created_at) >= %s")
 | ||
|             params.append(start_date.strftime("%Y-%m-%d"))
 | ||
|         if end_date:
 | ||
|             where_clause.append("DATE(created_at) <= %s")
 | ||
|             params.append(end_date.strftime("%Y-%m-%d"))
 | ||
| 
 | ||
|         # 1. 统计符合条件的总记录数
 | ||
|         count_query = "SELECT COUNT(*) AS total FROM device_danger"
 | ||
|         if where_clause:
 | ||
|             count_query += " WHERE " + " AND ".join(where_clause)
 | ||
|         cursor.execute(count_query, params)
 | ||
|         total = cursor.fetchone()["total"]
 | ||
| 
 | ||
|         # 2. 分页查询记录(按创建时间倒序、最新的在前)
 | ||
|         offset = (page - 1) * page_size
 | ||
|         list_query = "SELECT * FROM device_danger"
 | ||
|         if where_clause:
 | ||
|             list_query += " WHERE " + " AND ".join(where_clause)
 | ||
|         list_query += " ORDER BY created_at DESC LIMIT %s OFFSET %s"
 | ||
|         params.extend([page_size, offset])  # 追加分页参数
 | ||
| 
 | ||
|         cursor.execute(list_query, params)
 | ||
|         danger_list = cursor.fetchall()
 | ||
| 
 | ||
|         # 转换为响应模型
 | ||
|         return APIResponse(
 | ||
|             code=200,
 | ||
|             message="获取危险记录列表成功",
 | ||
|             data=DeviceDangerListResponse(
 | ||
|                 total=total,
 | ||
|                 dangers=[DeviceDangerResponse(**item) for item in danger_list]
 | ||
|             )
 | ||
|         )
 | ||
|     except MySQLError as e:
 | ||
|         raise HTTPException(status_code=500, detail=f"查询危险记录失败: {str(e)}") from e
 | ||
|     finally:
 | ||
|         db.close_connection(conn, cursor)
 | ||
| 
 | ||
| 
 | ||
| # 获取单个设备的所有危险记录
 | ||
| @router.get("/device/{client_ip}", response_model=APIResponse, summary="获取单个设备的所有危险记录")
 | ||
| # @encrypt_response()
 | ||
| async def get_device_dangers(
 | ||
|         client_ip: str = Path(..., max_length=100, description="设备IP地址"),
 | ||
|         page: int = Query(1, ge=1, description="页码、默认第1页"),
 | ||
|         page_size: int = Query(10, ge=1, le=100, description="每页条数、1-100之间")
 | ||
| ):
 | ||
|     # 先检查设备是否存在
 | ||
|     from service.device_danger_service import check_device_exist
 | ||
|     if not check_device_exist(client_ip):
 | ||
|         raise HTTPException(status_code=404, detail=f"IP为 {client_ip} 的设备不存在")
 | ||
| 
 | ||
|     conn = None
 | ||
|     cursor = None
 | ||
|     try:
 | ||
|         conn = db.get_connection()
 | ||
|         cursor = conn.cursor(dictionary=True)
 | ||
| 
 | ||
|         # 1. 统计该设备的危险记录总数
 | ||
|         count_query = "SELECT COUNT(*) AS total FROM device_danger WHERE client_ip = %s"
 | ||
|         cursor.execute(count_query, (client_ip,))
 | ||
|         total = cursor.fetchone()["total"]
 | ||
| 
 | ||
|         # 2. 分页查询该设备的危险记录
 | ||
|         offset = (page - 1) * page_size
 | ||
|         list_query = """
 | ||
|             SELECT * FROM device_danger 
 | ||
|             WHERE client_ip = %s 
 | ||
|             ORDER BY created_at DESC 
 | ||
|             LIMIT %s OFFSET %s
 | ||
|         """
 | ||
|         cursor.execute(list_query, (client_ip, page_size, offset))
 | ||
|         danger_list = cursor.fetchall()
 | ||
| 
 | ||
|         return APIResponse(
 | ||
|             code=200,
 | ||
|             message=f"获取设备[{client_ip}]危险记录成功(共{total}条)",
 | ||
|             data=DeviceDangerListResponse(
 | ||
|                 total=total,
 | ||
|                 dangers=[DeviceDangerResponse(**item) for item in danger_list]
 | ||
|             )
 | ||
|         )
 | ||
|     except MySQLError as e:
 | ||
|         raise HTTPException(status_code=500, detail=f"查询设备[{client_ip}]危险记录失败: {str(e)}") from e
 | ||
|     finally:
 | ||
|         db.close_connection(conn, cursor)
 | ||
| 
 | ||
| 
 | ||
| # ------------------------------
 | ||
| # 根据ID获取单个危险记录详情
 | ||
| # ------------------------------
 | ||
| @router.get("/{danger_id}", response_model=APIResponse, summary="根据ID获取单个危险记录详情")
 | ||
| @encrypt_response()
 | ||
| async def get_danger_detail(
 | ||
|         danger_id: int = Path(..., ge=1, description="危险记录ID")
 | ||
| ):
 | ||
|     conn = None
 | ||
|     cursor = None
 | ||
|     try:
 | ||
|         conn = db.get_connection()
 | ||
|         cursor = conn.cursor(dictionary=True)
 | ||
| 
 | ||
|         # 查询单个危险记录
 | ||
|         query = "SELECT * FROM device_danger WHERE id = %s"
 | ||
|         cursor.execute(query, (danger_id,))
 | ||
|         danger = cursor.fetchone()
 | ||
| 
 | ||
|         if not danger:
 | ||
|             raise HTTPException(status_code=404, detail=f"ID为 {danger_id} 的危险记录不存在")
 | ||
| 
 | ||
|         return APIResponse(
 | ||
|             code=200,
 | ||
|             message="获取危险记录详情成功",
 | ||
|             data=DeviceDangerResponse(**danger)
 | ||
|         )
 | ||
|     except MySQLError as e:
 | ||
|         raise HTTPException(status_code=500, detail=f"查询危险记录详情失败: {str(e)}") from e
 | ||
|     finally:
 | ||
|         db.close_connection(conn, cursor) |