Преглед изворни кода

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

 Conflicts:
	AdminController/AiServeController.py
	AdminController/DeviceManagementController.py
	AdminController/LogManagementController.py
	AdminController/ServeManagementController.py
	AdminController/UnicomManageController.py
	AdminController/UserManageController.py
	AdminController/VersionManagementController.py
	AdminController/dataSystemManagement/HomeDataController.py
	AdminController/dataSystemManagement/ServiceDataController.py
	Ansjer/cn_config/config_test.py
	Ansjer/cn_config/formal_settings.py
	Ansjer/eur_config/formal_settings.py
	Ansjer/server_urls/loocam_url.py
	Ansjer/urls.py
	Controller/AWS/KVSController.py
	Controller/AiController.py
	Controller/AlgorithmShop/AlgorithmShopController.py
	Controller/AppAccountManagement.py
	Controller/CloudStorage.py
	Controller/CloudTransfer.py
	Controller/CloudVod.py
	Controller/Cron/CronTaskController.py
	Controller/DetectController.py
	Controller/DetectControllerV2.py
	Controller/EquipmentManagerV3.py
	Controller/FeedBack.py
	Controller/InitController.py
	Controller/PaymentCycle.py
	Controller/SensorGateway/GatewayDeviceController.py
	Controller/SensorGateway/SmartSceneController.py
	Controller/SensorGateway/SmartSocketController.py
	Controller/SensorGateway/SubDeviceController.py
	Controller/SerialNumberController.py
	Controller/SysMsg.py
	Controller/TestApi.py
	Controller/UnicomCombo/UnicomComboTaskController.py
	Controller/UserController.py
	Controller/UserDevice/UserDeviceShareController.py
	Controller/UserManger.py
	Model/models.py
	Object/AWS/AmazonS3Util.py
	Service/CommonService.py
	requirements.txt
keiSenFront пре 2 година
родитељ
комит
ab2788c8ee
74 измењених фајлова са 4438 додато и 1566 уклоњено
  1. 48 13
      AdminController/AiServeController.py
  2. 79 96
      AdminController/DeviceManagementController.py
  3. 353 0
      AdminController/IcloudManagementController.py
  4. 7 7
      AdminController/LogManagementController.py
  5. 5 5
      AdminController/SerialManageController.py
  6. 8 8
      AdminController/ServeManagementController.py
  7. 5 5
      AdminController/SurveysManageController.py
  8. 1 0
      AdminController/UnicomManageController.py
  9. 34 27
      AdminController/UserManageController.py
  10. 93 81
      AdminController/VersionManagementController.py
  11. 2 2
      AdminController/dataSystemManagement/BusinessDataController.py
  12. 4 4
      AdminController/dataSystemManagement/DeviceDataController.py
  13. 38 6
      AdminController/dataSystemManagement/HomeDataController.py
  14. 24 18
      AdminController/dataSystemManagement/ServiceDataController.py
  15. 6 6
      AdminController/dataSystemManagement/UserDataController.py
  16. 13 0
      Ansjer/Config/gatewaySensorConfig.py
  17. 2 2
      Ansjer/cn_config/config_test.py
  18. 2 2
      Ansjer/cn_config/formal_settings.py
  19. 2 2
      Ansjer/eur_config/formal_settings.py
  20. 13 0
      Ansjer/server_urls/icloud_url.py
  21. 3 1
      Ansjer/server_urls/loocam_url.py
  22. 224 326
      Ansjer/urls.py
  23. 3 3
      Controller/AWS/KVSController.py
  24. 5 4
      Controller/AdminManage.py
  25. 17 18
      Controller/AiController.py
  26. 2 2
      Controller/AlgorithmShop/AlgorithmShopController.py
  27. 1 1
      Controller/AppAccountManagement.py
  28. 1 1
      Controller/AppLogController.py
  29. 2 2
      Controller/CDKController.py
  30. 297 46
      Controller/CloudStorage.py
  31. 3 3
      Controller/CloudTransfer.py
  32. 6 4
      Controller/CloudVod.py
  33. 227 52
      Controller/Cron/CronTaskController.py
  34. 4 3
      Controller/DetectController.py
  35. 47 17
      Controller/DetectControllerV2.py
  36. 1 1
      Controller/DeviceDebug.py
  37. 2 2
      Controller/DeviceLogController.py
  38. 1 1
      Controller/DeviceShare.py
  39. 4 2
      Controller/EquipmentManager.py
  40. 27 8
      Controller/EquipmentManagerV3.py
  41. 6 6
      Controller/FeedBack.py
  42. 609 0
      Controller/IcloudService/IcloudMeal.py
  43. 586 0
      Controller/IcloudService/IcloudService.py
  44. 7 1
      Controller/InitController.py
  45. 6 6
      Controller/IotCoreController.py
  46. 1 1
      Controller/MessagePush/EquipmentMessagePush.py
  47. 2 1
      Controller/OTAEquipment.py
  48. 8 6
      Controller/PaymentCycle.py
  49. 1 1
      Controller/SensorGateway/EquipmentFamilyController.py
  50. 144 63
      Controller/SensorGateway/GatewayDeviceController.py
  51. 4 4
      Controller/SensorGateway/GatewayFamilyRoomController.py
  52. 2 2
      Controller/SensorGateway/SensorGatewayController.py
  53. 134 73
      Controller/SensorGateway/SmartSceneController.py
  54. 7 7
      Controller/SensorGateway/SmartSocketController.py
  55. 352 0
      Controller/SensorGateway/SmartSwitchController.py
  56. 87 66
      Controller/SensorGateway/SubDeviceController.py
  57. 4 1
      Controller/SerialNumberController.py
  58. 1 1
      Controller/Surveys/CloudStorageController.py
  59. 11 3
      Controller/SysMsg.py
  60. 168 308
      Controller/TestApi.py
  61. 10 6
      Controller/TestController.py
  62. 2 2
      Controller/UidSetController.py
  63. 55 0
      Controller/UnicomCombo/UnicomComboTaskController.py
  64. 304 195
      Controller/UserController.py
  65. 2 2
      Controller/UserDevice/UserDeviceShareController.py
  66. 13 4
      Controller/UserManger.py
  67. 1 1
      Controller/VPGController.py
  68. 144 4
      Model/models.py
  69. 94 0
      Object/AWS/AmazonS3Util.py
  70. 1 1
      Object/IOTCore/IotObject.py
  71. 4 1
      Object/ResponseObject.py
  72. 52 4
      Service/CommonService.py
  73. BIN
      requirements.txt
  74. 0 15
      us_test_manage.py

+ 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)))

+ 79 - 96
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):
@@ -627,48 +633,52 @@ class DeviceManagement(View):
         model = request_dict.get('model', None)
         type = request_dict.get('type', None)
         # device_name_language表数据
-        lang = request_dict.get('lang', None)
         name = request_dict.get('name', None)
         sort = request_dict.get('sort', None)
         # 上传图标
         file = request.FILES.get('iconFile', None)
+        if not all([model, type, name, sort, version_number, file]):
+            return response.json(444, 'model, type, file, name, sort, version_number')
         fileName = file.name
-        if not all([model, type, lang, name, sort, version_number]):
-            return response.json(444, 'model, type, lang, name, sort, version_number')
         type = int(type)
+        data_name = eval(name)
         try:
             with transaction.atomic():
-                app_bundle_qs = AppBundle.objects.filter(id__in=app_bundle_id,
-                                                         app_device_type__devicenamelanguage__lang=lang,
-                                                         app_device_type__app_version_number_id=version_number,
-                                                         app_device_type__type=type,
-                                                         app_device_type__model=model)
-                #  数据是否重复
-                if app_bundle_qs.exists():
-                    return response.json(174)
-                # 是否存在相同的url
-                response_url = 'https://ansjerfilemanager.s3.amazonaws.com/app/device_type_images/' + format(fileName)
-                app_bundle_qs = AppDeviceType.objects.filter(appbundle__id__in=app_bundle_id, type=type, model=model)
-                if not app_bundle_qs.exists():
-                    #  上传设备图标至存储桶
-                    bucket_name = 'ansjerfilemanager'
-                    file_key = 'app/device_type_images/{}'.format(fileName)
-                    s3 = AmazonS3Util(AWS_ACCESS_KEY_ID[1], AWS_SECRET_ACCESS_KEY[1], AWS_SES_ACCESS_REGION)
-                    # 地址:https://ansjerfilemanager.s3.amazonaws.com/app/device_type_images/camera_c190.png
-                    s3.upload_file_obj(
-                        bucket_name,
-                        file_key,
-                        file,
-                        {'ContentType': file.content_type, 'ACL': 'public-read'})
+                for k, v in data_name.items():
+                    app_bundle_qs = AppBundle.objects.filter(id__in=app_bundle_id,
+                                                             app_device_type__devicenamelanguage__lang=k,
+                                                             app_device_type__app_version_number_id=version_number,
+                                                             app_device_type__type=type,
+                                                             app_device_type__model=model)
+                    #  数据是否重复
+                    if app_bundle_qs.exists():
+                        return response.json(174)
+                    # 是否存在相同的url
+                    response_url = 'https://ansjerfilemanager.s3.amazonaws.com/app/device_type_images/' + format(
+                        fileName)
+                    app_bundle_qs = AppDeviceType.objects.filter(appbundle__id__in=app_bundle_id, type=type,
+                                                                 model=model, icon=response_url)
+                    if not app_bundle_qs.exists():
+                        # 上传设备图标至存储桶
+                        bucket_name = 'ansjerfilemanager'
+                        file_key = 'app/device_type_images/{}'.format(fileName)
+                        s3 = AmazonS3Util(AWS_ACCESS_KEY_ID[1], AWS_SECRET_ACCESS_KEY[1], AWS_SES_ACCESS_REGION)
+                        # 地址:https://ansjerfilemanager.s3.amazonaws.com/app/device_type_images/camera_c190.png
+                        s3.upload_file_obj(
+                            bucket_name,
+                            file_key,
+                            file,
+                            {'ContentType': file.content_type, 'ACL': 'public-read'})
                 #  创建
-                for app_id in app_bundle_id:
-                    app_bundle_qs = AppBundle.objects.filter(id=app_id).values('id')
-                    app_device_type_qs = AppDeviceType.objects.create(model=model, type=type, icon=response_url,
-                                                                      app_version_number_id=version_number)
-                    DeviceNameLanguage.objects.create(lang=lang, name=name, sort=sort,
-                                                      app_device_type_id=app_device_type_qs.id)
-                    #  关联app包
-                    app_device_type_qs.appbundle_set.add(app_bundle_qs[0]['id'])
+                for k, v in data_name.items():
+                    for app_id in app_bundle_id:
+                        app_bundle_qs = AppBundle.objects.filter(id=app_id).values('id')
+                        app_device_type_qs = AppDeviceType.objects.create(model=model, type=type, icon=response_url,
+                                                                          app_version_number_id=version_number)
+                        DeviceNameLanguage.objects.create(lang=k, name=v, sort=sort,
+                                                          app_device_type_id=app_device_type_qs.id)
+                        #  关联app包
+                        app_device_type_qs.appbundle_set.add(app_bundle_qs[0]['id'])
                 return response.json(0)
         except Exception as e:
             print(e)
@@ -690,43 +700,22 @@ class DeviceManagement(View):
         if not all([lang, app_bundle_id, version_number]):
             return response.json(444)
         try:
-            version_number = list(map(int, version_number.split('.')))
+            # 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')
             #  判断版本是否存在, 不存在则获取输入版本范围内最接近的输入版本
             version_number_list = []
             app_bundle_list = []
-            id_list = []
             for version in app_bundle_qs:
-                version = version['app_device_type__app_version_number_id']
-                # 必须是版本号
-                if len(version) > 3:
-                    version_parts = list(map(int, version.split('.')))
-                    if version_parts <= version_number:
-                        version_number_list.append(version)
-                else:
-                    id_list.append(int(version))
-            # app_device_type__app_version_number_id为AppVersionNumber的主键时
-            version_list = []
-            if len(version_number_list) == 0:
-                version_qs = AppVersionNumber.objects.filter(
-                    id__in=id_list).values('version_number').distinct()
-                for version in version_qs:
-                    version_qs = AppVersionNumber.objects.filter(version_number=version['version_number'],
-                                                                 app_bundle__app_bundle_id=app_bundle_id).values('id')
-                    if not version_qs.exists():
-                        continue
-                    version_number_data = {
-                        version_qs[0]['id']: version['version_number']
-                    }
-                    version_list.append(version_number_data)
-                for version in version_list:
-                    for k, v in version.items():
-                        version_parts = list(map(int, v.split('.')))
-                        if version_parts <= version_number:
-                            version_number_list.append(k)
+                version_number_list.append(version['app_device_type__app_version_number_id'])
+            new_version_number = CommonService.compare_version_number(version_number, version_number_list)
+            app_device_qs = DeviceNameLanguage.objects.filter(lang=lang)
+            if not app_device_qs.exists():
+                lang = 'en'
             # 版本号对应的设备信息图标
-            for version_number in version_number_list:
+            for version_number in new_version_number:
                 app_bundle_qs = AppBundle.objects.filter(app_bundle_id=app_bundle_id,
                                                          app_device_type__devicenamelanguage__lang=lang,
                                                          app_device_type__app_version_number_id=version_number). \
@@ -738,20 +727,14 @@ class DeviceManagement(View):
                                                                                               'name', 'sort',
                                                                                               'app_device_type__app_version_number_id')
                 for app_bundle in app_bundle_qs:
-                    device_type = any(item['type'] == app_bundle['type'] for item in app_bundle_list)
-                    if device_type:
-                        break
-                    else:
-                        app_bundle_list.append({
-                            'model': app_bundle['model'],
-                            'type': app_bundle['type'],
-                            'icon': app_bundle['icon'],
-                            'name': app_bundle['name'],
-                            'sort': app_bundle['sort'],
-                            'app_device_type__app_version_number_id': app_bundle[
-                                'app_device_type__app_version_number_id'],
-                        })
-            # 去重
+                    app_bundle_list.append({
+                        'model': app_bundle['model'],
+                        'type': app_bundle['type'],
+                        'icon': app_bundle['icon'],
+                        'name': app_bundle['name'],
+                        'sort': app_bundle['sort'],
+                        'app_device_type__app_version_number_id': app_bundle['app_device_type__app_version_number_id'],
+                    })
             dvr_list = [app_bundle for app_bundle in app_bundle_list if app_bundle['model'] == 1]
             ipc_list = [app_bundle for app_bundle in app_bundle_list if app_bundle['model'] == 2]
             res = {

+ 353 - 0
AdminController/IcloudManagementController.py

@@ -0,0 +1,353 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+import time
+
+from django.db.models import F, Q, Sum
+from django.views.generic.base import View
+
+from Model.models import Lang, ICloudStoreMeal, AiService, Order_Model, Device_User, CountryModel, UidSetModel, \
+    Device_Info, VodBucketModel, IcloudUseDetails, IcloudService, IcloudStorageRecord
+from Object.AWS.AmazonS3Util import AmazonS3Util
+from Object.ResponseObject import ResponseObject
+from Object.TokenObject import TokenObject
+from Service.CommonService import CommonService
+from Ansjer.config import ACCESS_KEY_ID, SECRET_ACCESS_KEY, REGION_NAME, SERVER_DOMAIN, AWS_ACCESS_KEY_ID, \
+    AWS_SECRET_ACCESS_KEY, SERVER_DOMAIN_SSL, OAUTH_ACCESS_TOKEN_SECRET
+
+
+class IcloudServeView(View):
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.GET, request, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.POST, request, operation)
+
+    def validation(self, request_dict, request, operation):
+        language = request_dict.get('language', 'en')
+        response = ResponseObject(language, 'pc')
+        if operation == 'xxx':  # 不认证token接口
+            pass
+        else:
+            tko = TokenObject(
+                request.META.get('HTTP_AUTHORIZATION'),
+                returntpye='pc')
+            if tko.code != 0:
+                return response.json(tko.code)
+            response.lang = tko.lang
+            user_id = tko.userID
+            # icloud套餐信息相关
+            if operation == 'getIcloudStoreMealList':
+                return self.get_icloud_store_meal_list(request_dict, response)
+            elif operation == 'addOrEditIcloudStoreMeal':
+                return self.add_or_edit_icloud_store_meal(request_dict, response)
+            elif operation == 'getBucket':
+                return self.get_bucket(request_dict, response)
+            elif operation == 'deleteMeal':
+                return self.delete_meal(request_dict, response)
+            # icloud套餐语言相关
+            elif operation == 'getMealLang':
+                return self.get_meal_lang(request_dict, response)
+            elif operation == 'addOrEditLang':
+                return self.add_or_edit_lang(request_dict, response)
+            elif operation == 'deleteLang':
+                return self.delete_lang(request_dict, response)
+            # 用户云盘信息
+            elif operation == 'getUserIcloudInfo':
+                return self.get_user_icloud_info(request_dict, response)
+            elif operation == 'resetIcloud':
+                return self.reset_icloud(request_dict, response)
+            # 云盘订单信息
+            elif operation == 'getIcloudOrder':
+                return self.get_icloud_order(request_dict, response)
+            else:
+                return response.json(404)
+
+    @staticmethod
+    def get_icloud_store_meal_list(request_dict, response):
+        is_select = request_dict.get('isSelect', None)
+        page = request_dict.get('pageNo', None)
+        line = request_dict.get('pageSize', None)
+        if is_select:
+            # 获取套餐ID作为选项
+            icloud_meal_qs = ICloudStoreMeal.objects.filter().values('id')
+            return response.json(0, {'list': CommonService.qs_to_list(icloud_meal_qs)})
+        if not all([page, line]):
+            return response.json(444)
+        page = int(page)
+        line = int(line)
+        try:
+            icloud_meal_qs = ICloudStoreMeal.objects.values()
+            total = icloud_meal_qs.count()
+            icloud_meals = icloud_meal_qs[(page - 1) * line:page * line]
+            icloud_meal_list = []
+            for icloud_meal in icloud_meals:
+                # 获取支付方式列表
+                pay_type_list = list(
+                    ICloudStoreMeal.objects.filter(id=icloud_meal['id']).values('pay_type__id', 'pay_type__payment'))
+                # 获取存储桶信息
+                vod_bucket_qs = VodBucketModel.objects.filter(id=icloud_meal['bucket_id']).values('bucket')
+                if not vod_bucket_qs.exists():
+                    return response.json(173)
+                # 组织响应数据
+                icloud_meal_list.append({
+                    'IcloudMealID': icloud_meal['id'],
+                    'price': icloud_meal['price'],
+                    'symbol': icloud_meal['symbol'],
+                    'currency': icloud_meal['currency'],
+                    'is_show': icloud_meal['is_show'],
+                    'is_delete': icloud_meal['is_delete'],
+                    'expire': icloud_meal['expire'],
+                    'pay_type': pay_type_list,
+                    'size': icloud_meal['size'],
+                    'bucket': vod_bucket_qs[0]['bucket'],
+                    'addTime': icloud_meal['add_time'].strftime("%Y-%m-%d %H:%M:%S"),
+                    'updTime': icloud_meal['update_time'].strftime("%Y-%m-%d %H:%M:%S"),
+                })
+            return response.json(0, {'list': icloud_meal_list, 'total': total})
+        except Exception as e:
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
+    @staticmethod
+    def add_or_edit_icloud_store_meal(request_dict, response):
+        # 添加/编辑套餐
+        meal_id = request_dict.get('IcloudMealID', None)
+        expire = int(request_dict.get('expire', None))
+        price = request_dict.get('price', None)
+        currency = request_dict.get('currency', None)
+        symbol = request_dict.get('symbol', None)
+        pay_type = request_dict.get('pay_type', None)
+        is_show = int(request_dict.get('is_show', 1))
+        is_delete = int(request_dict.get('is_delete', 0))
+        size = float(request_dict.get('size', None))
+        is_edit = request_dict.get('isEdit', None)
+        bucket_id = request_dict.get('bucket_id', None)
+
+        if not all([expire, price, currency, symbol, pay_type, size, bucket_id]):
+            return response.json(444)
+        pay_type = pay_type.split(',')
+        try:
+            icloud_store_meal_data = {
+                'expire': expire,
+                'price': price,
+                'currency': currency,
+                'symbol': symbol,
+                'is_show': is_show,
+                'size': size,
+                'is_delete': is_delete,
+                'bucket_id': bucket_id
+            }
+            if is_edit:
+                if not meal_id:
+                    return response.json(444)
+                ICloudStoreMeal.objects.filter(id=meal_id).update(**icloud_store_meal_data)
+                ICloudStoreMeal.objects.get(id=meal_id).pay_type.set(pay_type)
+            else:
+                icloud_meal_qs = ICloudStoreMeal.objects.create(**icloud_store_meal_data)
+                icloud_meal_qs.pay_type.set(pay_type)
+            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)))
+
+    @staticmethod
+    def get_bucket(request_dict, response):
+        try:
+            bucket_qs = VodBucketModel.objects.all().values('id', 'bucket')
+            return response.json(0, list(bucket_qs))
+        except Exception as e:
+            print(e)
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
+    @staticmethod
+    def delete_meal(request_dict, response):
+        meal_id = request_dict.get('meal_id', None)
+        status = request_dict.get('status', None)
+        if not meal_id:
+            return response.json(444)
+        ICloudStoreMeal.objects.filter(id=meal_id).update(is_delete=status)
+        return response.json(0)
+
+    @staticmethod
+    def get_meal_lang(request_dict, response):
+        is_select = request_dict.get('isSelect', None)
+        meal_id = request_dict.get('mealId', None)
+        page = request_dict.get('pageNo', None)
+        line = request_dict.get('pageSize', None)
+        if not all([page, line]):
+            return response.json(444)
+        lang = Lang.objects.filter(type=3)
+        page = int(page)
+        line = int(line)
+        total = lang.count()
+        if is_select:
+            lang = ICloudStoreMeal.objects.values('id', 'lang__title')
+        else:
+            if meal_id:
+                lang = lang.filter(icloudstoremeal__id=meal_id).values('icloudstoremeal__id', 'id', 'lang', 'title',
+                                                                       'content')
+                total = lang.count()
+            else:
+                lang = lang.values('icloudstoremeal__id', 'id', 'lang', 'title', 'content')[
+                       (page - 1) * line:page * line]
+        return response.json(0, {'langList': list(lang), 'total': total})
+
+    @staticmethod
+    def add_or_edit_lang(request_dict, response):
+        lang_id = request_dict.get('lang_id', None)
+        meal_id = request_dict.get('meal_id', None)
+        lang = request_dict.get('lang', 'en')
+        title = request_dict.get('title', None)
+        content = request_dict.get('content', None)
+        try:
+            icloud_meal_qs = ICloudStoreMeal.objects.get(id=meal_id)
+            if not icloud_meal_qs:
+                return response.json(173)
+            if lang_id:
+                Lang.objects.filter(id=lang_id).update(lang=lang, title=title, content=content)
+            else:
+                lang_qs = Lang.objects.filter(lang=lang, title=title, content=content, type=3)
+                if not lang_qs.exists():
+                    Lang.objects.create(lang=lang, title=title, content=content, type=3)
+                    lang_qs = Lang.objects.filter(lang=lang, title=title, content=content, type=3)
+                icloud_meal_qs.lang.add(*lang_qs)
+            return response.json(0)
+        except Exception as e:
+            return response.json(500)
+
+    @staticmethod
+    def delete_lang(request_dict, response):
+        lang_id = request_dict.get('lang_id', None)
+        meal_id = request_dict.get('meal_id', None)
+        if not all([lang_id, meal_id]):
+            return response.json(444)
+        try:
+            lang = Lang.objects.filter(id=lang_id)
+            icloud_meal_qs = ICloudStoreMeal.objects.get(id=meal_id)
+            icloud_meal_qs.lang.remove(*lang)
+            lang.delete()
+            return response.json(0)
+        except Exception as e:
+            return response.json(500)
+
+    @staticmethod
+    def get_user_icloud_info(request_dict, response):
+        user_id = request_dict.get('user_id', None)
+        page = request_dict.get('pageNo', None)
+        line = request_dict.get('pageSize', None)
+        if not all([page, line]):
+            return response.json(444)
+        now_time = int(time.time())
+        page = int(page)
+        line = int(line)
+        try:
+            icloud_user_qs = IcloudUseDetails.objects.all()
+            if user_id:
+                icloud_user_qs = icloud_user_qs.filter(user_id=user_id)
+            icloud_user_qs = icloud_user_qs.values('use_size', 'user_id', 'detect_status', 'bucket_id',
+                                                   'id')
+            total = icloud_user_qs.count()
+            icloud_user_qs = icloud_user_qs[(page - 1) * line:page * line]
+            for item in icloud_user_qs:
+                use_details_id = item['id']
+                user_id = item['user_id']
+                bucket_id = item['bucket_id']
+                user_qs = Device_User.objects.filter(userID=user_id).values('username')
+                item['username'] = user_qs[0]['username']
+                bucket_qs = VodBucketModel.objects.filter(id=bucket_id).values('bucket')
+                item['bucket_name'] = bucket_qs[0]['bucket']
+                all_size = IcloudService.objects.filter(Q(use_details_id=use_details_id), Q(use_status=0),
+                                                        Q(end_time__gt=now_time) | Q(end_time=0)).values(
+                    'size').aggregate(total_size=Sum('size'))['total_size']
+                item['all_size'] = float(all_size * 1024) if all_size else 0  # 转换单位为MB
+
+            return response.json(0, {'list': list(icloud_user_qs), 'total': total})
+        except Exception as e:
+            return response.json(500)
+
+    @staticmethod
+    def reset_icloud(request_dict, response):
+        use_details_id = request_dict.get('id', None)
+        if not all([use_details_id]):
+            return response.json(444)
+        try:
+            icloud_use_qs = IcloudUseDetails.objects.filter(id=use_details_id).values('user_id', 'bucket_id')
+            user_id = icloud_use_qs[0]['user_id']
+            bucket_id = icloud_use_qs[0]['bucket_id']
+            bucket_qs = VodBucketModel.objects.filter(id=bucket_id).values('bucket', 'region', 'mold')
+            if not bucket_qs.exists():
+                return response.json(173)
+            bucket_name = bucket_qs[0]['bucket']
+            bucket_region = bucket_qs[0]['region']
+            mold = bucket_qs[0]['mold']
+            s3_obj = AmazonS3Util(
+                AWS_ACCESS_KEY_ID[mold],
+                AWS_SECRET_ACCESS_KEY[mold],
+                bucket_region
+            )
+            object_list = s3_obj.get_object_list(bucket_name, user_id)
+            for obj in object_list:
+                s3_obj.delete_obj(bucket_name, obj['Key'])
+            IcloudStorageRecord.objects.filter(user_id=user_id).delete()
+            icloud_use_qs.update(use_size=0)
+            return response.json(0)
+        except Exception as e:
+            return response.json(500)
+
+    @staticmethod
+    def get_icloud_order(request_dict, response):
+        page = request_dict.get('pageNo', None)
+        line = request_dict.get('pageSize', None)
+        order_id = request_dict.get('order_id', None)
+        username = request_dict.get('username', None)
+        pay_type = request_dict.get('pay_type', None)
+        status = request_dict.get('status', None)
+        time_range = request_dict.get('time_range', None)
+        trade_no = request_dict.get('trade_no', None)
+        if not all([page, line]):
+            return response.json(444)
+        page = int(page)
+        line = int(line)
+        try:
+            order_qs = Order_Model.objects.filter(order_type=4)
+            if order_id:
+                order_qs = order_qs.filter(orderID=order_id)
+            if username:
+                order_qs = order_qs.filter(userID__username=username)
+            if pay_type:
+                order_qs = order_qs.filter(payType=pay_type)
+            if status:
+                order_qs = order_qs.filter(status=status)
+            if time_range:
+                start_time, end_time = time_range.split(',')
+                order_qs = order_qs.filter(addTime__gte=start_time, addTime__lte=end_time)
+            if trade_no:
+                order_qs = order_qs.filter(trade_no=trade_no)
+            count = order_qs.count()
+            order_qs = order_qs.values('orderID', 'trade_no', 'userID__username', 'price', 'status', 'payType', 'desc',
+                                       'unify_combo_id', 'paypal', 'refunded_amount', 'addTime', 'updTime')[
+                       (page - 1) * line:page * line]
+            order_list = []
+            for item in order_qs:
+                icloud_dict = {
+                    'order_id': item['orderID'],
+                    'trade_no': item['trade_no'],
+                    'username': item['userID__username'],
+                    'price': item['price'],
+                    'status': item['status'],
+                    'pay_type': item['payType'],
+                    'refunded_amount': item['refunded_amount'],
+                    'add_time': item['addTime'],
+                    'upd_time': item['updTime'],
+                }
+                icloud_meal_qs = ICloudStoreMeal.objects.filter(id=item['unify_combo_id']).values('expire', 'size')
+                icloud_dict['expire'] = icloud_meal_qs[0]['expire'] if icloud_meal_qs.exists() else ''
+                icloud_dict['size'] = icloud_meal_qs[0]['size'] if icloud_meal_qs.exists() else ''
+                icloud_dict['paypal'] = item['paypal'] if item['paypal'] else ''
+                order_list.append(icloud_dict)
+            return response.json(0, {'list': order_list, 'total': count})
+        except Exception as e:
+            return response.json(500)

+ 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)))

+ 5 - 5
AdminController/SerialManageController.py

@@ -128,7 +128,7 @@ class SerialView(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 company_page(cls, request_dict, response):
@@ -155,7 +155,7 @@ class SerialView(View):
             return response.json(0, {'list': list(company_page), '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)))
 
     @classmethod
     def serial_page(cls, request_dict, response):
@@ -187,7 +187,7 @@ class SerialView(View):
             return response.json(0, {'list': list(serial_number_page), '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)))
 
     @classmethod
     def vpg_page(cls, request_dict, response):
@@ -228,7 +228,7 @@ class SerialView(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 uid_page(cls, request_dict, response):
@@ -299,4 +299,4 @@ class SerialView(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)))

+ 8 - 8
AdminController/ServeManagementController.py

@@ -761,20 +761,20 @@ class serveManagement(View):
                     'country': country
                 }
                 #  订单显示(或不显示)停用/退款功能
-                if order['order_type'] == 0 or order['order_type'] == 1:  # 云存
+                if order['order_type'] == 0:  # 云存
                     uid_bucket = UID_Bucket.objects.filter(uid=order['UID']).values('use_status')
                     user_status = uid_bucket[0]['use_status'] if uid_bucket.exists() else ''
                     if user_status != '':
                         data['user_status'] = user_status
                     else:
                         data['user_status'] = 2
-                # elif order['order_type'] == 1:  # ai
-                #     ai_service_qs = AiService.objects.filter(
-                #         Q(orders_id=order['orderID']) & ~Q(use_status=2))
-                #     if ai_service_qs.exists():
-                #         data['user_status'] = 1
-                #     else:
-                #         data['user_status'] = 2
+                elif order['order_type'] == 1:  # ai
+                    ai_service_qs = AiService.objects.filter(
+                        Q(orders_id=order['orderID']) & ~Q(use_status=2))
+                    if ai_service_qs.exists():
+                        data['user_status'] = 1
+                    else:
+                        data['user_status'] = 2
                 elif order['order_type'] == 2:  # 联通4G
                     unicom_combor_order_qs = UnicomComboOrderInfo.objects.filter(
                         Q(order_id=order['orderID']) & ~Q(status=2))

+ 5 - 5
AdminController/SurveysManageController.py

@@ -93,7 +93,7 @@ class SurveysView(View):
             return response.json(0, {'list': result_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)))
 
     @classmethod
     def save(cls, request_dict, response):
@@ -116,7 +116,7 @@ class SurveysView(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 edit(cls, request_dict, response):
@@ -160,7 +160,7 @@ class SurveysView(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_title_list(cls, request_dict, response):
@@ -262,7 +262,7 @@ class SurveysView(View):
             return response.json(0, {'list': result_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)))
 
     ''' 云存用户问卷调查统计 '''
 
@@ -315,4 +315,4 @@ class SurveysView(View):
                                      'unreadCount': unreadCount})
         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)))

+ 1 - 0
AdminController/UnicomManageController.py

@@ -761,6 +761,7 @@ class UnicomManageControllerView(View):
         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):

+ 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)))

+ 2 - 2
AdminController/dataSystemManagement/BusinessDataController.py

@@ -72,7 +72,7 @@ class BusinessDataView(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_device_vod_business(cls, request, request_dict, response):
@@ -111,4 +111,4 @@ class BusinessDataView(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)))

+ 4 - 4
AdminController/dataSystemManagement/DeviceDataController.py

@@ -147,7 +147,7 @@ class DeviceDataView(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)))
 
     @classmethod
     def golbal_active(cls, request, request_dict, response):
@@ -206,7 +206,7 @@ class DeviceDataView(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)))
 
     @classmethod
     def golbal_type(cls, request, request_dict, response):
@@ -309,7 +309,7 @@ class DeviceDataView(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 device_active(cls, request_dict, response):
@@ -467,7 +467,7 @@ class DeviceDataView(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)))
 
     @classmethod
     def regional_statistics(cls, response):

+ 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)))

+ 6 - 6
AdminController/dataSystemManagement/UserDataController.py

@@ -110,7 +110,7 @@ class UserDataView(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 user_active(cls, request_dict, response):
@@ -173,7 +173,7 @@ class UserDataView(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 user_region(cls, response):
@@ -226,7 +226,7 @@ class UserDataView(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 global_user_increase(cls, request, request_dict, response):
@@ -283,7 +283,7 @@ class UserDataView(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 global_user_active(cls, request, request_dict, response):
@@ -341,7 +341,7 @@ class UserDataView(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 global_user_region(cls, request, response):
@@ -397,4 +397,4 @@ class UserDataView(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)))

+ 13 - 0
Ansjer/Config/gatewaySensorConfig.py

@@ -8,6 +8,19 @@
 # MQTT主题名
 SMART_SCENE_TOPIC = 'loocam/gateway_sensor/smart_scene/{}'
 GET_SCENE_TOPIC = 'loocam/gateway_sensor/get_scene/{}'
+SUB_DEVICE_TOPIC = 'loocam/gateway_sensor/sub_device/{}'
+VOICE_AUDITION_TOPIC = 'loocam/gateway_sensor/voice_audition/{}'
+
+# 智能场景事件
+SCENE_EVENT_CREATE = 1
+SCENE_EVENT_EDIT = 2
+SCENE_EVENT_DELETE = 3
+SCENE_EVENT_EDIT_STATUS = 4
+SCENE_EVENT_SOS = 5
+
+# 智能场景状态
+SCENE_STATUS_ON = 1
+SCENE_STATUS_OFF = 0
 
 # 传感器类型
 SENSOR_TYPE = {

+ 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,

+ 13 - 0
Ansjer/server_urls/icloud_url.py

@@ -0,0 +1,13 @@
+# -*- coding: utf-8 -*-
+"""
+@Author : Rocky
+@Time : 2022/10/18 10:23
+@File :kvs_url.py
+"""
+from django.urls import re_path
+from Controller.IcloudService import IcloudMeal, IcloudService
+
+urlpatterns = [
+    re_path(r'^meal/(?P<operation>.*)$', IcloudMeal.IcloudMeal.as_view()),
+    re_path(r'^service/(?P<operation>.*)$', IcloudService.IcloudServiceView.as_view()),
+]

+ 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)))

+ 5 - 4
Controller/AdminManage.py

@@ -98,14 +98,15 @@ class AdminManage(TemplateView):
         if not own_permission:
             return response.json(404)
         duserID = request_dict.get('duserID', None)
-        userPwd = request_dict.get('userPwd', None)
+        userPwd = request_dict.get('userPwd', '123456')
+        password_version = request_dict.get('pwdVersion', 'V1')
         if not duserID:
             return response.json(444, 'duserID')
         UserValid = Device_User.objects.filter(userID=duserID)
         if UserValid:
-            if userPwd is None:
-                userPwd = '123456'
-            is_update = UserValid.update(password=make_password(userPwd))
+            if password_version == 'V1':
+                userPwd = make_password(userPwd)
+            is_update = UserValid.update(password=userPwd)
             if is_update:
                 return response.json(0)
             else:

+ 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):

+ 1 - 1
Controller/AppLogController.py

@@ -154,7 +154,7 @@ class AppLogView(View):
                     AppLogModel.objects.filter(id=id).delete()
                 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)
             else:

+ 2 - 2
Controller/CDKController.py

@@ -123,7 +123,7 @@ class CDKView(View):
         try:
             CDKcontextModel.objects.get(cdk=cdk_id).delete()
         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:
             page = int(request_dict.get('page', None))
             line = int(request_dict.get('line', None))
@@ -185,7 +185,7 @@ class CDKView(View):
                         update_dict['rank'] = rank
                     CDKcontextModel.objects.filter(id=cdk_id).update(**update_dict)
         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)
 

+ 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):

+ 4 - 3
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
@@ -181,6 +181,7 @@ class DetectControllerView(View):
 
     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', '')
         appBundleId = request_dict.get('appBundleId', None)
         app_type = request_dict.get('app_type', None)
         push_type = request_dict.get('push_type', None)
@@ -271,6 +272,7 @@ class DetectControllerView(View):
                         'app_type': app_type,
                         'push_type': push_type,
                         'token_val': token_val,
+                        'jg_token_val': jg_token_val,
                         'updTime': nowTime,
                         'lang': lang,
                         'tz': tz
@@ -285,6 +287,7 @@ class DetectControllerView(View):
                         'app_type': app_type,
                         'push_type': push_type,
                         'token_val': token_val,
+                        'jg_token_val': jg_token_val,
                         'm_code': m_code,
                         'addTime': nowTime,
                         'updTime': nowTime,
@@ -293,8 +296,6 @@ class DetectControllerView(View):
                     }
                     # 绑定设备推送
                     UidPushModel.objects.create(**uid_push_create_dict)
-                if appBundleId == 0 or appBundleId == '0':
-                    LOGGER.info('detect/changeStatus接口推送数据:{}'.format(request_dict))
                 if interval:
                     self.do_delete_redis(uid, int(interval))
                 else:

+ 47 - 17
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,13 +58,43 @@ 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', '')
         appBundleId = request_dict.get('appBundleId', None)
         app_type = request_dict.get('app_type', None)
         push_type = request_dict.get('push_type', None)
@@ -113,7 +143,6 @@ class DetectControllerViewV2(View):
             uid_set_data = {
                 'device_type': device_info_qs[0].Type
             }
-
             # 设置开关状态,0:关闭,1:开启
             if status:
                 status = int(status)
@@ -123,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)
@@ -141,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)
@@ -167,6 +197,7 @@ class DetectControllerViewV2(View):
                             'app_type': app_type,
                             'push_type': push_type,
                             'token_val': token_val,
+                            'jg_token_val': jg_token_val,
                             'updTime': nowTime,
                             'lang': lang,
                             'tz': tz
@@ -180,6 +211,7 @@ class DetectControllerViewV2(View):
                             'app_type': app_type,
                             'push_type': push_type,
                             'token_val': token_val,
+                            'jg_token_val': jg_token_val,
                             'm_code': m_code,
                             'addTime': nowTime,
                             'updTime': nowTime,
@@ -188,8 +220,6 @@ class DetectControllerViewV2(View):
                         }
                         # 绑定设备推送
                         UidPushModel.objects.create(**uid_push_create_dict)
-                if appBundleId == 0 or appBundleId == '0':
-                    LOGGER.info('detectV2/changeStatus接口推送数据:{}'.format(request_dict))
                 return response.json(0)
 
             if status == 0:
@@ -205,6 +235,7 @@ class DetectControllerViewV2(View):
                             'app_type': app_type,
                             'push_type': push_type,
                             'token_val': token_val,
+                            'jg_token_val': jg_token_val,
                             'updTime': nowTime,
                             'lang': lang,
                             'tz': tz
@@ -218,6 +249,7 @@ class DetectControllerViewV2(View):
                             'app_type': app_type,
                             'push_type': push_type,
                             'token_val': token_val,
+                            'jg_token_val': jg_token_val,
                             'm_code': m_code,
                             'addTime': nowTime,
                             'updTime': nowTime,
@@ -226,8 +258,6 @@ class DetectControllerViewV2(View):
                         }
                         # 绑定设备推送
                         UidPushModel.objects.create(**uid_push_create_dict)
-                if appBundleId == 0 or appBundleId == '0':
-                    LOGGER.info('detectV2/changeStatus接口推送数据:{}'.format(request_dict))
                 if interval:
                     self.do_delete_redis(uid, interval)
                 else:
@@ -252,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)

+ 1 - 1
Controller/DeviceDebug.py

@@ -100,4 +100,4 @@ class DeviceDebug(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)))

+ 2 - 2
Controller/DeviceLogController.py

@@ -76,7 +76,7 @@ class DeviceLogView(View):
             return response.json(0, {'put_url_list': put_url_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 uploaded(self, request, request_dict, response):
         uid = request_dict.get('uid', None)
@@ -102,4 +102,4 @@ class DeviceLogView(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)))

+ 1 - 1
Controller/DeviceShare.py

@@ -207,7 +207,7 @@ class DeviceShareView(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)))
 
     # 1,这个用户的分享出去的设备
     # 2,获得上面个的设备拥有者

+ 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']
         }
 
         # 调试

+ 27 - 8
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
@@ -120,6 +119,7 @@ class EquipmentManagerV3(View):
         app_type = request_dict.get('app_type', None)
         push_type = request_dict.get('push_type', None)
         token_val = request_dict.get('token_val', None)
+        jg_token_val = request_dict.get('jg_token_val', '')
         lang = request_dict.get('lang', 'en')
         tz = request_dict.get('tz', '0')
 
@@ -252,6 +252,7 @@ class EquipmentManagerV3(View):
                         'app_type': app_type,
                         'push_type': push_type,
                         'token_val': token_val,
+                        'jg_token_val': jg_token_val,
                         'updTime': nowTime,
                         'lang': lang,
                         'tz': tz
@@ -265,6 +266,7 @@ class EquipmentManagerV3(View):
                         'app_type': app_type,
                         'push_type': push_type,
                         'token_val': token_val,
+                        'jg_token_val': jg_token_val,
                         'm_code': m_code,
                         'addTime': nowTime,
                         'updTime': nowTime,
@@ -273,8 +275,6 @@ class EquipmentManagerV3(View):
                     }
                     # 绑定设备推送
                     UidPushModel.objects.create(**uid_push_create_dict)
-                if appBundleId == 0 or appBundleId == '0':
-                    LOGGER.info('v3/equipment/add接口推送数据:{}'.format(request_dict))
             # 查询uid_channel表有无该uid的数据
             uid_channel_set = UidChannelSetModel.objects.filter(uid_id=UidSet_id)
             if not uid_channel_set.exists():
@@ -741,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']:  # 存在序列号根据序列号查询
@@ -777,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:
@@ -786,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):
         """
@@ -957,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):
@@ -1082,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)))

+ 609 - 0
Controller/IcloudService/IcloudMeal.py

@@ -0,0 +1,609 @@
+# -*- coding: utf-8 -*-
+"""
+@Author : peng
+@Time : 2023-6-7 18:26:35
+@File :IcloudMeal.py
+"""
+from Ansjer.config import LOGGER
+import time
+from urllib.parse import quote, parse_qs, unquote
+
+import paypalrestsdk
+from django.db import transaction, connection
+from django.db.models import Q, Sum
+from django.http import HttpResponse, HttpResponseRedirect
+from django.views import View
+
+from Model.models import Device_User, ICloudStoreMeal, Order_Model, IcloudUseDetails, IcloudService, Pay_Type
+from Object.AliPayObject import AliPayObject
+from Object.RedisObject import RedisObject
+from Object.ResponseObject import ResponseObject
+from Object.TokenObject import TokenObject
+from Ansjer.config import ACCESS_KEY_ID, SECRET_ACCESS_KEY, REGION_NAME, SERVER_DOMAIN, PAYPAL_CRD, SERVER_DOMAIN_SSL
+from Object.WechatPayObject import WechatPayObject
+from Service.CommonService import CommonService
+from Controller.AiController import AiView
+
+
+class IcloudMeal(View):
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.GET, operation, request)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.POST, operation, request)
+
+    def validation(self, request_dict, operation, request):
+        response = ResponseObject()
+        if operation == 'doPayPalCallBack':  # paypal支付回调
+            return self.do_paypal_callback(request_dict, response)
+        elif operation == 'doAlipayCallBack':  # 支付宝支付回调
+            return self.do_alipay_callback(request_dict, response)
+        elif operation == 'doWechatCallBack':  # 微信支付回调
+            return self.do_wechat_callback(request, response)
+        else:
+            tko = TokenObject(request.META.get('HTTP_AUTHORIZATION'))
+            if tko.code != 0:
+                return response.json(tko.code)
+            response.lang = tko.lang
+            user_id = tko.userID
+            if operation == 'getMeal':  # 获取套餐
+                return self.get_meal(request_dict, response)
+            elif operation == 'createPayOrder':  # 购买订单
+                return self.create_pay_order(request_dict, request, user_id, response)
+            elif operation == 'getCloudDriveInit':  # 获取套餐明细
+                return self.get_cloud_drive_init(request_dict, response, user_id)
+            elif operation == 'getCapacity':  # 获取容量
+                return self.get_capacity(response, user_id)
+            elif operation == 'activateCloudDrive':  # 激活云盘
+                return self.activate_cloud_drive(request_dict, response, user_id)
+            else:
+                return response.json(414)
+
+    @staticmethod
+    def get_meal(request_dict, response):
+        """
+        获取套餐
+        @param request_dict: 请求参数
+        @request_dict lang: 语言
+        @param response: 响应对象
+        @return: response
+        """
+        lang = request_dict.get('lang', 'en')
+        # 隐藏的、删除的套餐不查
+        cloud_drive_qs = ICloudStoreMeal.objects.filter(Q(lang__lang=lang), Q(is_show=1), Q(is_delete=0)).values(
+            'id', 'currency', 'symbol', 'price', 'expire',
+            'pay_type',
+            'size', 'bucket_id', 'lang__title',
+            'lang__content', 'sort').order_by(
+            'sort')
+        try:
+            store_list = list(cloud_drive_qs)
+            for cloud_drive in store_list:
+                cloud_drive['title'] = cloud_drive.pop('lang__title')
+                cloud_drive['content'] = cloud_drive.pop('lang__content')
+                pay_type_qs = Pay_Type.objects.filter(id=cloud_drive['pay_type']).values("id", "payment")
+                cloud_drive['pay_type'] = list(pay_type_qs)
+            return response.json(0, store_list)
+        except Exception as e:
+            print(e)
+            return response.json(500)
+
+    @classmethod
+    def create_pay_order(cls, request_dict, request, user_id, response):
+        """
+        购买订单
+        @param request_dict: 请求参数
+        @param user_id: 用户id
+        @param request: 请求对象
+        @request_dict serial_number: 序列号
+        @param response: 响应对象
+        @return: response
+        """
+        pay_type = request_dict.get('pay_type', None)
+        rank = request_dict.get('rank', None)
+        lang = request_dict.get('lang', 'en')
+        if not all([pay_type, rank]):
+            return response.json(444, {'error param': 'rank, pay_type'})
+        user_qs = Device_User.objects.filter(userID=user_id)
+        if not user_qs.exists():
+            return response.json(173)
+        icloud_use_qs = IcloudUseDetails.objects.filter(user_id=user_id)
+        if not icloud_use_qs.exists():
+            return response.json(911)
+        meal_qs = ICloudStoreMeal.objects.filter(id=rank, is_show=1, is_delete=0, lang__lang=lang,
+                                                 pay_type=pay_type).values('lang__title', 'lang__content', 'currency',
+                                                                           'price', 'bucket_id')
+        if not meal_qs.exists():
+            return response.json(173)
+        # 查询中文套餐名
+        icloud_meal_qs = ICloudStoreMeal.objects.filter(id=rank, is_show=1, is_delete=0, lang__lang='cn').values(
+            'lang__title',
+            'lang__content')
+        if icloud_meal_qs.exists():
+            store_meal_name = icloud_meal_qs[0]['lang__title'] + '-' + icloud_meal_qs[0]['lang__content']
+        else:
+            store_meal_name = '未知套餐'
+        pay_type = int(pay_type)
+        title = meal_qs[0]['lang__title']
+        content = meal_qs[0]['lang__content']
+        currency = meal_qs[0]['currency']
+        price = meal_qs[0]['price']
+        bucket_id = meal_qs[0]['bucket_id']
+        now_time = int(time.time())
+        order_id = CommonService.createOrderID()
+        price = round(float(price), 2)
+        order_dict = {
+            'orderID': order_id,
+            'UID': '',
+            'userID_id': user_id,
+            'desc': content,
+            'payType': pay_type,
+            'payTime': now_time,
+            'price': price,
+            'currency': currency,
+            'addTime': now_time,
+            'updTime': now_time,
+            'ai_rank_id': 1,
+            'rank_id': 1,
+            'order_type': 4,
+            'store_meal_name': store_meal_name,
+            'unify_combo_id': rank,
+            'uid_bucket_id': bucket_id
+        }
+        try:
+            # 创建订单数据和返回支付回调链接
+            if pay_type == 1:  # PayPal支付
+                res_dict = cls.create_paypal_payment(lang, order_id, price, currency, content)
+                if not res_dict:
+                    return response.json(10, 'create icloud order failed')
+                order_dict['paymentID'], order_dict['pay_url'] = res_dict['payment_id'], res_dict['pay_url']
+                res_data = {'orderID': order_id, 'redirectUrl': order_dict['pay_url']}
+
+            elif pay_type == 2:  # 支付宝支付
+                res_dict = cls.create_alipay_payment(lang, order_id, price, title, content)
+                if not res_dict:
+                    return response.json(10, 'create icloud order failed')
+                order_dict['pay_url'] = res_dict['pay_url']
+                res_data = {'orderID': order_id, 'redirectUrl': order_dict['pay_url']}
+
+            elif pay_type == 3:  # 微信支付
+                ip = CommonService.get_ip_address(request)
+                res_dict = cls.create_wechat_payment(lang, order_id, price, ip, content)
+                if not res_dict:
+                    return response.json(10, 'create icloud order failed')
+                order_dict['pay_url'], sign_params = res_dict['pay_url'], res_dict['sign_params']
+                res_data = {'orderID': order_id, 'redirectUrl': order_dict['pay_url'], 'result': sign_params}
+            else:
+                return response.json(444, {'param': 'pay_type'})
+
+            Order_Model.objects.create(**order_dict)
+            return response.json(0, res_data)
+        except Exception as e:
+            LOGGER.info('云盘生成订单异常:{}'.format(repr(e)))
+            return response.json(500)
+
+    @classmethod
+    def do_paypal_callback(cls, request_dict, response):
+        """
+        paypal支付回调
+        @param request_dict: 请求数据
+        @request_dict paymentId: 支付id
+        @request_dict PayerID: 支付账号id
+        @request_dict orderID: 订单id
+        @request_dict lang: 语言
+        @param response: 响应
+        @return: response
+        """
+        LOGGER.info('云盘订单---paypal支付回调')
+        payment_id = request_dict.get('paymentId', None)
+        payer_id = request_dict.get('PayerID', None)
+        order_id = request_dict.get('orderID', None)
+        lang = request_dict.get('lang', 'en')
+
+        if not order_id:
+            pay_failed_url = CommonService.get_payment_status_url(lang, 'fail')
+            return HttpResponseRedirect(pay_failed_url)
+
+        # redis加锁,防止订单重复
+        redis_obj = RedisObject()
+        is_lock = redis_obj.CONN.setnx(order_id + 'creating_icloud_order', 1)
+        redis_obj.CONN.expire(order_id + 'creating_icloud_order', 60)
+        if not is_lock:
+            return response.json(5)
+
+        order_qs = Order_Model.objects.filter(orderID=order_id, status=0)
+        if not order_qs.exists():
+            return response.json(173)
+
+        try:
+            paypalrestsdk.configure(PAYPAL_CRD)
+            payment = paypalrestsdk.Payment.find(payment_id)
+            payer = payment.execute({'payer_id': payer_id})
+            if not payer:
+                pay_failed_url = CommonService.get_payment_status_url(lang, 'fail')
+                redis_obj.del_data(key=order_id + 'creating_icloud_order')
+                return HttpResponseRedirect(pay_failed_url)
+            return cls.payment_success(order_id, lang, order_qs, redis_obj)
+        except Exception as e:
+            LOGGER.info('云盘订单paypal支付回调异常:{}'.format(repr(e)))
+            order_qs.update(status=10)
+            pay_failed_url = CommonService.get_payment_status_url(lang, 'fail')
+            redis_obj.del_data(key=order_id + 'creating_icloud_order')
+            return HttpResponseRedirect(pay_failed_url)
+
+    @classmethod
+    def do_alipay_callback(cls, request_dict, response):
+        """
+        支付宝支付回调
+        @param request_dict: 请求数据
+        @param response: 响应
+        @return: response
+        """
+        LOGGER.info('云盘订单---支付宝支付回调')
+
+        data = request_dict.dict()
+        passback_params = data['passback_params']
+        params = dict([(k, v[0]) for k, v in parse_qs(unquote(passback_params)).items()])
+        lang = params['lang']
+        signature = data['sign']
+        data.pop('sign')
+        order_id = data['out_trade_no']
+
+        # redis加锁,防止订单重复
+        redis_obj = RedisObject()
+        is_lock = redis_obj.CONN.setnx(order_id + 'creating_icloud_order', 1)
+        redis_obj.CONN.expire(order_id + 'creating_icloud_order', 60)
+        if not is_lock:
+            return response.json(5)
+
+        order_qs = Order_Model.objects.filter(orderID=order_id, status=0)
+        if not order_qs.exists():
+            return response.json(173)
+
+        try:
+            alipay_obj = AliPayObject()
+            alipay = alipay_obj.conf()
+            success = alipay.verify(data, signature)
+            if not success or data['trade_status'] not in ('TRADE_SUCCESS', 'TRADE_FINISHED'):
+                return response.json(0, signature)
+            return cls.payment_success(order_id, lang, order_qs, redis_obj)
+        except Exception as e:
+            LOGGER.info('AI订单支付宝支付回调异常:{}'.format(repr(e)))
+            order_qs.update(status=10)
+            redis_obj.del_data(key=order_id + 'creating_icloud_order')
+            pay_failed_url = CommonService.get_payment_status_url(lang, 'fail')
+            redis_obj.del_data(key=order_id + 'creating_icloud_order')
+            return HttpResponseRedirect(pay_failed_url)
+
+    @classmethod
+    def do_wechat_callback(cls, request, response):
+        """
+        微信支付回调
+        @param request: 请求体
+        @param response: 响应
+        @return: response
+        """
+        LOGGER.info('云盘订单---微信支付回调')
+
+        pay = WechatPayObject()
+        data = pay.weixinpay_call_back(request.body)
+        attach = data["attach"]
+        params = dict([(k, v[0]) for k, v in parse_qs(unquote(attach)).items()])
+        lang = params['lang']
+        trade_status = data['result_code']  # 业务结果  SUCCESS/FAIL
+        order_id = data['out_trade_no']  # 商户订单号
+
+        # redis加锁,防止订单重复
+        redis_obj = RedisObject()
+        is_lock = redis_obj.CONN.setnx(order_id + 'creating_icloud_order', 1)
+        redis_obj.CONN.expire(order_id + 'creating_icloud_order', 60)
+        if not is_lock:
+            return response.json(5)
+
+        order_qs = Order_Model.objects.filter(orderID=order_id, status=0)
+        if not order_qs.exists():
+            return response.json(173)
+        try:
+            if trade_status != 'SUCCESS':
+                order_qs.update(status=10)
+                return HttpResponse(pay.xml_to_dict({'return_code': 'FAIL'}))
+            check_sign = pay.get_notifypay(data)
+            if not check_sign:
+                return HttpResponse(pay.xml_to_dict({'return_code': 'FAIL', 'return_msg': '签名失败'}))
+
+            return cls.payment_success(order_id, lang, order_qs, redis_obj, True)
+        except Exception as e:
+            order_qs.update(status=10)
+            redis_obj.del_data(key=order_id + 'creating_icloud_order')
+            return HttpResponse(pay.xml_to_dict({'return_code': 'FAIL', 'return_msg': repr(e)}))
+
+    @staticmethod
+    def payment_success(order_id, lang, order_qs, redis_obj, is_wechat_pay=False):
+        """
+        支付成功
+        @param order_id: 订单id
+        @param lang: 语言
+        @param order_qs: 订单QuerySet对象
+        @param redis_obj: redis对象
+        @param is_wechat_pay: 是否为微信支付
+        @return: HttpResponse or HttpResponseRedirect
+        """
+        now_time = int(time.time())
+        order_list = order_qs.values('unify_combo_id', 'userID__userID', 'userID__username')
+        user_id = order_list[0]['userID__userID']
+        rank_id = order_list[0]['unify_combo_id']
+
+        icloud_meal_qs = ICloudStoreMeal.objects.filter(id=rank_id).values('size', 'expire')
+        size = icloud_meal_qs[0]['size']
+        expire = icloud_meal_qs[0]['expire']
+        end_time = CommonService.calcMonthLater(expire)
+        icloud_service_dict = {'orders_id': order_id,
+                               'add_time': now_time,
+                               'upd_time': now_time,
+                               'type': 2,
+                               'size': size,
+                               'end_time': end_time
+                               }
+        icloud_use_qs = IcloudUseDetails.objects.filter(user_id=user_id).values('id')
+        icloud_service_dict['use_details_id'] = icloud_use_qs[0]['id']
+
+        with transaction.atomic():
+            # 更新订单数据,返回支付成功url
+            order_qs.update(status=1, updTime=now_time)
+            # 创建AiService数据
+            IcloudService.objects.create(**icloud_service_dict)
+
+        pay_success_url = CommonService.get_payment_status_url(lang, 'success')
+        redis_obj.del_data(key=order_id + 'creating_icloud_order')
+        if is_wechat_pay:
+            return HttpResponse("<xml>\
+              <return_code><![CDATA[SUCCESS]]></return_code>\
+              <return_msg><![CDATA[OK]]></return_msg>\
+            </xml>")
+        else:
+            return HttpResponseRedirect(pay_success_url)
+
+    @staticmethod
+    def create_paypal_payment(lang, order_id, price, currency, content):
+        """
+        创建PayPal支付
+        @param lang: 语言
+        @param order_id: 订单id
+        @param price: 价格
+        @param currency: 货币
+        @param content: 内容
+        @return: pay_dict
+        """
+        cancel_url = CommonService.get_payment_status_url(lang, 'fail')
+        call_sub_url = "{}icloud/meal/doPayPalCallBack?orderID={}&lang={}".format(SERVER_DOMAIN_SSL, order_id, lang)
+
+        try:
+            paypalrestsdk.configure(PAYPAL_CRD)
+            payment = paypalrestsdk.Payment({
+                "intent": "sale",
+                "payer": {"payment_method": "paypal"},
+                "redirect_urls": {"return_url": call_sub_url, "cancel_url": cancel_url},
+                "transactions": [{
+                    "item_list": {"items": [
+                        {"name": "Cloud video", "sku": "1", "price": price, "currency": "USD", "quantity": 1}]},
+                    "amount": {"total": price, "currency": currency},
+                    "description": content}]})
+
+            pay_dict = {}
+            if not payment.create():  # 创建失败
+                return pay_dict
+            payment_id = payment['id']  # 获取payment id
+            for link in payment.links:
+                if link.rel == "approval_url":
+                    pay_url = str(link.href)
+                    pay_dict['payment_id'] = payment_id
+                    pay_dict['pay_url'] = pay_url
+                    return pay_dict
+            return pay_dict
+        except Exception as e:
+            print(e)
+            return {}
+
+    @staticmethod
+    def create_alipay_payment(lang, order_id, price, title, content):
+        """
+        创建支付宝支付
+        @param lang: 语言
+        @param order_id: 订单id
+        @param price: 价格
+        @param title: 标题
+        @param content: 内容
+        @return: pay_dict
+        """
+        try:
+            aliPayObj = AliPayObject()
+            alipay = aliPayObj.conf()
+            subject = title + content
+            order_string = alipay.api_alipay_trade_wap_pay(
+                out_trade_no=order_id,
+                total_amount=price,
+                subject=subject,
+                return_url="{}web/paid2/success.html".format(SERVER_DOMAIN_SSL),
+                notify_url="{}icloud/meal/doAlipayCallBack".format(SERVER_DOMAIN_SSL),
+                quit_url="{}web/paid2/fail.html".format(SERVER_DOMAIN_SSL),
+                passback_params=quote("lang=" + lang)
+            )
+            if not order_string:
+                return {}
+            return {'pay_url': aliPayObj.alipay_prefix + order_string}
+        except Exception as e:
+            print(e)
+            return {}
+
+    @staticmethod
+    def create_wechat_payment(lang, order_id, price, ip, content):
+        """
+        创建微信支付
+        @param lang: 语言
+        @param order_id: 订单id
+        @param price: 价格
+        @param ip: ip
+        @param content: 内容
+        @return: pay_dict
+        """
+        pay_url = "{}icloud/meal/doWechatCallBack".format(SERVER_DOMAIN_SSL)
+        try:
+            pay = WechatPayObject()
+            content = CommonService.Package_Type(4, content)  # 云盘套餐
+            pay.get_parameter(order_id, content, float(price) * 100, ip, pay_url, quote("lang=" + lang))
+            sign_params = pay.re_finall(orderid=order_id)
+            if not sign_params:
+                return {}
+            return {'pay_url': pay_url, 'sign_params': sign_params}
+        except Exception as e:
+            print(e)
+            return {}
+
+    @staticmethod
+    def get_cloud_drive_init(request_dict, response, user_id):
+        """
+        获取套餐明细
+        @param request_dict: 请求数据
+        @request_dict page: 页
+        @request_dict line: 大小
+        @request_dict lang: 语言
+        @param user_id: 用户id
+        @param response: 响应
+        @return: response
+        """
+        lang = request_dict.get('lang', 'en')
+        page = request_dict.get('page', None)
+        line = request_dict.get('line', None)
+        if not all([page, line]):
+            return response.json(444)
+        page = int(page)
+        line = int(line)
+        cloud_use_qs = IcloudUseDetails.objects.filter(user_id=user_id).values('id')
+        if not cloud_use_qs.exists():
+            return response.json(0)
+        use_list = [obj['id'] for obj in cloud_use_qs]
+        cloud_service_qs = IcloudService.objects.filter(use_details_id__in=use_list)
+        if not cloud_use_qs.exists():
+            return response.json(0)
+        try:
+            cloud_service_list = []
+            count = cloud_service_qs.count()
+            cloud_service_qs = cloud_service_qs.values('use_status', 'type', 'order_id', 'add_time',
+                                                       'end_time').order_by(
+                '-add_time')[(page - 1) * line:page * line]
+            # 获取套餐明细
+            for service in cloud_service_qs:
+                data = {
+                    'use_status': service['use_status'],
+                    'type': service['type'],
+                    'order_id': service['order_id'],
+                    'add_time': service['add_time'],
+                    'end_time': service['end_time'],
+                }
+                # 注册永久送
+                if service['type'] == 0:
+                    icloud_meal_qs = ICloudStoreMeal.objects.filter(price=0, expire=0, is_show=0, size=1, pay_type=10,
+                                                                    lang__lang=lang).values('lang__title',
+                                                                                            'lang__content')
+                    data['title'] = icloud_meal_qs[0]['lang__title']
+                    data['note'] = icloud_meal_qs[0]['lang__content']
+                # 购买云存附送
+                if service['type'] == 1:
+                    orders_qs = Order_Model.objects.filter(orderID=service['order_id'], order_type=0). \
+                        values('desc', 'unify_combo_id')
+                    data['note'] = orders_qs[0]['desc']
+                    cloud_store_qs = ICloudStoreMeal.objects.filter(id=orders_qs[0]['unify_combo_id'],
+                                                                    lang__lang=lang).values(
+                        'lang__title')
+                    data['title'] = cloud_store_qs[0]['lang__title']
+                # 单独购买套餐
+                if service['type'] == 2:
+                    orders_qs = Order_Model.objects.filter(orderID=service['order_id']).values('desc', 'price',
+                                                                                               'currency')
+                    data['title'] = orders_qs[0]['desc']
+                    data['note'] = orders_qs[0]['price'] + orders_qs[0]['currency']
+                cloud_service_list.append(data)
+            return response.json(0, {'data': cloud_service_list, 'count': count})
+        except Exception as e:
+            LOGGER.info('异常错误,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            return response.json(500, e)
+
+    @staticmethod
+    def get_capacity(response, user_id):
+        """
+        获取云盘容量
+        @param user_id: 用户id
+        @param response: 响应
+        @return: response
+        """
+        nowTime = int(time.time())
+        try:
+            cloud_use_qs = IcloudUseDetails.objects.filter(user_id=user_id).values('id').aggregate(
+                total_used_size=Sum('use_size'),
+                id=Sum('id'))
+            cloud_service_qs = IcloudService.objects.filter(Q(use_details_id=cloud_use_qs['id']), Q(use_status=0),
+                                                            Q(end_time__gt=nowTime) | Q(end_time=0)).aggregate(
+                total_size=Sum('size'))
+
+            data = {
+                'M_size': round(cloud_use_qs['total_used_size'], 2),
+                'G_size': round(cloud_service_qs['total_size'], 0)
+            }
+            return response.json(0, data)
+        except Exception as e:
+            LOGGER.info('异常错误,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            return response.json(500, e)
+
+    @staticmethod
+    def activate_cloud_drive(request_dict, response, user_id):
+        """
+        激活云盘
+        @param request_dict: 请求数据
+        @param user_id: 用户id
+        @param response: 响应
+        @return: response
+        """
+        lang = request_dict.get('lang', 'en')
+        now_time = int(time.time())
+        try:
+            icloud_meal_qs = ICloudStoreMeal.objects.filter(price=0, expire=0, is_show=0, size=1, pay_type=10,
+                                                            lang__lang=lang).values('bucket_id')
+            if not icloud_meal_qs.exists():
+                return response.json(173)
+            cloud_use_qs = IcloudUseDetails.objects.filter(user_id=user_id).values('id')
+            if not cloud_use_qs.exists():
+                # 云盘使用
+                cloud_use_data = {
+                    'use_size': 0,
+                    'add_time': now_time,
+                    'upd_time': now_time,
+                    'detect_status': 1,
+                    'user_id': user_id,
+                    'bucket_id': icloud_meal_qs[0]['bucket_id']
+                }
+                cloud_use_qs = IcloudUseDetails.objects.create(**cloud_use_data)
+                use_details_id = cloud_use_qs.id
+            else:
+                use_details_id = cloud_use_qs[0]['id']
+            icloud_service_qs = IcloudService.objects.filter(use_details_id=use_details_id, size=1, end_time=0, type=0)
+            if not icloud_service_qs.exists():
+                # 云盘服务
+                cloud_service_data = {
+                    'size': 1,
+                    'end_time': 0,
+                    'add_time': now_time,
+                    'upd_time': now_time,
+                    'use_status': 0,
+                    'use_details_id': use_details_id,
+                    'type': 0,
+                    'order_id': 0
+                }
+                IcloudService.objects.create(**cloud_service_data)
+            return response.json(0)
+        except Exception as e:
+            LOGGER.info('异常错误,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            return response.json(500, e)

+ 586 - 0
Controller/IcloudService/IcloudService.py

@@ -0,0 +1,586 @@
+# -*- coding: utf-8 -*-
+"""
+@Author : peng
+@Time : 2023-6-7 18:26:35
+@File :IcloudMeal.py
+"""
+from Ansjer.config import LOGGER
+import time
+import jwt
+
+from django.db.models import Sum, Q
+from django.http import HttpResponse
+from django.views import View
+
+from Model.models import IcloudUseDetails, IcloudService, VodBucketModel, IcloudStorageRecord, Device_Info, Device_User
+from Object.AWS.AmazonS3Util import AmazonS3Util
+from Object.RedisObject import RedisObject
+from Object.ResponseObject import ResponseObject
+from Object.TokenObject import TokenObject
+from Ansjer.config import ACCESS_KEY_ID, SECRET_ACCESS_KEY, REGION_NAME, SERVER_DOMAIN, AWS_ACCESS_KEY_ID, \
+    AWS_SECRET_ACCESS_KEY, SERVER_DOMAIN_SSL, OAUTH_ACCESS_TOKEN_SECRET
+from Object.m3u8generate import PlaylistGenerator
+from Service.VodHlsService import SplitVodHlsObject
+
+
+class IcloudServiceView(View):
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.GET, operation, request)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.POST, operation, request)
+
+    def validation(self, request_dict, operation, request):
+        response = ResponseObject()
+        if operation == 'icloudPlay':  # 云盘播放
+            return self.icloud_play(request_dict, response)
+        else:
+            tko = TokenObject(request.META.get('HTTP_AUTHORIZATION'))
+            response.lang = tko.lang
+            user_id = tko.userID
+            if tko.code != 0:
+                return response.json(tko.code)
+            if operation == 'vodUpload':  # 云存上传云盘
+                return self.vod_upload(request_dict, response, user_id)
+            elif operation == 'getUploadUrl':  # 获取s3上传地址
+                return self.get_upload_url(request_dict, response, user_id)
+            elif operation == 'localUpload':  # 本地上传云盘
+                return self.local_upload(request_dict, response, user_id)
+            elif operation == 'deleteIcloudRecord':  # 删除云盘记录
+                return self.delete_icloud_record(request_dict, response, user_id)
+            elif operation == 'getIcloudList':  # 获取云盘播放列表
+                return self.get_icloud_list(request_dict, response, user_id)
+            elif operation == 'changeIcloudStatus':  # 修改云盘开关状态
+                return self.do_change_icloud_status(request_dict, response, user_id)
+            else:
+                return response.json(404)
+
+    @staticmethod
+    def vod_upload(request_dict, response, user_id):
+        """
+        云存上传云盘
+        @param request_dict: 请求参数
+        @param user_id: 用户id
+        @request_dict uid: 设备uid
+        @request_dict channel: 设备通道
+        @request_dict start_time: 播放时间戳
+        @param response: 响应对象
+        @return: response
+        """
+        LOGGER.info('开始云存转移到云盘')
+        uid = request_dict.get('uid', None)
+        channel = request_dict.get('channel', None)
+        time_stamp = request_dict.get('time_stamp', None)
+        if not all([uid, channel, time_stamp]):
+            return response.json(444, {'error param': 'uid,channel,start_time'})
+        device_qs = Device_Info.objects.filter(UID=uid, userID=user_id).values('NickName')
+        if not device_qs.exists():
+            return response.json(173)
+        # 查询是否开通云盘
+        use_details_qs = IcloudUseDetails.objects.filter(user_id=user_id).values('id', 'bucket_id', 'use_size')
+        if not use_details_qs.exists():
+            return response.json(173)
+        use_details_id = use_details_qs[0]['id']
+        target_bucket_id = use_details_qs[0]['bucket_id']
+        use_size = float(use_details_qs[0]['use_size'])
+        now_time = int(time.time())
+        nickname = device_qs[0]['NickName']
+        # 判断云盘是否还有容量
+        all_size = IcloudService.objects.filter(Q(use_details_id=use_details_id), Q(use_status=0),
+                                                Q(end_time__gt=now_time) | Q(end_time=0)).values(
+            'size').aggregate(total_size=Sum('size'))['total_size']
+        all_size = all_size * 1024 if all_size else 0
+        if use_size > all_size:
+            LOGGER.info('{}用户套餐总容量为:{},已使用容量为:{}'.format(uid, all_size, use_size))
+            return response.json(910)
+        split_vod_hls_obj = SplitVodHlsObject()
+        vod_hls = split_vod_hls_obj.get_vod_hls_data(uid=uid, channel=channel, start_time=time_stamp).values(
+            'bucket_id', 'fg', 'sec')
+        if not vod_hls.exists():
+            LOGGER.info('{}用户查无此云存:{}'.format(uid, time_stamp))
+            return response.json(173)
+        source_bucket_id = vod_hls[0]['bucket_id']
+        fg = int(vod_hls[0]['fg'])
+        sec = vod_hls[0]['sec']
+        target_bucket_qs = VodBucketModel.objects.filter(id=target_bucket_id).values('bucket')
+        if not target_bucket_qs.exists():
+            return response.json(173)
+        target_bucket_name = target_bucket_qs[0]['bucket']
+
+        source_bucket_qs = VodBucketModel.objects.filter(id=source_bucket_id).values('bucket', 'region', 'mold')
+        if not source_bucket_qs.exists():
+            return response.json(173)
+        bucket_region = source_bucket_qs[0]['region']
+        source_bucket_name = source_bucket_qs[0]['bucket']
+        mold = source_bucket_qs[0]["mold"]
+        ts_list = []
+        ts_size = 0
+        try:
+            s3_obj = AmazonS3Util(
+                AWS_ACCESS_KEY_ID[mold],
+                AWS_SECRET_ACCESS_KEY[mold],
+                bucket_region
+            )
+            # 获取视频封面
+            thumbs_png = '{uid}/vod{channel}/{time}/Thumb.jpeg'.format(uid=uid, channel=channel, time=time_stamp)
+            thumbs_png_size = s3_obj.get_object_size(source_bucket_name, thumbs_png)
+            if thumbs_png_size:
+                ts_size += thumbs_png_size
+                ts_list.append(thumbs_png)
+            # 获取s3对象,并计算总字节
+            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=time_stamp,
+                                                                          i=i)
+                    ts_list.append(ts_file)
+                    ts_size += s3_obj.get_object_size(source_bucket_name, ts_file)  # 获取存储对象字节,单位B
+            ts_size = round(ts_size / 1024 / 1024, 2)  # 字节转换为MB单位
+            temp_size = ts_size + use_size
+            if temp_size > all_size:
+                LOGGER.info('{}用户无空间上传,套餐容量为:{},使用容量为:{}'.format(uid, all_size, temp_size))
+                return response.json(910)
+            time_stamp = int(time_stamp) * 1000  # 转换单位为毫秒
+            icloud_record_qs = IcloudStorageRecord.objects.filter(user_id=user_id, uid=uid, channel=channel,
+                                                                  time_stamp=time_stamp,
+                                                                  size=ts_size, file_type=1)
+            if not icloud_record_qs.exists():  # 转移云盘,并记录上传记录,更新使用容量
+                for source_key in ts_list:
+                    ts_name = source_key.split('/')[-1]
+                    target_key = '{user_id}/ts_file/{uid}/channel{channel}/{time}/{ts_name}'.format(user_id=user_id,
+                                                                                                    uid=uid,
+                                                                                                    channel=channel,
+                                                                                                    time=time_stamp,
+                                                                                                    ts_name=ts_name)
+                    s3_obj.copy_single_obj(source_bucket_name, source_key, target_bucket_name, target_key,
+                                           StorageClass='STANDARD_IA')
+
+                IcloudStorageRecord.objects.create(user_id=user_id, uid=uid, channel=channel, time_stamp=time_stamp,
+                                                   nickname=nickname,
+                                                   sec=sec, bucket_id=target_bucket_id, fg=fg, size=ts_size,
+                                                   file_type=1)
+                use_details_qs.update(use_size=temp_size)
+                return response.json(0)
+            else:
+                return response.json(174)
+        except Exception as e:
+            LOGGER.info('云存转移云盘异常:{}'.format(repr(e)))
+            return response.json(500)
+
+    @staticmethod
+    def local_upload(request_dict, response, user_id):
+        """
+        本地上传云盘
+        @param request_dict: 请求参数
+        @param user_id: 用户id
+        @request_dict uid: 设备uid
+        @request_dict channel: 设备通道
+        @request_dict time_stamp: 时间戳
+        @request_dict size: 文件大小
+        @request_dict file_type: 文件类型
+        @request_dict sec: 时长
+        @param response: 响应对象
+        @return: response
+        """
+        LOGGER.info('开始本地转移到云盘')
+        uid = request_dict.get('uid', None)
+        channel = request_dict.get('channel', None)
+        time_stamp = request_dict.get('time_stamp', None)
+        size = request_dict.get('size', None)
+        file_type = request_dict.get('file_type', None)
+        sec = request_dict.get('sec', 0)
+        if not all([uid, channel, time_stamp, size]):
+            return response.json(444, {'error param': 'uid,channel,time_stamp,size'})
+        device_qs = Device_Info.objects.filter(UID=uid, userID=user_id).values('NickName')
+        if not device_qs.exists():
+            return response.json(173)
+        # 查询是否开通云盘
+        use_details_qs = IcloudUseDetails.objects.filter(user_id=user_id).values('id', 'use_size', 'bucket_id')
+        if not use_details_qs.exists():
+            return response.json(173)
+        size = float(size)  # 单位是MB
+        use_details_id = use_details_qs[0]['id']
+        bucket_id = use_details_qs[0]['bucket_id']
+        use_size = float(use_details_qs[0]['use_size'])
+        now_time = int(time.time())
+        nickname = device_qs[0]['NickName']
+        # 判断云盘是否还有容量
+        all_size = IcloudService.objects.filter(Q(use_details_id=use_details_id), Q(use_status=0),
+                                                Q(end_time__gt=now_time) | Q(end_time=0)).values(
+            'size').aggregate(total_size=Sum('size'))['total_size']
+        all_size = all_size * 1024 if all_size else 0
+        if use_size > all_size:
+            LOGGER.info('{}用户套餐总容量为:{},已使用容量为:{}'.format(uid, all_size, use_size))
+            return response.json(910)
+
+        try:
+            new_size = round(use_size + size, 2)
+            icloud_record_qs = IcloudStorageRecord.objects.filter(user_id=user_id, uid=uid, channel=channel,
+                                                                  time_stamp=time_stamp,
+                                                                  size=size, file_type=file_type)
+            if not icloud_record_qs.exists():
+                IcloudStorageRecord.objects.create(user_id=user_id, uid=uid, channel=channel, time_stamp=time_stamp,
+                                                   nickname=nickname,
+                                                   sec=sec, bucket_id=bucket_id, size=size,
+                                                   file_type=file_type)
+                use_details_qs.update(use_size=new_size)
+                return response.json(0)
+            else:
+                return response.json(174)
+        except Exception as e:
+            LOGGER.info('本地转移云盘异常:{}'.format(repr(e)))
+            return response.json(500)
+
+    @staticmethod
+    def get_upload_url(request_dict, response, user_id):
+        """
+        获取s3上传地址
+        @param request_dict: 请求参数
+        @param user_id: 用户id
+        @request_dict time_stamp: 时间戳
+        @request_dict file_type: 文件类型
+        @request_dict uid: 设备uid
+        @request_dict channel: 设备通道
+        @param response: 响应对象
+        @return: response
+        """
+        LOGGER.info('获取s3上传地址')
+        time_stamp = request_dict.get('time_stamp', None)
+        file_type = request_dict.get('file_type', None)
+        uid = request_dict.get('uid', None)
+        channel = request_dict.get('channel', None)
+        if not all([time_stamp, uid, channel]):
+            return response.json(444, {'error param': 'time_stamp,channel,uid'})
+        device_qs = Device_Info.objects.filter(UID=uid, userID=user_id)
+        if not device_qs.exists():
+            return response.json(173)
+        # 查询是否开通云盘
+        use_details_qs = IcloudUseDetails.objects.filter(user_id=user_id).values('id', 'use_size', 'bucket_id')
+        if not use_details_qs.exists():
+            return response.json(173)
+        use_details_id = use_details_qs[0]['id']
+        use_size = use_details_qs[0]['use_size']
+        bucket_id = use_details_qs[0]['bucket_id']
+        now_time = int(time.time())
+        # 判断云盘是否还有容量
+        all_size = IcloudService.objects.filter(Q(use_details_id=use_details_id), Q(use_status=0),
+                                                Q(end_time__gt=now_time) | Q(end_time=0)).values(
+            'size').aggregate(total_size=Sum('size'))['total_size']
+        all_size = all_size * 1024 if all_size else 0
+        excess_size = all_size - use_size
+        if excess_size < 0:
+            LOGGER.info('{}用户套餐总容量为:{},已使用容量为:{}'.format(user_id, all_size, use_size))
+            return response.json(910)
+
+        bucket_qs = VodBucketModel.objects.filter(id=bucket_id).values('bucket', 'region', 'mold')
+        if not bucket_qs.exists():
+            return response.json(173)
+        bucket_name = bucket_qs[0]['bucket']
+        bucket_region = bucket_qs[0]['region']
+        mold = bucket_qs[0]['mold']
+        try:
+            s3_obj = AmazonS3Util(
+                AWS_ACCESS_KEY_ID[mold],
+                AWS_SECRET_ACCESS_KEY[mold],
+                bucket_region
+            )
+            if file_type == '0':  # 图片
+                key_name = '{user_id}/image_file/{uid}/channel{channel}/{time}/{time}.jpeg'.format(user_id=user_id,
+                                                                                                   uid=uid,
+                                                                                                   channel=channel,
+                                                                                                   time=time_stamp)
+            elif file_type == '2':
+                key_name = '{user_id}/mp4_file/{uid}/channel{channel}/{time}/{time}.mp4'.format(user_id=user_id,
+                                                                                                uid=uid,
+                                                                                                channel=channel,
+                                                                                                time=time_stamp)
+            else:
+                return response.json(444, {'error param': 'file_type'})
+            upload_url = s3_obj.generate_put_obj_url(bucket_name, key_name, 'STANDARD_IA')
+            return response.json(0, {'uploadUrl': upload_url, 'excessSize': excess_size})
+        except Exception as e:
+            LOGGER.info('获取s3上传地址异常:{}'.format(repr(e)))
+            return response.json(500)
+
+    @staticmethod
+    def delete_icloud_record(request_dict, response, user_id):
+        """
+        删除云盘记录
+        @param request_dict: 请求参数
+        @param user_id: 用户id
+        @request_dict time_stamp: 时间戳
+        @request_dict uid: 设备uid
+        @request_dict channel: 设备通道
+        @request_dict file_type: 文件类型
+        @param response: 响应对象
+        @return: response
+        """
+        LOGGER.info('删除云盘记录')
+        record_ids = request_dict.get('record_ids', None)
+        if not all([record_ids]):
+            return response.json(444, {'error param': 'record_id'})
+        record_id_list = record_ids.split(',')
+        # 查询是否开通云盘
+        use_details_qs = IcloudUseDetails.objects.filter(user_id=user_id).values('use_size', 'bucket_id')
+        if not use_details_qs.exists():
+            return response.json(173)
+        use_size = float(use_details_qs[0]['use_size'])
+        bucket_id = use_details_qs[0]['bucket_id']
+        icloud_record_qs = IcloudStorageRecord.objects.filter(user_id=user_id, id__in=record_id_list)
+        if not icloud_record_qs.exists():
+            return response.json(173)
+        record_qs = icloud_record_qs.values('size', 'uid', 'channel', 'time_stamp', 'file_type')
+        bucket_qs = VodBucketModel.objects.filter(id=bucket_id).values('bucket', 'region', 'mold')
+        if not bucket_qs.exists():
+            return response.json(173)
+        bucket_name = bucket_qs[0]['bucket']
+        bucket_region = bucket_qs[0]['region']
+        mold = bucket_qs[0]['mold']
+        try:
+            s3_obj = AmazonS3Util(
+                AWS_ACCESS_KEY_ID[mold],
+                AWS_SECRET_ACCESS_KEY[mold],
+                bucket_region
+            )
+            for item in record_qs:
+                size = float(item['size'])
+                uid = item['uid']
+                channel = item['channel']
+                time_stamp = item['time_stamp']
+                file_type = item['file_type']
+                use_size = round(use_size - size, 2)
+                if file_type == 0:  # 图片
+                    key_name = '{user_id}/image_file/{uid}/channel{channel}/{time}'.format(user_id=user_id, uid=uid,
+                                                                                           channel=channel,
+                                                                                           time=time_stamp)
+                elif file_type == 1:  # ts文件
+                    key_name = '{user_id}/ts_file/{uid}/channel{channel}/{time}'.format(user_id=user_id, uid=uid,
+                                                                                        channel=channel,
+                                                                                        time=time_stamp)
+                elif file_type == 2:  # mp4文件
+                    key_name = '{user_id}/mp4_file/{uid}/channel{channel}/{time}'.format(user_id=user_id, uid=uid,
+                                                                                         channel=channel,
+                                                                                         time=time_stamp)
+                else:
+                    return response.json(444, {'error param': 'file_type'})
+                object_list = s3_obj.get_object_list(bucket_name, key_name)
+                for obj in object_list:
+                    s3_obj.delete_obj(bucket_name, obj['Key'])
+            use_size = use_size if use_size > 0 else 0
+            icloud_record_qs.delete()
+            use_details_qs.update(use_size=use_size)
+            return response.json(0)
+        except Exception as e:
+            LOGGER.info('删除云盘记录异常:{}'.format(repr(e)))
+            return response.json(500)
+
+    @staticmethod
+    def get_icloud_list(request_dict, response, user_id):
+        """
+        获取云盘播放列表
+        @param request_dict: 请求参数
+        @param user_id: 用户id
+        @request_dict time_stamp: 时间戳
+        @request_dict uid: 设备uid
+        @request_dict channel: 设备通道
+        @param response: 响应对象
+        @return: response
+        """
+        LOGGER.info('删除云盘记录')
+        start_time = request_dict.get('start_time', None)
+        end_time = request_dict.get('end_time', None)
+        uid = request_dict.get('uid', None)
+        file_type = request_dict.get('file_type', None)
+        page = request_dict.get('page', None)
+        line = request_dict.get('line', None)
+        if not all([page, line]):
+            return response.json(444, {'error param': 'page, line'})
+        page = int(page)
+        line = int(line)
+        now_time = int(time.time())
+        icloud_list = []
+        use_details_qs = IcloudUseDetails.objects.filter(user_id=user_id).values('id')
+        if not use_details_qs.exists():
+            return response.json(911)
+        use_details_id = use_details_qs[0]['id']
+        all_size = IcloudService.objects.filter(Q(use_details_id=use_details_id), Q(use_status=0),
+                                                Q(end_time__gt=now_time) | Q(end_time=0)).values(
+            'size').aggregate(total_size=Sum('size'))['total_size']
+        all_size = float(all_size * 1024) if all_size else 0  # 转换单位为MB
+        icloud_record_qs = IcloudStorageRecord.objects.filter(user_id=user_id)
+        if start_time and end_time:  # 按时间段查询
+            icloud_record_qs = icloud_record_qs.filter(time_stamp__gte=start_time, time_stamp__lt=end_time)
+        if uid:  # 按设备昵称查询
+            uid_list = uid.split(',')
+            icloud_record_qs = icloud_record_qs.filter(uid__in=uid_list)
+        if file_type:  # 按文件类型查询
+            file_type_list = file_type.split(',')
+            icloud_record_qs = icloud_record_qs.filter(file_type__in=file_type_list)
+        icloud_record_qs = icloud_record_qs.values('bucket_id', 'sec', 'fg', 'nickname', 'uid', 'channel', 'size', 'id',
+                                                   'time_stamp', 'file_type').order_by('-time_stamp')[
+                           (page - 1) * line:page * line]
+        if not icloud_record_qs.exists():
+            return response.json(0, {'icloudList': icloud_list, 'notShow': 0})
+        bucket_id = icloud_record_qs[0]['bucket_id']
+        bucket_qs = VodBucketModel.objects.filter(id=bucket_id).values('bucket', 'region', 'mold')
+        if not bucket_qs.exists():
+            return response.json(173)
+        bucket_name = bucket_qs[0]['bucket']
+        bucket_region = bucket_qs[0]['region']
+        mold = bucket_qs[0]['mold']
+        total_size = 0
+        try:
+            s3_obj = AmazonS3Util(
+                AWS_ACCESS_KEY_ID[mold],
+                AWS_SECRET_ACCESS_KEY[mold],
+                bucket_region
+            )
+            for item in icloud_record_qs:
+                uid = item['uid']
+                channel = item['channel']
+                time_stamp = item['time_stamp']
+                file_type = item['file_type']
+                total_size += float(item['size'])
+                uid_token = TokenObject().encryption(data={'uid': uid, 'user_id': user_id})
+                res_data = {
+                    'is_show': 1 if total_size < all_size else 0,  # 只展示剩余容量的数据,超过的部分不展示,1:展示;0:不展示
+                    'time_stamp': time_stamp,
+                    'icloud_id': item['id'],
+                    'file_type': file_type,
+                    'nick_name': item['nickname'],
+                    'uid': uid
+                }
+                if file_type == 0:  # 图片,只返回图片地址
+                    thumbs_png = '{user_id}/image_file/{uid}/channel{channel}/{time}/{time}.jpeg'.format(
+                        user_id=user_id,
+                        uid=uid,
+                        channel=channel,
+                        time=time_stamp)
+                    response_url = s3_obj.generate_file_obj_url(bucket_name, thumbs_png)
+                    res_data['thumb'] = response_url
+                    icloud_list.append(res_data)
+                elif file_type == 1:  # ts文件,返回播放地址
+                    thumbs_png = '{user_id}/ts_file/{uid}/channel{channel}/{time}/Thumb.jpeg'.format(
+                        user_id=user_id,
+                        uid=uid,
+                        channel=channel,
+                        time=time_stamp)
+                    response_url = s3_obj.generate_file_obj_url(bucket_name, thumbs_png)
+                    ts_num = int(item['fg']) & 0xf
+                    res_data['thumb'] = response_url
+                    icloud_url = '{server_domain}icloud/service/icloudPlay?' \
+                                 'uid={uid}&channel={channel}&time_stamp={time_stamp}&file_type=1&sign=tktktktk'. \
+                        format(server_domain=SERVER_DOMAIN_SSL, uid=uid_token, channel=channel, time_stamp=time_stamp)
+                    res_data['ts_num'] = ts_num
+                    res_data['icloud_url'] = icloud_url
+                    res_data['sec'] = item['sec']
+                    icloud_list.append(res_data)
+                elif file_type == 2:  # mp4文件,返回播放地址
+                    mp4_file = '{user_id}/mp4_file/{uid}/channel{channel}/{time}/{time}.mp4'.format(
+                        user_id=user_id,
+                        uid=uid,
+                        channel=channel,
+                        time=time_stamp)
+                    response_url = s3_obj.generate_file_obj_url(bucket_name, mp4_file)
+                    res_data['icloud_url'] = response_url
+                    res_data['sec'] = item['sec']
+                    icloud_list.append(res_data)
+            not_show = total_size - all_size if total_size > all_size else 0
+            return response.json(0, {'icloudList': icloud_list, 'notShow': not_show})
+        except Exception as e:
+            LOGGER.info('获取云盘播放列表异常:{}'.format(repr(e)))
+            return response.json(500)
+
+    @staticmethod
+    def icloud_play(request_dict, response):
+        """
+        云盘播放
+        @param request_dict: 请求参数
+        @request_dict time_stamp: 时间戳
+        @request_dict uid: 设备uid
+        @request_dict channel: 设备通道
+        @param response: 响应对象
+        @return: response
+        """
+        LOGGER.info('播放云盘记录')
+        time_stamp = request_dict.get('time_stamp', None)
+        uid_token = request_dict.get('uid', None)
+        channel = request_dict.get('channel', None)
+        file_type = request_dict.get('file_type', None)
+        if not all([time_stamp, uid_token, channel, file_type]):
+            return response.json(444, {'error param': 'time_stamp, uid_token, channel, file_type'})
+        if file_type != '1':
+            return response.json(444, {'error param': 'file_type'})
+        token = jwt.decode(uid_token, OAUTH_ACCESS_TOKEN_SECRET, algorithms='HS256')
+        uid = token.get('uid', '')
+        user_id = token.get('user_id', '')
+        icloud_record_qs = IcloudStorageRecord.objects.filter(user_id=user_id, uid=uid, channel=channel,
+                                                              file_type=file_type,
+                                                              time_stamp=time_stamp).values('bucket_id', 'fg')
+        if not icloud_record_qs.exists():
+            return response.json(173)
+        bucket_id = icloud_record_qs[0]['bucket_id']
+        fg = int(icloud_record_qs[0]['fg'])
+        bucket_qs = VodBucketModel.objects.filter(id=bucket_id).values('bucket', 'region', 'mold')
+        if not bucket_qs.exists():
+            return response.json(173)
+        bucket_name = bucket_qs[0]['bucket']
+        bucket_region = bucket_qs[0]['region']
+        mold = bucket_qs[0]['mold']
+        try:
+            s3_obj = AmazonS3Util(
+                AWS_ACCESS_KEY_ID[mold],
+                AWS_SECRET_ACCESS_KEY[mold],
+                bucket_region
+            )
+            playlist_entries = []
+            for i in range(15):
+                shift = (i + 1) * 4
+                duration = (fg >> shift) & 0xf
+                if duration > 0:
+                    ts_file = '{user_id}/ts_file/{uid}/channel{channel}/{time_stamp}/ts{i}.ts'.format(
+                        user_id=user_id, uid=uid, channel=channel, time_stamp=time_stamp, 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)
+            response['Content-Type'] = 'application/octet-stream'
+            response['Content-Disposition'] = 'attachment;filename="play.m3u8"'
+            return response
+        except Exception as e:
+            LOGGER.info('云盘播放异常:{}'.format(repr(e)))
+            return response.json(500)
+
+    @staticmethod
+    def do_change_icloud_status(request_dict, response, user_id):
+        """
+        修改云盘开关
+        @param request_dict: 请求参数
+        @param user_id: 用户id
+        @request_dict status: 开关状态, 0: 关闭, 1: 开启
+        @param response: 响应对象
+        @return: response
+        """
+        status = request_dict.get('status', None)
+
+        if not status:
+            return response.json(444, 'status')
+
+        try:
+            device_user_qs = Device_User.objects.filter(userID=user_id)
+            if not device_user_qs.exists():
+                return response.json(173)
+            icloud_use_details_qs = IcloudUseDetails.objects.filter(user_id=user_id)
+            icloud_use_details_qs.update(detect_status=status)
+            return response.json(0)
+        except Exception as e:
+            print(e)
+            return response.json(500)

+ 7 - 1
Controller/InitController.py

@@ -13,6 +13,7 @@ from Model.models import Device_User, Device_Info, Order_Model, UidPushModel, Us
     AppLogModel, UserFamily, FamilyMember, FamilyMemberJoin, SmartScene, DeviceSuperPassword, SceneLog
 from Object.RedisObject import RedisObject
 from Object.ResponseObject import ResponseObject
+from Service.CommonService import CommonService
 
 
 class InitView(View):
@@ -56,13 +57,18 @@ class InitView(View):
         LOGGER = logging.getLogger('info')
         username = request_dict.get('username', None)
         password = request_dict.get('password', None)
+        password_version = request_dict.get('pwdVersion', 'V1')
         response = ResponseObject()
         device_user_qs = Device_User.objects.filter(username=username).values('password', 'userID')
         if not device_user_qs.exists():
             return response.json(104)
 
         cipher_password, user_id = device_user_qs[0]['password'], device_user_qs[0]['userID']
-        if not check_password(password, cipher_password):
+        if password_version == 'V1':
+            check_flag = check_password(password, cipher_password)
+        else:
+            check_flag = CommonService.check_password(password, cipher_password)
+        if not check_flag:
             return response.json(111)
         try:
             with transaction.atomic():

+ 6 - 6
Controller/IotCoreController.py

@@ -161,7 +161,7 @@ class IotCoreView(View):
                 return response.json(0, {'res': 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 thing_regroup(request_dict, response):
@@ -245,7 +245,7 @@ class IotCoreView(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 clear_Iot_Cerm(self, request_dict, response):
         serial_number = request_dict.get('serial_number', None)
@@ -282,7 +282,7 @@ class IotCoreView(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 get_s3_pull_key(self, request_dict, response, request):
         # 通用发布主题通知
@@ -311,7 +311,7 @@ class IotCoreView(View):
             return response.json(0, MSG)
         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 get_s3_key_return_msg(self, endpoint):
         MSG = {}
@@ -362,7 +362,7 @@ class IotCoreView(View):
             res = {'endpoint': endpoint, 'token_iot_number': token_iot_number}
             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)))
 
     def pcGetIotInfo(self, request_dict, response):
         # PC工具获取IoT数据
@@ -388,4 +388,4 @@ class IotCoreView(View):
             res = {'endpoint': endpoint, 'token_iot_number': token_iot_number}
             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)))

+ 1 - 1
Controller/MessagePush/EquipmentMessagePush.py

@@ -118,4 +118,4 @@ class EquipmentMessagePushView(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)))

+ 2 - 1
Controller/OTAEquipment.py

@@ -569,7 +569,8 @@ def getNewVerInterface(request):
             result = {
                 'ver': ver,
                 'url': url,
-                "Description": equipment.Description,
+                'Description': equipment.Description,
+                'isPopup': equipment.is_popup
             }
             logger.info('<<<<<响应结果{}'.format(result))
             return response.json(0, result)

+ 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())

+ 1 - 1
Controller/SensorGateway/EquipmentFamilyController.py

@@ -1110,4 +1110,4 @@ class EquipmentFamilyView(View):
 
             return response.json(0, device_dict)
         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)))

+ 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))
+
+
 #
 #                   ___====-_  _-====___
 #             _--^^^#####//      \\#####^^^--_

+ 4 - 4
Controller/SensorGateway/GatewayFamilyRoomController.py

@@ -312,7 +312,7 @@ class GatewayFamilyRoomView(View):
             device_room['sort'] = list(sort)
             return response.json(0, device_room)
         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 devices_sort(request_dict, response):
@@ -339,7 +339,7 @@ class GatewayFamilyRoomView(View):
                         FamilyRoomDevice.objects.filter(sub_device=device_id).update(sort=i)
             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 device_category(request_dict, response):
@@ -363,7 +363,7 @@ class GatewayFamilyRoomView(View):
                     item['category_name'] = '摄像头类'
             return response.json(0, list(family_room_device_qs))
         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 category_sort(request_dict, response):
@@ -390,4 +390,4 @@ class GatewayFamilyRoomView(View):
                         family_room_device_qs.filter(category=category).update(category_sort=category_sort)
             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)))

+ 2 - 2
Controller/SensorGateway/SensorGatewayController.py

@@ -57,7 +57,7 @@ class SensorGateway(View):
             sensor_id = ''.join(random.sample(string.ascii_letters + string.digits, 6))
             return response.json(0, {'sensor_id': sensor_id})
         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 registerToAWSIoTCore(request_dict, response):
@@ -77,4 +77,4 @@ class SensorGateway(View):
         try:
             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)))

+ 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):

+ 352 - 0
Controller/SensorGateway/SmartSwitchController.py

@@ -0,0 +1,352 @@
+# -*- coding: utf-8 -*-
+"""
+# @Author : cheng
+# @Time : 2023/7/10 11:20
+# @File: SmartSwitchController.py
+"""
+
+from django.views import View
+
+from Model.models import SwitchInfo, SwitchDimmingSettings, SwitchChronopher
+from Service.CommonService import CommonService
+
+
+class SmartSwitchView(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):
+        token_code, user_id, response = CommonService.verify_token_get_user_id(request_dict, request)
+        if token_code != 0:
+            return response.json(token_code)
+        if operation == 'get-switch-info': # 设备获取智能开关数据
+            return self.get_switch_info(request_dict, response)
+        elif operation == 'get-switch-setting': # 获取智能开关调光设置
+            return self.get_switch_setting(request_dict, response)
+        elif operation == 'get-chronopher-setting': # 获取定时计划
+            return self.get_chronopher_setting(request_dict, response)
+        elif operation == 'add-or-edit-chronopher': # 添加/编辑定时计划
+            return self.add_or_edit_chronopher(request_dict, response)
+        elif operation == 'delete-chronopher': # 删除定时计划
+            return self.delete_chronopher(request_dict, response)
+        else:
+            return response.json(414)
+
+    @staticmethod
+    def get_switch_info(request_dict, response):
+        """
+        获取智能开关设备信息
+        @param request_dict: 请求参数
+        @request_dict deviceId: 设备id
+        @param response: 响应对象
+        @return: response
+        """
+        device_id = request_dict.get('deviceId', None)
+        if not device_id:
+            return response.json(444)
+        try:
+            switch_info_qs = SwitchInfo.objects.filter(device_id=device_id).values()
+            if not switch_info_qs.exists():
+                return response.json(173)
+            res = {
+                'model': switch_info_qs[0]['model'],
+                'hardwareVersion': switch_info_qs[0]['hardware_version'],
+                'firmwareVersion': switch_info_qs[0]['firmware_version'],
+                'mac': switch_info_qs[0]['mac'],
+            }
+            return response.json(0, res)
+        except Exception as e:
+            print(e)
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
+    @staticmethod
+    def get_switch_setting(request_dict, response, user_id):
+        """
+        获取智能开关设备设置信息
+        @param request_dict: 请求参数
+        @param user_id: 用戶user_id
+        @request_dict deviceId: 设备id
+        @param response: 响应对象
+        @return: response
+        """
+        device_id = request_dict.get('deviceId', None)
+        if not device_id:
+            return response.json(444)
+        try:
+            switch_setting_info_qs = SwitchDimmingSettings.objects.filter(device_id=device_id).values()
+            if not switch_setting_info_qs.exists():
+                return response.json(173)
+            res = {
+                'clickTurnOnSpeed': switch_setting_info_qs[0]['click_turn_on_speed'],
+                'clickTurnOffSpeed': switch_setting_info_qs[0]['click_turn_off_speed'],
+                'doubleClick': switch_setting_info_qs[0]['double_click'],
+                'press': switch_setting_info_qs[0]['press'],
+                'doublePressClickTurnOnSpeed': switch_setting_info_qs[0]['double_press_click_turn_on_speed'],
+                'doublePressClickTurnOffSpeed': switch_setting_info_qs[0]['double_press_click_turn_off_speed'],
+                'led': switch_setting_info_qs[0]['led'],
+                'dimmingCorrection': switch_setting_info_qs[0]['dimming_correction'],
+            }
+            return response.json(0, res)
+        except Exception as e:
+            print(e)
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
+    @staticmethod
+    def edit_switch_setting(request_dict, response):
+        """
+        修改智能开关设备设置
+        @param request_dict: 请求参数
+        @request_dict deviceId: 设备id
+        @request_dict deviceNickname: 设备名称
+        @request_dict location: 位置
+        @request_dict led: LED指示灯
+        @request_dict dimmingCorrection: 调光校正
+        @param response: 响应对象
+        @return: response
+        """
+        device_id = request_dict.get('deviceId', None)
+        device_nick_name = request_dict.get('deviceNickname', None)
+        location = request_dict.get('location', None)
+        led = request_dict.get('led', None)
+        dimming_correction = request_dict.get('dimmingCorrection', None)
+
+        if not device_id:
+            return response.json(444)
+        try:
+            switch_setting_data = {
+                'device_id': device_id,
+                'led': led,
+                'dimming_correction': dimming_correction,
+            }
+            SwitchDimmingSettings.objects.filter(device_id=device_id).update(**switch_setting_data)
+            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)))
+
+    @staticmethod
+    def edit_dimming_setting(request_dict, response):
+        """
+        修改智能开关调光设置
+        @param request_dict: 请求参数
+        @request_dict deviceId: 设备id
+        @request_dict clickTurnOnSpeed: 单击开启速度
+        @request_dict clickTurnOffSpeed: 单击关闭速度
+        @request_dict doubleClick: 双击
+        @request_dict press: 长按
+        @request_dict doublePressClickTurnOnSpeed: 双击/长按开启速度
+        @request_dict doublePressClickTurnOffSpeed: 双击/长按单击关闭速度
+        @param response: 响应对象
+        @return: response
+        """
+        device_id = request_dict.get('deviceId', None)
+        click_turn_on_speed = request_dict.get('clickTurnOnSpeed', None)
+        click_turn_off_speed = request_dict.get('clickTurnOffSpeed', None)
+        double_click = request_dict.get('doubleClick', None)
+        press = request_dict.get('press', None)
+        double_press_click_turn_on_speed = request_dict.get('doublePressClickTurnOnSpeed', None)
+        double_press_click_turn_off_speed = request_dict.get('doublePressClickTurnOffSpeed', None)
+
+        if not device_id:
+            return response.json(444)
+        try:
+            dimming_setting_data = {
+                'device_id': device_id,
+                'click_turn_on_speed': click_turn_on_speed,
+                'click_turn_off_speed': click_turn_off_speed,
+                'double_click': double_click,
+                'press': press,
+                'double_press_click_turn_on_speed': double_press_click_turn_on_speed,
+                'double_press_click_turn_off_speed': double_press_click_turn_off_speed
+            }
+            SwitchDimmingSettings.objects.filter(device_id=device_id).update(**dimming_setting_data)
+            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)))
+
+    @staticmethod
+    def get_location_list(request_dict, response):
+        """
+        获取房间列表
+        @param request_dict: 请求参数
+        @request_dict deviceId: 设备id
+        @param response: 响应对象
+        @return: response
+        """
+        device_id = request_dict.get('deviceId', None)
+        if not device_id:
+            return response.json(444)
+        try:
+            room_list_qs = SwitchDimmingSettings.objects.filter(device_id=device_id).values('location', 'location_list')
+            res = {
+                'location': room_list_qs[0]['location'],
+                'locationList': room_list_qs[0]['location_list']
+            }
+            return response.json(0, res)
+        except Exception as e:
+            print(e)
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
+    @staticmethod
+    def add_location(request_dict, response):
+        """
+        添加房间
+        @param request_dict: 请求参数
+        @request_dict deviceId: 设备id
+        @param response: 响应对象
+        @return: response
+        """
+        room_name = request_dict.get('roomName', None)
+        if not room_name:
+            return response.json(444)
+        try:
+            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)))
+
+    @staticmethod
+    def delete_location(request_dict, response):
+        """
+        删除房间
+        @param request_dict: 请求参数
+        @request_dict deviceId: 设备id
+        @param response: 响应对象
+        @return: response
+        """
+        room_name = request_dict.get('roomName', None)
+        if not room_name:
+            return response.json(444)
+        try:
+            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)))
+
+    @staticmethod
+    def get_chronopher_setting(request_dict, response):
+        """
+        获取定时计划设置
+        @param request_dict: 请求参数
+        @request_dict deviceId: 设备id
+        @param response: 响应对象
+        @return: response
+        """
+        device_id = request_dict.get('deviceId', None)
+        if not device_id:
+            return response.json(444)
+        try:
+            switch_chronopher_qs = SwitchChronopher.objects.filter(device_id=device_id).values()
+            if not switch_chronopher_qs.exists():
+                return response.json(173)
+            switch_chronopher_list = []
+            for item in switch_chronopher_qs:
+                switch_chronopher_list.append({
+                    'chronopherId': item['id'],
+                    'timeTypeRadio': item['time_type_radio'],
+                    'timePoint': item['time_point'],
+                    'timeQuantumStartTime': item['time_quantum_start_time'],
+                    'timeQuantumEndTime': item['time_quantum_end_time'],
+                    'timePointDeviceWillDoing': item['time_point_device_will_doing'],
+                    'timeQuantumDeviceWillDoing': item['time_quantum_device_will_doing'],
+                    'slowOpenOrCloseSpeed': item['slow_open_or_close_speed'],
+                    'repeat': item['repeat'],
+                })
+            return response.json(0, {'list': switch_chronopher_list})
+        except Exception as e:
+            print(e)
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
+    @staticmethod
+    def add_or_edit_chronopher(request_dict, response):
+        """
+        添加/编辑定时计划
+        @param request_dict: 请求参数
+        @request_dict deviceId: 设备id
+        @request_dict chronopherId: 定时计划id
+        @request_dict timeTypeRadio: 切换时间点/时间段
+        @request_dict timePoint: 时间点
+        @request_dict timeQuantumStartTime: 时间段开始时间
+        @request_dict timeQuantumEndTime: 时间段结束时间
+        @request_dict timePointDeviceWillDoing: 设备将会
+        @request_dict timeQuantumDeviceWillDoing: 设备将会
+        @request_dict slowOpenOrCloseSpeed: 缓慢开/关速度
+        @request_dict repeat: 重复周期
+        @param response: 响应对象
+        @return: response
+        """
+        is_edit = request_dict.get('isEdit', None)
+        device_id = request_dict.get('deviceId', None)
+        chronopher_id = request_dict.get('chronopherId', None)
+        time_type_radio = int(request_dict.get('timeTypeRadio', 0))
+        time_point = request_dict.get('timePoint', None)
+        time_quantum_start_time = request_dict.get('timeQuantumStartTime', None)
+        time_quantum_end_time = request_dict.get('timeQuantumEndTime', None)
+        time_point_device_will_doing = request_dict.get('timePointDeviceWillDoing', None)
+        time_quantum_device_will_doing = request_dict.get('timeQuantumDeviceWillDoing', None)
+        slow_open_or_close_speed = request_dict.get('slowOpenOrCloseSpeed', None)
+        repeat = request_dict.get('repeat', None)
+
+        if not all([device_id, time_type_radio, repeat]):
+            return response.json(444)
+        if time_type_radio == 1:
+            if not all([time_point, slow_open_or_close_speed]):
+                return response.json(444)
+            chronopher_data = {
+                'device_id': device_id,
+                'time_type_radio': time_type_radio,
+                'time_point': time_point,
+                'time_point_device_will_doing': time_point_device_will_doing,
+                'slow_open_or_close_speed': slow_open_or_close_speed
+            }
+        else:
+            if not all([time_quantum_start_time, time_quantum_end_time]):
+                return response.json(444)
+            chronopher_data = {
+                'device_id': device_id,
+                'time_type_radio': time_type_radio,
+                'time_quantum_start_time': time_quantum_start_time,
+                'time_quantum_end_time': time_quantum_end_time,
+                'time_quantum_device_will_doing': time_quantum_device_will_doing,
+            }
+        try:
+            if is_edit:
+                if not chronopher_id:
+                    return response.json(444)
+                SwitchChronopher.objects.filter(device_id=device_id, id=chronopher_id).update(**chronopher_data)
+            else:
+                SwitchChronopher.objects.create(**chronopher_data)
+            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)))
+
+    @staticmethod
+    def delete_chronopher(request_dict, response):
+        """
+        删除定时计划
+        @param request_dict: 请求参数
+        @request_dict deviceId: 设备id
+        @request_dict chronopherId: 定时计划id
+        @param response: 响应对象
+        @return: response
+        """
+        device_id = request_dict.get('deviceId', None)
+        chronopher_id = request_dict.get('chronopherId', None)
+
+        if not chronopher_id:
+            return response.json(444, {'error param': 'deviceId or chronopherId'})
+        try:
+            SwitchChronopher.objects.filter(device_id=device_id, id=chronopher_id).delete()
+            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)))

+ 87 - 66
Controller/SensorGateway/SubDeviceController.py

@@ -11,9 +11,10 @@ from django.db import transaction
 from django.db.models import Count, Q
 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_SOS
 from Model.models import Device_Info, GatewaySubDevice, FamilyRoomDevice, SensorRecord, SmartScene, SceneLog, FamilyRoom
 from Service.CommonService import CommonService
+from Object.ResponseObject import ResponseObject
 
 
 class GatewaySubDeviceView(View):
@@ -28,13 +29,25 @@ class GatewaySubDeviceView(View):
         return self.validation(request.POST, request, operation)
 
     def validation(self, request_dict, request, operation):
+
+        if operation == 'update-online-status':  # 更新子设备在线状态
+            response = ResponseObject()
+            return self.update_online_status(request_dict, response)
+
         token_code, user_id, response = CommonService.verify_token_get_user_id(request_dict, request)
         if token_code != 0:
             return response.json(token_code)
-        if operation == 'add':  # 添加子设备
-            return self.add_sub_device(request_dict, user_id, response)
+
+        if operation == 'home':  # 查询传感器主页信息
+            return self.sensor_home_info(request_dict, response)
+        elif operation == 'device-list':  # 获取设备信息
+            return self.get_device_list(request_dict, response)
+        elif operation == 'list':  # 获取子设备信息
+            return self.get_sensor_list(request_dict, response)
         elif operation == 'detail':  # 查询子设备信息
             return self.query_sub_device(request_dict, response)
+        elif operation == 'add':  # 添加子设备
+            return self.add_sub_device(request_dict, user_id, response)
         elif operation == 'update':  # 更新子设备信息
             return self.sensor_update(request_dict, response)
         elif operation == 'delete':  # 删除子设备
@@ -45,14 +58,8 @@ class GatewaySubDeviceView(View):
             return self.records(request_dict, response)
         elif operation == 'records-date':  # 查询传感器记录日期
             return self.records_date(request_dict, response)
-        elif operation == 'home':  # 查询传感器主页信息
-            return self.sensor_home_info(request_dict, response)
         elif operation == 'update-emergency-status':  # 更新智能按钮紧急开关状态
             return self.update_emergency_status(request_dict, response)
-        elif operation == 'list':  # 获取子设备信息
-            return self.get_sensor_list(request_dict, response)
-        elif operation == 'device-list':  # 获取设备信息
-            return self.get_device_list(request_dict, response)
         else:
             return response.json(414)
 
@@ -65,7 +72,6 @@ class GatewaySubDeviceView(View):
         @request_dict deviceType: 设备类型
         @request_dict nickName: 设备名
         @request_dict ieeeAddr: 长地址
-        @request_dict srcAddr: 短地址
         @request_dict mac: mac地址
         @request_dict deviceModel: 设备型号
         @request_dict manufacturer: 制造商
@@ -82,7 +88,6 @@ class GatewaySubDeviceView(View):
         device_type = int(request_dict.get('deviceType', None))
         nickname = request_dict.get('nickName', None)
         ieee_addr = request_dict.get('ieeeAddr', None)
-        src_addr = request_dict.get('srcAddr', None)
         mac = request_dict.get('mac', '')
         device_model = request_dict.get('deviceModel', '')
         manufacturer = request_dict.get('manufacturer', '')
@@ -93,10 +98,10 @@ class GatewaySubDeviceView(View):
         family_id = request_dict.get('familyId', None)
         room_id = request_dict.get('roomId', 0)
 
-        if not all([serial_number, device_type, nickname, src_addr, family_id]):
+        if not all([serial_number, device_type, nickname, family_id]):
             return response.json(444)
         now_time = int(time.time())
-        is_tampered = 1 if device_type == SENSOR_TYPE['smart_button'] else 0  # 智能按钮默认开启紧急开关
+
         try:
             # 查询网关设备数据
             device_info_qs = Device_Info.objects.filter(userID_id=user_id, serial_number=serial_number).values('id')
@@ -106,7 +111,6 @@ class GatewaySubDeviceView(View):
             # 查询是否已添加过该子设备
             sub_device_qs = GatewaySubDevice.objects.filter(device_id=device_id, ieee_addr=ieee_addr)
             if sub_device_qs.exists():
-                sub_device_qs.update(src_addr=src_addr)  # 更新短地址
                 return response.json(174)
             if device_type == SENSOR_TYPE['smart_button']:
                 sub_device_qs = GatewaySubDevice.objects.filter(device_id=device_id, device_type=device_type)
@@ -115,10 +119,10 @@ class GatewaySubDeviceView(View):
 
             with transaction.atomic():
                 sub_device = GatewaySubDevice.objects.create(device_id=device_id, device_type=device_type,
-                                                             nickname=nickname, ieee_addr=ieee_addr, src_addr=src_addr,
-                                                             status=1, mac=mac, device_model=device_model,
+                                                             nickname=nickname, ieee_addr=ieee_addr,
+                                                             mac=mac, device_model=device_model,
                                                              manufacturer=manufacturer, sensor_serial=sensor_serial,
-                                                             firmware_version=firmware_version, is_tampered=is_tampered,
+                                                             firmware_version=firmware_version,
                                                              hardware_version=hardware_version,
                                                              created_time=now_time, updated_time=now_time)
                 if device_type == 216:
@@ -138,7 +142,7 @@ class GatewaySubDeviceView(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 query_sub_device(request_dict, response):
@@ -171,7 +175,7 @@ class GatewaySubDeviceView(View):
                 res['emergency_status'] = gateway_sub_device_qs[0]['is_tampered']
             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 sensor_update(cls, request_dict, response):
@@ -200,7 +204,7 @@ class GatewaySubDeviceView(View):
             return response.json(0)
         except Exception as e:
             print(e.args)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
     def delete_sub_device(request_dict, response):
@@ -226,7 +230,7 @@ class GatewaySubDeviceView(View):
                     scene_log_qs.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)))
 
     @classmethod
     def records_tem_hum(cls, request_dict, response):
@@ -265,7 +269,7 @@ class GatewaySubDeviceView(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_record_dict(cycle, now_time, sub_device_id, event_type):
@@ -379,7 +383,7 @@ class GatewaySubDeviceView(View):
                 return response.json(0, [])
             return response.json(0, list(sensor_record_qs))
         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 records_date(request_dict, response):
@@ -411,7 +415,7 @@ class GatewaySubDeviceView(View):
                 })
             return response.json(0, record_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 sensor_home_info(request_dict, response):
@@ -457,7 +461,7 @@ class GatewaySubDeviceView(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 update_emergency_status(request_dict, response):
@@ -483,52 +487,31 @@ class GatewaySubDeviceView(View):
                 # 更新智能按钮紧急开关状态
                 sub_device_qs.update(is_tampered=emergency_status)
                 # 获取序列号
-                sub_device_qs = sub_device_qs.values('device_id', 'src_addr', 'device__serial_number')
+                sub_device_qs = sub_device_qs.values('device_id', 'ieee_addr', 'device__serial_number')
                 serial_number = sub_device_qs[0]['device__serial_number']
                 topic_name = SMART_SCENE_TOPIC.format(serial_number)
                 gateway_sub_device_qs = GatewaySubDevice.objects.filter(device_id=sub_device_qs[0]['device_id'],
                                                                         device_type=SENSOR_TYPE['smart_button']).values(
-                    'src_addr')
-                sos_count = gateway_sub_device_qs.count()
-                sos_num = 1
-                for index, gateway_sub_device in enumerate(gateway_sub_device_qs):
-                    if sub_device_qs[0]['src_addr'] == gateway_sub_device['src_addr']:
-                        sos_num += index
+                    'ieee_addr')
+
                 # 通知设备修改sos状态
                 msg = {
-                    'sos_count': sos_count,  # 该网关下的智能按钮数量
-                    'sos_num': sos_num,  # 第几个按钮
-                    'sensor_src': int(sub_device_qs[0]['src_addr'], 16),
-                    'sos_select': emergency_status
+                    'scene_event': SCENE_EVENT_SOS,
+                    'ieee_addr': sub_device_qs[0]['ieee_addr'],
+                    'sos': emergency_status
                 }
                 success = CommonService.req_publish_mqtt_msg(serial_number, topic_name, msg)
                 try:
                     assert success
                 except AssertionError:
                     return response.json(10044)
-                time.sleep(0.3)
+
                 # 如果打开紧急开关,关闭已开启的场景
                 if emergency_status == 1:
-                    smart_scene_qs = SmartScene.objects.filter(sub_device_id=sub_device_id, is_enable=True)
-                    if not smart_scene_qs.exists():
-                        return response.json(0)
-                    for smart_scene in smart_scene_qs:
-                        # 通知设备关闭场景
-                        msg = {
-                            'scene_id': smart_scene.id,
-                            'scene_status': 0
-                        }
-                        success = CommonService.req_publish_mqtt_msg(serial_number, topic_name, msg)
-                        try:
-                            assert success
-                        except AssertionError:
-                            return response.json(10044)
-                        time.sleep(0.3)
-                    smart_scene_qs.update(is_enable=False)
-
+                    SmartScene.objects.filter(sub_device_id=sub_device_id, is_enable=True).update(is_enable=False)
             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_sensor_list(request_dict, response):
@@ -554,14 +537,14 @@ class GatewaySubDeviceView(View):
                 room_qs = FamilyRoom.objects.filter(id=item['room_id']).values('name')
                 room_name = room_qs[0]['name'] if room_qs.exists() else ''
                 device_qs = GatewaySubDevice.objects.filter(id=item['sub_device']).values('id', 'nickname',
-                                                                                          'device_type', 'src_addr',
+                                                                                          'device_type', 'ieee_addr',
                                                                                           'status', 'created_time')
                 if device_qs.exists():
                     res = {
                         'gatewaySubId': device_qs[0]['id'],
                         'nickName': device_qs[0]['nickname'],
                         'deviceType': device_qs[0]['device_type'],
-                        'srcAddr': device_qs[0]['src_addr'],
+                        'srcAddr': device_qs[0]['ieee_addr'],
                         'status': device_qs[0]['status'],
                         'createdTime': device_qs[0]['created_time'],
                         'roomName': room_name,
@@ -570,7 +553,7 @@ class GatewaySubDeviceView(View):
                     device_list.append(res)
             return response.json(0, device_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_device_list(request_dict, response):
@@ -589,19 +572,21 @@ class GatewaySubDeviceView(View):
         try:
             family_room_device_qs = FamilyRoomDevice.objects.filter(family_id=family_id, sub_device=0,
                                                                     device__Type=200).values(
-                'device_id', 'device__NickName').order_by('-device__data_joined')
+                'device_id', 'device__NickName', 'device__serial_number').order_by('-device__data_joined')
             if room_id:
                 family_room_device_qs = family_room_device_qs.filter(room_id=room_id)
             device_list = []
             for item in family_room_device_qs:
+                device_id = item['device_id']
+                serial_number = item['device__serial_number']
                 device_dict = {
-                    'deviceId': item['device_id'],
                     'deviceType': 200,
-                    'deviceNickName': item['device__NickName'],
+                    'deviceId': device_id,
+                    'deviceNickName': item['device__NickName']
                 }
                 sub_device = []
                 family_room_sub_device_qs = FamilyRoomDevice.objects.filter(Q(family_id=family_id), ~Q(sub_device=0),
-                                                                            Q(device_id=item['device_id'])).values(
+                                                                            Q(device_id=device_id)).values(
                     'sub_device', 'room_id').order_by('sort')
                 if family_room_sub_device_qs.exists():
                     for each in family_room_sub_device_qs:
@@ -609,7 +594,7 @@ class GatewaySubDeviceView(View):
                         room_name = room_qs[0]['name'] if room_qs.exists() else ''
                         device_qs = GatewaySubDevice.objects.filter(id=each['sub_device']).values('id', 'nickname',
                                                                                                   'device_type',
-                                                                                                  'src_addr',
+                                                                                                  'ieee_addr',
                                                                                                   'status',
                                                                                                   'created_time')
                         if device_qs.exists():
@@ -617,17 +602,53 @@ class GatewaySubDeviceView(View):
                                 'gatewaySubId': device_qs[0]['id'],
                                 'nickName': device_qs[0]['nickname'],
                                 'deviceType': device_qs[0]['device_type'],
-                                'srcAddr': device_qs[0]['src_addr'],
+                                'srcAddr': device_qs[0]['ieee_addr'],
                                 'status': device_qs[0]['status'],
                                 'createdTime': device_qs[0]['created_time'],
                                 'roomName': room_name,
-                                'familyId': family_id
+                                'familyId': family_id,
+                                'serialNumber': serial_number
                             })
                     device_dict['subDevice'] = sub_device
                     device_list.append(device_dict)
             return response.json(0, device_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_online_status(request_dict, response):
+        """
+        更新子设备在线状态
+        @param request_dict: 请求参数
+        @request_dict online: 在线状态, 0:离线, 1:在线, 2:复位
+        @request_dict ieee_addr: 长地址
+        @param response: 响应对象
+        @return: response
+        """
+        online = request_dict.get('online', None)
+        ieee_addr = request_dict.get('ieee_addr', None)
+
+        if not all([online, ieee_addr]):
+            return response.json(444, {'error param': 'online or ieee_addr'})
+        online = int(online)
+        try:
+            if online == 2:     # 复位删除设备
+                gateway_sub_device_qs = GatewaySubDevice.objects.filter(ieee_addr=ieee_addr)
+                if not gateway_sub_device_qs.exists():
+                    return response.json(0)
+                sub_device_id = gateway_sub_device_qs.values('id')[0]['id']
+                # 删除设备信息,场景信息,场景日志
+                with transaction.atomic():
+                    gateway_sub_device_qs.delete()
+                    SmartScene.objects.filter(sub_device_id=sub_device_id).delete()
+                    SceneLog.objects.filter(sub_device_id=sub_device_id).delete()
+            else:
+                GatewaySubDevice.objects.filter(ieee_addr=ieee_addr).update(status=online)
+            return response.json(0)
+        except Exception as e:
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
+
 #
 #                   ___====-_  _-====___
 #             _--^^^#####//      \\#####^^^--_

+ 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
-

+ 1 - 1
Controller/Surveys/CloudStorageController.py

@@ -100,7 +100,7 @@ class CloudStorageView(View):
             return response.json(0, 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)))
 
     @classmethod
     def surveys_user_log_save(cls, status=False, userId='', survey_type=1):

+ 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)

+ 10 - 6
Controller/TestController.py

@@ -6,6 +6,7 @@ from django.contrib.auth.hashers import make_password, check_password
 from django.views import View
 
 from Object.uidManageResponseObject import uidManageResponseObject
+from Service.CommonService import CommonService
 
 
 class TestView(View):
@@ -35,19 +36,22 @@ class TestView(View):
 
     def do_create_password(self, request_dict, response):
         password = request_dict.get('password', None)
-        print(password)
-        result = make_password(password)
-        print(result)
-        print(check_password(password, result))
+        password_version = request_dict.get('pwdVersion', 'V1')
+        if password_version == 'V1':
+            password = make_password(password)
+        result = password
         return response.json(0, result)
 
     def do_check_password(self, request_dict, response):
         password = request_dict.get('password', None)
         password2 = request_dict.get('password2', None)
+        password_version = request_dict.get('pwdVersion', 'V1')
         print(password)
         print(password2)
-        check = check_password(password, password2)
-
+        if password_version == 'V1':
+            check = check_password(password, password2)
+        else:
+            check = CommonService.check_password(password, password2)
         return response.json(0, check)
 
     # def make_password(self, password):

+ 2 - 2
Controller/UidSetController.py

@@ -509,7 +509,7 @@ class UidSetView(View):
                     Device_Info.objects.filter(UID=uid).update(vodPrimaryUserID='', vodPrimaryMaster='')
             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)
 
@@ -535,7 +535,7 @@ class UidSetView(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 do_test(self, response):
     #     di_qs = Device_Info.objects.values('Type').annotate(c=Count('UID', distinct=True)).order_by()

+ 55 - 0
Controller/UnicomCombo/UnicomComboTaskController.py

@@ -59,6 +59,10 @@ class UnicomComboTaskView(View):
             return self.query_flow_used_history(response)
         elif operation == 'queryFlowCache':
             return self.query_flow_cache(response)
+        elif operation == 'getDeviceUsageHistory':
+            return self.get_device_usage_history(response)
+        else:
+            return response.json(414)
 
     @classmethod
     def check_activate_combo(cls, request_dict, response):
@@ -422,3 +426,54 @@ class UnicomComboTaskView(View):
         except Exception as e:
             logger.info('出错了~次月激活套餐异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
             return response.json(177, repr(e))
+
+    @staticmethod
+    def get_device_usage_history(response):
+        """
+        查询联通设备历史用量
+        """
+        card_qs = UnicomDeviceInfo.objects.filter(card_type=0).values('iccid')
+        if not card_qs.exists():
+            return response.json(0)
+        asy = threading.Thread(target=UnicomComboTaskView.async_update_device_usage_history, args=(card_qs,))
+        asy.start()
+        return response.json(0)
+
+    @staticmethod
+    def async_update_device_usage_history(qs):
+        """
+        异步更新设备用量历史
+        @param qs: 联通iccid集合
+        """
+        try:
+            u_service = UnicomObjeect()
+            iot_card_list = []
+            now_time = int(time.time())
+            # 获取当前时间
+            current_date = datetime.datetime.now()
+            # 计算上个月的时间
+            last_month_date = current_date - datetime.timedelta(days=current_date.day)
+            # 例格式化日期为 "202307"
+            formatted_date = last_month_date.strftime('%Y%m')
+            for item in qs:
+                params = {'iccid': item['iccid']}
+                result = u_service.query_device_usage_history(**params)
+                res_dict = u_service.get_text_dict(result)
+                if res_dict['code'] == 0 and res_dict['data']:
+                    for cycle in res_dict['data']:
+                        if cycle['flowTotalUsage'] <= 0 or cycle['cycle'] != int(formatted_date):
+                            continue
+                        iot_card_list.append(IotCardUsageHistory(
+                            iccid=item['iccid'],
+                            card_type=1,
+                            cycle=cycle['cycle'],
+                            flow_total_usage=cycle['flowTotalUsage'],
+                            created_time=now_time,
+                            updated_time=now_time
+                        ))
+            if not iot_card_list:
+                return None
+            IotCardUsageHistory.objects.bulk_create(iot_card_list)
+        except Exception as e:
+            logger.info('查询账期流量异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            return None

Разлика између датотеке није приказан због своје велике величине
+ 304 - 195
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):

+ 1 - 1
Controller/VPGController.py

@@ -274,4 +274,4 @@ def do_upload_uid(request):
         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)))

+ 144 - 4
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)
@@ -1383,6 +1385,7 @@ class UidSetModel(models.Model):
     tb_country = 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'
@@ -1401,6 +1404,7 @@ class UidPushModel(models.Model):
     push_type = models.IntegerField(default=0,
                                     verbose_name=u'推送类型')  # 0: apns, 1: 安卓gcm, 2: 极光, 3:华为, 4:小米, 5:vivo, 6:oppo, 7:魅族
     token_val = models.CharField(default='', max_length=500, verbose_name=u'设备验证令牌')
+    jg_token_val = models.CharField(default='', max_length=500, verbose_name=u'极光推送令牌')
     m_code = models.CharField(default='', max_length=64, verbose_name='手机唯一标识')
     addTime = models.IntegerField(verbose_name='添加时间', default=0)
     updTime = models.IntegerField(verbose_name='更新时间', default=0)
@@ -2759,7 +2763,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地址')
@@ -3534,6 +3538,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='兑换码')
@@ -3553,6 +3609,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号')

+ 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 []

+ 1 - 1
Object/IOTCore/IotObject.py

@@ -140,4 +140,4 @@ class IOTClient:
             return res, parameters
         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)))

+ 4 - 1
Object/ResponseObject.py

@@ -1,4 +1,3 @@
-from django.shortcuts import HttpResponse
 import simplejson as json
 from django.shortcuts import HttpResponse
 
@@ -78,6 +77,8 @@ class ResponseObject(object):
             904: 'Version does not support this feature!',
             906: 'Cause of file operation error',
             907: 'The download file does not exist!',
+            910: 'Icloud Insufficient capacity!',
+            911: 'No opened Icloud',
             10001: 'Customer number, customer confidentiality error',
             10002: 'Check your configuration: no customer number, customer confidentiality',
             10003: 'The authorization code does not exist. Please reauthorize',
@@ -195,6 +196,8 @@ class ResponseObject(object):
             904: '版本不支持本功能!',
             906: '文件操作错误',
             907: '文件不存在!',
+            910: '云盘容量不足!',
+            911: '未开通云盘!',
             10001: '客户编号,客户机密错误',
             10002: '检查您的配置:没有客户编号,客户机密',
             10003: '授权码不存在,请重新授权',

+ 52 - 4
Service/CommonService.py

@@ -5,6 +5,7 @@ import time
 from base64 import encodebytes
 from pathlib import Path
 from random import Random
+from distutils.version import LooseVersion
 
 import OpenSSL.crypto as ct
 import requests
@@ -12,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
 
@@ -549,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
         """
@@ -656,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')))
@@ -727,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):
@@ -737,4 +760,29 @@ GCqvlyw5dfxNA+EtxNE2wCW/LW7ENJlACgcfgPlBZtpLheWoZB/maw4=
         if any(i < 0 for i in number_list):
             return False
         else:
-            return True
+            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):
+        """
+        比对版本号大小
+        @param version_number: 版本号
+        @param version_number_list: 版本号列表
+        """
+        version_list = []
+        input_version = LooseVersion(version_number)
+        for version in version_number_list:
+            version = LooseVersion(version)
+            if input_version >= version:
+                version_list.append(version)
+            else:
+                continue
+        return version_list


+ 0 - 15
us_test_manage.py

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

Неке датотеке нису приказане због велике количине промена