Ver código fonte

Merge branch 'dev' into cloud_storage_dev

lang 3 anos atrás
pai
commit
d2ab99b2d4

+ 91 - 1
AdminController/LogManagementController.py

@@ -9,12 +9,14 @@ import uuid
 import boto3
 import boto3
 import threading
 import threading
 import logging
 import logging
+
+import requests
 from boto3.session import Session
 from boto3.session import Session
 from django.http import JsonResponse, HttpResponseRedirect, HttpResponse
 from django.http import JsonResponse, HttpResponseRedirect, HttpResponse
 from django.views.generic.base import View
 from django.views.generic.base import View
 
 
 from Controller.CheckUserData import date_handler
 from Controller.CheckUserData import date_handler
-from Model.models import Device_Info, Role, MenuModel, RequestRecordModel
+from Model.models import Device_Info, Role, MenuModel, RequestRecordModel, iotdeviceInfoModel
 from Object.ResponseObject import ResponseObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Object.TokenObject import TokenObject
 from Object.UidTokenObject import UidTokenObject
 from Object.UidTokenObject import UidTokenObject
@@ -49,6 +51,12 @@ class LogManagementView(View):
             userID = tko.userID
             userID = tko.userID
             if operation == 'getRequestList':
             if operation == 'getRequestList':
                 return self.getRequestList(request_dict, response)
                 return self.getRequestList(request_dict, response)
+            elif operation == 'getDeviceIotInfoList':
+                return self.getDeviceIotInfoList(request_dict, response)
+            elif operation == 'requestPublishMqtt':
+                return self.requestPublishMqtt(request_dict, response)
+            else:
+                return response.json(404)
 
 
     def getRequestList(self, request_dict, response):
     def getRequestList(self, request_dict, response):
         pageNo = request_dict.get('pageNo', None)
         pageNo = request_dict.get('pageNo', None)
@@ -96,3 +104,85 @@ class LogManagementView(View):
         except Exception as e:
         except Exception as e:
             print(e)
             print(e)
             return response.json(500, repr(e))
             return response.json(500, repr(e))
+
+    def getDeviceIotInfoList(self, request_dict, response):
+        serial_number = request_dict.get('serial_number', None)
+        uid = request_dict.get('uid', None)
+        pageNo = request_dict.get('pageNo', None)
+        pageSize = request_dict.get('pageSize', None)
+
+        if not all([pageNo, pageSize]):
+            return response.json(444)
+
+        page = int(pageNo)
+        line = int(pageSize)
+        try:
+            if serial_number or uid:
+                if serial_number:
+                    iot_device_info_qs = iotdeviceInfoModel.objects.filter(serial_number__contains=serial_number)
+                if uid:
+                    iot_device_info_qs = iotdeviceInfoModel.objects.filter(uid__contains=uid)
+                if not iot_device_info_qs.exists():
+                    return response.json(0)
+                total = len(iot_device_info_qs)
+                iot_device_info_qs = iot_device_info_qs.values('serial_number', 'uid', 'thing_name', 'thing_groups',
+                                                               'add_time', 'update_time')[(page - 1) * line:page * line]
+            else:
+                total = iotdeviceInfoModel.objects.filter().count()
+                iot_device_info_qs = iotdeviceInfoModel.objects.filter().values('serial_number', 'uid', 'thing_name',
+                                                                                'thing_groups', 'add_time', 'update_time')[(page - 1) * line:page * line]
+
+            iot_device_info_list = CommonService.qs_to_list(iot_device_info_qs)
+            # 获取序列号的uid
+            for iot_device_info in iot_device_info_list:
+                if not iot_device_info['uid']:
+                    device_info_qs = Device_Info.objects.filter(serial_number__contains=iot_device_info['serial_number']).values('UID')
+                    if device_info_qs.exists():
+                        iot_device_info['uid'] = device_info_qs[0]['UID']
+            return response.json(0, {'list': iot_device_info_list, 'total': total})
+        except Exception as e:
+            print(e)
+            return response.json(500, repr(e))
+
+    def requestPublishMqtt(self, request_dict, response):
+        # 通用发布主题通知
+        uid = request_dict.get('uid', None)
+        msg = request_dict.get('msg', None)
+        thing_name = request_dict.get('thing_name', None)
+        topic_name = request_dict.get('topic_name', None)
+        if not all([uid, msg, thing_name, topic_name]):
+            return response.json(444)
+
+        try:
+            # 设备没被添加不发送
+            device_info_qs = Device_Info.objects.filter(UID=uid).values('UID', 'serial_number')
+            if not device_info_qs.exists():
+                return response.json(10043)
+            # 获取数据组织将要请求的url
+            iot = iotdeviceInfoModel.objects.filter(thing_name=thing_name).values('endpoint', 'token_iot_number')
+            if not iot.exists():
+                return response.json(10043)
+            endpoint = iot[0]['endpoint']
+            Token = iot[0]['token_iot_number']
+
+            # api doc: https://docs.aws.amazon.com/zh_cn/iot/latest/developerguide/http.html
+            # url: https://IoT_data_endpoint/topics/url_encoded_topic_name?qos=1
+            # post请求url发布MQTT消息
+            url = 'https://{}/topics/{}'.format(endpoint, topic_name)
+            authorizer_name = 'Ansjer_Iot_Auth'
+            signature = CommonService.rsa_sign(Token)  # Token签名
+            headers = {'x-amz-customauthorizer-name': authorizer_name, 'Token': Token,
+                       'x-amz-customauthorizer-signature': signature}
+            msg = eval(msg)
+            r = requests.post(url=url, headers=headers, json=msg, timeout=2)
+            if r.status_code == 200:
+                res = r.json()
+                if res['message'] == 'OK':
+                    return response.json(0)
+                return response.json(10044)
+            else:
+                # print('发布失败')
+                return response.json(10044)
+        except Exception as e:
+            # print(e)
+            return response.json(500, repr(e))

+ 17 - 0
AdminController/UserManageController.py

@@ -311,6 +311,8 @@ class UserManagement(View):
             return self.getAppDataList(request_dict, response)
             return self.getAppDataList(request_dict, response)
         elif operation == 'replyFeedBack':
         elif operation == 'replyFeedBack':
             return self.replyFeedBack(request_dict, response)
             return self.replyFeedBack(request_dict, response)
+        elif operation == 'sendSysMsgToUser':
+            return self.sendSysMsgToUser(request_dict, response)
         else:
         else:
             tko = TokenObject(request.META.get('HTTP_AUTHORIZATION'), returntpye='pc')
             tko = TokenObject(request.META.get('HTTP_AUTHORIZATION'), returntpye='pc')
             if tko.code != 0:
             if tko.code != 0:
@@ -558,6 +560,21 @@ class UserManagement(View):
             print(e)
             print(e)
             return response.json(500, repr(e))
             return response.json(500, repr(e))
 
 
+    def sendSysMsgToUser(self, request_dict, response):
+        userID = request_dict.get('userID', None)
+        msg = request_dict.get('msg', None)
+
+        if not all([userID, msg]):
+            return response.json(444)
+
+        try:
+            nowTime = int(time.time())
+            SysMsgModel.objects.create(userID_id=userID, msg=msg, addTime=nowTime, updTime=nowTime)
+            return response.json(0)
+        except Exception as e:
+            print(e)
+            return response.json(500, repr(e))
+
     def deleteFeedBack(self, request_dict, response):
     def deleteFeedBack(self, request_dict, response):
         feedBackID = request_dict.get('feedBackID', None)
         feedBackID = request_dict.get('feedBackID', None)
         if not feedBackID:
         if not feedBackID:

+ 127 - 1
AdminController/VersionManagementController.py

@@ -2,10 +2,12 @@
 # -*- coding: utf-8 -*-
 # -*- coding: utf-8 -*-
 import os
 import os
 import hashlib
 import hashlib
+import time
+
 from django.views.generic.base import View
 from django.views.generic.base import View
 
 
 from Ansjer.config import BASE_DIR
 from Ansjer.config import BASE_DIR
-from Model.models import Equipment_Version
+from Model.models import Equipment_Version, App_Info, AppSetModel
 from Object.TokenObject import TokenObject
 from Object.TokenObject import TokenObject
 from Object.ResponseObject import ResponseObject
 from Object.ResponseObject import ResponseObject
 from Service.CommonService import CommonService
 from Service.CommonService import CommonService
@@ -41,6 +43,16 @@ class VersionManagement(View):
                 return self.editVersionInformation(request_dict, response)
                 return self.editVersionInformation(request_dict, response)
             elif operation == 'deleteEquipmentVersion':
             elif operation == 'deleteEquipmentVersion':
                 return self.deleteEquipmentVersion(request_dict, response)
                 return self.deleteEquipmentVersion(request_dict, response)
+            elif operation == 'getAppVersionList':
+                return self.getAppVersionList(request_dict, response)
+            elif operation == 'addOrEditAppInfo':
+                return self.addOrEditAppInfo(request_dict, response)
+            elif operation == 'deleteAppVersion':
+                return self.deleteAppVersion(request_dict, response)
+            elif operation == 'getAppSet':
+                return self.getAppSet(request_dict, response)
+            elif operation == 'editAppSet':
+                return self.editAppSet(request_dict, response)
             else:
             else:
                 return response.json(404)
                 return response.json(404)
 
 
@@ -178,3 +190,117 @@ class VersionManagement(View):
             print(e)
             print(e)
             return response.json(500, repr(e))
             return response.json(500, repr(e))
 
 
+    def getAppVersionList(self, request_dict, response):
+        app_type = request_dict.get('app_type', None)
+        appName = request_dict.get('appName', None)
+        version = request_dict.get('version', None)
+        pageNo = request_dict.get('pageNo', None)
+        pageSize = request_dict.get('pageSize', None)
+
+        if not all([pageNo, pageSize]):
+            return response.json(444)
+
+        page = int(pageNo)
+        line = int(pageSize)
+
+        try:
+            app_info_qs = App_Info.objects.filter()
+            if app_type:
+                if app_type == 'IOS':
+                    app_type = 1
+                elif app_type == '安卓':
+                    app_type = 2
+                else:
+                    app_type = 3
+                app_info_qs = app_info_qs.filter(app_type=app_type)
+            if appName:
+                app_info_qs = app_info_qs.filter(appName__contains=appName)
+            if version:
+                app_info_qs = app_info_qs.filter(version__contains=version)
+
+            total = app_info_qs.count()
+            app_info_qs = app_info_qs.values()[(page - 1) * line:page * line]
+            app_info_list = CommonService.qs_to_list(app_info_qs)
+            return response.json(0, {'list': app_info_list, 'total': total})
+        except Exception as e:
+            print(e)
+            return response.json(500, repr(e))
+
+    def addOrEditAppInfo(self, request_dict, response):
+        id = request_dict.get('id', None)
+        appName = request_dict.get('appName', '')
+        appBundleId = request_dict.get('appBundleId', '')
+        bundleVersion = request_dict.get('bundleVersion', '')
+        newAppversion = request_dict.get('newAppversion', '')
+        minAppversion = request_dict.get('minAppversion', '')
+        content = request_dict.get('content', '')
+        app_type = request_dict.get('app_type', '')
+        downloadLink = request_dict.get('downloadLink', '')
+
+        try:
+            app_type = int(app_type)
+            data_dict = {'appName': appName, 'appBundleId': appBundleId, 'bundleVersion': bundleVersion,
+                         'newAppversion': newAppversion, 'minAppversion': minAppversion, 'content': content,
+                         'app_type': app_type, 'downloadLink': downloadLink}
+            if not id:      # 添加
+                App_Info.objects.create(**data_dict)
+            else:           # 编辑
+                app_info_qs = App_Info.objects.filter(id=id)
+                if not app_info_qs.exists():
+                    return response.json(173)
+                app_info_qs.update(**data_dict)
+            return response.json(0)
+        except Exception as e:
+            print(e)
+            return response.json(500, repr(e))
+
+    def deleteAppVersion(self, request_dict, response):
+        appBundleId = request_dict.get('appBundleId', None)
+
+        if not appBundleId:
+            return response.json(444)
+
+        try:
+            App_Info.objects.filter(appBundleId=appBundleId).delete()
+            AppSetModel.objects.filter(appBundleId=appBundleId).delete()
+            return response.json(0)
+        except Exception as e:
+            print(e)
+            return response.json(500, repr(e))
+
+    def getAppSet(self, request_dict, response):
+        appBundleId = request_dict.get('appBundleId', None)
+
+        if not appBundleId:
+            return response.json(444)
+
+        try:
+            app_set_qs = AppSetModel.objects.filter(appBundleId=appBundleId).values('content')
+            if app_set_qs.exists():
+                content = app_set_qs[0]['content']
+                return response.json(0, {'content': content})
+            else:
+                nowTime = int(time.time())
+                AppSetModel.objects.create(
+                    appBundleId=appBundleId,
+                    addTime=nowTime,
+                    updTime=nowTime
+                )
+                return response.json(0)
+        except Exception as e:
+            print(e)
+            return response.json(500, repr(e))
+
+    def editAppSet(self, request_dict, response):
+        appBundleId = request_dict.get('appBundleId', None)
+        content = request_dict.get('content', None)
+
+        if not all([appBundleId, content]):
+            return response.json(444)
+
+        try:
+            AppSetModel.objects.filter(appBundleId=appBundleId).update(content=content)
+            return response.json(0)
+        except Exception as e:
+            print(e)
+            return response.json(500, repr(e))

