ZHIWEI666 commited on
Commit
0d68604
·
verified ·
1 Parent(s): 9abcb51

优化流水记录

Browse files
Files changed (2) hide show
  1. models_sql.py +7 -0
  2. router_wallet.py +75 -1
models_sql.py CHANGED
@@ -68,6 +68,13 @@ class Transaction(Base):
68
  prev_hash = Column(String) # 上一笔订单的哈希
69
  tx_hash = Column(String) # 本笔订单的哈希 (防篡改)
70
 
 
 
 
 
 
 
 
71
  # 🚀 P1性能优化:复合索引
72
  __table_args__ = (
73
  Index('ix_transactions_account_type', 'account', 'tx_type'),
 
68
  prev_hash = Column(String) # 上一笔订单的哈希
69
  tx_hash = Column(String) # 本笔订单的哈希 (防篡改)
70
 
71
+ # 💰 提现相关字段 (仅 WITHDRAW_APPLY 类型交易使用)
72
+ alipay_account = Column(String, nullable=True) # 收款支付宝账号
73
+ real_name = Column(String, nullable=True) # 收款人姓名
74
+ withdraw_status = Column(String, nullable=True) # pending / completed
75
+ payment_order_id = Column(String, nullable=True) # 管理员填写的打款订单号
76
+ net_amount = Column(Integer, nullable=True) # 实际到账金额(用于解冻时准确扣减)
77
+
78
  # 🚀 P1性能优化:复合索引
79
  __table_args__ = (
80
  Index('ix_transactions_account_type', 'account', 'tx_type'),
router_wallet.py CHANGED
@@ -13,6 +13,7 @@
13
  from fastapi import APIRouter, Depends, HTTPException, Request
14
  from fastapi.responses import Response
15
  from sqlalchemy.orm import Session
 
16
  import time
17
  import uuid
18
  import hashlib
@@ -24,6 +25,7 @@ from models_sql import Wallet, Transaction, Ownership, Refund
24
  from models import RechargeRequest, WithdrawRequest, PurchaseRequest, TipRequest
25
  import 数据库连接 as json_db
26
  from notifications import add_notification
 
27
 
28
  # 🔒 P0安全优化:API限流
29
  from slowapi import Limiter
@@ -536,6 +538,10 @@ async def withdraw(request: Request, req: WithdrawRequest, db: Session = Depends
536
 
537
  new_tx = Transaction(
538
  tx_id=tx_id, account=req.account, tx_type="WITHDRAW", amount=-actual_withdraw,
 
 
 
 
539
  prev_hash=prev_hash, tx_hash=tx_hash
540
  )
541
  db.add(new_tx)
@@ -859,4 +865,72 @@ async def refund_purchase(request: Request, account: str, item_id: str, db: Sess
859
  except Exception as e:
860
  db.rollback()
861
  logger.error(f"REFUND_ERROR | buyer={account} | item={item_id} | amount={refund_amount} | error={str(e)}")
862
- raise HTTPException(status_code=500, detail="退款处理失败,请稍后重试")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  from fastapi import APIRouter, Depends, HTTPException, Request
14
  from fastapi.responses import Response
15
  from sqlalchemy.orm import Session
16
+ from pydantic import BaseModel
17
  import time
18
  import uuid
19
  import hashlib
 
25
  from models import RechargeRequest, WithdrawRequest, PurchaseRequest, TipRequest
26
  import 数据库连接 as json_db
27
  from notifications import add_notification
28
+ from 安全认证 import require_auth, is_admin
29
 
30
  # 🔒 P0安全优化:API限流
31
  from slowapi import Limiter
 
538
 
539
  new_tx = Transaction(
540
  tx_id=tx_id, account=req.account, tx_type="WITHDRAW", amount=-actual_withdraw,
541
+ alipay_account=req.alipayAccount,
542
+ real_name=req.real_name,
543
+ withdraw_status="pending",
544
+ net_amount=net_amount, # 记录实际到账金额,用于解冻时准确扣减
545
  prev_hash=prev_hash, tx_hash=tx_hash
546
  )
547
  db.add(new_tx)
 
865
  except Exception as e:
866
  db.rollback()
867
  logger.error(f"REFUND_ERROR | buyer={account} | item={item_id} | amount={refund_amount} | error={str(e)}")
868
+ raise HTTPException(status_code=500, detail="退款处理失败,请稍后重试")
869
+
870
+ # ==========================================
871
+ # 💰 管理员提现管理 API
872
+ # ==========================================
873
+
874
+ @router.get("/api/admin/withdrawals")
875
+ async def get_admin_withdrawals(
876
+ status: str = None,
877
+ current_user: str = Depends(require_auth),
878
+ db: Session = Depends(get_db)
879
+ ):
880
+ """管理员查看提现记录列表"""
881
+ if not is_admin(current_user):
882
+ raise HTTPException(status_code=403, detail="需要管理员权限")
883
+
884
+ query = db.query(Transaction).filter(Transaction.tx_type == "WITHDRAW")
885
+ if status:
886
+ query = query.filter(Transaction.withdraw_status == status)
887
+
888
+ records = query.order_by(Transaction.created_at.desc()).all()
889
+
890
+ return {
891
+ "status": "success",
892
+ "data": [{
893
+ "tx_id": r.tx_id,
894
+ "account": r.account,
895
+ "amount": r.amount,
896
+ "alipay_account": r.alipay_account,
897
+ "real_name": r.real_name,
898
+ "withdraw_status": r.withdraw_status,
899
+ "payment_order_id": r.payment_order_id,
900
+ "created_at": r.created_at.isoformat() if r.created_at else None
901
+ } for r in records]
902
+ }
903
+
904
+ class CompleteWithdrawRequest(BaseModel):
905
+ payment_order_id: str
906
+
907
+ @router.post("/api/admin/withdrawals/{tx_id}/complete")
908
+ async def complete_withdrawal(
909
+ tx_id: str,
910
+ req: CompleteWithdrawRequest,
911
+ current_user: str = Depends(require_auth),
912
+ db: Session = Depends(get_db)
913
+ ):
914
+ """管理员确认打款完成"""
915
+ if not is_admin(current_user):
916
+ raise HTTPException(status_code=403, detail="需要管理员权限")
917
+
918
+ tx = db.query(Transaction).filter(Transaction.tx_id == tx_id, Transaction.tx_type == "WITHDRAW").first()
919
+ if not tx:
920
+ raise HTTPException(status_code=404, detail="提现记录不存在")
921
+ if tx.withdraw_status == "completed":
922
+ raise HTTPException(status_code=400, detail="该提现已完成打款")
923
+
924
+ # 更新提现状态
925
+ tx.withdraw_status = "completed"
926
+ tx.payment_order_id = req.payment_order_id
927
+
928
+ # 解冻余额(使用 net_amount 字段,确保解冻金额与冻结时一致)
929
+ wallet = db.query(Wallet).filter(Wallet.account == tx.account).first()
930
+ if wallet:
931
+ net_amount = tx.net_amount if tx.net_amount is not None else abs(tx.amount) # 优先使用 net_amount,兼容旧数据
932
+ wallet.frozen_balance = max(0, wallet.frozen_balance - net_amount)
933
+
934
+ db.commit()
935
+
936
+ return {"status": "success", "message": f"提现 {tx_id} 已确认打款完成"}