"""好友服务""" import uuid from datetime import datetime, timezone from sqlalchemy import select, and_ from sqlalchemy.ext.asyncio import AsyncSession from app.models.user import User from app.models.friend import Friend from app.models.friend_request import FriendRequest class FriendService: def __init__(self, db: AsyncSession): self.db = db async def send_request(self, from_user_id: str, to_user_id: str, message: str | None = None) -> FriendRequest: """发送好友请求""" if from_user_id == to_user_id: raise ValueError("不能添加自己为好友") # 检查目标用户是否存在 target = await self.db.execute(select(User).where(User.id == to_user_id)) if not target.scalars().first(): raise ValueError("目标用户不存在") # 检查是否已是好友 existing = await self.db.execute( select(Friend).where( Friend.user_id == from_user_id, Friend.friend_user_id == to_user_id, ) ) if existing.scalars().first(): raise ValueError("已经是好友了") # 检查是否有待处理的请求 pending = await self.db.execute( select(FriendRequest).where( FriendRequest.from_user_id == from_user_id, FriendRequest.to_user_id == to_user_id, FriendRequest.status == "pending", ) ) if pending.scalars().first(): raise ValueError("已发送过好友请求") request = FriendRequest( id=str(uuid.uuid4()), from_user_id=from_user_id, to_user_id=to_user_id, message=message, status="pending", ) self.db.add(request) return request async def accept_request(self, request_id: str, user_id: str): """接受好友请求""" result = await self.db.execute( select(FriendRequest).where(FriendRequest.id == request_id) ) request = result.scalars().first() if not request: raise ValueError("请求不存在") if request.to_user_id != user_id: raise ValueError("无权操作此请求") if request.status != "pending": raise ValueError("该请求已处理") request.status = "accepted" request.responded_at = datetime.utcnow() # 创建双向好友关系 self.db.add(Friend( id=str(uuid.uuid4()), user_id=request.from_user_id, friend_user_id=request.to_user_id, )) self.db.add(Friend( id=str(uuid.uuid4()), user_id=request.to_user_id, friend_user_id=request.from_user_id, )) async def reject_request(self, request_id: str, user_id: str): """拒绝好友请求""" result = await self.db.execute( select(FriendRequest).where(FriendRequest.id == request_id) ) request = result.scalars().first() if not request: raise ValueError("请求不存在") if request.to_user_id != user_id: raise ValueError("无权操作此请求") request.status = "rejected" request.responded_at = datetime.utcnow() async def get_friends(self, user_id: str) -> list[dict]: """获取好友列表""" result = await self.db.execute( select(Friend).where(Friend.user_id == user_id) ) friends = [] for friendship in result.scalars().all(): user_result = await self.db.execute( select(User).where(User.id == friendship.friend_user_id) ) user = user_result.scalars().first() if user: friends.append({ "id": friendship.id, "friend_user_id": user.id, "username": user.username, "nickname": user.bio, "avatar_url": user.avatar_url, "remark": friendship.remark, "status": user.status, }) return friends async def get_pending_requests(self, user_id: str) -> list[dict]: """获取待处理的好友请求""" result = await self.db.execute( select(FriendRequest).where( FriendRequest.to_user_id == user_id, FriendRequest.status == "pending", ).order_by(FriendRequest.created_at.desc()) ) requests = [] for req in result.scalars().all(): from_user = await self.db.execute(select(User).where(User.id == req.from_user_id)) fu = from_user.scalars().first() requests.append({ "id": req.id, "from_user_id": req.from_user_id, "from_username": fu.username if fu else "未知", "from_avatar": fu.avatar_url if fu else None, "to_user_id": req.to_user_id, "message": req.message, "status": req.status, "created_at": req.created_at, }) return requests async def remove_friend(self, user_id: str, friend_id: str): """删除好友""" await self.db.execute( select(Friend).where( Friend.user_id == user_id, Friend.friend_user_id == friend_id, ) ) # 删除双向关系 from sqlalchemy import delete await self.db.execute( delete(Friend).where( (Friend.user_id == user_id) & (Friend.friend_user_id == friend_id) | (Friend.user_id == friend_id) & (Friend.friend_user_id == user_id) ) )