Эх сурвалжийг харах

Merge remote-tracking branch 'origin/master'

lhq 4 жил өмнө
parent
commit
93cc715e25
100 өөрчлөгдсөн 14553 нэмэгдсэн , 2336 устгасан
  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__
 /Ansjer/test/__pycache__
 /Ansjer/test/__init__.py
+/static/log/error.log
 /sdk_install
 /DB/mydata4vipday2.ipdb
 /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.
 @AUTHOR: ASJRD018
@@ -32,6 +32,8 @@ 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_SES_ACCESS_REGION_WEST = 'us-west-1'
+
 AWS_BUCKET = 'ansjertest'
 # 设定离线时间为5分钟
 OFF_LINE_TIME_DELTA = 5
@@ -67,6 +69,11 @@ 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']
+
 # 不同环境配置
 if SERVER_TYPE == 'Ansjer.local_settings':
     from Ansjer.config_local import *
@@ -74,6 +81,220 @@ elif SERVER_TYPE == 'Ansjer.test_settings':
     from Ansjer.config_test import *
 elif SERVER_TYPE == 'Ansjer.formal_settings':
     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
 JPUSH_CONFIG = {
     'com.ansjer.accloud_ab': {
@@ -126,35 +347,59 @@ FCM_CONFIG = {
     'com.ansjer.accloud_a': 'AAAAb9YP3rk:APA91bFm06w8b9OKQ0gz0iaWFuRqRIkvgAz6z7Gp3dBU_X-LNGJQd1hc1QR2W7QzBglF8SHtERA45a2lbdLRa5qv7hxfd6W_sJLBK7dA8jklsOQBvy505oUzTwMKWy4TwH-exps9KrhO',
     '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
 @Contact: chanjunkai@163.com
 """
+import os
+
 NGINX_RTMP_STAT = 'http://www.dvema.com/stat'
 SERVER_DOMAIN_SSL = 'https://www.dvema.com/'
 SERVER_DOMAIN = 'http://www.dvema.com/'
@@ -21,40 +23,101 @@ PAYPAL_CRD = {
     "client_id": "AdSRd6WBn-qLl9OiQHQuNYTDFSx0ZX0RUttqa58au8bPzoGYQUrt8bc6591RmH8_pEAIPijdvVYSVXyI",
     "client_secret": "ENT-J08N3Fw0B0uAokg4RukljAwO9hFHPf8whE6-Dwd8oBWJO8AWMgpdTKpfB1pOy89t4bsFEzMWDowm"
 }
+# PAYPAL_CRD = {
+#     "mode": "sandbox",  # sandbox or live
+#     "client_id": "AVLoQVq3xHZ6FrF4mxHwlCPgVBAw4Fw5RtMkuxmYd23SkUTIY643n2g3KdK-Al8wV05I28lza5uoQbAA",
+#     "client_secret": "EO8kRc8yioDk0i2Qq-QMcVFfwkmyMJorTvBSLDTnxDJJ_wb9VoM_0jkUY9iEng2Flp1ze8wQOGpH5nB2"
+# }
+
 DETECT_PUSH_DOMAIN = 'http://push.dvema.com/'
+DETECT_PUSH_DOMAINS = 'https://push.dvema.com/'
+DETECT_PUSH_DOMAIN_JIUAN = 'http://jiuan.push.dvema.com/'
+DETECT_PUSH_DOMAINS_JIUAN = 'https://jiuan.push.dvema.com/'
 # 数据库dyanamo品牌日志数据库
 USER_BRAND = 'user_brand'
 USER_BRAND_ALL = 'user_brand_all'
 
+# type =2
+JPUSH_CONFIG = {
+    'com.ansjer.accloud_ab': {
+        'Key': 'f0dc047e5e53fd14199de5b0',
+        'Secret': 'aa7f7db33e9f0a7f3871aa1c'},
+    'com.ansjer.adcloud_ab': {
+        'Key': '76d97b535185114985608234',
+        'Secret': 'c9a92b301043cc9c52778692'},
+    'com.ansjer.zccloud_ab': {
+        'Key': 'd9924f56d3cc7c6017965130',
+        'Secret': '869d832d126a232f158b5987'},
+    'com.ansjer.loocamccloud_ab': {
+        'Key': 'd1cc44797b4642b0e05304fe',
+        'Secret': 'c3e8b4ca8c576de61401e56a'},
+    'com.ansjer.loocamdcloud_ab': {
+        'Key': '76d97b535185114985608234',
+        'Secret': 'c9a92b301043cc9c52778692'},
+    'com.ansjer.zccloud_a': {
+        'Key': '57de2a80d68bf270fd6bdf5a',
+        'Secret': '3d354eb6a0b49c2610decf42'},
+    'com.ansjer.accloud_a': {
+        'Key': 'ff95ee685f49c0dc4013347b',
+        'Secret': 'de2c20959f5516fdeeafe78e'},
+    'com.ansjer.adcloud_a': {
+        'Key': '2e47eb1aee9b164460df3668',
+        'Secret': 'b9137d8d684bc248f1809b6d'},
+    'com.ansjer.loocamccloud_a': {
+        'Key': '23c9213215c7ca0ec945629b',
+        'Secret': '81e4b1e859cc8387e2e6c431'},
+    'com.ansjer.loocamdcloud_a': {
+        'Key': '1dbdd60a16e9892d6f68a073',
+        'Secret': '80a97690e7e043109059b403'},
+    'com.ansjer.customizedb_a': {
+        'Key': '9d79630aa49adfa291fe2568',
+        'Secret': '4d8ff52f88136561875a0212'},
+    'com.ansjer.customizedd_a': {
+        'Key': '8fc4f495685bde53341ee25d',
+        'Secret': 'f1da11fa466509fa2670fb66',
+    }
+}
+# type =1
+FCM_CONFIG = {
+    'com.ansjer.zccloud_a': 'AAAAb9YP3rk:APA91bHu8u-CTpcd0g6lKPo0WNVqCi8jZub1cPPbSAY9AucT1HxlF65ZDUko9iG8q2ch17bwu9YWHpK1xI1gHSRXCslLvZlXEmHZC0AG3JKg15XuUvlFKACIajUFV-pOeGRT8tM6-31I',
+    'com.ansjer.loocamccloud_a': 'AAAAb9YP3rk:APA91bFCgd-kbVmpK4EVpfdHH_PJZQCYTkOGnTZdIuBWEz2r7aMRsJYHOH3sB-rwcbaRWgnufTyjX9nGQxb6KxQbWVk4ah_H-M3IqGh6Mb60WQQAuR33V6g_Jes5pGL6ViuIxGHqVMaR',
+    'com.ansjer.loocamdcloud_a': 'AAAAb9YP3rk:APA91bGw2I2KMD4i-5T7nZO_wB8kuAOuqgyqe5rxmY-W5qkpYEx9IL2IfmC_qf6B_xOyjIDDSjckvMo-RauN__SEoxvAkis7042GRkoKpw7cjZ_H8lC-d50PC0GclPzccrOGFusyKbFY',
+    'com.ansjer.customizedb_a': 'AAAAb9YP3rk:APA91bE7kI4vcm-9h_CJNFlOZfc-xwP4Btn6AnjOrwoKV6fgYN7fdarkO76sYxVZiAbDnxsFfOJyP7vQfwyan6mdjuyD5iHdt_XgO22VqniC0vA1V4GJiCS8Tp7LxIX8JVKZl9I_Powt',
+    'com.ansjer.customizeda_a': 'AAAAb9YP3rk:APA91bF0HzizVWDc6dKzobY9fsaKDK4veqkOZehDXshVXs8pEEvNWjR_YWbhP60wsRYCHCal8fWN5cECVOWNMMzDsfU88Ty2AUl8S5FtZsmeDTkoGntQOswBr8Ln7Fm_LAp1VqTf9CpM',
+    'com.ansjer.customizedd_a': 'AAAAb9YP3rk:APA91bHkxOozJWBrlv3eNT0PgwosYENI9aM4Zuzd418cX-iKkpa1zFNC5MkNDKApx1KH4fhmAfaJ6IMRZ0nj5GIxCpstDYCaZWwgC7-etqfSxG5JAq8LOwJx0o_1tUZqwjIic8ztsg0o',
+    'com.ansjer.adcloud_a': 'AAAAb9YP3rk:APA91bFm06w8b9OKQ0gz0iaWFuRqRIkvgAz6z7Gp3dBU_X-LNGJQd1hc1QR2W7QzBglF8SHtERA45a2lbdLRa5qv7hxfd6W_sJLBK7dA8jklsOQBvy505oUzTwMKWy4TwH-exps9KrhO',
+    'com.ansjer.accloud_a': 'AAAAb9YP3rk:APA91bFm06w8b9OKQ0gz0iaWFuRqRIkvgAz6z7Gp3dBU_X-LNGJQd1hc1QR2W7QzBglF8SHtERA45a2lbdLRa5qv7hxfd6W_sJLBK7dA8jklsOQBvy505oUzTwMKWy4TwH-exps9KrhO',
+    'com.ansjer.zccloud_ab': 'AAAAb9YP3rk:APA91bHu8u-CTpcd0g6lKPo0WNVqCi8jZub1cPPbSAY9AucT1HxlF65ZDUko9iG8q2ch17bwu9YWHpK1xI1gHSRXCslLvZlXEmHZC0AG3JKg15XuUvlFKACIajUFV-pOeGRT8tM6-31I',
+}
 APNS_CONFIG = {
     'com.ansjer.loocamccloud': {
-        'pem_path': 'Ansjer/file/apns_pem/lcc.pem',
+        'pem_path': 'Ansjer/file/apns_pem/lcc-dev.pem',
     },
     'com.ansjer.zosidcloud': {
-        'pem_path': 'Ansjer/file/apns_pem/zosidcloud.pem',
+        'pem_path': 'Ansjer/file/apns_pem/zosidcloud-dev.pem',
     },
     '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': {
-        'pem_path': 'Ansjer/file/apns_pem/customizeda.pem',
+        'pem_path': 'Ansjer/file/apns_pem/customizeda-dev.pem',
     },
     'com.ansjer.zccloud': {
-        'pem_path': 'Ansjer/file/apns_pem/zccloud.pem',
+        'pem_path': 'Ansjer/file/apns_pem/zccloud-dev.pem',
     },
     'com.ansjer.accloud': {
         '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'
+# 根路径
+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'

+ 14 - 8
Ansjer/config_local.py

@@ -15,20 +15,23 @@
 OAUTH_ACCESS_TOKEN_SECRET = 'local_a+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'
-# 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 = {
     "mode": "sandbox",  # sandbox or live
     "client_id": "AeuhR7FHisO-lOd2OwtzyDu7PSLMmDZoDLgmzuEQ12WCtTu_8Z1AzcD4gG5SnymnuvJs-n5KBB8H9Z_G",
     "client_secret": "EGkMCB3RWTcUGJGDYahJ9mCO0AQzEn2AvFfx1GAFjfyyn7-8a0NObcZks89QorlFpvNWTsDXVa2INRNM"
 }
 DETECT_PUSH_DOMAIN = 'http://test.push.dvema.com/'
+DETECT_PUSH_DOMAINS = 'https://test.push.dvema.com/'
+DETECT_PUSH_DOMAIN_JIUAN = 'http://jiuan.push.dvema.com/'
+DETECT_PUSH_DOMAINS_JIUAN = 'https://jiuan.push.dvema.com/'
 # 数据库dyanamo品牌日志数据库
 USER_BRAND = 'test_user_brand'
 USER_BRAND_ALL = 'test_user_brand_all'
@@ -52,7 +55,10 @@ APNS_CONFIG = {
     },
     'com.ansjer.accloud': {
         'pem_path': 'Ansjer/file/apns_pem/accloud-dev.pem',
-    }
+    },
+    'com.ansjer.customizede': {
+        'pem_path': 'Ansjer/file/apns_pem/ZhouShi-dev.pem',
+    },
 }
 APNS_MODE = 'dev'
 TUTK_PUSH_DOMAIN = 'http://push.iotcplatform.com/tpns'

+ 72 - 0
Ansjer/config_test.py

@@ -11,6 +11,8 @@
 @file: config_test.py
 @Contact: chanjunkai@163.com
 """
+import os
+
 NGINX_RTMP_STAT = 'http://test.dvema.com/stat'
 SERVER_DOMAIN = 'http://test.dvema.com/'
 SERVER_DOMAIN_SSL = 'https://test.dvema.com/'
@@ -33,11 +35,71 @@ PAYPAL_CRD = {
     "client_id": "AVLoQVq3xHZ6FrF4mxHwlCPgVBAw4Fw5RtMkuxmYd23SkUTIY643n2g3KdK-Al8wV05I28lza5uoQbAA",
     "client_secret": "EO8kRc8yioDk0i2Qq-QMcVFfwkmyMJorTvBSLDTnxDJJ_wb9VoM_0jkUY9iEng2Flp1ze8wQOGpH5nB2"
 }
+# PAYPAL_CRD = {
+#     "mode": "sandbox",  # sandbox or live
+#     "client_id": "ATXTpWs8sajNYeU46jNs1yzpy4H_o3RRrGVIJ8Tscc312BjMx12cpRgCucfWX07a4G6GbK8hzElB04Pd",
+#     "client_secret": "EHcnfrpL1o1ev9WnlQ-C1uymeRKDoJ6li6Y0d6iHoRGj4u8Sx5lSEEH774XphP4LQZ0DrDUdvxbux0T2"
+# }
 DETECT_PUSH_DOMAIN = 'http://test.push.dvema.com/'
+DETECT_PUSH_DOMAINS = 'https://test.push.dvema.com/'
+DETECT_PUSH_DOMAIN_JIUAN = 'http://jiuan.push.dvema.com/'
+DETECT_PUSH_DOMAINS_JIUAN = 'https://jiuan.push.dvema.com/'
 # 数据库dyanamo品牌日志数据库
 USER_BRAND = 'test_user_brand'
 USER_BRAND_ALL = 'test_user_brand_all'
 
+# type =2
+JPUSH_CONFIG = {
+    'com.ansjer.accloud_ab': {
+        'Key': 'f0dc047e5e53fd14199de5b0',
+        'Secret': 'aa7f7db33e9f0a7f3871aa1c'},
+    'com.ansjer.adcloud_ab': {
+        'Key': '76d97b535185114985608234',
+        'Secret': 'c9a92b301043cc9c52778692'},
+    'com.ansjer.zccloud_ab': {
+        'Key': 'd9924f56d3cc7c6017965130',
+        'Secret': '869d832d126a232f158b5987'},
+    'com.ansjer.loocamccloud_ab': {
+        'Key': 'd1cc44797b4642b0e05304fe',
+        'Secret': 'c3e8b4ca8c576de61401e56a'},
+    'com.ansjer.loocamdcloud_ab': {
+        'Key': '76d97b535185114985608234',
+        'Secret': 'c9a92b301043cc9c52778692'},
+    'com.ansjer.zccloud_a': {
+        'Key': '57de2a80d68bf270fd6bdf5a',
+        'Secret': '3d354eb6a0b49c2610decf42'},
+    'com.ansjer.accloud_a': {
+        'Key': 'ff95ee685f49c0dc4013347b',
+        'Secret': 'de2c20959f5516fdeeafe78e'},
+    'com.ansjer.adcloud_a': {
+        'Key': '2e47eb1aee9b164460df3668',
+        'Secret': 'b9137d8d684bc248f1809b6d'},
+    'com.ansjer.loocamccloud_a': {
+        'Key': '23c9213215c7ca0ec945629b',
+        'Secret': '81e4b1e859cc8387e2e6c431'},
+    'com.ansjer.loocamdcloud_a': {
+        'Key': '1dbdd60a16e9892d6f68a073',
+        'Secret': '80a97690e7e043109059b403'},
+    'com.ansjer.customizedb_a': {
+        'Key': '9d79630aa49adfa291fe2568',
+        'Secret': '4d8ff52f88136561875a0212'},
+    'com.ansjer.customizedd_a': {
+        'Key': '8fc4f495685bde53341ee25d',
+        'Secret': 'f1da11fa466509fa2670fb66',
+    }
+}
+# type =1
+FCM_CONFIG = {
+    'com.ansjer.zccloud_a': 'AAAAb9YP3rk:APA91bHu8u-CTpcd0g6lKPo0WNVqCi8jZub1cPPbSAY9AucT1HxlF65ZDUko9iG8q2ch17bwu9YWHpK1xI1gHSRXCslLvZlXEmHZC0AG3JKg15XuUvlFKACIajUFV-pOeGRT8tM6-31I',
+    'com.ansjer.loocamccloud_a': 'AAAAb9YP3rk:APA91bFCgd-kbVmpK4EVpfdHH_PJZQCYTkOGnTZdIuBWEz2r7aMRsJYHOH3sB-rwcbaRWgnufTyjX9nGQxb6KxQbWVk4ah_H-M3IqGh6Mb60WQQAuR33V6g_Jes5pGL6ViuIxGHqVMaR',
+    'com.ansjer.loocamdcloud_a': 'AAAAb9YP3rk:APA91bGw2I2KMD4i-5T7nZO_wB8kuAOuqgyqe5rxmY-W5qkpYEx9IL2IfmC_qf6B_xOyjIDDSjckvMo-RauN__SEoxvAkis7042GRkoKpw7cjZ_H8lC-d50PC0GclPzccrOGFusyKbFY',
+    'com.ansjer.customizedb_a': 'AAAAb9YP3rk:APA91bE7kI4vcm-9h_CJNFlOZfc-xwP4Btn6AnjOrwoKV6fgYN7fdarkO76sYxVZiAbDnxsFfOJyP7vQfwyan6mdjuyD5iHdt_XgO22VqniC0vA1V4GJiCS8Tp7LxIX8JVKZl9I_Powt',
+    'com.ansjer.customizeda_a': 'AAAAb9YP3rk:APA91bF0HzizVWDc6dKzobY9fsaKDK4veqkOZehDXshVXs8pEEvNWjR_YWbhP60wsRYCHCal8fWN5cECVOWNMMzDsfU88Ty2AUl8S5FtZsmeDTkoGntQOswBr8Ln7Fm_LAp1VqTf9CpM',
+    'com.ansjer.customizedd_a': 'AAAAb9YP3rk:APA91bHkxOozJWBrlv3eNT0PgwosYENI9aM4Zuzd418cX-iKkpa1zFNC5MkNDKApx1KH4fhmAfaJ6IMRZ0nj5GIxCpstDYCaZWwgC7-etqfSxG5JAq8LOwJx0o_1tUZqwjIic8ztsg0o',
+    'com.ansjer.adcloud_a': 'AAAAb9YP3rk:APA91bFm06w8b9OKQ0gz0iaWFuRqRIkvgAz6z7Gp3dBU_X-LNGJQd1hc1QR2W7QzBglF8SHtERA45a2lbdLRa5qv7hxfd6W_sJLBK7dA8jklsOQBvy505oUzTwMKWy4TwH-exps9KrhO',
+    'com.ansjer.accloud_a': 'AAAAb9YP3rk:APA91bFm06w8b9OKQ0gz0iaWFuRqRIkvgAz6z7Gp3dBU_X-LNGJQd1hc1QR2W7QzBglF8SHtERA45a2lbdLRa5qv7hxfd6W_sJLBK7dA8jklsOQBvy505oUzTwMKWy4TwH-exps9KrhO',
+    'com.ansjer.zccloud_ab': 'AAAAb9YP3rk:APA91bHu8u-CTpcd0g6lKPo0WNVqCi8jZub1cPPbSAY9AucT1HxlF65ZDUko9iG8q2ch17bwu9YWHpK1xI1gHSRXCslLvZlXEmHZC0AG3JKg15XuUvlFKACIajUFV-pOeGRT8tM6-31I',
+}
 APNS_CONFIG = {
     'com.ansjer.loocamccloud': {
         'pem_path': 'Ansjer/file/apns_pem/lcc-dev.pem',
@@ -56,7 +118,17 @@ APNS_CONFIG = {
     },
     'com.ansjer.accloud': {
         'pem_path': 'Ansjer/file/apns_pem/accloud-dev.pem',
+    },
+    'com.ansjer.customizede': {
+        'pem_path': 'Ansjer/file/apns_pem/ZhouShi-dev.pem',
+    },
+    'com.ansjer.customizedc': {
+        'pem_path': 'Ansjer/file/apns_pem/customizedc.pem',
     }
 }
+# 根路径
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 APNS_MODE = 'dev'
+SERVER_TYPE = os.environ.get('DJANGO_SETTINGS_MODULE')
+
 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_APPS_MAPPING = {
-    'db1': 'default',
+    'Model': 'default',
     'db2': 'mysql02',
 }
 
+
 AUTH_PASSWORD_VALIDATORS = [
     {
         'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
@@ -169,8 +170,7 @@ CORS_ALLOW_HEADERS = (
 '''
 # 管理员邮箱
 ADMINS = (
-    ('admin', 'chanjunkai@163.com'),
-    ('admin', '1379072853@qq.com'),
+    ('admin', 'sonalh@foxmail.com'),
 )
 
 # 非空链接,却发生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)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': {
     },
@@ -206,10 +210,10 @@ LOGGING = {
         },
         'default': {
             'level': 'ERROR',
-            'class': 'logging.handlers.RotatingFileHandler',
-            'filename': BASE_DIR + '/static/log/error.log',
-            'maxBytes': 1024 * 1024 * 5,  # 5 MB
-            'backupCount': 5,
+            'class': 'logging.handlers.TimedRotatingFileHandler',
+            'filename': BASE_DIR + '/static/log/error/error.log',
+            'backupCount': 30,
+            'when': 'D',
             'formatter': 'error_format',
         },
         'console': {
@@ -217,22 +221,34 @@ LOGGING = {
             'class': 'logging.StreamHandler',
             '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': {
         'django': {
             'handlers': ['default', 'console'],
             # 'handlers': ['mail_admins','default','console'],
+            # 'level': 'ERROR',
             'level': 'ERROR',
             'propagate': False
         },
+        # log 调用时需要当作参数传入
+        'info': {
+            'handlers': ['info'],
+            'level':'INFO',
+            'propagate': False
+        }
+        # 'django.db.backends': {
+        #     'handlers': ['console'],
+        #     'propagate': True,
+        #     'level': 'DEBUG',
+        # },
     }
-}
+}

+ 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',
     'imagekit',
     'Model',
+    'PushModel',
+    'SerialModel',
 ]
 
 MIDDLEWARE = [
@@ -31,7 +33,7 @@ MIDDLEWARE = [
     'django.contrib.messages.middleware.MessageMiddleware',
     'django.middleware.clickjacking.XFrameOptionsMiddleware',
     'django.middleware.security.SecurityMiddleware',
-    'django_global_request.middleware.GlobalRequestMiddleware',
+    # 'django_global_request.middleware.GlobalRequestMiddleware',
 ]
 
 AUTHENTICATION_BACKENDS = (
@@ -72,17 +74,24 @@ TEMPLATES = [
 
 WSGI_APPLICATION = 'Ansjer.local_wsgi.application'
 
-
 # 服务器类型
-DATABASE_DATA = 'ansjerlocal'
+#业务数据库
+DATABASE_DATA = 'ansjertest'
 SERVER_HOST = '127.0.0.1'
 DATABASES_USER = 'root'
-DATABASES_PASS = '123456'
+DATABASES_PASS = 'root'
 
-DATABASE_DATA2 = 'asjl'
+#推送数据库
+DATABASE_DATA2 = 'ansjerpush'
 SERVER_HOST2 = '127.0.0.1'
 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 = {
     'default': {
@@ -104,15 +113,25 @@ DATABASES = {
         'PORT': '3306',
         'OPTIONS': {'charset': 'utf8mb4', 'use_unicode': True, 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"},
         'AUTOCOMMIT': True
-    }
+    },
+    'mysql03': {
+        'ENGINE': 'django.db.backends.mysql',
+        'NAME': DATABASE_DATA3,
+        'USER': DATABASES_USER3,
+        'PASSWORD': DATABASES_PASS3,
+        'HOST': SERVER_HOST3,
+        'PORT': '3306',
+        'OPTIONS': {'charset': 'utf8mb4', 'use_unicode': True, 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"},
+        'AUTOCOMMIT': True
+    },
 }
 DATABASE_ROUTERS = ['Ansjer.database_router.DatabaseAppsRouter']
 DATABASE_APPS_MAPPING = {
-    'db1': 'default',
-    'db2': 'mysql02',
+    'Model': 'default',
+    'PushModel': 'mysql02',
+    'SerialModel': 'mysql03',
 }
 
-
 AUTH_PASSWORD_VALIDATORS = [
     {
         'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
@@ -171,8 +190,7 @@ CORS_ALLOW_HEADERS = (
 '''
 # 管理员邮箱
 ADMINS = (
-    ('admin', 'chanjunkai@163.com'),
-    ('admin', '1379072853@qq.com'),
+    ('admin', 'sonalh@foxmail.com'),
 )
 
 # 非空链接,却发生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)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': {
     },
@@ -220,6 +244,16 @@ LOGGING = {
             'class': 'logging.StreamHandler',
             'formatter': 'error_format'
         },
+        # 输出info日志
+        'info': {
+            'level': 'INFO',
+            'class': 'logging.handlers.RotatingFileHandler',
+            'filename': BASE_DIR + '/static/log/info.log',
+            'maxBytes': 1024 * 1024 * 5,
+            'backupCount': 5,
+            'formatter': 'standard',
+            'encoding': 'utf-8',  # 设置默认编码
+        },
     },
     'loggers': {
         'django': {
@@ -229,6 +263,12 @@ LOGGING = {
             'level': 'DEBUG',
             'propagate': True
         },
+        # log 调用时需要当作参数传入
+        'log': {
+            'handlers': ['info', 'console', 'default'],
+            'level': 'INFO',
+            'propagate': True
+        },
         # 'django.db.backends': {
         #     'handlers': ['console'],
         #     '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',
     'imagekit',
     'Model',
+    'PushModel',
+    'SerialModel',
 ]
 
 MIDDLEWARE = [
@@ -74,11 +76,13 @@ WSGI_APPLICATION = 'Ansjer.test_wsgi.application'
 
 
 # 服务器类型
+#业务数据库
 DATABASE_DATA = 'AnsjerTest'
 SERVER_HOST = 'database-2.clraczw4p0yj.us-west-1.rds.amazonaws.com'
 DATABASES_USER = 'azrds'
 DATABASES_PASS = 'azrds.x.x'
 
+#推送数据库
 DATABASE_DATA2 = 'AnsjerTest'
 SERVER_HOST2 = 'ansjerpush.clraczw4p0yj.us-west-1.rds.amazonaws.com'
 DATABASES_USER2 = 'azrds'
@@ -104,11 +108,12 @@ DATABASES = {
         'PORT': '3306',
         'OPTIONS': {'charset': 'utf8mb4', 'use_unicode': True, 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"},
         'AUTOCOMMIT': True
-    }
+    },
 }
+
 DATABASE_ROUTERS = ['Ansjer.database_router.DatabaseAppsRouter']
 DATABASE_APPS_MAPPING = {
-    'db1': 'default',
+    'Model': 'default',
     'db2': 'mysql02',
 }
 
@@ -170,8 +175,7 @@ CORS_ALLOW_HEADERS = (
 '''
 # 管理员邮箱
 ADMINS = (
-    ('admin', 'chanjunkai@163.com'),
-    ('admin', '1379072853@qq.com'),
+    ('admin', 'sonalh@foxmail.com'),
 )
 
 # 非空链接,却发生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)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': {
     },
@@ -207,10 +215,10 @@ LOGGING = {
         },
         'default': {
             'level': 'ERROR',
-            'class': 'logging.handlers.RotatingFileHandler',
-            'filename': BASE_DIR + '/static/log/error.log',
-            'maxBytes': 1024 * 1024 * 5,  # 5 MB
-            'backupCount': 5,
+            'class': 'logging.handlers.TimedRotatingFileHandler',
+            'filename': BASE_DIR + '/static/log/error/error.log',
+            'backupCount': 30,
+            'when': 'D',
             'formatter': 'error_format',
         },
         'console': {
@@ -218,13 +226,34 @@ LOGGING = {
             'class': 'logging.StreamHandler',
             'formatter': 'error_format'
         },
+        'info': {
+            'level': 'INFO',
+            'class': 'logging.handlers.TimedRotatingFileHandler',
+            'filename': BASE_DIR + '/static/log/info/info.log',
+            'backupCount': 30,
+            'when': 'D',
+            'formatter': 'standard',
+            'encoding': 'utf-8',
+        },
     },
     'loggers': {
         'django': {
             'handlers': ['default', 'console'],
             # 'handlers': ['mail_admins','default','console'],
+            # 'level': 'ERROR',
             'level': 'ERROR',
             'propagate': False
         },
+        # log 调用时需要当作参数传入
+        'info': {
+            'handlers': ['info'],
+            'level':'INFO',
+            'propagate': False
+        }
+        # 'django.db.backends': {
+        #     'handlers': ['console'],
+        #     'propagate': True,
+        #     'level': 'DEBUG',
+        # },
     }
-}
+}

+ 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.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, \
     AppSetController, \
     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 = [
     url(r'^testApi/(?P<operation>.*)$', TestApi.testView.as_view()),
-
     url(r'^account/authcode$', UserController.authCodeView.as_view()),
     url(r'^v3/account/generatepictureCodeView/$', UserController.generatePictureCodeView.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/delete', EquipmentManager.deleteInterface),
+    url(r'^equipment/batchDelete', EquipmentManager.batchDeleteInterface),
     url(r'^equipment/add', EquipmentManager.addInterface),
     url(r'^equipment/admin_add', EquipmentManager.admin_addInterface),
     url(r'^equipment/admin_modify', EquipmentManager.admin_modifyInterface),
@@ -104,12 +112,14 @@ urlpatterns = [
     # 统计访问日志路径
     path('access/staticPath/', AccessLog.statisticsPath),
     path('access/deleteSn/', AccessLog.deleteSn),
-    path('eq/del', EquipmentInfo.deleteExpireEquipmentInfo),
+    path('eq/delById', EquipmentInfo.deleteExpireEquipmentInfoById),
     # 新需求ota接口
     url(r'^OTA/getNewVer', OTAEquipment.getNewVerInterface),
     url(r'^OTA/uploadsPack$', OTAEquipment.uploadOTAInterfaceView.as_view()),
     url(r'^OTA/downloadsPack/(?P<fullPath>[0-9\w/.\-]+)', OTAEquipment.downloadOTAInterface),
     url(r'^dlotapack/(?P<fullPath>[0-9\w/.\-]+)', OTAEquipment.downloadOTAInterfaceV2),
+    url(r'^OTA/getDownLoadOTApackUrl$', OTAEquipment.getDownLoadOTApackUrl),
+    url(r'^OTA/checkMaxVersion$', OTAEquipment.checkMaxVersion),
 
     # h获取验证码    # v2接口
     url(r'^v2/account/authcode$', UserController.v2authCodeView.as_view()),
@@ -131,11 +141,18 @@ urlpatterns = [
     url(r'^v3/account/loginByFingerprint$', UserController.v3LoginByFingerprintView.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/add$', DetectController.PushNotificationView.as_view()),
+    # 推送项目接口
     url(r'^detect/(?P<operation>.*)$', DetectController.DetectControllerView.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'^meal/(?P<operation>.*)$', MealManage.MealView.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/information/(?P<operation>.*)$', UserController.InitUserInformationView.as_view()),
     # 获取时区相关信息
     url(r'^getTZ$', EquipmentStatus.getTZ),
 
@@ -177,7 +195,10 @@ urlpatterns = [
     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),
 
     # ap模式,新增设备表
@@ -218,6 +239,8 @@ urlpatterns = [
     url(r'^v2/userbrand/(?P<operation>.*)$', UserBrandControllerV2.UserBrandV2.as_view()),
     url(r'^statistcs/appFrequencyMonth$', StatisticsController.statistcsAppFrequency),
     url(r'^statistcs/appFrequencyYear$', StatisticsController.statistcsAppFrequencyYear),
+    url(r'^statistcs/pushDay$', StatisticsController.statistcsPushDay),
+    url(r'^statistcs/pushMonth$', StatisticsController.statistcsPushMonth),
 
     #统计alexa连接数
     url(r'^alexa/(?P<operation>.*)$', Alexa.AlexaConnectNum.as_view()),
@@ -233,16 +256,71 @@ urlpatterns = [
 
     # 本地登录接口
     url(r'^local/(?P<operation>.*)$', UserController.LocalUserView.as_view()),
+
     url(r'^account/updateUserCountry', UserController.updateUserCountry),
     url(r'^equipmentVersionLimit/(?P<operation>.*)$', EquipmentVersionLimit.EquipmentVersionLimitView.as_view()),
 
     # 订阅邮件
     url(r'^account/subscribe$', UserController.SubscribeEmailView.as_view()),
+    url(r'^account/subscribe/download$', UserController.SubscribeEmailView.as_view()),
+
+    # 语音提示
+    url(r'^voicePrompt/(?P<operation>.*)$', VoicePromptController.VoicePromptView.as_view()),
+    # 设备类型
+    url(r'^deviceType/(?P<operation>.*)$', DeviceTypeController.DeviceTypeView.as_view()),
+
+    # cdk(激活码)
+    url(r'^cdk/(?P<operation>.*)$', CDKController.CDKView.as_view()),
+    # 云存转移功能
+    url(r'^cloudTransfer/(?P<operation>.*)$', CloudTransfer.cloudTestView.as_view()),
 
     # app 设备消息模板
     # 路由加参数参考
     # url(r'^(?P<path>.*)/(?P<UID>.*)/lls$', Test.Test.as_view(), name=u'gg'),
     #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),
 
 

+ 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=searchByAdmin&token=test&page=1&line=10&content={"status":20}&order=-id
 
+
+
 http://192.168.136.40:8077/accesslog/staticPath/?token=stest
 '''
 

+ 206 - 3
Controller/AdminManage.py

@@ -1,6 +1,8 @@
 # -*- coding: utf-8 -*-
 import time
+from datetime import date, timedelta, timezone as asj_timezone
 
+import boto3
 import xlwt
 from django.db.models import Count,Q
 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.utils.decorators import method_decorator
 from django.contrib.auth.hashers import make_password  # 对密码加密模块
+from openpyxl import workbook
+
 from Model.models import Device_Info, Role, UserExModel, User_Brand, UidSetModel, AppFrequencyYearStatisticsModel, \
-    AppFrequencyStatisticsModel
+    AppFrequencyStatisticsModel, EquipmentInfoExStatisticsModel, Equipment_Info
 from Service.ModelService import ModelService
 from django.utils import timezone
 from Model.models import Access_Log, Device_User
 from django.views.decorators.http import require_http_methods
 from Object.ResponseObject import ResponseObject
 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
 from Service.CommonService import CommonService
 from Object.RedisObject import RedisObject
@@ -80,6 +85,12 @@ class AdminManage(TemplateView):
             return self.getAppFrequency(userID, request_dict, response)
         if operation == 'getHistoryAppFrequency':
             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':
             return self.download_subscribe_email(userID, request_dict, response)
 
@@ -438,6 +449,196 @@ class AdminManage(TemplateView):
         else:
             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):
         own_permission = ModelService.check_perm(userID=userID, permID=30)
         if own_permission is not True:
@@ -462,6 +663,9 @@ class AdminManage(TemplateView):
         return response
 
 
+def getCompareKey(item):
+    return item['Timestamp']
+
 @require_http_methods(["GET"])
 def getUserIds(request):
     token = request.GET.get('token', None)
@@ -547,4 +751,3 @@ def search_user_by_content(request):
         sqlDict['count'] = count
         return response.json(0, sqlDict)
     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):
+        lang = request_dict.get('lang', None)
         appBundleId = request_dict.get('appBundleId', None)
         if not appBundleId:
             return response.json(444,'appBundleId')
@@ -64,19 +65,34 @@ class AppSetView(View):
             key_id= "www"+appBundleId
         else:
             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:
             print('添加到缓存')
             # 查数据库
             sm_qs = AppSetModel.objects.filter(appBundleId=appBundleId)
             count = sm_qs.count()
             if count > 0:
+
                 sm_qs = sm_qs.values("content")
                 # 添加到缓存,缓存时间为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)
                 # 返回固定值
-                return response.json(0, json.loads(list(sm_qs)[0]['content']))
+                return response.json(0, content_json_str)
             else:
                 return response.json(173)
         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
+
+
+
+
+

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 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 time
 import urllib
+
+import boto3
+
 from Object.AliPayObject import AliPayObject
 import oss2
 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, \
     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.TokenObject import TokenObject
 from Object.UidTokenObject import UidTokenObject
@@ -97,12 +100,6 @@ class CloudVodView(View):
             return self.do_pay_ok()
         elif operation == 'payError':
             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:
             token = request_dict.get('token', None)
             # 设备主键uid
@@ -111,9 +108,7 @@ class CloudVodView(View):
             if tko.code != 0:
                 return response.json(tko.code)
             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)
             elif operation == 'details':
                 return self.do_get_details(request_dict, response)
@@ -121,142 +116,11 @@ class CloudVodView(View):
                 return self.do_filter_playlist(request_dict, userID, response)
             elif operation == 'findVod':
                 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':
-                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:
                 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):
         uid = request_dict.get('uid', None)
         dvqs = Device_Info.objects.filter(UID=uid, isShare=False)
@@ -380,7 +244,7 @@ class CloudVodView(View):
     		color : green
     	}
     	.content_img{
-    		width: 60px; 
+    		width: 60px;
     		height: 60px;
     	}
     	.bottom{
@@ -420,7 +284,7 @@ class CloudVodView(View):
     function payOKButton() {
         // 复杂数据
         console.log('success')
-        window.webkit.messageHandlers.jsCallOC.postMessage({"status": 1});
+        window.location.href="https://test.dvema.com/closePage";
     }
 	</script>
 </body> 
@@ -428,344 +292,237 @@ class CloudVodView(View):
         '''
         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):
         uidToken = request_dict.get('uidToken', None)
         utko = UidTokenObject(uidToken)
         if utko.flag is False:
             return response.json(444, 'uidToken')
-        UID = utko.UID
+        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')
+        print(uid)
         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)
-        # 套餐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):
         paymentId = request_dict.get('paymentId', None)
@@ -777,6 +534,7 @@ class CloudVodView(View):
         paypalrestsdk.configure(PAYPAL_CRD)
         # ID of the payment. This ID is provided when creating payment.
         payment = paypalrestsdk.Payment.find(paymentId)
+        print(payment)
         payres = payment.execute({"payer_id": PayerID})
         print(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']})
         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)
-        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[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:
-                # 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:
-                    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:
-            response.content = falil_pay_content
-            return response
+            return response.json(804)
+
+
 
 
 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
 
 
-
 class DateConView(View):
     @method_decorator(csrf_exempt)
     def dispatch(self, *args, **kwargs):
@@ -51,382 +50,382 @@ class DateConView(View):
         else:
             return response.json(414)
 
-    def do_date(self, request_dict,response):
+    def do_date(self, request_dict, response):
         h = request_dict.get('h', None)
         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:
-            if i['dayStr']==h:
+            if i['dayStr'] == h:
                 print(i)
-                srt=i
+                srt = i
         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 pyfcm import FCMNotification
 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.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
 
 '''
 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)
 
 
-# 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):
 
     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):
-        response = ResponseObject()
+
         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'})
-            # return response.json(444)
         if etk:
             eto = ETkObject(etk)
             uid = eto.uid
@@ -366,20 +372,440 @@ class NotificationView(View):
         else:
             utko = UidTokenObject(uidToken)
             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):
