Files
blog-service/schemas/blog.py
2025-12-11 14:02:39 +08:00

153 lines
5.2 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from typing import Optional
from pydantic import BaseModel, Field, field_validator, ConfigDict
from datetime import datetime
class BlogQuery(BaseModel):
"""博客查询参数"""
category: Optional[str] = Field(None, description="分类名称")
title: Optional[str] = Field(None, description="标题关键词")
year: Optional[int] = Field(None, description="发布年份", ge=2000, le=datetime.now().year)
@field_validator('year')
def validate_year(cls, v):
if v is not None and v > datetime.now().year:
raise ValueError('年份不能超过当前年份')
return v
class BlogBase(BaseModel):
"""博客基础模型"""
title: str = Field(..., min_length=1, max_length=255, description="博客标题")
top_value: int = Field(default=0, ge=0, description="置顶值,越大越靠前", alias="topValue")
is_great: bool = Field(default=False, description="是否是精品", alias="isGreat")
category: str = Field(..., min_length=1, max_length=45, description="分类名称")
content: Optional[str] = Field(None, description="博客内容")
is_approved: bool = Field(default=False, description="是否已发布", alias="isApproved")
@field_validator('title')
def title_not_empty(cls, v):
if not v or not v.strip():
raise ValueError('标题不能为空')
return v.strip()
@field_validator('category')
def category_not_empty(cls, v):
if not v or not v.strip():
raise ValueError('分类不能为空')
return v.strip()
class BlogCreate(BlogBase):
pass
class BlogUpdate(BlogBase):
pass
class BlogResponse(BlogBase):
id: int = Field(..., description="博客ID")
summary: Optional[str] = Field(None, description="内容摘要")
word_count: Optional[int] = Field(None, description="字数统计", alias="wordCount")
read_duration: Optional[float] = Field(None, description="阅读时长", alias="readDuration")
visit_count: Optional[int] = Field(0, description="访问次数", alias="visitCount")
create_time: datetime = Field(..., description="创建时间", alias="createTime")
update_time: datetime = Field(..., description="更新时间", alias="updateTime")
model_config = ConfigDict(
from_attributes=True,
populate_by_name=True,
json_encoders={
datetime: lambda dt: dt.strftime('%Y-%m-%d %H:%M:%S')
}
)
class BlogCategoryResponse(BaseModel):
name: str = Field(..., description="分类名称")
count: int = Field(..., description="博客数量")
model_config = ConfigDict(
from_attributes=True,
populate_by_name=True
)
class BlogStatsResponse(BaseModel):
blog_count: int = Field(..., description="博客总数", alias="blogCount")
category_count: int = Field(..., description="分类总数", alias="categoryCount")
word_count: int = Field(..., description="总字数", alias="wordCount")
class BlogVisitResponse(BaseModel):
ip: str = Field(..., description="IP地址")
os: str = Field(..., description="操作系统")
browser: str = Field(..., description="浏览器")
uri: str = Field(..., description="访问路径")
title: str = Field(None, description="博客标题")
visit_time: datetime = Field(..., description="访问时间", alias="visitTime")
model_config = ConfigDict(
from_attributes=True,
populate_by_name=True,
json_encoders={
datetime: lambda dt: dt.strftime('%Y-%m-%d %H:%M:%S')
}
)
class BlogLatestResponse(BaseModel):
id: int = Field(..., description="博客ID")
title: str = Field(..., description="博客标题")
model_config = ConfigDict(
from_attributes=True,
populate_by_name=True
)
class BlogAdjacentResponse(BaseModel):
id: int = Field(..., description="博客ID")
title: str = Field(..., description="博客标题")
model_config = ConfigDict(
from_attributes=True,
populate_by_name=True
)
class BlogCommentCreate(BaseModel):
parent_id: int = Field(default=0, ge=0, description="父评论ID0表示顶级评论", alias="parentId")
name: str = Field(..., min_length=1, max_length=50, description="评论人昵称")
website: Optional[str] = Field(None, description="评论人网站")
content: str = Field(..., min_length=1, max_length=1000, description="评论内容")
@field_validator('name')
def name_not_empty(cls, v):
if not v or not v.strip():
raise ValueError('昵称不能为空')
return v.strip()
@field_validator('content')
def content_not_empty(cls, v):
if not v or not v.strip():
raise ValueError('评论内容不能为空')
return v.strip()
class BlogCommentResponse(BlogCommentCreate):
id: int = Field(..., description="评论ID")
ip_address: str = Field(..., description="IP地址", alias="ipAddress")
user_agent: str = Field(..., description="浏览器信息", alias="userAgent")
create_time: datetime = Field(..., description="创建时间", alias="createTime")
model_config = ConfigDict(
from_attributes=True,
populate_by_name=True,
json_encoders={
datetime: lambda dt: dt.strftime('%Y-%m-%d %H:%M:%S')
}
)