from __future__ import annotations from typing import Annotated from fastapi import APIRouter, Depends, HTTPException, Query, status from fastapi.responses import FileResponse from app.api.deps import CurrentUserContext, get_current_user from app.schemas.common import ErrorResponse from app.schemas.receipt_folder import ( ReceiptFolderDeleteResponse, ReceiptFolderDetailRead, ReceiptFolderItemRead, ReceiptFolderUpdate, ) from app.services.receipt_folder import ReceiptFolderService router = APIRouter(prefix="/receipt-folder") CurrentUser = Annotated[CurrentUserContext, Depends(get_current_user)] @router.get( "", response_model=list[ReceiptFolderItemRead], summary="查询票据夹列表", description="返回当前登录用户上传并持久化的票据列表。", ) def list_receipts( current_user: CurrentUser, status_filter: Annotated[str, Query(alias="status")] = "all", ) -> list[ReceiptFolderItemRead]: return ReceiptFolderService().list_receipts( current_user=current_user, status_filter=status_filter, ) @router.get( "/{receipt_id}", response_model=ReceiptFolderDetailRead, summary="读取票据详情", responses={status.HTTP_404_NOT_FOUND: {"model": ErrorResponse, "description": "票据不存在。"}}, ) def get_receipt(receipt_id: str, current_user: CurrentUser) -> ReceiptFolderDetailRead: try: return ReceiptFolderService().get_receipt(receipt_id, current_user) except FileNotFoundError as exc: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Receipt not found") from exc @router.patch( "/{receipt_id}", response_model=ReceiptFolderDetailRead, summary="更新票据基础识别信息", responses={status.HTTP_404_NOT_FOUND: {"model": ErrorResponse, "description": "票据不存在。"}}, ) def update_receipt( receipt_id: str, payload: ReceiptFolderUpdate, current_user: CurrentUser, ) -> ReceiptFolderDetailRead: try: return ReceiptFolderService().update_receipt( receipt_id=receipt_id, payload=payload, current_user=current_user, ) except FileNotFoundError as exc: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Receipt not found") from exc @router.delete( "/{receipt_id}", response_model=ReceiptFolderDeleteResponse, summary="删除票据", responses={status.HTTP_404_NOT_FOUND: {"model": ErrorResponse, "description": "票据不存在。"}}, ) def delete_receipt(receipt_id: str, current_user: CurrentUser) -> ReceiptFolderDeleteResponse: try: return ReceiptFolderService().delete_receipt(receipt_id=receipt_id, current_user=current_user) except FileNotFoundError as exc: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Receipt not found") from exc @router.get( "/{receipt_id}/preview", summary="预览票据原始文件", responses={status.HTTP_404_NOT_FOUND: {"model": ErrorResponse, "description": "票据预览不存在。"}}, ) def preview_receipt(receipt_id: str, current_user: CurrentUser) -> FileResponse: try: file_path, media_type, file_name = ReceiptFolderService().resolve_preview(receipt_id, current_user) except FileNotFoundError as exc: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Receipt preview not found") from exc return FileResponse(file_path, media_type=media_type, filename=file_name) @router.get( "/{receipt_id}/source", summary="读取票据源文件", responses={status.HTTP_404_NOT_FOUND: {"model": ErrorResponse, "description": "票据源文件不存在。"}}, ) def source_receipt(receipt_id: str, current_user: CurrentUser) -> FileResponse: try: file_path, media_type, file_name = ReceiptFolderService().resolve_source(receipt_id, current_user) except FileNotFoundError as exc: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Receipt source not found") from exc return FileResponse(file_path, media_type=media_type, filename=file_name)