# -*- coding: utf-8 -*- from django.db import IntegrityError, transaction from django.utils import timezone from django_logit import logit from django_response import response from django.db.models import Q from account.models import UserInfo from sales.models import LotteryCampaignInfo, LotteryEntryInfo from utils.error.errno_utils import LotteryStatusCode, UserStatusCode def join_lottery(user, serial_no, model_id='', campaign_id='', submit_pk='', phone='', model_name=''): """ 写入抽奖名额(幂等) 返回 (entry, campaign, is_new): · 没有进行中的活动 → (None, None, False) · 已有名额 → (entry, campaign, False) · 首次参与 → (entry, campaign, True) """ serial_no = (serial_no or '').strip() campaign = LotteryCampaignInfo.objects.get(status=True, campaign_id=campaign_id) if not campaign: return None, None # 嵌套 atomic 生成 savepoint:并发插入冲突后还能继续查询 with transaction.atomic(): entry, created = LotteryEntryInfo.objects.update_or_create( campaign_id=campaign.campaign_id, serial_no=serial_no, submit_pk=submit_pk, title=campaign.title, user_id=user.user_id, model_id=model_id, model_name=model_name, defaults={ 'name': name, 'phone': phone, } ) return entry, campaign @logit(res=True) @transaction.atomic def lottery_join_api(request): """抽奖参与接口:写入名额""" user_id = request.POST.get('user_id', '') serial_no = request.POST.get('serial_no', '') model_id = request.POST.get('model_id') campaign_id = request.POST.get('campaign_id', '') submit_pk = request.POST.get('submit_pk', '') name = request.POST.get('name', '') phone = request.POST.get('phone', '') model_name = request.POST.get('model_name', '') try: user = UserInfo.objects.select_for_update().get(user_id=user_id) except UserInfo.DoesNotExist: return response(UserStatusCode.USER_NOT_FOUND) campaign = LotteryCampaignInfo.objects.get(status=True, campaign_id=campaign_id) if not campaign: return response(LotteryStatusCode.CAMPAIGN_NOT_FOUND) LotteryEntryInfo.objects.update_or_create( campaign_id=campaign.campaign_id, serial_no=serial_no, submit_pk=submit_pk, user_id=user.user_id, model_id=model_id, defaults={ 'campaign_title': campaign.title, 'name': name, 'phone': phone, 'model_name': model_name, } ) return response(200, 'join lottery campaign success', '参与抽奖成功')