fix(admin): 修复邀请排行榜查询逻辑错误

- 引入SQLAlchemy别名机制区分邀请人和被邀请人表
- 修正JOIN查询中表关联关系避免自关联问题
- 优化GROUP BY子句包含必要的字段确保数据准确性
- 调整查询结构提升代码可读性和维护性
```
This commit is contained in:
24024 2026-01-23 22:09:45 +08:00
parent 2ea495721c
commit a092cdfb4c
2 changed files with 47 additions and 8 deletions

View File

@ -576,15 +576,18 @@ def get_invite_stats():
total_grants = db.session.query(db.func.sum(PointsGrant.points)).scalar() or 0 total_grants = db.session.query(db.func.sum(PointsGrant.points)).scalar() or 0
# 邀请排行榜前10 # 邀请排行榜前10
from sqlalchemy.orm import aliased
Inviter = aliased(User)
Invitee = aliased(User)
top_inviters = db.session.query( top_inviters = db.session.query(
User.id, Inviter.id,
User.phone, Inviter.phone,
db.func.count(User.id).label('invite_count') db.func.count(Invitee.id).label('invite_count')
).join(User, User.invited_by == User.id, isouter=True).filter( ).join(Invitee, Invitee.invited_by == Inviter.id)\
User.invited_by.isnot(None) .group_by(Inviter.id, Inviter.phone)\
).group_by(User.invited_by).order_by( .order_by(db.desc('invite_count'))\
db.desc('invite_count') .limit(10).all()
).limit(10).all()
return jsonify({ return jsonify({
"total_invited": total_invited, "total_invited": total_invited,

36
scripts/reset_user.py Normal file
View File

@ -0,0 +1,36 @@
from app import create_app, db
from models import User, Order, InviteReward
import sys
def reset_user(phone):
app = create_app()
with app.app_context():
user = User.query.filter_by(phone=phone).first()
if not user:
print(f"❌ 找不到用户: {phone}")
return
print(f"🔧 正在重置用户 {phone} (ID: {user.id})...")
# 1. 删除该用户的订单
orders = Order.query.filter_by(user_id=user.id).all()
order_count = len(orders)
for order in orders:
# 删除与该订单关联的邀请奖励(如果存在)
InviteReward.query.filter_by(order_id=order.id).delete()
db.session.delete(order)
# 2. 重置用户积分(可选,方便测试)
# user.points = 2 # 重置为默认赠送积分
# 3. 删除该用户作为邀请人获得的奖励记录 (如果需要彻底重置)
# InviteReward.query.filter_by(inviter_id=user.id).delete()
db.session.commit()
print(f"✅ 已删除 {order_count} 条订单记录,用户重置完成。可以重新测试邀请奖励。")
if __name__ == "__main__":
if len(sys.argv) < 2:
print("使用方法: python scripts/reset_user.py <手机号>")
else:
reset_user(sys.argv[1])