瀏覽代碼

Merge branch 'test' of http://192.168.136.99:3000/servers/ASJServer into test

lang 3 年之前
父節點
當前提交
70e9f3d9a6

+ 1 - 3
AdminController/AiServeController.py

@@ -66,9 +66,7 @@ class AiServeView(View):
         isSelect = request_dict.get('isSelect', None)
         if isSelect:
             # 获取套餐ID作为选项
-            ai_meal_qs = AiStoreMeal.objects.filter(
-                lang__lang='cn').values(
-                'id', 'lang__title')
+            ai_meal_qs = AiStoreMeal.objects.filter().values('id')
             return response.json(
                 0, {'list': CommonService.qs_to_list(ai_meal_qs)})
 

+ 2 - 0
Ansjer/local_config/config_local.py

@@ -21,6 +21,8 @@ PAYPAL_CRD = {
     "client_secret": "EO8kRc8yioDk0i2Qq-QMcVFfwkmyMJorTvBSLDTnxDJJ_wb9VoM_0jkUY9iEng2Flp1ze8wQOGpH5nB2"
 }
 PAYPAL_WEB_HOOK_ID = '6TS30758D98835230'
+PAYPAL_WEB_HOOK_ID_TWO = '2BH56575UJ9324151'
+
 DETECT_PUSH_DOMAIN = 'http://test.push.dvema.com/'
 DETECT_PUSH_DOMAINS = 'https://test.push.dvema.com/'
 DETECT_PUSH_DOMAIN_JIUAN = 'http://jiuan.push.dvema.com/'

+ 30 - 52
Controller/DeviceConfirmRegion.py

@@ -1,47 +1,13 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-"""
-@Copyright (C) ansjer cop Video Technology Co.,Ltd.All rights reserved.
-@software: PyCharm
-@Version: python3.6
-"""
-import datetime
-import traceback
 import time
-import logging
-import jwt
-import simplejson
-import simplejson as json
-import requests
-from django.contrib.auth.hashers import make_password, check_password  # 对密码加密模块
-from django.db.models import Q
-from django.http import HttpResponseRedirect
+
 from django.utils.decorators import method_decorator
-from django.utils.timezone import utc
+
 from django.views.decorators.csrf import csrf_exempt
 from django.views.generic import TemplateView
-from jwt.algorithms import RSAAlgorithm
-from ratelimit.decorators import ratelimit
-
-from Ansjer.config import AuthCode_Expire, SERVER_DOMAIN, APNS_CONFIG, JPUSH_CONFIG, FCM_CONFIG, TUTK_PUSH_DOMAIN
-from Controller.CheckUserData import DataValid, date_handler, RandomStr
-from Model.models import Device_User, Role, UidPushModel, UserOauth2Model, UserExModel, Device_Info, UidSetModel, \
-    UserAppFrequencyModel, CountryIPModel, CountryModel, RegionModel, P2PIpModel, DeviceDomainModel
-from Object.AWS.SesClassObject import SesClassObject
-from Object.AliSmsObject import AliSmsObject
-from Object.RedisObject import RedisObject
+from Model.models import CountryModel, RegionModel, P2PIpModel, DeviceDomainModel
 from Object.ResponseObject import ResponseObject
-from Object.TokenObject import TokenObject
 from Service.CommonService import CommonService
-from Service.ModelService import ModelService
-from Service.TemplateService import TemplateService
-from django.views.generic import View
-import base64
-import random
-from io import BytesIO
-from PIL import Image, ImageDraw, ImageFont
-from django.shortcuts import HttpResponse
-from Ansjer.config import BASE_DIR
+
 
 #确认设备所在地区
 class ConfirmRegion(TemplateView):
@@ -73,52 +39,66 @@ class ConfirmRegion(TemplateView):
         return response.json(0,{"request_api_url": api[0]['api']})
 
 
-# 根据设备的ip返回域名
+# 根据设备的ip返回域名和地区id
 class ConfirmRegionV2(TemplateView):
     @method_decorator(csrf_exempt)
     def dispatch(self, *args, **kwargs):
         return super(ConfirmRegionV2, self).dispatch(*args, **kwargs)
 
     def get(self, request, *args, **kwargs):
+        response = ResponseObject()
+        uid = request.GET.get('uid', None)
+        serial_number = request.GET.get('serial_number', None)
+        if not uid and not serial_number:
+            return response.json(444)
         try:
-            response = ResponseObject()
-            uid = request.GET.get('uid', None)
-            serial_number = request.GET.get('serial_number', None)
-            if not uid and not serial_number:
-                return response.json(444)
             if uid:
                 data_dict = {'uid': uid}
                 device_domain_qs = DeviceDomainModel.objects.filter(uid=uid)
             else:
                 data_dict = {'serial_number': serial_number}
                 device_domain_qs = DeviceDomainModel.objects.filter(serial_number=serial_number)
+
+            # 根据请求ip确认地区
             request.encoding = 'utf-8'
             ip = CommonService.get_ip_address(request)
             data_dict['ip'] = ip
             ipInfo = CommonService.getIpIpInfo(ip, 'CN')
             country_code = ipInfo['country_code']
