重构表结构:合并 profiles→users,展平 API 响应,新增计数器字段

- models: 删除 Profile 模型,字段合并到 User;User 新增云朵/公开/收藏计数器;Cloud 新增 favorite_count
- schemas/serializers: 展平 UserOut/AuthOut/MeOut/AdminUserOut,移除嵌套 profile
- deps: user.profile.role→user.role,移除 selectinload profile
- auth/register: 注册时直接设置 user 字段,不再创建 Profile
- clouds: 创建/删除云朵时同步 user.cloud_count 计数器,状态变化时同步 public_cloud_count
- favorites: 点赞/取消时同步 cloud.favorite_count 计数器
- admin: 审批/隐藏/批量删时同步 public_cloud_count 计数器
- profiles/stats: 用计数器替代实时 COUNT 查询
- alembic: 新增 migration 合并 profiles 到 users,初始化 counters
This commit is contained in:
2026-07-28 23:48:57 +08:00
parent 118c5cbe96
commit e75833ee4b
14 changed files with 519 additions and 285 deletions
+35 -33
View File
@@ -49,30 +49,19 @@ class ChangePasswordIn(BaseModel):
password: str = Field(min_length=8, max_length=128)
class ProfileOut(BaseModel):
model_config = ConfigDict(from_attributes=True)
id: uuid.UUID
username: str
avatar_url: str | None = None
role: Role
is_disabled: bool
created_at: datetime
class PublicProfileOut(BaseModel):
id: uuid.UUID
username: str
avatar_url: str | None = None
created_at: datetime
class UserOut(BaseModel):
model_config = ConfigDict(from_attributes=True)
id: uuid.UUID
email: EmailStr
email_verified: bool
username: str
avatar_url: str | None = None
role: Role
is_disabled: bool
cloud_count: int
public_cloud_count: int
collection_count: int
created_at: datetime
@@ -81,12 +70,10 @@ class AuthOut(BaseModel):
token_type: Literal["bearer"] = "bearer"
expires_in: int
user: UserOut
profile: ProfileOut
class MeOut(BaseModel):
user: UserOut
profile: ProfileOut
class ProfileUpdateIn(BaseModel):
@@ -98,6 +85,16 @@ class ProfileUpdateIn(BaseModel):
return value.strip()
class ProfileStatsOut(BaseModel):
user_id: uuid.UUID
username: str
email: str
created_at: datetime
cloud_count: int
public_cloud_count: int
collection_count: int
class CloudTypeSummary(BaseModel):
id: int
name: str
@@ -138,6 +135,8 @@ class CloudOut(BaseModel):
cloud_type_name: str
cloud_type_rarity: Rarity
username: str
favorite_count: int = 0
is_favorited: bool = False
class CloudUpdateIn(BaseModel):
@@ -228,7 +227,6 @@ class AdminStatsOut(BaseModel):
class AdminUserOut(BaseModel):
user: UserOut
profile: ProfileOut
class AdminUserUpdateIn(BaseModel):
@@ -269,19 +267,7 @@ class BatchUpdateOut(BaseModel):
updated: int
class ProfileStatsOut(BaseModel):
user_id: uuid.UUID
username: str
email: str
created_at: datetime
cloud_count: int
public_cloud_count: int
collection_count: int
class FavoriteIn(BaseModel):
"""设置或取消对照片的点赞收藏。"""
favorited: bool
@@ -290,3 +276,19 @@ class FavoriteOut(BaseModel):
user_id: uuid.UUID
favorited: bool
favorite_count: int
class LikeStatsPhotoOut(BaseModel):
cloud_id: uuid.UUID
image_url: str
thumbnail_url: str
favorite_count: int
captured_at: datetime | None
created_at: datetime
class LikeStatsOut(BaseModel):
user_id: uuid.UUID
username: str
total_likes: int
photos: list[LikeStatsPhotoOut]