فهرست منبع

更新云存代码

lang 4 سال پیش
والد
کامیت
73a7003768

+ 3 - 1
Ansjer/urls.py

@@ -178,7 +178,9 @@ urlpatterns = [
     url(r'^oauth/unbunding', UserController.UnbundingWXView.as_view()),
 
     # 删除云存视频
-    path('cv/del', CloudVod.deleteVodHls),
+    path('cv/del', CloudStorage.deleteVodHls),
+    path('cv/updateExpiredUidBucket', CloudStorage.updateExpiredUidBucket),
+    path('cv/updateUnusedUidBucket', CloudStorage.updateUnusedUidBucket),
     url(r'^equipment/judge', EquipmentManager.judgeInterface),
 
     # ap模式,新增设备表

+ 258 - 0
Controller/CDKController.py

@@ -0,0 +1,258 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+"""
+@Copyright (C) ansjer cop Video Technology Co.,Ltd.All rights reserved.
+@AUTHOR: ASJRD018
+@NAME: AnsjerFormal
+@software: PyCharm
+@DATE: 2018/12/5 9:30
+@Version: python3.6
+@MODIFY DECORD:ansjer dev
+@file: cloudstorage.py
+@Contact: chanjunkai@163.com
+"""
+import json
+import time
+import urllib
+import uuid
+import hashlib
+
+import boto3
+import oss2
+import paypalrestsdk
+import threading
+from aliyunsdkcore import client
+from aliyunsdksts.request.v20150401 import AssumeRoleRequest
+from boto3.session import Session
+from django.http import JsonResponse, HttpResponseRedirect, HttpResponse
+from django.views.generic.base import View
+
+from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, OSS_ROLE_ARN, SERVER_DOMAIN, PAYPAL_CRD, \
+    SERVER_DOMAIN_SSL
+from Model.models import Device_Info, Order_Model, Store_Meal, VodHlsModel, OssCrdModel, UID_Bucket, StsCrdModel, \
+    ExperienceContextModel, CDKcontextModel
+from Object.AliPayObject import AliPayObject
+from Object.ResponseObject import ResponseObject
+from Object.TokenObject import TokenObject
+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, F
+from django.http import StreamingHttpResponse
+
+SERVER_DOMAIN = 'http://test.dvema.com/'
+
+
+# 设备信息添加
+class CDKView(View):
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.GET, request, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.POST, request, operation)
+
+    def validation(self, request_dict, request, operation):
+        response = ResponseObject()
+
+        if operation is None:
+            return response.json(444, 'error path')
+        else:
+            token = request_dict.get('token', None)
+            # 设备主键uid
+            tko = TokenObject(token)
+            response.lang = tko.lang
+            if tko.code != 0:
+                return response.json(tko.code)
+            userID = tko.userID
+            if operation == 'createCDK':
+                return self.createCDK(request_dict, response)
+            elif operation == 'deleteCDK':
+                return self.deleteCDK(request_dict, response)
+            elif operation == 'queryCDK':
+                return self.queryCDK(request_dict, response)
+            elif operation == 'saveOrEditCDKform':
+                return self.saveOrEditCDKform(request_dict, response)
+            elif operation == 'saveOrEditCDK':
+                return self.saveOrEditCDK(request_dict, response)
+            elif operation == 'downloadCDK':
+                return self.downloadCDK(request_dict, response)
+
+    def createCDK(self, request_dict, response):
+        cdk_num = request_dict.get("cdknum", None)
+        rank = request_dict.get('rank', None)
+        order = request_dict.get('order', None)
+        cdk_list = []
+        for i in range(int(cdk_num)):
+            nowTime = int(time.time())
+            cdk = hashlib.md5((str(uuid.uuid1()) + str(nowTime)).encode('utf-8')).hexdigest()
+            cdk_model = CDKcontextModel(
+                cdk=cdk,
+                create_time=nowTime,
+                valid_time=0,
+                is_activate=0,
+                rank_id=rank,
+                order=order,
+            )
+            cdk_list.append(cdk_model)
+        try:
+            CDKcontextModel.objects.bulk_create(cdk_list)
+        except Exception as e:
+            print(repr(e))
+            return response.json(404, repr(e))
+        else:
+            return response.json(0)
+
+    def queryCDK(self, request_dict, response):
+        page = int(request_dict.get('page', None))
+        line = int(request_dict.get('line', None))
+        # channel = request_dict.get('channel', None)
+        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()
+        elif order:
+            searchVal = order.strip()
+        elif is_activate:
+            searchVal = is_activate.strip()
+
+        if page and line:
+            cdk_qs = CDKcontextModel.objects.filter().all()  # values('cdk','create_time','valid_time','is_activate','rank__id','order__id')
+            if searchVal:
+                if cdk:
+                    cdk_qs = cdk_qs.filter(cdk__contains=searchVal)
+                elif order:
+                    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创建时间降序排序
+            count = cdk_qs.count()
+            cdk_qs = cdk_qs[(page - 1) * line:page * line]
+
+            # cdk_dict = {}
+            # for cdk in cdk_qs:
+            #     cdk_dict[cdk['id']] = {'id': cdk['id'], 'cdk': cdk['cdk'], 'create_time': cdk['create_time'],
+            #                            'valid_time': cdk['valid_time'], 'is_activate': cdk['is_activate'],
+            #                            'rank': cdk['rank__id'], 'order': cdk['order']}
+
+            res = {
+                'datas': list(cdk_qs),
+                'count': count
+            }
+            return response.json(0, res)
+        else:
+            return response.json(444, 'page,line')
+
+    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:
+            return response.json(500, repr(e))
+        else:
+            page = int(request_dict.get('page', None))
+            line = int(request_dict.get('line', None))
+            # channel = request_dict.get('channel', None)
+            cdk = request_dict.get('cdk', None)
+            order = request_dict.get('order', None)
+            is_activate = request_dict.get('is_activate', None)
+
+            searchVal = ''
+            if cdk:
+                searchVal = cdk.strip()
+            elif order:
+                searchVal = order.strip()
+            elif is_activate:
+                searchVal = is_activate.strip()
+
+            if page and line:
+                cdk_qs = CDKcontextModel.objects.filter().all()  # values('cdk','create_time','valid_time','is_activate','rank__id','order__id')
+                if searchVal:
+                    if cdk:
+                        cdk_qs = cdk_qs.filter(cdk__contains=searchVal)
+                    elif order:
+                        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创建时间降序排序
+                count = cdk_qs.count()
+                cdk_qs = cdk_qs[(page - 1) * line:page * line]
+                res = {
+                    'datas': list(cdk_qs),
+                    'count': count
+                }
+                return response.json(0, res)
+
+
+
+    def saveOrEditCDK(self, request_dict, response):
+        cdk_id = request_dict.get("id", None)
+        cdk = request_dict.get('cdk', None)
+        valid_time = request_dict.get('valid_time', None)
+        is_activate = request_dict.get('is_activate', None)
+        rank = request_dict.get('rank', None)
+
+        try:
+            if cdk_id:
+                if cdk or valid_time or is_activate or rank:
+                    update_dict = {}
+                    if cdk:
+                        update_dict['cdk'] = cdk
+                    if valid_time:
+                        update_dict['valid_time'] = valid_time
+                    if is_activate:
+                        update_dict['is_activate'] = is_activate
+                    if rank:
+                        update_dict['rank'] = rank
+                    CDKcontextModel.objects.filter(id=cdk_id).update(**update_dict)
+        except Exception as e:
+            return response.json(500, repr(e))
+        else:
+            return response.json(0)
+
+    def downloadCDK(self,request_dict, response):
+        region = request_dict.get('region', None)
+        content = ''
+        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)
+
+        response = StreamingHttpResponse(content)
+        response['Content-Type'] = 'application/octet-stream'
+        response['Content-Disposition'] = 'attachment;filename="CDK.txt"'
+        return response
+
+
+
+
+

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 644 - 464
Controller/CloudStorage.py


+ 187 - 0
Controller/CloudTransfer.py

@@ -0,0 +1,187 @@
+# -*- coding: utf-8 -*-
+"""
+@Time : 2020/12/16 8:44
+@Auth : Locky
+@File :CloudTransfer.py
+@IDE :PyCharm
+"""
+import time
+from django.db import transaction
+from django.views.generic.base import View
+
+from Object.TokenObject import TokenObject
+from Service.CommonService import CommonService
+from Service.ModelService import ModelService
+from Object.ResponseObject import ResponseObject
+from Model.models import Device_User, Device_Info, Order_Model, UID_Bucket, StsCrdModel, VodHlsModel, Unused_Uid_Meal, \
+    VodBucketModel
+
+
+class cloudTestView(View):
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.GET, request, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.POST, request, operation)
+
+    def validation(self, request_dict, request, operation):
+        response = ResponseObject()
+        if operation is None:
+            return response.json(444, 'error path')
+        else:
+            token = request_dict.get('token', None)
+            # 设备主键uid
+            tko = TokenObject(token)
+            response.lang = tko.lang
+            if tko.code != 0:
+                return response.json(tko.code)
+            userID = tko.userID
+            if operation == 'deviceTransfer':
+                return self.deviceTransfer(request_dict, response)
+            elif operation == 'mealTransfer':
+                return self.mealTransfer(request_dict, response, userID)
+            elif operation == 'expireMeal':
+                return self.expireMeal(request_dict, response)
+
+    def deviceTransfer(self, request_dict, response):
+        # 设备转移,一个用户下的设备转移到另一个用户
+        oldUserID = request_dict.get("oldUserID", None)
+        username = request_dict.get("username", None)
+        uid = request_dict.get('uid', None)
+        now_time = CommonService.timestamp_to_str(int(time.time()))
+        # print('now_time: ', now_time)
+
+        try:
+            # 查询该userID下是否存在此设备
+            old_deviceInfo_qs = Device_Info.objects.filter(userID_id=oldUserID, UID=uid, isExist=1).values('isShare','vodPrimaryUserID')
+            if not old_deviceInfo_qs.exists():
+                return response.json(10008)
+
+            newUserID = ModelService.get_userID_byname(username)    # 根据username获取userID
+            if newUserID is None:   # 没有此用户
+                return response.json(104)
+            if newUserID == oldUserID:  # 新用户的userID跟旧用户的一样
+                return response.json(10009)
+            # 分享的设备不能转移
+            isShare = old_deviceInfo_qs[0]['isShare']
+            if isShare:
+                return response.json(10015)
+            # 旧用户是设备主用户才能转移
+            vodPrimaryUserID = old_deviceInfo_qs[0]['vodPrimaryUserID']
+            if vodPrimaryUserID != '' and vodPrimaryUserID != oldUserID:
+                return response.json(10037)
+            # 判断新用户是否已有此设备
+            new_deviceInfo_qs = Device_Info.objects.filter(userID_id=newUserID, UID=uid, isExist=1)
+            if new_deviceInfo_qs:
+                return response.json(10009)
+
+            # 获取新设备的username
+            newUserName = Device_User.objects.get(userID=newUserID).username
+            vodPrimaryUserID = newUserID
+            vodPrimaryMaster = newUserName
+
+            with transaction.atomic():
+                # 更新旧设备的userID,设备添加时间
+                old_deviceInfo_qs.update(userID=newUserID, data_joined=now_time)
+                # 更新设备的主用户信息
+                Device_Info.objects.filter(UID=uid).update(vodPrimaryUserID=vodPrimaryUserID, vodPrimaryMaster=vodPrimaryMaster)
+                VodHlsModel.objects.filter(uid=uid).delete()
+        except Exception as e:
+            # print(e)
+            return response.json(500, repr(e))
+        else:
+            return response.json(0)
+
+    def mealTransfer(self, request_dict, response, userID):
+        # 云存套餐转移,同一用户下不同设备间的云存套餐转移
+        old_uid = request_dict.get("old_uid", None)
+        new_uid = request_dict.get("new_uid", None)
+        nowTime = int(time.time())
+
+        try:
+            # 查询两个UID是否在同一账号下
+            old_deviceInfo_qs = Device_Info.objects.filter(userID_id=userID, UID=old_uid).values('isExist','vodPrimaryUserID')
+            new_deviceInfo_qs = Device_Info.objects.filter(userID_id=userID, UID=new_uid).values('isExist')
+            if not (old_deviceInfo_qs.exists() and new_deviceInfo_qs.exists()):
+                return response.json(10010)
+
+            # 不是主用户无法转移
+            vodPrimaryUserID = old_deviceInfo_qs[0]['vodPrimaryUserID']
+            if vodPrimaryUserID != '' and vodPrimaryUserID != userID:
+                return response.json(10038)
+            vodPrimaryUserID = userID
+            vodPrimaryMaster = ModelService.get_user_name(userID)
+
+            new_isExist = new_deviceInfo_qs[0]['isExist']
+            if not new_isExist:
+                return response.json(10011)
+
+            # 查询转出设备正在使用的套餐
+            old_using_uid_bucket = UID_Bucket.objects.filter(uid=old_uid, endTime__gte=nowTime).values('id', 'bucket_id', 'has_unused').order_by('addTime')
+            if not old_using_uid_bucket.exists():
+                return response.json(10013)
+
+            # 免费存储桶不可转移
+            old_vod_bucket_id = old_using_uid_bucket[0]['bucket_id']
+            is_free = VodBucketModel.objects.get(id=old_vod_bucket_id).is_free
+            if is_free == 1:
+                return response.json(10012)
+
+            # 查询转入设备是否存在正在使用的套餐和未使用的套餐
+            new_using_uid_bucket = UID_Bucket.objects.filter(uid=new_uid, endTime__gte=nowTime)
+            new_unused_uid_bucket = Unused_Uid_Meal.objects.filter(uid=new_uid)
+            if new_using_uid_bucket.exists() or new_unused_uid_bucket.exists():
+                return response.json(10014)
+
+            # 如果转出设备有未使用套餐,更改第一个未使用套餐为正在使用
+            if old_using_uid_bucket[0]['has_unused'] == 1:
+                old_unused_uid_bucket = Unused_Uid_Meal.objects.filter(uid=old_uid).values('id', 'channel', 'bucket_id', 'addTime', 'expire', 'num')
+                count = old_unused_uid_bucket.count()
+                unused = old_unused_uid_bucket[0]
+                has_unused = 1 if count>1 else 0    # 如果存在不止一个未使用套餐,has_unused=1
+                endTime = CommonService.calcMonthLater(unused['expire'] * unused['num'])
+                data_dict = {
+                    'uid': old_uid,
+                    'channel': unused['channel'],
+                    'bucket_id': unused['bucket_id'],
+                    'addTime': unused['addTime'],
+                    'endTime': endTime,
+                    'updateTime': nowTime,
+                    'status': 1,
+                    'use_status': 1,
+                    'has_unused': has_unused
+                }
+                UID_Bucket.objects.create(**data_dict)  # 正在使用套餐表添加数据
+                Unused_Uid_Meal.objects.filter(uid=old_uid).first().delete()   # 删除未使用套餐表中的数据
+
+            with transaction.atomic():
+                # 更新转入设备的主用户信息
+                Device_Info.objects.filter(UID=new_uid).update(vodPrimaryUserID=vodPrimaryUserID, vodPrimaryMaster=vodPrimaryMaster)
+                # 更新正在使用套餐的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,has_unused=0)
+                StsCrdModel.objects.filter(uid=old_uid).delete()    # 删除转出设备stscrd表关联数据
+
+        except Exception as e:
+            # print(e)
+            return response.json(500, repr(e))
+        else:
+            return response.json(0)
+
+    def expireMeal(self, request_dict, response):
+        UID_Bucket_id = request_dict.get("UID_Bucket_id", None)
+        # 修改endTime让当前设备套餐过期
+        if UID_Bucket_id:
+            try:
+                UID_Bucket.objects.filter(id=UID_Bucket_id).update(use_status=2)
+            except Exception as e:
+                # print(e)
+                return response.json(500, repr(e))
+            else:
+                return response.json(0)
+        response.json(404)

+ 404 - 699
Controller/CloudVod.py

@@ -15,6 +15,9 @@ import json
 import math
 import time
 import urllib
+
+import boto3
+
 from Object.AliPayObject import AliPayObject
 import oss2
 import paypalrestsdk
@@ -28,7 +31,7 @@ from django.views.generic.base import View
 
 from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, OSS_ROLE_ARN, SERVER_DOMAIN, PAYPAL_CRD, \
     SERVER_DOMAIN_SSL
-from Model.models import Device_Info, Order_Model, Store_Meal, VodHlsModel, OssCrdModel, UID_Bucket
+from Model.models import Device_Info, Order_Model, Store_Meal, VodHlsModel, OssCrdModel, UID_Bucket, StsCrdModel
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Object.UidTokenObject import UidTokenObject
@@ -97,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
@@ -111,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)
@@ -121,142 +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)
-            elif operation == 'createPayOrder':
-                return self.do_create_pay_order(request_dict, userID, response)
+                return self.do_pay_status(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)
-
-            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("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="测试哟",
-                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"
-            )
-        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)
@@ -380,7 +244,7 @@ class CloudVodView(View):
     		color : green
     	}
     	.content_img{
-    		width: 60px; 
+    		width: 60px;
     		height: 60px;
     	}
     	.bottom{
@@ -420,7 +284,7 @@ class CloudVodView(View):
     function payOKButton() {
         // 复杂数据
         console.log('success')
-        window.webkit.messageHandlers.jsCallOC.postMessage({"status": 1});
+        window.location.href="https://test.dvema.com/closePage";
     }
 	</script>
 </body> 
@@ -428,344 +292,237 @@ 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, 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')
-
-    #  生成设备sts上传授权
     def do_getSts(self, request_dict, ip, response):
         uidToken = request_dict.get('uidToken', None)
         utko = UidTokenObject(uidToken)
         if utko.flag is False:
             return response.json(444, 'uidToken')
-        UID = utko.UID
+        uid = utko.UID
         channel = utko.channel
         print(channel)
-        print(UID)
-        ubqs = UID_Bucket.objects.filter(uid=UID, channel=channel, status=1). \
-            values('channel', 'bucket__bucket', 'bucket__endpoint', 'bucket__region', 'endTime')
+        print(uid)
         now_time = int(time.time())
-        if not ubqs.exists():
-            res = {'code': 404, 'msg': '未购买'}
-            return HttpResponse(json.dumps(res, ensure_ascii=False), content_type="application/json,charset=utf-8")
-        elif ubqs[0]['endTime'] < now_time:
-            res = {'code': 404, 'msg': '过期'}
-            return HttpResponse(json.dumps(res, ensure_ascii=False), content_type="application/json,charset=utf-8")
-        oc_qs = OssCrdModel.objects.filter(uid=UID, channel=channel).values("addTime", "data")
-        if oc_qs.exists():
-            endTime = int(oc_qs[0]["addTime"]) + 3500
-            if endTime > now_time:
-                print(endTime)
-                print(now_time)
-                res = json.loads(oc_qs[0]["data"])
+        ubqs = UID_Bucket.objects.filter(uid=uid, channel=channel, endTime__gte=now_time). \
+            values("bucket__mold", "bucket__bucket", "bucket__endpoint", "bucket__region", "endTime")
+        if ubqs.exists():
+            if ubqs[0]["bucket__mold"] == 0:
+                # 阿里云 oss sts
+                oc_qs = OssCrdModel.objects.filter(uid=uid, channel=channel). \
+                    values("addTime", "data")
+                if oc_qs.exists():
+                    endTime = int(oc_qs[0]["addTime"]) + 3500
+                    if endTime > now_time:
+                        print(endTime)
+                        print(now_time)
+                        res = json.loads(oc_qs[0]["data"])
+                        return JsonResponse(status=200, data=res)
+                # 套餐id
+                storage = '{uid}/vod{channel}/'.format(uid=uid, channel=channel)
+                bucket_name = ubqs[0]['bucket__bucket']
+                endpoint = ubqs[0]['bucket__endpoint']
+                access_key_id = OSS_STS_ACCESS_KEY
+                access_key_secret = OSS_STS_ACCESS_SECRET
+                region_id = ubqs[0]['bucket__region']
+                role_arn = OSS_ROLE_ARN
+                clt = client.AcsClient(access_key_id, access_key_secret, region_id)
+                req = AssumeRoleRequest.AssumeRoleRequest()
+                # 设置返回值格式为JSON。
+                req.set_accept_format('json')
+                req.set_RoleArn(role_arn)
+                req.set_RoleSessionName(uid + '_' + channel)
+                req.set_DurationSeconds(3600)
+                Resource_access = "acs:oss:*:*:{bucket_name}/{uid_channel}*". \
+                    format(bucket_name=bucket_name, uid_channel=storage)
+                print(Resource_access)
+                policys = {
+                    "Version": "1",
+                    "Statement": [
+                        {
+                            "Action": ["oss:PutObject", "oss:DeleteObject", ],
+                            "Resource": [Resource_access],
+                            "Effect": "Allow",
+                            "Condition": {
+                                "IpAddress": {"acs:SourceIp": ip}
+                                # "IpAddress": {"acs:SourceIp": "120.237.157.184"}
+                                # "IpAddress": {"acs:SourceIp": "*"}
+                            }
+                        }
+                    ]
+                }
+                req.set_Policy(Policy=json.dumps(policys))
+                body = clt.do_action(req)
+                # 使用RAM账号的AccessKeyId和AccessKeySecret向STS申请临时token。
+                token = json.loads(body.decode('utf-8'))
+                print(token)
+                res = {
+                    'AccessKeyId': token['Credentials']['AccessKeyId'],
+                    'AccessKeySecret': token['Credentials']['AccessKeySecret'],
+                    'SecurityToken': token['Credentials']['SecurityToken'],
+                    'Expiration': token['Credentials']['Expiration'],
+                    'expire': '3600',
+                    'endpoint': endpoint,
+                    'bucket_name': bucket_name,
+                    'arn': token['AssumedRoleUser']['Arn'],
+                    'code': 0,
+                    'storage': storage,
+                    'endTime': ubqs[0]['endTime'],
+                    'ip': ip}
+                if oc_qs.exists():
+                    oc_qs.update(data=json.dumps(res), addTime=now_time)
+                else:
+                    OssCrdModel.objects.create \
+                        (uid=uid, channel=channel, data=json.dumps(res), addTime=now_time)
                 return JsonResponse(status=200, data=res)
-        # 套餐id
-        storage = '{uid}/vod{channel}/'.format(uid=UID, channel=channel)
-        bucket_name = ubqs[0]['bucket__bucket']
-        endpoint = ubqs[0]['bucket__endpoint']
-        access_key_id = OSS_STS_ACCESS_KEY
-        access_key_secret = OSS_STS_ACCESS_SECRET
-        region_id = ubqs[0]['bucket__region']
-        role_arn = OSS_ROLE_ARN
-        clt = client.AcsClient(access_key_id, access_key_secret, region_id)
-        req = AssumeRoleRequest.AssumeRoleRequest()
-        # 设置返回值格式为JSON。
-        req.set_accept_format('json')
-        req.set_RoleArn(role_arn)
-        req.set_RoleSessionName(UID)
-        req.set_DurationSeconds(3600)
-        Resource_access = "acs:oss:*:*:{bucket_name}/{uid_channel}*".format(bucket_name=bucket_name,
-                                                                            uid_channel=storage)
-        print(Resource_access)
-        policys = {
-            "Version": "1",
-            "Statement": [
-                {
-                    "Action": ["oss:PutObject", "oss:DeleteObject", ],
-                    "Resource": [Resource_access],
-                    "Effect": "Allow",
-                    "Condition": {
-                        "IpAddress": {"acs:SourceIp": ip}
-                        # "IpAddress": {"acs:SourceIp": "120.237.157.184"}
-                        # "IpAddress": {"acs:SourceIp": "*"}
-                    }
+            elif ubqs[0]["bucket__mold"] == 1:
+                # 亚马逊 s3 sts
+                sts_qs = StsCrdModel.objects.filter(uid=uid, channel=channel). \
+                    values("addTime", "data")
+                if sts_qs.exists():
+                    endTime = int(sts_qs[0]["addTime"]) + 3500
+                    if endTime > now_time:
+                        print(endTime)
+                        print(now_time)
+                        res = json.loads(sts_qs[0]["data"])
+                        return JsonResponse(status=200, data=res)
+                    # 套餐id
+                storage = '{uid}/vod{channel}/'.format(uid=uid, channel=channel)
+                bucket_name = ubqs[0]['bucket__bucket']
+                endpoint = ubqs[0]['bucket__endpoint']
+                region_id = ubqs[0]['bucket__region']
+
+                ###############
+                REGION_NAME = region_id
+                boto3_sts = boto3.client(
+                    'sts',
+                    aws_access_key_id='AKIA2E67UIMD45Y3HL53',
+                    aws_secret_access_key='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',
+                    region_name=REGION_NAME
+                )
+                Policy = {
+                    "Version": "2012-10-17",
+                    "Statement": [
+                        {
+                            "Effect": "Allow",
+                            "Action": "s3:*",
+                            "Resource": ["arn:aws:s3:::azvod1/{uid_channel}/*".
+                                             format(uid_channel=storage)]
+                        }
+                    ]
                 }
-            ]
-        }
-        req.set_Policy(Policy=json.dumps(policys))
-        body = clt.do_action(req)
-        # 使用RAM账号的AccessKeyId和AccessKeySecret向STS申请临时token。
-        token = json.loads(body.decode('utf-8'))
-        print(token)
-        res = {
-            'AccessKeyId': token['Credentials']['AccessKeyId'],
-            'AccessKeySecret': token['Credentials']['AccessKeySecret'],
-            'SecurityToken': token['Credentials']['SecurityToken'],
-            'Expiration': token['Credentials']['Expiration'],
-            'expire': '3600',
-            'endpoint': endpoint,
-            'bucket_name': bucket_name,
-            'arn': token['AssumedRoleUser']['Arn'],
-            'code': 0,
-            'storage': storage,
-            'endTime': ubqs[0]['endTime'],
-            'ip': ip}
-        if oc_qs.exists():
-            oc_qs.update(data=json.dumps(res), addTime=now_time)
-        else:
-            OssCrdModel.objects.create(uid=UID, channel=channel, data=json.dumps(res), addTime=now_time)
-        return JsonResponse(status=200, data=res)
+                response = boto3_sts.get_federation_token(
+                    Name='{role_name}'.format(role_name=uid + '_' + channel),
+                    Policy=json.dumps(Policy),
+                    DurationSeconds=7200
+                )
+                ###############
+                res = {
+                    'AccessKeyId': response['Credentials']['AccessKeyId'],
+                    'AccessKeySecret': response['Credentials']['SecretAccessKey'],
+                    'SessionToken': response['Credentials']['SessionToken'],
+                    'Expiration': response['Credentials']['Expiration'],
+                    'expire': '3600',
+                    'endpoint': endpoint,
+                    'bucket_name': bucket_name,
+                    'arn': response['FederatedUser']['Arn'],
+                    'code': 0,
+                    'storage': storage,
+                    'endTime': ubqs[0]['endTime'],
+                    'ip': ip,
+                }
+                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")
+
+    #  生成设备sts上传授权
+    # def do_getSts(self, request_dict, ip, response):
+    #     uidToken = request_dict.get('uidToken', None)
+    #     utko = UidTokenObject(uidToken)
+    #     if utko.flag is False:
+    #         return response.json(444, 'uidToken')
+    #     UID = utko.UID
+    #     channel = utko.channel
+    #     print(channel)
+    #     print(UID)
+    #     ubqs = UID_Bucket.objects.filter(uid=UID, channel=channel, status=1). \
+    #         values('channel', 'bucket__bucket', 'bucket__endpoint', 'bucket__region', 'endTime')
+    #     now_time = int(time.time())
+    #     if not ubqs.exists():
+    #         res = {'code': 404, 'msg': '未购买'}
+    #         return HttpResponse(json.dumps(res, ensure_ascii=False), content_type="application/json,charset=utf-8")
+    #     elif ubqs[0]['endTime'] < now_time:
+    #         res = {'code': 404, 'msg': '过期'}
+    #         return HttpResponse(json.dumps(res, ensure_ascii=False), content_type="application/json,charset=utf-8")
+    #     oc_qs = OssCrdModel.objects.filter(uid=UID, channel=channel).values("addTime", "data")
+    #     if oc_qs.exists():
+    #         endTime = int(oc_qs[0]["addTime"]) + 3500
+    #         if endTime > now_time:
+    #             print(endTime)
+    #             print(now_time)
+    #             res = json.loads(oc_qs[0]["data"])
+    #             return JsonResponse(status=200, data=res)
+    #     # 套餐id
+    #     storage = '{uid}/vod{channel}/'.format(uid=UID, channel=channel)
+    #     bucket_name = ubqs[0]['bucket__bucket']
+    #     endpoint = ubqs[0]['bucket__endpoint']
+    #     access_key_id = OSS_STS_ACCESS_KEY
+    #     access_key_secret = OSS_STS_ACCESS_SECRET
+    #     region_id = ubqs[0]['bucket__region']
+    #     role_arn = OSS_ROLE_ARN
+    #     clt = client.AcsClient(access_key_id, access_key_secret, region_id)
+    #     req = AssumeRoleRequest.AssumeRoleRequest()
+    #     # 设置返回值格式为JSON。
+    #     req.set_accept_format('json')
+    #     req.set_RoleArn(role_arn)
+    #     req.set_RoleSessionName(UID)
+    #     req.set_DurationSeconds(3600)
+    #     Resource_access = "acs:oss:*:*:{bucket_name}/{uid_channel}*".format(bucket_name=bucket_name,
+    #                                                                         uid_channel=storage)
+    #     print(Resource_access)
+    #     policys = {
+    #         "Version": "1",
+    #         "Statement": [
+    #             {
+    #                 "Action": ["oss:PutObject", "oss:DeleteObject", ],
+    #                 "Resource": [Resource_access],
+    #                 "Effect": "Allow",
+    #                 "Condition": {
+    #                     "IpAddress": {"acs:SourceIp": ip}
+    #                     # "IpAddress": {"acs:SourceIp": "120.237.157.184"}
+    #                     # "IpAddress": {"acs:SourceIp": "*"}
+    #                 }
+    #             }
+    #         ]
+    #     }
+    #     req.set_Policy(Policy=json.dumps(policys))
+    #     body = clt.do_action(req)
+    #     # 使用RAM账号的AccessKeyId和AccessKeySecret向STS申请临时token。
+    #     token = json.loads(body.decode('utf-8'))
+    #     print(token)
+    #     res = {
+    #         'AccessKeyId': token['Credentials']['AccessKeyId'],
+    #         'AccessKeySecret': token['Credentials']['AccessKeySecret'],
+    #         'SecurityToken': token['Credentials']['SecurityToken'],
+    #         'Expiration': token['Credentials']['Expiration'],
+    #         'expire': '3600',
+    #         'endpoint': endpoint,
+    #         'bucket_name': bucket_name,
+    #         'arn': token['AssumedRoleUser']['Arn'],
+    #         'code': 0,
+    #         'storage': storage,
+    #         'endTime': ubqs[0]['endTime'],
+    #         'ip': ip}
+    #     if oc_qs.exists():
+    #         oc_qs.update(data=json.dumps(res), addTime=now_time)
+    #     else:
+    #         OssCrdModel.objects.create(uid=UID, channel=channel, data=json.dumps(res), addTime=now_time)
+    #     return JsonResponse(status=200, data=res)
 
     def do_paypal_execute(self, request_dict, response):
         paymentId = request_dict.get('paymentId', None)
@@ -777,6 +534,7 @@ class CloudVodView(View):
         paypalrestsdk.configure(PAYPAL_CRD)
         # ID of the payment. This ID is provided when creating payment.
         payment = paypalrestsdk.Payment.find(paymentId)
+        print(payment)
         payres = payment.execute({"payer_id": PayerID})
         print(payres)
         if not payres:
@@ -954,239 +712,186 @@ class CloudVodView(View):
                 {'name': vod['time'], 'sign_url': vod_play_url, 'thumb': thumb, 'sec': vod['sec'], 'id': vod['id']})
         return response.json(0, vod_play_list)
 
-    def do_pay_status(self, request_dict, userID):
+    def do_pay_status(self, request_dict, userID, response):
         orderID = request_dict.get('orderID', None)
-        om_qs = Order_Model.objects.filter(userID_id=userID, orderID=orderID).values('status')
-        response = HttpResponse()
-        success_pay_content = '''
-
-                <!DOCTYPE html>
-                <html>
-                <head>
-                	<!--浏览器不缓存-->
-                	<meta http-equiv="Pragma" content="no-cache">
-                	<meta http-equiv="Cache-Control" content="no-cache">
-                	<meta http-equiv="Expires" content="0">
-                	<!--utf-8-->
-                    <meta http-equiv="content-type" content="text/html;charset=utf-8">
-                    <!-- viewport的<meta>标签,这个标签可以修改在大部分的移动设备上面的显示,为了确保适当的绘制和触屏缩放。-->
-                    <meta name="viewport" content="width=device-width, initial-scale=1.0">
-                    <link rel="shortcut icon" href="https://test.dvema.com/web/images/favicon.ico" type="image/x-icon"  charset="utf-8"/>  
-                    <title>Trading particulars</title>
-                    <style>
-                    	.title_head{
-                    		height: 50px;
-                    		border-radius: 5px;
-                    		background-color: #c3c6c7; 
-                    		text-align: center;
-                    		line-height: 50px;
-                    	}
-                    	.content{
-                    		text-align: center;
-                    		margin-top: 50px;
-                    		font-size: 20px;
-                    		color : green
-                    	}
-                    	.content_img{
-                    		width: 60px; 
-                    		height: 60px;
-                    	}
-                    	.bottom{
-                    		 margin-bottom: 10px; 
-                    		 margin-top: 250px; 
-                    		 color : green
-                    	}
-                    	.bottom_div{
-                    		border: 1px solid green; 
-                    		line-height: 38px; 
-                    		text-align: center; 
-                    		width: 100px; 
-                    		height: 38px;
-                    		border-radius: 5px;
-                    	}
-
-                    	.bottom_div:hover{
-                    		background-color: #dde4e2;
-                    	}
-                    </style>
-                </head>
-                <body>
-                	<div class="title_head">Trading particulars</div>
-                    <div class="content">
-                    	<p >
-                    		<img src="https://test.dvema.com/web/images/timg.jpg" class="content_img">
-                    		<br />
-                    		Successful payment
-                    	</p>
-                    </div>
-                    <center class="bottom">
-                    	<div class="bottom_div" onclick="payOKButton()"> 
-                    	 Finish
-                    	</div>
-                    </center>
-                    <script> 	    // 点击付款成功按钮
-                    function payOKButton() {
-                        // 复杂数据
-                        console.log('success')
-                        window.webkit.messageHandlers.jsCallOC.postMessage({"status": 1});
-                    }
-                	</script>
-                </body> 
-                </html>
-                        '''
-        falil_pay_content = '''
-        <!DOCTYPE html>
-        <html>
-        <head>
-        	<!--浏览器不缓存-->
-        	<meta http-equiv="Pragma" content="no-cache">
-        	<meta http-equiv="Cache-Control" content="no-cache">
-        	<meta http-equiv="Expires" content="0">
-        	<!--utf-8-->
-            <meta http-equiv="content-type" content="text/html;charset=utf-8">
-            <!-- viewport的<meta>标签,这个标签可以修改在大部分的移动设备上面的显示,为了确保适当的绘制和触屏缩放。-->
-            <meta name="viewport" content="width=device-width, initial-scale=1.0">
-            <link rel="shortcut icon" href="https://test.dvema.com/web/images/favicon.ico" type="image/x-icon"  charset="utf-8"/>  
-            <title>Trading particulars</title>
-            <style>
-            	.title_head{
-            		height: 50px;
-            		border-radius: 5px;
-            		background-color: #c3c6c7; 
-            		text-align: center;
-            		line-height: 50px;
-            	}
-            	.content{
-            		text-align: center;
-            		margin-top: 50px;
-            		font-size: 20px;
-            		color : #ec7648
-            	}
-            	.content_img{
-            		width: 60px; 
-            		height: 60px;
-            	}
-            	.bottom{
-            		 margin-bottom: 10px; 
-            		 margin-top: 250px; 
-            		 color : #ec7648
-            	}
-            	.bottom_div{
-            		border: 1px solid #ec7648; 
-            		line-height: 38px; 
-            		text-align: center; 
-            		width: 100px; 
-            		height: 38px;
-            		border-radius: 5px;
-            	}
-
-            	.bottom_div:hover{
-            		background-color: #dde4e2;
-            	}
-            </style>
-        </head>
-        <body>
-        	<div class="title_head">Trading particulars</div>
-            <div class="content">
-            	<p >
-            		<img src="https://test.dvema.com/web/images/failed.jpg" class="content_img">
-            		<br />
-            		Payment failure
-            	</p>
-            </div>
-            <center class="bottom">
-            	<div class="bottom_div" onclick="payOKButton()"> 
-            	 Finish
-            	</div>
-            </center>
-            <script> 	    // 点击付款成功按钮
-            function payOKButton() {
-                // 复杂数据
-                console.log('success')
-                window.webkit.messageHandlers.jsCallOC.postMessage({"status": 0});
-            }
-        	</script>
-        </body> 
-        </html>
-                        '''
+        lang = request_dict.get('lang', 'en')
+        om_qs = Order_Model.objects.filter(orderID=orderID).values('status')
+        # response = HttpResponse()
+        # success_pay_content = '''
+        #                 '''
+        # falil_pay_content = '''
+        #
+        #                 '''
+
+        status = 0
+        url = "{SERVER_DOMAIN}web/paid2/fail.html".format(SERVER_DOMAIN=SERVER_DOMAIN)
+
         if om_qs.exists():
-            if om_qs[0]['status'] == 1:
-                response.content = success_pay_content
-                return response
+            status = om_qs[0]['status']
+            if status == 1:
+
+                url = "{SERVER_DOMAIN}web/paid2/success.html".format(SERVER_DOMAIN=SERVER_DOMAIN)
             else:
-                # response.content = falil_pay_content
-                # return response
-                # exit()
-                # 如果未支付则调用查询订单是否支付成功
-                aliPayObj = AliPayObject()
-                alipay = aliPayObj.conf()
-                # check order status
-                print("now sleep 3s")
-                # time.sleep(3)
-                result = alipay.api_alipay_trade_query(out_trade_no=orderID)
-                if result.get("trade_status", "") == "TRADE_SUCCESS":
-                    print('paid')
-                    print("trade succeed")
-                    order_qs = Order_Model.objects.filter(orderID=orderID, status=0)
-                    if order_qs.exists():
-                        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)
-
-                        smqs = Store_Meal.objects.filter(id=rank_id).values("day", "bucket_id", "bucket__storeDay")
-                        bucketId = smqs[0]['bucket_id']
-                        if not smqs.exists():
-                            response.content = falil_pay_content
-                            return response
-                        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']:
-                                        response.content = falil_pay_content
-                                        return response
-                                    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)
-
-                        response.content = success_pay_content
-                        return response
-                    else:
-                        response.content = falil_pay_content
-                        return response
+
+                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)
+
+    def query_alipay_order(self, request_dict, userID, response):
+        out_trade_no = request_dict.get('out_trade_no', None)
+
+        if out_trade_no is None:
+            return response.json(444)
+
+        try:
+            aliPayObj = AliPayObject()
+            alipay = aliPayObj.conf()
+            result = alipay.api_alipay_trade_query(out_trade_no=out_trade_no)
+            print(result)
+        except Exception as e:
+            print(repr(e))
+            return response.json(10, repr(e))
+        return response.json(0, {'result': result})
+
+    def do_alipay_cancel(self, request_dict, userID, response):
+        out_trade_no = request_dict.get('out_trade_no', None)
+
+        if out_trade_no is None:
+            return response.json(444)
+
+        order_qs = Order_Model.objects.filter(orderID=out_trade_no)
+        if not order_qs.exists():
+            return response.json(800)
+
+        order = order_qs[0]
+
+        # 交易状态:
+        # WAIT_BUYER_PAY(交易创建,等待买家付款)
+        # TRADE_CLOSED(未付款交易超时关闭,或支付完成后全额退款)
+        # TRADE_SUCCESS(交易支付成功)
+        # TRADE_FINISHED(交易结束,不可退款)
+
+        try:
+            aliPayObj = AliPayObject()
+            alipay = aliPayObj.conf()
+            result = alipay.api_alipay_trade_query(out_trade_no=out_trade_no)
+            result = result['result']
+
+            if result['code'] == '100000':
+                trade_status = result['trade_status']
+                if trade_status == 'TRADE_CLOSED' or trade_status == 'WAIT_BUYER_PAY':
+                    order.status = 2
+                    order.updTime = int(time.time())
+                    order.save()
+                    return response.json(0)
                 else:
