ZHIWEI666 commited on
Commit
2a551ce
·
verified ·
1 Parent(s): 0b38188

Upload 2 files

Browse files
Files changed (2) hide show
  1. router_messages.py +42 -18
  2. router_wallet.py +2 -1
router_messages.py CHANGED
@@ -9,25 +9,31 @@ from models import PrivateMessage
9
 
10
  router = APIRouter()
11
 
12
- # === 用于接收系统公告的请求体模型 ===
13
  class SystemAnnouncement(BaseModel):
14
  admin_account: str
15
  content: str
16
 
17
- # === 发布系统公告接口 (仅限管理员) ===
18
  @router.post("/api/system/announcement")
19
  async def publish_announcement(ann: SystemAnnouncement):
 
20
  if ann.admin_account != "666666":
21
  raise HTTPException(status_code=403, detail="无权发布系统公告")
22
 
23
  announcements_db = db.load_data("announcements.json", default_data=[])
24
 
 
 
 
 
 
25
  new_ann = {
26
  "id": f"sys_{int(time.time())}_{uuid.uuid4().hex[:6]}",
27
  "type": "system",
28
  "from_user": "666666",
29
  "from_name": "官方团队",
30
- "from_avatar": "https://via.placeholder.com/150/FF9800/FFFFFF?text=Sys",
31
  "content": ann.content,
32
  "created_at": int(time.time())
33
  }
@@ -37,6 +43,7 @@ async def publish_announcement(ann: SystemAnnouncement):
37
 
38
  return {"status": "success", "data": new_ann}
39
 
 
40
  @router.post("/api/messages/private")
41
  async def send_private_message(msg: PrivateMessage):
42
  chats_db = db.load_data("chats.json", default_data={})
@@ -90,11 +97,13 @@ async def get_chat_history(account: str, target_account: str):
90
  modified = False
91
 
92
  for m in msgs:
 
93
  if now - m.get("created_at", 0) < seven_days:
94
  valid_msgs.append(m)
95
  else:
96
  modified = True
97
 
 
98
  if m["receiver"] == account and not m.get("is_read"):
99
  m["is_read"] = True
100
  modified = True
@@ -110,29 +119,43 @@ async def get_messages(account: str):
110
  msgs_db = db.load_data("messages.json", default_data={})
111
  user_msgs = msgs_db.get(account, [])
112
 
113
- # --- 系统公告懒加载注入 ---
 
 
 
 
 
 
114
  announcements_db = db.load_data("announcements.json", default_data=[])
115
- user_msg_ids = {m.get("id") for m in user_msgs}
 
 
 
 
116
 
117
  injected = False
118
  for ann in announcements_db:
119
- if ann.get("id") not in user_msg_ids:
120
- new_sys_msg = dict(ann)
 
121
  new_sys_msg["is_read"] = False
122
  new_sys_msg["receiver"] = account
123
  user_msgs.append(new_sys_msg)
124
  injected = True
125
 
126
  if injected:
127
- user_msgs.sort(key=lambda x: x.get("created_at", 0), reverse=True)
128
- # --------------------------
 
129
 
130
  now = int(time.time())
131
  seven_days = 7 * 24 * 3600
132
  valid = []
 
133
  modified = injected
134
 
135
  for m in user_msgs:
 
136
  if not m.get("is_read") or (now - m.get("created_at", 0) < seven_days):
137
  valid.append(m)
138
  else:
@@ -142,7 +165,7 @@ async def get_messages(account: str):
142
  msgs_db[account] = valid
143
  db.save_data("messages.json", msgs_db)
144
 
145
- return {"status": "success", "data": valid, "unread_count": sum(1 for m in valid if not m.get("is_read"))}
146
 
147
  @router.post("/api/messages/{account}/read")
148
  async def mark_messages_read(account: str):
@@ -150,13 +173,14 @@ async def mark_messages_read(account: str):
150
  user_msgs = msgs_db.get(account, [])
151
  modified = False
152
 
153
- for m in user_msgs:
154
- if not m.get("is_read"):
155
- m["is_read"] = True
156
- modified = True
157
-
158
- if modified:
159
- msgs_db[account] = user_msgs
160
- db.save_data("messages.json", msgs_db)
 
161
 
162
  return {"status": "success"}
 
9
 
10
  router = APIRouter()
11
 
12
+ # === 新增:用于接收系统公告的请求体模型 ===
13
  class SystemAnnouncement(BaseModel):
14
  admin_account: str
15
  content: str
16
 
17
+ # === 新增:发布系统公告接口 (仅限管理员) ===
18
  @router.post("/api/system/announcement")
19
  async def publish_announcement(ann: SystemAnnouncement):
20
+ # 鉴权:只有指定的官方账号才能发公告
21
  if ann.admin_account != "666666":
22
  raise HTTPException(status_code=403, detail="无权发布系统公告")
23
 
24
  announcements_db = db.load_data("announcements.json", default_data=[])
25
 
26
+ # 【防御性修复】:确保就算之前存成了别的格式,这里也强制转换为列表,防止 append 报错
27
+ if not isinstance(announcements_db, list):
28
+ announcements_db = []
29
+
30
+ # 构造一条标准的系统公告数据结构
31
  new_ann = {
32
  "id": f"sys_{int(time.time())}_{uuid.uuid4().hex[:6]}",
33
  "type": "system",
34
  "from_user": "666666",
35
  "from_name": "官方团队",
36
+ "from_avatar": "https://via.placeholder.com/150/FF9800/FFFFFF?text=Sys", # 专属的橙色系统头像
37
  "content": ann.content,
38
  "created_at": int(time.time())
39
  }
 