@@ -441,136 +867,6 @@ class NotificationView(View):
         else:
             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):
         #
         qs_list = []
@@ -632,21 +928,38 @@ class PushNotificationView(View):
             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,!'}
+                res_data = {'code': 0, 'msg': 'success,!33333333333'}
                 return JsonResponse(status=200, data=res_data)
             else:
                 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)
                 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':
-                    return JsonResponse(status=200, data={'code': 0, 'msg': 'success'})
+                    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)
@@ -671,35 +984,87 @@ class PushNotificationView(View):
             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):
-        #
-        qs_list = []
-        nowTime = int(time.time())
+        now_time = int(time.time())
         # 设备昵称
         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 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 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:
-            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)
                 elif operation == 'deleteUser':
                     return self.do_delete_user(userID, request_dict, response)
+                elif operation == 'deleteUserV2':
+                    return self.do_delete_userV2(userID, request_dict, response)
                 else:
                     return response.json(414)
             else:
@@ -66,7 +68,7 @@ class DeviceShareView(View):
     def do_generate_token_url(self, userID, request_dict, response):
         UID = request_dict.get('UID', None)
         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:
             data = {'sharer': userID, 'UID': UID}
             # -----------------
@@ -85,10 +87,18 @@ class DeviceShareView(View):
                 share_user = userqs[0]['phone']
             else:
                 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, {
                 'shareToken': share_token,
                 'deviceName': dvqs[0]['NickName'],
                 'shareUser': share_user,
+                'userIconPath': userIconPath
             })
 
         else:
@@ -229,10 +239,21 @@ class DeviceShareView(View):
             try:
                 # redisObj = RedisObject(db=8)
                 # 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:
                 return response.json(10, repr(e))
             else:
                 return response.json(0)
         else:
             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():
             return response.json(14)
         try:
+
             nowTime = int(time.time())
             equipment_info = Equipment_Info(
                 userID_id=userID,
@@ -288,18 +289,30 @@ class EquipmentInfo(View):
 use information_schema;
 select concat(round(sum(data_length/1024/1024),2),'MB') as data from tables where table_schema='Ansjer81';
 '''
-# 按季度删除访问日志
+# 删除访问日志
 def deleteExpireEquipmentInfo(request):
     response = ResponseObject()
-    i = int(request.GET.get('i', 5))
-
     import 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)
 
 

+ 214 - 23
Controller/EquipmentManager.py

@@ -3,9 +3,12 @@ import time
 import traceback
 import threading
 import logging
+
+import requests
 import simplejson as json
 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 Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
@@ -16,6 +19,7 @@ from Object.ETkObject import ETkObject
 import oss2
 from django.http import JsonResponse
 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)
         # redisObj = RedisObject(db=8)
         # redisObj.del_data(key='uid_qs_' + userID)
+
         if dv_qs.exists():
             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()
+
             print('删除')
             UID_Preview.objects.filter(uid=uid).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.start()
+
     except Exception as e:
         errorInfo = traceback.format_exc()
         print('删除数据库记录错误: %s' % errorInfo)
@@ -360,6 +367,9 @@ def addInterface(request):
     View_Password = request_dict.get('View_Password', '')
     Type = request_dict.get('Type', 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]):
         tko = TokenObject(token)
         response.lang = tko.lang
@@ -380,10 +390,67 @@ def addInterface(request):
                     asy.start()
                     return response.json(10, 'illegal uid: {uid}'.format(uid=UID))
                 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:
                     # 判断是否有用户绑定
                     nowTime = int(time.time())
@@ -396,16 +463,34 @@ def addInterface(request):
                             'ip': CommonService.get_ip_address(request),
                             'channel': ChannelIndex,
                             'nickname': NickName,
+                            'version': version,
                         }
                         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)
+                                             View_Password=View_Password, Type=Type, ChannelIndex=ChannelIndex,
+                                             version=version, vodPrimaryUserID=vodPrimaryUserID, vodPrimaryMaster=vodPrimaryMaster)
                     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)
                 except Exception as e:
                     return response.json(10, repr(e))
@@ -414,14 +499,26 @@ def addInterface(request):
                                                                     'View_Account',
                                                                     'View_Password', 'ChannelIndex', 'Type',
                                                                     'isShare',
-                                                                    'primaryUserID', 'primaryMaster',
+                                                                    'primaryUserID', 'primaryMaster', 'vodPrimaryUserID', 'vodPrimaryMaster', 'userID__userEmail',
                                                                     'data_joined', 'version',
-                                                                    'isVod', 'isExist')
+                                                                    '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)
+
+
+                    # 新增获取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)
 
 
@@ -430,7 +527,7 @@ def addInterface(request):
         else:
             return response.json(tko.code)
     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,
                                    args=(CommonService.get_ip_address(request), userID, 'deleteV2', uid))
             asy.start()
+            if userID == dv_qs[0].vodPrimaryUserID:
+                Device_Info.objects.filter(UID=uid).update(vodPrimaryUserID='', vodPrimaryMaster='')
+
             if dv_qs[0].isShare:
                 dv_qs.delete()
             else:
@@ -689,6 +789,7 @@ def deleteInterface(request):
                 dv_qs.delete()
                 # 删除设备影子信息uid_set   外键关联删除设备推送配置信息 uid_push
                 up_qs = UidPushModel.objects.filter(uid_set__uid=uid)
+                DetectControllerView().do_delete_redis(uid)
                 if up_qs.count() > 1:
                     UidPushModel.objects.filter(uid_set__uid=uid, userID_id=userID).delete()
                     redisObj = RedisObject(db=6, SERVER_HOST='push.dvema.com')
@@ -697,10 +798,8 @@ def deleteInterface(request):
                         redisObj.del_data(key=ykey)
                 else:
                     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.start()
@@ -715,6 +814,71 @@ def deleteInterface(request):
     else:
         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):
@@ -749,14 +913,23 @@ def queryInterface(request):
         # count = dvqs.count()
         dvql = dvqs[(page - 1) * line:page * line].values('id', 'userID', 'NickName', 'UID', 'View_Account',
                                                           'View_Password', 'ChannelIndex', 'Type', 'isShare',
-                                                          'primaryUserID', 'primaryMaster', 'data_joined', 'version',
-                                                          'isVod', 'isExist', 'NotificationMode')
+                                                          'primaryUserID', 'primaryMaster', 'data_joined', 'version', 'vodPrimaryUserID', 'vodPrimaryMaster', 'userID__userEmail',
+                                                          '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'])
-            # 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). \
             values('bucket__content', 'status', 'channel', 'endTime', 'uid')
         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'],
                                   'nickname': us['nickname'],
                                   'detect_interval': us['detect_interval']}
+
         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']:
@@ -1010,10 +1196,15 @@ def update_device_shadow(request):
         is_reset = request_dict.get('is_reset', None)
         # 传1则重置设备信息
         if is_reset == '1':
+
             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缓存
             # data = di_qs.values()
             # 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 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.TokenObject import TokenObject
 from Service.CommonService import CommonService
@@ -146,15 +147,24 @@ class EquipmentManagerV2(View):
             dvql = dvqs[(page - 1) * line:page * line]. \
                 values('id', 'userID', 'NickName', 'UID', 'View_Account',
                        'View_Password', 'ChannelIndex', 'Type', 'isShare',
-                       'primaryUserID', 'primaryMaster', 'data_joined',
+                       'primaryUserID', 'primaryMaster', 'data_joined', 'vodPrimaryUserID', 'vodPrimaryMaster', 'userID__userEmail',
                        'version',
-                       'isVod', 'isExist', 'NotificationMode')
+                       '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'])
-                # 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). \
                 values('bucket__content', 'status', 'channel', 'endTime', 'uid')
             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())
             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 = {}
             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:
+                # 新增云分配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'] = []
                 for dm in ubqs:
                     if p['UID'] == dm['uid']:
@@ -185,6 +214,8 @@ class EquipmentManagerV2(View):
                     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['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']:
                         p['NickName'] = uv_dict[p_uid]['nickname']
@@ -202,7 +233,149 @@ class EquipmentManagerV2(View):
 
     def do_query_reset(self, userID, request_dict, response):
         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 time
 import traceback
+
+import requests
+
 from Controller.CheckUserData import RandomStr
 import oss2, base64
 from django.db.models import Q
 from django.views.generic.base import View
+from Controller.DeviceConfirmRegion import Device_Region
 from Object.RedisObject import RedisObject
 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.TokenObject import TokenObject
 from Service.CommonService import CommonService
 from Service.ModelService import ModelService
-import time,json
+import time, json
+
 
 class EquipmentManagerV3(View):
 
@@ -24,6 +30,7 @@ class EquipmentManagerV3(View):
 
     def post(self, request, *args, **kwargs):
         request.encoding = 'utf-8'
+
         operation = kwargs.get('operation')
         return self.validation(request.POST, request, operation)
 
@@ -31,111 +38,212 @@ class EquipmentManagerV3(View):
         response = ResponseObject()
         token = request_dict.get('token', None)
         # 设备主键uid
+
+        if operation == 'notLoginMainUserDevice':
+            return self.not_login_do_mainUserDevice(request_dict, response)
+
         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)
+        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):
-        token = request_dict.get('token', None)
         UID = request_dict.get('UID', None)
         NickName = request_dict.get('NickName', None)
         View_Account = request_dict.get('View_Account', None)
         View_Password = request_dict.get('View_Password', '')
+        encrypt_pass = View_Password
         print("准备解密")
         View_Password = self.decode_pwd(View_Password)
         Type = request_dict.get('Type', 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:
-                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:
-            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):
         token = request_dict.get('token', None)
@@ -150,10 +258,11 @@ class EquipmentManagerV3(View):
         userID = tko.userID
         if userID is None:
             return response.json(309)
+        deviceData = None
+        dev_info_qs = None
         try:
             # deviceData = json.loads(deviceContent)
             deviceData = eval(deviceContent)
-
             if deviceData.__contains__('userID_id'):
                 asy = threading.Thread(target=ModelService.update_log,
                                        args=(CommonService.get_ip_address(request), userID, 'modifyV3', deviceData, id))
@@ -165,6 +274,7 @@ class EquipmentManagerV3(View):
 
             # print(deviceData['View_Password'])
             if deviceData.__contains__('View_Password'):
+                encrypt_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.update(**deviceData)
@@ -176,15 +286,12 @@ class EquipmentManagerV3(View):
             res = CommonService.qs_to_dict(qs)
             if qs.exists():
                 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
                 # 增加设备影子信息修改昵称 start
                 us_qs = UidSetModel.objects.filter(uid=uid)
                 if us_qs.exists():
-                    us_qs.update(nickname=nickname)
+                    if deviceData.__contains__('NickName'):
+                        us_qs.update(nickname=nickname)
                 else:
                     ChannelIndex = qs[0].ChannelIndex
                     nowTime = int(time.time())
@@ -200,13 +307,24 @@ class EquipmentManagerV3(View):
                 di_qs = Device_Info.objects.filter(UID=uid)
                 di_qs.update(NickName=nickname)
                 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()
             # redisObj = RedisObject(db=8)
             # redisObj.del_data(key='uid_qs_' + userID)
             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):
         token = request_dict.get('token', None)
@@ -223,167 +341,373 @@ class EquipmentManagerV3(View):
         response.lang = tko.lang
         if page <= 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 = []
+                # 设备拓展信息表
+                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):
-                    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:
-            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):
             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')
             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')
             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')
         return userPwd
 
@@ -408,4 +732,87 @@ class EquipmentManagerV3(View):
                 password = password.decode('utf-8')
                 # 去前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 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.TokenObject import TokenObject
 from Object.UrlTokenObject import UrlTokenObject
@@ -63,22 +64,21 @@ class EquipmentOTA(View):
 
     def delete(self, request_dict, userID, response):
         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)
         if not own_perm:
             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)
         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:
             return response.json(176, repr(e))
         else:
@@ -284,6 +284,23 @@ class EquipmentVersionView(View):
             # 判断大小
             if ov > eqs[0].softwareVersion:
                 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
         if file_path.find('static/Upgrade/') != -1:
             path = file_path.replace('static/Upgrade/', '').replace('\\', '/')

+ 12 - 1
Controller/EquipmentStatus.py

@@ -12,6 +12,8 @@
 @Contact: chanjunkai@163.com
 """
 import base64
+import json
+import threading
 import urllib.parse
 import time
 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 Model.models import Device_Info
 from Object.ETkObject import ETkObject
+from Object.RedisObject import RedisObject
 from Object.ResponseObject import ResponseObject
+from Service.ModelService import ModelService
 from Service.CommonService import CommonService
 
 '''
@@ -109,7 +113,13 @@ def getTZ(request):
         uid = c.decode('utf-8')
         if len(uid) == 20:
             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)
             else:
                 info = CommonService.getIpIpInfo(ip=ip, lang=lang,update=False)