+
             if country_code:
                 data_dict['country_name'] = ipInfo['country_name']
-                device_request_url = CountryModel.objects.filter(country_code=country_code).values('region__api')
-                if device_request_url.exists():
-                    api = device_request_url[0]['region__api']
+                country_qs = CountryModel.objects.filter(country_code=country_code).\
+                    values('region__api', 'region__id')
+                if country_qs.exists():
+                    api = country_qs[0]['region__api']
+                    region_id = country_qs[0]['region__id']
                 else:   # 默认返回美洲地区api
-                    api = RegionModel.objects.filter(continent_code='NA').values('api')[0]['api']
+                    api, region_id = self.get_default_api()
             else:
                 # 默认返回美洲地区api
-                api = RegionModel.objects.filter(continent_code='NA').values('api')[0]['api']
+                api, region_id = self.get_default_api()
 
             # 更新或创建设备域名数据
             data_dict['api'] = api
+            data_dict['region_id'] = region_id
             if device_domain_qs.exists():
                 device_domain_qs.update(**data_dict)
             else:
                 device_domain_qs.create(**data_dict)
-            return response.json(0, {'request_api_url': api})
+            res = {'request_api_url': api, 'region_id': region_id}
+            return response.json(0, res)
         except Exception as e:
             print(e)
             return response.json(500, repr(e))
 
+    # 获取区域表美洲的相关数据
+    @staticmethod
+    def get_default_api():
+        region_qs = RegionModel.objects.filter(continent_code='NA').values('api', 'id')
+        api = region_qs[0]['api']
+        region_id = region_qs[0]['id']
+        return api, region_id
 
 #确认设备所在地区
 class Device_Region(object):
@@ -206,8 +186,6 @@ def confirm_country_with_ip(request):
                             ip = ip[:-1]
                         ipInfo = CommonService.getIpIpInfo(ip, "CN")
                         country = ipInfo['country_name'] if ipInfo['country_name'] else 'N/A'
-                        if country == '中国':
-                            country = '美国'
                     wf.write(country+'\n')
         return response.json(0)
     except Exception as e:

+ 66 - 77
Controller/IotCoreController.py

@@ -1,30 +1,24 @@
 #!/usr/bin/env python3
 # -*- coding: utf-8 -*-
-import logging
-import os
 import hashlib
-import json
+import logging
 import time
 import uuid
-import boto3
-import requests
 
+import requests
 from django.views import View
-from Ansjer.config import BASE_DIR, AWS_IOT_GETS3_PULL_CHINA_ID, AWS_IOT_GETS3_PULL_CHINA_SECRET, \
+
+from Ansjer.config import AWS_IOT_GETS3_PULL_CHINA_ID, AWS_IOT_GETS3_PULL_CHINA_SECRET, \
     AWS_IOT_GETS3_PULL_FOREIGN_ID, AWS_IOT_GETS3_PULL_FOREIGN_SECRET, AWS_ARN, AWS_IOT_SES_ACCESS_CHINA_REGION, \
     AWS_IOT_SES_ACCESS_FOREIGN_REGION_ASIA, AWS_IOT_SES_ACCESS_FOREIGN_REGION_EUROPE, \
-    AWS_IOT_SES_ACCESS_FOREIGN_REGION_AMERICA, SERVER_TYPE
-from base64 import b64encode, encodebytes
+    AWS_IOT_SES_ACCESS_FOREIGN_REGION_AMERICA
 from Controller.DeviceConfirmRegion import Device_Region
-from Model.models import Device_User, Device_Info, iotdeviceInfoModel, UIDCompanySerialModel, \
-    SerialNumberModel
+from Model.models import Device_Info, iotdeviceInfoModel, SerialNumberModel, UidSetModel
 from Object.IOTCore.IotObject import IOTClient
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Service.CommonService import CommonService
 
-import OpenSSL.crypto as ct
-
 
 class IotCoreView(View):
 
@@ -51,7 +45,7 @@ class IotCoreView(View):
         elif operation == 'getS3PullKey':
             return self.get_s3_pull_key(request_dict, response, request)
         elif operation == 'thingRegroup':
-            return self.thing_regroup(request_dict, response, request)
+            return self.thing_regroup(request_dict, response)
         elif operation == 'pcGetIotInfo':
             return self.pcGetIotInfo(request_dict, response)
         else:
@@ -68,7 +62,8 @@ class IotCoreView(View):
                 return response.json(404)
 
     # 设备注册到aws iot core
-    def create_keys_and_certificate(self, request_dict, response, request):
+    @staticmethod
+    def create_keys_and_certificate(request_dict, response, request):
         logger = logging.getLogger('info')
         logger.info('设备注册到aws iot core请求参数:{}'.format(request_dict))
         token = request_dict.get('token', None)
@@ -80,8 +75,8 @@ class IotCoreView(View):
             return response.json(444, {'param': 'token, language, time_stamp, device_version'})
 
         try:
-            no_rtc = request_dict.get('no_rtc', None)
             # 时间戳token校验
+            no_rtc = request_dict.get('no_rtc', None)
             if no_rtc:
                 if not CommonService.check_time_stamp_token_without_distance(token, time_stamp):
                     return response.json(13)
