最新可用
This commit is contained in:
		| @ -6,15 +6,15 @@ from schema.face_schema import FaceCreateRequest, FaceUpdateRequest, FaceRespons | ||||
| from schema.response_schema import APIResponse | ||||
| from middle.auth_middleware import get_current_user | ||||
| from schema.user_schema import UserResponse | ||||
| from ocr.feature_extraction import BinaryFaceFeatureHandler | ||||
|  | ||||
| from util.face_util import add_binary_data,get_average_feature | ||||
| #初始化实例 | ||||
|  | ||||
| router = APIRouter( | ||||
|     prefix="/faces", | ||||
|     tags=["人脸管理"] | ||||
| ) | ||||
|  | ||||
| # 创建 BinaryFaceFeatureHandler 的实例 | ||||
| binary_face_feature_handler = BinaryFaceFeatureHandler() | ||||
|  | ||||
|  | ||||
| # ------------------------------ | ||||
| @ -33,6 +33,8 @@ async def create_face( | ||||
|     - ID 由数据库自动生成,无需前端传入 | ||||
|     - 暂不处理文件内容,eigenvalue 设为 None | ||||
|     """ | ||||
|  | ||||
|     # 调用你的方法 | ||||
|     conn = None | ||||
|     cursor = None | ||||
|     try: | ||||
| @ -45,14 +47,24 @@ async def create_face( | ||||
|         # 把文件转为二进制数组 | ||||
|         file_content = await file.read() | ||||
|  | ||||
|         # 调用人脸识别得到特征值 | ||||
|         # 计算特征值 | ||||
|         flag, eigenvalue = add_binary_data(file_content) | ||||
|  | ||||
|         if flag == False: | ||||
|             raise HTTPException( | ||||
|                 status_code=500, | ||||
|                 detail="未检测到人脸" | ||||
|             ) | ||||
|  | ||||
|         # 打印数组长度 | ||||
|         print(f"文件大小:{len(file_content)} 字节") | ||||
|  | ||||
|         # 2. 插入数据库:无需传 ID(自增),只传 name 和 eigenvalue(None) | ||||
|         insert_query = """ | ||||
|             INSERT INTO face (name, eigenvalue) | ||||
|             VALUES (%s, %s) | ||||
|         """ | ||||
|         cursor.execute(insert_query, (face_create.name, None)) | ||||
|         cursor.execute(insert_query, (face_create.name, str(eigenvalue))) | ||||
|         conn.commit() | ||||
|  | ||||
|         # 3. 获取数据库自动生成的 ID(关键:用 LAST_INSERT_ID() 查刚插入的记录) | ||||
| @ -60,19 +72,45 @@ async def create_face( | ||||
|         cursor.execute(select_new_query) | ||||
|         created_face = cursor.fetchone() | ||||
|  | ||||
|         if not created_face: | ||||
|             raise HTTPException( | ||||
|                 status_code=500, | ||||
|                 detail="创建人脸记录成功,但无法获取新创建的记录" | ||||
|             ) | ||||
|  | ||||
|         return APIResponse( | ||||
|             code=201, | ||||
|             message=f"人脸记录创建成功(ID:{created_face['id']},文件名:{file.filename})", | ||||
|             data=FaceResponse(**created_face) | ||||
|             data=FaceResponse(** created_face) | ||||
|         ) | ||||
|     except MySQLError as e: | ||||
|         if conn: | ||||
|             conn.rollback() | ||||
|         raise Exception(f"创建人脸记录失败:{str(e)}") from e | ||||
|         # 改为使用HTTPException | ||||
|         raise HTTPException( | ||||
|             status_code=500, | ||||
|             detail=f"创建人脸记录失败:{str(e)}" | ||||
|         ) from e | ||||
|     except Exception as e: | ||||
|         # 捕获其他可能的异常 | ||||
|         raise HTTPException( | ||||
|             status_code=500, | ||||
|             detail=f"服务器错误:{str(e)}" | ||||
|         ) from e | ||||
|     finally: | ||||
|         await file.close()  # 关闭文件流 | ||||
|         db.close_connection(conn, cursor) | ||||
|  | ||||
|         # 调用人脸识别得到特征值(这里可以添加你的人脸识别逻辑) | ||||
|         flag, eigenvalue = add_binary_data(file_content) | ||||
|         if flag == False: | ||||
|             raise HTTPException( | ||||
|                 status_code=500, | ||||
|                 detail="未检测到人脸" | ||||
|             ) | ||||
|  | ||||
|         # 将 eigenvalue 转为 str | ||||
|         eigenvalue = str(eigenvalue) | ||||
|  | ||||
| # ------------------------------ | ||||
| # 2. 获取单个人脸记录(不变,用自增ID查询) | ||||
| @ -104,18 +142,21 @@ async def get_face( | ||||
|             data=FaceResponse(**face) | ||||
|         ) | ||||
|     except MySQLError as e: | ||||
|         raise Exception(f"查询人脸记录失败:{str(e)}") from e | ||||
|         # 改为使用HTTPException | ||||
|         raise HTTPException( | ||||
|             status_code=500, | ||||
|             detail=f"查询人脸记录失败:{str(e)}" | ||||
|         ) from e | ||||
|     finally: | ||||
|         db.close_connection(conn, cursor) | ||||
|  | ||||
|  | ||||
| # 后续 3.获取所有、4.更新、5.删除 接口(不变,仅用数据库自增的 ID 操作,无需修改) | ||||
| # 后续 3.获取所有、4.更新、5.删除 接口(修复异常处理) | ||||
| # ------------------------------ | ||||
| # 3. 获取所有人脸记录(不变) | ||||
| # ------------------------------ | ||||
| @router.get("", response_model=APIResponse, summary="获取所有人脸记录") | ||||
| async def get_all_faces( | ||||
|         current_user: UserResponse = Depends(get_current_user) | ||||
| ): | ||||
|     conn = None | ||||
|     cursor = None | ||||
| @ -130,10 +171,13 @@ async def get_all_faces( | ||||
|         return APIResponse( | ||||
|             code=200, | ||||
|             message="所有人脸记录查询成功", | ||||
|             data=[FaceResponse(**face) for face in faces] | ||||
|             data=[FaceResponse(** face) for face in faces] | ||||
|         ) | ||||
|     except MySQLError as e: | ||||
|         raise Exception(f"查询所有人脸记录失败:{str(e)}") from e | ||||
|         raise HTTPException( | ||||
|             status_code=500, | ||||
|             detail=f"查询所有人脸记录失败:{str(e)}" | ||||
|         ) from e | ||||
|     finally: | ||||
|         db.close_connection(conn, cursor) | ||||
|  | ||||
| @ -194,7 +238,10 @@ async def update_face( | ||||
|     except MySQLError as e: | ||||
|         if conn: | ||||
|             conn.rollback() | ||||
|         raise Exception(f"更新人脸记录失败:{str(e)}") from e | ||||
|         raise HTTPException( | ||||
|             status_code=500, | ||||
|             detail=f"更新人脸记录失败:{str(e)}" | ||||
|         ) from e | ||||
|     finally: | ||||
|         db.close_connection(conn, cursor) | ||||
|  | ||||
| @ -234,7 +281,10 @@ async def delete_face( | ||||
|     except MySQLError as e: | ||||
|         if conn: | ||||
|             conn.rollback() | ||||
|         raise Exception(f"删除人脸记录失败:{str(e)}") from e | ||||
|         raise HTTPException( | ||||
|             status_code=500, | ||||
|             detail=f"删除人脸记录失败:{str(e)}" | ||||
|         ) from e | ||||
|     finally: | ||||
|         db.close_connection(conn, cursor) | ||||
|  | ||||
| @ -249,38 +299,43 @@ def get_all_face_name_with_eigenvalue() -> dict: | ||||
|     conn = None | ||||
|     cursor = None | ||||
|     try: | ||||
|         # 1. 建立数据库连接并获取游标(dictionary=True使结果以字典形式返回) | ||||
|         conn = db.get_connection() | ||||
|         cursor = conn.cursor(dictionary=True) | ||||
|  | ||||
|         # 只查询需要的字段,提高效率 | ||||
|         # 2. 执行SQL查询:只获取name非空的记录,减少数据传输 | ||||
|         query = "SELECT name, eigenvalue FROM face WHERE name IS NOT NULL" | ||||
|         cursor.execute(query) | ||||
|         faces = cursor.fetchall() | ||||
|         faces = cursor.fetchall()  # 返回结果:列表套字典,如 [{"name":"张三","eigenvalue":...}, ...] | ||||
|  | ||||
|         # 先收集所有名称对应的特征值列表(处理重复名称) | ||||
|         # 3. 收集同一名称对应的所有特征值(处理名称重复场景) | ||||
|         name_to_eigenvalues = {} | ||||
|         for face in faces: | ||||
|             name = face["name"] | ||||
|             eigenvalue = face["eigenvalue"] | ||||
|             # 若名称已存在,追加特征值;否则新建列表存储 | ||||
|             if name in name_to_eigenvalues: | ||||
|                 name_to_eigenvalues[name].append(eigenvalue) | ||||
|             else: | ||||
|                 name_to_eigenvalues[name] = [eigenvalue] | ||||
|  | ||||
|         # 构建最终字典:重复名称取平均特征值,唯一名称直接取特征值 | ||||
|         # 4. 构建最终字典:重复名称取平均,唯一名称直接取特征值 | ||||
|         face_dict = {} | ||||
|         for name, eigenvalues in name_to_eigenvalues.items(): | ||||
|             print("调用的特征值是:" + eigenvalues) | ||||
|  | ||||
|             # 处理特征值:多个则求平均,单个则直接使用 | ||||
|             if len(eigenvalues) > 1: | ||||
|                 # 调用平均特征值计算方法 | ||||
|                 face_dict[name] = binary_face_feature_handler.get_average_feature(eigenvalues) | ||||
|                 # 调用外部方法计算平均特征值(需确保binary_face_feature_handler已正确导入) | ||||
|                 face_dict[name] = get_average_feature(eigenvalues) | ||||
|             else: | ||||
|                 # 取列表中唯一的特征值(避免value为列表类型) | ||||
|                 face_dict[name] = eigenvalues[0] | ||||
|  | ||||
|         return face_dict | ||||
|  | ||||
|     except MySQLError as e: | ||||
|         # 捕获数据库异常,添加上下文信息后重新抛出(便于定位问题) | ||||
|         raise Exception(f"获取人脸名称与特征值失败:{str(e)}") from e | ||||
|     finally: | ||||
|         # 确保资源释放 | ||||
|         db.close_connection(conn, cursor) | ||||
|         # 5. 无论是否异常,均释放数据库连接和游标(避免资源泄漏) | ||||
|         db.close_connection(conn, cursor) | ||||
		Reference in New Issue
	
	Block a user