+ 4 - 1
Ansjer/cn_config/config_formal.py

@@ -125,7 +125,10 @@ TUTK_PUSH_DOMAIN = 'http://push.iotcplatform.com/tpns'
 
 
 # aws api key
 # aws api key
 AWS_ARN_S3 = 'arn:aws-cn:s3'
 AWS_ARN_S3 = 'arn:aws-cn:s3'
-AVATAR_BUCKET = 'avatar-cn'
 REGION_NAME = 'cn-northwest-1'
 REGION_NAME = 'cn-northwest-1'
 ACCESS_KEY_ID = 'AKIA2MMWBR4DSFG67DTG'
 ACCESS_KEY_ID = 'AKIA2MMWBR4DSFG67DTG'
 SECRET_ACCESS_KEY = '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'
 SECRET_ACCESS_KEY = 'aI9gxcAKPmiGgPy9axrtFKzjYGbvpuytEX4xWweL'
+
+# 存储桶名
+AVATAR_BUCKET = 'avatar-cn'         # 头像存储桶
+LOG_BUCKET = 'ansjer-statres'       # 日志存储桶

+ 4 - 1
Ansjer/cn_config/config_test.py

@@ -137,7 +137,10 @@ TUTK_PUSH_DOMAIN = 'http://push.iotcplatform.com/tpns'
 
 
 # aws api key
 # aws api key
 AWS_ARN_S3 = 'arn:aws-cn:s3'
 AWS_ARN_S3 = 'arn:aws-cn:s3'
-AVATAR_BUCKET = 'avatar-cn'
 REGION_NAME = 'cn-northwest-1'
 REGION_NAME = 'cn-northwest-1'
 ACCESS_KEY_ID = 'AKIA2MMWBR4DSFG67DTG'
 ACCESS_KEY_ID = 'AKIA2MMWBR4DSFG67DTG'
 SECRET_ACCESS_KEY = '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'
 SECRET_ACCESS_KEY = 'aI9gxcAKPmiGgPy9axrtFKzjYGbvpuytEX4xWweL'
+
+# 存储桶名
+AVATAR_BUCKET = 'avatar-cn'         # 头像存储桶
+LOG_BUCKET = 'ansjer-statres'       # 日志存储桶

+ 4 - 1
Ansjer/local_config/config_local.py

@@ -58,7 +58,10 @@ TUTK_PUSH_DOMAIN = 'http://push.iotcplatform.com/tpns'
 
 
 # aws api key
 # aws api key
 AWS_ARN_S3 = 'arn:aws-cn:s3'
 AWS_ARN_S3 = 'arn:aws-cn:s3'
-AVATAR_BUCKET = 'avatar-cn'
 REGION_NAME = 'cn-northwest-1'
 REGION_NAME = 'cn-northwest-1'
 ACCESS_KEY_ID = 'AKIA2MMWBR4DSFG67DTG'
 ACCESS_KEY_ID = 'AKIA2MMWBR4DSFG67DTG'
 SECRET_ACCESS_KEY = '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'
 SECRET_ACCESS_KEY = 'aI9gxcAKPmiGgPy9axrtFKzjYGbvpuytEX4xWweL'
+
+# 存储桶名
+AVATAR_BUCKET = 'avatar-cn'         # 头像存储桶
+LOG_BUCKET = 'ansjer-statres'       # 日志存储桶

+ 4 - 1
Ansjer/us_config/config_formal.py

@@ -125,7 +125,10 @@ TUTK_PUSH_DOMAIN = 'http://push.iotcplatform.com/tpns'
 
 
 # aws api key
 # aws api key
 AWS_ARN_S3 = 'arn:aws:s3'
 AWS_ARN_S3 = 'arn:aws:s3'
-AVATAR_BUCKET = 'avatar-us'
 REGION_NAME = 'us-east-1'
 REGION_NAME = 'us-east-1'
 ACCESS_KEY_ID = 'AKIA2E67UIMD45Y3HL53'
 ACCESS_KEY_ID = 'AKIA2E67UIMD45Y3HL53'
 SECRET_ACCESS_KEY = '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'
 SECRET_ACCESS_KEY = 'ckYLg4Lo9ZXJIcJEAKkzf2rWvs8Xth1FCjqiAqUw'
+
+# 存储桶名
+AVATAR_BUCKET = 'avatar-us'         # 头像存储桶
+LOG_BUCKET = 'ansjer-statres'       # 日志存储桶

+ 4 - 1
Ansjer/us_config/config_test.py

@@ -136,7 +136,10 @@ TUTK_PUSH_DOMAIN = 'http://push.iotcplatform.com/tpns'
 
 
 # aws api key
 # aws api key
 AWS_ARN_S3 = 'arn:aws:s3'
 AWS_ARN_S3 = 'arn:aws:s3'
-AVATAR_BUCKET = 'avatar-us'
 REGION_NAME = 'us-east-1'
 REGION_NAME = 'us-east-1'
 ACCESS_KEY_ID = 'AKIA2E67UIMD45Y3HL53'
 ACCESS_KEY_ID = 'AKIA2E67UIMD45Y3HL53'
 SECRET_ACCESS_KEY = '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'
 SECRET_ACCESS_KEY = 'ckYLg4Lo9ZXJIcJEAKkzf2rWvs8Xth1FCjqiAqUw'
+
+# 存储桶名
+AVATAR_BUCKET = 'avatar-us'         # 头像存储桶
+LOG_BUCKET = 'ansjer-statres'       # 日志存储桶

+ 3 - 2
Controller/AppLogController.py

@@ -7,7 +7,8 @@ import botocore
 import oss2
 import oss2
 from django.views.generic.base import View
 from django.views.generic.base import View
 
 
-from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, REGION_NAME, ACCESS_KEY_ID, SECRET_ACCESS_KEY
+from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, REGION_NAME, ACCESS_KEY_ID, SECRET_ACCESS_KEY, \
+    LOG_BUCKET
 from Model.models import AppLogModel
 from Model.models import AppLogModel
 from Object.ResponseObject import ResponseObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Object.TokenObject import TokenObject
