Ver Fonte

从新拉去test分支

peng há 2 anos atrás
pai
commit
e8bf354ab6
40 ficheiros alterados com 3046 adições e 2187 exclusões
  1. 48 13
      AdminController/AiServeController.py
  2. 28 19
      AdminController/DeviceManagementController.py
  3. 7 7
      AdminController/LogManagementController.py
  4. 848 847
      AdminController/UnicomManageController.py
  5. 34 27
      AdminController/UserManageController.py
  6. 93 81
      AdminController/VersionManagementController.py
  7. 38 6
      AdminController/dataSystemManagement/HomeDataController.py
  8. 24 18
      AdminController/dataSystemManagement/ServiceDataController.py
  9. 2 2
      Ansjer/cn_config/config_test.py
  10. 2 2
      Ansjer/cn_config/formal_settings.py
  11. 2 2
      Ansjer/eur_config/formal_settings.py
  12. 3 1
      Ansjer/server_urls/loocam_url.py
  13. 224 326
      Ansjer/urls.py
  14. 3 3
      Controller/AWS/KVSController.py
  15. 17 18
      Controller/AiController.py
  16. 2 2
      Controller/AlgorithmShop/AlgorithmShopController.py
  17. 1 1
      Controller/AppAccountManagement.py
  18. 297 46
      Controller/CloudStorage.py
  19. 3 3
      Controller/CloudTransfer.py
  20. 6 4
      Controller/CloudVod.py
  21. 227 52
      Controller/Cron/CronTaskController.py
  22. 1 1
      Controller/DetectController.py
  23. 42 13
      Controller/DetectControllerV2.py
  24. 4 2
      Controller/EquipmentManager.py
  25. 24 6
      Controller/EquipmentManagerV3.py
  26. 6 6
      Controller/FeedBack.py
  27. 8 6
      Controller/PaymentCycle.py
  28. 144 63
      Controller/SensorGateway/GatewayDeviceController.py
  29. 134 73
      Controller/SensorGateway/SmartSceneController.py
  30. 7 7
      Controller/SensorGateway/SmartSocketController.py
  31. 4 1
      Controller/SerialNumberController.py
  32. 11 3
      Controller/SysMsg.py
  33. 168 308
      Controller/TestApi.py
  34. 299 192
      Controller/UserController.py
  35. 2 2
      Controller/UserDevice/UserDeviceShareController.py
  36. 13 4
      Controller/UserManger.py
  37. 143 17
      Model/models.py
  38. 94 0
      Object/AWS/AmazonS3Util.py
  39. 33 3
      Service/CommonService.py
  40. BIN
      requirements.txt

+ 48 - 13
AdminController/AiServeController.py

@@ -5,7 +5,7 @@ import time
 from django.db.models import F
 from django.views.generic.base import View
 
-from Model.models import Lang, AiStoreMeal, AiService, Order_Model, Device_User, CountryModel, UidSetModel
+from Model.models import Lang, AiStoreMeal, AiService, Order_Model, Device_User, CountryModel, UidSetModel, Device_Info
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Service.CommonService import CommonService
@@ -123,7 +123,7 @@ class AiServeView(View):
                 0, {'list': ai_meal_list, 'total': total})
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def addOrEditAiStoreMeal(self, request_dict, response):
         # 添加/编辑套餐
@@ -169,7 +169,7 @@ class AiServeView(View):
             return response.json(0)
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def deleteAiStoreMeal(self, request_dict, response):
         # 删除ai套餐
@@ -182,7 +182,7 @@ class AiServeView(View):
             return response.json(0)
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def getAiMealLanguage(self, request_dict, response):
         # 获取ai套餐语言
@@ -228,7 +228,7 @@ class AiServeView(View):
                 0, {'list': ai_meal_lang_list, 'total': total})
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def addOrEditAiMealLanguage(self, request_dict, response):
         # 添加/编辑套餐语言
@@ -270,7 +270,8 @@ class AiServeView(View):
                         lang=lang,
                         title=title,
                         content=content,
-                        discount_content=discount_content)
+                        discount_content=discount_content,
+                        type=1)
                     lang_obj = Lang.objects.filter(
                         lang=lang,
                         title=title,
@@ -280,7 +281,7 @@ class AiServeView(View):
             return response.json(0)
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def deleteAiMealLanguage(self, request_dict, response):
         # 删除套餐语言
@@ -299,12 +300,13 @@ class AiServeView(View):
             return response.json(0)
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def getDeviceAiMealList(self, request_dict, response):
         pageNo = request_dict.get('pageNo', None)
         pageSize = request_dict.get('pageSize', None)
         uid = request_dict.get('uid', None)
+        serialNumber = request_dict.get('serialNumber', None)
         if not all([pageNo, pageSize]):
             return response.json(444)
 
@@ -314,6 +316,10 @@ class AiServeView(View):
             ai_service_qs = AiService.objects.all()
             if uid:
                 ai_service_qs = ai_service_qs.filter(uid__contains=uid)
+            if serialNumber:
+                device_info_qs = Device_Info.objects.filter(serial_number=serialNumber).values('UID')
+                uid = device_info_qs[0]['UID'] if device_info_qs.exists() else 'N/A'
+                ai_service_qs = ai_service_qs.filter(uid__icontains=uid)
 
             if not ai_service_qs.exists():
                 return response.json(0, [])
@@ -331,11 +337,30 @@ class AiServeView(View):
                 'addTime',
                 'updTime', 'user_name').order_by('-addTime')
             ai_service_qs = ai_service_qs[(page - 1) * line:page * line]
+            ai_service_list = []
+            for ai_service in ai_service_qs:
+                data = {
+                    'id': ai_service['id'],
+                    'uid': ai_service['uid'],
+                    'channel': ai_service['channel'],
+                    'use_status': ai_service['use_status'],
+                    'detect_status': ai_service['detect_status'],
+                    'detect_group': ai_service['detect_group'],
+                    'endTime': ai_service['endTime'],
+                    'addTime': ai_service['addTime'],
+                    'updTime': ai_service['updTime'],
+                    'user_name': ai_service['user_name'],
+                    'serial_number': 'N/A'
+                }
+                device_info_qs = Device_Info.objects.filter(UID=ai_service['uid']).values('serial_number')
+                if device_info_qs.exists():
+                    data['serial_number'] = device_info_qs[0]['serial_number'] if device_info_qs[0]['serial_number'] else 'N/A'
+                ai_service_list.append(data)
             return response.json(
-                0, {'list': list(ai_service_qs), 'total': count})
+                0, {'list': ai_service_list, 'total': count})
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def getAiUserList(self, request_dict, response):
         username = request_dict.get('username', None)
@@ -344,6 +369,7 @@ class AiServeView(View):
         payType = request_dict.get('payType', None)
         status = request_dict.get('status', None)
         use_status = request_dict.get('use_status', None)
+        serialNumber = request_dict.get('serialNumber', None)
         addTimeRange = request_dict.getlist('addTimeRange[]', None)
 
         pageNo = request_dict.get('pageNo', None)
@@ -356,7 +382,7 @@ class AiServeView(View):
         try:
             order_qs = Order_Model.objects.filter(
                 order_type=1).order_by('-addTime')
-            if username or NickName or uid or payType or status or use_status or addTimeRange:
+            if username or NickName or uid or payType or status or use_status or addTimeRange or serialNumber:
                 if username:
                     order_qs = order_qs.filter(
                         userID__username__contains=username)
@@ -371,6 +397,10 @@ class AiServeView(View):
                     order_qs = order_qs.filter(status=status)
                 if use_status:
                     order_qs = order_qs.filter(use_status=use_status)
+                if serialNumber:
+                    device_info_qs = Device_Info.objects.filter(serial_number=serialNumber).values('UID')
+                    uid = device_info_qs[0]['UID'] if device_info_qs.exists() else 'N/A'
+                    order_qs = order_qs.filter(UID=uid)
                 if addTimeRange:
                     addStartTime, addEndTime = int(
                         addTimeRange[0][:-3]), int(addTimeRange[1][:-3])
@@ -430,12 +460,17 @@ class AiServeView(View):
                 if ai_service_qs.exists():
                     data_dict['endTime'] = ai_service_qs[0]['endTime']
                     data_dict['use_status'] = ai_service_qs[0]['use_status']
+                data_dict['serial_number'] = 'N/A'
+                device_info_qs = Device_Info.objects.filter(UID=order['UID']).values('serial_number')
+                if device_info_qs.exists():
+                    data_dict['serial_number'] = device_info_qs[0]['serial_number'] if device_info_qs[0][
+                        'serial_number'] else 'N/A'
                 data_list.append(data_dict)
             return response.json(
                 0, {'list': data_list, 'total': count})
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def get_device_country(ip):
@@ -502,4 +537,4 @@ class AiServeView(View):
             return response.json(0, {'list': list_data})
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))

+ 28 - 19
AdminController/DeviceManagementController.py

@@ -3,7 +3,6 @@
 import json
 import operator
 import time
-from bisect import bisect_left
 
 import oss2
 from django.db import transaction
@@ -162,14 +161,17 @@ class DeviceManagement(View):
                             device_info_list["datas"][k]['fields']['Type'] = device_type_qs[0]['name']
                         uid_set_qs = UidSetModel.objects.filter(
                             uid=device_info_list["datas"][k]['fields']['UID']).values('is_alexa', 'ip', 'version',
-                                                                                      'is_ai', 'is_human', 'cloud_vod')
+                                                                                      'is_ai', 'is_human', 'cloud_vod',
+                                                                                      'ucode', 'device_type')
                         if uid_set_qs.exists():
                             isAlexa = '是' if uid_set_qs[0]['is_alexa'] else '否'
                             isHuman = '是' if uid_set_qs[0]['is_human'] else '否'
-                            if uid_set_qs[0]['cloud_vod'] == 2:
-                                cloud_vod = '不支持'
-                            else:
+                            cloud_vod = CommonService.is_cloud_device(uid_set_qs[0]['ucode'],
+                                                                      uid_set_qs[0]['device_type'])
+                            if cloud_vod:
                                 cloud_vod = '支持'
+                            else:
+                                cloud_vod = '不支持'
                             if uid_set_qs[0]['is_ai'] == 2:
                                 isAI = '不支持'
                             elif uid_set_qs[0]['is_ai'] == 1:
@@ -199,7 +201,7 @@ class DeviceManagement(View):
             return response.json(0, {'list': device_info_list, 'total': total})
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     # 根据id删除设备
     def deleteDevice(self, request_dict, response):
@@ -220,7 +222,7 @@ class DeviceManagement(View):
             return response.json(0)
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     # 重置设备主用户
     def resetPrimaryUser(self, request, request_dict, response):
@@ -244,7 +246,7 @@ class DeviceManagement(View):
             Device_Info.objects.filter(UID=uid).update(vodPrimaryUserID='', vodPrimaryMaster='')
             return response.json(0)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     # 重置设备云存
     def resetVod(self, request, request_dict, response):
@@ -280,7 +282,7 @@ class DeviceManagement(View):
             return response.json(0)
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def reset_ai(request, request_dict, response):
@@ -308,7 +310,7 @@ class DeviceManagement(View):
             return response.json(0)
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     # 获取设备类型数据
     def getDeviceTypeList(self, request_dict, response):
@@ -342,7 +344,7 @@ class DeviceManagement(View):
             return response.json(0, {'list': device_type_list, 'total': total})
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     # 删除设备类型
     def deleteDeviceType(self, request_dict, response):
@@ -354,7 +356,7 @@ class DeviceManagement(View):
             return response.json(0)
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     # 添加设备类型
     def addDeviceType(self, request, request_dict, response):
@@ -382,7 +384,7 @@ class DeviceManagement(View):
             return response.json(0)
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def del_device_data(request_dict, response):
@@ -492,7 +494,8 @@ class DeviceManagement(View):
                 sort=F('app_device_type__devicenamelanguage__sort')).values('id', 'app_device_type__id', 'model',
                                                                             'type', 'icon',
                                                                             'app_device_type__devicenamelanguage__id',
-                                                                            'lang', 'name', 'sort').order_by(
+                                                                            'lang', 'name', 'sort',
+                                                                            'app_device_type__app_version_number_id').order_by(
                 'app_device_type__devicenamelanguage__sort')
             if not app_bundle_qs.exists():
                 return response.json(0)
@@ -505,11 +508,14 @@ class DeviceManagement(View):
                 app_bundle_qs = app_bundle_qs.filter(type=type)
             total = app_bundle_qs.count()
             app_bundle_qs = app_bundle_qs[(page - 1) * line:page * line]
-            app_device_type_list = [app_bundle for app_bundle in app_bundle_qs]
+            app_device_type_list = []
+            for app_bundle in app_bundle_qs:
+                app_bundle['version_number'] = app_bundle.pop('app_device_type__app_version_number_id')
+                app_device_type_list.append(app_bundle)
             return response.json(0, {'list': app_device_type_list, 'total': total})
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def get_app_bundle_id_list(response):
@@ -519,7 +525,7 @@ class DeviceManagement(View):
             return response.json(0, {'list': appBundleIdList})
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def edit_app_device_type(request_dict, response):
@@ -544,7 +550,7 @@ class DeviceManagement(View):
             return response.json(0)
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def delete_app_device_type(request_dict, response):
@@ -559,7 +565,7 @@ class DeviceManagement(View):
             return response.json(0)
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def reset_all(request, request_dict, response):
@@ -694,6 +700,9 @@ class DeviceManagement(View):
         if not all([lang, app_bundle_id, version_number]):
             return response.json(444)
         try:
+            # tc是ios繁体字语言类型
+            if lang == 'tc':
+                lang = 'cn_tw'
             app_bundle_qs = AppBundle.objects.filter(app_bundle_id=app_bundle_id).values(
                 'app_device_type__app_version_number_id').distinct().order_by('app_device_type__app_version_number_id')
             #  判断版本是否存在, 不存在则获取输入版本范围内最接近的输入版本

+ 7 - 7
AdminController/LogManagementController.py

@@ -100,7 +100,7 @@ class LogManagementView(View):
                 0, {'list': qs_list, 'total': count})
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def getDeviceIotInfoList(self, request_dict, response):
         serial_number = request_dict.get('serial_number', None)
@@ -153,7 +153,7 @@ class LogManagementView(View):
                 0, {'list': iot_device_info_list, 'total': total})
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     # 通用发布MQTT通知
     @staticmethod
@@ -171,7 +171,7 @@ class LogManagementView(View):
                 return response.json(10044)
             return response.json(0)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def getAccessLogList(self, request_dict, response):
         user = request_dict.get('user', None)
@@ -210,7 +210,7 @@ class LogManagementView(View):
             return response.json(0, {'list': access_log_list, 'total': total})
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def getDeviceLogList(self, request_dict, response):
         uid = request_dict.get('uid', None)
@@ -266,7 +266,7 @@ class LogManagementView(View):
             return response.json(0, {'list': device_log_list, 'total': total})
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def getOperationLogList(self, request_dict, response):
         operation = request_dict.get('operation', None)
@@ -295,7 +295,7 @@ class LogManagementView(View):
                 0, {'list': log_list, 'total': count})
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def getAppLogList(self, request_dict, response):
         """
@@ -351,4 +351,4 @@ class LogManagementView(View):
             return response.json(0, {'list': app_log_list, 'total': count})
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))

+ 848 - 847
AdminController/UnicomManageController.py

@@ -1,847 +1,848 @@
-# Copyright (C) 2022 #
-# @Time    : 2022/7/18 16:16
-# @Author  : ghl
-# @Email   : Guanhailogn@asj6.wecom.work
-# @File    : UnicomManageController.py
-# @Software: PyCharm
-import datetime
-import hashlib
-import json
-import time
-import uuid
-from decimal import Decimal
-
-import openpyxl
-import requests
-from django.db import transaction, connection
-from django.http import HttpResponse
-from django.views.generic.base import View
-
-from Ansjer.config import CONFIG_INFO
-from Ansjer.config import LOGGER
-from Controller.UnicomCombo.UnicomComboController import UnicomComboView
-from Model.models import UnicomDeviceInfo, UnicomCombo, Pay_Type, UnicomComboOrderInfo, Device_User, Order_Model, \
-    ExchangeCode, UnicomFlowPush, SysMsgModel, UnicomComboExperienceHistory, LogModel
-from Object.Enums.WXOperatorEnum import WXOperatorEnum
-from Object.ResponseObject import ResponseObject
-from Object.TokenObject import TokenObject
-from Object.UnicomObject import UnicomObjeect
-from Object.WXTechObject import WXTechObject
-from Service.CommonService import CommonService
-
-
-class UnicomManageControllerView(View):
-
-    def get(self, request, *args, **kwargs):
-        request.encoding = 'utf-8'
-        operation = kwargs.get('operation')
-        return self.validation(request.GET, request, operation)
-
-    def post(self, request, *args, **kwargs):
-        request.encoding = 'utf-8'
-        operation = kwargs.get('operation')
-        return self.validation(request.POST, request, operation)
-
-    def validation(self, request_dict, request, operation):
-        response = ResponseObject()
-        # 获取支付类型
-        if operation == 'get/pay':
-            return self.get_pay_type(response)
-        # 获取套餐类型
-        elif operation == 'combo/type':
-            return self.get_unicom_combo_type(response)
-        elif operation == 'downloadCDK':  # 下载兑换码
-            return self.package_cdk_export_excel(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 == 'get/deta/info':
-                return self.get_unicom_info(request_dict, response)
-            # 添加和编辑卡套餐
-            elif operation == 'edit/combo':
-                return self.edit_combo(request_dict, response)
-            # 统计4G套餐
-            elif operation == 'getComboDataList':
-                return self.static_info(request_dict, response)
-            # 删除卡套餐
-            elif operation == 'dele/combo/info':
-                return self.combo_order_info(request_dict, response)
-            # 获取/筛选用户信息
-            elif operation == 'filter/user':
-                return self.get_user_info(request_dict, response)
-            # 充值流量
-            elif operation == 'getFlowPackages':
-                return self.get_flow_packages(request_dict, response)
-            #  获取/筛选4G流量卡订单信息
-            elif operation == 'query-order':
-                return self.query_4G_user_order(request_dict, response)
-            elif operation == 'sim-info':
-                return self.get_iccid_info(request_dict, response)
-            elif operation == 'batchGenerateCDK':  # 批量生成兑换码
-                return self.create_package_cdk(request_dict, response)
-            elif operation == 'resetCardPackage':
-                return self.reset_card_package(request, request_dict, response)
-            elif operation == 'getPackageDetails':
-                return self.get_package_details(request_dict, response)
-            else:
-                return response.json(404)
-
-    @classmethod
-    def reset_card_package(cls, request, request_dict, response):
-        try:
-            serial_number = request_dict.get('serialNumber', None)
-            if not serial_number:
-                return response.json(444)
-            device_info_qs = UnicomDeviceInfo.objects.filter(serial_no=serial_number)
-            now_time = int(time.time())
-            if device_info_qs.exists():  # 首先查询SIM卡绑定信息是否存在
-                iccid = device_info_qs.first().iccid
-                if device_info_qs.first().card_type == 1:  # 五兴电信
-                    data = {'iccids': iccid, 'operator': WXOperatorEnum.TELECOM.value}
-                    wx_tech = WXTechObject()
-                    res = wx_tech.delete_card_package(**data)
-                    if res['code'] == '0':
-                        UnicomComboExperienceHistory.objects.filter(iccid=iccid).delete()
-                        return response.json(0)
-                    return response.json(176)
-                flow_push_qs = UnicomFlowPush.objects.filter(serial_no=serial_number)
-                if flow_push_qs.exists():  # 删除流量预警推送
-                    flow_push_qs.delete()
-                sys_msg_qs = SysMsgModel.objects.filter(uid=serial_number)
-                if sys_msg_qs.exists():  # 删除有关系统消息数据
-                    sys_msg_qs.delete()
-                # 将4G用户信息状态改为已完成测试状态
-                device_info_qs.update(status=1, updated_time=now_time, user_id='')
-                combo_order_qs = UnicomComboOrderInfo.objects.filter(iccid=iccid)
-                if combo_order_qs.exists():
-                    combo_order_qs.delete()
-                combo_experience_history_qs = UnicomComboExperienceHistory.objects.filter(iccid=iccid)
-                if combo_experience_history_qs.exists():
-                    combo_experience_history_qs.delete()
-                UnicomObjeect().change_device_to_disable(iccid)  # 重置流量停用设备
-                ip = CommonService.get_ip_address(request)
-                describe = '重置4G流量序列号{},iccid:{}'.format(serial_number, iccid)
-                cls.generate_card_package_order(iccid, serial_number)
-                cls.create_operation_log('unicom/manage/resetCardPackage', ip, request_dict, describe)
-                return response.json(0)
-            return response.json(173)
-        except Exception as e:
-            LOGGER.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
-            return response.json(500)
-
-    @classmethod
-    def generate_card_package_order(cls, iccid, serial_number):
-        """
-        模拟设备上电赠送1G
-        @param iccid:
-        @param serial_number:
-        @return:
-        """
-        url = 'https://www.zositechc.cn/' if CONFIG_INFO == 'cn' else 'https://test.zositechc.cn/'
-        url = url + 'unicom/api/device-bind'
-        now_time = int(time.time())
-        sign = CommonService.encode_data(str(now_time))
-        data = {
-            'iccid': iccid,
-            'serialNo': serial_number,
-            'timeStamp': now_time,
-            'sign': sign,
-            'sim': 1
-        }
-        response = requests.post(url=url, data=data, timeout=5)
-        LOGGER.info(f"生成体验套餐结果:{json.loads(response.text)}")
-
-    @classmethod
-    def create_operation_log(cls, url, ip, request_dict, describe):
-        """
-        存入操作日志
-        @param url: 请求路径
-        @param describe: 描述
-        @param ip: 当前IP
-        @param request_dict: 请求参数
-        @return: True | False
-        """
-        try:
-            # 记录操作日志
-            content = json.loads(json.dumps(request_dict))
-            log = {
-                'ip': ip,
-                'user_id': 1,
-                'status': 200,
-                'time': int(time.time()),
-                'content': json.dumps(content),
-                'url': url,
-                'operation': describe,
-            }
-            LogModel.objects.create(**log)
-            return True
-        except Exception as e:
-            print('日志异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
-            return False
-
-    def get_user_info(self, request_dict, response):
-        """
-        获取/筛选卡用户信息
-        @param request_dict:
-        @param response:
-        @return:
-        NickName:用户昵称 phone: 电话
-        serial_no: 设备序列号
-        """
-        NickName = request_dict.get('NickName', None)
-        phone = request_dict.get('phone', None)
-        iccid = request_dict.get('iccid', None)
-        serial_no = request_dict.get('serialNo', None)
-        status = request_dict.get('status')
-        pageSize = request_dict.get('pageSize', None)
-        pageNo = request_dict.get('pageNo', None)
-
-        if not all({pageNo, pageSize}):
-            return response.json(444)
-        page = int(pageNo)
-        line = int(pageSize)
-
-        try:
-            unicom_device_qs = UnicomDeviceInfo.objects.all().order_by('-updated_time')
-            device_user_qs = Device_User.objects.filter().values(
-                'userID', 'NickName', 'phone')
-            if status:
-                unicom_device_qs = unicom_device_qs.filter(status=status)
-            if iccid:
-                unicom_device_qs = unicom_device_qs.filter(iccid__icontains=iccid)
-            if serial_no:
-                unicom_device_qs = unicom_device_qs.filter(serial_no__icontains=serial_no)
-            if NickName:
-                device_user_qs = device_user_qs.filter(NickName__icontains=NickName)
-                if not device_user_qs.exists():
-                    return response.json(0, [])
-                userID = device_user_qs.first()['userID']
-                unicom_device_qs = unicom_device_qs.filter(user_id=userID)
-            if phone:
-                device_user_qs = device_user_qs.filter(phone=phone)
-                if not device_user_qs.exists():
-                    return response.json(0, [])
-                userID = device_user_qs.first()['userID']
-                unicom_device_qs = unicom_device_qs.filter(user_id=userID)
-            total = unicom_device_qs.count()
-            unicom_device_qs = unicom_device_qs[(page - 1) * line:page * line]
-            list_data = []
-            for unicom_device in unicom_device_qs:
-                data = {'iccid': unicom_device.iccid, 'serialNo': unicom_device.serial_no,
-                        'userID': unicom_device.user_id, 'cardType': unicom_device.card_type,
-                        'status': unicom_device.status, 'mainCard': unicom_device.main_card,
-                        'createdTime': unicom_device.created_time, 'updatedTime': unicom_device.updated_time,
-                        'cardStatus': self.get_device_status_by_iccid(unicom_device.iccid, unicom_device.card_type)}
-                device_user_qs = Device_User.objects.filter(userID=unicom_device.user_id).values('username', 'NickName',
-                                                                                                 'phone')
-                data['userName'] = device_user_qs[0]['username'] if device_user_qs.exists() else ''
-                data['NickName'] = device_user_qs[0]['NickName'] if device_user_qs.exists() else ''
-                data['phone'] = device_user_qs[0]['phone'] if device_user_qs.exists() else ''
-                list_data.append(data)
-            return response.json(0, {'list': list_data, 'total': total})
-        except Exception as e:
-            print(e)
-            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
-
-    @staticmethod
-    def query_sql_4g():
-        """
-        4G关联查询SQL
-        @return: str
-        """
-        sql = 'SELECT '
-        sql += 'du.username,du.phone,o.UID as uid,o.`status`,udi.serial_no as serialNo,o.orderID,o.`desc`, '
-        sql += 'o.price,uo.next_month_activate as nextActivate,uo.iccid,uo.`status` as useStatus,uo.`flow_total_usage`,'
-        sql += 'uo.updated_time as upTime, uo.activation_time as acTime,uo.expire_time as epTime '
-        sql += 'FROM orders o '
-        sql += 'LEFT JOIN unicom_combo_order_info uo ON o.orderID = uo.order_id '
-        sql += 'INNER JOIN device_user du ON du.userID = o.userID_id '
-        sql += 'INNER JOIN unicom_device_info udi ON udi.iccid = uo.iccid '
-        return sql
-
-    @staticmethod
-    def query_4G_user_order(request_dict, response):
-        """
-        查询4G用户订单
-        """
-        try:
-            page = int(request_dict.get('pageNo', 1))
-            size = int(request_dict.get('pageSize', 10))
-            user_name = request_dict.get('userName', None)
-            uid = request_dict.get('uid', None)
-            serial_no = request_dict.get('serialNo', None)
-            combo_use_type = request_dict.get('comboUseType', None)
-            cursor = connection.cursor()
-            sql = UnicomManageControllerView.query_sql_4g()
-            sql += 'WHERE o.order_type = %s '
-            param_list = [2]
-            if user_name:
-                sql += "and du.username LIKE %s "
-                param_list.append(user_name)
-            if uid:
-                sql += "and o.UID LIKE %s "
-                param_list.append(uid)
-            if serial_no:
-                sql += "and udi.serial_no LIKE %s "
-                param_list.append(serial_no)
-            if combo_use_type:
-                sql += 'and uo.status = %s '
-                param_list.append(int(combo_use_type))
-            cursor.execute(sql, param_list)
-            total = len(cursor.fetchall())
-            param_list.append((page - 1) * size)
-            param_list.append(size, )
-            sql += 'order by o.addTime DESC LIMIT %s,%s '
-            cursor.execute(sql, param_list)
-            data_obj = cursor.fetchall()
-            cursor.close()  # 执行完,关闭
-            connection.close()
-            result_list = []
-            col_names = [desc[0] for desc in cursor.description]
-            for item in data_obj:
-                order_dict = dict(zip(col_names, item))
-                order_dict['using_total'] = 0
-                result_list.append(order_dict)
-            return response.json(0, {'orderList': result_list, 'total': total})
-        except Exception as e:
-            meg = '异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e))
-            return response.json(500, meg)
-
-    @staticmethod
-    def check_sim_user(iccid):
-        """
-        检查SIM卡用户
-        @param iccid:物联卡
-        @return:
-        """
-        u_device_qs = UnicomDeviceInfo.objects.filter(iccid=iccid).values('user_id')
-        if not u_device_qs.exists() or not u_device_qs[0]['user_id']:
-            return False
-        return True
-
-    @classmethod
-    def edit_combo(cls, request_dict, response):
-        """
-        添加和编辑卡套餐
-        @param request_dict:
-        @param response:
-        @return:
-        """
-        combo_id = request_dict.get('id', None)
-        combo_name = request_dict.get('comboName', None)
-        status = request_dict.get('status', None)
-        combo_type = request_dict.get('comboType', None)
-        flow_total = request_dict.get('flowTotal', None)
-        expiration_days = request_dict.get('expirationDays', None)
-        expiration_type = request_dict.get('expirationType', None)
-        pay_type = request_dict.get(
-            'payTypes', '')[
-                   1:-1].split(',')  # '[1,2]' -> ['1','2']
-        sort = request_dict.get('sort', None)
-        price = request_dict.get('price', None)
-        remark = request_dict.get('remark', None)
-        is_show = request_dict.get('isShow', None)
-        virtualPrice = request_dict.get('virtualPrice', None)
-
-        if not all([pay_type, price, is_show, status, combo_type, flow_total, expiration_days, expiration_type]):
-            return response.json(444)
-        flow_total = int(flow_total)
-        expiration_days = int(expiration_days)
-        expiration_type = int(expiration_type)
-        status = int(status)
-        combo_type = int(combo_type)
-        is_show = int(is_show)
-        sort = int(sort)
-        nowTime = int(time.time())
-
-        # 判断是编辑还是添加
-        with transaction.atomic():
-            try:
-                re_data = {
-                    'combo_name': combo_name,
-                    'status': status,
-                    'combo_type': combo_type,
-                    'flow_total': flow_total,
-                    'expiration_days': expiration_days,
-                    'expiration_type': expiration_type,
-                    'price': price,
-                    'sort': sort,
-                    'remark': remark if remark else '',
-                    'is_show': is_show,
-                    'virtual_price': virtualPrice,
-                }
-                if combo_id:
-                    combo_type_qs = UnicomCombo.objects.filter(id=combo_id)
-                    if not combo_type_qs.exists():
-                        return response.json(173)
-                    re_data['updated_time'] = nowTime
-                    combo_type_qs.filter(id=combo_id).update(**re_data)
-                    combo_type_qs.get(id=combo_id).pay_type.set(pay_type)
-                else:
-                    re_data['updated_time'] = int(time.time())
-                    re_data['created_time'] = int(time.time())
-                    UnicomCombo.objects.create(**re_data).pay_type.set(pay_type)
-                return response.json(0)
-            except Exception as e:
-                return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
-
-    @staticmethod
-    def get_unicom_info(request_dict, response):
-        """
-        获取套餐详细表
-        @param request_dict:
-        @param response:
-        @return:
-        """
-        pageNo = request_dict.get('pageNo', None)
-        pageSize = request_dict.get('pageSize', None)
-        if not all([pageNo, pageSize]):
-            return response.json(444)
-        elif pageNo and pageSize:
-            pass
-        page = int(pageNo)
-        line = int(pageSize)
-        try:
-            combo_qs = UnicomCombo.objects.filter(is_del=False) \
-                .values('id', 'status', 'combo_name',
-                        'flow_total', 'combo_type',
-                        'expiration_days',
-                        'expiration_type', 'price', 'is_unlimited',
-                        'updated_time', 'created_time',
-                        'remark', 'is_show', 'sort', 'virtual_price').order_by('sort')
-            if not combo_qs.exists():
-                return response.json(0, [])
-            total = combo_qs.count()
-            combo_qs = combo_qs[(page - 1) * line:page * line]
-            combo_list = []
-            for item in combo_qs:
-                # 获取支付方式列表
-                pay_type_list = [pay_type['id'] for pay_type in
-                                 UnicomCombo.objects.get(id=item['id']).pay_type.values('id')]
-                combo_list.append({
-                    'id': item['id'],
-                    'status': item['status'],
-                    'comboType': item['combo_type'],
-                    'comboName': item['combo_name'],
-                    'flowTotal': item['flow_total'],
-                    'expirationDays': item['expiration_days'],
-                    'expirationType': item['expiration_type'],
-                    'price': item['price'],
-                    'sort': item['sort'],
-                    'isUnlimited': item['is_unlimited'],
-                    'updatedTime': item['updated_time'],
-                    'createdTime': item['created_time'],
-                    'remark': item['remark'],
-                    'isShow': item['is_show'],
-                    'payTypes': pay_type_list,
-                    'virtualPrice': item['virtual_price']
-                })
-            return response.json(0, {'list': combo_list, 'total': total})
-        except Exception as e:
-            print(e)
-            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
-
-    @classmethod
-    def get_pay_type(cls, response):
-        """
-        获取支付类型
-        @param response:
-        @return:
-        """
-        pay_type_qs = Pay_Type.objects.all().values('id', 'payment')
-        if not pay_type_qs.exists():
-            return response.json(0, [])
-        pay_type_list = []
-        for pay_type in pay_type_qs:
-            pay_type_list.append(pay_type)
-        return response.json(0, pay_type_list)
-
-    @classmethod
-    def get_unicom_combo_type(cls, response):
-        """
-        获取赠送套餐
-        @param response:
-        @return:
-        """
-        unicom_combo_qs = UnicomCombo.objects.filter(combo_type=2, status=0).values('id', 'combo_name')
-        if not unicom_combo_qs.exists():
-            return response.json(0, [])
-        combo_list = []
-        for combo in unicom_combo_qs:
-            combo_list.append(combo)
-        return response.json(0, combo_list)
-
-    @classmethod
-    def combo_order_info(cls, request_dict, response):
-        """
-        删除卡套餐信息(修改状态)
-        @param request_dict
-        @param response
-        @return:
-        """
-        combo_id = request_dict.get('id', None)
-
-        if not combo_id:
-            return response.json(444)
-        combo_qs = UnicomCombo.objects.filter(id=combo_id)
-        #  只修改默认状态
-        if combo_qs.exists():
-            combo_qs.update(is_del=True)
-        return response.json(0)
-
-    def static_info(self, request_dict, response):
-        """
-        统计联通套餐
-        @param request_dict:请求参数
-        @param response: 响应对象
-        @param return:
-        """
-        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 = []
-        unicom_combo_qs = UnicomCombo.objects.filter().values('id', 'combo_type', 'combo_name')
-        if not unicom_combo_qs.exists():
-            return response.json(173)
-        try:
-            for unicom_combo in unicom_combo_qs:
-                name = unicom_combo['combo_name']
-                combo_order = UnicomComboOrderInfo.objects.filter(combo_id=unicom_combo['id'])
-                if not combo_order.exists():
-                    continue
-                Jan_count = combo_order.filter(created_time__range=[Jan, Feb]).count()
-                Feb_count = combo_order.filter(created_time__range=[Feb, Mar]).count()
-                Mar_count = combo_order.filter(created_time__range=[Mar, Apr]).count()
-                Apr_count = combo_order.filter(created_time__range=[Apr, May]).count()
-                May_count = combo_order.filter(created_time__range=[May, Jun]).count()
-                Jun_count = combo_order.filter(created_time__range=[Jun, Jul]).count()
-                Jul_count = combo_order.filter(created_time__range=[Jul, Aug]).count()
-                Aug_count = combo_order.filter(created_time__range=[Aug, Sep]).count()
-                Sep_count = combo_order.filter(created_time__range=[Sep, Oct]).count()
-                Oct_count = combo_order.filter(created_time__range=[Oct, Nov]).count()
-                Nov_count = combo_order.filter(created_time__range=[Nov, Dec]).count()
-                Dec_count = combo_order.filter(created_time__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, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
-
-    @classmethod
-    def get_flow_packages(cls, request_dict, response):
-        """
-        赠送套餐流量
-        @param request_dict:请求参数
-        @username request_dict:用户名
-        @comboType request_dict:套餐类型
-        @serialNo request_dict:序列号
-        @param response: 响应对象
-        @return:
-        """
-        userId = request_dict.get('userId', None)
-        serialNo = request_dict.get('serialNo', None)
-        comboId = request_dict.get('comboId', None)
-        if not all([userId, serialNo, comboId]):
-            return response.json(444)
-        try:
-            while transaction.atomic():
-                combo_info_qs = UnicomCombo.objects.filter(id=comboId, combo_type=2, status=0) \
-                    .values('id', 'combo_name', 'price', 'virtual_price', 'remark', 'combo_type')
-                unicom_device_info_qs = UnicomDeviceInfo.objects.filter(serial_no=serialNo,
-                                                                        user_id=userId).values \
-                    ('iccid')
-                if not unicom_device_info_qs.exists() or not combo_info_qs.exists():
-                    return response.json(173)
-                combo_info_qs = combo_info_qs.first()
-                unicom_device_info_qs = unicom_device_info_qs.first()
-                n_time = int(time.time())
-                order_id = CommonService.createOrderID()  # 生成订单号
-                #  赠送套餐下个月生效
-                unicom_combo = UnicomComboView.create_combo_order_info(order_id=order_id, activate_type=1,
-                                                                       iccid=unicom_device_info_qs['iccid'],
-                                                                       combo_id=comboId)
-                if unicom_combo is False:
-                    return response.json(178)
-                rank_id, ai_rank_id = UnicomComboView.get_cloud_or_ai_combo()  # 生成订单必须添加该字段
-                uid = CommonService.query_uid_with_serial(serialNo)  # 获取序列号或UID
-                # 获取套餐信息
-                order_dict = {
-                    'orderID': order_id,
-                    'UID': uid,
-                    'rank_id': rank_id,
-                    'ai_rank_id': ai_rank_id,
-                    'userID_id': userId,
-                    'desc': combo_info_qs['combo_name'],
-                    'payType': 10,
-                    'payTime': n_time,
-                    'price': combo_info_qs['price'],
-                    'addTime': n_time,
-                    'updTime': n_time,
-                    'status': 1,
-                    'unify_combo_id': str(combo_info_qs['id']),
-                    'order_type': 2,
-                    'store_meal_name': combo_info_qs['combo_name']
-                }
-                Order_Model.objects.create(**order_dict)
-                return response.json(0)
-        except Exception as e:
-            print(e)
-            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
-
-    @classmethod
-    def get_iccid_info(cls, request_dict, response):
-        """
-        获取联通iccid最新状态
-        """
-        try:
-            iccid = request_dict.get('iccid', None)
-            if not iccid:
-                return response.json(444)
-            re_data = {'iccid': iccid}
-            result = UnicomObjeect().query_device_status(**re_data)
-            res_dict = UnicomObjeect().get_text_dict(result)
-            # 状态不等于1(激活)时进行激活 1:激活;2:停用
-            return response.json(0, res_dict['data']['status'])
-        except Exception as e:
-            print(e)
-            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
-
-    @classmethod
-    def package_cdk_export_excel(cls, response):
-        """
-        流量包兑换码导出excel
-        """
-        try:
-            # 创建一个新的excel文档
-            wb = openpyxl.Workbook()
-            # 获取默认的工作表
-            sheet = wb.active
-            sheet.title = '周视国内流量年卡兑换码'
-            sheet.column_dimensions['A'].width = 15
-            sheet.column_dimensions['B'].width = 20
-            exchange_code = ExchangeCode.objects.filter(status=False, is_down=False)
-            if not exchange_code.exists():
-                return response.json(173)
-            # 将兑换码写入到excel表
-            for i, vo in enumerate(list(exchange_code)):
-                code_no = cls.fix_string_length(str(vo.id))
-                sheet.cell(row=i + 1, column=1, value=code_no)
-                sheet.cell(row=i + 1, column=2, value=vo.code)
-            filename = '国内流量年卡兑换码-{}.xlsx'.format(exchange_code.count())
-            # 创建一个http响应
-            res = HttpResponse(content_type='application/vnd.ms-excel')
-            # 设置响应头,告诉浏览器文件要下载而不是直接打开
-            res['Content-Disposition'] = 'attachment; filename={}'.format(filename)
-            # 将excel文档保存到http响应中
-            wb.save(res)
-            exchange_code.update(is_down=True, updated_time=int(time.time()))
-            return res
-        except Exception as e:
-            LOGGER.info('*****UnicomManageController.package_cdk_export_excel:errLine:{}, errMsg:{}'
-                        .format(e.__traceback__.tb_lineno, repr(e)))
-            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
-
-    @staticmethod
-    def fix_string_length(code_no):
-        """
-        将兑换码编号生成固定6位长度
-        """
-        if len(code_no) < 6:
-            return 'NO.' + code_no.rjust(6, '0')
-        else:
-            return 'NO.' + code_no
-
-    @classmethod
-    def create_package_cdk(cls, request_dict, response):
-        """
-        批量生成兑换码
-        """
-        try:
-            LOGGER.info('*****UnicomManageController.create_package_cdk,params:{}'.format(request_dict))
-            quantity = request_dict.get('quantity', None)
-            package_id = request_dict.get('packageId', None)
-            if not all([quantity, package_id]):
-                return response.json(444)
-            combo_qs = UnicomCombo.objects.filter(id=int(package_id))
-            if not combo_qs.exists():
-                return response.json(173)
-            combo = combo_qs.first()
-            exchange_code_list = []
-            now_time = int(time.time())
-            if combo.combo_type == 3:  # 五兴电信
-                for i in range(int(quantity)):
-                    # 10位兑换码 后面两位为标识代表五兴电信
-                    code = cls.generate_code() + 'WD'
-                    exchange_code_list.append(ExchangeCode(code=code, status=False, is_down=0,
-                                                           package_type=1, package_id=combo.id,
-                                                           expire_time=0,
-                                                           created_time=now_time,
-                                                           updated_time=now_time))
-            elif combo.combo_type == 0:  # 珠海联通
-                for i in range(int(quantity)):
-                    # 10位兑换码 后面两位为标识代表五兴电信
-                    code = cls.generate_code() + 'ZL'
-                    exchange_code_list.append(ExchangeCode(code=code, status=False, is_down=0,
-                                                           package_type=0, package_id=combo.id,
-                                                           expire_time=0,
-                                                           created_time=now_time,
-                                                           updated_time=now_time))
-            if exchange_code_list:
-                ExchangeCode.objects.bulk_create(exchange_code_list)
-                return response.json(0)
-            return response.json(178)
-        except Exception as e:
-            LOGGER.info('*****UnicomManageController.create_package_cdk:errLine:{}, errMsg:{}'
-                        .format(e.__traceback__.tb_lineno, repr(e)))
-            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
-
-    @classmethod
-    def generate_code(cls):
-        # 生成uuid并移除-
-        uuid_str = str(uuid.uuid4()).replace('-', '')
-        now_time = int(time.time())
-        uuid_str += str(now_time)
-        # 使用SHA1算法生成哈希值
-        sha1 = hashlib.sha1(uuid_str.encode('utf-8'))
-        # 取哈希值的前8位,并将其转换为大写字母
-        code = sha1.hexdigest()[:8].upper()
-        return code
-
-    @classmethod
-    def get_package_details(cls, request_dict, response):
-        """
-        根据序列号获取套餐包列表
-        """
-        serial_number = request_dict.get('serialNumber', None)
-        if not serial_number:
-            return response.json(444)
-        ud_qs = UnicomDeviceInfo.objects.filter(serial_no=serial_number) \
-            .values('iccid', 'card_type')
-        package_list = []
-        if not ud_qs.exists():
-            return response.json(0, {'packageList': package_list})
-        iccid = ud_qs[0]['iccid']
-        card_type = ud_qs[0]['card_type']
-        if card_type == 0:
-            o_qs = UnicomComboOrderInfo.objects.filter(iccid=iccid) \
-                .values('status', 'flow_total_usage', 'flow_exceed', 'activation_time', 'expire_time',
-                        'combo__combo_name', 'combo__flow_total', 'updated_time') \
-                .order_by('created_time')
-            if not o_qs:
-                return response.json(0, {'packageList': package_list})
-            return response.json(0, {'package_list': cls.get_unicom_package_list(iccid, o_qs)})
-        if card_type == 1:
-            data = {'iccid': iccid, 'operator': 3}
-            return response.json(0, {'package_list': cls.get_wx_package_list(**data)})
-
-    @staticmethod
-    def get_unicom_package_list(iccid, o_qs):
-        package_list = []
-        unicom_api = UnicomObjeect()
-        for i, item in enumerate(o_qs):
-            package_status = item['status']
-            flow_total = item['combo__flow_total']
-            flow_total_usage = float(unicom_api.get_flow_usage_total(iccid))
-            activate_flow = float(item['flow_total_usage']) if item['flow_total_usage'] else 0
-            used = 0
-            if package_status == 1:
-                used = flow_total_usage - activate_flow  # 已用流量
-            elif package_status == 2:
-                index = i + 1
-                if index < len(o_qs) and o_qs[index]['flow_total_usage']:
-                    package_used_flow = float(o_qs[i + 1]['flow_total_usage'])
-                    used = package_used_flow - activate_flow
-                else:
-                    used = flow_total_usage - activate_flow
-            status_dict = {0: "待使用", 1: "使用中", 2: "已失效"}
-            status = status_dict.get(item['status'])
-            package_list.append({
-                'packageName': item['combo__combo_name'],
-                'status': status,
-                'flowTotal': flow_total,
-                'used': Decimal(used).quantize(Decimal('0.00')),
-                'activationTime': datetime.datetime.fromtimestamp(item['activation_time']).strftime(
-                    '%Y-%m-%d %H:%M:%S'),
-                'expireTime': datetime.datetime.fromtimestamp(item['expire_time']).strftime('%Y-%m-%d %H:%M:%S'),
-                'updatedTime': datetime.datetime.fromtimestamp(item['updated_time']).strftime('%Y-%m-%d %H:%M:%S')
-            })
-        return package_list
-
-    @staticmethod
-    def get_wx_package_list(**data):
-        """
-        获取五兴套餐订购记录
-        @param data: iccid,operator
-        @return: 订购记录结果
-        """
-        try:
-            package_list = []
-            wx_tech = WXTechObject()
-            result = wx_tech.get_package_order_record(**data)
-            if not result:
-                return package_list
-            status_dict = {0: "待使用", 1: "使用中", 2: "已完成", 3: "已退订", 4: "已失效", 5: "已删除"}
-            for item in result['data']:
-                used_flow = float(item['flowTotal']) - float(item['flowRemain'])
-                package_list.append({
-                    'packageName': item['packageName'],
-                    'status': status_dict.get(int(item['state'])),
-                    'flowTotal': item['flowTotal'],
-                    'used': Decimal(used_flow).quantize(Decimal('0.00')),
-                    'activationTime': item['startDate'],
-                    'expireTime': item['endDate'],
-                    'updatedTime': ''
-                })
-            return package_list
-        except Exception as e:
-            print(repr(e))
-            return []
-
-    @staticmethod
-    def get_device_status_by_iccid(iccid, card_type):
-        try:
-            re_data = {'iccid': iccid}
-            if card_type == 0:
-                status_dict = {1: '已激活', 2: '可激活', 3: '已停用', 4: '已失效', 5: '可测试', 6: '库存', 7: '已更换', 8: '已清除'}
-                result = UnicomObjeect().query_device_status(**re_data)
-                res_dict = UnicomObjeect().get_text_dict(result)
-                return status_dict.get(int(res_dict['data']['status']), 'N/A')
-            elif card_type == 1:
-                status_dict = {1: '库存', 2: '可激活', 3: '已激活', 4: '已停用', 5: '已失效', 6: '强制停机'}
-                data = {'iccid': iccid, 'operator': 3}
-                wx_tech = WXTechObject()
-                result = wx_tech.get_cards_info(**data)
-                return status_dict.get(int(result['data']['cardStatusCode']), 'N/A')
-            else:
-                return 'N/A'
-        except Exception as e:
-            print(repr(e))
-            return 'N/A'
+# Copyright (C) 2022 #
+# @Time    : 2022/7/18 16:16
+# @Author  : ghl
+# @Email   : Guanhailogn@asj6.wecom.work
+# @File    : UnicomManageController.py
+# @Software: PyCharm
+import datetime
+import hashlib
+import json
+import time
+import uuid
+from decimal import Decimal
+
+import openpyxl
+import requests
+from django.db import transaction, connection
+from django.http import HttpResponse
+from django.views.generic.base import View
+
+from Ansjer.config import CONFIG_INFO
+from Ansjer.config import LOGGER
+from Controller.UnicomCombo.UnicomComboController import UnicomComboView
+from Model.models import UnicomDeviceInfo, UnicomCombo, Pay_Type, UnicomComboOrderInfo, Device_User, Order_Model, \
+    ExchangeCode, UnicomFlowPush, SysMsgModel, UnicomComboExperienceHistory, LogModel
+from Object.Enums.WXOperatorEnum import WXOperatorEnum
+from Object.ResponseObject import ResponseObject
+from Object.TokenObject import TokenObject
+from Object.UnicomObject import UnicomObjeect
+from Object.WXTechObject import WXTechObject
+from Service.CommonService import CommonService
+
+
+class UnicomManageControllerView(View):
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.GET, request, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.POST, request, operation)
+
+    def validation(self, request_dict, request, operation):
+        response = ResponseObject()
+        # 获取支付类型
+        if operation == 'get/pay':
+            return self.get_pay_type(response)
+        # 获取套餐类型
+        elif operation == 'combo/type':
+            return self.get_unicom_combo_type(response)
+        elif operation == 'downloadCDK':  # 下载兑换码
+            return self.package_cdk_export_excel(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 == 'get/deta/info':
+                return self.get_unicom_info(request_dict, response)
+            # 添加和编辑卡套餐
+            elif operation == 'edit/combo':
+                return self.edit_combo(request_dict, response)
+            # 统计4G套餐
+            elif operation == 'getComboDataList':
+                return self.static_info(request_dict, response)
+            # 删除卡套餐
+            elif operation == 'dele/combo/info':
+                return self.combo_order_info(request_dict, response)
+            # 获取/筛选用户信息
+            elif operation == 'filter/user':
+                return self.get_user_info(request_dict, response)
+            # 充值流量
+            elif operation == 'getFlowPackages':
+                return self.get_flow_packages(request_dict, response)
+            #  获取/筛选4G流量卡订单信息
+            elif operation == 'query-order':
+                return self.query_4G_user_order(request_dict, response)
+            elif operation == 'sim-info':
+                return self.get_iccid_info(request_dict, response)
+            elif operation == 'batchGenerateCDK':  # 批量生成兑换码
+                return self.create_package_cdk(request_dict, response)
+            elif operation == 'resetCardPackage':
+                return self.reset_card_package(request, request_dict, response)
+            elif operation == 'getPackageDetails':
+                return self.get_package_details(request_dict, response)
+            else:
+                return response.json(404)
+
+    @classmethod
+    def reset_card_package(cls, request, request_dict, response):
+        try:
+            serial_number = request_dict.get('serialNumber', None)
+            if not serial_number:
+                return response.json(444)
+            device_info_qs = UnicomDeviceInfo.objects.filter(serial_no=serial_number)
+            now_time = int(time.time())
+            if device_info_qs.exists():  # 首先查询SIM卡绑定信息是否存在
+                iccid = device_info_qs.first().iccid
+                if device_info_qs.first().card_type == 1:  # 五兴电信
+                    data = {'iccids': iccid, 'operator': WXOperatorEnum.TELECOM.value}
+                    wx_tech = WXTechObject()
+                    res = wx_tech.delete_card_package(**data)
+                    if res['code'] == '0':
+                        UnicomComboExperienceHistory.objects.filter(iccid=iccid).delete()
+                        return response.json(0)
+                    return response.json(176)
+                flow_push_qs = UnicomFlowPush.objects.filter(serial_no=serial_number)
+                if flow_push_qs.exists():  # 删除流量预警推送
+                    flow_push_qs.delete()
+                sys_msg_qs = SysMsgModel.objects.filter(uid=serial_number)
+                if sys_msg_qs.exists():  # 删除有关系统消息数据
+                    sys_msg_qs.delete()
+                # 将4G用户信息状态改为已完成测试状态
+                device_info_qs.update(status=1, updated_time=now_time, user_id='')
+                combo_order_qs = UnicomComboOrderInfo.objects.filter(iccid=iccid)
+                if combo_order_qs.exists():
+                    combo_order_qs.delete()
+                combo_experience_history_qs = UnicomComboExperienceHistory.objects.filter(iccid=iccid)
+                if combo_experience_history_qs.exists():
+                    combo_experience_history_qs.delete()
+                UnicomObjeect().change_device_to_disable(iccid)  # 重置流量停用设备
+                ip = CommonService.get_ip_address(request)
+                describe = '重置4G流量序列号{},iccid:{}'.format(serial_number, iccid)
+                cls.generate_card_package_order(iccid, serial_number)
+                cls.create_operation_log('unicom/manage/resetCardPackage', ip, request_dict, describe)
+                return response.json(0)
+            return response.json(173)
+        except Exception as e:
+            LOGGER.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            return response.json(500)
+
+    @classmethod
+    def generate_card_package_order(cls, iccid, serial_number):
+        """
+        模拟设备上电赠送1G
+        @param iccid:
+        @param serial_number:
+        @return:
+        """
+        url = 'https://www.zositechc.cn/' if CONFIG_INFO == 'cn' else 'https://test.zositechc.cn/'
+        url = url + 'unicom/api/device-bind'
+        now_time = int(time.time())
+        sign = CommonService.encode_data(str(now_time))
+        data = {
+            'iccid': iccid,
+            'serialNo': serial_number,
+            'timeStamp': now_time,
+            'sign': sign,
+            'sim': 1
+        }
+        response = requests.post(url=url, data=data, timeout=5)
+        LOGGER.info(f"生成体验套餐结果:{json.loads(response.text)}")
+
+    @classmethod
+    def create_operation_log(cls, url, ip, request_dict, describe):
+        """
+        存入操作日志
+        @param url: 请求路径
+        @param describe: 描述
+        @param ip: 当前IP
+        @param request_dict: 请求参数
+        @return: True | False
+        """
+        try:
+            # 记录操作日志
+            content = json.loads(json.dumps(request_dict))
+            log = {
+                'ip': ip,
+                'user_id': 1,
+                'status': 200,
+                'time': int(time.time()),
+                'content': json.dumps(content),
+                'url': url,
+                'operation': describe,
+            }
+            LogModel.objects.create(**log)
+            return True
+        except Exception as e:
+            print('日志异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            return False
+
+    def get_user_info(self, request_dict, response):
+        """
+        获取/筛选卡用户信息
+        @param request_dict:
+        @param response:
+        @return:
+        NickName:用户昵称 phone: 电话
+        serial_no: 设备序列号
+        """
+        NickName = request_dict.get('NickName', None)
+        phone = request_dict.get('phone', None)
+        iccid = request_dict.get('iccid', None)
+        serial_no = request_dict.get('serialNo', None)
+        status = request_dict.get('status')
+        pageSize = request_dict.get('pageSize', None)
+        pageNo = request_dict.get('pageNo', None)
+
+        if not all({pageNo, pageSize}):
+            return response.json(444)
+        page = int(pageNo)
+        line = int(pageSize)
+
+        try:
+            unicom_device_qs = UnicomDeviceInfo.objects.all().order_by('-updated_time')
+            device_user_qs = Device_User.objects.filter().values(
+                'userID', 'NickName', 'phone')
+            if status:
+                unicom_device_qs = unicom_device_qs.filter(status=status)
+            if iccid:
+                unicom_device_qs = unicom_device_qs.filter(iccid__icontains=iccid)
+            if serial_no:
+                unicom_device_qs = unicom_device_qs.filter(serial_no__icontains=serial_no)
+            if NickName:
+                device_user_qs = device_user_qs.filter(NickName__icontains=NickName)
+                if not device_user_qs.exists():
+                    return response.json(0, [])
+                userID = device_user_qs.first()['userID']
+                unicom_device_qs = unicom_device_qs.filter(user_id=userID)
+            if phone:
+                device_user_qs = device_user_qs.filter(phone=phone)
+                if not device_user_qs.exists():
+                    return response.json(0, [])
+                userID = device_user_qs.first()['userID']
+                unicom_device_qs = unicom_device_qs.filter(user_id=userID)
+            total = unicom_device_qs.count()
+            unicom_device_qs = unicom_device_qs[(page - 1) * line:page * line]
+            list_data = []
+            for unicom_device in unicom_device_qs:
+                data = {'iccid': unicom_device.iccid, 'serialNo': unicom_device.serial_no,
+                        'userID': unicom_device.user_id, 'cardType': unicom_device.card_type,
+                        'status': unicom_device.status, 'mainCard': unicom_device.main_card,
+                        'createdTime': unicom_device.created_time, 'updatedTime': unicom_device.updated_time,
+                        'cardStatus': self.get_device_status_by_iccid(unicom_device.iccid, unicom_device.card_type)}
+                device_user_qs = Device_User.objects.filter(userID=unicom_device.user_id).values('username', 'NickName',
+                                                                                                 'phone')
+                data['userName'] = device_user_qs[0]['username'] if device_user_qs.exists() else ''
+                data['NickName'] = device_user_qs[0]['NickName'] if device_user_qs.exists() else ''
+                data['phone'] = device_user_qs[0]['phone'] if device_user_qs.exists() else ''
+                list_data.append(data)
+            return response.json(0, {'list': list_data, 'total': total})
+        except Exception as e:
+            print(e)
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
+    @staticmethod
+    def query_sql_4g():
+        """
+        4G关联查询SQL
+        @return: str
+        """
+        sql = 'SELECT '
+        sql += 'du.username,du.phone,o.UID as uid,o.`status`,udi.serial_no as serialNo,o.orderID,o.`desc`, '
+        sql += 'o.price,uo.next_month_activate as nextActivate,uo.iccid,uo.`status` as useStatus,uo.`flow_total_usage`,'
+        sql += 'uo.updated_time as upTime, uo.activation_time as acTime,uo.expire_time as epTime '
+        sql += 'FROM orders o '
+        sql += 'LEFT JOIN unicom_combo_order_info uo ON o.orderID = uo.order_id '
+        sql += 'INNER JOIN device_user du ON du.userID = o.userID_id '
+        sql += 'INNER JOIN unicom_device_info udi ON udi.iccid = uo.iccid '
+        return sql
+
+    @staticmethod
+    def query_4G_user_order(request_dict, response):
+        """
+        查询4G用户订单
+        """
+        try:
+            page = int(request_dict.get('pageNo', 1))
+            size = int(request_dict.get('pageSize', 10))
+            user_name = request_dict.get('userName', None)
+            uid = request_dict.get('uid', None)
+            serial_no = request_dict.get('serialNo', None)
+            combo_use_type = request_dict.get('comboUseType', None)
+            cursor = connection.cursor()
+            sql = UnicomManageControllerView.query_sql_4g()
+            sql += 'WHERE o.order_type = %s '
+            param_list = [2]
+            if user_name:
+                sql += "and du.username LIKE %s "
+                param_list.append(user_name)
+            if uid:
+                sql += "and o.UID LIKE %s "
+                param_list.append(uid)
+            if serial_no:
+                sql += "and udi.serial_no LIKE %s "
+                param_list.append(serial_no)
+            if combo_use_type:
+                sql += 'and uo.status = %s '
+                param_list.append(int(combo_use_type))
+            cursor.execute(sql, param_list)
+            total = len(cursor.fetchall())
+            param_list.append((page - 1) * size)
+            param_list.append(size, )
+            sql += 'order by o.addTime DESC LIMIT %s,%s '
+            cursor.execute(sql, param_list)
+            data_obj = cursor.fetchall()
+            cursor.close()  # 执行完,关闭
+            connection.close()
+            result_list = []
+            col_names = [desc[0] for desc in cursor.description]
+            for item in data_obj:
+                order_dict = dict(zip(col_names, item))
+                order_dict['using_total'] = 0
+                result_list.append(order_dict)
+            return response.json(0, {'orderList': result_list, 'total': total})
+        except Exception as e:
+            meg = '异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e))
+            return response.json(500, meg)
+
+    @staticmethod
+    def check_sim_user(iccid):
+        """
+        检查SIM卡用户
+        @param iccid:物联卡
+        @return:
+        """
+        u_device_qs = UnicomDeviceInfo.objects.filter(iccid=iccid).values('user_id')
+        if not u_device_qs.exists() or not u_device_qs[0]['user_id']:
+            return False
+        return True
+
+    @classmethod
+    def edit_combo(cls, request_dict, response):
+        """
+        添加和编辑卡套餐
+        @param request_dict:
+        @param response:
+        @return:
+        """
+        combo_id = request_dict.get('id', None)
+        combo_name = request_dict.get('comboName', None)
+        status = request_dict.get('status', None)
+        combo_type = request_dict.get('comboType', None)
+        flow_total = request_dict.get('flowTotal', None)
+        expiration_days = request_dict.get('expirationDays', None)
+        expiration_type = request_dict.get('expirationType', None)
+        pay_type = request_dict.get(
+            'payTypes', '')[
+                   1:-1].split(',')  # '[1,2]' -> ['1','2']
+        sort = request_dict.get('sort', None)
+        price = request_dict.get('price', None)
+        remark = request_dict.get('remark', None)
+        is_show = request_dict.get('isShow', None)
+        virtualPrice = request_dict.get('virtualPrice', None)
+
+        if not all([pay_type, price, is_show, status, combo_type, flow_total, expiration_days, expiration_type]):
+            return response.json(444)
+        flow_total = int(flow_total)
+        expiration_days = int(expiration_days)
+        expiration_type = int(expiration_type)
+        status = int(status)
+        combo_type = int(combo_type)
+        is_show = int(is_show)
+        sort = int(sort)
+        nowTime = int(time.time())
+
+        # 判断是编辑还是添加
+        with transaction.atomic():
+            try:
+                re_data = {
+                    'combo_name': combo_name,
+                    'status': status,
+                    'combo_type': combo_type,
+                    'flow_total': flow_total,
+                    'expiration_days': expiration_days,
+                    'expiration_type': expiration_type,
+                    'price': price,
+                    'sort': sort,
+                    'remark': remark if remark else '',
+                    'is_show': is_show,
+                    'virtual_price': virtualPrice,
+                }
+                if combo_id:
+                    combo_type_qs = UnicomCombo.objects.filter(id=combo_id)
+                    if not combo_type_qs.exists():
+                        return response.json(173)
+                    re_data['updated_time'] = nowTime
+                    combo_type_qs.filter(id=combo_id).update(**re_data)
+                    combo_type_qs.get(id=combo_id).pay_type.set(pay_type)
+                else:
+                    re_data['updated_time'] = int(time.time())
+                    re_data['created_time'] = int(time.time())
+                    UnicomCombo.objects.create(**re_data).pay_type.set(pay_type)
+                return response.json(0)
+            except Exception as e:
+                return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
+    @staticmethod
+    def get_unicom_info(request_dict, response):
+        """
+        获取套餐详细表
+        @param request_dict:
+        @param response:
+        @return:
+        """
+        pageNo = request_dict.get('pageNo', None)
+        pageSize = request_dict.get('pageSize', None)
+        if not all([pageNo, pageSize]):
+            return response.json(444)
+        elif pageNo and pageSize:
+            pass
+        page = int(pageNo)
+        line = int(pageSize)
+        try:
+            combo_qs = UnicomCombo.objects.filter(is_del=False) \
+                .values('id', 'status', 'combo_name',
+                        'flow_total', 'combo_type',
+                        'expiration_days',
+                        'expiration_type', 'price', 'is_unlimited',
+                        'updated_time', 'created_time',
+                        'remark', 'is_show', 'sort', 'virtual_price').order_by('sort')
+            if not combo_qs.exists():
+                return response.json(0, [])
+            total = combo_qs.count()
+            combo_qs = combo_qs[(page - 1) * line:page * line]
+            combo_list = []
+            for item in combo_qs:
+                # 获取支付方式列表
+                pay_type_list = [pay_type['id'] for pay_type in
+                                 UnicomCombo.objects.get(id=item['id']).pay_type.values('id')]
+                combo_list.append({
+                    'id': item['id'],
+                    'status': item['status'],
+                    'comboType': item['combo_type'],
+                    'comboName': item['combo_name'],
+                    'flowTotal': item['flow_total'],
+                    'expirationDays': item['expiration_days'],
+                    'expirationType': item['expiration_type'],
+                    'price': item['price'],
+                    'sort': item['sort'],
+                    'isUnlimited': item['is_unlimited'],
+                    'updatedTime': item['updated_time'],
+                    'createdTime': item['created_time'],
+                    'remark': item['remark'],
+                    'isShow': item['is_show'],
+                    'payTypes': pay_type_list,
+                    'virtualPrice': item['virtual_price']
+                })
+            return response.json(0, {'list': combo_list, 'total': total})
+        except Exception as e:
+            print(e)
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
+    @classmethod
+    def get_pay_type(cls, response):
+        """
+        获取支付类型
+        @param response:
+        @return:
+        """
+        pay_type_qs = Pay_Type.objects.all().values('id', 'payment')
+        if not pay_type_qs.exists():
+            return response.json(0, [])
+        pay_type_list = []
+        for pay_type in pay_type_qs:
+            pay_type_list.append(pay_type)
+        return response.json(0, pay_type_list)
+
+    @classmethod
+    def get_unicom_combo_type(cls, response):
+        """
+        获取赠送套餐
+        @param response:
+        @return:
+        """
+        unicom_combo_qs = UnicomCombo.objects.filter(combo_type=2, status=0).values('id', 'combo_name')
+        if not unicom_combo_qs.exists():
+            return response.json(0, [])
+        combo_list = []
+        for combo in unicom_combo_qs:
+            combo_list.append(combo)
+        return response.json(0, combo_list)
+
+    @classmethod
+    def combo_order_info(cls, request_dict, response):
+        """
+        删除卡套餐信息(修改状态)
+        @param request_dict
+        @param response
+        @return:
+        """
+        combo_id = request_dict.get('id', None)
+
+        if not combo_id:
+            return response.json(444)
+        combo_qs = UnicomCombo.objects.filter(id=combo_id)
+        #  只修改默认状态
+        if combo_qs.exists():
+            combo_qs.update(is_del=True)
+        return response.json(0)
+
+    def static_info(self, request_dict, response):
+        """
+        统计联通套餐
+        @param request_dict:请求参数
+        @param response: 响应对象
+        @param return:
+        """
+        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 = []
+        unicom_combo_qs = UnicomCombo.objects.filter().values('id', 'combo_type', 'combo_name')
+        if not unicom_combo_qs.exists():
+            return response.json(173)
+        try:
+            for unicom_combo in unicom_combo_qs:
+                name = unicom_combo['combo_name']
+                combo_order = UnicomComboOrderInfo.objects.filter(combo_id=unicom_combo['id'])
+                if not combo_order.exists():
+                    continue
+                Jan_count = combo_order.filter(created_time__range=[Jan, Feb]).count()
+                Feb_count = combo_order.filter(created_time__range=[Feb, Mar]).count()
+                Mar_count = combo_order.filter(created_time__range=[Mar, Apr]).count()
+                Apr_count = combo_order.filter(created_time__range=[Apr, May]).count()
+                May_count = combo_order.filter(created_time__range=[May, Jun]).count()
+                Jun_count = combo_order.filter(created_time__range=[Jun, Jul]).count()
+                Jul_count = combo_order.filter(created_time__range=[Jul, Aug]).count()
+                Aug_count = combo_order.filter(created_time__range=[Aug, Sep]).count()
+                Sep_count = combo_order.filter(created_time__range=[Sep, Oct]).count()
+                Oct_count = combo_order.filter(created_time__range=[Oct, Nov]).count()
+                Nov_count = combo_order.filter(created_time__range=[Nov, Dec]).count()
+                Dec_count = combo_order.filter(created_time__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, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
+    @classmethod
+    def get_flow_packages(cls, request_dict, response):
+        """
+        赠送套餐流量
+        @param request_dict:请求参数
+        @username request_dict:用户名
+        @comboType request_dict:套餐类型
+        @serialNo request_dict:序列号
+        @param response: 响应对象
+        @return:
+        """
+        userId = request_dict.get('userId', None)
+        serialNo = request_dict.get('serialNo', None)
+        comboId = request_dict.get('comboId', None)
+        if not all([userId, serialNo, comboId]):
+            return response.json(444)
+        try:
+            while transaction.atomic():
+                combo_info_qs = UnicomCombo.objects.filter(id=comboId, combo_type=2, status=0) \
+                    .values('id', 'combo_name', 'price', 'virtual_price', 'remark', 'combo_type')
+                unicom_device_info_qs = UnicomDeviceInfo.objects.filter(serial_no=serialNo,
+                                                                        user_id=userId).values \
+                    ('iccid')
+                if not unicom_device_info_qs.exists() or not combo_info_qs.exists():
+                    return response.json(173)
+                combo_info_qs = combo_info_qs.first()
+                unicom_device_info_qs = unicom_device_info_qs.first()
+                n_time = int(time.time())
+                order_id = CommonService.createOrderID()  # 生成订单号
+                #  赠送套餐下个月生效
+                unicom_combo = UnicomComboView.create_combo_order_info(order_id=order_id, activate_type=1,
+                                                                       iccid=unicom_device_info_qs['iccid'],
+                                                                       combo_id=comboId)
+                if unicom_combo is False:
+                    return response.json(178)
+                rank_id, ai_rank_id = UnicomComboView.get_cloud_or_ai_combo()  # 生成订单必须添加该字段
+                uid = CommonService.query_uid_with_serial(serialNo)  # 获取序列号或UID
+                # 获取套餐信息
+                order_dict = {
+                    'orderID': order_id,
+                    'UID': uid,
+                    'rank_id': rank_id,
+                    'ai_rank_id': ai_rank_id,
+                    'userID_id': userId,
+                    'desc': combo_info_qs['combo_name'],
+                    'payType': 10,
+                    'payTime': n_time,
+                    'price': combo_info_qs['price'],
+                    'addTime': n_time,
+                    'updTime': n_time,
+                    'status': 1,
+                    'unify_combo_id': str(combo_info_qs['id']),
+                    'order_type': 2,
+                    'store_meal_name': combo_info_qs['combo_name']
+                }
+                Order_Model.objects.create(**order_dict)
+                return response.json(0)
+        except Exception as e:
+            print(e)
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
+    @classmethod
+    def get_iccid_info(cls, request_dict, response):
+        """
+        获取联通iccid最新状态
+        """
+        try:
+            iccid = request_dict.get('iccid', None)
+            if not iccid:
+                return response.json(444)
+            re_data = {'iccid': iccid}
+            result = UnicomObjeect().query_device_status(**re_data)
+            res_dict = UnicomObjeect().get_text_dict(result)
+            # 状态不等于1(激活)时进行激活 1:激活;2:停用
+            return response.json(0, res_dict['data']['status'])
+        except Exception as e:
+            print(e)
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
+    @classmethod
+    def package_cdk_export_excel(cls, response):
+        """
+        流量包兑换码导出excel
+        """
+        try:
+            # 创建一个新的excel文档
+            wb = openpyxl.Workbook()
+            # 获取默认的工作表
+            sheet = wb.active
+            sheet.title = '周视国内流量年卡兑换码'
+            sheet.column_dimensions['A'].width = 15
+            sheet.column_dimensions['B'].width = 20
+            exchange_code = ExchangeCode.objects.filter(status=False, is_down=False)
+            if not exchange_code.exists():
+                return response.json(173)
+            # 将兑换码写入到excel表
+            for i, vo in enumerate(list(exchange_code)):
+                code_no = cls.fix_string_length(str(vo.id))
+                sheet.cell(row=i + 1, column=1, value=code_no)
+                sheet.cell(row=i + 1, column=2, value=vo.code)
+            filename = '国内流量年卡兑换码-{}.xlsx'.format(exchange_code.count())
+            # 创建一个http响应
+            res = HttpResponse(content_type='application/vnd.ms-excel')
+            # 设置响应头,告诉浏览器文件要下载而不是直接打开
+            res['Content-Disposition'] = 'attachment; filename={}'.format(filename)
+            # 将excel文档保存到http响应中
+            wb.save(res)
+            exchange_code.update(is_down=True, updated_time=int(time.time()))
+            return res
+        except Exception as e:
+            LOGGER.info('*****UnicomManageController.package_cdk_export_excel:errLine:{}, errMsg:{}'
+                        .format(e.__traceback__.tb_lineno, repr(e)))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
+    @staticmethod
+    def fix_string_length(code_no):
+        """
+        将兑换码编号生成固定6位长度
+        """
+        if len(code_no) < 6:
+            return 'NO.' + code_no.rjust(6, '0')
+        else:
+            return 'NO.' + code_no
+
+    @classmethod
+    def create_package_cdk(cls, request_dict, response):
+        """
+        批量生成兑换码
+        """
+        try:
+            LOGGER.info('*****UnicomManageController.create_package_cdk,params:{}'.format(request_dict))
+            quantity = request_dict.get('quantity', None)
+            package_id = request_dict.get('packageId', None)
+            if not all([quantity, package_id]):
+                return response.json(444)
+            combo_qs = UnicomCombo.objects.filter(id=int(package_id))
+            if not combo_qs.exists():
+                return response.json(173)
+            combo = combo_qs.first()
+            exchange_code_list = []
+            now_time = int(time.time())
+            if combo.combo_type == 3:  # 五兴电信
+                for i in range(int(quantity)):
+                    # 10位兑换码 后面两位为标识代表五兴电信
+                    code = cls.generate_code() + 'WD'
+                    exchange_code_list.append(ExchangeCode(code=code, status=False, is_down=0,
+                                                           package_type=1, package_id=combo.id,
+                                                           expire_time=0,
+                                                           created_time=now_time,
+                                                           updated_time=now_time))
+            elif combo.combo_type == 0:  # 珠海联通
+                for i in range(int(quantity)):
+                    # 10位兑换码 后面两位为标识代表五兴电信
+                    code = cls.generate_code() + 'ZL'
+                    exchange_code_list.append(ExchangeCode(code=code, status=False, is_down=0,
+                                                           package_type=0, package_id=combo.id,
+                                                           expire_time=0,
+                                                           created_time=now_time,
+                                                           updated_time=now_time))
+            if exchange_code_list:
+                ExchangeCode.objects.bulk_create(exchange_code_list)
+                return response.json(0)
+            return response.json(178)
+        except Exception as e:
+            LOGGER.info('*****UnicomManageController.create_package_cdk:errLine:{}, errMsg:{}'
+                        .format(e.__traceback__.tb_lineno, repr(e)))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
+    @classmethod
+    def generate_code(cls):
+        # 生成uuid并移除-
+        uuid_str = str(uuid.uuid4()).replace('-', '')
+        now_time = int(time.time())
+        uuid_str += str(now_time)
+        # 使用SHA1算法生成哈希值
+        sha1 = hashlib.sha1(uuid_str.encode('utf-8'))
+        # 取哈希值的前8位,并将其转换为大写字母
+        code = sha1.hexdigest()[:8].upper()
+        return code
+
+    @classmethod
+    def get_package_details(cls, request_dict, response):
+        """
+        根据序列号获取套餐包列表
+        """
+        serial_number = request_dict.get('serialNumber', None)
+        if not serial_number:
+            return response.json(444)
+        ud_qs = UnicomDeviceInfo.objects.filter(serial_no=serial_number) \
+            .values('iccid', 'card_type')
+        package_list = []
+        if not ud_qs.exists():
+            return response.json(0, {'packageList': package_list})
+        iccid = ud_qs[0]['iccid']
+        card_type = ud_qs[0]['card_type']
+        if card_type == 0:
+            o_qs = UnicomComboOrderInfo.objects.filter(iccid=iccid) \
+                .values('status', 'flow_total_usage', 'flow_exceed', 'activation_time', 'expire_time',
+                        'combo__combo_name', 'combo__flow_total', 'updated_time') \
+                .order_by('created_time')
+            if not o_qs:
+                return response.json(0, {'packageList': package_list})
+            return response.json(0, {'package_list': cls.get_unicom_package_list(iccid, o_qs)})
+        if card_type == 1:
+            data = {'iccid': iccid, 'operator': 3}
+            return response.json(0, {'package_list': cls.get_wx_package_list(**data)})
+        return response.json(0, {'package_list': package_list})
+
+    @staticmethod
+    def get_unicom_package_list(iccid, o_qs):
+        package_list = []
+        unicom_api = UnicomObjeect()
+        for i, item in enumerate(o_qs):
+            package_status = item['status']
+            flow_total = item['combo__flow_total']
+            flow_total_usage = float(unicom_api.get_flow_usage_total(iccid))
+            activate_flow = float(item['flow_total_usage']) if item['flow_total_usage'] else 0
+            used = 0
+            if package_status == 1:
+                used = flow_total_usage - activate_flow  # 已用流量
+            elif package_status == 2:
+                index = i + 1
+                if index < len(o_qs) and o_qs[index]['flow_total_usage']:
+                    package_used_flow = float(o_qs[i + 1]['flow_total_usage'])
+                    used = package_used_flow - activate_flow
+                else:
+                    used = flow_total_usage - activate_flow
+            status_dict = {0: "待使用", 1: "使用中", 2: "已失效"}
+            status = status_dict.get(item['status'])
+            package_list.append({
+                'packageName': item['combo__combo_name'],
+                'status': status,
+                'flowTotal': flow_total,
+                'used': Decimal(used).quantize(Decimal('0.00')),
+                'activationTime': datetime.datetime.fromtimestamp(item['activation_time']).strftime(
+                    '%Y-%m-%d %H:%M:%S'),
+                'expireTime': datetime.datetime.fromtimestamp(item['expire_time']).strftime('%Y-%m-%d %H:%M:%S'),
+                'updatedTime': datetime.datetime.fromtimestamp(item['updated_time']).strftime('%Y-%m-%d %H:%M:%S')
+            })
+        return package_list
+
+    @staticmethod
+    def get_wx_package_list(**data):
+        """
+        获取五兴套餐订购记录
+        @param data: iccid,operator
+        @return: 订购记录结果
+        """
+        try:
+            package_list = []
+            wx_tech = WXTechObject()
+            result = wx_tech.get_package_order_record(**data)
+            if not result:
+                return package_list
+            status_dict = {0: "待使用", 1: "使用中", 2: "已完成", 3: "已退订", 4: "已失效", 5: "已删除"}
+            for item in result['data']:
+                used_flow = float(item['flowTotal']) - float(item['flowRemain'])
+                package_list.append({
+                    'packageName': item['packageName'],
+                    'status': status_dict.get(int(item['state'])),
+                    'flowTotal': item['flowTotal'],
+                    'used': Decimal(used_flow).quantize(Decimal('0.00')),
+                    'activationTime': item['startDate'],
+                    'expireTime': item['endDate'],
+                    'updatedTime': ''
+                })
+            return package_list
+        except Exception as e:
+            print(repr(e))
+            return []
+
+    @staticmethod
+    def get_device_status_by_iccid(iccid, card_type):
+        try:
+            re_data = {'iccid': iccid}
+            if card_type == 0:
+                status_dict = {1: '已激活', 2: '可激活', 3: '已停用', 4: '已失效', 5: '可测试', 6: '库存', 7: '已更换', 8: '已清除'}
+                result = UnicomObjeect().query_device_status(**re_data)
+                res_dict = UnicomObjeect().get_text_dict(result)
+                return status_dict.get(int(res_dict['data']['status']), 'N/A')
+            elif card_type == 1:
+                status_dict = {1: '库存', 2: '可激活', 3: '已激活', 4: '已停用', 5: '已失效', 6: '强制停机'}
+                data = {'iccid': iccid, 'operator': 3}
+                wx_tech = WXTechObject()
+                result = wx_tech.get_cards_info(**data)
+                return status_dict.get(int(result['data']['cardStatusCode']), 'N/A')
+            else:
+                return 'N/A'
+        except Exception as e:
+            print(repr(e))
+            return 'N/A'

+ 34 - 27
AdminController/UserManageController.py

@@ -51,41 +51,46 @@ class LoginView(TemplateView):
     def validates(self, request_dict, response):
         username = request_dict.get('username', None)
         password = request_dict.get('password', None)
+        password_version = request_dict.get('pwdVersion', 'V1')
         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)
+            return self.do_email_login(username, password, response, password_version)
         elif data_valid.mobile_validate(username):
-            return self.do_phone_login(username, password, response)
+            return self.do_phone_login(username, password, response, password_version)
         elif data_valid.name_validate(username):
-            return self.do_name_login(username, password, response)
+            return self.do_name_login(username, password, response, password_version)
         else:
             return response.json(107)
 
-    def do_email_login(self, email, password, response):
+    def do_email_login(self, email, password, response, password_version):
         user_qs = Device_User.objects.filter(Q(username=email) | Q(userEmail=email))
-        return self.valid_login(user_qs, password, response)
+        return self.valid_login(user_qs, password, response, password_version)
 
-    def do_phone_login(self, phone, password, response):
+    def do_phone_login(self, phone, password, response, password_version):
         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)
+        return self.valid_login(user_qs, password, response, password_version)
 
-    def do_name_login(self, username, password, response):
+    def do_name_login(self, username, password, response, password_version):
         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)
+        return self.valid_login(user_qs, password, response, password_version)
 
-    def valid_login(self, user_qs, password, response):
+    def valid_login(self, user_qs, password, response, password_version):
         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']):
+        if password_version == 'V1':
+            check_flag = check_password(password, users['password'])
+        else:
+            check_flag = CommonService.check_password(password, users['password'])
+        if not check_flag:
             return response.json(111)
         userID = users['userID']
         tko = TokenObject(returntpye='pc')
@@ -383,7 +388,7 @@ class UserManagement(View):
             return response.json(0, {'list': user_list, 'total': total})
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def AddOrEditAccount(self, userID, request_dict, response):
         """
@@ -401,6 +406,7 @@ class UserManagement(View):
         roleName = request_dict.get('role', None)
         password = request_dict.get('password', None)
         isEdit = request_dict.get('isEdit', None)
+        password_version = request_dict.get('pwdVersion', 'V1')
 
         # 校验用户名,邮箱,密码是否符合规则
         dataValid = DataValid()
@@ -411,7 +417,8 @@ class UserManagement(View):
         if not isEdit:  # 添加用户需要输入密码
             if not password or not dataValid.password_validate(password):
                 return response.json(444, {'Parameter error': 'password'})
-
+        if password_version == 'V1':
+            password = make_password(password)
         try:
             if isEdit:  # 编辑用户信息
                 userID = request_dict.get('userID')
@@ -419,7 +426,7 @@ class UserManagement(View):
                     "username": username,
                     "NickName": username,
                     "userEmail": userEmail,
-                    "password": make_password(password),
+                    "password": password,
                 }
                 device_user_qs = Device_User.objects.filter(userID=userID)
                 device_user_qs.update(**user_data)
@@ -441,7 +448,7 @@ class UserManagement(View):
                     "username": username,
                     "NickName": username,
                     "userEmail": userEmail,
-                    "password": make_password(password),
+                    "password": password,
                     "userID": CommonService.getUserID(μs=False, setOTAID=True),
                     "is_active": True,
                     "user_isValid": True,
@@ -450,7 +457,7 @@ class UserManagement(View):
             return response.json(0)
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def doDelete(self, request_dict, response):
         userID = request_dict.get('userID', '')
@@ -461,7 +468,7 @@ class UserManagement(View):
             return response.json(0)
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def resetPassword(self, request_dict, response):
         userID = request_dict.get('userID', None)
@@ -476,7 +483,7 @@ class UserManagement(View):
                 return response.json(177)
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def getFeedbackList(self, request_dict, response):
         """
@@ -550,7 +557,7 @@ class UserManagement(View):
             return response.json(0, {'list': feed_back_list, 'total': total})
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def replyFeedBack(self, request_dict, response):
         feedBackID = request_dict.get('feedBackID', None)
@@ -572,7 +579,7 @@ class UserManagement(View):
             return response.json(0)
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def sendSysMsgToUser(self, request_dict, response):
         """
@@ -595,7 +602,7 @@ class UserManagement(View):
             return response.json(0)
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def deleteFeedBack(self, request_dict, response):
         feedBackID = request_dict.get('feedBackID', None)
@@ -609,7 +616,7 @@ class UserManagement(View):
             return response.json(0)
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def getSysMessageList(self, request_dict, response):
         # 功能群发查询
@@ -632,7 +639,7 @@ class UserManagement(View):
             return response.json(0, {'list': list(sys_mass_qs), 'total': total})
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def getAppDataList(self, request_dict, response):
         print('request_dict: ', request_dict)
@@ -653,7 +660,7 @@ class UserManagement(View):
             return response.json(0, {'appBundleId_list': appBundleId_list})
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def sendSysMessage(self, request_dict, response):
         print('request_dict: ', request_dict)
@@ -694,7 +701,7 @@ class UserManagement(View):
             return response.json(0)
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def collectFeedBack(self, request_dict, response):
         """收藏或取消收藏用户反馈信息"""
@@ -817,7 +824,7 @@ class UserManagement(View):
                 return response.json(177)
         except Exception as e:
             print('修改状态异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def getDeviceSuperPassword(self, request_dict, response):
         """
@@ -863,7 +870,7 @@ class UserManagement(View):
             return response.json(0, {'list': list(device_super_password_qs), 'count': count})
         except Exception as e:
             print('查询异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def deleteInformation(self, request_dict, response):
         """

+ 93 - 81
AdminController/VersionManagementController.py

@@ -3,11 +3,13 @@
 import os
 import hashlib
 import time
+import math
 
 import boto3
 import botocore
 from django.db import transaction
 from django.views.generic.base import View
+from Ansjer.config import LOGGER
 
 from Ansjer.config import BASE_DIR, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY
 from Object.TokenObject import TokenObject
@@ -101,7 +103,7 @@ class VersionManagement(View):
             return response.json(0, {'list': equipment_version_list, 'total': total})
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def upLoadFile(self, request, request_dict, response):
         file = request.FILES.get('file', None)
@@ -113,64 +115,68 @@ class VersionManagement(View):
         resolutionRatio = request_dict.get('resolutionRatio', '')
         Description = request_dict.get('Description', '')
         status = request_dict.get('status', 0)
+        isPopup = request_dict.get('isPopup', 0)
 
         if not all([file, mci, lang, ESN, max_ver, channel, resolutionRatio]):
             return response.json(444)
 
         try:
-            nowTime = CommonService.timestamp_to_str(timestamp=int(time.time()))
-            channel = int(channel)
-            resolutionRatio = int(resolutionRatio)
-            status = int(status)
-            # 文件名为设备版本,最后一个'.'的前面为软件版本,后面为设备规格名称
-            # V2.2.4.16E201252CA,软件版本:2.2.4,设备规格名称:16E201252CA
-            # V1.7.2.36C11680X30411F000600000150001Z,软件版本:1.7.2,设备规格名称:36C11680X30411F000600000150001Z
-            file_name = str(file)  # 文件名
-            # .img和.tar.gz文件
-            file_type_index = file_name.find('.img')
-            if file_type_index == -1:
-                file_type_index = file_name.find('.tar')
+            with transaction.atomic():
+                nowTime = CommonService.timestamp_to_str(timestamp=int(time.time()))
+                channel = int(channel)
+                resolutionRatio = int(resolutionRatio)
+                status = int(status)
+                isPopup = int(isPopup)
+                # 文件名为设备版本,最后一个'.'的前面为软件版本,后面为设备规格名称
+                # V2.2.4.16E201252CA,软件版本:2.2.4,设备规格名称:16E201252CA
+                # V1.7.2.36C11680X30411F000600000150001Z,软件版本:1.7.2,设备规格名称:36C11680X30411F000600000150001Z
+                file_name = str(file)  # 文件名
+                # .img和.tar.gz文件
+                file_type_index = file_name.find('.img')
                 if file_type_index == -1:
-                    return response.json(903)
-            version = file_name[:file_type_index]  # 设备版本
-            version_index = version.rindex('.')
-            softwareVersion = version[1:version_index]  # 软件版本
-            code = version[version_index + 1:]  # 设备规格名称
-            chipModelList2Code = code[:4]  # 主芯片
-            type = code[8:10]  # 设备机型
-            companyCode = code[-1:]  # 公司代码
-            fileSize = file.size
-            filePath = '/'.join(('static/otapack', mci, lang, file_name))
-            file_data = file.read()
-            fileMd5 = hashlib.md5(file_data).hexdigest()
-            data_dict = {'mci': mci, 'lang': lang, 'ESN': ESN, 'max_ver': max_ver, 'channel': channel,
-                         'resolutionRatio': resolutionRatio, 'Description': Description, 'status': status,
-                         'version': version, 'softwareVersion': softwareVersion, 'code': code,
-                         'chipModelList2Code': chipModelList2Code, 'type': type, 'companyCode': companyCode,
-                         'fileSize': fileSize, 'filePath': filePath, 'fileMd5': fileMd5, 'update_time': nowTime}
-            # Equipment_Version表创建或更新数据
-            equipment_version_qs = Equipment_Version.objects.filter(code=code, lang=lang)
-            if not equipment_version_qs.exists():
-                Equipment_Version.objects.create(eid=CommonService.getUserID(getUser=False, setOTAID=True),
-                                                 **data_dict)
-            else:
-                equipment_version_qs.update(**data_dict)
-
-            # 上传文件到服务器
-            upload_path = '/'.join((BASE_DIR, 'static/otapack', mci, lang)).replace('\\', '/') + '/'
-            if not os.path.exists(upload_path):  # 上传目录不存在则创建
-                os.makedirs(upload_path)
-            # 文件上传
-            full_name = upload_path + file_name
-            if os.path.exists(full_name):   # 删除同名文件
-                os.remove(full_name)
-            with open(full_name, 'wb+') as write_file:
-                for chunk in file.chunks():
-                    write_file.write(chunk)
-            return response.json(0)
+                    file_type_index = file_name.find('.tar')
+                    if file_type_index == -1:
+                        return response.json(903)
+                version = file_name[:file_type_index]  # 设备版本
+                version_index = version.rindex('.')
+                softwareVersion = version[1:version_index]  # 软件版本
+                code = version[version_index + 1:]  # 设备规格名称
+                chipModelList2Code = code[:4]  # 主芯片
+                type = code[8:10]  # 设备机型
+                companyCode = code[-1:]  # 公司代码
+                fileSize = file.size
+                filePath = '/'.join(('static/otapack', mci, lang, file_name))
+                file_data = file.read()
+                fileMd5 = hashlib.md5(file_data).hexdigest()
+                data_dict = {'mci': mci, 'lang': lang, 'ESN': ESN, 'max_ver': max_ver, 'channel': channel,
+                             'resolutionRatio': resolutionRatio, 'Description': Description, 'status': status,
+                             'is_popup': isPopup, 'version': version, 'softwareVersion': softwareVersion, 'code': code,
+                             'chipModelList2Code': chipModelList2Code, 'type': type, 'companyCode': companyCode,
+                             'fileSize': fileSize, 'filePath': filePath, 'fileMd5': fileMd5, 'update_time': nowTime}
+                # Equipment_Version表创建或更新数据
+                equipment_version_qs = Equipment_Version.objects.filter(code=code, lang=lang)
+                if not equipment_version_qs.exists():
+                    Equipment_Version.objects.create(eid=CommonService.getUserID(getUser=False, setOTAID=True),
+                                                     **data_dict)
+                else:
+                    equipment_version_qs.update(**data_dict)
+
+                # 上传文件到服务器
+                upload_path = '/'.join((BASE_DIR, 'static/otapack', mci, lang)).replace('\\', '/') + '/'
+                if not os.path.exists(upload_path):  # 上传目录不存在则创建
+                    os.makedirs(upload_path)
+                # 文件上传
+                full_name = upload_path + file_name
+                if os.path.exists(full_name):  # 删除同名文件
+                    os.remove(full_name)
+                with open(full_name, 'wb+') as write_file:
+                    for chunk in file.chunks():
+                        write_file.write(chunk)
+                LOGGER.info('versionManagement/upLoadFile成功上传{}'.format(file_name))
+                return response.json(0)
         except Exception as e:
-            print(e)
-            return response.json(500, repr(e))
+            LOGGER.info('versionManagement/upLoadFile接口异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def editVersionInformation(self, request_dict, response):
         eid = request_dict.get('eid', None)
@@ -194,7 +200,7 @@ class VersionManagement(View):
             return response.json(0)
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def deleteEquipmentVersion(self, request_dict, response):
         eid = request_dict.get('eid', None)
@@ -213,7 +219,7 @@ class VersionManagement(View):
             return response.json(0)
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def getAppVersionList(self, request_dict, response):
         app_type = request_dict.get('app_type', None)
@@ -249,7 +255,7 @@ class VersionManagement(View):
             return response.json(0, {'list': app_info_list, 'total': total})
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def addOrEditAppInfo(self, request_dict, response):
         id = request_dict.get('id', None)
@@ -267,9 +273,9 @@ class VersionManagement(View):
             data_dict = {'appName': appName, 'appBundleId': appBundleId, 'bundleVersion': bundleVersion,
                          'newAppversion': newAppversion, 'minAppversion': minAppversion, 'content': content,
                          'app_type': app_type, 'downloadLink': downloadLink}
-            if not id:      # 添加
+            if not id:  # 添加
                 App_Info.objects.create(**data_dict)
-            else:           # 编辑
+            else:  # 编辑
                 app_info_qs = App_Info.objects.filter(id=id)
                 if not app_info_qs.exists():
                     return response.json(173)
@@ -277,7 +283,7 @@ class VersionManagement(View):
             return response.json(0)
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def deleteAppVersion(self, request_dict, response):
         appBundleId = request_dict.get('appBundleId', None)
@@ -291,7 +297,7 @@ class VersionManagement(View):
             return response.json(0)
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def getAppSet(self, request_dict, response):
         appBundleId = request_dict.get('appBundleId', None)
@@ -314,7 +320,7 @@ class VersionManagement(View):
                 return response.json(0)
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def editAppSet(self, request_dict, response):
         appBundleId = request_dict.get('appBundleId', None)
@@ -328,7 +334,7 @@ class VersionManagement(View):
             return response.json(0)
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def getAppRecordList_1(self, request_dict, response):
         app_type = request_dict.get('app_type', 'IOS')
@@ -349,13 +355,15 @@ class VersionManagement(View):
                     app_type = 2
                 else:
                     app_type = 3
-            app_colophon_qs = App_Colophon.objects.filter(app_id__app_type=app_type).order_by('app_id').values_list('app_id__appBundleId', flat=True).distinct()
+            app_colophon_qs = App_Colophon.objects.filter(app_id__app_type=app_type).order_by('app_id').values_list(
+                'app_id__appBundleId', flat=True).distinct()
             if not app_colophon_qs.exists():
                 return response.json(173)
             total = app_colophon_qs.count()
             app_colophon_list = list(app_colophon_qs[(page - 1) * line:page * line])
-            app_info_qs = App_Colophon.objects.filter(app_id__appBundleId__in=app_colophon_list).\
-                values("id", "lang", "newApp_version", "content","version_time", "app_id__appBundleId", "app_id__appName", "app_id__app_type")
+            app_info_qs = App_Colophon.objects.filter(app_id__appBundleId__in=app_colophon_list). \
+                values("id", "lang", "newApp_version", "content", "version_time", "app_id__appBundleId",
+                       "app_id__appName", "app_id__app_type")
             app_info_list = list(app_info_qs)
             data_dict = {}
             # 组装数据
@@ -377,7 +385,7 @@ class VersionManagement(View):
             return response.json(0, res)
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def getAppRecordList(self, request_dict, response):
         app_type = request_dict.get('appType', 'IOS')
@@ -399,16 +407,18 @@ class VersionManagement(View):
                 app_type = 2
             else:
                 app_type = 3
-            app_colophon_qs = App_Colophon.objects.filter(app_id__app_type=app_type).order_by('app_id').values_list('app_id__appBundleId', flat=True).distinct()
+            app_colophon_qs = App_Colophon.objects.filter(app_id__app_type=app_type).order_by('app_id').values_list(
+                'app_id__appBundleId', flat=True).distinct()
             if not app_colophon_qs.exists():
                 return response.json(173)
             total = app_colophon_qs.count()
             app_colophon_list = list(app_colophon_qs[(page - 1) * line:page * line])
-            app_info_qs = App_Colophon.objects.filter(app_id__appBundleId__in=app_colophon_list).\
-                values("id", "lang", "newApp_version", "content", "version_time", "app_id__appBundleId", "app_id__appName", "app_id__app_type")
+            app_info_qs = App_Colophon.objects.filter(app_id__appBundleId__in=app_colophon_list). \
+                values("id", "lang", "newApp_version", "content", "version_time", "app_id__appBundleId",
+                       "app_id__appName", "app_id__app_type")
             app_info_list = list(app_info_qs)
-            app_record_list = []    # 响应的app record数据
-            appBundleId_list = []   # 记录已添加过的appBundleId
+            app_record_list = []  # 响应的app record数据
+            appBundleId_list = []  # 记录已添加过的appBundleId
             # 组装数据
             for app_info in app_info_list:
                 version = app_info['lang'] + app_info['newApp_version']
@@ -428,7 +438,8 @@ class VersionManagement(View):
                     if queryVersion and queryVersion == version and queryAppBundleId == app_info['app_id__appBundleId']:
                         app_record_dict['id'] = app_info['id']
                         app_record_dict['content'] = app_info['content']
-                        app_record_dict['version_time'] = time.strftime("%Y-%m-%d", time.localtime(app_info['version_time']))
+                        app_record_dict['version_time'] = time.strftime("%Y-%m-%d",
+                                                                        time.localtime(app_info['version_time']))
 
                     app_record_list.append(app_record_dict)
                 else:
@@ -439,7 +450,8 @@ class VersionManagement(View):
                         # app_record_list里对应字典插入值
                         app_record_list[index]['id'] = app_info['id']
                         app_record_list[index]['content'] = app_info['content']
-                        app_record_list[index]['version_time'] = time.strftime("%Y-%m-%d", time.localtime(app_info['version_time']))
+                        app_record_list[index]['version_time'] = time.strftime("%Y-%m-%d",
+                                                                               time.localtime(app_info['version_time']))
                         app_record_list[index]['version'] = version
                         app_record_list[index]['newApp_version_list'].insert(0, newApp_version_list)
                     else:
@@ -452,7 +464,7 @@ class VersionManagement(View):
             return response.json(0, res)
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def getAppBundleIdList(self, request_dict, response):
         print('request_dict:', request_dict)
@@ -470,7 +482,7 @@ class VersionManagement(View):
             return response.json(0, {'appBundleIdList': appBundleIdList})
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def addOrEditAppRecord(self, request_dict, response):
         print('request_dict:', request_dict)
@@ -487,13 +499,13 @@ class VersionManagement(View):
 
         try:
             version_time = int(time.mktime(time.strptime(version_time, '%Y-%m-%d')))  # 字符串转时间戳
-            if app_colophon_id:     # 编辑
+            if app_colophon_id:  # 编辑
                 # 编辑获取的版本信息前两位为语言
                 lang = newApp_version[:2]
                 newApp_version = newApp_version[2:]
                 App_Colophon.objects.filter(id=app_colophon_id).update(lang=lang, newApp_version=newApp_version,
                                                                        content=content, version_time=version_time)
-            else:   # 添加
+            else:  # 添加
                 app_info_qs = App_Info.objects.filter(appBundleId=appBundleId).values('id')
                 if not app_info_qs.exists():
                     return response.json(173)
@@ -515,7 +527,7 @@ class VersionManagement(View):
             return response.json(0)
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def deleteAppRecord(self, request_dict, response):
         print('request_dict:', request_dict)
@@ -531,7 +543,7 @@ class VersionManagement(View):
             return response.json(0)
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def getPcInfoList(self, request_dict, response):
         print('request_dict:', request_dict)
@@ -557,7 +569,7 @@ class VersionManagement(View):
             return response.json(0, {'list': pc_info_list, 'total': total})
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def editPcVersion(self, request_dict, response):
         pc_info_id = request_dict.get('id', None)
@@ -601,7 +613,7 @@ class VersionManagement(View):
             return response.json(0)
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def deletePcInfo(self, request_dict, response):
         print('request_dict:', request_dict)
@@ -630,4 +642,4 @@ class VersionManagement(View):
                 return response.json(0)
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))

+ 38 - 6
AdminController/dataSystemManagement/HomeDataController.py

@@ -147,8 +147,17 @@ class HomeDataView(View):
                 ai_cny_total = round(ai_cny_total + temp_total.get('CNY', 0), 2)
                 ai_usd_total = round(ai_usd_total + temp_total.get('USD', 0), 2)
             ai_order_total = {'cnyTotal': ai_cny_total, 'usdTotal': ai_usd_total}
+            # 昨日云盘订单销售额
+            icloud_order_total = order_qs.filter(service_type=4)
+            icloud_cny_total = 0
+            icloud_usd_total = 0
+            for item in icloud_order_total:
+                temp_total = eval(item['total'])
+                icloud_cny_total = round(icloud_cny_total + temp_total.get('CNY', 0), 2)
+                icloud_usd_total = round(icloud_usd_total + temp_total.get('USD', 0), 2)
+            icloud_order_total = {'cnyTotal': icloud_cny_total, 'usdTotal': icloud_usd_total}
             # 昨日联通订单销售额
-            unicom_order_total = order_qs.filter(service_type=2)
+            unicom_order_total = order_qs.filter(service_type__in=[2, 3])
             unicom_cny_total = 0
             unicom_usd_total = 0
             for item in unicom_order_total:
@@ -183,6 +192,15 @@ class HomeDataView(View):
                 ai_cny_all_total = round(ai_cny_all_total + temp_total.get('CNY', 0), 2)
                 ai_usd_all_total = round(ai_usd_all_total + temp_total.get('USD', 0), 2)
             ai_order_all_total = {'cnyTotal': ai_cny_all_total, 'usdTotal': ai_usd_all_total}
+            # 所有云盘订单销售额
+            icloud_order_all_total = order_all_qs.filter(service_type=4)
+            icloud_cny_all_total = 0
+            icloud_usd_all_total = 0
+            for item in icloud_order_all_total:
+                temp_total = eval(item['total'])
+                icloud_cny_all_total = round(icloud_cny_all_total + temp_total.get('CNY', 0), 2)
+                icloud_usd_all_total = round(icloud_usd_all_total + temp_total.get('USD', 0), 2)
+            icloud_order_all_total = {'cnyTotal': icloud_cny_all_total, 'usdTotal': icloud_usd_all_total}
             # 所有联通订单销售额
             unicom_order_all_total = order_all_qs.filter(service_type=2)
             unicom_cny_all_total = 0
@@ -202,17 +220,19 @@ class HomeDataView(View):
                 'orderTotal': order_total,
                 'vodOrderTotal': vod_order_total,
                 'aiOrderTotal': ai_order_total,
+                'icloudOrderTotal': icloud_order_total,
                 'unicomOrderTotal': unicom_order_total,
                 'orderAllTotal': order_all_total,
                 'vodOrderAllTotal': vod_order_all_total,
                 'aiOrderAllTotal': ai_order_all_total,
+                'icloudOrderAllTotal': icloud_order_all_total,
                 'unicomOrderAllTotal': unicom_order_all_total,
                 'userIncreaseRegion': user_increase_region_list,
                 'userAllRegion': user_all_region_list
             }
             return response.json(0, res)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @classmethod
     def query_sales_volume_data(cls, request_dict, response):
@@ -254,7 +274,7 @@ class HomeDataView(View):
                 order_list.append(res)
             return response.json(0, order_list)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @classmethod
     def query_global_all_data(cls, request, request_dict, response):
@@ -279,10 +299,12 @@ class HomeDataView(View):
             order_total = {'cnyTotal': 0, 'usdTotal': 0}
             vod_order_total = {'cnyTotal': 0, 'usdTotal': 0}
             ai_order_total = {'cnyTotal': 0, 'usdTotal': 0}
+            icloud_order_total = {'cnyTotal': 0, 'usdTotal': 0}
             unicom_order_total = {'cnyTotal': 0, 'usdTotal': 0}
             order_all_total = {'cnyTotal': 0, 'usdTotal': 0}
             vod_order_all_total = {'cnyTotal': 0, 'usdTotal': 0}
             ai_order_all_total = {'cnyTotal': 0, 'usdTotal': 0}
+            icloud_order_all_total = {'cnyTotal': 0, 'usdTotal': 0}
             unicom_order_all_total = {'cnyTotal': 0, 'usdTotal': 0}
             user_increase_temp_list = []
             user_increase_list = []
@@ -313,6 +335,10 @@ class HomeDataView(View):
                         ai_order_total['cnyTotal'] + result['result']['aiOrderTotal']['cnyTotal'], 2)
                     ai_order_total['usdTotal'] = round(
                         ai_order_total['usdTotal'] + result['result']['aiOrderTotal']['usdTotal'], 2)
+                    icloud_order_total['cnyTotal'] = round(
+                        icloud_order_total['cnyTotal'] + result['result']['icloudOrderTotal']['cnyTotal'], 2)
+                    icloud_order_total['usdTotal'] = round(
+                        icloud_order_total['usdTotal'] + result['result']['icloudOrderTotal']['usdTotal'], 2)
                     unicom_order_total['cnyTotal'] = round(
                         unicom_order_total['cnyTotal'] + result['result']['unicomOrderTotal']['cnyTotal'], 2)
                     unicom_order_total['usdTotal'] = round(
@@ -329,6 +355,10 @@ class HomeDataView(View):
                         ai_order_all_total['cnyTotal'] + result['result']['aiOrderAllTotal']['cnyTotal'], 2)
                     ai_order_all_total['usdTotal'] = round(
                         ai_order_all_total['usdTotal'] + result['result']['aiOrderAllTotal']['usdTotal'], 2)
+                    icloud_order_all_total['cnyTotal'] = round(
+                        icloud_order_all_total['cnyTotal'] + result['result']['icloudOrderAllTotal']['cnyTotal'], 2)
+                    icloud_order_all_total['usdTotal'] = round(
+                        icloud_order_all_total['usdTotal'] + result['result']['icloudOrderAllTotal']['usdTotal'], 2)
                     unicom_order_all_total['cnyTotal'] = round(
                         unicom_order_all_total['cnyTotal'] + result['result']['unicomOrderAllTotal']['cnyTotal'], 2)
                     unicom_order_all_total['usdTotal'] = round(
@@ -395,17 +425,19 @@ class HomeDataView(View):
                 'orderTotal': order_total,
                 'vodOrderTotal': vod_order_total,
                 'aiOrderTotal': ai_order_total,
+                'icloudOrderTotal': icloud_order_total,
                 'unicomOrderTotal': unicom_order_total,
                 'orderAllTotal': order_all_total,
                 'vodOrderAllTotal': vod_order_all_total,
                 'aiOrderAllTotal': ai_order_all_total,
+                'icloudOrderAllTotal': icloud_order_all_total,
                 'unicomOrderAllTotal': unicom_order_all_total,
                 'userIncreaseRegion': user_increase_list,
                 'userAllRegion': user_all_list
             }
             return response.json(0, res)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @classmethod
     def query_global_sales_volume_data(cls, request, request_dict, response):
@@ -441,7 +473,7 @@ class HomeDataView(View):
                     return response.json(result['result_code'], result['result'])
             return response.json(0, order_list)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @classmethod
     def export_data(cls, request_dict, response):
@@ -475,4 +507,4 @@ class HomeDataView(View):
             #     res['Content-Disposition'] = 'attachment;filename="{}"'.format(file_name)
             return res
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))

+ 24 - 18
AdminController/dataSystemManagement/ServiceDataController.py

@@ -71,10 +71,12 @@ class ServiceDataView(View):
         if not all([start_time, end_time, time_unit, store_meal_type]):
             return response.json(444, {'error param': 'startTime or endTime or timeUnit or storeMealType'})
         try:
-            store_meal_type = int(store_meal_type)
+            store_meal_type = store_meal_type.split(',')
             order_qs = OrdersSummary.objects.filter(time__gte=start_time, time__lt=end_time, query_type=0,
-                                                    service_type=store_meal_type).values('count', 'country', 'total',
-                                                                                         'device_type', 'store_meal')
+                                                    service_type__in=store_meal_type).values('count', 'country',
+                                                                                             'total',
+                                                                                             'device_type',
+                                                                                             'store_meal')
             all_order_qs = OrdersSummary.objects.filter(time__gte=start_time, time__lt=end_time).filter(
                 Q(query_type=0) | Q(query_type=1)).values('total', 'count')
             all_order_count = 0
@@ -205,7 +207,7 @@ class ServiceDataView(View):
             }
             return response.json(0, res)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @classmethod
     def query_free_order(cls, request_dict, response):
@@ -226,10 +228,10 @@ class ServiceDataView(View):
         if not all([start_time, end_time, time_unit, store_meal_type]):
             return response.json(444, {'error param': 'startTime or endTime or timeUnit or storeMealType'})
         try:
-            store_meal_type = int(store_meal_type)
+            store_meal_type = store_meal_type.split(',')
             order_qs = OrdersSummary.objects.filter(time__gte=start_time, time__lt=end_time, query_type=1,
-                                                    service_type=store_meal_type).values('count', 'country',
-                                                                                         'device_type')
+                                                    service_type__in=store_meal_type).values('count', 'country',
+                                                                                             'device_type')
             free_order_count = order_qs.aggregate(count=Sum('count'))['count']
             free_order_count = free_order_count if free_order_count else 0  # 免费订单数量
             all_order_qs = OrdersSummary.objects.filter(time__gte=start_time, time__lt=end_time).filter(
@@ -314,7 +316,7 @@ class ServiceDataView(View):
             }
             return response.json(0, res)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @classmethod
     def query_first_pay_order(cls, request_dict, response):
@@ -335,9 +337,11 @@ class ServiceDataView(View):
         if not all([start_time, end_time, time_unit, store_meal_type]):
             return response.json(444, {'error param': 'startTime or endTime or timeUnit or storeMealType'})
         try:
+            store_meal_type = store_meal_type.split(',')
             order_qs = OrdersSummary.objects.filter(time__gte=start_time, time__lt=end_time, query_type=2,
-                                                    service_type=store_meal_type).values('count', 'country', 'total',
-                                                                                         'device_type')
+                                                    service_type__in=store_meal_type).values('count', 'country',
+                                                                                             'total',
+                                                                                             'device_type')
             all_order_qs = OrdersSummary.objects.filter(time__gte=start_time, time__lt=end_time).filter(
                 Q(query_type=0) | Q(query_type=1)).values('total', 'count')
             all_order_count = 0
@@ -441,7 +445,7 @@ class ServiceDataView(View):
             }
             return response.json(0, res)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @classmethod
     def query_repeat_pay_order(cls, request_dict, response):
@@ -462,9 +466,11 @@ class ServiceDataView(View):
         if not all([start_time, end_time, time_unit, store_meal_type]):
             return response.json(444, {'error param': 'startTime or endTime or timeUnit or storeMealType'})
         try:
+            store_meal_type = store_meal_type.split(',')
             order_qs = OrdersSummary.objects.filter(time__gte=start_time, time__lt=end_time, query_type=3,
-                                                    service_type=store_meal_type).values('count', 'country', 'total',
-                                                                                         'device_type')
+                                                    service_type__in=store_meal_type).values('count', 'country',
+                                                                                             'total',
+                                                                                             'device_type')
             repeat_pay_order_count = order_qs.aggregate(count=Sum('count'))['count']
             repeat_pay_order_count = repeat_pay_order_count if repeat_pay_order_count else 0
             all_order_qs = OrdersSummary.objects.filter(time__gte=start_time, time__lt=end_time).filter(
@@ -572,7 +578,7 @@ class ServiceDataView(View):
             }
             return response.json(0, res)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @classmethod
     def query_global_pay_order(cls, request, request_dict, response):
@@ -691,7 +697,7 @@ class ServiceDataView(View):
             }
             return response.json(0, res)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @classmethod
     def query_global_free_order(cls, request, request_dict, response):
@@ -770,7 +776,7 @@ class ServiceDataView(View):
             }
             return response.json(0, res)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @classmethod
     def query_global_first_pay_order(cls, request, request_dict, response):
@@ -865,7 +871,7 @@ class ServiceDataView(View):
             }
             return response.json(0, res)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @classmethod
     def query_global_repeat_pay_order(cls, request, request_dict, response):
@@ -966,4 +972,4 @@ class ServiceDataView(View):
             }
             return response.json(0, res)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))

+ 2 - 2
Ansjer/cn_config/config_test.py

@@ -27,8 +27,8 @@ LOG_BUCKET = 'ansjer-statres'                       # 日志存储桶
 PUSH_CLOUD_PHOTO = 'push-cloud-photo'               # 推送云相册存储桶
 
 # redis节点
-SERVER_HOST = 'backendserver.3xavzq.0001.cnw1.cache.amazonaws.com.cn'
-PUSH_REDIS_ADDRESS = 'pushredis.3xavzq.0001.cnw1.cache.amazonaws.com.cn'
+SERVER_HOST = '127.0.0.1'
+PUSH_REDIS_ADDRESS = '127.0.0.1'
 # ======================================================================================================================
 
 # 域名

+ 2 - 2
Ansjer/cn_config/formal_settings.py

@@ -95,7 +95,7 @@ DATABASES = {
         'HOST': SERVER_HOST,
         'PORT': '3306',
         'AUTOCOMMIT': True,
-        'CONN_MAX_AGE': 60,
+        # 'CONN_MAX_AGE': 1,
         'OPTIONS': {
             'charset': 'utf8mb4',
             'use_unicode': True,
@@ -110,7 +110,7 @@ DATABASES = {
         'HOST': SERVER_HOST2,
         'PORT': '3306',
         'AUTOCOMMIT': True,
-        'CONN_MAX_AGE': 60,
+        # 'CONN_MAX_AGE': 1,
         'OPTIONS': {
             'charset': 'utf8mb4',
             'use_unicode': True,

+ 2 - 2
Ansjer/eur_config/formal_settings.py

@@ -92,7 +92,7 @@ DATABASES = {
         'HOST': SERVER_HOST,
         'PORT': '3306',
         'AUTOCOMMIT': True,
-        # 'CONN_MAX_AGE': 1,
+        'CONN_MAX_AGE': 60,
         'OPTIONS': {
             'charset': 'utf8mb4',
             'use_unicode': True,
@@ -107,7 +107,7 @@ DATABASES = {
         'HOST': SERVER_HOST2,
         'PORT': '3306',
         'AUTOCOMMIT': True,
-        # 'CONN_MAX_AGE': 1,
+        'CONN_MAX_AGE': 60,
         'OPTIONS': {
             'charset': 'utf8mb4',
             'use_unicode': True,

+ 3 - 1
Ansjer/server_urls/loocam_url.py

@@ -9,7 +9,8 @@
 from django.urls import re_path
 
 from Controller.SensorGateway import GatewayFamilyRoomController, SubDeviceController, GatewayFamilyMemberController, \
-    EquipmentFamilyController, GatewayDeviceController, SmartSceneController, SmartSocketController
+    EquipmentFamilyController, GatewayDeviceController, SmartSceneController, SmartSocketController, \
+    SmartSwitchController
 
 urlpatterns = [
     re_path(r'^sensor/gateway/(?P<operation>.*)$', EquipmentFamilyController.EquipmentFamilyView.as_view()),
@@ -20,4 +21,5 @@ urlpatterns = [
     re_path(r'^gateway/device/info/(?P<operation>.*)$', GatewayDeviceController.GatewayDeviceView.as_view()),
     re_path(r'^smartscene/(?P<operation>.*)$', SmartSceneController.SmartSceneView.as_view()),
     re_path(r'^open/socket/(?P<operation>.*)$', SmartSocketController.SmartSocketView.as_view()),
+    re_path(r'^smartswitch/(?P<operation>.*)$', SmartSwitchController.SmartSwitchView.as_view()),
 ]

+ 224 - 326
Ansjer/urls.py

@@ -1,10 +1,10 @@
-from django.conf.urls import url
 from django.contrib import admin
-from django.urls import path, re_path
+from django.urls import include
+from django.urls import re_path
 
 from AdminController import UserManageController, RoleController, MenuController, TestServeController, \
     ServeManagementController, LogManagementController, DeviceManagementController, VersionManagementController, \
-    AiServeController, SurveysManageController, SerialManageController
+    AiServeController, SurveysManageController, SerialManageController, IcloudManagementController
 from Controller import FeedBack, EquipmentOTA, EquipmentInfo, AdminManage, AppInfo, \
     Test, MealManage, DeviceManage, EquipmentStatus, SysManage, DeviceLog, LogAccess, \
     AppColophon, DateController, \
@@ -25,10 +25,8 @@ from Controller import FeedBack, EquipmentOTA, EquipmentInfo, AdminManage, AppIn
     DeviceLogController, CouponController, AiController, ShadowController, AppAccountManagement, InitController
 from Controller.Cron import CronTaskController
 from Controller.MessagePush import EquipmentMessagePush
-from Controller.Surveys import CloudStorageController
 from Controller.SensorGateway import SensorGatewayController, EquipmentFamilyController
-from django.urls import include
-
+from Controller.Surveys import CloudStorageController
 from Controller.UserDevice import UserDeviceShareController
 
 urlpatterns = [
@@ -36,342 +34,242 @@ urlpatterns = [
     re_path(r'^testApi/(?P<operation>.*)', TestApi.testView.as_view()),
     re_path(r'^account/authcode', UserController.authCodeView.as_view()),
     re_path(r'^v3/account/generatepictureCodeView/$', UserController.generatePictureCodeView.as_view()),
-    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/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()),
-    url(r'^account/refreshTk$', UserController.refreshTokenView.as_view()),
-    url(r'^v3/account/refreshTk$', UserController.refreshTokenViewV3.as_view()),
-    url(r'^v3/account/deleteUser$', UserController.DeleteUser.as_view()),
-    url(r'^favicon.ico$', UserManger.success, name=u'favicon.ico'),
-    url(r'^account/showUserMore$', UserManger.showUserMoreView.as_view()),
-    url(r'^account/perfectUserInfo$', UserManger.perfectUserInfoView.as_view()),
-    url(r'^account/getAvatar/(?P<filePath>.*)$', UserManger.getAvatarView.as_view()),
-    url(r'^account/delUser$', UserManger.delUserInterface),
-    url(r'^account/setUserValid$', UserManger.setUserValidView.as_view()),
-    url(r'^account/showAllUser$', UserManger.showAllUserInterface),
-    url(r'^account/help$', LogManager.HelpView.as_view()),
-    url(r'^account/searchUser$', shareUserPermission.searchUserView.as_view()),
-    path('accounts', AdminManage.search_user_by_content),  # 多条件搜索用户信息admin
-    url(r'^account/shareUserEquipment$', shareUserPermission.shareUserEquipmentView.as_view()),
-    url(r'^account/unsharedUserEquipment$', shareUserPermission.unsharedUserEquipmentView.as_view()),
-    url(r'^response/success$', UserManger.success),
-    url(r'^equipment/queryUserEquipment$', EquipmentManager.queryUserEquipmentInterface),
-    url(r'^equipment/addNewUserEquipment$', EquipmentManager.addNewUserEquipmentInterface),
-    url(r'^equipment/delUserEquipment$', EquipmentManager.delUserEquipmentInterface),
-    url(r'^equipment/modifyUserEquipment$', EquipmentManager.modifyUserEquipmentInterface),
-    url(r'^equipment/showAllUserEquipment$', EquipmentManager.showAllUserEquipmentInterface),
-    url(r'^equipment/findEquipmentInfo$', EquipmentManager.findEquipmentInfoInterface),
-    # 新删除设备接口
-    url(r'^equipment/delete', EquipmentManager.deleteInterface),
-    url(r'^equipment/batchDelete', EquipmentManager.batchDeleteInterface),
-    url(r'^equipment/add', EquipmentManager.addInterface),
-    url(r'^equipment/admin_add', EquipmentManager.admin_addInterface),
-    url(r'^equipment/admin_modify', EquipmentManager.admin_modifyInterface),
-
-    url(r'^equipment/query', EquipmentManager.queryInterface),
-    # 获取设备影子信息接口
-    url(r'^equipment/flow$', EquipmentManager.uid_status),
-
-    url(r'^OTA/uploads$', OTAEquipment.getUploadFiletoDirView.as_view()),
-    url(r'^OTA/download$', OTAEquipment.downloadUpdataFileUrl),
-    url(r'^OTA/downloads/(\w+)/(\w+[\w+]*.+[^_w]*.\w+)$', OTAEquipment.downloadUpdataFileUrlInterface),
-    url(r'^OTA/getEquipmentVersion$', OTAEquipment.getEquipmentVersionInterface),
-    url(r'^OTA/getUpdataFileUrl$', OTAEquipment.getUpdataFileUrlInterface),
-    url(r'^OTA/addNewEquipmentVersion$', OTAEquipment.addNewEquipmentVersionInterface),
-
-    url(r'^roles/addNewRole$', PermissionManager.addNewRoleView.as_view()),
-    url(r'^roles/queryRole$', PermissionManager.queryRoleView.as_view()),
-    url(r'^roles/delRole$', PermissionManager.delRoleView.as_view()),
-    url(r'^roles/modifyRole$', PermissionManager.modifyRoleView.as_view()),
-    url(r'^perms/addNewPerms$', PermissionManager.addNewPermsView.as_view()),
-    url(r'^perms/delPerms$', PermissionManager.delPermsView.as_view()),
-    url(r'^perms/queryPerms$', PermissionManager.queryPermsView.as_view()),
-    url(r'^perms/modifyPerms$', PermissionManager.modifyPermsView.as_view()),
-    url(r'^permsManager/queryRolePerms$', PermissionManager.queryRolePermsView.as_view()),
-    url(r'^uploads/upgrade$', OTAEquipment.getUploadFiletoDirView.as_view()),
-    url(r'^upgrade/download/(\w+.[^_w]*\w+.\w+)$', CheckUserData.download_file),
-    url(r'^downloads/upgrade/(\w+)/(\w+.[^_w]*\w+.\w+)$', OTAEquipment.downloadUpdataFileUrlInterface),
-    url(r'^getOTAurl/getUpdataFileUrl$', OTAEquipment.getUpdataFileUrlInterface),
-    url(r'^equipment/info', EquipmentInfo.EquipmentInfo.as_view()),
-    url(r'^adminManage/manage', AdminManage.AdminManage.as_view()),  # 管理员专属view
-    url(r'^equipment/OTA', EquipmentOTA.EquipmentOTA.as_view()),  # OTA重构类
-    url(r'^userbrandinfo/(?P<operation>.*)$', UserBrandController.UserBrandInfo.as_view()),  # 用户登录的手机端品牌记录统计信息表
-
-    url(r'^uidset/(?P<operation>.*)$', UidSetController.UidSetView.as_view()),
-    url(r'^appInfo', AppInfo.AppInfo.as_view()),  # app版本信息
-
-    url(r'^meal/manage', MealManage.MealManage.as_view()),
-    url(r'^device/manage$', DeviceManage.DeviceManage.as_view()),
-    # 设备在线
-    url(r'^device/online$', EquipmentStatus.EquipmentOnline),
-    # 设备离线
-    url(r'^device/offline$', EquipmentStatus.EquipmentOffline),
-    # 设备离线
-    url(r'^device/updateIP$', EquipmentStatus.updateIP),
-    # 系统ctr
-    url(r'^sys/updateLog', SysManage.updateLog),
-    url(r'^devices/(\w+)/logs$', DeviceLog.DeviceLog),
-    url(r'^devices/(\w+)$', DeviceManage.Devices),
-    # 访问日志 mongodb版
-    url(r'^LogAccess$', LogAccess.LogAccess),
-    # 上传操作文档
-    url(r'^HelpCHM/upload$', LogManager.upload_help_chm),
-    url(r'^admin/userIDs$', AdminManage.getUserIds),
-    path('eq/delById', EquipmentInfo.deleteExpireEquipmentInfoById),
-    # 新需求ota接口
-    url(r'^OTA/getNewVer', OTAEquipment.getNewVerInterface),
-    url(r'^OTA/uploadsPack$', OTAEquipment.uploadOTAInterfaceView.as_view()),
-    url(r'^OTA/downloadsPack/(?P<fullPath>[0-9\w/.\-]+)', OTAEquipment.downloadOTAInterface),
-    url(r'^dlotapack/(?P<fullPath>[0-9\w/.\-]+)', OTAEquipment.downloadOTAInterfaceV2),
-    url(r'^OTA/getDownLoadOTApackUrl$', OTAEquipment.getDownLoadOTApackUrl),
-    url(r'^OTA/checkMaxVersion$', OTAEquipment.checkMaxVersion),
-
-    # h获取验证码    # v2接口
-    url(r'^v2/account/authcode$', UserController.v2authCodeView.as_view()),
-    url(r'^v2/account/register$', UserController.v2registerView.as_view()),
-    url(r'^v2/account/forgetCode$', UserController.v2forgetPwdCodeView.as_view()),
-    url(r'^v2/account/resetPwdByCode$', UserController.v2resetPwdByCodeView.as_view()),
-
-    # 重置密码验证码校验
-    url(r'^v2/authcode/verify$', UserController.verifyAuthcode.as_view()),
-    url(r'^v2/account/logout$', UserController.V2LogoutView.as_view()),
-    url(r'^v2/account/login$', UserController.v3LoginView.as_view()),
-    url(r'^v3/account/login$', UserController.v3LoginView.as_view()),
-    url(r'^account/oneClickLogin$', UserController.oneClickLoginView.as_view()),
-    url(r'^account/createPwd$', UserController.createPwd.as_view()),
-
-    # 用户删除/注销
-    url(r'^account/delete$', UserController.deleteAccount),
-
-    # 确认地区
-    url(r'^user/confirmRegion$', UserController.confirmRegion),
-
-    # 验证码登录
-    url(r'^account/loginCode$', UserController.loginCodeView.as_view()),
-    url(r'^v3/account/loginByCode$', UserController.v3LoginByCodeView.as_view()),
-
-    # 指纹登录
-    url(r'^v3/account/loginByFingerprint$', UserController.v3LoginByFingerprintView.as_view()),
-    url(r'^v3/account/setFingerprint$', UserController.v3SetFingerprintView.as_view()),
-
-    # 推送项目接口
-    url(r'^detect/(?P<operation>.*)$', DetectController.DetectControllerView.as_view()),
-    url(r'^detectV2/(?P<operation>.*)$', DetectControllerV2.DetectControllerViewV2.as_view()),
-
-    # 新增
-    url(r'^cloudVod/(?P<operation>.*)$', CloudVod.CloudVodView.as_view()),
-    url(r'^meal/(?P<operation>.*)$', MealManage.MealView.as_view()),
-    url(r'^order/(?P<operation>.*)$', OrderContrller.OrderView.as_view()),
-    url(r'^appCol/(?P<operation>.*)$', AppColophon.AppColView.as_view()),
-    url(r'^vodBucket/(?P<operation>.*)$', VodBucket.VodBucketView.as_view()),
-    url(r'^UIDBucket/(?P<operation>.*)$', VodBucket.UidBucketView.as_view()),
-    url(r'^EquipmentVersion/(?P<operation>.*)$', EquipmentOTA.EquipmentVersionView.as_view()),
-
-    url(r'^deviceShare/(?P<operation>.*)$', DeviceShare.DeviceShareView.as_view()),
-    url(r'^appVer/views$', AppInfo.AppVersionView.as_view()),
-
-    # 屏蔽
-    url(r'^user/initInfo$', UserController.InitInfoView.as_view()),
-    url(r'^user/information/(?P<operation>.*)$', UserController.InitUserInformationView.as_view()),
-    # 获取时区相关信息
-    url(r'^getTZ$', EquipmentStatus.getTZ),
-
-    # oss授权
-    url(r'^stsOss/(?P<operation>.*)$', StsOssController.StsOssView.as_view()),
-
-    # 用户反馈信息
-    url(r'^feedback/(?P<operation>.*)$', FeedBack.FeedBackView.as_view()),
-    url(r'^uidpreview/(?P<operation>.*)$', UIDPreview.UIDPreview.as_view()),
-    url(r'^sysmsg/(?P<operation>.*)$', SysMsg.SysMsgView.as_view()),
-    url(r'^sysfile/(?P<filePath>.*)$', SysManage.getStatView.as_view()),
-
-    url(r'^equipment/flowUpdate', EquipmentManager.update_uid_set),
-
-    url(r'^log/getUploadUrl', EquipmentStatus.getUploadLogUrl),
-    url(r'^app/getIdData', AppInfo.AppIdDataView.as_view()),
-    url(r'^wechat/authsign', UserController.wxAuthSignView.as_view()),
-    url(r'^wechat/perfect', UserController.wxPerfectView.as_view()),
-    # 分区分流
-    path('Test', Test.Test.as_view()),
-    # 微信绑定的用户获取验证码
-    url(r'^oauth/authcode', UserController.OauthAuthCodeView.as_view()),
-    url(r'^oauth/perfect', UserController.OauthPerfectView.as_view()),
-    url(r'^oauth/unbunding', UserController.UnbundingWXView.as_view()),
-
-    url(r'^equipment/judge', EquipmentManager.judgeInterface),
-
-    # ap模式,新增设备表
-    url(r'^uiduser/add', UidUser.addInterface),
-    url(r'^uiduser/query', UidUser.queryInterface),
-    url(r'^uiduser/update', UidUser.updateInterface),
-    url(r'^uiduser/delete', UidUser.deleteInterface),
-    url(r'^uid_user/(?P<operation>.*)$', UidUser.UidUserView.as_view()),
-    # add query update delete
-    url(r'^v2/equipment/(?P<operation>.*)$', EquipmentManagerV2.EquipmentManagerV2.as_view()),
-
-    url(r'^msg/init', SysManage.initMsgFunc),
-
-    url(r'^oss_crd/(?P<operation>.*)$', OssCrd.OssCrdView.as_view()),
-    url(r'^push_deploy/(?P<operation>.*)$', PushDeploy.PushDeployView.as_view()),
-    url(r'^oalexa/auth', UserController.alexaAuthView.as_view()),
-    url(r'^oalexa/discoveryuid', UserController.alexaUidView.as_view()),
+    re_path(r'^v3/account/imageCodeRegister/$', UserController.Image_Code_RegisterView.as_view()),
+    re_path(r'^account/register$', UserController.registerView.as_view()),
+    re_path(r'^account/login$', UserController.v2LoginView.as_view()),
+    re_path(r'^account/logout$', UserController.LogoutView.as_view()),
+    re_path(r'^account/noPasslogin$', UserController.noPasslogin.as_view()),
+    re_path(r'^account/changePwd$', UserController.ChangePwdView.as_view()),
+    re_path(r'^account/forget$', UserController.ForgetPwdView.as_view()),
+    re_path(r'^account/email-re-pwd$', UserController.EmailResetPwdView.as_view()),
+    re_path(r'^account/refreshTk$', UserController.refreshTokenView.as_view()),
+    re_path(r'^v3/account/refreshTk$', UserController.refreshTokenViewV3.as_view()),
+    re_path(r'^v3/account/deleteUser$', UserController.DeleteUser.as_view()),
+    re_path(r'^favicon.ico$', UserManger.success, name=u'favicon.ico'),
+    re_path(r'^account/showUserMore$', UserManger.showUserMoreView.as_view()),
+    re_path(r'^account/perfectUserInfo$', UserManger.perfectUserInfoView.as_view()),
+    re_path(r'^account/getAvatar/(?P<filePath>.*)$', UserManger.getAvatarView.as_view()),
+    re_path(r'^account/delUser$', UserManger.delUserInterface),
+    re_path(r'^account/setUserValid$', UserManger.setUserValidView.as_view()),
+    re_path(r'^account/showAllUser$', UserManger.showAllUserInterface),
+    re_path(r'^account/help$', LogManager.HelpView.as_view()),
+    re_path(r'^account/searchUser$', shareUserPermission.searchUserView.as_view()),
+    re_path('accounts', AdminManage.search_user_by_content),  # 多条件搜索用户信息admin
+    re_path(r'^account/shareUserEquipment$', shareUserPermission.shareUserEquipmentView.as_view()),
+    re_path(r'^account/unsharedUserEquipment$', shareUserPermission.unsharedUserEquipmentView.as_view()),
+    re_path(r'^response/success$', UserManger.success),
+    re_path(r'^equipment/queryUserEquipment$', EquipmentManager.queryUserEquipmentInterface),
+    re_path(r'^equipment/addNewUserEquipment$', EquipmentManager.addNewUserEquipmentInterface),
+    re_path(r'^equipment/delUserEquipment$', EquipmentManager.delUserEquipmentInterface),
+    re_path(r'^equipment/modifyUserEquipment$', EquipmentManager.modifyUserEquipmentInterface),
+    re_path(r'^equipment/showAllUserEquipment$', EquipmentManager.showAllUserEquipmentInterface),
+    re_path(r'^equipment/findEquipmentInfo$', EquipmentManager.findEquipmentInfoInterface),
+    re_path(r'^equipment/delete', EquipmentManager.deleteInterface),
+    re_path(r'^equipment/batchDelete', EquipmentManager.batchDeleteInterface),
+    re_path(r'^equipment/add', EquipmentManager.addInterface),
+    re_path(r'^equipment/admin_add', EquipmentManager.admin_addInterface),
+    re_path(r'^equipment/admin_modify', EquipmentManager.admin_modifyInterface),
+    re_path(r'^equipment/query', EquipmentManager.queryInterface),
+    re_path(r'^equipment/flow$', EquipmentManager.uid_status),
+    re_path(r'^OTA/uploads$', OTAEquipment.getUploadFiletoDirView.as_view()),
+    re_path(r'^OTA/download$', OTAEquipment.downloadUpdataFileUrl),
+    re_path(r'^OTA/downloads/(\w+)/(\w+[\w+]*.+[^_w]*.\w+)$', OTAEquipment.downloadUpdataFileUrlInterface),
+    re_path(r'^OTA/getEquipmentVersion$', OTAEquipment.getEquipmentVersionInterface),
+    re_path(r'^OTA/getUpdataFileUrl$', OTAEquipment.getUpdataFileUrlInterface),
+    re_path(r'^OTA/addNewEquipmentVersion$', OTAEquipment.addNewEquipmentVersionInterface),
+    re_path(r'^roles/addNewRole$', PermissionManager.addNewRoleView.as_view()),
+    re_path(r'^roles/queryRole$', PermissionManager.queryRoleView.as_view()),
+    re_path(r'^roles/delRole$', PermissionManager.delRoleView.as_view()),
+    re_path(r'^roles/modifyRole$', PermissionManager.modifyRoleView.as_view()),
+    re_path(r'^perms/addNewPerms$', PermissionManager.addNewPermsView.as_view()),
+    re_path(r'^perms/delPerms$', PermissionManager.delPermsView.as_view()),
+    re_path(r'^perms/queryPerms$', PermissionManager.queryPermsView.as_view()),
+    re_path(r'^perms/modifyPerms$', PermissionManager.modifyPermsView.as_view()),
+    re_path(r'^permsManager/queryRolePerms$', PermissionManager.queryRolePermsView.as_view()),
+    re_path(r'^uploads/upgrade$', OTAEquipment.getUploadFiletoDirView.as_view()),
+    re_path(r'^upgrade/download/(\w+.[^_w]*\w+.\w+)$', CheckUserData.download_file),
+    re_path(r'^downloads/upgrade/(\w+)/(\w+.[^_w]*\w+.\w+)$', OTAEquipment.downloadUpdataFileUrlInterface),
+    re_path(r'^getOTAurl/getUpdataFileUrl$', OTAEquipment.getUpdataFileUrlInterface),
+    re_path(r'^equipment/info', EquipmentInfo.EquipmentInfo.as_view()),
+    re_path(r'^adminManage/manage', AdminManage.AdminManage.as_view()),
+    re_path(r'^equipment/OTA', EquipmentOTA.EquipmentOTA.as_view()),
+    re_path(r'^userbrandinfo/(?P<operation>.*)$', UserBrandController.UserBrandInfo.as_view()),
+    re_path(r'^uidset/(?P<operation>.*)$', UidSetController.UidSetView.as_view()),
+    re_path(r'^appInfo', AppInfo.AppInfo.as_view()),
+    re_path(r'^meal/manage', MealManage.MealManage.as_view()),
+    re_path(r'^device/manage$', DeviceManage.DeviceManage.as_view()),
+    re_path(r'^device/online$', EquipmentStatus.EquipmentOnline),
+    re_path(r'^device/offline$', EquipmentStatus.EquipmentOffline),
+    re_path(r'^device/updateIP$', EquipmentStatus.updateIP),
+    re_path(r'^sys/updateLog', SysManage.updateLog),
+    re_path(r'^devices/(\w+)/logs$', DeviceLog.DeviceLog),
+    re_path(r'^devices/(\w+)$', DeviceManage.Devices),
+    re_path(r'^LogAccess$', LogAccess.LogAccess),
+    re_path(r'^HelpCHM/upload$', LogManager.upload_help_chm),
+    re_path(r'^admin/userIDs$', AdminManage.getUserIds),
+    re_path('eq/delById', EquipmentInfo.deleteExpireEquipmentInfoById),
+    re_path(r'^OTA/getNewVer', OTAEquipment.getNewVerInterface),
+    re_path(r'^OTA/uploadsPack$', OTAEquipment.uploadOTAInterfaceView.as_view()),
+    re_path(r'^OTA/downloadsPack/(?P<fullPath>[0-9\w/.\-]+)', OTAEquipment.downloadOTAInterface),
+    re_path(r'^dlotapack/(?P<fullPath>[0-9\w/.\-]+)', OTAEquipment.downloadOTAInterfaceV2),
+    re_path(r'^OTA/getDownLoadOTApackUrl$', OTAEquipment.getDownLoadOTApackUrl),
+    re_path(r'^OTA/checkMaxVersion$', OTAEquipment.checkMaxVersion),
+    re_path(r'^v2/account/authcode$', UserController.v2authCodeView.as_view()),
+    re_path(r'^v2/account/register$', UserController.v2registerView.as_view()),
+    re_path(r'^v2/account/forgetCode$', UserController.v2forgetPwdCodeView.as_view()),
+    re_path(r'^v2/account/resetPwdByCode$', UserController.v2resetPwdByCodeView.as_view()),
+    re_path(r'^v2/authcode/verify$', UserController.verifyAuthcode.as_view()),
+    re_path(r'^v2/account/logout$', UserController.V2LogoutView.as_view()),
+    re_path(r'^v2/account/login$', UserController.v3LoginView.as_view()),
+    re_path(r'^v3/account/login$', UserController.v3LoginView.as_view()),
+    re_path(r'^account/oneClickLogin$', UserController.oneClickLoginView.as_view()),
+    re_path(r'^account/createPwd$', UserController.createPwd.as_view()),
+    re_path(r'^account/delete$', UserController.deleteAccount),
+    re_path(r'^user/confirmRegion$', UserController.confirmRegion),
+    re_path(r'^account/loginCode$', UserController.loginCodeView.as_view()),
+    re_path(r'^v3/account/loginByCode$', UserController.v3LoginByCodeView.as_view()),
+    re_path(r'^v3/account/loginByFingerprint$', UserController.v3LoginByFingerprintView.as_view()),
+    re_path(r'^v3/account/setFingerprint$', UserController.v3SetFingerprintView.as_view()),
+    re_path(r'^detect/(?P<operation>.*)$', DetectController.DetectControllerView.as_view()),
+    re_path(r'^detectV2/(?P<operation>.*)$', DetectControllerV2.DetectControllerViewV2.as_view()),
+    re_path(r'^cloudVod/(?P<operation>.*)$', CloudVod.CloudVodView.as_view()),
+    re_path(r'^meal/(?P<operation>.*)$', MealManage.MealView.as_view()),
+    re_path(r'^order/(?P<operation>.*)$', OrderContrller.OrderView.as_view()),
+    re_path(r'^appCol/(?P<operation>.*)$', AppColophon.AppColView.as_view()),
+    re_path(r'^vodBucket/(?P<operation>.*)$', VodBucket.VodBucketView.as_view()),
+    re_path(r'^UIDBucket/(?P<operation>.*)$', VodBucket.UidBucketView.as_view()),
+    re_path(r'^EquipmentVersion/(?P<operation>.*)$', EquipmentOTA.EquipmentVersionView.as_view()),
+    re_path(r'^deviceShare/(?P<operation>.*)$', DeviceShare.DeviceShareView.as_view()),
+    re_path(r'^appVer/views$', AppInfo.AppVersionView.as_view()),
+    re_path(r'^user/initInfo$', UserController.InitInfoView.as_view()),
+    re_path(r'^user/information/(?P<operation>.*)$', UserController.InitUserInformationView.as_view()),
+    re_path(r'^user/getSalt$', UserController.getPasswordSalt),
+    re_path(r'^getTZ$', EquipmentStatus.getTZ),
+    re_path(r'^stsOss/(?P<operation>.*)$', StsOssController.StsOssView.as_view()),
+    re_path(r'^feedback/(?P<operation>.*)$', FeedBack.FeedBackView.as_view()),
+    re_path(r'^uidpreview/(?P<operation>.*)$', UIDPreview.UIDPreview.as_view()),
+    re_path(r'^sysmsg/(?P<operation>.*)$', SysMsg.SysMsgView.as_view()),
+    re_path(r'^sysfile/(?P<filePath>.*)$', SysManage.getStatView.as_view()),
+    re_path(r'^equipment/flowUpdate', EquipmentManager.update_uid_set),
+    re_path(r'^log/getUploadUrl', EquipmentStatus.getUploadLogUrl),
+    re_path(r'^app/getIdData', AppInfo.AppIdDataView.as_view()),
+    re_path(r'^wechat/authsign', UserController.wxAuthSignView.as_view()),
+    re_path(r'^wechat/perfect', UserController.wxPerfectView.as_view()),
+    re_path(r'^Test', Test.Test.as_view()),
+    re_path(r'^oauth/authcode', UserController.OauthAuthCodeView.as_view()),
+    re_path(r'^oauth/perfect', UserController.OauthPerfectView.as_view()),
+    re_path(r'^oauth/unbunding', UserController.UnbundingWXView.as_view()),
+    re_path(r'^equipment/judge', EquipmentManager.judgeInterface),
+    re_path(r'^uiduser/add', UidUser.addInterface),
+    re_path(r'^uiduser/query', UidUser.queryInterface),
+    re_path(r'^uiduser/update', UidUser.updateInterface),
+    re_path(r'^uiduser/delete', UidUser.deleteInterface),
+    re_path(r'^uid_user/(?P<operation>.*)$', UidUser.UidUserView.as_view()),
+    re_path(r'^v2/equipment/(?P<operation>.*)$', EquipmentManagerV2.EquipmentManagerV2.as_view()),
+    re_path(r'^msg/init', SysManage.initMsgFunc),
+    re_path(r'^oss_crd/(?P<operation>.*)$', OssCrd.OssCrdView.as_view()),
+    re_path(r'^push_deploy/(?P<operation>.*)$', PushDeploy.PushDeployView.as_view()),
+    re_path(r'^oalexa/auth', UserController.alexaAuthView.as_view()),
+    re_path(r'^oalexa/discoveryuid', UserController.alexaUidView.as_view()),
     re_path(r'^oalexa/discoveryswitch', UserController.alexaSwitchView.as_view()),
     re_path('appset/(?P<operation>.*)', AppSetController.AppSetView.as_view()),
-    url(r'^application/(?P<operation>.*)$', ApplicationController.ApplicationView.as_view()),
-    url(r'^login/oauth/(?P<operation>.*)$', ApplicationController.AuthView.as_view()),
-    url(r'^grant/code/(?P<operation>.*)$', ApplicationController.GrantCodeView.as_view()),
-    url(r'^user/ex/(?P<operation>.*)$', UserExController.UserExView.as_view()),
-    url(r'^v3/equipment/(?P<operation>.*)$', EquipmentManagerV3.EquipmentManagerV3.as_view()),
-    url(r'^cloudstorage/(?P<operation>.*)$', CloudStorage.CloudStorageView.as_view()),
-    url(r'^payCycle/(?P<operation>.*)$', PaymentCycle.PaypalCycleNotify.as_view()),  # 周期扣款
-    url(r'^paypalCycleNotify/(?P<operation>.*)$', PaymentCycle.PaypalCycleNotify.as_view()),  # paypal周期扣款订阅通知
-    url(r'^paymentCycle/(?P<operation>.*)$', PaymentCycle.payCycle.as_view()),  # paypal周期扣款
-
-    # AI服务
-    url(r'^AiService/(?P<operation>.*)$', AiController.AiView.as_view()),
-    # 消息提醒
-    url(r'^app/setting/notification/(?P<operation>.*)$', EquipmentMessagePush.EquipmentMessagePushView.as_view()),
-
-    # 新增解密的接口
-    url(r'^v3/account/changePwd$', UserController.v3ChangePwdView.as_view()),
-    url(r'^v3/account/resetPwdByCode$', UserController.v3resetPwdByCodeView.as_view()),
-    url(r'^v3/account/register$', UserController.v3registerView.as_view()),
-    url(r'^v3/uiduser/add', UidUser.v3addInterface),
-    url(r'^v3/uiduser/query', UidUser.v3queryInterface),
-    # 判断节假日接口
-    url(r'^date/(?P<operation>.*)$', DateController.DateConView.as_view()),
-
-    url(r'^equipment/flow_test$', EquipmentManager.uid_status_test),
-    url(r'^account/appFrequency/(?P<operation>.*)$', UserController.UserAppFrequencyView.as_view()),
-    url(r'^v2/userbrand/(?P<operation>.*)$', UserBrandControllerV2.UserBrandV2.as_view()),
-    url(r'^statistcs/appFrequencyMonth$', StatisticsController.statistcsAppFrequency),
-    url(r'^statistcs/appFrequencyYear$', StatisticsController.statistcsAppFrequencyYear),
-    url(r'^statistcs/pushDay$', StatisticsController.statistcsPushDay),
-    url(r'^statistcs/pushMonth$', StatisticsController.statistcsPushMonth),
-
-    # 统计alexa连接数
-    url(r'^alexa/(?P<operation>.*)$', Alexa.AlexaConnectNum.as_view()),
-
-    # FAQ
-    url(r'^faq/upload', FAQController.FAQUploadView.as_view()),
-    url(r'^faq/image/(?P<filePath>.*)$', FAQController.getFAQImage.as_view()),
-    url(r'^faq/(?P<operation>.*)$', FAQController.FAQView.as_view()),
-
-    # 苹果登录
-    url(r'^ios/authsign', UserController.AppleAuthLogin.as_view()),
-    # app/设备上传日志接口
-    url(r'^appLog/(?P<operation>.*)$', AppLogController.AppLogView.as_view()),
-    url(r'deviceLog/(?P<operation>.*)', DeviceLogController.DeviceLogView.as_view()),
-    # 本地登录接口
-    url(r'^local/(?P<operation>.*)$', UserController.LocalUserView.as_view()),
-
-    url(r'^account/updateUserCountry', UserController.updateUserCountry),
-    url(r'^equipmentVersionLimit/(?P<operation>.*)$', EquipmentVersionLimit.EquipmentVersionLimitView.as_view()),
-
-    # 订阅邮件
-    url(r'^account/subscribe$', UserController.SubscribeEmailView.as_view()),
-    url(r'^account/subscribe/download$', UserController.SubscribeEmailView.as_view()),
-
-    # 语音提示
-    url(r'^voicePrompt/(?P<operation>.*)$', VoicePromptController.VoicePromptView.as_view()),
-    # 设备类型
-    url(r'^deviceType/(?P<operation>.*)$', DeviceTypeController.DeviceTypeView.as_view()),
-
-    # cdk(激活码)
-    url(r'^cdk/(?P<operation>.*)$', CDKController.CDKView.as_view()),
-    # 云存转移功能
-    url(r'^cloudTransfer/(?P<operation>.*)$', CloudTransfer.cloudTestView.as_view()),
-    # 优惠券
-    url(r'^coupon/(?P<operation>.*)$', CouponController.CouponView.as_view()),
-
-    # 云存服务统计
-    url(r'^Cloudsum/(?P<operation>.*)$', Cloudsum.Cloudsum.as_view()),
-    # 设备ip地区统计
-    url(r'^device/StatisticsIpRegion$', DeviceConfirmRegion.StatisticsIpRegion.as_view()),
-
-    # Iot Core
+    re_path(r'^application/(?P<operation>.*)$', ApplicationController.ApplicationView.as_view()),
+    re_path(r'^login/oauth/(?P<operation>.*)$', ApplicationController.AuthView.as_view()),
+    re_path(r'^grant/code/(?P<operation>.*)$', ApplicationController.GrantCodeView.as_view()),
+    re_path(r'^user/ex/(?P<operation>.*)$', UserExController.UserExView.as_view()),
+    re_path(r'^v3/equipment/(?P<operation>.*)$', EquipmentManagerV3.EquipmentManagerV3.as_view()),
+    re_path(r'^cloudstorage/(?P<operation>.*)$', CloudStorage.CloudStorageView.as_view()),
+    re_path(r'^payCycle/(?P<operation>.*)$', PaymentCycle.PaypalCycleNotify.as_view()),
+    re_path(r'^paypalCycleNotify/(?P<operation>.*)$', PaymentCycle.PaypalCycleNotify.as_view()),
+    re_path(r'^paymentCycle/(?P<operation>.*)$', PaymentCycle.payCycle.as_view()),
+    re_path(r'^AiService/(?P<operation>.*)$', AiController.AiView.as_view()),
+    re_path(r'^app/setting/notification/(?P<operation>.*)$', EquipmentMessagePush.EquipmentMessagePushView.as_view()),
+    re_path(r'^v3/account/changePwd$', UserController.v3ChangePwdView.as_view()),
+    re_path(r'^v3/account/resetPwdByCode$', UserController.v3resetPwdByCodeView.as_view()),
+    re_path(r'^v3/account/register$', UserController.v3registerView.as_view()),
+    re_path(r'^v3/uiduser/add', UidUser.v3addInterface),
+    re_path(r'^v3/uiduser/query', UidUser.v3queryInterface),
+    re_path(r'^date/(?P<operation>.*)$', DateController.DateConView.as_view()),
+    re_path(r'^equipment/flow_test$', EquipmentManager.uid_status_test),
+    re_path(r'^account/appFrequency/(?P<operation>.*)$', UserController.UserAppFrequencyView.as_view()),
+    re_path(r'^v2/userbrand/(?P<operation>.*)$', UserBrandControllerV2.UserBrandV2.as_view()),
+    re_path(r'^statistcs/appFrequencyMonth$', StatisticsController.statistcsAppFrequency),
+    re_path(r'^statistcs/appFrequencyYear$', StatisticsController.statistcsAppFrequencyYear),
+    re_path(r'^statistcs/pushDay$', StatisticsController.statistcsPushDay),
+    re_path(r'^statistcs/pushMonth$', StatisticsController.statistcsPushMonth),
+    re_path(r'^alexa/(?P<operation>.*)$', Alexa.AlexaConnectNum.as_view()),
+    re_path(r'^faq/upload', FAQController.FAQUploadView.as_view()),
+    re_path(r'^faq/image/(?P<filePath>.*)$', FAQController.getFAQImage.as_view()),
+    re_path(r'^faq/(?P<operation>.*)$', FAQController.FAQView.as_view()),
+    re_path(r'^ios/authsign', UserController.AppleAuthLogin.as_view()),
+    re_path(r'^appLog/(?P<operation>.*)$', AppLogController.AppLogView.as_view()),
+    re_path(r'deviceLog/(?P<operation>.*)$', DeviceLogController.DeviceLogView.as_view()),
+    re_path(r'^local/(?P<operation>.*)$', UserController.LocalUserView.as_view()),
+    re_path(r'^account/updateUserCountry', UserController.updateUserCountry),
+    re_path(r'^equipmentVersionLimit/(?P<operation>.*)$', EquipmentVersionLimit.EquipmentVersionLimitView.as_view()),
+    re_path(r'^account/subscribe$', UserController.SubscribeEmailView.as_view()),
+    re_path(r'^account/subscribe/download$', UserController.SubscribeEmailView.as_view()),
+    re_path(r'^voicePrompt/(?P<operation>.*)$', VoicePromptController.VoicePromptView.as_view()),
+    re_path(r'^deviceType/(?P<operation>.*)$', DeviceTypeController.DeviceTypeView.as_view()),
+    re_path(r'^cdk/(?P<operation>.*)$', CDKController.CDKView.as_view()),
+    re_path(r'^cloudTransfer/(?P<operation>.*)$', CloudTransfer.cloudTestView.as_view()),
+    re_path(r'^coupon/(?P<operation>.*)$', CouponController.CouponView.as_view()),
+    re_path(r'^Cloudsum/(?P<operation>.*)$', Cloudsum.Cloudsum.as_view()),
+    re_path(r'^device/StatisticsIpRegion$', DeviceConfirmRegion.StatisticsIpRegion.as_view()),
     re_path('iot/(?P<operation>.*)', IotCoreController.IotCoreView.as_view()),
-
-    # S3预签名
-    url(r's3_getsts/(?P<operation>.*)$', S3GetStsController.S3GetStsView.as_view()),
-
-    # 云分配UID
-    path('admin/', admin.site.urls),
+    re_path(r's3_getsts/(?P<operation>.*)$', S3GetStsController.S3GetStsView.as_view()),
+    re_path('admin/', admin.site.urls),
     re_path('user/(?P<operation>.*)', UIDManageUserController.UserView.as_view()),
     re_path('uid/(?P<operation>.*)', UIDController.UIDView.as_view()),
     re_path('history/(?P<operation>.*)', HistoryUIDController.HistoryUIDView.as_view()),
     re_path('^log/(?P<operation>.*)', LogController.LogView.as_view()),
     re_path('orderTask/(?P<operation>.*)', OrderTaskController.OrderTaskView.as_view()),
-    path('upload', FileController.UploadUIDFileView.as_view()),
-    path('download', FileController.DownloadUIDFileView.as_view()),
-    path('sales', SalesController.SalesView.as_view()),
-    path('device/online', SalesController.DeviceOnlineView.as_view()),
+    re_path('^upload', FileController.UploadUIDFileView.as_view()),
+    re_path('^download', FileController.DownloadUIDFileView.as_view()),
+    re_path('^sales', SalesController.SalesView.as_view()),
+    re_path('device/online', SalesController.DeviceOnlineView.as_view()),
     re_path('serialNumber/(?P<operation>.*)', SerialNumberController.SerialNumberView.as_view()),
     re_path('deviceShadow/updateV2', ShadowController.update_device_shadow),
     re_path('company/(?P<operation>.*)', CompanyController.CompanyView.as_view()),
     re_path('region/(?P<operation>.*)', RegionController.RegionView.as_view()),
     re_path('vpg/(?P<operation>.*)', VPGController.VPGView.as_view()),
-    path('vpgUid/uid', VPGController.do_upload_uid),
+    re_path('vpgUid/uid', VPGController.do_upload_uid),
     re_path('language/(?P<operation>.*)', LanguageController.LanguageView.as_view()),
-
     re_path('test/(?P<operation>.*)', TestController.TestView.as_view()),
-    # 日志管理系统
-    url(r'^OperatingLogs/(?P<operation>.*)$', OperatingLogs.OperatingLogsView.as_view()),
-    url(r'^ProcessInfo/(?P<operation>.*)$', ProcessInfo.ProcessInfoView.as_view()),
-    url(r'^Cloudsum/(?P<operation>.*)$', Cloudsum.Cloudsum.as_view()),
-
-    url(r'regionCountry/(?P<operation>.*$)', RegionCountryController.RegionCountryView.as_view()),
-
-    # 验证验证码
-    url(r'verifyCode/(?P<operation>.*$)', VerifyCodeController.VerifyCodeView.as_view()),
-
-    # 设备确定分配地区
-    url(r'^device/confirmRegion$', DeviceConfirmRegion.ConfirmRegion.as_view()),
-    url(r'^device/confirmRegionV2$', DeviceConfirmRegion.ConfirmRegionV2.as_view()),
-    url(r'^device/confirmCountry$', DeviceConfirmRegion.confirm_country_with_ip),
-
-    # pc端软件信息
-    url(r'^pcInfo/(?P<operation>.*)$', PcInfo.PcInfo.as_view()),
-
-    # pc端测试软件
-    url(r'^pcTest/(?P<operation>.*)$', PctestController.PcTest.as_view()),
-
-    # 设备debug
+    re_path(r'^OperatingLogs/(?P<operation>.*)$', OperatingLogs.OperatingLogsView.as_view()),
+    re_path(r'^ProcessInfo/(?P<operation>.*)$', ProcessInfo.ProcessInfoView.as_view()),
+    re_path(r'^Cloudsum/(?P<operation>.*)$', Cloudsum.Cloudsum.as_view()),
+    re_path(r'regionCountry/(?P<operation>.*$)', RegionCountryController.RegionCountryView.as_view()),
+    re_path(r'verifyCode/(?P<operation>.*$)', VerifyCodeController.VerifyCodeView.as_view()),
+    re_path(r'^device/confirmRegion$', DeviceConfirmRegion.ConfirmRegion.as_view()),
+    re_path(r'^device/confirmRegionV2$', DeviceConfirmRegion.ConfirmRegionV2.as_view()),
+    re_path(r'^device/confirmCountry$', DeviceConfirmRegion.confirm_country_with_ip),
+    re_path(r'^pcInfo/(?P<operation>.*)$', PcInfo.PcInfo.as_view()),
+    re_path(r'^pcTest/(?P<operation>.*)$', PctestController.PcTest.as_view()),
     re_path('deviceDebug/(?P<operation>.*)', DeviceDebug.DeviceDebug.as_view()),
-
-    # 问卷调查
-    url(r'^api/surveys/(?P<operation>.*)$', CloudStorageController.CloudStorageView.as_view()),
-    # 设备分享
-    url(r'^api/device/share/(?P<operation>.*)$', UserDeviceShareController.UserDeviceShareView.as_view()),
-
-    # 网关家庭模块
-    url(r'^app/sensor/gateway/(?P<operation>.*)$', EquipmentFamilyController.EquipmentFamilyView.as_view()),
-    url(r'^loocam/', include("Ansjer.server_urls.loocam_url")),
+    re_path(r'^api/surveys/(?P<operation>.*)$', CloudStorageController.CloudStorageView.as_view()),
+    re_path(r'^api/device/share/(?P<operation>.*)$', UserDeviceShareController.UserDeviceShareView.as_view()),
+    re_path(r'^app/sensor/gateway/(?P<operation>.*)$', EquipmentFamilyController.EquipmentFamilyView.as_view()),
+    re_path(r'^loocam/', include("Ansjer.server_urls.loocam_url")),
     re_path(r'^api/loocam/', include("Ansjer.server_urls.loocam_url")),
-    # 联通4G套餐模块
-    url(r'^unicom/', include("Ansjer.server_urls.unicom_url")),
-    # 算法小店
-    url(r'^algorithm-shop/', include("Ansjer.server_urls.algorithm_shop_url")),
+    re_path(r'^unicom/', include("Ansjer.server_urls.unicom_url")),
+    re_path(r'^algorithm-shop/', include("Ansjer.server_urls.algorithm_shop_url")),
     re_path(r'^api/algorithm/', include("Ansjer.server_urls.algorithm_shop_url")),
-    # KVS模块
-    url(r'^kvs/', include("Ansjer.server_urls.kvs_url")),
-    # 超级密码模块
+    re_path(r'^kvs/', include("Ansjer.server_urls.kvs_url")),
+    re_path(r'^icloud/', include("Ansjer.server_urls.icloud_url")),
     re_path('appAccout/(?P<operation>.*)', AppAccountManagement.AppAccoutView.as_view()),
-
-    # 传感器网关
     re_path('sensorGateway/(?P<operation>.*)', SensorGatewayController.SensorGateway.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(r'^api/surveys/(?P<operation>.*)$', CloudStorageController.CloudStorageView.as_view()),
+    re_path(r'^api/device/share/(?P<operation>.*)$', UserDeviceShareController.UserDeviceShareView.as_view()),
+    re_path(r'^server/(?P<apiVersion>[a-zA-Z0-9]+)/open/detect/(?P<operation>.*)$',
+            DetectControllerV2.DetectControllerViewV2.as_view()),
+
+    # 后台界面接口 -------------------------------------------------------------------------------------------------------
+    # 登录,用户信息,权限
+    re_path(r'^login$', UserManageController.LoginView.as_view()),
+    re_path(r'^noPasslogin$', UserManageController.LoginView.as_view()),
+    re_path(r'^userInfo$', UserManageController.GetPermissions.as_view()),
+    re_path(r'^router/getList$', UserManageController.GetList.as_view()),
     # 角色管理
     re_path('roleManagement/(?P<operation>.*)', RoleController.RoleView.as_view()),
     # 菜单管理
@@ -396,13 +294,13 @@ urlpatterns = [
     re_path(r'serial/(?P<operation>.*)', SerialManageController.SerialView.as_view()),
     # 数据系统模块
     re_path(r'^dataManagement/', include("Ansjer.server_urls.datasystem_url")),
-    # 后台界面接口 -----------------------------------------------------
+    # 数据系统模块
+    re_path(r'^icloudserve/(?P<operation>.*)', IcloudManagementController.IcloudServeView.as_view()),
+    # 后台界面接口 -------------------------------------------------------------------------------------------------------
 
-    # 定时删除任务接口
+    # 定时任务接口
     re_path(r'^cron/del/(?P<operation>.*)', CronTaskController.CronDelDataView.as_view()),
-    # 定时更新任务接口
     re_path(r'^cron/update/(?P<operation>.*)', CronTaskController.CronUpdateDataView.as_view()),
-    # 定时收集数据任务接口
     re_path(r'^cron/collect/(?P<operation>.*)', CronTaskController.CronCollectDataView.as_view()),
 
     # 国内域名备案网站/错误路径

+ 3 - 3
Controller/AWS/KVSController.py

@@ -372,7 +372,7 @@ class KVSView(View):
             return response.json(0, {"HlsStreamingSessionUrl": hls_streaming_session_url})
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def get_device_midea_list(request_dict, response):
@@ -430,7 +430,7 @@ class KVSView(View):
             return response.json(0, res)
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def download_clip(request_dict, response):
@@ -469,4 +469,4 @@ class KVSView(View):
             return res
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))

+ 17 - 18
Controller/AiController.py

@@ -56,20 +56,20 @@ class AiView(View):
             user_id = tko.userID
 
             # 套餐相关接口
-            if operation == 'commoditylist':        # 查询套餐列表
+            if operation == 'commoditylist':  # 查询套餐列表
                 return self.commodity_list(request_dict, response)
-            elif operation == 'experienceOrder':    # 体验套餐
+            elif operation == 'experienceOrder':  # 体验套餐
                 return self.experience_order(request_dict, user_id, response)
-            elif operation == 'createpayorder':     # 创建支付订单
+            elif operation == 'createpayorder':  # 创建支付订单
                 return self.create_pay_order(request_dict, request, user_id, response)
-            elif operation == 'queryorderlist':     # 查询订单列表
+            elif operation == 'queryorderlist':  # 查询订单列表
                 return self.query_order_list(request_dict, user_id, response)
-            elif operation == 'getUsingPackage':    # 获取当前使用套餐
+            elif operation == 'getUsingPackage':  # 获取当前使用套餐
                 return self.get_using_package(request_dict, response)
             # 开关相关接口
-            elif operation == 'getAiStatus':        # 获取开关状态
+            elif operation == 'getAiStatus':  # 获取开关状态
                 return self.get_ai_status(request_dict, response)
-            elif operation == 'changeaistatus':     # 修改开关状态
+            elif operation == 'changeaistatus':  # 修改开关状态
                 return self.change_ai_status(request_dict, user_id, response)
             else:
                 return response.json(414)
@@ -118,7 +118,7 @@ class AiView(View):
             }
             return response.json(0, result)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def experience_order(request_dict, user_id, response):
@@ -209,7 +209,7 @@ class AiView(View):
                                            store_meal_name=store_meal_name, order_type=1,
                                            rank_id=1, ai_rank_id=rank, status=1)
                 # ai服务表创建数据
-                AiService.objects.create(uid=uid, channel=channel, orders_id=orderID, detect_status=1, endTime=endTime,
+                AiService.objects.create(uid=uid, channel=channel, detect_status=1, endTime=endTime,
                                          addTime=nowTime, updTime=nowTime, use_status=1)
                 logger.info('{}成功开通AI体验,结束时间{}'.format(uid, endTime))
                 if pay_type == 10:
@@ -225,8 +225,8 @@ class AiView(View):
                 pay_ok_url = "{}cloudstorage/payOK?paytype={}&lang={}".format(SERVER_DOMAIN_SSL, pay_type, lang)
                 return response.json(0, pay_ok_url)
         except Exception as e:
-            print(e)
             redisObj.del_data(key=redis_key)
+            logger.info('开通AI异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
             return response.json(474)
 
     @classmethod
@@ -323,7 +323,7 @@ class AiView(View):
             return response.json(0, res_data)
 
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def query_order_list(request_dict, user_id, response):
@@ -351,7 +351,7 @@ class AiView(View):
         try:
             order_qs = Order_Model.objects.filter(userID_id=user_id, status=1, order_type=1, ai_rank__lang__lang=lang)
 
-            if uid:     # 查询指定设备订单
+            if uid:  # 查询指定设备订单
                 order_qs.filter(UID=uid)
             if not order_qs.exists():
                 return response.json(173)
@@ -383,7 +383,7 @@ class AiView(View):
                         data.append(order)
             return response.json(0, {'data': data, 'count': count})
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def get_using_package(request_dict, response):
@@ -425,7 +425,7 @@ class AiView(View):
 
             return response.json(0, [ai_service_data])
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def get_ai_status(request_dict, response):
@@ -449,7 +449,7 @@ class AiView(View):
             }
             return response.json(0, {'data': res})
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def change_ai_status(request_dict, user_id, response):
@@ -589,7 +589,7 @@ class AiView(View):
                     return response.json(10044)
                 return response.json(0, {'aiIdentificationUrl': aiIdentificationUrl, 'endTime': endTime, 'etk': etk})
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def create_paypal_payment(lang, order_id, price, currency, content):
@@ -846,8 +846,7 @@ class AiView(View):
         effective_day = order_list[0]['ai_rank__effective_day']
 
         ai_service_qs = AiService.objects.filter(Q(uid=UID), Q(channel=channel), Q(use_status=1))
-        ai_service_dict = {'orders_id': order_id,
-                           'uid': UID,
+        ai_service_dict = {'uid': UID,
                            'channel': channel,
                            'detect_status': 1,
                            'addTime': now_time,

+ 2 - 2
Controller/AlgorithmShop/AlgorithmShopController.py

@@ -191,7 +191,7 @@ class AlgorithmShopView(View):
             return response.json(0, result_dto)
         except Exception as e:
             LOGGER.info('接口异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @classmethod
     def get_scenario_algorithm_list(cls, request_dist, response):
@@ -269,7 +269,7 @@ class AlgorithmShopView(View):
             return response.json(0, algorithm_list)
         except Exception as e:
             print('查询算法小店列表异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @classmethod
     def get_algorithm_details(cls, request_dict, response):

+ 1 - 1
Controller/AppAccountManagement.py

@@ -82,7 +82,7 @@ class AppAccoutView(View):
             return response.json(0)
         except Exception as e:
             print('生成验证码异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def verifyTheVerificationCode(request_dict, response, userID):

+ 297 - 46
Controller/CloudStorage.py

@@ -21,17 +21,19 @@ from django.http import JsonResponse, HttpResponseRedirect, HttpResponse
 from django.views.generic.base import View
 
 from Ansjer.config import SERVER_DOMAIN, PAYPAL_CRD, SERVER_DOMAIN_SSL, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, \
-    AWS_ARN, OAUTH_ACCESS_TOKEN_SECRET
+    AWS_ARN, OAUTH_ACCESS_TOKEN_SECRET, DETECT_PUSH_DOMAINS, CONFIG_INFO, CONFIG_CN
 from Controller.CheckUserData import DataValid
 from Controller.CloudPhoto.CloudServiceController import CloudServiceController
 from Controller.PaymentCycle import Paypal
 from Model.models import Device_Info, Order_Model, Store_Meal, VodHlsModel, UID_Bucket, StsCrdModel, \
     ExperienceContextModel, Pay_Type, CDKcontextModel, Device_User, SysMsgModel, Unused_Uid_Meal, PromotionRuleModel, \
-    VideoPlaybackTimeModel, CouponModel, VodBucketModel, VodHlsSummary, VodHlsTagType
+    VideoPlaybackTimeModel, CouponModel, VodBucketModel, VodHlsSummary, AiService, UidSetModel, UidPushModel, \
+    VodHlsTagType, ICloudStoreMeal, IcloudUseDetails, IcloudService
 from Object.AWS.AmazonS3Util import AmazonS3Util
 from Object.AWS.S3Email import S3Email
 from Object.AliPayObject import AliPayObject
 from Object.AliSmsObject import AliSmsObject
+from Object.ETkObject import ETkObject
 from Object.RedisObject import RedisObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
@@ -45,6 +47,7 @@ from Service.VodHlsService import SplitVodHlsObject
 ssl._create_default_https_context = ssl._create_unverified_context
 LOGGER = logging.getLogger('info')
 
+
 # 设备信息添加
 class CloudStorageView(View):
 
@@ -95,6 +98,8 @@ class CloudStorageView(View):
                 return self.do_create_pay_order(request_dict, user_id, ip, response)
             elif operation == 'changevodstatus':  # 修改云存状态,传送两个url,即getsignsts接口和storeplaylist接口
                 return self.do_change_vod_status(request_dict, user_id, response)
+            elif operation == 'changevodaistatus':  # 修改云存AI状态
+                return self.do_change_vod_ai_status(request_dict, user_id, response)
             elif operation == 'queryvodlist':  # 获取视频播放列表
                 return self.do_query_vod_list(request_dict, user_id, response)
             elif operation == 'commoditylist':  # 查询套餐列表
@@ -295,11 +300,12 @@ class CloudStorageView(View):
         now_time = int(time.time())
 
         split_vod_hls_obj = SplitVodHlsObject()
-        vod_hls_qs = split_vod_hls_obj.get_vod_hls_data(uid=uid, channel=channel, start_time=start_time,
+        vod_hls_qs = split_vod_hls_obj.get_vod_hls_data(uid=uid, channel=channel, start_time__gte=start_time,
                                                         end_time__gte=now_time).values("sec", "fg", "bucket_id",
-                                                                                       'start_time')
+                                                                                       'start_time')[:10]
         if not vod_hls_qs.exists():
             return response.json(173)
+        vod_hls_qs = sorted(vod_hls_qs, key=lambda item: item['start_time'])[:10]
         bucket_id = vod_hls_qs[0]['bucket_id']
         vod_bucket_qs = VodBucketModel.objects.filter(id=bucket_id).values('bucket', 'region', 'mold')
         if not vod_bucket_qs.exists():
@@ -307,7 +313,6 @@ class CloudStorageView(View):
         bucket_region = vod_bucket_qs[0]['region']
         bucket_name = vod_bucket_qs[0]['bucket']
         mold = vod_bucket_qs[0]["mold"]
-        fg = int(vod_hls_qs[0]['fg'])
         s3_obj = AmazonS3Util(
             AWS_ACCESS_KEY_ID[mold],
             AWS_SECRET_ACCESS_KEY[mold],
@@ -317,16 +322,20 @@ class CloudStorageView(View):
         playlist_entries = []
         # ts_count = fg & 0xf
         # fg 64位整型,低四位代表ts文件总数,然后进行位运算,一次移四位,每四位转为十进制即为当前ts文件的秒数
-        for i in range(15):
-            shift = (i + 1) * 4
-            duration = (fg >> shift) & 0xf
-            if duration > 0:
-                ts_file = '{uid}/vod{channel}/{time}/ts{i}.ts'.format(uid=uid, channel=channel, time=start_time, i=i)
-                response_url = s3_obj.generate_file_obj_url(bucket_name, ts_file)
-                playlist_entries.append({
-                    'name': response_url,
-                    'duration': duration,
-                })
+        for item in vod_hls_qs:
+            fg = int(item['fg'])
+            temp_time = item['start_time']
+            for i in range(15):
+                shift = (i + 1) * 4
+                duration = (fg >> shift) & 0xf
+                if duration > 0:
+                    ts_file = '{uid}/vod{channel}/{time}/ts{i}.ts'.format(uid=uid, channel=channel, time=temp_time,
+                                                                          i=i)
+                    response_url = s3_obj.generate_file_obj_url(bucket_name, ts_file)
+                    playlist_entries.append({
+                        'name': response_url,
+                        'duration': duration,
+                    })
 
         playlist = PlaylistGenerator(playlist_entries).generate()
         response = HttpResponse(playlist)
@@ -397,7 +406,7 @@ class CloudStorageView(View):
                         "Effect": "Allow",
                         "Action": "s3:*",
                         "Resource": ["{aws_arn}:::{bucket_name}/{uid_channel}*".
-                                         format(aws_arn=aws_arn, bucket_name=bucket_name, uid_channel=storage)]
+                                     format(aws_arn=aws_arn, bucket_name=bucket_name, uid_channel=storage)]
                     }
                 ]
             }
@@ -429,7 +438,7 @@ class CloudStorageView(View):
                                            addTime=now_time, type=1)
             return JsonResponse(status=200, data=res)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def do_query_vod_list(request_dict, user_id, response):  # 获取视频播放列表
@@ -461,11 +470,10 @@ class CloudStorageView(View):
             })
 
         device_info_qs = Device_Info.objects.filter(userID_id=user_id, UID=uid, isShare=False).values(
-            'vodPrimaryUserID',
-            'vodPrimaryMaster')
+            'vodPrimaryUserID', 'Type', 'vodPrimaryMaster')
         if not device_info_qs.exists():
             return response.json(12)
-
+        device_type = device_info_qs[0]['Type']
         device_info_qs_time_over = int(time.time())
         if uid == 'UWE2ZJ52SE4FX75U111A':
             logger.info({
@@ -476,8 +484,10 @@ class CloudStorageView(View):
         if device_info_qs[0]['vodPrimaryUserID'] != user_id:
             return response.json(10034)
         now_time = int(time.time())
-        uid_bucket_qs = UID_Bucket.objects.filter(uid=uid, endTime__gte=now_time, channel=channel).values(
-            'bucket_id').order_by('addTime')
+        if device_type == 34:  # 枪球设备开通云存不区分通道
+            uid_bucket_qs = UID_Bucket.objects.filter(uid=uid, endTime__gte=now_time)
+        else:
+            uid_bucket_qs = UID_Bucket.objects.filter(uid=uid, endTime__gte=now_time, channel=channel)
         if not uid_bucket_qs.exists():
             return response.json(10030)
 
@@ -645,7 +655,7 @@ class CloudStorageView(View):
             res = {'code': 0, 'msg': '存储成功'}
             return HttpResponse(json.dumps(res, ensure_ascii=False), content_type='application/json,charset=utf-8')
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def do_change_vod_status(request_dict, user_id, response):  # 修改云存状态
@@ -666,18 +676,23 @@ class CloudStorageView(View):
         if not all([uid, status, channel]):
             return response.json(444, 'uid,status,channel')
         device_info_qs = Device_Info.objects.filter(userID_id=user_id, UID=uid, isShare=False, isExist=1).values(
-            'vodPrimaryUserID')
+            'vodPrimaryUserID', 'Type')
         if not device_info_qs.exists() or device_info_qs[0]['vodPrimaryUserID'] != user_id:
             return response.json(12)
-        uid_bucket_qs = UID_Bucket.objects.filter(channel=channel, uid=uid)
+        device_type = device_info_qs[0]['Type']
+        if device_type == 34:  # 枪球设备开通云存不区分通道
+            uid_bucket_qs = UID_Bucket.objects.filter(uid=uid)
+        else:
+            uid_bucket_qs = UID_Bucket.objects.filter(channel=channel, uid=uid)
         if not uid_bucket_qs.exists():
             return response.json(10030)
         now_time = int(time.time())
         if now_time > uid_bucket_qs[0].endTime:
             return response.json(10031)
-        uid_bucket_qs.update(status=status)
         if status == 0:
+            uid_bucket_qs.update(status=status)
             return response.json(0)
+        uid_bucket_qs.update(status=status, channel=channel)
         uid_obj = UidTokenObject()
         uid_obj.generate(data={'uid': uid, 'channel': channel})
 
@@ -689,6 +704,157 @@ class CloudStorageView(View):
         store_hls_url = '{}cloudstorage/storeplaylist?uidToken={}'.format(urls, uid_obj.token)
         return response.json(0, {'uidTkUrl': uid_tk_url, 'storeHlsUrl': store_hls_url})
 
+    @staticmethod
+    def do_change_vod_ai_status(request_dict, user_id, response):  # 修改云存状态
+        """
+        修改云存状态
+        @param request_dict: 请求数据
+        @param user_id: 用户id
+        @request_dict uid: uid
+        @request_dict status: 套餐状态
+        @request_dict channel: 通道
+        @param response: 响应
+        @return: response
+        """
+        uid = request_dict.get('uid', None)
+        vod_status = request_dict.get('vod_status', None)
+        channel = request_dict.get('channel', None)
+        domain_name = request_dict.get('domain_name', None)
+        token_val = request_dict.get('token_val', None)
+        appBundleId = request_dict.get('appBundleId', None)
+        app_type = request_dict.get('app_type', None)
+        push_type = request_dict.get('push_type', None)
+        ai_status = request_dict.get('ai_status', None)
+        m_code = request_dict.get('m_code', None)
+        lang = request_dict.get('lang', 'en')
+        tz = request_dict.get('tz', '0')
+        detect_group = request_dict.get('detect_group', None)
+        interval = request_dict.get('interval', None)
+        if not all([uid, vod_status, channel]):
+            return response.json(444, 'uid,vod_status,channel')
+        vod_status = int(vod_status)
+        device_info_qs = Device_Info.objects.filter(userID_id=user_id, UID=uid, isShare=False, isExist=1).values(
+            'vodPrimaryUserID', 'Type')
+        if not device_info_qs.exists() or device_info_qs[0]['vodPrimaryUserID'] != user_id:
+            return response.json(12)
+        device_type = device_info_qs[0]['Type']
+        uid_set_qs = UidSetModel.objects.filter(uid=uid)
+        if not uid_set_qs.exists():
+            return response.json(12)
+        if device_type == 34:  # 枪球设备开通云存不区分通道
+            uid_bucket_qs = UID_Bucket.objects.filter(uid=uid)
+        else:
+            uid_bucket_qs = UID_Bucket.objects.filter(channel=channel, uid=uid)
+        if not uid_bucket_qs.exists():
+            return response.json(10030)
+        now_time = int(time.time())
+        end_time = uid_bucket_qs[0].endTime
+        if now_time > end_time:
+            return response.json(10031)
+        try:
+            with transaction.atomic():
+                if vod_status == 0:
+                    uid_bucket_qs.update(status=vod_status)
+                    ai_status = '0'
+                    if uid_set_qs[0].is_ai == 2:
+                        return response.json(0)
+                uid_bucket_qs.update(status=vod_status, channel=channel)
+                uid_obj = UidTokenObject()
+                uid_obj.generate(data={'uid': uid, 'channel': channel})
+
+                # 欧洲域名固定返回欧洲域名
+                urls = SERVER_DOMAIN_SSL
+                if domain_name in ['api.zositeche.com', 'api.loocam3.com', 'common.neutral3.com']:
+                    urls = 'https://api.zositeche.com/'
+                uid_tk_url = '{}cloudstorage/getsignsts?uidToken={}'.format(urls, uid_obj.token)
+                store_hls_url = '{}cloudstorage/storeplaylist?uidToken={}'.format(urls, uid_obj.token)
+                if uid_set_qs[0].is_ai != 2 and CONFIG_INFO != CONFIG_CN:
+                    if not all([appBundleId, app_type, token_val, uid, m_code, ai_status]):
+                        return response.json(444, 'appBundleId, app_type, token_val, uid,m_code, ai_status')
+
+                    # 如果传空上来,就默认为0
+                    tz = '0' if tz == '' else tz.replace('GMT', '')
+                    ai_status = int(ai_status)
+                    ai_service_qs = AiService.objects.filter(uid=uid, use_status=1)
+                    if not ai_service_qs.exists():
+                        return response.json(10053)
+
+                    uid_set_id = uid_set_qs[0].id
+                    interval = uid_set_qs[0].new_detect_interval if not interval else interval
+                    qs_data = {
+                        'updTime': now_time,
+                    }
+                    if interval:
+                        qs_data['detect_interval'] = int(interval)
+                        qs_data['detect_group'] = detect_group if detect_group else ''
+                    uid_set_qs.update(**qs_data)
+
+                    qs_data['detect_status'] = ai_status  # ai开关状态
+                    qs_data['endTime'] = end_time
+                    ai_service_qs.update(**qs_data)
+                    thing_name = CommonService.query_serial_with_uid(uid)  # 存在序列号则为使用序列号作为物品名
+                    topic_name = 'ansjer/generic/{}'.format(thing_name)
+
+                    if ai_status == 0:  # 关闭
+                        # mqtt通知设备关闭AI识别功能
+                        msg = {'commandType': 'AIDisable'}
+                        req_success = CommonService.req_publish_mqtt_msg(thing_name, topic_name, msg)
+                        if not req_success:
+                            return response.json(10044)
+                        if vod_status == 0:
+                            return response.json(0)
+                        return response.json(0, {'uidTkUrl': uid_tk_url, 'storeHlsUrl': store_hls_url})
+                    elif ai_status == 1:  # 开启
+                        # 更新或创建uid_push数据
+                        uid_push_qs = UidPushModel.objects.filter(userID_id=user_id, m_code=m_code, uid_set__uid=uid)
+                        uid_push_data = {
+                            'appBundleId': appBundleId,
+                            'app_type': app_type,
+                            'push_type': push_type,
+                            'token_val': token_val,
+                            'updTime': now_time,
+                            'lang': lang,
+                            'tz': tz
+                        }
+
+                        if uid_push_qs.exists():
+                            uid_push_qs.update(**uid_push_data)
+                        else:
+                            uid_push_data['uid_set_id'] = uid_set_id
+                            uid_push_data['userID_id'] = user_id
+                            uid_push_data['m_code'] = m_code
+                            uid_push_data['addTime'] = now_time
+                            UidPushModel.objects.create(**uid_push_data)
+                        if appBundleId == 0 or appBundleId == '0':
+                            LOGGER.info('cloudstorage/changevodaistatus接口推送数据{}'.format(request_dict))
+                        etkObj = ETkObject(etk='')
+                        etk = etkObj.encrypt(uid)
+
+                        # mqtt通知设备开启AI识别功能
+                        push_url = DETECT_PUSH_DOMAINS
+                        # 欧洲域名固定返回欧洲域名
+                        if domain_name in ['api.zositeche.com', 'api.loocam3.com', 'common.neutral3.com']:
+                            push_url = 'https://push.zositeche.com/'
+                        aiIdentificationUrl = '{}AiService/identification'.format(push_url)
+                        msg = {
+                            'commandType': 'AIEnable',
+                            'payload': {
+                                'etk': etk,
+                                'endTime': end_time,
+                                'aiIdentificationUrl': aiIdentificationUrl,
+                            }
+                        }
+                        req_success = CommonService.req_publish_mqtt_msg(thing_name, topic_name, msg)
+                        if not req_success:
+                            return response.json(10044)
+                        return response.json(0, {'uidTkUrl': uid_tk_url, 'storeHlsUrl': store_hls_url,
+                                                 'aiIdentificationUrl': aiIdentificationUrl, 'endTime': end_time,
+                                                 'etk': etk})
+
+                return response.json(0, {'uidTkUrl': uid_tk_url, 'storeHlsUrl': store_hls_url})
+        except Exception as e:
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
     @staticmethod
     def do_pay_error():
         response = HttpResponse()
@@ -755,13 +921,19 @@ class CloudStorageView(View):
                 channel = order_list[0]['channel']
                 rank = order_list[0]['rank']
 
-                store_qs = Store_Meal.objects.filter(id=rank).values("day", "bucket_id", "bucket__storeDay", "expire")
-                bucket_id = store_qs[0]['bucket_id']
+                store_qs = Store_Meal.objects.filter(id=rank).values("day", "bucket_id", "bucket__storeDay", "expire",
+                                                                     'icloud_store_meal_id')
                 if not store_qs.exists():
                     return response.json(173)
-                uiu_bucket_qs = UID_Bucket.objects.filter(uid=uid).values("id", "bucket_id", "bucket__storeDay",
+                bucket_id = store_qs[0]['bucket_id']
+                uid_bucket_qs = UID_Bucket.objects.filter(uid=uid).values("id", "bucket_id", "bucket__storeDay",
                                                                           "bucket__region", "endTime", "use_status")
                 expire = store_qs[0]['expire']
+                # icloud_store_meal_id = store_qs[0]['icloud_store_meal_id']
+                # icloud_meal_qs = ICloudStoreMeal.objects.filter(id=icloud_store_meal_id).values('size')
+                # if not icloud_meal_qs.exists():
+                #     return response.json(173)
+                # size = icloud_meal_qs[0]['size']
                 if order_list[0]['isSelectDiscounts'] == 1:
                     expire = store_qs[0]['expire'] * 2
                 # 是否有促销
@@ -772,8 +944,8 @@ class CloudStorageView(View):
                     promotion_rule_id = promotion[0]['id']
                     expire = expire * 2
                 with transaction.atomic():
-                    if uiu_bucket_qs.exists():
-                        uid_bucket = uiu_bucket_qs.first()
+                    if uid_bucket_qs.exists():
+                        uid_bucket = uid_bucket_qs.first()
                         if uid_bucket['use_status'] == 1 and uid_bucket['bucket_id'] == bucket_id:  # 套餐使用中并且相同套餐叠加过期时间
                             end_time = CommonService.calcMonthLater(expire, uid_bucket['endTime'])
                             UID_Bucket.objects.filter(id=uid_bucket['id']).update(uid=uid, channel=channel,
@@ -814,6 +986,20 @@ class CloudStorageView(View):
                     order_qs.update(status=1, updTime=now_time, uid_bucket_id=uid_bucket_id,
                                     promotion_rule_id=promotion_rule_id)
                     date_time = time.strftime("%Y-%m-%d", time.localtime())
+                    # 开通云盘服务
+                    # icloud_use_qs = IcloudUseDetails.objects.filter(user_id=userid).values('id')
+                    # if not icloud_use_qs.exists():
+                    #     bucket_qs = VodBucketModel.objects.filter(bucket='icloud').values('id')
+                    #     icloud_use_qs = IcloudUseDetails.objects.create(add_time=now_time, upd_time=now_time,
+                    #                                                     detect_status=1, user_id=userid,
+                    #                                                     bucket_id=bucket_qs[0]['id'])
+                    #     use_details_id = icloud_use_qs.id
+                    #     IcloudService.objects.create(add_time=now_time, upd_time=now_time, type=0,
+                    #                                  size=1, use_details_id=use_details_id)
+                    # else:
+                    #     use_details_id = icloud_use_qs[0]['id']
+                    # IcloudService.objects.create(order_id=order_id, add_time=now_time, upd_time=now_time, type=1,
+                    #                              size=size, end_time=end_time, use_details_id=use_details_id)
                     # 如果存在序列号,消息提示用序列号
                     device_info_qs = Device_Info.objects.filter(UID=uid).values('serial_number', 'Type')
                     serial_number = device_info_qs[0]['serial_number']
@@ -909,14 +1095,19 @@ class CloudStorageView(View):
             uid = order_list[0]['UID']
             channel = order_list[0]['channel']
             rank = order_list[0]['rank']
-            store_qs = Store_Meal.objects.filter(id=rank).values("day", "bucket_id", "bucket__storeDay", "expire")
-            bucket_id = store_qs[0]['bucket_id']
+            store_qs = Store_Meal.objects.filter(id=rank).values("day", "bucket_id", "bucket__storeDay", "expire",
+                                                                 'icloud_store_meal_id')
             if not store_qs.exists():
                 return response.json(173)
+            bucket_id = store_qs[0]['bucket_id']
             uid_bucket_qs = UID_Bucket.objects.filter(uid=uid).values("id", "bucket_id", "bucket__storeDay",
                                                                       "bucket__region", "endTime", "use_status")
             expire = store_qs[0]['expire']
-
+            # icloud_store_meal_id = store_qs[0]['icloud_store_meal_id']
+            # icloud_meal_qs = ICloudStoreMeal.objects.filter(id=icloud_store_meal_id).values('size')
+            # if not icloud_meal_qs.exists():
+            #     return response.json(173)
+            # size = icloud_meal_qs[0]['size']
             if order_list[0]['isSelectDiscounts'] == 1:
                 expire = store_qs[0]['expire'] * 2
             # 是否有促销
@@ -968,6 +1159,20 @@ class CloudStorageView(View):
                 order_qs.update(status=1, updTime=now_time, uid_bucket_id=uid_bucket_id,
                                 promotion_rule_id=promotion_rule_id)
                 date_time = time.strftime("%Y-%m-%d", time.localtime())
+                # 开通云盘服务
+                # icloud_use_qs = IcloudUseDetails.objects.filter(user_id=userid).values('id')
+                # if not icloud_use_qs.exists():
+                #     bucket_qs = VodBucketModel.objects.filter(bucket='icloud').values('id')
+                #     icloud_use_qs = IcloudUseDetails.objects.create(add_time=now_time, upd_time=now_time,
+                #                                                     detect_status=1, user_id=userid,
+                #                                                     bucket_id=bucket_qs[0]['id'])
+                #     use_details_id = icloud_use_qs.id
+                #     IcloudService.objects.create(add_time=now_time, upd_time=now_time, type=0,
+                #                                  size=1, use_details_id=use_details_id)
+                # else:
+                #     use_details_id = icloud_use_qs[0]['id']
+                # IcloudService.objects.create(order_id=order_id, add_time=now_time, upd_time=now_time, type=1,
+                #                              size=size, end_time=end_time, use_details_id=use_details_id)
                 # 如果存在序列号,消息提示用序列号
                 device_info_qs = Device_Info.objects.filter(UID=uid).values('serial_number', 'Type')
                 serial_number = device_info_qs[0]['serial_number']
@@ -1045,13 +1250,19 @@ class CloudStorageView(View):
                 uid = order_list[0]['UID']
                 channel = order_list[0]['channel']
                 rank = order_list[0]['rank']
-                store_qs = Store_Meal.objects.filter(id=rank).values("day", "bucket_id", "bucket__storeDay", "expire")
-                bucket_id = store_qs[0]['bucket_id']
+                store_qs = Store_Meal.objects.filter(id=rank).values("day", "bucket_id", "bucket__storeDay", "expire",
+                                                                     'icloud_store_meal_id')
                 if not store_qs.exists():
                     return HttpResponse(pay.xml_to_dict({'return_code': 'FAIL', 'return_msg': '套餐不存在'}))
+                bucket_id = store_qs[0]['bucket_id']
                 uid_bucket_qs = UID_Bucket.objects.filter(uid=uid).values("id", "bucket_id", "bucket__storeDay",
                                                                           "bucket__region", "endTime", "use_status")
                 expire = store_qs[0]['expire']
+                # icloud_store_meal_id = store_qs[0]['icloud_store_meal_id']
+                # icloud_meal_qs = ICloudStoreMeal.objects.filter(id=icloud_store_meal_id).values('size')
+                # if not icloud_meal_qs.exists():
+                #     return response.json(173)
+                # size = icloud_meal_qs[0]['size']
                 if order_list[0]['isSelectDiscounts'] == 1:
                     expire = store_qs[0]['expire'] * 2
                 # 是否有促销
@@ -1104,6 +1315,20 @@ class CloudStorageView(View):
                     order_qs.update(status=1, updTime=now_time, uid_bucket_id=uid_bucket_id,
                                     promotion_rule_id=promotion_rule_id)
                     date_time = time.strftime("%Y-%m-%d", time.localtime())
+                    # 开通云盘服务
+                    # icloud_use_qs = IcloudUseDetails.objects.filter(user_id=userid).values('id')
+                    # if not icloud_use_qs.exists():
+                    #     bucket_qs = VodBucketModel.objects.filter(bucket='icloud').values('id')
+                    #     icloud_use_qs = IcloudUseDetails.objects.create(add_time=now_time, upd_time=now_time,
+                    #                                                     detect_status=1, user_id=userid,
+                    #                                                     bucket_id=bucket_qs[0]['id'])
+                    #     use_details_id = icloud_use_qs.id
+                    #     IcloudService.objects.create(add_time=now_time, upd_time=now_time, type=0,
+                    #                                  size=1, use_details_id=use_details_id)
+                    # else:
+                    #     use_details_id = icloud_use_qs[0]['id']
+                    # IcloudService.objects.create(order_id=order_id, add_time=now_time, upd_time=now_time, type=1,
+                    #                              size=size, end_time=end_time, use_details_id=use_details_id)
                     # 如果存在序列号,消息提示用序列号
                     device_info_qs = Device_Info.objects.filter(UID=uid).values('serial_number', 'Type')
                     serial_number = device_info_qs[0]['serial_number']
@@ -1231,12 +1456,13 @@ class CloudStorageView(View):
                     return response.json(10048)
                 Order_Model.objects.create(orderID=order_id, UID=uid, channel=channel, userID_id=user_id,
                                            desc=content, payType=pay_type, payTime=now_time,
-                                           price=price, currency=currency, addTime=now_time, updTime=now_time,
+                                           price=price, currency=currency, addTime=now_time,
+                                           updTime=now_time,
                                            pay_url=sub_info['url'], isSelectDiscounts=is_select_discount,
                                            commodity_code=commodity_code, commodity_type=commodity_type,
-                                           rank_id=rank, plan_id=sub_info['plan_id'], coupon_id=coupon_id, ai_rank_id=1,
+                                           rank_id=rank, plan_id=sub_info['plan_id'], coupon_id=coupon_id,
+                                           ai_rank_id=1,
                                            store_meal_name=store_meal_name)
-
                 return response.json(0, {"redirectUrl": sub_info['url'], "orderID": order_id})
             # 正常扣款
             call_clc_url = "{}web/paid2/fail.html".format(SERVER_DOMAIN_SSL)
@@ -1265,10 +1491,12 @@ class CloudStorageView(View):
                     approval_url = str(link.href)
                     Order_Model.objects.create(orderID=order_id, UID=uid, channel=channel, userID_id=user_id,
                                                desc=content, payType=pay_type, payTime=now_time,
-                                               price=price, currency=currency, addTime=now_time, updTime=now_time,
+                                               price=price, currency=currency, addTime=now_time,
+                                               updTime=now_time,
                                                pay_url=approval_url, isSelectDiscounts=is_select_discount,
                                                commodity_code=commodity_code, commodity_type=commodity_type,
-                                               rank_id=rank, paymentID=payment_id, coupon_id=coupon_id, ai_rank_id=1,
+                                               rank_id=rank, paymentID=payment_id, coupon_id=coupon_id,
+                                               ai_rank_id=1,
                                                store_meal_name=store_meal_name)
                     return response.json(0, {"redirectUrl": approval_url, "orderID": order_id})
             return response.json(10, 'generate_order_false')
@@ -1295,7 +1523,8 @@ class CloudStorageView(View):
                     redirect_url = ali_pay_obj.alipay_prefix + order_string
                     Order_Model.objects.create(orderID=order_id, UID=uid, channel=channel, userID_id=user_id,
                                                desc=content, payType=pay_type, payTime=now_time,
-                                               price=price, currency=currency, addTime=now_time, updTime=now_time,
+                                               price=price, currency=currency, addTime=now_time,
+                                               updTime=now_time,
                                                pay_url=redirect_url, isSelectDiscounts=is_select_discount,
                                                commodity_code=commodity_code, commodity_type=commodity_type,
                                                rank_id=rank, coupon_id=coupon_id, ai_rank_id=1,
@@ -1325,7 +1554,8 @@ class CloudStorageView(View):
                                        desc=content, payType=pay_type, payTime=now_time,
                                        price=price, currency=currency, addTime=now_time, updTime=now_time,
                                        pay_url=notify_url, isSelectDiscounts=is_select_discount,
-                                       commodity_code=commodity_code, commodity_type=commodity_type, rank_id=rank,
+                                       commodity_code=commodity_code, commodity_type=commodity_type,
+                                       rank_id=rank,
                                        ai_rank_id=1, store_meal_name=store_meal_name)
             return JsonResponse(status=200, data={'result_code': 0, 'reason': 'success',
                                                   'result': response,
@@ -1402,13 +1632,19 @@ class CloudStorageView(View):
         store_qs = 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')
+                                                                                         'currency', 'commodity_type',
+                                                                                         'icloud_store_meal_id')
         if not store_qs.exists():
             return response.json(173)
         bucket_id = store_qs[0]['bucket_id']
         uid_bucket_qs = UID_Bucket.objects.filter(uid=uid).values("id", "bucket_id", "bucket__storeDay",
                                                                   "bucket__region", "endTime", "use_status")
         expire = store_qs[0]['expire']
+        # icloud_store_meal_id = store_qs[0]['icloud_store_meal_id']
+        # icloud_meal_qs = ICloudStoreMeal.objects.filter(id=icloud_store_meal_id).values('size')
+        # if not icloud_meal_qs.exists():
+        #     return response.json(173)
+        # size = icloud_meal_qs[0]['size']
         try:
             with transaction.atomic():
                 if uid_bucket_qs.exists():
@@ -1434,6 +1670,21 @@ class CloudStorageView(View):
                                                            endTime=end_time, addTime=now_time, updateTime=now_time,
                                                            use_status=1)
                     uid_bucket_id = uid_bucket.id
+                #  开通云盘体验
+                # icloud_use_qs = IcloudUseDetails.objects.filter(user_id=user_id).values('id')
+                # if not icloud_use_qs.exists():
+                #     bucket_qs = VodBucketModel.objects.filter(bucket='icloud').values('id')
+                #     icloud_use_qs = IcloudUseDetails.objects.create(add_time=now_time, upd_time=now_time,
+                #                                                     detect_status=1, user_id=user_id,
+                #                                                     bucket_id=bucket_qs[0]['id'])
+                #     use_details_id = icloud_use_qs.id
+                #     IcloudService.objects.create(add_time=now_time, upd_time=now_time, type=0,
+                #                                  size=1, use_details_id=use_details_id)
+                # else:
+                #     use_details_id = icloud_use_qs[0]['id']
+                # IcloudService.objects.create(order_id=order_id, add_time=now_time, upd_time=now_time, type=1,
+                #                              size=size, end_time=end_time, use_details_id=use_details_id)
+
                 store_meal_qs = Store_Meal.objects.filter(id=rank, lang__lang='cn', is_show=0).values('lang__title',
                                                                                                       'lang__content')
                 if store_meal_qs.exists():
@@ -1766,7 +2017,7 @@ class CloudStorageView(View):
             return response.json(0)
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def do_vod_msg_notice(self, uid, channel, user_id, lang, sys_msg_text_list, sms):  # 云存操作系统消息
         """
@@ -2004,4 +2255,4 @@ class CloudStorageView(View):
         except Exception as e:
             logger = logging.getLogger('info')
             logger.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))

+ 3 - 3
Controller/CloudTransfer.py

@@ -144,7 +144,7 @@ class cloudTestView(View):
 
         except Exception as e:
             # print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
         else:
             return response.json(0)
 
@@ -243,7 +243,7 @@ class cloudTestView(View):
                 LogModel.objects.create(**log)
             return response.json(0)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def expireMeal(self, request_dict, response):
         UID_Bucket_id = request_dict.get("UID_Bucket_id", None)
@@ -253,7 +253,7 @@ class cloudTestView(View):
                 UID_Bucket.objects.filter(id=UID_Bucket_id).update(use_status=2)
             except Exception as e:
                 # print(e)
-                return response.json(500, repr(e))
+                return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
             else:
                 return response.json(0)
         response.json(404)

+ 6 - 4
Controller/CloudVod.py

@@ -13,9 +13,10 @@ 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 import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, OSS_ROLE_ARN, SERVER_DOMAIN, PAYPAL_CRD
-from Model.models import Device_Info, Order_Model, Store_Meal, VodHlsModel, OssCrdModel, UID_Bucket, StsCrdModel, \
-    VodBucketModel
+from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, OSS_ROLE_ARN, SERVER_DOMAIN, PAYPAL_CRD, \
+    CONFIG_INFO, CONFIG_CN
+from Model.models import Device_Info, Order_Model, Store_Meal, OssCrdModel, UID_Bucket, StsCrdModel, \
+    VodBucketModel, UidSetModel, AiService
 from Object.AliPayObject import AliPayObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
@@ -564,7 +565,8 @@ class CloudVodView(View):
             thumb = bucket.sign_url('GET', ts, 3600,
                                     params={'x-oss-process': 'video/snapshot,t_1000,m_fast,w_300'})
             vod_play_list.append(
-                {'name': vod['start_time'], 'sign_url': vod_play_url, 'thumb': thumb, 'sec': vod['sec'], 'id': vod['id']})
+                {'name': vod['start_time'], 'sign_url': vod_play_url, 'thumb': thumb, 'sec': vod['sec'],
+                 'id': vod['id']})
         vod_play_list = sorted(vod_play_list, key=lambda item: -item['name'])
         return response.json(0, vod_play_list)
 

+ 227 - 52
Controller/Cron/CronTaskController.py

@@ -10,18 +10,18 @@
 import datetime
 import threading
 import time
-import logging
+
 import requests
 from django.db import connection, connections, transaction
 from django.db.models import Q, Sum, Count
 from django.views import View
 
 from Ansjer.config import USED_SERIAL_REDIS_LIST, UNUSED_SERIAL_REDIS_LIST, CONFIG_INFO, CONFIG_US, \
-    RESET_REGION_ID_SERIAL_REDIS_LIST
+    RESET_REGION_ID_SERIAL_REDIS_LIST, LOGGER
 from Model.models import Device_User, Device_Info, UidSetModel, UID_Bucket, Unused_Uid_Meal, Order_Model, StsCrdModel, \
     VodHlsModel, ExperienceContextModel, AiService, VodHlsSummary, VideoPlaybackTimeModel, DeviceUserSummary, \
     CountryModel, DeviceTypeModel, OrdersSummary, DeviceInfoSummary, CompanySerialModel, \
-    CloudLogModel, UidCloudStorageCount, UserExModel, DeviceDomainRegionModel, VodHlsTag, VodHlsTagType, \
+    CloudLogModel, UidCloudStorageCount, UserExModel, DeviceDomainRegionModel, VodHlsTag, VodHlsTagType, IcloudService, \
     Store_Meal, Lang, VodBucketModel, UnicomComboOrderInfo, UnicomDeviceInfo
 from Object.RedisObject import RedisObject
 from Object.ResponseObject import ResponseObject
@@ -30,7 +30,6 @@ from Service.CommonService import CommonService
 from Service.VodHlsService import SplitVodHlsObject
 from Object.UnicomObject import UnicomObjeect
 
-LOGGER = logging.getLogger('info')
 
 class CronDelDataView(View):
     def get(self, request, *args, **kwargs):
@@ -104,7 +103,7 @@ class CronDelDataView(View):
             UidSetModel.objects.filter(ucode__in=ucode_list, is_custom_voice=0).update(is_custom_voice=1)
             return response.json(0)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def delAppLog(response):
@@ -122,7 +121,7 @@ class CronDelDataView(View):
             cursor.close()
             return response.json(0)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def uid_cloud_storage_upload_count(response):
@@ -163,7 +162,7 @@ class CronDelDataView(View):
             connection.close()
             return response.json(0)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def delPushInfo(response):
@@ -202,7 +201,7 @@ class CronDelDataView(View):
             cursor.close()
             return response.json(0)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def delVodHls(response):
@@ -219,7 +218,7 @@ class CronDelDataView(View):
             split_vod_hls_obj.del_vod_hls_data(end_time__lt=month_ago_time)
             return response.json(0)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def del_vod_hls_tag():
@@ -243,7 +242,7 @@ class CronDelDataView(View):
             cursor.close()
             return response.json(0)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def delTesterDevice(response):
@@ -285,7 +284,7 @@ class CronDelDataView(View):
                 Device_Info.objects.filter(userID__in=device_user).delete()
             return response.json(0)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
 
 class CronUpdateDataView(View):
@@ -305,6 +304,8 @@ class CronUpdateDataView(View):
             return self.updateUnusedUidBucket(response)
         elif operation == 'updateUnusedAiService':  # 定时更新过期ai关联的未使用套餐状态
             return self.updateUnusedAiService(response)
+        elif operation == 'updateIcloudService':  # 定时更新过期云盘套餐使用状态
+            return self.updateIcloudService(response)
         elif operation == 'reqUpdateSerialStatus':  # 定时请求更新序列号状态
             return self.reqUpdateSerialStatus(response)
         elif operation == 'updateSerialStatus':  # 更新序列号状态
@@ -330,8 +331,7 @@ class CronUpdateDataView(View):
         if expired_uid_bucket.exists():
             expired_uid_bucket.update(use_status=2)
         # 监控有未使用套餐则自动生效
-        expired_uid_buckets = \
-            UID_Bucket.objects.filter(endTime__lte=now_time, has_unused=1).values("id", "uid")[0:1000]
+        expired_uid_buckets = UID_Bucket.objects.filter(endTime__lte=now_time, has_unused=1).values("id", "uid")[0:1000]
         for expired_uid_bucket in expired_uid_buckets:
             unuseds = Unused_Uid_Meal.objects.filter(
                 uid=expired_uid_bucket['uid']).values(
@@ -341,28 +341,25 @@ class CronUpdateDataView(View):
                 "addTime",
                 "expire",
                 "num",
-                "bucket_id").order_by('addTime')[0:1]
+                "bucket_id").order_by('addTime')
             if not unuseds.exists():
                 continue
             unused = unuseds[0]
             try:
                 with transaction.atomic():
-                    count_unused = Unused_Uid_Meal.objects.filter(
-                        uid=expired_uid_bucket['uid']).count()
+                    count_unused = Unused_Uid_Meal.objects.filter(uid=expired_uid_bucket['uid']).count()
                     has_unused = 1 if count_unused > 1 else 0
-                    endTime = CommonService.calcMonthLater(
-                        unused['expire'] * unused['num'])
+                    end_time = CommonService.calcMonthLater(unused['expire'] * unused['num'])
                     UID_Bucket.objects.filter(
                         uid=expired_uid_bucket['uid']).update(
                         channel=unused['channel'],
-                        endTime=endTime,
+                        endTime=end_time,
                         bucket_id=unused['bucket_id'],
                         updateTime=now_time,
                         use_status=1,
                         has_unused=has_unused)
                     Unused_Uid_Meal.objects.filter(id=unused['id']).delete()
-                    StsCrdModel.objects.filter(
-                        uid=expired_uid_bucket['uid']).delete()  # 删除sts记录
+                    StsCrdModel.objects.filter(uid=expired_uid_bucket['uid']).delete()  # 删除sts记录
             except Exception as e:
                 print(repr(e))
                 continue
@@ -401,29 +398,44 @@ class CronUpdateDataView(View):
                 continue
         return response.json(0)
 
+    @staticmethod
+    def updateIcloudService(response):
+        """
+        监控云盘套餐过期修改状态
+        @param response:
+        @return:
+        """
+        # 定时更新已过期套餐修改状态为2
+        now_time = int(time.time())
+        try:
+            IcloudService.objects.filter(Q(end_time__lte=now_time), ~Q(end_time=0),
+                                         ~Q(use_status=1)).update(use_status=1)
+            return response.json(0)
+        except Exception as e:
+            return response.json(500)
+
     @classmethod
     def reqUpdateSerialStatus(cls, response):
         redis_obj = RedisObject()
-        logger = logging.getLogger('info')
 
         # 更新已使用序列号其他服务器的状态
         used_serial_redis_list = redis_obj.lrange(USED_SERIAL_REDIS_LIST, 0, -1)  # 读取redis已使用序列号
         if used_serial_redis_list:
-            logger.info('---请求更新已使用序列号列表---used_serial_redis_list:{}'.format(used_serial_redis_list))
+            LOGGER.info('---请求更新已使用序列号列表---used_serial_redis_list:{}'.format(used_serial_redis_list))
             used_serial_redis_list = [str(i, 'utf-8') for i in used_serial_redis_list]
             cls.do_request_function(used_serial_redis_list, 3)
 
         # 更新未使用序列号其他服务器的状态
         unused_serial_redis_list = redis_obj.lrange(UNUSED_SERIAL_REDIS_LIST, 0, -1)  # 读取redis未使用序列号
         if unused_serial_redis_list:
-            logger.info('---请求更新未使用序列号列表---unused_serial_redis_list:{}'.format(unused_serial_redis_list))
+            LOGGER.info('---请求更新未使用序列号列表---unused_serial_redis_list:{}'.format(unused_serial_redis_list))
             unused_serial_redis_list = [str(i, 'utf-8') for i in unused_serial_redis_list]
             cls.do_request_function(unused_serial_redis_list, 1)
 
         # 重置地区id
         reset_region_id_serial_redis_list = redis_obj.lrange(RESET_REGION_ID_SERIAL_REDIS_LIST, 0, -1)  # 读取redis未使用序列号
         if reset_region_id_serial_redis_list:
-            logger.info('---请求重置地区id的序列号列表---:{}'.format(reset_region_id_serial_redis_list))
+            LOGGER.info('---请求重置地区id的序列号列表---:{}'.format(reset_region_id_serial_redis_list))
             reset_region_id_serial_redis_list = [str(i, 'utf-8') for i in reset_region_id_serial_redis_list]
             cls.do_request_reset_region_id(reset_region_id_serial_redis_list)
         return response.json(0)
@@ -442,31 +454,30 @@ class CronUpdateDataView(View):
         # 确认域名列表
         orders_domain_name_list = CommonService.get_orders_domain_name_list()
         redis_obj = RedisObject()
-        logger = logging.getLogger('info')
-        logger.info('---请求更新序列号线程---data:{},orders_domain_name_list:{}'.format(data, orders_domain_name_list))
+        LOGGER.info('---请求更新序列号线程---data:{},orders_domain_name_list:{}'.format(data, orders_domain_name_list))
         try:
             requests_failed_flag = False  # 请求失败标志位
             for domain_name in orders_domain_name_list:
                 url = '{}cron/update/updateSerialStatus'.format(domain_name)
                 response = requests.post(url=url, data=data, timeout=5)
-                logger.info('---请求更新序列号响应时间---:{}'.format(response.elapsed.total_seconds()))
+                LOGGER.info('---请求更新序列号响应时间---:{}'.format(response.elapsed.total_seconds()))
                 result = response.json()
                 if result['result_code'] != 0:  # 请求失败标志位置位
                     requests_failed_flag = True
                     break
 
                 # 状态为未使用,重置美洲服的地区id
-                if status == 1:     # 美洲服直接更新
+                if status == 1:  # 美洲服直接更新
                     if CONFIG_INFO == CONFIG_US:
-                        DeviceDomainRegionModel.objects.filter(~Q(region_id=0), serial_number__in=serial_redis_list).\
+                        DeviceDomainRegionModel.objects.filter(~Q(region_id=0), serial_number__in=serial_redis_list). \
                             update(region_id=0)
-                    else:   # 其他服请求到美洲服更新
+                    else:  # 其他服请求到美洲服更新
                         req_url = 'https://www.dvema.com/cron/update/reset-region-id'
                         req_data = {
                             'serial_redis_list': str(serial_redis_list)
                         }
                         response = requests.post(url=req_url, data=req_data, timeout=5)
-                        logger.info('---请求重置地区id响应时间---:{}'.format(response.elapsed.total_seconds()))
+                        LOGGER.info('---请求重置地区id响应时间---:{}'.format(response.elapsed.total_seconds()))
                         result = response.json()
                         if result['result_code'] != 0:  # 请求失败标志位置位
                             requests_failed_flag = True
@@ -480,7 +491,7 @@ class CronUpdateDataView(View):
                     for i in serial_redis_list:
                         redis_obj.lrem(USED_SERIAL_REDIS_LIST, 0, i)
         except Exception as e:
-            logger.info('---更新序列号状态异常---:{}'.format(repr(e)))
+            LOGGER.info('---更新序列号状态异常---:{}'.format(repr(e)))
 
     @staticmethod
     def do_request_reset_region_id(reset_region_id_serial_redis_list):
@@ -489,7 +500,6 @@ class CronUpdateDataView(View):
         @param reset_region_id_serial_redis_list: 序列号redis列表
         """
         redis_obj = RedisObject()
-        logger = logging.getLogger('info')
         requests_failed_flag = False  # 请求失败标志位
         data = {
             'serial_redis_list': str(reset_region_id_serial_redis_list),
@@ -505,7 +515,7 @@ class CronUpdateDataView(View):
                 for serial in reset_region_id_serial_redis_list:
                     redis_obj.lrem(RESET_REGION_ID_SERIAL_REDIS_LIST, 0, serial)
         except Exception as e:
-            logger.info('---请求重置地区id异常---:{}'.format(repr(e)))
+            LOGGER.info('---请求重置地区id异常---:{}'.format(repr(e)))
 
     @staticmethod
     def updateSerialStatus(request_dict, response):
@@ -518,8 +528,7 @@ class CronUpdateDataView(View):
         """
         serial_redis_list = request_dict.get('serial_redis_list', None)
         status = request_dict.get('status', None)
-        logger = logging.getLogger('info')
-        logger.info('---更新序列号状态参数---serial_redis_list:{},status:{}'.format(serial_redis_list, status))
+        LOGGER.info('---更新序列号状态参数---serial_redis_list:{},status:{}'.format(serial_redis_list, status))
         if not all([serial_redis_list, status]):
             return response.json(444)
         now_time = int(time.time())
@@ -529,7 +538,7 @@ class CronUpdateDataView(View):
                                                                                           update_time=now_time)
             return response.json(0)
         except Exception as e:
-            logger.info('---更新序列号状态异常---:{}'.format(repr(e)))
+            LOGGER.info('---更新序列号状态异常---:{}'.format(repr(e)))
             return response.json(500)
 
     @staticmethod
@@ -541,8 +550,7 @@ class CronUpdateDataView(View):
         @param response: 响应对象
         """
         serial_redis_list = request_dict.get('serial_redis_list', None)
-        logger = logging.getLogger('info')
-        logger.info('---重置地区id参数---serial_redis_list:{}'.format(serial_redis_list))
+        LOGGER.info('---重置地区id参数---serial_redis_list:{}'.format(serial_redis_list))
         if not serial_redis_list:
             return response.json(444)
         try:
@@ -550,7 +558,7 @@ class CronUpdateDataView(View):
             DeviceDomainRegionModel.objects.filter(serial_number__in=serial_redis_list).update(region_id=0)
             return response.json(0)
         except Exception as e:
-            logger.info('---重置地区id异常---:{}'.format(repr(e)))
+            LOGGER.info('---重置地区id异常---:{}'.format(repr(e)))
             return response.json(500)
 
     @staticmethod
@@ -571,25 +579,33 @@ class CronUpdateDataView(View):
                 elif lang == 'en':
                     Lang.objects.filter(lang=lang, store_meal__id=meal_id).update(content='1-Month plan (free trial)')
                 elif lang == 'es':
-                    Lang.objects.filter(lang=lang, store_meal__id=meal_id).update(content='Plan de 1 mes (prueba gratuita)')
+                    Lang.objects.filter(lang=lang, store_meal__id=meal_id).update(
+                        content='Plan de 1 mes (prueba gratuita)')
                 elif lang == 'fr':
-                    Lang.objects.filter(lang=lang, store_meal__id=meal_id).update(content='Forfait de 1 mois (essai gratuit)')
+                    Lang.objects.filter(lang=lang, store_meal__id=meal_id).update(
+                        content='Forfait de 1 mois (essai gratuit)')
                 elif lang == 'de':
-                    Lang.objects.filter(lang=lang, store_meal__id=meal_id).update(content='1 Monat Paket (kostenlose Testversion) ')
+                    Lang.objects.filter(lang=lang, store_meal__id=meal_id).update(
+                        content='1 Monat Paket (kostenlose Testversion) ')
                 elif lang == 'cn_tw':
                     Lang.objects.filter(lang=lang, store_meal__id=meal_id).update(content='一個月套餐(免費試用)')
                 elif lang == 'pt':
-                    Lang.objects.filter(lang=lang, store_meal__id=meal_id).update(content='Plano de 1 mês (teste gratuito)')
+                    Lang.objects.filter(lang=lang, store_meal__id=meal_id).update(
+                        content='Plano de 1 mês (teste gratuito)')
                 elif lang == 'ru':
-                    Lang.objects.filter(lang=lang, store_meal__id=meal_id).update(content='Тариф 1 месяц (бесплатный пробный период)')
+                    Lang.objects.filter(lang=lang, store_meal__id=meal_id).update(
+                        content='Тариф 1 месяц (бесплатный пробный период)')
                 elif lang == 'ja':
                     Lang.objects.filter(lang=lang, store_meal__id=meal_id).update(content='1ヶ月プラン(無料試用)')
                 elif lang == 'it':
-                    Lang.objects.filter(lang=lang, store_meal__id=meal_id).update(content='Pacchetto di 1 mese (prova gratuita)')
+                    Lang.objects.filter(lang=lang, store_meal__id=meal_id).update(
+                        content='Pacchetto di 1 mese (prova gratuita)')
                 elif lang == 'pl':
-                    Lang.objects.filter(lang=lang, store_meal__id=meal_id).update(content='jednomiesięczny pakiet (bezpłatny próbny)')
+                    Lang.objects.filter(lang=lang, store_meal__id=meal_id).update(
+                        content='jednomiesięczny pakiet (bezpłatny próbny)')
                 elif lang == 'nl':
-                    Lang.objects.filter(lang=lang, store_meal__id=meal_id).update(content='Pakket van 1 maand (gratis proefperiode)')
+                    Lang.objects.filter(lang=lang, store_meal__id=meal_id).update(
+                        content='Pakket van 1 maand (gratis proefperiode)')
             VodBucketModel.objects.filter(id=meal_qs[0]['bucket']).update(content='国内存储桶免费体验30天,录像保存7天')
             meal_qs.update(expire=1)
             return response.json(0)
@@ -597,6 +613,7 @@ class CronUpdateDataView(View):
             LOGGER.info('---修改体验套餐有效期---:{}'.format(repr(e)))
             return response.json(500)
 
+
 class CronCollectDataView(View):
     def get(self, request, *args, **kwargs):
         request.encoding = 'utf-8'
@@ -616,6 +633,8 @@ class CronCollectDataView(View):
             return self.collect_device_user(response)
         elif operation == 'collectOrder':  # 定时保存订单数据
             return self.collect_order(response)
+        elif operation == 'collectIcloudOrder':  # 定时保存云盘订单数据
+            return self.collect_icloud_order(response)
         elif operation == 'collectDeviceInfo':  # 定时保存设备数据
             return self.collect_device_info(response)
         elif operation == 'collectFlowInfo':  # 定时保存设备数据
@@ -654,7 +673,7 @@ class CronCollectDataView(View):
 
             return response.json(0)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def collect_device_user(response):
@@ -711,7 +730,7 @@ class CronCollectDataView(View):
 
             return response.json(0)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def collect_order(response):
@@ -752,6 +771,8 @@ class CronCollectDataView(View):
                     country_id = uid_set_qs[0]['tb_country'] if uid_set_qs.exists() else 0
                     country_name = country_dict.get(country_id, '未知国家')
                     order_type = item['order_type']
+                    if order_type == '4' or order_type == 4:
+                        continue
                     device_info_qs = Device_Info.objects.filter(UID=item['UID']).values('Type')
                     device_type_id = device_info_qs[0]['Type'] if device_info_qs.exists() else 0
                     device_type_name = device_type_dict.get(device_type_id, '未知设备')
@@ -942,7 +963,161 @@ class CronCollectDataView(View):
                                                      device_type=device_type_temp_dict, store_meal=store_meal_temp_dict)
             return response.json(0)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
+    @staticmethod
+    def collect_icloud_order(response):
+        try:
+            order_type = 4
+            created_time = int(time.time())
+            today = datetime.datetime.today()
+            start_time = datetime.datetime(today.year, today.month, today.day)
+            end_time = start_time + datetime.timedelta(days=1)
+            start_time = CommonService.str_to_timestamp(start_time.strftime('%Y-%m-%d %H:%M:%S'))
+            end_time = CommonService.str_to_timestamp(end_time.strftime('%Y-%m-%d %H:%M:%S'))
+            order_qs = Order_Model.objects.filter(addTime__gte=start_time, addTime__lt=end_time, order_type=order_type,
+                                                  status=1).values('userID',
+                                                                   'store_meal_name', 'price',
+                                                                   'addTime', 'currency').order_by(
+                'addTime')
+            user_list = []
+            all_order_qs = Order_Model.objects.filter(addTime__lt=start_time, status=1, order_type=order_type).values(
+                'userID')
+            for item in all_order_qs:
+                if item['userID'] not in user_list:
+                    user_list.append(item['userID'])
+            # 国家表数据
+            country_qs = CountryModel.objects.values('id', 'country_name')
+            country_dict = {}
+            for item in country_qs:
+                country_dict[item['id']] = item['country_name']
+            with transaction.atomic():
+                for item in order_qs:
+                    price = float(item['price'])
+                    currency = item['currency']
+                    user_qs = Device_User.objects.filter(userID=item['userID']).values('region_country')
+                    country_id = user_qs[0]['region_country'] if user_qs.exists() else 0
+                    country_name = country_dict.get(country_id, '未知国家')
+                    store_meal_name = item['store_meal_name']
+                    add_time_stamp = item['addTime']
+                    add_time_str = datetime.datetime.fromtimestamp(int(add_time_stamp))
+                    add_time_str = datetime.datetime(add_time_str.year, add_time_str.month, add_time_str.day)
+                    add_time_stamp = CommonService.str_to_timestamp(add_time_str.strftime('%Y-%m-%d %H:%M:%S'))
+
+                    order_summary_qs = OrdersSummary.objects.filter(time=add_time_stamp, query_type=0,
+                                                                    service_type=order_type)
+                    if item['userID'] not in user_list:
+                        pay_order_summary_qs = OrdersSummary.objects.filter(time=add_time_stamp, query_type=2,
+                                                                            service_type=order_type)
+                        query_type = 2
+                    else:
+                        pay_order_summary_qs = OrdersSummary.objects.filter(time=add_time_stamp, query_type=3,
+                                                                            service_type=order_type)
+                        query_type = 3
+                    if pay_order_summary_qs.exists():
+                        pay_order_summary = pay_order_summary_qs.first()
+                        pay_order_summary.count += 1
+                        temp_total = eval(pay_order_summary.total)
+                        if currency not in temp_total:
+                            temp_total[currency] = price
+                        else:
+                            temp_total[currency] = round(temp_total[currency] + price, 2)
+                        pay_order_summary.total = temp_total
+                        country_temp_dict = eval(pay_order_summary.country)
+                        if country_name in country_temp_dict:
+                            country_temp_dict[country_name]['数量'] += 1
+                            if currency not in country_temp_dict[country_name]:
+                                country_temp_dict[country_name][currency] = price
+                            else:
+                                country_temp_dict[country_name][currency] = round(
+                                    country_temp_dict[country_name][currency] + price, 2)
+                        else:
+                            country_temp_dict[country_name] = {'数量': 1, currency: price}
+                        pay_order_summary.country = country_temp_dict
+                        store_meal_temp_dict = eval(pay_order_summary.store_meal)
+                        if store_meal_name in store_meal_temp_dict:
+                            store_meal_temp_dict[store_meal_name]['数量'] += 1
+                            if currency not in store_meal_temp_dict[store_meal_name]:
+                                store_meal_temp_dict[store_meal_name][currency] = price
+                            else:
+                                store_meal_temp_dict[store_meal_name][currency] = round(
+                                    store_meal_temp_dict[store_meal_name][currency] + price, 2)
+                        else:
+                            store_meal_temp_dict[store_meal_name] = {'数量': 1, currency: price}
+                        pay_order_summary.store_meal = store_meal_temp_dict
+                        pay_order_summary.save()
+                    else:
+                        final_total = {currency: price}
+                        country_temp_dict = {
+                            country_name: {
+                                '数量': 1,
+                                currency: price
+                            }
+                        }
+                        store_meal_temp_dict = {
+                            store_meal_name: {
+                                '数量': 1,
+                                currency: price
+                            }
+                        }
+                        OrdersSummary.objects.create(time=add_time_stamp, count=1, query_type=query_type,
+                                                     service_type=order_type, total=final_total,
+                                                     country=country_temp_dict, created_time=created_time,
+                                                     device_type={},
+                                                     store_meal=store_meal_temp_dict)
+                    if order_summary_qs.exists():
+                        order_summary = order_summary_qs.first()
+                        order_summary.count += 1
+                        temp_total = eval(order_summary.total)
+                        if currency not in temp_total:
+                            temp_total[currency] = price
+                        else:
+                            temp_total[currency] = round(temp_total[currency] + price, 2)
+                        order_summary.total = temp_total
+                        country_temp_dict = eval(order_summary.country)
+                        if country_name in country_temp_dict:
+                            country_temp_dict[country_name]['数量'] += 1
+                            if currency not in country_temp_dict[country_name]:
+                                country_temp_dict[country_name][currency] = price
+                            else:
+                                country_temp_dict[country_name][currency] = round(
+                                    country_temp_dict[country_name][currency] + price, 2)
+                        else:
+                            country_temp_dict[country_name] = {'数量': 1, currency: price}
+                        order_summary.country = country_temp_dict
+                        store_meal_temp_dict = eval(order_summary.store_meal)
+                        if store_meal_name in store_meal_temp_dict:
+                            store_meal_temp_dict[store_meal_name]['数量'] += 1
+                            if currency not in store_meal_temp_dict[store_meal_name]:
+                                store_meal_temp_dict[store_meal_name][currency] = price
+                            else:
+                                store_meal_temp_dict[store_meal_name][currency] = round(
+                                    store_meal_temp_dict[store_meal_name][currency] + price, 2)
+                        else:
+                            store_meal_temp_dict[store_meal_name] = {'数量': 1, currency: price}
+                        order_summary.store_meal = store_meal_temp_dict
+                        order_summary.save()
+                    else:
+                        final_total = {currency: price}
+                        country_temp_dict = {
+                            country_name: {
+                                '数量': 1,
+                                currency: price
+                            }
+                        }
+                        store_meal_temp_dict = {
+                            store_meal_name: {
+                                '数量': 1,
+                                currency: price
+                            }
+                        }
+                        OrdersSummary.objects.create(time=add_time_stamp, count=1, query_type=0,
+                                                     service_type=order_type, total=final_total,
+                                                     country=country_temp_dict, created_time=created_time,
+                                                     device_type={}, store_meal=store_meal_temp_dict)
+            return response.json(0)
+        except Exception as e:
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def collect_device_info(response):

+ 1 - 1
Controller/DetectController.py

@@ -26,7 +26,7 @@ from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, DETECT_PUSH
     JPUSH_CONFIG, FCM_CONFIG, APNS_CONFIG, \
     BASE_DIR, APNS_MODE, SERVER_TYPE, LOGGER
 from Ansjer.config import PUSH_REDIS_ADDRESS
-from Model.models import Device_Info, VodHlsModel, Equipment_Info, UidSetModel, UidPushModel, SysMsgModel, \
+from Model.models import Device_Info, Equipment_Info, UidSetModel, UidPushModel, SysMsgModel, \
     VodBucketModel
 from Object.ETkObject import ETkObject
 from Object.RedisObject import RedisObject

+ 42 - 13
Controller/DetectControllerV2.py

@@ -10,7 +10,6 @@ from django.views.generic.base import View
 
 from Ansjer.config import DETECT_PUSH_DOMAIN, DETECT_PUSH_DOMAINS, DETECT_PUSH_DOMAIN_JIUAN, DETECT_PUSH_DOMAINS_JIUAN, \
     OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, LOGGER
-from Ansjer.config import PUSH_REDIS_ADDRESS
 from Model.models import Device_Info, Equipment_Info, UidSetModel, UidPushModel, CompanyModel, SysMsgModel, \
     AiService, VodBucketModel
 from Object.ETkObject import ETkObject
@@ -28,17 +27,18 @@ class DetectControllerViewV2(View):
     def get(self, request, *args, **kwargs):
         request.encoding = 'utf-8'
         operation = kwargs.get('operation')
+        api_version = kwargs.get('apiVersion')
         # self.ip = CommonService.get_ip_address(request)
-        return self.validation(request.GET, operation)
+        return self.validation(request, request.GET, operation, api_version)
 
     def post(self, request, *args, **kwargs):
         request.encoding = 'utf-8'
         operation = kwargs.get('operation')
+        api_version = kwargs.get('apiVersion')
         # self.ip = CommonService.get_ip_address(request)
-        return self.validation(request.POST, operation)
-
-    def validation(self, request_dict, operation):
+        return self.validation(request, request.POST, operation, api_version)
 
+    def validation(self, request, request_dict, operation, api_version):
         response = ResponseObject()
         if operation is None:
             return response.json(444, 'error path')
@@ -58,11 +58,40 @@ class DetectControllerViewV2(View):
             # 更新推送延迟
             elif operation == 'updateInterval':
                 return self.do_update_interval(userID, request_dict, response)
+            # 消息提醒配置
+            elif operation == 'messageNotificationSet':
+                return self.message_notification_set(api_version, request_dict, response)
             else:
                 return response.json(414)
         else:
             return response.json(tko.code)
 
+    @classmethod
+    def message_notification_set(cls, api_version, request_dict, response):
+        """
+        消息提醒设置
+        @param api_version: 版本号
+        @param request_dict: 参数json格式
+        @param response: 响应数据
+        """
+        try:
+            msg_data = request_dict.get('msgData', None)
+            uid = request_dict.get('uid', None)
+            LOGGER.info('*****DetectControllerViewV2.message_notification_set*****api_version:{},uid:{}'
+                        .format(api_version, uid))
+            if not all([msg_data, uid]):
+                return response.json(444)
+            data = json.loads(msg_data)
+            uid_set_qs = UidSetModel.objects.filter(uid=uid)
+            if not uid_set_qs.exists():
+                return response.json(173)
+            uid_set_qs.update(msg_notify=data, updTime=int(time.time()))
+            return response.json(0)
+        except Exception as e:
+            LOGGER.info('*****DetectControllerViewV2.message_notification_set:errLine:{}, errMsg:{}'
+                        .format(e.__traceback__.tb_lineno, repr(e)))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
     def do_change_status(self, userID, request_dict, response):
         token_val = request_dict.get('token_val', None)
         jg_token_val = request_dict.get('jg_token_val', '')
@@ -114,7 +143,6 @@ class DetectControllerViewV2(View):
             uid_set_data = {
                 'device_type': device_info_qs[0].Type
             }
-
             # 设置开关状态,0:关闭,1:开启
             if status:
                 status = int(status)
@@ -124,9 +152,6 @@ class DetectControllerViewV2(View):
             # 检测类型
             if detect_group:
                 uid_set_data['detect_group'] = detect_group
-            # uid_set = UidSetModel.objects.filter(uid=uid).order_by('-updTime')
-            # if uid_set.exists():
-            #     interval = uid_set.first().new_detect_interval if not interval else interval
             # 设置消息推送间隔
             if interval:
                 interval = int(interval)
@@ -142,12 +167,16 @@ class DetectControllerViewV2(View):
                         }
                     }
                     CommonService.req_publish_mqtt_msg(uid, topic_name, msg)
-                    # req_success = CommonService.req_publish_mqtt_msg(uid, topic_name, msg)
-                    # if not req_success:
-                    #     return response.json(10044)
 
             uid_set_qs = UidSetModel.objects.filter(uid=uid)
             if uid_set_qs.exists():
+                msg_data = uid_set_qs.first().msg_notify
+                if status == 0 and msg_data:
+                    msg_data['appPush'] = -1
+                    uid_set_data['msg_notify'] = msg_data
+                elif status == 1 and msg_data:
+                    msg_data['appPush'] = 1
+                    uid_set_data['msg_notify'] = msg_data
                 uid_set_id = uid_set_qs[0].id
                 uid_set_data['updTime'] = nowTime
                 uid_set_qs.update(**uid_set_data)
@@ -253,7 +282,7 @@ class DetectControllerViewV2(View):
             else:
                 return response.json(173)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def do_delete_redis(self, uid, detect_interval=0):
         keyPattern = '{uid}*'.format(uid=uid)

+ 4 - 2
Controller/EquipmentManager.py

@@ -1088,7 +1088,8 @@ 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', 'is_ptz')
+                                                    'detect_group', 'is_alexa', 'region_alexa', 'is_ptz',
+                                                    'msg_notify')
 
     # 调试
     debugOnes = int(time.time())
@@ -1119,7 +1120,8 @@ 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']
+            'is_ptz': qs[0]['is_ptz'],
+            'msgData': qs[0]['msg_notify']
         }
 
         # 调试

+ 24 - 6
Controller/EquipmentManagerV3.py

@@ -11,15 +11,14 @@ from django.db import transaction
 from django.db.models import Q
 from django.views.generic.base import View
 
-from Ansjer.config import OSS_STS_ACCESS_SECRET, OSS_STS_ACCESS_KEY, SERVER_DOMAIN_LIST, SERVER_DOMAIN_TEST, \
-    SERVER_DOMAIN_CN, SERVER_DOMAIN_US, SERVER_DOMAIN_EUR
+from Ansjer.config import OSS_STS_ACCESS_SECRET, OSS_STS_ACCESS_KEY
 from Controller.CheckUserData import RandomStr
 from Controller.DeviceConfirmRegion import Device_Region
 from Controller.SensorGateway.EquipmentFamilyController import EquipmentFamilyView
 from Controller.UnicomCombo.UnicomComboController import UnicomComboView
 from Model.models import Device_Info, UID_Bucket, UID_Preview, UidSetModel, UidChannelSetModel, \
     Device_User, iotdeviceInfoModel, UIDCompanySerialModel, UnicomDeviceInfo, CountryModel, \
-    DeviceCloudPhotoInfo, UidPushModel
+    DeviceCloudPhotoInfo, UidPushModel, ExperienceContextModel
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Service.CommonService import CommonService
@@ -742,6 +741,8 @@ class EquipmentManagerV3(View):
             p_uid = p['UID'].upper()
             UserDeviceService.get_sim_by_serial_number(p)  # 获取SIM卡属性
             p['cloudPhoto'] = self.get_cloud_photo_status(p['UID'])
+            # 获取云存使用状态
+            p['vod_use_status'] = self.get_vod_use_status(p_uid, nowTime)
             # 获取iot_deviceInfo表的endpoint和token_iot_number
             p['iot'] = []
             if p['serial_number']:  # 存在序列号根据序列号查询
@@ -778,7 +779,7 @@ class EquipmentManagerV3(View):
             p['View_Password'] = self.encrypt_pwd(p['View_Password'])
 
             # 判断设备是否支持4G
-            uid_set_qs =UidSetModel.objects.filter(uid=p['UID']).values('mobile_4g')
+            uid_set_qs = UidSetModel.objects.filter(uid=p['UID']).values('mobile_4g')
             if uid_set_qs.exists():
                 uid_set_qs = uid_set_qs.first()
                 if uid_set_qs['mobile_4g'] == 1:
@@ -787,6 +788,23 @@ class EquipmentManagerV3(View):
         result = data
         return response.json(0, result)
 
+    @staticmethod
+    def get_vod_use_status(uid, now_time):
+        """
+        根据UID获取云存使用状态
+        @param uid: 设备uid
+        @param now_time: 现在时间戳
+        @return: 0:未体验;1:使用中;2:已过期
+        """
+        experience_context_qs = ExperienceContextModel.objects.filter(uid=uid, experience_type=0)
+        if not experience_context_qs.exists():
+            return 0
+        uid_bucket_qs = UID_Bucket.objects.filter(uid=uid, endTime__gt=now_time, use_status=1)
+        if uid_bucket_qs.exists():
+            return 1
+        else:
+            return 2
+
     @staticmethod
     def get_cloud_photo_status(uid):
         """
@@ -958,7 +976,7 @@ class EquipmentManagerV3(View):
                         items.append(item)
             return response.json(0, items)
         except Exception as e:
-            return response.json(500, 'error_ine:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     # 加密
     def encrypt_pwd(self, userPwd):
@@ -1083,7 +1101,7 @@ class EquipmentManagerV3(View):
                     EquipmentInfoService.get_equipment_info_model('', val).filter(device_uid=uid).delete()
             return response.json(0)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def do_get_device_features(self, request_dict, response):
         uid = request_dict.get('uid', None)

+ 6 - 6
Controller/FeedBack.py

@@ -139,7 +139,7 @@ class FeedBackView(View):
                     fb.FS.add(StatResModel.objects.create(addTime=nowTime, name=res_3))
         except Exception as e:
             print(repr(e))
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
         else:
             return response.json(0)
 
@@ -174,7 +174,7 @@ class FeedBackView(View):
             print('----------')
 
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
         else:
             return response.json(0)
 
@@ -200,7 +200,7 @@ class FeedBackView(View):
                 try:
                     fb_qs = FeedBackModel.objects.filter()
                 except Exception as e:
-                    return response.json(500, repr(e))
+                    return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
                 print('----------')
                 if filter_data:
                     fb_qs = fb_qs.filter(**filter_data)
@@ -253,7 +253,7 @@ class FeedBackView(View):
                 fb_qs.delete()
                 print('----------')
             except Exception as e:
-                return response.json(500, repr(e))
+                return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
             else:
                 return response.json(0)
         else:
@@ -328,7 +328,7 @@ class FeedBackView(View):
             else:
                 return response.json(174)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def push_inaccurate(user_id, request_dict, response):
@@ -368,4 +368,4 @@ class FeedBackView(View):
                                                   add_time=now_time, tag=tag, is_st=is_st, event_time=event_time)
             return response.json(0)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))

+ 8 - 6
Controller/PaymentCycle.py

@@ -255,7 +255,6 @@ class PaypalCycleNotify(View):
                         (uid=UID, channel=channel, bucket_id=bucketId, endTime=endTime, addTime=nowTime,
                          updateTime=nowTime, use_status=1)
                     uid_bucket_id = ub_cqs.id
-
                 dvq = Device_Info.objects.filter(UID=UID, vodPrimaryUserID='', vodPrimaryMaster='')
                 if dvq.exists():
                     dvq_set_update_dict = {
@@ -461,7 +460,6 @@ class PaypalCycleNotify(View):
 
             bucketId = store_meal_qs[0]['bucket_id']
             expire = store_meal_qs[0]['expire']
-
             ubqs = UID_Bucket.objects.filter(uid=UID).values("id", "bucket_id", "bucket__storeDay", "bucket__region",
                                                              "endTime", "use_status")
 
@@ -489,7 +487,7 @@ class PaypalCycleNotify(View):
                         (uid=UID, channel=channel, bucket_id=bucketId, endTime=endTime, addTime=nowTime,
                          updateTime=nowTime, use_status=1)
                     uid_bucket_id = ub_cqs.id
-
+                # 开通AI服务
                 dvq = Device_Info.objects.filter(UID=UID, vodPrimaryUserID='', vodPrimaryMaster='')
                 if dvq.exists():
                     dvq_set_update_dict = {
@@ -506,13 +504,17 @@ class PaypalCycleNotify(View):
                 else:
                     store_meal_name = '未知套餐'
                 Order_Model.objects.create(orderID=orderID, UID=UID, channel=channel, userID_id=userid,
-                                           desc=desc, payType=pay_type, payTime=nowTime, price=amount.get('total'),
-                                           currency=order_qs[0]['currency'], addTime=nowTime, updTime=nowTime,
-                                           pay_url='', isSelectDiscounts=0, commodity_code=commodity_code,
+                                           desc=desc, payType=pay_type, payTime=nowTime,
+                                           price=amount.get('total'),
+                                           currency=order_qs[0]['currency'], addTime=nowTime,
+                                           updTime=nowTime,
+                                           pay_url='', isSelectDiscounts=0,
+                                           commodity_code=commodity_code,
                                            commodity_type=commodity_type, rank_id=rank, paymentID='',
                                            coupon_id='', uid_bucket_id=uid_bucket_id, status=1,
                                            agreement_id=agreement_id, store_meal_name=store_meal_name,
                                            plan_id=plan_id, ai_rank_id=1, trade_no=paypal_transaction_id)
+
                 # 如果存在序列号,消息提示用序列号
                 device_name = CommonService.query_serial_with_uid(uid=UID)
                 datetime = time.strftime("%Y-%m-%d", time.localtime())

+ 144 - 63
Controller/SensorGateway/GatewayDeviceController.py

@@ -7,6 +7,7 @@
 @Software: PyCharm
 """
 import datetime
+import threading
 import time
 
 import requests
@@ -14,7 +15,7 @@ from django.db import transaction
 from django.db.models import Q
 from django.views.generic.base import View
 
-from Ansjer.Config.gatewaySensorConfig import SMART_SCENE_TOPIC
+from Ansjer.Config.gatewaySensorConfig import SMART_SCENE_TOPIC, SCENE_EVENT_DELETE, SUB_DEVICE_TOPIC
 from Ansjer.config import CONFIG_INFO, AWS_IOT_SES_ACCESS_CHINA_ID, AWS_IOT_SES_ACCESS_CHINA_SECRET, \
     AWS_IOT_SES_ACCESS_CHINA_REGION, AWS_IOT_SES_ACCESS_FOREIGN_ID, AWS_IOT_SES_ACCESS_FOREIGN_SECRET, \
     AWS_IOT_SES_ACCESS_FOREIGN_REGION_AMERICA
@@ -23,12 +24,13 @@ from Controller.SensorGateway.EquipmentFamilyController import EquipmentFamilyVi
 from Controller.SensorGateway.SmartSocketController import SmartSocketView
 from Model.models import FamilyRoomDevice, FamilyRoom, GatewaySubDevice, Device_Info, UserFamily, FamilyMember, \
     UidSetModel, iotdeviceInfoModel, SmartScene, SceneLog, SocketInfo, SocketPowerStatistics, SocketSchedule, \
-    CountryModel
+    CountryModel, SensorRecord
 from Object.AWS.AWSIoTDataPlaneUtil import AWSIoTDataPlaneService
 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
 
 
 class GatewayDeviceView(View):
@@ -49,6 +51,9 @@ class GatewayDeviceView(View):
         if operation == 'bind-serial-user':
             response = ResponseObject()
             return self.bind_serial_user(request_dict, response)
+        elif operation == 'reset':
+            response = ResponseObject()
+            return self.reset(request_dict, response)
 
         token = TokenObject(request.META.get('HTTP_AUTHORIZATION'))
         lang = request_dict.get('lang', None)
@@ -164,6 +169,7 @@ class GatewayDeviceView(View):
         @param response:
         @return:
         """
+        LOGGER.info('开始删除设备:{}'.format(request_dict))
         device_id = request_dict.get('deviceId')
         family_id = request_dict.get('familyId')
         # 1 删除网关 否则删除子设备
@@ -178,35 +184,53 @@ class GatewayDeviceView(View):
                 if device_id:
                     device_qs = Device_Info.objects.filter(id=device_id)
                     if device_qs.exists():
-                        family_device_qs = FamilyRoomDevice.objects.filter(device_id=device_id)
-                        if family_device_qs.exists():
-                            family_device_qs.delete()
-                        uid_set_qs = UidSetModel.objects.filter(uid=device_qs.first().UID)
-                        if uid_set_qs.exists():
-                            uid_set_qs.delete()
+                        serial_number = device_qs.first().serial_number
+                        FamilyRoomDevice.objects.filter(device_id=device_id).delete()
+                        UidSetModel.objects.filter(uid=device_qs.first().UID).delete()
                         socket_info_qs = SocketInfo.objects.filter(device_id=device_id)
                         if socket_info_qs.exists():
                             # 设备在不在线, 都发布重置
-                            serial_number = device_qs.first().serial_number
                             cls.reset_device(serial_number)
                             socket_info_qs.delete()
-                            socket_power_qs = SocketPowerStatistics.objects.filter(device_id=device_id)
-                            if socket_power_qs.exists():
-                                socket_power_qs.delete()
-                            socket_schedule_qs = SocketSchedule.objects.filter(device_id=device_id)
-                            if socket_schedule_qs.exists():
-                                socket_schedule_qs.delete()
-                            scene_log_qs = SceneLog.objects.filter(device_id=serial_number)
-                            if scene_log_qs.exists():
-                                scene_log_qs.delete()
+                            SocketPowerStatistics.objects.filter(device_id=device_id).delete()
+                            SocketSchedule.objects.filter(device_id=device_id).delete()
+                            SceneLog.objects.filter(device_id=serial_number).delete()
                             SmartSocketView.delete_alexa_socket(serial_number)
-
+                        # 重置设备
+                        topic_name = SUB_DEVICE_TOPIC.format(serial_number)
+                        msg = {
+                            'zigbee': 'recover',
+                        }
+                        success = CommonService.req_publish_mqtt_msg(serial_number, topic_name, msg)
+                        LOGGER.info('删除重置设备结果:{}'.format(success))
+                        try:
+                            assert success
+                        except AssertionError:
+                            return response.json(10044)
+                        time.sleep(0.3)
                         # 如果有子设备,删除子设备和关联的场景数据
                         gateway_qs = GatewaySubDevice.objects.filter(device_id=device_id)
                         if gateway_qs.exists():
                             sub_id_list = gateway_qs.values_list('id', flat=True)
+                            # 删除传感器记录
+                            SensorRecord.objects.filter(gateway_sub_device_id__in=list(sub_id_list)).delete()
                             smart_scene_qs = SmartScene.objects.filter(
                                 Q(device_id=device_id) | Q(sub_device_id__in=sub_id_list))
+
+                            # 下发删除设备消息
+                            ieee_addr_list = gateway_qs.values_list('ieee_addr', flat=True)
+                            for ieee_addr in ieee_addr_list:
+                                # 删除设备
+                                msg = {
+                                    'zigbee': 'delete',
+                                    'ieee': ieee_addr
+                                }
+                                success = CommonService.req_publish_mqtt_msg(serial_number, topic_name, msg)
+                                try:
+                                    assert success
+                                except AssertionError:
+                                    return response.json(10044)
+                                time.sleep(0.3)
                         else:
                             smart_scene_qs = SmartScene.objects.filter(device_id=device_id)
                         if smart_scene_qs.exists():
@@ -216,7 +240,8 @@ class GatewayDeviceView(View):
                             topic_name = SMART_SCENE_TOPIC.format(serial_number)
                             for smart_scene in smart_scene_info:
                                 msg = {
-                                    'smart_scene_delete': int(smart_scene['id'])
+                                    'scene_event': SCENE_EVENT_DELETE,
+                                    'scene_id': int(smart_scene['id'])
                                 }
                                 success = CommonService.req_publish_mqtt_msg(serial_number, topic_name, msg)
                                 try:
@@ -226,44 +251,48 @@ class GatewayDeviceView(View):
                                 time.sleep(0.3)
                             smart_scene_qs.delete()
                         gateway_qs.delete()  # 删除子设备
-                        scene_log_qs = SceneLog.objects.filter(device_id=device_id)
-                        if scene_log_qs.exists():
-                            scene_log_qs.delete()
+                        SceneLog.objects.filter(device_id=device_id).delete()
                         device_qs.delete()
+                        # 异步删除推送消息
+                        asy = threading.Thread(target=ModelService.del_eq_info, args=(user_id, serial_number))
+                        asy.start()
                 elif sub_ids:
-                    sub_ids = sub_ids.split(',')
-                    ids = []
-                    for item in sub_ids:
-                        sub_id = int(item)
-                        ids.append(sub_id)
-                        sub_device_qs = GatewaySubDevice.objects.filter(id=sub_id).values('device_type', 'src_addr',
-                                                                                          'device__serial_number')
-                        serial_number = sub_device_qs[0]['device__serial_number']
-                        topic_name = SMART_SCENE_TOPIC.format(serial_number)
-                        device_type = sub_device_qs[0]['device_type']
-                        if device_type == 216:  # 删除智能按钮通知设备
-                            msg = {
-                                'sos_delete': int(sub_device_qs[0]['src_addr'], 16)
-                            }
-                            success = CommonService.req_publish_mqtt_msg(serial_number, topic_name, msg)
-                            try:
-                                assert success
-                            except AssertionError:
-                                return response.json(10044)
-                            time.sleep(0.3)
-                    family_device_qs = FamilyRoomDevice.objects.filter(sub_device__in=ids)
-                    if family_device_qs.exists():
-                        family_device_qs.delete()
-                    gateway_sub_qs = GatewaySubDevice.objects.filter(id__in=ids)
-                    if gateway_sub_qs.exists():
-                        gateway_sub_qs.delete()
-                    smart_scene_qs = SmartScene.objects.filter(sub_device_id__in=ids)
+                    sub_id_list = list(map(int, sub_ids.split(',')))
+                    FamilyRoomDevice.objects.filter(sub_device__in=sub_id_list).delete()
+                    # 删除传感器记录
+                    SensorRecord.objects.filter(gateway_sub_device_id__in=sub_id_list).delete()
+                    # 查询网关序列号,确定MQTT主题
+                    sub_device_qs = GatewaySubDevice.objects.filter(id=sub_id_list[0]). \
+                        values('device__serial_number')
+                    assert sub_device_qs.exists()
+                    serial_number = sub_device_qs[0]['device__serial_number']
+
+                    # 下发删除设备消息
+                    gateway_sub_device_qs = GatewaySubDevice.objects.filter(id__in=sub_id_list)
+                    ieee_addr_list = gateway_sub_device_qs.values_list('ieee_addr', flat=True)
+                    topic_name = SUB_DEVICE_TOPIC.format(serial_number)
+                    for ieee_addr in ieee_addr_list:
+                        # 删除设备
+                        msg = {
+                            'zigbee': 'delete',
+                            'ieee': ieee_addr
+                        }
+                        success = CommonService.req_publish_mqtt_msg(serial_number, topic_name, msg)
+                        try:
+                            assert success
+                        except AssertionError:
+                            return response.json(10044)
+                        time.sleep(0.3)
+                    # 删除场景,下发MQTT通知设备
+                    smart_scene_qs = SmartScene.objects.filter(sub_device_id__in=sub_id_list)
                     if smart_scene_qs.exists():
+                        topic_name = SMART_SCENE_TOPIC.format(serial_number)
                         smart_scene_info = smart_scene_qs.values('id')
                         for smart_scene in smart_scene_info:
                             # 通知设备删除场景id
                             msg = {
-                                'smart_scene_delete': int(smart_scene['id'])
+                                'scene_event': SCENE_EVENT_DELETE,
+                                'scene_id': int(smart_scene['id'])
                             }
                             success = CommonService.req_publish_mqtt_msg(serial_number, topic_name, msg)
                             try:
@@ -272,13 +301,15 @@ class GatewayDeviceView(View):
                                 return response.json(10044)
                             time.sleep(0.3)
                         smart_scene_qs.delete()
-                    scene_log_qs = SceneLog.objects.filter(sub_device_id__in=ids)
-                    if scene_log_qs.exists():
-                        scene_log_qs.delete()
+
+                    gateway_sub_device_qs.delete()
+                    SceneLog.objects.filter(sub_device_id__in=sub_id_list).delete()
+                    # 异步删除推送消息
+                    asy = threading.Thread(target=ModelService.del_eq_info, args=(user_id, serial_number))
+                    asy.start()
                 return response.json(0)
         except Exception as e:
-            print(e)
-            return response.json(177, repr(e))
+            return response.json(177, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def reset_device(serial_number):
@@ -388,10 +419,7 @@ class GatewayDeviceView(View):
                     sub_id = item['sub_device']
                     sub_id_list.append(sub_id)
                     gateway_sub_qs = GatewaySubDevice.objects.filter(device_id=device_id, id=sub_id).values(
-                        'id', 'device_type',
-                        'nickname',
-                        'src_addr', 'status',
-                        'created_time', 'ieee_addr')
+                        'id', 'device_type', 'nickname', 'status', 'created_time', 'ieee_addr')
                     if not gateway_sub_qs.exists():
                         continue
                     room_id = item['room_id']
@@ -402,7 +430,6 @@ class GatewayDeviceView(View):
                         'gatewaySubId': gateway_sub_qs['id'],
                         'nickName': gateway_sub_qs['nickname'],
                         'deviceType': gateway_sub_qs['device_type'],
-                        'srcAddr': gateway_sub_qs['src_addr'],
                         'status': gateway_sub_qs['status'],
                         'createdTime': gateway_sub_qs['created_time'],
                         'roomName': gateway_room_name,
@@ -481,13 +508,15 @@ class GatewayDeviceView(View):
         if not all([user_id, serial_number]):
             return response.json(444)
         try:
+            now_time = int(time.time())
+            LOGGER.info('用户{}的设备{}上传序列号时间:{}'.format(user_id, serial_number, now_time))
             redis_obj = RedisObject()
             result = redis_obj.set_data(user_id, serial_number, 300)
             if not result:
                 return response.json(178)
             return response.json(0)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def get_serial_user(user_id, request_dict, response):
@@ -499,13 +528,63 @@ class GatewayDeviceView(View):
         @return:
         """
         try:
+            now_time = int(time.time())
             redis_obj = RedisObject()
             serial_number = redis_obj.get_data(user_id)
+            LOGGER.info('用户{}的设备{}获取序列号时间:{}'.format(user_id, serial_number, now_time))
             if not serial_number:
                 return response.json(173)
             return response.json(0, {'serialNumber': serial_number})
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
+    @staticmethod
+    def reset(request_dict, response):
+        """
+        网关复位删除设备信息
+        @param request_dict: 请求参数字典
+        @request_dict serial_number: 序列号
+        @param response: 响应对象
+        @return:
+        """
+        serial_number = request_dict.get('serial_number')
+        if not serial_number:
+            return response.json(444)
+        try:
+            with transaction.atomic():
+                device_qs = Device_Info.objects.filter(serial_number=serial_number)
+                device_id_list = list(device_qs.values_list('id', flat=True))
+                user_id_list = list(device_qs.values_list('userID_id', flat=True))
+                if not device_qs.exists():
+                    return response.json(173)
+
+                FamilyRoomDevice.objects.filter(device_id__in=device_id_list).delete()
+                UidSetModel.objects.filter(uid=device_qs.first().UID).delete()
+                socket_info_qs = SocketInfo.objects.filter(device_id__in=device_id_list)
+                if socket_info_qs.exists():
+                    socket_info_qs.delete()
+                    SocketPowerStatistics.objects.filter(device_id__in=device_id_list).delete()
+                    SocketSchedule.objects.filter(device_id__in=device_id_list).delete()
+                    SmartSocketView.delete_alexa_socket(serial_number)
+
+                # 如果有子设备,删除子设备和关联的场景数据,删除传感器记录
+                gateway_qs = GatewaySubDevice.objects.filter(device_id__in=device_id_list)
+                if gateway_qs.exists():
+                    sub_id_list = gateway_qs.values_list('id', flat=True)
+                    SensorRecord.objects.filter(gateway_sub_device_id__in=list(sub_id_list)).delete()
+                    SmartScene.objects.filter(Q(device_id__in=device_id_list) | Q(sub_device_id__in=sub_id_list)).delete()
+                else:
+                    SmartScene.objects.filter(device_id__in=device_id_list).delete()
+
+                gateway_qs.delete()  # 删除子设备
+                SceneLog.objects.filter(device_id__in=device_id_list).delete()
+                device_qs.delete()
+                # 异步删除推送消息
+                asy = threading.Thread(target=ModelService.del_user_list_eq_info, args=(user_id_list, serial_number))
+                asy.start()
+            return response.json(0)
+        except Exception as e:
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @classmethod
     def update_socket(cls, serial_number, device_name, user_id, region):
@@ -521,6 +600,8 @@ class GatewayDeviceView(View):
             requests.post(url=url, data=data, timeout=5)
         except Exception as e:
             print(repr(e))
+
+
 #
 #                   ___====-_  _-====___
 #             _--^^^#####//      \\#####^^^--_

+ 134 - 73
Controller/SensorGateway/SmartSceneController.py

@@ -12,7 +12,9 @@ from django.db import transaction
 from django.db.models import F, Q, Count
 from django.views import View
 
-from Ansjer.Config.gatewaySensorConfig import SMART_SCENE_TOPIC, SENSOR_TYPE, EVENT_TYPE
+from Ansjer.Config.gatewaySensorConfig import SMART_SCENE_TOPIC, SENSOR_TYPE, EVENT_TYPE, SCENE_EVENT_CREATE, \
+    SCENE_EVENT_EDIT, SCENE_EVENT_DELETE, SCENE_STATUS_ON, SCENE_STATUS_OFF, SCENE_EVENT_EDIT_STATUS, \
+    VOICE_AUDITION_TOPIC
 from Model.models import FamilyRoomDevice, GatewaySubDevice, FamilyRoom, SmartScene, EffectiveTime, Device_Info, \
     SceneLog
 from Object.ResponseObject import ResponseObject
@@ -58,6 +60,8 @@ class SmartSceneView(View):
             return self.scene_log(request_dict, response)
         elif operation == 'log-date':  # 查询智能场景日志日期
             return self.scene_log_date(request_dict, response)
+        elif operation == 'voice-audition':  # 智能场景音频试听
+            return self.voice_audition(request_dict, response)
         else:
             return response.json(414)
 
@@ -84,7 +88,7 @@ class SmartSceneView(View):
             res = cls.get_sub_device_room_name(gateway_sub_device_qs)
             return response.json(0, res)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @classmethod
     def task_devices(cls, request_dict, response):
@@ -114,8 +118,9 @@ class SmartSceneView(View):
                 else:  # 智能按钮返回网关,门磁和人体传感器(如果存在)
                     gateway_data = cls.get_gateway_data(device_id)
                     sub_device_qs = GatewaySubDevice.objects.filter(
-                        Q(device_id=device_id) & Q(device_type=SENSOR_TYPE['door_magnet']) | Q(
-                            device_type=SENSOR_TYPE['body_sensor'])).values('id', 'nickname', 'status', 'device_type')
+                        Q(Q(device_id=device_id) & Q(device_type=SENSOR_TYPE['door_magnet'])) |
+                        Q(Q(device_id=device_id) & Q(device_type=SENSOR_TYPE['body_sensor']))
+                    ).values('id', 'nickname', 'status', 'device_type')
                     if sub_device_qs.exists():
                         res = cls.get_sub_device_room_name(sub_device_qs, gateway_data)
                     else:
@@ -123,7 +128,7 @@ class SmartSceneView(View):
 
             return response.json(0, res)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def get_sub_device_room_name(sub_device_qs, gateway_data=None):
@@ -161,13 +166,15 @@ class SmartSceneView(View):
         @param device_id: 网关设备id
         @return: res
         """
-        device_info_qs = Device_Info.objects.filter(id=device_id).values('NickName', 'Type')
+        device_info_qs = Device_Info.objects.filter(id=device_id).values('NickName', 'Type', 'serial_number')
         nickname = device_info_qs[0]['NickName']
         device_type = device_info_qs[0]['Type']
+        serial_number = device_info_qs[0]['serial_number']
         room_id = FamilyRoomDevice.objects.filter(device_id=device_id).values('room_id')[0]['room_id']
         room_id_qs = FamilyRoom.objects.filter(id=room_id).values('name')
         room_name = room_id_qs.first()['name'] if room_id_qs.exists() else ''
         res = {
+            'serialNumber': serial_number,
             'deviceNickName': nickname,
             'deviceType': device_type,
             'roomName': room_name,
@@ -175,8 +182,8 @@ class SmartSceneView(View):
         }
         return res
 
-    @staticmethod
-    def create_smart_scene(request_dict, user_id, response):
+    @classmethod
+    def create_smart_scene(cls, request_dict, user_id, response):
         """
         创建智能场景
         @param request_dict: 请求参数
@@ -222,7 +229,8 @@ class SmartSceneView(View):
                 'updated_time': now_time,
             }
             msg = {
-                'scene_status': 1
+                'scene_event': SCENE_EVENT_CREATE,
+                'scene_status': SCENE_STATUS_ON
             }
             # 处理设置时间
             if is_all_day is not None:
@@ -238,6 +246,12 @@ class SmartSceneView(View):
                 if not device_info_qs.exists():
                     return response.json(173)
                 serial_number = device_info_qs[0]['serial_number']
+
+                # 网关数据
+                msg['sensor_type'] = 200
+                msg['sensor_status'] = 2002
+                msg['sensor_ieee_addr'] = 'FFFFFFFFFFFFFFFF'
+
             else:  # 子设备设置场景
                 if not sub_device_id:
                     return response.json(444, {'error param': 'subDeviceId'})
@@ -265,13 +279,13 @@ class SmartSceneView(View):
 
                 smart_scene_dict['sub_device_id'] = sub_device_id
                 sub_device_qs = GatewaySubDevice.objects.filter(id=sub_device_id).values('device__serial_number',
-                                                                                         'src_addr')
+                                                                                         'ieee_addr')
                 if not sub_device_qs.exists():
                     return response.json(173)
                 serial_number = sub_device_qs[0]['device__serial_number']
 
                 msg['sensor_type'] = int(conditions_dict['sensor']['device_type'])
-                msg['sensor_src'] = int(sub_device_qs[0]['src_addr'], 16)
+                msg['sensor_ieee_addr'] = sub_device_qs[0]['ieee_addr']
                 msg['sensor_status'] = int(conditions_dict['sensor']['eventValues'][0]['event_type'])
 
             with transaction.atomic():
@@ -313,24 +327,10 @@ class SmartSceneView(View):
                     return response.json(444, {'error param': 'invalid isAllDay'})
 
                 msg['time'] = time_dict
-                msg['smart_scene_id'] = smart_scene_qs.id
-                task_list = []
-                for task in tasks_list:
-                    task_temp = {
-                        'sensor_type': int(task['device_type']),
-                        'sensor_action': int(task['event_type'])
-                    }
-
-                    # 延时
-                    if 'delay_time' in task and task['delay_time'] != 0:
-                        task_temp['sensor_delay'] = task['delay_time']
+                msg['scene_id'] = smart_scene_qs.id
 
-                    sub_device_id = task.get('subDeviceId', None)
-                    if sub_device_id:
-                        sub_device_qs = GatewaySubDevice.objects.filter(id=sub_device_id).values('src_addr').first()
-                        task_temp['sensor_src'] = int(sub_device_qs['src_addr'], 16)
-                    task_list.append(task_temp)
-                msg['task'] = task_list
+                # 获取设备任务数据
+                msg['task'] = cls.get_msg_task_list(tasks_list)
 
                 smart_scene_qs.device_data = json.dumps(msg)
                 smart_scene_qs.save()
@@ -346,7 +346,7 @@ class SmartSceneView(View):
 
             return response.json(0)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def scene_list(request_dict, user_id, response):
@@ -394,7 +394,7 @@ class SmartSceneView(View):
                 smart_scene_list.append(smart_scene_dict)
             return response.json(0, smart_scene_list)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def smart_button_scene_list(request_dict, user_id, response):
@@ -447,7 +447,7 @@ class SmartSceneView(View):
                 })
             return response.json(0, scene_list)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def update_status(request_dict, response):
@@ -466,8 +466,9 @@ class SmartSceneView(View):
             return response.json(444, {'error param': 'smartSceneId and status'})
         try:
             smart_scene_id = int(smart_scene_id)
-            scene_status = 1 if is_enable == 'True' else 0
+            scene_status = SCENE_STATUS_ON if is_enable == 'True' else SCENE_STATUS_OFF
             msg = {
+                'scene_event': SCENE_EVENT_EDIT_STATUS,
                 'scene_id': smart_scene_id,
                 'scene_status': scene_status
             }
@@ -493,7 +494,7 @@ class SmartSceneView(View):
                     return response.json(10044)
             return response.json(0)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def scene_detail(request_dict, response):
@@ -537,10 +538,10 @@ class SmartSceneView(View):
             return response.json(0, res)
 
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
-    @staticmethod
-    def edit_smart_scene(request_dict, user_id, response):
+    @classmethod
+    def edit_smart_scene(cls, request_dict, user_id, response):
         """
         编辑智能场景
         @param request_dict: 请求参数
@@ -585,7 +586,8 @@ class SmartSceneView(View):
 
             scene_status = 1 if smart_scene_qs[0].is_enable else 0
             msg = {
-                'smart_scene_id': smart_scene_id,
+                'scene_id': smart_scene_id,
+                'scene_event': SCENE_EVENT_EDIT,
                 'scene_status': scene_status
             }
             if conditions_dict['type'] == 2:  # 条件为选择子设备
@@ -615,13 +617,13 @@ class SmartSceneView(View):
                     msg['sensor_data'] = float(value)
 
                 device_id = ''
-                sub_device_qs = GatewaySubDevice.objects.filter(id=sub_device_id).values('src_addr',
+                sub_device_qs = GatewaySubDevice.objects.filter(id=sub_device_id).values('ieee_addr',
                                                                                          'device__serial_number')
                 if not sub_device_qs.exists():
                     return response.json(173)
                 serial_number = sub_device_qs[0]['device__serial_number']
                 msg['sensor_type'] = int(conditions_dict['sensor']['device_type'])
-                msg['sensor_src'] = int(sub_device_qs[0]['src_addr'], 16)
+                msg['sensor_ieee_addr'] = sub_device_qs[0]['ieee_addr']
                 msg['sensor_status'] = int(conditions_dict['sensor']['eventValues'][0]['event_type'])
             else:
                 if not device_id:
@@ -631,24 +633,13 @@ class SmartSceneView(View):
                 if not device_qs.exists():
                     return response.json(173)
                 serial_number = device_qs[0]['serial_number']
+                # 网关数据
+                msg['sensor_type'] = 200
+                msg['sensor_status'] = 2002
+                msg['sensor_ieee_addr'] = 'FFFFFFFFFFFFFFFF'
 
-            task_list = []
-            for task in tasks_list:
-                task_temp = {
-                    'sensor_type': int(task['device_type']),
-                    'sensor_action': int(task['event_type'])
-                }
-
-                # 延时
-                if 'delay_time' in task and task['delay_time'] != 0:
-                    task_temp['sensor_delay'] = task['delay_time']
-
-                task_sub_device_id = task.get('subDeviceId', None)
-                if task_sub_device_id:
-                    sub_device_qs = GatewaySubDevice.objects.filter(id=task_sub_device_id).values('src_addr').first()
-                    task_temp['sensor_src'] = int(sub_device_qs['src_addr'], 16)
-                task_list.append(task_temp)
-            msg['task'] = task_list
+            # 获取设备任务数据
+            msg['task'] = cls.get_msg_task_list(tasks_list)
 
             with transaction.atomic():
                 smart_scene_qs.update(scene_name=scene_name, conditions=conditions, tasks=tasks,
@@ -705,7 +696,7 @@ class SmartSceneView(View):
             return response.json(0, res)
 
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def delete_smart_scene(request_dict, response):
@@ -737,7 +728,8 @@ class SmartSceneView(View):
                 for smart_scene_id in smart_scene_id_list:
                     # 通知设备删除场景id
                     msg = {
-                        'smart_scene_delete': int(smart_scene_id)
+                        'scene_event': SCENE_EVENT_DELETE,
+                        'scene_id': int(smart_scene_id)
                     }
                     success = CommonService.req_publish_mqtt_msg(serial_number, topic_name, msg)
                     try:
@@ -747,7 +739,7 @@ class SmartSceneView(View):
                     time.sleep(0.3)
             return response.json(0)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def scene_log(request_dict, response):
@@ -783,17 +775,19 @@ class SmartSceneView(View):
                     device_list.append(device['device'])
                 if device['sub_device']:
                     sub_device_list.append(device['sub_device'])
-        elif sub_device_id:
-            family_room_device_qs = FamilyRoomDevice.objects.filter(family_id=family_id, sub_device=sub_device_id)
+        elif sub_device_id:  # 查询子设备
+            family_room_device_qs = FamilyRoomDevice.objects.filter(family_id=family_id,
+                                                                    sub_device=sub_device_id).values('device_id')
+            for device in family_room_device_qs:
+                device_list.append(device['device_id'])
             sub_device_list.append(sub_device_id)
-        else:
-            family_room_device_qs = FamilyRoomDevice.objects.filter(family_id=family_id, device=device_id).values(
+        else:  # 查询网关
+            family_room_device_qs = FamilyRoomDevice.objects.filter(Q(family_id=family_id) & Q(device=device_id) &
+                                                                    ~Q(sub_device=0)).values(
                 'sub_device')
             device_list.append(device_id)
             for device in family_room_device_qs:
                 sub_device_list.append(device['sub_device'])
-        if not family_room_device_qs.exists():
-            return response.json(173)
         try:
             page, size = int(page), int(size)
             scene_log_qs = SceneLog.objects.filter(Q(device_id__in=device_list) | Q(sub_device_id__in=sub_device_list))
@@ -828,11 +822,13 @@ class SmartSceneView(View):
                 else:
                     device_qs = Device_Info.objects.filter(id=item['device_id']).values('Type')
                     item['device_type'] = device_qs[0]['Type'] if device_qs.exists() else ''
-                item['tasks'] = eval(item['tasks'])
-            return response.json(0, list(scene_log_qs))
+                if item['tasks'] != '':
+                    item['tasks'] = eval(item['tasks'])
+            scene_log_list = list(scene_log_qs)
+            return response.json(0, scene_log_list)
         except Exception as e:
-            print(repr(e))
-            return response.json(500, repr(e))
+            print('error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def scene_log_date(request_dict, response):
@@ -886,7 +882,7 @@ class SmartSceneView(View):
                 })
             return response.json(0, log_date_list)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def get_scene_data(request_dict, response):
@@ -931,14 +927,14 @@ class SmartSceneView(View):
             # 下发智能按钮数据
             smart_button_qs = GatewaySubDevice.objects.filter(device_id=device_id,
                                                               device_type=SENSOR_TYPE['smart_button']).values(
-                'src_addr', 'is_tampered')
+                'ieee_addr', 'is_tampered')
             if smart_button_qs.exists():
                 sos_count = smart_button_qs.count()
                 for index, smart_button in enumerate(smart_button_qs):
                     msg = {
                         'sos_count': sos_count,  # 该网关下的智能按钮数量
                         'sos_num': index + 1,  # 第几个按钮
-                        'sensor_src': int(smart_button['src_addr'], 16),
+                        'sensor_ieee_addr': smart_button['ieee_addr'],
                         'sos_select': smart_button['is_tampered']
                     }
                     success = CommonService.req_publish_mqtt_msg(serial_number, topic_name, msg)
@@ -950,7 +946,72 @@ class SmartSceneView(View):
 
             return response.json(0)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
+    @staticmethod
+    def voice_audition(request_dict, response):
+        """
+        智能场景音频试听
+        @param request_dict: 请求参数
+        @request_dict serial_number: 序列号
+        @request_dict voiceId: 音频id
+        @param response: 响应对象
+        @return: response
+        """
+        serial_number = request_dict.get('serial_number', None)
+        voice_id = request_dict.get('voiceId', None)
+        if not all([serial_number, voice_id]):
+            return response.json(444)
+        try:
+            topic_name = VOICE_AUDITION_TOPIC.format(serial_number)
+            msg = {'voice_id': int(voice_id)}
+            success = CommonService.req_publish_mqtt_msg(serial_number, topic_name, msg)
+            try:
+                assert success
+            except AssertionError:
+                return response.json(10044)
+            return response.json(0)
+        except Exception as e:
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
+    @staticmethod
+    def get_msg_task_list(tasks_list):
+        """
+        获取设备任务数据
+        @param tasks_list: app任务列表
+        @return: task_list
+        """
+        task_list = []
+        for task in tasks_list:
+            sensor_type = int(task['device_type'])
+            task_temp = {
+                'sensor_type': sensor_type,
+                'sensor_delay': 0
+            }
+
+            # 延时
+            if 'delay_time' in task and task['delay_time'] != 0:
+                task_temp['sensor_delay'] = task['delay_time']
+
+            # 不为-1时需要其他数据
+            if sensor_type != -1:
+                task_temp['sensor_action'] = int(task['event_type'])
+                # 子设备返回长地址
+                sub_device_id = task.get('subDeviceId', None)
+                if sub_device_id:
+                    sub_device_qs = GatewaySubDevice.objects.filter(id=sub_device_id).values('ieee_addr').first()
+                    task_temp['sensor_ieee_addr'] = sub_device_qs['ieee_addr']
+                # 网关添加报警类型数据
+                else:
+                    task_temp['voice_type'] = task.get('voice_type')
+                    task_temp['voice_id'] = task.get('voice_id')
+                    task_temp['count'] = task.get('count')
+                    task_temp['delay_time'] = task.get('delay_time')
+                    task_temp['duration'] = task.get('duration')
+                    task_temp['value_type'] = task.get('value_type')
+            task_list.append(task_temp)
+        return task_list
+
 
 #
 #                   ___====-_  _-====___

+ 7 - 7
Controller/SensorGateway/SmartSocketController.py

@@ -502,7 +502,7 @@ class SmartSocketView(View):
                 data['electricityYesterday'] = 0
             return response.json(0, data)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def get_socket_schedule(request_dict, response):
@@ -552,7 +552,7 @@ class SmartSocketView(View):
                 })
             return response.json(0, schedule_list)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def get_log(request_dict, response):
@@ -602,7 +602,7 @@ class SmartSocketView(View):
                 log_list.append(data)
             return response.json(0, log_list)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @classmethod
     def splittings_time(cls, startTime, endTime, unit):
@@ -770,7 +770,7 @@ class SmartSocketView(View):
             data['week_or_month_or_year'] = new_list
             return response.json(0, data)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @classmethod
     def get_subscript(cls, unit, time_stamp):
@@ -825,7 +825,7 @@ class SmartSocketView(View):
                 })
             return response.json(0, schedule_date_list)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @classmethod
     def alexa_socket_switch(cls, request_dict, response):
@@ -851,7 +851,7 @@ class SmartSocketView(View):
             return response.json(0)
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @classmethod
     def get_socket_state(cls, request_dict, response):
@@ -877,7 +877,7 @@ class SmartSocketView(View):
             return response.json(173)
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @classmethod
     def delete_alexa_socket(cls, serial_number):

+ 4 - 1
Controller/SerialNumberController.py

@@ -883,6 +883,10 @@ class SerialNumberView(View):
         try:
             if not CONFIG_INFO == 'eur':
                 return False
+            serial = serial_number[0:6]
+            device_iot_qs = iotdeviceInfoModel.objects.filter(serial_number=serial)
+            if device_iot_qs.exists():
+                return False
             response = requests.get("https://www.dvema.com/serialNumber/getIoTCoreBySerialNumber",
                                     params={'serialNumber': serial_number}, timeout=3)
             if response.status_code != 200:
@@ -927,4 +931,3 @@ class SerialNumberView(View):
         except Exception as e:
             LOGGER.info('{}判断是否4G设备异常,errLine:{}, errMsg:{}'.format(serial_number, e.__traceback__.tb_lineno, repr(e)))
             return False
-

+ 11 - 3
Controller/SysMsg.py

@@ -12,6 +12,7 @@
 @Contact: chanjunkai@163.com
 """
 import time
+import re
 
 from django.views.generic.base import View
 
@@ -133,7 +134,7 @@ class SysMsgView(View):
                         SysMsgModel.objects.create(**create_data)
                         fb_qs.update(status=1)
                     except Exception as e:
-                        return response.json(500, repr(e))
+                        return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
                     else:
                         return response.json(0, {'status': 1, 'updTime': nowTime})
                 else:
@@ -154,7 +155,8 @@ class SysMsgView(View):
         try:
             # 如果没有系统消息,周视ios用户暂时生成消息并返回
             if not sm_qs.exists():
-                user_ex_qs = UserExModel.objects.filter(userID_id=userID, appBundleId='com.ansjer.zccloud').values('region')
+                user_ex_qs = UserExModel.objects.filter(userID_id=userID, appBundleId='com.ansjer.zccloud').values(
+                    'region')
                 if not user_ex_qs.exists():
                     return response.json(0, [])
                 now_time = int(time.time())
@@ -190,6 +192,12 @@ class SysMsgView(View):
                 sm_q['jumpLink'] = ''
                 if sm_q['eventType'] > 0:
                     uid_list.append(sm_q['uid'])
+                if sm_q['eventType'] == 2:
+                    msg = sm_q['msg']
+                    number_list = re.findall('\d+', msg)
+                    for number in number_list:
+                        if len(number) == 6:
+                            sm_q['code'] = number
                 data_res.append(sm_q)
             if uid_list:
                 uid_set_qs = UidSetModel.objects.filter(uid__in=uid_list).values('uid', 'nickname')
@@ -201,7 +209,7 @@ class SysMsgView(View):
                     data_res.append(sm_q)
             return response.json(0, {'data': data_res, 'count': count})
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def do_query_by_admin(self, userID, request_dict, response):
         own_perm = ModelService.check_perm(userID, 30)

+ 168 - 308
Controller/TestApi.py

@@ -1,67 +1,47 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-"""
-@Copyright (C) ansjer cop Video Technology Co.,Ltd.All rights reserved.
-@AUTHOR: ASJRD018
-@NAME: Ansjer
-@software: PyCharm
-@DATE: 2018/5/22 13:58
-@Version: python3.6
-@MODIFY DECORD:ansjer dev
-@file: Test.py
-@Contact: chanjunkai@163.com
-"""
+import json
+import logging
 import os
+import time
 import traceback
+import urllib
 
+import boto3
 import botocore
 import cv2
-from botocore import client
-from django.db import transaction
-
-from Ansjer.cn_config.config_formal import CONFIG_INFO
-from Ansjer.config import CONFIG_INFO
-from Controller.DeviceConfirmRegion import Device_Region
-from Object.AWS.AmazonS3Util import AmazonS3Util
-from Object.RedisObject import RedisObject
-from Service.VodHlsService import SplitVodHlsObject
-
-'''
-http://192.168.136.40:8077/Test
-'''
-import json
-import time
-import urllib
-import requests
-from Object.AliPayObject import AliPayObject
-import boto3
-from boto3.session import Session
 import oss2
 import paypalrestsdk
-import logging
+import requests
+from boto3.session import Session
+from botocore import client
+from django.contrib.auth.hashers import make_password  # 对密码加密模块
+from django.db import transaction, connection
 from django.http import JsonResponse, HttpResponse
 from django.utils.decorators import method_decorator
 from django.views.decorators.csrf import csrf_exempt
 from django.views.generic.base import View
-from django.contrib.auth.hashers import make_password  # 对密码加密模块
+
+from Ansjer.config import CONFIG_INFO
 from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, AWS_ACCESS_KEY_ID, \
     AWS_SECRET_ACCESS_KEY, SERVER_TYPE, AWS_SES_ACCESS_REGION
+from Ansjer.config import SERVER_DOMAIN_SSL
+from Controller.DeviceConfirmRegion import Device_Region
+from Model.models import Device_Info, UID_Bucket, UID_Preview, UidSetModel
 from Model.models import Order_Model, Store_Meal, DeviceLogModel, VodBucketModel, \
-    TestSerialRepetition, UIDCompanySerialModel, CompanySerialModel, LogModel
+    TestSerialRepetition, TestDeviceFindSerial, UIDCompanySerialModel, CompanySerialModel, LogModel, Device_User
+from Object.AWS.AmazonS3Util import AmazonS3Util
+from Object.AliPayObject import AliPayObject
+from Object.RedisObject import RedisObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
-from Service.CommonService import CommonService
 from Object.m3u8generate import PlaylistGenerator
-from Model.models import Device_Info, UID_Bucket, UID_Preview, UidSetModel
-from Ansjer.config import SERVER_DOMAIN_SSL
+from Service.CommonService import CommonService
+from Service.VodHlsService import SplitVodHlsObject
 
-SERVER_DOMAIN = 'http://test.dvema.com/'
 ACCESS_KEY = "AKIA2E67UIMD3CYTIWPA"
 SECRET_KEY = "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"
 LOGGER = logging.getLogger('info')
 
 
-# 测试接口sdk
 class testView(View):
     @method_decorator(csrf_exempt)
     def dispatch(self, *args, **kwargs):
@@ -85,48 +65,15 @@ class testView(View):
 
     def validation(self, request_dict, request, operation):
         response = ResponseObject()
-        # operation => cloudVod/path
-        if operation is None:
-            return response.json(444, 'error path')
-        elif operation == 'tests':
-            logger = logging.getLogger('info')
-            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':
-            ip = CommonService.get_ip_address(request)
-            userID = '158943594633713800138000'
-            return self.do_test_query_vod_list(userID, ip, request_dict, response)
+        if operation == 'generateToken':
+            return self.generate_token(request_dict)
         elif operation == 'signplaym3u8':
             return self.do_sign_play_m3u8(request_dict, response)
-        elif operation == 'get_sign_sts':
-            ip = CommonService.get_ip_address(request)
-            return self.do_test_get_sign_sts(request_dict, ip, response)
-        elif operation == 'eqi_query':
-            userID = '158943594633713800138000'
-            return self.queryInterface(request_dict, userID, response)
-        elif operation == 'getAlexa':
-            userID = '158943594633713800138000'
-            return self.queryInterface(request_dict, userID, response)
-        elif operation == 'generateToken':
-            userID = '158943604783713800138000'
-            return self.generate_token(request_dict, userID)
+        elif operation == 'analysisToken':
+            return self.analysis_token(request_dict, response)
         elif operation == 'test_upload_s3':
-            userID = '158943604783713800138000'
             return self.test_upload_s3(request_dict, response)
         elif operation == 'rekognition':
-            userID = '158943604783713800138000'
             return self.testRekognition(request, request_dict)
         elif operation == 'ip':
             return self.ip(response)
@@ -140,6 +87,8 @@ class testView(View):
             return self.do_comb(request_dict, response)
         elif operation == 'count_ts':
             return self.count_ts(request_dict, response)
+        elif operation == 'tsCount':
+            return self.ts_count(request_dict, response)
         elif operation == 'upload-s3':
             return self.file_upload_s3(request, request_dict, response)
         elif operation == 'v2/upload-s3':
@@ -170,8 +119,18 @@ class testView(View):
             return self.getSerialNumberInfo(request_dict, response)
         elif operation == 'get-serial-details':  # 序列号信息查询
             return self.get_serial_details(request_dict, response, request)
+        elif operation == 'find_device_serial':  # 查找设备序列号接口:306低功耗无Wi-Fi产品
+            return self.find_device_serial(request_dict, response)
         else:
-            return 123
+            return response.json(414)
+
+    @staticmethod
+    def generate_token(request_dict):
+        tko = TokenObject()
+        userID = request_dict.get('userID', None)
+        username = request_dict.get('username', None)
+        res = tko.generate(data={'userID': userID, 'lang': 'cn', 'user': username, 'm_code': username})
+        return JsonResponse(status=200, data=res, safe=False)
 
     @classmethod
     def serial_repetition_test_v2(cls, request_dict, response):
@@ -203,30 +162,6 @@ class testView(View):
             logging.info('异常错误,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
             return response.json(178, e)
 
-    @classmethod
-    def serial_repetition_test(cls, request_dict, response):
-        return response.json()
-        # try:
-        #     serial_no = request_dict.get('serialNo', None)
-        #     if not serial_no:
-        #         return response.json(444)
-        #     with transaction.atomic():
-        #         first_serial = serial_no[:6]
-        #         first_serial_qs = TestSerialRepetition.objects.filter(serial_number__icontains=first_serial)
-        #         if first_serial_qs.exists():
-        #             return response.json(174)
-        #         serial_qs = TestSerialRepetition.objects.filter(serial_number=serial_no)
-        #         if not serial_qs.exists():
-        #             n_time = int(time.time())
-        #             params = {'serial_number': serial_no, 'created_time': n_time}
-        #             TestSerialRepetition.objects.create(**params)
-        #             return response.json(0)
-        #         else:
-        #             return response.json(174)
-        # except Exception as e:
-        #     logging.info('异常错误,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
-        #     return response.json(178, e)
-
     @classmethod
     def generate_video(cls, request_dict, response):
         # 设计抽取图片规则通过消息随机还是时间随机,调试copy S3对象查询是否携带失效时间
@@ -417,139 +352,6 @@ class testView(View):
         # print(related_resources)
         # return HttpResponse(sale)
 
-    def createBucket(self):
-
-        # 查看桶列表
-        # url = "https://azvod1.s3-ap-northeast-1.amazonaws.com"
-        # session = Session(ACCESS_KEY, SECRET_KEY)
-        # s3_client = session.client('s3', endpoint_url=url)
-        # results = s3_client.list_buckets()
-        # return JsonResponse(status=200, data={'code': 200, 'msg': results['Buckets']})
-
-        # Create bucket
-        session = Session(ACCESS_KEY, SECRET_KEY)
-        s3_client = session.client('s3')
-
-        # 上传
-        # s3_client.put_object(Bucket="azvod1", Key="file/rule.txt", Body=open(r"E:\download\Shadowsocks-4.1.10.0\user-rule.txt", 'rb').read())
-
-        # 下载
-        resp = s3_client.get_object(Bucket="azvod1", Key="file/rule.txt")
-        with open('local.txt', 'wb') as f:
-            f.write(resp['Body'].read())
-
-    # 新查询设备字段
-    def queryInterface(self, request_dict, userID, response):
-        page = request_dict.get('page', None)
-        line = request_dict.get('line', None)
-        NickName = request_dict.get('NickName', None)
-        uid = request_dict.get('uid', None)
-        page = int(page)
-        line = int(line)
-        response.lang = 'cn'
-        userID = userID
-        dvqs = Device_Info.objects.filter(userID_id=userID)
-        # # 已重置的设备
-        # dvqs = dvqs.filter(~Q(isExist=2))
-        if NickName:
-            dvqs = dvqs.filter(NickName__icontains=NickName)
-        if uid:
-            dvqs = dvqs.filter(UID=uid)
-        # count = dvqs.count()
-        # 分页
-        dvql = dvqs[(page - 1) * line:page * line].values('id', 'userID', 'NickName', 'UID', 'View_Account',
-                                                          'View_Password', 'ChannelIndex', 'Type', 'isShare',
-                                                          'primaryUserID', 'primaryMaster', 'data_joined',
-                                                          'version',
-                                                          'isVod', 'isExist', 'NotificationMode')
-        dvls = CommonService.qs_to_list(dvql)
-        uid_list = []
-        for dvl in dvls:
-            uid_list.append(dvl['UID'])
-            # if dvl['isShare'] is False:
-            #     uid_list.append(dvl['UID'])
-        ubqs = UID_Bucket.objects.filter(uid__in=uid_list). \
-            values('bucket__content', 'status', 'channel', 'endTime', 'uid')
-        upqs = UID_Preview.objects.filter(uid__in=uid_list).order_by('channel').values('id', 'uid', 'channel')
-        auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
-        bucket = oss2.Bucket(auth, 'oss-cn-hongkong.aliyuncs.com', 'statres')
-        nowTime = int(time.time())
-        data = []
-        # 设备拓展信息表
-        us_qs = UidSetModel.objects.filter(uid__in=uid_list). \
-            values('uid', 'version', 'nickname', 'detect_interval')
-        uv_dict = {}
-        for us in us_qs:
-            uv_dict[us['uid']] = {'version': us['version'],
-                                  'nickname': us['nickname'],
-                                  'detect_interval': us['detect_interval']}
-        for p in dvls:
-            p['vod'] = []
-            for dm in ubqs:
-                if p['UID'] == dm['uid']:
-                    if dm['endTime'] > nowTime:
-                        p['vod'].append(dm)
-            p['preview'] = []
-            for up in upqs:
-                if p['UID'] == up['uid']:
-                    obj = 'uid_preview/{uid}/channel_{channel}.png'. \
-                        format(uid=up['uid'], channel=up['channel'])
-                    img_sign = bucket.sign_url('GET', obj, 300)
-                    p['preview'].append(img_sign)
-            p_uid = p['UID']
-            if p_uid in uv_dict:
-                # 设备版本号
-                p['uid_version'] = uv_dict[p_uid]['version']
-                p['detect_interval'] = uv_dict[p_uid]['detect_interval']
-                # 设备昵称 调用影子信息昵称,先阶段不可
-                if uv_dict[p_uid]['nickname']:
-                    p['NickName'] = uv_dict[p_uid]['nickname']
-            else:
-                # 设备版本号
-                p['uid_version'] = ''
-            data.append(p)
-        return response.json(0, data)
-
-    # 获取播放列表
-    def do_test_query_vod_list(self, userID, ip, request_dict, response):
-        uid = 'GZL2PEFJPLY7W6BG111A'
-        channel = 2
-        userID = '158943594633713800138000'
-        dv_qs = Device_Info.objects.filter(UID=uid, userID_id=userID, isShare=False)
-        if not dv_qs.exists():
-            return response.json(12)
-        vod_play_list = []
-        bucket_name = 'azvod1'
-        aws_access_key_id = 'AKIA2E67UIMD45Y3HL53'
-        aws_secret_access_key = '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'
-        session = Session(
-            aws_access_key_id=aws_access_key_id,
-            aws_secret_access_key=aws_secret_access_key,
-            region_name='ap-northeast-1'
-        )
-        conn = session.client('s3')
-        thumbspng = '{uid}/vod{channel}/{time}/thumbs.png'. \
-            format(uid=uid, channel=channel, time=1590485548)
-        response_url = conn.generate_presigned_url(
-            'get_object',
-            Params={
-                'Bucket': bucket_name,
-                'Key': thumbspng
-            },
-            ExpiresIn=3600
-        )
-        # m3u8 = '{uid}/vod{channel}/{time}/{time}.m3u8'. \
-        #     format(uid=uid, channel=channel, time=vod['time'])
-        thumb_url = response_url
-        vod_url = 'http://192.168.136.191:8000/testApi/signplaym3u8?' \
-                  'uid={uid}&channel={channel}&time={time}&sign=tktktktk'. \
-            format(ip=ip, uid=uid, channel=channel, time=1590485548)
-        vod_play_list.append({
-            'name': 1590485548,
-            'sign_url': vod_url,
-            'thumb': thumb_url,
-            'sec': 12})
-        return response.json(0, vod_play_list)
 
     # 生成m3u8列表
     def do_sign_play_m3u8(self, request_dict, response):
@@ -709,21 +511,13 @@ class testView(View):
                 {'name': vod['start_time'], 'sign_url': vod_play_url, 'thumb': thumb, 'sec': vod['sec']})
         return response.json(0, vod_play_list)
 
-    def generate_token(self, request_dict, userID):
-        # UserIdToken
-        tko = TokenObject()
-        userID = request_dict.get('userID', None)
-        username = request_dict.get('username', None)
-        res = tko.generate(
-            data={'userID': userID, 'lang': 'cn', 'user': username, 'm_code': username})
-        # uidToken
-        # utko = UidTokenObject()
-        # res = utko.generate(data={'uid': '4UZSEDP93MJ3X7YB111A','channel': 1})
-
-        # from Object.ETkObject import ETkObject
-        # etkObj = ETkObject(etk='')
-        # res = etkObj.encrypt("4UZSEDP93MJ3X7YB111A")
-        return JsonResponse(status=200, data=res, safe=False)
+    @staticmethod
+    def analysis_token(request_dict, response):
+        token = request_dict.get('token', None)
+        token = TokenObject(token)
+        user_id = token.userID
+        username = Device_User.objects.get(userID=user_id).username
+        return response.json(0, username)
 
     def test_upload_s3(self, request_dict, response):
         aws_s3_guonei = boto3.client(
@@ -817,11 +611,35 @@ class testView(View):
                 sumSec += (fg >> shift) & 0xf
         size = 0
         return HttpResponse(
-            "{year}年{month}月 </br>上传的TS总数:{sumTs} </br> 总秒数:{sumSec} </br> 总大小:{size}GB (1秒约等150KB计算)".format(year=year,
-                                                                                                              month=month,
-                                                                                                              sumTs=sumTs,
-                                                                                                              sumSec=sumSec,
-                                                                                                              size=size))
+            "{year}年{month}月 </br>上传的TS总数:{sumTs} </br> 总秒数:{sumSec} </br> 总大小:{size}GB (1秒约等150KB计算)".format(
+                year=year,
+                month=month,
+                sumTs=sumTs,
+                sumSec=sumSec,
+                size=size))
+
+    @staticmethod
+    def ts_count(request_dict, response):
+        uid = request_dict.get('uid', None)
+        start_time = request_dict.get('start_time', None)
+        end_time = request_dict.get('end_time', None)
+
+        cursor = connection.cursor()
+        sql = 'SELECT fg FROM `vod_hls_mon` WHERE uid=%s AND start_time BETWEEN 1685289600 AND 1685548800 UNION ALL SELECT fg FROM `vod_hls_tues` WHERE uid=%s AND start_time BETWEEN 1685289600 AND 1685548800 UNION ALL SELECT fg FROM `vod_hls_wed` WHERE uid=%s AND start_time BETWEEN 1685289600 AND 1685548800 UNION ALL SELECT fg FROM `vod_hls_thur` WHERE uid=%s AND start_time BETWEEN 1685289600 AND 1685548800 UNION ALL SELECT fg FROM `vod_hls_fri` WHERE uid=%s AND start_time BETWEEN 1685289600 AND 1685548800 UNION ALL SELECT fg FROM `vod_hls_sat` WHERE uid=%s AND start_time BETWEEN 1685289600 AND 1685548800 UNION ALL SELECT fg FROM `vod_hls_sun` WHERE uid=%s AND start_time BETWEEN 1685289600 AND 1685548800'
+        print(sql)
+        try:
+            cursor.execute(sql, ['7TR9XE46NHXL5921111A', '7TR9XE46NHXL5921111A', '7TR9XE46NHXL5921111A',
+                                 '7TR9XE46NHXL5921111A', '7TR9XE46NHXL5921111A', '7TR9XE46NHXL5921111A',
+                                 '7TR9XE46NHXL5921111A'])
+            result = cursor.fetchall()
+            cursor.close()
+            ts_count = 0
+            for fg in result:
+                ts_count += int(fg[0]) & 0xf
+            return response.json(0, ts_count)
+        except Exception as e:
+            print(e)
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def write_redis_list(response):
@@ -894,7 +712,7 @@ class testView(View):
             return response
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @classmethod
     def getSerialNumberInfo(cls, request_dict, response):
@@ -902,78 +720,68 @@ class testView(View):
         serial_number = request_dict.get('serialNumber', None)
         if not serial_number:
             return response.json(444)
+        serialNumber = serial_number[:9]
+        serial_number = serial_number[:6]
         try:
             uid_user_message = {
                 "uid": "",
                 "serialNumber": "",
                 "userID": "",
                 "username": "",
-                "primaryUserID": "",
+                "primaryUserID": ""
             }
             data = {
                 "uid": "",
-                "serialNumber": serial_number[:9],
+                "serialNumber": serialNumber,
                 "status": "",
-                "add_time": "",
                 "uid_user_message": uid_user_message
             }
-            # 获取序列哈状态
-            company_serial_qs = CompanySerialModel.objects.filter(serial_number=serial_number[:6]).values('status')
+            company_serial_qs = CompanySerialModel.objects.filter(serial_number=serial_number).values('status')
             if not company_serial_qs.exists():
                 return response.json(173)
-            company_serial_qs = company_serial_qs.first()
-            if company_serial_qs['status'] == 0:
+            if company_serial_qs[0]['status'] == 0:
                 return response.json(0, {'contents': '序列号未分配'})
             uid_company_serial_qs = UIDCompanySerialModel.objects.filter(
-                company_serial__serial_number=serial_number[:6]).values('uid__uid', 'uid__status',
-                                                                        'company_serial__serial_number', 'add_time')
-            if not uid_company_serial_qs.exists():
-                data['status'] = cls.serial_number_status(company_serial_qs['status'])
+                company_serial__serial_number=serial_number).values('uid__uid', 'uid__status',
+                                                                    'company_serial__serial_number')
+            if not uid_company_serial_qs.exists() and company_serial_qs[0]['status'] != 0:
+                if company_serial_qs[0]['status'] == 1:
+                    data['status'] = '已分配'
+                if company_serial_qs[0]['status'] == 2:
+                    data['status'] = '绑定uid'
+                if company_serial_qs[0]['status'] == 3:
+                    data['status'] = '已占用'
                 return response.json(0, data)
-            uid_company_serial = uid_company_serial_qs.first()
-            data['uid'] = uid_company_serial['uid__uid']
-            data['status'] = uid_company_serial['uid__status']
-            data['add_time'] = CommonService.timestamp_to_str(uid_company_serial['add_time'])
-            data['status'] = cls.serial_number_status(company_serial_qs['status'])
-            device_info_qs = Device_Info.objects.filter(UID=data['uid']).values(
-                'UID',
-                'serial_number',
-                'userID_id',
-                'primaryUserID',
-                'userID__username',
-                'data_joined').order_by('-data_joined')
-            if device_info_qs.exists():
-                # 判断主用户是否存在
-                primary_qs = device_info_qs.exclude(primaryUserID='')
-                if primary_qs.exists():
-                    uid_user_message['uid'] = primary_qs[0]['UID'],
-                    uid_user_message['serialNumber'] = primary_qs[0]['serial_number']
-                    uid_user_message['userID'] = primary_qs[0]['userID_id']
-                    uid_user_message['username'] = primary_qs[0]['userID__username']
-                    uid_user_message['primaryUserID'] = primary_qs[0]['primaryUserID']
-                else:
-                    device_info = device_info_qs.first()
-                    uid_user_message['uid'] = device_info['UID']
-                    uid_user_message['serialNumber'] = device_info['serial_number']
-                    uid_user_message['userID'] = device_info['userID_id']
-                    uid_user_message['username'] = device_info['userID__username']
-                    uid_user_message['primaryUserID'] = device_info['primaryUserID']
+            for uid_company_serial in uid_company_serial_qs:
+                data['uid'] = uid_company_serial['uid__uid']
+                data['serialNumber'] = serialNumber
+                data['status'] = uid_company_serial['uid__status']
+                if company_serial_qs[0]['status'] == 1:
+                    data['status'] = '已分配'
+                if company_serial_qs[0]['status'] == 2:
+                    data['status'] = '绑定uid'
+                if company_serial_qs[0]['status'] == 3:
+                    data['status'] = '已占用'
+                uid = uid_company_serial['uid__uid'] if uid_company_serial['uid__uid'] else ''
+                device_info_qs = Device_Info.objects.filter(UID=uid).values(
+                    'UID',
+                    'serial_number',
+                    'userID_id',
+                    'primaryUserID',
+                    'userID__username')
+                uid_user_message = {
+                    'uid': device_info_qs[0]['UID'] if device_info_qs.exists() else '',
+                    'serialNumber': device_info_qs[0]['serial_number'] if device_info_qs.exists() else '',
+                    'userID': device_info_qs[0]['userID_id'] if device_info_qs.exists() else '',
+                    'username': device_info_qs[0]['userID__username'] if device_info_qs.exists() else '',
+                    'primaryUserID': device_info_qs[0]['primaryUserID'] if device_info_qs.exists() else ''
+                }
+                data['uid_user_message'] = uid_user_message
             return response.json(0, data)
         except Exception as e:
-            logger.error('序列号:{}, 查询异常:{}'.format(serial_number, e))
+            logger.info('查询异常:{}'.format(e))
             return response.json(500)
 
-    @staticmethod
-    def serial_number_status(status):
-        # 判断序号状态
-        if status == 1:
-            status = '已分配'
-        elif status == 2:
-            status = '绑定uid'
-        elif status == 3:
-            status = '已占用'
-        return status
-
     @classmethod
     def get_serial_details(cls, request_dict, response, request):
         """
@@ -1034,3 +842,55 @@ class testView(View):
             LOGGER.info('异常详情,errLine:{}, errMsg:{}'
                         .format(e.__traceback__.tb_lineno, repr(e)))
             return response.json(500)
+
+    @classmethod
+    def find_device_serial(cls, request_dict, response):
+        try:
+            firmware_time_code_no = request_dict.get('firmwareTimeCode', None)
+            function_type_str = request_dict.get('functionType', None)
+            serial_no = request_dict.get('serialNo', None)
+            time_stamp = request_dict.get('timeStamp', None)
+            sign = request_dict.get('sign', None)
+            if not CommonService.check_time_stamp_token(sign, time_stamp):
+                return response.json(13)
+            if not function_type_str:
+                return response.json(444)
+            with transaction.atomic():
+                first_firmwares_qs = TestDeviceFindSerial.objects.filter(firmware_time_code=firmware_time_code_no)
+                if function_type_str == 'device_save_serial':  # 设备上报序列号绑定固件码  get_device_serial
+                    if not all([firmware_time_code_no, serial_no]):
+                        return response.json(444)
+                    if first_firmwares_qs.exists():
+                        return response.json(174)
+                    nowtime = int(time.time())
+                    params = {'firmware_time_code': firmware_time_code_no,
+                              'serial_number': serial_no,
+                              'created_time': nowtime}
+                    TestDeviceFindSerial.objects.create(**params)
+                    return response.json(0)
+                elif function_type_str == 'get_device-serial':  # 根据固件码获取序列号
+                    if not firmware_time_code_no:
+                        return response.json(444)
+                    if first_firmwares_qs.exists():
+                        result = {'Id': first_firmwares_qs.first().id,
+                                  'firmwareTimeCode': firmware_time_code_no,
+                                  'serialNumber': first_firmwares_qs.first().serial_number,
+                                  'createdTime': first_firmwares_qs.first().created_time}
+                        print('返回结果 : %s', result)
+                        return response.json(0, result)
+                    else:
+                        return response.json(173)
+                else:
+                    return response.json(444)
+
+        except Exception as e:
+            LOGGER.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            return response.json(178, e)
+
+    @staticmethod
+    def password(request_dict, response):
+        password = request_dict.get('password', None)
+        password_version = request_dict.get('pwdVersion', 'V1')
+        if password_version == 'V1':
+            password = make_password(password)
+        return response.json(0)

Diff do ficheiro suprimidas por serem muito extensas
+ 299 - 192
Controller/UserController.py


+ 2 - 2
Controller/UserDevice/UserDeviceShareController.py

@@ -88,7 +88,7 @@ class UserDeviceShareView(View):
             return response.json(0, data)
         except Exception as e:
             LOGGER.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @classmethod
     def user_channel_permission_save(cls, request_dict, response):
@@ -137,7 +137,7 @@ class UserDeviceShareView(View):
                 return response.json(0)
         except Exception as e:
             LOGGER.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def qrcode_share_channel_permission_save(user_id, uid):

+ 13 - 4
Controller/UserManger.py

@@ -12,7 +12,8 @@ from django.views.generic import TemplateView, View
 
 from Ansjer.config import BASE_DIR, 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, CountryLanguageModel, LanguageModel, App_Info
+from Model.models import Role, Device_User, UserOauth2Model, UserExModel, CountryLanguageModel, LanguageModel, App_Info, \
+    IcloudUseDetails
 from Object.RedisObject import RedisObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
@@ -74,6 +75,9 @@ class showUserMoreView(TemplateView):
                         userIconUrl = SERVER_DOMAIN + 'account/getAvatar/' + userIconPath
                         sqlDict['datas'][k]['fields']['userIconUrl'] = userIconUrl
 
+                # 判断用户是否开通云盘
+                icloud_user_qs = IcloudUseDetails.objects.filter(user_id=user_id)
+                v['fields']['is_cloudDrive'] = 1 if icloud_user_qs.exists() else 0
                 # 确认地区字段
                 sqlDict['datas'][k]['fields']['region_status'] = 1 if region_status else 0
 
@@ -111,7 +115,7 @@ class showUserMoreView(TemplateView):
                     region_country = sqlDict['datas'][k]['fields']['region_country']
                     language_qs = LanguageModel.objects.filter(lang=lang).values('id')
                     region_qs = CountryLanguageModel.objects.filter(country_id=region_country,
-                                                                    language_id=language_qs[0]['id']).\
+                                                                    language_id=language_qs[0]['id']). \
                         values('country_name')
                     sqlDict['datas'][k]['fields']['region'] = region_qs[0]['country_name'] if region_qs.exists() else ''
 
@@ -120,7 +124,7 @@ class showUserMoreView(TemplateView):
             sqlDict['oauth2'] = list(ua_qs)
             return response.json(0, sqlDict)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
 
 class perfectUserInfoView(TemplateView):
@@ -213,6 +217,11 @@ class perfectUserInfoView(TemplateView):
             for k, v in enumerate(res["datas"]):
                 res['datas'][k]['fields'].pop('password')
                 userIconPath = res['datas'][k]['fields']['userIconPath']
+                region_status = res['datas'][k]['fields']['region_status']
+                if region_status is True:
+                    res['datas'][k]['fields']['region_status'] = 1
+                else:
+                    res['datas'][k]['fields']['region_status'] = 0
                 if userIconPath and userIconUrl != '':
                     res['datas'][k]['fields']['userIconUrl'] = userIconUrl
             return response.json(0, res)
@@ -253,7 +262,7 @@ class getAvatarView(TemplateView):
                 return HttpResponse(get_object_response['Body'], content_type="image/jpeg")
             except Exception as e:
                 print(e)
-                return response.json(500, repr(e))
+                return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
         fullPath = os.path.join(BASE_DIR, "static", filePath).replace('\\', '/')
         if os.path.isfile(fullPath):

+ 143 - 17
Model/models.py

@@ -754,8 +754,8 @@ class Store_Meal(models.Model):
     lang = models.ManyToManyField(to='Lang', verbose_name='套餐语言', db_table='store_meal_lang')
     cycle_config_id = models.IntegerField(null=True, verbose_name='周期付款配置表id')
     sort = models.IntegerField(default=99, blank=True, verbose_name=u'排序,越小越靠前')  # 单位月
+    icloud_store_meal_id = models.IntegerField(default=0, verbose_name='关联云盘套餐id')
     # 备用字段
-    spare_3 = models.CharField(default='', blank=True, max_length=64, db_index=True, verbose_name=u'备用字段3')
     spare_4 = models.CharField(default='', blank=True, max_length=64, db_index=True, verbose_name=u'备用字段4')
 
     def __str__(self):
@@ -815,6 +815,7 @@ class Lang(models.Model):
     title = models.CharField(blank=True, max_length=320, verbose_name='标题')
     content = models.TextField(blank=True, null=True, verbose_name='描述')
     discount_content = models.CharField(blank=True, max_length=320, verbose_name=u'优惠信息描述')
+    type = models.SmallIntegerField(default=0, verbose_name='类型')  # 0:云存 1:AI 2:4G 3:云盘
 
     def __str__(self):
         return self.id
@@ -848,6 +849,7 @@ class Equipment_Version(models.Model):
     mci = models.CharField(default='', blank=True, max_length=10, verbose_name='设备类型')
     img = models.CharField(max_length=300, blank=True, default='', verbose_name=u'图片路径')
     max_ver = models.CharField(default='', max_length=16, verbose_name='最大版本号')
+    is_popup = models.SmallIntegerField(default=0, verbose_name=u'是否弹窗')
 
     def __str__(self):
         return self.eid
@@ -933,7 +935,7 @@ class Order_Model(models.Model):
     rank = models.ForeignKey(Store_Meal, to_field='id', default='', on_delete=models.CASCADE, verbose_name='关联云存套餐表')
     ai_rank = models.ForeignKey(AiStoreMeal, to_field='id', default='', on_delete=models.CASCADE,
                                 verbose_name='关联ai套餐表')
-    order_type = models.SmallIntegerField(default=0, verbose_name='订单类型:0:云存,1:ai,2:联通4G')
+    order_type = models.SmallIntegerField(default=0, verbose_name='订单类型:0:云存,1:ai,2:联通4G,3:五兴,4:云盘')
     unify_combo_id = models.CharField(blank=True, default='', max_length=32, verbose_name=u'统一套餐id')
     nickname = models.CharField(default='', max_length=64, verbose_name='设备昵称')
     uid_bucket_id = models.IntegerField(default=0, verbose_name='关联uid_bucket的字段')
@@ -1270,7 +1272,7 @@ class UID_Bucket(models.Model):
     uid = models.CharField(max_length=20, verbose_name='设备UID', db_index=True)
     channel = models.SmallIntegerField(default=0, verbose_name='通道')
     bucket = models.ForeignKey(VodBucketModel, blank=True, to_field='id', on_delete=models.CASCADE, verbose_name='存储空间')
-    status = models.SmallIntegerField(default=0, verbose_name='状态[0:关闭,1:开启]')
+    status = models.SmallIntegerField(default=0, verbose_name='状态[0:关闭,1:开启]')  # 修改2023/5/15(原状态[0:开启,1:关闭])
     endTime = models.BigIntegerField(verbose_name='套餐结束时间', db_index=True, default=0)
     addTime = models.IntegerField(verbose_name='添加时间', default=0)
     updateTime = models.BigIntegerField(verbose_name='更新时间', default=0)
@@ -1384,6 +1386,7 @@ class UidSetModel(models.Model):
     tb_city_information_id = models.IntegerField(blank=True, default=0, verbose_name='城市信息')
     device_type = models.SmallIntegerField(default=0, verbose_name='设备类型')
     ai_type = models.SmallIntegerField(default=0, verbose_name='检测类型')
+    msg_notify = models.JSONField(null=True, verbose_name='消息通知Json')
 
     class Meta:
         db_table = 'uid_set'
@@ -2761,7 +2764,7 @@ class GatewaySubDevice(models.Model):
     nickname = models.CharField(default='', max_length=32, verbose_name=u'设备名称')
     ieee_addr = models.CharField(default='', max_length=64, verbose_name=u'长地址')
     src_addr = models.CharField(default='', max_length=16, verbose_name=u'短地址')
-    status = models.SmallIntegerField(default=0, verbose_name='状态')  # 0:关闭, 1:开启
+    status = models.SmallIntegerField(default=1, verbose_name='在线状态')  # 1:在线, 0:离线
     # 0:正常, 1:被拆动, 智能按钮紧急开关状态: 0:关闭, 1:开启
     is_tampered = models.SmallIntegerField(default=0, verbose_name='拆动状态')
     mac = models.CharField(default='', max_length=32, verbose_name=u'mac地址')
@@ -3536,6 +3539,58 @@ class SocketSchedule(models.Model):
         verbose_name_plural = verbose_name
 
 
+class SwitchInfo(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name='自增id')
+    device_id = models.CharField(max_length=32, default='', verbose_name='设备id')
+    model = models.CharField(max_length=32, default='', verbose_name='型号')
+    hardware_version = models.CharField(max_length=32, default='', verbose_name='硬件版本')
+    firmware_version = models.CharField(max_length=32, default='', verbose_name='固件版本')
+    mac = models.CharField(max_length=32, default='', verbose_name='mac地址')
+
+    class Meta:
+        db_table = 'switch_info'
+        verbose_name = '智能开关信息'
+        verbose_name_plural = verbose_name
+
+
+class SwitchDimmingSettings(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name='自增id')
+    device_id = models.CharField(max_length=32, default='', verbose_name='设备id')
+    click_turn_on_speed = models.SmallIntegerField(default=0, verbose_name='单击开启速度')
+    click_turn_off_speed = models.SmallIntegerField(default=0, verbose_name='单击关闭速度')
+    double_click = models.CharField(max_length=8, default='', verbose_name='双击')  # 0: 无, 1: 缓慢开/关, x%: 预设亮度
+    press = models.CharField(max_length=8, default='', verbose_name='长按')  # 0: 无, 1: 缓慢开/关, x%: 预设亮度
+    double_press_click_turn_on_speed = models.SmallIntegerField(default=0, verbose_name='双击/长按开启速度')
+    double_press_click_turn_off_speed = models.SmallIntegerField(default=0, verbose_name='双击/长按单击关闭速度')
+    led = models.BooleanField(default=False, verbose_name='LED指示灯')  # True: 开, False: 关
+    dimming_correction = models.CharField(max_length=8, default='', verbose_name='调光校正')
+
+    class Meta:
+        db_table = 'switch_dimming_settings'
+        verbose_name = '智能开关调光设置'
+        verbose_name_plural = verbose_name
+
+
+class SwitchChronopher(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name='自增id')
+    device_id = models.CharField(max_length=32, default='', verbose_name='设备id')
+    time_type_radio = models.SmallIntegerField(default=0, verbose_name='切换时间点/时间段')  # 1: 按时间点, 2: 按时间段
+    time_point = models.IntegerField(default=0, verbose_name='时间点')
+    time_quantum_start_time = models.IntegerField(default=0, verbose_name='时间段开始时间')
+    time_quantum_end_time = models.IntegerField(default=0, verbose_name='时间段结束时间')
+    time_point_device_will_doing = models.CharField(max_length=8, default='',
+                                                    verbose_name='设备将会')  # 0: 开启, 1: 关闭, x%: 预设亮度
+    time_quantum_device_will_doing = models.SmallIntegerField(default=0,
+                                                              verbose_name='设备将会')  # 0: 开启, 1: 关闭, x: 开启/关闭切换间隔
+    slow_open_or_close_speed = models.SmallIntegerField(default=0, verbose_name='缓慢开/关速度')
+    repeat = models.SmallIntegerField(default=0, verbose_name=u'重复周期')
+
+    class Meta:
+        db_table = 'switch_chronopher'
+        verbose_name = '定时计划'
+        verbose_name_plural = verbose_name
+
+
 class ExchangeCode(models.Model):
     id = models.AutoField(primary_key=True)
     code = models.CharField(max_length=32, unique=True, verbose_name='兑换码')
@@ -3555,6 +3610,90 @@ class ExchangeCode(models.Model):
         verbose_name_plural = verbose_name
 
 
+class ICloudStoreMeal(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name=u'自增ID')
+    currency = models.CharField(blank=True, default='$', max_length=32, verbose_name=u'货币符号')
+    symbol = models.CharField(blank=True, default='$', max_length=32, verbose_name=u'符号')
+    price = models.CharField(blank=True, max_length=32, verbose_name=u'价格')
+    expire = models.IntegerField(default=0, blank=True, verbose_name=u'有效期')  # 单位月
+    add_time = models.DateTimeField(blank=True, null=True, verbose_name=u'加入时间', auto_now_add=True)
+    pay_type = models.ManyToManyField(to='Pay_Type', verbose_name='付款类型', db_table='icloud_store_meal_pay')
+    update_time = models.DateTimeField(blank=True, verbose_name=u'更新时间', auto_now=True)
+    is_show = models.SmallIntegerField(default=0, verbose_name=u'是否隐藏 [0=隐藏,1展示]')
+    is_delete = models.SmallIntegerField(default=0, verbose_name=u'是否删除 [0=否,1=是]')
+    lang = models.ManyToManyField(to='Lang', verbose_name='套餐语言', db_table='icloud_store_meal_lang')
+    size = models.IntegerField(null=True, default=0, verbose_name='云盘容量大小')  # 单位GB
+    bucket_id = models.SmallIntegerField(default=0, verbose_name='关联存储桶id')
+    sort = models.IntegerField(default=99, blank=True, verbose_name=u'排序,越小越靠前')
+
+    def __str__(self):
+        return self.id
+
+    class Meta:
+        db_table = 'icloud_store_meal'
+        verbose_name = u'云盘套餐'
+        verbose_name_plural = verbose_name
+        ordering = ('id',)
+
+
+class IcloudUseDetails(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
+    use_size = models.DecimalField(default=0, max_digits=10, decimal_places=2, verbose_name='已使用容量大小')  # 单位MB
+    add_time = models.IntegerField(verbose_name='添加时间', default=0)
+    upd_time = models.BigIntegerField(verbose_name='更新时间', default=0)
+    detect_status = models.SmallIntegerField(default=0, verbose_name='开关状态')  # 0:关闭, 1:开启
+    user_id = models.CharField(blank=True, max_length=32, verbose_name=u'用户id')
+    bucket_id = models.SmallIntegerField(default=0, verbose_name='关联存储桶id')
+
+    class Meta:
+        db_table = 'icloud_use_details'
+        verbose_name = '云盘使用表'
+        verbose_name_plural = verbose_name
+        ordering = ('id',)
+
+
+class IcloudService(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
+    size = models.IntegerField(default=0, verbose_name='容量大小')  # 单位GB
+    end_time = models.IntegerField(verbose_name='套餐结束时间', db_index=True, default=0)
+    add_time = models.IntegerField(verbose_name='添加时间', default=0)
+    upd_time = models.IntegerField(verbose_name='更新时间', default=0)
+    use_status = models.IntegerField(verbose_name='使用状态', default=0)  # 0:使用中, 1:已过期
+    use_details_id = models.IntegerField(default=0, verbose_name='关联云盘使用表id')
+    type = models.SmallIntegerField(default=0, verbose_name='云盘购买类型')  # 0:注册永久送,1:购买云存附送,2:单独购买套餐
+    order_id = models.CharField(default='', max_length=20, verbose_name='关联订单id')
+
+    class Meta:
+        db_table = 'icloud_service'
+        verbose_name = '云盘服务表'
+        verbose_name_plural = verbose_name
+        ordering = ('id',)
+
+
+class IcloudStorageRecord(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name='回放列表主键')
+    user_id = models.CharField(blank=True, max_length=32, verbose_name=u'用户id')
+    uid = models.CharField(max_length=20, verbose_name='设备UID', db_index=True)
+    nickname = models.CharField(max_length=20, verbose_name='设备昵称', db_index=True)
+    channel = models.SmallIntegerField(default=0, verbose_name='通道')
+    time_stamp = models.BigIntegerField(verbose_name='视频/图片名字时间戳', default=0, db_index=True)  # 单位毫秒
+    sec = models.IntegerField(verbose_name='秒数', default=0)
+    bucket_id = models.IntegerField(verbose_name='关联存储桶id', default=0)
+    fg = models.CharField(max_length=20, verbose_name='ts个数,时间描述片段数',
+                          default='')  # 阿里为时间片段数,亚马逊为一个32bit整型,前28bit代表ts文件的时长
+    size = models.DecimalField(default=0, max_digits=4, decimal_places=2, verbose_name='视频/图片大小')  # 单位MB
+    file_type = models.SmallIntegerField(default=0, verbose_name='文件类型')  # 0:图片, 1:ts视频, 2:MP4视频
+
+    def __str__(self):
+        return self.id
+
+    class Meta:
+        db_table = 'icloud_storage_record'
+        verbose_name = u'云盘信息记录表'
+        verbose_name_plural = verbose_name
+        ordering = ('-id',)
+
+
 class IotCardUsageHistory(models.Model):
     id = models.AutoField(primary_key=True, verbose_name='列表主键')
     iccid = models.CharField(default='', max_length=32, verbose_name=u'ICCID号')
@@ -3572,16 +3711,3 @@ class IotCardUsageHistory(models.Model):
         db_table = 'iot_card_usage_history'
         verbose_name = '物联网卡用量历史'
         verbose_name_plural = verbose_name
-
-
-class CityInformation(models.Model):
-    id = models.AutoField(primary_key=True, verbose_name='自增id')
-    city_id = models.IntegerField(default=0, verbose_name='城市id')
-    city_name = models.CharField(default='', max_length=50, verbose_name='城市名称')
-    secondary_name = models.CharField(default='', max_length=50, verbose_name='市级名称')
-    province_name = models.CharField(default='', max_length=30, verbose_name='省级名称')
-
-    class Meta:
-        db_table = 'city_information'
-        verbose_name = '城市信息'
-        verbose_name_plural = verbose_name

+ 94 - 0
Object/AWS/AmazonS3Util.py

@@ -149,3 +149,97 @@ class AmazonS3Util:
             'Key': file_key
         }
         self.session_conn.meta.client.copy(source_dict, to_bucket, file_key)
+
+    def copy_single_obj(self, source_bucket, source_object, target_bucket, target_object, StorageClass=None):
+        """
+        单个对象复制
+        @param source_bucket:源存储桶
+        @param source_object:源对象
+        @param target_bucket:目标存储桶
+        @param target_object:目标对象
+        @param StorageClass:存储类
+        @return: None
+        """
+        s3 = self.session_conn
+        copy_source = {
+            'Bucket': source_bucket,
+            'Key': source_object
+        }
+        target_object = s3.Object(target_bucket, target_object)
+        if StorageClass:
+            target_object.copy_from(CopySource=copy_source, StorageClass=StorageClass)
+        else:
+            target_object.copy_from(CopySource=copy_source)
+
+    def generate_put_obj_url(self, bucket_name, obj_key, storage_class=None):
+        """
+        生成预签名对象URL
+        @param bucket_name: 存储桶名称
+        @param obj_key: 对象key
+        @param storage_class: 存储类 例
+        @return: 对象URL
+        """
+        params = {
+            'Bucket': bucket_name,
+            'Key': obj_key,
+        }
+        if storage_class:
+            params['StorageClass'] = storage_class
+        return self.session_conn.meta.client.generate_presigned_url('put_object',
+                                                                    Params=params,
+                                                                    ExpiresIn=7200)
+
+    def batch_copy_obj(self, source_bucket, target_bucket, prefix, target_prefix, storage_class=None):
+        """
+        批量拷贝对象
+        @param source_bucket: 源存储桶
+        @param target_bucket: 目标存储桶
+        @param prefix: 需要搜索的对象前缀 例:AUS000247LTCLY/vod1/1686043996
+        @param target_prefix: 目标对象前缀 例:app/algorithm-shop/1686043996
+        @param storage_class: 存储类
+        @return: None
+        """
+        s3 = self.session_conn
+        # 遍历源存储桶中指定前缀下的所有对象,依次进行复制操作
+        for obj in s3.Bucket(source_bucket).objects.filter(Prefix=prefix):
+            key = obj.key  # 对象键名
+            target_key = f'{target_prefix}/' + key.split('/')[-1]  # 新的对象键名,此处为 "new_path/" + 原有文件名
+            copy_source = {
+                'Bucket': source_bucket,
+                'Key': key
+            }
+            # 将对象复制到目标存储桶,并设置存储类型和新的对象键名
+            if storage_class:
+                s3.Object(target_bucket, target_key).copy_from(CopySource=copy_source, StorageClass=storage_class)
+            else:
+                s3.Object(target_bucket, target_key).copy_from(CopySource=copy_source)
+
+    def get_object_size(self,bucket_name, object_key):
+        """
+        获取存储桶中指定对象的大小
+
+        :param bucket_name: string,存储桶名称
+        :param object_key: string,对象键名
+        :return: int,指定对象的大小,单位为字节
+        """
+        s3 = self.session_conn
+        obj = s3.Object(bucket_name, object_key)
+        try:
+            return obj.content_length
+        except Exception as e:
+            return 0
+
+    def get_object_list(self, bucket_name, prefix):
+        """
+        获取指定路径所有对象
+
+        :param bucket_name: string,存储桶名称
+        :param prefix: string,路径
+        :return: int,指定对象的大小,单位为字节
+        """
+        try:
+            s3 = self.client_conn
+            obj = s3.list_objects_v2(Bucket=bucket_name, Prefix=prefix)
+            return obj['Contents']
+        except Exception as e:
+            return []

+ 33 - 3
Service/CommonService.py

@@ -13,12 +13,13 @@ import simplejson as json
 from dateutil.relativedelta import relativedelta
 from django.core import serializers
 from django.utils import timezone
+from django.utils.crypto import constant_time_compare
 from pyipip import IPIPDatabase
 
 from Ansjer.config import BASE_DIR, SERVER_DOMAIN_SSL, CONFIG_INFO, CONFIG_TEST, CONFIG_CN, SERVER_DOMAIN_TEST, \
     SERVER_DOMAIN_CN, SERVER_DOMAIN_US, CONFIG_US, CONFIG_EUR, SERVER_DOMAIN_LIST, SERVER_DOMAIN_EUR
 from Controller.CheckUserData import RandomStr
-from Model.models import iotdeviceInfoModel, Device_Info, UIDModel
+from Model.models import iotdeviceInfoModel, Device_Info, UIDModel, AppDeviceType
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 
@@ -550,7 +551,7 @@ GCqvlyw5dfxNA+EtxNE2wCW/LW7ENJlACgcfgPlBZtpLheWoZB/maw4=
         """
         根据uid查询返回完整序列号
         @param uid: uid
-        @param serial_number: 序列号
+        @param serial_number: 9位序列号
         @param device_type: 设备类型
         @return: full_serial_number
         """
@@ -657,7 +658,7 @@ GCqvlyw5dfxNA+EtxNE2wCW/LW7ENJlACgcfgPlBZtpLheWoZB/maw4=
 
         time_list = []
         while True:
-            mid_time = datetime.datetime(start_time.year, start_time.month, start_time.day)+relativedelta(days=1)
+            mid_time = datetime.datetime(start_time.year, start_time.month, start_time.day) + relativedelta(days=1)
             if mid_time < end_time:
                 time_tuple = (CommonService.str_to_timestamp(start_time.strftime('%Y-%m-%d %H:%M:%S')),
                               CommonService.str_to_timestamp(mid_time.strftime('%Y-%m-%d %H:%M:%S')))
@@ -728,6 +729,27 @@ GCqvlyw5dfxNA+EtxNE2wCW/LW7ENJlACgcfgPlBZtpLheWoZB/maw4=
             return content
         elif order_type == 2:
             pass
+        elif order_type == 4:
+            content = content + '(' + '云盘' + ')'
+            return content
+
+    @staticmethod
+    def is_cloud_device(ucode, device_type):
+        """
+        设备是否支持云存
+        @param ucode: 设备版本
+        @param device_type: 设备类型
+        """
+        if len(ucode) > 4:
+            number = ucode[-4]
+        else:
+            return False
+        device_type_qs = AppDeviceType.objects.filter(type=device_type).values('model')
+        model = device_type_qs[0]['model'] if device_type_qs.exists() else ''
+        #  判断设备是否为ipc设备和是否支持云存
+        if model == 2 and number in ['4', '5']:
+            return True
+        return False
 
     @staticmethod
     def negative_number_judgment(number_list):
@@ -740,6 +762,14 @@ GCqvlyw5dfxNA+EtxNE2wCW/LW7ENJlACgcfgPlBZtpLheWoZB/maw4=
         else:
             return True
 
+    @staticmethod
+    def check_password(password1, password2):
+        """
+        比较密码
+        @param 返回True or False
+        """
+        return constant_time_compare(password1, password2)
+
     @staticmethod
     def compare_version_number(version_number, version_number_list):
         """

BIN
requirements.txt


Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff