فهرست منبع

Merge branch 'dev' into cloud_storage_dev

lang 3 سال پیش
والد
کامیت
ff6fa4285a

+ 0 - 2
AdminController/MenuController.py

@@ -60,10 +60,8 @@ class MenuView(View):
                 return response.json(404)
 
     def getList(self, userID, request_dict, response):
-        role_qs = Role.objects.filter(device_user=userID)
         menu_qs = MenuModel.objects.filter(parentId=0)
         list = []
-        i = 0
         for menu in menu_qs:
             list.append(
                 {

+ 14 - 5
AdminController/ServeManagementController.py

@@ -516,6 +516,7 @@ class serveManagement(View):
                 'create_time',
                 'valid_time',
                 'is_activate',
+                'is_down',
                 'rank__id',
                 'rank__title',
                 'order',
@@ -536,7 +537,7 @@ class serveManagement(View):
         order = request_dict.get('order', None)
         cdk_list = []
         sm_qs = Store_Meal.objects.filter(
-            pay_type__payment='cdk_pay', bucket__mold=mold)
+            pay_type__payment='cdk_pay', bucket__mold=mold, is_show=0)
         if sm_qs.exists:
             rank = sm_qs[0].id
             for i in range(int(cdk_num)):
@@ -548,6 +549,7 @@ class serveManagement(View):
                     create_time=nowTime,
                     valid_time=0,
                     is_activate=0,
+                    is_down=0,
                     rank_id=rank,
                     order=order,
                 )
@@ -576,17 +578,16 @@ class serveManagement(View):
         if region == 'cn':
             # 下载国内未使用激活码
             content += '激活码(国内)\n'
-            cdk_inactivate_qs = CDKcontextModel.objects.filter(
-                is_activate=0, rank__bucket__mold=0).values('cdk')
+            cdk_inactivate_qs = CDKcontextModel.objects.filter(is_down=0, is_activate=0, rank__bucket__mold=0, rank__is_show=0).values('cdk')
         else:
             # 下载国外未使用激活码
             content += '激活码(国外)\n'
-            cdk_inactivate_qs = CDKcontextModel.objects.filter(
-                is_activate=0, rank__bucket__mold=1).values('cdk')
+            cdk_inactivate_qs = CDKcontextModel.objects.filter(is_down=0, is_activate=0, rank__bucket__mold=1, rank__is_show=0).values('cdk')
         for cdk_inactivate in cdk_inactivate_qs:
             content += cdk_inactivate['cdk'] + '\n'
         # print(content)
 
+        cdk_inactivate_qs.update(is_down=1)
         response = StreamingHttpResponse(content)
         response['Content-Type'] = 'application/octet-stream'
         response['Content-Disposition'] = 'attachment;filename="CDK.txt"'
@@ -905,6 +906,13 @@ class serveManagement(View):
         # 日志表查询
         logTimeRange = request_dict.getlist('logTimeRange[]', 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:
             uid_bucket_qs = UID_Bucket.objects.all()
             if uid:
@@ -965,6 +973,7 @@ class serveManagement(View):
                     time__lte=logEndTime)
             list_data = []
             count = uid_bucket_qs.count()