@@ -91,9 +86,8 @@ class IotCoreView(View):
 
             uid = request_dict.get('uid', '')
             uid_code = request_dict.get('uid_code', None)
-            companyMark = '11A'
-            if not uid:
-                # 使用序列号
+            company_mark = '11A'
+            if not uid:  # 传序列号
                 serial_number = request_dict.get('serial_number', None)
                 serial_number_code = request_dict.get('serial_number_code', None)
                 if not all([serial_number, serial_number_code]):
@@ -105,44 +99,48 @@ class IotCoreView(View):
                     return response.json(404)
 
                 serial = serial_number[0:6]
-                companyMark = serial_number[-3:]
+                company_mark = serial_number[-3:]
                 try:
                     SerialNumberModel.objects.get(serial_number=serial)
                 except:
                     return response.json(444)
 
-                ThingNameSuffix = serial_number  # 物品名后缀
-                iotdeviceInfo_qs = iotdeviceInfoModel.objects.filter(serial_number=serial)
-            else:
-                # 使用uid
+                thing_name_suffix = serial_number  # 物品名后缀
+                iot_device_info_qs = iotdeviceInfoModel.objects.filter(serial_number=serial)
+            else:  # 传uid
                 # uid编码解码校验
                 uid_code = CommonService.decode_data(uid_code)
                 if uid != uid_code:
                     return response.json(404)
 
-                serial = ''     # iot_deviceInfo表写入serial_number为''
-                ThingNameSuffix = uid     # 物品名后缀
-                iotdeviceInfo_qs = iotdeviceInfoModel.objects.filter(uid=uid)
-            # 判断设备是否已注册证书
-            if not iotdeviceInfo_qs.exists():
-                # 设备模拟国外环境测试
-                # if SERVER_TYPE == 'Ansjer.us_config.formal_settings':  # 国外正式配置使用固定ip进行测试
-                #     ip = '67.220.90.13'
-                # else:
-                #     ip = CommonService.get_ip_address(request)
-                ip = CommonService.get_ip_address(request)
-                region_id = Device_Region().get_device_region(ip)
+                serial = ''  # iot_deviceInfo表写入serial_number为''
+                thing_name_suffix = uid  # 物品名后缀
+                iot_device_info_qs = iotdeviceInfoModel.objects.filter(uid=uid)
+            # 判断设备是否已注册过
+            if iot_device_info_qs.exists():
+                iot = iot_device_info_qs[0]
+                res = {
+                    'certificateId': iot.certificate_id,
+                    'certificatePem': iot.certificate_pem,
+                    'publicKey': iot.public_key,
+                    'privateKey': iot.private_key,
+                    'endpoint': iot.endpoint
+                }
+                return response.json(0, {'res': res})
+            else:
+                # 根据地区id确定使用的boto3 client
+                region_id = request_dict.get('region_id', None)
+                if region_id:
+                    region_id = int(region_id)
+                else:
+                    ip = CommonService.get_ip_address(request)
+                    region_id = Device_Region().get_device_region(ip)
                 iotClient = IOTClient(region_id)
 
                 # 拼接物品名
-                if companyMark == '11A':
-                    ThingName = 'Ansjer_Device_' + ThingNameSuffix
-                elif companyMark == '11L':
-                    ThingName = 'Loocam_Device_' + ThingNameSuffix
-                else:
-                    ThingName = ThingNameSuffix
+                thingName = CommonService.get_thing_name(company_mark, thing_name_suffix)
                 thingGroup = device_version + '_' + language
-                res = iotClient.register_to_iot_core(ThingName, thingGroup, response)
+                res = iotClient.register_to_iot_core(thingName, thingGroup, response)
 
                 token_iot_number = hashlib.md5((str(uuid.uuid1()) + str(int(time.time()))).encode('utf-8')).hexdigest()
                 iotdeviceInfoModel.objects.create(uid=uid,
@@ -164,50 +162,44 @@ class IotCoreView(View):
                     'endpoint': res[0]['endpoint']
                 }
                 return response.json(0, {'res': res})
-            else:
-                iot = iotdeviceInfo_qs[0]
-                res = {
-                    'certificateId': iot.certificate_id,
-                    'certificatePem': iot.certificate_pem,
-                    'publicKey': iot.public_key,
-                    'privateKey': iot.private_key,
-                    'endpoint': iot.endpoint
-                }
-                return response.json(0, {'res': res})
         except Exception as e:
             print(e)
             return response.json(500, repr(e))
 
-    def thing_regroup(self, request_dict, response, request):
+    @staticmethod
+    def thing_regroup(request_dict, response):
         # 物品重新分组
         uid = request_dict.get('uid', '')
         token = request_dict.get('token', None)
         language = request_dict.get('language', None)
+        region_id = request_dict.get('region_id', None)
         time_stamp = request_dict.get('time_stamp', None)
         device_version = request_dict.get('device_version', None)
 
-        if not all([token, language, time_stamp, device_version]):
-            return response.json(444, {'param: token, language, time_stamp, device_version'})
+        if not all([token, language, region_id, time_stamp, device_version]):
+            return response.json(444)
 
         # 时间戳token校验
         if not CommonService.check_time_stamp_token(token, time_stamp):
             return response.json(13)
 