@@ -66,7 +67,7 @@ class AppLogView(View):
         response_url = aws_s3_client.generate_presigned_url(
         response_url = aws_s3_client.generate_presigned_url(
             ClientMethod='put_object',
             ClientMethod='put_object',
             Params={
             Params={
-                'Bucket': 'ansjer-statres',
+                'Bucket': LOG_BUCKET,
                 'Key': obj
                 'Key': obj
             },
             },
             ExpiresIn=3600
             ExpiresIn=3600

+ 8 - 1
Controller/AppSetController.py

@@ -12,7 +12,7 @@
 @Contact: chanjunkai@163.com
 @Contact: chanjunkai@163.com
 """
 """
 from Ansjer.config import SERVER_TYPE
 from Ansjer.config import SERVER_TYPE
-from Model.models import AppSetModel
+from Model.models import AppSetModel,PromotionRuleModel
 from django.views.generic.base import View
 from django.views.generic.base import View
 from Object.RedisObject import RedisObject
 from Object.RedisObject import RedisObject
 from Object.TokenObject import TokenObject
 from Object.TokenObject import TokenObject
@@ -67,6 +67,13 @@ class AppSetView(View):
             if not app_set_qs[0]['content']:
             if not app_set_qs[0]['content']:
                 return response.json(0)
                 return response.json(0)
             dict_json = json.loads(app_set_qs[0]['content'])
             dict_json = json.loads(app_set_qs[0]['content'])
+            #加入促销弹窗
+            promotion = PromotionRuleModel.objects.filter(status=1).values('startTime','endTime','popups')
+            if promotion.exists():
+                dict_json['popupsStartTime'] = promotion[0]['startTime']
+                dict_json['popupsEndTime'] = promotion[0]['endTime']
+                dict_json['popupsContent'] = json.loads(promotion[0]['popups']).get(lang,'')
+                dict_json['nowTime'] = int(time.time())
             if 'editionUpgrading' in dict_json:
             if 'editionUpgrading' in dict_json:
                 if dict_json['editionUpgrading'] == 1:
                 if dict_json['editionUpgrading'] == 1:
                     if lang == 'cn':
                     if lang == 'cn':

+ 95 - 19
Controller/CloudStorage.py

@@ -40,7 +40,7 @@ from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, OSS_ROLE_AR
 from Controller.CheckUserData import DataValid
 from Controller.CheckUserData import DataValid
 from Model.models import Device_Info, Order_Model, Store_Meal, VodHlsModel, OssCrdModel, UID_Bucket, StsCrdModel, \
 from Model.models import Device_Info, Order_Model, Store_Meal, VodHlsModel, OssCrdModel, UID_Bucket, StsCrdModel, \
     ExperienceContextModel, Pay_Type, CDKcontextModel, Device_User, SysMassModel, SysMsgModel, UidPushModel, \
     ExperienceContextModel, Pay_Type, CDKcontextModel, Device_User, SysMassModel, SysMsgModel, UidPushModel, \
-    Unused_Uid_Meal, UIDMainUser, UserModel
+    Unused_Uid_Meal, UIDMainUser, UserModel, PromotionRuleModel
 from Object.AWS.S3Email import S3Email
 from Object.AWS.S3Email import S3Email
 from Object.AliPayObject import AliPayObject
 from Object.AliPayObject import AliPayObject
 from Object.AliSmsObject import AliSmsObject
 from Object.AliSmsObject import AliSmsObject
@@ -52,7 +52,7 @@ from Service.CommonService import CommonService
 from Object.m3u8generate import PlaylistGenerator
 from Object.m3u8generate import PlaylistGenerator
 from Object.WechatPayObject import WechatPayObject
 from Object.WechatPayObject import WechatPayObject
 from django.db.models import Q, F, Count
 from django.db.models import Q, F, Count
-
+from Ansjer.config import SERVER_TYPE
 from Service.ModelService import ModelService
 from Service.ModelService import ModelService
 
 
 # SERVER_DOMAIN = 'http://test.dvema.com/'
 # SERVER_DOMAIN = 'http://test.dvema.com/'
@@ -232,13 +232,32 @@ class CloudStorageView(View):
 
 
                 res_c = {'area': area, 'items': items_list}
                 res_c = {'area': area, 'items': items_list}
                 res.append(res_c)
                 res.append(res_c)
+            #是否促销
+            nowTime = int(time.time())
+            promotion = PromotionRuleModel.objects.filter(status=1, startTime__lte=nowTime,
+                                                          endTime__gte=nowTime).values('id','ruleConfig','ruleName',
+                                                                                       'startTime','endTime','ruleDesc')
+            if promotion.exists():
+                promotion = {
+                    'is_promotion': 1,
+                    'promotionStartTime': promotion[0]['startTime'],
+                    'promotionEndTime': promotion[0]['endTime'],
+                    'promotionName': json.loads(promotion[0]['ruleName']).get(lang, ''),
+                    'promotionDesc': json.loads(promotion[0]['ruleDesc']).get(lang, ''),
+                    'nowTime':int(time.time())
+                }
+            else:
+                promotion = {
+                    'is_promotion': 0
+                }
             result = {
             result = {
                 'meals': res,
                 'meals': res,
                 'extra':
                 'extra':
                     {
                     {
                         'cloud_banner': SERVER_DOMAIN+'web/images/cloud_cn_banner.png',
                         'cloud_banner': SERVER_DOMAIN+'web/images/cloud_cn_banner.png',
                         'cloud_en_baner': SERVER_DOMAIN_SSL+'web/images/cloud_en_banner.png'
                         'cloud_en_baner': SERVER_DOMAIN_SSL+'web/images/cloud_en_banner.png'
-                    }
+                    },
+                'promotion':promotion
             }
             }
             return response.json(0, result)
             return response.json(0, result)
         else:
         else:
@@ -418,6 +437,7 @@ class CloudStorageView(View):
         vh_qs = VodHlsModel.objects.filter \
         vh_qs = VodHlsModel.objects.filter \
             (uid=uid, channel=channel, endTime__gte=now_time, time__range=(startTime, endTime)). \
             (uid=uid, channel=channel, endTime__gte=now_time, time__range=(startTime, endTime)). \
             values("id", "time", "sec", "bucket__bucket", "fg", "bucket__endpoint", "bucket__region", "bucket__mold")
             values("id", "time", "sec", "bucket__bucket", "fg", "bucket__endpoint", "bucket__region", "bucket__mold")
+
         vod_play_list = []
         vod_play_list = []
         if not vh_qs.exists():
         if not vh_qs.exists():
             return response.json(0, vod_play_list)
             return response.json(0, vod_play_list)
@@ -726,12 +746,17 @@ class CloudStorageView(View):
             data.pop('sign')
             data.pop('sign')
             orderID = data['out_trade_no']
             orderID = data['out_trade_no']
 
 
-            order_qs = Order_Model.objects.filter(orderID=orderID, status=0)
+            # redis加锁,防止订单重复
+            redisObj = RedisObject()
+            isLock = redisObj.CONN.setnx(orderID + 'do_notify', 1)
+            redisObj.CONN.expire(orderID + 'do_notify', 60)
+            if not isLock:
+                return response.json(5)
 
 
+            order_qs = Order_Model.objects.filter(orderID=orderID, status=0)
             aliPayObj = AliPayObject()
             aliPayObj = AliPayObject()
             alipay = aliPayObj.conf()
             alipay = aliPayObj.conf()
             success = alipay.verify(data, signature)
             success = alipay.verify(data, signature)
-
             if success and data["trade_status"] in ("TRADE_SUCCESS", "TRADE_FINISHED"):
             if success and data["trade_status"] in ("TRADE_SUCCESS", "TRADE_FINISHED"):
                 print("trade succeed")
                 print("trade succeed")
 
 
@@ -754,6 +779,14 @@ class CloudStorageView(View):
                 expire = smqs[0]['expire']
                 expire = smqs[0]['expire']
                 if order_list[0]['isSelectDiscounts'] == 1:
                 if order_list[0]['isSelectDiscounts'] == 1:
                     expire = smqs[0]['expire'] * 2
                     expire = smqs[0]['expire'] * 2
+                # 是否有促销
+                nowTime = int(time.time())
+                promotion = PromotionRuleModel.objects.filter(status=1, startTime__lte=nowTime,
+                                                              endTime__gte=nowTime).values('id','ruleConfig')
+                promotion_rule_id = ''
+                if promotion.exists():
+                    promotion_rule_id = promotion[0]['id']
+                    expire = expire * 2
                 with transaction.atomic():
                 with transaction.atomic():
                     if ubqs.exists():
                     if ubqs.exists():
                         ubq = ubqs[0]
                         ubq = ubqs[0]
@@ -765,6 +798,8 @@ class CloudStorageView(View):
                         else:     #已过期或者不相同的套餐加入未使用的关联套餐表
                         else:     #已过期或者不相同的套餐加入未使用的关联套餐表
                             has_unused = Unused_Uid_Meal.objects.filter(uid=UID, bucket_id=bucketId).values("id")
                             has_unused = Unused_Uid_Meal.objects.filter(uid=UID, bucket_id=bucketId).values("id")
                             nums = 2 if order_list[0]['isSelectDiscounts'] == 1 else 1
                             nums = 2 if order_list[0]['isSelectDiscounts'] == 1 else 1
+                            if promotion.exists():
+                                nums = nums + 1
                             if has_unused.exists():
                             if has_unused.exists():
                                 Unused_Uid_Meal.objects.filter(id=has_unused[0]['id']).update(num=F('num') + nums)
                                 Unused_Uid_Meal.objects.filter(id=has_unused[0]['id']).update(num=F('num') + nums)
                             else:
                             else:
@@ -795,18 +830,20 @@ class CloudStorageView(View):
                     #     }
                     #     }
                     #     UIDMainUser.objects.create(**uid_main_dict)
                     #     UIDMainUser.objects.create(**uid_main_dict)
 
 
-                    order_qs.update(status=1, updTime=nowTime, uid_bucket_id=uid_bucket_id)
+                    order_qs.update(status=1, updTime=nowTime, uid_bucket_id=uid_bucket_id, promotion_rule_id=promotion_rule_id)
                     datetime = time.strftime("%Y-%m-%d", time.localtime())
                     datetime = time.strftime("%Y-%m-%d", time.localtime())
                     sys_msg_text_list = ['温馨提示:尊敬的客户,您的'+UID+'设备在'+datetime+'已成功购买云存套餐', 'Dear customer,you already subscribed the cloud storage package successfully for device ' + UID + ' on '+ time.strftime("%b %dth,%Y", time.localtime())]
                     sys_msg_text_list = ['温馨提示:尊敬的客户,您的'+UID+'设备在'+datetime+'已成功购买云存套餐', 'Dear customer,you already subscribed the cloud storage package successfully for device ' + UID + ' on '+ time.strftime("%b %dth,%Y", time.localtime())]
                     self.do_vod_msg_Notice(UID, channel, userid, lang, sys_msg_text_list, 'SMS_219738485')
                     self.do_vod_msg_Notice(UID, channel, userid, lang, sys_msg_text_list, 'SMS_219738485')
                     red_url = "{SERVER_DOMAIN_SSL}web/paid2/success.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
                     red_url = "{SERVER_DOMAIN_SSL}web/paid2/success.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
                     if lang != 'cn':
                     if lang != 'cn':
                         red_url = "{SERVER_DOMAIN_SSL}web/paid2/en_success.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
                         red_url = "{SERVER_DOMAIN_SSL}web/paid2/en_success.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
+                    redisObj.del_data(key=orderID + 'do_notify')
                     return HttpResponseRedirect(red_url)
                     return HttpResponseRedirect(red_url)
             return response.json(0, signature)
             return response.json(0, signature)
         except Exception as e:
         except Exception as e:
             if order_qs:
             if order_qs:
-                order_qs.update(status=10)
+                order_qs.update(status=10, promotion_rule_id=promotion_rule_id)
+            redisObj.del_data(key=orderID + 'do_notify')
             red_url = "{SERVER_DOMAIN_SSL}web/paid2/fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
             red_url = "{SERVER_DOMAIN_SSL}web/paid2/fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
             if lang != 'cn':
             if lang != 'cn':
                 red_url = "{SERVER_DOMAIN_SSL}web/paid2/en_fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
                 red_url = "{SERVER_DOMAIN_SSL}web/paid2/en_fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
@@ -817,6 +854,12 @@ class CloudStorageView(View):
         PayerID = request_dict.get('PayerID', None)
         PayerID = request_dict.get('PayerID', None)
         orderID = request_dict.get('orderID', None)
         orderID = request_dict.get('orderID', None)
         lang = request_dict.get('lang', 'en')
         lang = request_dict.get('lang', 'en')
+        # redis加锁,防止订单重复
+        redisObj = RedisObject()
+        isLock = redisObj.CONN.setnx(orderID + 'do_notify', 1)
+        redisObj.CONN.expire(orderID + 'do_notify', 60)
+        if not isLock:
+            return response.json(5)
         try:
         try:
             order_qs = Order_Model.objects.filter(orderID=orderID, status=0)
             order_qs = Order_Model.objects.filter(orderID=orderID, status=0)
 
 
@@ -837,6 +880,7 @@ class CloudStorageView(View):
                 red_url = "{SERVER_DOMAIN_SSL}web/paid2/fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
                 red_url = "{SERVER_DOMAIN_SSL}web/paid2/fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
                 if lang != 'cn':
                 if lang != 'cn':
                     red_url = "{SERVER_DOMAIN_SSL}web/paid2/en_fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
                     red_url = "{SERVER_DOMAIN_SSL}web/paid2/en_fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
+                redisObj.del_data(key=orderID + 'do_notify')
                 return HttpResponseRedirect(red_url)
                 return HttpResponseRedirect(red_url)
             print("Payment execute successfully")
             print("Payment execute successfully")
 
 
@@ -861,6 +905,14 @@ class CloudStorageView(View):
 
 
             if order_list[0]['isSelectDiscounts'] == 1:
             if order_list[0]['isSelectDiscounts'] == 1:
                 expire = smqs[0]['expire'] * 2
                 expire = smqs[0]['expire'] * 2
+            # 是否有促销
+            nowTime = int(time.time())
+            promotion = PromotionRuleModel.objects.filter(status=1, startTime__lte=nowTime,
+                                                          endTime__gte=nowTime).values('id','ruleConfig')
+            promotion_rule_id = ''
+            if promotion.exists():
+                promotion_rule_id = promotion[0]['id']
+                expire = expire * 2
             with transaction.atomic():
             with transaction.atomic():
                 if ubqs.exists():
                 if ubqs.exists():
                     ubq = ubqs[0]
                     ubq = ubqs[0]
@@ -872,6 +924,8 @@ class CloudStorageView(View):
                     else:     #已过期或者不相同的套餐加入未使用的关联套餐表
                     else:     #已过期或者不相同的套餐加入未使用的关联套餐表
                         has_unused = Unused_Uid_Meal.objects.filter(uid=UID, bucket_id=bucketId).values("id")
                         has_unused = Unused_Uid_Meal.objects.filter(uid=UID, bucket_id=bucketId).values("id")
                         nums = 2 if order_list[0]['isSelectDiscounts'] == 1 else 1
                         nums = 2 if order_list[0]['isSelectDiscounts'] == 1 else 1
+                        if promotion.exists():
+                            nums = nums + 1
                         if has_unused.exists():
                         if has_unused.exists():
                             Unused_Uid_Meal.objects.filter(id=has_unused[0]['id']).update(num=F('num') + nums)
                             Unused_Uid_Meal.objects.filter(id=has_unused[0]['id']).update(num=F('num') + nums)
                         else:
                         else:
@@ -902,7 +956,7 @@ class CloudStorageView(View):
                 #     }
                 #     }
                 #     UIDMainUser.objects.create(**uid_main_dict)
                 #     UIDMainUser.objects.create(**uid_main_dict)
 
 
-                order_qs.update(status=1, updTime=nowTime, uid_bucket_id=uid_bucket_id)
+                order_qs.update(status=1, updTime=nowTime, uid_bucket_id=uid_bucket_id, promotion_rule_id=promotion_rule_id)
                 datetime = time.strftime("%Y-%m-%d", time.localtime())
                 datetime = time.strftime("%Y-%m-%d", time.localtime())
                 sys_msg_text_list = ['温馨提示:尊敬的客户,您的' + UID + '设备在' + datetime + '已成功购买云存套餐',
                 sys_msg_text_list = ['温馨提示:尊敬的客户,您的' + UID + '设备在' + datetime + '已成功购买云存套餐',
                                      'Dear customer,you already subscribed the cloud storage package successfully for device ' + UID + ' on ' + time.strftime(
                                      'Dear customer,you already subscribed the cloud storage package successfully for device ' + UID + ' on ' + time.strftime(
@@ -914,15 +968,16 @@ class CloudStorageView(View):
                 red_url = "{SERVER_DOMAIN_SSL}web/paid2/success.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
                 red_url = "{SERVER_DOMAIN_SSL}web/paid2/success.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
                 if lang != 'cn':
                 if lang != 'cn':
                     red_url = "{SERVER_DOMAIN_SSL}web/paid2/en_success.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
                     red_url = "{SERVER_DOMAIN_SSL}web/paid2/en_success.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
-
+                redisObj.del_data(key=orderID + 'do_notify')
                 return HttpResponseRedirect(red_url)
                 return HttpResponseRedirect(red_url)
         except Exception as e:
         except Exception as e:
             print(repr(e))
             print(repr(e))
             if order_qs:
             if order_qs:
-                order_qs.update(status=10)
+                order_qs.update(status=10, promotion_rule_id=promotion_rule_id)
             red_url = "{SERVER_DOMAIN_SSL}web/paid2/fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
             red_url = "{SERVER_DOMAIN_SSL}web/paid2/fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
             if lang != 'cn':
             if lang != 'cn':
                 red_url = "{SERVER_DOMAIN_SSL}web/paid2/en_fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
                 red_url = "{SERVER_DOMAIN_SSL}web/paid2/en_fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
+            redisObj.del_data(key=orderID + 'do_notify')
             return HttpResponseRedirect(red_url)
             return HttpResponseRedirect(red_url)
 
 
     def do_pay_by_wechat_callback(self, request, response):  # 微信支付回调
     def do_pay_by_wechat_callback(self, request, response):  # 微信支付回调
@@ -938,17 +993,25 @@ class CloudStorageView(View):
             out_trade_no = data['out_trade_no']  # 商户订单号
             out_trade_no = data['out_trade_no']  # 商户订单号
             order_qs = Order_Model.objects.filter(orderID=out_trade_no, status=0)
             order_qs = Order_Model.objects.filter(orderID=out_trade_no, status=0)
             if trade_status == "SUCCESS":
             if trade_status == "SUCCESS":
-                logger.info('微信回调返回值 进来了。')
                 check_sign = pay.get_notifypay(data)
                 check_sign = pay.get_notifypay(data)
                 if not check_sign:
                 if not check_sign:
                     return HttpResponse(pay.xml_to_dict({'return_code': 'FAIL', 'return_msg': '签名失败'}))
                     return HttpResponse(pay.xml_to_dict({'return_code': 'FAIL', 'return_msg': '签名失败'}))
-                logger.info('签名成功')
                 orderID = out_trade_no
                 orderID = out_trade_no
-                print("进来了,微信支付成功回调")
+
+                #redis加锁,防止订单重复
+                redisObj = RedisObject()
+                isLock = redisObj.CONN.setnx(orderID + 'do_notify', 1)
+                redisObj.CONN.expire(orderID + 'do_notify', 60)
+                if not isLock:
+                    return response.json(5)
 
 
                 nowTime = int(time.time())
                 nowTime = int(time.time())
                 order_list = order_qs.values("UID", "channel", "commodity_code", "rank", "isSelectDiscounts",
                 order_list = order_qs.values("UID", "channel", "commodity_code", "rank", "isSelectDiscounts",
-                                             "userID__userID", "userID__username")
+                                             "userID__userID", "userID__username","status")
+
+                logger.info(order_list[0]['UID'])
+                logger.info(orderID)
+
                 userid = order_list[0]['userID__userID']
                 userid = order_list[0]['userID__userID']
                 username = order_list[0]['userID__username']
                 username = order_list[0]['userID__username']
                 UID = order_list[0]['UID']
                 UID = order_list[0]['UID']
@@ -965,6 +1028,13 @@ class CloudStorageView(View):
                 expire = smqs[0]['expire']
                 expire = smqs[0]['expire']
                 if order_list[0]['isSelectDiscounts'] == 1:
                 if order_list[0]['isSelectDiscounts'] == 1:
                     expire = smqs[0]['expire'] * 2
                     expire = smqs[0]['expire'] * 2
+                #是否有促销
+                nowTime = int(time.time())
+                promotion = PromotionRuleModel.objects.filter(status=1,startTime__lte=nowTime,endTime__gte=nowTime).values('id','ruleConfig')
+                promotion_rule_id = ''
+                if promotion.exists():
+                    promotion_rule_id = promotion[0]['id']
+                    expire = expire * 2
                 with transaction.atomic():
                 with transaction.atomic():
                     if ubqs.exists():
                     if ubqs.exists():
                         ubq = ubqs[0]
                         ubq = ubqs[0]
@@ -976,6 +1046,8 @@ class CloudStorageView(View):
                         else:     #已过期或者不相同的套餐加入未使用的关联套餐表
                         else:     #已过期或者不相同的套餐加入未使用的关联套餐表
                             has_unused = Unused_Uid_Meal.objects.filter(uid=UID, bucket_id=bucketId).values("id")
                             has_unused = Unused_Uid_Meal.objects.filter(uid=UID, bucket_id=bucketId).values("id")
                             nums = 2 if order_list[0]['isSelectDiscounts'] == 1 else 1
                             nums = 2 if order_list[0]['isSelectDiscounts'] == 1 else 1
+                            if promotion.exists():
+                                nums = nums + 1
                             if has_unused.exists():
                             if has_unused.exists():
                                 Unused_Uid_Meal.objects.filter(id=has_unused[0]['id']).update(num=F('num') + nums)
                                 Unused_Uid_Meal.objects.filter(id=has_unused[0]['id']).update(num=F('num') + nums)
                             else:
                             else:
@@ -1006,20 +1078,24 @@ class CloudStorageView(View):
                     #     }
                     #     }
                     #     UIDMainUser.objects.create(**uid_main_dict)
                     #     UIDMainUser.objects.create(**uid_main_dict)
 
 
-                    order_qs.update(status=1, updTime=nowTime, uid_bucket_id=uid_bucket_id)
+                    order_qs.update(status=1, updTime=nowTime, uid_bucket_id=uid_bucket_id, promotion_rule_id=promotion_rule_id)
                     datetime = time.strftime("%Y-%m-%d", time.localtime())
                     datetime = time.strftime("%Y-%m-%d", time.localtime())
                     sys_msg_text_list = ['温馨提示:尊敬的客户,您的' + UID + '设备在' + datetime + '已成功购买云存套餐',
                     sys_msg_text_list = ['温馨提示:尊敬的客户,您的' + UID + '设备在' + datetime + '已成功购买云存套餐',
                                          'Dear customer,you already subscribed the cloud storage package successfully for device ' + UID + ' on ' + time.strftime(
                                          'Dear customer,you already subscribed the cloud storage package successfully for device ' + UID + ' on ' + time.strftime(
                                              "%b %dth,%Y", time.localtime())]
                                              "%b %dth,%Y", time.localtime())]
-
                     self.do_vod_msg_Notice(UID, channel, userid, lang, sys_msg_text_list, 'SMS_219738485')
                     self.do_vod_msg_Notice(UID, channel, userid, lang, sys_msg_text_list, 'SMS_219738485')
-                    return HttpResponse(pay.xml_to_dict({'return_code': 'SUCCESS', 'return_msg': 'OK'}))
+                    redisObj.del_data(key=orderID + 'do_notify')
+                    return HttpResponse("<xml>\
+                      <return_code><![CDATA[SUCCESS]]></return_code>\
+                      <return_msg><![CDATA[OK]]></return_msg>\
+                    </xml>")
             else:
             else:
-                order_qs.update(status=10)
+                order_qs.update(status=10, promotion_rule_id=promotion_rule_id)
             return HttpResponse(pay.xml_to_dict({'return_code': 'FAIL', 'return_msg': '参数格式校验错误'}))
             return HttpResponse(pay.xml_to_dict({'return_code': 'FAIL', 'return_msg': '参数格式校验错误'}))
         except Exception as e:
         except Exception as e:
             if order_qs:
             if order_qs:
-                order_qs.update(status=10)
+                order_qs.update(status=10, promotion_rule_id=promotion_rule_id)
+            redisObj.del_data(key=orderID + 'do_notify')
             return HttpResponse(pay.xml_to_dict({'return_code': 'FAIL', 'return_msg': repr(e)}))
             return HttpResponse(pay.xml_to_dict({'return_code': 'FAIL', 'return_msg': repr(e)}))
 
 
     def do_create_pay_order(self, request_dict, userID, ip, response):  # 创建支付订单
     def do_create_pay_order(self, request_dict, userID, ip, response):  # 创建支付订单

+ 236 - 37
Controller/EquipmentManagerV3.py

@@ -50,6 +50,8 @@ class EquipmentManagerV3(View):
         # 手机端添加设备,查询,修改
         # 手机端添加设备,查询,修改
         if operation == 'add':
         if operation == 'add':
             return self.do_add(userID, request_dict, response, request)
             return self.do_add(userID, request_dict, response, request)
+        if operation == 'batchAdd':
+            return self.do_batch_add(userID, request_dict, response, request)
         elif operation == 'query':
         elif operation == 'query':
             return self.do_query(userID, request_dict, response)
             return self.do_query(userID, request_dict, response)
         elif operation == 'modify':
         elif operation == 'modify':
@@ -257,6 +259,213 @@ class EquipmentManagerV3(View):
                 }
                 }
             return response.json(0, res)
             return response.json(0, res)
 
 
+    def do_batch_add(self, userID, request_dict, response, request):
+        # 批量添加设备
+        uidContent = request_dict.get('uidContent', None)
+
+        if not uidContent:
+            return response.json(444, {'param': 'uidContent'})
+
+        try:
+            deviceNumber = 0            # 添加成功数量
+            add_success_flag = False    # 添加成功标识
+            exception_flag = False      # 异常标识
+            exists_flag = False         # 已存在标识
+            uid_content_list = eval(uidContent)
+            print('uidContent: ', uid_content_list)
+            re_uid = re.compile(r'^[A-Za-z0-9]{14,20}$')
+            for uid_content in uid_content_list:
+                exception_flag = False  # 重置异常标识
+                exists_flag = False     # 已存在标识
+                UID = uid_content['uid']
+                NickName = uid_content['nickName']
+                Type = uid_content['type']
+                ChannelIndex = uid_content['channelIndex']
+                version = uid_content['version']
+                isCheckMainUser = uid_content['isCheckMainUser']
+                View_Account = uid_content['viewAccount']
+                encryptPassword = uid_content['encryptPassword']
+                View_Password = self.decode_pwd(encryptPassword)
+                if not all([UID, NickName, View_Account]):  # Type和ChannelIndex可能为0
+                    return response.json(444, {'param': 'UID, NickName, View_Account'})
+
+                if not re_uid.match(UID):   # 检查uid长度
+                    return response.json(444, {'error uid length': UID})
+
+                device_info_qs = Device_Info.objects.filter(UID=UID, userID_id=userID)
+                if device_info_qs:
+                    # 判断设备是否已存在
+                    if device_info_qs[0].isExist == 1:
+                        exists_res = {UID: 'device already exists!'}
+                        exists_flag = True
+                        continue
+                    else:
+                        device_info_qs.delete()
+
+                id = 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
+                primaryUserID = ''
+                primaryMaster = ''
+                isShare = False
+
+                is_bind = Device_Info.objects.filter(UID=UID, isShare=False).values('userID__userID', 'primaryUserID', 'primaryMaster')
+
+                if main_exist.exists():
+                    vodPrimaryUserID = main_exist[0]['vodPrimaryUserID']
+                    vodPrimaryMaster = main_exist[0]['vodPrimaryMaster']
+
+                if is_bind.exists():
+                    primaryUserID = is_bind[0]['primaryUserID']
+                    primaryMaster = is_bind[0]['primaryMaster']
+                    isShare = True
+
+                isusermain = False
+                if (vodPrimaryUserID != userID and vodPrimaryUserID != '') or (primaryUserID != userID and primaryUserID != ''):
+                    isusermain = True
+
+                # 判断是否有已绑定用户
+                if isCheckMainUser == 1 and isusermain:
+                    res = {
+                        'id': id,
+                        'userID': userID,
+                        'NickName': NickName,
+                        'UID': UID,
+                        'View_Account': View_Account,
+                        'View_Password': View_Password,
+                        'ChannelIndex': ChannelIndex,
+                        'Type': Type,
+                        'isShare': isShare,
+                        'primaryUserID': primaryUserID,
+                        'primaryMaster': 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
+                    continue
+
+                # 判断是否有用户绑定
+                nowTime = int(time.time())
+                us_qs = UidSetModel.objects.filter(uid=UID)
+                if us_qs.exists():
+                    us_qs.update(nickname=NickName)
+                    UidSet_id = us_qs.first().id
+                else:
+                    ip = CommonService.get_ip_address(request)
+                    region_id = Device_Region().get_device_region(ip)
+                    region_alexa = 'CN' if region_id == 1 else 'ALL'
+                    uid_set_create_dict = {
+                        'uid': UID,
+                        'addTime': nowTime,
+                        'updTime': nowTime,
+                        'ip': CommonService.get_ip_address(request_dict),
+                        'channel': ChannelIndex,
+                        'nickname': NickName,
+                        'version': version,
+                        'region_alexa': region_alexa,
+                    }
+                    UidSet = UidSetModel.objects.create(**uid_set_create_dict)
+                    UidSet_id = UidSet.id
+
+                # 查询uid_channel表有无该uid的数据
+                uid_channel_set = UidChannelSetModel.objects.filter(uid_id=UidSet_id)
+                if not uid_channel_set.exists():
+                    # 多通道设备设置通道名
+                    multi_channel_list = [1, 2, 3, 4, 10001]
+                    if Type in multi_channel_list:
+                        UidChannelSet_bulk = []
+                        for i in range(1, ChannelIndex+1):
+                            channel_name = 'channel'+str(i)  # channel1,channel2...
+                            UidChannelSet = UidChannelSetModel(uid_id=UidSet_id, channel=i, channel_name=channel_name)
+                            UidChannelSet_bulk.append(UidChannelSet)
+                        UidChannelSetModel.objects.bulk_create(UidChannelSet_bulk)
+
+                userDevice = Device_Info(id=id, userID_id=userID, UID=UID, NickName=NickName, View_Account=View_Account,
+                                         View_Password=View_Password, Type=Type, ChannelIndex=ChannelIndex, version=version,
+                                         vodPrimaryUserID=vodPrimaryUserID, vodPrimaryMaster=vodPrimaryMaster)
+                userDevice.save()
+                uid_serial_qs = UIDCompanySerialModel.objects.filter(uid__uid=UID)
+                if uid_serial_qs.exists():
+                    uid_serial = uid_serial_qs[0]
+                    Device_Info.objects.filter(UID=UID).update(vodPrimaryUserID=vodPrimaryUserID,
+                                                               vodPrimaryMaster=vodPrimaryMaster,
+                                                               serial_number=uid_serial.company_serial.serial_number + uid_serial.company_serial.company.mark)
+                else:
+                    Device_Info.objects.filter(UID=UID).update(vodPrimaryUserID=vodPrimaryUserID,
+                                                               vodPrimaryMaster=vodPrimaryMaster)
+
+                if not us_qs.exists():
+                    us_qs = UidSetModel.objects.filter(uid=UID)
+
+                if us_qs.exists() and us_qs[0].is_alexa == 1:
+                    if us_qs[0].channel > 1:
+                        data_list = []
+                        uid_channel_set_qs = UidChannelSetModel.objects.filter(uid_id=us_qs[0].id).\
+                            values('channel', 'channel_name')
+                        if uid_channel_set_qs.exists():
+                            # 多通道设备名为 UidChannelSetModel 的 channel_name
+                            for uid_channel_set in uid_channel_set_qs:
+                                data_list.append({'userID': userID, 'UID': UID, 'uid_nick': uid_channel_set['channel_name'],
+                                                  'channel': uid_channel_set['channel'], 'password': encryptPassword})
+                    else:
+                        data_list = [{'userID': userID, 'UID': UID, 'uid_nick': NickName, 'password': encryptPassword}]
+
+                    # 请求Alexa服务器更新事件网关
+                    data_list = json.dumps(data_list)
+                    data = {'data_list': data_list}
+                    url = 'https://www.zositech.xyz/deviceStatus/addOrUpdateV2'
+                    requests.post(url, data=data, timeout=2)
+                dvqs = Device_Info.objects.filter(id=id).values('id', 'userID', 'NickName', 'UID',
+                                                                'View_Account',
+                                                                'View_Password', 'ChannelIndex', 'Type',
+                                                                'isShare',
+                                                                'primaryUserID', 'primaryMaster',
+                                                                'vodPrimaryUserID', 'vodPrimaryMaster',
+                                                                'userID__userEmail',
+                                                                'data_joined', 'version',
+                                                                'isVod', 'isExist', 'isCameraOpenCloud', 'serial_number')
+                dvql = CommonService.qs_to_list(dvqs)
+                ubqs = UID_Bucket.objects.filter(uid=UID). \
+                    values('bucket__content', 'status', 'channel', 'endTime', 'uid')
+                success_res = dvql[0]
+                success_res['vod'] = list(ubqs)
+                iotqs = iotdeviceInfoModel.objects.filter(serial_number=dvql[0]['serial_number'])
+                if iotqs.exists():
+                    success_res['iot'] = {'endpoint': iotqs[0].endpoint, 'token_iot_number': iotqs[0].endpoint}
+                deviceNumber += 1
+                success_res['deviceNumber'] = deviceNumber
+                add_success_flag = True
+        except Exception as e:
+            print(e)
+            error_res = repr(e)
+            exception_flag = True
+            pass
+        finally:
+            if add_success_flag:    # 有一台添加成功则返回成功
+                return response.json(0, success_res)
+            if exists_flag:         # 全部设备已存在
+                return response.json(174, exists_res)
+            if exception_flag:
+                return response.json(500, error_res)
+            return response.json(0, res)
 
 
     def do_modify(self, userID, request_dict, response, request):
     def do_modify(self, userID, request_dict, response, request):
         token = request_dict.get('token', None)
         token = request_dict.get('token', None)
@@ -368,17 +577,12 @@ class EquipmentManagerV3(View):
                            'isCameraOpenCloud', 'serial_number')
                            'isCameraOpenCloud', 'serial_number')
         dvls = CommonService.qs_to_list(dvql)
         dvls = CommonService.qs_to_list(dvql)
         uid_list = []
         uid_list = []
-        serial_number_list = []
         for dvl in dvls:
         for dvl in dvls:
             if dvl['primaryUserID'] and dvl['id'] == dvl['primaryUserID']:
             if dvl['primaryUserID'] and dvl['id'] == dvl['primaryUserID']:
                 dvl['isPrimaryUser'] = 1
                 dvl['isPrimaryUser'] = 1
             else:
             else:
                 dvl['isPrimaryUser'] = 0
                 dvl['isPrimaryUser'] = 0
             uid_list.append(dvl['UID'])
             uid_list.append(dvl['UID'])
-            serial_number_list.append(dvl['serial_number'][0:6])
-
-        # 新增获取IOT证书内容
-        iotqs = iotdeviceInfoModel.objects.filter(serial_number__in=serial_number_list)
 
 
         ubqs = UID_Bucket.objects.filter(uid__in=uid_list). \
         ubqs = UID_Bucket.objects.filter(uid__in=uid_list). \
             values('bucket__content', 'status', 'channel', 'endTime', 'uid')
             values('bucket__content', 'status', 'channel', 'endTime', 'uid')
@@ -457,16 +661,18 @@ class EquipmentManagerV3(View):
             uv_dict[us['uid']]['channels'] = channels
             uv_dict[us['uid']]['channels'] = channels
 
 
         for p in dvls:
         for p in dvls:
-            # 新增IOT
+            # 获取iot_deviceInfo表的endpoint和token_iot_number
             p['iot'] = []
             p['iot'] = []
-            for iot in iotqs:
-                if p['serial_number'][0:6] == iot.serial_number:
-                    p['iot'].append(
-                        {
-                            'endpoint': iot.endpoint,
-                            'token_iot_number': iot.token_iot_number
-                        }
-                    )
+            if p['serial_number']:  # 存在序列号根据序列号查询
+                iotdeviceInfo_qs = iotdeviceInfoModel.objects.filter(serial_number=p['serial_number'][0:6])
+            else:   # 根据uid查询
+                iotdeviceInfo_qs = iotdeviceInfoModel.objects.filter(uid=p['UID'])
+            if iotdeviceInfo_qs.exists():
+                iotdeviceInfo = iotdeviceInfo_qs.values('endpoint', 'token_iot_number')
+                p['iot'].append({
+                    'endpoint': iotdeviceInfo[0]['endpoint'],
+                    'token_iot_number': iotdeviceInfo[0]['token_iot_number']
+                })
 
 
             p['vod'] = []
             p['vod'] = []
             for dm in ubqs:
             for dm in ubqs:
@@ -545,6 +751,7 @@ class EquipmentManagerV3(View):
                     item['View_Password'] = self.encrypt_pwd(item['View_Password'])
                     item['View_Password'] = self.encrypt_pwd(item['View_Password'])
                     data.append(item)
                     data.append(item)
                     return response.json(0, data)
                     return response.json(0, data)
+                return response.json(0, data)
         items = []
         items = []
         # print('缓存分页')
         # print('缓存分页')
         for index, item in enumerate(result):
         for index, item in enumerate(result):
@@ -579,13 +786,8 @@ class EquipmentManagerV3(View):
 
 
                 dvls = CommonService.qs_to_list(device_qs)
                 dvls = CommonService.qs_to_list(device_qs)
                 uid_list = []
                 uid_list = []
-                serial_number_list = []
                 for dvl in dvls:
                 for dvl in dvls:
                     uid_list.append(dvl['UID'])
                     uid_list.append(dvl['UID'])
-                    serial_number_list.append(dvl['serial_number'][0:6])
-
-                # 新增获取IOT证书内容
-                iotqs = iotdeviceInfoModel.objects.filter(serial_number__in=serial_number_list)
 
 
                 ubqs = UID_Bucket.objects.filter(uid__in=uid_list). \
                 ubqs = UID_Bucket.objects.filter(uid__in=uid_list). \
                     values('bucket__content', 'status', 'channel', 'endTime', 'uid')
                     values('bucket__content', 'status', 'channel', 'endTime', 'uid')
@@ -650,17 +852,19 @@ class EquipmentManagerV3(View):
                     uv_dict[us['uid']]['channels'] = channels
                     uv_dict[us['uid']]['channels'] = channels
 
 
                 for p in dvls:
                 for p in dvls:
-                    # 新增IOT
+                    # 获取iot_deviceInfo表的endpoint和token_iot_number
                     p['iot'] = []
                     p['iot'] = []
-                    for iot in iotqs:
-                        if p['serial_number'][0:6] == iot.serial_number:
-                            p['iot'].append(
-                                {
-                                    'endpoint': iot.endpoint,
-                                    'token_iot_number': iot.token_iot_number
-
-                                }
-                            )
+                    if p['serial_number']:  # 存在序列号根据序列号查询
+                        iotdeviceInfo_qs = iotdeviceInfoModel.objects.filter(serial_number=p['serial_number'][0:6])
+                    else:  # 根据uid查询
+                        iotdeviceInfo_qs = iotdeviceInfoModel.objects.filter(uid=p['UID'])
+                    if iotdeviceInfo_qs.exists():
+                        iotdeviceInfo = iotdeviceInfo_qs.values('endpoint', 'token_iot_number')
+                        p['iot'].append({
+                            'endpoint': iotdeviceInfo[0]['endpoint'],
+                            'token_iot_number': iotdeviceInfo[0]['token_iot_number']
+                        })
+
                     p['vod'] = []
                     p['vod'] = []
                     for dm in ubqs:
                     for dm in ubqs:
                         if p['UID'] == dm['uid']:
                         if p['UID'] == dm['uid']:
@@ -795,14 +999,9 @@ class EquipmentManagerV3(View):
         if not all([token, time_stamp]):
         if not all([token, time_stamp]):
             return response.json(444)
             return response.json(444)
 
 
-        token = int(CommonService.decode_data(token))
-        time_stamp = int(time_stamp)
-
-        now_time = int(time.time())
-        distance = now_time - time_stamp
-
-        if token != time_stamp or distance > 60000 or distance < -60000:  # 为了全球化时间控制在一天内
-            return response.json(404)
+        # 时间戳token校验
+        if not CommonService.check_time_stamp_token(token, time_stamp):
+            return response.json(13)
 
 
         dvq = Device_Info.objects.filter(UID=UID)
         dvq = Device_Info.objects.filter(UID=UID)
         dvq = dvq.filter(~Q(vodPrimaryUserID='')).values('vodPrimaryUserID')
         dvq = dvq.filter(~Q(vodPrimaryUserID='')).values('vodPrimaryUserID')

+ 9 - 109
Controller/IotCoreController.py

@@ -74,13 +74,9 @@ class IotCoreView(View):
         if not all([token, time_stamp, device_version, language]):
         if not all([token, time_stamp, device_version, language]):
             return response.json(444, {'param': 'token, uid_code, time_stamp, device_version, language'})
             return response.json(444, {'param': 'token, uid_code, time_stamp, device_version, language'})
 
 
-        # token时间戳校验
-        token = int(CommonService.decode_data(token))
-        time_stamp = int(time_stamp)
-        now_time = int(time.time())
-        distance = now_time - time_stamp
-        if token != time_stamp or distance > 60000 or distance < -60000:  # 为了全球化时间控制在一天内
-            return response.json(404)
+        # 时间戳token校验
+        if not CommonService.check_time_stamp_token(token, time_stamp):
+            return response.json(13)
 
 
         if not uid:
         if not uid:
             # 使用序列号
             # 使用序列号
@@ -120,7 +116,7 @@ class IotCoreView(View):
 
 
             iotClient = IOTClient(region_id)
             iotClient = IOTClient(region_id)
             res = iotClient.create_keys_and_certificate(ThingNameSuffix, thingGroup, response)
             res = iotClient.create_keys_and_certificate(ThingNameSuffix, thingGroup, response)
-            token_iot_number = hashlib.md5((str(uuid.uuid1()) + str(now_time)).encode('utf-8')).hexdigest()
+            token_iot_number = hashlib.md5((str(uuid.uuid1()) + str(int(time.time()))).encode('utf-8')).hexdigest()
 
 
             iotdeviceInfoModel.objects.create(uid=uid,
             iotdeviceInfoModel.objects.create(uid=uid,
                                               serial_number=serial,
                                               serial_number=serial,
@@ -164,13 +160,9 @@ class IotCoreView(View):
         if not all([token, language, time_stamp, device_version]):
         if not all([token, language, time_stamp, device_version]):
             return response.json(444, {'param: token, language, time_stamp, device_version'})
             return response.json(444, {'param: token, language, time_stamp, device_version'})
 
 
-        # 封装token认证
-        token = int(CommonService.decode_data(token))
-        time_stamp = int(time_stamp)
-        now_time = int(time.time())
-        distance = now_time - time_stamp
-        if token != time_stamp or distance > 60000 or distance < -60000:  # 为了全球化时间控制在一天内
-            return response.json(404)
+        # 时间戳token校验
+        if not CommonService.check_time_stamp_token(token, time_stamp):
+            return response.json(13)
 
 
         ip = CommonService.get_ip_address(request)
         ip = CommonService.get_ip_address(request)
         region_id = Device_Region().get_device_region(ip)
         region_id = Device_Region().get_device_region(ip)
@@ -242,7 +234,7 @@ class IotCoreView(View):
             return response.json(444)
             return response.json(444)
 
 
         try:
         try:
-            # 获取检查uid的序列号,如果没有序列号,不使用MQTT下发消息
+            # 获取设备的物品名后缀
             device_info_qs = Device_Info.objects.filter(UID=UID).values('UID', 'serial_number')
             device_info_qs = Device_Info.objects.filter(UID=UID).values('UID', 'serial_number')
             if not device_info_qs.exists():
             if not device_info_qs.exists():
                 return response.json(10043)
                 return response.json(10043)
@@ -268,60 +260,7 @@ class IotCoreView(View):
             # post请求url来发布MQTT消息
             # post请求url来发布MQTT消息
             url = 'https://{}/topics/{}'.format(endpoint, topic_name)
             url = 'https://{}/topics/{}'.format(endpoint, topic_name)
             authorizer_name = 'Ansjer_Iot_Auth'
             authorizer_name = 'Ansjer_Iot_Auth'
-            signature = self.rsa_sign(Token)  # Token签名
-            headers = {'x-amz-customauthorizer-name': authorizer_name, 'Token': Token,
-                       'x-amz-customauthorizer-signature': signature}
-            params = {'command': MSG}
-            r = requests.post(url=url, headers=headers, json=params, timeout=2)
-            if r.status_code == 200:
-                res = r.json()
-                if res['message'] == 'OK':
-                    return response.json(0)
-                return response.json(10044)
-            else:
-                # print('发布失败')
-                return response.json(10044)
-        except Exception as e:
-            # print(e)
-            return response.json(500, repr(e))
-
-    def request_publish_mqtt(self, request_dict, response, request):
-        # 通用发布主题通知
-        UID = request_dict.get('UID', None)
-        MSG = request_dict.get('MSG', None)
-        return_topic_name = request_dict.get('return_topic_name', None)
-        if not all([UID, MSG]):
-            return response.json(444)
-
-        try:
-            # 获取检查uid的序列号,如果没有序列号,不使用MQTT下发消息
-            device_info_qs = Device_Info.objects.filter(UID=UID).values('UID', 'serial_number')
-            if not device_info_qs.exists():
-                return response.json(10043)
-            uid = device_info_qs[0]['UID']
-            serial_number = device_info_qs[0]['serial_number']
-            # 如果device_info表的serial_number不为空,物品名为'Ansjer_Device_序列号'
-            thing_name_suffix = serial_number if serial_number != '' else uid
-            # 获取数据组织将要请求的url
-            iot = iotdeviceInfoModel.objects.filter(thing_name__contains=thing_name_suffix).values('thing_name',
-                                                                                                   'endpoint',
-                                                                                                   'token_iot_number')
-            if not iot.exists():
-                return response.json(10043)
-            thing_name = iot[0]['thing_name'][14:]  # IoT core上的物品名: Ansjer_Device_ + 序列号+企业编码/uid
-            endpoint = iot[0]['endpoint']
-            Token = iot[0]['token_iot_number']
-            # Token = '297a601b3925e04daab5a60280650e09'
-            topic_name = thing_name + return_topic_name     # MQTT主题
-            if return_topic_name == 'get_s3_key_return':
-                MSG = self.get_s3_key_return_msg(endpoint)
-
-            # api doc: https://docs.aws.amazon.com/zh_cn/iot/latest/developerguide/http.html
-            # url: https://IoT_data_endpoint/topics/url_encoded_topic_name?qos=1
-            # post请求url来发布MQTT消息
-            url = 'https://{}/topics/{}'.format(endpoint, topic_name)
-            authorizer_name = 'Ansjer_Iot_Auth'
-            signature = self.rsa_sign(Token)  # Token签名
+            signature = CommonService.rsa_sign(Token)  # Token签名
             headers = {'x-amz-customauthorizer-name': authorizer_name, 'Token': Token,
             headers = {'x-amz-customauthorizer-name': authorizer_name, 'Token': Token,
                        'x-amz-customauthorizer-signature': signature}
                        'x-amz-customauthorizer-signature': signature}
             params = {'command': MSG}
             params = {'command': MSG}
@@ -391,42 +330,3 @@ class IotCoreView(View):
         MSG['arn'] = arn
         MSG['arn'] = arn
         MSG['region_name'] = region_name
         MSG['region_name'] = region_name
         return MSG
         return MSG
-
-
-    def rsa_sign(self, Token):
-        # 私钥签名Token
-        private_key_file = '''-----BEGIN RSA PRIVATE KEY-----
-MIIEpQIBAAKCAQEA5iJzEDPqtGmFMggekVro6C0lrjuC2BjunGkrFNJWpDYzxCzE
-X5jf4/Fq7hcIaQd5sqHugDxPVollSLPe9zNilbrd0sZfU+Ed8gRVuKW9KwfE9XFr
-L0pt6bKRQ0IIRfiZ9TuR0tsQysvcO1GZSXcYfPue3tGM1zOnWFThWDqZ06+sOxzt
-RMRl4yNfbpCG4MfxG3itNXOfrjZv2OMLSXrxmzubSvRpUYSvQPs4fm9302SAnySY
-0MKzx6H6528ZQm/IDDSZy6EmNBIyTRDfxC56vnYcXvqedAQh7jJnjdvt6Q4MhASH
-eIYi1FBSdu2NT6wgpnrqXzx5pq9kR/lnsLID0wIDAQABAoIBAQCiF4GT1/1oNSpr
-ouxk1PNXFPWFUsVGD8mAwVJmx//eiY7MjfuCmdqYYmI+cFqsH2fIOeYSzGfVO9Dq
-9EYHN1oovAWhf7eFDPpajFMUSyiCNmazub8VAAeKowtNpCTPo9pMsDh1m3aoYA4u
-ebrN0+Sbo16y8kWRDgDAZoiR7DSMs8lczk16hwfv5mw8XpNDbaL3Coi4Koe2S1Yh
-2SX3vWFlpd7qF1ZYXuZIp+b8JPrV7n9eUKoFgzj0gqgwQK80CoexIjiOrNMPvkQa
-q+8kCvFjAzKxOK7e8gjM8lMRiGodb61kmYZkkJzFwWO4EaGbl34lfVECd1Ixp3tF
-be0OWAGBAoGBAPSteXDzzToD8ovM7LL11x0jWwI6HOiHu89kZtW566rIezjWBuA2
-TxrcYKM3h9jQRXS3CsMdoIv6XGk5lqM8ADtjn23FBWe/THYLh8bm8JOgh5RRWQDg
-SvkLfi9Ih2mM4NJfmuuDOh3Nze2efLM7+kOZWUQwF2Zx9mL5jvRBk351AoGBAPDI
-sYmT2Li+i5+0vykA2m5uPF8ZOW8BGtAfCZv0suW7BNzSgin78g9WapRd/4p0NNiL
-/nVMqPPCpd1akCUpV+GDWQt0hV+HZjxANE0KWhciQRyo2qvo51j8SWILJSgh0tXC
-aTF8qt6oGw3VN3m57vKhbrlDaz0J/NDJFci6msAnAoGBAOuG6bXPGijUj+//DYKf
-n7jOxdZ49kboEePrtAncdHzri6IEdI3z+WXT6bpzw/LzWUimwldb96WHFNm9s8Hi
-Ch8hIODbnP5naUTgiIzw1XhmONyPCewL/F+LrqX5XVA/alNX8JrwsUrrR2WLAGLQ
-Q3I69XDsEjptTU2tCO0bCs3ZAoGBAJ2lCHfm0JHET230zONvp5N9oREyVqQSuRdh
-+syc3TQDyh85w/bw+X6JOaaCFHj1tFPC9Iqf8k4GNspCLPXnp54CfR4+38O3xnvU
-HWoDSRC0YKT++IxtJGriYrlKSr2Hx54kdvLriIPW1D+uRW/xCDza7L9nIKMKEvgv
-b4/IfOEpAoGAeKM9Te7T1VzlAkS0CJOwanzwYV/zrex84WuXxlsGgPQ871lTs5AP
-H1QLfLfFXH+UVrCEC2yv4eml/cqFkpB3gE5i4MQ8GPVIOSs5tsIyl8YUA03vdNdB
-GCqvlyw5dfxNA+EtxNE2wCW/LW7ENJlACgcfgPlBZtpLheWoZB/maw4=
------END RSA PRIVATE KEY-----'''
-        # 使用密钥文件方式
-        # private_key_file_path = os.path.join(BASE_DIR, 'static/iotCore/private.pem')#.replace('\\', '/')
-        # private_key_file = open(private_key_file_path, 'r')
-        private_key = ct.load_privatekey(ct.FILETYPE_PEM, private_key_file)
-        signature = ct.sign(private_key, Token.encode('utf8'), 'sha256')
-        signature = encodebytes(signature).decode('utf8').replace('\n', '')
-        # print('signature:', signature)
-        return signature

+ 20 - 61
Controller/SerialNumberController.py

@@ -132,25 +132,21 @@ class SerialNumberView(View):
         company_id = request_dict.get('company_id', None)
         company_id = request_dict.get('company_id', None)
         token = request_dict.get('token', None)
         token = request_dict.get('token', None)
         time_stamp = request_dict.get('time_stamp', None)
         time_stamp = request_dict.get('time_stamp', None)
-        DeviceSubType = request_dict.get('DeviceSubType', None)
-        p2ptype = request_dict.get('p2ptype', 1)
+        p2p_type = request_dict.get('p2ptype', 1)
+
         if not all([serial_number, company_id, token, time_stamp]):
         if not all([serial_number, company_id, token, time_stamp]):
             return response.json(444)
             return response.json(444)
 
 
-        token = int(CommonService.decode_data(token))
-        time_stamp = int(time_stamp)
+        # 时间戳token校验
+        if not CommonService.check_time_stamp_token(token, time_stamp):
+            return response.json(13)
 
 
         now_time = int(time.time())
         now_time = int(time.time())
-        distance = now_time - time_stamp
-
-        if token != time_stamp or distance > 60000 or distance < -60000:  # 为了全球化时间控制在一天内
-            return response.json(404)
-
         serial = serial_number[0:6]
         serial = serial_number[0:6]
         full_serial = serial_number[0:9]
         full_serial = serial_number[0:9]
 
 
         if serial_number[9:10]:
         if serial_number[9:10]:
-            p2ptype = serial_number[9:10]
+            p2p_type = serial_number[9:10]
         try:
         try:
             if not country_id:
             if not country_id:
                 ip = CommonService.get_ip_address(request)
                 ip = CommonService.get_ip_address(request)
@@ -172,44 +168,18 @@ class SerialNumberView(View):
                     while count < 3:
                     while count < 3:
                         # 查询是否存在未绑定序列号的uid
                         # 查询是否存在未绑定序列号的uid
                         uid_qs = UIDModel.objects.filter(vpg__company_id=company_serial.company.id,
                         uid_qs = UIDModel.objects.filter(vpg__company_id=company_serial.company.id,
-                                                         vpg__region_id=country_id, status=0, p2p_type=p2ptype). \
+                                                         vpg__region_id=country_id, status=0, p2p_type=p2p_type). \
                                                          order_by('id')
                                                          order_by('id')
                         if not uid_qs.exists():
                         if not uid_qs.exists():
                             return response.json(173)
                             return response.json(173)
 
 
                         uid = uid_qs[0]
                         uid = uid_qs[0]
+                        # 判断uid是否已绑定过序列号
+                        uid_company_serial_qs = UIDCompanySerialModel.objects.filter(uid_id=uid.id)
+                        if uid_company_serial_qs.exists():
+                            return response.json(174)
 
 
-                        if DeviceSubType:
-                            # 获取最新的mac,判断分配到哪里,且进行绑定
-                            mac = MacModel.objects.filter().values('id', 'value', 'is_active')[0]
-                            current_mac = mac['value']
-                            username = 'cspublic@ansjer.com'
-                            if current_mac[-8:] == '1F:42:40':  # 一组一共1048576个,此mac是第100w个时
-                                sys_msg_text = "当前国外uid管理系统mac地址已分配到" + current_mac + ",此mac地址是当前组的第100w个,还剩下48576个可分配,mac地址即将用完。"
-                                S3Email().faEmail(sys_msg_text, username)
-                            elif current_mac[-8:] == '1F:90:60':  # 此mac是第102w个时
-                                sys_msg_text = "当前国外uid管理系统mac地址已分配到" + current_mac + ",此mac地址是当前组的第102w个,还剩下28576个可分配,mac地址即将用完。"
-                                S3Email().faEmail(sys_msg_text, username)
-                            elif not mac['is_active']:
-                                return response.json(175)
-                            elif current_mac[-8:] == '1F:FF:FF':
-                                MacModel.objects.filter().update(is_active=False)  # 更改mac可使用的状态,当再此调用接口时使用上面条件进行阻止
-                                sys_msg_text = "当前国外uid管理系统mac地址已分配到" + current_mac + ",mac地址已分配使用完,请更换分组。"
-                                S3Email().faEmail(sys_msg_text, username)
-                                return response.json(175)
-                            UIDModel.objects.filter(id=uid.id).update(mac=current_mac)  # 更新绑定uid的mac值
-                            # 绑定mac地址成功后更新mac表
-                            temp_mac = CommonService.updateMac(current_mac)  # mac地址值+1;后3个字节为FF时返回None
-                            if temp_mac:
-                                current_mac = temp_mac  # 更新赋值写入uid表
-                            else:
-                                temp_mac = current_mac  # 赋值为FF写入mac表
-                            MacModel.objects.filter().update(value=temp_mac, add_time=now_time,
-                                                             update_time=now_time)  # 更新mac表的mac地址值
-
-                        result = UIDModel.objects.filter(id=uid.id, status=0).\
-                            update(status=2, update_time=now_time)
-
+                        result = UIDModel.objects.filter(id=uid.id, status=0).update(status=2, update_time=now_time)
                         if int(result) <= 0:    # 更新失败
                         if int(result) <= 0:    # 更新失败
                             count += 1
                             count += 1
                             continue
                             continue
@@ -232,7 +202,6 @@ class SerialNumberView(View):
                         res = {
                         res = {
                             'full_uid_code': CommonService.encode_data(full_uid_code),
                             'full_uid_code': CommonService.encode_data(full_uid_code),
                             'uid': CommonService.encode_data(uid.uid),
                             'uid': CommonService.encode_data(uid.uid),
-                            'mac': CommonService.encode_data(uid.mac),
                             'extra': uid.uid_extra,
                             'extra': uid.uid_extra,
                             'platform': uid.platform,
                             'platform': uid.platform,
                             'initString': uid.init_string,
                             'initString': uid.init_string,
@@ -267,7 +236,6 @@ class SerialNumberView(View):
                 res = {
                 res = {
                     'full_uid_code': CommonService.encode_data(full_uid_code),
                     'full_uid_code': CommonService.encode_data(full_uid_code),
                     'uid': CommonService.encode_data(uid['uid__uid']),
                     'uid': CommonService.encode_data(uid['uid__uid']),
-                    'mac': CommonService.encode_data(uid['uid__mac']),
                     'extra': uid['uid__uid_extra'],
                     'extra': uid['uid__uid_extra'],
                     'platform': uid['uid__platform'],
                     'platform': uid['uid__platform'],
                     'initString': uid['uid__init_string'],
                     'initString': uid['uid__init_string'],
@@ -284,16 +252,10 @@ class SerialNumberView(View):
         token = request_dict.get('token', None)
         token = request_dict.get('token', None)
         time_stamp = request_dict.get('time_stamp', None)
         time_stamp = request_dict.get('time_stamp', None)
 
 
-        if token and time_stamp and serial_number :
-
-            token = int(CommonService.decode_data(token))
-            time_stamp = int(time_stamp)
-
-            now_time = int(time.time())
-            distance = now_time - time_stamp
-
-            if token != time_stamp or distance > 60000 or distance < -60000:  # 为了全球化时间控制在一天内
-                return response.json(404)
+        if token and time_stamp and serial_number:
+            # 时间戳token校验
+            if not CommonService.check_time_stamp_token(token, time_stamp):
+                return response.json(13)
 
 
             mark = serial_number[6:9]
             mark = serial_number[6:9]
             serial = serial_number[0:6]
             serial = serial_number[0:6]
@@ -321,15 +283,12 @@ class SerialNumberView(View):
 
 
         if not all([token, time_stamp, serial_number]):
         if not all([token, time_stamp, serial_number]):
             return response.json(444)
             return response.json(444)
-        token = int(CommonService.decode_data(token))
-        time_stamp = int(time_stamp)
 
 
-        now_time = int(time.time())
-        distance = now_time - time_stamp
-
-        if token != time_stamp or distance > 60000 or distance < -60000:  # 为了全球化时间控制在一天内
-            return response.json(404)
+        # 时间戳token校验
+        if not CommonService.check_time_stamp_token(token, time_stamp):
+            return response.json(13)
 
 
+        now_time = int(time.time())
         serial = serial_number[0:6]
         serial = serial_number[0:6]
         uid_serial_qs = UIDCompanySerialModel.objects.filter(company_serial__serial_number=serial)
         uid_serial_qs = UIDCompanySerialModel.objects.filter(company_serial__serial_number=serial)
         if not uid_serial_qs.exists():
         if not uid_serial_qs.exists():

+ 4 - 2
Controller/SysManage.py

@@ -12,6 +12,7 @@
 @Contact: chanjunkai@163.com
 @Contact: chanjunkai@163.com
 """
 """
 import os
 import os
+import time
 
 
 from django.http import HttpResponse
 from django.http import HttpResponse
 from django.views.decorators.csrf import csrf_exempt
 from django.views.decorators.csrf import csrf_exempt
@@ -103,9 +104,10 @@ def initMsgFunc(request):
     response.lang = tko.lang
     response.lang = tko.lang
     if tko.code == 0:
     if tko.code == 0:
         userID = tko.userID
         userID = tko.userID
+        seven_days_ago = int(time.time()) - 3600 * 24 * 7   # 过滤七天前数据
         sm_count = SysMsgModel.objects.filter(userID_id=userID, status=0).count()
         sm_count = SysMsgModel.objects.filter(userID_id=userID, status=0).count()
-        eq_count = Equipment_Info.objects.filter(userID_id=userID).filter(status=False).count()
-        rq_count = Equipment_Info.objects.filter(userID_id=userID).filter(eventType=57, status=False,).count()
+        eq_count = Equipment_Info.objects.filter(userID_id=userID, eventTime__gt=seven_days_ago, status=False).count()
+        rq_count = Equipment_Info.objects.filter(userID_id=userID, eventTime__gt=seven_days_ago, eventType=57, status=False,).count()
         uid_reset_count = Device_Info.objects.filter(userID_id=userID, isExist=2).count()
         uid_reset_count = Device_Info.objects.filter(userID_id=userID, isExist=2).count()
         res = {
         res = {
             'sm_count': sm_count,  # 系统消息未读数量
             'sm_count': sm_count,  # 系统消息未读数量

+ 17 - 42
Controller/VPGController.py

@@ -196,9 +196,6 @@ class VPGView(View):
 @csrf_exempt
 @csrf_exempt
 def do_upload_uid(request):
 def do_upload_uid(request):
     # 上传UID,需要request.FILES,单独提取出来
     # 上传UID,需要request.FILES,单独提取出来
-    # perm = ModelService.check_perm_uid_manage(userID, 0)
-    # if not perm:
-    #     return response.json(309)
 
 
     request.encoding = 'utf-8'
     request.encoding = 'utf-8'
     response = uidManageResponseObject()
     response = uidManageResponseObject()
@@ -210,33 +207,24 @@ def do_upload_uid(request):
         return response.json(444)
         return response.json(444)
     file = request.FILES.get('file', None)
     file = request.FILES.get('file', None)
     vpg_id = request_dict.get('vpg_id', None)
     vpg_id = request_dict.get('vpg_id', None)
+    p2p_type = request_dict.get('p2p_type', None)
     platform = request_dict.get('platform', '')
     platform = request_dict.get('platform', '')
     init_string = request_dict.get('init_string', '')
     init_string = request_dict.get('init_string', '')
     init_string_app = request_dict.get('init_string_app', '')
     init_string_app = request_dict.get('init_string_app', '')
 
 
-    if not vpg_id:
+    if not all([vpg_id, p2p_type]):
         return response.json(444)
         return response.json(444)
 
 
-    bulk = []
-    add_time = update_time = int(time.time())
-    # MAC = MacModel.objects.filter().values('id', 'value', 'is_active')[0]   # 获取最新可用的mac
-    # current_mac = MAC['value']
-    # if (not MAC['is_active']) or (current_mac[-8:] == 'FF.FF.FF'):
-    #     return response.json(175)
-
-    area = 1 if vpg_id != '1' else 0
-    # path = '/'.join((BASE_DIR, 'static/uid')).replace('\\', '/') + '/'
-    # if not os.path.exists(path):
-    #     os.makedirs(path)
-    # full_path = path + str(file)
-    # with open(full_path, 'wb+') as uid_file:
     try:
     try:
+        bulk = []
+        p2p_type = int(p2p_type)
+        # 尚云必须输入平台和初始化字符
+        if p2p_type == 1 and (not platform or not platform or not init_string_app):
+            return response.json(444)
+        p2p = '尚云' if p2p_type == 1 else 'tutk'
+        area = 1 if vpg_id != '1' else 0    # vpg_id为'1':国内
+        add_time = update_time = int(time.time())
         for chunk in file.chunks():
         for chunk in file.chunks():
-            # str_chunk = str(chunk)
-            # print('str(chunk):', str_chunk)
-            # str_chunk = re.findall("b\'(.*)\'", str_chunk)[0]
-            # str_chunk = str_chunk.split('\\r\\n')
-            # print('str(chunk):', str_chunk)
             uid_list = re.findall("b\'(.*)\'", str(chunk))[0].split('\\r\\n')
             uid_list = re.findall("b\'(.*)\'", str(chunk))[0].split('\\r\\n')
             for uid in uid_list:
             for uid in uid_list:
                 UID = UIDModel(
                 UID = UIDModel(
@@ -247,29 +235,17 @@ def do_upload_uid(request):
                     update_time=update_time,
                     update_time=update_time,
                     area=area,  # 关联vgp表已有区域信息,可以考虑去掉
                     area=area,  # 关联vgp表已有区域信息,可以考虑去掉
                     vpg_id=vpg_id,
                     vpg_id=vpg_id,
+                    p2p_type=p2p_type,
                     platform=platform,
                     platform=platform,
                     init_string=init_string,
                     init_string=init_string,
                     init_string_app=init_string_app
                     init_string_app=init_string_app
                 )
                 )
-                if len(uid) == 14:  # 宸云
-                    UID.p2p_type = 1
-                    UID.uid = uid
-                elif len(uid) == 20:    # tutk
-                    UID.p2p_type = 2
-                    UID.uid = uid
-                elif len(uid) == 23:    # 宸云完整uid
-                    a = uid.split('-')
-                    new_uid = a[0] + a[1] + a[2].split(',')[0]
-                    UID.p2p_type = 1
-                    UID.uid = new_uid
+                if '-' in uid:  # 尚云完整uid,eg.ACN-000005-FHCGR,VRWEDU -> ACN000005FHCGR
                     UID.full_uid_code = uid
                     UID.full_uid_code = uid
+                    uid_split = uid.split('-')
+                    uid = uid_split[0] + uid_split[1] + uid_split[2].split(',')[0]
+                UID.uid = uid
                 bulk.append(UID)
                 bulk.append(UID)
-                # temp_mac = CommonService.updateMac(current_mac)    # mac地址值+1;后3个字节为FF时返回None
-                # if temp_mac:
-                #     current_mac = temp_mac  # 更新赋值写入uid表
-                # else:
-                #     temp_mac = current_mac  # 赋值为FF写入mac表
-                #     break
 
 
         ip = CommonService.get_ip_address(request)
         ip = CommonService.get_ip_address(request)
         content = json.loads(json.dumps(request_dict))
         content = json.loads(json.dumps(request_dict))
@@ -280,7 +256,7 @@ def do_upload_uid(request):
             'time': add_time,
             'time': add_time,
             'url': 'vpgUid/uid',
             'url': 'vpgUid/uid',
             'content': json.dumps(content),
             'content': json.dumps(content),
-            'operation': '上传{}个uid到VPG ID {}'.format(len(uid_list), vpg_id),
+            'operation': '上传{}个{}uid到VPG ID {}'.format(len(uid_list), p2p, vpg_id),
         }
         }
         
         
         with transaction.atomic():
         with transaction.atomic():
@@ -288,8 +264,7 @@ def do_upload_uid(request):
             UIDModel.objects.bulk_create(bulk)  # 批量写入uid数据
             UIDModel.objects.bulk_create(bulk)  # 批量写入uid数据
             uid_count = UIDModel.objects.filter(vpg_id=vpg_id).count()  # 获取族群下uid的数量
             uid_count = UIDModel.objects.filter(vpg_id=vpg_id).count()  # 获取族群下uid的数量
             VPGModel.objects.filter(id=vpg_id).update(uid_count=uid_count)   # 更新vgp表的uid_count
             VPGModel.objects.filter(id=vpg_id).update(uid_count=uid_count)   # 更新vgp表的uid_count
-            # MacModel.objects.filter().update(value=temp_mac)  # 更新mac表的mac地址值
         return response.json(0)
         return response.json(0)
     except Exception as e:
     except Exception as e:
         print(e)
         print(e)
-        return response.json(500, repr(e))
+        return response.json(500, repr(e))

+ 42 - 3
Model/models.py

@@ -622,6 +622,7 @@ class Order_Model(models.Model):
     commodity_code = models.CharField(default='', max_length=32, verbose_name='套餐规格码')
     commodity_code = models.CharField(default='', max_length=32, verbose_name='套餐规格码')
     pay_url = models.CharField(max_length=2000, 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')
     paypal = models.CharField(max_length=500, null=True, blank=True, verbose_name='支付批准url')
+    promotion_rule_id = models.CharField(blank=True, max_length=64, default='', verbose_name='促销id')
 
 
     # 备用字段
     # 备用字段
     spare_1 = models.CharField(default='', blank=True, max_length=64, verbose_name=u'备用字段1')
     spare_1 = models.CharField(default='', blank=True, max_length=64, verbose_name=u'备用字段1')
@@ -638,6 +639,27 @@ class Order_Model(models.Model):
         verbose_name_plural = verbose_name
         verbose_name_plural = verbose_name
         ordering = ('-orderID',)
         ordering = ('-orderID',)
 
 
+class PromotionRuleModel(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name='主键')
+    ruleName = models.TextField(default='', verbose_name='规则名字')                     #json格式, 例: {"cn":"黑色星期五","en":"Black Friday"}
+    ruleDesc = models.TextField(default='', verbose_name='规则描述')                     #json格式,   例:  {"cn":"买一送一","en":"buy one get one free"}
+    ruleConfig = models.CharField(max_length=2000, default='', verbose_name='规则配置')  #json格式, 例: {"buy": 1, "get": 1}
+    startTime = models.IntegerField(verbose_name='促销活动开始时间', default=0)
+    endTime = models.IntegerField(verbose_name='促销活动结束时间', default=0)
+    status = models.SmallIntegerField(default=0, verbose_name='活动状态:0未进行;1进行中')
+    remark = models.CharField(max_length=50, default='', verbose_name='备注')
+    popups = models.CharField(max_length=2000, default='', verbose_name='app弹窗消息')   #json格式 ,例: {"cn":"买一送一","en":"buy one get one free"}
+
+    def __str__(self):
+        return self.id
+
+    class Meta:
+        db_table = 'promotion_rule'
+        verbose_name = u'促销规则表'
+        verbose_name_plural = verbose_name
+        ordering = ('-id',)
+
+
 
 
 class VodHlsModel(models.Model):
 class VodHlsModel(models.Model):
     id = models.AutoField(primary_key=True, verbose_name='回放列表主键')
     id = models.AutoField(primary_key=True, verbose_name='回放列表主键')
@@ -1116,7 +1138,7 @@ class AppLogModel(models.Model):
     user = models.ForeignKey(Device_User, to_field='userID', on_delete=models.CASCADE, verbose_name='关联设备用户表')
     user = models.ForeignKey(Device_User, to_field='userID', on_delete=models.CASCADE, verbose_name='关联设备用户表')
     uid = models.CharField(max_length=20, default='', verbose_name='设备uid')
     uid = models.CharField(max_length=20, default='', verbose_name='设备uid')
     average_delay = models.CharField(max_length=32, default='', verbose_name='最高平均延时')
     average_delay = models.CharField(max_length=32, default='', verbose_name='最高平均延时')
-    status = models.SmallIntegerField(default=0, verbose_name='失败状态')
+    status = models.SmallIntegerField(default=0, verbose_name='失败状态')   # 0: 成功,1: 失败
     filename = models.CharField(max_length=120, default='', verbose_name='文件名')
     filename = models.CharField(max_length=120, default='', verbose_name='文件名')
     add_time = models.IntegerField(default=0, verbose_name='日期')
     add_time = models.IntegerField(default=0, verbose_name='日期')
 
 
@@ -1126,6 +1148,20 @@ class AppLogModel(models.Model):
         verbose_name_plural = verbose_name
         verbose_name_plural = verbose_name
 
 
 
 
+class DeviceLogModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    ip = models.CharField(default='', max_length=32, verbose_name='ip')
+    uid = models.CharField(max_length=32, default='', verbose_name='设备uid')
+    status = models.SmallIntegerField(default=0, verbose_name='上传状态')   # 0: 成功,1: 失败
+    filename = models.CharField(max_length=120, default='', verbose_name='文件名')
+    add_time = models.DateTimeField(blank=True, auto_now_add=True, verbose_name=u'添加时间')
+
+    class Meta:
+        db_table = 'device_log'
+        verbose_name = '设备日志表'
+        verbose_name_plural = verbose_name
+
+
 class EquipmentInfoExStatisticsModel(models.Model):
 class EquipmentInfoExStatisticsModel(models.Model):
     id = models.AutoField(primary_key=True)
     id = models.AutoField(primary_key=True)
     push_type = models.SmallIntegerField(default=0, verbose_name='第三方推送服务器标志。0:APNS推送,1:谷歌推送,2:极光推送')
     push_type = models.SmallIntegerField(default=0, verbose_name='第三方推送服务器标志。0:APNS推送,1:谷歌推送,2:极光推送')
@@ -1584,11 +1620,14 @@ class iotdeviceInfoModel(models.Model):
     thing_name = models.CharField(blank=True, max_length=256, default='', verbose_name=u'IoT Thing Name')
     thing_name = models.CharField(blank=True, max_length=256, default='', verbose_name=u'IoT Thing Name')
     thing_groups = models.CharField(blank=True, max_length=256, default='', verbose_name=u'IoT Thing Groups')
     thing_groups = models.CharField(blank=True, max_length=256, default='', verbose_name=u'IoT Thing Groups')
     endpoint = models.CharField(blank=True, max_length=256, db_index=True, default='', verbose_name=u'iot端点')
     endpoint = models.CharField(blank=True, max_length=256, db_index=True, default='', verbose_name=u'iot端点')
-    token_iot_number = models.CharField(blank=True,  db_index=True ,default='', max_length=50, verbose_name='连接iot令牌')
+    token_iot_number = models.CharField(blank=True,  db_index=True, default='', max_length=50, verbose_name='连接iot令牌')
+    add_time = models.DateTimeField(blank=True, auto_now_add=True, verbose_name=u'添加时间')
+    update_time = models.DateTimeField(blank=True, auto_now=True, verbose_name=u'更新时间')
     class Meta:
     class Meta:
         db_table = 'iot_deviceInfo'
         db_table = 'iot_deviceInfo'
         verbose_name = 'iot设备信息表'
         verbose_name = 'iot设备信息表'
         verbose_name_plural = verbose_name
         verbose_name_plural = verbose_name
+        ordering = ('-add_time',)
 
 
 
 
 class UIDMainUser(models.Model):
 class UIDMainUser(models.Model):
@@ -1630,7 +1669,7 @@ class Pc_Info(models.Model):
 class CloudLogModel(models.Model):
 class CloudLogModel(models.Model):
     id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
     id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
     user = models.CharField(max_length=100, default='', db_index=True, blank=True, verbose_name=u'用户')
     user = models.CharField(max_length=100, default='', db_index=True, blank=True, verbose_name=u'用户')
-    uid = models.CharField(blank=True, max_length=32, verbose_name=u'uid', default='')
+    uid = models.CharField(blank=True, max_length=32, db_index=True, verbose_name=u'uid', default='')
     operation = models.CharField(max_length=100, db_index=True, default='', blank=True, verbose_name=u'操作')
     operation = models.CharField(max_length=100, db_index=True, default='', blank=True, verbose_name=u'操作')
     ip = models.CharField(max_length=100, default='', db_index=True, blank=True, verbose_name=u'访问ip地址')
     ip = models.CharField(max_length=100, default='', db_index=True, blank=True, verbose_name=u'访问ip地址')
     url = models.CharField(max_length=150, default='', blank=True, verbose_name=u'访问路径')
     url = models.CharField(max_length=150, default='', blank=True, verbose_name=u'访问路径')

+ 2 - 0
Object/ResponseObject.py

@@ -13,6 +13,7 @@ class ResponseObject(object):
             5: 'Please try again one minute later!',
             5: 'Please try again one minute later!',
             10: res,
             10: res,
             12: 'You are not the primary user of the device!',
             12: 'You are not the primary user of the device!',
+            13: 'Timestamp token verification failed',
             14: 'Device is not belong to you',
             14: 'Device is not belong to you',
             15: 'Device has been bound',
             15: 'Device has been bound',
             16: 'WeChat has been bound, please log in and unbind using WeChat',
             16: 'WeChat has been bound, please log in and unbind using WeChat',
@@ -109,6 +110,7 @@ class ResponseObject(object):
             5: '请一分钟后再尝试',
             5: '请一分钟后再尝试',
             10: res,
             10: res,
             12: '非设备主用户',
             12: '非设备主用户',
+            13: '时间戳token校验失败',
             14: '设备不属于您',
             14: '设备不属于您',
             15: '设备已被绑定',
             15: '设备已被绑定',
             16: '微信已被绑定,请使用微信登录并解绑',
             16: '微信已被绑定,请使用微信登录并解绑',

+ 68 - 3
Service/CommonService.py

@@ -1,4 +1,5 @@
 # -*- coding: utf-8 -*-
 # -*- coding: utf-8 -*-
+# 高复用性函数封装到CommonService类
 import base64
 import base64
 import datetime
 import datetime
 import time
 import time
@@ -10,9 +11,8 @@ from django.core import serializers
 from django.utils import timezone
 from django.utils import timezone
 from pyipip import IPIPDatabase
 from pyipip import IPIPDatabase
 from Ansjer.config import BASE_DIR, UNICODE_ASCII_CHARACTER_SET
 from Ansjer.config import BASE_DIR, UNICODE_ASCII_CHARACTER_SET
-
-
-# 复用性且公用较高封装代码在这
+import OpenSSL.crypto as ct
+from base64 import encodebytes
 from Controller.CheckUserData import RandomStr
 from Controller.CheckUserData import RandomStr
 from Service.ModelService import ModelService
 from Service.ModelService import ModelService
 
 
@@ -253,6 +253,8 @@ class CommonService:
 
 
     @staticmethod
     @staticmethod
     def decode_data(content, start=1, end=4):
     def decode_data(content, start=1, end=4):
+        if not content:
+            return ''
         try:
         try:
             for i in range(start, end):
             for i in range(start, end):
                 if i == 1:
                 if i == 1:
@@ -275,6 +277,8 @@ class CommonService:
 
 
     @staticmethod
     @staticmethod
     def encode_data(content, start=1, end=4):
     def encode_data(content, start=1, end=4):
+        if not content:
+            return ''
         for i in range(start, end):
         for i in range(start, end):
             if i == 1:
             if i == 1:
                 content = RandomStr(3, False)+content+RandomStr(3, False)
                 content = RandomStr(3, False)+content+RandomStr(3, False)
@@ -385,6 +389,8 @@ class CommonService:
 
 
     @staticmethod
     @staticmethod
     def decode_data(content, start=1, end=4):
     def decode_data(content, start=1, end=4):
+        if not content:
+            return ''
         try:
         try:
             for i in range(start, end):
             for i in range(start, end):
                 if i == 1:
                 if i == 1:
@@ -408,6 +414,8 @@ class CommonService:
 
 
     @staticmethod
     @staticmethod
     def encode_data(content, start=1, end=4):
     def encode_data(content, start=1, end=4):
+        if not content:
+            return ''
         for i in range(start, end):
         for i in range(start, end):
             if i == 1:
             if i == 1:
                 content = CommonService.RandomStr(3, False) + content + CommonService.RandomStr(3, False)
                 content = CommonService.RandomStr(3, False) + content + CommonService.RandomStr(3, False)
@@ -424,4 +432,61 @@ class CommonService:
     def encode_data_without_salt(content):
     def encode_data_without_salt(content):
         return base64.b64encode(str(content).encode("utf-8")).decode('utf8')
         return base64.b64encode(str(content).encode("utf-8")).decode('utf8')
 
 
+    @staticmethod
+    def check_time_stamp_token(token, time_stamp):
+        # 时间戳token校验
+        if not all([token, time_stamp]):
+            return False
+        try:
+            token = int(CommonService.decode_data(token))
+            time_stamp = int(time_stamp)
+            now_time = int(time.time())
+            distance = now_time - time_stamp
+            if token != time_stamp or distance > 60000 or distance < -60000:  # 为了全球化时间控制在一天内
+                return False
+            return True
+        except Exception as e:
+            print(e)
+            return False
+
+    @staticmethod
+    def rsa_sign(Token):
+        # 私钥签名Token
+        if not Token:
+            return ''
+        private_key_file = '''-----BEGIN RSA PRIVATE KEY-----
+MIIEpQIBAAKCAQEA5iJzEDPqtGmFMggekVro6C0lrjuC2BjunGkrFNJWpDYzxCzE
+X5jf4/Fq7hcIaQd5sqHugDxPVollSLPe9zNilbrd0sZfU+Ed8gRVuKW9KwfE9XFr
+L0pt6bKRQ0IIRfiZ9TuR0tsQysvcO1GZSXcYfPue3tGM1zOnWFThWDqZ06+sOxzt
+RMRl4yNfbpCG4MfxG3itNXOfrjZv2OMLSXrxmzubSvRpUYSvQPs4fm9302SAnySY
+0MKzx6H6528ZQm/IDDSZy6EmNBIyTRDfxC56vnYcXvqedAQh7jJnjdvt6Q4MhASH
+eIYi1FBSdu2NT6wgpnrqXzx5pq9kR/lnsLID0wIDAQABAoIBAQCiF4GT1/1oNSpr
+ouxk1PNXFPWFUsVGD8mAwVJmx//eiY7MjfuCmdqYYmI+cFqsH2fIOeYSzGfVO9Dq
+9EYHN1oovAWhf7eFDPpajFMUSyiCNmazub8VAAeKowtNpCTPo9pMsDh1m3aoYA4u
+ebrN0+Sbo16y8kWRDgDAZoiR7DSMs8lczk16hwfv5mw8XpNDbaL3Coi4Koe2S1Yh
+2SX3vWFlpd7qF1ZYXuZIp+b8JPrV7n9eUKoFgzj0gqgwQK80CoexIjiOrNMPvkQa
+q+8kCvFjAzKxOK7e8gjM8lMRiGodb61kmYZkkJzFwWO4EaGbl34lfVECd1Ixp3tF
+be0OWAGBAoGBAPSteXDzzToD8ovM7LL11x0jWwI6HOiHu89kZtW566rIezjWBuA2
+TxrcYKM3h9jQRXS3CsMdoIv6XGk5lqM8ADtjn23FBWe/THYLh8bm8JOgh5RRWQDg
+SvkLfi9Ih2mM4NJfmuuDOh3Nze2efLM7+kOZWUQwF2Zx9mL5jvRBk351AoGBAPDI
+sYmT2Li+i5+0vykA2m5uPF8ZOW8BGtAfCZv0suW7BNzSgin78g9WapRd/4p0NNiL
+/nVMqPPCpd1akCUpV+GDWQt0hV+HZjxANE0KWhciQRyo2qvo51j8SWILJSgh0tXC
+aTF8qt6oGw3VN3m57vKhbrlDaz0J/NDJFci6msAnAoGBAOuG6bXPGijUj+//DYKf
+n7jOxdZ49kboEePrtAncdHzri6IEdI3z+WXT6bpzw/LzWUimwldb96WHFNm9s8Hi
+Ch8hIODbnP5naUTgiIzw1XhmONyPCewL/F+LrqX5XVA/alNX8JrwsUrrR2WLAGLQ
+Q3I69XDsEjptTU2tCO0bCs3ZAoGBAJ2lCHfm0JHET230zONvp5N9oREyVqQSuRdh
++syc3TQDyh85w/bw+X6JOaaCFHj1tFPC9Iqf8k4GNspCLPXnp54CfR4+38O3xnvU
+HWoDSRC0YKT++IxtJGriYrlKSr2Hx54kdvLriIPW1D+uRW/xCDza7L9nIKMKEvgv
+b4/IfOEpAoGAeKM9Te7T1VzlAkS0CJOwanzwYV/zrex84WuXxlsGgPQ871lTs5AP
+H1QLfLfFXH+UVrCEC2yv4eml/cqFkpB3gE5i4MQ8GPVIOSs5tsIyl8YUA03vdNdB
+GCqvlyw5dfxNA+EtxNE2wCW/LW7ENJlACgcfgPlBZtpLheWoZB/maw4=
+-----END RSA PRIVATE KEY-----'''
+        # 使用密钥文件方式
+        # private_key_file_path = os.path.join(BASE_DIR, 'static/iotCore/private.pem')#.replace('\\', '/')
+        # private_key_file = open(private_key_file_path, 'r')
+        private_key = ct.load_privatekey(ct.FILETYPE_PEM, private_key_file)
+        signature = ct.sign(private_key, Token.encode('utf8'), 'sha256')
+        signature = encodebytes(signature).decode('utf8').replace('\n', '')
+        # print('signature:', signature)
+        return signature