注意:启用定时任务之后,任务为每分钟执行一次,每分钟检测一次表中记录是否24小时之前创建,所以不能达到正好24小时退款,误差在一分钟以内

一.配置使用

安装并配置好需要的模块之后启动worker和beta,然后就可以查看运行效果,当然我们先把代码写好后再启动

  1. celery -A 项目名 beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler #启动beta 调度器使用数据库
  2. celery worker -A 项目名 -l info #启动woker
  3. celery --app=项目名 worker -P eventlet -l INFO # celery5.0及以上版本需要用此命令

二.转账

转账就是一个账号的钱减少,另一个账号的钱增加,先设计转账记录表

  1. class Transfer_record(models.Model):
  2. Transfer_record_id = models.AutoField(primary_key=True, verbose_name="记录id")
  3. """Sponsor information"""
  4. Sponsor_user_id = models.CharField(max_length=20, verbose_name="发起人用户id", help_text="用户id", null=False)
  5. Sponsor_user_Balance = models.DecimalField(max_digits=100000, decimal_places=2, verbose_name="发起人余额",help_text="发起人余额", null=False)
  6. """Payer information"""
  7. Payer_user_id = models.CharField(max_length=20, verbose_name="收款人用户id", help_text="用户id", null=False)
  8. Payer_user_Balance = models.DecimalField(max_digits=100000, decimal_places=2, verbose_name="收款人余额",help_text="收款人余额", null=False)
  9. """Transfer record information"""
  10. Transfer_amount = models.DecimalField(max_digits=100000, decimal_places=2, verbose_name="转账金额",help_text="转账金额", null=False)
  11. Transfer_record_State = models.CharField(max_length=3, choices=_Transfer_State, default="未到账",verbose_name="转账状态(已到账/未到账)",help_text="转账状态", null=False)
  12. initiating_time = models.DateTimeField(auto_now_add=True, verbose_name="发起时间", null=False)
  13. account_time = models.DateTimeField(verbose_name="到帐时间", blank=True, null=True, help_text="到帐时间")

点击转账之后,发起人余额减少,收款人余额不增多,等待收款人点击确认收款之后,收款人余额才会变化

  1. def collection(request):
  2. """收款"""
  3. Payer_user_id = request.POST.get('Payer_user_id') # 收款人id
  4. Transfer_record_id = request.POST.get('Transfer_record_id') # 记录id
  5. a = Transfer_record.objects.get(Transfer_record_id=Transfer_record_id)
  6. if a.Transfer_record_State == '已到账':
  7. return Response(data={'message': '已到账'}, status=status.HTTP_200_OK)
  8. else:
  9. user_list = personal_info.objects.filter(user_id=Payer_user_id).update(user_balance=F('user_balance') + a.Transfer_amount)
  10. a.Transfer_record_State = '已到账'
  11. a.account_time = datetime.datetime.now()
  12. a.save()
  13. return Response(data={'message': '收款成功'}, status=status.HTTP_200_OK)

点击后如果状态为已到账,则返回已到账,如果不是,则收款人余额增加,记录表状态改为已到账

三.24小时未领取退回

如果24小时内没有领取,钱将自动退回,在app目录里新建tasks.py

  1. from __future__ import absolute_import, unicode_literals
  2. from celery import shared_task
  3. from django.db.models import F
  4. from django.utils import timezone
  5. from blog.models import Transfer_record
  6. from user.models import personal_info
  7. @shared_task
  8. def transfer_accounts():
  9. """
  10. 转账,24小时不领取退回
  11. :return:
  12. """
  13. ctime = timezone.localtime() # 现在时间
  14. stime = ctime + timezone.timedelta(days=-1) # 一天前
  15. skill_is_changed = Transfer_record.objects.filter(initiating_time__lte=stime,Transfer_record_State='未到账') # 一天前创建而且未到账的记录
  16. for i in skill_is_changed:
  17. personal_info.objects.filter(user_id=i.Sponsor_user_id).update(user_balance=F('user_balance')+i.Transfer_amount)
  18. i.Transfer_record_State='已退回'
  19. i.save()
  20. return None

ctime为现在的时间,stime为一天前,判断记录表里一天前创建而且未到账的记录,然后进行退回

代码写好后不能自动执行,需要进行配置,在admin后台找到
image.png

进行增加自动任务
image.png
image.png

进行保存之后,按照配置使用在终端启动worker和beta,即可启动任务,测试的时候也可以把days=-1改为minutes=-1,即一分钟钱创建的记录

四.注意

启用定时任务之后,任务为每分钟执行一次,每分钟检测一次表中记录是否24小时之前创建,所以不能达到正好24小时退款,误差在一分钟以内