Ver Fonte

Merge remote-tracking branch 'origin/test'

# Conflicts:
#	Ansjer/urls.py
#	Ansjer/us_config/config_formal.py
#	Controller/CloudStorage.py
#	Controller/DetectController.py
#	Controller/DetectControllerV2.py
#	Controller/EquipmentManager.py
#	Controller/TestApi.py
locky há 3 anos atrás
pai
commit
6a9a824107
76 ficheiros alterados com 5482 adições e 723 exclusões
  1. 98 0
      AdminController/LogManagementController.py
  2. 164 0
      AdminController/MenuController.py
  3. 127 0
      AdminController/RoleController.py
  4. 1146 0
      AdminController/ServeManagementController.py
  5. 81 0
      AdminController/TestServeController.py
  6. 446 0
      AdminController/UserManageController.py
  7. 131 0
      Ansjer/cn_config/config_formal.py
  8. 143 0
      Ansjer/cn_config/config_test.py
  9. 256 0
      Ansjer/cn_config/formal_settings.py
  10. 16 0
      Ansjer/cn_config/formal_wsgi.py
  11. 275 0
      Ansjer/cn_config/test_settings.py
  12. 1 1
      Ansjer/cn_config/test_wsgi.py
  13. 18 6
      Ansjer/config.py
  14. 13 13
      Ansjer/local_config/config_local.py
  15. 78 67
      Ansjer/local_config/local_settings.py
  16. 1 1
      Ansjer/local_config/local_wsgi.py
  17. 0 5
      Ansjer/pushconfig.py
  18. 37 3
      Ansjer/urls.py
  19. 8 1
      Ansjer/us_config/config_formal.py
  20. 11 3
      Ansjer/us_config/config_test.py
  21. 2 2
      Ansjer/us_config/formal_settings.py
  22. 16 0
      Ansjer/us_config/formal_wsgi.py
  23. 16 1
      Ansjer/us_config/test_settings.py
  24. 1 1
      Ansjer/us_config/test_wsgi.py
  25. 3 3
      Controller/Alexa.py
  26. 2 2
      Controller/CDKController.py
  27. 17 7
      Controller/CloudStorage.py
  28. 44 69
      Controller/CompanyController.py
  29. 2 16
      Controller/DetectController.py
  30. 2 16
      Controller/DetectControllerV2.py
  31. 55 1
      Controller/DeviceConfirmRegion.py
  32. 75 0
      Controller/DeviceDebug.py
  33. 3 8
      Controller/DynamoDBLog.py
  34. 10 5
      Controller/EquipmentManager.py
  35. 3 1
      Controller/EquipmentManagerV2.py
  36. 8 1
      Controller/EquipmentStatus.py
  37. 5 7
      Controller/FAQController.py
  38. 22 15
      Controller/IotCoreController.py
  39. 1 1
      Controller/LogManager.py
  40. 3 2
      Controller/MealManage.py
  41. 5 3
      Controller/OrderContrller.py
  42. 689 0
      Controller/PcInfo.py
  43. 528 0
      Controller/PctestController.py
  44. 201 202
      Controller/SerialNumberController.py
  45. 3 1
      Controller/ShadowController.py
  46. 71 45
      Controller/TestApi.py
  47. 16 0
      Controller/UIDController.py
  48. 2 0
      Controller/UidSetController.py
  49. 3 1
      Controller/UidUser.py
  50. 136 31
      Controller/UserController.py
  51. 59 44
      Controller/UserManger.py
  52. 40 15
      Controller/VPGController.py
  53. 22 15
      Controller/VoicePromptController.py
  54. 0 0
      CrontabTask/formal_statistics_push_day_task.py
  55. 0 0
      CrontabTask/formal_statistics_push_month_task.py
  56. 0 0
      CrontabTask/formal_zositech_help_weekly_task.py
  57. 6 2
      CrontabTask/test_statistics_push_day_task.py
  58. 6 2
      CrontabTask/test_statistics_push_month_task.py
  59. 6 2
      CrontabTask/test_zositech_help_weekly_task.py
  60. 7 0
      MiddleWare/__init__.py
  61. 67 0
      MiddleWare/requestRecord.py
  62. 177 4
      Model/models.py
  63. 15 20
      Object/AWS/S3Email.py
  64. 4 1
      Object/ResponseObject.py
  65. 14 1
      Object/TokenObject.py
  66. 3 8
      Service/CloudLogs.py
  67. 17 0
      Service/CommonService.py
  68. 3 3
      Service/MiscellService.py
  69. 0 40
      Service/ModelService.py
  70. 8 5
      Service/middleware.py
  71. 15 0
      cn_formal_manage.py
  72. 1 1
      cn_test_manage.py
  73. 1 9
      local_manage.py
  74. 1 9
      manage.py
  75. 15 0
      us_formal_manage.py
  76. 1 1
      us_test_manage.py

+ 98 - 0
AdminController/LogManagementController.py

@@ -0,0 +1,98 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+
+import json
+import time
+import urllib
+import uuid
+import boto3
+import threading
+import logging
+from boto3.session import Session
+from django.http import JsonResponse, HttpResponseRedirect, HttpResponse
+from django.views.generic.base import View
+
+from Controller.CheckUserData import date_handler
+from Model.models import Device_Info, Role, MenuModel, RequestRecordModel
+from Object.ResponseObject import ResponseObject
+from Object.TokenObject import TokenObject
+from Object.UidTokenObject import UidTokenObject
+from Service.CommonService import CommonService
+from django.db.models import Q, F
+from time import strftime
+
+
+class LogManagementView(View):
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.GET, request, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.POST, request, operation)
+
+    def validation(self, request_dict, request, operation):
+        language = request_dict.get('language', 'en')
+        response = ResponseObject(language, 'pc')
+        if operation == '??':
+            return 0
+        else:
+            tko = TokenObject(
+                request.META.get('HTTP_AUTHORIZATION'),
+                returntpye='pc')
+            # if tko.code != 0:
+            #     return response.json(tko.code)
+            response.lang = tko.lang
+            userID = tko.userID
+            if operation == 'getRequestList':
+                return self.getRequestList(request_dict, response)
+
+    def getRequestList(self, request_dict, response):
+        pageNo = request_dict.get('pageNo', None)
+        pageSize = request_dict.get('pageSize', None)
+        method = request_dict.get('method', None)
+        url = request_dict.get('url', None)
+        parameter = request_dict.get('parameter', None)
+        status_code = request_dict.get('status_code', None)
+        reason_phrase = request_dict.get('reason_phrase', None)
+        if not all([pageNo, pageSize]):
+            return response.json(444)
+
+        page = int(pageNo)
+        line = int(pageSize)
+        try:
+            request_qs = RequestRecordModel.objects.all()
+            if method:
+                request_qs = request_qs.filter(method=method)
+            if url:
+                request_qs = request_qs.filter(url__contains=url)
+            if parameter:
+                request_qs = request_qs.filter(parameter__contains=parameter)
+            if status_code:
+                request_qs = request_qs.filter(status_code=status_code)
+            if reason_phrase:
+                request_qs = request_qs.filter(reason_phrase=reason_phrase)
+
+            count = request_qs.count()
+
+            request_qs = request_qs[(page - 1) * line:page * line]
+            qs_list = []
+            for requsetobj in request_qs:
+                qs_list.append({
+                    'id': requsetobj.id,
+                    'method': requsetobj.method,
+                    'url': requsetobj.url,
+                    'parameter': requsetobj.parameter,
+                    'execute_time': round(requsetobj.execute_time, 2),  # 时间保留小数点后两位
+                    'status_code': requsetobj.status_code,
+                    'reason_phrase': requsetobj.reason_phrase,
+                    'add_time': requsetobj.add_time.strftime("%Y-%m-%d %H:%M:%S"),
+                })
+            return response.json(
+                0, {'list': qs_list, 'total': count})
+        except Exception as e:
+            print(e)
+            return response.json(500, repr(e))

+ 164 - 0
AdminController/MenuController.py

@@ -0,0 +1,164 @@
+#!/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: 2021/07/06 11:17
+@Version: python3.6
+@MODIFY DECORD:ansjer dev
+"""
+import json
+import time
+import urllib
+import uuid
+import boto3
+import threading
+import logging
+from boto3.session import Session
+from django.http import JsonResponse, HttpResponseRedirect, HttpResponse
+from django.views.generic.base import View
+from Model.models import Device_Info, Role, MenuModel
+from Object.ResponseObject import ResponseObject
+from Object.TokenObject import TokenObject
+from Object.UidTokenObject import UidTokenObject
+from Service.CommonService import CommonService
+from django.db.models import Q, F
+from time import strftime
+
+
+class MenuView(View):
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.GET, request, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.POST, request, operation)
+
+    def validation(self, request_dict, request, operation):
+        language = request_dict.get('language', 'en')
+        response = ResponseObject(language, 'pc')
+        if operation == '??':
+            return 0
+        else:
+            tko = TokenObject(request.META.get('HTTP_AUTHORIZATION'),returntpye='pc')
+            if tko.code != 0:
+                return response.json(tko.code)
+            response.lang = tko.lang
+            userID = tko.userID
+            if operation == 'getList':
+                return self.getList(userID, request_dict, response)
+            if operation == 'doEdit':
+                return self.doEdit(userID, request_dict, response)
+            if operation == 'doDelete':
+                return self.doDelete(userID, request_dict, response)
+            else:
+                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(
+                {
+                    '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
+                    }
+                }
+            )
+        menu_qs = MenuModel.objects.filter()
+        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
+
+    def doEdit(self, userID, request_dict, response):
+        print('request_dict: ', request_dict)
+        data_dict = CommonService.request_dict_to_dict(request_dict)
+
+        if data_dict['isEdit']:
+            # data_dict.index(76)
+            data_dict.pop('isEdit')
+            keys = ['parentId', 'name', 'path', 'component', 'hidden', 'alwaysShow', 'levelHidden', 'title', 'icon',
+                    'isCustomSvg', 'noKeepAlive', 'badge', 'tabHidden', 'activeMenu', 'dot', 'dynamicNewTab',
+                    'redirect', 'menu_code', 'menutype', 'sort']
+            data = {}
+            for key in keys:
+                if key in data_dict:
+                    data[key] = data_dict[key]
+
+            MenuModel.objects.filter(id=data_dict['id']).update(**data)
+        else:
+            data_dict.pop('isEdit')
+            MenuModel.objects.create(**data_dict)
+        return response.json(0)
+
+    def doDelete(self, userID, request_dict, response):
+        id = request_dict.get('id', '')
+        MenuModel.objects.filter(id=id).delete()
+        return response.json(0)

+ 127 - 0
AdminController/RoleController.py

@@ -0,0 +1,127 @@
+#!/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: 2021/07/06 11:17
+@Version: python3.6
+@MODIFY DECORD:ansjer dev
+"""
+import json
+import time
+import urllib
+import uuid
+import boto3
+import threading
+import logging
+from boto3.session import Session
+from django.http import JsonResponse, HttpResponseRedirect, HttpResponse
+from django.views.generic.base import View
+from Model.models import Device_Info, Role, MenuModel
+from Object.ResponseObject import ResponseObject
+from Object.TokenObject import TokenObject
+from Object.UidTokenObject import UidTokenObject
+from Service.CommonService import CommonService
+from django.db.models import Q, F, Max
+from time import strftime
+
+
+class RoleView(View):
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.GET, request, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.POST, request, operation)
+
+    def validation(self, request_dict, request, operation):
+        language = request_dict.get('language', 'en')
+        response = ResponseObject(language, 'pc')
+        if operation == '??':
+            return 0
+        else:
+            tko = TokenObject(request.META.get('HTTP_AUTHORIZATION'),returntpye='pc')
+            if tko.code != 0:
+                return response.json(tko.code)
+            response.lang = tko.lang
+            userID = tko.userID
+            if operation == 'getList':
+                return self.getList(userID, request_dict, response)
+            elif operation == 'doEdit':
+                return self.doEdit(userID, request_dict, response)
+            elif operation == 'doDelete':
+                return self.doDelete(userID, request_dict, response)
+            elif operation == 'getPerms':
+                return self.getPerms(userID, request_dict, response)
+            elif operation == 'setPerms':
+                return self.setPerms(userID, request_dict, response)
+            else:
+                return response.json(404)
+
+    def getList(self, userID, request_dict, response):
+        isSelect = request_dict.get('isSelect', None)   # 获取全部数据作为角色选项
+        if isSelect:
+            role_qs = Role.objects.all().values('rid', 'roleName', 'Description')
+            return response.json(0, {'list': CommonService.qs_to_list(role_qs)})
+
+        roleName = request_dict.get('roleName', '').strip()  # 移除字符串头尾的空格
+        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)
+        if roleName:
+            role_qs = Role.objects.filter(roleName=roleName).values('rid', 'roleName', 'Description')
+        else:
+            role_qs = Role.objects.all().values('rid', 'roleName', 'Description')
+
+        count = role_qs.count()
+        role_qs = role_qs.order_by('rid')[(page - 1) * line:page * line]
+
+
+        return response.json(0, {'list': CommonService.qs_to_list(role_qs), 'total': count})
+
+    def doEdit(self, userID, request_dict, response):
+
+        data_dict = request_dict.dict()
+        # data_dict = json.loads(data_str)
+        if 'rid' in data_dict:
+            Role.objects.filter(rid=data_dict['rid']).update(**data_dict)
+        else:
+            id = Role.objects.all().aggregate(Max('rid'))['rid__max'] + 1
+            data_dict['rid'] = id
+            Role.objects.create(**data_dict)
+        return response.json(0)
+
+    def doDelete(self, userID, request_dict, response):
+        rid = request_dict.get('rid', '')
+        if not all([rid]):
+            return response.json(444)
+        Role.objects.filter(rid=rid).delete()
+        return response.json(0)
+
+    def getPerms(self, userID, request_dict, response):
+        rid = request_dict.get('rid', '')
+
+        if rid:
+            role_qs = Role.objects.filter(rid=rid).values('menu__id')
+            return response.json(0, CommonService.qs_to_list(role_qs))
+
+        return response.json(0)
+
+    def setPerms(self, userID, request_dict, response):
+        rid = request_dict.get('rid', '')
+        permsIds = request_dict.get('permsIds', '')
+        if not all([rid]):
+            return response.json(444)
+        Role.objects.get(rid=rid).menu.clear()
+        menu_obj = MenuModel.objects.filter(id__in=permsIds.split(','))
+        Role.objects.filter(rid=rid)[0].menu.add(*menu_obj)
+        return response.json(0)

+ 1146 - 0
AdminController/ServeManagementController.py

