From 09dc5cebba2ca01b13cffcb1a7914a3a612e5df0 Mon Sep 17 00:00:00 2001 From: XingQue Date: Thu, 18 Jun 2026 14:19:09 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B9=8B=E5=89=8D=E4=BF=9D=E8=AF=81=E9=87=91?= =?UTF-8?q?=E6=8F=90=E7=8E=B0=EF=BC=88leixing=3D5=EF=BC=89=E5=9C=A8?= =?UTF-8?q?=E7=94=B3=E8=AF=B7=E6=89=A3=E6=AC=BE=E6=97=B6=E4=BC=9A=E5=B0=81?= =?UTF-8?q?=E7=A6=81=EF=BC=88zhanghaozhuangtai=3D0=EF=BC=89=EF=BC=8C?= =?UTF-8?q?=E9=A9=B3=E5=9B=9E=E9=80=80=E6=AC=BE=E6=97=B6=E4=BC=9A=E8=A7=A3?= =?UTF-8?q?=E5=B0=81=EF=BC=88zhanghaozhuangtai=3D1=EF=BC=89=E3=80=82?= =?UTF-8?q?=E6=94=B6=E6=AC=BE=E6=B5=81=E7=A8=8B=E6=9C=AC=E8=BA=AB=E4=B8=8D?= =?UTF-8?q?=E4=BC=9A=E5=B0=81=E7=A6=81=EF=BC=8C=E4=BD=86=E8=8B=A5=E7=94=B3?= =?UTF-8?q?=E8=AF=B7=E6=97=B6=E5=B7=B2=E5=B0=81=E7=A6=81=EF=BC=8C=E6=94=B6?= =?UTF-8?q?=E6=AC=BE=E6=A0=A1=E9=AA=8C=E4=BC=9A=E6=8B=A6=E6=8E=89=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yonghu/tixian_shenhe_services.py | 2 - yonghu/views.py | 145 ++++++++++++++++++------------- 2 files changed, 84 insertions(+), 63 deletions(-) diff --git a/yonghu/tixian_shenhe_services.py b/yonghu/tixian_shenhe_services.py index f7ae212..799059a 100644 --- a/yonghu/tixian_shenhe_services.py +++ b/yonghu/tixian_shenhe_services.py @@ -873,7 +873,6 @@ def refund_balance(user_main, leixing, jine): elif leixing == 5: dashou = UserDashou.objects.select_for_update().get(user=user_main) dashou.yajin += jine - dashou.zhanghaozhuangtai = 1 dashou.save() elif leixing == 6: shangjia = UserShangjia.objects.select_for_update().get(user=user_main) @@ -918,7 +917,6 @@ def deduct_balance(user_main, leixing, jine): if dashou.yajin < jine: raise ValueError('押金余额不足') dashou.yajin -= jine - dashou.zhanghaozhuangtai = 0 dashou.save() return dashou.nicheng or '' if leixing == 6: diff --git a/yonghu/views.py b/yonghu/views.py index 01c7b6b..e7ac5b8 100644 --- a/yonghu/views.py +++ b/yonghu/views.py @@ -3,7 +3,7 @@ import time import random import hashlib import requests -from django.db import transaction +from django.db import transaction, IntegrityError from django.conf import settings from rest_framework.views import APIView from rest_framework.response import Response @@ -24,7 +24,7 @@ from rest_framework.permissions import AllowAny # 新增这行 from django.conf import settings from django.utils import timezone -from django.db import transaction +from django.db import transaction, IntegrityError from django.core.exceptions import ObjectDoesNotExist from rest_framework.views import APIView from rest_framework.response import Response @@ -71,6 +71,63 @@ def huoquYonghuDaili(request): return user_agent[:100] if user_agent else '' +def shengcheng_yonghu_id(): + """生成7位数字用户ID""" + 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 UserMain.objects.filter(yonghuid=user_id).exists(): + return user_id + raise Exception('生成用户ID失败') + + +def get_or_create_wechat_user(openid, user_type='normal'): + """ + 按 openid 获取或创建微信用户,兼容并发注册导致的主键/唯一键冲突。 + 返回 (user_main, created) + """ + for attempt in range(3): + try: + with transaction.atomic(): + user_main = UserMain.objects.select_for_update().filter(openid=openid).first() + if user_main: + if not user_main.yonghuid: + yonghuid = shengcheng_yonghu_id() + UserMain.objects.filter(pk=user_main.pk).update(yonghuid=yonghuid) + user_main.refresh_from_db() + return user_main, False + + user_main = UserMain.objects.create( + openid=openid, + yonghuid=shengcheng_yonghu_id(), + user_type=user_type, + ) + user_main.refresh_from_db() + return user_main, True + except IntegrityError: + if attempt == 2: + user_main = UserMain.objects.filter(openid=openid).first() + if user_main: + return user_main, False + raise + user_main = UserMain.objects.get(openid=openid) + return user_main, False + + +def update_wechat_user_login_info(user_main, ip, unionid=None): + """更新登录信息,使用 update 避免 save() 误触发 INSERT。""" + update_fields = { + 'ip': ip, + 'last_login_time': timezone.now(), + } + if unionid and unionid != user_main.unionid: + update_fields['unionid'] = unionid + UserMain.objects.filter(pk=user_main.pk).update(**update_fields) + user_main.refresh_from_db() + + @@ -112,20 +169,8 @@ class WechatMiniProgramLoginView(APIView): kehuduan_ip = self.huoquKehuduanIP(request) with transaction.atomic(): - # 创建或获取用户 - user_main, created = UserMain.objects.select_for_update().get_or_create( - openid=openid, - defaults={'yonghuid': self.shengchengYonghuID(), 'user_type': 'normal'} - ) - - # 🆕【新增】保存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.save() + user_main, created = get_or_create_wechat_user(openid, user_type='normal') + update_wechat_user_login_info(user_main, kehuduan_ip, unionid=unionid or None) if created: UserBoss.objects.create(user=user_main, nickname='板板大人') @@ -513,7 +558,7 @@ class WeixinOfficialCallbackView(APIView): # yonghu/views.py from rest_framework.parsers import MultiPartParser, FormParser,JSONParser from rest_framework import permissions -from django.db import transaction +from django.db import transaction, IntegrityError from rest_framework.response import Response from rest_framework import status from rest_framework.views import APIView @@ -1597,7 +1642,7 @@ class GuanshiYaoqingDashouListView(APIView): from rest_framework.views import APIView from rest_framework import permissions, status from rest_framework.response import Response -from django.db import transaction +from django.db import transaction, IntegrityError from .models import UserMain, UserDashou, UserGuanshi, Tixianjilu import os import uuid @@ -1811,7 +1856,7 @@ class ShoukuanXinxiShangchuanView(APIView): from rest_framework.views import APIView from rest_framework import permissions, status from rest_framework.response import Response -from django.db import transaction +from django.db import transaction, IntegrityError from django.db.models import F import decimal import traceback @@ -1820,7 +1865,7 @@ from .models import UserMain, UserDashou, UserGuanshi, Tixianjilu from rest_framework.views import APIView from rest_framework import permissions, status from rest_framework.response import Response -from django.db import transaction +from django.db import transaction, IntegrityError from django.db.models import F import decimal import traceback @@ -1979,8 +2024,6 @@ class TixianShenqingView(APIView): if profile.yajin < jine: return Response({'code': 53, 'msg': '押金余额不足'}) profile.yajin = F('yajin') - jine - # 押金提现后封禁打手账号 - profile.zhanghaozhuangtai = 0 # 0表示禁用 profile.save() nicheng = profile.nicheng or '' elif leixing == 6: @@ -2460,7 +2503,7 @@ from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import status from rest_framework.permissions import IsAuthenticated -from django.db import transaction +from django.db import transaction, IntegrityError from django.core.exceptions import ObjectDoesNotExist import json @@ -2926,7 +2969,7 @@ from rest_framework.response import Response from rest_framework.permissions import IsAuthenticated from rest_framework.parsers import JSONParser from rest_framework import status -from django.db import transaction +from django.db import transaction, IntegrityError import logging # 获取日志器 @@ -4323,7 +4366,7 @@ class AdTongYiChuFa(APIView): from django.utils import timezone from datetime import timedelta from decimal import Decimal -from django.db import transaction +from django.db import transaction, IntegrityError from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.permissions import IsAuthenticated @@ -5700,7 +5743,7 @@ from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import status from rest_framework.permissions import IsAuthenticated -from django.db import transaction +from django.db import transaction, IntegrityError from django.utils import timezone from peizhi.models import Szjilu # 添加收支记录表导入 @@ -6609,20 +6652,8 @@ class WechatLoginAndDashouRegisterView(APIView): # 4. 开始数据库事务(确保登录和注册的原子性) with transaction.atomic(): - # 4.1 创建或获取用户(登录逻辑) - user_main, created = UserMain.objects.select_for_update().get_or_create( - openid=openid, - defaults={ - 'yonghuid': self.shengchengYonghuID(), - 'user_type': 'normal', - } - ) - - # 更新用户IP和最后登录时间 - cunchu_ip = kehuduan_ip - user_main.ip = cunchu_ip - user_main.last_login_time = timezone.now() - user_main.save() + user_main, created = get_or_create_wechat_user(openid, user_type='normal') + update_wechat_user_login_info(user_main, kehuduan_ip) if created: # 新用户:创建老板扩展表 @@ -7650,7 +7681,7 @@ class DashouShensuView(APIView): }, status=status.HTTP_400_BAD_REQUEST) # 🔴🆕【关键】使用事务确保数据一致性 - from django.db import transaction + from django.db import transaction, IntegrityError with transaction.atomic(): # 1. 查询处罚记录 @@ -8842,7 +8873,7 @@ class KefuGetOrderDetailView(APIView): import logging -from django.db import transaction +from django.db import transaction, IntegrityError from django.core.exceptions import ObjectDoesNotExist from rest_framework.views import APIView from rest_framework.response import Response @@ -9070,7 +9101,7 @@ import requests import xmltodict import time from decimal import Decimal -from django.db import transaction +from django.db import transaction, IntegrityError from django.conf import settings from django.core.exceptions import ObjectDoesNotExist from rest_framework.views import APIView @@ -9626,7 +9657,7 @@ class KefuPlatformRefundView(APIView): # dingdan/views.py import logging -from django.db import transaction +from django.db import transaction, IntegrityError from django.core.exceptions import ObjectDoesNotExist from rest_framework.views import APIView from rest_framework.response import Response @@ -11489,7 +11520,7 @@ class KefuPunishmentDetailView(APIView): -from django.db import transaction +from django.db import transaction, IntegrityError from decimal import Decimal class KefuPunishmentActionView(APIView): @@ -12050,7 +12081,7 @@ class KefuWithdrawDetailView(APIView): import logging import json from decimal import Decimal -from django.db import transaction +from django.db import transaction, IntegrityError from django.utils import timezone from django.core.exceptions import ObjectDoesNotExist from rest_framework.views import APIView @@ -12395,7 +12426,7 @@ class KefuPunishView(APIView): return Response({'code': 0, 'msg': '处罚成功'}) -from django.db import transaction +from django.db import transaction, IntegrityError from django.contrib.auth.hashers import make_password class AdKftjView(APIView): @@ -12641,7 +12672,7 @@ import time from datetime import date import requests -from django.db import transaction +from django.db import transaction, IntegrityError from django.conf import settings from rest_framework.views import APIView from rest_framework import permissions, status @@ -12669,7 +12700,7 @@ from datetime import date import logging import requests -from django.db import transaction +from django.db import transaction, IntegrityError from django.conf import settings from django.core.cache import cache from django.utils import timezone @@ -12700,7 +12731,7 @@ from datetime import date import logging import requests -from django.db import transaction +from django.db import transaction, IntegrityError from django.conf import settings from django.core.cache import cache from django.utils import timezone @@ -13542,16 +13573,8 @@ class WechatLoginAndGuanshiRegisterView(APIView): kehuduan_ip = self._huoqu_kehuduan_ip(request) with transaction.atomic(): - user_main, created = UserMain.objects.select_for_update().get_or_create( - openid=openid, - defaults={ - 'yonghuid': self._shengcheng_yonghu_id(), - 'user_type': 'normal', - } - ) - user_main.ip = kehuduan_ip - user_main.last_login_time = timezone.now() - user_main.save() + user_main, created = get_or_create_wechat_user(openid, user_type='normal') + update_wechat_user_login_info(user_main, kehuduan_ip) if created: UserBoss.objects.create(user=user_main, nickname='微信用户') @@ -13784,7 +13807,7 @@ class WechatLoginAndGuanshiRegisterView(APIView): -from django.db import transaction, models +from django.db import transaction, IntegrityError, models class GuanshiRegisterView(APIView): """