-        ip = CommonService.get_ip_address(request)
-        region_id = Device_Region().get_device_region(ip)
-        iotClient = IOTClient(region_id)
-
-        ThingNameSuffix = uid
+        company_mark = '11A'
+        thing_name_suffix = uid
         if not uid:
             # 使用序列号
             serial_number = request_dict.get('serial_number', None)
             if not serial_number:
                 return response.json(444)
-            ThingNameSuffix = serial_number
-        thingName = 'Ansjer_Device_' + ThingNameSuffix
+            company_mark = serial_number[-3:]
+            thing_name_suffix = serial_number
+            uid = CommonService.query_uid_with_serial(serial_number)
+
+        uid_set_qs = UidSetModel.objects.filter(uid=uid)
+        thingName = CommonService.get_thing_name(company_mark, thing_name_suffix)
         new_thingGroupName = (device_version + '_' + language).replace('.', '_')  # 物品组命名不能包含'.'
 
         try:
+            iotClient = IOTClient(int(region_id))
             # 获取旧物品组
             list_groups_res = iotClient.client.list_thing_groups_for_thing(thingName=thingName, maxResults=1)
             old_thingGroupName = list_groups_res['thingGroups'][0]['groupName']
@@ -232,10 +224,7 @@ class IotCoreView(View):
                                                            , thingGroupsToRemove=[old_thingGroupName])
 
             # 更新设备版本信息
-            if uid:
-                Device_Info.objects.filter(UID=uid).update(version=device_version)
-            else:
-                Device_Info.objects.filter(serial_number=serial_number).update(version=device_version)
+            uid_set_qs.update(version=device_version)
             return response.json(0)
         except Exception as e:
             print(e)
@@ -282,7 +271,7 @@ class IotCoreView(View):
             Token = iot[0]['token_iot_number']
             # Token = '297a601b3925e04daab5a60280650e09'
             topic_suffix = '_power_topic' if 'Turn' in MSG else '_rtsp_topic'
-            topic_name = thing_name + topic_suffix     # MQTT主题
+            topic_name = thing_name + topic_suffix  # MQTT主题
 
             # 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
@@ -330,14 +319,14 @@ class IotCoreView(View):
             endpoint = iot[0]['endpoint']
             MSG = self.get_s3_key_return_msg(endpoint)
 
-            return response.json(0,MSG)
+            return response.json(0, MSG)
         except Exception as e:
             # print(e)
             return response.json(500, repr(e))
 
-    def get_s3_key_return_msg(self,endpoint):
+    def get_s3_key_return_msg(self, endpoint):
         MSG = {}
-        if 'cn-northwest-1' in endpoint :
+        if 'cn-northwest-1' in endpoint:
             key = AWS_IOT_GETS3_PULL_CHINA_ID
             secret = AWS_IOT_GETS3_PULL_CHINA_SECRET
             arn = AWS_ARN[0]
@@ -346,11 +335,11 @@ class IotCoreView(View):
             key = AWS_IOT_GETS3_PULL_FOREIGN_ID
             secret = AWS_IOT_GETS3_PULL_FOREIGN_SECRET
             arn = AWS_ARN[1]
-            if 'ap-southeast-1' in endpoint :
+            if 'ap-southeast-1' in endpoint:
                 region_name = AWS_IOT_SES_ACCESS_FOREIGN_REGION_ASIA
-            if 'eu-west-1' in endpoint :
+            if 'eu-west-1' in endpoint:
                 region_name = AWS_IOT_SES_ACCESS_FOREIGN_REGION_EUROPE
-            if 'us-east-1' in endpoint :
+            if 'us-east-1' in endpoint:
                 region_name = AWS_IOT_SES_ACCESS_FOREIGN_REGION_AMERICA
 
         MSG['AccessKeyId'] = key
@@ -370,10 +359,10 @@ class IotCoreView(View):
         try:
             if serial_number:
                 serial_number = serial_number[0:6]
-                iot_info_qs = iotdeviceInfoModel.objects.filter(serial_number=serial_number).\
+                iot_info_qs = iotdeviceInfoModel.objects.filter(serial_number=serial_number). \
                     values('endpoint', 'token_iot_number')
             else:
-                iot_info_qs = iotdeviceInfoModel.objects.filter(uid=uid).\
+                iot_info_qs = iotdeviceInfoModel.objects.filter(uid=uid). \
                     values('endpoint', 'token_iot_number')
 
             if not iot_info_qs.exists():
@@ -396,10 +385,10 @@ class IotCoreView(View):
         try:
             if serial_number:
                 serial_number = serial_number[0:6]
-                iot_info_qs = iotdeviceInfoModel.objects.filter(serial_number=serial_number).\
+                iot_info_qs = iotdeviceInfoModel.objects.filter(serial_number=serial_number). \
                     values('endpoint', 'token_iot_number')
             else:
-                iot_info_qs = iotdeviceInfoModel.objects.filter(uid=uid).\
+                iot_info_qs = iotdeviceInfoModel.objects.filter(uid=uid). \
                     values('endpoint', 'token_iot_number')
 
             if not iot_info_qs.exists():

