add
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,111 @@
|
||||
"""管理后台请求模型(对应《03-接口文档》第 11 章)"""
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class AdminLoginReq(BaseModel):
|
||||
"""管理员登录(11.1)"""
|
||||
|
||||
username: str = Field(min_length=1, max_length=50)
|
||||
password: str = Field(min_length=1, max_length=100)
|
||||
|
||||
|
||||
class VideoReviewReq(BaseModel):
|
||||
"""审核视频(11.4)"""
|
||||
|
||||
action: str = Field(pattern="^(approve|reject)$")
|
||||
reason: str | None = Field(None, max_length=200)
|
||||
|
||||
|
||||
class ReasonReq(BaseModel):
|
||||
"""通用敏感操作原因(下架视频 / 删除评论等)"""
|
||||
|
||||
reason: str = Field(min_length=1, max_length=200)
|
||||
|
||||
|
||||
class UserStatusReq(BaseModel):
|
||||
"""封禁/解封用户(11.8)"""
|
||||
|
||||
status: int = Field(ge=1, le=2) # 1正常 2封禁
|
||||
reason: str = Field(min_length=1, max_length=200)
|
||||
|
||||
|
||||
class PointsAdjustReq(BaseModel):
|
||||
"""积分调整(11.9)"""
|
||||
|
||||
user_id: int = Field(ge=1)
|
||||
change_amount: int = Field(ge=-1000000, le=1000000) # 非 0 由服务端校验
|
||||
reason: str = Field(min_length=1, max_length=200)
|
||||
|
||||
|
||||
class ResettleReq(BaseModel):
|
||||
"""人工补单(11.12)"""
|
||||
|
||||
reason: str = Field(min_length=1, max_length=200)
|
||||
third_trade_no: str | None = Field(None, max_length=64)
|
||||
|
||||
|
||||
class RefundReq(BaseModel):
|
||||
"""退款登记(11.12-2【敏感】):reason 必填"""
|
||||
|
||||
reason: str = Field(min_length=1, max_length=200)
|
||||
|
||||
|
||||
class PackageCreateReq(BaseModel):
|
||||
"""新增充值套餐(11.14)"""
|
||||
|
||||
amount_yuan: int = Field(ge=1, le=100000)
|
||||
bonus_points: int = Field(0, ge=0)
|
||||
sort: int = 0
|
||||
points: int | None = Field(None, ge=0) # 不传则按汇率计算
|
||||
|
||||
|
||||
class PackageUpdateReq(BaseModel):
|
||||
"""修改充值套餐(11.15)"""
|
||||
|
||||
amount_yuan: int | None = Field(None, ge=1, le=100000)
|
||||
bonus_points: int | None = Field(None, ge=0)
|
||||
sort: int | None = None
|
||||
status: int | None = Field(None, ge=0, le=1)
|
||||
|
||||
|
||||
class GiftReq(BaseModel):
|
||||
"""赠送会员/积分(11.17)"""
|
||||
|
||||
user_ids: list[int] = Field(min_length=1, max_length=100)
|
||||
gift_type: str = Field(pattern="^(membership|points)$")
|
||||
plan_code: str | None = Field(None, max_length=20)
|
||||
points: int | None = Field(None, gt=0, le=1000000)
|
||||
reason: str = Field(min_length=1, max_length=200)
|
||||
|
||||
|
||||
class WithdrawReviewReq(BaseModel):
|
||||
"""提现审核(11.20)"""
|
||||
|
||||
action: str = Field(pattern="^(approve|reject)$")
|
||||
reason: str | None = Field(None, max_length=200)
|
||||
|
||||
|
||||
class ReferralReviewReq(BaseModel):
|
||||
"""推荐风控处理(11.22)"""
|
||||
|
||||
action: str = Field(pattern="^(release|invalid)$")
|
||||
reason: str = Field(min_length=1, max_length=200)
|
||||
|
||||
|
||||
class ConfigUpdateReq(BaseModel):
|
||||
"""修改平台配置(11.24)"""
|
||||
|
||||
value: str = Field(max_length=500)
|
||||
|
||||
|
||||
class ReportReviewReq(BaseModel):
|
||||
"""举报处理(11.29)"""
|
||||
|
||||
action: str = Field(pattern="^(offline_video|delete_comment|reject)$")
|
||||
reason: str = Field(min_length=1, max_length=200)
|
||||
|
||||
|
||||
class SensitiveWordAddReq(BaseModel):
|
||||
"""添加敏感词(11.31)"""
|
||||
|
||||
word: str = Field(min_length=1, max_length=50)
|
||||
@@ -0,0 +1,107 @@
|
||||
"""认证模块请求/响应模型"""
|
||||
import re
|
||||
|
||||
from pydantic import BaseModel, Field, field_validator, model_validator
|
||||
|
||||
PASSWORD_RE = re.compile(r"^(?=.*[A-Za-z])(?=.*\d).{8,32}$")
|
||||
PHONE_RE = re.compile(r"^1\d{10}$")
|
||||
EMAIL_RE = re.compile(r"^[\w.+-]+@[\w-]+\.[\w.]+$")
|
||||
|
||||
|
||||
def _check_password(v: str) -> str:
|
||||
if not PASSWORD_RE.match(v):
|
||||
raise ValueError("密码须 8-32 位且包含字母和数字")
|
||||
return v
|
||||
|
||||
|
||||
class SmsSendReq(BaseModel):
|
||||
phone: str
|
||||
scene: str = Field(pattern="^(register|login|reset)$")
|
||||
|
||||
@field_validator("phone")
|
||||
@classmethod
|
||||
def _v_phone(cls, v: str) -> str:
|
||||
if not PHONE_RE.match(v):
|
||||
raise ValueError("手机号格式不正确")
|
||||
return v
|
||||
|
||||
|
||||
class EmailSendReq(BaseModel):
|
||||
email: str
|
||||
scene: str = Field(pattern="^(register|login|reset)$")
|
||||
|
||||
@field_validator("email")
|
||||
@classmethod
|
||||
def _v_email(cls, v: str) -> str:
|
||||
if not EMAIL_RE.match(v):
|
||||
raise ValueError("邮箱格式不正确")
|
||||
return v
|
||||
|
||||
|
||||
class RegisterReq(BaseModel):
|
||||
type: str = Field(pattern="^(phone|email)$")
|
||||
phone: str | None = None
|
||||
email: str | None = None
|
||||
code: str = Field(min_length=4, max_length=8)
|
||||
password: str
|
||||
nickname: str | None = Field(default=None, max_length=20)
|
||||
invite_code: str | None = Field(default=None, max_length=10)
|
||||
|
||||
@field_validator("password")
|
||||
@classmethod
|
||||
def _v_pwd(cls, v: str) -> str:
|
||||
return _check_password(v)
|
||||
|
||||
@model_validator(mode="after")
|
||||
def _v_target(self):
|
||||
if self.type == "phone" and not (self.phone and PHONE_RE.match(self.phone)):
|
||||
raise ValueError("手机号格式不正确")
|
||||
if self.type == "email" and not (self.email and EMAIL_RE.match(self.email)):
|
||||
raise ValueError("邮箱格式不正确")
|
||||
return self
|
||||
|
||||
|
||||
class LoginReq(BaseModel):
|
||||
type: str = Field(pattern="^(phone_password|phone_code|email_password)$")
|
||||
phone: str | None = None
|
||||
email: str | None = None
|
||||
password: str | None = None
|
||||
code: str | None = None
|
||||
revoke: bool = False # 注销冻结期内:确认撤销注销
|
||||
|
||||
@model_validator(mode="after")
|
||||
def _v_fields(self):
|
||||
if self.type.startswith("phone") and not self.phone:
|
||||
raise ValueError("手机号必填")
|
||||
if self.type.startswith("email") and not self.email:
|
||||
raise ValueError("邮箱必填")
|
||||
if self.type.endswith("password") and not self.password:
|
||||
raise ValueError("密码必填")
|
||||
if self.type.endswith("code") and not self.code:
|
||||
raise ValueError("验证码必填")
|
||||
return self
|
||||
|
||||
|
||||
class RefreshReq(BaseModel):
|
||||
refresh_token: str = Field(min_length=10)
|
||||
|
||||
|
||||
class PasswordResetReq(BaseModel):
|
||||
type: str = Field(pattern="^(phone|email)$")
|
||||
phone: str | None = None
|
||||
email: str | None = None
|
||||
code: str = Field(min_length=4, max_length=8)
|
||||
new_password: str
|
||||
|
||||
@field_validator("new_password")
|
||||
@classmethod
|
||||
def _v_pwd(cls, v: str) -> str:
|
||||
return _check_password(v)
|
||||
|
||||
@model_validator(mode="after")
|
||||
def _v_target(self):
|
||||
if self.type == "phone" and not (self.phone and PHONE_RE.match(self.phone)):
|
||||
raise ValueError("手机号格式不正确")
|
||||
if self.type == "email" and not (self.email and EMAIL_RE.match(self.email)):
|
||||
raise ValueError("邮箱格式不正确")
|
||||
return self
|
||||
@@ -0,0 +1,24 @@
|
||||
"""通用模块请求模型"""
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class NotificationReadReq(BaseModel):
|
||||
"""标记已读(10.4):ids 与 all 二选一"""
|
||||
|
||||
ids: list[int] | None = None
|
||||
all: bool | None = None
|
||||
|
||||
|
||||
class ReportReq(BaseModel):
|
||||
"""提交举报(10.5)"""
|
||||
|
||||
target_type: int = Field(ge=1, le=2) # 1视频 2评论
|
||||
target_id: int = Field(ge=1)
|
||||
reason_type: int = Field(ge=1, le=5) # 1色情低俗 2暴力血腥 3侵权 4广告营销 5其他
|
||||
remark: str | None = Field(None, max_length=200)
|
||||
|
||||
|
||||
class RedeemReq(BaseModel):
|
||||
"""积分开通会员(7.3)"""
|
||||
|
||||
plan_code: str = Field(min_length=1, max_length=20)
|
||||
@@ -0,0 +1,18 @@
|
||||
"""激励模块请求模型"""
|
||||
from decimal import Decimal
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class BindInviteReq(BaseModel):
|
||||
"""绑定邀请码(9.2)"""
|
||||
|
||||
invite_code: str = Field(min_length=1, max_length=10)
|
||||
|
||||
|
||||
class WithdrawReq(BaseModel):
|
||||
"""申请提现(9.5)"""
|
||||
|
||||
assets: Decimal = Field(gt=0, le=Decimal("1000000"), max_digits=12, decimal_places=1)
|
||||
channel: int = Field(ge=1, le=3) # 1支付宝 2微信 3USDT
|
||||
account: str = Field(min_length=1, max_length=200)
|
||||
@@ -0,0 +1,10 @@
|
||||
"""互动模块请求模型"""
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class CommentCreateReq(BaseModel):
|
||||
"""发表评论(6.4):parent_id=0 为一级评论"""
|
||||
|
||||
content: str = Field(min_length=1, max_length=500)
|
||||
parent_id: int = 0
|
||||
reply_to_user_id: int | None = None
|
||||
@@ -0,0 +1,14 @@
|
||||
"""推广归因模块请求模型"""
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class InviteClickReq(BaseModel):
|
||||
"""H5 中间页点击埋点"""
|
||||
|
||||
code: str = Field(min_length=4, max_length=10)
|
||||
|
||||
|
||||
class InviteMatchReq(BaseModel):
|
||||
"""App 首启归因上报(按设备指纹匹配点击记录)"""
|
||||
|
||||
device_id: str = Field(min_length=8, max_length=64)
|
||||
@@ -0,0 +1,9 @@
|
||||
"""支付模块请求模型"""
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class RechargeReq(BaseModel):
|
||||
"""创建充值订单(8.2)"""
|
||||
|
||||
amount_yuan: int = Field(ge=1, le=100000)
|
||||
pay_method: int = Field(ge=1, le=3) # 1支付宝 2微信 3USDT
|
||||
@@ -0,0 +1,12 @@
|
||||
"""用户模块请求模型(对应《03-接口文档》第 4 章)"""
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class UpdateMeReq(BaseModel):
|
||||
nickname: str | None = Field(default=None, min_length=2, max_length=20)
|
||||
bio: str | None = Field(default=None, max_length=200)
|
||||
gender: int | None = Field(default=None, ge=0, le=2)
|
||||
|
||||
|
||||
class DeactivateReq(BaseModel):
|
||||
password: str = Field(min_length=1, max_length=32)
|
||||
@@ -0,0 +1,37 @@
|
||||
"""视频模块请求模型(对应《03-接口文档》第 5 章)"""
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class WatchReq(BaseModel):
|
||||
position: int = Field(default=0, ge=0, description="当前播放进度(秒)")
|
||||
|
||||
|
||||
class WatchCompleteReq(BaseModel):
|
||||
watch_duration: int = Field(ge=0, description="本次实际观看时长(秒)")
|
||||
|
||||
|
||||
class UploadTokenReq(BaseModel):
|
||||
"""5.5 获取上传凭证"""
|
||||
|
||||
file_name: str = Field(min_length=1, max_length=200)
|
||||
file_size: int = Field(gt=0, description="字节数")
|
||||
upload_mode: str = Field(default="raw", pattern="^(raw|hls)$")
|
||||
|
||||
|
||||
class PublishVideoReq(BaseModel):
|
||||
"""5.6 发布视频(开发环境仅支持 raw 模式:object_key 必填)"""
|
||||
|
||||
object_key: str = Field(min_length=1, max_length=300)
|
||||
title: str = Field(min_length=1, max_length=100)
|
||||
description: str = Field(default="", max_length=500)
|
||||
category_id: int = Field(ge=1)
|
||||
tags: list[str] = Field(default_factory=list, max_length=5)
|
||||
|
||||
|
||||
class EditVideoReq(BaseModel):
|
||||
"""5.12 编辑视频(字段均可选,传哪个改哪个)"""
|
||||
|
||||
title: str | None = Field(default=None, min_length=1, max_length=100)
|
||||
description: str | None = Field(default=None, max_length=500)
|
||||
category_id: int | None = Field(default=None, ge=1)
|
||||
tags: list[str] | None = Field(default=None, max_length=5)
|
||||
Reference in New Issue
Block a user