ZHIWEI666 commited on
Commit
9ef4857
·
verified ·
1 Parent(s): be75899

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +60 -28
app.py CHANGED
@@ -1,4 +1,4 @@
1
- # ⚙️ 后端逻辑/核心服务端.py
2
  from fastapi import FastAPI, HTTPException
3
  from fastapi.middleware.cors import CORSMiddleware
4
  from pydantic import BaseModel
@@ -6,7 +6,7 @@ from typing import Optional
6
  import time
7
  import uuid
8
 
9
- # 导入刚刚写好的数据库操作模块
10
  import 数据库连接 as db
11
 
12
  app = FastAPI(title="ComfyUI Ranking Community API")
@@ -27,7 +27,11 @@ def read_root():
27
 
28
  # --- 数据模型 ---
29
  class UserRegister(BaseModel):
30
- name: str
 
 
 
 
31
  gender: str
32
  avatarDataUrl: Optional[str] = None
33
  age: Optional[int] = None
@@ -35,26 +39,38 @@ class UserRegister(BaseModel):
35
  region: Optional[str] = None
36
  intro: Optional[str] = None
37
 
 
 
 
 
38
  class InteractionToggle(BaseModel):
39
  item_id: str
40
- user_id: str # 使用 name 作为唯一标识 (简化版)
41
  action_type: str # "like", "favorite"
42
  is_active: bool
43
 
44
  class CommentCreate(BaseModel):
45
  item_id: str
46
- author: str
47
  content: str
48
  reply_to_user: Optional[str] = None
49
- parent_id: Optional[str] = None # 如果是回复,记录父评论ID
50
 
51
  # --- 1. 用户系统 ---
52
  @app.post("/api/users/register")
53
  async def register_user(user: UserRegister):
54
  users_db = db.load_data("users.json", default_data={})
55
 
56
- if user.name in users_db:
57
- raise HTTPException(status_code=400, detail="该用户名已被注册")
 
 
 
 
 
 
 
 
58
 
59
  # 构建用户档案,初始化各项统计为 0
60
  new_user = user.dict()
@@ -63,34 +79,57 @@ async def register_user(user: UserRegister):
63
  "privacy": {"follows": False, "likes": False, "favorites": False, "downloads": False}
64
  })
65
 
66
- users_db[user.name] = new_user
67
  db.save_data("users.json", users_db)
68
 
69
- return {"status": "success", "message": "注册成功", "data": new_user}
 
 
70
 
71
- @app.get("/api/users/{username}")
72
- async def get_user_profile(username: str):
73
  users_db = db.load_data("users.json", default_data={})
74
- if username not in users_db:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  raise HTTPException(status_code=404, detail="用户不存在")
76
- return {"status": "success", "data": users_db[username]}
 
 
 
77
 
78
  # --- 2. 排行榜核心数据流 ---
79
  @app.get("/api/items")
80
  async def get_items(type: str = "tool", sort: str = "time", limit: int = 20):
81
  items_db = db.load_data("items.json", default_data=[])
82
 
83
- # 过滤类型
84
  filtered_items = [item for item in items_db if item.get("type") == type]
85
 
86
- # 排序逻辑
87
  if sort == "likes":
88
  filtered_items.sort(key=lambda x: x.get("likes", 0), reverse=True)
89
  elif sort == "favorites":
90
  filtered_items.sort(key=lambda x: x.get("favorites", 0), reverse=True)
91
  elif sort == "downloads":
92
  filtered_items.sort(key=lambda x: x.get("uses", 0), reverse=True)
93
- else: # time (默认)
94
  filtered_items.sort(key=lambda x: x.get("created_at", 0), reverse=True)
95
 
96
  return {"status": "success", "data": filtered_items[:limit]}
@@ -104,8 +143,7 @@ async def toggle_interaction(interaction: InteractionToggle):
104
  if not target_item:
105
  raise HTTPException(status_code=404, detail="目标工具/应用不存在")
106
 
107
- # 确定要操作的列表字段,例如 "liked_by" 或 "favorited_by"
108
- list_key = f"{interaction.action_type}d_by" # liked_by / favorited_by
109
  count_key = "likes" if interaction.action_type == "like" else "favorites"
110
 
111
  if list_key not in target_item:
@@ -114,7 +152,6 @@ async def toggle_interaction(interaction: InteractionToggle):
114
 
115
  user_list = target_item[list_key]
116
 
117
- # 执行 Toggle 逻辑
118
  if interaction.is_active:
119
  if interaction.user_id not in user_list:
120
  user_list.append(interaction.user_id)