@@ -124,6 +134,7 @@ def getTZ(request):
                 elif len(tz) == 8:
                     gmtz = tz.replace('UTC-', 'GMT-0').replace('UTC+', 'GMT+0')
                     info['gmt_offset'] = gmtz
+                redisObject.set_data(key=ip, val=json.dumps(info), expire=3600)
             except Exception as e:
                 pass
             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 traceback
 
+from django.core import serializers
 from django.http import HttpResponse
 from django.utils.decorators import method_decorator
 from django.views.decorators.csrf import csrf_exempt
@@ -20,7 +21,8 @@ from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 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):
@@ -168,9 +170,9 @@ class FAQView(View):
     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 != 'zositechHelp':
+            if token.code != 0:
+                return response.json(token.code)
         if operation == 'add':
             return self.do_add(token, request_dict, response)
         elif operation == 'query':
@@ -179,6 +181,10 @@ class FAQView(View):
             return self.do_update(token, request_dict, response)
         elif operation == 'delete':
             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:
             return response.json(404)
 
@@ -321,4 +327,67 @@ class FAQView(View):
             else:
                 return response.json(0)
         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)
             elif operation == 'deleteByAdmin':
                 return self.do_delete_by_admin(userID, request_dict, response)
+            elif operation == 'deleteImage':
+                return self.do_delete_image(userID, request_dict, response)
             else:
                 return response.json(414)
         else:
@@ -264,3 +266,36 @@ class FeedBackView(View):
                 return response.json(0)
         else:
             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
 
+from django.db.models import F
 from django.utils import timezone
 from django.utils.decorators import method_decorator
 from django.views.decorators.csrf import csrf_exempt
 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.TokenObject import TokenObject
 from Service.CommonService import CommonService
@@ -68,19 +69,36 @@ class MealManage(View):
             return self.delete(request_dict, userID, response)
         elif operation == 'find':
             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:
             return response.json(444, 'operation')
 
     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)
         price = request_dict.get('price', None)
-        content = request_dict.get('content', None)
+        # content = request_dict.get('content', None)
         day = request_dict.get('day', None)
+        commodity_code = request_dict.get('commodity_code', None)
         currency = request_dict.get('currency', 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')
         own_perm = ModelService.check_perm(userID=userID, permID=40)
         if own_perm is not True:
@@ -89,9 +107,13 @@ class MealManage(View):
             bucketQs = VodBucketModel.objects.filter(id=bucketID)
             if Store_Meal.objects.filter(id=id):
                 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()
+            paytype = paytype.split(',')
+            if len(paytype) > 0:
+                Store_Meal.objects.get(id=id).pay_type.set(paytype)
         except Exception:
             errorInfo = traceback.format_exc()
             print(errorInfo)
@@ -102,42 +124,63 @@ class MealManage(View):
                     'bucket__bucket': bucketQs[0].bucket,
                     'bucket__storeDay': bucketQs[0].storeDay,
                     'id': id,
-                    'title': title,
                     'price': price,
-                    'content': content,
                     'currency': currency,
                     'day': day,
                     'add_time': str(store_meal.add_time),
                     'update_time': str(store_meal.update_time)})
 
     def query(self, request_dict, response):
-
         page = int(request_dict.get('page', None))
         line = int(request_dict.get('line', None))
+        lang = request_dict.get('lang', 'cn')
         if page is None or line is None:
             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 = {}
+        items_list = []
         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)
 
     def update(self, request_dict, userID, response):
         id = request_dict.get('id', None)
-        title = request_dict.get('title', None)
+        # title = request_dict.get('title', None)
         price = request_dict.get('price', 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)
         bucketID = request_dict.get('bucketID', None)
         commodity_type = request_dict.get('commodity_type', 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)
-        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)
         if own_perm is not True:
             return response.json(404)
@@ -145,18 +188,29 @@ class MealManage(View):
             store_meal = Store_Meal.objects.get(id=id)
             now_time = timezone.localtime(timezone.now())
             print(now_time)
-            store_meal.title = title
+            # store_meal.title = title
             store_meal.price = price
-            store_meal.content = content
+            # store_meal.content = content
             store_meal.commodity_type = commodity_type
             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.type = type
             if bucketID:
                 store_meal.bucket_id = bucketID
             if currency:
                 store_meal.currency = currency
             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:
             errorInfo = traceback.format_exc()
             print(errorInfo)
@@ -198,6 +252,93 @@ class MealManage(View):
             return response.json(0, send_json)
         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). \
                 values("id", "title", "content", "price", "day", "currency",
                        "bucket__storeDay", "bucket__bucket", "bucket__area",
-                       "type")
+                       "type", "symbol")
         else:
             qs = Store_Meal.objects.all(). \
                 values("id", "title", "content", "price", "day", "currency",
                        "bucket__storeDay", "bucket__bucket", "bucket__area",
-                       "type")
+                       "type", "symbol")
         if qs.exists():
             ql = list(qs)
             from operator import itemgetter
@@ -266,4 +407,4 @@ class MealView(View):
             }
             return response.json(0, result)
         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)
     uid = request_dict.get('uid', None)
     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')
     tko = TokenObject(token)
     response.lang = tko.lang
@@ -494,7 +494,7 @@ def getNewVerInterface(request):
 
     if equipmentValid.exists():
         equipment = equipmentValid[0]
-        redisObject = RedisObject(db=3)
+        redisObject = RedisObject()
         key = 'limit_{eid}'.format(eid=equipment.eid)
 
         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)
         if evl_qs and len(evl_qs) > 0:
             evl = evl_qs[0]
-            if evl['type'] == 1:  # uid限制
+            if evl['type'] == 1: # uid限制
                 uids = json.loads(evl['content'])
                 if not uids.__contains__(uid):
                     return response.json(902)
-            elif evl['type'] == 2:  # user限制
+            elif evl['type'] == 2: # user限制
                 users = json.loads(evl['content'])
                 if not users.__contains__(tko.userID):
                     return response.json(902)
-            elif evl['type'] == 3:  # 国家地区限制
+            elif evl['type'] == 3: # 国家地区限制
                 countries = json.loads(evl['content'])
                 country_ip_qs = CountryIPModel.objects.filter(user_ex__userID=tko.userID)
                 if country_ip_qs.exists():
@@ -538,10 +538,10 @@ def getNewVerInterface(request):
             #     url = SERVER_DOMAIN + 'dlotapack/' + file_path
             # else:
             #     这里调用国内服务器进行下载,防止下载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, {
                 'ver': ver,
                 'url': url,