+ 71 - 68
Controller/PaymentCycle.py

@@ -1,6 +1,6 @@
-from Ansjer.config import PAYPAL_CRD,SERVER_DOMAIN,SERVER_DOMAIN_SSL,PAYPAL_WEB_HOOK_ID, PAYPAL_WEB_HOOK_ID_TWO
-from Model.models import PayCycleConfigModel,Order_Model, Store_Meal, UID_Bucket, PromotionRuleModel,\
-    Unused_Uid_Meal,Device_Info, CouponModel, Order_Model, PaypalWebHookEvent
+from Ansjer.config import PAYPAL_CRD, SERVER_DOMAIN, SERVER_DOMAIN_SSL, PAYPAL_WEB_HOOK_ID, PAYPAL_WEB_HOOK_ID_TWO
+from Model.models import PayCycleConfigModel, Order_Model, Store_Meal, UID_Bucket, PromotionRuleModel, \
+    Unused_Uid_Meal, Device_Info, CouponModel, Order_Model, PaypalWebHookEvent
 from Service.CommonService import CommonService
 from django.http import JsonResponse, HttpResponseRedirect, HttpResponse
 import requests
@@ -21,12 +21,12 @@ import json
 from paypalrestsdk import BillingPlan
 
 
-#周期扣款相关
+# 周期扣款相关
 class Paypal:
-    #检查是否有重复订阅
-    def checkSubscriptions(userID,uid,rank):
-        hasOrder = Order_Model.objects.filter(UID=uid,rank=rank)
-        hasOrder = hasOrder.filter(~Q(agreement_id='')).values('agreement_id','orderID').order_by('-addTime')[0:1]
+    # 检查是否有重复订阅
+    def checkSubscriptions(userID, uid, rank):
+        hasOrder = Order_Model.objects.filter(UID=uid, rank=rank)
+        hasOrder = hasOrder.filter(~Q(agreement_id='')).values('agreement_id', 'orderID').order_by('-addTime')[0:1]
         if not hasOrder.exists():
             return True
         paypalrestsdk.configure(PAYPAL_CRD)
@@ -35,7 +35,7 @@ class Paypal:
             return False
         return True
 
-    def subscriptions(store_info,lang,orderID,price):
+    def subscriptions(store_info, lang, orderID, price):
         logger = logging.getLogger('pay')
         cycle_config = PayCycleConfigModel.objects.filter(id=store_info['cycle_config_id']).values()
         if not cycle_config:
@@ -104,9 +104,9 @@ class Paypal:
             start_date_timestamp = now_time + 86400 - 3600  # 下次扣款为明天,提前1个小时扣款
             start_date_str = CommonService.timestamp_to_str(start_date_timestamp, "%Y-%m-%dT%H:%M:%SZ")
         elif cycle_config[0]['frequency'] == "MONTH":
-            start_date_timestamp = CommonService.calcMonthLater(1, now_time) - (5 * 86400) #下次扣款为下个月提前5天扣款
+            start_date_timestamp = CommonService.calcMonthLater(1, now_time) - (5 * 86400)  # 下次扣款为下个月提前5天扣款
             start_date_str = CommonService.timestamp_to_str(start_date_timestamp, "%Y-%m-%dT%H:%M:%SZ")