-                    print("not paid...")
-                    response.content = falil_pay_content
-                    return response
+                    order.status = 1
+                    order.updTime = int(time.time())
+                    order.save()
+                    return response.json(802)
+            else:
+                return response.json(10, result['sub_msg'])
+
+        except Exception as e:
+            print(repr(e))
+            return response.json(10, repr(e))
+
+    def do_alipay_refund(self, request_dict, userID, response):
+        out_trade_no = request_dict.get('out_trade_no', None)
+        refund_amount = request_dict.get('refund_amount', None)
+        reason = request_dict.get('reason', '正常退款')
+
+        if out_trade_no is None:
+            return response.json(444)
+
+        order_qs = Order_Model.objects.filter(orderID=out_trade_no)
+
+        if not order_qs.exists():
+            return response.json(800)
 
+        order = order_qs[0]
+        if refund_amount > order.price:
+            return response.json(801)
+
+        try:
+            # extra = {
+            #     'refund_currency': order[0].currency
+            # }
+            aliPayObj = AliPayObject()
+            alipay = aliPayObj.conf()
+            result = alipay.api_alipay_trade_refund(refund_amount=refund_amount, out_trade_no=out_trade_no)
+            result = result['result']
+            print(result)
+            if result['code'] == '10000':
+                order.status = 3
+                order.updTime = int(time.time())
+                order.save()
+                return response.json(0)
+            else:
+                return response.json(10, result['sub_msg'])
+
+        except Exception as e:
+            print(repr(e))
+            return response.json(10, repr(e))
+
+    def do_paypal_refund(self, request_dict, userID, response):
+        out_trade_no = request_dict.get('out_trade_no', None)
+        refund_amount = request_dict.get('refund_amount', None)
+
+        order_qs = Order_Model.objects.filter(orderID=out_trade_no, userID__userID=userID)
+
+        if not order_qs.exists():
+            return response.json(800)
+
+        order = order_qs[0]
+
+        refund_amount = float(refund_amount)
+        if order.price < refund_amount:
+            return response.json(801)
+
+        paypalrestsdk.configure(PAYPAL_CRD)
+        payment = paypalrestsdk.Payment.find(order.trade_no)
+        transactions = payment['transactions']
+        transaction = transactions[0]
+        related_resources = transaction['related_resources']
+        if len(related_resources) > 0:
+            related_resource = related_resources[0]
+            sale = related_resource['sale']
+            id = sale['id']
+
+            if sale['state'] == 'completed':
+                paypalSale = paypalrestsdk.Sale.find(id)
+                refund = paypalSale.refund({
+                    'amount': {
+                        'total': refund_amount,
+                        'currency': order.currency
+                    }
+                })
+
+                if refund.success():
+                    return response.json(0)
+                else:
+                    return response.json(10, refund.error)
+            elif sale['state'] == 'refunded':
+                return response.json(804)
         else:
-            response.content = falil_pay_content
-            return response
+            return response.json(804)
+
+
 
 
 def deleteVodHls(request):

+ 71 - 7
Controller/EquipmentManager.py

@@ -360,6 +360,9 @@ def addInterface(request):
     View_Password = request_dict.get('View_Password', '')
     Type = request_dict.get('Type', None)
     ChannelIndex = request_dict.get('ChannelIndex', None)
+    version = request_dict.get('version', '')
+    isCheckMainUser = request_dict.get('isCheckMainUser', None)
+    isMainUserExists = False
     if all([UID, NickName, View_Account, Type, ChannelIndex]):
         tko = TokenObject(token)
         response.lang = tko.lang
@@ -384,6 +387,61 @@ def addInterface(request):
                 # # 判断是否有已绑定用户
                 # if is_bind:
                 #     return response.json(15)
+                pk = CommonService.getUserID(getUser=False)
+
+
+
+                userName = Device_User.objects.get(userID=userID).username
+                main_exist = Device_Info.objects.filter(UID=UID)
+                main_exist = main_exist.filter(~Q(vodPrimaryUserID='')).values('vodPrimaryUserID', 'vodPrimaryMaster')
+                vodPrimaryUserID = userID
+                vodPrimaryMaster = userName
+                if main_exist.exists():
+                    vodPrimaryUserID = main_exist[0]['vodPrimaryUserID']
+                    vodPrimaryMaster = main_exist[0]['vodPrimaryMaster']
+
+                is_bind = Device_Info.objects.filter(UID=UID, isShare=False).values('userID__userID', 'vodPrimaryUserID')
+                # 判断是否有已绑定用户
+                isvodPrimaryUserID = ''
+
+                for forbind in is_bind:
+                    if forbind['vodPrimaryUserID'] != '':
+                        isvodPrimaryUserID = forbind['vodPrimaryUserID']
+
+                # 判断是否有已绑定用户
+                if is_bind and isCheckMainUser == '1' and isvodPrimaryUserID != userID and isvodPrimaryUserID != '':
+                    res = {
+                        'id': pk,
+                        'userID': userID,
+                        'NickName': NickName,
+                        'UID': UID,
+                        'View_Account': View_Account,
+                        'View_Password': View_Password,
+                        'ChannelIndex': ChannelIndex,
+                        'Type': Type,
+                        'isShare': False,
+                        'primaryUserID': '',
+                        'primaryMaster': '',
+                        'vodPrimaryUserID': vodPrimaryUserID,
+                        'vodPrimaryMaster': vodPrimaryMaster,
+                        'data_joined': '',
+                        'version': version,
+                        'isVod': 0,
+                        'isExist': 1,
+                        'userID__userEmail': ''
+                    }
+                    res['vod'] = [
+                        {
+                            "status": 1,
+                            "channel": ChannelIndex,
+                            "endTime": '',
+                            "bucket__content": '',
+                            "uid": UID
+                        }
+                    ]
+                    res['isMainUserExists'] = 1
+                    return response.json(0, res)
+
                 try:
                     # 判断是否有用户绑定
                     nowTime = int(time.time())
@@ -396,15 +454,19 @@ def addInterface(request):
                             'ip': CommonService.get_ip_address(request),
                             'channel': ChannelIndex,
                             'nickname': NickName,
+                            'version': version,
                         }
                         UidSetModel.objects.create(**uid_set_create_dict)
                     else:
                         us_qs.update(nickname=NickName)
-                    pk = CommonService.getUserID(getUser=False)
+
                     userDevice = Device_Info(id=pk, userID_id=userID, UID=UID,
                                              NickName=NickName, View_Account=View_Account,
-                                             View_Password=View_Password, Type=Type, ChannelIndex=ChannelIndex)
+                                             View_Password=View_Password, Type=Type, ChannelIndex=ChannelIndex,
+                                             version=version, vodPrimaryUserID=vodPrimaryUserID, vodPrimaryMaster=vodPrimaryMaster)
                     userDevice.save()
+                    Device_Info.objects.filter(UID=UID).update(vodPrimaryUserID=vodPrimaryUserID,
+                                                               vodPrimaryMaster=vodPrimaryMaster)
                     # redisObj = RedisObject(db=8)
                     # redisObj.del_data(key='uid_qs_' + userID)
                 except Exception as e:
@@ -414,14 +476,16 @@ def addInterface(request):
                                                                     'View_Account',
                                                                     'View_Password', 'ChannelIndex', 'Type',
                                                                     'isShare',
-                                                                    'primaryUserID', 'primaryMaster',
+                                                                    'primaryUserID', 'primaryMaster', 'vodPrimaryUserID', 'vodPrimaryMaster', 'userID__userEmail',
                                                                     'data_joined', 'version',
-                                                                    'isVod', 'isExist')
+                                                                    'isVod', 'isExist', 'isCameraOpenCloud', 'endpoint', 'token_iot_number')
                     dvql = CommonService.qs_to_list(dvqs)
                     ubqs = UID_Bucket.objects.filter(uid=UID). \
                         values('bucket__content', 'status', 'channel', 'endTime', 'uid')
                     res = dvql[0]
                     res['vod'] = list(ubqs)
+                    if isMainUserExists:
+                        res['isMainUserExists'] = 1
                     return response.json(0, res)
 
 
@@ -430,7 +494,7 @@ def addInterface(request):
         else:
             return response.json(tko.code)
     else:
-        return response.json(444, {'param': 'UID,NickName,View_Account,View_Password,Type,ChannelIndex'})
+        return response.json(444, {'param': 'UID,NickName,View_Account,View_Password,Type,ChannelIndex,version'})
 
 
 # 添加设备字段
@@ -749,8 +813,8 @@ def queryInterface(request):
         # count = dvqs.count()
         dvql = dvqs[(page - 1) * line:page * line].values('id', 'userID', 'NickName', 'UID', 'View_Account',
                                                           'View_Password', 'ChannelIndex', 'Type', 'isShare',
-                                                          'primaryUserID', 'primaryMaster', 'data_joined', 'version',
-                                                          'isVod', 'isExist', 'NotificationMode')
+                                                          'primaryUserID', 'primaryMaster', 'data_joined', 'version', 'vodPrimaryUserID', 'vodPrimaryMaster', 'userID__userEmail',
+                                                          'isVod', 'isExist', 'NotificationMode', 'isCameraOpenCloud', 'endpoint', 'token_iot_number')
         dvls = CommonService.qs_to_list(dvql)
         uid_list = []
         for dvl in dvls:

+ 11 - 4
Controller/EquipmentManagerV2.py

@@ -146,12 +146,16 @@ class EquipmentManagerV2(View):
             dvql = dvqs[(page - 1) * line:page * line]. \
                 values('id', 'userID', 'NickName', 'UID', 'View_Account',
                        'View_Password', 'ChannelIndex', 'Type', 'isShare',
-                       'primaryUserID', 'primaryMaster', 'data_joined',
+                       'primaryUserID', 'primaryMaster', 'data_joined', 'vodPrimaryUserID', 'vodPrimaryMaster', 'userID__userEmail',
                        'version',
-                       'isVod', 'isExist', 'NotificationMode')
+                       'isVod', 'isExist', 'NotificationMode', 'isOpenCloud', 'endpoint')
             dvls = CommonService.qs_to_list(dvql)
             uid_list = []
             for dvl in dvls:
+                if dvl['primaryUserID'] and dvl['id'] == dvl['primaryUserID']:
+                    dvl['isPrimaryUser'] = 1
+                else:
+                    dvl['isPrimaryUser'] = 0
                 uid_list.append(dvl['UID'])
                 # if dvl['isShare'] is False:
                 #     uid_list.append(dvl['UID'])
@@ -202,7 +206,10 @@ class EquipmentManagerV2(View):
 
     def do_query_reset(self, userID, request_dict, response):
         dvqs = Device_Info.objects.filter(userID_id=userID, isExist=2)
-        dvql = dvqs.values \
-            ('id', 'NickName', 'UID', 'ChannelIndex', 'Type', 'isShare')
+        dvql = dvqs.values('id', 'userID', 'NickName', 'UID', 'View_Account',
+                           'View_Password', 'ChannelIndex', 'Type', 'isShare',
+                           'primaryUserID', 'primaryMaster', 'data_joined', 'vodPrimaryUserID', 'vodPrimaryMaster',
+                           'userID__userEmail',
+                           'version', 'isVod', 'isExist', 'NotificationMode', 'isCameraOpenCloud', 'endpoint', 'token_iot_number')
         res = CommonService.qs_to_list(dvql)
         return response.json(0, res)

+ 97 - 13
Controller/EquipmentManagerV3.py

@@ -42,6 +42,8 @@ class EquipmentManagerV3(View):
                 return self.do_query(userID, request_dict, response)
             elif operation == 'modify':
                 return self.do_modify(userID, request_dict, response, request)
+            elif operation == 'mainUserDevice':
+                return self.do_mainUserDevice( request_dict, response)
             else:
                 return response.json(414)
         else:
@@ -57,7 +59,9 @@ class EquipmentManagerV3(View):
         View_Password = self.decode_pwd(View_Password_Encypt)
         Type = request_dict.get('Type', None)
         ChannelIndex = request_dict.get('ChannelIndex', None)
-
+        version = request_dict.get('version', '')
+        isCheckMainUser = request_dict.get('isCheckMainUser', None)
+        isMainUserExists = False
         if all([UID, NickName, View_Account, Type, ChannelIndex]):
             tko = TokenObject(token)
 
@@ -82,6 +86,62 @@ class EquipmentManagerV3(View):
                     # # 判断是否有已绑定用户
                     # if is_bind:
                     #     return response.json(15)
+
+                    pk = CommonService.getUserID(getUser=False)
+
+
+
+
+                    userName = Device_User.objects.get(userID=userID).username
+                    main_exist = Device_Info.objects.filter(UID=UID)
+                    main_exist = main_exist.filter(~Q(vodPrimaryUserID='')).values('vodPrimaryUserID', 'vodPrimaryMaster')
+                    vodPrimaryUserID = userID
+                    vodPrimaryMaster = userName
+                    if main_exist.exists():
+                        vodPrimaryUserID = main_exist[0]['vodPrimaryUserID']
+                        vodPrimaryMaster = main_exist[0]['vodPrimaryMaster']
+
+                    is_bind = Device_Info.objects.filter(UID=UID, isShare=False).values('userID__userID', 'vodPrimaryUserID')
+                    isvodPrimaryUserID = ''
+
+                    for forbind in is_bind:
+                        if forbind['vodPrimaryUserID'] != '':
+                            isvodPrimaryUserID = forbind['vodPrimaryUserID']
+
+                    # 判断是否有已绑定用户
+                    if is_bind and isCheckMainUser == '1' and isvodPrimaryUserID != userID and isvodPrimaryUserID != '':
+                        res = {
+                            'id': pk,
+                            'userID': userID,
+                            'NickName': NickName,
+                            'UID': UID,
+                            'View_Account': View_Account,
+                            'View_Password': View_Password,
+                            'ChannelIndex': ChannelIndex,
+                            'Type': Type,
+                            'isShare': False,
+                            'primaryUserID': '',
+                            'primaryMaster': '',
+                            'vodPrimaryUserID': vodPrimaryUserID,
+                            'vodPrimaryMaster': vodPrimaryMaster,
+                            'data_joined': '',
+                            'version': version,
+                            'isVod': 0,
+                            'isExist': 1,
+                            'userID__userEmail': ''
+                        }
+                        res['vod'] = [
+                            {
+                                "status": 1,
+                                "channel": ChannelIndex,
+                                "endTime": '',
+                                "bucket__content": '',
+                                "uid": UID
+                            }
+                        ]
+                        res['isMainUserExists'] = 1
+                        return response.json(0, res)
+
                     try:
                         # 判断是否有用户绑定
                         nowTime = int(time.time())
@@ -94,15 +154,19 @@ class EquipmentManagerV3(View):
                                 'ip': CommonService.get_ip_address(request_dict),
                                 'channel': ChannelIndex,
                                 'nickname': NickName,
+                                'version': version,
                             }
                             UidSetModel.objects.create(**uid_set_create_dict)
                         else:
                             us_qs.update(nickname=NickName)
-                        pk = CommonService.getUserID(getUser=False)
                         userDevice = Device_Info(id=pk, userID_id=userID, UID=UID,
                                                  NickName=NickName, View_Account=View_Account,
-                                                 View_Password=View_Password, Type=Type, ChannelIndex=ChannelIndex)
+                                                 View_Password=View_Password, Type=Type, ChannelIndex=ChannelIndex,
+                                                 version=version,
+                                                 vodPrimaryUserID=vodPrimaryUserID, vodPrimaryMaster=vodPrimaryMaster)
                         userDevice.save()
+                        Device_Info.objects.filter(UID=UID).update(vodPrimaryUserID=vodPrimaryUserID,
+                                                                   vodPrimaryMaster=vodPrimaryMaster)
 
                         if not us_qs.exists():
                             us_qs = UidSetModel.objects.filter(uid=UID)
@@ -121,14 +185,17 @@ class EquipmentManagerV3(View):
                                                                         'View_Password', 'ChannelIndex', 'Type',
                                                                         'isShare',
                                                                         'primaryUserID', 'primaryMaster',
+                                                                        'vodPrimaryUserID', 'vodPrimaryMaster',
+                                                                        'userID__userEmail',
                                                                         'data_joined', 'version',
-                                                                        'isVod', 'isExist')
-                        dvql = CommonService.qs_to_list(dvqs)
-                        ubqs = UID_Bucket.objects.filter(uid=UID). \
-                            values('bucket__content', 'status', 'channel', 'endTime', 'uid')
-                        res = dvql[0]
-                        res['vod'] = list(ubqs)
-                        return response.json(0, res)
+                                                                        'isVod', 'isExist', 'isCameraOpenCloud', 'endpoint', 'token_iot_number')
+                    dvql = CommonService.qs_to_list(dvqs)
+                    ubqs = UID_Bucket.objects.filter(uid=UID). \
+                        values('bucket__content', 'status', 'channel', 'endTime', 'uid')
+                    res = dvql[0]
+                    res['vod'] = list(ubqs)
+
+                    return response.json(0, res)
 
                 else:
                     return response.json(444, {'param': 'UID'})
@@ -230,11 +297,17 @@ class EquipmentManagerV3(View):
             dvqs = dvqs.filter(~Q(isExist=2))
             dvql = dvqs.values('id', 'userID', 'NickName', 'UID', 'View_Account',
                                'View_Password', 'ChannelIndex', 'Type', 'isShare',
-                               'primaryUserID', 'primaryMaster', 'data_joined',
-                               'version', 'isVod', 'isExist', 'NotificationMode')
+                               'primaryUserID', 'primaryMaster', 'data_joined', 'vodPrimaryUserID', 'vodPrimaryMaster',
+                               'userID__userEmail',
+                               'version', 'isVod', 'isExist', 'NotificationMode', 'isCameraOpenCloud',
+                               'endpoint', 'token_iot_number')
             dvls = CommonService.qs_to_list(dvql)
             uid_list = []
             for dvl in dvls:
+                if dvl['primaryUserID'] and dvl['id'] == dvl['primaryUserID']:
+                    dvl['isPrimaryUser'] = 1
+                else:
+                    dvl['isPrimaryUser'] = 0
                 uid_list.append(dvl['UID'])
             ubqs = UID_Bucket.objects.filter(uid__in=uid_list). \
                 values('bucket__content', 'status', 'channel', 'endTime', 'uid')
@@ -412,4 +485,15 @@ class EquipmentManagerV3(View):
                 password = password.decode('utf-8')
                 # 去前3位,后3位
                 password = password[3:-3]
