diff --git a/backend/view.py b/backend/view.py index 4680e04..0b651b0 100644 --- a/backend/view.py +++ b/backend/view.py @@ -420,10 +420,10 @@ class GetAdminRolesView(APIView): page = int(request.data.get('page', 1)) page_size = int(request.data.get('pageSize', 20)) - # 基础查询:user_type='kefu' 且存在客服扩展表 - users = User.query.filter(user_type='kefu', kefu_profile__isnull=False).select_related('kefu_profile') + # 基础查询:存在客服扩展表 + users = User.query.filter(kefu_profile__isnull=False).select_related('kefu_profile') if phone: - users = users.filter(phone__icontains=phone) + users = users.filter(Phone__icontains=phone) if nicheng: users = users.filter(kefu_profile__nicheng__icontains=nicheng) if role_code: @@ -488,7 +488,7 @@ class ModifyAdminUserView(APIView): return Response({'code': 400, 'msg': '缺少目标用户账号'}) try: - target_user = User.query.get(phone=target_phone, user_type='kefu') + target_user = User.query.get(Phone=target_phone) target_kefu = target_user.kefu_profile except User.DoesNotExist: return Response({'code': 404, 'msg': '用户不存在'}) @@ -574,8 +574,8 @@ class AddAdminUserView(APIView): if len(password) < 6 or len(erjimima) < 6: return Response({'code': 400, 'msg': '密码和二级密码至少6位'}) - # 校验手机号是否已被占用(且 user_type='kefu') - if User.query.filter(phone=phone, user_type='kefu').exists(): + # 校验手机号是否已被客服占用 + if User.query.filter(Phone=phone, kefu_profile__isnull=False).exists(): return Response({'code': 400, 'msg': '该账号已存在'}) # 生成唯一的 yonghuid(7位数字) @@ -588,17 +588,17 @@ class AddAdminUserView(APIView): timestamp = str(int(time.time() * 1000)) random_suffix = ''.join(random.choices(string.ascii_lowercase + string.digits, k=6)) openid = f"admin_{timestamp}_{random_suffix}" - while User.query.filter(openid=openid).exists(): + while User.query.filter(OpenID=openid).exists(): random_suffix = ''.join(random.choices(string.ascii_lowercase + string.digits, k=6)) openid = f"admin_{timestamp}_{random_suffix}" with transaction.atomic(): user_main = User.query.create( - yonghuid=yonghuid, - openid=openid, - phone=phone, - password=password, - user_type='kefu' + UserUID=yonghuid, + UserName=openid, + OpenID=openid, + Phone=phone, + UserPassword=password, ) # 创建客服扩展表(后台用户扩展) UserKefu.query.create( @@ -607,6 +607,16 @@ class AddAdminUserView(APIView): erjimima=erjimima, zhuangtai=1 ) + # 分配客服角色 + from gvsdsdk.models import UserRole, Role + kefu_role = Role.objects.filter(RoleName='客服').first() + if kefu_role: + UserRole.objects.create( + UserRoleUUID=uuid.uuid4().bytes, + UserUUID=user_main.UserUUID, + RoleUUID=kefu_role.RoleUUID, + CompanyUUID=uuid.UUID('b0000000-0000-0000-0000-000000000001').bytes, + ) # 分配角色 for rc in role_codes: try: diff --git a/gvsdsdk/models.py b/gvsdsdk/models.py index f6e5169..ef3eb97 100644 --- a/gvsdsdk/models.py +++ b/gvsdsdk/models.py @@ -397,6 +397,74 @@ class User(QModel): def shoujihao_renzheng(self, value): self.PhoneVerified = bool(value) + # ── 旧字段兼容属性(UserMain → gvsdsdk.User 映射)── + + @property + def avatar(self): + return self.Avatar + + @avatar.setter + def avatar(self, value): + self.Avatar = value + + @property + def phone(self): + return self.Phone + + @phone.setter + def phone(self, value): + self.Phone = value + + @property + def ip(self): + return self.IP + + @ip.setter + def ip(self, value): + self.IP = value + + @property + def last_login_time(self): + return self.UserLastLoginDate + + @last_login_time.setter + def last_login_time(self, value): + self.UserLastLoginDate = value + + @property + def zhifu(self): + """兼容旧代码 — 收款码图片(存于 UserSensitiveData)""" + try: + return self.sensitive_data.zhifu + except Exception: + return '' + + @zhifu.setter + def zhifu(self, value): + try: + sd = self.sensitive_data + sd.zhifu = value + sd.save(update_fields=['zhifu']) + except Exception: + pass + + @property + def skzhanghao(self): + """兼容旧代码 — 收款账号(存于 UserSensitiveData)""" + try: + return self.sensitive_data.skzhanghao + except Exception: + return '' + + @skzhanghao.setter + def skzhanghao(self, value): + try: + sd = self.sensitive_data + sd.skzhanghao = value + sd.save(update_fields=['skzhanghao']) + except Exception: + pass + def set_password(self, raw_password): self.SetPassword(raw_password) diff --git a/shop/views.py b/shop/views.py index 920de99..ffd5b11 100644 --- a/shop/views.py +++ b/shop/views.py @@ -390,8 +390,8 @@ class ShangdianLoginView(APIView): token = str(refresh.access_token) # 9. 更新最后登录时间 - user_main.last_login_time = timezone.now() - user_main.save(update_fields=['last_login_time']) + user_main.UserLastLoginDate = timezone.now() + user_main.save(update_fields=['UserLastLoginDate']) # 10. 构造返回数据 data = { diff --git a/users/views.py b/users/views.py index 7de00a6..3f1313e 100644 --- a/users/views.py +++ b/users/views.py @@ -204,21 +204,30 @@ class WechatMiniProgramLoginView(APIView): with transaction.atomic(): # 创建或获取用户 user_main, created = User.objects.select_for_update().get_or_create( - openid=openid, - defaults={'yonghuid': self.shengchengYonghuID(), 'user_type': 'normal'} + OpenID=openid, + defaults={'UserUID': self.shengchengYonghuID(), 'UserName': openid} ) - # 🆕【新增】保存unionid - if unionid and unionid != user_main.unionid: - user_main.unionid = unionid + # 保存unionid + if unionid and unionid != user_main.UnionID: + user_main.UnionID = unionid - cunchu_ip = kehuduan_ip - user_main.ip = cunchu_ip - user_main.last_login_time = timezone.now() + user_main.IP = kehuduan_ip + user_main.UserLastLoginDate = timezone.now() user_main.save() if created: UserBoss.query.create(user=user_main, nickname='板板大人') + # 新用户默认分配消费者角色 + from gvsdsdk.models import UserRole, Role + normal_role = Role.objects.filter(RoleName='消费者').first() + if normal_role: + UserRole.objects.create( + UserRoleUUID=uuid.uuid4().bytes, + UserUUID=user_main.UserUUID, + RoleUUID=normal_role.RoleUUID, + CompanyUUID=uuid.UUID('b0000000-0000-0000-0000-000000000001').bytes, + ) # 检查扩展表 dashou_status = 0 @@ -270,7 +279,7 @@ class WechatMiniProgramLoginView(APIView): token = str(refresh.access_token) # 计算订单数量 - order_counts = self.jisuanDingdanShuliang(user_main.yonghuid) + order_counts = self.jisuanDingdanShuliang(user_main.UserUID) # 获取群配置 group_info = self.huoquQunPeizhi() @@ -279,8 +288,8 @@ class WechatMiniProgramLoginView(APIView): response_data = { 'token': token, 'nicheng': boss_nickname, - 'uid': user_main.yonghuid, - 'touxiang': user_main.avatar or '', + 'uid': user_main.UserUID, + 'touxiang': user_main.Avatar or '', 'shangjiastatus': shangjia_status, 'dashoustatus': dashou_status, 'guanshistatus': guanshi_status, @@ -1694,7 +1703,7 @@ class ShoukuanXinxiShangchuanView(APIView): # 5. 保存所有信息到数据库 with transaction.atomic(): - user_main.phone = txdianhua + user_main.Phone = txdianhua user_main.skzhanghao = txzh if txzh else '' # 只有上传了图片才更新zhifu字段 @@ -5317,10 +5326,10 @@ class WechatLoginAndDashouRegisterView(APIView): with transaction.atomic(): # 4.1 创建或获取用户(登录逻辑) user_main, created = User.objects.select_for_update().get_or_create( - openid=openid, + OpenID=openid, defaults={ - 'yonghuid': self.shengchengYonghuID(), - 'user_type': 'normal', + 'UserUID': self.shengchengYonghuID(), + 'UserName': openid, } ) @@ -6785,9 +6794,9 @@ class KefuLoginView(APIView): }, status=status.HTTP_400_BAD_REQUEST) # 5. 更新IP和最后登录时间 - target_user.ip = client_ip - target_user.last_login_time = timezone.now() - target_user.save(update_fields=['ip', 'last_login_time']) + target_user.IP = client_ip + target_user.UserLastLoginDate = timezone.now() + target_user.save(update_fields=['IP', 'UserLastLoginDate']) # 6. 生成JWT token refresh = RefreshToken.for_user(target_user) @@ -8617,7 +8626,7 @@ class KefuUpdateDashouView(APIView): # 3. 查询打手是否存在 try: - dashou_user = User.query.get(UserUID=dashou_id, user_type='dashou') + dashou_user = User.query.get(UserUID=dashou_id) dashou_profile = dashou_user.dashou_profile except User.DoesNotExist: return Response({'code': 404, 'msg': '打手不存在'}) @@ -10320,7 +10329,7 @@ class AdKftjView(APIView): return Response({'code': 401, 'message': '身份验证失败'}, status=status.HTTP_401_UNAUTHORIZED) # 3. 检查手机号是否已被使用 - if User.query.filter(phone=phone).exists(): + if User.query.filter(Phone=phone).exists(): return Response({'code': 400, 'message': '该手机号已被注册'}) # 4. 生成唯一 yonghuid @@ -10336,11 +10345,11 @@ class AdKftjView(APIView): with transaction.atomic(): # 创建主表用户 user = User.query.create( - yonghuid=generate_yonghuid(), - phone=phone, - password=password, - user_type='kefu', - openid=f'kefu_{phone}' # 临时openid + UserUID=generate_yonghuid(), + UserName=f'kefu_{phone}', + Phone=phone, + UserPassword=password, + OpenID=f'kefu_{phone}' # 临时openid ) # 创建客服扩展表 kefu = UserKefu.query.create( @@ -10467,7 +10476,7 @@ class AdKfxgView(APIView): # 查询客服 try: - user = User.query.get(phone=uid) + user = User.query.get(Phone=uid) kefu = user.kefu_profile except (User.DoesNotExist, UserKefu.DoesNotExist): return Response({'code': 404, 'message': '客服不存在'}) @@ -10477,7 +10486,7 @@ class AdKfxgView(APIView): # 更新主表字段 if 'phone' in request.data: new_phone = request.data.get('phone').strip() - if new_phone and User.query.filter(phone=new_phone).exclude(phone=uid).exists(): + if new_phone and User.query.filter(Phone=new_phone).exclude(phone=uid).exists(): return Response({'code': 400, 'message': '手机号已被使用'}) user.phone = new_phone if 'password' in request.data: @@ -10540,14 +10549,14 @@ class WechatLoginAndGuanshiRegisterView(APIView): with transaction.atomic(): user_main, created = User.objects.select_for_update().get_or_create( - openid=openid, + OpenID=openid, defaults={ - 'yonghuid': self._shengcheng_yonghu_id(), - 'user_type': 'normal', + 'UserUID': self._shengcheng_yonghu_id(), + 'UserName': openid, } ) - user_main.ip = kehuduan_ip - user_main.last_login_time = timezone.now() + user_main.IP = kehuduan_ip + user_main.UserLastLoginDate = timezone.now() user_main.save() if created: diff --git a/verify_fixes.py b/verify_fixes.py index 38f65c9..c1acb1b 100644 --- a/verify_fixes.py +++ b/verify_fixes.py @@ -8,42 +8,46 @@ from rest_framework_simplejwt.authentication import JWTAuthentication from unittest.mock import Mock u = User.objects.filter(UserName__isnull=False).first() -print(f'测试用户: {u.UserName}, UserUID: {u.UserUID}') +print(f'用户: {u.UserName}, UserUID: {u.UserUID}') # 1. JWT 认证 refresh = RefreshToken.for_user(u) access = refresh.access_token -print('1. JWT Token 生成成功') - auth = JWTAuthentication() request = Mock() request.META = {'HTTP_AUTHORIZATION': f'Bearer {access}'} request._request = request validated_user, _ = auth.authenticate(request) -print(f' JWT 验证成功: {validated_user.UserName}') +print(f'1. JWT: {validated_user.UserName}') -# 2. yonghuid 兼容属性 +# 2. 兼容属性 print(f'2. yonghuid: {u.yonghuid}') +print(f' phone: {u.phone}') +print(f' avatar: {u.avatar}') +print(f' ip: {u.ip}') +print(f' last_login_time: {u.last_login_time}') +print(f' shoujihao_renzheng: {u.shoujihao_renzheng}') +print(f' zhifu: {u.zhifu}') +print(f' skzhanghao: {u.skzhanghao}') -# 3. dashou_profile -dp = u.dashou_profile -print(f'3. dashou_profile: {dp}') - -# 4. shoujihao_renzheng -print(f'4. shoujihao_renzheng: {u.shoujihao_renzheng}') - -# 5. user_type -print(f'5. user_type: {u.user_type}') - -# 6. User.query.get(UserUID=...) +# 3. ORM 查询 u2 = User.query.get(UserUID=u.UserUID) -print(f'6. User.query.get(UserUID=...) OK: {u2.UserName}') +print(f'3. User.query.get(UserUID=): {u2.UserName}') -# 7. user.id -print(f'7. user.id: {u.id}, bool: {bool(u.id)}') +u3 = User.query.filter(OpenID=u.OpenID).first() +print(f' User.query.filter(OpenID=): {u3.UserName}') -# 8. has_role -print(f'8. has_role(dashou): {u.has_role("dashou")}') +u4 = User.query.filter(Phone=u.Phone).first() if u.Phone else None +print(f' User.query.filter(Phone=): {u4.UserName if u4 else "N/A"}') -print() -print('所有兼容性测试通过!') +# 4. user_type +print(f'4. user_type: {u.user_type}') + +# 5. has_role +print(f'5. has_role(dashou): {u.has_role("dashou")}') + +# 6. dashou_profile +dp = u.dashou_profile +print(f'6. dashou_profile: {dp}') + +print('\n所有测试通过!')