148 lines
4.7 KiB
Python
148 lines
4.7 KiB
Python
from pydantic import BaseModel, Field, validator
|
|
from typing import Optional, List
|
|
from datetime import datetime
|
|
import re
|
|
|
|
class FileUploadRequest(BaseModel):
|
|
"""文件上传请求"""
|
|
description: Optional[str] = Field(None, max_length=500, description="文件描述")
|
|
tags: Optional[str] = Field(None, max_length=200, description="文件标签,用逗号分隔")
|
|
is_public: bool = Field(False, description="是否公开分享")
|
|
|
|
@validator('tags')
|
|
def validate_tags(cls, v):
|
|
if v:
|
|
# 验证标签格式,只允许字母、数字、中文、下划线、中划线
|
|
tags = v.split(',')
|
|
for tag in tags:
|
|
tag = tag.strip()
|
|
if not re.match(r'^[\w\u4e00-\u9fa5-]+$', tag):
|
|
raise ValueError(f"标签 '{tag}' 格式不正确,只允许字母、数字、中文、下划线、中划线")
|
|
if len(tag) > 20:
|
|
raise ValueError(f"标签 '{tag}' 长度不能超过20个字符")
|
|
return v
|
|
|
|
class FileResponse(BaseModel):
|
|
"""文件响应"""
|
|
id: int
|
|
user_id: int
|
|
filename: str
|
|
original_filename: str
|
|
file_size: int
|
|
mime_type: str
|
|
file_hash: str
|
|
is_public: bool
|
|
download_count: int
|
|
description: Optional[str] = None
|
|
tags: Optional[str] = None
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
last_accessed_at: Optional[datetime] = None
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
class FileListResponse(BaseModel):
|
|
"""文件列表响应"""
|
|
files: List[FileResponse]
|
|
total: int
|
|
page: int
|
|
size: int
|
|
pages: int
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
class FileListRequest(BaseModel):
|
|
"""文件列表请求"""
|
|
user_id: int = Field(..., description="用户ID")
|
|
page: int = Field(1, ge=1, description="页码")
|
|
size: int = Field(20, ge=1, le=100, description="每页数量")
|
|
|
|
class FileIdRequest(BaseModel):
|
|
"""文件ID请求"""
|
|
user_id: int = Field(..., description="用户ID")
|
|
file_id: int = Field(..., description="文件ID")
|
|
|
|
class StorageInfoRequest(BaseModel):
|
|
"""存储信息请求"""
|
|
user_id: int = Field(..., description="用户ID")
|
|
|
|
class FileUpdateRequest(BaseModel):
|
|
"""文件更新请求"""
|
|
description: Optional[str] = Field(None, max_length=500, description="文件描述")
|
|
tags: Optional[str] = Field(None, max_length=200, description="文件标签,用逗号分隔")
|
|
is_public: Optional[bool] = Field(None, description="是否公开分享")
|
|
|
|
@validator('tags')
|
|
def validate_tags(cls, v):
|
|
if v:
|
|
tags = v.split(',')
|
|
for tag in tags:
|
|
tag = tag.strip()
|
|
if not re.match(r'^[\w\u4e00-\u9fa5-]+$', tag):
|
|
raise ValueError(f"标签 '{tag}' 格式不正确,只允许字母、数字、中文、下划线、中划线")
|
|
if len(tag) > 20:
|
|
raise ValueError(f"标签 '{tag}' 长度不能超过20个字符")
|
|
return v
|
|
|
|
class FileSearchRequest(BaseModel):
|
|
"""文件搜索请求"""
|
|
filename: Optional[str] = Field(None, description="文件名搜索")
|
|
tags: Optional[str] = Field(None, description="标签搜索,用逗号分隔")
|
|
mime_type: Optional[str] = Field(None, description="MIME类型过滤")
|
|
is_public: Optional[bool] = Field(None, description="是否公开文件")
|
|
start_date: Optional[datetime] = Field(None, description="开始日期")
|
|
end_date: Optional[datetime] = Field(None, description="结束日期")
|
|
min_size: Optional[int] = Field(None, ge=0, description="最小文件大小(字节)")
|
|
max_size: Optional[int] = Field(None, ge=0, description="最大文件大小(字节)")
|
|
|
|
class FileInfo(BaseModel):
|
|
"""文件信息"""
|
|
id: int
|
|
filename: str
|
|
original_filename: str
|
|
file_size: int
|
|
mime_type: str
|
|
file_hash: str
|
|
is_image: bool
|
|
is_document: bool
|
|
file_extension: str
|
|
size_formatted: str
|
|
is_public: bool = False
|
|
download_count: int = 0
|
|
description: Optional[str] = None
|
|
tags: Optional[str] = None
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
last_accessed_at: Optional[datetime] = None
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
class UploadResponse(BaseModel):
|
|
"""文件上传响应"""
|
|
file_info: FileResponse
|
|
message: str
|
|
success: bool
|
|
|
|
class DeleteResponse(BaseModel):
|
|
"""删除文件响应"""
|
|
message: str
|
|
success: bool
|
|
|
|
class StorageInfo(BaseModel):
|
|
"""存储信息"""
|
|
total_quota: int
|
|
used_space: int
|
|
available_space: int
|
|
usage_percentage: float
|
|
file_count: int
|
|
|
|
# 通用API响应格式
|
|
class ApiResponse(BaseModel):
|
|
"""API响应"""
|
|
success: bool
|
|
message: str
|
|
data: Optional[dict] = None
|
|
code: Optional[str] = None |