"""用户所属俱乐部解析。""" from django.db import IntegrityError from jituan.constants import CLUB_ID_DEFAULT from jituan.models import UserWxOpenid def resolve_invite_party_club(user, request_club_id=None): """ 邀请链校验用:只返回已落库的俱乐部归属。 未归属任何俱乐部时返回 None(勿默认 xq,避免星之界扫码误拦)。 """ if not user: return None explicit = (getattr(user, 'ClubID', None) or '').strip() if explicit: return explicit uid = getattr(user, 'UserUID', None) or getattr(user, 'yonghuid', None) if not uid: return None req = (request_club_id or '').strip() if req: hit = UserWxOpenid.query.filter(yonghuid=uid, club_id=req).first() if hit: return req binding = UserWxOpenid.query.filter(yonghuid=uid).order_by('id').first() if binding: return binding.club_id return None def find_user_by_wx_openid(club_id, openid): """按俱乐部 openid 绑定或 legacy OpenID/UserName 定位用户。""" from users.business_models import User if club_id and openid: binding = UserWxOpenid.query.filter(club_id=club_id, openid=openid).first() if binding: user = User.query.filter(UserUID=binding.yonghuid).first() if not user: user = User.objects.filter(UserUID=binding.yonghuid).first() if user: return user user = User.query.filter(OpenID=openid).first() if not user: user = User.objects.filter(OpenID=openid).first() if not user: user = User.query.filter(UserName=openid).first() if not user: user = User.objects.filter(UserName=openid).first() return user def ensure_wx_openid_binding(club_id, openid, user, unionid=''): if not club_id or not openid or not user: return None uid = getattr(user, 'UserUID', None) if not uid: return None binding = UserWxOpenid.query.filter(club_id=club_id, openid=openid).first() if binding: return binding try: return UserWxOpenid.query.create( club_id=club_id, openid=openid, yonghuid=uid, unionid=unionid or getattr(user, 'UnionID', None) or '', ) except IntegrityError: return UserWxOpenid.query.filter(club_id=club_id, openid=openid).first() def get_user_club_id(user): """ 解析用户归属 club(注册/邀请链隔离用)。 优先级:User.ClubID → user_wx_openid → 默认 xq。 """ if not user: return CLUB_ID_DEFAULT club_id = getattr(user, 'ClubID', None) or getattr(user, 'club_id', None) if club_id: return club_id uid = getattr(user, 'UserUID', None) or getattr(user, 'yonghuid', None) if uid: binding = UserWxOpenid.query.filter(yonghuid=uid).order_by('id').first() if binding: return binding.club_id return CLUB_ID_DEFAULT def ensure_user_club_id(user, club_id): """登录/注册后确保 User.ClubID 与绑定 club 一致。""" if not user or not club_id: return current = getattr(user, 'ClubID', None) if current != club_id and hasattr(user, 'ClubID'): user.ClubID = club_id user.save(update_fields=['ClubID']) def get_wx_openid_for_user(user, club_id=None): """ 按俱乐部取微信支付 JSAPI 用 openid。 多俱乐部用户 openid 在 user_wx_openid;xq 老用户可回落 User.OpenID。 """ if not user: return '' cid = (club_id or '').strip() or get_user_club_id(user) uid = getattr(user, 'UserUID', None) or getattr(user, 'yonghuid', None) if uid and cid: binding = UserWxOpenid.query.filter(yonghuid=uid, club_id=cid).first() if binding and binding.openid: return binding.openid legacy = getattr(user, 'OpenID', None) or getattr(user, 'openid', None) return legacy or '' def get_payment_openid(request, user=None, club_id=None): """下单/充值:按请求俱乐部解析 openid。""" from jituan.services.club_write import resolve_club_id_for_write user = user or getattr(request, 'user', None) cid = club_id or resolve_club_id_for_write(request, user) return get_wx_openid_for_user(user, cid), cid