File size: 8,563 Bytes
13f2c73
856d1b0
2814e79
d5dffcf
d3ae963
 
13f2c73
 
 
d3ae963
d5dffcf
 
 
 
13f2c73
d5dffcf
 
13f2c73
d5dffcf
 
 
 
 
 
 
 
 
e3fab5f
d5dffcf
 
 
 
 
e904a47
d5dffcf
 
 
 
e904a47
d5dffcf
 
13f2c73
d5dffcf
13f2c73
 
 
 
d5dffcf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0be9501
d5dffcf
85494ee
4c9deec
c60e0ef
 
8f0ec20
8e0cd3e
d5dffcf
13f2c73
 
 
 
 
 
0be9501
13f2c73
 
c60e0ef
 
8f0ec20
8e0cd3e
13f2c73
d5dffcf
 
 
 
 
 
 
 
90d7999
 
 
 
 
 
71ce6d2
 
13f2c73
 
 
 
 
85494ee
856d1b0
 
 
 
 
 
 
 
 
 
 
13f2c73
85494ee
13f2c73
 
85494ee
 
 
012c1d3
 
 
 
 
 
13f2c73
f68778c
13f2c73
 
 
 
 
 
b71f16d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c60e0ef
 
 
 
 
 
 
 
 
 
 
 
 
8f0ec20
c70d6e7
 
c60e0ef
 
 
 
 
 
8f0ec20
c70d6e7
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
# models.py
from pydantic import BaseModel, validator
from typing import Optional, List

class SendCodeRequest(BaseModel):
    contact: str
    contact_type: str  
    action_type: str   
    account: Optional[str] = None  

class UserRegister(BaseModel):
    account: str   
    password: str  
    email: str     
    phone: Optional[str] = "" 
    name: str      
    gender: str
    code: str      
    avatarDataUrl: Optional[str] = None
    age: Optional[int] = None
    country: Optional[str] = None
    region: Optional[str] = None
    intro: Optional[str] = None

class UserLogin(BaseModel):
    account: str   
    password: str
    remember: Optional[bool] = True  # 保持登录选项:True=30天, False=24小时

class UserUpdate(BaseModel):
    name: Optional[str] = None
    intro: Optional[str] = None
    age: Optional[int] = None
    birthday: Optional[str] = None          # 🚀 出生日期
    country: Optional[str] = None
    region: Optional[str] = None
    gender: Optional[str] = None
    avatarDataUrl: Optional[str] = None
    bannerUrl: Optional[str] = None         # 🚀 个人资料卡背景图云端URL

class PasswordReset(BaseModel):
    old_password: Optional[str] = None
    new_password: str
    verifyContact: str
    verifyType: str
    code: str
    account: str

class CommentCreate(BaseModel):
    item_id: str
    author: str 
    content: str
    reply_to_user: Optional[str] = None
    parent_id: Optional[str] = None 

class ItemCreate(BaseModel):
    type: str
    title: str
    shortDesc: str
    fullDesc: str
    link: str
    coverUrl: Optional[str] = None
    imageUrls: Optional[List[str]] = []
    author: str 
    price: int = 0
    github_token: Optional[str] = None
    netdisk_password: Optional[str] = None  # ☁️ 网盘提取码(加密存储,购买后解密)
    is_netdisk: Optional[bool] = False      # ☁️ 是否为网盘资源
    is_original: Optional[bool] = False     # 🎨 是否为原创作品
    allow_refund: Optional[bool] = True     # 💸 是否支持退款(默认支持)

class ItemUpdate(BaseModel):
    title: Optional[str] = None
    shortDesc: Optional[str] = None
    fullDesc: Optional[str] = None
    link: Optional[str] = None
    coverUrl: Optional[str] = None
    imageUrls: Optional[List[str]] = []
    price: Optional[int] = None
    github_token: Optional[str] = None
    netdisk_password: Optional[str] = None  # ☁️ 网盘提取码
    is_netdisk: Optional[bool] = None       # ☁️ 是否为网盘资源
    is_original: Optional[bool] = None      # 🎨 是否为原创作品
    allow_refund: Optional[bool] = None     # 💸 是否支持退款

class FollowToggle(BaseModel):
    user_id: str
    target_account: str
    is_active: bool

class PrivateMessage(BaseModel):
    sender: str
    receiver: str
    content: str

class PrivacySettings(BaseModel):
    follows: bool
    likes: bool
    favorites: bool
    downloads: bool

class InteractionToggle(BaseModel):
    item_id: str
    user_id: str
    action_type: str
    is_active: bool

class RatingRequest(BaseModel):
    score: int  # 1-5

    @validator("score")
    def validate_score(cls, v):
        if not isinstance(v, int):
            raise ValueError("score must be an integer between 1 and 5")
        if v < 1 or v > 5:
            raise ValueError("score must be between 1 and 5")
        return v

class RechargeRequest(BaseModel):
    account: str
    amount: int
    method: Optional[str] = "alipay"

class PurchaseRequest(BaseModel):
    account: str
    item_id: str

class TipRequest(BaseModel):
    sender_account: str
    target_account: str
    amount: int
    is_anonymous: bool
    item_id: Optional[str] = None  # 🚀 新增:记录是为哪个作品打赏的

class WithdrawRequest(BaseModel):
    account: str
    amount: int
    alipayAccount: str
    real_name: str
    code: str


# ==========================================
# 📝 任务榜数据模型
# ==========================================
class TaskCreate(BaseModel):
    """ 发布新任务 """
    title: str                              # 任务标题
    description: str                        # 任务详情
    referenceImages: Optional[List[str]] = []  # 参考图(最多6张)
    referenceLink: Optional[str] = None     # 参考链接
    totalPrice: int                         # 总价格(积分)
    depositRatio: int                       # 订金比例(10/20/30/50)
    deadline: str                           # 截止时间 (ISO格式)
    publisher: str                          # 发布者账号

class TaskUpdate(BaseModel):
    """ 更新任务 """
    title: Optional[str] = None
    description: Optional[str] = None
    referenceImages: Optional[List[str]] = None
    referenceLink: Optional[str] = None
    totalPrice: Optional[int] = None
    depositRatio: Optional[int] = None
    deadline: Optional[str] = None

class TaskApply(BaseModel):
    """ 申请接单 """
    task_id: str
    applicant: str                          # 申请者账号
    message: Optional[str] = None           # 申请留言

class TaskAssign(BaseModel):
    """ 指派接单者 """
    task_id: str
    publisher: str                          # 发布者(校验权限)
    assignee: str                           # 被指派的接单者

class TaskSubmit(BaseModel):
    """ 接单者提交成果 """
    task_id: str
    assignee: str                           # 接单者(校验权限)
    deliverables: List[str]                 # 交付物图片URL列表
    note: Optional[str] = None              # 备注说明

class TaskAccept(BaseModel):
    """ 发布者验收 """
    task_id: str
    publisher: str                          # 发布者(校验权限)
    is_accepted: bool                       # True=验收通过, False=验收不通过
    feedback: Optional[str] = None          # 反馈意见


# ==========================================
# ⚖️ P3增强:任务申诉数据模型
# ==========================================
class TaskDispute(BaseModel):
    """ 发起申诉 """
    task_id: str                            # 任务ID
    initiator: str                          # 申诉发起人(可以是发布者或接单者)
    reason: str                             # 申诉理由
    evidence: Optional[List[str]] = []      # 证据图片URL列表

class TaskDisputeResponse(BaseModel):
    """ 被申诉方回应 """
    dispute_id: str                         # 申诉ID
    respondent: str                         # 回应人
    response: str                           # 回应内容
    evidence: Optional[List[str]] = []      # 证据图片URL列表

class TaskDisputeResolve(BaseModel):
    """ 管理员仲裁 """
    dispute_id: str                         # 申诉ID
    admin_account: str                      # 管理员账号
    result: str                             # 仲裁结果: support_initiator / support_respondent / split
    split_ratio: Optional[int] = 50         # 分成比例(申诉方获得的百分比,仅当result=split时有效)
    admin_note: Optional[str] = None        # 管理员备注

# ==========================================
# 💬 讨论区数据模型(小红书风格图文社区)
# ==========================================

class PostCreate(BaseModel):
    """ 创建帖子 """
    title: str                              # 标题
    content: str                            # 正文/文案
    cover_image: str                        # 封面图(第一张)
    images: Optional[List[str]] = []       # 图片列表(最多9张)
    author: str                             # 作者账号
    is_original: Optional[bool] = False     # 🎨 是否为原创作品
    post_type: str = "image"                # "image" 或 "video"
    video_url: Optional[str] = None         # 视频 URL(仅 video 类型)

class PostUpdate(BaseModel):
    """ 更新帖子 """
    title: Optional[str] = None
    content: Optional[str] = None
    cover_image: Optional[str] = None
    images: Optional[List[str]] = None
    is_original: Optional[bool] = None      # 🎨 是否为原创作品
    post_type: Optional[str] = None         # "image" 或 "video"
    video_url: Optional[str] = None         # 视频 URL(仅 video 类型)