@@ -128,15 +165,14 @@ async def toggle_interaction(interaction: InteractionToggle):
128
 
129
  return {
130
  "status": "success",
131
- "message": f"操作成功",
132
  "new_count": target_item[count_key]
133
  }
134
 
135
  # --- 4. 评论系统 ---
136
  @app.post("/api/comments")
137
  async def post_comment(comment: CommentCreate):
138
- comments_db = db.load_data("comments.json", default_data={}) # 结构: {"item_id": [comment_list]}
139
-
140
  item_comments = comments_db.get(comment.item_id, [])
141
 
142
  new_comment = {
@@ -149,7 +185,6 @@ async def post_comment(comment: CommentCreate):
149
  "created_at": int(time.time())
150
  }
151
 
152
- # 如果传了 parent_id,说明是子回复,要把它塞进父评论的 replies 数组里
153
  if comment.parent_id:
154
  parent = next((c for c in item_comments if c["id"] == comment.parent_id), None)
155
  if parent:
@@ -157,7 +192,6 @@ async def post_comment(comment: CommentCreate):
157
  else:
158
  raise HTTPException(status_code=404, detail="找不到要回复的父级评论")
159
  else:
160
- # 否则作为顶级评论插入
161
  item_comments.append(new_comment)
162
 
163
  comments_db[comment.item_id] = item_comments
@@ -170,16 +204,14 @@ async def soft_delete_comment(item_id: str, comment_id: str, author: str):
170
  comments_db = db.load_data("comments.json", default_data={})
171
  item_comments = comments_db.get(item_id, [])
172
 
173
- # 递归查找要删除的评论
174
  def find_and_delete(comments_list):
175
  for c in comments_list:
176
  if c["id"] == comment_id:
177
  if c["author"] != author:
178
  raise HTTPException(status_code=403, detail="无权删除他人的评论")
179
  c["isDeleted"] = True
180
- c["content"] = "" # 清空敏感或不良内容
181
  return True
182
- # 检查子回复
183
  if "replies" in c and find_and_delete(c["replies"]):
184
  return True
185
  return False
 
1
+ # ⚙️ 后端逻辑/核心服务端.py (Hugging Face Spaces app.py)
2
  from fastapi import FastAPI, HTTPException
3
  from fastapi.middleware.cors import CORSMiddleware
4
  from pydantic import BaseModel
 
6
  import time
7
  import uuid
8
 
9
+ # 导入数据库操作模块
10
  import 数据库连接 as db
11
 
12
  app = FastAPI(title="ComfyUI Ranking Community API")
 
27
 
28
  # --- 数据模型 ---
29
  class UserRegister(BaseModel):
30
+ account: str # 唯一账号 (新增为主键)
31
+ password: str # 密码 (新增)
32
+ email: str # 邮箱 (新增)
33
+ phone: str # 手机号 (新增)
34
+ name: str # 显示名称 (昵称)
35
  gender: str
36
  avatarDataUrl: Optional[str] = None
37
  age: Optional[int] = None
 
39
  region: Optional[str] = None
40
  intro: Optional[str] = None
41
 
42
+ class UserLogin(BaseModel):
43
+ account: str # 改为使用 account 登录
44
+ password: str
45
+
46
  class InteractionToggle(BaseModel):
47
  item_id: str
48
+ user_id: str # 使用 account 作为唯一标识
49
  action_type: str # "like", "favorite"
50
  is_active: bool
51
 
52
  class CommentCreate(BaseModel):
53
  item_id: str
54
+ author: str # 存储用户的 account 或 name,建议后续前端统一使用 account 作为关联
55
  content: str
56
  reply_to_user: Optional[str] = None
57
+ parent_id: Optional[str] = None
58
 
59
  # --- 1. 用户系统 ---
60
  @app.post("/api/users/register")
61
  async def register_user(user: UserRegister):
62
  users_db = db.load_data("users.json", default_data={})
63
 
64
+ # 核心修改:通过 account 查重,而不是 name
65
+ if user.account in users_db:
66
+ raise HTTPException(status_code=400, detail="该账号已被注册,请尝试其他账号名")
67
+
68
+ # 额外防重校验:邮箱和手机号不能被多个账号绑定
69
+ for existing_user in users_db.values():
70
+ if existing_user.get("email") == user.email:
71
+ raise HTTPException(status_code=400, detail="该邮箱已被绑定")
72
+ if existing_user.get("phone") == user.phone:
73
+ raise HTTPException(status_code=400, detail="该手机号已被绑定")
74
 
75
  # 构建用户档案,初始化各项统计为 0
76
  new_user = user.dict()
 
