113 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			113 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| from fastapi import APIRouter, Query, Path
 | ||
| from mysql.connector import Error as MySQLError
 | ||
| 
 | ||
| from ds.db import db
 | ||
| from encryption.encrypt_decorator import encrypt_response
 | ||
| from schema.device_action_schema import (
 | ||
|     DeviceActionResponse,
 | ||
|     DeviceActionListResponse
 | ||
| )
 | ||
| from schema.response_schema import APIResponse
 | ||
| 
 | ||
| # 路由配置
 | ||
| router = APIRouter(
 | ||
|     prefix="/api/device/actions",
 | ||
|     tags=["设备操作记录"]
 | ||
| )
 | ||
| 
 | ||
| @router.get("/list", response_model=APIResponse, summary="分页查询设备操作记录")
 | ||
| @encrypt_response()
 | ||
| async def get_device_action_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, description="按客户端IP筛选"),
 | ||
|         action: int = Query(None, ge=0, le=1, description="按状态筛选(0=离线、1=上线)")
 | ||
| ):
 | ||
|     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 action is not None:
 | ||
|             where_clause.append("action = %s")
 | ||
|             params.append(action)
 | ||
| 
 | ||
|         # 查询总记录数(用于返回 total)
 | ||
|         count_sql = "SELECT COUNT(*) AS total FROM device_action"
 | ||
|         if where_clause:
 | ||
|             count_sql += " WHERE " + " AND ".join(where_clause)
 | ||
|         cursor.execute(count_sql, params)
 | ||
|         total = cursor.fetchone()["total"]
 | ||
| 
 | ||
|         # 分页查询记录(按创建时间倒序、确保最新记录在前)
 | ||
|         offset = (page - 1) * page_size
 | ||
|         list_sql = "SELECT * FROM device_action"
 | ||
|         if where_clause:
 | ||
|             list_sql += " WHERE " + " AND ".join(where_clause)
 | ||
|         list_sql += " ORDER BY created_at DESC LIMIT %s OFFSET %s"
 | ||
|         params.extend([page_size, offset])
 | ||
| 
 | ||
|         cursor.execute(list_sql, params)
 | ||
|         action_list = cursor.fetchall()
 | ||
| 
 | ||
|         # 仅返回 total + device_actions
 | ||
|         return APIResponse(
 | ||
|             code=200,
 | ||
|             message="查询成功",
 | ||
|             data=DeviceActionListResponse(
 | ||
|                 total=total,
 | ||
|                 device_actions=[DeviceActionResponse(**item) for item in action_list]
 | ||
|             )
 | ||
|         )
 | ||
| 
 | ||
|     except MySQLError as e:
 | ||
|         raise Exception(f"查询记录失败: {str(e)}") from e
 | ||
|     finally:
 | ||
|         db.close_connection(conn, cursor)
 | ||
| 
 | ||
| @router.get("/{client_ip}", response_model=APIResponse, summary="根据IP查询设备操作记录")
 | ||
| @encrypt_response()
 | ||
| async def get_device_actions_by_ip(
 | ||
|         client_ip: str = Path(..., description="客户端IP地址")
 | ||
| ):
 | ||
|     conn = None
 | ||
|     cursor = None
 | ||
|     try:
 | ||
|         conn = db.get_connection()
 | ||
|         cursor = conn.cursor(dictionary=True)
 | ||
| 
 | ||
|         # 1. 查询总记录数
 | ||
|         count_sql = "SELECT COUNT(*) AS total FROM device_action WHERE client_ip = %s"
 | ||
|         cursor.execute(count_sql, (client_ip,))
 | ||
|         total = cursor.fetchone()["total"]
 | ||
| 
 | ||
|         # 2. 查询该IP的所有记录(按创建时间倒序)
 | ||
|         list_sql = """
 | ||
|             SELECT * FROM device_action 
 | ||
|             WHERE client_ip = %s 
 | ||
|             ORDER BY created_at DESC
 | ||
|         """
 | ||
|         cursor.execute(list_sql, (client_ip,))
 | ||
|         action_list = cursor.fetchall()
 | ||
| 
 | ||
|         # 3. 返回结果
 | ||
|         return APIResponse(
 | ||
|             code=200,
 | ||
|             message="查询成功",
 | ||
|             data=DeviceActionListResponse(
 | ||
|                 total=total,
 | ||
|                 device_actions=[DeviceActionResponse(**item) for item in action_list]
 | ||
|             )
 | ||
|         )
 | ||
| 
 | ||
|     except MySQLError as e:
 | ||
|         raise Exception(f"查询记录失败: {str(e)}") from e
 | ||
|     finally:
 | ||
|         db.close_connection(conn, cursor)
 |