ZHIWEI666 commited on
Commit
027a973
·
verified ·
1 Parent(s): 1774480

Upload 3 files

Browse files
Files changed (3) hide show
  1. models.py +3 -3
  2. models_sql.py +1 -1
  3. router_wallet.py +41 -7
models.py CHANGED
@@ -1,5 +1,5 @@
1
  # models.py
2
- from pydantic import BaseModel, validator
3
  from typing import Optional, List
4
 
5
  class SendCodeRequest(BaseModel):
@@ -118,7 +118,7 @@ class RatingRequest(BaseModel):
118
 
119
  class RechargeRequest(BaseModel):
120
  account: str
121
- amount: int
122
  method: Optional[str] = "alipay"
123
 
124
  class PurchaseRequest(BaseModel):
@@ -134,7 +134,7 @@ class TipRequest(BaseModel):
134
 
135
  class WithdrawRequest(BaseModel):
136
  account: str
137
- amount: int
138
  alipayAccount: str
139
  real_name: str
140
  code: str
 
1
  # models.py
2
+ from pydantic import BaseModel, Field, validator
3
  from typing import Optional, List
4
 
5
  class SendCodeRequest(BaseModel):
 
118
 
119
  class RechargeRequest(BaseModel):
120
  account: str
121
+ amount: int = Field(..., ge=1, le=10000) # 单次充值1-10000
122
  method: Optional[str] = "alipay"
123
 
124
  class PurchaseRequest(BaseModel):
 
134
 
135
  class WithdrawRequest(BaseModel):
136
  account: str
137
+ amount: int = Field(..., ge=1, le=5000) # 单次提现1-5000
138
  alipayAccount: str
139
  real_name: str
140
  code: str
models_sql.py CHANGED
@@ -61,7 +61,7 @@ class Transaction(Base):
61
 
62
  tx_id = Column(String, primary_key=True)
63
  account = Column(String, index=True)
64
- tx_type = Column(String) # 枚举: RECHARGE, PURCHASE, EARN, TIP_SEND, TIP_RECEIVE, WITHDRAW_APPLY, REFUND
65
  amount = Column(Integer)
66
  related_account = Column(String, nullable=True)
67
  item_id = Column(String, nullable=True)
 
61
 
62
  tx_id = Column(String, primary_key=True)
63
  account = Column(String, index=True)
64
+ tx_type = Column(String) # 枚举: RECHARGE, PURCHASE, SALE, TIP_OUT, TIP_IN, WITHDRAW, WITHDRAW_FEE, REFUND, TASK_FREEZE, TASK_DEPOSIT, TASK_PAYMENT, TASK_INCOME, TASK_REFUND, TASK_CANCEL_REFUND
65
  amount = Column(Integer)
66
  related_account = Column(String, nullable=True)
67
  item_id = Column(String, nullable=True)
router_wallet.py CHANGED
@@ -124,13 +124,15 @@ def calculate_tx_hash(tx_id, account, tx_type, amount, prev_hash):
124
  return hashlib.sha256(data.encode()).hexdigest()
125
 
126
  @router.post("/api/wallet/create_recharge_order")
127
- async def create_recharge_order(req: RechargeRequest):
128
  if not alipay:
129
  # 这里会将真实的错误原因直接弹窗发给前端!
130
  raise HTTPException(status_code=500, detail=f"支付网关配置错误: {alipay_error_msg}")
131
 
 
 
132
  order_id = f"PAY_{int(time.time())}_{uuid.uuid4().hex[:6]}"
133
- subject = f"ComfyUI Community Points - {req.account}"
134
 
