Browse Source

Merge branch 'pzb'

# Conflicts:
#	Service/TemplateService.py
#	Service/middleware.py
pzb 5 năm trước cách đây
mục cha
commit
bbfdcb11ad
41 tập tin đã thay đổi với 2957 bổ sung920 xóa
  1. 59 42
      Ansjer/config.py
  2. 35 0
      Ansjer/config_formal.py
  3. 41 0
      Ansjer/config_local.py
  4. 44 0
      Ansjer/config_test.py
  5. 0 64
      Ansjer/file/apns_pem/apns-dev-test.pem
  6. 0 67
      Ansjer/file/apns_pem/apns-dev.pem
  7. 0 41
      Ansjer/file/apns_pem/apns-dev_nw.pem
  8. 0 41
      Ansjer/file/apns_pem/apns-loocamccloud.pem
  9. 68 0
      Ansjer/file/apns_pem/lcc-dev.pem
  10. 68 0
      Ansjer/file/apns_pem/lcc.pem
  11. 2 1
      Ansjer/test/.cache/v/cache/lastfailed
  12. 8 0
      Ansjer/test/kbt.py
  13. 17 4
      Ansjer/urls.py
  14. 1 1
      Controller/AccessLog.py
  15. 115 37
      Controller/AppInfo.py
  16. 1 1
      Controller/CheckUserData.py
  17. 311 191
      Controller/DetectController.py
  18. 22 19
      Controller/DeviceShare.py
  19. 147 0
      Controller/DynamoDBLog.py
  20. 0 92
      Controller/EquipmentInfo.py
  21. 14 12
      Controller/EquipmentManager.py
  22. 35 8
      Controller/EquipmentOTA.py
  23. 1 1
      Controller/EquipmentStatus.py
  24. 22 6
      Controller/FeedBack.py
  25. 39 14
      Controller/OTAEquipment.py
  26. 40 6
      Controller/SysManage.py
  27. 75 4
      Controller/SysMsg.py
  28. 13 19
      Controller/Test.py
  29. 50 9
      Controller/UidSetController.py
  30. 609 202
      Controller/UserBrandController.py
  31. 656 13
      Controller/UserController.py
  32. 6 4
      Controller/shareUserPermission.py
  33. 48 5
      Model/models.py
  34. 61 0
      Object/AWS/DynamodbObject.py
  35. 8 0
      Object/ResponseObject.py
  36. 1 1
      Object/TokenObject.py
  37. 11 5
      Service/CommonService.py
  38. 312 1
      Service/MiscellService.py
  39. 11 2
      Service/ModelService.py
  40. 2 3
      Service/TemplateService.py
  41. 4 4
      Service/middleware.py

+ 59 - 42
Ansjer/config.py

@@ -17,12 +17,16 @@ import datetime, os
 SERVER_TYPE = os.environ.get('DJANGO_SETTINGS_MODULE')
 print(SERVER_TYPE)
 
+# 亚马逊的数据库DynamoDB的密钥
+AWS_DynamoDB_REGION = 'us-west-1'
+AWS_DynamoDB_ACCESS_KEY = 'AKIA2E67UIMD6X23FEBG'
+AWS_DynamoDB_SECRET_KEY = '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'
+
 # 阿里云发邮箱
 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'
@@ -35,6 +39,7 @@ 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)
@@ -60,47 +65,59 @@ OSS_ROLE_ARN = 'acs:ram::1901342792446414:role/stsoss'
 
 # 不同环境配置
 if SERVER_TYPE == 'Ansjer.local_settings':
-    NGINX_RTMP_STAT = 'http://192.168.136.45:8077/stat'
-    SERVER_DOMAIN = 'http://192.168.136.45:8077/'
-    SERVER_DOMAIN_SSL = 'http://192.168.136.45:8077/'
-    SERVER_HOST = '192.168.136.45'
-    DOMAIN_HOST = '192.168.136.45'
-    RTMP_PUSH_URL = 'rtmp://192.168.136.45: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/'
-
+    from Ansjer.config_local import *
 elif SERVER_TYPE == 'Ansjer.test_settings':
-    NGINX_RTMP_STAT = 'http://test.dvema.com/stat'
-    SERVER_DOMAIN = 'http://test.dvema.com/'
-    SERVER_DOMAIN_SSL = 'https://test.dvema.com/'
-
-    DOMAIN_HOST = 'test.dvema.com'
-    SERVER_HOST = 'localhost'
-    PAYPAL_CRD = {
-        "mode": "live",  # sandbox or live
-        "client_id": "AdSRd6WBn-qLl9OiQHQuNYTDFSx0ZX0RUttqa58au8bPzoGYQUrt8bc6591RmH8_pEAIPijdvVYSVXyI",
-        "client_secret": "ENT-J08N3Fw0B0uAokg4RukljAwO9hFHPf8whE6-Dwd8oBWJO8AWMgpdTKpfB1pOy89t4bsFEzMWDowm"
-        # "mode": "sandbox",  # sandbox or live
-        # "client_id": "AeuhR7FHisO-lOd2OwtzyDu7PSLMmDZoDLgmzuEQ12WCtTu_8Z1AzcD4gG5SnymnuvJs-n5KBB8H9Z_G",
-        # "client_secret": "EGkMCB3RWTcUGJGDYahJ9mCO0AQzEn2AvFfx1GAFjfyyn7-8a0NObcZks89QorlFpvNWTsDXVa2INRNM"
-    }
-    DETECT_PUSH_DOMAIN = 'http://test.push.dvema.com/'
-
+    from Ansjer.config_test import *
 elif SERVER_TYPE == 'Ansjer.formal_settings':
-    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"
+    from Ansjer.config_formal import *
+# 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',
     }
-    DETECT_PUSH_DOMAIN = 'http://push.dvema.com/'
-
-
+}
+# 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'
+}

+ 35 - 0
Ansjer/config_formal.py

@@ -0,0 +1,35 @@
+#!/usr/bin/env python3  
+# -*- coding: utf-8 -*-  
+"""
+@Copyright (C) ansjer cop Video Technology Co.,Ltd.All rights reserved.
+@AUTHOR: ASJRD018
+@NAME: AnsjerFormal
+@software: PyCharm
+@DATE: 2019/10/16 9:45
+@Version: python3.6
+@MODIFY DECORD:ansjer dev
+@file: config_formal.py
+@Contact: chanjunkai@163.com
+"""
+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/'
+# 数据库dyanamo品牌日志数据库
+USER_BRAND = 'user_brand'
+USER_BRAND_ALL = 'user_brand_all'
+
+APNS_CONFIG = {
+    'com.ansjer.loocamccloud': {
+        'pem_path': 'Ansjer/file/apns_pem/lcc.pem',
+        'password': '111111'
+    }
+}
+APNS_MODE = 'prod'

+ 41 - 0
Ansjer/config_local.py

@@ -0,0 +1,41 @@
+#!/usr/bin/env python3  
+# -*- coding: utf-8 -*-  
+"""
+@Copyright (C) ansjer cop Video Technology Co.,Ltd.All rights reserved.
+@AUTHOR: ASJRD018
+@NAME: AnsjerFormal
+@software: PyCharm
+@DATE: 2019/10/16 9:45
+@Version: python3.6
+@MODIFY DECORD:ansjer dev
+@file: config_local.py
+@Contact: chanjunkai@163.com
+"""
+# token的secret
+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.45:8077/stat'
+SERVER_DOMAIN = 'http://192.168.136.45:8077/'
+SERVER_DOMAIN_SSL = 'http://192.168.136.45:8077/'
+SERVER_HOST = '192.168.136.45'
+DOMAIN_HOST = '192.168.136.45'
+RTMP_PUSH_URL = 'rtmp://192.168.136.45: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/'
+# 数据库dyanamo品牌日志数据库
+USER_BRAND = 'test_user_brand'
+USER_BRAND_ALL = 'test_user_brand_all'
+
+
+APNS_CONFIG = {
+    'com.ansjer.loocamccloud': {
+        'pem_path': 'Ansjer/file/apns_pem/lcc-dev.pem',
+        'password': '111111'
+    }
+}
+APNS_MODE = 'dev'

+ 44 - 0
Ansjer/config_test.py

@@ -0,0 +1,44 @@
+#!/usr/bin/env python3  
+# -*- coding: utf-8 -*-  
+"""
+@Copyright (C) ansjer cop Video Technology Co.,Ltd.All rights reserved.
+@AUTHOR: ASJRD018
+@NAME: AnsjerFormal
+@software: PyCharm
+@DATE: 2019/10/16 9:45
+@Version: python3.6
+@MODIFY DECORD:ansjer dev
+@file: config_test.py
+@Contact: chanjunkai@163.com
+"""
+NGINX_RTMP_STAT = 'http://test.dvema.com/stat'
+SERVER_DOMAIN = 'http://test.dvema.com/'
+SERVER_DOMAIN_SSL = 'https://test.dvema.com/'
+
+
+# token的secret
+OAUTH_ACCESS_TOKEN_SECRET = 'test_a+jbgnw%@1%zy^=@dn62%'
+OAUTH_REFRESH_TOKEN_SECRET = 'test_r+jbgnw%@1%zy^=@dn62%'
+
+DOMAIN_HOST = 'test.dvema.com'
+SERVER_HOST = 'localhost'
+PAYPAL_CRD = {
+    "mode": "live",  # sandbox or live
+    "client_id": "AdSRd6WBn-qLl9OiQHQuNYTDFSx0ZX0RUttqa58au8bPzoGYQUrt8bc6591RmH8_pEAIPijdvVYSVXyI",
+    "client_secret": "ENT-J08N3Fw0B0uAokg4RukljAwO9hFHPf8whE6-Dwd8oBWJO8AWMgpdTKpfB1pOy89t4bsFEzMWDowm"
+    # "mode": "sandbox",  # sandbox or live
+    # "client_id": "AeuhR7FHisO-lOd2OwtzyDu7PSLMmDZoDLgmzuEQ12WCtTu_8Z1AzcD4gG5SnymnuvJs-n5KBB8H9Z_G",
+    # "client_secret": "EGkMCB3RWTcUGJGDYahJ9mCO0AQzEn2AvFfx1GAFjfyyn7-8a0NObcZks89QorlFpvNWTsDXVa2INRNM"
+}
+DETECT_PUSH_DOMAIN = 'http://test.push.dvema.com/'
+# 数据库dyanamo品牌日志数据库
+USER_BRAND = 'test_user_brand'
+USER_BRAND_ALL = 'test_user_brand_all'
+
+APNS_CONFIG = {
+    'com.ansjer.loocamccloud': {
+        'pem_path': 'Ansjer/file/apns_pem/lcc-dev.pem',
+        'password': '111111'
+    }
+}
+APNS_MODE = 'dev'

+ 0 - 64
Ansjer/file/apns_pem/apns-dev-test.pem

@@ -1,64 +0,0 @@
-Bag Attributes
-    friendlyName: Apple Development IOS Push Services: com.ansjer.loocamccloud
-    localKeyID: 88 F8 4C E3 C3 6E E8 8E 07 D4 F6 FD 04 7E 79 A4 93 4F 7E 82 
-subject=/UID=com.ansjer.loocamccloud/CN=Apple Development IOS Push Services: com.ansjer.loocamccloud/OU=JCHT67XT68/C=US
-issuer=/C=US/O=Apple Inc./OU=Apple Worldwide Developer Relations/CN=Apple Worldwide Developer Relations Certification Authority
------BEGIN CERTIFICATE-----
-MIIFkzCCBHugAwIBAgIIYwaKq6f2DAEwDQYJKoZIhvcNAQEFBQAwgZYxCzAJBgNV
-BAYTAlVTMRMwEQYDVQQKDApBcHBsZSBJbmMuMSwwKgYDVQQLDCNBcHBsZSBXb3Js
-ZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9uczFEMEIGA1UEAww7QXBwbGUgV29ybGR3
-aWRlIERldmVsb3BlciBSZWxhdGlvbnMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkw
-HhcNMTkwNjI2MDU1MzM5WhcNMjAwNjI1MDU1MzM5WjCBkjEnMCUGCgmSJomT8ixk
-AQEMF2NvbS5hbnNqZXIubG9vY2FtY2Nsb3VkMUUwQwYDVQQDDDxBcHBsZSBEZXZl
-bG9wbWVudCBJT1MgUHVzaCBTZXJ2aWNlczogY29tLmFuc2plci5sb29jYW1jY2xv
-dWQxEzARBgNVBAsMCkpDSFQ2N1hUNjgxCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG
-9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwjdrw+8hKwbPbgsK8z3WhOX6ZlWE1xB3EK8M
-GmVdluRco4/utE31gheJXmRCTGrOVyoLwls2zmlzv51KNG5/h0M9ltN4JIJMvlWx
-au0EJp6PM/cVTBbJ2ssY8SdaW2nxUoWcbiYVcBs2WXqzQYtXs3GH5nFYWH47LQ4w
-bMqBUnhzPdqHLT4u+CVXCK/LcRpnMT9Vepve8vLchakgpGRXOOWta5Yg5G4KgQKT
-j62IpHhBmGD+2Vq14odVsb0GmlFCHHVYqQ88a/0cL9pb0wqQnzxdeyguAtfvK3VM
-4o+dGshx7/U9fpwtmTeVfpsRbejy0UVLavQ/qO1OyVxJgKxmywIDAQABo4IB5TCC
-AeEwCQYDVR0TBAIwADAfBgNVHSMEGDAWgBSIJxcJqbYYYIvs67r2R1nFUlSjtzCC
-AQ8GA1UdIASCAQYwggECMIH/BgkqhkiG92NkBQEwgfEwgcMGCCsGAQUFBwICMIG2
-DIGzUmVsaWFuY2Ugb24gdGhpcyBjZXJ0aWZpY2F0ZSBieSBhbnkgcGFydHkgYXNz
-dW1lcyBhY2NlcHRhbmNlIG9mIHRoZSB0aGVuIGFwcGxpY2FibGUgc3RhbmRhcmQg
-dGVybXMgYW5kIGNvbmRpdGlvbnMgb2YgdXNlLCBjZXJ0aWZpY2F0ZSBwb2xpY3kg
-YW5kIGNlcnRpZmljYXRpb24gcHJhY3RpY2Ugc3RhdGVtZW50cy4wKQYIKwYBBQUH
-AgEWHWh0dHA6Ly93d3cuYXBwbGUuY29tL2FwcGxlY2EvMBMGA1UdJQQMMAoGCCsG
-AQUFBwMCME0GA1UdHwRGMEQwQqBAoD6GPGh0dHA6Ly9kZXZlbG9wZXIuYXBwbGUu
-Y29tL2NlcnRpZmljYXRpb25hdXRob3JpdHkvd3dkcmNhLmNybDAdBgNVHQ4EFgQU
-iPhM48Nu6I4H1Pb9BH55pJNPfoIwCwYDVR0PBAQDAgeAMBAGCiqGSIb3Y2QGAwEE
-AgUAMA0GCSqGSIb3DQEBBQUAA4IBAQCQAjc/KENJjRAJ1dugJUlY5GtaRFHDtFi6
-rU0FdxlyAYUJUzRzqEKE0onMWpJ3CevfTcoXIG+iEQ1DiNwWh5crYP85RlOoSqs8
-oporzTq+TUgI/XByzhCgtJwNx8gvUWJKJIgmL6SHvsGUit8fQjSlSjEjR2aPAuFG
-olZWsQmjNH9dluy5+BZLKSJ9hBo2TrhwJB1vk4B8+K2uqdG0T/elHxgNiq3KlPQt
-1s2Y+6kzGBnZuu42zlYnGSsNehNbWaEeW27avK/jilpNYaKQHotavbihXHQoUQml
-UYNFOqIRJyaMUDoC85+HH1CnfaFjj9T229z2/2pQUQGXskIt6hSa
------END CERTIFICATE-----
------BEGIN RSA PRIVATE KEY-----
-MIIEowIBAAKCAQEAwjdrw+8hKwbPbgsK8z3WhOX6ZlWE1xB3EK8MGmVdluRco4/u
-tE31gheJXmRCTGrOVyoLwls2zmlzv51KNG5/h0M9ltN4JIJMvlWxau0EJp6PM/cV
-TBbJ2ssY8SdaW2nxUoWcbiYVcBs2WXqzQYtXs3GH5nFYWH47LQ4wbMqBUnhzPdqH
-LT4u+CVXCK/LcRpnMT9Vepve8vLchakgpGRXOOWta5Yg5G4KgQKTj62IpHhBmGD+
-2Vq14odVsb0GmlFCHHVYqQ88a/0cL9pb0wqQnzxdeyguAtfvK3VM4o+dGshx7/U9
-fpwtmTeVfpsRbejy0UVLavQ/qO1OyVxJgKxmywIDAQABAoIBAG4mIn94cxZFAYYG
-y0oTS0QKbs51OCcFVpHmxXV/AepfT88QBbDK+i+zC5y2Pge7F5XF6e9r7hR5KEWH
-fptoA/oB/7835k7Ge6IDVeEv1YfVq6AsRS7nScpGH7o9uHhaCJzl3Ed4X/Y56MQs
-29eToMTL4einZhSiWwt9nadF3ryXR2/ZIYZbdfqKwA60ELL0/G90CU6vI76bxivZ
-QAzl2fG6U0WiwNKcmdc7MfYOXz2t9tsjPeRvPoKvNMwTIJXKAa7WzkUvZsjXaE1U
-fd6JQ1zlDqeAbbA2MCUdXM1ZAkLnwjh2+OxegEM9bEj8k4RLr530ywJKfI0FoqS+
-tz6RAikCgYEA93d9HmgPzysclhalZHBEDQEVpXaV9B4nmDg5WkOUdn48sFGNYgT6
-205XqxsCbSL2dur3T5xQMDYqqxX+rOXfq+eaU0y2ddTv4fvTWWAKdvlb1b23QXJV
-suWwkPbF1inOiNo0WEy1GY6cCrliuXexsrfTp8uZtnT9VowRMzoxkR0CgYEAyOnd
-prSvj1vavASPZ0BF4pdcfbm0T82ZlQo2TLzbUapsrNlqdHADylUMsB8YpoPf95b+
-VFjL76o3DPrjL9fsf0It7nI7AiMpdUPXqCsPWYcvBBUVXiXnzWcrT0Cw81TitK0/
-rU7HYn3LroqBZTpYXatyxpw1pdZiPCWsecwS+wcCgYAwDpVOrVi8m5uujfFKgv7E
-I7zHaDMQuDZqOijxHYScSkGQ4BV7vonUwu8FfHZJKWwBhfnHDQ0Jf8tjdB8EBpQc
-NxriKFiao2J+WUAe8Ca4Gg66gGAxJnn8Btz2GeYrg+zm6LEXoLXeo7Ir5vqEF/l7
-QnWo9UIBi9CS2RqR/zAXBQKBgQCMeWeubVrqgzC2kQGrEXdLbMUQas01lu0xFcjN
-cqZtvRjq6cDS1Jbx2vFaGwPjOQVZWUtNsiA02/BNtQUvqGsEt0LiGyBC6E7OXLbm
-L+U1lZ0733nnL92Y8e+IJBUUrV8tMIz7Ib+qj4Xf7Zt3KYorQ/ql/wZLg09/+l9T
-cWo79QKBgCg/6UmTTEFzkxBNTevQy/i+2WSl8Hs3jfBr/jMKoSb17HMuXVTP89eK
-4N8z8DZrx8czW7oOPhgWd4uYSx5ti0SSCdUqne57IE7Gf3Ul1ORIth1lvXccvMTj
-PtnftfShMZ6z1wVvpzR1+x1L4h0qBHFoLH4HrMHKod60u2xbdtoO
------END RSA PRIVATE KEY-----

+ 0 - 67
Ansjer/file/apns_pem/apns-dev.pem

@@ -1,67 +0,0 @@
-Bag Attributes
-    friendlyName: Apple Push Services: com.ansjer.zccloud
-    localKeyID: 9D A9 1D 37 7D DA 96 D1 8C 2D 3E D1 C0 47 5E 73 1C EF 6A 20 
-subject=/UID=com.ansjer.zccloud/CN=Apple Push Services: com.ansjer.zccloud/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-----
-MIIGJDCCBQygAwIBAgIIPBvSaz/ByJ0wDQYJKoZIhvcNAQELBQAwgZYxCzAJBgNV
-BAYTAlVTMRMwEQYDVQQKDApBcHBsZSBJbmMuMSwwKgYDVQQLDCNBcHBsZSBXb3Js
-ZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9uczFEMEIGA1UEAww7QXBwbGUgV29ybGR3
-aWRlIERldmVsb3BlciBSZWxhdGlvbnMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkw
-HhcNMTkwNDA5MDExNzAwWhcNMjAwNTA4MDExNzAwWjCBnDEiMCAGCgmSJomT8ixk
-AQEMEmNvbS5hbnNqZXIuemNjbG91ZDEwMC4GA1UEAwwnQXBwbGUgUHVzaCBTZXJ2
-aWNlczogY29tLmFuc2plci56Y2Nsb3VkMRMwEQYDVQQLDAo3NzJONUhYQVIyMSIw
-IAYDVQQKDBlaT1NJIFRlY2hub2xvZ3kgQ28uICwgTHRkMQswCQYDVQQGEwJDTjCC
-ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPCdYuZ6mESGlJx9VKZxUgSg
-aRwjYzanIcssyqZukWLG6ZaKkOneCV6O9FwcOXsTXds5wBHt43IhphFTpSLYqmU4
-ZlvV9hC9mliVLyvp1NEg4RpdDyg3dCfxk2uqlT7Gi73krgIrAXPewKuw11yxwJaQ
-oaclPB9PtFACFk84aHaJiqQcbczMSFC6ETzw/ubijwi370GsRhMitTrDesthNwwa
-avyjHI/IPebh8Whrp0UnqMGLk2+G4Ro27tJvcpjNCyjjqJIgXfJHvgLQtk99lvpy
-LlZnw9AkvfLC65ANCWRLFNhNrLt9dsfAvn7Xca3WkMhFD7oCFDC2R4Dux4qZZoUC
-AwEAAaOCAmwwggJoMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUiCcXCam2GGCL
-7Ou69kdZxVJUo7cwggEcBgNVHSAEggETMIIBDzCCAQsGCSqGSIb3Y2QFATCB/TCB
-wwYIKwYBBQUHAgIwgbYMgbNSZWxpYW5jZSBvbiB0aGlzIGNlcnRpZmljYXRlIGJ5
-IGFueSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGlj
-YWJsZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRp
-ZmljYXRlIHBvbGljeSBhbmQgY2VydGlmaWNhdGlvbiBwcmFjdGljZSBzdGF0ZW1l
-bnRzLjA1BggrBgEFBQcCARYpaHR0cDovL3d3dy5hcHBsZS5jb20vY2VydGlmaWNh
-dGVhdXRob3JpdHkwEwYDVR0lBAwwCgYIKwYBBQUHAwIwMAYDVR0fBCkwJzAloCOg
-IYYfaHR0cDovL2NybC5hcHBsZS5jb20vd3dkcmNhLmNybDAdBgNVHQ4EFgQUnakd
-N33altGMLT7RwEdecxzvaiAwDgYDVR0PAQH/BAQDAgeAMBAGCiqGSIb3Y2QGAwEE
-AgUAMBAGCiqGSIb3Y2QGAwIEAgUAMH0GCiqGSIb3Y2QGAwYEbzBtDBJjb20uYW5z
-amVyLnpjY2xvdWQwBQwDYXBwDBdjb20uYW5zamVyLnpjY2xvdWQudm9pcDAGDAR2
-b2lwDB9jb20uYW5zamVyLnpjY2xvdWQuY29tcGxpY2F0aW9uMA4MDGNvbXBsaWNh
-dGlvbjANBgkqhkiG9w0BAQsFAAOCAQEAk+4mP5l3/78GHOv0hmojKBA6kDZOWjT7
-HNoe2uJxtdoiGDFtrZw1QuobiIhnVab1UXOy5Iu5QhmST7odn9ZJuCp+6K9wV7nK
-HcEdYJX/zZtkIodFynAf8Zy6Emar4BJ+g7fb6DBNJ/NN1Hl3/8BhB3QfvMjVj+wy
-d8ayqk48lVzZXwWHRc9yhWheLa2nSbtT2c8aosOGKmbXBH2JpB9XINg5srRKrggw
-rtawrv2q2kDuBRg0rzP52Q76Q4J3ko4fMnh4Wa78V5TJOm2IncOont6W8RzOCK0x
-dv8d9qMJj42CC2D6yBwQ9ClUmgxnno+nynTX+BZfYqA8JdvYrtp/Cg==
------END CERTIFICATE-----
------BEGIN RSA PRIVATE KEY-----
-MIIEpAIBAAKCAQEA8J1i5nqYRIaUnH1UpnFSBKBpHCNjNqchyyzKpm6RYsbploqQ
-6d4JXo70XBw5exNd2znAEe3jciGmEVOlItiqZThmW9X2EL2aWJUvK+nU0SDhGl0P
-KDd0J/GTa6qVPsaLveSuAisBc97Aq7DXXLHAlpChpyU8H0+0UAIWTzhodomKpBxt
-zMxIULoRPPD+5uKPCLfvQaxGEyK1OsN6y2E3DBpq/KMcj8g95uHxaGunRSeowYuT
-b4bhGjbu0m9ymM0LKOOokiBd8ke+AtC2T32W+nIuVmfD0CS98sLrkA0JZEsU2E2s
-u312x8C+ftdxrdaQyEUPugIUMLZHgO7HiplmhQIDAQABAoIBAQC9NRYDZV39bNLJ
-5+g75hp31ugwn0cyP+TcDwHgNEwRH5epsJbZwKcfe0x+bhdpR8ZjUJtPvgA/zGP5
-dgwCRdxgMiSTjMGtUltf0xg/8OVP+gnpIEp99nVZv6aMYJxxu9FBZuTKgaTnx788
-g5gmpQRroZnshOQtPxDsZWfDrfi/VEyjZYZJpOHQUR0NKjFlLVOmKZK7Byjhw+hH
-CyMbfeN2JwN/iqYxZAQQCTFaW1FBxPkMNLPwPGFOMHafMiUv4hj2Km5wpTyFYs7c
-yrpr4IjwVG2rBeRAsQf3lNIuL5jOqu9qh/qBvpkh+ecg1zbWosO6oPwgThhtTqrb
-BAqJ966BAoGBAPiLR+7C6g+HdaNIMysml9wnvRDtTRxM5CaCFxMcbZkiCc+kenyW
-ySxhPO4qRNNXUZHPg6KylyVWuxn52RR9CcSG/XQnN7odOdkc7gTe1fxdESVRwZnZ
-zxHSEdJ/BopcIU9tezWDQCMCyakRMqZHbUL/3q3wrVhoujTGg+HOZFNhAoGBAPfV
-NjBJvCxpQsYEuIJXieBRrnLy/Ab7fzqpYGBwCxLYE0BSeF1PAe60YKXlUxNE6RD+
-VO+V/BcDgs1An3JAYwGup2C3pfSYf7QHnKU3jbRP8uadseVRhs14snC5EmxXxML7
-GyozM7X0QCezNPU3mYBsq+nLi57oeLyWoJQRyUmlAoGAICfs+5AONkohRynNLPUG
-Sr59cJYzFsk/71d/YsKXz2se99Vg34OmrW47MtkXJHy0mffOIRuYAIWzGU5A7qyq
-udl5KzDzvcmQNW3PwaOO7eKgmEJ2mNAcQUL7eU9j6jy3No6ElUzQ3Ha83nnSIr80
-/KkcB0cPNlP+W1ufrnREeKECgYAKHpab2ibo2VN0qnSuPczPcAZjgzBvSI2lY40f
-4vNQzanbkoJ/rN4zVQItQ/PkcYfivb/SGJm2htosb1sTWzWvt+X1uQn5ttBgFX97
-74zFtA4DBKVi67VJZohCugvaiKrsGzy8uGKAJ30HIfYjnSWTbNyIK1uEHZHwgWYF
-JcTGUQKBgQCF0ppZeDT0c4u8mHUIjyfUxF9v/VejNGSQaLbTIUX2CBMMF/AObjwt
-n+nmifWLgFVuI7t+7PLZVEnY9H5jxKwI+uyuPRlTtDxLIz2vH59GY3Ey/aCwHMD4
-eRdenIp0Cg2ZUh+sW/XartIP0lYXEot7WAI/Z//m7wAyVUEucyVD0Q==
------END RSA PRIVATE KEY-----

