| @@ -15,7 +15,7 @@ from pywe_storage import RedisStorage | ||
| 15 | 15 | from account.models import UserInfo | 
| 16 | 16 | from logs.models import MchInfoDecryptLogInfo, MchInfoEncryptLogInfo | 
| 17 | 17 | from marketcode.models import MarketCodeInfo | 
| 18 | -from mch.models import ActivityInfo, BrandInfo, ModelInfo | |
| 18 | +from mch.models import ActivityInfo, BrandInfo, ModelInfo, ConsumeShotUnbindingInfo | |
| 19 | 19 | from utils.algorithm.b64 import b64_decrypt, b64_encrypt | 
| 20 | 20 | from utils.algorithm.caesar import caesar_decrypt, caesar_encrypt | 
| 21 | 21 | from utils.algorithm.rsalg import rsa_decrypt, rsa_encrypt | 
| @@ -147,6 +147,8 @@ def decrypt(request, v='v2'): | ||
| 147 | 147 | mdli.decrypt_count += 1 | 
| 148 | 148 | mdli.save() | 
| 149 | 149 |  | 
| 150 | + unbound = ConsumeShotUnbindingInfo.objects.filter(model_id=model.model_id, sn=sn, status=True).exists() | |
| 151 | + | |
| 150 | 152 | # 弃用老版本的劵形式,和会员系统统一 | 
| 151 | 153 | if v == 'v1': | 
| 152 | 154 | has_unexpired_activity = False | 
| @@ -173,6 +175,7 @@ def decrypt(request, v='v2'): | ||
| 173 | 175 | }, | 
| 174 | 176 | 'has_unexpired_activity': False, | 
| 175 | 177 | 'coupon_infos': coupon_infos, | 
| 178 | + 'unbound': unbound, | |
| 176 | 179 | }) | 
| 177 | 180 |  | 
| 178 | 181 |  | 
| @@ -241,6 +244,8 @@ def decrypt2(request, v='v2'): | ||
| 241 | 244 | mdli.decrypt_count += 1 | 
| 242 | 245 | mdli.save() | 
| 243 | 246 |  | 
| 247 | + unbound = ConsumeShotUnbindingInfo.objects.filter(model_id=model.model_id, sn=sn, status=True).exists() | |
| 248 | + | |
| 244 | 249 | if v == 'v1': | 
| 245 | 250 | has_unexpired_activity = False | 
| 246 | 251 |          coupon_infos = {} | 
| @@ -266,4 +271,5 @@ def decrypt2(request, v='v2'): | ||
| 266 | 271 | }, | 
| 267 | 272 | 'has_unexpired_activity': False, | 
| 268 | 273 | 'coupon_infos': coupon_infos, | 
| 274 | + 'unbound': unbound, | |
| 269 | 275 | }) | 
| @@ -296,7 +296,13 @@ def consumer_info_api(request): | ||
| 296 | 296 | status=True | 
| 297 | 297 | ).exists() | 
| 298 | 298 |  | 
| 299 | - if dupload: | |
| 299 | + unbound = ConsumeShotUnbindingInfo.objects.filter( | |
| 300 | + model_id=model.model_id, | |
| 301 | + sn=serialNo, | |
| 302 | + status=True | |
| 303 | + ).exists() | |
| 304 | + | |
| 305 | + if dupload or unbound: | |
| 300 | 306 | act = None | 
| 301 | 307 | during_activity = False | 
| 302 | 308 | else: | 
| @@ -330,10 +336,11 @@ def consumer_info_api(request): | ||
| 330 | 336 | ym=ymd[:6], | 
| 331 | 337 | ymd=ymd, | 
| 332 | 338 | province=user.province_name if lat == 0.0 and lon == 0.0 else '', | 
| 333 | - submit_during_activity=during_activity | |
| 339 | + submit_during_activity=during_activity, | |
| 340 | + unbound=unbound | |
| 334 | 341 | ) | 
| 335 | 342 |  | 
| 336 | - if not dupload: | |
| 343 | + if not dupload and not unbound: | |
| 337 | 344 | for act in activities: | 
| 338 | 345 | try: | 
| 339 | 346 | coupon = CouponInfo.objects.get(coupon_id=act['coupon_id']) | 
| @@ -370,7 +377,7 @@ def consumer_info_api(request): | ||
| 370 | 377 | user.resgister_at = log.created_at | 
| 371 | 378 | user.save() | 
| 372 | 379 |  | 
| 373 | - if not user.test_user and not dupload: | |
| 380 | + if not user.test_user and not dupload and not unbound: | |
| 374 | 381 |  | 
| 375 | 382 | # TODO: Make statistic async | 
| 376 | 383 | cusi, _ = ConsumeUserStatisticInfo.objects.get_or_create( | 
| @@ -457,7 +464,7 @@ def consumer_info_api(request): | ||
| 457 | 464 | 'pk': log.pk, | 
| 458 | 465 | }) | 
| 459 | 466 |  | 
| 460 | - if not dupload: | |
| 467 | + if not dupload and not unbound: | |
| 461 | 468 | log.integral = model.shot_member_integral | 
| 462 | 469 | log.save() | 
| 463 | 470 | user.shots_num += 1 | 
| @@ -539,13 +546,13 @@ def consumer_shot_unbinding(request): | ||
| 539 | 546 | except UserInfo.DoesNotExist: | 
| 540 | 547 | return response(UserStatusCode.USER_NOT_FOUND) | 
| 541 | 548 |  | 
| 549 | + ConsumeInfoSubmitLogInfo.objects.filter(user_id=user_id, model_id=model_id, serialNo=sn).update(delete_type=ConsumeInfoSubmitLogInfo.UNBINDING, status=False) | |
| 550 | + | |
| 542 | 551 |      ConsumeShotUnbindingInfo.objects.update_or_create(user_id=user_id, submit_pk=submit_pk, defaults={ | 
| 543 | 552 | 'model_id': model_id, | 
| 544 | 553 | 'sn': sn, | 
| 545 | 554 | 'submit_at': submit_at, | 
| 546 | 555 | 'reason': reason, | 
| 547 | 556 | }) | 
| 548 | - | |
| 557 | + | |
| 549 | 558 | return response(200, 'Consume Shot Unbinding Success', u'消费者镜头解绑成功') | 
| 550 | - | |
| 551 | - | 
| @@ -271,9 +271,10 @@ def exec_del_consumer_submit(pk, admin_id): | ||
| 271 | 271 | sn = ssli.serialNo | 
| 272 | 272 |  | 
| 273 | 273 | ssli.status = False | 
| 274 | + ssli.delete_type = ConsumeInfoSubmitLogInfo.RETURN | |
| 274 | 275 | ssli.save() | 
| 275 | 276 |  | 
| 276 | - ConsumeInfoSubmitLogInfo.objects.filter(serialNo=sn, model_id=ssli.model_id, dupload=True, status=True).update(status=False) | |
| 277 | + ConsumeInfoSubmitLogInfo.objects.filter(serialNo=sn, model_id=ssli.model_id, dupload=True, status=True).update(delete_type=ConsumeInfoSubmitLogInfo.RETURN, status=False) | |
| 277 | 278 |  | 
| 278 | 279 | if ssli.dupload: | 
| 279 | 280 | return response() | 
| @@ -245,7 +245,7 @@ class ConsumeInfoSubmitLogInfoAdmin(AdvancedExportExcelModelAdmin, ReadOnlyModel | ||
| 245 | 245 |  | 
| 246 | 246 | class ConsumeShotUnbindingInfoAdmin(admin.ModelAdmin): | 
| 247 | 247 |      list_display = ('user_id', 'submit_pk', 'submit_at', 'model_id', 'sn', 'reason', 'created_at') | 
| 248 | -    search_fields = ('sn') | |
| 248 | +    search_fields = ('sn', ) | |
| 249 | 249 |  | 
| 250 | 250 |  | 
| 251 | 251 | class ActivityInfoAdmin(admin.ModelAdmin): | 
| @@ -0,0 +1,25 @@ | ||
| 1 | +# -*- coding: utf-8 -*- | |
| 2 | + | |
| 3 | +# Generated by Django 3.2.6 on 2023-03-02 09:54 | |
| 4 | + | |
| 5 | +from django.db import migrations, models | |
| 6 | + | |
| 7 | + | |
| 8 | +class Migration(migrations.Migration): | |
| 9 | + | |
| 10 | + dependencies = [ | |
| 11 | +        ('mch', '0068_alter_consumeshotunbindinginfo_reason'), | |
| 12 | + ] | |
| 13 | + | |
| 14 | + operations = [ | |
| 15 | + migrations.AddField( | |
| 16 | + model_name='consumeinfosubmitloginfo', | |
| 17 | + name='delete_type', | |
| 18 | + field=models.IntegerField(choices=[(0, '未删除'), (1, '退货'), (2, '解绑')], db_index=True, default=0, help_text='删除类型', verbose_name='delete_type'), | |
| 19 | + ), | |
| 20 | + migrations.AddField( | |
| 21 | + model_name='consumeinfosubmitloginfo', | |
| 22 | + name='unbound', | |
| 23 | + field=models.BooleanField(default=False, help_text='是否为已解绑镜头', verbose_name='unbound'), | |
| 24 | + ), | |
| 25 | + ] | 
| @@ -674,6 +674,17 @@ class LatestAppScreenInfo(BaseModelMixin): | ||
| 674 | 674 |  | 
| 675 | 675 |  | 
| 676 | 676 | class ConsumeInfoSubmitLogInfo(BaseModelMixin): | 
| 677 | + | |
| 678 | + UNDELETE = 0 | |
| 679 | + RETURN = 1 | |
| 680 | + UNBINDING = 2 | |
| 681 | + | |
| 682 | + DELETE_TYPE = ( | |
| 683 | + (UNDELETE, u'未删除'), | |
| 684 | + (RETURN, u'退货'), | |
| 685 | + (UNBINDING, u'解绑'), | |
| 686 | + ) | |
| 687 | + | |
| 677 | 688 | user_id = models.CharField(_(u'user_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True) | 
| 678 | 689 |  | 
| 679 | 690 | phone = models.CharField(_(u'phone'), max_length=11, blank=True, null=True, help_text=u'用户手机', db_index=True) | 
| @@ -718,6 +729,9 @@ class ConsumeInfoSubmitLogInfo(BaseModelMixin): | ||
| 718 | 729 |  | 
| 719 | 730 | test_user = models.BooleanField(_(u'test_user'), default=False, help_text=u'是否为测试用户') | 
| 720 | 731 |  | 
| 732 | + unbound = models.BooleanField(_(u'unbound'), default=False, help_text=u'是否为已解绑镜头') | |
| 733 | + delete_type = models.IntegerField(_(u'delete_type'), choices=DELETE_TYPE, default=UNDELETE, help_text=u'删除类型', db_index=True) | |
| 734 | + | |
| 721 | 735 | class Meta: | 
| 722 | 736 | verbose_name = _(u'消费者信息提交记录') | 
| 723 | 737 | verbose_name_plural = _(u'消费者信息提交记录') | 
| @@ -783,6 +797,7 @@ class ConsumeInfoSubmitLogInfo(BaseModelMixin): | ||
| 783 | 797 | 'serialNo': self.serialNo, | 
| 784 | 798 | 'integral': self.integral, | 
| 785 | 799 | 'dupload': self.dupload, | 
| 800 | + 'unbound': self.unbound, | |
| 786 | 801 | 'code_version': self.code_version, | 
| 787 | 802 | 'created_at': tc.local_string(utc_dt=self.created_at, format='%Y-%m-%d'), | 
| 788 | 803 | } | 
| @@ -798,6 +813,7 @@ class ConsumeInfoSubmitLogInfo(BaseModelMixin): | ||
| 798 | 813 | 'phone': self.phone, | 
| 799 | 814 | 'code_version': self.code_version, | 
| 800 | 815 | 'dupload': self.dupload, | 
| 816 | + 'unbound': self.unbound, | |
| 801 | 817 | 'created_at': tc.local_string(utc_dt=self.created_at), | 
| 802 | 818 | } | 
| 803 | 819 |  |