Ver código fonte

Merge branch 'dev' of http://192.168.136.99:3000/SERVER/AnsjerServer into zjz

 Conflicts:
	Ansjer/urls.py
	Controller/Cloudsum.py
zjz 4 anos atrás
pai
commit
6027dbda32

+ 7 - 0
Ansjer/config.py

@@ -33,6 +33,12 @@ AWS_SES_ACCESS_ID = 'AKIAJKPU23EU5QWHFPKQ'
 AWS_SES_ACCESS_SECRET = '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'
 AWS_SES_ACCESS_REGION = 'us-east-1'
 AWS_SES_ACCESS_REGION_WEST = 'us-west-1'
+
+# Iot Core
+AWS_IOT_SES_ACCESS_ID = 'AKIA2E67UIMD62VUBV5I'
+AWS_IOT_SES_ACCESS_SECRET = '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'
+AWS_IOT_SES_ACCESS_REGION = 'us-east-1'
+
 AWS_BUCKET = 'ansjertest'
 # 设定离线时间为5分钟
 OFF_LINE_TIME_DELTA = 5
@@ -151,6 +157,7 @@ DEVICE_TYPE = {
     14: 'C190',
     15: 'C199_PRO',
     17: 'C289',
+    18: 'C308',
     10001: 'DVRPTZ'
 }
 

+ 12 - 6
Ansjer/urls.py

@@ -10,9 +10,9 @@ from Controller import FeedBack, EquipmentOTA, EquipmentInfo, AdminManage, AppIn
     StsOssController, UIDPreview, OssCrd, SysMsg, UidUser, EquipmentManagerV2, EquipmentManagerV3, PushDeploy, \
     AppSetController, \
     ApplicationController, UserExController, CloudStorage, TestApi, UserBrandControllerV2, \
-    StatisticsController, Alexa, FAQController, AppLogController, EquipmentVersionLimit, VoicePromptController, CDKController, \
-    DeviceTypeController, CloudTest, Cloudsum
-
+    StatisticsController, Alexa, FAQController, AppLogController, EquipmentVersionLimit, VoicePromptController, \
+    CDKController, \
+    DeviceTypeController, CloudTest, Cloudsum, IotCoreController
 
 urlpatterns = [
     url(r'^testApi/(?P<operation>.*)$', TestApi.testView.as_view()),
@@ -107,11 +107,14 @@ urlpatterns = [
     path('access/staticPath/', AccessLog.statisticsPath),
     path('access/deleteSn/', AccessLog.deleteSn),
     path('eq/del', EquipmentInfo.deleteExpireEquipmentInfo),
+    path('eq/delById', EquipmentInfo.deleteExpireEquipmentInfoById),
     # 新需求ota接口
     url(r'^OTA/getNewVer', OTAEquipment.getNewVerInterface),
     url(r'^OTA/uploadsPack$', OTAEquipment.uploadOTAInterfaceView.as_view()),
     url(r'^OTA/downloadsPack/(?P<fullPath>[0-9\w/.\-]+)', OTAEquipment.downloadOTAInterface),
     url(r'^dlotapack/(?P<fullPath>[0-9\w/.\-]+)', OTAEquipment.downloadOTAInterfaceV2),
+    url(r'^OTA/getDownLoadOTApackUrl$', OTAEquipment.getDownLoadOTApackUrl),
+    url(r'^OTA/checkMaxVersion$', OTAEquipment.checkMaxVersion),
 
     # h获取验证码    # v2接口
     url(r'^v2/account/authcode$', UserController.v2authCodeView.as_view()),
@@ -181,7 +184,8 @@ urlpatterns = [
     # 删除云存视频
     # path('cv/del', CloudVod.deleteVodHls),
     path('cv/del', CloudStorage.deleteVodHls),
-    path('cv/deleteExpiredUidBucket', CloudStorage.deleteExpiredUidBucket),
+    path('cv/updateExpiredUidBucket', CloudStorage.updateExpiredUidBucket),
+    path('cv/updateUnusedUidBucket', CloudStorage.updateUnusedUidBucket),
     url(r'^equipment/judge', EquipmentManager.judgeInterface),
 
     # ap模式,新增设备表
@@ -263,8 +267,10 @@ urlpatterns = [
     #testing....................
 
     #云存服务统计
-    #url(r'^test/(?P<operation>.*)$', Cloudsum.Cloudsum.as_view()),
-    url(r'^Cloudsum/$', Cloudsum.Cloudsum.as_view()),
+    url(r'^Cloudsum/(?P<operation>.*)$', Cloudsum.Cloudsum.as_view()),
+
+    #Iot Core
+    url(r'iot/(?P<operation>.*)$', IotCoreController.IotCoreView.as_view()),
 
     re_path('(?P<path>.*)', LogManager.errorPath),
 

+ 23 - 7
Controller/CDKController.py

@@ -38,7 +38,7 @@ from Object.UidTokenObject import UidTokenObject
 from Service.CommonService import CommonService
 from Object.m3u8generate import PlaylistGenerator
 from Object.WechatPayObject import WechatPayObject
-from django.db.models import Q
+from django.db.models import Q, F
 from django.http import StreamingHttpResponse
 
 SERVER_DOMAIN = 'http://test.dvema.com/'
@@ -81,7 +81,7 @@ class CDKView(View):
             elif operation == 'saveOrEditCDK':
                 return self.saveOrEditCDK(request_dict, response)
             elif operation == 'downloadCDK':
-                return self.downloadCDK(response)
+                return self.downloadCDK(request_dict, response)
 
     def createCDK(self, request_dict, response):
         cdk_num = request_dict.get("cdknum", None)
@@ -115,7 +115,7 @@ class CDKView(View):
         cdk = request_dict.get('cdk', None)
         order = request_dict.get('order', None)
         is_activate = request_dict.get('is_activate', None)
-
+        lang = request_dict.get('lang', 'cn')
         searchVal = ''
         if cdk:
             searchVal = cdk.strip()
@@ -133,6 +133,10 @@ class CDKView(View):
                     cdk_qs = cdk_qs.filter(order=searchVal)
                 elif is_activate:
                     cdk_qs = cdk_qs.filter(is_activate=searchVal)
+
+
+            cdk_qs = cdk_qs.filter(rank__lang__lang=lang)
+            cdk_qs = cdk_qs.annotate(rank__title=F('rank__lang__title'))
             cdk_qs = cdk_qs.values('id', 'cdk', 'create_time', 'valid_time', 'is_activate', 'rank__id', 'rank__title', 'order',
                                    'create_time')
             cdk_qs = cdk_qs.order_by('-create_time')  # 根据CDK创建时间降序排序
@@ -155,6 +159,7 @@ class CDKView(View):
 
     def deleteCDK(self, request_dict, response):
         cdk_id = request_dict.get("id", None)
+        lang = request_dict.get("lang", 'cn')
         try:
             CDKcontextModel.objects.get(cdk=cdk_id).delete()
         except Exception as e:
@@ -184,6 +189,10 @@ class CDKView(View):
                         cdk_qs = cdk_qs.filter(order=searchVal)
                     elif is_activate:
                         cdk_qs = cdk_qs.filter(is_activate=searchVal)
+
+
+                cdk_qs = cdk_qs.filter(rank__lang__lang=lang)
+                cdk_qs = cdk_qs.annotate(rank__title=F('rank__lang__title'))
                 cdk_qs = cdk_qs.values('id', 'cdk', 'create_time', 'valid_time', 'is_activate', 'rank__id',
                                        'rank__title', 'order',
                                        'create_time')
@@ -223,13 +232,20 @@ class CDKView(View):
         else:
             return response.json(0)
 
-    def downloadCDK(self, response):
+    def downloadCDK(self,request_dict, response):
+        region = request_dict.get('region', None)
         content = ''
-        cdk_inactivate_qs = CDKcontextModel.objects.filter(is_activate=0).values('cdk')
-        content += '激活码\n'
+        if region == 'cn':
+            # 下载国内未使用激活码
+            content += '激活码(国内)\n'
+            cdk_inactivate_qs = CDKcontextModel.objects.filter(is_activate=0, rank__bucket__mold=0).values('cdk')
+        else:
+            # 下载国外未使用激活码
+            content += '激活码(国外)\n'
+            cdk_inactivate_qs = CDKcontextModel.objects.filter(is_activate=0, rank__bucket__mold=1).values('cdk')
         for cdk_inactivate in cdk_inactivate_qs:
             content += cdk_inactivate['cdk'] + '\n'
-        print(content)
+        # print(content)
 
         response = StreamingHttpResponse(content)
         response['Content-Type'] = 'application/octet-stream'

+ 431 - 218
Controller/CloudStorage.py

@@ -30,13 +30,16 @@ from aliyunsdkcore import client
 from aliyunsdksts.request.v20150401 import AssumeRoleRequest
 from boto3.session import Session
 from django.http import JsonResponse, HttpResponseRedirect, HttpResponse
+from django.db import transaction
 from django.views.generic.base import View
+import jwt
 from pyfcm import FCMNotification
 
 from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, OSS_ROLE_ARN, SERVER_DOMAIN, PAYPAL_CRD, \
-    SERVER_DOMAIN_SSL, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_ARN, APNS_MODE, APNS_CONFIG, BASE_DIR, JPUSH_CONFIG
+    SERVER_DOMAIN_SSL, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_ARN, APNS_MODE, APNS_CONFIG, BASE_DIR, \
+    JPUSH_CONFIG, FCM_CONFIG, OAUTH_ACCESS_TOKEN_SECRET
 from Model.models import Device_Info, Order_Model, Store_Meal, VodHlsModel, OssCrdModel, UID_Bucket, StsCrdModel, \
-    ExperienceContextModel, Pay_Type, CDKcontextModel, Device_User, SysMassModel, SysMsgModel, UidPushModel
+    ExperienceContextModel, Pay_Type, CDKcontextModel, Device_User, SysMassModel, SysMsgModel, UidPushModel, Unused_Uid_Meal
 from Object.AliPayObject import AliPayObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
@@ -44,7 +47,7 @@ from Object.UidTokenObject import UidTokenObject
 from Service.CommonService import CommonService
 from Object.m3u8generate import PlaylistGenerator
 from Object.WechatPayObject import WechatPayObject
-from django.db.models import Q
+from django.db.models import Q, F
 
 from Service.ModelService import ModelService
 
@@ -94,6 +97,9 @@ class CloudStorageView(View):
         elif operation == 'getsignsts':
             ip = CommonService.get_ip_address(request)
             return self.do_get_sign_sts(request_dict, ip, response)
+        elif operation == 'testgetsignsts':
+            ip = CommonService.get_ip_address(request)
+            return self.do_test_get_sign_sts(request_dict, ip, response)
             # return self.do_get_sign_sts_test(request_dict, ip, response)
         elif operation == 'storeplaylist':
             return self.do_store_playlist(request_dict, response)
@@ -202,14 +208,15 @@ class CloudStorageView(View):
     def do_commodity_list(self, request_dict, userID, response):
         mold = request_dict.get('mold', None)
         uid = request_dict.get('uid', None)
+        lang = request_dict.get('lang', None)
         qs = Store_Meal.objects
         eq = ExperienceContextModel.objects.filter(uid=uid, experience_type=0).values('id')
         # userqs = Device_User.objects.filter(userID=userID).values('is_experience')
 
         if mold:
-            qs = qs.filter(bucket__mold=mold)
+            qs = qs.filter(bucket__mold=mold,lang__lang=lang)
         else:
-            qs = qs.all()
+            qs = qs.filter(lang__lang=lang)
 
         if eq:
             qs = qs.filter(~Q(pay_type='10'))
@@ -217,6 +224,7 @@ class CloudStorageView(View):
             qs = qs.filter(pay_type='10')
 
         qs = qs.filter(~Q(pay_type='11'))  # 过滤不显示激活码套餐
+        qs = qs.annotate(title=F('lang__title'),content=F('lang__content'),discount_content=F('lang__discount_content'))
         qs = qs.values("id", "title", "content", "price", "day", "currency", "bucket__storeDay",
                        "bucket__bucket", "bucket__area", "commodity_code",
                        "commodity_type", "is_discounts", "virtual_price", "expire",
@@ -250,6 +258,7 @@ class CloudStorageView(View):
 
     def do_sign_play_m3u8(self, request_dict, response):
         uid = request_dict.get('uid', None)
+        uid = jwt.decode(uid, OAUTH_ACCESS_TOKEN_SECRET, algorithms='HS256').get('uid', '')
         channel = request_dict.get('channel', None)
         storeTime = request_dict.get('time', None)
         now_time = int(time.time())
@@ -343,7 +352,7 @@ class CloudStorageView(View):
             sts_qs = StsCrdModel.objects.filter(uid=uid, channel=channel). \
                 values("addTime", "data")
             if sts_qs.exists():
-                endTime = int(sts_qs[0]["addTime"]) + 3500
+                endTime = int(sts_qs[0]["addTime"]) + 800
                 if endTime > now_time:
                     print(endTime)
                     print(now_time)
@@ -384,7 +393,95 @@ class CloudStorageView(View):
             response = boto3_sts.get_federation_token(
                 Name='{role_name}'.format(role_name=uid + '_' + str(channel)),
                 Policy=json.dumps(Policy),
-                DurationSeconds=7200
+                DurationSeconds=900
+            )
+            ##############
+            res = {
+                'AccessKeyId': response['Credentials']['AccessKeyId'],
+                'AccessKeySecret': response['Credentials']['SecretAccessKey'],
+                'SessionToken': response['Credentials']['SessionToken'],
+                'Expiration': response['Credentials']['Expiration'],
+                'expire': 900,
+                'endpoint': endpoint,
+                'bucket_name': bucket_name,
+                'arn': response['FederatedUser']['Arn'],
+                'code': 0,
+                'storage': storage,
+                'endTime': ubqs[0]['endTime'],
+                'ip': ip,
+                'region': region_id,
+                'bucket_mold':ubqs[0]['bucket__mold']
+            }
+            if sts_qs.exists():
+                sts_qs.update(data=json.dumps(res, default=str), addTime=now_time)
+            else:
+                StsCrdModel.objects.create(uid=uid, channel=channel, data=json.dumps(res, default=str),
+                                           addTime=now_time, type=1)
+            return JsonResponse(status=200, data=res)
+            # else:
+            #     res = {'code': 404, 'msg': 'data not exists!'}
+            #     return HttpResponse(json.dumps(res, ensure_ascii=False), content_type="application/json,charset=utf-8")
+        res = {'code': 405, 'msg': 'Not purchased or expired!'}
+        return HttpResponse(json.dumps(res, ensure_ascii=False), content_type="application/json,charset=utf-8")
+
+    def do_test_get_sign_sts(self, request_dict, ip, response):
+        uidToken = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1aWQiOiJYS1daU0M1RkNKWVQxOUI3MTExQSIsImNoYW5uZWwiOjF9.YvBCETPrKknw7B-RU3Mij-WJLKf46KGrDQvZMMN7dQk'
+        reset = request_dict.get('reset', 0)
+        utko = UidTokenObject(uidToken)
+        if utko.flag is False:
+            return response.json(444, 'uidToken')
+        uid = utko.UID
+        channel = utko.channel
+        now_time = int(time.time())
+        ubqs = UID_Bucket.objects.filter(uid=uid, channel=channel, endTime__gte=now_time). \
+                   values("bucket__mold", "bucket__bucket", "bucket__endpoint",
+                          "bucket__region", "endTime").order_by('addTime')[:1]
+        if ubqs.exists():
+            # 亚马逊 s3 sts
+            sts_qs = StsCrdModel.objects.filter(uid=uid, channel=channel). \
+                values("addTime", "data")
+            if sts_qs.exists():
+                endTime = int(sts_qs[0]["addTime"]) + 800
+                if reset == '0' and endTime > now_time:
+                    print(endTime)
+                    print(now_time)
+                    res = json.loads(sts_qs[0]["data"])
+                    return JsonResponse(status=200, data=res)
+                # 套餐id
+            storage = '{uid}/test/'.format(uid=uid)
+            bucket_name = ubqs[0]['bucket__bucket']
+            endpoint = ubqs[0]['bucket__endpoint']
+            region_id = ubqs[0]['bucket__region']
+            try:
+                aws_access_key_id = AWS_ACCESS_KEY_ID[ubqs[0]["bucket__mold"]]
+                aws_secret_access_key = AWS_SECRET_ACCESS_KEY[ubqs[0]["bucket__mold"]]
+                aws_arn = AWS_ARN[ubqs[0]["bucket__mold"]]
+            except:
+                res = {'code': 404, 'msg': 'mold not exists!'}
+                return HttpResponse(json.dumps(res, ensure_ascii=False), content_type="application/json,charset=utf-8")
+
+            ###############
+            boto3_sts = boto3.client(
+                'sts',
+                aws_access_key_id=aws_access_key_id,
+                aws_secret_access_key=aws_secret_access_key,
+                region_name=region_id
+            )
+            Policy = {
+                "Version": "2012-10-17",
+                "Statement": [
+                    {
+                        "Effect": "Allow",
+                        "Action": "s3:*",
+                        "Resource": ["{aws_arn}:::{bucket_name}/{uid_channel}*".
+                                         format(aws_arn=aws_arn, bucket_name=bucket_name, uid_channel=storage)]
+                    }
+                ]
+            }
+            response = boto3_sts.get_federation_token(
+                Name='{role_name}'.format(role_name=uid + '_' + str(channel)),
+                Policy=json.dumps(Policy),
+                DurationSeconds=900
             )
             ##############
             res = {
@@ -392,7 +489,7 @@ class CloudStorageView(View):
                 'AccessKeySecret': response['Credentials']['SecretAccessKey'],
                 'SessionToken': response['Credentials']['SessionToken'],
                 'Expiration': response['Credentials']['Expiration'],
-                'expire': '3600',
+                'expire': 900,
                 'endpoint': endpoint,
                 'bucket_name': bucket_name,
                 'arn': response['FederatedUser']['Arn'],
@@ -400,6 +497,8 @@ class CloudStorageView(View):
                 'storage': storage,
                 'endTime': ubqs[0]['endTime'],
                 'ip': ip,
+                'region': region_id,
+                'bucket_mold':ubqs[0]['bucket__mold']
             }
             if sts_qs.exists():
                 sts_qs.update(data=json.dumps(res, default=str), addTime=now_time)
@@ -461,7 +560,7 @@ class CloudStorageView(View):
             )
             vod_url = '{server_domain}/cloudstorage/signplaym3u8?' \
                       'uid={uid}&channel={channel}&time={time}&sign=tktktktk'. \
-                format(server_domain=SERVER_DOMAIN, uid=uid, channel=channel, time=vod['time'])
+                format(server_domain=SERVER_DOMAIN, uid=TokenObject().encryption(data={'uid': uid}), channel=channel, time=vod['time'])
             ts_num = int(vod['fg']) & 0xf
             vod_play_list.append({
                 'name': vod['time'],
@@ -536,7 +635,7 @@ class CloudStorageView(View):
             .values('vodPrimaryUserID')
         if not dv_qs.exists() or dv_qs[0]['vodPrimaryUserID'] != userID:
             return response.json(12)
-        ubqs = UID_Bucket.objects.filter(channel=channel, uid=uid).order_by('addTime')
+        ubqs = UID_Bucket.objects.filter(channel=channel, uid=uid)
         if not ubqs.exists():
             return response.json(10030)
         now_time = int(time.time())
@@ -635,13 +734,27 @@ class CloudStorageView(View):
     def do_pay_ok(self, request_dict):
         response = HttpResponse()
         paytype = request_dict.get('paytype', None)
+        lang = request_dict.get('lang', None)
+
         showtitle = "支付成功"
-        if paytype == "10":
+        if paytype == "10" :
             showtitle = "成功体验云存"
 
         if paytype == "11":
             showtitle = "兑换成功"
+
+        wancheng = '完成'
+        if lang != 'cn':
+            showtitle = "Payment successful"
+            if paytype == "10":
+                showtitle = "Successful experience of cloud storage"
+
+            if paytype == "11":
+                showtitle = "Successful exchange"
+
+            wancheng = 'complete'
         response.content = '''
+        
 <html>
 <head>
         <!--浏览器不缓存-->
@@ -705,7 +818,7 @@ class CloudStorageView(View):
     </div>
     <center class="bottom">
             <div class="bottom_div" onclick="payOKButton()"> 
-             完成
+             '''+wancheng+'''
             </div>
     </center>
     <script src="//hm.baidu.com/hm.js?eaa57ca47dacb4ad4f5a257001a3457c"></script><script>             // 点击付款成功按钮
@@ -722,11 +835,9 @@ class CloudStorageView(View):
         return response
 
     def do_pay_by_ali_callback(self, request):
-
         response = ResponseObject()
         data = request.POST.dict()
-        logger = logging.getLogger('log')
-
+        # logger = logging.getLogger('log')
         try:
             passback_params = data["passback_params"]
             parmap = dict([(k, v[0]) for k, v in parse_qs(unquote(passback_params)).items()])
@@ -752,52 +863,64 @@ class CloudStorageView(View):
                 UID = order_list[0]['UID']
                 channel = order_list[0]['channel']
                 rank = order_list[0]['rank']
+
                 smqs = Store_Meal.objects.filter(id=rank). \
                     values("day", "bucket_id", "bucket__storeDay", "expire")
                 bucketId = smqs[0]['bucket_id']
-
                 if not smqs.exists():
                     return response.json(173)
-                ubqs = UID_Bucket.objects.filter(bucket__id=bucketId, uid=UID, channel=channel, endTime__gte=nowTime). \
-                           values("id", "bucket__storeDay", "bucket__region", "endTime").order_by('addTime')[:1]
+                ubqs = UID_Bucket.objects.filter(uid=UID).values("id", "bucket_id", "bucket__storeDay", "bucket__region",
+                                                                 "endTime", "use_status")
                 expire = smqs[0]['expire']
-
                 if order_list[0]['isSelectDiscounts'] == 1:
                     expire = smqs[0]['expire'] * 2
-                if ubqs.exists():
-                    ubq = ubqs[0]
-                    endTime = CommonService.calcMonthLater(expire, ubq['endTime'])
-
-                    ub_cqs = UID_Bucket.objects.filter(id=ubq['id']).update \
-                        (uid=UID, channel=channel, bucket_id=bucketId,
-                         endTime=endTime, updateTime=nowTime)
-                    logger.info('5')
-                    uid_bucket_id = ubq['id']
-                else:
-                    endTime = CommonService.calcMonthLater(expire)
-                    ub_cqs = UID_Bucket.objects.create \
-                        (uid=UID, channel=channel, bucket_id=bucketId, endTime=endTime, addTime=nowTime,
-                         updateTime=nowTime)
-                    uid_bucket_id = ub_cqs.id
-
-                dvq = Device_Info.objects.filter(UID=UID, vodPrimaryUserID='', vodPrimaryMaster='')
-                if dvq.exists():
-                    dvq_set_update_dict = {
-                        'vodPrimaryUserID': userid,
-                        'vodPrimaryMaster': username
-                    }
-                    dvq.update(**dvq_set_update_dict)
-
-                order_qs.update(status=1, updTime=nowTime, uid_bucket_id=uid_bucket_id)
-                sys_msg_text_list = ['成功购买云存', 'Successful purchase of cloud storage']
-                self.do_vod_msg_Notice(UID, channel, userid, lang, sys_msg_text_list)
-                red_url = "{SERVER_DOMAIN}web/paid2/success.html".format(SERVER_DOMAIN=SERVER_DOMAIN)
-                return HttpResponseRedirect(red_url)
+                with transaction.atomic():
+                    if ubqs.exists():
+                        ubq = ubqs[0]
+                        if ubq['use_status'] == 1 and ubq['bucket_id'] == bucketId:  #套餐使用中并且相同套餐叠加过期时间
+                            endTime = CommonService.calcMonthLater(expire, ubq['endTime'])
+                            UID_Bucket.objects.filter(id=ubq['id']).update \
+                                (uid=UID, channel=channel, bucket_id=bucketId,
+                                 endTime=endTime, updateTime=nowTime)
+                        else:     #已过期或者不相同的套餐加入未使用的关联套餐表
+                            has_unused = Unused_Uid_Meal.objects.filter(uid=UID, bucket_id=bucketId).values("id")
+                            nums = 2 if order_list[0]['isSelectDiscounts'] == 1 else 1
+                            if has_unused.exists():
+                                Unused_Uid_Meal.objects.filter(id=has_unused[0]['id']).update(num=F('num') + nums)
+                            else:
+                                Unused_Uid_Meal.objects.create(uid=UID,channel=channel,addTime=nowTime,num=nums,
+                                                               expire=smqs[0]['expire'],bucket_id=bucketId)
+                            UID_Bucket.objects.filter(id=ubq['id']).update(has_unused=1)
+                        uid_bucket_id = ubq['id']
+                    else:
+                        endTime = CommonService.calcMonthLater(expire)
+                        ub_cqs = UID_Bucket.objects.create \
+                            (uid=UID, channel=channel, bucket_id=bucketId, endTime=endTime, addTime=nowTime,
+                             updateTime=nowTime,use_status=1)
+                        uid_bucket_id = ub_cqs.id
+
+                    dvq = Device_Info.objects.filter(UID=UID, vodPrimaryUserID='', vodPrimaryMaster='')
+                    if dvq.exists():
+                        dvq_set_update_dict = {
+                            'vodPrimaryUserID': userid,
+                            'vodPrimaryMaster': username
+                        }
+                        dvq.update(**dvq_set_update_dict)
+
+                    order_qs.update(status=1, updTime=nowTime, uid_bucket_id=uid_bucket_id)
+                    sys_msg_text_list = ['成功购买云存', 'Successful purchase of cloud storage']
+                    self.do_vod_msg_Notice(UID, channel, userid, lang, sys_msg_text_list)
+                    red_url = "{SERVER_DOMAIN}web/paid2/success.html".format(SERVER_DOMAIN=SERVER_DOMAIN)
+                    if lang != 'cn':
+                        red_url = "{SERVER_DOMAIN}web/paid2/en_success.html".format(SERVER_DOMAIN=SERVER_DOMAIN)
+                    return HttpResponseRedirect(red_url)
             return response.json(0, signature)
         except Exception as e:
             if order_qs:
                 order_qs.update(status=10)
             red_url = "{SERVER_DOMAIN}web/paid2/fail.html".format(SERVER_DOMAIN=SERVER_DOMAIN)
+            if lang != 'cn':
+                red_url = "{SERVER_DOMAIN}web/paid2/en_fail.html".format(SERVER_DOMAIN=SERVER_DOMAIN)
             return HttpResponseRedirect(red_url)
 
     def do_pay_by_paypal_callback(self, request_dict, response):
@@ -805,12 +928,13 @@ class CloudStorageView(View):
         PayerID = request_dict.get('PayerID', None)
         orderID = request_dict.get('orderID', None)
         lang = request_dict.get('lang', None)
-
         try:
             order_qs = Order_Model.objects.filter(orderID=orderID, status=0)
 
             if not orderID:
                 red_url = "{SERVER_DOMAIN}web/paid2/fail.html".format(SERVER_DOMAIN=SERVER_DOMAIN)
+                if lang != 'cn':
+                    red_url = "{SERVER_DOMAIN}web/paid2/en_fail.html".format(SERVER_DOMAIN=SERVER_DOMAIN)
                 return HttpResponseRedirect(red_url)
             # else:
             #     order_qs.update(status=9)
@@ -821,6 +945,8 @@ class CloudStorageView(View):
             print(payres)
             if not payres:
                 red_url = "{SERVER_DOMAIN}web/paid2/fail.html".format(SERVER_DOMAIN=SERVER_DOMAIN)
+                if lang != 'cn':
+                    red_url = "{SERVER_DOMAIN}web/paid2/en_fail.html".format(SERVER_DOMAIN=SERVER_DOMAIN)
                 return HttpResponseRedirect(red_url)
             print("Payment execute successfully")
 
@@ -839,54 +965,69 @@ class CloudStorageView(View):
             if not smqs.exists():
                 return response.json(173)
             # ##
-            ubqs = UID_Bucket.objects.filter(bucket__id=bucketId, uid=UID, channel=channel, endTime__gte=nowTime). \
-                       values("id", "bucket__storeDay", "bucket__region", "endTime").order_by('addTime')[:1]
+            ubqs = UID_Bucket.objects.filter(uid=UID).values("id", "bucket_id", "bucket__storeDay", "bucket__region",
+                                                             "endTime", "use_status")
             expire = smqs[0]['expire']
+
             if order_list[0]['isSelectDiscounts'] == 1:
                 expire = smqs[0]['expire'] * 2
-            if ubqs.exists():
-                ubq = ubqs[0]
-                endTime = CommonService.calcMonthLater(expire, ubq['endTime'])
-                ub_cqs = UID_Bucket.objects.filter(id=ubq['id']).update \
-                    (uid=UID, channel=channel, bucket_id=bucketId,
-                     endTime=endTime, updateTime=nowTime)
-                uid_bucket_id = ubq['id']
-            else:
-                endTime = CommonService.calcMonthLater(expire)
-                ub_cqs = UID_Bucket.objects.create \
-                    (uid=UID, channel=channel, bucket_id=bucketId, endTime=endTime, addTime=nowTime, updateTime=nowTime)
-                uid_bucket_id = ub_cqs.id
-
-            dvq = Device_Info.objects.filter(UID=UID, vodPrimaryUserID='', vodPrimaryMaster='')
-            if dvq.exists():
-                dvq_set_update_dict = {
-                    'vodPrimaryUserID': userid,
-                    'vodPrimaryMaster': username
-                }
-                dvq.update(**dvq_set_update_dict)
-            order_qs.update(status=1, updTime=nowTime, uid_bucket_id=uid_bucket_id)
-            sys_msg_text_list = ['成功购买云存','Successful purchase of cloud storage']
-            self.do_vod_msg_Notice(UID, channel, userid, lang, sys_msg_text_list)
+            with transaction.atomic():
+                if ubqs.exists():
+                    ubq = ubqs[0]
+                    if ubq['use_status'] == 1 and ubq['bucket_id'] == bucketId:  #套餐使用中并且相同套餐叠加过期时间
+                        endTime = CommonService.calcMonthLater(expire, ubq['endTime'])
+                        UID_Bucket.objects.filter(id=ubq['id']).update \
+                            (uid=UID, channel=channel, bucket_id=bucketId,
+                             endTime=endTime, updateTime=nowTime)
+                    else:     #已过期或者不相同的套餐加入未使用的关联套餐表
+                        has_unused = Unused_Uid_Meal.objects.filter(uid=UID, bucket_id=bucketId).values("id")
+                        nums = 2 if order_list[0]['isSelectDiscounts'] == 1 else 1
+                        if has_unused.exists():
+                            Unused_Uid_Meal.objects.filter(id=has_unused[0]['id']).update(num=F('num') + nums)
+                        else:
+                            Unused_Uid_Meal.objects.create(uid=UID,channel=channel,addTime=nowTime,num=nums,
+                                                           expire=smqs[0]['expire'],bucket_id=bucketId)
+                        UID_Bucket.objects.filter(id=ubq['id']).update(has_unused=1)
+                    uid_bucket_id = ubq['id']
+                else:
+                    endTime = CommonService.calcMonthLater(expire)
+                    ub_cqs = UID_Bucket.objects.create \
+                        (uid=UID, channel=channel, bucket_id=bucketId, endTime=endTime, addTime=nowTime,
+                         updateTime=nowTime,use_status=1)
+                    uid_bucket_id = ub_cqs.id
 
-            # return response.json(0)
-            red_url = "{SERVER_DOMAIN}web/paid2/success.html".format(SERVER_DOMAIN=SERVER_DOMAIN)
-            return HttpResponseRedirect(red_url)
+                dvq = Device_Info.objects.filter(UID=UID, vodPrimaryUserID='', vodPrimaryMaster='')
+                if dvq.exists():
+                    dvq_set_update_dict = {
+                        'vodPrimaryUserID': userid,
+                        'vodPrimaryMaster': username
+                    }
+                    dvq.update(**dvq_set_update_dict)
+                order_qs.update(status=1, updTime=nowTime, uid_bucket_id=uid_bucket_id)
+                sys_msg_text_list = ['成功购买云存','Successful purchase of cloud storage']
+                self.do_vod_msg_Notice(UID, channel, userid, lang, sys_msg_text_list)
+
+                # return response.json(0)
+                red_url = "{SERVER_DOMAIN}web/paid2/success.html".format(SERVER_DOMAIN=SERVER_DOMAIN)
+                if lang != 'cn':
+                    red_url = "{SERVER_DOMAIN}web/paid2/en_success.html".format(SERVER_DOMAIN=SERVER_DOMAIN)
+
+                return HttpResponseRedirect(red_url)
         except Exception as e:
             print(repr(e))
             if order_qs:
                 order_qs.update(status=10)
-
             red_url = "{SERVER_DOMAIN}web/paid2/fail.html".format(SERVER_DOMAIN=SERVER_DOMAIN)
+            if lang != 'cn':
+                red_url = "{SERVER_DOMAIN}web/paid2/en_fail.html".format(SERVER_DOMAIN=SERVER_DOMAIN)
             return HttpResponseRedirect(red_url)
 
     def do_pay_by_wechat_callback(self, request, response):
 
         logger = logging.getLogger('log')
-
         try:
             pay = WechatPayObject()
             data = pay.weixinpay_call_back(request.body)
-
             attach = data["attach"]
             parmap = dict([(k, v[0]) for k, v in parse_qs(unquote(attach)).items()])
             lang = parmap["lang"]
@@ -916,45 +1057,53 @@ class CloudStorageView(View):
                 if not smqs.exists():
                     return HttpResponse(pay.xml_to_dict({'return_code': 'FAIL', 'return_msg': '套餐不存在'}))
                 # ##
-                ubqs = UID_Bucket.objects.filter(bucket__id=bucketId, uid=UID, channel=channel, endTime__gte=nowTime). \
-                           values("id", "bucket__storeDay", "bucket__region", "endTime").order_by('addTime')[:1]
+                ubqs = UID_Bucket.objects.filter(uid=UID).values("id", "bucket_id", "bucket__storeDay",
+                                                                 "bucket__region", "endTime", "use_status")
                 expire = smqs[0]['expire']
                 if order_list[0]['isSelectDiscounts'] == 1:
                     expire = smqs[0]['expire'] * 2
-                if ubqs.exists():
-                    ubq = ubqs[0]
-                    endTime = CommonService.calcMonthLater(expire, ubq['endTime'])
-                    ub_cqs = UID_Bucket.objects.filter(id=ubq['id']).update \
-                        (uid=UID, channel=channel, bucket_id=bucketId,
-                         endTime=endTime, updateTime=nowTime)
-                    uid_bucket_id = ubq['id']
-                else:
-                    endTime = CommonService.calcMonthLater(expire)
-                    ub_cqs = UID_Bucket.objects.create \
-                        (uid=UID, channel=channel, bucket_id=bucketId, endTime=endTime, addTime=nowTime,
-                         updateTime=nowTime)
-                    uid_bucket_id = ub_cqs.id
-
-                dvq = Device_Info.objects.filter(UID=UID, vodPrimaryUserID='', vodPrimaryMaster='')
-                if dvq.exists():
-                    dvq_set_update_dict = {
-                        'vodPrimaryUserID': userid,
-                        'vodPrimaryMaster': username
-                    }
-                    dvq.update(**dvq_set_update_dict)
-                order_qs.update(status=1, updTime=nowTime, uid_bucket_id=uid_bucket_id)
-                sys_msg_text_list = ['成功购买云存', 'Successful purchase of cloud storage']
-                self.do_vod_msg_Notice(UID, channel, userid, lang, sys_msg_text_list)
-                return HttpResponse(pay.xml_to_dict({'return_code': 'SUCCESS', 'return_msg': 'OK'}))
-
+                with transaction.atomic():
+                    if ubqs.exists():
+                        ubq = ubqs[0]
+                        if ubq['use_status'] == 1 and ubq['bucket_id'] == bucketId:  #套餐使用中并且相同套餐叠加过期时间
+                            endTime = CommonService.calcMonthLater(expire, ubq['endTime'])
+                            UID_Bucket.objects.filter(id=ubq['id']).update \
+                                (uid=UID, channel=channel, bucket_id=bucketId,
+                                 endTime=endTime, updateTime=nowTime)
+                        else:     #已过期或者不相同的套餐加入未使用的关联套餐表
+                            has_unused = Unused_Uid_Meal.objects.filter(uid=UID, bucket_id=bucketId).values("id")
+                            nums = 2 if order_list[0]['isSelectDiscounts'] == 1 else 1
+                            if has_unused.exists():
+                                Unused_Uid_Meal.objects.filter(id=has_unused[0]['id']).update(num=F('num') + nums)
+                            else:
+                                Unused_Uid_Meal.objects.create(uid=UID,channel=channel,addTime=nowTime,num=nums,
+                                                               expire=smqs[0]['expire'],bucket_id=bucketId)
+                            UID_Bucket.objects.filter(id=ubq['id']).update(has_unused=1)
+                        uid_bucket_id = ubq['id']
+                    else:
+                        endTime = CommonService.calcMonthLater(expire)
+                        ub_cqs = UID_Bucket.objects.create \
+                            (uid=UID, channel=channel, bucket_id=bucketId, endTime=endTime, addTime=nowTime,
+                             updateTime=nowTime,use_status=1)
+                        uid_bucket_id = ub_cqs.id
+
+                    dvq = Device_Info.objects.filter(UID=UID, vodPrimaryUserID='', vodPrimaryMaster='')
+                    if dvq.exists():
+                        dvq_set_update_dict = {
+                            'vodPrimaryUserID': userid,
+                            'vodPrimaryMaster': username
+                        }
+                        dvq.update(**dvq_set_update_dict)
+                    order_qs.update(status=1, updTime=nowTime, uid_bucket_id=uid_bucket_id)
+                    sys_msg_text_list = ['成功购买云存', 'Successful purchase of cloud storage']
+                    self.do_vod_msg_Notice(UID, channel, userid, lang, sys_msg_text_list)
+                    return HttpResponse(pay.xml_to_dict({'return_code': 'SUCCESS', 'return_msg': 'OK'}))
             else:
                 order_qs.update(status=10)
             return HttpResponse(pay.xml_to_dict({'return_code': 'FAIL', 'return_msg': '参数格式校验错误'}))
-
         except Exception as e:
             if order_qs:
                 order_qs.update(status=10)
-
             return HttpResponse(pay.xml_to_dict({'return_code': 'FAIL', 'return_msg': repr(e)}))
 
     def do_create_pay_order(self, request_dict, userID, ip, response):
@@ -986,9 +1135,9 @@ class CloudStorageView(View):
 
         # if dv_qs[0]['vodPrimaryUserID'] != '' and dv_qs[0]['vodPrimaryUserID'] != userID:
         #     return response.json(10033)
-        smqs = Store_Meal.objects.filter(id=rank, pay_type=pay_type). \
-            values('currency', 'price', 'content', 'day',
-                   'commodity_type', 'title', 'content',
+        smqs = Store_Meal.objects.filter(id=rank, pay_type=pay_type, lang__lang=lang). \
+            values('currency', 'price', 'lang__content', 'day',
+                   'commodity_type', 'lang__title',
                    'expire', 'commodity_code', 'discount_price')
         if not smqs.exists():
             return response.json(173)
@@ -996,7 +1145,7 @@ class CloudStorageView(View):
         price = smqs[0]['price']
         if is_select_discount == '1':
             price = float(smqs[0]['price']) + float(smqs[0]['discount_price'])
-        content = smqs[0]['content']
+        content = smqs[0]['lang__content']
         day = smqs[0]['day']
         commodity_code = smqs[0]['commodity_code']
         commodity_type = smqs[0]['commodity_type']
@@ -1009,11 +1158,15 @@ class CloudStorageView(View):
 
         orderID = CommonService.createOrderID()
         if pay_type == 1:
+
+            cal_url = "{SERVER_DOMAIN}web/paid2/fail.html".format(SERVER_DOMAIN=SERVER_DOMAIN)
+            if lang != 'cn':
+                cal_url = "{SERVER_DOMAIN}web/paid2/en_fail.html".format(SERVER_DOMAIN=SERVER_DOMAIN)
             call_sub_url = "{SERVER_DOMAIN}cloudstorage/dopaypalcallback?orderID={orderID}&lang={lang}". \
                 format(SERVER_DOMAIN=SERVER_DOMAIN, orderID=orderID, lang=lang)
             # call_sub_url = "http://binbin.uicp.vip/cloudstorage/dopaypalcallback?orderID={orderID}".format(
             # SERVER_DOMAIN=SERVER_DOMAIN, orderID=orderID)
-            call_clc_url = "{SERVER_DOMAIN}web/paid2/fail.html".format(SERVER_DOMAIN=SERVER_DOMAIN)
+            call_clc_url = cal_url
             paypalrestsdk.configure(PAYPAL_CRD)
             payment = paypalrestsdk.Payment({
                 "intent": "sale",
@@ -1046,7 +1199,7 @@ class CloudStorageView(View):
             try:
                 aliPayObj = AliPayObject()
                 alipay = aliPayObj.conf()
-                subject = smqs[0]['title'] + smqs[0]['content']
+                subject = smqs[0]['lang__title'] + smqs[0]['lang__content']
                 # biz_content = {
                 #     "subject": subject,
                 #     "out_trade_no": orderID,
@@ -1124,7 +1277,7 @@ class CloudStorageView(View):
         pay_type = int(request_dict.get('pay_type', None))
         rank = request_dict.get('rank', None)
         cdk = request_dict.get('cdk', None)
-
+        lang = request_dict.get('lang', None)
         if cdk != None and pay_type == 11:
             cdk_qs = CDKcontextModel.objects.filter(cdk=cdk).values('is_activate', 'rank__id', 'rank__commodity_code')
             if not cdk_qs.exists():
@@ -1152,63 +1305,86 @@ class CloudStorageView(View):
 
         orderID = CommonService.createOrderID()
         nowTime = int(time.time())
-        smqs = Store_Meal.objects.filter(id=rank). \
-            values("day", "bucket_id", "bucket__storeDay", "expire", 'content', 'price', 'currency', 'commodity_type')
+        smqs = Store_Meal.objects.filter(id=rank,lang__lang=lang). \
+            values("day", "bucket_id", "bucket__storeDay", "expire", 'lang__content', 'price', 'currency', 'commodity_type')
         if not smqs.exists():
             return response.json(173)
         bucketId = smqs[0]['bucket_id']
         # ##
-        ubqs = UID_Bucket.objects.filter(bucket__id=bucketId, uid=uid, channel=channel, endTime__gte=nowTime). \
-                   values("id", "bucket__storeDay", "bucket__region", "endTime").order_by('addTime')[:1]
+        ubqs = UID_Bucket.objects.filter(uid=uid).values("id", "bucket_id", "bucket__storeDay", "bucket__region",
+                                                         "endTime", "use_status")
         expire = smqs[0]['expire']
-        if ubqs.exists():
-            ubq = ubqs[0]
-            endTime = CommonService.calcMonthLater(expire, ubq['endTime'])
-            ub_cqs = UID_Bucket.objects.filter(id=ubq['id']).update \
-                (uid=uid, channel=channel, bucket_id=bucketId,
-                 endTime=endTime, updateTime=nowTime)
-            uid_bucket_id = ubq['id']
-        else:
-            endTime = CommonService.calcMonthLater(expire)
-            ub_cqs = UID_Bucket.objects.create \
-                (uid=uid, channel=channel, bucket_id=bucketId, endTime=endTime, addTime=nowTime, updateTime=nowTime)
-            uid_bucket_id = ub_cqs.id
-        Order_Model.objects.create(orderID=orderID, UID=uid, channel=channel, userID_id=userID,
-                                   desc=smqs[0]['content'], payType=pay_type, payTime=nowTime,
-                                   price=smqs[0]['price'], currency=smqs[0]['currency'], addTime=nowTime,
-                                   updTime=nowTime,
-                                   pay_url="体验版",
-                                   commodity_code=commodity_code, commodity_type=smqs[0]['commodity_type'],
-                                   rank_id=rank, status=1, uid_bucket_id=uid_bucket_id)
-
-        duq = Device_User.objects.filter(userID=userID).values('username')
-        dvq = Device_Info.objects.filter(UID=uid, vodPrimaryUserID='', vodPrimaryMaster='')
-        if dvq.exists():
-            dvq_set_update_dict = {
-                'vodPrimaryUserID': userID,
-                'vodPrimaryMaster': duq[0]['username']
-            }
-            dvq.update(**dvq_set_update_dict)
-
-        # return response.json(0)
-        returnurl = "{SERVER_DOMAIN}cloudstorage/payOK".format(SERVER_DOMAIN=SERVER_DOMAIN)
-        if pay_type == 10:
-            ExperienceContextModel.objects.create(
-                experience_type=0,
-                uid=uid,
-                do_time=nowTime
-            )
-            returnurl = "{SERVER_DOMAIN}cloudstorage/payOK?paytype=10".format(SERVER_DOMAIN=SERVER_DOMAIN)
+        try:
+            with transaction.atomic():
+                if ubqs.exists():
+                    ubq = ubqs[0]
+                    if ubq['use_status'] == 1 and ubq['bucket_id'] == bucketId:  #套餐使用中并且相同套餐叠加过期时间
+                        endTime = CommonService.calcMonthLater(expire, ubq['endTime'])
+                        UID_Bucket.objects.filter(id=ubq['id']).update \
+                            (uid=uid, channel=channel, bucket_id=bucketId,
+                             endTime=endTime, updateTime=nowTime)
+                    else:     #已过期或者不相同的套餐加入未使用的关联套餐表
+                        has_unused = Unused_Uid_Meal.objects.filter(uid=uid, bucket_id=bucketId).values("id")
+                        nums = 1
+                        if has_unused.exists():
+                            Unused_Uid_Meal.objects.filter(id=has_unused[0]['id']).update(num=F('num') + nums)
+                        else:
+                            Unused_Uid_Meal.objects.create(uid=uid,channel=channel,addTime=nowTime,num=nums,
+                                                           expire=smqs[0]['expire'],bucket_id=bucketId)
+                        UID_Bucket.objects.filter(id=ubq['id']).update(has_unused=1)
+                    uid_bucket_id = ubq['id']
+                else:
+                    endTime = CommonService.calcMonthLater(expire)
+                    ub_cqs = UID_Bucket.objects.create \
+                        (uid=uid, channel=channel, bucket_id=bucketId, endTime=endTime, addTime=nowTime,
+                         updateTime=nowTime,use_status=1)
+                    uid_bucket_id = ub_cqs.id
+                Order_Model.objects.create(orderID=orderID, UID=uid, channel=channel, userID_id=userID,
+                                           desc=smqs[0]['lang__content'], payType=pay_type, payTime=nowTime,
+                                           price=smqs[0]['price'], currency=smqs[0]['currency'], addTime=nowTime,
+                                           updTime=nowTime,
+                                           pay_url="体验版",
+                                           commodity_code=commodity_code, commodity_type=smqs[0]['commodity_type'],
+                                           rank_id=rank, status=1, uid_bucket_id=uid_bucket_id)
+
+                duq = Device_User.objects.filter(userID=userID).values('username')
+                dvq = Device_Info.objects.filter(UID=uid, vodPrimaryUserID='', vodPrimaryMaster='')
+
 
-        if pay_type == 11:
-            update_dict = {}
-            update_dict['is_activate'] = 1
-            update_dict['order'] = orderID
-            CDKcontextModel.objects.filter(cdk=cdk).update(**update_dict)
-            returnurl = "{SERVER_DOMAIN}cloudstorage/payOK?paytype=11".format(SERVER_DOMAIN=SERVER_DOMAIN)
 
-        result = returnurl
-        return response.json(0, result)
+                if dvq.exists():
+                    dvq_set_update_dict = {
+                        'vodPrimaryUserID': userID,
+                        'vodPrimaryMaster': duq[0]['username']
+                    }
+                    dvq.update(**dvq_set_update_dict)
+
+                sys_msg_text_list = ['成功购买云存', 'Successful purchase of cloud storage']
+                # return response.json(0)
+                returnurl = "{SERVER_DOMAIN}cloudstorage/payOK?lang={lang}".format(SERVER_DOMAIN=SERVER_DOMAIN,lang=lang)
+                if pay_type == 10:
+                    ExperienceContextModel.objects.create(
+                        experience_type=0,
+                        uid=uid,
+                        do_time=nowTime
+                    )
+                    returnurl = "{SERVER_DOMAIN}cloudstorage/payOK?paytype=10&lang={lang}".format(SERVER_DOMAIN=SERVER_DOMAIN,lang=lang)
+                    sys_msg_text_list = ['成功体验云存', 'Successful experience of cloud storage']
+
+                if pay_type == 11:
+                    update_dict = {}
+                    update_dict['is_activate'] = 1
+                    update_dict['order'] = orderID
+                    CDKcontextModel.objects.filter(cdk=cdk).update(**update_dict)
+                    returnurl = "{SERVER_DOMAIN}cloudstorage/payOK?paytype=11&lang={lang}".format(SERVER_DOMAIN=SERVER_DOMAIN,lang=lang)
+                    sys_msg_text_list = ['成功兑换云存', 'Successful exchange of cloud storage']
+
+
+                self.do_vod_msg_Notice(uid, channel, userID, lang, sys_msg_text_list)
+                result = returnurl
+                return response.json(0, result)
+        except Exception:
+            return response.json(474)
         # red_url =
         # return JsonResponse(status=200, data={'red_url': red_url})
 
@@ -1255,21 +1431,47 @@ class CloudStorageView(View):
     # 设备关联套餐列表
     def device_commodity(self, request_dict, userID, response):
         uid = request_dict.get('uid', None)
+        lang = request_dict.get('lang', None)
         dv_qs = Device_Info.objects.filter(userID_id=userID, UID=uid, isShare=False, isExist=1) \
             .values('vodPrimaryUserID')
         if not dv_qs.exists() or dv_qs[0]['vodPrimaryUserID'] != userID:
             return response.json(12)
         now_time = int(time.time())
-        uid_bucket = UID_Bucket.objects.filter(uid=uid, endTime__gte=now_time).values("id", "uid", "endTime",
-                                                                                      "bucket__content").order_by(
-            'addTime')
-        if not uid_bucket.exists():
+        bucket_id_list = []
+        store_list = []
+        uid_bucket = UID_Bucket.objects.filter(uid=uid, endTime__gte=now_time).values("id", "uid","bucket__content",
+                                                                    "use_status","endTime","has_unused","bucket__id")
+        if not uid_bucket:
             return response.json(10030)
-        for index, value in enumerate(uid_bucket):
-            value['is_use'] = 0
-            if index == 0:
-                value['is_use'] = 1
-        return response.json(0, list(uid_bucket))
+        uid_bucket[0]['storage'] = 0
+        has_unused = uid_bucket[0]['has_unused']
+        del uid_bucket[0]['has_unused']
+        store_list.append(uid_bucket[0])
+        bucket_id_list.append(uid_bucket[0]['bucket__id'])
+        if has_unused == 1:
+            unuseds = Unused_Uid_Meal.objects.filter(uid=uid).annotate(unused_id=F('id')) \
+                .values("unused_id","uid","bucket__content","num","bucket__id","expire")
+            for ub in unuseds:
+                storage_time = ub['num'] *  ub['expire']
+                storage = "{storage_time}个月".format(storage_time=storage_time)
+                unused_dict = {
+                    "id":ub['unused_id'],
+                    "uid":ub['uid'],
+                    "bucket__content":ub['bucket__content'],
+                    "use_status":0,
+                    "endTime":0,
+                    "bucket__id":ub['bucket__id'],
+                    "storage":storage,
+                }
+                store_list.append(unused_dict)
+                bucket_id_list.append(ub['bucket__id'])
+        smqs = Store_Meal.objects.filter(bucket__id__in=bucket_id_list, lang__lang=lang).values('lang__lang','bucket__id','lang__title')
+        for index, value in enumerate(store_list):
+            for sm in smqs:
+                if value['bucket__id'] == sm['bucket__id']:
+                    value['bucket__content'] = sm['lang__title']
+
+        return response.json(0, list(store_list))
 
     # 提前使用设备关联套餐
     def switch_device_commodity(self, request_dict, userID, response):
@@ -1278,22 +1480,29 @@ class CloudStorageView(View):
             .values('vodPrimaryUserID')
         if not dv_qs.exists() or dv_qs[0]['vodPrimaryUserID'] != userID:
             return response.json(12)
-        switch_commodity_id = request_dict.get('switch_commodity_id', None)
-        if switch_commodity_id:
+        unused_id = request_dict.get('switch_commodity_id', None)
+        if unused_id:
             # 切换设备套餐关联
-            using_uid_bucket = UID_Bucket.objects.filter(uid=uid, endTime__gte=int(time.time())).values("id", "uid",
-                                                                                                        "endTime","bucket__content","addTime").order_by('addTime')
-            if not using_uid_bucket.exists():
+            using_uid_bucket = UID_Bucket.objects.filter(uid=uid,has_unused=1).values("id", "uid", "endTime",
+                                                                 "bucket__content","addTime")
+            unuseds = Unused_Uid_Meal.objects.filter(id=unused_id).values("id","uid","channel","addTime","expire",
+                                                                         "num","bucket_id")
+            if not unuseds.exists() or not using_uid_bucket.exists():
                 return response.json(10030)
-            useing_uid_bucket_id = using_uid_bucket[0]['id']
-            useing_uid_bucket_addTime = using_uid_bucket[0]['addTime']
-            if int(useing_uid_bucket_id) == int(switch_commodity_id):
-                return response.json(10032)
-
-            UID_Bucket.objects.filter(id=switch_commodity_id).update(addTime=useing_uid_bucket_addTime)#更新转移的云存套餐为使用中
-            UID_Bucket.objects.filter(id=useing_uid_bucket_id).delete()  # 删除原来使用中的云存套餐
-            VodHlsModel.objects.filter(uid=uid).delete()  # 删除播放列表
-            StsCrdModel.objects.filter(uid=uid).delete()  # 删除sts记录
+            unused = unuseds[0]
+            nowTime = int(time.time())
+            try:
+                with transaction.atomic():
+                    count_unused = Unused_Uid_Meal.objects.filter(uid=uid).count()
+                    has_unused = 1 if count_unused>1 else 0
+                    endTime = CommonService.calcMonthLater(unused['expire'] * unused['num'])
+                    UID_Bucket.objects.filter(uid=uid).update(channel=unused['channel'],endTime=endTime,bucket_id=unused['bucket_id']
+                                                              ,updateTime=nowTime,use_status=1, has_unused=has_unused)
+                    Unused_Uid_Meal.objects.filter(id=unused_id).delete()
+                    StsCrdModel.objects.filter(uid=uid).delete()  # 删除sts记录
+                    VodHlsModel.objects.filter(uid=uid).delete()  # 删除播放列表,后期数据量多时应该考虑延后删除
+            except Exception:
+                return response.json(474)
             return response.json(0)
         return response.json(444)
 
@@ -1318,7 +1527,7 @@ class CloudStorageView(View):
         except Exception as e:
             return repr(e)
     # 云存到期续费提醒   提前1天
-    def do_vod_msg_end(self):
+    def do_vod_msg_end(self, request_dict):
         response = ResponseObject()
         now_time = int(time.time())
 
@@ -1390,19 +1599,7 @@ class CloudStorageView(View):
             if tz is None or tz == '':
                 tz = 0
 
-            package_title_config = {
-                'com.ansjer.customizedd_a': 'DVS',
-                'com.ansjer.zccloud_a': 'ZosiSmart',
-                'com.ansjer.zccloud_ab': '周视',
-                'com.ansjer.adcloud_a': 'ADCloud',
-                'com.ansjer.adcloud_ab': 'ADCloud',
-                'com.ansjer.accloud_a': 'ACCloud',
-                'com.ansjer.loocamccloud_a': 'Loocam',
-                'com.ansjer.loocamdcloud_a': 'Anlapus',
-                'com.ansjer.customizedb_a': 'COCOONHD',
-                'com.ansjer.customizeda_a': 'Guardian365',
-                'com.ansjer.customizedc_a': 'PatrolSecure',
-            }
+            package_title_config = FCM_CONFIG[appBundleId]
             if appBundleId in package_title_config.keys():
                 msg_title = package_title_config[appBundleId] + '(' + nickname + ')'
             else:
@@ -1447,17 +1644,6 @@ class CloudStorageView(View):
 
             elif push_type == 1:  # android gcm
                 try:
-                    FCM_CONFIG = {
-                        'com.ansjer.zccloud_a': 'AAAAb9YP3rk:APA91bHu8u-CTpcd0g6lKPo0WNVqCi8jZub1cPPbSAY9AucT1HxlF65ZDUko9iG8q2ch17bwu9YWHpK1xI1gHSRXCslLvZlXEmHZC0AG3JKg15XuUvlFKACIajUFV-pOeGRT8tM6-31I',
-                        'com.ansjer.loocamccloud_a': 'AAAAb9YP3rk:APA91bFCgd-kbVmpK4EVpfdHH_PJZQCYTkOGnTZdIuBWEz2r7aMRsJYHOH3sB-rwcbaRWgnufTyjX9nGQxb6KxQbWVk4ah_H-M3IqGh6Mb60WQQAuR33V6g_Jes5pGL6ViuIxGHqVMaR',
-                        'com.ansjer.loocamdcloud_a': 'AAAAb9YP3rk:APA91bGw2I2KMD4i-5T7nZO_wB8kuAOuqgyqe5rxmY-W5qkpYEx9IL2IfmC_qf6B_xOyjIDDSjckvMo-RauN__SEoxvAkis7042GRkoKpw7cjZ_H8lC-d50PC0GclPzccrOGFusyKbFY',
-                        'com.ansjer.customizedb_a': 'AAAAb9YP3rk:APA91bE7kI4vcm-9h_CJNFlOZfc-xwP4Btn6AnjOrwoKV6fgYN7fdarkO76sYxVZiAbDnxsFfOJyP7vQfwyan6mdjuyD5iHdt_XgO22VqniC0vA1V4GJiCS8Tp7LxIX8JVKZl9I_Powt',
-                        'com.ansjer.customizeda_a': 'AAAAb9YP3rk:APA91bF0HzizVWDc6dKzobY9fsaKDK4veqkOZehDXshVXs8pEEvNWjR_YWbhP60wsRYCHCal8fWN5cECVOWNMMzDsfU88Ty2AUl8S5FtZsmeDTkoGntQOswBr8Ln7Fm_LAp1VqTf9CpM',
-                        'com.ansjer.customizedd_a': 'AAAAb9YP3rk:APA91bHkxOozJWBrlv3eNT0PgwosYENI9aM4Zuzd418cX-iKkpa1zFNC5MkNDKApx1KH4fhmAfaJ6IMRZ0nj5GIxCpstDYCaZWwgC7-etqfSxG5JAq8LOwJx0o_1tUZqwjIic8ztsg0o',
-                        'com.ansjer.adcloud_a': 'AAAAb9YP3rk:APA91bFm06w8b9OKQ0gz0iaWFuRqRIkvgAz6z7Gp3dBU_X-LNGJQd1hc1QR2W7QzBglF8SHtERA45a2lbdLRa5qv7hxfd6W_sJLBK7dA8jklsOQBvy505oUzTwMKWy4TwH-exps9KrhO',
-                        'com.ansjer.accloud_a': 'AAAAb9YP3rk:APA91bFm06w8b9OKQ0gz0iaWFuRqRIkvgAz6z7Gp3dBU_X-LNGJQd1hc1QR2W7QzBglF8SHtERA45a2lbdLRa5qv7hxfd6W_sJLBK7dA8jklsOQBvy505oUzTwMKWy4TwH-exps9KrhO',
-                        'com.ansjer.zccloud_ab': 'AAAAb9YP3rk:APA91bHu8u-CTpcd0g6lKPo0WNVqCi8jZub1cPPbSAY9AucT1HxlF65ZDUko9iG8q2ch17bwu9YWHpK1xI1gHSRXCslLvZlXEmHZC0AG3JKg15XuUvlFKACIajUFV-pOeGRT8tM6-31I',
-                    }
                     serverKey = FCM_CONFIG[appBundleId]
                 except Exception as e:
                     return 'serverKey abnormal'
@@ -1528,11 +1714,38 @@ def deleteVodHls(request):
     return response.json(0)
 
 
-# 删除过期云存关联套餐
-def deleteExpiredUidBucket(request):
+# 更新过期云存关联套餐
+def updateExpiredUidBucket(request):
     response = ResponseObject()
     now_time = int(time.time())
     expired_uid_bucket = UID_Bucket.objects.filter(endTime__lte=now_time)
     id_list = expired_uid_bucket.values_list("id", flat=True)
-    UID_Bucket.objects.filter(id__in=list(id_list)).delete()  # 删除过期云存关联套餐, 后续是否考虑用软删除
+    UID_Bucket.objects.filter(id__in=list(id_list)).update(use_status=2)  # 更新过期云存关联套餐状态
+    return response.json(0)
+
+# 如果云存关联套餐过期,更新未使用的关联套餐
+def updateUnusedUidBucket(request):
+    response = ResponseObject()
+    now_time = int(time.time())
+    expired_uid_buckets = UID_Bucket.objects.filter(endTime__lte=now_time,has_unused=1).values("id","uid")[0:1000]
+    for expired_uid_bucket in expired_uid_buckets:
+        unuseds = Unused_Uid_Meal.objects.filter(uid=expired_uid_bucket['uid']).values("id","uid","channel","addTime","expire",
+                                                                  "num","bucket_id","userID_id").order_by('addTime')[0:1]
+        if not unuseds.exists():
+            continue
+        unused = unuseds[0]
+        try:
+            with transaction.atomic():
+                count_unused = Unused_Uid_Meal.objects.filter(uid=expired_uid_bucket['uid']).count()
+                has_unused = 1 if count_unused>1 else 0
+                endTime = CommonService.calcMonthLater(unused['expire'] * unused['num'])
+                UID_Bucket.objects.filter(uid=expired_uid_bucket['uid']).update(channel=unused['channel'],endTime=endTime,bucket_id=unused['bucket_id']
+                                                          ,updateTime=now_time,use_status=1,userID_id=unused['userID_id'],
+                                                          has_unused=has_unused)
+                Unused_Uid_Meal.objects.filter(id=unused['id']).delete()
+                StsCrdModel.objects.filter(uid=expired_uid_bucket['uid']).delete()  # 删除sts记录
+                VodHlsModel.objects.filter(uid=expired_uid_bucket['uid']).delete()  # 删除播放列表,后期数据量多时应该考虑延后删除
+        except Exception:
+            continue
+    # UID_Bucket.objects.filter(id__in=list(id_list)).update(use_status=2)  # 更新过期云存关联套餐状态
     return response.json(0)

+ 6 - 5
Controller/CloudTest.py

@@ -12,7 +12,7 @@ from django.views.generic.base import View
 from Object.TokenObject import TokenObject
 from Service.ModelService import ModelService
 from Object.ResponseObject import ResponseObject
-from Model.models import Device_User, Device_Info, Order_Model, UID_Bucket, StsCrdModel, VodHlsModel
+from Model.models import Device_User, Device_Info, Order_Model, UID_Bucket, StsCrdModel, VodHlsModel, Unused_Uid_Meal
 
 
 class cloudTestView(View):
@@ -132,7 +132,9 @@ class cloudTestView(View):
 
             # 查询转入设备正在使用的套餐
             new_using_uid_bucket = UID_Bucket.objects.filter(uid=new_uid, endTime__gte=nowTime)
-            if new_using_uid_bucket.exists():
+            new_unused_uid_bucket = Unused_Uid_Meal.objects.filter(uid=new_uid)
+            new_unused_id_list = new_unused_uid_bucket.values_list("id", flat=True)
+            if new_using_uid_bucket.exists() or new_unused_uid_bucket.exists():
                 return response.json(10014)
 
             with transaction.atomic():
@@ -141,6 +143,7 @@ class cloudTestView(View):
                 # vod_uid_bucket表更新uid
                 old_using_uid_bucket_id = old_using_uid_bucket[0]['id']
                 UID_Bucket.objects.filter(id=old_using_uid_bucket_id).update(uid=new_uid)
+                Unused_Uid_Meal.objects.filter(id__in=list(new_unused_id_list)).update(uid=new_uid)  # 更新过期云存关联套餐状态
                 # 删除转出设备stscrd表关联数据
                 StsCrdModel.objects.filter(uid=old_uid).delete()
         except Exception as e:
@@ -151,12 +154,10 @@ class cloudTestView(View):
 
     def expireMeal(self, request_dict, response):
         UID_Bucket_id = request_dict.get("UID_Bucket_id", None)
-
         # 修改endTime让当前设备套餐过期
         if UID_Bucket_id:
-            nowTime = int(time.time())
             try:
-                UID_Bucket.objects.filter(id=UID_Bucket_id).update(endTime=nowTime-1)
+                UID_Bucket.objects.filter(id=UID_Bucket_id).update(use_status=2)
             except Exception as e:
                 # print(e)
                 return response.json(500, repr(e))

+ 15 - 403
Controller/CloudVod.py

@@ -100,12 +100,6 @@ class CloudVodView(View):
             return self.do_pay_ok()
         elif operation == 'payError':
             return self.do_pay_error()
-        elif operation == 'aliPayCallback':
-            return self.do_ali_pay_callback(request)
-        elif operation == 'dopaypalcallback':
-            return self.do_pay_by_paypal_callback(request)
-        elif operation == 'doalicallback':
-            return self.do_pay_by_ali_callback(request)
         else:
             token = request_dict.get('token', None)
             # 设备主键uid
@@ -114,9 +108,7 @@ class CloudVodView(View):
             if tko.code != 0:
                 return response.json(tko.code)
             userID = tko.userID
-            if operation == 'createOrder':
-                return self.do_create_order(request_dict, userID, response)
-            elif operation == 'status':
+            if operation == 'status':
                 return self.do_change_status(request_dict, userID, response)
             elif operation == 'details':
                 return self.do_get_details(request_dict, response)
@@ -124,149 +116,11 @@ class CloudVodView(View):
                 return self.do_filter_playlist(request_dict, userID, response)
             elif operation == 'findVod':
                 return self.do_find_playlist(request_dict, userID, response)
-            # 支付宝支付
-            elif operation == 'aliPayCreateOrder':
-                return self.do_pay_by_ali(request_dict, userID, response)
             elif operation == 'orderStatus':
                 return self.do_pay_status(request_dict, userID, response)
-            elif operation == 'createPayOrder':
-                return self.do_create_pay_order(request_dict, userID, response)
-            # elif operation == 'queryAlipayOrder':
-            #     return self.query_alipay_order(request_dict, userID, response)
-            # elif operation == 'alipayCancel':
-            #     return self.do_alipay_cancel(request_dict, userID, response)
-            # elif operation == 'alipayRefund':
-            #     return self.do_alipay_refund(request_dict, userID, response)
             else:
                 return response.json(414)
 
-    def do_ali_pay_callback(self, request):
-        response = ResponseObject()
-        data = request.POST.dict()
-        signature = data["sign"]
-        data.pop('sign')
-        orderID = data['out_trade_no']
-
-        order_qs = Order_Model.objects.filter(orderID=orderID, status=0)
-        print(order_qs)
-
-        if not order_qs.exists():
-            return response.json(404)
-        print(json.dumps(data))
-        print(signature)
-        # verify
-        aliPayObj = AliPayObject()
-        alipay = aliPayObj.conf()
-        success = alipay.verify(data, signature)
-        if success and data["trade_status"] in ("TRADE_SUCCESS", "TRADE_FINISHED"):
-            print("trade succeed")
-            nowTime = int(time.time())
-            order_list = order_qs.values("UID", "rank__id", "channel")
-            rank_id = order_list[0]['rank__id']
-            print(rank_id)
-            UID = order_list[0]['UID']
-            channel = order_list[0]['channel']
-            order_qs.update(status=1, updTime=nowTime, trade_no=data['trade_no'])
-
-            smqs = Store_Meal.objects.filter(id=rank_id).values("day", "bucket_id", "bucket__storeDay")
-            bucketId = smqs[0]['bucket_id']
-            if not smqs.exists():
-                return response.json(0, '套餐已删除')
-            addTime = int(smqs[0]["day"]) * 24 * 3600
-            ubqs = UID_Bucket.objects.filter(uid=UID, channel=channel). \
-                values("bucket_id", "endTime", "bucket__storeDay")
-            nowTime = int(time.time())
-            if ubqs.exists():
-                # 判断是否过期了
-                if nowTime > ubqs[0]['endTime']:
-                    ubqs.update(endTime=nowTime + addTime)
-                else:
-                    # 同一个bucket续费
-                    if bucketId == ubqs[0]['bucket_id']:
-                        ubqs.update(endTime=ubqs[0]['endTime'] + addTime)
-                    else:
-                        if ubqs[0]['bucket__storeDay'] > smqs[0]['bucket__storeDay']:
-                            return response.json(10, '不可选低级别套餐')
-                        else:
-                            # 升级
-                            origin_storeDay = int(ubqs[0]['bucket__storeDay'])
-                            upgrade_storeDay = int(smqs[0]['bucket__storeDay'])
-                            ctcTime = ubqs[0]['endTime'] - nowTime
-                            multiple = math.ceil(upgrade_storeDay / origin_storeDay)
-                            ubqs.update(endTime=ctcTime / multiple + addTime + ubqs[0]['endTime'], bucket_id=bucketId)
-                            # 付款成功把oss token删除
-                            OssCrdModel.objects.filter(uid=UID, channel=channel).delete()
-            # 新增模式
-            else:
-                print('create')
-                UID_Bucket.objects.create(uid=UID, channel=channel,
-                                          bucket_id=bucketId, endTime=nowTime + addTime)
-            red_url = "{SERVER_DOMAIN}cloudVod/payOK".format(SERVER_DOMAIN=SERVER_DOMAIN)
-            return HttpResponseRedirect(red_url)
-        return response.json(0, signature)
-
-    #发起支付宝支付
-    def do_pay_by_ali(self, request_dict, userID, response):
-        uid = request_dict.get('uid', None)
-        rank = request_dict.get('rank', None)
-        channel = request_dict.get('channel', None)
-        qs = Device_Info.objects.filter(userID_id=userID, UID=uid, isShare=False)
-        if not qs.exists():
-            return response.json(12)
-        if not channel or not rank:
-            return response.json(444, 'channel,rank')
-        smqs = Store_Meal.objects.filter(id=rank). \
-            values("title", "currency", "price", "content", "day", "bucket__storeDay", "bucket__region", "type")
-        if not smqs.exists():
-            # 套餐不存在
-            return response.json(173)
-        if smqs[0]['type'] != 1:
-            return response.json(10, '不支持支付宝支付')
-        currency = smqs[0]['currency']
-        price = smqs[0]['price']
-        content = smqs[0]['content']
-        day = smqs[0]['day']
-        nowTime = int(time.time())
-        ubqs = UID_Bucket.objects.filter(uid=uid, channel=channel, endTime__gte=nowTime). \
-            values("bucket__storeDay", "bucket__region")
-        if ubqs.exists():
-            if ubqs[0]['bucket__region'] != smqs[0]['bucket__region']:
-                return response.json(712)  # 区域不一致
-            elif ubqs[0]['bucket__storeDay'] != smqs[0]['bucket__storeDay']:
-                return response.json(713)  # 不可更改套餐
-            # 续费流程
-        nowTime = int(time.time())
-        # 新增流程
-        orderID = CommonService.createOrderID()
-
-        try:
-            aliPayObj = AliPayObject()
-            alipay = aliPayObj.conf()
-            order_string = alipay.api_alipay_trade_wap_pay(
-                out_trade_no=orderID,
-                total_amount=price,
-                subject=smqs[0]['title'],
-                return_url="{SERVER_DOMAIN_SSL}cloudVod/payOK".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL),
-                notify_url="{SERVER_DOMAIN_SSL}cloudVod/aliPayCallback".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
-                # return_url="http://192.168.136.40/cloudVod/payOK",
-                # notify_url="http://192.168.136.40/cloudVod/aliPayCallback"
-            )
-            print(order_string)
-        except Exception as e:
-            print(repr(e))
-            return response.json(10, repr(e))
-        if order_string:
-            redirectUrl = aliPayObj.alipay_prefix + order_string
-            Order_Model.objects.create(orderID=orderID, UID=uid, channel=channel, userID_id=userID, desc=content,
-                                       price=price, currency=currency, addTime=nowTime, updTime=nowTime,
-                                       endTime=nowTime + int(day) * 3600 * 24, rank_id=rank, payType=1)
-            return JsonResponse(status=200,
-                                data={'result_code': 0, 'reason': 'success',
-                                      'result': {"redirectUrl": redirectUrl, "orderID": orderID},
-                                      'error_code': 0})
-        else:
-            return response.json(10, '生成订单错误')
-
     def do_get_details(self, request_dict, response):
         uid = request_dict.get('uid', None)
         dvqs = Device_Info.objects.filter(UID=uid, isShare=False)
@@ -438,262 +292,6 @@ class CloudVodView(View):
         '''
         return response
 
-    def do_pay_by_ali_callback(self, request):
-        response = ResponseObject()
-        data = request.POST.dict()
-        signature = data["sign"]
-        data.pop('sign')
-        orderID = data['out_trade_no']
-
-        order_qs = Order_Model.objects.filter(orderID=orderID, status=0)
-        print(order_qs)
-
-        if not order_qs.exists():
-            return response.json(404)
-        print(json.dumps(data))
-        print(signature)
-        # verify
-        aliPayObj = AliPayObject()
-        alipay = aliPayObj.conf()
-        success = alipay.verify(data, signature)
-        if success and data["trade_status"] in ("TRADE_SUCCESS", "TRADE_FINISHED"):
-            print("trade succeed")
-            nowTime = int(time.time())
-            order_list = order_qs.values("UID", "commodity_code", "channel")
-            UID = order_list[0]['UID']
-            channel = order_list[0]['channel']
-            commodity_code = order_list[0]['commodity_code']
-            order_qs.update(status=1, updTime=nowTime)
-            smqs = Store_Meal.objects.filter(commodity_code=commodity_code).\
-                values("day", "bucket_id", "bucket__storeDay")
-            bucketId = smqs[0]['bucket_id']
-            if not smqs.exists():
-                return response.json(0, '套餐已删除')
-            addTime = int(smqs[0]["day"]) * 24 * 3600
-            ubqs = UID_Bucket.objects.filter(uid=UID, channel=channel). \
-                values("bucket_id", "endTime", "bucket__storeDay")
-            nowTime = int(time.time())
-            if ubqs.exists():
-                ubqs_count = ubqs.count()
-                ubq = ubqs[ubqs_count - 1, ubqs_count]
-                new_starTime = ubq['endTime'] + 1
-                UID_Bucket.objects.create(uid=UID, channel=channel, bucket_id=bucketId, endTime=new_starTime + addTime)
-            else:
-                UID_Bucket.objects.create(uid=UID, channel=channel, bucket_id=bucketId, endTime=nowTime + addTime)
-            red_url = "{SERVER_DOMAIN}cloudVod/payOK".format(SERVER_DOMAIN=SERVER_DOMAIN)
-            return HttpResponseRedirect(red_url)
-        return response.json(0, signature)
-
-    def do_pay_by_paypal_callback(self, request_dict, response):
-        paymentId = request_dict.get('paymentId', None)
-        PayerID = request_dict.get('PayerID', None)
-        orderID = request_dict.get('orderID', None)
-        if not paymentId or not PayerID or not orderID:
-            red_url = "{SERVER_DOMAIN}cloudVod/payError".format(SERVER_DOMAIN=SERVER_DOMAIN)
-            return HttpResponseRedirect(red_url)
-        paypalrestsdk.configure(PAYPAL_CRD)
-        # ID of the payment. This ID is provided when creating payment.
-        payment = paypalrestsdk.Payment.find(paymentId)
-        payres = payment.execute({"payer_id": PayerID})
-        print(payres)
-        if not payres:
-            red_url = "{SERVER_DOMAIN}cloudVod/payError".format(SERVER_DOMAIN=SERVER_DOMAIN)
-            return HttpResponseRedirect(red_url)
-        print("Payment execute successfully")
-        order_qs = Order_Model.objects.filter(orderID=orderID)
-        nowTime = int(time.time())
-        order_qs.update(status=1, updTime=nowTime)
-        order_list = order_qs.values("UID", "channel", "commodity_code")
-        UID = order_list[0]['UID']
-        channel = order_list[0]['channel']
-        commodity_code = order_list[0]['commodity_code']
-        smqs = Store_Meal.objects.filter(commodity_code=commodity_code).\
-            values("day", "bucket_id", "bucket__storeDay")
-        bucketId = smqs[0]['bucket_id']
-        if not smqs.exists():
-            return response.json(0, '套餐已删除')
-        addTime = int(smqs[0]["day"]) * 24 * 3600
-        # ##
-        ubqs = UID_Bucket.objects.filter(uid=UID, channel=channel, endTime__gte=nowTime). \
-            values("bucket__storeDay", "bucket__region", "endTime")
-        if ubqs.exists():
-            ubqs_count = ubqs.count()
-            ubq = ubqs[ubqs_count - 1, ubqs_count]
-            new_starTime = ubq['endTime'] + 1
-            UID_Bucket.objects.create(uid=UID, channel=channel, bucket_id=bucketId, endTime=new_starTime + addTime)
-        else:
-            UID_Bucket.objects.create(uid=UID, channel=channel, bucket_id=bucketId, endTime=nowTime + addTime)
-            # return response.json(0)
-        red_url = "{SERVER_DOMAIN}cloudVod/payOK".format(SERVER_DOMAIN=SERVER_DOMAIN)
-        return HttpResponseRedirect(red_url)
-
-    def do_create_pay_order(self, request_dict, userID, response):
-        uid = request_dict.get('uid', None)
-        channel = request_dict.get('channel', None)
-        commodity_code = request_dict.get('commodity_code', None)
-        pay_type = int(request_dict.get('pay_type', None))
-        dv_qs = Device_Info.objects.filter(userID_id=userID, UID=uid, isShare=False, isExist=1)
-        if not dv_qs.exists():
-            return response.json(12)
-        smqs = Store_Meal.objects.filter(commodity_code=commodity_code, type=pay_type). \
-            values('currency', 'price', 'content', 'day', 'commodity_type', 'title', 'content')
-        if not smqs.exists():
-            return response.json(10, '套餐不存在')
-        currency = smqs[0]['currency']
-        price = smqs[0]['price']
-        content = smqs[0]['content']
-        day = smqs[0]['day']
-        commodity_type = smqs[0]['commodity_type']
-        # ubqs = UID_Bucket.objects.filter(uid=uid, channel=channel, endTime__gte=nowTime). \
-        #     values("bucket__storeDay", "bucket__region", "endTime")
-        # if ubqs.exists():
-        #     ubqs_count = ubqs.count()
-        #     ubq = ubqs[ubqs_count - 1, ubqs_count]
-        #     new_starTime = ubq['endTime'] + 1
-        nowTime = int(time.time())
-        orderID = CommonService.createOrderID()
-        if pay_type == 0:
-            call_sub_url = "{SERVER_DOMAIN}cloudVod/dopaypalcallback?orderID={orderID}". \
-                format(SERVER_DOMAIN=SERVER_DOMAIN, orderID=orderID)
-            # call_sub_url = "http://192.168.136.40:8077/cloudVod/payExecute?orderID={orderID}".format(
-            #     SERVER_DOMAIN=SERVER_DOMAIN, orderID=orderID)
-            call_clc_url = "{SERVER_DOMAIN}cloudVod/payError".format(SERVER_DOMAIN=SERVER_DOMAIN)
-            paypalrestsdk.configure(PAYPAL_CRD)
-            payment = paypalrestsdk.Payment({
-                "intent": "sale",
-                "payer": {"payment_method": "paypal"},
-                "redirect_urls": {"return_url": call_sub_url, "cancel_url": call_clc_url},
-                "transactions": [{
-                    "item_list": {
-                        "items": [
-                            {"name": "Cloud video", "sku": "1", "price": price, "currency": "USD", "quantity": 1}]},
-                    "amount": {"total": price, "currency": currency},
-                    "description": content
-                }]})
-            if payment.create():
-                print("Payment created successfully")
-            else:
-                print(payment.error)
-                return response.json(10, payment.error)
-            print(payment)
-            for link in payment.links:
-                if link.rel == "approval_url":
-                    approval_url = str(link.href)
-                    print("Redirect for approval: %s" % (approval_url))
-                    Order_Model.objects.create(orderID=orderID, UID=uid, channel=channel, userID_id=userID,
-                                               desc=content,
-                                               price=price, currency=currency, addTime=nowTime, updTime=nowTime,
-                                               endTime=(nowTime + int(day) * 3600 * 24), paypal=approval_url,
-                                               commodity_code=commodity_code, commodity_type=commodity_type)
-                    return response.json(0, {"redirectUrl": approval_url, "orderID": orderID})
-            return response.json(10, 'generate_order_false')
-        else:
-            try:
-                aliPayObj = AliPayObject()
-                alipay = aliPayObj.conf()
-                subject = smqs[0]['title'] + smqs[0]['content']
-                order_string = alipay.api_alipay_trade_wap_pay(
-                    out_trade_no=orderID,
-                    total_amount=price,
-                    subject=subject,
-                    return_url="{SERVER_DOMAIN_SSL}cloudVod/payOK".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL),
-                    notify_url="{SERVER_DOMAIN_SSL}cloudVod/doalicallback".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
-                    # return_url="http://192.168.136.40/cloudVod/payOK",
-                    # notify_url="http://192.168.136.40/cloudVod/aliPayCallback"
-                )
-            except Exception as e:
-                print(repr(e))
-                return response.json(10, repr(e))
-            else:
-                if order_string:
-                    redirectUrl = aliPayObj.alipay_prefix + order_string
-                    Order_Model.objects.create(orderID=orderID, UID=uid, channel=channel, userID_id=userID,
-                                               desc=content, price=price, currency=currency, addTime=nowTime,
-                                               updTime=nowTime, endTime=nowTime + int(day) * 3600 * 24,
-                                               commodity_code=commodity_code, commodity_type=commodity_type,
-                                               paypal='', payType=1)
-                    return JsonResponse(status=200, data={'result_code': 0, 'reason': 'success',
-                                                          'result': {"redirectUrl": redirectUrl, "orderID": orderID},
-                                                          'error_code': 0})
-                else:
-                    return response.json(10, '生成订单错误')
-
-    # 发起paypal支付
-    def do_create_order(self, request_dict, userID, response):
-        uid = request_dict.get('uid', None)
-        rank = request_dict.get('rank', None)
-        channel = request_dict.get('channel', None)
-        if not uid or not channel or not rank:
-            return response.json(444, 'channel,rank')
-        qs = Device_Info.objects.filter(userID_id=userID, UID=uid, isShare=False)
-
-        if not qs.exists():
-            return response.json(12)
-        smqs = Store_Meal.objects.filter(id=rank). \
-            values("currency", "price", "content", "day", "bucket__storeDay", "bucket__region", "type")
-        if not smqs.exists():
-            return response.json(10, '套餐不存在')
-        if smqs[0]['type'] != 0:
-            return response.json(10, '套餐不支持paypal支付')
-        currency = smqs[0]['currency']
-        price = smqs[0]['price']
-        content = smqs[0]['content']
-        day = smqs[0]['day']
-        nowTime = int(time.time())
-        ubqs = UID_Bucket.objects.filter(uid=uid, channel=channel, endTime__gte=nowTime). \
-            values("bucket__storeDay", "bucket__region")
-        if ubqs.exists():
-            if ubqs[0]['bucket__region'] != smqs[0]['bucket__region']:
-                return response.json(712)  # 区域不一致
-            # elif ubqs[0]['bucket__storeDay'] > smqs[0]['bucket__storeDay']:
-            #     return response.json(711)  # 不可降级
-            elif ubqs[0]['bucket__storeDay'] != smqs[0]['bucket__storeDay']:
-                return response.json(713)  # 不可更改套餐
-            # 续费流程
-        nowTime = int(time.time())
-        # 判断是否存在未完成订单
-        # hasOrder = Order_Model.objects.filter(UID=uid, channel=channel, addTime__gte=nowTime - 3600, status=0,
-        #                                       rank_id=rank, userID_id=userID).values('paypal')
-        # if hasOrder.exists():
-        #     approval_url = hasOrder[0]['paypal']
-        #     return response.json(0, {"redirectUrl": approval_url})
-        # 新增流程
-        orderID = CommonService.createOrderID()
-        call_sub_url = "{SERVER_DOMAIN}cloudVod/payExecute?orderID={orderID}". \
-            format(SERVER_DOMAIN=SERVER_DOMAIN, orderID=orderID)
-        # call_sub_url = "http://192.168.136.40:8077/cloudVod/payExecute?orderID={orderID}".format(
-        #     SERVER_DOMAIN=SERVER_DOMAIN, orderID=orderID)
-        call_clc_url = "{SERVER_DOMAIN}cloudVod/payError".format(SERVER_DOMAIN=SERVER_DOMAIN)
-        paypalrestsdk.configure(PAYPAL_CRD)
-        payment = paypalrestsdk.Payment({
-            "intent": "sale",
-            "payer": {"payment_method": "paypal"},
-            "redirect_urls": {"return_url": call_sub_url, "cancel_url": call_clc_url},
-            "transactions": [{
-                "item_list": {
-                    "items": [{"name": "Cloud video", "sku": "1", "price": price, "currency": "USD", "quantity": 1}]},
-                "amount": {"total": price, "currency": currency},
-                "description": content
-            }]})
-        if payment.create():
-            print("Payment created successfully")
-        else:
-            print(payment.error)
-            return response.json(10, payment.error)
-        print(payment)
-        for link in payment.links:
-            if link.rel == "approval_url":
-                approval_url = str(link.href)
-                print("Redirect for approval: %s" % (approval_url))
-                Order_Model.objects.create(orderID=orderID, UID=uid, trade_no=payment['id'], channel=channel, userID_id=userID, desc=content,
-                                           price=price, currency=currency, addTime=nowTime, updTime=nowTime,
-                                           endTime=nowTime + int(day) * 3600 * 24,
-                                           rank_id=rank,
-                                           paypal=approval_url)
-                return response.json(0, {"redirectUrl": approval_url, "orderID": orderID})
-        return response.json(10, 'generate_order_false')
-
-
     def do_getSts(self, request_dict, ip, response):
         uidToken = request_dict.get('uidToken', None)
         utko = UidTokenObject(uidToken)
@@ -1116,6 +714,7 @@ class CloudVodView(View):
 
     def do_pay_status(self, request_dict, userID, response):
         orderID = request_dict.get('orderID', None)
+        lang = request_dict.get('lang', None)
         om_qs = Order_Model.objects.filter(orderID=orderID).values('status')
         # response = HttpResponse()
         # success_pay_content = '''
@@ -1136,6 +735,19 @@ class CloudVodView(View):
 
                 url = "{SERVER_DOMAIN}web/paid2/fail.html".format(SERVER_DOMAIN=SERVER_DOMAIN)
 
+        if lang !='cn':
+            status = 0
+            url = "{SERVER_DOMAIN}web/paid2/en_fail.html".format(SERVER_DOMAIN=SERVER_DOMAIN)
+
+            if om_qs.exists():
+                status = om_qs[0]['status']
+                if status == 1:
+
+                    url = "{SERVER_DOMAIN}web/paid2/en_success.html".format(SERVER_DOMAIN=SERVER_DOMAIN)
+                else:
+
+                    url = "{SERVER_DOMAIN}web/paid2/en_fail.html".format(SERVER_DOMAIN=SERVER_DOMAIN)
+
         res = {'status': status, 'url': url}
         return response.json(0, res)
 

+ 14 - 8
Controller/Cloudsum.py

@@ -1,5 +1,11 @@
-from Model.models import Order_Model,UID_Bucket,UserExModel,App_Info
-from django.http import JsonResponse
+# -*- coding: utf-8 -*-
+"""
+@Time : 2021/1/8 12:00
+@Auth : liehaoquan
+@File :Cloudsum.py
+@IDE :PyCharm
+"""
+from Model.models import Order_Model, UID_Bucket, UserExModel
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from django.views import View
@@ -52,10 +58,10 @@ class Cloudsum(View):
         own_permission = ModelService.check_perm(userID=userID, permID=30)
         if own_permission is not True:
             return response.json(404)
-        res = UserExModel.objects.extra(tables=['App_Info'],
-                                        select={'appname':'App_Info.appName',
-                                                'appversion':'App_Info.newAppversion'},
-                                        where=["user_ex.appBundleId=app_Info.appBundleId"]).\
+        res = UserExModel.objects.extra(tables=['app_info'],
+                                        select={'appname':'app_info.appName',
+                                                'appversion':'app_info.newAppversion'},
+                                        where=["user_ex.appBundleId=app_info.appBundleId"]).\
             values('appBundleId','appname','appversion').annotate(dates=Count('appBundleId')).order_by()
         print(res.query)
         print(res)
@@ -84,7 +90,7 @@ class Cloudsum(View):
     # 类型:云存服务统计
     # 统计开通云存的设备有多少台√
     # 统计未支付,支付成功的订单√
-    # 统计开通云存的增长率    (每个月开通云存的总数)√
+    # 统计开通云存的增长率    (每个月开通云存套餐的总数)√
     # 统计已开通云存的各套餐总数√
     # 统计已支付的订单总金额√
     def cloudservicesum(self, userID, response):
@@ -105,7 +111,7 @@ class Cloudsum(View):
         }
         return response.json(0, data_dict)
 
-    # 每个月开通云存的总数
+    # 每个月开通云存套餐的总数
     def usercloud(self, userID, response):
         own_permission = ModelService.check_perm(userID=userID, permID=30)
         if own_permission is not True:

+ 12 - 0
Controller/EquipmentInfo.py

@@ -304,3 +304,15 @@ def deleteExpireEquipmentInfo(request):
     return response.json(0)
 
 
+# 按季度删除访问日志
+def deleteExpireEquipmentInfoById(request):
+    response = ResponseObject()
+    id = int(request.GET.get('id', None))
+
+    if id is None:
+        return response.json(0)
+
+    Equipment_Info.objects.filter(id__lte=id).delete()
+    return response.json(0)
+
+

+ 1 - 1
Controller/EquipmentManager.py

@@ -399,7 +399,7 @@ def addInterface(request):
                     vodPrimaryUserID = main_exist[0]['vodPrimaryUserID']
                     vodPrimaryMaster = main_exist[0]['vodPrimaryMaster']
 
-                is_bind = Device_Info.objects.filter(UID=UID, isShare=False).values('userID__userID')
+                is_bind = Device_Info.objects.filter(UID=UID, isShare=False).values('userID__userID', 'vodPrimaryUserID')
                 # 判断是否有已绑定用户
                 isvodPrimaryUserID = ''
 

+ 11 - 2
Controller/EquipmentManagerV2.py

@@ -168,10 +168,17 @@ class EquipmentManagerV2(View):
             nowTime = int(time.time())
             data = []
             # 设备拓展信息表
-            us_qs = UidSetModel.objects.filter(uid__in=uid_list).values('uid', 'version', 'nickname', 'ucode','detect_interval')
+            us_qs = UidSetModel.objects.filter(uid__in=uid_list).values('uid', 'version', 'nickname', 'ucode','detect_interval', 'is_human', 'is_custom_voice')
             uv_dict = {}
             for us in us_qs:
-                uv_dict[us['uid']] = {'version': us['version'], 'nickname': us['nickname'], 'ucode': us['ucode'],'detect_interval':us['detect_interval']}
+                uv_dict[us['uid']] = {
+                    'version': us['version'],
+                    'nickname': us['nickname'],
+                    'ucode': us['ucode'],
+                    'detect_interval': us['detect_interval'],
+                    'is_human': us['is_human'],
+                    'is_custom_voice': us['is_custom_voice'],
+                }
             for p in dvls:
                 p['vod'] = []
                 for dm in ubqs:
@@ -190,6 +197,8 @@ class EquipmentManagerV2(View):
                     p['uid_version'] = uv_dict[p_uid]['version']
                     p['ucode'] = uv_dict[p_uid]['ucode']
                     p['detect_interval'] = uv_dict[p_uid]['detect_interval']
+                    p['is_human'] = uv_dict[p_uid]['is_human']
+                    p['is_custom_voice'] = uv_dict[p_uid]['is_custom_voice']
                     # 设备昵称 调用影子信息昵称,先阶段不可
                     if uv_dict[p_uid]['nickname']:
                         p['NickName'] = uv_dict[p_uid]['nickname']

+ 6 - 2
Controller/EquipmentManagerV3.py

@@ -324,7 +324,7 @@ class EquipmentManagerV3(View):
                                                                         'TimeZone', 'TimeStatus', 'SpaceUsable',
                                                                         'SpaceSum', 'MirrorType', 'RecordType',
                                                                         'OutdoorModel', 'WIFIName', 'isDetector',
-                                                                        'DetectorRank')
+                                                                        'DetectorRank', 'is_human', 'is_custom_voice')
             uv_dict = {}
             for us in us_qs:
                 uv_dict[us['uid']] = {
@@ -346,7 +346,9 @@ class EquipmentManagerV3(View):
                     'OutdoorModel': us['OutdoorModel'],
                     'WIFIName': us['WIFIName'],
                     'isDetector': us['isDetector'],
-                    'DetectorRank': us['DetectorRank']
+                    'DetectorRank': us['DetectorRank'],
+                    'is_human': us['is_human'],
+                    'is_custom_voice': us['is_custom_voice']
                 }
                 # 从uid_channel里面取出通道配置信息
                 ucs_qs = UidChannelSetModel.objects.filter(uid__id=us['id']).values('channel', 'pir_audio', 'mic_audio',
@@ -412,6 +414,8 @@ class EquipmentManagerV3(View):
                     p['WIFIName'] = uv_dict[p_uid]['WIFIName']
                     p['isDetector'] = uv_dict[p_uid]['isDetector']
                     p['DetectorRank'] = uv_dict[p_uid]['DetectorRank']
+                    p['is_human'] = uv_dict[p_uid]['is_human']
+                    p['is_custom_voice'] = uv_dict[p_uid]['is_custom_voice']
                     p['channels'] = uv_dict[p_uid]['channels']
                     # 设备昵称 调用影子信息昵称,先阶段不可
                     if uv_dict[p_uid]['nickname']:

+ 47 - 0
Controller/IotCoreController.py

@@ -0,0 +1,47 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+import boto3
+from django.views import View
+
+from Ansjer.config import AWS_IOT_SES_ACCESS_REGION, AWS_IOT_SES_ACCESS_ID, \
+    AWS_IOT_SES_ACCESS_SECRET
+from Object.ResponseObject import ResponseObject
+
+
+class IotCoreView(View):
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.GET
+        operation = kwargs.get('operation', None)
+        return self.validate(operation, request_dict)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.POST
+        operation = kwargs.get('operation', None)
+        return self.validate(operation, request_dict)
+
+    def validate(self, operation, request_dict):
+
+        response = ResponseObject()
+
+        if operation == 'createProvisioningClaim':
+            return self.create_provisioning_claim(response)
+        else:
+            return response.json(404)
+
+    def create_provisioning_claim(self, response):
+        client = boto3.client('iot', region_name=AWS_IOT_SES_ACCESS_REGION, aws_access_key_id=AWS_IOT_SES_ACCESS_ID,
+                              aws_secret_access_key=AWS_IOT_SES_ACCESS_SECRET)
+        result = client.create_provisioning_claim(templateName='Ansjer_Iot_Queue')
+
+        res = {
+            'certificateId': result['certificateId'],
+            'certificatePem': result['certificatePem'],
+            'publicKey': result['keyPair']['PublicKey'],
+            'privateKey': result['keyPair']['PrivateKey'],
+            'endpoint': 'a2rqy12o004ad8-ats.iot.us-east-1.amazonaws.com'
+        }
+
+        return response.json(0, {'res': res})

+ 118 - 24
Controller/MealManage.py

@@ -13,12 +13,13 @@
 """
 import traceback
 
+from django.db.models import F
 from django.utils import timezone
 from django.utils.decorators import method_decorator
 from django.views.decorators.csrf import csrf_exempt
 from django.views.generic.base import View
 
-from Model.models import Store_Meal, VodBucketModel, Pay_Type
+from Model.models import Store_Meal, VodBucketModel, Pay_Type, Lang
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Service.CommonService import CommonService
@@ -68,26 +69,35 @@ class MealManage(View):
             return self.delete(request_dict, userID, response)
         elif operation == 'find':
             return self.find(request_dict, userID, response)
+        elif operation == 'query_language':
+            return self.query_language(request_dict, response)
+        elif operation == 'add_language':
+            return self.add_language(request_dict, response)
+        elif operation == 'delete_language':
+            return self.delete_language(request_dict, response)
+        elif operation == 'edit_language':
+            return self.edit_language(request_dict, response)
         else:
             return response.json(444, 'operation')
 
     def add(self, request_dict, userID, response):
-        title = request_dict.get('title', None)
+        # title = request_dict.get('title', None)
         id = request_dict.get('id', None)
         price = request_dict.get('price', None)
-        content = request_dict.get('content', None)
+        # content = request_dict.get('content', None)
         day = request_dict.get('day', None)
+        commodity_code = request_dict.get('commodity_code', None)
         currency = request_dict.get('currency', None)
         bucketID = request_dict.get('bucketID', None)
         paytype = request_dict.get('paytype', None)
         virtual_price = request_dict.get('virtual_price', None)
         is_discounts = request_dict.get('is_discounts', None)
         discount_price = request_dict.get('discount_price', None)
-        discount_content = request_dict.get('discount_content', None)
         expire = request_dict.get('expire', None)
         symbol = request_dict.get('symbol', None)
 
-        if not title or not id or not price or not day or not content:
+        # if not title or not id or not price or not day or not content:
+        if not id or not price or not day:
             return response.json(444, 'title,id,price,content,day,bucketID')
         own_perm = ModelService.check_perm(userID=userID, permID=40)
         if own_perm is not True:
@@ -96,9 +106,9 @@ class MealManage(View):
             bucketQs = VodBucketModel.objects.filter(id=bucketID)
             if Store_Meal.objects.filter(id=id):
                 return response.json(10, '已存在')
-            store_meal = Store_Meal(id=id, title=title, price=price, content=content, day=day, bucket_id=bucketID,
+            store_meal = Store_Meal(id=id, price=price, day=day, bucket_id=bucketID, commodity_code=commodity_code,
                                     currency=currency, virtual_price=virtual_price, is_discounts=is_discounts,
-                                    discount_price=discount_price, discount_content=discount_content, expire=expire, symbol=symbol)
+                                    discount_price=discount_price, expire=expire, symbol=symbol)
             store_meal.save()
             paytype = paytype.split(',')
             if len(paytype) > 0:
@@ -113,32 +123,31 @@ class MealManage(View):
                     'bucket__bucket': bucketQs[0].bucket,
                     'bucket__storeDay': bucketQs[0].storeDay,
                     'id': id,
-                    'title': title,
                     'price': price,
-                    'content': content,
                     'currency': currency,
                     'day': day,
                     'add_time': str(store_meal.add_time),
                     'update_time': str(store_meal.update_time)})
 
     def query(self, request_dict, response):
-
         page = int(request_dict.get('page', None))
         line = int(request_dict.get('line', None))
+        lang = request_dict.get('lang', 'cn')
         if page is None or line is None:
             return response.json(444)
 
-        qs = Store_Meal.objects.values("id", "title", "price", "content", "day", "add_time", "update_time", "currency"
-                                       , "bucket_id", "commodity_type", "commodity_code", "virtual_price", "is_discounts"
-                                       , "discount_price", "discount_content", "expire", "symbol"
-                                       , "bucket__bucket", "bucket__area", "bucket__storeDay")
+        qs = Store_Meal.objects.filter(lang__lang=lang)
+        qs = qs.annotate(title=F('lang__title'), content=F('lang__content'))
+        qs = qs.values("id", "title", "price", "day", "add_time", "update_time", "currency", "expire", "symbol"
+                       , "commodity_type", "commodity_code", "virtual_price", "is_discounts", "discount_price"
+                       , "bucket_id", "bucket__bucket", "bucket__area", "bucket__storeDay", "bucket__mold")
         res = {}
         if qs.exists():
             ql = list(qs)
             from operator import itemgetter
             from itertools import groupby
             ql.sort(key=itemgetter('bucket__area'))
-            ql=CommonService.qs_to_list(ql[(page - 1) * line:page * line])
+            ql = CommonService.qs_to_list(ql[(page - 1) * line:page * line])
             # for area, items in groupby(ql, key=itemgetter('bucket__area')):
             items_list = list(ql)
             for key, val in enumerate(items_list):
@@ -150,10 +159,10 @@ class MealManage(View):
 
     def update(self, request_dict, userID, response):
         id = request_dict.get('id', None)
-        title = request_dict.get('title', None)
+        # title = request_dict.get('title', None)
         price = request_dict.get('price', None)
         day = request_dict.get('day', None)
-        content = request_dict.get('content', None)
+        # content = request_dict.get('content', None)
         currency = request_dict.get('currency', None)
         bucketID = request_dict.get('bucketID', None)
         commodity_type = request_dict.get('commodity_type', None)
@@ -161,12 +170,13 @@ class MealManage(View):
         virtual_price = request_dict.get('virtual_price', None)
         is_discounts = request_dict.get('is_discounts', None)
         discount_price = request_dict.get('discount_price', None)
-        discount_content = request_dict.get('discount_content', None)
         expire = request_dict.get('expire', None)
         symbol = request_dict.get('symbol', None)
         type = request_dict.get('type', None)
-        if not id or not title or not price or not content or not day or not type:
-            return response.json(444, 'id, title, price, content, day,type')
+        # if not id or not title or not price or not content or not day or not type:
+        if not id or not price or not day or not type:
+            # return response.json(444, 'id, title, price, content, day,type')
+            return response.json(444, 'id, price, day,type')
         own_perm = ModelService.check_perm(userID=userID, permID=30)
         if own_perm is not True:
             return response.json(404)
@@ -174,15 +184,14 @@ class MealManage(View):
             store_meal = Store_Meal.objects.get(id=id)
             now_time = timezone.localtime(timezone.now())
             print(now_time)
-            store_meal.title = title
+            # store_meal.title = title
             store_meal.price = price
-            store_meal.content = content
+            # store_meal.content = content
             store_meal.commodity_type = commodity_type
             store_meal.commodity_code = commodity_code
             store_meal.virtual_price = virtual_price
             store_meal.is_discounts = is_discounts
             store_meal.discount_price = discount_price
-            store_meal.discount_content = discount_content
             store_meal.expire = expire
             store_meal.symbol = symbol
             store_meal.day = day
@@ -238,6 +247,91 @@ class MealManage(View):
             return response.json(0, send_json)
         return response.json(0)
 
+    def query_language(self, request_dict, response):
+        # 查询套餐语言
+        page = int(request_dict.get('page', None))
+        line = int(request_dict.get('line', None))
+        id = request_dict.get('id', None)
+        if page is None or line is None:
+            return response.json(444)
+
+        if id:
+            # 如果传入id,只查询id下的语言
+            storeMeal_lang_qs = Store_Meal.objects.filter(id=id, lang__isnull=False).values('id', 'lang__id',
+                                                                                            'lang__lang',
+                                                                                            'lang__title',
+                                                                                            'lang__content',
+                                                                                            'lang__discount_content')
+        else:
+            storeMeal_lang_qs = Store_Meal.objects.filter(lang__isnull=False).values('id', 'lang__id', 'lang__lang',
+                                                                                     'lang__title', 'lang__content',
+                                                                                     'lang__discount_content')
+        count = storeMeal_lang_qs.count()
+        storeMeal_lang_qs = storeMeal_lang_qs[(page - 1) * line:page * line]
+        res = {
+            'datas': list(storeMeal_lang_qs),
+            'count': count
+        }
+        return response.json(0, res)
+
+    def add_language(self, request_dict, response):
+        # 添加套餐语言
+        store_meal_id = request_dict.get('store_meal_id', None)
+        # lang_id = request_dict.get('lang_id', None)
+        lang = request_dict.get('lang', None)
+        title = request_dict.get('title', None)
+        content = request_dict.get('content', None)
+        discount_content = request_dict.get('discount_content', None)
+        if not store_meal_id or not lang or not title or not content or not discount_content:
+            return response.json(444, 'store_meal_id,lang,title,content,discount_content')
+        # 查询该套餐是否存在
+        storeMeal_qs = Store_Meal.objects.get(id=store_meal_id)
+        if not storeMeal_qs:
+            return response.json(500)
+        lang_obj = Lang.objects.filter(lang=lang, title=title, content=content, discount_content=discount_content)
+        if not lang_obj.exists():
+            # 数据不存在,lang表创建数据
+            Lang.objects.create(lang=lang, title=title, content=content, discount_content=discount_content)
+            lang_obj = Lang.objects.filter(lang=lang, title=title, content=content, discount_content=discount_content)
+        storeMeal_qs.lang.add(*lang_obj)  # store_meal表添加语言数据
+        return response.json(0)
+
+    def edit_language(self, request_dict, response):
+        # 编辑套餐语言
+        store_meal_id = request_dict.get('store_meal_id', None)
+        lang_id = request_dict.get('lang_id', None)
+        lang = request_dict.get('lang', None)
+        title = request_dict.get('title', None)
+        content = request_dict.get('content', None)
+        discount_content = request_dict.get('discount_content', None)
+        if not store_meal_id or not lang_id or not lang or not title or not content or not discount_content:
+            return response.json(444, 'store_meal_id,lang_id,lang,title,content,discount_content')
+        storeMeal_qs = Store_Meal.objects.get(id=store_meal_id)
+        if not storeMeal_qs:
+            return response.json(500)
+        # 删除原有数据
+        lang_qs = Lang.objects.filter(id=lang_id)
+        storeMeal_qs.lang.remove(*lang_qs)
+        lang_obj = Lang.objects.filter(lang=lang, title=title, content=content, discount_content=discount_content)
+        if not lang_obj.exists():
+            # 数据不存在,lang表创建数据
+            Lang.objects.create(lang=lang, title=title, content=content, discount_content=discount_content)
+            lang_obj = Lang.objects.filter(lang=lang, title=title, content=content, discount_content=discount_content)
+        storeMeal_qs.lang.add(*lang_obj)  # store_meal表添加语言数据
+        return response.json(0)
+
+    def delete_language(self, request_dict, response):
+        # 删除套餐语言
+        store_meal_id = request_dict.get('store_meal_id', None)
+        lang_id = request_dict.get('lang_id', None)
+
+        storeMeal_qs = Store_Meal.objects.get(id=store_meal_id)
+        if not storeMeal_qs:
+            return response.json(500)
+        lang_qs = Lang.objects.filter(id=lang_id)
+        storeMeal_qs.lang.remove(*lang_qs)
+        return response.json(0)
+
 
 '''
 用户获取全部套餐信息
@@ -306,4 +400,4 @@ class MealView(View):
             }
             return response.json(0, result)
         else:
-            return response.json(0)
+            return response.json(0)

+ 69 - 0
Controller/OTAEquipment.py

@@ -685,3 +685,72 @@ def downloadOTAInterfaceV2(request, fullPath, *callback_args, **callback_kwargs)
             return res.json(907)
     else:
         return res.json(444, 'fullPath')
+
+
+@csrf_exempt
+def getDownLoadOTApackUrl(request):
+    # QT获取升级文件的下载链接
+    response = ResponseObject()
+    if request.method == "POST":
+        request_dict = request.POST
+    elif request.method == "GET":
+        request_dict = request.GET
+    else:
+        return response.json(444)
+    deviceType = request_dict.get('deviceType', None)
+    version = request_dict.get('version', None)
+    if not deviceType or not version:
+        return response.json(444, 'deviceType or version')
+    equipmentVersion = Equipment_Version.objects.filter(mci=deviceType, version=version)
+    # 判断是否有该版本存在
+    if not equipmentVersion.exists():
+        return response.json(907)
+    file_path = equipmentVersion[0].filePath
+    if file_path:
+        if file_path.find('static/otapack') != -1:  # 只下载otapack路径下的文件
+            url = SERVER_DOMAIN + 'OTA/downloadsPack/' + file_path  # 复用以前的文件下载方式
+            # SERVER_DOMAIN = 'https://test.dvema.com/'
+            # url = SERVER_DOMAIN + 'OTA/downloadsPack/' + file_path
+            res = {
+                "url": url,
+            }
+            return response.json(0, res)
+        else:
+            return response.json(901)
+    else:
+        return response.json(901)
+
+
+@csrf_exempt
+def checkMaxVersion(request):
+    # QT检查ota设备软件版本是否为最新版本
+    response = ResponseObject()
+    if request.method == "POST":
+        request_dict = request.POST
+    elif request.method == "GET":
+        request_dict = request.GET
+    else:
+        return response.json(444)
+    deviceType = request_dict.get('deviceType', None)
+    version = request_dict.get('version', None) # 设备版本:当前版本+设备规格代码
+    if not deviceType or not version:
+        return response.json(444, 'deviceType or version')
+    equipmentVersion = Equipment_Version.objects.filter(mci=deviceType, version=version)
+    # 判断是否有该版本存在
+    if not equipmentVersion.exists():
+        return response.json(907)
+    # now_version = version[:version.rindex('.')]
+    # code = version[version.rindex('.')+1:]
+
+    file_path = equipmentVersion[0].filePath
+    softwareVersion = equipmentVersion[0].softwareVersion
+    max_version = equipmentVersion[0].max_ver
+    if softwareVersion < max_version:
+        # 当前版本小于最大版本,返回文件下载链接
+        url = SERVER_DOMAIN + 'OTA/downloadsPack/' + file_path
+        res = {
+            "url": url,
+        }
+        return response.json(0, res)
+    else:
+        return response.json(902)

+ 16 - 13
Controller/OrderContrller.py

@@ -14,6 +14,7 @@
 import time
 
 import paypalrestsdk
+from django.db.models import F
 from django.utils.decorators import method_decorator
 from django.views.decorators.csrf import csrf_exempt
 from django.views.generic.base import View
@@ -90,11 +91,12 @@ class OrderView(View):
         page = request_dict.get('page', None)
         line = request_dict.get('line', None)
         uid = request_dict.get('uid', None)
+        lang = request_dict.get('lang', None)
         if not page or not line:
             return response.json(444, 'page,line')
         page = int(page)
         line = int(line)
-        omqs = Order_Model.objects.filter(userID_id=userID, status=1)
+        omqs = Order_Model.objects.filter(userID_id=userID, status=1, rank__lang__lang=lang)
         # 筛选指定设备id的订单
         if uid:
             omqs.filter(UID=uid)
@@ -102,6 +104,7 @@ class OrderView(View):
             return response.json(173)
             # return response.json(10, '订单不存在')
         count = omqs.count()
+        omqs = omqs.annotate(rank__title=F('rank__lang__title'), rank__content=F('rank__lang__content'))
         order_ql = omqs[(page - 1) * line:page * line].values("orderID", "UID", "channel", "desc", "price", "currency",
                                                               "addTime",
                                                               "updTime", "paypal", "rank__day", "payType",
@@ -147,7 +150,7 @@ class OrderView(View):
             orderID = request_dict.get('orderID', None)
             page = int(page)
             line = int(line)
-            omqs = Order_Model.objects.filter()
+            omqs = Order_Model.objects.all()
             # 筛选指定设备id的订单
             if uid:
                 omqs = omqs.filter(UID=uid)
@@ -162,9 +165,7 @@ class OrderView(View):
                                                                   "currency", "addTime", "updTime", "paypal",
                                                                   "payType",
                                                                   "rank__day",
-                                                                  "rank__price", "status",
-                                                                  "rank__content", "rank__title", "rank__currency",
-                                                                  "rank_id")
+                                                                  "rank__price", "status")
             order_list = list(order_ql)
             return response.json(0, {'data': order_list, 'count': count})
 
@@ -175,16 +176,16 @@ class OrderView(View):
         status = request_dict.get('status', None)
         page = request_dict.get('page', None)
         line = request_dict.get('line', None)
-
+        lang = request_dict.get('lang',None)
         if status and page and line:
             order_qs = None
             status = int(status)
             if status == -1: # 获取所有订单
-                order_qs = Order_Model.objects.filter(userID__userID=userID)
+                order_qs = Order_Model.objects.filter(userID__userID=userID,rank__lang__lang=lang)
             elif status == 0: # 获取【代付款】订单
-                order_qs = Order_Model.objects.filter(userID__userID=userID, status=0)
+                order_qs = Order_Model.objects.filter(userID__userID=userID, status=0,rank__lang__lang=lang)
             elif status == 1:
-                order_qs = Order_Model.objects.filter(userID__userID=userID, status=1)
+                order_qs = Order_Model.objects.filter(userID__userID=userID, status=1,rank__lang__lang=lang)
 
             if order_qs is None or not order_qs.exists():
                 return response.json(0, {'data': [], 'count': 0})
@@ -194,6 +195,7 @@ class OrderView(View):
             start = (page - 1) * line
             end = status + line
             count = order_qs.count()
+            order_qs = order_qs.annotate(rank__title=F('rank__lang__title'))
             order_qs = order_qs[start:end].values("orderID", "UID", "channel", "desc", "price",
                                                   "currency", "addTime", "payType", "rank__day", "rank__price",
                                                   "status", 'channel', "rank__title", "currency")
@@ -203,11 +205,12 @@ class OrderView(View):
 
     def do_query_order_detail(self, request_dict, userID, response):
         orderID = request_dict.get('orderID', None)
-
+        lang = request_dict.get('lang', None)
         if orderID:
-            order_qs = Order_Model.objects.filter(orderID=orderID, userID__userID=userID)
+            order_qs = Order_Model.objects.filter(orderID=orderID, userID__userID=userID, rank__lang__lang=lang)
             if order_qs.exists():
                 print(order_qs)
+                order_qs = order_qs.annotate(rank__title=F('rank__lang__title'))
                 order = order_qs.values("orderID", "UID", "channel", "desc", "price",
                                         "currency", "addTime", "endTime", "payType",
                                         "rank__day", "rank__price", "status", 'channel', "rank__title", "currency")[0]
@@ -220,11 +223,11 @@ class OrderView(View):
 
     def do_cancel_order(self, request_dict, userID, response):
         orderID = request_dict.get('orderID', None)
-
+        lang = request_dict.get('lang', None)
         if orderID is None:
             return response.json(444)
 
-        order_qs = Order_Model.objects.filter(orderID=orderID)
+        order_qs = Order_Model.objects.filter(orderID=orderID,rank__lang__lang=lang)
         if not order_qs.exists():
             return response.json(800)
 

+ 2 - 2
Controller/SysManage.py

@@ -104,8 +104,8 @@ def initMsgFunc(request):
     if tko.code == 0:
         userID = tko.userID
         sm_count = SysMsgModel.objects.filter(userID_id=userID, status=0).count()
-        eq_count = Equipment_Info.objects.filter(status=False,userID_id=userID).count()
-        rq_count = Equipment_Info.objects.filter(status=False, eventType=57,userID_id=userID).count()
+        eq_count = Equipment_Info.objects.filter(userID_id=userID).filter(status=False).count()
+        rq_count = Equipment_Info.objects.filter(userID_id=userID).filter(eventType=57, status=False,).count()
         uid_reset_count = Device_Info.objects.filter(userID_id=userID, isExist=2).count()
         res = {
             'sm_count': sm_count,  # 系统消息未读数量

+ 3 - 1
Controller/UidSetController.py

@@ -23,7 +23,8 @@ from django.views.decorators.csrf import csrf_exempt
 from django.views.generic.base import View
 
 from Model.models import UidSetModel, Device_User, Device_Info, UidPushModel, Equipment_Info, UID_Preview, UID_Bucket, \
-    VodHlsModel, Order_Model, OssCrdModel, UidUserModel, UidChannelSetModel, User_Brand, ExperienceContextModel
+    VodHlsModel, Order_Model, OssCrdModel, UidUserModel, UidChannelSetModel, User_Brand, ExperienceContextModel, \
+    StsCrdModel
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Service.CommonService import CommonService
@@ -495,6 +496,7 @@ class UidSetView(View):
                     # 删除和更新设备云存相关数据
                     UID_Bucket.objects.filter(uid=uid).delete()
                     Order_Model.objects.filter(UID=uid).delete()
+                    StsCrdModel.objects.filter(uid=uid).delete()
                     VodHlsModel.objects.filter(uid=uid).delete()
                     ExperienceContextModel.objects.filter(uid=uid).delete()
                     Device_Info.objects.filter(UID=uid).update(vodPrimaryUserID='', vodPrimaryMaster='')

+ 13 - 8
Controller/VodBucket.py

@@ -18,10 +18,12 @@ from django.utils.decorators import method_decorator
 from django.views.decorators.csrf import csrf_exempt
 from django.views.generic.base import View
 
-from Model.models import VodBucketModel, UID_Bucket, Store_Meal, Device_Info, OssCrdModel
+from Model.models import VodBucketModel, UID_Bucket, Store_Meal, Device_Info, OssCrdModel, VodHlsModel, StsCrdModel, \
+    Unused_Uid_Meal
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Service.ModelService import ModelService
+from django.db import transaction
 import time
 
 
@@ -239,13 +241,16 @@ class UidBucketView(View):
             id = request_dict.get('id', None)
             page = int(request_dict.get('page', None))
             line = int(request_dict.get('line', None))
-            d_ubqs = UID_Bucket.objects.filter(id=id)
-            uid = d_ubqs[0].uid
-            channel = d_ubqs[0].channel
-            d_ubqs.delete()
-            oss_crd_qs = OssCrdModel.objects.filter(uid=uid, channel=channel)
-            if oss_crd_qs.exists():
-                oss_crd_qs.delete()
+            uid_bucket_qs = UID_Bucket.objects.filter(id=id)
+            uid = uid_bucket_qs[0].uid
+            bucket_id = uid_bucket_qs[0].bucket_id
+            # channel = uid_bucket_qs[0].channel
+            with transaction.atomic():
+                uid_bucket_qs.delete()
+                # OssCrdModel.objects.filter(uid=uid, channel=channel).delete()
+                VodHlsModel.objects.filter(uid=uid).delete()
+                StsCrdModel.objects.filter(uid=uid).delete()
+                Unused_Uid_Meal.objects.filter(uid=uid).delete()
         except Exception as e:
             return response.json(10, repr(e))
         else:

+ 46 - 6
Model/models.py

@@ -416,17 +416,16 @@ class VodBucketModel(models.Model):
 
 class Store_Meal(models.Model):
     id = models.AutoField(primary_key=True, verbose_name=u'自增ID')
-    title = models.CharField(blank=True, max_length=32, verbose_name=u'标题')
+    # title = models.CharField(blank=True, max_length=32, verbose_name=u'标题')
     currency = models.CharField(blank=True, default='$', max_length=32, verbose_name=u'货币符号')
     symbol = models.CharField(blank=True, default='$', max_length=32, verbose_name=u'符号')
     price = models.CharField(blank=True, max_length=32, verbose_name=u'价格')
     virtual_price = models.CharField(blank=True, max_length=32, verbose_name=u'虚拟价格')
     is_discounts = models.SmallIntegerField(default=0, verbose_name=u'该套餐是否有优惠 [0=否,1是]')   # 0没有;1有
     discount_price = models.CharField(blank=True, max_length=32, verbose_name=u'第二年优惠价格')
-    discount_content = models.CharField(blank=True, max_length=320, verbose_name=u'优惠信息描述')
     day = models.IntegerField(default=0, blank=True, verbose_name=u'云存录像保存天数(循环)')   # 7,30,180,360
     expire = models.IntegerField(default=0, blank=True, verbose_name=u'有效期') #单位月
-    content = models.TextField(blank=True, null=True, verbose_name=u'描述')
+    # content = models.TextField(blank=True, null=True, verbose_name=u'描述')
     add_time = models.DateTimeField(blank=True, null=True, verbose_name=u'加入时间', auto_now_add=True)
     # type = models.SmallIntegerField(default=0, verbose_name='付款类型')  # 0是paypal,1为支付宝
     pay_type = models.ManyToManyField(to='Pay_Type', verbose_name='付款类型', db_table='store_meal_pay')
@@ -435,6 +434,8 @@ class Store_Meal(models.Model):
                                default=1, verbose_name='存储空间')
     commodity_type = models.SmallIntegerField(default=0, verbose_name='云存储套餐类型')  # 0:事件型 1:连续型
     commodity_code = models.CharField(default='', max_length=32, verbose_name='套餐规格码')
+    # lang = models.CharField(default='', max_length=20, verbose_name='语言/国家')
+    lang = models.ManyToManyField(to='Lang', verbose_name='套餐语言', db_table='store_meal_lang')
 
     def __str__(self):
         return self.id
@@ -445,6 +446,7 @@ class Store_Meal(models.Model):
         verbose_name_plural = verbose_name
         ordering = ('id',)
 
+
 class Pay_Type(models.Model):
     id = models.AutoField(primary_key=True, verbose_name=u'自增ID')
     payment = models.CharField(max_length=32, verbose_name=u'支付方式')
@@ -459,6 +461,24 @@ class Pay_Type(models.Model):
         ordering = ('id',)
 
 
+# 套餐语言表
+class Lang(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name='自增ID')
+    lang = models.CharField(default='', max_length=20, verbose_name='语言/国家')
+    title = models.CharField(blank=True, max_length=32, verbose_name='标题')
+    content = models.TextField(blank=True, null=True, verbose_name='描述')
+    discount_content = models.CharField(blank=True, max_length=320, verbose_name=u'优惠信息描述')
+
+    def __str__(self):
+        return self.id
+
+    class Meta:
+        db_table = 'lang'
+        verbose_name = '套餐语言'
+        verbose_name_plural = verbose_name
+        ordering = ('id',)
+
+
 class Equipment_Version(models.Model):
     eid = models.CharField(blank=True, max_length=32, primary_key=True)
     ESN = models.CharField(blank=True, max_length=32, verbose_name=u'设备规格名称')
@@ -638,10 +658,11 @@ class UID_Bucket(models.Model):
     channel = models.SmallIntegerField(default=0, verbose_name='通道')
     bucket = models.ForeignKey(VodBucketModel, blank=True, to_field='id', on_delete=models.CASCADE, verbose_name='存储空间')
     status = models.SmallIntegerField(default=0, verbose_name='状态[0:开启,1:关闭]')
-    endTime = models.BigIntegerField(verbose_name='套餐结束时间', default=0)
+    endTime = models.BigIntegerField(verbose_name='套餐结束时间', db_index=True, default=0)
     addTime = models.IntegerField(verbose_name='添加时间', default=0)
     updateTime = models.BigIntegerField(verbose_name='更新时间', default=0)
-    # is_use = models.IntegerField(verbose_name='是否使用中[0:未使用,1:使用中]', default=0)
+    use_status = models.IntegerField(verbose_name='使用状态[1:使用中,2已过期]', default=0)
+    has_unused = models.SmallIntegerField(default=0, verbose_name='是否拥有其它未使用的套餐[0:否,1:是]')
 
     class Meta:
         db_table = 'vod_uid_bucket'
@@ -649,6 +670,23 @@ class UID_Bucket(models.Model):
         verbose_name_plural = verbose_name
         ordering = ('id',)
 
+class Unused_Uid_Meal(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
+    uid = models.CharField(max_length=20, verbose_name='设备UID')
+    channel = models.SmallIntegerField(default=0, verbose_name='通道')
+    bucket = models.ForeignKey(VodBucketModel, blank=True, to_field='id', on_delete=models.CASCADE, verbose_name='存储空间')
+    addTime = models.IntegerField(verbose_name='添加时间', default=0)
+    expire = models.IntegerField(verbose_name='存储桶存储时长[月份]', default=0)
+    num = models.IntegerField(verbose_name='个数', default=0)
+    # effect_time = models.BigIntegerField(verbose_name='生效时间', db_index=True, default=0)
+    # uid_bucket = models.ForeignKey(UID_Bucket, blank=True, to_field='id', on_delete=models.CASCADE, default=0,
+    #                            verbose_name='uid_bucket关联')
+    class Meta:
+        db_table = 'unused_uid_Meal'
+        verbose_name = '未使用的设备关联套餐表'
+        verbose_name_plural = verbose_name
+        ordering = ('id',)
+
 
 class UID_Preview(models.Model):
     id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
@@ -718,7 +756,9 @@ class UidSetModel(models.Model):
     WIFIName = models.CharField(blank=True, max_length=50, default='', verbose_name=u'无线名称')
     isDetector = models.SmallIntegerField(default=0, verbose_name=u'侦测开关0:关闭,1:开启')
     DetectorRank = models.IntegerField(default=0, verbose_name=u'侦测灵敏度 0:低,1:中,2:高,3:最高')
-
+    is_human = models.IntegerField(default=0, verbose_name='是否支持人形追踪。0:不支持,1:支持')
+    is_custom_voice = models.IntegerField(default=0, verbose_name='是否支持自定义语音。0:不支持,1:支持')
+    double_wifi = models.IntegerField(default=0, verbose_name='是否支持双频wifi。0:不支持,1:支持')
 
     class Meta:
         db_table = 'uid_set'

+ 20 - 0
Object/TokenObject.py

@@ -97,6 +97,26 @@ class TokenObject:
             self.code = 0
             return res
 
+    def encryption(self, data={}):
+        try:
+            access_expire = int(OAUTH_ACCESS_TOKEN_TIME.total_seconds())
+            refresh_expire = int(OAUTH_REFRESH_TOKEN_TIME.total_seconds())
+            now_stamp = int(time.time())
+            access_data = data
+            refresh_data = data
+            access_data['exp'] = access_expire + now_stamp
+            refresh_data['exp'] = refresh_expire + now_stamp
+            access_token = jwt.encode(access_data,
+                                      OAUTH_ACCESS_TOKEN_SECRET,
+                                      algorithm='HS256')
+            return access_token.decode('utf-8')
+        except Exception as e:
+            self.code = 309
+            print(repr(e))
+        else:
+            self.code = 0
+            return res
+
     def refresh(self):
         if not self.token:
             self.code = 309