79
  "privacy": {"follows": False, "likes": False, "favorites": False, "downloads": False}
80
  })
81
 
82
+ users_db[user.account] = new_user # 使用 account 作为字典的 Key
83
  db.save_data("users.json", users_db)
84
 
85
+ # 返回时为了安全,剔除密码字段
86
+ safe_user_data = {k: v for k, v in new_user.items() if k != "password"}
87
+ return {"status": "success", "message": "注册成功", "data": safe_user_data}
88
 
89
+ @app.post("/api/users/login")
90
+ async def login_user(user: UserLogin):
91
  users_db = db.load_data("users.json", default_data={})
92
+
93
+ if user.account not in users_db:
94
+ raise HTTPException(status_code=404, detail="账号不存在,请检查或先注册")
95
+
96
+ user_data = users_db[user.account]
97
+
98
+ if user_data.get("password") != user.password:
99
+ raise HTTPException(status_code=401, detail="密码错误")
100
+
101
+ return {
102
+ "status": "success",
103
+ "token": f"mock_token_{user.account}", # 模拟生成 token
104
+ "account": user.account,
105
+ "name": user_data["name"],
106
+ "avatar": user_data.get("avatarDataUrl", "https://via.placeholder.com/150")
107
+ }
108
+
109
+ @app.get("/api/users/{account}")
110
+ async def get_user_profile(account: str):
111
+ users_db = db.load_data("users.json", default_data={})
112
+ if account not in users_db:
113
  raise HTTPException(status_code=404, detail="用户不存在")
114
+
115
+ user_data = users_db[account]
116
+ safe_user_data = {k: v for k, v in user_data.items() if k != "password"}
117
+ return {"status": "success", "data": safe_user_data}
118
 
119
  # --- 2. 排行榜核心数据流 ---
120
  @app.get("/api/items")
121
  async def get_items(type: str = "tool", sort: str = "time", limit: int = 20):
122
  items_db = db.load_data("items.json", default_data=[])
123
 
 
124
  filtered_items = [item for item in items_db if item.get("type") == type]
125
 
 
126
  if sort == "likes":
127
  filtered_items.sort(key=lambda x: x.get("likes", 0), reverse=True)
128
  elif sort == "favorites":
129
  filtered_items.sort(key=lambda x: x.get("favorites", 0), reverse=True)
130
  elif sort == "downloads":
131
  filtered_items.sort(key=lambda x: x.get("uses", 0), reverse=True)
132
+ else:
133
  filtered_items.sort(key=lambda x: x.get("created_at", 0), reverse=True)
134
 
135
  return {"status": "success", "data": filtered_items[:limit]}
 
143
  if not target_item:
144
  raise HTTPException(status_code=404, detail="目标工具/应用不存在")
145
 
146
+ list_key = f"{interaction.action_type}d_by"
 
147
  count_key = "likes" if interaction.action_type == "like" else "favorites"
148
 
149
  if list_key not in target_item:
 
152
 
153
  user_list = target_item[list_key]
154
 
 
155
  if interaction.is_active:
156
  if interaction.user_id not in user_list:
157
  user_list.append(interaction.user_id)
 
165
 
166
  return {
167
  "status": "success",
168
+ "message": "操作成功",
169
  "new_count": target_item[count_key]
170
  }
171
 
172
  # --- 4. 评论系统 ---
173
  @app.post("/api/comments")
174
  async def post_comment(comment: CommentCreate):
175
+ comments_db = db.load_data("comments.json", default_data={})
 
176
  item_comments = comments_db.get(comment.item_id, [])
177
 
178
  new_comment = {
 
185
  "created_at": int(time.time())
186
  }
187
 
 
188
  if comment.parent_id:
189
  parent = next((c for c in item_comments if c["id"] == comment.parent_id), None)
190
  if parent:
 
192
  else:
193
  raise HTTPException(status_code=404, detail="找不到要回复的父级评论")
194
  else:
 
195
  item_comments.append(new_comment)
196
 
197
  comments_db[comment.item_id] = item_comments
 
204
  comments_db = db.load_data("comments.json", default_data={})
205
  item_comments = comments_db.get(item_id, [])
206
 
 
207
  def find_and_delete(comments_list):
208
  for c in comments_list:
209
  if c["id"] == comment_id:
210
  if c["author"] != author:
211
  raise HTTPException(status_code=403, detail="无权删除他人的评论")
212
  c["isDeleted"] = True
213
+ c["content"] = ""
214
  return True
 
215
  if "replies" in c and find_and_delete(c["replies"]):
216
  return True
217
  return False