-        #订阅
+        # 订阅
         billingAgreement = {
             "name": store_info['lang__content'],
             "description": orderID,
@@ -129,6 +129,7 @@ class Paypal:
             logger.info(billing_agreement.error)
             return False
 
+
 class PaypalCycleNotify(View):
     def get(self, request, *args, **kwargs):
         request.encoding = 'utf-8'
@@ -147,12 +148,13 @@ class PaypalCycleNotify(View):
         elif operation == 'paypalCycleReturn':  # paypal成功订阅回调
             return self.do_paypal_cycle_return(request_dict, response)
         elif operation == 'paypalCycleNotify':  # paypal 周期付款回调
-            return self.do_paypal_webhook_notify(request_dict,request, response)
-        elif operation == 'subscriptionBreakNotify':               # paypal 订阅相关回调
-            return self.do_subscription_break_notify(request_dict,request, response)
+            return self.do_paypal_webhook_notify(request_dict, request, response)
+        elif operation == 'subscriptionBreakNotify':  # paypal 订阅相关回调
+            return self.do_subscription_break_notify(request_dict, request, response)
+
     def do_paypal_cycle_return(self, request_dict, response):
         lang = request_dict.get('lang', 'en')
-        token = request_dict.get('token',None)
+        token = request_dict.get('token', None)
 
         logger = logging.getLogger('pay')
         logger.info('--------进入paypay首次订阅付款回调--------')
@@ -169,12 +171,12 @@ class PaypalCycleNotify(View):
             return HttpResponseRedirect(red_url)
 
         orderID = billing_agreement_response.description
-
+        state = billing_agreement_response.state
+        nowTime = int(time.time())
+        promotion_rule_id = ''
         logger.info('----订阅详情----')
         logger.info(billing_agreement_response)
-
         agreement_id = billing_agreement_response.id
-        promotion_rule_id = ''
         order_qs = Order_Model.objects.filter(orderID=orderID, status=0)
         order_list = order_qs.values("UID", "channel", "commodity_code", "rank", "isSelectDiscounts",
                                      "userID__userID",
@@ -186,6 +188,15 @@ class PaypalCycleNotify(View):
                 red_url = "{SERVER_DOMAIN_SSL}web/paid2/en_fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
             return HttpResponseRedirect(red_url)
         UID = order_list[0]['UID']
+        if state != 'Active':
+            order_qs.update(status=2, promotion_rule_id=promotion_rule_id)
+            logger.info('----UID:{UID},用户名:{last_time} {first_time}首次订阅付款失败----'.format
+                        (UID=UID,
+                         last_time=billing_agreement_response.payer.payer_info.last_name,
+                         first_time=billing_agreement_response.payer.payer_info.first_time,
+                         ))
+            logger.info('billing_agreement_state')
+            logger.info(state)
         try:
             userid = order_list[0]['userID__userID']
             username = order_list[0]['userID__username']
@@ -208,21 +219,20 @@ class PaypalCycleNotify(View):
             if order_list[0]['isSelectDiscounts'] == 1:
                 expire = smqs[0]['expire'] * 2
             # 是否有促销
-            nowTime = int(time.time())
             promotion = PromotionRuleModel.objects.filter(status=1, startTime__lte=nowTime,
-                                                          endTime__gte=nowTime).values('id','ruleConfig')
+                                                          endTime__gte=nowTime).values('id', 'ruleConfig')
             if promotion.exists():
                 promotion_rule_id = promotion[0]['id']
                 expire = expire * 2
             with transaction.atomic():
                 if ubqs.exists():
                     ubq = ubqs[0]
-                    if ubq['use_status'] == 1 and ubq['bucket_id'] == bucketId:  #套餐使用中并且相同套餐叠加过期时间
+                    if ubq['use_status'] == 1 and ubq['bucket_id'] == bucketId:  # 套餐使用中并且相同套餐叠加过期时间
                         endTime = CommonService.calcMonthLater(expire, ubq['endTime'])
                         UID_Bucket.objects.filter(id=ubq['id']).update \
                             (uid=UID, channel=channel, bucket_id=bucketId,
                              endTime=endTime, updateTime=nowTime)
-                    else:     #已过期或者不相同的套餐加入未使用的关联套餐表
+                    else:  # 已过期或者不相同的套餐加入未使用的关联套餐表
                         has_unused = Unused_Uid_Meal.objects.filter(uid=UID, bucket_id=bucketId).values("id")
                         nums = 2 if order_list[0]['isSelectDiscounts'] == 1 else 1
                         if promotion.exists():
@@ -230,15 +240,15 @@ class PaypalCycleNotify(View):
                         if has_unused.exists():
                             Unused_Uid_Meal.objects.filter(id=has_unused[0]['id']).update(num=F('num') + nums)
                         else:
-                            Unused_Uid_Meal.objects.create(uid=UID,channel=channel,addTime=nowTime,num=nums,
-                                                           expire=smqs[0]['expire'],bucket_id=bucketId)
+                            Unused_Uid_Meal.objects.create(uid=UID, channel=channel, addTime=nowTime, num=nums,
+                                                           expire=smqs[0]['expire'], bucket_id=bucketId)
                         UID_Bucket.objects.filter(id=ubq['id']).update(has_unused=1)
                     uid_bucket_id = ubq['id']
                 else:
                     endTime = CommonService.calcMonthLater(expire)
                     ub_cqs = UID_Bucket.objects.create \
                         (uid=UID, channel=channel, bucket_id=bucketId, endTime=endTime, addTime=nowTime,
-                         updateTime=nowTime,use_status=1)
+                         updateTime=nowTime, use_status=1)
                     uid_bucket_id = ub_cqs.id
 
                 dvq = Device_Info.objects.filter(UID=UID, vodPrimaryUserID='', vodPrimaryMaster='')
@@ -262,14 +272,15 @@ class PaypalCycleNotify(View):
                     CouponModel.objects.filter(id=order_list[0]['coupon_id']).update(use_status=2)
 
                 order_qs.update(status=1, updTime=nowTime, uid_bucket_id=uid_bucket_id,
-                                promotion_rule_id=promotion_rule_id,agreement_id=agreement_id)
+                                promotion_rule_id=promotion_rule_id, agreement_id=agreement_id)
                 # 如果存在序列号,消息提示用序列号
                 device_name = CommonService.query_serial_with_uid(uid=UID)
                 datetime = time.strftime("%Y-%m-%d", time.localtime())
                 sys_msg_text_list = ['温馨提示:尊敬的客户,您的' + device_name + '设备在' + datetime + '已成功订阅云存套餐',
                                      'Dear customer,you already subscribed the cloud storage package successfully for device ' + device_name + ' on ' + time.strftime(
                                          "%b %dth,%Y", time.localtime())]