@@ -685,3 +685,74 @@ def downloadOTAInterfaceV2(request, fullPath, *callback_args, **callback_kwargs)
             return res.json(907)
     else:
         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
 """
 import time
+
+import paypalrestsdk
+from django.db.models import F
 from django.utils.decorators import method_decorator
 from django.views.decorators.csrf import csrf_exempt
 from django.views.generic.base import View
+
+from Ansjer.config_test import PAYPAL_CRD
+from Object.AliPayObject import AliPayObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Model.models import Order_Model, Device_Info
@@ -50,7 +56,7 @@ class OrderView(View):
         token = request_dict.get('token', None)
         # 设备主键uid
         tko = TokenObject(token)
-        response.lang = tko.lang
+        response.lang = request_dict.get('language', 'en')
         if tko.code != 0:
             return response.json(tko.code)
         userID = tko.userID
@@ -62,6 +68,14 @@ class OrderView(View):
             return self.do_admin_query(request_dict, userID, response)
         elif operation == 'detail':
             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:
             return response.json(444, 'error path')
 
@@ -77,11 +91,12 @@ class OrderView(View):
         page = request_dict.get('page', None)
         line = request_dict.get('line', None)
         uid = request_dict.get('uid', None)
+        lang = request_dict.get('lang', 'en')
         if not page or not line:
             return response.json(444, 'page,line')
         page = int(page)
         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的订单
         if uid:
             omqs.filter(UID=uid)
@@ -89,12 +104,13 @@ class OrderView(View):
             return response.json(173)
             # return response.json(10, '订单不存在')
         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",
                                                               "addTime",
-                                                              "updTime", "endTime", "paypal", "rank__day", "payType",
+                                                              "updTime", "paypal", "rank__day", "payType",
                                                               "rank__price", "status",
                                                               "rank__content", "rank__title", "rank__currency",
-                                                              "rank_id")
+                                                              "rank_id","rank__expire")
         order_list = list(order_ql)
         data = []
         nowTime = int(time.time())
@@ -112,6 +128,7 @@ class OrderView(View):
                     d['did'] = did['id']
                     d['Type'] = did['Type']
                     data.append(d)
+            d['rank__expire_unit'] = '月' if lang == 'cn' else 'month'
         return response.json(0, {'data': data, 'count': count})
 
     # admins ^^^^^^^^^^^^
@@ -134,7 +151,7 @@ class OrderView(View):
             orderID = request_dict.get('orderID', None)
             page = int(page)
             line = int(line)
-            omqs = Order_Model.objects.filter()
+            omqs = Order_Model.objects.all()
             # 筛选指定设备id的订单
             if uid:
                 omqs = omqs.filter(UID=uid)
@@ -146,14 +163,149 @@ class OrderView(View):
                 return response.json(0, [])
             count = omqs.count()
             order_ql = omqs[(page - 1) * line:page * line].values("orderID", "UID", "channel", "desc", "price",
-                                                                  "currency", "addTime", "updTime", "endTime", "paypal",
+                                                                  "currency", "addTime", "updTime", "paypal",
                                                                   "payType",
                                                                   "rank__day",
-                                                                  "rank__price", "status",
-                                                                  "rank__content", "rank__title", "rank__currency",
-                                                                  "rank_id")
+                                                                  "rank__price", "status")
             order_list = list(order_ql)
             return response.json(0, {'data': order_list, 'count': count})
 
         else:
             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 Model.models import UserAppFrequencyModel, AppFrequencyStatisticsModel, Device_User, \
-    AppFrequencyYearStatisticsModel
+    AppFrequencyYearStatisticsModel, Equipment_Info, EquipmentInfoExStatisticsModel
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 
@@ -40,13 +40,17 @@ def statistcsAppFrequency(request):
 
     time_struct = [current_year, 1, 1, 0, 0, 0, 0, 0, 0]
 
+    distance_time = 8 * 60 * 60
+
     # 该月的开始时间
     time_struct[1] = current_month
     start_time = time.mktime(tuple(time_struct))
+    start_time = start_time - time.timezone - distance_time
 
     # 该月的结束时间
     time_struct[1] = current_month + 1
     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) \
@@ -135,3 +139,120 @@ def statistcsAppFrequencyYear(request):
         }
         AppFrequencyYearStatisticsModel.objects.create(**data)
     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:
         userID = tko.userID
         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()
         res = {
             'sm_count': sm_count,  # 系统消息未读数量

+ 0 - 1
Controller/SysMsg.py

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

+ 75 - 6
Controller/TestApi.py

@@ -21,6 +21,7 @@ import json
 import math
 import time
 import urllib
+import datetime
 from Object.AliPayObject import AliPayObject
 import logging
 import boto3
@@ -29,6 +30,9 @@ from botocore.exceptions import ClientError
 import oss2
 import paypalrestsdk
 import logging
+import requests
+import hashlib
+import hmac
 from aliyunsdkcore import client
 from aliyunsdksts.request.v20150401 import AssumeRoleRequest
 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.generic.base import View
 from django.contrib.auth.hashers import make_password, check_password  # 对密码加密模块
-
 from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, OSS_ROLE_ARN, SERVER_DOMAIN, PAYPAL_CRD, \
     SERVER_DOMAIN_SSL
-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.TokenObject import TokenObject
 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/'
 ACCESS_KEY = "AKIA2E67UIMD3CYTIWPA"
 SECRET_KEY = "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"
@@ -77,8 +81,8 @@ class testView(View):
         if operation is None:
             return response.json(444, 'error path')
         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':
             return self.createBucket()
         elif operation == 'vodList':
@@ -96,8 +100,17 @@ class testView(View):
         elif operation == 'getAlexa':
             userID = '158943594633713800138000'
             return self.queryInterface(request_dict, userID, response)
+        elif operation == 'generateToken':
+            userID = '158943604783713800138000'
+            return self.generate_token(request_dict,userID)
+        elif operation == '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:
-            return 12344444
+            return 123
 
     def createBucket(self):
 
@@ -431,7 +444,7 @@ class testView(View):
     def do_get_sign_sts(self, request_dict, ip, response):
         # uid = 'GZL2PEFJPLY7W6BG111A'
         # channel = 2
-        uid = 'VVDHCVBYDKFMJRWA111A'
+        uid = '86YC8Z192VB1VMKU111A'
         channel = 1
         now_time = int(time.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']})
         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 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.TokenObject import TokenObject
 from Service.CommonService import CommonService
@@ -87,6 +88,10 @@ class UidSetView(View):
             return self.do_update_set(request, request_dict, response)
         elif operation == 'updateChannel':
             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':
         #     return self.do_test(response)
         else:
@@ -410,6 +415,99 @@ class UidSetView(View):
         else:
             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):
     #     di_qs = Device_Info.objects.values('Type').annotate(c=Count('UID', distinct=True)).order_by()
     #     for di in di_qs:

+ 164 - 85
Controller/UserController.py

@@ -14,7 +14,7 @@
 import datetime
 import traceback
 import time
-
+import logging
 import jwt
 import simplejson
 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 Controller.CheckUserData import DataValid, date_handler, RandomStr
 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.AliSmsObject import AliSmsObject
 from Object.RedisObject import RedisObject
@@ -49,7 +49,6 @@ from PIL import Image, ImageDraw, ImageFont
 from django.shortcuts import HttpResponse
 from Ansjer.config import BASE_DIR
 
-
 # 获取验证码
 class authCodeView(TemplateView):
 
@@ -173,6 +172,9 @@ class registerView(TemplateView):
         password = request_dict.get('userPwd', None)
         authCode = request_dict.get('identifyingCode', None)
         language = request_dict.get('language', None)
+        unique = request_dict.get('unique', None)
+        if unique:
+            delete_local_account(unique)
         response = ResponseObject(language)
         if username and password and authCode:
             # 过滤空格
@@ -286,7 +288,6 @@ class registerView(TemplateView):
         else:
             return response.json(109)
 
-
 # 登出
 class LogoutView(TemplateView):
     @method_decorator(csrf_exempt)
@@ -858,6 +859,10 @@ class v2registerView(TemplateView):
         password = request_dict.get('password', None)
         authcode = request_dict.get('authcode', 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)
         if not lang:
             lang = request_dict.get('language', None)
@@ -866,13 +871,13 @@ class v2registerView(TemplateView):
         if authcode is None:
             return response.json(444, 'identifyingCode')
         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:
-            return self.do_email_register(email, password, authcode, response)
+            return self.do_email_register(email, password, authcode, number, response)
         else:
             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()
         if data_valid.mobile_validate(phone) is not True:
             return response.json(100)
@@ -891,15 +896,19 @@ class v2registerView(TemplateView):
         if phone_qs.exists():
             return response.json(101)
         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:
             errorInfo = traceback.format_exc()
             print(errorInfo)
@@ -938,7 +947,7 @@ class v2registerView(TemplateView):
         print(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()
         if data_valid.email_validate(email) is not True:
             return response.json(105)
@@ -957,15 +966,18 @@ class v2registerView(TemplateView):
         if email_qs.exists():
             return response.json(103)
         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:
             errorInfo = traceback.format_exc()
             print(errorInfo)
@@ -999,6 +1011,8 @@ class v3registerView(TemplateView):
         authcode = request_dict.get('authcode', 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)
@@ -1045,13 +1059,13 @@ class v3registerView(TemplateView):
             if authcode is None:
                 return response.json(444, 'identifyingCode')
             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:
-                return self.do_email_register(email, password, authcode, response)
+                return self.do_email_register(email, password, authcode, number, response)
             else:
                 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()
         if data_valid.mobile_validate(phone) is not True:
             return response.json(100)
@@ -1070,15 +1084,20 @@ class v3registerView(TemplateView):
         if phone_qs.exists():
             return response.json(101)
         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:
             errorInfo = traceback.format_exc()
             print(errorInfo)
@@ -1116,7 +1135,7 @@ class v3registerView(TemplateView):
         res['phone'] = user_list[0]["phone"] if user_list[0]["phone"] is not None else ''
         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()
         if data_valid.email_validate(email) is not True:
             return response.json(105)
@@ -1130,20 +1149,25 @@ class v3registerView(TemplateView):
         # 验证码是否正确
         if authcode != identifyingCode:
             return response.json(121)
+
         email_qs = Device_User.objects.filter(Q(userEmail=email) | Q(username=email))
         # 是否已存在
         if email_qs.exists():
             return response.json(103)
         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:
             errorInfo = traceback.format_exc()
             print(errorInfo)
@@ -1765,8 +1789,7 @@ class v3LoginView(TemplateView):
             user_qs.update(subscribe_email=subscribe)
 
         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']):
             return response.json(111)
         userID = users['userID']
@@ -1778,6 +1801,7 @@ class v3LoginView(TemplateView):
         if oauth_qs.exists():
             auth_type = oauth_qs[0].authType
 
+
         if tko.code == 0:
             now_time = datetime.datetime.utcnow().replace(tzinfo=utc).astimezone(utc)
             user_qs.update(last_login=now_time, language=response.lang)
@@ -1829,8 +1853,7 @@ class InitInfoView(View):
         else:
             return response.json(tko.code)
 
-        # 初始化设备token
-
+    # 初始化设备token
     def init_info(self, request_dict, userID, response, request):
         # 未读的系统消息
         token_val = request_dict.get('token_val', None)
@@ -2706,39 +2729,41 @@ class alexaUidView(TemplateView):
             return response.json(107)
 
     def validates(self, request_dict, response):
-        userID = request_dict.get('alexa_user_id')
         sid = request_dict.get('sid')
         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)
+        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")  # 设置字体
         print("字体可以")
         valid_code_str = ''
-        for i in range(5):
+        for i in range(6):
             random_num = str(random.randint(0, 9))
             random_low_alpha = chr(random.randint(97, 122))
             random_high_alpha = chr(random.randint(65, 90))
             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
@@ -2914,6 +2939,7 @@ class Image_Code_RegisterView(TemplateView):
         response = ResponseObject(lang)
         valid_code = request_dict.get('id_v_code', None)
         unique = request_dict.get('unique', None)
+        number = request_dict.get('number', None)
         if unique:
             delete_local_account(unique)
         if not all([userEmail, password, lang, imageCodeId, valid_code]):
@@ -2990,6 +3016,8 @@ class Image_Code_RegisterView(TemplateView):
             "is_active": True,
             "user_isValid": True,
         }
+        if number:
+            create_data["region_country"] = number
         users = Device_User.objects.create(**create_data)
         return self.do_login(email_qs, response)
 
@@ -3244,6 +3272,7 @@ class v3LoginByCodeView(View):
         if oauth_qs.exists():
             auth_type = oauth_qs[0].authType
 
+
         if tko.code == 0:
             now_time = datetime.datetime.utcnow().replace(tzinfo=utc).astimezone(utc)
             user_qs.update(last_login=now_time, language=response.lang)
@@ -3412,12 +3441,13 @@ class AppleAuthLogin(View):
 
         response = ResponseObject(lang)
         identity_token = CommonService.decode_data(identity_token)
+        # print(identity_token)
         if identity_token:
             key_url = 'https://appleid.apple.com/auth/keys'
             key_response = requests.get(key_url).json()
-            print(key_response)
+            # print(key_response)
             head = jwt.get_unverified_header(identity_token)
-            print(head)
+            # print(head)
             token_key = head['kid']
             key_object = None
             alg = None
@@ -3491,6 +3521,7 @@ class AppleAuthLogin(View):
         if oauth_qs.exists():
             auth_type = oauth_qs[0].authType
         res['authType'] = auth_type
+
         user_qs.update(last_login=now_time, online=True)
         return response.json(0, res)
 
@@ -3695,3 +3726,51 @@ def updateUserCountry(request):
         # CountryIPModel.objects.filter(id__in=tuple(ids)).update(status=1)
     response = ResponseObject()
     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.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.TokenObject import TokenObject
 from Service.ModelService import ModelService
+from django.db import transaction
 import time
 
 
@@ -239,13 +241,16 @@ class UidBucketView(View):
             id = request_dict.get('id', None)
             page = int(request_dict.get('page', 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:
             return response.json(10, repr(e))
         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:
             User = Device_User.objects.filter(**fieldDict).order_by('-data_joined')
         if User.exists():
-            ddUser = User[0].device_info_set.all()
+            ddUser = User[0].device_info_set.filter(isShare=False)
             sqlJSON = serializers.serialize('json', User)
             sqlList = json.loads(sqlJSON)
             if ddUser:
@@ -107,7 +107,7 @@ class searchUserView(View):
                 for k, v in enumerate(sqlDict["datas"]):
                     for val in device_user_res:
                         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_user关联到device_info
                             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 Service.CommonService import CommonService
 from django.contrib.auth.models import BaseUserManager, AbstractBaseUser
 from django.db import models
 from django.utils import six, timezone
@@ -22,7 +21,7 @@ class PermissionsManager(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
 
@@ -119,7 +118,6 @@ class Role(models.Model):
             permslist.sort()
             return permslist
 
-
 class Device_User(AbstractBaseUser):
     userID = models.CharField(blank=True, max_length=32, primary_key=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)
     fingerprint_enable = models.SmallIntegerField(default=0, verbose_name=u'是否开启了指纹登录') # 0:未开启,1:已开启
     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()
 
     USERNAME_FIELD = 'userID'  # 必须有一个唯一标识
@@ -206,6 +205,7 @@ class Device_User(AbstractBaseUser):
 
 # 设备表是建项目开发者设计的,自己看着办
 # 谢谢提醒!我选择凉拌。
+# 我选择狗带
 class Device_Info(models.Model):
     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)
@@ -228,6 +228,8 @@ class Device_Info(models.Model):
                                   help_text=u'是否为共享获取的设备', default=False)
     primaryUserID = models.CharField(blank=True, verbose_name='主用户id', max_length=32, 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)
     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)
     isVod = models.SmallIntegerField(blank=True, default=0, verbose_name='是否支持云存')  # 是否支持云存设备
     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 = []
 
@@ -290,8 +294,9 @@ class Equipment_Info(models.Model):
     alarm = models.CharField(blank=True, max_length=256, 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'接收到报警时间')
-    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,视频
+    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')
     # 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:失败')
@@ -308,7 +313,6 @@ class Equipment_Info(models.Model):
         ordering = ('-id',)
         app_label = "db2"
 
-
 class StatResModel(models.Model):
     id = models.AutoField(primary_key=True, verbose_name='自动ID')
     name = models.CharField(default='', max_length=120, verbose_name='图片名称', unique=True)
@@ -391,17 +395,19 @@ class User_Brand(models.Model):
 # 存储通表
 class VodBucketModel(models.Model):
     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='存储生命周期(天)')
     content = models.TextField(verbose_name='描述', default='')
     endpoint = models.CharField(max_length=125, default='', verbose_name='存储节点')
     area = models.CharField(max_length=16, default='', verbose_name='区域')
     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)
     updTime = models.IntegerField(verbose_name='更新时间', default=0)
 
     mold = models.SmallIntegerField(default=0, verbose_name='存储区域类型')  # 0:国内阿里 1:国外aws
+    region_id = models.IntegerField(default=1, verbose_name='大洲编号')
 
     def __str__(self):
         return self.id
@@ -415,18 +421,33 @@ class VodBucketModel(models.Model):
 
 class Store_Meal(models.Model):
     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'价格')
-    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)
-    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)
     bucket = models.ForeignKey(VodBucketModel, blank=True, to_field='id', on_delete=models.CASCADE,
                                default=1, verbose_name='存储空间')
     commodity_type = models.SmallIntegerField(default=0, verbose_name='云存储套餐类型')  # 0:事件型 1:连续型
     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):
         return self.id
@@ -438,6 +459,38 @@ class Store_Meal(models.Model):
         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):
     eid = models.CharField(blank=True, max_length=32, primary_key=True)
     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):
     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)
     UID = models.CharField(max_length=20, verbose_name='设备UID')
     channel = models.SmallIntegerField(default=0, verbose_name=u'通道数')
     desc = models.CharField(max_length=50, default='', 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)
     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')
     payTime = models.IntegerField(verbose_name='支付成功时间', default=0)
     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的字段')
     commodity_type = models.SmallIntegerField(default=0, 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')
 
+    # 备用字段
+    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):
         return self.orderID
@@ -550,14 +610,14 @@ class Order_Model(models.Model):
 
 class VodHlsModel(models.Model):
     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='通道')
     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)
     bucket = models.ForeignKey(VodBucketModel, blank=True, to_field='id', on_delete=models.CASCADE, default=1,
                                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):
@@ -591,7 +651,7 @@ class OssCrdModel(models.Model):
 
 class StsCrdModel(models.Model):
     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='通道')
     data = models.TextField(verbose_name='设备sts')
     addTime = models.IntegerField(verbose_name='添加时间', default=0)
@@ -611,11 +671,15 @@ class StsCrdModel(models.Model):
 
 class UID_Bucket(models.Model):
     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='通道')
     bucket = models.ForeignKey(VodBucketModel, blank=True, to_field='id', on_delete=models.CASCADE, verbose_name='存储空间')
     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:
         db_table = 'vod_uid_bucket'
@@ -623,6 +687,23 @@ class UID_Bucket(models.Model):
         verbose_name_plural = verbose_name
         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):
     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='')
     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,不支持
-    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
     nickname = models.CharField(default='', max_length=64, verbose_name='设备昵称')
     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'无线名称')
     isDetector = models.SmallIntegerField(default=0, verbose_name=u'侦测开关0:关闭,1:开启')
     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:
         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')
     userID = models.ForeignKey(Device_User, to_field='userID', 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')
     uid = models.ForeignKey(UidSetModel, to_field='id', on_delete=models.CASCADE)
     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:开启')
     mic_audio = models.SmallIntegerField(default=0, verbose_name='mic声音。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秒')
     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_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_vol = models.IntegerField(default=0, verbose_name='报警音量')  # 音量值0-100
     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:
         db_table = 'uid_channel'
@@ -998,6 +1095,22 @@ class AppLogModel(models.Model):
         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):
     id = models.AutoField(primary_key=True)
     ip = models.CharField(default='', max_length=32, verbose_name='ip')
@@ -1012,6 +1125,33 @@ class CountryIPModel(models.Model):
         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):
     id = models.AutoField(primary_key=True)
     type = models.SmallIntegerField(default=0, verbose_name='限制类型')
@@ -1024,4 +1164,405 @@ class EquipmentVersionLimitModel(models.Model):
     class Meta:
         db_table = 'equipment_version_limit'
         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

+ 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"}
         # code = isv.BUSINESS_LIMIT_CONTROL 一分钟只能发一次
         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.send_sign_in_sms(phone=13119657713,code=123456)

+ 3 - 0
Object/ETkObject.py

@@ -32,6 +32,9 @@ class ETkObject(object):
             if len(uid) == 20:
                 self.uid = uid
                 print(uid)
+            elif len(uid) == 14:
+                self.uid = uid
+                print(uid)
         except Exception as 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):
         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):
         return self.CONN.llen(name=name)

+ 58 - 0
Object/ResponseObject.py

@@ -41,6 +41,7 @@ class ResponseObject(object):
             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!',
@@ -56,6 +57,10 @@ class ResponseObject(object):
             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!',
@@ -69,6 +74,30 @@ class ResponseObject(object):
             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',
+            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 = {
             0: '成功',
@@ -104,6 +133,7 @@ class ResponseObject(object):
             177: '更新错误',
             178: '增加错误',
             179: '名称不能重复',
+            201: '最多只能添加3条自定义语音',
             306: '链接已超过有效期!',
             309: '请重新登录!',
             404: '您没有访问的权限!',
@@ -119,6 +149,10 @@ class ResponseObject(object):
             712: '区域不一致',
             713: '有效期内不可更改存储规则',
             717: '授权过期',
+            800: '订单不存在',
+            801: '退款金额不能大于订单价格',
+            802: '订单已完成,不能撤销',
+            804: '订单已退款,请勿重复操作',
             900: '版本信息不存在',
             901: '获取链接失败',
             902: '无更新!',
@@ -132,6 +166,30 @@ class ResponseObject(object):
             10004: '请求方法不正确。请联系开发者',
             10005: '配置错误,客户编号这个值是错误的',
             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':
             msg = data_cn

+ 24 - 4
Object/TokenObject.py

@@ -43,10 +43,10 @@ class TokenObject:
             self.lang = res.get('lang', None)
             self.user = res.get('user', '')
             # 刷新登录时间
-            if self.userID:
-                print(self.user)
-                redisObj = RedisObject(db=3)
-                redisObj.set_data(key=self.userID, val=self.user, expire=300)
+            # if self.userID:
+            #     print(self.user)
+            #     redisObj = RedisObject(db=3)
+            #     redisObj.set_data(key=self.userID, val=self.user, expire=300)
 
         except jwt.ExpiredSignatureError as e:
             print('过期')
@@ -97,6 +97,26 @@ class TokenObject:
             self.code = 0
             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):
         if not self.token:
             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


Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно