Initial commit: MyBlog full stack blog

This commit is contained in:
2026-08-22 22:28:41 +08:00
commit c61193f2af
64 changed files with 7290 additions and 0 deletions
+222
View File
@@ -0,0 +1,222 @@
"""
Pydantic 数据校验模型(Schemas)。
职责:
- 定义前后端 JSON 通信所需的数据结构
- 统一定义全局响应格式 {success, data, message}
"""
from datetime import datetime
from typing import Any, Optional
from pydantic import BaseModel, ConfigDict, Field
class UnifiedResponse(BaseModel):
"""全局统一响应格式:所有接口返回该结构。"""
success: bool = True
data: Optional[Any] = None
message: str = ""
class UserCreate(BaseModel):
"""创建用户(注册)请求体:需携带邮箱验证码;角色固定为 visitor(后端强制)。"""
email: str = Field(max_length=255)
username: str = Field(min_length=2, max_length=50)
password: str = Field(max_length=128)
code: str = Field(default="", max_length=10, description="邮箱验证码(注册前通过 /api/email/send-code 获取)")
class UserOut(BaseModel):
"""用户信息输出(不含密码哈希)。"""
model_config = ConfigDict(from_attributes=True)
id: int
email: str
username: str
role: str
created_time: datetime
class LoginRequest(BaseModel):
"""登录请求体。"""
email: str
password: str
class TokenOut(BaseModel):
"""登录成功返回的 JWT 令牌与用户基础信息。"""
token: str
user_id: int
username: str
role: str
class UserLevelOut(BaseModel):
"""用户权限级别(角色)输出。"""
user_id: int
role: str
class ProfileOut(BaseModel):
"""个人资料输出(头像、简介等)。"""
model_config = ConfigDict(from_attributes=True)
id: int
email: str
username: str
role: str
avatar: Optional[str] = None
bio: Optional[str] = None
created_time: datetime
class BloggerProfileOut(BaseModel):
"""博主公开资料输出(我的简介页面使用)。"""
username: str
avatar: Optional[str] = None
bio: Optional[str] = None
role: str
class ProfileUpdate(BaseModel):
"""更新个人资料请求体(头像 / 简介,均可选)。"""
avatar: Optional[str] = Field(default=None, max_length=500)
bio: Optional[str] = Field(default=None, max_length=2000)
class SendCodeRequest(BaseModel):
"""发送邮箱验证码请求体。"""
email: str
purpose: str
class VerifyCodeRequest(BaseModel):
"""校验邮箱验证码请求体。"""
email: str
code: str
purpose: str
class ForgotPasswordRequest(BaseModel):
"""忘记密码请求体。"""
email: str
class ResetPasswordRequest(BaseModel):
"""重置密码请求体。"""
email: str
code: str
new_password: str = Field(max_length=128)
class ArticleCreate(BaseModel):
"""创建文章请求体。"""
title: str = Field(min_length=1, max_length=200)
content: str = Field(min_length=1, max_length=200000)
cover: Optional[str] = Field(default=None, max_length=500)
visibility: str = "public"
category: str = Field(default="life", description="分区:life 生活 / study 学习(取值由路由校验,统一 400 提示)")
class ArticleUpdate(BaseModel):
"""更新文章请求体(字段均可选,仅更新传入的字段)。"""
title: Optional[str] = Field(default=None, min_length=1, max_length=200)
content: Optional[str] = Field(default=None, min_length=1, max_length=200000)
cover: Optional[str] = Field(default=None, max_length=500)
visibility: Optional[str] = None
category: Optional[str] = None
class ArticleOut(BaseModel):
"""文章信息输出。"""
model_config = ConfigDict(from_attributes=True)
id: int
title: str
content: str
cover: Optional[str] = None
visibility: str
author_id: int
created_time: datetime
class CommentCreate(BaseModel):
"""发表评论请求体(parent_id 用于回复,顶层评论不填)。"""
article_id: int
content: str = Field(min_length=1, max_length=5000)
parent_id: Optional[int] = None
class CommentOut(BaseModel):
"""评论信息输出。"""
model_config = ConfigDict(from_attributes=True)
id: int
article_id: int
user_id: int
parent_id: Optional[int] = None
content: str
created_time: datetime
class ProjectOut(BaseModel):
"""项目信息输出(在线演示 / GitHub 外链)。"""
model_config = ConfigDict(from_attributes=True)
id: int
name: str
description: Optional[str] = None
tech: Optional[str] = None
project_type: str
visibility: str
demo_url: Optional[str] = None
download_url: Optional[str] = None
github_url: Optional[str] = None
created_time: datetime
updated_time: datetime
class LikeCreate(BaseModel):
"""点赞请求体。"""
article_id: int
class LikeOut(BaseModel):
"""点赞信息输出。"""
model_config = ConfigDict(from_attributes=True)
id: int
article_id: int
user_id: int
class FriendOut(BaseModel):
"""好友申请信息输出。"""
model_config = ConfigDict(from_attributes=True)
id: int
user_id: int
status: str