Files
muyingbaogaojiedu/后端-孕期报告解读-api/app/routers/chat.py
shutiaozhao127-boop cfdeeb5e41 chore: 初始化项目结构并添加基础配置文件
添加后端API和前端项目的初始目录结构,包括应用层模块、工具模块和模型定义
配置前后端的.dockerignore文件以排除开发环境文件
添加前端样式文件,包括字体、Tailwind CSS和主题配置
初始化Python虚拟环境中的类型标记文件
2026-04-01 16:55:24 +08:00

99 lines
3.2 KiB
Python

import logging
from datetime import datetime, timezone
from fastapi import APIRouter, Depends, HTTPException
from app.middleware.auth import get_current_user
from app.models.chat import ChatSession, ChatMessage
from app.models.report import Report
from app.models.user import User
from app.schemas.chat import ChatMessageRequest, ChatSessionResponse, ChatMessageResponse
from app.services.ai_service import chat_with_ai
from app.utils.helpers import parse_object_id
logger = logging.getLogger(__name__)
router = APIRouter()
@router.post("/{report_id}/message")
async def send_message(
report_id: str,
req: ChatMessageRequest,
user: User = Depends(get_current_user),
):
"""发送消息并获取 AI 回复"""
oid = parse_object_id(report_id)
report = await Report.get(oid)
if not report or report.user_id != user.id:
raise HTTPException(status_code=404, detail="报告不存在")
# Get or create chat session
session = await ChatSession.find_one(
ChatSession.user_id == user.id,
ChatSession.report_id == report.id,
)
if not session:
session = ChatSession(user_id=user.id, report_id=report.id)
await session.insert()
# Add user message
user_msg = ChatMessage(role="user", content=req.content)
session.messages.append(user_msg)
# Get AI response
history = [{"role": m.role, "content": m.content} for m in session.messages[:-1]]
try:
ai_response = await chat_with_ai(report, user, history, req.content)
except Exception:
logger.exception("AI 对话失败 report_id=%s", report_id)
raise HTTPException(status_code=502, detail="AI 对话服务暂时不可用,请稍后重试")
# Add AI message
ai_msg = ChatMessage(role="assistant", content=ai_response)
session.messages.append(ai_msg)
session.updated_at = datetime.now(timezone.utc)
await session.save()
return {
"user_message": {"role": "user", "content": req.content, "timestamp": user_msg.timestamp.isoformat()},
"ai_message": {"role": "assistant", "content": ai_response, "timestamp": ai_msg.timestamp.isoformat()},
}
@router.get("/{report_id}/history")
async def get_chat_history(
report_id: str, user: User = Depends(get_current_user)
):
"""获取聊天历史"""
oid = parse_object_id(report_id)
report = await Report.get(oid)
if not report or report.user_id != user.id:
raise HTTPException(status_code=404, detail="报告不存在")
session = await ChatSession.find_one(
ChatSession.user_id == user.id,
ChatSession.report_id == report.id,
)
if not session:
return {"messages": [], "quick_questions": _get_quick_questions()}
return {
"messages": [
{"role": m.role, "content": m.content, "timestamp": m.timestamp.isoformat()}
for m in session.messages
],
"quick_questions": _get_quick_questions(),
}
def _get_quick_questions() -> list[str]:
return [
"这个指标偏高会影响宝宝吗?",
"我需要注意什么饮食?",
"什么时候需要复查?",
"这个结果严重吗?",
"有什么改善建议?",
]