135
  order_string = alipay.api_alipay_trade_precreate(
136
  out_trade_no=order_id,
@@ -270,7 +272,9 @@ async def get_wallet(account: str, db: Session = Depends(get_db)):
270
 
271
  @router.post("/api/wallet/purchase")
272
  @limiter.limit("10/minute") # 🔒 P0安全优化:购买每分钟最多10次
273
- async def purchase_item(request: Request, req: PurchaseRequest, db: Session = Depends(get_db)):
 
 
274
  items_db = json_db.load_data("items.json", default_data=[])
275
  item = next((i for i in items_db if i["id"] == req.item_id), None)
276
 
@@ -381,6 +385,24 @@ async def purchase_item(request: Request, req: PurchaseRequest, db: Session = De
381
  related_user_name=seller_user_name
382
  )
383
  db.add(new_tx)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
384
  db.commit()
385
 
386
  # 📝 P2优化:购买审计日志
@@ -413,7 +435,9 @@ async def purchase_item(request: Request, req: PurchaseRequest, db: Session = De
413
 
414
  @router.post("/api/wallet/tip")
415
  @limiter.limit("20/minute") # 🔒 P0安全优化:打赏每分钟最多20次
416
- async def tip_user(request: Request, req: TipRequest, db: Session = Depends(get_db)):
 
 
417
  if req.amount <= 0:
418
  raise HTTPException(status_code=400, detail="打赏金额必须大于0")
419
  if req.sender_account == req.target_account:
@@ -568,7 +592,9 @@ async def tip_user(request: Request, req: TipRequest, db: Session = Depends(get_
568
 
569
  @router.post("/api/wallet/withdraw")
570
  @limiter.limit("3/minute") # 🔒 P0安全优化:提现每分钟最多3次
571
- async def withdraw(request: Request, req: WithdrawRequest, db: Session = Depends(get_db)):
 
 
572
  # 🔒 P1幂等性防护:检查最近10秒内是否存在相同提现请求
573
  recent_cutoff = datetime.datetime.utcnow() - datetime.timedelta(seconds=10)
574
  duplicate_tx = db.query(Transaction).filter(
@@ -882,6 +908,12 @@ async def get_sales_stats(account: str, db: Session = Depends(get_db)):
882
  total_purchase = abs(purchase_stats.total or 0)
883
  purchase_count = purchase_stats.count or 0
884
 
 
 
 
 
 
 
885
  # 净销售 = 销售收入 - 购买支出
886
  net_sales = total_sales - total_purchase
887
 
@@ -889,7 +921,7 @@ async def get_sales_stats(account: str, db: Session = Depends(get_db)):
889
  "status": "success",
890
  "data": {
891
  "total_sales": total_sales,
892
- "sales_count": 0, # 目前无法精确统计销售笔数(没有卖家交易记录)
893
  "total_purchase": total_purchase,
894
  "purchase_count": purchase_count,
895
  "net_sales": net_sales
@@ -974,7 +1006,9 @@ async def get_purchase_status(account: str, item_id: str, db: Session = Depends(
974
 
975
  @router.post("/api/wallet/refund")
976
  @limiter.limit("3/minute") # 🔒 P0安全优化:退款每分钟最多3次
977
- async def refund_purchase(request: Request, account: str, item_id: str, db: Session = Depends(get_db)):
 
 
978
  """
979
  🔄 P7后悔模式:申请退款
980
  - 24小时内可退款
 
124
  return hashlib.sha256(data.encode()).hexdigest()
125
 
126
  @router.post("/api/wallet/create_recharge_order")
127
+ async def create_recharge_order(req: RechargeRequest, current_user: str = Depends(require_auth)):
128
  if not alipay:
129
  # 这里会将真实的错误原因直接弹窗发给前端!
130
  raise HTTPException(status_code=500, detail=f"支付网关配置错误: {alipay_error_msg}")
131
 
132
+ # 🔒 使用已认证用户账号,忽略客户端传入的 account
133
+ authenticated_account = current_user
134
  order_id = f"PAY_{int(time.time())}_{uuid.uuid4().hex[:6]}"
135
+ subject = f"ComfyUI Community Points - {authenticated_account}"
136
 
137
  order_string = alipay.api_alipay_trade_precreate(
138
  out_trade_no=order_id,
 
272
 
273
  @router.post("/api/wallet/purchase")
274
  @limiter.limit("10/minute") # 🔒 P0安全优化:购买每分钟最多10次
275
+ async def purchase_item(request: Request, req: PurchaseRequest, current_user: str = Depends(require_auth), db: Session = Depends(get_db)):
276
+ # 🔒 使用已认证用户账号,忽略客户端传入的 account
277
+ req.account = current_user
278
  items_db = json_db.load_data("items.json", default_data=[])
279
  item = next((i for i in items_db if i["id"] == req.item_id), None)
280
 
 
385
  related_user_name=seller_user_name
386
  )
387
  db.add(new_tx)
388
+
389
+ # 为卖家生成销售收入记录
390
+ buyer_info = users_db.get(req.account, {})
391
+ buyer_user_name = buyer_info.get("name", req.account)
392
+ seller_tx_id = f"SALE_{int(time.time())}_{uuid.uuid4().hex[:6]}"
393
+ seller_tx = Transaction(
394
+ tx_id=seller_tx_id,
395
+ account=seller_account,
396
+ tx_type="SALE",
397
+ amount=price,
398
+ related_account=req.account,
399
+ item_id=req.item_id,
400
+ item_title=item.get('title', ''),
401
+ item_type=item.get('type', ''),
402
+ related_user_name=buyer_user_name,
403
+ description=f"销售收入: {item.get('title', req.item_id)}"
404
+ )
405
+ db.add(seller_tx)
406
  db.commit()
407
 
408
  # 📝 P2优化:购买审计日志
 
435
 
436
  @router.post("/api/wallet/tip")
437
  @limiter.limit("20/minute") # 🔒 P0安全优化:打赏每分钟最多20次
438
+ async def tip_user(request: Request, req: TipRequest, current_user: str = Depends(require_auth), db: Session = Depends(get_db)):
439
+ # 🔒 使用已认证用户账号,忽略客户端传入的 sender_account
440
+ req.sender_account = current_user
441
  if req.amount <= 0:
442
  raise HTTPException(status_code=400, detail="打赏金额必须大于0")
443
  if req.sender_account == req.target_account:
 
592
 
593
  @router.post("/api/wallet/withdraw")
594
  @limiter.limit("3/minute") # 🔒 P0安全优化:提现每分钟最多3次
595
+ async def withdraw(request: Request, req: WithdrawRequest, current_user: str = Depends(require_auth), db: Session = Depends(get_db)):
596
+ # 🔒 使用已认证用户账号,忽略客户端传入的 account
597
+ req.account = current_user
598
  # 🔒 P1幂等性防护:检查最近10秒内是否存在相同提现请求
599
  recent_cutoff = datetime.datetime.utcnow() - datetime.timedelta(seconds=10)
600
  duplicate_tx = db.query(Transaction).filter(
 
908
  total_purchase = abs(purchase_stats.total or 0)
909
  purchase_count = purchase_stats.count or 0
910
 
911
+ # 统计销售笔数(SALE类型交易记录)
912
+ sales_count = db.query(sql_func.count(Transaction.tx_id)).filter(
913
+ Transaction.account == account,
914
+ Transaction.tx_type == "SALE"
915
+ ).scalar() or 0
916
+
917
  # 净销售 = 销售收入 - 购买支出
918
  net_sales = total_sales - total_purchase
919
 
 
921
  "status": "success",
922
  "data": {
923
  "total_sales": total_sales,
924
+ "sales_count": sales_count,
925
  "total_purchase": total_purchase,
926
  "purchase_count": purchase_count,
927
  "net_sales": net_sales
 
1006
 
1007
  @router.post("/api/wallet/refund")
1008
  @limiter.limit("3/minute") # 🔒 P0安全优化:退款每分钟最多3次
1009
+ async def refund_purchase(request: Request, item_id: str, current_user: str = Depends(require_auth), db: Session = Depends(get_db)):
1010
+ # 🔒 使用已认证用户账号,忽略客户端传入的 account
1011
+ account = current_user
1012
  """
1013
  🔄 P7后悔模式:申请退款
1014
  - 24小时内可退款