@@ -0,0 +1,1146 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+import hashlib
+import json
+import time
+import urllib
+import uuid
+import boto3
+import threading
+import logging
+
+import xlwt
+from boto3.session import Session
+from django.http import JsonResponse, HttpResponseRedirect, HttpResponse, StreamingHttpResponse
+from django.views.generic.base import View
+from Model.models import Device_Info, Role, MenuModel, VodBucketModel, CDKcontextModel, Store_Meal, Order_Model, \
+    UID_Bucket, ExperienceContextModel, Lang, Device_User, CloudLogModel, UidSetModel
+from Object.ResponseObject import ResponseObject
+from Object.TokenObject import TokenObject
+from Object.UidTokenObject import UidTokenObject
+from Service.CommonService import CommonService
+from django.db.models import Q, F
+from time import strftime
+
+
+class serveManagement(View):
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.GET, request, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.POST, request, operation)
+
+    def validation(self, request_dict, request, operation):
+        language = request_dict.get('language', 'en')
+        response = ResponseObject(language, 'pc')
+        if operation == 'exportCloudUserList':  # 导出云存用户信息
+            return self.exportCloudUserList(request_dict, response)
+        elif operation == 'getCloudDataList':
+            return self.getCloudDataList(request_dict, response)
+        else:
+            tko = TokenObject(
+                request.META.get('HTTP_AUTHORIZATION'),
+                returntpye='pc')
+            if tko.code != 0:
+                return response.json(tko.code)
+            response.lang = tko.lang
+            userID = tko.userID
+            if operation == 'getVodBucketList':
+                return self.getVodBucketList(userID, request_dict, response)
+            elif operation == 'addOrEditVodBucket':
+                return self.addOrEditVodBucket(userID, request_dict, response)
+            elif operation == 'deleteVodBucket':
+                return self.deleteVodBucket(userID, request_dict, response)
+            elif operation == 'getStoreMealList':
+                return self.getStoreMealList(userID, request_dict, response)
+            elif operation == 'addOrEditStoreMeal':
+                return self.addOrEditStoreMeal(userID, request_dict, response)
+            elif operation == 'deleteStoreMeal':
+                return self.deleteStoreMeal(userID, request_dict, response)
+            elif operation == 'getStoreMealLanguage':
+                return self.getStoreMealLanguage(
+                    userID, request_dict, response)
+            elif operation == 'addOrEditStoreMealLanguage':
+                return self.addOrEditStoreMealLanguage(
+                    userID, request_dict, response)
+            elif operation == 'deleteStoreMealLanguage':
+                return self.deleteStoreMealLanguage(
+                    userID, request_dict, response)
+            elif operation == 'getCdkList':
+                return self.getCdkList(userID, request_dict, response)
+            elif operation == 'createCdk':
+                return self.createCdk(request_dict, response)
+            elif operation == 'deleteCdk':
+                return self.deleteCdk(request_dict, response)
+            elif operation == 'downloadCDK':
+                return self.downloadCDK(request_dict, response)
+            elif operation == 'getDeviceOrderList':
+                return self.getDeviceOrderList(request_dict, response)
+            elif operation == 'deleteDeviceOrder':
+                return self.deleteDeviceOrder(userID, request_dict, response)
+            elif operation == 'getDevicePackageList':
+                return self.getDevicePackageList(request_dict, response)
+            elif operation == 'deleteDevicePackage':
+                return self.deleteDevicePackage(userID, request_dict, response)
+            elif operation == 'experiencereset':  # 重置设备云存体验
+                return self.do_experience_reset(request_dict, userID, response)
+            elif operation == 'getCloudUserList':  # 获取云存用户信息
+                return self.getCloudUserList(request_dict, response)
+            else:
+                return response.json(404)
+
+    def getVodBucketList(self, userID, request_dict, response):
+        # 查询存储桶数据
+        print('request_dict: ', request_dict)
+
+        isSelect = request_dict.get('isSelect', None)
+        if isSelect:
+            # 获取全部数据作为存储桶选项
+            vod_bucket_qs = VodBucketModel.objects.all().values('id', 'bucket')
+            return response.json(
+                0, {'list': CommonService.qs_to_list(vod_bucket_qs)})
+
+        bucket = request_dict.get('bucket', None)
+        mold = request_dict.get('mold', None)
+        is_free = request_dict.get('is_free', None)
+        pageNo = request_dict.get('pageNo', None)
+        pageSize = request_dict.get('pageSize', None)
+
+        if not all([pageNo, pageSize]):
+            return response.json(444)
+
+        page = int(pageNo)
+        line = int(pageSize)
+        try:
+            if bucket or mold or is_free:   # 条件查询
+                if bucket:
+                    vod_bucket_qs = VodBucketModel.objects.filter(
+                        bucket=bucket)
+                elif mold:
+                    vod_bucket_qs = VodBucketModel.objects.filter(
+                        mold=int(mold))
+                elif is_free:
+                    vod_bucket_qs = VodBucketModel.objects.filter(
+                        is_free=int(is_free))
+            else:   # 查询全部
+                vod_bucket_qs = VodBucketModel.objects.filter().all()
+            total = len(vod_bucket_qs)
+            vod_buckets = vod_bucket_qs[(page - 1) * line:page * line]
+            vod_bucket_list = []
+            for vod_bucket in vod_buckets:
+                vod_bucket_list.append({
+                    'bucketID': vod_bucket.id,
+                    'bucket': vod_bucket.bucket,
+                    'content': vod_bucket.content,
+                    'mold': vod_bucket.mold,
+                    'area': vod_bucket.area,
+                    'region': vod_bucket.region,
+                    'endpoint': vod_bucket.endpoint,
+                    'is_free': vod_bucket.is_free,
+                    'storeDay': vod_bucket.storeDay,
+                    'region_id': vod_bucket.region_id,
+                    'addTime': time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(vod_bucket.addTime)),
+                    'updTime': time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(vod_bucket.updTime)),
+                })
+            print('vod_bucket_list: ', vod_bucket_list)
+            return response.json(
+                0, {'list': vod_bucket_list, 'total': total})
+        except Exception as e:
+            print(e)
+            return response.json(500, repr(e))
+
+    def addOrEditVodBucket(self, userID, request_dict, response):
+        # 添加/编辑存储桶
+        print('request_dict: ', request_dict)
+        bucketID = request_dict.get('bucketID', None)
+        bucket = request_dict.get('bucket', '').strip()   # 移除字符串头尾的空格
+        content = request_dict.get('content', '').strip()
+        mold = int(request_dict.get('mold', 1))
+        area = request_dict.get('area', '').strip()
+        region = request_dict.get('region', '').strip()
+        endpoint = request_dict.get('endpoint', '').strip()
+        is_free = int(request_dict.get('is_free', 0))
+        storeDay = int(request_dict.get('storeDay', 0))
+        region_id = int(request_dict.get('region_id', 1))
+        isEdit = request_dict.get('isEdit', None)
+
+        if not all([bucket, content, area, region, endpoint]):
+            return response.json(444)
+
+        try:
+            now_time = int(time.time())
+            vod_bucket_data = {
+                'bucket': bucket,
+                'content': content,
+                'mold': mold,
+                'area': area,
+                'region': region,
+                'endpoint': endpoint,
+                'is_free': is_free,
+                'storeDay': storeDay,
+                'region_id': region_id,
+            }
+            if isEdit:
+                if not bucketID:
+                    return response.json(444)
+                vod_bucket_data['updTime'] = now_time
+                VodBucketModel.objects.filter(
+                    id=bucketID).update(
+                    **vod_bucket_data)
+            else:
+                vod_bucket_data['addTime'] = now_time
+                VodBucketModel.objects.create(**vod_bucket_data)
+            return response.json(0)
+        except Exception as e:
+            print(e)
+            return response.json(500, repr(e))
+
+    def deleteVodBucket(self, userID, request_dict, response):
+        # 删除存储桶
+        print('request_dict: ', request_dict)
+        bucketID = request_dict.get('bucketID', None)
+        if not bucketID:
+            return response.json(444)
+        try:
+            VodBucketModel.objects.filter(id=bucketID).delete()
+            return response.json(0)
+        except Exception as e:
+            print(e)
+            return response.json(500, repr(e))
+
+    def getStoreMealList(self, userID, request_dict, response):
+        # 获取云存套餐信息数据
+        print('request_dict: ', request_dict)
+
+        isSelect = request_dict.get('isSelect', None)
+        if isSelect:
+            # 获取套餐ID作为选项
+            store_meal_qs = Store_Meal.objects.all().values('id', 'bucket__bucket')
+            return response.json(
+                0, {'list': CommonService.qs_to_list(store_meal_qs)})
+
+        bucket = request_dict.get('bucket', None)
+        pageNo = request_dict.get('pageNo', None)
+        pageSize = request_dict.get('pageSize', None)
+
+        if not all([pageNo, pageSize]):
+            return response.json(444)
+
+        page = int(pageNo)
+        line = int(pageSize)
+        try:
+            if bucket:   # 条件查询
+                bucket_id = VodBucketModel.objects.filter(
+                    bucket=bucket).values('id')[0]['id']
+                store_meal_qs = Store_Meal.objects.filter(
+                    bucket_id=bucket_id)
+            else:   # 查询全部
+                store_meal_qs = Store_Meal.objects.filter()
+            store_meal_val = store_meal_qs.values(
+                'id',
+                'bucket__bucket',
+                'day',
+                'expire',
+                'commodity_type',
+                'commodity_code',
+                'is_discounts',
+                'discount_price',
+                'virtual_price',
+                'price',
+                'currency',
+                'symbol',
+                'is_show',
+                'add_time',
+                'update_time')
+            total = len(store_meal_val)
+            store_meals = store_meal_val[(page - 1) * line:page * line]
+            store_meal_list = []
+            for store_meal in store_meals:
+                # 获取支付方式列表
+                pay_type_list = [
+                    pay_type['id'] for pay_type in Store_Meal.objects.get(
+                        id=store_meal['id']).pay_type.values('id')]
+                # 组织响应数据
+                store_meal_list.append({
+                    'storeMealID': store_meal['id'],
+                    'bucket': store_meal['bucket__bucket'],
+                    'day': store_meal['day'],
+                    'expire': store_meal['expire'],
+                    'commodity_type': store_meal['commodity_type'],
+                    'pay_type': pay_type_list,
+                    'commodity_code': store_meal['commodity_code'],
+                    'is_discounts': store_meal['is_discounts'],
+                    'discount_price': store_meal['discount_price'],
+                    'virtual_price': store_meal['virtual_price'],
+                    'price': store_meal['price'],
+                    'currency': store_meal['currency'],
+                    'symbol': store_meal['symbol'],
+                    'is_show': store_meal['is_show'],
+                    'addTime': store_meal['add_time'].strftime("%Y-%m-%d %H:%M:%S"),
+                    'updTime': store_meal['update_time'].strftime("%Y-%m-%d %H:%M:%S"),
+                })
+            print('store_meal_list: ', store_meal_list)
+            return response.json(
+                0, {'list': store_meal_list, 'total': total})
+        except Exception as e:
+            print(e)
+            return response.json(500, repr(e))
+
+    def addOrEditStoreMeal(self, userID, request_dict, response):
+        # 添加/编辑套餐
+        print('request_dict: ', request_dict)
+        storeMealID = request_dict.get('storeMealID', None)
+        bucket = request_dict.get('bucket', '')
+        day = int(request_dict.get('day', 0))
+        expire = int(request_dict.get('expire', 0))
+        commodity_type = int(request_dict.get('commodity_type', 0))
+        pay_type = request_dict.get(
+            'pay_type', '')[
+            1:-1].split(',')    # '[1,2]' -> ['1','2']
+        commodity_code = request_dict.get('commodity_code', '')
+        is_discounts = int(request_dict.get('is_discounts', 0))
+        discount_price = request_dict.get('discount_price', '')
+        virtual_price = request_dict.get('virtual_price', '')
+        price = request_dict.get('price', '')
+        currency = request_dict.get('currency', '')
+        symbol = request_dict.get('symbol', '')
+        is_show = int(request_dict.get('is_show', 0))
+        isEdit = request_dict.get('isEdit', None)
+
+        if not all([bucket, pay_type, price, currency, symbol]):
+            return response.json(444)
+
+        try:
+            bucket_id = VodBucketModel.objects.filter(
+                bucket=bucket).values('id')[0]['id']
+            store_meal_data = {
+                'bucket_id': bucket_id,
+                'day': day,
+                'expire': expire,
+                'commodity_type': commodity_type,
+                'commodity_code': commodity_code,
+                'is_discounts': is_discounts,
+                'discount_price': discount_price,
+                'virtual_price': virtual_price,
+                'price': price,
+                'currency': currency,
+                'symbol': symbol,
+                'is_show': is_show,
+            }
+            if isEdit:
+                if not storeMealID:
+                    return response.json(444)
+                Store_Meal.objects.filter(
+                    id=storeMealID).update(
+                    **store_meal_data)
+                Store_Meal.objects.get(id=storeMealID).pay_type.set(pay_type)
+            else:
+                Store_Meal.objects.create(
+                    **store_meal_data).pay_type.set(pay_type)
+            return response.json(0)
+        except Exception as e:
+            print(e)
+            return response.json(500, repr(e))
+
+    def deleteStoreMeal(self, userID, request_dict, response):
+        # 删除套餐信息
+        print('request_dict: ', request_dict)
+        storeMealID = request_dict.get('storeMealID', None)
+        if not storeMealID:
+            return response.json(444)
+        try:
+            Store_Meal.objects.filter(id=storeMealID).delete()
+            return response.json(0)
+        except Exception as e:
+            print(e)
+            return response.json(500, repr(e))
+
+    def getStoreMealLanguage(self, userID, request_dict, response):
+        # 获取套餐语言
+        print('request_dict: ', request_dict)
+        storeMealID = request_dict.get('storeMealID', None)
+        pageNo = request_dict.get('pageNo', None)
+        pageSize = request_dict.get('pageSize', None)
+
+        if not all([pageNo, pageSize]):
+            return response.json(444)
+
+        page = int(pageNo)
+        line = int(pageSize)
+        try:
+            if storeMealID:   # 条件查询
+                store_meal_lang_qs = Store_Meal.objects.filter(id=storeMealID)
+            else:   # 查询全部
+                store_meal_lang_qs = Store_Meal.objects.filter(
+                    lang__isnull=False)
+            store_meal_lang_val = store_meal_lang_qs.values(
+                'id',
+                'lang__id',
+                'lang__lang',
+                'lang__title',
+                'lang__content',
+                'lang__discount_content',
+            )
+            total = len(store_meal_lang_val)
+            store_meal_langs = store_meal_lang_val[(
+                page - 1) * line:page * line]
+            store_meal_lang_list = []
+            for store_meal_lang in store_meal_langs:
+                store_meal_lang_list.append({
+                    'storeMealID': store_meal_lang['id'],
+                    'langID': store_meal_lang['lang__id'],
+                    'lang': store_meal_lang['lang__lang'],
+                    'title': store_meal_lang['lang__title'],
+                    'content': store_meal_lang['lang__content'],
+                    'discountContent': store_meal_lang['lang__discount_content'],
+                })
+            print('store_meal_lang_list: ', store_meal_lang_list)
+            return response.json(
+                0, {'list': store_meal_lang_list, 'total': total})
+        except Exception as e:
+            print(e)
+            return response.json(500, repr(e))
+
+    def addOrEditStoreMealLanguage(self, userID, request_dict, response):
+        # 添加/编辑套餐语言
+        print('request_dict: ', request_dict)
+        storeMealID = request_dict.get('storeMealID', None)
+        lang = request_dict.get('lang', None)
+        title = request_dict.get('title', None)
+        content = request_dict.get('content', None)
+        discount_content = request_dict.get('discount_content', '')
+        isEdit = request_dict.get('isEdit', None)
+
+        if not all([storeMealID, lang, title, content]):
+            return response.json(444)
+
+        try:
+            # 查询套餐是否存在
+            store_meal_qs = Store_Meal.objects.get(id=storeMealID)
+            if not store_meal_qs:
+                return response.json(173)
+            if isEdit:  # 编辑
+                langID = request_dict.get('langID', None)
+                if not langID:
+                    return response.json(444)
+                Lang.objects.filter(
+                    id=langID).update(
+                    lang=lang,
+                    title=title,
+                    content=content,
+                    discount_content=discount_content)
+            else:   # 添加
+                lang_obj = Lang.objects.filter(
+                    lang=lang,
+                    title=title,
+                    content=content,
+                    discount_content=discount_content)
+                if not lang_obj.exists():
+                    # 数据不存在,lang表创建数据
+                    Lang.objects.create(
+                        lang=lang,
+                        title=title,
+                        content=content,
+                        discount_content=discount_content)
+                    lang_obj = Lang.objects.filter(
+                        lang=lang,
+                        title=title,
+                        content=content,
+                        discount_content=discount_content)
+                store_meal_qs.lang.add(*lang_obj)  # store_meal表添加语言数据
+            return response.json(0)
+        except Exception as e:
+            print(e)
+            return response.json(500, repr(e))
+
+    def deleteStoreMealLanguage(self, userID, request_dict, response):
+        # 删除套餐语言
+        storeMealID = request_dict.get('storeMealID', None)
+        langID = request_dict.get('langID', None)
+
+        if not all([storeMealID, langID]):
+            return response.json(444)
+
+        try:
+            storeMeal_qs = Store_Meal.objects.get(id=storeMealID)
+            if not storeMeal_qs:
+                return response.json(173)
+            lang_qs = Lang.objects.filter(id=langID)
+            storeMeal_qs.lang.remove(*lang_qs)
+            return response.json(0)
+        except Exception as e:
+            print(e)
+            return response.json(500, repr(e))
+
+    def getCdkList(self, userID, request_dict, response):
+        # 获取激活码列表
+        pageNo = request_dict.get('pageNo', None)
+        pageSize = request_dict.get('pageSize', None)
+        cdk = request_dict.get('cdk', None)
+        order = request_dict.get('order', None)
+        is_activate = request_dict.get('is_activate', None)
+        mold = request_dict.get('mold', None)
+        lang = request_dict.get('lang', 'cn')
+        if not all([pageNo, pageSize]):
+            return response.json(444)
+
+        page = int(pageNo)
+        line = int(pageSize)
+        try:
+            if cdk:
+                searchVal = cdk.strip()
+            if order:
+                searchVal = order.strip()
+            if is_activate:
+                searchVal = is_activate.strip()
+
+            cdk_qs = CDKcontextModel.objects.filter().all()
+            if cdk:
+                cdk_qs = cdk_qs.filter(cdk__contains=searchVal)
+            if order:
+                cdk_qs = cdk_qs.filter(order__contains=searchVal)
+            if is_activate:
+                cdk_qs = cdk_qs.filter(is_activate=searchVal)
+            if mold:
+                cdk_qs = cdk_qs.filter(rank__bucket__mold=mold)
+
+            cdk_qs = cdk_qs.filter(rank__lang__lang=lang)
+            cdk_qs = cdk_qs.annotate(rank__title=F('rank__lang__title'))
+            cdk_qs = cdk_qs.values(
+                'id',
+                'cdk',
+                'create_time',
+                'valid_time',
+                'is_activate',
+                'rank__id',
+                'rank__title',
+                'order',
+                'create_time',
+                'rank__bucket__mold')
+            cdk_qs = cdk_qs.order_by('-create_time')  # 根据CDK创建时间降序排序
+            count = cdk_qs.count()
+            cdk_qs = cdk_qs[(page - 1) * line:page * line]
+            return response.json(
+                0, {'list': list(cdk_qs), 'total': count})
+        except Exception as e:
+            print(e)
+            return response.json(500, repr(e))
+
+    def createCdk(self, request_dict, response):
+        cdk_num = request_dict.get("cdknum", None)
+        mold = request_dict.get('mold', None)
+        order = request_dict.get('order', None)
+        cdk_list = []
+        sm_qs = Store_Meal.objects.filter(
+            pay_type__payment='cdk_pay', bucket__mold=mold)
+        if sm_qs.exists:
+            rank = sm_qs[0].id
+            for i in range(int(cdk_num)):
+                nowTime = int(time.time())
+                cdk = hashlib.md5((str(uuid.uuid1()) +
+                                   str(nowTime)).encode('utf-8')).hexdigest()
+                cdk_model = CDKcontextModel(
+                    cdk=cdk,
+                    create_time=nowTime,
+                    valid_time=0,
+                    is_activate=0,
+                    rank_id=rank,
+                    order=order,
+                )
+                cdk_list.append(cdk_model)
+            try:
+                CDKcontextModel.objects.bulk_create(cdk_list)
+            except Exception as e:
+                print(repr(e))
+                return response.json(404, repr(e))
+            else:
+                return response.json(0)
+
+        return response.json(0)
+
+    def deleteCdk(self, request_dict, response):
+        cdk_id = request_dict.get("id", None)
+        try:
+            CDKcontextModel.objects.get(id=cdk_id).delete()
+            return response.json(0)
+        except Exception as e:
+            return response.json(500, repr(e))
+
+    def downloadCDK(self, request_dict, response):
+        region = request_dict.get('region', None)
+        content = ''
+        if region == 'cn':
+            # 下载国内未使用激活码
+            content += '激活码(国内)\n'
+            cdk_inactivate_qs = CDKcontextModel.objects.filter(
+                is_activate=0, rank__bucket__mold=0).values('cdk')
+        else:
+            # 下载国外未使用激活码
+            content += '激活码(国外)\n'
+            cdk_inactivate_qs = CDKcontextModel.objects.filter(
+                is_activate=0, rank__bucket__mold=1).values('cdk')
+        for cdk_inactivate in cdk_inactivate_qs:
+            content += cdk_inactivate['cdk'] + '\n'
+        # print(content)
+
+        response = StreamingHttpResponse(content)
+        response['Content-Type'] = 'application/octet-stream'
+        response['Content-Disposition'] = 'attachment;filename="CDK.txt"'
+        return response
+
+    def getDeviceOrderList(self, request_dict, response):
+        print('request_dict: ', request_dict)
+        pageNo = request_dict.get('pageNo', None)
+        pageSize = request_dict.get('pageSize', None)
+        uid = request_dict.get('uid', None)
+        channel = request_dict.get('channel', None)
+        orderID = request_dict.get('orderID', None)
+        userID__username = request_dict.get('userID__username', None)
+        currency = request_dict.get('currency', None)
+        payType = request_dict.get('payType', None)
+        status = request_dict.get('status', None)
+        timeRange = request_dict.getlist('timeRange[]', None)
+
+        if not all([pageNo, pageSize]):
+            return response.json(444)
+
+        page = int(pageNo)
+        line = int(pageSize)
+        try:
+            omqs = Order_Model.objects.all()
+            # 筛选指定设备id的订单
+            if uid:
+                omqs = omqs.filter(UID=uid)
+            if channel:
+                omqs = omqs.filter(channel=channel)
+            if orderID:
+                omqs = omqs.filter(orderID=orderID)
+            if userID__username:
+                omqs = omqs.filter(userID__username=userID__username)
+            if currency:
+                omqs = omqs.filter(currency=currency)
+            if payType:
+                omqs = omqs.filter(payType=payType)
+            if status:
+                omqs = omqs.filter(status=status)
+            if timeRange:
+                startTime, endTime = int(
+                    timeRange[0][:-3]), int(timeRange[1][:-3])
+                omqs = omqs.filter(
+                    addTime__gte=startTime,
+                    addTime__lte=endTime)
+            if not omqs.exists():
+                return response.json(0, [])
+
+            count = omqs.count()
+
+            order_ql = omqs.values(
+                "orderID",
+                "UID",
+                "userID__username",
+                "channel",
+                "desc",
+                "price",
+                "currency",
+                "addTime",
+                "updTime",
+                "paypal",
+                "payType",
+                "rank__day",
+                "rank__price",
+                "status")
+            order_ql = order_ql.order_by('-addTime')  # 根据CDK创建时间降序排序
+            order_ql = order_ql[(page - 1) * line:page * line]
+            return response.json(
+                0, {'list': list(order_ql), 'total': count})
+        except Exception as e:
+            print(e)
+            return response.json(500, repr(e))
+
+    def deleteDeviceOrder(self, userID, request_dict, response):
+        orderID = request_dict.get('orderID', None)
+
+        if orderID:
+            Order_Model.objects.filter(orderID=orderID).delete()
+            return response.json(0)
+        else:
+            return response.json(444)
+
+    def getDevicePackageList(self, request_dict, response):
+        pageNo = request_dict.get('pageNo', None)
+        pageSize = request_dict.get('pageSize', None)
+        uid = request_dict.get('uid', None)
+        if not all([pageNo, pageSize]):
+            return response.json(444)
+
+        page = int(pageNo)
+        line = int(pageSize)
+        try:
+            ubqs = UID_Bucket.objects.all()
+            if uid:
+                ubqs = ubqs.filter(uid__contains=uid)
+
+            if not ubqs.exists():
+                return response.json(0, [])
+
+            count = ubqs.count()
+            ubqs = ubqs.values(
+                'id',
+                'uid',
+                'channel',
+                'status',
+                'endTime',
+                'bucket__bucket',
+                'bucket__storeDay',
+                'bucket__area')
+
+            ubqs = ubqs.order_by('-addTime')  # 根据CDK创建时间降序排序
+            ubqs = ubqs[(page - 1) * line:page * line]
+            return response.json(
+                0, {'list': list(ubqs), 'total': count})
+        except Exception as e:
+            print(e)
+            return response.json(500, repr(e))
+
+    def deleteDevicePackage(self, userID, request_dict, response):
+        orderID = request_dict.get('orderID', None)
+
+        if orderID:
+            Order_Model.objects.filter(orderID=orderID).delete()
+            return response.json(0)
+        else:
+            return response.json(444)
+
+    # 重置设备云存体验
+    def do_experience_reset(self, request_dict, userID, response):
+        bid = request_dict.get("id", None)
+        ubq = UID_Bucket.objects.filter(id=bid)
+        if ubq:
+            eq = ExperienceContextModel.objects.filter(uid=ubq[0].uid)
+            if eq:
+                eq.delete()
+                Order_Model.objects.filter(uid_bucket_id=bid).delete()
+                ubq.delete()
+                return response.json(0)
+            else:
+                return response.json(10007)
+
+        else:
+            return response.json(0, '重置云存体验失败')
+
+    def getCloudUserList(self, request_dict, response):
+        print('request_dict: ', request_dict)
+
+        # UID_Bucket表查询数据
+        uid = request_dict.get('uid', None)
+        status = request_dict.get('status', None)
+        use_status = request_dict.get('use_status', None)
+        has_unused = request_dict.get('has_unused', None)
+        addTimeRange = request_dict.getlist('addTimeRange[]', None)
+        endTimeRange = request_dict.getlist('endTimeRange[]', None)
+
+        # Order_Model表查询数据
+        username = request_dict.get('username', None)
+        phone = request_dict.get('phone', None)
+        userEmail = request_dict.get('userEmail', None)
+        payType = request_dict.get('payType', None)
+
+        # uid_set 表查询
+        ucode = request_dict.getlist('ucode', None)
+        version = request_dict.getlist('version', None)
+
+        # 日志表查询
+        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:
+                uid_bucket_qs = uid_bucket_qs.filter(uid__contains=uid)
+            if status:
+                uid_bucket_qs = uid_bucket_qs.filter(status=status)
+            if use_status:
+                uid_bucket_qs = uid_bucket_qs.filter(use_status=use_status)
+            if has_unused:
+                uid_bucket_qs = uid_bucket_qs.filter(has_unused=has_unused)
+            if addTimeRange:
+                addStartTime, addEndTime = int(
+                    addTimeRange[0][:-3]), int(addTimeRange[1][:-3])
+                uid_bucket_qs = uid_bucket_qs.filter(
+                    addTime__gte=addStartTime,
+                    addTime__lte=addEndTime)
+            if endTimeRange:
+                endStartTime, endEndTime = int(
+                    endTimeRange[0][:-3]), int(endTimeRange[1][:-3])
+                uid_bucket_qs = uid_bucket_qs.filter(
+                    addTime__gte=endStartTime,
+                    addTime__lte=endEndTime)
+            if not uid_bucket_qs.exists():
+                return response.json(0, [])
+
+            order_qs = Order_Model.objects.filter(
+                uid_bucket_id__in=uid_bucket_qs.values('id'))
+            if username or phone or userEmail or payType:
+                if username:
+                    order_qs = order_qs.filter(userID__username=username)
+                if phone:
+                    order_qs = order_qs.filter(userID__phone__contains=phone)
+                if userEmail:
+                    order_qs = order_qs.filter(
+                        userID__userEmail__contains=userEmail)
+                if payType:
+                    order_qs = order_qs.filter(payType=int(payType))
+                # 过滤套餐关联的UID_Bucket数据
+                uid_bucket_qs = uid_bucket_qs.filter(
+                    id__in=order_qs.values_list(
+                        'uid_bucket_id', flat=True))
+
+            uidset_qs = UidSetModel.objects.filter(
+                uid__in=uid_bucket_qs.values('uid'))
+            if ucode or version:
+                if ucode:
+                    uidset_qs = uidset_qs.filter(ucode=ucode)
+                if version:
+                    uidset_qs = uidset_qs.filter(version=version)
+
+            cg_qs = CloudLogModel.objects.filter(
+                operation='cloudstorage/queryvodlist')
+            if logTimeRange:
+                logStartTime, logEndTime = int(
+                    logTimeRange[0][:-3]), int(logTimeRange[1][:-3])
+                cg_qs = cg_qs.filter(
+                    time__gte=logStartTime,
+                    time__lte=logEndTime)
+                # 过滤套餐关联的UID_Bucket数据
+                uid_bucket_qs = uid_bucket_qs.filter(
+                    uid__in=cg_qs.values('uid'))
+
+            list_data = []
+            count = uid_bucket_qs.count()
+            uid_bucket_qs = uid_bucket_qs[(page - 1) * line:page * line]
+
+            for uid_bucket in uid_bucket_qs:
+                data = {
+                    'id': uid_bucket.id,
+                    'uid': uid_bucket.uid,
+                    'channel': uid_bucket.channel,
+                    'status': uid_bucket.status,
+                    'endTime': time.strftime(
+                        "%Y--%m--%d %H:%M:%S",
+                        time.localtime(
+                            uid_bucket.endTime)),
+                    'addTime': time.strftime(
+                        "%Y--%m--%d %H:%M:%S",
+                        time.localtime(
+                            uid_bucket.addTime)),
+                    'use_status': uid_bucket.use_status,
+                    'has_unused': uid_bucket.has_unused}
+
+                for order in order_qs.filter(
+                        uid_bucket_id=uid_bucket.id).values(
+                        'uid_bucket_id',
+                        'desc',
+                        'userID__userID',
+                        'UID',
+                        'price',
+                        'payType',
+                        'userID__username',
+                        'userID__phone',
+                        'userID__userEmail',
+                        'userID__data_joined'):
+                    data['desc'] = order['desc']
+                    data['payType'] = order['payType']
+                    data['price'] = order['price']
+                    data['username'] = order['userID__username']
+                    data['phone'] = order['userID__phone']
+                    data['userEmail'] = order['userID__userEmail']
+                    data['data_joined'] = order['userID__data_joined'].strftime(
+                        "%Y-%m-%d %H:%M:%S")
+                    data['playcount'] = cg_qs.filter(
+                        operation='cloudstorage/queryvodlist', uid=order['UID']).count()
+
+                for uidset in uidset_qs.filter(
+                        uid=uid_bucket.uid).values(
+                        'ucode',
+                        'version'):
+                    data['ucode'] = uidset['ucode']
+                    data['version'] = uidset['version']
+
+                list_data.append(data)
+            return response.json(
+                0, {'list': list_data, 'total': count})
+        except Exception as e:
+            print(e)
+            return response.json(500, repr(e))
+
+    def exportCloudUserList(self, request_dict, response):
+        # UID_Bucket表查询数据
+        uid = request_dict.get('uid', None)
+        status = request_dict.get('status', None)
+        use_status = request_dict.get('use_status', None)
+        has_unused = request_dict.get('has_unused', None)
+        addTimeRange = request_dict.getlist('addTimeRange[]', None)
+        endTimeRange = request_dict.getlist('endTimeRange[]', None)
+
+        # Order_Model表查询数据
+        username = request_dict.get('username', None)
+        phone = request_dict.get('phone', None)
+        userEmail = request_dict.get('userEmail', None)
+        payType = request_dict.get('payType', None)
+
+        #uid_set 表查询
+        ucode = request_dict.getlist('ucode', None)
+        version = request_dict.getlist('version', None)
+
+        # 日志表查询
+        logTimeRange = request_dict.getlist('logTimeRange[]', None)
+
+        try:
+            uid_bucket_qs = UID_Bucket.objects.all()
+            if uid:
+                uid_bucket_qs = uid_bucket_qs.filter(uid__contains=uid)
+            if status:
+                uid_bucket_qs = uid_bucket_qs.filter(status=status)
+            if use_status:
+                uid_bucket_qs = uid_bucket_qs.filter(use_status=use_status)
+            if has_unused:
+                uid_bucket_qs = uid_bucket_qs.filter(has_unused=has_unused)
+            if addTimeRange:
+                addStartTime, addEndTime = int(
+                    addTimeRange[0][:-3]), int(addTimeRange[1][:-3])
+                uid_bucket_qs = uid_bucket_qs.filter(
+                    addTime__gte=addStartTime,
+                    addTime__lte=addEndTime)
+            if endTimeRange:
+                endStartTime, endEndTime = int(
+                    endTimeRange[0][:-3]), int(endTimeRange[1][:-3])
+                uid_bucket_qs = uid_bucket_qs.filter(
+                    addTime__gte=endStartTime,
+                    addTime__lte=endEndTime)
+            if not uid_bucket_qs.exists():
+                return response.json(0, [])
+
+            order_qs = Order_Model.objects.filter(
+                uid_bucket_id__in=uid_bucket_qs.values('id'))
+            if username or phone or userEmail or payType:
+                if username:
+                    order_qs = order_qs.filter(userID__username=username)
+                if phone:
+                    order_qs = order_qs.filter(userID__phone__contains=phone)
+                if userEmail:
+                    order_qs = order_qs.filter(
+                        userID__userEmail__contains=userEmail)
+                if payType:
+                    order_qs = order_qs.filter(payType=int(payType))
+                # 过滤套餐关联的UID_Bucket数据
+                uid_bucket_qs = uid_bucket_qs.filter(
+                    id__in=order_qs.values_list(
+                        'uid_bucket_id', flat=True))
+
+            uidset_qs = UidSetModel.objects.filter(
+                uid__in=uid_bucket_qs.values('uid'))
+            if ucode or version:
+                if ucode:
+                    uidset_qs = uidset_qs.filter(ucode=ucode)
+                if version:
+                    uidset_qs = uidset_qs.filter(version=version)
+
+            cg_qs = CloudLogModel.objects.filter(
+                operation='cloudstorage/queryvodlist')
+            if logTimeRange:
+                logStartTime, logEndTime = int(
+                    logTimeRange[0][:-3]), int(logTimeRange[1][:-3])
+                cg_qs = cg_qs.filter(
+                    time__gte=logStartTime,
+                    time__lte=logEndTime)
+            list_data = []
+            count = uid_bucket_qs.count()
+            for uid_bucket in uid_bucket_qs:
+                data = {
+                    'id': uid_bucket.id,
+                    'uid': uid_bucket.uid,
+                    'channel': uid_bucket.channel,
+                    'status': uid_bucket.status,
+                    'endTime': time.strftime(
+                        "%Y--%m--%d %H:%M:%S",
+                        time.localtime(
+                            uid_bucket.endTime)),
+                    'addTime': time.strftime(
+                        "%Y--%m--%d %H:%M:%S",
+                        time.localtime(
+                            uid_bucket.addTime)),
+                    'use_status': uid_bucket.use_status,
+                    'has_unused': uid_bucket.has_unused}
+
+                for order in order_qs.filter(
+                        uid_bucket_id=uid_bucket.id).values(
+                        'uid_bucket_id',
+                        'desc',
+                        'userID__userID',
+                        'UID',
+                        'price',
+                        'payType',
+                        'userID__username',
+                        'userID__phone',
+                        'userID__userEmail',
+                        'userID__data_joined'):
+                    data['desc'] = order['desc']
+                    data['payType'] = order['payType']
+                    data['price'] = order['price']
+                    data['username'] = order['userID__username']
+                    data['phone'] = order['userID__phone']
+                    data['userEmail'] = order['userID__userEmail']
+                    data['data_joined'] = order['userID__data_joined'].strftime(
+                        "%Y-%m-%d %H:%M:%S")
+                    data['playcount'] = cg_qs.filter(
+                        operation='cloudstorage/queryvodlist', uid=order['UID']).count()
+
+                for uidset in uidset_qs.filter(
+                        uid=uid_bucket.uid).values(
+                        'ucode',
+                        'version'):
+                    data['ucode'] = uidset['ucode']
+                    data['version'] = uidset['version']
+
+                list_data.append(data)
+
+            response = HttpResponse(content_type='application/vnd.ms-excel')
+            response['Content-Disposition'] = 'attachment; filename=userinfo.xls'
+            workbook = xlwt.Workbook(encoding='utf-8')
+            sheet1 = workbook.add_sheet('UID')
+
+            headtitle = [
+              'id',
+              '用户账号',
+              '用户手机号',
+              '用户邮箱',
+              '注册时间',
+              '设备UID',
+              '设备通道',
+              '云存状态',
+              '添加时间',
+              '到期时间',
+              '使用状态',
+              '是否有未使用套餐',
+              '套餐描述',
+              '支付方式',
+              '价格',
+              '播放次数',
+              '产品编码',
+              '版本'
+            ]
+            headnum = 0
+            for title in headtitle:
+                sheet1.write(0, headnum, title)
+                headnum= headnum+1
+
+            fields = [
+              'id',
+              'username',
+              'phone',
+              'userEmail',
+              'data_joined',
+              'uid',
+              'channel',
+              'status',
+              'addTime',
+              'endTime',
+              'use_status',
+              'has_unused',
+              'desc',
+              'payType',
+              'price',
+              'playcount',
+              'ucode',
+              'version'
+            ]
+            num = 1
+            for item in list_data:
+                fieldnum = 0
+                for key in fields:
+                    val = item[key]
+                    if key == 'payType':
+                        if val == 1:
+                            val = 'PayPal'
+                        if val == 2:
+                            val = '支付宝'
+                        if val == 3:
+                            val = '微信支付'
+                        if val == 10:
+                            val = '免费体验'
+                        if val == 11:
+                            val = '激活码'
+
+                    sheet1.write(num, fieldnum, val)
+                    fieldnum = fieldnum+1
+                num =num+1
+            workbook.save(response)
+            return response
+        except Exception as e:
+            print(e)
+            return response.json(500, repr(e))
+
+    def getCloudDataList(self, request_dict, response):
+        year = request_dict.get('year', None)
+        Jan = int(time.mktime(time.strptime(year + '-1-1 00:00:00', "%Y-%m-%d %H:%M:%S")))
+        Feb = int(time.mktime(time.strptime(year + '-2-1 00:00:00', "%Y-%m-%d %H:%M:%S")))
+        Mar = int(time.mktime(time.strptime(year + '-3-1 00:00:00', "%Y-%m-%d %H:%M:%S")))
+        Apr = int(time.mktime(time.strptime(year + '-4-1 00:00:00', "%Y-%m-%d %H:%M:%S")))
+        May = int(time.mktime(time.strptime(year + '-5-1 00:00:00', "%Y-%m-%d %H:%M:%S")))
+        Jun = int(time.mktime(time.strptime(year + '-6-1 00:00:00', "%Y-%m-%d %H:%M:%S")))
+        Jul = int(time.mktime(time.strptime(year + '-7-1 00:00:00', "%Y-%m-%d %H:%M:%S")))
+        Aug = int(time.mktime(time.strptime(year + '-8-1 00:00:00', "%Y-%m-%d %H:%M:%S")))
+        Sep = int(time.mktime(time.strptime(year + '-9-1 00:00:00', "%Y-%m-%d %H:%M:%S")))
+        Oct = int(time.mktime(time.strptime(year + '-10-1 00:00:00', "%Y-%m-%d %H:%M:%S")))
+        Nov = int(time.mktime(time.strptime(year + '-11-1 00:00:00', "%Y-%m-%d %H:%M:%S")))
+        Dec = int(time.mktime(time.strptime(year + '-12-1 00:00:00', "%Y-%m-%d %H:%M:%S")))
+        Jan_next = int(time.mktime(time.strptime(str(int(year)+1) + '-1-1 00:00:00', "%Y-%m-%d %H:%M:%S")))
+
+        list_data = []
+        vod_bucket_qs = VodBucketModel.objects.filter()
+        if not vod_bucket_qs.exists():
+            return response.json(173)
+        try:
+            for vod_bucket in vod_bucket_qs:
+                vod_bucket_id = vod_bucket.id
+                store_meal = Store_Meal.objects.filter(bucket_id=vod_bucket_id, lang__lang='cn').values('lang__title', 'lang__content')
+                if not store_meal.exists():
+                    continue
+                name = store_meal[0]['lang__title']+'-'+store_meal[0]['lang__content']
+                order = Order_Model.objects.filter(rank__bucket_id=vod_bucket_id)
+                Jan_count = order.filter(status=1, addTime__range=[Jan, Feb]).count()
+                Feb_count = order.filter(status=1, addTime__range=[Feb, Mar]).count()
+                Mar_count = order.filter(status=1, addTime__range=[Mar, Apr]).count()
+                Apr_count = order.filter(status=1, addTime__range=[Apr, May]).count()
+                May_count = order.filter(status=1, addTime__range=[May, Jun]).count()
+                Jun_count = order.filter(status=1, addTime__range=[Jun, Jul]).count()
+                Jul_count = order.filter(status=1, addTime__range=[Jul, Aug]).count()
+                Aug_count = order.filter(status=1, addTime__range=[Aug, Sep]).count()
+                Sep_count = order.filter(status=1, addTime__range=[Sep, Oct]).count()
+                Oct_count = order.filter(status=1, addTime__range=[Oct, Nov]).count()
+                Nov_count = order.filter(status=1, addTime__range=[Nov, Dec]).count()
+                Dec_count = order.filter(status=1, addTime__range=[Dec, Jan_next]).count()
+                data = [Jan_count, Feb_count, Mar_count, Apr_count, May_count, Jun_count, Jul_count, Aug_count, Sep_count,
+                        Oct_count, Nov_count, Dec_count]
+
+                cloud_data = {
+                    'name': name,
+                    'type': 'line',
+                    'data': data,
+                }
+                list_data.append(cloud_data)
+
+            return response.json(0, {'list': list_data})
+        except Exception as e:
+            print(e)
+            return response.json(500, repr(e))

+ 81 - 0
AdminController/TestServeController.py

@@ -0,0 +1,81 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+
+import json
+import time
+import urllib
+import uuid
+import boto3
+import threading
+import logging
+from boto3.session import Session
+from django.http import JsonResponse, HttpResponseRedirect, HttpResponse
+from django.views.generic.base import View
+from Model.models import Device_Info, Role, MenuModel
+from Object.ResponseObject import ResponseObject
+from Object.TokenObject import TokenObject
+from Object.UidTokenObject import UidTokenObject
+from Service.CommonService import CommonService
+from django.db.models import Q, F
+from time import strftime
+
+
+class TestServeView(View):
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.GET, request, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.POST, request, operation)
+
+    def validation(self, request_dict, request, operation):
+        language = request_dict.get('language', 'en')
+        response = ResponseObject(language, 'pc')
+        if operation == '??':
+            return 0
+        else:
+            tko = TokenObject(
+                request.META.get('HTTP_AUTHORIZATION'),
+                returntpye='pc')
+            # if tko.code != 0:
+            #     return response.json(tko.code)
+            response.lang = tko.lang
+            userID = tko.userID
+            if operation == 'AItest':
+                return self.AItest(userID, request, request_dict, response)
+            if operation == 'doEdit':
+                return self.doEdit(userID, request_dict, response)
+            if operation == 'doDelete':
+                return self.doDelete(userID, request_dict, response)
+            else:
+                return response.json(404)
+
+    def AItest(self, userID, request, request_dict, response):
+        file = request.FILES.get('file', None)
+        if not file:
+            return response.json(444)
+        maxLabels = int(request_dict.get('maxLabels', 5))
+        minConfidence = float(request_dict.get('minConfidence', 55))
+
+        try:
+            client = boto3.client(
+                'rekognition',
+                aws_access_key_id='AKIA2E67UIMD6JD6TN3J',
+                aws_secret_access_key='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',
+                region_name='us-east-1')
+            # doc:
+            # https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rekognition.html#Rekognition.Client.detect_labels
+            rekognition_res = client.detect_labels(
+                Image={
+                    'Bytes': file.read()},
+                MaxLabels=maxLabels,
+                MinConfidence=minConfidence)
+            print('rekognition_res: ', rekognition_res)
+            return response.json(0, {'rekognition_res': rekognition_res})
+        except Exception as e:
+            print(e)
+            return response.json(500, repr(e))

+ 446 - 0
AdminController/UserManageController.py

@@ -0,0 +1,446 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+"""
+@Copyright (C) ansjer cop Video Technology Co.,Ltd.All rights reserved.
+@AUTHOR: ASJRD018
+@NAME: AnsjerFormal
+@software: PyCharm
+@DATE: 2018/9/11 15:08
+@Version: python3.6
+@MODIFY DECORD:ansjer dev
+@file: UserController.py
+@Contact: chanjunkai@163.com
+"""
+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, UidChannelSetModel, MenuModel
+from Object.AWS.SesClassObject import SesClassObject
+from Object.AliSmsObject import AliSmsObject
+from Object.RedisObject import RedisObject
+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 LoginView(TemplateView):
+    @method_decorator(csrf_exempt)  # @csrf_exempt
+    def dispatch(self, *args, **kwargs):
+        return super(LoginView, self).dispatch(*args, **kwargs)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.POST
+        language = request_dict.get('language', 'en')
+        response = ResponseObject(language,'pc')
+
+        return self.validates(request_dict, response)
+
+
+
+    def validates(self, request_dict, response):
+        username = request_dict.get('username', None)
+        password = request_dict.get('password', None)
+        if not username or not password:
+            return response.json(111)
+        username = username.strip()
+        password = password.strip()
+        data_valid = DataValid()
+        if data_valid.email_validate(username):
+            return self.do_email_login(username, password, response)
+        elif data_valid.mobile_validate(username):
+            return self.do_phone_login(username, password, response)
+        elif data_valid.name_validate(username):
+            return self.do_name_login(username, password, response)
+        else:
+            return response.json(107)
+
+    def do_email_login(self, email, password, response):
+        user_qs = Device_User.objects.filter(Q(username=email) | Q(userEmail=email))
+        return self.valid_login(user_qs, password, response)
+
+    def do_phone_login(self, phone, password, response):
+        user_qs = Device_User.objects.filter(Q(phone=phone) | Q(username=phone), is_active=True, user_isValid=True)
+        return self.valid_login(user_qs, password, response)
+
+    def do_name_login(self, username, password, response):
+        user_qs = Device_User.objects.filter(Q(username=username) | Q(phone=username) | Q(userEmail=username),
+                                             is_active=True, user_isValid=True)
+        return self.valid_login(user_qs, password, response)
+
+    def valid_login(self, user_qs, password, response):
+        if not user_qs.exists():
+            return response.json(104)
+        # users = user_qs.values('role__rid', 'role__roleName', 'userID', 'role', 'NickName', 'username', 'userEmail',
+        #                        'phone', 'password', 'userIconPath', 'user_isValid', 'is_active')[0]
+        users = user_qs.values('role__rid', 'role__roleName', 'userID', 'NickName', 'username', 'userEmail',
+                               'phone', 'password', 'userIconPath')[0]
+        if not check_password(password, users['password']):
+            return response.json(111)
+        userID = users['userID']
+        tko = TokenObject(returntpye='pc')
+        res = tko.generate(
+            data={'userID': userID, 'lang': response.lang, 'user': users['username'], 'm_code': '123413243214'})
+        if tko.code == 0:
+            now_time = datetime.datetime.utcnow().replace(tzinfo=utc).astimezone(utc)
+            user_qs.update(last_login=now_time, language=response.lang)
+            res['rid'] = users['role__rid']
+            res['roleName'] = users['role__roleName']
+            res['permList'] = ModelService.own_permission(userID)
+            res['userID'] = userID
+            # 昵称,邮箱,电话,刷新,头像
+            userIconPath = str(users['userIconPath'])
+            if userIconPath and userIconPath.find('static/') != -1:
+                userIconPath = userIconPath.replace('static/', '').replace('\\', '/')
+                res['userIconUrl'] = SERVER_DOMAIN + 'account/getAvatar/' + userIconPath
+            else:
+                res['userIconUrl'] = ''
+            res['NickName'] = users['NickName'] if users['NickName'] is not None else ''
+            res['username'] = users['username'] if users['username'] is not None else ''
+            res['userEmail'] = users['userEmail'] if users['userEmail'] is not None else ''
+            res['phone'] = users['phone'] if users['phone'] is not None else ''
+            return response.json(0, res)
+        else:
+            return response.json(tko.code)
+
+
+
+
+# 获取登录权限
+class GetPermissions(TemplateView):
+    @method_decorator(csrf_exempt)  # @csrf_exempt
+    def dispatch(self, *args, **kwargs):
+        return super(GetPermissions, self).dispatch(*args, **kwargs)
+
+    def get(self, request, *args, **kwargs):
+        token = request.META.get('HTTP_AUTHORIZATION')
+        request.encoding = 'utf-8'
+        request_dict = request.GET
+        language = request_dict.get('language', 'en')
+        response = ResponseObject(language, 'pc')
+        return self.validates(request_dict,token, response)
+
+
+
+
+    def validates(self, request_dict,token, response):
+        tko = TokenObject(token,returntpye='pc')
+        response.lang = tko.lang
+        if tko.code != 0:
+            return response.json(tko.code)
+        userID = tko.userID
+
+
+        user_qs = Device_User.objects.filter(userID=userID)
+        if not user_qs.exists():
+            return response.json(104)
+        #待补充逻辑
+        username = user_qs[0].username
+        userIconPath = user_qs[0].userIconPath.url
+        if userIconPath:
+            if userIconPath.find('static/') != -1:
+                userIconPath = userIconPath.replace('static/', '').replace('\\', '/')
+                userIconUrl = SERVER_DOMAIN + 'account/getAvatar/' + userIconPath
+
+        role_qs = Role.objects.filter(device_user=userID)
+        menu_qs = MenuModel.objects.filter(role__in=role_qs,menutype=2);
+        perms = []
+        for menu in menu_qs:
+            perms.append(menu.menu_code)
+        res={
+          "code": 200,
+          "msg": "success",
+          "data": {
+            "roles": ["admin"], # 一个用户可包含多个角色如["admin","editor","XXXX"],必须返回,如小项目用不到角色权限请返回 ["admin"]
+            "ability": ["READ", "WRITE", "DELETE"], # 如果用不到rabc精细化权限可以不返回,建议返回
+            "username": username, # 用户名,必须返回
+            "avatar": userIconUrl,# 头像,必须返回
+            "perms": perms
+          }
+        }
+        return response.json(0, res)
+
+
+# 获取菜单
+class GetList(TemplateView):
+    @method_decorator(csrf_exempt)  # @csrf_exempt
+    def dispatch(self, *args, **kwargs):
+        return super(GetList, self).dispatch(*args, **kwargs)
+
+    def get(self, request, *args, **kwargs):
+        token = request.META.get('HTTP_AUTHORIZATION')
+        request.encoding = 'utf-8'
+        request_dict = request.GET
+        language = request_dict.get('language', 'en')
+        response = ResponseObject(language, 'pc')
+        return self.validates(request_dict,token, response)
+
+
+    def validates(self, request_dict,token, response):
+        tko = TokenObject(token,returntpye='pc')
+        response.lang = tko.lang
+        if tko.code != 0:
+            return response.json(tko.code)
+        userID = tko.userID
+
+        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(
+                {
+                '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
+                    }
+                }
+            )
+        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
+
+
+
+class UserManagement(View):
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.GET, request, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.POST, request, operation)
+
+    def validation(self, request_dict, request, operation):
+        language = request_dict.get('language', 'en')
+        response = ResponseObject(language, 'pc')
+        if operation == '??':
+            return 0
+        else:
+            tko = TokenObject(request.META.get('HTTP_AUTHORIZATION'), returntpye='pc')
+            if tko.code != 0:
+                return response.json(tko.code)
+            response.lang = tko.lang
+            userID = tko.userID
+            if operation == 'getUserInfo':
+                return self.getUserInfo(userID, request_dict, response)
+            elif operation == 'AddOrEditAccount':
+                return self.AddOrEditAccount(userID, request_dict, response)
+            elif operation == 'doDelete':
+                return self.doDelete(userID, request_dict, response)
+            elif operation == 'resetPassword':
+                return self.resetPassword(request_dict, response)
+            else:
+                return response.json(404)
+
+    def getUserInfo(self, userID, request_dict, response):
+        print('request_dict: ', request_dict)
+        username = request_dict.get('username', '').strip()   # 移除字符串头尾的空格
+        NickName = request_dict.get('NickName', '').strip()
+        phone = request_dict.get('phone', '').strip()
+        userEmail = request_dict.get('userEmail', '').strip()
+        pageNo = request_dict.get('pageNo', None)
+        pageSize = request_dict.get('pageSize', None)
+
+        if not all([pageNo, pageSize]):
+            return response.json(444)
+
+        page = int(pageNo)
+        line = int(pageSize)
+        try:
+            if username or NickName or phone or userEmail:
+                # 条件查询
+                if username:
+                    device_user_qs = Device_User.objects.filter(username__contains=username)
+                if NickName:
+                    device_user_qs = Device_User.objects.filter(NickName__contains=NickName)
+                if phone:
+                    device_user_qs = Device_User.objects.filter(phone__contains=phone)
+                if userEmail:
+                    device_user_qs = Device_User.objects.filter(userEmail__contains=userEmail)
+                if not device_user_qs.exists():
+                    return response.json(0)
+
+            else:
+                device_user_qs = Device_User.objects.filter()  # 查询全部
+            total = len(device_user_qs)
+            device_users = device_user_qs[(page - 1) * line:page * line]
+            user_list = []
+            for device_user in device_users:
+                role = device_user.role.first()
+                rid = role.rid if role else 1   # 不存在角色默认分配为'Users'
+                user_list.append({
+                    'userID': device_user.userID,
+                    'username': device_user.username,
+                    'NickName': device_user.NickName,
+                    'role': Role.objects.get(rid=rid).roleName,
+                    'phone': device_user.phone,
+                    'userEmail': device_user.userEmail,
+                    'data_joined': device_user.data_joined.strftime("%Y-%m-%d %H:%M:%S"),
+                    'last_login': device_user.last_login.strftime("%Y-%m-%d %H:%M:%S"),
+                    'online': device_user.online,
+                })
+            print('user_list: ', user_list)
+            return response.json(0, {'list': user_list, 'total': total})
+        except Exception as e:
+            print(e)
+            return response.json(500, repr(e))
+
+    def AddOrEditAccount(self, userID, request_dict, response):
+        # 添加/编辑用户
+        print('request_dict: ', request_dict)
+        username = request_dict.get('username', '').strip()   # 移除字符串头尾的空格
+        userEmail = request_dict.get('userEmail', '').strip()
+        roleName = request_dict.get('role', None)
+        password = request_dict.get('password', None)
+        isEdit = request_dict.get('isEdit', None)
+
+        if not all([username, userEmail, roleName, password]):
+            return response.json(444)
+
+        # 校验用户名,邮箱,密码是否符合规则
+        dataValid = DataValid()
+        if not dataValid.name_validate(username) or not dataValid.email_validate(userEmail) \
+                or not dataValid.password_validate(password):
+            return response.json(444)
+
+        try:
+            if isEdit:  # 编辑用户信息
+                userID = request_dict.get('userID')
+                user_data = {
+                    "username": username,
+                    "NickName": username,
+                    "userEmail": userEmail,
+                    "password": make_password(password),
+                }
+                device_user_qs = Device_User.objects.filter(userID=userID)
+                device_user_qs.update(**user_data)
+
+                # 如果角色改变,修改用户角色
+                device_user_role = device_user_qs[0].role
+                user_role = device_user_role.first()
+                if not user_role or roleName != user_role.roleName:
+                    device_user_role.clear()
+                    role_qs = Role.objects.filter(roleName=roleName)  # 账号角色
+                    device_user_qs[0].role.set(role_qs)
+            else:   # 添加用户
+                # 查询邮箱是否已注册
+                if Device_User.objects.filter(userEmail=userEmail).exists():
+                    return response.json(103)
+                role_qs = Role.objects.filter(roleName=roleName)    # 账号角色
+                # 创建用户
+                user_data = {
+                    "username": username,
+                    "NickName": username,
+                    "userEmail": userEmail,
+                    "password": make_password(password),
+                    "userID": CommonService.getUserID(μs=False, setOTAID=True),
+                    "is_active": True,
+                    "user_isValid": True,
+                }
+                Device_User.objects.create(**user_data).role.set(role_qs)
+            return response.json(0)
+        except Exception as e:
+            print(e)
+            return response.json(500, repr(e))
+
+    def doDelete(self, userID, request_dict, response):
+        userID = request_dict.get('userID', '')
+        Device_User.objects.filter(userID=userID).delete()
+        return response.json(0)
+
+    def resetPassword(self, request_dict, response):
+        userID = request_dict.get('userID', None)
+        if not userID:
+            return response.json(444)
+        try:
+            password = '123456'
+            is_update = Device_User.objects.filter(userID=userID).update(password=make_password(password))
+            if is_update:
+                return response.json(0)
+            else:
+                return response.json(177)
+        except Exception as e:
+            print(e)
+            return response.json(500, repr(e))

