ZHIWEI666 commited on
Commit
1fa72c8
·
verified ·
1 Parent(s): 0f858b8

Delete routers.py

Browse files
Files changed (1) hide show
  1. routers.py +0 -314
routers.py DELETED
@@ -1,314 +0,0 @@
1
- from fastapi import APIRouter, HTTPException
2
- import time
3
- import uuid
4
- import re
5
- import 数据库连接 as db
6
- from notifications import add_notification
7
- from models import (UserRegister, UserLogin, UserUpdate, PasswordReset,
8
- InteractionToggle, CommentCreate, ItemCreate,
9
- FollowToggle, PrivateMessage)
10
-
11
- router = APIRouter()
12
-
13
- # --- 1. 用户系统 ---
14
- @router.post("/api/users/register")
15
- async def register_user(user: UserRegister):
16
- users_db = db.load_data("users.json", default_data={})
17
- if len(user.account) <= 5: raise HTTPException(status_code=400, detail="账号必须大于5个字符")
18
- if not re.match(r'^[a-zA-Z0-9_]{6,20}$', user.account): raise HTTPException(status_code=400, detail="账号仅支持大小写英文字母、数字及下划线")
19
- if len(user.password) < 6: raise HTTPException(status_code=400, detail="密码必须大于等于6个字符")
20
- if not re.match(r'^[a-zA-Z0-9!@#$%^&*()_+\-=\[\]{};\':"\\|,.<>\/?]{6,}$', user.password): raise HTTPException(status_code=400, detail="密码包含不支持的特殊字符")
21
- if user.intro and len(user.intro) > 100: raise HTTPException(status_code=400, detail="个人介绍不能超过100个字符")
22
- if user.account in users_db: raise HTTPException(status_code=400, detail="该账号已被注册")
23
- for existing_user in users_db.values():
24
- if existing_user.get("email") == user.email: raise HTTPException(status_code=400, detail="该邮箱已被绑定")
25
- if existing_user.get("phone") == user.phone: raise HTTPException(status_code=400, detail="该手机号已被绑定")
26
-
27
- new_user = user.dict()
28
- new_user.update({"created_at": int(time.time()), "followers": [], "following": [], "privacy": {"follows": False, "likes": False, "favorites": False, "downloads": False}})
29
- users_db[user.account] = new_user
30
- db.save_data("users.json", users_db)
31
- return {"status": "success", "message": "注册成功", "data": {k: v for k, v in new_user.items() if k != "password"}}
32
-
33
- @router.post("/api/users/login")
34
- async def login_user(user: UserLogin):
35
- users_db = db.load_data("users.json", default_data={})
36
- if user.account not in users_db: raise HTTPException(status_code=404, detail="账号不存在")
37
- user_data = users_db[user.account]
38
- if user_data.get("password") != user.password: raise HTTPException(status_code=401, detail="密码错误")
39
- return {"status": "success", "token": f"mock_token_{user.account}", "account": user.account, "name": user_data["name"], "avatar": user_data.get("avatarDataUrl", "https://via.placeholder.com/150")}
40
-
41
- @router.get("/api/users/{account}")
42
- async def get_user_profile(account: str):
43
- users_db = db.load_data("users.json", default_data={})
44
- if account not in users_db: raise HTTPException(status_code=404, detail="用户不存在")
45
- user_data = users_db[account]
46
- items_db = db.load_data("items.json", default_data=[])
47
- user_items = [item for item in items_db if item.get("author") == account]
48
- user_data["receivedLikes"] = sum(item.get("likes", 0) for item in user_items)
49
- user_data["receivedFavorites"] = sum(item.get("favorites", 0) for item in user_items)
50
- user_data["receivedUses"] = sum(item.get("uses", 0) for item in user_items)
51
- return {"status": "success", "data": {k: v for k, v in user_data.items() if k != "password"}}
52
-
53
- @router.put("/api/users/{account}")
54
- async def update_user_profile(account: str, update_data: UserUpdate):
55
- users_db = db.load_data("users.json", default_data={})
56
- if account not in users_db: raise HTTPException(status_code=404, detail="用户不存在")
57
- if update_data.intro and len(update_data.intro) > 100: raise HTTPException(status_code=400, detail="个人介绍不能超过100个字符")
58
- user = users_db[account]
59
- for k, v in update_data.dict(exclude_unset=True).items():
60
- if v is not None: user[k] = v
61
- db.save_data("users.json", users_db)
62
- return {"status": "success", "data": {k: v for k, v in user.items() if k != "password"}}
63
-
64
- @router.post("/api/users/{account}/reset-password")
65
- async def reset_password(account: str, pwd_data: PasswordReset):
66
- users_db = db.load_data("users.json", default_data={})
67
- if account not in users_db: raise HTTPException(status_code=404, detail="用户不存在")
68
- if len(pwd_data.new_password) < 6: raise HTTPException(status_code=400, detail="新密码必须大于等于6个字符")
69
- if not re.match(r'^[a-zA-Z0-9!@#$%^&*()_+\-=\[\]{};\':"\\|,.<>\/?]{6,}$', pwd_data.new_password): raise HTTPException(status_code=400, detail="新密码包含不支持的特殊字符")
70
- user = users_db[account]
71
- if user.get("password") != pwd_data.old_password: raise HTTPException(status_code=401, detail="原密码错误")
72
- user["password"] = pwd_data.new_password
73
- db.save_data("users.json", users_db)
74
- return {"status": "success"}
75
-
76
- @router.post("/api/users/follow")
77
- async def toggle_follow(follow: FollowToggle):
78
- users_db = db.load_data("users.json", default_data={})
79
- if follow.target_account not in users_db or follow.user_id not in users_db: raise HTTPException(status_code=404, detail="用户不存在")
80
- target_followers = users_db[follow.target_account].setdefault("followers", [])
81
- current_following = users_db[follow.user_id].setdefault("following", [])
82
- if follow.is_active:
83
- if follow.user_id not in target_followers:
84
- target_followers.append(follow.user_id)
85
- add_notification(follow.target_account, {"type": "follow", "from_user": follow.user_id})
86
- if follow.target_account not in current_following: current_following.append(follow.target_account)
87
- else:
88
- if follow.user_id in target_followers: target_followers.remove(follow.user_id)
89
- if follow.target_account in current_following: current_following.remove(follow.target_account)
90
- db.save_data("users.json", users_db)
91
- return {"status": "success"}
92
-
93
- # --- 2. 排行榜核心 ---
94
- @router.get("/api/items")
95
- async def get_items(type: str = "tool", sort: str = "time", limit: int = 20):
96
- items_db = db.load_data("items.json", default_data=[])
97
- comments_db = db.load_data("comments.json", default_data={})
98
- filtered_items = [item for item in items_db if item.get("type") == type]
99
- for item in filtered_items:
100
- item["commentsData"] = comments_db.get(item["id"], [])
101
- item["comments"] = len(item["commentsData"])
102
- if sort == "likes": filtered_items.sort(key=lambda x: x.get("likes", 0), reverse=True)
103
- elif sort == "favorites": filtered_items.sort(key=lambda x: x.get("favorites", 0), reverse=True)
104
- elif sort == "downloads": filtered_items.sort(key=lambda x: x.get("uses", 0), reverse=True)
105
- else: filtered_items.sort(key=lambda x: x.get("created_at", 0), reverse=True)
106
- return {"status": "success", "data": filtered_items[:limit]}
107
-
108
- @router.get("/api/creators")
109
- async def get_creators(sort: str = "downloads", limit: int = 20):
110
- users_db = db.load_data("users.json", default_data={})
111
- items_db = db.load_data("items.json", default_data=[])
112
- comments_db = db.load_data("comments.json", default_data={})
113
- creators = []
114
- for account, u in users_db.items():
115
- u_items = [i for i in items_db if i.get("author") == account]
116
- tools_count = sum(1 for i in u_items if i.get("type") == "tool")
117
- apps_count = sum(1 for i in u_items if i.get("type") == "app")
118
- creators.append({
119
- "account": account, "name": u.get("name", account), "avatar": u.get("avatarDataUrl", "https://via.placeholder.com/150"),
120
- "shortDesc": u.get("intro", "这个人很懒,什么都没写..."), "fullDesc": u.get("intro", "这个人很懒,什么都没写..."),
121
- "likes": sum(i.get("likes", 0) for i in u_items), "favorites": sum(i.get("favorites", 0) for i in u_items), "downloads": sum(i.get("uses", 0) for i in u_items),
122
- "toolsCount": tools_count, "appsCount": apps_count, "followers": len(u.get("followers", [])), "created_at": u.get("created_at", 0),
123
- "commentsData": comments_db.get(account, []), "trendData": {"tools": [0,0,0,0,0, tools_count], "apps": [0,0,0,0,0, apps_count]}
124
- })
125
- if sort == "likes": creators.sort(key=lambda x: x.get("likes", 0), reverse=True)
126
- elif sort == "favorites": creators.sort(key=lambda x: x.get("favorites", 0), reverse=True)
127
- elif sort == "downloads": creators.sort(key=lambda x: x.get("downloads", 0), reverse=True)
128
- else: creators.sort(key=lambda x: x.get("created_at", 0), reverse=True)
129
- return {"status": "success", "data": creators[:limit]}
130
-
131
- @router.post("/api/items")
132
- async def create_item(item: ItemCreate):
133
- items_db = db.load_data("items.json", default_data=[])
134
- new_item = {
135
- "id": f"{item.type}_{int(time.time())}_{uuid.uuid4().hex[:6]}", "type": item.type, "title": item.title, "author": item.author,
136
- "shortDesc": item.shortDesc, "fullDesc": item.fullDesc, "link": item.link, "coverUrl": item.coverUrl, "price": item.price,
137
- "likes": 0, "favorites": 0, "comments": 0, "uses": 0, "created_at": int(time.time()), "liked_by": [], "favorited_by": []
138
- }
139
- items_db.insert(0, new_item)
140
- db.save_data("items.json", items_db)
141
- return {"status": "success", "data": new_item}
142
-
143
- # --- 3. 互动与评论 ---
144
- @router.post("/api/interactions/toggle")
145
- async def toggle_interaction(interaction: InteractionToggle):
146
- items_db = db.load_data("items.json", default_data=[])
147
- target_item = next((item for item in items_db if item["id"] == interaction.item_id), None)
148
- if not target_item: raise HTTPException(status_code=404, detail="目标存在问题")
149
-
150
- list_key = f"{interaction.action_type}d_by"
151
- count_key = "likes" if interaction.action_type == "like" else "favorites"
152
- if list_key not in target_item: target_item[list_key] = []; target_item[count_key] = 0
153
-
154
- user_list = target_item[list_key]
155
- if interaction.is_active:
156
- if interaction.user_id not in user_list:
157
- user_list.append(interaction.user_id)
158
- target_item[count_key] += 1
159
- add_notification(target_item.get("author", ""), {"type": interaction.action_type, "from_user": interaction.user_id, "target_item_id": target_item["id"], "target_item_title": target_item["title"]})
160
- else:
161
- if interaction.user_id in user_list:
162
- user_list.remove(interaction.user_id)
163
- target_item[count_key] = max(0, target_item[count_key] - 1)
164
- db.save_data("items.json", items_db)
165
- return {"status": "success", "new_count": target_item[count_key]}
166
-
167
- @router.post("/api/comments")
168
- async def post_comment(comment: CommentCreate):
169
- comments_db = db.load_data("comments.json", default_data={})
170
- users_db = db.load_data("users.json", default_data={})
171
- author_info = users_db.get(comment.author, {})
172
- reply_name = users_db.get(comment.reply_to_user, {}).get("name", comment.reply_to_user) if comment.reply_to_user else None
173
-
174
- item_comments = comments_db.get(comment.item_id, [])
175
- new_comment = {
176
- "id": f"c_{int(time.time())}_{uuid.uuid4().hex[:6]}", "author": comment.author,
177
- "authorName": author_info.get("name", comment.author), "avatar": author_info.get("avatarDataUrl", "https://via.placeholder.com/150"),
178
- "content": comment.content, "replyToUser": comment.reply_to_user, "replyToUserName": reply_name,
179
- "isDeleted": False, "replies": [], "created_at": int(time.time())
180
- }
181
-
182
- if comment.parent_id:
183
- parent = next((c for c in item_comments if c["id"] == comment.parent_id), None)
184
- if parent:
185
- parent["replies"].append(new_comment)
186
- if comment.reply_to_user:
187
- add_notification(comment.reply_to_user, {"type": "reply", "from_user": comment.author, "target_item_id": comment.item_id, "target_item_title": "收到新的回复", "content": comment.content})
188
- else: raise HTTPException(status_code=404, detail="找不到要回复的评论")
189
- else:
190
- item_comments.append(new_comment)
191
- items_db = db.load_data("items.json", default_data=[])
192
- target_item = next((item for item in items_db if item["id"] == comment.item_id), None)
193
- if target_item:
194
- add_notification(target_item.get("author", ""), {"type": "comment", "from_user": comment.author, "target_item_id": comment.item_id, "target_item_title": target_item["title"], "content": comment.content})
195
- elif comment.item_id in users_db:
196
- add_notification(comment.item_id, {"type": "comment", "from_user": comment.author, "target_item_id": comment.item_id, "target_item_title": "您的个人留言板", "content": comment.content})
197
-
198
- comments_db[comment.item_id] = item_comments
199
- db.save_data("comments.json", comments_db)
200
- return {"status": "success", "data": new_comment}
201
-
202
- @router.delete("/api/comments/{item_id}/{comment_id}")
203
- async def soft_delete_comment(item_id: str, comment_id: str, author: str):
204
- comments_db = db.load_data("comments.json", default_data={})
205
- item_comments = comments_db.get(item_id, [])
206
- def find_and_delete(comments_list):
207
- for c in comments_list:
208
- if c["id"] == comment_id:
209
- if c["author"] != author: raise HTTPException(status_code=403, detail="无权删除他人的评论")
210
- c["isDeleted"] = True; c["content"] = ""; return True
211
- if "replies" in c and find_and_delete(c["replies"]): return True
212
- return False
213
- if find_and_delete(item_comments):
214
- db.save_data("comments.json", comments_db)
215
- return {"status": "success"}
216
- raise HTTPException(status_code=404, detail="找不到该评论")
217
-
218
- # --- 4. 专属聊天信箱聚合 (【核心更新】:已读超过7天自动释放) ---
219
- @router.post("/api/messages/private")
220
- async def send_private_message(msg: PrivateMessage):
221
- chats_db = db.load_data("chats.json", default_data={})
222
- conv_id = f"{min(msg.sender, msg.receiver)}_{max(msg.sender, msg.receiver)}"
223
- if conv_id not in chats_db: chats_db[conv_id] = []
224
-
225
- chat_msg = {"id": f"chat_{int(time.time())}_{uuid.uuid4().hex[:6]}", "sender": msg.sender, "receiver": msg.receiver, "content": msg.content, "created_at": int(time.time()), "is_read": False}
226
- chats_db[conv_id].append(chat_msg)
227
- db.save_data("chats.json", chats_db)
228
-
229
- add_notification(msg.receiver, {"type": "private", "from_user": msg.sender, "content": msg.content})
230
- return {"status": "success"}
231
-
232
- @router.get("/api/chats/{account}")
233
- async def get_chat_list(account: str):
234
- chats_db = db.load_data("chats.json", default_data={})
235
- users_db = db.load_data("users.json", default_data={})
236
- chat_list = []
237
- now = int(time.time())
238
- seven_days = 7 * 24 * 3600
239
-
240
- for conv_id, msgs in chats_db.items():
241
- accs = conv_id.split("_")
242
- if account in accs and msgs:
243
- # 列表中只统计有效消息
244
- valid_msgs = [m for m in msgs if not m.get("is_read") or (now - m.get("created_at", 0) < seven_days)]
245
- if valid_msgs:
246
- target = accs[0] if accs[1] == account else accs[1]
247
- target_info = users_db.get(target, {})
248
- chat_list.append({
249
- "target_account": target, "target_name": target_info.get("name", target),
250
- "last_message": valid_msgs[-1]["content"], "last_time": valid_msgs[-1]["created_at"],
251
- "unread": sum(1 for m in valid_msgs if m["receiver"] == account and not m.get("is_read"))
252
- })
253
- chat_list.sort(key=lambda x: x["last_time"], reverse=True)
254
- return {"status": "success", "data": chat_list}
255
-
256
- @router.get("/api/chats/{account}/{target}")
257
- async def get_chat_history(account: str, target: str):
258
- chats_db = db.load_data("chats.json", default_data={})
259
- conv_id = f"{min(account, target)}_{max(account, target)}"
260
- msgs = chats_db.get(conv_id, [])
261
-
262
- now = int(time.time())
263
- seven_days = 7 * 24 * 3600
264
- valid_msgs = []
265
- modified = False
266
-
267
- for m in msgs:
268
- # 【核心策略】:未读的永远保留,已读的超过 7 天直接抛弃
269
- if not m.get("is_read") or (now - m.get("created_at", 0) < seven_days):
270
- valid_msgs.append(m)
271
- else:
272
- modified = True
273
-
274
- # 本次访问即为已读
275
- if m["receiver"] == account and not m.get("is_read"):
276
- m["is_read"] = True
277
- modified = True
278
-
279
- if modified or len(valid_msgs) != len(msgs):
280
- chats_db[conv_id] = valid_msgs
281
- db.save_data("chats.json", chats_db)
282
-
283
- return {"status": "success", "data": valid_msgs}
284
-
285
- @router.get("/api/messages/{account}")
286
- async def get_messages(account: str):
287
- msgs_db = db.load_data("messages.json", default_data={})
288
- user_msgs = msgs_db.get(account, [])
289
-
290
- now = int(time.time())
291
- seven_days = 7 * 24 * 3600
292
- valid = []
293
- modified = False
294
-
295
- for m in user_msgs:
296
- if not m.get("is_read") or (now - m.get("created_at", 0) < seven_days):
297
- valid.append(m)
298
- else:
299
- modified = True
300
-
301
- if modified:
302
- msgs_db[account] = valid
303
- db.save_data("messages.json", msgs_db)
304
-
305
- return {"status": "success", "data": valid, "unread_count": sum(1 for m in valid if not m.get("is_read"))}
306
-
307
- @router.post("/api/messages/{account}/read")
308
- async def mark_messages_read(account: str):
309
- msgs_db = db.load_data("messages.json", default_data={})
310
- user_msgs = msgs_db.get(account, [])
311
- for m in user_msgs: m["is_read"] = True
312
- msgs_db[account] = user_msgs
313
- db.save_data("messages.json", msgs_db)
314
- return {"status": "success"}