初始提交:极码 GeekCode 全栈项目(FastAPI + Vue3)
This commit is contained in:
214
backend/routers/users.py
Normal file
214
backend/routers/users.py
Normal file
@@ -0,0 +1,214 @@
|
||||
"""用户主页和关注系统路由"""
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from sqlalchemy.orm import Session
|
||||
from sqlalchemy import func
|
||||
from database import get_db
|
||||
from models.user import User
|
||||
from models.post import Post
|
||||
from models.follow import Follow
|
||||
from models.like import Collect
|
||||
from models.notification import Notification
|
||||
from routers.auth import get_current_user
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/{user_id}")
|
||||
def get_user_profile(
|
||||
user_id: int,
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""获取用户主页信息"""
|
||||
user = db.query(User).filter(User.id == user_id).first()
|
||||
if not user:
|
||||
raise HTTPException(status_code=404, detail="用户不存在")
|
||||
|
||||
post_count = db.query(func.count(Post.id)).filter(Post.user_id == user_id, Post.is_public == True).scalar()
|
||||
follower_count = db.query(func.count(Follow.id)).filter(Follow.following_id == user_id).scalar()
|
||||
following_count = db.query(func.count(Follow.id)).filter(Follow.follower_id == user_id).scalar()
|
||||
is_following = db.query(Follow).filter(
|
||||
Follow.follower_id == current_user.id, Follow.following_id == user_id
|
||||
).first() is not None
|
||||
|
||||
return {
|
||||
"id": user.id,
|
||||
"username": user.username,
|
||||
"email": user.email,
|
||||
"avatar": user.avatar,
|
||||
"created_at": user.created_at,
|
||||
"post_count": post_count,
|
||||
"follower_count": follower_count,
|
||||
"following_count": following_count,
|
||||
"is_following": is_following,
|
||||
"is_self": current_user.id == user_id,
|
||||
}
|
||||
|
||||
|
||||
@router.post("/{user_id}/follow")
|
||||
def toggle_follow(
|
||||
user_id: int,
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""关注/取消关注"""
|
||||
if current_user.id == user_id:
|
||||
raise HTTPException(status_code=400, detail="不能关注自己")
|
||||
|
||||
target = db.query(User).filter(User.id == user_id).first()
|
||||
if not target:
|
||||
raise HTTPException(status_code=404, detail="用户不存在")
|
||||
|
||||
existing = db.query(Follow).filter(
|
||||
Follow.follower_id == current_user.id, Follow.following_id == user_id
|
||||
).first()
|
||||
|
||||
if existing:
|
||||
db.delete(existing)
|
||||
db.commit()
|
||||
return {"followed": False}
|
||||
else:
|
||||
follow = Follow(follower_id=current_user.id, following_id=user_id)
|
||||
db.add(follow)
|
||||
# 创建通知
|
||||
notif = Notification(
|
||||
user_id=user_id,
|
||||
type="follow",
|
||||
content=f"{current_user.username} 关注了你",
|
||||
from_user_id=current_user.id,
|
||||
related_id=current_user.id,
|
||||
)
|
||||
db.add(notif)
|
||||
db.commit()
|
||||
return {"followed": True}
|
||||
|
||||
|
||||
@router.get("/{user_id}/posts")
|
||||
def get_user_posts(
|
||||
user_id: int,
|
||||
page: int = 1,
|
||||
page_size: int = 20,
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""获取用户的帖子列表"""
|
||||
query = db.query(Post).filter(Post.user_id == user_id)
|
||||
if user_id != current_user.id:
|
||||
query = query.filter(Post.is_public == True)
|
||||
posts = query.order_by(Post.created_at.desc()).offset((page - 1) * page_size).limit(page_size).all()
|
||||
|
||||
user = db.query(User).filter(User.id == user_id).first()
|
||||
username = user.username if user else "未知"
|
||||
avatar = user.avatar if user else ""
|
||||
|
||||
return [
|
||||
{
|
||||
"id": p.id, "title": p.title, "content": p.content[:200],
|
||||
"category": p.category, "tags": p.tags,
|
||||
"view_count": p.view_count, "like_count": p.like_count,
|
||||
"comment_count": p.comment_count, "collect_count": p.collect_count,
|
||||
"created_at": p.created_at, "updated_at": p.updated_at,
|
||||
"author": {"id": user_id, "username": username, "avatar": avatar},
|
||||
}
|
||||
for p in posts
|
||||
]
|
||||
|
||||
|
||||
@router.get("/{user_id}/followers")
|
||||
def get_followers(
|
||||
user_id: int,
|
||||
page: int = 1,
|
||||
page_size: int = 20,
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""获取粉丝列表"""
|
||||
follows = (
|
||||
db.query(Follow)
|
||||
.filter(Follow.following_id == user_id)
|
||||
.order_by(Follow.created_at.desc())
|
||||
.offset((page - 1) * page_size).limit(page_size).all()
|
||||
)
|
||||
user_ids = [f.follower_id for f in follows]
|
||||
users = db.query(User).filter(User.id.in_(user_ids)).all() if user_ids else []
|
||||
user_map = {u.id: u for u in users}
|
||||
|
||||
return [
|
||||
{
|
||||
"id": uid,
|
||||
"username": user_map[uid].username if uid in user_map else "",
|
||||
"avatar": user_map[uid].avatar if uid in user_map else "",
|
||||
}
|
||||
for uid in user_ids
|
||||
]
|
||||
|
||||
|
||||
@router.get("/{user_id}/following")
|
||||
def get_following(
|
||||
user_id: int,
|
||||
page: int = 1,
|
||||
page_size: int = 20,
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""获取关注列表"""
|
||||
follows = (
|
||||
db.query(Follow)
|
||||
.filter(Follow.follower_id == user_id)
|
||||
.order_by(Follow.created_at.desc())
|
||||
.offset((page - 1) * page_size).limit(page_size).all()
|
||||
)
|
||||
user_ids = [f.following_id for f in follows]
|
||||
users = db.query(User).filter(User.id.in_(user_ids)).all() if user_ids else []
|
||||
user_map = {u.id: u for u in users}
|
||||
|
||||
return [
|
||||
{
|
||||
"id": uid,
|
||||
"username": user_map[uid].username if uid in user_map else "",
|
||||
"avatar": user_map[uid].avatar if uid in user_map else "",
|
||||
}
|
||||
for uid in user_ids
|
||||
]
|
||||
|
||||
|
||||
@router.get("/{user_id}/collects")
|
||||
def get_user_collects(
|
||||
user_id: int,
|
||||
page: int = 1,
|
||||
page_size: int = 20,
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""获取用户收藏的帖子"""
|
||||
collects = (
|
||||
db.query(Collect)
|
||||
.filter(Collect.user_id == user_id)
|
||||
.order_by(Collect.created_at.desc())
|
||||
.offset((page - 1) * page_size).limit(page_size).all()
|
||||
)
|
||||
post_ids = [c.post_id for c in collects]
|
||||
if not post_ids:
|
||||
return []
|
||||
|
||||
posts = db.query(Post).filter(Post.id.in_(post_ids)).all()
|
||||
post_map = {p.id: p for p in posts}
|
||||
author_ids = list(set(p.user_id for p in posts))
|
||||
authors = db.query(User).filter(User.id.in_(author_ids)).all()
|
||||
author_map = {a.id: a for a in authors}
|
||||
|
||||
result = []
|
||||
for pid in post_ids:
|
||||
p = post_map.get(pid)
|
||||
if not p:
|
||||
continue
|
||||
a = author_map.get(p.user_id)
|
||||
result.append({
|
||||
"id": p.id, "title": p.title, "content": p.content[:200],
|
||||
"category": p.category, "tags": p.tags,
|
||||
"view_count": p.view_count, "like_count": p.like_count,
|
||||
"comment_count": p.comment_count, "collect_count": p.collect_count,
|
||||
"created_at": p.created_at,
|
||||
"author": {"id": p.user_id, "username": a.username if a else "", "avatar": a.avatar if a else ""},
|
||||
})
|
||||
return result
|
||||
Reference in New Issue
Block a user