-                CloudStorage.CloudStorageView().do_vod_msg_Notice(UID, channel, userid, lang, sys_msg_text_list, 'SMS_219738485')
+                CloudStorage.CloudStorageView().do_vod_msg_Notice(UID, channel, userid, lang, sys_msg_text_list,
+                                                                  'SMS_219738485')
 
                 # return response.json(0)
                 red_url = "{SERVER_DOMAIN_SSL}web/paid2/success.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
@@ -290,7 +301,6 @@ class PaypalCycleNotify(View):
                 red_url = "{SERVER_DOMAIN_SSL}web/paid2/en_fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
             return HttpResponseRedirect(red_url)
 
-
     def do_paypal_webhook_notify(self, request_dict, request, response):
         logger = logging.getLogger('pay')
         logger.info('--------进入周期扣款钩子--------')
@@ -378,7 +388,7 @@ class PaypalCycleNotify(View):
                 logger.info('----订阅详情----')
                 logger.info(billing_agreement)
                 logger.info('订阅续费订单完成周期数==0,结束')
-                #更新order表,paypal的商家交易号
+                # 更新order表,paypal的商家交易号
                 Order_Model.objects.filter(orderID=billing_agreement.description).update(
                     updTime=int(time.time()),
                     trade_no=paypal_transaction_id
@@ -389,10 +399,11 @@ class PaypalCycleNotify(View):
             if not order_qs:
                 return HttpResponse('fail', status=500)
             order_list = order_qs.values("UID", "channel", "commodity_code", "rank", "isSelectDiscounts",
-                                         "userID__userID","uid_bucket_id",
-                                         "userID__username",'plan_id','addTime','desc','payType','currency','commodity_type','updTime')
+                                         "userID__userID", "uid_bucket_id",
+                                         "userID__username", 'plan_id', 'addTime', 'desc', 'payType', 'currency',
+                                         'commodity_type', 'updTime')
             nowTime = int(time.time())
-            if order_list[0]['addTime'] + 9200 > nowTime:  #避免续费订单重复支付
+            if order_list[0]['addTime'] + 9200 > nowTime:  # 避免续费订单重复支付
                 logger.info('----paypal重复异步回调----')
                 return HttpResponse('success')
 
@@ -467,12 +478,17 @@ class PaypalCycleNotify(View):
                 #     UIDMainUser.objects.create(**uid_main_dict)
                 orderID = CommonService.createOrderID()
                 Order_Model.objects.create(orderID=orderID, UID=UID, channel=channel, userID_id=userid,
-                                           desc=order_list[0]['desc'], payType=order_list[0]['payType'], payTime=nowTime,
-                                           price=amount.get('total'), currency=order_list[0]['currency'], addTime=nowTime, updTime=nowTime,
-                                           pay_url='', isSelectDiscounts=0,commodity_code=order_list[0]['commodity_code'],
-                                           commodity_type=order_list[0]['commodity_type'],rank_id=rank, paymentID='',
-                                           coupon_id='',uid_bucket_id=uid_bucket_id,status=1,agreement_id=agreement_id,
-                                           plan_id=order_list[0]['plan_id'], ai_rank_id=1, trade_no=paypal_transaction_id)
+                                           desc=order_list[0]['desc'], payType=order_list[0]['payType'],
+                                           payTime=nowTime,
+                                           price=amount.get('total'), currency=order_list[0]['currency'],
+                                           addTime=nowTime, updTime=nowTime,
+                                           pay_url='', isSelectDiscounts=0,
+                                           commodity_code=order_list[0]['commodity_code'],
+                                           commodity_type=order_list[0]['commodity_type'], rank_id=rank, paymentID='',
+                                           coupon_id='', uid_bucket_id=uid_bucket_id, status=1,
+                                           agreement_id=agreement_id,
+                                           plan_id=order_list[0]['plan_id'], ai_rank_id=1,
+                                           trade_no=paypal_transaction_id)
                 # 如果存在序列号,消息提示用序列号
                 device_name = CommonService.query_serial_with_uid(uid=UID)
                 datetime = time.strftime("%Y-%m-%d", time.localtime())
@@ -485,11 +501,11 @@ class PaypalCycleNotify(View):
                 else:
                     lang = 'cn'
                 CloudStorage.CloudStorageView().do_vod_msg_Notice(UID, channel, userid, lang,
-                                                                sys_msg_text_list, 'SMS_219738485')
+                                                                  sys_msg_text_list, 'SMS_219738485')
                 logger.info('----周期扣款结果----')
                 logger.info('success')
 