+            uid_bucket_qs = uid_bucket_qs.order_by('-addTime')[(page - 1) * line:page * line]
             for uid_bucket in uid_bucket_qs:
                 data = {
                     'id': uid_bucket.id,

+ 114 - 40
AdminController/UserManageController.py

@@ -16,6 +16,7 @@ import traceback
 import time
 import logging
 import jwt
+import oss2
 import simplejson
 import simplejson as json
 import requests
@@ -29,10 +30,11 @@ 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 Ansjer.config import AuthCode_Expire, SERVER_DOMAIN, APNS_CONFIG, JPUSH_CONFIG, FCM_CONFIG, TUTK_PUSH_DOMAIN, \
+    OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET
 from Controller.CheckUserData import DataValid, date_handler, RandomStr
 from Model.models import Device_User, Role, UidPushModel, UserOauth2Model, UserExModel, Device_Info, UidSetModel, \
-    UserAppFrequencyModel, CountryIPModel, CountryModel, UidChannelSetModel, MenuModel
+    UserAppFrequencyModel, CountryIPModel, CountryModel, UidChannelSetModel, MenuModel, FeedBackModel, StatResModel
 from Object.AWS.SesClassObject import SesClassObject
 from Object.AliSmsObject import AliSmsObject
 from Object.RedisObject import RedisObject
@@ -214,7 +216,7 @@ class GetList(TemplateView):
         role_qs =Role.objects.filter(device_user=userID)
         menu_qs = MenuModel.objects.filter(parentId=0,role__in=role_qs,menutype=1);
         list = []
-        i = 0
+
         for menu in menu_qs:
             list.append(
                 {
@@ -241,43 +243,49 @@ class GetList(TemplateView):
                 }
             )
         menu_qs = MenuModel.objects.filter(role__in=role_qs,menutype=1)
-        menulist = self.menulist(menu_qs, list)
-
-        return response.json(0, {'list':menulist})
-
-    def menulist(self,menu_qs,list):
-        for menulist in list:
-            for menu in menu_qs:
-                if menulist['id'] == menu.parentId:
-                    if 'children' not in menulist:
-                        menulist['children'] = []
-                    menulist['children'].append(
-                        {
-                        'id': menu.id,
-                        'parentId': menu.parentId,
-                        'path': menu.path,
-                        'name': menu.name,
-                        'component': menu.component,
-                        'meta': {
-                                'hidden': menu.hidden,
-                                'levelHidden': menu.levelHidden,
-                                'title': menu.title,
-                                'icon': menu.icon,
-                                'isCustomSvg': menu.isCustomSvg,
-                                'noKeepAlive': menu.noKeepAlive,
-                                'noClosable': menu.noClosable,
-                                'badge': menu.badge,
-                                'tabHidden': menu.tabHidden,
-                                'activeMenu': menu.activeMenu,
-                                'dot': menu.dot,
-                                'dynamicNewTab': menu.dynamicNewTab,
-                                'sort': menu.sort
-                            }
-                        }
-                    )
-                    self.menulist(menu_qs,menulist['children'])
-
-        return list
+        menulist = []
+        for objlist in list:
+            menulist.append(self.menulist(menu_qs, objlist))
+        return response.json(0, {'list': menulist})
+
+    def menulist(self, menu_qs, objlist):
+        if objlist is None:
+            return
+        for menu in menu_qs:
+            if objlist['id'] == menu.parentId:
+                if 'children' not in objlist:
+                    objlist['children'] = []
+
+                obj = {
+                    'id': menu.id,
+                    'parentId': menu.parentId,
+                    'path': menu.path,
+                    'name': menu.name,
+                    'component': menu.component,
+                    'menutype': menu.menutype,
+                    'menu_code': menu.menu_code,
+                    'meta': {
+                        'hidden': menu.hidden,
+                        'levelHidden': menu.levelHidden,
+                        'title': menu.title,
+                        'icon': menu.icon,
+                        'isCustomSvg': menu.isCustomSvg,
+                        'noKeepAlive': menu.noKeepAlive,
+                        'noClosable': menu.noClosable,
+                        'badge': menu.badge,
+                        'tabHidden': menu.tabHidden,
+                        'activeMenu': menu.activeMenu,
+                        'dot': menu.dot,
+                        'dynamicNewTab': menu.dynamicNewTab,
+                        'sort': menu.sort
+                    }
+                }
+                objlist['children'].append(
+                    obj
+                )
+                self.menulist(menu_qs, obj)
+
+        return objlist
 
 
 
@@ -311,6 +319,8 @@ class UserManagement(View):
                 return self.doDelete(userID, request_dict, response)
             elif operation == 'resetPassword':
                 return self.resetPassword(request_dict, response)
+            elif operation == 'getFeedbackList':
+                return self.getFeedbackList(request_dict, response)
             else:
                 return response.json(404)
 
@@ -446,3 +456,67 @@ class UserManagement(View):
         except Exception as e:
             print(e)
             return response.json(500, repr(e))
+
+    def getFeedbackList(self, request_dict, response):
+        status = request_dict.get('status', 0)
+        username = request_dict.get('username', 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:
+            filter_data = {}
+            if status or username:
+                if status:
+                    filter_data['status'] = int(status)
+                if username:
+                    filter_data['userID_id'] = ModelService.get_userID_byname(username)
+            feed_back_qs = FeedBackModel.objects.filter()
+            if filter_data:
+                feed_back_qs = feed_back_qs.filter(**filter_data)
+            total = feed_back_qs.count()
+            feed_backs = feed_back_qs[(page - 1) * line:page * line]. values(
+                'id',
+                'userID__username',
+                'userID__phone',
+                'userID__userEmail',
+                'content',
+                'addTime',
+                'status',
+                'type',
+                'app',
+                'app_version',
+                'phone_model',
+                'os_version',
+                'uid',
+                'appBundleId',
+                'score')
+
+            feed_back_id_list = [feed_back['id'] for feed_back in feed_backs]
+            stat_res_qs = StatResModel.objects.filter(
+                feedbackmodel__id__in=feed_back_id_list).values(
+                'name', 'feedbackmodel__id')
+            auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
+            bucket = oss2.Bucket(
+                auth, 'oss-cn-hongkong.aliyuncs.com', 'statres')
+            feed_back_list = []
+            for feed_back in feed_backs:
+                feed_back['img_url'] = []
+                for stat_res in stat_res_qs:
+                    if stat_res['feedbackmodel__id'] == feed_back['id']:
+                        obj = 'feedback/' + stat_res['name']
+                        img_url = bucket.sign_url('GET', obj, 3600)
+                        feed_back['img_url'].append(img_url)
+                        if not feed_back['userID__username']:
+                            feed_back['userID__username'] = feed_back['userID__userEmail'] if feed_back[
+                                'userID__userEmail'] else feed_back['userID__phone']
+                feed_back_list.append(feed_back)
+            return response.json(0, {'list': feed_back_list, 'total': total})
+        except Exception as e:
+            print(e)
+            return response.json(500, repr(e))
+

+ 124 - 0
Ansjer/eur_config/config_formal.py

@@ -0,0 +1,124 @@
+#!/usr/bin/env python3  
+# -*- coding: utf-8 -*-  
+"""
+@Copyright (C) ansjer cop Video Technology Co.,Ltd.All rights reserved.
+@AUTHOR: ASJRD018
+@NAME: AnsjerFormal
+@software: PyCharm
+@DATE: 2019/10/16 9:45
+@Version: python3.6
+@MODIFY DECORD:ansjer dev
+@file: config_formal.py
+@Contact: chanjunkai@163.com
+"""
+import os
+
+NGINX_RTMP_STAT = 'http://www.dvema.com/stat'
+SERVER_DOMAIN_SSL = 'https://www.dvema.com/'
+SERVER_DOMAIN = 'http://www.dvema.com/'
+DOMAIN_HOST = 'www.dvema.com'
+SERVER_HOST = 'backendserver.5tgle2.0001.usw1.cache.amazonaws.com'
+PUSH_REDIS_ADDRESS = 'pushredis.5tgle2.0001.usw1.cache.amazonaws.com'
+# PAYPAL_CRD = {
+#     "mode": "live",  # sandbox or live
+#     "client_id": "AdSRd6WBn-qLl9OiQHQuNYTDFSx0ZX0RUttqa58au8bPzoGYQUrt8bc6591RmH8_pEAIPijdvVYSVXyI",
+#     "client_secret": "ENT-J08N3Fw0B0uAokg4RukljAwO9hFHPf8whE6-Dwd8oBWJO8AWMgpdTKpfB1pOy89t4bsFEzMWDowm"
+# }
+PAYPAL_CRD = {
+    "mode": "sandbox",  # sandbox or live
+    "client_id": "AVLoQVq3xHZ6FrF4mxHwlCPgVBAw4Fw5RtMkuxmYd23SkUTIY643n2g3KdK-Al8wV05I28lza5uoQbAA",
+    "client_secret": "EO8kRc8yioDk0i2Qq-QMcVFfwkmyMJorTvBSLDTnxDJJ_wb9VoM_0jkUY9iEng2Flp1ze8wQOGpH5nB2"
+}
+
+DETECT_PUSH_DOMAIN = 'http://push.dvema.com/'
+DETECT_PUSH_DOMAINS = 'https://push.dvema.com/'
+DETECT_PUSH_DOMAIN_JIUAN = 'http://jiuan.push.dvema.com/'
+DETECT_PUSH_DOMAINS_JIUAN = 'https://jiuan.push.dvema.com/'
+# 数据库dyanamo品牌日志数据库
+USER_BRAND = 'user_brand'
+USER_BRAND_ALL = 'user_brand_all'
+
+# type =2
+JPUSH_CONFIG = {
+    'com.ansjer.accloud_ab': {
+        'Key': 'f0dc047e5e53fd14199de5b0',
+        'Secret': 'aa7f7db33e9f0a7f3871aa1c'},
+    'com.ansjer.adcloud_ab': {
+        'Key': '76d97b535185114985608234',
+        'Secret': 'c9a92b301043cc9c52778692'},
+    'com.ansjer.zccloud_ab': {
+        'Key': 'd9924f56d3cc7c6017965130',
+        'Secret': '869d832d126a232f158b5987'},
+    'com.ansjer.loocamccloud_ab': {
+        'Key': 'd1cc44797b4642b0e05304fe',
+        'Secret': 'c3e8b4ca8c576de61401e56a'},
+    'com.ansjer.loocamdcloud_ab': {
+        'Key': '76d97b535185114985608234',
+        'Secret': 'c9a92b301043cc9c52778692'},
+    'com.ansjer.zccloud_a': {
+        'Key': '57de2a80d68bf270fd6bdf5a',
+        'Secret': '3d354eb6a0b49c2610decf42'},
+    'com.ansjer.accloud_a': {
+        'Key': 'ff95ee685f49c0dc4013347b',
+        'Secret': 'de2c20959f5516fdeeafe78e'},
+    'com.ansjer.adcloud_a': {
+        'Key': '2e47eb1aee9b164460df3668',
+        'Secret': 'b9137d8d684bc248f1809b6d'},
+    'com.ansjer.loocamccloud_a': {
+        'Key': '23c9213215c7ca0ec945629b',
+        'Secret': '81e4b1e859cc8387e2e6c431'},
+    'com.ansjer.loocamdcloud_a': {
+        'Key': '1dbdd60a16e9892d6f68a073',
+        'Secret': '80a97690e7e043109059b403'},
+    'com.ansjer.customizedb_a': {
+        'Key': '9d79630aa49adfa291fe2568',
+        'Secret': '4d8ff52f88136561875a0212'},
+    'com.ansjer.customizedd_a': {
+        'Key': '8fc4f495685bde53341ee25d',
+        'Secret': 'f1da11fa466509fa2670fb66',
+    }
+}
+# type =1
+FCM_CONFIG = {
+    'com.ansjer.zccloud_a': 'AAAAb9YP3rk:APA91bHu8u-CTpcd0g6lKPo0WNVqCi8jZub1cPPbSAY9AucT1HxlF65ZDUko9iG8q2ch17bwu9YWHpK1xI1gHSRXCslLvZlXEmHZC0AG3JKg15XuUvlFKACIajUFV-pOeGRT8tM6-31I',
+    'com.ansjer.loocamccloud_a': 'AAAAb9YP3rk:APA91bFCgd-kbVmpK4EVpfdHH_PJZQCYTkOGnTZdIuBWEz2r7aMRsJYHOH3sB-rwcbaRWgnufTyjX9nGQxb6KxQbWVk4ah_H-M3IqGh6Mb60WQQAuR33V6g_Jes5pGL6ViuIxGHqVMaR',
+    'com.ansjer.loocamdcloud_a': 'AAAAb9YP3rk:APA91bGw2I2KMD4i-5T7nZO_wB8kuAOuqgyqe5rxmY-W5qkpYEx9IL2IfmC_qf6B_xOyjIDDSjckvMo-RauN__SEoxvAkis7042GRkoKpw7cjZ_H8lC-d50PC0GclPzccrOGFusyKbFY',
+    'com.ansjer.customizedb_a': 'AAAAb9YP3rk:APA91bE7kI4vcm-9h_CJNFlOZfc-xwP4Btn6AnjOrwoKV6fgYN7fdarkO76sYxVZiAbDnxsFfOJyP7vQfwyan6mdjuyD5iHdt_XgO22VqniC0vA1V4GJiCS8Tp7LxIX8JVKZl9I_Powt',
+    'com.ansjer.customizeda_a': 'AAAAb9YP3rk:APA91bF0HzizVWDc6dKzobY9fsaKDK4veqkOZehDXshVXs8pEEvNWjR_YWbhP60wsRYCHCal8fWN5cECVOWNMMzDsfU88Ty2AUl8S5FtZsmeDTkoGntQOswBr8Ln7Fm_LAp1VqTf9CpM',
+    'com.ansjer.customizedd_a': 'AAAAb9YP3rk:APA91bHkxOozJWBrlv3eNT0PgwosYENI9aM4Zuzd418cX-iKkpa1zFNC5MkNDKApx1KH4fhmAfaJ6IMRZ0nj5GIxCpstDYCaZWwgC7-etqfSxG5JAq8LOwJx0o_1tUZqwjIic8ztsg0o',
+    'com.ansjer.adcloud_a': 'AAAAb9YP3rk:APA91bFm06w8b9OKQ0gz0iaWFuRqRIkvgAz6z7Gp3dBU_X-LNGJQd1hc1QR2W7QzBglF8SHtERA45a2lbdLRa5qv7hxfd6W_sJLBK7dA8jklsOQBvy505oUzTwMKWy4TwH-exps9KrhO',
+    'com.ansjer.accloud_a': 'AAAAb9YP3rk:APA91bFm06w8b9OKQ0gz0iaWFuRqRIkvgAz6z7Gp3dBU_X-LNGJQd1hc1QR2W7QzBglF8SHtERA45a2lbdLRa5qv7hxfd6W_sJLBK7dA8jklsOQBvy505oUzTwMKWy4TwH-exps9KrhO',
+    'com.ansjer.zccloud_ab': 'AAAAb9YP3rk:APA91bHu8u-CTpcd0g6lKPo0WNVqCi8jZub1cPPbSAY9AucT1HxlF65ZDUko9iG8q2ch17bwu9YWHpK1xI1gHSRXCslLvZlXEmHZC0AG3JKg15XuUvlFKACIajUFV-pOeGRT8tM6-31I',
+}
+APNS_CONFIG = {
+    'com.ansjer.loocamccloud': {
+        'pem_path': 'Ansjer/file/apns_pem/lcc-dev.pem',
+    },
+    'com.ansjer.zosidcloud': {
+        'pem_path': 'Ansjer/file/apns_pem/zosidcloud-dev.pem',
+    },
+    'com.ansjer.customizedb': {
+        'pem_path': 'Ansjer/file/apns_pem/customizedb-dev.pem',
+    },
+    'com.ansjer.customizeda': {
+        'pem_path': 'Ansjer/file/apns_pem/customizeda-dev.pem',
+    },
+    'com.ansjer.zccloud': {
+        'pem_path': 'Ansjer/file/apns_pem/zccloud-dev.pem',
+    },
+    'com.ansjer.accloud': {
+        'pem_path': 'Ansjer/file/apns_pem/accloud-dev.pem',
+    },
+    'com.ansjer.customizede': {
+        'pem_path': 'Ansjer/file/apns_pem/ZhouShi-dev.pem',
+    },
+    'com.ansjer.customizedc': {
+        'pem_path': 'Ansjer/file/apns_pem/customizedc.pem',
+    }
+}
+APNS_MODE = 'prod'
+# 根路径
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+SERVER_TYPE = os.environ.get('DJANGO_SETTINGS_MODULE')
+
+TUTK_PUSH_DOMAIN = 'http://push.iotcplatform.com/tpns'

+ 67 - 0
Ansjer/eur_config/config_local.py

@@ -0,0 +1,67 @@
+#!/usr/bin/env python3  
+# -*- coding: utf-8 -*-  
+"""
+@Copyright (C) ansjer cop Video Technology Co.,Ltd.All rights reserved.
+@AUTHOR: ASJRD018
+@NAME: AnsjerFormal
+@software: PyCharm
+@DATE: 2019/10/16 9:45
+@Version: python3.6
+@MODIFY DECORD:ansjer dev
+@file: config_local.py
+@Contact: chanjunkai@163.com
+"""
+import os
+
+# token的secret
+OAUTH_ACCESS_TOKEN_SECRET = 'local_a+jbgnw%@1%zy^=@dn62%'
+OAUTH_REFRESH_TOKEN_SECRET = 'local_r+jbgnw%@1%zy^=@dn62%'
+
+NGINX_RTMP_STAT = 'http://127.0.0.1:8077/stat'
+SERVER_DOMAIN = 'http://127.0.0.1:8077/'
+SERVER_DOMAIN_SSL = 'http://127.0.0.1:8077/'
+SERVER_HOST = '127.0.0.1'
+DOMAIN_HOST = '127.0.0.1'
+# SERVER_HOST = '127.0.0.1'
+# DOMAIN_HOST = '127.0.0.1'
+RTMP_PUSH_URL = 'rtmp://127.0.0.1:1935/hls'
+PAYPAL_CRD = {
+    "mode": "sandbox",  # sandbox or live
+    "client_id": "AeuhR7FHisO-lOd2OwtzyDu7PSLMmDZoDLgmzuEQ12WCtTu_8Z1AzcD4gG5SnymnuvJs-n5KBB8H9Z_G",
+    "client_secret": "EGkMCB3RWTcUGJGDYahJ9mCO0AQzEn2AvFfx1GAFjfyyn7-8a0NObcZks89QorlFpvNWTsDXVa2INRNM"
+}
+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/'
+DETECT_PUSH_DOMAINS_JIUAN = 'https://jiuan.push.dvema.com/'
+# 数据库dyanamo品牌日志数据库
+USER_BRAND = 'test_user_brand'
+USER_BRAND_ALL = 'test_user_brand_all'
+
+
+APNS_CONFIG = {
+    'com.ansjer.loocamccloud': {
+        'pem_path': 'Ansjer/file/apns_pem/lcc-dev.pem',
+    },
+    'com.ansjer.zosidcloud': {
+        'pem_path': 'Ansjer/file/apns_pem/zosidcloud-dev.pem',
+    },
+    'com.ansjer.customizedb': {
+        'pem_path': 'Ansjer/file/apns_pem/customizedb-dev.pem',
+    },
+    'com.ansjer.customizeda': {
+        'pem_path': 'Ansjer/file/apns_pem/customizeda-dev.pem',
+    },
+    'com.ansjer.zccloud': {
+        'pem_path': 'Ansjer/file/apns_pem/zccloud-dev.pem',
+    },
+    'com.ansjer.accloud': {
+        'pem_path': 'Ansjer/file/apns_pem/accloud-dev.pem',
+    },
+    'com.ansjer.customizede': {
+        'pem_path': 'Ansjer/file/apns_pem/ZhouShi-dev.pem',
+    },
+}
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+APNS_MODE = 'dev'
+TUTK_PUSH_DOMAIN = 'http://push.iotcplatform.com/tpns'

+ 134 - 0
Ansjer/eur_config/config_test.py

@@ -0,0 +1,134 @@
+#!/usr/bin/env python3  
+# -*- coding: utf-8 -*-  
+"""
+@Copyright (C) ansjer cop Video Technology Co.,Ltd.All rights reserved.
+@AUTHOR: ASJRD018
+@NAME: AnsjerFormal
+@software: PyCharm
+@DATE: 2019/10/16 9:45
+@Version: python3.6
+@MODIFY DECORD:ansjer dev
+@file: config_test.py
+@Contact: chanjunkai@163.com
+"""
+import os
+
+NGINX_RTMP_STAT = 'http://test.dvema.com/stat'
+SERVER_DOMAIN = 'http://test.dvema.com/'
+SERVER_DOMAIN_SSL = 'https://test.dvema.com/'
+
+
+# token的secret
+OAUTH_ACCESS_TOKEN_SECRET = 'test_a+jbgnw%@1%zy^=@dn62%'
+OAUTH_REFRESH_TOKEN_SECRET = 'test_r+jbgnw%@1%zy^=@dn62%'
+
+DOMAIN_HOST = 'test.dvema.com'
+SERVER_HOST = 'localhost'
+PAYPAL_CRD = {
+    # "mode": "live",  # sandbox or live
+    # "client_id": "AdSRd6WBn-qLl9OiQHQuNYTDFSx0ZX0RUttqa58au8bPzoGYQUrt8bc6591RmH8_pEAIPijdvVYSVXyI",
+    # "client_secret": "ENT-J08N3Fw0B0uAokg4RukljAwO9hFHPf8whE6-Dwd8oBWJO8AWMgpdTKpfB1pOy89t4bsFEzMWDowm"
+    # "mode": "sandbox",  # sandbox or live
+    # "client_id": "AeuhR7FHisO-lOd2OwtzyDu7PSLMmDZoDLgmzuEQ12WCtTu_8Z1AzcD4gG5SnymnuvJs-n5KBB8H9Z_G",
+    # "client_secret": "EGkMCB3RWTcUGJGDYahJ9mCO0AQzEn2AvFfx1GAFjfyyn7-8a0NObcZks89QorlFpvNWTsDXVa2INRNM"
+    "mode": "sandbox",  # sandbox or live
+    "client_id": "AVLoQVq3xHZ6FrF4mxHwlCPgVBAw4Fw5RtMkuxmYd23SkUTIY643n2g3KdK-Al8wV05I28lza5uoQbAA",
+    "client_secret": "EO8kRc8yioDk0i2Qq-QMcVFfwkmyMJorTvBSLDTnxDJJ_wb9VoM_0jkUY9iEng2Flp1ze8wQOGpH5nB2"
+}
+# PAYPAL_CRD = {
+#     "mode": "sandbox",  # sandbox or live
+#     "client_id": "ATXTpWs8sajNYeU46jNs1yzpy4H_o3RRrGVIJ8Tscc312BjMx12cpRgCucfWX07a4G6GbK8hzElB04Pd",
+#     "client_secret": "EHcnfrpL1o1ev9WnlQ-C1uymeRKDoJ6li6Y0d6iHoRGj4u8Sx5lSEEH774XphP4LQZ0DrDUdvxbux0T2"
+# }
+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/'
+DETECT_PUSH_DOMAINS_JIUAN = 'https://jiuan.push.dvema.com/'
+# 数据库dyanamo品牌日志数据库
+USER_BRAND = 'test_user_brand'
+USER_BRAND_ALL = 'test_user_brand_all'
+
+# type =2
+JPUSH_CONFIG = {
+    'com.ansjer.accloud_ab': {
+        'Key': 'f0dc047e5e53fd14199de5b0',
+        'Secret': 'aa7f7db33e9f0a7f3871aa1c'},
+    'com.ansjer.adcloud_ab': {
+        'Key': '76d97b535185114985608234',
+        'Secret': 'c9a92b301043cc9c52778692'},
+    'com.ansjer.zccloud_ab': {
+        'Key': 'd9924f56d3cc7c6017965130',
+        'Secret': '869d832d126a232f158b5987'},
+    'com.ansjer.loocamccloud_ab': {
+        'Key': 'd1cc44797b4642b0e05304fe',
+        'Secret': 'c3e8b4ca8c576de61401e56a'},
+    'com.ansjer.loocamdcloud_ab': {
+        'Key': '76d97b535185114985608234',
+        'Secret': 'c9a92b301043cc9c52778692'},
+    'com.ansjer.zccloud_a': {
+        'Key': '57de2a80d68bf270fd6bdf5a',
+        'Secret': '3d354eb6a0b49c2610decf42'},
+    'com.ansjer.accloud_a': {
+        'Key': 'ff95ee685f49c0dc4013347b',
+        'Secret': 'de2c20959f5516fdeeafe78e'},
+    'com.ansjer.adcloud_a': {
+        'Key': '2e47eb1aee9b164460df3668',
+        'Secret': 'b9137d8d684bc248f1809b6d'},
+    'com.ansjer.loocamccloud_a': {
+        'Key': '23c9213215c7ca0ec945629b',
+        'Secret': '81e4b1e859cc8387e2e6c431'},
+    'com.ansjer.loocamdcloud_a': {
+        'Key': '1dbdd60a16e9892d6f68a073',
+        'Secret': '80a97690e7e043109059b403'},
+    'com.ansjer.customizedb_a': {
+        'Key': '9d79630aa49adfa291fe2568',
+        'Secret': '4d8ff52f88136561875a0212'},
+    'com.ansjer.customizedd_a': {
+        'Key': '8fc4f495685bde53341ee25d',
+        'Secret': 'f1da11fa466509fa2670fb66',
+    }
+}
+# type =1
+FCM_CONFIG = {
+    'com.ansjer.zccloud_a': 'AAAAb9YP3rk:APA91bHu8u-CTpcd0g6lKPo0WNVqCi8jZub1cPPbSAY9AucT1HxlF65ZDUko9iG8q2ch17bwu9YWHpK1xI1gHSRXCslLvZlXEmHZC0AG3JKg15XuUvlFKACIajUFV-pOeGRT8tM6-31I',
+    'com.ansjer.loocamccloud_a': 'AAAAb9YP3rk:APA91bFCgd-kbVmpK4EVpfdHH_PJZQCYTkOGnTZdIuBWEz2r7aMRsJYHOH3sB-rwcbaRWgnufTyjX9nGQxb6KxQbWVk4ah_H-M3IqGh6Mb60WQQAuR33V6g_Jes5pGL6ViuIxGHqVMaR',
+    'com.ansjer.loocamdcloud_a': 'AAAAb9YP3rk:APA91bGw2I2KMD4i-5T7nZO_wB8kuAOuqgyqe5rxmY-W5qkpYEx9IL2IfmC_qf6B_xOyjIDDSjckvMo-RauN__SEoxvAkis7042GRkoKpw7cjZ_H8lC-d50PC0GclPzccrOGFusyKbFY',
+    'com.ansjer.customizedb_a': 'AAAAb9YP3rk:APA91bE7kI4vcm-9h_CJNFlOZfc-xwP4Btn6AnjOrwoKV6fgYN7fdarkO76sYxVZiAbDnxsFfOJyP7vQfwyan6mdjuyD5iHdt_XgO22VqniC0vA1V4GJiCS8Tp7LxIX8JVKZl9I_Powt',
+    'com.ansjer.customizeda_a': 'AAAAb9YP3rk:APA91bF0HzizVWDc6dKzobY9fsaKDK4veqkOZehDXshVXs8pEEvNWjR_YWbhP60wsRYCHCal8fWN5cECVOWNMMzDsfU88Ty2AUl8S5FtZsmeDTkoGntQOswBr8Ln7Fm_LAp1VqTf9CpM',
+    'com.ansjer.customizedd_a': 'AAAAb9YP3rk:APA91bHkxOozJWBrlv3eNT0PgwosYENI9aM4Zuzd418cX-iKkpa1zFNC5MkNDKApx1KH4fhmAfaJ6IMRZ0nj5GIxCpstDYCaZWwgC7-etqfSxG5JAq8LOwJx0o_1tUZqwjIic8ztsg0o',
+    'com.ansjer.adcloud_a': 'AAAAb9YP3rk:APA91bFm06w8b9OKQ0gz0iaWFuRqRIkvgAz6z7Gp3dBU_X-LNGJQd1hc1QR2W7QzBglF8SHtERA45a2lbdLRa5qv7hxfd6W_sJLBK7dA8jklsOQBvy505oUzTwMKWy4TwH-exps9KrhO',
+    'com.ansjer.accloud_a': 'AAAAb9YP3rk:APA91bFm06w8b9OKQ0gz0iaWFuRqRIkvgAz6z7Gp3dBU_X-LNGJQd1hc1QR2W7QzBglF8SHtERA45a2lbdLRa5qv7hxfd6W_sJLBK7dA8jklsOQBvy505oUzTwMKWy4TwH-exps9KrhO',
+    'com.ansjer.zccloud_ab': 'AAAAb9YP3rk:APA91bHu8u-CTpcd0g6lKPo0WNVqCi8jZub1cPPbSAY9AucT1HxlF65ZDUko9iG8q2ch17bwu9YWHpK1xI1gHSRXCslLvZlXEmHZC0AG3JKg15XuUvlFKACIajUFV-pOeGRT8tM6-31I',
+}
+APNS_CONFIG = {
+    'com.ansjer.loocamccloud': {
+        'pem_path': 'Ansjer/file/apns_pem/lcc-dev.pem',
+    },
+    'com.ansjer.zosidcloud': {
+        'pem_path': 'Ansjer/file/apns_pem/zosidcloud-dev.pem',
+    },
+    'com.ansjer.customizedb': {
+        'pem_path': 'Ansjer/file/apns_pem/customizedb-dev.pem',
+    },
+    'com.ansjer.customizeda': {
+        'pem_path': 'Ansjer/file/apns_pem/customizeda-dev.pem',
+    },
+    'com.ansjer.zccloud': {
+        'pem_path': 'Ansjer/file/apns_pem/zccloud-dev.pem',
+    },
+    'com.ansjer.accloud': {
+        'pem_path': 'Ansjer/file/apns_pem/accloud-dev.pem',
+    },
+    'com.ansjer.customizede': {
+        'pem_path': 'Ansjer/file/apns_pem/ZhouShi-dev.pem',
+    },
+    'com.ansjer.customizedc': {
+        'pem_path': 'Ansjer/file/apns_pem/customizedc.pem',
+    }
+}
+# 根路径
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+APNS_MODE = 'dev'
+SERVER_TYPE = os.environ.get('DJANGO_SETTINGS_MODULE')
+
+TUTK_PUSH_DOMAIN = 'http://push.iotcplatform.com/tpns'

+ 254 - 0
Ansjer/eur_config/formal_settings.py

@@ -0,0 +1,254 @@
+import os
+from Ansjer.config import BASE_DIR
+
+SECRET_KEY = 'c7ki2_gkg4#sjfm-u1%$s#&n#szf01f*v69rwv2qsf#-zmm@tl'
+# DEBUG = True
+DEBUG = False
+ALLOWED_HOSTS = ['*']
+
+INSTALLED_APPS = [
+    'django.contrib.admin',
+    'django.contrib.auth',
+    'django.contrib.contenttypes',
+    'django.contrib.sessions',
+    'django.contrib.messages',
+    'django.contrib.staticfiles',
+    'corsheaders',
+    'imagekit',
+    'Model',
+]
+
+MIDDLEWARE = [
+    'corsheaders.middleware.CorsMiddleware',
+    'Service.middleware.StatisticsUrlMiddleware',
+    'django.middleware.security.SecurityMiddleware',
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.middleware.common.CommonMiddleware',
+    # 'django.middleware.csrf.CsrfViewMiddleware',
+    'corsheaders.middleware.CorsPostCsrfMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+    'django.contrib.messages.middleware.MessageMiddleware',
+    'django.middleware.clickjacking.XFrameOptionsMiddleware',
+    'django.middleware.security.SecurityMiddleware',
+    'django_global_request.middleware.GlobalRequestMiddleware',
+]
+
+AUTHENTICATION_BACKENDS = (
+    'django.contrib.auth.backends.ModelBackend',  # django default backend
+    'guardian.backends.ObjectPermissionBackend',
+)
+
+ADDR_URL = []
+ANONYMOUS_USER_ID = -1  # 支持匿名用户.
+
+STATIC_URL = '/static/'
+
+# 上传路径根目录
+MEDIA_ROOT = os.path.join(BASE_DIR, 'static/Upgrate')
+# 在浏览器上访问该上传文件的url的前缀
+MEDIA_URL = '/static/Upgrate/'
+ROOT_URLCONF = 'Ansjer.urls'
+LOGIN_URL = '/account/login'
+AUTH_USER_MODEL = 'Model.Device_User'  # 自定义Model
+APPEND_SLASH = False
+
+TEMPLATES = [
+    {
+        'BACKEND': 'django.template.backends.django.DjangoTemplates',
+        # 'DIRS': [BASE_DIR + '/static/templates', ],
+        'DIRS': [BASE_DIR + '/templates', ],
+        'APP_DIRS': True,
+        'OPTIONS': {
+            'context_processors': [
+                'django.template.context_processors.debug',
+                'django.template.context_processors.request',
+                'django.contrib.auth.context_processors.auth',
+                'django.contrib.messages.context_processors.messages',
+            ],
+        },
+    },
+]
+
+WSGI_APPLICATION = 'Ansjer.us_config.formal_wsgi.application'
+
+
+# 服务器类型
+DATABASE_DATA = 'Ansjer81'
+SERVER_HOST = 'database-2.clraczw4p0yj.us-west-1.rds.amazonaws.com'
+DATABASES_USER = 'azrds'
+DATABASES_PASS = 'azrds.x.x'
+
+DATABASE_DATA2 = 'Ansjer81'
+SERVER_HOST2 = 'ansjerpush.clraczw4p0yj.us-west-1.rds.amazonaws.com'
+DATABASES_USER2 = 'azrds'
+DATABASES_PASS2 = 'azrds.x.x'
+
+DATABASES = {
+    'default': {
+        'ENGINE': 'django.db.backends.mysql',
+        'NAME': DATABASE_DATA,
+        'USER': DATABASES_USER,
+        'PASSWORD': DATABASES_PASS,
+        'HOST': SERVER_HOST,
+        'PORT': '3306',
+        'OPTIONS': {'charset': 'utf8mb4', 'use_unicode': True, 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"},
+        'AUTOCOMMIT': True
+    },
+    'mysql02': {
+        'ENGINE': 'django.db.backends.mysql',
+        'NAME': DATABASE_DATA2,
+        'USER': DATABASES_USER2,
+        'PASSWORD': DATABASES_PASS2,
+        'HOST': SERVER_HOST2,
+        'PORT': '3306',
+        'OPTIONS': {'charset': 'utf8mb4', 'use_unicode': True, 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"},
+        'AUTOCOMMIT': True
+    }
+}
+DATABASE_ROUTERS = ['Ansjer.database_router.DatabaseAppsRouter']
+DATABASE_APPS_MAPPING = {
+    'Model': 'default',
+    'db2': 'mysql02',
+}
+
+
+AUTH_PASSWORD_VALIDATORS = [
+    {
+        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
+    },
+    {
+        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
+    },
+    {
+        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
+    },
+    {
+        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
+    },
+]
+
+LANGUAGE_CODE = 'en-us'
+TIME_ZONE = 'Asia/Shanghai'
+# TIME_ZONE = 'UTC'
+USE_I18N = True
+USE_L10N = True
+USE_TZ = True
+
+# 跨域增加忽略
+CORS_ALLOW_CREDENTIALS = True
+CORS_ORIGIN_ALLOW_ALL = True
+# CORS_ORIGIN_WHITELIST = ('*')
+
+CORS_ALLOW_METHODS = (
+    'DELETE',
+    'GET',
+    'OPTIONS',
+    'PATCH',
+    'POST',
+    'PUT',
+    'VIEW',
+)
+
+CORS_ALLOW_HEADERS = (
+    'XMLHttpRequest',
+    'X_FILENAME',
+    'accept',
+    'accept-encoding',
+    'authorization',
+    'content-type',
+    'dnt',
+    'origin',
+    'user-agent',
+    'x-csrftoken',
+    'x-requested-with',
+    'Pragma',
+)
+
+#########################################
+'''
+增加错误信息推送到管理员邮箱
+'''
+# 管理员邮箱
+ADMINS = (
+    ('admin', 'sonalh@foxmail.com'),
+)
+
+# 非空链接,却发生404错误,发送通知MANAGERS
+SEND_BROKEN_LINK_EMAILS = True
+MANAGERS = ADMINS
+
+# Email设置
+EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
+EMAIL_HOST = 'smtp.163.com'  # QQ邮箱SMTP服务器(邮箱需要开通SMTP服务)
+EMAIL_PORT = 25  # QQ邮箱SMTP服务端口
+EMAIL_HOST_USER = 'chanjunkai@163.com'  # 我的邮箱帐号
+EMAIL_HOST_PASSWORD = 'cjk1234'  # 授权码
+EMAIL_SUBJECT_PREFIX = 'website'  # 为邮件标题的前缀,默认是'[django]'
+EMAIL_USE_TLS = True  # 开启安全链接
+DEFAULT_FROM_EMAIL = SERVER_EMAIL = EMAIL_HOST_USER  # 设置发件人
+
+LOGGING = {
+    'version': 1,
+    'disable_existing_loggers': True,
+    'formatters': {
+        'error_format': {
+            # 'format': '{"asctime":"%(asctime)s","thread":"%(threadName)s:%(thread)d","errorline":"%(lineno)d","errorlevel":"%(levelname)s","errorcontent":"%(message)s"}'
+            'format': '%(asctime)s %(threadName)s %(thread)d %(lineno)d %(levelname)s %(message)s'
+        },
+        'standard': {
+            'format': '[%(asctime)s] [%(filename)s:%(lineno)d] [%(module)s:%(funcName)s] '
+                      '[%(levelname)s]- %(message)s'},
+
+    },
+    'filters': {
+    },
+    'handlers': {
+        'mail_admins': {
+            'level': 'ERROR',
+            'class': 'django.utils.log.AdminEmailHandler',
+            'include_html': True,
+        },
+        'default': {
+            'level': 'ERROR',
+            'class': 'logging.handlers.TimedRotatingFileHandler',
+            'filename': BASE_DIR + '/static/log/error/error.log',
+            'backupCount': 30,
+            'when': 'D',
+            'formatter': 'error_format',
+        },
+        'console': {
+            'level': 'ERROR',
+            'class': 'logging.StreamHandler',
+            'formatter': 'error_format'
+        },
+        'info': {
+            'level': 'INFO',
+            'class': 'logging.handlers.TimedRotatingFileHandler',
+            'filename': BASE_DIR + '/static/log/info/info.log',
+            'backupCount': 30,
+            'when': 'D',
+            'formatter': 'standard',
+            'encoding': 'utf-8',
+        },
+    },
+    'loggers': {
+        'django': {
+            'handlers': ['default', 'console'],
+            # 'handlers': ['mail_admins','default','console'],
+            # 'level': 'ERROR',
+            'level': 'ERROR',
+            'propagate': False
+        },
+        # log 调用时需要当作参数传入
+        'info': {
+            'handlers': ['info'],
+            'level':'INFO',
+            'propagate': False
+        }
+        # 'django.db.backends': {
+        #     'handlers': ['console'],
+        #     'propagate': True,
+        #     'level': 'DEBUG',
+        # },
+    }
+}

+ 16 - 0
Ansjer/eur_config/formal_wsgi.py

@@ -0,0 +1,16 @@
+"""
+WSGI config for Ansjer project.
+
+It exposes the WSGI callable as a module-level variable named ``application``.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/dev/howto/deployment/wsgi/
+"""
+
+import os
+
+from django.core.wsgi import get_wsgi_application
+
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Ansjer.us_config.formal_settings")
+
+application = get_wsgi_application()

+ 457 - 0
Ansjer/eur_config/local_settings.py

@@ -0,0 +1,457 @@
+import os
+from Ansjer.config import BASE_DIR
+
+
+SECRET_KEY = 'c7ki2_gkg4#sjfm-u1%$s#&n#szf01f*v69rwv2qsf#-zmm@tl'
+DEBUG = True
+# DEBUG = False
+ALLOWED_HOSTS = ['*']
+
+INSTALLED_APPS = [
+    'django.contrib.admin',
+    'django.contrib.auth',
+    'django.contrib.contenttypes',
+    'django.contrib.sessions',
+    'django.contrib.messages',
+    'django.contrib.staticfiles',
+    'corsheaders',
+    'imagekit',
+    'Model',
+]
+
+MIDDLEWARE = [
+    'corsheaders.middleware.CorsMiddleware',
+    'Service.middleware.StatisticsUrlMiddleware',
+    'django.middleware.security.SecurityMiddleware',
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.middleware.common.CommonMiddleware',
+    # 'django.middleware.csrf.CsrfViewMiddleware',
+    'corsheaders.middleware.CorsPostCsrfMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+    'django.contrib.messages.middleware.MessageMiddleware',
+    'django.middleware.clickjacking.XFrameOptionsMiddleware',
+    'django.middleware.security.SecurityMiddleware',
+    # 'django_global_request.middleware.GlobalRequestMiddleware',
+]
+
+AUTHENTICATION_BACKENDS = (
+    'django.contrib.auth.backends.ModelBackend',  # django default backend
+    'guardian.backends.ObjectPermissionBackend',
+)
+
+ADDR_URL = []
+ANONYMOUS_USER_ID = -1  # 支持匿名用户
+
+STATIC_URL = '/static/'
+STATICFILES_DIRS = (os.path.join(BASE_DIR,'static'),)
+
+# 上传路径根目录
+MEDIA_ROOT = os.path.join(BASE_DIR, 'static/Upgrate')
+# 在浏览器上访问该上传文件的url的前缀
+MEDIA_URL = '/static/Upgrate/'
+ROOT_URLCONF = 'Ansjer.urls'
+LOGIN_URL = '/account/login'
+AUTH_USER_MODEL = 'Model.Device_User'  # 自定义Model
+APPEND_SLASH = False
+
+TEMPLATES = [
+    {
+        'BACKEND': 'django.template.backends.django.DjangoTemplates',
+        # 'DIRS': [BASE_DIR + '/static/templates', ],
+        'DIRS': [BASE_DIR + '/templates'],
+        'APP_DIRS': True,
+        'OPTIONS': {
+            'context_processors': [
+                'django.template.context_processors.debug',
+                'django.template.context_processors.request',
+                'django.contrib.auth.context_processors.auth',
+                'django.contrib.messages.context_processors.messages',
+            ],
+        },
+    },
+]
+
+WSGI_APPLICATION = 'Ansjer.us_config.local_wsgi.application'
+
+# 服务器类型
+DATABASE_DATA = 'ansjertest'
+SERVER_HOST = '127.0.0.1'
+DATABASES_USER = 'root'
+DATABASES_PASS = '123456'
+
+# DATABASE_DATA2 = 'ansjerpush'
+# SERVER_HOST2 = '127.0.0.1'
+# DATABASES_USER2 = 'root'
+# DATABASES_PASS2 = '123456'
+
+
+
+DATABASES = {
+    'default': {
+        'ENGINE': 'django.db.backends.mysql',
+        'NAME': DATABASE_DATA,
+        'USER': DATABASES_USER,
+        'PASSWORD': DATABASES_PASS,
+        'HOST': SERVER_HOST,
+        'PORT': '3306',
+        'OPTIONS': {'charset': 'utf8mb4', 'use_unicode': True, 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"},
+        'AUTOCOMMIT': True
+    },
+    # 'mysql02': {
+    #     'ENGINE': 'django.db.backends.mysql',
+    #     'NAME': DATABASE_DATA2,
+    #     'USER': DATABASES_USER2,
+    #     'PASSWORD': DATABASES_PASS2,
+    #     'HOST': SERVER_HOST2,
+    #     'PORT': '3306',
+    #     'OPTIONS': {'charset': 'utf8mb4', 'use_unicode': True, 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"},
+    #     'AUTOCOMMIT': True
+    # }
+}
+DATABASE_ROUTERS = ['Ansjer.database_router.DatabaseAppsRouter']
+DATABASE_APPS_MAPPING = {
+    'Model': 'default',
+    'db2': 'mysql02',
+}
+
+AUTH_PASSWORD_VALIDATORS = [
+    {
+        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
+    },
+    {
+        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
+    },
+    {
+        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
+    },
+    {
+        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
+    },
+]
+
+LANGUAGE_CODE = 'en-us'
+TIME_ZONE = 'Asia/Shanghai'
+# TIME_ZONE = 'UTC'
+USE_I18N = True
+USE_L10N = True
+USE_TZ = True
+
+# 跨域增加忽略
+CORS_ALLOW_CREDENTIALS = True
+CORS_ORIGIN_ALLOW_ALL = True
+# CORS_ORIGIN_WHITELIST = ('*')
+
+CORS_ALLOW_METHODS = (
+    'DELETE',
+    'GET',
+    'OPTIONS',
+    'PATCH',
+    'POST',
+    'PUT',
+    'VIEW',
+)
+
+CORS_ALLOW_HEADERS = (
+    'XMLHttpRequest',
+    'X_FILENAME',
+    'accept',
+    'accept-encoding',
+    'authorization',
+    'content-type',
+    'dnt',
+    'origin',
+    'user-agent',
+    'x-csrftoken',
+    'x-requested-with',
+    'Pragma',
+)
+
+#########################################
+'''
+增加错误信息推送到管理员邮箱
+'''
+# 管理员邮箱
+ADMINS = (
+    ('admin', 'chanjunkai@163.com'),
+    ('admin', '1379072853@qq.com'),
+)
+
+# 非空链接,却发生404错误,发送通知MANAGERS
+SEND_BROKEN_LINK_EMAILS = True
+MANAGERS = ADMINS
+
+# Email设置
+EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
+EMAIL_HOST = 'smtp.163.com'  # QQ邮箱SMTP服务器(邮箱需要开通SMTP服务)
+EMAIL_PORT = 25  # QQ邮箱SMTP服务端口
+EMAIL_HOST_USER = 'chanjunkai@163.com'  # 我的邮箱帐号
+EMAIL_HOST_PASSWORD = 'cjk1234'  # 授权码
+EMAIL_SUBJECT_PREFIX = 'website'  # 为邮件标题的前缀,默认是'[django]'
+EMAIL_USE_TLS = True  # 开启安全链接
+DEFAULT_FROM_EMAIL = SERVER_EMAIL = EMAIL_HOST_USER  # 设置发件人
+
+INSTALLED_APPS = [
+    'django.contrib.admin',
+    'django.contrib.auth',
+    'django.contrib.contenttypes',
+    'django.contrib.sessions',
+    'django.contrib.messages',
+    'django.contrib.staticfiles',
+    'corsheaders',
+    'imagekit',
+    'Model',
+    'PushModel',
+    'SerialModel',
+]
+
+MIDDLEWARE = [
+    'corsheaders.middleware.CorsMiddleware',
+    'Service.middleware.StatisticsUrlMiddleware',
+    'django.middleware.security.SecurityMiddleware',
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.middleware.common.CommonMiddleware',
+    # 'django.middleware.csrf.CsrfViewMiddleware',
+    'corsheaders.middleware.CorsPostCsrfMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+    'django.contrib.messages.middleware.MessageMiddleware',
+    'django.middleware.clickjacking.XFrameOptionsMiddleware',
+    'django.middleware.security.SecurityMiddleware',
+    # 'django_global_request.middleware.GlobalRequestMiddleware',
+]
+
+AUTHENTICATION_BACKENDS = (
+    'django.contrib.auth.backends.ModelBackend',  # django default backend
+    'guardian.backends.ObjectPermissionBackend',
+)
+
+ADDR_URL = []
+ANONYMOUS_USER_ID = -1  # 支持匿名用户
+
+STATIC_URL = '/static/'
+
+# 上传路径根目录
+MEDIA_ROOT = os.path.join(BASE_DIR, 'static/Upgrate')
+# 在浏览器上访问该上传文件的url的前缀
+MEDIA_URL = '/static/Upgrate/'
+ROOT_URLCONF = 'Ansjer.urls'
+LOGIN_URL = '/account/login'
+AUTH_USER_MODEL = 'Model.Device_User'  # 自定义Model
+APPEND_SLASH = False
+
+TEMPLATES = [
+    {
+        'BACKEND': 'django.template.backends.django.DjangoTemplates',
+        # 'DIRS': [BASE_DIR + '/static/templates', ],
+        'DIRS': [BASE_DIR + '/templates'],
+        'APP_DIRS': True,
+        'OPTIONS': {
+            'context_processors': [
+                'django.template.context_processors.debug',
+                'django.template.context_processors.request',
+                'django.contrib.auth.context_processors.auth',
+                'django.contrib.messages.context_processors.messages',
+            ],
+        },
+    },
+]
+
+WSGI_APPLICATION = 'Ansjer.local_wsgi.application'
+
+# 服务器类型
+#业务数据库
+DATABASE_DATA = 'ansjertest'
+SERVER_HOST = '127.0.0.1'
+DATABASES_USER = 'root'
+DATABASES_PASS = 'root'
+
+#推送数据库
+DATABASE_DATA2 = 'ansjerpush'
+SERVER_HOST2 = '127.0.0.1'
+DATABASES_USER2 = 'root'
+DATABASES_PASS2 = 'root'
+
+#序列号公共数据库
+DATABASE_DATA3 = 'serial'
+SERVER_HOST3 = '127.0.0.1'
+DATABASES_USER3 = 'root'
+DATABASES_PASS3 = 'root'
+
+DATABASES = {
+    'default': {
+        'ENGINE': 'django.db.backends.mysql',
+        'NAME': DATABASE_DATA,
+        'USER': DATABASES_USER,
+        'PASSWORD': DATABASES_PASS,
+        'HOST': SERVER_HOST,
+        'PORT': '3306',
+        'OPTIONS': {'charset': 'utf8mb4', 'use_unicode': True, 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"},
+        'AUTOCOMMIT': True
+    },
+    'mysql02': {
+        'ENGINE': 'django.db.backends.mysql',
+        'NAME': DATABASE_DATA2,
+        'USER': DATABASES_USER2,
+        'PASSWORD': DATABASES_PASS2,
+        'HOST': SERVER_HOST2,
+        'PORT': '3306',
+        'OPTIONS': {'charset': 'utf8mb4', 'use_unicode': True, 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"},
+        'AUTOCOMMIT': True
+    },
+    'mysql03': {
+        'ENGINE': 'django.db.backends.mysql',
+        'NAME': DATABASE_DATA3,
+        'USER': DATABASES_USER3,
+        'PASSWORD': DATABASES_PASS3,
+        'HOST': SERVER_HOST3,
+        'PORT': '3306',
+        'OPTIONS': {'charset': 'utf8mb4', 'use_unicode': True, 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"},
+        'AUTOCOMMIT': True
+    },
+}
+DATABASE_ROUTERS = ['Ansjer.database_router.DatabaseAppsRouter']
+DATABASE_APPS_MAPPING = {
+    'Model': 'default',
+    'PushModel': 'mysql02',
+    'SerialModel': 'mysql03',
+}
+
+AUTH_PASSWORD_VALIDATORS = [
+    {
+        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
+    },
+    {
+        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
+    },
+    {
+        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
+    },
+    {
+        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
+    },
+]
+
+LANGUAGE_CODE = 'en-us'
+TIME_ZONE = 'Asia/Shanghai'
+# TIME_ZONE = 'UTC'
+USE_I18N = True
+USE_L10N = True
+USE_TZ = True
+
+# 跨域增加忽略
+CORS_ALLOW_CREDENTIALS = True
+CORS_ORIGIN_ALLOW_ALL = True
+# CORS_ORIGIN_WHITELIST = ('*')
+
+CORS_ALLOW_METHODS = (
+    'DELETE',
+    'GET',
+    'OPTIONS',
+    'PATCH',
+    'POST',
+    'PUT',
+    'VIEW',
+)
+
+CORS_ALLOW_HEADERS = (
+    'XMLHttpRequest',
+    'X_FILENAME',
+    'accept',
+    'accept-encoding',
+    'authorization',
+    'content-type',
+    'dnt',
+    'origin',
+    'user-agent',
+    'x-csrftoken',
+    'x-requested-with',
+    'Pragma',
+)
+
+#########################################
+'''
+增加错误信息推送到管理员邮箱
+'''
+# 管理员邮箱
+ADMINS = (
+    ('admin', 'sonalh@foxmail.com'),
+)
+
+# 非空链接,却发生404错误,发送通知MANAGERS
+SEND_BROKEN_LINK_EMAILS = True
+MANAGERS = ADMINS
+
+# Email设置
+EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
+EMAIL_HOST = 'smtp.163.com'  # QQ邮箱SMTP服务器(邮箱需要开通SMTP服务)
+EMAIL_PORT = 25  # QQ邮箱SMTP服务端口
+EMAIL_HOST_USER = 'chanjunkai@163.com'  # 我的邮箱帐号
+EMAIL_HOST_PASSWORD = 'cjk1234'  # 授权码
+EMAIL_SUBJECT_PREFIX = 'website'  # 为邮件标题的前缀,默认是'[django]'
+EMAIL_USE_TLS = True  # 开启安全链接
+DEFAULT_FROM_EMAIL = SERVER_EMAIL = EMAIL_HOST_USER  # 设置发件人
+
+LOGGING = {
+    'version': 1,
+    'disable_existing_loggers': True,
+    'formatters': {
+        'error_format': {
+            # 'format': '{"asctime":"%(asctime)s","thread":"%(threadName)s:%(thread)d","errorline":"%(lineno)d","errorlevel":"%(levelname)s","errorcontent":"%(message)s"}'
+            'format': '%(asctime)s %(threadName)s %(thread)d %(lineno)d %(levelname)s %(message)s'
+        },
+        'standard': {
+            'format': '[%(asctime)s] [%(filename)s:%(lineno)d] [%(module)s:%(funcName)s] '
+                      '[%(levelname)s]- %(message)s'},
+
+    },
+    'filters': {
+    },
+    'handlers': {
+        'mail_admins': {
+            'level': 'ERROR',
+            'class': 'django.utils.log.AdminEmailHandler',
+            'include_html': True,
+        },
+        'default': {
+            'level': 'ERROR',
+            'class': 'logging.handlers.TimedRotatingFileHandler',
+            'filename': BASE_DIR + '/static/log/error/error.log',
+            'backupCount': 30,
+            'when': 'D',
+            'formatter': 'error_format',
+        },
+        'console': {
+            'level': 'ERROR',
+            'class': 'logging.StreamHandler',
+            'formatter': 'error_format'
+        },
+        'info': {
+            'level': 'INFO',
+            'class': 'logging.handlers.TimedRotatingFileHandler',
+            'filename': BASE_DIR + '/static/log/info/info.log',
+            'backupCount': 30,
+            'when': 'D',
+            'formatter': 'standard',
+            'encoding': 'utf-8',
+        },
+    },
+    'loggers': {
+        'django': {
+            'handlers': ['default', 'console'],
+            # 'handlers': ['mail_admins','default','console'],
+            # 'level': 'ERROR',
+            'level': 'ERROR',
+            'propagate': False
+        },
+        # log 调用时需要当作参数传入
+        'info': {
+            'handlers': ['info'],
+            'level':'INFO',
+            'propagate': False
+        }
+        # 'django.db.backends': {
+        #     'handlers': ['console'],
+        #     'propagate': True,
+        #     'level': 'DEBUG',
+        # },
+    }
+}

+ 16 - 0
Ansjer/eur_config/local_wsgi.py

@@ -0,0 +1,16 @@
+"""
+WSGI config for Ansjer project.
+
+It exposes the WSGI callable as a module-level variable named ``application``.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/dev/howto/deployment/wsgi/
+"""
+
+import os
+
+from django.core.wsgi import get_wsgi_application
+
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Ansjer.us_config.local_settings")
+
+application = get_wsgi_application()

+ 274 - 0
Ansjer/eur_config/test_settings.py

@@ -0,0 +1,274 @@
+import os
+from Ansjer.config import BASE_DIR
+
+
+SECRET_KEY = 'c7ki2_gkg4#sjfm-u1%$s#&n#szf01f*v69rwv2qsf#-zmm@tl'
+DEBUG = True
+# DEBUG = False
+ALLOWED_HOSTS = ['*']
+
+INSTALLED_APPS = [
+    'django.contrib.admin',
+    'django.contrib.auth',
+    'django.contrib.contenttypes',
+    'django.contrib.sessions',
+    'django.contrib.messages',
+    'django.contrib.staticfiles',
+    'corsheaders',
+    'imagekit',
+    'Model',
+    'PushModel',
+    'SerialModel',
+]
+
+MIDDLEWARE = [
+    'corsheaders.middleware.CorsMiddleware',
+    'Service.middleware.StatisticsUrlMiddleware',
+    'django.middleware.security.SecurityMiddleware',
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.middleware.common.CommonMiddleware',
+    # 'django.middleware.csrf.CsrfViewMiddleware',
+    'corsheaders.middleware.CorsPostCsrfMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+    'django.contrib.messages.middleware.MessageMiddleware',
+    'django.middleware.clickjacking.XFrameOptionsMiddleware',
+    'django.middleware.security.SecurityMiddleware',
+    'django_global_request.middleware.GlobalRequestMiddleware',
+]
+
+AUTHENTICATION_BACKENDS = (
+    'django.contrib.auth.backends.ModelBackend',  # django default backend
+    'guardian.backends.ObjectPermissionBackend',
+)
+
+ADDR_URL = []
+ANONYMOUS_USER_ID = -1  # 支持匿名用户
+
+STATIC_URL = '/static/'
+
+# 上传路径根目录
+MEDIA_ROOT = os.path.join(BASE_DIR, 'static/Upgrate')
+# 在浏览器上访问该上传文件的url的前缀
+MEDIA_URL = '/static/Upgrate/'
+ROOT_URLCONF = 'Ansjer.urls'
+LOGIN_URL = '/account/login'
+AUTH_USER_MODEL = 'Model.Device_User'  # 自定义Model
+APPEND_SLASH = False
+
+TEMPLATES = [
+    {
+        'BACKEND': 'django.template.backends.django.DjangoTemplates',
+        # 'DIRS': [BASE_DIR + '/static/templates', ],
+        'DIRS': [BASE_DIR + '/templates', ],
+        'APP_DIRS': True,
+        'OPTIONS': {
+            'context_processors': [
+                'django.template.context_processors.debug',
+                'django.template.context_processors.request',
+                'django.contrib.auth.context_processors.auth',
+                'django.contrib.messages.context_processors.messages',
+            ],
+        },
+    },
+]
+
+WSGI_APPLICATION = 'Ansjer.us_config.test_wsgi.application'
+
+
+# 服务器类型
+#业务数据库
+DATABASE_DATA = 'AnsjerTest'
+SERVER_HOST = 'database-2.clraczw4p0yj.us-west-1.rds.amazonaws.com'
+DATABASES_USER = 'azrds'
+DATABASES_PASS = 'azrds.x.x'
+
+#推送数据库
+DATABASE_DATA2 = 'AnsjerTest'
+SERVER_HOST2 = 'ansjerpush.clraczw4p0yj.us-west-1.rds.amazonaws.com'
+DATABASES_USER2 = 'azrds'
+DATABASES_PASS2 = 'azrds.x.x'
+
+DATABASES = {
+    'default': {
+        'ENGINE': 'django.db.backends.mysql',
+        'NAME': DATABASE_DATA,
+        'USER': DATABASES_USER,
+        'PASSWORD': DATABASES_PASS,
+        'HOST': SERVER_HOST,
+        'PORT': '3306',
+        'OPTIONS': {'charset': 'utf8mb4', 'use_unicode': True, 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"},
+        'AUTOCOMMIT': True
+    },
+    'mysql02': {
+        'ENGINE': 'django.db.backends.mysql',
+        'NAME': DATABASE_DATA2,
+        'USER': DATABASES_USER2,
+        'PASSWORD': DATABASES_PASS2,
+        'HOST': SERVER_HOST2,
+        'PORT': '3306',
+        'OPTIONS': {'charset': 'utf8mb4', 'use_unicode': True, 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"},
+        'AUTOCOMMIT': True
+    },
+}
+
+DATABASE_ROUTERS = ['Ansjer.database_router.DatabaseAppsRouter']
+DATABASE_APPS_MAPPING = {
+    'Model': 'default',
+    'db2': 'mysql02',
+}
+
+AUTH_PASSWORD_VALIDATORS = [
+    {
+        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
+    },
+    {
+        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
+    },
+    {
+        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
+    },
+    {
+        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
+    },
+]
+
+LANGUAGE_CODE = 'en-us'
+# TIME_ZONE = 'Asia/Shanghai'
+TIME_ZONE = 'UTC'
+USE_I18N = True
+USE_L10N = True
+USE_TZ = True
+
+# 跨域增加忽略
+CORS_ALLOW_CREDENTIALS = True
+CORS_ORIGIN_ALLOW_ALL = True
+# CORS_ORIGIN_WHITELIST = ('*')
+
+CORS_ALLOW_METHODS = (
+    'DELETE',
+    'GET',
+    'OPTIONS',
+    'PATCH',
+    'POST',
+    'PUT',
+    'VIEW',
+)
+
+CORS_ALLOW_HEADERS = (
+    'XMLHttpRequest',
+    'X_FILENAME',
+    'accept',
+    'accept-encoding',
+    'authorization',
+    'content-type',
+    'dnt',
+    'origin',
+    'user-agent',
+    'x-csrftoken',
+    'x-requested-with',
+    'Pragma',
+)
+
+#########################################
+'''
+增加错误信息推送到管理员邮箱
+'''
+# 管理员邮箱
+ADMINS = (
+    ('admin', 'sonalh@foxmail.com'),
+)
+
+# 非空链接,却发生404错误,发送通知MANAGERS
+SEND_BROKEN_LINK_EMAILS = True
+MANAGERS = ADMINS
+
+# Email设置
+EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
+EMAIL_HOST = 'smtp.163.com'  # QQ邮箱SMTP服务器(邮箱需要开通SMTP服务)
+EMAIL_PORT = 25  # QQ邮箱SMTP服务端口
+EMAIL_HOST_USER = 'chanjunkai@163.com'  # 我的邮箱帐号
+EMAIL_HOST_PASSWORD = 'cjk1234'  # 授权码
+EMAIL_SUBJECT_PREFIX = 'website'  # 为邮件标题的前缀,默认是'[django]'
+EMAIL_USE_TLS = True  # 开启安全链接
+DEFAULT_FROM_EMAIL = SERVER_EMAIL = EMAIL_HOST_USER  # 设置发件人
+
+LOGGING = {
+    'version': 1,
+    'disable_existing_loggers': True,
+    'formatters': {
+        'error_format': {
+            # 'format': '{"asctime":"%(asctime)s","thread":"%(threadName)s:%(thread)d","errorline":"%(lineno)d","errorlevel":"%(levelname)s","errorcontent":"%(message)s"}'
+            'format': '%(asctime)s %(threadName)s %(thread)d %(lineno)d %(levelname)s %(message)s'
+        },
+        'standard': {
+            'format': '[%(asctime)s] [%(filename)s:%(lineno)d] [%(module)s:%(funcName)s] '
+                      '[%(levelname)s]- %(message)s'},
+
+    },
+    'filters': {
+    },
+    'handlers': {
+        'mail_admins': {
+            'level': 'ERROR',
+            'class': 'django.utils.log.AdminEmailHandler',
+            'include_html': True,
+        },
+        'default': {
+            'level': 'ERROR',
+            'class': 'logging.handlers.TimedRotatingFileHandler',
+            'filename': BASE_DIR + '/static/log/error/error.log',
+            'backupCount': 30,
+            'when': 'D',
+            'formatter': 'error_format',
+        },
+        'console': {
+            'level': 'ERROR',
+            'class': 'logging.StreamHandler',
+            'formatter': 'error_format'
+        },
+        'info': {
+            'level': 'INFO',
+            'class': 'logging.handlers.TimedRotatingFileHandler',
+            'filename': BASE_DIR + '/static/log/info/info.log',
+            'backupCount': 30,
+            'when': 'D',
+            'formatter': 'standard',
+            'encoding': 'utf-8',
+        },
+        'device_info': {
+            'level': 'INFO',
+            'class': 'logging.handlers.TimedRotatingFileHandler',
+            'filename': BASE_DIR + '/static/log/device_info/info.log',
+            'backupCount': 30,
+            'when': 'D',
+            'formatter': 'standard',
+            'encoding': 'utf-8',
+        },
+    },
+    'loggers': {
+        'django': {
+            'handlers': ['default', 'console'],
+            # 'handlers': ['mail_admins','default','console'],
+            # 'level': 'ERROR',
+            'level': 'ERROR',
+            'propagate': False
+        },
+        # log 调用时需要当作参数传入
+        'info': {
+            'handlers': ['info'],
+            'level':'INFO',
+            'propagate': False
+        },
+
+        'device_info':{
+            'handlers': ['device_info'],
+            'level':'INFO',
+            'propagate': False
+        }
+        # 'django.db.backends': {
+        #     'handlers': ['console'],
+        #     'propagate': True,
+        #     'level': 'DEBUG',
+        # },
+    }
+}

+ 16 - 0
Ansjer/eur_config/test_wsgi.py

@@ -0,0 +1,16 @@
+"""
+WSGI config for Ansjer project.
+
+It exposes the WSGI callable as a module-level variable named ``application``.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/dev/howto/deployment/wsgi/
+"""
+
+import os
+
+from django.core.wsgi import get_wsgi_application
+
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Ansjer.us_config.test_settings")
+
+application = get_wsgi_application()

+ 6 - 1
Ansjer/urls.py

@@ -134,9 +134,14 @@ urlpatterns = [
     url(r'^v2/authcode/verify$', UserController.verifyAuthcode.as_view()),
     url(r'^v2/account/logout$', UserController.V2LogoutView.as_view()),
     url(r'^v2/account/login$', UserController.v3LoginView.as_view()),
-    url(r'^account/delete$', UserController.deleteAccount),
     url(r'^v3/account/login$', UserController.v3LoginView.as_view()),
 
+    #用户删除/注销
+    url(r'^account/delete$', UserController.deleteAccount),
+
+    #确认地区
+    url(r'^user/confirmRegion$', UserController.confirmRegion),
+
     # 验证码登录
     url(r'^account/loginCode$', UserController.loginCodeView.as_view()),
     url(r'^v3/account/loginByCode$', UserController.v3LoginByCodeView.as_view()),

+ 24 - 12
Controller/AppLogController.py

@@ -2,10 +2,12 @@
 # -*- coding: utf-8 -*-
 import time
 
+import boto3
+import botocore
 import oss2
 from django.views.generic.base import View
 
-from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET
+from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, REGION_NAME, ACCESS_KEY_ID, SECRET_ACCESS_KEY
 from Model.models import AppLogModel
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
@@ -34,7 +36,6 @@ class AppLogView(View):
         token = TokenObject(token)
         if token.code != 0:
             return response.json(token.code)
-
         if operation == 'getUploadUrl':
             return self.get_upload_url(token.userID, request_dict, response)
         elif operation == 'add':
@@ -50,17 +51,28 @@ class AppLogView(View):
 
     def get_upload_url(self, userID, request_dict, response):
         upload_type = request_dict.get('upload_type', None)
-        if upload_type:
-            auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
-            bucket = oss2.Bucket(auth, 'oss-cn-hongkong.aliyuncs.com', 'statres')
-            name = CommonService.createOrderID()
-            filename = str(name) + '.' + upload_type
-            obj = 'app_log/{userID}/'.format(userID=userID) + filename
-
-            url = bucket.sign_url('PUT', obj, 7200)
-            return response.json(0, {'put_url': url, 'filename': filename})
-        else:
+        if not upload_type:
             return response.json(444)
+        name = CommonService.createOrderID()
+        filename = str(name) + '.' + upload_type
+        obj = 'app_log/{userID}/'.format(userID=userID) + filename
+        aws_s3_client = boto3.client(
+            's3',
+            region_name=REGION_NAME,
+            aws_access_key_id=ACCESS_KEY_ID,
+            aws_secret_access_key=SECRET_ACCESS_KEY,
+            config=botocore.client.Config(signature_version='s3v4'),
+        )
+        response_url = aws_s3_client.generate_presigned_url(
+            ClientMethod='put_object',
+            Params={
+                'Bucket': 'ansjer-statres',
+                'Key': obj
+            },
+            ExpiresIn=3600
+        )
+        return response.json(0, {'put_url': response_url, 'filename': filename})
+
 
     def do_add(self, userID, request_dict, response):
         uid = request_dict.get('uid', None)

+ 18 - 39
Controller/AppSetController.py

@@ -58,47 +58,26 @@ class AppSetView(View):
         lang = request_dict.get('lang', None)
         appBundleId = request_dict.get('appBundleId', None)
         if not appBundleId:
-            return response.json(444,'appBundleId')
-        redis = RedisObject()
-
-        if SERVER_TYPE != "Ansjer.formal_settings":
-            key_id= "www"+appBundleId
-        else:
-            key_id = "test" + appBundleId
-        #redis_value = redis.get_data(key=key_id)  去除到缓存中找
-        redis_value = False
-        if redis_value == False:
-            print('添加到缓存')
-            # 查数据库
-            sm_qs = AppSetModel.objects.filter(appBundleId=appBundleId)
-            count = sm_qs.count()
-            if count > 0:
+            return response.json(444, 'appBundleId')
 
-                sm_qs = sm_qs.values("content")
-                # 添加到缓存,缓存时间为3600秒------指的是一个钟后再次访问,就会刷新缓存一次
-                dict_json = json.loads(sm_qs[0]['content'])
-                if 'editionUpgrading' in dict_json :
-                    if  dict_json['editionUpgrading'] == 1:
-                        if lang !='cn':
-                            dict_json['editionUpgrading'] = 'Upgrading, please sign in later'
-                        else:
-                            dict_json['editionUpgrading'] = '正在升级,请稍后登录'
+        app_set_qs = AppSetModel.objects.filter(appBundleId=appBundleId).values('content')
+        if not app_set_qs.exists():
+            return response.json(173)
+        try:
+            if not app_set_qs[0]['content']:
+                return response.json(0)
+            dict_json = json.loads(app_set_qs[0]['content'])
+            if 'editionUpgrading' in dict_json:
+                if dict_json['editionUpgrading'] == 1:
+                    if lang == 'cn':
+                        dict_json['editionUpgrading'] = '正在升级,请稍后登录'
                     else:
-                        dict_json['editionUpgrading'] = ''
-
-
-
-                content_json_str = dict_json
-
-                redis.set_data(key=key_id, val=content_json_str, expire=3600)
-                # 返回固定值
-                return response.json(0, content_json_str)
-            else:
-                return response.json(173)
-        else:
-            print('去缓存找')
-            # 返回固定值
-            return response.json(0, json.loads(redis_value))
+                        dict_json['editionUpgrading'] = 'Upgrading, please sign in later'
+                else:
+                    dict_json['editionUpgrading'] = ''
+            return response.json(0, dict_json)
+        except Exception as e:
+            return response.json(500, repr(e))
 
         # res = {}
         # res['grade'] = 1

+ 4 - 2
Controller/CDKController.py

@@ -97,6 +97,7 @@ class CDKView(View):
                 create_time=nowTime,
                 valid_time=0,
                 is_activate=0,
+                is_down=0,
                 rank_id=rank,
                 order=order,
             )
@@ -241,15 +242,16 @@ class CDKView(View):
         if region == 'cn':
             # 下载国内未使用激活码
             content += '激活码(国内)\n'
-            cdk_inactivate_qs = CDKcontextModel.objects.filter(is_activate=0, rank__bucket__mold=0).values('cdk')
+            cdk_inactivate_qs = CDKcontextModel.objects.filter(is_down=0, is_activate=0, rank__bucket__mold=0, rank__is_show=0).values('cdk')
         else:
             # 下载国外未使用激活码
             content += '激活码(国外)\n'
-            cdk_inactivate_qs = CDKcontextModel.objects.filter(is_activate=0, rank__bucket__mold=1).values('cdk')
+            cdk_inactivate_qs = CDKcontextModel.objects.filter(is_down=0, is_activate=0, rank__bucket__mold=1, rank__is_show=0).values('cdk')
         for cdk_inactivate in cdk_inactivate_qs:
             content += cdk_inactivate['cdk'] + '\n'
         # print(content)
 
+        cdk_inactivate_qs.update(is_down=1)
         response = StreamingHttpResponse(content)
         response['Content-Type'] = 'application/octet-stream'
         response['Content-Disposition'] = 'attachment;filename="CDK.txt"'

+ 31 - 5
Controller/PctestController.py

@@ -382,19 +382,45 @@ class PcTest(View):
     def updatePass(self, request_dict, userID, response):
 
         id = request_dict.get('id', None)
-        password = request_dict.get('password', None)
+        oldpass = request_dict.get('oldpass', None)
+        newpass1 = request_dict.get('newpass1', None)
+        newpass2 = request_dict.get('newpass2', None)
+
         param_flag = CommonService.get_param_flag(
-            data=[id,password])
+            data=[id,oldpass,newpass1,newpass2])
         if param_flag is not True:
             return response.json(444)
 
         # 判断员工与岗位是否存在,员工存在返回174
-        user_list = PctestuserModel.objects.filter(id=id)
-        if user_list.exists():
-            user_list.update(password=password)
+        user_list = PctestuserModel.objects.filter(id=id, password=oldpass)
+        if not user_list.exists():
+            if not PctestuserModel.objects.filter(id=id).exists():
+                return response.json(104)
+            return response.json(111)
+
+        if newpass1 != newpass2:
+            return response.json(10,'两次密码不相同,请重新输入')
+
+        user_list.update(password=newpass1)
 
         return response.json(0)
 
+    # def updatePass(self, request_dict, userID, response):
+    #
+    #     id = request_dict.get('id', None)
+    #     password = request_dict.get('password', None)
+    #     param_flag = CommonService.get_param_flag(
+    #         data=[id,password])
+    #     if param_flag is not True:
+    #         return response.json(444)
+    #
+    #     # 判断员工与岗位是否存在,员工存在返回174
+    #     user_list = PctestuserModel.objects.filter(id=id)
+    #     if user_list.exists():
+    #         user_list.update(password=password)
+    #
+    #     return response.json(0)
+
 
 
 

+ 5 - 1
Controller/TestApi.py

@@ -717,7 +717,11 @@ class testView(View):
             data={'userID': 158943594633713800138000, 'lang': 'cn', 'user': '597471180@qq.com', 'm_code': '123413243214'})
         #uidToken
         # utko = UidTokenObject()
-        # res = utko.generate(data={'uid': 'XKWZSC5FCJYT19B7111A','channel': 1})
+        # res = utko.generate(data={'uid': '4UZSEDP93MJ3X7YB111A','channel': 1})
+
+        # from Object.ETkObject import ETkObject
+        # etkObj = ETkObject(etk='')
+        # res = etkObj.encrypt("4UZSEDP93MJ3X7YB111A")
         return JsonResponse(status=200, data=res,safe=False)
 
 

+ 59 - 15
Controller/UserController.py

@@ -32,7 +32,7 @@ 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, UidChannelSetModel
+    UserAppFrequencyModel, CountryIPModel, CountryModel, UidChannelSetModel, Order_Model
 from Object.AWS.SesClassObject import SesClassObject
 from Object.AliSmsObject import AliSmsObject
 from Object.RedisObject import RedisObject
@@ -3847,26 +3847,70 @@ def updateUserCountry(request):
     response = ResponseObject()
     return response.json(0)
 
+def confirmRegion(request):
+    response = ResponseObject()
+    request.encoding = 'utf-8'
+    # test
+    number = request.POST.get('number', None)
+    if number is None:
+        return response.json(309)
+    number = request.POST.get('number', None)
+    selectRegion = CountryModel.objects.filter(number=number).values('region__api')
+    if not selectRegion.exists():
+        return response.json(0,{"request_url":"https://www.dvema.com"})
+    else:
+        return response.json(0,{"request_url":selectRegion[0]['region__api']})
+
 
 def deleteAccount(request):
     response = ResponseObject()
     request.encoding = 'utf-8'
     #test
     token = request.POST.get('token',None)
-    if token is None:
-        return response.json(309)
-    tko = TokenObject(token)
-    response.lang = tko.lang
-    if tko.code != 0:
-        return response.json(tko.code)
-    userID = tko.userID
-    if not userID:
-        return response.json(309)
-    delUser = Device_User.objects.filter(userID=userID)
-    if not delUser.exists():
-        return response.json(104)
-    delUser.delete()
-    return response.json(0)
+    password = request.POST.get('userPwd',None)
+    try:
+        for i in range(1, 4):
+            if i == 1:
+                # 第一次先解密
+                password = base64.b64decode(password)
+                password = password.decode('utf-8')
+                # 截去第一位,最后一位
+                password = password[1:-1]
+            if i == 2:
+                # 第2次先解密
+                password = base64.b64decode(password)
+                password = password.decode('utf-8')
+                # 去前2位,后2位
+                password = password[2:-2]
+            if i == 3:
+                # 第3次先解密
+                password = base64.b64decode(password)
+                password = password.decode('utf-8')
+                # 去前3位,后3位
+                password = password[3:-3]
+    except Exception as e:
+        return response.json(111)
+    else:
+        if token is None:
+            return response.json(309)
+        tko = TokenObject(token)
+        response.lang = tko.lang
+        if tko.code != 0:
+            return response.json(tko.code)
+        userID = tko.userID
+        if not userID:
+            return response.json(309)
+        delUser = Device_User.objects.filter(userID=userID)
+        if not delUser.exists():
+            return response.json(104)
+        userPWD = delUser.values('password')[0]
+        if not check_password(password, userPWD['password']):
+            return response.json(111)
+        hasOrder = Order_Model.objects.filter(userID=userID,status=1)
+        if hasOrder.exists():
+            return response.json(10046)
+        delUser.delete()
+        return response.json(0)
 
 
 class InitUserInformationView(View):

+ 3 - 3
MiddleWare/requestRecord.py

@@ -42,10 +42,10 @@ class RequestRecordMiddleware(MiddlewareMixin):
                 }
                 RequestRecordModel.objects.create(**request_record_data)
             elif response.content:     # 处理捕获异常的情况
-                print('content: ', response.content)
+                # print('content: ', response.content)
                 content = eval(str(response.content, 'utf-8'))   # bytes 转为 dict
-                logger = logging.getLogger('info')
-                logger.info('content: {}'.format(content))
+                # logger = logging.getLogger('info')
+                # logger.info('content: {}'.format(content))
                 error_flag = False
                 if 'result_code' in content and content['result_code'] == 500:
                     reason_phrase = content['result']

+ 1 - 0
Model/models.py

@@ -1216,6 +1216,7 @@ class CDKcontextModel(models.Model):
     create_time = models.IntegerField(default=0, verbose_name='创建时间')
     valid_time = models.IntegerField(default=0, verbose_name='有效期间')  #超过有效期激活码不可在激活 ,0:永久
     is_activate = models.SmallIntegerField(default=0, verbose_name='是否已激活') #0 未激活  1 已激活
+    is_down = models.SmallIntegerField(default=0, verbose_name='是否已下载') #0 未下载 1 已下载
     rank = models.ForeignKey(Store_Meal, to_field='id', default='', on_delete=models.CASCADE, verbose_name='套餐类型')
     # order = models.ForeignKey(Order_Model, blank=True, max_length=20, to_field='orderID', on_delete=models.CASCADE, verbose_name='订单id', unique=True)
     order = models.CharField(max_length=20, blank=True, unique=True, verbose_name='订单id')

+ 2 - 0
Object/ResponseObject.py

@@ -101,6 +101,7 @@ class ResponseObject(object):
             10043: 'The device does not registered a certificate',
             10044: 'Request to publish MQTT topic message failed',
             10045: 'Already the latest version',
+            10046: 'Sorry, users who have activated cloud storage packages do not support logout at the moment, please contact customer service',
         }
         data_cn = {
             0: '成功',
@@ -195,6 +196,7 @@ class ResponseObject(object):
             10043: '此设备没有注册证书',
             10044: '请求发布MQTT主题消息失败',
             10045: '当前为最新版本',
+            10046: '已开通云存的用户,暂不支持注销,请联系客服',
         }
         if self.lang == 'cn':
             msg = data_cn