This commit is contained in:
2026-06-13 11:02:47 +08:00
parent 318ddd85a5
commit 68678304ff
15 changed files with 659 additions and 78 deletions
+57 -43
View File
@@ -82,7 +82,7 @@ class MomentService:
unique.sort(key=lambda x: x.created_at, reverse=True)
unique = unique[:limit]
return [await self._moment_to_dict(m, user_id) for m in unique]
return await self._moments_to_dicts(unique, user_id)
async def get_user_moments(self, user_id: str, viewer_id: str | None = None,
cursor: str | None = None, limit: int = 20) -> list[dict]:
@@ -116,7 +116,7 @@ class MomentService:
if viewer_id == user_id:
filtered.append(m)
return [await self._moment_to_dict(m, viewer_id) for m in filtered]
return await self._moments_to_dicts(filtered, viewer_id)
async def delete_moment(self, moment_id: str, user_id: str):
"""删除动态(仅作者)"""
@@ -243,56 +243,70 @@ class MomentService:
raise ValueError("只能删除自己的评论")
await self.db.delete(comment)
async def _moment_to_dict(self, moment: Moment, viewer_id: str | None) -> dict:
"""将 Moment ORM 对象转为前端需要的字典"""
user_result = await self.db.execute(select(User).where(User.id == moment.user_id))
user = user_result.scalars().first()
async def _moments_to_dicts(self, moments: list[Moment], viewer_id: str | None) -> list[dict]:
"""批量将 Moment ORM 对象转为前端需要的字典(优化 N+1 查询)"""
if not moments:
return []
# 点赞数
like_count_result = await self.db.execute(
select(func.count(MomentLike.id)).where(MomentLike.moment_id == moment.id)
moment_ids = [m.id for m in moments]
user_ids = list(set(m.user_id for m in moments))
# 批量获取所有作者
users_result = await self.db.execute(select(User).where(User.id.in_(user_ids)))
users_map = {u.id: u for u in users_result.scalars().all()}
# 批量获取点赞数
like_counts_result = await self.db.execute(
select(MomentLike.moment_id, func.count(MomentLike.id))
.where(MomentLike.moment_id.in_(moment_ids))
.group_by(MomentLike.moment_id)
)
like_count = like_count_result.scalar() or 0
like_counts_map = dict(like_counts_result.all())
# 是否已点赞
is_liked = False
# 批量获取评论数
comment_counts_result = await self.db.execute(
select(MomentComment.moment_id, func.count(MomentComment.id))
.where(MomentComment.moment_id.in_(moment_ids))
.group_by(MomentComment.moment_id)
)
comment_counts_map = dict(comment_counts_result.all())
# 批量获取当前用户的点赞状态
liked_moment_ids = set()
if viewer_id:
like_result = await self.db.execute(
select(MomentLike).where(
MomentLike.moment_id == moment.id,
liked_result = await self.db.execute(
select(MomentLike.moment_id).where(
MomentLike.moment_id.in_(moment_ids),
MomentLike.user_id == viewer_id,
)
)
is_liked = like_result.scalars().first() is not None
liked_moment_ids = {r[0] for r in liked_result.all()}
# 评论数
comment_count_result = await self.db.execute(
select(func.count(MomentComment.id)).where(MomentComment.moment_id == moment.id)
)
comment_count = comment_count_result.scalar() or 0
result = []
for moment in moments:
user = users_map.get(moment.user_id)
images = []
if moment.images:
try:
images = json.loads(moment.images)
except Exception:
pass
# 解析图片
images = []
if moment.images:
try:
images = json.loads(moment.images)
except:
pass
return {
"id": moment.id,
"user_id": moment.user_id,
"username": user.username if user else "未知",
"nickname": user.nickname if user else None,
"avatar_url": user.avatar_url if user else None,
"content": moment.content,
"images": images,
"visibility": moment.visibility,
"like_count": like_count,
"is_liked": is_liked,
"comment_count": comment_count,
"created_at": moment.created_at,
}
result.append({
"id": moment.id,
"user_id": moment.user_id,
"username": user.username if user else "未知",
"nickname": user.nickname if user else None,
"avatar_url": user.avatar_url if user else None,
"content": moment.content,
"images": images,
"visibility": moment.visibility,
"like_count": like_counts_map.get(moment.id, 0),
"is_liked": moment.id in liked_moment_ids,
"comment_count": comment_counts_map.get(moment.id, 0),
"created_at": moment.created_at,
})
return result
async def _get_friend_ids(self, user_id: str) -> list[str]:
"""获取好友ID列表"""