43
 
44
  return {"status": "success", "data": new_ann}
45
 
46
+
47
  @router.post("/api/messages/private")
48
  async def send_private_message(msg: PrivateMessage):
49
  chats_db = db.load_data("chats.json", default_data={})
 
97
  modified = False
98
 
99
  for m in msgs:
100
+ # 聊天记录也遵循 7 天冷数据截断
101
  if now - m.get("created_at", 0) < seven_days:
102
  valid_msgs.append(m)
103
  else:
104
  modified = True
105
 
106
+ # 本次访问即为已读
107
  if m["receiver"] == account and not m.get("is_read"):
108
  m["is_read"] = True
109
  modified = True
 
119
  msgs_db = db.load_data("messages.json", default_data={})
120
  user_msgs = msgs_db.get(account, [])
121
 
122
+ # 【防御性修复】:确保 user_msgs 是列表
123
+ if not isinstance(user_msgs, list):
124
+ user_msgs = []
125
+
126
+ # =========================================================
127
+ # 系统公告懒加载注入逻辑 (Lazy Push)
128
+ # =========================================================
129
  announcements_db = db.load_data("announcements.json", default_data=[])
130
+ if not isinstance(announcements_db, list):
131
+ announcements_db = []
132
+
133
+ # 获取用户已经拥有的消息 ID 集合,用于快速比对(加入防脏数据判断)
134
+ user_msg_ids = {m.get("id") for m in user_msgs if isinstance(m, dict)}
135
 
136
  injected = False
137
  for ann in announcements_db:
138
+ if isinstance(ann, dict) and ann.get("id") not in user_msg_ids:
139
+ # 如果是新公告,构造一条个人消息注入进去
140
+ new_sys_msg = dict(ann) # 浅拷贝,防止修改全局数据
141
  new_sys_msg["is_read"] = False
142
  new_sys_msg["receiver"] = account
143
  user_msgs.append(new_sys_msg)
144
  injected = True
145
 
146
  if injected:
147
+ # 如果注入了新公告,按照时间重新倒序排列,确保最新的消息/公告在最上面
148
+ user_msgs.sort(key=lambda x: x.get("created_at", 0) if isinstance(x, dict) else 0, reverse=True)
149
+ # =========================================================
150
 
151
  now = int(time.time())
152
  seven_days = 7 * 24 * 3600
153
  valid = []
154
+ # 如果刚才注入了新公告,说明用户的消息列表被修改了,必须触发保存
155
  modified = injected
156
 
157
  for m in user_msgs:
158
+ if not isinstance(m, dict): continue
159
  if not m.get("is_read") or (now - m.get("created_at", 0) < seven_days):
160
  valid.append(m)
161
  else:
 
165
  msgs_db[account] = valid
166
  db.save_data("messages.json", msgs_db)
167
 
168
+ return {"status": "success", "data": valid, "unread_count": sum(1 for m in valid if m.get("is_read") is False)}
169
 
170
  @router.post("/api/messages/{account}/read")
171
  async def mark_messages_read(account: str):
 
173
  user_msgs = msgs_db.get(account, [])
174
  modified = False
175
 
176
+ if isinstance(user_msgs, list):
177
+ for m in user_msgs:
178
+ if isinstance(m, dict) and not m.get("is_read"):
179
+ m["is_read"] = True
180
+ modified = True
181
+
182
+ if modified:
183
+ msgs_db[account] = user_msgs
184
+ db.save_data("messages.json", msgs_db)
185
 
186
  return {"status": "success"}
router_wallet.py CHANGED
@@ -1,5 +1,6 @@
1
  # router_wallet.py
2
  from fastapi import APIRouter, Depends, HTTPException, Request
 
3
  from sqlalchemy.orm import Session
4
  import time
5
  import uuid
@@ -104,7 +105,7 @@ async def tip_user(req: TipRequest, db: Session = Depends(get_db)):
104
 
105
  @router.post("/api/wallet/withdraw")
106
  async def submit_withdraw(req: WithdrawRequest, db: Session = Depends(get_db)):
107
- # 1. 验证码校验(若想关闭风控测试,可注释掉此处)
108
  verify_data = VERIFY_CODES.get(req.account)
109
  if not verify_data or verify_data["code"] != req.code or verify_data["action"] != "withdraw":
110
  raise HTTPException(status_code=400, detail="验证码无效或已过期")
 
1
  # router_wallet.py
2
  from fastapi import APIRouter, Depends, HTTPException, Request
3
+ from fastapi.responses import Response # 【必须导入的模块,否则支付宝回调报 500】
4
  from sqlalchemy.orm import Session
5
  import time
6
  import uuid
 
105
 
106
  @router.post("/api/wallet/withdraw")
107
  async def submit_withdraw(req: WithdrawRequest, db: Session = Depends(get_db)):
108
+ # 1. 验证码校验
109
  verify_data = VERIFY_CODES.get(req.account)
110
  if not verify_data or verify_data["code"] != req.code or verify_data["action"] != "withdraw":
111
  raise HTTPException(status_code=400, detail="验证码无效或已过期")