+ 0 - 41
Ansjer/file/apns_pem/apns-dev_nw.pem

@@ -1,41 +0,0 @@
-Bag Attributes
-    friendlyName: Apple Development IOS Push Services: com.ansjer.loocamccloud
-    localKeyID: 88 F8 4C E3 C3 6E E8 8E 07 D4 F6 FD 04 7E 79 A4 93 4F 7E 82 
-subject=/UID=com.ansjer.loocamccloud/CN=Apple Development IOS Push Services: com.ansjer.loocamccloud/OU=JCHT67XT68/C=US
-issuer=/C=US/O=Apple Inc./OU=Apple Worldwide Developer Relations/CN=Apple Worldwide Developer Relations Certification Authority
------BEGIN CERTIFICATE-----
-MIIFkzCCBHugAwIBAgIIYwaKq6f2DAEwDQYJKoZIhvcNAQEFBQAwgZYxCzAJBgNV
-BAYTAlVTMRMwEQYDVQQKDApBcHBsZSBJbmMuMSwwKgYDVQQLDCNBcHBsZSBXb3Js
-ZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9uczFEMEIGA1UEAww7QXBwbGUgV29ybGR3
-aWRlIERldmVsb3BlciBSZWxhdGlvbnMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkw
-HhcNMTkwNjI2MDU1MzM5WhcNMjAwNjI1MDU1MzM5WjCBkjEnMCUGCgmSJomT8ixk
-AQEMF2NvbS5hbnNqZXIubG9vY2FtY2Nsb3VkMUUwQwYDVQQDDDxBcHBsZSBEZXZl
-bG9wbWVudCBJT1MgUHVzaCBTZXJ2aWNlczogY29tLmFuc2plci5sb29jYW1jY2xv
-dWQxEzARBgNVBAsMCkpDSFQ2N1hUNjgxCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG
-9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwjdrw+8hKwbPbgsK8z3WhOX6ZlWE1xB3EK8M
-GmVdluRco4/utE31gheJXmRCTGrOVyoLwls2zmlzv51KNG5/h0M9ltN4JIJMvlWx
-au0EJp6PM/cVTBbJ2ssY8SdaW2nxUoWcbiYVcBs2WXqzQYtXs3GH5nFYWH47LQ4w
-bMqBUnhzPdqHLT4u+CVXCK/LcRpnMT9Vepve8vLchakgpGRXOOWta5Yg5G4KgQKT
-j62IpHhBmGD+2Vq14odVsb0GmlFCHHVYqQ88a/0cL9pb0wqQnzxdeyguAtfvK3VM
-4o+dGshx7/U9fpwtmTeVfpsRbejy0UVLavQ/qO1OyVxJgKxmywIDAQABo4IB5TCC
-AeEwCQYDVR0TBAIwADAfBgNVHSMEGDAWgBSIJxcJqbYYYIvs67r2R1nFUlSjtzCC
-AQ8GA1UdIASCAQYwggECMIH/BgkqhkiG92NkBQEwgfEwgcMGCCsGAQUFBwICMIG2
-DIGzUmVsaWFuY2Ugb24gdGhpcyBjZXJ0aWZpY2F0ZSBieSBhbnkgcGFydHkgYXNz
-dW1lcyBhY2NlcHRhbmNlIG9mIHRoZSB0aGVuIGFwcGxpY2FibGUgc3RhbmRhcmQg
-dGVybXMgYW5kIGNvbmRpdGlvbnMgb2YgdXNlLCBjZXJ0aWZpY2F0ZSBwb2xpY3kg
-YW5kIGNlcnRpZmljYXRpb24gcHJhY3RpY2Ugc3RhdGVtZW50cy4wKQYIKwYBBQUH
-AgEWHWh0dHA6Ly93d3cuYXBwbGUuY29tL2FwcGxlY2EvMBMGA1UdJQQMMAoGCCsG
-AQUFBwMCME0GA1UdHwRGMEQwQqBAoD6GPGh0dHA6Ly9kZXZlbG9wZXIuYXBwbGUu
-Y29tL2NlcnRpZmljYXRpb25hdXRob3JpdHkvd3dkcmNhLmNybDAdBgNVHQ4EFgQU
-iPhM48Nu6I4H1Pb9BH55pJNPfoIwCwYDVR0PBAQDAgeAMBAGCiqGSIb3Y2QGAwEE
-AgUAMA0GCSqGSIb3DQEBBQUAA4IBAQCQAjc/KENJjRAJ1dugJUlY5GtaRFHDtFi6
-rU0FdxlyAYUJUzRzqEKE0onMWpJ3CevfTcoXIG+iEQ1DiNwWh5crYP85RlOoSqs8
-oporzTq+TUgI/XByzhCgtJwNx8gvUWJKJIgmL6SHvsGUit8fQjSlSjEjR2aPAuFG
-olZWsQmjNH9dluy5+BZLKSJ9hBo2TrhwJB1vk4B8+K2uqdG0T/elHxgNiq3KlPQt
-1s2Y+6kzGBnZuu42zlYnGSsNehNbWaEeW27avK/jilpNYaKQHotavbihXHQoUQml
-UYNFOqIRJyaMUDoC85+HH1CnfaFjj9T229z2/2pQUQGXskIt6hSa
------END CERTIFICATE-----
-Bag Attributes
-    friendlyName: ansjer
-    localKeyID: 88 F8 4C E3 C3 6E E8 8E 07 D4 F6 FD 04 7E 79 A4 93 4F 7E 82 
-Key Attributes: <No Attributes>

+ 0 - 41
Ansjer/file/apns_pem/apns-loocamccloud.pem

@@ -1,41 +0,0 @@
-Bag Attributes
-    friendlyName: Apple Development IOS Push Services: com.loocam.loocamcloud
-    localKeyID: B0 37 EA 76 9F F8 94 4C E7 6A E7 85 05 37 99 B4 10 AC E7 A2 
-subject=/UID=com.loocam.loocamcloud/CN=Apple Development IOS Push Services: com.loocam.loocamcloud/OU=JCHT67XT68/C=US
-issuer=/C=US/O=Apple Inc./OU=Apple Worldwide Developer Relations/CN=Apple Worldwide Developer Relations Certification Authority
------BEGIN CERTIFICATE-----
-MIIFkTCCBHmgAwIBAgIIS894dI4qHJYwDQYJKoZIhvcNAQEFBQAwgZYxCzAJBgNV
-BAYTAlVTMRMwEQYDVQQKDApBcHBsZSBJbmMuMSwwKgYDVQQLDCNBcHBsZSBXb3Js
-ZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9uczFEMEIGA1UEAww7QXBwbGUgV29ybGR3
-aWRlIERldmVsb3BlciBSZWxhdGlvbnMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkw
-HhcNMTkwNjI2MDI1MDQ3WhcNMjAwNjI1MDI1MDQ3WjCBkDEmMCQGCgmSJomT8ixk
-AQEMFmNvbS5sb29jYW0ubG9vY2FtY2xvdWQxRDBCBgNVBAMMO0FwcGxlIERldmVs
-b3BtZW50IElPUyBQdXNoIFNlcnZpY2VzOiBjb20ubG9vY2FtLmxvb2NhbWNsb3Vk
-MRMwEQYDVQQLDApKQ0hUNjdYVDY4MQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcN
-AQEBBQADggEPADCCAQoCggEBALtezKRHBBko9CaDqJTnX/itHK1baMPB6WHviVDJ
-6FG1vphLhg2PbZCIPdU3fQXnnqo+4u67ol/j5ER9jW1nmf5e9AzkjCGIA1Yst6SH
-s2VpIlwG3kd96f5Yjk161iXbJ0iMyu1Y2WiElpwOhd8IthXZl2eB7NYBJxW4utEg
-pXqS90U7QYg0Mt7hdO8gE9yO5K996Z8YabTQHRdoKhdgLUH8iGl57oO6usgiDvj0
-nXHjruBLOV0HwvV4SXPwShEScQN5M87WQx/EC2ocoocKL1G4x61ITPYEtq0VoELK
-LChnHyl4OaDhGQKtAZZlEKiZKql2r5JitsVsz/sFAA1QsiUCAwEAAaOCAeUwggHh
-MAkGA1UdEwQCMAAwHwYDVR0jBBgwFoAUiCcXCam2GGCL7Ou69kdZxVJUo7cwggEP
-BgNVHSAEggEGMIIBAjCB/wYJKoZIhvdjZAUBMIHxMIHDBggrBgEFBQcCAjCBtgyB
-s1JlbGlhbmNlIG9uIHRoaXMgY2VydGlmaWNhdGUgYnkgYW55IHBhcnR5IGFzc3Vt
-ZXMgYWNjZXB0YW5jZSBvZiB0aGUgdGhlbiBhcHBsaWNhYmxlIHN0YW5kYXJkIHRl
-cm1zIGFuZCBjb25kaXRpb25zIG9mIHVzZSwgY2VydGlmaWNhdGUgcG9saWN5IGFu
-ZCBjZXJ0aWZpY2F0aW9uIHByYWN0aWNlIHN0YXRlbWVudHMuMCkGCCsGAQUFBwIB
-Fh1odHRwOi8vd3d3LmFwcGxlLmNvbS9hcHBsZWNhLzATBgNVHSUEDDAKBggrBgEF
-BQcDAjBNBgNVHR8ERjBEMEKgQKA+hjxodHRwOi8vZGV2ZWxvcGVyLmFwcGxlLmNv
-bS9jZXJ0aWZpY2F0aW9uYXV0aG9yaXR5L3d3ZHJjYS5jcmwwHQYDVR0OBBYEFLA3
-6naf+JRM52rnhQU3mbQQrOeiMAsGA1UdDwQEAwIHgDAQBgoqhkiG92NkBgMBBAIF
-ADANBgkqhkiG9w0BAQUFAAOCAQEApenYB9Kku9rAtx8UOZc9aUlnolxp119BDgte
-t8JXi5FA5ujxT1JVLNUhgqeQmEHFzlgBs8/cWUdcyJpvoH3ppSlFefJf09pu2Nrw
-4UOHeoUFVJMc2hFEgHqEPk8gnY/PebgfrBc2E5iRj+C3nf+iyqCB9Ot8KNy9N9XB
-XrL6fcu4MHYuEgAjdq5ysVFgWEyYYEmKRAc1qnXkBIa8GUJ1q2JZ910aG4anfSDy
-km49HnxQJBzOpTjWWuNDwCwKXf55wNXocq1bZgjho/ByLX9waWSlTeamuHp5bu/P
-22NkrcR2/KLMjCPbRn5+ew5SPNEuFTkRML9WBCUcpPC1hzyxqA==
------END CERTIFICATE-----
-Bag Attributes
-    friendlyName: mac mini01
-    localKeyID: B0 37 EA 76 9F F8 94 4C E7 6A E7 85 05 37 99 B4 10 AC E7 A2 
-Key Attributes: <No Attributes>

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

@@ -0,0 +1,68 @@
+Bag Attributes
+    friendlyName: Apple Push Services: com.ansjer.loocamccloud
+    localKeyID: 81 BA F8 2E C5 58 9A A4 86 A9 47 F6 EF B7 16 48 1C 7A 1E E9
+subject=/UID=com.ansjer.loocamccloud/CN=Apple Push Services: com.ansjer.loocamccloud/OU=JCHT67XT68/O=Loocam Technology LLC/C=US
+issuer=/C=US/O=Apple Inc./OU=Apple Worldwide Developer Relations/CN=Apple Worldwide Developer Relations Certification Authority
+-----BEGIN CERTIFICATE-----
+MIIGOjCCBSKgAwIBAgIIEh/B+Kd1dVowDQYJKoZIhvcNAQELBQAwgZYxCzAJBgNV
+BAYTAlVTMRMwEQYDVQQKDApBcHBsZSBJbmMuMSwwKgYDVQQLDCNBcHBsZSBXb3Js
+ZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9uczFEMEIGA1UEAww7QXBwbGUgV29ybGR3
+aWRlIERldmVsb3BlciBSZWxhdGlvbnMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkw
+HhcNMTkxMDE1MDk0OTQ4WhcNMjAxMTEzMDk0OTQ4WjCBojEnMCUGCgmSJomT8ixk
+AQEMF2NvbS5hbnNqZXIubG9vY2FtY2Nsb3VkMTUwMwYDVQQDDCxBcHBsZSBQdXNo
+IFNlcnZpY2VzOiBjb20uYW5zamVyLmxvb2NhbWNjbG91ZDETMBEGA1UECwwKSkNI
+VDY3WFQ2ODEeMBwGA1UECgwVTG9vY2FtIFRlY2hub2xvZ3kgTExDMQswCQYDVQQG
+EwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMIfC7vgq2k1bNRW
+4/Ix+W5CYWLzlbZJ3WS+A4X8GEZVkpcuQhADCs/fxMk/KMzl3XvX8YiNQoItKGzK
+Gd0wEtwdjmQvsXwjZG47v7OGE0qj9beQRMYo0gq6SOK7J7r7/8QW9ggmZJXfTqu2
+kQimrpTLeEQdKERbZLxV4i5oOTaAwyzHChNDmvcg2LCjkYaHuOMKtuQHOcMd8RQ4
+DybXkCyPbItIRxuAksMSem2TBHyHoO6Agx3epPgU+9nTbze7eU0OpAiAl7lFqc3i
+80llb8N23q4WUK+1u/5KEVlZjXHvdmOYldVpUK2GUgc4gcBbZoda3DIQ/F8nddTI
+gczwXRMCAwEAAaOCAnwwggJ4MAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUiCcX
+Cam2GGCL7Ou69kdZxVJUo7cwggEcBgNVHSAEggETMIIBDzCCAQsGCSqGSIb3Y2QF
+ATCB/TCBwwYIKwYBBQUHAgIwgbYMgbNSZWxpYW5jZSBvbiB0aGlzIGNlcnRpZmlj
+YXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4g
+YXBwbGljYWJsZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2Us
+IGNlcnRpZmljYXRlIHBvbGljeSBhbmQgY2VydGlmaWNhdGlvbiBwcmFjdGljZSBz
+dGF0ZW1lbnRzLjA1BggrBgEFBQcCARYpaHR0cDovL3d3dy5hcHBsZS5jb20vY2Vy
+dGlmaWNhdGVhdXRob3JpdHkwEwYDVR0lBAwwCgYIKwYBBQUHAwIwMAYDVR0fBCkw
+JzAloCOgIYYfaHR0cDovL2NybC5hcHBsZS5jb20vd3dkcmNhLmNybDAdBgNVHQ4E
+FgQUgbr4LsVYmqSGqUf277cWSBx6HukwDgYDVR0PAQH/BAQDAgeAMBAGCiqGSIb3
+Y2QGAwEEAgUAMBAGCiqGSIb3Y2QGAwIEAgUAMIGMBgoqhkiG92NkBgMGBH4wfAwX
+Y29tLmFuc2plci5sb29jYW1jY2xvdWQwBQwDYXBwDBxjb20uYW5zamVyLmxvb2Nh
+bWNjbG91ZC52b2lwMAYMBHZvaXAMJGNvbS5hbnNqZXIubG9vY2FtY2Nsb3VkLmNv
+bXBsaWNhdGlvbjAODAxjb21wbGljYXRpb24wDQYJKoZIhvcNAQELBQADggEBABr9
+dM8BvrJVSwYRGw39JU7kiGV+dOhcJ59XwOdo2xO05dv1iQJeVDRSpni9yfeHX/pu
+rycGgEm40IQxqTNs851KUqBiLjEwRjkX6MZQMbWnTZY8xiLFKm7lhY6mFUsxfkXH
+/dygY9uZkNCzYfzs8JbWRU8p2uNwF3ZRvZiXITncNWImkdtneSHgF3IQtq/6flc5
+aA89zIH8P7V5/Rvye7JFuM98AXNUHO8XznwgGru6kZCpi4e+83AAXhD9JQmHv/wN
+iHCDWHq1TFS8KgbxfvgGkB2r5vlGkWSo2E3xnxGZu6tiRYgNyNqNsJoMeAtH/352
+xQQMuMMfCP/eKBojC+8=
+-----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAwh8Lu+CraTVs1Fbj8jH5bkJhYvOVtkndZL4DhfwYRlWSly5C
+EAMKz9/EyT8ozOXde9fxiI1Cgi0obMoZ3TAS3B2OZC+xfCNkbju/s4YTSqP1t5BE
+xijSCrpI4rsnuvv/xBb2CCZkld9Oq7aRCKaulMt4RB0oRFtkvFXiLmg5NoDDLMcK
+E0Oa9yDYsKORhoe44wq25Ac5wx3xFDgPJteQLI9si0hHG4CSwxJ6bZMEfIeg7oCD
+Hd6k+BT72dNvN7t5TQ6kCICXuUWpzeLzSWVvw3berhZQr7W7/koRWVmNce92Y5iV
+1WlQrYZSBziBwFtmh1rcMhD8Xyd11MiBzPBdEwIDAQABAoIBAAi22BIBDfDVIyON
+GwJ+V9IpTLHieXALdNLW7NWQ8Y4GvWPoAbMyT8PxKaZXHX/FOeIbWY5luPybBluL
+3wlc5RvYf9HjijYmaJXCPOLUO/13ysoIwe2bW4J7xlXXTPtJ4LtuxHCtOIq50ZBH
+y871nJS1ZZq5LFuVNrp1qIeoyhi2LuMdkzjpA5MujOhr9vEgI2P2wBazgL2XZ/i/
+2FTJBWp13wSCj6usohni+Ppm77+/Ax9kj0K2vXTjy/fRDIcmkAHdfzifd3oGHtIs
+zc5m1i5GnKXhUB87GrCSvZ1gqJII2ZgXCroprp1TzrWOtH0mzDtzuqYsT8aUpAuG
+Fbnj0sECgYEA+78DbnEAWfzjQXjUytgE2FVSWINsl0zUyr0mIh85r0QY+eQc3LX6
+RDPQq1qndhwXPGY5Nv+hGncAIP0o6eldT1D6LuAcyTzff025aTMLxAswtj1qSfNL
+vVEA+V8Q45TqKIC+CfzJysx5xk53S3DFesCxGfHk5ozmg8ILQSblUlECgYEAxWbD
+OwEW1Wi9UmQcGfKjM7tN22EpY4qid0BJsib/qqfI++42BAuytFKZyyAnaOaNCEKx
+ktaKGZcTCjtstathMiB+3sjJbqOXV+WntrVb4eu35N+IhhRd/ltdyXqx9PwMeMpC
+i73JZZhw9Wn4M7aAC/M37vw3Ztecx5hiTKixXCMCgYAFb3dcgBYY20vw0vINOyLH
+pPf1L0k97wu9IN5c6D2vmhHL+2/gGBHCPTgpKvjopOyfgjmEBXrt/lnDXJPwkPhR
+yRbNwkr80VKmBgCV0+NSJUe095h+5kDhYolZ2QKdV07C9xyjTJDyzv1mGbWbrGCn
+KNfqDn35uFsVxy/FBVj4MQKBgQCkwCyGzVTqTh1ca1MM0PYm0decFg5+FpGb55ra
+RjQxkRFsOhb47255k0rqPe7GXU0trMQZolbmHrF0Y75KLTvUo0xf0cJURdKlOHXu
+RpTmDF6RdYKzLMJ57HVtF6r4pXgfQ+egS4iP81era4MMXe+miZqQKg5vFdqyttqr
+0ksccwKBgQC0jmQ6/KCE2hvNcNIKJzXDZ+4C5LGn6f6hSe5G2yzyt0KVUuUd1gk9
+/IbwSYbNR5SO8KmHoL3yjhBnv+eVE5VFTgy5Gc+J+ON9pPjvYqpwMjlqBCzhUWZN
+gm9kUGZQPYOvuweViXECMZntcVNxG2bKodaMFHKda3xD2fTSeB6OCg==
+-----END RSA PRIVATE KEY-----

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

@@ -0,0 +1,68 @@
+Bag Attributes
+    friendlyName: Apple Push Services: com.ansjer.loocamccloud
+    localKeyID: 81 BA F8 2E C5 58 9A A4 86 A9 47 F6 EF B7 16 48 1C 7A 1E E9 
+subject=/UID=com.ansjer.loocamccloud/CN=Apple Push Services: com.ansjer.loocamccloud/OU=JCHT67XT68/O=Loocam Technology LLC/C=US
+issuer=/C=US/O=Apple Inc./OU=Apple Worldwide Developer Relations/CN=Apple Worldwide Developer Relations Certification Authority
+-----BEGIN CERTIFICATE-----
+MIIGOjCCBSKgAwIBAgIIEh/B+Kd1dVowDQYJKoZIhvcNAQELBQAwgZYxCzAJBgNV
+BAYTAlVTMRMwEQYDVQQKDApBcHBsZSBJbmMuMSwwKgYDVQQLDCNBcHBsZSBXb3Js
+ZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9uczFEMEIGA1UEAww7QXBwbGUgV29ybGR3
+aWRlIERldmVsb3BlciBSZWxhdGlvbnMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkw
+HhcNMTkxMDE1MDk0OTQ4WhcNMjAxMTEzMDk0OTQ4WjCBojEnMCUGCgmSJomT8ixk
+AQEMF2NvbS5hbnNqZXIubG9vY2FtY2Nsb3VkMTUwMwYDVQQDDCxBcHBsZSBQdXNo
+IFNlcnZpY2VzOiBjb20uYW5zamVyLmxvb2NhbWNjbG91ZDETMBEGA1UECwwKSkNI
+VDY3WFQ2ODEeMBwGA1UECgwVTG9vY2FtIFRlY2hub2xvZ3kgTExDMQswCQYDVQQG
+EwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMIfC7vgq2k1bNRW
+4/Ix+W5CYWLzlbZJ3WS+A4X8GEZVkpcuQhADCs/fxMk/KMzl3XvX8YiNQoItKGzK
+Gd0wEtwdjmQvsXwjZG47v7OGE0qj9beQRMYo0gq6SOK7J7r7/8QW9ggmZJXfTqu2
+kQimrpTLeEQdKERbZLxV4i5oOTaAwyzHChNDmvcg2LCjkYaHuOMKtuQHOcMd8RQ4
+DybXkCyPbItIRxuAksMSem2TBHyHoO6Agx3epPgU+9nTbze7eU0OpAiAl7lFqc3i
+80llb8N23q4WUK+1u/5KEVlZjXHvdmOYldVpUK2GUgc4gcBbZoda3DIQ/F8nddTI
+gczwXRMCAwEAAaOCAnwwggJ4MAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUiCcX
+Cam2GGCL7Ou69kdZxVJUo7cwggEcBgNVHSAEggETMIIBDzCCAQsGCSqGSIb3Y2QF
+ATCB/TCBwwYIKwYBBQUHAgIwgbYMgbNSZWxpYW5jZSBvbiB0aGlzIGNlcnRpZmlj
+YXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4g
+YXBwbGljYWJsZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2Us
+IGNlcnRpZmljYXRlIHBvbGljeSBhbmQgY2VydGlmaWNhdGlvbiBwcmFjdGljZSBz
+dGF0ZW1lbnRzLjA1BggrBgEFBQcCARYpaHR0cDovL3d3dy5hcHBsZS5jb20vY2Vy
+dGlmaWNhdGVhdXRob3JpdHkwEwYDVR0lBAwwCgYIKwYBBQUHAwIwMAYDVR0fBCkw
+JzAloCOgIYYfaHR0cDovL2NybC5hcHBsZS5jb20vd3dkcmNhLmNybDAdBgNVHQ4E
+FgQUgbr4LsVYmqSGqUf277cWSBx6HukwDgYDVR0PAQH/BAQDAgeAMBAGCiqGSIb3
+Y2QGAwEEAgUAMBAGCiqGSIb3Y2QGAwIEAgUAMIGMBgoqhkiG92NkBgMGBH4wfAwX
+Y29tLmFuc2plci5sb29jYW1jY2xvdWQwBQwDYXBwDBxjb20uYW5zamVyLmxvb2Nh
+bWNjbG91ZC52b2lwMAYMBHZvaXAMJGNvbS5hbnNqZXIubG9vY2FtY2Nsb3VkLmNv
+bXBsaWNhdGlvbjAODAxjb21wbGljYXRpb24wDQYJKoZIhvcNAQELBQADggEBABr9
+dM8BvrJVSwYRGw39JU7kiGV+dOhcJ59XwOdo2xO05dv1iQJeVDRSpni9yfeHX/pu
+rycGgEm40IQxqTNs851KUqBiLjEwRjkX6MZQMbWnTZY8xiLFKm7lhY6mFUsxfkXH
+/dygY9uZkNCzYfzs8JbWRU8p2uNwF3ZRvZiXITncNWImkdtneSHgF3IQtq/6flc5
+aA89zIH8P7V5/Rvye7JFuM98AXNUHO8XznwgGru6kZCpi4e+83AAXhD9JQmHv/wN
+iHCDWHq1TFS8KgbxfvgGkB2r5vlGkWSo2E3xnxGZu6tiRYgNyNqNsJoMeAtH/352
+xQQMuMMfCP/eKBojC+8=
+-----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAwh8Lu+CraTVs1Fbj8jH5bkJhYvOVtkndZL4DhfwYRlWSly5C
+EAMKz9/EyT8ozOXde9fxiI1Cgi0obMoZ3TAS3B2OZC+xfCNkbju/s4YTSqP1t5BE
+xijSCrpI4rsnuvv/xBb2CCZkld9Oq7aRCKaulMt4RB0oRFtkvFXiLmg5NoDDLMcK
+E0Oa9yDYsKORhoe44wq25Ac5wx3xFDgPJteQLI9si0hHG4CSwxJ6bZMEfIeg7oCD
+Hd6k+BT72dNvN7t5TQ6kCICXuUWpzeLzSWVvw3berhZQr7W7/koRWVmNce92Y5iV
+1WlQrYZSBziBwFtmh1rcMhD8Xyd11MiBzPBdEwIDAQABAoIBAAi22BIBDfDVIyON
+GwJ+V9IpTLHieXALdNLW7NWQ8Y4GvWPoAbMyT8PxKaZXHX/FOeIbWY5luPybBluL
+3wlc5RvYf9HjijYmaJXCPOLUO/13ysoIwe2bW4J7xlXXTPtJ4LtuxHCtOIq50ZBH
+y871nJS1ZZq5LFuVNrp1qIeoyhi2LuMdkzjpA5MujOhr9vEgI2P2wBazgL2XZ/i/
+2FTJBWp13wSCj6usohni+Ppm77+/Ax9kj0K2vXTjy/fRDIcmkAHdfzifd3oGHtIs
+zc5m1i5GnKXhUB87GrCSvZ1gqJII2ZgXCroprp1TzrWOtH0mzDtzuqYsT8aUpAuG
+Fbnj0sECgYEA+78DbnEAWfzjQXjUytgE2FVSWINsl0zUyr0mIh85r0QY+eQc3LX6
+RDPQq1qndhwXPGY5Nv+hGncAIP0o6eldT1D6LuAcyTzff025aTMLxAswtj1qSfNL
+vVEA+V8Q45TqKIC+CfzJysx5xk53S3DFesCxGfHk5ozmg8ILQSblUlECgYEAxWbD
+OwEW1Wi9UmQcGfKjM7tN22EpY4qid0BJsib/qqfI++42BAuytFKZyyAnaOaNCEKx
+ktaKGZcTCjtstathMiB+3sjJbqOXV+WntrVb4eu35N+IhhRd/ltdyXqx9PwMeMpC
+i73JZZhw9Wn4M7aAC/M37vw3Ztecx5hiTKixXCMCgYAFb3dcgBYY20vw0vINOyLH
+pPf1L0k97wu9IN5c6D2vmhHL+2/gGBHCPTgpKvjopOyfgjmEBXrt/lnDXJPwkPhR
+yRbNwkr80VKmBgCV0+NSJUe095h+5kDhYolZ2QKdV07C9xyjTJDyzv1mGbWbrGCn
+KNfqDn35uFsVxy/FBVj4MQKBgQCkwCyGzVTqTh1ca1MM0PYm0decFg5+FpGb55ra
+RjQxkRFsOhb47255k0rqPe7GXU0trMQZolbmHrF0Y75KLTvUo0xf0cJURdKlOHXu
+RpTmDF6RdYKzLMJ57HVtF6r4pXgfQ+egS4iP81era4MMXe+miZqQKg5vFdqyttqr
+0ksccwKBgQC0jmQ6/KCE2hvNcNIKJzXDZ+4C5LGn6f6hSe5G2yzyt0KVUuUd1gk9
+/IbwSYbNR5SO8KmHoL3yjhBnv+eVE5VFTgy5Gc+J+ON9pPjvYqpwMjlqBCzhUWZN
+gm9kUGZQPYOvuweViXECMZntcVNxG2bKodaMFHKda3xD2fTSeB6OCg==
+-----END RSA PRIVATE KEY-----

