"""俱乐部微信登录(多 openid 绑定,不修改旧 wechatlogin 逻辑)。""" import logging import random import time import uuid from django.db import transaction from django.utils import timezone from rest_framework_simplejwt.tokens import RefreshToken from jituan.constants import CLUB_ID_DEFAULT from jituan.models import UserWxOpenid from jituan.services.club_resolver import jscode2session, resolve_club_by_appid from jituan.services.club_user import ( ensure_user_club_id, ensure_wx_openid_binding, find_user_by_wx_openid, resolve_or_create_wx_user, ) from users.business_models import User from users.models import UserBoss, UserDashou, UserGuanshi, UserShangjia, UserZuzhang, UserShenheguan from gvsdsdk.models import Role logger = logging.getLogger(__name__) def _generate_user_uid(): for _ in range(10): timestamp_part = str(int(time.time()))[-5:].zfill(5) random_part = str(random.randint(0, 99)).zfill(2) user_id = timestamp_part + random_part if len(user_id) == 7 and user_id.isdigit(): if not User.query.filter(UserUID=user_id).exists(): return user_id raise RuntimeError('生成用户ID失败') def _ensure_boss_profile(user): try: UserBoss.query.get(user=user) except UserBoss.DoesNotExist: UserBoss.query.create(user=user, nickname='板板大人') def _ensure_consumer_role(user): from users.business_models import UserRole as BizUserRole normal_role = Role.objects.filter(RoleName='消费者').first() if not normal_role: return exists = BizUserRole.objects.filter(UserUUID=user.UserUUID, RoleUUID=normal_role.RoleUUID).exists() if not exists: BizUserRole.objects.create( UserRoleUUID=uuid.uuid4().bytes, UserUUID=user.UserUUID, RoleUUID=normal_role.RoleUUID, CompanyUUID=uuid.UUID('b0000000-0000-0000-0000-000000000001').bytes, ) def _collect_role_status(user): dashou_status = None shangjia_status = None guanshi_status = None zuzhang_status = None kaoheguan_status = 0 boss_nickname = '微信用户' try: boss = UserBoss.query.get(user=user) boss_nickname = boss.nickname or '微信用户' except UserBoss.DoesNotExist: pass try: UserDashou.query.get(user=user) dashou_status = 1 except UserDashou.DoesNotExist: dashou_status = None try: UserShangjia.query.get(user=user) shangjia_status = 1 except UserShangjia.DoesNotExist: shangjia_status = None try: UserGuanshi.query.get(user=user) guanshi_status = 1 except UserGuanshi.DoesNotExist: guanshi_status = None try: UserZuzhang.query.get(user=user) zuzhang_status = 1 except UserZuzhang.DoesNotExist: zuzhang_status = None try: kg = UserShenheguan.query.get(user=user) kaoheguan_status = 1 if kg.zhuangtai == 1 else 0 except UserShenheguan.DoesNotExist: kaoheguan_status = 0 return { 'dashou_status': dashou_status, 'shangjia_status': shangjia_status, 'guanshi_status': guanshi_status, 'zuzhang_status': zuzhang_status, 'kaoheguan_status': kaoheguan_status, 'boss_nickname': boss_nickname, } def login_or_register_by_club(code, club_id=None, app_id=None, client_ip=''): """ 俱乐部微信登录核心逻辑。 - 通过 user_wx_openid(club_id, openid) 定位用户 - xq 俱乐部兼容:若绑定不存在但 User.OpenID 已存在,则自动建绑定(不新建用户) """ wx_data = jscode2session(code, club_id=club_id, app_id=app_id) if not wx_data or 'openid' not in wx_data: return None, wx_data.get('errmsg', '微信授权失败') openid = wx_data['openid'] unionid = wx_data.get('unionid', '') resolved_club_id = wx_data.get('club_id') or club_id or CLUB_ID_DEFAULT with transaction.atomic(): binding = UserWxOpenid.query.filter( club_id=resolved_club_id, openid=openid ).first() user = None created = False if binding: user = User.query.filter(UserUID=binding.yonghuid).first() if not user: user = User.objects.filter(UserUID=binding.yonghuid).first() if not user: user, created = resolve_or_create_wx_user( resolved_club_id, openid, _generate_user_uid, unionid=unionid, ) if created: _ensure_boss_profile(user) _ensure_consumer_role(user) else: ensure_wx_openid_binding(resolved_club_id, openid, user, unionid) if unionid and unionid != (user.UnionID or ''): user.UnionID = unionid if client_ip: user.IP = client_ip user.UserLastLoginDate = timezone.now() user.save() ensure_user_club_id(user, resolved_club_id) roles = _collect_role_status(user) refresh = RefreshToken.for_user(user) token = str(refresh.access_token) from merchant_ops.services.authz import staff_fields_for_login from users.views import WechatMiniProgramLoginView staff_fields = staff_fields_for_login(user) login_view = WechatMiniProgramLoginView() order_counts = login_view.jisuanOrderShuliang(user.UserUID) group_info = login_view.huoquQunPeizhi() data = { 'token': token, 'nicheng': roles['boss_nickname'], 'uid': user.UserUID, 'touxiang': user.Avatar or '', 'shangjiastatus': roles['shangjia_status'], 'dashoustatus': roles['dashou_status'], 'guanshistatus': roles['guanshi_status'], 'zuzhangstatus': roles['zuzhang_status'], 'kaoheguanstatus': roles['kaoheguan_status'], 'dingdantiaoshu': order_counts, 'dashouqun': group_info.get('dashouqun', ''), 'dashouqunid': group_info.get('dashouqunid', ''), 'guanshiqun': group_info.get('guanshiqun', ''), 'guanshiqunid': group_info.get('guanshiqunid', ''), 'club_id': resolved_club_id, 'is_new_user': created, **staff_fields, } return data, None