-                #更新agreement
+                # 更新agreement
                 billing_agreement_update_attributes = [
                     {
                         "op": "replace",
@@ -510,7 +526,6 @@ class PaypalCycleNotify(View):
             logger.info(repr(e))
             return HttpResponse('fail', status=500)
 
-
     def do_subscription_break_notify(self, request_dict, request, response):
         logger = logging.getLogger('pay')
         logger.info('--------进入订阅失败,付款失败,暂停--------')
@@ -594,9 +609,7 @@ class PaypalCycleNotify(View):
             logger.info(repr(e))
             return HttpResponse('fail', status=500)
 
-
-
-    def get_plan_desc(self,plan_id):
+    def get_plan_desc(self, plan_id):
         paypalrestsdk.configure(PAYPAL_CRD)
         billing_plan = paypalrestsdk.BillingPlan.find(plan_id)
         print("Got Billing Plan Details for Billing Plan[%s]" % (billing_plan.id))
@@ -626,24 +639,26 @@ class payCycle(View):
         if operation is None:
             return response.json(444, 'error path')
         elif operation == 'queryPayCycle':  # paypal成功订阅回调
-            return self.do_query_pay_cycle(request_dict,userID, response)
+            return self.do_query_pay_cycle(request_dict, userID, response)
         elif operation == 'cancelPayCycle':  # 取消自动续费
-            return self.do_cancel_pay_cycle(request_dict,userID, response)
+            return self.do_cancel_pay_cycle(request_dict, userID, response)
+
     def do_query_pay_cycle(self, request_dict, userID, response):
         lang = request_dict.get('lang', 'en')
-        uid = request_dict.get('uid',None)
-        orderObject = Order_Model.objects.filter(userID=userID,status=1,rank__lang__lang=lang).annotate(rank__title=F('rank__lang__title'), rank__content=F('rank__lang__content'))
+        uid = request_dict.get('uid', None)
+        orderObject = Order_Model.objects.filter(userID=userID, status=1, rank__lang__lang=lang).annotate(
+            rank__title=F('rank__lang__title'), rank__content=F('rank__lang__content'))
         if uid:
             orderObject = orderObject.filter(UID=uid)
-        orderObject = orderObject.filter(~Q(agreement_id = ''))
+        orderObject = orderObject.filter(~Q(agreement_id=''))
         if not orderObject.exists():
-            return response.json(0, {'data':[], 'count': 0})
+            return response.json(0, {'data': [], 'count': 0})
         orderQuery = orderObject.values("orderID", "UID", "channel", "desc", "price", "currency",
-                "addTime",
-                "updTime", "paypal", "rank__day", "payType",
-                "rank__price", "status",
-                "rank__lang__content", "rank__lang__title", "rank__currency",
-                "rank_id", "rank__expire","agreement_id").order_by('addTime')
+                                        "addTime",
+                                        "updTime", "paypal", "rank__day", "payType",
+                                        "rank__price", "status",
+                                        "rank__lang__content", "rank__lang__title", "rank__currency",
+                                        "rank_id", "rank__expire", "agreement_id").order_by('addTime')
         new_data = []
         values = []
         for d in orderQuery:
@@ -656,7 +671,7 @@ class payCycle(View):
     def do_cancel_pay_cycle(self, request_dict, userID, response):
         orderID = request_dict.get('orderID', 'None')
         orderObject = Order_Model.objects.filter(orderID=orderID)
-        orderObject = orderObject.filter(~Q(agreement_id = '')).values("agreement_id")
+        orderObject = orderObject.filter(~Q(agreement_id='')).values("agreement_id")
         if not orderObject.exists():
             return response.json(800)
 
@@ -675,15 +690,3 @@ class payCycle(View):
                 return response.json(10052)
         except Exception as e:
             return response.json(10052)
-
-
-
-
-
-
-
-
-
-
-
-

+ 2 - 2
Controller/UserManger.py

@@ -183,9 +183,9 @@ class getAvatarView(TemplateView):
         return self.getAvatar(filePath)
 
     def get(self, request, *args, **kwargs):
-        request.encoding = 'gb2312'
+        request.encoding = 'utf-8'
         filePath = kwargs.get('filePath', '')
-        filePath.encode(encoding='gb2312', errors='strict')
+        filePath.encode(encoding='utf-8', errors='strict')
         return self.getAvatar(filePath)
 
     def getAvatar(self, filePath):

+ 1 - 0
Model/models.py

@@ -2113,6 +2113,7 @@ class DeviceDomainModel(models.Model):
     ip = models.CharField(default='', max_length=32, verbose_name='ip')
     country_name = models.CharField(max_length=20, default='', verbose_name='国家名')
     api = models.CharField(max_length=50, default='', verbose_name='使用的域名')
+    region_id = models.SmallIntegerField(default=0, verbose_name='地区id')
     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'更新时间')
 

+ 20 - 0
Service/CommonService.py

@@ -571,3 +571,23 @@ GCqvlyw5dfxNA+EtxNE2wCW/LW7ENJlACgcfgPlBZtpLheWoZB/maw4=
             if serial_number:
                 return serial_number
         return uid
+
+    # 根据序列号查询uid,存在则返回uid,否则返回序列号
+    @staticmethod
+    def query_uid_with_serial(serial_number):
+        device_info_qs = Device_Info.objects.filter(serial_number=serial_number).values('UID')
+        if device_info_qs.exists():
+            uid = device_info_qs[0]['UID']
+            if uid:
+                return uid
+        return serial_number
+
+    # 根据企业标识返回物品名
+    @staticmethod
+    def get_thing_name(company_mark, thing_name_suffix):
+        if company_mark == '11A':
+            return 'Ansjer_Device_' + thing_name_suffix
+        elif company_mark == '11L':
+            return 'Loocam_Device_' + thing_name_suffix
+        else:
+            return thing_name_suffix