@@ -8,7 +8,7 @@ from mch.models import ConsumeInfoSubmitLogInfo  | 
            ||
| 8 | 8 | 
                 | 
            
| 9 | 9 | 
                 | 
            
| 10 | 10 | 
                class UserInfoAdmin(ChangeOnlyModelAdmin, admin.ModelAdmin):  | 
            
| 11 | 
                -    list_display = ('user_id', 'nickname', 'phone', 'appid', 'unionid', 'openid', 'openid_miniapp', 'location', 'balance', 'integral', 'freeze_integral', 'user_status', 'test_user', 'integral', 'freeze_integral', 'shots_num', 'level', 'coupon_expire_at', 'is_maintenance', 'status', 'created_at', 'updated_at')
               | 
            |
| 11 | 
                +    list_display = ('user_id', 'nickname', 'phone', 'appid', 'unionid', 'openid', 'openid_miniapp', 'location', 'balance', 'user_status', 'test_user', 'integral', 'freeze_integral', 'shots_num', 'level', 'coupon_expire_at', 'is_maintenance', 'status', 'created_at', 'updated_at')
               | 
            |
| 12 | 12 | 
                     list_filter = ('user_from', 'appid', 'subscribe', 'has_membercard', 'test_user', 'is_maintenance', 'sex', 'user_status', 'status', 'code_version', 'new_subscribe', 'created_at', 'integral')
               | 
            
| 13 | 13 | 
                     readonly_fields = ('user_id', )
               | 
            
| 14 | 14 | 
                     search_fields = ('user_id', 'username', 'unionid', 'openid', 'openid_miniapp', 'name', 'phone', 'location', 'memberusercardcode')
               | 
            
                @@ -20,8 +20,9 @@ class UserInfoAdmin(ChangeOnlyModelAdmin, admin.ModelAdmin):  | 
            ||
| 20 | 20 | 
                 | 
            
| 21 | 21 | 
                 | 
            
| 22 | 22 | 
                class UserIntegralIncomeExpensesInfoAdmin(ChangeOnlyModelAdmin, admin.ModelAdmin):  | 
            
| 23 | 
                -    list_display = ('user_id', 'model_id', 'model_name', 'code', 'integral', 'remark', 'updated_at', 'created_at')
               | 
            |
| 24 | 
                -    search_fields = ('user_id',)
               | 
            |
| 23 | 
                +    list_display = ('user_id', 'brand_id', 'brand_name', 'model_id', 'model_name', 'code', 'integral_from', 'integral', 'final_integral', 'remark', 'updated_at', 'created_at')
               | 
            |
| 24 | 
                +    list_filter = ('integral_from', 'status')
               | 
            |
| 25 | 
                +    search_fields = ('user_id', )
               | 
            |
| 25 | 26 | 
                 | 
            
| 26 | 27 | 
                 | 
            
| 27 | 28 | 
                admin.site.register(UserInfo, UserInfoAdmin)  | 
            
                @@ -0,0 +1,19 @@  | 
            ||
| 1 | 
                +# -*- coding: utf-8 -*-  | 
            |
| 2 | 
                +# Generated by Django 3.2.16 on 2022-10-27 10:07  | 
            |
| 3 | 
                +  | 
            |
| 4 | 
                +from django.db import migrations, models  | 
            |
| 5 | 
                +  | 
            |
| 6 | 
                +  | 
            |
| 7 | 
                +class Migration(migrations.Migration):  | 
            |
| 8 | 
                +  | 
            |
| 9 | 
                + dependencies = [  | 
            |
| 10 | 
                +        ('account', '0054_userinfo_coupon_expire_at'),
               | 
            |
| 11 | 
                + ]  | 
            |
| 12 | 
                +  | 
            |
| 13 | 
                + operations = [  | 
            |
| 14 | 
                + migrations.AddField(  | 
            |
| 15 | 
                + model_name='userintegralincomeexpensesinfo',  | 
            |
| 16 | 
                + name='final_integral',  | 
            |
| 17 | 
                + field=models.IntegerField(default=0, help_text='最终积分', verbose_name='final_integral'),  | 
            |
| 18 | 
                + ),  | 
            |
| 19 | 
                + ]  | 
            
                @@ -0,0 +1,19 @@  | 
            ||
| 1 | 
                +# -*- coding: utf-8 -*-  | 
            |
| 2 | 
                +# Generated by Django 3.2.16 on 2022-10-27 10:38  | 
            |
| 3 | 
                +  | 
            |
| 4 | 
                +from django.db import migrations, models  | 
            |
| 5 | 
                +  | 
            |
| 6 | 
                +  | 
            |
| 7 | 
                +class Migration(migrations.Migration):  | 
            |
| 8 | 
                +  | 
            |
| 9 | 
                + dependencies = [  | 
            |
| 10 | 
                +        ('account', '0055_userintegralincomeexpensesinfo_final_integral'),
               | 
            |
| 11 | 
                + ]  | 
            |
| 12 | 
                +  | 
            |
| 13 | 
                + operations = [  | 
            |
| 14 | 
                + migrations.AlterField(  | 
            |
| 15 | 
                + model_name='userintegralincomeexpensesinfo',  | 
            |
| 16 | 
                + name='integral_from',  | 
            |
| 17 | 
                + field=models.IntegerField(choices=[(0, '产品'), (1, '分享'), (2, '投稿'), (99, '会员活动投稿福利')], default=0, help_text='积分来源', verbose_name='integral_from'),  | 
            |
| 18 | 
                + ),  | 
            |
| 19 | 
                + ]  | 
            
                @@ -331,11 +331,13 @@ class UserIntegralIncomeExpensesInfo(BaseModelMixin):  | 
            ||
| 331 | 331 | 
                PRODUCT = 0  | 
            
| 332 | 332 | 
                SHARE = 1  | 
            
| 333 | 333 | 
                CONTRIBUTE = 2  | 
            
| 334 | 
                + MEMBER_ACTIVITY_CONTRIBUTION_WELFARE = 99  | 
            |
| 334 | 335 | 
                 | 
            
| 335 | 336 | 
                INTEGRAL_FROM = (  | 
            
| 336 | 337 | 
                (PRODUCT, u'产品'),  | 
            
| 337 | 338 | 
                (SHARE, u'分享'),  | 
            
| 338 | 339 | 
                (CONTRIBUTE, u'投稿'),  | 
            
| 340 | 
                + (MEMBER_ACTIVITY_CONTRIBUTION_WELFARE, u'会员活动投稿福利'),  | 
            |
| 339 | 341 | 
                )  | 
            
| 340 | 342 | 
                 | 
            