+ 2 - 1
Ansjer/test/.cache/v/cache/lastfailed

@@ -1,3 +1,4 @@
 {
-  "mqtt_client.py::test": true
+  "mqtt_client.py::test": true,
+  "s3sts.py": true
 }

+ 8 - 0
Ansjer/test/kbt.py

@@ -0,0 +1,8 @@
+'''
+
+
+
+
+tar -cvpzf ubuntu_backup@`date +%Y-%m+%d`.tar.gz --exclude=/proc --exclude=/tmp --exclude=/boot --exclude=/home --exclude=/lost+found --exclude=/media --exclude=/mnt --exclude=/run --exclude=/home/sda1 / --warning=no-file-change
+
+'''

+ 17 - 4
Ansjer/urls.py

@@ -2,7 +2,8 @@ from django.conf.urls import url
 from django.urls import path, re_path
 
 from Controller import FeedBack, EquipmentOTA, EquipmentInfo, EquipmentSensor, StreamMedia, AdminManage, AppInfo, \
-    AccessLog, Test, MealManage, DeviceManage, EquipmentStatus, SysManage, DeviceLog, LogAccess, AppColophon, \
+    AccessLog, DynamoDBLog, Test, MealManage, DeviceManage, EquipmentStatus, SysManage, DeviceLog, LogAccess, \
+    AppColophon, \
     EquipmentManager, LogManager, PermissionManager, OTAEquipment, shareUserPermission, UidSetController, \
     UserManger, CheckUserData, \
     UserController, CloudVod, OrderContrller, VodBucket, DetectController, DeviceShare, UserBrandController, \
@@ -73,12 +74,13 @@ urlpatterns = [
     url(r'^equipment/info', EquipmentInfo.EquipmentInfo.as_view()),
     url(r'^adminManage/manage', AdminManage.AdminManage.as_view()),  # 管理员专属view
     url(r'^equipment/OTA', EquipmentOTA.EquipmentOTA.as_view()),  # OTA重构类
-    # url(r'^feedbackInfo', FeedBackInfo.FeedBackInfo.as_view()),  # 用户反馈信息
     url(r'^userbrandinfo/(?P<operation>.*)$', UserBrandController.UserBrandInfo.as_view()),  # 用户登录的手机端品牌记录统计信息表
 
     url(r'^uidset/(?P<operation>.*)$', UidSetController.UidSetView.as_view()),
     url(r'^appInfo', AppInfo.AppInfo.as_view()),  # app版本信息
     url(r'^accesslog', AccessLog.AccessLog.as_view()),
+    url(r'^dynamoDBLog/(?P<operation>.*)$', DynamoDBLog.DynamoDBLog.as_view()),
+
     url(r'^meal/manage', MealManage.MealManage.as_view()),
     url(r'^device/manage$', DeviceManage.DeviceManage.as_view()),
     # 设备在线
@@ -108,14 +110,15 @@ urlpatterns = [
 
     # h获取验证码    # v2接口
     url(r'^v2/account/authcode$', UserController.v2authCodeView.as_view()),
+
     url(r'^v2/account/register$', UserController.v2registerView.as_view()),
     url(r'^v2/account/forgetCode$', UserController.v2forgetPwdCodeView.as_view()),
     url(r'^v2/account/resetPwdByCode$', UserController.v2resetPwdByCodeView.as_view()),
     # 重置密码验证码校验
     url(r'^v2/authcode/verify$', UserController.verifyAuthcode.as_view()),
 
-    url(r'^detect/add$', EquipmentInfo.AddDetectionView.as_view()),
-    url(r'^detect/status$', EquipmentInfo.DetectStatusView.as_view()),
+    url(r'^detect/add$', DetectController.PushNotificationView.as_view()),
+    # url(r'^detect/status$', EquipmentInfo.DetectStatusView.as_view()),
     url(r'^detect/(?P<operation>.*)$', DetectController.DetectControllerView.as_view()),
     url(r'^notify/push$', DetectController.NotificationView.as_view()),
     url(r'^cloudVod/(?P<operation>.*)$', CloudVod.CloudVodView.as_view()),
@@ -142,14 +145,24 @@ urlpatterns = [
     url(r'^feedback/(?P<operation>.*)$', FeedBack.FeedBackView.as_view()),
     url(r'^uidpreview/(?P<operation>.*)$', UIDPreview.UIDPreview.as_view()),
     url(r'^sysmsg/(?P<operation>.*)$', SysMsg.SysMsgView.as_view()),
+    url(r'^sysfile/(?P<filePath>.*)$', SysManage.getStatView.as_view()),
 
     url(r'^equipment/flowUpdate', EquipmentManager.update_uid_set),
 
     url(r'^deviceShadow/update', EquipmentManager.update_device_shadow),
 
     url(r'^log/getUploadUrl', EquipmentStatus.getUploadLogUrl),
+    url(r'^app/getIdData', AppInfo.AppIdDataView.as_view()),
+    url(r'^wechat/authsign', UserController.wxAuthSignView.as_view()),
+    url(r'^wechat/perfect', UserController.wxPerfectView.as_view()),
     # 分区分流
     path('Test', Test.Test.as_view()),
+    # 微信绑定的用户获取验证码
+    url(r'^oauth/authcode', UserController.OauthAuthCodeView.as_view()),
+    url(r'^oauth/perfect', UserController.OauthPerfectView.as_view()),
+    url(r'^oauth/unbunding', UserController.UnbundingWXView.as_view()),
+
+
     # 路由加参数参考
     # url(r'^(?P<path>.*)/(?P<UID>.*)/lls$', Test.Test.as_view(), name=u'gg'),
     re_path('(?P<path>.*)', LogManager.errorPath),

+ 1 - 1
Controller/AccessLog.py

@@ -14,7 +14,6 @@ from Service.ModelService import ModelService
 from Service.TemplateService import TemplateService
 from Ansjer.config import SERVER_TYPE
 from Object.RedisObject import RedisObject
-
 '''
 http://192.168.136.40:8077/accesslog?operation=queryByAdmin&token=test&page=1&line=5&order=-id
 http://192.168.136.40:8077/accesslog?operation=truncateByAdmin&token=test
@@ -24,6 +23,7 @@ http://192.168.136.40:8077/accesslog/staticPath/?token=stest
 '''
 
 
+
 class AccessLog(View):
     @method_decorator(csrf_exempt)
     def dispatch(self, *args, **kwargs):

+ 115 - 37
Controller/AppInfo.py

@@ -1,15 +1,18 @@
-from django.views.generic.base import View
+import time
+import traceback
+import os
+from django.shortcuts import render_to_response
 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 App_Info, App_Colophon
+from Object.ResponseObject import ResponseObject
+from Object.TokenObject import TokenObject
 from Service.CommonService import CommonService
 from Service.ModelService import ModelService
-from Model.models import App_Info,App_Colophon
-import traceback
-from Object.TokenObject import TokenObject
-from Object.ResponseObject import ResponseObject
-from django.shortcuts import render_to_response,render
-import simplejson as json
-import re,time
+from Ansjer.config import BASE_DIR, SERVER_DOMAIN
+
 '''
 http://192.168.136.45:8077/appInfo?operation=add&token=test&appBundleId=123456&appName=%E8%AF%BA%E5%9F%BA%E4%BA%9A1%E5%8F%B7&systemLanguage=US&content=dladfjklsjfdsajkdfasjkljlk&app_type=2&newAppversion=1234&bundleVersion=1234
 http://192.168.136.45:8077/appInfo?operation=update&token=test&appBundleId=1234&appName=%E8%AF%BA%E5%9F%BA%E4%BA%9A3%E5%8F%B7&systemLanguage=US&content=dladfjklsjfdsajkdfasjkljlk&app_type=2&newAppversion=555&id=6
@@ -27,10 +30,12 @@ class AppInfo(View):
 
     def get(self, request, *args, **kwargs):
         request.encoding = 'utf-8'
+        self.request = request
         return self.validation(request_dict=request.GET)
 
     def post(self, request, *args, **kwargs):
         request.encoding = 'utf-8'
+        self.request = request
         return self.validation(request_dict=request.POST)
 
     def validation(self, request_dict, *args, **kwargs):
@@ -79,7 +84,7 @@ class AppInfo(View):
                                          'downloadLink': app_info.downloadLink,
                                          'id': app_info.id,
                                          'bundleVersion': app_info.bundleVersion,
-                                         'minAppversion':app_info.minAppversion
+                                         'minAppversion': app_info.minAppversion
                                          })
         else:
             return response.json(444, 'app_type,appBundleId')
@@ -97,6 +102,7 @@ class AppInfo(View):
         bundleVersion = request_dict.get('bundleVersion', None)
         downloadLink = request_dict.get('downloadLink', None)
         minAppversion = request_dict.get('minAppversion', None)
+        f = self.request.FILES.get('file', None)
         param_flag = CommonService.get_param_flag(
             data=[appBundleId, appName, systemLanguage, minAppversion, newAppversion, content, app_type, bundleVersion])
         if param_flag is not True:
@@ -106,16 +112,32 @@ class AppInfo(View):
             return response.json(174)
         else:
             try:
-                app_Info = App_Info(
-                    appBundleId=appBundleId,
-                    appName=appName,
-                    newAppversion=newAppversion,
-                    systemLanguage=systemLanguage,
-                    content=content,
-                    app_type=app_type,
-                    bundleVersion=bundleVersion,
-                    minAppversion =minAppversion,
-                    downloadLink=downloadLink)
+                create_dict = {
+                    'appBundleId': appBundleId,
+                    'appName': appName,
+                    'newAppversion': newAppversion,
+                    'systemLanguage': systemLanguage,
+                    'content': content,
+                    'app_type': app_type,
+                    'bundleVersion': bundleVersion,
+                    'minAppversion': minAppversion,
+                    'downloadLink': downloadLink
+                }
+                # 产品图片
+                if f:
+                    try:
+                        rv_path = 'static/app/image/' + appBundleId + '.png'
+                        as_path = os.path.join(BASE_DIR, rv_path)
+                        if os.path.exists(as_path):
+                            os.remove(as_path)
+                        with open(as_path, 'wb+') as destination:
+                            for chunk in f.chunks():
+                                destination.write(chunk)
+                        create_dict['img'] = rv_path
+                    except Exception as e:
+                        print(repr(e))
+                        pass
+                app_Info = App_Info(**create_dict)
                 app_Info.save()
             except Exception:
                 errorInfo = traceback.format_exc()
@@ -131,7 +153,7 @@ class AppInfo(View):
                            'app_type': app_Info.app_type,
                            'id': app_Info.id,
                            'downloadLink': downloadLink,
-                           'minAppversion':app_Info.minAppversion,
+                           'minAppversion': app_Info.minAppversion,
                            'bundleVersion': app_Info.bundleVersion}
                     return response.json(0, res)
                 else:
@@ -151,6 +173,10 @@ class AppInfo(View):
             count = queryset.count()
             res = queryset[(page - 1) * line:page * line]
             send_json = CommonService.qs_to_dict(res)
+            for k, v in enumerate(send_json["datas"]):
+                if send_json['datas'][k]['fields']['img']:
+                    img = SERVER_DOMAIN + 'sysfile/' + send_json['datas'][k]['fields']['img']
+                    send_json["datas"][k]['fields']['img'] = img
             send_json['count'] = count
             return response.json(0, send_json)
         return response.json(0)
@@ -167,27 +193,53 @@ class AppInfo(View):
         content = request_dict.get('content', None)
         app_type = request_dict.get('app_type', None)
         bundleVersion = request_dict.get('bundleVersion', None)
-        minAppversion =  request_dict.get('minAppversion', None)
+        minAppversion = request_dict.get('minAppversion', None)
         downloadLink = request_dict.get('downloadLink', None)
-        if not all(
-                [appBundleId, appName, systemLanguage, newAppversion, content, app_type, bundleVersion]):
-            return response.json(444)
+        f = self.request.FILES.get('file', None)
         try:
+            res = {}
             app_info = App_Info.objects.get(id=id)
-            app_info.appBundleId = appBundleId
-            app_info.appName = appName
-            app_info.systemLanguage = systemLanguage
-            app_info.newAppversion = newAppversion
-            app_info.content = content
-            app_info.app_type = app_type
-            app_info.minAppversion = minAppversion
-            app_info.bundleVersion = bundleVersion
-            app_info.downloadLink = downloadLink
+            if appBundleId:
+                app_info.appBundleId = appBundleId
+            if appName:
+                app_info.appName = appName
+            if systemLanguage:
+                app_info.systemLanguage = systemLanguage
+            if newAppversion:
+                app_info.newAppversion = newAppversion
+            if content:
+                app_info.content = content
+            if app_type:
+                app_info.app_type = app_type
+            if minAppversion:
+                app_info.minAppversion = minAppversion
+            if bundleVersion:
+                app_info.bundleVersion = bundleVersion
+            if downloadLink:
+                app_info.downloadLink = downloadLink
+            if f:
+                try:
+                    rv_path = 'static/app/image/' + appBundleId + '.png'
+                    as_path = os.path.join(BASE_DIR, rv_path)
+                    print(as_path)
+                    if os.path.exists(as_path):
+                        os.remove(as_path)
+                    with open(as_path, 'wb+') as destination:
+                        for chunk in f.chunks():
+                            destination.write(chunk)
+                except Exception as e:
+                    print(repr(e))
+                    pass
+                else:
+                    app_info.img = rv_path
+                    res['img'] = SERVER_DOMAIN + 'sysfile/' + rv_path
             app_info.save()
         except Exception as e:
             return response.json(404, repr(e))
         else:
-            return response.json(0, {'update_id': app_info.id, 'update_time': str(app_info.update_time)})
+            res['update_id'] = app_info.id
+            res['update_time'] = str(app_info.update_time)
+            return response.json(0, res)
 
     def delete(self, request_dict, userID, response):
         own_perm = ModelService.check_perm(userID=userID, permID=10)
@@ -226,13 +278,14 @@ class AppVersionView(View):
         #     return render_to_response('appVersionLists_cn.html')
         # else:
         #     return render_to_response('appVersionLists_en.html')
-        queryset = App_Colophon.objects.filter(lang=lang,app_id__appBundleId=appBundleId,app_id__app_type=app_type).order_by('-version_time','-newApp_version')
+        queryset = App_Colophon.objects.filter(lang=lang, app_id__appBundleId=appBundleId,
+                                               app_id__app_type=app_type).order_by('-version_time', '-newApp_version')
         queryset_dict = CommonService.qs_to_dict(queryset).get('datas')
-        print (queryset_dict)
+        print(queryset_dict)
         # 修改数据逻辑改装数据返回值
         for k, v in enumerate(queryset_dict):
             content = v['fields']['content']
-            content = content.split('\n') #分割字符串
+            content = content.split('\n')  # 分割字符串
             v['fields']['content'] = content
             # 时间戳转日期
             version_time = v['fields']['version_time']
@@ -241,5 +294,30 @@ class AppVersionView(View):
         return render_to_response('appVerList.html', locals())
 
 
+class AppIdDataView(View):
+
+    def get(self, request):
+        request.encoding = 'utf-8'
+        return self.validation(request_dict=request.GET)
 
+    def post(self, request):
+        request.encoding = 'utf-8'
+        return self.validation(request_dict=request.POST)
 
+    def validation(self, request_dict):
+        response = ResponseObject()
+        token = request_dict.get('token', None)
+        tko = TokenObject(token)
+        if tko.code == 0:
+            # 获取appbulidID
+            res = {'ios': [], 'android': []}
+            qs = App_Info.objects.filter().values('appBundleId', 'appName', 'app_type')
+            print(qs)
+            for q in qs:
+                if q['app_type'] == 1:
+                    res['ios'].append({'appBundleId': q['appBundleId'], 'appName': q['appName']})
+                if q['app_type'] == 2:
+                    res['android'].append({'appBundleId': q['appBundleId'], 'appName': q['appName']})
+            return response.json(0, res)
+        else:
+            return response.json(tko.code)

+ 1 - 1
Controller/CheckUserData.py

@@ -39,7 +39,7 @@ class DataValid:
     def __init__(self):
         # 用户名正则
         # self.re_name = re.compile(r'^[A-Za-z0-9\u4e00-\u9fa5\.\_]{1,16}$')
-        self.re_name = re.compile(r'^[A-Za-z0-9\u4e00-\u9fa5\.\_\-\@]{4,40}$')
+        self.re_name = re.compile(r'^[A-Za-z0-9\u4e00-\u9fa5\.\_\-\@]{4,64}$')
         # 密码强度正则
         self.re_password = re.compile(r'^[\w\.\_\@\-]{1,16}$')
         # 手机号码正则

+ 311 - 191
Controller/DetectController.py

@@ -11,46 +11,43 @@
 @file: DetectController.py
 @Contact: chanjunkai@163.com
 """
-import json
-import os
 import time
-from pyfcm import FCMNotification
-
+import os
 import apns2
 import jpush as jpush
 import oss2
+from django.http import JsonResponse
 from django.utils.decorators import method_decorator
 from django.views.decorators.csrf import csrf_exempt
 from django.views.generic.base import View
-from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, BASE_DIR, DETECT_PUSH_DOMAIN
+from pyfcm import FCMNotification
+
+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 Object.RedisObject import RedisObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Object.UidTokenObject import UidTokenObject
-from django.http import JsonResponse
-from Object.RedisObject import RedisObject
 from Service.CommonService import CommonService
+from Object.ETkObject import ETkObject
+'''
+http://test.dvema.com/detect/changeStatus?push_type=2&token_val=1507bfd3f7ba3bbb551&appBundleId=com.ansjer.zccloud_ab&tz=+08.00&uid=T4AZ3CUKCERH9FZA111A&status=1&m_code=AN020000own000000unkn.zccloud_ab&token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NzUxOTAxNjksInVzZXJJRCI6IjE1Njc3NTgyMTg2MTkxMzgwMDEzODAwMCIsImxhbmciOiJ0YyIsInVzZXIiOiIxMzExOTY1NzcxMyJ9.rQ11jA3IQPxQofFbZyG0nvLhGVcxOR82N2qQ8i04VuU&lang=tc&app_type=2
+http://test.push.dvema.com/notify/push?uidToken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiJUNEFaM0NVS0NFUkg5RlpBMTExQSJ9.GtrXeq5gb2Z9M3mKECxi9eNQbPxqC-6PtgJkOOg6PwI&n_time=1598456451&channel=1&event_type=1&is_st=1
+'''
 
-
-# http://192.168.136.40:8077/detect/changeStatus?uid=JW3684H8BSHG9TTM111A&token_val=18071adc03536302f34&appBundleId=com.ansjer.zccloud_ab&push_type=2&token=local&status=1&app_type=1&m_code=12
 class DetectControllerView(View):
-    @method_decorator(csrf_exempt)
-    def dispatch(self, *args, **kwargs):
-        return super(DetectControllerView, self).dispatch(*args, **kwargs)
-
-    def __init__(self):
-        self.ip = ''
 
     def get(self, request, *args, **kwargs):
         request.encoding = 'utf-8'
         operation = kwargs.get('operation')
-        self.ip = CommonService.get_ip_address(request)
+        # 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)
+        # self.ip = CommonService.get_ip_address(request)
         return self.validation(request.POST, operation)
 
     def validation(self, request_dict, operation):
@@ -78,26 +75,31 @@ class DetectControllerView(View):
     def do_query(self, request_dict, response, userID):
         page = int(request_dict.get('page', None))
         line = int(request_dict.get('line', None))
-        nowTime = int(time.time())
         if not page or not line:
             return response.json(444, 'page,line')
-
-        qs = Equipment_Info.objects.filter(userID_id=userID, addTime__gte=nowTime - 3600 * 24 * 27)
-        uid = request_dict.get('uid', None)
-        if uid:
-            qs = qs.filter(devUid=uid)
-            dvqs = Device_Info.objects.filter(UID=uid).values('Type', 'NickName')
-            uid_type_dict = {uid: {'type': dvqs[0]['Type'], 'NickName': dvqs[0]['NickName']}}
+        startTime = request_dict.get('startTime', None)
+        endTime = request_dict.get('endTime', None)
+        qs = Equipment_Info.objects.filter(userID_id=userID)
+        if startTime and endTime:
+            qs = qs.filter(addTime__range=(startTime, endTime))
+        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)
+        # 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')
+                       'receiveTime', 'is_st', 'addTime')
         count = qs.count()
         qr = qs[(page - 1) * line:page * line]
         res = []
@@ -117,7 +119,7 @@ class DetectControllerView(View):
                 # 列表装载回放时间戳标记
                 vodqs = VodHlsModel.objects.filter(uid=devUid, channel=channel, time=int(eventTime)) \
                     .values("bucket__bucket", "bucket__endpoint")
-                print(vodqs)
+                # print(vodqs)
                 if vodqs.exists():
                     bucket_name = vodqs[0]['bucket__bucket']
                     endpoint = vodqs[0]['bucket__endpoint']
@@ -136,7 +138,7 @@ class DetectControllerView(View):
             res.append(p)
         return response.json(0, {'datas': res, 'count': count})
 
-    def do_change_status(self, userID, request_dict, response):
+    def do_change_status1(self, userID, request_dict, response):
         uid = request_dict.get('uid', None)
         token_val = request_dict.get('token_val', None)
         appBundleId = request_dict.get('appBundleId', None)
@@ -146,20 +148,32 @@ class DetectControllerView(View):
         m_code = request_dict.get('m_code', None)
         # 设备语言
         lang = request_dict.get('lang', 'en')
+        tz = request_dict.get('tz', '0')
         # interval = request_dict.get('interval', None)
-        print('status:' + status)
         if not status:
             return response.json(444, 'status')
         # 关闭推送
         if not all([appBundleId, app_type, token_val, uid, m_code]):
             return response.json(444, 'appBundleId,app_type,token_val,uid,m_code')
+        # 判断推送类型对应key是否存在
+        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)
         if dvqs.exists():
             # 获取用户区域
-            ip = self.ip
-            ipInfo = CommonService.getIpIpInfo(ip=ip, lang='EN')
-            area = ipInfo['country_name']
+            # ip = self.ip
+            # ipInfo = CommonService.getIpIpInfo(ip=ip, lang='EN')
+            # area = ipInfo['country_name']
             # if area == 'China':
             #     DETECT_PUSH_DOMAIN = 'cn.push.dvema.com'
             # else:
@@ -175,7 +189,8 @@ class DetectControllerView(View):
                     'push_type': push_type,
                     'token_val': token_val,
                     'updTime': nowTime,
-                    'lang': lang
+                    'lang': lang,
+                    'tz': tz
                 }
                 uid_set_qs.update(detect_status=status, updTime=nowTime)
                 UidPushModel.objects.filter(userID_id=userID, m_code=m_code, uid_set__uid=uid). \
@@ -219,7 +234,8 @@ class DetectControllerView(View):
                     'm_code': m_code,
                     'addTime': nowTime,
                     'updTime': nowTime,
-                    'lang': lang
+                    'lang': lang,
+                    'tz': tz
                 }
                 # 绑定设备推送
                 UidPushModel.objects.create(**uid_push_create_dict)
@@ -233,6 +249,104 @@ class DetectControllerView(View):
         else:
             return response.json(14)
 
+    def do_change_status(self, userID, request_dict, response):
+        uid = request_dict.get('uid', None)
+        token_val = request_dict.get('token_val', None)
+        appBundleId = request_dict.get('appBundleId', None)
+        app_type = request_dict.get('app_type', None)
+        push_type = request_dict.get('push_type', None)
+        status = request_dict.get('status', None)
+        m_code = request_dict.get('m_code', None)
+        # 设备语言
+        lang = request_dict.get('lang', 'en')
+        tz = request_dict.get('tz', '0')
+        # interval = request_dict.get('interval', None)
+        if not status:
+            return response.json(444, 'status')
+        # 关闭推送
+        if not all([appBundleId, app_type, token_val, uid, m_code]):
+            return response.json(444, 'appBundleId,app_type,token_val,uid,m_code')
+        # 判断推送类型对应key是否存在
+        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 = 'cn.push.dvema.com'
+        # else:
+        #     DETECT_PUSH_DOMAIN = 'en.push.dvema.com'
+        nowTime = int(time.time())
+        if dvqs.exists():
+            uid_set_qs = UidSetModel.objects.filter(uid=uid)
+            # uid配置信息是否存在
+            if uid_set_qs.exists():
+                uid_set_id = uid_set_qs[0].id
+            else:
+                uid_set_create_dict = {
+                    'uid': uid,
+                    'addTime': nowTime,
+                    'updTime': nowTime,
+                    'detect_status': status,
+                }
+                # 添加设备配置
+                uid_set_qs = UidSetModel.objects.create(**uid_set_create_dict)
+                uid_set_id = uid_set_qs.id
+            uid_set_qs.update(detect_status=status, updTime=nowTime)
+            if status == 0:
+                UidPushModel.objects.filter(uid_set__uid=uid).delete()
+                return response.json(0)
+            elif status == 1:
+                uid_push_qs = UidPushModel.objects.filter(userID_id=userID, m_code=m_code, uid_set__uid=uid)
+                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)
+                utko = UidTokenObject()
+                # right
+                utko.generate(data={'uid': uid})
+                detectUrl = "{DETECT_PUSH_DOMAIN}notify/push?uidToken={uidToken}". \
+                    format(uidToken=utko.token, DETECT_PUSH_DOMAIN=DETECT_PUSH_DOMAIN)
+                return response.json(0, {'detectUrl': detectUrl})
+        else:
+            return response.json(14)
+
     def do_update_interval(self, userID, request_dict, response):
         uid = request_dict.get('uid', None)
         interval = request_dict.get('interval', None)
@@ -277,27 +391,30 @@ class NotificationView(View):
             # return response.json(444)
         utko = UidTokenObject(uidToken)
         uid = utko.UID
+        redisObj = RedisObject(db=6)
+        pkey = '{uid}_{channel}_ptl'.format(uid=uid, channel=channel)
+        if redisObj.get_data(key=pkey):
+            res_data = {'code': 0, 'msg': 'success,!'}
+            return JsonResponse(status=200, data=res_data)
+        else:
+            # 设置推送间隔60秒一次
+            redisObj.set_data(key=pkey, val=1, expire=60)
         uid_set_qs = UidSetModel.objects.filter(uid=uid, detect_status=1)
         if uid_set_qs.exists():
             uid_set_id = uid_set_qs[0].id
             nickname = uid_set_qs[0].nickname
+            if not nickname:
+                nickname = uid
             uid_push_qs = UidPushModel.objects.filter(uid_set__id=uid_set_id). \
-                values('token_val', 'app_type', 'appBundleId', 'push_type', 'userID_id', 'userID__NickName', 'lang')
-            if uid_set_qs.exists():
-                redisObj = RedisObject(db=6)
-                pkey = '{uid}_{channel}_ptl'.format(uid=uid, channel=channel)
-                if redisObj.get_data(key=pkey):
-                    res_data = {'code': 0, 'msg': 'success,!'}
-                    return JsonResponse(status=200, data=res_data)
-                else:
-                    detect_interval = uid_set_qs[0].detect_interval
-                    if detect_interval:
-                        redisObj.set_data(key=pkey, val=1, expire=detect_interval)
+                values('token_val', 'app_type', 'appBundleId', 'push_type', 'userID_id', 'userID__NickName', 'lang',
+                       'tz')
+            if uid_push_qs.exists():
                 auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
                 bucket = oss2.Bucket(auth, 'oss-cn-shenzhen.aliyuncs.com', 'apg')
                 for up in uid_push_qs:
                     push_type = up['push_type']
                     # ios apns
+                    print(push_type)
                     if push_type == 0:
                         self.do_apns(request_dict, up, response, uid, channel, nickname)
                     # android gcm
@@ -326,53 +443,14 @@ class NotificationView(View):
 
     def do_jpush(self, request_dict, uaql, response, uid, channel, nickname):
         event_type = request_dict.get('event_type', None)
-        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': '8fc4f495685bde53341ee25dMaster',
-                'Secret': 'f1da11fa466509fa2670fb66',
-            }
-        }
         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 = 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()
@@ -382,19 +460,8 @@ class NotificationView(View):
         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}
-        n_date = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(int(n_time)))
-        if lang == 'cn':
-            if nickname:
-                message_title = "周视({nickname})".format(nickname=nickname)
-            else:
-                message_title = "周视({uid})".format(uid=uid)
-            send_text = '通道:{channel} 日期:{date}'.format(channel=channel, date=n_date)
-        else:
-            if nickname:
-                message_title = "zosi({nickname})".format(nickname=nickname)
-            else:
-                message_title = "zosi({uid})".format(uid=uid)
-            send_text = 'channel:{channel} date:{date}'.format(channel=channel, date=n_date)
+        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)
         android = jpush.android(alert=send_text, priority=1, style=1, alert_type=7,
                                 big_text=send_text, title=message_title,
                                 extras=push_data)
@@ -412,75 +479,47 @@ class NotificationView(View):
         else:
             return response.json(0)
 
-    '''
-    def do_gmc(self, request_dict, uaql, response, uid, channel):
-
-        n_time = request_dict.get('n_time')
-        appBundleId = uaql['appBundleId']
-        token_val = uaql['token_val']
-        gcm_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',
+    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',
         }
-        serverKey = gcm_config[appBundleId]
-        event_type = request_dict.get('event_type', None)
-        push_data = {"alert": "Motion ", "event_time": n_time, "event_type": event_type, "msg": "",
-                     "received_at": n_time, "sound": "sound.aif", "uid": uid, "zpush": "1"}
-        json_data = {
-            "collapse_key": "WhatYouWant",
-            "data": push_data,
-            "delay_while_idle": False,
-            "time_to_live": 3600,
-            "registration_ids": [token_val]
-        }
-
-        url = 'https://android.googleapis.com/gcm/send'
-        # serverKey = "AAAAb9YP3rk:APA91bHu8u-CTpcd0g6lKPo0WNVqCi8jZub1cPPbSAY9AucT1HxlF65ZDUko9iG8q2ch17bwu9YWHpK1xI1gHSRXCslLvZlXEmHZC0AG3JKg15XuUvlFKACIajUFV-pOeGRT8tM6-31I"
+        if appBundleId in package_title_config.keys():
+            return package_title_config[appBundleId] + '(' + nickname + ')'
+        else:
+            return nickname
 
-        data = json.dumps(json_data).encode('utf-8')
-        headers = {'Content-Type': 'application/json', 'Authorization': 'key=%s' % serverKey}
-        req = requests.post(url, data, headers=headers)
-        return response.json(0)
-    '''
+    def get_send_text(self, channel, n_time, lang, tz):
+        n_date = CommonService.get_now_time_str(n_time=n_time, tz=tz)
+        send_text = 'channel:{channel} date:{date}'.format(channel=channel, date=n_date)
+        if lang == 'cn':
+            send_text = '通道:{channel} 日期:{date}'.format(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']
-        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'
-        }
+        tz = uaql['tz']
         try:
-            serverKey = fcm_config[appBundleId]
+            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
-        n_date = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(int(n_time)))
-        if lang == 'cn':
-            if nickname:
-                message_title = "周视({nickname})".format(nickname=nickname)
-            else:
-                message_title = "周视({uid})".format(uid=uid)
-            send_text = '通道:{channel} 日期:{date}'.format(channel=channel, date=n_date)
-        else:
-            if nickname:
-                message_title = "zosi({nickname})".format(nickname=nickname)
-            else:
-                message_title = "zosi({uid})".format(uid=uid)
-            send_text = 'channel:{channel} date:{date}'.format(channel=channel, date=n_date)
+        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)
         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,
@@ -499,28 +538,15 @@ class NotificationView(View):
         lang = uaql['lang']
         n_time = request_dict.get('n_time')
         appBundleId = uaql['appBundleId']
-        apns_config = {
-            'com.ansjer.loocamccloud': {
-                'pem_path': os.path.join(BASE_DIR, 'Ansjer/file/apns_pem/apns-dev-test.pem'),
-                'password': '111111'
-            }
-        }
-        n_date = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(int(n_time)))
-        if lang == 'cn':
-            if nickname:
-                message_title = "周视({nickname})".format(nickname=nickname)
-            else:
-                message_title = "周视({uid})".format(uid=uid)
-            send_text = '通道:{channel} 日期:{date}'.format(channel=channel, date=n_date)
-        else:
-            if nickname:
-                message_title = "zosi({nickname})".format(nickname=nickname)
-            else:
-                message_title = "zosi({uid})".format(uid=uid)
-            send_text = 'channel:{channel} date:{date}'.format(channel=channel, date=n_date)
+        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)
         try:
-            cli = apns2.APNSClient(mode="dev", client_cert=apns_config[appBundleId]['pem_path'],
-                                   password=apns_config[appBundleId]['password'])
+            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)
@@ -529,12 +555,15 @@ class NotificationView(View):
             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 
+            # 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):
@@ -542,21 +571,112 @@ class NotificationView(View):
         qs_list = []
         nowTime = int(time.time())
         # 设备昵称
+        userID_ids = []
+        for dv in uaqs:
+            userID_id = dv["userID_id"]
+            if userID_id not in userID_ids:
+                add_data = {
+                    'userID_id': dv["userID_id"],
+                    'eventTime': n_time,
+                    'eventType': event_type,
+                    'devUid': uid,
+                    'devNickName': uid,
+                    '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)
+            return True
+        else:
+            return False
+
+
+# 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)
+            # 推送时间限制
+            if redisObj.get_data(key=pkey):
+                res_data = {'code': 0, 'msg': 'success,!'}
+                return JsonResponse(status=200, data=res_data)
+            else:
+                redisObj.set_data(key=pkey, val=1, expire=60)
+            uid_set_qs = UidSetModel.objects.filter(uid=uid, detect_status=1)
+            if uid_set_qs.exists():
+                uid_set_id = uid_set_qs[0].id
+                uid_push_qs = UidPushModel.objects.filter(uid_set__id=uid_set_id). \
+                    values('token_val', 'app_type', 'appBundleId', 'push_type',
+                           'userID_id', 'userID__NickName', 'lang', 'tz')
+                if uid_set_qs.exists():
+                    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)
+                    if is_st == '0' or is_st == '2':
+                        return JsonResponse(status=200, data={'code': 0, 'msg': 'success'})
+                    else:
+                        # 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)
+                else:
+                    return JsonResponse(status=200, data={'code': 404, 'msg': 'data is not exist'})
+            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):
+        #
+        qs_list = []
+        nowTime = int(time.time())
+        # 设备昵称
+        userID_ids = []
         for dv in uaqs:
-            add_data = {
-                'userID_id': dv["userID_id"],
-                'eventTime': n_time,
-                'eventType': event_type,
-                'devUid': uid,
-                'devNickName': uid,
-                '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_id = dv["userID_id"]
+            if userID_id not in userID_ids:
+                add_data = {
+                    'userID_id': dv["userID_id"],
+                    'eventTime': n_time,
+                    'eventType': event_type,
+                    'devUid': uid,
+                    'devNickName': uid,
+                    '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)

+ 22 - 19
Controller/DeviceShare.py

@@ -12,18 +12,18 @@
 @Contact: chanjunkai@163.com
 """
 
+import json
+import time
+
 from django.views.generic.base import View
 
+from Ansjer.config import SERVER_DOMAIN
 from Model.models import Device_Info, Device_User
+from Model.models import UID_Bucket
+from Object.RedisObject import RedisObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
-from Ansjer.config import SERVER_DOMAIN
-import jwt
 from Service.CommonService import CommonService
-from Model.models import UID_Bucket
-from Object.RedisObject import RedisObject
-import time
-import json
 
 
 class DeviceShareView(View):
@@ -107,20 +107,23 @@ class DeviceShareView(View):
                 UID = data.get('UID', None)
                 sharerDvqs = Device_Info.objects.filter(userID_id=sharer, UID=UID, isShare=False). \
                     values('NickName', 'Type')
-                sharerDuqs = Device_User.objects.filter(userID=sharer).values('username', 'userEmail', 'phone')
-                if sharerDuqs[0]['username']:
-                    share_user = sharerDuqs[0]['username']
-                elif sharerDuqs[0]['userEmail']:
-                    share_user = sharerDuqs[0]['userEmail']
-                elif sharerDuqs[0]['phone']:
-                    share_user = sharerDuqs[0]['phone']
+                if sharerDvqs.exists():
+                    sharerDuqs = Device_User.objects.filter(userID=sharer).values('username', 'userEmail', 'phone')
+                    if sharerDuqs[0]['username']:
+                        share_user = sharerDuqs[0]['username']
+                    elif sharerDuqs[0]['userEmail']:
+                        share_user = sharerDuqs[0]['userEmail']
+                    elif sharerDuqs[0]['phone']:
+                        share_user = sharerDuqs[0]['phone']
+                    else:
+                        share_user = ''
+                    return response.json(0, {
+                        'deviceName': sharerDvqs[0]['NickName'],
+                        'deviceType': sharerDvqs[0]['Type'],
+                        'shareUser': share_user,
+                    })
                 else:
-                    share_user = ''
-                return response.json(0, {
-                    'deviceName': sharerDvqs[0]['NickName'],
-                    'deviceType': sharerDvqs[0]['Type'],
-                    'shareUser': share_user,
-                })
+                    return response.json(173)
             else:
                 return response.json(119)
         else:

+ 147 - 0
Controller/DynamoDBLog.py

@@ -0,0 +1,147 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+"""
+@Copyright (C) ansjer cop Video Technology Co.,Ltd.All rights reserved.
+@AUTHOR: ASJRD019
+@NAME: AnsjerFormal
+@software: PyCharm
+@DATE: 2019/10/9 11:50
+@Version: python3.6
+@MODIFY DECORD:ansjer dev
+@file: AliPayObject.py
+@Contact: pzb3076@163.com
+"""
+
+from django.views.generic.base import View
+from django.utils.decorators import method_decorator
+from django.views.decorators.csrf import csrf_exempt
+from Service.ModelService import ModelService
+from Model.models import User_Brand,Device_User
+from django.utils import timezone
+import traceback,time,json,urllib.request
+from Object.ResponseObject import ResponseObject
+from Object.TokenObject import TokenObject
+from Service.CommonService import CommonService
+from collections import Counter
+from Ansjer.config import DOMAIN_HOST,AWS_DynamoDB_REGION,AWS_DynamoDB_ACCESS_KEY,AWS_DynamoDB_SECRET_KEY
+from Object.RedisObject import RedisObject
+from Service.MiscellService import MiscellService
+import datetime, simplejson as json
+import time
+'''
+http://192.168.136.39:8000/dynamoDBLog/searchByAdmin?search_value=154390905041313800138000&token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VySUQiOiIxNTQzOTA5MDUwNDEzMTM4MDAxMzgwMDAiLCJsYW5nIjoiY24iLCJ1c2VyIjoiMTM4MDAxMzgwMDEiLCJtX2NvZGUiOiIxMjM0MTMyNDMyMTQiLCJleHAiOjE1NzMyNjc3OTR9.YWNEHKKrzFfEc4liz6N8ANQl8C1VfhhLv_MEOqf3yV4&page=1&line=12
+
+
+http://192.168.136.39:8000/dynamoDBLog/connector?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VySUQiOiIxNTQzOTA5MDUwNDEzMTM4MDAxMzgwMDAiLCJsYW5nIjoiY24iLCJ1c2VyIjoiMTM4MDAxMzgwMDEiLCJtX2NvZGUiOiIxMjM0MTMyNDMyMTQiLCJleHAiOjE1NzMyNjc3OTR9.YWNEHKKrzFfEc4liz6N8ANQl8C1VfhhLv_MEOqf3yV4
+
+ '''
+class DynamoDBLog(View):
+    @method_decorator(csrf_exempt)
+    def dispatch(self, *args, **kwargs):
+        return super(DynamoDBLog, self).dispatch(*args, **kwargs)
+
+    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):
+        self.clientIP = CommonService.get_ip_address(request)
+        response = ResponseObject()
+        token = request_dict.get('token', None)
+        tko = TokenObject(token)
+        response.lang = tko.lang
+        if tko.code == 0:
+            userID = tko.userID
+            if operation == 'searchByAdmin':
+                return self.search_info(request_dict, userID, response)
+            elif operation == 'connector':
+                return self.connector_info(request_dict, userID, response)
+            elif operation == 'daySearch':
+                return self.get_day_search(request_dict, userID, response)
+            else:
+                return response.json(444)
+        else:
+            return response.json(tko.code)
+
+    # 查询搜索表(可以通过用户名,和接口名称,ip地址搜索等)
+    def search_info(self, request_dict, userID,response):
+        search_value = request_dict.get('search_value',None)
+        check_perm = ModelService.check_perm(userID=userID,permID=30)
+        if check_perm is True:
+            if search_value is None or search_value is '':
+                return response.json(0, {'datas': {}, 'count': 0})
+            else:
+                if DOMAIN_HOST == 'www.dvema.com':
+                    user_brand = 'access_log'
+                else:
+                    user_brand = 'test_access_log'
+                # 查询
+                user_ID = Device_User.objects.filter(username=search_value).values('userID', 'NickName')
+                try:
+                    search_value = user_ID[0]['userID']
+                except Exception:
+                    search_value = search_value
+                items = MiscellService.get_item_log( user_brand ,search_value)
+                for k, v in enumerate(items):
+                    user_ID = Device_User.objects.filter(userID=items[k]['userID']).values('username')
+                    try:
+                        items[k]['userID'] = user_ID[0]['username']
+                    except Exception:
+                        items[k]['userID'] = ''
+                return response.json(0, {'datas': items, 'count': len(items)})
+        else:
+            return response.json(404)
+
+    # 查询接口的访问量的对应数量
+    def connector_info(self, request_dict, userID,response):
+        check_perm = ModelService.check_perm(userID=userID,permID=30)
+        if check_perm is True:
+            if DOMAIN_HOST == 'www.dvema.com':
+                user_brand = 'access_log'
+            else:
+                user_brand = 'test_access_log'
+            table_value = MiscellService.item_get_brand(user_brand)
+            send_jsons = []
+            counts = 0
+            for i in table_value:
+                send_jsons.append(table_value[counts]['operation'])
+                counts = counts + 1
+            send_jsons = Counter(send_jsons)
+            return response.json(0, {'datas': send_jsons,'counts':counts})
+        else:
+            return response.json(404)
+
+    # 通过传过来日期天来搜索,访问量,并返回对应小时的访问数量
+    def get_day_search(self, request_dict,userID, response):
+        check_perm = ModelService.check_perm(userID=userID, permID=30)
+        if DOMAIN_HOST == 'www.dvema.com':
+            user_brand = 'access_log'
+        else:
+            user_brand = 'test_access_log'
+        time_stamp = int(request_dict.get('timestamp', None))
+        if check_perm is True:
+            # 分割小时再去搜索
+            times = datetime.datetime.fromtimestamp(time_stamp)
+            time_dict = CommonService.getTimeDict(times)
+            res = {}
+            for k, v in time_dict.items():
+                start_date = time_dict[k]
+                end_date = time_dict[k] + datetime.timedelta(hours=1)
+                start_date = int(start_date.timestamp())
+                end_date = int(end_date.timestamp())
+                count = MiscellService.get_item_time(user_brand,start_date, end_date)
+                if count:
+                    res[k] = count
+                else:
+                    res[k] = 0
+
+            # res = MiscellService.get_item_date(user_brand,time_stamp)
+            return response.json(0, {'count': res})
+        else:
+            return response.json(404)

+ 0 - 92
Controller/EquipmentInfo.py

@@ -358,98 +358,6 @@ class EquipmentInfo(View):
             return response.json(404)
 
 
-# http://192.168.136.40:8077/detect/add?UID=FTSLL8HM437Z38WU111A&Channel=0&eventType=1&eventTime=1234567890
-# 设备推送信息添加接口
-class AddDetectionView(TemplateView):
-    @method_decorator(csrf_exempt)
-    def dispatch(self, *args, **kwargs):
-        return super(AddDetectionView, self).dispatch(*args, **kwargs)
-
-    def get(self, request, *args, **kwargs):
-        request.encoding = 'utf-8'
-        return self.validation(request_dict=request.GET)
-
-    def post(self, request, *args, **kwargs):
-        request.encoding = 'utf-8'
-        return self.validation(request_dict=request.POST)
-
-    def validation(self, request_dict, *args, **kwargs):
-        response = ResponseObject()
-        # 设备添加token
-        uidToken = request_dict.get('uidToken', None)
-        Channel = request_dict.get('Channel', None)
-        eventType = request_dict.get('eventType', None)
-        eventTime = request_dict.get('eventTime', None)
-        utko = UidTokenObject(uidToken)
-        if utko.flag is False:
-            return response.json(444, 'tidToken is wrong')
-        UID = utko.UID
-        if not Channel or not eventType or not eventTime:
-            return response.json(444, 'uidToken,Channel,eventType,eventTime')
-        dv_qs = Device_Info.objects.filter(UID=UID, iSNotification=True).values("userID_id", "NickName")
-        if not dv_qs.exists():
-            return response.json(10, 'device not detect')
-        qs_list = []
-        for dv in dv_qs:
-            add_data = {
-                'userID_id': dv["userID_id"],
-                'devUid': UID,
-                'Channel': Channel,
-                'eventType': eventType,
-                'eventTime': eventTime,
-                'devNickName': dv["NickName"],
-            }
-            qs_list.append(Equipment_Info(**add_data))
-        if qs_list:
-            print(1)
-            Equipment_Info.objects.bulk_create(qs_list)
-            print(2)
-            return response.json(0)
-        else:
-            return response.json(10, '无设备开启')
-
-
-# http://192.168.136.40:8077/detect/status?token=local&id=138001380001543918745881545&iSNotification=0
-# 设备推送开关
-class DetectStatusView(View):
-    @method_decorator(csrf_exempt)
-    def dispatch(self, *args, **kwargs):
-        return super(DetectStatusView, self).dispatch(*args, **kwargs)
-
-    def get(self, request, *args, **kwargs):
-        request.encoding = 'utf-8'
-        return self.validation(request_dict=request.GET)
-
-    def post(self, request, *args, **kwargs):
-        request.encoding = 'utf-8'
-        return self.validation(request_dict=request.POST)
-
-    def validation(self, request_dict, *args, **kwargs):
-        token = request_dict.get('token', None)
-        id = request_dict.get('id', None)
-        iSNotification = request_dict.get('iSNotification', None)
-        response = ResponseObject()
-        if token is None:
-            return response.json(309)
-        tko = TokenObject(token)
-        response.lang = tko.lang
-        if tko.code != 0:
-            return response.json(tko.code)
-        userID = tko.userID
-        return self.do_update(userID, id, iSNotification, response)
-
-    def do_update(self, userID, id, iSNotification, response):
-        qs = Device_Info.objects.filter(id=id, userID_id=userID)
-        if qs.exists():
-            qs.update(iSNotification=iSNotification)
-            data = {'uid': qs[0].UID}
-            utko = UidTokenObject()
-            uid_token = utko.generate(data)
-            return response.json(0, {'uid_token': uid_token,
-                                     'push_url': '{SERVER_DOMAIN}detect/add'.format(SERVER_DOMAIN=SERVER_DOMAIN)})
-        else:
-            return response.json(173)
-
 '''
 use information_schema;
 select concat(round(sum(data_length/1024/1024),2),'MB') as data from tables where table_schema='Ansjer81';

+ 14 - 12
Controller/EquipmentManager.py

@@ -338,15 +338,17 @@ def addInterface(request):
                                                  View_Password=View_Password, Type=Type, ChannelIndex=ChannelIndex)
                         userDevice.save()
                         nowTime = int(time.time())
-                        uid_set_create_dict = {
-                            'uid': UID,
-                            'addTime': nowTime,
-                            'updTime': nowTime,
-                            'ip': CommonService.get_ip_address(request),
-                            'channel': ChannelIndex,
-                            'nickname': NickName,
-                        }
-                        UidSetModel.objects.create(**uid_set_create_dict)
+                        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),
+                                'channel': ChannelIndex,
+                                'nickname': NickName,
+                            }
+                            UidSetModel.objects.create(**uid_set_create_dict)
                     except Exception as e:
                         return response.json(10, repr(e))
                     else:
