feat: 初始化孕育无忧全栈项目基础代码结构
完成项目初始搭建,包含后端FastAPI+MongoDB服务、前端React+Vite项目的完整基础结构,添加各类配置文件与依赖清单,涵盖核心业务初始框架。
This commit is contained in:
98
backend/app/routers/chat.py
Normal file
98
backend/app/routers/chat.py
Normal file
@@ -0,0 +1,98 @@
|
||||
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 [
|
||||
"这个指标偏高会影响宝宝吗?",
|
||||
"我需要注意什么饮食?",
|
||||
"什么时候需要复查?",
|
||||
"这个结果严重吗?",
|
||||
"有什么改善建议?",
|
||||
]
|
||||
Reference in New Issue
Block a user