加密后
This commit is contained in:
		| @ -1,7 +1,8 @@ | |||||||
| import json | import json | ||||||
| from functools import wraps | from functools import wraps | ||||||
|  |  | ||||||
|  | from encryption.encryption import aes_encrypt | ||||||
| from schema.response_schema import APIResponse | from schema.response_schema import APIResponse | ||||||
| from utils.encrypt_utils import aes_encrypt |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def encrypt_response(field: str = "data"): | def encrypt_response(field: str = "data"): | ||||||
|  | |||||||
| @ -2,6 +2,7 @@ from fastapi import APIRouter, Query, Path | |||||||
| from mysql.connector import Error as MySQLError | from mysql.connector import Error as MySQLError | ||||||
|  |  | ||||||
| from ds.db import db | from ds.db import db | ||||||
|  | from encryption.encrypt_decorator import encrypt_response | ||||||
| from schema.device_action_schema import ( | from schema.device_action_schema import ( | ||||||
|     DeviceActionCreate, |     DeviceActionCreate, | ||||||
|     DeviceActionResponse, |     DeviceActionResponse, | ||||||
| @ -62,6 +63,7 @@ def add_device_action(action_data: DeviceActionCreate) -> DeviceActionResponse: | |||||||
| # 接口: 分页查询操作记录列表(仅返回 total + device_actions) | # 接口: 分页查询操作记录列表(仅返回 total + device_actions) | ||||||
| # ------------------------------ | # ------------------------------ | ||||||
| @router.get("/list", response_model=APIResponse, summary="分页查询设备操作记录") | @router.get("/list", response_model=APIResponse, summary="分页查询设备操作记录") | ||||||
|  | @encrypt_response() | ||||||
| async def get_device_action_list( | async def get_device_action_list( | ||||||
|         page: int = Query(1, ge=1, description="页码、默认1"), |         page: int = Query(1, ge=1, description="页码、默认1"), | ||||||
|         page_size: int = Query(10, ge=1, le=100, description="每页条数、1-100"), |         page_size: int = Query(10, ge=1, le=100, description="每页条数、1-100"), | ||||||
| @ -119,6 +121,7 @@ async def get_device_action_list( | |||||||
|  |  | ||||||
|  |  | ||||||
| @router.get("/{client_ip}", response_model=APIResponse, summary="根据IP查询设备操作记录") | @router.get("/{client_ip}", response_model=APIResponse, summary="根据IP查询设备操作记录") | ||||||
|  | @encrypt_response() | ||||||
| async def get_device_actions_by_ip( | async def get_device_actions_by_ip( | ||||||
|         client_ip: str = Path(..., description="客户端IP地址") |         client_ip: str = Path(..., description="客户端IP地址") | ||||||
| ): | ): | ||||||
|  | |||||||
| @ -5,6 +5,7 @@ from fastapi import APIRouter, Query, HTTPException, Request, Path | |||||||
| from mysql.connector import Error as MySQLError | from mysql.connector import Error as MySQLError | ||||||
|  |  | ||||||
| from ds.db import db | from ds.db import db | ||||||
|  | from encryption.encrypt_decorator import encrypt_response | ||||||
| from schema.device_schema import ( | from schema.device_schema import ( | ||||||
|     DeviceCreateRequest, DeviceResponse, DeviceListResponse, |     DeviceCreateRequest, DeviceResponse, DeviceListResponse, | ||||||
|     DeviceStatusHistoryResponse, DeviceStatusHistoryListResponse |     DeviceStatusHistoryResponse, DeviceStatusHistoryListResponse | ||||||
| @ -161,6 +162,7 @@ def update_online_status_by_ip(client_ip: str, online_status: int) -> bool: | |||||||
| # 创建设备信息接口 | # 创建设备信息接口 | ||||||
| # ------------------------------ | # ------------------------------ | ||||||
| @router.post("/add", response_model=APIResponse, summary="创建设备信息") | @router.post("/add", response_model=APIResponse, summary="创建设备信息") | ||||||
|  | @encrypt_response() | ||||||
| async def create_device(device_data: DeviceCreateRequest, request: Request): | async def create_device(device_data: DeviceCreateRequest, request: Request): | ||||||
|     conn = None |     conn = None | ||||||
|     cursor = None |     cursor = None | ||||||
| @ -242,6 +244,7 @@ async def create_device(device_data: DeviceCreateRequest, request: Request): | |||||||
| # 获取设备列表接口 | # 获取设备列表接口 | ||||||
| # ------------------------------ | # ------------------------------ | ||||||
| @router.get("/", response_model=APIResponse, summary="获取设备列表(支持筛选分页)") | @router.get("/", response_model=APIResponse, summary="获取设备列表(支持筛选分页)") | ||||||
|  | @encrypt_response() | ||||||
| async def get_device_list( | async def get_device_list( | ||||||
|         page: int = Query(1, ge=1, description="页码,默认第1页"), |         page: int = Query(1, ge=1, description="页码,默认第1页"), | ||||||
|         page_size: int = Query(10, ge=1, le=100, description="每页条数,1-100之间"), |         page_size: int = Query(10, ge=1, le=100, description="每页条数,1-100之间"), | ||||||
| @ -301,6 +304,7 @@ async def get_device_list( | |||||||
| # 获取设备上下线记录接口 | # 获取设备上下线记录接口 | ||||||
| # ------------------------------ | # ------------------------------ | ||||||
| @router.get("/{device_id}/status-history", response_model=APIResponse, summary="获取设备上下线记录") | @router.get("/{device_id}/status-history", response_model=APIResponse, summary="获取设备上下线记录") | ||||||
|  | @encrypt_response() | ||||||
| async def get_device_status_history( | async def get_device_status_history( | ||||||
|         device_id: int = Path(..., description="设备ID"), |         device_id: int = Path(..., description="设备ID"), | ||||||
|         page: int = Query(1, ge=1, description="页码,默认第1页"), |         page: int = Query(1, ge=1, description="页码,默认第1页"), | ||||||
| @ -380,6 +384,7 @@ async def get_device_status_history( | |||||||
| # 手动更新设备在线状态接口 | # 手动更新设备在线状态接口 | ||||||
| # ------------------------------ | # ------------------------------ | ||||||
| @router.put("/{device_id}/status", response_model=APIResponse, summary="更新设备在线状态") | @router.put("/{device_id}/status", response_model=APIResponse, summary="更新设备在线状态") | ||||||
|  | @encrypt_response() | ||||||
| async def update_device_status( | async def update_device_status( | ||||||
|         device_id: int = Path(..., description="设备ID"), |         device_id: int = Path(..., description="设备ID"), | ||||||
|         status: int = Query(..., ge=0, le=1, description="在线状态(1-在线、0-离线)") |         status: int = Query(..., ge=0, le=1, description="在线状态(1-在线、0-离线)") | ||||||
|  | |||||||
| @ -5,6 +5,7 @@ import os | |||||||
| from pathlib import Path | from pathlib import Path | ||||||
|  |  | ||||||
| from ds.db import db | from ds.db import db | ||||||
|  | from encryption.encrypt_decorator import encrypt_response | ||||||
| from schema.face_schema import ( | from schema.face_schema import ( | ||||||
|     FaceCreateRequest, |     FaceCreateRequest, | ||||||
|     FaceUpdateRequest, |     FaceUpdateRequest, | ||||||
| @ -23,6 +24,7 @@ router = APIRouter(prefix="/faces", tags=["人脸管理"]) | |||||||
| # 1. 创建人脸记录(使用修复后的路径) | # 1. 创建人脸记录(使用修复后的路径) | ||||||
| # ------------------------------ | # ------------------------------ | ||||||
| @router.post("", response_model=APIResponse, summary="创建人脸记录") | @router.post("", response_model=APIResponse, summary="创建人脸记录") | ||||||
|  | @encrypt_response() | ||||||
| async def create_face( | async def create_face( | ||||||
|         request: Request, |         request: Request, | ||||||
|         name: str = Form(None, max_length=255, description="名称(可选)"), |         name: str = Form(None, max_length=255, description="名称(可选)"), | ||||||
| @ -97,6 +99,7 @@ async def create_face( | |||||||
| # 2. 获取单个人脸记录 | # 2. 获取单个人脸记录 | ||||||
| # ------------------------------ | # ------------------------------ | ||||||
| @router.get("/{face_id}", response_model=APIResponse, summary="获取单个人脸记录") | @router.get("/{face_id}", response_model=APIResponse, summary="获取单个人脸记录") | ||||||
|  | @encrypt_response() | ||||||
| async def get_face(face_id: int): | async def get_face(face_id: int): | ||||||
|     conn = None |     conn = None | ||||||
|     cursor = None |     cursor = None | ||||||
| @ -130,6 +133,7 @@ async def get_face(face_id: int): | |||||||
| # 3. 获取人脸列表 | # 3. 获取人脸列表 | ||||||
| # ------------------------------ | # ------------------------------ | ||||||
| @router.get("", response_model=APIResponse, summary="获取人脸列表(分页+筛选)") | @router.get("", response_model=APIResponse, summary="获取人脸列表(分页+筛选)") | ||||||
|  | @encrypt_response() | ||||||
| async def get_face_list( | async def get_face_list( | ||||||
|         page: int = Query(1, ge=1), |         page: int = Query(1, ge=1), | ||||||
|         page_size: int = Query(10, ge=1, le=100), |         page_size: int = Query(10, ge=1, le=100), | ||||||
| @ -189,6 +193,7 @@ async def get_face_list( | |||||||
| # 4. 更新人脸记录 | # 4. 更新人脸记录 | ||||||
| # ------------------------------ | # ------------------------------ | ||||||
| @router.put("/{face_id}", response_model=APIResponse, summary="更新人脸记录") | @router.put("/{face_id}", response_model=APIResponse, summary="更新人脸记录") | ||||||
|  | @encrypt_response() | ||||||
| async def update_face(face_id: int, face_update: FaceUpdateRequest): | async def update_face(face_id: int, face_update: FaceUpdateRequest): | ||||||
|     conn = None |     conn = None | ||||||
|     cursor = None |     cursor = None | ||||||
| @ -255,6 +260,7 @@ async def update_face(face_id: int, face_update: FaceUpdateRequest): | |||||||
| # 5. 删除人脸记录 | # 5. 删除人脸记录 | ||||||
| # ------------------------------ | # ------------------------------ | ||||||
| @router.delete("/{face_id}", response_model=APIResponse, summary="删除人脸记录") | @router.delete("/{face_id}", response_model=APIResponse, summary="删除人脸记录") | ||||||
|  | @encrypt_response() | ||||||
| async def delete_face(face_id: int): | async def delete_face(face_id: int): | ||||||
|     conn = None |     conn = None | ||||||
|     cursor = None |     cursor = None | ||||||
| @ -305,6 +311,7 @@ async def delete_face(face_id: int): | |||||||
| # 6. 获取人脸图片 | # 6. 获取人脸图片 | ||||||
| # ------------------------------ | # ------------------------------ | ||||||
| @router.get("/{face_id}/image", summary="获取人脸图片") | @router.get("/{face_id}/image", summary="获取人脸图片") | ||||||
|  | @encrypt_response() | ||||||
| async def get_face_image(face_id: int): | async def get_face_image(face_id: int): | ||||||
|     conn = None |     conn = None | ||||||
|     cursor = None |     cursor = None | ||||||
|  | |||||||
| @ -18,12 +18,11 @@ app = Flask(__name__) | |||||||
| # ------------------------------ | # ------------------------------ | ||||||
| # 核心修改:与 FastAPI 对齐的跨域配置 | # 核心修改:与 FastAPI 对齐的跨域配置 | ||||||
| # ------------------------------ | # ------------------------------ | ||||||
| # 1. 允许的前端域名(完全复制 FastAPI 的 ALLOWED_ORIGINS,确保前后端一致) | # 1. 允许的前端域名(根据实际环境修改,生产环境删除 "*") | ||||||
| ALLOWED_ORIGINS = [ | ALLOWED_ORIGINS = [ | ||||||
|     # "http://localhost:8080",  # 本地前端开发地址(必改:替换为你的前端实际地址) |     # "http://localhost:8080",  # 本地前端开发地址 | ||||||
|     # "http://127.0.0.1:8080", |     # "http://127.0.0.1:8080", | ||||||
|     # "http://服务器IP:8080",    # 部署后前端地址(替换为你的服务器IP/域名) |     # "http://服务器IP:8080",    # 部署后前端地址 | ||||||
|     # # "*" 仅开发环境临时使用,生产环境必须删除(安全风险) |  | ||||||
|     "*" |     "*" | ||||||
| ] | ] | ||||||
|  |  | ||||||
| @ -31,33 +30,29 @@ ALLOWED_ORIGINS = [ | |||||||
| CORS( | CORS( | ||||||
|     app, |     app, | ||||||
|     resources={ |     resources={ | ||||||
|         r"/*": {  # 对所有 Flask 路由生效(覆盖图片、模型下载所有接口) |         r"/*": { | ||||||
|             "origins": ALLOWED_ORIGINS,        # 允许的前端域名(与 FastAPI 一致) |             "origins": ALLOWED_ORIGINS, | ||||||
|             "allow_credentials": True,         # 允许携带 Cookie(与 FastAPI 一致,需登录态必开) |             "allow_credentials": True, | ||||||
|             "methods": ["*"],                  # 允许所有 HTTP 方法(FastAPI 用 "*",此处同步) |             "methods": ["*"], | ||||||
|             "allow_headers": ["*"],            # 允许所有请求头(与 FastAPI 一致) |             "allow_headers": ["*"], | ||||||
|         } |         } | ||||||
|     }, |     }, | ||||||
| ) | ) | ||||||
|  |  | ||||||
| # ------------------------------ | # ------------------------------ | ||||||
| # 核心路径配置(不变,确保资源目录正确) | # 核心路径配置(关键修改:修正 PROJECT_ROOT 计算) | ||||||
|  | # 原问题:file_service.py 在 service 文件夹内,需向上跳一级到项目根目录 | ||||||
| # ------------------------------ | # ------------------------------ | ||||||
| CURRENT_FILE_PATH = Path(__file__).resolve() | CURRENT_FILE_PATH = Path(__file__).resolve()  # 当前文件路径:service/file_service.py | ||||||
| PROJECT_ROOT = CURRENT_FILE_PATH.parent  # 项目根目录(video/) | PROJECT_ROOT = CURRENT_FILE_PATH.parent.parent  # 项目根目录(service 文件夹的父目录) | ||||||
| # 资源目录(图片、模型) | # 资源目录(现在正确指向项目根目录下的文件夹) | ||||||
| BASE_IMAGE_DIR_DECT = str((PROJECT_ROOT / "resource" / "dect").resolve())       # 检测图片目录 | BASE_IMAGE_DIR_DECT = str((PROJECT_ROOT / "resource" / "dect").resolve())       # 根目录/resource/dect | ||||||
| BASE_IMAGE_DIR_UP_IMAGES = str((PROJECT_ROOT / "up_images").resolve())          # 人脸图片目录 | BASE_IMAGE_DIR_UP_IMAGES = str((PROJECT_ROOT / "up_images").resolve())          # 根目录/up_images | ||||||
| BASE_MODEL_DIR = str((PROJECT_ROOT / "resource" / "models").resolve())          # 模型文件目录 | BASE_MODEL_DIR = str((PROJECT_ROOT / "resource" / "models").resolve())          # 根目录/resource/models | ||||||
|  |  | ||||||
| # 打印路径配置(调试用,确认目录正确) |  | ||||||
| # logger.info(f"[Flask 配置] 项目根目录:{PROJECT_ROOT}") |  | ||||||
| # logger.info(f"[Flask 配置] 模型目录:{BASE_MODEL_DIR}") |  | ||||||
| # logger.info(f"[Flask 配置] 人脸图片目录:{BASE_IMAGE_DIR_UP_IMAGES}") |  | ||||||
| # logger.info(f"[Flask 配置] 检测图片目录:{BASE_IMAGE_DIR_DECT}") |  | ||||||
|  |  | ||||||
| # ------------------------------ | # ------------------------------ | ||||||
| # 安全检查装饰器(不变,防路径遍历/非法文件) | # 安全检查装饰器(不变) | ||||||
| # ------------------------------ | # ------------------------------ | ||||||
| def safe_path_check(root_dir: str): | def safe_path_check(root_dir: str): | ||||||
|     def decorator(func): |     def decorator(func): | ||||||
| @ -86,7 +81,7 @@ def safe_path_check(root_dir: str): | |||||||
|                 ) |                 ) | ||||||
|                 abort(404) |                 abort(404) | ||||||
|  |  | ||||||
|             # 3. 限制文件大小(模型200MB,图片10MB,避免超大文件攻击) |             # 3. 限制文件大小(模型200MB,图片10MB) | ||||||
|             max_size = 200 * 1024 * 1024 if "models" in root_dir else 10 * 1024 * 1024 |             max_size = 200 * 1024 * 1024 if "models" in root_dir else 10 * 1024 * 1024 | ||||||
|             if os.path.getsize(full_file_path) > max_size: |             if os.path.getsize(full_file_path) > max_size: | ||||||
|                 logger.warning( |                 logger.warning( | ||||||
| @ -121,7 +116,7 @@ def download_model(resource_path, root_dir): | |||||||
|             f"[Flask 模型下载] 成功请求!IP:{request.remote_addr} | 文件:{file_name} | 目录:{full_dir}" |             f"[Flask 模型下载] 成功请求!IP:{request.remote_addr} | 文件:{file_name} | 目录:{full_dir}" | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|         # 强制浏览器下载(而非预览),设置二进制文件类型 |         # 强制浏览器下载(而非预览) | ||||||
|         return send_from_directory( |         return send_from_directory( | ||||||
|             full_dir, |             full_dir, | ||||||
|             file_name, |             file_name, | ||||||
| @ -158,7 +153,7 @@ def get_face_image(resource_path, root_dir): | |||||||
|             f"[Flask 人脸图片] 成功请求!IP:{request.remote_addr} | 文件:{file_name} | 目录:{full_dir}" |             f"[Flask 人脸图片] 成功请求!IP:{request.remote_addr} | 文件:{file_name} | 目录:{full_dir}" | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|         # 允许浏览器预览图片(而非下载) |         # 允许浏览器预览图片 | ||||||
|         return send_from_directory(full_dir, file_name, as_attachment=False) |         return send_from_directory(full_dir, file_name, as_attachment=False) | ||||||
|  |  | ||||||
|     except Exception as e: |     except Exception as e: | ||||||
| @ -205,7 +200,6 @@ def get_dect_image(resource_path, root_dir): | |||||||
| @safe_path_check(root_dir=BASE_IMAGE_DIR_DECT) | @safe_path_check(root_dir=BASE_IMAGE_DIR_DECT) | ||||||
| def get_compatible_image(resource_path, root_dir): | def get_compatible_image(resource_path, root_dir): | ||||||
|     try: |     try: | ||||||
|         # 逻辑与检测图片接口一致,仅URL前缀不同(兼容旧前端) |  | ||||||
|         resource_path = resource_path.replace("/", os.sep).replace("\\", os.sep) |         resource_path = resource_path.replace("/", os.sep).replace("\\", os.sep) | ||||||
|         dir_path, file_name = os.path.split(resource_path) |         dir_path, file_name = os.path.split(resource_path) | ||||||
|         full_dir = os.path.abspath(os.path.join(root_dir, dir_path)) |         full_dir = os.path.abspath(os.path.join(root_dir, dir_path)) | ||||||
| @ -230,7 +224,7 @@ def get_compatible_image(resource_path, root_dir): | |||||||
|         abort(500) |         abort(500) | ||||||
|  |  | ||||||
| # ------------------------------ | # ------------------------------ | ||||||
| # 全局错误处理器(友好提示,与 FastAPI 错误信息风格一致) | # 全局错误处理器(不变) | ||||||
| # ------------------------------ | # ------------------------------ | ||||||
| @app.errorhandler(403) | @app.errorhandler(403) | ||||||
| def forbidden_error(error): | def forbidden_error(error): | ||||||
| @ -256,7 +250,7 @@ def server_error(error): | |||||||
| # Flask 独立启动入口(供测试,实际由 main.py 子线程启动) | # Flask 独立启动入口(供测试,实际由 main.py 子线程启动) | ||||||
| # ------------------------------ | # ------------------------------ | ||||||
| if __name__ == '__main__': | if __name__ == '__main__': | ||||||
|     # 确保所有资源目录存在(防止初始化失败) |     # 确保所有资源目录存在 | ||||||
|     required_dirs = [ |     required_dirs = [ | ||||||
|         (BASE_IMAGE_DIR_DECT, "检测图片目录"), |         (BASE_IMAGE_DIR_DECT, "检测图片目录"), | ||||||
|         (BASE_IMAGE_DIR_UP_IMAGES, "人脸图片目录"), |         (BASE_IMAGE_DIR_UP_IMAGES, "人脸图片目录"), | ||||||
| @ -267,16 +261,16 @@ if __name__ == '__main__': | |||||||
|             logger.info(f"[Flask 初始化] {dir_desc}不存在,创建:{dir_path}") |             logger.info(f"[Flask 初始化] {dir_desc}不存在,创建:{dir_path}") | ||||||
|             os.makedirs(dir_path, exist_ok=True) |             os.makedirs(dir_path, exist_ok=True) | ||||||
|  |  | ||||||
|     # 启动提示(含访问示例) |     # 启动提示 | ||||||
|     logger.info("\n[Flask 服务启动成功!] 支持的接口:") |     logger.info("\n[Flask 服务启动成功!] 支持的接口:") | ||||||
|     logger.info(f"1. 模型下载 → http://服务器IP:5000/model/download/resource/models/xxx.pt") |     logger.info(f"1. 模型下载 → http://服务器IP:5000/model/download/resource/models/xxx.pt") | ||||||
|     logger.info(f"2. 人脸图片 → http://服务器IP:5000/up_images/xxx.jpg") |     logger.info(f"2. 人脸图片 → http://服务器IP:5000/up_images/xxx.jpg") | ||||||
|     logger.info(f"3. 检测图片 → http://服务器IP:5000/resource/dect/xxx.jpg 或 http://服务器IP:5000/images/xxx.jpg\n") |     logger.info(f"3. 检测图片 → http://服务器IP:5000/resource/dect/xxx.jpg 或 http://服务器IP:5000/images/xxx.jpg\n") | ||||||
|  |  | ||||||
|     # 启动服务(禁用 debug 和自动重载,避免多线程冲突) |     # 启动服务(禁用 debug 和自动重载) | ||||||
|     app.run( |     app.run( | ||||||
|         host="0.0.0.0",  # 允许外部IP访问 |         host="0.0.0.0", | ||||||
|         port=5000,        # 与 main.py 中 Flask 端口一致 |         port=5000, | ||||||
|         debug=False, |         debug=False, | ||||||
|         use_reloader=False |         use_reloader=False | ||||||
|     ) |     ) | ||||||
| @ -11,6 +11,7 @@ from mysql.connector import Error as MySQLError | |||||||
|  |  | ||||||
| # 复用项目依赖 | # 复用项目依赖 | ||||||
| from ds.db import db | from ds.db import db | ||||||
|  | from encryption.encrypt_decorator import encrypt_response | ||||||
| from schema.model_schema import ( | from schema.model_schema import ( | ||||||
|     ModelCreateRequest, |     ModelCreateRequest, | ||||||
|     ModelUpdateRequest, |     ModelUpdateRequest, | ||||||
| @ -190,6 +191,7 @@ def get_current_conf_threshold(): | |||||||
|  |  | ||||||
| # 1. 上传模型(保持不变) | # 1. 上传模型(保持不变) | ||||||
| @router.post("", response_model=APIResponse, summary="上传YOLO模型(.pt格式)") | @router.post("", response_model=APIResponse, summary="上传YOLO模型(.pt格式)") | ||||||
|  | @encrypt_response() | ||||||
| async def upload_model( | async def upload_model( | ||||||
|         name: str = Form(..., description="模型名称"), |         name: str = Form(..., description="模型名称"), | ||||||
|         description: str = Form(None, description="模型描述"), |         description: str = Form(None, description="模型描述"), | ||||||
| @ -281,6 +283,7 @@ async def upload_model( | |||||||
|  |  | ||||||
| # 2. 获取模型列表(保持不变) | # 2. 获取模型列表(保持不变) | ||||||
| @router.get("", response_model=APIResponse, summary="获取模型列表(分页)") | @router.get("", response_model=APIResponse, summary="获取模型列表(分页)") | ||||||
|  | @encrypt_response() | ||||||
| async def get_model_list( | async def get_model_list( | ||||||
|         page: int = Query(1, ge=1), |         page: int = Query(1, ge=1), | ||||||
|         page_size: int = Query(10, ge=1, le=100), |         page_size: int = Query(10, ge=1, le=100), | ||||||
| @ -337,6 +340,7 @@ async def get_model_list( | |||||||
|  |  | ||||||
| # 3. 获取默认模型(保持不变) | # 3. 获取默认模型(保持不变) | ||||||
| @router.get("/default", response_model=APIResponse, summary="获取当前默认模型") | @router.get("/default", response_model=APIResponse, summary="获取当前默认模型") | ||||||
|  | @encrypt_response() | ||||||
| async def get_default_model(): | async def get_default_model(): | ||||||
|     conn = None |     conn = None | ||||||
|     cursor = None |     cursor = None | ||||||
| @ -379,6 +383,7 @@ async def get_default_model(): | |||||||
|  |  | ||||||
| # 4. 获取单个模型详情(保持不变) | # 4. 获取单个模型详情(保持不变) | ||||||
| @router.get("/{model_id}", response_model=APIResponse, summary="获取单个模型详情") | @router.get("/{model_id}", response_model=APIResponse, summary="获取单个模型详情") | ||||||
|  | @encrypt_response() | ||||||
| async def get_model(model_id: int): | async def get_model(model_id: int): | ||||||
|     conn = None |     conn = None | ||||||
|     cursor = None |     cursor = None | ||||||
| @ -414,6 +419,7 @@ async def get_model(model_id: int): | |||||||
|  |  | ||||||
| # 5. 更新模型信息(保持不变) | # 5. 更新模型信息(保持不变) | ||||||
| @router.put("/{model_id}", response_model=APIResponse, summary="更新模型信息") | @router.put("/{model_id}", response_model=APIResponse, summary="更新模型信息") | ||||||
|  | @encrypt_response() | ||||||
| async def update_model(model_id: int, model_update: ModelUpdateRequest): | async def update_model(model_id: int, model_update: ModelUpdateRequest): | ||||||
|     conn = None |     conn = None | ||||||
|     cursor = None |     cursor = None | ||||||
| @ -497,6 +503,7 @@ async def update_model(model_id: int, model_update: ModelUpdateRequest): | |||||||
|  |  | ||||||
| # 5.1 更换默认模型(添加置信度参数) | # 5.1 更换默认模型(添加置信度参数) | ||||||
| @router.put("/{model_id}/set-default", response_model=APIResponse, summary="更换默认模型(自动重启服务)") | @router.put("/{model_id}/set-default", response_model=APIResponse, summary="更换默认模型(自动重启服务)") | ||||||
|  | @encrypt_response() | ||||||
| async def set_default_model( | async def set_default_model( | ||||||
|     model_id: int, |     model_id: int, | ||||||
|     conf_threshold: float = Query(0.8, ge=0.01, le=0.99, description="模型检测置信度阈值(0.01-0.99)") |     conf_threshold: float = Query(0.8, ge=0.01, le=0.99, description="模型检测置信度阈值(0.01-0.99)") | ||||||
| @ -591,6 +598,7 @@ async def set_default_model( | |||||||
|  |  | ||||||
| # 6. 删除模型(保持不变) | # 6. 删除模型(保持不变) | ||||||
| @router.delete("/{model_id}", response_model=APIResponse, summary="删除模型") | @router.delete("/{model_id}", response_model=APIResponse, summary="删除模型") | ||||||
|  | @encrypt_response() | ||||||
| async def delete_model(model_id: int): | async def delete_model(model_id: int): | ||||||
|     conn = None |     conn = None | ||||||
|     cursor = None |     cursor = None | ||||||
| @ -650,6 +658,7 @@ async def delete_model(model_id: int): | |||||||
|  |  | ||||||
| # 7. 下载模型文件(保持不变) | # 7. 下载模型文件(保持不变) | ||||||
| @router.get("/{model_id}/download", summary="下载模型文件") | @router.get("/{model_id}/download", summary="下载模型文件") | ||||||
|  | @encrypt_response() | ||||||
| async def download_model(model_id: int): | async def download_model(model_id: int): | ||||||
|     conn = None |     conn = None | ||||||
|     cursor = None |     cursor = None | ||||||
|  | |||||||
| @ -25,6 +25,7 @@ router = APIRouter( | |||||||
| # 1. 创建敏感信息记录 | # 1. 创建敏感信息记录 | ||||||
| # ------------------------------ | # ------------------------------ | ||||||
| @router.post("", response_model=APIResponse, summary="创建敏感信息记录") | @router.post("", response_model=APIResponse, summary="创建敏感信息记录") | ||||||
|  | @encrypt_response() | ||||||
| async def create_sensitive( | async def create_sensitive( | ||||||
|         sensitive: SensitiveCreateRequest, |         sensitive: SensitiveCreateRequest, | ||||||
|         current_user: UserResponse = Depends(get_current_user)  # 补充登录认证依赖(与其他接口保持一致) |         current_user: UserResponse = Depends(get_current_user)  # 补充登录认证依赖(与其他接口保持一致) | ||||||
| @ -76,7 +77,9 @@ async def create_sensitive( | |||||||
| # ------------------------------ | # ------------------------------ | ||||||
| # 2. 获取单个敏感信息记录 | # 2. 获取单个敏感信息记录 | ||||||
| # ------------------------------ | # ------------------------------ | ||||||
|  |  | ||||||
| @router.get("/{sensitive_id}", response_model=APIResponse, summary="获取单个敏感信息记录") | @router.get("/{sensitive_id}", response_model=APIResponse, summary="获取单个敏感信息记录") | ||||||
|  | @encrypt_response() | ||||||
| async def get_sensitive( | async def get_sensitive( | ||||||
|         sensitive_id: int, |         sensitive_id: int, | ||||||
|         current_user: UserResponse = Depends(get_current_user)  # 需登录认证 |         current_user: UserResponse = Depends(get_current_user)  # 需登录认证 | ||||||
| @ -125,8 +128,7 @@ async def get_sensitive( | |||||||
| async def get_sensitive_list( | async def get_sensitive_list( | ||||||
|         page: int = Query(1, ge=1, description="页码(默认1,最小1)"), |         page: int = Query(1, ge=1, description="页码(默认1,最小1)"), | ||||||
|         page_size: int = Query(10, ge=1, le=100, description="每页条数(默认10,1-100)"), |         page_size: int = Query(10, ge=1, le=100, description="每页条数(默认10,1-100)"), | ||||||
|         name: Optional[str] = Query(None, description="敏感词关键词搜索(模糊匹配)"), |         name: Optional[str] = Query(None, description="敏感词关键词搜索(模糊匹配)") | ||||||
|         current_user: UserResponse = Depends(get_current_user)  # 需登录认证 |  | ||||||
| ): | ): | ||||||
|     """ |     """ | ||||||
|     获取敏感信息分页列表: |     获取敏感信息分页列表: | ||||||
| @ -191,6 +193,7 @@ async def get_sensitive_list( | |||||||
| # 4. 更新敏感信息记录 | # 4. 更新敏感信息记录 | ||||||
| # ------------------------------ | # ------------------------------ | ||||||
| @router.put("/{sensitive_id}", response_model=APIResponse, summary="更新敏感信息记录") | @router.put("/{sensitive_id}", response_model=APIResponse, summary="更新敏感信息记录") | ||||||
|  | @encrypt_response() | ||||||
| async def update_sensitive( | async def update_sensitive( | ||||||
|         sensitive_id: int, |         sensitive_id: int, | ||||||
|         sensitive_update: SensitiveUpdateRequest, |         sensitive_update: SensitiveUpdateRequest, | ||||||
| @ -269,6 +272,7 @@ async def update_sensitive( | |||||||
| # 5. 删除敏感信息记录 | # 5. 删除敏感信息记录 | ||||||
| # ------------------------------ | # ------------------------------ | ||||||
| @router.delete("/{sensitive_id}", response_model=APIResponse, summary="删除敏感信息记录") | @router.delete("/{sensitive_id}", response_model=APIResponse, summary="删除敏感信息记录") | ||||||
|  | @encrypt_response() | ||||||
| async def delete_sensitive( | async def delete_sensitive( | ||||||
|         sensitive_id: int, |         sensitive_id: int, | ||||||
|         current_user: UserResponse = Depends(get_current_user)  # 需登录认证 |         current_user: UserResponse = Depends(get_current_user)  # 需登录认证 | ||||||
|  | |||||||
| @ -27,6 +27,7 @@ router = APIRouter( | |||||||
| # 1. 用户注册接口 | # 1. 用户注册接口 | ||||||
| # ------------------------------ | # ------------------------------ | ||||||
| @router.post("/register", response_model=APIResponse, summary="用户注册") | @router.post("/register", response_model=APIResponse, summary="用户注册") | ||||||
|  | @encrypt_response() | ||||||
| async def user_register(request: UserRegisterRequest): | async def user_register(request: UserRegisterRequest): | ||||||
|     """ |     """ | ||||||
|     用户注册: |     用户注册: | ||||||
| @ -78,6 +79,7 @@ async def user_register(request: UserRegisterRequest): | |||||||
| # 2. 用户登录接口 | # 2. 用户登录接口 | ||||||
| # ------------------------------ | # ------------------------------ | ||||||
| @router.post("/login", response_model=APIResponse, summary="用户登录(获取 Token)") | @router.post("/login", response_model=APIResponse, summary="用户登录(获取 Token)") | ||||||
|  | @encrypt_response() | ||||||
| async def user_login(request: UserLoginRequest): | async def user_login(request: UserLoginRequest): | ||||||
|     """ |     """ | ||||||
|     用户登录: |     用户登录: | ||||||
| @ -140,6 +142,7 @@ async def user_login(request: UserLoginRequest): | |||||||
| # 3. 获取当前登录用户信息(需认证) | # 3. 获取当前登录用户信息(需认证) | ||||||
| # ------------------------------ | # ------------------------------ | ||||||
| @router.get("/me", response_model=APIResponse, summary="获取当前用户信息") | @router.get("/me", response_model=APIResponse, summary="获取当前用户信息") | ||||||
|  | @encrypt_response() | ||||||
| async def get_current_user_info( | async def get_current_user_info( | ||||||
|         current_user: UserResponse = Depends(get_current_user)  # 依赖认证中间件 |         current_user: UserResponse = Depends(get_current_user)  # 依赖认证中间件 | ||||||
| ): | ): | ||||||
| @ -159,6 +162,7 @@ async def get_current_user_info( | |||||||
| # 4. 获取用户列表(仅需登录权限) | # 4. 获取用户列表(仅需登录权限) | ||||||
| # ------------------------------ | # ------------------------------ | ||||||
| @router.get("/list", response_model=APIResponse, summary="获取用户列表") | @router.get("/list", response_model=APIResponse, summary="获取用户列表") | ||||||
|  | @encrypt_response() | ||||||
| async def get_user_list( | async def get_user_list( | ||||||
|         page: int = Query(1, ge=1, description="页码,从1开始"), |         page: int = Query(1, ge=1, description="页码,从1开始"), | ||||||
|         page_size: int = Query(10, ge=1, le=100, description="每页条数,1-100之间"), |         page_size: int = Query(10, ge=1, le=100, description="每页条数,1-100之间"), | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user