| 341 | 343 | 
                user_id = models.CharField(_(u'user_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True)  | 
            
                @@ -343,14 +345,14 @@ class UserIntegralIncomeExpensesInfo(BaseModelMixin):  | 
            ||
| 343 | 345 | 
                brand_id = models.CharField(_(u'brand_id'), max_length=32, blank=True, null=True, help_text=u'品牌唯一标识', db_index=True)  | 
            
| 344 | 346 | 
                brand_name = models.CharField(_(u'brand_name'), max_length=255, blank=True, null=True, help_text=u'品牌名称')  | 
            
| 345 | 347 | 
                 | 
            
| 346 | 
                - integral_from = models.IntegerField(_(u'integral_from'), choices=INTEGRAL_FROM, default=PRODUCT, help_text=u'积分来源')  | 
            |
| 347 | 
                -  | 
            |
| 348 | 348 | 
                model_id = models.CharField(_(u'model_id'), max_length=32, blank=True, null=True, help_text=u'型号唯一标识', db_index=True)  | 
            
| 349 | 349 | 
                model_name = models.CharField(_(u'model_name'), max_length=255, blank=True, null=True, help_text=u'型号名称')  | 
            
| 350 | 350 | 
                 | 
            
| 351 | 351 | 
                code = models.CharField(_(u'code'), max_length=32, blank=True, null=True, help_text=u'机身码', db_index=True)  | 
            
| 352 | 352 | 
                 | 
            
| 353 | 
                + integral_from = models.IntegerField(_(u'integral_from'), choices=INTEGRAL_FROM, default=PRODUCT, help_text=u'积分来源')  | 
            |
| 353 | 354 | 
                integral = models.IntegerField(_(u'integral'), default=0, help_text=u'增减积分')  | 
            
| 355 | 
                + final_integral = models.IntegerField(_(u'final_integral'), default=0, help_text=u'最终积分')  | 
            |
| 354 | 356 | 
                 | 
            
| 355 | 357 | 
                remark = models.CharField(_(u'remark'), max_length=255, blank=True, null=True, help_text=u'备注')  | 
            
| 356 | 358 | 
                 | 
            
                @@ -29,10 +29,11 @@ from member.models import (GoodsInfo, GoodsOrderInfo, MemberActivityContribution  | 
            ||
| 29 | 29 | 
                MemberActivityGroupShareInfo, MemberActivityInfo, MemberActivitySignupInfo)  | 
            
| 30 | 30 | 
                from pre.custom_message import sendtemplatemessage, sendwxasubscribemessage  | 
            
| 31 | 31 | 
                from statistic.models import ConsumeModelSaleStatisticInfo, ConsumeSaleStatisticInfo, ConsumeUserStatisticInfo  | 
            
| 32 | 
                -from utils.error.errno_utils import (AdministratorStatusCode, ComplementCodeStatusCode,  | 
            |
| 32 | 
                +from utils.error.errno_utils import (AdministratorStatusCode, ComplementCodeStatusCode, CouponStatusCode,  | 
            |
| 33 | 33 | 
                MemberActivityContributionStatusCode, MemberActivityContributionWelfareStatusCode,  | 
            
| 34 | 
                - MemberActivityContributionWelfareUnblockingStatusCode, ProductBrandStatusCode,  | 
            |
| 35 | 
                - ProductCouponStatusCode, ProductMachineStatusCode, UserStatusCode)  | 
            |
| 34 | 
                + MemberActivityContributionWelfareUnblockingStatusCode, MemberActivityStatusCode,  | 
            |
| 35 | 
                + MemberGoodStatusCode, ProductCouponStatusCode, ProductMachineStatusCode,  | 
            |
| 36 | 
                + UserStatusCode)  | 
            |
| 36 | 37 | 
                 | 
            
| 37 | 38 | 
                 | 
            
| 38 | 39 | 
                WECHAT = settings.WECHAT  | 
            
                @@ -791,7 +792,7 @@ def member_activity_detail(request, administrator):  | 
            ||
| 791 | 792 | 
                try:  | 
            
| 792 | 793 | 
                log = MemberActivityInfo.objects.get(activity_id=activity_id)  | 
            
| 793 | 794 | 
                except MemberActivityInfo.DoesNotExist:  | 
            
| 794 | 
                - return response()  | 
            |
| 795 | 
                + return response(MemberActivityStatusCode.ACTIVITY_NOT_FOUND)  | 
            |
| 795 | 796 | 
                 | 
            
| 796 | 797 | 
                     return response(200, 'Get Member Activity Record Details Success', u'获取会员活动详情成功', data={
               | 
            
| 797 | 798 | 
                'log': log.admindetails,  | 
            
                @@ -804,10 +805,10 @@ def member_activity_update(request, administrator):  | 
            ||
| 804 | 805 | 
                     activity_type = int(request.POST.get('activity_type', 0))
               | 
            
| 805 | 806 | 
                     title = request.POST.get('title', '')
               | 
            
| 806 | 807 | 
                     subtitle = request.POST.get('subtitle', '')
               | 
            
| 807 | 
                -    start_date = request.POST.get('start_date', '') or settings.DEFAULT_START_DATE
               | 
            |
| 808 | 
                -    end_date = date = request.POST.get('date', '') or request.POST.get('end_date', '') or settings.DEFAULT_END_DATE
               | 
            |
| 809 | 
                -    start_display_date = request.POST.get('start_display_date', '') or settings.DEFAULT_START_DATE
               | 
            |
| 810 | 
                -    end_display_date = request.POST.get('end_display_date', '') or settings.DEFAULT_END_DATE
               | 
            |
| 808 | 
                +    start_date = tc.to_date(request.POST.get('start_date', '') or settings.DEFAULT_START_DATE)
               | 
            |
| 809 | 
                +    end_date = date = tc.to_date(request.POST.get('date', '') or request.POST.get('end_date', '') or settings.DEFAULT_END_DATE)
               | 
            |
| 810 | 
                +    start_display_date = tc.to_date(request.POST.get('start_display_date', '') or settings.DEFAULT_START_DATE)
               | 
            |
| 811 | 
                +    end_display_date = tc.to_date(request.POST.get('end_display_date', '') or settings.DEFAULT_END_DATE)
               | 
            |
| 811 | 812 | 
                     city = request.POST.get('city', '')
               | 
            
| 812 | 813 | 
                     location = request.POST.get('location', '')
               | 
            
| 813 | 814 | 
                     integral = int(request.POST.get('integral', 0))
               | 
            
                @@ -828,7 +829,7 @@ def member_activity_update(request, administrator):  | 
            ||
| 828 | 829 | 
                try:  | 
            
| 829 | 830 | 
                log = MemberActivityInfo.objects.get(activity_id=activity_id, status=True)  | 
            
| 830 | 831 | 
                except MemberActivityInfo.DoesNotExist:  | 
            
| 831 | 
                - return response()  | 
            |
| 832 | 
                + return response(MemberActivityStatusCode.ACTIVITY_NOT_FOUND)  | 
            |
| 832 | 833 | 
                 | 
            
| 833 | 834 | 
                log.activity_type = activity_type  | 
            
| 834 | 835 | 
                log.title = title  | 
            
                @@ -1110,6 +1111,11 @@ def member_activity_contribute_welfare_unlock(request, administrator):  | 
            ||
| 1110 | 1111 | 
                except MemberActivityContributionInfo.DoesNotExist:  | 
            
| 1111 | 1112 | 
                return response(MemberActivityContributionStatusCode.ACTIVITY_CONTRIBUTION_NOT_FOUND)  | 
            
| 1112 | 1113 | 
                 | 
            
| 1114 | 
                + try:  | 
            |
| 1115 | 
                + welfare = MemberActivityContributionWelfareInfo.objects.get(welfare_id=welfare_id, status=True)  | 
            |
| 1116 | 
                + except MemberActivityContributionWelfareInfo.DoesNotExist:  | 
            |
| 1117 | 
                + return response(MemberActivityContributionWelfareStatusCode.ACTIVITY_CONTRIBUTION_WELFARE_NOT_FOUND)  | 
            |
| 1118 | 
                +  | 
            |
| 1113 | 1119 | 
                MemberActivityContributionWelfareUnlockingInfo.objects.create(  | 
            
| 1114 | 1120 | 
                brand_id=administrator.brand_id,  | 
            
| 1115 | 1121 | 
                admin_id=admin_id,  | 
            
                @@ -1117,6 +1123,8 @@ def member_activity_contribute_welfare_unlock(request, administrator):  | 
            ||
| 1117 | 1123 | 
                activity_id=contribution.activity_id,  | 
            
| 1118 | 1124 | 
                contribution_id=contribution_id,  | 
            
| 1119 | 1125 | 
                welfare_id=welfare_id,  | 
            
| 1126 | 
                + welfare_type=welfare.welfare_type,  | 
            |
| 1127 | 
                + welfare_value=welfare.welfare_value,  | 
            |
| 1120 | 1128 | 
                )  | 
            
| 1121 | 1129 | 
                 | 
            
| 1122 | 1130 | 
                return response(200, 'Unlock Member Activity Contribute Welfare Success', u'解锁会员活动投稿福利成功')  | 
            
                @@ -1246,7 +1254,7 @@ def coupon_detail(request, administrator):  | 
            ||
| 1246 | 1254 | 
                try:  | 
            
| 1247 | 1255 | 
                log = CouponInfo.objects.get(coupon_id=coupon_id)  | 
            
| 1248 | 1256 | 
                except CouponInfo.DoesNotExist:  | 
            
| 1249 | 
                - return response()  | 
            |
| 1257 | 
                + return response(CouponStatusCode.COUPON_NOT_FOUND)  | 
            |
| 1250 | 1258 | 
                 | 
            
| 1251 | 1259 | 
                log = log.admindetails  | 
            
| 1252 | 1260 | 
                 | 
            
                @@ -1299,7 +1307,7 @@ def coupon_update(request, administrator):  | 
            ||
| 1299 | 1307 | 
                try:  | 
            
| 1300 | 1308 | 
                log = CouponInfo.objects.get(coupon_id=coupon_id, status=True)  | 
            
| 1301 | 1309 | 
                except CouponInfo.DoesNotExist:  | 
            
| 1302 | 
                - return response()  | 
            |
| 1310 | 
                + return response(CouponStatusCode.COUPON_NOT_FOUND)  | 
            |
| 1303 | 1311 | 
                 | 
            
| 1304 | 1312 | 
                log.brand_id = administrator.brand_id  | 
            
| 1305 | 1313 | 
                log.coupon_title = coupon_title  | 
            
                @@ -1323,7 +1331,7 @@ def coupon_delete(request, administrator):  | 
            ||
| 1323 | 1331 | 
                try:  | 
            
| 1324 | 1332 | 
                log = CouponInfo.objects.get(coupon_id=coupon_id, status=True)  | 
            
| 1325 | 1333 | 
                except CouponInfo.DoesNotExist:  | 
            
| 1326 | 
                - return response()  | 
            |
| 1334 | 
                + return response(CouponStatusCode.COUPON_NOT_FOUND)  | 
            |
| 1327 | 1335 | 
                 | 
            
| 1328 | 1336 | 
                log.status = False  | 
            
| 1329 | 1337 | 
                log.save()  | 
            
                @@ -1357,7 +1365,7 @@ def member_goods_detail(request, administrator):  | 
            ||
| 1357 | 1365 | 
                try:  | 
            
| 1358 | 1366 | 
                log = GoodsInfo.objects.get(good_id=good_id)  | 
            
| 1359 | 1367 | 
                except GoodsInfo.DoesNotExist:  | 
            
| 1360 | 
                - return response()  | 
            |
| 1368 | 
                + return response(MemberGoodStatusCode.GOOD_NOT_FOUND)  | 
            |
| 1361 | 1369 | 
                 | 
            
| 1362 | 1370 | 
                log = log.admindetails  | 
            
| 1363 | 1371 | 
                 | 
            
                @@ -1382,7 +1390,7 @@ def member_goods_update(request, administrator):  | 
            ||
| 1382 | 1390 | 
                try:  | 
            
| 1383 | 1391 | 
                log = GoodsInfo.objects.get(good_id=good_id, status=True)  | 
            
| 1384 | 1392 | 
                except GoodsInfo.DoesNotExist:  | 
            
| 1385 | 
                - return response()  | 
            |
| 1393 | 
                + return response(MemberGoodStatusCode.GOOD_NOT_FOUND)  | 
            |
| 1386 | 1394 | 
                 | 
            
| 1387 | 1395 | 
                log.title = title  | 
            
| 1388 | 1396 | 
                log.desc = desc  | 
            
                @@ -1519,7 +1527,7 @@ def complement_code_audit(request, administrator):  | 
            ||
| 1519 | 1527 | 
                try:  | 
            
| 1520 | 1528 | 
                user = UserInfo.objects.get(user_id=log.user_id, status=True)  | 
            
| 1521 | 1529 | 
                except UserInfo.DoesNotExist:  | 
            
| 1522 | 
                - return response()  | 
            |
| 1530 | 
                + return response(UserStatusCode.USER_NOT_FOUND)  | 
            |
| 1523 | 1531 | 
                 | 
            
| 1524 | 1532 | 
                # Send template_message  | 
            
| 1525 | 1533 | 
                         data = {
               | 
            
                @@ -13,7 +13,7 @@ from pywe_miniapp import get_shareinfo  | 
            ||
| 13 | 13 | 
                from pywe_storage import RedisStorage  | 
            
| 14 | 14 | 
                from TimeConvert import TimeConvert as tc  | 
            
| 15 | 15 | 
                 | 
            
| 16 | 
                -from account.models import UserInfo  | 
            |
| 16 | 
                +from account.models import UserInfo, UserIntegralIncomeExpensesInfo  | 
            |
| 17 | 17 | 
                from coupon.models import UserCouponInfo  | 
            
| 18 | 18 | 
                from member.models import (GoodsInfo, GoodsOrderInfo, MemberActivityContributionInfo,  | 
            
| 19 | 19 | 
                MemberActivityContributionWelfareUnlockingInfo, MemberActivityGroupShareInfo,  | 
            
                @@ -422,7 +422,7 @@ def activity_signup_info(request):  | 
            ||
| 422 | 422 | 
                try:  | 
            
| 423 | 423 | 
                contribution = MemberActivityContributionInfo.objects.get(user_id=user_id, activity_id=activity_id, content_type=0, status=True)  | 
            
| 424 | 424 | 
                except MemberActivityContributionInfo.DoesNotExist:  | 
            
| 425 | 
                - return response()  | 
            |
| 425 | 
                + return response(MemberActivityContributionStatusCode.ACTIVITY_CONTRIBUTION_NOT_FOUND)  | 
            |
| 426 | 426 | 
                 | 
            
| 427 | 427 | 
                     return response(data={
               | 
            
| 428 | 428 | 
                'signup_info': signup_info.data,  | 
            
                @@ -501,7 +501,7 @@ def activity_group_share(request):  | 
            ||
| 501 | 501 | 
                return response()  | 
            
| 502 | 502 | 
                 | 
            
| 503 | 503 | 
                try:  | 
            
| 504 | 
                - user = UserInfo.objects.get(user_id=share_user_id, status=True)  | 
            |
| 504 | 
                + user = UserInfo.objects.select_for_update().get(user_id=share_user_id, status=True)  | 
            |
| 505 | 505 | 
                except UserInfo.DoesNotExist:  | 
            
| 506 | 506 | 
                return response(UserStatusCode.USER_NOT_FOUND)  | 
            
| 507 | 507 | 
                 | 
            
                @@ -746,12 +746,31 @@ def activity_contribute_welfare_unlocking_handled(request):  | 
            ||
| 746 | 746 | 
                except MemberActivityContributionWelfareUnlockingInfo.DoesNotExist:  | 
            
| 747 | 747 | 
                return response(MemberActivityContributionWelfareUnblockingStatusCode.ACTIVITY_CONTRIBUTION_WELFARE_UNBLOCKING_NOT_FOUND)  | 
            
| 748 | 748 | 
                 | 
            
| 749 | 
                + if unlocking.is_handled:  | 
            |
| 750 | 
                + return response(MemberActivityContributionWelfareUnblockingStatusCode.ACTIVITY_CONTRIBUTION_WELFARE_UNBLOCKING_HAS_HANDLED)  | 
            |
| 751 | 
                +  | 
            |
| 749 | 752 | 
                if user_id != unlocking.user_id:  | 
            
| 750 | 753 | 
                return response(PermissionStatusCode.PERMISSION_DENIED)  | 
            
| 751 | 754 | 
                 | 
            
| 752 | 755 | 
                unlocking.is_handled = True  | 
            
| 753 | 756 | 
                unlocking.save()  | 
            
| 754 | 757 | 
                 | 
            
| 755 | 
                - # TODO: 积分相关逻辑在这里处理?  | 
            |
| 758 | 
                + if unlocking.welfare_type == MemberActivityContributionWelfareUnlockingInfo.WELFARE_INTEGRAL:  | 
            |
| 759 | 
                + try:  | 
            |
| 760 | 
                + user = UserInfo.objects.select_for_update().get(user_id=user_id, status=True)  | 
            |
| 761 | 
                + except UserInfo.DoesNotExist:  | 
            |
| 762 | 
                + return response(UserStatusCode.USER_NOT_FOUND)  | 
            |
| 763 | 
                +  | 
            |
| 764 | 
                + user.integral += unlocking.welfare_value  | 
            |
| 765 | 
                + user.save()  | 
            |
| 766 | 
                +  | 
            |
| 767 | 
                + UserIntegralIncomeExpensesInfo.objects.create(  | 
            |
| 768 | 
                + brand_id=brand_id,  | 
            |
| 769 | 
                + user_id=user_id,  | 
            |
| 770 | 
                + integral_from=UserIntegralIncomeExpensesInfo.MEMBER_ACTIVITY_CONTRIBUTION_WELFARE,  | 
            |
| 771 | 
                + integral=unlocking.welfare_value,  | 
            |
| 772 | 
                + final_integral=user.integral,  | 
            |
| 773 | 
                + remark=unlocking.id,  | 
            |
| 774 | 
                + )  | 
            |
| 756 | 775 | 
                 | 
            
| 757 | 776 | 
                return response(200, 'Update Member Activity Contribute Welfare Unblocking Success', u'处理会员活动投稿福利解锁成功')  | 
            
                @@ -16,7 +16,8 @@ from staff.models import StaffDeleteClerkSaleSubmitLogInfo, StaffDeleteConsumerS  | 
            ||
| 16 | 16 | 
                from statistic.models import (ConsumeModelSaleStatisticInfo, ConsumeSaleStatisticInfo, ConsumeUserStatisticInfo,  | 
            
| 17 | 17 | 
                DistributorSaleStatisticInfo, ModelSaleStatisticInfo, ProvinceSaleStatisticInfo,  | 
            
| 18 | 18 | 
                SaleclerkSaleStatisticInfo, SaleStatisticInfo)  | 
            
| 19 | 
                -from utils.error.errno_utils import AdministratorStatusCode  | 
            |
| 19 | 
                +from utils.error.errno_utils import (AdministratorStatusCode, ProductBrandStatusCode, ProductDistributorStatusCode,  | 
            |
| 20 | 
                + ProductModelStatusCode, SaleclerkStatusCode, UserStatusCode)  | 
            |
| 20 | 21 | 
                 | 
            
| 21 | 22 | 
                 | 
            
| 22 | 23 | 
                def exec_del_clerk_sale_submit(pk, admin_id):  | 
            
                @@ -35,22 +36,22 @@ def exec_del_clerk_sale_submit(pk, admin_id):  | 
            ||
| 35 | 36 | 
                try:  | 
            
| 36 | 37 | 
                brand = BrandInfo.objects.get(pk=ssli.brand_pk)  | 
            
| 37 | 38 | 
                except BrandInfo.DoesNotExist:  | 
            
| 38 | 
                - return response()  | 
            |
| 39 | 
                + return response(ProductBrandStatusCode)  | 
            |
| 39 | 40 | 
                 | 
            
| 40 | 41 | 
                try:  | 
            
| 41 | 42 | 
                model = ModelInfo.objects.get(pk=ssli.model_pk)  | 
            
| 42 | 43 | 
                except ModelInfo.DoesNotExist:  | 
            
| 43 | 
                - return response()  | 
            |
| 44 | 
                + return response(ProductModelStatusCode)  | 
            |
| 44 | 45 | 
                 | 
            
| 45 | 46 | 
                try:  | 
            
| 46 | 47 | 
                clerk = SaleclerkInfo.objects.select_for_update().get(clerk_id=ssli.clerk_id, status=True)  | 
            
| 47 | 48 | 
                except SaleclerkInfo.DoesNotExist:  | 
            
| 48 | 
                - return response()  | 
            |
| 49 | 
                + return response(SaleclerkStatusCode.CLERK_NOT_FOUND)  | 
            |
| 49 | 50 | 
                 | 
            
| 50 | 51 | 
                try:  | 
            
| 51 | 52 | 
                distributor = DistributorInfo.objects.get(distributor_id=clerk.distributor_id)  | 
            
| 52 | 53 | 
                except DistributorInfo.DoesNotExist:  | 
            
| 53 | 
                - return response()  | 
            |
| 54 | 
                + return response(ProductDistributorStatusCode.DISTRIBUTOR_NOT_FOUND)  | 
            |
| 54 | 55 | 
                 | 
            
| 55 | 56 | 
                ymd = str(ssli.ymd)  | 
            
| 56 | 57 | 
                 | 
            
                @@ -280,17 +281,17 @@ def exec_del_consumer_submit(pk, admin_id):  | 
            ||
| 280 | 281 | 
                try:  | 
            
| 281 | 282 | 
                brand = BrandInfo.objects.get(brand_id=ssli.brand_id)  | 
            
| 282 | 283 | 
                except BrandInfo.DoesNotExist:  | 
            
| 283 | 
                - return response()  | 
            |
| 284 | 
                + return response(ProductBrandStatusCode.BRAND_NOT_FOUND)  | 
            |
| 284 | 285 | 
                 | 
            
| 285 | 286 | 
                try:  | 
            
| 286 | 287 | 
                model = ModelInfo.objects.get(model_id=ssli.model_id)  | 
            
| 287 | 288 | 
                except ModelInfo.DoesNotExist:  | 
            
| 288 | 
                - return response()  | 
            |
| 289 | 
                + return response(ProductModelStatusCode.MODEL_NOT_FOUND)  | 
            |
| 289 | 290 | 
                 | 
            
| 290 | 291 | 
                try:  | 
            
| 291 | 292 | 
                user = UserInfo.objects.select_for_update().get(user_id=ssli.user_id)  | 
            
| 292 | 293 | 
                except UserInfo.DoesNotExist:  | 
            
| 293 | 
                - return response()  | 
            |
| 294 | 
                + return response(UserStatusCode.USER_NOT_FOUND)  | 
            |
| 294 | 295 | 
                 | 
            
| 295 | 296 | 
                # 记录删除日志  | 
            
| 296 | 297 | 
                StaffDeleteConsumerSubmitLogInfo.objects.create(  | 
            
                @@ -3,6 +3,7 @@  | 
            ||
| 3 | 3 | 
                import logging  | 
            
| 4 | 4 | 
                import time  | 
            
| 5 | 5 | 
                 | 
            
| 6 | 
                +from django.db import transaction  | 
            |
| 6 | 7 | 
                from django_six import CompatibilityBaseCommand, close_old_connections  | 
            
| 7 | 8 | 
                from TimeConvert import TimeConvert as tc  | 
            
| 8 | 9 | 
                 | 
            
                @@ -42,83 +43,84 @@ class Command(CompatibilityBaseCommand):  | 
            ||
| 42 | 43 | 
                # TODO: Opt by delay execute  | 
            
| 43 | 44 | 
                time.sleep(5)  | 
            
| 44 | 45 | 
                 | 
            
| 45 | 
                - try:  | 
            |
| 46 | 
                - user = UserInfo.objects.get(user_id=user_id)  | 
            |
| 47 | 
                - except UserInfo.DoesNotExist:  | 
            |
| 48 | 
                - continue  | 
            |
| 49 | 
                -  | 
            |
| 50 | 
                - if coupon_id:  | 
            |
| 51 | 
                - # 发放商城兑换券  | 
            |
| 46 | 
                + with transaction.atomic():  | 
            |
| 52 | 47 | 
                try:  | 
            
| 53 | 
                - coupon = CouponInfo.objects.get(coupon_id=coupon_id)  | 
            |
| 54 | 
                - except CouponInfo.DoesNotExist:  | 
            |
| 48 | 
                + user = UserInfo.objects.get(user_id=user_id)  | 
            |
| 49 | 
                + except UserInfo.DoesNotExist:  | 
            |
| 55 | 50 | 
                continue  | 
            
| 56 | 51 | 
                 | 
            
| 57 | 
                - UserCouponInfo.objects.create(  | 
            |
| 58 | 
                - brand_id=coupon.brand_id,  | 
            |
| 59 | 
                - brand_name=coupon.brand_name,  | 
            |
| 60 | 
                - coupon_id=coupon_id,  | 
            |
| 61 | 
                - user_id=user_id,  | 
            |
| 62 | 
                - coupon_title=coupon.coupon_title,  | 
            |
| 63 | 
                - coupon_detail=coupon.coupon_detail,  | 
            |
| 64 | 
                - coupon_value=coupon.coupon_value,  | 
            |
| 65 | 
                - coupon_image=coupon.coupon_image,  | 
            |
| 66 | 
                - coupon_from='INTEGRAL_MALL',  | 
            |
| 67 | 
                - active_at=tc.utc_datetime(),  | 
            |
| 68 | 
                - expire_at=tc.utc_datetime(days=coupon.coupon_valid_period) if coupon.coupon_expire_type == CouponInfo.CHANGED_EXPIRED_TIME else coupon.coupon_expire_at,  | 
            |
| 69 | 
                - coupon_valid_period=coupon.coupon_valid_period,  | 
            |
| 70 | 
                - coupon_limit_model_ids=coupon.coupon_limit_model_ids,  | 
            |
| 71 | 
                - is_coupon_admin_writeoff=coupon.is_coupon_admin_writeoff,  | 
            |
| 72 | 
                - )  | 
            |
| 73 | 
                -  | 
            |
| 74 | 
                - else:  | 
            |
| 75 | 
                - # 发放会员权益  | 
            |
| 76 | 
                - active_at = tc.utc_datetime()  | 
            |
| 77 | 
                - expire_at = tc.utc_datetime(days=365)  | 
            |
| 78 | 
                -  | 
            |
| 79 | 
                - rights = RightInfo.objects.filter(is_send_coupon=True, status=True)  | 
            |
| 80 | 
                - for right in rights:  | 
            |
| 81 | 
                - if user.level == UserInfo.MEMBER_LRC:  | 
            |
| 82 | 
                - coupon_id = right.coupon_level1_id  | 
            |
| 83 | 
                - coupon_num = right.coupon_level1_num  | 
            |
| 84 | 
                - elif user.level == UserInfo.MEMBER_SILVER:  | 
            |
| 85 | 
                - coupon_id = right.coupon_level2_id  | 
            |
| 86 | 
                - coupon_num = right.coupon_level2_num  | 
            |
| 87 | 
                - elif user.level == UserInfo.MEMBER_GOLD:  | 
            |
| 88 | 
                - coupon_id = right.coupon_level3_id  | 
            |
| 89 | 
                - coupon_num = right.coupon_level3_num  | 
            |
| 90 | 
                - elif user.level == UserInfo.MEMBER_WHITE_GOLD:  | 
            |
| 91 | 
                - coupon_id = right.coupon_level4_id  | 
            |
| 92 | 
                - coupon_num = right.coupon_level4_num  | 
            |
| 93 | 
                - elif user.level == UserInfo.MEMBER_BLACK_GOLD:  | 
            |
| 94 | 
                - coupon_id = right.coupon_level5_id  | 
            |
| 95 | 
                - coupon_num = right.coupon_level5_num  | 
            |
| 96 | 
                -  | 
            |
| 97 | 
                - if not coupon_id:  | 
            |
| 98 | 
                - continue  | 
            |
| 99 | 
                -  | 
            |
| 52 | 
                + if coupon_id:  | 
            |
| 53 | 
                + # 发放商城兑换券  | 
            |
| 100 | 54 | 
                try:  | 
            
| 101 | 55 | 
                coupon = CouponInfo.objects.get(coupon_id=coupon_id)  | 
            
| 102 | 56 | 
                except CouponInfo.DoesNotExist:  | 
            
| 103 | 57 | 
                continue  | 
            
| 104 | 58 | 
                 | 
            
| 105 | 
                - for _ in range(right.coupon_num or coupon_num):  | 
            |
| 106 | 
                - UserCouponInfo.objects.create(  | 
            |
| 107 | 
                - brand_id=coupon.brand_id,  | 
            |
| 108 | 
                - brand_name=coupon.brand_name,  | 
            |
| 109 | 
                - coupon_id=coupon_id,  | 
            |
| 110 | 
                - user_id=user_id,  | 
            |
| 111 | 
                - coupon_title=coupon.coupon_title,  | 
            |
| 112 | 
                - coupon_detail=coupon.coupon_detail,  | 
            |
| 113 | 
                - coupon_value=coupon.coupon_value,  | 
            |
| 114 | 
                - coupon_image=coupon.coupon_image,  | 
            |
| 115 | 
                - active_at=active_at,  | 
            |
| 116 | 
                - expire_at=expire_at,  | 
            |
| 117 | 
                - coupon_valid_period=coupon.coupon_valid_period,  | 
            |
| 118 | 
                - coupon_limit_model_ids=coupon.coupon_limit_model_ids,  | 
            |
| 119 | 
                - )  | 
            |
| 120 | 
                -  | 
            |
| 121 | 
                - user.coupon_expire_at = expire_at  | 
            |
| 122 | 
                - user.save()  | 
            |
| 59 | 
                + UserCouponInfo.objects.create(  | 
            |
| 60 | 
                + brand_id=coupon.brand_id,  | 
            |
| 61 | 
                + brand_name=coupon.brand_name,  | 
            |
| 62 | 
                + coupon_id=coupon_id,  | 
            |
| 63 | 
                + user_id=user_id,  | 
            |
| 64 | 
                + coupon_title=coupon.coupon_title,  | 
            |
| 65 | 
                + coupon_detail=coupon.coupon_detail,  | 
            |
| 66 | 
                + coupon_value=coupon.coupon_value,  | 
            |
| 67 | 
                + coupon_image=coupon.coupon_image,  | 
            |
| 68 | 
                + coupon_from='INTEGRAL_MALL',  | 
            |
| 69 | 
                + active_at=tc.utc_datetime(),  | 
            |
| 70 | 
                + expire_at=tc.utc_datetime(days=coupon.coupon_valid_period) if coupon.coupon_expire_type == CouponInfo.CHANGED_EXPIRED_TIME else coupon.coupon_expire_at,  | 
            |
| 71 | 
                + coupon_valid_period=coupon.coupon_valid_period,  | 
            |
| 72 | 
                + coupon_limit_model_ids=coupon.coupon_limit_model_ids,  | 
            |
| 73 | 
                + is_coupon_admin_writeoff=coupon.is_coupon_admin_writeoff,  | 
            |
| 74 | 
                + )  | 
            |
| 75 | 
                +  | 
            |
| 76 | 
                + else:  | 
            |
| 77 | 
                + # 发放会员权益  | 
            |
| 78 | 
                + active_at = tc.utc_datetime()  | 
            |
| 79 | 
                + expire_at = tc.utc_datetime(days=365)  | 
            |
| 80 | 
                +  | 
            |
| 81 | 
                + rights = RightInfo.objects.filter(is_send_coupon=True, status=True)  | 
            |
| 82 | 
                + for right in rights:  | 
            |
| 83 | 
                + if user.level == UserInfo.MEMBER_LRC:  | 
            |
| 84 | 
                + coupon_id = right.coupon_level1_id  | 
            |
| 85 | 
                + coupon_num = right.coupon_level1_num  | 
            |
| 86 | 
                + elif user.level == UserInfo.MEMBER_SILVER:  | 
            |
| 87 | 
                + coupon_id = right.coupon_level2_id  | 
            |
| 88 | 
                + coupon_num = right.coupon_level2_num  | 
            |
| 89 | 
                + elif user.level == UserInfo.MEMBER_GOLD:  | 
            |
| 90 | 
                + coupon_id = right.coupon_level3_id  | 
            |
| 91 | 
                + coupon_num = right.coupon_level3_num  | 
            |
| 92 | 
                + elif user.level == UserInfo.MEMBER_WHITE_GOLD:  | 
            |
| 93 | 
                + coupon_id = right.coupon_level4_id  | 
            |
| 94 | 
                + coupon_num = right.coupon_level4_num  | 
            |
| 95 | 
                + elif user.level == UserInfo.MEMBER_BLACK_GOLD:  | 
            |
| 96 | 
                + coupon_id = right.coupon_level5_id  | 
            |
| 97 | 
                + coupon_num = right.coupon_level5_num  | 
            |
| 98 | 
                +  | 
            |
| 99 | 
                + if not coupon_id:  | 
            |
| 100 | 
                + continue  | 
            |
| 101 | 
                +  | 
            |
| 102 | 
                + try:  | 
            |
| 103 | 
                + coupon = CouponInfo.objects.get(coupon_id=coupon_id)  | 
            |
| 104 | 
                + except CouponInfo.DoesNotExist:  | 
            |
| 105 | 
                + continue  | 
            |
| 106 | 
                +  | 
            |
| 107 | 
                + for _ in range(right.coupon_num or coupon_num):  | 
            |
| 108 | 
                + UserCouponInfo.objects.create(  | 
            |
| 109 | 
                + brand_id=coupon.brand_id,  | 
            |
| 110 | 
                + brand_name=coupon.brand_name,  | 
            |
| 111 | 
                + coupon_id=coupon_id,  | 
            |
| 112 | 
                + user_id=user_id,  | 
            |
| 113 | 
                + coupon_title=coupon.coupon_title,  | 
            |
| 114 | 
                + coupon_detail=coupon.coupon_detail,  | 
            |
| 115 | 
                + coupon_value=coupon.coupon_value,  | 
            |
| 116 | 
                + coupon_image=coupon.coupon_image,  | 
            |
| 117 | 
                + active_at=active_at,  | 
            |
| 118 | 
                + expire_at=expire_at,  | 
            |
| 119 | 
                + coupon_valid_period=coupon.coupon_valid_period,  | 
            |
| 120 | 
                + coupon_limit_model_ids=coupon.coupon_limit_model_ids,  | 
            |
| 121 | 
                + )  | 
            |
| 122 | 
                +  | 
            |
| 123 | 
                + user.coupon_expire_at = expire_at  | 
            |
| 124 | 
                + user.save()  | 
            |
| 123 | 125 | 
                 | 
            
| 124 | 126 | 
                close_old_connections()  | 
            
                @@ -2,6 +2,7 @@  | 
            ||
| 2 | 2 | 
                 | 
            
| 3 | 3 | 
                import logging  | 
            
| 4 | 4 | 
                 | 
            
| 5 | 
                +from django.db import transaction  | 
            |
| 5 | 6 | 
                from django_six import CompatibilityBaseCommand, close_old_connections  | 
            
| 6 | 7 | 
                from TimeConvert import TimeConvert as tc  | 
            
| 7 | 8 | 
                 | 
            
                @@ -37,58 +38,59 @@ class Command(CompatibilityBaseCommand):  | 
            ||
| 37 | 38 | 
                             brand_id = v.get('brand_id', '')
               | 
            
| 38 | 39 | 
                             user_id = v.get('user_id', '')
               | 
            
| 39 | 40 | 
                 | 
            
| 40 | 
                - try:  | 
            |
| 41 | 
                - user = UserInfo.objects.get(user_id=user_id)  | 
            |
| 42 | 
                - except UserInfo.DoesNotExist:  | 
            |
| 43 | 
                - continue  | 
            |
| 44 | 
                -  | 
            |
| 45 | 
                - active_at = user.coupon_expire_at  | 
            |
| 46 | 
                - expire_at = tc.utc_datetime(user.coupon_expire_at, days=365)  | 
            |
| 47 | 
                -  | 
            |
| 48 | 
                - # 发放会员权益  | 
            |
| 49 | 
                - rights = RightInfo.objects.filter(is_send_coupon=True, is_continue_send_coupon=True, status=True)  | 
            |
| 50 | 
                - for right in rights:  | 
            |
| 51 | 
                - if user.level == UserInfo.MEMBER_LRC:  | 
            |
| 52 | 
                - coupon_id = right.coupon_level1_id  | 
            |
| 53 | 
                - coupon_num = right.coupon_level1_num  | 
            |
| 54 | 
                - elif user.level == UserInfo.MEMBER_SILVER:  | 
            |
| 55 | 
                - coupon_id = right.coupon_level2_id  | 
            |
| 56 | 
                - coupon_num = right.coupon_level2_num  | 
            |
| 57 | 
                - elif user.level == UserInfo.MEMBER_GOLD:  | 
            |
| 58 | 
                - coupon_id = right.coupon_level3_id  | 
            |
| 59 | 
                - coupon_num = right.coupon_level3_num  | 
            |
| 60 | 
                - elif user.level == UserInfo.MEMBER_WHITE_GOLD:  | 
            |
| 61 | 
                - coupon_id = right.coupon_level4_id  | 
            |
| 62 | 
                - coupon_num = right.coupon_level4_num  | 
            |
| 63 | 
                - elif user.level == UserInfo.MEMBER_BLACK_GOLD:  | 
            |
| 64 | 
                - coupon_id = right.coupon_level5_id  | 
            |
| 65 | 
                - coupon_num = right.coupon_level5_num  | 
            |
| 66 | 
                -  | 
            |
| 67 | 
                - if not coupon_id:  | 
            |
| 68 | 
                - continue  | 
            |
| 69 | 
                -  | 
            |
| 41 | 
                + with transaction.atomic():  | 
            |
| 70 | 42 | 
                try:  | 
            
| 71 | 
                - coupon = CouponInfo.objects.get(coupon_id=coupon_id)  | 
            |
| 72 | 
                - except CouponInfo.DoesNotExist:  | 
            |
| 43 | 
                + user = UserInfo.objects.get(user_id=user_id)  | 
            |
| 44 | 
                + except UserInfo.DoesNotExist:  | 
            |
| 73 | 45 | 
                continue  | 
            
| 74 | 46 | 
                 | 
            
| 75 | 
                - for _ in range(right.coupon_num or coupon_num):  | 
            |
| 76 | 
                - UserCouponInfo.objects.create(  | 
            |
| 77 | 
                - brand_id=coupon.brand_id,  | 
            |
| 78 | 
                - brand_name=coupon.brand_name,  | 
            |
| 79 | 
                - coupon_id=coupon_id,  | 
            |
| 80 | 
                - user_id=user_id,  | 
            |
| 81 | 
                - coupon_title=coupon.coupon_title,  | 
            |
| 82 | 
                - coupon_detail=coupon.coupon_detail,  | 
            |
| 83 | 
                - coupon_value=coupon.coupon_value,  | 
            |
| 84 | 
                - coupon_image=coupon.coupon_image,  | 
            |
| 85 | 
                - active_at=active_at,  | 
            |
| 86 | 
                - expire_at=expire_at,  | 
            |
| 87 | 
                - coupon_valid_period=coupon.coupon_valid_period,  | 
            |
| 88 | 
                - coupon_limit_model_ids=coupon.coupon_limit_model_ids,  | 
            |
| 89 | 
                - )  | 
            |
| 90 | 
                -  | 
            |
| 91 | 
                - user.coupon_expire_at = expire_at  | 
            |
| 92 | 
                - user.save()  | 
            |
| 47 | 
                + active_at = user.coupon_expire_at  | 
            |
| 48 | 
                + expire_at = tc.utc_datetime(user.coupon_expire_at, days=365)  | 
            |
| 49 | 
                +  | 
            |
| 50 | 
                + # 发放会员权益  | 
            |
| 51 | 
                + rights = RightInfo.objects.filter(is_send_coupon=True, is_continue_send_coupon=True, status=True)  | 
            |
| 52 | 
                + for right in rights:  | 
            |
| 53 | 
                + if user.level == UserInfo.MEMBER_LRC:  | 
            |
| 54 | 
                + coupon_id = right.coupon_level1_id  | 
            |
| 55 | 
                + coupon_num = right.coupon_level1_num  | 
            |
| 56 | 
                + elif user.level == UserInfo.MEMBER_SILVER:  | 
            |
| 57 | 
                + coupon_id = right.coupon_level2_id  | 
            |
| 58 | 
                + coupon_num = right.coupon_level2_num  | 
            |
| 59 | 
                + elif user.level == UserInfo.MEMBER_GOLD:  | 
            |
| 60 | 
                + coupon_id = right.coupon_level3_id  | 
            |
| 61 | 
                + coupon_num = right.coupon_level3_num  | 
            |
| 62 | 
                + elif user.level == UserInfo.MEMBER_WHITE_GOLD:  | 
            |
| 63 | 
                + coupon_id = right.coupon_level4_id  | 
            |
| 64 | 
                + coupon_num = right.coupon_level4_num  | 
            |
| 65 | 
                + elif user.level == UserInfo.MEMBER_BLACK_GOLD:  | 
            |
| 66 | 
                + coupon_id = right.coupon_level5_id  | 
            |
| 67 | 
                + coupon_num = right.coupon_level5_num  | 
            |
| 68 | 
                +  | 
            |
| 69 | 
                + if not coupon_id:  | 
            |
| 70 | 
                + continue  | 
            |
| 71 | 
                +  | 
            |
| 72 | 
                + try:  | 
            |
| 73 | 
                + coupon = CouponInfo.objects.get(coupon_id=coupon_id)  | 
            |
| 74 | 
                + except CouponInfo.DoesNotExist:  | 
            |
| 75 | 
                + continue  | 
            |
| 76 | 
                +  | 
            |
| 77 | 
                + for _ in range(right.coupon_num or coupon_num):  | 
            |
| 78 | 
                + UserCouponInfo.objects.create(  | 
            |
| 79 | 
                + brand_id=coupon.brand_id,  | 
            |
| 80 | 
                + brand_name=coupon.brand_name,  | 
            |
| 81 | 
                + coupon_id=coupon_id,  | 
            |
| 82 | 
                + user_id=user_id,  | 
            |
| 83 | 
                + coupon_title=coupon.coupon_title,  | 
            |
| 84 | 
                + coupon_detail=coupon.coupon_detail,  | 
            |
| 85 | 
                + coupon_value=coupon.coupon_value,  | 
            |
| 86 | 
                + coupon_image=coupon.coupon_image,  | 
            |
| 87 | 
                + active_at=active_at,  | 
            |
| 88 | 
                + expire_at=expire_at,  | 
            |
| 89 | 
                + coupon_valid_period=coupon.coupon_valid_period,  | 
            |
| 90 | 
                + coupon_limit_model_ids=coupon.coupon_limit_model_ids,  | 
            |
| 91 | 
                + )  | 
            |
| 92 | 
                +  | 
            |
| 93 | 
                + user.coupon_expire_at = expire_at  | 
            |
| 94 | 
                + user.save()  | 
            |
| 93 | 95 | 
                 | 
            
| 94 | 96 | 
                close_old_connections()  | 
            
                @@ -110,7 +110,7 @@ class MemberActivityContributionWelfareInfoAdmin(admin.ModelAdmin):  | 
            ||
| 110 | 110 | 
                 | 
            
| 111 | 111 | 
                 | 
            
| 112 | 112 | 
                class MemberActivityContributionWelfareUnlockingInfoAdmin(admin.ModelAdmin):  | 
            
| 113 | 
                -    list_display = ('unlocking_id', 'admin_id', 'user_id', 'activity_id', 'contribution_id', 'welfare_id', 'name', 'phone', 'address', 'tracking_number', 'is_handled', 'status', 'created_at', 'updated_at')
               | 
            |
| 113 | 
                +    list_display = ('unlocking_id', 'admin_id', 'user_id', 'activity_id', 'contribution_id', 'welfare_id', 'welfare_type', 'welfare_value', 'name', 'phone', 'address', 'tracking_number', 'is_handled', 'status', 'created_at', 'updated_at')
               | 
            |
| 114 | 114 | 
                     list_filter = ('admin_id', 'activity_id', 'welfare_id', 'is_handled', 'status')
               | 
            
| 115 | 115 | 
                 | 
            
| 116 | 116 | 
                 | 
            
                @@ -0,0 +1,19 @@  | 
            ||
| 1 | 
                +# -*- coding: utf-8 -*-  | 
            |
| 2 | 
                +# Generated by Django 3.2.16 on 2022-10-27 10:38  | 
            |
| 3 | 
                +  | 
            |
| 4 | 
                +from django.db import migrations, models  | 
            |
| 5 | 
                +  | 
            |
| 6 | 
                +  | 
            |
| 7 | 
                +class Migration(migrations.Migration):  | 
            |
| 8 | 
                +  | 
            |
| 9 | 
                + dependencies = [  | 
            |
| 10 | 
                +        ('member', '0045_auto_20221026_2102'),
               | 
            |
| 11 | 
                + ]  | 
            |
| 12 | 
                +  | 
            |
| 13 | 
                + operations = [  | 
            |
| 14 | 
                + migrations.AddField(  | 
            |
| 15 | 
                + model_name='memberactivitycontributionwelfareunlockinginfo',  | 
            |
| 16 | 
                + name='welfare_value',  | 
            |
| 17 | 
                + field=models.IntegerField(default=0, help_text='福利数量', verbose_name='welfare_value'),  | 
            |
| 18 | 
                + ),  | 
            |
| 19 | 
                + ]  | 
            
                @@ -0,0 +1,19 @@  | 
            ||
| 1 | 
                +# -*- coding: utf-8 -*-  | 
            |
| 2 | 
                +# Generated by Django 3.2.16 on 2022-10-27 10:46  | 
            |
| 3 | 
                +  | 
            |
| 4 | 
                +from django.db import migrations, models  | 
            |
| 5 | 
                +  | 
            |
| 6 | 
                +  | 
            |
| 7 | 
                +class Migration(migrations.Migration):  | 
            |
| 8 | 
                +  | 
            |
| 9 | 
                + dependencies = [  | 
            |
| 10 | 
                +        ('member', '0046_memberactivitycontributionwelfareunlockinginfo_welfare_value'),
               | 
            |
| 11 | 
                + ]  | 
            |
| 12 | 
                +  | 
            |
| 13 | 
                + operations = [  | 
            |
| 14 | 
                + migrations.AddField(  | 
            |
| 15 | 
                + model_name='memberactivitycontributionwelfareunlockinginfo',  | 
            |
| 16 | 
                + name='welfare_type',  | 
            |
| 17 | 
                + field=models.IntegerField(choices=[(0, '实物'), (1, '积分'), (2, '虚拟')], db_index=True, default=0, help_text='福利类型', verbose_name='welfare_type'),  | 
            |
| 18 | 
                + ),  | 
            |
| 19 | 
                + ]  | 
            
                @@ -795,6 +795,7 @@ class MemberActivityContributionWelfareInfo(BaseModelMixin, BrandInfoMixin):  | 
            ||
| 795 | 795 | 
                 | 
            
| 796 | 796 | 
                 | 
            
| 797 | 797 | 
                class MemberActivityContributionWelfareUnlockingInfo(BaseModelMixin, BrandInfoMixin):  | 
            
| 798 | 
                + WELFARE_INTEGRAL = 1  | 
            |
| 798 | 799 | 
                WELFARE_TYPE = (  | 
            
| 799 | 800 | 
                (0, u'实物'),  | 
            
| 800 | 801 | 
                (1, u'积分'),  | 
            
                @@ -811,6 +812,8 @@ class MemberActivityContributionWelfareUnlockingInfo(BaseModelMixin, BrandInfoMi  | 
            ||
| 811 | 812 | 
                contribution_id = models.CharField(_(u'contribution_id'), max_length=32, blank=True, null=True, help_text=u'投稿唯一标识', db_index=True)  | 
            
| 812 | 813 | 
                 | 
            
| 813 | 814 | 
                welfare_id = models.CharField(_(u'welfare_id'), max_length=32, blank=True, null=True, help_text=u'福利唯一标识', db_index=True)  | 
            
| 815 | 
                + welfare_type = models.IntegerField(_(u'welfare_type'), choices=WELFARE_TYPE, default=0, help_text=u'福利类型', db_index=True)  | 
            |
| 816 | 
                + welfare_value = models.IntegerField(_(u'welfare_value'), default=0, help_text=_(u'福利数量'))  | 
            |
| 814 | 817 | 
                 | 
            
| 815 | 818 | 
                name = models.CharField(_(u'name'), max_length=255, blank=True, null=True, help_text=u'姓名')  | 
            
| 816 | 819 | 
                phone = models.CharField(_(u'phone'), max_length=255, blank=True, null=True, help_text=u'电话')  | 
            
                @@ -318,19 +318,20 @@ def user_integral_add(request):  | 
            ||
| 318 | 318 | 
                return response(ProductBrandStatusCode.BRAND_NOT_MATCH)  | 
            
| 319 | 319 | 
                 | 
            
| 320 | 320 | 
                try:  | 
            
| 321 | 
                - user = UserInfo.objects.get(user_id=user_id, status=True)  | 
            |
| 321 | 
                + user = UserInfo.objects.select_for_update().get(user_id=user_id, status=True)  | 
            |
| 322 | 322 | 
                except UserInfo.DoesNotExist:  | 
            
| 323 | 323 | 
                return response(UserStatusCode.USER_NOT_FOUND)  | 
            
| 324 | 324 | 
                 | 
            
| 325 | 
                + user.integral += integral  | 
            |
| 326 | 
                + user.save()  | 
            |
| 327 | 
                +  | 
            |
| 325 | 328 | 
                UserIntegralIncomeExpensesInfo.objects.create(  | 
            
| 326 | 329 | 
                brand_id=brand_id,  | 
            
| 327 | 330 | 
                user_id=user_id,  | 
            
| 328 | 331 | 
                integral_from=UserIntegralIncomeExpensesInfo.CONTRIBUTE,  | 
            
| 329 | 332 | 
                integral=integral,  | 
            
| 330 | 
                - remark=remark  | 
            |
| 333 | 
                + final_integral=user.integral,  | 
            |
| 334 | 
                + remark=remark,  | 
            |
| 331 | 335 | 
                )  | 
            
| 332 | 336 | 
                 | 
            
| 333 | 
                - user.integral += integral  | 
            |
| 334 | 
                - user.save()  | 
            |
| 335 | 
                -  | 
            |
| 336 | 337 | 
                return response(200, 'Add User Integral Success', u'添加用户投稿积分成功')  | 
            
                @@ -8,6 +8,78 @@ class ParamStatusCode(BaseStatusCode):  | 
            ||
| 8 | 8 | 
                PARAM_NOT_FOUND = StatusCodeField(400000, 'Param Not Found', description=u'参数不存在')  | 
            
| 9 | 9 | 
                 | 
            
| 10 | 10 | 
                 | 
            
| 11 | 
                +class PermissionStatusCode(BaseStatusCode):  | 
            |
| 12 | 
                + """ 4099xx 权限相关错误码 """  | 
            |
| 13 | 
                + PERMISSION_DENIED = StatusCodeField(409900, 'Permission Denied', description=u'权限不足')  | 
            |
| 14 | 
                +  | 
            |
| 15 | 
                +  | 
            |
| 16 | 
                +class AdministratorStatusCode(BaseStatusCode):  | 
            |
| 17 | 
                + """ 操作员相关错误码 4002xx """  | 
            |
| 18 | 
                + ADMINISTRATOR_NOT_FOUND = StatusCodeField(400201, 'Administrator Not Found', description=u'管理员不存在')  | 
            |
| 19 | 
                + ADMINISTRATOR_PERMISSION_DENIED = StatusCodeField(508002, 'Administrator Permission Denied', description=u'管理员权限不足')  | 
            |
| 20 | 
                +  | 
            |
| 21 | 
                + # 密码  | 
            |
| 22 | 
                + ADMINISTRATOR_PASSWORD_ERROR = StatusCodeField(400202, 'Administrator Password Error', description=u'管理员密码错误')  | 
            |
| 23 | 
                + # 手机号  | 
            |
| 24 | 
                + ADMINISTRATOR_PHONE_ALREADY_EXISTS = StatusCodeField(400205, 'Administrator Phone Already Exists', description=u'管理员手机号已经存在')  | 
            |
| 25 | 
                + # 状态  | 
            |
| 26 | 
                + ADMINISTRATOR_NOT_ACTIVATED = StatusCodeField(400215, 'Administrator Not Activated', description=u'管理员未激活')  | 
            |
| 27 | 
                + ADMINISTRATOR_HAS_DISABLED = StatusCodeField(400216, 'Administrator Has Disabled', description=u'管理员已禁用')  | 
            |
| 28 | 
                + ADMINISTRATOR_HAS_DELETED = StatusCodeField(400217, 'Administrator Has Deleted', description=u'管理员已删除')  | 
            |
| 29 | 
                + # 管理员  | 
            |
| 30 | 
                + MAINTENANCE_NOT_FOUND = StatusCodeField(400251, 'Maintenance Not Found', description=u'核销员不存在')  | 
            |
| 31 | 
                +  | 
            |
| 32 | 
                +  | 
            |
| 33 | 
                +class OperatorStatusCode(BaseStatusCode):  | 
            |
| 34 | 
                + """ 操作员相关错误码 4003xx """  | 
            |
| 35 | 
                + OPERATOR_NOT_FOUND = StatusCodeField(400301, 'Operator Not Found', description=u'操作员不存在')  | 
            |
| 36 | 
                + # 密码  | 
            |
| 37 | 
                + OPERATOR_PASSWORD_ERROR = StatusCodeField(400302, 'Operator Password Error', description=u'操作员密码错误')  | 
            |
| 38 | 
                + # 手机号  | 
            |
| 39 | 
                + OPERATOR_PHONE_ALREADY_EXISTS = StatusCodeField(400305, 'Operator Phone Already Exists', description=u'操作员手机号已经存在')  | 
            |
| 40 | 
                + # 状态  | 
            |
| 41 | 
                + OPERATOR_NOT_ACTIVATED = StatusCodeField(400315, 'Operator Not Activated', description=u'操作员未激活')  | 
            |
| 42 | 
                + OPERATOR_HAS_DISABLED = StatusCodeField(400316, 'Operator Has Disabled', description=u'操作员已禁用')  | 
            |
| 43 | 
                + OPERATOR_HAS_DELETED = StatusCodeField(400317, 'Operator Has Deleted', description=u'操作员已删除')  | 
            |
| 44 | 
                +  | 
            |
| 45 | 
                +  | 
            |
| 46 | 
                +class UserStatusCode(BaseStatusCode):  | 
            |
| 47 | 
                + """ 用户相关错误码 4005xx """  | 
            |
| 48 | 
                + USER_NOT_FOUND = StatusCodeField(400501, 'User Not Found', description=u'用户不存在')  | 
            |
| 49 | 
                + USER_PASSWORD_ERROR = StatusCodeField(400502, 'User Password Error', description=u'用户密码错误')  | 
            |
| 50 | 
                + USERNAME_HAS_REGISTERED = StatusCodeField(400503, 'Username Has Registered', description=u'用户名已注册')  | 
            |
| 51 | 
                + # 游客  | 
            |
| 52 | 
                + GUEST_NOT_ALLOWED = StatusCodeField(400511, 'Guest Not ALLOWED', description=u'游客登录未开启')  | 
            |
| 53 | 
                + # 身份  | 
            |
| 54 | 
                + USER_NOT_LENSMAN = StatusCodeField(400521, 'User Not Lensman', description=u'用户非摄影师')  | 
            |
| 55 | 
                + USER_NOT_TOURGUIDE = StatusCodeField(400522, 'User Not Tourguide', description=u'用户非导游')  | 
            |
| 56 | 
                +  | 
            |
| 57 | 
                +  | 
            |
| 58 | 
                +class PhoneStatusCode(BaseStatusCode):  | 
            |
| 59 | 
                + """ 手机相关错误码 4006xx """  | 
            |
| 60 | 
                + PHONE_NOT_FOUND = StatusCodeField(400601, 'Phone Not Found', description=u'手机不存在')  | 
            |
| 61 | 
                +  | 
            |
| 62 | 
                +  | 
            |
| 63 | 
                +class WechatStatusCode(BaseStatusCode):  | 
            |
| 64 | 
                + """ 微信相关错误码 4007xx """  | 
            |
| 65 | 
                + WECHAT_NOT_FOUND = StatusCodeField(400701, 'Wechat Not Found', description=u'微信不存在')  | 
            |
| 66 | 
                + UNIONID_NOT_FOUND = StatusCodeField(400702, 'Unionid Not Found', description=u'微信 UNIONID 不存在')  | 
            |
| 67 | 
                + OPENID_NOT_FOUND = StatusCodeField(400703, 'OPENID Not Found', description=u'微信 OPENID 不存在')  | 
            |
| 68 | 
                +  | 
            |
| 69 | 
                +  | 
            |
| 70 | 
                +class ScreenStatusCode(BaseStatusCode):  | 
            |
| 71 | 
                + """ 群组/团相关错误码 4030xx """  | 
            |
| 72 | 
                + QRCODE_NOT_SCAN = StatusCodeField(403001, 'QRCode Not Scan', description=u'二维码未扫描')  | 
            |
| 73 | 
                +  | 
            |
| 74 | 
                +  | 
            |
| 75 | 
                +class CouponStatusCode(BaseStatusCode):  | 
            |
| 76 | 
                + """ 4050xx 优惠劵相关错误码 """  | 
            |
| 77 | 
                + COUPON_NOT_FOUND = StatusCodeField(405001, 'Coupon Not Found', description=u'劵不存在')  | 
            |
| 78 | 
                + COUPON_EXPIRED = StatusCodeField(405002, 'Coupon Expired', description=u'劵已过期')  | 
            |
| 79 | 
                + COUPON_PERMISSION_DENIED = StatusCodeField(405003, 'Permission Denied', description=u'核销劵权限不足')  | 
            |
| 80 | 
                + COUPON_HAS_USED = StatusCodeField(405004, 'Coupon Has Used', description=u'劵已核销')  | 
            |
| 81 | 
                +  | 
            |
| 82 | 
                +  | 
            |
| 11 | 83 | 
                class SaleclerkStatusCode(BaseStatusCode):  | 
            
| 12 | 84 | 
                """ 店员相关错误码 5001xx """  | 
            
| 13 | 85 | 
                CLERK_NOT_FOUND = StatusCodeField(500101, 'Clerk Not Found', description=u'店员不存在')  | 
            
                @@ -107,7 +179,8 @@ class MemberActivityContributionWelfareStatusCode(BaseStatusCode):  | 
            ||
| 107 | 179 | 
                 | 
            
| 108 | 180 | 
                class MemberActivityContributionWelfareUnblockingStatusCode(BaseStatusCode):  | 
            
| 109 | 181 | 
                """ 会员活动投稿福利相关错误码 5039xx """  | 
            
| 110 | 
                - ACTIVITY_CONTRIBUTION_WELFARE_UNBLOCKING_NOT_FOUND = StatusCodeField(503999, 'Activity Contribution Welfare Unblocking Not Found', description=u'活动投稿福利解锁不存在')  | 
            |
| 182 | 
                + ACTIVITY_CONTRIBUTION_WELFARE_UNBLOCKING_NOT_FOUND = StatusCodeField(503901, 'Activity Contribution Welfare Unblocking Not Found', description=u'活动投稿福利解锁不存在')  | 
            |
| 183 | 
                + ACTIVITY_CONTRIBUTION_WELFARE_UNBLOCKING_HAS_HANDLED = StatusCodeField(503902, 'Activity Contribution Welfare Unblocking Has Handled', description=u'活动投稿福利解锁已处理')  | 
            |
| 111 | 184 | 
                 | 
            
| 112 | 185 | 
                 | 
            
| 113 | 186 | 
                class MemberCouponStatusCode(BaseStatusCode):  | 
            
                @@ -138,75 +211,3 @@ class MaintenanceStatusCode(BaseStatusCode):  | 
            ||
| 138 | 211 | 
                """ 维修相关错误码 5080xx """  | 
            
| 139 | 212 | 
                MAINTENACE_NOT_FOUND = StatusCodeField(508001, 'Maintenance Not Found', description=u'维修不存在')  | 
            
| 140 | 213 | 
                MAINTENACE_PERMISSION_DENIED = StatusCodeField(508002, 'Maintenance Permission Denied', description=u'维修权限不足')  | 
            
| 141 | 
                -  | 
            |
| 142 | 
                -  | 
            |
| 143 | 
                -class AdministratorStatusCode(BaseStatusCode):  | 
            |
| 144 | 
                - """ 操作员相关错误码 4002xx """  | 
            |
| 145 | 
                - ADMINISTRATOR_NOT_FOUND = StatusCodeField(400201, 'Administrator Not Found', description=u'管理员不存在')  | 
            |
| 146 | 
                - ADMINISTRATOR_PERMISSION_DENIED = StatusCodeField(508002, 'Administrator Permission Denied', description=u'管理员权限不足')  | 
            |
| 147 | 
                -  | 
            |
| 148 | 
                - # 密码  | 
            |
| 149 | 
                - ADMINISTRATOR_PASSWORD_ERROR = StatusCodeField(400202, 'Administrator Password Error', description=u'管理员密码错误')  | 
            |
| 150 | 
                - # 手机号  | 
            |
| 151 | 
                - ADMINISTRATOR_PHONE_ALREADY_EXISTS = StatusCodeField(400205, 'Administrator Phone Already Exists', description=u'管理员手机号已经存在')  | 
            |
| 152 | 
                - # 状态  | 
            |
| 153 | 
                - ADMINISTRATOR_NOT_ACTIVATED = StatusCodeField(400215, 'Administrator Not Activated', description=u'管理员未激活')  | 
            |
| 154 | 
                - ADMINISTRATOR_HAS_DISABLED = StatusCodeField(400216, 'Administrator Has Disabled', description=u'管理员已禁用')  | 
            |
| 155 | 
                - ADMINISTRATOR_HAS_DELETED = StatusCodeField(400217, 'Administrator Has Deleted', description=u'管理员已删除')  | 
            |
| 156 | 
                - # 管理员  | 
            |
| 157 | 
                - MAINTENANCE_NOT_FOUND = StatusCodeField(400251, 'Maintenance Not Found', description=u'核销员不存在')  | 
            |
| 158 | 
                -  | 
            |
| 159 | 
                -  | 
            |
| 160 | 
                -class OperatorStatusCode(BaseStatusCode):  | 
            |
| 161 | 
                - """ 操作员相关错误码 4003xx """  | 
            |
| 162 | 
                - OPERATOR_NOT_FOUND = StatusCodeField(400301, 'Operator Not Found', description=u'操作员不存在')  | 
            |
| 163 | 
                - # 密码  | 
            |
| 164 | 
                - OPERATOR_PASSWORD_ERROR = StatusCodeField(400302, 'Operator Password Error', description=u'操作员密码错误')  | 
            |
| 165 | 
                - # 手机号  | 
            |
| 166 | 
                - OPERATOR_PHONE_ALREADY_EXISTS = StatusCodeField(400305, 'Operator Phone Already Exists', description=u'操作员手机号已经存在')  | 
            |
| 167 | 
                - # 状态  | 
            |
| 168 | 
                - OPERATOR_NOT_ACTIVATED = StatusCodeField(400315, 'Operator Not Activated', description=u'操作员未激活')  | 
            |
| 169 | 
                - OPERATOR_HAS_DISABLED = StatusCodeField(400316, 'Operator Has Disabled', description=u'操作员已禁用')  | 
            |
| 170 | 
                - OPERATOR_HAS_DELETED = StatusCodeField(400317, 'Operator Has Deleted', description=u'操作员已删除')  | 
            |
| 171 | 
                -  | 
            |
| 172 | 
                -  | 
            |
| 173 | 
                -class UserStatusCode(BaseStatusCode):  | 
            |
| 174 | 
                - """ 用户相关错误码 4005xx """  | 
            |
| 175 | 
                - USER_NOT_FOUND = StatusCodeField(400501, 'User Not Found', description=u'用户不存在')  | 
            |
| 176 | 
                - USER_PASSWORD_ERROR = StatusCodeField(400502, 'User Password Error', description=u'用户密码错误')  | 
            |
| 177 | 
                - USERNAME_HAS_REGISTERED = StatusCodeField(400503, 'Username Has Registered', description=u'用户名已注册')  | 
            |
| 178 | 
                - # 游客  | 
            |
| 179 | 
                - GUEST_NOT_ALLOWED = StatusCodeField(400511, 'Guest Not ALLOWED', description=u'游客登录未开启')  | 
            |
| 180 | 
                - # 身份  | 
            |
| 181 | 
                - USER_NOT_LENSMAN = StatusCodeField(400521, 'User Not Lensman', description=u'用户非摄影师')  | 
            |
| 182 | 
                - USER_NOT_TOURGUIDE = StatusCodeField(400522, 'User Not Tourguide', description=u'用户非导游')  | 
            |
| 183 | 
                -  | 
            |
| 184 | 
                -  | 
            |
| 185 | 
                -class PhoneStatusCode(BaseStatusCode):  | 
            |
| 186 | 
                - """ 手机相关错误码 4006xx """  | 
            |
| 187 | 
                - PHONE_NOT_FOUND = StatusCodeField(400601, 'Phone Not Found', description=u'手机不存在')  | 
            |
| 188 | 
                -  | 
            |
| 189 | 
                -  | 
            |
| 190 | 
                -class WechatStatusCode(BaseStatusCode):  | 
            |
| 191 | 
                - """ 微信相关错误码 4007xx """  | 
            |
| 192 | 
                - WECHAT_NOT_FOUND = StatusCodeField(400701, 'Wechat Not Found', description=u'微信不存在')  | 
            |
| 193 | 
                - UNIONID_NOT_FOUND = StatusCodeField(400702, 'Unionid Not Found', description=u'微信 UNIONID 不存在')  | 
            |
| 194 | 
                - OPENID_NOT_FOUND = StatusCodeField(400703, 'OPENID Not Found', description=u'微信 OPENID 不存在')  | 
            |
| 195 | 
                -  | 
            |
| 196 | 
                -  | 
            |
| 197 | 
                -class ScreenStatusCode(BaseStatusCode):  | 
            |
| 198 | 
                - """ 群组/团相关错误码 4030xx """  | 
            |
| 199 | 
                - QRCODE_NOT_SCAN = StatusCodeField(403001, 'QRCode Not Scan', description=u'二维码未扫描')  | 
            |
| 200 | 
                -  | 
            |
| 201 | 
                -  | 
            |
| 202 | 
                -class PermissionStatusCode(BaseStatusCode):  | 
            |
| 203 | 
                - """ 4099xx 权限相关错误码 """  | 
            |
| 204 | 
                - PERMISSION_DENIED = StatusCodeField(409900, 'Permission Denied', description=u'权限不足')  | 
            |
| 205 | 
                -  | 
            |
| 206 | 
                -  | 
            |
| 207 | 
                -class CouponStatusCode(BaseStatusCode):  | 
            |
| 208 | 
                - """ 4050xx 优惠劵相关错误码 """  | 
            |
| 209 | 
                - COUPON_NOT_FOUND = StatusCodeField(405001, 'Coupon Not Found', description=u'劵不存在')  | 
            |
| 210 | 
                - COUPON_EXPIRED = StatusCodeField(405002, 'Coupon Expired', description=u'劵已过期')  | 
            |
| 211 | 
                - COUPON_PERMISSION_DENIED = StatusCodeField(405003, 'Permission Denied', description=u'核销劵权限不足')  | 
            |
| 212 | 
                - COUPON_HAS_USED = StatusCodeField(405004, 'Coupon Has Used', description=u'劵已核销')  |