@@ -569,11 +571,11 @@ def deleteInterface(request):
                 # a.主用户删除设备
                 dv_qs.delete()
                 # 删除设备影子信息uid_set   外键关联删除设备推送配置信息 uid_push
-                up_qs = UidPushModel.objects.filter(uid=uid)
-                if up_qs.count > 1:
+                up_qs = UidPushModel.objects.filter(uid_set__uid=uid)
+                if up_qs.count() > 1:
                     UidPushModel.objects.filter(uid_set__uid=uid, userID_id=userID).delete()
                 else:
-                    UidSetModel.objects.filter(uid=uid).delete()
+                    up_qs.delete()
                 # b.分享获得用户假删除
                 ud_dv_qs = Device_Info.objects.filter(UID=uid, isShare=True, primaryUserID=userID)
                 if ud_dv_qs.exists():

+ 35 - 8
Controller/EquipmentOTA.py

@@ -21,6 +21,8 @@ http://192.168.136.45:8077/equipment/OTA?token=test&operation=query&page=1&line=
 http://192.168.136.45:8077/equipment/OTA?token=test&operation=find&page=1&line=10&content={}
 http://192.168.136.40:8077/equipment/OTA?eid=138001524641441203480138000&token=test&operation=delete
 http://192.168.136.40:8077/equipment/OTA?eid=138001524641441203480138000&token=test&operation=update&status=1
