diff --git a/server/src/app/api/v1/endpoints/orchestrator.py b/server/src/app/api/v1/endpoints/orchestrator.py index 185dfbd..9fbbfe4 100644 --- a/server/src/app/api/v1/endpoints/orchestrator.py +++ b/server/src/app/api/v1/endpoints/orchestrator.py @@ -49,12 +49,14 @@ def get_latest_conversation( user_id: Annotated[str, Query(min_length=1, description="当前用户 ID。")], db: DbSession, session_type: Annotated[str | None, Query(description="会话类型,例如 expense / knowledge。")] = None, + prefer_recoverable: Annotated[bool, Query(description="是否优先返回最近一条可恢复的会话。")] = False, ) -> ConversationLookupResponse: service = AgentConversationService(db) conversation = service.get_latest_conversation_for_user( user_id=user_id, source="user_message", session_type=session_type, + prefer_recoverable=prefer_recoverable, ) if conversation is None: return ConversationLookupResponse(found=False, conversation=None) diff --git a/server/src/app/api/v1/endpoints/reimbursements.py b/server/src/app/api/v1/endpoints/reimbursements.py index 226399a..2994952 100644 --- a/server/src/app/api/v1/endpoints/reimbursements.py +++ b/server/src/app/api/v1/endpoints/reimbursements.py @@ -272,6 +272,43 @@ def get_expense_claim_item_attachment_meta( return ExpenseClaimAttachmentRead(**payload) +@router.get( + "/claims/{claim_id}/items/{item_id}/attachment/preview", + response_class=FileResponse, + summary="读取费用明细附件预览资源", + description="优先返回票据预览图;若无单独预览图,则回退到原附件内容。", + responses={ + status.HTTP_404_NOT_FOUND: { + "model": ErrorResponse, + "description": "报销单、费用明细或附件预览不存在。", + }, + }, +) +def get_expense_claim_item_attachment_preview( + claim_id: str, + item_id: str, + db: DbSession, + current_user: CurrentUser, +) -> FileResponse: + service = ExpenseClaimService(db) + try: + payload = service.get_claim_item_attachment_preview_content( + claim_id=claim_id, + item_id=item_id, + current_user=current_user, + ) + except LookupError as error: + raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(error)) from error + except FileNotFoundError as error: + raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(error)) from error + + if payload is None: + raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Claim not found") + + file_path, media_type, filename = payload + return FileResponse(file_path, media_type=media_type, filename=filename) + + @router.get( "/claims/{claim_id}/items/{item_id}/attachment", response_class=FileResponse,