Files
Django/jituan/services/wechat_login.py

210 lines
6.8 KiB
Python

"""俱乐部微信登录(多 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 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 and resolved_club_id == CLUB_ID_DEFAULT:
user = User.query.filter(OpenID=openid).first()
if not user:
user = User.objects.filter(OpenID=openid).first()
if user:
UserWxOpenid.query.create(
club_id=resolved_club_id,
openid=openid,
yonghuid=user.UserUID,
unionid=unionid or user.UnionID,
)
if not user:
user_uuid = uuid.uuid4().bytes
new_uid = _generate_user_uid()
user = User(
UserUUID=user_uuid,
UserUID=new_uid,
UserName=openid,
OpenID=openid if resolved_club_id == CLUB_ID_DEFAULT else None,
UnionID=unionid or None,
)
user.save()
created = True
_ensure_boss_profile(user)
_ensure_consumer_role(user)
UserWxOpenid.query.create(
club_id=resolved_club_id,
openid=openid,
yonghuid=user.UserUID,
unionid=unionid,
)
if unionid and unionid != (user.UnionID or ''):
user.UnionID = unionid
if client_ip:
user.IP = client_ip
user.UserLastLoginDate = timezone.now()
user.save()
from jituan.services.club_user import ensure_user_club_id
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