+https://cdna.artstation.com/p/assets/images/images/004/727/674/large/daniel-dociu-snowcavels.jpg?1485828233&dl=1
+https://cdna.artstation.com/p/assets/images/images/004/693/910/large/daniel-dociu-smoothsailing.jpg?1485560128&dl=1
 '''
 
 
@@ -150,14 +152,14 @@ class EquipmentVersionView(View):
     def get(self, request, *args, **kwargs):
         request.encoding = 'utf-8'
         operation = kwargs.get('operation')
-        return self.validation(request.GET, operation)
+        return self.validation(request.GET, operation,request)
 
     def post(self, request, *args, **kwargs):
         request.encoding = 'utf-8'
         operation = kwargs.get('operation')
-        return self.validation(request.POST, operation)
+        return self.validation(request.POST, operation,request)
 
-    def validation(self, request_dict, operation):
+    def validation(self, request_dict, operation, request):
         response = ResponseObject()
         if operation is None:
             return response.json(444, 'error path')
@@ -178,26 +180,51 @@ class EquipmentVersionView(View):
         if operation == 'query':
             return self.do_query(request_dict, response)
         if operation == 'update':
-            return self.do_update(request_dict, response)
+            return self.do_update(request_dict, response,request)
         if operation == 'filter':
             return self.do_filter(request_dict, response)
         else:
             return response.json(444, 'error path')
 
-    def do_update(self, request_dict, response):
+    def do_update(self, request_dict, response,request):
         code = request_dict.get('code', None)
         status = request_dict.get('status', None)
         lang = request_dict.get('lang', None)
+
+        file_s = request.FILES.get('file', None)
+        paths = 'static/versions/image'
+        if not os.path.exists(paths):
+            os.makedirs(paths)  # makedirs 创建文件时如果路径不存在会创建这个路径
+            # print ('该文件不存在')
+        else:
+            print ('该文件存在')
+        ev = Equipment_Version.objects.filter(code=code, lang=lang)
+        if file_s is None:
+             rv_path = 'static/versions/image/' + code + '.png'
+             img = SERVER_DOMAIN + 'sysfile/' + rv_path
+        else:
+            rv_path = 'static/versions/image/' + code + '.png'
+            try:
+                as_path = os.path.join(BASE_DIR, rv_path)
+                if os.path.exists(as_path):
+                    os.remove(as_path)
+                with open(as_path, 'wb+') as destination:
+                    for chunk in file_s.chunks():
+                        destination.write(chunk)
+            except Exception as e:
+                pass
+            else:
+                img= SERVER_DOMAIN + 'sysfile/' + rv_path
         if code is not None:
-            ev = Equipment_Version.objects.filter(code=code, lang=lang)
+
             if ev.exists():
                 try:
                     update_time = timezone.localtime(timezone.now())
-                    ev.update(status=status, update_time=update_time)
+                    ev.update(status=status,img=img, update_time=update_time)
                 except Exception as e:
                     return response.json(404, repr(e))
                 else:
-                    return response.json(0, {'update_time': str(update_time)})
+                    return response.json(0, {'update_time': str(update_time),'img':img})
             else:
                 return response.json(173)
         else:

+ 1 - 1
Controller/EquipmentStatus.py

@@ -149,7 +149,7 @@ def getUploadLogUrl(request):
         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())
-        obj = 'log/{uid}'.format(uid=uid) + str(nowTime) + '.log'
+        obj = 'log/{uid}/'.format(uid=uid) + str(nowTime) + '.log'
         url = bucket.sign_url('PUT', obj, 7200)
         return JsonResponse(status=200, data={'code': 0, 'msg': 'success', 'url': url})
     else:

+ 22 - 6
Controller/FeedBack.py

@@ -12,18 +12,19 @@
 @Contact: chanjunkai@163.com
 """
 
-import time
 import json
+import time
+
 import oss2
+from django.db import transaction
 from django.views.generic.base import View
-from var_dump import var_dump
+
 from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET
 from Model.models import FeedBackModel, StatResModel
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Service.CommonService import CommonService
 from Service.ModelService import ModelService
-from django.db import transaction
 
 
 class FeedBackView(View):
@@ -104,7 +105,8 @@ class FeedBackView(View):
         uid = request_dict.get('uid', None)
         product_type = request_dict.get('product_type', None)
         app_version = request_dict.get('app_version', None)
-
+        appBundleId = request_dict.get('appBundleId', None)
+        email = request_dict.get('email', None)
         try:
             with transaction.atomic():
                 fb = FeedBackModel()
@@ -125,6 +127,10 @@ class FeedBackView(View):
                     fb.product_type = product_type
                 if app_version:
                     fb.app_version = app_version
+                if appBundleId:
+                    fb.appBundleId = appBundleId
+                if email:
+                    fb.email = email
                 fb.userID_id = userID
                 fb.save()
                 if res_1:
@@ -192,13 +198,19 @@ class FeedBackView(View):
                     filter_data = {'userID_id': ModelService.get_userID_byname(username)}
                 if type:
                     filter_data = {'type': type}
-                fb_qs = FeedBackModel.objects.filter()
+
+                try:
+                    fb_qs = FeedBackModel.objects.filter()
+                except Exception as e:
+                    return response.json(500, repr(e))
+                print('----------')
                 if filter_data:
                     fb_qs = fb_qs.filter(**filter_data)
                 count = fb_qs.count()
                 fb_qs = fb_qs[(page - 1) * line:page * line].values('id', 'type', 'status', 'content', 'addTime', 'app',
                                                                     'uid', 'os_version', 'phone_model', 'product_type',
-                                                                    'updTime', 'userID__username','app_version')
+                                                                    'updTime', 'userID__username','userID__phone','userID__userEmail','app_version','appBundleId','email'
+                                                                    )
                 sid_list = []
                 print(fb_qs)
                 for fb in fb_qs:
@@ -218,6 +230,10 @@ class FeedBackView(View):
                             # img_url.replace('statres.oss-cn-hongkong.aliyuncs.com','static.zositech.xyz')
                             fb['img_url'].append(img_url)
                             # fb['FS__name'] = sm['name']
+                            if fb['userID__username'] =='':
+                                fb['userID__username'] = sm['userID__userEmail']
+                            if fb['userID__username'] =='':
+                                fb['userID__username'] = sm['userID__phone']
                     res.append(fb)
                 return response.json(0, {'datas': res, 'count': count})
             else:

+ 39 - 14
Controller/OTAEquipment.py

@@ -1,21 +1,26 @@
-from zlib import crc32
-from django.core import serializers
+import hashlib
+import os
+import simplejson as json
+import time
+import traceback
 from wsgiref.util import FileWrapper
-import traceback, hashlib
-from Ansjer.config import SERVER_DOMAIN
+from zlib import crc32
+
+from django.http import HttpResponse
+from django.utils.decorators import method_decorator
 from django.views.decorators.csrf import csrf_exempt
 from django.views.generic import TemplateView
-from django.utils.decorators import method_decorator
-from Model.models import Equipment_Version
+
+from Ansjer.config import BASE_DIR
+from Ansjer.config import SERVER_DOMAIN
+from Ansjer.config import SERVER_TYPE
 from Model.models import Device_User
-from Service.ModelService import ModelService
-from Service.CommonService import CommonService
-import time, os, simplejson as json
+from Model.models import Equipment_Version
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Object.UrlTokenObject import UrlTokenObject
-from django.http import HttpResponse
-from Ansjer.config import BASE_DIR
+from Service.CommonService import CommonService
+from Service.ModelService import ModelService
 
 
 def downloadUrl(fileType, fileCode, fileVersion, fileName):
@@ -385,6 +390,7 @@ def addNewEquipmentVersionInterface(request):
         return response.json(444)
     deviceContent = request_dict.get('content', None).encode('utf-8')
     token = request_dict.get('token', None)
+    file_s = request.FILES.get('file', None)
     deviceContent = str(deviceContent, encoding='utf-8')
     deviceContent = deviceContent.replace(' ', ' ').replace('\'', '\"')
     if deviceContent is None:
@@ -411,6 +417,28 @@ def addNewEquipmentVersionInterface(request):
         if version is None or filePath is None:
             return response.json(444, 'content')
         deviceData['filePath'] = ','.join(filePath)
+        paths = 'static/versions/image'
+        if not os.path.exists(paths):
+            os.makedirs(paths)  # makedirs 创建文件时如果路径不存在会创建这个路径
+            # print ('该文件不存在')
+        else:
+            print ('该文件存在')
+        print(file_s)
+        if file_s is None:
+            deviceData['img'] = ''
+        else:
+            rv_path = 'static/versions/image/' + code + '.png'
+            try:
+                as_path = os.path.join(BASE_DIR, rv_path)
+                if os.path.exists(as_path):
+                    os.remove(as_path)
+                with open(as_path, 'wb+') as destination:
+                    for chunk in file_s.chunks():
+                        destination.write(chunk)
+            except Exception as e:
+                pass
+            else:
+                deviceData['img'] = SERVER_DOMAIN + 'sysfile/' + rv_path
         ev_qs = Equipment_Version(
             eid=CommonService.getUserID(getUser=False, setOTAID=True),
             **deviceData)
@@ -434,9 +462,6 @@ def showAllEquipmentVersion(userID, response):
     return response.json(0, res)
 
 
-from Ansjer.config import SERVER_TYPE
-
-
 # 检测ota更新包
 @csrf_exempt
 def getNewVerInterface(request):

+ 40 - 6
Controller/SysManage.py

@@ -11,13 +11,16 @@
 @file: SysManage.py
 @Contact: chanjunkai@163.com
 """
+import os
+
+from django.http import HttpResponse
 from django.views.decorators.csrf import csrf_exempt
-from Service.CommonService import CommonService
-from Service.ModelService import ModelService
+from django.views.generic.base import View
+
 from Ansjer.config import BASE_DIR
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
-import os
+from Service.ModelService import ModelService
 
 
 @csrf_exempt
@@ -30,10 +33,10 @@ def updateLog(request):
         request_dict = request.POST
     else:
         response.json(404)
-    token = request_dict.get('token',None)
-    content = request_dict.get('content',None)
+    token = request_dict.get('token', None)
+    content = request_dict.get('content', None)
     if not content:
-        return response.json(444,'content')
+        return response.json(444, 'content')
     tko = TokenObject(token)
     response.lang = tko.lang
     if tko.code != 0:
@@ -50,3 +53,34 @@ def updateLog(request):
         pass
     return response.json(0)
 
+
+class getStatView(View):
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        filePath = kwargs.get('filePath', None)
+        filePath.encode(encoding='utf-8', errors='strict')
+        response = ResponseObject()
+        return self.getFile(filePath, response)
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'gb2312'
+        filePath = kwargs.get('filePath', None)
+        response = ResponseObject()
+        filePath.encode(encoding='gb2312', errors='strict')
+        return self.getFile(filePath, response)
+
+    def getFile(self, filePath,response):
+        if filePath:
+            pass
+        else:
+            return response.json(800)
+        fullPath = os.path.join(BASE_DIR,filePath).replace('\\', '/')
+        from var_dump import var_dump
+        var_dump(fullPath)
+        if os.path.isfile(fullPath):
+            try:
+                Imagedata = open(fullPath, 'rb').read()
+            except Exception as e:
+                return response.json(906, repr(e))
+            else:
+                return HttpResponse(Imagedata, content_type="image/jpeg")

+ 75 - 4
Controller/SysMsg.py

@@ -15,14 +15,13 @@ import time
 
 from django.views.generic.base import View
 
-from Model.models import SysMsgModel, FeedBackModel
+from Model.models import SysMsgModel, FeedBackModel, UserExtendModel, SysMassModel
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Service.ModelService import ModelService
 
 
 class SysMsgView(View):
-
     def get(self, request, *args, **kwargs):
         request.encoding = 'utf-8'
         operation = kwargs.get('operation', None)
@@ -51,11 +50,72 @@ class SysMsgView(View):
                 return self.do_delete(userID, request_dict, response)
             elif operation == 'deleteByAdmin':
                 return self.do_delete_by_admin(userID, request_dict, response)
+            elif operation == 'massPush':
+                return self.do_mass_push(userID, request_dict, response)
+            elif operation == 'queryMassPush':
+                return self.do_query_mass_push(userID, request_dict, response)
             else:
                 return response.json(414)
         else:
             return response.json(tko.code)
 
+    def do_query_mass_push(self, userID, request_dict, response):
+        own_perm = ModelService.check_perm(userID, 10)
+        sender = request_dict.get('sender', None)
+        page = int(request_dict.get('page', None))
+        line = int(request_dict.get('line', None))
+        if own_perm:
+            smss_qs = SysMassModel.objects.filter()
+            if sender:
+                smss_qs.filter(sender__username=sender)
+            count = smss_qs.count()
+            smss_qs = smss_qs.values('id', 'sender__username', 'addTime', 'updTime', 'lang', 'recever', 'msg',
+                                     'platform')
+            smss_qs = smss_qs[(page - 1) * line:page * line]
+            return response.json(0, {'count': count, 'datas': list(smss_qs)})
+        else:
+            return response.json(404)
+
+    def do_mass_push(self, userID, request_dict, response):
+        own_perm = ModelService.check_perm(userID, 10)
+        if own_perm:
+            app_str = request_dict.get('app_list', None)
+            msg = request_dict.get('msg', None)
+            region_str = request_dict.get('region', None)
+            platform = request_dict.get('platform', None)
+            app_list = app_str.split(',')
+            region = region_str.split(',')
+            nowTime = int(time.time())
+            ue_filter = UserExtendModel.objects.filter()
+            if app_list:
+                ue_filter = ue_filter.filter(appBundleId__in=app_list)
+            if region:
+                ue_filter = ue_filter.filter(region__in=region)
+            ue_count = ue_filter.count()
+            # range_count = math.ceil(ue_count / 5000)
+            SysMassModel.objects.create(
+                sender_id=userID,
+                lang=region_str,
+                recever=app_str,
+                msg=msg,
+                addTime=nowTime,
+                updTime=nowTime,
+                platform=platform
+            )
+            querysetlist = []
+            userID_list = ue_filter.values_list('userID_id', flat=True)
+            for urd in userID_list:
+                querysetlist.append(SysMsgModel(userID_id=urd, msg=msg, addTime=nowTime, updTime=nowTime))
+                if len(querysetlist) > 5000:
+                    is_y = SysMsgModel.objects.bulk_create(querysetlist)
+                    print(is_y)
+                    querysetlist = []
+            SysMsgModel.objects.bulk_create(querysetlist)
+
+            return response.json(0)
+        else:
+            return response.json(404)
+
     def do_push_msg_feed_back(self, userID, request_dict, response):
         own_perm = ModelService.check_perm(userID, 10)
         if own_perm:
@@ -115,8 +175,16 @@ class SysMsgView(View):
                     sm_qs = sm_qs.filter(userID_id__in=userID_list)
                 count = sm_qs.count()
                 sm_qs = sm_qs[(page - 1) * line:page * line]. \
-                    values('status', 'id', 'msg', 'addTime', 'updTime', 'userID__username')
+                    values('status', 'id', 'msg', 'addTime', 'updTime', 'userID__username', 'userID__userEmail',
+                           'userID__phone')
+                for k, v in enumerate(sm_qs):
 
+                    if sm_qs[k]['userID__username'] == '':
+                        sm_qs[k]['userID__username'] = sm_qs[k]['userID__userEmail']
+                    if sm_qs[k]['userID__username'] == '':
+                        sm_qs[k]['userID__username'] = sm_qs[k]['userID__phone']
+                    sm_qs[k].pop('userID__userEmail')
+                    sm_qs[k].pop('userID__phone')
                 return response.json(0, {'datas': list(sm_qs), 'count': count})
             else:
                 return response.json(444, 'page,line')
@@ -138,8 +206,9 @@ class SysMsgView(View):
 
     def do_delete(self, userID, request_dict, response):
         sid = request_dict.get('sid', None)
+        sid_list = sid.split(',')
         if sid:
-            sm_qs = SysMsgModel.objects.filter(userID_id=userID, id=sid)
+            sm_qs = SysMsgModel.objects.filter(userID_id=userID, id__in=sid_list)
             if sm_qs.exists():
                 sm_qs.delete()
                 return response.json(0)
@@ -167,3 +236,5 @@ class SysMsgView(View):
                 return response.json(173)
         else:
             return response.json(444, 'sid')
+
+# 回复记录

+ 13 - 19
Controller/Test.py

@@ -125,34 +125,28 @@ class Test(View):
 
     def do_apns(self, request_dict):
         token_val = request_dict.get('token_val', None)
-        pem_path = os.path.join(BASE_DIR, 'Ansjer/file/apns_pem/apns-dev-test.pem')
+        pem_path = os.path.join(BASE_DIR, 'Ansjer/file/apns_pem/apns-dev2.pem')
+        # pem_path = os.path.join(BASE_DIR, 'Ansjer/file/apns_pem/apns-loocamccloud.pem')
         print(pem_path)
         response = ResponseObject()
         try:
-            import apns2
-            now_time = int(time.time())
-
-            # cli = apns2.APNSClient(mode="dev", client_cert="/your/path.pem")
-            # alert = apns2.PayloadAlert(body="body!", title="title!")
-            # payload = apns2.Payload(alert=alert)
-            # n = apns2.Notification(payload=payload, priority=apns2.PRIORITY_LOW)
-            # response = cli.push(n=n, device_token="your_token")
-            # assert response.status_code == 200, response.reason
-            # assert response.apns_id
-
-            # cli = apns2.APNSClient(mode="prod", client_cert=pem_path)
-            cli = apns2.APNSClient(mode="dev", client_cert=pem_path, password='111111')
-            push_data = {"alert": "Motion ", "event_time": now_time, "event_type": "51", "msg": "",
-                         "received_at": now_time, "sound": "sound.aif", "uid": "XFDJUHUIOKJHYTGSFFDR", "zpush": "1"}
-            alert = apns2.PayloadAlert(body=json.dumps(push_data), title="title!")
-            payload = apns2.Payload(alert=alert)
-
+            n_time = int(time.time())
+
+            cli = apns2.APNSClient(mode="dev", client_cert=pem_path,
+                                   password='111111')
+            push_data = {"alert": "Motion ", "event_time": n_time, "event_type": 51, "msg": "",
+                         "received_at": n_time, "sound": "sound.aif", "uid": 'XFDJUHUIOKJHYTGSFFDR', "zpush": "1", "channel": 1}
+            alert = apns2.PayloadAlert(body='通道:1 uid:XFDJUHUIOKJHYTGSFFDR', title='ansjer')
+            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='com.ansjer.loocamccloud')
+            # assert res.status_code == 200, res.reason
+            # assert res.apns_id
             if res.status_code == 200:
                 return response.json(0)
             else:
                 return response.json(404, res.reason)
+
         except Exception as e:
             return response.json(10, repr(e))
 

+ 50 - 9
Controller/UidSetController.py

@@ -19,7 +19,7 @@ from django.utils.decorators import method_decorator
 from django.views.decorators.csrf import csrf_exempt
 from django.views.generic.base import View
 
-from Model.models import UidSetModel, Device_User, Device_Info
+from Model.models import UidSetModel, Device_User, Device_Info,UidPushModel
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Service.CommonService import CommonService
@@ -66,6 +66,8 @@ class UidSetView(View):
         userID = tko.userID
         if operation == 'queryAll':
             return self.do_queryAll(request_dict, userID, response)
+        elif operation == 'adminQueryAll':
+            return self.do_admin_queryAll(request_dict, userID, response)
         elif operation == 'adminDelete':
             return self.do_admin_delete(request_dict, userID, response)
         elif operation == 'adminQuery':
@@ -88,6 +90,28 @@ class UidSetView(View):
         else:
             return response.json(0)
 
+    def do_admin_queryAll(self, request_dict, userID, response):
+            uid_list = Device_Info.objects.filter(userID_id=userID).values_list('UID', flat=True)
+            print (uid_list)
+            id = request_dict.get('id', None)
+            uid_set_qs = UidPushModel.objects.filter(uid_set__id=id).values('addTime',
+                                                                            'appBundleId','app_type','lang','m_code','push_type','token_val','tz','uid_set',
+                                                                            'updTime','userID','userID__username'
+                                                                            , 'userID__userEmail', 'userID__NickName'
+                                                                            , 'userID__is_active', 'userID__phone'
+                                                                            , 'uid_set__channel', 'uid_set__uid'
+                                                                            , 'uid_set__detect_status'
+                                                                            ,'uid_set__detect_interval', 'uid_set__ucode'
+                                                                            , 'uid_set__version'
+                                                                            , 'uid_set__p2p_region'
+                                                                            ,'uid_set__cloud_vod', 'uid_set__tz'
+                                                                            , 'uid_set__video_code'
+                                                                            ,'uid_set__nickname'
+                                                                            ,'uid_set__ip'
+                                                                            )
+
+            return response.json(0, list(uid_set_qs))
+
         # 管理员删除
 
     def do_admin_delete(self, request_dict, userID, response):
@@ -115,14 +139,31 @@ class UidSetView(View):
             line = request_dict.get('line', None)
             page = int(page)
             line = int(line)
-            omqs = UidSetModel.objects.all().order_by('-id')
-            if not omqs.exists():
-                return response.json(0, [])
-            count = omqs.count()
-            order_ql = omqs[(page - 1) * line:page * line]
-            uidset_json = CommonService.qs_to_dict(order_ql)
-            uidset_json['count'] = count
-            return response.json(0, uidset_json)
+            deviceContent = request_dict.get('content', None)
+            if deviceContent:
+                try:
+                    searchCondition = json.loads(deviceContent)
+                except Exception as e:
+                    return response.json(10, repr(e))
+                else:
+                    kwargs = CommonService.get_kwargs(data=searchCondition)
+                    omqs = UidSetModel.objects.filter(**kwargs)
+                    if not omqs.exists():
+                        return response.json(0, [])
+                    count = omqs.count()
+                    order_ql = omqs[(page - 1) * line:page * line]
+                    uidset_json = CommonService.qs_to_dict(order_ql)
+                    uidset_json['count'] = count
+                    return response.json(0, uidset_json)
+            else:
+                omqs = UidSetModel.objects.all().order_by('-id')
+                if not omqs.exists():
+                    return response.json(0, [])
+                count = omqs.count()
+                order_ql = omqs[(page - 1) * line:page * line]
+                uidset_json = CommonService.qs_to_dict(order_ql)
+                uidset_json['count'] = count
+                return response.json(0, uidset_json)
         else:
             return response.json(404)
 

+ 609 - 202
Controller/UserBrandController.py

@@ -12,25 +12,444 @@
 @Contact: pzb3076@163.com
 """
 
-from django.views.generic.base import View
+import time
+from collections import Counter
+
 from django.utils.decorators import method_decorator
 from django.views.decorators.csrf import csrf_exempt
-from Service.ModelService import ModelService
-from Model.models import User_Brand,Device_User
-from django.utils import timezone
-import traceback,time,json,urllib.request
+from django.views.generic.base import View
+
+from Ansjer.config import AWS_DynamoDB_REGION, AWS_DynamoDB_ACCESS_KEY, AWS_DynamoDB_SECRET_KEY, \
+    USER_BRAND, USER_BRAND_ALL
+from Model.models import Device_User
+from Object.RedisObject import RedisObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Service.CommonService import CommonService
-from collections import Counter
+from Service.ModelService import ModelService
+
 '''
-http://192.168.136.39:8000/userbrandinfo/queryByAdmin?token=test&page=1&line=10  全部记录
+http://192.168.136.39:8000/userbrandinfo/queryByAdmin?token=test&page=1&line=10  记录
 http://192.168.136.39:8000/userbrandinfo/queryArea?token=test   市的区域统计
 http://192.168.136.39:8000/userbrandinfo/queryDeviceSupplier?token=test 品牌统计
-http://192.168.136.39:8000/userbrandinfo/queryAllByAdmin?token=test&page=1&line=10  全部记录中过滤查询每个用户的最新一条数据
+http://192.168.136.39:8000/userbrandinfo/queryAllByAdmin?token=test&page=1&line=10  全部记录中每个用户的数据
 
 http://192.168.136.39:8000/userbrandinfo/queryAll?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VySUQiOiIxNTQzOTA5MDUwNDEzMTM4MDAxMzgwMDAiLCJsYW5nIjoiY24iLCJ1c2VyIjoiMTM4MDAxMzgwMDEiLCJtX2NvZGUiOiIxMjM0MTMyNDMyMTQiLCJleHAiOjE1NTk4OTY4NTd9.nhK3VSghSGjyXKjel4woz7R_3bhjgqQDlX-ypYsklNU&page=1&line=5
 '''
+# coding:utf-8
+from boto3 import Session
+from botocore.exceptions import ClientError
+from boto3.dynamodb.conditions import Key, Attr
+import logging
+import json
+
+logger = logging.getLogger(__name__)
+
+
+class MyserviceDynamodb(object):
+    def __init__(self, **kwargs):
+        self.region = AWS_DynamoDB_REGION
+        self.access_key = AWS_DynamoDB_ACCESS_KEY
+        self.secret_key = AWS_DynamoDB_SECRET_KEY
+        self.session = self.__session()
+
+    def __session(self):
+        try:
+            session = Session(aws_access_key_id=self.access_key, aws_secret_access_key=self.secret_key,
+                              region_name=self.region)
+        except:
+            print("Failed to connect session in region{0}".format(self.region))
+        return session
+
+    # 创建user_brand_all表
+    def user_brand_all_table_create(self, table_name):
+        dynamodb = self.session.resource('dynamodb')
+        inventory = my.tables_list(table_name)
+        if table_name in inventory:
+            print('包含')
+        else:
+            try:
+                table = dynamodb.create_table(
+                    TableName=table_name,
+                    KeySchema=[
+                        {
+                            'AttributeName': 'userID',
+                            'KeyType': 'HASH'
+                        },
+                        {
+                            'AttributeName': 'addTime',
+                            'KeyType': 'RANGE'
+                        }
+                    ],
+                    AttributeDefinitions=[
+                        {
+                            'AttributeName': 'userID',
+                            'AttributeType': 'S'
+                        },
+                        {
+                            'AttributeName': 'addTime',
+                            'AttributeType': 'N'
+                        },
+
+                    ],
+                    ProvisionedThroughput={
+                        'ReadCapacityUnits': 5,
+                        'WriteCapacityUnits': 5,
+                    }
+                )
+            except Exception:
+                logger.error(table_name + '表已经存在')
+
+    # 查询aws数据库里面有什么表
+    def tables_list(self, table_name):
+        client = self.session.client('dynamodb')
+        response = client.list_tables()
+        return response['TableNames']
+
+    # 创建user_brand表
+    def table_create(self, table_name):
+        dynamodb = self.session.resource('dynamodb')
+        inventory = my.tables_list(table_name)
+        if table_name in inventory:
+            print('包含')
+        else:
+            try:
+                table = dynamodb.create_table(
+                    TableName=table_name,
+                    KeySchema=[
+                        {
+                            'AttributeName': 'userID',
+                            'KeyType': 'HASH'
+                        }
+                    ],
+                    AttributeDefinitions=[
+                        {
+                            'AttributeName': 'userID',
+                            'AttributeType': 'S'
+                        }
+                    ],
+                    ProvisionedThroughput={
+                        'ReadCapacityUnits': 5,
+                        'WriteCapacityUnits': 5,
+                    }
+                )
+            except Exception:
+                logger.error(table_name + '表已经存在')
+
+    # 添加user_brand_all表数据
+    def user_brand_all_item_put(self, table_name, data_list):
+        dynamodb = self.session.resource('dynamodb')
+        table = dynamodb.Table(table_name)
+        with table.batch_writer() as batch:
+
+            for i in data_list:
+                data = json.loads(i.decode('utf-8'))
+                # print (json.loads(i))
+                # data = i
+                if data['city'] == '':
+                    data['city'] = '无'
+                if data['area'] == '':
+                    data['area'] = '无'
+                if data['street'] == '':
+                    data['street'] = '无'
+                if data['longitude'] == '':
+                    data['longitude'] = '无'
+                if data['latitude'] == '':
+                    data['latitude'] = '无'
+                batch.put_item(
+                    Item={
+                        'userID': data['userID'],
+                        'addTime': data['addTime'],
+                        'deviceSupplier': data['deviceSupplier'],
+                        'deviceModel': data['deviceModel'],
+                        'osType': data['osType'],
+                        'osVersion': data['osVersion'],
+                        'country': data['country'],
+                        'province': data['province'],
+                        'city': data['city'],
+                        'area': data['area'],
+                        'street': data['street'],
+                        'longitude': data['longitude'],
+                        'latitude': data['latitude'],
+                        'appId': data['appId'],
+                        'status_all': data['status_all'],
+                        'ExpirationTime_TTL': data['ExpirationTime_TTL'],
+                        'ip': data['ip'],
+                    }
+                )
+            print('批量添加数据成功!')
+
+    # 添加user_brand表数据
+    def user_brand_item_put(self, table_name, user_id, add_time, device_supplier, device_model, os_type,
+                            os_version, country, province, city, area, street, longitude, latitude, app_id,
+                            status_all, ip):
+        dynamodb = self.session.resource('dynamodb')
+        table = dynamodb.Table(table_name)
+        table.put_item(
+            Item={
+                'userID': user_id,
+                'addTime': add_time,
+                'deviceSupplier': device_supplier,
+                'deviceModel': device_model,
+                'osType': os_type,
+                'osVersion': os_version,
+                'country': country,
+                'province': province,
+                'city': city,
+                'area': area,
+                'street': street,
+                'longitude': longitude,
+                'latitude': latitude,
+                'appId': app_id,
+                'status_all': status_all,
+                'ip': ip,
+            }
+        )
+        print('添加表一条数据成功!')
+
+    # page分页数,line条数,table_name表名称,last_evaluated查询开始值,page_value记录分页开始值
+    def get_page_line(self, page, line, table_name, last_evaluated, page_value):
+        dynamodb = self.session.resource('dynamodb')
+        # if not dynamodb:
+        #     raise DynamodbConnectionError("Failed to get resource for dynamodb!")
+        table = dynamodb.Table(table_name)
+        last_evaluated_key = last_evaluated
+        try:
+            if last_evaluated_key is None:
+                response = table.scan(
+                    Limit=line,
+                )
+                page_value.append(last_evaluated_key)
+            else:
+                # 构建分页的起点,传入下一页面的起点,这是由主键来控制的,last_evaluated_key的值就是本表中的uid
+                response = table.scan(
+                    Limit=line,
+                    ExclusiveStartKey=last_evaluated_key)
+            try:
+                last_evaluated_key = response['LastEvaluatedKey']
+                # 如果有知就追加在该值的后面
+                page_value.append(last_evaluated_key)
+                my.get_page_line(page, line, table_name, last_evaluated_key, page_value)
+            except Exception:
+                return page_value
+        except Exception as e:
+            logger.error("Failed to get table {0}, error".format(table_name, e))
+        return page_value
+
+    def item_get(self, line, table_name, last_evaluated_key):
+        dynamodb = self.session.resource('dynamodb')
+        table = dynamodb.Table(table_name)
+        if last_evaluated_key is None:
+            response = table.scan(
+                Limit=line,
+            )
+        else:
+            # 构建分页的起点,传入下一页面的起点,这是由主键来控制的,last_evaluated_key的值就是本表中的uid
+            response = table.scan(
+                Limit=line,
+                ExclusiveStartKey=last_evaluated_key)
+        return response
+
+    def item_get_count(self, table_name):
+        dynamodb = self.session.resource('dynamodb')
+        table = dynamodb.Table(table_name)
+
+        response = table.scan()
+        return len(response['Items'])
+# 已经查询全部
+    def item_get_brand(self, table_name):
+        dynamodb = self.session.resource('dynamodb')
+        table = dynamodb.Table(table_name)
+        last_evaluated_key = None
+        i = 0
+        table_info = []
+        while True:
+            # 刚开始,不需要传入startkey
+            if last_evaluated_key is None:
+                response = table.scan()
+            else:
+                # 构建分页的起点,传入下一页面的起点,这是由主键来控制的,last_evaluated_key的值就是本表中的uid
+                try:
+                    response = table.scan(ExclusiveStartKey=last_evaluated_key)
+                except Exception:
+                    break
+            # print type(response) #字典
+            i = i + 1
+            print (i)
+            if response['Items'] != []:
+                table_info.extend(response['Items'])
+            # 判断有没有这个LastEvaluatedKey,如果有,那么还有页面没有拉取玩,将这个值带入request的ExclusiveStartKey中,继续读取页面
+            try:
+                if response['LastEvaluatedKey']:
+                    last_evaluated_key = response['LastEvaluatedKey']
+                    continue
+                else:
+                    break
+            except Exception:
+                break
+        return table_info
+
+
+    def put_item(self, table, item_dict=None):
+        try:
+            response = table.put_item(Item=item_dict)
+        except Exception as e:
+            logger.error("Failed to put item in to {0}:error{1}".format(table, e))
+        return response
+
+    def update_table(self, table_name, user_id, username, add_time, deviceSupplier, deviceModel, osType, osVersion,
+                     country, province, city, area, street, longitude, latitude, appId, ip, status_all
+                     ):
+        dynamodb = self.session.resource('dynamodb')
+        table = dynamodb.Table(table_name)
+        try:
+            response = table.update_item(
+                Key={
+                    'userID': user_id,
+                    'username': username
+                },
+                UpdateExpression="SET addTime = :add_time, deviceSupplier= :deviceSupplier, deviceModel = :deviceModel, osType = :osType, osVersion = :osVersion, country = :country, province = :province, city = :city, area= :area, street= :street, longitude= :longitude, latitude= :latitude, appId= :appId, ip= :ip, status_all= :status_all",
+
+                ExpressionAttributeValues={
+                    ':add_time': add_time,
+                    ':deviceSupplier': deviceSupplier,
+                    ':deviceModel': deviceModel,
+                    ':osType': osType,
+                    ':osVersion': osVersion,
+                    ':country': country,
+                    ':province': province,
+                    ':city': city,
+                    ':area': area,
+                    ':street': street,
+                    ':longitude': longitude,
+                    ':latitude': latitude,
+                    ':appId': appId,
+                    ':ip': ip,
+                    ':status_all': status_all,
+                }, ReturnValues="UPDATED_NEW")
+        except ClientError as e:
+            if e.response['Error']['Code'] == "ConditionalCheckFailedException":
+                logger.error(e.response['Error']['Message'])
+            else:
+                print('Failed update the dynamodb by event_id,not Failed Conditional')
+        else:
+            print('修改成功')
+
+    def table_delete(self, table_name):
+        dynamodb = self.session.resource('dynamodb')
+        table = dynamodb.Table(table_name)
+        table.delete()
+        print('删除表成功')
+
+    def item_delete(self, table_name, name, user_id, add_time):
+        dynamodb = self.session.resource('dynamodb')
+        table = dynamodb.Table(table_name)
+        try:
+            if name == 'user_brand':
+                table.delete_item(
+                    Key={
+                        'userID': user_id,
+                    }
+                )
+            else:
+                table.delete_item(
+                    Key={
+                        'userID': user_id,
+                        'addTime': int(add_time),
+                    }
+                )
+            return 'ok'
+        except Exception:
+            logger.error("Failed to put item in to {0}:error{1}".format(table))
+            return 'no'
+# 搜索查询并分页查询全部
+    def get_table_info(self, table_name, username):
+        """
+        对表进行分页扫描,这里尝试的是对visit_info表进行扫描
+        """
+        # 通过dynamodb服务获取目标table的操作对象
+        dynamodb = self.session.resource('dynamodb')
+        table_handle = dynamodb.Table(table_name)
+        # 这个值是在分页查询的时候,用来记录页面的最后一个主键的下一个,以方便下一个页面的开启
+        last_evaluated_key = None
+        i = 0
+        table_info =[]
+        while True:
+            # 刚开始,不需要传入startkey
+            if last_evaluated_key is None:
+                response = table_handle.scan(
+                    FilterExpression=Attr('deviceSupplier').eq(username)
+                                 | Key('osType').eq(username)
+                                 | Key('deviceModel').eq(username)
+                                 | Key('userID').eq(username)
+                                 | Key('osVersion').eq(username)
+                                 | Key('country').eq(username)
+                                 | Key('appId').eq(username)
+                                 | Key('province').eq(username)
+                                 | Key('city').eq(username)
+                                 | Key('area').eq(username)
+                                 | Key('street').eq(username)
+                                 | Key('longitude').eq(username)
+                                 | Key('latitude').eq(username)
+                                 | Key('status_all').eq(username)
+                                 | Key('ip').eq(username))
+            else:
+                # 构建分页的起点,传入下一页面的起点,这是由主键来控制的,last_evaluated_key的值就是本表中的uid
+                try:
+                    response = table_handle.scan(
+                        ExclusiveStartKey=last_evaluated_key,
+                        FilterExpression=Attr('deviceSupplier').eq(username)
+                                     | Key('osType').eq(username)
+                                     | Key('deviceModel').eq(username)
+                                     | Key('userID').eq(username)
+                                     | Key('osVersion').eq(username)
+                                     | Key('country').eq(username)
+                                     | Key('appId').eq(username)
+                                     | Key('province').eq(username)
+                                     | Key('city').eq(username)
+                                     | Key('area').eq(username)
+                                     | Key('street').eq(username)
+                                     | Key('longitude').eq(username)
+                                     | Key('latitude').eq(username)
+                                     | Key('status_all').eq(username)
+                                     | Key('ip').eq(username))
+                except Exception:
+                    break
+            # response 有一个标准的json格式,包含了这次scan结果的各种信息
+            # print type(response) #字典
+            i = i+1
+            print (i)
+            if response['Items']!=[]:
+                table_info.extend(response['Items'])
+            # 判断有没有这个LastEvaluatedKey,如果有,那么还有页面没有拉取玩,将这个值带入request的ExclusiveStartKey中,继续读取页面
+            try:
+                if response['LastEvaluatedKey']:
+                    last_evaluated_key = response['LastEvaluatedKey']
+                    continue
+                else:
+                    break
+            except Exception:
+                break
+        for k, v in enumerate(table_info):
+            user_ID = Device_User.objects.filter(userID=table_info[k]['userID']).values('userID', 'username', 'NickName')
+            try:
+                table_info[k]['username'] = user_ID[0]['username']
+            except Exception:
+                table_info[k]['username'] = ''
+        return table_info
+        pass
+
+
+my = MyserviceDynamodb()
+# print(my.table_delete('user_brand'))
+# print(my.table_delete('user_brand_all'))
+
+# my.table_create(USER_BRAND)
+# my.user_brand_all_table_create(USER_BRAND_ALL)
+
+
+# print(my.item_put('user_brand'))
+# table_value = my.get_table('user_brand')
 
 
 class UserBrandInfo(View):
@@ -49,74 +468,64 @@ class UserBrandInfo(View):
         return self.validation(request.POST, request, operation)
 
     def validation(self, request_dict, request, operation):
-        if operation is None:
-            return response.json(444, 'error path')
         self.clientIP = CommonService.get_ip_address(request)
         response = ResponseObject()
         token = request_dict.get('token', None)
-        if token is not None:
-            tko = TokenObject(token)
+        tko = TokenObject(token)
+        if tko.code == 0:
             response.lang = tko.lang
-            if tko.code == 0:
-                userID = tko.userID
-                if userID is not None:
-                    if operation == 'queryByAdmin':
-                        return self.query_info(request_dict, userID,response)
-                    elif operation == 'add':
-                        return self.add_info(request_dict, userID,response)
-                    elif operation == 'queryAllByAdmin':
-                        return self.query_all_info(request_dict, userID,response)
-                    elif operation == 'deleteByAdmin':
-                        return self.delete_by_admin(request_dict, userID,response)
-                    elif operation == 'queryDeviceSupplier':
-                        return self.query_deviceSupplier_info(request_dict, userID,response)
-                    elif operation == 'queryArea':
-                        return self.query_area_info(request_dict, userID,response)
-
-                    else:
-                        return response.json(444)
-                else:
-                    return response.json(309)
+            userID = tko.userID
+            if operation == 'add':
+                return self.add_info(request_dict, userID, USER_BRAND, USER_BRAND_ALL, response)
+            elif operation == 'queryByAdmin':
+                return self.query_info(request_dict, userID, USER_BRAND, USER_BRAND_ALL, response)
+            elif operation == 'queryAllByAdmin':
+                return self.query_all_info(request_dict, userID, USER_BRAND, USER_BRAND_ALL, response)
+            elif operation == 'deleteByAdmin':
+                return self.delete_by_admin(request_dict, userID, USER_BRAND, USER_BRAND_ALL, response)
+            elif operation == 'queryDeviceSupplier':
+                return self.query_deviceSupplier_info(request_dict, userID, USER_BRAND, USER_BRAND_ALL, response)
+            elif operation == 'queryArea':
+                return self.query_area_info(request_dict, userID, USER_BRAND, USER_BRAND_ALL, response)
+
             else:
-                return response.json(tko.code)
+                return response.json(444)
         else:
-            return response.json(309)
-            # 获取外网IP
-
-
-
+            return response.json(tko.code)
 
     # http://192.168.136.39:8000/userbrandinfo?operation=add&token=test&deviceSupplier=小米&deviceModel=HM NOTE 1TD&osType=WEB&osVersion=4.0.0
-    def add_info(self, request_dict, userID,response):
+    def add_info(self, request_dict, userID, user_brand, user_brand_all, response):
         deviceSupplier = request_dict.get('deviceSupplier', None)
         deviceModel = request_dict.get('deviceModel', None)
         osType = request_dict.get('osType', None)
         osVersion = request_dict.get('osVersion', None)
         country = request_dict.get('country', None)
         province = request_dict.get('province', None)
-        city = request_dict.get('city', None)
-        area = request_dict.get('area', None)
-        street = request_dict.get('street', None)
-        longitude = request_dict.get('longitude', None)
-        latitude = request_dict.get('latitude', None)
+        city = request_dict.get('city', '')
+        area = request_dict.get('area', '')
+        street = request_dict.get('street', '')
+        longitude = request_dict.get('longitude', '')
+        latitude = request_dict.get('latitude', '')
         appId = request_dict.get('appId', None)
-        if area is None:
-            area=''
-        if street is None:
-            street=''
-        if longitude is None:
-            longitude=''
-        if latitude is None:
-            latitude=''
-        param_area = CommonService.get_param_flag(data=[country,province,city])
-        must_fill_in = CommonService.get_param_flag(data=[appId,deviceSupplier,deviceModel,osType,osVersion])
+        if city == '':
+            city = '无'
+        if area == '':
+            area = '无'
+        if street == '':
+            street = '无'
+        if longitude == '':
+            longitude = '无'
+        if latitude == '':
+            latitude = '无'
+        param_area = CommonService.get_param_flag(data=[country, province, city])
+        must_fill_in = CommonService.get_param_flag(data=[appId, deviceSupplier, deviceModel, osType, osVersion])
         if must_fill_in is False:
-            return response.json(444,'appId,deviceSupplier,deviceModel,osType,osVersion')
-        if  param_area is True:
+            return response.json(444, 'appId,deviceSupplier,deviceModel,osType,osVersion')
+        if param_area is True:
             if '省' in province:
-                province = province.replace('省','')
+                province = province.replace('省', '')
             if '市' in city:
-                city = city.replace('市','')
+                city = city.replace('市', '')
             status = 1
             country = country
             province = province
@@ -127,199 +536,197 @@ class UserBrandInfo(View):
             latitude = latitude
         else:
             status = 0
-            print (self.clientIP)
-            jsonData = CommonService.getIpIpInfo(ip=self.clientIP,lang='CN')
+            jsonData = CommonService.getIpIpInfo(ip=self.clientIP, lang='CN')
             country = jsonData['country_name']
             province = jsonData['region_name']
             city = jsonData['city_name']
-            area = ''
-            street = ''
+            area = ''
+            street = ''
             longitude = jsonData['longitude']
             latitude = jsonData['latitude']
-        param_flag = CommonService.get_param_flag(data=[deviceSupplier, deviceModel,osType,osVersion])
+            if country == '局域网':
+                city = '无'
+                longitude = '无'
+                latitude = '无'
+
+        param_flag = CommonService.get_param_flag(data=[deviceSupplier, deviceModel, osType, osVersion])
         if param_flag is True:
+            addTime = int(time.time())
+            print(time.time())
+            add_data = {
+                'userID': userID,
+                'addTime': addTime,
+                'deviceSupplier': deviceSupplier,
+                'deviceModel': deviceModel,
+                'osType': osType,
+                'osVersion': osVersion,
+                'country': country,
+                'province': province,
+                'city': city,
+                'area': area,
+                'street': street,
+                'longitude': longitude,
+                'latitude': latitude,
+                'appId': appId,
+                'status_all': status,
+                'ExpirationTime_TTL': addTime + 2592000,
+                'ip': self.clientIP
+            }
+            # 增加用户扩展信息
+            redisObj = RedisObject()
+            add_user_brand_all_data = json.dumps(add_data)
+            logKey = USER_BRAND_ALL
+            redisObj.rpush(name=logKey, val=add_user_brand_all_data)
+            # print (redisObj.llen(name=logKey))
+            # 判断redis列表长度
             try:
-                user_brand = User_Brand(
-                    userID=Device_User.objects.get(userID=userID),
-                    deviceSupplier=deviceSupplier,
-                    deviceModel=deviceModel,
-                    osType=osType,
-                    osVersion=osVersion,
-                    ip=self.clientIP,
-                    addTime = int(time.time()),
-                    status = status,
-                    country = country,
-                    province = province,
-                    city = city,
-                    appId=appId,
-                    area = area,
-                    street = street,
-                    longitude = longitude,
-                    latitude = latitude
-                )
-                user_brand.save()
+                if redisObj.llen(name=logKey) > 100:
+                    data_list = redisObj.lrange(logKey, 0, -1)
+                    redisObj.del_data(key=logKey)
+                    # 添加user_brand_all表信息
+                    my.user_brand_all_item_put(user_brand_all, data_list)
+
+                # 添加user_brand表信息
+                my.user_brand_item_put(user_brand, userID, addTime, deviceSupplier, deviceModel,
+                                       osType, osVersion,
+                                       country, province, city, area, street, longitude, latitude, appId, status,
+                                       self.clientIP)
             except Exception:
-                errorInfo = traceback.format_exc()
-                print(errorInfo)
-                return response.json(424, {'details': errorInfo})
-            else:
-                print(type(user_brand.addTime))
-                return response.json(0,{'id':user_brand.id})
+                my.table_create(USER_BRAND)
+                my.user_brand_all_table_create(USER_BRAND_ALL)
+
+            return response.json(0, {'OK': int(time.time())})
         else:
             # 参数错误
-             return response.json(444)
-
-
+            return response.json(444)
 
+    # 查询每个用户的最新登录数据表
+    def query_info(self, request_dict, userID, user_brand, user_brand_all, response):
 
-    def query_info(self, request_dict, userID,response):
         page = int(request_dict.get('page', None))
         line = int(request_dict.get('line', None))
-        username = request_dict.get('username',None)
-
+        username = request_dict.get('username', None)
         param_flag = CommonService.get_param_flag(data=[page, line])
         if param_flag is True:
-            check_perm = ModelService.check_perm(userID=userID,permID=30)
+            check_perm = ModelService.check_perm(userID=userID, permID=30)
+            page_value = []
             if check_perm is True:
                 if username is None or username is '':
-                    user_brand_queryset = User_Brand.objects.all().order_by( '-id')
+                    # table_Limit_value = my.get_page_line(page,line,user_brand,None,page_value)
+                    # # 页面减1
+                    # page = page-1
+                    # if page < len(table_Limit_value):
+                    #     # 分页后查询
+                    #     table_value = my.item_get(line,user_brand,table_Limit_value[page])
+                    #     table_value = table_value['Items']
+                    #     count = my.item_get_count(user_brand)
+                    #     return response.json(0, {'datas': table_value, 'count': count})
+
+                    return response.json(0, {'datas': {}, 'count': 0})
                 else:
-                    user_brand_queryset = User_Brand.objects.filter(userID__username=username).order_by('-id')
-                if user_brand_queryset.exists():
-                    count = user_brand_queryset.count()
-                    res = user_brand_queryset[(page - 1) * line:page * line]
-                    send_json = CommonService.qs_to_dict(res)
-                    for k, v in enumerate(send_json["datas"]):
-                            username = ModelService.get_user_name(userID=send_json["datas"][k]['fields']['userID'])
-                            send_json["datas"][k]['fields']['username']=username
-                    send_json['count'] = count
-                    return response.json(0, send_json)
-                return response.json(0, {'datas': [], 'count': 0})
+                    # 查询
+                    user_ID = Device_User.objects.filter(username=username).values('userID', 'NickName')
+                    try:
+                        username = user_ID[0]['userID']
+                    except Exception:
+                        username = username
+                    table_value = my.get_table_info(user_brand, username)
+                    return response.json(0, {'datas': table_value, 'count': len(table_value)})
             else:
                 return response.json(404)
         else:
             return response.json(444)
-    def delete_by_admin(self, request_dict, userID,response):
-        id_list = request_dict.getlist('id', None)
-        param_flag = CommonService.get_param_flag(data=[id_list])
+        # 删除接口
+
+    def delete_by_admin(self, request_dict, userID, user_brand, user_brand_all, response):
+        id = request_dict.getlist('id', None)
+        username = request_dict.getlist('username', None)
+        add_time = request_dict.getlist('add_time', None)
+        table_name = request_dict.getlist('table_name', None)
+        param_flag = CommonService.get_param_flag(data=[id, username])
+
         if param_flag is True:
             check_perm = ModelService.check_perm(userID=userID, permID=10)
             if check_perm is True:
-                is_delete = User_Brand.objects.filter(id__in=id_list).delete()
+                if str(table_name[0]) == 'user_brand':
+                    is_delete = my.item_delete(user_brand, 'user_brand', id[0], add_time[0])
+                else:
+                    is_delete = my.item_delete(user_brand_all, 'user_brand_all', id[0], add_time[0])
                 return response.json(0, {'delete_count': is_delete[0]})
             else:
                 return response.json(404)
         else:
             return response.json(444)
-    # 查询每个用户最新的一条记录统计信息
-    def query_all_info(self, request_dict, userID,response):
+
+    # Query each user record statistics
+    def query_all_info(self, request_dict, userID, user_brand, user_brand_all, response):
+
         page = int(request_dict.get('page', None))
         line = int(request_dict.get('line', None))
         username = request_dict.get('username', None)
         param_flag = CommonService.get_param_flag(data=[page, line])
+
+        # 增加用户扩展信息
+
+        try:
+            redisObj = RedisObject()
+            logKey = USER_BRAND_ALL
+            data_list = redisObj.lrange(logKey, 0, -1)
+            redisObj.del_data(key=logKey)
+            # 添加user_brand_all表信息
+            my.user_brand_all_item_put(user_brand_all, data_list)
+        except Exception:
+            print ('有误')
+        print ('添加了数据')
         if param_flag is True:
-            check_perm = ModelService.check_perm(userID=userID,permID=30)
+            check_perm = ModelService.check_perm(userID=userID, permID=30)
+            page_value = []
             if check_perm is True:
                 if username is None or username is '':
-                # 按照用户去重复查询
-                # 分页
-                    user_brand_queryset = User_Brand.objects.all().order_by('userID').values_list('userID', flat=True).distinct()[(page - 1) * line:page * line]
+                    return response.json(0, {'datas': {}, 'count': 0})
                 else:
-                    # 分页
-                    user_brand_queryset = User_Brand.objects.filter(userID__username=username).order_by('userID').values_list( 'userID',flat=True).distinct()[(page - 1) * line:page * line]
-                send_jsons=[]
-                counts=0
-                for i in user_brand_queryset:
-                    counts=counts+1
-                    user_brand_querysetlast = User_Brand.objects.filter(userID=i).order_by('-addTime')[:1]
-                    user_brand_querysetlast = CommonService.qs_to_dict(user_brand_querysetlast)
-                    username = ModelService.get_user_name(userID=user_brand_querysetlast["datas"][0]['fields']['userID'])
-                    user_brand_querysetlast["datas"][0]['fields']['username']=username
-                    send_jsons.append(user_brand_querysetlast["datas"][0])
-                # 按照加入的日期排序
-                send_jsons = sorted(send_jsons, key=lambda x:x['fields']['addTime'], reverse=True)
-                return response.json(0, {'datas': send_jsons, 'count': counts})
+                    # 查询
+                    user_ID = Device_User.objects.filter(username=username).values('userID', 'NickName')
+                    try:
+                        username = user_ID[0]['userID']
+                    except Exception:
+                        username = username
+                    table_value = my.get_table_info(user_brand_all, username)
+
+                    return response.json(0, {'datas': table_value, 'count': len(table_value)})
             else:
                 return response.json(404)
         else:
             return response.json(444)
 
-    # 品牌统计的接口
-    def query_deviceSupplier_info(self, request_dict, userID,response):
-        check_perm = ModelService.check_perm(userID=userID,permID=30)
-        print ('---------------------------------------------------------')
+    # Brand statistics interface
+    def query_deviceSupplier_info(self, request_dict, userID, user_brand, user_brand_all, response):
+        check_perm = ModelService.check_perm(userID=userID, permID=30)
         if check_perm is True:
-            # 按照用户去重复查询
-            user_brand_queryset = User_Brand.objects.all().order_by('userID').values_list('userID', flat=True).distinct()
-            send_jsons=[]
-            counts=0
-            for i in user_brand_queryset:
-                counts=counts+1
-                user_brand_querysetlast = User_Brand.objects.filter(userID=i).order_by('-addTime')[:1]
-                user_brand_querysetlast = CommonService.qs_to_dict(user_brand_querysetlast)
-                username = ModelService.get_user_name(userID=user_brand_querysetlast["datas"][0]['fields']['userID'])
-                user_brand_querysetlast["datas"][0]['fields']['username']=username
-                send_jsons.append(user_brand_querysetlast["datas"][0])
-            deviceSupplier=[]
-            for k, v in enumerate(send_jsons):
-                deviceSupplier.append(v['fields']['deviceSupplier'])
-            # user_brand_queryset = User_Brand.objects.all().order_by('userID').values_list('userID', flat=True).distinct()
-            # send_jsons=[]
-            # counts=0
-            # for i in user_brand_queryset:
-            #     counts=counts+1
-            #     user_brand_querysetlast = User_Brand.objects.filter(userID=i).order_by('-addTime')[:1]
-            #     user_brand_querysetlast = CommonService.qs_to_dict(user_brand_querysetlast)
-            #     username = ModelService.get_user_name(userID=user_brand_querysetlast["datas"][0]['fields']['userID'])
-            #     user_brand_querysetlast["datas"][0]['fields']['username']=username
-            #     send_jsons.append(user_brand_querysetlast["datas"][0])
-            # deviceSupplier=[]
-            # for k, v in enumerate(send_jsons):
-            #     deviceSupplier.append(v['fields']['deviceSupplier'])
-            # deviceSupplier = Counter(deviceSupplier)
-            # return response.json(0, {'datas': deviceSupplier,'counts':counts})
-
-            ub_qs = User_Brand.objects.filter().values('userID','deviceSupplier').order_by('userID').order_by('userID').distinct()
-            count = ub_qs.count()
-            print (ub_qs)
-            print ('---------------------------------------------------------')
-            deviceSupplier = []
-            ub_ql = CommonService.qs_to_list(ub_qs)
-
-            for v in ub_qs:
-                deviceSupplier.append(v['deviceSupplier'])
-                print (v)
-            deviceSupplier = Counter(deviceSupplier)
-            return response.json(0, {'datas': deviceSupplier,'counts':counts})
-            print(deviceSupplier)
-            print ('---------------------------------------------------------')
-            return response.json(0, {'datas': deviceSupplier, 'counts': count})
+            table_value = my.item_get_brand(user_brand)
+            send_jsons = []
+            counts = 0
+            for i in table_value:
+                send_jsons.append(table_value[counts]['deviceSupplier'])
+                counts = counts + 1
+            send_jsons = Counter(send_jsons)
+            return response.json(0, {'datas': send_jsons, 'counts': counts})
         else:
             return response.json(404)
-    # 区域统计的接口
-    def query_area_info(self, request_dict, userID,response):
-        check_perm = ModelService.check_perm(userID=userID,permID=30)
+
+    # Interface to area statistics
+    def query_area_info(self, request_dict, userID, user_brand, user_brand_all, response):
+        check_perm = ModelService.check_perm(userID=userID, permID=30)
         district = request_dict.get('district', None)
         if check_perm is True:
             # 按照用户去重复查询
-            user_brand_queryset = User_Brand.objects.all().order_by('userID').values_list('userID', flat=True).distinct()
-            send_jsons=[]
-            counts=0
-            for i in user_brand_queryset:
-                counts=counts+1
-                user_brand_querysetlast = User_Brand.objects.filter(userID=i).order_by('-addTime')[:1]
-                user_brand_querysetlast = CommonService.qs_to_dict(user_brand_querysetlast)
-                username = ModelService.get_user_name(userID=user_brand_querysetlast["datas"][0]['fields']['userID'])
-                user_brand_querysetlast["datas"][0]['fields']['username']=username
-                send_jsons.append(user_brand_querysetlast["datas"][0])
-            deviceSupplier=[]
-            for k, v in enumerate(send_jsons):
-                deviceSupplier.append(v['fields'][district])
-            deviceSupplier = Counter(deviceSupplier)
-            return response.json(0, {'datas': deviceSupplier,'counts':counts})
-
+            table_value = my.item_get_brand(user_brand)
+            send_jsons = []
+            counts = 0
+            for i in table_value:
+                send_jsons.append(table_value[counts][district])
+                counts = counts + 1
+            send_jsons = Counter(send_jsons)
+            return response.json(0, {'datas': send_jsons, 'counts': counts})
         else:
             return response.json(404)
-
-
-

+ 656 - 13
Controller/UserController.py

@@ -13,8 +13,9 @@
 """
 import datetime
 import traceback
-
+import time
 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
@@ -24,9 +25,9 @@ from django.views.decorators.csrf import csrf_exempt
 from django.views.generic import TemplateView
 from ratelimit.decorators import ratelimit
 
-from Ansjer.config import AuthCode_Expire, SERVER_DOMAIN
+from Ansjer.config import AuthCode_Expire, SERVER_DOMAIN, APNS_CONFIG, JPUSH_CONFIG, FCM_CONFIG
 from Controller.CheckUserData import DataValid, date_handler, RandomStr
-from Model.models import Device_User, Role, SysMsgModel, UidPushModel, UidSetModel
+from Model.models import Device_User, Role, SysMsgModel, UidPushModel, UidSetModel, UserExtendModel
 from Object.AWS.SesClassObject import SesClassObject
 from Object.AliSmsObject import AliSmsObject
 from Object.RedisObject import RedisObject
@@ -303,7 +304,7 @@ class LogoutView(TemplateView):
             if m_code:
                 userID = tko.userID
                 try:
-                    UidPushModel.objects.filter(userID_id=userID).delete()
+                    UidPushModel.objects.filter(userID_id=userID, m_code=m_code).delete()
                 except Exception as e:
                     pass
                 else:
@@ -512,11 +513,24 @@ class refreshTokenView(TemplateView):
             tko = TokenObject(token)
             tko.lang = lang
             res = tko.refresh()
-            code = tko.code
-            if code == 0:
+            userID = tko.userID
+            if tko.code == 0:
+                # 更新用户扩展信息语言
+                try:
+                    user_extend_qs = UserExtendModel.objects.filter(userID_id=userID)
+                    if user_extend_qs.exists():
+                        nowTime = int(time.time())
+                        update_dict = {
+                            'updTime': nowTime,
+                            'region': lang
+                        }
+                        user_extend_qs.update(**update_dict)
+                except Exception as e:
+                    pass
+                # # #
                 return response.json(0, res)
             else:
-                return response.json(code)
+                return response.json(tko.code)
         else:
             return response.json(444, 'token')
 
@@ -913,15 +927,15 @@ class v2forgetPwdCodeView(TemplateView):
         if phone is not None:
             phone = phone.strip()
             if country_code is None:
-                return self.do_send_phone_code(phone, response,sign_name)
+                return self.do_send_phone_code(phone, response, sign_name)
             else:
-                return self.do_v2_send_phone_code(country_code, phone, response,sign_name)
+                return self.do_v2_send_phone_code(country_code, phone, response, sign_name)
         elif email is not None:
             return self.do_send_email_code(email, response)
         else:
             return response.json(444, 'phone')
 
-    def do_send_phone_code(self, phone, response,sign_name):
+    def do_send_phone_code(self, phone, response, sign_name):
         data_valid = DataValid()
         if data_valid.mobile_validate(phone) is not True:
             return response.json(100)
@@ -952,7 +966,7 @@ class v2forgetPwdCodeView(TemplateView):
         else:
             return response.json(10, res["Message"])
 
-    def do_v2_send_phone_code(self, country_code, phone, response,sign_name):
+    def do_v2_send_phone_code(self, country_code, phone, response, sign_name):
         data_valid = DataValid()
         if data_valid.mobile_validate(phone) is not True:
             return response.json(100)
@@ -1264,9 +1278,53 @@ class InitInfoView(View):
         m_code = request_dict.get('m_code', None)
         push_type = request_dict.get('push_type', None)
         appBundleId = request_dict.get('appBundleId', None)
+        tz = request_dict.get('tz', '0')
+        lang = request_dict.get('lang', '')  # 语言区域
+        # region = request_dict.get('region', '')  # 语言区域
+        nowTime = int(time.time())
         if all([token_val, push_type, appBundleId]):
-            UidPushModel.objects.filter(userID_id=userID, m_code=m_code). \
-                update(token_val=token_val, push_type=push_type)
+            push_type = int(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(444, 'push_type')
+            uid_list = ModelService.get_uid_list(userID=userID)
+            if uid_list:
+                # 获取设备推送状态
+                update_dict = {
+                    'token_val': token_val,
+                    'push_type': push_type,
+                    'tz': tz,
+                }
+                # 更新当前用户推送设备状态
+                UidPushModel.objects.filter(userID_id=userID, m_code=m_code, uid_set__detect_status=1).update(
+                    **update_dict)
+            if appBundleId:
+                user_extend_qs = UserExtendModel.objects.filter(userID_id=userID)
+                if user_extend_qs.exists():
+                    update_dict = {
+                        'updTime': nowTime,
+                        'appBundleId': appBundleId,
+                        'region': lang
+                        # 'is_cn':
+                    }
+                    user_extend_qs.update(**update_dict)
+                else:
+                    create_dict = {
+                        'addTime': nowTime,
+                        'updTime': nowTime,
+                        'appBundleId': appBundleId,
+                        'userID_id': userID,
+                        'region': lang
+                    }
+                    UserExtendModel.objects.create(**create_dict)
         res = {
             'usmsg': sm_count
         }
@@ -1332,3 +1390,588 @@ class verifyAuthcode(TemplateView):
         if authcode != resetCode:
             return response.json(121)
         return response.json(0)
+
+
+# 获取验证码
+class wxAuthSignView(TemplateView):
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        lang = request.POST.get('lang', None)
+        response = ResponseObject(lang)
+        request_dict = request.POST
+        return self.ValidationError(request_dict, response)
+
+    def get(self, request, *args, **kwargs):
+        # Device_User.objects.filter(userEmail='chanjunkai@163.com').delete()
+        request.encoding = 'utf-8'
+        lang = request.GET.get('lang', None)
+        response = ResponseObject(lang)
+        request_dict = request.GET
+        # return self.do_register('157113010663213800138000', '157113010663213800138000', response, 'xx')
+
+        return self.ValidationError(request_dict, response)
+
+    def ValidationError(self, request_dict, response):
+        grant_code = request_dict.get('grant_code', None)  # 微信授权code
+        appBundleID = request_dict.get('appBundleID', None)  # 包名
+        print('grant_code')
+        print(grant_code)
+        print('appBundleID')
+        print(appBundleID)
+        if all([grant_code, appBundleID]):
+            app_config = {
+                'com.ansjer.zccloud': {'appid': 'wx2a9f5ef9baf2760f', 'secret': '5d38c7079676463149ffea593c58f2ed'},
+                # ios
+                'com.ansjer.zccloud_ab': {'appid': 'wx2a9f5ef9baf2760f', 'secret': '5d38c7079676463149ffea593c58f2ed'},
+                # android
+            }
+            if appBundleID in app_config.keys():
+                appid = app_config[appBundleID]['appid']
+                secret = app_config[appBundleID]['secret']
+                # 获取access_token请求
+                at_url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid={appid}&secret={secret}&code={code}&grant_type=authorization_code'.format(
+                    appid=appid, secret=secret, code=grant_code)
+                res_req = requests.get(url=at_url)
+                res_json = res_req.json()
+                print(res_json)
+                if 'access_token' not in res_json.keys():
+                    # 授权过期
+                    return response.json(717)
+                access_token = res_json['access_token']
+                openid = res_json['openid']
+                if access_token and openid:
+                    user_extend_qs = UserExtendModel.objects.filter(authOpenID=openid, authType=1)
+                    if user_extend_qs.exists():
+                        # 如果用户绑定过则直接登录
+                        userID = user_extend_qs[0].userID_id
+                        print(userID)
+                        user_qs = Device_User.objects.filter(userID=userID)
+                        return self.do_login(user_qs, response)
+                    else:
+                        # 如果用户为绑定过则创建用户并进行登录返回token
+                        info_url = 'https://api.weixin.qq.com/sns/userinfo?access_token={access_token}&openid={openid}'.format(
+                            access_token=access_token, openid=openid)
+                        res_req = requests.get(url=info_url)
+                        res_json = res_req.json()
+                        print(res_json)
+                        userID = CommonService.getUserID(getUser=False)
+                        nickname = res_json['nickname'] + '_' + CommonService.RandomStr(4)
+                        return self.do_register(userID, nickname, response, appBundleID, openid)
+                else:
+                    return response.json(414, 'access_token,openid')
+            else:
+                return response.json(414, 'appBundleID is wrong!')
+        else:
+            return response.json(414)
+        # if wxcode
+
+    # 登录
+    def do_login(self, user_qs, response):
+        now_time = datetime.datetime.utcnow().replace(tzinfo=utc).astimezone(utc)
+        userID = user_qs[0].userID
+        print('userID' + userID)
+        tko = TokenObject()
+        user_list = user_qs.values("NickName", "userIconUrl", "userIconPath", "username", "userEmail", "phone")
+        res = tko.generate(data={'userID': userID, 'lang': response.lang, 'user': user_list[0]["username"]})
+        # 增加角色
+        user_qs[0].role.add(Role.objects.get(rid=1))
+        role_dict = ModelService.own_role(userID=userID)
+        res['rid'] = role_dict['rid']
+        res['roleName'] = role_dict['roleName']
+        res['permList'] = ModelService.own_permission(userID)
+        res['userID'] = userID
+        # 昵称,邮箱,电话,刷新,头像
+        userIconPath = str(user_list[0]["userIconPath"])
+        if userIconPath and userIconPath.find('static/') != -1:
+            userIconPath = userIconPath.replace('static/', '').replace('\\', '/')
+            res['userIconUrl'] = SERVER_DOMAIN + 'account/getAvatar/' + userIconPath
+        else:
+            res['userIconUrl'] = ''
+        res['NickName'] = user_list[0]["NickName"] if user_list[0]["NickName"] is not None else ''
+        res['username'] = user_list[0]["username"] if user_list[0]["username"] is not None else ''
+        res['userEmail'] = user_list[0]["userEmail"] if user_list[0]["userEmail"] is not None else ''
+        res['phone'] = user_list[0]["phone"] if user_list[0]["phone"] is not None else ''
+        print(res)
+        user_qs.update(last_login=now_time, online=True)
+        return response.json(0, res)
+
+    def do_register(self, userID, nickname, response, appBundleId, openid):
+        data_valid = DataValid()
+        if data_valid.name_validate(userID) is not True:
+            return response.json(105)
+        try:
+            users = Device_User.objects.create(
+                username=userID,
+                NickName=nickname,
+                password=make_password('123456'),
+                userID=userID,
+                is_active=True,
+                user_isValid=True,
+            )
+
+            nowTime = int(time.time())
+            UserExtendModel.objects.create(
+                addTime=nowTime,
+                updTime=nowTime,
+                appBundleId=appBundleId,
+                userID_id=users.userID,
+                authType=1,
+                authOpenID=openid
+            )
+        except Exception as e:
+            errorInfo = traceback.format_exc()
+            print(errorInfo)
+            return response.json(424, repr(e))
+        else:
+            user_qs = Device_User.objects.filter(Q(userID=userID))
+            print('---')
+            print(user_qs)
+            return self.do_login(user_qs, response)
+
+
+# 获取验证码
+class wxPerfectView(TemplateView):
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        lang = request.POST.get('lang', None)
+        response = ResponseObject(lang)
+        request_dict = request.POST
+        return self.ValidationError(request_dict, response)
+
+    def get(self, request, *args, **kwargs):
+        # Device_User.objects.filter(userEmail='chanjunkai@163.com').delete()
+        request.encoding = 'utf-8'
+        lang = request.GET.get('lang', None)
+        response = ResponseObject(lang)
+        request_dict = request.GET
+        # return self.do_register('157113010663213800138000', '157113010663213800138000', response, 'xx')
+
+        return self.ValidationError(request_dict, response)
+
+    def ValidationError(self, request_dict, response):
+        grant_code = request_dict.get('grant_code', None)  # 微信授权code
+        appBundleID = request_dict.get('appBundleID', None)  # 包名
+        token = request_dict.get('token', None)  # 包名
+        if all([grant_code, appBundleID, token]):
+            tko = TokenObject(token)
+            if tko.code == 0:
+                userID = tko.userID
+                app_config = {
+                    'com.ansjer.zccloud': {'appid': 'wx2a9f5ef9baf2760f', 'secret': '5d38c7079676463149ffea593c58f2ed'},
+                    # ios
+                    'com.ansjer.zccloud_ab': {'appid': 'wx2a9f5ef9baf2760f',
+                                              'secret': '5d38c7079676463149ffea593c58f2ed'},
+                    # android
+                }
+                if appBundleID in app_config.keys():
+                    appid = app_config[appBundleID]['appid']
+                    secret = app_config[appBundleID]['secret']
+                    # 获取access_token请求
+                    at_url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid={appid}&secret={secret}&code={code}&grant_type=authorization_code'.format(
+                        appid=appid, secret=secret, code=grant_code)
+                    res_req = requests.get(url=at_url)
+                    res_json = res_req.json()
+                    print(res_json)
+                    if 'access_token' not in res_json.keys():
+                        # 授权过期
+                        return response.json(717)
+                    access_token = res_json['access_token']
+                    openid = res_json['openid']
+                    if access_token and openid:
+                        user_has_bind = UserExtendModel.objects.filter(authOpenID=openid)
+                        if user_has_bind.exists():
+                            user_extend_qs = UserExtendModel.objects. \
+                                filter(userID_id=userID, authType=1, appBundleId=appBundleID)
+                            if user_extend_qs.exists():
+                                user_extend_qs.update(authOpenID=openid)
+                                return response.json(0)
+                            else:
+                                try:
+                                    nowTime = int(time.time())
+                                    UserExtendModel.objects.create(
+                                        addTime=nowTime,
+                                        updTime=nowTime,
+                                        appBundleId=appBundleID,
+                                        userID_id=userID,
+                                        authType=1,
+                                        authOpenID=openid)
+                                except Exception as e:
+                                    return response.json(424, repr(e))
+                                else:
+                                    return response.json(0)
+                        else:
+                            return response.json(16)
+                    else:
+                        return response.json(414, 'access_token,openid')
+                else:
+                    return response.json(414, 'appBundleID is wrong!')
+            else:
+                return response.json(tko.code)
+        else:
+            return response.json(414)
+
+
+# 获取验证码
+class OauthAuthCodeView(TemplateView):
+
+    @method_decorator(csrf_exempt)
+    def dispatch(self, *args, **kwargs):
+        return super(OauthAuthCodeView, self).dispatch(*args, **kwargs)
+
+    @ratelimit(key='ip', rate='2/m')
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        lang = request.POST.get('lang', None)
+        if not lang:
+            lang = request.POST.get('language', None)
+        response = ResponseObject(lang)
+        request_dict = request.POST
+        phone = request_dict.get('phone', None)
+        if phone is not None:
+            was_limited = getattr(request, 'limited', False)
+            if was_limited is True:
+                return response.json(5)
+        return self.ValidationError(request_dict, response)
+
+    @ratelimit(key='ip', rate='2/m')
+    def get(self, request, *args, **kwargs):
+        # Device_User.objects.filter(userEmail='chanjunkai@163.com').delete()
+        request.encoding = 'utf-8'
+        lang = request.GET.get('lang', None)
+        if not lang:
+            lang = request.GET.get('language', None)
+        response = ResponseObject(lang)
+        was_limited = getattr(request, 'limited', False)
+        if was_limited is True:
+            return response.json(5)
+        request_dict = request.GET
+        return self.ValidationError(request_dict, response)
+
+    def ValidationError(self, request_dict, response):
+        email = request_dict.get('email', None)
+        phone = request_dict.get('phone', None)
+        country_code = request_dict.get('country_code', None)
+        sign_name = request_dict.get('sign_name', None)
+        token = request_dict.get('token', None)
+        print(token)
+        if email is not None:
+            email = email.strip()
+            # 阿里云的发送邮箱的调用方法
+            return self.aliyun_emailCode(email, response)
+
+            # return self.emailCode(email, response)
+        elif phone is not None:
+            phone = phone.strip()
+            if country_code is None:
+                return self.phoneCode(phone, response, sign_name)
+            else:
+                country_code = str(country_code.strip())
+                return self.phoneCodeV2(country_code, phone, response, sign_name)
+        else:
+            return response.json(444)
+
+    def emailCode(self, email, response):
+
+        dataValid = DataValid()
+        # 邮箱匹配
+        if dataValid.email_validate(email) is False:
+            return response.json(107)
+        reds = RedisObject()
+        identifyingCode = reds.get_data(key=email + '_OauthPerfect')
+        # 是否以获取邮箱验证码
+        if identifyingCode:
+            return response.json(89)
+        user_qs = Device_User.objects.filter(username=email)
+        email_qs = Device_User.objects.filter(userEmail=email)
+        # 邮箱用户是否已存在
+        if user_qs.exists():
+            return response.json(103)
+        elif email_qs.exists():
+            return response.json(103)
+        # 生成随机6位数
+        identifyingCode = RandomStr(6, True)
+        # 设置随机数缓存生命周期
+        send_data = TemplateService.email_message(type='register_code', language=response.lang)
+        ses = SesClassObject()
+        # 发送邮件
+        send_res = ses.send_email(
+            send_address_list=[email],
+            subject=send_data['title'],
+            body=send_data['body'].replace("{username}", email).replace("{captcha}",
+                                                                        str(identifyingCode))
+        )
+        if send_res is not True:
+            return response.json(44)
+        if reds.set_data(key=email + '_OauthPerfect', val=identifyingCode, expire=600) is not True:
+            return response.json(10, 'error')
+        return response.json(0)
+        # return response.json(0, {'identifyingCode': identifyingCode})
+
+    # 阿里云获取邮箱验证码
+    def aliyun_emailCode(self, email, response):
+        print('阿里云开始')
+        dataValid = DataValid()
+        # 邮箱匹配
+        if dataValid.email_validate(email) is False:
+            return response.json(107)
+        reds = RedisObject()
+        identifyingCode = reds.get_data(key=email + '_OauthPerfect')
+        # 是否以获取邮箱验证码
+        if identifyingCode:
+            return response.json(89)
+        user_qs = Device_User.objects.filter(username=email)
+        email_qs = Device_User.objects.filter(userEmail=email)
+        # 邮箱用户是否已存在
+        if user_qs.exists():
+            return response.json(103)
+        elif email_qs.exists():
+            return response.json(103)
+        # 生成随机6位数
+        identifyingCode = RandomStr(6, True)
+        # 设置随机数缓存生命周期
+        send_data = TemplateService.email_message(type='register_code', language=response.lang)
+        ses = SesClassObject()
+        # 发送邮件
+        send_res = ses.alyEmailCode(
+            send_address_list=[email],
+            subject=send_data['title'],
+            body=send_data['body'].replace("{username}", email).replace("{captcha}", str(identifyingCode))
+        )
+        if send_res is not True:
+            return response.json(44)
+        if reds.set_data(key=email + '_OauthPerfect', val=identifyingCode, expire=600) is not True:
+            return response.json(10, 'error')
+        return response.json(0)
+
+    def phoneCode(self, phone, response, sign_name):
+        dataValid = DataValid()
+        if dataValid.mobile_validate(phone) is not True:
+            return response.json(107)
+        reds = RedisObject()
+        reds_key = str(phone) + '_OauthPerfect'
+        identifyingCode = reds.get_data(key=reds_key)
+        reds_key_ttl = reds.get_ttl(key=reds_key)
+        if reds_key_ttl > 240 and identifyingCode:
+            # if identifyingCode :
+            return response.json(90)
+        user_qs = Device_User.objects.filter(username=phone)
+        phone_qs = Device_User.objects.filter(phone=phone)
+        if user_qs.exists() or phone_qs.exists():
+            return response.json(101)
+        identifyingCode = RandomStr(6, True)
+        # 发送手机验证码
+        aliSms = AliSmsObject()
+        if sign_name == 'zosi':
+            sign_ms = '周视'
+        else:
+            sign_ms = 'Ansjer'
+        res = aliSms.send_code_sms(phone=phone, code=identifyingCode, sign_name=sign_ms,
+                                   temp_msg='SMS_151600991')
+        print(res)
+        if res["Code"] == "OK":
+            if reds.set_data(key=reds_key, val=identifyingCode, expire=300) is not True:
+                # if reds.set_data(key=phone + '_identifyingCode', val=identifyingCode, expire=60) is not True:
+
+                return response.json(10, '生成缓存系统错误')
+            return response.json(0)
+        else:
+            return response.json(10, res["Message"])
+
+    def phoneCodeV2(self, country_code, phone, response, sign_name):
+        dataValid = DataValid()
+        if dataValid.mobile_validate(phone) is not True:
+            return response.json(107)
+        reds = RedisObject()
+        reds_key = str(phone) + '_OauthPerfect'
+        identifyingCode = reds.get_data(key=reds_key)
+        reds_key_ttl = reds.get_ttl(key=reds_key)
+        if reds_key_ttl > 240 and identifyingCode:
+            # if identifyingCode :
+            return response.json(90)
+        user_qs = Device_User.objects.filter(username=phone)
+        phone_qs = Device_User.objects.filter(phone=phone)
+        if user_qs.exists() or phone_qs.exists():
+            return response.json(101)
+        identifyingCode = RandomStr(6, True)
+        # 短信签名
+        # sign_name_dict = {
+        #     'ansjer':'Ansjer',
+        #     'zosi':'周视'
+        # }
+        sign_ms = ''
+        if country_code == '86':
+            # 国内短信推送模板
+            temp_msg = 'SMS_151600991'
+            rec_phone = phone
+            if sign_name == 'zosi':
+                sign_ms = '周视'
+            else:
+                sign_ms = 'Ansjer'
+        else:
+            # 国际短信推送模板
+            temp_msg = 'SMS_172165867'
+            rec_phone = country_code + phone
+            sign_ms = 'Ansjer'
+
+        # 发送手机验证码
+        aliSms = AliSmsObject()
+        res = aliSms.send_code_sms(phone=rec_phone, code=identifyingCode, sign_name=sign_ms,
+                                   temp_msg=temp_msg)
+        print(res)
+        if res["Code"] == "OK":
+            # if reds.set_data(key=reds_key, val=identifyingCode, expire=60) is not True:
+            if reds.set_data(key=reds_key, val=identifyingCode, expire=300) is not True:
+                return response.json(10, '生成缓存系统错误')
+            return response.json(0)
+        else:
+            return response.json(10, res["Message"])
+
+
+class OauthPerfectView(TemplateView):
+    @method_decorator(csrf_exempt)
+    def dispatch(self, *args, **kwargs):
+        return super(OauthPerfectView, self).dispatch(*args, **kwargs)
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.GET
+        lang = request_dict.get('lang')
+        if not lang:
+            lang = request_dict.get('language', None)
+        response = ResponseObject(lang)
+        was_limited = getattr(request, 'limited', False)
+        if was_limited is True:
+            return response.json(5)
+        return self.ValidationError(request_dict, response)
+
+    def post(self, request):
+        request.encoding = 'utf-8'
+        request_dict = request.POST
+        lang = request_dict.get('lang')
+        if not lang:
+            lang = request_dict.get('language', None)
+        response = ResponseObject(lang)
+        was_limited = getattr(request, 'limited', False)
+        if was_limited is True:
+            return response.json(5)
+        return self.ValidationError(request_dict, response)
+
+    def ValidationError(self, request_dict, response):
+        phone = request_dict.get('phone', None)
+        email = request_dict.get('email', None)
+        password = request_dict.get('password', None)
+        authcode = request_dict.get('authcode', None)
+        token = request_dict.get('token', None)
+        print(token)
+        token = request_dict.get('token')
+        tko = TokenObject(token)
+        if password is None or authcode is None:
+            return response.json(444, 'password,authcode')
+        authcode = authcode.strip()
+        password = password.strip()
+        if phone is not None:
+            phone = phone.strip()
+            return self.do_phone(tko, phone, authcode, password, response)
+        elif email is not None:
+            email = email.strip()
+            return self.do_email(tko, email, authcode, password, response)
+        else:
+            return response.json(444, 'phone')
+
+    def do_email(self, tko, email, authcode, password, response):
+        data_valid = DataValid()
+        if data_valid.email_validate(email) is not True:
+            return response.json(105)
+        if data_valid.password_validate(password) is not True:
+            return response.json(109)
+
+        if tko.code == 0:
+            user_qs = Device_User.objects.filter(userID=tko.userID)
+        else:
+            return response.json(tko.code)
+        if not user_qs.exists():
+            return response.json(104)
+        reds = RedisObject()
+        resetCode = reds.get_data(key=email + '_OauthPerfect')
+        if resetCode is False:
+            return response.json(90)
+        if authcode != resetCode:
+            return response.json(121)
+        # if not reds.set_data(key=email + '_forgetPwdResetCode', val=resetCode, expire=300):
+        #     return response.json(10, '生成缓存错误')
+        user_qs.update(userEmail=email, password=make_password(password))
+        if not reds.del_data(email + '_OauthPerfect'):
+            return response.json(10, '删除缓存失败')
+        return response.json(0)
+
+    def do_phone(self, tko, phone, authcode, password, response):
+        data_valid = DataValid()
+        if data_valid.mobile_validate(phone) is not True:
+            return response.json(100)
+        if data_valid.password_validate(password) is not True:
+            return response.json(109)
+
+        if tko.code == 0:
+            user_qs = Device_User.objects.filter(userID=tko.userID)
+        else:
+            return response.json(tko.code)
+        if not user_qs.exists():
+            return response.json(102)
+        reds = RedisObject()
+        resetCode = reds.get_data(key=str(phone) + '_OauthPerfect')
+        print(resetCode)
+        if resetCode is False:
+            return response.json(90)
+        if authcode != resetCode:
+            return response.json(121)
+        # if not reds.set_data(key=phone + '_forgetPwdResetCode', val=resetCode, expire=300):
+        #     return response.json(10, '生成缓存错误')
+        user_qs.update(phone=phone, password=make_password(password))
+        if not reds.del_data(str(phone) + '_OauthPerfect'):
+            return response.json(10, '删除缓存失败')
+        return response.json(0)
+
+
+class UnbundingWXView(TemplateView):
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.GET
+        lang = request_dict.get('lang')
+        if not lang:
+            lang = request_dict.get('language', None)
+        response = ResponseObject(lang)
+        return self.ValidationError(request_dict, response)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.POST
+        lang = request_dict.get('lang')
+        if not lang:
+            lang = request_dict.get('language', None)
+        response = ResponseObject(lang)
+        return self.ValidationError(request_dict, response)
+
+    def ValidationError(self, request_dict, response):
+        token = request_dict.get('token', None)
+        auth_type = request_dict.get('auth_type', None)
+        if not all([token, auth_type]):
+            return response.json(444, 'token,auth_type')
+        tko = TokenObject(token)
+        if tko.code == 0:
+            userID = tko.userID
+            user_extend_qs = UserExtendModel.objects.filter(
+                ~Q(authOpenID='') & Q(userID_id=userID) & Q(authType=auth_type))
+            if user_extend_qs.exists():
+                user_qs = Device_User.objects.filter(phone='', userEmail='', userID=userID)
+                if user_qs.exists():
+                    return response.json(17)
+                else:
+                    user_extend_qs.update(authOpenID='', authType=0)
+                    return response.json(0)
+            else:
+                return response.json(173)
+        else:
+            return response.json(tko.code)

+ 6 - 4
Controller/shareUserPermission.py

@@ -40,6 +40,9 @@ class searchUserView(View):
         elif 'userID' in fieldDict.keys():
             userID = fieldDict.get('userID', None)
             User = Device_User.objects.filter(userID=userID).order_by('-data_joined')
+        elif 'roleName' in fieldDict.keys():
+            roleName = fieldDict.get('roleName', None)
+            User = Device_User.objects.filter(role__roleName__contains=roleName).order_by('-data_joined')
         else:
             User = Device_User.objects.filter(**fieldDict).order_by('-data_joined')
         if User.exists():
@@ -242,13 +245,13 @@ class shareUserEquipmentView(View):
                 return response.json(500, {"details": repr(e)})
             else:
                 if dictLen > 0:
-                    res = {'Shared': dictLen,'Sharing': len(querysetList),'errormsg': 'some had share'}
+                    res = {'Shared': dictLen, 'Sharing': len(querysetList), 'errormsg': 'some had share'}
                 else:
                     if sharedAll:
                         res = {'Sharing': len(querysetList)}
                     else:
                         if len(UID) > 0:
-                            res = {'error_UID': UID,'Sharing': len(querysetList)}
+                            res = {'error_UID': UID, 'Sharing': len(querysetList)}
                         else:
                             res = {'Sharing': len(querysetList)}
                 return response.json(0, res)
@@ -297,7 +300,7 @@ class unsharedUserEquipmentView(View):
                     if content != None and MasterID != None:
                         return self.unsharedUserEquipmentSQL(MasterID, GuestID, False, response, args, content=content)
                     else:
-                        return response.json(444,'content or unsharedAll')
+                        return response.json(444, 'content or unsharedAll')
             else:
                 return response.json(tko.code)
         else:
@@ -339,4 +342,3 @@ class unsharedUserEquipmentView(View):
                         return response.json(173, {'removeCount': removeCount, 'error_UID': errorUID})
                     else:
                         return response.json(0, {'removeCount': removeCount})
-

+ 48 - 5
Model/models.py

@@ -378,6 +378,9 @@ class FeedBackModel(models.Model):
     product_type = models.CharField(max_length=32, default='', verbose_name='设备uid')
     app_version = models.CharField(max_length=32, default='', verbose_name='app版本信息')
 
+    appBundleId = models.CharField(max_length=32, default='', verbose_name='app版本appBundleId')
+    email = models.CharField(max_length=32, default='', verbose_name='app版本email')
+
     def __str__(self):
         return self.id
 
@@ -486,6 +489,7 @@ class Equipment_Version(models.Model):
     update_time = models.DateTimeField(blank=True, verbose_name=u'更新时间', auto_now=True)
     lang = models.CharField(blank=True, default='en', max_length=32, verbose_name=u'ota包内置语言')
     mci = models.CharField(default='', blank=True, max_length=10, verbose_name='设备类型')
+    img = models.TextField(blank=True, default='', verbose_name=u'图片路径')
 
     def __str__(self):
         return self.eid
@@ -509,6 +513,7 @@ class App_Info(models.Model):
     add_time = models.DateTimeField(blank=True, null=True, verbose_name=u'加入时间', auto_now_add=True)
     update_time = models.DateTimeField(blank=True, verbose_name=u'更新时间', auto_now=True)
     downloadLink = models.TextField(blank=True, default='', verbose_name='升级')
+    img = models.CharField(default='', max_length=128, verbose_name='图片路径')
 
     def __str__(self):
         return self.id
@@ -623,7 +628,7 @@ class UID_Bucket(models.Model):
 
 class UID_Preview(models.Model):
     id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
-    uid = models.CharField(default='', max_length=20, verbose_name='设备UID')
+    uid = models.CharField(default='', max_length=20, db_index=True, verbose_name='设备UID')
     channel = models.SmallIntegerField(verbose_name=u'通道号', default=0)
     addTime = models.IntegerField(verbose_name='添加时间', default=0)
     updTime = models.IntegerField(verbose_name='更新时间', default=0)
@@ -638,8 +643,8 @@ class UID_Preview(models.Model):
 # 系统发送信息新到用户
 class SysMsgModel(models.Model):
     id = models.AutoField(primary_key=True, verbose_name='自增id')
-    userID = models.ForeignKey(Device_User, to_field='userID', on_delete=models.CASCADE)
-    msg = models.TextField(blank=True, default='', verbose_name=u'更新内容')
+    userID = models.ForeignKey(Device_User, to_field='userID', on_delete=models.CASCADE)  # 用户信息
+    msg = models.TextField(blank=True, default='', verbose_name=u'发送内容')
     status = models.SmallIntegerField(verbose_name='是否已读', default=0)  # 0:否,1:是
     addTime = models.IntegerField(verbose_name='添加时间', default=0)
     updTime = models.IntegerField(verbose_name='更新时间', default=0)
@@ -655,10 +660,10 @@ class SysMsgModel(models.Model):
 # 设备配置表,新
 class UidSetModel(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, db_index=True, verbose_name='设备UID')
     channel = models.SmallIntegerField(default=0, verbose_name='通道数量')  #
     detect_status = models.SmallIntegerField(default=0, verbose_name='推送开关')  # 状态[0:关闭,1:开启,2:用户解绑]
-    detect_interval = models.IntegerField(verbose_name='推送间隔', default=0)  # 秒
+    detect_interval = models.IntegerField(verbose_name='推送间隔', default=60)  # 秒
     addTime = models.IntegerField(verbose_name='添加时间', default=0)
     updTime = models.IntegerField(verbose_name='更新时间', default=0)
     # addTime 2019年 05月 27日 星期一 16:52:55 CST
@@ -693,9 +698,47 @@ class UidPushModel(models.Model):
     addTime = models.IntegerField(verbose_name='添加时间', default=0)
     updTime = models.IntegerField(verbose_name='更新时间', default=0)
     lang = models.CharField(max_length=8, verbose_name='推送语言类型', default='en')  # en英文 cn中文
+    tz = models.CharField(max_length=8, verbose_name='utc时区', default='0')
 
     class Meta:
         db_table = 'uid_push'
         verbose_name = '设备绑定'
         verbose_name_plural = verbose_name
         ordering = ('-id',)
+
+
+# oauth2 第三方登录补全信息
+class UserExtendModel(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name='自增id')
+    userID = models.ForeignKey(Device_User, to_field='userID', on_delete=models.CASCADE)
+    appBundleId = models.CharField(default='', max_length=32, verbose_name=u'appID')
+    authType = models.SmallIntegerField(default=0, verbose_name=0)  # 授权类型 0 非授权,1 微信授权
+    authOpenID = models.CharField(default='', max_length=64, verbose_name='唯一标记')  # 绑定唯一标记
+    region = models.CharField(default='', max_length=16, verbose_name='区域语言')
+    addTime = models.IntegerField(verbose_name='添加时间', default=0)
+    updTime = models.IntegerField(verbose_name='更新时间', default=0)
+
+    # {'cn': '简体中文', 'tc': '繁体中文', 'fr': '法文', 'ru': '俄文', 'es': '西班牙文', 'pl': '波兰文', 'ja': '日文', 'de': '德文', 'en': '英文'}
+
+    class Meta:
+        db_table = 'user_extend'
+        verbose_name = '用户扩展信息表'
+        verbose_name_plural = verbose_name
+        ordering = ('-id',)
+
+
+class SysMassModel(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name='主键自增id')
+    sender = models.ForeignKey(Device_User, to_field='userID', on_delete=models.CASCADE)  # 发送人
+    platform = models.CharField(default='', verbose_name='平台', max_length=16)
+    lang = models.TextField(blank=True, default='', verbose_name=u'语种')
+    recever = models.TextField(blank=True, default='', verbose_name=u'接受者')
+    msg = models.TextField(blank=True, default='', verbose_name=u'发送内容')
+    addTime = models.IntegerField(verbose_name='添加时间', default=0)
+    updTime = models.IntegerField(verbose_name='修改时间', default=0)
+
+    class Meta:
+        db_table = 'sys_mass'
+        verbose_name = '群发消息记录表'
+        verbose_name_plural = verbose_name
+        ordering = ('-id',)

+ 61 - 0
Object/AWS/DynamodbObject.py

@@ -0,0 +1,61 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+"""
+@Copyright (C) ansjer cop Video Technology Co.,Ltd.All rights reserved.
+@AUTHOR: ASJRD018
+@NAME: AnsjerFormal
+@software: PyCharm
+@DATE: 2019/10/9 16:17
+@Version: python3.6
+@MODIFY DECORD:ansjer dev
+@file: DynamodbObject.py
+@Contact: chanjunkai@163.com
+"""
+from boto3 import Session
+from botocore.exceptions import ClientError
+from boto3.dynamodb.conditions import Key, Attr
+import logging
+import json
+import boto3
+from var_dump import var_dump
+
+# AWS_DynamoDB_REGION = ''
+# AWS_DynamoDB_ACCESS_KEY = ''
+# AWS_DynamoDB_SECRET_KEY = ''
+AWS_DynamoDB_REGION = 'us-west-1'
+AWS_DynamoDB_ACCESS_KEY = 'AKIA2E67UIMD4PZTYKYD'
+AWS_DynamoDB_SECRET_KEY = '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'
+
+
+class DynamodbObject(object):
+    def __init__(self, *args, **kwargs):
+        self.region = AWS_DynamoDB_REGION
+        self.access_key = AWS_DynamoDB_ACCESS_KEY
+        self.secret_key = AWS_DynamoDB_SECRET_KEY
+        self.session = Session(aws_access_key_id=self.access_key,
+                               aws_secret_access_key=self.secret_key,
+                               region_name=self.region)
+
+    def do_table_handle(self, table_name):
+        dynamodb = self.session.resource('dynamodb')
+        table_handle = dynamodb.Table(table_name)
+        return table_handle
+
+    def do_san(self, filter_data, table_name):
+        var_dump('xjklfjl;asjl;sdf')
+        table_handle = self.do_table_handle(table_name)
+        response = table_handle.scan(
+            ProjectionExpression="userID",
+            FilterExpression=Attr('appId').eq('com.ansjer.zccloud'),
+        )
+        var_dump('xxloo')
+        var_dump(response)
+        var_dump('****************')
+        items = response['Items']
+
+        return ''
+
+
+# dobj = DynamodbObject()
+# res = dobj.do_san(filter_data={'appId': 'com.ansjer.zccloud'}, table_name='user_brand')
+

+ 8 - 0
Object/ResponseObject.py

@@ -14,6 +14,8 @@ class ResponseObject(object):
             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',
@@ -52,10 +54,12 @@ class ResponseObject(object):
             711: 'Do not downgrade',
             712: 'Area needs to be consistent',
             713: 'Storage rules cannot be changed during the validity period',
+            717: 'Authorization expires',
             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!',
         }
@@ -66,6 +70,8 @@ class ResponseObject(object):
             12: '非设备主用户',
             14: '设备不属于您',
             15: '设备已被绑定',
+            16: '微信已被绑定,请使用微信登录并解绑',
+            17: '未绑定邮箱或者手机登录方式',
             44: '系统错误!无法发送电子邮件',
             48: '系统对象错误',
             89: '已发验证码,请检测或10分钟后重新获取。',
@@ -104,10 +110,12 @@ class ResponseObject(object):
             711: '不可降级',
             712: '区域不一致',
             713: '有效期内不可更改存储规则',
+            717: '授权过期',
             900: '版本信息不存在',
             901: '获取链接失败',
             902: '无更新!',
             903: '文件名不符合!',
+            904: '版本不支持本功能!',
             906: '文件操作错误',
             907: '文件不存在!',
         }

+ 1 - 1
Object/TokenObject.py

@@ -21,7 +21,7 @@ class TokenObject:
 
     def __init__(self, token=None):
         if token == 'local':
-            token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VySUQiOiIxNTQzOTA5MDUwNDEzMTM4MDAxMzgwMDAiLCJsYW5nIjoiZW4iLCJ1c2VyIjoiMTM4MDAxMzgwMDEiLCJtX2NvZGUiOiIxMjM0MTMyNDMyMTQiLCJleHAiOjE1NzA2ODY5NDl9.ivlkQ3d9ADaIsC76DR7q0K1irhTnm8RwaLnn_AVyO9g'
+            token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VySUQiOiIxNTQzOTA5MDUwNDEzMTM4MDAxMzgwMDAiLCJsYW5nIjoiZW4iLCJ1c2VyIjoiMTM4MDAxMzgwMDEiLCJtX2NvZGUiOiIxMjM0MTMyNDMyMTQiLCJleHAiOjE1NzMyODEzMjB9.qc20AsKGCVz-rvPSPyxulQy0BrG_nUdO3fxjT-KSv0w'
         if token == 'test':
             token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiMTM4MDAxMzgwMDEiLCJleHAiOjE1Njk5OTg4OTYsInVzZXJJRCI6IjE1MTU2NDI2MjMzNzkzOTUxMzgwMDEzODAwMSIsImxhbmciOiJlbiIsIm1fY29kZSI6IjEyMzQxMzI0MzIxNCJ9.VAQtT9AbCCfXcrNj9DL5cvVasMDoI7AP8ptgU1GoMu8'
         self.token = token

+ 11 - 5
Service/CommonService.py

@@ -50,7 +50,7 @@ class CommonService:
 
     @staticmethod
     def get_param_flag(data=[]):
-        print(data)
+        # print(data)
         flag = True
         for v in data:
             if v is None:
@@ -102,14 +102,11 @@ class CommonService:
 
     # 通过ip检索ipip指定信息 lang为CN或EN
     @staticmethod
-    def getIpIpInfo(ip,lang,update=False):
+    def getIpIpInfo(ip, lang, update=False):
         ipbd_dir = BASE_DIR + "/DB/mydata4vipday2.ipdb"
         db = ipdb.City(ipbd_dir)
         if update:
-            from var_dump import var_dump
-            var_dump('is_update')
             rr = db.reload(ipbd_dir)
-            var_dump(rr)
         info = db.find_map(ip, lang)
         return info
 
@@ -193,3 +190,12 @@ class CommonService:
                     ps['data_joined'] = ''
             res.append(ps)
         return res
+
+    # 获取当前时间
+    @staticmethod
+    def get_now_time_str(n_time, tz):
+        n_time = int(n_time)
+        if tz:
+            n_time = n_time + 3600 * float(tz)
+        n_date = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(int(n_time)))
+        return n_date

+ 312 - 1
Service/MiscellService.py

@@ -5,6 +5,7 @@ import time
 import requests
 import simplejson as json
 from django.utils.timezone import utc
+from Ansjer import local_settings as api_settings
 
 from Object.TokenObject import TokenObject
 from Object.mongodb import mongodb
@@ -13,6 +14,200 @@ from Service.ModelService import ModelService
 from Service.TemplateService import TemplateService
 from Object.RedisObject import RedisObject
 from Ansjer.config import SERVER_TYPE
+from Model.models import Device_User
+# coding:utf-8
+from boto3 import Session
+from botocore.exceptions import ClientError
+from boto3.dynamodb.conditions import Key, Attr
+import logging
+import json
+from Ansjer.config import DOMAIN_HOST,AWS_DynamoDB_REGION,AWS_DynamoDB_ACCESS_KEY,AWS_DynamoDB_SECRET_KEY
+logger = logging.getLogger(__name__)
+
+class MyserviceDynamodb():
+    def __init__(self, **kwargs):
+        self.region = AWS_DynamoDB_REGION
+        self.access_key = AWS_DynamoDB_ACCESS_KEY
+        self.secret_key = AWS_DynamoDB_SECRET_KEY
+        self.session = self.__session()
+
+    def __session(self):
+        try:
+            session = Session(aws_access_key_id=self.access_key, aws_secret_access_key=self.secret_key,region_name=self.region)
+        except:
+            print("Failed to connect session in region{0}".format(self.region))
+        return session
+
+    # 添加access_log表数据
+    def access_log_item_put(self,table_name,data_list):
+        dynamodb = self.session.resource('dynamodb')
+        table = dynamodb.Table(table_name)
+        with table.batch_writer() as batch:
+            for i in data_list:
+                data = json.loads(i.decode('utf-8'))
+                if data['userID'] == '' :
+                    try:
+                        user_id = Device_User.objects.filter(username= data['userName']).values('userID')
+                        data['userID'] = user_id[0]['userID']
+                    except Exception:
+                        data['userID'] =''
+                batch.put_item(
+                    Item={
+                        'userID':data['userID'],
+                        'addTime':data['addTime'],
+                        'ip':data['ip'],
+                        'status':data['status'],
+                        'operation':data['operation'],
+                        'content':data['content'],
+                        'Expiration_time':data['Expiration_time'],
+                    }
+                )
+        print ('添加access_log表数据成功!')
+
+# 搜索该数据库表的方法
+    def get_item(self, table_name, values):
+        dynamodb = self.session.resource('dynamodb')
+        if not dynamodb:
+            raise DynamodbConnectionError("Failed to get resource for dynamodb!")
+        try:
+            table = dynamodb.Table(table_name)
+            response = table.scan(
+                FilterExpression = Attr('userID').eq(values)
+                                 | Key('ip').eq(values)
+                                 | Key('status').eq(values)
+                                 | Key('content').eq(values)
+                                 | Key('operation').eq(values)
+            )
+            items = response['Items']
+            return items
+        except Exception as e:
+            logger.error("Failed to get table {0}, error".format(table_name, e))
+            return []
+
+    # 时间段搜索
+    def get_item_time(self, table_name, start_date, end_date):
+        dynamodb = self.session.resource('dynamodb')
+        if not dynamodb:
+            raise DynamodbConnectionError("Failed to get resource for dynamodb!")
+        try:
+            table = dynamodb.Table(table_name)
+            response = table.scan(
+                Select='COUNT',
+                FilterExpression=(Attr('addTime').gt(start_date)
+                                 & Key('addTime').lt(end_date)) | Key('addTime').eq(start_date)
+            )
+            items = response['Count']
+            return items
+        except Exception as e:
+            logger.error("Failed to get table {0}, error".format(table_name, e))
+            return 0
+
+    # 时间段搜索
+    def get_item_date(self, table_name, date):
+        dynamodb = self.session.resource('dynamodb')
+        if not dynamodb:
+            raise DynamodbConnectionError("Failed to get resource for dynamodb!")
+        res = {}
+        try:
+            table = dynamodb.Table(table_name)
+            times = datetime.datetime.fromtimestamp(date)
+            time_dict = CommonService.getTimeDict(times)
+            for k, v in time_dict.items():
+                start_date = time_dict[k]
+                end_date = time_dict[k] + datetime.timedelta(hours=1)
+                start_date = int(start_date.timestamp())
+                end_date = int(end_date.timestamp())
+                response = table.scan(
+                    Select = 'COUNT',
+                    FilterExpression=(Attr('addTime').gt(start_date)
+                                      & Key('addTime').lt(end_date)) | Key('addTime').eq(start_date)
+                )
+                print (response['Count'])
+                count = response['Count']
+                if count:
+                    res[k] = count
+                else:
+                    res[k] = 0
+        except Exception as e:
+            logger.error("Failed to get table {0}, error".format(table_name, e))
+        return res
+
+    def item_get_brand(self, table_name):
+        dynamodb = self.session.resource('dynamodb')
+        table = dynamodb.Table(table_name)
+        try:
+            response = table.scan()
+            response = response['Items']
+            return response
+        except Exception:
+            logger.error("Failed to put item in to {0}:error{1}".format(table))
+
+
+
+# 查询aws数据库里面有什么表
+    def tables_list(self, table_name):
+        client = self.session.client('dynamodb')
+        response = client.list_tables()
+        return response['TableNames']
+
+    # 创建access_log表
+    def access_log_table_create(self, table_name):
+        dynamodb = self.session.resource('dynamodb')
+        inventory = my.tables_list(table_name)
+        if table_name in inventory:
+            print ('access_log表包含')
+        else:
+            try:
+                table = dynamodb.create_table(
+                    TableName=table_name,
+                    KeySchema=[
+                        {
+                            'AttributeName': 'userID',
+                            'KeyType': 'HASH'
+                        },
+                        {
+                            'AttributeName': 'addTime',
+                            'KeyType': 'RANGE'
+                        }
+                    ],
+                    AttributeDefinitions=[
+                        {
+                            'AttributeName': 'userID',
+                            'AttributeType': 'S'
+                        },
+                        {
+                            'AttributeName': 'addTime',
+                            'AttributeType': 'N'
+                        },
+
+                    ],
+                    ProvisionedThroughput={
+                        'ReadCapacityUnits': 5,
+                        'WriteCapacityUnits': 5,
+                    }
+                )
+                print ('创建表成功')
+            except Exception:
+                logger.error (table_name + '表已经存在')
+
+    # 删除表
+    def table_delete(self, table_name):
+        dynamodb = self.session.resource('dynamodb')
+        table = dynamodb.Table(table_name)
+        table.delete()
+        print ('删除表成功')
+
+my = MyserviceDynamodb()
+
+# print(my.table_delete('user_brand_all'))
+if DOMAIN_HOST == 'www.dvema.com':
+    user_brand = 'access_log'
+else:
+    user_brand = 'test_access_log'
+
+# my.table_delete(user_brand)
+# my.access_log_table_create(user_brand)
+
 
 
 # 杂项类,共用行不高,但有些地方需求
@@ -102,6 +297,26 @@ class MiscellService():
                     country = json_data['data']['country']
         return country
 
+    @staticmethod
+    def get_item_log(table_name, values):
+        item_log = my.get_item(table_name, values)
+        return item_log
+
+    @staticmethod
+    def item_get_brand(table_name):
+        item_log = my.item_get_brand(table_name)
+        return item_log
+
+    @staticmethod
+    def get_item_time(table_name,start_date, end_date):
+        item_log = my.get_item_time(table_name,start_date, end_date)
+        return item_log
+
+    @staticmethod
+    def get_item_date(table_name,date):
+        item_log = my.get_item_date(table_name,date)
+        return item_log
+
     # 下载接口添加访问日志
     @staticmethod
     def add_ota_download_log(request):
@@ -124,6 +339,11 @@ class MiscellService():
         asy = threading.Thread(target=batch_add_log_ctr, args=(request, status_code))
         asy.start()
 
+    @staticmethod
+    def DynamoDB_add_access_log(request, status_code):
+        asy = threading.Thread(target=dynamo_db_add_log_ctr, args=(request, status_code))
+        asy.start()
+
 
 def addLog(request, status_code):
     try:
@@ -189,7 +409,7 @@ def batch_add_log_ctr(request, status_code):
         }
         redisObj = RedisObject()
         loggerData = json.dumps(add_data)
-        print(loggerData)
+        # print(loggerData)
         if SERVER_TYPE == 'Ansjer.formal_settings':
             logKey = 'logger'
         else:
@@ -200,3 +420,94 @@ def batch_add_log_ctr(request, status_code):
             data_list = redisObj.lrange(logKey, 0, -1)
             redisObj.del_data(key=logKey)
             ModelService.add_batch_log(data_list)
+
+
+def dynamo_db_add_log_ctr(request, status_code):
+    request.encoding = 'utf-8'
+    if request.method == 'GET':
+        request_dict = request.GET
+    elif request.method == 'POST':
+        request_dict = request.POST
+    else:
+        return
+    api_list = TemplateService.log_api()
+    request_path = request.path.strip().strip('/')
+    if SERVER_TYPE == 'Ansjer.formal_settings':
+        logKey = 'loggers'
+    else:
+        logKey = 'test_loggers'
+    # 判断redis列表长度为10条以上就会添加日志
+    num = 1
+    clientIP = CommonService.get_ip_address(request)
+    token = request_dict.get('token', None)
+    userID = '无'
+    if token is not None:
+        tko = TokenObject(token)
+        userID = tko.userID
+    password = request_dict.get('userPwd', None)
+    userName = request_dict.get('userName', None)
+    if password is not None:
+        request_dict = dict(request_dict)
+        request_dict.pop('userPwd')
+    content = json.dumps(request_dict)
+    addTime = int(time.time())
+    if DOMAIN_HOST == 'www.dvema.com':
+        user_brand = 'access_log'
+    else:
+        user_brand = 'test_access_log'
+    # 过滤某些接口集合
+    if request_path in api_list:
+        add_data = {
+            'userName':userName,
+            'userID': userID,
+            'ip': clientIP,
+            'status': status_code,
+            'operation': request_path,
+            'addTime': addTime,
+            'content': content,
+            'Expiration_time': addTime + 2592000
+        }
+        redisObj = RedisObject()
+        loggerData = json.dumps(add_data)
+        redisObj.rpush(name=logKey, val=loggerData)
+        # 判断redis列表长度
+        if redisObj.llen(name=logKey) > num or SERVER_TYPE == 'Ansjer.test_settings':
+            data_list = redisObj.lrange(logKey, 0, -1)
+            redisObj.del_data(key=logKey)
+            my.access_log_item_put(user_brand,data_list)
+
+    # 判断是是否是下载接口的
+    else:
+        path = request.path
+        index = path.find('/OTA/downloads')
+        if index != -1:
+            addsCount = len(api_settings.ADDR_URL)
+            if addsCount > 1000:
+                response = ResponseObject()
+                # 提示获取链接失败,实际上是下载太频繁,超过了1000的并发量
+                return response.json(901)
+            else:
+                # 合理的情况就添加访问日志
+                adds = request.META.get('REMOTE_ADDR', None)
+                api_settings.ADDR_URL.append(adds)
+                add_data = {
+                    'userName': '无',
+                    'userID':'无',
+                    'ip': clientIP,
+                    'status': status_code,
+                    'operation': request_path,
+                    'addTime': addTime,
+                    'content': content,
+                    'Expiration_time': addTime + 2592000
+                }
+                redisObj = RedisObject()
+                loggerData = json.dumps(add_data)
+                redisObj.rpush(name=logKey, val=loggerData)
+                # 判断redis列表长度
+                if redisObj.llen(name=logKey) > num or SERVER_TYPE == 'Ansjer.test_settings':
+                    data_list = redisObj.lrange(logKey, 0, -1)
+                    redisObj.del_data(key=logKey)
+                    my.access_log_item_put(user_brand, data_list)
+
+
+

+ 11 - 2
Service/ModelService.py

@@ -113,6 +113,7 @@ class ModelService:
         else:
             return True
 
+
     # 通过用户名获取userIDLIST
     @staticmethod
     def get_user_list_by_username(username):
@@ -121,9 +122,17 @@ class ModelService:
         return userID_list
 
     @staticmethod
-    def del_eq_info(userID,uid):
+    def del_eq_info(userID, uid):
         ei_qs = Equipment_Info.objects.filter(userID_id=userID, devUid=uid)
         ei_qs.delete()
         # ei_count = ei_qs.count()
         # while (ei_count > 1000):
-        #     ei_qs[0:1000].delete()
+        #     ei_qs[0:1000].delete()
+
+        # 根据设备主键ID判断是否拥有该设备
+
+    # 获取绑定用户设备列表
+    @staticmethod
+    def get_uid_list(userID):
+        uid_list = Device_Info.objects.filter(userID_id=userID).values_list('UID', flat=True)
+        return list(uid_list)

+ 2 - 3
Service/TemplateService.py

@@ -60,15 +60,14 @@ class TemplateService:
             'deviceShare/confirm',
             'deviceShare/deleteUser',
             'equipment/delete',
-            'equipment/add',
             'equipment/query',
             'order/querylist',
             'detect/changeStatus',
             # 'notify/push',
             'equipment/flowUpdate',
             'wechat/authsign',
-        ]
-        return apiList
+
+		 return apiList
 
     @staticmethod
     def email_message(type, language):

+ 4 - 4
Service/middleware.py

@@ -77,18 +77,18 @@ class StatisticsUrlMiddleware(MiddlewareMixin):
         '''
         self._https_statistics_to_close(request)
         ########记录访问日志
+        # MiscellService.DynamoDB_add_access_log(request=request, status_code=response.status_code)
+
         if request.path !='/favicon.ico':
             print('process_response', request, response)
             try:
+                #pass
                 # mysql
                 MiscellService.batch_add_access_log(request=request, status_code=response.status_code)
-
-                print(request.path);
                 # MiscellService.add_access_log(request=request, status_code=response.status_code)
                 # mongodb版
                 # MiscellService.access_log(request=request, response=response, type=0)
             except Exception as e:
                 print(repr(e))
             django.db.close_old_connections()
-        return response
-
+		return response