-        return password
+        return password
+
+    def do_mainUserDevice(self, request_dict, response):
+        UID = request_dict.get('UID')
+        dvq = Device_Info.objects.filter(UID=UID)
+        dvq = dvq.filter(~Q(vodPrimaryUserID='')).values('vodPrimaryUserID')
+        qs = {}
+        if dvq.exists():
+            qs = Device_User.objects.filter(userID=dvq[0]['vodPrimaryUserID']).values('userID', 'NickName', 'username', 'userEmail', 'phone')
+            qs = CommonService.qs_to_list(qs)
+
+        return response.json(0, qs)

+ 159 - 25
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
+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,19 +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)
-        type = request_dict.get('type', None)
-        if not title or not id or not price or not day or not content:
+        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)
+        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 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:
@@ -89,9 +106,13 @@ 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,
-                                    currency=currency, type=type)
+            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, expire=expire, symbol=symbol)
             store_meal.save()
+            paytype = paytype.split(',')
+            if len(paytype) > 0:
+                Store_Meal.objects.get(id=id).pay_type.set(paytype)
         except Exception:
             errorInfo = traceback.format_exc()
             print(errorInfo)
@@ -102,42 +123,60 @@ 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",
-                                       "type", "bucket_id", "bucket__bucket", "commodity_type", "commodity_code",
-                                       "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():
-            res['count'] = qs.count()
-            res['data'] = CommonService.qs_to_list(qs[(page - 1) * line:page * line])
+            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])
+            # for area, items in groupby(ql, key=itemgetter('bucket__area')):
+            items_list = list(ql)
+            for key, val in enumerate(items_list):
+                pay_types = Pay_Type.objects.filter(store_meal=items_list[key]['id']).values("id", "payment")
+                items_list[key]['pay_type'] = list(pay_types)
+        res['count'] = len(ql)
+        res['data'] = items_list
         return response.json(0, res)
 
     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)
         commodity_code = request_dict.get('commodity_code', 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)
+        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)
@@ -145,18 +184,28 @@ 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.expire = expire
+            store_meal.symbol = symbol
             store_meal.day = day
-            store_meal.type = type
             if bucketID:
                 store_meal.bucket_id = bucketID
             if currency:
                 store_meal.currency = currency
             store_meal.save()
+            type = type.split(',')
+            if len(type) > 0:
+                Store_Meal.objects.get(id=id).pay_type.set(type)
+            else:
+                Store_Meal.objects.get(id=id).pay_type.clear()
+
         except Exception:
             errorInfo = traceback.format_exc()
             print(errorInfo)
