Przeglądaj źródła

Merge remote-tracking branch 'origin/master'

lhq 4 lat temu
rodzic
commit
93cc715e25
100 zmienionych plików z 14553 dodań i 2336 usunięć
  1. 1 0
      .gitignore
  2. 16 0
      Ansjer/asgi.py
  3. 276 31
      Ansjer/config.py
  4. 76 13
      Ansjer/config_formal.py
  5. 14 8
      Ansjer/config_local.py
  6. 72 0
      Ansjer/config_test.py
  7. 68 0
      Ansjer/file/apns_pem/ZhouShi-dev.pem
  8. 68 0
      Ansjer/file/apns_pem/customizedc.pem
  9. 33 17
      Ansjer/formal_settings.py
  10. 27 0
      Ansjer/formal_statistics_push_day_task.py
  11. 27 0
      Ansjer/formal_statistics_push_month_task.py
  12. 49 0
      Ansjer/formal_zositech_help_weekly_task.py
  13. 46 0
      Ansjer/generacode.py
  14. 52 12
      Ansjer/local_settings.py
  15. 27 0
      Ansjer/push_element_into_redis.py
  16. 199 0
      Ansjer/pushconfig.py
  17. 38 9
      Ansjer/test_settings.py
  18. 27 0
      Ansjer/test_statistics_push_day_task.py
  19. 27 0
      Ansjer/test_statistics_push_month_task.py
  20. 48 0
      Ansjer/test_zositech_help_weekly_task.py
  21. 83 5
      Ansjer/urls.py
  22. 16 0
      Ansjer/wsgi.py
  23. 2 0
      Controller/AccessLog.py
  24. 206 3
      Controller/AdminManage.py
  25. 19 3
      Controller/AppSetController.py
  26. 258 0
      Controller/CDKController.py
  27. 699 485
      Controller/CloudStorage.py
  28. 202 0
      Controller/CloudTransfer.py
  29. 404 699
      Controller/CloudVod.py
  30. 180 0
      Controller/Cloudsum.py
  31. 237 0
      Controller/CompanyController.py
  32. 371 372
      Controller/DateController.py
  33. 553 188
      Controller/DetectController.py
  34. 1195 0
      Controller/DetectControllerV2.py
  35. 89 0
      Controller/DeviceConfirmRegion.py
  36. 23 2
      Controller/DeviceShare.py
  37. 117 0
      Controller/DeviceTypeController.py
  38. 21 8
      Controller/EquipmentInfo.py
  39. 214 23
      Controller/EquipmentManager.py
  40. 184 11
      Controller/EquipmentManagerV2.py
  41. 656 249
      Controller/EquipmentManagerV3.py
  42. 29 12
      Controller/EquipmentOTA.py
  43. 12 1
      Controller/EquipmentStatus.py
  44. 74 5
      Controller/FAQController.py
  45. 35 0
      Controller/FeedBack.py
  46. 541 0
      Controller/FileController.py
  47. 402 0
      Controller/HistoryUIDController.py
  48. 312 0
      Controller/IotCoreController.py
  49. 97 0
      Controller/LanguageController.py
  50. 99 0
      Controller/LogController.py
  51. 166 25
      Controller/MealManage.py
  52. 80 9
      Controller/OTAEquipment.py
  53. 77 0
      Controller/OperatingLogs.py
  54. 161 9
      Controller/OrderContrller.py
  55. 104 0
      Controller/OrderTaskController.py
  56. 64 0
      Controller/ProcessInfo.py
  57. 295 0
      Controller/RegionController.py
  58. 46 0
      Controller/RegionCountryController.py
  59. 98 0
      Controller/S3GetStsController.py
  60. 107 0
      Controller/SalesController.py
  61. 403 0
      Controller/SerialNumberController.py
  62. 157 0
      Controller/ShadowController.py
  63. 122 1
      Controller/StatisticsController.py
  64. 2 2
      Controller/SysManage.py
  65. 0 1
      Controller/SysMsg.py
  66. 75 6
      Controller/TestApi.py
  67. 63 0
      Controller/TestController.py
  68. 708 0
      Controller/TestDetectController.py
  69. 489 0
      Controller/UIDController.py
  70. 296 0
      Controller/UIDManageUserController.py
  71. 99 1
      Controller/UidSetController.py
  72. 164 85
      Controller/UserController.py
  73. 270 0
      Controller/VPGController.py
  74. 121 0
      Controller/VerifyCodeController.py
  75. 13 8
      Controller/VodBucket.py
  76. 372 0
      Controller/VoicePromptController.py
  77. 2 2
      Controller/shareUserPermission.py
  78. 0 0
      Model/__init__.py
  79. 568 27
      Model/models.py
  80. 3 0
      Model/tests.py
  81. 3 0
      Model/views.py
  82. 52 0
      Object/AWS/S3Email.py
  83. 20 0
      Object/AliSmsObject.py
  84. 3 0
      Object/ETkObject.py
  85. 180 0
      Object/IOTCore/IotObject.py
  86. 17 0
      Object/LogUtil.py
  87. 210 0
      Object/LogsObject.py
  88. 7 0
      Object/RedisObject.py
  89. 58 0
      Object/ResponseObject.py
  90. 24 4
      Object/TokenObject.py
  91. 201 0
      Object/WechatPayObject.py
  92. 115 0
      Object/uidManageResponseObject.py
  93. 0 0
      PushModel/__init__.py
  94. 3 0
      PushModel/admin.py
  95. 5 0
      PushModel/apps.py
  96. 0 0
      PushModel/migrations/__init__.py
  97. 3 0
      PushModel/models.py
  98. 3 0
      PushModel/tests.py
  99. 3 0
      PushModel/views.py
  100. 0 0
      SerialModel/__init__.py

+ 1 - 0
.gitignore

@@ -11,6 +11,7 @@
 */__pycache__
 */__pycache__
 /Ansjer/test/__pycache__
 /Ansjer/test/__pycache__
 /Ansjer/test/__init__.py
 /Ansjer/test/__init__.py
+/static/log/error.log
 /sdk_install
 /sdk_install
 /DB/mydata4vipday2.ipdb
 /DB/mydata4vipday2.ipdb
 /venv
 /venv

+ 16 - 0
Ansjer/asgi.py

@@ -0,0 +1,16 @@
+"""
+ASGI config for AnsjerUIDManage project.
+
+It exposes the ASGI callable as a module-level variable named ``application``.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/3.0/howto/deployment/asgi/
+"""
+
+import os
+
+from django.core.asgi import get_asgi_application
+
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'AnsjerUIDManage.settings')
+
+application = get_asgi_application()

+ 276 - 31
Ansjer/config.py

@@ -1,5 +1,5 @@
-#!/usr/bin/env python3  
-# -*- coding: utf-8 -*-  
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
 """
 """
 @Copyright (C) ansjer cop Video Technology Co.,Ltd.All rights reserved.
 @Copyright (C) ansjer cop Video Technology Co.,Ltd.All rights reserved.
 @AUTHOR: ASJRD018
 @AUTHOR: ASJRD018
@@ -32,6 +32,8 @@ SES_COMPANY_EMAIL = 'user_server@nsst.com'
 AWS_SES_ACCESS_ID = 'AKIAJKPU23EU5QWHFPKQ'
 AWS_SES_ACCESS_ID = 'AKIAJKPU23EU5QWHFPKQ'
 AWS_SES_ACCESS_SECRET = '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'
 AWS_SES_ACCESS_SECRET = 'oYJsF4h95ITWf3bxpPf5uUTvULPrq8DhRaQQzTjf'
 AWS_SES_ACCESS_REGION = 'us-east-1'
 AWS_SES_ACCESS_REGION = 'us-east-1'
+AWS_SES_ACCESS_REGION_WEST = 'us-west-1'
+
 AWS_BUCKET = 'ansjertest'
 AWS_BUCKET = 'ansjertest'
 # 设定离线时间为5分钟
 # 设定离线时间为5分钟
 OFF_LINE_TIME_DELTA = 5
 OFF_LINE_TIME_DELTA = 5
@@ -67,6 +69,11 @@ OSS_STS_ACCESS_KEY = 'LTAIyMkGfEdogyL9'
 OSS_STS_ACCESS_SECRET = '71uIjpsqVOmF7DAITRyRuc259jHOjO'
 OSS_STS_ACCESS_SECRET = '71uIjpsqVOmF7DAITRyRuc259jHOjO'
 OSS_ROLE_ARN = 'acs:ram::1901342792446414:role/stsoss'
 OSS_ROLE_ARN = 'acs:ram::1901342792446414:role/stsoss'
 
 
+# aws api key
+AWS_ACCESS_KEY_ID = ['AKIA2MMWBR4DSFG67DTG','AKIA2E67UIMD45Y3HL53']  #0国内, 1国外
+AWS_SECRET_ACCESS_KEY = ['aI9gxcAKPmiGgPy9axrtFKzjYGbvpuytEX4xWweL','ckYLg4Lo9ZXJIcJEAKkzf2rWvs8Xth1FCjqiAqUw']
+AWS_ARN = ['arn:aws-cn:s3','arn:aws:s3']
+
 # 不同环境配置
 # 不同环境配置
 if SERVER_TYPE == 'Ansjer.local_settings':
 if SERVER_TYPE == 'Ansjer.local_settings':
     from Ansjer.config_local import *
     from Ansjer.config_local import *
@@ -74,6 +81,220 @@ elif SERVER_TYPE == 'Ansjer.test_settings':
     from Ansjer.config_test import *
     from Ansjer.config_test import *
 elif SERVER_TYPE == 'Ansjer.formal_settings':
 elif SERVER_TYPE == 'Ansjer.formal_settings':
     from Ansjer.config_formal import *
     from Ansjer.config_formal import *
+
+
+DEVICE_TYPE = {
+    0: 'UNKOWN',
+    1: 'DVR',
+    2: 'NVR',
+    3: 'POENVR',
+    4: 'WIRELESSNVR',
+    5: 'POEIPC',
+    6: 'BOLTIPC',
+    7: 'IPC',
+    8: 'KAPIANJI',
+    9: 'FISHEYE',
+    10: 'C512',
+    11: 'C611',
+    12: 'C612',
+    13: 'C199',
+    14: 'C190',
+    15: 'C199_PRO',
+    17: 'C289',
+    18: 'C308',
+    10001: 'DVRPTZ'
+}
+
+APP_FREQUENT = {
+    0: 'UNKOWN',
+    1: '每天',
+    2: '三天',
+    3: '一周',
+    4: '两周',
+    5: '一个月',
+    6: '一个月以上',
+
+}
+
+# Iot Core国外
+AWS_IOT_SES_ACCESS_FOREIGN_ID = 'AKIA2E67UIMD62VUBV5I'
+AWS_IOT_SES_ACCESS_FOREIGN_SECRET = '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'
+AWS_IOT_SES_ACCESS_FOREIGN_REGION_AMERICA = 'us-east-1'
+AWS_IOT_SES_ACCESS_FOREIGN_REGION_ASIA = 'ap-southeast-1'
+AWS_IOT_SES_ACCESS_FOREIGN_REGION_EUROPE = 'eu-west-1'
+AWS_IOT_SES_ACCESS_FOREIGN_ROLE = 'arn:aws:iam::697864307463:role/Ansjer_Iot_Admin'
+
+
+# Iot Core国内
+AWS_IOT_SES_ACCESS_CHINA_ID = 'AKIA2MMWBR4DUUYPCFNJ'
+AWS_IOT_SES_ACCESS_CHINA_SECRET = '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'
+AWS_IOT_SES_ACCESS_CHINA_REGION = 'cn-northwest-1'
+AWS_IOT_SES_ACCESS_CHINA_ROLE = 'arn:aws-cn:iam::713816116999:role/service-role/Ansjer_Iot_Admin'
+
+IOT_HOST = {
+    1: 'a250bbr0p9u7as-ats.iot.cn-northwest-1.amazonaws.com.cn',
+    2: 'a2rqy12o004ad8-ats.iot.ap-southeast-1.amazonaws.com',
+    3: 'a2rqy12o004ad8-ats.iot.eu-west-1.amazonaws.com',
+    4: 'a2rqy12o004ad8-ats.iot.us-east-1.amazonaws.com'
+}
+ONLINE_DEVICE = 1000000
+
+SALES = {
+    2020: [
+        {
+            'name': 'United States',
+            'value': [3768901, 23.337, '美国']
+        },
+        {
+            'name': 'Japan',
+            'value': [1886988, 9.027, '日本']
+        },
+        {
+            'name': 'Russia',
+            'value': [1940038, 7.923, '俄国']
+        },
+        {
+            'name': 'Germany',
+            'value': [1319651, 6.253, '德国']
+        },
+        {
+            'name': 'France',
+            'value': [1291157, 5.825, '法国']
+        },
+        {
+            'name': 'United Kingdom',
+            'value': [1041917, 4.567, '英国']
+        },
+        {
+            'name': 'Italy',
+            'value': [859811, 3.875, '意大利']
+        }
+    ],
+    2019: [
+        {
+            'name': 'United States',
+            'value': [2768900, 37.374, '美国']
+        },
+        {
+            'name': 'Japan',
+            'value': [1086988, 14.672, '日本']
+        },
+        {
+            'name': 'Russia',
+            'value': [940038, 12.689, '俄国']
+        },
+        {
+            'name': 'Germany',
+            'value': [919651, 12.413, '德国']
+        },
+        {
+            'name': 'France',
+            'value': [691157, 9.329, '法国']
+        },
+        {
+            'name': 'United Kingdom',
+            'value': [541917, 7.315, '英国']
+        },
+        {
+            'name': 'Italy',
+            'value': [459811, 6.206, '意大利']
+        }
+    ],
+    2018: [
+        {
+            'name': 'United States',
+            'value': [2068912, 32.329, '美国']
+        },
+        {
+            'name': 'Japan',
+            'value': [1007988, 15.751, '日本']
+        },
+        {
+            'name': 'Germany',
+            'value': [909653, 14.214, '德国']
+        },
+        {
+            'name': 'Russia',
+            'value': [900038, 14.064, '俄国']
+        },
+
+        {
+            'name': 'France',
+            'value': [601158, 9.394, '法国']
+        },
+        {
+            'name': 'United Kingdom',
+            'value': [501920, 7.843, '英国']
+        },
+        {
+            'name': 'Italy',
+            'value': [409813, 6.404, '意大利']
+        }
+    ],
+    2017: [
+        {
+            'name': 'United States',
+            'value': [1668900, 30.914, '美国']
+        },
+        {
+            'name': 'Japan',
+            'value': [906988, 16.800, '日本']
+        },
+        {
+            'name': 'Germany',
+            'value': [809651, 14.998, '德国']
+        },
+        {
+            'name': 'Russia',
+            'value': [800038, 14.820, '俄国']
+        },
+        {
+            'name': 'France',
+            'value': [501157, 9.283, '法国']
+        },
+        {
+            'name': 'United Kingdom',
+            'value': [401920, 7.445, '英国']
+        },
+        {
+            'name': 'Italy',
+            'value': [309822, 5.739, '意大利']
+        }
+    ],
+    2016: [
+        {
+            'name': 'United States',
+            'value': [1468900, 31.943, '美国']
+        },
+        {
+            'name': 'Japan',
+            'value': [806988, 17.549, '日本']
+        },
+        {
+            'name': 'Germany',
+            'value': [709651, 15.432, '德国']
+        },
+        {
+            'name': 'Russia',
+            'value': [700038, 15.223, '俄国']
+        },
+
+        {
+            'name': 'France',
+            'value': [401157, 8.724, '法国']
+        },
+        {
+            'name': 'United Kingdom',
+            'value': [301917, 6.566, '英国']
+        },
+        {
+            'name': 'Italy',
+            'value': [209811, 4.562, '意大利']
+        }
+    ]
+
+}
+
 # type =2
 # type =2
 JPUSH_CONFIG = {
 JPUSH_CONFIG = {
     'com.ansjer.accloud_ab': {
     'com.ansjer.accloud_ab': {
@@ -126,35 +347,59 @@ FCM_CONFIG = {
     'com.ansjer.accloud_a': 'AAAAb9YP3rk:APA91bFm06w8b9OKQ0gz0iaWFuRqRIkvgAz6z7Gp3dBU_X-LNGJQd1hc1QR2W7QzBglF8SHtERA45a2lbdLRa5qv7hxfd6W_sJLBK7dA8jklsOQBvy505oUzTwMKWy4TwH-exps9KrhO',
     'com.ansjer.accloud_a': 'AAAAb9YP3rk:APA91bFm06w8b9OKQ0gz0iaWFuRqRIkvgAz6z7Gp3dBU_X-LNGJQd1hc1QR2W7QzBglF8SHtERA45a2lbdLRa5qv7hxfd6W_sJLBK7dA8jklsOQBvy505oUzTwMKWy4TwH-exps9KrhO',
     'com.ansjer.zccloud_ab': 'AAAAb9YP3rk:APA91bHu8u-CTpcd0g6lKPo0WNVqCi8jZub1cPPbSAY9AucT1HxlF65ZDUko9iG8q2ch17bwu9YWHpK1xI1gHSRXCslLvZlXEmHZC0AG3JKg15XuUvlFKACIajUFV-pOeGRT8tM6-31I',
     'com.ansjer.zccloud_ab': 'AAAAb9YP3rk:APA91bHu8u-CTpcd0g6lKPo0WNVqCi8jZub1cPPbSAY9AucT1HxlF65ZDUko9iG8q2ch17bwu9YWHpK1xI1gHSRXCslLvZlXEmHZC0AG3JKg15XuUvlFKACIajUFV-pOeGRT8tM6-31I',
 }
 }
-
-DEVICE_TYPE = {
-    0: 'UNKOWN',
-    1: 'DVR',
-    2: 'NVR',
-    3: 'POENVR',
-    4: 'WIRELESSNVR',
-    5: 'POEIPC',
-    6: 'BOLTIPC',
-    7: 'IPC',
-    8: 'KAPIANJI',
-    9: 'FISHEYE',
-    10: 'C512',
-    11: 'C611',
-    12: 'C612',
-    13: 'C199',
-    14: 'C190',
-    15: 'C199_PRO',
-    17: 'C289',
-    10001: 'DVRPTZ'
+APNS_CONFIG = {
+    'com.ansjer.loocamccloud': {
+        'pem_path': 'AnsjerPush/file/apns_pem/lcc-dev.pem',
+    },
+    'com.ansjer.zosidcloud': {
+        'pem_path': 'AnsjerPush/file/apns_pem/zosidcloud-dev.pem',
+    },
+    'com.ansjer.customizedb': {
+        'pem_path': 'AnsjerPush/file/apns_pem/customizedb-dev.pem',
+    },
+    'com.ansjer.customizeda': {
+        'pem_path': 'AnsjerPush/file/apns_pem/customizeda-dev.pem',
+    },
+    'com.ansjer.zccloud': {
+        'pem_path': 'AnsjerPush/file/apns_pem/zccloud-dev.pem',
+    },
+    'com.ansjer.accloud': {
+        'pem_path': 'AnsjerPush/file/apns_pem/accloud-dev.pem',
+    },
+    'com.ansjer.customizedc':{
+        'pem_path': 'AnsjerPush/file/apns_pem/customizedc.pem',
+    },
+    'com.ansjer.customizede': {
+        'pem_path': 'AnsjerPush/file/apns_pem/customizede.pem',
+    },
 }
 }
+APNS_MODE = 'dev'
+SERVER_TYPE = os.environ.get('DJANGO_SETTINGS_MODULE')
 
 
-APP_FREQUENT = {
-    0: 'UNKOWN',
-    1: '每天',
-    2: '三天',
-    3: '一周',
-    4: '两周',
-    5: '一个月',
-    6: '一个月以上',
-
+JPUSH_CODE = {
+    -1: '只库存不推送',
+    200: '推送成功',
+    400: '错误请求',
+    401: '没有验证信息或者验证失败',
+    403: '请求被拒绝',
+    404: '资源不存在,请求的用户的不存在,请求的格式不被支持',
+    405: '请求方法不合适',
+    410: '请求的资源已下线',
+    429: '请求超出了频率限制',
+    500: '极光内部服务错误',
+    502: '业务服务器下线了或者正在升级。请稍后重试',
+    503: '服务暂时失效',
+    504: '代理超时'
+}
+APNS_CODE = {
+    -1: '只库存不推送',
+    200: '推送成功',
+    400: '请求有问题',
+    403: '证书或Token有问题',
+    405: '请求方式不正确, 只支持POST请求',
+    410: '设备的Token与证书不一致'
+}
+APP_TYPE = {
+    1: 'ios',
+    2: 'android'
 }
 }

+ 76 - 13
Ansjer/config_formal.py

@@ -11,6 +11,8 @@
 @file: config_formal.py
 @file: config_formal.py
 @Contact: chanjunkai@163.com
 @Contact: chanjunkai@163.com
 """
 """
+import os
+
 NGINX_RTMP_STAT = 'http://www.dvema.com/stat'
 NGINX_RTMP_STAT = 'http://www.dvema.com/stat'
 SERVER_DOMAIN_SSL = 'https://www.dvema.com/'
 SERVER_DOMAIN_SSL = 'https://www.dvema.com/'
 SERVER_DOMAIN = 'http://www.dvema.com/'
 SERVER_DOMAIN = 'http://www.dvema.com/'
@@ -21,40 +23,101 @@ PAYPAL_CRD = {
     "client_id": "AdSRd6WBn-qLl9OiQHQuNYTDFSx0ZX0RUttqa58au8bPzoGYQUrt8bc6591RmH8_pEAIPijdvVYSVXyI",
     "client_id": "AdSRd6WBn-qLl9OiQHQuNYTDFSx0ZX0RUttqa58au8bPzoGYQUrt8bc6591RmH8_pEAIPijdvVYSVXyI",
     "client_secret": "ENT-J08N3Fw0B0uAokg4RukljAwO9hFHPf8whE6-Dwd8oBWJO8AWMgpdTKpfB1pOy89t4bsFEzMWDowm"
     "client_secret": "ENT-J08N3Fw0B0uAokg4RukljAwO9hFHPf8whE6-Dwd8oBWJO8AWMgpdTKpfB1pOy89t4bsFEzMWDowm"
 }
 }
+# PAYPAL_CRD = {
+#     "mode": "sandbox",  # sandbox or live
+#     "client_id": "AVLoQVq3xHZ6FrF4mxHwlCPgVBAw4Fw5RtMkuxmYd23SkUTIY643n2g3KdK-Al8wV05I28lza5uoQbAA",
+#     "client_secret": "EO8kRc8yioDk0i2Qq-QMcVFfwkmyMJorTvBSLDTnxDJJ_wb9VoM_0jkUY9iEng2Flp1ze8wQOGpH5nB2"
+# }
+
 DETECT_PUSH_DOMAIN = 'http://push.dvema.com/'
 DETECT_PUSH_DOMAIN = 'http://push.dvema.com/'
+DETECT_PUSH_DOMAINS = 'https://push.dvema.com/'
+DETECT_PUSH_DOMAIN_JIUAN = 'http://jiuan.push.dvema.com/'
+DETECT_PUSH_DOMAINS_JIUAN = 'https://jiuan.push.dvema.com/'
 # 数据库dyanamo品牌日志数据库
 # 数据库dyanamo品牌日志数据库
 USER_BRAND = 'user_brand'
 USER_BRAND = 'user_brand'
 USER_BRAND_ALL = 'user_brand_all'
 USER_BRAND_ALL = 'user_brand_all'
 
 
+# type =2
+JPUSH_CONFIG = {
+    'com.ansjer.accloud_ab': {
+        'Key': 'f0dc047e5e53fd14199de5b0',
+        'Secret': 'aa7f7db33e9f0a7f3871aa1c'},
+    'com.ansjer.adcloud_ab': {
+        'Key': '76d97b535185114985608234',
+        'Secret': 'c9a92b301043cc9c52778692'},
+    'com.ansjer.zccloud_ab': {
+        'Key': 'd9924f56d3cc7c6017965130',
+        'Secret': '869d832d126a232f158b5987'},
+    'com.ansjer.loocamccloud_ab': {
+        'Key': 'd1cc44797b4642b0e05304fe',
+        'Secret': 'c3e8b4ca8c576de61401e56a'},
+    'com.ansjer.loocamdcloud_ab': {
+        'Key': '76d97b535185114985608234',
+        'Secret': 'c9a92b301043cc9c52778692'},
+    'com.ansjer.zccloud_a': {
+        'Key': '57de2a80d68bf270fd6bdf5a',
+        'Secret': '3d354eb6a0b49c2610decf42'},
+    'com.ansjer.accloud_a': {
+        'Key': 'ff95ee685f49c0dc4013347b',
+        'Secret': 'de2c20959f5516fdeeafe78e'},
+    'com.ansjer.adcloud_a': {
+        'Key': '2e47eb1aee9b164460df3668',
+        'Secret': 'b9137d8d684bc248f1809b6d'},
+    'com.ansjer.loocamccloud_a': {
+        'Key': '23c9213215c7ca0ec945629b',
+        'Secret': '81e4b1e859cc8387e2e6c431'},
+    'com.ansjer.loocamdcloud_a': {
+        'Key': '1dbdd60a16e9892d6f68a073',
+        'Secret': '80a97690e7e043109059b403'},
+    'com.ansjer.customizedb_a': {
+        'Key': '9d79630aa49adfa291fe2568',
+        'Secret': '4d8ff52f88136561875a0212'},
+    'com.ansjer.customizedd_a': {
+        'Key': '8fc4f495685bde53341ee25d',
+        'Secret': 'f1da11fa466509fa2670fb66',
+    }
+}
+# type =1
+FCM_CONFIG = {
+    'com.ansjer.zccloud_a': 'AAAAb9YP3rk:APA91bHu8u-CTpcd0g6lKPo0WNVqCi8jZub1cPPbSAY9AucT1HxlF65ZDUko9iG8q2ch17bwu9YWHpK1xI1gHSRXCslLvZlXEmHZC0AG3JKg15XuUvlFKACIajUFV-pOeGRT8tM6-31I',
+    'com.ansjer.loocamccloud_a': 'AAAAb9YP3rk:APA91bFCgd-kbVmpK4EVpfdHH_PJZQCYTkOGnTZdIuBWEz2r7aMRsJYHOH3sB-rwcbaRWgnufTyjX9nGQxb6KxQbWVk4ah_H-M3IqGh6Mb60WQQAuR33V6g_Jes5pGL6ViuIxGHqVMaR',
+    'com.ansjer.loocamdcloud_a': 'AAAAb9YP3rk:APA91bGw2I2KMD4i-5T7nZO_wB8kuAOuqgyqe5rxmY-W5qkpYEx9IL2IfmC_qf6B_xOyjIDDSjckvMo-RauN__SEoxvAkis7042GRkoKpw7cjZ_H8lC-d50PC0GclPzccrOGFusyKbFY',
+    'com.ansjer.customizedb_a': 'AAAAb9YP3rk:APA91bE7kI4vcm-9h_CJNFlOZfc-xwP4Btn6AnjOrwoKV6fgYN7fdarkO76sYxVZiAbDnxsFfOJyP7vQfwyan6mdjuyD5iHdt_XgO22VqniC0vA1V4GJiCS8Tp7LxIX8JVKZl9I_Powt',
+    'com.ansjer.customizeda_a': 'AAAAb9YP3rk:APA91bF0HzizVWDc6dKzobY9fsaKDK4veqkOZehDXshVXs8pEEvNWjR_YWbhP60wsRYCHCal8fWN5cECVOWNMMzDsfU88Ty2AUl8S5FtZsmeDTkoGntQOswBr8Ln7Fm_LAp1VqTf9CpM',
+    'com.ansjer.customizedd_a': 'AAAAb9YP3rk:APA91bHkxOozJWBrlv3eNT0PgwosYENI9aM4Zuzd418cX-iKkpa1zFNC5MkNDKApx1KH4fhmAfaJ6IMRZ0nj5GIxCpstDYCaZWwgC7-etqfSxG5JAq8LOwJx0o_1tUZqwjIic8ztsg0o',
+    'com.ansjer.adcloud_a': 'AAAAb9YP3rk:APA91bFm06w8b9OKQ0gz0iaWFuRqRIkvgAz6z7Gp3dBU_X-LNGJQd1hc1QR2W7QzBglF8SHtERA45a2lbdLRa5qv7hxfd6W_sJLBK7dA8jklsOQBvy505oUzTwMKWy4TwH-exps9KrhO',
+    'com.ansjer.accloud_a': 'AAAAb9YP3rk:APA91bFm06w8b9OKQ0gz0iaWFuRqRIkvgAz6z7Gp3dBU_X-LNGJQd1hc1QR2W7QzBglF8SHtERA45a2lbdLRa5qv7hxfd6W_sJLBK7dA8jklsOQBvy505oUzTwMKWy4TwH-exps9KrhO',
+    'com.ansjer.zccloud_ab': 'AAAAb9YP3rk:APA91bHu8u-CTpcd0g6lKPo0WNVqCi8jZub1cPPbSAY9AucT1HxlF65ZDUko9iG8q2ch17bwu9YWHpK1xI1gHSRXCslLvZlXEmHZC0AG3JKg15XuUvlFKACIajUFV-pOeGRT8tM6-31I',
+}
 APNS_CONFIG = {
 APNS_CONFIG = {
     'com.ansjer.loocamccloud': {
     'com.ansjer.loocamccloud': {
-        'pem_path': 'Ansjer/file/apns_pem/lcc.pem',
+        'pem_path': 'Ansjer/file/apns_pem/lcc-dev.pem',
     },
     },
     'com.ansjer.zosidcloud': {
     'com.ansjer.zosidcloud': {
-        'pem_path': 'Ansjer/file/apns_pem/zosidcloud.pem',
+        'pem_path': 'Ansjer/file/apns_pem/zosidcloud-dev.pem',
     },
     },
     'com.ansjer.customizedb': {
     'com.ansjer.customizedb': {
-        'pem_path': 'Ansjer/file/apns_pem/customizedb.pem',
-    },
-    'com.ansjer.customizedd': {
-        'pem_path': 'Ansjer/file/apns_pem/customizedd.pem',
-    },
-    'com.ansjer.customizede': {
-        'pem_path': 'Ansjer/file/apns_pem/customizede.pem',
+        'pem_path': 'Ansjer/file/apns_pem/customizedb-dev.pem',
     },
     },
     'com.ansjer.customizeda': {
     'com.ansjer.customizeda': {
-        'pem_path': 'Ansjer/file/apns_pem/customizeda.pem',
+        'pem_path': 'Ansjer/file/apns_pem/customizeda-dev.pem',
     },
     },
     'com.ansjer.zccloud': {
     'com.ansjer.zccloud': {
-        'pem_path': 'Ansjer/file/apns_pem/zccloud.pem',
+        'pem_path': 'Ansjer/file/apns_pem/zccloud-dev.pem',
     },
     },
     'com.ansjer.accloud': {
     'com.ansjer.accloud': {
         'pem_path': 'Ansjer/file/apns_pem/accloud-dev.pem',
         'pem_path': 'Ansjer/file/apns_pem/accloud-dev.pem',
     },
     },
-    'com.ansjer.adcloud': {
-        'pem_path': 'Ansjer/file/apns_pem/apns-dis-adcloud.pem',
+    'com.ansjer.customizede': {
+        'pem_path': 'Ansjer/file/apns_pem/ZhouShi-dev.pem',
+    },
+    'com.ansjer.customizedc': {
+        'pem_path': 'Ansjer/file/apns_pem/customizedc.pem',
     }
     }
 }
 }
 APNS_MODE = 'prod'
 APNS_MODE = 'prod'
+# 根路径
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+SERVER_TYPE = os.environ.get('DJANGO_SETTINGS_MODULE')
 
 
 TUTK_PUSH_DOMAIN = 'http://push.iotcplatform.com/tpns'
 TUTK_PUSH_DOMAIN = 'http://push.iotcplatform.com/tpns'

+ 14 - 8
Ansjer/config_local.py

@@ -15,20 +15,23 @@
 OAUTH_ACCESS_TOKEN_SECRET = 'local_a+jbgnw%@1%zy^=@dn62%'
 OAUTH_ACCESS_TOKEN_SECRET = 'local_a+jbgnw%@1%zy^=@dn62%'
 OAUTH_REFRESH_TOKEN_SECRET = 'local_r+jbgnw%@1%zy^=@dn62%'
 OAUTH_REFRESH_TOKEN_SECRET = 'local_r+jbgnw%@1%zy^=@dn62%'
 
 
-NGINX_RTMP_STAT = 'http://192.168.136.99:8077/stat'
-SERVER_DOMAIN = 'http://192.168.136.99:8077/'
-SERVER_DOMAIN_SSL = 'http://192.168.136.99:8077/'
-SERVER_HOST = '192.168.136.99'
-DOMAIN_HOST = '192.168.136.99'
+NGINX_RTMP_STAT = 'http://127.0.0.1:8077/stat'
+SERVER_DOMAIN = 'http://127.0.0.1:8077/'
+SERVER_DOMAIN_SSL = 'http://127.0.0.1:8077/'
+SERVER_HOST = '127.0.0.1'
+DOMAIN_HOST = '127.0.0.1'
 # SERVER_HOST = '127.0.0.1'
 # SERVER_HOST = '127.0.0.1'
-# DOMAIN_HOST = '192.168.136.99'
-RTMP_PUSH_URL = 'rtmp://192.168.136.99:1935/hls'
+# DOMAIN_HOST = '127.0.0.1'
+RTMP_PUSH_URL = 'rtmp://127.0.0.1:1935/hls'
 PAYPAL_CRD = {
 PAYPAL_CRD = {
     "mode": "sandbox",  # sandbox or live
     "mode": "sandbox",  # sandbox or live
     "client_id": "AeuhR7FHisO-lOd2OwtzyDu7PSLMmDZoDLgmzuEQ12WCtTu_8Z1AzcD4gG5SnymnuvJs-n5KBB8H9Z_G",
     "client_id": "AeuhR7FHisO-lOd2OwtzyDu7PSLMmDZoDLgmzuEQ12WCtTu_8Z1AzcD4gG5SnymnuvJs-n5KBB8H9Z_G",
     "client_secret": "EGkMCB3RWTcUGJGDYahJ9mCO0AQzEn2AvFfx1GAFjfyyn7-8a0NObcZks89QorlFpvNWTsDXVa2INRNM"
     "client_secret": "EGkMCB3RWTcUGJGDYahJ9mCO0AQzEn2AvFfx1GAFjfyyn7-8a0NObcZks89QorlFpvNWTsDXVa2INRNM"
 }
 }
 DETECT_PUSH_DOMAIN = 'http://test.push.dvema.com/'
 DETECT_PUSH_DOMAIN = 'http://test.push.dvema.com/'
+DETECT_PUSH_DOMAINS = 'https://test.push.dvema.com/'
+DETECT_PUSH_DOMAIN_JIUAN = 'http://jiuan.push.dvema.com/'
+DETECT_PUSH_DOMAINS_JIUAN = 'https://jiuan.push.dvema.com/'
 # 数据库dyanamo品牌日志数据库
 # 数据库dyanamo品牌日志数据库
 USER_BRAND = 'test_user_brand'
 USER_BRAND = 'test_user_brand'
 USER_BRAND_ALL = 'test_user_brand_all'
 USER_BRAND_ALL = 'test_user_brand_all'
@@ -52,7 +55,10 @@ APNS_CONFIG = {
     },
     },
     'com.ansjer.accloud': {
     'com.ansjer.accloud': {
         'pem_path': 'Ansjer/file/apns_pem/accloud-dev.pem',
         'pem_path': 'Ansjer/file/apns_pem/accloud-dev.pem',
-    }
+    },
+    'com.ansjer.customizede': {
+        'pem_path': 'Ansjer/file/apns_pem/ZhouShi-dev.pem',
+    },
 }
 }
 APNS_MODE = 'dev'
 APNS_MODE = 'dev'
 TUTK_PUSH_DOMAIN = 'http://push.iotcplatform.com/tpns'
 TUTK_PUSH_DOMAIN = 'http://push.iotcplatform.com/tpns'

+ 72 - 0
Ansjer/config_test.py

@@ -11,6 +11,8 @@
 @file: config_test.py
 @file: config_test.py
 @Contact: chanjunkai@163.com
 @Contact: chanjunkai@163.com
 """
 """
+import os
+
 NGINX_RTMP_STAT = 'http://test.dvema.com/stat'
 NGINX_RTMP_STAT = 'http://test.dvema.com/stat'
 SERVER_DOMAIN = 'http://test.dvema.com/'
 SERVER_DOMAIN = 'http://test.dvema.com/'
 SERVER_DOMAIN_SSL = 'https://test.dvema.com/'
 SERVER_DOMAIN_SSL = 'https://test.dvema.com/'
@@ -33,11 +35,71 @@ PAYPAL_CRD = {
     "client_id": "AVLoQVq3xHZ6FrF4mxHwlCPgVBAw4Fw5RtMkuxmYd23SkUTIY643n2g3KdK-Al8wV05I28lza5uoQbAA",
     "client_id": "AVLoQVq3xHZ6FrF4mxHwlCPgVBAw4Fw5RtMkuxmYd23SkUTIY643n2g3KdK-Al8wV05I28lza5uoQbAA",
     "client_secret": "EO8kRc8yioDk0i2Qq-QMcVFfwkmyMJorTvBSLDTnxDJJ_wb9VoM_0jkUY9iEng2Flp1ze8wQOGpH5nB2"
     "client_secret": "EO8kRc8yioDk0i2Qq-QMcVFfwkmyMJorTvBSLDTnxDJJ_wb9VoM_0jkUY9iEng2Flp1ze8wQOGpH5nB2"
 }
 }
+# PAYPAL_CRD = {
+#     "mode": "sandbox",  # sandbox or live
+#     "client_id": "ATXTpWs8sajNYeU46jNs1yzpy4H_o3RRrGVIJ8Tscc312BjMx12cpRgCucfWX07a4G6GbK8hzElB04Pd",
+#     "client_secret": "EHcnfrpL1o1ev9WnlQ-C1uymeRKDoJ6li6Y0d6iHoRGj4u8Sx5lSEEH774XphP4LQZ0DrDUdvxbux0T2"
+# }
 DETECT_PUSH_DOMAIN = 'http://test.push.dvema.com/'
 DETECT_PUSH_DOMAIN = 'http://test.push.dvema.com/'
+DETECT_PUSH_DOMAINS = 'https://test.push.dvema.com/'
+DETECT_PUSH_DOMAIN_JIUAN = 'http://jiuan.push.dvema.com/'
+DETECT_PUSH_DOMAINS_JIUAN = 'https://jiuan.push.dvema.com/'
 # 数据库dyanamo品牌日志数据库
 # 数据库dyanamo品牌日志数据库
 USER_BRAND = 'test_user_brand'
 USER_BRAND = 'test_user_brand'
 USER_BRAND_ALL = 'test_user_brand_all'
 USER_BRAND_ALL = 'test_user_brand_all'
 
 
+# type =2
+JPUSH_CONFIG = {
+    'com.ansjer.accloud_ab': {
+        'Key': 'f0dc047e5e53fd14199de5b0',
+        'Secret': 'aa7f7db33e9f0a7f3871aa1c'},
+    'com.ansjer.adcloud_ab': {
+        'Key': '76d97b535185114985608234',
+        'Secret': 'c9a92b301043cc9c52778692'},
+    'com.ansjer.zccloud_ab': {
+        'Key': 'd9924f56d3cc7c6017965130',
+        'Secret': '869d832d126a232f158b5987'},
+    'com.ansjer.loocamccloud_ab': {
+        'Key': 'd1cc44797b4642b0e05304fe',
+        'Secret': 'c3e8b4ca8c576de61401e56a'},
+    'com.ansjer.loocamdcloud_ab': {
+        'Key': '76d97b535185114985608234',
+        'Secret': 'c9a92b301043cc9c52778692'},
+    'com.ansjer.zccloud_a': {
+        'Key': '57de2a80d68bf270fd6bdf5a',
+        'Secret': '3d354eb6a0b49c2610decf42'},
+    'com.ansjer.accloud_a': {
+        'Key': 'ff95ee685f49c0dc4013347b',
+        'Secret': 'de2c20959f5516fdeeafe78e'},
+    'com.ansjer.adcloud_a': {
+        'Key': '2e47eb1aee9b164460df3668',
+        'Secret': 'b9137d8d684bc248f1809b6d'},
+    'com.ansjer.loocamccloud_a': {
+        'Key': '23c9213215c7ca0ec945629b',
+        'Secret': '81e4b1e859cc8387e2e6c431'},
+    'com.ansjer.loocamdcloud_a': {
+        'Key': '1dbdd60a16e9892d6f68a073',
+        'Secret': '80a97690e7e043109059b403'},
+    'com.ansjer.customizedb_a': {
+        'Key': '9d79630aa49adfa291fe2568',
+        'Secret': '4d8ff52f88136561875a0212'},
+    'com.ansjer.customizedd_a': {
+        'Key': '8fc4f495685bde53341ee25d',
+        'Secret': 'f1da11fa466509fa2670fb66',
+    }
+}
+# type =1
+FCM_CONFIG = {
+    'com.ansjer.zccloud_a': 'AAAAb9YP3rk:APA91bHu8u-CTpcd0g6lKPo0WNVqCi8jZub1cPPbSAY9AucT1HxlF65ZDUko9iG8q2ch17bwu9YWHpK1xI1gHSRXCslLvZlXEmHZC0AG3JKg15XuUvlFKACIajUFV-pOeGRT8tM6-31I',
+    'com.ansjer.loocamccloud_a': 'AAAAb9YP3rk:APA91bFCgd-kbVmpK4EVpfdHH_PJZQCYTkOGnTZdIuBWEz2r7aMRsJYHOH3sB-rwcbaRWgnufTyjX9nGQxb6KxQbWVk4ah_H-M3IqGh6Mb60WQQAuR33V6g_Jes5pGL6ViuIxGHqVMaR',
+    'com.ansjer.loocamdcloud_a': 'AAAAb9YP3rk:APA91bGw2I2KMD4i-5T7nZO_wB8kuAOuqgyqe5rxmY-W5qkpYEx9IL2IfmC_qf6B_xOyjIDDSjckvMo-RauN__SEoxvAkis7042GRkoKpw7cjZ_H8lC-d50PC0GclPzccrOGFusyKbFY',
+    'com.ansjer.customizedb_a': 'AAAAb9YP3rk:APA91bE7kI4vcm-9h_CJNFlOZfc-xwP4Btn6AnjOrwoKV6fgYN7fdarkO76sYxVZiAbDnxsFfOJyP7vQfwyan6mdjuyD5iHdt_XgO22VqniC0vA1V4GJiCS8Tp7LxIX8JVKZl9I_Powt',
+    'com.ansjer.customizeda_a': 'AAAAb9YP3rk:APA91bF0HzizVWDc6dKzobY9fsaKDK4veqkOZehDXshVXs8pEEvNWjR_YWbhP60wsRYCHCal8fWN5cECVOWNMMzDsfU88Ty2AUl8S5FtZsmeDTkoGntQOswBr8Ln7Fm_LAp1VqTf9CpM',
+    'com.ansjer.customizedd_a': 'AAAAb9YP3rk:APA91bHkxOozJWBrlv3eNT0PgwosYENI9aM4Zuzd418cX-iKkpa1zFNC5MkNDKApx1KH4fhmAfaJ6IMRZ0nj5GIxCpstDYCaZWwgC7-etqfSxG5JAq8LOwJx0o_1tUZqwjIic8ztsg0o',
+    'com.ansjer.adcloud_a': 'AAAAb9YP3rk:APA91bFm06w8b9OKQ0gz0iaWFuRqRIkvgAz6z7Gp3dBU_X-LNGJQd1hc1QR2W7QzBglF8SHtERA45a2lbdLRa5qv7hxfd6W_sJLBK7dA8jklsOQBvy505oUzTwMKWy4TwH-exps9KrhO',
+    'com.ansjer.accloud_a': 'AAAAb9YP3rk:APA91bFm06w8b9OKQ0gz0iaWFuRqRIkvgAz6z7Gp3dBU_X-LNGJQd1hc1QR2W7QzBglF8SHtERA45a2lbdLRa5qv7hxfd6W_sJLBK7dA8jklsOQBvy505oUzTwMKWy4TwH-exps9KrhO',
+    'com.ansjer.zccloud_ab': 'AAAAb9YP3rk:APA91bHu8u-CTpcd0g6lKPo0WNVqCi8jZub1cPPbSAY9AucT1HxlF65ZDUko9iG8q2ch17bwu9YWHpK1xI1gHSRXCslLvZlXEmHZC0AG3JKg15XuUvlFKACIajUFV-pOeGRT8tM6-31I',
+}
 APNS_CONFIG = {
 APNS_CONFIG = {
     'com.ansjer.loocamccloud': {
     'com.ansjer.loocamccloud': {
         'pem_path': 'Ansjer/file/apns_pem/lcc-dev.pem',
         'pem_path': 'Ansjer/file/apns_pem/lcc-dev.pem',
@@ -56,7 +118,17 @@ APNS_CONFIG = {
     },
     },
     'com.ansjer.accloud': {
     'com.ansjer.accloud': {
         'pem_path': 'Ansjer/file/apns_pem/accloud-dev.pem',
         'pem_path': 'Ansjer/file/apns_pem/accloud-dev.pem',
+    },
+    'com.ansjer.customizede': {
+        'pem_path': 'Ansjer/file/apns_pem/ZhouShi-dev.pem',
+    },
+    'com.ansjer.customizedc': {
+        'pem_path': 'Ansjer/file/apns_pem/customizedc.pem',
     }
     }
 }
 }
+# 根路径
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 APNS_MODE = 'dev'
 APNS_MODE = 'dev'
+SERVER_TYPE = os.environ.get('DJANGO_SETTINGS_MODULE')
+
 TUTK_PUSH_DOMAIN = 'http://push.iotcplatform.com/tpns'
 TUTK_PUSH_DOMAIN = 'http://push.iotcplatform.com/tpns'

+ 68 - 0
Ansjer/file/apns_pem/ZhouShi-dev.pem

@@ -0,0 +1,68 @@
+Bag Attributes
+    friendlyName: Apple Push Services: com.ansjer.customizede
+    localKeyID: F9 76 DF A5 B7 2C 38 04 6E CD FA BF F5 74 9F AD 83 1A E9 8E 
+subject=/UID=com.ansjer.customizede/CN=Apple Push Services: com.ansjer.customizede/OU=772N5HXAR2/O=ZOSI Technology Co. , Ltd/C=CN
+issuer=/C=US/O=Apple Inc./OU=Apple Worldwide Developer Relations/CN=Apple Worldwide Developer Relations Certification Authority
+-----BEGIN CERTIFICATE-----
+MIIGOTCCBSGgAwIBAgIIPI2iB4mqqDEwDQYJKoZIhvcNAQELBQAwgZYxCzAJBgNV
+BAYTAlVTMRMwEQYDVQQKDApBcHBsZSBJbmMuMSwwKgYDVQQLDCNBcHBsZSBXb3Js
+ZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9uczFEMEIGA1UEAww7QXBwbGUgV29ybGR3
+aWRlIERldmVsb3BlciBSZWxhdGlvbnMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkw
+HhcNMjAxMjE5MDY1NDE0WhcNMjIwMTE4MDY1NDE0WjCBpDEmMCQGCgmSJomT8ixk
+AQEMFmNvbS5hbnNqZXIuY3VzdG9taXplZGUxNDAyBgNVBAMMK0FwcGxlIFB1c2gg
+U2VydmljZXM6IGNvbS5hbnNqZXIuY3VzdG9taXplZGUxEzARBgNVBAsMCjc3Mk41
+SFhBUjIxIjAgBgNVBAoMGVpPU0kgVGVjaG5vbG9neSBDby4gLCBMdGQxCzAJBgNV
+BAYTAkNOMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuIhNiP1jkZsf
+HD8nyx6G5DjF4RONEZGMUYph5GFpQSlnY4c1IeHFcNa7qKnvrx3t2ZnIIKaAaMWc
+w+9XiK3KNDpo/A4CEt/Es0Dh5gDze8bG8DK1qORI5XMDUC3r2wRdZ1jSSDcXJ0Fu
+byIkxrOaCe4J0hlJkPbzB/2z9AXMhSh4UhzcHUNMqfWbpzrUCG1nv0woA2MaWrw9
+OiwLy4HckGHXDJEV1eIPsN3v+W5RoP2VJp69gx7M2LH5KcFTvpzhlcXl4elSETgU
+07dqHnoHkSaVVNB8dmPmpHn11Sk8S+fm1qMtNy9PB5gmMaCQt31+YThFp1rl8Zs4
+ERVmbPWtVQIDAQABo4ICeTCCAnUwDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBSI
+JxcJqbYYYIvs67r2R1nFUlSjtzCCARwGA1UdIASCARMwggEPMIIBCwYJKoZIhvdj
+ZAUBMIH9MIHDBggrBgEFBQcCAjCBtgyBs1JlbGlhbmNlIG9uIHRoaXMgY2VydGlm
+aWNhdGUgYnkgYW55IHBhcnR5IGFzc3VtZXMgYWNjZXB0YW5jZSBvZiB0aGUgdGhl
+biBhcHBsaWNhYmxlIHN0YW5kYXJkIHRlcm1zIGFuZCBjb25kaXRpb25zIG9mIHVz
+ZSwgY2VydGlmaWNhdGUgcG9saWN5IGFuZCBjZXJ0aWZpY2F0aW9uIHByYWN0aWNl
+IHN0YXRlbWVudHMuMDUGCCsGAQUFBwIBFilodHRwOi8vd3d3LmFwcGxlLmNvbS9j
+ZXJ0aWZpY2F0ZWF1dGhvcml0eTATBgNVHSUEDDAKBggrBgEFBQcDAjAwBgNVHR8E
+KTAnMCWgI6Ahhh9odHRwOi8vY3JsLmFwcGxlLmNvbS93d2RyY2EuY3JsMB0GA1Ud
+DgQWBBT5dt+ltyw4BG7N+r/1dJ+tgxrpjjAOBgNVHQ8BAf8EBAMCB4AwEAYKKoZI
+hvdjZAYDAQQCBQAwEAYKKoZIhvdjZAYDAgQCBQAwgYkGCiqGSIb3Y2QGAwYEezB5
+DBZjb20uYW5zamVyLmN1c3RvbWl6ZWRlMAUMA2FwcAwbY29tLmFuc2plci5jdXN0
+b21pemVkZS52b2lwMAYMBHZvaXAMI2NvbS5hbnNqZXIuY3VzdG9taXplZGUuY29t
+cGxpY2F0aW9uMA4MDGNvbXBsaWNhdGlvbjANBgkqhkiG9w0BAQsFAAOCAQEAOS3j
+rVNOYYSoEYf7OgUl26ubcAMyYwVHhggxtQw0hR63+pdSXWi2/E5IynEf7qmBmbk/
+wTuIkWXnvR5a+sjJy+f94TM9Qe5bXvSuqQn+3HA0XruuBq1A7OGfbORBBZwwNSWZ
+mEjBd9vNdT3ZDksY2XSLvoKOE8gW7i60u4dE5GYqxe3CnICXLlgKjWZx5xbbMl/m
+W6j6ikKOVCqIG6nA8uUwrbznZQAUfQHblB2Yj58zOpCg/0KLqmtQMQJG4kCnZres
+4FElErUr0aEJXPTLqTHLX3PlvFA7Iwb7alTA8a7AFJYxyB184XoKS7rV8MZLuhdd
+wIggtF2b+92ah39F4w==
+-----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAuIhNiP1jkZsfHD8nyx6G5DjF4RONEZGMUYph5GFpQSlnY4c1
+IeHFcNa7qKnvrx3t2ZnIIKaAaMWcw+9XiK3KNDpo/A4CEt/Es0Dh5gDze8bG8DK1
+qORI5XMDUC3r2wRdZ1jSSDcXJ0FubyIkxrOaCe4J0hlJkPbzB/2z9AXMhSh4Uhzc
+HUNMqfWbpzrUCG1nv0woA2MaWrw9OiwLy4HckGHXDJEV1eIPsN3v+W5RoP2VJp69
+gx7M2LH5KcFTvpzhlcXl4elSETgU07dqHnoHkSaVVNB8dmPmpHn11Sk8S+fm1qMt
+Ny9PB5gmMaCQt31+YThFp1rl8Zs4ERVmbPWtVQIDAQABAoIBAF9NjfW9IApYOgYF
+nBCsUHBX3eKzjTzQlc6bEJm5sXmE36+oacl459ayIDMoqPAhHfEvGgu60kDKJn+P
+Af9F+lNlA0mCFpIW3WjSjpiSTy3S6HWvSuDSHc/ayZBEVzZDF9ZDKj8/rIaKpXVi
+BepVYa3VMV8/zh2/XJ746VKTGCCAd0fLHHL4A0GRHnNBktLB9Ik3KzMqg+3yh2K3
+gDdl1zP1vVgUHZUw6wSwYVUVycsSxD1uwa4iKs1G6taWK0hm2cZ/UkFHfLylWymx
+ZMU/zXeloIHz2/PwWrczx7lBEgaYNQ3rptgc+BbafHBEIpH36XlU1N2wdQUAkQqC
+VeCxbQECgYEA83imEE5pwCdBxcbg7WXL5GrvQqdzCxkqL8xSsftDklvyHGktc8OU
+XBkVkip+D9FBSNbKYWzCGXBaHg6mdtskmkxsq9rALzIzvVDNJ0r4WzyuRi//AEbV
+Mg+gZ3NeXYx61pwE0tYEC1RocboYGEpYGbJ6+SXG/BySiks7FBukJ8ECgYEAwgc6
+Pcfu7dUmFrj31xjylVgpdhsZNDr200eKgJ1dE3wbrJYz31sVMYULhaoJGKrYKNKY
+ECTDmhywKnM/0Z9MqpG64VWeR10hEbsL+bKrVbPQZkLKGpichNRF7QIOT64cjZt2
+kjMYCWEp+ip8yy9PrVufVqrhG6/a6XxXQGwdCpUCgYEAv4n86vslStwXbGaHcXwS
+KYLO89sUMHj9rVjK/eY0RKI9GIjODzKgNswtIi53ui3fdFQ2JusO0ECJRPg1kW/Z
+neHd5F1VsEuIVLmKjAz40Z4tZF5B+I/BDX8pq/khFet8f/WB/fQMfnVLLZ0/c2yZ
+Xq4A/JzxrEk2J8IDmlAcloECgYEAmawjwr7RS+kfq6uAEAqgRwx2eiZoRefVie0F
+k2wPRdlsCbtFBkgbdwcK4yiS38igP2TcLx0PFsZV+KkjCKGElSuqucGYBKmMAYEF
+sRSDgvNRwUxwybPJc6K0Z0zTjOQ3lShmNtDk3rjoCE0SXdLw5jrE7l2UwNr9JSPn
+7wwxzCkCgYBCRf/n0ID2NcsbVJBhxqel19Pa3vxxvY7Lw1j0kzgXx4a5LrOw6qnZ
+KRQUOK9EMrby63tjrIE9p2xuwXj7r0jMi9GFrk0fd1yLBveqAt/Hq9+DmWU4YDSN
+ZnxCyQ+VQ+wGtVqmuwV0iUWnnhhSLYuaqVgvsnY1QoNmxHIXgSV04g==
+-----END RSA PRIVATE KEY-----

+ 68 - 0
Ansjer/file/apns_pem/customizedc.pem

@@ -0,0 +1,68 @@
+Bag Attributes
+    friendlyName: Apple Push Services: com.ansjer.customizedc
+    localKeyID: 7C 1A EE 33 33 71 66 7C 92 4E 03 CC F9 CA 61 C4 EC 4B C7 61 
+subject=/UID=com.ansjer.customizedc/CN=Apple Push Services: com.ansjer.customizedc/OU=9NRJLKV9UB/O=SMD Technologies Pty LTD/C=ZA
+issuer=/C=US/O=Apple Inc./OU=Apple Worldwide Developer Relations/CN=Apple Worldwide Developer Relations Certification Authority
+-----BEGIN CERTIFICATE-----
+MIIGODCCBSCgAwIBAgIId0lTH2/IAa4wDQYJKoZIhvcNAQELBQAwgZYxCzAJBgNV
+BAYTAlVTMRMwEQYDVQQKDApBcHBsZSBJbmMuMSwwKgYDVQQLDCNBcHBsZSBXb3Js
+ZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9uczFEMEIGA1UEAww7QXBwbGUgV29ybGR3
+aWRlIERldmVsb3BlciBSZWxhdGlvbnMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkw
+HhcNMjEwMzEwMTA1NTE0WhcNMjIwNDA5MTA1NTEzWjCBozEmMCQGCgmSJomT8ixk
+AQEMFmNvbS5hbnNqZXIuY3VzdG9taXplZGMxNDAyBgNVBAMMK0FwcGxlIFB1c2gg
+U2VydmljZXM6IGNvbS5hbnNqZXIuY3VzdG9taXplZGMxEzARBgNVBAsMCjlOUkpM
+S1Y5VUIxITAfBgNVBAoMGFNNRCBUZWNobm9sb2dpZXMgUHR5IExURDELMAkGA1UE
+BhMCWkEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCaX1qQS/CHT5r5
+EVvly9+0XHhTt8I6Rynom3Y7NIoYb1TMTBHlIE9DQ+g4VXBrENkdYjRuicR5ADto
+MfNjRxse3+7E3gg1Nt2oUsDodWDlrjLEUDh+FFF8mcXAAwiiOdB3daUUvxkplcCU
+4/3mNpBmVfCWenCKY8gLHqtXHC71SWd4dSTj0tg8/62F1MUCh3gPpb65hhDAtWgS
+KiQ3rbsL/kXllEGbAkO7fokRu3Nd7telCnO8PHT30BSqgJnOSJZhD+ZGxZLlqIqS
+T6axSWeZC0dllZO/XAPkfQmJgMl7fS5PdSrfoPl2CM+Xa1f/eUrxa86tRSGAgl8G
+O3JZMAZ3AgMBAAGjggJ5MIICdTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFIgn
+Fwmpthhgi+zruvZHWcVSVKO3MIIBHAYDVR0gBIIBEzCCAQ8wggELBgkqhkiG92Nk
+BQEwgf0wgcMGCCsGAQUFBwICMIG2DIGzUmVsaWFuY2Ugb24gdGhpcyBjZXJ0aWZp
+Y2F0ZSBieSBhbnkgcGFydHkgYXNzdW1lcyBhY2NlcHRhbmNlIG9mIHRoZSB0aGVu
+IGFwcGxpY2FibGUgc3RhbmRhcmQgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YgdXNl
+LCBjZXJ0aWZpY2F0ZSBwb2xpY3kgYW5kIGNlcnRpZmljYXRpb24gcHJhY3RpY2Ug
+c3RhdGVtZW50cy4wNQYIKwYBBQUHAgEWKWh0dHA6Ly93d3cuYXBwbGUuY29tL2Nl
+cnRpZmljYXRlYXV0aG9yaXR5MBMGA1UdJQQMMAoGCCsGAQUFBwMCMDAGA1UdHwQp
+MCcwJaAjoCGGH2h0dHA6Ly9jcmwuYXBwbGUuY29tL3d3ZHJjYS5jcmwwHQYDVR0O
+BBYEFHwa7jMzcWZ8kk4DzPnKYcTsS8dhMA4GA1UdDwEB/wQEAwIHgDAQBgoqhkiG
+92NkBgMBBAIFADAQBgoqhkiG92NkBgMCBAIFADCBiQYKKoZIhvdjZAYDBgR7MHkM
+FmNvbS5hbnNqZXIuY3VzdG9taXplZGMwBQwDYXBwDBtjb20uYW5zamVyLmN1c3Rv
+bWl6ZWRjLnZvaXAwBgwEdm9pcAwjY29tLmFuc2plci5jdXN0b21pemVkYy5jb21w
+bGljYXRpb24wDgwMY29tcGxpY2F0aW9uMA0GCSqGSIb3DQEBCwUAA4IBAQAwrr5I
+UlUPnRi7j2lEWx3GHK1iovps25C2rz4f11d3+9cZQfOFW96cjoFp2o9hILzril4P
+0YVkaWF3RBGngT27j1OdsdQCRwLHBVw42J4njrNUINJ3FVlSEVXJtAo3fHm3PajB
+KZo96vNbFbZe3MFC+CfEctM1lyizAWEWp68exyZeC8ppM7og55BSWEjSRJQRuon2
+wVHsWUwCNfuTNBomwzzSfQVaZkQogFNwO0F0AIxYUhHDUFG3/v+HfvmIpz0QTH+g
+nzvheeNzz44zDfetSCEy/7z0d4lgCw4QQ3hCko3jvNuv8vF3yZ4Y4Im2VqqFFWuX
+mXV7h0xmGK9HGJZH
+-----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAml9akEvwh0+a+RFb5cvftFx4U7fCOkcp6Jt2OzSKGG9UzEwR
+5SBPQ0PoOFVwaxDZHWI0bonEeQA7aDHzY0cbHt/uxN4INTbdqFLA6HVg5a4yxFA4
+fhRRfJnFwAMIojnQd3WlFL8ZKZXAlOP95jaQZlXwlnpwimPICx6rVxwu9UlneHUk
+49LYPP+thdTFAod4D6W+uYYQwLVoEiokN627C/5F5ZRBmwJDu36JEbtzXe7XpQpz
+vDx099AUqoCZzkiWYQ/mRsWS5aiKkk+msUlnmQtHZZWTv1wD5H0JiYDJe30uT3Uq
+36D5dgjPl2tX/3lK8WvOrUUhgIJfBjtyWTAGdwIDAQABAoIBAAObzwYogErpdXn1
+CezpQyV4M+fhF8089KHXYIApzkCb+aN8874jbzbnU3pdpO8bybeCIC+lUM5zTvA0
+mrfrZZrnKTG47wAvdCcHKDNG6yjzVYR5S5jG6NC8136Rk5YXO+RO/7jobrImKgZQ
+/hJvnBiIUcNywUa65mY8JU03/3EEaPd0CESSvX+IAbJzIW0vRvYJQ5YthiKzBwFg
+2FA7dLnIwMY9vL3ggYPrAgKfyyIGB0wlsLygrldnb2sJ+KiG3r7WlLTIb9Vs9UTv
+09q+Hk4fdRbg/vw1AyUE4oWcZdFGNI8fobUN30u6rjrhJj8ZS4JVngfvShgKiU65
+T0q032ECgYEAx5SpbAr3xebfG2iNPZeV1KlUIXqRVxYvguztgk0m7Q30rTuOfJtp
+SdHRGE+sLPKa3jQXi4xlx0J5oZt0USl6Y0hlWrq2C2W7DXF2T2WEJ/G9HLWZ5yXO
+zt4V6+4t0r9Tn/fPcSAYQzs5brUY1M/Sd7ygD/JIK25V+FxIOseDncsCgYEAxgML
+RHFrGfpN0TPd8Pkycw4NKl+Ft5+iWgyH4TwcXik8otu7vwwWvQRTjToSUtC7W1Vh
+C+S9c4ruX+4QWESiNNDsyybwrfTEQ/8+zoLrLDq6lJLkowqDShMY/Rsrn5ALK91M
+BSnhjTB0Jc20lIXz7KrqbkMfYSDF6Mru3qsLpIUCgYBkEOJ9XGZsoFv+pwYh+o3S
+CXA4NPcIPgRmVZqj+UDqHFQwQysmyNkafQukb9X4107U2DNx8Vvaczb+0y2Xv/8w
+Jk1DF1hNEJ2fmOLj3hdL28WgzmCy517wk6NUHqB1CR7Jlvs4Ugo4M0qRelVP5j81
+b6qlNCoBNJoAI2zHo98WzwKBgQCqnGzU6DS0CWuLWfldbBn/8Jd/bxa0BKPKmwlp
+FHYM29MXL+Uw06Wz70peYS7wlFEafRJFQS3LpGWH2oPSyjBI+ctNr5upB0EkpYTk
+QwGG9oNVCMxffutoo9PgIc0QivhVLzQVLuTc1mb9O6TgZBqsTQf5QXSEJ8zerBvt
+V8uMUQKBgCI93kALFOS/pc3CnKOtapyIGvyrOx7FX7WbhUiQzgiWlNVxkjklSPba
+H3I2hsjMnfiYXAHZcFl62z6/3v7C0oet2F+dAezMogEvrKhxqXPna+kFV0TLNkxa
+B9eJ1ZaZKdYZzra8nB+YwUbqd6xnCx5+YUETquInluyBv6T41xPp
+-----END RSA PRIVATE KEY-----

+ 33 - 17
Ansjer/formal_settings.py

@@ -107,10 +107,11 @@ DATABASES = {
 }
 }
 DATABASE_ROUTERS = ['Ansjer.database_router.DatabaseAppsRouter']
 DATABASE_ROUTERS = ['Ansjer.database_router.DatabaseAppsRouter']
 DATABASE_APPS_MAPPING = {
 DATABASE_APPS_MAPPING = {
-    'db1': 'default',
+    'Model': 'default',
     'db2': 'mysql02',
     'db2': 'mysql02',
 }
 }
 
 
+
 AUTH_PASSWORD_VALIDATORS = [
 AUTH_PASSWORD_VALIDATORS = [
     {
     {
         'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
         'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
@@ -169,8 +170,7 @@ CORS_ALLOW_HEADERS = (
 '''
 '''
 # 管理员邮箱
 # 管理员邮箱
 ADMINS = (
 ADMINS = (
-    ('admin', 'chanjunkai@163.com'),
-    ('admin', '1379072853@qq.com'),
+    ('admin', 'sonalh@foxmail.com'),
 )
 )
 
 
 # 非空链接,却发生404错误,发送通知MANAGERS
 # 非空链接,却发生404错误,发送通知MANAGERS
@@ -195,6 +195,10 @@ LOGGING = {
             # 'format': '{"asctime":"%(asctime)s","thread":"%(threadName)s:%(thread)d","errorline":"%(lineno)d","errorlevel":"%(levelname)s","errorcontent":"%(message)s"}'
             # 'format': '{"asctime":"%(asctime)s","thread":"%(threadName)s:%(thread)d","errorline":"%(lineno)d","errorlevel":"%(levelname)s","errorcontent":"%(message)s"}'
             'format': '%(asctime)s %(threadName)s %(thread)d %(lineno)d %(levelname)s %(message)s'
             'format': '%(asctime)s %(threadName)s %(thread)d %(lineno)d %(levelname)s %(message)s'
         },
         },
+        'standard': {
+            'format': '[%(asctime)s] [%(filename)s:%(lineno)d] [%(module)s:%(funcName)s] '
+                      '[%(levelname)s]- %(message)s'},
+
     },
     },
     'filters': {
     'filters': {
     },
     },
@@ -206,10 +210,10 @@ LOGGING = {
         },
         },
         'default': {
         'default': {
             'level': 'ERROR',
             'level': 'ERROR',
-            'class': 'logging.handlers.RotatingFileHandler',
-            'filename': BASE_DIR + '/static/log/error.log',
-            'maxBytes': 1024 * 1024 * 5,  # 5 MB
-            'backupCount': 5,
+            'class': 'logging.handlers.TimedRotatingFileHandler',
+            'filename': BASE_DIR + '/static/log/error/error.log',
+            'backupCount': 30,
+            'when': 'D',
             'formatter': 'error_format',
             'formatter': 'error_format',
         },
         },
         'console': {
         'console': {
@@ -217,22 +221,34 @@ LOGGING = {
             'class': 'logging.StreamHandler',
             'class': 'logging.StreamHandler',
             'formatter': 'error_format'
             'formatter': 'error_format'
         },
         },
-        # 'info': {  # 向文件中输出日志
-        #     'level': 'INFO',
-        #     'class': 'logging.handlers.RotatingFileHandler',
-        #     'filename': BASE_DIR + '/static/log/print.log',  # 日志文件的位置
-        #     'maxBytes': 20 * 1024 * 1024,  # 20M大小
-        #     'backupCount': 10,
-        #     'formatter': 'verbose',
-        #     'encoding': 'utf-8'
-        # },
+        'info': {
+            'level': 'INFO',
+            'class': 'logging.handlers.TimedRotatingFileHandler',
+            'filename': BASE_DIR + '/static/log/info/info.log',
+            'backupCount': 30,
+            'when': 'D',
+            'formatter': 'standard',
+            'encoding': 'utf-8',
+        },
     },
     },
     'loggers': {
     'loggers': {
         'django': {
         'django': {
             'handlers': ['default', 'console'],
             'handlers': ['default', 'console'],
             # 'handlers': ['mail_admins','default','console'],
             # 'handlers': ['mail_admins','default','console'],
+            # 'level': 'ERROR',
             'level': 'ERROR',
             'level': 'ERROR',
             'propagate': False
             'propagate': False
         },
         },
+        # log 调用时需要当作参数传入
+        'info': {
+            'handlers': ['info'],
+            'level':'INFO',
+            'propagate': False
+        }
+        # 'django.db.backends': {
+        #     'handlers': ['console'],
+        #     'propagate': True,
+        #     'level': 'DEBUG',
+        # },
     }
     }
-}
+}

+ 27 - 0
Ansjer/formal_statistics_push_day_task.py

@@ -0,0 +1,27 @@
+import json
+
+import requests
+
+
+base_url = 'http://dvema.com'
+username='13800138001'
+password='ansjer123456'
+
+login_url = base_url + 'account/login'
+
+data = {
+    'userName': username,
+    'userPwd': password
+}
+res = requests.post(url=login_url, data=data)
+res = res.json()
+print(res)
+
+if res['result_code'] == 0:
+    statistics_url = base_url + 'statistcs/pushDay'
+    data = {
+        'token': res['result']['access_token']
+    }
+    res = requests.post(url=statistics_url, data=data)
+    print(res.json())
+

+ 27 - 0
Ansjer/formal_statistics_push_month_task.py

@@ -0,0 +1,27 @@
+import json
+
+import requests
+
+
+# url = 'http://test.dvema.com'
+base_url = 'http://dvema.com/'
+username='13800138001'
+password='ansjer123456'
+login_url = base_url + 'account/login'
+
+data = {
+    'userName': username,
+    'userPwd': password
+}
+res = requests.post(url=login_url, data=data)
+res = res.json()
+print(res)
+
+if res['result_code'] == 0:
+    statistics_url = base_url + 'statistcs/pushMonth'
+    data = {
+        'token': res['result']['access_token']
+    }
+    res = requests.post(url=statistics_url, data=data)
+    print(res.json())
+

+ 49 - 0
Ansjer/formal_zositech_help_weekly_task.py

@@ -0,0 +1,49 @@
+import json
+
+import requests
+import time
+
+
+# url = 'http://test.dvema.com'
+# base_url = 'http://127.0.0.1:8000/'
+base_url = 'http://dvema.com/'
+username='13800138001'
+password='ansjer.x123789'
+login_url = base_url + 'account/login'
+
+data = {
+    'userName': username,
+    'userPwd': password
+}
+res = requests.post(url=login_url, data=data)
+res = res.json()
+
+if res['result_code'] == 0:
+    request_times = 0
+    while request_times < 5:
+        try:
+            statistics_url = base_url + 'faq/synZositechHelp'
+            # zh_url = 'https://mobileapphelp.zendesk.com/api/v2/help_center/articles/embeddable_search.json?locale=zh-cn&section=null&origin=web_widget'
+            zh_url = 'https://mobileapphelp.zendesk.com/api/v2/help_center/zh-cn/articles.json?page%5Bsize%5D=100'
+            zhcnDatares = requests.get(url=zh_url, timeout=10).text
+
+            en_url = 'https://mobileapphelp.zendesk.com/api/v2/help_center/en-us/articles.json?page%5Bsize%5D=100'
+            # en_url = 'https://mobileapphelp.zendesk.com/api/v2/help_center/articles/embeddable_search.json?locale=en-us&section=null&origin=web_widget'
+            enusDatares = requests.get(url=en_url, timeout=10).text
+            data = {
+                'token': res['result']['access_token'],
+                'zhresults': zhcnDatares,
+                'enresults': enusDatares
+            }
+            res = requests.post(url=statistics_url, data=data)
+
+        except Exception as e:
+            print(e)
+            request_times += 1
+            print(request_times)
+            time.sleep(3)
+
+print('success')
+
+
+

+ 46 - 0
Ansjer/generacode.py

@@ -0,0 +1,46 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+import json
+
+import xlwt
+
+from Object.TokenObject import TokenObject
+import base64
+import requests
+
+token = TokenObject()
+token = token.generate({'userID': str(2)})
+
+file = open('./file/UID-2020-09-09-06-14-44.txt', mode='r', encoding='utf-8')
+content = file.read()
+content = content.replace(' ', '\t')
+
+file1 = open('./file/UID_2020_09_09_06_14_44.txt', mode='w', encoding='utf-8')
+file1.write(content)
+file1.close()
+
+tmps = content.split('\n')
+workbook = xlwt.Workbook(encoding='utf-8')
+sheet1 = workbook.add_sheet('UID')
+num = 0
+for tmp in tmps:
+    lines = tmp.split('\t')
+    for i in range(len(lines)):
+        sheet1.write(num, i, lines[i].strip())
+    num += 1
+
+workbook.save('./file/UID_2020_09_09_06_14_44.xls')
+
+
+file.close()
+
+# url = 'http://192.168.136.35:8000/upload'
+# postData = {
+#     'area': 0,
+#     'token': token['access_token'],
+#     'fileName': content
+# }
+# # postData = json.dumps(postData)
+# print(postData)
+# res = requests.post(url=url, data=postData)
+# print(res)

+ 52 - 12
Ansjer/local_settings.py

@@ -17,6 +17,8 @@ INSTALLED_APPS = [
     'corsheaders',
     'corsheaders',
     'imagekit',
     'imagekit',
     'Model',
     'Model',
+    'PushModel',
+    'SerialModel',
 ]
 ]
 
 
 MIDDLEWARE = [
 MIDDLEWARE = [
@@ -31,7 +33,7 @@ MIDDLEWARE = [
     'django.contrib.messages.middleware.MessageMiddleware',
     'django.contrib.messages.middleware.MessageMiddleware',
     'django.middleware.clickjacking.XFrameOptionsMiddleware',
     'django.middleware.clickjacking.XFrameOptionsMiddleware',
     'django.middleware.security.SecurityMiddleware',
     'django.middleware.security.SecurityMiddleware',
-    'django_global_request.middleware.GlobalRequestMiddleware',
+    # 'django_global_request.middleware.GlobalRequestMiddleware',
 ]
 ]
 
 
 AUTHENTICATION_BACKENDS = (
 AUTHENTICATION_BACKENDS = (
@@ -72,17 +74,24 @@ TEMPLATES = [
 
 
 WSGI_APPLICATION = 'Ansjer.local_wsgi.application'
 WSGI_APPLICATION = 'Ansjer.local_wsgi.application'
 
 
-
 # 服务器类型
 # 服务器类型
-DATABASE_DATA = 'ansjerlocal'
+#业务数据库
+DATABASE_DATA = 'ansjertest'
 SERVER_HOST = '127.0.0.1'
 SERVER_HOST = '127.0.0.1'
 DATABASES_USER = 'root'
 DATABASES_USER = 'root'
-DATABASES_PASS = '123456'
+DATABASES_PASS = 'root'
 
 
-DATABASE_DATA2 = 'asjl'
+#推送数据库
+DATABASE_DATA2 = 'ansjerpush'
 SERVER_HOST2 = '127.0.0.1'
 SERVER_HOST2 = '127.0.0.1'
 DATABASES_USER2 = 'root'
 DATABASES_USER2 = 'root'
-DATABASES_PASS2 = '123456'
+DATABASES_PASS2 = 'root'
+
+#序列号公共数据库
+DATABASE_DATA3 = 'serial'
+SERVER_HOST3 = '127.0.0.1'
+DATABASES_USER3 = 'root'
+DATABASES_PASS3 = 'root'
 
 
 DATABASES = {
 DATABASES = {
     'default': {
     'default': {
@@ -104,15 +113,25 @@ DATABASES = {
         'PORT': '3306',
         'PORT': '3306',
         'OPTIONS': {'charset': 'utf8mb4', 'use_unicode': True, 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"},
         'OPTIONS': {'charset': 'utf8mb4', 'use_unicode': True, 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"},
         'AUTOCOMMIT': True
         'AUTOCOMMIT': True
-    }
+    },
+    'mysql03': {
+        'ENGINE': 'django.db.backends.mysql',
+        'NAME': DATABASE_DATA3,
+        'USER': DATABASES_USER3,
+        'PASSWORD': DATABASES_PASS3,
+        'HOST': SERVER_HOST3,
+        'PORT': '3306',
+        'OPTIONS': {'charset': 'utf8mb4', 'use_unicode': True, 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"},
+        'AUTOCOMMIT': True
+    },
 }
 }
 DATABASE_ROUTERS = ['Ansjer.database_router.DatabaseAppsRouter']
 DATABASE_ROUTERS = ['Ansjer.database_router.DatabaseAppsRouter']
 DATABASE_APPS_MAPPING = {
 DATABASE_APPS_MAPPING = {
-    'db1': 'default',
-    'db2': 'mysql02',
+    'Model': 'default',
+    'PushModel': 'mysql02',
+    'SerialModel': 'mysql03',
 }
 }
 
 
-
 AUTH_PASSWORD_VALIDATORS = [
 AUTH_PASSWORD_VALIDATORS = [
     {
     {
         'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
         'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
@@ -171,8 +190,7 @@ CORS_ALLOW_HEADERS = (
 '''
 '''
 # 管理员邮箱
 # 管理员邮箱
 ADMINS = (
 ADMINS = (
-    ('admin', 'chanjunkai@163.com'),
-    ('admin', '1379072853@qq.com'),
+    ('admin', 'sonalh@foxmail.com'),
 )
 )
 
 
 # 非空链接,却发生404错误,发送通知MANAGERS
 # 非空链接,却发生404错误,发送通知MANAGERS
@@ -197,6 +215,12 @@ LOGGING = {
             # 'format': '{"asctime":"%(asctime)s","thread":"%(threadName)s:%(thread)d","errorline":"%(lineno)d","errorlevel":"%(levelname)s","errorcontent":"%(message)s"}'
             # 'format': '{"asctime":"%(asctime)s","thread":"%(threadName)s:%(thread)d","errorline":"%(lineno)d","errorlevel":"%(levelname)s","errorcontent":"%(message)s"}'
             'format': '%(asctime)s %(threadName)s %(thread)d %(lineno)d %(levelname)s %(message)s'
             'format': '%(asctime)s %(threadName)s %(thread)d %(lineno)d %(levelname)s %(message)s'
         },
         },
+        'standard': {
+            'format': '[%(asctime)s] [%(filename)s:%(lineno)d] [%(module)s:%(funcName)s] '
+                      '[%(levelname)s]- %(message)s'},
+        'simple': {  # 简单格式
+            'format': '%(levelname)s %(message)s'
+        },
     },
     },
     'filters': {
     'filters': {
     },
     },
@@ -220,6 +244,16 @@ LOGGING = {
             'class': 'logging.StreamHandler',
             'class': 'logging.StreamHandler',
             'formatter': 'error_format'
             'formatter': 'error_format'
         },
         },
+        # 输出info日志
+        'info': {
+            'level': 'INFO',
+            'class': 'logging.handlers.RotatingFileHandler',
+            'filename': BASE_DIR + '/static/log/info.log',
+            'maxBytes': 1024 * 1024 * 5,
+            'backupCount': 5,
+            'formatter': 'standard',
+            'encoding': 'utf-8',  # 设置默认编码
+        },
     },
     },
     'loggers': {
     'loggers': {
         'django': {
         'django': {
@@ -229,6 +263,12 @@ LOGGING = {
             'level': 'DEBUG',
             'level': 'DEBUG',
             'propagate': True
             'propagate': True
         },
         },
+        # log 调用时需要当作参数传入
+        'log': {
+            'handlers': ['info', 'console', 'default'],
+            'level': 'INFO',
+            'propagate': True
+        },
         # 'django.db.backends': {
         # 'django.db.backends': {
         #     'handlers': ['console'],
         #     'handlers': ['console'],
         #     'propagate': True,
         #     'propagate': True,

+ 27 - 0
Ansjer/push_element_into_redis.py

@@ -0,0 +1,27 @@
+import _thread
+
+from Object.RedisObject import RedisObject
+
+key = 'serial_lock'
+key1 = 'create_serial_lock'
+key2 = 'company_serial_lock'
+redisObject = RedisObject()
+
+value = redisObject.lrange(key, 0, 1)
+if len(value) == 0:
+    redisObject.rpush(key, 1)
+
+value = redisObject.lrange(key1, 0, 1)
+if len(value) == 0:
+    redisObject.rpush(key1, 1)
+
+value = redisObject.lrange(key2, 0, 1)
+if len(value) == 0:
+    redisObject.rpush(key2, 1)
+
+
+
+
+
+
+

+ 199 - 0
Ansjer/pushconfig.py

@@ -0,0 +1,199 @@
+#!/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/7/2 14:06
+@Version: python3.6
+@MODIFY DECORD:ansjer dev
+@file: Conf.py
+@Contact: chanjunkai@163.com
+"""
+# 主要静态变量配置文件
+import datetime, os
+
+
+DEBUG_MODE = 'DEV'
+# MODE = 'PRO'
+# 阿里云发邮箱
+ALY_SES_ACCESS_NAME = 'message@dvema.com'
+ALY_SES_ACCESS_PAW = 'SMtp123456'
+ALY_SES_ACCESS_REPLYTO = '***'
+
+# 发送邮件邮箱
+SES_COMPANY_EMAIL = 'user_server@nsst.com'
+AWS_SES_ACCESS_ID = 'AKIAJKPU23EU5QWHFPKQ'
+AWS_SES_ACCESS_SECRET = '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'
+AWS_SES_ACCESS_REGION = 'us-east-1'
+AWS_BUCKET = 'ansjertest'
+# 设定离线时间为5分钟
+OFF_LINE_TIME_DELTA = 5
+
+# token的secret
+OAUTH_ACCESS_TOKEN_SECRET = 'a+jbgnw%@1%zy^=@dn62%'
+OAUTH_REFRESH_TOKEN_SECRET = 'r+jbgnw%@1%zy^=@dn62%'
+# access_token超时
+# OAUTH_ACCESS_TOKEN_TIME = datetime.timedelta(hours=1)
+OAUTH_ACCESS_TOKEN_TIME = datetime.timedelta(days=30)
+# refresh_token超时
+OAUTH_REFRESH_TOKEN_TIME = datetime.timedelta(days=30)
+# 腾讯验证,短信发送
+TX_PHONE_APP_ID = '1400052907'
+TX_PHONE_APP_KEY = '7705976ca6e85fe7b86d6bc2d11f7783'
+
+# 验证码超时时间
+AuthCode_Expire = 600
+
+# 根路径
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+# uid token key
+UID_TOKEN_KEY = 'c+565*j@%^'
+
+# oss param
+OSS_STS_ACCESS_KEY = 'LTAIyMkGfEdogyL9'
+OSS_STS_ACCESS_SECRET = '71uIjpsqVOmF7DAITRyRuc259jHOjO'
+OSS_ROLE_ARN = 'acs:ram::1901342792446414:role/stsoss'
+
+# aws api key
+AWS_ACCESS_KEY_ID = ['AKIA2MMWBR4DSFG67DTG', 'AKIA2E67UIMD45Y3HL53']  # 0国内, 1国外
+AWS_SECRET_ACCESS_KEY = ['aI9gxcAKPmiGgPy9axrtFKzjYGbvpuytEX4xWweL', 'ckYLg4Lo9ZXJIcJEAKkzf2rWvs8Xth1FCjqiAqUw']
+AWS_ARN = ['arn:aws-cn:s3', 'arn:aws:s3']
+
+
+NGINX_RTMP_STAT = 'http://www.dvema.com/stat'
+SERVER_DOMAIN = 'http://www.dvema.com/'
+SERVER_DOMAIN_SSL = 'https://www.dvema.com/'
+DOMAIN_HOST = 'www.dvema.com'
+# SERVER_HOST = 'localhost'
+PAYPAL_CRD = {
+    "mode": "live",  # sandbox or live
+    "client_id": "AdSRd6WBn-qLl9OiQHQuNYTDFSx0ZX0RUttqa58au8bPzoGYQUrt8bc6591RmH8_pEAIPijdvVYSVXyI",
+    "client_secret": "ENT-J08N3Fw0B0uAokg4RukljAwO9hFHPf8whE6-Dwd8oBWJO8AWMgpdTKpfB1pOy89t4bsFEzMWDowm"
+}
+DETECT_PUSH_DOMAIN = 'http://push.dvema.com/'
+
+
+JPUSH_CONFIG = {
+    'com.ansjer.accloud_ab': {
+        'Key': 'f0dc047e5e53fd14199de5b0',
+        'Secret': 'aa7f7db33e9f0a7f3871aa1c'},
+    'com.ansjer.adcloud_ab': {
+        'Key': '76d97b535185114985608234',
+        'Secret': 'c9a92b301043cc9c52778692'},
+    'com.ansjer.zccloud_ab': {
+        'Key': 'd9924f56d3cc7c6017965130',
+        'Secret': '869d832d126a232f158b5987'},
+    'com.ansjer.loocamccloud_ab': {
+        'Key': 'd1cc44797b4642b0e05304fe',
+        'Secret': 'c3e8b4ca8c576de61401e56a'},
+    'com.ansjer.loocamdcloud_ab': {
+        'Key': '76d97b535185114985608234',
+        'Secret': 'c9a92b301043cc9c52778692'},
+    'com.ansjer.zccloud_a': {
+        'Key': '57de2a80d68bf270fd6bdf5a',
+        'Secret': '3d354eb6a0b49c2610decf42'},
+    'com.ansjer.accloud_a': {
+        'Key': 'ff95ee685f49c0dc4013347b',
+        'Secret': 'de2c20959f5516fdeeafe78e'},
+    'com.ansjer.adcloud_a': {
+        'Key': '2e47eb1aee9b164460df3668',
+        'Secret': 'b9137d8d684bc248f1809b6d'},
+    'com.ansjer.loocamccloud_a': {
+        'Key': '23c9213215c7ca0ec945629b',
+        'Secret': '81e4b1e859cc8387e2e6c431'},
+    'com.ansjer.loocamdcloud_a': {
+        'Key': '1dbdd60a16e9892d6f68a073',
+        'Secret': '80a97690e7e043109059b403'},
+    'com.ansjer.customizedb_a': {
+        'Key': '9d79630aa49adfa291fe2568',
+        'Secret': '4d8ff52f88136561875a0212'},
+    'com.ansjer.customizedd_a': {
+        'Key': '8fc4f495685bde53341ee25d',
+        'Secret': 'f1da11fa466509fa2670fb66',
+    }
+}
+# type =1
+FCM_CONFIG = {
+    'com.ansjer.zccloud_a': 'AAAAb9YP3rk:APA91bHu8u-CTpcd0g6lKPo0WNVqCi8jZub1cPPbSAY9AucT1HxlF65ZDUko9iG8q2ch17bwu9YWHpK1xI1gHSRXCslLvZlXEmHZC0AG3JKg15XuUvlFKACIajUFV-pOeGRT8tM6-31I',
+    'com.ansjer.loocamccloud_a': 'AAAAb9YP3rk:APA91bFCgd-kbVmpK4EVpfdHH_PJZQCYTkOGnTZdIuBWEz2r7aMRsJYHOH3sB-rwcbaRWgnufTyjX9nGQxb6KxQbWVk4ah_H-M3IqGh6Mb60WQQAuR33V6g_Jes5pGL6ViuIxGHqVMaR',
+    'com.ansjer.loocamdcloud_a': 'AAAAb9YP3rk:APA91bGw2I2KMD4i-5T7nZO_wB8kuAOuqgyqe5rxmY-W5qkpYEx9IL2IfmC_qf6B_xOyjIDDSjckvMo-RauN__SEoxvAkis7042GRkoKpw7cjZ_H8lC-d50PC0GclPzccrOGFusyKbFY',
+    'com.ansjer.customizedb_a': 'AAAAb9YP3rk:APA91bE7kI4vcm-9h_CJNFlOZfc-xwP4Btn6AnjOrwoKV6fgYN7fdarkO76sYxVZiAbDnxsFfOJyP7vQfwyan6mdjuyD5iHdt_XgO22VqniC0vA1V4GJiCS8Tp7LxIX8JVKZl9I_Powt',
+    'com.ansjer.customizeda_a': 'AAAAb9YP3rk:APA91bF0HzizVWDc6dKzobY9fsaKDK4veqkOZehDXshVXs8pEEvNWjR_YWbhP60wsRYCHCal8fWN5cECVOWNMMzDsfU88Ty2AUl8S5FtZsmeDTkoGntQOswBr8Ln7Fm_LAp1VqTf9CpM',
+    'com.ansjer.customizedd_a': 'AAAAb9YP3rk:APA91bHkxOozJWBrlv3eNT0PgwosYENI9aM4Zuzd418cX-iKkpa1zFNC5MkNDKApx1KH4fhmAfaJ6IMRZ0nj5GIxCpstDYCaZWwgC7-etqfSxG5JAq8LOwJx0o_1tUZqwjIic8ztsg0o',
+    'com.ansjer.adcloud_a': 'AAAAb9YP3rk:APA91bFm06w8b9OKQ0gz0iaWFuRqRIkvgAz6z7Gp3dBU_X-LNGJQd1hc1QR2W7QzBglF8SHtERA45a2lbdLRa5qv7hxfd6W_sJLBK7dA8jklsOQBvy505oUzTwMKWy4TwH-exps9KrhO',
+    'com.ansjer.accloud_a': 'AAAAb9YP3rk:APA91bFm06w8b9OKQ0gz0iaWFuRqRIkvgAz6z7Gp3dBU_X-LNGJQd1hc1QR2W7QzBglF8SHtERA45a2lbdLRa5qv7hxfd6W_sJLBK7dA8jklsOQBvy505oUzTwMKWy4TwH-exps9KrhO',
+    'com.ansjer.zccloud_ab': 'AAAAb9YP3rk:APA91bHu8u-CTpcd0g6lKPo0WNVqCi8jZub1cPPbSAY9AucT1HxlF65ZDUko9iG8q2ch17bwu9YWHpK1xI1gHSRXCslLvZlXEmHZC0AG3JKg15XuUvlFKACIajUFV-pOeGRT8tM6-31I',
+}
+SERVER_TYPE = os.environ.get('DJANGO_SETTINGS_MODULE')
+
+APNS_CONFIG = {
+    'com.ansjer.loocamccloud': {
+        'pem_path': 'AnsjerPush/file/apns_pem/lcc-dev.pem',
+    },
+    'com.ansjer.zosidcloud': {
+        'pem_path': 'AnsjerPush/file/apns_pem/zosidcloud-dev.pem',
+    },
+    'com.ansjer.customizedb': {
+        'pem_path': 'AnsjerPush/file/apns_pem/customizedb-dev.pem',
+    },
+    'com.ansjer.customizeda': {
+        'pem_path': 'AnsjerPush/file/apns_pem/customizeda-dev.pem',
+    },
+    'com.ansjer.zccloud': {
+        'pem_path': 'AnsjerPush/file/apns_pem/zccloud-dev.pem',
+    },
+    'com.ansjer.accloud': {
+        'pem_path': 'AnsjerPush/file/apns_pem/accloud-dev.pem',
+    },
+    'com.ansjer.customizedc':{
+        'pem_path': 'AnsjerPush/file/apns_pem/customizedc.pem',
+    }
+}
+APNS_MODE = 'dev'
+REDIS_ADDRESS = '127.0.0.1'
+
+if SERVER_TYPE == 'AnsjerPush.local_settings':
+    from AnsjerPush.local_config import *
+elif SERVER_TYPE == 'AnsjerPush.test_settings':
+    from AnsjerPush.test_config import *
+elif SERVER_TYPE == 'AnsjerPush.formal_settings':
+    from AnsjerPush.formal_config import *
+
+APNS_CODE = {
+    -1: '只库存不推送',
+    200: '推送成功',
+    400: '请求有问题',
+    403: '证书或Token有问题',
+    405: '请求方式不正确, 只支持POST请求',
+    410: '设备的Token与证书不一致'
+}
+
+JPUSH_CODE = {
+    -1: '只库存不推送',
+    200: '推送成功',
+    400: '错误请求',
+    401: '没有验证信息或者验证失败',
+    403: '请求被拒绝',
+    404: '资源不存在,请求的用户的不存在,请求的格式不被支持',
+    405: '请求方法不合适',
+    410: '请求的资源已下线',
+    429: '请求超出了频率限制',
+    500: '极光内部服务错误',
+    502: '业务服务器下线了或者正在升级。请稍后重试',
+    503: '服务暂时失效',
+    504: '代理超时'
+}
+
+FCM_CODE = {
+    -1: '只库存不推送',
+    200: '推送成功',
+    400: '无效数据',
+    401: '没有验证信息或者验证失败'
+}
+
+APP_TYPE = {
+    1: 'ios',
+    2: 'android'
+}

+ 38 - 9
Ansjer/test_settings.py

@@ -17,6 +17,8 @@ INSTALLED_APPS = [
     'corsheaders',
     'corsheaders',
     'imagekit',
     'imagekit',
     'Model',
     'Model',
+    'PushModel',
+    'SerialModel',
 ]
 ]
 
 
 MIDDLEWARE = [
 MIDDLEWARE = [
@@ -74,11 +76,13 @@ WSGI_APPLICATION = 'Ansjer.test_wsgi.application'
 
 
 
 
 # 服务器类型
 # 服务器类型
+#业务数据库
 DATABASE_DATA = 'AnsjerTest'
 DATABASE_DATA = 'AnsjerTest'
 SERVER_HOST = 'database-2.clraczw4p0yj.us-west-1.rds.amazonaws.com'
 SERVER_HOST = 'database-2.clraczw4p0yj.us-west-1.rds.amazonaws.com'
 DATABASES_USER = 'azrds'
 DATABASES_USER = 'azrds'
 DATABASES_PASS = 'azrds.x.x'
 DATABASES_PASS = 'azrds.x.x'
 
 
+#推送数据库
 DATABASE_DATA2 = 'AnsjerTest'
 DATABASE_DATA2 = 'AnsjerTest'
 SERVER_HOST2 = 'ansjerpush.clraczw4p0yj.us-west-1.rds.amazonaws.com'
 SERVER_HOST2 = 'ansjerpush.clraczw4p0yj.us-west-1.rds.amazonaws.com'
 DATABASES_USER2 = 'azrds'
 DATABASES_USER2 = 'azrds'
@@ -104,11 +108,12 @@ DATABASES = {
         'PORT': '3306',
         'PORT': '3306',
         'OPTIONS': {'charset': 'utf8mb4', 'use_unicode': True, 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"},
         'OPTIONS': {'charset': 'utf8mb4', 'use_unicode': True, 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"},
         'AUTOCOMMIT': True
         'AUTOCOMMIT': True
-    }
+    },
 }
 }
+
 DATABASE_ROUTERS = ['Ansjer.database_router.DatabaseAppsRouter']
 DATABASE_ROUTERS = ['Ansjer.database_router.DatabaseAppsRouter']
 DATABASE_APPS_MAPPING = {
 DATABASE_APPS_MAPPING = {
-    'db1': 'default',
+    'Model': 'default',
     'db2': 'mysql02',
     'db2': 'mysql02',
 }
 }
 
 
@@ -170,8 +175,7 @@ CORS_ALLOW_HEADERS = (
 '''
 '''
 # 管理员邮箱
 # 管理员邮箱
 ADMINS = (
 ADMINS = (
-    ('admin', 'chanjunkai@163.com'),
-    ('admin', '1379072853@qq.com'),
+    ('admin', 'sonalh@foxmail.com'),
 )
 )
 
 
 # 非空链接,却发生404错误,发送通知MANAGERS
 # 非空链接,却发生404错误,发送通知MANAGERS
@@ -196,6 +200,10 @@ LOGGING = {
             # 'format': '{"asctime":"%(asctime)s","thread":"%(threadName)s:%(thread)d","errorline":"%(lineno)d","errorlevel":"%(levelname)s","errorcontent":"%(message)s"}'
             # 'format': '{"asctime":"%(asctime)s","thread":"%(threadName)s:%(thread)d","errorline":"%(lineno)d","errorlevel":"%(levelname)s","errorcontent":"%(message)s"}'
             'format': '%(asctime)s %(threadName)s %(thread)d %(lineno)d %(levelname)s %(message)s'
             'format': '%(asctime)s %(threadName)s %(thread)d %(lineno)d %(levelname)s %(message)s'
         },
         },
+        'standard': {
+            'format': '[%(asctime)s] [%(filename)s:%(lineno)d] [%(module)s:%(funcName)s] '
+                      '[%(levelname)s]- %(message)s'},
+
     },
     },
     'filters': {
     'filters': {
     },
     },
@@ -207,10 +215,10 @@ LOGGING = {
         },
         },
         'default': {
         'default': {
             'level': 'ERROR',
             'level': 'ERROR',
-            'class': 'logging.handlers.RotatingFileHandler',
-            'filename': BASE_DIR + '/static/log/error.log',
-            'maxBytes': 1024 * 1024 * 5,  # 5 MB
-            'backupCount': 5,
+            'class': 'logging.handlers.TimedRotatingFileHandler',
+            'filename': BASE_DIR + '/static/log/error/error.log',
+            'backupCount': 30,
+            'when': 'D',
             'formatter': 'error_format',
             'formatter': 'error_format',
         },
         },
         'console': {
         'console': {
@@ -218,13 +226,34 @@ LOGGING = {
             'class': 'logging.StreamHandler',
             'class': 'logging.StreamHandler',
             'formatter': 'error_format'
             'formatter': 'error_format'
         },
         },
+        'info': {
+            'level': 'INFO',
+            'class': 'logging.handlers.TimedRotatingFileHandler',
+            'filename': BASE_DIR + '/static/log/info/info.log',
+            'backupCount': 30,
+            'when': 'D',
+            'formatter': 'standard',
+            'encoding': 'utf-8',
+        },
     },
     },
     'loggers': {
     'loggers': {
         'django': {
         'django': {
             'handlers': ['default', 'console'],
             'handlers': ['default', 'console'],
             # 'handlers': ['mail_admins','default','console'],
             # 'handlers': ['mail_admins','default','console'],
+            # 'level': 'ERROR',
             'level': 'ERROR',
             'level': 'ERROR',
             'propagate': False
             'propagate': False
         },
         },
+        # log 调用时需要当作参数传入
+        'info': {
+            'handlers': ['info'],
+            'level':'INFO',
+            'propagate': False
+        }
+        # 'django.db.backends': {
+        #     'handlers': ['console'],
+        #     'propagate': True,
+        #     'level': 'DEBUG',
+        # },
     }
     }
-}
+}

+ 27 - 0
Ansjer/test_statistics_push_day_task.py

@@ -0,0 +1,27 @@
+import json
+
+import requests
+
+
+# url = 'http://test.dvema.com'
+base_url = 'http://test.dvema.com/'
+username='13800138001'
+password='ansjer999999'
+login_url = base_url + 'account/login'
+
+data = {
+    'userName': username,
+    'userPwd': password
+}
+res = requests.post(url=login_url, data=data)
+res = res.json()
+print(res)
+
+if res['result_code'] == 0:
+    statistics_url = base_url + 'statistcs/pushDay'
+    data = {
+        'token': res['result']['access_token']
+    }
+    res = requests.post(url=statistics_url, data=data)
+    print(res.json())
+

+ 27 - 0
Ansjer/test_statistics_push_month_task.py

@@ -0,0 +1,27 @@
+import json
+
+import requests
+
+
+# url = 'http://test.dvema.com'
+base_url = 'http://test.dvema.com/'
+username='13800138001'
+password='ansjer999999'
+login_url = base_url + 'account/login'
+
+data = {
+    'userName': username,
+    'userPwd': password
+}
+res = requests.post(url=login_url, data=data)
+res = res.json()
+print(res)
+
+if res['result_code'] == 0:
+    statistics_url = base_url + 'statistcs/pushMonth'
+    data = {
+        'token': res['result']['access_token']
+    }
+    res = requests.post(url=statistics_url, data=data)
+    print(res.json())
+

+ 48 - 0
Ansjer/test_zositech_help_weekly_task.py

@@ -0,0 +1,48 @@
+import json
+
+import requests
+import time
+
+
+# url = 'http://test.dvema.com'
+# base_url = 'http://127.0.0.1:8000/'
+base_url = 'http://test.dvema.com/'
+username='13800138001'
+password='ansjer999999'
+login_url = base_url + 'account/login'
+
+data = {
+    'userName': username,
+    'userPwd': password
+}
+res = requests.post(url=login_url, data=data, timeout=10)
+res = res.json()
+
+if res['result_code'] == 0:
+    request_times = 0
+    while request_times < 5:
+        try:
+            statistics_url = base_url + 'faq/synZositechHelp'
+            # zh_url = 'https://mobileapphelp.zendesk.com/api/v2/help_center/articles/embeddable_search.json?locale=zh-cn&section=null&origin=web_widget'
+            zh_url = 'https://mobileapphelp.zendesk.com/api/v2/help_center/zh-cn/articles.json?page%5Bsize%5D=100'
+            zhcnDatares = requests.get(url=zh_url, timeout=10).text
+
+            en_url = 'https://mobileapphelp.zendesk.com/api/v2/help_center/en-us/articles.json?page%5Bsize%5D=100'
+            # en_url = 'https://mobileapphelp.zendesk.com/api/v2/help_center/articles/embeddable_search.json?locale=en-us&section=null&origin=web_widget'
+            enusDatares = requests.get(url=en_url, timeout=10).text
+            data = {
+                'token': res['result']['access_token'],
+                'zhresults': zhcnDatares,
+                'enresults': enusDatares
+            }
+            res = requests.post(url=statistics_url, data=data)
+
+        except Exception as e:
+            print(e)
+            request_times += 1
+            print(request_times)
+            time.sleep(3)
+
+print('success')
+
+

+ 83 - 5
Ansjer/urls.py

@@ -1,3 +1,4 @@
+from django.contrib import admin
 from django.conf.urls import url
 from django.conf.urls import url
 from django.urls import path, re_path
 from django.urls import path, re_path
 
 
@@ -10,11 +11,17 @@ from Controller import FeedBack, EquipmentOTA, EquipmentInfo, AdminManage, AppIn
     StsOssController, UIDPreview, OssCrd, SysMsg, UidUser, EquipmentManagerV2, EquipmentManagerV3, PushDeploy, \
     StsOssController, UIDPreview, OssCrd, SysMsg, UidUser, EquipmentManagerV2, EquipmentManagerV3, PushDeploy, \
     AppSetController, \
     AppSetController, \
     ApplicationController, UserExController, CloudStorage, TestApi, UserBrandControllerV2, \
     ApplicationController, UserExController, CloudStorage, TestApi, UserBrandControllerV2, \
-    StatisticsController, Alexa, FAQController, AppLogController, EquipmentVersionLimit
+    StatisticsController, Alexa, FAQController, AppLogController, EquipmentVersionLimit, VoicePromptController, \
+    CDKController, \
+    DeviceTypeController, CloudTransfer, Cloudsum, IotCoreController, OperatingLogs, ProcessInfo, \
+    RegionCountryController, \
+    VerifyCodeController, FileController, UIDController, LogController, SalesController, \
+    OrderTaskController, HistoryUIDController, UIDManageUserController, SerialNumberController, CompanyController, \
+    RegionController, VPGController, LanguageController, TestController, DeviceConfirmRegion, S3GetStsController, \
+    DetectControllerV2, ShadowController, TestDetectController
 
 
 urlpatterns = [
 urlpatterns = [
     url(r'^testApi/(?P<operation>.*)$', TestApi.testView.as_view()),
     url(r'^testApi/(?P<operation>.*)$', TestApi.testView.as_view()),
-
     url(r'^account/authcode$', UserController.authCodeView.as_view()),
     url(r'^account/authcode$', UserController.authCodeView.as_view()),
     url(r'^v3/account/generatepictureCodeView/$', UserController.generatePictureCodeView.as_view()),
     url(r'^v3/account/generatepictureCodeView/$', UserController.generatePictureCodeView.as_view()),
     url(r'^v3/account/imageCodeRegister/$', UserController.Image_Code_RegisterView.as_view()),
     url(r'^v3/account/imageCodeRegister/$', UserController.Image_Code_RegisterView.as_view()),
@@ -46,6 +53,7 @@ urlpatterns = [
     url(r'^equipment/findEquipmentInfo$', EquipmentManager.findEquipmentInfoInterface),
     url(r'^equipment/findEquipmentInfo$', EquipmentManager.findEquipmentInfoInterface),
     # 新删除设备接口
     # 新删除设备接口
     url(r'^equipment/delete', EquipmentManager.deleteInterface),
     url(r'^equipment/delete', EquipmentManager.deleteInterface),
+    url(r'^equipment/batchDelete', EquipmentManager.batchDeleteInterface),
     url(r'^equipment/add', EquipmentManager.addInterface),
     url(r'^equipment/add', EquipmentManager.addInterface),
     url(r'^equipment/admin_add', EquipmentManager.admin_addInterface),
     url(r'^equipment/admin_add', EquipmentManager.admin_addInterface),
     url(r'^equipment/admin_modify', EquipmentManager.admin_modifyInterface),
     url(r'^equipment/admin_modify', EquipmentManager.admin_modifyInterface),
@@ -104,12 +112,14 @@ urlpatterns = [
     # 统计访问日志路径
     # 统计访问日志路径
     path('access/staticPath/', AccessLog.statisticsPath),
     path('access/staticPath/', AccessLog.statisticsPath),
     path('access/deleteSn/', AccessLog.deleteSn),
     path('access/deleteSn/', AccessLog.deleteSn),
-    path('eq/del', EquipmentInfo.deleteExpireEquipmentInfo),
+    path('eq/delById', EquipmentInfo.deleteExpireEquipmentInfoById),
     # 新需求ota接口
     # 新需求ota接口
     url(r'^OTA/getNewVer', OTAEquipment.getNewVerInterface),
     url(r'^OTA/getNewVer', OTAEquipment.getNewVerInterface),
     url(r'^OTA/uploadsPack$', OTAEquipment.uploadOTAInterfaceView.as_view()),
     url(r'^OTA/uploadsPack$', OTAEquipment.uploadOTAInterfaceView.as_view()),
     url(r'^OTA/downloadsPack/(?P<fullPath>[0-9\w/.\-]+)', OTAEquipment.downloadOTAInterface),
     url(r'^OTA/downloadsPack/(?P<fullPath>[0-9\w/.\-]+)', OTAEquipment.downloadOTAInterface),
     url(r'^dlotapack/(?P<fullPath>[0-9\w/.\-]+)', OTAEquipment.downloadOTAInterfaceV2),
     url(r'^dlotapack/(?P<fullPath>[0-9\w/.\-]+)', OTAEquipment.downloadOTAInterfaceV2),
+    url(r'^OTA/getDownLoadOTApackUrl$', OTAEquipment.getDownLoadOTApackUrl),
+    url(r'^OTA/checkMaxVersion$', OTAEquipment.checkMaxVersion),
 
 
     # h获取验证码    # v2接口
     # h获取验证码    # v2接口
     url(r'^v2/account/authcode$', UserController.v2authCodeView.as_view()),
     url(r'^v2/account/authcode$', UserController.v2authCodeView.as_view()),
@@ -131,11 +141,18 @@ urlpatterns = [
     url(r'^v3/account/loginByFingerprint$', UserController.v3LoginByFingerprintView.as_view()),
     url(r'^v3/account/loginByFingerprint$', UserController.v3LoginByFingerprintView.as_view()),
     url(r'^v3/account/setFingerprint$', UserController.v3SetFingerprintView.as_view()),
     url(r'^v3/account/setFingerprint$', UserController.v3SetFingerprintView.as_view()),
 
 
-    # 新增
     url(r'^detect/detect_group_push$',DetectController.NotificationView.detect_group_push),
     url(r'^detect/detect_group_push$',DetectController.NotificationView.detect_group_push),
     url(r'^detect/add$', DetectController.PushNotificationView.as_view()),
     url(r'^detect/add$', DetectController.PushNotificationView.as_view()),
+    # 推送项目接口
     url(r'^detect/(?P<operation>.*)$', DetectController.DetectControllerView.as_view()),
     url(r'^detect/(?P<operation>.*)$', DetectController.DetectControllerView.as_view()),
     url(r'^notify/push$', DetectController.NotificationView.as_view()),
     url(r'^notify/push$', DetectController.NotificationView.as_view()),
+    url(r'^detectV2/(?P<operation>.*)$', DetectControllerV2.DetectControllerViewV2.as_view()),
+    url(r'^notifyV2/push$', DetectControllerV2.NotificationView.as_view()),
+    url(r'^deviceShadow/update$', ShadowController.update_device_shadow),
+    url(r'^deviceShadow/generateUTK$', ShadowController.generate_utk),
+    url(r'^test/notify/push$', TestDetectController.NotificationView.as_view()),
+    url(r'^eq/del$', EquipmentInfo.deleteExpireEquipmentInfo),
+    # 新增
     url(r'^cloudVod/(?P<operation>.*)$', CloudVod.CloudVodView.as_view()),
     url(r'^cloudVod/(?P<operation>.*)$', CloudVod.CloudVodView.as_view()),
     url(r'^meal/(?P<operation>.*)$', MealManage.MealView.as_view()),
     url(r'^meal/(?P<operation>.*)$', MealManage.MealView.as_view()),
     url(r'^order/(?P<operation>.*)$', OrderContrller.OrderView.as_view()),
     url(r'^order/(?P<operation>.*)$', OrderContrller.OrderView.as_view()),
@@ -149,6 +166,7 @@ urlpatterns = [
 
 
     # 屏蔽
     # 屏蔽
     url(r'^user/initInfo$', UserController.InitInfoView.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),
     url(r'^getTZ$', EquipmentStatus.getTZ),
 
 
@@ -177,7 +195,10 @@ urlpatterns = [
     url(r'^oauth/unbunding', UserController.UnbundingWXView.as_view()),
     url(r'^oauth/unbunding', UserController.UnbundingWXView.as_view()),
 
 
     # 删除云存视频
     # 删除云存视频
-    path('cv/del', CloudVod.deleteVodHls),
+    # path('cv/del', CloudVod.deleteVodHls),
+    path('cv/del', CloudStorage.deleteVodHls),
+    path('cv/updateExpiredUidBucket', CloudStorage.updateExpiredUidBucket),
+    path('cv/updateUnusedUidBucket', CloudStorage.updateUnusedUidBucket),
     url(r'^equipment/judge', EquipmentManager.judgeInterface),
     url(r'^equipment/judge', EquipmentManager.judgeInterface),
 
 
     # ap模式,新增设备表
     # ap模式,新增设备表
@@ -218,6 +239,8 @@ urlpatterns = [
     url(r'^v2/userbrand/(?P<operation>.*)$', UserBrandControllerV2.UserBrandV2.as_view()),
     url(r'^v2/userbrand/(?P<operation>.*)$', UserBrandControllerV2.UserBrandV2.as_view()),
     url(r'^statistcs/appFrequencyMonth$', StatisticsController.statistcsAppFrequency),
     url(r'^statistcs/appFrequencyMonth$', StatisticsController.statistcsAppFrequency),
     url(r'^statistcs/appFrequencyYear$', StatisticsController.statistcsAppFrequencyYear),
     url(r'^statistcs/appFrequencyYear$', StatisticsController.statistcsAppFrequencyYear),
+    url(r'^statistcs/pushDay$', StatisticsController.statistcsPushDay),
+    url(r'^statistcs/pushMonth$', StatisticsController.statistcsPushMonth),
 
 
     #统计alexa连接数
     #统计alexa连接数
     url(r'^alexa/(?P<operation>.*)$', Alexa.AlexaConnectNum.as_view()),
     url(r'^alexa/(?P<operation>.*)$', Alexa.AlexaConnectNum.as_view()),
@@ -233,16 +256,71 @@ urlpatterns = [
 
 
     # 本地登录接口
     # 本地登录接口
     url(r'^local/(?P<operation>.*)$', UserController.LocalUserView.as_view()),
     url(r'^local/(?P<operation>.*)$', UserController.LocalUserView.as_view()),
+
     url(r'^account/updateUserCountry', UserController.updateUserCountry),
     url(r'^account/updateUserCountry', UserController.updateUserCountry),
     url(r'^equipmentVersionLimit/(?P<operation>.*)$', EquipmentVersionLimit.EquipmentVersionLimitView.as_view()),
     url(r'^equipmentVersionLimit/(?P<operation>.*)$', EquipmentVersionLimit.EquipmentVersionLimitView.as_view()),
 
 
     # 订阅邮件
     # 订阅邮件
     url(r'^account/subscribe$', UserController.SubscribeEmailView.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()),
 
 
     # app 设备消息模板
     # app 设备消息模板
     # 路由加参数参考
     # 路由加参数参考
     # url(r'^(?P<path>.*)/(?P<UID>.*)/lls$', Test.Test.as_view(), name=u'gg'),
     # url(r'^(?P<path>.*)/(?P<UID>.*)/lls$', Test.Test.as_view(), name=u'gg'),
     #testing....................
     #testing....................
+
+    #云存服务统计
+    url(r'^Cloudsum/(?P<operation>.*)$', Cloudsum.Cloudsum.as_view()),
+
+    #Iot Core
+    url(r'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('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('serialNumber/(?P<operation>.*)', SerialNumberController.SerialNumberView.as_view()),
+    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('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()),
+
     re_path('(?P<path>.*)', LogManager.errorPath),
     re_path('(?P<path>.*)', LogManager.errorPath),
 
 
 
 

+ 16 - 0
Ansjer/wsgi.py

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

+ 2 - 0
Controller/AccessLog.py

@@ -19,6 +19,8 @@ http://192.168.136.40:8077/accesslog?operation=queryByAdmin&token=test&page=1&li
 http://192.168.136.40:8077/accesslog?operation=truncateByAdmin&token=test
 http://192.168.136.40:8077/accesslog?operation=truncateByAdmin&token=test
 http://192.168.136.40:8077/accesslog?operation=searchByAdmin&token=test&page=1&line=10&content={"status":20}&order=-id
 http://192.168.136.40:8077/accesslog?operation=searchByAdmin&token=test&page=1&line=10&content={"status":20}&order=-id
 
 
+
+
 http://192.168.136.40:8077/accesslog/staticPath/?token=stest
 http://192.168.136.40:8077/accesslog/staticPath/?token=stest
 '''
 '''
 
 

+ 206 - 3
Controller/AdminManage.py

@@ -1,6 +1,8 @@
 # -*- coding: utf-8 -*-
 # -*- coding: utf-8 -*-
 import time
 import time
+from datetime import date, timedelta, timezone as asj_timezone
 
 
+import boto3
 import xlwt
 import xlwt
 from django.db.models import Count,Q
 from django.db.models import Count,Q
 from django.http import HttpResponse
 from django.http import HttpResponse
@@ -8,15 +10,18 @@ from django.views.decorators.csrf import csrf_exempt
 from django.views.generic import TemplateView
 from django.views.generic import TemplateView
 from django.utils.decorators import method_decorator
 from django.utils.decorators import method_decorator
 from django.contrib.auth.hashers import make_password  # 对密码加密模块
 from django.contrib.auth.hashers import make_password  # 对密码加密模块
+from openpyxl import workbook
+
 from Model.models import Device_Info, Role, UserExModel, User_Brand, UidSetModel, AppFrequencyYearStatisticsModel, \
 from Model.models import Device_Info, Role, UserExModel, User_Brand, UidSetModel, AppFrequencyYearStatisticsModel, \
-    AppFrequencyStatisticsModel
+    AppFrequencyStatisticsModel, EquipmentInfoExStatisticsModel, Equipment_Info
 from Service.ModelService import ModelService
 from Service.ModelService import ModelService
 from django.utils import timezone
 from django.utils import timezone
 from Model.models import Access_Log, Device_User
 from Model.models import Access_Log, Device_User
 from django.views.decorators.http import require_http_methods
 from django.views.decorators.http import require_http_methods
 from Object.ResponseObject import ResponseObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Object.TokenObject import TokenObject
-from Ansjer.config import OFF_LINE_TIME_DELTA, DEVICE_TYPE
+from Ansjer.config import OFF_LINE_TIME_DELTA, DEVICE_TYPE, AWS_SES_ACCESS_ID, AWS_SES_ACCESS_SECRET, \
+    AWS_SES_ACCESS_REGION_WEST
 import datetime, simplejson as json
 import datetime, simplejson as json
 from Service.CommonService import CommonService
 from Service.CommonService import CommonService
 from Object.RedisObject import RedisObject
 from Object.RedisObject import RedisObject
@@ -80,6 +85,12 @@ class AdminManage(TemplateView):
             return self.getAppFrequency(userID, request_dict, response)
             return self.getAppFrequency(userID, request_dict, response)
         if operation == 'getHistoryAppFrequency':
         if operation == 'getHistoryAppFrequency':
             return self.getAllAppFrequency(userID, response)
             return self.getAllAppFrequency(userID, response)
+        if operation == 'getPushStatistics':
+            return self.query_push_by_level(userID, request_dict, response)
+        if operation == 'getPushFailures':
+            return self.query_failures_push(userID, request_dict, response)
+        if operation == 'getPushServerCPUUsage':
+            return self.query_push_server_cpu_usage(userID, request_dict, response)
         if operation == 'downloadSubscribeEmail':
         if operation == 'downloadSubscribeEmail':
             return self.download_subscribe_email(userID, request_dict, response)
             return self.download_subscribe_email(userID, request_dict, response)
 
 
@@ -438,6 +449,196 @@ class AdminManage(TemplateView):
         else:
         else:
             return response.json(0, [])
             return response.json(0, [])
 
 
+    def query_push_by_level(self, userID, request_dict, response):
+        own_permission = ModelService.check_perm(userID=userID, permID=30)
+        if own_permission is not True:
+            return response.json(404)
+
+        level = request_dict.get('level', None)
+        print(level)
+        if level is None:
+            return response.json(444)
+
+        level = int(level)
+        if level < 0:
+            return response.json(444)
+        elif level < 3:
+            return self.query_push_day_statistics(level, response)
+        else:
+            return response.json(404)
+
+    def query_push_day_statistics(self, level, response):
+        start_time = 0
+
+        gmtime = time.gmtime(int(time.time()) + 28800)
+        current_day = gmtime.tm_mday
+        time_struct = [gmtime.tm_year, gmtime.tm_mon, current_day, 0, 0, 0, 0, 0, 0]
+        current_time = int(time.mktime(tuple(time_struct))) - 28800
+
+        count = 0
+        if level == 0: # 七天
+            start_time = current_time - 6 * 24 * 3600
+            count = 6
+        elif level == 1:
+            start_time = current_time - 13 * 24 * 3600
+            count = 13
+        elif level == 2:
+            start_time = current_time - 29 * 24 * 3600
+            count = 29
+
+        end_time = current_time
+
+        eqx_qs = EquipmentInfoExStatisticsModel.objects.filter(statistics_date__gte=start_time, statistics_date__lte=end_time, date_type=0, push_type=-1).values()
+        data = []
+
+        for i in range(count + 1):
+            data.append({
+                'date_time': int(start_time),
+                'data': None
+            })
+            start_time += (24 * 60 * 60)
+
+        tmp_dict = {}
+        successes = 0
+        failures = 0
+        for eqx in eqx_qs:
+            successes += eqx['number_of_successes']
+            failures += eqx['number_of_failures']
+            tmp_dict[eqx['statistics_date']] = {
+                'number_of_successes': eqx['number_of_successes'],
+                'number_of_failures': eqx['number_of_failures'],
+                'total': (eqx['number_of_successes'] + eqx['number_of_failures'])
+            }
+
+        # 取出当前的推送数据
+        start_time = current_time
+        current_time = int(time.time())
+        eq_qs = Equipment_Info.objects.filter(addTime__gte=start_time, addTime__lte=current_time)
+        print(eq_qs.values())
+        # 0:APNS推送,1:谷歌推送,2:极光推送
+        tmp = {
+            'number_of_successes': 0,
+            'number_of_failures': 0,
+            'total': 0
+        }
+        for eq in eq_qs:
+            if eq.push_server_status == 200:
+                tmp['number_of_successes'] += 1
+                successes += 1
+            else:
+                tmp['number_of_failures'] += 1
+                failures += 1
+            tmp['total'] += 1
+
+        tmp_dict[current_time] = tmp
+
+        for item in data:
+            if tmp_dict.__contains__(item['date_time']):
+                item['data'] = tmp_dict[item['date_time']]
+
+        success_rate = round(successes / (successes + failures), 2)
+        arrival_rate = success_rate
+
+        res = {
+            'data': data,
+            'successes': successes,
+            'failures': failures,
+            'success_rate': success_rate,
+            'arrival_rate': arrival_rate
+        }
+
+        return response.json(0, res)
+
+    # def query_push_month_statistics(self, level, response):
+    #     start_time = 0
+    #     end_time = 0
+    #     localtime = time.localtime()
+    #     current_month = localtime.tm_mon
+    #
+    #     time_struct = [localtime.tm_year, current_month, 1, 0, 0, 0, 0, 0, 0]
+    #     current_time = int(time.mktime(tuple(time_struct)))
+    #     current_time = current_time - time.timezone - 8 * 60 * 60
+    #     count = 0
+    #     start_month = 0
+    #     if level == 3:  # 6个月
+    #         start_month = current_month - 5
+    #         count = 5
+    #     elif level == 4:
+    #         start_month = current_month - 11
+    #         count = 10
+    #
+    #
+    #     return
+
+    def query_failures_push(self, userID, request_dict, response):
+        own_permission = ModelService.check_perm(userID=userID, permID=30)
+        if own_permission is not True:
+            return response.json(404)
+
+        start_time = request_dict.get('start_time', None)
+        end_time = request_dict.get('end_time', None)
+        page = request_dict.get('page', None)
+        line = request_dict.get('line', None)
+
+        if not start_time or not end_time or not page or not line:
+            return response.json(444)
+
+        start_time = int(start_time)
+        end_time = int(end_time)
+        page = int(page)
+        line = int(line)
+        if page <= 0 or line < 0:
+            return response.json(444, 'page, line')
+
+        eq_qs = Equipment_Info.objects.filter(addTime__gte=start_time, addTime__lte=end_time)\
+            .filter(~Q(push_server_status=200)).values('id', 'devUid', 'devNickName', 'Channel', 'alarm', 'eventType', 'eventTime', 'receiveTime', 'push_server_status', 'userID__username')
+        if eq_qs.exists():
+            count = eq_qs.count()
+            eq_qs = eq_qs[(page-1)*line: page * line]
+            return response.json(0, {'count': count, 'data': list(eq_qs)})
+        else:
+            return response.json(0, {'count': 0, 'data': []})
+
+    def query_push_server_cpu_usage(self, userID, request_dict, response):
+        own_permission = ModelService.check_perm(userID=userID, permID=30)
+        if own_permission is not True:
+            return response.json(404)
+
+        start_time = request_dict.get('start_time', None)
+        end_time = request_dict.get('end_time', None)
+        tz = request_dict.get('tz', None)
+
+        if start_time is None or end_time is None or tz is None:
+            return response.json(444)
+
+        date = datetime.datetime(2020, 9, 15)
+        start_time = date.fromtimestamp((int(start_time)))
+        end_time = date.fromtimestamp(int(end_time))
+        tz = int(tz)
+
+        cloudwatch = boto3.client('cloudwatch', region_name=AWS_SES_ACCESS_REGION_WEST, aws_access_key_id=AWS_SES_ACCESS_ID,
+                                  aws_secret_access_key=AWS_SES_ACCESS_SECRET)
+        try:
+            result = cloudwatch.get_metric_statistics(Namespace='AWS/EC2', MetricName='CPUUtilization',
+                                                      StartTime=start_time,
+                                                      EndTime=end_time, Period=60,
+                                                      Statistics=['Average'],
+                                                      Dimensions=[
+                                                          {'Name': 'InstanceId', 'Value': 'i-0596e00c9af077027'}])
+            datas = result['Datapoints']
+            datas.sort(key=getCompareKey)
+            result = []
+            for data in datas:
+                tmp = data
+                utcdt = data['Timestamp']
+                time1 = str(utcdt.astimezone(asj_timezone(timedelta(hours=int(-tz)))))
+                tmp['Timestamp'] = time1[0:time1.find('+')]
+                result.append(tmp)
+            return response.json(0, result)
+        except Exception as e:
+            print(repr(e))
+            return response.json(10, 'AWS Server Error')
+
     def download_subscribe_email(self, userID, request_dict, response):
     def download_subscribe_email(self, userID, request_dict, response):
         own_permission = ModelService.check_perm(userID=userID, permID=30)
         own_permission = ModelService.check_perm(userID=userID, permID=30)
         if own_permission is not True:
         if own_permission is not True:
@@ -462,6 +663,9 @@ class AdminManage(TemplateView):
         return response
         return response
 
 
 
 
+def getCompareKey(item):
+    return item['Timestamp']
+
 @require_http_methods(["GET"])
 @require_http_methods(["GET"])
 def getUserIds(request):
 def getUserIds(request):
     token = request.GET.get('token', None)
     token = request.GET.get('token', None)
@@ -547,4 +751,3 @@ def search_user_by_content(request):
         sqlDict['count'] = count
         sqlDict['count'] = count
         return response.json(0, sqlDict)
         return response.json(0, sqlDict)
     return response.json(0, {'datas': [], 'count': 0})
     return response.json(0, {'datas': [], 'count': 0})
-

+ 19 - 3
Controller/AppSetController.py

@@ -55,6 +55,7 @@ class AppSetView(View):
 
 
     # 查询
     # 查询
     def do_query(self, request_dict, response):
     def do_query(self, request_dict, response):
+        lang = request_dict.get('lang', None)
         appBundleId = request_dict.get('appBundleId', None)
         appBundleId = request_dict.get('appBundleId', None)
         if not appBundleId:
         if not appBundleId:
             return response.json(444,'appBundleId')
             return response.json(444,'appBundleId')
@@ -64,19 +65,34 @@ class AppSetView(View):
             key_id= "www"+appBundleId
             key_id= "www"+appBundleId
         else:
         else:
             key_id = "test" + appBundleId
             key_id = "test" + appBundleId
-        redis_value = redis.get_data(key=key_id)
+        #redis_value = redis.get_data(key=key_id)  去除到缓存中找
+        redis_value = False
         if redis_value == False:
         if redis_value == False:
             print('添加到缓存')
             print('添加到缓存')
             # 查数据库
             # 查数据库
             sm_qs = AppSetModel.objects.filter(appBundleId=appBundleId)
             sm_qs = AppSetModel.objects.filter(appBundleId=appBundleId)
             count = sm_qs.count()
             count = sm_qs.count()
             if count > 0:
             if count > 0:
+
                 sm_qs = sm_qs.values("content")
                 sm_qs = sm_qs.values("content")
                 # 添加到缓存,缓存时间为3600秒------指的是一个钟后再次访问,就会刷新缓存一次
                 # 添加到缓存,缓存时间为3600秒------指的是一个钟后再次访问,就会刷新缓存一次
-                content_json_str = list(sm_qs)[0]['content'].replace("'", '"')
+                dict_json = json.loads(sm_qs[0]['content'])
+                if 'editionUpgrading' in dict_json :
+                    if  dict_json['editionUpgrading'] == 1:
+                        if lang !='cn':
+                            dict_json['editionUpgrading'] = 'Upgrading, please sign in later'
+                        else:
+                            dict_json['editionUpgrading'] = '正在升级,请稍后登录'
+                    else:
+                        dict_json['editionUpgrading'] = ''
+
+
+
+                content_json_str = dict_json
+
                 redis.set_data(key=key_id, val=content_json_str, expire=3600)
                 redis.set_data(key=key_id, val=content_json_str, expire=3600)
                 # 返回固定值
                 # 返回固定值
-                return response.json(0, json.loads(list(sm_qs)[0]['content']))
+                return response.json(0, content_json_str)
             else:
             else:
                 return response.json(173)
                 return response.json(173)
         else:
         else:

+ 258 - 0
Controller/CDKController.py

@@ -0,0 +1,258 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+"""
+@Copyright (C) ansjer cop Video Technology Co.,Ltd.All rights reserved.
+@AUTHOR: ASJRD018
+@NAME: AnsjerFormal
+@software: PyCharm
+@DATE: 2018/12/5 9:30
+@Version: python3.6
+@MODIFY DECORD:ansjer dev
+@file: cloudstorage.py
+@Contact: chanjunkai@163.com
+"""
+import json
+import time
+import urllib
+import uuid
+import hashlib
+
+import boto3
+import oss2
+import paypalrestsdk
+import threading
+from aliyunsdkcore import client
+from aliyunsdksts.request.v20150401 import AssumeRoleRequest
+from boto3.session import Session
+from django.http import JsonResponse, HttpResponseRedirect, HttpResponse
+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, \
+    SERVER_DOMAIN_SSL
+from Model.models import Device_Info, Order_Model, Store_Meal, VodHlsModel, OssCrdModel, UID_Bucket, StsCrdModel, \
+    ExperienceContextModel, CDKcontextModel
+from Object.AliPayObject import AliPayObject
+from Object.ResponseObject import ResponseObject
+from Object.TokenObject import TokenObject
+from Object.UidTokenObject import UidTokenObject
+from Service.CommonService import CommonService
+from Object.m3u8generate import PlaylistGenerator
+from Object.WechatPayObject import WechatPayObject
+from django.db.models import Q, F
+from django.http import StreamingHttpResponse
+
+SERVER_DOMAIN = 'http://test.dvema.com/'
+
+
+# 设备信息添加
+class CDKView(View):
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.GET, request, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.POST, request, operation)
+
+    def validation(self, request_dict, request, operation):
+        response = ResponseObject()
+
+        if operation is None:
+            return response.json(444, 'error path')
+        else:
+            token = request_dict.get('token', None)
+            # 设备主键uid
+            tko = TokenObject(token)
+            response.lang = tko.lang
+            if tko.code != 0:
+                return response.json(tko.code)
+            userID = tko.userID
+            if operation == 'createCDK':
+                return self.createCDK(request_dict, response)
+            elif operation == 'deleteCDK':
+                return self.deleteCDK(request_dict, response)
+            elif operation == 'queryCDK':
+                return self.queryCDK(request_dict, response)
+            elif operation == 'saveOrEditCDKform':
+                return self.saveOrEditCDKform(request_dict, response)
+            elif operation == 'saveOrEditCDK':
+                return self.saveOrEditCDK(request_dict, response)
+            elif operation == 'downloadCDK':
+                return self.downloadCDK(request_dict, response)
+
+    def createCDK(self, request_dict, response):
+        cdk_num = request_dict.get("cdknum", None)
+        rank = request_dict.get('rank', None)
+        order = request_dict.get('order', None)
+        cdk_list = []
+        for i in range(int(cdk_num)):
+            nowTime = int(time.time())
+            cdk = hashlib.md5((str(uuid.uuid1()) + str(nowTime)).encode('utf-8')).hexdigest()
+            cdk_model = CDKcontextModel(
+                cdk=cdk,
+                create_time=nowTime,
+                valid_time=0,
+                is_activate=0,
+                rank_id=rank,
+                order=order,
+            )
+            cdk_list.append(cdk_model)
+        try:
+            CDKcontextModel.objects.bulk_create(cdk_list)
+        except Exception as e:
+            print(repr(e))
+            return response.json(404, repr(e))
+        else:
+            return response.json(0)
+
+    def queryCDK(self, request_dict, response):
+        page = int(request_dict.get('page', None))
+        line = int(request_dict.get('line', None))
+        # channel = request_dict.get('channel', None)
+        cdk = request_dict.get('cdk', None)
+        order = request_dict.get('order', None)
+        is_activate = request_dict.get('is_activate', None)
+        lang = request_dict.get('lang', 'cn')
+        searchVal = ''
+        if cdk:
+            searchVal = cdk.strip()
+        elif order:
+            searchVal = order.strip()
+        elif is_activate:
+            searchVal = is_activate.strip()
+
+        if page and line:
+            cdk_qs = CDKcontextModel.objects.filter().all()  # values('cdk','create_time','valid_time','is_activate','rank__id','order__id')
+            if searchVal:
+                if cdk:
+                    cdk_qs = cdk_qs.filter(cdk__contains=searchVal)
+                elif order:
+                    cdk_qs = cdk_qs.filter(order=searchVal)
+                elif is_activate:
+                    cdk_qs = cdk_qs.filter(is_activate=searchVal)
+
+
+            cdk_qs = cdk_qs.filter(rank__lang__lang=lang)
+            cdk_qs = cdk_qs.annotate(rank__title=F('rank__lang__title'))
+            cdk_qs = cdk_qs.values('id', 'cdk', 'create_time', 'valid_time', 'is_activate', 'rank__id', 'rank__title', 'order',
+                                   'create_time')
+            cdk_qs = cdk_qs.order_by('-create_time')  # 根据CDK创建时间降序排序
+            count = cdk_qs.count()
+            cdk_qs = cdk_qs[(page - 1) * line:page * line]
+
+            # cdk_dict = {}
+            # for cdk in cdk_qs:
+            #     cdk_dict[cdk['id']] = {'id': cdk['id'], 'cdk': cdk['cdk'], 'create_time': cdk['create_time'],
+            #                            'valid_time': cdk['valid_time'], 'is_activate': cdk['is_activate'],
+            #                            'rank': cdk['rank__id'], 'order': cdk['order']}
+
+            res = {
+                'datas': list(cdk_qs),
+                'count': count
+            }
+            return response.json(0, res)
+        else:
+            return response.json(444, 'page,line')
+
+    def deleteCDK(self, request_dict, response):
+        cdk_id = request_dict.get("id", None)
+        lang = request_dict.get("lang", 'cn')
+        try:
+            CDKcontextModel.objects.get(cdk=cdk_id).delete()
+        except Exception as e:
+            return response.json(500, repr(e))
+        else:
+            page = int(request_dict.get('page', None))
+            line = int(request_dict.get('line', None))
+            # channel = request_dict.get('channel', None)
+            cdk = request_dict.get('cdk', None)
+            order = request_dict.get('order', None)
+            is_activate = request_dict.get('is_activate', None)
+
+            searchVal = ''
+            if cdk:
+                searchVal = cdk.strip()
+            elif order:
+                searchVal = order.strip()
+            elif is_activate:
+                searchVal = is_activate.strip()
+
+            if page and line:
+                cdk_qs = CDKcontextModel.objects.filter().all()  # values('cdk','create_time','valid_time','is_activate','rank__id','order__id')
+                if searchVal:
+                    if cdk:
+                        cdk_qs = cdk_qs.filter(cdk__contains=searchVal)
+                    elif order:
+                        cdk_qs = cdk_qs.filter(order=searchVal)
+                    elif is_activate:
+                        cdk_qs = cdk_qs.filter(is_activate=searchVal)
+
+
+                cdk_qs = cdk_qs.filter(rank__lang__lang=lang)
+                cdk_qs = cdk_qs.annotate(rank__title=F('rank__lang__title'))
+                cdk_qs = cdk_qs.values('id', 'cdk', 'create_time', 'valid_time', 'is_activate', 'rank__id',
+                                       'rank__title', 'order',
+                                       'create_time')
+                cdk_qs = cdk_qs.order_by('-create_time')  # 根据CDK创建时间降序排序
+                count = cdk_qs.count()
+                cdk_qs = cdk_qs[(page - 1) * line:page * line]
+                res = {
+                    'datas': list(cdk_qs),
+                    'count': count
+                }
+                return response.json(0, res)
+
+
+
+    def saveOrEditCDK(self, request_dict, response):
+        cdk_id = request_dict.get("id", None)
+        cdk = request_dict.get('cdk', None)
+        valid_time = request_dict.get('valid_time', None)
+        is_activate = request_dict.get('is_activate', None)
+        rank = request_dict.get('rank', None)
+
+        try:
+            if cdk_id:
+                if cdk or valid_time or is_activate or rank:
+                    update_dict = {}
+                    if cdk:
+                        update_dict['cdk'] = cdk
+                    if valid_time:
+                        update_dict['valid_time'] = valid_time
+                    if is_activate:
+                        update_dict['is_activate'] = is_activate
+                    if rank:
+                        update_dict['rank'] = rank
+                    CDKcontextModel.objects.filter(id=cdk_id).update(**update_dict)
+        except Exception as e:
+            return response.json(500, repr(e))
+        else:
+            return response.json(0)
+
+    def downloadCDK(self,request_dict, response):
+        region = request_dict.get('region', None)
+        content = ''
+        if region == 'cn':
+            # 下载国内未使用激活码
+            content += '激活码(国内)\n'
+            cdk_inactivate_qs = CDKcontextModel.objects.filter(is_activate=0, rank__bucket__mold=0).values('cdk')
+        else:
+            # 下载国外未使用激活码
+            content += '激活码(国外)\n'
+            cdk_inactivate_qs = CDKcontextModel.objects.filter(is_activate=0, rank__bucket__mold=1).values('cdk')
+        for cdk_inactivate in cdk_inactivate_qs:
+            content += cdk_inactivate['cdk'] + '\n'
+        # print(content)
+
+        response = StreamingHttpResponse(content)
+        response['Content-Type'] = 'application/octet-stream'
+        response['Content-Disposition'] = 'attachment;filename="CDK.txt"'
+        return response
+
+
+
+
+

Plik diff jest za duży
+ 699 - 485
Controller/CloudStorage.py


+ 202 - 0
Controller/CloudTransfer.py

@@ -0,0 +1,202 @@
+# -*- coding: utf-8 -*-
+"""
+@Time : 2020/12/16 8:44
+@Auth : Locky
+@File :CloudTransfer.py
+@IDE :PyCharm
+"""
+import time
+from django.db import transaction
+from django.views.generic.base import View
+
+from Object.TokenObject import TokenObject
+from Service.CommonService import CommonService
+from Service.ModelService import ModelService
+from Object.ResponseObject import ResponseObject
+from Model.models import Device_User, Device_Info, Order_Model, UID_Bucket, StsCrdModel, VodHlsModel, Unused_Uid_Meal, \
+    VodBucketModel, UIDMainUser
+
+
+class cloudTestView(View):
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.GET, request, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.POST, request, operation)
+
+    def validation(self, request_dict, request, operation):
+        response = ResponseObject()
+        if operation is None:
+            return response.json(444, 'error path')
+        else:
+            token = request_dict.get('token', None)
+            # 设备主键uid
+            tko = TokenObject(token)
+            response.lang = tko.lang
+            if tko.code != 0:
+                return response.json(tko.code)
+            userID = tko.userID
+            if operation == 'deviceTransfer':
+                return self.deviceTransfer(request_dict, response)
+            elif operation == 'mealTransfer':
+                return self.mealTransfer(request_dict, response, userID)
+            elif operation == 'expireMeal':
+                return self.expireMeal(request_dict, response)
+
+    def deviceTransfer(self, request_dict, response):
+        # 设备转移,一个用户下的设备转移到另一个用户
+        oldUserID = request_dict.get("oldUserID", None)
+        username = request_dict.get("username", None)
+        uid = request_dict.get('uid', None)
+        now_time = CommonService.timestamp_to_str(int(time.time()))
+        # print('now_time: ', now_time)
+
+        try:
+            # 查询该userID下是否存在此设备
+            old_deviceInfo_qs = Device_Info.objects.filter(userID_id=oldUserID, UID=uid, isExist=1).values('isShare','vodPrimaryUserID')
+            if not old_deviceInfo_qs.exists():
+                return response.json(10008)
+
+            newUserID = ModelService.get_userID_byname(username)    # 根据username获取userID
+            if newUserID is None:   # 没有此用户
+                return response.json(104)
+            if newUserID == oldUserID:  # 新用户的userID跟旧用户的一样
+                return response.json(10009)
+            # 分享的设备不能转移
+            isShare = old_deviceInfo_qs[0]['isShare']
+            if isShare:
+                return response.json(10015)
+            # 旧用户是设备主用户才能转移
+            vodPrimaryUserID = old_deviceInfo_qs[0]['vodPrimaryUserID']
+            if vodPrimaryUserID != '' and vodPrimaryUserID != oldUserID:
+                return response.json(10037)
+
+            # uid_mian = UIDMainUser.objects.filter(UID=uid).values('UID', 'user_id')
+            # if uid_mian.exists():
+            #     vodPrimaryUserID = uid_mian[0]['user_id']
+            #     if vodPrimaryUserID != '' and vodPrimaryUserID != oldUserID:
+            #         return response.json(10037)
+
+            # 判断新用户是否已有此设备
+            new_deviceInfo_qs = Device_Info.objects.filter(userID_id=newUserID, UID=uid, isExist=1)
+            if new_deviceInfo_qs:
+                return response.json(10009)
+
+            # 获取新设备的username
+            newUserName = Device_User.objects.get(userID=newUserID).username
+            vodPrimaryUserID = newUserID
+            vodPrimaryMaster = newUserName
+
+            with transaction.atomic():
+                # 更新旧设备的userID,设备添加时间
+                old_deviceInfo_qs.update(userID=newUserID, data_joined=now_time)
+                # 更新设备的主用户信息
+                Device_Info.objects.filter(UID=uid).update(vodPrimaryUserID=vodPrimaryUserID, vodPrimaryMaster=vodPrimaryMaster)
+                VodHlsModel.objects.filter(uid=uid).delete()
+
+                # UIDMainUser.objects.filter(UID=uid).delete()
+                # uid_main_dict = {
+                #     'UID': uid,
+                #     'user_id': newUserID
+                # }
+                # UIDMainUser.objects.create(**uid_main_dict)
+
+        except Exception as e:
+            # print(e)
+            return response.json(500, repr(e))
+        else:
+            return response.json(0)
+
+    def mealTransfer(self, request_dict, response, userID):
+        # 云存套餐转移,同一用户下不同设备间的云存套餐转移
+        old_uid = request_dict.get("old_uid", None)
+        new_uid = request_dict.get("new_uid", None)
+        nowTime = int(time.time())
+
+        try:
+            # 查询两个UID是否在同一账号下
+            old_deviceInfo_qs = Device_Info.objects.filter(userID_id=userID, UID=old_uid).values('isExist','vodPrimaryUserID')
+            new_deviceInfo_qs = Device_Info.objects.filter(userID_id=userID, UID=new_uid).values('isExist')
+            if not (old_deviceInfo_qs.exists() and new_deviceInfo_qs.exists()):
+                return response.json(10010)
+
+            # 不是主用户无法转移
+            vodPrimaryUserID = old_deviceInfo_qs[0]['vodPrimaryUserID']
+            if vodPrimaryUserID != '' and vodPrimaryUserID != userID:
+                return response.json(10038)
+            vodPrimaryUserID = userID
+            vodPrimaryMaster = ModelService.get_user_name(userID)
+
+            new_isExist = new_deviceInfo_qs[0]['isExist']
+            if not new_isExist:
+                return response.json(10011)
+
+            # 查询转出设备正在使用的套餐
+            old_using_uid_bucket = UID_Bucket.objects.filter(uid=old_uid, endTime__gte=nowTime).values('id', 'bucket_id', 'has_unused').order_by('addTime')
+            if not old_using_uid_bucket.exists():
+                return response.json(10013)
+
+            # 免费存储桶不可转移
+            old_vod_bucket_id = old_using_uid_bucket[0]['bucket_id']
+            is_free = VodBucketModel.objects.get(id=old_vod_bucket_id).is_free
+            if is_free == 1:
+                return response.json(10012)
+
+            # 查询转入设备是否存在正在使用的套餐和未使用的套餐
+            new_using_uid_bucket = UID_Bucket.objects.filter(uid=new_uid, endTime__gte=nowTime)
+            new_unused_uid_bucket = Unused_Uid_Meal.objects.filter(uid=new_uid)
+            if new_using_uid_bucket.exists() or new_unused_uid_bucket.exists():
+                return response.json(10014)
+
+            # 如果转出设备有未使用套餐,更改第一个未使用套餐为正在使用
+            if old_using_uid_bucket[0]['has_unused'] == 1:
+                old_unused_uid_bucket = Unused_Uid_Meal.objects.filter(uid=old_uid).values('id', 'channel', 'bucket_id', 'addTime', 'expire', 'num')
+                count = old_unused_uid_bucket.count()
+                unused = old_unused_uid_bucket[0]
+                has_unused = 1 if count>1 else 0    # 如果存在不止一个未使用套餐,has_unused=1
+                endTime = CommonService.calcMonthLater(unused['expire'] * unused['num'])
+                data_dict = {
+                    'uid': old_uid,
+                    'channel': unused['channel'],
+                    'bucket_id': unused['bucket_id'],
+                    'addTime': unused['addTime'],
+                    'endTime': endTime,
+                    'updateTime': nowTime,
+                    'status': 1,
+                    'use_status': 1,
+                    'has_unused': has_unused
+                }
+                UID_Bucket.objects.create(**data_dict)  # 正在使用套餐表添加数据
+                Unused_Uid_Meal.objects.filter(uid=old_uid).first().delete()   # 删除未使用套餐表中的数据
+
+            with transaction.atomic():
+                # 更新转入设备的主用户信息
+                Device_Info.objects.filter(UID=new_uid).update(vodPrimaryUserID=vodPrimaryUserID, vodPrimaryMaster=vodPrimaryMaster)
+                # 更新正在使用套餐的uid,重置拥有未使用套餐
+                old_using_uid_bucket_id = old_using_uid_bucket[0]['id']
+                UID_Bucket.objects.filter(id=old_using_uid_bucket_id).update(uid=new_uid,has_unused=0)
+                StsCrdModel.objects.filter(uid=old_uid).delete()    # 删除转出设备stscrd表关联数据
+
+        except Exception as e:
+            # print(e)
+            return response.json(500, repr(e))
+        else:
+            return response.json(0)
+
+    def expireMeal(self, request_dict, response):
+        UID_Bucket_id = request_dict.get("UID_Bucket_id", None)
+        # 修改endTime让当前设备套餐过期
+        if UID_Bucket_id:
+            try:
+                UID_Bucket.objects.filter(id=UID_Bucket_id).update(use_status=2)
+            except Exception as e:
+                # print(e)
+                return response.json(500, repr(e))
+            else:
+                return response.json(0)
+        response.json(404)

+ 404 - 699
Controller/CloudVod.py

@@ -15,6 +15,9 @@ import json
 import math
 import math
 import time
 import time
 import urllib
 import urllib
+
+import boto3
+
 from Object.AliPayObject import AliPayObject
 from Object.AliPayObject import AliPayObject
 import oss2
 import oss2
 import paypalrestsdk
 import paypalrestsdk
@@ -28,7 +31,7 @@ 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 Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, OSS_ROLE_ARN, SERVER_DOMAIN, PAYPAL_CRD, \
     SERVER_DOMAIN_SSL
     SERVER_DOMAIN_SSL
-from Model.models import Device_Info, Order_Model, Store_Meal, VodHlsModel, OssCrdModel, UID_Bucket
+from Model.models import Device_Info, Order_Model, Store_Meal, VodHlsModel, OssCrdModel, UID_Bucket, StsCrdModel
 from Object.ResponseObject import ResponseObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Object.TokenObject import TokenObject
 from Object.UidTokenObject import UidTokenObject
 from Object.UidTokenObject import UidTokenObject
@@ -97,12 +100,6 @@ class CloudVodView(View):
             return self.do_pay_ok()
             return self.do_pay_ok()
         elif operation == 'payError':
         elif operation == 'payError':
             return self.do_pay_error()
             return self.do_pay_error()
-        elif operation == 'aliPayCallback':
-            return self.do_ali_pay_callback(request)
-        elif operation == 'dopaypalcallback':
-            return self.do_pay_by_paypal_callback(request)
-        elif operation == 'doalicallback':
-            return self.do_pay_by_ali_callback(request)
         else:
         else:
             token = request_dict.get('token', None)
             token = request_dict.get('token', None)
             # 设备主键uid
             # 设备主键uid
@@ -111,9 +108,7 @@ class CloudVodView(View):
             if tko.code != 0:
             if tko.code != 0:
                 return response.json(tko.code)
                 return response.json(tko.code)
             userID = tko.userID
             userID = tko.userID
-            if operation == 'createOrder':
-                return self.do_create_order(request_dict, userID, response)
-            elif operation == 'status':
+            if operation == 'status':
                 return self.do_change_status(request_dict, userID, response)
                 return self.do_change_status(request_dict, userID, response)
             elif operation == 'details':
             elif operation == 'details':
                 return self.do_get_details(request_dict, response)
                 return self.do_get_details(request_dict, response)
@@ -121,142 +116,11 @@ class CloudVodView(View):
                 return self.do_filter_playlist(request_dict, userID, response)
                 return self.do_filter_playlist(request_dict, userID, response)
             elif operation == 'findVod':
             elif operation == 'findVod':
                 return self.do_find_playlist(request_dict, userID, response)
                 return self.do_find_playlist(request_dict, userID, response)
-            # 支付宝支付
-            elif operation == 'aliPayCreateOrder':
-                return self.do_pay_by_ali(request_dict, userID, response)
             elif operation == 'orderStatus':
             elif operation == 'orderStatus':
-                return self.do_pay_status(request_dict, userID)
-            elif operation == 'createPayOrder':
-                return self.do_create_pay_order(request_dict, userID, response)
+                return self.do_pay_status(request_dict, userID, response)
             else:
             else:
                 return response.json(414)
                 return response.json(414)
 
 
-    def do_ali_pay_callback(self, request):
-        response = ResponseObject()
-        data = request.POST.dict()
-        signature = data["sign"]
-        data.pop('sign')
-        orderID = data['out_trade_no']
-
-        order_qs = Order_Model.objects.filter(orderID=orderID, status=0)
-        print(order_qs)
-
-        if not order_qs.exists():
-            return response.json(404)
-        print(json.dumps(data))
-        print(signature)
-        # verify
-        aliPayObj = AliPayObject()
-        alipay = aliPayObj.conf()
-        success = alipay.verify(data, signature)
-        if success and data["trade_status"] in ("TRADE_SUCCESS", "TRADE_FINISHED"):
-            print("trade succeed")
-            nowTime = int(time.time())
-            order_list = order_qs.values("UID", "rank__id", "channel")
-            rank_id = order_list[0]['rank__id']
-            print(rank_id)
-            UID = order_list[0]['UID']
-            channel = order_list[0]['channel']
-            order_qs.update(status=1, updTime=nowTime)
-
-            smqs = Store_Meal.objects.filter(id=rank_id).values("day", "bucket_id", "bucket__storeDay")
-            bucketId = smqs[0]['bucket_id']
-            if not smqs.exists():
-                return response.json(0, '套餐已删除')
-            addTime = int(smqs[0]["day"]) * 24 * 3600
-            ubqs = UID_Bucket.objects.filter(uid=UID, channel=channel). \
-                values("bucket_id", "endTime", "bucket__storeDay")
-            nowTime = int(time.time())
-            if ubqs.exists():
-                # 判断是否过期了
-                if nowTime > ubqs[0]['endTime']:
-                    ubqs.update(endTime=nowTime + addTime)
-                else:
-                    # 同一个bucket续费
-                    if bucketId == ubqs[0]['bucket_id']:
-                        ubqs.update(endTime=ubqs[0]['endTime'] + addTime)
-                    else:
-                        if ubqs[0]['bucket__storeDay'] > smqs[0]['bucket__storeDay']:
-                            return response.json(10, '不可选低级别套餐')
-                        else:
-                            # 升级
-                            origin_storeDay = int(ubqs[0]['bucket__storeDay'])
-                            upgrade_storeDay = int(smqs[0]['bucket__storeDay'])
-                            ctcTime = ubqs[0]['endTime'] - nowTime
-                            multiple = math.ceil(upgrade_storeDay / origin_storeDay)
-                            ubqs.update(endTime=ctcTime / multiple + addTime + ubqs[0]['endTime'], bucket_id=bucketId)
-                            # 付款成功把oss token删除
-                            OssCrdModel.objects.filter(uid=UID, channel=channel).delete()
-            # 新增模式
-            else:
-                print('create')
-                UID_Bucket.objects.create(uid=UID, channel=channel,
-                                          bucket_id=bucketId, endTime=nowTime + addTime)
-            red_url = "{SERVER_DOMAIN}cloudVod/payOK".format(SERVER_DOMAIN=SERVER_DOMAIN)
-            return HttpResponseRedirect(red_url)
-        return response.json(0, signature)
-
-    #发起支付宝支付
-    def do_pay_by_ali(self, request_dict, userID, response):
-        uid = request_dict.get('uid', None)
-        rank = request_dict.get('rank', None)
-        channel = request_dict.get('channel', None)
-        qs = Device_Info.objects.filter(userID_id=userID, UID=uid, isShare=False)
-        if not qs.exists():
-            return response.json(12)
-        if not channel or not rank:
-            return response.json(444, 'channel,rank')
-        smqs = Store_Meal.objects.filter(id=rank). \
-            values("currency", "price", "content", "day", "bucket__storeDay", "bucket__region", "type")
-        if not smqs.exists():
-            # 套餐不存在
-            return response.json(173)
-        if smqs[0]['type'] != 1:
-            return response.json(10, '不支持支付宝支付')
-        currency = smqs[0]['currency']
-        price = smqs[0]['price']
-        content = smqs[0]['content']
-        day = smqs[0]['day']
-        nowTime = int(time.time())
-        ubqs = UID_Bucket.objects.filter(uid=uid, channel=channel, endTime__gte=nowTime). \
-            values("bucket__storeDay", "bucket__region")
-        if ubqs.exists():
-            if ubqs[0]['bucket__region'] != smqs[0]['bucket__region']:
-                return response.json(712)  # 区域不一致
-            elif ubqs[0]['bucket__storeDay'] != smqs[0]['bucket__storeDay']:
-                return response.json(713)  # 不可更改套餐
-            # 续费流程
-        nowTime = int(time.time())
-        # 新增流程
-        orderID = CommonService.createOrderID()
-
-        try:
-            aliPayObj = AliPayObject()
-            alipay = aliPayObj.conf()
-            order_string = alipay.api_alipay_trade_wap_pay(
-                out_trade_no=orderID,
-                total_amount=price,
-                subject="测试哟",
-                return_url="{SERVER_DOMAIN_SSL}cloudVod/payOK".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL),
-                notify_url="{SERVER_DOMAIN_SSL}cloudVod/aliPayCallback".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
-                # return_url="http://192.168.136.40/cloudVod/payOK",
-                # notify_url="http://192.168.136.40/cloudVod/aliPayCallback"
-            )
-        except Exception as e:
-            print(repr(e))
-            return response.json(10, repr(e))
-        if order_string:
-            redirectUrl = aliPayObj.alipay_prefix + order_string
-            Order_Model.objects.create(orderID=orderID, UID=uid, channel=channel, userID_id=userID, desc=content,
-                                       price=price, currency=currency, addTime=nowTime, updTime=nowTime,
-                                       endTime=nowTime + int(day) * 3600 * 24, rank_id=rank, payType=1)
-            return JsonResponse(status=200,
-                                data={'result_code': 0, 'reason': 'success',
-                                      'result': {"redirectUrl": redirectUrl, "orderID": orderID},
-                                      'error_code': 0})
-        else:
-            return response.json(10, '生成订单错误')
-
     def do_get_details(self, request_dict, response):
     def do_get_details(self, request_dict, response):
         uid = request_dict.get('uid', None)
         uid = request_dict.get('uid', None)
         dvqs = Device_Info.objects.filter(UID=uid, isShare=False)
         dvqs = Device_Info.objects.filter(UID=uid, isShare=False)
@@ -380,7 +244,7 @@ class CloudVodView(View):
     		color : green
     		color : green
     	}
     	}
     	.content_img{
     	.content_img{
-    		width: 60px; 
+    		width: 60px;
     		height: 60px;
     		height: 60px;
     	}
     	}
     	.bottom{
     	.bottom{
@@ -420,7 +284,7 @@ class CloudVodView(View):
     function payOKButton() {
     function payOKButton() {
         // 复杂数据
         // 复杂数据
         console.log('success')
         console.log('success')
-        window.webkit.messageHandlers.jsCallOC.postMessage({"status": 1});
+        window.location.href="https://test.dvema.com/closePage";
     }
     }
 	</script>
 	</script>
 </body> 
 </body> 
@@ -428,344 +292,237 @@ class CloudVodView(View):
         '''
         '''
         return response
         return response
 
 
-    def do_pay_by_ali_callback(self, request):
-        response = ResponseObject()
-        data = request.POST.dict()
-        signature = data["sign"]
-        data.pop('sign')
-        orderID = data['out_trade_no']
-
-        order_qs = Order_Model.objects.filter(orderID=orderID, status=0)
-        print(order_qs)
-
-        if not order_qs.exists():
-            return response.json(404)
-        print(json.dumps(data))
-        print(signature)
-        # verify
-        aliPayObj = AliPayObject()
-        alipay = aliPayObj.conf()
-        success = alipay.verify(data, signature)
-        if success and data["trade_status"] in ("TRADE_SUCCESS", "TRADE_FINISHED"):
-            print("trade succeed")
-            nowTime = int(time.time())
-            order_list = order_qs.values("UID", "commodity_code", "channel")
-            UID = order_list[0]['UID']
-            channel = order_list[0]['channel']
-            commodity_code = order_list[0]['commodity_code']
-            order_qs.update(status=1, updTime=nowTime)
-            smqs = Store_Meal.objects.filter(commodity_code=commodity_code).\
-                values("day", "bucket_id", "bucket__storeDay")
-            bucketId = smqs[0]['bucket_id']
-            if not smqs.exists():
-                return response.json(0, '套餐已删除')
-            addTime = int(smqs[0]["day"]) * 24 * 3600
-            ubqs = UID_Bucket.objects.filter(uid=UID, channel=channel). \
-                values("bucket_id", "endTime", "bucket__storeDay")
-            nowTime = int(time.time())
-            if ubqs.exists():
-                ubqs_count = ubqs.count()
-                ubq = ubqs[ubqs_count - 1, ubqs_count]
-                new_starTime = ubq['endTime'] + 1
-                UID_Bucket.objects.create(uid=UID, channel=channel, bucket_id=bucketId, endTime=new_starTime + addTime)
-            else:
-                UID_Bucket.objects.create(uid=UID, channel=channel, bucket_id=bucketId, endTime=nowTime + addTime)
-            red_url = "{SERVER_DOMAIN}cloudVod/payOK".format(SERVER_DOMAIN=SERVER_DOMAIN)
-            return HttpResponseRedirect(red_url)
-        return response.json(0, signature)
-
-    def do_pay_by_paypal_callback(self, request_dict, response):
-        paymentId = request_dict.get('paymentId', None)
-        PayerID = request_dict.get('PayerID', None)
-        orderID = request_dict.get('orderID', None)
-        if not paymentId or not PayerID or not orderID:
-            red_url = "{SERVER_DOMAIN}cloudVod/payError".format(SERVER_DOMAIN=SERVER_DOMAIN)
-            return HttpResponseRedirect(red_url)
-        paypalrestsdk.configure(PAYPAL_CRD)
-        # ID of the payment. This ID is provided when creating payment.
-        payment = paypalrestsdk.Payment.find(paymentId)
-        payres = payment.execute({"payer_id": PayerID})
-        print(payres)
-        if not payres:
-            red_url = "{SERVER_DOMAIN}cloudVod/payError".format(SERVER_DOMAIN=SERVER_DOMAIN)
-            return HttpResponseRedirect(red_url)
-        print("Payment execute successfully")
-        order_qs = Order_Model.objects.filter(orderID=orderID)
-        nowTime = int(time.time())
-        order_qs.update(status=1, updTime=nowTime)
-        order_list = order_qs.values("UID", "channel", "commodity_code")
-        UID = order_list[0]['UID']
-        channel = order_list[0]['channel']
-        commodity_code = order_list[0]['commodity_code']
-        smqs = Store_Meal.objects.filter(commodity_code=commodity_code).\
-            values("day", "bucket_id", "bucket__storeDay")
-        bucketId = smqs[0]['bucket_id']
-        if not smqs.exists():
-            return response.json(0, '套餐已删除')
-        addTime = int(smqs[0]["day"]) * 24 * 3600
-        # ##
-        ubqs = UID_Bucket.objects.filter(uid=UID, channel=channel, endTime__gte=nowTime). \
-            values("bucket__storeDay", "bucket__region", "endTime")
-        if ubqs.exists():
-            ubqs_count = ubqs.count()
-            ubq = ubqs[ubqs_count - 1, ubqs_count]
-            new_starTime = ubq['endTime'] + 1
-            UID_Bucket.objects.create(uid=UID, channel=channel, bucket_id=bucketId, endTime=new_starTime + addTime)
-        else:
-            UID_Bucket.objects.create(uid=UID, channel=channel, bucket_id=bucketId, endTime=nowTime + addTime)
-            # return response.json(0)
-        red_url = "{SERVER_DOMAIN}cloudVod/payOK".format(SERVER_DOMAIN=SERVER_DOMAIN)
-        return HttpResponseRedirect(red_url)
-
-    def do_create_pay_order(self, request_dict, userID, response):
-        uid = request_dict.get('uid', None)
-        channel = request_dict.get('channel', None)
-        commodity_code = request_dict.get('commodity_code', None)
-        pay_type = int(request_dict.get('pay_type', None))
-        dv_qs = Device_Info.objects.filter(userID_id=userID, UID=uid, isShare=False, isExist=1)
-        if not dv_qs.exists():
-            return response.json(12)
-        smqs = Store_Meal.objects.filter(commodity_code=commodity_code, type=pay_type). \
-            values('currency', 'price', 'content', 'day', 'commodity_type', 'title', 'content')
-        if not smqs.exists():
-            return response.json(10, '套餐不存在')
-        currency = smqs[0]['currency']
-        price = smqs[0]['price']
-        content = smqs[0]['content']
-        day = smqs[0]['day']
-        commodity_type = smqs[0]['commodity_type']
-        # ubqs = UID_Bucket.objects.filter(uid=uid, channel=channel, endTime__gte=nowTime). \
-        #     values("bucket__storeDay", "bucket__region", "endTime")
-        # if ubqs.exists():
-        #     ubqs_count = ubqs.count()
-        #     ubq = ubqs[ubqs_count - 1, ubqs_count]
-        #     new_starTime = ubq['endTime'] + 1
-        nowTime = int(time.time())
-        orderID = CommonService.createOrderID()
-        if pay_type == 0:
-            call_sub_url = "{SERVER_DOMAIN}cloudVod/dopaypalcallback?orderID={orderID}". \
-                format(SERVER_DOMAIN=SERVER_DOMAIN, orderID=orderID)
-            # call_sub_url = "http://192.168.136.40:8077/cloudVod/payExecute?orderID={orderID}".format(
-            #     SERVER_DOMAIN=SERVER_DOMAIN, orderID=orderID)
-            call_clc_url = "{SERVER_DOMAIN}cloudVod/payError".format(SERVER_DOMAIN=SERVER_DOMAIN)
-            paypalrestsdk.configure(PAYPAL_CRD)
-            payment = paypalrestsdk.Payment({
-                "intent": "sale",
-                "payer": {"payment_method": "paypal"},
-                "redirect_urls": {"return_url": call_sub_url, "cancel_url": call_clc_url},
-                "transactions": [{
-                    "item_list": {
-                        "items": [
-                            {"name": "Cloud video", "sku": "1", "price": price, "currency": "USD", "quantity": 1}]},
-                    "amount": {"total": price, "currency": currency},
-                    "description": content
-                }]})
-            if payment.create():
-                print("Payment created successfully")
-            else:
-                print(payment.error)
-                return response.json(10, payment.error)
-            print(payment)
-            for link in payment.links:
-                if link.rel == "approval_url":
-                    approval_url = str(link.href)
-                    print("Redirect for approval: %s" % (approval_url))
-                    Order_Model.objects.create(orderID=orderID, UID=uid, channel=channel, userID_id=userID,
-                                               desc=content,
-                                               price=price, currency=currency, addTime=nowTime, updTime=nowTime,
-                                               endTime=(nowTime + int(day) * 3600 * 24), paypal=approval_url,
-                                               commodity_code=commodity_code, commodity_type=commodity_type)
-                    return response.json(0, {"redirectUrl": approval_url, "orderID": orderID})
-            return response.json(10, 'generate_order_false')
-        else:
-            try:
-                aliPayObj = AliPayObject()
-                alipay = aliPayObj.conf()
-                subject = smqs[0]['title'] + smqs[0]['content']
-                order_string = alipay.api_alipay_trade_wap_pay(
-                    out_trade_no=orderID,
-                    total_amount=price,
-                    subject=subject,
-                    return_url="{SERVER_DOMAIN_SSL}cloudVod/payOK".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL),
-                    notify_url="{SERVER_DOMAIN_SSL}cloudVod/doalicallback".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
-                    # return_url="http://192.168.136.40/cloudVod/payOK",
-                    # notify_url="http://192.168.136.40/cloudVod/aliPayCallback"
-                )
-            except Exception as e:
-                print(repr(e))
-                return response.json(10, repr(e))
-            else:
-                if order_string:
-                    redirectUrl = aliPayObj.alipay_prefix + order_string
-                    Order_Model.objects.create(orderID=orderID, UID=uid, channel=channel, userID_id=userID,
-                                               desc=content, price=price, currency=currency, addTime=nowTime,
-                                               updTime=nowTime, endTime=nowTime + int(day) * 3600 * 24,
-                                               commodity_code=commodity_code, commodity_type=commodity_type,
-                                               paypal='', payType=1)
-                    return JsonResponse(status=200, data={'result_code': 0, 'reason': 'success',
-                                                          'result': {"redirectUrl": redirectUrl, "orderID": orderID},
-                                                          'error_code': 0})
-                else:
-                    return response.json(10, '生成订单错误')
-
-    # 发起paypal支付
-    def do_create_order(self, request_dict, userID, response):
-        uid = request_dict.get('uid', None)
-        rank = request_dict.get('rank', None)
-        channel = request_dict.get('channel', None)
-        if not uid or not channel or not rank:
-            return response.json(444, 'channel,rank')
-        qs = Device_Info.objects.filter(userID_id=userID, UID=uid, isShare=False)
-
-        if not qs.exists():
-            return response.json(12)
-        smqs = Store_Meal.objects.filter(id=rank). \
-            values("currency", "price", "content", "day", "bucket__storeDay", "bucket__region", "type")
-        if not smqs.exists():
-            return response.json(10, '套餐不存在')
-        if smqs[0]['type'] != 0:
-            return response.json(10, '套餐不支持paypal支付')
-        currency = smqs[0]['currency']
-        price = smqs[0]['price']
-        content = smqs[0]['content']
-        day = smqs[0]['day']
-        nowTime = int(time.time())
-        ubqs = UID_Bucket.objects.filter(uid=uid, channel=channel, endTime__gte=nowTime). \
-            values("bucket__storeDay", "bucket__region")
-        if ubqs.exists():
-            if ubqs[0]['bucket__region'] != smqs[0]['bucket__region']:
-                return response.json(712)  # 区域不一致
-            # elif ubqs[0]['bucket__storeDay'] > smqs[0]['bucket__storeDay']:
-            #     return response.json(711)  # 不可降级
-            elif ubqs[0]['bucket__storeDay'] != smqs[0]['bucket__storeDay']:
-                return response.json(713)  # 不可更改套餐
-            # 续费流程
-        nowTime = int(time.time())
-        # 判断是否存在未完成订单
-        # hasOrder = Order_Model.objects.filter(UID=uid, channel=channel, addTime__gte=nowTime - 3600, status=0,
-        #                                       rank_id=rank, userID_id=userID).values('paypal')
-        # if hasOrder.exists():
-        #     approval_url = hasOrder[0]['paypal']
-        #     return response.json(0, {"redirectUrl": approval_url})
-        # 新增流程
-        orderID = CommonService.createOrderID()
-        call_sub_url = "{SERVER_DOMAIN}cloudVod/payExecute?orderID={orderID}". \
-            format(SERVER_DOMAIN=SERVER_DOMAIN, orderID=orderID)
-        # call_sub_url = "http://192.168.136.40:8077/cloudVod/payExecute?orderID={orderID}".format(
-        #     SERVER_DOMAIN=SERVER_DOMAIN, orderID=orderID)
-        call_clc_url = "{SERVER_DOMAIN}cloudVod/payError".format(SERVER_DOMAIN=SERVER_DOMAIN)
-        paypalrestsdk.configure(PAYPAL_CRD)
-        payment = paypalrestsdk.Payment({
-            "intent": "sale",
-            "payer": {"payment_method": "paypal"},
-            "redirect_urls": {"return_url": call_sub_url, "cancel_url": call_clc_url},
-            "transactions": [{
-                "item_list": {
-                    "items": [{"name": "Cloud video", "sku": "1", "price": price, "currency": "USD", "quantity": 1}]},
-                "amount": {"total": price, "currency": currency},
-                "description": content
-            }]})
-        if payment.create():
-            print("Payment created successfully")
-        else:
-            print(payment.error)
-            return response.json(10, payment.error)
-        print(payment)
-        for link in payment.links:
-            if link.rel == "approval_url":
-                approval_url = str(link.href)
-                print("Redirect for approval: %s" % (approval_url))
-                Order_Model.objects.create(orderID=orderID, UID=uid, channel=channel, userID_id=userID, desc=content,
-                                           price=price, currency=currency, addTime=nowTime, updTime=nowTime,
-                                           endTime=nowTime + int(day) * 3600 * 24,
-                                           rank_id=rank,
-                                           paypal=approval_url)
-                return response.json(0, {"redirectUrl": approval_url, "orderID": orderID})
-        return response.json(10, 'generate_order_false')
-
-    #  生成设备sts上传授权
     def do_getSts(self, request_dict, ip, response):
     def do_getSts(self, request_dict, ip, response):
         uidToken = request_dict.get('uidToken', None)
         uidToken = request_dict.get('uidToken', None)
         utko = UidTokenObject(uidToken)
         utko = UidTokenObject(uidToken)
         if utko.flag is False:
         if utko.flag is False:
             return response.json(444, 'uidToken')
             return response.json(444, 'uidToken')
-        UID = utko.UID
+        uid = utko.UID
         channel = utko.channel
         channel = utko.channel
         print(channel)
         print(channel)
-        print(UID)
-        ubqs = UID_Bucket.objects.filter(uid=UID, channel=channel, status=1). \
-            values('channel', 'bucket__bucket', 'bucket__endpoint', 'bucket__region', 'endTime')
+        print(uid)
         now_time = int(time.time())
         now_time = int(time.time())
-        if not ubqs.exists():
-            res = {'code': 404, 'msg': '未购买'}
-            return HttpResponse(json.dumps(res, ensure_ascii=False), content_type="application/json,charset=utf-8")
-        elif ubqs[0]['endTime'] < now_time:
-            res = {'code': 404, 'msg': '过期'}
-            return HttpResponse(json.dumps(res, ensure_ascii=False), content_type="application/json,charset=utf-8")
-        oc_qs = OssCrdModel.objects.filter(uid=UID, channel=channel).values("addTime", "data")
-        if oc_qs.exists():
-            endTime = int(oc_qs[0]["addTime"]) + 3500
-            if endTime > now_time:
-                print(endTime)
-                print(now_time)
-                res = json.loads(oc_qs[0]["data"])
+        ubqs = UID_Bucket.objects.filter(uid=uid, channel=channel, endTime__gte=now_time). \
+            values("bucket__mold", "bucket__bucket", "bucket__endpoint", "bucket__region", "endTime")
+        if ubqs.exists():
+            if ubqs[0]["bucket__mold"] == 0:
+                # 阿里云 oss sts
+                oc_qs = OssCrdModel.objects.filter(uid=uid, channel=channel). \
+                    values("addTime", "data")
+                if oc_qs.exists():
+                    endTime = int(oc_qs[0]["addTime"]) + 3500
+                    if endTime > now_time:
+                        print(endTime)
+                        print(now_time)
+                        res = json.loads(oc_qs[0]["data"])
+                        return JsonResponse(status=200, data=res)
+                # 套餐id
+                storage = '{uid}/vod{channel}/'.format(uid=uid, channel=channel)
+                bucket_name = ubqs[0]['bucket__bucket']
+                endpoint = ubqs[0]['bucket__endpoint']
+                access_key_id = OSS_STS_ACCESS_KEY
+                access_key_secret = OSS_STS_ACCESS_SECRET
+                region_id = ubqs[0]['bucket__region']
+                role_arn = OSS_ROLE_ARN
+                clt = client.AcsClient(access_key_id, access_key_secret, region_id)
+                req = AssumeRoleRequest.AssumeRoleRequest()
+                # 设置返回值格式为JSON。
+                req.set_accept_format('json')
+                req.set_RoleArn(role_arn)
+                req.set_RoleSessionName(uid + '_' + channel)
+                req.set_DurationSeconds(3600)
+                Resource_access = "acs:oss:*:*:{bucket_name}/{uid_channel}*". \
+                    format(bucket_name=bucket_name, uid_channel=storage)
+                print(Resource_access)
+                policys = {
+                    "Version": "1",
+                    "Statement": [
+                        {
+                            "Action": ["oss:PutObject", "oss:DeleteObject", ],
+                            "Resource": [Resource_access],
+                            "Effect": "Allow",
+                            "Condition": {
+                                "IpAddress": {"acs:SourceIp": ip}
+                                # "IpAddress": {"acs:SourceIp": "120.237.157.184"}
+                                # "IpAddress": {"acs:SourceIp": "*"}
+                            }
+                        }
+                    ]
+                }
+                req.set_Policy(Policy=json.dumps(policys))
+                body = clt.do_action(req)
+                # 使用RAM账号的AccessKeyId和AccessKeySecret向STS申请临时token。
+                token = json.loads(body.decode('utf-8'))
+                print(token)
+                res = {
+                    'AccessKeyId': token['Credentials']['AccessKeyId'],
+                    'AccessKeySecret': token['Credentials']['AccessKeySecret'],
+                    'SecurityToken': token['Credentials']['SecurityToken'],
+                    'Expiration': token['Credentials']['Expiration'],
+                    'expire': '3600',
+                    'endpoint': endpoint,
+                    'bucket_name': bucket_name,
+                    'arn': token['AssumedRoleUser']['Arn'],
+                    'code': 0,
+                    'storage': storage,
+                    'endTime': ubqs[0]['endTime'],
+                    'ip': ip}
+                if oc_qs.exists():
+                    oc_qs.update(data=json.dumps(res), addTime=now_time)
+                else:
+                    OssCrdModel.objects.create \
+                        (uid=uid, channel=channel, data=json.dumps(res), addTime=now_time)
                 return JsonResponse(status=200, data=res)
                 return JsonResponse(status=200, data=res)
-        # 套餐id
-        storage = '{uid}/vod{channel}/'.format(uid=UID, channel=channel)
-        bucket_name = ubqs[0]['bucket__bucket']
-        endpoint = ubqs[0]['bucket__endpoint']
-        access_key_id = OSS_STS_ACCESS_KEY
-        access_key_secret = OSS_STS_ACCESS_SECRET
-        region_id = ubqs[0]['bucket__region']
-        role_arn = OSS_ROLE_ARN
-        clt = client.AcsClient(access_key_id, access_key_secret, region_id)
-        req = AssumeRoleRequest.AssumeRoleRequest()
-        # 设置返回值格式为JSON。
-        req.set_accept_format('json')
-        req.set_RoleArn(role_arn)
-        req.set_RoleSessionName(UID)
-        req.set_DurationSeconds(3600)
-        Resource_access = "acs:oss:*:*:{bucket_name}/{uid_channel}*".format(bucket_name=bucket_name,
-                                                                            uid_channel=storage)
-        print(Resource_access)
-        policys = {
-            "Version": "1",
-            "Statement": [
-                {
-                    "Action": ["oss:PutObject", "oss:DeleteObject", ],
-                    "Resource": [Resource_access],
-                    "Effect": "Allow",
-                    "Condition": {
-                        "IpAddress": {"acs:SourceIp": ip}
-                        # "IpAddress": {"acs:SourceIp": "120.237.157.184"}
-                        # "IpAddress": {"acs:SourceIp": "*"}
-                    }
+            elif ubqs[0]["bucket__mold"] == 1:
+                # 亚马逊 s3 sts
+                sts_qs = StsCrdModel.objects.filter(uid=uid, channel=channel). \
+                    values("addTime", "data")
+                if sts_qs.exists():
+                    endTime = int(sts_qs[0]["addTime"]) + 3500
+                    if endTime > now_time:
+                        print(endTime)
+                        print(now_time)
+                        res = json.loads(sts_qs[0]["data"])
+                        return JsonResponse(status=200, data=res)
+                    # 套餐id
+                storage = '{uid}/vod{channel}/'.format(uid=uid, channel=channel)
+                bucket_name = ubqs[0]['bucket__bucket']
+                endpoint = ubqs[0]['bucket__endpoint']
+                region_id = ubqs[0]['bucket__region']
+
+                ###############
+                REGION_NAME = region_id
+                boto3_sts = boto3.client(
+                    'sts',
+                    aws_access_key_id='AKIA2E67UIMD45Y3HL53',
+                    aws_secret_access_key='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',
+                    region_name=REGION_NAME
+                )
+                Policy = {
+                    "Version": "2012-10-17",
+                    "Statement": [
+                        {
+                            "Effect": "Allow",
+                            "Action": "s3:*",
+                            "Resource": ["arn:aws:s3:::azvod1/{uid_channel}/*".
+                                             format(uid_channel=storage)]
+                        }
+                    ]
                 }
                 }
-            ]
-        }
-        req.set_Policy(Policy=json.dumps(policys))
-        body = clt.do_action(req)
-        # 使用RAM账号的AccessKeyId和AccessKeySecret向STS申请临时token。
-        token = json.loads(body.decode('utf-8'))
-        print(token)
-        res = {
-            'AccessKeyId': token['Credentials']['AccessKeyId'],
-            'AccessKeySecret': token['Credentials']['AccessKeySecret'],
-            'SecurityToken': token['Credentials']['SecurityToken'],
-            'Expiration': token['Credentials']['Expiration'],
-            'expire': '3600',
-            'endpoint': endpoint,
-            'bucket_name': bucket_name,
-            'arn': token['AssumedRoleUser']['Arn'],
-            'code': 0,
-            'storage': storage,
-            'endTime': ubqs[0]['endTime'],
-            'ip': ip}
-        if oc_qs.exists():
-            oc_qs.update(data=json.dumps(res), addTime=now_time)
-        else:
-            OssCrdModel.objects.create(uid=UID, channel=channel, data=json.dumps(res), addTime=now_time)
-        return JsonResponse(status=200, data=res)
+                response = boto3_sts.get_federation_token(
+                    Name='{role_name}'.format(role_name=uid + '_' + channel),
+                    Policy=json.dumps(Policy),
+                    DurationSeconds=7200
+                )
+                ###############
+                res = {
+                    'AccessKeyId': response['Credentials']['AccessKeyId'],
+                    'AccessKeySecret': response['Credentials']['SecretAccessKey'],
+                    'SessionToken': response['Credentials']['SessionToken'],
+                    'Expiration': response['Credentials']['Expiration'],
+                    'expire': '3600',
+                    'endpoint': endpoint,
+                    'bucket_name': bucket_name,
+                    'arn': response['FederatedUser']['Arn'],
+                    'code': 0,
+                    'storage': storage,
+                    'endTime': ubqs[0]['endTime'],
+                    'ip': ip,
+                }
+                if sts_qs.exists():
+                    sts_qs.update(data=json.dumps(res,default=str), addTime=now_time)
+                else:
+                    StsCrdModel.objects.create(uid=uid, channel=channel, data=json.dumps(res, default=str),
+                                               addTime=now_time, type=1)
+                return JsonResponse(status=200, data=res)
+            else:
+                res = {'code': 404, 'msg': 'data not exists!'}
+                return HttpResponse(json.dumps(res, ensure_ascii=False),
+                                    content_type="application/json,charset=utf-8")
+
+    #  生成设备sts上传授权
+    # def do_getSts(self, request_dict, ip, response):
+    #     uidToken = request_dict.get('uidToken', None)
+    #     utko = UidTokenObject(uidToken)
+    #     if utko.flag is False:
+    #         return response.json(444, 'uidToken')
+    #     UID = utko.UID
+    #     channel = utko.channel
+    #     print(channel)
+    #     print(UID)
+    #     ubqs = UID_Bucket.objects.filter(uid=UID, channel=channel, status=1). \
+    #         values('channel', 'bucket__bucket', 'bucket__endpoint', 'bucket__region', 'endTime')
+    #     now_time = int(time.time())
+    #     if not ubqs.exists():
+    #         res = {'code': 404, 'msg': '未购买'}
+    #         return HttpResponse(json.dumps(res, ensure_ascii=False), content_type="application/json,charset=utf-8")
+    #     elif ubqs[0]['endTime'] < now_time:
+    #         res = {'code': 404, 'msg': '过期'}
+    #         return HttpResponse(json.dumps(res, ensure_ascii=False), content_type="application/json,charset=utf-8")
+    #     oc_qs = OssCrdModel.objects.filter(uid=UID, channel=channel).values("addTime", "data")
+    #     if oc_qs.exists():
+    #         endTime = int(oc_qs[0]["addTime"]) + 3500
+    #         if endTime > now_time:
+    #             print(endTime)
+    #             print(now_time)
+    #             res = json.loads(oc_qs[0]["data"])
+    #             return JsonResponse(status=200, data=res)
+    #     # 套餐id
+    #     storage = '{uid}/vod{channel}/'.format(uid=UID, channel=channel)
+    #     bucket_name = ubqs[0]['bucket__bucket']
+    #     endpoint = ubqs[0]['bucket__endpoint']
+    #     access_key_id = OSS_STS_ACCESS_KEY
+    #     access_key_secret = OSS_STS_ACCESS_SECRET
+    #     region_id = ubqs[0]['bucket__region']
+    #     role_arn = OSS_ROLE_ARN
+    #     clt = client.AcsClient(access_key_id, access_key_secret, region_id)
+    #     req = AssumeRoleRequest.AssumeRoleRequest()
+    #     # 设置返回值格式为JSON。
+    #     req.set_accept_format('json')
+    #     req.set_RoleArn(role_arn)
+    #     req.set_RoleSessionName(UID)
+    #     req.set_DurationSeconds(3600)
+    #     Resource_access = "acs:oss:*:*:{bucket_name}/{uid_channel}*".format(bucket_name=bucket_name,
+    #                                                                         uid_channel=storage)
+    #     print(Resource_access)
+    #     policys = {
+    #         "Version": "1",
+    #         "Statement": [
+    #             {
+    #                 "Action": ["oss:PutObject", "oss:DeleteObject", ],
+    #                 "Resource": [Resource_access],
+    #                 "Effect": "Allow",
+    #                 "Condition": {
+    #                     "IpAddress": {"acs:SourceIp": ip}
+    #                     # "IpAddress": {"acs:SourceIp": "120.237.157.184"}
+    #                     # "IpAddress": {"acs:SourceIp": "*"}
+    #                 }
+    #             }
+    #         ]
+    #     }
+    #     req.set_Policy(Policy=json.dumps(policys))
+    #     body = clt.do_action(req)
+    #     # 使用RAM账号的AccessKeyId和AccessKeySecret向STS申请临时token。
+    #     token = json.loads(body.decode('utf-8'))
+    #     print(token)
+    #     res = {
+    #         'AccessKeyId': token['Credentials']['AccessKeyId'],
+    #         'AccessKeySecret': token['Credentials']['AccessKeySecret'],
+    #         'SecurityToken': token['Credentials']['SecurityToken'],
+    #         'Expiration': token['Credentials']['Expiration'],
+    #         'expire': '3600',
+    #         'endpoint': endpoint,
+    #         'bucket_name': bucket_name,
+    #         'arn': token['AssumedRoleUser']['Arn'],
+    #         'code': 0,
+    #         'storage': storage,
+    #         'endTime': ubqs[0]['endTime'],
+    #         'ip': ip}
+    #     if oc_qs.exists():
+    #         oc_qs.update(data=json.dumps(res), addTime=now_time)
+    #     else:
+    #         OssCrdModel.objects.create(uid=UID, channel=channel, data=json.dumps(res), addTime=now_time)
+    #     return JsonResponse(status=200, data=res)
 
 
     def do_paypal_execute(self, request_dict, response):
     def do_paypal_execute(self, request_dict, response):
         paymentId = request_dict.get('paymentId', None)
         paymentId = request_dict.get('paymentId', None)
@@ -777,6 +534,7 @@ class CloudVodView(View):
         paypalrestsdk.configure(PAYPAL_CRD)
         paypalrestsdk.configure(PAYPAL_CRD)
         # ID of the payment. This ID is provided when creating payment.
         # ID of the payment. This ID is provided when creating payment.
         payment = paypalrestsdk.Payment.find(paymentId)
         payment = paypalrestsdk.Payment.find(paymentId)
+        print(payment)
         payres = payment.execute({"payer_id": PayerID})
         payres = payment.execute({"payer_id": PayerID})
         print(payres)
         print(payres)
         if not payres:
         if not payres:
@@ -954,239 +712,186 @@ class CloudVodView(View):
                 {'name': vod['time'], 'sign_url': vod_play_url, 'thumb': thumb, 'sec': vod['sec'], 'id': vod['id']})
                 {'name': vod['time'], 'sign_url': vod_play_url, 'thumb': thumb, 'sec': vod['sec'], 'id': vod['id']})
         return response.json(0, vod_play_list)
         return response.json(0, vod_play_list)
 
 
-    def do_pay_status(self, request_dict, userID):
+    def do_pay_status(self, request_dict, userID, response):
         orderID = request_dict.get('orderID', None)
         orderID = request_dict.get('orderID', None)
-        om_qs = Order_Model.objects.filter(userID_id=userID, orderID=orderID).values('status')
-        response = HttpResponse()
-        success_pay_content = '''
-
-                <!DOCTYPE html>
-                <html>
-                <head>
-                	<!--浏览器不缓存-->
-                	<meta http-equiv="Pragma" content="no-cache">
-                	<meta http-equiv="Cache-Control" content="no-cache">
-                	<meta http-equiv="Expires" content="0">
-                	<!--utf-8-->
-                    <meta http-equiv="content-type" content="text/html;charset=utf-8">
-                    <!-- viewport的<meta>标签,这个标签可以修改在大部分的移动设备上面的显示,为了确保适当的绘制和触屏缩放。-->
-                    <meta name="viewport" content="width=device-width, initial-scale=1.0">
-                    <link rel="shortcut icon" href="https://test.dvema.com/web/images/favicon.ico" type="image/x-icon"  charset="utf-8"/>  
-                    <title>Trading particulars</title>
-                    <style>
-                    	.title_head{
-                    		height: 50px;
-                    		border-radius: 5px;
-                    		background-color: #c3c6c7; 
-                    		text-align: center;
-                    		line-height: 50px;
-                    	}
-                    	.content{
-                    		text-align: center;
-                    		margin-top: 50px;
-                    		font-size: 20px;
-                    		color : green
-                    	}
-                    	.content_img{
-                    		width: 60px; 
-                    		height: 60px;
-                    	}
-                    	.bottom{
-                    		 margin-bottom: 10px; 
-                    		 margin-top: 250px; 
-                    		 color : green
-                    	}
-                    	.bottom_div{
-                    		border: 1px solid green; 
-                    		line-height: 38px; 
-                    		text-align: center; 
-                    		width: 100px; 
-                    		height: 38px;
-                    		border-radius: 5px;
-                    	}
-
-                    	.bottom_div:hover{
-                    		background-color: #dde4e2;
-                    	}
-                    </style>
-                </head>
-                <body>
-                	<div class="title_head">Trading particulars</div>
-                    <div class="content">
-                    	<p >
-                    		<img src="https://test.dvema.com/web/images/timg.jpg" class="content_img">
-                    		<br />
-                    		Successful payment
-                    	</p>
-                    </div>
-                    <center class="bottom">
-                    	<div class="bottom_div" onclick="payOKButton()"> 
-                    	 Finish
-                    	</div>
-                    </center>
-                    <script> 	    // 点击付款成功按钮
-                    function payOKButton() {
-                        // 复杂数据
-                        console.log('success')
-                        window.webkit.messageHandlers.jsCallOC.postMessage({"status": 1});
-                    }
-                	</script>
-                </body> 
-                </html>
-                        '''
-        falil_pay_content = '''
-        <!DOCTYPE html>
-        <html>
-        <head>
-        	<!--浏览器不缓存-->
-        	<meta http-equiv="Pragma" content="no-cache">
-        	<meta http-equiv="Cache-Control" content="no-cache">
-        	<meta http-equiv="Expires" content="0">
-        	<!--utf-8-->
-            <meta http-equiv="content-type" content="text/html;charset=utf-8">
-            <!-- viewport的<meta>标签,这个标签可以修改在大部分的移动设备上面的显示,为了确保适当的绘制和触屏缩放。-->
-            <meta name="viewport" content="width=device-width, initial-scale=1.0">
-            <link rel="shortcut icon" href="https://test.dvema.com/web/images/favicon.ico" type="image/x-icon"  charset="utf-8"/>  
-            <title>Trading particulars</title>
-            <style>
-            	.title_head{
-            		height: 50px;
-            		border-radius: 5px;
-            		background-color: #c3c6c7; 
-            		text-align: center;
-            		line-height: 50px;
-            	}
-            	.content{
-            		text-align: center;
-            		margin-top: 50px;
-            		font-size: 20px;
-            		color : #ec7648
-            	}
-            	.content_img{
-            		width: 60px; 
-            		height: 60px;
-            	}
-            	.bottom{
-            		 margin-bottom: 10px; 
-            		 margin-top: 250px; 
-            		 color : #ec7648
-            	}
-            	.bottom_div{
-            		border: 1px solid #ec7648; 
-            		line-height: 38px; 
-            		text-align: center; 
-            		width: 100px; 
-            		height: 38px;
-            		border-radius: 5px;
-            	}
-
-            	.bottom_div:hover{
-            		background-color: #dde4e2;
-            	}
-            </style>
-        </head>
-        <body>
-        	<div class="title_head">Trading particulars</div>
-            <div class="content">
-            	<p >
-            		<img src="https://test.dvema.com/web/images/failed.jpg" class="content_img">
-            		<br />
-            		Payment failure
-            	</p>
-            </div>
-            <center class="bottom">
-            	<div class="bottom_div" onclick="payOKButton()"> 
-            	 Finish
-            	</div>
-            </center>
-            <script> 	    // 点击付款成功按钮
-            function payOKButton() {
-                // 复杂数据
-                console.log('success')
-                window.webkit.messageHandlers.jsCallOC.postMessage({"status": 0});
-            }
-        	</script>
-        </body> 
-        </html>
-                        '''
+        lang = request_dict.get('lang', 'en')
+        om_qs = Order_Model.objects.filter(orderID=orderID).values('status')
+        # response = HttpResponse()
+        # success_pay_content = '''
+        #                 '''
+        # falil_pay_content = '''
+        #
+        #                 '''
+
+        status = 0
+        url = "{SERVER_DOMAIN}web/paid2/fail.html".format(SERVER_DOMAIN=SERVER_DOMAIN)
+
         if om_qs.exists():
         if om_qs.exists():
-            if om_qs[0]['status'] == 1:
-                response.content = success_pay_content
-                return response
+            status = om_qs[0]['status']
+            if status == 1:
+
+                url = "{SERVER_DOMAIN}web/paid2/success.html".format(SERVER_DOMAIN=SERVER_DOMAIN)
             else:
             else:
-                # response.content = falil_pay_content
-                # return response
-                # exit()
-                # 如果未支付则调用查询订单是否支付成功
-                aliPayObj = AliPayObject()
-                alipay = aliPayObj.conf()
-                # check order status
-                print("now sleep 3s")
-                # time.sleep(3)
-                result = alipay.api_alipay_trade_query(out_trade_no=orderID)
-                if result.get("trade_status", "") == "TRADE_SUCCESS":
-                    print('paid')
-                    print("trade succeed")
-                    order_qs = Order_Model.objects.filter(orderID=orderID, status=0)
-                    if order_qs.exists():
-                        nowTime = int(time.time())
-                        order_list = order_qs.values("UID", "rank__id", "channel")
-                        rank_id = order_list[0]['rank__id']
-                        print(rank_id)
-                        UID = order_list[0]['UID']
-                        channel = order_list[0]['channel']
-                        order_qs.update(status=1, updTime=nowTime)
-
-                        smqs = Store_Meal.objects.filter(id=rank_id).values("day", "bucket_id", "bucket__storeDay")
-                        bucketId = smqs[0]['bucket_id']
-                        if not smqs.exists():
-                            response.content = falil_pay_content
-                            return response
-                        addTime = int(smqs[0]["day"]) * 24 * 3600
-                        ubqs = UID_Bucket.objects.filter(uid=UID, channel=channel). \
-                            values("bucket_id", "endTime", "bucket__storeDay")
-                        nowTime = int(time.time())
-                        if ubqs.exists():
-                            # 判断是否过期了
-                            if nowTime > ubqs[0]['endTime']:
-                                ubqs.update(endTime=nowTime + addTime)
-                            else:
-                                # 同一个bucket续费
-                                if bucketId == ubqs[0]['bucket_id']:
-                                    ubqs.update(endTime=ubqs[0]['endTime'] + addTime)
-                                else:
-                                    if ubqs[0]['bucket__storeDay'] > smqs[0]['bucket__storeDay']:
-                                        response.content = falil_pay_content
-                                        return response
-                                    else:
-                                        # 升级
-                                        origin_storeDay = int(ubqs[0]['bucket__storeDay'])
-                                        upgrade_storeDay = int(smqs[0]['bucket__storeDay'])
-                                        ctcTime = ubqs[0]['endTime'] - nowTime
-                                        multiple = math.ceil(upgrade_storeDay / origin_storeDay)
-                                        ubqs.update(endTime=ctcTime / multiple + addTime + ubqs[0]['endTime'],
-                                                    bucket_id=bucketId)
-                                        # 付款成功把oss token删除
-                                        OssCrdModel.objects.filter(uid=UID, channel=channel).delete()
-                        # 新增模式
-                        else:
-                            print('create')
-                            UID_Bucket.objects.create(uid=UID, channel=channel,
-                                                      bucket_id=bucketId, endTime=nowTime + addTime)
-
-                        response.content = success_pay_content
-                        return response
-                    else:
-                        response.content = falil_pay_content
-                        return response
+
+                url = "{SERVER_DOMAIN}web/paid2/fail.html".format(SERVER_DOMAIN=SERVER_DOMAIN)
+
+        if lang !='cn':
+            status = 0
+            url = "{SERVER_DOMAIN}web/paid2/en_fail.html".format(SERVER_DOMAIN=SERVER_DOMAIN)
+
+            if om_qs.exists():
+                status = om_qs[0]['status']
+                if status == 1:
+
+                    url = "{SERVER_DOMAIN}web/paid2/en_success.html".format(SERVER_DOMAIN=SERVER_DOMAIN)
+                else:
+
+                    url = "{SERVER_DOMAIN}web/paid2/en_fail.html".format(SERVER_DOMAIN=SERVER_DOMAIN)
+
+        res = {'status': status, 'url': url}
+        return response.json(0, res)
+
+    def query_alipay_order(self, request_dict, userID, response):
+        out_trade_no = request_dict.get('out_trade_no', None)
+
+        if out_trade_no is None:
+            return response.json(444)
+
+        try:
+            aliPayObj = AliPayObject()
+            alipay = aliPayObj.conf()
+            result = alipay.api_alipay_trade_query(out_trade_no=out_trade_no)
+            print(result)
+        except Exception as e:
+            print(repr(e))
+            return response.json(10, repr(e))
+        return response.json(0, {'result': result})
+
+    def do_alipay_cancel(self, request_dict, userID, response):
+        out_trade_no = request_dict.get('out_trade_no', None)
+
+        if out_trade_no is None:
+            return response.json(444)
+
+        order_qs = Order_Model.objects.filter(orderID=out_trade_no)
+        if not order_qs.exists():
+            return response.json(800)
+
+        order = order_qs[0]
+
+        # 交易状态:
+        # WAIT_BUYER_PAY(交易创建,等待买家付款)
+        # TRADE_CLOSED(未付款交易超时关闭,或支付完成后全额退款)
+        # TRADE_SUCCESS(交易支付成功)
+        # TRADE_FINISHED(交易结束,不可退款)
+
+        try:
+            aliPayObj = AliPayObject()
+            alipay = aliPayObj.conf()
+            result = alipay.api_alipay_trade_query(out_trade_no=out_trade_no)
+            result = result['result']
+
+            if result['code'] == '100000':
+                trade_status = result['trade_status']
+                if trade_status == 'TRADE_CLOSED' or trade_status == 'WAIT_BUYER_PAY':
+                    order.status = 2
+                    order.updTime = int(time.time())
+                    order.save()
+                    return response.json(0)
                 else:
                 else:
-                    print("not paid...")
-                    response.content = falil_pay_content
-                    return response
+                    order.status = 1
+                    order.updTime = int(time.time())
+                    order.save()
+                    return response.json(802)
+            else:
+                return response.json(10, result['sub_msg'])
+
+        except Exception as e:
+            print(repr(e))
+            return response.json(10, repr(e))
+
+    def do_alipay_refund(self, request_dict, userID, response):
+        out_trade_no = request_dict.get('out_trade_no', None)
+        refund_amount = request_dict.get('refund_amount', None)
+        reason = request_dict.get('reason', '正常退款')
+
+        if out_trade_no is None:
+            return response.json(444)
+
+        order_qs = Order_Model.objects.filter(orderID=out_trade_no)
+
+        if not order_qs.exists():
+            return response.json(800)
 
 
+        order = order_qs[0]
+        if refund_amount > order.price:
+            return response.json(801)
+
+        try:
+            # extra = {
+            #     'refund_currency': order[0].currency
+            # }
+            aliPayObj = AliPayObject()
+            alipay = aliPayObj.conf()
+            result = alipay.api_alipay_trade_refund(refund_amount=refund_amount, out_trade_no=out_trade_no)
+            result = result['result']
+            print(result)
+            if result['code'] == '10000':
+                order.status = 3
+                order.updTime = int(time.time())
+                order.save()
+                return response.json(0)
+            else:
+                return response.json(10, result['sub_msg'])
+
+        except Exception as e:
+            print(repr(e))
+            return response.json(10, repr(e))
+
+    def do_paypal_refund(self, request_dict, userID, response):
+        out_trade_no = request_dict.get('out_trade_no', None)
+        refund_amount = request_dict.get('refund_amount', None)
+
+        order_qs = Order_Model.objects.filter(orderID=out_trade_no, userID__userID=userID)
+
+        if not order_qs.exists():
+            return response.json(800)
+
+        order = order_qs[0]
+
+        refund_amount = float(refund_amount)
+        if order.price < refund_amount:
+            return response.json(801)
+
+        paypalrestsdk.configure(PAYPAL_CRD)
+        payment = paypalrestsdk.Payment.find(order.trade_no)
+        transactions = payment['transactions']
+        transaction = transactions[0]
+        related_resources = transaction['related_resources']
+        if len(related_resources) > 0:
+            related_resource = related_resources[0]
+            sale = related_resource['sale']
+            id = sale['id']
+
+            if sale['state'] == 'completed':
+                paypalSale = paypalrestsdk.Sale.find(id)
+                refund = paypalSale.refund({
+                    'amount': {
+                        'total': refund_amount,
+                        'currency': order.currency
+                    }
+                })
+
+                if refund.success():
+                    return response.json(0)
+                else:
+                    return response.json(10, refund.error)
+            elif sale['state'] == 'refunded':
+                return response.json(804)
         else:
         else:
-            response.content = falil_pay_content
-            return response
+            return response.json(804)
+
+
 
 
 
 
 def deleteVodHls(request):
 def deleteVodHls(request):

+ 180 - 0
Controller/Cloudsum.py

@@ -0,0 +1,180 @@
+# -*- coding: utf-8 -*-
+"""
+@Time : 2021/1/8 12:00
+@Auth : liehaoquan
+@File :Cloudsum.py
+@IDE :PyCharm
+"""
+import json
+
+from Ansjer.config import SERVER_TYPE
+from Model.models import Order_Model, UID_Bucket, UserExModel, EquipmentLogModel
+from Object.RedisObject import RedisObject
+from Object.ResponseObject import ResponseObject
+from Object.TokenObject import TokenObject
+from django.views import View
+
+from Service.CommonService import CommonService
+from Service.ModelService import Device_User, ModelService
+from django.db.models import Count, Sum
+
+
+class Cloudsum(View):
+    def dispatch(self, requset, *args, **kwargs):
+        return super(Cloudsum, self).dispatch(requset, *args, **kwargs)
+
+    def get(self, request, *args, **kwargs):
+        operation = kwargs.get('operation')
+        request.encoding = 'utf-8'
+        return self.validation(request.GET, request, operation)
+
+    def post(self, request, *args, **kwargs):
+        operation = kwargs.get('operation')
+        request.encoding = 'utf-8'
+        return self.validation(request.POST, request, operation)
+
+    def validation(self, request_dict, request, operation):
+        response = ResponseObject()
+        token = request_dict.get('token', None)
+        tko = TokenObject(token)
+        response.lang = tko.lang
+        userID = tko.userID
+        print('userID:', userID)
+        if tko.code != 0:
+            return response.json(tko.code)
+        if userID is None or operation is None:
+            return response.json(444, 'operation')
+        if operation == 'cloudservicesum':
+            return self.cloudservicesum(userID, response)
+        if operation == 'userappversion':
+            return self.userappversion(userID, response)
+        if operation == 'usercount':
+            return self.usercount(userID, request_dict, response)
+        if operation == 'usercloud':
+            return self.usercloud(userID, response)
+        if operation == 'equipment_logs':
+            return self.equipment_logs(userID, request_dict, response)
+
+    # 类型:用户手机
+    # 统计用户手机型号  已有
+    # 统计某段时间内新用户的增长数√
+    # 统计一天用户打开zosi app的频率   已有
+    # 统计用户下载zosi app数,卸载人数
+    # 统计用户使用zosi app的版本√
+
+    # 统计用户使用zosi app的版本以及使用zosi app不同版本的用户数量
+    def userappversion(self, userID, response):
+        own_permission = ModelService.check_perm(userID=userID, permID=30)
+        if own_permission is not True:
+            return response.json(404)
+        res = UserExModel.objects.extra(tables=['app_info'],
+                                        select={'appname': 'app_info.appName',
+                                                'appversion': 'app_info.newAppversion'},
+                                        where=["user_ex.appBundleId=app_info.appBundleId"]). \
+            values('appBundleId', 'appname', 'appversion').annotate(dates=Count('appBundleId')).order_by()
+        print(res.query)
+        print(res)
+        return response.json(0, list(res))
+
+    # 统计某段时间内新用户的增长数
+    def usercount(self, userID, request_dict, response):
+        own_permission = ModelService.check_perm(userID=userID, permID=30)
+        if own_permission is not True:
+            return response.json(404)
+
+        # 优化代码
+        # usercountyear = request_dict.get('usercountyear', None)
+        # if usercountyear == None:
+        #     return response.json(444)
+        # usercountyear = int(usercountyear)
+        # count = Device_User.objects.extra(select={'dates': "DATE_FORMAT(data_joined,'%%Y-%%m')"},
+        #                                   where=["data_joined between '%s-01-01' and '%s-01-01' "],
+        #                                   params=[usercountyear, usercountyear+1]).values(
+        #     'dates').annotate(用户合计=Count('data_joined')).order_by('dates')
+        count = Device_User.objects.extra(select={'dates': "DATE_FORMAT(data_joined,'%%Y-%%m')"}, ).values(
+            'dates').annotate(用户合计=Count('data_joined')).order_by('dates')
+        print(count.query)
+        return response.json(0, list(count))
+
+    # 类型:云存服务统计
+    # 统计开通云存的设备有多少台√
+    # 统计未支付,支付成功的订单√
+    # 统计开通云存的增长率    (每个月开通云存套餐的总数)√
+    # 统计已开通云存的各套餐总数√
+    # 统计已支付的订单总金额√
+    def cloudservicesum(self, userID, response):
+        own_permission = ModelService.check_perm(userID=userID, permID=30)
+        if own_permission is not True:
+            return response.json(404)
+        uid_cloud = UID_Bucket.objects.values('uid').distinct().count()
+        cloud_sum = UID_Bucket.objects.all().count()
+        pay_0 = Order_Model.objects.filter(status='0').count()
+        pay_1 = Order_Model.objects.filter(status='1').count()
+        money = Order_Model.objects.filter(status='1').aggregate(Sum('price'))
+        data_dict = {
+            "开通云存的设备数": uid_cloud,
+            "已开通云存的各套餐总数": cloud_sum,
+            "未支付的订单数": pay_0,
+            "已支付的订单数": pay_1,
+            "已支付的订单总金额": money['price__sum'],
+        }
+        return response.json(0, data_dict)
+
+    # 每个月开通云存套餐的总数
+    def usercloud(self, userID, response):
+        own_permission = ModelService.check_perm(userID=userID, permID=30)
+        if own_permission is not True:
+            return response.json(404)
+        a = Order_Model.objects.extra(select={'dates': "FROM_UNIXTIME(addTime,'%%Y-%%m')"}).values(
+            'dates').filter(status=1).annotate(开通云存合计=Count('addTime')).order_by('dates')
+        return response.json(0, list(a))
+
+    def equipment_logs(self, userID, request_dict, response):
+        page = int(request_dict.get('page', None))
+        line = int(request_dict.get('line', None))
+        order = request_dict.get('order', '-id')
+        if order == '':
+            order = '-id'
+        if not page or not line:
+            return response.json(444, 'page,line')
+
+        own_perm = ModelService.check_perm(userID=userID, permID=30)
+        if own_perm is not True:
+            return response.json(404)
+
+        if SERVER_TYPE == 'Ansjer.formal_settings':
+            logKey = 'logger'
+        else:
+            logKey = 'test_logger'
+        # 判断redis列表长度
+        redisObj = RedisObject()
+        data_list = redisObj.lrange(logKey, 0, -1)
+        redisObj.del_data(key=logKey)
+        add_batch_log(data_list)
+
+        qs = EquipmentLogModel.objects.all().order_by(order)
+        if qs.exists():
+            count = qs.count()
+            res = qs[(page - 1) * line:page * line]
+            send_json = CommonService.qs_to_dict(res)
+            send_json['count'] = count
+            return response.json(0, send_json)
+        return response.json(0, {'datas': [], 'count': 0})
+
+# 访问日志批量添加
+def add_batch_log(data_list):
+    try:
+        if data_list:
+            querysetlist = []
+            for i in data_list:
+                data = json.loads(i.decode('utf-8'))
+                querysetlist.append(EquipmentLogModel(**data))
+            EquipmentLogModel.objects.bulk_create(querysetlist)
+        else:
+            return
+    except Exception as e:
+        print('ggga')
+        print(repr(e))
+        return False
+    else:
+        return True

+ 237 - 0
Controller/CompanyController.py

@@ -0,0 +1,237 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+import logging
+import time
+
+from django.db import transaction
+from django.views import View
+
+from Model.models import CompanyModel, UserModel, SerialNumberModel, CompanySerialModel
+from Object.uidManageResponseObject import uidManageResponseObject
+from Object.TokenObject import TokenObject
+from Service.CommonService import CommonService
+from Service.ModelService import ModelService
+
+
+class CompanyView(View):
+
+    def get(self, request, *arg, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.GET
+        operation = kwargs.get('operation', None)
+        return self.validate(request_dict, operation)
+
+    def post(self, request, *arg, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.POST
+        operation = kwargs.get('operation', None)
+        return self.validate(request_dict, operation)
+
+    def validate(self, request_dict, operation):
+
+        token = TokenObject(request_dict.get('token', None))
+
+        response = uidManageResponseObject()
+
+        if token.code != 0:
+            return response.json(token.code)
+
+        if operation == 'create':
+            return self.do_create(token.userID, request_dict, response)
+        elif operation == 'update':
+            return self.do_update(token.userID, request_dict, response)
+        elif operation == 'delete':
+            return self.do_delete(token.userID, request_dict, response)
+        elif operation == 'list':
+            return self.do_list(token.userID, request_dict, response)
+        elif operation == 'createSerial':
+            return self.do_create_serial(token.userID, request_dict, response)
+        else:
+            return response.json(404)
+
+    def do_create(self, userID, request_dict, response):
+
+        # perm = ModelService.check_perm_uid_manage(userID, 0)
+        # if not perm:
+        #     return response.json(309)
+
+        name = request_dict.get('name', None)
+        mark = request_dict.get('mark', None)
+
+        if name and mark:
+            now_time = int(time.time())
+            company_qs = CompanyModel.objects.filter(mark=mark)
+            if company_qs.exists():
+                return response.json(174)
+
+            secret = self.create_secret(mark)
+            print(secret)
+
+            company = CompanyModel(
+                name=name,
+                mark=mark,
+                secret=secret,
+                quantity=0,
+                add_time=now_time,
+                update_time=now_time
+            )
+            company.save()
+            return response.json(0)
+        else:
+            return response.json(444)
+
+    def do_update(self, userID, request_dict, response):
+
+        # perm = ModelService.check_perm_uid_manage(userID, 0)
+        # if not perm:
+        #     return response.json(309)
+
+        id = request_dict.get('id', None)
+
+        if id:
+            name = request_dict.get('name', None)
+            quantity = request_dict.get('quantity', None)
+
+            update = {}
+
+            if name:
+                update['name'] = name
+
+            if quantity:
+                update['quantity'] = quantity
+
+            company_qs = CompanyModel.objects.filter(id=id)
+            if company_qs.exists():
+                company_qs.update(**update)
+                return response.json(0)
+            else:
+                return response.json(173)
+
+        else:
+            return response.json(444)
+
+    def do_delete(self, userID, request_dict, response):
+
+        # perm = ModelService.check_perm_uid_manage(userID, 0)
+        # if not perm:
+        #     return response.json(309)
+
+        id = request_dict.get('id', None)
+
+        if id:
+            CompanyModel.objects.filter(id=id).delete()
+            return response.json(0)
+        else:
+            return response.json(444)
+
+    @transaction.atomic
+    def do_create_serial(self, userID, request_dict, response):
+        # perm = ModelService.check_perm_uid_manage(userID, 0)
+        # if not perm:
+        #     return response.json(309)
+
+        id = request_dict.get('id', None)
+        quantity = request_dict.get('quantity', None)
+        p2p = request_dict.get('p2p', None)
+        if id and quantity:
+            company_qs = CompanyModel.objects.filter(id=id)
+
+            if not company_qs.exists():
+                return response.json(444)
+            p2p_sum_Serial = SerialNumberModel.objects.filter(p2p=p2p).count()
+            p2p_sum_Serial_company = CompanySerialModel.objects.filter(p2p=p2p).count()
+            p2p_sum_bind = p2p_sum_Serial - p2p_sum_Serial_company
+            if int(quantity) > int(p2p_sum_bind):
+                return response.json(10041)
+
+            savePoint = transaction.savepoint()
+            try:
+                try:
+
+                    company = company_qs[0]
+                    # start = company.quantity
+                    # start = int(start)
+                    # end = start + int(quantity)
+                    # serial_qs = SerialNumberModel.objects.filter(p2p=p2p)[start:end]
+                    start_1 = p2p_sum_Serial_company
+                    end_1 = int(start_1) + int(quantity)
+                    serial_qs = SerialNumberModel.objects.filter(p2p=p2p)[start_1:end_1]
+                    if serial_qs.exists():
+                        data = []
+                        now_time = int(time.time())
+                        for item in serial_qs:
+                            data.append(CompanySerialModel(
+                                company_id=company.id,
+                                serial_number=item.serial_number,
+                                add_time=now_time,
+                                update_time=now_time,
+                                p2p=p2p
+                            ))
+
+                            if len(data) == 5000:
+                                CompanySerialModel.objects.bulk_create(data)
+                                data.clear()
+                        if len(data) > 0:
+                            CompanySerialModel.objects.bulk_create(data)
+                            data.clear()
+
+                        # company.quantity = company.quantity + end - start
+                        company.quantity =CompanySerialModel.objects.filter(company_id=id).count()
+                        company.save()
+                        return response.json(0)
+                    else:
+                        return response.json(173)
+                except Exception as e:
+                    # print('--------------------------error 5000')
+                    # print(repr(e))
+                    if savePoint:
+                        transaction.rollback(savePoint)
+                    djangoLogger = logging.getLogger('django')
+                    djangoLogger.exception(repr(e))
+                    return response.json(176, str(e))
+            except Exception as e:
+                # print('--------------------------error 5001')
+                # print(repr(e))
+                djangoLogger = logging.getLogger('django')
+                djangoLogger.exception(repr(e))
+                return response.json(176, str(e))
+        else:
+            return response.json(444)
+
+    def do_list(self, userID, request_dict, response):
+        # perm = ModelService.check_perm_uid_manage(userID, 0)
+        # if not perm:
+        #     return response.json(309)
+
+        page = request_dict.get('page', None)
+        line = request_dict.get('limit', None)
+        if page and line:
+            page = int(page)
+            line = int(line)
+
+            start = (page - 1) * line
+            end = start + line
+
+            company_qs = CompanyModel.objects.filter()
+            count = company_qs.count()
+
+            company_qs = company_qs[start: end].values()
+            print(company_qs)
+
+            res = {
+                'count': count,
+                'data': list(company_qs)
+            }
+            return response.json(0, res)
+        else:
+            return response.json(444)
+
+    def create_secret(self, mark):
+        len1 = len(mark)
+        secret = ''
+        for i in range(len1):
+            secret += CommonService.RandomStr(randomlength=1)
+            secret += mark[i]
+
+        print(mark)
+        return CommonService.encode_data_without_salt(secret)

+ 371 - 372
Controller/DateController.py

@@ -26,7 +26,6 @@ from Service.CommonService import CommonService
 from Service.ModelService import ModelService
 from Service.ModelService import ModelService
 
 
 
 
-
 class DateConView(View):
 class DateConView(View):
     @method_decorator(csrf_exempt)
     @method_decorator(csrf_exempt)
     def dispatch(self, *args, **kwargs):
     def dispatch(self, *args, **kwargs):
@@ -51,382 +50,382 @@ class DateConView(View):
         else:
         else:
             return response.json(414)
             return response.json(414)
 
 
-    def do_date(self, request_dict,response):
+    def do_date(self, request_dict, response):
         h = request_dict.get('h', None)
         h = request_dict.get('h', None)
         day = [
         day = [
-        {"dayStr": "20200101", "type": "2"},
-        {"dayStr": "20200102", "type": "0"},
-        {"dayStr": "20200103", "type": "0"},
-        {"dayStr": "20200104", "type": "1"},
-        {"dayStr": "20200105", "type": "1"},
-        {"dayStr": "20200106", "type": "0"},
-        {"dayStr": "20200107", "type": "0"},
-        {"dayStr": "20200108", "type": "0"},
-        {"dayStr": "20200109", "type": "0"},
-        {"dayStr": "20200110", "type": "0"},
-        {"dayStr": "20200111", "type": "1"},
-        {"dayStr": "20200112", "type": "1"},
-        {"dayStr": "20200113", "type": "0"},
-        {"dayStr": "20200114", "type": "0"},
-        {"dayStr": "20200115", "type": "0"},
-        {"dayStr": "20200116", "type": "0"},
-        {"dayStr": "20200117", "type": "0"},
-        {"dayStr": "20200118", "type": "1"},
-        {"dayStr": "20200119", "type": "0"},
-        {"dayStr": "20200120", "type": "0"},
-        {"dayStr": "20200121", "type": "0"},
-        {"dayStr": "20200122", "type": "0"},
-        {"dayStr": "20200123", "type": "0"},
-        {"dayStr": "20200124", "type": "2"},
-        {"dayStr": "20200125", "type": "2"},
-        {"dayStr": "20200126", "type": "2"},
-        {"dayStr": "20200127", "type": "2"},
-        {"dayStr": "20200128", "type": "2"},
-        {"dayStr": "20200129", "type": "2"},
-        {"dayStr": "20200130", "type": "2"},
-        {"dayStr": "20200131", "type": "0"},
-        {"dayStr": "20200201", "type": "0"},
-        {"dayStr": "20200202", "type": "1"},
-        {"dayStr": "20200203", "type": "0"},
-        {"dayStr": "20200204", "type": "0"},
-        {"dayStr": "20200205", "type": "0"},
-        {"dayStr": "20200206", "type": "0"},
-        {"dayStr": "20200207", "type": "0"},
-        {"dayStr": "20200208", "type": "1"},
-        {"dayStr": "20200209", "type": "1"},
-        {"dayStr": "20200210", "type": "0"},
-        {"dayStr": "20200211", "type": "0"},
-        {"dayStr": "20200212", "type": "0"},
-        {"dayStr": "20200213", "type": "0"},
-        {"dayStr": "20200214", "type": "0"},
-        {"dayStr": "20200215", "type": "1"},
-        {"dayStr": "20200216", "type": "1"},
-        {"dayStr": "20200217", "type": "0"},
-        {"dayStr": "20200218", "type": "0"},
-        {"dayStr": "20200219", "type": "0"},
-        {"dayStr": "20200220", "type": "0"},
-        {"dayStr": "20200221", "type": "0"},
-        {"dayStr": "20200222", "type": "1"},
-        {"dayStr": "20200223", "type": "1"},
-        {"dayStr": "20200224", "type": "0"},
-        {"dayStr": "20200225", "type": "0"},
-        {"dayStr": "20200226", "type": "0"},
-        {"dayStr": "20200227", "type": "0"},
-        {"dayStr": "20200228", "type": "0"},
-        {"dayStr": "20200229", "type": "1"},
-        {"dayStr": "20200301", "type": "1"},
-        {"dayStr": "20200302", "type": "0"},
-        {"dayStr": "20200303", "type": "0"},
-        {"dayStr": "20200304", "type": "0"},
-        {"dayStr": "20200305", "type": "0"},
-        {"dayStr": "20200306", "type": "0"},
-        {"dayStr": "20200307", "type": "1"},
-        {"dayStr": "20200308", "type": "1"},
-        {"dayStr": "20200309", "type": "0"},
-        {"dayStr": "20200310", "type": "0"},
-        {"dayStr": "20200311", "type": "0"},
-        {"dayStr": "20200312", "type": "0"},
-        {"dayStr": "20200313", "type": "0"},
-        {"dayStr": "20200314", "type": "1"},
-        {"dayStr": "20200315", "type": "1"},
-        {"dayStr": "20200316", "type": "0"},
-        {"dayStr": "20200317", "type": "0"},
-        {"dayStr": "20200318", "type": "0"},
-        {"dayStr": "20200319", "type": "0"},
-        {"dayStr": "20200320", "type": "0"},
-        {"dayStr": "20200321", "type": "1"},
-        {"dayStr": "20200322", "type": "1"},
-        {"dayStr": "20200323", "type": "0"},
-        {"dayStr": "20200324", "type": "0"},
-        {"dayStr": "20200325", "type": "0"},
-        {"dayStr": "20200326", "type": "0"},
-        {"dayStr": "20200327", "type": "0"},
-        {"dayStr": "20200328", "type": "1"},
-        {"dayStr": "20200329", "type": "1"},
-        {"dayStr": "20200330", "type": "0"},
-        {"dayStr": "20200331", "type": "0"},
-        {"dayStr": "20200401", "type": "0"},
-        {"dayStr": "20200402", "type": "0"},
-        {"dayStr": "20200403", "type": "0"},
-        {"dayStr": "20200404", "type": "2"},
-        {"dayStr": "20200405", "type": "2"},
-        {"dayStr": "20200406", "type": "2"},
-        {"dayStr": "20200407", "type": "0"},
-        {"dayStr": "20200408", "type": "0"},
-        {"dayStr": "20200409", "type": "0"},
-        {"dayStr": "20200410", "type": "0"},
-        {"dayStr": "20200411", "type": "1"},
-        {"dayStr": "20200412", "type": "1"},
-        {"dayStr": "20200413", "type": "0"},
-        {"dayStr": "20200414", "type": "0"},
-        {"dayStr": "20200415", "type": "0"},
-        {"dayStr": "20200416", "type": "0"},
-        {"dayStr": "20200417", "type": "0"},
-        {"dayStr": "20200418", "type": "1"},
-        {"dayStr": "20200419", "type": "1"},
-        {"dayStr": "20200420", "type": "0"},
-        {"dayStr": "20200421", "type": "0"},
-        {"dayStr": "20200422", "type": "0"},
-        {"dayStr": "20200423", "type": "0"},
-        {"dayStr": "20200424", "type": "0"},
-        {"dayStr": "20200425", "type": "1"},
-        {"dayStr": "20200426", "type": "0"},
-        {"dayStr": "20200427", "type": "0"},
-        {"dayStr": "20200428", "type": "0"},
-        {"dayStr": "20200429", "type": "0"},
-        {"dayStr": "20200430", "type": "0"},
-        {"dayStr": "20200501", "type": "2"},
-        {"dayStr": "20200502", "type": "2"},
-        {"dayStr": "20200503", "type": "2"},
-        {"dayStr": "20200504", "type": "2"},
-        {"dayStr": "20200505", "type": "2"},
-        {"dayStr": "20200506", "type": "0"},
-        {"dayStr": "20200507", "type": "0"},
-        {"dayStr": "20200508", "type": "0"},
-        {"dayStr": "20200509", "type": "0"},
-        {"dayStr": "20200510", "type": "1"},
-        {"dayStr": "20200511", "type": "0"},
-        {"dayStr": "20200512", "type": "0"},
-        {"dayStr": "20200513", "type": "0"},
-        {"dayStr": "20200514", "type": "0"},
-        {"dayStr": "20200515", "type": "0"},
-        {"dayStr": "20200516", "type": "1"},
-        {"dayStr": "20200517", "type": "1"},
-        {"dayStr": "20200518", "type": "0"},
-        {"dayStr": "20200519", "type": "0"},
-        {"dayStr": "20200520", "type": "0"},
-        {"dayStr": "20200521", "type": "0"},
-        {"dayStr": "20200522", "type": "0"},
-        {"dayStr": "20200523", "type": "1"},
-        {"dayStr": "20200524", "type": "1"},
-        {"dayStr": "20200525", "type": "0"},
-        {"dayStr": "20200526", "type": "0"},
-        {"dayStr": "20200527", "type": "0"},
-        {"dayStr": "20200528", "type": "0"},
-        {"dayStr": "20200529", "type": "0"},
-        {"dayStr": "20200530", "type": "1"},
-        {"dayStr": "20200531", "type": "1"},
-        {"dayStr": "20200601", "type": "0"},
-        {"dayStr": "20200602", "type": "0"},
-        {"dayStr": "20200603", "type": "0"},
-        {"dayStr": "20200604", "type": "0"},
-        {"dayStr": "20200605", "type": "0"},
-        {"dayStr": "20200606", "type": "1"},
-        {"dayStr": "20200607", "type": "1"},
-        {"dayStr": "20200608", "type": "0"},
-        {"dayStr": "20200609", "type": "0"},
-        {"dayStr": "20200610", "type": "0"},
-        {"dayStr": "20200611", "type": "0"},
-        {"dayStr": "20200612", "type": "0"},
-        {"dayStr": "20200613", "type": "1"},
-        {"dayStr": "20200614", "type": "1"},
-        {"dayStr": "20200615", "type": "0"},
-        {"dayStr": "20200616", "type": "0"},
-        {"dayStr": "20200617", "type": "0"},
-        {"dayStr": "20200618", "type": "0"},
-        {"dayStr": "20200619", "type": "0"},
-        {"dayStr": "20200620", "type": "1"},
-        {"dayStr": "20200621", "type": "1"},
-        {"dayStr": "20200622", "type": "0"},
-        {"dayStr": "20200623", "type": "0"},
-        {"dayStr": "20200624", "type": "0"},
-        {"dayStr": "20200625", "type": "2"},
-        {"dayStr": "20200626", "type": "2"},
-        {"dayStr": "20200627", "type": "2"},
-        {"dayStr": "20200628", "type": "0"},
-        {"dayStr": "20200629", "type": "0"},
-        {"dayStr": "20200630", "type": "0"},
-        {"dayStr": "20200701", "type": "0"},
-        {"dayStr": "20200702", "type": "0"},
-        {"dayStr": "20200703", "type": "0"},
-        {"dayStr": "20200704", "type": "1"},
-        {"dayStr": "20200705", "type": "1"},
-        {"dayStr": "20200706", "type": "0"},
-        {"dayStr": "20200707", "type": "0"},
-        {"dayStr": "20200708", "type": "0"},
-        {"dayStr": "20200709", "type": "0"},
-        {"dayStr": "20200710", "type": "0"},
-        {"dayStr": "20200711", "type": "1"},
-        {"dayStr": "20200712", "type": "1"},
-        {"dayStr": "20200713", "type": "0"},
-        {"dayStr": "20200714", "type": "0"},
-        {"dayStr": "20200715", "type": "0"},
-        {"dayStr": "20200716", "type": "0"},
-        {"dayStr": "20200717", "type": "0"},
-        {"dayStr": "20200718", "type": "1"},
-        {"dayStr": "20200719", "type": "1"},
-        {"dayStr": "20200720", "type": "0"},
-        {"dayStr": "20200721", "type": "0"},
-        {"dayStr": "20200722", "type": "0"},
-        {"dayStr": "20200723", "type": "0"},
-        {"dayStr": "20200724", "type": "0"},
-        {"dayStr": "20200725", "type": "1"},
-        {"dayStr": "20200726", "type": "1"},
-        {"dayStr": "20200727", "type": "0"},
-        {"dayStr": "20200728", "type": "0"},
-        {"dayStr": "20200729", "type": "0"},
-        {"dayStr": "20200730", "type": "0"},
-        {"dayStr": "20200731", "type": "0"},
-        {"dayStr": "20200801", "type": "1"},
-        {"dayStr": "20200802", "type": "1"},
-        {"dayStr": "20200803", "type": "0"},
-        {"dayStr": "20200804", "type": "0"},
-        {"dayStr": "20200805", "type": "0"},
-        {"dayStr": "20200806", "type": "0"},
-        {"dayStr": "20200807", "type": "0"},
-        {"dayStr": "20200808", "type": "1"},
-        {"dayStr": "20200809", "type": "1"},
-        {"dayStr": "20200810", "type": "0"},
-        {"dayStr": "20200811", "type": "0"},
-        {"dayStr": "20200812", "type": "0"},
-        {"dayStr": "20200813", "type": "0"},
-        {"dayStr": "20200814", "type": "0"},
-        {"dayStr": "20200815", "type": "1"},
-        {"dayStr": "20200816", "type": "1"},
-        {"dayStr": "20200817", "type": "0"},
-        {"dayStr": "20200818", "type": "0"},
-        {"dayStr": "20200819", "type": "0"},
-        {"dayStr": "20200820", "type": "0"},
-        {"dayStr": "20200821", "type": "0"},
-        {"dayStr": "20200822", "type": "1"},
-        {"dayStr": "20200823", "type": "1"},
-        {"dayStr": "20200824", "type": "0"},
-        {"dayStr": "20200825", "type": "0"},
-        {"dayStr": "20200826", "type": "0"},
-        {"dayStr": "20200827", "type": "0"},
-        {"dayStr": "20200828", "type": "0"},
-        {"dayStr": "20200829", "type": "1"},
-        {"dayStr": "20200830", "type": "1"},
-        {"dayStr": "20200831", "type": "0"},
-        {"dayStr": "20200901", "type": "0"},
-        {"dayStr": "20200902", "type": "0"},
-        {"dayStr": "20200903", "type": "0"},
-        {"dayStr": "20200904", "type": "0"},
-        {"dayStr": "20200905", "type": "1"},
-        {"dayStr": "20200906", "type": "1"},
-        {"dayStr": "20200907", "type": "0"},
-        {"dayStr": "20200908", "type": "0"},
-        {"dayStr": "20200909", "type": "0"},
-        {"dayStr": "20200910", "type": "0"},
-        {"dayStr": "20200911", "type": "0"},
-        {"dayStr": "20200912", "type": "1"},
-        {"dayStr": "20200913", "type": "1"},
-        {"dayStr": "20200914", "type": "0"},
-        {"dayStr": "20200915", "type": "0"},
-        {"dayStr": "20200916", "type": "0"},
-        {"dayStr": "20200917", "type": "0"},
-        {"dayStr": "20200918", "type": "0"},
-        {"dayStr": "20200919", "type": "1"},
-        {"dayStr": "20200920", "type": "1"},
-        {"dayStr": "20200921", "type": "0"},
-        {"dayStr": "20200922", "type": "0"},
-        {"dayStr": "20200923", "type": "0"},
-        {"dayStr": "20200924", "type": "0"},
-        {"dayStr": "20200925", "type": "0"},
-        {"dayStr": "20200926", "type": "1"},
-        {"dayStr": "20200927", "type": "0"},
-        {"dayStr": "20200928", "type": "0"},
-        {"dayStr": "20200929", "type": "0"},
-        {"dayStr": "20200930", "type": "0"},
-        {"dayStr": "20201001", "type": "2"},
-        {"dayStr": "20201002", "type": "2"},
-        {"dayStr": "20201003", "type": "2"},
-        {"dayStr": "20201004", "type": "2"},
-        {"dayStr": "20201005", "type": "2"},
-        {"dayStr": "20201006", "type": "2"},
-        {"dayStr": "20201007", "type": "2"},
-        {"dayStr": "20201008", "type": "2"},
-        {"dayStr": "20201009", "type": "0"},
-        {"dayStr": "20201010", "type": "0"},
-        {"dayStr": "20201011", "type": "1"},
-        {"dayStr": "20201012", "type": "0"},
-        {"dayStr": "20201013", "type": "0"},
-        {"dayStr": "20201014", "type": "0"},
-        {"dayStr": "20201015", "type": "0"},
-        {"dayStr": "20201016", "type": "0"},
-        {"dayStr": "20201017", "type": "1"},
-        {"dayStr": "20201018", "type": "1"},
-        {"dayStr": "20201019", "type": "0"},
-        {"dayStr": "20201020", "type": "0"},
-        {"dayStr": "20201021", "type": "0"},
-        {"dayStr": "20201022", "type": "0"},
-        {"dayStr": "20201023", "type": "0"},
-        {"dayStr": "20201024", "type": "1"},
-        {"dayStr": "20201025", "type": "1"},
-        {"dayStr": "20201026", "type": "0"},
-        {"dayStr": "20201027", "type": "0"},
-        {"dayStr": "20201028", "type": "0"},
-        {"dayStr": "20201029", "type": "0"},
-        {"dayStr": "20201030", "type": "0"},
-        {"dayStr": "20201031", "type": "1"},
-        {"dayStr": "20201101", "type": "1"},
-        {"dayStr": "20201102", "type": "0"},
-        {"dayStr": "20201103", "type": "0"},
-        {"dayStr": "20201104", "type": "0"},
-        {"dayStr": "20201105", "type": "0"},
-        {"dayStr": "20201106", "type": "0"},
-        {"dayStr": "20201107", "type": "1"},
-        {"dayStr": "20201108", "type": "1"},
-        {"dayStr": "20201109", "type": "0"},
-        {"dayStr": "20201110", "type": "0"},
-        {"dayStr": "20201111", "type": "0"},
-        {"dayStr": "20201112", "type": "0"},
-        {"dayStr": "20201113", "type": "0"},
-        {"dayStr": "20201114", "type": "1"},
-        {"dayStr": "20201115", "type": "1"},
-        {"dayStr": "20201116", "type": "0"},
-        {"dayStr": "20201117", "type": "0"},
-        {"dayStr": "20201118", "type": "0"},
-        {"dayStr": "20201119", "type": "0"},
-        {"dayStr": "20201120", "type": "0"},
-        {"dayStr": "20201121", "type": "1"},
-        {"dayStr": "20201122", "type": "1"},
-        {"dayStr": "20201123", "type": "0"},
-        {"dayStr": "20201124", "type": "0"},
-        {"dayStr": "20201125", "type": "0"},
-        {"dayStr": "20201126", "type": "0"},
-        {"dayStr": "20201127", "type": "0"},
-        {"dayStr": "20201128", "type": "1"},
-        {"dayStr": "20201129", "type": "1"},
-        {"dayStr": "20201130", "type": "0"},
-        {"dayStr": "20201201", "type": "0"},
-        {"dayStr": "20201202", "type": "0"},
-        {"dayStr": "20201203", "type": "0"},
-        {"dayStr": "20201204", "type": "0"},
-        {"dayStr": "20201205", "type": "1"},
-        {"dayStr": "20201206", "type": "1"},
-        {"dayStr": "20201207", "type": "0"},
-        {"dayStr": "20201208", "type": "0"},
-        {"dayStr": "20201209", "type": "0"},
-        {"dayStr": "20201210", "type": "0"},
-        {"dayStr": "20201211", "type": "0"},
-        {"dayStr": "20201212", "type": "1"},
-        {"dayStr": "20201213", "type": "1"},
-        {"dayStr": "20201214", "type": "0"},
-        {"dayStr": "20201215", "type": "0"},
-        {"dayStr": "20201216", "type": "0"},
-        {"dayStr": "20201217", "type": "0"},
-        {"dayStr": "20201218", "type": "0"},
-        {"dayStr": "20201219", "type": "1"},
-        {"dayStr": "20201220", "type": "1"},
-        {"dayStr": "20201221", "type": "0"},
-        {"dayStr": "20201222", "type": "0"},
-        {"dayStr": "20201223", "type": "0"},
-        {"dayStr": "20201224", "type": "0"},
-        {"dayStr": "20201225", "type": "0"},
-        {"dayStr": "20201226", "type": "1"},
-        {"dayStr": "20201227", "type": "1"},
-        {"dayStr": "20201228", "type": "0"},
-        {"dayStr": "20201229", "type": "0"},
-        {"dayStr": "20201230", "type": "0"},
-        {"dayStr": "20201231", "type": "0"}
+            {"dayStr": "20210101", "type": "2"},
+            {"dayStr": "20210102", "type": "2"},
+            {"dayStr": "20210103", "type": "2"},
+            {"dayStr": "20210104", "type": "0"},
+            {"dayStr": "20210105", "type": "0"},
+            {"dayStr": "20210106", "type": "0"},
+            {"dayStr": "20210107", "type": "0"},
+            {"dayStr": "20210108", "type": "0"},
+            {"dayStr": "20210109", "type": "1"},
+            {"dayStr": "20210110", "type": "1"},
+            {"dayStr": "20210111", "type": "0"},
+            {"dayStr": "20210112", "type": "0"},
+            {"dayStr": "20210113", "type": "0"},
+            {"dayStr": "20210114", "type": "0"},
+            {"dayStr": "20210115", "type": "0"},
+            {"dayStr": "20210116", "type": "1"},
+            {"dayStr": "20210117", "type": "1"},
+            {"dayStr": "20210118", "type": "0"},
+            {"dayStr": "20210119", "type": "0"},
+            {"dayStr": "20210120", "type": "0"},
+            {"dayStr": "20210121", "type": "0"},
+            {"dayStr": "20210122", "type": "0"},
+            {"dayStr": "20210123", "type": "1"},
+            {"dayStr": "20210124", "type": "1"},
+            {"dayStr": "20210125", "type": "0"},
+            {"dayStr": "20210126", "type": "0"},
+            {"dayStr": "20210127", "type": "0"},
+            {"dayStr": "20210128", "type": "0"},
+            {"dayStr": "20210129", "type": "0"},
+            {"dayStr": "20210130", "type": "1"},
+            {"dayStr": "20210131", "type": "1"},
+            {"dayStr": "20210201", "type": "0"},
+            {"dayStr": "20210202", "type": "0"},
+            {"dayStr": "20210203", "type": "0"},
+            {"dayStr": "20210204", "type": "0"},
+            {"dayStr": "20210205", "type": "0"},
+            {"dayStr": "20210206", "type": "1"},
+            {"dayStr": "20210207", "type": "0"},
+            {"dayStr": "20210208", "type": "0"},
+            {"dayStr": "20210209", "type": "0"},
+            {"dayStr": "20210210", "type": "0"},
+            {"dayStr": "20210211", "type": "2"},
+            {"dayStr": "20210212", "type": "2"},
+            {"dayStr": "20210213", "type": "2"},
+            {"dayStr": "20210214", "type": "2"},
+            {"dayStr": "20210215", "type": "2"},
+            {"dayStr": "20210216", "type": "2"},
+            {"dayStr": "20210217", "type": "2"},
+            {"dayStr": "20210218", "type": "0"},
+            {"dayStr": "20210219", "type": "0"},
+            {"dayStr": "20210220", "type": "0"},
+            {"dayStr": "20210221", "type": "1"},
+            {"dayStr": "20210222", "type": "0"},
+            {"dayStr": "20210223", "type": "0"},
+            {"dayStr": "20210224", "type": "0"},
+            {"dayStr": "20210225", "type": "0"},
+            {"dayStr": "20210226", "type": "0"},
+            {"dayStr": "20210227", "type": "1"},
+            {"dayStr": "20210228", "type": "1"},
+            {"dayStr": "20210229", "type": "0"},
+            {"dayStr": "20210301", "type": "0"},
+            {"dayStr": "20210302", "type": "0"},
+            {"dayStr": "20210303", "type": "0"},
+            {"dayStr": "20210304", "type": "0"},
+            {"dayStr": "20210305", "type": "0"},
+            {"dayStr": "20210306", "type": "1"},
+            {"dayStr": "20210307", "type": "1"},
+            {"dayStr": "20210308", "type": "0"},
+            {"dayStr": "20210309", "type": "0"},
+            {"dayStr": "20210310", "type": "0"},
+            {"dayStr": "20210311", "type": "0"},
+            {"dayStr": "20210312", "type": "0"},
+            {"dayStr": "20210313", "type": "1"},
+            {"dayStr": "20210314", "type": "1"},
+            {"dayStr": "20210315", "type": "0"},
+            {"dayStr": "20210316", "type": "0"},
+            {"dayStr": "20210317", "type": "0"},
+            {"dayStr": "20210318", "type": "0"},
+            {"dayStr": "20210319", "type": "0"},
+            {"dayStr": "20210320", "type": "1"},
+            {"dayStr": "20210321", "type": "1"},
+            {"dayStr": "20210322", "type": "0"},
+            {"dayStr": "20210323", "type": "0"},
+            {"dayStr": "20210324", "type": "0"},
+            {"dayStr": "20210325", "type": "0"},
+            {"dayStr": "20210326", "type": "0"},
+            {"dayStr": "20210327", "type": "1"},
+            {"dayStr": "20210328", "type": "1"},
+            {"dayStr": "20210329", "type": "0"},
+            {"dayStr": "20210330", "type": "0"},
+            {"dayStr": "20210331", "type": "0"},
+            {"dayStr": "20210401", "type": "0"},
+            {"dayStr": "20210402", "type": "0"},
+            {"dayStr": "20210403", "type": "2"},
+            {"dayStr": "20210404", "type": "2"},
+            {"dayStr": "20210405", "type": "2"},
+            {"dayStr": "20210406", "type": "0"},
+            {"dayStr": "20210407", "type": "0"},
+            {"dayStr": "20210408", "type": "0"},
+            {"dayStr": "20210409", "type": "0"},
+            {"dayStr": "20210410", "type": "1"},
+            {"dayStr": "20210411", "type": "1"},
+            {"dayStr": "20210412", "type": "0"},
+            {"dayStr": "20210413", "type": "0"},
+            {"dayStr": "20210414", "type": "0"},
+            {"dayStr": "20210415", "type": "0"},
+            {"dayStr": "20210416", "type": "0"},
+            {"dayStr": "20210417", "type": "1"},
+            {"dayStr": "20210418", "type": "1"},
+            {"dayStr": "20210419", "type": "0"},
+            {"dayStr": "20210420", "type": "0"},
+            {"dayStr": "20210421", "type": "0"},
+            {"dayStr": "20210422", "type": "0"},
+            {"dayStr": "20210423", "type": "0"},
+            {"dayStr": "20210424", "type": "1"},
+            {"dayStr": "20210425", "type": "0"},
+            {"dayStr": "20210426", "type": "0"},
+            {"dayStr": "20210427", "type": "0"},
+            {"dayStr": "20210428", "type": "0"},
+            {"dayStr": "20210429", "type": "0"},
+            {"dayStr": "20210430", "type": "0"},
+            {"dayStr": "20210501", "type": "2"},
+            {"dayStr": "20210502", "type": "2"},
+            {"dayStr": "20210503", "type": "2"},
+            {"dayStr": "20210504", "type": "2"},
+            {"dayStr": "20210505", "type": "2"},
+            {"dayStr": "20210506", "type": "0"},
+            {"dayStr": "20210507", "type": "0"},
+            {"dayStr": "20210508", "type": "0"},
+            {"dayStr": "20210509", "type": "1"},
+            {"dayStr": "20210510", "type": "0"},
+            {"dayStr": "20210511", "type": "0"},
+            {"dayStr": "20210512", "type": "0"},
+            {"dayStr": "20210513", "type": "0"},
+            {"dayStr": "20210514", "type": "0"},
+            {"dayStr": "20210515", "type": "1"},
+            {"dayStr": "20210516", "type": "1"},
+            {"dayStr": "20210517", "type": "0"},
+            {"dayStr": "20210518", "type": "0"},
+            {"dayStr": "20210519", "type": "0"},
+            {"dayStr": "20210520", "type": "0"},
+            {"dayStr": "20210521", "type": "0"},
+            {"dayStr": "20210522", "type": "1"},
+            {"dayStr": "20210523", "type": "1"},
+            {"dayStr": "20210524", "type": "0"},
+            {"dayStr": "20210525", "type": "0"},
+            {"dayStr": "20210526", "type": "0"},
+            {"dayStr": "20210527", "type": "0"},
+            {"dayStr": "20210528", "type": "0"},
+            {"dayStr": "20210529", "type": "1"},
+            {"dayStr": "20210530", "type": "1"},
+            {"dayStr": "20210531", "type": "0"},
+            {"dayStr": "20210601", "type": "0"},
+            {"dayStr": "20210602", "type": "0"},
+            {"dayStr": "20210603", "type": "0"},
+            {"dayStr": "20210604", "type": "0"},
+            {"dayStr": "20210605", "type": "1"},
+            {"dayStr": "20210606", "type": "1"},
+            {"dayStr": "20210607", "type": "0"},
+            {"dayStr": "20210608", "type": "0"},
+            {"dayStr": "20210609", "type": "0"},
+            {"dayStr": "20210610", "type": "0"},
+            {"dayStr": "20210611", "type": "0"},
+            {"dayStr": "20210612", "type": "2"},
+            {"dayStr": "20210613", "type": "2"},
+            {"dayStr": "20210614", "type": "2"},
+            {"dayStr": "20210615", "type": "0"},
+            {"dayStr": "20210616", "type": "0"},
+            {"dayStr": "20210617", "type": "0"},
+            {"dayStr": "20210618", "type": "0"},
+            {"dayStr": "20210619", "type": "1"},
+            {"dayStr": "20210620", "type": "1"},
+            {"dayStr": "20210621", "type": "0"},
+            {"dayStr": "20210622", "type": "0"},
+            {"dayStr": "20210623", "type": "0"},
+            {"dayStr": "20210624", "type": "0"},
+            {"dayStr": "20210625", "type": "0"},
+            {"dayStr": "20210626", "type": "1"},
+            {"dayStr": "20210627", "type": "1"},
+            {"dayStr": "20210628", "type": "0"},
+            {"dayStr": "20210629", "type": "0"},
+            {"dayStr": "20210630", "type": "0"},
+            {"dayStr": "20210701", "type": "0"},
+            {"dayStr": "20210702", "type": "0"},
+            {"dayStr": "20210703", "type": "1"},
+            {"dayStr": "20210704", "type": "1"},
+            {"dayStr": "20210705", "type": "0"},
+            {"dayStr": "20210706", "type": "0"},
+            {"dayStr": "20210707", "type": "0"},
+            {"dayStr": "20210708", "type": "0"},
+            {"dayStr": "20210709", "type": "0"},
+            {"dayStr": "20210710", "type": "1"},
+            {"dayStr": "20210711", "type": "1"},
+            {"dayStr": "20210712", "type": "0"},
+            {"dayStr": "20210713", "type": "0"},
+            {"dayStr": "20210714", "type": "0"},
+            {"dayStr": "20210715", "type": "0"},
+            {"dayStr": "20210716", "type": "0"},
+            {"dayStr": "20210717", "type": "1"},
+            {"dayStr": "20210718", "type": "1"},
+            {"dayStr": "20210719", "type": "0"},
+            {"dayStr": "20210720", "type": "0"},
+            {"dayStr": "20210721", "type": "0"},
+            {"dayStr": "20210722", "type": "0"},
+            {"dayStr": "20210723", "type": "0"},
+            {"dayStr": "20210724", "type": "1"},
+            {"dayStr": "20210725", "type": "1"},
+            {"dayStr": "20210726", "type": "0"},
+            {"dayStr": "20210727", "type": "0"},
+            {"dayStr": "20210728", "type": "0"},
+            {"dayStr": "20210729", "type": "0"},
+            {"dayStr": "20210730", "type": "0"},
+            {"dayStr": "20210731", "type": "1"},
+            {"dayStr": "20210801", "type": "1"},
+            {"dayStr": "20210802", "type": "0"},
+            {"dayStr": "20210803", "type": "0"},
+            {"dayStr": "20210804", "type": "0"},
+            {"dayStr": "20210805", "type": "0"},
+            {"dayStr": "20210806", "type": "0"},
+            {"dayStr": "20210807", "type": "1"},
+            {"dayStr": "20210808", "type": "1"},
+            {"dayStr": "20210809", "type": "0"},
+            {"dayStr": "20210810", "type": "0"},
+            {"dayStr": "20210811", "type": "0"},
+            {"dayStr": "20210812", "type": "0"},
+            {"dayStr": "20210813", "type": "0"},
+            {"dayStr": "20210814", "type": "1"},
+            {"dayStr": "20210815", "type": "1"},
+            {"dayStr": "20210816", "type": "0"},
+            {"dayStr": "20210817", "type": "0"},
+            {"dayStr": "20210818", "type": "0"},
+            {"dayStr": "20210819", "type": "0"},
+            {"dayStr": "20210820", "type": "0"},
+            {"dayStr": "20210821", "type": "1"},
+            {"dayStr": "20210822", "type": "1"},
+            {"dayStr": "20210823", "type": "0"},
+            {"dayStr": "20210824", "type": "0"},
+            {"dayStr": "20210825", "type": "0"},
+            {"dayStr": "20210826", "type": "0"},
+            {"dayStr": "20210827", "type": "0"},
+            {"dayStr": "20210828", "type": "1"},
+            {"dayStr": "20210829", "type": "1"},
+            {"dayStr": "20210830", "type": "0"},
+            {"dayStr": "20210831", "type": "0"},
+            {"dayStr": "20210901", "type": "0"},
+            {"dayStr": "20210902", "type": "0"},
+            {"dayStr": "20210903", "type": "0"},
+            {"dayStr": "20210904", "type": "1"},
+            {"dayStr": "20210905", "type": "1"},
+            {"dayStr": "20210906", "type": "0"},
+            {"dayStr": "20210907", "type": "0"},
+            {"dayStr": "20210908", "type": "0"},
+            {"dayStr": "20210909", "type": "0"},
+            {"dayStr": "20210910", "type": "0"},
+            {"dayStr": "20210911", "type": "1"},
+            {"dayStr": "20210912", "type": "1"},
+            {"dayStr": "20210913", "type": "0"},
+            {"dayStr": "20210914", "type": "0"},
+            {"dayStr": "20210915", "type": "0"},
+            {"dayStr": "20210916", "type": "0"},
+            {"dayStr": "20210917", "type": "0"},
+            {"dayStr": "20210918", "type": "0"},
+            {"dayStr": "20210919", "type": "2"},
+            {"dayStr": "20210920", "type": "2"},
+            {"dayStr": "20210921", "type": "2"},
+            {"dayStr": "20210922", "type": "0"},
+            {"dayStr": "20210923", "type": "0"},
+            {"dayStr": "20210924", "type": "0"},
+            {"dayStr": "20210925", "type": "1"},
+            {"dayStr": "20210926", "type": "0"},
+            {"dayStr": "20210927", "type": "0"},
+            {"dayStr": "20210928", "type": "0"},
+            {"dayStr": "20210929", "type": "0"},
+            {"dayStr": "20210930", "type": "0"},
+            {"dayStr": "20211001", "type": "2"},
+            {"dayStr": "20211002", "type": "2"},
+            {"dayStr": "20211003", "type": "2"},
+            {"dayStr": "20211004", "type": "2"},
+            {"dayStr": "20211005", "type": "2"},
+            {"dayStr": "20211006", "type": "2"},
+            {"dayStr": "20211007", "type": "2"},
+            {"dayStr": "20211008", "type": "0"},
+            {"dayStr": "20211009", "type": "0"},
+            {"dayStr": "20211010", "type": "1"},
+            {"dayStr": "20211011", "type": "0"},
+            {"dayStr": "20211012", "type": "0"},
+            {"dayStr": "20211013", "type": "0"},
+            {"dayStr": "20211014", "type": "0"},
+            {"dayStr": "20211015", "type": "0"},
+            {"dayStr": "20211016", "type": "1"},
+            {"dayStr": "20211017", "type": "1"},
+            {"dayStr": "20211018", "type": "0"},
+            {"dayStr": "20211019", "type": "0"},
+            {"dayStr": "20211020", "type": "0"},
+            {"dayStr": "20211021", "type": "0"},
+            {"dayStr": "20211022", "type": "0"},
+            {"dayStr": "20211023", "type": "1"},
+            {"dayStr": "20211024", "type": "1"},
+            {"dayStr": "20211025", "type": "0"},
+            {"dayStr": "20211026", "type": "0"},
+            {"dayStr": "20211027", "type": "0"},
+            {"dayStr": "20211028", "type": "0"},
+            {"dayStr": "20211029", "type": "0"},
+            {"dayStr": "20211030", "type": "1"},
+            {"dayStr": "20211031", "type": "1"},
+            {"dayStr": "20211101", "type": "0"},
+            {"dayStr": "20211102", "type": "0"},
+            {"dayStr": "20211103", "type": "0"},
+            {"dayStr": "20211104", "type": "0"},
+            {"dayStr": "20211105", "type": "0"},
+            {"dayStr": "20211106", "type": "1"},
+            {"dayStr": "20211107", "type": "1"},
+            {"dayStr": "20211108", "type": "0"},
+            {"dayStr": "20211109", "type": "0"},
+            {"dayStr": "20211110", "type": "0"},
+            {"dayStr": "20211111", "type": "0"},
+            {"dayStr": "20211112", "type": "0"},
+            {"dayStr": "20211113", "type": "1"},
+            {"dayStr": "20211114", "type": "1"},
+            {"dayStr": "20211115", "type": "0"},
+            {"dayStr": "20211116", "type": "0"},
+            {"dayStr": "20211117", "type": "0"},
+            {"dayStr": "20211118", "type": "0"},
+            {"dayStr": "20211119", "type": "0"},
+            {"dayStr": "20211120", "type": "1"},
+            {"dayStr": "20211121", "type": "1"},
+            {"dayStr": "20211122", "type": "0"},
+            {"dayStr": "20211123", "type": "0"},
+            {"dayStr": "20211124", "type": "0"},
+            {"dayStr": "20211125", "type": "0"},
+            {"dayStr": "20211126", "type": "0"},
+            {"dayStr": "20211127", "type": "1"},
+            {"dayStr": "20211128", "type": "1"},
+            {"dayStr": "20211129", "type": "0"},
+            {"dayStr": "20211130", "type": "0"},
+            {"dayStr": "20211201", "type": "0"},
+            {"dayStr": "20211202", "type": "0"},
+            {"dayStr": "20211203", "type": "0"},
+            {"dayStr": "20211204", "type": "1"},
+            {"dayStr": "20211205", "type": "1"},
+            {"dayStr": "20211206", "type": "0"},
+            {"dayStr": "20211207", "type": "0"},
+            {"dayStr": "20211208", "type": "0"},
+            {"dayStr": "20211209", "type": "0"},
+            {"dayStr": "20211210", "type": "0"},
+            {"dayStr": "20211211", "type": "1"},
+            {"dayStr": "20211212", "type": "1"},
+            {"dayStr": "20211213", "type": "0"},
+            {"dayStr": "20211214", "type": "0"},
+            {"dayStr": "20211215", "type": "0"},
+            {"dayStr": "20211216", "type": "0"},
+            {"dayStr": "20211217", "type": "0"},
+            {"dayStr": "20211218", "type": "1"},
+            {"dayStr": "20211219", "type": "1"},
+            {"dayStr": "20211220", "type": "0"},
+            {"dayStr": "20211221", "type": "0"},
+            {"dayStr": "20211222", "type": "0"},
+            {"dayStr": "20211223", "type": "0"},
+            {"dayStr": "20211224", "type": "0"},
+            {"dayStr": "20211225", "type": "1"},
+            {"dayStr": "20211226", "type": "1"},
+            {"dayStr": "20211227", "type": "0"},
+            {"dayStr": "20211228", "type": "0"},
+            {"dayStr": "20211229", "type": "0"},
+            {"dayStr": "20211230", "type": "0"},
+            {"dayStr": "20211231", "type": "0"}
         ]
         ]
 
 
-        srt=[{"dayStr": h, "type": "该日期不支持,只支持2020年"}]
+        srt = [{"dayStr": h, "type": "该日期不支持,只支持2021年"}]
         for i in day:
         for i in day:
-            if i['dayStr']==h:
+            if i['dayStr'] == h:
                 print(i)
                 print(i)
-                srt=i
+                srt = i
         print(h)
         print(h)
 
 
-        return response.json(0,srt)
+        return response.json(0, srt)

+ 553 - 188
Controller/DetectController.py

@@ -21,15 +21,17 @@ from django.http import JsonResponse
 from django.views.generic.base import View
 from django.views.generic.base import View
 from pyfcm import FCMNotification
 from pyfcm import FCMNotification
 from Object.RedisObject import RedisObject
 from Object.RedisObject import RedisObject
-from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, DETECT_PUSH_DOMAIN, JPUSH_CONFIG, \
-    FCM_CONFIG, APNS_CONFIG, BASE_DIR, APNS_MODE
-from Model.models import Device_Info, VodHlsModel, Equipment_Info, UidSetModel, UidPushModel
+from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, DETECT_PUSH_DOMAIN,\
+                            JPUSH_CONFIG, FCM_CONFIG, APNS_CONFIG, \
+                            BASE_DIR, APNS_MODE,  SERVER_TYPE
+from Model.models import Device_Info, VodHlsModel, Equipment_Info, UidSetModel, UidPushModel, SysMsgModel
 from Object.ETkObject import ETkObject
 from Object.ETkObject import ETkObject
 from Object.RedisObject import RedisObject
 from Object.RedisObject import RedisObject
 from Object.ResponseObject import ResponseObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Object.TokenObject import TokenObject
 from Object.UidTokenObject import UidTokenObject
 from Object.UidTokenObject import UidTokenObject
 from Service.CommonService import CommonService
 from Service.CommonService import CommonService
+from Service.ModelService import ModelService
 
 
 '''
 '''
 http://test.push.dvema.com/notify/push?uidToken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiJUNEFaM0NVS0NFUkg5RlpBMTExQSJ9.GtrXeq5gb2Z9M3mKECxi9eNQbPxqC-6PtgJkOOg6PwI&n_time=1598456451&channel=1&event_type=1&is_st=1
 http://test.push.dvema.com/notify/push?uidToken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiJUNEFaM0NVS0NFUkg5RlpBMTExQSJ9.GtrXeq5gb2Z9M3mKECxi9eNQbPxqC-6PtgJkOOg6PwI&n_time=1598456451&channel=1&event_type=1&is_st=1
@@ -330,34 +332,38 @@ class DetectControllerView(View):
             return response.json(0)
             return response.json(0)
 
 
 
 
-# http://192.168.136.40:8077/notify/push?uidToken=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1aWQiOiJUTjdNUEUzMjExVUU3NkFQMTExQSJ9.k501567VdnhFpn_ygzGRDat3Kqlz5CsEA9jAC2dDk_g&obj=12341234&n_time=1234561234
-# http://test.dvema.com/notify/push?uidToken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiJQMldOR0pSRDJFSEE1RVU5MTExQSJ9.xOCI5lerk8JOs5OcAzunrKCfCrtuPIZ3AnkMmnd-bPY&n_time=1526845794&channel=1&event_type=51&is_st=0
+
+'''
+http://push.dvema.com/notify/push?etk=Y2lTRXhMTjBWS01sWlpURTVJU0ZWTlJ6RXhNVUU9T3o=&n_time=1526845794&channel=1&event_type=704&is_st=0
+http://push.dvema.com/deviceShadow/generateUTK?username=debug_user&password=debug_password&uid=VVDHCVBYDKFMJRWA111A
+'''
+
+
 # 移动侦测接口
 # 移动侦测接口
 class NotificationView(View):
 class NotificationView(View):
 
 
     def get(self, request, *args, **kwargs):
     def get(self, request, *args, **kwargs):
         request.encoding = 'utf-8'
         request.encoding = 'utf-8'
-        # operation = kwargs.get('operation')
         return self.validation(request.GET)
         return self.validation(request.GET)
 
 
     def post(self, request, *args, **kwargs):
     def post(self, request, *args, **kwargs):
         request.encoding = 'utf-8'
         request.encoding = 'utf-8'
-        # operation = kwargs.get('operation')
         return self.validation(request.POST)
         return self.validation(request.POST)
 
 
     def validation(self, request_dict):
     def validation(self, request_dict):
-        response = ResponseObject()
+
         uidToken = request_dict.get('uidToken', None)
         uidToken = request_dict.get('uidToken', None)
         etk = request_dict.get('etk', None)
         etk = request_dict.get('etk', None)
         channel = request_dict.get('channel', '1')
         channel = request_dict.get('channel', '1')
         n_time = request_dict.get('n_time', None)
         n_time = request_dict.get('n_time', None)
         event_type = request_dict.get('event_type', None)
         event_type = request_dict.get('event_type', None)
         is_st = request_dict.get('is_st', None)
         is_st = request_dict.get('is_st', None)
+        # print("aaa")
+        # return JsonResponse(0,safe=False)
         if not all([channel, n_time]):
         if not all([channel, n_time]):
             return JsonResponse(status=200, data={
             return JsonResponse(status=200, data={
                 'code': 444,
                 'code': 444,
                 'msg': 'param is wrong'})
                 'msg': 'param is wrong'})
-            # return response.json(444)
         if etk:
         if etk:
             eto = ETkObject(etk)
             eto = ETkObject(etk)
             uid = eto.uid
             uid = eto.uid
@@ -366,20 +372,440 @@ class NotificationView(View):
         else:
         else:
             utko = UidTokenObject(uidToken)
             utko = UidTokenObject(uidToken)
             uid = utko.UID
             uid = utko.UID
-        # utko = UidTokenObject(uidToken)
-        # uid = utko.UID
-        detect_group = UidSetModel.objects.filter(uid=uid). \
-            values('detect_group')
-        event_type = detect_group
-        # 新增 移动侦测
-        if event_type == '0':
-            self.detect_group_push(self, request_dict, uid, response, channel, n_time, event_type, is_st)
-        # 新增 pir侦测
-        if event_type == '1':
-            self.detect_group_push(self, request_dict, uid, response, channel, n_time, event_type, is_st)
-        # 新增 移动侦测和pir侦测
-        if event_type == '01':
-            self.detect_group_push(self, request_dict, uid, response, channel, n_time, event_type, is_st)
+
+        pkey = '{uid}_{channel}_{event_type}_ptl'.format(uid=uid, event_type=event_type, channel=channel)
+        # ykey = 'MUJ887NLR8K8GBM9111A_redis_qs'.format(uid=uid)
+        ykey = '{uid}_redis_qs'.format(uid=uid)
+        # dkey = '{uid}_{channel}_{event_type}_flag'.format(uid=uid, event_type=event_type, channel=channel)
+        is_sys_msg = self.is_sys_msg(int(event_type))
+        if is_sys_msg is True:
+            dkey = '{uid}_{channel}_{event_type}_flag'.format(uid=uid, event_type=event_type, channel=channel)
+        else:
+            dkey = '{uid}_{channel}_flag'.format(uid=uid, channel=channel)
+
+        # 判断redisObj.get_data(key=pkey):不为空
+        redisObj = RedisObject(db=6)
+        have_ykey = redisObj.get_data(key=ykey)  # uid_set 数据库缓存
+        have_pkey = redisObj.get_data(key=pkey)  # 一分钟限制key
+        have_dkey = redisObj.get_data(key=dkey)  # 推送类型限制
+
+        # 一分钟外,推送开启状态
+        detect_med_type = 0  # 0推送旧机制 1存库不推送,2推送存库
+        # 暂时注销
+        if have_pkey:
+            if SERVER_TYPE != "Ansjer.formal_settings":
+                res_data = {'code': 0, 'msg': 'Push once every 10 seconds'}
+            else:
+                res_data = {'code': 0, 'msg': 'Push it once a minute'}
+
+            return JsonResponse(status=200, data=res_data)
+
+        # 数据库读取数据
+        if have_ykey:
+            redis_list = eval(redisObj.get_data(key=ykey))
+            print(have_ykey)
+        else:
+            # 从数据库查询出来
+            uid_push_qs = UidPushModel.objects.filter(uid_set__uid=uid,uid_set__detect_status=1). \
+                values('token_val', 'app_type', 'appBundleId','m_code',
+                       'push_type', 'userID_id', 'userID__NickName',
+                       'lang', 'm_code', 'tz', 'uid_set__nickname', 'uid_set__detect_interval', 'uid_set__detect_group',
+                       'uid_set__channel')
+            print(uid_push_qs)
+            # 新建一个list接收数据
+            redis_list = []
+            # 把数据库数据追加进redis_list
+            for qs in uid_push_qs:
+                redis_list.append(qs)
+            # 修改redis数据,并设置过期时间为10分钟
+            redisObj.set_data(key=ykey, val=str(redis_list), expire=600)
+            if not redis_list:
+                res_data = {'code': 404, 'msg': 'error !'}
+                return JsonResponse(status=200, data=res_data)
+
+            # 此时应该更新一下redis里面的dkey的有效时间
+            # detect_interval = redis_list[0]['uid_set__detect_interval']
+            # tmp_channel = redis_list[0]['uid_set__channel']
+            # self.do_update_detect_interval(uid, tmp_channel, redisObj, detect_interval)
+
+        if not redis_list:
+            print("没有redi_list")
+            res_data = {'code': 0, 'msg': 'no redi_list success!'}
+            return JsonResponse(status=200, data=res_data)
+
+        # is_sys_msg = self.is_sys_msg(int(event_type))
+        nickname = redis_list[0]['uid_set__nickname']
+        detect_interval = redis_list[0]['uid_set__detect_interval']
+        detect_group = redis_list[0]['uid_set__detect_group']
+        now_time = int(time.time())
+        if not nickname:
+            nickname = uid
+
+        if detect_group is not None:
+            if have_dkey:
+                detect_med_type = 1  # 1为存库不推送
+            else:
+                detect_med_type = 2  # 为2的话,既推送,又存库
+                # detect_group=0允许全部推送的时候
+                if detect_group == '0'or detect_group == '':
+                    redisObj.set_data(key=dkey, val=1, expire=detect_interval)
+                else:
+                    detect_group_list = detect_group.split(',')
+                    if event_type in detect_group_list:
+                        if detect_interval < 60:
+                            detect_interval = 60
+                        redisObj.set_data(key=dkey, val=1, expire=detect_interval)
+                # 改为1秒
+                # 如果不是正式
+                if SERVER_TYPE!="Ansjer.formal_settings":
+                    redisObj.set_data(key=pkey, val=1, expire=10)
+                else:
+                    redisObj.set_data(key=pkey, val=1, expire=60)
+
+            # 打印have_ykey
+        # return JsonResponse(status=200, data={'pkey': 0, 'have_ykey': have_ykey, 'have_pkey': have_pkey, 'have_ykey': have_dkey})
+
+        # 旧模式并且没有pkey,重新创建一个
+        if not detect_group and not have_pkey:
+            # 设置推送时间为60秒一次
+            # 如果不是正式
+            if SERVER_TYPE != "Ansjer.formal_settings":
+                redisObj.set_data(key=pkey, val=1, expire=10)
+            else:
+                redisObj.set_data(key=pkey, val=1, expire=60)
+        auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
+        bucket = oss2.Bucket(auth, 'oss-cn-shenzhen.aliyuncs.com', 'apg')
+        kwag_args = {
+            'uid': uid,
+            'channel': channel,
+            'event_type': event_type,
+            'n_time': n_time,
+            # 'appBundleId': appBundleId,
+            # 'token_val': token_val,
+            # 'msg_title': msg_title,
+            # 'msg_text': msg_text
+        }
+        eq_list = []
+        sys_msg_list = []
+        userID_ids = []
+        do_apns_code = ''
+        do_fcm_code = ''
+        do_jpush_code = ''
+        for up in redis_list:
+            push_type = up['push_type']
+            appBundleId = up['appBundleId']
+            token_val = up['token_val']
+            lang = up['lang']
+            tz = up['tz']
+            if tz is None or tz == '':
+                tz = 0
+            # 发送标题
+            msg_title = self.get_msg_title(appBundleId=appBundleId, nickname=nickname)
+            # 发送内容
+            msg_text = self.get_msg_text(channel=channel, n_time=n_time, lang=lang, tz=tz,
+                                         event_type=event_type)
+            kwag_args['appBundleId'] = appBundleId
+            kwag_args['token_val'] = token_val
+            kwag_args['msg_title'] = msg_title
+            kwag_args['msg_text'] = msg_text
+            push_server_status = 0
+            #推送
+            if detect_med_type == 2 or detect_med_type == 0:
+                if push_type == 0:  # ios apns
+                    print('do_apns')
+                    # self.do_apns(**kwag_args)
+                    do_apns_code = self.do_apns(**kwag_args)
+                    if isinstance(do_apns_code, int):
+                        push_server_status = do_apns_code
+                    else:
+                        push_server_status = 400
+                elif push_type == 1:  # android gcm
+                    print('do_fcm')
+                    do_fcm_code = self.do_fcm(**kwag_args)
+                    push_server_status = 200
+                elif push_type == 2:  # android jpush
+                    print('do_jpush')
+                    do_jpush_code = self.do_jpush(**kwag_args)
+                    push_server_status = do_jpush_code
+                    # return JsonResponse(status=200, data={'code': 0, '状态:': self.do_jpush(**kwag_args)})
+            if detect_med_type == 1:
+                do_apns_code = '只存库不推送'
+                do_fcm_code = '只存库不推送'
+                do_jpush_code = '只存库不推送'
+            # 以下是存库
+            userID_id = up["userID_id"]
+            int_is_st = int(is_st)
+            if userID_id not in userID_ids:
+                eq_list.append(Equipment_Info(
+                    userID_id=userID_id,
+                    eventTime=n_time,
+                    eventType=event_type,
+                    devUid=uid,
+                    devNickName=nickname,
+                    Channel=channel,
+                    alarm='Motion \tChannel:{channel}'.format(channel=channel),
+                    is_st=int_is_st,
+                    receiveTime=n_time,
+                    addTime=now_time,
+                    storage_location=1
+                ))
+                if is_sys_msg:
+                    sys_msg_text = self.get_msg_text(channel=channel, n_time=n_time, lang=lang, tz=tz,
+                                                     event_type=event_type, is_sys=1)
+                    sys_msg_list.append(SysMsgModel(
+                        userID_id=userID_id,
+                        msg=sys_msg_text,
+                        addTime=now_time,
+                        updTime=now_time,
+                        uid=uid,
+                        eventType=event_type))
+                userID_ids.append(userID_id)
+        if is_sys_msg:
+            SysMsgModel.objects.bulk_create(sys_msg_list)
+        Equipment_Info.objects.bulk_create(eq_list)
+        if is_st == '0' or is_st == '2':
+            print("is_st=0or2")
+            for up in redis_list:
+                if up['push_type'] == 0:  # ios apns
+                    up['do_apns_code'] = do_apns_code
+                elif up['push_type'] == 1:  # android gcm
+                    up['do_fcm_code'] = do_fcm_code
+                elif up['push_type'] == 2:  # android jpush
+                    up['do_jpush_code'] = do_jpush_code
+                up['test_or_www'] = SERVER_TYPE
+                del up['push_type']
+                del up['userID_id']
+                del up['userID__NickName']
+                del up['lang']
+                del up['tz']
+                del up['uid_set__nickname']
+                del up['uid_set__detect_interval']
+                del up['uid_set__detect_group']
+            return JsonResponse(status=200, data={'code': 0, 'msg': 'success 0 or 2' ,'re_list':redis_list})
+
+        elif is_st == '1':
+            print("is_st=1")
+            # Endpoint以杭州为例,其它Region请按实际情况填写。
+            obj = '{uid}/{channel}/{filename}.jpeg'.format(uid=uid, channel=channel, filename=n_time)
+            # 设置此签名URL在60秒内有效。
+            url = bucket.sign_url('PUT', obj, 7200)
+            for up in redis_list:
+                up['do_apns_code'] = do_apns_code
+                up['do_fcm_code'] = do_fcm_code
+                up['do_jpush_code'] = do_jpush_code
+                up['test_or_www'] = SERVER_TYPE
+                del up['push_type']
+                del up['userID_id']
+                del up['userID__NickName']
+                del up['lang']
+                del up['tz']
+                del up['uid_set__nickname']
+                del up['uid_set__detect_interval']
+                del up['uid_set__detect_group']
+                # 不是正式服务器
+            if SERVER_TYPE != "Ansjer.formal_settings":
+                res_data = {'code': 0, 'img_push': url, 'msg': 'success', 're_list': redis_list}
+            else:
+                # 是正式服务器的时候
+                res_data = {'code': 0, 'img_push': url, 'msg': 'success'}
+            return JsonResponse(status=200, data=res_data)
+
+        elif is_st == '3':
+            print("is_st=3")
+            # 人形检测带动图
+            # Endpoint以杭州为例,其它Region请按实际情况填写。
+            img_url_list = []
+            for i in range(int(is_st)):
+                obj = '{uid}/{channel}/{filename}_{st}.jpeg'. \
+                    format(uid=uid, channel=channel, filename=n_time, st=i)
+                # 设置此签名URL在60秒内有效。
+                url = bucket.sign_url('PUT', obj, 7200)
+                img_url_list.append(url)
+
+            for up in redis_list:
+                up['do_apns_code'] = do_apns_code
+                up['do_fcm_code'] = do_fcm_code
+                up['do_jpush_code'] = do_jpush_code
+                up['test_or_www'] = SERVER_TYPE
+                del up['push_type']
+                del up['userID_id']
+                del up['userID__NickName']
+                del up['lang']
+                del up['tz']
+                del up['uid_set__nickname']
+                del up['uid_set__detect_interval']
+                del up['uid_set__detect_group']
+
+            # 不是正式服务器
+            if SERVER_TYPE != "Ansjer.formal_settings":
+                res_data = {'code': 0, 'img_url_list': img_url_list, 'msg': 'success 3', 're_list': redis_list}
+            else:
+                # 是正式服务器的时候
+                res_data = {'code': 0, 'img_url_list': img_url_list, 'msg': 'success 3'}
+            return JsonResponse(status=200, data=res_data)
+
+
+    def get_msg_title(self, appBundleId, nickname):
+        package_title_config = {
+            'com.ansjer.customizedd_a': 'DVS',
+            'com.ansjer.zccloud_a': 'ZosiSmart',
+            'com.ansjer.zccloud_ab': '周视',
+            'com.ansjer.adcloud_a': 'ADCloud',
+            'com.ansjer.adcloud_ab': 'ADCloud',
+            'com.ansjer.accloud_a': 'ACCloud',
+            'com.ansjer.loocamccloud_a': 'Loocam',
+            'com.ansjer.loocamdcloud_a': 'Anlapus',
+            'com.ansjer.customizedb_a': 'COCOONHD',
+            'com.ansjer.customizeda_a': 'Guardian365',
+            'com.ansjer.customizedc_a': 'PatrolSecure',
+        }
+        if appBundleId in package_title_config.keys():
+            return package_title_config[appBundleId] + '(' + nickname + ')'
+        else:
+            return nickname
+
+    def is_sys_msg(self, event_type):
+        event_type_list = [702, 703, 704]
+        if event_type in event_type_list:
+            return True
+        return False
+
+    def get_msg_text(self, channel, n_time, lang, tz, event_type, is_sys=0):
+        n_date = CommonService.get_now_time_str(n_time=n_time, tz=tz,lang=lang)
+        etype = int(event_type)
+        if lang == 'cn':
+            if etype == 704:
+                msg_type = '电量过低'
+            elif etype == 702:
+                msg_type = '摄像头休眠'
+            elif etype == 703:
+                msg_type = '摄像头唤醒'
+            else:
+                msg_type = ''
+            if is_sys:
+                send_text = '{msg_type} 通道:{channel}'.format(msg_type=msg_type, channel=channel)
+            else:
+                send_text = '{msg_type} 通道:{channel} 日期:{date}'.format(msg_type=msg_type, channel=channel, date=n_date)
+                # send_text = '{msg_type} 通道:{channel} 日期:{date}'.format(msg_type=msg_type, channel=channel, date=n_date)
+        else:
+            if etype == 704:
+                msg_type = 'Low battery'
+            elif etype == 702:
+                msg_type = 'Camera sleep'
+            elif etype == 703:
+                msg_type = 'Camera wake'
+            else:
+                msg_type = ''
+            if is_sys:
+                send_text = '{msg_type} channel:{channel}'. \
+                    format(msg_type=msg_type, channel=channel)
+            else:
+                send_text = '{msg_type} channel:{channel} date:{date}'. \
+                    format(msg_type=msg_type, channel=channel, date=n_date)
+        return send_text
+
+    def do_jpush(self, uid, channel, appBundleId, token_val, event_type, n_time,
+                 msg_title, msg_text):
+        app_key = JPUSH_CONFIG[appBundleId]['Key']
+        master_secret = JPUSH_CONFIG[appBundleId]['Secret']
+        # 此处换成各自的app_key和master_secre
+        _jpush = jpush.JPush(app_key, master_secret)
+        push = _jpush.create_push()
+        # if you set the logging level to "DEBUG",it will show the debug logging.
+        # _jpush.set_logging("DEBUG")
+        # push.audience = jpush.all_
+        push.audience = jpush.registration_id(token_val)
+        push_data = {"alert": "Motion ", "event_time": n_time, "event_type": event_type, "msg": "",
+                     "received_at": n_time, "sound": "sound.aif", "uid": uid, "zpush": "1", "channel": channel}
+        android = jpush.android(alert=msg_text, priority=1, style=1, alert_type=7,
+                                big_text=msg_text, title=msg_title,
+                                extras=push_data)
+        push.notification = jpush.notification(android=android)
+        push.platform = jpush.all_
+        res = push.send()
+        print(res)
+        return res.status_code
+        # try:
+        #     res = push.send()
+        #     print(res)
+        # except Exception as e:
+        #     print("jpush fail")
+        #     print("Exception")
+        #     print(repr(e))
+        #     return
+        # else:
+        #     print("jpush success")
+        #     return
+
+    def do_fcm(self, uid, channel, appBundleId, token_val, event_type, n_time, msg_title, msg_text):
+        try:
+            serverKey = FCM_CONFIG[appBundleId]
+        except Exception as e:
+            return 'serverKey abnormal'
+        push_service = FCMNotification(api_key=serverKey)
+        data = {"alert": "Motion ", "event_time": n_time, "event_type": event_type, "msg": "",
+                "received_at": n_time, "sound": "sound.aif", "uid": uid, "zpush": "1", "channel": channel}
+        result = push_service.notify_single_device(registration_id=token_val, message_title=msg_title,
+                                                   message_body=msg_text, data_message=data,
+                                                   extra_kwargs={
+                                                       'default_vibrate_timings': True,
+                                                       'default_sound': True,
+                                                       'default_light_settings': True
+                                                   })
+        print('fcm push ing')
+        print(result)
+        return result
+
+    def do_apns(self, uid, channel, appBundleId, token_val, event_type, n_time, msg_title,
+                msg_text):
+        try:
+            cli = apns2.APNSClient(mode=APNS_MODE,
+                                   client_cert=os.path.join(BASE_DIR, APNS_CONFIG[appBundleId]['pem_path']))
+
+            push_data = {"alert": "Motion ", "event_time": n_time, "event_type": event_type, "msg": "",
+                         "received_at": n_time, "sound": "sound.aif", "uid": uid, "zpush": "1", "channel": channel}
+            alert = apns2.PayloadAlert(body=msg_text, title=msg_title)
+            payload = apns2.Payload(alert=alert, custom=push_data)
+
+            # return uid, channel, appBundleId, str(token_val), event_type, n_time, msg_title,msg_text
+            n = apns2.Notification(payload=payload, priority=apns2.PRIORITY_LOW)
+            res = cli.push(n=n, device_token=token_val, topic=appBundleId)
+            print(res.status_code)
+
+            #     200, 推送成功。
+            #   400, 请求有问题。
+            #   403, 证书或Token有问题。
+            #   405, 请求方式不正确, 只支持POST请求
+            #   410, 设备的Token与证书不一致
+            if res.status_code == 200:
+                return res.status_code
+            else:
+                print('apns push fail')
+                print(res.reason)
+                return res.status_code
+        except (ValueError, ArithmeticError):
+            return 'The program has a numeric format exception, one of the arithmetic exceptions'
+        except Exception as e:
+            print(repr(e))
+            return repr(e)
+
+    def do_update_detect_interval(self, uid, channel, redisObject, detect_interval):
+        if channel == 0:
+            channel = 17
+        else:
+            channel += 1
+        for i in range(1, channel):
+            tmpDKey = '{uid}_{channel}_{event_type}_flag'.format(uid=uid, event_type=51, channel=i)
+            if tmpDKey is not False:
+                llt = redisObject.get_ttl(tmpDKey)
+                if llt > detect_interval:
+                    redisObject.set_data(key=tmpDKey, val=1, expire=detect_interval)
+
+            tmpDKey = '{uid}_{channel}_{event_type}_flag'.format(uid=uid, event_type=54, channel=i)
+            if tmpDKey is not False:
+                llt = redisObject.get_ttl(tmpDKey)
+                if llt > detect_interval:
+                    redisObject.set_data(key=tmpDKey, val=1, expire=detect_interval)
 
 
     # 新增 把代码封装以便后面分侦测类型
     # 新增 把代码封装以便后面分侦测类型
     def detect_group_push(self, request_dict, uid, response, channel, n_time, event_type, is_st):
     def detect_group_push(self, request_dict, uid, response, channel, n_time, event_type, is_st):
@@ -441,136 +867,6 @@ class NotificationView(View):
         else:
         else:
             return JsonResponse(status=200, data={'code': 404, 'msg': 'data is not exist'})
             return JsonResponse(status=200, data={'code': 404, 'msg': 'data is not exist'})
 
 
-    def do_jpush(self, request_dict, uaql, response, uid, channel, nickname):
-        event_type = request_dict.get('event_type', None)
-        n_time = request_dict.get('n_time', None)
-        appBundleId = uaql['appBundleId']
-        token_val = uaql['token_val']
-        lang = uaql['lang']
-        tz = uaql['tz']
-        response = ResponseObject()
-        app_key = JPUSH_CONFIG[appBundleId]['Key']
-        master_secret = JPUSH_CONFIG[appBundleId]['Secret']
-        # 此处换成各自的app_key和master_secre
-        _jpush = jpush.JPush(app_key, master_secret)
-        push = _jpush.create_push()
-        # if you set the logging level to "DEBUG",it will show the debug logging.
-        _jpush.set_logging("DEBUG")
-        # push.audience = jpush.all_
-        push.audience = jpush.registration_id(token_val)
-        push_data = {"alert": "Motion ", "event_time": n_time, "event_type": event_type, "msg": "",
-                     "received_at": n_time, "sound": "sound.aif", "uid": uid, "zpush": "1", "channel": channel}
-        message_title = self.get_message_title(appBundleId=appBundleId, nickname=nickname)
-        send_text = self.get_send_text(channel=channel, n_time=n_time, lang=lang, tz=tz, event_type=event_type)
-        android = jpush.android(alert=send_text, priority=1, style=1, alert_type=7,
-                                big_text=send_text, title=message_title,
-                                extras=push_data)
-
-        push.notification = jpush.notification(android=android)
-
-        push.platform = jpush.all_
-        try:
-            res = push.send()
-            print(res)
-        except Exception as e:
-            print("Exception")
-            print(repr(e))
-            return response.json(10, repr(e))
-        else:
-            return response.json(0)
-
-    def get_message_title(self, appBundleId, nickname):
-        package_title_config = {
-            'com.ansjer.customizedd_a': 'DVS',
-            'com.ansjer.zccloud_a': 'ZosiSmart',
-            'com.ansjer.zccloud_ab': '周视',
-            'com.ansjer.adcloud_a': 'ADCloud',
-            'com.ansjer.adcloud_ab': 'ADCloud',
-            'com.ansjer.accloud_a': 'ACCloud',
-            'com.ansjer.loocamccloud_a': 'Loocam',
-            'com.ansjer.loocamdcloud_a': 'Anlapus',
-            'com.ansjer.customizedb_a': 'COCOONHD',
-            'com.ansjer.customizeda_a': 'Guardian365',
-            'com.ansjer.customizedc_a': 'PatrolSecure',
-        }
-        if appBundleId in package_title_config.keys():
-            return package_title_config[appBundleId] + '(' + nickname + ')'
-        else:
-            return nickname
-
-    def get_send_text(self, channel, n_time, lang, tz, event_type):
-        n_date = CommonService.get_now_time_str(n_time=n_time, tz=tz)
-        msg_type = ''
-        if int(event_type) == 704:
-            msg_type = 'battery is too low'
-            if lang == 'cn':
-                msg_type = '电池电量过低'
-        send_text = '{msg_type}channel:{channel} date:{date}'.format(msg_type=msg_type, channel=channel, date=n_date)
-        if lang == 'cn':
-            send_text = '{msg_type}通道:{channel} 日期:{date}'.format(msg_type=msg_type, channel=channel, date=n_date)
-        return send_text
-
-    def do_fcm(self, request_dict, uaql, response, uid, channel, nickname):
-        n_time = request_dict.get('n_time')
-        appBundleId = uaql['appBundleId']
-        token_val = uaql['token_val']
-        lang = uaql['lang']
-        tz = uaql['tz']
-        try:
-            serverKey = FCM_CONFIG[appBundleId]
-        except Exception as e:
-            return response.json(404)
-        event_type = request_dict.get('event_type', None)
-        push_service = FCMNotification(api_key=serverKey)
-        registration_id = token_val
-        message_title = self.get_message_title(appBundleId=appBundleId, nickname=nickname)
-        send_text = self.get_send_text(channel=channel, n_time=n_time, lang=lang, tz=tz, event_type=event_type)
-        data = {"alert": "Motion ", "event_time": n_time, "event_type": event_type, "msg": "",
-                "received_at": n_time, "sound": "sound.aif", "uid": uid, "zpush": "1", "channel": channel}
-        result = push_service.notify_single_device(registration_id=registration_id, message_title=message_title,
-                                                   message_body=send_text, data_message=data,
-                                                   extra_kwargs={
-                                                       'default_vibrate_timings': True,
-                                                       'default_sound': True,
-                                                       'default_light_settings': True
-                                                   })
-        response = ResponseObject()
-        return response.json(0, result)
-
-    def do_apns(self, request_dict, uaql, response, uid, channel, nickname):
-        event_type = request_dict.get('event_type', None)
-        token_val = uaql['token_val']
-        lang = uaql['lang']
-        n_time = request_dict.get('n_time')
-        appBundleId = uaql['appBundleId']
-        tz = uaql['tz']
-        message_title = self.get_message_title(appBundleId=appBundleId, nickname=nickname)
-        send_text = self.get_send_text(channel=channel, n_time=n_time, lang=lang, tz=tz, event_type=event_type)
-        try:
-            print('---')
-
-            cli = apns2.APNSClient(mode=APNS_MODE,
-                                   client_cert=os.path.join(BASE_DIR, APNS_CONFIG[appBundleId]['pem_path']))
-            # password=APNS_CONFIG[appBundleId]['password'])
-            push_data = {"alert": "Motion ", "event_time": n_time, "event_type": event_type, "msg": "",
-                         "received_at": n_time, "sound": "sound.aif", "uid": uid, "zpush": "1", "channel": channel}
-            # body = json.dumps(push_data)
-            alert = apns2.PayloadAlert(body=send_text, title=message_title)
-            payload = apns2.Payload(alert=alert, custom=push_data)
-            n = apns2.Notification(payload=payload, priority=apns2.PRIORITY_LOW)
-            res = cli.push(n=n, device_token=token_val, topic=appBundleId)
-            # assert res.status_code == 200, res.reason
-            # assert res.apns_id
-            print('========')
-            print(res.status_code)
-            if res.status_code == 200:
-                return response.json(0)
-            else:
-                return response.json(404, res.reason)
-        except Exception as e:
-            print(repr(e))
-            return response.json(10, repr(e))
-
     def do_bulk_create_info(self, uaqs, n_time, channel, event_type, is_st, uid):
     def do_bulk_create_info(self, uaqs, n_time, channel, event_type, is_st, uid):
         #
         #
         qs_list = []
         qs_list = []
@@ -632,21 +928,38 @@ class PushNotificationView(View):
             redisObj = RedisObject(db=6)
             redisObj = RedisObject(db=6)
             # pkey = '{uid}_{channel}_ptl'.format(uid=uid, channel=channel)
             # pkey = '{uid}_{channel}_ptl'.format(uid=uid, channel=channel)
             pkey = '{uid}_ptl'.format(uid=uid)
             pkey = '{uid}_ptl'.format(uid=uid)
-            # 推送时间限制
+            ykey = '{uid}_redis_qs'.format(uid=uid)
             if redisObj.get_data(key=pkey):
             if redisObj.get_data(key=pkey):
-                res_data = {'code': 0, 'msg': 'success,!'}
+                res_data = {'code': 0, 'msg': 'success,!33333333333'}
                 return JsonResponse(status=200, data=res_data)
                 return JsonResponse(status=200, data=res_data)
             else:
             else:
                 redisObj.set_data(key=pkey, val=1, expire=60)
                 redisObj.set_data(key=pkey, val=1, expire=60)
-            uid_push_qs = UidPushModel.objects.filter(uid_set__uid=uid, uid_set__detect_status=1). \
-                values('token_val', 'app_type', 'appBundleId', 'push_type', 'userID_id', 'userID__NickName', 'lang',
-                       'tz', 'uid_set__nickname')
-            if uid_push_qs.exists():
+            ##############
+            redis_data = redisObj.get_data(key=ykey)
+            if redis_data:
+                redis_list = eval(redis_data)
+            else:
+                # 设置推送时间为60秒一次
+                redisObj.set_data(key=pkey, val=1, expire=60)
+                print("从数据库查到数据")
+                # 从数据库查询出来
+                uid_push_qs = UidPushModel.objects.filter(uid_set__uid=uid, uid_set__detect_status=1). \
+                    values('token_val', 'app_type', 'appBundleId',
+                           'push_type', 'userID_id', 'lang','m_code',
+                           'tz', 'uid_set__nickname')
+                # 新建一个list接收数据
+                redis_list = []
+                # 把数据库数据追加进redis_list
+                for qs in uid_push_qs:
+                    redis_list.append(qs)
+                # 修改redis数据,并设置过期时间为10分钟
+            if redis_list:
+                redisObj.set_data(key=ykey, val=str(redis_list), expire=600)
                 auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
                 auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
                 bucket = oss2.Bucket(auth, 'oss-cn-shenzhen.aliyuncs.com', 'apg')
                 bucket = oss2.Bucket(auth, 'oss-cn-shenzhen.aliyuncs.com', 'apg')
-                self.do_bulk_create_info(uid_push_qs, n_time, channel, event_type, is_st, uid)
+                self.do_bulk_create_info(redis_list, n_time, channel, event_type, is_st, uid)
                 if is_st == '0' or is_st == '2':
                 if is_st == '0' or is_st == '2':
-                    return JsonResponse(status=200, data={'code': 0, 'msg': 'success'})
+                    return JsonResponse(status=200, data={'code': 0, 'msg': 'success44444444444444444'})
                 elif is_st == '1':
                 elif is_st == '1':
                     # Endpoint以杭州为例,其它Region请按实际情况填写。
                     # Endpoint以杭州为例,其它Region请按实际情况填写。
                     obj = '{uid}/{channel}/{filename}.jpeg'.format(uid=uid, channel=channel, filename=n_time)
                     obj = '{uid}/{channel}/{filename}.jpeg'.format(uid=uid, channel=channel, filename=n_time)
@@ -671,35 +984,87 @@ class PushNotificationView(View):
             return JsonResponse(status=200, data={'code': 404, 'msg': 'wrong etk'})
             return JsonResponse(status=200, data={'code': 404, 'msg': 'wrong etk'})
 
 
     def do_bulk_create_info(self, uaqs, n_time, channel, event_type, is_st, uid):
     def do_bulk_create_info(self, uaqs, n_time, channel, event_type, is_st, uid):
-        #
-        qs_list = []
-        nowTime = int(time.time())
+        now_time = int(time.time())
         # 设备昵称
         # 设备昵称
         userID_ids = []
         userID_ids = []
-        for dv in uaqs:
-            userID_id = dv["userID_id"]
+        sys_msg_list = []
+        is_sys_msg = self.is_sys_msg(int(event_type))
+        is_st = int(is_st)
+        eq_list = []
+        nickname = uaqs[0]['uid_set__nickname']
+        if not nickname:
+            nickname = uid
+        for ua in uaqs:
+            lang = ua['lang']
+            tz = ua['tz']
+            userID_id = ua["userID_id"]
             if userID_id not in userID_ids:
             if userID_id not in userID_ids:
-                if dv['uid_set__nickname']:
-                    uid_nickname = dv['uid_set__nickname']
-                else:
-                    uid_nickname = uid
-                add_data = {
-                    'userID_id': dv["userID_id"],
-                    'eventTime': n_time,
-                    'eventType': event_type,
-                    'devUid': uid,
-                    'devNickName': uid_nickname,
-                    'Channel': channel,
-                    'alarm': 'Motion \tChannel:{channel}'.format(channel=channel),
-                    'is_st': int(is_st),
-                    'receiveTime': n_time,
-                    'addTime': nowTime
-                }
-                qs_list.append(Equipment_Info(**add_data))
-                userID_ids.append(userID_id)
-        if qs_list:
-            print(1)
-            Equipment_Info.objects.bulk_create(qs_list)
+                eq_list.append(Equipment_Info(
+                    userID_id=userID_id,
+                    eventTime=n_time,
+                    eventType=event_type,
+                    devUid=uid,
+                    devNickName=nickname,
+                    Channel=channel,
+                    alarm='Motion \tChannel:{channel}'.format(channel=channel),
+                    is_st=is_st,
+                    receiveTime=n_time,
+                    addTime=now_time,
+                    storage_location=1
+                ))
+                if is_sys_msg:
+                    sys_msg_text = self.get_msg_text(channel=channel, n_time=n_time, lang=lang, tz=tz,
+                                                     event_type=event_type, is_sys=1)
+                    sys_msg_list.append(SysMsgModel(
+                        userID_id=userID_id,
+                        msg=sys_msg_text,
+                        addTime=now_time,
+                        updTime=now_time,
+                        uid=uid,
+                        eventType=event_type))
+        if eq_list:
+            print('eq_list')
+            Equipment_Info.objects.bulk_create(eq_list)
+        if is_sys_msg:
+            print('sys_msg')
+            SysMsgModel.objects.bulk_create(sys_msg_list)
+        return True
+
+    def is_sys_msg(self, event_type):
+        event_type_list = [702, 703, 704]
+        if event_type in event_type_list:
             return True
             return True
+        return False
+
+    def get_msg_text(self, channel, n_time, lang, tz, event_type, is_sys=0):
+        n_date = CommonService.get_now_time_str(n_time=n_time, tz=tz)
+        etype = int(event_type)
+        if lang == 'cn':
+            if etype == 704:
+                msg_type = '电量过低'
+            elif etype == 702:
+                msg_type = '摄像头休眠'
+            elif etype == 703:
+                msg_type = '摄像头唤醒'
+            else:
+                msg_type = ''
+            if is_sys:
+                send_text = '{msg_type} 通道:{channel}'.format(msg_type=msg_type, channel=channel)
+            else:
+                send_text = '{msg_type} 通道:{channel} 日期:{date}'.format(msg_type=msg_type, channel=channel, date=n_date)
         else:
         else:
-            return False
+            if etype == 704:
+                msg_type = 'Low battery'
+            elif etype == 702:
+                msg_type = 'Camera sleep'
+            elif etype == 703:
+                msg_type = 'Camera wake'
+            else:
+                msg_type = ''
+            if is_sys:
+                send_text = '{msg_type} channel:{channel}'. \
+                    format(msg_type=msg_type, channel=channel)
+            else:
+                send_text = '{msg_type} channel:{channel} date:{date}'. \
+                    format(msg_type=msg_type, channel=channel, date=n_date)
+        return send_text

+ 1195 - 0
Controller/DetectControllerV2.py

@@ -0,0 +1,1195 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+"""
+@Copyright (C) ansjer cop Video Technology Co.,Ltd.All rights reserved.
+@AUTHOR: ASJRD018
+@NAME: AnsjerFormal
+@software: PyCharm
+@DATE: 2019/1/14 15:57
+@Version: python3.6
+@MODIFY DECORD:ansjer dev
+@file: DetectController.py
+@Contact: chanjunkai@163.com
+"""
+import os
+import time
+
+import apns2
+import jpush as jpush
+import oss2
+from django.http import JsonResponse
+from django.views.generic.base import View
+from pyfcm import FCMNotification
+from Object.RedisObject import RedisObject
+from Ansjer.config import DETECT_PUSH_DOMAIN, DETECT_PUSH_DOMAINS, DETECT_PUSH_DOMAIN_JIUAN, DETECT_PUSH_DOMAINS_JIUAN,\
+                            SERVER_DOMAIN, SERVER_DOMAIN_SSL, \
+                            OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, \
+                            JPUSH_CONFIG, FCM_CONFIG, APNS_CONFIG, BASE_DIR, APNS_MODE,  SERVER_TYPE
+from Model.models import Device_Info, VodHlsModel, Equipment_Info, UidSetModel, UidPushModel, CompanyModel, SysMsgModel
+from Object.ETkObject import ETkObject
+from Object.RedisObject import RedisObject
+from Object.ResponseObject import ResponseObject
+from Object.TokenObject import TokenObject
+from Object.UidTokenObject import UidTokenObject
+from Service.CommonService import CommonService
+from Service.ModelService import ModelService
+import boto3
+import botocore
+from botocore import client
+
+'''
+http://test.push.dvema.com/notify/push?uidToken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiJUNEFaM0NVS0NFUkg5RlpBMTExQSJ9.GtrXeq5gb2Z9M3mKECxi9eNQbPxqC-6PtgJkOOg6PwI&n_time=1598456451&channel=1&event_type=1&is_st=1
+http://push.dvema.com/notify/push?uidToken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiJUNEFaM0NVS0NFUkg5RlpBMTExQSJ9.GtrXeq5gb2Z9M3mKECxi9eNQbPxqC-6PtgJkOOg6PwI&n_time=1598456451&channel=1&event_type=1&is_st=1
+
+http://www.dvema.com/detect/changeStatus?push_type=2&token_val=1a0018970a332cca935&appBundleId=com.ansjer.zccloud_ab&tz=+08.00&uid=HLK7EJ2VYLNHHUMG111A&status=1&m_code=AN02000025070000001207.zccloud_ab&token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiMTMxMTk2NTc3MTMiLCJsYW5nIjoiZW4iLCJtX2NvZGUiOiIxMjM0MTMyNDMyMTQiLCJ1c2VySUQiOiIxNTQ0ODM4MjMyOTczMTM4MDAxMzgwMDAiLCJleHAiOjE1ODQxNDc0NjN9.NjK91B26jZDtdmq8tW-8hXNQPqqDfo9Zwf_Jg6Uf7co&lang=cn&app_type=2
+
+http://127.0.0.1:8077/detect/changeStatus?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VySUQiOiIxNTg0MzUxODk2MjgyMTM4MDAxMzgwMDAiLCJsYW5nIjoiZW4iLCJ1c2VyIjoiMTM2ODAzMTc1OTYiLCJtX2NvZGUiOiIxMjM0MTMyNDMyMTQiLCJleHAiOjE1ODcyNjEzODN9.H87931EDg6PGZK63EAsvY1FRJov9qo_S70mBKvpZeQM&push_type=2&token_val=token_val&appBundleId=appBundleId&tz=0&uid=158440619973313800138000&status=1&m_code&lang=cn&app_type=0&start_status=1&interval=60&eventType=60
+http://192.168.136.140:8077/detect/changeStatus?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VySUQiOiIxNTg0MzUxODk2MjgyMTM4MDAxMzgwMDAiLCJsYW5nIjoiZW4iLCJ1c2VyIjoiMTM2ODAzMTc1OTYiLCJtX2NvZGUiOiIxMjM0MTMyNDMyMTQiLCJleHAiOjE1ODcyNjEzODN9.H87931EDg6PGZK63EAsvY1FRJov9qo_S70mBKvpZeQM&push_type=2&token_val=token_val&appBundleId=appBundleId&tz=0&uid=158440619973313800138000&status=1&m_code&lang=cn&app_type=0&start_status=1&interval=60&eventType=60
+detect/changeStatus
+
+'''
+
+
+class DetectControllerViewV2(View):
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        # self.ip = CommonService.get_ip_address(request)
+        return self.validation(request.GET, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        # self.ip = CommonService.get_ip_address(request)
+        return self.validation(request.POST, operation)
+
+    def validation(self, request_dict, operation):
+        response = ResponseObject()
+        if operation is None:
+            return response.json(444, 'error path')
+        token = request_dict.get('token', None)
+        tko = TokenObject(token)
+        if tko.code == 0:
+            userID = tko.userID
+            # 修改推送设置
+            if operation == 'changeStatus':
+                print("进入changeStatus")
+                return self.do_change_status(userID, request_dict, response)
+            # 查询推送信息
+            elif operation == 'queryInfo':
+                return self.do_query(request_dict, response, userID)
+            # 更新推送延迟
+            elif operation == 'updateInterval':
+                return self.do_update_interval(userID, request_dict, response)
+            else:
+                return response.json(414)
+        else:
+            return response.json(tko.code)
+
+    def do_change_status(self, userID, request_dict, response):
+        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)
+        status = request_dict.get('status', None)
+        m_code = request_dict.get('m_code', None)
+        uid = request_dict.get('uid', None)
+        # 设备语言
+        lang = request_dict.get('lang', 'en')
+        tz = request_dict.get('tz', '0')
+        company_secrete = request_dict.get('company_secrete', None)
+        region = request_dict.get('region', None)  # app必须传:2:国内 1:国外
+        if not region:
+            return response.json(444, 'region')
+        region = int(region)
+        # 消息提醒功能新增
+
+        # 如果传空上来,就默认为0
+        if tz == '':
+            tz = 0
+        detect_group = request_dict.get('detect_group', None)
+        interval = request_dict.get('interval', None)
+        if not status:
+            return response.json(444, 'status')
+        if not company_secrete:
+            return response.json(444, 'company_secrete')
+        company = CompanyModel.objects.filter(secret=company_secrete)
+        if not company.exists():
+            return response.json(444, 'company_secrete')
+        # 关闭推送
+        if not all([appBundleId, app_type, token_val, uid, m_code]):
+            return response.json(444, 'appBundleId,app_type,token_val,uid,m_code')
+        # 判断推送类型对应key是否存在
+        print('push_type:', push_type)
+
+        if push_type == '0':
+            if appBundleId not in APNS_CONFIG.keys():
+                return response.json(904)
+        elif push_type == '1':
+            if appBundleId not in FCM_CONFIG.keys():
+                return response.json(904)
+        elif push_type == '2':
+            if appBundleId not in JPUSH_CONFIG.keys():
+                return response.json(904)
+        else:
+            return response.json(173)
+        dvqs = Device_Info.objects.filter(userID_id=userID, UID=uid)
+        status = int(status)
+        # 获取用户区域
+        # ip = self.ip
+        # ipInfo = CommonService.getIpIpInfo(ip=ip, lang='EN')
+        # area = ipInfo['country_name']
+        # if area == 'China':
+        #     DETECT_PUSH_DOMAIN_V2 = 'cn.push.dvema.com'
+        # else:
+        #     DETECT_PUSH_DOMAIN_V2 = 'en.push.dvema.com'
+
+        nowTime = int(time.time())
+        if dvqs.exists():
+            # 修改状态
+            dvqs.update(NotificationMode=status)
+            uid_set_qs = UidSetModel.objects.filter(uid=uid)
+            # uid配置信息是否存在
+
+            if uid_set_qs.exists():
+                uid_set_id = uid_set_qs[0].id
+                qs_data = {
+                    'detect_status': status,
+                    'updTime': nowTime,
+                }
+                if interval:
+                    qs_data['detect_interval'] = int(interval)
+                if detect_group:
+                    qs_data['detect_group'] = detect_group
+                print(qs_data)
+                uid_set_qs.update(**qs_data)
+
+            else:
+                qs_data = {
+                    'uid': uid,
+                    'addTime': nowTime,
+                    'updTime': nowTime,
+                    'detect_status': status,
+                }
+                if interval:
+                    qs_data['detect_interval'] = int(interval)
+                if detect_group:
+                    qs_data['detect_group'] = detect_group
+                # 添加设备配置
+                uid_set_qs = UidSetModel.objects.create(**qs_data)
+
+                uid_set_id = uid_set_qs.id
+
+            if status == 0:
+                UidPushModel.objects.filter(uid_set__uid=uid).delete()
+                # 状态为0的时候删除redis缓存数据
+                self.do_delete_redis(uid)
+                return response.json(0)
+            elif status == 1:
+                uid_push_qs = UidPushModel.objects.filter(userID_id=userID, m_code=m_code, uid_set__uid=uid)
+                # ykey = '{uid}_redis_qs'.format(uid=uid)
+                # redisObj = RedisObject(db=6, SERVER_HOST='push.dvema.com')
+                # redisObj.del_data(key=ykey)
+
+                if uid_push_qs.exists():
+                    uid_push_update_dict = {
+                        'appBundleId': appBundleId,
+                        'app_type': app_type,
+                        'push_type': push_type,
+                        'token_val': token_val,
+                        'updTime': nowTime,
+                        'lang': lang,
+                        'tz': tz
+                    }
+                    uid_push_qs.update(**uid_push_update_dict)
+                else:
+                    # uid_set_id = uid_set_qs[0].id
+                    uid_push_create_dict = {
+                        'uid_set_id': uid_set_id,
+                        'userID_id': userID,
+                        'appBundleId': appBundleId,
+                        'app_type': app_type,
+                        'push_type': push_type,
+                        'token_val': token_val,
+                        'm_code': m_code,
+                        'addTime': nowTime,
+                        'updTime': nowTime,
+                        'lang': lang,
+                        'tz': tz
+                    }
+                    # 绑定设备推送
+                    UidPushModel.objects.create(**uid_push_create_dict)
+
+                if interval:
+                    self.do_delete_redis(uid, int(interval))
+                else:
+                    self.do_delete_redis(uid)
+                # utko = UidTokenObject()
+                # # right
+                # utko.generate(data={'uid': uid})
+                etkObj = ETkObject(etk='')
+                etk = etkObj.encrypt(uid)
+
+                if company_secrete == 'MTEyMTNB':
+                    url = DETECT_PUSH_DOMAIN
+                    urls = DETECT_PUSH_DOMAINS
+                else:
+                    url = DETECT_PUSH_DOMAIN_JIUAN
+                    urls = DETECT_PUSH_DOMAINS_JIUAN
+                detectUrl = "{DETECT_PUSH_DOMAIN}notifyV2/push?etk={etk}&company_secrete={company_secrete}&region={region}". \
+                    format(etk=etk, company_secrete=company_secrete, DETECT_PUSH_DOMAIN=url, region=region)
+                detectUrls = "{DETECT_PUSH_DOMAIN_V2}notifyV2/push?etk={etk}&company_secrete={company_secrete}&region={region}". \
+                    format(etk=etk, company_secrete=company_secrete, DETECT_PUSH_DOMAIN_V2=urls, region=region)
+                return response.json(0, {'detectUrl': detectUrl, 'detectUrls': detectUrls})
+        else:
+            return response.json(14)
+
+    def do_delete_redis(self, uid, detect_interval=0):
+        keyPattern = '{uid}*'.format(uid=uid)
+        redisObj = RedisObject(db=6, SERVER_HOST='push.dvema.com')
+        keys = redisObj.get_keys(keyPattern)
+        if keys:
+            for key in keys:
+                key = key.decode()
+                if detect_interval == 0:
+                    redisObj.del_data(key=key)
+                elif key.find('plt') != -1:
+                    continue
+                elif key.find('flag') != -1:
+                    redisObj.set_data(key=key, val=1, expire=detect_interval)
+                else:
+                    redisObj.del_data(key=key)
+
+    def do_query(self, request_dict, response, userID):
+        page = int(request_dict.get('page', None))
+        line = int(request_dict.get('line', None))
+        if not page or not line:
+            return response.json(444, 'page,line')
+        startTime = request_dict.get('startTime', None)
+        endTime = request_dict.get('endTime', None)
+        eventType = request_dict.get('eventType', None)
+        region = request_dict.get('region', None)
+        if not region:
+            return response.json(444, 'region')
+        region = int(region)
+        qs = Equipment_Info.objects.filter(userID_id=userID).order_by('-eventTime')
+        if startTime and endTime:
+            qs = qs.filter(eventTime__range=(startTime, endTime))
+        if eventType:
+            qs = qs.filter(eventType=eventType)
+        uids = request_dict.get('uids', None)
+        if uids:
+            uid_list = uids.split(',')
+            qs = qs.filter(devUid__in=uid_list)
+            dvqs = Device_Info.objects.filter(UID__in=uid_list, userID_id=userID).values('UID', 'Type', 'NickName')
+            uid_type_dict = {}
+            for dv in dvqs:
+                uid_type_dict[dv['UID']] = {'type': dv['Type'], 'NickName': dv['NickName']}
+        else:
+            dvqs = Device_Info.objects.filter(userID_id=userID).values('UID', 'Type', 'NickName')
+            uid_type_dict = {}
+            for dv in dvqs:
+                uid_type_dict[dv['UID']] = {'type': dv['Type'], 'NickName': dv['NickName']}
+        # print(uid_type_dict)
+        if not qs.exists():
+            return response.json(0, {'datas': [], 'count': 0})
+        qs = qs.values('id', 'devUid', 'devNickName', 'Channel', 'eventType', 'status', 'alarm', 'eventTime',
+                       'receiveTime', 'is_st', 'addTime', 'storage_location')
+
+        count = qs.count()
+        qr = qs[(page - 1) * line:page * line]
+        res = []
+        auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
+        oss_img_bucket = oss2.Bucket(auth, 'oss-cn-shenzhen.aliyuncs.com', 'apg')
+        aws_s3_guonei = boto3.client(
+            's3',
+            aws_access_key_id=AWS_ACCESS_KEY_ID[0],
+            aws_secret_access_key=AWS_SECRET_ACCESS_KEY[0],
+            config=botocore.client.Config(signature_version='s3v4'),
+            region_name='cn-northwest-1'
+        )
+        aws_s3_guowai = boto3.client(
+            's3',
+            aws_access_key_id=AWS_ACCESS_KEY_ID[1],
+            aws_secret_access_key=AWS_SECRET_ACCESS_KEY[1],
+            config=botocore.client.Config(signature_version='s3v4'),
+            region_name='us-east-1'
+        )
+        # vod_time_list = []
+        for p in qr:
+            devUid = p['devUid']
+            eventTime = p['eventTime']
+            channel = p['Channel']
+            storage_location = p['storage_location']
+            if p['is_st'] == 1:
+                thumbspng = '{uid}/{channel}/{time}.jpeg'.format(uid=devUid, channel=p['Channel'], time=eventTime)
+                if storage_location == 1:   # oss
+                    response_url = oss_img_bucket.sign_url('GET', thumbspng, 300)
+                    p['img'] = response_url
+                    p['img_list'] = [response_url]
+                elif region == 2 and storage_location == 2:  # 2:国内,aws
+                    response_url = aws_s3_guonei.generate_presigned_url('get_object',
+                                                                        Params={'Bucket': 'push', 'Key': thumbspng},
+                                                                        ExpiresIn=300)
+                    p['img'] = response_url
+                    p['img_list'] = [response_url]
+                elif region == 1 and storage_location == 2:   # 1:国外,aws
+                    response_url = aws_s3_guowai.generate_presigned_url('get_object',
+                                                                        Params={'Bucket': 'foreignpush', 'Key': thumbspng},
+                                                                        ExpiresIn=300)
+                    p['img'] = response_url
+                    p['img_list'] = [response_url]
+
+            elif p['is_st'] == 2:
+                # 列表装载回放时间戳标记
+                vodqs = VodHlsModel.objects.filter(uid=devUid, channel=channel, time=int(eventTime)) \
+                    .values("bucket__bucket", "bucket__endpoint")
+                # print(vodqs)
+                if vodqs.exists():
+                    bucket_name = vodqs[0]['bucket__bucket']
+                    endpoint = vodqs[0]['bucket__endpoint']
+                    bucket = oss2.Bucket(auth, endpoint, bucket_name)
+                    ts = '{uid}/vod{channel}/{etime}/ts0.ts'.format(uid=devUid, channel=p['Channel'], etime=eventTime)
+                    if storage_location == 1:   # oss
+                        thumb0 = bucket.sign_url('GET', ts, 3600, params={'x-oss-process': 'video/snapshot,t_0000,w_700'})
+                        thumb1 = bucket.sign_url('GET', ts, 3600, params={'x-oss-process': 'video/snapshot,t_1000,w_700'})
+                        thumb2 = bucket.sign_url('GET', ts, 3600, params={'x-oss-process': 'video/snapshot,t_2000,w_700'})
+                        # thumb3 = bucket.sign_url('GET', ts, 3600, params={'x-oss-process': 'video/snapshot,t_3000,w_700'})
+                        p['img_list'] = [thumb0, thumb1, thumb2]
+                    elif region == 2 and storage_location == 2:     # 2:国内,aws
+                        thumb = aws_s3_guonei.generate_presigned_url('get_object',
+                                                                     Params={'Bucket': 'push', 'Key': ts},
+                                                                     ExpiresIn=3600)
+                        p['img_list'] = [thumb]
+                    elif region == 1 and storage_location == 2:   # 1:国外,aws
+                        thumb = aws_s3_guowai.generate_presigned_url('get_object',
+                                                                     Params={'Bucket': 'foreignpush', 'Key': ts},
+                                                                     ExpiresIn=3600)
+                        p['img_list'] = [thumb]
+            elif p['is_st'] == 3:
+                # 列表装载回放时间戳标记
+                p['img_list'] = []
+                for i in range(p['is_st']):
+                    thumbspng = '{uid}/{channel}/{time}_{st}.jpeg'.format(uid=devUid, channel=p['Channel'], time=eventTime, st=i)
+                    if storage_location == 1:   # oss
+                        img = oss_img_bucket.sign_url('GET', thumbspng, 300)
+                        p['img_list'].append(img)
+                    elif region == 2 and storage_location == 2:  # 2:国内,aws
+                        response_url = aws_s3_guonei.generate_presigned_url('get_object',
+                                                                            Params={'Bucket': 'push', 'Key': thumbspng},
+                                                                            ExpiresIn=300)
+                        img = response_url
+                        p['img_list'].append(img)
+                    elif region == 1 and storage_location == 2:   # 1:国外,aws
+                        response_url = aws_s3_guowai.generate_presigned_url('get_object',
+                                                                            Params={'Bucket': 'foreignpush', 'Key': thumbspng},
+                                                                            ExpiresIn=300)
+                        img = response_url
+                        p['img_list'].append(img)
+            if devUid in uid_type_dict.keys():
+                p['uid_type'] = uid_type_dict[devUid]['type']
+                p['devNickName'] = uid_type_dict[devUid]['NickName']
+            else:
+                p['uid_type'] = ''
+            res.append(p)
+        return response.json(0, {'datas': res, 'count': count})
+
+    def do_update_interval(self, userID, request_dict, response):
+        uid = request_dict.get('uid', None)
+        interval = request_dict.get('interval', None)
+        dvqs = Device_Info.objects.filter(userID_id=userID, UID=uid)
+        if dvqs.exists():
+            uid_set_qs = UidSetModel.objects. \
+                filter(uid=uid, uidpushmodel__userID_id=userID)
+            # redisObj = RedisObject(db=8)
+            # redisObj.del_data(key='uid_qs_' + userID)
+            if uid_set_qs.exists():
+                uid_set_qs.update(interval=int(interval))
+            else:
+                return response.json(173)
+        else:
+            return response.json(0)
+
+
+# 设备调用接口
+# 移动侦测接口
+class NotificationView(View):
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        return self.validation(request.GET)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        return self.validation(request.POST)
+
+    def validation(self, request_dict):
+
+        uidToken = request_dict.get('uidToken', None)
+        etk = request_dict.get('etk', None)
+        channel = request_dict.get('channel', '1')
+        n_time = request_dict.get('n_time', None)
+        event_type = request_dict.get('event_type', None)
+        is_st = request_dict.get('is_st', None)
+        company_secrete = request_dict.get('company_secrete', None)
+        region = request_dict.get('region', None)
+        if not region:
+            return JsonResponse(status=200, data={'code': 404, 'msg': 'region is not exist'})
+        region = int(region)
+        # print("aaa")
+        # return JsonResponse(0,safe=False)
+        if not all([channel, n_time]):
+            return JsonResponse(status=200, data={
+                'code': 444,
+                'msg': 'param is wrong'})
+        if etk:
+            eto = ETkObject(etk)
+            uid = eto.uid
+            if len(uid) != 20 and len(uid) != 14:
+                return JsonResponse(status=200, data={'code': 404, 'msg': 'data is not exist'})
+        else:
+            utko = UidTokenObject(uidToken)
+            uid = utko.UID
+
+        pkey = '{uid}_{channel}_{event_type}_ptl'.format(uid=uid, event_type=event_type, channel=channel)
+        # ykey = 'MUJ887NLR8K8GBM9111A_redis_qs'.format(uid=uid)
+        ykey = '{uid}_redis_qs'.format(uid=uid)
+        # dkey = '{uid}_{channel}_{event_type}_flag'.format(uid=uid, event_type=event_type, channel=channel)
+        is_sys_msg = self.is_sys_msg(int(event_type))
+        if is_sys_msg is True:
+            dkey = '{uid}_{channel}_{event_type}_flag'.format(uid=uid, event_type=event_type, channel=channel)
+        else:
+            dkey = '{uid}_{channel}_flag'.format(uid=uid, channel=channel)
+
+        # 判断redisObj.get_data(key=pkey):不为空
+        redisObj = RedisObject(db=6)
+        have_ykey = redisObj.get_data(key=ykey)  # uid_set 数据库缓存
+        have_pkey = redisObj.get_data(key=pkey)  # 一分钟限制key
+        have_dkey = redisObj.get_data(key=dkey)  # 推送类型限制
+
+        # 一分钟外,推送开启状态
+        detect_med_type = 0  # 0推送旧机制 1存库不推送,2推送存库
+        # 暂时注销
+        if have_pkey:
+            if SERVER_TYPE != "Ansjer.formal_settings":
+                res_data = {'code': 0, 'msg': 'Push once every 10 seconds'}
+            else:
+                res_data = {'code': 0, 'msg': 'Push it once a minute'}
+
+            return JsonResponse(status=200, data=res_data)
+
+        # 数据库读取数据
+        if have_ykey:
+            redis_list = eval(redisObj.get_data(key=ykey))
+            print(have_ykey)
+            if not redis_list:
+                # 从数据库查询出来
+                uid_push_qs = UidPushModel.objects.filter(uid_set__uid=uid, uid_set__detect_status=1). \
+                    values('token_val', 'app_type', 'appBundleId', 'm_code',
+                           'push_type', 'userID_id', 'userID__NickName',
+                           'lang', 'm_code', 'tz', 'uid_set__nickname', 'uid_set__detect_interval', 'uid_set__detect_group',
+                           'uid_set__channel')
+                print(uid_push_qs)
+                # 新建一个list接收数据
+                redis_list = []
+                # 把数据库数据追加进redis_list
+                for qs in uid_push_qs:
+                    redis_list.append(qs)
+                # 修改redis数据,并设置过期时间为10分钟
+                redisObj.set_data(key=ykey, val=str(redis_list), expire=600)
+                if not redis_list:
+                    res_data = {'code': 404, 'msg': 'error !'}
+                    return JsonResponse(status=200, data=res_data)
+        else:
+            # 从数据库查询出来
+            uid_push_qs = UidPushModel.objects.filter(uid_set__uid=uid,uid_set__detect_status=1). \
+                values('token_val', 'app_type', 'appBundleId','m_code',
+                       'push_type', 'userID_id', 'userID__NickName',
+                       'lang', 'm_code', 'tz', 'uid_set__nickname', 'uid_set__detect_interval', 'uid_set__detect_group',
+                       'uid_set__channel')
+            print(uid_push_qs)
+            # 新建一个list接收数据
+            redis_list = []
+            # 把数据库数据追加进redis_list
+            for qs in uid_push_qs:
+                redis_list.append(qs)
+            # 修改redis数据,并设置过期时间为10分钟
+            redisObj.set_data(key=ykey, val=str(redis_list), expire=600)
+            if not redis_list:
+                res_data = {'code': 404, 'msg': 'error !'}
+                return JsonResponse(status=200, data=res_data)
+
+            # 此时应该更新一下redis里面的dkey的有效时间
+            # detect_interval = redis_list[0]['uid_set__detect_interval']
+            # tmp_channel = redis_list[0]['uid_set__channel']
+            # self.do_update_detect_interval(uid, tmp_channel, redisObj, detect_interval)
+
+        if not redis_list:
+            print("没有redi_list")
+            res_data = {'code': 0, 'msg': 'no redi_list success!'}
+            return JsonResponse(status=200, data=res_data)
+
+        # is_sys_msg = self.is_sys_msg(int(event_type))
+        nickname = redis_list[0]['uid_set__nickname']
+        detect_interval = redis_list[0]['uid_set__detect_interval']
+        detect_group = redis_list[0]['uid_set__detect_group']
+        now_time = int(time.time())
+        if not nickname:
+            nickname = uid
+
+        if detect_group is not None:
+            if have_dkey:
+                detect_med_type = 1  # 1为存库不推送
+            else:
+                detect_med_type = 2  # 为2的话,既推送,又存库
+                # detect_group=0允许全部推送的时候
+                if detect_group == '0'or detect_group == '':
+                    redisObj.set_data(key=dkey, val=1, expire=detect_interval)
+                else:
+                    detect_group_list = detect_group.split(',')
+                    if event_type in detect_group_list:
+                        if detect_interval < 60:
+                            detect_interval = 60
+                        redisObj.set_data(key=dkey, val=1, expire=detect_interval)
+                # 改为1秒
+                # 如果不是正式
+                if SERVER_TYPE!="Ansjer.formal_settings":
+                    redisObj.set_data(key=pkey, val=1, expire=10)
+                else:
+                    redisObj.set_data(key=pkey, val=1, expire=60)
+
+            # 打印have_ykey
+        # return JsonResponse(status=200, data={'pkey': 0, 'have_ykey': have_ykey, 'have_pkey': have_pkey, 'have_ykey': have_dkey})
+
+        # 旧模式并且没有pkey,重新创建一个
+        if not detect_group and not have_pkey:
+            # 设置推送时间为60秒一次
+            # 如果不是正式
+            if SERVER_TYPE != "Ansjer.formal_settings":
+                redisObj.set_data(key=pkey, val=1, expire=10)
+            else:
+                redisObj.set_data(key=pkey, val=1, expire=60)
+        # auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
+        # bucket = oss2.Bucket(auth, 'oss-cn-shenzhen.aliyuncs.com', 'apg')
+        aws_s3_guonei = boto3.client(
+            's3',
+            aws_access_key_id=AWS_ACCESS_KEY_ID[0],
+            aws_secret_access_key=AWS_SECRET_ACCESS_KEY[0],
+            config=botocore.client.Config(signature_version='s3v4'),
+            region_name='cn-northwest-1'
+        )
+        aws_s3_guowai = boto3.client(
+            's3',
+            aws_access_key_id=AWS_ACCESS_KEY_ID[1],
+            aws_secret_access_key=AWS_SECRET_ACCESS_KEY[1],
+            config=botocore.client.Config(signature_version='s3v4'),
+            region_name='us-east-1'
+        )
+        kwag_args = {
+            'uid': uid,
+            'channel': channel,
+            'event_type': event_type,
+            'n_time': n_time,
+            # 'appBundleId': appBundleId,
+            # 'token_val': token_val,
+            # 'msg_title': msg_title,
+            # 'msg_text': msg_text
+        }
+        eq_list = []
+        sys_msg_list = []
+        userID_ids = []
+        do_apns_code = ''
+        do_fcm_code = ''
+        do_jpush_code = ''
+        for up in redis_list:
+            push_type = up['push_type']
+            appBundleId = up['appBundleId']
+            token_val = up['token_val']
+            lang = up['lang']
+            tz = up['tz']
+            if tz is None or tz == '':
+                tz = 0
+            # 发送标题
+            msg_title = self.get_msg_title(appBundleId=appBundleId, nickname=nickname)
+            # 发送内容
+            msg_text = self.get_msg_text(channel=channel, n_time=n_time, lang=lang, tz=tz,
+                                         event_type=event_type)
+            kwag_args['appBundleId'] = appBundleId
+            kwag_args['token_val'] = token_val
+            kwag_args['msg_title'] = msg_title
+            kwag_args['msg_text'] = msg_text
+            push_server_status = 0
+            #推送
+            if detect_med_type == 2 or detect_med_type == 0:
+                if push_type == 0:  # ios apns
+                    print('do_apns')
+                    # self.do_apns(**kwag_args)
+                    do_apns_code = self.do_apns(**kwag_args)
+                    if isinstance(do_apns_code, int):
+                        push_server_status = do_apns_code
+                    else:
+                        push_server_status = 400
+                elif push_type == 1:  # android gcm
+                    print('do_fcm')
+                    do_fcm_code = self.do_fcm(**kwag_args)
+                    push_server_status = 200
+                elif push_type == 2:  # android jpush
+                    print('do_jpush')
+                    do_jpush_code = self.do_jpush(**kwag_args)
+                    push_server_status = do_jpush_code
+                    # return JsonResponse(status=200, data={'code': 0, '状态:': self.do_jpush(**kwag_args)})
+            if detect_med_type == 1:
+                do_apns_code = '只存库不推送'
+                do_fcm_code = '只存库不推送'
+                do_jpush_code = '只存库不推送'
+            # 以下是存库
+            userID_id = up["userID_id"]
+            int_is_st = int(is_st)
+            if userID_id not in userID_ids:
+                eq_list.append(Equipment_Info(
+                    userID_id=userID_id,
+                    eventTime=n_time,
+                    eventType=event_type,
+                    devUid=uid,
+                    devNickName=nickname,
+                    Channel=channel,
+                    alarm='Motion \tChannel:{channel}'.format(channel=channel),
+                    is_st=int_is_st,
+                    receiveTime=n_time,
+                    addTime=now_time,
+                    storage_location=2
+                ))
+                if is_sys_msg:
+                    sys_msg_text = self.get_msg_text(channel=channel, n_time=n_time, lang=lang, tz=tz,
+                                                     event_type=event_type, is_sys=1)
+                    sys_msg_list.append(SysMsgModel(
+                        userID_id=userID_id,
+                        msg=sys_msg_text,
+                        addTime=now_time,
+                        updTime=now_time,
+                        uid=uid,
+                        eventType=event_type))
+                userID_ids.append(userID_id)
+        if is_sys_msg:
+            SysMsgModel.objects.bulk_create(sys_msg_list)
+        Equipment_Info.objects.bulk_create(eq_list)
+        if is_st == '0' or is_st == '2':
+            print("is_st=0or2")
+            for up in redis_list:
+                if up['push_type'] == 0:  # ios apns
+                    up['do_apns_code'] = do_apns_code
+                elif up['push_type'] == 1:  # android gcm
+                    up['do_fcm_code'] = do_fcm_code
+                elif up['push_type'] == 2:  # android jpush
+                    up['do_jpush_code'] = do_jpush_code
+                up['test_or_www'] = SERVER_TYPE
+                del up['push_type']
+                del up['userID_id']
+                del up['userID__NickName']
+                del up['lang']
+                del up['tz']
+                del up['uid_set__nickname']
+                del up['uid_set__detect_interval']
+                del up['uid_set__detect_group']
+            return JsonResponse(status=200, data={'code': 0, 'msg': 'success 0 or 2' ,'re_list':redis_list})
+
+        elif is_st == '1':
+            print("is_st=1")
+            # Endpoint以杭州为例,其它Region请按实际情况填写。
+            # obj = '{uid}/{channel}/{filename}.jpeg'.format(uid=uid, channel=channel, filename=n_time)
+            # 设置此签名URL在60秒内有效。
+            # url = bucket.sign_url('PUT', obj, 7200)
+            thumbspng = '{uid}/{channel}/{filename}.jpeg'.format(uid=uid, channel=channel, filename=n_time)
+            if region == 2:  # 2:国内
+                response_url = aws_s3_guonei.generate_presigned_url(
+                    ClientMethod='put_object',
+                    Params={
+                        'Bucket': 'push',
+                        'Key': thumbspng
+                    },
+                    ExpiresIn=3600
+                )
+            else:   # 1:国外
+                response_url = aws_s3_guowai.generate_presigned_url(
+                    ClientMethod='put_object',
+                    Params={
+                        'Bucket': 'foreignpush',
+                        'Key': thumbspng
+                    },
+                    ExpiresIn=3600
+                )
+            for up in redis_list:
+                up['do_apns_code'] = do_apns_code
+                up['do_fcm_code'] = do_fcm_code
+                up['do_jpush_code'] = do_jpush_code
+                up['test_or_www'] = SERVER_TYPE
+                del up['push_type']
+                del up['userID_id']
+                del up['userID__NickName']
+                del up['lang']
+                del up['tz']
+                del up['uid_set__nickname']
+                del up['uid_set__detect_interval']
+                del up['uid_set__detect_group']
+                # 不是正式服务器
+            # response_url = response_url[:4] + response_url[5:]
+            if SERVER_TYPE != "Ansjer.formal_settings":
+                # res_data = {'code': 0, 'img_push': url, 'msg': 'success', 're_list': redis_list}
+                res_data = {'code': 0, 'img_push': response_url, 'msg': 'success', 're_list': redis_list}
+            else:
+                # 是正式服务器的时候
+                # res_data = {'code': 0, 'img_push': url, 'msg': 'success'}
+                res_data = {'code': 0, 'img_push': response_url, 'msg': 'success'}
+            return JsonResponse(status=200, data=res_data)
+
+        elif is_st == '3':
+            print("is_st=3")
+            # 人形检测带动图
+            # Endpoint以杭州为例,其它Region请按实际情况填写。
+            img_url_list = []
+            for i in range(int(is_st)):
+                obj = '{uid}/{channel}/{filename}_{st}.jpeg'. \
+                    format(uid=uid, channel=channel, filename=n_time, st=i)
+                # 设置此签名URL在60秒内有效。
+                # url = bucket.sign_url('PUT', obj, 7200)
+
+                thumbspng = '{uid}/{channel}/{filename}_{st}.jpeg'. \
+                    format(uid=uid, channel=channel, filename=n_time, st=i)
+                if region == 2:  # 2:国内
+                    response_url = aws_s3_guonei.generate_presigned_url(
+                        ClientMethod='put_object',
+                        Params={
+                            'Bucket': 'push',
+                            'Key': thumbspng
+                        },
+                        ExpiresIn=3600
+                    )
+                else:   # 1:国外
+                    response_url = aws_s3_guowai.generate_presigned_url(
+                        ClientMethod='put_object',
+                        Params={
+                            'Bucket': 'foreignpush',
+                            'Key': thumbspng
+                        },
+                        ExpiresIn=3600
+                    )
+                # response_url = response_url[:4] + response_url[5:]
+                img_url_list.append(response_url)
+
+                # img_url_list.append(url)
+
+            for up in redis_list:
+                up['do_apns_code'] = do_apns_code
+                up['do_fcm_code'] = do_fcm_code
+                up['do_jpush_code'] = do_jpush_code
+                up['test_or_www'] = SERVER_TYPE
+                del up['push_type']
+                del up['userID_id']
+                del up['userID__NickName']
+                del up['lang']
+                del up['tz']
+                del up['uid_set__nickname']
+                del up['uid_set__detect_interval']
+                del up['uid_set__detect_group']
+
+            # 不是正式服务器
+            if SERVER_TYPE != "Ansjer.formal_settings":
+                res_data = {'code': 0, 'img_url_list': img_url_list, 'msg': 'success 3', 're_list': redis_list}
+            else:
+                # 是正式服务器的时候
+                res_data = {'code': 0, 'img_url_list': img_url_list, 'msg': 'success 3'}
+            return JsonResponse(status=200, data=res_data)
+
+
+    def get_msg_title(self, appBundleId, nickname):
+        package_title_config = {
+            'com.ansjer.customizedd_a': 'DVS',
+            'com.ansjer.zccloud_a': 'ZosiSmart',
+            'com.ansjer.zccloud_ab': '周视',
+            'com.ansjer.adcloud_a': 'ADCloud',
+            'com.ansjer.adcloud_ab': 'ADCloud',
+            'com.ansjer.accloud_a': 'ACCloud',
+            'com.ansjer.loocamccloud_a': 'Loocam',
+            'com.ansjer.loocamdcloud_a': 'Anlapus',
+            'com.ansjer.customizedb_a': 'COCOONHD',
+            'com.ansjer.customizeda_a': 'Guardian365',
+            'com.ansjer.customizedc_a': 'PatrolSecure',
+        }
+        if appBundleId in package_title_config.keys():
+            return package_title_config[appBundleId] + '(' + nickname + ')'
+        else:
+            return nickname
+
+    def is_sys_msg(self, event_type):
+        event_type_list = [702, 703, 704]
+        if event_type in event_type_list:
+            return True
+        return False
+
+    def get_msg_text(self, channel, n_time, lang, tz, event_type, is_sys=0):
+        n_date = CommonService.get_now_time_str(n_time=n_time, tz=tz,lang=lang)
+        etype = int(event_type)
+        if lang == 'cn':
+            if etype == 704:
+                msg_type = '电量过低'
+            elif etype == 702:
+                msg_type = '摄像头休眠'
+            elif etype == 703:
+                msg_type = '摄像头唤醒'
+            else:
+                msg_type = ''
+            if is_sys:
+                send_text = '{msg_type} 通道:{channel}'.format(msg_type=msg_type, channel=channel)
+            else:
+                send_text = '{msg_type} 通道:{channel} 日期:{date}'.format(msg_type=msg_type, channel=channel, date=n_date)
+                # send_text = '{msg_type} 通道:{channel} 日期:{date}'.format(msg_type=msg_type, channel=channel, date=n_date)
+        else:
+            if etype == 704:
+                msg_type = 'Low battery'
+            elif etype == 702:
+                msg_type = 'Camera sleep'
+            elif etype == 703:
+                msg_type = 'Camera wake'
+            else:
+                msg_type = ''
+            if is_sys:
+                send_text = '{msg_type} channel:{channel}'. \
+                    format(msg_type=msg_type, channel=channel)
+            else:
+                send_text = '{msg_type} channel:{channel} date:{date}'. \
+                    format(msg_type=msg_type, channel=channel, date=n_date)
+        return send_text
+
+    def do_jpush(self, uid, channel, appBundleId, token_val, event_type, n_time,
+                 msg_title, msg_text):
+        app_key = JPUSH_CONFIG[appBundleId]['Key']
+        master_secret = JPUSH_CONFIG[appBundleId]['Secret']
+        # 此处换成各自的app_key和master_secre
+        _jpush = jpush.JPush(app_key, master_secret)
+        push = _jpush.create_push()
+        # if you set the logging level to "DEBUG",it will show the debug logging.
+        # _jpush.set_logging("DEBUG")
+        # push.audience = jpush.all_
+        push.audience = jpush.registration_id(token_val)
+        push_data = {"alert": "Motion ", "event_time": n_time, "event_type": event_type, "msg": "",
+                     "received_at": n_time, "sound": "sound.aif", "uid": uid, "zpush": "1", "channel": channel}
+        android = jpush.android(alert=msg_text, priority=1, style=1, alert_type=7,
+                                big_text=msg_text, title=msg_title,
+                                extras=push_data)
+        push.notification = jpush.notification(android=android)
+        push.platform = jpush.all_
+        res = push.send()
+        print(res)
+        return res.status_code
+        # try:
+        #     res = push.send()
+        #     print(res)
+        # except Exception as e:
+        #     print("jpush fail")
+        #     print("Exception")
+        #     print(repr(e))
+        #     return
+        # else:
+        #     print("jpush success")
+        #     return
+
+    def do_fcm(self, uid, channel, appBundleId, token_val, event_type, n_time, msg_title, msg_text):
+        try:
+            serverKey = FCM_CONFIG[appBundleId]
+        except Exception as e:
+            return 'serverKey abnormal'
+        push_service = FCMNotification(api_key=serverKey)
+        data = {"alert": "Motion ", "event_time": n_time, "event_type": event_type, "msg": "",
+                "received_at": n_time, "sound": "sound.aif", "uid": uid, "zpush": "1", "channel": channel}
+        result = push_service.notify_single_device(registration_id=token_val, message_title=msg_title,
+                                                   message_body=msg_text, data_message=data,
+                                                   extra_kwargs={
+                                                       'default_vibrate_timings': True,
+                                                       'default_sound': True,
+                                                       'default_light_settings': True
+                                                   })
+        print('fcm push ing')
+        print(result)
+        return result
+
+    def do_apns(self, uid, channel, appBundleId, token_val, event_type, n_time, msg_title,
+                msg_text):
+        try:
+            cli = apns2.APNSClient(mode=APNS_MODE,
+                                   client_cert=os.path.join(BASE_DIR, APNS_CONFIG[appBundleId]['pem_path']))
+
+            push_data = {"alert": "Motion ", "event_time": n_time, "event_type": event_type, "msg": "",
+                         "received_at": n_time, "sound": "sound.aif", "uid": uid, "zpush": "1", "channel": channel}
+            alert = apns2.PayloadAlert(body=msg_text, title=msg_title)
+            payload = apns2.Payload(alert=alert, custom=push_data)
+
+            # return uid, channel, appBundleId, str(token_val), event_type, n_time, msg_title,msg_text
+            n = apns2.Notification(payload=payload, priority=apns2.PRIORITY_LOW)
+            res = cli.push(n=n, device_token=token_val, topic=appBundleId)
+            print(res.status_code)
+
+            #     200, 推送成功。
+            #   400, 请求有问题。
+            #   403, 证书或Token有问题。
+            #   405, 请求方式不正确, 只支持POST请求
+            #   410, 设备的Token与证书不一致
+            if res.status_code == 200:
+                return res.status_code
+            else:
+                print('apns push fail')
+                print(res.reason)
+                return res.status_code
+        except (ValueError, ArithmeticError):
+            return 'The program has a numeric format exception, one of the arithmetic exceptions'
+        except Exception as e:
+            print(repr(e))
+            return repr(e)
+
+    def do_update_detect_interval(self, uid, channel, redisObject, detect_interval):
+        if channel == 0:
+            channel = 17
+        else:
+            channel += 1
+        for i in range(1, channel):
+            tmpDKey = '{uid}_{channel}_{event_type}_flag'.format(uid=uid, event_type=51, channel=i)
+            if tmpDKey is not False:
+                llt = redisObject.get_ttl(tmpDKey)
+                if llt > detect_interval:
+                    redisObject.set_data(key=tmpDKey, val=1, expire=detect_interval)
+
+            tmpDKey = '{uid}_{channel}_{event_type}_flag'.format(uid=uid, event_type=54, channel=i)
+            if tmpDKey is not False:
+                llt = redisObject.get_ttl(tmpDKey)
+                if llt > detect_interval:
+                    redisObject.set_data(key=tmpDKey, val=1, expire=detect_interval)
+
+
+# 这个接口没有调用过,不敢动
+# http://test.dvema.com/detect/add?uidToken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiJQMldOR0pSRDJFSEE1RVU5MTExQSJ9.xOCI5lerk8JOs5OcAzunrKCfCrtuPIZ3AnkMmnd-bPY&n_time=1526845794&channel=1&event_type=51&is_st=0
+# 移动侦测接口
+class PushNotificationView(View):
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        # operation = kwargs.get('operation')
+        return self.validation(request.GET)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        # operation = kwargs.get('operation')
+        return self.validation(request.POST)
+
+    def validation(self, request_dict):
+        etk = request_dict.get('etk', None)
+        channel = request_dict.get('channel', '1')
+        n_time = request_dict.get('n_time', None)
+        event_type = request_dict.get('event_type', None)
+        is_st = request_dict.get('is_st', None)
+        region = request_dict.get('region', '2')
+        region = int(region)
+        eto = ETkObject(etk)
+        uid = eto.uid
+        if len(uid) == 20:
+            redisObj = RedisObject(db=6)
+            # pkey = '{uid}_{channel}_ptl'.format(uid=uid, channel=channel)
+            pkey = '{uid}_ptl'.format(uid=uid)
+            ykey = '{uid}_redis_qs'.format(uid=uid)
+            if redisObj.get_data(key=pkey):
+                res_data = {'code': 0, 'msg': 'success,!33333333333'}
+                return JsonResponse(status=200, data=res_data)
+            else:
+                redisObj.set_data(key=pkey, val=1, expire=60)
+            ##############
+            redis_data = redisObj.get_data(key=ykey)
+            if redis_data:
+                redis_list = eval(redis_data)
+            else:
+                # 设置推送时间为60秒一次
+                redisObj.set_data(key=pkey, val=1, expire=60)
+                print("从数据库查到数据")
+                # 从数据库查询出来
+                uid_push_qs = UidPushModel.objects.filter(uid_set__uid=uid, uid_set__detect_status=1). \
+                    values('token_val', 'app_type', 'appBundleId',
+                           'push_type', 'userID_id', 'lang','m_code',
+                           'tz', 'uid_set__nickname')
+                # 新建一个list接收数据
+                redis_list = []
+                # 把数据库数据追加进redis_list
+                for qs in uid_push_qs:
+                    redis_list.append(qs)
+                # 修改redis数据,并设置过期时间为10分钟
+            if redis_list:
+                redisObj.set_data(key=ykey, val=str(redis_list), expire=600)
+                # auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
+                # bucket = oss2.Bucket(auth, 'oss-cn-shenzhen.aliyuncs.com', 'apg')
+                aws_s3_guonei = boto3.client(
+                    's3',
+                    aws_access_key_id=AWS_ACCESS_KEY_ID[0],
+                    aws_secret_access_key=AWS_SECRET_ACCESS_KEY[0],
+                    config=botocore.client.Config(signature_version='s3v4'),
+                    region_name='cn-northwest-1'
+                )
+                aws_s3_guowai = boto3.client(
+                    's3',
+                    aws_access_key_id=AWS_ACCESS_KEY_ID[1],
+                    aws_secret_access_key=AWS_SECRET_ACCESS_KEY[1],
+                    config=botocore.client.Config(signature_version='s3v4'),
+                    region_name='us-east-1'
+                )
+                self.do_bulk_create_info(redis_list, n_time, channel, event_type, is_st, uid)
+                if is_st == '0' or is_st == '2':
+                    return JsonResponse(status=200, data={'code': 0, 'msg': 'success44444444444444444'})
+                elif is_st == '1':
+                    # Endpoint以杭州为例,其它Region请按实际情况填写。
+                    # obj = '{uid}/{channel}/{filename}.jpeg'.format(uid=uid, channel=channel, filename=n_time)
+                    # 设置此签名URL在60秒内有效。
+                    # url = bucket.sign_url('PUT', obj, 7200)
+                    thumbspng = '{uid}/{channel}/{filename}.jpeg'.format(uid=uid, channel=channel, filename=n_time)
+                    if region == 2:  # 2:国内
+                        response_url = aws_s3_guonei.generate_presigned_url(
+                            ClientMethod='put_object',
+                            Params={
+                                'Bucket': 'push',
+                                'Key': thumbspng
+                            },
+                            ExpiresIn=3600
+                        )
+                    else:   # 1:国外
+                        response_url = aws_s3_guowai.generate_presigned_url(
+                            ClientMethod='put_object',
+                            Params={
+                                'Bucket': 'foreignpush',
+                                'Key': thumbspng
+                            },
+                            ExpiresIn=3600
+                        )
+                    # res_data = {'code': 0, 'img_push': url, 'msg': 'success'}
+                    # response_url = response_url[:4] + response_url[5:]
+                    res_data = {'code': 0, 'img_push': response_url, 'msg': 'success'}
+                    return JsonResponse(status=200, data=res_data)
+                elif is_st == '3':
+                    # 人形检测带动图
+                    img_url_list = []
+                    for i in range(int(is_st)):
+                        # obj = '{uid}/{channel}/{filename}_{st}.jpeg'. \
+                        #     format(uid=uid, channel=channel, filename=n_time, st=i)
+                        # 设置此签名URL在60秒内有效。
+                        # url = bucket.sign_url('PUT', obj, 7200)
+
+                        thumbspng = '{uid}/{channel}/{filename}_{st}.jpeg'. \
+                            format(uid=uid, channel=channel, filename=n_time, st=i)
+                        if region == 2:  # 2:国内
+                            response_url = aws_s3_guonei.generate_presigned_url(
+                                ClientMethod='put_object',
+                                Params={
+                                    'Bucket': 'push',
+                                    'Key': thumbspng
+                                },
+                                ExpiresIn=3600
+                            )
+                        else:   # 1:国外
+                            response_url = aws_s3_guowai.generate_presigned_url(
+                                ClientMethod='put_object',
+                                Params={
+                                    'Bucket': 'foreignpush',
+                                    'Key': thumbspng
+                                },
+                                ExpiresIn=3600
+                            )
+                        # response_url = response_url[:4] + response_url[5:]
+                        img_url_list.append(response_url)
+
+                        # img_url_list.append(url)
+                    res_data = {'code': 0, 'img_url_list': img_url_list, 'msg': 'success'}
+                    return JsonResponse(status=200, data=res_data)
+            else:
+                return JsonResponse(status=200, data={'code': 404, 'msg': 'data is not exist'})
+        else:
+            return JsonResponse(status=200, data={'code': 404, 'msg': 'wrong etk'})
+
+    def do_bulk_create_info(self, uaqs, n_time, channel, event_type, is_st, uid):
+        now_time = int(time.time())
+        # 设备昵称
+        userID_ids = []
+        sys_msg_list = []
+        is_sys_msg = self.is_sys_msg(int(event_type))
+        is_st = int(is_st)
+        eq_list = []
+        nickname = uaqs[0]['uid_set__nickname']
+        if not nickname:
+            nickname = uid
+        for ua in uaqs:
+            lang = ua['lang']
+            tz = ua['tz']
+            userID_id = ua["userID_id"]
+            if userID_id not in userID_ids:
+                eq_list.append(Equipment_Info(
+                    userID_id=userID_id,
+                    eventTime=n_time,
+                    eventType=event_type,
+                    devUid=uid,
+                    devNickName=nickname,
+                    Channel=channel,
+                    alarm='Motion \tChannel:{channel}'.format(channel=channel),
+                    is_st=is_st,
+                    receiveTime=n_time,
+                    addTime=now_time,
+                    storage_location=2
+                ))
+                if is_sys_msg:
+                    sys_msg_text = self.get_msg_text(channel=channel, n_time=n_time, lang=lang, tz=tz,
+                                                     event_type=event_type, is_sys=1)
+                    sys_msg_list.append(SysMsgModel(
+                        userID_id=userID_id,
+                        msg=sys_msg_text,
+                        addTime=now_time,
+                        updTime=now_time,
+                        uid=uid,
+                        eventType=event_type))
+        if eq_list:
+            print('eq_list')
+            Equipment_Info.objects.bulk_create(eq_list)
+        if is_sys_msg:
+            print('sys_msg')
+            SysMsgModel.objects.bulk_create(sys_msg_list)
+        return True
+
+    def is_sys_msg(self, event_type):
+        event_type_list = [702, 703, 704]
+        if event_type in event_type_list:
+            return True
+        return False
+
+    def get_msg_text(self, channel, n_time, lang, tz, event_type, is_sys=0):
+        n_date = CommonService.get_now_time_str(n_time=n_time, tz=tz)
+        etype = int(event_type)
+        if lang == 'cn':
+            if etype == 704:
+                msg_type = '电量过低'
+            elif etype == 702:
+                msg_type = '摄像头休眠'
+            elif etype == 703:
+                msg_type = '摄像头唤醒'
+            else:
+                msg_type = ''
+            if is_sys:
+                send_text = '{msg_type} 通道:{channel}'.format(msg_type=msg_type, channel=channel)
+            else:
+                send_text = '{msg_type} 通道:{channel} 日期:{date}'.format(msg_type=msg_type, channel=channel, date=n_date)
+        else:
+            if etype == 704:
+                msg_type = 'Low battery'
+            elif etype == 702:
+                msg_type = 'Camera sleep'
+            elif etype == 703:
+                msg_type = 'Camera wake'
+            else:
+                msg_type = ''
+            if is_sys:
+                send_text = '{msg_type} channel:{channel}'. \
+                    format(msg_type=msg_type, channel=channel)
+            else:
+                send_text = '{msg_type} channel:{channel} date:{date}'. \
+                    format(msg_type=msg_type, channel=channel, date=n_date)
+        return send_text

+ 89 - 0
Controller/DeviceConfirmRegion.py

@@ -0,0 +1,89 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+"""
+@Copyright (C) ansjer cop Video Technology Co.,Ltd.All rights reserved.
+@software: PyCharm
+@Version: python3.6
+"""
+import datetime
+import traceback
+import time
+import logging
+import jwt
+import simplejson
+import simplejson as json
+import requests
+from django.contrib.auth.hashers import make_password, check_password  # 对密码加密模块
+from django.db.models import Q
+from django.http import HttpResponseRedirect
+from django.utils.decorators import method_decorator
+from django.utils.timezone import utc
+from django.views.decorators.csrf import csrf_exempt
+from django.views.generic import TemplateView
+from jwt.algorithms import RSAAlgorithm
+from ratelimit.decorators import ratelimit
+
+from Ansjer.config import AuthCode_Expire, SERVER_DOMAIN, APNS_CONFIG, JPUSH_CONFIG, FCM_CONFIG, TUTK_PUSH_DOMAIN
+from Controller.CheckUserData import DataValid, date_handler, RandomStr
+from Model.models import Device_User, Role, UidPushModel, UserOauth2Model, UserExModel, Device_Info, UidSetModel, \
+    UserAppFrequencyModel, CountryIPModel, CountryModel, RegionModel
+from Object.AWS.SesClassObject import SesClassObject
+from Object.AliSmsObject import AliSmsObject
+from Object.RedisObject import RedisObject
+from Object.ResponseObject import ResponseObject
+from Object.TokenObject import TokenObject
+from Service.CommonService import CommonService
+from Service.ModelService import ModelService
+from Service.TemplateService import TemplateService
+from django.views.generic import View
+import base64
+import random
+from io import BytesIO
+from PIL import Image, ImageDraw, ImageFont
+from django.shortcuts import HttpResponse
+from Ansjer.config import BASE_DIR
+
+#确认设备所在地区
+class ConfirmRegion(TemplateView):
+    @method_decorator(csrf_exempt)
+    def dispatch(self, *args, **kwargs):
+        return super(ConfirmRegion, self).dispatch(*args, **kwargs)
+
+    def get(self, request, *args, **kwargs):
+        response = ResponseObject()
+        request.encoding = 'utf-8'
+        # number = request.POST.get('number', None)
+        # selectRegion = CountryModel.objects.filter(number=number).values('region__api_url')
+        # if not selectRegion.exists():
+        #     return response.json(0,{"api_url":"https://test.dvema.com"})
+        # else:
+        #     return response.json(0,{"api_url":selectRegion[0]['region__api_url']})
+
+        # serial_number = request.POST.get('serial_number', None)
+        ip = CommonService.get_ip_address(request)
+        # ip = '14.102.176.0'
+        ipInfo = CommonService.getIpIpInfo(ip,"CN")
+        if ipInfo['country_code']:
+            device_request_url = CountryModel.objects.filter(country_code=ipInfo['country_code']).values("region__api")
+            if device_request_url.exists():
+                return response.json(0,{"request_api_url":device_request_url[0]['region__api']})
+
+        # 不存在默认返回美洲地区api。
+        api = RegionModel.objects.filter(continent_code='NA').values("api")
+        return response.json(0,{"request_api_url":api[0]['api']})
+
+#确认设备所在地区
+class Device_Region(object):
+
+    def get_device_region(self, ip):
+
+        ipInfo = CommonService.getIpIpInfo(ip, "CN")
+        if ipInfo['country_code']:
+            device_request_url = CountryModel.objects.filter(country_code=ipInfo['country_code']).values("region__api","region__id")
+            if device_request_url.exists():
+                return device_request_url[0]['region__id']
+        # 不存在默认返回美洲地区api
+        api = RegionModel.objects.filter(continent_code='NA').values("id")
+        return api[0]['id']
+
+

+ 23 - 2
Controller/DeviceShare.py

@@ -56,6 +56,8 @@ class DeviceShareView(View):
                     return self.do_query_user(userID, request_dict, response)
                     return self.do_query_user(userID, request_dict, response)
                 elif operation == 'deleteUser':
                 elif operation == 'deleteUser':
                     return self.do_delete_user(userID, request_dict, response)
                     return self.do_delete_user(userID, request_dict, response)
+                elif operation == 'deleteUserV2':
+                    return self.do_delete_userV2(userID, request_dict, response)
                 else:
                 else:
                     return response.json(414)
                     return response.json(414)
             else:
             else:
@@ -66,7 +68,7 @@ class DeviceShareView(View):
     def do_generate_token_url(self, userID, request_dict, response):
     def do_generate_token_url(self, userID, request_dict, response):
         UID = request_dict.get('UID', None)
         UID = request_dict.get('UID', None)
         dvqs = Device_Info.objects.filter(UID=UID, userID_id=userID, isShare=False).values('NickName')
         dvqs = Device_Info.objects.filter(UID=UID, userID_id=userID, isShare=False).values('NickName')
-        userqs = Device_User.objects.filter(userID=userID).values('username', 'userEmail', 'phone')
+        userqs = Device_User.objects.filter(userID=userID).values('username', 'userEmail', 'phone', 'userIconPath')
         if dvqs:
         if dvqs:
             data = {'sharer': userID, 'UID': UID}
             data = {'sharer': userID, 'UID': UID}
             # -----------------
             # -----------------
@@ -85,10 +87,18 @@ class DeviceShareView(View):
                 share_user = userqs[0]['phone']
                 share_user = userqs[0]['phone']
             else:
             else:
                 share_user = ''
                 share_user = ''
+
+            userIconPath = userqs[0]['userIconPath']
+            if userIconPath:
+                if userIconPath.find('static/') != -1:
+                    userIconPath = userIconPath.replace('static/', '').replace('\\', '/')
+                    userIconUrl = SERVER_DOMAIN + 'account/getAvatar/' + userIconPath
+
             return response.json(0, {
             return response.json(0, {
                 'shareToken': share_token,
                 'shareToken': share_token,
                 'deviceName': dvqs[0]['NickName'],
                 'deviceName': dvqs[0]['NickName'],
                 'shareUser': share_user,
                 'shareUser': share_user,
+                'userIconPath': userIconPath
             })
             })
 
 
         else:
         else:
@@ -229,10 +239,21 @@ class DeviceShareView(View):
             try:
             try:
                 # redisObj = RedisObject(db=8)
                 # redisObj = RedisObject(db=8)
                 # redisObj.del_data(key='uid_qs_' + userID)
                 # redisObj.del_data(key='uid_qs_' + userID)
-                Device_Info.objects.filter(id=id, primaryUserID=userID).update(isExist=0)
+                Device_Info.objects.filter(id=id, primaryUserID=userID).delete()
             except Exception as e:
             except Exception as e:
                 return response.json(10, repr(e))
                 return response.json(10, repr(e))
             else:
             else:
                 return response.json(0)
                 return response.json(0)
         else:
         else:
             return response.json(444, 'id')
             return response.json(444, 'id')
+
+    def do_delete_userV2(self, userID, request_dict, response):
+        ids = request_dict.get('ids', None)
+        if not ids:
+            return response.json(444, 'id')
+        try:
+            Device_Info.objects.filter(id__in=ids.split(','), primaryUserID=userID).delete()
+        except Exception as e:
+            return response.json(10, repr(e))
+        else:
+            return response.json(0)

+ 117 - 0
Controller/DeviceTypeController.py

@@ -0,0 +1,117 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+import time
+
+import oss2
+from django.views import View
+
+from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET
+from Model.models import DeviceTypeModel
+from Object.ResponseObject import ResponseObject
+from Object.TokenObject import TokenObject
+from Service.CommonService import CommonService
+from Service.ModelService import ModelService
+
+
+class DeviceTypeView(View):
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.GET
+        operation = kwargs.get('operation', None)
+        return self.validate(request_dict, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.POST
+        operation = kwargs.get('operation', None)
+        return self.validate(request_dict, operation)
+
+    def validate(self, request_dict, operation):
+        token = request_dict.get('token', None)
+        lang = request_dict.get('lang', None)
+
+        response = ResponseObject(lang=lang)
+        token = TokenObject(token)
+        if token.code != 0:
+            return response.json(token.code)
+
+        if operation == 'add':
+            return self.do_admin_add(token.userID, request_dict, response)
+        elif operation == 'query':
+            return self.do_query(request_dict, response)
+        elif operation == 'delete':
+            return self.do_admin_delete(token.userID, request_dict, response)
+        elif operation == 'getUploadUrl':
+            return self.get_upload_url(request_dict, response)
+        else:
+            return response.json(404)
+
+    def get_upload_url(self, request_dict, response):
+        upload_type = request_dict.get('upload_type', None)
+
+        if upload_type:
+            auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
+            bucket = oss2.Bucket(auth, 'oss-cn-shenzhen.aliyuncs.com', 'ansjer-static-resources')
+            name = CommonService.createOrderID()
+            filename = str(name) + '.' + upload_type
+            obj = 'device_type/' + filename
+            url = bucket.sign_url('PUT', obj, 7200)
+            return response.json(0, {'put_url': url, 'filename': filename})
+        else:
+            return response.json(444)
+
+    def do_admin_add(self, userID, request_dict, response):
+        own_perm = ModelService.check_perm(userID, 10)
+        if not own_perm:
+            return response.json(404)
+
+        name = request_dict.get('name', None)
+        model = request_dict.get('model', None)
+        type = request_dict.get('type', None)
+        ptz_type = request_dict.get('ptz_type', None)
+        icon = request_dict.get('icon', None)
+
+        if name and model and type and ptz_type and icon:
+            now_time = int(time.time())
+            device_type = DeviceTypeModel()
+            device_type.name = name
+            device_type.model = model
+            device_type.type = type
+            device_type.ptz_type = ptz_type
+            device_type.icon = icon
+            device_type.add_time = now_time
+            device_type.update_time = now_time
+            device_type.save()
+            return response.json(0)
+        else:
+            return response.json(444)
+
+    def do_query(self, request_dict, response):
+        device_type_qs = DeviceTypeModel.objects.filter().values('id', 'type', 'ptz_type', 'model', 'icon', 'name')
+        res = {}
+        data = []
+        res['data'] = data
+        if device_type_qs.exists():
+            for device_type in device_type_qs:
+                auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
+                bucket = oss2.Bucket(auth, 'oss-cn-shenzhen.aliyuncs.com', 'ansjer-static-resources')
+
+                icon = device_type['icon']
+                url = 'device_type/' + icon
+                device_type['icon'] = bucket.sign_url('GET', url, 3600)
+                data.append(device_type)
+
+        return response.json(0, res)
+
+    def do_admin_delete(self, userID, request_dict, response):
+        own_perm = ModelService.check_perm(userID, 10)
+        if not own_perm:
+            return response.json(404)
+
+        id = request_dict.get('id', None)
+        if id:
+            DeviceTypeModel.objects.filter(id=id).delete()
+            return response.json(0)
+        else:
+            return response.json(444)

+ 21 - 8
Controller/EquipmentInfo.py

@@ -84,6 +84,7 @@ class EquipmentInfo(View):
         if not device_info.exists():
         if not device_info.exists():
             return response.json(14)
             return response.json(14)
         try:
         try:
+
             nowTime = int(time.time())
             nowTime = int(time.time())
             equipment_info = Equipment_Info(
             equipment_info = Equipment_Info(
                 userID_id=userID,
                 userID_id=userID,
@@ -288,18 +289,30 @@ class EquipmentInfo(View):
 use information_schema;
 use information_schema;
 select concat(round(sum(data_length/1024/1024),2),'MB') as data from tables where table_schema='Ansjer81';
 select concat(round(sum(data_length/1024/1024),2),'MB') as data from tables where table_schema='Ansjer81';
 '''
 '''
-# 按季度删除访问日志
+# 删除访问日志
 def deleteExpireEquipmentInfo(request):
 def deleteExpireEquipmentInfo(request):
     response = ResponseObject()
     response = ResponseObject()
-    i = int(request.GET.get('i', 5))
-
     import time
     import time
     nowTime = int(time.time())
     nowTime = int(time.time())
-    for i in range(i):
-        ei = Equipment_Info.objects.filter(addTime__lte=str(nowTime - 3600 * 24 * 7))[0:10000]
-        id_list = ei.values_list("id", flat=True)
-        print(id_list)
-        Equipment_Info.objects.filter(id__in=list(id_list)).delete()
+    try:
+        for i in range(5):
+            ei = Equipment_Info.objects.filter(addTime__lte=str(nowTime - 3600 * 24 * 7))[0:10000]
+            id_list = list(ei.values_list("id", flat=True))
+            Equipment_Info.objects.filter(id__in=id_list).delete()
+        return response.json(0)
+    except Exception as e:
+        return response.json(500, repr(e))
+
+
+# 按季度删除访问日志
+def deleteExpireEquipmentInfoById(request):
+    response = ResponseObject()
+    id = int(request.GET.get('id', None))
+
+    if id is None:
+        return response.json(0)
+
+    Equipment_Info.objects.filter(id__lte=id).delete()
     return response.json(0)
     return response.json(0)
 
 
 
 

+ 214 - 23
Controller/EquipmentManager.py

@@ -3,9 +3,12 @@ import time
 import traceback
 import traceback
 import threading
 import threading
 import logging
 import logging
+
+import requests
 import simplejson as json
 import simplejson as json
 from django.utils import timezone
 from django.utils import timezone
-from Model.models import Device_User, Device_Info, UID_Bucket, UID_Preview, UidSetModel, UidPushModel
+from Model.models import Device_User, Device_Info, UID_Bucket, UID_Preview, UidSetModel, UidPushModel, \
+    UIDCompanySerialModel, iotdeviceInfoModel, UIDMainUser
 from django.db.models import Q
 from django.db.models import Q
 from Object.ResponseObject import ResponseObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Object.TokenObject import TokenObject
@@ -16,6 +19,7 @@ from Object.ETkObject import ETkObject
 import oss2
 import oss2
 from django.http import JsonResponse
 from django.http import JsonResponse
 from Object.RedisObject import RedisObject
 from Object.RedisObject import RedisObject
+from Controller.DetectController import DetectControllerView
 
 
 
 
 #     查询用户设备
 #     查询用户设备
@@ -158,16 +162,19 @@ def delUserEquipmentInterface(request):
         dv_qs = Device_Info.objects.filter(userID_id=userID, id=id)
         dv_qs = Device_Info.objects.filter(userID_id=userID, id=id)
         # redisObj = RedisObject(db=8)
         # redisObj = RedisObject(db=8)
         # redisObj.del_data(key='uid_qs_' + userID)
         # redisObj.del_data(key='uid_qs_' + userID)
+
         if dv_qs.exists():
         if dv_qs.exists():
             uid = dv_qs[0].UID
             uid = dv_qs[0].UID
-            asy = threading.Thread(target=ModelService.delete_log,
-                                   args=(CommonService.get_ip_address(request), userID, 'deleteV1', uid))
+            asy = threading.Thread(target=ModelService.add_log, args=(CommonService.get_ip_address(request), userID, 'deleteV1'))
             asy.start()
             asy.start()
+
             print('删除')
             print('删除')
             UID_Preview.objects.filter(uid=uid).delete()
             UID_Preview.objects.filter(uid=uid).delete()
             dv_qs.delete()
             dv_qs.delete()
+            Device_Info.objects.filter(UID=uid).update(vodPrimaryUserID='', vodPrimaryMaster='')
             asy = threading.Thread(target=ModelService.del_eq_info, args=(userID, uid))
             asy = threading.Thread(target=ModelService.del_eq_info, args=(userID, uid))
             asy.start()
             asy.start()
+
     except Exception as e:
     except Exception as e:
         errorInfo = traceback.format_exc()
         errorInfo = traceback.format_exc()
         print('删除数据库记录错误: %s' % errorInfo)
         print('删除数据库记录错误: %s' % errorInfo)
@@ -360,6 +367,9 @@ def addInterface(request):
     View_Password = request_dict.get('View_Password', '')
     View_Password = request_dict.get('View_Password', '')
     Type = request_dict.get('Type', None)
     Type = request_dict.get('Type', None)
     ChannelIndex = request_dict.get('ChannelIndex', None)
     ChannelIndex = request_dict.get('ChannelIndex', None)
+    version = request_dict.get('version', '')
+    isCheckMainUser = request_dict.get('isCheckMainUser', None)
+    isMainUserExists = False
     if all([UID, NickName, View_Account, Type, ChannelIndex]):
     if all([UID, NickName, View_Account, Type, ChannelIndex]):
         tko = TokenObject(token)
         tko = TokenObject(token)
         response.lang = tko.lang
         response.lang = tko.lang
@@ -380,10 +390,67 @@ def addInterface(request):
                     asy.start()
                     asy.start()
                     return response.json(10, 'illegal uid: {uid}'.format(uid=UID))
                     return response.json(10, 'illegal uid: {uid}'.format(uid=UID))
                 pass
                 pass
-                # is_bind = Device_Info.objects.filter(UID=UID, isShare=False)
-                # # 判断是否有已绑定用户
-                # if is_bind:
-                #     return response.json(15)
+
+                pk = CommonService.getUserID(getUser=False)
+                userName = Device_User.objects.get(userID=userID).username
+                main_exist = Device_Info.objects.filter(UID=UID)
+                main_exist = main_exist.filter(~Q(vodPrimaryUserID='')).values('vodPrimaryUserID', 'vodPrimaryMaster')
+
+                vodPrimaryUserID = userID
+                vodPrimaryMaster = userName
+                primaryUserID = ''
+                primaryMaster = ''
+                isShare = False
+
+                is_bind = Device_Info.objects.filter(UID=UID, isShare=False).values('userID__userID', 'primaryUserID', 'primaryMaster')
+
+                if main_exist.exists():
+                    vodPrimaryUserID = main_exist[0]['vodPrimaryUserID']
+                    vodPrimaryMaster = main_exist[0]['vodPrimaryMaster']
+
+                if is_bind.exists():
+                    primaryUserID = is_bind[0]['primaryUserID']
+                    primaryMaster = is_bind[0]['primaryMaster']
+                    isShare = True
+
+                isusermain = False
+                if (vodPrimaryUserID != userID and vodPrimaryUserID != '') or (primaryUserID != userID and primaryUserID != ''):
+                    isusermain = True
+
+                # 判断是否有已绑定用户
+                if isCheckMainUser == '1' and isusermain:
+                    res = {
+                        'id': pk,
+                        'userID': userID,
+                        'NickName': NickName,
+                        'UID': UID,
+                        'View_Account': View_Account,
+                        'View_Password': View_Password,
+                        'ChannelIndex': ChannelIndex,
+                        'Type': Type,
+                        'isShare': isShare,
+                        'primaryUserID': primaryUserID,
+                        'primaryMaster': primaryMaster,
+                        'vodPrimaryUserID': vodPrimaryUserID,
+                        'vodPrimaryMaster': vodPrimaryMaster,
+                        'data_joined': '',
+                        'version': version,
+                        'isVod': 0,
+                        'isExist': 1,
+                        'userID__userEmail': ''
+                    }
+                    res['vod'] = [
+                        {
+                            "status": 1,
+                            "channel": ChannelIndex,
+                            "endTime": '',
+                            "bucket__content": '',
+                            "uid": UID
+                        }
+                    ]
+                    res['isMainUserExists'] = 1
+                    return response.json(0, res)
+
                 try:
                 try:
                     # 判断是否有用户绑定
                     # 判断是否有用户绑定
                     nowTime = int(time.time())
                     nowTime = int(time.time())
@@ -396,16 +463,34 @@ def addInterface(request):
                             'ip': CommonService.get_ip_address(request),
                             'ip': CommonService.get_ip_address(request),
                             'channel': ChannelIndex,
                             'channel': ChannelIndex,
                             'nickname': NickName,
                             'nickname': NickName,
+                            'version': version,
                         }
                         }
                         UidSetModel.objects.create(**uid_set_create_dict)
                         UidSetModel.objects.create(**uid_set_create_dict)
                     else:
                     else:
                         us_qs.update(nickname=NickName)
                         us_qs.update(nickname=NickName)
-                    pk = CommonService.getUserID(getUser=False)
+
                     userDevice = Device_Info(id=pk, userID_id=userID, UID=UID,
                     userDevice = Device_Info(id=pk, userID_id=userID, UID=UID,
                                              NickName=NickName, View_Account=View_Account,
                                              NickName=NickName, View_Account=View_Account,
-                                             View_Password=View_Password, Type=Type, ChannelIndex=ChannelIndex)
+                                             View_Password=View_Password, Type=Type, ChannelIndex=ChannelIndex,
+                                             version=version, vodPrimaryUserID=vodPrimaryUserID, vodPrimaryMaster=vodPrimaryMaster)
                     userDevice.save()
                     userDevice.save()
-                    # redisObj = RedisObject(db=8)
+                    uid_serial_qs = UIDCompanySerialModel.objects.filter(
+                        uid__uid=UID)
+                    if uid_serial_qs.exists():
+                        uid_serial = uid_serial_qs[0]
+                        Device_Info.objects.filter(UID=UID).update(vodPrimaryUserID=vodPrimaryUserID,
+                                                                   vodPrimaryMaster=vodPrimaryMaster,
+                                                                   serial_number=uid_serial.company_serial.serial_number + uid_serial.company_serial.company.mark)
+                    else:
+                        Device_Info.objects.filter(UID=UID).update(vodPrimaryUserID=vodPrimaryUserID,
+                                                                   vodPrimaryMaster=vodPrimaryMaster)
+                    # if isCheckMainUser == '1':
+                    #     uid_main_dict = {
+                    #         'UID': UID,
+                    #         'user_id': vodPrimaryUserID
+                    #     }
+                    #     UIDMainUser.objects.create(**uid_main_dict)
+                # redisObj = RedisObject(db=8)
                     # redisObj.del_data(key='uid_qs_' + userID)
                     # redisObj.del_data(key='uid_qs_' + userID)
                 except Exception as e:
                 except Exception as e:
                     return response.json(10, repr(e))
                     return response.json(10, repr(e))
@@ -414,14 +499,26 @@ def addInterface(request):
                                                                     'View_Account',
                                                                     'View_Account',
                                                                     'View_Password', 'ChannelIndex', 'Type',
                                                                     'View_Password', 'ChannelIndex', 'Type',
                                                                     'isShare',
                                                                     'isShare',
-                                                                    'primaryUserID', 'primaryMaster',
+                                                                    'primaryUserID', 'primaryMaster', 'vodPrimaryUserID', 'vodPrimaryMaster', 'userID__userEmail',
                                                                     'data_joined', 'version',
                                                                     'data_joined', 'version',
-                                                                    'isVod', 'isExist')
+                                                                    'isVod', 'isExist', 'isCameraOpenCloud', 'serial_number')
                     dvql = CommonService.qs_to_list(dvqs)
                     dvql = CommonService.qs_to_list(dvqs)
                     ubqs = UID_Bucket.objects.filter(uid=UID). \
                     ubqs = UID_Bucket.objects.filter(uid=UID). \
                         values('bucket__content', 'status', 'channel', 'endTime', 'uid')
                         values('bucket__content', 'status', 'channel', 'endTime', 'uid')
                     res = dvql[0]
                     res = dvql[0]
                     res['vod'] = list(ubqs)
                     res['vod'] = list(ubqs)
+
+
+                    # 新增获取IOT证书内容
+                    iotqs = iotdeviceInfoModel.objects.filter(serial_number=dvql[0]['serial_number'])
+                    if iotqs.exists():
+                        res['iot'] = {
+                                'endpoint': iotqs[0].endpoint,
+                                'token_iot_number': iotqs[0].endpoint
+                        }
+
+                    if isMainUserExists:
+                        res['isMainUserExists'] = 1
                     return response.json(0, res)
                     return response.json(0, res)
 
 
 
 
@@ -430,7 +527,7 @@ def addInterface(request):
         else:
         else:
             return response.json(tko.code)
             return response.json(tko.code)
     else:
     else:
-        return response.json(444, {'param': 'UID,NickName,View_Account,View_Password,Type,ChannelIndex'})
+        return response.json(444, {'param': 'UID,NickName,View_Account,View_Password,Type,ChannelIndex,version'})
 
 
 
 
 # 添加设备字段
 # 添加设备字段
@@ -682,6 +779,9 @@ def deleteInterface(request):
             asy = threading.Thread(target=ModelService.delete_log,
             asy = threading.Thread(target=ModelService.delete_log,
                                    args=(CommonService.get_ip_address(request), userID, 'deleteV2', uid))
                                    args=(CommonService.get_ip_address(request), userID, 'deleteV2', uid))
             asy.start()
             asy.start()
+            if userID == dv_qs[0].vodPrimaryUserID:
+                Device_Info.objects.filter(UID=uid).update(vodPrimaryUserID='', vodPrimaryMaster='')
+
             if dv_qs[0].isShare:
             if dv_qs[0].isShare:
                 dv_qs.delete()
                 dv_qs.delete()
             else:
             else:
@@ -689,6 +789,7 @@ def deleteInterface(request):
                 dv_qs.delete()
                 dv_qs.delete()
                 # 删除设备影子信息uid_set   外键关联删除设备推送配置信息 uid_push
                 # 删除设备影子信息uid_set   外键关联删除设备推送配置信息 uid_push
                 up_qs = UidPushModel.objects.filter(uid_set__uid=uid)
                 up_qs = UidPushModel.objects.filter(uid_set__uid=uid)
+                DetectControllerView().do_delete_redis(uid)
                 if up_qs.count() > 1:
                 if up_qs.count() > 1:
                     UidPushModel.objects.filter(uid_set__uid=uid, userID_id=userID).delete()
                     UidPushModel.objects.filter(uid_set__uid=uid, userID_id=userID).delete()
                     redisObj = RedisObject(db=6, SERVER_HOST='push.dvema.com')
                     redisObj = RedisObject(db=6, SERVER_HOST='push.dvema.com')
@@ -697,10 +798,8 @@ def deleteInterface(request):
                         redisObj.del_data(key=ykey)
                         redisObj.del_data(key=ykey)
                 else:
                 else:
                     up_qs.delete()
                     up_qs.delete()
-                # b.分享获得用户假删除
-                ud_dv_qs = Device_Info.objects.filter(UID=uid, isShare=True, primaryUserID=userID)
-                if ud_dv_qs.exists():
-                    ud_dv_qs.update(isExist=0)
+                # b.删除次用户设备
+                Device_Info.objects.filter(UID=uid, isShare=True, primaryUserID=userID).delete()
                 # 异步删除推送消息
                 # 异步删除推送消息
             asy = threading.Thread(target=ModelService.del_eq_info, args=(userID, uid))
             asy = threading.Thread(target=ModelService.del_eq_info, args=(userID, uid))
             asy.start()
             asy.start()
@@ -715,6 +814,71 @@ def deleteInterface(request):
     else:
     else:
         return response.json(0)
         return response.json(0)
 
 
+# 批量删除设备
+def batchDeleteInterface(request):
+    '''
+    批量删除用户设备
+    :param request: token,ids
+    :return:
+    '''
+    response = ResponseObject()
+    request.encoding = 'utf-8'
+    if request.method == 'POST':
+        request_dict = request.POST
+    elif request.method == 'GET':
+        request_dict = request.GET
+    else:
+        return response.json(444)
+    token = request_dict.get('token', None)
+    ids = request_dict.get('ids', None)
+    if not ids:
+        return response.json(444, 'ids')
+    tko = TokenObject(token)
+    response.lang = tko.lang
+    if tko.code != 0:
+        return response.json(tko.code)
+    userID = tko.userID
+    # userID = request_dict.get('userID', None)   # 调试
+    # 主用户删除设备全部删除
+    if not userID:
+        return response.json(309)
+    try:
+        deviceInfo_qs = Device_Info.objects.filter(userID_id=userID, id__in=ids.split(','))
+        if not deviceInfo_qs.exists():
+            return response.json(14)
+        for deviceInfo in deviceInfo_qs:
+            uid = deviceInfo.UID
+            asy = threading.Thread(target=ModelService.delete_log,
+                                   args=(CommonService.get_ip_address(request), userID, 'deleteV2', uid))
+            asy.start()
+            if userID == deviceInfo.vodPrimaryUserID:
+                Device_Info.objects.filter(UID=uid).update(vodPrimaryUserID='', vodPrimaryMaster='')
+
+            deviceInfo.delete()
+            if not deviceInfo.isShare:
+                # a.主用户删除设备
+                # 删除设备影子信息uid_set   外键关联删除设备推送配置信息 uid_push
+                up_qs = UidPushModel.objects.filter(uid_set__uid=uid)
+                DetectControllerView().do_delete_redis(uid)
+                if up_qs.count() > 1:
+                    UidPushModel.objects.filter(uid_set__uid=uid, userID_id=userID).delete()
+                    redisObj = RedisObject(db=6, SERVER_HOST='push.dvema.com')
+                    ykey = '{uid}_redis_qs'.format(uid=uid)
+                    if ykey:
+                        redisObj.del_data(key=ykey)
+                else:
+                    up_qs.delete()
+                # b.删除次用户设备
+                Device_Info.objects.filter(UID=uid, isShare=True, primaryUserID=userID).delete()
+                    # 异步删除推送消息
+            asy = threading.Thread(target=ModelService.del_eq_info, args=(userID, uid))
+            asy.start()
+    except Exception as e:
+        errorInfo = traceback.format_exc()
+        print('删除数据库记录错误: %s' % errorInfo)
+        return response.json(176, repr(e))
+    else:
+        return response.json(0)
 
 
 # 新查询设备字段
 # 新查询设备字段
 def queryInterface(request):
 def queryInterface(request):
@@ -749,14 +913,23 @@ def queryInterface(request):
         # count = dvqs.count()
         # count = dvqs.count()
         dvql = dvqs[(page - 1) * line:page * line].values('id', 'userID', 'NickName', 'UID', 'View_Account',
         dvql = dvqs[(page - 1) * line:page * line].values('id', 'userID', 'NickName', 'UID', 'View_Account',
                                                           'View_Password', 'ChannelIndex', 'Type', 'isShare',
                                                           'View_Password', 'ChannelIndex', 'Type', 'isShare',
-                                                          'primaryUserID', 'primaryMaster', 'data_joined', 'version',
-                                                          'isVod', 'isExist', 'NotificationMode')
+                                                          'primaryUserID', 'primaryMaster', 'data_joined', 'version', 'vodPrimaryUserID', 'vodPrimaryMaster', 'userID__userEmail',
+                                                          'isVod', 'isExist', 'NotificationMode', 'isCameraOpenCloud', 'serial_number')
         dvls = CommonService.qs_to_list(dvql)
         dvls = CommonService.qs_to_list(dvql)
         uid_list = []
         uid_list = []
+        serial_number_list = []
         for dvl in dvls:
         for dvl in dvls:
+            if dvl['primaryUserID'] and dvl['id'] == dvl['primaryUserID']:
+                dvl['isPrimaryUser'] = 1
+            else:
+                dvl['isPrimaryUser'] = 0
             uid_list.append(dvl['UID'])
             uid_list.append(dvl['UID'])
-            # if dvl['isShare'] is False:
-            #     uid_list.append(dvl['UID'])
+            serial_number_list.append(dvl['serial_number'][0:6])
+
+
+        #新增获取IOT证书内容
+        iotqs = iotdeviceInfoModel.objects.filter(serial_number__in=serial_number_list)
+
         ubqs = UID_Bucket.objects.filter(uid__in=uid_list). \
         ubqs = UID_Bucket.objects.filter(uid__in=uid_list). \
             values('bucket__content', 'status', 'channel', 'endTime', 'uid')
             values('bucket__content', 'status', 'channel', 'endTime', 'uid')
         upqs = UID_Preview.objects.filter(uid__in=uid_list).order_by('channel').values('id', 'uid', 'channel')
         upqs = UID_Preview.objects.filter(uid__in=uid_list).order_by('channel').values('id', 'uid', 'channel')
@@ -772,7 +945,20 @@ def queryInterface(request):
             uv_dict[us['uid']] = {'version': us['version'],
             uv_dict[us['uid']] = {'version': us['version'],
                                   'nickname': us['nickname'],
                                   'nickname': us['nickname'],
                                   'detect_interval': us['detect_interval']}
                                   'detect_interval': us['detect_interval']}
+
         for p in dvls:
         for p in dvls:
+            #新增IOT
+            p['iot'] = []
+            for iot in iotqs:
+                if p['serial_number'][0:6] == iot.serial_number:
+                        p['iot'].append(
+                            {
+                                'endpoint':iot.endpoint,
+                                'token_iot_number':iot.token_iot_number
+
+                            }
+                        )
+
             p['vod'] = []
             p['vod'] = []
             for dm in ubqs:
             for dm in ubqs:
                 if p['UID'] == dm['uid']:
                 if p['UID'] == dm['uid']:
@@ -1010,10 +1196,15 @@ def update_device_shadow(request):
         is_reset = request_dict.get('is_reset', None)
         is_reset = request_dict.get('is_reset', None)
         # 传1则重置设备信息
         # 传1则重置设备信息
         if is_reset == '1':
         if is_reset == '1':
+
             UidSetModel.objects.filter(uid=uid).delete()
             UidSetModel.objects.filter(uid=uid).delete()
             # 重置设备,判断设备为已删除
             # 重置设备,判断设备为已删除
-            di_qs = Device_Info.objects.filter(UID=uid)
-            di_qs.update(isExist=2)
+            nowTime = int(time.time())
+            uid_bucket = UID_Bucket.objects.filter(uid=uid, endTime__gte=nowTime).values('id', 'has_unused').order_by('addTime')
+            if not uid_bucket.exists():
+                di_qs = Device_Info.objects.filter(UID=uid)
+                di_qs.update(isExist=2)
+
             # 清除redis缓存
             # 清除redis缓存
             # data = di_qs.values()
             # data = di_qs.values()
             # redisObj = RedisObject(db=8)
             # redisObj = RedisObject(db=8)

+ 184 - 11
Controller/EquipmentManagerV2.py

@@ -8,7 +8,8 @@ from django.db.models import Q
 from django.views.generic.base import View
 from django.views.generic.base import View
 
 
 from Ansjer.config import OSS_STS_ACCESS_SECRET, OSS_STS_ACCESS_KEY
 from Ansjer.config import OSS_STS_ACCESS_SECRET, OSS_STS_ACCESS_KEY
-from Model.models import Device_Info, UID_Bucket, UID_Preview, UidSetModel, UidPushModel
+from Model.models import Device_Info, UID_Bucket, UID_Preview, UidSetModel, UidPushModel, UidChannelSetModel, \
+    iotdeviceInfoModel
 from Object.ResponseObject import ResponseObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Object.TokenObject import TokenObject
 from Service.CommonService import CommonService
 from Service.CommonService import CommonService
@@ -146,15 +147,24 @@ class EquipmentManagerV2(View):
             dvql = dvqs[(page - 1) * line:page * line]. \
             dvql = dvqs[(page - 1) * line:page * line]. \
                 values('id', 'userID', 'NickName', 'UID', 'View_Account',
                 values('id', 'userID', 'NickName', 'UID', 'View_Account',
                        'View_Password', 'ChannelIndex', 'Type', 'isShare',
                        'View_Password', 'ChannelIndex', 'Type', 'isShare',
-                       'primaryUserID', 'primaryMaster', 'data_joined',
+                       'primaryUserID', 'primaryMaster', 'data_joined', 'vodPrimaryUserID', 'vodPrimaryMaster', 'userID__userEmail',
                        'version',
                        'version',
-                       'isVod', 'isExist', 'NotificationMode')
+                       'isVod', 'isExist', 'NotificationMode', 'isCameraOpenCloud', 'serial_number')
             dvls = CommonService.qs_to_list(dvql)
             dvls = CommonService.qs_to_list(dvql)
+
             uid_list = []
             uid_list = []
+            serial_number_list = []
             for dvl in dvls:
             for dvl in dvls:
+                if dvl['primaryUserID'] and dvl['id'] == dvl['primaryUserID']:
+                    dvl['isPrimaryUser'] = 1
+                else:
+                    dvl['isPrimaryUser'] = 0
                 uid_list.append(dvl['UID'])
                 uid_list.append(dvl['UID'])
-                # if dvl['isShare'] is False:
-                #     uid_list.append(dvl['UID'])
+                serial_number_list.append(dvl['serial_number'][0:6])
+
+            # 新增获取IOT证书内容
+            iotqs = iotdeviceInfoModel.objects.filter(serial_number__in=serial_number_list)
+
             ubqs = UID_Bucket.objects.filter(uid__in=uid_list). \
             ubqs = UID_Bucket.objects.filter(uid__in=uid_list). \
                 values('bucket__content', 'status', 'channel', 'endTime', 'uid')
                 values('bucket__content', 'status', 'channel', 'endTime', 'uid')
             upqs = UID_Preview.objects.filter(uid__in=uid_list).order_by('channel').values('id', 'uid', 'channel')
             upqs = UID_Preview.objects.filter(uid__in=uid_list).order_by('channel').values('id', 'uid', 'channel')
@@ -163,11 +173,30 @@ class EquipmentManagerV2(View):
             nowTime = int(time.time())
             nowTime = int(time.time())
             data = []
             data = []
             # 设备拓展信息表
             # 设备拓展信息表
-            us_qs = UidSetModel.objects.filter(uid__in=uid_list).values('uid', 'version', 'nickname', 'ucode','detect_interval')
+            us_qs = UidSetModel.objects.filter(uid__in=uid_list).values('uid', 'version', 'nickname', 'ucode','detect_interval', 'is_human', 'is_custom_voice')
             uv_dict = {}
             uv_dict = {}
             for us in us_qs:
             for us in us_qs:
-                uv_dict[us['uid']] = {'version': us['version'], 'nickname': us['nickname'], 'ucode': us['ucode'],'detect_interval':us['detect_interval']}
+                uv_dict[us['uid']] = {
+                    'version': us['version'],
+                    'nickname': us['nickname'],
+                    'ucode': us['ucode'],
+                    'detect_interval': us['detect_interval'],
+                    'is_human': us['is_human'],
+                    'is_custom_voice': us['is_custom_voice'],
+                }
             for p in dvls:
             for p in dvls:
+                # 新增云分配UID
+                p['iot'] = []
+                for iot in iotqs:
+                    if p['serial_number'][0:6] == iot.serial_number:
+                        p['iot'].append(
+                            {
+                                'endpoint': iot.endpoint,
+                                'token_iot_number': iot.token_iot_number
+
+                            }
+                        )
+
                 p['vod'] = []
                 p['vod'] = []
                 for dm in ubqs:
                 for dm in ubqs:
                     if p['UID'] == dm['uid']:
                     if p['UID'] == dm['uid']:
@@ -185,6 +214,8 @@ class EquipmentManagerV2(View):
                     p['uid_version'] = uv_dict[p_uid]['version']
                     p['uid_version'] = uv_dict[p_uid]['version']
                     p['ucode'] = uv_dict[p_uid]['ucode']
                     p['ucode'] = uv_dict[p_uid]['ucode']
                     p['detect_interval'] = uv_dict[p_uid]['detect_interval']
                     p['detect_interval'] = uv_dict[p_uid]['detect_interval']
+                    p['is_human'] = uv_dict[p_uid]['is_human']
+                    p['is_custom_voice'] = uv_dict[p_uid]['is_custom_voice']
                     # 设备昵称 调用影子信息昵称,先阶段不可
                     # 设备昵称 调用影子信息昵称,先阶段不可
                     if uv_dict[p_uid]['nickname']:
                     if uv_dict[p_uid]['nickname']:
                         p['NickName'] = uv_dict[p_uid]['nickname']
                         p['NickName'] = uv_dict[p_uid]['nickname']
@@ -202,7 +233,149 @@ class EquipmentManagerV2(View):
 
 
     def do_query_reset(self, userID, request_dict, response):
     def do_query_reset(self, userID, request_dict, response):
         dvqs = Device_Info.objects.filter(userID_id=userID, isExist=2)
         dvqs = Device_Info.objects.filter(userID_id=userID, isExist=2)
-        dvql = dvqs.values \
-            ('id', 'NickName', 'UID', 'ChannelIndex', 'Type', 'isShare')
-        res = CommonService.qs_to_list(dvql)
-        return response.json(0, res)
+        dvql = dvqs.values('id', 'userID', 'NickName', 'UID', 'View_Account',
+                           'View_Password', 'ChannelIndex', 'Type', 'isShare',
+                           'primaryUserID', 'primaryMaster', 'data_joined', 'vodPrimaryUserID', 'vodPrimaryMaster',
+                           'userID__userEmail',
+                           'version', 'isVod', 'isExist', 'NotificationMode', 'isCameraOpenCloud', 'serial_number')
+        dvls = CommonService.qs_to_list(dvql)
+        uid_list = []
+        serial_number_list = []
+        for dvl in dvls:
+            if dvl['primaryUserID'] and dvl['id'] == dvl['primaryUserID']:
+                dvl['isPrimaryUser'] = 1
+            else:
+                dvl['isPrimaryUser'] = 0
+            uid_list.append(dvl['UID'])
+            serial_number_list.append(dvl['serial_number'])
+
+        # 新增获取IOT证书内容
+        iotqs = iotdeviceInfoModel.objects.filter(serial_number__in=serial_number_list)
+
+        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('id', 'uid', 'version', 'nickname', 'ucode',
+                                                                    'detect_status', 'detect_group',
+                                                                    'detect_interval',
+                                                                    'region_alexa', 'is_alexa', 'deviceModel',
+                                                                    'TimeZone', 'TimeStatus', 'SpaceUsable',
+                                                                    'SpaceSum', 'MirrorType', 'RecordType',
+                                                                    'OutdoorModel', 'WIFIName', 'isDetector',
+                                                                    'DetectorRank')
+        uv_dict = {}
+        for us in us_qs:
+            uv_dict[us['uid']] = {
+                'version': us['version'],
+                'nickname': us['nickname'],
+                'ucode': us['ucode'],
+                'detect_interval': us['detect_interval'],
+                'detect_group': us['detect_group'],
+                'detect_status': us['detect_status'],
+                'region_alexa': us['region_alexa'],
+                'is_alexa': us['is_alexa'],
+                'deviceModel': us['deviceModel'],
+                'TimeZone': us['TimeZone'],
+                'TimeStatus': us['TimeStatus'],
+                'SpaceUsable': us['SpaceUsable'],
+                'SpaceSum': us['SpaceSum'],
+                'MirrorType': us['MirrorType'],
+                'RecordType': us['RecordType'],
+                'OutdoorModel': us['OutdoorModel'],
+                'WIFIName': us['WIFIName'],
+                'isDetector': us['isDetector'],
+                'DetectorRank': us['DetectorRank']
+            }
+            # 从uid_channel里面取出通道配置信息
+            ucs_qs = UidChannelSetModel.objects.filter(uid__id=us['id']).values('channel', 'pir_audio', 'mic_audio',
+                                                                                'battery_status', 'battery_level',
+                                                                                'sleep_status', 'sleep_time',
+                                                                                'light_night_model',
+                                                                                'light_alarm_type',
+                                                                                'light_alarm_level',
+                                                                                'light_alarm_man_en',
+                                                                                'light_alarm_vol',
+                                                                                'light_long_light'
+                                                                                )
+            channels = []
+            for ucs in ucs_qs:
+                channels_dict = {
+                    'channel': ucs['channel'],
+                    'pir_audio': ucs['pir_audio'],
+                    'mic_audio': ucs['mic_audio'],
+                    'battery_status': ucs['battery_status'],
+                    'battery_level': ucs['battery_level'],
+                    'sleep_status': ucs['sleep_status'],
+                    'sleep_time': ucs['sleep_time'],
+                    'light_night_model': ucs['light_night_model'],
+                    'light_alarm_type': ucs['light_alarm_type'],
+                    'light_alarm_level': ucs['light_alarm_level'],
+                    'light_alarm_man_en': ucs['light_alarm_man_en'],
+                    'light_alarm_vol': ucs['light_alarm_vol'],
+                    'light_long_light': ucs['light_long_light']
+                }
+                channels.append(channels_dict)
+            uv_dict[us['uid']]['channels'] = channels
+
+        for p in dvls:
+            # 新增IOT
+            p['iot'] = []
+            for iot in iotqs:
+                if p['serial_number'][0:6] == iot.serial_number:
+                    p['iot'].append(
+                        {
+                            'endpoint': iot.endpoint,
+                            'token_iot_number': iot.token_iot_number
+
+                        }
+                    )
+
+            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['ucode'] = uv_dict[p_uid]['ucode']
+                p['detect_interval'] = uv_dict[p_uid]['detect_interval']
+                p['detect_status'] = uv_dict[p_uid]['detect_status']
+                p['detect_group'] = uv_dict[p_uid]['detect_group']
+                p['region_alexa'] = uv_dict[p_uid]['region_alexa']
+                p['is_alexa'] = uv_dict[p_uid]['is_alexa']
+                p['deviceModel'] = uv_dict[p_uid]['deviceModel']
+                p['TimeZone'] = uv_dict[p_uid]['TimeZone']
+                p['TimeStatus'] = uv_dict[p_uid]['TimeStatus']
+                p['SpaceUsable'] = uv_dict[p_uid]['SpaceUsable']
+                p['SpaceSum'] = uv_dict[p_uid]['SpaceSum']
+                p['MirrorType'] = uv_dict[p_uid]['MirrorType']
+                p['RecordType'] = uv_dict[p_uid]['RecordType']
+                p['OutdoorModel'] = uv_dict[p_uid]['OutdoorModel']
+                p['WIFIName'] = uv_dict[p_uid]['WIFIName']
+                p['isDetector'] = uv_dict[p_uid]['isDetector']
+                p['DetectorRank'] = uv_dict[p_uid]['DetectorRank']
+                p['channels'] = uv_dict[p_uid]['channels']
+                # 设备昵称 调用影子信息昵称,先阶段不可
+                if uv_dict[p_uid]['nickname']:
+                    p['NickName'] = uv_dict[p_uid]['nickname']
+            else:
+                # 设备版本号
+                p['uid_version'] = ''
+                p['ucode'] = ''
+            data.append(p)
+        result = data
+
+        return response.json(0, result)

+ 656 - 249
Controller/EquipmentManagerV3.py

@@ -2,18 +2,24 @@ import re
 import threading
 import threading
 import time
 import time
 import traceback
 import traceback
+
+import requests
+
 from Controller.CheckUserData import RandomStr
 from Controller.CheckUserData import RandomStr
 import oss2, base64
 import oss2, base64
 from django.db.models import Q
 from django.db.models import Q
 from django.views.generic.base import View
 from django.views.generic.base import View
+from Controller.DeviceConfirmRegion import Device_Region
 from Object.RedisObject import RedisObject
 from Object.RedisObject import RedisObject
 from Ansjer.config import OSS_STS_ACCESS_SECRET, OSS_STS_ACCESS_KEY, BASE_DIR
 from Ansjer.config import OSS_STS_ACCESS_SECRET, OSS_STS_ACCESS_KEY, BASE_DIR
-from Model.models import Device_Info, UID_Bucket, UID_Preview, UidSetModel, UidPushModel, UidChannelSetModel
+from Model.models import Device_Info, UID_Bucket, UID_Preview, UidSetModel, UidPushModel, UidChannelSetModel, \
+    Device_User, iotdeviceInfoModel, UIDCompanySerialModel, UIDMainUser, UIDModel
 from Object.ResponseObject import ResponseObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Object.TokenObject import TokenObject
 from Service.CommonService import CommonService
 from Service.CommonService import CommonService
 from Service.ModelService import ModelService
 from Service.ModelService import ModelService
-import time,json
+import time, json
+
 
 
 class EquipmentManagerV3(View):
 class EquipmentManagerV3(View):
 
 
@@ -24,6 +30,7 @@ class EquipmentManagerV3(View):
 
 
     def post(self, request, *args, **kwargs):
     def post(self, request, *args, **kwargs):
         request.encoding = 'utf-8'
         request.encoding = 'utf-8'
+
         operation = kwargs.get('operation')
         operation = kwargs.get('operation')
         return self.validation(request.POST, request, operation)
         return self.validation(request.POST, request, operation)
 
 
@@ -31,111 +38,212 @@ class EquipmentManagerV3(View):
         response = ResponseObject()
         response = ResponseObject()
         token = request_dict.get('token', None)
         token = request_dict.get('token', None)
         # 设备主键uid
         # 设备主键uid
+
+        if operation == 'notLoginMainUserDevice':
+            return self.not_login_do_mainUserDevice(request_dict, response)
+
         tko = TokenObject(token)
         tko = TokenObject(token)
-        if tko.code == 0:
-            response.lang = tko.lang
-            userID = tko.userID
-            # 手机端添加设备,查询,修改
-            if operation == 'add':
-                return self.do_add(userID, request_dict, response, request)
-            elif operation == 'query':
-                return self.do_query(userID, request_dict, response)
-            elif operation == 'modify':
-                return self.do_modify(userID, request_dict, response, request)
-            else:
-                return response.json(414)
-        else:
+        if tko.code != 0:
             return response.json(tko.code)
             return response.json(tko.code)
+        response.lang = tko.lang
+        userID = tko.userID
+        # 手机端添加设备,查询,修改
+        if operation == 'add':
+            return self.do_add(userID, request_dict, response, request)
+        elif operation == 'query':
+            return self.do_query(userID, request_dict, response)
+        elif operation == 'modify':
+            return self.do_modify(userID, request_dict, response, request)
+        elif operation == 'modifyChannelName':
+            return self.do_modify_channel_name(userID, request_dict, response, request)
+        elif operation == 'fuzzyQuery':
+            return self.do_fuzzy_query(userID, request_dict, response)
+        elif operation == 'mainUserDevice':
+            return self.do_mainUserDevice( request_dict, response)
+        elif operation == 'getDeviceFeatures':
+            return self.do_get_device_features(request_dict, response)
+        else:
+            return response.json(414)
 
 
     def do_add(self, userID, request_dict, response, request):
     def do_add(self, userID, request_dict, response, request):
-        token = request_dict.get('token', None)
         UID = request_dict.get('UID', None)
         UID = request_dict.get('UID', None)
         NickName = request_dict.get('NickName', None)
         NickName = request_dict.get('NickName', None)
         View_Account = request_dict.get('View_Account', None)
         View_Account = request_dict.get('View_Account', None)
         View_Password = request_dict.get('View_Password', '')
         View_Password = request_dict.get('View_Password', '')
+        encrypt_pass = View_Password
         print("准备解密")
         print("准备解密")
         View_Password = self.decode_pwd(View_Password)
         View_Password = self.decode_pwd(View_Password)
         Type = request_dict.get('Type', None)
         Type = request_dict.get('Type', None)
         ChannelIndex = request_dict.get('ChannelIndex', None)
         ChannelIndex = request_dict.get('ChannelIndex', None)
+        version = request_dict.get('version', '')
+        isCheckMainUser = request_dict.get('isCheckMainUser', None)
 
 
-        if all([UID, NickName, View_Account, Type, ChannelIndex]):
-            tko = TokenObject(token)
-
-            response.lang = tko.lang
-            if tko.code == 0:
-                userID = tko.userID
-                re_uid = re.compile(r'^[A-Za-z0-9]{20}$')
-                if re_uid.match(UID):
-                    is_exist = Device_Info.objects.filter(UID=UID, userID_id=userID)
-                    if is_exist:
-                        # 判断设备是否已存在
-                        if is_exist[0].isExist == 1:
-                            return response.json(174)
-                        else:
-                            is_exist.delete()
-                    if UID == '98UXAA8BRPA35VAL111A':
-                        asy = threading.Thread(target=ModelService.add_log,
-                                               args=(CommonService.get_ip_address(request), userID, 'addV3'))
-                        asy.start()
-                        return response.json(10, 'illegal uid: {uid}'.format(uid=UID))
-                    # is_bind = Device_Info.objects.filter(UID=UID, isShare=False)
-                    # # 判断是否有已绑定用户
-                    # if is_bind:
-                    #     return response.json(15)
-                    try:
-                        # 判断是否有用户绑定
-                        nowTime = int(time.time())
-                        us_qs = UidSetModel.objects.filter(uid=UID)
-                        if not us_qs.exists():
-                            uid_set_create_dict = {
-                                'uid': UID,
-                                'addTime': nowTime,
-                                'updTime': nowTime,
-                                'ip': CommonService.get_ip_address(request_dict),
-                                'channel': ChannelIndex,
-                                'nickname': NickName,
-                            }
-                            UidSetModel.objects.create(**uid_set_create_dict)
-                        else:
-                            us_qs.update(nickname=NickName)
-                        pk = CommonService.getUserID(getUser=False)
-                        userDevice = Device_Info(id=pk, userID_id=userID, UID=UID,
-                                                 NickName=NickName, View_Account=View_Account,
-                                                 View_Password=View_Password, Type=Type, ChannelIndex=ChannelIndex)
-                        userDevice.save()
-
-                        if not us_qs.exists():
-                            us_qs = UidSetModel.objects.filter(uid=UID)
-
-                        if us_qs.exists() and us_qs[0].is_alexa == 1:
-                            asy = threading.Thread(target=ModelService.notify_alexa_add, args=(UID, userID, NickName))
-                            asy.start()
-
-                        # redisObj = RedisObject(db=8)
-                        # redisObj.del_data(key='uid_qs_' + userID)
-                    except Exception as e:
-                        return response.json(10, repr(e))
-                    else:
-                        dvqs = Device_Info.objects.filter(id=pk).values('id', 'userID', 'NickName', 'UID',
-                                                                        'View_Account',
-                                                                        'View_Password', 'ChannelIndex', 'Type',
-                                                                        'isShare',
-                                                                        'primaryUserID', 'primaryMaster',
-                                                                        'data_joined', 'version',
-                                                                        'isVod', 'isExist')
-                        dvql = CommonService.qs_to_list(dvqs)
-                        ubqs = UID_Bucket.objects.filter(uid=UID). \
-                            values('bucket__content', 'status', 'channel', 'endTime', 'uid')
-                        res = dvql[0]
-                        res['vod'] = list(ubqs)
-                        return response.json(0, res)
+        if not all([UID, NickName, View_Account, Type, ChannelIndex]):  # Type和ChannelIndex可能为0
+            return response.json(444, {'param': 'UID, NickName, View_Account, Type, ChannelIndex'})
 
 
-                else:
-                    return response.json(444, {'param': 'UID'})
+        Type = int(Type)
+        ChannelIndex = int(ChannelIndex)
+
+        re_uid = re.compile(r'^[A-Za-z0-9]{14,20}$')
+        if not re_uid.match(UID):
+            return response.json(444, {'param': 'UID'})
+
+        device_info_qs = Device_Info.objects.filter(UID=UID, userID_id=userID)
+        if device_info_qs:
+            # 判断设备是否已存在
+            if device_info_qs[0].isExist == 1:
+                return response.json(174)
             else:
             else:
-                return response.json(tko.code)
+                device_info_qs.delete()
+
+        id = CommonService.getUserID(getUser=False)
+        userName = Device_User.objects.get(userID=userID).username
+        main_exist = Device_Info.objects.filter(UID=UID)
+        main_exist = main_exist.filter(~Q(vodPrimaryUserID='')).values('vodPrimaryUserID', 'vodPrimaryMaster')
+
+        vodPrimaryUserID = userID
+        vodPrimaryMaster = userName
+        primaryUserID = ''
+        primaryMaster = ''
+        isShare = False
+
+        is_bind = Device_Info.objects.filter(UID=UID, isShare=False).values('userID__userID', 'primaryUserID', 'primaryMaster')
+
+        if main_exist.exists():
+            vodPrimaryUserID = main_exist[0]['vodPrimaryUserID']
+            vodPrimaryMaster = main_exist[0]['vodPrimaryMaster']
+
+
+        if is_bind.exists():
+            primaryUserID = is_bind[0]['primaryUserID']
+            primaryMaster = is_bind[0]['primaryMaster']
+            isShare = True
+
+
+        isusermain = False
+        if (vodPrimaryUserID != userID and vodPrimaryUserID != '') or (primaryUserID != userID and primaryUserID != ''):
+            isusermain = True
+
+        # 判断是否有已绑定用户
+        if isCheckMainUser == '1' and isusermain:
+            res = {
+                'id': id,
+                'userID': userID,
+                'NickName': NickName,
+                'UID': UID,
+                'View_Account': View_Account,
+                'View_Password': View_Password,
+                'ChannelIndex': ChannelIndex,
+                'Type': Type,
+                'isShare': isShare,
+                'primaryUserID': primaryUserID,
+                'primaryMaster': primaryMaster,
+                'vodPrimaryUserID': vodPrimaryUserID,
+                'vodPrimaryMaster': vodPrimaryMaster,
+                'data_joined': '',
+                'version': version,
+                'isVod': 0,
+                'isExist': 1,
+                'userID__userEmail': ''
+            }
+            res['vod'] = [
+                {
+                    "status": 1,
+                    "channel": ChannelIndex,
+                    "endTime": '',
+                    "bucket__content": '',
+                    "uid": UID
+                }
+            ]
+            res['isMainUserExists'] = 1
+            return response.json(0, res)
+
+        try:
+            # 判断是否有用户绑定
+            nowTime = int(time.time())
+            us_qs = UidSetModel.objects.filter(uid=UID)
+            if us_qs.exists():
+                us_qs.update(nickname=NickName)
+                UidSet_id = us_qs.first().id
+            else:
+                ip = CommonService.get_ip_address(request)
+                region_id = Device_Region().get_device_region(ip)
+                region_alexa = 'CN' if region_id == 1 else 'ALL'
+                uid_set_create_dict = {
+                    'uid': UID,
+                    'addTime': nowTime,
+                    'updTime': nowTime,
+                    'ip': CommonService.get_ip_address(request_dict),
+                    'channel': ChannelIndex,
+                    'nickname': NickName,
+                    'version': version,
+                    'region_alexa': region_alexa,
+                }
+                UidSet = UidSetModel.objects.create(**uid_set_create_dict)
+                UidSet_id = UidSet.id
+
+            # 查询uid_channel表有无该uid的数据
+            uid_channel_set = UidChannelSetModel.objects.filter(uid_id=UidSet_id)
+            if not uid_channel_set.exists():
+                # 多通道设备设置通道名
+                multi_channel_list = [1, 2, 3, 4, 10001]
+                if Type in multi_channel_list:
+                    UidChannelSet_bulk = []
+                    for i in range(1, ChannelIndex+1):
+                        channel_name = 'channel'+str(i)  # channel1,channel2...
+                        UidChannelSet = UidChannelSetModel(uid_id=UidSet_id, channel=i, channel_name=channel_name)
+                        UidChannelSet_bulk.append(UidChannelSet)
+                    UidChannelSetModel.objects.bulk_create(UidChannelSet_bulk)
+
+            userDevice = Device_Info(id=id, userID_id=userID, UID=UID, NickName=NickName, View_Account=View_Account,
+                                     View_Password=View_Password, Type=Type, ChannelIndex=ChannelIndex, version=version,
+                                     vodPrimaryUserID=vodPrimaryUserID, vodPrimaryMaster=vodPrimaryMaster)
+            userDevice.save()
+            uid_serial_qs = UIDCompanySerialModel.objects.filter(uid__uid=UID)
+            if uid_serial_qs.exists():
+                uid_serial = uid_serial_qs[0]
+                Device_Info.objects.filter(UID=UID).update(vodPrimaryUserID=vodPrimaryUserID,
+                                                           vodPrimaryMaster=vodPrimaryMaster,
+                                                           serial_number=uid_serial.company_serial.serial_number + uid_serial.company_serial.company.mark)
+            else:
+                Device_Info.objects.filter(UID=UID).update(vodPrimaryUserID=vodPrimaryUserID,
+                                                           vodPrimaryMaster=vodPrimaryMaster)
+
+            if not us_qs.exists():
+                us_qs = UidSetModel.objects.filter(uid=UID)
+
+            if us_qs.exists() and us_qs[0].is_alexa == 1:
+                asy = threading.Thread(target=ModelService.notify_alexa_add,
+                                       args=(UID, userID, NickName, encrypt_pass))
+                asy.start()
+
+        except Exception as e:
+            return response.json(10, repr(e))
         else:
         else:
-            return response.json(444, {'param': 'UID,NickName,View_Account,View_Password,Type,ChannelIndex'})
+            dvqs = Device_Info.objects.filter(id=id).values('id', 'userID', 'NickName', 'UID',
+                                                            'View_Account',
+                                                            'View_Password', 'ChannelIndex', 'Type',
+                                                            'isShare',
+                                                            'primaryUserID', 'primaryMaster',
+                                                            'vodPrimaryUserID', 'vodPrimaryMaster',
+                                                            'userID__userEmail',
+                                                            'data_joined', 'version',
+                                                            'isVod', 'isExist', 'isCameraOpenCloud', 'serial_number')
+            dvql = CommonService.qs_to_list(dvqs)
+            ubqs = UID_Bucket.objects.filter(uid=UID). \
+                values('bucket__content', 'status', 'channel', 'endTime', 'uid')
+            res = dvql[0]
+            res['vod'] = list(ubqs)
+
+            iotqs = iotdeviceInfoModel.objects.filter(serial_number=dvql[0]['serial_number'])
+            if iotqs.exists():
+                res['iot'] = {
+                        'endpoint': iotqs[0].endpoint,
+                        'token_iot_number': iotqs[0].endpoint
+                }
+
+            return response.json(0, res)
+
 
 
     def do_modify(self, userID, request_dict, response, request):
     def do_modify(self, userID, request_dict, response, request):
         token = request_dict.get('token', None)
         token = request_dict.get('token', None)
@@ -150,10 +258,11 @@ class EquipmentManagerV3(View):
         userID = tko.userID
         userID = tko.userID
         if userID is None:
         if userID is None:
             return response.json(309)
             return response.json(309)
+        deviceData = None
+        dev_info_qs = None
         try:
         try:
             # deviceData = json.loads(deviceContent)
             # deviceData = json.loads(deviceContent)
             deviceData = eval(deviceContent)
             deviceData = eval(deviceContent)
-
             if deviceData.__contains__('userID_id'):
             if deviceData.__contains__('userID_id'):
                 asy = threading.Thread(target=ModelService.update_log,
                 asy = threading.Thread(target=ModelService.update_log,
                                        args=(CommonService.get_ip_address(request), userID, 'modifyV3', deviceData, id))
                                        args=(CommonService.get_ip_address(request), userID, 'modifyV3', deviceData, id))
@@ -165,6 +274,7 @@ class EquipmentManagerV3(View):
 
 
             # print(deviceData['View_Password'])
             # print(deviceData['View_Password'])
             if deviceData.__contains__('View_Password'):
             if deviceData.__contains__('View_Password'):
+                encrypt_pwd = deviceData['View_Password']
                 deviceData['View_Password'] = self.decode_pwd(deviceData['View_Password'])
                 deviceData['View_Password'] = self.decode_pwd(deviceData['View_Password'])
             dev_info_qs = Device_Info.objects.filter(userID_id=userID, id=id)
             dev_info_qs = Device_Info.objects.filter(userID_id=userID, id=id)
             dev_info_qs.update(**deviceData)
             dev_info_qs.update(**deviceData)
@@ -176,15 +286,12 @@ class EquipmentManagerV3(View):
             res = CommonService.qs_to_dict(qs)
             res = CommonService.qs_to_dict(qs)
             if qs.exists():
             if qs.exists():
                 uid = qs[0].UID
                 uid = qs[0].UID
-                if uid == '98UXAA8BRPA35VAL111A':
-                    asy = threading.Thread(target=ModelService.update_log,
-                                           args=(CommonService.get_ip_address(request), userID, 'modifyV3', deviceData, id))
-                    asy.start()
                 nickname = qs[0].NickName
                 nickname = qs[0].NickName
                 # 增加设备影子信息修改昵称 start
                 # 增加设备影子信息修改昵称 start
                 us_qs = UidSetModel.objects.filter(uid=uid)
                 us_qs = UidSetModel.objects.filter(uid=uid)
                 if us_qs.exists():
                 if us_qs.exists():
-                    us_qs.update(nickname=nickname)
+                    if deviceData.__contains__('NickName'):
+                        us_qs.update(nickname=nickname)
                 else:
                 else:
                     ChannelIndex = qs[0].ChannelIndex
                     ChannelIndex = qs[0].ChannelIndex
                     nowTime = int(time.time())
                     nowTime = int(time.time())
@@ -200,13 +307,24 @@ class EquipmentManagerV3(View):
                 di_qs = Device_Info.objects.filter(UID=uid)
                 di_qs = Device_Info.objects.filter(UID=uid)
                 di_qs.update(NickName=nickname)
                 di_qs.update(NickName=nickname)
                 if deviceData is not None and deviceData.__contains__('NickName') and us_qs[0].is_alexa == 1:
                 if deviceData is not None and deviceData.__contains__('NickName') and us_qs[0].is_alexa == 1:
-
-                    asy = threading.Thread(target=ModelService.notify_alexa_add, args=(uid, userID, nickname))
+                    password = encrypt_pwd if deviceData.__contains__('View_Password') else ''
+                    asy = threading.Thread(target=ModelService.notify_alexa_add, args=(uid, userID, nickname, password))
                     asy.start()
                     asy.start()
             # redisObj = RedisObject(db=8)
             # redisObj = RedisObject(db=8)
             # redisObj.del_data(key='uid_qs_' + userID)
             # redisObj.del_data(key='uid_qs_' + userID)
             return response.json(0, res)
             return response.json(0, res)
 
 
+    # 编辑通道名
+    def do_modify_channel_name(self, userID, request_dict, response):
+        uid = request_dict.get('uid', None)
+        channel = request_dict.get('channel', None)
+        channel_name = request_dict.get('channel_name', None)
+        if not all([uid, channel, channel_name]):
+            return response.json(444)
+        # 更新通道名
+        UidChannelSetModel.objects.filter(uid__uid=uid).update(channel_name=channel_name)
+        return response.json(0)
+
     # 新查询设备字段
     # 新查询设备字段
     def do_query(self, userID, request_dict, response):
     def do_query(self, userID, request_dict, response):
         token = request_dict.get('token', None)
         token = request_dict.get('token', None)
@@ -223,167 +341,373 @@ class EquipmentManagerV3(View):
         response.lang = tko.lang
         response.lang = tko.lang
         if page <= 0:
         if page <= 0:
             return response.json(0)
             return response.json(0)
-        if tko.code == 0:
-            userID = tko.userID
-            dvqs = Device_Info.objects.filter(userID_id=userID)
-            # # 过滤已重置的设备
-            dvqs = dvqs.filter(~Q(isExist=2))
-            dvql = dvqs.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'])
-            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('id', 'uid', 'version', 'nickname', 'ucode',
-                                                                        'detect_status', 'detect_group',
-                                                                        'detect_interval',
-                                                                        'region_alexa', 'is_alexa', 'deviceModel',
-                                                                        'TimeZone', 'TimeStatus', 'SpaceUsable',
-                                                                        'SpaceSum', 'MirrorType', 'RecordType',
-                                                                        'OutdoorModel', 'WIFIName', 'isDetector',
-                                                                        'DetectorRank')
-            uv_dict = {}
-            for us in us_qs:
-                uv_dict[us['uid']] = {
-                    'version': us['version'],
-                    'nickname': us['nickname'],
-                    'ucode': us['ucode'],
-                    'detect_interval': us['detect_interval'],
-                    'detect_group': us['detect_group'],
-                    'detect_status': us['detect_status'],
-                    'region_alexa': us['region_alexa'],
-                    'is_alexa': us['is_alexa'],
-                    'deviceModel': us['deviceModel'],
-                    'TimeZone': us['TimeZone'],
-                    'TimeStatus': us['TimeStatus'],
-                    'SpaceUsable': us['SpaceUsable'],
-                    'SpaceSum': us['SpaceSum'],
-                    'MirrorType': us['MirrorType'],
-                    'RecordType': us['RecordType'],
-                    'OutdoorModel': us['OutdoorModel'],
-                    'WIFIName': us['WIFIName'],
-                    'isDetector': us['isDetector'],
-                    'DetectorRank': us['DetectorRank']
+        if tko.code != 0:
+            return response.json(tko.code)
+        userID = tko.userID
+        dvqs = Device_Info.objects.filter(userID_id=userID)
+        # # 过滤已重置的设备
+        dvqs = dvqs.filter(~Q(isExist=2))
+        dvql = dvqs.values('id', 'userID', 'NickName', 'UID', 'View_Account','View_Password', 'ChannelIndex',
+                           'Type', 'isShare', 'primaryUserID', 'primaryMaster', 'data_joined', 'vodPrimaryUserID',
+                           'vodPrimaryMaster', 'userID__userEmail', 'version', 'isVod', 'isExist', 'NotificationMode',
+                           'isCameraOpenCloud', 'serial_number')
+        dvls = CommonService.qs_to_list(dvql)
+        uid_list = []
+        serial_number_list = []
+        for dvl in dvls:
+            if dvl['primaryUserID'] and dvl['id'] == dvl['primaryUserID']:
+                dvl['isPrimaryUser'] = 1
+            else:
+                dvl['isPrimaryUser'] = 0
+            uid_list.append(dvl['UID'])
+            serial_number_list.append(dvl['serial_number'][0:6])
+
+        # 新增获取IOT证书内容
+        iotqs = iotdeviceInfoModel.objects.filter(serial_number__in=serial_number_list)
+
+        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('id', 'uid', 'version', 'nickname', 'ucode',
+                                                                    'detect_status', 'detect_group',
+                                                                    'detect_interval',
+                                                                    'region_alexa', 'is_alexa', 'deviceModel',
+                                                                    'TimeZone', 'TimeStatus', 'SpaceUsable',
+                                                                    'SpaceSum', 'MirrorType', 'RecordType',
+                                                                    'OutdoorModel', 'WIFIName', 'isDetector',
+                                                                    'DetectorRank', 'is_human', 'is_custom_voice')
+        uv_dict = {}
+        for us in us_qs:
+            uv_dict[us['uid']] = {
+                'version': us['version'],
+                'nickname': us['nickname'],
+                'ucode': us['ucode'],
+                'detect_interval': us['detect_interval'],
+                'detect_group': us['detect_group'],
+                'detect_status': us['detect_status'],
+                'region_alexa': us['region_alexa'],
+                'is_alexa': us['is_alexa'],
+                'deviceModel': us['deviceModel'],
+                'TimeZone': us['TimeZone'],
+                'TimeStatus': us['TimeStatus'],
+                'SpaceUsable': us['SpaceUsable'],
+                'SpaceSum': us['SpaceSum'],
+                'MirrorType': us['MirrorType'],
+                'RecordType': us['RecordType'],
+                'OutdoorModel': us['OutdoorModel'],
+                'WIFIName': us['WIFIName'],
+                'isDetector': us['isDetector'],
+                'DetectorRank': us['DetectorRank'],
+                'is_human': us['is_human'],
+                'is_custom_voice': us['is_custom_voice']
+            }
+            # 从uid_channel里面取出通道配置信息
+            ucs_qs = UidChannelSetModel.objects.filter(uid__id=us['id']).values('channel', 'channel_name',
+                                                                                'pir_audio', 'mic_audio',
+                                                                                'battery_status', 'battery_level',
+                                                                                'sleep_status', 'sleep_time',
+                                                                                'light_night_model',
+                                                                                'light_alarm_type',
+                                                                                'light_alarm_level',
+                                                                                'light_alarm_man_en',
+                                                                                'light_alarm_vol',
+                                                                                'light_long_light'
+                                                                                )
+            channels = []
+            for ucs in ucs_qs:
+                channels_dict = {
+                    'channel': ucs['channel'],
+                    'channel_name': ucs['channel_name'],
+                    'pir_audio': ucs['pir_audio'],
+                    'mic_audio': ucs['mic_audio'],
+                    'battery_status': ucs['battery_status'],
+                    'battery_level': ucs['battery_level'],
+                    'sleep_status': ucs['sleep_status'],
+                    'sleep_time': ucs['sleep_time'],
+                    'light_night_model': ucs['light_night_model'],
+                    'light_alarm_type': ucs['light_alarm_type'],
+                    'light_alarm_level': ucs['light_alarm_level'],
+                    'light_alarm_man_en': ucs['light_alarm_man_en'],
+                    'light_alarm_vol': ucs['light_alarm_vol'],
+                    'light_long_light': ucs['light_long_light']
                 }
                 }
-                # 从uid_channel里面取出通道配置信息
-                ucs_qs = UidChannelSetModel.objects.filter(uid__id=us['id']).values()
-                channels = []
-                for ucs in ucs_qs:
-                    channel = {
-                        'channel': ucs['channel'],
-                        'pir_audio': ucs['pir_audio'],
-                        'mic_audio': ucs['mic_audio'],
-                        'battery_status': ucs['battery_status'],
-                        'battery_level': ucs['battery_level'],
-                        'sleep_status': ucs['sleep_status'],
-                        'sleep_time': ucs['sleep_time'],
-                        'light_night_model': ucs['light_night_model'],
-                        'light_alarm_type': ucs['light_alarm_type'],
-                        'light_alarm_level': ucs['light_alarm_level'],
-                        'light_alarm_man_en': ucs['light_alarm_man_en'],
-                        'light_alarm_vol': ucs['light_alarm_vol'],
-                        'light_long_light': ucs['light_long_light']
-                    }
-                    channels.append(channel)
-                uv_dict[us['uid']]['channels'] = channels
-
-            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['ucode'] = uv_dict[p_uid]['ucode']
-                    p['detect_interval'] = uv_dict[p_uid]['detect_interval']
-                    p['detect_status'] = uv_dict[p_uid]['detect_status']
-                    p['detect_group'] = uv_dict[p_uid]['detect_group']
-                    p['region_alexa'] = uv_dict[p_uid]['region_alexa']
-                    p['is_alexa'] = uv_dict[p_uid]['is_alexa']
-                    p['deviceModel'] = uv_dict[p_uid]['deviceModel']
-                    p['TimeZone'] = uv_dict[p_uid]['TimeZone']
-                    p['TimeStatus'] = uv_dict[p_uid]['TimeStatus']
-                    p['SpaceUsable'] = uv_dict[p_uid]['SpaceUsable']
-                    p['SpaceSum'] = uv_dict[p_uid]['SpaceSum']
-                    p['MirrorType'] = uv_dict[p_uid]['MirrorType']
-                    p['RecordType'] = uv_dict[p_uid]['RecordType']
-                    p['OutdoorModel'] = uv_dict[p_uid]['OutdoorModel']
-                    p['WIFIName'] = uv_dict[p_uid]['WIFIName']
-                    p['isDetector'] = uv_dict[p_uid]['isDetector']
-                    p['DetectorRank'] = uv_dict[p_uid]['DetectorRank']
-                    p['channels'] = uv_dict[p_uid]['channels']
-                    # 设备昵称 调用影子信息昵称,先阶段不可
-                    if uv_dict[p_uid]['nickname']:
-                        p['NickName'] = uv_dict[p_uid]['nickname']
-                else:
-                    # 设备版本号
-                    p['uid_version'] = ''
-                    p['ucode'] = ''
-                data.append(p)
-            result = data
-
-            if NickName:
-                # print('NickName搜索缓存')
-                data = []
-                for index, item in enumerate(result):
-                    if NickName == item['NickName']:
-                        # 加密
-                        item['View_Password'] = self.encrypt_pwd(item['View_Password'])
-                        data.append(item)
-                        return response.json(0, data)
-            if uid:
-                # print('uid搜索缓存')
+                channels.append(channels_dict)
+            uv_dict[us['uid']]['channels'] = channels
+
+        for p in dvls:
+            # 新增IOT
+            p['iot'] = []
+            for iot in iotqs:
+                if p['serial_number'][0:6] == iot.serial_number:
+                    p['iot'].append(
+                        {
+                            'endpoint': iot.endpoint,
+                            'token_iot_number': iot.token_iot_number
+                        }
+                    )
+
+            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']
+
+            # # 返回设备初始化字符
+            # uid_qs = UIDModel.objects.filter(uid=p_uid).values('platform', 'init_string', 'init_string_app')
+            # if uid_qs.exists():
+            #     p['platform'] = uid_qs[0]['platform']
+            #     p['initString'] = uid_qs[0]['init_string']
+            #     p['initStringApp'] = uid_qs[0]['init_string_app']
+
+            if p_uid in uv_dict:
+                # 设备版本号
+                p['uid_version'] = uv_dict[p_uid]['version']
+                p['ucode'] = uv_dict[p_uid]['ucode']
+                p['detect_interval'] = uv_dict[p_uid]['detect_interval']
+                p['detect_status'] = uv_dict[p_uid]['detect_status']
+                p['detect_group'] = uv_dict[p_uid]['detect_group']
+                p['region_alexa'] = uv_dict[p_uid]['region_alexa']
+                p['is_alexa'] = uv_dict[p_uid]['is_alexa']
+                p['deviceModel'] = uv_dict[p_uid]['deviceModel']
+                p['TimeZone'] = uv_dict[p_uid]['TimeZone']
+                p['TimeStatus'] = uv_dict[p_uid]['TimeStatus']
+                p['SpaceUsable'] = uv_dict[p_uid]['SpaceUsable']
+                p['SpaceSum'] = uv_dict[p_uid]['SpaceSum']
+                p['MirrorType'] = uv_dict[p_uid]['MirrorType']
+                p['RecordType'] = uv_dict[p_uid]['RecordType']
+                p['OutdoorModel'] = uv_dict[p_uid]['OutdoorModel']
+                p['WIFIName'] = uv_dict[p_uid]['WIFIName']
+                p['isDetector'] = uv_dict[p_uid]['isDetector']
+                p['DetectorRank'] = uv_dict[p_uid]['DetectorRank']
+                p['is_human'] = uv_dict[p_uid]['is_human']
+                p['is_custom_voice'] = uv_dict[p_uid]['is_custom_voice']
+                p['channels'] = uv_dict[p_uid]['channels']
+                # 设备昵称 调用影子信息昵称,先阶段不可
+                if uv_dict[p_uid]['nickname']:
+                    p['NickName'] = uv_dict[p_uid]['nickname']
+            else:
+                # 设备版本号
+                p['uid_version'] = ''
+                p['ucode'] = ''
+            data.append(p)
+        result = data
+
+        if NickName:
+            # print('NickName搜索缓存')
+            data = []
+            for index, item in enumerate(result):
+                if NickName == item['NickName']:
+                    # 加密
+                    item['View_Password'] = self.encrypt_pwd(item['View_Password'])
+                    data.append(item)
+                    return response.json(0, data)
+        if uid:
+            # print('uid搜索缓存')
+            data = []
+            for index, item in enumerate(result):
+                if uid == item['UID']:
+                    # 加密
+                    item['View_Password'] = self.encrypt_pwd(item['View_Password'])
+                    data.append(item)
+                    return response.json(0, data)
+        items = []
+        # print('缓存分页')
+        for index, item in enumerate(result):
+            if (page - 1) * line <= index:
+                if index < page * line:
+                    # 加密
+                    item['View_Password'] = self.encrypt_pwd(item['View_Password'])
+                    print(item)
+                    items.append(item)
+        print(items)
+        return response.json(0, items)
+
+    def do_fuzzy_query(self, userID, request_dict, response):
+        fuzzy = request_dict.get('fuzzy', None)
+        page = request_dict.get('page', None)
+        line = request_dict.get('line', None)
+
+        if page and line:
+            page = int(page)
+            line = int(line)
+            device_qs = Device_Info.objects.filter(userID=userID)
+            device_qs = device_qs.filter(~Q(isExist=2))
+            if device_qs.exists():
+                if fuzzy:
+                    device_qs = device_qs.filter(Q(UID__contains=fuzzy) | Q(NickName__contains=fuzzy))
+
+                device_qs = device_qs.values('id', 'userID', 'NickName', 'UID', 'View_Account',
+                                             'View_Password', 'ChannelIndex', 'Type', 'isShare',
+                                             'primaryUserID', 'primaryMaster', 'data_joined', 'vodPrimaryUserID',
+                                             'vodPrimaryMaster', 'userID__userEmail',
+                                             'version', 'isVod', 'isExist', 'NotificationMode', 'isCameraOpenCloud', 'serial_number')
+
+                dvls = CommonService.qs_to_list(device_qs)
+                uid_list = []
+                serial_number_list = []
+                for dvl in dvls:
+                    uid_list.append(dvl['UID'])
+                    serial_number_list.append(dvl['serial_number'][0:6])
+
+                # 新增获取IOT证书内容
+                iotqs = iotdeviceInfoModel.objects.filter(serial_number__in=serial_number_list)
+
+                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 = []
                 data = []
+                # 设备拓展信息表
+                us_qs = UidSetModel.objects.filter(uid__in=uid_list).values('id', 'uid', 'version', 'nickname', 'ucode',
+                                                                            'detect_status', 'detect_group',
+                                                                            'detect_interval',
+                                                                            'region_alexa', 'is_alexa', 'deviceModel',
+                                                                            'TimeZone', 'TimeStatus', 'SpaceUsable',
+                                                                            'SpaceSum', 'MirrorType', 'RecordType',
+                                                                            'OutdoorModel', 'WIFIName', 'isDetector',
+                                                                            'DetectorRank')
+                uv_dict = {}
+                for us in us_qs:
+                    uv_dict[us['uid']] = {
+                        'version': us['version'],
+                        'nickname': us['nickname'],
+                        'ucode': us['ucode'],
+                        'detect_interval': us['detect_interval'],
+                        'detect_group': us['detect_group'],
+                        'detect_status': us['detect_status'],
+                        'region_alexa': us['region_alexa'],
+                        'is_alexa': us['is_alexa'],
+                        'deviceModel': us['deviceModel'],
+                        'TimeZone': us['TimeZone'],
+                        'TimeStatus': us['TimeStatus'],
+                        'SpaceUsable': us['SpaceUsable'],
+                        'SpaceSum': us['SpaceSum'],
+                        'MirrorType': us['MirrorType'],
+                        'RecordType': us['RecordType'],
+                        'OutdoorModel': us['OutdoorModel'],
+                        'WIFIName': us['WIFIName'],
+                        'isDetector': us['isDetector'],
+                        'DetectorRank': us['DetectorRank']
+                    }
+                    # 从uid_channel里面取出通道配置信息
+                    ucs_qs = UidChannelSetModel.objects.filter(uid__id=us['id']).values()
+                    channels = []
+                    for ucs in ucs_qs:
+                        channel = {
+                            'channel': ucs['channel'],
+                            'channel_name': ucs['channel_name'],
+                            'pir_audio': ucs['pir_audio'],
+                            'mic_audio': ucs['mic_audio'],
+                            'battery_status': ucs['battery_status'],
+                            'battery_level': ucs['battery_level'],
+                            'sleep_status': ucs['sleep_status'],
+                            'sleep_time': ucs['sleep_time'],
+                            'light_night_model': ucs['light_night_model'],
+                            'light_alarm_type': ucs['light_alarm_type'],
+                            'light_alarm_level': ucs['light_alarm_level'],
+                            'light_alarm_man_en': ucs['light_alarm_man_en'],
+                            'light_alarm_vol': ucs['light_alarm_vol'],
+                            'light_long_light': ucs['light_long_light']
+                        }
+                        channels.append(channel)
+                    uv_dict[us['uid']]['channels'] = channels
+
+                for p in dvls:
+                    # 新增IOT
+                    p['iot'] = []
+                    for iot in iotqs:
+                        if p['serial_number'][0:6] == iot.serial_number:
+                            p['iot'].append(
+                                {
+                                    'endpoint': iot.endpoint,
+                                    'token_iot_number': iot.token_iot_number
+
+                                }
+                            )
+                    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['ucode'] = uv_dict[p_uid]['ucode']
+                        p['detect_interval'] = uv_dict[p_uid]['detect_interval']
+                        p['detect_status'] = uv_dict[p_uid]['detect_status']
+                        p['detect_group'] = uv_dict[p_uid]['detect_group']
+                        p['region_alexa'] = uv_dict[p_uid]['region_alexa']
+                        p['is_alexa'] = uv_dict[p_uid]['is_alexa']
+                        p['deviceModel'] = uv_dict[p_uid]['deviceModel']
+                        p['TimeZone'] = uv_dict[p_uid]['TimeZone']
+                        p['TimeStatus'] = uv_dict[p_uid]['TimeStatus']
+                        p['SpaceUsable'] = uv_dict[p_uid]['SpaceUsable']
+                        p['SpaceSum'] = uv_dict[p_uid]['SpaceSum']
+                        p['MirrorType'] = uv_dict[p_uid]['MirrorType']
+                        p['RecordType'] = uv_dict[p_uid]['RecordType']
+                        p['OutdoorModel'] = uv_dict[p_uid]['OutdoorModel']
+                        p['WIFIName'] = uv_dict[p_uid]['WIFIName']
+                        p['isDetector'] = uv_dict[p_uid]['isDetector']
+                        p['DetectorRank'] = uv_dict[p_uid]['DetectorRank']
+                        p['channels'] = uv_dict[p_uid]['channels']
+                        # 设备昵称 调用影子信息昵称,先阶段不可
+                        if uv_dict[p_uid]['nickname']:
+                            p['NickName'] = uv_dict[p_uid]['nickname']
+                    else:
+                        # 设备版本号
+                        p['uid_version'] = ''
+                        p['ucode'] = ''
+                    data.append(p)
+                result = data
+                items = []
+                # print('缓存分页')
                 for index, item in enumerate(result):
                 for index, item in enumerate(result):
-                    if uid == item['UID']:
-                        # 加密
-                        item['View_Password'] = self.encrypt_pwd(item['View_Password'])
-                        data.append(item)
-                        return response.json(0, data)
-            items = []
-            # print('缓存分页')
-            for index, item in enumerate(result):
-                if (page - 1) * line <= index:
-                    if index < page * line:
-                        # 加密
-                        item['View_Password'] = self.encrypt_pwd(item['View_Password'])
-                        print(item)
-                        items.append(item)
-            print(items)
-            return response.json(0, items)
+                    if (page - 1) * line <= index:
+                        if index < page * line:
+                            # 加密
+                            item['View_Password'] = self.encrypt_pwd(item['View_Password'])
+                            print(item)
+                            items.append(item)
+                print(items)
+                return response.json(0, items)
+            else:
+                return response.json(0, [])
         else:
         else:
-            return response.json(tko.code)
+            return response.json(444)
 
 
     # 加密
     # 加密
-    def encrypt_pwd(self,userPwd):
+    def encrypt_pwd(self, userPwd):
         for i in range(1, 4):
         for i in range(1, 4):
             if i == 1:
             if i == 1:
-                userPwd = RandomStr(3, False)+userPwd+RandomStr(3, False)
+                userPwd = RandomStr(3, False) + userPwd + RandomStr(3, False)
                 userPwd = base64.b64encode(str(userPwd).encode("utf-8")).decode('utf8')
                 userPwd = base64.b64encode(str(userPwd).encode("utf-8")).decode('utf8')
             if i == 2:
             if i == 2:
-                userPwd = RandomStr(2, False)+str(userPwd)+RandomStr(2, False)
+                userPwd = RandomStr(2, False) + str(userPwd) + RandomStr(2, False)
                 userPwd = base64.b64encode(str(userPwd).encode("utf-8")).decode('utf8')
                 userPwd = base64.b64encode(str(userPwd).encode("utf-8")).decode('utf8')
             if i == 3:
             if i == 3:
-                userPwd = RandomStr(1, False)+str(userPwd)+RandomStr(1, False)
+                userPwd = RandomStr(1, False) + str(userPwd) + RandomStr(1, False)
                 userPwd = base64.b64encode(str(userPwd).encode("utf-8")).decode('utf8')
                 userPwd = base64.b64encode(str(userPwd).encode("utf-8")).decode('utf8')
         return userPwd
         return userPwd
 
 
@@ -408,4 +732,87 @@ class EquipmentManagerV3(View):
                 password = password.decode('utf-8')
                 password = password.decode('utf-8')
                 # 去前3位,后3位
                 # 去前3位,后3位
                 password = password[3:-3]
                 password = password[3:-3]
-        return password
+        return password
+
+    def do_mainUserDevice(self, request_dict, response):
+        UID = request_dict.get('UID')
+        dvq = Device_Info.objects.filter(UID=UID)
+        dvq = dvq.filter(~Q(vodPrimaryUserID='')).values('vodPrimaryUserID')
+        qs = {}
+        if dvq.exists():
+            qs = Device_User.objects.filter(userID=dvq[0]['vodPrimaryUserID']).values('userID', 'NickName', 'username',
+                                                                                      'userEmail', 'phone')
+            NickName = qs[0]['username']
+            userEmail = qs[0]['userEmail']
+            phone = qs[0]['phone']
+            username = qs[0]['username']
+            qs = CommonService.qs_to_list(qs)
+            if NickName =='':
+                qs[0]['NickName'] = username
+
+            # if userEmail =='':
+            #     qs[0]['userEmail'] = NickName
+
+            if phone =='':
+                qs[0]['phone'] = NickName
+
+
+        # if not qs:
+        #     uidq = UIDMainUser.objects.filter(UID=UID).values('user_id')
+        #     if uidq.exists():
+        #         qs = Device_User.objects.filter(userID=uidq[0]['user_id']).values('userID', 'NickName', 'username', 'userEmail', 'phone')
+        #         qs = CommonService.qs_to_list(qs)
+
+        return response.json(0, qs)
+
+    def not_login_do_mainUserDevice(self, request_dict, response):
+        UID = request_dict.get('UID')
+        token = request_dict.get('token', None)
+        time_stamp = request_dict.get('time_stamp', None)
+
+        if not all([token, time_stamp]):
+            return response.json(444)
+
+        token = int(CommonService.decode_data(token))
+        time_stamp = int(time_stamp)
+
+        now_time = int(time.time())
+        distance = now_time - time_stamp
+
+        if token != time_stamp or distance > 60000 or distance < -60000:  # 为了全球化时间控制在一天内
+            return response.json(404)
+
+        dvq = Device_Info.objects.filter(UID=UID)
+        dvq = dvq.filter(~Q(vodPrimaryUserID='')).values('vodPrimaryUserID')
+        qs = {}
+        if dvq.exists():
+            qs = Device_User.objects.filter(userID=dvq[0]['vodPrimaryUserID']).values('userID', 'NickName', 'username',
+                                                                                      'userEmail', 'phone')
+            NickName = qs[0]['username']
+            phone = qs[0]['phone']
+            username = qs[0]['username']
+            qs = CommonService.qs_to_list(qs)
+            if NickName =='':
+                qs[0]['NickName'] = username
+            if phone =='':
+                qs[0]['phone'] = NickName
+        return response.json(0, qs)
+
+    def do_get_device_features(self, request_dict, response):
+        uid = request_dict.get('uid', None)
+
+        if uid:
+            uid = CommonService.decode_data(uid)
+
+            if uid:
+                uid_qs = UidSetModel.objects.filter(uid=uid)
+                if uid_qs.exists():
+                    uid_qs = uid_qs.values('is_alexa', 'is_human', 'is_custom_voice', 'double_wifi')
+                    return response.json(0, uid_qs[0])
+                else:
+                    return response.json(173)
+            else:
+                return response.json(444)
+
+        else:
+            return response.json(444)

+ 29 - 12
Controller/EquipmentOTA.py

@@ -7,7 +7,8 @@ from django.views.decorators.csrf import csrf_exempt
 from django.views.generic.base import View
 from django.views.generic.base import View
 
 
 from Ansjer.config import BASE_DIR, SERVER_DOMAIN
 from Ansjer.config import BASE_DIR, SERVER_DOMAIN
-from Model.models import Equipment_Version
+from Model.models import Equipment_Version, EquipmentVersionLimitModel, CountryIPModel
+from Object.RedisObject import RedisObject
 from Object.ResponseObject import ResponseObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Object.TokenObject import TokenObject
 from Object.UrlTokenObject import UrlTokenObject
 from Object.UrlTokenObject import UrlTokenObject
@@ -63,22 +64,21 @@ class EquipmentOTA(View):
 
 
     def delete(self, request_dict, userID, response):
     def delete(self, request_dict, userID, response):
         eid = request_dict.get('eid', None)
         eid = request_dict.get('eid', None)
-        if not eid:
-            return response.json(444, 'eid')
+        version = request_dict.get('version', None)
+        if not eid or not version:
+            return response.json(444, 'eid or version')
         own_perm = ModelService.check_perm(userID=userID, permID=230)
         own_perm = ModelService.check_perm(userID=userID, permID=230)
         if not own_perm:
         if not own_perm:
             return response.json(404)
             return response.json(404)
-        ev = Equipment_Version.objects.filter(eid=eid)
-        if not ev.exists():
+        equipment_version = Equipment_Version.objects.filter(eid=eid, version=version)
+        if not equipment_version.exists():
             return response.json(173)
             return response.json(173)
         try:
         try:
-            has_ev = Equipment_Version.objects.filter(filePath=ev[0].filePath)
-            if has_ev.exists():
-                pass
-            else:
-                filepath = os.path.join(BASE_DIR, ev[0].filePath)
-                os.remove(filepath)
-            ev.delete()
+            # 删除文件和相应数据
+            file_path = equipment_version[0].filePath
+            file_path = os.path.join(BASE_DIR, file_path).replace('\\', '/')
+            os.remove(file_path)
+            equipment_version.delete()
         except Exception as e:
         except Exception as e:
             return response.json(176, repr(e))
             return response.json(176, repr(e))
         else:
         else:
@@ -284,6 +284,23 @@ class EquipmentVersionView(View):
             # 判断大小
             # 判断大小
             if ov > eqs[0].softwareVersion:
             if ov > eqs[0].softwareVersion:
                 return response.json(0, {'softwareVersion': ov})
                 return response.json(0, {'softwareVersion': ov})
+        equipment = eqs[0]
+        redisObject = RedisObject()
+        key = 'limit_{eid}'.format(eid=equipment.eid)
+
+        evl_qs = redisObject.get_data(key=key)
+        if evl_qs:
+            evl_qs = json.loads(evl_qs)
+        else:
+            evl_qs = EquipmentVersionLimitModel.objects.filter(equipment_version_id=equipment.eid, status=1).values()
+            if evl_qs.exists():
+                redisObject.set_data(key=key, val=json.dumps(list(evl_qs.values())), expire=600)
+        if evl_qs and len(evl_qs) > 0:
+            evl = evl_qs[0]
+            if evl['type'] == 1:  # uid限制
+                uids = json.loads(evl['content'])
+                if not uids.__contains__(uid):
+                    return response.json(902)
         file_path = eqs[0].filePath
         file_path = eqs[0].filePath
         if file_path.find('static/Upgrade/') != -1:
         if file_path.find('static/Upgrade/') != -1:
             path = file_path.replace('static/Upgrade/', '').replace('\\', '/')
             path = file_path.replace('static/Upgrade/', '').replace('\\', '/')

+ 12 - 1
Controller/EquipmentStatus.py

@@ -12,6 +12,8 @@
 @Contact: chanjunkai@163.com
 @Contact: chanjunkai@163.com
 """
 """
 import base64
 import base64
+import json
+import threading
 import urllib.parse
 import urllib.parse
 import time
 import time
 import oss2
 import oss2
@@ -21,7 +23,9 @@ from django.views.decorators.csrf import csrf_exempt
 from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET
 from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET
 from Model.models import Device_Info
 from Model.models import Device_Info
 from Object.ETkObject import ETkObject
 from Object.ETkObject import ETkObject
+from Object.RedisObject import RedisObject
 from Object.ResponseObject import ResponseObject
 from Object.ResponseObject import ResponseObject
+from Service.ModelService import ModelService
 from Service.CommonService import CommonService
 from Service.CommonService import CommonService
 
 
 '''
 '''
@@ -109,7 +113,13 @@ def getTZ(request):
         uid = c.decode('utf-8')
         uid = c.decode('utf-8')
         if len(uid) == 20:
         if len(uid) == 20:
             print(uid)
             print(uid)
-            if update:
+            redisObject = RedisObject(db=7)
+            data = redisObject.get_data(key=ip)
+
+            if data:
+                info = json.loads(data)
+                return JsonResponse(status=200, data={'code': 0, 'msg': 'success', 'data': info})
+            elif update:
                 info = CommonService.getIpIpInfo(ip=ip, lang=lang,update=True)
                 info = CommonService.getIpIpInfo(ip=ip, lang=lang,update=True)
             else:
             else:
                 info = CommonService.getIpIpInfo(ip=ip, lang=lang,update=False)
                 info = CommonService.getIpIpInfo(ip=ip, lang=lang,update=False)
@@ -124,6 +134,7 @@ def getTZ(request):
                 elif len(tz) == 8:
                 elif len(tz) == 8:
                     gmtz = tz.replace('UTC-', 'GMT-0').replace('UTC+', 'GMT+0')
                     gmtz = tz.replace('UTC-', 'GMT-0').replace('UTC+', 'GMT+0')
                     info['gmt_offset'] = gmtz
                     info['gmt_offset'] = gmtz
+                redisObject.set_data(key=ip, val=json.dumps(info), expire=3600)
             except Exception as e:
             except Exception as e:
                 pass
                 pass
             return JsonResponse(status=200, data={'code': 0, 'msg': 'success', 'data': info})
             return JsonResponse(status=200, data={'code': 0, 'msg': 'success', 'data': info})

+ 74 - 5
Controller/FAQController.py

@@ -6,6 +6,7 @@ import shutil
 import time
 import time
 import traceback
 import traceback
 
 
+from django.core import serializers
 from django.http import HttpResponse
 from django.http import HttpResponse
 from django.utils.decorators import method_decorator
 from django.utils.decorators import method_decorator
 from django.views.decorators.csrf import csrf_exempt
 from django.views.decorators.csrf import csrf_exempt
@@ -20,7 +21,8 @@ from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Object.TokenObject import TokenObject
 from var_dump import var_dump
 from var_dump import var_dump
 
 
-from Service.ModelService import ModelService
+from Service.CommonService import CommonService
+from Service.ModelService import ModelService, ZositechHelpModel
 
 
 
 
 class FAQUploadView(View):
 class FAQUploadView(View):
@@ -168,9 +170,9 @@ class FAQView(View):
     def validate(self, request_dict, operation):
     def validate(self, request_dict, operation):
         token = TokenObject(request_dict.get('token', None))
         token = TokenObject(request_dict.get('token', None))
         response = ResponseObject()
         response = ResponseObject()
-        if token.code != 0:
-            return response.json(token.code)
-
+        if operation != 'zositechHelp':
+            if token.code != 0:
+                return response.json(token.code)
         if operation == 'add':
         if operation == 'add':
             return self.do_add(token, request_dict, response)
             return self.do_add(token, request_dict, response)
         elif operation == 'query':
         elif operation == 'query':
@@ -179,6 +181,10 @@ class FAQView(View):
             return self.do_update(token, request_dict, response)
             return self.do_update(token, request_dict, response)
         elif operation == 'delete':
         elif operation == 'delete':
             return self.do_delete(token.userID, request_dict, response)
             return self.do_delete(token.userID, request_dict, response)
+        elif operation == 'zositechHelp':
+            return self.do_zositechHelp(request_dict, response)
+        elif operation == 'synZositechHelp':
+            return self.do_synZositechHelp(request_dict, response)
         else:
         else:
             return response.json(404)
             return response.json(404)
 
 
@@ -321,4 +327,67 @@ class FAQView(View):
             else:
             else:
                 return response.json(0)
                 return response.json(0)
         else:
         else:
-            return response.json(444)
+            return response.json(444)
+
+    def do_zositechHelp(self, request_dict, response):
+
+        locale = request_dict.get('locale', None)
+        label_names = request_dict.get('label_names', None)
+        origin = request_dict.get('origin', None)
+        help_qs = None
+        if label_names:
+            help = ZositechHelpModel.objects.filter(locale=locale, label_names__contains=label_names,
+                                                    origin=origin).values()
+        else:
+            help = ZositechHelpModel.objects.filter(locale=locale, origin=origin).values()
+
+        if help.exists():
+            # send_dict = CommonService.qs_to_dict(help)
+            send_dict = list(help)
+
+            return response.json(0, send_dict)
+
+        else:
+            return response.json(444)
+
+    def do_synZositechHelp(self, request_dict, response):
+        zhresults = request_dict.get('zhresults', None).replace("\'", "XX??????XX")
+        #.replace("\"", "XX??????XX").replace("\'", "\"").replace("XX??????XX", "\'")
+        zhresults = json.loads(zhresults)
+
+        enresults = request_dict.get('enresults', None).replace("\'", "XX??????XX")
+        enresults = json.loads(enresults)
+
+        ZositechHelpModel.objects.all().delete()
+
+        for data in zhresults['articles']:
+            labname = ""
+            if data['label_names']:
+                for lab in data['label_names']:
+                    if lab:
+                        labname += ","
+                    labname = lab
+            if not labname:
+                labname = None
+            ZositechHelpModel.objects.create(**{
+                'locale': data['locale'],
+                'label_names': labname,
+                'origin': 'web_widget',
+                'content': json.dumps(data).replace("\'", "\"").replace("XX??????XX", "\'")
+            })
+        for data in enresults['articles']:
+            labname = ""
+            if data['label_names']:
+                for lab in data['label_names']:
+                    if lab:
+                        labname += ","
+                    labname = lab
+            if not labname:
+                labname = None
+            ZositechHelpModel.objects.create(**{
+                'locale': data['locale'],
+                'label_names': labname,
+                'origin': 'web_widget',
+                'content': json.dumps(data).replace("\'", "\"").replace("XX??????XX", "\'")
+            })
+        return response.json(0)

+ 35 - 0
Controller/FeedBack.py

@@ -56,6 +56,8 @@ class FeedBackView(View):
                 return self.do_query_by_admin(userID, request_dict, response)
                 return self.do_query_by_admin(userID, request_dict, response)
             elif operation == 'deleteByAdmin':
             elif operation == 'deleteByAdmin':
                 return self.do_delete_by_admin(userID, request_dict, response)
                 return self.do_delete_by_admin(userID, request_dict, response)
+            elif operation == 'deleteImage':
+                return self.do_delete_image(userID, request_dict, response)
             else:
             else:
                 return response.json(414)
                 return response.json(414)
         else:
         else:
@@ -264,3 +266,36 @@ class FeedBackView(View):
                 return response.json(0)
                 return response.json(0)
         else:
         else:
             return response.json(404)
             return response.json(404)
+
+    def do_delete_image(self, userID, request_dict, response):
+        # own_perm = ModelService.check_perm(userID, 10)
+        # if not own_perm:
+        #     return response.json(404)
+        end_time = request_dict.get('end_time', None)
+        if end_time is None:
+            return response.json(444)
+        sys_ms_qs = FeedBackModel.objects.filter(addTime__lt=end_time).order_by('id').values('id')
+        ids = []
+        for sys_ms in sys_ms_qs:
+            ids.append(sys_ms['id'])
+
+        sm_qs = StatResModel.objects.filter(feedbackmodel__id__in=ids).values('id', 'name')
+        names = []
+        time_struct = time.localtime()
+        current_year = time_struct.tm_year
+        target_year = current_year - 1
+        str_prefix = str(target_year)
+        print(str_prefix)
+        for sm in sm_qs:
+            name = sm['name']
+            if name.find(str_prefix) == 0:
+                names.append('feedback/' + name)
+
+        # auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
+        # bucket = oss2.Bucket(auth, 'oss-cn-hongkong.aliyuncs.com', 'statres')
+        # bucket.batch_delete_objects(names)
+        # FeedBackModel.objects.filter(id__in=ids).delete()
+        print(names)
+        print(len(names))
+
+        return response.json(0)

+ 541 - 0
Controller/FileController.py

@@ -0,0 +1,541 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+import base64
+import json
+import logging
+import os
+import time
+import zipfile
+
+import xlwt
+
+from django.http import StreamingHttpResponse, HttpResponse, QueryDict
+from django.utils.decorators import method_decorator
+from django.views import View
+from django.views.decorators.csrf import csrf_exempt
+from django.db import transaction
+
+from Ansjer.config import BASE_DIR
+from Model.models import UIDModel, UserUIDModel, UserModel, LogModel, MacModel, OrderTaskModel, OrderUIDModel
+from Object.RedisObject import RedisObject
+from Object.TokenObject import TokenObject
+from Object.uidManageResponseObject import uidManageResponseObject
+from Service.CommonService import CommonService
+
+
+class UploadUIDFileView(View):
+
+    @method_decorator(csrf_exempt)
+    def dispatch(self, request, *args, **kwargs):
+        return super(UploadUIDFileView, self).dispatch(request, *args, **kwargs)
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.GET
+        fileName = request.FILES.get('fileName', None)
+        return self.validate(fileName, request_dict, request)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.POST
+        fileName = request.FILES.get('fileName', None)
+        return self.validate(fileName, request_dict, request)
+
+    def validate(self, fileName, request_dict, request):
+        token = request_dict.get('token', None)
+        area = request_dict.get('area', None)
+        isReset = request_dict.get('isReset', 0)
+        content = request_dict.get('fileName', None)
+        vpg_id = request_dict.get('vpg_id', None)
+
+        print('content')
+        print(content)
+
+        content = base64.b64decode(content).decode().strip()
+        content = content[3:(len(content) - 3)]
+        uids = content.split('\n')
+        # print(uids)
+        # print(len(uids))
+
+        response = uidManageResponseObject()
+
+        tko = TokenObject(token)
+        if tko.code != 0:
+            return response.json(tko.code)
+
+        # if not fileName and not area:
+        #     return response.json(444, 'fileName,area')
+
+        data = {}
+        duplicate = []
+        for line in uids:
+
+            if len(line) < 20:
+                continue
+
+            if data.__contains__(line):
+                duplicate.append(line)
+            else:
+                data[line] = ''
+
+        if isReset == 0:
+            return self.do_insert(data, duplicate, vpg_id, area, response, request, tko)
+        else:
+            return self.do_reset(data, response, area, request, tko)
+
+    @transaction.atomic
+    def do_insert(self, data, duplicate, vpg_id, area, response, request, token):
+        bulk = []
+        count = 0
+        add_time = int(time.time())
+        update_time = int(time.time())
+        keys = data.keys()
+
+        # 获取最新的mac
+        mac = MacModel.objects.filter().values('id', 'value', 'is_active')[0]
+        if not mac['is_active']:
+            return response.json(175)
+        # redisObject = RedisObject(db=3)
+        key = ''
+        tmpMac = mac['value']
+        savePoint = None
+        for item in keys:
+            key = item.strip()
+            # value = redisObject.get_data(key)
+            # if value is False:
+            #     # redisObject.set_data(key, '1', 600)
+            # else:
+            #     duplicate.append(key)
+            #     continue
+            bulk.append(UIDModel(
+                uid=item.strip(),
+                uid_extra='',
+                status=0,
+                add_time=add_time,
+                update_time=update_time,
+                area=area,
+                mac=mac['value'],
+                vpg_id=vpg_id
+            ))
+            try:
+                try:
+                    if (count % 5000) == 0:
+                        savePoint = transaction.savepoint()
+                        UIDModel.objects.bulk_create(bulk)
+                        bulk.clear()
+                        data = {
+                            'value': mac['value'],
+                            'is_active': tmpMac is not None
+                        }
+                        MacModel.objects.filter().update(**data)
+                except Exception as e:
+                    # print('--------------------------error 5000')
+                    # print(repr(e))
+                    if savePoint:
+                        transaction.rollback(savePoint)
+                    djangoLogger = logging.getLogger('django')
+                    djangoLogger.exception(repr(e))
+                    return response.json(174, str(e))
+                else:
+                    savePoint = None
+            except Exception as e:
+                # print('--------------------------error 5001')
+                # print(repr(e))
+                djangoLogger = logging.getLogger('django')
+                djangoLogger.exception(repr(e))
+                return response.json(174, str(e))
+            count += 1
+            tmpMac = CommonService.updateMac(mac['value'])
+            if tmpMac is None:
+                # 能分配的mac已用完
+                break
+            else:
+                mac['value'] = tmpMac
+
+        # 当bulk不足5000时,还有数据要插入
+        try:
+            try:
+                savePoint = transaction.savepoint()  # 事务保存点
+                if len(bulk) > 0:
+                    UIDModel.objects.bulk_create(bulk)
+                    bulk.clear()
+            except Exception as e:
+                # print('--------------------------error')
+                # print(repr(e))
+                if savePoint:
+                    transaction.rollback(savePoint)
+                djangoLogger = logging.getLogger('django')
+                djangoLogger.exception(repr(e))
+                return response.json(174)
+            else:
+                del data
+                del bulk
+                data = {
+                    'value': mac['value'],
+                    'is_active': tmpMac is not None
+                }
+                MacModel.objects.filter().update(**data)
+        except Exception as e:
+            # print('--------------------------error 1111')
+            # print(repr(e))
+            djangoLogger = logging.getLogger('django')
+            djangoLogger.exception(repr(e))
+            return response.json(174)
+
+        # print('重复:')
+        # print(duplicate)
+
+        try:
+            operation = self.formatOperation(operation='上传', quantity=int(count), area=int(area))
+            print(operation)
+            self.add_log(request, operation, token)
+        except Exception as e:
+            djangoLogger = logging.getLogger('django')
+            djangoLogger.exception(repr(e))
+
+        if tmpMac is None:
+            return response.json(175, {'last_uid': key})
+        return response.json(0, {'count': count, 'duplicate_count': len(duplicate), 'data': duplicate})
+
+    def do_reset(self, data, response, area, request, token):
+        keys = data.keys()
+        uids = []
+        count = 0
+        for key in keys:
+            uids.append(key.strip())
+            if len(uids) % 5000 == 0:
+                count += self.do_update_uid_status(uids, area)
+                uids.clear()
+
+        if len(uids) > 0:
+            count += self.do_update_uid_status(uids, area)
+            uids.clear()
+
+        operation = self.formatOperation('重置', int(count), int(area))
+        self.add_log(request, operation, token)
+        return response.json(0)
+
+    def do_update_uid_status(self, uids, area):
+        uid_qs = UIDModel.objects.filter(uid__in=uids, area=area, status=2)
+        if uid_qs.exists():
+            uid_ids = []
+            for uid in uid_qs:
+                if uid.status == 2:
+                    uid.status = 1
+                    uid_ids.append(uid.id)
+            UIDModel.objects.bulk_update(uid_qs, fields=['status'])
+
+            try:
+                OrderUIDModel.objects.filter(uid__id__in=tuple(uid_ids)).delete()
+            except Exception as e:
+                print(e)
+
+            return uid_qs.count()
+        return 0
+
+    def add_log(self, request, operation, token):
+        ip = CommonService.get_ip_address(request)
+        now_time = time.time()
+        content = json.loads(json.dumps(request.POST))
+        user_qs = UserModel.objects.filter(id=token.userID)
+
+        if content.__contains__('fileName'):
+            del content['fileName']
+        log = {
+            'status': 200,
+            'content': json.dumps(content),
+            'ip': ip,
+            'time': now_time,
+            'url': 'upload',
+            'operation': operation,
+            'user': user_qs[0]
+        }
+
+        try:
+            LogModel.objects.create(**log)
+        except Exception as e:
+            print('出错')
+            print(repr(e))
+
+    def formatOperation(self, operation, quantity, area):
+        str = '{operation}{quantity}个{area}UID'
+        if area == 0:
+            return str.format(operation=operation, quantity=quantity, area='国内')
+        else:
+            return str.format(operation=operation, quantity=quantity, area='国外')
+
+
+class DownloadUIDFileView(View):
+
+    @method_decorator(csrf_exempt)
+    def dispatch(self, request, *args, **kwargs):
+        return super(DownloadUIDFileView, self).dispatch(request, *args, **kwargs)
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.GET
+        return self.validate(request_dict)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.POST
+        return self.validate(request_dict)
+
+    def validate(self, request_dict):
+        token = request_dict.get('token', None)
+        area = request_dict.get('area', None)
+        quantity = int(request_dict.get('quantity', None))
+        fileType = request_dict.get('fileType', None)
+        order_number = request_dict.get('order_number', None)
+        board = request_dict.get('board', None)
+        plan = request_dict.get('plan', None)
+        checksum = request_dict.get('checksum', None)
+        ic_model = request_dict.get('ic_model', None)
+        order_quantity = request_dict.get('order_quantity', None)
+        response = uidManageResponseObject()
+
+        # print(area)
+        # print(quantity)
+        token = TokenObject(token)
+        if token.code != 0:
+            return response.json(token.code)
+
+        if not area or not order_number or not board or not plan or not checksum or not ic_model or not order_quantity or not fileType:
+            return response.json(444)
+
+        area = int(area)
+
+        if area >= 0 and quantity > 0:
+
+            # 保存订单信息
+            now_time = int(time.time())
+            order = {
+                'order_number': order_number,
+                'board': board,
+                'plan': plan,
+                'checksum': checksum,
+                'ic_model': ic_model,
+                'quantity': order_quantity,
+                'add_time': now_time
+            }
+
+            tmp = OrderTaskModel.objects.create(**order)
+            print(tmp)
+
+            order = OrderTaskModel.objects.filter(order_number=order_number).order_by('-add_time')[0]
+
+            uid_qs = UserUIDModel.objects.filter(user__id=token.userID, uid__status=1, uid__area=area)
+
+            uid_values = uid_qs.values('uid__id', 'uid__uid', 'uid__mac', 'uid__uid_extra', 'uid__add_time', 'uid__update_time', 'uid__area')
+
+            count = uid_values.count()
+            if count < quantity:
+                return response.json(444, '设备UID不足')
+
+            if uid_values.exists():
+
+                uid_values = uid_values[0:quantity]
+                uid_qs = uid_qs[0: quantity]
+                if fileType == 'txt':
+                    # return self.download_txt(uid_values, uid_qs, order)
+                    # return self.download_excel(uid_values, order)
+                    return self.download_zip(uid_values, order)
+                elif fileType == 'excel':
+                    return self.download_excel(uid_values, order)
+                else:
+                    return response.json(444, 'fileType')
+            else:
+                return response.json(444, '111')
+        else:
+            return response.json(444, '222')
+
+    def download_txt(self, uid_values, uid_qs, order):
+        updates = []
+        updates_uid = []
+        content = ''
+        now_time = int(time.time())
+        for i in range(len(uid_values)):
+            # print(item)
+            item = uid_values[i]
+            mac = str(item['uid__mac'])
+            index = mac.rfind(':')
+            tmp = mac[0:index] + '\t' + mac[index:]
+            content += tmp + '\t'
+            content += item['uid__uid'].strip()
+            content += '\r\n'
+            uidModel = UIDModel(
+                id=item['uid__id'],
+                uid=item['uid__uid'],
+                mac=item['uid__mac'],
+                uid_extra=item['uid__uid_extra'],
+                status=2,
+                add_time=item['uid__add_time'],
+                update_time=now_time,
+                area=item['uid__area']
+            )
+            updates.append(uidModel)
+
+            order_uid = OrderUIDModel(uid=uidModel, order=order, add_time=now_time, update_time=now_time)
+            updates_uid.append(order_uid)
+
+            if len(updates) % 5000 == 0:
+                UIDModel.objects.bulk_update(updates, fields=["status"])
+                OrderUIDModel.objects.bulk_create(updates_uid)
+                updates.clear()
+                updates_uid.clear()
+            # print(item['uid__uid'])
+
+        if len(updates) > 0:
+            UIDModel.objects.bulk_update(updates, fields=["status"])
+            OrderUIDModel.objects.bulk_create(updates_uid)
+            updates.clear()
+            updates_uid.clear()
+
+        del updates
+        del updates_uid
+        content = content[0:len(content) - 1]
+        response = StreamingHttpResponse(content)
+        response['Content-Type'] = 'application/octet-stream'
+        response['Content-Disposition'] = 'attachment;filename=UID'+time.strftime('-%Y-%m-%d-%H-%M-%S', time.localtime()) + '.txt'
+        return response
+
+    def download_excel(self, uid_qs, order):
+        response = HttpResponse(content_type='application/vnd.ms-excel')
+        response['Content-Disposition'] = 'attachment; filename=UID' + time.strftime('-%Y-%m-%d-%H-%M-%S',
+                                                                                     time.localtime()) + '.xls'
+        workbook = xlwt.Workbook(encoding='utf-8')
+        sheet1 = workbook.add_sheet('UID')
+        # row1 = [u'设备UID']
+        # for i in range(0, len(row1)):
+        #     sheet1.write(0, i, row1[i])
+
+        num = 1
+        updates = []
+        updates_uid = []
+        now_time = int(time.time())
+        for item in uid_qs:
+            uid = item['uid__uid']
+            mac = item['uid__mac']
+            index = mac.rfind(':')
+            sheet1.write(num, 0, mac[0:index])
+            sheet1.write(num, 1, mac[index:])
+            sheet1.write(num, 2, uid)
+            num += 1
+            uidModel = UIDModel(
+                id=item['uid__id'],
+                uid=item['uid__uid'],
+                mac=item['uid__mac'],
+                uid_extra=item['uid__uid_extra'],
+                status=2,
+                add_time=item['uid__add_time'],
+                update_time=now_time,
+                area=item['uid__area']
+            )
+            updates.append(uidModel)
+
+            order_uid = OrderUIDModel(uid=uidModel, order=order, add_time=now_time, update_time=now_time)
+            updates_uid.append(order_uid)
+
+            if len(updates) % 5000 == 0:
+                UIDModel.objects.bulk_update(updates, fields=["status"])
+                OrderUIDModel.objects.bulk_create(updates_uid)
+                updates.clear()
+                updates_uid.clear()
+            # print(item['uid__uid'])
+
+        if len(updates) > 0:
+            UIDModel.objects.bulk_update(updates, fields=["status"])
+            OrderUIDModel.objects.bulk_create(updates_uid)
+            updates.clear()
+            updates_uid.clear()
+
+        UIDModel.objects.bulk_update(updates, fields=["status"])
+        workbook.save(response)
+        return response
+
+    def download_zip(self, uid_qs, order):
+        dir_name = 'static/' + time.strftime('%Y_%m_%d_%H_%M_%S', time.localtime())
+        path = '/'.join((BASE_DIR, dir_name)).replace('\\', '/') + '/'
+        if not os.path.exists(path):
+            os.mkdir(path)
+
+        filename = time.strftime('_%Y_%m_%d_%H_%M_%S', time.localtime())
+        txt_filename = 'UID' + filename + '.txt'
+        excel_filename = 'UID' + filename + '.xls'
+
+        txt_file = open(path + txt_filename, 'w+')
+        workbook = xlwt.Workbook(encoding='utf-8')
+        sheet1 = workbook.add_sheet('UID')
+        num = 1
+
+        updates = []
+        updates_uid = []
+        content = ''
+        now_time = int(time.time())
+        for i in range(len(uid_qs)):
+            # print(item)
+            item = uid_qs[i]
+            uid = item['uid__uid']
+            mac = item['uid__mac']
+            index = mac.rfind(':')
+            tmp = mac[0:index] + '\t' + mac[index:]
+            content += tmp + '\t'
+            content += item['uid__uid'].strip()
+            content += '\r\n'
+
+            sheet1.write(num, 0, mac[0:index])
+            sheet1.write(num, 1, mac[index:])
+            sheet1.write(num, 2, uid)
+            num += 1
+
+            uidModel = UIDModel(
+                id=item['uid__id'],
+                uid=item['uid__uid'],
+                mac=item['uid__mac'],
+                uid_extra=item['uid__uid_extra'],
+                status=2,
+                add_time=item['uid__add_time'],
+                update_time=now_time,
+                area=item['uid__area']
+            )
+            updates.append(uidModel)
+
+            order_uid = OrderUIDModel(uid=uidModel, order=order, add_time=now_time, update_time=now_time)
+            updates_uid.append(order_uid)
+
+            if len(updates) % 5000 == 0:
+                UIDModel.objects.bulk_update(updates, fields=["status"])
+                OrderUIDModel.objects.bulk_create(updates_uid)
+                updates.clear()
+                updates_uid.clear()
+            # print(item['uid__uid'])
+
+        if len(updates) > 0:
+            UIDModel.objects.bulk_update(updates, fields=["status"])
+            OrderUIDModel.objects.bulk_create(updates_uid)
+            updates.clear()
+            updates_uid.clear()
+
+        del updates
+        del updates_uid
+        content = content[0:len(content) - 1]
+        txt_file.write(content)
+        txt_file.close()
+
+        workbook.save(path + excel_filename)
+
+        zip_name = path[0:path.rfind('/')] + '.zip'
+        return self.get_zip(path, os.listdir(path), zip_name)
+
+    def get_zip(self, path, files, zip_name):
+        zp = zipfile.ZipFile(zip_name, 'w', zipfile.ZIP_DEFLATED)
+        for file in files:
+            zp.write(filename=(path + file), arcname=str(file))
+        zp.close()
+
+        response = StreamingHttpResponse(open(zip_name, 'rb'))
+        response['content_type'] = "application/octet-stream"
+        response['Content-Disposition'] = 'attachment; filename=UID' + time.strftime('_%Y_%m_%d_%H_%M_%S',
+                                                                                     time.localtime()) + '.zip'
+        return response
+

+ 402 - 0
Controller/HistoryUIDController.py

@@ -0,0 +1,402 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+import json
+import logging
+import time
+
+from django.db import transaction
+from django.http import StreamingHttpResponse
+from django.utils.decorators import method_decorator
+from django.views import View
+from django.views.decorators.csrf import csrf_exempt
+from django.db.models import Avg,Max,Min,Count,Sum, Q  #   引入函数
+
+from Model.models import UIDModel, UserModel, UserUIDModel, HistoryUIDModel
+from Object.RedisObject import RedisObject
+from Object.uidManageResponseObject import uidManageResponseObject
+from Object.TokenObject import TokenObject
+from Service.ModelService import ModelService
+
+
+class HistoryUIDView(View):
+
+    @method_decorator(csrf_exempt)
+    def dispatch(self, request, *args, **kwargs):
+        return super(HistoryUIDView, self).dispatch(request, *args, **kwargs)
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.GET
+        operation = kwargs.get('operation')
+        return self.validate(request_dict, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.POST
+        operation = kwargs.get('operation')
+        return self.validate(request_dict, operation)
+
+    def validate(self, request_dict, operation):
+        token = request_dict.get('token', None)
+        response = uidManageResponseObject()
+
+        token = TokenObject(token)
+        if token.code != 0:
+            return response.json(token.code)
+
+        if operation == 'quantity':
+            return self.do_quantity(request_dict, response)
+        elif operation == 'remove':
+            return self.do_remove(request_dict, response)
+        elif operation == 'download':
+            return self.download_txt(token, response)
+        elif operation == 'list':
+            return self.do_list(request_dict, response)
+        elif operation == 'delete':
+            return self.do_delete(token.userID, request_dict, response)
+        elif operation == 'batchDelete':
+            return self.do_batch_delete(token.userID, request_dict, response)
+        elif operation == 'adminUpdate':
+            return self.do_admin_update(token.userID, request_dict, response)
+        else:
+            return response.json(309)
+
+    # 查询当前可用的UID的数量
+    def do_quantity(self, request_dict, response):
+        token = request_dict.get('token', None)
+
+        token = TokenObject(token)
+        if token.code != 0:
+            return response.json(token.code)
+
+        user_qs = UserModel.objects.filter(id=token.userID)
+        if user_qs.exists():
+            user = user_qs[0]
+            if user.permission == '0':
+                return self.do_admin_quantity(request_dict, response, user.username)
+            else:
+                return self.do_not_admin_quantity(request_dict, response, user.username)
+        else:
+            return response.json(9)
+
+    # 管理员的查询UID数量操作
+    def do_admin_quantity(self, request_dict, response, admin):
+        datas = []
+        domestic = HistoryUIDModel.objects.filter(area=0, status=0).count()
+        foreign = HistoryUIDModel.objects.filter(area=1, status=0).count()
+        item = {}
+        item['isAdmin'] = 1
+        item['domestic'] = domestic
+        item['foreign'] = foreign
+        item['username'] = admin
+        datas.append(item)
+
+        user_qs = UserModel.objects.filter(~Q(Q(permission='0')))
+        for user in user_qs:
+            item = {'isAdmin': 0}
+            result = UserUIDModel.objects.filter(user__id=user.id, uid__status=1, uid__area=0).aggregate(num=Count('uid__status'))
+            item['domestic'] = result['num']
+            result = UserUIDModel.objects.filter(user__id=user.id, uid__status=1, uid__area=1).aggregate(num=Count('uid__status'))
+            item['foreign'] = result['num']
+            item['username'] = user.username
+            datas.append(item)
+
+        return response.json(0, {'data': datas})
+
+    # 非管理员的查询UID数量操作
+    def do_not_admin_quantity(self, request_dict, response, username):
+        user_qs = UserModel.objects.filter(username=username)
+        if user_qs.exists():
+            user = user_qs[0]
+            datas = []
+            item = {'isAdmin': 0}
+            result = UserUIDModel.objects.filter(user__id=user.id, uid__status=1, uid__area=0).aggregate(num=Count('uid__status'))
+            item['domestic'] = result['num']
+            result = UserUIDModel.objects.filter(user__id=user.id, uid__status=1, uid__area=1).aggregate(num=Count('uid__status'))
+            item['foreign'] = result['num']
+            item['username'] = user.username
+            datas.append(item)
+            return response.json(0, {'data': datas})
+        else:
+            return response.json(444)
+
+    # 分配UID
+    @transaction.atomic
+    def do_allot(self, request_dict, response):
+        username = request_dict.get('username', None)
+        quantity = int(request_dict.get('quantity', None))
+        area = request_dict.get('area', None)
+        token = request_dict.get('token', None)
+
+        token = TokenObject(token)
+        if token.code != 0:
+            return response.json(token.code)
+        user = UserModel.objects.get(id=token.userID)
+
+        if not user or '0' not in user.permission:
+            return response.json(404)
+
+        # 要分配的对象
+        allot_user_qs = UserModel.objects.filter(username=username)
+        if not allot_user_qs.exists():
+            return response.json(444, 'username')
+
+        # 取出对应区域可用的UID分配给allot_user
+        uid_qs = HistoryUIDModel.objects.filter(area=area, status=0)
+        count = uid_qs.count()
+        if count < quantity:
+            return response.json(444, '设备UID不足')
+
+        updates = []
+        datas = []
+        count = 0
+        if uid_qs.exists():
+            uid_qs = uid_qs[0:quantity]
+            now_time = int(time.time())
+            savePoint = transaction.savepoint()
+            for item in uid_qs:
+                item.status = 1
+                item.update_time = time.time()
+                user_uid = UserUIDModel()
+                user_uid.uid = item
+                user_uid.user = allot_user_qs[0]
+                user_uid.add_time = now_time
+                user_uid.update_time = now_time
+                datas.append(user_uid)
+                updates.append(item)
+
+                if len(datas) % 5000 == 0:
+                    result = self.do_update(datas, updates, savePoint)
+                    if result != 0:
+                        return response.json(result)
+
+            if len(datas) > 0:
+                result = self.do_update(datas, updates, savePoint)
+                if result != 0:
+                    return response.json(result)
+            redisObject = RedisObject()
+            values = uid_qs.values('uid')
+            print(values)
+            redisObject.set_data(key=token.token, val=json.dumps(list(values)), expire=3600)
+            del datas
+            del updates
+            return response.json(0)
+        else:
+            return response.json(444)
+
+    def do_update(self, datas, updates, savePoint, count=0):
+        try:
+            try:
+                if count == 2:
+                    raise Exception("Invalid level!")
+                UserUIDModel.objects.bulk_create(datas)
+                HistoryUIDModel.objects.bulk_update(updates, fields=['status', 'update_time'])
+                datas.clear()
+                updates.clear()
+            except Exception as e:
+                if savePoint:
+                    transaction.savepoint_rollback(savePoint)
+                djangoLogger = logging.getLogger('django')
+                djangoLogger.exception(repr(e))
+                return 174
+        except Exception as e:
+            return 174
+        return 0
+
+    # 把UID表中的数据移动到HistoryUID表中
+    def do_remove(self, request_dict, response):
+        token = TokenObject(request_dict.get('token', None))
+        id = request_dict.get('id', None)
+        start = request_dict.get('start', None)
+        stop = request_dict.get('stop', None)
+
+        if token.code != 0:
+            return response.json(token.code)
+
+        # 通过userID查找用户,判断是否是管理员
+        user_qs = UserModel.objects.filter(id=token.userID)
+        if user_qs.exists():
+            user = user_qs[0]
+            if user.permission != '0':
+                return response.json(404)
+        else:
+            return response.json(9)
+
+        if id:
+            return self.do_remove_by_id(id, response)
+        elif start and stop:
+            return self.do_bulk_remove(int(start), int(stop), response)
+        else:
+            return response.json(444, 'id,start,stop')
+
+    # 移除单条UID记录,id:记录id
+    def do_remove_by_id(self, id, response):
+        id = int(id)
+        uid_qs = HistoryUIDModel.objects.filter(id=id)
+        if not uid_qs.exists():
+            return response.json(173)
+
+        uid = uid_qs[0]
+        if uid:
+            data = {
+                'uid': uid.uid,
+                'uid_extra': uid.uid_extra,
+                'status': uid.status,
+                'add_time': uid.add_time,
+                'update_time': uid.update_time,
+                'area': uid.area
+            }
+            HistoryUIDModel.objects.create(**data)
+            uid.delete()
+            return response.json(0)
+        else:
+            return response.json(444, 'id')
+
+    # 批量移除UID记录。start:开始的UID记录的id;stop:结束的UID记录的id
+    def do_bulk_remove(self, start, stop, response):
+        uid_qs = UIDModel.objects.filter(id__range=(start, stop))
+        histories = []
+        if uid_qs.exists():
+            for item in uid_qs:
+                histories.append(HistoryUIDModel(
+                    uid=item.uid,
+                    uid_extra=item.uid_extra,
+                    status=item.status,
+                    add_time=item.add_time,
+                    update_time=item.update_time,
+                    area=item.area
+                ))
+                if len(histories) % 5000 == 0:
+                    HistoryUIDModel.objects.bulk_create(histories)
+                    histories.clear()
+            if len(histories) > 0:
+                HistoryUIDModel.objects.bulk_create(histories)
+                histories.clear()
+            uid_qs.delete()
+            return response.json(0)
+        else:
+            return response.json(173)
+
+    def download_txt(self, token, response):
+
+        redisObject = RedisObject()
+        uid_qs = redisObject.get_data(key=token.token)
+
+        if uid_qs is False:
+            return response.json(308)
+
+        uid_qs = json.loads(uid_qs)
+        content = ''
+        for item in uid_qs:
+            # print(item)
+            content += item['uid']
+            content += '\r\n'
+
+        redisObject.del_data(key=token.token)
+
+        content = content[0:len(content) - 1]
+        response = StreamingHttpResponse(content)
+        response['Content-Type'] = 'application/octet-stream'
+        filename = 'uid_need_to_set_up_push.txt'
+        response['Content-Disposition'] = 'attachment;filename=' + filename
+
+        return response
+
+    def do_list(self, request_dict, response):
+        page = request_dict.get('page', None)
+        line = request_dict.get('limit', None)
+        status = request_dict.get('status', None)
+        area = request_dict.get('area', None)
+        start_time = request_dict.get('starttime', None)
+        stop_time = request_dict.get('endtime', None)
+        uid = request_dict.get('uid', None)
+
+        if page and line:
+
+            uid_qs = HistoryUIDModel.objects.filter()
+            res = {
+                'count': 0,
+                'data': []
+            }
+
+            if uid_qs.exists():
+                page = int(page)
+                line = int(line)
+
+                start = (page - 1) * line
+                end = start + line
+
+                if uid:
+                    uid_qs = uid_qs.filter(uid=uid)
+
+                if status:
+                    uid_qs = uid_qs.filter(status=status)
+
+                if area:
+                    uid_qs = uid_qs.filter(area=area)
+
+                if start_time:
+                    uid_qs = uid_qs.filter(update_time__gte=start_time)
+
+                if stop_time:
+                    if stop_time > start:
+                        uid_qs = uid_qs.filter(update_time__lte=stop_time)
+
+                res['count'] = uid_qs.count()
+                uid_qs = uid_qs.values()[start:end]
+
+                res['data'] = list(uid_qs)
+
+            print(res)
+            return response.json(0, res)
+        else:
+            return response.json(444)
+
+    def do_delete(self, userID, request_dict, response):
+        uid = request_dict.get('uid', None)
+        user_qs = UserModel.objects.filter(id=userID)
+
+        if user_qs.exists():
+            user = user_qs[0]
+            if int(user.permission) != 0:
+                return response.json(309)
+
+            HistoryUIDModel.objects.filter(uid=uid).delete()
+            return response.json(0)
+        else:
+            return response.json(309)
+
+    def do_batch_delete(self, userID, request_dict, response):
+        # perm = ModelService.check_perm_uid_manage(userID, 0)
+        # if not perm:
+        #     return response.json(309)
+
+        uids = request_dict.get('uidlist', None)
+
+        if uids:
+            uids = json.loads(uids)
+            HistoryUIDModel.objects.filter(uid__in=uids).delete()
+            return response.json(0)
+        else:
+            return response.json(444)
+
+    def do_admin_update(self, userID, request_dict, response):
+        # perm = ModelService.check_perm_uid_manage(userID, 0)
+        # if not perm:
+        #     return response.json(309)
+
+        uid = request_dict.get('uid', None)
+        content = request_dict.get('content', None)
+
+        if uid and content:
+            content = json.loads(content)
+            print(content)
+            content['update_time'] = int(time.time())
+            uid_qs = HistoryUIDModel.objects.filter(uid=uid)
+            if uid_qs.exists():
+                uid_qs.update(**content)
+                return response.json(0)
+            else:
+                return response.json(173)
+        else:
+            return response.json(444)

+ 312 - 0
Controller/IotCoreController.py

@@ -0,0 +1,312 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+import os
+import hashlib
+import json
+import time
+import uuid
+import boto3
+import requests
+
+from django.views import View
+from Ansjer.config import BASE_DIR
+from base64 import b64encode, encodebytes
+from Controller.DeviceConfirmRegion import Device_Region
+from Model.models import Device_User, Device_Info, iotdeviceInfoModel, UIDCompanySerialModel, \
+    SerialNumberModel
+from Object.IOTCore.IotObject import IOTClient
+from Object.ResponseObject import ResponseObject
+from Object.TokenObject import TokenObject
+from Service.CommonService import CommonService
+
+import OpenSSL.crypto as ct
+
+
+class IotCoreView(View):
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.GET
+        operation = kwargs.get('operation', None)
+        return self.validate(operation, request_dict, request)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.POST
+        operation = kwargs.get('operation', None)
+        return self.validate(operation, request_dict, request)
+
+    def validate(self, operation, request_dict, request):
+        response = ResponseObject()
+
+        if operation == 'createKeysAndCertificate':
+            return self.create_keys_and_certificate(request_dict, response, request)
+        elif operation == 'requestPublishMessage':
+            return self.request_publish_message(request_dict, response, request)
+        elif operation == 'thingRegroup':
+            return self.thing_regroup(request_dict, response, request)
+        else:
+            token = TokenObject(request_dict.get('token', None))
+            if token.code != 0:
+                return response.json(token.code)
+            if operation == 'clearIotCerm':
+                return self.clear_Iot_Cerm(request_dict, response)
+            else:
+                return response.json(404)
+
+    # CVM注册  :正使用
+    def create_keys_and_certificate(self, request_dict, response, request):
+        uid = request_dict.get('uid', '')
+        token = request_dict.get('token', None)
+        uid_code = request_dict.get('uid_code', None)
+        language = request_dict.get('language', None)
+        time_stamp = request_dict.get('time_stamp', None)
+        device_version = request_dict.get('device_version', None).replace('.', '_')  # 物品组命名不能包含'.'
+
+        if not all([token, time_stamp, device_version, language]):
+            return response.json(444, {'param': 'token, uid_code, time_stamp, device_version, language'})
+
+        # token时间戳校验
+        token = int(CommonService.decode_data(token))
+        time_stamp = int(time_stamp)
+        now_time = int(time.time())
+        distance = now_time - time_stamp
+        if token != time_stamp or distance > 60000 or distance < -60000:  # 为了全球化时间控制在一天内
+            return response.json(404)
+
+        if not uid:
+            # 使用序列号
+            serial_number = request_dict.get('serial_number', None)
+            serial_number_code = request_dict.get('serial_number_code', None)
+            if not all([serial_number, serial_number_code]):
+                return response.json(444, {'param': 'serial_number, serial_number_code'})
+
+            # 序列号编码解码校验
+            serial_number_code = CommonService.decode_data(serial_number_code)
+            if serial_number != serial_number_code:
+                return response.json(404)
+
+            serial = serial_number[0:6]
+            try:
+                SerialNumberModel.objects.get(serial_number=serial)
+            except:
+                return response.json(444)
+
+            ThingNameSuffix = serial_number  # 物品名后缀
+            iotdeviceInfo_qs = iotdeviceInfoModel.objects.filter(serial_number=serial)
+        else:
+            # 使用uid
+            # uid编码解码校验
+            uid_code = CommonService.decode_data(uid_code)
+            if uid != uid_code:
+                return response.json(404)
+
+            serial = ''     # iot_deviceInfo表写入serial_number为''
+            ThingNameSuffix = uid     # 物品名后缀
+            iotdeviceInfo_qs = iotdeviceInfoModel.objects.filter(uid=uid)
+        # 判断设备是否已注册证书
+        if not iotdeviceInfo_qs.exists():
+            thingGroup = device_version + '_' + language
+            ip = CommonService.get_ip_address(request)
+            region_id = Device_Region().get_device_region(ip)
+
+            iotClient = IOTClient(region_id)
+            res = iotClient.create_keys_and_certificate(ThingNameSuffix, thingGroup, response)
+            token_iot_number = hashlib.md5((str(uuid.uuid1()) + str(now_time)).encode('utf-8')).hexdigest()
+
+            iotdeviceInfoModel.objects.create(uid=uid,
+                                              serial_number=serial,
+                                              endpoint=res[0]['endpoint'],
+                                              certificate_id=res[0]['certificateId'],
+                                              certificate_pem=res[0]['certificatePem'],
+                                              public_key=res[0]['publicKey'],
+                                              private_key=res[0]['privateKey'],
+                                              thing_name=res[1]['ThingName'],
+                                              thing_groups=res[1]['thingGroupName'],
+                                              token_iot_number=token_iot_number
+                                              )
+            res = {
+                'certificateId': res[0]['certificateId'],
+                'certificatePem': res[0]['certificatePem'],
+                'publicKey': res[0]['publicKey'],
+                'privateKey': res[0]['privateKey'],
+                'endpoint': res[0]['endpoint']
+            }
+            return response.json(0, {'res': res})
+        else:
+            iot = iotdeviceInfo_qs[0]
+            res = {
+                'certificateId': iot.certificate_id,
+                'certificatePem': iot.certificate_pem,
+                'publicKey': iot.public_key,
+                'privateKey': iot.private_key,
+                'endpoint': iot.endpoint
+            }
+            # print('此设备已注册证书')
+            return response.json(0, {'res': res})
+
+    def thing_regroup(self, request_dict, response, request):
+        # 物品重新分组
+        uid = request_dict.get('uid', '')
+        token = request_dict.get('token', None)
+        language = request_dict.get('language', None)
+        time_stamp = request_dict.get('time_stamp', None)
+        device_version = request_dict.get('device_version', None)
+
+        if not all([token, language, time_stamp, device_version]):
+            return response.json(444, {'param: token, language, time_stamp, device_version'})
+
+        # 封装token认证
+        token = int(CommonService.decode_data(token))
+        time_stamp = int(time_stamp)
+        now_time = int(time.time())
+        distance = now_time - time_stamp
+        if token != time_stamp or distance > 60000 or distance < -60000:  # 为了全球化时间控制在一天内
+            return response.json(404)
+
+        ip = CommonService.get_ip_address(request)
+        region_id = Device_Region().get_device_region(ip)
+        iotClient = IOTClient(region_id)
+
+        ThingNameSuffix = uid
+        if not uid:
+            # 使用序列号
+            serial_number = request_dict.get('serial_number', None)
+            if not serial_number:
+                return response.json(444)
+            ThingNameSuffix = serial_number
+        thingName = 'Ansjer_Device_' + ThingNameSuffix
+        new_thingGroupName = (device_version + '_' + language).replace('.', '_')  # 物品组命名不能包含'.'
+
+        try:
+            # 获取旧物品组
+            list_groups_res = iotClient.client.list_thing_groups_for_thing(thingName=thingName, maxResults=1)
+            old_thingGroupName = list_groups_res['thingGroups'][0]['groupName']
+            # 没有新物品组则创建
+            list_thing_groups_res = iotClient.client.list_thing_groups(namePrefixFilter=new_thingGroupName
+                                                                       , maxResults=1, recursive=False)
+            if not list_thing_groups_res['thingGroups']:
+                attributes = {
+                    "update_time": "0"
+                }
+                thingGroupProperties = {
+                    "thingGroupDescription": "OTA",
+                    "attributePayload": {
+                        "attributes": attributes,
+                        "merge": False  # 更新时覆盖掉而不是合并
+                    }
+                }
+                iotClient.client.create_thing_group(thingGroupName=new_thingGroupName
+                                                    , thingGroupProperties=thingGroupProperties)
+            iotClient.client.update_thing_groups_for_thing(thingName=thingName
+                                                           , thingGroupsToAdd=[new_thingGroupName]
+                                                           , thingGroupsToRemove=[old_thingGroupName])
+
+            # 更新设备版本信息
+            if uid:
+                Device_Info.objects.filter(UID=uid).update(version=device_version)
+            else:
+                Device_Info.objects.filter(serial_number=serial_number).update(version=device_version)
+            return response.json(0)
+        except Exception as e:
+            print(e)
+            return response.json(500, repr(e))
+
+    def clear_Iot_Cerm(self, userID, request_dict, response):
+        serial_number = request_dict.get('serial_number', None)
+
+        if serial_number:
+
+            iot = iotdeviceInfoModel.objects.filter(thing_name="Ansjer_Device_" + serial_number)
+            if iot.exists():
+                iot.delete()
+            return response.json(0)
+
+        else:
+            return response.json(444)
+
+    def request_publish_message(self, request_dict, response, request):
+        # Alexa请求IoT Core下发MQTT消息
+        UID = request_dict.get('UID', None)
+        MSG = request_dict.get('MSG', None)
+
+        if not all([UID, MSG]):
+            return response.json(444)
+
+        try:
+            # 获取检查uid的序列号,如果没有序列号,不使用MQTT下发消息
+            device_info_qs = Device_Info.objects.filter(UID=UID).values('UID', 'serial_number')
+            uid = device_info_qs[0]['UID']
+            serial_number = device_info_qs[0]['serial_number']
+            # 如果device_info表的serial_number不为空,物品名为'Ansjer_Device_序列号'
+            ThingNameSuffix = serial_number if serial_number != '' else uid
+
+            thing_name = 'Ansjer_Device_' + ThingNameSuffix
+            # 获取数据组织将要请求的url
+            iot = iotdeviceInfoModel.objects.filter(thing_name__contains=thing_name).values('thing_name', 'endpoint',
+                                                                                            'token_iot_number')
+            if not iot.exists():
+                return response.json(10043)
+            thing_name = iot[0]['thing_name']  # IoT core上的物品名: Ansjer_Device_+序列号+企业编码
+            endpoint = iot[0]['endpoint']
+            Token = iot[0]['token_iot_number']
+            # Token = '297a601b3925e04daab5a60280650e09'
+            topic_name = thing_name + '_rtsp_topic'     # MQTT主题
+
+            # rtsp://rtsp.zositech.org:8554/ZFdqWldXRFpMTkVaYVZEaEJXRXhUV0RFeE1VRT1B
+            # api doc: https://docs.aws.amazon.com/zh_cn/iot/latest/developerguide/http.html
+            # https://IoT_data_endpoint/topics/url_encoded_topic_name?qos=1
+            # POST请求url来发布消息
+            url = 'https://{}/topics/{}?rtsp_command={}'.format(endpoint, topic_name, MSG)
+            authorizer_name = 'Ansjer_Iot_Auth'
+            signature = self.rsa_sign(Token)  # Token签名
+            headers = {'x-amz-customauthorizer-name': authorizer_name, 'Token': Token,
+                       'x-amz-customauthorizer-signature': signature}
+            params = {'rtsp_command': MSG}
+            r = requests.post(url=url, headers=headers, json=params, timeout=2)
+            if r.status_code == 200:
+                return response.json(0)
+            else:
+                # print('发布失败')
+                return response.json(10044)
+        except Exception as e:
+            # print(e)
+            return response.json(500, repr(e))
+
+    def rsa_sign(self, Token):
+        # 私钥签名Token
+        private_key_file = '''-----BEGIN RSA PRIVATE KEY-----
+MIIEpQIBAAKCAQEA5iJzEDPqtGmFMggekVro6C0lrjuC2BjunGkrFNJWpDYzxCzE
+X5jf4/Fq7hcIaQd5sqHugDxPVollSLPe9zNilbrd0sZfU+Ed8gRVuKW9KwfE9XFr
+L0pt6bKRQ0IIRfiZ9TuR0tsQysvcO1GZSXcYfPue3tGM1zOnWFThWDqZ06+sOxzt
+RMRl4yNfbpCG4MfxG3itNXOfrjZv2OMLSXrxmzubSvRpUYSvQPs4fm9302SAnySY
+0MKzx6H6528ZQm/IDDSZy6EmNBIyTRDfxC56vnYcXvqedAQh7jJnjdvt6Q4MhASH
+eIYi1FBSdu2NT6wgpnrqXzx5pq9kR/lnsLID0wIDAQABAoIBAQCiF4GT1/1oNSpr
+ouxk1PNXFPWFUsVGD8mAwVJmx//eiY7MjfuCmdqYYmI+cFqsH2fIOeYSzGfVO9Dq
+9EYHN1oovAWhf7eFDPpajFMUSyiCNmazub8VAAeKowtNpCTPo9pMsDh1m3aoYA4u
+ebrN0+Sbo16y8kWRDgDAZoiR7DSMs8lczk16hwfv5mw8XpNDbaL3Coi4Koe2S1Yh
+2SX3vWFlpd7qF1ZYXuZIp+b8JPrV7n9eUKoFgzj0gqgwQK80CoexIjiOrNMPvkQa
+q+8kCvFjAzKxOK7e8gjM8lMRiGodb61kmYZkkJzFwWO4EaGbl34lfVECd1Ixp3tF
+be0OWAGBAoGBAPSteXDzzToD8ovM7LL11x0jWwI6HOiHu89kZtW566rIezjWBuA2
+TxrcYKM3h9jQRXS3CsMdoIv6XGk5lqM8ADtjn23FBWe/THYLh8bm8JOgh5RRWQDg
+SvkLfi9Ih2mM4NJfmuuDOh3Nze2efLM7+kOZWUQwF2Zx9mL5jvRBk351AoGBAPDI
+sYmT2Li+i5+0vykA2m5uPF8ZOW8BGtAfCZv0suW7BNzSgin78g9WapRd/4p0NNiL
+/nVMqPPCpd1akCUpV+GDWQt0hV+HZjxANE0KWhciQRyo2qvo51j8SWILJSgh0tXC
+aTF8qt6oGw3VN3m57vKhbrlDaz0J/NDJFci6msAnAoGBAOuG6bXPGijUj+//DYKf
+n7jOxdZ49kboEePrtAncdHzri6IEdI3z+WXT6bpzw/LzWUimwldb96WHFNm9s8Hi
+Ch8hIODbnP5naUTgiIzw1XhmONyPCewL/F+LrqX5XVA/alNX8JrwsUrrR2WLAGLQ
+Q3I69XDsEjptTU2tCO0bCs3ZAoGBAJ2lCHfm0JHET230zONvp5N9oREyVqQSuRdh
++syc3TQDyh85w/bw+X6JOaaCFHj1tFPC9Iqf8k4GNspCLPXnp54CfR4+38O3xnvU
+HWoDSRC0YKT++IxtJGriYrlKSr2Hx54kdvLriIPW1D+uRW/xCDza7L9nIKMKEvgv
+b4/IfOEpAoGAeKM9Te7T1VzlAkS0CJOwanzwYV/zrex84WuXxlsGgPQ871lTs5AP
+H1QLfLfFXH+UVrCEC2yv4eml/cqFkpB3gE5i4MQ8GPVIOSs5tsIyl8YUA03vdNdB
+GCqvlyw5dfxNA+EtxNE2wCW/LW7ENJlACgcfgPlBZtpLheWoZB/maw4=
+-----END RSA PRIVATE KEY-----'''
+        # 使用密钥文件方式
+        # private_key_file_path = os.path.join(BASE_DIR, 'static/iotCore/private.pem')#.replace('\\', '/')
+        # private_key_file = open(private_key_file_path, 'r')
+        private_key = ct.load_privatekey(ct.FILETYPE_PEM, private_key_file)
+        signature = ct.sign(private_key, Token.encode('utf8'), 'sha256')
+        signature = encodebytes(signature).decode('utf8').replace('\n', '')
+        # print('signature:', signature)
+        return signature

+ 97 - 0
Controller/LanguageController.py

@@ -0,0 +1,97 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+import time
+
+from django.views import View
+
+from Model.models import LanguageModel
+from Object.uidManageResponseObject import uidManageResponseObject
+from Object.TokenObject import TokenObject
+from Service.ModelService import ModelService
+
+
+class LanguageView(View):
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation', None)
+        request_dict = request.GET
+        return self.validate(request_dict, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation', None)
+        request_dict = request.POST
+        return self.validate(request_dict, operation)
+
+    def validate(self, request_dict, operation):
+        token = TokenObject(request_dict.get('token', None))
+
+        response = uidManageResponseObject()
+
+        if token.code != 0:
+            return response.json(token.code)
+
+        if operation == 'add':
+            return self.do_add(token.userID, request_dict, response)
+        elif operation == 'update':
+            return self.do_update(token.userID, request_dict, response)
+        elif operation == 'getLanguage':
+            return self.do_get(request_dict, response)
+        else:
+            return response.json(404)
+
+    def do_add(self, userID, request_dict, response):
+        # perm = ModelService.check_perm_uid_manage(userID, 0)
+        # if not perm:
+        #     return response.json(309)
+
+        lang = request_dict.get('lang', None)
+        lang_youdao = request_dict.get('lang_youdao', None)
+
+        if lang:
+            now_time = int(time.time())
+
+            language = LanguageModel(lang=lang, lang_youdao=lang_youdao, add_time=now_time, update_time=now_time)
+            language.save()
+            return response.json(0)
+        else:
+            return response.json(444)
+
+    def do_update(self, userID, request_dict, response):
+        # perm = ModelService.check_perm_uid_manage(userID, 0)
+        # if not perm:
+        #     return response.json(309)
+
+        id = request_dict.get('id', None)
+        if id:
+            lang = request_dict.get('lang', None)
+            lang_youdao = request_dict.get('lang_youdao', None)
+
+            update = {
+
+            }
+            if lang:
+                update['lang'] = lang
+
+            if lang_youdao:
+                update['lang_youdao'] = lang_youdao
+
+            LanguageModel.objects.filter(id=id).update(**update)
+            return response.json(0)
+        else:
+            return response.json(444)
+
+    def do_get(self, request_dict, response):
+        type = request_dict.get('type', None)
+
+        if type:
+            lang_qs = LanguageModel.objects.filter(lang=type)
+            if lang_qs.exists():
+                lang = lang_qs.values('id', 'lang', 'lang_youdao')
+
+                return response.json(0, lang)
+            else:
+                return response.json(173)
+        else:
+            return response.json(444)

+ 99 - 0
Controller/LogController.py

@@ -0,0 +1,99 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+from django.utils.decorators import method_decorator
+from django.views import View
+from django.views.decorators.csrf import csrf_exempt
+
+from Model.models import LogModel
+from Object.uidManageResponseObject import uidManageResponseObject
+from Object.TokenObject import TokenObject
+
+
+class LogView(View):
+
+    @method_decorator(csrf_exempt)
+    def dispatch(self, request, *args, **kwargs):
+        return super(LogView, self).dispatch(request, *args, **kwargs)
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.GET
+        operation = kwargs.get('operation')
+        return self.validate(request_dict, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.POST
+        operation = kwargs.get('operation')
+        return self.validate(request_dict, operation)
+
+    def validate(self, request_dict, operation):
+        token = TokenObject(request_dict.get('token', None))
+        response = uidManageResponseObject()
+
+        if token.code != 0:
+            return response.json(token.code)
+
+        if operation == 'query':
+            return self.do_query(request_dict, token, response)
+        elif operation == 'queryAll':
+            return self.do_query_all(request_dict, token, response)
+        elif operation == 'delete':
+            return self.do_delete(request_dict, response)
+        elif operation == 'adminQuery':
+            return self.do_admin_query(request_dict, token, response)
+        else:
+            return response.json(404)
+
+    def do_query(self, request_dict, token: TokenObject, response):
+        page = request_dict.get('page', None)
+        line = request_dict.get('line', None)
+
+        if page and line:
+            log_qs = LogModel.objects.filter(user__id=token.userID).values('id', 'operation', 'time', 'ip', 'user__username')
+            if log_qs.exists():
+                page = int(page)
+                line = int(line)
+                start = (page - 1) * line
+                count = log_qs.count()
+                data = log_qs[start:(start + line)]
+                return response.json(0, {'count': count, 'data': list(data)})
+            else:
+                return response.json(0, {'count': 0, 'data': []})
+        else:
+            return response.json(444)
+
+    def do_query_all(self, request_dict, token: TokenObject, response: uidManageResponseObject):
+        log_qs = LogModel.objects.filter(user__id=token.userID).values('id', 'operation', 'time', 'ip')
+        if log_qs.exists():
+            count = log_qs.count()
+            return response.json(0, {'count': count, 'data': list(log_qs)})
+        else:
+            return response.json(0, {'count': 0, 'data': []})
+
+    def do_delete(self, request_dict, response):
+        id = request_dict.get('id', None)
+
+        if id:
+            LogModel.objects.filter(id=id).delete()
+            return response.json(0)
+        else:
+            return response.json(444)
+
+    def do_admin_query(self, request_dict, token: TokenObject, response):
+        page = request_dict.get('page', None)
+        line = request_dict.get('limit', None)
+
+        if page and line:
+            log_qs = LogModel.objects.filter().values('id', 'operation', 'time', 'ip', 'user__username')
+            if log_qs.exists():
+                page = int(page)
+                line = int(line)
+                start = (page - 1) * line
+                count = log_qs.count()
+                data = log_qs[start:(start + line)]
+                return response.json(0, {'count': count, 'data': list(data)})
+            else:
+                return response.json(0, {'count': 0, 'data': []})
+        else:
+            return response.json(444)

+ 166 - 25
Controller/MealManage.py

@@ -13,12 +13,13 @@
 """
 """
 import traceback
 import traceback
 
 
+from django.db.models import F
 from django.utils import timezone
 from django.utils import timezone
 from django.utils.decorators import method_decorator
 from django.utils.decorators import method_decorator
 from django.views.decorators.csrf import csrf_exempt
 from django.views.decorators.csrf import csrf_exempt
 from django.views.generic.base import View
 from django.views.generic.base import View
 
 
-from Model.models import Store_Meal, VodBucketModel
+from Model.models import Store_Meal, VodBucketModel, Pay_Type, Lang
 from Object.ResponseObject import ResponseObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Object.TokenObject import TokenObject
 from Service.CommonService import CommonService
 from Service.CommonService import CommonService
@@ -68,19 +69,36 @@ class MealManage(View):
             return self.delete(request_dict, userID, response)
             return self.delete(request_dict, userID, response)
         elif operation == 'find':
         elif operation == 'find':
             return self.find(request_dict, userID, response)
             return self.find(request_dict, userID, response)
+        elif operation == 'query_language':
+            return self.query_language(request_dict, response)
+        elif operation == 'add_language':
+            return self.add_language(request_dict, response)
+        elif operation == 'delete_language':
+            return self.delete_language(request_dict, response)
+        elif operation == 'edit_language':
+            return self.edit_language(request_dict, response)
         else:
         else:
             return response.json(444, 'operation')
             return response.json(444, 'operation')
 
 
     def add(self, request_dict, userID, response):
     def add(self, request_dict, userID, response):
-        title = request_dict.get('title', None)
+        # title = request_dict.get('title', None)
         id = request_dict.get('id', None)
         id = request_dict.get('id', None)
         price = request_dict.get('price', None)
         price = request_dict.get('price', None)
-        content = request_dict.get('content', None)
+        # content = request_dict.get('content', None)
         day = request_dict.get('day', None)
         day = request_dict.get('day', None)
+        commodity_code = request_dict.get('commodity_code', None)
         currency = request_dict.get('currency', None)
         currency = request_dict.get('currency', None)
         bucketID = request_dict.get('bucketID', None)
         bucketID = request_dict.get('bucketID', None)
-        type = request_dict.get('type', None)
-        if not title or not id or not price or not day or not content:
+        paytype = request_dict.get('paytype', None)
+        virtual_price = request_dict.get('virtual_price', None)
+        is_discounts = request_dict.get('is_discounts', None)
+        discount_price = request_dict.get('discount_price', None)
+        expire = request_dict.get('expire', None)
+        symbol = request_dict.get('symbol', None)
+        is_show = request_dict.get('is_show', None)
+
+        # if not title or not id or not price or not day or not content:
+        if not id or not price or not day:
             return response.json(444, 'title,id,price,content,day,bucketID')
             return response.json(444, 'title,id,price,content,day,bucketID')
         own_perm = ModelService.check_perm(userID=userID, permID=40)
         own_perm = ModelService.check_perm(userID=userID, permID=40)
         if own_perm is not True:
         if own_perm is not True:
@@ -89,9 +107,13 @@ class MealManage(View):
             bucketQs = VodBucketModel.objects.filter(id=bucketID)
             bucketQs = VodBucketModel.objects.filter(id=bucketID)
             if Store_Meal.objects.filter(id=id):
             if Store_Meal.objects.filter(id=id):
                 return response.json(10, '已存在')
                 return response.json(10, '已存在')
-            store_meal = Store_Meal(id=id, title=title, price=price, content=content, day=day, bucket_id=bucketID,
-                                    currency=currency, type=type)
+            store_meal = Store_Meal(id=id, price=price, day=day, bucket_id=bucketID, commodity_code=commodity_code,
+                                    currency=currency, virtual_price=virtual_price, is_discounts=is_discounts,
+                                    discount_price=discount_price, expire=expire, symbol=symbol, is_show=is_show)
             store_meal.save()
             store_meal.save()
+            paytype = paytype.split(',')
+            if len(paytype) > 0:
+                Store_Meal.objects.get(id=id).pay_type.set(paytype)
         except Exception:
         except Exception:
             errorInfo = traceback.format_exc()
             errorInfo = traceback.format_exc()
             print(errorInfo)
             print(errorInfo)
@@ -102,42 +124,63 @@ class MealManage(View):
                     'bucket__bucket': bucketQs[0].bucket,
                     'bucket__bucket': bucketQs[0].bucket,
                     'bucket__storeDay': bucketQs[0].storeDay,
                     'bucket__storeDay': bucketQs[0].storeDay,
                     'id': id,
                     'id': id,
-                    'title': title,
                     'price': price,
                     'price': price,
-                    'content': content,
                     'currency': currency,
                     'currency': currency,
                     'day': day,
                     'day': day,
                     'add_time': str(store_meal.add_time),
                     'add_time': str(store_meal.add_time),
                     'update_time': str(store_meal.update_time)})
                     'update_time': str(store_meal.update_time)})
 
 
     def query(self, request_dict, response):
     def query(self, request_dict, response):
-
         page = int(request_dict.get('page', None))
         page = int(request_dict.get('page', None))
         line = int(request_dict.get('line', None))
         line = int(request_dict.get('line', None))
+        lang = request_dict.get('lang', 'cn')
         if page is None or line is None:
         if page is None or line is None:
             return response.json(444)
             return response.json(444)
-        qs = Store_Meal.objects.values("id", "title", "price", "content", "day", "add_time", "update_time", "currency",
-                                       "type", "bucket_id", "bucket__bucket", "commodity_type", "commodity_code",
-                                       "bucket__storeDay")
+
+        qs = Store_Meal.objects.filter(lang__lang=lang)
+        qs = qs.annotate(title=F('lang__title'), content=F('lang__content'))
+        qs = qs.values("id", "title", "price", "day", "add_time", "update_time", "currency", "expire", "symbol"
+                       , "commodity_type", "commodity_code", "virtual_price", "is_discounts", "discount_price"
+                       , "bucket_id", "bucket__bucket", "bucket__area", "bucket__storeDay", "bucket__mold", "is_show")
         res = {}
         res = {}
+        items_list = []
         if qs.exists():
         if qs.exists():
-            res['count'] = qs.count()
-            res['data'] = CommonService.qs_to_list(qs[(page - 1) * line:page * line])
+            ql = list(qs)
+            from operator import itemgetter
+            from itertools import groupby
+            ql.sort(key=itemgetter('bucket__area'))
+            ql = CommonService.qs_to_list(ql[(page - 1) * line:page * line])
+            # for area, items in groupby(ql, key=itemgetter('bucket__area')):
+            items_list = list(ql)
+            for key, val in enumerate(items_list):
+                pay_types = Pay_Type.objects.filter(store_meal=items_list[key]['id']).values("id", "payment")
+                items_list[key]['pay_type'] = list(pay_types)
+
+        res['count'] =Store_Meal.objects.filter(lang__lang=lang).count()
+        res['data'] = items_list
         return response.json(0, res)
         return response.json(0, res)
 
 
     def update(self, request_dict, userID, response):
     def update(self, request_dict, userID, response):
         id = request_dict.get('id', None)
         id = request_dict.get('id', None)
-        title = request_dict.get('title', None)
+        # title = request_dict.get('title', None)
         price = request_dict.get('price', None)
         price = request_dict.get('price', None)
         day = request_dict.get('day', None)
         day = request_dict.get('day', None)
-        content = request_dict.get('content', None)
+        # content = request_dict.get('content', None)
         currency = request_dict.get('currency', None)
         currency = request_dict.get('currency', None)
         bucketID = request_dict.get('bucketID', None)
         bucketID = request_dict.get('bucketID', None)
         commodity_type = request_dict.get('commodity_type', None)
         commodity_type = request_dict.get('commodity_type', None)
         commodity_code = request_dict.get('commodity_code', None)
         commodity_code = request_dict.get('commodity_code', None)
+        virtual_price = request_dict.get('virtual_price', None)
+        is_discounts = request_dict.get('is_discounts', None)
+        discount_price = request_dict.get('discount_price', None)
+        expire = request_dict.get('expire', None)
+        symbol = request_dict.get('symbol', None)
         type = request_dict.get('type', None)
         type = request_dict.get('type', None)
-        if not id or not title or not price or not content or not day or not type:
-            return response.json(444, 'id, title, price, content, day,type')
+        is_show = request_dict.get('is_show', None)
+        # if not id or not title or not price or not content or not day or not type:
+        if not id or not price or not day or not type:
+            # return response.json(444, 'id, title, price, content, day,type')
+            return response.json(444, 'id, price, day,type')
         own_perm = ModelService.check_perm(userID=userID, permID=30)
         own_perm = ModelService.check_perm(userID=userID, permID=30)
         if own_perm is not True:
         if own_perm is not True:
             return response.json(404)
             return response.json(404)
@@ -145,18 +188,29 @@ class MealManage(View):
             store_meal = Store_Meal.objects.get(id=id)
             store_meal = Store_Meal.objects.get(id=id)
             now_time = timezone.localtime(timezone.now())
             now_time = timezone.localtime(timezone.now())
             print(now_time)
             print(now_time)
-            store_meal.title = title
+            # store_meal.title = title
             store_meal.price = price
             store_meal.price = price
-            store_meal.content = content
+            # store_meal.content = content
             store_meal.commodity_type = commodity_type
             store_meal.commodity_type = commodity_type
             store_meal.commodity_code = commodity_code
             store_meal.commodity_code = commodity_code
+            store_meal.virtual_price = virtual_price
+            store_meal.is_discounts = is_discounts
+            store_meal.discount_price = discount_price
+            store_meal.expire = expire
+            store_meal.symbol = symbol
+            store_meal.is_show = is_show
             store_meal.day = day
             store_meal.day = day
-            store_meal.type = type
             if bucketID:
             if bucketID:
                 store_meal.bucket_id = bucketID
                 store_meal.bucket_id = bucketID
             if currency:
             if currency:
                 store_meal.currency = currency
                 store_meal.currency = currency
             store_meal.save()
             store_meal.save()
+            type = type.split(',')
+            if len(type) > 0:
+                Store_Meal.objects.get(id=id).pay_type.set(type)
+            else:
+                Store_Meal.objects.get(id=id).pay_type.clear()
+
         except Exception:
         except Exception:
             errorInfo = traceback.format_exc()
             errorInfo = traceback.format_exc()
             print(errorInfo)
             print(errorInfo)
@@ -198,6 +252,93 @@ class MealManage(View):
             return response.json(0, send_json)
             return response.json(0, send_json)
         return response.json(0)
         return response.json(0)
 
 
+    def query_language(self, request_dict, response):
+        # 查询套餐语言
+        page = int(request_dict.get('page', None))
+        line = int(request_dict.get('line', None))
+        id = request_dict.get('id', None)
+        if page is None or line is None:
+            return response.json(444)
+
+        if id:
+            # 如果传入id,只查询id下的语言
+            storeMeal_lang_qs = Store_Meal.objects.filter(id=id, lang__isnull=False).values('id', 'lang__id',
+                                                                                            'lang__lang',
+                                                                                            'lang__title',
+                                                                                            'lang__content',
+                                                                                            'lang__discount_content')
+        else:
+            storeMeal_lang_qs = Store_Meal.objects.filter(lang__isnull=False).values('id', 'lang__id', 'lang__lang',
+                                                                                     'lang__title', 'lang__content',
+                                                                                     'lang__discount_content')
+        count = storeMeal_lang_qs.count()
+        storeMeal_lang_qs = storeMeal_lang_qs[(page - 1) * line:page * line]
+        res = {
+            'datas': list(storeMeal_lang_qs),
+            'count': count
+        }
+        return response.json(0, res)
+
+    def add_language(self, request_dict, response):
+        # 添加套餐语言
+        store_meal_id = request_dict.get('store_meal_id', None)
+        # lang_id = request_dict.get('lang_id', None)
+        lang = request_dict.get('lang', None)
+        title = request_dict.get('title', None)
+        content = request_dict.get('content', None)
+        discount_content = request_dict.get('discount_content', '')
+        if not store_meal_id or not lang or not title or not content:
+            return response.json(444, 'store_meal_id,lang,title,content')
+        # 查询该套餐是否存在
+        storeMeal_qs = Store_Meal.objects.get(id=store_meal_id)
+        if not storeMeal_qs:
+            return response.json(500)
+        lang_obj = Lang.objects.filter(lang=lang, title=title, content=content, discount_content=discount_content)
+        if not lang_obj.exists():
+            # 数据不存在,lang表创建数据
+            Lang.objects.create(lang=lang, title=title, content=content, discount_content=discount_content)
+            lang_obj = Lang.objects.filter(lang=lang, title=title, content=content, discount_content=discount_content)
+        storeMeal_qs.lang.add(*lang_obj)  # store_meal表添加语言数据
+        return response.json(0)
+
+    def edit_language(self, request_dict, response):
+        # 编辑套餐语言
+        store_meal_id = request_dict.get('store_meal_id', None)
+        lang_id = request_dict.get('lang_id', None)
+        lang = request_dict.get('lang', None)
+        title = request_dict.get('title', None)
+        content = request_dict.get('content', None)
+        discount_content = request_dict.get('discount_content', '')
+        if not store_meal_id or not lang_id or not lang or not title or not content:
+            return response.json(444, 'store_meal_id,lang_id,lang,title,content')
+        storeMeal_qs = Store_Meal.objects.get(id=store_meal_id)
+        if not storeMeal_qs:
+            return response.json(500)
+        Lang.objects.filter(id=lang_id).update(lang=lang, title=title, content=content, discount_content=discount_content)
+        return response.json(0)
+        # # 删除原有数据
+        # lang_qs = Lang.objects.filter(id=lang_id)
+        # storeMeal_qs.lang.remove(*lang_qs)
+        # lang_obj = Lang.objects.filter(lang=lang, title=title, content=content, discount_content=discount_content)
+        # if not lang_obj.exists():
+        #     # 数据不存在,lang表创建数据
+        #     Lang.objects.create(lang=lang, title=title, content=content, discount_content=discount_content)
+        #     lang_obj = Lang.objects.filter(lang=lang, title=title, content=content, discount_content=discount_content)
+        # storeMeal_qs.lang.add(*lang_obj)  # store_meal表添加语言数据
+        # return response.json(0)
+
+    def delete_language(self, request_dict, response):
+        # 删除套餐语言
+        store_meal_id = request_dict.get('store_meal_id', None)
+        lang_id = request_dict.get('lang_id', None)
+
+        storeMeal_qs = Store_Meal.objects.get(id=store_meal_id)
+        if not storeMeal_qs:
+            return response.json(500)
+        lang_qs = Lang.objects.filter(id=lang_id)
+        storeMeal_qs.lang.remove(*lang_qs)
+        return response.json(0)
+
 
 
 '''
 '''
 用户获取全部套餐信息
 用户获取全部套餐信息
@@ -241,12 +382,12 @@ class MealView(View):
             qs = Store_Meal.objects.filter(bucket__mold=1). \
             qs = Store_Meal.objects.filter(bucket__mold=1). \
                 values("id", "title", "content", "price", "day", "currency",
                 values("id", "title", "content", "price", "day", "currency",
                        "bucket__storeDay", "bucket__bucket", "bucket__area",
                        "bucket__storeDay", "bucket__bucket", "bucket__area",
-                       "type")
+                       "type", "symbol")
         else:
         else:
             qs = Store_Meal.objects.all(). \
             qs = Store_Meal.objects.all(). \
                 values("id", "title", "content", "price", "day", "currency",
                 values("id", "title", "content", "price", "day", "currency",
                        "bucket__storeDay", "bucket__bucket", "bucket__area",
                        "bucket__storeDay", "bucket__bucket", "bucket__area",
-                       "type")
+                       "type", "symbol")
         if qs.exists():
         if qs.exists():
             ql = list(qs)
             ql = list(qs)
             from operator import itemgetter
             from operator import itemgetter
@@ -266,4 +407,4 @@ class MealView(View):
             }
             }
             return response.json(0, result)
             return response.json(0, result)
         else:
         else:
-            return response.json(0)
+            return response.json(0)

+ 80 - 9
Controller/OTAEquipment.py

@@ -479,7 +479,7 @@ def getNewVerInterface(request):
     now_ver = request_dict.get('ver', None)
     now_ver = request_dict.get('ver', None)
     uid = request_dict.get('uid', None)
     uid = request_dict.get('uid', None)
     if not code or not now_ver:
     if not code or not now_ver:
-        return response.json(902, {'param': 'code,ver'})
+        return response.json(902, {'param':'code,ver'})
         # return response.json(444, 'code,ver')
         # return response.json(444, 'code,ver')
     tko = TokenObject(token)
     tko = TokenObject(token)
     response.lang = tko.lang
     response.lang = tko.lang
@@ -494,7 +494,7 @@ def getNewVerInterface(request):
 
 
     if equipmentValid.exists():
     if equipmentValid.exists():
         equipment = equipmentValid[0]
         equipment = equipmentValid[0]
-        redisObject = RedisObject(db=3)
+        redisObject = RedisObject()
         key = 'limit_{eid}'.format(eid=equipment.eid)
         key = 'limit_{eid}'.format(eid=equipment.eid)
 
 
         evl_qs = redisObject.get_data(key=key)
         evl_qs = redisObject.get_data(key=key)
@@ -506,15 +506,15 @@ def getNewVerInterface(request):
                 redisObject.set_data(key=key, val=json.dumps(list(evl_qs.values())), expire=600)
                 redisObject.set_data(key=key, val=json.dumps(list(evl_qs.values())), expire=600)
         if evl_qs and len(evl_qs) > 0:
         if evl_qs and len(evl_qs) > 0:
             evl = evl_qs[0]
             evl = evl_qs[0]
-            if evl['type'] == 1:  # uid限制
+            if evl['type'] == 1: # uid限制
                 uids = json.loads(evl['content'])
                 uids = json.loads(evl['content'])
                 if not uids.__contains__(uid):
                 if not uids.__contains__(uid):
                     return response.json(902)
                     return response.json(902)
-            elif evl['type'] == 2:  # user限制
+            elif evl['type'] == 2: # user限制
                 users = json.loads(evl['content'])
                 users = json.loads(evl['content'])
                 if not users.__contains__(tko.userID):
                 if not users.__contains__(tko.userID):
                     return response.json(902)
                     return response.json(902)
-            elif evl['type'] == 3:  # 国家地区限制
+            elif evl['type'] == 3: # 国家地区限制
                 countries = json.loads(evl['content'])
                 countries = json.loads(evl['content'])
                 country_ip_qs = CountryIPModel.objects.filter(user_ex__userID=tko.userID)
                 country_ip_qs = CountryIPModel.objects.filter(user_ex__userID=tko.userID)
                 if country_ip_qs.exists():
                 if country_ip_qs.exists():
@@ -538,10 +538,10 @@ def getNewVerInterface(request):
             #     url = SERVER_DOMAIN + 'dlotapack/' + file_path
             #     url = SERVER_DOMAIN + 'dlotapack/' + file_path
             # else:
             # else:
             #     这里调用国内服务器进行下载,防止下载bug
             #     这里调用国内服务器进行下载,防止下载bug
-            # if code == '18E201200CA' or code == '18E201200CZ':
-            #     url = 'http://www.zositech.xyz/dlotapack/' + file_path
-            # else:
-            #     url = SERVER_DOMAIN + 'dlotapack/' + file_path
+                # if code == '18E201200CA' or code == '18E201200CZ':
+                #     url = 'http://www.zositech.xyz/dlotapack/' + file_path
+                # else:
+                #     url = SERVER_DOMAIN + 'dlotapack/' + file_path
             return response.json(0, {
             return response.json(0, {
                 'ver': ver,
                 'ver': ver,
                 'url': url,
                 'url': url,
@@ -685,3 +685,74 @@ def downloadOTAInterfaceV2(request, fullPath, *callback_args, **callback_kwargs)
             return res.json(907)
             return res.json(907)
     else:
     else:
         return res.json(444, 'fullPath')
         return res.json(444, 'fullPath')
+
+
+@csrf_exempt
+def getDownLoadOTApackUrl(request):
+    # QT获取升级文件的下载链接
+    response = ResponseObject()
+    if request.method == "POST":
+        request_dict = request.POST
+    elif request.method == "GET":
+        request_dict = request.GET
+    else:
+        return response.json(444)
+    deviceType = request_dict.get('deviceType', None)
+    version = request_dict.get('version', None)
+    if not deviceType or not version:
+        return response.json(444, 'deviceType or version')
+    equipmentVersion = Equipment_Version.objects.filter(mci=deviceType, version=version)
+    # 判断是否有该版本存在
+    if not equipmentVersion.exists():
+        return response.json(907)
+    file_path = equipmentVersion[0].filePath
+    if file_path:
+        if file_path.find('static/otapack') != -1:  # 只下载otapack路径下的文件
+            url = SERVER_DOMAIN + 'OTA/downloadsPack/' + file_path  # 复用app下载ota包的方式
+            # SERVER_DOMAIN = 'https://test.dvema.com/'
+            # url = SERVER_DOMAIN + 'OTA/downloadsPack/' + file_path
+            res = {
+                "url": url,
+            }
+            return response.json(0, res)
+        else:
+            return response.json(901)
+    else:
+        return response.json(901)
+
+
+@csrf_exempt
+def checkMaxVersion(request):
+    # QT检查ota设备软件版本是否需要更新
+    response = ResponseObject()
+    if request.method == "POST":
+        request_dict = request.POST
+    elif request.method == "GET":
+        request_dict = request.GET
+    else:
+        return response.json(444)
+    deviceType = request_dict.get('deviceType', None)
+    version = request_dict.get('version', None) # 设备版本:当前版本+设备规格代码
+    lang = request_dict.get('lang', None)   # 'zh-Hans','en'
+    if not deviceType or not version:
+        return response.json(444, 'deviceType or version')
+    now_version = version[1:version.rindex('.')] # 去掉V
+    code = version[version.rindex('.')+1:]
+    equipmentVersion = Equipment_Version.objects.filter(mci=deviceType, code=code, lang=lang, status=1) # order by data_joined
+    # 判断是否有该版本存在
+    if not equipmentVersion.exists():
+        return response.json(907)
+
+    filePath = equipmentVersion[0].filePath
+    softwareVersion = equipmentVersion[0].softwareVersion   # 可用最新版本的版本号
+    maxVersion = equipmentVersion[0].max_ver
+    if now_version >= softwareVersion:
+        # 当前版本大于等于最新版本,不需要更新
+        return response.json(902)
+    url = SERVER_DOMAIN + 'OTA/downloadsPack/' + filePath   # 复用app下载ota包的方式
+    res = {
+        'url': url,
+    }
+    return response.json(0, res)
+
+

+ 77 - 0
Controller/OperatingLogs.py

@@ -0,0 +1,77 @@
+from django.views import View
+from Object.ResponseObject import ResponseObject
+from Model.models import OperatingLogsModel
+from Controller.ProcessInfo import ProcessInfoView
+from Object.TokenObject import TokenObject
+from Object.LogsObject import LogsObject
+
+class OperatingLogsView(View):
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.GET
+        operation = kwargs.get('operation', None)
+        return self.validate(request_dict, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.POST
+        operation = kwargs.get('operation', None)
+        return self.validate(request_dict, operation)
+
+    def validate(self, request_dict, operation):
+        response = LogsObject()
+        # token = request_dict.get('token', None)
+        # tko = TokenObject(token)
+
+        if operation is None:
+            return response.json(444, 'error path')
+        elif operation == 'add_logs':
+            return self.add_logs(request_dict, response)
+        elif operation == 'delete_logs':
+            return self.delete_logs(request_dict, response)
+
+    def add_logs(self, request_dict, response):
+        d = self.get_info(request_dict)
+        if(d['userId'] == ''):
+            return response.json(908)
+        OperatingLogsModel.objects.create(
+            userId=d['userId'],
+            operatingcontent=d['operatingcontent'],
+            operatingtype=d['operatingtype'],
+            is_saveprocessinfo=d['is_saveprocessinfo'],
+            devUid=d['devUid'],
+            userIp=d['userIp'],
+        )
+        if d['is_saveprocessinfo'] == '1':
+            ProcessInfoView.validate(ProcessInfoView(), request_dict, 'add_processinfo')
+        return response.json(0)
+
+    def delete_logs(self, request_dict, response):
+        userId = request_dict.get('userId', None)
+        if userId:
+            OperatingLogsModel.objects.filter(userId=userId).delete()
+            return response.json(0)
+        else:
+            return response.json(444, 'userId is not exist')
+
+
+    def get_info(self, request_dict):
+        userId = request_dict.get('userId', None)
+        operatingcontent = request_dict.get('operatingcontent', None)
+        operatingtype = request_dict.get('operatingtype', None)
+        is_saveprocessinfo = request_dict.get('is_saveprocessinfo', None)
+        devUid = request_dict.get('devUid', None)
+        userIp = request_dict.get('userIp', None)
+        return {
+            'userId': userId,
+            'operatingcontent': operatingcontent,
+            'operatingtype': operatingtype,
+            'is_saveprocessinfo': is_saveprocessinfo,
+            'devUid': devUid,
+            'userIp': userIp,
+        }
+
+
+
+
+

+ 161 - 9
Controller/OrderContrller.py

@@ -12,9 +12,15 @@
 @Contact: chanjunkai@163.com
 @Contact: chanjunkai@163.com
 """
 """
 import time
 import time
+
+import paypalrestsdk
+from django.db.models import F
 from django.utils.decorators import method_decorator
 from django.utils.decorators import method_decorator
 from django.views.decorators.csrf import csrf_exempt
 from django.views.decorators.csrf import csrf_exempt
 from django.views.generic.base import View
 from django.views.generic.base import View
+
+from Ansjer.config_test import PAYPAL_CRD
+from Object.AliPayObject import AliPayObject
 from Object.ResponseObject import ResponseObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Object.TokenObject import TokenObject
 from Model.models import Order_Model, Device_Info
 from Model.models import Order_Model, Device_Info
@@ -50,7 +56,7 @@ class OrderView(View):
         token = request_dict.get('token', None)
         token = request_dict.get('token', None)
         # 设备主键uid
         # 设备主键uid
         tko = TokenObject(token)
         tko = TokenObject(token)
-        response.lang = tko.lang
+        response.lang = request_dict.get('language', 'en')
         if tko.code != 0:
         if tko.code != 0:
             return response.json(tko.code)
             return response.json(tko.code)
         userID = tko.userID
         userID = tko.userID
@@ -62,6 +68,14 @@ class OrderView(View):
             return self.do_admin_query(request_dict, userID, response)
             return self.do_admin_query(request_dict, userID, response)
         elif operation == 'detail':
         elif operation == 'detail':
             return self.do_detail(request_dict, userID, response)
             return self.do_detail(request_dict, userID, response)
+        elif operation == 'queryByStatus':
+            return self.do_query_order_by_status(request_dict, userID, response)
+        elif operation == 'orderDetail':
+            return self.do_query_order_detail(request_dict, userID, response)
+        elif operation == 'cancel':
+            return self.do_cancel_order(request_dict, userID, response)
+        elif operation == 'delete':
+            return self.do_delete_order(request_dict, userID, response)
         else:
         else:
             return response.json(444, 'error path')
             return response.json(444, 'error path')
 
 
@@ -77,11 +91,12 @@ class OrderView(View):
         page = request_dict.get('page', None)
         page = request_dict.get('page', None)
         line = request_dict.get('line', None)
         line = request_dict.get('line', None)
         uid = request_dict.get('uid', None)
         uid = request_dict.get('uid', None)
+        lang = request_dict.get('lang', 'en')
         if not page or not line:
         if not page or not line:
             return response.json(444, 'page,line')
             return response.json(444, 'page,line')
         page = int(page)
         page = int(page)
         line = int(line)
         line = int(line)
-        omqs = Order_Model.objects.filter(userID_id=userID, status=1)
+        omqs = Order_Model.objects.filter(userID_id=userID, status=1, rank__lang__lang=lang)
         # 筛选指定设备id的订单
         # 筛选指定设备id的订单
         if uid:
         if uid:
             omqs.filter(UID=uid)
             omqs.filter(UID=uid)
@@ -89,12 +104,13 @@ class OrderView(View):
             return response.json(173)
             return response.json(173)
             # return response.json(10, '订单不存在')
             # return response.json(10, '订单不存在')
         count = omqs.count()
         count = omqs.count()
+        omqs = omqs.annotate(rank__title=F('rank__lang__title'), rank__content=F('rank__lang__content'))
         order_ql = omqs[(page - 1) * line:page * line].values("orderID", "UID", "channel", "desc", "price", "currency",
         order_ql = omqs[(page - 1) * line:page * line].values("orderID", "UID", "channel", "desc", "price", "currency",
                                                               "addTime",
                                                               "addTime",
-                                                              "updTime", "endTime", "paypal", "rank__day", "payType",
+                                                              "updTime", "paypal", "rank__day", "payType",
                                                               "rank__price", "status",
                                                               "rank__price", "status",
                                                               "rank__content", "rank__title", "rank__currency",
                                                               "rank__content", "rank__title", "rank__currency",
-                                                              "rank_id")
+                                                              "rank_id","rank__expire")
         order_list = list(order_ql)
         order_list = list(order_ql)
         data = []
         data = []
         nowTime = int(time.time())
         nowTime = int(time.time())
@@ -112,6 +128,7 @@ class OrderView(View):
                     d['did'] = did['id']
                     d['did'] = did['id']
                     d['Type'] = did['Type']
                     d['Type'] = did['Type']
                     data.append(d)
                     data.append(d)
+            d['rank__expire_unit'] = '月' if lang == 'cn' else 'month'
         return response.json(0, {'data': data, 'count': count})
         return response.json(0, {'data': data, 'count': count})
 
 
     # admins ^^^^^^^^^^^^
     # admins ^^^^^^^^^^^^
@@ -134,7 +151,7 @@ class OrderView(View):
             orderID = request_dict.get('orderID', None)
             orderID = request_dict.get('orderID', None)
             page = int(page)
             page = int(page)
             line = int(line)
             line = int(line)
-            omqs = Order_Model.objects.filter()
+            omqs = Order_Model.objects.all()
             # 筛选指定设备id的订单
             # 筛选指定设备id的订单
             if uid:
             if uid:
                 omqs = omqs.filter(UID=uid)
                 omqs = omqs.filter(UID=uid)
@@ -146,14 +163,149 @@ class OrderView(View):
                 return response.json(0, [])
                 return response.json(0, [])
             count = omqs.count()
             count = omqs.count()
             order_ql = omqs[(page - 1) * line:page * line].values("orderID", "UID", "channel", "desc", "price",
             order_ql = omqs[(page - 1) * line:page * line].values("orderID", "UID", "channel", "desc", "price",
-                                                                  "currency", "addTime", "updTime", "endTime", "paypal",
+                                                                  "currency", "addTime", "updTime", "paypal",
                                                                   "payType",
                                                                   "payType",
                                                                   "rank__day",
                                                                   "rank__day",
-                                                                  "rank__price", "status",
-                                                                  "rank__content", "rank__title", "rank__currency",
-                                                                  "rank_id")
+                                                                  "rank__price", "status")
             order_list = list(order_ql)
             order_list = list(order_ql)
             return response.json(0, {'data': order_list, 'count': count})
             return response.json(0, {'data': order_list, 'count': count})
 
 
         else:
         else:
             return response.json(404)
             return response.json(404)
+
+    def do_query_order_by_status(self, request_dict, userID, response):
+        status = request_dict.get('status', None)
+        page = request_dict.get('page', None)
+        line = request_dict.get('line', None)
+        lang = request_dict.get('lang', 'en')
+        if status and page and line:
+            order_qs = None
+            status = int(status)
+            if status == -1: # 获取所有订单
+                order_qs = Order_Model.objects.filter(userID__userID=userID,rank__lang__lang=lang)
+            elif status == 0: # 获取【代付款】订单
+                order_qs = Order_Model.objects.filter(userID__userID=userID, status=0,rank__lang__lang=lang)
+            elif status == 1:
+                order_qs = Order_Model.objects.filter(userID__userID=userID, status=1,rank__lang__lang=lang)
+
+            if order_qs is None or not order_qs.exists():
+                return response.json(0, {'data': [], 'count': 0})
+
+            page = int(page)
+            line = int(line)
+            start = (page - 1) * line
+            end = status + line
+            count = order_qs.count()
+            order_qs = order_qs.annotate(rank__title=F('rank__lang__title'))
+            order_qs = order_qs[start:end].values("orderID", "UID", "channel", "desc", "price",
+                                                  "currency", "addTime", "payType", "rank__day", "rank__price",
+                                                  "status", 'channel', "rank__title", "currency")
+            return response.json(0, {'data': list(order_qs), 'count': count})
+        else:
+            return response.json(444)
+
+    def do_query_order_detail(self, request_dict, userID, response):
+        orderID = request_dict.get('orderID', None)
+        lang = request_dict.get('lang', 'en')
+        if orderID:
+            order_qs = Order_Model.objects.filter(orderID=orderID, userID__userID=userID, rank__lang__lang=lang)
+            if order_qs.exists():
+                print(order_qs)
+                order_qs = order_qs.annotate(rank__title=F('rank__lang__title'))
+                order = order_qs.values("orderID", "UID", "channel", "desc", "price",
+                                        "currency", "addTime", "endTime", "payType",
+                                        "rank__day", "rank__price", "status", 'channel', "rank__title", "currency")[0]
+
+                return response.json(0, {'data': order})
+            else:
+                return response.json(173)
+        else:
+            return response.json(444)
+
+    def do_cancel_order(self, request_dict, userID, response):
+        orderID = request_dict.get('orderID', None)
+        lang = request_dict.get('lang', 'en')
+        if orderID is None:
+            return response.json(444)
+
+        order_qs = Order_Model.objects.filter(orderID=orderID,rank__lang__lang=lang)
+        if not order_qs.exists():
+            return response.json(800)
+
+        order = order_qs[0]
+        if order.status != 0:
+            return response.json(802)
+
+        if order.payType == 1: # 支付宝支付的订单
+            return self.do_cancel_alipay_order(order, response)
+        else:
+            return self.do_cancel_paypal_order(order, response)
+
+    def do_delete_order(self, request_dict, userID, response):
+        orderID = request_dict.get('orderID', None)
+
+        if orderID:
+            Order_Model.objects.filter(orderID=orderID, userID__userID=userID).delete()
+            return response.json(0)
+        else:
+            return response.json(444)
+
+    def do_cancel_alipay_order(self, order, response):
+        # 交易状态:
+        # WAIT_BUYER_PAY(交易创建,等待买家付款)
+        # TRADE_CLOSED(未付款交易超时关闭,或支付完成后全额退款)
+        # TRADE_SUCCESS(交易支付成功)
+        # TRADE_FINISHED(交易结束,不可退款)
+
+        try:
+            aliPayObj = AliPayObject()
+            alipay = aliPayObj.conf()
+            result = alipay.api_alipay_trade_query(out_trade_no=order.orderID)
+            print(result)
+
+            if result['code'] == '100000':
+                trade_status = result['trade_status']
+                if trade_status == 'TRADE_CLOSED' or trade_status == 'WAIT_BUYER_PAY':
+                    order.status = 2
+                    order.updTime = int(time.time())
+                    order.save()
+                    return response.json(0)
+                elif trade_status == 'TRADE_SUCCESS':
+                    order.status = 1
+                    order.updTime = int(time.time())
+                    order.save()
+                    return response.json(802)
+            elif result['code'] == '40004':
+                order.status = 2
+                order.updTime = int(time.time())
+                order.save()
+                return response.json(0)
+            else:
+                return response.json(10, result['sub_msg'])
+
+        except Exception as e:
+            print(repr(e))
+            return response.json(10, repr(e))
+
+    def do_cancel_paypal_order(self, order, response):
+        paypalrestsdk.configure(PAYPAL_CRD)
+        payment = paypalrestsdk.Payment.find(order.trade_no)
+        transactions = payment['transactions']
+        transaction = transactions[0]
+        related_resources = transaction['related_resources']
+        if len(related_resources) > 0:
+            related_resource = related_resources[0]
+            sale = related_resource['sale']
+            if sale['state'] == 'completed':
+                order.status = 1
+            elif sale['state'] == 'refunded':
+                order.status = 3
+
+            order.updTime = int(time.time())
+            order.save()
+            return response.json(802)
+
+        order.status = 2
+        order.updTime = int(time.time())
+        order.save()
+        return response.json(0)

+ 104 - 0
Controller/OrderTaskController.py

@@ -0,0 +1,104 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+import json
+
+from django.views import View
+
+from Model.models import OrderTaskModel
+from Object.uidManageResponseObject import uidManageResponseObject
+from Object.TokenObject import TokenObject
+from Service.ModelService import ModelService
+
+
+class OrderTaskView(View):
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation', None)
+        request_dict = request.GET
+        return self.validate(request_dict, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation', None)
+        request_dict = request.POST
+        return self.validate(request_dict, operation)
+
+    def validate(self, request_dict, operation):
+
+        token = request_dict.get('token', None)
+
+        response = uidManageResponseObject()
+        token = TokenObject(token)
+
+        if token.code != 0:
+            return response.json(0)
+
+        if operation == 'query':
+            return self.do_query(token.userID, request_dict, response)
+        elif operation == 'update':
+            return self.do_update(token.userID, request_dict, response)
+        elif operation == 'delete':
+            return self.do_delete(token.userID, request_dict, response)
+        else:
+            return response.json(404)
+
+    def do_query(self, userID, request_dict, response):
+        # perm = ModelService.check_perm_uid_manage(userID, 0)
+        # if not perm:
+        #     return response.json(309)
+
+        page = request_dict.get('page', None)
+        line = request_dict.get('limit', None)
+
+        if page and line:
+
+            order_task_qs = OrderTaskModel.objects.filter()
+            res = {
+                'count': 0,
+                'data': []
+            }
+            if order_task_qs.exists():
+                page = int(page)
+                line = int(line)
+
+                res['count'] = order_task_qs.count()
+                start = (page - 1) * line
+                end = start + line
+
+                order_task_qs = order_task_qs[start:end].values()
+                res['data'] = list(order_task_qs)
+
+            return response.json(0, res)
+        else:
+            return response.json(444)
+
+    def do_update(self, userID, request_dict, response):
+        # perm = ModelService.check_perm_uid_manage(userID, 0)
+        # if not perm:
+        #     return response.json(309)
+
+        id = request_dict.get('id', None)
+        content = request_dict.get('content', None)
+        print(content)
+
+        if id and content:
+            content = json.loads(content)
+            print(content)
+            OrderTaskModel.objects.filter(id=id).update(**content)
+            return response.json(0)
+        else:
+            return response.json(444)
+
+    def do_delete(self, userID, request_dict, response):
+        # perm = ModelService.check_perm_uid_manage(userID, 0)
+        # if not perm:
+        #     return response.json(309)
+
+        id = request_dict.get('id', None)
+
+        if id:
+            OrderTaskModel.objects.filter(id=id).delete()
+            return response.json(0)
+        else:
+            return response.json(444)

+ 64 - 0
Controller/ProcessInfo.py

@@ -0,0 +1,64 @@
+from django.views import View
+from Object.ResponseObject import ResponseObject
+from Model.models import ProcessInfoLogsModel
+from Object.TokenObject import TokenObject
+from Object.LogsObject import LogsObject
+
+class ProcessInfoView(View):
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.GET
+        operation = kwargs.get('operation', None)
+        return self.validate(request_dict, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.POST
+        operation = kwargs.get('operation', None)
+        return self.validate(request_dict, operation)
+
+    def validate(self, request_dict, operation):
+        response = LogsObject()
+        # token = request_dict.get('token', None)
+
+        if operation is None:
+            return response.json(444, 'error path')
+        elif operation == 'add_processinfo':
+            return self.add_processinfo(request_dict, response)
+        elif operation == 'delete_processinfo':
+            return self.delete_processinfo(request_dict, response)
+
+    def add_processinfo(self, request_dict, response):
+        d = self.get_info(request_dict)
+        if(d['userId'] == ''):
+            return response.json(908)
+        ProcessInfoLogsModel.objects.create(
+            userId=d['userId'],
+            devUid=d['devUid'],
+            operatingcontent=d['operatingcontent'],
+        )
+        return response.json(0)
+
+    def delete_processinfo(self, request_dict, response):
+        userId = request_dict.get('userId', None)
+        if userId:
+            ProcessInfoLogsModel.objects.filter(userId=userId).delete()
+            return response.json(0)
+        else:
+            return response.json(444, 'userId is not exist')
+
+    def get_info(self, request_dict):
+        devUid = request_dict.get('devUid', None)
+        operatingcontent = request_dict.get('operatingcontent', None)
+        operatingtime = request_dict.get('operatingtime', None)
+        userId = request_dict.get('userId', None)
+        return {
+            'devUid': devUid,
+            'operatingcontent': operatingcontent,
+            'operatingtime': operatingtime,
+            'userId': userId,
+        }
+
+
+
+

+ 295 - 0
Controller/RegionController.py

@@ -0,0 +1,295 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+import json
+import time
+
+from django.views import View
+
+from Model.models import RegionModel, CountryModel, LanguageModel, CountryLanguageModel
+from Object.uidManageResponseObject import uidManageResponseObject
+from Object.TokenObject import TokenObject
+from Service.CommonService import CommonService
+from Service.ModelService import ModelService
+
+
+class RegionView(View):
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation', None)
+        request_dict = request.GET
+        return self.validate(request_dict, operation)
+
+    def post(self, request, *arg, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation', None)
+        request_dict = request.POST
+        return self.validate(request_dict, operation)
+
+    def validate(self, request_dict, operation):
+        token = TokenObject(request_dict.get('token', None))
+
+        response = uidManageResponseObject()
+
+        if operation == 'getCountry':
+            return self.get_country(request_dict, response)
+        else:
+            if token.code != 0:
+                return response.json(token.code)
+
+            if operation == 'add':
+                return self.do_add(token.userID, request_dict, response)
+            elif operation == 'update':
+                return self.do_update(token.userID, request_dict, response)
+            elif operation == 'delete':
+                return self.do_delete(token.userID, request_dict, response)
+            elif operation == 'list':
+                return self.do_list(token.userID, request_dict, response)
+            elif operation == 'addCountry':
+                return self.do_add_country(token.userID, request_dict, response)
+            elif operation == 'updateCountry':
+                return self.do_update_country(token.userID, request_dict, response)
+            elif operation == 'deleteCountry':
+                return self.do_delete_country(token.userID, request_dict, response)
+            elif operation == 'listCountry':
+                return self.do_list_country(token.userID, request_dict, response)
+            else:
+                return response.json(404)
+
+    def do_add(self, userID, request_dict, response):
+        # perm = ModelService.check_perm_uid_manage(userID, 0)
+        # if not perm:
+        #     return response.json(309)
+
+        name = request_dict.get('region', None)
+
+        if name:
+            region = RegionModel(name=name)
+            region.save()
+
+            return response.json(0)
+        else:
+            return response.json(444)
+
+    def do_update(self,  userID, request_dict, response):
+        # perm = ModelService.check_perm_uid_manage(userID, 0)
+        # if not perm:
+        #     return response.json(309)
+
+        id = request_dict.get('id', None)
+        name = request_dict.get('region', None)
+
+        if id and name:
+            region_qs = RegionModel.objects.filter(id=id)
+            if region_qs.exists():
+                region = region_qs[0]
+                region.name = name
+                region.save()
+                return response.json(0)
+            else:
+                return response.json(173)
+        else:
+            return response.json(444)
+
+    def do_delete(self, userID, request_dict, response):
+        # perm = ModelService.check_perm_uid_manage(userID, 0)
+        # if not perm:
+        #     return response.json(309)
+
+        id = request_dict.get('id', None)
+
+        if id:
+            region_qs = RegionModel.objects.filter(id=id)
+            if region_qs.exists():
+                region_qs.delete()
+                return response.json(0)
+            else:
+                return response.json(173)
+        else:
+            return response.json(444)
+
+    def do_list(self, userID, request_dict, response):
+        # perm = ModelService.check_perm_uid_manage(userID, 0)
+        # if not perm:
+        #     return response.json(309)
+
+        page = request_dict.get('page', None)
+        line = request_dict.get('limit', None)
+
+        if page and line:
+            page = int(page)
+            line = int(line)
+
+            start = (page - 1) * line
+            end = start + line
+
+            region_qs = RegionModel.objects.filter()
+            count = region_qs.count()
+
+            region_qs = region_qs[start: end].values()
+
+            res = {
+                'count': count,
+                'data': list(region_qs)
+            }
+
+            return response.json(0, res)
+        else:
+            return response.json(444)
+
+    def do_add_country(self, userID, request_dict, response):
+        # perm = ModelService.check_perm_uid_manage(userID, 0)
+        # if not perm:
+        #     return response.json(309)
+
+        number = request_dict.get('number', None)
+        region_id = request_dict.get('region_id', None)
+        countries = request_dict.get('countries', None)
+        countries_en = request_dict.get('countries_en', None)
+
+        if number and region_id and countries:
+            res = {
+                '1': countries,
+                '2': countries_en
+            }
+            now_time = int(time.time())
+            # countries = json.loads(countries)
+
+            country_qs =CountryModel.objects.filter(number=number)
+            if not country_qs.exists():
+                country = CountryModel(number=number, region_id=region_id, add_time=now_time, update_time=now_time, country_name=countries)
+                country.save()
+            else:
+                country = country_qs[0]
+
+            for item in res:
+                country_language_qs = CountryLanguageModel.objects.filter(language_id=item, country_id=country.id)
+                if not country_language_qs.exists():
+                    countryLanguage = CountryLanguageModel(
+                        country_name=res[item], language_id=item, country_id=country.id, add_time=now_time, update_time=now_time)
+                    countryLanguage.save()
+            return response.json(0)
+        else:
+            return response.json(444)
+
+    def do_update_country(self, userID, request_dict, response):
+        # perm = ModelService.check_perm_uid_manage(userID, 0)
+        # if not perm:
+        #     return response.json(309)
+
+        id = request_dict.get('country_id', None)
+        number = request_dict.get('number', None)
+        region_id = request_dict.get('region_id', None)
+        countries = request_dict.get('countries', None)
+
+        if id and number and region_id and countries:
+
+            country_qs = CountryModel.objects.filter(id=id)
+            if not country_qs.exists():
+                return response.json(173)
+
+            now_time = int(time.time())
+            countries = json.loads(countries)
+            country = {
+                'number': number,
+                'region_id': region_id,
+                'update_time': now_time,
+            }
+
+            country_qs.update(**country)
+
+            return response.json(0)
+        else:
+            return response.json(444)
+
+    def do_delete_country(self, userID, request_dict, response):
+        # perm = ModelService.check_perm_uid_manage(userID, 0)
+        # if not perm:
+        #     return response.json(309)
+
+        id = request_dict.get('id', None)
+
+        if id:
+            country_qs = CountryModel.objects.filter(id=id)
+            if country_qs.exists():
+                country_qs.delete()
+                return response.json(0)
+            else:
+                return response.json(173)
+        else:
+            return response.json(444)
+
+    def do_list_country(self, userID, request_dict, response):
+        # perm = ModelService.check_perm_uid_manage(userID, 0)
+        # if not perm:
+        #     return response.json(309)
+
+        region_id = request_dict.get('region_id', None)
+        page = request_dict.get('page', None)
+        line = request_dict.get('limit', None)
+
+        if page and line:
+            page = int(page)
+            line = int(line)
+
+            start = (page - 1) * line
+            end = start + line
+
+            region_qs = CountryLanguageModel.objects.filter(language_id=1)
+            if region_id:
+                region_qs = region_qs.filter(country__region__id=region_id)
+
+            count = region_qs.count()
+
+            if region_qs.exists():
+                region_qs = region_qs[start: end].values('country_id', 'country_name', 'country__number', 'country__region__name', 'add_time', 'update_time')
+            else:
+                region_qs = []
+            res = {
+                'count': count,
+                'data': list(region_qs)
+            }
+
+            return response.json(0, res)
+        else:
+            return response.json(444)
+
+    def get_country(self, request_dict, response):
+        type = request_dict.get('type', None)
+        token = request_dict.get('token', None)
+        time_stamp = request_dict.get('time_stamp', None)
+
+        if token and time_stamp and type:
+            token = int(CommonService.decode_data(token))
+            time_stamp = int(time_stamp)
+
+            now_time = int(time.time())
+            distance = now_time - time_stamp
+
+            if token != time_stamp or distance > 60000 or distance < -60000:  # 为了全球化时间控制在一天内
+                return response.json(404)
+
+            lang_qs = LanguageModel.objects.filter(lang=type)
+
+            if not lang_qs.exists():
+                lang_qs = LanguageModel.objects.filter(lang='en')
+
+            lang = lang_qs[0]
+            country_qs = CountryLanguageModel.objects.filter(language_id=lang.id).values('country_name', 'country__number')
+
+            return response.json(0, list(country_qs))
+        else:
+            return response.json(444)
+
+    def get_country_info(self, userID, request_dict, response):
+        # perm = ModelService.check_perm_uid_manage(userID, 0)
+        # if not perm:
+        #     return response.json(309)
+
+        country_number = request_dict.get('country_number', None)
+
+        if country_number:
+            country_language_qs = CountryLanguageModel.objects.filter(country__number=country_number)
+            if country_language_qs.exists():
+                country_language_qs = country_language_qs
+        pass

+ 46 - 0
Controller/RegionCountryController.py

@@ -0,0 +1,46 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+import time
+
+from django.views import View
+
+from Model.models import Device_User
+from Object.ResponseObject import ResponseObject
+from Object.TokenObject import TokenObject
+
+class RegionCountryView(View):
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation', None)
+        request_dict = request.GET
+        return self.validate(request_dict, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation', None)
+        request_dict = request.POST
+        return self.validate(request_dict, operation)
+
+    def validate(self, request_dict, operation):
+        token = TokenObject(request_dict.get('token', None))
+
+        response = ResponseObject()
+
+        if token.code != 0:
+            return response.json(token.code)
+
+        if operation == 'initUserRegion':
+            return self.do_initUserRegion(token.userID, request_dict, response)
+        else:
+            return response.json(404)
+
+    def do_initUserRegion(self, userID, request_dict, response):
+        user = Device_User.objects.get(userID=userID)
+        number = request_dict.get('number', None)
+        if not user:
+            return response.json(309)
+
+        user.region_country=number
+        user.save()
+        return response.json(0)

+ 98 - 0
Controller/S3GetStsController.py

@@ -0,0 +1,98 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+import hashlib
+import json
+import time
+import uuid
+
+import boto3
+from django.http import HttpResponse, JsonResponse
+from django.views import View
+
+from Ansjer.config import AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_ARN
+from Controller.DeviceConfirmRegion import Device_Region
+from Model.models import Device_User, Device_Info, iotdeviceInfoModel, UIDCompanySerialModel, \
+    SerialNumberModel
+from Object.IOTCore.IotObject import IOTClient
+from Object.ResponseObject import ResponseObject
+from Service.CommonService import CommonService
+
+
+class S3GetStsView(View):
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.GET
+        operation = kwargs.get('operation', None)
+        return self.validate(operation, request_dict, request)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.POST
+        operation = kwargs.get('operation', None)
+        return self.validate(operation, request_dict, request)
+
+    def validate(self, operation, request_dict, request):
+
+        response = ResponseObject()
+
+        if operation == 'ota':
+            return self.ota(request_dict, response, request)
+        else:
+            return response.json(404)
+
+
+    # 授权ota升级s3预签名
+    def ota(self, request_dict, response, request):
+        mold = request_dict.get('mold', None)  #0国内, 1国外
+        region_name = request_dict.get('region_name', None)
+        bucket_name = request_dict.get('bucket_name', None)
+        endpoint = request_dict.get('endpoint', None)
+        filepath = request_dict.get('filepath', None)
+        role_name = request_dict.get('jobname', None)
+        mold = int(mold)
+        try:
+            aws_access_key_id = AWS_ACCESS_KEY_ID[mold]
+            aws_secret_access_key = AWS_SECRET_ACCESS_KEY[mold]
+            aws_arn = AWS_ARN[mold]
+        except:
+            res = {'code': 404, 'msg': 'mold not exists!'}
+            return HttpResponse(json.dumps(res, ensure_ascii=False), content_type="application/json,charset=utf-8")
+
+        ###############
+        boto3_sts = boto3.client(
+            'sts',
+            aws_access_key_id=aws_access_key_id,
+            aws_secret_access_key=aws_secret_access_key,
+            region_name=region_name
+        )
+        Policy = {
+            "Version": "2012-10-17",
+            "Statement": [
+                {
+                    "Effect": "Allow",
+                    "Action": "s3:*",
+                    "Resource": ["{aws_arn}:::{bucket_name}/{filepath}*".
+                                     format(aws_arn=aws_arn, bucket_name=bucket_name, filepath=filepath)]
+                }
+            ]
+        }
+        response = boto3_sts.get_federation_token(
+            Name='{role_name}'.format(role_name=role_name),
+            Policy=json.dumps(Policy),
+            DurationSeconds=7200
+        )
+        ##############
+        res = {
+            'AccessKeyId': response['Credentials']['AccessKeyId'],
+            'AccessKeySecret': response['Credentials']['SecretAccessKey'],
+            'SessionToken': response['Credentials']['SessionToken'],
+            'Expiration': response['Credentials']['Expiration'],
+            'expire': 900,
+            'endpoint': endpoint,
+            'bucket_name': bucket_name,
+            'arn': response['FederatedUser']['Arn'],
+            'region': region_name,
+            'bucket_mold': mold
+        }
+        return JsonResponse(status=200, data=res)

+ 107 - 0
Controller/SalesController.py

@@ -0,0 +1,107 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+import datetime
+import json
+import random
+
+from django.utils.decorators import method_decorator
+from django.views import View
+from django.views.decorators.csrf import csrf_exempt
+
+from Ansjer.config import SALES, ONLINE_DEVICE
+from Object.uidManageResponseObject import uidManageResponseObject
+
+
+class SalesView(View):
+
+    @method_decorator(csrf_exempt)
+    def dispatch(self, request, *args, **kwargs):
+        return super(SalesView, self).dispatch(request, *args, **kwargs)
+
+    def get(self, request, *args, **kwargs):
+        request_dict = request.GET
+        return self.validate(request_dict)
+
+    def post(self, request, *args, **kwargs):
+        request_dict = request.POST
+        return self.validate(request_dict)
+
+    def validate(self, request_dict):
+        year = request_dict.get('year', 0)
+        response = uidManageResponseObject()
+        if year:
+            year = int(year)
+            if year == 0:
+                data = SALES.copy()
+                data[2020] = self.get_last_year_data(SALES[2020])
+                return response.json(0, {'data': self.format_data(data)})
+            elif 2015 < year < 2020:
+                data = {year: SALES[year]}
+                return response.json(0, {'data': self.format_data(data)})
+            elif year == 2020:
+                data = {year: self.get_last_year_data(SALES[year])}
+                return response.json(0, {'data': self.format_data(data)})
+            else:
+                return response.json(444)
+        else:
+            return response.json(444)
+
+    def get_last_year_data(self, data):
+        result = []
+        month = datetime.datetime.now().month
+        print(month)
+        sum = 0
+        for item in data:
+            value = item['value']
+            sale = int(value[0] / 12 * month)
+            sum += sale
+
+        for item in data:
+            tmp = {}
+            tmp['name'] = item['name']
+            value = item['value']
+            sale = int(value[0] / 12 * month)
+            percent = round(sale * 100 / sum, 3)
+
+            tmpValue = []
+            tmpValue.append(sale)
+            tmpValue.append(percent)
+            tmpValue.append(value[2])
+            tmp['value'] = tmpValue
+            result.append(tmp)
+        print(result)
+        return result
+
+    def format_data(self, data: dict):
+        result = []
+        keys = data.keys()
+        for key in keys:
+            tmp = {
+                'time': key,
+                'data': data[key]
+            }
+            result.append(tmp)
+        return result
+
+
+class DeviceOnlineView(View):
+
+    @method_decorator(csrf_exempt)
+    def dispatch(self, request, *args, **kwargs):
+        return super(DeviceOnlineView, self).dispatch(request, *args, **kwargs)
+
+    def get(self, request, *args, **kwargs):
+        request_dict = request.GET
+        return self.validate(request_dict)
+
+    def post(self, request, *args, **kwargs):
+        request_dict = request.POST
+        return self.validate(request_dict)
+
+    def validate(self, request_dict):
+        response = uidManageResponseObject()
+        return response.json(0,{'online': random.randint((0.9 * ONLINE_DEVICE), ONLINE_DEVICE)})
+
+
+
+

+ 403 - 0
Controller/SerialNumberController.py

@@ -0,0 +1,403 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+import logging
+import random
+import time
+
+from django.db import transaction
+from django.views import View
+
+from Controller.DeviceConfirmRegion import Device_Region
+from Model.models import SerialNumberModel, CompanySerialModel, UIDCompanySerialModel, CompanyModel, RegionModel, \
+    CountryModel, UIDModel, Device_Info, iotdeviceInfoModel
+from Object.RedisObject import RedisObject
+from Object.uidManageResponseObject import uidManageResponseObject
+from Object.TokenObject import TokenObject
+from Service.AlgorithmService import AlgorithmBaseOn35
+from Service.CommonService import CommonService
+from Service.ModelService import ModelService
+
+
+class SerialNumberView(View):
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation', None)
+        request_dict = request.GET
+        return self.validate(request_dict, operation, request)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation', None)
+        request_dict = request.POST
+        return self.validate(request_dict, operation, request)
+
+    def validate(self, request_dict, operation, request):
+        token = TokenObject(request_dict.get('token', None))
+        response = uidManageResponseObject()
+
+        if operation == 'getUID':
+            return self.do_get_uid(request_dict, response)
+        elif operation == 'getSerial':
+            return self.do_get_serial_number(request_dict, response)
+        elif operation == 'attachUID':
+            return self.do_attach_uid(request_dict, response, request)
+        elif operation == 'detachUID':
+            return self.do_detach_uid(request_dict, response)
+        elif operation == 'create':
+            return self.do_create(request_dict, response)
+        else:
+            if token.code != 0:
+                return response.json(token.code)
+
+            # if operation == 'create':
+            #     return self.do_create(request_dict, response)
+            elif operation == 'list':
+                return self.do_list(token.userID, request_dict, response)
+            elif operation == 'update':
+                return self.do_update(token.userID, request_dict, response)
+            else:
+                return response.json(404)
+
+    def do_create(self, request_dict, response):
+        quantity = int(request_dict.get('quantity', 0))
+        p2p = int(request_dict.get('p2p', 0))
+
+        if not quantity:
+            return response.json(444)
+
+        try:
+            try:
+                sum = SerialNumberModel.objects.last().id
+            except:
+                sum = 0
+            serial_number_bulk = []
+            now_time = int(time.time())
+            algorithm = AlgorithmBaseOn35()
+            for i in range(quantity):
+                serial_number = algorithm.getLetter(sum)
+                sum += 1    # sum每次递增1
+                # 前面补0至六位
+                serial_number = (6-len(serial_number))*'0' + serial_number
+                serial_number_bulk.append(SerialNumberModel(serial_number=serial_number, add_time=now_time, p2p=p2p))
+            # 开启事务写入
+            with transaction.atomic():
+                SerialNumberModel.objects.bulk_create(serial_number_bulk)
+            return response.json(0)
+        except Exception as e:
+            print(e)
+            return response.json(500, repr(e))
+
+    # 提供给pc端获取序列号
+    def do_get_serial_number(self, request_dict, response):
+        quantity = request_dict.get('quantity', None)
+        company_id = request_dict.get('company_id', None)
+        token = request_dict.get('token', None)
+        time_stamp = request_dict.get('time_stamp', None)
+        p2p_type = request_dict.get('p2p_type', None)
+
+        if token and time_stamp and quantity and company_id:
+
+            token = int(CommonService.decode_data(token))
+            time_stamp = int(time_stamp)
+
+            now_time = int(time.time())
+            distance = now_time - time_stamp
+
+            if token != time_stamp or distance > 60000 or distance < -60000: #为了全球化时间控制在一天内
+                return response.json(404)
+
+            redisObject = RedisObject()
+            key = 'serial_lock'
+            value = redisObject.lpop(key)
+            count = 0
+            while value is False and count < 5:
+                time.sleep(1)
+                value = redisObject.lpop(key)
+                count += 1
+
+            if count == 5 and value is False:    #暂时注释
+                return response.json(5)
+
+            quantity = int(quantity)
+
+            company_serial_qs = CompanySerialModel.objects.filter(company__secret=company_id, status=0, p2p=p2p_type)
+            if not company_serial_qs.exists():
+                redisObject.rpush(key, value)
+                return response.json(373)
+
+            # 存在对应的企业
+            company_serial_qs = company_serial_qs[0:quantity]
+
+            #company_serial_qs = company_serial_qs.values('id', 'serial_number__serial_number', 'company__mark')
+            data = []
+            ids = []
+            for serial in company_serial_qs:
+                ids.append(serial.id)
+                data.append(serial.serial_number + serial.company.mark)
+            CompanySerialModel.objects.filter(id__in=ids).update(status=1)
+            redisObject.rpush(key, value)
+            return response.json(0, data)
+        else:
+            return response.json(444)
+
+    def do_list(self, userID, request_dict, response):
+        # perm = ModelService.check_perm_uid_manage(userID, 0)
+        # if not perm:
+        #     return response.json(309)
+
+        page = request_dict.get('page', None)
+        line = request_dict.get('limit', None)
+        serial_number = request_dict.get('serial_number', None)
+        status = request_dict.get('status', None)
+
+        if page and line:
+            page = int(page)
+            line = int(line)
+
+            serial_qs = SerialNumberModel.objects.filter().order_by('-id')
+
+            if serial_number:
+                serial_qs = serial_qs.filter(serial_number__contains=serial_number)
+
+            if status:
+                serial_qs = serial_qs.filter(status=status)
+
+            count = serial_qs.count()
+
+            start = (page - 1) * line
+            end = start + line
+
+            serial_qs = serial_qs[start: end].values()
+            res = {
+                'count': count,
+                'data': list(serial_qs)
+            }
+
+            return response.json(0, res)
+        else:
+            return response.json(444)
+
+    @transaction.atomic
+    def do_attach_uid(self, request_dict, response, request):
+        serial_number = request_dict.get('serial_number', None)
+        country_id = request_dict.get('country_id', None)
+        company_id = request_dict.get('company_id', None)
+        token = request_dict.get('token', None)
+        time_stamp = request_dict.get('time_stamp', None)
+
+        if serial_number and len(serial_number) == 9  and company_id:
+
+            token = int(CommonService.decode_data(token))
+            time_stamp = int(time_stamp)
+
+            now_time = int(time.time())
+            distance = now_time - time_stamp
+
+            if token != time_stamp or distance > 60000 or distance < -60000: #为了全球化时间控制在一天内
+                return response.json(404)
+
+            mark = serial_number[6:9]
+            serial = serial_number[0:6]
+
+            savePoint = transaction.savepoint()
+            try:
+                try:
+                    if not country_id :
+                        ip = CommonService.get_ip_address(request)
+                        country_id = Device_Region().get_device_region(ip)
+
+                    # 判断序列号是否已和企业关联
+                    company_serial_qs = CompanySerialModel.objects.filter(company__secret=company_id,
+                                                                          serial_number=serial)
+                    if not company_serial_qs.exists():
+                        return response.json(173)
+
+                    # 当序列号已关联UID
+                    company_serial = company_serial_qs[0]
+
+                    if company_serial.status == 0:
+                        # 该序列号未绑定企业
+                        return response.json(173)
+                    elif company_serial.status == 1:
+                        # 确定所在区域
+                        country_qs = CountryModel.objects.filter(number=country_id)
+                        if not country_qs.exists():
+                            return response.json(374)
+
+                        region = country_qs.values('region_id')[0]
+
+                        count = 0
+                        while count < 3:
+                            p2p = SerialNumberModel.objects.filter(serial_number=serial).values('p2p')
+                            print('此序列号的p2p类型:', p2p[0]['p2p'])
+                            uid_qs = UIDModel.objects.filter(vpg__company_id=company_serial.company.id, vpg__region_id=region['region_id'],
+                                                             status=0, p2p_type=p2p[0]['p2p']).order_by('id')[0:10]
+                            # uid_qs:未进行绑定的uid列表
+                            if uid_qs.exists():
+                                uid = uid_qs[0]
+                                # uid.status = 2
+                                # uid.update_time = int(time.time())
+                                result = UIDModel.objects.filter(id=uid.id, status=0).update(**{
+                                    'status': 2, 'update_time': int(time.time())
+                                })
+
+                                if int(result) <= 0:
+                                    count += 1
+                                    continue
+
+                                now_time = int(time.time())
+                                uid_serial = UIDCompanySerialModel(uid_id=uid.id, company_serial_id=company_serial.id,
+                                                                   add_time=now_time, update_time=now_time)
+                                uid_serial.save()
+
+                                company_serial.status = 2
+                                company_serial.save()
+
+                                dev = Device_Info.objects.filter(UID=uid.uid)
+                                if dev.exists():
+                                    dev.update(serial_number=serial_number)
+
+                                res = {
+                                    'full_uid_code': CommonService.encode_data(uid.full_uid_code),
+                                    'uid': CommonService.encode_data(uid.uid),
+                                    'mac': CommonService.encode_data(uid.mac),
+                                    'extra': uid.uid_extra
+                                }
+                                return response.json(0, res)
+                            else:
+                                return response.json(375)
+
+                        return response.json(5)
+                    else:
+                        uid_qs = UIDCompanySerialModel.objects.filter(company_serial_id=company_serial.id)
+                        if uid_qs.exists():
+                            uid = uid_qs.values('uid__uid', 'uid__mac', 'uid__uid_extra', 'uid__full_uid_code')[0]
+                            res = {
+                                'full_uid_code': CommonService.encode_data(uid['uid__full_uid_code']),
+                                'uid': CommonService.encode_data(uid['uid__uid']),
+                                'mac': CommonService.encode_data(uid['uid__mac']),
+                                'extra': uid['uid__uid_extra']
+                            }
+                            return response.json(0, res)
+                        else:
+                            return response.json(173)
+                except Exception as e:
+                    # print('--------------------------error 5000')
+                    # print(repr(e))
+                    if savePoint:
+                        transaction.rollback(savePoint)
+                    djangoLogger = logging.getLogger('django')
+                    djangoLogger.exception(repr(e))
+                    return response.json(176, str(e))
+            except Exception as e:
+                # print('--------------------------error 5001')
+                # print(repr(e))
+                djangoLogger = logging.getLogger('django')
+                djangoLogger.exception(repr(e))
+                return response.json(176, str(e))
+
+        else:
+            return response.json(444)
+
+    def do_get_uid(self, request_dict, response):
+        serial_number = request_dict.get('serial_number', None)
+        token = request_dict.get('token', None)
+        time_stamp = request_dict.get('time_stamp', None)
+
+        if token and time_stamp and serial_number and len(serial_number) == 9:
+
+            token = int(CommonService.decode_data(token))
+            time_stamp = int(time_stamp)
+
+            now_time = int(time.time())
+            distance = now_time - time_stamp
+
+            if token != time_stamp or distance > 60000 or distance < -60000:  #为了全球化时间控制在一天内
+                return response.json(404)
+
+            mark = serial_number[6:9]
+            serial = serial_number[0:6]
+            uid_company_serial_qs = UIDCompanySerialModel.objects.filter(company_serial__company__mark=mark, company_serial__serial_number__serial_number=serial)
+
+            if uid_company_serial_qs.exists():
+                uid = uid_company_serial_qs.values('uid__uid', 'uid__mac', 'uid__uid_extra')[0]
+
+                res = {
+                    'uid': CommonService.encode_data(uid['uid__uid']),
+                    'mac': CommonService.encode_data(uid['uid__mac']),
+                    'extra': uid['uid__uid_extra']
+                }
+
+                return response.json(0, res)
+            else:
+                return response.json(173)
+        else:
+            return response.json(444)
+
+    def do_detach_uid(self, request_dict, response):
+        serial_number = request_dict.get('serial_number', None)
+        token = request_dict.get('token', None)
+        time_stamp = request_dict.get('time_stamp', None)
+
+        if token and time_stamp and serial_number:
+            token = int(CommonService.decode_data(token))
+            time_stamp = int(time_stamp)
+
+            now_time = int(time.time())
+            distance = now_time - time_stamp
+
+            if token != time_stamp or distance > 60000 or distance < -60000:  # 为了全球化时间控制在一天内
+                return response.json(404)
+
+            serial = serial_number[0:6]
+
+            uid_serial_qs = UIDCompanySerialModel.objects.filter(company_serial__serial_number=serial)
+            if uid_serial_qs.exists():
+                uid_serial = uid_serial_qs[0]
+
+                #iot = iotdeviceInfoModel.objects.filter(serial_number__serial_number=serial)
+                iot = iotdeviceInfoModel.objects.filter(thing_name="Ansjer_Device_" + serial_number)
+                if iot.exists():
+                    iot.delete()
+
+                company_serial_qs = CompanySerialModel.objects.filter(id=uid_serial.company_serial.id)
+                if company_serial_qs.exists():
+                    company_serial = company_serial_qs[0]
+                    company_serial.status = 1
+                    company_serial.save()
+
+                uid_qs = UIDModel.objects.filter(uid=uid_serial.uid.uid)
+                if uid_qs.exists():
+                    uid = uid_qs[0]
+                    uid.status = 0
+                    uid.save()
+                uid_serial.delete()
+
+                dev = Device_Info.objects.filter(serial_number=serial_number)
+                if dev.exists():
+                    dev.update(serial_number='')
+                return response.json(0)
+            else:
+                return response.json(173)
+        else:
+            return response.json(444)
+
+    def do_update(self, userID, request_dict, response):
+        # perm = ModelService.check_perm_uid_manage(userID, 0)
+        # if not perm:
+        #     return response.json(309)
+
+        id = request_dict.get('id', None)
+        status = request_dict.get('status', None)
+        p2p = request_dict.get('p2p', None)
+
+        if id and status:
+            serial_number_qs = SerialNumberModel.objects.filter(id=id)
+            if serial_number_qs.exists():
+                serial_number_qs.update(**{'status': status, 'p2p': p2p})
+                return response.json(0)
+            else:
+                return response.json(173)
+        else:
+            return response.json(444)

+ 157 - 0
Controller/ShadowController.py

@@ -0,0 +1,157 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+"""
+@Copyright (C) ansjer cop Video Technology Co.,Ltd.All rights reserved.
+@AUTHOR: ASJRD018
+@NAME: AnsjerPush
+@software: PyCharm
+@DATE: 2020/2/14 13:54
+@Version: python3.6
+@MODIFY DECORD:ansjer dev
+@file: ShadowController.py
+@Contact: chanjunkai@163.com
+"""
+# 测试环境
+# test.shadow.dvema.com
+# 生产环境
+# shadow.dvema.com
+# 设备影子更新
+from Object.LogUtil import LogUtil
+from Object.ResponseObject import ResponseObject
+from Object.ETkObject import ETkObject
+import time
+from Model.models import Device_Info, UidSetModel, UID_Preview, VoicePromptModel, UID_Bucket
+from Service.CommonService import CommonService
+from django.http import JsonResponse
+from Object.UidTokenObject import UidTokenObject
+
+def generate_utk(request):
+    request.encoding = 'utf-8'
+    response = ResponseObject()
+    if request.method == 'GET':
+        request_dict = request.GET
+    elif request.method == 'POST':
+        request_dict = request.POST
+    else:
+        return response.json(444,'wrong method')
+    username = request_dict.get('username',None)
+    password = request_dict.get('password',None)
+    uid = request_dict.get('uid',None)
+    if username and password:
+        if username == 'debug_user' and password == 'debug_password':
+            # utko = UidTokenObject()
+            # # right
+            # utko.generate(data={'uid': uid})
+            etkObj = ETkObject(etk='')
+            etk = etkObj.encrypt(uid)
+            return response.json(0, {'etk': etk})
+        else:
+            return response.json(404)
+    else:
+        return response.json(444,'username password')
+
+
+# 设备影子更新
+def update_device_shadow(request):
+    request.encoding = 'utf-8'
+    response = ResponseObject()
+    if request.method == 'POST':
+        request_dict = request.POST
+    elif request.method == 'GET':
+        request_dict = request.GET
+    else:
+        return response.json(444)
+    etk = request_dict.get('etk', None)
+    eto = ETkObject(etk)
+    uid = eto.uid
+    if uid:
+        # 重置按钮
+        is_reset = request_dict.get('is_reset', None)
+        # 传1则重置设备信息
+        if is_reset == '1':
+            UidSetModel.objects.filter(uid=uid).delete()
+            # 重置设备,判断设备为已删除
+            nowTime = int(time.time())
+            uid_bucket = UID_Bucket.objects.filter(uid=uid, endTime__gte=nowTime).values('id', 'has_unused').order_by('addTime')
+            if not uid_bucket.exists():
+                di_qs = Device_Info.objects.filter(UID=uid)
+                di_qs.update(isExist=2)
+            # 删除预览图
+            uid_pre_qs = UID_Preview.objects.filter(uid=uid)
+            if uid_pre_qs.exists():
+                uid_pre_qs.delete()
+
+            # 删除语音提示
+            voice_qs = VoicePromptModel.objects.filter(uid=uid)
+            if voice_qs.exists():
+                voice_qs.delete()
+
+        # return JsonResponse(status=200, data={'code': 0, 'msg': 'success', 'data': {}})
+        ucode = request_dict.get('ucode', None)
+        version = request_dict.get('version', None)
+        p2p_region = request_dict.get('p2p_region', None)
+        tz = request_dict.get('tz', None)
+        video_code = request_dict.get('video_code', None)
+        ip = CommonService.get_ip_address(request)
+        channel = request_dict.get('channel', None)
+        cloud_vod = request_dict.get('cloud_vod', None)
+        push_status = request_dict.get('push_status', None)
+        pwd = request_dict.get('pwd', None)
+        resetTime = request_dict.get('resetTime', None)
+        is_alexa = request_dict.get('is_alexa', None)
+        is_human = request_dict.get('is_human', None)
+        is_custom_voice = request_dict.get('is_custom', None)
+        double_wifi = request_dict.get('double_wifi', None)
+
+        us_qs = UidSetModel.objects.filter(uid=uid)
+        # 更新
+        nowTime = int(time.time())
+
+        print('-------')
+        print(resetTime)
+        print('-------')
+        qs_dict = {
+            'updTime': nowTime,
+            'ip': ip
+        }
+        if channel:
+            qs_dict['channel'] = channel
+        if p2p_region:
+            qs_dict['p2p_region'] = p2p_region
+        if ucode:
+            qs_dict['ucode'] = ucode
+        if version:
+            qs_dict['version'] = version
+        if tz:
+            qs_dict['tz'] = tz
+        if video_code:
+            qs_dict['video_code'] = video_code
+        if cloud_vod:
+            qs_dict['cloud_vod'] = cloud_vod
+        if push_status:
+            qs_dict['detect_status'] = push_status
+        if pwd:
+            qs_dict['pwd'] = pwd
+        if is_human:
+            qs_dict['is_human'] = is_human
+        if is_custom_voice:
+            qs_dict['is_custom_voice'] = is_custom_voice
+        if double_wifi:
+            qs_dict['double_wifi'] = double_wifi
+        if us_qs.exists():
+            if is_alexa and us_qs[0].is_alexa == 0:
+                qs_dict['is_alexa'] = is_alexa
+            us_qs.update(**qs_dict)
+            # 如果推送状态开启,返回推送url
+            return JsonResponse(status=200, data={'code': 0, 'msg': 'success', 'data': {}})
+        # 新增
+        else:
+            if is_alexa:
+                qs_dict['is_alexa'] = is_alexa
+            qs_dict['uid'] = uid
+            qs_dict['addTime'] = nowTime
+            UidSetModel.objects.create(**qs_dict)
+            # 如果推送状态开启,返回推送url
+            return JsonResponse(status=200, data={'code': 0, 'msg': 'success', 'data': {}})
+    else:
+        return JsonResponse(status=200, data={'code': 403, 'msg': 'error etk'})

+ 122 - 1
Controller/StatisticsController.py

@@ -7,7 +7,7 @@ from django.db.models import Count
 from django.views.decorators.csrf import csrf_exempt
 from django.views.decorators.csrf import csrf_exempt
 
 
 from Model.models import UserAppFrequencyModel, AppFrequencyStatisticsModel, Device_User, \
 from Model.models import UserAppFrequencyModel, AppFrequencyStatisticsModel, Device_User, \
-    AppFrequencyYearStatisticsModel
+    AppFrequencyYearStatisticsModel, Equipment_Info, EquipmentInfoExStatisticsModel
 from Object.ResponseObject import ResponseObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Object.TokenObject import TokenObject
 
 
@@ -40,13 +40,17 @@ def statistcsAppFrequency(request):
 
 
     time_struct = [current_year, 1, 1, 0, 0, 0, 0, 0, 0]
     time_struct = [current_year, 1, 1, 0, 0, 0, 0, 0, 0]
 
 
+    distance_time = 8 * 60 * 60
+
     # 该月的开始时间
     # 该月的开始时间
     time_struct[1] = current_month
     time_struct[1] = current_month
     start_time = time.mktime(tuple(time_struct))
     start_time = time.mktime(tuple(time_struct))
+    start_time = start_time - time.timezone - distance_time
 
 
     # 该月的结束时间
     # 该月的结束时间
     time_struct[1] = current_month + 1
     time_struct[1] = current_month + 1
     end_time = time.mktime(tuple(time_struct))
     end_time = time.mktime(tuple(time_struct))
+    end_time = end_time - time.timezone - distance_time
 
 
     # 统计该月的数据
     # 统计该月的数据
     uaf_qs = UserAppFrequencyModel.objects.filter(data_time__gte=start_time, data_time__lt=end_time) \
     uaf_qs = UserAppFrequencyModel.objects.filter(data_time__gte=start_time, data_time__lt=end_time) \
@@ -135,3 +139,120 @@ def statistcsAppFrequencyYear(request):
         }
         }
         AppFrequencyYearStatisticsModel.objects.create(**data)
         AppFrequencyYearStatisticsModel.objects.create(**data)
     return response.json(0)
     return response.json(0)
+
+
+@csrf_exempt
+def statistcsPushDay(request):
+    request.encoding = 'utf-8'
+    response = ResponseObject()
+    if request.method == 'POST':
+        request_dict = request.POST
+    elif request.method == 'GET':
+        request_dict = request.GET
+    else:
+        return response.json(444)
+
+    token = TokenObject(request_dict.get('token', None))
+    if token.code != 0:
+        return response.json(token.code)
+
+    current_time = int(time.time())
+    count = int((current_time + 8 * 3600) / (24 * 3600))
+    end_time = count * 24 * 3600 - 8 * 3600
+    start_time = end_time - 24 * 3600
+    print(start_time)
+    print(end_time)
+
+    eq_qs = Equipment_Info.objects.filter(addTime__gte=start_time, addTime__lte=end_time)
+    print(eq_qs.values())
+    # 0:APNS推送,1:谷歌推送,2:极光推送
+    now_time = int(time.time())
+    jpush = EquipmentInfoExStatisticsModel(push_type=2, statistics_date=start_time, add_time=now_time, date_type=0)
+    apns = EquipmentInfoExStatisticsModel(push_type=0, statistics_date=start_time, add_time=now_time, date_type=0)
+    gcm = EquipmentInfoExStatisticsModel(push_type=1, statistics_date=start_time, add_time=now_time, date_type=0)
+    total = EquipmentInfoExStatisticsModel(push_type=-1, statistics_date=start_time, add_time=now_time, date_type=0)
+    for eq in eq_qs:
+        if eq.push_type == 0:
+            do_sum(eq, apns)
+        elif eq.push_type == 1:
+            do_sum(eq, gcm)
+        elif eq.push_type == 2:
+            do_sum(eq, jpush)
+        do_sum(eq, total)
+    datas = []
+    datas.append(apns)
+    datas.append(gcm)
+    datas.append(jpush)
+    datas.append(total)
+
+    EquipmentInfoExStatisticsModel.objects.bulk_create(datas)
+    return response.json(0)
+
+
+@csrf_exempt
+def statistcsPushMonth(request):
+    request.encoding = 'utf-8'
+    response = ResponseObject()
+    if request.method == 'POST':
+        request_dict = request.POST
+    elif request.method == 'GET':
+        request_dict = request.GET
+    else:
+        return response.json(444)
+
+    token = TokenObject(request_dict.get('token', None))
+    if token.code != 0:
+        return response.json(token.code)
+
+    gmtime = time.gmtime(int(time.time()) + 28800)
+    current_month = gmtime.tm_mon - 1
+    # print(current_month)
+
+    time_struct = [gmtime.tm_year, current_month, 1, 0, 0, 0, 0, 0, gmtime.tm_isdst]
+    start_time = int(time.mktime(tuple(time_struct))) - 28800
+    # print(start_time)
+
+    time_struct[1] = current_month + 1
+    end_time = int(time.mktime(tuple(time_struct))) - 28800
+    # print(end_time)
+
+    eq_qs = EquipmentInfoExStatisticsModel.objects.filter(statistics_date__gte=start_time, statistics_date__lte=end_time, date_type=0)
+    # 0:APNS推送,1:谷歌推送,2:极光推送
+    now_time = int(time.time())
+    jpush = EquipmentInfoExStatisticsModel(push_type=2, statistics_date=start_time, add_time=now_time, date_type=1)
+    apns = EquipmentInfoExStatisticsModel(push_type=0, statistics_date=start_time, add_time=now_time, date_type=1)
+    gcm = EquipmentInfoExStatisticsModel(push_type=1, statistics_date=start_time, add_time=now_time, date_type=1)
+    total = EquipmentInfoExStatisticsModel(push_type=-1, statistics_date=start_time, add_time=now_time, date_type=1)
+    for eq in eq_qs:
+        if eq.push_type == 0:
+            do_sum_two(eq, apns)
+        elif eq.push_type == 1:
+            do_sum_two(eq, gcm)
+        elif eq.push_type == 2:
+            do_sum_two(eq, jpush)
+        elif eq.push_type == -1:
+            do_sum_two(eq, total)
+    datas = []
+    datas.append(apns)
+    datas.append(gcm)
+    datas.append(jpush)
+    datas.append(total)
+
+    EquipmentInfoExStatisticsModel.objects.bulk_create(datas)
+    return response.json(0)
+
+
+def do_sum(eq: Equipment_Info, target: EquipmentInfoExStatisticsModel):
+    if eq.push_server_status == 200:
+        target.number_of_successes += 1
+    else:
+        target.number_of_failures += 1
+
+    if eq.push_device_status == 1:
+        target.number_of_arrival += 1
+
+
+def do_sum_two(eq: EquipmentInfoExStatisticsModel, target: EquipmentInfoExStatisticsModel):
+    target.number_of_successes += eq.number_of_successes
+    target.number_of_failures += eq.number_of_failures
+    target.number_of_arrival += eq.number_of_arrival

+ 2 - 2
Controller/SysManage.py

@@ -104,8 +104,8 @@ def initMsgFunc(request):
     if tko.code == 0:
     if tko.code == 0:
         userID = tko.userID
         userID = tko.userID
         sm_count = SysMsgModel.objects.filter(userID_id=userID, status=0).count()
         sm_count = SysMsgModel.objects.filter(userID_id=userID, status=0).count()
-        eq_count = Equipment_Info.objects.filter(status=False,userID_id=userID).count()
-        rq_count = Equipment_Info.objects.filter(status=False, eventType=57,userID_id=userID).count()
+        eq_count = Equipment_Info.objects.filter(userID_id=userID).filter(status=False).count()
+        rq_count = Equipment_Info.objects.filter(userID_id=userID).filter(eventType=57, status=False,).count()
         uid_reset_count = Device_Info.objects.filter(userID_id=userID, isExist=2).count()
         uid_reset_count = Device_Info.objects.filter(userID_id=userID, isExist=2).count()
         res = {
         res = {
             'sm_count': sm_count,  # 系统消息未读数量
             'sm_count': sm_count,  # 系统消息未读数量

+ 0 - 1
Controller/SysMsg.py

@@ -250,5 +250,4 @@ class SysMsgView(View):
                 return response.json(173)
                 return response.json(173)
         else:
         else:
             return response.json(444, 'sid')
             return response.json(444, 'sid')
-
 # 回复记录
 # 回复记录

+ 75 - 6
Controller/TestApi.py

@@ -21,6 +21,7 @@ import json
 import math
 import math
 import time
 import time
 import urllib
 import urllib
+import datetime
 from Object.AliPayObject import AliPayObject
 from Object.AliPayObject import AliPayObject
 import logging
 import logging
 import boto3
 import boto3
@@ -29,6 +30,9 @@ from botocore.exceptions import ClientError
 import oss2
 import oss2
 import paypalrestsdk
 import paypalrestsdk
 import logging
 import logging
+import requests
+import hashlib
+import hmac
 from aliyunsdkcore import client
 from aliyunsdkcore import client
 from aliyunsdksts.request.v20150401 import AssumeRoleRequest
 from aliyunsdksts.request.v20150401 import AssumeRoleRequest
 from django.http import JsonResponse, HttpResponseRedirect, HttpResponse
 from django.http import JsonResponse, HttpResponseRedirect, HttpResponse
@@ -36,10 +40,9 @@ from django.utils.decorators import method_decorator
 from django.views.decorators.csrf import csrf_exempt
 from django.views.decorators.csrf import csrf_exempt
 from django.views.generic.base import View
 from django.views.generic.base import View
 from django.contrib.auth.hashers import make_password, check_password  # 对密码加密模块
 from django.contrib.auth.hashers import make_password, check_password  # 对密码加密模块
-
 from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, OSS_ROLE_ARN, SERVER_DOMAIN, PAYPAL_CRD, \
 from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, OSS_ROLE_ARN, SERVER_DOMAIN, PAYPAL_CRD, \
     SERVER_DOMAIN_SSL
     SERVER_DOMAIN_SSL
-from Model.models import Device_Info, Order_Model, Store_Meal, VodHlsModel, OssCrdModel, UID_Bucket
+from Model.models import Device_Info, Order_Model, Store_Meal, VodHlsModel, OssCrdModel, UID_Bucket, CompanySerialModel, SerialNumberModel, CompanyModel, VPGModel
 from Object.ResponseObject import ResponseObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Object.TokenObject import TokenObject
 from Object.UidTokenObject import UidTokenObject
 from Object.UidTokenObject import UidTokenObject
@@ -50,6 +53,7 @@ from Model.models import Device_User, Device_Info, UID_Bucket, UID_Preview, UidS
 
 
 
 
 
 
+
 SERVER_DOMAIN = 'http://test.dvema.com/'
 SERVER_DOMAIN = 'http://test.dvema.com/'
 ACCESS_KEY = "AKIA2E67UIMD3CYTIWPA"
 ACCESS_KEY = "AKIA2E67UIMD3CYTIWPA"
 SECRET_KEY = "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"
 SECRET_KEY = "mHl79oiKxEf+89friTtwIcF8FUFIdVksUwySixwQ"
@@ -77,8 +81,8 @@ class testView(View):
         if operation is None:
         if operation is None:
             return response.json(444, 'error path')
             return response.json(444, 'error path')
         elif operation == 'tests':
         elif operation == 'tests':
-             res = make_password(123456)
-             return JsonResponse(status=200, data=res,safe=False)
+            res = make_password(123456)
+            return JsonResponse(status=200, data=res,safe=False)
         elif operation == 'cbu':
         elif operation == 'cbu':
             return self.createBucket()
             return self.createBucket()
         elif operation == 'vodList':
         elif operation == 'vodList':
@@ -96,8 +100,17 @@ class testView(View):
         elif operation == 'getAlexa':
         elif operation == 'getAlexa':
             userID = '158943594633713800138000'
             userID = '158943594633713800138000'
             return self.queryInterface(request_dict, userID, response)
             return self.queryInterface(request_dict, userID, response)
+        elif operation == 'generateToken':
+            userID = '158943604783713800138000'
+            return self.generate_token(request_dict,userID)
+        elif operation == 'test_upload_s3':
+            userID = '158943604783713800138000'
+            return self.test_upload_s3(request_dict)
+        elif operation == 'test_request':
+            userID = '158943604783713800138000'
+            return self.testRequest(request,request_dict)
         else:
         else:
-            return 12344444
+            return 123
 
 
     def createBucket(self):
     def createBucket(self):
 
 
@@ -431,7 +444,7 @@ class testView(View):
     def do_get_sign_sts(self, request_dict, ip, response):
     def do_get_sign_sts(self, request_dict, ip, response):
         # uid = 'GZL2PEFJPLY7W6BG111A'
         # uid = 'GZL2PEFJPLY7W6BG111A'
         # channel = 2
         # channel = 2
-        uid = 'VVDHCVBYDKFMJRWA111A'
+        uid = '86YC8Z192VB1VMKU111A'
         channel = 1
         channel = 1
         now_time = int(time.time())
         now_time = int(time.time())
         ubqs = UID_Bucket.objects.filter(uid=uid, channel=channel, endTime__gte=now_time). \
         ubqs = UID_Bucket.objects.filter(uid=uid, channel=channel, endTime__gte=now_time). \
@@ -674,4 +687,60 @@ class testView(View):
             vod_play_list.append({'name': vod['time'], 'sign_url': vod_play_url, 'thumb': thumb, 'sec': vod['sec']})
             vod_play_list.append({'name': vod['time'], 'sign_url': vod_play_url, 'thumb': thumb, 'sec': vod['sec']})
         return response.json(0, vod_play_list)
         return response.json(0, vod_play_list)
 
 
+    def generate_token(self,request_dict,userID):
+        # UserIdToken
+        tko = TokenObject()
+        res = tko.generate(
+            data={'userID': 158943594633713800138000, 'lang': 'cn', 'user': '597471180@qq.com', 'm_code': '123413243214'})
+        #uidToken
+        # utko = UidTokenObject()
+        # res = utko.generate(data={'uid': 'XKWZSC5FCJYT19B7111A','channel': 1})
+        return JsonResponse(status=200, data=res,safe=False)
+
+
+    def test_upload_s3(self,request_dict):
+        res = CompanyModel.objects.filter(id=3).delete()
+        exit(res)
+
+        testd = hmac.new('AWS4rf/xnQ3jIgY8bj7Sz4An4KbYct2sq2MbrfmP8rVV'.encode("utf-8"), '20210223'.encode("utf-8"), hashlib.sha256).digest()
+        region_sign = hmac.new(testd, 'cn-northwest-1'.encode("utf-8"), hashlib.sha256).hexdigest()
+        exit(region_sign)
+        kService = sign(kRegion, 's3')
+        kSigning = sign(kService, 'aws4_request')
+
+        # exit(CommonService.getIpIpInfo("120.197.196.156",'CN'))
+        aws_key = "ASIA2MMWBR4DUPTFDTOJ" #【你的 aws_access_key】
+        aws_secret = "tTFZ9wpxFadeufhfaJ1erErv4U1bJ+TS/SJwTptx" #【你的 aws_access_key】
+        aws_session_token = "IQoJb3JpZ2luX2VjEJT//////////wEaDmNuLW5vcnRod2VzdC0xIkYwRAIgenLaMN6NdFji0x18OuaUTPvvtRBAWwjdEYdBTCMh0ywCIEzntAbgRPmwS+YFuNg+F31z60I4J1IoqmrQHR7wmPzVKtsCCML//////////wEQABoMNzEzODE2MTE2OTk5IgyJTmdtNJ319TtNORAqrwLPG6Px0z5CsEQpFt/TCbSSMRtYqBU+x5Ll9hZIuTvg8H+56H02/cr0nSCNiy05z7dSrSWMFoMhVKvHq7as5TRvVXkvMbbYPQuQxxPFr7EswaB+XITeDpdGBI6N7mqnt6h4YJbhk2dNRa2/4Ypr1DuyGnhVV6NxNHA5INtY7apLi3UTcNKwKSQRVzUWZBpoj86wG3j77KOZg18I9P8UWBpA9fpz/Wiv4xrzZSexrUnq5svTLEqMfTYCPBXkxrJBjNrwVjvkBkgeIfQZPz+A5X97p7wXbPf0Jo5aHHRDefbAmBuXYoSfpHjiFWindkcvCaMxQzUiHVLvnN/5SvgQEzN3pLUAAioepRZIZQLaky1aRmYYm1wOCjzgsg9V+GV6gKTE+ipFG/6Nv03Vh++Hv+YwyamJgQY6mgEmxhOhncek0PgQeExx2EXk73olY/6L15eDyHbSWoEKBMTmdlmpYD9Cj3qP4aUUW6UT6V5Tql/s5eBEsYwY+hzgtQiTmd7vjytXxae+dpN9VsWGW4AJ9P+/LgBe6zExUx2MOVst0+hb+dd8bg/qkz7UBYNQAmU+BEoL2Cd7lNXdrv56Gboapo+BosQO49GT8u1k5EheQ9JKHCqv"
+        session = Session(aws_access_key_id=aws_key,
+                          aws_secret_access_key=aws_secret,
+                          aws_session_token=aws_session_token,
+                          region_name="cn-northwest-1") # 此处根据自己的 s3 地区位置改变
+        s3 = session.resource("s3")
+        # client = session.client("s3")
+        bucket = "7cdk" # 【你 bucket 的名字】 # 首先需要保.证 s3 上已经存在该存储桶,否则报错
+        upload_data = open("./././static/log/test.log", "rb")
+        upload_key = "XKWZSC5FCJYT19B7111A/test/test6/test.log"
+        file_obj = s3.Bucket(bucket).put_object(Key=upload_key, Body=upload_data)
+        print('---------------------')
+        print(file_obj)
+        print(8/0)
+        exit()
+
+
+    def testRequest(self,request,request_dict):
+        ip = CommonService.get_ip_address(request)
+        ipInfo = CommonService.getIpIpInfo(ip,"CN")
+        # print(type(ipInfo))
+        # exit(ipInfo)
+        addr = CommonService.getAddr(ip)
+        dicts = {
+            'ipInfo':ipInfo,
+            'addr':addr,
+        }
+        return HttpResponse(json.dumps(dicts, ensure_ascii=False),
+                            content_type="application/json,charset=utf-8")
+
+
+
 
 

+ 63 - 0
Controller/TestController.py

@@ -0,0 +1,63 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+import hashlib
+
+from django.contrib.auth.hashers import make_password, check_password
+from django.views import View
+
+from Object.uidManageResponseObject import uidManageResponseObject
+
+
+class TestView(View):
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation', None)
+        request_dict = request.GET
+        return self.validate(request_dict, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation', None)
+        request_dict = request.POST
+        return self.validate(request_dict, operation)
+
+    def validate(self, request_dict, operation):
+
+        response = uidManageResponseObject()
+
+        if operation == 'createPassword':
+            return self.do_create_password(request_dict, response)
+        elif operation == 'checkPassword':
+            return self.do_check_password(request_dict, response)
+        else:
+            return response.json(404)
+
+    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))
+        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)
+        print(password)
+        print(password2)
+        check = check_password(password, password2)
+
+        return response.json(0, check)
+
+    # def make_password(self, password):
+    #     md5 = hashlib.md5()
+    #     md5.update(str(password).encode('utf-8'))
+    #     return md5.hexdigest()
+    #
+    # def check_password(self, password, encryp):
+    #     print(password)
+    #     print(encryp)
+    #     password1 = self.make_password(password)
+    #     print(password1)
+    #     return encryp == self.make_password(password)

+ 708 - 0
Controller/TestDetectController.py

@@ -0,0 +1,708 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+"""
+@Copyright (C) ansjer cop Video Technology Co.,Ltd.All rights reserved.
+@AUTHOR: ASJRD018
+@NAME: AnsjerFormal
+@software: PyCharm
+@DATE: 2019/1/14 15:57
+@Version: python3.6
+@MODIFY DECORD:ansjer dev
+@file: DetectController.py
+@Contact: chanjunkai@163.com
+"""
+import os
+import time
+
+import apns2
+import jpush as jpush
+import oss2
+from django.http import JsonResponse, HttpResponse
+from django.views.generic.base import View
+from pyfcm import FCMNotification
+from Ansjer.config import SERVER_TYPE, JPUSH_CODE, APNS_CODE, APP_TYPE
+from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, DETECT_PUSH_DOMAIN, JPUSH_CONFIG, FCM_CONFIG, \
+    APNS_CONFIG, BASE_DIR, APNS_MODE
+from Model.models import Equipment_Info, UidPushModel, SysMsgModel
+from Object.ETkObject import ETkObject
+from Object.RedisObject import RedisObject
+from Object.UidTokenObject import UidTokenObject
+from Service.CommonService import CommonService
+import json
+
+'''
+http://push.dvema.com/notify/push?etk=Y2lTRXhMTjBWS01sWlpURTVJU0ZWTlJ6RXhNVUU9T3o=&n_time=1526845794&channel=1&event_type=704&is_st=0
+http://push.dvema.com/deviceShadow/generateUTK?username=debug_user&password=debug_password&uid=VVDHCVBYDKFMJRWA111A
+'''
+
+
+# 移动侦测接口
+class NotificationView(View):
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        return self.validation(request.GET, 0)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        return self.validation(request.POST, 1)
+
+    def validation(self, request_dict, request_type):
+        uidToken = request_dict.get('uidToken', None)
+        etk = request_dict.get('etk', None)
+        channel = request_dict.get('channel', '1')
+        n_time = request_dict.get('n_time', None)
+        event_type = request_dict.get('event_type', None)
+        is_st = request_dict.get('is_st', None)
+        # print("aaa")
+        # return JsonResponse(0,safe=False)
+        if not all([channel, n_time]):
+            return JsonResponse(status=200, data={
+                'code': 444,
+                'msg': 'param is wrong'})
+        if etk:
+            eto = ETkObject(etk)
+            uid = eto.uid
+            if len(uid) != 20:
+                return JsonResponse(status=200, data={'code': 404, 'msg': 'data is not exist'})
+        else:
+            utko = UidTokenObject(uidToken)
+            uid = utko.UID
+        pkey = '{uid}_{channel}_{event_type}_ptl'.format(uid=uid, event_type=event_type, channel=channel)
+        # ykey = 'MUJ887NLR8K8GBM9111A_redis_qs'.format(uid=uid)
+        ykey = '{uid}_redis_qs'.format(uid=uid)
+        dkey = '{uid}_{channel}_{event_type}_flag'.format(uid=uid, event_type=event_type, channel=channel)
+        # 判断redisObj.get_data(key=pkey):不为空
+        redisObj = RedisObject(db=6)
+        have_ykey = redisObj.get_data(key=ykey)  # uid_set 数据库缓存
+        have_pkey = redisObj.get_data(key=pkey)  # 一分钟限制key
+        have_dkey = redisObj.get_data(key=dkey)  # 推送类型限制
+
+        # 一分钟外,推送开启状态
+        detect_med_type = 0  # 0推送旧机制 1存库不推送,2推送存库
+        # 暂时注销
+        if have_pkey:
+            if SERVER_TYPE != "Ansjer.formal_settings":
+                res_data = {'code': 0, 'msg': 'Push once every 10 seconds'}
+            else:
+                res_data = {'code': 0, 'msg': 'Push it once a minute'}
+            return JsonResponse(status=200, data=res_data)
+
+        # 数据库读取数据
+        if have_ykey:
+            redis_list = eval(redisObj.get_data(key=ykey))
+        else:
+            # 从数据库查询出来
+            uid_push_qs = UidPushModel.objects.filter(uid_set__uid=uid, uid_set__detect_status=1). \
+                values('token_val', 'app_type', 'appBundleId', 'm_code',
+                       'push_type', 'userID_id', 'userID__NickName', 'userID__username',
+                       'lang', 'm_code', 'tz', 'uid_set__nickname', 'uid_set__detect_interval', 'uid_set__detect_group',
+                       'uid_set__channel')
+            # 新建一个list接收数据
+            redis_list = []
+            # 把数据库数据追加进redis_list
+            for qs in uid_push_qs:
+                redis_list.append(qs)
+            # 修改redis数据,并设置过期时间为10分钟
+            redisObj.set_data(key=ykey, val=str(redis_list), expire=600)
+            if not redis_list:
+                res_data = {'code': 404, 'msg': 'error !'}
+                return JsonResponse(status=200, data=res_data)
+
+            # 此时应该更新一下redis里面的dkey的有效时间
+            detect_interval = redis_list[0]['uid_set__detect_interval']
+            channel = redis_list[0]['uid_set__channel']
+            self.do_update_detect_interval(uid, channel, redisObj, detect_interval)
+
+
+        if not redis_list:
+            print("没有redi_list")
+            res_data = {'code': 0, 'msg': 'no redi_list success!'}
+            return JsonResponse(status=200, data=res_data)
+
+        is_sys_msg = self.is_sys_msg(int(event_type))
+        nickname = redis_list[0]['uid_set__nickname']
+        detect_interval = redis_list[0]['uid_set__detect_interval']
+        detect_group = redis_list[0]['uid_set__detect_group']
+        now_time = int(time.time())
+        if not nickname:
+            nickname = uid
+        print('detect_group')
+        print(detect_group)
+        print(detect_interval)
+        if detect_group:
+            if have_dkey:
+                detect_med_type = 1  # 1为存库不推送
+            else:
+                detect_med_type = 2  # 为2的话,既推送,又存库
+                # detect_group=0允许全部推送的时候
+                if detect_group == '0':
+                    redisObj.set_data(key=dkey, val=1, expire=detect_interval)
+                else:
+                    detect_group_list = detect_group.split(',')
+                    if event_type in detect_group_list:
+                        if detect_interval < 60:
+                            detect_interval = 60
+                        redisObj.set_data(key=dkey, val=1, expire=detect_interval)
+                # 改为1秒
+                # 如果不是正式
+                if SERVER_TYPE!="Ansjer.formal_settings":
+                    redisObj.set_data(key=pkey, val=1, expire=10)
+                else:
+                    redisObj.set_data(key=pkey, val=1, expire=60)
+
+            # 打印have_ykey
+        # return JsonResponse(status=200, data={'pkey': 0, 'have_ykey': have_ykey, 'have_pkey': have_pkey, 'have_ykey': have_dkey})
+
+        # 旧模式并且没有pkey,重新创建一个
+        if not detect_group and not have_pkey:
+            # 设置推送时间为60秒一次
+            # 如果不是正式
+            if SERVER_TYPE != "Ansjer.formal_settings":
+                redisObj.set_data(key=pkey, val=1, expire=10)
+            else:
+                redisObj.set_data(key=pkey, val=1, expire=60)
+        auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
+        bucket = oss2.Bucket(auth, 'oss-cn-shenzhen.aliyuncs.com', 'apg')
+        kwag_args = {
+            'uid': uid,
+            'channel': channel,
+            'event_type': event_type,
+            'n_time': n_time,
+            # 'appBundleId': appBundleId,
+            # 'token_val': token_val,
+            # 'msg_title': msg_title,
+            # 'msg_text': msg_text
+        }
+        eq_list = []
+        sys_msg_list = []
+        userID_ids = []
+        do_apns_code = ''
+        do_fcm_code = ''
+        do_jpush_code = ''
+        for up in redis_list:
+            push_type = up['push_type']
+            appBundleId = up['appBundleId']
+            token_val = up['token_val']
+            lang = up['lang']
+            tz = up['tz']
+            # 发送标题
+            msg_title = self.get_msg_title(appBundleId=appBundleId, nickname=nickname)
+            # 发送内容
+            msg_text = self.get_msg_text(channel=channel, n_time=n_time, lang=lang, tz=tz,
+                                         event_type=event_type)
+            kwag_args['appBundleId'] = appBundleId
+            kwag_args['token_val'] = token_val
+            kwag_args['msg_title'] = msg_title
+            kwag_args['msg_text'] = msg_text
+            #推送
+            if detect_med_type == 2 or detect_med_type == 0:
+                if push_type == 0:  # ios apns
+                    print('do_apns')
+                    # self.do_apns(**kwag_args)
+                    do_apns_code = self.do_apns(**kwag_args)
+                    up['push_code'] = do_apns_code
+                elif push_type == 1:  # android gcm
+                    print('do_fcm')
+                    do_fcm_code = self.do_fcm(**kwag_args)
+                    up['push_code'] = do_fcm_code
+                elif push_type == 2:  # android jpush
+                    print('do_jpush')
+                    do_jpush_code = self.do_jpush(**kwag_args)
+                    up['push_code'] = do_jpush_code
+                    # return JsonResponse(status=200, data={'code': 0, '状态:': self.do_jpush(**kwag_args)})
+
+            if detect_med_type == 1:
+                do_apns_code = '只存库不推送'
+                do_fcm_code = '只存库不推送'
+                do_jpush_code = '只存库不推送'
+                up['push_code'] = -1
+
+            # 以下是存库
+            userID_id = up["userID_id"]
+            int_is_st = int(is_st)
+            if userID_id not in userID_ids:
+                eq_list.append(Equipment_Info(
+                    userID_id=userID_id,
+                    eventTime=n_time,
+                    eventType=event_type,
+                    devUid=uid,
+                    devNickName=nickname,
+                    Channel=channel,
+                    alarm='Motion \tChannel:{channel}'.format(channel=channel),
+                    is_st=int_is_st,
+                    receiveTime=n_time,
+                    addTime=now_time
+                ))
+                if is_sys_msg:
+                    sys_msg_text = self.get_msg_text(channel=channel, n_time=n_time, lang=lang, tz=tz,
+                                                     event_type=event_type, is_sys=1)
+                    sys_msg_list.append(SysMsgModel(
+                        userID_id=userID_id,
+                        msg=sys_msg_text,
+                        addTime=now_time,
+                        updTime=now_time,
+                        uid=uid,
+                        eventType=event_type))
+                userID_ids.append(userID_id)
+        if is_sys_msg:
+            SysMsgModel.objects.bulk_create(sys_msg_list)
+        Equipment_Info.objects.bulk_create(eq_list)
+
+        if is_st == '0' or is_st == '2':
+            print("is_st=0or2")
+            for up in redis_list:
+                # if up['push_type'] == 0:  # ios apns
+                #     up['do_apns_code'] = do_apns_code
+                # elif up['push_type'] == 1:  # android gcm
+                #     up['do_fcm_code'] = do_fcm_code
+                # elif up['push_type'] == 2:  # android jpush
+
+                try:
+
+                    code = up['push_code']
+                    print("push_code is ")
+                    print(code)
+                    if up['push_type'] == 0:
+                        up['push_res'] = '{code} {desc}'.format(code=code, desc=APNS_CODE[code])
+                        up['push_type'] = '苹果推送'
+                    elif up['push_type'] == 1:
+                        up['push_res'] = code
+                        up['push_type'] = '谷歌推送'
+                    elif up['push_type'] == 2:
+                        up['push_res'] = '{code} {desc}'.format(code=code, desc=JPUSH_CODE[code])
+                        up['push_type'] = '极光推送'
+
+
+                except KeyError as ke:
+                    print(ke)
+                else:
+                    del up['push_code']
+
+                #up['test_or_www'] = SERVER_TYPE
+                if SERVER_TYPE == 'Ansjer.formal_settings':
+                    up['server_type'] = '正式服务器'
+                else:
+                    up['server_type'] = '测试服务器'
+
+                up['app_type'] = APP_TYPE[up['app_type']]
+
+                # del up['push_type']
+                del up['userID_id']
+                del up['userID__NickName']
+                del up['lang']
+                del up['tz']
+                del up['uid_set__nickname']
+                del up['uid_set__detect_interval']
+                del up['uid_set__detect_group']
+
+                if request_type == 0:
+                    data = ""
+                    for up in redis_list:
+                        data += ("<p>" + repr(up) + "</p>")
+                    return HttpResponse(repr(data))
+                else:
+                    return JsonResponse(status=200, data={'code': 0, 'msg': 'success 0 or 2', 're_list': redis_list})
+
+        elif is_st == '1':
+            print("is_st=1")
+            # Endpoint以杭州为例,其它Region请按实际情况填写。
+            obj = '{uid}/{channel}/{filename}.jpeg'.format(uid=uid, channel=channel, filename=n_time)
+            # 设置此签名URL在60秒内有效。
+            url = bucket.sign_url('PUT', obj, 7200)
+            for up in redis_list:
+                up['do_apns_code'] = do_apns_code
+                up['do_fcm_code'] = do_fcm_code
+                up['do_jpush_code'] = do_jpush_code
+                up['test_or_www'] = SERVER_TYPE
+                del up['push_type']
+                del up['userID_id']
+                del up['userID__NickName']
+                del up['lang']
+                del up['tz']
+                del up['uid_set__nickname']
+                del up['uid_set__detect_interval']
+                del up['uid_set__detect_group']
+                # 不是正式服务器
+            if SERVER_TYPE != "Ansjer.formal_settings":
+                res_data = {'code': 0, 'img_push': url, 'msg': 'success', 're_list': redis_list}
+            else:
+                # 是正式服务器的时候
+                res_data = {'code': 0, 'img_push': url, 'msg': 'success'}
+
+            return JsonResponse(status=200, data=res_data)
+
+        elif is_st == '3':
+            print("is_st=3")
+            # 人形检测带动图
+            # Endpoint以杭州为例,其它Region请按实际情况填写。
+            img_url_list = []
+            for i in range(int(is_st)):
+                obj = '{uid}/{channel}/{filename}_{st}.jpeg'. \
+                    format(uid=uid, channel=channel, filename=n_time, st=i)
+                # 设置此签名URL在60秒内有效。
+                url = bucket.sign_url('PUT', obj, 7200)
+                img_url_list.append(url)
+
+            for up in redis_list:
+                up['do_apns_code'] = do_apns_code
+                up['do_fcm_code'] = do_fcm_code
+                up['do_jpush_code'] = do_jpush_code
+                up['test_or_www'] = SERVER_TYPE
+                del up['push_type']
+                del up['userID_id']
+                del up['userID__NickName']
+                del up['lang']
+                del up['tz']
+                del up['uid_set__nickname']
+                del up['uid_set__detect_interval']
+                del up['uid_set__detect_group']
+
+            # 不是正式服务器
+            if SERVER_TYPE != "Ansjer.formal_settings":
+                res_data = {'code': 0, 'img_url_list': img_url_list, 'msg': 'success 3', 're_list': redis_list}
+            else:
+                # 是正式服务器的时候
+                res_data = {'code': 0, 'img_url_list': img_url_list, 'msg': 'success 3'}
+            return JsonResponse(status=200, data=res_data)
+
+
+    def get_msg_title(self, appBundleId, nickname):
+        package_title_config = {
+            'com.ansjer.customizedd_a': 'DVS',
+            'com.ansjer.zccloud_a': 'ZosiSmart',
+            'com.ansjer.zccloud_ab': '周视',
+            'com.ansjer.adcloud_a': 'ADCloud',
+            'com.ansjer.adcloud_ab': 'ADCloud',
+            'com.ansjer.accloud_a': 'ACCloud',
+            'com.ansjer.loocamccloud_a': 'Loocam',
+            'com.ansjer.loocamdcloud_a': 'Anlapus',
+            'com.ansjer.customizedb_a': 'COCOONHD',
+            'com.ansjer.customizeda_a': 'Guardian365',
+            'com.ansjer.customizedc_a': 'PatrolSecure',
+        }
+        if appBundleId in package_title_config.keys():
+            return package_title_config[appBundleId] + '(' + nickname + ')'
+        else:
+            return nickname
+
+    def is_sys_msg(self, event_type):
+        event_type_list = [702, 703, 704]
+        if event_type in event_type_list:
+            return True
+        return False
+
+    def get_msg_text(self, channel, n_time, lang, tz, event_type, is_sys=0):
+        n_date = CommonService.get_now_time_str(n_time=n_time, tz=tz,lang=lang)
+        etype = int(event_type)
+        if lang == 'cn':
+            if etype == 704:
+                msg_type = '电量过低'
+            elif etype == 702:
+                msg_type = '摄像头休眠'
+            elif etype == 703:
+                msg_type = '摄像头唤醒'
+            else:
+                msg_type = ''
+            if is_sys:
+                send_text = '{msg_type} 通道:{channel}'.format(msg_type=msg_type, channel=channel)
+            else:
+                send_text = '{msg_type} 通道:{channel} 日期:{date}'.format(msg_type=msg_type, channel=channel, date=n_date)
+                # send_text = '{msg_type} 通道:{channel} 日期:{date}'.format(msg_type=msg_type, channel=channel, date=n_date)
+        else:
+            if etype == 704:
+                msg_type = 'Low battery'
+            elif etype == 702:
+                msg_type = 'Camera sleep'
+            elif etype == 703:
+                msg_type = 'Camera wake'
+            else:
+                msg_type = ''
+            if is_sys:
+                send_text = '{msg_type} channel:{channel}'. \
+                    format(msg_type=msg_type, channel=channel)
+            else:
+                send_text = '{msg_type} channel:{channel} date:{date}'. \
+                    format(msg_type=msg_type, channel=channel, date=n_date)
+        return send_text
+
+    def do_jpush(self, uid, channel, appBundleId, token_val, event_type, n_time,
+                 msg_title, msg_text):
+        app_key = JPUSH_CONFIG[appBundleId]['Key']
+        master_secret = JPUSH_CONFIG[appBundleId]['Secret']
+        # 此处换成各自的app_key和master_secre
+        _jpush = jpush.JPush(app_key, master_secret)
+        push = _jpush.create_push()
+        # if you set the logging level to "DEBUG",it will show the debug logging.
+        # _jpush.set_logging("DEBUG")
+        # push.audience = jpush.all_
+        push.audience = jpush.registration_id(token_val)
+        push_data = {"alert": "Motion ", "event_time": n_time, "event_type": event_type, "msg": "",
+                     "received_at": n_time, "sound": "sound.aif", "uid": uid, "zpush": "1", "channel": channel}
+        android = jpush.android(alert=msg_text, priority=1, style=1, alert_type=7,
+                                big_text=msg_text, title=msg_title,
+                                extras=push_data)
+        push.notification = jpush.notification(android=android)
+        push.platform = jpush.all_
+        res = push.send()
+        print(res)
+        return res.status_code
+        # try:
+        #     res = push.send()
+        #     print(res)
+        # except Exception as e:
+        #     print("jpush fail")
+        #     print("Exception")
+        #     print(repr(e))
+        #     return
+        # else:
+        #     print("jpush success")
+        #     return
+
+    def do_fcm(self, uid, channel, appBundleId, token_val, event_type, n_time, msg_title, msg_text):
+        try:
+            serverKey = FCM_CONFIG[appBundleId]
+        except Exception as e:
+            return 'serverKey abnormal'
+        push_service = FCMNotification(api_key=serverKey)
+        data = {"alert": "Motion ", "event_time": n_time, "event_type": event_type, "msg": "",
+                "received_at": n_time, "sound": "sound.aif", "uid": uid, "zpush": "1", "channel": channel}
+        result = push_service.notify_single_device(registration_id=token_val, message_title=msg_title,
+                                                   message_body=msg_text, data_message=data,
+                                                   extra_kwargs={
+                                                       'default_vibrate_timings': True,
+                                                       'default_sound': True,
+                                                       'default_light_settings': True
+                                                   })
+        print('fcm push ing')
+        print(result)
+        return result
+
+    def do_apns(self, uid, channel, appBundleId, token_val, event_type, n_time, msg_title,
+                msg_text):
+        try:
+            cli = apns2.APNSClient(mode=APNS_MODE,
+                                   client_cert=os.path.join(BASE_DIR, APNS_CONFIG[appBundleId]['pem_path']))
+
+            push_data = {"alert": "Motion ", "event_time": n_time, "event_type": event_type, "msg": "",
+                         "received_at": n_time, "sound": "sound.aif", "uid": uid, "zpush": "1", "channel": channel}
+            alert = apns2.PayloadAlert(body=msg_text, title=msg_title)
+            payload = apns2.Payload(alert=alert, custom=push_data)
+
+            # return uid, channel, appBundleId, str(token_val), event_type, n_time, msg_title,msg_text
+            n = apns2.Notification(payload=payload, priority=apns2.PRIORITY_LOW)
+            res = cli.push(n=n, device_token=token_val, topic=appBundleId)
+            print(res.status_code)
+
+            #     200, 推送成功。
+            #   400, 请求有问题。
+            #   403, 证书或Token有问题。
+            #   405, 请求方式不正确, 只支持POST请求
+            #   410, 设备的Token与证书不一致
+            if res.status_code == 200:
+                return res.status_code
+            else:
+                print('apns push fail')
+                print(res.reason)
+                return res.status_code
+        except (ValueError, ArithmeticError):
+            return 'The program has a numeric format exception, one of the arithmetic exceptions'
+        except Exception as e:
+            print(repr(e))
+            return repr(e)
+
+
+    def getJPushReport(self, msg_id, appBundleId):
+        app_key = JPUSH_CONFIG[appBundleId]['Key']
+        master_secret = JPUSH_CONFIG[appBundleId]['Secret']
+        _jpush = jpush.JPush(app_key, master_secret)
+        report = _jpush.create_report()
+        res = report.get_received_detail(msg_id)
+        print("getJPushReport")
+        print(res)
+
+    def do_update_detect_interval(self, uid, channel, redisObject, detect_interval):
+        if channel == 0:
+            channel = 17
+        else:
+            channel += 1
+        for i in range(1, channel):
+            tmpDKey = '{uid}_{channel}_{event_type}_flag'.format(uid=uid, event_type=51, channel=i)
+            if tmpDKey is not False:
+                llt = redisObject.get_ttl(tmpDKey)
+                if llt > detect_interval:
+                    redisObject.set_data(key=tmpDKey, val=1, expire=detect_interval)
+
+            tmpDKey = '{uid}_{channel}_{event_type}_flag'.format(uid=uid, event_type=54, channel=i)
+            if tmpDKey is not False:
+                llt = redisObject.get_ttl(tmpDKey)
+                if llt > detect_interval:
+                    redisObject.set_data(key=tmpDKey, val=1, expire=detect_interval)
+
+
+
+# http://test.dvema.com/detect/add?uidToken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiJQMldOR0pSRDJFSEE1RVU5MTExQSJ9.xOCI5lerk8JOs5OcAzunrKCfCrtuPIZ3AnkMmnd-bPY&n_time=1526845794&channel=1&event_type=51&is_st=0
+# 移动侦测接口
+class PushNotificationView(View):
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        # operation = kwargs.get('operation')
+        return self.validation(request.GET)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        # operation = kwargs.get('operation')
+        return self.validation(request.POST)
+
+    def validation(self, request_dict):
+        etk = request_dict.get('etk', None)
+        channel = request_dict.get('channel', '1')
+        n_time = request_dict.get('n_time', None)
+        event_type = request_dict.get('event_type', None)
+        is_st = request_dict.get('is_st', None)
+        eto = ETkObject(etk)
+        uid = eto.uid
+        if len(uid) == 20:
+            redisObj = RedisObject(db=6)
+            # pkey = '{uid}_{channel}_ptl'.format(uid=uid, channel=channel)
+            pkey = '{uid}_ptl'.format(uid=uid)
+            ykey = '{uid}_redis_qs'.format(uid=uid)
+            if redisObj.get_data(key=pkey):
+                res_data = {'code': 0, 'msg': 'success,!33333333333'}
+                return JsonResponse(status=200, data=res_data)
+            else:
+                redisObj.set_data(key=pkey, val=1, expire=60)
+            ##############
+            redis_data = redisObj.get_data(key=ykey)
+            if redis_data:
+                redis_list = eval(redis_data)
+            else:
+                # 设置推送时间为60秒一次
+                redisObj.set_data(key=pkey, val=1, expire=60)
+                print("从数据库查到数据")
+                # 从数据库查询出来
+                uid_push_qs = UidPushModel.objects.filter(uid_set__uid=uid, uid_set__detect_status=1). \
+                    values('token_val', 'app_type', 'appBundleId',
+                           'push_type', 'userID_id', 'lang','m_code',
+                           'tz', 'uid_set__nickname')
+                # 新建一个list接收数据
+                redis_list = []
+                # 把数据库数据追加进redis_list
+                for qs in uid_push_qs:
+                    redis_list.append(qs)
+                # 修改redis数据,并设置过期时间为10分钟
+            if redis_list:
+                redisObj.set_data(key=ykey, val=str(redis_list), expire=600)
+                auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
+                bucket = oss2.Bucket(auth, 'oss-cn-shenzhen.aliyuncs.com', 'apg')
+                self.do_bulk_create_info(redis_list, n_time, channel, event_type, is_st, uid)
+                if is_st == '0' or is_st == '2':
+                    return JsonResponse(status=200, data={'code': 0, 'msg': 'success44444444444444444'})
+                elif is_st == '1':
+                    # Endpoint以杭州为例,其它Region请按实际情况填写。
+                    obj = '{uid}/{channel}/{filename}.jpeg'.format(uid=uid, channel=channel, filename=n_time)
+                    # 设置此签名URL在60秒内有效。
+                    url = bucket.sign_url('PUT', obj, 7200)
+                    res_data = {'code': 0, 'img_push': url, 'msg': 'success'}
+                    return JsonResponse(status=200, data=res_data)
+                elif is_st == '3':
+                    # 人形检测带动图
+                    img_url_list = []
+                    for i in range(int(is_st)):
+                        obj = '{uid}/{channel}/{filename}_{st}.jpeg'. \
+                            format(uid=uid, channel=channel, filename=n_time, st=i)
+                        # 设置此签名URL在60秒内有效。
+                        url = bucket.sign_url('PUT', obj, 7200)
+                        img_url_list.append(url)
+                    res_data = {'code': 0, 'img_url_list': img_url_list, 'msg': 'success'}
+                    return JsonResponse(status=200, data=res_data)
+            else:
+                return JsonResponse(status=200, data={'code': 404, 'msg': 'data is not exist'})
+        else:
+            return JsonResponse(status=200, data={'code': 404, 'msg': 'wrong etk'})
+
+    def do_bulk_create_info(self, uaqs, n_time, channel, event_type, is_st, uid):
+        now_time = int(time.time())
+        # 设备昵称
+        userID_ids = []
+        sys_msg_list = []
+        is_sys_msg = self.is_sys_msg(int(event_type))
+        is_st = int(is_st)
+        eq_list = []
+        nickname = uaqs[0]['uid_set__nickname']
+        if not nickname:
+            nickname = uid
+        for ua in uaqs:
+            lang = ua['lang']
+            tz = ua['tz']
+            userID_id = ua["userID_id"]
+            if userID_id not in userID_ids:
+                eq_list.append(Equipment_Info(
+                    userID_id=userID_id,
+                    eventTime=n_time,
+                    eventType=event_type,
+                    devUid=uid,
+                    devNickName=nickname,
+                    Channel=channel,
+                    alarm='Motion \tChannel:{channel}'.format(channel=channel),
+                    is_st=is_st,
+                    receiveTime=n_time,
+                    addTime=now_time
+                ))
+                if is_sys_msg:
+                    sys_msg_text = self.get_msg_text(channel=channel, n_time=n_time, lang=lang, tz=tz,
+                                                     event_type=event_type, is_sys=1)
+                    sys_msg_list.append(SysMsgModel(
+                        userID_id=userID_id,
+                        msg=sys_msg_text,
+                        addTime=now_time,
+                        updTime=now_time,
+                        uid=uid,
+                        eventType=event_type))
+        if eq_list:
+            print('eq_list')
+            Equipment_Info.objects.bulk_create(eq_list)
+        if is_sys_msg:
+            print('sys_msg')
+            SysMsgModel.objects.bulk_create(sys_msg_list)
+        return True
+
+    def is_sys_msg(self, event_type):
+        event_type_list = [702, 703, 704]
+        if event_type in event_type_list:
+            return True
+        return False
+
+    def get_msg_text(self, channel, n_time, lang, tz, event_type, is_sys=0):
+        n_date = CommonService.get_now_time_str(n_time=n_time, tz=tz)
+        etype = int(event_type)
+        if lang == 'cn':
+            if etype == 704:
+                msg_type = '电量过低'
+            elif etype == 702:
+                msg_type = '摄像头休眠'
+            elif etype == 703:
+                msg_type = '摄像头唤醒'
+            else:
+                msg_type = ''
+            if is_sys:
+                send_text = '{msg_type} 通道:{channel}'.format(msg_type=msg_type, channel=channel)
+            else:
+                send_text = '{msg_type} 通道:{channel} 日期:{date}'.format(msg_type=msg_type, channel=channel, date=n_date)
+        else:
+            if etype == 704:
+                msg_type = 'Low battery'
+            elif etype == 702:
+                msg_type = 'Camera sleep'
+            elif etype == 703:
+                msg_type = 'Camera wake'
+            else:
+                msg_type = ''
+            if is_sys:
+                send_text = '{msg_type} channel:{channel}'. \
+                    format(msg_type=msg_type, channel=channel)
+            else:
+                send_text = '{msg_type} channel:{channel} date:{date}'. \
+                    format(msg_type=msg_type, channel=channel, date=n_date)
+        return send_text

+ 489 - 0
Controller/UIDController.py

@@ -0,0 +1,489 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+import json
+import logging
+import time
+
+from django.db import transaction
+from django.http import StreamingHttpResponse
+from django.utils.decorators import method_decorator
+from django.views import View
+from django.views.decorators.csrf import csrf_exempt
+from django.db.models import Avg,Max,Min,Count,Sum, Q  #   引入函数
+
+from Model.models import UIDModel, UserModel, UserUIDModel, HistoryUIDModel, UIDCompanySerialModel
+from Object.RedisObject import RedisObject
+from Object.uidManageResponseObject import uidManageResponseObject
+from Object.TokenObject import TokenObject
+from Service.ModelService import ModelService
+
+
+class UIDView(View):
+
+    @method_decorator(csrf_exempt)
+    def dispatch(self, request, *args, **kwargs):
+        return super(UIDView, self).dispatch(request, *args, **kwargs)
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.GET
+        operation = kwargs.get('operation')
+        return self.validate(request_dict, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.POST
+        operation = kwargs.get('operation')
+        return self.validate(request_dict, operation)
+
+    def validate(self, request_dict, operation):
+        token = request_dict.get('token', None)
+        response = uidManageResponseObject()
+
+        token = TokenObject(token)
+        if token.code != 0:
+            return response.json(token.code)
+
+        if operation == 'quantity':
+            return self.do_quantity(request_dict, response)
+        elif operation == 'allot':
+            return self.do_allot(request_dict, response)
+        elif operation == 'remove':
+            return self.do_remove(request_dict, response)
+        elif operation == 'download':
+            return self.download_txt(token, response)
+        elif operation == 'download_1':
+            return self.download_txt_two(token, response)
+        elif operation == 'list':
+            return self.do_list(request_dict, response)
+        elif operation == 'delete':
+            return self.do_delete(token.userID, request_dict, response)
+        elif operation == 'batchDelete':
+            return self.do_batch_delete(token.userID, request_dict, response)
+        elif operation == 'adminUpdate':
+            return self.do_admin_update(token.userID, request_dict, response)
+        elif operation == 'history':
+            return self.do_history(token.userID, request_dict, response)
+        elif operation == 'statistics':
+            return self.do_admin_statistics(token.userID, request_dict, response)
+        else:
+            return response.json(309)
+
+    # 查询当前可用的UID的数量
+    def do_quantity(self, request_dict, response):
+        token = request_dict.get('token', None)
+
+        token = TokenObject(token)
+        if token.code != 0:
+            return response.json(token.code)
+
+        user_qs = UserModel.objects.filter(id=token.userID)
+        if user_qs.exists():
+            user = user_qs[0]
+            if user.permission == '0':
+                return self.do_admin_quantity(request_dict, response, user.username)
+            else:
+                return self.do_not_admin_quantity(request_dict, response, user.username)
+        else:
+            return response.json(9)
+
+    # 管理员的查询UID数量操作
+    def do_admin_quantity(self, request_dict, response, admin):
+        datas = []
+        domestic = UIDModel.objects.filter(area=0, status=0).count()
+        foreign = UIDModel.objects.filter(area=1, status=0).count()
+        item = {}
+        item['isAdmin'] = 1
+        item['domestic'] = domestic
+        item['foreign'] = foreign
+        item['username'] = admin
+        datas.append(item)
+
+        user_qs = UserModel.objects.filter(~Q(Q(permission='0')))
+        for user in user_qs:
+            item = {'isAdmin': 0}
+            result = UserUIDModel.objects.filter(user__id=user.id, uid__status=1, uid__area=0).aggregate(num=Count('uid__status'))
+            item['domestic'] = result['num']
+            result = UserUIDModel.objects.filter(user__id=user.id, uid__status=1, uid__area=1).aggregate(num=Count('uid__status'))
+            item['foreign'] = result['num']
+            item['username'] = user.username
+            datas.append(item)
+
+        return response.json(0, {'data': datas})
+
+    # 非管理员的查询UID数量操作
+    def do_not_admin_quantity(self, request_dict, response, username):
+        user_qs = UserModel.objects.filter(username=username)
+        if user_qs.exists():
+            user = user_qs[0]
+            datas = []
+            item = {'isAdmin': 0}
+            result = UserUIDModel.objects.filter(user__id=user.id, uid__status=1, uid__area=0).aggregate(num=Count('uid__status'))
+            item['domestic'] = result['num']
+            result = UserUIDModel.objects.filter(user__id=user.id, uid__status=1, uid__area=1).aggregate(num=Count('uid__status'))
+            item['foreign'] = result['num']
+            item['username'] = user.username
+            datas.append(item)
+            return response.json(0, {'data': datas})
+        else:
+            return response.json(444)
+
+    # 分配UID
+    @transaction.atomic
+    def do_allot(self, request_dict, response):
+        username = request_dict.get('username', None)
+        quantity = int(request_dict.get('quantity', None))
+        area = request_dict.get('area', None)
+        token = request_dict.get('token', None)
+
+        token = TokenObject(token)
+        if token.code != 0:
+            return response.json(token.code)
+        user = UserModel.objects.get(id=token.userID)
+
+        if not user or '0' not in user.permission:
+            return response.json(404)
+
+        # 要分配的对象
+        allot_user_qs = UserModel.objects.filter(username=username)
+        if not allot_user_qs.exists():
+            return response.json(444, 'username')
+
+        # 取出对应区域可用的UID分配给allot_user
+        uid_qs = UIDModel.objects.filter(area=area, status=0)
+        count = uid_qs.count()
+        if count < quantity:
+            return response.json(444, '设备UID不足')
+
+        updates = []
+        datas = []
+        count = 0
+        if uid_qs.exists():
+            uid_qs = uid_qs[0:quantity]
+            now_time = int(time.time())
+            savePoint = transaction.savepoint()
+            for item in uid_qs:
+                item.status = 1
+                item.update_time = time.time()
+                user_uid = UserUIDModel()
+                user_uid.uid = item
+                user_uid.user = allot_user_qs[0]
+                user_uid.add_time = now_time
+                user_uid.update_time = now_time
+                datas.append(user_uid)
+                updates.append(item)
+
+                if len(datas) % 5000 == 0:
+                    result = self.do_update(datas, updates, savePoint)
+                    if result != 0:
+                        return response.json(result)
+
+            if len(datas) > 0:
+                result = self.do_update(datas, updates, savePoint)
+                if result != 0:
+                    return response.json(result)
+            redisObject = RedisObject()
+            values = uid_qs.values('uid')
+            print(values)
+            redisObject.set_data(key=token.token, val=json.dumps(list(values)), expire=3600)
+            del datas
+            del updates
+            return response.json(0)
+        else:
+            return response.json(444)
+
+    def do_update(self, datas, updates, savePoint, count=0):
+        try:
+            try:
+                UserUIDModel.objects.bulk_create(datas)
+                UIDModel.objects.bulk_update(updates, fields=['status', 'update_time'])
+                datas.clear()
+                updates.clear()
+            except Exception as e:
+                if savePoint:
+                    transaction.savepoint_rollback(savePoint)
+                djangoLogger = logging.getLogger('django')
+                djangoLogger.exception(repr(e))
+                return 174
+        except Exception as e:
+            return 174
+        return 0
+
+    # 把UID表中的数据移动到HistoryUID表中
+    def do_remove(self, request_dict, response):
+        token = TokenObject(request_dict.get('token', None))
+        id = request_dict.get('id', None)
+        start = request_dict.get('start', None)
+        stop = request_dict.get('stop', None)
+
+        if token.code != 0:
+            return response.json(token.code)
+
+        # 通过userID查找用户,判断是否是管理员
+        user_qs = UserModel.objects.filter(id=token.userID)
+        if user_qs.exists():
+            user = user_qs[0]
+            if user.permission != '0':
+                return response.json(404)
+        else:
+            return response.json(9)
+
+        if id:
+            return self.do_remove_by_id(id, response)
+        elif start and stop:
+            return self.do_bulk_remove(int(start), int(stop), response)
+        else:
+            return response.json(444, 'id,start,stop')
+
+    # 移除单条UID记录,id:记录id
+    def do_remove_by_id(self, id, response):
+        id = int(id)
+        uid_qs = UIDModel.objects.filter(id=id)
+        if not uid_qs.exists():
+            return response.json(173)
+
+        uid = uid_qs[0]
+        if uid:
+            data = {
+                'uid': uid.uid,
+                'uid_extra': uid.uid_extra,
+                'status': uid.status,
+                'add_time': uid.add_time,
+                'update_time': uid.update_time,
+                'area': uid.area
+            }
+            HistoryUIDModel.objects.create(**data)
+            uid.delete()
+            return response.json(0)
+        else:
+            return response.json(444, 'id')
+
+    # 批量移除UID记录。start:开始的UID记录的id;stop:结束的UID记录的id
+    def do_bulk_remove(self, start, stop, response):
+        uid_qs = UIDModel.objects.filter(id__range=(start, stop))
+        histories = []
+        if uid_qs.exists():
+            for item in uid_qs:
+                histories.append(HistoryUIDModel(
+                    uid=item.uid,
+                    uid_extra=item.uid_extra,
+                    status=item.status,
+                    add_time=item.add_time,
+                    update_time=item.update_time,
+                    area=item.area
+                ))
+                if len(histories) % 5000 == 0:
+                    HistoryUIDModel.objects.bulk_create(histories)
+                    histories.clear()
+            if len(histories) > 0:
+                HistoryUIDModel.objects.bulk_create(histories)
+                histories.clear()
+            uid_qs.delete()
+            return response.json(0)
+        else:
+            return response.json(173)
+
+    def download_txt(self, token, response):
+
+        redisObject = RedisObject()
+        uid_qs = redisObject.get_data(key=token.token)
+
+        if uid_qs is False:
+            return response.json(308)
+
+        uid_qs = json.loads(uid_qs)
+        content = ''
+        for item in uid_qs:
+            # print(item)
+            content += item['uid']
+            content += '\r\n'
+
+        redisObject.del_data(key=token.token)
+
+        content = content[0:len(content) - 1]
+        response = StreamingHttpResponse(content)
+        response['Content-Type'] = 'application/octet-stream'
+        filename = 'uid_need_to_set_up_push.txt'
+        response['Content-Disposition'] = 'attachment;filename=' + filename
+
+        return response
+
+    def download_txt_two(self, token, response):
+
+        uid_qs = UIDModel.objects.filter(status=1)
+
+        if not uid_qs.exists():
+            return response.json(308)
+
+        uid_qs = uid_qs.values()
+        content = ''
+        for item in uid_qs:
+            # print(item)
+            content += item['uid']
+            content += '\r\n'
+
+        content = content[0:len(content) - 1]
+        response = StreamingHttpResponse(content)
+        response['Content-Type'] = 'application/octet-stream'
+        filename = 'uid_need_to_set_up_push.txt'
+        response['Content-Disposition'] = 'attachment;filename=' + filename
+
+        return response
+
+    def do_list(self, request_dict, response):
+        page = request_dict.get('page', None)
+        line = request_dict.get('limit', None)
+        status = request_dict.get('status', None)
+        area = request_dict.get('area', None)
+        start_time = request_dict.get('starttime', None)
+        stop_time = request_dict.get('endtime', None)
+        uid = request_dict.get('uid', None)
+
+        if page and line:
+
+            uid_qs = UIDModel.objects.filter()
+            res = {
+                'count': 0,
+                'data': []
+            }
+
+            if uid_qs.exists():
+                page = int(page)
+                line = int(line)
+
+                start = (page - 1) * line
+                end = start + line
+
+                if uid:
+                    uid_qs = uid_qs.filter(uid=uid)
+
+                if status:
+                    uid_qs = uid_qs.filter(status=status)
+
+                if area:
+                    uid_qs = uid_qs.filter(area=area)
+
+                if start_time:
+                    uid_qs = uid_qs.filter(update_time__gte=start_time)
+
+                if stop_time:
+                    if stop_time > start:
+                        uid_qs = uid_qs.filter(update_time__lte=stop_time)
+
+                res['count'] = uid_qs.count()
+                uid_qs = uid_qs.values()[start:end]
+
+                uid_list = []
+                for uobj in uid_qs:
+                    uid_list.append(uobj['id'])
+
+                serial_uid_qs = UIDCompanySerialModel.objects.filter(uid__id__in=uid_list).values('uid__id','company_serial__serial_number')
+                res['data'] = []
+                for uobj in uid_qs:
+                    list_data = uobj
+                    for data in list(serial_uid_qs):
+                            if uobj['id'] == data['uid__id']:
+                                list_data['serial_number'] = data['company_serial__serial_number']
+                    res['data'].append(list_data)
+            print(res)
+            return response.json(0, res)
+        else:
+            return response.json(444)
+
+    def do_delete(self, userID, request_dict, response):
+        uid = request_dict.get('uid', None)
+        user_qs = UserModel.objects.filter(id=userID)
+
+        if user_qs.exists():
+            user = user_qs[0]
+            if int(user.permission) != 0:
+                return response.json(309)
+
+            UIDModel.objects.filter(uid=uid).delete()
+            return response.json(0)
+        else:
+            return response.json(309)
+
+    def do_batch_delete(self, userID, request_dict, response):
+        # perm = ModelService.check_perm_uid_manage(userID, 0)
+        # if not perm:
+        #     return response.json(309)
+
+        uids = request_dict.get('uidlist', None)
+
+        if uids:
+            uids = json.loads(uids)
+            UIDModel.objects.filter(uid__in=uids).delete()
+            return response.json(0)
+        else:
+            return response.json(444)
+
+    def do_admin_update(self, userID, request_dict, response):
+        # perm = ModelService.check_perm_uid_manage(userID, 0)
+        # if not perm:
+        #     return response.json(309)
+
+        uid = request_dict.get('uid', None)
+        content = request_dict.get('content', None)
+        print(content)
+
+        if uid and content:
+            content = json.loads(content)
+            print(content)
+            content['update_time'] = int(time.time())
+            uid_qs = UIDModel.objects.filter(uid=uid)
+            if uid_qs.exists():
+                uid_qs.update(**content)
+                return response.json(0)
+            else:
+                return response.json(173)
+        else:
+            return response.json(444)
+
+    def do_history(self, userID, request_dict, response):
+        # perm = ModelService.check_perm_uid_manage(userID, 0)
+        # if not perm:
+        #     return response.json(309)
+
+        uid_qs = UIDModel.objects.filter(status=2)
+
+        if uid_qs.exists():
+
+            uids = []
+            for uid in uid_qs:
+                uids.append(uid)
+
+                if (len(uids) % 5000) == 0:
+                    HistoryUIDModel.objects.bulk_create(uids)
+                    uids.clear()
+
+            if len(uids) > 0:
+                HistoryUIDModel.objects.bulk_create(uids)
+                uids.clear()
+
+        uid_qs.delete()
+
+        return response.json(0)
+
+    def do_admin_statistics(self, userID, request_dict, response):
+        # perm = ModelService.check_perm_uid_manage(userID, 0)
+        # if not perm:
+        #     return response.json(309)
+
+        uid_not_use = UIDModel.objects.filter(status=0).count()
+
+        uid_allocated = UIDModel.objects.filter(status=1).count()
+
+        uid_has_use = UIDModel.objects.filter(status=2).count()
+
+        total = uid_not_use + uid_allocated + uid_has_use
+
+        res = {
+            'uid_not_use': uid_not_use,
+            'uid_allocated': uid_allocated,
+            'uid_has_use': uid_has_use,
+            'total': total
+        }
+
+        return response.json(0, res)
+

+ 296 - 0
Controller/UIDManageUserController.py

@@ -0,0 +1,296 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+import time
+
+from django.db.models import Q
+from django.utils.decorators import method_decorator
+from django.views import View
+from django.views.decorators.csrf import csrf_exempt
+
+from Model.models import UserModel
+from Object.uidManageResponseObject import uidManageResponseObject
+from Object.TokenObject import TokenObject
+from Service.ModelService import ModelService
+
+
+class UserView(View):
+
+    @method_decorator(csrf_exempt)
+    def dispatch(self, request, *args, **kwargs):
+        return super(UserView, self).dispatch(request, *args, **kwargs)
+
+    def get(self, request, *args, **kwargs):
+        # print('get')
+        request.encoding = 'utf-8'
+        request_dict = request.GET
+        operation = kwargs.get('operation')
+        return self.validation(request_dict, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.POST
+        operation = kwargs.get('operation')
+        return self.validation(request_dict, operation)
+
+    def validation(self, request_dict, operation):
+
+        if operation == 'login':
+            return self.login(request_dict)
+        elif operation == 'logout':
+            return self.logout(request_dict)
+        else:
+            token = request_dict.get('token', None)
+
+            token = TokenObject(token)
+            response = uidManageResponseObject()
+            if token.code != 0:
+                return response.json(token.code)
+
+            if operation == 'query':
+                return self.do_query(request_dict)
+            elif operation == 'modify':
+                return self.do_modify_password(request_dict)
+            elif operation == 'list':
+                return self.do_list(request_dict)
+            elif operation == 'adminAdd':
+                return self.do_admin_add(token.userID, request_dict, response)
+            elif operation == 'adminDelete':
+                return self.do_admin_delete(token.userID, request_dict, response)
+            elif operation == 'adminUpdate':
+                return self.do_admin_update(token.userID, request_dict, response)
+            elif operation == 'adminReset':
+                return self.do_admin_reset(token.userID, request_dict, response)
+            else:
+                return uidManageResponseObject().json(309)
+
+    def login(self, request_dict):
+        username = request_dict.get('username', None)
+        password = request_dict.get('password', None)
+
+        response = uidManageResponseObject()
+
+        if username is None or password is None:
+            return response.json(444)
+
+        user = UserModel.objects.filter(username=username)
+        if user.exists():
+            if user[0].password != password:
+                return response.json(99)
+            else:
+                token = TokenObject()
+                res = token.generate({'userID': user[0].id})
+                res['permission'] = user[0].permission
+                res['username'] = user[0].username
+                user[0].online = 1
+                update = {
+                    'online': 1
+                }
+                user.update(**update)
+                return response.json(0, res)
+        else:
+            return response.json(99)
+
+    def do_query(self, request_dict):
+        # print('do_query')
+        token = TokenObject(request_dict.get('token', None))
+        # page = request_dict.get('page', None)
+        # line = request_dict.get('line', None)
+        # username = request_dict.get('username', None)
+        response = uidManageResponseObject()
+
+        if token.code != 0:
+            return response.json(token.code)
+
+        # if username:
+        #     user_qs = UserModel.objects.filter(username__icontains=username)
+        #     if user_qs.exists():
+        #         users = list(user_qs.values('username'))
+        #         return response.json(0, {'data': users})
+        #     else:
+        #         return response.json(0, {'data': []})
+        # elif page and line:
+        #     print('query_page')
+        #     user_qs = UserModel.objects.filter(id=token.userID)
+        #     if user_qs.exists():
+        #         user = user_qs[0]
+        #         if user.permission == '0':
+        #             return self.do_query_pagination(int(page), int(line), response)
+        #         else:
+        #             return response.json(404)
+        #     else:
+        #         return response.json(9)
+
+        user_qs = UserModel.objects.filter(~Q(Q(permission='0'))).values('id', 'username')
+
+        return response.json(0, {'data': list(user_qs)})
+
+    def do_query_pagination(self, page, line, response):
+        # print('query start')
+        user_qs = UserModel.objects.filter().values()
+        if user_qs.exists():
+            count = user_qs.count()
+            start = (page - 1) * line
+            end = start + line
+            users = list(user_qs[start:end])
+            # print('query end')
+            return response.json(0, {'count': count, 'data': users})
+        else:
+            return response.json(0, {'count': 0, 'data': []})
+
+    def do_modify_password(self, request_dict):
+        token = request_dict.get('token', None)
+        old_password = request_dict.get('oldPassword', None)
+        new_password = request_dict.get('newPassword', None)
+        token = TokenObject(token)
+
+        response = uidManageResponseObject()
+        if token.code != 0:
+            return response.json(token.code)
+
+        if old_password and new_password:
+            user_qs = UserModel.objects.filter(id=token.userID)
+            if user_qs.exists():
+                if user_qs[0].password != old_password:
+                    return response.json(47)
+                user = {
+                    'password': new_password
+                }
+                user_qs.update(**user)
+                return response.json(0)
+            else:
+                return response.json(9)
+        else:
+            return response.json(444)
+
+    def logout(self, request_dict):
+        token = request_dict.get('token', None)
+        token = TokenObject(token)
+        response = uidManageResponseObject()
+        if token.code != 0:
+            return response.json(0)
+
+        user_qs = UserModel.objects.filter(id=token.userID)
+        if user_qs.exists():
+            user = {
+                'online': 0
+            }
+            user_qs.update(**user)
+            return response.json(0)
+        else:
+            return response.json(0)
+
+    def do_list(self, request_dict):
+        token = request_dict.get('token', None)
+
+        response = uidManageResponseObject()
+        token = TokenObject(token)
+        if token.code != 0:
+            return response.json(token.code)
+
+        page = request_dict.get('page', None)
+        line = request_dict.get('limit', None)
+
+        if page and line:
+            user_qs = UserModel.objects.filter()
+
+            res = {
+                'count': user_qs.count(),
+                'data': []
+            }
+            if user_qs.exists():
+                page = int(page)
+                line = int(line)
+
+                start = (page - 1) * line
+                end = start + line
+
+                user_qs = user_qs[start:end].values('id', 'username', 'permission', 'phone', 'login_time', 'add_time')
+
+                res['data'] = list(user_qs)
+            return response.json(0, res)
+        else:
+            return response.json(444)
+
+    def do_admin_add(self, userID, request_dict, response):
+        # perm = ModelService.check_perm_uid_manage(userID, 0)
+        # if not perm:
+        #     return response.json(309)
+
+        print(request_dict)
+        username = request_dict.get('username', None)
+        password = request_dict.get('password', None)
+        phone = request_dict.get('phone', None)
+        role = request_dict.get('role', None)
+
+        if username and password and role:
+            user = UserModel()
+            user.username = username
+            user.password = password
+            user.permission = role
+            user.phone = phone
+            user.add_time = int(time.time())
+            user.save()
+            return response.json(0)
+        else:
+            return response.json(444)
+
+    def do_admin_delete(self, userID, request_dict, response):
+        # perm = ModelService.check_perm_uid_manage(userID, 0)
+        # if not perm:
+        #     return response.json(309)
+
+        username = request_dict.get('username', None)
+
+        if username:
+            user_qs = UserModel.objects.filter(username=username)
+            if user_qs.exists():
+                user_qs.delete()
+                return response.json(0)
+            else:
+                return response.json(9)
+        else:
+            return response.json(444)
+
+    def do_admin_update(self, userID, request_dict, response):
+        # perm = ModelService.check_perm_uid_manage(userID, 0)
+        # if not perm:
+        #     return response.json(309)
+
+        username = request_dict.get('username', None)
+        role = request_dict.get('role', None)
+        password = request_dict.get('password', None)
+        phone = request_dict.get('phone', None)
+
+        if username:
+            update_data = {}
+
+            if role:
+                update_data['permission'] = role
+
+            if password:
+                update_data['password'] = password
+
+            if phone:
+                update_data['phone'] = phone
+
+            UserModel.objects.filter(username=username).update(**update_data)
+            return response.json(0)
+        else:
+            return response.json(444)
+
+    def do_admin_reset(self, userID, request_dict, response):
+        # perm = ModelService.check_perm_uid_manage(userID, 0)
+        # if not perm:
+        #     return response.json(309)
+
+        username = request_dict.get('username', None)
+
+        if username:
+            user_qs = UserModel.objects.filter(username=username)
+            if user_qs.exists():
+                user_qs.update(password='123456')
+                return response.json(0)
+            else:
+                return response.json(9)
+        else:
+            return response.json(444)

+ 99 - 1
Controller/UidSetController.py

@@ -23,7 +23,8 @@ from django.views.decorators.csrf import csrf_exempt
 from django.views.generic.base import View
 from django.views.generic.base import View
 
 
 from Model.models import UidSetModel, Device_User, Device_Info, UidPushModel, Equipment_Info, UID_Preview, UID_Bucket, \
 from Model.models import UidSetModel, Device_User, Device_Info, UidPushModel, Equipment_Info, UID_Preview, UID_Bucket, \
-    VodHlsModel, Order_Model, OssCrdModel, UidUserModel, UidChannelSetModel, User_Brand
+    VodHlsModel, Order_Model, OssCrdModel, UidUserModel, UidChannelSetModel, User_Brand, ExperienceContextModel, \
+    StsCrdModel, Unused_Uid_Meal, UIDMainUser
 from Object.ResponseObject import ResponseObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Object.TokenObject import TokenObject
 from Service.CommonService import CommonService
 from Service.CommonService import CommonService
@@ -87,6 +88,10 @@ class UidSetView(View):
             return self.do_update_set(request, request_dict, response)
             return self.do_update_set(request, request_dict, response)
         elif operation == 'updateChannel':
         elif operation == 'updateChannel':
             return self.do_update_channel_set(request_dict, response)
             return self.do_update_channel_set(request_dict, response)
+        elif operation == 'setVoicePrompt':
+            return self.do_set_voice(userID, request_dict, response)
+        elif operation == 'vod_reset':
+            return self.vod_reset(request_dict, response)
         # elif operation == 'test':
         # elif operation == 'test':
         #     return self.do_test(response)
         #     return self.do_test(response)
         else:
         else:
@@ -410,6 +415,99 @@ class UidSetView(View):
         else:
         else:
             return response.json(0)
             return response.json(0)
 
 
+    def do_set_voice(self, userID, request_dict, response):
+        uid = request_dict.get('uid', None)
+        channel = request_dict.get('channel', None)
+        enter_voice = request_dict.get('enter_voice', None)
+        leave_voice = request_dict.get('leave_voice', None)
+        voice_status = request_dict.get('voice_status', None)
+        intelligent_mute = request_dict.get('intelligent_mute', None)
+        start_x = request_dict.get('start_x', None)
+        start_y = request_dict.get('start_y', None)
+        end_x = request_dict.get('end_x', None)
+        end_y = request_dict.get('end_y', None)
+        start_time = request_dict.get('start_time', None)
+        end_time = request_dict.get('end_time', None)
+        repeat_day = request_dict.get('repeat_day', None)
+        direction = request_dict.get('direction', None)
+
+        if uid and channel:
+            channel = int(channel)
+            if channel < 1:
+                return response.json(444, 'channel')
+            try:
+                ucs = {}
+                if enter_voice:
+                    ucs['voice_prompt_enter'] = enter_voice
+
+                if leave_voice:
+                    ucs['voice_prompt_leave'] = leave_voice
+
+                if voice_status:
+                    ucs['voice_prompt_status'] = voice_status
+
+                if intelligent_mute:
+                    ucs['voice_prompt_intelligent_mute'] = intelligent_mute
+
+                if start_x:
+                    ucs['voice_start_x'] = start_x
+
+                if start_y:
+                    ucs['voice_start_y'] = start_y
+
+                if end_x:
+                    ucs['voice_end_x'] = end_x
+
+                if end_y:
+                    ucs['voice_end_y'] = end_y
+
+                if start_time:
+                    ucs['voice_start_time'] = start_time
+
+                if end_time:
+                    ucs['voice_end_time'] = end_time
+
+                if repeat_day:
+                    ucs['voice_repeat_day'] = repeat_day
+
+                if direction:
+                    ucs['voice_direction'] = direction
+
+                uid_channel_set_qs = UidChannelSetModel.objects.filter(uid__uid=uid, channel=channel)
+                if not uid_channel_set_qs.exists():
+                    uidObject = UidSetModel.objects.filter(uid=uid)
+                    ucs['channel'] = channel
+                    ucs['uid'] = uidObject[0]
+                    UidChannelSetModel.objects.create(**ucs)
+                else:
+                    uid_channel_set_qs.update(**ucs)
+
+            except Exception as e:
+                return response.json(177, repr(e))
+            else:
+                return response.json(0)
+
+    # 重置设备云存
+    def vod_reset(self, request_dict, response):
+        uid = request_dict.get('uid', None)
+        if uid:
+            try:
+                with transaction.atomic():
+                    # 删除和更新设备云存相关数据
+                    UID_Bucket.objects.filter(uid=uid).delete()
+                    Unused_Uid_Meal.objects.filter(uid=uid).delete()
+                    Order_Model.objects.filter(UID=uid).delete()
+                    StsCrdModel.objects.filter(uid=uid).delete()
+                    VodHlsModel.objects.filter(uid=uid).delete()
+                    ExperienceContextModel.objects.filter(uid=uid).delete()
+                    # UIDMainUser.objects.filter(UID=uid).delete()
+                    Device_Info.objects.filter(UID=uid).update(vodPrimaryUserID='', vodPrimaryMaster='')
+            except Exception as e:
+                print(e)
+                return response.json(500, repr(e))
+            else:
+                return response.json(0)
+
     # def do_test(self, response):
     # def do_test(self, response):
     #     di_qs = Device_Info.objects.values('Type').annotate(c=Count('UID', distinct=True)).order_by()
     #     di_qs = Device_Info.objects.values('Type').annotate(c=Count('UID', distinct=True)).order_by()
     #     for di in di_qs:
     #     for di in di_qs:

+ 164 - 85
Controller/UserController.py

@@ -14,7 +14,7 @@
 import datetime
 import datetime
 import traceback
 import traceback
 import time
 import time
-
+import logging
 import jwt
 import jwt
 import simplejson
 import simplejson
 import simplejson as json
 import simplejson as json
@@ -32,7 +32,7 @@ from ratelimit.decorators import ratelimit
 from Ansjer.config import AuthCode_Expire, SERVER_DOMAIN, APNS_CONFIG, JPUSH_CONFIG, FCM_CONFIG, TUTK_PUSH_DOMAIN
 from Ansjer.config import AuthCode_Expire, SERVER_DOMAIN, APNS_CONFIG, JPUSH_CONFIG, FCM_CONFIG, TUTK_PUSH_DOMAIN
 from Controller.CheckUserData import DataValid, date_handler, RandomStr
 from Controller.CheckUserData import DataValid, date_handler, RandomStr
 from Model.models import Device_User, Role, UidPushModel, UserOauth2Model, UserExModel, Device_Info, UidSetModel, \
 from Model.models import Device_User, Role, UidPushModel, UserOauth2Model, UserExModel, Device_Info, UidSetModel, \
-    UserAppFrequencyModel, CountryIPModel
+    UserAppFrequencyModel, CountryIPModel, CountryModel
 from Object.AWS.SesClassObject import SesClassObject
 from Object.AWS.SesClassObject import SesClassObject
 from Object.AliSmsObject import AliSmsObject
 from Object.AliSmsObject import AliSmsObject
 from Object.RedisObject import RedisObject
 from Object.RedisObject import RedisObject
@@ -49,7 +49,6 @@ from PIL import Image, ImageDraw, ImageFont
 from django.shortcuts import HttpResponse
 from django.shortcuts import HttpResponse
 from Ansjer.config import BASE_DIR
 from Ansjer.config import BASE_DIR
 
 
-
 # 获取验证码
 # 获取验证码
 class authCodeView(TemplateView):
 class authCodeView(TemplateView):
 
 
@@ -173,6 +172,9 @@ class registerView(TemplateView):
         password = request_dict.get('userPwd', None)
         password = request_dict.get('userPwd', None)
         authCode = request_dict.get('identifyingCode', None)
         authCode = request_dict.get('identifyingCode', None)
         language = request_dict.get('language', None)
         language = request_dict.get('language', None)
+        unique = request_dict.get('unique', None)
+        if unique:
+            delete_local_account(unique)
         response = ResponseObject(language)
         response = ResponseObject(language)
         if username and password and authCode:
         if username and password and authCode:
             # 过滤空格
             # 过滤空格
@@ -286,7 +288,6 @@ class registerView(TemplateView):
         else:
         else:
             return response.json(109)
             return response.json(109)
 
 
-
 # 登出
 # 登出
 class LogoutView(TemplateView):
 class LogoutView(TemplateView):
     @method_decorator(csrf_exempt)
     @method_decorator(csrf_exempt)
@@ -858,6 +859,10 @@ class v2registerView(TemplateView):
         password = request_dict.get('password', None)
         password = request_dict.get('password', None)
         authcode = request_dict.get('authcode', None)
         authcode = request_dict.get('authcode', None)
         lang = request_dict.get('lang', None)
         lang = request_dict.get('lang', None)
+        unique = request_dict.get('unique', None)
+        number = request_dict.get('number', None)
+        if unique:
+            delete_local_account(unique)
         response = ResponseObject(lang)
         response = ResponseObject(lang)
         if not lang:
         if not lang:
             lang = request_dict.get('language', None)
             lang = request_dict.get('language', None)
@@ -866,13 +871,13 @@ class v2registerView(TemplateView):
         if authcode is None:
         if authcode is None:
             return response.json(444, 'identifyingCode')
             return response.json(444, 'identifyingCode')
         if phone is not None:
         if phone is not None:
-            return self.do_phone_register(phone, password, authcode, response)
+            return self.do_phone_register(phone, password, authcode, number, response)
         elif email is not None:
         elif email is not None:
-            return self.do_email_register(email, password, authcode, response)
+            return self.do_email_register(email, password, authcode, number, response)
         else:
         else:
             return response.json(444, 'phone or email')
             return response.json(444, 'phone or email')
 
 
-    def do_phone_register(self, phone, password, authcode, response):
+    def do_phone_register(self, phone, password, authcode, number, response):
         data_valid = DataValid()
         data_valid = DataValid()
         if data_valid.mobile_validate(phone) is not True:
         if data_valid.mobile_validate(phone) is not True:
             return response.json(100)
             return response.json(100)
@@ -891,15 +896,19 @@ class v2registerView(TemplateView):
         if phone_qs.exists():
         if phone_qs.exists():
             return response.json(101)
             return response.json(101)
         try:
         try:
-            users = Device_User.objects.create(
-                username=phone,
-                NickName=phone,
-                phone=phone,
-                password=make_password(password),
-                userID=CommonService.getUserID(μs=False, setOTAID=True),
-                is_active=True,
-                user_isValid=True,
-            )
+            create_data = {
+                "username": phone,
+                "NickName": phone,
+                "phone": phone,
+                "password": make_password(password),
+                "userID": CommonService.getUserID(μs=False, setOTAID=True),
+                "is_active": True,
+                "user_isValid": True,
+            }
+            if number:
+                create_data["region_country"] = number
+
+            users = Device_User.objects.create(**create_data)
         except Exception as e:
         except Exception as e:
             errorInfo = traceback.format_exc()
             errorInfo = traceback.format_exc()
             print(errorInfo)
             print(errorInfo)
@@ -938,7 +947,7 @@ class v2registerView(TemplateView):
         print(res)
         print(res)
         return response.json(0, res)
         return response.json(0, res)
 
 
-    def do_email_register(self, email, password, authcode, response):
+    def do_email_register(self, email, password, authcode, number, response):
         data_valid = DataValid()
         data_valid = DataValid()
         if data_valid.email_validate(email) is not True:
         if data_valid.email_validate(email) is not True:
             return response.json(105)
             return response.json(105)
@@ -957,15 +966,18 @@ class v2registerView(TemplateView):
         if email_qs.exists():
         if email_qs.exists():
             return response.json(103)
             return response.json(103)
         try:
         try:
-            users = Device_User.objects.create(
-                username=email,
-                NickName=email,
-                userEmail=email,
-                password=make_password(password),
-                userID=CommonService.getUserID(μs=False, setOTAID=True),
-                is_active=True,
-                user_isValid=True,
-            )
+            create_data = {
+                "username": email,
+                "NickName": email,
+                "userEmail": email,
+                "password": make_password(password),
+                "userID": CommonService.getUserID(μs=False, setOTAID=True),
+                "is_active": True,
+                "user_isValid": True,
+            }
+            if number:
+                create_data["region_country"] = number
+            users = Device_User.objects.create(**create_data)
         except Exception as e:
         except Exception as e:
             errorInfo = traceback.format_exc()
             errorInfo = traceback.format_exc()
             print(errorInfo)
             print(errorInfo)
@@ -999,6 +1011,8 @@ class v3registerView(TemplateView):
         authcode = request_dict.get('authcode', None)
         authcode = request_dict.get('authcode', None)
         lang = request_dict.get('lang', None)
         lang = request_dict.get('lang', None)
         unique = request_dict.get('unique', None)
         unique = request_dict.get('unique', None)
+        number = request_dict.get('number', None)
+
         if unique:
         if unique:
             delete_local_account(unique)
             delete_local_account(unique)
         response = ResponseObject(lang)
         response = ResponseObject(lang)
@@ -1045,13 +1059,13 @@ class v3registerView(TemplateView):
             if authcode is None:
             if authcode is None:
                 return response.json(444, 'identifyingCode')
                 return response.json(444, 'identifyingCode')
             if phone is not None:
             if phone is not None:
-                return self.do_phone_register(phone, password, authcode, response)
+                return self.do_phone_register(phone, password, authcode, number, response)
             elif email is not None:
             elif email is not None:
-                return self.do_email_register(email, password, authcode, response)
+                return self.do_email_register(email, password, authcode, number, response)
             else:
             else:
                 return response.json(444, 'phone or email')
                 return response.json(444, 'phone or email')
 
 
-    def do_phone_register(self, phone, password, authcode, response):
+    def do_phone_register(self, phone, password, authcode, number, response):
         data_valid = DataValid()
         data_valid = DataValid()
         if data_valid.mobile_validate(phone) is not True:
         if data_valid.mobile_validate(phone) is not True:
             return response.json(100)
             return response.json(100)
@@ -1070,15 +1084,20 @@ class v3registerView(TemplateView):
         if phone_qs.exists():
         if phone_qs.exists():
             return response.json(101)
             return response.json(101)
         try:
         try:
-            users = Device_User.objects.create(
-                username=phone,
-                NickName=phone,
-                phone=phone,
-                password=make_password(password),
-                userID=CommonService.getUserID(μs=False, setOTAID=True),
-                is_active=True,
-                user_isValid=True,
-            )
+            create_data = {
+                "username": phone,
+                "NickName": phone,
+                "phone": phone,
+                "password": make_password(password),
+                "userID": CommonService.getUserID(μs=False, setOTAID=True),
+                "is_active": True,
+                "user_isValid": True,
+            }
+            if number:
+                create_data["region_country"] = number
+
+            users = Device_User.objects.create(**create_data)
+
         except Exception as e:
         except Exception as e:
             errorInfo = traceback.format_exc()
             errorInfo = traceback.format_exc()
             print(errorInfo)
             print(errorInfo)
@@ -1116,7 +1135,7 @@ class v3registerView(TemplateView):
         res['phone'] = user_list[0]["phone"] if user_list[0]["phone"] is not None else ''
         res['phone'] = user_list[0]["phone"] if user_list[0]["phone"] is not None else ''
         return response.json(0, res)
         return response.json(0, res)
 
 
-    def do_email_register(self, email, password, authcode, response):
+    def do_email_register(self, email, password, authcode, number, response):
         data_valid = DataValid()
         data_valid = DataValid()
         if data_valid.email_validate(email) is not True:
         if data_valid.email_validate(email) is not True:
             return response.json(105)
             return response.json(105)
@@ -1130,20 +1149,25 @@ class v3registerView(TemplateView):
         # 验证码是否正确
         # 验证码是否正确
         if authcode != identifyingCode:
         if authcode != identifyingCode:
             return response.json(121)
             return response.json(121)
+
         email_qs = Device_User.objects.filter(Q(userEmail=email) | Q(username=email))
         email_qs = Device_User.objects.filter(Q(userEmail=email) | Q(username=email))
         # 是否已存在
         # 是否已存在
         if email_qs.exists():
         if email_qs.exists():
             return response.json(103)
             return response.json(103)
         try:
         try:
-            users = Device_User.objects.create(
-                username=email,
-                NickName=email,
-                userEmail=email,
-                password=make_password(password),
-                userID=CommonService.getUserID(μs=False, setOTAID=True),
-                is_active=True,
-                user_isValid=True,
-            )
+            create_data = {
+                "username": email,
+                "NickName": email,
+                "userEmail": email,
+                "password": make_password(password),
+                "userID": CommonService.getUserID(μs=False, setOTAID=True),
+                "is_active": True,
+                "user_isValid": True,
+            }
+            if number:
+                create_data["region_country"] = number
+            users = Device_User.objects.create(**create_data)
+
         except Exception as e:
         except Exception as e:
             errorInfo = traceback.format_exc()
             errorInfo = traceback.format_exc()
             print(errorInfo)
             print(errorInfo)
@@ -1765,8 +1789,7 @@ class v3LoginView(TemplateView):
             user_qs.update(subscribe_email=subscribe)
             user_qs.update(subscribe_email=subscribe)
 
 
         users = user_qs.values('role__rid', 'role__roleName', 'userID', 'NickName', 'username', 'userEmail',
         users = user_qs.values('role__rid', 'role__roleName', 'userID', 'NickName', 'username', 'userEmail',
-                               'phone', 'password', 'userIconPath', 'fingerprint_enable', 'fingerprint_key',
-                               'subscribe_email')[0]
+                               'phone', 'password', 'userIconPath', 'fingerprint_enable', 'fingerprint_key', 'subscribe_email')[0]
         if not check_password(password, users['password']):
         if not check_password(password, users['password']):
             return response.json(111)
             return response.json(111)
         userID = users['userID']
         userID = users['userID']
@@ -1778,6 +1801,7 @@ class v3LoginView(TemplateView):
         if oauth_qs.exists():
         if oauth_qs.exists():
             auth_type = oauth_qs[0].authType
             auth_type = oauth_qs[0].authType
 
 
+
         if tko.code == 0:
         if tko.code == 0:
             now_time = datetime.datetime.utcnow().replace(tzinfo=utc).astimezone(utc)
             now_time = datetime.datetime.utcnow().replace(tzinfo=utc).astimezone(utc)
             user_qs.update(last_login=now_time, language=response.lang)
             user_qs.update(last_login=now_time, language=response.lang)
@@ -1829,8 +1853,7 @@ class InitInfoView(View):
         else:
         else:
             return response.json(tko.code)
             return response.json(tko.code)
 
 
-        # 初始化设备token
-
+    # 初始化设备token
     def init_info(self, request_dict, userID, response, request):
     def init_info(self, request_dict, userID, response, request):
         # 未读的系统消息
         # 未读的系统消息
         token_val = request_dict.get('token_val', None)
         token_val = request_dict.get('token_val', None)
@@ -2706,39 +2729,41 @@ class alexaUidView(TemplateView):
             return response.json(107)
             return response.json(107)
 
 
     def validates(self, request_dict, response):
     def validates(self, request_dict, response):
-        userID = request_dict.get('alexa_user_id')
         sid = request_dict.get('sid')
         sid = request_dict.get('sid')
         sst = request_dict.get('sst')
         sst = request_dict.get('sst')
+        userID = request_dict.get('alexa_user_id')
 
 
-        if sid == 'admin' and sst == 'admin':
-            uid_qs = Device_Info.objects.filter(userID_id=userID, isExist=1).values('UID', 'NickName', 'View_Password')
-            uid_dict = {}
-            uid_list = []
-            for uid_q in uid_qs:
-                # 追加
-                uid_list.append(uid_q['UID'])
-                # 给uid_q['UID']赋值
-                uid_dict[uid_q['UID']] = {'nick': uid_q['NickName'], 'password': uid_q['View_Password']}
-            us_qs = UidSetModel.objects.filter(uid__in=uid_list, is_alexa=1).values('uid', 'region_alexa')
-
-            # uid,password,region的列表
-            uid_arr = []
-            for us in us_qs:
-                uid = us['uid']
-                # 设备alexa区域
-                region_alexa = us['region_alexa']
-                if region_alexa == '':
-                    region_alexa = "en"
-                # uid_arr.append({'uid': uid, 'nick': uid_dict[uid]['nick'], 'password': uid_dict['uid']['password']})
-                uid_arr.append({'uid': uid, 'nick': uid_dict[uid]['nick'], 'password': uid_dict[uid]['password'],
-                                'region': region_alexa})
-            res = {
-                'uid_arr': uid_arr
-
-            }
-            return response.json(0, res)
-        else:
+        if sid != 'admin' or sst != 'admin':
             return response.json(107)
             return response.json(107)
+        uid_qs = Device_Info.objects.filter(userID_id=userID, isExist=1).values('UID', 'NickName', 'View_Password')
+        if not uid_qs.exists():
+            return response.json(107)
+
+        uid_dict = {}
+        uid_list = []
+        for uid_q in uid_qs:
+            # 追加
+            uid_list.append(uid_q['UID'])
+            # 给uid_q['UID']赋值
+            uid_dict[uid_q['UID']] = {'nick': uid_q['NickName'], 'password': uid_q['View_Password']}
+
+        us_qs = UidSetModel.objects.filter(uid__in=uid_list, is_alexa=1).values('uid', 'region_alexa')
+        if not us_qs.exists():
+            return response.json(173)
+        # uid,password,region的列表
+        uid_arr = []
+        for us in us_qs:
+            uid = us['uid']
+            # 设备alexa区域
+            region_alexa = us['region_alexa']
+            if region_alexa == '':
+                region_alexa = 'EN'
+            uid_arr.append({'uid': uid, 'nick': uid_dict[uid]['nick'], 'password': uid_dict[uid]['password'],
+                            'region': region_alexa})
+        res = {
+            'uid_arr': uid_arr
+        }
+        return response.json(0, res)
 
 
 
 
 # 登出
 # 登出
@@ -2824,12 +2849,12 @@ class generatePictureCodeView(TemplateView):
         kumo_font = ImageFont.truetype(path, 40, encoding="unic")  # 设置字体
         kumo_font = ImageFont.truetype(path, 40, encoding="unic")  # 设置字体
         print("字体可以")
         print("字体可以")
         valid_code_str = ''
         valid_code_str = ''
-        for i in range(5):
+        for i in range(6):
             random_num = str(random.randint(0, 9))
             random_num = str(random.randint(0, 9))
             random_low_alpha = chr(random.randint(97, 122))
             random_low_alpha = chr(random.randint(97, 122))
             random_high_alpha = chr(random.randint(65, 90))
             random_high_alpha = chr(random.randint(65, 90))
             random_char = random.choice([random_num, random_low_alpha, random_high_alpha])
             random_char = random.choice([random_num, random_low_alpha, random_high_alpha])
-            draw.text((i * 50 + 20, -3), random_char, 'white', kumo_font)
+            draw.text((i * 40 + 20, -3), random_char, 'white', kumo_font)
 
 
             # 保存验证码字符串
             # 保存验证码字符串
             valid_code_str += random_char
             valid_code_str += random_char
@@ -2914,6 +2939,7 @@ class Image_Code_RegisterView(TemplateView):
         response = ResponseObject(lang)
         response = ResponseObject(lang)
         valid_code = request_dict.get('id_v_code', None)
         valid_code = request_dict.get('id_v_code', None)
         unique = request_dict.get('unique', None)
         unique = request_dict.get('unique', None)
+        number = request_dict.get('number', None)
         if unique:
         if unique:
             delete_local_account(unique)
             delete_local_account(unique)
         if not all([userEmail, password, lang, imageCodeId, valid_code]):
         if not all([userEmail, password, lang, imageCodeId, valid_code]):
@@ -2990,6 +3016,8 @@ class Image_Code_RegisterView(TemplateView):
             "is_active": True,
             "is_active": True,
             "user_isValid": True,
             "user_isValid": True,
         }
         }
+        if number:
+            create_data["region_country"] = number
         users = Device_User.objects.create(**create_data)
         users = Device_User.objects.create(**create_data)
         return self.do_login(email_qs, response)
         return self.do_login(email_qs, response)
 
 
@@ -3244,6 +3272,7 @@ class v3LoginByCodeView(View):
         if oauth_qs.exists():
         if oauth_qs.exists():
             auth_type = oauth_qs[0].authType
             auth_type = oauth_qs[0].authType
 
 
+
         if tko.code == 0:
         if tko.code == 0:
             now_time = datetime.datetime.utcnow().replace(tzinfo=utc).astimezone(utc)
             now_time = datetime.datetime.utcnow().replace(tzinfo=utc).astimezone(utc)
             user_qs.update(last_login=now_time, language=response.lang)
             user_qs.update(last_login=now_time, language=response.lang)
@@ -3412,12 +3441,13 @@ class AppleAuthLogin(View):
 
 
         response = ResponseObject(lang)
         response = ResponseObject(lang)
         identity_token = CommonService.decode_data(identity_token)
         identity_token = CommonService.decode_data(identity_token)
+        # print(identity_token)
         if identity_token:
         if identity_token:
             key_url = 'https://appleid.apple.com/auth/keys'
             key_url = 'https://appleid.apple.com/auth/keys'
             key_response = requests.get(key_url).json()
             key_response = requests.get(key_url).json()
-            print(key_response)
+            # print(key_response)
             head = jwt.get_unverified_header(identity_token)
             head = jwt.get_unverified_header(identity_token)
-            print(head)
+            # print(head)
             token_key = head['kid']
             token_key = head['kid']
             key_object = None
             key_object = None
             alg = None
             alg = None
@@ -3491,6 +3521,7 @@ class AppleAuthLogin(View):
         if oauth_qs.exists():
         if oauth_qs.exists():
             auth_type = oauth_qs[0].authType
             auth_type = oauth_qs[0].authType
         res['authType'] = auth_type
         res['authType'] = auth_type
+
         user_qs.update(last_login=now_time, online=True)
         user_qs.update(last_login=now_time, online=True)
         return response.json(0, res)
         return response.json(0, res)
 
 
@@ -3695,3 +3726,51 @@ def updateUserCountry(request):
         # CountryIPModel.objects.filter(id__in=tuple(ids)).update(status=1)
         # CountryIPModel.objects.filter(id__in=tuple(ids)).update(status=1)
     response = ResponseObject()
     response = ResponseObject()
     return response.json(0)
     return response.json(0)
+
+
+class InitUserInformationView(View):
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation', None)
+        request_dict = request.GET
+        return self.validate(request_dict, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation', None)
+        request_dict = request.POST
+        return self.validate(request_dict, operation)
+
+    def validate(self, request_dict, operation):
+        token = TokenObject(request_dict.get('token', None))
+
+        response = ResponseObject()
+
+        if token.code != 0:
+            return response.json(token.code)
+
+        if operation == 'init':
+            return self.do_init(token.userID, request_dict, response)
+        else:
+            return response.json(444)
+
+    def do_init(self, userID, request_dict, response):
+        appBundleId = request_dict.get('appBundleId', None)
+
+        if appBundleId:
+            user_ex_qs = UserExModel.objects.filter(userID_id=userID)
+            now_time = int(time.time())
+            if user_ex_qs.exists():
+                update = {
+                    'appBundleId':appBundleId,
+                    'updTime': now_time
+                }
+                user_ex_qs.update(**update)
+            else:
+
+                user_ex = UserExModel(userID_id=userID, appBundleId=appBundleId, addTime=now_time, updTime=now_time)
+                user_ex.save()
+            return response.json(0)
+        else:
+            return response.json(444)

+ 270 - 0
Controller/VPGController.py

@@ -0,0 +1,270 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+import os
+import re
+import time
+
+from django.db import transaction
+from django.views import View
+from django.views.decorators.csrf import csrf_exempt
+
+from Ansjer.config import BASE_DIR
+from Model.models import RegionModel, CompanyModel, VPGModel, UIDModel, MacModel, UIDCompanySerialModel
+from Object.uidManageResponseObject import uidManageResponseObject
+from Object.TokenObject import TokenObject
+from Service.CommonService import CommonService
+from Service.ModelService import ModelService
+
+
+class VPGView(View):
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation', None)
+        request_dict = request.GET
+        return self.validate(request_dict, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation', None)
+        request_dict = request.POST
+        return self.validate(request_dict, operation)
+
+    def validate(self, request_dict, operation):
+        token = TokenObject(request_dict.get('token', None))
+        response = uidManageResponseObject()
+
+        if token.code != 0:
+            return response.json(token.code)
+
+        if operation == 'add':
+            return self.do_add(token.userID, request_dict, response)
+        elif operation == 'update':
+            return self.do_update(token.userID, request_dict, response)
+        elif operation == 'delete':
+            return self.do_delete(token.userID, request_dict, response)
+        elif operation == 'list':
+            return self.do_list(token.userID, request_dict, response)
+        elif operation == 'uid_list':
+            return self.do_uid_list(token.userID, request_dict, response)
+        else:
+            return response.json(404)
+
+    def do_add(self, userID, request_dict, response):
+        # perm = ModelService.check_perm_uid_manage(userID, 0)
+        # if not perm:
+        #     return response.json(309)
+
+        name = request_dict.get('vpg', None)
+        region_id = request_dict.get('region_id', None)
+        company_id = request_dict.get('company_id', None)
+
+        if name and region_id and company_id:
+            region_qs = RegionModel.objects.filter(id=region_id)
+            if not region_qs.exists():
+                return response.json(374)
+
+            company_qs = CompanyModel.objects.filter(secret=company_id)
+            if not company_qs.exists():
+                return response.json(373)
+
+            company = company_qs[0]
+            now_time = int(time.time())
+            vpgModel = VPGModel(name=name, region_id=region_id, company_id=company.id, add_time=now_time, update_time=now_time)
+            vpgModel.save()
+            return response.json(0)
+        else:
+            return response.json(444)
+
+    def do_update(self, userID, request_dict, response):
+        # perm = ModelService.check_perm_uid_manage(userID, 0)
+        # if not perm:
+        #     return response.json(309)
+
+        id = request_dict.get('id', None)
+        name = request_dict.get('vpg', None)
+        region_id = request_dict.get('region_id', None)
+        company_id = request_dict.get('company_id', None)
+
+        if id:
+            vpg_qs = VPGModel.objects.filter(id=id)
+
+            if vpg_qs.exists():
+
+                now_time = int(time.time())
+                update = {
+                    'update_time': now_time
+                }
+
+                if name:
+                    update['name'] = name
+
+                if region_id:
+                    update['region_id'] = region_id
+
+                if company_id:
+                    update['company_id'] = company_id
+
+                vpg_qs.update(**update)
+                return response.json(0)
+            else:
+                return response.json(173)
+        else:
+            return response.json(444)
+
+    def do_delete(self, userID, request_dict, response):
+        # perm = ModelService.check_perm_uid_manage(userID, 0)
+        # if not perm:
+        #     return response.json(309)
+
+        id = request_dict.get('id', None)
+        if id:
+            vpg_qs = VPGModel.objects.filter(id=id)
+
+            if vpg_qs.exists():
+                vpg_qs.delete()
+                return response.json(0)
+            else:
+                return response.json(173)
+        else:
+            return response.json(444)
+
+    def do_list(self, userID, request_dict, response):
+        # perm = ModelService.check_perm_uid_manage(userID, 0)
+        # if not perm:
+        #     return response.json(309)
+
+        company_id = request_dict.get('company_id', None)
+        region_id = request_dict.get('region_id', None)
+        page = request_dict.get('page', None)
+        line = request_dict.get('limit', None)
+
+        if page and line:
+            page = int(page)
+            line = int(line)
+
+            start = (page - 1) * line
+            end = start + line
+
+            vpg_qs = VPGModel.objects.filter()
+
+            if company_id:
+                vpg_qs.filter(company_id=company_id)
+
+            if region_id:
+                vpg_qs.filter(region_id=region_id)
+
+            count = vpg_qs.count()
+            vpg_qs = vpg_qs.values('id', 'name', 'region__name', 'region_id', 'company__name', 'add_time',
+                                   'update_time', 'company__secret', 'uid_count')
+            vpg_qs = vpg_qs[start:end]
+            # for vpg in vpg_qs:
+            #     vpg['uid_count'] = UIDModel.objects.filter(vpg_id=vpg['id']).count()
+
+            res = {
+                'count': count,
+                'data': list(vpg_qs),
+            }
+
+            return response.json(0, res)
+        else:
+            return response.json(444)
+
+
+    def do_uid_list(self, userID, request_dict, response):
+        vpg_id = request_dict.get('vpg_id', None)
+        page = int(request_dict.get('page', None))
+        line = int(request_dict.get('limit', None))
+
+        if not vpg_id:
+            return response.json(444)
+
+        start = (page - 1) * line
+        end = start + line
+        uid_qs = UIDModel.objects.filter(vpg_id=vpg_id).values('uid')
+
+        count = VPGModel.objects.get(id=vpg_id).uid_count   # 从vpg表获取uid总数
+        uid_qs = uid_qs[start:end]  # 显示条数
+        res = {
+            'count': count,
+            'data': list(uid_qs),
+        }
+        return response.json(0, res)
+
+
+@csrf_exempt
+def do_upload_uid(request):
+    # 上传UID,需要request.FILES,单独提取出来
+    # perm = ModelService.check_perm_uid_manage(userID, 0)
+    # if not perm:
+    #     return response.json(309)
+
+    request.encoding = 'utf-8'
+    response = uidManageResponseObject()
+    if request.method == "POST":
+        request_dict = request.POST
+    elif request.method == "GET":
+        request_dict = request.GET
+    else:
+        return response.json(444)
+    file = request.FILES.get('file', None)
+    vpg_id = request_dict.get('vpg_id', None)
+
+    bulk = []
+    add_time = update_time = int(time.time())
+    MAC = MacModel.objects.filter().values('id', 'value', 'is_active')[0]   # 获取最新可用的mac
+    current_mac = MAC['value']
+    if (not MAC['is_active']) or (current_mac[-8:] == 'FF.FF.FF'):
+        return response.json(175)
+
+    # path = '/'.join((BASE_DIR, 'static/uid')).replace('\\', '/') + '/'
+    # if not os.path.exists(path):
+    #     os.makedirs(path)
+    # full_path = path + str(file)
+    # with open(full_path, 'wb+') as uid_file:
+    try:
+        for chunk in file.chunks():
+            # str_chunk = str(chunk)
+            # print('str(chunk):', str_chunk)
+            # str_chunk = re.findall("b\'(.*)\'", str_chunk)[0]
+            # str_chunk = str_chunk.split('\\r\\n')
+            # print('str(chunk):', str_chunk)
+            uid_list = re.findall("b\'(.*)\'", str(chunk))[0].split('\\r\\n')
+            for uid in uid_list:
+                UID = UIDModel(
+                    mac=current_mac,
+                    uid_extra='',
+                    status=0,
+                    add_time=add_time,
+                    update_time=update_time,
+                    area=0,  # 关联vgp表已有区域信息,可以考虑去掉
+                    vpg_id=vpg_id,
+                )
+                if len(uid) == 14:  # 宸云
+                    UID.p2p_type = 1
+                    UID.uid = uid
+                elif len(uid) == 20:    # tutk
+                    UID.p2p_type = 2
+                    UID.uid = uid
+                elif len(uid) == 23:    # 宸云完整uid
+                    a = uid.split('-')
+                    new_uid = a[0] + a[1] + a[2].split(',')[0]
+                    UID.p2p_type = 1
+                    UID.uid = new_uid
+                    UID.full_uid_code = uid
+                bulk.append(UID)
+                temp_mac = CommonService.updateMac(current_mac)    # mac地址值+1;后3个字节为FF时返回None
+                if temp_mac:
+                    current_mac = temp_mac  # 更新赋值写入uid表
+                else:
+                    temp_mac = current_mac  # 赋值为FF写入mac表
+                    break
+        with transaction.atomic():
+            UIDModel.objects.bulk_create(bulk)  # 批量写入uid数据
+            uid_count = UIDModel.objects.filter(vpg_id=vpg_id).count()  # 获取族群下uid的数量
+            VPGModel.objects.filter(id=vpg_id).update(uid_count=uid_count)   # 更新vgp表的uid_count
+            MacModel.objects.filter().update(value=temp_mac)  # 更新mac表的mac地址值
+        return response.json(0)
+    except Exception as e:
+        print(e)
+        return response.json(500, repr(e))

+ 121 - 0
Controller/VerifyCodeController.py

@@ -0,0 +1,121 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+from django.views import View
+
+from Controller.CheckUserData import DataValid
+from Object.RedisObject import RedisObject
+from Object.ResponseObject import ResponseObject
+from Object.TokenObject import TokenObject
+from Service.CommonService import CommonService
+
+
+class VerifyCodeView(View):
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation', None)
+        request_dict = request.GET
+        return self.validate(request_dict, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation', None)
+        request_dict = request.POST
+        return self.validate(request_dict, operation)
+
+    def validate(self, request_dict, operation):
+
+        response = ResponseObject()
+
+        if operation == 'forget':
+            return self.verify_forget(request_dict, response)
+        elif operation == 'register':
+            return self.verify_register(request_dict, response)
+        elif operation == 'image':
+            return self.verify_image(request_dict, response)
+        else:
+            return response.json(404)
+
+    def verify_forget(self, request_dict, response):
+        email = request_dict.get('email', None)
+        phone = request_dict.get('phone', None)
+        authcode = request_dict.get('authcode', None)
+        key = '_forgetPwdResetCode'
+
+        if authcode is None:
+            return response.json(444)
+
+        authcode = CommonService.decode_data(authcode)
+
+        if email is not None:
+            email = email.strip()
+            return self.email_validate(key, email, authcode, response)
+        elif phone is not None:
+            phone = phone.strip()
+            return self.phone_validate(key, phone, authcode, response)
+        else:
+            return response.json(444)
+
+    def verify_register(self, request_dict, response):
+        email = request_dict.get('email', None)
+        phone = request_dict.get('phone', None)
+        authcode = request_dict.get('authcode', None)
+        key = '_identifyingCode'
+        if authcode is None:
+            return response.json(444)
+
+        authcode = CommonService.decode_data(authcode)
+
+        if email is not None:
+            email = email.strip()
+            return self.email_validate(key, email, authcode, response)
+        elif phone is not None:
+            phone = phone.strip()
+            return self.phone_validate(key, phone, authcode, response)
+        else:
+            return response.json(444)
+
+    def verify_image(self, request_dict, response):
+        imageCodeId = request_dict.get('imageCodeId', None)
+        authcode = request_dict.get('authcode', None)
+
+        if imageCodeId and authcode:
+
+            authcode = CommonService.decode_data(authcode)
+            image_code_key = 'image_code_' + imageCodeId
+            redisObj = RedisObject(db=6)
+            # redis里面的验证码
+            redis_image_code = redisObj.get_data(key=image_code_key)
+            # 验证用户输入的验证码和redis中的验证码
+            if redis_image_code is False or authcode.lower() != redis_image_code.lower():
+                return response.json(121)
+            else:
+                return response.json(0)
+        else:
+            return response.json(444)
+
+    def email_validate(self, key, email, authcode, response):
+        authcode.strip()
+        data_valid = DataValid()
+        if data_valid.email_validate(email) is not True:
+            return response.json(105)
+        reds = RedisObject()
+        resetCode = reds.get_data(key=email + key)
+        if resetCode is False:
+            return response.json(120)
+        if authcode != resetCode:
+            return response.json(121)
+        return response.json(0)
+
+    def phone_validate(self, key, phone, authcode, response):
+        authcode.strip()
+        data_valid = DataValid()
+        if data_valid.mobile_validate(phone) is not True:
+            return response.json(100)
+        reds = RedisObject()
+        resetCode = reds.get_data(key=phone + key)
+        if resetCode is False:
+            return response.json(120)
+        print(resetCode)
+        if authcode != resetCode:
+            return response.json(121)
+        return response.json(0)

+ 13 - 8
Controller/VodBucket.py

@@ -18,10 +18,12 @@ from django.utils.decorators import method_decorator
 from django.views.decorators.csrf import csrf_exempt
 from django.views.decorators.csrf import csrf_exempt
 from django.views.generic.base import View
 from django.views.generic.base import View
 
 
-from Model.models import VodBucketModel, UID_Bucket, Store_Meal, Device_Info, OssCrdModel
+from Model.models import VodBucketModel, UID_Bucket, Store_Meal, Device_Info, OssCrdModel, VodHlsModel, StsCrdModel, \
+    Unused_Uid_Meal
 from Object.ResponseObject import ResponseObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Object.TokenObject import TokenObject
 from Service.ModelService import ModelService
 from Service.ModelService import ModelService
+from django.db import transaction
 import time
 import time
 
 
 
 
@@ -239,13 +241,16 @@ class UidBucketView(View):
             id = request_dict.get('id', None)
             id = request_dict.get('id', None)
             page = int(request_dict.get('page', None))
             page = int(request_dict.get('page', None))
             line = int(request_dict.get('line', None))
             line = int(request_dict.get('line', None))
-            d_ubqs = UID_Bucket.objects.filter(id=id)
-            uid = d_ubqs[0].uid
-            channel = d_ubqs[0].channel
-            d_ubqs.delete()
-            oss_crd_qs = OssCrdModel.objects.filter(uid=uid, channel=channel)
-            if oss_crd_qs.exists():
-                oss_crd_qs.delete()
+            uid_bucket_qs = UID_Bucket.objects.filter(id=id)
+            uid = uid_bucket_qs[0].uid
+            bucket_id = uid_bucket_qs[0].bucket_id
+            # channel = uid_bucket_qs[0].channel
+            with transaction.atomic():
+                uid_bucket_qs.delete()
+                # OssCrdModel.objects.filter(uid=uid, channel=channel).delete()
+                VodHlsModel.objects.filter(uid=uid).delete()
+                StsCrdModel.objects.filter(uid=uid).delete()
+                Unused_Uid_Meal.objects.filter(uid=uid).delete()
         except Exception as e:
         except Exception as e:
             return response.json(10, repr(e))
             return response.json(10, repr(e))
         else:
         else:

+ 372 - 0
Controller/VoicePromptController.py

@@ -0,0 +1,372 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+import time
+
+import oss2
+from django.views import View
+
+from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET
+from Model.models import VoicePromptModel, UidChannelSetModel, Device_Info
+from Object.ResponseObject import ResponseObject
+from Object.TokenObject import TokenObject
+from Service.CommonService import CommonService
+from Service.ModelService import ModelService
+
+
+class VoicePromptView(View):
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.GET
+        operation = kwargs.get('operation', None)
+        return self.validate(request_dict, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.POST
+        operation = kwargs.get('operation', None)
+        return self.validate(request_dict, operation)
+
+    def validate(self, request_dict, operation):
+        token = request_dict.get('token', None)
+        print(token)
+        lang = request_dict.get('lang', None)
+        response = ResponseObject(lang=lang)
+        token = TokenObject(token)
+        if token.code != 0:
+            return response.json(token.code)
+
+        if operation == 'getUploadUrl':
+            return self.get_upload_url(request_dict, response)
+        elif operation == 'add':
+            return self.do_add(request_dict, response)
+        elif operation == 'delete':
+            return self.do_delete(token.userID, request_dict, response)
+        elif operation == 'query':
+            return self.do_query(request_dict, response)
+        elif operation == 'update':
+            return self.do_update(token.userID, request_dict, response)
+        elif operation == 'adminGetUploadUrl':
+            return self.admin_get_upload_url(token.userID, request_dict, response)
+        elif operation == 'adminAdd':
+            return self.do_admin_add(token.userID, request_dict, response)
+        elif operation == 'adminQuery':
+            return self.do_admin_query(token.userID, request_dict, response)
+        elif operation == 'adminUpdate':
+            return self.do_admin_update(token.userID, request_dict, response)
+        elif operation == 'adminDelete':
+            return self.do_admin_delete(token.userID, request_dict, response)
+        else:
+            return response.json(404)
+
+    def get_upload_url(self, request_dict, response):
+        upload_type = request_dict.get('upload_type', None)
+        uid = request_dict.get('uid', None)
+        channel = request_dict.get('channel', None)
+        type = request_dict.get('type', None)
+
+        if upload_type and uid and channel:
+            count = VoicePromptModel.objects.filter(uid=uid, channel=channel, type=type).count()
+            if count >= 3:
+                return response.json(201)
+
+            auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
+            bucket = oss2.Bucket(auth, 'oss-cn-shenzhen.aliyuncs.com', 'ansjer-static-resources')
+            name = CommonService.createOrderID()
+            filename = str(name) + '.' + upload_type
+            obj = 'voice_prompt/{uid}/{channel}/'.format(uid=uid, channel=channel) + filename
+
+            url = bucket.sign_url('PUT', obj, 7200)
+            return response.json(0, {'put_url': url, 'filename': filename})
+        else:
+            return response.json(444)
+
+    def do_add(self, request_dict, response):
+        filename = request_dict.get('filename', None)
+        title = request_dict.get('title', None)
+        type = request_dict.get('type', None)
+        lang = request_dict.get('lang', '')
+        uid = request_dict.get('uid', None)
+        channel = request_dict.get('channel', None)
+
+        if filename and title and type and uid and channel:
+            voice_prompt = VoicePromptModel()
+            voice_prompt.filename = filename
+            voice_prompt.title = title
+            voice_prompt.type = type
+            voice_prompt.language = lang
+            voice_prompt.classification = 1
+            voice_prompt.uid = uid
+            voice_prompt.channel = channel
+            voice_prompt.add_time = int(time.time())
+            voice_prompt.save()
+
+            res = {
+                'id': voice_prompt.id,
+                'filename': filename,
+                'title': title,
+                'type': type,
+            }
+            auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
+            bucket = oss2.Bucket(auth, 'oss-cn-shenzhen.aliyuncs.com', 'ansjer-static-resources')
+            filename = res['filename']
+            obj = 'voice_prompt/{uid}/{channel}/'.format(uid=uid, channel=channel) + filename
+            url = bucket.sign_url('GET', obj, 3600)
+            res['url'] = url
+            del res['filename']
+            return response.json(0, res)
+        else:
+            return response.json(444)
+
+    def do_update(self, userID, request_dict, response):
+        id = request_dict.get('id', None)
+        title = request_dict.get('title', None)
+
+        if id and title:
+            voice_qs = VoicePromptModel.objects.filter(id=id)
+            if voice_qs.exists():
+                uid = voice_qs[0].uid
+                device_qs = Device_Info.objects.filter(UID=uid, userID=userID)
+                if device_qs.exists():
+                    voice_qs.update(title=title)
+                    return response.json(0)
+                else:
+                    return response.json(404)
+            else:
+                return response.json(173)
+        else:
+            return response.json(444)
+
+    def do_delete(self, userID, request_dict, response):
+        id = request_dict.get('id', None)
+        if id:
+            voice_qs = VoicePromptModel.objects.filter(id=id)
+            if voice_qs.exists():
+                uid = voice_qs[0].uid
+                device_qs = Device_Info.objects.filter(UID=uid, userID=userID)
+                if device_qs.exists():
+                    channel = voice_qs[0].channel
+                    filename = voice_qs[0].filename
+                    voice_qs.delete()
+                    auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
+                    bucket = oss2.Bucket(auth, 'http://oss-cn-shenzhen.aliyuncs.com', 'ansjer-static-resources')
+                    obj = 'voice_prompt/{uid}/{channel}/'.format(uid=uid, channel=channel) + filename
+                    bucket.delete_object(obj)
+                    return response.json(0)
+                else:
+                    return response.json(404)
+            else:
+                return response.json(173)
+        else:
+            return response.json(444)
+
+    def do_query(self, request_dict, response):
+        lang = request_dict.get('lang', None)
+        uid = request_dict.get('uid', None)
+        channel = request_dict.get('channel', None)
+
+        if uid and channel and lang:
+            voice_qs = VoicePromptModel.objects.filter(uid=uid, channel=channel, classification=1)
+            system_qs = VoicePromptModel.objects.filter(classification=0, language=lang, status=1)
+            channel_qs = UidChannelSetModel.objects.filter(uid__uid=uid, channel=channel)
+
+            res = {
+                'enter_voice': {},
+                'leave_voice': {},
+                'voice_status': 0,
+                'voice_mute': 0
+            }
+            enter_voice_id = 0
+            leave_voice_id = 0
+            if channel_qs.exists():
+                channel_qs = channel_qs.values('voice_prompt_enter', 'voice_prompt_leave', 'voice_prompt_status',
+                                               'voice_prompt_intelligent_mute', 'voice_start_x', 'voice_start_y',
+                                               'voice_end_x', 'voice_end_y', 'voice_start_time', 'voice_end_time',
+                                               'voice_repeat_day', 'voice_direction')
+                print(channel_qs)
+                enter_voice_id = int(channel_qs[0]['voice_prompt_enter'])
+                leave_voice_id = int(channel_qs[0]['voice_prompt_leave'])
+                res['voice_status'] = channel_qs[0]['voice_prompt_status']
+                res['voice_mute'] = channel_qs[0]['voice_prompt_intelligent_mute']
+                res['start_x'] = channel_qs[0]['voice_start_x']
+                res['start_y'] = channel_qs[0]['voice_start_y']
+                res['end_x'] = channel_qs[0]['voice_end_x']
+                res['end_y'] = channel_qs[0]['voice_end_y']
+                res['start_time'] = channel_qs[0]['voice_start_time']
+                res['end_time'] = channel_qs[0]['voice_end_time']
+                res['repeat_day'] = channel_qs[0]['voice_repeat_day']
+                res['direction'] = channel_qs[0]['voice_direction']
+
+            enter_systems = []
+            leave_systems = []
+            enter_customs = []
+            leave_customs = []
+
+            res['system'] = {}
+            res['custom'] = {}
+            auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
+            bucket = oss2.Bucket(auth, 'oss-cn-shenzhen.aliyuncs.com', 'ansjer-static-resources')
+            if system_qs.exists():
+                system_qs = system_qs.values('id', 'title', 'filename', 'type')
+                for system in system_qs:
+                    filename = system['filename']
+                    obj = 'voice_prompt/system/' + filename
+                    url = bucket.sign_url('GET', obj, 3600)
+                    system['url'] = url
+                    del system['filename']
+                    if system['type'] == 0:
+                        enter_systems.append(system)
+                        if enter_voice_id == system['id']:
+                            res['enter_voice'] = system
+
+                    elif system['type'] == 1:
+                        leave_systems.append(system)
+                        if leave_voice_id == system['id']:
+                            res['leave_voice'] = system
+
+            if voice_qs.exists():
+                voice_qs = voice_qs.values('id', 'title', 'filename', 'type')
+
+                for voice in voice_qs:
+                    filename = voice['filename']
+                    obj = 'voice_prompt/' + uid + '/' + channel + '/' + filename
+                    url = bucket.sign_url('GET', obj, 3600)
+                    voice['url'] = url
+                    del voice['filename']
+                    if voice['type'] == 0:
+                        enter_customs.append(voice)
+                        if enter_voice_id == voice['id']:
+                            res['enter_voice'] = voice
+                    elif voice['type'] == 1:
+                        leave_customs.append(voice)
+                        if leave_voice_id == voice['id']:
+                            res['leave_voice'] = voice
+
+            res['system']['enter'] = enter_systems
+            res['system']['leave'] = leave_systems
+            res['custom']['enter'] = enter_customs
+            res['custom']['leave'] = leave_customs
+
+            return response.json(0, res)
+
+        else:
+            return response.json(444)
+
+    def admin_get_upload_url(self, userID, request_dict, response):
+        own_perm = ModelService.check_perm(userID, 10)
+        if not own_perm:
+            return response.json(404)
+
+        upload_type = request_dict.get('upload_type', None)
+
+        if upload_type:
+            auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
+            bucket = oss2.Bucket(auth, 'oss-cn-shenzhen.aliyuncs.com', 'ansjer-static-resources')
+            name = CommonService.createOrderID()
+            filename = str(name) + '.' + upload_type
+            obj = 'voice_prompt/system/' + filename
+
+            url = bucket.sign_url('PUT', obj, 7200)
+            return response.json(0, {'put_url': url, 'filename': filename})
+        else:
+            return response.json(444)
+
+    def do_admin_add(self, userID, request_dict, response):
+        own_perm = ModelService.check_perm(userID, 10)
+        if not own_perm:
+            return response.json(404)
+
+        filename = request_dict.get('filename', None)
+        title = request_dict.get('title', None)
+        type = request_dict.get('type', None)
+        lang = request_dict.get('lang', '')
+
+        if filename and title and type:
+            voice_prompt = VoicePromptModel()
+            voice_prompt.filename = filename
+            voice_prompt.title = title
+            voice_prompt.type = type
+            voice_prompt.language = lang
+            voice_prompt.classification = 0
+            voice_prompt.add_time = int(time.time())
+            voice_prompt.status = 0
+            voice_prompt.save()
+
+            return response.json(0)
+        else:
+            return response.json(444)
+
+    def do_admin_query(self, userID, request_dict, response):
+        own_perm = ModelService.check_perm(userID, 10)
+        if not own_perm:
+            return response.json(404)
+
+        type = request_dict.get('type', 0)
+        page = request_dict.get('page', None)
+        line = request_dict.get('line', None)
+
+        if page is None or line is None:
+            return response.json(444)
+
+        voice_qs = VoicePromptModel.objects.filter(classification=0, type=type)
+        print(voice_qs)
+        res = {
+            'count': 0
+        }
+
+        if voice_qs.exists():
+            page = int(page)
+            line = int(line)
+
+            start = (page - 1) * line
+            end = start + line
+            count = voice_qs.count()
+            res['count'] = count
+
+            voice_qs = voice_qs.values('id', 'title', 'type', 'language', 'status', 'filename')[start:end]
+
+            auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
+            bucket = oss2.Bucket(auth, 'oss-cn-shenzhen.aliyuncs.com', 'ansjer-static-resources')
+
+            for item in voice_qs:
+                filename = item['filename']
+                obj = 'voice_prompt/system/' + filename
+                url = bucket.sign_url('GET', obj, 3600)
+                item['url'] = url
+                del item['filename']
+            res['data'] = list(voice_qs)
+            return response.json(0, res)
+        else:
+            res['data'] = []
+            return response.json(0, res)
+
+    def do_admin_update(self, userID, request_dict, response):
+        own_perm = ModelService.check_perm(userID, 10)
+        if not own_perm:
+            return response.json(404)
+
+        id = request_dict.get('id', None)
+        status = request_dict.get('status', None)
+        title = request_dict.get('title', None)
+
+        if id and status and title:
+            VoicePromptModel.objects.filter(id=id, classification=0).update(status=status, title=title)
+            return response.json(0)
+        else:
+            return response.json(444)
+
+    def do_admin_delete(self, userID, request_dict, response):
+        own_perm = ModelService.check_perm(userID, 10)
+        if not own_perm:
+            return response.json(404)
+
+        id = request_dict.get('id', None)
+        if id:
+            VoicePromptModel.objects.filter(id=id, classification=0).delete()
+            return response.json(0)
+        else:
+            return response.json(444)
+
+
+
+

+ 2 - 2
Controller/shareUserPermission.py

@@ -46,7 +46,7 @@ class searchUserView(View):
         else:
         else:
             User = Device_User.objects.filter(**fieldDict).order_by('-data_joined')
             User = Device_User.objects.filter(**fieldDict).order_by('-data_joined')
         if User.exists():
         if User.exists():
-            ddUser = User[0].device_info_set.all()
+            ddUser = User[0].device_info_set.filter(isShare=False)
             sqlJSON = serializers.serialize('json', User)
             sqlJSON = serializers.serialize('json', User)
             sqlList = json.loads(sqlJSON)
             sqlList = json.loads(sqlJSON)
             if ddUser:
             if ddUser:
@@ -107,7 +107,7 @@ class searchUserView(View):
                 for k, v in enumerate(sqlDict["datas"]):
                 for k, v in enumerate(sqlDict["datas"]):
                     for val in device_user_res:
                     for val in device_user_res:
                         if v['pk'] == val.userID:
                         if v['pk'] == val.userID:
-                            dvqs = val.device_info_set.all()
+                            dvqs = val.device_info_set.filter(isShare=False)
                             device_info_list = CommonService.qs_to_dict(dvqs)
                             device_info_list = CommonService.qs_to_dict(dvqs)
                             # device_user关联到device_info
                             # device_user关联到device_info
                             sqlDict["datas"][k]['device_info'] = device_info_list
                             sqlDict["datas"][k]['device_info'] = device_info_list

+ 0 - 0
Model/__init__.py


+ 568 - 27
Model/models.py

@@ -1,5 +1,4 @@
 from itertools import chain
 from itertools import chain
-from Service.CommonService import CommonService
 from django.contrib.auth.models import BaseUserManager, AbstractBaseUser
 from django.contrib.auth.models import BaseUserManager, AbstractBaseUser
 from django.db import models
 from django.db import models
 from django.utils import six, timezone
 from django.utils import six, timezone
@@ -22,7 +21,7 @@ class PermissionsManager(models.Manager):
 
 
 class RoleManager(models.Manager):
 class RoleManager(models.Manager):
     """
     """
-    The manager for the auth's Role model.
+    The manager for the auth's Role model..
     """
     """
     use_in_migrations = True
     use_in_migrations = True
 
 
@@ -119,7 +118,6 @@ class Role(models.Model):
             permslist.sort()
             permslist.sort()
             return permslist
             return permslist
 
 
-
 class Device_User(AbstractBaseUser):
 class Device_User(AbstractBaseUser):
     userID = models.CharField(blank=True, max_length=32, primary_key=True,
     userID = models.CharField(blank=True, max_length=32, primary_key=True,
                               verbose_name=u'用户ID', unique=True)
                               verbose_name=u'用户ID', unique=True)
@@ -149,8 +147,9 @@ class Device_User(AbstractBaseUser):
     phone = models.CharField(max_length=16, db_index=True, verbose_name=u'手机号', default='', blank=True)
     phone = models.CharField(max_length=16, db_index=True, verbose_name=u'手机号', default='', blank=True)
     fingerprint_enable = models.SmallIntegerField(default=0, verbose_name=u'是否开启了指纹登录') # 0:未开启,1:已开启
     fingerprint_enable = models.SmallIntegerField(default=0, verbose_name=u'是否开启了指纹登录') # 0:未开启,1:已开启
     fingerprint_key = models.CharField(max_length=128, default='', verbose_name=u'客户端用于解码的密钥等信息')
     fingerprint_key = models.CharField(max_length=128, default='', verbose_name=u'客户端用于解码的密钥等信息')
-    is_local = models.BooleanField(blank=True, default=False, verbose_name=u'是否是本地登录用户')
-    subscribe_email = models.SmallIntegerField(default=0, verbose_name=u'是否订阅营销邮件')  # 0:未订阅,1:订阅,2:不订阅
+    is_local = models.BooleanField(blank=True, default=False, verbose_name=u'是否是本地登录用户') # False:账号登录,1:本地登录
+    subscribe_email = models.SmallIntegerField(default=0, verbose_name=u'是否订阅营销邮件') # 0:未订阅,1:订阅,2:不订阅
+    region_country = models.IntegerField(blank=True, default=0, verbose_name='地区表唯一标识')
     objects = UserManager()
     objects = UserManager()
 
 
     USERNAME_FIELD = 'userID'  # 必须有一个唯一标识
     USERNAME_FIELD = 'userID'  # 必须有一个唯一标识
@@ -206,6 +205,7 @@ class Device_User(AbstractBaseUser):
 
 
 # 设备表是建项目开发者设计的,自己看着办
 # 设备表是建项目开发者设计的,自己看着办
 # 谢谢提醒!我选择凉拌。
 # 谢谢提醒!我选择凉拌。
+# 我选择狗带
 class Device_Info(models.Model):
 class Device_Info(models.Model):
     id = models.CharField(blank=True, max_length=32, primary_key=True)
     id = models.CharField(blank=True, max_length=32, primary_key=True)
     userID = models.ForeignKey(Device_User, blank=True, to_field='userID', on_delete=models.CASCADE)
     userID = models.ForeignKey(Device_User, blank=True, to_field='userID', on_delete=models.CASCADE)
@@ -228,6 +228,8 @@ class Device_Info(models.Model):
                                   help_text=u'是否为共享获取的设备', default=False)
                                   help_text=u'是否为共享获取的设备', default=False)
     primaryUserID = models.CharField(blank=True, verbose_name='主用户id', max_length=32, default='')
     primaryUserID = models.CharField(blank=True, verbose_name='主用户id', max_length=32, default='')
     primaryMaster = models.CharField(max_length=64, verbose_name=u'主用户名', default='')
     primaryMaster = models.CharField(max_length=64, verbose_name=u'主用户名', default='')
+    vodPrimaryUserID = models.CharField(blank=True, verbose_name='云存主用户id', max_length=32, default='')
+    vodPrimaryMaster = models.CharField(max_length=64, verbose_name=u'云存主用户名', default='')
     data_joined = models.DateTimeField(blank=True, verbose_name=u'设备添加时间', auto_now_add=True)
     data_joined = models.DateTimeField(blank=True, verbose_name=u'设备添加时间', auto_now_add=True)
     update_time = models.DateTimeField(blank=True, verbose_name=u'更新时间', auto_now=True, null=True)
     update_time = models.DateTimeField(blank=True, verbose_name=u'更新时间', auto_now=True, null=True)
 
 
@@ -238,6 +240,8 @@ class Device_Info(models.Model):
     iSNotification = models.BooleanField(blank=True, verbose_name=u'报警通知 0:关闭,1:开启)', default=False)
     iSNotification = models.BooleanField(blank=True, verbose_name=u'报警通知 0:关闭,1:开启)', default=False)
     isVod = models.SmallIntegerField(blank=True, default=0, verbose_name='是否支持云存')  # 是否支持云存设备
     isVod = models.SmallIntegerField(blank=True, default=0, verbose_name='是否支持云存')  # 是否支持云存设备
     isExist = models.SmallIntegerField(blank=True, default=1, verbose_name='是否被删除')  # 是否被删除了(需主用户交互) 1存在,0不存在,2设备被重置
     isExist = models.SmallIntegerField(blank=True, default=1, verbose_name='是否被删除')  # 是否被删除了(需主用户交互) 1存在,0不存在,2设备被重置
+    isCameraOpenCloud =  models.SmallIntegerField(blank=True, default=1, verbose_name='是否开启云存')  # 0:不开启  1:开启
+    serial_number = models.CharField(blank=True, max_length=9, default='', verbose_name='关联序列号')
     ###
     ###
     REQUIRED_FIELDS = []
     REQUIRED_FIELDS = []
 
 
@@ -290,8 +294,9 @@ class Equipment_Info(models.Model):
     alarm = models.CharField(blank=True, max_length=256, verbose_name=u'报警信息')
     alarm = models.CharField(blank=True, max_length=256, verbose_name=u'报警信息')
     eventTime = models.CharField(blank=True, default='', max_length=16, verbose_name=u'设备报警时间')
     eventTime = models.CharField(blank=True, default='', max_length=16, verbose_name=u'设备报警时间')
     receiveTime = models.CharField(blank=True, default='', max_length=16, verbose_name=u'接收到报警时间')
     receiveTime = models.CharField(blank=True, default='', max_length=16, verbose_name=u'接收到报警时间')
-    userID_id = models.CharField(default='',  db_index=True,blank=True, max_length=32, verbose_name=u'用户ID')
+    userID_id = models.CharField(default='',  db_index=True, blank=True, max_length=32, verbose_name=u'用户ID')
     is_st = models.SmallIntegerField(default=0, verbose_name='是否截图')  # 0 否,1 是图,2,视频
     is_st = models.SmallIntegerField(default=0, verbose_name='是否截图')  # 0 否,1 是图,2,视频
+    storage_location = models.SmallIntegerField(default=1, db_index=True, verbose_name='数据信息存储位置。1:阿里云oss,2:aws')
     # message_id = models.CharField(blank=True, max_length=32, default='', verbose_name='第三方推送服务器返回的id')
     # message_id = models.CharField(blank=True, max_length=32, default='', verbose_name='第三方推送服务器返回的id')
     # push_type = models.SmallIntegerField(blank=True, default=0, verbose_name='第三方推送服务器标志。0:APNS推送,1:谷歌推送,2:极光推送')
     # push_type = models.SmallIntegerField(blank=True, default=0, verbose_name='第三方推送服务器标志。0:APNS推送,1:谷歌推送,2:极光推送')
     # push_server_status = models.IntegerField(blank=True, default=200, verbose_name='是否成功推送到第三方服务器。200:成功,other:失败')
     # push_server_status = models.IntegerField(blank=True, default=200, verbose_name='是否成功推送到第三方服务器。200:成功,other:失败')
@@ -308,7 +313,6 @@ class Equipment_Info(models.Model):
         ordering = ('-id',)
         ordering = ('-id',)
         app_label = "db2"
         app_label = "db2"
 
 
-
 class StatResModel(models.Model):
 class StatResModel(models.Model):
     id = models.AutoField(primary_key=True, verbose_name='自动ID')
     id = models.AutoField(primary_key=True, verbose_name='自动ID')
     name = models.CharField(default='', max_length=120, verbose_name='图片名称', unique=True)
     name = models.CharField(default='', max_length=120, verbose_name='图片名称', unique=True)
@@ -391,17 +395,19 @@ class User_Brand(models.Model):
 # 存储通表
 # 存储通表
 class VodBucketModel(models.Model):
 class VodBucketModel(models.Model):
     id = models.AutoField(primary_key=True, verbose_name='主键')
     id = models.AutoField(primary_key=True, verbose_name='主键')
-    bucket = models.CharField(max_length=30, verbose_name='设备UID')
+    bucket = models.CharField(max_length=60, verbose_name='存储桶名称')
     storeDay = models.IntegerField(default=0, verbose_name='存储生命周期(天)')
     storeDay = models.IntegerField(default=0, verbose_name='存储生命周期(天)')
     content = models.TextField(verbose_name='描述', default='')
     content = models.TextField(verbose_name='描述', default='')
     endpoint = models.CharField(max_length=125, default='', verbose_name='存储节点')
     endpoint = models.CharField(max_length=125, default='', verbose_name='存储节点')
     area = models.CharField(max_length=16, default='', verbose_name='区域')
     area = models.CharField(max_length=16, default='', verbose_name='区域')
     region = models.CharField(max_length=16, default='', verbose_name='regionID')
     region = models.CharField(max_length=16, default='', verbose_name='regionID')
+    is_free = models.SmallIntegerField(default=0, verbose_name='是否为免费存储桶[0:否,1:是]')
 
 
     addTime = models.IntegerField(verbose_name='添加时间', default=0)
     addTime = models.IntegerField(verbose_name='添加时间', default=0)
     updTime = models.IntegerField(verbose_name='更新时间', default=0)
     updTime = models.IntegerField(verbose_name='更新时间', default=0)
 
 
     mold = models.SmallIntegerField(default=0, verbose_name='存储区域类型')  # 0:国内阿里 1:国外aws
     mold = models.SmallIntegerField(default=0, verbose_name='存储区域类型')  # 0:国内阿里 1:国外aws
+    region_id = models.IntegerField(default=1, verbose_name='大洲编号')
 
 
     def __str__(self):
     def __str__(self):
         return self.id
         return self.id
@@ -415,18 +421,33 @@ class VodBucketModel(models.Model):
 
 
 class Store_Meal(models.Model):
 class Store_Meal(models.Model):
     id = models.AutoField(primary_key=True, verbose_name=u'自增ID')
     id = models.AutoField(primary_key=True, verbose_name=u'自增ID')
-    title = models.CharField(blank=True, max_length=32, verbose_name=u'标题')
-    currency = models.CharField(blank=True, default='USD', max_length=32, verbose_name=u'货币')
+    # title = models.CharField(blank=True, max_length=32, verbose_name=u'标题')
+    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'价格')
     price = models.CharField(blank=True, max_length=32, verbose_name=u'价格')
-    day = models.IntegerField(default=0, blank=True, verbose_name=u'套餐天数')
-    content = models.TextField(blank=True, null=True, verbose_name=u'描述')
+    virtual_price = models.CharField(blank=True, max_length=32, verbose_name=u'虚拟价格')
+    is_discounts = models.SmallIntegerField(default=0, verbose_name=u'该套餐是否有优惠 [0=否,1是]')   # 0没有;1有
+    discount_price = models.CharField(blank=True, max_length=32, verbose_name=u'第二年优惠价格')
+    day = models.IntegerField(default=0, blank=True, verbose_name=u'云存录像保存天数(循环)')   # 7,30,180,360
+    expire = models.IntegerField(default=0, blank=True, verbose_name=u'有效期') #单位月
+    # content = models.TextField(blank=True, null=True, verbose_name=u'描述')
     add_time = models.DateTimeField(blank=True, null=True, verbose_name=u'加入时间', auto_now_add=True)
     add_time = models.DateTimeField(blank=True, null=True, verbose_name=u'加入时间', auto_now_add=True)
-    type = models.SmallIntegerField(default=0, verbose_name='付款类型')  # 0 是paypal,1为支付宝
+    # type = models.SmallIntegerField(default=0, verbose_name='付款类型')  # 0是paypal,1为支付宝
+    pay_type = models.ManyToManyField(to='Pay_Type', verbose_name='付款类型', db_table='store_meal_pay')
     update_time = models.DateTimeField(blank=True, verbose_name=u'更新时间', auto_now=True)
     update_time = models.DateTimeField(blank=True, verbose_name=u'更新时间', auto_now=True)
     bucket = models.ForeignKey(VodBucketModel, blank=True, to_field='id', on_delete=models.CASCADE,
     bucket = models.ForeignKey(VodBucketModel, blank=True, to_field='id', on_delete=models.CASCADE,
                                default=1, verbose_name='存储空间')
                                default=1, verbose_name='存储空间')
     commodity_type = models.SmallIntegerField(default=0, verbose_name='云存储套餐类型')  # 0:事件型 1:连续型
     commodity_type = models.SmallIntegerField(default=0, verbose_name='云存储套餐类型')  # 0:事件型 1:连续型
     commodity_code = models.CharField(default='', max_length=32, verbose_name='套餐规格码')
     commodity_code = models.CharField(default='', max_length=32, verbose_name='套餐规格码')
+    is_show = models.SmallIntegerField(default=0, verbose_name=u'该套餐是否隐藏 [0=否,1是]')
+    # lang = models.CharField(default='', max_length=20, verbose_name='语言/国家')
+    lang = models.ManyToManyField(to='Lang', verbose_name='套餐语言', db_table='store_meal_lang')
+
+    # 备用字段
+    spare_1 = models.CharField(default='', blank=True, max_length=64, verbose_name=u'备用字段1')
+    spare_2 = models.CharField(default='', blank=True, max_length=64, verbose_name=u'备用字段2')
+    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):
     def __str__(self):
         return self.id
         return self.id
@@ -438,6 +459,38 @@ class Store_Meal(models.Model):
         ordering = ('id',)
         ordering = ('id',)
 
 
 
 
+class Pay_Type(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name=u'自增ID')
+    payment = models.CharField(max_length=32, verbose_name=u'支付方式')
+
+    def __str__(self):
+        return self.id
+
+    class Meta:
+        db_table = 'pay_type'
+        verbose_name = u'付款类型'
+        verbose_name_plural = verbose_name
+        ordering = ('id',)
+
+
+# 套餐语言表
+class Lang(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name='自增ID')
+    lang = models.CharField(default='', max_length=20, db_index=True, verbose_name='语言/国家')
+    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'优惠信息描述')
+
+    def __str__(self):
+        return self.id
+
+    class Meta:
+        db_table = 'lang'
+        verbose_name = '套餐语言'
+        verbose_name_plural = verbose_name
+        ordering = ('id',)
+
+
 class Equipment_Version(models.Model):
 class Equipment_Version(models.Model):
     eid = models.CharField(blank=True, max_length=32, primary_key=True)
     eid = models.CharField(blank=True, max_length=32, primary_key=True)
     ESN = models.CharField(blank=True, max_length=32, verbose_name=u'设备规格名称')
     ESN = models.CharField(blank=True, max_length=32, verbose_name=u'设备规格名称')
@@ -516,17 +569,19 @@ class App_Colophon(models.Model):
 
 
 class Order_Model(models.Model):
 class Order_Model(models.Model):
     orderID = models.CharField(blank=True, max_length=20, primary_key=True, verbose_name=u'订单id')
     orderID = models.CharField(blank=True, max_length=20, primary_key=True, verbose_name=u'订单id')
+    trade_no = models.CharField(blank=True, max_length=32, default='', verbose_name='第三方订单号')
     # 订单关联用户
     # 订单关联用户
     userID = models.ForeignKey(Device_User, to_field='userID', on_delete=models.CASCADE)
     userID = models.ForeignKey(Device_User, to_field='userID', on_delete=models.CASCADE)
     UID = models.CharField(max_length=20, verbose_name='设备UID')
     UID = models.CharField(max_length=20, verbose_name='设备UID')
     channel = models.SmallIntegerField(default=0, verbose_name=u'通道数')
     channel = models.SmallIntegerField(default=0, verbose_name=u'通道数')
     desc = models.CharField(max_length=50, default='', verbose_name='商品描述')
     desc = models.CharField(max_length=50, default='', verbose_name='商品描述')
     price = models.CharField(default='', max_length=16, verbose_name='价格')
     price = models.CharField(default='', max_length=16, verbose_name='价格')
-    currency = models.CharField(blank=True, default='USD', max_length=32, verbose_name=u'货币')
+    currency = models.CharField(blank=True, default='$', max_length=32, verbose_name=u'货币')
     addTime = models.IntegerField(verbose_name='添加时间', default=0)
     addTime = models.IntegerField(verbose_name='添加时间', default=0)
     updTime = models.IntegerField(verbose_name='更新时间', default=0)
     updTime = models.IntegerField(verbose_name='更新时间', default=0)
-    endTime = models.IntegerField(verbose_name='结束时间', default=0)
-    status = models.SmallIntegerField(default=0, verbose_name='付款状态')  # 0:否,1:成功
+    # endTime = models.IntegerField(verbose_name='结束时间', default=0)
+    isSelectDiscounts = models.SmallIntegerField(default=0, verbose_name=u'用户是否选择了第二年优惠 [0=否,1是]')
+    status = models.SmallIntegerField(default=0, verbose_name='付款状态')  # 0:待支付,1:成功,2:取消,3:已退款, 9:处理中,10:付款失败
     payType = models.SmallIntegerField(default=0, verbose_name='付款类型0:paypal,1:alipay')
     payType = models.SmallIntegerField(default=0, verbose_name='付款类型0:paypal,1:alipay')
     payTime = models.IntegerField(verbose_name='支付成功时间', default=0)
     payTime = models.IntegerField(verbose_name='支付成功时间', default=0)
     rank = models.ForeignKey(Store_Meal, to_field='id', default='', on_delete=models.CASCADE, verbose_name='套餐类型')
     rank = models.ForeignKey(Store_Meal, to_field='id', default='', on_delete=models.CASCADE, verbose_name='套餐类型')
@@ -534,9 +589,14 @@ class Order_Model(models.Model):
     uid_bucket_id = models.IntegerField(default=0, verbose_name='关联uid_bucket的字段')
     uid_bucket_id = models.IntegerField(default=0, verbose_name='关联uid_bucket的字段')
     commodity_type = models.SmallIntegerField(default=0, verbose_name='云存储套餐类型')
     commodity_type = models.SmallIntegerField(default=0, verbose_name='云存储套餐类型')
     commodity_code = models.CharField(default='', max_length=32, verbose_name='套餐规格码')
     commodity_code = models.CharField(default='', max_length=32, verbose_name='套餐规格码')
-    pay_url = models.CharField(max_length=500, default='', verbose_name='支付url')
+    pay_url = models.CharField(max_length=2000, default='', verbose_name='支付url')
     paypal = models.CharField(max_length=500, null=True, blank=True, verbose_name='支付批准url')
     paypal = models.CharField(max_length=500, null=True, blank=True, verbose_name='支付批准url')
 
 
+    # 备用字段
+    spare_1 = models.CharField(default='', blank=True, max_length=64, verbose_name=u'备用字段1')
+    spare_2 = models.CharField(default='', blank=True, max_length=64, verbose_name=u'备用字段2')
+    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):
     def __str__(self):
         return self.orderID
         return self.orderID
@@ -550,14 +610,14 @@ class Order_Model(models.Model):
 
 
 class VodHlsModel(models.Model):
 class VodHlsModel(models.Model):
     id = models.AutoField(primary_key=True, verbose_name='回放列表主键')
     id = models.AutoField(primary_key=True, verbose_name='回放列表主键')
-    uid = models.CharField(max_length=20, verbose_name='设备UID')
+    uid = models.CharField(max_length=20, verbose_name='设备UID', db_index=True)
     channel = models.SmallIntegerField(default=0, verbose_name='通道')
     channel = models.SmallIntegerField(default=0, verbose_name='通道')
     time = models.IntegerField(verbose_name='播放列表名字时间戳', default=0, db_index=True)
     time = models.IntegerField(verbose_name='播放列表名字时间戳', default=0, db_index=True)
-    endTime = models.IntegerField(verbose_name='删除时间', default=0)
+    endTime = models.IntegerField(verbose_name='云存储删除时间(周期)', default=0)
     sec = models.IntegerField(verbose_name='秒数', default=0)
     sec = models.IntegerField(verbose_name='秒数', default=0)
     bucket = models.ForeignKey(VodBucketModel, blank=True, to_field='id', on_delete=models.CASCADE, default=1,
     bucket = models.ForeignKey(VodBucketModel, blank=True, to_field='id', on_delete=models.CASCADE, default=1,
                                verbose_name='存储空间')
                                verbose_name='存储空间')
-    fg = models.SmallIntegerField(default=0,verbose_name='时间片段数') # 0为阿里云存储方案 >0为亚马逊方案
+    fg = models.CharField(max_length=20,verbose_name='ts个数,时间描述片段数') # 阿里为时间片段数,亚马逊为一个32bit整型,前28bit代表ts文件的时长
 
 
 
 
     def __str__(self):
     def __str__(self):
@@ -591,7 +651,7 @@ class OssCrdModel(models.Model):
 
 
 class StsCrdModel(models.Model):
 class StsCrdModel(models.Model):
     id = models.AutoField(primary_key=True, verbose_name='主键')
     id = models.AutoField(primary_key=True, verbose_name='主键')
-    uid = models.CharField(max_length=20, verbose_name='设备UID')
+    uid = models.CharField(max_length=20, verbose_name='设备UID', db_index=True)
     channel = models.SmallIntegerField(default=0, verbose_name='通道')
     channel = models.SmallIntegerField(default=0, verbose_name='通道')
     data = models.TextField(verbose_name='设备sts')
     data = models.TextField(verbose_name='设备sts')
     addTime = models.IntegerField(verbose_name='添加时间', default=0)
     addTime = models.IntegerField(verbose_name='添加时间', default=0)
@@ -611,11 +671,15 @@ class StsCrdModel(models.Model):
 
 
 class UID_Bucket(models.Model):
 class UID_Bucket(models.Model):
     id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
     id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
-    uid = models.CharField(max_length=20, verbose_name='设备UID')
+    uid = models.CharField(max_length=20, verbose_name='设备UID', db_index=True)
     channel = models.SmallIntegerField(default=0, verbose_name='通道')
     channel = models.SmallIntegerField(default=0, verbose_name='通道')
     bucket = models.ForeignKey(VodBucketModel, blank=True, to_field='id', on_delete=models.CASCADE, 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:关闭]')
-    endTime = models.IntegerField(verbose_name='结束时间', default=0)
+    endTime = models.BigIntegerField(verbose_name='套餐结束时间', db_index=True, default=0)
+    addTime = models.IntegerField(verbose_name='添加时间', default=0)
+    updateTime = models.BigIntegerField(verbose_name='更新时间', default=0)
+    use_status = models.IntegerField(verbose_name='使用状态[1:使用中,2已过期]', default=0)
+    has_unused = models.SmallIntegerField(default=0, verbose_name='是否拥有其它未使用的套餐[0:否,1:是]')
 
 
     class Meta:
     class Meta:
         db_table = 'vod_uid_bucket'
         db_table = 'vod_uid_bucket'
@@ -623,6 +687,23 @@ class UID_Bucket(models.Model):
         verbose_name_plural = verbose_name
         verbose_name_plural = verbose_name
         ordering = ('id',)
         ordering = ('id',)
 
 
+class Unused_Uid_Meal(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
+    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='存储空间')
+    addTime = models.IntegerField(verbose_name='添加时间', default=0)
+    expire = models.IntegerField(verbose_name='存储桶存储时长[月份]', default=0)
+    num = models.IntegerField(verbose_name='个数', default=0)
+    # effect_time = models.BigIntegerField(verbose_name='生效时间', db_index=True, default=0)
+    # uid_bucket = models.ForeignKey(UID_Bucket, blank=True, to_field='id', on_delete=models.CASCADE, default=0,
+    #                            verbose_name='uid_bucket关联')
+    class Meta:
+        db_table = 'unused_uid_Meal'
+        verbose_name = '未使用的设备关联套餐表'
+        verbose_name_plural = verbose_name
+        ordering = ('id',)
+
 
 
 class UID_Preview(models.Model):
 class UID_Preview(models.Model):
     id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
     id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
@@ -671,7 +752,7 @@ class UidSetModel(models.Model):
     version = models.CharField(max_length=32, verbose_name='设备版本', default='')
     version = models.CharField(max_length=32, verbose_name='设备版本', default='')
     p2p_region = models.CharField(max_length=16, verbose_name='设备p2p区域', default='ALL')  # ALL CN EU US
     p2p_region = models.CharField(max_length=16, verbose_name='设备p2p区域', default='ALL')  # ALL CN EU US
     cloud_vod = models.SmallIntegerField(default=2, verbose_name='云存开关')  # 0,关闭,1开启,2,不支持
     cloud_vod = models.SmallIntegerField(default=2, verbose_name='云存开关')  # 0,关闭,1开启,2,不支持
-    tz = models.CharField(default='', max_length=16, verbose_name='设备时区')  # +8
+    tz = models.CharField(default='', max_length=16, verbose_name ='设备时区')  # +8
     video_code = models.SmallIntegerField(default=0, verbose_name='编码类型')  # 0:264,1:265
     video_code = models.SmallIntegerField(default=0, verbose_name='编码类型')  # 0:264,1:265
     nickname = models.CharField(default='', max_length=64, verbose_name='设备昵称')
     nickname = models.CharField(default='', max_length=64, verbose_name='设备昵称')
     ip = models.CharField(max_length=20, default='', verbose_name=u'设备ip')
     ip = models.CharField(max_length=20, default='', verbose_name=u'设备ip')
@@ -692,6 +773,9 @@ class UidSetModel(models.Model):
     WIFIName = models.CharField(blank=True, max_length=50, default='', verbose_name=u'无线名称')
     WIFIName = models.CharField(blank=True, max_length=50, default='', verbose_name=u'无线名称')
     isDetector = models.SmallIntegerField(default=0, verbose_name=u'侦测开关0:关闭,1:开启')
     isDetector = models.SmallIntegerField(default=0, verbose_name=u'侦测开关0:关闭,1:开启')
     DetectorRank = models.IntegerField(default=0, verbose_name=u'侦测灵敏度 0:低,1:中,2:高,3:最高')
     DetectorRank = models.IntegerField(default=0, verbose_name=u'侦测灵敏度 0:低,1:中,2:高,3:最高')
+    is_human = models.IntegerField(default=0, verbose_name='是否支持人形追踪。0:不支持,1:支持')
+    is_custom_voice = models.IntegerField(default=0, verbose_name='是否支持自定义语音。0:不支持,1:支持')
+    double_wifi = models.IntegerField(default=0, verbose_name='是否支持双频wifi。0:不支持,1:支持')
 
 
     class Meta:
     class Meta:
         db_table = 'uid_set'
         db_table = 'uid_set'
@@ -701,7 +785,7 @@ class UidSetModel(models.Model):
 
 
 
 
 # 设备关联用户推送
 # 设备关联用户推送
-class UidPushModel(models.Model):
+class   UidPushModel(models.Model):
     id = models.AutoField(primary_key=True, verbose_name='自增id')
     id = models.AutoField(primary_key=True, verbose_name='自增id')
     userID = models.ForeignKey(Device_User, to_field='userID', on_delete=models.CASCADE)
     userID = models.ForeignKey(Device_User, to_field='userID', on_delete=models.CASCADE)
     uid_set = models.ForeignKey(UidSetModel, to_field='id', on_delete=models.CASCADE)
     uid_set = models.ForeignKey(UidSetModel, to_field='id', on_delete=models.CASCADE)
@@ -727,6 +811,7 @@ class UidChannelSetModel(models.Model):
     id = models.AutoField(primary_key=True, verbose_name='自增id')
     id = models.AutoField(primary_key=True, verbose_name='自增id')
     uid = models.ForeignKey(UidSetModel, to_field='id', on_delete=models.CASCADE)
     uid = models.ForeignKey(UidSetModel, to_field='id', on_delete=models.CASCADE)
     channel = models.IntegerField(default=1, verbose_name='通道号')
     channel = models.IntegerField(default=1, verbose_name='通道号')
+    channel_name = models.CharField(blank=True, default='', max_length=20, verbose_name=u'通道名')
     pir_audio = models.SmallIntegerField(default=0, verbose_name='pir声音。0:关闭,1:开启')
     pir_audio = models.SmallIntegerField(default=0, verbose_name='pir声音。0:关闭,1:开启')
     mic_audio = models.SmallIntegerField(default=0, verbose_name='mic声音。0:关闭,1:开启')
     mic_audio = models.SmallIntegerField(default=0, verbose_name='mic声音。0:关闭,1:开启')
     battery_status = models.SmallIntegerField(default=0, verbose_name='低电量提醒状态。0:关闭,1:开启')
     battery_status = models.SmallIntegerField(default=0, verbose_name='低电量提醒状态。0:关闭,1:开启')
@@ -735,11 +820,23 @@ class UidChannelSetModel(models.Model):
     sleep_time = models.SmallIntegerField(default=0, verbose_name='摄像机进入休眠时间。0:不休眠;1:10秒;2:20秒;3:30秒')
     sleep_time = models.SmallIntegerField(default=0, verbose_name='摄像机进入休眠时间。0:不休眠;1:10秒;2:20秒;3:30秒')
     light_night_model = models.IntegerField(default=0, verbose_name='夜视模式')  # 0:全彩模式,1:黑白模式,2:智能夜视模式
     light_night_model = models.IntegerField(default=0, verbose_name='夜视模式')  # 0:全彩模式,1:黑白模式,2:智能夜视模式
     light_alarm_type = models.IntegerField(default=0, verbose_name='警报人形类型')  # 0为人形,1为移动,3是人形和移动侦测0x0f
     light_alarm_type = models.IntegerField(default=0, verbose_name='警报人形类型')  # 0为人形,1为移动,3是人形和移动侦测0x0f
-    light_alarm_level = models.IntegerField(default=0,
-                                            verbose_name='声光报警级别')  # 0: 关闭,1:强烈声光告警,2:轻微声光告警,3: 强烈声告警,4:轻微声告警,5:强烈光告警
+    # 声光报警级别: 0: 关闭,1:强烈声光告警,2:轻微声光告警,3: 强烈声告警,4:轻微声告警,5:强烈光告警
+    light_alarm_level = models.IntegerField(default=0, verbose_name='声光报警级别')
     light_alarm_man_en = models.IntegerField(default=0, verbose_name='人为告警状态')  # 0:关,1:开
     light_alarm_man_en = models.IntegerField(default=0, verbose_name='人为告警状态')  # 0:关,1:开
     light_alarm_vol = models.IntegerField(default=0, verbose_name='报警音量')  # 音量值0-100
     light_alarm_vol = models.IntegerField(default=0, verbose_name='报警音量')  # 音量值0-100
     light_long_light = models.IntegerField(default=0, verbose_name='长亮')
     light_long_light = models.IntegerField(default=0, verbose_name='长亮')
+    voice_prompt_status = models.SmallIntegerField(default=0, verbose_name='个性语音提示快关。0:关闭,1:开启')
+    voice_prompt_enter = models.IntegerField(default=0, verbose_name='进入铃声id')
+    voice_prompt_leave = models.IntegerField(default=0, verbose_name='离开铃声id')
+    voice_prompt_intelligent_mute = models.SmallIntegerField(default=0, verbose_name='智能静音。0:关闭,1:开启')
+    voice_start_x = models.FloatField(default=0, verbose_name='起始坐标的x')
+    voice_start_y = models.FloatField(default=18, verbose_name='起始坐标的y')
+    voice_end_x = models.FloatField(default=44, verbose_name='结束坐标的x')
+    voice_end_y = models.FloatField(default=18, verbose_name='结束坐标的y')
+    voice_start_time = models.IntegerField(default=0, verbose_name='语音执行的起始时间')
+    voice_end_time = models.IntegerField(default=0, verbose_name='语音执行的结束时间')
+    voice_repeat_day = models.IntegerField(default=127, verbose_name='语音执行的日期,周几')
+    voice_direction = models.IntegerField(default=0, verbose_name='语音方向。')
 
 
     class Meta:
     class Meta:
         db_table = 'uid_channel'
         db_table = 'uid_channel'
@@ -998,6 +1095,22 @@ class AppLogModel(models.Model):
         verbose_name_plural = verbose_name
         verbose_name_plural = verbose_name
 
 
 
 
+class EquipmentInfoExStatisticsModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    push_type = models.SmallIntegerField(default=0, verbose_name='第三方推送服务器标志。0:APNS推送,1:谷歌推送,2:极光推送')
+    number_of_successes = models.IntegerField(default=0, verbose_name='推送成功数量')
+    number_of_failures = models.IntegerField(default=0, verbose_name='推送失败数量')
+    number_of_arrival = models.IntegerField(default=0, verbose_name='推送到达数量')
+    statistics_date = models.IntegerField(default=0, verbose_name='属于哪天、哪月的统计')
+    date_type = models.SmallIntegerField(default=0, verbose_name='统计日期的类型。0:天,1:月')
+    add_time = models.IntegerField(default=0, verbose_name='添加时间')
+
+    class Meta:
+        db_table = 'equipment_info_ex_statistics'
+        verbose_name = '推送消息统计表'
+        verbose_name_plural = verbose_name
+
+
 class CountryIPModel(models.Model):
 class CountryIPModel(models.Model):
     id = models.AutoField(primary_key=True)
     id = models.AutoField(primary_key=True)
     ip = models.CharField(default='', max_length=32, verbose_name='ip')
     ip = models.CharField(default='', max_length=32, verbose_name='ip')
@@ -1012,6 +1125,33 @@ class CountryIPModel(models.Model):
         verbose_name_plural = verbose_name
         verbose_name_plural = verbose_name
 
 
 
 
+class ZositechHelpModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    locale = models.CharField(default='', db_index=True, max_length=50, verbose_name='语言')
+    label_names =  models.CharField(default='', db_index=True, max_length=50, verbose_name='标签')
+    origin  =  models.CharField(default='', db_index=True ,max_length=50, verbose_name='来源')
+    # author_id = models.CharField(default='', max_length=50, verbose_name='管理员id')
+    # body = models.TextField(default='', blank=True, verbose_name='内容')
+    # comments_disabled = models.CharField(default='', max_length=10, verbose_name='comments')
+    # created_at = models.CharField(default='', max_length=50, verbose_name='创建时间')
+    # draft = models.CharField(default='', max_length=10, verbose_name='草稿')
+    # edited_at = models.CharField(default='',max_length=50, verbose_name='修改时间')
+    # html_url = models.CharField(default='', blank=True, verbose_name='跳转路径')
+    # body = models.CharField(default='', blank=True, verbose_name='标签')
+    # body = models.CharField(default='', blank=True, verbose_name='标签')
+    # body = models.TextField(default='', blank=True, verbose_name='标签')
+    # body = models.TextField(default='', blank=True, verbose_name='标签')
+    # body = models.CharField(default='', blank=True, verbose_name='标签')
+    # body = models.CharField(default='', blank=True, verbose_name='标签')
+
+    content = models.TextField(blank=True, default='', verbose_name=u'内容')
+
+    class Meta:
+        db_table = 'zositech_help'
+        verbose_name = '周视使用帮助表'
+        verbose_name_plural = verbose_name
+
+
 class EquipmentVersionLimitModel(models.Model):
 class EquipmentVersionLimitModel(models.Model):
     id = models.AutoField(primary_key=True)
     id = models.AutoField(primary_key=True)
     type = models.SmallIntegerField(default=0, verbose_name='限制类型')
     type = models.SmallIntegerField(default=0, verbose_name='限制类型')
@@ -1024,4 +1164,405 @@ class EquipmentVersionLimitModel(models.Model):
     class Meta:
     class Meta:
         db_table = 'equipment_version_limit'
         db_table = 'equipment_version_limit'
         verbose_name = '设备版本信息限制表'
         verbose_name = '设备版本信息限制表'
+        verbose_name_plural = verbose_name
+
+
+class ExperienceContextModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    experience_type = models.SmallIntegerField(default=0,verbose_name='体验类型') # 0: 免费体验套餐, 1: 激活码
+    uid = models.CharField(max_length=20, default='', verbose_name='设备uid')
+    do_time = models.IntegerField(default=0, verbose_name='激活时间')
+    # is_experience = models.SmallIntegerField(default=0, verbose_name=u'是否云存体验用户')  # 0:不是体验用户,1:是体验用户
+
+    class Meta:
+        db_table = 'experience_context'
+        verbose_name = '设备体验表'
+        verbose_name_plural = verbose_name
+
+class CDKcontextModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    cdk = models.CharField(max_length=50,unique=True,verbose_name='激活码')
+    create_time = models.IntegerField(default=0, verbose_name='创建时间')
+    valid_time = models.IntegerField(default=0, verbose_name='有效期间')  #超过有效期激活码不可在激活 ,0:永久
+    is_activate = models.SmallIntegerField(default=0, verbose_name='是否已激活') #0 未激活  1 已激活
+    rank = models.ForeignKey(Store_Meal, to_field='id', default='', on_delete=models.CASCADE, verbose_name='套餐类型')
+    # order = models.ForeignKey(Order_Model, blank=True, max_length=20, to_field='orderID', on_delete=models.CASCADE, verbose_name='订单id', unique=True)
+    order = models.CharField(max_length=20, blank=True, unique=True, verbose_name='订单id')
+
+    # 备用字段
+    spare_1 = models.CharField(default='', blank=True, max_length=64, verbose_name=u'备用字段1')
+    spare_2 = models.CharField(default='', blank=True, max_length=64, verbose_name=u'备用字段2')
+    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')
+
+    class Meta:
+        db_table = 'cdk_context'
+        verbose_name = '激活码表'
+        verbose_name_plural = verbose_name
+
+
+class VoicePromptModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    title = models.CharField(max_length=128, default='', verbose_name='语音标题')
+    type = models.SmallIntegerField(default=0, verbose_name='语音类型。0:进入语音,1:离开语音')
+    filename = models.CharField(max_length=120, default='', verbose_name='文件名')
+    language = models.CharField(max_length=16, default='', verbose_name='语言类型')
+    classification = models.SmallIntegerField(default=1, verbose_name='语音分类。0:系统,1:自定义')
+    add_time = models.IntegerField(default=0, verbose_name='添加时间')
+    uid = models.CharField(max_length=20, default='0', verbose_name='关联设备UID')
+    channel = models.IntegerField(default=0, verbose_name='通道号')
+    status = models.SmallIntegerField(default=1, verbose_name='是否启用。0:不启用,1:启用')
+
+    class Meta:
+        db_table = 'voice_prompt'
+        verbose_name = '语音提示表'
+        verbose_name_plural = verbose_name
+
+
+class DeviceTypeModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    name = models.CharField(max_length=64, default='', verbose_name='设备名称')
+    model = models.SmallIntegerField(default=0, verbose_name='设备大类。1:dvr,2:ipc')
+    type = models.IntegerField(default=0, verbose_name='设备类型')
+    ptz_type = models.IntegerField(default=0, verbose_name='ptz类型。1:dvr球机,2:IPCPTZ,3:同轴菜单')
+    icon = models.CharField(max_length=120, default='', verbose_name='文件名')
+    add_time = models.IntegerField(default=0, verbose_name='添加时间')
+    update_time = models.IntegerField(default=0, verbose_name='更新时间')
+
+    class Meta:
+        db_table = 'device_type'
+        verbose_name = '设备类型表'
+        verbose_name_plural = verbose_name
+
+
+class OperatingLogsModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    userId = models.CharField(blank=False, max_length=32, db_index=True, verbose_name=u'操作人')
+    operatingtime = models.DateTimeField(blank=True, verbose_name=u'操作时间', auto_now=True)
+    operatingcontent = models.TextField(blank=True, default='', verbose_name=u'操作内容')
+    operatingtype = models.CharField(blank=True, verbose_name=u'操作类型', max_length=32)
+    is_saveprocessinfo = models.SmallIntegerField(default=1, verbose_name=u'是否保存过程信息。1:保存,2:不保存')
+    devUid = models.CharField(default='', blank=True, max_length=32, verbose_name=u'设备ID')
+    userIp = models.CharField(blank=True, max_length=20, default='', verbose_name=u'用户ip')
+
+    class Meta:
+        db_table = 'operating_logs'
+        verbose_name = '操作数据表'
+        verbose_name_plural = verbose_name
+
+
+class ProcessInfoLogsModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    userId = models.CharField(blank=False, max_length=32, db_index=True, verbose_name=u'操作人')
+    devUid = models.CharField(default='', blank=True, max_length=32, verbose_name=u'设备ID')
+    operatingcontent = models.TextField(blank=True, default='', verbose_name=u'操作内容')
+    operatingtime = models.DateTimeField(blank=True, verbose_name=u'操作时间', auto_now=True)
+
+    class Meta:
+        db_table = 'processinfo_logs'
+        verbose_name = '过程信息表'
+        verbose_name_plural = verbose_name
+
+class EquipmentLogModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    user = models.CharField(blank=False, max_length=32, db_index=True, verbose_name=u'操作用户')
+    uid = models.CharField(default='', blank=True, max_length=32, verbose_name=u'设备uid')
+    equipmentid = models.CharField(blank=False, max_length=100, db_index=True, verbose_name=u'设备主键id')
+    NickName = models.CharField(blank=True, max_length=32, verbose_name=u'设备名称')
+    ip = models.CharField(max_length=100, default='', db_index=True, blank=True, verbose_name=u'访问ip地址')
+    time = models.DateTimeField(null=True, blank=True, db_index=True, verbose_name=u'访问时间')
+    operatingcontent = models.TextField(blank=True, default='', verbose_name=u'操作内容')
+    url = models.CharField(max_length=150, default='', blank=True, verbose_name=u'访问路径')
+    class Meta:
+        db_table = 'equipment_log'
+        verbose_name = '设备日志表'
+        verbose_name_plural = verbose_name
+
+
+class UserModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    username = models.CharField(unique=True, max_length=128, null=False, verbose_name='用户名')
+    password = models.CharField(max_length=128, null=False, verbose_name='密码')
+    permission = models.CharField(max_length=24, null=False, verbose_name='权限')
+    login_time = models.IntegerField(blank=True, default=0, verbose_name='登录时间')
+    online = models.SmallIntegerField(default=0, verbose_name='是否在线')
+    phone = models.CharField(max_length=11, default='', verbose_name='手机号')
+    add_time = models.IntegerField(default=0, verbose_name='添加时间')
+
+    class Meta:
+        verbose_name = '用户表'
+        verbose_name_plural = verbose_name
+        db_table = 'user'
+
+
+class CompanyModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    name = models.CharField(max_length=64, unique=True, default='', verbose_name='企业名称')
+    mark = models.CharField(max_length=3, unique=True, default='', verbose_name='企业标志,用于序列号的后三位')
+    secret = models.CharField(max_length=10, db_index=True, default='', verbose_name='企业秘钥')
+    quantity = models.IntegerField(default=0, verbose_name='已购买的序列号的数量')
+    add_time = models.IntegerField(default=0, verbose_name='添加时间')
+    update_time = models.IntegerField(default=0, verbose_name='更新时间')
+
+    class Meta:
+        db_table = 'tb_company'
+        verbose_name = '企业表'
+        verbose_name_plural = verbose_name
+
+
+class RegionModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    name = models.CharField(max_length=32, default='', verbose_name='区域名称')
+    continent_code = models.CharField(max_length=3, default='', verbose_name='洲代码')
+    api = models.CharField(max_length=50, default='', verbose_name='请求地址')
+
+
+    class Meta:
+        db_table = 'tb_region'
+        verbose_name = '区域表'
+        verbose_name_plural = verbose_name
+
+
+class VPGModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    name = models.CharField(max_length=32, default='', verbose_name='群组名称')
+    uid_count = models.IntegerField(default=0, verbose_name='uid数量')
+    region = models.ForeignKey(RegionModel, to_field='id', on_delete=models.DO_NOTHING, verbose_name='群组用于的地区')
+    company = models.ForeignKey(CompanyModel, to_field='id', on_delete=models.DO_NOTHING, verbose_name='关联企业表')
+    add_time = models.IntegerField(default=0, verbose_name='添加时间')
+    update_time = models.IntegerField(default=0, verbose_name='更新时间')
+
+    class Meta:
+        db_table = 'tb_vpg'
+        verbose_name = 'vpg表'
+        verbose_name_plural = verbose_name
+
+
+class UIDModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    uid = models.CharField(max_length=20, null=False, db_index=True, unique=True, verbose_name='设备id')
+    mac = models.CharField(max_length=17, null=False, default='', unique=True, verbose_name='设备id对应的mac地址')
+    uid_extra = models.TextField(default='', verbose_name='uid的额外描述')
+    status = models.SmallIntegerField(default=0, verbose_name='使用状态')   # 0:未分配,1:已分配,2:已使用
+    add_time = models.IntegerField(default=0, verbose_name='添加时间')
+    update_time = models.IntegerField(default=0, verbose_name='更新时间')
+    area = models.SmallIntegerField(default=0, verbose_name='区域')  #0:国内;1:国外
+    vpg = models.ForeignKey(VPGModel, to_field='id', default=1, on_delete=models.DO_NOTHING, verbose_name='关联VPG表的id')
+    p2p_type = models.IntegerField(default=1, verbose_name='p2p类型。1:宸云,2:tutk')
+    full_uid_code = models.CharField(max_length=256, default='', verbose_name='宸云完整uid')
+
+    class Meta:
+        ordering = ('-add_time',)
+        verbose_name = 'uid表'
+        verbose_name_plural = verbose_name
+        db_table = 'uid'
+
+
+class UserUIDModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    user = models.ForeignKey(UserModel, to_field='id', on_delete=models.CASCADE, verbose_name='关联用户表id')
+    uid = models.ForeignKey(UIDModel, to_field='id', on_delete=models.CASCADE, verbose_name='关联uid表id')
+    add_time = models.IntegerField(default=0, verbose_name='添加时间')
+    update_time = models.IntegerField(default=0, verbose_name='更新时间')
+
+    class Meta:
+        verbose_name = '用户与UID的关联表'
+        verbose_name_plural = verbose_name
+        db_table = 'user_uid'
+
+
+class PermissionModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    type = models.SmallIntegerField(null=False, verbose_name='权限枚举')
+    description = models.TextField(default='', verbose_name='权限描述')
+
+    class Meta:
+        verbose_name = '权限表'
+        verbose_name_plural = verbose_name
+        db_table = 'permission'
+
+
+class LogModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    operation = models.CharField(max_length=100, default='', verbose_name='操作描述')
+    time = models.IntegerField(default=0, verbose_name='操作时间')
+    ip = models.CharField(default='', max_length=24, verbose_name='用户ip')
+    user = models.ForeignKey(UserModel, to_field='id', on_delete=models.CASCADE, verbose_name='关联用户id')
+    content = models.TextField(default='', verbose_name='请求参数')
+    status = models.IntegerField(default=0, verbose_name='请求状态')
+    url = models.CharField(max_length=150, default='', verbose_name='请求路径')
+
+    class Meta:
+        ordering = ('-time',)
+        verbose_name = '日志表'
+        verbose_name_plural = verbose_name
+        db_table = 'log'
+
+
+class HistoryUIDModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    uid = models.CharField(max_length=20, null=False, db_index=True, verbose_name='设备id')
+    uid_extra = models.TextField(default='', verbose_name='uid的额外描述')
+    status = models.SmallIntegerField(default=0, verbose_name='使用状态')
+    add_time = models.IntegerField(default=0, verbose_name='添加时间')
+    update_time = models.IntegerField(default=0, verbose_name='更新时间')
+    area = models.SmallIntegerField(default=0, verbose_name='区域')  # 0:国内;1:国外
+
+    class Meta:
+        verbose_name = '历史UID表'
+        verbose_name_plural = verbose_name
+        db_table = 'history_uid'
+
+
+class MacModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    value = models.CharField(max_length=17, null=False, verbose_name='最新的mac地址')
+    is_active = models.BooleanField(default=True, verbose_name='当前mac地址是否可用')
+    add_time = models.IntegerField(default=0, verbose_name='添加时间')
+    update_time = models.IntegerField(default=0, verbose_name='更新时间')
+
+    class Meta:
+        verbose_name = '最新的mac地址表'
+        verbose_name_plural = verbose_name
+        db_table = 'tb_mac'
+
+
+class OrderTaskModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    order_number = models.CharField(max_length=32, verbose_name='订单号')
+    board = models.CharField(max_length=32, verbose_name='主板')
+    plan = models.CharField(max_length=32, verbose_name='配置方案')
+    checksum = models.CharField(max_length=32, verbose_name='校验和')
+    ic_model = models.CharField(max_length=32, verbose_name='ic型号')
+    quantity = models.IntegerField(default=0, verbose_name='通知单上的生成数量')
+    add_time = models.IntegerField(default=0, verbose_name='添加时间')
+
+    class Meta:
+        db_table = 'order_task'
+        verbose_name = '订单任务表'
+        verbose_name_plural = verbose_name
+
+
+class OrderUIDModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    uid = models.ForeignKey(UIDModel, to_field='id', on_delete=models.CASCADE, verbose_name='关联uid表')
+    order = models.ForeignKey(OrderTaskModel, to_field='id', on_delete=models.CASCADE, verbose_name='关联订单任务表')
+    add_time = models.IntegerField(default=0, verbose_name='添加时间')
+    update_time = models.IntegerField(default=0, verbose_name='更新时间')
+
+    class Meta:
+        db_table = 'order_uid'
+        verbose_name = '订单与uid关联表'
+        verbose_name_plural = verbose_name
+
+
+class CountryModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    number = models.IntegerField(unique=True, verbose_name='区号')
+    add_time = models.IntegerField(default=0, verbose_name='添加时间')
+    update_time = models.IntegerField(default=0, verbose_name='更新时间')
+    region = models.ForeignKey(RegionModel, to_field='id', on_delete=models.DO_NOTHING, verbose_name='关联区域表')
+    country_code = models.CharField(max_length=2, default='', verbose_name='国家iso2代码')
+    country_name = models.CharField(max_length=20, default='', verbose_name='国家名')
+
+    class Meta:
+        db_table = 'tb_country'
+        verbose_name = '地区表'
+        verbose_name_plural = verbose_name
+
+
+class LanguageModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    lang = models.CharField(max_length=16, default='', verbose_name='语种')
+    lang_youdao = models.CharField(max_length=16, default='', verbose_name='有道的语种')
+    add_time = models.IntegerField(default=0, verbose_name='添加时间')
+    update_time = models.IntegerField(default=0, verbose_name='更新时间')
+
+    class Meta:
+        db_table = 'tb_language'
+        verbose_name = '语言表'
+        verbose_name_plural = verbose_name
+
+
+class CountryLanguageModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    country_name = models.CharField(max_length=64, default='', verbose_name='国家名称')
+    language = models.ForeignKey(LanguageModel, to_field='id', on_delete=models.CASCADE, verbose_name='关联语言表的id')
+    country = models.ForeignKey(CountryModel, to_field='id', on_delete=models.CASCADE, verbose_name='关联地区表的id')
+    add_time = models.IntegerField(default=0, verbose_name='添加时间')
+    update_time = models.IntegerField(default=0, verbose_name='更新时间')
+
+    class Meta:
+        db_table = 'tb_country_language'
+        verbose_name = '不同语言的地区名称表'
+        verbose_name_plural = verbose_name
+
+
+class SerialNumberModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    serial_number = models.CharField(max_length=9, db_index=True, unique=True, verbose_name='序列号')
+    status = models.SmallIntegerField(default=1, verbose_name='可用状态。0:不可用,1:可用')
+    use_status = models.SmallIntegerField(default=0, db_index=True, verbose_name='使用状态, 0: 未使用, 1: 已分配')
+    p2p = models.SmallIntegerField(default=0, db_index=True, verbose_name='p2p类型。0:无,1:宸云,2:tutk')
+    add_time = models.IntegerField(default=0, verbose_name='添加时间')
+
+    class Meta:
+        db_table = 'tb_serial_number'
+        verbose_name = '序列号表'
+        verbose_name_plural = verbose_name
+
+
+class CompanySerialModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    company = models.ForeignKey(CompanyModel, to_field='id', on_delete=models.CASCADE, verbose_name='关联企业表的id')
+    serial_number = models.CharField(max_length=11, db_index=True, blank=True, default='', verbose_name=u'6位数序列号')
+    status = models.SmallIntegerField(default=0, verbose_name='序列号的状态。0:未使用,1:已使用,2:已和UID关联')
+    p2p = models.SmallIntegerField(default=0, verbose_name='p2p类型。0:无,1:宸云,2:tutk')
+    add_time = models.IntegerField(default=0, verbose_name='添加时间')
+    update_time = models.IntegerField(default=0, verbose_name='更新时间')
+
+    class Meta:
+        db_table = 'tb_company_serial'
+        verbose_name = '企业关联序列号表'
+        verbose_name_plural = verbose_name
+
+
+class UIDCompanySerialModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    uid = models.ForeignKey(UIDModel, to_field='id', on_delete=models.CASCADE, verbose_name='关联UID表')
+    company_serial = models.ForeignKey(CompanySerialModel, to_field='id', on_delete=models.CASCADE, verbose_name='6位数序列号')
+    add_time = models.IntegerField(default=0, verbose_name='添加时间')
+    update_time = models.IntegerField(default=0, verbose_name='更新时间')
+
+    class Meta:
+        db_table = 'tb_uid_company_serial'
+        verbose_name = 'UID关联【企业关联序列号】表'
+        verbose_name_plural = verbose_name
+
+
+class iotdeviceInfoModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    serial_number = models.CharField(max_length=11, blank=True, default='', db_index=True, verbose_name=u'关联Device_Info表的序列号')
+    uid = models.CharField(blank=True, max_length=32, default='', db_index=True, verbose_name=u'设备UID')
+    certificate_id = models.CharField(blank=True, max_length=256, default='', verbose_name=u'证书id')
+    certificate_pem = models.TextField(blank=True, default='', verbose_name=u'证书项目')
+    public_key = models.TextField(blank=True, default='', verbose_name=u'公有密钥')
+    private_key = models.TextField(blank=True, default='', verbose_name=u'私有密钥')
+    thing_name = models.CharField(blank=True, max_length=256, default='', verbose_name=u'IoT Thing Name')
+    thing_groups = models.CharField(blank=True, max_length=256, default='', verbose_name=u'IoT Thing Groups')
+    endpoint = models.CharField(blank=True, max_length=256, db_index=True, default='', verbose_name=u'iot端点')
+    token_iot_number = models.CharField(blank=True,  db_index=True ,default='', max_length=50, verbose_name='连接iot令牌')
+    class Meta:
+        db_table = 'iot_deviceInfo'
+        verbose_name = 'iot设备信息表'
+        verbose_name_plural = verbose_name
+
+
+class UIDMainUser(models.Model):
+    id = models.AutoField(primary_key=True)
+    UID = models.CharField(blank=True, max_length=32, verbose_name=u'设备UID', default='')
+    user_id = models.CharField(blank=True, max_length=32, verbose_name=u'用户ID', default='')
+    class Meta:
+        db_table = 'uid_mainuser'
+        verbose_name = '设备主用户表'
         verbose_name_plural = verbose_name
         verbose_name_plural = verbose_name

+ 3 - 0
Model/tests.py

@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.

+ 3 - 0
Model/views.py

@@ -0,0 +1,3 @@
+from django.shortcuts import render
+
+# Create your views here.

+ 52 - 0
Object/AWS/S3Email.py

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

+ 20 - 0
Object/AliSmsObject.py

@@ -76,6 +76,26 @@ class AliSmsObject(object):
         # {"Message":"OK","RequestId":"985FA027-C887-4186-A8F5-B6B8F3D123DB","BizId":"973407842937195533^0","Code":"OK"}
         # {"Message":"OK","RequestId":"985FA027-C887-4186-A8F5-B6B8F3D123DB","BizId":"973407842937195533^0","Code":"OK"}
         # code = isv.BUSINESS_LIMIT_CONTROL 一分钟只能发一次
         # code = isv.BUSINESS_LIMIT_CONTROL 一分钟只能发一次
         return res_json
         return res_json
+
+        # 发送验证码
+
+    def send_code_sms_cloud(self, phone, params, sign_name, temp_msg):
+        __business_id = uuid.uuid1()
+        # print(__business_id)
+        # params = "{\"code\":\"{"+str(code)+"}\"}"
+        params = params
+        # params = u'{"name":"wqb","code":"12345678","address":"bz","phone":"13000000000"}'
+        # 签名
+        # sign_name = 'Ansjer'
+        # 模板信息
+        # temp_msg = 'SMS_151600991'
+        res = self.do_send_sms(__business_id, phone, sign_name, temp_msg, params)
+        # print(send_sms(__business_id, "13119657713", "云通信测试", "SMS_5250008", params))
+        res_json = json.loads(res.decode('utf-8'))
+        print(res_json)
+        # {"Message":"OK","RequestId":"985FA027-C887-4186-A8F5-B6B8F3D123DB","BizId":"973407842937195533^0","Code":"OK"}
+        # code = isv.BUSINESS_LIMIT_CONTROL 一分钟只能发一次
+        return res_json
 #
 #
 # aliSms = AliSmsObject()
 # aliSms = AliSmsObject()
 # aliSms.send_sign_in_sms(phone=13119657713,code=123456)
 # aliSms.send_sign_in_sms(phone=13119657713,code=123456)

+ 3 - 0
Object/ETkObject.py

@@ -32,6 +32,9 @@ class ETkObject(object):
             if len(uid) == 20:
             if len(uid) == 20:
                 self.uid = uid
                 self.uid = uid
                 print(uid)
                 print(uid)
+            elif len(uid) == 14:
+                self.uid = uid
+                print(uid)
         except Exception as e:
         except Exception as e:
             print(repr(e))
             print(repr(e))
 
 

+ 180 - 0
Object/IOTCore/IotObject.py

@@ -0,0 +1,180 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+import json
+from abc import ABCMeta,abstractmethod
+
+import boto3
+
+from Ansjer.config import AWS_IOT_SES_ACCESS_CHINA_REGION, AWS_IOT_SES_ACCESS_CHINA_ID, AWS_IOT_SES_ACCESS_CHINA_SECRET, \
+    AWS_IOT_SES_ACCESS_FOREIGN_REGION_AMERICA, AWS_IOT_SES_ACCESS_FOREIGN_ID, AWS_IOT_SES_ACCESS_FOREIGN_SECRET, \
+    AWS_IOT_SES_ACCESS_FOREIGN_REGION_EUROPE, AWS_IOT_SES_ACCESS_FOREIGN_REGION_ASIA, AWS_IOT_SES_ACCESS_CHINA_ROLE, \
+    AWS_IOT_SES_ACCESS_FOREIGN_ROLE
+
+
+class IOTObject(metaclass=ABCMeta):
+
+    @abstractmethod
+    def create_provisioning_claim(self, templateName):
+        pass
+
+    @abstractmethod
+    def create_keys_and_certificate(self, uid):
+        pass
+
+
+class IOTClient(IOTObject):
+
+    def __init__(self, region_id = 1):
+
+        if region_id == 1:
+            self.client = boto3.client('iot', region_name=AWS_IOT_SES_ACCESS_CHINA_REGION,
+                                       aws_access_key_id=AWS_IOT_SES_ACCESS_CHINA_ID,
+                                       aws_secret_access_key=AWS_IOT_SES_ACCESS_CHINA_SECRET)
+            self.endpoint = 'a250bbr0p9u7as-ats.iot.cn-northwest-1.amazonaws.com.cn'
+            self.iotrole = AWS_IOT_SES_ACCESS_CHINA_ROLE
+
+        if region_id == 2:
+            self.client = boto3.client('iot', region_name=AWS_IOT_SES_ACCESS_FOREIGN_REGION_ASIA,
+                                       aws_access_key_id=AWS_IOT_SES_ACCESS_FOREIGN_ID,
+                                       aws_secret_access_key=AWS_IOT_SES_ACCESS_FOREIGN_SECRET)
+            self.endpoint = 'a2rqy12o004ad8-ats.iot.ap-southeast-1.amazonaws.com'
+            self.iotrole = AWS_IOT_SES_ACCESS_FOREIGN_ROLE
+
+        if region_id == 3:
+            self.client = boto3.client('iot', region_name=AWS_IOT_SES_ACCESS_FOREIGN_REGION_AMERICA,
+                                       aws_access_key_id=AWS_IOT_SES_ACCESS_FOREIGN_ID,
+                                       aws_secret_access_key=AWS_IOT_SES_ACCESS_FOREIGN_SECRET)
+            self.endpoint = 'a2rqy12o004ad8-ats.iot.us-east-1.amazonaws.com'
+            self.iotrole = AWS_IOT_SES_ACCESS_FOREIGN_ROLE
+
+        if region_id == 4:
+            self.client = boto3.client('iot', region_name=AWS_IOT_SES_ACCESS_FOREIGN_REGION_EUROPE,
+                                       aws_access_key_id=AWS_IOT_SES_ACCESS_FOREIGN_ID,
+                                       aws_secret_access_key=AWS_IOT_SES_ACCESS_FOREIGN_SECRET)
+            self.endpoint = 'a2rqy12o004ad8-ats.iot.eu-west-1.amazonaws.com'
+            self.iotrole = AWS_IOT_SES_ACCESS_FOREIGN_ROLE
+
+
+
+    def create_provisioning_claim(self, templateName):
+
+        result = self.client.create_provisioning_claim(templateName=templateName)
+
+        res = {
+            'certificateId': result['certificateId'],
+            'certificatePem': result['certificatePem'],
+            'publicKey': result['keyPair']['PublicKey'],
+            'privateKey': result['keyPair']['PrivateKey'],
+            'endpoint': self.endpoint
+        }
+        return res
+
+    def create_keys_and_certificate(self, ThingNameSuffix, thingGroup, response):
+        try:
+            result = self.client.create_keys_and_certificate(setAsActive=True)
+            res = {
+                'certificateId': result['certificateId'],
+                'certificatePem': result['certificatePem'],
+                'publicKey': result['keyPair']['PublicKey'],
+                'privateKey': result['keyPair']['PrivateKey'],
+                'endpoint': self.endpoint
+            }
+            # 搜索是否存在该物品组
+            thing_groups_res = self.client.list_thing_groups(nextToken='', maxResults=1,
+                                                             namePrefixFilter=thingGroup, recursive=False)
+            if thing_groups_res['thingGroups']:
+                thingGroupName = thing_groups_res['thingGroups'][0]['groupName']  # 获取物品组名称
+            else:
+                attributes = {
+                    "update_time": "0"
+                }
+                thingGroupProperties = {
+                    "thingGroupDescription": "OTA",
+                    "attributePayload": {
+                        "attributes": attributes,
+                        "merge": False  # 更新时覆盖掉而不是合并
+                    }
+                }
+                create_thing_group_res = self.client.create_thing_group(thingGroupName=thingGroup,
+                                                                        thingGroupProperties=thingGroupProperties)
+                thingGroupName = create_thing_group_res['thingGroupName']  # 获取物品组名称
+            print('物品组:', thingGroupName)
+            # 根据证书ID注册物品和策略
+            templateBody = {
+                "Parameters": {
+                    "ThingName": {
+                        "Type": "String"
+                    },
+                    "SerialNumber": {
+                        "Type": "String"
+                    },
+                    "thingGroupName": {
+                        "Type": "String"
+                    },
+                    "AWS::IoT::Certificate::Id": {
+                        "Type": "String"
+                    }
+                },
+                "Resources": {
+                    "thing": {
+                        "Type": "AWS::IoT::Thing",
+                        "Properties": {
+                            "AttributePayload": {},
+                            # "ThingGroups" : ["v1-lightbulbs", {"Ref" : "DeviceLocation"}],
+                            "ThingName": {
+                                "Ref": "ThingName"
+                            },
+                            "ThingGroups": [{"Ref": "thingGroupName"}]
+                        },
+                        "OverrideSettings": {
+                            "AttributePayload": "MERGE",
+                            "ThingTypeName": "REPLACE",
+                            "ThingGroups": "DO_NOTHING"
+                        }
+                    },
+                    "certificate": {
+                        "Type": "AWS::IoT::Certificate",
+                        "Properties": {
+                            "CertificateId": {"Ref": "AWS::IoT::Certificate::Id"},
+                            "Status": "Active"
+                        }
+                    },
+                    "policy": {
+                        "Properties": {
+                            "PolicyName": "My_Iot_Policy"
+                        },
+                        "Type": "AWS::IoT::Policy"
+                    },
+                }
+            }
+            ThingName = 'Ansjer_Device_' + ThingNameSuffix
+            templateBody = json.dumps(templateBody)
+            parameters = {"ThingName": ThingName,
+                          "thingGroupName": thingGroupName,
+                          "AWS::IoT::Certificate::Id": res['certificateId']}
+            self.client.register_thing(
+                templateBody=templateBody,
+                parameters=parameters
+            )
+            topicsql = "SELECT * FROM 'my/things/" + ThingName + "/shadow/update_lwt'"
+            self.client.create_topic_rule(
+                ruleName= ThingName + '_LWT',
+                topicRulePayload={
+                    "sql": topicsql,
+                    "ruleDisabled": False,
+                    "awsIotSqlVersion": "2016-03-23",
+                    'actions': [
+                        {
+                            'republish': {
+                                'roleArn': self.iotrole,
+                                'topic': '$$aws/things/' + ThingName + '/shadow/update',
+                                'qos': 1
+                            }
+                        }
+                    ]
+                }
+            )
+            return res, parameters
+        except Exception as e:
+            print(e)
+            return response.json(500, repr(e))

+ 17 - 0
Object/LogUtil.py

@@ -0,0 +1,17 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+from Ansjer.config import BASE_DIR
+
+
+class LogUtil:
+
+    @staticmethod
+    def write_log(file_path=None, log=''):
+        if not file_path:
+            file_path = '/'.join((BASE_DIR, 'static/test.log'))
+
+        file = open(file_path, 'a+')
+        file.write(log)
+        file.write('\n')
+        file.flush()
+        file.close()

+ 210 - 0
Object/LogsObject.py

@@ -0,0 +1,210 @@
+from django.shortcuts import HttpResponse
+import simplejson as json
+
+
+class LogsObject(object):
+    def __init__(self, lang='en'):
+        self.lang = lang
+
+    def data(self, code, res={}):
+        data_en = {
+            0: 'Success',
+            5: 'Please try again one minute later!',
+            10: res,
+            12: 'You are not the primary user of the device!',
+            14: 'Device is not belong to you',
+            15: 'Device has been bound',
+            16: 'WeChat has been bound, please log in and unbind using WeChat',
+            17: 'No email or mobile phone login',
+            44: 'System error! Can not send email',
+            48: 'System object error!',
+            89: 'Already send the code, please check it or get it again after 10m',
+            90: 'please check code or get it again after 1m',
+            99: 'Mail doesn\'t exist!',
+            100: 'Phone format error!',
+            101: 'Phone already existed!',
+            102: 'Phone doesn\'t exist!',
+            103: 'Mail already existed!',
+            104: 'Account doesn\'t exist!',
+            105: 'Email format error!',
+            107: 'The username not conform to the rules!',
+            109: 'The password not conform to the rules!',
+            110: 'user doesn\'t activated',
+            111: 'Error password',
+            112: 'Fingerprint login is not turned on',
+            119: 'The qr code has expired',
+            120: 'The code has expired',
+            121: 'The verification code is wrong!',
+            173: 'Data does not exists!',
+            174: 'Data already exists!',
+            176: 'Delete error',
+            177: 'Update error',
+            178: 'ADD error',
+            179: 'Nickname repeated',
+            201: 'You can only add 3 custom voice at most',
+            306: 'The link has expired!',
+            309: 'Please ReLogin! errmsg token',
+            404: 'You don not have permission to access this!',
+            414: 'Please confirm the request url!',
+            424: 'Database Error !',
+            444: 'Wrong parameters!',
+            474: 'System Maintaining!',
+            475: 'App Version too low, please upgrade!',
+            500: 'Query Database Error:',
+            700: 'Upload file error',
+            701: 'The file does not exist!',
+            711: 'Do not downgrade',
+            712: 'Area needs to be consistent',
+            713: 'Storage rules cannot be changed during the validity period',
+            717: 'Authorization expires',
+            800: 'Order does not exist',
+            801: 'The refund amount cannot be greater than the order price',
+            802: 'The order has been completed and cannot be cancelled',
+            804: 'Refund, please do not repeat the operation',
+            900: 'There is no information about this version!',
+            901: 'Getting URL failure!',
+            902: 'No update!',
+            903: 'Error filename',
+            904: 'Version does not support this feature!',
+            906: 'Cause of file operation error',
+            907: 'The download file does not exist!',
+            908: 'userId cannot be empty',
+            10001: 'Customer number, customer confidentiality error',
+            10002: 'Check your configuration: no customer number, customer confidentiality',
+            10003: 'The authorization code does not exist. Please reauthorize',
+            10004: 'The request method is incorrect. Please contact the developer',
+            10005: 'Wrong configuration, wrong customer number',
+            10006: 'Configuration error. The path value is incorrect',
+            10007: 'This device is not an experience package and cannot be reset',
+            10008: 'The user does not have this device and cannot transfer',
+            10009: 'The user already owns the device and cannot transfer it',
+            10010: 'Devices that are not under the same account cannot be transferred',
+            10011: 'Receiving transfer device does not exist and cannot be transferred',
+            10012: 'Experience packages cannot be transferred',
+            10013: 'Original equipment package has expired and cannot be transferred',
+            10014: 'Accept transfer of equipment packages that have not expired and cannot be transferred',
+            10015: 'Shared devices cannot be transferred',
+            10030: 'No purchase of cloud storage',
+            10031: 'The cloud storage has expired',
+            10032: 'The switched cloud storage package ID cannot be the same as the one in use',
+            10033: 'The primary user of the device cannot purchase it',
+            10034: 'Non device primary users cannot view cloud storage',
+            10035: 'Non device primary users cannot experience cloud storage',
+            10036: 'Non device primary users cannot exchange for cloud storage',
+            10037: 'Non device primary user cannot transfer device',
+            10038: 'Non device primary user cannot transfer packages',
+            10039: 'Activation code has been used',
+            10040: 'Invalid activation code'
+        }
+        data_cn = {
+            0: '成功',
+            5: '请一分钟后再尝试',
+            10: res,
+            12: '非设备主用户',
+            14: '设备不属于您',
+            15: '设备已被绑定',
+            16: '微信已被绑定,请使用微信登录并解绑',
+            17: '未绑定邮箱或者手机登录方式',
+            44: '系统错误!无法发送电子邮件',
+            48: '系统对象错误',
+            89: '已发验证码,请检测或10分钟后重新获取。',
+            90: '请检测或1分钟后重新获取。',
+            99: '邮箱不存在!',
+            100: '手机格式错误!',
+            101: '手机已存在!',
+            102: '手机不存在!',
+            103: '邮箱已存在!',
+            104: '账户不存在!',
+            105: '邮箱格式错误!',
+            107: '用户名格式不符合!',
+            109: '密码格式不符合!',
+            110: '用户未激活!',
+            111: '密码不正确!',
+            112: '未开通指纹登录',
+            119: '二维码过期',
+            120: '验证码过期',
+            121: '验证码错了!',
+            173: '数据不存在!',
+            174: '数据已存在!',
+            176: '删除错误',
+            177: '更新错误',
+            178: '增加错误',
+            179: '名称不能重复',
+            201: '最多只能添加3条自定义语音',
+            306: '链接已超过有效期!',
+            309: '请重新登录!',
+            404: '您没有访问的权限!',
+            414: '请确认请求url!',
+            424: '数据库错误!',
+            444: '参数错误!',
+            474: '系统维护中!',
+            475: '版本过低,请升级程序!',
+            500: '查询数据库错误!',
+            700: '上传文件错误',
+            701: '文件不存在',
+            711: '不可降级',
+            712: '区域不一致',
+            713: '有效期内不可更改存储规则',
+            717: '授权过期',
+            800: '订单不存在',
+            801: '退款金额不能大于订单价格',
+            802: '订单已完成,不能撤销',
+            804: '订单已退款,请勿重复操作',
+            900: '版本信息不存在',
+            901: '获取链接失败',
+            902: '无更新!',
+            903: '文件名不符合!',
+            904: '版本不支持本功能!',
+            906: '文件操作错误',
+            907: '文件不存在!',
+            908: '用户id不能为空',
+            10001: '客户编号,客户机密错误',
+            10002: '检查您的配置:没有客户编号,客户机密',
+            10003: '授权码不存在,请重新授权',
+            10004: '请求方法不正确。请联系开发者',
+            10005: '配置错误,客户编号这个值是错误的',
+            10006: '配置错误,路径这个值是错误的',
+            10007: '此设备不是体验套餐,无法重置',
+            10008: '用户没有此设备,无法转移',
+            10009: '用户已拥有此设备,无法转移',
+            10010: '不是同一账户下的设备,无法转移',
+            10011: '接受转移设备不存在,无法转移',
+            10012: '体验套餐无法转移',
+            10013: '原设备套餐已过期,无法转移',
+            10014: '接受转移设备套餐未过期,无法转移',
+            10015: '分享的设备无法转移',
+            10030: '未购买云存',
+            10031: '云存已过期',
+            10032: '切换的云存套餐ID不能与正在使用中的相同',
+            10033: '非设备主用户无法购买',
+            10034: '非设备主用户无法查看云存',
+            10035: '非设备主用户无法体验云存',
+            10036: '非设备主用户无法兑换云存',
+            10037: '非设备主用户无法转移设备',
+            10038: '非设备主用户无法转移套餐',
+            10039: '激活码已被使用过',
+            10040: '无效激活码'
+        }
+        if self.lang == 'cn':
+            msg = data_cn
+        elif self.lang == 'zh-Hans':
+            msg = data_cn
+        elif self.lang == 'zh-Hant':
+            msg = data_cn
+        else:
+            msg = data_en
+        try:
+            message = msg[code]
+        except Exception as e:
+            message = '系统错误,code不存在'
+        print(self.lang == 'cn')
+        print(msg)
+        return {'result_code': code, 'reason': message, 'result': res, 'error_code': code}
+
+    def formal(self, code, res={}):
+        formal_data = self.data(code, res)
+        return json.dumps(formal_data, ensure_ascii=False)
+
+    def json(self, code, res={}):
+        result = self.formal(code, res)
+        return HttpResponse(result)

+ 7 - 0
Object/RedisObject.py

@@ -70,6 +70,13 @@ class RedisObject:
     def rpush(self, name, val):
     def rpush(self, name, val):
         self.CONN.rpush(name, val)
         self.CONN.rpush(name, val)
 
 
+    def lpop(self, key):
+        val = self.CONN.lpop(key)
+        if val:
+            return val.decode('utf-8')
+        else:
+            return False
+
     # 获取列表长度
     # 获取列表长度
     def llen(self, name):
     def llen(self, name):
         return self.CONN.llen(name=name)
         return self.CONN.llen(name=name)

+ 58 - 0
Object/ResponseObject.py

@@ -41,6 +41,7 @@ class ResponseObject(object):
             177: 'Update error',
             177: 'Update error',
             178: 'ADD error',
             178: 'ADD error',
             179: 'Nickname repeated',
             179: 'Nickname repeated',
+            201: 'You can only add 3 custom voice at most',
             306: 'The link has expired!',
             306: 'The link has expired!',
             309: 'Please ReLogin! errmsg token',
             309: 'Please ReLogin! errmsg token',
             404: 'You don not have permission to access this!',
             404: 'You don not have permission to access this!',
@@ -56,6 +57,10 @@ class ResponseObject(object):
             712: 'Area needs to be consistent',
             712: 'Area needs to be consistent',
             713: 'Storage rules cannot be changed during the validity period',
             713: 'Storage rules cannot be changed during the validity period',
             717: 'Authorization expires',
             717: 'Authorization expires',
+            800: 'Order does not exist',
+            801: 'The refund amount cannot be greater than the order price',
+            802: 'The order has been completed and cannot be cancelled',
+            804: 'Refund, please do not repeat the operation',
             900: 'There is no information about this version!',
             900: 'There is no information about this version!',
             901: 'Getting URL failure!',
             901: 'Getting URL failure!',
             902: 'No update!',
             902: 'No update!',
@@ -69,6 +74,30 @@ class ResponseObject(object):
             10004: 'The request method is incorrect. Please contact the developer',
             10004: 'The request method is incorrect. Please contact the developer',
             10005: 'Wrong configuration, wrong customer number',
             10005: 'Wrong configuration, wrong customer number',
             10006: 'Configuration error. The path value is incorrect',
             10006: 'Configuration error. The path value is incorrect',
+            10007: 'This device is not an experience package and cannot be reset',
+            10008: 'The user does not have this device and cannot transfer',
+            10009: 'The user already owns the device and cannot transfer it',
+            10010: 'Devices that are not under the same account cannot be transferred',
+            10011: 'Receiving transfer device does not exist and cannot be transferred',
+            10012: 'Experience packages cannot be transferred',
+            10013: 'Original equipment package has expired and cannot be transferred',
+            10014: 'Accept transfer of equipment packages that have not expired and cannot be transferred',
+            10015: 'Shared devices cannot be transferred',
+            10030: 'No purchase of cloud storage',
+            10031: 'The cloud storage has expired',
+            10032: 'The switched cloud storage package ID cannot be the same as the one in use',
+            10033: 'The primary user of the device cannot purchase it',
+            10034: 'Non device primary users cannot view cloud storage',
+            10035: 'Non device primary users cannot experience cloud storage',
+            10036: 'Non device primary users cannot exchange for cloud storage',
+            10037: 'Non device primary user cannot transfer device',
+            10038: 'Non device primary user cannot transfer packages',
+            10039: 'Activation code has been used',
+            10040: 'Invalid activation code',
+            10041: 'This device has purchased a domestic cloud storage package, and cannot purchase a foreign cloud storage package',
+            10042: 'The device has registered a certificate',
+            10043: 'The device does not have a serial number',
+            10044: 'Request to publish MQTT topic message failed',
         }
         }
         data_cn = {
         data_cn = {
             0: '成功',
             0: '成功',
@@ -104,6 +133,7 @@ class ResponseObject(object):
             177: '更新错误',
             177: '更新错误',
             178: '增加错误',
             178: '增加错误',
             179: '名称不能重复',
             179: '名称不能重复',
+            201: '最多只能添加3条自定义语音',
             306: '链接已超过有效期!',
             306: '链接已超过有效期!',
             309: '请重新登录!',
             309: '请重新登录!',
             404: '您没有访问的权限!',
             404: '您没有访问的权限!',
@@ -119,6 +149,10 @@ class ResponseObject(object):
             712: '区域不一致',
             712: '区域不一致',
             713: '有效期内不可更改存储规则',
             713: '有效期内不可更改存储规则',
             717: '授权过期',
             717: '授权过期',
+            800: '订单不存在',
+            801: '退款金额不能大于订单价格',
+            802: '订单已完成,不能撤销',
+            804: '订单已退款,请勿重复操作',
             900: '版本信息不存在',
             900: '版本信息不存在',
             901: '获取链接失败',
             901: '获取链接失败',
             902: '无更新!',
             902: '无更新!',
@@ -132,6 +166,30 @@ class ResponseObject(object):
             10004: '请求方法不正确。请联系开发者',
             10004: '请求方法不正确。请联系开发者',
             10005: '配置错误,客户编号这个值是错误的',
             10005: '配置错误,客户编号这个值是错误的',
             10006: '配置错误,路径这个值是错误的',
             10006: '配置错误,路径这个值是错误的',
+            10007: '此设备不是体验套餐,无法重置',
+            10008: '用户没有此设备,无法转移',
+            10009: '用户已拥有此设备,无法转移',
+            10010: '不是同一账户下的设备,无法转移',
+            10011: '接受转移设备不存在,无法转移',
+            10012: '体验套餐无法转移',
+            10013: '原设备套餐已过期,无法转移',
+            10014: '接受转移设备套餐未过期,无法转移',
+            10015: '分享的设备无法转移',
+            10030: '未购买云存',
+            10031: '云存已过期',
+            10032: '切换的云存套餐ID不能与正在使用中的相同',
+            10033: '非设备主用户无法购买',
+            10034: '非设备主用户无法查看云存',
+            10035: '非设备主用户无法体验云存',
+            10036: '非设备主用户无法兑换云存',
+            10037: '非设备主用户无法转移设备',
+            10038: '非设备主用户无法转移套餐',
+            10039: '激活码已被使用过',
+            10040: '无效激活码',
+            10041: '此设备已购买过国内云存套餐,无法购买国外云存套餐',
+            10042: '此设备已注册证书',
+            10043: '此设备没有序列号',
+            10044: '请求发布MQTT主题消息失败',
         }
         }
         if self.lang == 'cn':
         if self.lang == 'cn':
             msg = data_cn
             msg = data_cn

+ 24 - 4
Object/TokenObject.py

@@ -43,10 +43,10 @@ class TokenObject:
             self.lang = res.get('lang', None)
             self.lang = res.get('lang', None)
             self.user = res.get('user', '')
             self.user = res.get('user', '')
             # 刷新登录时间
             # 刷新登录时间
-            if self.userID:
-                print(self.user)
-                redisObj = RedisObject(db=3)
-                redisObj.set_data(key=self.userID, val=self.user, expire=300)
+            # if self.userID:
+            #     print(self.user)
+            #     redisObj = RedisObject(db=3)
+            #     redisObj.set_data(key=self.userID, val=self.user, expire=300)
 
 
         except jwt.ExpiredSignatureError as e:
         except jwt.ExpiredSignatureError as e:
             print('过期')
             print('过期')
@@ -97,6 +97,26 @@ class TokenObject:
             self.code = 0
             self.code = 0
             return res
             return res
 
 
+    def encryption(self, data={}):
+        try:
+            access_expire = int(OAUTH_ACCESS_TOKEN_TIME.total_seconds())
+            refresh_expire = int(OAUTH_REFRESH_TOKEN_TIME.total_seconds())
+            now_stamp = int(time.time())
+            access_data = data
+            refresh_data = data
+            access_data['exp'] = access_expire + now_stamp
+            refresh_data['exp'] = refresh_expire + now_stamp
+            access_token = jwt.encode(access_data,
+                                      OAUTH_ACCESS_TOKEN_SECRET,
+                                      algorithm='HS256')
+            return access_token.decode('utf-8')
+        except Exception as e:
+            self.code = 309
+            print(repr(e))
+        else:
+            self.code = 0
+            return res
+
     def refresh(self):
     def refresh(self):
         if not self.token:
         if not self.token:
             self.code = 309
             self.code = 309

+ 201 - 0
Object/WechatPayObject.py

@@ -0,0 +1,201 @@
+import hashlib
+import time
+from urllib.parse import quote
+
+import requests
+import xmltodict
+
+
+class WechatPayObject:
+    """配置账号信息"""
+    # 微信公众号身份的唯一标识。审核通过后,在微信发送的邮件中查看
+
+    def __init__(self):
+        # 开发者调用支付统一下单API生成预交易单
+        self.APPID = 'wx2a9f5ef9baf2760f'
+        # 商户id
+        self.MCHID = '1508209741'
+        # 异步通知url,商户根据实际开发过程设定
+        self.NOTIFY_URL = 'test'
+        self.TRADE_TYPE = 'APP'
+        self.APIKEY = 'ZHansjeransjeransjer680301000000'
+        self.url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'  # 微信请求url
+        self.error = None
+        self.params = None
+
+    def get_parameter(self, order_id, body, total_fee, spbill_create_ip, notify_url, attach):
+        self.params = {
+            'appid': self.APPID,  # appid
+            'mch_id': self.MCHID,  # 商户号
+            'nonce_str': self.getNonceStr(),
+            'body': body,  # 商品描述
+            'out_trade_no': str(order_id),  # 商户订单号
+            'total_fee': str(int(total_fee)),
+            'spbill_create_ip': spbill_create_ip,  # 127.0.0.1
+            'trade_type': self.TRADE_TYPE,  # 交易类型
+            'notify_url': notify_url,  # 微信支付结果异步通知地址
+            'receipt': 'Y',
+            'attach' : attach
+        }
+        return self.params
+
+    def getNonceStr(self, length=32):
+        """生成随机字符串"""
+        import random
+        chars = "abcdefghijklmnopqrstuvwxyz0123456789"
+        strs = []
+        for x in range(length):
+            strs.append(chars[random.randrange(0, len(chars))])
+        return "".join(strs)
+
+    def key_value_url(self, value, urlencode):
+        """
+        将键值对转为 key1=value1&key2=value2
+        对参数按照key=value的格式,并按照参数名ASCII字典序排序
+        """
+        slist = sorted(value)
+        buff = []
+        for k in slist:
+            v = quote(value[k]) if urlencode else value[k]
+            buff.append("{0}={1}".format(k, v))
+
+        return "&".join(buff)
+
+    def get_sign(self, params):
+        """
+        生成sign
+        拼接API密钥
+        """
+        stringA = self.key_value_url(params, False)
+        stringSignTemp = stringA + '&key=' + self.APIKEY  # APIKEY, API密钥,需要在商户后台设置
+        sign = (hashlib.md5(stringSignTemp.encode("utf-8")).hexdigest()).upper()
+        params['sign'] = sign
+        return params
+
+    def get_req_xml(self):
+        """
+        拼接XML
+        """
+        self.get_sign(self.params)
+        xml = "<xml>"
+        for k, v in self.params.items():
+            # v = v.encode('utf8')
+            # k = k.encode('utf8')
+            xml += '<' + k + '>' + v + '</' + k + '>'
+        xml += "</xml>"
+        return xml.encode("utf-8")
+
+    def get_prepay_id(self):
+        """
+        请求获取prepay_id
+        """
+        xml = self.get_req_xml()
+        respone = requests.post(self.url, xml, headers={'Content-Type': 'application/xml'})
+        msg = respone.text.encode('ISO-8859-1').decode('utf-8')
+        xmlresp = xmltodict.parse(msg)
+        if xmlresp['xml']['return_code'] == 'SUCCESS':
+            if xmlresp['xml']['result_code'] == 'SUCCESS':
+                prepay_id = xmlresp['xml']['prepay_id']
+                self.params['prepay_id'] = prepay_id
+                self.params['packageId'] = "Sign=WXPay"
+                self.params['timestamp'] = str(int(time.time()))
+                return self.params
+            else:
+                return 'failure'
+        else:
+            return 'failure'
+
+    def re_finall(self,orderid = None):
+        """得到prepay_id后再次签名,返回给终端参数.
+        """
+        self.get_prepay_id()
+        if self.error:
+            return False
+        sign_again_params = {
+            'appid': self.params['appid'],
+            'noncestr': self.params['nonce_str'],
+            'package': self.params['packageId'],
+            'partnerid': self.params['mch_id'],
+            'timestamp': self.params['timestamp'],
+            'prepayid': self.params['prepay_id']
+        }
+        self.get_sign(sign_again_params)
+        sign_again_params['sign'] = sign_again_params['sign']
+        sign_again_params['packageId'] = sign_again_params['package']
+        sign_again_params['out_trade_no'] = orderid
+        return sign_again_params  # 返回给app
+
+    def get_notifypay(self, data):
+
+        success = self.get_sign(data)
+        # print('success', success)
+        if success:
+            success.pop("sign", None)
+            success.pop("sign_type", None)
+            # return success
+            return True
+        else:
+            return False
+
+    def weixinpay_call_back(self, data):
+
+        args = str(data, 'utf-8')
+
+        if args is None:
+            return None
+
+        print(args)
+
+        # 验证平台签名
+
+        resp_dict = self.handle_wx_response_xml(args)
+        if resp_dict is None:
+            print('签名验证失败!!!')
+            return None
+
+        return resp_dict
+
+    def handle_wx_response_xml(self, params):
+
+        """
+
+        处理微信支付返回的xml格式数据
+
+        """
+
+        try:
+
+            resp_dict = xmltodict.parse(params)['xml']
+
+            if not resp_dict or len(resp_dict) < 1:
+                print('resp_dict is zero+++++++++')
+
+                return None
+
+            return_code = resp_dict.get('return_code')
+
+            if return_code == 'SUCCESS':  # 仅仅判断通信标识成功,非交易标识成功,交易需判断result_code
+                return resp_dict
+
+
+        except Exception as e:
+            print(e)
+
+            return None
+
+        return None
+
+    @staticmethod
+    def xml_to_dict(params):
+        """
+        拼接XML
+        """
+        if not isinstance(params, dict):
+            return None
+        xml = "<xml>"
+        for k, v in params.items():
+            # v = v.encode('utf8')
+            # k = k.encode('utf8')
+            xml += '<' + k + '>' + v + '</' + k + '>'
+        xml += "</xml>"
+        return xml

+ 115 - 0
Object/uidManageResponseObject.py

@@ -0,0 +1,115 @@
+from django.shortcuts import HttpResponse
+import simplejson as json
+
+
+class uidManageResponseObject(object):
+
+    def __init__(self, lang='cn'):
+        self.lang = lang
+
+    def data(self, code, res={}):
+        data_cn = {
+            0: '成功',
+            5: '请一分钟后再尝试',
+            8: '用户账号已存在',
+            9: '用户账号不存在',
+            10: res,
+            42: '两次输入的新密码错误',
+            43: '客户端服务器已关闭,请下载新版本使用',
+            44: '系统错误,发送邮件失败',
+            45: '系统错误,生成令牌出错!',
+            46: '系统错误,发送短信失败!',
+            47: '旧密码不正确',
+            74: '关联旧用户失败!',
+            79: '您已经申请过重置密码,请到邮箱进行确认!',
+            89: '您已经获得了验证码,请在10分钟后检查或再次确认。',
+            99: '账户或密码错误',
+            101: '手机的用户账号已经存在!',
+            102: '手机的用户账号不存在!',
+            103: '邮箱用户帐户已经存在!',
+            104: '邮箱用户帐户不存在!',
+            107: '用户名格式不符合规则!',
+            108: '邮箱格式不符合规则!',
+            110: '因为用户未激活,用户是无效用户!',
+            111: '您输入的密码不正确!',
+            120: '验证码已过期或不存在、请重新获得验证码!',
+            121: '验证码错了!',
+            138: '手机格式不符合规则!',
+            173: '数据不存在!',
+            174: '数据已存在',
+            175: 'mac地址已用完',
+            176: '数据库异常',
+            305: '令牌格式是错误的,相关参数是不存在的!',
+            307: '令牌已过期!',
+            308: '此次下载已失效',
+            309: '你没有权限访问',
+            373: '没有相应的公司',
+            374: '没有相应的地区',
+            375: 'uid不足',
+            404: 'You don not have permission to access this!',
+            444: '请确认参数的正确性!',
+            1112: '您输入的两次密码不一致!',
+            208: '只能预定当天的或者以后的!',
+            10041: '已超出序列号剩余可绑定数'
+        }
+        data_en = {
+            0: 'Success',
+            5: 'Please try again one minute later!',
+            8: 'User accounts already exist',
+            9: 'User accounts is not exist',
+            10: res,
+            42: 'The new password entered twice is incorrect',
+            43: 'The client server is closed. Please download the new version for use',
+            44: 'System error,send email fail!',
+            45: 'System error,generate token fail!',
+            46: 'System error, sending SMS failed!',
+            47: 'Old password is incorrect',
+            74: 'Failed to connect old users!',
+            79: 'You have applied for reset password, please go to email for confirmation!',
+            89: 'You have already obtained the verification code, please check it or get it again after 10 minutes.',
+            99: ' ERROR Incorrect account or password',
+            101: 'The user account of the mobile phone has already existed!',
+            102: 'The user account of the mobile phone does not exist!',
+            103: 'The mailbox user account has already existed!',
+            104: 'The mailbox user account does not exist!',
+            107: 'The username format does not conform to the rules!',
+            108: 'The mailbox format does not conform to the rules! ',
+            110: 'Because the user is not activated, the user is an invalid user!',
+            111: 'The password you entered is incorrect!',
+            120: 'The captcha has expired or does not exist, please obtain the captcha again!',
+            121: 'The verification code is wrong!',
+            138: 'The phone format does not conform to the rules! ',
+            173: 'Data does not exists!',
+            174: 'Data already exists',
+            175: 'MAC address has been used up',
+            176: 'Database exception',
+            305: 'The Token format is wrong and the related parameter is None!',
+            307: 'The Token has expired!',
+            308: 'This download has expired!',
+            309: 'You have no access',
+            373: 'No corresponding company',
+            374: 'Region does not exist',
+            375: 'uid不足',
+            404: 'You don not have permission to access this!',
+            444: 'Please confirm the correctness of the parameters!',
+            1112: 'The two passwords you entered do not match!',
+            10041: 'The remaining number of serial numbers that can be bound has exceeded'
+        }
+
+        if self.lang == 'cn':
+            msg = data_cn
+        else:
+            msg = data_en
+        try:
+            message = msg[code]
+        except Exception as e:
+            message = '系统错误,code不存在'
+        return {'result_code': code, 'reason': message, 'result': res, 'error_code': code}
+
+    def formal(self, code, res={}):
+        formal_data = self.data(code, res)
+        return json.dumps(formal_data,ensure_ascii=False)
+
+    def json(self, code, res={}):
+        result = self.formal(code, res)
+        return HttpResponse(result)

+ 0 - 0
PushModel/__init__.py


+ 3 - 0
PushModel/admin.py

@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.

+ 5 - 0
PushModel/apps.py

@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class PushmodelConfig(AppConfig):
+    name = 'PushModel'

+ 0 - 0
PushModel/migrations/__init__.py


+ 3 - 0
PushModel/models.py

@@ -0,0 +1,3 @@
+from django.db import models
+
+# Create your models here.

+ 3 - 0
PushModel/tests.py

@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.

+ 3 - 0
PushModel/views.py

@@ -0,0 +1,3 @@
+from django.shortcuts import render
+
+# Create your views here.

+ 0 - 0
SerialModel/__init__.py


Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików