From a092cdfb4cdc41529899859ef27c6ab79fbba00b Mon Sep 17 00:00:00 2001 From: 24024 <240241002@qq.com> Date: Fri, 23 Jan 2026 22:09:45 +0800 Subject: [PATCH] =?UTF-8?q?```=20fix(admin):=20=E4=BF=AE=E5=A4=8D=E9=82=80?= =?UTF-8?q?=E8=AF=B7=E6=8E=92=E8=A1=8C=E6=A6=9C=E6=9F=A5=E8=AF=A2=E9=80=BB?= =?UTF-8?q?=E8=BE=91=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 引入SQLAlchemy别名机制区分邀请人和被邀请人表 - 修正JOIN查询中表关联关系避免自关联问题 - 优化GROUP BY子句包含必要的字段确保数据准确性 - 调整查询结构提升代码可读性和维护性 ``` --- blueprints/admin.py | 19 +++++++++++-------- scripts/reset_user.py | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 8 deletions(-) create mode 100644 scripts/reset_user.py diff --git a/blueprints/admin.py b/blueprints/admin.py index 5ad601f..4b372b1 100644 --- a/blueprints/admin.py +++ b/blueprints/admin.py @@ -576,15 +576,18 @@ def get_invite_stats(): total_grants = db.session.query(db.func.sum(PointsGrant.points)).scalar() or 0 # 邀请排行榜(前10) + from sqlalchemy.orm import aliased + Inviter = aliased(User) + Invitee = aliased(User) + top_inviters = db.session.query( - User.id, - User.phone, - db.func.count(User.id).label('invite_count') - ).join(User, User.invited_by == User.id, isouter=True).filter( - User.invited_by.isnot(None) - ).group_by(User.invited_by).order_by( - db.desc('invite_count') - ).limit(10).all() + Inviter.id, + Inviter.phone, + db.func.count(Invitee.id).label('invite_count') + ).join(Invitee, Invitee.invited_by == Inviter.id)\ + .group_by(Inviter.id, Inviter.phone)\ + .order_by(db.desc('invite_count'))\ + .limit(10).all() return jsonify({ "total_invited": total_invited, diff --git a/scripts/reset_user.py b/scripts/reset_user.py new file mode 100644 index 0000000..2f81a0f --- /dev/null +++ b/scripts/reset_user.py @@ -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])