From b41f11a9e0feedb9cd05959e9d494f75a3b19240 Mon Sep 17 00:00:00 2001 From: aaron <> Date: Thu, 23 Jan 2025 12:32:10 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=B6=88=E6=81=AF=E4=B8=AD?= =?UTF-8?q?=E5=BF=83=E7=9A=84=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/endpoints/message.py | 89 ++++++++++++++++++++++++++++++++++++ app/models/message.py | 37 +++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 app/api/endpoints/message.py create mode 100644 app/models/message.py diff --git a/app/api/endpoints/message.py b/app/api/endpoints/message.py new file mode 100644 index 0000000..acba0e3 --- /dev/null +++ b/app/api/endpoints/message.py @@ -0,0 +1,89 @@ +from fastapi import APIRouter, Depends +from sqlalchemy.orm import Session +from typing import List, Optional +from app.models.message import MessageDB, MessageCreate, MessageInfo +from app.models.database import get_db +from app.api.deps import get_current_user, get_admin_user +from app.models.user import UserDB +from app.core.response import success_response, error_response, ResponseModel + +router = APIRouter() + +@router.post("", response_model=ResponseModel) +async def create_message( + message: MessageCreate, + db: Session = Depends(get_db), + admin: UserDB = Depends(get_admin_user) # 仅管理员可创建消息 +): + """创建消息""" + db_message = MessageDB(**message.model_dump()) + + try: + db.add(db_message) + db.commit() + db.refresh(db_message) + return success_response( + message="消息创建成功", + data=MessageInfo.model_validate(db_message) + ) + except Exception as e: + db.rollback() + return error_response(code=500, message=f"创建消息失败: {str(e)}") + +@router.post("/{message_id}/read", response_model=ResponseModel) +async def mark_message_read( + message_id: int, + db: Session = Depends(get_db), + current_user: UserDB = Depends(get_current_user) +): + """标记消息为已读""" + message = db.query(MessageDB).filter( + MessageDB.id == message_id, + MessageDB.user_id == current_user.userid + ).first() + + if not message: + return error_response(code=404, message="消息不存在") + + try: + message.is_read = True + db.commit() + db.refresh(message) + return success_response( + message="消息已标记为已读", + data=MessageInfo.model_validate(message) + ) + except Exception as e: + db.rollback() + return error_response(code=500, message=f"标记已读失败: {str(e)}") + +@router.get("/list", response_model=ResponseModel) +async def get_user_messages( + unread_only: bool = False, + skip: int = 0, + limit: int = 20, + db: Session = Depends(get_db), + current_user: UserDB = Depends(get_current_user) +): + """获取用户消息列表""" + # 构建基础查询 + query = db.query(MessageDB).filter( + MessageDB.user_id == current_user.userid + ) + + # 如果只查询未读消息 + if unread_only: + query = query.filter(MessageDB.is_read == False) + + # 获取总数 + total = query.count() + + # 获取分页数据 + messages = query.order_by( + MessageDB.create_time.desc() + ).offset(skip).limit(limit).all() + + return success_response(data={ + "total": total, + "items": [MessageInfo.model_validate(m) for m in messages] + }) \ No newline at end of file diff --git a/app/models/message.py b/app/models/message.py new file mode 100644 index 0000000..fe97a66 --- /dev/null +++ b/app/models/message.py @@ -0,0 +1,37 @@ +from datetime import datetime +from sqlalchemy import Column, Integer, String, Boolean, DateTime, Text, ForeignKey +from sqlalchemy.sql import func +from pydantic import BaseModel +from typing import Optional +from app.models.database import Base + +class MessageDB(Base): + """消息数据库模型""" + __tablename__ = "messages" + + id = Column(Integer, primary_key=True, index=True) + user_id = Column(String(32), index=True, nullable=False, comment="用户ID") + content = Column(Text, nullable=False, comment="消息内容") + is_read = Column(Boolean, default=False, comment="是否已读") + url = Column(String(255), nullable=True, comment="跳转链接") + create_time = Column(DateTime(timezone=True), server_default=func.now(), comment="创建时间") + update_time = Column(DateTime(timezone=True), onupdate=func.now(), comment="更新时间") + +class MessageCreate(BaseModel): + """创建消息请求模型""" + user_id: str + content: str + url: Optional[str] = None + +class MessageInfo(BaseModel): + """消息信息响应模型""" + id: int + user_id: str + content: str + is_read: bool + url: Optional[str] = None + create_time: datetime + update_time: Optional[datetime] = None + + class Config: + from_attributes = True \ No newline at end of file