@@ -198,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)
+
 
 '''
 用户获取全部套餐信息
@@ -241,12 +375,12 @@ class MealView(View):
             qs = Store_Meal.objects.filter(bucket__mold=1). \
                 values("id", "title", "content", "price", "day", "currency",
                        "bucket__storeDay", "bucket__bucket", "bucket__area",
-                       "type")
+                       "type", "symbol")
         else:
             qs = Store_Meal.objects.all(). \
                 values("id", "title", "content", "price", "day", "currency",
                        "bucket__storeDay", "bucket__bucket", "bucket__area",
-                       "type")
+                       "type", "symbol")
         if qs.exists():
             ql = list(qs)
             from operator import itemgetter
@@ -266,4 +400,4 @@ class MealView(View):
             }
             return response.json(0, result)
         else:
-            return response.json(0)
+            return response.json(0)

+ 159 - 8
Controller/OrderContrller.py

@@ -12,9 +12,15 @@
 @Contact: chanjunkai@163.com
 """
 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
+
+from Ansjer.config_test import PAYPAL_CRD
+from Object.AliPayObject import AliPayObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Model.models import Order_Model, Device_Info
@@ -50,7 +56,7 @@ class OrderView(View):
         token = request_dict.get('token', None)
         # 设备主键uid
         tko = TokenObject(token)
-        response.lang = tko.lang
+        response.lang = request_dict.get('language', 'en')
         if tko.code != 0:
             return response.json(tko.code)
         userID = tko.userID
@@ -62,6 +68,14 @@ class OrderView(View):
             return self.do_admin_query(request_dict, userID, response)
         elif operation == 'detail':
             return self.do_detail(request_dict, userID, response)
+        elif operation == 'queryByStatus':
+            return self.do_query_order_by_status(request_dict, userID, response)
+        elif operation == 'orderDetail':
+            return self.do_query_order_detail(request_dict, userID, response)
+        elif operation == 'cancel':
+            return self.do_cancel_order(request_dict, userID, response)
+        elif operation == 'delete':
+            return self.do_delete_order(request_dict, userID, response)
         else:
             return response.json(444, 'error path')
 
@@ -77,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', 'en')
         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)
@@ -89,9 +104,10 @@ 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", "endTime", "paypal", "rank__day", "payType",
+                                                              "updTime", "paypal", "rank__day", "payType",
                                                               "rank__price", "status",
                                                               "rank__content", "rank__title", "rank__currency",
                                                               "rank_id")
@@ -134,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)
@@ -146,14 +162,149 @@ class OrderView(View):
                 return response.json(0, [])
             count = omqs.count()
             order_ql = omqs[(page - 1) * line:page * line].values("orderID", "UID", "channel", "desc", "price",
-                                                                  "currency", "addTime", "updTime", "endTime", "paypal",
+                                                                  "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})
 
         else:
             return response.json(404)
+
+    def do_query_order_by_status(self, request_dict, userID, response):
+        status = request_dict.get('status', None)
+        page = request_dict.get('page', None)
+        line = request_dict.get('line', None)
+        lang = request_dict.get('lang', 'en')
+        if status and page and line:
+            order_qs = None
+            status = int(status)
+            if status == -1: # 获取所有订单
+                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,rank__lang__lang=lang)
+            elif 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})
+
+            page = int(page)
+            line = int(line)
+            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")
+            return response.json(0, {'data': list(order_qs), 'count': count})
+        else:
+            return response.json(444)
+
+    def do_query_order_detail(self, request_dict, userID, response):
+        orderID = request_dict.get('orderID', None)
+        lang = request_dict.get('lang', 'en')
+        if orderID:
+            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]
+
+                return response.json(0, {'data': order})
+            else:
+                return response.json(173)
+        else:
+            return response.json(444)
+
+    def do_cancel_order(self, request_dict, userID, response):
+        orderID = request_dict.get('orderID', None)
+        lang = request_dict.get('lang', 'en')
+        if orderID is None:
+            return response.json(444)
+
+        order_qs = Order_Model.objects.filter(orderID=orderID,rank__lang__lang=lang)
+        if not order_qs.exists():
+            return response.json(800)
+
+        order = order_qs[0]
+        if order.status != 0:
+            return response.json(802)
+
+        if order.payType == 1: # 支付宝支付的订单
+            return self.do_cancel_alipay_order(order, response)
+        else:
+            return self.do_cancel_paypal_order(order, response)
+
+    def do_delete_order(self, request_dict, userID, response):
+        orderID = request_dict.get('orderID', None)
+
+        if orderID:
+            Order_Model.objects.filter(orderID=orderID, userID__userID=userID).delete()
+            return response.json(0)
+        else:
+            return response.json(444)
+
+    def do_cancel_alipay_order(self, order, response):
+        # 交易状态:
+        # WAIT_BUYER_PAY(交易创建,等待买家付款)
+        # TRADE_CLOSED(未付款交易超时关闭,或支付完成后全额退款)
+        # TRADE_SUCCESS(交易支付成功)
+        # TRADE_FINISHED(交易结束,不可退款)
+
+        try:
+            aliPayObj = AliPayObject()
+            alipay = aliPayObj.conf()
+            result = alipay.api_alipay_trade_query(out_trade_no=order.orderID)
+            print(result)
+
+            if result['code'] == '100000':
+                trade_status = result['trade_status']
+                if trade_status == 'TRADE_CLOSED' or trade_status == 'WAIT_BUYER_PAY':
+                    order.status = 2
+                    order.updTime = int(time.time())
+                    order.save()
+                    return response.json(0)
+                elif trade_status == 'TRADE_SUCCESS':
+                    order.status = 1
+                    order.updTime = int(time.time())
+                    order.save()
+                    return response.json(802)
+            elif result['code'] == '40004':
+                order.status = 2
+                order.updTime = int(time.time())
+                order.save()
+                return response.json(0)
+            else:
+                return response.json(10, result['sub_msg'])
+
+        except Exception as e:
+            print(repr(e))
+            return response.json(10, repr(e))
+
+    def do_cancel_paypal_order(self, order, response):
+        paypalrestsdk.configure(PAYPAL_CRD)
+        payment = paypalrestsdk.Payment.find(order.trade_no)
+        transactions = payment['transactions']
+        transaction = transactions[0]
+        related_resources = transaction['related_resources']
+        if len(related_resources) > 0:
+            related_resource = related_resources[0]
+            sale = related_resource['sale']
+            if sale['state'] == 'completed':
+                order.status = 1
+            elif sale['state'] == 'refunded':
+                order.status = 3
+
+            order.updTime = int(time.time())
+            order.save()
+            return response.json(802)
+
+        order.status = 2
+        order.updTime = int(time.time())
+        order.save()
+        return response.json(0)

+ 503 - 21
Model/models.py

@@ -1,5 +1,4 @@
 from itertools import chain
-from Service.CommonService import CommonService
 from django.contrib.auth.models import BaseUserManager, AbstractBaseUser
 from django.db import models
 from django.utils import six, timezone
@@ -22,7 +21,7 @@ class PermissionsManager(models.Manager):
 
 class RoleManager(models.Manager):
     """
-    The manager for the auth's Role model.
+    The manager for the auth's Role model..
     """
     use_in_migrations = True
 
@@ -120,6 +119,21 @@ class Role(models.Model):
             return permslist
 
 
+class RegionCountryModel(models.Model):
+    number = models.IntegerField(primary_key=True, verbose_name='唯一标识')
+    region_id = models.IntegerField(verbose_name='大洲编号')
+    name = models.CharField(max_length=50, verbose_name=u'名称')
+    cn = models.CharField(blank=True, max_length=64, verbose_name=u'中文名称')
+    en = models.CharField(blank=True, max_length=64, verbose_name=u'英文名称')
+    add_time = models.IntegerField(default=0, verbose_name='添加时间')
+    update_time = models.IntegerField(default=0, verbose_name='更新时间')
+
+    class Meta:
+        db_table = 'region_country'
+        verbose_name = '地区表'
+        verbose_name_plural = verbose_name
+
+
 class Device_User(AbstractBaseUser):
     userID = models.CharField(blank=True, max_length=32, primary_key=True,
                               verbose_name=u'用户ID', unique=True)
@@ -149,8 +163,9 @@ class Device_User(AbstractBaseUser):
     phone = models.CharField(max_length=16, verbose_name=u'手机号', default='', blank=True)
     fingerprint_enable = models.SmallIntegerField(default=0, verbose_name=u'是否开启了指纹登录') # 0:未开启,1:已开启
     fingerprint_key = models.CharField(max_length=128, default='', verbose_name=u'客户端用于解码的密钥等信息')
-    is_local = models.BooleanField(blank=True, default=False, verbose_name=u'是否是本地登录用户')
-    subscribe_email = models.SmallIntegerField(default=0, verbose_name=u'是否订阅营销邮件')  # 0:未订阅,1:订阅,2:不订阅
+    is_local = models.BooleanField(blank=True, default=False, verbose_name=u'是否是本地登录用户') # False:账号登录,1:本地登录
+    subscribe_email = models.SmallIntegerField(default=0, verbose_name=u'是否订阅营销邮件') # 0:未订阅,1:订阅,2:不订阅
+    region_country = models.IntegerField(blank=True, default=0, verbose_name='地区表唯一标识')
     objects = UserManager()
 
     USERNAME_FIELD = 'userID'  # 必须有一个唯一标识
@@ -206,6 +221,7 @@ class Device_User(AbstractBaseUser):
 
 # 设备表是建项目开发者设计的,自己看着办
 # 谢谢提醒!我选择凉拌。
+# 我选择狗带
 class Device_Info(models.Model):
     id = models.CharField(blank=True, max_length=32, primary_key=True)
     userID = models.ForeignKey(Device_User, blank=True, to_field='userID', on_delete=models.CASCADE)
@@ -228,6 +244,8 @@ class Device_Info(models.Model):
                                   help_text=u'是否为共享获取的设备', default=False)
     primaryUserID = models.CharField(blank=True, verbose_name='主用户id', max_length=32, default='')
     primaryMaster = models.CharField(max_length=64, verbose_name=u'主用户名', default='')
+    vodPrimaryUserID = models.CharField(blank=True, verbose_name='云存主用户id', max_length=32, default='')
+    vodPrimaryMaster = models.CharField(max_length=64, verbose_name=u'云存主用户名', default='')
     data_joined = models.DateTimeField(blank=True, verbose_name=u'设备添加时间', auto_now_add=True)
     update_time = models.DateTimeField(blank=True, verbose_name=u'更新时间', auto_now=True, null=True)
 
@@ -238,6 +256,9 @@ class Device_Info(models.Model):
     iSNotification = models.BooleanField(blank=True, verbose_name=u'报警通知 0:关闭,1:开启)', default=False)
     isVod = models.SmallIntegerField(blank=True, default=0, verbose_name='是否支持云存')  # 是否支持云存设备
     isExist = models.SmallIntegerField(blank=True, default=1, verbose_name='是否被删除')  # 是否被删除了(需主用户交互) 1存在,0不存在,2设备被重置
+    isCameraOpenCloud =  models.SmallIntegerField(blank=True, default=1, verbose_name='是否开启云存')  # 0:不开启  1:开启
+    endpoint = models.CharField(blank=True, max_length=256, default='', verbose_name=u'iot端点')
+    token_iot_number = models.CharField(blank=True, default='', max_length=50, verbose_name='连接iot令牌')
     ###
     REQUIRED_FIELDS = []
 
@@ -290,7 +311,7 @@ class Equipment_Info(models.Model):
     alarm = models.CharField(blank=True, max_length=256, verbose_name=u'报警信息')
     eventTime = models.CharField(blank=True, default='', max_length=16, verbose_name=u'设备报警时间')
     receiveTime = models.CharField(blank=True, default='', max_length=16, verbose_name=u'接收到报警时间')
-    userID_id = models.CharField(default='',  db_index=True,blank=True, max_length=32, verbose_name=u'用户ID')
+    userID_id = models.CharField(default='',  db_index=True, blank=True, max_length=32, verbose_name=u'用户ID')
     is_st = models.SmallIntegerField(default=0, verbose_name='是否截图')  # 0 否,1 是图,2,视频
     # message_id = models.CharField(blank=True, max_length=32, default='', verbose_name='第三方推送服务器返回的id')
     # push_type = models.SmallIntegerField(blank=True, default=0, verbose_name='第三方推送服务器标志。0:APNS推送,1:谷歌推送,2:极光推送')
@@ -308,7 +329,6 @@ class Equipment_Info(models.Model):
         ordering = ('-id',)
         app_label = "db2"
 
-
 class StatResModel(models.Model):
     id = models.AutoField(primary_key=True, verbose_name='自动ID')
     name = models.CharField(default='', max_length=120, verbose_name='图片名称', unique=True)
@@ -391,17 +411,19 @@ class User_Brand(models.Model):
 # 存储通表
 class VodBucketModel(models.Model):
     id = models.AutoField(primary_key=True, verbose_name='主键')
-    bucket = models.CharField(max_length=30, verbose_name='设备UID')
+    bucket = models.CharField(max_length=30, verbose_name='存储桶名称')
     storeDay = models.IntegerField(default=0, verbose_name='存储生命周期(天)')
     content = models.TextField(verbose_name='描述', default='')
     endpoint = models.CharField(max_length=125, default='', verbose_name='存储节点')
     area = models.CharField(max_length=16, default='', verbose_name='区域')
     region = models.CharField(max_length=16, default='', verbose_name='regionID')
+    is_free = models.SmallIntegerField(default=0, verbose_name='是否为免费存储桶[0:否,1:是]')
 
     addTime = models.IntegerField(verbose_name='添加时间', default=0)
     updTime = models.IntegerField(verbose_name='更新时间', default=0)
 
     mold = models.SmallIntegerField(default=0, verbose_name='存储区域类型')  # 0:国内阿里 1:国外aws
+    region_id = models.IntegerField(default=1, verbose_name='大洲编号')
 
     def __str__(self):
         return self.id
@@ -415,18 +437,32 @@ 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'标题')
-    currency = models.CharField(blank=True, default='USD', 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'价格')
-    day = models.IntegerField(default=0, blank=True, verbose_name=u'套餐天数')
-    content = models.TextField(blank=True, null=True, 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'第二年优惠价格')
+    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'描述')
     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为支付宝
+    # type = models.SmallIntegerField(default=0, verbose_name='付款类型')  # 0是paypal,1为支付宝
+    pay_type = models.ManyToManyField(to='Pay_Type', verbose_name='付款类型', db_table='store_meal_pay')
     update_time = models.DateTimeField(blank=True, verbose_name=u'更新时间', auto_now=True)
     bucket = models.ForeignKey(VodBucketModel, blank=True, to_field='id', on_delete=models.CASCADE,
                                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')
+
+    # 备用字段
+    spare_1 = models.CharField(default='', blank=True, max_length=64, verbose_name=u'备用字段1')
+    spare_2 = models.CharField(default='', blank=True, max_length=64, verbose_name=u'备用字段2')
+    spare_3 = models.CharField(default='', blank=True, max_length=64, db_index=True, verbose_name=u'备用字段3')
+    spare_4 = models.CharField(default='', blank=True, max_length=64, db_index=True, verbose_name=u'备用字段4')
 
     def __str__(self):
         return self.id
@@ -438,6 +474,38 @@ class Store_Meal(models.Model):
         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'支付方式')
+
+    def __str__(self):
+        return self.id
+
+    class Meta:
+        db_table = 'pay_type'
+        verbose_name = u'付款类型'
+        verbose_name_plural = verbose_name
+        ordering = ('id',)
+
+
+# 套餐语言表
+class Lang(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name='自增ID')
+    lang = models.CharField(default='', max_length=20, db_index=True, verbose_name='语言/国家')
+    title = models.CharField(blank=True, max_length=320, 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'设备规格名称')
@@ -516,17 +584,19 @@ class App_Colophon(models.Model):
 
 class Order_Model(models.Model):
     orderID = models.CharField(blank=True, max_length=20, primary_key=True, verbose_name=u'订单id')
+    trade_no = models.CharField(blank=True, max_length=32, default='', verbose_name='第三方订单号')
     # 订单关联用户
     userID = models.ForeignKey(Device_User, to_field='userID', on_delete=models.CASCADE)
     UID = models.CharField(max_length=20, verbose_name='设备UID')
     channel = models.SmallIntegerField(default=0, verbose_name=u'通道数')
     desc = models.CharField(max_length=50, default='', verbose_name='商品描述')
     price = models.CharField(default='', max_length=16, verbose_name='价格')
-    currency = models.CharField(blank=True, default='USD', max_length=32, verbose_name=u'货币')
+    currency = models.CharField(blank=True, default='$', max_length=32, verbose_name=u'货币')
     addTime = models.IntegerField(verbose_name='添加时间', default=0)
     updTime = models.IntegerField(verbose_name='更新时间', default=0)
-    endTime = models.IntegerField(verbose_name='结束时间', default=0)
-    status = models.SmallIntegerField(default=0, verbose_name='付款状态')  # 0:否,1:成功
+    # endTime = models.IntegerField(verbose_name='结束时间', default=0)
+    isSelectDiscounts = models.SmallIntegerField(default=0, verbose_name=u'用户是否选择了第二年优惠 [0=否,1是]')
+    status = models.SmallIntegerField(default=0, verbose_name='付款状态')  # 0:待支付,1:成功,2:取消,3:已退款, 9:处理中,10:付款失败
     payType = models.SmallIntegerField(default=0, verbose_name='付款类型0:paypal,1:alipay')
     payTime = models.IntegerField(verbose_name='支付成功时间', default=0)
     rank = models.ForeignKey(Store_Meal, to_field='id', default='', on_delete=models.CASCADE, verbose_name='套餐类型')
@@ -534,9 +604,14 @@ class Order_Model(models.Model):
     uid_bucket_id = models.IntegerField(default=0, verbose_name='关联uid_bucket的字段')
     commodity_type = models.SmallIntegerField(default=0, verbose_name='云存储套餐类型')
     commodity_code = models.CharField(default='', max_length=32, verbose_name='套餐规格码')
-    pay_url = models.CharField(max_length=500, default='', verbose_name='支付url')
+    pay_url = models.CharField(max_length=2000, default='', verbose_name='支付url')
     paypal = models.CharField(max_length=500, null=True, blank=True, verbose_name='支付批准url')
 
+    # 备用字段
+    spare_1 = models.CharField(default='', blank=True, max_length=64, verbose_name=u'备用字段1')
+    spare_2 = models.CharField(default='', blank=True, max_length=64, verbose_name=u'备用字段2')
+    spare_3 = models.CharField(default='', blank=True, max_length=64, db_index=True, verbose_name=u'备用字段3')
+    spare_4 = models.CharField(default='', blank=True, max_length=64, db_index=True, verbose_name=u'备用字段4')
 
     def __str__(self):
         return self.orderID
@@ -550,14 +625,14 @@ class Order_Model(models.Model):
 
 class VodHlsModel(models.Model):
     id = models.AutoField(primary_key=True, verbose_name='回放列表主键')
-    uid = models.CharField(max_length=20, verbose_name='设备UID')
+    uid = models.CharField(max_length=20, verbose_name='设备UID', db_index=True)
     channel = models.SmallIntegerField(default=0, verbose_name='通道')
     time = models.IntegerField(verbose_name='播放列表名字时间戳', default=0, db_index=True)
-    endTime = models.IntegerField(verbose_name='删除时间', default=0)
+    endTime = models.IntegerField(verbose_name='云存储删除时间(周期)', default=0)
     sec = models.IntegerField(verbose_name='秒数', default=0)
     bucket = models.ForeignKey(VodBucketModel, blank=True, to_field='id', on_delete=models.CASCADE, default=1,
                                verbose_name='存储空间')
-    fg = models.SmallIntegerField(default=0,verbose_name='时间片段数') # 0为阿里云存储方案 >0为亚马逊方案
+    fg = models.CharField(max_length=20,verbose_name='ts个数,时间描述片段数') # 阿里为时间片段数,亚马逊为一个32bit整型,前28bit代表ts文件的时长
 
 
     def __str__(self):
@@ -615,7 +690,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.IntegerField(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)
+    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'
@@ -623,6 +702,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')
@@ -671,7 +767,7 @@ class UidSetModel(models.Model):
     version = models.CharField(max_length=32, verbose_name='设备版本', default='')
     p2p_region = models.CharField(max_length=16, verbose_name='设备p2p区域', default='ALL')  # ALL CN EU US
     cloud_vod = models.SmallIntegerField(default=2, verbose_name='云存开关')  # 0,关闭,1开启,2,不支持
-    tz = models.CharField(default='', max_length=16, verbose_name='设备时区')  # +8
+    tz = models.CharField(default='', max_length=16, verbose_name ='设备时区')  # +8
     video_code = models.SmallIntegerField(default=0, verbose_name='编码类型')  # 0:264,1:265
     nickname = models.CharField(default='', max_length=64, verbose_name='设备昵称')
     ip = models.CharField(max_length=20, default='', verbose_name=u'设备ip')
@@ -1013,6 +1109,22 @@ class AppLogModel(models.Model):
         verbose_name_plural = verbose_name
 
 
+class EquipmentInfoExStatisticsModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    push_type = models.SmallIntegerField(default=0, verbose_name='第三方推送服务器标志。0:APNS推送,1:谷歌推送,2:极光推送')
+    number_of_successes = models.IntegerField(default=0, verbose_name='推送成功数量')
+    number_of_failures = models.IntegerField(default=0, verbose_name='推送失败数量')
+    number_of_arrival = models.IntegerField(default=0, verbose_name='推送到达数量')
+    statistics_date = models.IntegerField(default=0, verbose_name='属于哪天、哪月的统计')
+    date_type = models.SmallIntegerField(default=0, verbose_name='统计日期的类型。0:天,1:月')
+    add_time = models.IntegerField(default=0, verbose_name='添加时间')
+
+    class Meta:
+        db_table = 'equipment_info_ex_statistics'
+        verbose_name = '推送消息统计表'
+        verbose_name_plural = verbose_name
+
+
 class CountryIPModel(models.Model):
     id = models.AutoField(primary_key=True)
     ip = models.CharField(default='', max_length=32, verbose_name='ip')
@@ -1027,6 +1139,33 @@ class CountryIPModel(models.Model):
         verbose_name_plural = verbose_name
 
 
+class ZositechHelpModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    locale = models.CharField(default='', db_index=True, max_length=50, verbose_name='语言')
+    label_names =  models.CharField(default='', db_index=True, max_length=50, verbose_name='标签')
+    origin  =  models.CharField(default='', db_index=True ,max_length=50, verbose_name='来源')
+    # author_id = models.CharField(default='', max_length=50, verbose_name='管理员id')
+    # body = models.TextField(default='', blank=True, verbose_name='内容')
+    # comments_disabled = models.CharField(default='', max_length=10, verbose_name='comments')
+    # created_at = models.CharField(default='', max_length=50, verbose_name='创建时间')
+    # draft = models.CharField(default='', max_length=10, verbose_name='草稿')
+    # edited_at = models.CharField(default='',max_length=50, verbose_name='修改时间')
+    # html_url = models.CharField(default='', blank=True, verbose_name='跳转路径')
+    # body = models.CharField(default='', blank=True, verbose_name='标签')
+    # body = models.CharField(default='', blank=True, verbose_name='标签')
+    # body = models.TextField(default='', blank=True, verbose_name='标签')
+    # body = models.TextField(default='', blank=True, verbose_name='标签')
+    # body = models.CharField(default='', blank=True, verbose_name='标签')
+    # body = models.CharField(default='', blank=True, verbose_name='标签')
+
+    content = models.TextField(blank=True, default='', verbose_name=u'内容')
+
+    class Meta:
+        db_table = 'zositech_help'
+        verbose_name = '周视使用帮助表'
+        verbose_name_plural = verbose_name
+
+
 class EquipmentVersionLimitModel(models.Model):
     id = models.AutoField(primary_key=True)
     type = models.SmallIntegerField(default=0, verbose_name='限制类型')
@@ -1042,6 +1181,40 @@ class EquipmentVersionLimitModel(models.Model):
         verbose_name_plural = verbose_name
 
 
+class ExperienceContextModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    experience_type = models.SmallIntegerField(default=0,verbose_name='体验类型') # 0: 免费体验套餐, 1: 激活码
+    uid = models.CharField(max_length=20, default='', verbose_name='设备uid')
+    do_time = models.IntegerField(default=0, verbose_name='激活时间')
+    # is_experience = models.SmallIntegerField(default=0, verbose_name=u'是否云存体验用户')  # 0:不是体验用户,1:是体验用户
+
+    class Meta:
+        db_table = 'experience_context'
+        verbose_name = '设备体验表'
+        verbose_name_plural = verbose_name
+
+class CDKcontextModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    cdk = models.CharField(max_length=50,unique=True,verbose_name='激活码')
+    create_time = models.IntegerField(default=0, verbose_name='创建时间')
+    valid_time = models.IntegerField(default=0, verbose_name='有效期间')  #超过有效期激活码不可在激活 ,0:永久
+    is_activate = models.SmallIntegerField(default=0, verbose_name='是否已激活') #0 未激活  1 已激活
+    rank = models.ForeignKey(Store_Meal, to_field='id', default='', on_delete=models.CASCADE, verbose_name='套餐类型')
+    # order = models.ForeignKey(Order_Model, blank=True, max_length=20, to_field='orderID', on_delete=models.CASCADE, verbose_name='订单id', unique=True)
+    order = models.CharField(max_length=20, blank=True, unique=True, verbose_name='订单id')
+
+    # 备用字段
+    spare_1 = models.CharField(default='', blank=True, max_length=64, verbose_name=u'备用字段1')
+    spare_2 = models.CharField(default='', blank=True, max_length=64, verbose_name=u'备用字段2')
+    spare_3 = models.CharField(default='', blank=True, max_length=64, db_index=True, verbose_name=u'备用字段3')
+    spare_4 = models.CharField(default='', blank=True, max_length=64, db_index=True, verbose_name=u'备用字段4')
+
+    class Meta:
+        db_table = 'cdk_context'
+        verbose_name = '激活码表'
+        verbose_name_plural = verbose_name
+
+
 class VoicePromptModel(models.Model):
     id = models.AutoField(primary_key=True)
     title = models.CharField(max_length=128, default='', verbose_name='语音标题')
@@ -1073,4 +1246,313 @@ class DeviceTypeModel(models.Model):
     class Meta:
         db_table = 'device_type'
         verbose_name = '设备类型表'
+        verbose_name_plural = verbose_name
+
+
+class OperatingLogsModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    userId = models.CharField(blank=False, max_length=32, db_index=True, verbose_name=u'操作人')
+    operatingtime = models.DateTimeField(blank=True, verbose_name=u'操作时间', auto_now=True)
+    operatingcontent = models.TextField(blank=True, default='', verbose_name=u'操作内容')
+    operatingtype = models.CharField(blank=True, verbose_name=u'操作类型', max_length=32)
+    is_saveprocessinfo = models.SmallIntegerField(default=1, verbose_name=u'是否保存过程信息。1:保存,2:不保存')
+    devUid = models.CharField(default='', blank=True, max_length=32, verbose_name=u'设备ID')
+    userIp = models.CharField(blank=True, max_length=20, default='', verbose_name=u'用户ip')
+
+    class Meta:
+        db_table = 'operating_logs'
+        verbose_name = '操作数据表'
+        verbose_name_plural = verbose_name
+
+
+class ProcessInfoLogsModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    userId = models.CharField(blank=False, max_length=32, db_index=True, verbose_name=u'操作人')
+    devUid = models.CharField(default='', blank=True, max_length=32, verbose_name=u'设备ID')
+    operatingcontent = models.TextField(blank=True, default='', verbose_name=u'操作内容')
+    operatingtime = models.DateTimeField(blank=True, verbose_name=u'操作时间', auto_now=True)
+
+    class Meta:
+        db_table = 'processinfo_logs'
+        verbose_name = '过程信息表'
+        verbose_name_plural = verbose_name
+
+class EquipmentLogModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    user = models.CharField(blank=False, max_length=32, db_index=True, verbose_name=u'操作用户')
+    uid = models.CharField(default='', blank=True, max_length=32, verbose_name=u'设备uid')
+    equipmentid = models.CharField(blank=False, max_length=100, db_index=True, verbose_name=u'设备主键id')
+    NickName = models.CharField(blank=True, max_length=32, verbose_name=u'设备名称')
+    ip = models.CharField(max_length=100, default='', db_index=True, blank=True, verbose_name=u'访问ip地址')
+    time = models.DateTimeField(null=True, blank=True, db_index=True, verbose_name=u'访问时间')
+    operatingcontent = models.TextField(blank=True, default='', verbose_name=u'操作内容')
+    url = models.CharField(max_length=150, default='', blank=True, verbose_name=u'访问路径')
+    class Meta:
+        db_table = 'equipment_log'
+        verbose_name = '设备日志表'
+        verbose_name_plural = verbose_name
+
+
+class UserModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    username = models.CharField(unique=True, max_length=128, null=False, verbose_name='用户名')
+    password = models.CharField(max_length=128, null=False, verbose_name='密码')
+    permission = models.CharField(max_length=24, null=False, verbose_name='权限')
+    login_time = models.IntegerField(blank=True, default=0, verbose_name='登录时间')
+    online = models.SmallIntegerField(default=0, verbose_name='是否在线')
+    phone = models.CharField(max_length=11, default='', verbose_name='手机号')
+    add_time = models.IntegerField(default=0, verbose_name='添加时间')
+
+    class Meta:
+        verbose_name = '用户表'
+        verbose_name_plural = verbose_name
+        db_table = 'user'
+
+
+class CompanyModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    name = models.CharField(max_length=64, unique=True, default='', verbose_name='企业名称')
+    mark = models.CharField(max_length=3, unique=True, default='', verbose_name='企业标志,用于序列号的后三位')
+    secret = models.CharField(max_length=10, db_index=True, default='', verbose_name='企业秘钥')
+    quantity = models.IntegerField(default=0, verbose_name='已购买的序列号的数量')
+    add_time = models.IntegerField(default=0, verbose_name='添加时间')
+    update_time = models.IntegerField(default=0, verbose_name='更新时间')
+
+    class Meta:
+        db_table = 'tb_company'
+        verbose_name = '企业表'
+        verbose_name_plural = verbose_name
+
+
+class RegionModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    name = models.CharField(max_length=32, default='', verbose_name='区域名称')
+
+    class Meta:
+        db_table = 'tb_region'
+        verbose_name = '区域表'
+        verbose_name_plural = verbose_name
+
+
+class VPGModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    name = models.CharField(max_length=32, default='', verbose_name='群组名称')
+    region = models.ForeignKey(RegionModel, to_field='id', on_delete=models.DO_NOTHING, verbose_name='群组用于的地区')
+    company = models.ForeignKey(CompanyModel, to_field='id', on_delete=models.DO_NOTHING, verbose_name='关联企业表')
+    add_time = models.IntegerField(default=0, verbose_name='添加时间')
+    update_time = models.IntegerField(default=0, verbose_name='更新时间')
+
+    class Meta:
+        db_table = 'tb_vpg'
+        verbose_name = 'vpg表'
+        verbose_name_plural = verbose_name
+
+
+class UIDModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    uid = models.CharField(max_length=20, null=False, db_index=True, unique=True, verbose_name='设备id')
+    mac = models.CharField(max_length=17, null=False, default='', verbose_name='设备id对应的mac地址')
+    uid_extra = models.TextField(default='', verbose_name='uid的额外描述')
+    status = models.SmallIntegerField(default=0, verbose_name='使用状态')
+    add_time = models.IntegerField(default=0, verbose_name='添加时间')
+    update_time = models.IntegerField(default=0, verbose_name='更新时间')
+    area = models.SmallIntegerField(default=0, verbose_name='区域')  #0:国内;1:国外
+    vpg = models.ForeignKey(VPGModel, to_field='id', default=1, on_delete=models.DO_NOTHING, verbose_name='关联VPG表的id')
+
+    class Meta:
+        ordering = ('-add_time',)
+        verbose_name = 'uid表'
+        verbose_name_plural = verbose_name
+        db_table = 'uid'
+
+
+class UserUIDModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    user = models.ForeignKey(UserModel, to_field='id', on_delete=models.CASCADE, verbose_name='关联用户表id')
+    uid = models.ForeignKey(UIDModel, to_field='id', on_delete=models.CASCADE, verbose_name='关联uid表id')
+    add_time = models.IntegerField(default=0, verbose_name='添加时间')
+    update_time = models.IntegerField(default=0, verbose_name='更新时间')
+
+    class Meta:
+        verbose_name = '用户与UID的关联表'
+        verbose_name_plural = verbose_name
+        db_table = 'user_uid'
+
+
+class PermissionModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    type = models.SmallIntegerField(null=False, verbose_name='权限枚举')
+    description = models.TextField(default='', verbose_name='权限描述')
+
+    class Meta:
+        verbose_name = '权限表'
+        verbose_name_plural = verbose_name
+        db_table = 'permission'
+
+
+class LogModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    operation = models.CharField(max_length=100, default='', verbose_name='操作描述')
+    time = models.IntegerField(default=0, verbose_name='操作时间')
+    ip = models.CharField(default='', max_length=24, verbose_name='用户ip')
+    user = models.ForeignKey(UserModel, to_field='id', on_delete=models.CASCADE, verbose_name='关联用户id')
+    content = models.TextField(default='', verbose_name='请求参数')
+    status = models.IntegerField(default=0, verbose_name='请求状态')
+    url = models.CharField(max_length=150, default='', verbose_name='请求路径')
+
+    class Meta:
+        ordering = ('-time',)
+        verbose_name = '日志表'
+        verbose_name_plural = verbose_name
+        db_table = 'log'
+
+
+class HistoryUIDModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    uid = models.CharField(max_length=20, null=False, db_index=True, verbose_name='设备id')
+    uid_extra = models.TextField(default='', verbose_name='uid的额外描述')
+    status = models.SmallIntegerField(default=0, verbose_name='使用状态')
+    add_time = models.IntegerField(default=0, verbose_name='添加时间')
+    update_time = models.IntegerField(default=0, verbose_name='更新时间')
+    area = models.SmallIntegerField(default=0, verbose_name='区域')  # 0:国内;1:国外
+
+    class Meta:
+        verbose_name = '历史UID表'
+        verbose_name_plural = verbose_name
+        db_table = 'history_uid'
+
+
+class MacModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    value = models.CharField(max_length=17, null=False, verbose_name='最新的mac地址')
+    is_active = models.BooleanField(default=True, verbose_name='当前mac地址是否可用')
+    add_time = models.IntegerField(default=0, verbose_name='添加时间')
+    update_time = models.IntegerField(default=0, verbose_name='更新时间')
+
+    class Meta:
+        verbose_name = '最新的mac地址表'
+        verbose_name_plural = verbose_name
+        db_table = 'tb_mac'
+
+
+class OrderTaskModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    order_number = models.CharField(max_length=32, verbose_name='订单号')
+    board = models.CharField(max_length=32, verbose_name='主板')
+    plan = models.CharField(max_length=32, verbose_name='配置方案')
+    checksum = models.CharField(max_length=32, verbose_name='校验和')
+    ic_model = models.CharField(max_length=32, verbose_name='ic型号')
+    quantity = models.IntegerField(default=0, verbose_name='通知单上的生成数量')
+    add_time = models.IntegerField(default=0, verbose_name='添加时间')
+
+    class Meta:
+        db_table = 'order_task'
+        verbose_name = '订单任务表'
+        verbose_name_plural = verbose_name
+
+
+class OrderUIDModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    uid = models.ForeignKey(UIDModel, to_field='id', on_delete=models.CASCADE, verbose_name='关联uid表')
+    order = models.ForeignKey(OrderTaskModel, to_field='id', on_delete=models.CASCADE, verbose_name='关联订单任务表')
+    add_time = models.IntegerField(default=0, verbose_name='添加时间')
+    update_time = models.IntegerField(default=0, verbose_name='更新时间')
+
+    class Meta:
+        db_table = 'order_uid'
+        verbose_name = '订单与uid关联表'
+        verbose_name_plural = verbose_name
+
+
+class CountryModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    number = models.IntegerField(unique=True, verbose_name='区号')
+    add_time = models.IntegerField(default=0, verbose_name='添加时间')
+    update_time = models.IntegerField(default=0, verbose_name='更新时间')
+    region = models.ForeignKey(RegionModel, to_field='id', on_delete=models.DO_NOTHING, verbose_name='关联区域表')
+
+    class Meta:
+        db_table = 'tb_country'
+        verbose_name = '地区表'
+        verbose_name_plural = verbose_name
+
+
+class LanguageModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    lang = models.CharField(max_length=16, default='', verbose_name='语种')
+    lang_youdao = models.CharField(max_length=16, default='', verbose_name='有道的语种')
+    add_time = models.IntegerField(default=0, verbose_name='添加时间')
+    update_time = models.IntegerField(default=0, verbose_name='更新时间')
+
+    class Meta:
+        db_table = 'tb_language'
+        verbose_name = '语言表'
+        verbose_name_plural = verbose_name
+
+
+class CountryLanguageModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    country_name = models.CharField(max_length=64, default='', verbose_name='国家名称')
+    language = models.ForeignKey(LanguageModel, to_field='id', on_delete=models.CASCADE, verbose_name='关联语言表的id')
+    country = models.ForeignKey(CountryModel, to_field='id', on_delete=models.CASCADE, verbose_name='关联地区表的id')
+    add_time = models.IntegerField(default=0, verbose_name='添加时间')
+    update_time = models.IntegerField(default=0, verbose_name='更新时间')
+
+    class Meta:
+        db_table = 'tb_country_language'
+        verbose_name = '不同语言的地区名称表'
+        verbose_name_plural = verbose_name
+
+
+class SerialNumberModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    serial_number = models.CharField(max_length=9, db_index=True, verbose_name='序列号')
+    status = models.SmallIntegerField(default=1, verbose_name='可用状态。0:不可用,1:可用')
+    add_time = models.IntegerField(default=0, verbose_name='添加时间')
+
+    class Meta:
+        db_table = 'tb_serial_number'
+        verbose_name = '序列号表'
+        verbose_name_plural = verbose_name
+
+
+class CompanySerialModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    company = models.ForeignKey(CompanyModel, to_field='id', on_delete=models.CASCADE, verbose_name='关联企业表的id')
+    serial_number = models.ForeignKey(SerialNumberModel, to_field='id', on_delete=models.CASCADE, verbose_name='关联序列号表的id')
+    status = models.SmallIntegerField(default=0, verbose_name='序列号的状态。0:未使用,1:已使用,2:已和UID关联')
+    add_time = models.IntegerField(default=0, verbose_name='添加时间')
+    update_time = models.IntegerField(default=0, verbose_name='更新时间')
+
+    class Meta:
+        db_table = 'tb_company_serial'
+        verbose_name = '企业关联序列号表'
+        verbose_name_plural = verbose_name
+
+
+class UIDCompanySerialModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    uid = models.ForeignKey(UIDModel, to_field='id', on_delete=models.CASCADE, verbose_name='关联UID表')
+    company_serial = models.ForeignKey(CompanySerialModel, to_field='id', on_delete=models.CASCADE, verbose_name='关联【企业关联序列号表】的id')
+    add_time = models.IntegerField(default=0, verbose_name='添加时间')
+    update_time = models.IntegerField(default=0, verbose_name='更新时间')
+
+    class Meta:
+        db_table = 'tb_uid_company_serial'
+        verbose_name = 'UID关联【企业关联序列号】表'
+        verbose_name_plural = verbose_name
+
+
+class iotdeviceInfoModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    uid = models.CharField(blank=True, max_length=32, default='', verbose_name=u'设备uid')
+    certificateId = models.CharField(blank=True, max_length=256, default='', verbose_name=u'证书id')
+    certificatePem = models.TextField(blank=True, default='', verbose_name=u'证书项目')
+    publicKey = models.TextField(blank=True, default='', verbose_name=u'公有密钥')
+    privateKey = models.TextField(blank=True, default='', verbose_name=u'私有密钥')
+    Thingname = models.CharField(blank=True, max_length=256, default='', verbose_name=u'IoT Thing Name')
+
+    class Meta:
+        db_table = 'iot_deviceInfo'
+        verbose_name = 'iot设备信息表'
         verbose_name_plural = verbose_name

+ 54 - 0
Object/ResponseObject.py

@@ -41,6 +41,7 @@ class ResponseObject(object):
             177: 'Update error',
             178: 'ADD error',
             179: 'Nickname repeated',
+            201: 'You can only add 3 custom voice at most',
             306: 'The link has expired!',
             309: 'Please ReLogin! errmsg token',
             404: 'You don not have permission to access this!',
@@ -56,6 +57,10 @@ class ResponseObject(object):
             712: 'Area needs to be consistent',
             713: 'Storage rules cannot be changed during the validity period',
             717: 'Authorization expires',
+            800: 'Order does not exist',
+            801: 'The refund amount cannot be greater than the order price',
+            802: 'The order has been completed and cannot be cancelled',
+            804: 'Refund, please do not repeat the operation',
             900: 'There is no information about this version!',
             901: 'Getting URL failure!',
             902: 'No update!',
@@ -69,6 +74,28 @@ class ResponseObject(object):
             10004: 'The request method is incorrect. Please contact the developer',
             10005: 'Wrong configuration, wrong customer number',
             10006: 'Configuration error. The path value is incorrect',
+            10007: 'This device is not an experience package and cannot be reset',
+            10008: 'The user does not have this device and cannot transfer',
+            10009: 'The user already owns the device and cannot transfer it',
+            10010: 'Devices that are not under the same account cannot be transferred',
+            10011: 'Receiving transfer device does not exist and cannot be transferred',
+            10012: 'Experience packages cannot be transferred',
+            10013: 'Original equipment package has expired and cannot be transferred',
+            10014: 'Accept transfer of equipment packages that have not expired and cannot be transferred',
+            10015: 'Shared devices cannot be transferred',
+            10030: 'No purchase of cloud storage',
+            10031: 'The cloud storage has expired',
+            10032: 'The switched cloud storage package ID cannot be the same as the one in use',
+            10033: 'The primary user of the device cannot purchase it',
+            10034: 'Non device primary users cannot view cloud storage',
+            10035: 'Non device primary users cannot experience cloud storage',
+            10036: 'Non device primary users cannot exchange for cloud storage',
+            10037: 'Non device primary user cannot transfer device',
+            10038: 'Non device primary user cannot transfer packages',
+            10039: 'Activation code has been used',
+            10040: 'Invalid activation code',
+            10041: 'This device has purchased a domestic cloud storage package, and cannot purchase a foreign cloud storage package',
+            10042: 'The device has registered a certificate'
         }
         data_cn = {
             0: '成功',
@@ -104,6 +131,7 @@ class ResponseObject(object):
             177: '更新错误',
             178: '增加错误',
             179: '名称不能重复',
+            201: '最多只能添加3条自定义语音',
             306: '链接已超过有效期!',
             309: '请重新登录!',
             404: '您没有访问的权限!',
@@ -119,6 +147,10 @@ class ResponseObject(object):
             712: '区域不一致',
             713: '有效期内不可更改存储规则',
             717: '授权过期',
+            800: '订单不存在',
+            801: '退款金额不能大于订单价格',
+            802: '订单已完成,不能撤销',
+            804: '订单已退款,请勿重复操作',
             900: '版本信息不存在',
             901: '获取链接失败',
             902: '无更新!',
@@ -132,6 +164,28 @@ class ResponseObject(object):
             10004: '请求方法不正确。请联系开发者',
             10005: '配置错误,客户编号这个值是错误的',
             10006: '配置错误,路径这个值是错误的',
+            10007: '此设备不是体验套餐,无法重置',
+            10008: '用户没有此设备,无法转移',
+            10009: '用户已拥有此设备,无法转移',
+            10010: '不是同一账户下的设备,无法转移',
+            10011: '接受转移设备不存在,无法转移',
+            10012: '体验套餐无法转移',
+            10013: '原设备套餐已过期,无法转移',
+            10014: '接受转移设备套餐未过期,无法转移',
+            10015: '分享的设备无法转移',
+            10030: '未购买云存',
+            10031: '云存已过期',
+            10032: '切换的云存套餐ID不能与正在使用中的相同',
+            10033: '非设备主用户无法购买',
+            10034: '非设备主用户无法查看云存',
+            10035: '非设备主用户无法体验云存',
+            10036: '非设备主用户无法兑换云存',
+            10037: '非设备主用户无法转移设备',
+            10038: '非设备主用户无法转移套餐',
+            10039: '激活码已被使用过',
+            10040: '无效激活码',
+            10041: '此设备已购买过国内云存套餐,无法购买国外云存套餐',
+            10042: '此设备已注册证书'
         }
         if self.lang == 'cn':
             msg = data_cn

+ 201 - 0
Object/WechatPayObject.py

@@ -0,0 +1,201 @@
+import hashlib
+import time
+from urllib.parse import quote
+
+import requests
+import xmltodict
+
+
+class WechatPayObject:
+    """配置账号信息"""
+    # 微信公众号身份的唯一标识。审核通过后,在微信发送的邮件中查看
+
+    def __init__(self):
+        # 开发者调用支付统一下单API生成预交易单
+        self.APPID = 'wx2a9f5ef9baf2760f'
+        # 商户id
+        self.MCHID = '1508209741'
+        # 异步通知url,商户根据实际开发过程设定
+        self.NOTIFY_URL = 'test'
+        self.TRADE_TYPE = 'APP'
+        self.APIKEY = 'ZHansjeransjeransjer680301000000'
+        self.url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'  # 微信请求url
+        self.error = None
+        self.params = None
+
+    def get_parameter(self, order_id, body, total_fee, spbill_create_ip, notify_url, attach):
+        self.params = {
+            'appid': self.APPID,  # appid
+            'mch_id': self.MCHID,  # 商户号
+            'nonce_str': self.getNonceStr(),
+            'body': body,  # 商品描述
+            'out_trade_no': str(order_id),  # 商户订单号
+            'total_fee': str(int(total_fee)),
+            'spbill_create_ip': spbill_create_ip,  # 127.0.0.1
+            'trade_type': self.TRADE_TYPE,  # 交易类型
+            'notify_url': notify_url,  # 微信支付结果异步通知地址
+            'receipt': 'Y',
+            'attach' : attach
+        }
+        return self.params
+
+    def getNonceStr(self, length=32):
+        """生成随机字符串"""
+        import random
+        chars = "abcdefghijklmnopqrstuvwxyz0123456789"
+        strs = []
+        for x in range(length):
+            strs.append(chars[random.randrange(0, len(chars))])
+        return "".join(strs)
+
+    def key_value_url(self, value, urlencode):
+        """
+        将键值对转为 key1=value1&key2=value2
+        对参数按照key=value的格式,并按照参数名ASCII字典序排序
+        """
+        slist = sorted(value)
+        buff = []
+        for k in slist:
+            v = quote(value[k]) if urlencode else value[k]
+            buff.append("{0}={1}".format(k, v))
+
+        return "&".join(buff)
+
+    def get_sign(self, params):
+        """
+        生成sign
+        拼接API密钥
+        """
+        stringA = self.key_value_url(params, False)
+        stringSignTemp = stringA + '&key=' + self.APIKEY  # APIKEY, API密钥,需要在商户后台设置
+        sign = (hashlib.md5(stringSignTemp.encode("utf-8")).hexdigest()).upper()
+        params['sign'] = sign
+        return params
+
+    def get_req_xml(self):
+        """
+        拼接XML
+        """
+        self.get_sign(self.params)
+        xml = "<xml>"
+        for k, v in self.params.items():
+            # v = v.encode('utf8')
+            # k = k.encode('utf8')
+            xml += '<' + k + '>' + v + '</' + k + '>'
+        xml += "</xml>"
+        return xml.encode("utf-8")
+
+    def get_prepay_id(self):
+        """
+        请求获取prepay_id
+        """
+        xml = self.get_req_xml()
+        respone = requests.post(self.url, xml, headers={'Content-Type': 'application/xml'})
+        msg = respone.text.encode('ISO-8859-1').decode('utf-8')
+        xmlresp = xmltodict.parse(msg)
+        if xmlresp['xml']['return_code'] == 'SUCCESS':
+            if xmlresp['xml']['result_code'] == 'SUCCESS':
+                prepay_id = xmlresp['xml']['prepay_id']
+                self.params['prepay_id'] = prepay_id
+                self.params['packageId'] = "Sign=WXPay"
+                self.params['timestamp'] = str(int(time.time()))
+                return self.params
+            else:
+                return 'failure'
+        else:
+            return 'failure'
+
+    def re_finall(self,orderid = None):
+        """得到prepay_id后再次签名,返回给终端参数.
+        """
+        self.get_prepay_id()
+        if self.error:
+            return False
+        sign_again_params = {
+            'appid': self.params['appid'],
+            'noncestr': self.params['nonce_str'],
+            'package': self.params['packageId'],
+            'partnerid': self.params['mch_id'],
+            'timestamp': self.params['timestamp'],
+            'prepayid': self.params['prepay_id']
+        }
+        self.get_sign(sign_again_params)
+        sign_again_params['sign'] = sign_again_params['sign']
+        sign_again_params['packageId'] = sign_again_params['package']
+        sign_again_params['out_trade_no'] = orderid
+        return sign_again_params  # 返回给app
+
+    def get_notifypay(self, data):
+
+        success = self.get_sign(data)
+        # print('success', success)
+        if success:
+            success.pop("sign", None)
+            success.pop("sign_type", None)
+            # return success
+            return True
+        else:
+            return False
+
+    def weixinpay_call_back(self, data):
+
+        args = str(data, 'utf-8')
+
+        if args is None:
+            return None
+
+        print(args)
+
+        # 验证平台签名
+
+        resp_dict = self.handle_wx_response_xml(args)
+        if resp_dict is None:
+            print('签名验证失败!!!')
+            return None
+
+        return resp_dict
+
+    def handle_wx_response_xml(self, params):
+
+        """
+
+        处理微信支付返回的xml格式数据
+
+        """
+
+        try:
+
+            resp_dict = xmltodict.parse(params)['xml']
+
+            if not resp_dict or len(resp_dict) < 1:
+                print('resp_dict is zero+++++++++')
+
+                return None
+
+            return_code = resp_dict.get('return_code')
+
+            if return_code == 'SUCCESS':  # 仅仅判断通信标识成功,非交易标识成功,交易需判断result_code
+                return resp_dict
+
+
+        except Exception as e:
+            print(e)
+
+            return None
+
+        return None
+
+    @staticmethod
+    def xml_to_dict(params):
+        """
+        拼接XML
+        """
+        if not isinstance(params, dict):
+            return None
+        xml = "<xml>"
+        for k, v in params.items():
+            # v = v.encode('utf8')
+            # k = k.encode('utf8')
+            xml += '<' + k + '>' + v + '</' + k + '>'
+        xml += "</xml>"
+        return xml

+ 143 - 0
Service/CommonService.py

@@ -14,6 +14,7 @@ from Ansjer.config import BASE_DIR, UNICODE_ASCII_CHARACTER_SET
 
 # 复用性且公用较高封装代码在这
 from Controller.CheckUserData import RandomStr
+from Service.ModelService import ModelService
 
 
 class CommonService:
@@ -95,11 +96,14 @@ class CommonService:
     # 根据ip获取地址
     @staticmethod
     def getAddr(ip):
+        print('start_time=' + str(time.time()))
         base_dir = BASE_DIR
         # ip数据库
         db = IPIPDatabase(base_dir + '/DB/17monipdb.dat')
         addr = db.lookup(ip)
+        # ModelService.add_tmp_log(addr)
         ts = addr.split('\t')[0]
+        print('end_time=' + str(time.time()))
         return ts
 
     # 通过ip检索ipip指定信息 lang为CN或EN
@@ -262,3 +266,142 @@ class CommonService:
                 content = RandomStr(1, False)+str(content)+RandomStr(1, False)
                 content = base64.b64encode(str(content).encode("utf-8")).decode('utf8')
         return content
+
+    #把格式化时间转换成时间戳
+    @staticmethod
+    def str_to_timestamp(str_time=None, format='%Y-%m-%d %H:%M:%S'):
+        if str_time:
+            time_tuple = time.strptime(str_time, format)  # 把格式化好的时间转换成元祖
+            result = time.mktime(time_tuple)  # 把时间元祖转换成时间戳
+            return int(result)
+        return int(time.time())
+
+
+
+
+    # 把时间戳转换成格式化
+    @staticmethod
+    def timestamp_to_str(timestamp=None, format='%Y-%m-%d %H:%M:%S'):
+        if timestamp:
+            time_tuple = time.localtime(timestamp)  # 把时间戳转换成时间元祖
+            result = time.strftime(format, time_tuple)  # 把时间元祖转换成格式化好的时间
+            return result
+        else:
+            return time.strptime(format)
+
+
+    #计算N个月后的时间戳
+    @staticmethod
+    def calcMonthLater(addMonth, unix_timestamp=None):
+        if unix_timestamp:
+            now_year = time.localtime(unix_timestamp).tm_year
+            now_month = time.localtime(unix_timestamp).tm_mon
+            now_day = time.localtime(unix_timestamp).tm_mday
+            now_hour = time.localtime(unix_timestamp).tm_hour
+            now_min = time.localtime(unix_timestamp).tm_min
+            now_second = time.localtime(unix_timestamp).tm_sec
+        else:
+            now_year = datetime.datetime.now().year
+            now_month = datetime.datetime.now().month
+            now_day = datetime.datetime.now().day
+            now_hour = datetime.datetime.now().hour
+            now_min = datetime.datetime.now().minute
+            now_second = datetime.datetime.now().second
+        for add in range(addMonth):
+            if now_month == 12:
+                now_year += 1
+                now_month = 1
+            else:
+                now_month += 1
+
+        for is_format in range(4):
+            try:
+                date_format = '{now_year}-{now_month}-{now_day} {now_hour}:{now_min}:{now_second}' \
+                    .format(now_year=now_year,now_month=now_month,now_day=now_day,now_hour=now_hour,
+                            now_min=now_min,now_second=now_second)
+                timestamps = CommonService.str_to_timestamp(date_format)
+            except Exception as e:
+                if str(e) == 'day is out of range for month':
+                    now_day = now_day - 1
+        return timestamps
+
+    @staticmethod
+    def updateMac(mac: str):
+        macArray = mac.split(':')
+
+        macArray[0] = int(macArray[0], 16)
+        macArray[1] = int(macArray[1], 16)
+        macArray[2] = int(macArray[2], 16)
+        first = int(macArray[5], 16)
+        second = int(macArray[4], 16)
+        three = int(macArray[3], 16)
+
+        # print(macArray)
+        # print(first)
+        # print(second)
+        # print(three)
+
+        if first == 255 and second == 255 and three == 255:
+            return None
+
+        first += 1
+
+        if first / 256 == 1:
+            second += 1
+            first = first % 256
+
+        if second / 256 == 1:
+            three += 1
+            second = second % 256
+
+        macArray[3] = three
+        macArray[4] = second
+        macArray[5] = first
+        # print(macArray)
+
+        tmp = ':'.join(map(lambda x: "%02x" % x, macArray))
+        # print(tmp)
+        return tmp.upper()
+
+    @staticmethod
+    def decode_data(content, start=1, end=4):
+        try:
+            for i in range(start, end):
+                if i == 1:
+                    content = base64.b64decode(content)
+                    content = content.decode('utf-8')
+                    content = content[1:-1]
+                if i == 2:
+                    content = base64.b64decode(content)
+                    content = content.decode('utf-8')
+                    content = content[2:-2]
+                if i == 3:
+                    content = base64.b64decode(content)
+                    content = content.decode('utf-8')
+                    content = content[3:-3]
+                    print(content)
+
+            return content
+        except Exception as e:
+            print(e)
+            return None
+
+    @staticmethod
+    def encode_data(content, start=1, end=4):
+        for i in range(start, end):
+            if i == 1:
+                content = CommonService.RandomStr(3, False) + content + CommonService.RandomStr(3, False)
+                content = base64.b64encode(str(content).encode("utf-8")).decode('utf8')
+            if i == 2:
+                content = CommonService.RandomStr(2, False) + str(content) + CommonService.RandomStr(2, False)
+                content = base64.b64encode(str(content).encode("utf-8")).decode('utf8')
+            if i == 3:
+                content = CommonService.RandomStr(1, False) + str(content) + CommonService.RandomStr(1, False)
+                content = base64.b64encode(str(content).encode("utf-8")).decode('utf8')
+        return content
+
+    @staticmethod
+    def encode_data_without_salt(content):
+        return base64.b64encode(str(content).encode("utf-8")).decode('utf8')
+
+

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است