+ 131 - 0
Ansjer/cn_config/config_formal.py

@@ -0,0 +1,131 @@
+#!/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.zositechc.cn/stat'
+SERVER_DOMAIN_SSL = 'https://www.zositechc.cn/'
+SERVER_DOMAIN = 'http://www.zositechc.cn/'
+DOMAIN_HOST = 'www.zositechc.cn'
+SERVER_HOST = 'backendserver.3xavzq.0001.cnw1.cache.amazonaws.com.cn'
+PUSH_REDIS_ADDRESS = 'pushredis.3xavzq.0001.cnw1.cache.amazonaws.com.cn'
+# 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.zositechc.cn/'
+DETECT_PUSH_DOMAINS = 'https://push.zositechc.cn/'
+DETECT_PUSH_DOMAIN_JIUAN = 'http://jiuan.push.zositechc.cn/'
+DETECT_PUSH_DOMAINS_JIUAN = 'https://jiuan.push.zositechc.cn/'
+# 数据库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'
+
+# aws api key
+AWS_ARN_S3 = 'arn:aws-cn:s3'
+AVATAR_BUCKET = 'avatar-cn'
+REGION_NAME = 'cn-northwest-1'
+ACCESS_KEY_ID = 'AKIA2MMWBR4DSFG67DTG'
+SECRET_ACCESS_KEY = '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'

+ 143 - 0
Ansjer/cn_config/config_test.py

@@ -0,0 +1,143 @@
+#!/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.zositechc.cn/stat/'
+SERVER_DOMAIN = 'http://test.zositechc.cn/'
+SERVER_DOMAIN_SSL = 'https://test.zositechc.cn/'
+
+
+# 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.zositechc.cn'
+SERVER_HOST = 'backendserver.3xavzq.0001.cnw1.cache.amazonaws.com.cn'
+PUSH_REDIS_ADDRESS = 'pushredis.3xavzq.0001.cnw1.cache.amazonaws.com.cn'
+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'
+
+
+# aws api key
+AWS_ARN_S3 = 'arn:aws-cn:s3'
+AVATAR_BUCKET = 'avatar-cn'
+REGION_NAME = 'cn-northwest-1'
+ACCESS_KEY_ID = 'AKIA2MMWBR4DSFG67DTG'
+SECRET_ACCESS_KEY = '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'

+ 256 - 0
Ansjer/cn_config/formal_settings.py

@@ -0,0 +1,256 @@
+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',
+    'MiddleWare.requestRecord.RequestRecordMiddleware',  # 记录请求信息
+    # '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.cn_config.formal_wsgi.application'
+
+
+# 服务器类型
+DATABASE_DATA = 'Ansjer81'
+SERVER_HOST = 'business-server.cvp7gfpnmziz.rds.cn-northwest-1.amazonaws.com.cn'
+DATABASES_USER = 'azrds'
+DATABASES_PASS = 'UKv78ezQhiGMmSef5U5s'
+
+DATABASE_DATA2 = 'Ansjer81'
+SERVER_HOST2 = 'ansjerpush.cvp7gfpnmziz.rds.cn-northwest-1.amazonaws.com.cn'
+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/cn_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.cn_config.formal_settings")
+
+application = get_wsgi_application()

+ 275 - 0
Ansjer/cn_config/test_settings.py

@@ -0,0 +1,275 @@
+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',
+    'MiddleWare.requestRecord.RequestRecordMiddleware',     # 记录请求信息
+    # '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.cn_config.test_wsgi.application'
+
+
+# 服务器类型
+#国内宁夏测试业务数据库
+DATABASE_DATA = 'AnsjerTest'
+SERVER_HOST = 'business-server.cvp7gfpnmziz.rds.cn-northwest-1.amazonaws.com.cn'
+DATABASES_USER = 'azrds'
+DATABASES_PASS = 'UKv78ezQhiGMmSef5U5s'
+
+#推送数据库
+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',
+        # },
+    }
+}

+ 1 - 1
Ansjer/test_wsgi.py → Ansjer/cn_config/test_wsgi.py

@@ -11,6 +11,6 @@ import os
 
 from django.core.wsgi import get_wsgi_application
 
-os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Ansjer.test_settings")
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Ansjer.cn_config.test_settings")
 
 application = get_wsgi_application()

+ 18 - 6
Ansjer/config.py

@@ -57,6 +57,7 @@ AuthCode_Expire = 600
 RTMP_PUSH_URL = 'http://13.56.215.252:8091/hls'
 # 根路径
 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+ADDR_URL = []
 # uid token key
 UID_TOKEN_KEY = 'c+565*j@%^'
 
@@ -74,13 +75,24 @@ AWS_ACCESS_KEY_ID = ['AKIA2MMWBR4DSFG67DTG','AKIA2E67UIMD45Y3HL53']  #0国内,
 AWS_SECRET_ACCESS_KEY = ['aI9gxcAKPmiGgPy9axrtFKzjYGbvpuytEX4xWweL','ckYLg4Lo9ZXJIcJEAKkzf2rWvs8Xth1FCjqiAqUw']
 AWS_ARN = ['arn:aws-cn:s3','arn:aws:s3']
 
+#尚云服务器CRCKey
+CRCKey = {'AUS':'CRCKey', 'ACN':'CRCKey'}   #{平台名:CRCKey值}
+
 # 不同环境配置
-if SERVER_TYPE == 'Ansjer.local_settings':
-    from Ansjer.config_local import *
-elif SERVER_TYPE == 'Ansjer.test_settings':
-    from Ansjer.config_test import *
-elif SERVER_TYPE == 'Ansjer.formal_settings':
-    from Ansjer.config_formal import *
+# 本地
+if SERVER_TYPE == 'Ansjer.local_config.local_settings':
+    from Ansjer.local_config.config_local import *
+# 美国
+elif SERVER_TYPE == 'Ansjer.us_config.test_settings':
+    from Ansjer.us_config.config_test import *
+elif SERVER_TYPE == 'Ansjer.us_config.formal_settings':
+    from Ansjer.us_config.config_formal import *
+
+# 国内
+elif SERVER_TYPE == 'Ansjer.cn_config.formal_settings':
+    from Ansjer.cn_config.config_formal import *
+elif SERVER_TYPE == 'Ansjer.cn_config.test_settings':
+    from Ansjer.cn_config.config_test import *
 
 
 DEVICE_TYPE = {

+ 13 - 13
Ansjer/config_local.py → Ansjer/local_config/config_local.py

@@ -1,17 +1,8 @@
 #!/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
-"""
-# token的secret
+
+import os
+
 OAUTH_ACCESS_TOKEN_SECRET = 'local_a+jbgnw%@1%zy^=@dn62%'
 OAUTH_REFRESH_TOKEN_SECRET = 'local_r+jbgnw%@1%zy^=@dn62%'
 
@@ -20,6 +11,7 @@ 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'
+PUSH_REDIS_ADDRESS = '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'
@@ -60,5 +52,13 @@ APNS_CONFIG = {
         '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'
+TUTK_PUSH_DOMAIN = 'http://push.iotcplatform.com/tpns'
+
+# aws api key
+AWS_ARN_S3 = 'arn:aws-cn:s3'
+AVATAR_BUCKET = 'avatar-cn'
+REGION_NAME = 'cn-northwest-1'
+ACCESS_KEY_ID = 'AKIA2MMWBR4DSFG67DTG'
+SECRET_ACCESS_KEY = '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'

+ 78 - 67
Ansjer/local_settings.py → Ansjer/local_config/local_settings.py

@@ -7,44 +7,14 @@ 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/'
+STATICFILES_DIRS = (os.path.join(BASE_DIR,'static'),)
 
 # 上传路径根目录
 MEDIA_ROOT = os.path.join(BASE_DIR, 'static/Upgrate')
@@ -72,26 +42,76 @@ TEMPLATES = [
     },
 ]
 
-WSGI_APPLICATION = 'Ansjer.local_wsgi.application'
+'''
+增加错误信息推送到管理员邮箱
+'''
+# 管理员邮箱
+ADMINS = (
+    ('admin', 'chanjunkai@163.com'),
+    ('admin', '1379072853@qq.com'),
+)
+
+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',
+    'MiddleWare.requestRecord.RequestRecordMiddleware',     # 记录请求信息
+    # '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',
+)
+
+WSGI_APPLICATION = 'Ansjer.local_config.local_wsgi.application'
 
 # 服务器类型
-#业务数据库
-DATABASE_DATA = 'ansjertest'
+# 国内测试数据库
+# DATABASE_DATA = 'AnsjerTest'
+# SERVER_HOST = 'business-server.cvp7gfpnmziz.rds.cn-northwest-1.amazonaws.com.cn'
+# DATABASES_USER = 'azrds'
+# DATABASES_PASS = 'UKv78ezQhiGMmSef5U5s'
+
+# 本地数据库
+DATABASE_DATA = 'ansjer'
 SERVER_HOST = '127.0.0.1'
 DATABASES_USER = 'root'
-DATABASES_PASS = 'root'
+DATABASES_PASS = '123456'
 
-#推送数据库
-DATABASE_DATA2 = 'ansjerpush'
+# 推送数据库
+DATABASE_DATA2 = 'push'
 SERVER_HOST2 = '127.0.0.1'
 DATABASES_USER2 = 'root'
-DATABASES_PASS2 = 'root'
+DATABASES_PASS2 = '123456'
 
-#序列号公共数据库
+# 序列号公共数据库
 DATABASE_DATA3 = 'serial'
 SERVER_HOST3 = '127.0.0.1'
 DATABASES_USER3 = 'root'
-DATABASES_PASS3 = 'root'
+DATABASES_PASS3 = '123456'
 
 DATABASES = {
     'default': {
@@ -218,9 +238,7 @@ LOGGING = {
         'standard': {
             'format': '[%(asctime)s] [%(filename)s:%(lineno)d] [%(module)s:%(funcName)s] '
                       '[%(levelname)s]- %(message)s'},
-        'simple': {  # 简单格式
-            'format': '%(levelname)s %(message)s'
-        },
+
     },
     'filters': {
     },
@@ -232,27 +250,25 @@ LOGGING = {
         },
         'default': {
             'level': 'ERROR',
-            'class': 'logging.handlers.RotatingFileHandler',
-            'filename': BASE_DIR + '/static/log/error.log',
-            'maxBytes': 1024 * 1024 * 5,  # 5 MB
-            'backupCount': 5,
+            'class': 'logging.handlers.TimedRotatingFileHandler',
+            'filename': BASE_DIR + '/static/log/error/error.log',
+            'backupCount': 30,
+            'when': 'D',
             'formatter': 'error_format',
         },
         'console': {
-            # 'level': 'ERROR',
-            'level': 'DEBUG',
+            'level': 'ERROR',
             'class': 'logging.StreamHandler',
             'formatter': 'error_format'
         },
-        # 输出info日志
         'info': {
             'level': 'INFO',
-            'class': 'logging.handlers.RotatingFileHandler',
-            'filename': BASE_DIR + '/static/log/info.log',
-            'maxBytes': 1024 * 1024 * 5,
-            'backupCount': 5,
+            'class': 'logging.handlers.TimedRotatingFileHandler',
+            'filename': BASE_DIR + '/static/log/info/info.log',
+            'backupCount': 30,
+            'when': 'D',
             'formatter': 'standard',
-            'encoding': 'utf-8',  # 设置默认编码
+            'encoding': 'utf-8',
         },
     },
     'loggers': {
@@ -260,19 +276,14 @@ LOGGING = {
             'handlers': ['default', 'console'],
             # 'handlers': ['mail_admins','default','console'],
             # 'level': 'ERROR',
-            'level': 'DEBUG',
-            'propagate': True
+            'level': 'ERROR',
+            'propagate': False
         },
         # log 调用时需要当作参数传入
-        'log': {
-            'handlers': ['info', 'console', 'default'],
-            'level': 'INFO',
-            'propagate': True
-        },
-        # 'django.db.backends': {
-        #     'handlers': ['console'],
-        #     'propagate': True,
-        #     'level': 'DEBUG',
-        # },
+        'info': {
+            'handlers': ['info'],
+            'level':'INFO',
+            'propagate': False
+        }
     }
 }

+ 1 - 1
Ansjer/local_wsgi.py → Ansjer/local_config/local_wsgi.py

@@ -11,6 +11,6 @@ import os
 
 from django.core.wsgi import get_wsgi_application
 
-os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Ansjer.local_settings")
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Ansjer.local_config.local_settings")
 
 application = get_wsgi_application()

+ 0 - 5
Ansjer/pushconfig.py

@@ -62,11 +62,6 @@ AWS_SECRET_ACCESS_KEY = ['aI9gxcAKPmiGgPy9axrtFKzjYGbvpuytEX4xWweL', 'ckYLg4Lo9Z
 AWS_ARN = ['arn:aws-cn:s3', 'arn:aws:s3']
 
 
-NGINX_RTMP_STAT = 'http://www.dvema.com/stat'
-SERVER_DOMAIN = 'http://www.dvema.com/'
-SERVER_DOMAIN_SSL = 'https://www.dvema.com/'
-DOMAIN_HOST = 'www.dvema.com'
-# SERVER_HOST = 'localhost'
 PAYPAL_CRD = {
     "mode": "live",  # sandbox or live
     "client_id": "AdSRd6WBn-qLl9OiQHQuNYTDFSx0ZX0RUttqa58au8bPzoGYQUrt8bc6591RmH8_pEAIPijdvVYSVXyI",

+ 37 - 3
Ansjer/urls.py

@@ -18,7 +18,9 @@ from Controller import FeedBack, EquipmentOTA, EquipmentInfo, AdminManage, AppIn
     VerifyCodeController, FileController, UIDController, LogController, SalesController, \
     OrderTaskController, HistoryUIDController, UIDManageUserController, SerialNumberController, CompanyController, \
     RegionController, VPGController, LanguageController, TestController, DeviceConfirmRegion, S3GetStsController, \
-    DetectControllerV2, ShadowController, TestDetectController
+    DetectControllerV2, ShadowController, TestDetectController, PcInfo, PctestController, DeviceDebug
+from AdminController import UserManageController, RoleController, MenuController, TestServeController, \
+    ServeManagementController, LogManagementController
 
 urlpatterns = [
     url(r'^testApi/(?P<operation>.*)$', TestApi.testView.as_view()),
@@ -27,7 +29,8 @@ urlpatterns = [
     url(r'^v3/account/imageCodeRegister/$', UserController.Image_Code_RegisterView.as_view()),
     url(r'^account/register$', UserController.registerView.as_view()),
     url(r'^account/login$', UserController.v2LoginView.as_view()),
-    url(r'^account/logout$', UserController.LogoutView.as_view()),
+	url(r'^account/logout$', UserController.LogoutView.as_view()),
+    url(r'^account/noPasslogin$', UserController.noPasslogin.as_view()),
     url(r'^account/changePwd$', UserController.ChangePwdView.as_view()),
     url(r'^account/forget$', UserController.ForgetPwdView.as_view()),
     url(r'^account/email-re-pwd$', UserController.EmailResetPwdView.as_view()),
@@ -281,6 +284,8 @@ urlpatterns = [
 
     #云存服务统计
     url(r'^Cloudsum/(?P<operation>.*)$', Cloudsum.Cloudsum.as_view()),
+    # 设备ip地区统计
+    url(r'^device/StatisticsIpRegion$', DeviceConfirmRegion.StatisticsIpRegion.as_view()),
 
     #Iot Core
     url(r'iot/(?P<operation>.*)$', IotCoreController.IotCoreView.as_view()),
@@ -321,7 +326,36 @@ urlpatterns = [
     #设备确定分配地区
     url(r'^device/confirmRegion$', DeviceConfirmRegion.ConfirmRegion.as_view()),
 
+    # pc端软件信息
+    url(r'^pcInfo/(?P<operation>.*)$', PcInfo.PcInfo.as_view()),
+
+    # pc端测试软件
+    url(r'^pcTest/(?P<operation>.*)$', PctestController.PcTest.as_view()),
+
+    # 设备debug
+    # url(r'^deviceDebug/(?P<operation>.*)$', DeviceDebug.DeviceDebug.as_view()),
+    re_path('deviceDebug/(?P<operation>.*)', DeviceDebug.DeviceDebug.as_view()),
+
+    #后台界面接口 -----------------------------------------------------
+    #用户登录信息等
+    url(r'^login$', UserManageController.LoginView.as_view()),
+    url(r'^noPasslogin$', UserManageController.LoginView.as_view()),
+    url(r'^userInfo$', UserManageController.GetPermissions.as_view()),
+    url(r'^router/getList$', UserManageController.GetList.as_view()),
+    re_path('userManagement/(?P<operation>.*)', UserManageController.UserManagement.as_view()),
+
+    #角色管理
+    re_path('roleManagement/(?P<operation>.*)', RoleController.RoleView.as_view()),
+
+    # 菜单管理
+    re_path('menuManagement/(?P<operation>.*)', MenuController.MenuView.as_view()),
+    # 服务管理
+    re_path('serveManagement/(?P<operation>.*)', ServeManagementController.serveManagement.as_view()),
+    # 测试服务
+    re_path('testServe/(?P<operation>.*)', TestServeController.TestServeView.as_view()),
+    # 日志管理
+    re_path('logManagement/(?P<operation>.*)', LogManagementController.LogManagementView.as_view()),
+    #后台界面接口 -----------------------------------------------------
     re_path('(?P<path>.*)', LogManager.errorPath),
 
-
 ]

+ 8 - 1
Ansjer/config_formal.py → Ansjer/us_config/config_formal.py

@@ -120,4 +120,11 @@ APNS_MODE = 'prod'
 BASE_DIR = 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'
+TUTK_PUSH_DOMAIN = 'http://push.iotcplatform.com/tpns'
+
+# aws api key
+AWS_ARN_S3 = 'arn:aws:s3'
+AVATAR_BUCKET = 'avatar-us'
+REGION_NAME = 'us-east-1'
+ACCESS_KEY_ID = 'AKIA2E67UIMD45Y3HL53'
+SECRET_ACCESS_KEY = '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'

+ 11 - 3
Ansjer/config_test.py → Ansjer/us_config/config_test.py

@@ -23,7 +23,8 @@ 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'
+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",
@@ -127,8 +128,15 @@ APNS_CONFIG = {
     }
 }
 # 根路径
-BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+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'
+TUTK_PUSH_DOMAIN = 'http://push.iotcplatform.com/tpns'
+
+# aws api key
+AWS_ARN_S3 = 'arn:aws:s3'
+AVATAR_BUCKET = 'avatar-us'
+REGION_NAME = 'us-east-1'
+ACCESS_KEY_ID = 'AKIA2E67UIMD45Y3HL53'
+SECRET_ACCESS_KEY = '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'

+ 2 - 2
Ansjer/formal_settings.py → Ansjer/us_config/formal_settings.py

@@ -69,7 +69,7 @@ TEMPLATES = [
     },
 ]
 
-WSGI_APPLICATION = 'Ansjer.formal_wsgi.application'
+WSGI_APPLICATION = 'Ansjer.us_config.formal_wsgi.application'
 
 
 # 服务器类型
@@ -137,7 +137,7 @@ USE_TZ = True
 # 跨域增加忽略
 CORS_ALLOW_CREDENTIALS = True
 CORS_ORIGIN_ALLOW_ALL = True
-CORS_ORIGIN_WHITELIST = ('*')
+# CORS_ORIGIN_WHITELIST = ('*')
 
 CORS_ALLOW_METHODS = (
     'DELETE',

+ 16 - 0
Ansjer/us_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()

+ 16 - 1
Ansjer/test_settings.py → Ansjer/us_config/test_settings.py

@@ -72,7 +72,7 @@ TEMPLATES = [
     },
 ]
 
-WSGI_APPLICATION = 'Ansjer.test_wsgi.application'
+WSGI_APPLICATION = 'Ansjer.us_config.test_wsgi.application'
 
 
 # 服务器类型
@@ -235,6 +235,15 @@ LOGGING = {
             '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': {
@@ -249,6 +258,12 @@ LOGGING = {
             'handlers': ['info'],
             'level':'INFO',
             'propagate': False
+        },
+
+        'device_info':{
+            'handlers': ['device_info'],
+            'level':'INFO',
+            'propagate': False
         }
         # 'django.db.backends': {
         #     'handlers': ['console'],

+ 1 - 1
Ansjer/formal_wsgi.py → Ansjer/us_config/test_wsgi.py

@@ -11,6 +11,6 @@ import os
 
 from django.core.wsgi import get_wsgi_application
 
-os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Ansjer.formal_settings")
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Ansjer.us_config.test_settings")
 
 application = get_wsgi_application()

+ 3 - 3
Controller/Alexa.py

@@ -88,9 +88,9 @@ class AlexaConnectNum(TemplateView):
         res = []
         #最近三十天每天最高连接数
         if operation == 'thirtyDays':
-            query_num = AlexaConnectStatisticsModel.objects. \
-                            extra(select={"month_day_time": "FROM_UNIXTIME(data_time, '%%m-%%d')"}). \
-                            values('num', 'month_day_time').order_by('-data_time')[:30]
+            query_num = AlexaConnectStatisticsModel.objects.\
+                extra(select={"month_day_time": "FROM_UNIXTIME(data_time, '%%m-%%d')"}).\
+                values('num', 'month_day_time').order_by('-data_time')[:30]
             res = list(query_num)
 
         #最近十二个月每月最高连接数

+ 2 - 2
Controller/CDKController.py

@@ -139,8 +139,8 @@ class CDKView(View):
 
             cdk_qs = cdk_qs.filter(rank__lang__lang=lang)
             cdk_qs = cdk_qs.annotate(rank__title=F('rank__lang__title'))
-            cdk_qs = cdk_qs.values('id', 'cdk', 'create_time', 'valid_time', 'is_activate', 'rank__id', 'rank__title', 'order',
-                                   'create_time')
+            cdk_qs = cdk_qs.values('id', 'cdk', 'create_time', 'valid_time', 'is_activate', 'rank__id', 'rank__title',
+                                    'rank__bucket__mold', 'order', 'create_time')
             cdk_qs = cdk_qs.order_by('-create_time')  # 根据CDK创建时间降序排序
             count = cdk_qs.count()
             cdk_qs = cdk_qs[(page - 1) * line:page * line]

+ 17 - 7
Controller/CloudStorage.py

@@ -44,6 +44,7 @@ from Model.models import Device_Info, Order_Model, Store_Meal, VodHlsModel, OssC
 from Object.AWS.S3Email import S3Email
 from Object.AliPayObject import AliPayObject
 from Object.AliSmsObject import AliSmsObject
+from Object.RedisObject import RedisObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Object.UidTokenObject import UidTokenObject
@@ -202,9 +203,7 @@ class CloudStorageView(View):
             qs = qs.filter(pay_type='10')
 
         qs = qs.filter(~Q(pay_type='11'))  # 过滤不显示激活码套餐
-
         qs = qs.filter(is_show=0)  #过滤隐藏套餐
-
         #qs = qs.filter(id='11111111')
         #qs = qs.filter(bucket__region_id=regionObj.region_id)  # 过滤大洲
         qs = qs.annotate(title=F('lang__title'),content=F('lang__content'),discount_content=F('lang__discount_content'))
@@ -231,8 +230,8 @@ class CloudStorageView(View):
                 'meals': res,
                 'extra':
                     {
-                        'cloud_banner': 'https://www.dvema.com/web/images/cloud_cn_banner.png',
-                        'cloud_en_baner': 'https://www.dvema.com/web/images/cloud_en_banner.png'
+                        'cloud_banner': SERVER_DOMAIN+'web/images/cloud_cn_banner.png',
+                        'cloud_en_baner': SERVER_DOMAIN_SSL+'web/images/cloud_en_banner.png'
                     }
             }
             return response.json(0, result)
@@ -1193,7 +1192,8 @@ class CloudStorageView(View):
         rank = request_dict.get('rank', None)
         cdk = request_dict.get('cdk', None)
         lang = request_dict.get('lang', 'en')
-        if cdk != None and pay_type == 11:
+
+        if cdk is not None and pay_type == 11:
             cdk_qs = CDKcontextModel.objects.filter(cdk=cdk).values('is_activate', 'rank__id', 'rank__commodity_code')
             if not cdk_qs.exists():
                 return response.json(10040)
@@ -1202,9 +1202,14 @@ class CloudStorageView(View):
             rank = cdk_qs[0]['rank__id']
             commodity_code = cdk_qs[0]['rank__commodity_code']
 
-        if uid == None or channel == None or commodity_code == None or pay_type == None or rank == None:
+        if uid is None or channel is None or commodity_code is None or pay_type is None or rank is None:
             return response.json(13, '参数有误.')
 
+        redisObj = RedisObject()
+        if redisObj.get_data(key=uid+'do_experience_order'):
+            return response.json(5)
+        redisObj.set_data(key=uid+'do_experience_order', val=uid, expire=300)
+
         dvq = Device_Info.objects.filter(UID=uid)
         dvq = dvq.filter(~Q(vodPrimaryUserID='')).values('vodPrimaryUserID')
         if dvq.exists():
@@ -1220,7 +1225,7 @@ class CloudStorageView(View):
 
         orderID = CommonService.createOrderID()
         nowTime = int(time.time())
-        smqs = Store_Meal.objects.filter(id=rank,lang__lang=lang, is_show=0). \
+        smqs = Store_Meal.objects.filter(id=rank,lang__lang=lang,is_show=0). \
             values("day", "bucket_id", "bucket__storeDay", "expire", 'lang__content', 'price', 'currency', 'commodity_type')
         if not smqs.exists():
             return response.json(173)
@@ -1313,6 +1318,7 @@ class CloudStorageView(View):
                     sms = 'SMS_219748439'
 
                 self.do_vod_msg_Notice(uid, channel, userID, lang, sys_msg_text_list, sms)
+                redisObj.del_data(key=uid+'do_experience_order')
                 result = returnurl
                 return response.json(0, result)
         except Exception:
@@ -1505,6 +1511,10 @@ class CloudStorageView(View):
     def do_vod_msg_end(self, request_dict):
         response = ResponseObject()
         now_time = int(time.time())
+        # 过期前第365天提示一次,测试用
+        # list = UID_Bucket.objects.filter(Q(endTime__gt=now_time + 3600 * 8736) & Q(endTime__lte=(now_time + 3600 * 8760))).values('id','uid','bucket__area','channel','endTime')
+        # self.do_vod_msg(now_time,list)
+
         # 过期前第7天提示一次
         list = UID_Bucket.objects.filter(Q(endTime__gt=now_time + 3600 * 144) & Q(endTime__lte=(now_time + 3600 * 168))).values('id','uid','bucket__area','channel','endTime')
         self.do_vod_msg(now_time,list)

+ 44 - 69
Controller/CompanyController.py

@@ -29,10 +29,12 @@ class CompanyView(View):
 
     def validate(self, request_dict, operation):
 
-        token = TokenObject(request_dict.get('token', None))
-
         response = uidManageResponseObject()
 
+        if operation == 'createSerial':
+            return self.do_create_serial(request_dict, response)
+
+        token = TokenObject(request_dict.get('token', None))
         if token.code != 0:
             return response.json(token.code)
 
@@ -44,8 +46,6 @@ class CompanyView(View):
             return self.do_delete(token.userID, request_dict, response)
         elif operation == 'list':
             return self.do_list(token.userID, request_dict, response)
-        elif operation == 'createSerial':
-            return self.do_create_serial(token.userID, request_dict, response)
         else:
             return response.json(404)
 
@@ -124,80 +124,55 @@ class CompanyView(View):
         else:
             return response.json(444)
 
-    @transaction.atomic
-    def do_create_serial(self, userID, request_dict, response):
+    def do_create_serial(self, request_dict, response):
         # perm = ModelService.check_perm_uid_manage(userID, 0)
         # if not perm:
         #     return response.json(309)
 
         id = request_dict.get('id', None)
         quantity = request_dict.get('quantity', None)
-        p2p = request_dict.get('p2p', None)
-        if id and quantity:
-            company_qs = CompanyModel.objects.filter(id=id)
 
-            if not company_qs.exists():
-                return response.json(444)
-            p2p_sum_Serial = SerialNumberModel.objects.filter(p2p=p2p).count()
-            p2p_sum_Serial_company = CompanySerialModel.objects.filter(p2p=p2p).count()
-            p2p_sum_bind = p2p_sum_Serial - p2p_sum_Serial_company
-            if int(quantity) > int(p2p_sum_bind):
-                return response.json(10041)
-
-            savePoint = transaction.savepoint()
-            try:
-                try:
-
-                    company = company_qs[0]
-                    # start = company.quantity
-                    # start = int(start)
-                    # end = start + int(quantity)
-                    # serial_qs = SerialNumberModel.objects.filter(p2p=p2p)[start:end]
-                    start_1 = p2p_sum_Serial_company
-                    end_1 = int(start_1) + int(quantity)
-                    serial_qs = SerialNumberModel.objects.filter(p2p=p2p)[start_1:end_1]
-                    if serial_qs.exists():
-                        data = []
-                        now_time = int(time.time())
-                        for item in serial_qs:
-                            data.append(CompanySerialModel(
-                                company_id=company.id,
-                                serial_number=item.serial_number,
-                                add_time=now_time,
-                                update_time=now_time,
-                                p2p=p2p
-                            ))
-
-                            if len(data) == 5000:
-                                CompanySerialModel.objects.bulk_create(data)
-                                data.clear()
-                        if len(data) > 0:
-                            CompanySerialModel.objects.bulk_create(data)
-                            data.clear()
-
-                        # company.quantity = company.quantity + end - start
-                        company.quantity =CompanySerialModel.objects.filter(company_id=id).count()
-                        company.save()
-                        return response.json(0)
-                    else:
-                        return response.json(173)
-                except Exception as e:
-                    # print('--------------------------error 5000')
-                    # print(repr(e))
-                    if savePoint:
-                        transaction.rollback(savePoint)
-                    djangoLogger = logging.getLogger('django')
-                    djangoLogger.exception(repr(e))
-                    return response.json(176, str(e))
-            except Exception as e:
-                # print('--------------------------error 5001')
-                # print(repr(e))
-                djangoLogger = logging.getLogger('django')
-                djangoLogger.exception(repr(e))
-                return response.json(176, str(e))
-        else:
+        if not all([id, quantity]):
             return response.json(444)
 
+        company_qs = CompanyModel.objects.filter(id=id)
+        if not company_qs.exists():
+            return response.json(444)
+
+        sum_Serial = SerialNumberModel.objects.filter().count()
+        sum_Serial_company = CompanySerialModel.objects.filter().count()
+        sum_bind = sum_Serial - sum_Serial_company  # 剩余可绑定的序列号
+        if int(quantity) > int(sum_bind):
+            return response.json(10041)
+
+        try:
+            company = company_qs[0]
+            start_1 = sum_Serial_company
+            end_1 = int(start_1) + int(quantity)
+            serial_qs = SerialNumberModel.objects.filter()[start_1:end_1]
+            if serial_qs.exists():
+                company_serial_bulk = []
+                now_time = int(time.time())
+                for item in serial_qs:
+                    company_serial_bulk.append(CompanySerialModel(
+                        status=1,
+                        add_time=now_time,
+                        update_time=now_time,
+                        company_id=company.id,
+                        serial_number=item.serial_number,
+                    ))
+                with transaction.atomic():
+                    CompanySerialModel.objects.bulk_create(company_serial_bulk)
+                    company.quantity = CompanySerialModel.objects.filter(company_id=id).count()
+                    company.save()
+                return response.json(0)
+            else:
+                return response.json(173)
+        except Exception as e:
+            djangoLogger = logging.getLogger('django')
+            djangoLogger.exception(repr(e))
+            return response.json(176, str(e))
+
     def do_list(self, userID, request_dict, response):
         # perm = ModelService.check_perm_uid_manage(userID, 0)
         # if not perm:

+ 2 - 16
Controller/DetectController.py

@@ -32,18 +32,7 @@ from Object.TokenObject import TokenObject
 from Object.UidTokenObject import UidTokenObject
 from Service.CommonService import CommonService
 from Service.ModelService import ModelService
-
-'''
-http://test.push.dvema.com/notify/push?uidToken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiJUNEFaM0NVS0NFUkg5RlpBMTExQSJ9.GtrXeq5gb2Z9M3mKECxi9eNQbPxqC-6PtgJkOOg6PwI&n_time=1598456451&channel=1&event_type=1&is_st=1
-http://push.dvema.com/notify/push?uidToken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiJUNEFaM0NVS0NFUkg5RlpBMTExQSJ9.GtrXeq5gb2Z9M3mKECxi9eNQbPxqC-6PtgJkOOg6PwI&n_time=1598456451&channel=1&event_type=1&is_st=1
-
-http://www.dvema.com/detect/changeStatus?push_type=2&token_val=1a0018970a332cca935&appBundleId=com.ansjer.zccloud_ab&tz=+08.00&uid=HLK7EJ2VYLNHHUMG111A&status=1&m_code=AN02000025070000001207.zccloud_ab&token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiMTMxMTk2NTc3MTMiLCJsYW5nIjoiZW4iLCJtX2NvZGUiOiIxMjM0MTMyNDMyMTQiLCJ1c2VySUQiOiIxNTQ0ODM4MjMyOTczMTM4MDAxMzgwMDAiLCJleHAiOjE1ODQxNDc0NjN9.NjK91B26jZDtdmq8tW-8hXNQPqqDfo9Zwf_Jg6Uf7co&lang=cn&app_type=2
-
-http://127.0.0.1:8077/detect/changeStatus?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VySUQiOiIxNTg0MzUxODk2MjgyMTM4MDAxMzgwMDAiLCJsYW5nIjoiZW4iLCJ1c2VyIjoiMTM2ODAzMTc1OTYiLCJtX2NvZGUiOiIxMjM0MTMyNDMyMTQiLCJleHAiOjE1ODcyNjEzODN9.H87931EDg6PGZK63EAsvY1FRJov9qo_S70mBKvpZeQM&push_type=2&token_val=token_val&appBundleId=appBundleId&tz=0&uid=158440619973313800138000&status=1&m_code&lang=cn&app_type=0&start_status=1&interval=60&eventType=60
-http://192.168.136.140:8077/detect/changeStatus?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VySUQiOiIxNTg0MzUxODk2MjgyMTM4MDAxMzgwMDAiLCJsYW5nIjoiZW4iLCJ1c2VyIjoiMTM2ODAzMTc1OTYiLCJtX2NvZGUiOiIxMjM0MTMyNDMyMTQiLCJleHAiOjE1ODcyNjEzODN9.H87931EDg6PGZK63EAsvY1FRJov9qo_S70mBKvpZeQM&push_type=2&token_val=token_val&appBundleId=appBundleId&tz=0&uid=158440619973313800138000&status=1&m_code&lang=cn&app_type=0&start_status=1&interval=60&eventType=60
-detect/changeStatus
-
-'''
+from Ansjer.config import PUSH_REDIS_ADDRESS
 
 
 class DetectControllerView(View):
@@ -253,9 +242,6 @@ class DetectControllerView(View):
                 return response.json(0)
             elif status == 1:
                 uid_push_qs = UidPushModel.objects.filter(userID_id=userID, m_code=m_code, uid_set__uid=uid)
-                # ykey = '{uid}_redis_qs'.format(uid=uid)
-                # redisObj = RedisObject(db=6, SERVER_HOST='pushredis.5tgle2.0001.usw1.cache.amazonaws.com')
-                # redisObj.del_data(key=ykey)
 
                 if uid_push_qs.exists():
                     uid_push_update_dict = {
@@ -303,7 +289,7 @@ class DetectControllerView(View):
 
     def do_delete_redis(self, uid, detect_interval=0):
         keyPattern = '{uid}*'.format(uid=uid)
-        redisObj = RedisObject(db=6, SERVER_HOST='pushredis.5tgle2.0001.usw1.cache.amazonaws.com')
+        redisObj = RedisObject(db=6, SERVER_HOST=PUSH_REDIS_ADDRESS)
         keys = redisObj.get_keys(keyPattern)
         if keys:
             for key in keys:

+ 2 - 16
Controller/DetectControllerV2.py

@@ -36,18 +36,7 @@ from Service.ModelService import ModelService
 import boto3
 import botocore
 from botocore import client
-
-'''
-http://test.push.dvema.com/notify/push?uidToken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiJUNEFaM0NVS0NFUkg5RlpBMTExQSJ9.GtrXeq5gb2Z9M3mKECxi9eNQbPxqC-6PtgJkOOg6PwI&n_time=1598456451&channel=1&event_type=1&is_st=1
-http://push.dvema.com/notify/push?uidToken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiJUNEFaM0NVS0NFUkg5RlpBMTExQSJ9.GtrXeq5gb2Z9M3mKECxi9eNQbPxqC-6PtgJkOOg6PwI&n_time=1598456451&channel=1&event_type=1&is_st=1
-
-http://www.dvema.com/detect/changeStatus?push_type=2&token_val=1a0018970a332cca935&appBundleId=com.ansjer.zccloud_ab&tz=+08.00&uid=HLK7EJ2VYLNHHUMG111A&status=1&m_code=AN02000025070000001207.zccloud_ab&token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiMTMxMTk2NTc3MTMiLCJsYW5nIjoiZW4iLCJtX2NvZGUiOiIxMjM0MTMyNDMyMTQiLCJ1c2VySUQiOiIxNTQ0ODM4MjMyOTczMTM4MDAxMzgwMDAiLCJleHAiOjE1ODQxNDc0NjN9.NjK91B26jZDtdmq8tW-8hXNQPqqDfo9Zwf_Jg6Uf7co&lang=cn&app_type=2
-
-http://127.0.0.1:8077/detect/changeStatus?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VySUQiOiIxNTg0MzUxODk2MjgyMTM4MDAxMzgwMDAiLCJsYW5nIjoiZW4iLCJ1c2VyIjoiMTM2ODAzMTc1OTYiLCJtX2NvZGUiOiIxMjM0MTMyNDMyMTQiLCJleHAiOjE1ODcyNjEzODN9.H87931EDg6PGZK63EAsvY1FRJov9qo_S70mBKvpZeQM&push_type=2&token_val=token_val&appBundleId=appBundleId&tz=0&uid=158440619973313800138000&status=1&m_code&lang=cn&app_type=0&start_status=1&interval=60&eventType=60
-http://192.168.136.140:8077/detect/changeStatus?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VySUQiOiIxNTg0MzUxODk2MjgyMTM4MDAxMzgwMDAiLCJsYW5nIjoiZW4iLCJ1c2VyIjoiMTM2ODAzMTc1OTYiLCJtX2NvZGUiOiIxMjM0MTMyNDMyMTQiLCJleHAiOjE1ODcyNjEzODN9.H87931EDg6PGZK63EAsvY1FRJov9qo_S70mBKvpZeQM&push_type=2&token_val=token_val&appBundleId=appBundleId&tz=0&uid=158440619973313800138000&status=1&m_code&lang=cn&app_type=0&start_status=1&interval=60&eventType=60
-detect/changeStatus
-
-'''
+from Ansjer.config import PUSH_REDIS_ADDRESS
 
 
 class DetectControllerViewV2(View):
@@ -190,9 +179,6 @@ class DetectControllerViewV2(View):
                 return response.json(0)
             elif status == 1:
                 uid_push_qs = UidPushModel.objects.filter(userID_id=userID, m_code=m_code, uid_set__uid=uid)
-                # ykey = '{uid}_redis_qs'.format(uid=uid)
-                # redisObj = RedisObject(db=6, SERVER_HOST='pushredis.5tgle2.0001.usw1.cache.amazonaws.com')
-                # redisObj.del_data(key=ykey)
 
                 if uid_push_qs.exists():
                     uid_push_update_dict = {
@@ -249,7 +235,7 @@ class DetectControllerViewV2(View):
 
     def do_delete_redis(self, uid, detect_interval=0):
         keyPattern = '{uid}*'.format(uid=uid)
-        redisObj = RedisObject(db=6, SERVER_HOST='pushredis.5tgle2.0001.usw1.cache.amazonaws.com')
+        redisObj = RedisObject(db=6, SERVER_HOST=PUSH_REDIS_ADDRESS)
         keys = redisObj.get_keys(keyPattern)
         if keys:
             for key in keys:

+ 55 - 1
Controller/DeviceConfirmRegion.py

@@ -26,7 +26,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, RegionModel
+    UserAppFrequencyModel, CountryIPModel, CountryModel, RegionModel, P2PIpModel
 from Object.AWS.SesClassObject import SesClassObject
 from Object.AliSmsObject import AliSmsObject
 from Object.RedisObject import RedisObject
@@ -78,6 +78,8 @@ class Device_Region(object):
     def get_device_region(self, ip):
 
         ipInfo = CommonService.getIpIpInfo(ip, "CN")
+
+        #暂时测试国外
         if ipInfo['country_code']:
             device_request_url = CountryModel.objects.filter(country_code=ipInfo['country_code']).values("region__api","region__id")
             if device_request_url.exists():
@@ -87,3 +89,55 @@ class Device_Region(object):
         return api[0]['id']
 
 
+# 根据p2p的ip统计设备所在地区
+class StatisticsIpRegion(TemplateView):
+    @method_decorator(csrf_exempt)
+    def dispatch(self, *args, **kwargs):
+        return super(StatisticsIpRegion, self).dispatch(*args, **kwargs)
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        return self.ipRegion(request.GET)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        return self.ipRegion(request.POST)
+
+    def ipRegion(self, request_dict):
+        response = ResponseObject()
+        ip = request_dict.get('ip', None)
+        uid = request_dict.get('uid', None)
+        p2p_request_times = int(request_dict.get('p2p_request_times', 0))
+        relay_request_times = int(request_dict.get('relay_request_times', 0))
+
+        if not all([ip, uid]) or (not p2p_request_times and not relay_request_times):
+            return response.json(444)
+
+        try:
+            now_time = int(time.time())
+            p2p_ip_qs = P2PIpModel.objects.filter(uid=uid).values('p2p_request_times', 'relay_request_times')
+            if p2p_ip_qs.exists():
+                # 已存在数据,更新p2p请求次数和relay请求次数
+                p2p_request_times = p2p_ip_qs[0]['p2p_request_times'] + p2p_request_times
+                relay_request_times = p2p_ip_qs[0]['relay_request_times'] + relay_request_times
+                p2p_ip_qs.update(p2p_request_times=p2p_request_times, relay_request_times=relay_request_times, update_time=now_time)
+            else:
+                # 根据ip确定位置信息
+                ip_info = CommonService.getIpIpInfo(ip, 'CN')
+                # 获取大洲,国家,地区,城市
+                continent_code = ip_info['continent_code']
+                country_name = ip_info['country_name']
+                if continent_code == 'AP' and country_name != 'CN':
+                    # 如果大洲代码为'AP',国家不为'CN',为亚洲
+                    continent_code = 'AS'
+                continent_name = RegionModel.objects.filter(continent_code=continent_code).values('name')[0]['name']
+                region_name = ip_info['region_name']
+                city_name = ip_info['city_name']
+                P2PIpModel.objects.create(uid=uid, ip=ip, continent_name=continent_name, country_name=country_name,
+                                          region_name=region_name, city_name=city_name, p2p_request_times=p2p_request_times,
+                                          relay_request_times=relay_request_times, add_time=now_time, update_time=now_time)
+            return response.json(0)
+        except Exception as e:
+            print(e)
+            return response.json(500, repr(e))
+

+ 75 - 0
Controller/DeviceDebug.py

@@ -0,0 +1,75 @@
+#!/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: 2021/07/06 11:17
+@Version: python3.6
+@MODIFY DECORD:ansjer dev
+"""
+import json
+import time
+import urllib
+import uuid
+import boto3
+import threading
+import logging
+from boto3.session import Session
+from django.http import JsonResponse, HttpResponseRedirect, HttpResponse
+from django.views.generic.base import View
+from Model.models import Device_Info
+from Object.ResponseObject import ResponseObject
+from Object.TokenObject import TokenObject
+from Object.UidTokenObject import UidTokenObject
+from Service.CommonService import CommonService
+from django.db.models import Q, F
+from time import strftime
+
+
+class DeviceDebug(View):
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.GET, request, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.POST, request, operation)
+
+    def validation(self, request_dict, request, operation):
+        response = ResponseObject()
+        if not operation:
+            return response.json(444,'operation')
+        uidToken = request_dict.get('uidToken', None)
+        if uidToken is not None:
+            utko = UidTokenObject(uidToken)
+            if utko.flag is False:
+                return response.json(444, 'uidToken')
+            uid = utko.UID
+            if uid is not None:
+                if operation == 'singleDebug':
+                    return self.single_debug(request, request_dict, uid, response)
+            return response.json(444, 'operation')
+        else:
+            return response.json(309)
+
+    def single_debug(self,request, request_dict, uid, response):
+        ip = CommonService.get_ip_address(request)
+        device_info = logging.getLogger('device_info')
+        device_info.info("----------------------------------------------------------------------------------")
+        device_info.info("----------------------------------------------------------------------------------")
+        device_info.info("----------------------------------------------------------------------------------")
+        device_info.info("----------------------------------------------------------------------------------")
+        device_info.info("----------------------------------------------------------------------------------")
+        device_info.info("----------------------------------------------------------------------------------")
+        device_info.info("debug----------------------------------------------------------------------------------start")
+        device_info.info("uid:"+uid)
+        device_info.info(strftime("%Y-%m-%d %H:%M:%S"))
+        device_info.info("ip:"+ip)
+        device_info.info(request_dict.get('debug_log'))
+        device_info.info("debug------------------------------------------------------------------------------------end")
+        return response.json(0,'debug success')
+                # return response.json(10, '生成失败')

+ 3 - 8
Controller/DynamoDBLog.py

@@ -28,13 +28,8 @@ from Object.RedisObject import RedisObject
 from Service.MiscellService import MiscellService
 import datetime, simplejson as json
 import time
-'''
-http://192.168.136.39:8000/dynamoDBLog/searchByAdmin?search_value=154390905041313800138000&token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VySUQiOiIxNTQzOTA5MDUwNDEzMTM4MDAxMzgwMDAiLCJsYW5nIjoiY24iLCJ1c2VyIjoiMTM4MDAxMzgwMDEiLCJtX2NvZGUiOiIxMjM0MTMyNDMyMTQiLCJleHAiOjE1NzMyNjc3OTR9.YWNEHKKrzFfEc4liz6N8ANQl8C1VfhhLv_MEOqf3yV4&page=1&line=12
 
 
-http://192.168.136.39:8000/dynamoDBLog/connector?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VySUQiOiIxNTQzOTA5MDUwNDEzMTM4MDAxMzgwMDAiLCJsYW5nIjoiY24iLCJ1c2VyIjoiMTM4MDAxMzgwMDEiLCJtX2NvZGUiOiIxMjM0MTMyNDMyMTQiLCJleHAiOjE1NzMyNjc3OTR9.YWNEHKKrzFfEc4liz6N8ANQl8C1VfhhLv_MEOqf3yV4
-
- '''
 class DynamoDBLog(View):
     @method_decorator(csrf_exempt)
     def dispatch(self, *args, **kwargs):
@@ -77,7 +72,7 @@ class DynamoDBLog(View):
             if search_value is None or search_value is '':
                 return response.json(0, {'datas': {}, 'count': 0})
             else:
-                if DOMAIN_HOST == 'www.dvema.com':
+                if DOMAIN_HOST == 'www.zositechc.cn':
                     user_brand = 'access_log'
                 else:
                     user_brand = 'test_access_log'
@@ -102,7 +97,7 @@ class DynamoDBLog(View):
     def connector_info(self, request_dict, userID,response):
         check_perm = ModelService.check_perm(userID=userID,permID=30)
         if check_perm is True:
-            if DOMAIN_HOST == 'www.dvema.com':
+            if DOMAIN_HOST == 'www.zositechc.cn':
                 user_brand = 'access_log'
             else:
                 user_brand = 'test_access_log'
@@ -120,7 +115,7 @@ class DynamoDBLog(View):
     # 通过传过来日期天来搜索,访问量,并返回对应小时的访问数量
     def get_day_search(self, request_dict,userID, response):
         check_perm = ModelService.check_perm(userID=userID, permID=30)
-        if DOMAIN_HOST == 'www.dvema.com':
+        if DOMAIN_HOST == 'www.zositechc.cn':
             user_brand = 'access_log'
         else:
             user_brand = 'test_access_log'

+ 10 - 5
Controller/EquipmentManager.py

@@ -20,7 +20,7 @@ import oss2
 from django.http import JsonResponse
 from Object.RedisObject import RedisObject
 from Controller.DetectController import DetectControllerView
-
+from Ansjer.config import PUSH_REDIS_ADDRESS
 
 #     查询用户设备
 def queryUserEquipmentInterface(request):
@@ -815,7 +815,7 @@ def deleteInterface(request):
                 DetectControllerView().do_delete_redis(uid)
                 if up_qs.count() > 1:
                     UidPushModel.objects.filter(uid_set__uid=uid, userID_id=userID).delete()
-                    redisObj = RedisObject(db=6, SERVER_HOST='pushredis.5tgle2.0001.usw1.cache.amazonaws.com')
+                    redisObj = RedisObject(db=6, SERVER_HOST=PUSH_REDIS_ADDRESS)
                     ykey = '{uid}_redis_qs'.format(uid=uid)
                     if ykey:
                         redisObj.del_data(key=ykey)
@@ -885,7 +885,7 @@ def batchDeleteInterface(request):
                 DetectControllerView().do_delete_redis(uid)
                 if up_qs.count() > 1:
                     UidPushModel.objects.filter(uid_set__uid=uid, userID_id=userID).delete()
-                    redisObj = RedisObject(db=6, SERVER_HOST='pushredis.5tgle2.0001.usw1.cache.amazonaws.com')
+                    redisObj = RedisObject(db=6, SERVER_HOST=PUSH_REDIS_ADDRESS)
                     ykey = '{uid}_redis_qs'.format(uid=uid)
                     if ykey:
                         redisObj.del_data(key=ykey)
@@ -962,11 +962,12 @@ def queryInterface(request):
         data = []
         # 设备拓展信息表
         us_qs = UidSetModel.objects.filter(uid__in=uid_list).\
-            values('uid', 'version', 'nickname', 'detect_interval')
+            values('uid', 'version', 'nickname', 'detect_interval', 'is_ptz')
         uv_dict = {}
         for us in us_qs:
             uv_dict[us['uid']] = {'version': us['version'],
                                   'nickname': us['nickname'],
+                                  'is_ptz': us['is_ptz'],
                                   'detect_interval': us['detect_interval']}
 
         for p in dvls:
@@ -1035,7 +1036,7 @@ def uid_status(request):
     # 判断用户是否绑定设备
     qs = UidSetModel.objects.filter(uid=uid).values('uid', 'detect_status', 'detect_interval', 'version', 'ucode',
                                                     'p2p_region', 'tz', 'video_code', 'channel', 'cloud_vod', 'id',
-                                                    'detect_group', 'is_alexa', 'region_alexa')
+                                                    'detect_group', 'is_alexa', 'region_alexa','is_ptz')
 
     # 调试
     debugOnes = int(time.time())
@@ -1066,6 +1067,7 @@ def uid_status(request):
             'detect_group': qs[0]['detect_group'],  # 推送组
             'is_alexa': qs[0]['is_alexa'],  # 推送组
             'region_alexa': qs[0]['region_alexa'],  # 推送组
+            'is_ptz': qs[0]['is_ptz']
         }
 
         # 调试
@@ -1248,6 +1250,7 @@ def update_device_shadow(request):
         push_status = request_dict.get('push_status', None)
         pwd = request_dict.get('pwd', None)
         resetTime = request_dict.get('resetTime', None)
+        is_ptz = request_dict.get('is_ptz', None)
         is_alexa = request_dict.get('is_alexa', None)
 
         us_qs = UidSetModel.objects.filter(uid=uid)
@@ -1279,6 +1282,8 @@ def update_device_shadow(request):
             qs_dict['detect_status'] = push_status
         if pwd:
             qs_dict['pwd'] = pwd
+        if is_ptz:
+            qs_dict['is_ptz'] = is_ptz
         if is_alexa:
             qs_dict['is_alexa'] = is_alexa
         if us_qs.exists():

+ 3 - 1
Controller/EquipmentManagerV2.py

@@ -173,7 +173,7 @@ class EquipmentManagerV2(View):
             nowTime = int(time.time())
             data = []
             # 设备拓展信息表
-            us_qs = UidSetModel.objects.filter(uid__in=uid_list).values('uid', 'version', 'nickname', 'ucode','detect_interval', 'is_human', 'is_custom_voice')
+            us_qs = UidSetModel.objects.filter(uid__in=uid_list).values('uid', 'version', 'nickname', 'ucode','detect_interval', 'is_human', 'is_custom_voice', 'is_ptz')
             uv_dict = {}
             for us in us_qs:
                 uv_dict[us['uid']] = {
@@ -183,6 +183,7 @@ class EquipmentManagerV2(View):
                     'detect_interval': us['detect_interval'],
                     'is_human': us['is_human'],
                     'is_custom_voice': us['is_custom_voice'],
+                    'is_ptz': us['is_ptz']
                 }
             for p in dvls:
                 # 新增云分配UID
@@ -216,6 +217,7 @@ class EquipmentManagerV2(View):
                     p['detect_interval'] = uv_dict[p_uid]['detect_interval']
                     p['is_human'] = uv_dict[p_uid]['is_human']
                     p['is_custom_voice'] = uv_dict[p_uid]['is_custom_voice']
+                    p['is_ptz'] = uv_dict[p_uid]['is_ptz']
                     # 设备昵称 调用影子信息昵称,先阶段不可
                     if uv_dict[p_uid]['nickname']:
                         p['NickName'] = uv_dict[p_uid]['nickname']

+ 8 - 1
Controller/EquipmentStatus.py

@@ -115,7 +115,6 @@ def getTZ(request):
             print(uid)
             redisObject = RedisObject(db=7)
             data = redisObject.get_data(key=ip)
-
             if data:
                 info = json.loads(data)
                 return JsonResponse(status=200, data={'code': 0, 'msg': 'success', 'data': info})
@@ -125,12 +124,20 @@ def getTZ(request):
                 info = CommonService.getIpIpInfo(ip=ip, lang=lang,update=False)
             try:
                 tz = info['utc_offset']
+                if len(tz) == 0:
+                    info['utc_offset'] = "UTC+8"
+                    info['gmt_offset'] = "GMT+08:00"
                 # 增加GMT,且补:00
                 if len(tz) == 5:
                     gmtz = tz.replace('UTC-', 'GMT-0').replace('UTC+', 'GMT+0')
                     if ':' not in gmtz:
                         gmtz = gmtz + ':00'
                     info['gmt_offset'] = gmtz
+                if len(tz) == 6:
+                    gmtz = tz.replace('UTC-', 'GMT-').replace('UTC+', 'GMT+')
+                    if ':' not in gmtz:
+                        gmtz = gmtz + ':00'
+                    info['gmt_offset'] = gmtz
                 elif len(tz) == 8:
                     gmtz = tz.replace('UTC-', 'GMT-0').replace('UTC+', 'GMT+0')
                     info['gmt_offset'] = gmtz

+ 5 - 7
Controller/FAQController.py

@@ -13,8 +13,7 @@ from django.views.decorators.csrf import csrf_exempt
 from django.views.generic.base import View
 
 import Ansjer
-from Ansjer.config import BASE_DIR, SERVER_TYPE
-from Ansjer.config_formal import SERVER_DOMAIN
+from Ansjer.config import BASE_DIR, SERVER_TYPE, SERVER_DOMAIN, SERVER_DOMAIN_SSL
 from Model.models import FAQModel
 from Object.RedisObject import RedisObject
 from Object.ResponseObject import ResponseObject
@@ -71,10 +70,9 @@ class FAQUploadView(View):
                     index = file_name.find('static/')
                     filePath = file_name[index:]
                     if SERVER_TYPE == "Ansjer.formal_settings":
-                        filePath = 'http://www.dvema.com/faq/image/' + filePath
+                        filePath = SERVER_DOMAIN+'faq/image/' + filePath
                     else:
-                        filePath = 'http://test.www.dvema.com/faq/image/' + filePath
-                    # filePath = "http://192.168.136.35:8000/" + 'faq/image/' + filePath
+                        filePath = SERVER_DOMAIN_SSL+'faq/image/' + filePath
                     return response.json(0, {'filePath': filePath})
 
             # redis中没有对应的图片信息
@@ -109,9 +107,9 @@ class FAQUploadView(View):
             index = file_name.find('static/')
             filePath = file_name[index:]
             if SERVER_TYPE == "Ansjer.formal_settings":
-                filePath = 'http://www.dvema.com/faq/image/' + filePath
+                filePath = 'http://www.zositechc.cn/faq/image/' + filePath
             else:
-                filePath = 'http://test.www.dvema.com/faq/image/' + filePath
+                filePath = 'http://test.www.zositechc.cn/faq/image/' + filePath
             # filePath = "http://192.168.136.35:8000/" + 'faq/image/' + filePath
             return response.json(0, {'filePath': filePath})
 

+ 22 - 15
Controller/IotCoreController.py

@@ -38,7 +38,8 @@ class IotCoreView(View):
 
     def validate(self, operation, request_dict, request):
         response = ResponseObject()
-
+        lang = request_dict.get('lang', 'en')
+        response.lang = lang
         if operation == 'createKeysAndCertificate':
             return self.create_keys_and_certificate(request_dict, response, request)
         elif operation == 'requestPublishMessage':
@@ -49,6 +50,8 @@ class IotCoreView(View):
             token = TokenObject(request_dict.get('token', None))
             if token.code != 0:
                 return response.json(token.code)
+            response.lang = token.lang
+
             if operation == 'clearIotCerm':
                 return self.clear_Iot_Cerm(request_dict, response)
             else:
@@ -226,7 +229,7 @@ class IotCoreView(View):
             return response.json(444)
 
     def request_publish_message(self, request_dict, response, request):
-        # Alexa请求IoT Core下发MQTT消息
+        # Alexa请求IoT Core下发MQTT消息通知设备开始或停止推流,或唤醒设备
         UID = request_dict.get('UID', None)
         MSG = request_dict.get('MSG', None)
 
@@ -236,36 +239,40 @@ class IotCoreView(View):
         try:
             # 获取检查uid的序列号,如果没有序列号,不使用MQTT下发消息
             device_info_qs = Device_Info.objects.filter(UID=UID).values('UID', 'serial_number')
+            if not device_info_qs.exists():
+                return response.json(10043)
             uid = device_info_qs[0]['UID']
             serial_number = device_info_qs[0]['serial_number']
             # 如果device_info表的serial_number不为空,物品名为'Ansjer_Device_序列号'
-            ThingNameSuffix = serial_number if serial_number != '' else uid
-
-            thing_name = 'Ansjer_Device_' + ThingNameSuffix
+            thing_name_suffix = serial_number if serial_number != '' else uid
             # 获取数据组织将要请求的url
-            iot = iotdeviceInfoModel.objects.filter(thing_name__contains=thing_name).values('thing_name', 'endpoint',
-                                                                                            'token_iot_number')
+            iot = iotdeviceInfoModel.objects.filter(thing_name__contains=thing_name_suffix).values('thing_name',
+                                                                                                   'endpoint',
+                                                                                                   'token_iot_number')
             if not iot.exists():
                 return response.json(10043)
-            thing_name = iot[0]['thing_name']  # IoT core上的物品名: Ansjer_Device_+序列号+企业编码
+            thing_name = iot[0]['thing_name'][14:]  # IoT core上的物品名: Ansjer_Device_ + 序列号+企业编码/uid
             endpoint = iot[0]['endpoint']
             Token = iot[0]['token_iot_number']
             # Token = '297a601b3925e04daab5a60280650e09'
-            topic_name = thing_name + '_rtsp_topic'     # MQTT主题
+            topic_suffix = '_power_topic' if 'Turn' in MSG else '_rtsp_topic'
+            topic_name = thing_name + topic_suffix     # MQTT主题
 
-            # rtsp://rtsp.zositech.org:8554/ZFdqWldXRFpMTkVaYVZEaEJXRXhUV0RFeE1VRT1B
             # api doc: https://docs.aws.amazon.com/zh_cn/iot/latest/developerguide/http.html
-            # https://IoT_data_endpoint/topics/url_encoded_topic_name?qos=1
-            # POST请求url来发布消息
-            url = 'https://{}/topics/{}?rtsp_command={}'.format(endpoint, topic_name, MSG)
+            # url: https://IoT_data_endpoint/topics/url_encoded_topic_name?qos=1
+            # post请求url来发布MQTT消息
+            url = 'https://{}/topics/{}'.format(endpoint, topic_name)
             authorizer_name = 'Ansjer_Iot_Auth'
             signature = self.rsa_sign(Token)  # Token签名
             headers = {'x-amz-customauthorizer-name': authorizer_name, 'Token': Token,
                        'x-amz-customauthorizer-signature': signature}
-            params = {'rtsp_command': MSG}
+            params = {'command': MSG}
             r = requests.post(url=url, headers=headers, json=params, timeout=2)
             if r.status_code == 200:
-                return response.json(0)
+                res = r.json()
+                if res['message'] == 'OK':
+                    return response.json(0)
+                return response.json(10044)
             else:
                 # print('发布失败')
                 return response.json(10044)

+ 1 - 1
Controller/LogManager.py

@@ -2,7 +2,7 @@ from Controller import OTAEquipment
 from django.views.decorators.csrf import csrf_exempt
 from django.views.generic import TemplateView
 from django.utils.decorators import method_decorator
-from Ansjer import local_settings as api_settings
+from Ansjer import config as api_settings
 from Service.ModelService import ModelService
 import time,os
 from Object.ResponseObject import ResponseObject

+ 3 - 2
Controller/MealManage.py

@@ -13,6 +13,7 @@
 """
 import traceback
 
+from Ansjer.config import SERVER_DOMAIN_SSL
 from django.db.models import F
 from django.utils import timezone
 from django.utils.decorators import method_decorator
@@ -401,8 +402,8 @@ class MealView(View):
                 'meals': res,
                 'extra':
                     {
-                        'cloud_banner': 'https://www.dvema.com/web/images/cloud_cn_banner.png',
-                        'cloud_en_baner': 'https://www.dvema.com/web/images/cloud_en_banner.png'
+                        'cloud_banner': SERVER_DOMAIN_SSL+'web/images/cloud_cn_banner.png',
+                        'cloud_en_baner': SERVER_DOMAIN_SSL+'web/images/cloud_en_banner.png'
                     }
             }
             return response.json(0, result)

+ 5 - 3
Controller/OrderContrller.py

@@ -19,7 +19,7 @@ from django.utils.decorators import method_decorator
 from django.views.decorators.csrf import csrf_exempt
 from django.views.generic.base import View
 
-from Ansjer.config_test import PAYPAL_CRD
+from Ansjer.us_config.config_test import PAYPAL_CRD
 from Object.AliPayObject import AliPayObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
@@ -109,7 +109,7 @@ class OrderView(View):
                                                               "addTime",
                                                               "updTime", "paypal", "rank__day", "payType",
                                                               "rank__price", "status",
-                                                              "rank__content", "rank__title", "rank__currency",
+                                                              "rank__lang__content", "rank__title", "rank__currency",
                                                               "rank_id","rank__expire")
         order_list = list(order_ql)
         data = []
@@ -128,7 +128,9 @@ class OrderView(View):
                     d['did'] = did['id']
                     d['Type'] = did['Type']
                     data.append(d)
-            d['rank__expire_unit'] = '月' if lang == 'cn' else 'month'
+            d['rank__content'] = d['rank__lang__content']
+            del d['rank__lang__content']
+            # d['rank__lang__content'] = '月' if lang == 'cn' else 'month'
         return response.json(0, {'data': data, 'count': count})
 
     # admins ^^^^^^^^^^^^

+ 689 - 0
Controller/PcInfo.py

@@ -0,0 +1,689 @@
+import hashlib
+import logging
+import shutil
+import time
+import traceback
+import os
+from urllib import request, parse
+import requests
+from boto3 import Session
+from django.http import HttpResponse
+
+from django.views.generic.base import View
+
+from Controller.PctestController import TokenObject1
+from Model.models import Pc_Info, PctestlogModel
+from Object.ResponseObject import ResponseObject
+from Object.TokenObject import TokenObject
+from Service.CommonService import CommonService
+from Ansjer.config import AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_ARN, BASE_DIR
+import boto3
+import botocore
+from botocore import client
+from wsgiref.util import FileWrapper
+from zlib import crc32
+from typing import Union
+
+
+class PcInfo(View):
+    def dispatch(self, requset, *args, **kwargs):
+        return super(PcInfo, self).dispatch(requset, *args, **kwargs)
+
+    def get(self, request, *args, **kwargs):
+        operation = kwargs.get('operation')
+        request.encoding = 'utf-8'
+        return self.validation(request.GET, request, operation)
+
+    def post(self, request, *args, **kwargs):
+        operation = kwargs.get('operation')
+        request.encoding = 'utf-8'
+        return self.validation(request.POST, request, operation)
+
+    def validation(self, request_dict, request, operation):
+        response = ResponseObject()
+        if not operation:
+            return response.json(444, 'operation')
+        else:
+
+            if operation == 'query':     # pc端调用查询
+                return self.query(request_dict, response)
+            elif operation == 's3addandupload':
+                return self.s3addandupload(request_dict, response, request)
+            elif operation == 's3addanduploadlog': #上传日志文件
+                return self.s3addanduploadlog(request_dict, response, request)
+            elif operation == 's3download':
+                return self.s3download(request_dict, response)
+            elif operation == 's3downloadlog': #下载日志文件
+                return self.s3downloadlog(request_dict, response)
+            elif operation == 's3delete':
+                return self.s3delete(request_dict, response)
+            elif operation == 'edit':
+                return self.edit(request_dict, response)
+            elif operation == 'getnewversion':    # 获取当前软件的最新版本
+                return self.getnewversion(request_dict, response)
+            elif operation == 'getnewversionV2':   # 获取当前软件的最新版本
+                return self.getnewversionV2(request_dict, response)
+            elif operation == 'queryall':   # 后台查询
+                return self.queryall(request_dict, response)
+            elif operation == 'addandupload':   # 上传到服务器
+                return self.addandupload(request_dict, response, request)
+            elif operation == 'download':   # 服务器下载
+                return self.download(request_dict, response)
+            elif operation == 'delete':
+                return self.delete(request_dict, response)
+            else:
+                return response.json(414)
+
+    def getnewversion(self, request_dict, response):
+        pc_name = request_dict.get('pc_name', None)
+        bundle_version = request_dict.get('bundle_version', None)
+        pc_version = request_dict.get('pc_version', None)
+        pc_test = request_dict.get('pc_test', None)
+        param_flag = CommonService.get_param_flag(
+            data=[pc_name, bundle_version, pc_version, pc_test])
+        if param_flag is not True:
+            return response.json(444)
+        file = Pc_Info.objects.filter(pc_name=pc_name, bundle_version=bundle_version, pc_test=pc_test)
+        if not file:
+            return response.json(173)
+        app_list = Pc_Info.objects.filter(pc_name=pc_name, bundle_version=bundle_version, pc_test=pc_test)
+        all_version = app_list.values('pc_version')
+        v = []
+        for i in all_version:
+            v.append(i['pc_version'])
+        new_version = max(v)
+        if pc_version == new_version:
+            return response.json(10045)
+        else:
+            path = app_list.filter(pc_version=new_version).values('download_link')[0]['download_link']
+            print('path', path)
+            aws_s3_guonei = boto3.client(
+                's3',
+                aws_access_key_id=AWS_ACCESS_KEY_ID[0],
+                aws_secret_access_key=AWS_SECRET_ACCESS_KEY[0],
+                config=botocore.client.Config(signature_version='s3v4'),
+                region_name='cn-northwest-1')
+            response_url = aws_s3_guonei.generate_presigned_url(
+                ClientMethod='get_object',
+                Params={'Bucket': 'pc-package', 'Key': path}, ExpiresIn=3600)
+            res = {'pc_name': pc_name,
+                   'new_version': new_version,
+                   'path': path,
+                   'response_url': response_url}
+            return response.json(0, res)
+
+    def getnewversionV2(self, request_dict, response):
+        pc_name = request_dict.get('pc_name', None)
+        bundle_version = request_dict.get('bundle_version', None)
+        pc_version = request_dict.get('pc_version', None)
+        pc_test = request_dict.get('pc_test', None)
+        param_flag = CommonService.get_param_flag(
+            data=[pc_name, bundle_version, pc_version, pc_test])
+        if param_flag is not True:
+            return response.json(444)
+        file = Pc_Info.objects.filter(pc_name=pc_name, bundle_version=bundle_version, pc_test=pc_test)
+        if not file.exists():
+            return response.json(173)
+        aws_s3_guonei = boto3.client(
+            's3',
+            aws_access_key_id=AWS_ACCESS_KEY_ID[0],
+            aws_secret_access_key=AWS_SECRET_ACCESS_KEY[0],
+            config=botocore.client.Config(signature_version='s3v4'),
+            region_name='cn-northwest-1')
+        version_list = []
+        for i in range(2):
+            app_list = Pc_Info.objects.filter(pc_name=pc_name, bundle_version=bundle_version, pc_test=pc_test, is_update=i)
+            # 当前软件不存在强制更新(is_update=1)的版本返回空
+            if not app_list.exists():
+                res = {'pc_name': '',
+                       'new_version': '',
+                       'is_update': i,
+                       'explain': '',
+                       'path': '',
+                       'response_url': ''}
+                version_list.append(res)
+                continue
+            all_version = app_list.values('pc_version')
+            v = []
+            for i in all_version:
+                v.append(i['pc_version'])
+            new_version = max(v)
+            # 当前软件版本为最新时返回空
+            if pc_version >= new_version:
+                res = {'pc_name': '',
+                       'new_version': '',
+                       'is_update': app_list.filter(pc_version=new_version).values('is_update')[0]['is_update'],
+                       'explain': '',
+                       'path': '',
+                       'response_url': ''}
+                version_list.append(res)
+                continue
+            path = app_list.filter(pc_version=new_version).values('download_link')[0]['download_link']
+            print('path', path)
+            response_url = aws_s3_guonei.generate_presigned_url(
+                ClientMethod='get_object',
+                Params={'Bucket': 'pc-package', 'Key': path}, ExpiresIn=3600)
+            res = {'pc_name': pc_name,
+                   'new_version': new_version,
+                   'is_update': app_list.filter(pc_version=new_version).values('is_update')[0]['is_update'],
+                   'explain': app_list.filter(pc_version=new_version).values('explain')[0]['explain'],
+                   'path': path,
+                   'response_url': response_url}
+            version_list.append(res)
+        return response.json(0, version_list)
+
+    def query(self, request_dict, response):
+        pc_name = request_dict.get('pc_name', None)
+        bundle_version = request_dict.get('bundle_version', None)
+        pc_version = request_dict.get('pc_version', None)
+        pc_test = request_dict.get('pc_test', None)
+        package = request_dict.get('package', None)
+        file_type = request_dict.get('file_type', None)
+        # 根据传的参数筛选,没传时返回全部
+        queryset = Pc_Info.objects.all()
+        if package:
+            queryset = Pc_Info.objects.filter(package=package)
+        if file_type:
+            queryset = Pc_Info.objects.filter(file_type=file_type)
+        if pc_name and file_type:
+            queryset = Pc_Info.objects.filter(pc_name=pc_name, file_type=file_type)
+        if file_type and package:
+            queryset = Pc_Info.objects.filter(file_type=file_type, package=package)
+        if pc_name and bundle_version and pc_version and pc_test:
+            queryset = Pc_Info.objects.filter(pc_name=pc_name, bundle_version=bundle_version, pc_version=pc_version, pc_test=pc_test)
+        count = queryset.count()
+        res = queryset
+        send_json = CommonService.qs_to_dict(res)
+        send_json['count'] = count
+        return response.json(0, send_json)
+
+    def s3addandupload(self, request_dict, response, request):
+        logger = logging.getLogger('info')
+        logger.info('s3方式上传参数:')
+        logger.info(request_dict)
+        token = request_dict.get('token', None)
+        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(104)
+        pc_name = request_dict.get('pc_name', None)
+        bundle_version = request_dict.get('bundle_version', None)
+        pc_version = request_dict.get('pc_version', None)
+        pc_test = request_dict.get('pc_test', None)
+        lang = request_dict.get('lang', None)
+        file_name = request_dict.get('file_name', None)
+        file_type = request_dict.get('file_type', None)
+        package = request_dict.get('package', None)
+        explain = request_dict.get('explain', '')
+        is_update = request_dict.get('is_update', None)
+        is_open = request_dict.get('is_open', None)
+        # logger.info('文件名字:')
+        # logger.info(file_name)
+        param_flag = CommonService.get_param_flag(
+            data=[pc_name, bundle_version, pc_version, pc_test, lang, file_name, file_type, package, is_update, is_open])
+        if param_flag is not True:
+            return response.json(444)
+        else:
+            file = Pc_Info.objects.filter(pc_name=pc_name, bundle_version=bundle_version,
+                                          pc_version=pc_version, pc_test=pc_test)
+            if file:
+                return response.json(174)
+            try:
+                logger.info('开始上传')
+                # 把安装包上传到s3
+                aws_s3_guonei = boto3.client(
+                    's3',
+                    aws_access_key_id=AWS_ACCESS_KEY_ID[0],
+                    aws_secret_access_key=AWS_SECRET_ACCESS_KEY[0],
+                    config=botocore.client.Config(signature_version='s3v4'),
+                    region_name='cn-northwest-1'
+                )
+                download_link = '{pc_name}/{pc_version}_{bundle_version}_{pc_test}_{file_name}'.format(
+                    pc_name=pc_name, pc_version=pc_version, bundle_version=bundle_version,
+                    pc_test=pc_test, file_name=file_name)
+                response_url = aws_s3_guonei.generate_presigned_url(
+                    ClientMethod='put_object',
+                    Params={
+                        'Bucket': 'pc-package',
+                        'Key': download_link
+                    },
+                    ExpiresIn=3600
+                )
+                # 通过上传签名url对文件进行上传
+                # requests.put(response_url, data=file_name)
+                # logger.info('上传完成')
+                add_time = time.time()
+                create_dict = {
+                    'pc_name': pc_name,
+                    'bundle_version': bundle_version,
+                    'pc_version': pc_version,
+                    'pc_test': pc_test,
+                    'lang': lang,
+                    'download_link': download_link,
+                    'add_time': add_time,
+                    'update_time': add_time,
+                    'file_type': file_type,
+                    'package': package,
+                    'explain': explain,
+                    'is_update': is_update,
+                    'is_open': is_open
+                }
+                pc_Info = Pc_Info(**create_dict)
+                pc_Info.save()
+            except Exception:
+                errorInfo = traceback.format_exc()
+                print(errorInfo)
+                return response.json(500, {'details': errorInfo})
+            else:
+                if pc_Info.id:
+                    res = {'id': pc_Info.id,
+                           'pc_name': pc_Info.pc_name,
+                           'bundle_version': pc_Info.bundle_version,
+                           'pc_version': pc_Info.pc_version,
+                           'pc_test': pc_Info.pc_test,
+                           'download_link': pc_Info.download_link,
+                           'lang': pc_Info.lang,
+                           'add_time': pc_Info.add_time,
+                           'update_time': pc_Info.update_time,
+                           'file_type': pc_Info.file_type,
+                           'package': pc_Info.package,
+                           'explain': pc_Info.explain,
+                           'is_update': pc_Info.is_update,
+                           'is_open': pc_Info.is_open,
+                           'upload_url': response_url
+                           }
+                    return response.json(0, res)
+                else:
+                    return response.json(500)
+
+    def s3addanduploadlog(self, request_dict, response, request):
+        logger = logging.getLogger('info')
+        logger.info('s3方式上传参数:')
+        logger.info(request_dict)
+        token = request_dict.get('token', None)
+        tko = TokenObject1(token)
+        response.lang = tko.lang
+        if tko.code != 0:
+            return response.json(tko.code)
+        # 获取访问者的id和岗位
+        userID = tko.id
+
+
+        datetime = request_dict.get('datetime', None)
+        file_name = request_dict.get('file_name', None)
+        pathtype = request_dict.get('pathtype', 'log')
+        # logger.info('文件名字:')
+        # logger.info(file_name)
+        param_flag = CommonService.get_param_flag(
+            data=[datetime, file_name, pathtype])
+        if param_flag is not True:
+            return response.json(444)
+
+        logger.info('开始上传')
+        # 把安装包上传到s3
+        aws_s3_guonei = boto3.client(
+            's3',
+            aws_access_key_id=AWS_ACCESS_KEY_ID[0],
+            aws_secret_access_key=AWS_SECRET_ACCESS_KEY[0],
+            config=botocore.client.Config(signature_version='s3v4'),
+            region_name='cn-northwest-1'
+        )
+        download_link = '{pathtype}/{datetime}/{file_name}'.format(
+            pathtype=pathtype, datetime=datetime, file_name=file_name)
+        response_url = aws_s3_guonei.generate_presigned_url(
+            ClientMethod='put_object',
+            Params={
+                'Bucket': 'pc-package',
+                'Key': download_link
+            },
+            ExpiresIn=3600
+        )
+        add_time = time.time()
+        PctestlogModel.objects.create(user_id=userID, content=download_link, addtime=add_time)
+        return response.json(0, {'upload_url': response_url, 'datetime': datetime})
+
+
+    def s3download(self, request_dict, response):
+        pc_name = request_dict.get('pc_name', None)
+        bundle_version = request_dict.get('bundle_version', None)
+        pc_version = request_dict.get('pc_version', None)
+        pc_test = request_dict.get('pc_test', None)
+        param_flag = CommonService.get_param_flag(
+            data=[pc_name, bundle_version, pc_version, pc_test])
+        if param_flag is not True:
+            return response.json(444)
+        path = Pc_Info.objects.filter(pc_name=pc_name, bundle_version=bundle_version, pc_version=pc_version,
+                                      pc_test=pc_test).values('download_link')
+        if not path:
+            return response.json(173)
+        path = path[0]['download_link']
+        aws_s3_guonei = boto3.client(
+            's3',
+            aws_access_key_id=AWS_ACCESS_KEY_ID[0],
+            aws_secret_access_key=AWS_SECRET_ACCESS_KEY[0],
+            config=botocore.client.Config(signature_version='s3v4'),
+            region_name='cn-northwest-1'
+        )
+        response_url = aws_s3_guonei.generate_presigned_url(
+            ClientMethod='get_object',
+            Params={
+                'Bucket': 'pc-package',
+                'Key': path
+            },
+            ExpiresIn=3600
+        )
+        res = {'path': path,
+               'response_url': response_url
+               }
+        return response.json(0, res)
+
+    def s3downloadlog(self, request_dict, response):
+        id = request_dict.get('id', None)
+        pclog_qs = PctestlogModel.objects.filter(id=id)
+        if not pclog_qs:
+            return response.json(173)
+        path = pclog_qs[0].content
+        aws_s3_guonei = boto3.client(
+            's3',
+            aws_access_key_id=AWS_ACCESS_KEY_ID[0],
+            aws_secret_access_key=AWS_SECRET_ACCESS_KEY[0],
+            config=botocore.client.Config(signature_version='s3v4'),
+            region_name='cn-northwest-1'
+        )
+        response_url = aws_s3_guonei.generate_presigned_url(
+            ClientMethod='get_object',
+            Params={
+                'Bucket': 'pc-package',
+                'Key': path
+            },
+            ExpiresIn=3600
+        )
+        res = {'path': path,
+               'response_url': response_url
+               }
+        return response.json(0, res)
+
+    def edit(self, request_dict, response):
+        id = request_dict.get('id', None)
+        explain = request_dict.get('explain', None)
+        is_open = request_dict.get('is_open', None)
+        param_flag = CommonService.get_param_flag(
+            data=[id, explain, is_open])
+        if param_flag is not True:
+            return response.json(444)
+        file = Pc_Info.objects.filter(id=id)
+        if not file.exists():
+            return response.json(173)
+        else:
+            file.update(explain=explain, is_open=is_open)
+            return response.json(0)
+
+    def s3delete(self, request_dict, response):
+        global file
+        token = request_dict.get('token', None)
+        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(104)
+        id = request_dict.get('id', None)
+        package = request_dict.get('package', None)
+        if id and package:
+            return response.json(444)
+        elif id and package is None:
+            file = Pc_Info.objects.filter(id=id)
+        elif package and id is None:
+            try:
+                package = int(package)
+                file = Pc_Info.objects.filter(package=package)
+            except Exception as e:
+                return response.json(176)
+        if not file.exists():
+            return response.json(173)
+        try:
+            # 删除s3和数据库里的相应数据
+            file_path = file[0].download_link
+            aws_s3_guonei = boto3.client(
+                's3',
+                aws_access_key_id=AWS_ACCESS_KEY_ID[0],
+                aws_secret_access_key=AWS_SECRET_ACCESS_KEY[0],
+                config=botocore.client.Config(signature_version='s3v4'),
+                region_name='cn-northwest-1'
+            )
+            try:
+                # 获取存储桶的对象,判断对象是否上传成功
+                obj = aws_s3_guonei.get_object(Bucket='pc-package', Key=file_path)
+            except Exception as e:
+                print(e)
+                file.delete()
+            else:
+                if obj:
+                    aws_s3_guonei.delete_object(Bucket='pc-package', Key=file_path)
+                    file.delete()
+        except Exception as e:
+            return response.json(176, repr(e))
+        else:
+            return response.json(0)
+
+    def queryall(self, request_dict, response):
+        token = request_dict.get('token', None)
+        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(104)
+        page = int(request_dict.get('page', None))
+        line = int(request_dict.get('line', None))
+        if page is None or line is None:
+            return response.json(444, 'page,line')
+        queryset = Pc_Info.objects.all()
+        if queryset.exists():
+            count = queryset.count()
+            res = queryset[(page - 1) * line:page * line]
+            send_json = CommonService.qs_to_dict(res)
+            send_json['count'] = count
+            return response.json(0, send_json)
+        else:
+            return response.json(173)
+
+    def addandupload(self, request_dict, response, request):
+        token = request_dict.get('token', None)
+        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(104)
+        pc_name = request_dict.get('pc_name', None)
+        bundle_version = request_dict.get('bundle_version', None)
+        pc_version = request_dict.get('pc_version', None)
+        pc_test = request_dict.get('pc_test', None)
+        lang = request_dict.get('lang', None)
+        file_name = request.FILES.get('file_name', None)
+        param_flag = CommonService.get_param_flag(
+            data=[pc_name, bundle_version, pc_version, pc_test, lang, file_name])
+        if param_flag is not True:
+            return response.json(444)
+        else:
+            file = Pc_Info.objects.filter(pc_name=pc_name, bundle_version=bundle_version,
+                                          pc_version=pc_version, pc_test=pc_test)
+            if file:
+                return response.json(174)
+            try:
+                # 安装包上传到服务器本地
+                file_path = 'static/pc/' + pc_name
+                if not os.path.exists(file_path):
+                    os.makedirs(os.path.join(BASE_DIR, file_path))
+                a = os.path.splitext(str(file_name))[-1]
+                if not a:
+                    return response.json(444, "文件无后缀")
+                name = pc_version + '_' + bundle_version + '_' + pc_test + str(a)
+                file_path = file_path + '/' + str(name)
+                upload_path = os.path.join(BASE_DIR, file_path)
+                print('upload_path:', upload_path)
+                with open(upload_path, 'wb+') as destination:
+                    for chunk in file_name.chunks():
+                        destination.write(chunk)
+                add_time = time.time()
+                create_dict = {
+                    'pc_name': pc_name,
+                    'bundle_version': bundle_version,
+                    'pc_version': pc_version,
+                    'pc_test': pc_test,
+                    'lang': lang,
+                    'download_link': file_path,
+                    'add_time': add_time,
+                    'update_time': add_time
+                }
+                pc_Info = Pc_Info(**create_dict)
+                pc_Info.save()
+            except Exception:
+                errorInfo = traceback.format_exc()
+                print(errorInfo)
+                return response.json(700, {'details': errorInfo})
+            else:
+                if pc_Info.id:
+                    res = {'pc_name': pc_Info.pc_name,
+                           'bundle_version': pc_Info.bundle_version,
+                           'pc_version': pc_Info.pc_version,
+                           'pc_test': pc_Info.pc_test,
+                           'download_link': pc_Info.download_link,
+                           'lang': pc_Info.lang,
+                           'add_time': pc_Info.add_time,
+                           'update_time': pc_Info.update_time
+                           }
+                    return response.json(0, res)
+                else:
+                    return response.json(500)
+
+
+    def download(self, request_dict, response):
+        pc_name = request_dict.get('pc_name', None)
+        bundle_version = request_dict.get('bundle_version', None)
+        pc_version = request_dict.get('pc_version', None)
+        pc_test = request_dict.get('pc_test', None)
+        param_flag = CommonService.get_param_flag(
+            data=[pc_name, bundle_version, pc_version, pc_test])
+        if param_flag is not True:
+            return response.json(444)
+        path = Pc_Info.objects.filter(pc_name=pc_name, bundle_version=bundle_version, pc_version=pc_version,
+                                      pc_test=pc_test).values('download_link')
+        if not path:
+            return response.json(173)
+        filepath = path[0]['download_link']
+        fullPath = os.path.join(BASE_DIR, filepath)
+        fullPath.replace('\\', '/')
+        res = ResponseObject()
+        print('fullPath:')
+        print(fullPath)
+        print(os.path.basename(fullPath))
+        if fullPath:
+            if os.path.isfile(fullPath):
+                try:
+                    wrapper = FileWrapper(open(fullPath, 'rb'))
+                    response = HttpResponse(wrapper, content_type="application/octet-stream")
+                    response['Content-Length'] = os.path.getsize(fullPath)
+                    response['Content-Disposition'] = 'attachment; filename={}'.format(parse.quote_plus(os.path.basename(fullPath), encoding="utf-8"))
+                    response['Content-MD5'] = getMD5orSHA265(fullPath)
+                    # 校验文件md5值
+                    response['Content-SHA265'] = getMD5orSHA265(fullPath, 'SHA265')
+                    response['Content-CRC32'] = getMD5orSHA265(fullPath, 'CRC32')
+                    response['Content-Error'] = res.formal(0)
+                    return response
+                except Exception as e:
+                    return res.json(906, repr(e))
+            else:
+                return res.json(907)
+        else:
+            return res.json(444, 'fullPath')
+
+    def delete(self, request_dict, response):
+        token = request_dict.get('token', None)
+        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(104)
+        id = request_dict.get('id', None)
+        param_flag = CommonService.get_param_flag(data=[id])
+        if param_flag is not True:
+            return response.json(444)
+        file = Pc_Info.objects.filter(id=id)
+        if not file.exists():
+            return response.json(173)
+        try:
+            # 删除文件,文件夹和数据库里的相应数据
+            file_path = file[0].download_link
+            file_path = os.path.join(BASE_DIR, file_path).replace('\\', '/')
+            os.remove(file_path)
+            # file_path = file_path.split("/")
+            # file_path = [str(i) for i in file_path][:-1]
+            # file_path = "/".join(file_path)
+            # shutil.rmtree(file_path)
+            file.delete()
+        except Exception as e:
+            return response.json(176, repr(e))
+        else:
+            return response.json(0)
+
+def compareVersion(s1: str, s2: str) -> Union[str, int]:
+    i, j = 0, 0
+    while i < len(s1) or j < len(s2):
+        k1 = i
+        while k1 < len(s1) and s1[k1] != '.':
+            k1 += 1
+        k2 = j
+        while k2 < len(s2) and s2[k2] != '.':
+            k2 += 1
+
+        a = int(s1[i:k1]) if i != k1 else 0
+        b = int(s2[j:k2]) if j != k2 else 0
+        if a > b:
+            return s1
+        if a < b:
+            return s2
+        i = k1 + 1
+        j = k2 + 1
+    return 0
+
+def getMD5orSHA265(fileName, encryptionType='MD5'):
+    """
+
+    :param filePath:
+    :param encryptionType:
+    :return:
+    """
+    if not os.path.isfile(fileName):
+        return ''
+    else:
+        if encryptionType == 'MD5':
+            encryption = hashlib.md5()
+        elif encryptionType == 'SHA265':
+            encryption = hashlib.sha256()
+        elif encryptionType == 'CRC32':
+            f = open(fileName, 'rb')
+            chunk = f.read()
+            return crc32(chunk)
+
+        f = open(fileName, 'rb')
+        block_size = 8192  # why is 8192 | 8192 is fast than 2048
+
+        while True:
+            chunk = f.read(block_size)
+            if not chunk:
+                break
+            encryption.update(chunk)
+
+        f.close()
+        return encryption.hexdigest()
+

+ 528 - 0
Controller/PctestController.py

@@ -0,0 +1,528 @@
+import hashlib
+import logging
+import shutil
+import time
+import traceback
+import os
+from urllib import request, parse
+import requests
+from django.http import HttpResponse
+import jwt
+from django.views.generic.base import View
+
+from Model.models import PctestuserModel, PctestjobModel, PctestdeviceModel,\
+    PctestfunctionModel, PctestjobdeviceModel, PctestModel, PctestlogModel
+from Object.ResponseObject import ResponseObject
+from Object.TokenObject import TokenObject
+from Service.CommonService import CommonService
+from Ansjer.config import OAUTH_ACCESS_TOKEN_SECRET
+
+
+class PcTest(View):
+    def dispatch(self, requset, *args, **kwargs):
+        return super(PcTest, self).dispatch(requset, *args, **kwargs)
+
+    def get(self, request, *args, **kwargs):
+        operation = kwargs.get('operation')
+        request.encoding = 'utf-8'
+        return self.validation(request.GET, request, operation)
+
+    def post(self, request, *args, **kwargs):
+        operation = kwargs.get('operation')
+        request.encoding = 'utf-8'
+        return self.validation(request.POST, request, operation)
+
+    def validation(self, request_dict, request, operation):
+        response = ResponseObject()
+        if not operation:
+            return response.json(444, 'operation')
+        else:
+            if operation == 'login':
+                return self.login(request_dict, response)
+            else:
+                print(operation)
+                token = request_dict.get('token', None)
+                print('token:', token)
+                # 解析token,验证是否有id
+                tko = TokenObject1(token)
+                response.lang = tko.lang
+                if tko.code != 0:
+                    return response.json(tko.code)
+                # 获取访问者的id和岗位
+                userID = tko.id
+                jobID = tko.job
+                # if jobID == 1:
+                #     # 管理员可访问的接口
+                if operation == 'job/add':
+                    return self.jobadd(request_dict, userID, response)
+                elif operation == 'job/query':
+                    return self.jobquery(request_dict, userID, response)
+                elif operation == 'job/delete':
+                    return self.jobdelete(request_dict, userID, response)
+                elif operation == 'device/add':
+                    return self.deviceadd(request_dict, userID, response)
+                elif operation == 'device/query':
+                    return self.devicequery(request_dict, userID, response)
+                elif operation == 'device/delete':
+                    return self.devicedelete(request_dict, userID, response)
+                elif operation == 'function/add':
+                    return self.functionadd(request_dict, userID, response)
+                elif operation == 'function/query':
+                    return self.functionquery(request_dict, userID, response)
+                elif operation == 'function/delete':
+                    return self.functiondelete(request_dict, userID, response)
+                elif operation == 'job/device/add':
+                    return self.jobdeviceadd(request_dict, userID, response)
+                elif operation == 'device/function/add':
+                    return self.devicefunctionadd(request_dict, userID, response)
+                elif operation == 'staff/add':
+                    return self.staffadd(request_dict, userID, response)
+                elif operation == 'staff/query':
+                    return self.staffquery(request_dict, userID, response)
+                elif operation == 'staff/delete':
+                    return self.staffdelete(request_dict, userID, response)
+
+
+                # 公共访问的接口
+                if operation == 'job/device/query':
+                    return self.jobdevicequery(request_dict, jobID, response)
+                elif operation == 'device/function/query':
+                    return self.devicefunctionquery(request_dict, jobID, response)
+                elif operation == 'log/add':
+                    return self.logadd(request_dict, userID, response)
+                elif operation == 'log/query':
+                    return self.logquery(request_dict, userID, response)
+                elif operation == 'token/fullInfo':
+                    return self.fullInfo(request_dict, userID, response)
+                elif operation == 'staff/initPass':
+                    return self.initPass(request_dict, userID, response)
+                elif operation == 'staff/updatePass':
+                    return self.updatePass(request_dict, userID, response)
+                else:
+                    return response.json(404)
+
+
+    def login(self, request_dict, response):
+        username = request_dict.get('username', None)
+        password = request_dict.get('password', None)
+        param_flag = CommonService.get_param_flag(
+            data=[username, password])
+        if param_flag is not True:
+            return response.json(444)
+        user_qs = PctestuserModel.objects.filter(username=username, password=password)
+        if not user_qs.exists():
+            if not PctestuserModel.objects.filter(username=username).exists():
+                return response.json(104)
+            return response.json(111)
+
+        users = user_qs.values('id', 'username', 'password', 'job__id', 'job__jobcode')[0]
+        tko = TokenObject()
+        # 加密
+        res = tko.generate(
+            data={'id': users['id'], 'username': users['username'], 'password': users['password'], 'jobid': users['job__id'], 'job': users['job__jobcode']})
+        res_qs = {
+            'res': res,
+            'id': users['id'],
+            'username': users['username'],
+            'job': users['job__jobcode'],
+            'jobid': users['job__id']
+        }
+        return response.json(0, res_qs)
+
+    def jobadd(self, request_dict, userID, response):
+        jobname = request_dict.get('jobname', None)
+        jobcode = request_dict.get('jobcode', None)
+        param_flag = CommonService.get_param_flag(
+            data=[jobname])
+        if param_flag is not True:
+            return response.json(444)
+        job_qs = PctestjobModel.objects.filter(jobname=jobname)
+        if job_qs.exists():
+            return response.json(174)
+        else:
+            PctestjobModel.objects.create(jobname=jobname,jobcode=jobcode)
+            return response.json(0)
+
+    def jobquery(self, request_dict, userID, response):
+        # user_qs = PctestuserModel.objects.filter(id=userID).values('job')
+        # job_qs = PctestjobModel.objects.filter(id=user_qs[0]['job'])
+        #
+        # if job_qs[0].id == 1:
+        #     job_qs = PctestjobModel.objects.filter()
+        job_qs = PctestjobModel.objects.filter()
+        device_qs = PctestjobdeviceModel.objects.filter(job__in=job_qs).values('device')
+
+        data = CommonService.qs_to_list(job_qs.values('id', 'jobname', 'jobcode'))
+
+        i = 0
+        for jobs in job_qs:
+            data[i]['devices'] = CommonService.qs_to_list(device_qs.filter(job__id=jobs.id).values('device__id', 'device__devicename'))
+            i = i + 1
+        count = device_qs.count()
+        return response.json(0, {'datas': data, 'count': count})
+
+    def jobdelete(self, request_dict, userID, response):
+        id = request_dict.get('id', None)
+        job_qs = PctestjobModel.objects.filter(id=id)
+        if job_qs.exists:
+            job_qs.delete()
+            PctestjobdeviceModel.objects.filter(job__in=job_qs).delete()
+        return response.json(0)
+
+    def deviceadd(self, request_dict, userID, response):
+        deviceid = request_dict.get('deviceid', None)
+        devicename = request_dict.get('devicename', None)
+        functions= request_dict.get('functions', None)
+        param_flag = CommonService.get_param_flag(
+            data=[devicename])
+        if param_flag is not True:
+            return response.json(444)
+
+        if not deviceid:
+            device_qs = PctestdeviceModel.objects.filter(devicename=devicename)
+            if device_qs.exists():
+                return response.json(174)
+            PctestdeviceModel.objects.create(devicename=devicename)
+
+        else:
+            device_qs = PctestdeviceModel.objects.filter(id=deviceid)
+            PctestdeviceModel.objects.filter(id=deviceid).update(devicename=devicename)
+
+
+        function_list = PctestfunctionModel.objects.filter(id__in=functions.split(','))
+        # 判断设备与此职能是否有关联,避免重复添加
+        PctestModel.objects.filter(device_id=device_qs[0].id).delete()
+        for fid in functions.split(','):
+            for fun in function_list:
+                if int(fid) ==fun.id:
+                    PctestModel.objects.create(device_id=device_qs[0].id, function_id=fun.id)
+        return response.json(0)
+
+
+
+
+    def devicequery(self, request_dict, userID, response):
+        # user_qs = PctestuserModel.objects.filter(id=userID).values('job')
+        # job_qs = PctestjobModel.objects.filter(id=user_qs[0]['job'])
+        #
+        # if job_qs[0].id == 1:
+        #     device_qs = PctestjobdeviceModel.objects.filter().values('device')
+        # else:
+        #     device_qs = PctestjobdeviceModel.objects.filter(job__in=job_qs).values('device')
+        device_qs = PctestdeviceModel.objects.filter()
+
+        function_qs = PctestModel.objects.filter(device__in=device_qs)
+
+        device_qs = device_qs.values('id', 'devicename')
+        data = CommonService.qs_to_list(device_qs)
+        i = 0
+        for devices in device_qs:
+            data[i]['functions'] = CommonService.qs_to_list(function_qs.filter(device__id=devices['id']).values('function__id','function__functionname','function__functioncode'))
+            i = i + 1
+        count = device_qs.count()
+        return response.json(0, {'datas': data, 'count': count})
+
+    def devicedelete(self, request_dict, userID, response):
+        id = request_dict.get('id', None)
+        device_qs = PctestdeviceModel.objects.filter(id=id)
+        if device_qs.exists:
+            PctestjobdeviceModel.objects.filter(device__in=device_qs).delete()
+            PctestModel.objects.filter(device__in=device_qs).delete()
+            device_qs.delete()
+
+
+        return response.json(0)
+
+    def functionadd(self, request_dict, userID, response):
+        functionname = request_dict.get('functionname', None)
+        functioncode = request_dict.get('functioncode', None)
+        id = request_dict.get('id', None)
+        param_flag = CommonService.get_param_flag(
+            data=[functionname])
+        if param_flag is not True:
+            return response.json(444)
+
+        if not id:
+            job_qs = PctestfunctionModel.objects.filter(functionname=functionname)
+            if job_qs.exists():
+                return response.json(174)
+            PctestfunctionModel.objects.create(functionname=functionname,functioncode=functioncode)
+        else:
+            PctestfunctionModel.objects.filter(id=id).update(functionname=functionname, functioncode=functioncode)
+
+        return response.json(0)
+
+    def functiondelete(self, request_dict, userID, response):
+        id = request_dict.get('id', None)
+        function_qs = PctestfunctionModel.objects.filter(id=id)
+
+        if function_qs.exists:
+            PctestModel.objects.filter(function__in=function_qs).delete()
+            function_qs.delete()
+        return response.json(0)
+
+    def functionquery(self, request_dict, userID, response):
+        function_list = PctestfunctionModel.objects.all()
+        count = function_list.count()
+        res = function_list
+        send_json = CommonService.qs_to_dict(res)
+        send_json['count'] = count
+        return response.json(0, send_json)
+
+    def jobdeviceadd(self, request_dict, userID, response):
+        job_id = request_dict.get('job_id', None)
+        device_id = request_dict.get('device_id', None)
+        param_flag = CommonService.get_param_flag(
+            data=[job_id, device_id])
+        if param_flag is not True:
+            return response.json(444)
+        # 判断岗位与设备是否存在
+        job_list = PctestjobModel.objects.filter(id=job_id)
+        device_list = PctestdeviceModel.objects.filter(id=device_id)
+        if not job_list.exists() or not device_list.exists():
+            return response.json(173)
+        # 判断岗位与此设备是否有关联,避免重复添加
+        job_device_list = PctestjobdeviceModel.objects.filter(job_id=job_id, device_id=device_id)
+        if job_device_list.exists():
+            return response.json(174)
+        else:
+            PctestjobdeviceModel.objects.create(job_id=job_id, device_id=device_id)
+            return response.json(0)
+
+    def jobdevicequery(self, request_dict, jobID, response):
+        if jobID == 1:
+            job_device_list = PctestjobdeviceModel.objects.values('job__jobname', 'device__devicename')
+        else:
+            job_device_list = PctestjobdeviceModel.objects.filter(job_id=jobID).values('device_id','device__devicename')
+        device_list = []
+        for i in job_device_list:
+            device_list.append(i)
+        return response.json(0, device_list)
+
+    def devicefunctionadd(self, request_dict, userID, response):
+        device_id = request_dict.get('device_id', None)
+        function_id = request_dict.get('function_id', None)
+        param_flag = CommonService.get_param_flag(
+            data=[function_id, device_id])
+        if param_flag is not True:
+            return response.json(444)
+        # 判断设备与职能是否存在
+        device_list = PctestdeviceModel.objects.filter(id=device_id)
+        function_list = PctestfunctionModel.objects.filter(id=function_id)
+        if not function_list.exists() or not device_list.exists():
+            return response.json(173)
+        # 判断设备与此职能是否有关联,避免重复添加
+        device_function_list = PctestModel.objects.filter(device_id=device_id, function_id=function_id)
+        if device_function_list.exists():
+            return response.json(174)
+        else:
+            PctestModel.objects.create(device_id=device_id, function_id=function_id)
+            return response.json(0)
+
+    def devicefunctionquery(self, request_dict, jobID, response):
+        if jobID == 1:
+            device_function_list = PctestModel.objects.values('device__devicename', 'function__functionname')
+        else:
+            device_id = request_dict.get('device_id', None)
+            param_flag = CommonService.get_param_flag(
+                data=[device_id])
+            if param_flag is not True:
+                return response.json(444)
+            # 判断岗位与此设备是否有关联,有关联则通过
+            job_device_list = PctestjobdeviceModel.objects.filter(job_id=jobID, device_id=device_id)
+            if not job_device_list.exists():
+                return response.json(173)
+            device_function_list = PctestModel.objects.filter(device_id=device_id).values('function_id', 'function__functionname')
+        function_list = []
+        for i in device_function_list:
+            function_list.append(i)
+        return response.json(0, function_list)
+
+    def staffadd(self, request_dict, userID, response):
+        username = request_dict.get('username', None)
+        password = request_dict.get('password', None)
+        id = request_dict.get('id', None)
+        job_id = request_dict.get('job_id', None)
+        param_flag = CommonService.get_param_flag(
+            data=[username, job_id])
+        if param_flag is not True:
+            return response.json(444)
+        # 判断员工与岗位是否存在,员工存在返回174
+        user_list = PctestuserModel.objects.filter(username=username)
+
+        job_list = PctestjobModel.objects.filter(id=job_id)
+        if not job_list.exists():
+            return response.json(174)
+
+        if not id:
+            if user_list.exists():
+                return response.json(174)
+            PctestuserModel.objects.create(username=username, password=password, job_id=job_id)
+        else:
+            PctestuserModel.objects.filter(id=id).update(username=username, job_id=job_id)
+
+        return response.json(0)
+
+
+    def initPass(self, request_dict, userID, response):
+
+        id = request_dict.get('id', None)
+        param_flag = CommonService.get_param_flag(
+            data=[id])
+        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='555')
+
+        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)
+
+
+
+
+    def staffquery(self, request_dict, userID, response):
+        user_list = PctestuserModel.objects.filter(id__gt=1).values('id', 'username', 'job__id', 'job__jobname', 'job__jobcode')
+        users_list = []
+        for i in user_list:
+            users_list.append(i)
+        return response.json(0, users_list)
+
+    def staffdelete(self, request_dict, userID, response):
+        id = request_dict.get('id', None)
+        param_flag = CommonService.get_param_flag(data=[id])
+        if param_flag is not True:
+            return response.json(444)
+        staff = PctestuserModel.objects.filter(id=id)
+        if not staff.exists():
+            return response.json(173)
+        else:
+            staff.delete()
+            return response.json(0)
+
+    def logadd(self, request_dict, userID, response):
+        content = request_dict.get('content', None)
+        param_flag = CommonService.get_param_flag(data=[content])
+        if param_flag is not True:
+            return response.json(444)
+        addtime = time.time()
+        PctestlogModel.objects.create(user_id=userID, content=content, addtime=addtime)
+        return response.json(0)
+
+    def logquery(self, request_dict, userID, response):
+        startDateTime = request_dict.get('startDateTime', None)
+        endDateTime = request_dict.get('endDateTime', None)
+        userid = request_dict.get('userid', None)
+        if userid :
+            job_device_list = PctestlogModel.objects.filter(user_id=userID,addtime__range=(startDateTime, endDateTime)).values('id', 'user__id', 'user__username', 'content', 'addtime')
+        else:
+            job_device_list = PctestlogModel.objects.filter(addtime__range=(startDateTime, endDateTime)).values('id', 'user__id', 'user__username', 'content', 'addtime')
+        device_list = []
+        for i in job_device_list:
+            device_list.append(i)
+        return response.json(0, device_list)
+
+    def fullInfo(self, request_dict, userID, response):
+        user_qs = PctestuserModel.objects.filter(id=userID).values('job')
+        fullinfo = []
+        data = {}
+        if user_qs.exists():
+
+            job_qs = PctestjobModel.objects.filter(id=user_qs[0]['job'])
+            user_qs = user_qs.values('id', 'username')
+
+            # device_qs = PctestjobdeviceModel.objects.filter(job__in=job_qs).values('device')
+            #
+            # function_qs = PctestModel.objects.filter(device__in=device_qs)
+
+
+            data = user_qs[0]
+            data['jobs'] = CommonService.qs_to_list(job_qs.values('id', 'jobname', 'jobcode'))
+
+            # i = 0
+            # for jobs in data['jobs']:
+            #
+            #     data['jobs'][i]['devices'] = CommonService.qs_to_list(device_qs.filter(job__id=jobs['id']).values('device__id', 'device__devicename'))
+            #
+            #     j = 0
+            #     for devices in jobs['devices']:
+            #         data['jobs'][i]['devices'][j]['functions'] = CommonService.qs_to_list(function_qs.filter(device__id=devices['device__id']).values('function__id','function__functionname','function__functioncode'))
+            #         j = j+1
+            #
+            #     i = i+1
+
+
+            fullinfo.append(data)
+        return response.json(0, fullinfo)
+
+
+class TokenObject1:
+
+    def __init__(self, token=None):
+        if token == 'local':
+            token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VySUQiOiIxNTg0MzUxODk2MjgyMTM4MDAxMzgwMDAiLCJsYW5nIjoiZW4iLCJ1c2VyIjoiMTM2ODAzMTc1OTYiLCJtX2NvZGUiOiIxMjM0MTMyNDMyMTQiLCJleHAiOjE1ODcyNzcwNjB9.c0LV_XyxwbzUlYqMJqx7vw9f19Jv-0kGnUHuu_go-mo'
+        if token == 'test':
+            token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiMTM4MDAxMzgwMDEiLCJleHAiOjE1Njk5OTg4OTYsInVzZXJJRCI6IjE1MTU2NDI2MjMzNzkzOTUxMzgwMDEzODAwMSIsImxhbmciOiJlbiIsIm1fY29kZSI6IjEyMzQxMzI0MzIxNCJ9.VAQtT9AbCCfXcrNj9DL5cvVasMDoI7AP8ptgU1GoMu8'
+        self.token = token
+        self.lang = None
+        self.id = None
+        self.job = None
+        self.user = ''
+        self.code = 0
+        # 令牌校验
+        self.valid()
+
+    def valid(self):
+        if self.token is None:
+            self.code = 309
+            return
+        try:
+            res = jwt.decode(self.token, OAUTH_ACCESS_TOKEN_SECRET, algorithms='HS256')
+            print('res:', res)
+            # print(res)
+            self.id = res.get('id', None)
+            self.lang = res.get('lang', None)
+            self.job = res.get('job', None)
+            self.user = res.get('user', '')
+            # 刷新登录时间
+            # if self.userID:
+            #     print(self.user)
+            #     redisObj = RedisObject(db=3)
+            #     redisObj.set_data(key=self.userID, val=self.user, expire=300)
+
+        except jwt.ExpiredSignatureError as e:
+            print('过期')
+            print(repr(e))
+            self.code = 309
+            return
+        except Exception as e:
+            self.code = 309
+            return
+        else:
+            if not self.id:
+                self.code = 309
+                return
+            else:
+                if self.id:
+                    self.code = 0
+                    return res
+                else:
+                    self.code = 309
+                    return

+ 201 - 202
Controller/SerialNumberController.py

@@ -1,5 +1,6 @@
 #!/usr/bin/env python3
 # -*- coding: utf-8 -*-
+import json
 import logging
 import random
 import time
@@ -7,15 +8,18 @@ import time
 from django.db import transaction
 from django.views import View
 
+from Controller.DetectController import DetectControllerView
 from Controller.DeviceConfirmRegion import Device_Region
 from Model.models import SerialNumberModel, CompanySerialModel, UIDCompanySerialModel, CompanyModel, RegionModel, \
-    CountryModel, UIDModel, Device_Info, iotdeviceInfoModel
+    CountryModel, UIDModel, Device_Info, iotdeviceInfoModel, UidPushModel, LogModel, MacModel
 from Object.RedisObject import RedisObject
 from Object.uidManageResponseObject import uidManageResponseObject
 from Object.TokenObject import TokenObject
 from Service.AlgorithmService import AlgorithmBaseOn35
 from Service.CommonService import CommonService
+from Ansjer.config import CRCKey
 from Service.ModelService import ModelService
+from Object.AWS.S3Email import S3Email
 
 
 class SerialNumberView(View):
@@ -38,12 +42,10 @@ class SerialNumberView(View):
 
         if operation == 'getUID':
             return self.do_get_uid(request_dict, response)
-        elif operation == 'getSerial':
-            return self.do_get_serial_number(request_dict, response)
         elif operation == 'attachUID':
             return self.do_attach_uid(request_dict, response, request)
         elif operation == 'detachUID':
-            return self.do_detach_uid(request_dict, response)
+            return self.do_detach_uid(request, request_dict, response)
         elif operation == 'create':
             return self.do_create(request_dict, response)
         else:
@@ -61,7 +63,6 @@ class SerialNumberView(View):
 
     def do_create(self, request_dict, response):
         quantity = int(request_dict.get('quantity', 0))
-        p2p = int(request_dict.get('p2p', 0))
 
         if not quantity:
             return response.json(444)
@@ -76,10 +77,10 @@ class SerialNumberView(View):
             algorithm = AlgorithmBaseOn35()
             for i in range(quantity):
                 serial_number = algorithm.getLetter(sum)
-                sum += 1    # sum每次递增1
+                sum += 1  # sum每次递增1
                 # 前面补0至六位
-                serial_number = (6-len(serial_number))*'0' + serial_number
-                serial_number_bulk.append(SerialNumberModel(serial_number=serial_number, add_time=now_time, p2p=p2p))
+                serial_number = (6 - len(serial_number)) * '0' + serial_number
+                serial_number_bulk.append(SerialNumberModel(serial_number=serial_number, add_time=now_time))
             # 开启事务写入
             with transaction.atomic():
                 SerialNumberModel.objects.bulk_create(serial_number_bulk)
@@ -88,59 +89,6 @@ class SerialNumberView(View):
             print(e)
             return response.json(500, repr(e))
 
-    # 提供给pc端获取序列号
-    def do_get_serial_number(self, request_dict, response):
-        quantity = request_dict.get('quantity', None)
-        company_id = request_dict.get('company_id', None)
-        token = request_dict.get('token', None)
-        time_stamp = request_dict.get('time_stamp', None)
-        p2p_type = request_dict.get('p2p_type', None)
-
-        if token and time_stamp and quantity and company_id:
-
-            token = int(CommonService.decode_data(token))
-            time_stamp = int(time_stamp)
-
-            now_time = int(time.time())
-            distance = now_time - time_stamp
-
-            if token != time_stamp or distance > 60000 or distance < -60000: #为了全球化时间控制在一天内
-                return response.json(404)
-
-            redisObject = RedisObject()
-            key = 'serial_lock'
-            value = redisObject.lpop(key)
-            count = 0
-            while value is False and count < 5:
-                time.sleep(1)
-                value = redisObject.lpop(key)
-                count += 1
-
-            if count == 5 and value is False:    #暂时注释
-                return response.json(5)
-
-            quantity = int(quantity)
-
-            company_serial_qs = CompanySerialModel.objects.filter(company__secret=company_id, status=0, p2p=p2p_type)
-            if not company_serial_qs.exists():
-                redisObject.rpush(key, value)
-                return response.json(373)
-
-            # 存在对应的企业
-            company_serial_qs = company_serial_qs[0:quantity]
-
-            #company_serial_qs = company_serial_qs.values('id', 'serial_number__serial_number', 'company__mark')
-            data = []
-            ids = []
-            for serial in company_serial_qs:
-                ids.append(serial.id)
-                data.append(serial.serial_number + serial.company.mark)
-            CompanySerialModel.objects.filter(id__in=ids).update(status=1)
-            redisObject.rpush(key, value)
-            return response.json(0, data)
-        else:
-            return response.json(444)
-
     def do_list(self, userID, request_dict, response):
         # perm = ModelService.check_perm_uid_manage(userID, 0)
         # if not perm:
@@ -178,134 +126,165 @@ class SerialNumberView(View):
         else:
             return response.json(444)
 
-    @transaction.atomic
     def do_attach_uid(self, request_dict, response, request):
         serial_number = request_dict.get('serial_number', None)
         country_id = request_dict.get('country_id', None)
         company_id = request_dict.get('company_id', None)
         token = request_dict.get('token', None)
         time_stamp = request_dict.get('time_stamp', None)
+        DeviceSubType = request_dict.get('DeviceSubType', None)
+        p2ptype = request_dict.get('p2ptype', 1)
+        if not all([serial_number, company_id, token, time_stamp]):
+            return response.json(444)
 
-        if serial_number and len(serial_number) == 9  and company_id:
+        token = int(CommonService.decode_data(token))
+        time_stamp = int(time_stamp)
 
-            token = int(CommonService.decode_data(token))
-            time_stamp = int(time_stamp)
+        now_time = int(time.time())
+        distance = now_time - time_stamp
 
-            now_time = int(time.time())
-            distance = now_time - time_stamp
-
-            if token != time_stamp or distance > 60000 or distance < -60000: #为了全球化时间控制在一天内
-                return response.json(404)
+        if token != time_stamp or distance > 60000 or distance < -60000:  # 为了全球化时间控制在一天内
+            return response.json(404)
 
-            mark = serial_number[6:9]
-            serial = serial_number[0:6]
+        serial = serial_number[0:6]
+        full_serial = serial_number[0:9]
 
-            savePoint = transaction.savepoint()
-            try:
-                try:
-                    if not country_id :
-                        ip = CommonService.get_ip_address(request)
-                        country_id = Device_Region().get_device_region(ip)
+        if serial_number[9:10]:
+            p2ptype = serial_number[9:10]
+        try:
+            if not country_id:
+                ip = CommonService.get_ip_address(request)
+                country_id = Device_Region().get_device_region(ip)
 
-                    # 判断序列号是否已和企业关联
-                    company_serial_qs = CompanySerialModel.objects.filter(company__secret=company_id,
-                                                                          serial_number=serial)
-                    if not company_serial_qs.exists():
-                        return response.json(173)
+            # 判断序列号是否已和企业关联
+            company_serial_qs = CompanySerialModel.objects.filter(company__secret=company_id, serial_number=serial)
+            if not company_serial_qs.exists():
+                return response.json(173)
 
-                    # 当序列号已关联UID
-                    company_serial = company_serial_qs[0]
+            # 当序列号已关联UID
+            company_serial = company_serial_qs[0]
 
-                    if company_serial.status == 0:
-                        # 该序列号未绑定企业
-                        return response.json(173)
-                    elif company_serial.status == 1:
-                        # 确定所在区域
-                        country_qs = CountryModel.objects.filter(number=country_id)
-                        if not country_qs.exists():
-                            return response.json(374)
-
-                        region = country_qs.values('region_id')[0]
-
-                        count = 0
-                        while count < 3:
-                            p2p = SerialNumberModel.objects.filter(serial_number=serial).values('p2p')
-                            print('此序列号的p2p类型:', p2p[0]['p2p'])
-                            uid_qs = UIDModel.objects.filter(vpg__company_id=company_serial.company.id, vpg__region_id=region['region_id'],
-                                                             status=0, p2p_type=p2p[0]['p2p']).order_by('id')[0:10]
-                            # uid_qs:未进行绑定的uid列表
-                            if uid_qs.exists():
-                                uid = uid_qs[0]
-                                # uid.status = 2
-                                # uid.update_time = int(time.time())
-                                result = UIDModel.objects.filter(id=uid.id, status=0).update(**{
-                                    'status': 2, 'update_time': int(time.time())
-                                })
-
-                                if int(result) <= 0:
-                                    count += 1
-                                    continue
-
-                                now_time = int(time.time())
-                                uid_serial = UIDCompanySerialModel(uid_id=uid.id, company_serial_id=company_serial.id,
-                                                                   add_time=now_time, update_time=now_time)
-                                uid_serial.save()
-
-                                company_serial.status = 2
-                                company_serial.save()
-
-                                dev = Device_Info.objects.filter(UID=uid.uid)
-                                if dev.exists():
-                                    dev.update(serial_number=serial_number)
-
-                                res = {
-                                    'full_uid_code': CommonService.encode_data(uid.full_uid_code),
-                                    'uid': CommonService.encode_data(uid.uid),
-                                    'mac': CommonService.encode_data(uid.mac),
-                                    'extra': uid.uid_extra
-                                }
-                                return response.json(0, res)
-                            else:
-                                return response.json(375)
-
-                        return response.json(5)
-                    else:
-                        uid_qs = UIDCompanySerialModel.objects.filter(company_serial_id=company_serial.id)
-                        if uid_qs.exists():
-                            uid = uid_qs.values('uid__uid', 'uid__mac', 'uid__uid_extra', 'uid__full_uid_code')[0]
-                            res = {
-                                'full_uid_code': CommonService.encode_data(uid['uid__full_uid_code']),
-                                'uid': CommonService.encode_data(uid['uid__uid']),
-                                'mac': CommonService.encode_data(uid['uid__mac']),
-                                'extra': uid['uid__uid_extra']
-                            }
-                            return response.json(0, res)
-                        else:
+            if company_serial.status == 0:  # 该序列号未绑定企业
+                return response.json(173)
+            elif company_serial.status == 1:    # 绑定uid
+                with transaction.atomic():
+                    count = 0
+                    while count < 3:
+                        # 查询是否存在未绑定序列号的uid
+                        uid_qs = UIDModel.objects.filter(vpg__company_id=company_serial.company.id,
+                                                         vpg__region_id=country_id, status=0, p2p_type=p2ptype). \
+                                                         order_by('id')
+                        if not uid_qs.exists():
                             return response.json(173)
-                except Exception as e:
-                    # print('--------------------------error 5000')
-                    # print(repr(e))
-                    if savePoint:
-                        transaction.rollback(savePoint)
-                    djangoLogger = logging.getLogger('django')
-                    djangoLogger.exception(repr(e))
-                    return response.json(176, str(e))
-            except Exception as e:
-                # print('--------------------------error 5001')
-                # print(repr(e))
-                djangoLogger = logging.getLogger('django')
-                djangoLogger.exception(repr(e))
-                return response.json(176, str(e))
 
-        else:
-            return response.json(444)
+                        uid = uid_qs[0]
+
+                        if DeviceSubType:
+                            # 获取最新的mac,判断分配到哪里,且进行绑定
+                            mac = MacModel.objects.filter().values('id', 'value', 'is_active')[0]
+                            current_mac = mac['value']
+                            username = 'cspublic@ansjer.com'
+                            if current_mac[-8:] == '1F:42:40':  # 一组一共1048576个,此mac是第100w个时
+                                sys_msg_text = "当前国外uid管理系统mac地址已分配到" + current_mac + ",此mac地址是当前组的第100w个,还剩下48576个可分配,mac地址即将用完。"
+                                S3Email().faEmail(sys_msg_text, username)
+                            elif current_mac[-8:] == '1F:90:60':  # 此mac是第102w个时
+                                sys_msg_text = "当前国外uid管理系统mac地址已分配到" + current_mac + ",此mac地址是当前组的第102w个,还剩下28576个可分配,mac地址即将用完。"
+                                S3Email().faEmail(sys_msg_text, username)
+                            elif not mac['is_active']:
+                                return response.json(175)
+                            elif current_mac[-8:] == '1F:FF:FF':
+                                MacModel.objects.filter().update(is_active=False)  # 更改mac可使用的状态,当再此调用接口时使用上面条件进行阻止
+                                sys_msg_text = "当前国外uid管理系统mac地址已分配到" + current_mac + ",mac地址已分配使用完,请更换分组。"
+                                S3Email().faEmail(sys_msg_text, username)
+                                return response.json(175)
+                            UIDModel.objects.filter(id=uid.id).update(mac=current_mac)  # 更新绑定uid的mac值
+                            # 绑定mac地址成功后更新mac表
+                            temp_mac = CommonService.updateMac(current_mac)  # mac地址值+1;后3个字节为FF时返回None
+                            if temp_mac:
+                                current_mac = temp_mac  # 更新赋值写入uid表
+                            else:
+                                temp_mac = current_mac  # 赋值为FF写入mac表
+                            MacModel.objects.filter().update(value=temp_mac, add_time=now_time,
+                                                             update_time=now_time)  # 更新mac表的mac地址值
+
+                        result = UIDModel.objects.filter(id=uid.id, status=0).\
+                            update(status=2, update_time=now_time)
+
+                        if int(result) <= 0:    # 更新失败
+                            count += 1
+                            continue
+
+                        # UID关联【企业关联序列号】表创建数据
+                        UIDCompanySerialModel.objects.create(uid_id=uid.id, company_serial_id=company_serial.id,
+                                                             add_time=now_time, update_time=now_time)
+
+                        company_serial.status = 2
+                        company_serial.save()
+
+                        dev = Device_Info.objects.filter(UID=uid.uid)
+                        if dev.exists():
+                            dev.update(serial_number=full_serial)
+
+                        full_uid_code = uid.full_uid_code
+                        if uid.platform in CRCKey.keys():
+                            full_uid_code += ':'+CRCKey[uid.platform]
+
+                        res = {
+                            'full_uid_code': CommonService.encode_data(full_uid_code),
+                            'uid': CommonService.encode_data(uid.uid),
+                            'mac': CommonService.encode_data(uid.mac),
+                            'extra': uid.uid_extra,
+                            'platform': uid.platform,
+                            'initString': uid.init_string,
+                            'initStringApp': uid.init_string_app,
+                        }
+
+                        # 记录操作日志
+                        ip = CommonService.get_ip_address(request)
+                        content = json.loads(json.dumps(request_dict))
+                        log = {
+                            'ip': ip,
+                            'user_id': 1,
+                            'status': 200,
+                            'time': now_time,
+                            'content': json.dumps(content),
+                            'url': 'serialNumber/attachUID',
+                            'operation': '序列号{}绑定uid: {}'.format(serial, uid.uid),
+                        }
+                        LogModel.objects.create(**log)
+                        return response.json(0, res)
+
+                    return response.json(5)
+            else:   # 返回uid
+                uid_qs = UIDCompanySerialModel.objects.filter(company_serial_id=company_serial.id)
+                if not uid_qs.exists():
+                    return response.json(173)
+                uid = uid_qs.values('uid__uid', 'uid__mac', 'uid__uid_extra', 'uid__full_uid_code',
+                                    'uid__platform', 'uid__init_string', 'uid__init_string_app')[0]
+                full_uid_code = uid['uid__full_uid_code']
+                if uid['uid__platform'] in CRCKey.keys():
+                    full_uid_code += ':'+CRCKey[uid['uid__platform']]
+                res = {
+                    'full_uid_code': CommonService.encode_data(full_uid_code),
+                    'uid': CommonService.encode_data(uid['uid__uid']),
+                    'mac': CommonService.encode_data(uid['uid__mac']),
+                    'extra': uid['uid__uid_extra'],
+                    'platform': uid['uid__platform'],
+                    'initString': uid['uid__init_string'],
+                    'initStringApp': uid['uid__init_string_app'],
+                }
+                return response.json(0, res)
+        except Exception as e:
+            djangoLogger = logging.getLogger('django')
+            djangoLogger.exception(repr(e))
+            return response.json(176, str(e))
 
     def do_get_uid(self, request_dict, response):
         serial_number = request_dict.get('serial_number', None)
         token = request_dict.get('token', None)
         time_stamp = request_dict.get('time_stamp', None)
 
-        if token and time_stamp and serial_number and len(serial_number) == 9:
+        if token and time_stamp and serial_number :
 
             token = int(CommonService.decode_data(token))
             time_stamp = int(time_stamp)
@@ -313,12 +292,13 @@ class SerialNumberView(View):
             now_time = int(time.time())
             distance = now_time - time_stamp
 
-            if token != time_stamp or distance > 60000 or distance < -60000:  #为了全球化时间控制在一天内
+            if token != time_stamp or distance > 60000 or distance < -60000:  # 为了全球化时间控制在一天内
                 return response.json(404)
 
             mark = serial_number[6:9]
             serial = serial_number[0:6]
-            uid_company_serial_qs = UIDCompanySerialModel.objects.filter(company_serial__company__mark=mark, company_serial__serial_number__serial_number=serial)
+            uid_company_serial_qs = UIDCompanySerialModel.objects.filter(company_serial__company__mark=mark,
+                                                                         company_serial__serial_number__serial_number=serial)
 
             if uid_company_serial_qs.exists():
                 uid = uid_company_serial_qs.values('uid__uid', 'uid__mac', 'uid__uid_extra')[0]
@@ -328,60 +308,80 @@ class SerialNumberView(View):
                     'mac': CommonService.encode_data(uid['uid__mac']),
                     'extra': uid['uid__uid_extra']
                 }
-
                 return response.json(0, res)
             else:
                 return response.json(173)
         else:
             return response.json(444)
 
-    def do_detach_uid(self, request_dict, response):
-        serial_number = request_dict.get('serial_number', None)
+    def do_detach_uid(self, request, request_dict, response):
         token = request_dict.get('token', None)
         time_stamp = request_dict.get('time_stamp', None)
+        serial_number = request_dict.get('serial_number', None)
 
-        if token and time_stamp and serial_number:
-            token = int(CommonService.decode_data(token))
-            time_stamp = int(time_stamp)
-
-            now_time = int(time.time())
-            distance = now_time - time_stamp
+        if not all([token, time_stamp, serial_number]):
+            return response.json(444)
+        token = int(CommonService.decode_data(token))
+        time_stamp = int(time_stamp)
 
-            if token != time_stamp or distance > 60000 or distance < -60000:  # 为了全球化时间控制在一天内
-                return response.json(404)
+        now_time = int(time.time())
+        distance = now_time - time_stamp
 
-            serial = serial_number[0:6]
+        if token != time_stamp or distance > 60000 or distance < -60000:  # 为了全球化时间控制在一天内
+            return response.json(404)
 
-            uid_serial_qs = UIDCompanySerialModel.objects.filter(company_serial__serial_number=serial)
-            if uid_serial_qs.exists():
-                uid_serial = uid_serial_qs[0]
+        serial = serial_number[0:6]
+        uid_serial_qs = UIDCompanySerialModel.objects.filter(company_serial__serial_number=serial)
+        if not uid_serial_qs.exists():
+            return response.json(173)
+        uid_serial = uid_serial_qs[0]
 
-                #iot = iotdeviceInfoModel.objects.filter(serial_number__serial_number=serial)
-                iot = iotdeviceInfoModel.objects.filter(thing_name="Ansjer_Device_" + serial_number)
+        try:
+            with transaction.atomic():
+                # 删除iot设备信息表数据
+                iot = iotdeviceInfoModel.objects.filter(serial_number=serial)
                 if iot.exists():
                     iot.delete()
 
+                uid = uid_serial.uid.uid
                 company_serial_qs = CompanySerialModel.objects.filter(id=uid_serial.company_serial.id)
                 if company_serial_qs.exists():
                     company_serial = company_serial_qs[0]
                     company_serial.status = 1
                     company_serial.save()
+                    dv_qs = Device_Info.objects.filter(UID=uid)
+                    if dv_qs.exists():
+                        # 删除设备
+                        dv_qs.delete()
+                        # 删除设备影子信息uid_set   外键关联删除设备推送配置信息 uid_push
+                        up_qs = UidPushModel.objects.filter(uid_set__uid=uid)
+                        # DetectControllerView().do_delete_redis(uid)
+                        if up_qs.count() > 1:
+                            UidPushModel.objects.filter(uid_set__uid=uid).delete()
+                        else:
+                            up_qs.delete()
 
-                uid_qs = UIDModel.objects.filter(uid=uid_serial.uid.uid)
-                if uid_qs.exists():
-                    uid = uid_qs[0]
-                    uid.status = 0
-                    uid.save()
+                UIDModel.objects.filter(uid=uid).update(status=0, mac='')    # 重置uid的使用状态为未分配
                 uid_serial.delete()
 
-                dev = Device_Info.objects.filter(serial_number=serial_number)
-                if dev.exists():
-                    dev.update(serial_number='')
-                return response.json(0)
-            else:
-                return response.json(173)
-        else:
-            return response.json(444)
+                # 记录操作日志
+                ip = CommonService.get_ip_address(request)
+                content = json.loads(json.dumps(request_dict))
+                log = {
+                    'ip': ip,
+                    'user_id': 1,
+                    'status': 200,
+                    'time': now_time,
+                    'content': json.dumps(content),
+                    'url': 'serialNumber/detachUID',
+                    'operation': '序列号{}解绑uid: {}'.format(serial, uid),
+                }
+                LogModel.objects.create(**log)
+            return response.json(0)
+        except Exception as e:
+            djangoLogger = logging.getLogger('django')
+            djangoLogger.exception(repr(e))
+            return response.json(176, str(e))
 
     def do_update(self, userID, request_dict, response):
         # perm = ModelService.check_perm_uid_manage(userID, 0)
@@ -390,14 +390,13 @@ class SerialNumberView(View):
 
         id = request_dict.get('id', None)
         status = request_dict.get('status', None)
-        p2p = request_dict.get('p2p', None)
 
         if id and status:
             serial_number_qs = SerialNumberModel.objects.filter(id=id)
             if serial_number_qs.exists():
-                serial_number_qs.update(**{'status': status, 'p2p': p2p})
+                serial_number_qs.update(**{'status': status})
                 return response.json(0)
             else:
                 return response.json(173)
         else:
-            return response.json(444)
+            return response.json(444)

+ 3 - 1
Controller/ShadowController.py

@@ -102,7 +102,7 @@ def update_device_shadow(request):
         is_human = request_dict.get('is_human', None)
         is_custom_voice = request_dict.get('is_custom', None)
         double_wifi = request_dict.get('double_wifi', None)
-
+        is_ptz = request_dict.get('is_ptz', None)
         us_qs = UidSetModel.objects.filter(uid=uid)
         # 更新
         nowTime = int(time.time())
@@ -138,6 +138,8 @@ def update_device_shadow(request):
             qs_dict['is_custom_voice'] = is_custom_voice
         if double_wifi:
             qs_dict['double_wifi'] = double_wifi
+        if is_ptz:
+            qs_dict['is_ptz'] = is_ptz
         if us_qs.exists():
             if is_alexa and us_qs[0].is_alexa == 0:
                 qs_dict['is_alexa'] = is_alexa

+ 71 - 45
Controller/TestApi.py

@@ -11,6 +11,7 @@
 @file: Test.py
 @Contact: chanjunkai@163.com
 """
+import botocore
 from django.db import transaction
 from django.views.generic.base import View
 import os
@@ -24,6 +25,7 @@ import time
 import urllib
 import datetime
 from Object.AliPayObject import AliPayObject
+import logging
 import boto3
 from boto3.session import Session
 from botocore.exceptions import ClientError
@@ -39,9 +41,10 @@ from django.http import JsonResponse, HttpResponseRedirect, HttpResponse
 from django.utils.decorators import method_decorator
 from django.views.decorators.csrf import csrf_exempt
 from django.views.generic.base import View
+from Object.RedisObject import RedisObject
 from django.contrib.auth.hashers import make_password, check_password  # 对密码加密模块
 from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, OSS_ROLE_ARN, SERVER_DOMAIN, PAYPAL_CRD, \
-    SERVER_DOMAIN_SSL
+    SERVER_DOMAIN_SSL, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY
 from Model.models import Device_Info, Order_Model, Store_Meal, VodHlsModel, OssCrdModel, UID_Bucket, CompanySerialModel, \
     SerialNumberModel, CompanyModel, VPGModel, Unused_Uid_Meal, StsCrdModel, ExperienceContextModel
 from Object.ResponseObject import ResponseObject
@@ -76,6 +79,12 @@ class testView(View):
         operation = kwargs.get('operation')
         return self.validation(request.POST, request, operation)
 
+    def put(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        response = ResponseObject()
+        return response.json(0,request.body)
+
     def validation(self, request_dict, request, operation):
         response = ResponseObject()
         # operation => cloudVod/path
@@ -86,6 +95,15 @@ class testView(View):
             logger.info('测试打印')
             res = make_password(123456)
             return JsonResponse(status=200, data=res,safe=False)
+        elif operation == 'testMiddleWare':
+            a = int('a')
+            return JsonResponse(status=200, safe=False)
+        elif operation == 'testMiddleWare2':
+            try:
+                a = int('a')
+                return JsonResponse(status=200, safe=False)
+            except Exception as e:
+                return response.json(500, repr(e))
         elif operation == 'cbu':
             return self.createBucket()
         elif operation == 'vodList':
@@ -108,10 +126,10 @@ class testView(View):
             return self.generate_token(request_dict,userID)
         elif operation == 'test_upload_s3':
             userID = '158943604783713800138000'
-            return self.test_upload_s3(request_dict)
-        elif operation == 'test_request':
+            return self.test_upload_s3(request_dict, response)
+        elif operation == 'rekognition':
             userID = '158943604783713800138000'
-            return self.testRequest(request,request_dict)
+            return self.testRekognition(request,request_dict)
         elif operation == 'deleteDevice':
             return self.delete_device(response)
         else:
@@ -703,47 +721,55 @@ class testView(View):
         return JsonResponse(status=200, data=res,safe=False)
 
 
-    def test_upload_s3(self,request_dict):
-        res = CompanyModel.objects.filter(id=3).delete()
-        exit(res)
-
-        testd = hmac.new('AWS4rf/xnQ3jIgY8bj7Sz4An4KbYct2sq2MbrfmP8rVV'.encode("utf-8"), '20210223'.encode("utf-8"), hashlib.sha256).digest()
-        region_sign = hmac.new(testd, 'cn-northwest-1'.encode("utf-8"), hashlib.sha256).hexdigest()
-        exit(region_sign)
-        kService = sign(kRegion, 's3')
-        kSigning = sign(kService, 'aws4_request')
-
-        # exit(CommonService.getIpIpInfo("120.197.196.156",'CN'))
-        aws_key = "ASIA2MMWBR4DUPTFDTOJ" #【你的 aws_access_key】
-        aws_secret = "tTFZ9wpxFadeufhfaJ1erErv4U1bJ+TS/SJwTptx" #【你的 aws_access_key】
-        aws_session_token = "IQoJb3JpZ2luX2VjEJT//////////wEaDmNuLW5vcnRod2VzdC0xIkYwRAIgenLaMN6NdFji0x18OuaUTPvvtRBAWwjdEYdBTCMh0ywCIEzntAbgRPmwS+YFuNg+F31z60I4J1IoqmrQHR7wmPzVKtsCCML//////////wEQABoMNzEzODE2MTE2OTk5IgyJTmdtNJ319TtNORAqrwLPG6Px0z5CsEQpFt/TCbSSMRtYqBU+x5Ll9hZIuTvg8H+56H02/cr0nSCNiy05z7dSrSWMFoMhVKvHq7as5TRvVXkvMbbYPQuQxxPFr7EswaB+XITeDpdGBI6N7mqnt6h4YJbhk2dNRa2/4Ypr1DuyGnhVV6NxNHA5INtY7apLi3UTcNKwKSQRVzUWZBpoj86wG3j77KOZg18I9P8UWBpA9fpz/Wiv4xrzZSexrUnq5svTLEqMfTYCPBXkxrJBjNrwVjvkBkgeIfQZPz+A5X97p7wXbPf0Jo5aHHRDefbAmBuXYoSfpHjiFWindkcvCaMxQzUiHVLvnN/5SvgQEzN3pLUAAioepRZIZQLaky1aRmYYm1wOCjzgsg9V+GV6gKTE+ipFG/6Nv03Vh++Hv+YwyamJgQY6mgEmxhOhncek0PgQeExx2EXk73olY/6L15eDyHbSWoEKBMTmdlmpYD9Cj3qP4aUUW6UT6V5Tql/s5eBEsYwY+hzgtQiTmd7vjytXxae+dpN9VsWGW4AJ9P+/LgBe6zExUx2MOVst0+hb+dd8bg/qkz7UBYNQAmU+BEoL2Cd7lNXdrv56Gboapo+BosQO49GT8u1k5EheQ9JKHCqv"
-        session = Session(aws_access_key_id=aws_key,
-                          aws_secret_access_key=aws_secret,
-                          aws_session_token=aws_session_token,
-                          region_name="cn-northwest-1") # 此处根据自己的 s3 地区位置改变
-        s3 = session.resource("s3")
-        # client = session.client("s3")
-        bucket = "7cdk" # 【你 bucket 的名字】 # 首先需要保.证 s3 上已经存在该存储桶,否则报错
-        upload_data = open("./././static/log/test.log", "rb")
-        upload_key = "XKWZSC5FCJYT19B7111A/test/test6/test.log"
-        file_obj = s3.Bucket(bucket).put_object(Key=upload_key, Body=upload_data)
-        print('---------------------')
-        print(file_obj)
-        print(8/0)
-        exit()
-
-
-    def testRequest(self,request,request_dict):
-        ip = CommonService.get_ip_address(request)
-        ipInfo = CommonService.getIpIpInfo(ip,"CN")
-        # print(type(ipInfo))
-        # exit(ipInfo)
-        addr = CommonService.getAddr(ip)
-        dicts = {
-            'ipInfo':ipInfo,
-            'addr':addr,
-        }
-        return HttpResponse(json.dumps(dicts, ensure_ascii=False),
+    def test_upload_s3(self,request_dict , response):
+        aws_s3_guonei = boto3.client(
+            's3',
+            aws_access_key_id=AWS_ACCESS_KEY_ID[0],
+            aws_secret_access_key=AWS_SECRET_ACCESS_KEY[0],
+            config=botocore.client.Config(signature_version='s3v4'),
+            region_name='cn-northwest-1'
+        )
+        download_link = 'ipctest'
+        response_url = aws_s3_guonei.generate_presigned_url(
+            ClientMethod='put_object',
+            Params={
+                'Bucket': 'pc-package',
+                'Key': download_link
+            },
+            ExpiresIn=3600
+        )
+        return response.json(0, {'datas': response_url, 'count': 1})
+
+
+    def testRekognition(self,request,request_dict):
+        # ip = CommonService.get_ip_address(request)
+        # ipInfo = CommonService.getIpIpInfo(ip,"CN")
+        # # print(type(ipInfo))
+        # # exit(ipInfo)
+        # addr = CommonService.getAddr(ip)
+        # dicts = {
+        #     'ipInfo':ipInfo,
+        #     'addr':addr,
+        # }
+        # return HttpResponse(json.dumps(dicts, ensure_ascii=False),
+        #                     content_type="application/json,charset=utf-8")
+        # client = boto3.client('s3', aws_access_key_id='AKIA2E67UIMD45Y3HL53',aws_secret_access_key='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',region_name='us-east-1')
+        # exit(request.FILES)
+
+
+        files = request.FILES.get('image')
+        labels = int(request_dict.get('labels',5))
+        minConfidence = int(request_dict.get('minConfidence',99))
+        if not files:
+            return HttpResponse('请上传图片!!!!')
+        client = boto3.client('rekognition', aws_access_key_id='AKIA2E67UIMD6JD6TN3J',aws_secret_access_key='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',region_name='us-east-1')
+        # image = open('E:/photo/a615fa40b8c476bab0f6eeb332e62a5a-1000.jpg', "rb")
+        response = client.detect_labels(Image={'Bytes':files.read()},MaxLabels=labels,MinConfidence=minConfidence)
+        # for obj in response['Labels']:
+        #     exit(obj)
+        #     if obj['Name'] == 'Person':
+        #         jsonstr = json.dumps(obj)
+        return HttpResponse(json.dumps(response, ensure_ascii=False),
                             content_type="application/json,charset=utf-8")
 
     def delete_device(self, response):

+ 16 - 0
Controller/UIDController.py

@@ -66,6 +66,8 @@ class UIDView(View):
             return self.do_history(token.userID, request_dict, response)
         elif operation == 'statistics':
             return self.do_admin_statistics(token.userID, request_dict, response)
+        elif operation == 'queryInitString':
+            return self.query_init_string(token.userID, request_dict, response)
         else:
             return response.json(309)
 
@@ -487,3 +489,17 @@ class UIDView(View):
 
         return response.json(0, res)
 
+    def query_init_string(self, userID, request_dict, response):
+        uid = request_dict.get('uid', None)
+        if not uid:
+            return response.json(444)
+        uid_qs = UIDModel.objects.filter(uid=uid).values('platform', 'init_string', 'init_string_app')
+        if not uid_qs.exists():
+            return response.json(173)
+        res = {
+            'platform': uid_qs[0]['platform'],
+            'initString': uid_qs[0]['init_string'],
+            'initStringApp': uid_qs[0]['init_string_app'],
+        }
+        return response.json(0, res)
+

+ 2 - 0
Controller/UidSetController.py

@@ -11,9 +11,11 @@
 @file: AliPayObject.py
 @Contact: pzb3076@163.com
 """
+import threading
 import time
 import traceback
 
+import requests
 from django.db.models import Count
 
 from Object.RedisObject import RedisObject

+ 3 - 1
Controller/UidUser.py

@@ -61,7 +61,9 @@ def addInterface(request):
         if tko.code == 0:
             userID = tko.userID
             re_uid = re.compile(r'^[A-Za-z0-9]{20}$')
-            if re_uid.match(UID):
+            sy_uid = re.compile(r'^[A-Za-z0-9]{14}$')
+            sy_uid23 = re.compile(r'^[A-Za-z0-9]{23}$')
+            if re_uid.match(UID) or sy_uid.match(UID) or sy_uid23.match(UID):
                 is_ap = int(is_ap)
                 is_exist = UidUserModel.objects.filter(UID=UID, userID_id=userID, is_ap=is_ap)
                 if is_exist:

+ 136 - 31
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
+    UserAppFrequencyModel, CountryIPModel, CountryModel, UidChannelSetModel
 from Object.AWS.SesClassObject import SesClassObject
 from Object.AliSmsObject import AliSmsObject
 from Object.RedisObject import RedisObject
@@ -560,15 +560,15 @@ class EmailResetPwdView(TemplateView):
                     is_update = user_qs.update(password=make_password(reset_pwd))
                     if is_update:
                         return HttpResponseRedirect(
-                            "http://www.dvema.com/web/html/paw_update_success.html?code=" + reset_pwd)
+                            "http://www.zositechc.cn/web/html/paw_update_success.html?code=" + reset_pwd)
                     else:
                         return response.json(10)
                 else:
                     return response.json(104)
             else:
-                return HttpResponseRedirect('http://www.dvema.com/web/html/paw_update_unsuccessful.html?lang=en')
+                return HttpResponseRedirect('http://www.zositechc.cn/web/html/paw_update_unsuccessful.html?lang=en')
         else:
-            return HttpResponseRedirect('http://www.dvema.com/web/html/paw_update_unsuccessful.html?lang=en')
+            return HttpResponseRedirect('http://www.zositechc.cn/web/html/paw_update_unsuccessful.html?lang=en')
 
 
 class refreshTokenView(TemplateView):
@@ -789,8 +789,8 @@ class v2authCodeView(TemplateView):
             msg = res["Message"]
             if code == "isv.MOBILE_NUMBER_ILLEGAL":
                 if response.lang == "cn":
-                    msg = phone + "非法手机"
-            return response.json(10, msg)
+                    msg = phone+"非法手机"
+            return response.json(10,msg)
 
     def phoneCodeV2(self, country_code, phone, response, sign_name):
         dataValid = DataValid()
@@ -1700,6 +1700,97 @@ class v2LoginView(TemplateView):
             return response.json(tko.code)
 
 
+# 登录
+class noPasslogin(TemplateView):
+    @method_decorator(csrf_exempt)  # @csrf_exempt
+    def dispatch(self, *args, **kwargs):
+        return super(noPasslogin, self).dispatch(*args, **kwargs)
+
+    @ratelimit(key='ip', rate='5/m')
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.POST
+        language = request_dict.get('language', 'en')
+        response = ResponseObject(language)
+        was_limited = getattr(request, 'limited', False)
+        if was_limited is True:
+            return response.json(5)
+        return self.validates(request_dict, response)
+
+    # @ratelimit(key='ip', rate='5/m')
+    def get(self, request, *args, **kwargs):
+        print("进来了")
+        request.encoding = 'utf-8'
+        request_dict = request.GET
+        language = request_dict.get('language', 'en')
+        response = ResponseObject(language)
+        was_limited = getattr(request, 'limited', False)
+        if was_limited is True:
+            return response.json(5)
+        return self.validates(request_dict, response)
+
+    def validates(self, request_dict, response):
+        username = request_dict.get('userName', None)
+        if not username:
+            return response.json(111)
+        username = username.strip()
+        data_valid = DataValid()
+        if data_valid.email_validate(username):
+            return self.do_email_login(username, response)
+        elif data_valid.mobile_validate(username):
+            return self.do_phone_login(username, response)
+        elif data_valid.name_validate(username):
+            return self.do_name_login(username, response)
+        else:
+            return response.json(107)
+
+    def do_email_login(self, email, response):
+        user_qs = Device_User.objects.filter(Q(username=email) | Q(userEmail=email))
+        return self.valid_login(user_qs, response)
+
+    def do_phone_login(self, phone, response):
+        user_qs = Device_User.objects.filter(Q(phone=phone) | Q(username=phone), is_active=True, user_isValid=True)
+        return self.valid_login(user_qs, response)
+
+    def do_name_login(self, username, response):
+        user_qs = Device_User.objects.filter(Q(username=username) | Q(phone=username) | Q(userEmail=username),
+                                             is_active=True, user_isValid=True)
+        return self.valid_login(user_qs, response)
+
+    def valid_login(self, user_qs, response):
+        if not user_qs.exists():
+            return response.json(104)
+        # users = user_qs.values('role__rid', 'role__roleName', 'userID', 'role', 'NickName', 'username', 'userEmail',
+        #                        'phone', 'password', 'userIconPath', 'user_isValid', 'is_active')[0]
+        users = user_qs.values('role__rid', 'role__roleName', 'userID', 'NickName', 'username', 'userEmail',
+                               'phone', 'password', 'userIconPath')[0]
+        userID = users['userID']
+        tko = TokenObject()
+        res = tko.generate(
+            data={'userID': userID, 'lang': response.lang, 'user': users['username'], 'm_code': '123413243214'})
+        if tko.code == 0:
+            now_time = datetime.datetime.utcnow().replace(tzinfo=utc).astimezone(utc)
+            user_qs.update(last_login=now_time, language=response.lang)
+            res['rid'] = users['role__rid']
+            res['roleName'] = users['role__roleName']
+            res['permList'] = ModelService.own_permission(userID)
+            res['userID'] = userID
+            # 昵称,邮箱,电话,刷新,头像
+            userIconPath = str(users['userIconPath'])
+            if userIconPath and userIconPath.find('static/') != -1:
+                userIconPath = userIconPath.replace('static/', '').replace('\\', '/')
+                res['userIconUrl'] = SERVER_DOMAIN + 'account/getAvatar/' + userIconPath
+            else:
+                res['userIconUrl'] = ''
+            res['NickName'] = users['NickName'] if users['NickName'] is not None else ''
+            res['username'] = users['username'] if users['username'] is not None else ''
+            res['userEmail'] = users['userEmail'] if users['userEmail'] is not None else ''
+            res['phone'] = users['phone'] if users['phone'] is not None else ''
+            return response.json(0, res)
+        else:
+            return response.json(tko.code)
+
+
 # 密码加密新登录
 class v3LoginView(TemplateView):
     @method_decorator(csrf_exempt)  # @csrf_exempt
@@ -2744,32 +2835,46 @@ class alexaUidView(TemplateView):
         if not uid_qs.exists():
             return response.json(107)
 
-        uid_dict = {}
-        uid_list = []
-        for uid_q in uid_qs:
-            # 追加
-            uid_list.append(uid_q['UID'])
-            # 给uid_q['UID']赋值
-            uid_dict[uid_q['UID']] = {'nick': uid_q['NickName'], 'password': uid_q['View_Password']}
-
-        us_qs = UidSetModel.objects.filter(uid__in=uid_list, is_alexa=1).values('uid', 'region_alexa')
-        if not us_qs.exists():
-            return response.json(173)
-        # uid,password,region的列表
-        uid_arr = []
-        for us in us_qs:
-            uid = us['uid']
-            # 设备alexa区域
-            region_alexa = us['region_alexa']
-            if region_alexa == '':
-                region_alexa = 'EN'
-            uid_arr.append({'uid': uid, 'nick': uid_dict[uid]['nick'], 'password': uid_dict[uid]['password'],
-                            'region': region_alexa})
-        res = {
-            'uid_arr': uid_arr
-        }
-        return response.json(0, res)
+        try:
+            uid_dict = {}
+            uid_list = []
+            for uid_q in uid_qs:
+                # 追加
+                uid_list.append(uid_q['UID'])
+                # 给uid_q['UID']赋值
+                uid_dict[uid_q['UID']] = {'nick': uid_q['NickName'], 'password': uid_q['View_Password']}
 
+            us_qs = UidSetModel.objects.filter(uid__in=uid_list, is_alexa=1).values('id', 'uid', 'region_alexa', 'channel')
+            if not us_qs.exists():
+                return response.json(173)
+            # uid,password,region的列表
+            uid_arr = []
+            for us in us_qs:
+                uid = us['uid']
+                channel = us['channel']
+                # 设备alexa区域
+                region_alexa = us['region_alexa']
+                if region_alexa == '':
+                    region_alexa = 'EN'
+
+                # 多通道设备获取通道名
+                if channel > 1:
+                    uid_channel_set_qs = UidChannelSetModel.objects.filter(uid_id=us['id']).values('channel', 'channel_name')
+                    if uid_channel_set_qs.exists():
+                        # DVR设备名为 UidChannelSetModel 的 channel_name
+                        for uid_channel_set in uid_channel_set_qs:
+                            uid_arr.append({'uid': uid, 'nick': uid_channel_set['channel_name'], 'region': region_alexa,
+                                            'password': uid_dict[uid]['password'], 'multi_channel': 1,
+                                            'channel': uid_channel_set['channel']})
+                else:
+                    uid_arr.append({'uid': uid, 'nick': uid_dict[uid]['nick'], 'region': region_alexa,
+                                    'password': uid_dict[uid]['password'], 'multi_channel': 0})
+            res = {
+                'uid_arr': uid_arr
+            }
+            return response.json(0, res)
+        except Exception as e:
+            return response.json(500, repr(e))
 
 # 登出
 class V2LogoutView(TemplateView):

+ 59 - 44
Controller/UserManger.py

@@ -1,8 +1,12 @@
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
+import logging
 import os
 import traceback
 
+import boto3
+import botocore
+from botocore import client
 import simplejson as json
 from django.core.files.storage import FileSystemStorage
 from django.http import HttpResponse
@@ -10,7 +14,7 @@ from django.utils.decorators import method_decorator
 from django.views.decorators.csrf import csrf_exempt
 from django.views.generic import TemplateView, View
 
-from Ansjer.config import BASE_DIR
+from Ansjer.config import BASE_DIR, SERVER_TYPE, ACCESS_KEY_ID, SECRET_ACCESS_KEY, REGION_NAME, AVATAR_BUCKET
 from Ansjer.config import SERVER_DOMAIN
 from Model.models import Role, Device_User, UserOauth2Model, UserExModel
 from Object.RedisObject import RedisObject
@@ -101,32 +105,33 @@ class perfectUserInfoView(TemplateView):
         userID = tko.userID
         if not userID:
             return response.json(309)
-        if userIcon != None:
-            location = 'static/User/Images/' + userID + '/'
-            fss = FileSystemStorage(location=location)
-            if fss.exists(userIcon.name):
-                fss.delete(userIcon.name)
-            filename = fss.save(userIcon.name, userIcon)
-            # userIconUrl = fss.url(filename)
-            userIconPath = fss.path(filename).replace('\\', '/')
-        else:
-            userIconPath = None
-        if userContent != None:
+        userIconPath = ''
+        if userIcon:
+            # 上传头像到aws s3
+            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'),
+            )
+            Key = userID + '/' + userIcon.name
+            aws_s3_client.put_object(Bucket=AVATAR_BUCKET, Key=Key, Body=userIcon)
+            userIconPath = userID + '/' + userIcon.name
+        if userContent:
             dataValid = json.loads(userContent)
             if 'userID' and 'password' and 'is_superuser' in dataValid.keys():
                 return response.json(444)
-        if userIconPath == None and userContent == None:
+        if not userIconPath and not userContent:
             return response.json(444)
-        elif userIconPath == None and userContent != None:
+        elif not userIconPath and userContent:
             return self.perfectUserInfoUpdate(userID, response, userContent=userContent)
-        elif userIconPath != None and userContent == None:
+        elif userIconPath and not userContent:
             return self.perfectUserInfoUpdate(userID, response, userIconPath=userIconPath)
         else:
-            return self.perfectUserInfoUpdate(userID, response, userIconPath=userIconPath,
-                                              userContent=userContent)
+            return self.perfectUserInfoUpdate(userID, response, userIconPath=userIconPath, userContent=userContent)
 
-    def perfectUserInfoUpdate(slef, userID, response, *args,
-                              **kwargs):
+    def perfectUserInfoUpdate(slef, userID, response, **kwargs):
         """
         :param username:
         :param userContent:
@@ -139,24 +144,21 @@ class perfectUserInfoView(TemplateView):
             return response.json(104)
         userIconPath = kwargs.get('userIconPath', None)
         userContent = kwargs.get('userContent', None)
-        if userIconPath is not None:
-            userIconPath = userIconPath[userIconPath.find('static/'):]
-            userIconUrl = SERVER_DOMAIN + 'account/getAvatar/' + userIconPath[7:]
-        if userContent != None:
+        if userIconPath:
+            userIconUrl = SERVER_DOMAIN + 'account/getAvatar/' + userIconPath
+        if userContent:
             try:
                 UserData = json.loads(userContent)
             except Exception as e:
                 return response.json(444, repr(e))
         try:
-            if userIconPath is not None and userContent is not None:
+            if userIconPath and userContent:
                 User.update(userIconPath=userIconPath, userIconUrl=userIconUrl, **UserData)
-            elif userIconPath is None and userContent is not None:
+            elif not userIconPath and userContent:
                 User.update(**UserData)
-            elif userIconPath is not None and userContent is None:
+            elif userIconPath and not userContent:
                 User.update(userIconPath=userIconPath, userIconUrl=userIconUrl)
         except Exception as e:
-            errorInfo = traceback.format_exc()
-            print('修改设备信息错误: %s ' % errorInfo)
             return response.json(117, repr(e))
         else:
             res = CommonService.qs_to_dict(User)
@@ -164,10 +166,7 @@ class perfectUserInfoView(TemplateView):
                 res['datas'][k]['fields'].pop('password')
                 userIconPath = res['datas'][k]['fields']['userIconPath']
                 if userIconPath:
-                    if userIconPath.find('static/') != -1:
-                        userIconPath = userIconPath.replace('static/', '').replace('\\', '/')
-                        userIconUrl = SERVER_DOMAIN + 'account/getAvatar/' + userIconPath
-                        res['datas'][k]['fields']['userIconUrl'] = userIconUrl
+                    res['datas'][k]['fields']['userIconUrl'] = userIconUrl
             return response.json(0, res)
 
 
@@ -190,28 +189,44 @@ class getAvatarView(TemplateView):
 
     def getAvatar(self, filePath):
         response = ResponseObject()
-        if filePath == '' or filePath == None:
+        if not filePath:
             return response.json(800)
+        if filePath == 'User/default.png' or filePath == 'User/defaultUser.png':
+            # 使用默认头像
+            try:
+                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'),
+                )
+                get_object_response = aws_s3_client.get_object(Bucket=AVATAR_BUCKET, Key='default/default.png')
+                return HttpResponse(get_object_response['Body'], content_type="image/jpeg")
+            except Exception as e:
+                print(e)
+                return response.json(500, repr(e))
+        
         fullPath = os.path.join(BASE_DIR, "static", filePath).replace('\\', '/')
-        defaultPath = os.path.join(BASE_DIR, "static", "User/default.png").replace('\\', '/')
         if os.path.isfile(fullPath):
             try:
-                Imagedata = open(fullPath, 'rb').read()
+                imageData = open(fullPath, 'rb').read()
+                return HttpResponse(imageData, content_type="image/jpeg")
             except Exception as e:
                 return response.json(906, repr(e))
-            else:
-                return HttpResponse(Imagedata, content_type="image/jpeg")
         else:
-            print('----------------')
-            print(defaultPath)
-            print('----------------')
             try:
-                Imagedata = open(defaultPath, 'rb').read()
+                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'),
+                )
+                get_object_response = aws_s3_client.get_object(Bucket=AVATAR_BUCKET, Key=filePath)
+                return HttpResponse(get_object_response['Body'], content_type="image/jpeg")
             except Exception as e:
                 return response.json(906, repr(e))
-            else:
-                return HttpResponse(Imagedata, content_type="image/jpeg")
-            # return response.json(907)
 
 
 @csrf_exempt

+ 40 - 15
Controller/VPGController.py

@@ -1,5 +1,6 @@
 #!/usr/bin/env python3
 # -*- coding: utf-8 -*-
+import json
 import os
 import re
 import time
@@ -9,7 +10,7 @@ from django.views import View
 from django.views.decorators.csrf import csrf_exempt
 
 from Ansjer.config import BASE_DIR
-from Model.models import RegionModel, CompanyModel, VPGModel, UIDModel, MacModel, UIDCompanySerialModel
+from Model.models import RegionModel, CompanyModel, VPGModel, UIDModel, MacModel, UIDCompanySerialModel, LogModel
 from Object.uidManageResponseObject import uidManageResponseObject
 from Object.TokenObject import TokenObject
 from Service.CommonService import CommonService
@@ -181,7 +182,7 @@ class VPGView(View):
 
         start = (page - 1) * line
         end = start + line
-        uid_qs = UIDModel.objects.filter(vpg_id=vpg_id).values('uid')
+        uid_qs = UIDModel.objects.filter(vpg_id=vpg_id).values('uid', 'p2p_type', 'platform', 'init_string', 'init_string_app')
 
         count = VPGModel.objects.get(id=vpg_id).uid_count   # 从vpg表获取uid总数
         uid_qs = uid_qs[start:end]  # 显示条数
@@ -209,14 +210,21 @@ def do_upload_uid(request):
         return response.json(444)
     file = request.FILES.get('file', None)
     vpg_id = request_dict.get('vpg_id', None)
+    platform = request_dict.get('platform', '')
+    init_string = request_dict.get('init_string', '')
+    init_string_app = request_dict.get('init_string_app', '')
+
+    if not vpg_id:
+        return response.json(444)
 
     bulk = []
     add_time = update_time = int(time.time())
-    MAC = MacModel.objects.filter().values('id', 'value', 'is_active')[0]   # 获取最新可用的mac
-    current_mac = MAC['value']
-    if (not MAC['is_active']) or (current_mac[-8:] == 'FF.FF.FF'):
-        return response.json(175)
+    # MAC = MacModel.objects.filter().values('id', 'value', 'is_active')[0]   # 获取最新可用的mac
+    # current_mac = MAC['value']
+    # if (not MAC['is_active']) or (current_mac[-8:] == 'FF.FF.FF'):
+    #     return response.json(175)
 
+    area = 1 if vpg_id != '1' else 0
     # path = '/'.join((BASE_DIR, 'static/uid')).replace('\\', '/') + '/'
     # if not os.path.exists(path):
     #     os.makedirs(path)
@@ -232,13 +240,16 @@ def do_upload_uid(request):
             uid_list = re.findall("b\'(.*)\'", str(chunk))[0].split('\\r\\n')
             for uid in uid_list:
                 UID = UIDModel(
-                    mac=current_mac,
+                    mac='',
                     uid_extra='',
                     status=0,
                     add_time=add_time,
                     update_time=update_time,
-                    area=0,  # 关联vgp表已有区域信息,可以考虑去掉
+                    area=area,  # 关联vgp表已有区域信息,可以考虑去掉
                     vpg_id=vpg_id,
+                    platform=platform,
+                    init_string=init_string,
+                    init_string_app=init_string_app
                 )
                 if len(uid) == 14:  # 宸云
                     UID.p2p_type = 1
@@ -253,17 +264,31 @@ def do_upload_uid(request):
                     UID.uid = new_uid
                     UID.full_uid_code = uid
                 bulk.append(UID)
-                temp_mac = CommonService.updateMac(current_mac)    # mac地址值+1;后3个字节为FF时返回None
-                if temp_mac:
-                    current_mac = temp_mac  # 更新赋值写入uid表
-                else:
-                    temp_mac = current_mac  # 赋值为FF写入mac表
-                    break
+                # temp_mac = CommonService.updateMac(current_mac)    # mac地址值+1;后3个字节为FF时返回None
+                # if temp_mac:
+                #     current_mac = temp_mac  # 更新赋值写入uid表
+                # else:
+                #     temp_mac = current_mac  # 赋值为FF写入mac表
+                #     break
+
+        ip = CommonService.get_ip_address(request)
+        content = json.loads(json.dumps(request_dict))
+        log = {
+            'ip': ip,
+            'user_id': 1,
+            'status': 200,
+            'time': add_time,
+            'url': 'vpgUid/uid',
+            'content': json.dumps(content),
+            'operation': '上传{}个uid到VPG ID {}'.format(len(uid_list), vpg_id),
+        }
+        
         with transaction.atomic():
+            LogModel.objects.create(**log)  # 记录操作日志
             UIDModel.objects.bulk_create(bulk)  # 批量写入uid数据
             uid_count = UIDModel.objects.filter(vpg_id=vpg_id).count()  # 获取族群下uid的数量
             VPGModel.objects.filter(id=vpg_id).update(uid_count=uid_count)   # 更新vgp表的uid_count
-            MacModel.objects.filter().update(value=temp_mac)  # 更新mac表的mac地址值
+            # MacModel.objects.filter().update(value=temp_mac)  # 更新mac表的mac地址值
         return response.json(0)
     except Exception as e:
         print(e)

+ 22 - 15
Controller/VoicePromptController.py

@@ -139,24 +139,31 @@ class VoicePromptView(View):
 
     def do_delete(self, userID, request_dict, response):
         id = request_dict.get('id', None)
+        ids = request_dict.get('ids', None)
         if id:
             voice_qs = VoicePromptModel.objects.filter(id=id)
-            if voice_qs.exists():
-                uid = voice_qs[0].uid
-                device_qs = Device_Info.objects.filter(UID=uid, userID=userID)
-                if device_qs.exists():
-                    channel = voice_qs[0].channel
-                    filename = voice_qs[0].filename
-                    voice_qs.delete()
-                    auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
-                    bucket = oss2.Bucket(auth, 'http://oss-cn-shenzhen.aliyuncs.com', 'ansjer-static-resources')
-                    obj = 'voice_prompt/{uid}/{channel}/'.format(uid=uid, channel=channel) + filename
-                    bucket.delete_object(obj)
-                    return response.json(0)
-                else:
-                    return response.json(404)
+        elif ids:
+            voice_qs = VoicePromptModel.objects.filter(id__in=ids.split(','))
+
+
+        if not voice_qs.exists():
+            return response.json(14)
+
+        for voice in voice_qs:
+            uid = voice.uid
+            device_qs = Device_Info.objects.filter(UID=uid, userID=userID)
+            if device_qs.exists():
+                channel = voice.channel
+                filename = voice.filename
+                voice_qs.delete()
+                auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
+                bucket = oss2.Bucket(auth, 'http://oss-cn-shenzhen.aliyuncs.com', 'ansjer-static-resources')
+                obj = 'voice_prompt/{uid}/{channel}/'.format(uid=uid, channel=channel) + filename
+                bucket.delete_object(obj)
+                return response.json(0)
             else:
-                return response.json(173)
+                return response.json(404)
+
         else:
             return response.json(444)
 

+ 0 - 0
Ansjer/formal_statistics_push_day_task.py → CrontabTask/formal_statistics_push_day_task.py


+ 0 - 0
Ansjer/formal_statistics_push_month_task.py → CrontabTask/formal_statistics_push_month_task.py


+ 0 - 0
Ansjer/formal_zositech_help_weekly_task.py → CrontabTask/formal_zositech_help_weekly_task.py


+ 6 - 2
Ansjer/test_statistics_push_day_task.py → CrontabTask/test_statistics_push_day_task.py

@@ -1,10 +1,14 @@
 import json
 
 import requests
+from Ansjer.config import SERVER_TYPE
 
+base_url = ''
+if SERVER_TYPE == "Ansjer.us_config.test_settings":
+    base_url = 'http://test.dvema.com/'
+elif SERVER_TYPE == "Ansjer.cn_config.test_settings":
+    base_url = 'http://http://test.zositechc.cn/'
 
-# url = 'http://test.dvema.com'
-base_url = 'http://test.dvema.com/'
 username='13800138001'
 password='ansjer999999'
 login_url = base_url + 'account/login'

+ 6 - 2
Ansjer/test_statistics_push_month_task.py → CrontabTask/test_statistics_push_month_task.py

@@ -1,10 +1,14 @@
 import json
 
 import requests
+from Ansjer.config import SERVER_TYPE
 
+base_url = ''
+if SERVER_TYPE == "Ansjer.us_config.test_settings":
+    base_url = 'http://test.dvema.com/'
+elif SERVER_TYPE == "Ansjer.cn_config.test_settings":
+    base_url = 'http://http://test.zositechc.cn/'
 
-# url = 'http://test.dvema.com'
-base_url = 'http://test.dvema.com/'
 username='13800138001'
 password='ansjer999999'
 login_url = base_url + 'account/login'

+ 6 - 2
Ansjer/test_zositech_help_weekly_task.py → CrontabTask/test_zositech_help_weekly_task.py

@@ -2,11 +2,15 @@ import json
 
 import requests
 import time
+from Ansjer.config import SERVER_TYPE
 
+base_url = ''
+if SERVER_TYPE == "Ansjer.us_config.test_settings":
+    base_url = 'http://test.dvema.com/'
+elif SERVER_TYPE == "Ansjer.cn_config.test_settings":
+    base_url = 'http://http://test.zositechc.cn/'
 
-# url = 'http://test.dvema.com'
 # base_url = 'http://127.0.0.1:8000/'
-base_url = 'http://test.dvema.com/'
 username='13800138001'
 password='ansjer999999'
 login_url = base_url + 'account/login'

+ 7 - 0
MiddleWare/__init__.py

@@ -0,0 +1,7 @@
+# -*- coding: utf-8 -*-
+"""
+@Time : 2021/9/22 17:00
+@Auth : Locky
+@File :__init__.py.py
+@IDE :PyCharm
+"""

+ 67 - 0
MiddleWare/requestRecord.py

@@ -0,0 +1,67 @@
+# -*- coding: utf-8 -*-
+"""
+@Time : 2021/9/22 17:08
+@Auth : Locky
+@File :requestRecord.py
+@IDE :PyCharm
+"""
+import json
+import logging
+import time
+from django.utils.deprecation import MiddlewareMixin
+
+from Model.models import RequestRecordModel
+
+
+class RequestRecordMiddleware(MiddlewareMixin):
+    def process_request(self, request):
+        request.start_time = time.time()
+
+    def process_response(self, request, response):
+        try:
+            execute_time = time.time() - request.start_time
+            method = request.method
+            url = request.path
+
+            # 获取请求参数并转为字符串
+            if method == 'GET':
+                parameter = json.dumps(request.GET.dict())
+            elif method == 'POST':
+                parameter = json.dumps(request.POST.dict())
+            else:
+                parameter = ''
+
+            if response.status_code == 500:     # 处理没有捕获异常的情况
+                request_record_data = {
+                    'method': method,
+                    'url': url,
+                    'parameter': parameter,
+                    'execute_time': execute_time,
+                    'status_code': 500,
+                    'reason_phrase': response.reason_phrase,
+                }
+                RequestRecordModel.objects.create(**request_record_data)
+            elif response.content:     # 处理捕获异常的情况
+                print('content: ', response.content)
+                content = eval(str(response.content, 'utf-8'))   # bytes 转为 dict
+                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']
+                    error_flag = True
+                elif 'code' in content and content['code'] == 500:    # ResponseObject.returntype == 'pc'
+                    reason_phrase = content['data']
+                    error_flag = True
+                if error_flag:
+                    request_record_data = {
+                        'method': method,
+                        'url': url,
+                        'parameter': parameter,
+                        'execute_time': execute_time,
+                        'status_code': 500,
+                        'reason_phrase': reason_phrase,
+                    }
+                    RequestRecordModel.objects.create(**request_record_data)
+        finally:
+            return response

+ 177 - 4
Model/models.py

@@ -78,12 +78,42 @@ class Permissions(models.Model):
     def natural_key(self):
         return (self.permName)
 
+class MenuModel(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
+    parentId = models.IntegerField(default=0, verbose_name='父节点ID')
+    name = models.CharField(max_length=50,  null=True, default='', verbose_name='名称')   #首字母大写,一定要与vue文件的name对应起来,用于noKeepAlive缓存控制(该项特别重要)
+    path = models.CharField(max_length=100, null=True, default='',verbose_name='路径')
+    component = models.CharField(max_length=100, null=True, default='', verbose_name='vue文件路径') #所谓的vue 组件
+    hidden = models.BooleanField(blank=True, default=False, verbose_name=u'是否隐藏')
+    alwaysShow = models.BooleanField(blank=True, default=False, verbose_name=u'始终显示当前节点')
+    levelHidden = models.BooleanField(blank=True, default=False, verbose_name=u'是否隐藏一级路由')
+    title = models.CharField(max_length=50, default='',verbose_name='标题')
+    icon = models.CharField(max_length=50, default='',verbose_name='图标名')
+    isCustomSvg = models.BooleanField(blank=True, default=False, verbose_name=u'是否是自定义svg图标')
+    noKeepAlive = models.BooleanField(blank=True, default=False, verbose_name=u'当前路由是否不缓存')
+    noClosable = models.BooleanField(blank=True, default=False, verbose_name=u'当前路由是否可关闭多标签页')
+    badge = models.CharField(max_length=10, default='', verbose_name='badge小标签(只支持子级)')
+    tabHidden = models.BooleanField(blank=True, default=False, verbose_name=u'当前路由是否不显示多标签页')
+    activeMenu = models.CharField(max_length=50, default='', verbose_name='高亮指定菜单')
+    dot = models.BooleanField(blank=True, default=False, verbose_name=u'小圆点')
+    dynamicNewTab = models.BooleanField(blank=True, default=False, verbose_name=u'动态传参路由是否新开标签页')
+    redirect = models.CharField(max_length=50, default='', verbose_name='重定向')
+    menu_code = models.CharField(max_length=100, default='', verbose_name='菜单编码')
+    menutype  = models.SmallIntegerField(default=1, verbose_name=u'类型') #类型: 1-菜单 2-按钮
+    sort = models.IntegerField(default=0, verbose_name='排序')
+
+    class Meta:
+        db_table = 'menu'
+        verbose_name = u'菜单表'
+        verbose_name_plural = verbose_name
 
 class Role(models.Model):
     rid = models.SmallIntegerField(primary_key=True, unique=True, verbose_name=u'用户角色组ID')
     roleName = models.CharField(max_length=32, unique=True,
                                 default='User', verbose_name=u'角色名称')
     permission = models.ManyToManyField(to='Permissions', blank=True, verbose_name=u'权限', db_table='role_permissions')
+    menu = models.ManyToManyField(to='MenuModel', blank=True, verbose_name=u'后台菜单权限', db_table='role_menu')
+
     Description = models.TextField(blank=True, default='', verbose_name=u'描述信息')
 
     objects = RoleManager()
@@ -1342,7 +1372,7 @@ class VPGModel(models.Model):
 class UIDModel(models.Model):
     id = models.AutoField(primary_key=True)
     uid = models.CharField(max_length=20, null=False, db_index=True, unique=True, verbose_name='设备id')
-    mac = models.CharField(max_length=17, null=False, default='', unique=True, verbose_name='设备id对应的mac地址')
+    mac = models.CharField(max_length=17, null=True, default='', verbose_name='设备id对应的mac地址')
     uid_extra = models.TextField(default='', verbose_name='uid的额外描述')
     status = models.SmallIntegerField(default=0, verbose_name='使用状态')   # 0:未分配,1:已分配,2:已使用
     add_time = models.IntegerField(default=0, verbose_name='添加时间')
@@ -1351,6 +1381,9 @@ class UIDModel(models.Model):
     vpg = models.ForeignKey(VPGModel, to_field='id', default=1, on_delete=models.DO_NOTHING, verbose_name='关联VPG表的id')
     p2p_type = models.IntegerField(default=1, verbose_name='p2p类型。1:宸云,2:tutk')
     full_uid_code = models.CharField(max_length=256, default='', verbose_name='宸云完整uid')
+    platform = models.CharField(max_length=10, default='', verbose_name='平台')
+    init_string = models.CharField(max_length=256, default='', verbose_name='尚云设备初始化字符')
+    init_string_app = models.CharField(max_length=256, default='', verbose_name='尚云设备app初始化字符')
 
     class Meta:
         ordering = ('-add_time',)
@@ -1504,7 +1537,6 @@ class SerialNumberModel(models.Model):
     serial_number = models.CharField(max_length=9, db_index=True, unique=True, verbose_name='序列号')
     status = models.SmallIntegerField(default=1, verbose_name='可用状态。0:不可用,1:可用')
     use_status = models.SmallIntegerField(default=0, db_index=True, verbose_name='使用状态, 0: 未使用, 1: 已分配')
-    p2p = models.SmallIntegerField(default=0, db_index=True, verbose_name='p2p类型。0:无,1:宸云,2:tutk')
     add_time = models.IntegerField(default=0, verbose_name='添加时间')
 
     class Meta:
@@ -1518,7 +1550,6 @@ class CompanySerialModel(models.Model):
     company = models.ForeignKey(CompanyModel, to_field='id', on_delete=models.CASCADE, verbose_name='关联企业表的id')
     serial_number = models.CharField(max_length=11, db_index=True, blank=True, default='', verbose_name=u'6位数序列号')
     status = models.SmallIntegerField(default=0, verbose_name='序列号的状态。0:未使用,1:已使用,2:已和UID关联')
-    p2p = models.SmallIntegerField(default=0, verbose_name='p2p类型。0:无,1:宸云,2:tutk')
     add_time = models.IntegerField(default=0, verbose_name='添加时间')
     update_time = models.IntegerField(default=0, verbose_name='更新时间')
 
@@ -1569,6 +1600,29 @@ class UIDMainUser(models.Model):
         verbose_name_plural = verbose_name
 
 
+class Pc_Info(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
+    pc_name = models.CharField(blank=True, max_length=32, verbose_name=u'软件名称')
+    bundle_version = models.IntegerField(default=0, verbose_name=u'项目类型。0:Zosi;149:COCOON HD; 150:Loocam; 151:中性')
+    pc_version = models.CharField(blank=True, max_length=12, verbose_name=u'版本号')
+    pc_test = models.SmallIntegerField(default=0, verbose_name='测试版。0:否,1:是')
+    lang = models.CharField(blank=True, max_length=32, verbose_name=u'语言类型')
+    download_link = models.CharField(max_length=300, blank=True, default='', verbose_name='下载链接')
+    add_time = models.IntegerField(verbose_name='添加时间', default=0)
+    update_time = models.IntegerField(verbose_name='更新时间', default=0)
+    file_type = models.CharField(blank=True, max_length=32, verbose_name=u'文件类型')
+    package = models.CharField(blank=True, max_length=32, verbose_name=u'整合包id')
+    explain = models.TextField(blank=True, default='', verbose_name=u'更新内容')
+    is_update = models.SmallIntegerField(blank=True, default=0, verbose_name='强制更新。0:否,1:是')
+    is_open = models.SmallIntegerField(blank=True, default=0, verbose_name='是否开启版本。0:否,1:是')
+
+    class Meta:
+        db_table = 'pc_info'
+        verbose_name = u'pc信息表'
+        verbose_name_plural = verbose_name
+        ordering = ('id',)
+
+
 class CloudLogModel(models.Model):
     id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
     user = models.CharField(max_length=100, default='', db_index=True, blank=True, verbose_name=u'用户')
@@ -1581,4 +1635,123 @@ class CloudLogModel(models.Model):
     class Meta:
         db_table = 'cloud_log'
         verbose_name = '云存api记录表'
-        verbose_name_plural = verbose_name
+        verbose_name_plural = verbose_name
+
+
+class PctestjobModel(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
+    jobname = models.CharField(blank=True, max_length=32, verbose_name=u'岗位名字')
+    jobcode = models.SmallIntegerField(default=3, verbose_name='岗位code 。1:管理员,3:普通人员')
+    class Meta:
+        db_table = 'pctest_job'
+        verbose_name = u'pc岗位表'
+        verbose_name_plural = verbose_name
+        ordering = ('id',)
+
+
+class PctestdeviceModel(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
+    devicename = models.CharField(blank=True, max_length=32, verbose_name=u'设备名字')
+
+    class Meta:
+        db_table = 'pctest_device'
+        verbose_name = u'pc测试设备表'
+        verbose_name_plural = verbose_name
+        ordering = ('id',)
+
+
+class PctestfunctionModel(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
+    functionname = models.CharField(blank=True, max_length=32, verbose_name=u'职能名字')
+    functioncode = models.SmallIntegerField(default=1, verbose_name='职能code 。PC端自己逻辑判断')
+    class Meta:
+        db_table = 'pctest_function'
+        verbose_name = u'pc设备职能表'
+        verbose_name_plural = verbose_name
+        ordering = ('id',)
+
+
+class PctestuserModel(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
+    username = models.CharField(blank=True, max_length=32, verbose_name=u'用户名字')
+    password = models.CharField(blank=True, max_length=32, verbose_name=u'用户名字')
+    job = models.ForeignKey(PctestjobModel, to_field='id', on_delete=models.DO_NOTHING, verbose_name='关联pc岗位表')
+
+    class Meta:
+        db_table = 'pctest_user'
+        verbose_name = u'pc角色岗位表'
+        verbose_name_plural = verbose_name
+        ordering = ('id',)
+
+
+class PctestlogModel(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
+    user = models.ForeignKey(PctestuserModel, to_field='id', on_delete=models.DO_NOTHING, verbose_name='关联pc岗位表')
+    content = models.TextField(blank=True, default='', verbose_name=u'测试日志')
+    addtime = models.IntegerField(verbose_name='添加时间', default=0)
+
+    class Meta:
+        db_table = 'pctest_log'
+        verbose_name = u'pc测试日志表'
+        verbose_name_plural = verbose_name
+        ordering = ('id',)
+
+
+class PctestjobdeviceModel(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
+    job = models.ForeignKey(PctestjobModel, to_field='id', on_delete=models.DO_NOTHING, verbose_name='关联pc岗位表')
+    device = models.ForeignKey(PctestdeviceModel, to_field='id', on_delete=models.DO_NOTHING, verbose_name='关联pc测试设备表')
+
+    class Meta:
+        db_table = 'pctest_job_device'
+        verbose_name = u'pc岗位设备关联表'
+        verbose_name_plural = verbose_name
+        ordering = ('id',)
+
+
+class PctestModel(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
+    device = models.ForeignKey(PctestdeviceModel, to_field='id', on_delete=models.DO_NOTHING, verbose_name='关联pc测试设备表')
+    function = models.ForeignKey(PctestfunctionModel, to_field='id', on_delete=models.DO_NOTHING, verbose_name='关联pc设备职能表')
+
+    class Meta:
+        db_table = 'pctest_device_function'
+        verbose_name = u'pc岗位设备关联表'
+        verbose_name_plural = verbose_name
+        ordering = ('id',)
+
+
+class P2PIpModel(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
+    uid = models.CharField(max_length=20, default='', unique=True, db_index=True, verbose_name='设备uid')
+    ip = models.CharField(default='', max_length=32, verbose_name='ip')
+    p2p_request_times = models.IntegerField(default=0, verbose_name='p2p请求次数')
+    relay_request_times = models.IntegerField(default=0, verbose_name='relay请求次数')
+    continent_name = models.CharField(default='', max_length=10, verbose_name='大洲')
+    country_name = models.CharField(default='', max_length=100, verbose_name='国家')
+    region_name = models.CharField(default='', max_length=100, verbose_name='地区')
+    city_name = models.CharField(default='', max_length=100, verbose_name='城市')
+    add_time = models.IntegerField(default=0, verbose_name='添加时间')
+    update_time = models.IntegerField(default=0, verbose_name='更新时间')
+
+    class Meta:
+        db_table = 'p2p_ip'
+        verbose_name = u'设备p2p_ip地区表'
+        verbose_name_plural = verbose_name
+
+
+class RequestRecordModel(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name=u'自增ID')
+    method = models.CharField(max_length=10, default='', verbose_name='请求类型')
+    url = models.CharField(max_length=200, default='', verbose_name='请求路径')
+    parameter = models.CharField(max_length=200, default='', verbose_name='请求参数')
+    execute_time = models.FloatField(default=0, verbose_name='执行时间')
+    status_code = models.CharField(max_length=10, default='', verbose_name='响应状态码')
+    reason_phrase = models.CharField(max_length=200, default='', verbose_name='错误信息')
+    add_time = models.DateTimeField(blank=True, auto_now_add=True, verbose_name=u'添加时间')
+
+    class Meta:
+        db_table = 'request_record'
+        verbose_name = u'请求记录表'
+        verbose_name_plural = verbose_name
+        ordering = ('-add_time',)

+ 15 - 20
Object/AWS/S3Email.py

@@ -5,21 +5,16 @@ from email.mime.text import MIMEText
 
 class S3Email:
 
-   def __init__(self, *args, **kwargs):
-       SENDER = 'rdpublic@ansjer.com'  # 邮箱名
-       SENDERNAME = 'rdpublic@ansjer.com'
-       USERNAME_SMTP = "AKIA2E67UIMD6MOSFKXW"  # 带有邮件权限的 IAM 帐号
-       PASSWORD_SMTP = "BHuQ6EQTtFK4qh46o9omO9ZzO3NXzjk/JCWLXnVFmqzM"  # 带有邮件权限的 IAM 密码
-       PORT = 587
-       HOST = "email-smtp.us-east-1.amazonaws.com"
 
-
-   def faEmail(self, content ,RECIPIENT):
-
-        SUBJECT = 'Amazon SES Error (Python smtplib)'
-        BODY_TEXT = ("Amazon SES Test\r\n"
-                     "This email was sent through the Amazon SES SMTP "
-                     "Interface using the Python smtplib package."
+   def faEmail(self, sys_msg_text ,username):
+        SENDER = 'rdpublic@ansjer.com'  # 邮箱名
+        SENDERNAME = 'rdpublic@ansjer.com'
+        USERNAME_SMTP = 'AKIA2E67UIMD6MOSFKXW'  # 带有邮件权限的 IAM 帐号
+        PASSWORD_SMTP = 'BHuQ6EQTtFK4qh46o9omO9ZzO3NXzjk/JCWLXnVFmqzM'  # 带有邮件权限的 IAM 密码
+        PORT = '587'
+        HOST = 'email-smtp.us-east-1.amazonaws.com'
+        SUBJECT = sys_msg_text
+        BODY_TEXT = (sys_msg_text
                      )
         BODY_HTML = """<html>
         <head></head>
@@ -27,24 +22,24 @@ class S3Email:
           <h1>{}<h1>
         </body>
         </html>
-                    """.format(content)
+                    """.format(sys_msg_text)
 
         msg = MIMEMultipart('alternative')
         msg['Subject'] = SUBJECT
-        msg['From'] = email.utils.formataddr((self.SENDERNAME, self.SENDER))
-        msg['To'] = RECIPIENT
+        msg['From'] = email.utils.formataddr((SENDERNAME, SENDER))
+        msg['To'] = username
         part1 = MIMEText(BODY_TEXT, 'plain')
         part2 = MIMEText(BODY_HTML, 'html')
         msg.attach(part1)
         msg.attach(part2)
 
         try:
-            server = smtplib.SMTP(self.HOST, self.PORT)
+            server = smtplib.SMTP(HOST, PORT)
             server.ehlo()
             server.starttls()
             server.ehlo()
-            server.login(self.USERNAME_SMTP, self.PASSWORD_SMTP)
-            server.sendmail(self.SENDER, RECIPIENT, msg.as_string())
+            server.login(USERNAME_SMTP, PASSWORD_SMTP)
+            server.sendmail(SENDER, username, msg.as_string())
             server.close()
         except Exception as e:
             print("Error: ", e)

+ 4 - 1
Object/ResponseObject.py

@@ -3,8 +3,9 @@ import simplejson as json
 
 
 class ResponseObject(object):
-    def __init__(self, lang='en'):
+    def __init__(self, lang='en', returntype='currency'):
         self.lang = lang
+        self.returntype = returntype
 
     def data(self, code, res={}):
         data_en = {
@@ -209,6 +210,8 @@ class ResponseObject(object):
             message = '系统错误,code不存在'
         print(self.lang == 'cn')
         print(msg)
+        if self.returntype=='pc':
+            return {'code': code, 'msg': message, 'data': res, 'error_code': code}
         return {'result_code': code, 'reason': message, 'result': res, 'error_code': code}
 
     def formal(self, code, res={}):

+ 14 - 1
Object/TokenObject.py

@@ -19,7 +19,7 @@ from Object.RedisObject import RedisObject
 
 class TokenObject:
 
-    def __init__(self, token=None):
+    def __init__(self, token=None, returntpye='currency'):
         if token == 'local':
             token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VySUQiOiIxNTg0MzUxODk2MjgyMTM4MDAxMzgwMDAiLCJsYW5nIjoiZW4iLCJ1c2VyIjoiMTM2ODAzMTc1OTYiLCJtX2NvZGUiOiIxMjM0MTMyNDMyMTQiLCJleHAiOjE1ODcyNzcwNjB9.c0LV_XyxwbzUlYqMJqx7vw9f19Jv-0kGnUHuu_go-mo'
         if token == 'test':
@@ -31,12 +31,15 @@ class TokenObject:
         self.code = 0
         # 令牌校验
         self.valid()
+        self.returntpye = returntpye
 
     def valid(self):
         if self.token is None:
             self.code = 309
             return
         try:
+            self.token= self.token.replace("Bearer ", "")
+
             res = jwt.decode(self.token, OAUTH_ACCESS_TOKEN_SECRET, algorithms='HS256')
             # print(res)
             self.userID = res.get('userID', None)
@@ -84,12 +87,22 @@ class TokenObject:
                 refresh_data,
                 OAUTH_REFRESH_TOKEN_SECRET,
                 algorithm='HS256')
+
             res = {
                 'access_token': access_token.decode('utf-8'),
                 'access_expire': access_expire,
                 'refresh_expire': refresh_expire,
                 'refresh_token': refresh_token.decode('utf-8'),
             }
+
+            if self.returntpye=='pc':
+                res = {
+                    'token': access_token.decode('utf-8'),
+                    'access_expire': access_expire,
+                    'refresh_expire': refresh_expire,
+                    'refresh_token': refresh_token.decode('utf-8'),
+                }
+
         except Exception as e:
             self.code = 309
             print(repr(e))

+ 3 - 8
Service/CloudLogs.py

@@ -26,13 +26,8 @@ def batch_add_log_ctr(request, status_code):
         request_dict = request.POST
     else:
         return
-    api_list = [
-        'cloudstorage/getsignsts',
-        'cloudstorage/storeplaylist',
-        'cloudstorage/queryvodlist',
-    ]
     request_path = request.path.strip().strip('/')
-    if 'cloudstorage' in request_path:
+    if 'cloudstorage' in request_path :
         user = MiscellService.get_access_name(request_dict)
         uidToken = request_dict.get('uidToken', None)
         utko = UidTokenObject(uidToken)
@@ -69,7 +64,7 @@ def batch_add_log_ctr(request, status_code):
             logKey = 'test_logger'
         redisObj.rpush(name=logKey, val=loggerData)
         # 判断redis列表长度
-        if redisObj.llen(name=logKey) > 0:
+        if redisObj.llen(name=logKey) > 100:
             data_list = redisObj.lrange(logKey, 0, -1)
             redisObj.del_data(key=logKey)
             add_batch_log(data_list)
@@ -97,4 +92,4 @@ def add_batch_log(data_list):
         print(repr(e))
         return False
     else:
-        return True
+        return True

+ 17 - 0
Service/CommonService.py

@@ -36,6 +36,23 @@ class CommonService:
         sqlDict = dict(zip(["datas"], [sqlList]))
         return sqlDict
 
+    # 格式化query_set转dict
+    @staticmethod
+    def request_dict_to_dict(request_dict):
+        # 传参格式转换,键包含meta获取meta[]中的值,值'true'/'false'转为True,False
+        key_list = []
+        value_list = []
+        for k, v in request_dict.items():
+            key_list.append(k[k.index('[')+1:k.index(']')] if 'meta' in k else k)
+            if v == 'true':
+                v = True
+            elif v == 'false':
+                v = False
+            value_list.append(v)
+        data_dict = dict(zip(key_list, value_list))
+        print(data_dict)
+        return data_dict
+
     # 获取文件大小
     @staticmethod
     def get_file_size(file_path='', suffix_type='', decimal_point=0):

+ 3 - 3
Service/MiscellService.py

@@ -5,7 +5,7 @@ import time
 import requests
 import simplejson as json
 from django.utils.timezone import utc
-from Ansjer import local_settings as api_settings
+from Ansjer import config as api_settings
 
 from Object.TokenObject import TokenObject
 from Object.mongodb import mongodb
@@ -200,7 +200,7 @@ class MyserviceDynamodb():
 my = MyserviceDynamodb()
 
 # print(my.table_delete('user_brand_all'))
-if DOMAIN_HOST == 'www.dvema.com':
+if DOMAIN_HOST == 'www.zositechc.cn':
     user_brand = 'access_log'
 else:
     user_brand = 'test_access_log'
@@ -459,7 +459,7 @@ def dynamo_db_add_log_ctr(request, status_code):
         request_dict.pop('userPwd')
     content = json.dumps(request_dict)
     addTime = int(time.time())
-    if DOMAIN_HOST == 'www.dvema.com':
+    if DOMAIN_HOST == 'www.zositechc.cn':
         user_brand = 'access_log'
     else:
         user_brand = 'test_access_log'

+ 0 - 40
Service/ModelService.py

@@ -1,11 +1,9 @@
-import base64
 import logging
 import time
 
 import requests
 
 from Ansjer.config import BASE_DIR
-from Controller.CheckUserData import RandomStr
 from Model.models import *
 import json
 from django.db.models import Q
@@ -250,44 +248,6 @@ class ModelService:
         file.flush()
         file.close()
 
-    @staticmethod
-    # 加密
-    def encrypt_pwd(userPwd):
-        for i in range(1, 4):
-            if i == 1:
-                userPwd = RandomStr(3, False) + userPwd + RandomStr(3, False)
-                userPwd = base64.b64encode(str(userPwd).encode("utf-8")).decode('utf8')
-            if i == 2:
-                userPwd = RandomStr(2, False) + str(userPwd) + RandomStr(2, False)
-                userPwd = base64.b64encode(str(userPwd).encode("utf-8")).decode('utf8')
-            if i == 3:
-                userPwd = RandomStr(1, False) + str(userPwd) + RandomStr(1, False)
-                userPwd = base64.b64encode(str(userPwd).encode("utf-8")).decode('utf8')
-        return userPwd
-
-    @staticmethod
-    # 解密
-    def decode_pwd(password):
-        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]
-        return password
 
 def notify_alexa_delete(userID, UID):
     url = 'https://www.zositech.xyz/deviceStatus/delete'

+ 8 - 5
Service/middleware.py

@@ -2,12 +2,13 @@
 # -*- coding: utf-8 -*-
 from django.utils.deprecation import MiddlewareMixin
 
-from Ansjer import local_settings as api_settings
+from Ansjer import config as api_settings
 from Ansjer.config import SERVER_TYPE
 
 from Object.ResponseObject import ResponseObject
 from Service.MiscellService import MiscellService
-from Service import OperatingLogs, CloudLogs
+from Service import OperatingLogs
+from Service import CloudLogs
 import django.db
 
 
@@ -56,7 +57,7 @@ class StatisticsUrlMiddleware(MiddlewareMixin):
         (无视其种类)以及相应的view。 Django将立即返回该 HttpResponse。
         '''
         if request.path != '/favicon.ico':
-            print('process_request', request)
+            print('process_request:', request)
         result = self._https_statistics_to_reverse(request)
         if result == -1:
             response = ResponseObject()
@@ -65,7 +66,7 @@ class StatisticsUrlMiddleware(MiddlewareMixin):
 
     def process_view(self, request, callback, callback_args, callback_kwargs):
         if request.path != '/favicon.ico':
-            print('process_view', request)
+            print('process_view:', request)
         return None
 
     def process_response(self, request, response):
@@ -82,13 +83,15 @@ class StatisticsUrlMiddleware(MiddlewareMixin):
         ########记录访问日志
         # MiscellService.DynamoDB_add_access_log(request=request, status_code=response.status_code)
         if request.path !='/favicon.ico':
-            print('process_response', request, response)
+            print('process_response:', request, response)
+            print('SERVER_TYPE:', SERVER_TYPE)
             CloudLogs.batch_add_access_log(request=request, status_code=response.status_code)
             try:
                 pass
                 # mysql
                 if SERVER_TYPE!="Ansjer.formal_settings":
                     # print('添加日志')
+                    # CloudLogs.batch_add_access_log(request=request, status_code=response.status_code)
                     OperatingLogs.add_access_log(request=request, status_code=response.status_code)
                     MiscellService.add_access_log(request=request, status_code=response.status_code)
                 # else:

+ 15 - 0
cn_formal_manage.py

@@ -0,0 +1,15 @@
+#!/usr/bin/env python
+import os
+import sys
+
+if __name__ == "__main__":
+    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Ansjer.cn_config.formal_settings")
+    try:
+        from django.core.management import execute_from_command_line
+    except ImportError as exc:
+        raise ImportError(
+            "Couldn't import Django. Are you sure it's installed and "
+            "available on your PYTHONPATH environment variable? Did you "
+            "forget to activate a virtual environment?"
+        ) from exc
+    execute_from_command_line(sys.argv)

+ 1 - 1
formal_manage.py → cn_test_manage.py

@@ -3,7 +3,7 @@ import os
 import sys
 
 if __name__ == "__main__":
-    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Ansjer.formal_settings")
+    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Ansjer.cn_config.test_settings")
     try:
         from django.core.management import execute_from_command_line
     except ImportError as exc:

+ 1 - 9
local_manage.py

@@ -3,15 +3,7 @@ import os
 import sys
 
 if __name__ == "__main__":
-    # import socket
-    #
-    # addrs = socket.getaddrinfo(socket.gethostname(), None)
-    # for index, item in enumerate(addrs):
-    #     if index == 5:
-    #         ip = item[4][0]
-    #
-    #         print('当前局域网ip地址为:' + ip)
-    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Ansjer.local_settings")
+    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Ansjer.local_config.local_settings")
     try:
         from django.core.management import execute_from_command_line
     except ImportError as exc:

+ 1 - 9
manage.py

@@ -3,15 +3,7 @@ import os
 import sys
 
 if __name__ == "__main__":
-    # import socket
-    #
-    # addrs = socket.getaddrinfo(socket.gethostname(), None)
-    # for index, item in enumerate(addrs):
-    #     if index == 5:
-    #         ip = item[4][0]
-    #
-    #         print('当前局域网ip地址为:' + ip)
-    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Ansjer.local_settings")
+    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Ansjer.local_config.local_settings")
     try:
         from django.core.management import execute_from_command_line
     except ImportError as exc:

+ 15 - 0
us_formal_manage.py

@@ -0,0 +1,15 @@
+#!/usr/bin/env python
+import os
+import sys
+
+if __name__ == "__main__":
+    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Ansjer.us_config.formal_settings")
+    try:
+        from django.core.management import execute_from_command_line
+    except ImportError as exc:
+        raise ImportError(
+            "Couldn't import Django. Are you sure it's installed and "
+            "available on your PYTHONPATH environment variable? Did you "
+            "forget to activate a virtual environment?"
+        ) from exc
+    execute_from_command_line(sys.argv)

+ 1 - 1
test_manage.py → us_test_manage.py

@@ -3,7 +3,7 @@ import os
 import sys
 
 if __name__ == "__main__":
-    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Ansjer.test_settings")
+    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Ansjer.us_config.test_settings")
     try:
         from django.core.management import execute_from_command_line
     except ImportError as exc: