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

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

 Conflicts:
	Controller/OTAEquipment.py
zhangdongming 3 жил өмнө
parent
commit
6c3607bad5

+ 6 - 1
AdminController/DeviceManagementController.py

@@ -11,6 +11,8 @@ from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from django.views.generic.base import View
+
+from Service.EquipmentInfoService import EquipmentInfoService
 from Service.ModelService import ModelService
 from Service.CommonService import CommonService
 from Model.models import Device_Info, UidSetModel, LogModel, UID_Bucket, Unused_Uid_Meal, Order_Model, StsCrdModel, \
@@ -131,7 +133,10 @@ class DeviceManagement(View):
         try:
             with transaction.atomic():
                 Device_Info.objects.filter(id=deviceID).delete()
-                Equipment_Info.objects.filter(userID_id=userID, devUid=uid).delete()    # 删除推送消息
+                # 删除推送消息
+                for val in range(1, 8):
+                    EquipmentInfoService.get_equipment_info_model('', val).\
+                        filter(device_user_id=userID, device_uid=uid).delete()
             return response.json(0)
         except Exception as e:
             print(e)

+ 1 - 1
AdminController/SerialManageController.py

@@ -182,7 +182,7 @@ class SerialView(View):
             if not company_serial_qs.exists():
                 return response.json(0, {'list': '', 'total': 0})
             total = company_serial_qs.count()
-            serial_number_page = company_serial_qs.order_by('-add_time')[(page - 1) * line:page * line].\
+            serial_number_page = company_serial_qs.order_by('-serial_number')[(page - 1) * line:page * line].\
                 values('serial_number', 'company__name', 'status', 'add_time', 'update_time')
             return response.json(0, {'list': list(serial_number_page), 'total': total})
         except Exception as e:

+ 1 - 0
Ansjer/config.py

@@ -154,6 +154,7 @@ AWS_IOT_GETS3_PULL_CHINA_SECRET = 'NaZwPz1si6/6x9c834w7+sxCXL6RIRAYC+g14PPG'
 AWS_IOT_SES_ACCESS_CHINA_ID = 'AKIA2MMWBR4DUUYPCFNJ'
 AWS_IOT_SES_ACCESS_CHINA_SECRET = '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'
 AWS_IOT_SES_ACCESS_CHINA_REGION = 'cn-northwest-1'
+# IAM角色: https://console.amazonaws.cn/iamv2/home#/roles/details/Ansjer_Iot_Admin?section=permissions
 AWS_IOT_SES_ACCESS_CHINA_ROLE = 'arn:aws-cn:iam::713816116999:role/service-role/Ansjer_Iot_Admin'
 
 IOT_HOST = {

+ 8 - 4
Ansjer/urls.py

@@ -25,6 +25,7 @@ from Controller.Cron import CronTaskController
 from AdminController import UserManageController, RoleController, MenuController, TestServeController, \
     ServeManagementController, LogManagementController, DeviceManagementController, VersionManagementController, \
     AiServeController, SurveysManageController, SerialManageController
+from SensorGateway import SensorGatewayController
 
 urlpatterns = [
     url(r'^testApi/(?P<operation>.*)$', TestApi.testView.as_view()),
@@ -358,6 +359,9 @@ urlpatterns = [
     # 问卷调查
     url(r'^api/surveys/(?P<operation>.*)$', CloudStorageController.CloudStorageView.as_view()),
 
+    # 传感器网关
+    re_path('sensorGateway/(?P<operation>.*)', SensorGatewayController.SensorGateway.as_view()),
+
     # 后台界面接口 -----------------------------------------------------
     # 用户登录信息等
     url(r'^login$', UserManageController.LoginView.as_view()),
@@ -383,15 +387,15 @@ urlpatterns = [
     # AI服务
     re_path('aiServe/(?P<operation>.*)', AiServeController.AiServeView.as_view()),
     # 问卷调查管理
-    url(r'surveys/(?P<operation>.*)', SurveysManageController.SurveysView.as_view()),
+    re_path(r'surveys/(?P<operation>.*)', SurveysManageController.SurveysView.as_view()),
     # 序列号管理
-    url(r'serial/(?P<operation>.*)', SerialManageController.SerialView.as_view()),
+    re_path(r'serial/(?P<operation>.*)', SerialManageController.SerialView.as_view()),
     # 后台界面接口 -----------------------------------------------------
 
     # 定时删除任务接口
-    url(r'^cron/del/(?P<operation>.*)', CronTaskController.CronDelDataView.as_view()),
+    re_path(r'^cron/del/(?P<operation>.*)', CronTaskController.CronDelDataView.as_view()),
     # 定时更新任务接口
-    url(r'^cron/update/(?P<operation>.*)', CronTaskController.CronUpdateDataView.as_view()),
+    re_path(r'^cron/update/(?P<operation>.*)', CronTaskController.CronUpdateDataView.as_view()),
 
     re_path('(?P<path>.*)', LogManager.errorPath),
 

+ 36 - 14
Controller/Cron/CronTaskController.py

@@ -7,6 +7,7 @@
 # @Email   : zhangdongming@asj6.wecom.work
 # @File    : CronTaskController.py
 # @Software: PyCharm
+import datetime
 import time
 
 from django.db import connection, connections, transaction
@@ -32,7 +33,7 @@ class CronDelDataView(View):
 
     def validation(self, request_dict, request, operation):
         response = ResponseObject()
-        if operation == 'delAccessLog':   # 定时删除访问接口数据
+        if operation == 'delAccessLog':  # 定时删除访问接口数据
             return self.delAccessLog(response)
         elif operation == 'delPushInfo':  # 定时删除推送数据
             return self.delPushInfo(response)
@@ -62,14 +63,35 @@ class CronDelDataView(View):
 
     @staticmethod
     def delPushInfo(response):
-        nowTime = int(time.time())
+        now_time = int(time.time())
         cursor = connections['mysql02'].cursor()
         try:
+            # 当前时间转日期
+            local_date_now = str(datetime.datetime.fromtimestamp(int(now_time)).date())
+            # 根据日期获取周几
+            week_val = LocalDateTimeUtil.date_to_week(local_date_now)
+            # 根据当前时间获取7天前时间戳
+            expiration_time = LocalDateTimeUtil.get_before_days_timestamp(now_time, 7)
+            # 每次删除条数
+            size = 10000
+            # 删除7天前的数据
+            sql = "DELETE FROM equipment_info WHERE eventTime<= %s LIMIT %s "
+            if week_val == 1:
+                sql = "DELETE FROM equipment_info_sunday WHERE event_time<= %s LIMIT %s "
+            if week_val == 2:
+                sql = "DELETE FROM equipment_info_monday WHERE event_time<= %s LIMIT %s "
+            if week_val == 3:
+                sql = "DELETE FROM equipment_info_tuesday WHERE event_time<= %s LIMIT %s "
+            if week_val == 4:
+                sql = "DELETE FROM equipment_info_wednesday WHERE event_time<= %s LIMIT %s "
+            if week_val == 5:
+                sql = "DELETE FROM equipment_info_thursday WHERE event_time<= %s LIMIT %s "
+            if week_val == 6:
+                sql = "DELETE FROM equipment_info_friday WHERE event_time<= %s LIMIT %s "
+            if week_val == 7:
+                sql = "DELETE FROM equipment_info_saturday WHERE event_time<= %s LIMIT %s "
             for i in range(5):
-                # 删除7天前的数据
-                sql = "DELETE FROM `equipment_info` WHERE addTime<={} LIMIT 10000".format(
-                    nowTime - 3600 * 24 * 7)
-                cursor.execute(sql)
+                cursor.execute(sql, [expiration_time, size])
             # 关闭游标
             cursor.close()
             return response.json(0)
@@ -160,11 +182,11 @@ class CronUpdateDataView(View):
 
     def validation(self, request_dict, request, operation):
         response = ResponseObject()
-        if operation == 'expiredUidBucket':   # 定时更新过期云存套餐状态
+        if operation == 'expiredUidBucket':  # 定时更新过期云存套餐状态
             return self.expiredUidBucket(response)
-        elif operation == 'updateUnusedUidBucket':   # 定时更新过期云存关联的未使用套餐状态
+        elif operation == 'updateUnusedUidBucket':  # 定时更新过期云存关联的未使用套餐状态
             return self.updateUnusedUidBucket(response)
-        elif operation == 'updateUnusedAiService':   # 定时更新过期ai关联的未使用套餐状态
+        elif operation == 'updateUnusedAiService':  # 定时更新过期ai关联的未使用套餐状态
             return self.updateUnusedAiService(response)
         else:
             return response.json(404)
@@ -185,7 +207,7 @@ class CronUpdateDataView(View):
             has_unused=1).values(
             "id",
             "uid")[
-            0:1000]
+                              0:1000]
         for expired_uid_bucket in expired_uid_buckets:
             unuseds = Unused_Uid_Meal.objects.filter(
                 uid=expired_uid_bucket['uid']).values(
@@ -196,7 +218,7 @@ class CronUpdateDataView(View):
                 "expire",
                 "num",
                 "bucket_id").order_by('addTime')[
-                0:1]
+                      0:1]
             if not unuseds.exists():
                 continue
             unused = unuseds[0]
@@ -230,18 +252,18 @@ class CronUpdateDataView(View):
             use_status=1).values(
             'id',
             'uid')[
-            0:200]
+                        0:200]
         for ai_service in ai_service_qs:
             try:
                 with transaction.atomic():
                     AiService.objects.filter(
                         id=ai_service['id']).update(
-                        use_status=2)      # 更新过期ai订单状态
+                        use_status=2)  # 更新过期ai订单状态
                     # 如果存在未使用套餐,更新为使用
                     unused_ai_service = AiService.objects.filter(
                         uid=ai_service['uid'],
                         use_status=0).order_by('addTime')[
-                        :1].values(
+                                        :1].values(
                         'id',
                         'endTime')
                     if unused_ai_service.exists():

+ 75 - 59
Controller/DetectControllerV2.py

@@ -11,34 +11,33 @@
 @file: DetectController.py
 @Contact: chanjunkai@163.com
 """
+import json
 import os
 import time
-import json
+
 import apns2
+import boto3
+import botocore
 import jpush as jpush
 import oss2
+from botocore import client
 from django.http import JsonResponse
 from django.views.generic.base import View
 from pyfcm import FCMNotification
-from Object.RedisObject import RedisObject
-from Ansjer.config import DETECT_PUSH_DOMAIN, DETECT_PUSH_DOMAINS, DETECT_PUSH_DOMAIN_JIUAN, DETECT_PUSH_DOMAINS_JIUAN,\
-                            SERVER_DOMAIN, SERVER_DOMAIN_SSL, \
-                            OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, \
-                            JPUSH_CONFIG, FCM_CONFIG, APNS_CONFIG, BASE_DIR, APNS_MODE,  SERVER_TYPE
+
+from Ansjer.config import DETECT_PUSH_DOMAIN, DETECT_PUSH_DOMAINS, DETECT_PUSH_DOMAIN_JIUAN, DETECT_PUSH_DOMAINS_JIUAN, \
+    OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, \
+    JPUSH_CONFIG, FCM_CONFIG, APNS_CONFIG, BASE_DIR, APNS_MODE, SERVER_TYPE
+from Ansjer.config import PUSH_REDIS_ADDRESS
 from Model.models import Device_Info, VodHlsModel, Equipment_Info, UidSetModel, UidPushModel, CompanyModel, SysMsgModel, \
     AiService
 from Object.ETkObject import ETkObject
 from Object.RedisObject import RedisObject
-from django.db.models import Q
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Object.UidTokenObject import UidTokenObject
 from Service.CommonService import CommonService
-from Service.ModelService import ModelService
-import boto3
-import botocore
-from botocore import client
-from Ansjer.config import PUSH_REDIS_ADDRESS
+from Service.EquipmentInfoService import EquipmentInfoService
 
 
 class DetectControllerViewV2(View):
@@ -288,24 +287,34 @@ class DetectControllerViewV2(View):
         if not region:
             return response.json(444, 'region')
         region = int(region)
-        now_time = int(time.time())
-
-        qs = Equipment_Info.objects.filter(userID_id=userID).order_by('-eventTime')
-        qs = qs.filter(eventTime__gt=now_time - 3600 * 168)
+        # now_time = int(time.time())
 
+        # qs = Equipment_Info.objects.filter(userID_id=userID).order_by('-eventTime')
+        # qs = qs.filter(eventTime__gt=now_time - 3600 * 168)
+        # 根据时间筛选消息推送
         if startTime and endTime:
-            qs = qs.filter(eventTime__range=(startTime, endTime))
-        if eventType:
-            if ',' in eventType:   #兼容AI查询
-                eventTypeList = eventType.split(',')
-                eventTypeList = [int(i.strip()) for i in eventTypeList]
-                qs = qs.filter(eventType__in=eventTypeList)
-            else:
-                qs = qs.filter(eventType=eventType)
+            qs, count = EquipmentInfoService.find_by_start_time_equipment_info(page, line, userID, startTime,
+                                                                               endTime, eventType,
+                                                                               request_dict.get('uids', None))
+
+        else:
+            # 默认查询近七天消息推送
+            qs, count = EquipmentInfoService.get_equipment_info_week_all(page, line, userID, startTime, endTime,
+                                                                         eventType,
+                                                                         request_dict.get('uids', None))
+        # if startTime and endTime:
+        #     qs = qs.filter(eventTime__range=(startTime, endTime))
+        # if eventType:
+        #     if ',' in eventType:  # 兼容AI查询
+        #         eventTypeList = eventType.split(',')
+        #         eventTypeList = [int(i.strip()) for i in eventTypeList]
+        #         qs = qs.filter(eventType__in=eventTypeList)
+        #     else:
+        #         qs = qs.filter(eventType=eventType)
         uids = request_dict.get('uids', None)
         if uids:
             uid_list = uids.split(',')
-            qs = qs.filter(devUid__in=uid_list)
+            # 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:
@@ -316,13 +325,14 @@ class DetectControllerViewV2(View):
             for dv in dvqs:
                 uid_type_dict[dv['UID']] = {'type': dv['Type'], 'NickName': dv['NickName']}
         # print(uid_type_dict)
-        if not qs.exists():
+        if not qs or count == 0 or not qs.exists():
             return response.json(0, {'datas': [], 'count': 0})
-        qs = qs.values('id', 'devUid', 'devNickName', 'Channel', 'eventType', 'status', 'alarm', 'eventTime',
-                       'receiveTime', 'is_st', 'addTime', 'storage_location', 'borderCoords')
+        # qs = qs.values('id', 'devUid', 'devNickName', 'Channel', 'eventType', 'status', 'alarm', 'eventTime',
+        #                'receiveTime', 'is_st', 'addTime', 'storage_location', 'borderCoords')
 
-        count = qs.count()
-        qr = qs[(page - 1) * line:page * line]
+        # count = qs.count()
+        # qr = qs[(page - 1) * line:page * line]
+        qr = qs
         res = []
         auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
         oss_img_bucket = oss2.Bucket(auth, 'oss-cn-shenzhen.aliyuncs.com', 'apg')
@@ -346,10 +356,10 @@ class DetectControllerViewV2(View):
             eventTime = p['eventTime']
             channel = p['Channel']
             storage_location = p['storage_location']
-            p['borderCoords'] = '' if p['borderCoords'] =='' else json.loads(p['borderCoords'])
+            p['borderCoords'] = '' if p['borderCoords'] == '' else json.loads(p['borderCoords'])
             if p['is_st'] == 1:
                 thumbspng = '{uid}/{channel}/{time}.jpeg'.format(uid=devUid, channel=p['Channel'], time=eventTime)
-                if storage_location == 1:   # oss
+                if storage_location == 1:  # oss
                     response_url = oss_img_bucket.sign_url('GET', thumbspng, 300)
                     p['img'] = response_url
                     p['img_list'] = [response_url]
@@ -359,9 +369,10 @@ class DetectControllerViewV2(View):
                                                                         ExpiresIn=300)
                     p['img'] = response_url
                     p['img_list'] = [response_url]
-                elif region == 1 and storage_location == 2:   # 1:国外,aws
+                elif region == 1 and storage_location == 2:  # 1:国外,aws
                     response_url = aws_s3_guowai.generate_presigned_url('get_object',
-                                                                        Params={'Bucket': 'foreignpush', 'Key': thumbspng},
+                                                                        Params={'Bucket': 'foreignpush',
+                                                                                'Key': thumbspng},
                                                                         ExpiresIn=300)
                     p['img'] = response_url
                     p['img_list'] = [response_url]
@@ -376,18 +387,21 @@ class DetectControllerViewV2(View):
                     endpoint = vodqs[0]['bucket__endpoint']
                     bucket = oss2.Bucket(auth, endpoint, bucket_name)
                     ts = '{uid}/vod{channel}/{etime}/ts0.ts'.format(uid=devUid, channel=p['Channel'], etime=eventTime)
-                    if storage_location == 1:   # oss
-                        thumb0 = bucket.sign_url('GET', ts, 3600, params={'x-oss-process': 'video/snapshot,t_0000,w_700'})
-                        thumb1 = bucket.sign_url('GET', ts, 3600, params={'x-oss-process': 'video/snapshot,t_1000,w_700'})
-                        thumb2 = bucket.sign_url('GET', ts, 3600, params={'x-oss-process': 'video/snapshot,t_2000,w_700'})
+                    if storage_location == 1:  # oss
+                        thumb0 = bucket.sign_url('GET', ts, 3600,
+                                                 params={'x-oss-process': 'video/snapshot,t_0000,w_700'})
+                        thumb1 = bucket.sign_url('GET', ts, 3600,
+                                                 params={'x-oss-process': 'video/snapshot,t_1000,w_700'})
+                        thumb2 = bucket.sign_url('GET', ts, 3600,
+                                                 params={'x-oss-process': 'video/snapshot,t_2000,w_700'})
                         # thumb3 = bucket.sign_url('GET', ts, 3600, params={'x-oss-process': 'video/snapshot,t_3000,w_700'})
                         p['img_list'] = [thumb0, thumb1, thumb2]
-                    elif region == 2 and storage_location == 2:     # 2:国内,aws
+                    elif region == 2 and storage_location == 2:  # 2:国内,aws
                         thumb = aws_s3_guonei.generate_presigned_url('get_object',
                                                                      Params={'Bucket': 'push', 'Key': ts},
                                                                      ExpiresIn=3600)
                         p['img_list'] = [thumb]
-                    elif region == 1 and storage_location == 2:   # 1:国外,aws
+                    elif region == 1 and storage_location == 2:  # 1:国外,aws
                         thumb = aws_s3_guowai.generate_presigned_url('get_object',
                                                                      Params={'Bucket': 'foreignpush', 'Key': ts},
                                                                      ExpiresIn=3600)
@@ -396,8 +410,9 @@ class DetectControllerViewV2(View):
                 # 列表装载回放时间戳标记
                 p['img_list'] = []
                 for i in range(p['is_st']):
-                    thumbspng = '{uid}/{channel}/{time}_{st}.jpeg'.format(uid=devUid, channel=p['Channel'], time=eventTime, st=i)
-                    if storage_location == 1:   # oss
+                    thumbspng = '{uid}/{channel}/{time}_{st}.jpeg'.format(uid=devUid, channel=p['Channel'],
+                                                                          time=eventTime, st=i)
+                    if storage_location == 1:  # oss
                         img = oss_img_bucket.sign_url('GET', thumbspng, 300)
                         p['img_list'].append(img)
                     elif region == 2 and storage_location == 2:  # 2:国内,aws
@@ -406,9 +421,10 @@ class DetectControllerViewV2(View):
                                                                             ExpiresIn=300)
                         img = response_url
                         p['img_list'].append(img)
-                    elif region == 1 and storage_location == 2:   # 1:国外,aws
+                    elif region == 1 and storage_location == 2:  # 1:国外,aws
                         response_url = aws_s3_guowai.generate_presigned_url('get_object',
-                                                                            Params={'Bucket': 'foreignpush', 'Key': thumbspng},
+                                                                            Params={'Bucket': 'foreignpush',
+                                                                                    'Key': thumbspng},
                                                                             ExpiresIn=300)
                         img = response_url
                         p['img_list'].append(img)
@@ -513,7 +529,8 @@ class NotificationView(View):
                 uid_push_qs = UidPushModel.objects.filter(uid_set__uid=uid, uid_set__detect_status=1). \
                     values('token_val', 'app_type', 'appBundleId', 'm_code',
                            'push_type', 'userID_id', 'userID__NickName',
-                           'lang', 'm_code', 'tz', 'uid_set__nickname', 'uid_set__detect_interval', 'uid_set__detect_group',
+                           'lang', 'm_code', 'tz', 'uid_set__nickname', 'uid_set__detect_interval',
+                           'uid_set__detect_group',
                            'uid_set__channel')
                 print(uid_push_qs)
                 # 新建一个list接收数据
@@ -528,8 +545,8 @@ class NotificationView(View):
                     return JsonResponse(status=200, data=res_data)
         else:
             # 从数据库查询出来
-            uid_push_qs = UidPushModel.objects.filter(uid_set__uid=uid,uid_set__detect_status=1). \
-                values('token_val', 'app_type', 'appBundleId','m_code',
+            uid_push_qs = UidPushModel.objects.filter(uid_set__uid=uid, uid_set__detect_status=1). \
+                values('token_val', 'app_type', 'appBundleId', 'm_code',
                        'push_type', 'userID_id', 'userID__NickName',
                        'lang', 'm_code', 'tz', 'uid_set__nickname', 'uid_set__detect_interval', 'uid_set__detect_group',
                        'uid_set__channel')
@@ -569,7 +586,7 @@ class NotificationView(View):
             else:
                 detect_med_type = 2  # 为2的话,既推送,又存库
                 # detect_group=0允许全部推送的时候
-                if detect_group == '0'or detect_group == '':
+                if detect_group == '0' or detect_group == '':
                     redisObj.set_data(key=dkey, val=1, expire=detect_interval)
                 else:
                     detect_group_list = detect_group.split(',')
@@ -579,7 +596,7 @@ class NotificationView(View):
                         redisObj.set_data(key=dkey, val=1, expire=detect_interval)
                 # 改为1秒
                 # 如果不是正式
-                if SERVER_TYPE!="Ansjer.formal_settings":
+                if SERVER_TYPE != "Ansjer.formal_settings":
                     redisObj.set_data(key=pkey, val=1, expire=10)
                 else:
                     redisObj.set_data(key=pkey, val=1, expire=60)
@@ -645,7 +662,7 @@ class NotificationView(View):
             kwag_args['msg_title'] = msg_title
             kwag_args['msg_text'] = msg_text
             push_server_status = 0
-            #推送
+            # 推送
             if detect_med_type == 2 or detect_med_type == 0:
                 if push_type == 0:  # ios apns
                     print('do_apns')
@@ -717,7 +734,7 @@ class NotificationView(View):
                 del up['uid_set__nickname']
                 del up['uid_set__detect_interval']
                 del up['uid_set__detect_group']
-            return JsonResponse(status=200, data={'code': 0, 'msg': 'success 0 or 2' ,'re_list':redis_list})
+            return JsonResponse(status=200, data={'code': 0, 'msg': 'success 0 or 2', 're_list': redis_list})
 
         elif is_st == '1':
             print("is_st=1")
@@ -735,7 +752,7 @@ class NotificationView(View):
                     },
                     ExpiresIn=3600
                 )
-            else:   # 1:国外
+            else:  # 1:国外
                 response_url = aws_s3_guowai.generate_presigned_url(
                     ClientMethod='put_object',
                     Params={
@@ -790,7 +807,7 @@ class NotificationView(View):
                         },
                         ExpiresIn=3600
                     )
-                else:   # 1:国外
+                else:  # 1:国外
                     response_url = aws_s3_guowai.generate_presigned_url(
                         ClientMethod='put_object',
                         Params={
@@ -826,7 +843,6 @@ class NotificationView(View):
                 res_data = {'code': 0, 'img_url_list': img_url_list, 'msg': 'success 3'}
             return JsonResponse(status=200, data=res_data)
 
-
     def get_msg_title(self, appBundleId, nickname):
         package_title_config = {
             'com.ansjer.customizedd_a': 'DVS',
@@ -853,7 +869,7 @@ class NotificationView(View):
         return False
 
     def get_msg_text(self, channel, n_time, lang, tz, event_type, is_sys=0):
-        n_date = CommonService.get_now_time_str(n_time=n_time, tz=tz,lang=lang)
+        n_date = CommonService.get_now_time_str(n_time=n_time, tz=tz, lang=lang)
         etype = int(event_type)
         if lang == 'cn':
             if etype == 704:
@@ -1036,7 +1052,7 @@ class PushNotificationView(View):
                 # 从数据库查询出来
                 uid_push_qs = UidPushModel.objects.filter(uid_set__uid=uid, uid_set__detect_status=1). \
                     values('token_val', 'app_type', 'appBundleId',
-                           'push_type', 'userID_id', 'lang','m_code',
+                           'push_type', 'userID_id', 'lang', 'm_code',
                            'tz', 'uid_set__nickname')
                 # 新建一个list接收数据
                 redis_list = []
@@ -1080,7 +1096,7 @@ class PushNotificationView(View):
                             },
                             ExpiresIn=3600
                         )
-                    else:   # 1:国外
+                    else:  # 1:国外
                         response_url = aws_s3_guowai.generate_presigned_url(
                             ClientMethod='put_object',
                             Params={
@@ -1113,7 +1129,7 @@ class PushNotificationView(View):
                                 },
                                 ExpiresIn=3600
                             )
-                        else:   # 1:国外
+                        else:  # 1:国外
                             response_url = aws_s3_guowai.generate_presigned_url(
                                 ClientMethod='put_object',
                                 Params={
@@ -1217,4 +1233,4 @@ class PushNotificationView(View):
             else:
                 send_text = '{msg_type} channel:{channel} date:{date}'. \
                     format(msg_type=msg_type, channel=channel, date=n_date)
-        return send_text
+        return send_text

+ 24 - 20
Controller/EquipmentInfo.py

@@ -1,21 +1,16 @@
 import time
 import traceback
 
-import oss2
-from django.db import connection, connections
 from django.utils.decorators import method_decorator
 from django.views.decorators.csrf import csrf_exempt
-from django.views.generic import TemplateView
 from django.views.generic.base import View
 
-from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET
-from Ansjer.config import SERVER_DOMAIN
-from Model.models import Device_Info, VodHlsModel, Equipment_Info
+from Model.models import Device_Info, Equipment_Info
 from Model.models import Device_User
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
-from Object.UidTokenObject import UidTokenObject
 from Service.CommonService import CommonService
+from Service.EquipmentInfoService import EquipmentInfoService
 from Service.ModelService import ModelService
 
 '''
@@ -149,16 +144,18 @@ class EquipmentInfo(View):
             res.append(p)
         return response.json(0, {'datas': res, 'count': count})
 
-
     def update_info(self, request_dict, userID, response):
         is_update_all = request_dict.get('is_update_all', 0)
         eventType = request_dict.get('eventType', None)
         if int(is_update_all) == 1:
             try:
-                eq = Equipment_Info.objects.filter(userID_id=userID)
-                if eventType:
-                    eq = eq.filter(eventType=int(eventType))
-                is_update = eq.update(status=1)
+                is_update = 0
+                for i in range(1, 8):
+                    eq_qs = EquipmentInfoService.get_equipment_info_model('', i)
+                    eq_qs = eq_qs.filter(device_user_id=userID)
+                    if eventType:
+                        eq_qs = eq_qs.filter(event_type=int(eventType))
+                    is_update += eq_qs.update(status=1)
                 return response.json(0, {'update_count': is_update})
             except Exception as e:
                 print(repr(e))
@@ -170,14 +167,18 @@ class EquipmentInfo(View):
             param_flag = CommonService.get_param_flag(data=[id_list])
             if param_flag is True:
                 count = 0
-                for id in id_list:
+                for ei_id in id_list:
                     try:
-                        eq = Equipment_Info.objects.filter(id=int(id))
+                        tab_val = int(ei_id[0:1])
+                        ei_id = int(ei_id[1:])
+                        eq = EquipmentInfoService.get_equipment_info_model('', tab_val)
+                        eq = eq.filter(id=ei_id)
                         if eq.exists():
-                            own_dev = ModelService.check_own_device(userID, eq[0].devUid)
+                            own_dev = ModelService.check_own_device(userID, eq[0].device_uid)
                             if own_dev is True:
                                 count += 1
                                 eq.update(status=1)
+
                     except Exception as e:
                         print(repr(e))
                 return response.json(0, {'update_success': count})
@@ -191,12 +192,16 @@ class EquipmentInfo(View):
         param_flag = CommonService.get_param_flag(data=[id_list])
         if param_flag is True:
             try:
-                for id in id_list:
-                    eq = Equipment_Info.objects.filter(id=id)
+                for ei_id in id_list:
+                    tab_val = int(ei_id[0:1])
+                    ei_id = int(ei_id[1:])
+                    eq = EquipmentInfoService.get_equipment_info_model('', tab_val)
+                    eq = eq.filter(id=ei_id)
                     if eq.exists():
-                        own_dev = ModelService.check_own_device(userID, eq[0].devUid)
+                        own_dev = ModelService.check_own_device(userID, eq[0].device_uid)
                         if own_dev is True:
                             eq.delete()
+
             except Exception as e:
                 errorInfo = traceback.format_exc()
                 print(errorInfo)
@@ -291,6 +296,7 @@ use information_schema;
 select concat(round(sum(data_length/1024/1024),2),'MB') as data from tables where table_schema='Ansjer81';
 '''
 
+
 # 按季度删除访问日志
 def deleteExpireEquipmentInfoById(request):
     response = ResponseObject()
@@ -301,5 +307,3 @@ def deleteExpireEquipmentInfoById(request):
 
     Equipment_Info.objects.filter(id__lte=id).delete()
     return response.json(0)
-
-

+ 11 - 5
Controller/EquipmentOTA.py

@@ -1,4 +1,7 @@
+import hashlib
 import os
+import uuid
+
 import simplejson as json
 import time
 from django.utils import timezone
@@ -311,14 +314,17 @@ class EquipmentVersionView(View):
             url = SERVER_DOMAIN + 'OTA/downloads/' + path
         elif file_path.find('static/otapack') != -1:
             file_path = file_path
+            param_url = "ansjer/" + CommonService.RandomStr(6) + "/" + file_path
+            data = {'Url': param_url, 'user_id': '', 'uid': uid, 'serial_number': '', 'old_version': ov,
+                    'new_version': eqs[0].softwareVersion, 'mci': 'NVR'}
+            dvr_ota_key = 'ASJ:SERVER:VERSION:{}'.format(uid)
+            dvr_ota_value = json.dumps(data)
+            expire = 3600 * 24 * 2 + 600
+            redisObject.set_data(dvr_ota_key, dvr_ota_value, expire)
             # 创建url的token
             tko = UrlTokenObject()
-            file_path = tko.generate(data={'Url': "ansjer/" + CommonService.RandomStr(6) + "/" + file_path})
-
+            file_path = tko.generate(data={'uid': uid})
             url = SERVER_DOMAIN + 'dlotapack/' + file_path
-        else:
-            return response.json(900, '2')
-        # http: // 192.168.136.39:8000 / EquipmentVersion / checkVer?code = 20D20410010
 
         res = {
             "url": url,

+ 1 - 3
Controller/OTAEquipment.py

@@ -555,7 +555,7 @@ def getNewVerInterface(request):
             redisObject.set_data(device_info_key, device_info_value, expire)
 
             url_tko = UrlTokenObject()
-            file_path = url_tko.generate(data={'Url': 'a', 'uid': str_uuid})
+            file_path = url_tko.generate(data={'uid': str_uuid})
 
             url = SERVER_DOMAIN + 'dlotapack/' + file_path
             logger.info('<<<<<<<URL={}'.format(url))
@@ -742,8 +742,6 @@ def downloadOTAInterfaceV2(request, fullPath, *callback_args, **callback_kwargs)
                     uid=uid,
                     mci=mci,
                 )
-                del_data = redis_object.del_data(device_key)
-                logger.info('删除缓存={}'.format(del_data))
                 return response
             except Exception as e:
                 return res.json(906, repr(e))

+ 23 - 161
Controller/PaymentCycle.py

@@ -174,17 +174,16 @@ class PaypalCycleNotify(View):
         order_list = order_qs.values("UID", "channel", "commodity_code", "rank", "isSelectDiscounts",
                                      "userID__userID",
                                      "userID__username", 'coupon_id')
+        if not orderID:
+            print("not orderID")
+            red_url = "{SERVER_DOMAIN_SSL}web/paid2/fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
+            if lang != 'cn':
+                red_url = "{SERVER_DOMAIN_SSL}web/paid2/en_fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
+            return HttpResponseRedirect(red_url)
+        UID = order_list[0]['UID']
         try:
-            if not orderID:
-                print("not orderID")
-                red_url = "{SERVER_DOMAIN_SSL}web/paid2/fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
-                if lang != 'cn':
-                    red_url = "{SERVER_DOMAIN_SSL}web/paid2/en_fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
-                return HttpResponseRedirect(red_url)
-
             userid = order_list[0]['userID__userID']
             username = order_list[0]['userID__username']
-            UID = order_list[0]['UID']
             channel = order_list[0]['channel']
             rank = order_list[0]['rank']
             smqs = Store_Meal.objects.filter(id=rank). \
@@ -271,10 +270,12 @@ class PaypalCycleNotify(View):
                 red_url = "{SERVER_DOMAIN_SSL}web/paid2/success.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
                 if lang != 'cn':
                     red_url = "{SERVER_DOMAIN_SSL}web/paid2/en_success.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
+                logger.info('{UID}成功开通paypal自动续费:----'.format(UID=UID))
                 return HttpResponseRedirect(red_url)
         except Exception as e:
             print(repr(e))
             logger.info('do_paypal_cycle_return支付失败:----')
+            logger.info('{UID}开通paypal自动续费失败'.format(UID=UID))
             logger.info("错误行数:{errLine}".format(errLine=e.__traceback__.tb_lineno))
             logger.info(repr(e))
             if order_qs:
@@ -345,7 +346,7 @@ class PaypalCycleNotify(View):
                     oldOrderID = billing_agreement.description
                     order_qs = Order_Model.objects.filter(orderID=oldOrderID, status=1)
                     if not order_qs:
-                        return HttpResponse('fail')
+                        return HttpResponse('fail', status=500)
                     order_list = order_qs.values("UID", "channel", "commodity_code", "rank", "isSelectDiscounts",
                                                  "userID__userID","uid_bucket_id",
                                                  "userID__username",'plan_id','addTime','desc','payType','currency','commodity_type','updTime')
@@ -365,7 +366,7 @@ class PaypalCycleNotify(View):
                         values("day", "bucket_id", "bucket__storeDay", "expire")
                     bucketId = smqs[0]['bucket_id']
                     if not smqs.exists():
-                        return HttpResponse('fail')
+                        return HttpResponse('fail', status=500)
                     # ##
                     ubqs = UID_Bucket.objects.filter(uid=UID).values("id", "bucket_id", "bucket__storeDay",
                                                                      "bucket__region",
@@ -458,7 +459,7 @@ class PaypalCycleNotify(View):
                             }
                         ]
                         billing_agreement.replace(billing_agreement_update_attributes)
-
+                        logger.info('{UID}成功续费paypal:----'.format(UID=UID))
                         return HttpResponse('success')
                 except Exception as e:
                     print(e)
@@ -467,162 +468,23 @@ class PaypalCycleNotify(View):
                     logger.info('do_paypal_webhook_notify支付失败:----')
                     logger.info("错误行数:{errLine}".format(errLine=e.__traceback__.tb_lineno))
                     logger.info(repr(e))
-                    return HttpResponse('fail')
+                    return HttpResponse('fail', status=500)
         return HttpResponse('fail')
 
 
     def do_test(self, request_dict, request, response):
-        paypalrestsdk.configure(PAYPAL_CRD)
-        billing_agreement = paypalrestsdk.BillingAgreement
-        billing_agreement = billing_agreement.find("I-17SRPP7TS71U")
-        print("Got Billing Agreement Details for Billing Agreement[%s]" % (
-            billing_agreement.id))
-        exit(billing_agreement)
-        #normal_pay
-        # json_str = '{"id":"WH-8SU832847J141682K-0FF265943E8692615","event_version":"1.0","create_time":"2022-01-10T06:31:49.863Z","resource_type":"sale","event_type":"PAYMENT.SALE.COMPLETED","summary":"Payment completed for $ 0.02 USD","resource":{"amount":{"total":"0.02","currency":"USD","details":{"subtotal":"0.02"}},"payment_mode":"INSTANT_TRANSFER","create_time":"2022-01-10T06:31:45Z","transaction_fee":{"currency":"USD","value":"0.02"},"parent_payment":"PAYID-MHN5E5Y1RH70069CT417990V","update_time":"2022-01-10T06:31:45Z","protection_eligibility_type":"ITEM_NOT_RECEIVED_ELIGIBLE,UNAUTHORIZED_PAYMENT_ELIGIBLE","application_context":{"related_qualifiers":[{"id":"0FJ93448LU7282046","type":"CART"}]},"protection_eligibility":"ELIGIBLE","links":[{"method":"GET","rel":"self","href":"https://api.sandbox.paypal.com/v1/payments/sale/6N498138TH641260G"},{"method":"POST","rel":"refund","href":"https://api.sandbox.paypal.com/v1/payments/sale/6N498138TH641260G/refund"},{"method":"GET","rel":"parent_payment","href":"https://api.sandbox.paypal.com/v1/payments/payment/PAYID-MHN5E5Y1RH70069CT417990V"}],"id":"6N498138TH641260G","state":"completed","invoice_number":""},"links":[{"href":"https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-8SU832847J141682K-0FF265943E8692615","rel":"self","method":"GET"},{"href":"https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-8SU832847J141682K-0FF265943E8692615/resend","rel":"resend","method":"POST"}]}'
-        json_agreement_str = '{"id":"WH-9BE23393R5338163R-48P08088YL173821A","event_version":"1.0","create_time":"2022-01-10T10:27:42.925Z","resource_type":"sale","event_type":"PAYMENT.SALE.COMPLETED","summary":"Payment completed for $ 0.02 USD","resource":{"billing_agreement_id":"I-K8PCK2NJC6N6","amount":{"total":"0.02","currency":"USD","details":{"subtotal":"0.02"}},"payment_mode":"INSTANT_TRANSFER","update_time":"2022-01-10T10:27:19Z","create_time":"2022-01-10T10:27:19Z","protection_eligibility_type":"ITEM_NOT_RECEIVED_ELIGIBLE,UNAUTHORIZED_PAYMENT_ELIGIBLE","transaction_fee":{"currency":"USD","value":"0.02"},"protection_eligibility":"ELIGIBLE","links":[{"method":"GET","rel":"self","href":"https://api.sandbox.paypal.com/v1/payments/sale/4H259512Y67055105"},{"method":"POST","rel":"refund","href":"https://api.sandbox.paypal.com/v1/payments/sale/4H259512Y67055105/refund"}],"id":"4H259512Y67055105","state":"completed","invoice_number":""},"links":[{"href":"https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-9BE23393R5338163R-48P08088YL173821A","rel":"self","method":"GET"},{"href":"https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-9BE23393R5338163R-48P08088YL173821A/resend","rel":"resend","method":"POST"}]}'
-        header = {'wsgi.file_wrapper': '<class gunicorn.http.wsgi.FileWrapper>', 'wsgi.version': '(1, 0)', 'HTTP_CONNECTION': 'close', 'wsgi.url_scheme': 'http', 'HTTP_PAYPAL_CERT_URL': 'https://api.sandbox.paypal.com/v1/notifications/certs/CERT-360caa42-fca2a594-7a8abba8', 'HTTP_PAYPAL_TRANSMISSION_ID': '022fbbc0-7139-11ec-afa1-0114a54fc1fc', 'SERVER_NAME': '0.0.0.0', 'HTTP_CORRELATION_ID': 'be4c80f0a6c05', 'REMOTE_ADDR': '127.0.0.1', 'HTTP_PAYPAL_TRANSMISSION_SIG': 'IM3Xwyjw5YUgBKPsgyjPdMAh6DSFTtqdwy8zbJBXBhFyB77B6mEqnRfhtEgwwBhag6HsStmKBGIScFhs5Nuraru7DbT4+7Tu5fNx3oQIHeHtR/FYZoQcv86bjZ9cq+Xo04HmhUfgBAsSetS+CuY5TsN60d1m8Hld1MTDjk1UuSbk8HA3dBLiMzWT7wUw3/SUau/C7TtLnWGmdJlkFne+b/5s0+HsuXn3wQQCDIHO0sBMBo72NdlyMlLIunSdoEJ61pKi2U1jQ6qqe/59IrY2q4ufx9D6JZ4bUB6z3NQZ+Gm7zrlKabT6HkVovLJbuBgRgRWWUoY02CuVXZ9w4AzVNQ==', 'REMOTE_PORT': '58060', 'HTTP_ACCEPT': '*/*', 'CONTENT_TYPE': 'application/json', 'HTTP_USER_AGENT': 'PayPal/AUHR-214.0-56015767', 'SCRIPT_NAME': '', 'HTTP_X_FORWARDED_FOR': '173.0.80.117', 'HTTP_HOST': 'test.zositechc.cn:443', 'wsgi.multiprocess': True, 'SERVER_PROTOCOL': 'HTTP/1.0', 'PATH_INFO': '/payCycle/paypalCycleNotify', 'SERVER_SOFTWARE': 'gunicorn/19.7.1', 'wsgi.input': '<gunicorn.http.body.Body object at 0x7fb966cddfd0>', 'REQUEST_METHOD': 'POST', 'wsgi.errors': '<gunicorn.http.wsgi.WSGIErrorsWrapper object at 0x7fb966cdda90>', 'CONTENT_LENGTH': '1226', 'wsgi.run_once': False, 'HTTP_X_B3_SPANID': 'e8ede80526720f95', 'HTTP_PAYPAL_AUTH_ALGO': 'SHA256withRSA', 'QUERY_STRING': '', 'HTTP_PAYPAL_TRANSMISSION_TIME': '2022-01-09T10:43:40Z', 'wsgi.multithread': False, 'HTTP_HTTP_X_FORWARDED_FOR': '173.0.80.117', 'HTTP_X_REAL_IP': '173.0.80.117', 'RAW_URI': '/payCycle/paypalCycleNotify', 'HTTP_PAYPAL_AUTH_VERSION': 'v2', 'gunicorn.socket': '<socket.socket fd=51, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=(127.0.0.1, 8082), raddr=(127.0.0.1, 58060)>', 'SERVER_PORT': '8082'}
-
-
+        logger = logging.getLogger('info')
+        logger.info('---into---webhook_notify--------')
+        logger.info('---request_dict-------')
+        logger.info(request_dict)
+        json_agreement_str = request.body.decode("utf-8")
         json_obj = json.loads(json_agreement_str)
+        header = request.META
         paypal_body = json_obj.get('resource')
-        billing_agreement_id = paypal_body.get('billing_agreement_id')
-        amount = paypal_body.get('amount')
-        if not billing_agreement_id:
-            return HttpResponse('success')
-
-        nowTime = int(time.time())
-        transmission_id = header.get('HTTP_PAYPAL_TRANSMISSION_ID',None)
-        transmission_time = header.get('HTTP_PAYPAL_TRANSMISSION_TIME',None)
-        webhook_id = '6TS30758D98835230'
-        cert_url = header.get('HTTP_PAYPAL_CERT_URL',None)
-        transmission_sig = header.get('HTTP_PAYPAL_TRANSMISSION_SIG',None)
-        auth_algo = header.get('HTTP_PAYPAL_AUTH_ALGO',None)
-        resource_type = json_obj.get('resource_type')
-        # return HttpResponse(resource_type)
-
-
-        transmission_id = 'f42509f0-71ff-11ec-a473-05e6d85b61e7'
-        transmission_time = '2022-01-10T10:27:46Z'
-        webhook_id = '3J888119TD851704M'
-        cert_url = 'https://api.sandbox.paypal.com/v1/notifications/certs/CERT-360caa42-fca2a594-7a8abba8'
-        transmission_sig = 'R6sBDhsoq5+FRQHWe+8tSeKJMlRDnt9F2SlWlWVVEfDu9mvQ0zKl74bwcN1zMbvH4o7fWVNbwkcPW70/t4O0YBsj9BcMwL8hDxcuWuHp20RBzaI2dlBpdPEke19wr/fhJKGZCDYuvptV2RJGCSePBn3gKs7hkY5ribELPDqHuajlgVxMmoXm/+CHrMmPo6gSGgTuEMzEn4/ENuj3uJoCkcYqsFx3tUHg6eakUvQ+vYAyflRx9hX7QXEQHp15PWLgGzHkm9zGmnX6YoG5keo5MbJEYh9LfHJjmHmHVErvOtHebJxfTEDZwGoqw+WHr3KqnP4L1gaUj7XIXsQzbiFTBg=='
-        auth_algo = 'SHA256withRSA'
-        resource_type = 'sale'
-        self.get_plan_desc('P-4CG284532S612303METMEINY')
-        if resource_type == 'sale' and paypal_body.get('state') == 'completed':
-            # paypalrestsdk.configure(PAYPAL_CRD)
-            # response = paypalrestsdk.WebhookEvent.verify(
-            #     transmission_id, transmission_time, webhook_id, json_agreement_str, cert_url, transmission_sig, auth_algo)
-            response = True
-            if response:
-                try:
-                    agreement_id = paypal_body.get('billing_agreement_id')
-                    order_qs = Order_Model.objects.filter(agreement_id=agreement_id, status=1)
-                    if not order_qs:
-                        return HttpResponse('failss')
-                    order_list = order_qs.values("UID", "channel", "commodity_code", "rank", "isSelectDiscounts",
-                                                 "userID__userID","uid_bucket_id",
-                                                 "userID__username",'plan_id','addTime','desc','payType','currency','commodity_type')
-                    plan_id = order_list[0]['plan_id']
-                    # plan_cycle = self.get_plan_desc(plan_id)
-                    # 订阅续费订单(如果查到的本地订单已经付过了且包中的完成周期数`不是0, 则说明是续费订单, 本地可以新建一个订单标记是续费的)
-                    nowTime = int(time.time())
-                    if(order_list[0]['addTime']+600 > nowTime):
-                        return HttpResponse('success')
-
-                    userid = order_list[0]['userID__userID']
-                    username = order_list[0]['userID__username']
-                    UID = order_list[0]['UID']
-                    channel = order_list[0]['channel']
-                    rank = order_list[0]['rank']
-                    smqs = Store_Meal.objects.filter(id=rank). \
-                        values("day", "bucket_id", "bucket__storeDay", "expire")
-                    bucketId = smqs[0]['bucket_id']
-                    if not smqs.exists():
-                        return HttpResponse('fail')
-                    # ##
-                    ubqs = UID_Bucket.objects.filter(uid=UID).values("id", "bucket_id", "bucket__storeDay",
-                                                                     "bucket__region",
-                                                                     "endTime", "use_status")
-                    expire = smqs[0]['expire']
-
-                    # if order_list[0]['isSelectDiscounts'] == 1:
-                    #     expire = smqs[0]['expire'] * 2
-                    # 是否有促销
-                    # nowTime = int(time.time())
-                    # promotion = PromotionRuleModel.objects.filter(status=1, startTime__lte=nowTime,
-                    #                                               endTime__gte=nowTime).values('id', 'ruleConfig')
-                    # if promotion.exists():
-                    #     promotion_rule_id = promotion[0]['id']
-                    #     expire = expire * 2
-                    with transaction.atomic():
-                        if ubqs.exists():
-                            ubq = ubqs[0]
-                            if ubq['use_status'] == 1 and ubq['bucket_id'] == bucketId:  # 套餐使用中并且相同套餐叠加过期时间
-                                endTime = CommonService.calcMonthLater(expire, ubq['endTime'])
-                                UID_Bucket.objects.filter(id=ubq['id']).update \
-                                    (uid=UID, channel=channel, bucket_id=bucketId,
-                                     endTime=endTime, updateTime=nowTime)
-                            else:  # 已过期或者不相同的套餐加入未使用的关联套餐表
-                                has_unused = Unused_Uid_Meal.objects.filter(uid=UID, bucket_id=bucketId).values("id")
-                                # nums = 2 if order_list[0]['isSelectDiscounts'] == 1 else 1
-                                # if promotion.exists():
-                                nums = 1
-                                if has_unused.exists():
-                                    Unused_Uid_Meal.objects.filter(id=has_unused[0]['id']).update(num=F('num') + nums)
-                                else:
-                                    Unused_Uid_Meal.objects.create(uid=UID, channel=channel, addTime=nowTime, num=nums,
-                                                                   expire=smqs[0]['expire'], bucket_id=bucketId)
-                                UID_Bucket.objects.filter(id=ubq['id']).update(has_unused=1)
-                            uid_bucket_id = ubq['id']
-                        else:
-                            endTime = CommonService.calcMonthLater(expire)
-                            ub_cqs = UID_Bucket.objects.create \
-                                (uid=UID, channel=channel, bucket_id=bucketId, endTime=endTime, addTime=nowTime,
-                                 updateTime=nowTime, use_status=1)
-                            uid_bucket_id = ub_cqs.id
-
-                        dvq = Device_Info.objects.filter(UID=UID, vodPrimaryUserID='', vodPrimaryMaster='')
-                        if dvq.exists():
-                            dvq_set_update_dict = {
-                                'vodPrimaryUserID': userid,
-                                'vodPrimaryMaster': username
-                            }
-                            dvq.update(**dvq_set_update_dict)
-
-                        # uid_main_exist = UIDMainUser.objects.filter(UID=UID)
-                        # if not uid_main_exist.exists():
-                        #     uid_main_dict = {
-                        #         'UID': UID,
-                        #         'user_id': userid
-                        #     }
-                        #     UIDMainUser.objects.create(**uid_main_dict)
-                        orderID = CommonService.createOrderID()
-                        Order_Model.objects.create(orderID=orderID, UID=UID, channel=channel, userID_id=userid,
-                                                   desc=order_list[0]['desc'], payType=order_list[0]['payType'], payTime=nowTime,
-                                                   price=amount.get('total'), currency=order_list[0]['currency'], addTime=nowTime, updTime=nowTime,
-                                                   pay_url='', isSelectDiscounts=0,
-                                                   commodity_code=order_list[0]['commodity_code'], commodity_type=order_list[0]['commodity_type'],
-                                                   rank_id=rank, paymentID='', coupon_id='',uid_bucket_id=uid_bucket_id,status=1,agreement_id=agreement_id,plan_id=order_list[0]['plan_id'])
-                        # 如果存在序列号,消息提示用序列号
-                        device_name = CommonService.query_serial_with_uid(uid=UID)
-                        datetime = time.strftime("%Y-%m-%d", time.localtime())
-                        sys_msg_text_list = ['温馨提示:尊敬的客户,您的' + device_name + '设备在' + datetime + '已成功续订云存套餐',
-                                             'Dear customer,you already subscribed the cloud storage package successfully for device ' + device_name + ' on ' + time.strftime(
-                                                 "%b %dth,%Y", time.localtime())]
-
-                        if order_list[0]['payType'] == 1:
-                            lang = 'en'
-                        else:
-                            lang = 'cn'
-                        CloudStorage.CloudStorageView().do_vod_msg_Notice(UID, channel, userid, lang,
-                                                                        sys_msg_text_list, 'SMS_219738485')
-                        return HttpResponse('success')
-                except Exception as e:
-                    print(e)
-                    return HttpResponse('fail')
-        return HttpResponse('fail')
+        logger.info('-----paypal_body------')
+        logger.info(paypal_body)
+        logger.info('-----paypal_header------')
+        logger.info(header)
 
 
     def get_plan_desc(self,plan_id):

+ 5 - 2
Controller/SerialNumberController.py

@@ -20,6 +20,7 @@ from Object.TokenObject import TokenObject
 from Service.AlgorithmService import AlgorithmBaseOn35
 from Service.CommonService import CommonService
 from Ansjer.config import CRCKey, SERVER_TYPE, SERVER_DOMAIN_US, SERVER_DOMAIN_CN
+from Service.EquipmentInfoService import EquipmentInfoService
 from Service.ModelService import ModelService
 from Object.AWS.S3Email import S3Email
 
@@ -337,8 +338,10 @@ class SerialNumberView(View):
                 Device_Info.objects.filter(UID=uid).delete()
                 UidSetModel.objects.filter(uid=uid).delete()
                 UidUserModel.objects.filter(UID=uid).delete()
-                Equipment_Info.objects.filter(devUid=uid).delete()
                 iotdeviceInfoModel.objects.filter(serial_number=serial).delete()
+                # 删除推送消息
+                for val in range(1, 8):
+                    EquipmentInfoService.get_equipment_info_model('', val).filter(device_uid=uid).delete()
 
                 # 重置设备云存
                 UID_Bucket.objects.filter(uid=uid).delete()
@@ -355,7 +358,7 @@ class SerialNumberView(View):
                 except AssertionError:
                     return response.json(378)
 
-                UIDModel.objects.filter(uid=uid).update(status=0, mac='')    # 重置uid的使用状态为未分配
+                UIDModel.objects.filter(uid=uid).update(status=0, mac='')    # 重置uid的使用状态为未使用
                 uid_serial.delete()
 
                 # 记录操作日志

+ 21 - 5
Controller/SysManage.py

@@ -19,10 +19,10 @@ from django.views.decorators.csrf import csrf_exempt
 from django.views.generic.base import View
 
 from Ansjer.config import BASE_DIR
+from Model.models import SysMsgModel, Device_Info, Ai_Push_Info
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Service.ModelService import ModelService
-from Model.models import SysMsgModel, Equipment_Info, Device_Info, Ai_Push_Info
 
 
 @csrf_exempt
@@ -90,6 +90,9 @@ class getStatView(View):
             return response.json(907)
 
 
+from Service.EquipmentInfoService import EquipmentInfoService
+
+
 def initMsgFunc(request):
     response = ResponseObject()
     request.encoding = 'utf-8'
@@ -104,10 +107,23 @@ def initMsgFunc(request):
     response.lang = tko.lang
     if tko.code == 0:
         userID = tko.userID
-        seven_days_ago = int(time.time()) - 3600 * 24 * 7   # 过滤七天前数据
+        seven_days_ago = int(time.time()) - 3600 * 24 * 7  # 过滤七天前数据
+        sm_count = SysMsgModel.objects.filter(userID_id=userID, status=0).count()
+        # eq_count = Equipment_Info.objects.filter(userID_id=userID, eventTime__gt=seven_days_ago, status=False).count()
+        # rq_count = Equipment_Info.objects.filter(userID_id=userID, eventTime__gt=seven_days_ago, eventType=57,
+        # status=False).count()
         sm_count = SysMsgModel.objects.filter(userID_id=userID, status=0).count()
-        eq_count = Equipment_Info.objects.filter(userID_id=userID, eventTime__gt=seven_days_ago, status=False).count()
-        rq_count = Equipment_Info.objects.filter(userID_id=userID, eventTime__gt=seven_days_ago, eventType=57, status=False).count()
+        # eq_count = Equipment_Info.objects.filter(userID_id=userID, eventTime__gt=seven_days_ago, status=False).count()
+        # rq_count = Equipment_Info.objects.filter(userID_id=userID, eventTime__gt=seven_days_ago, eventType=57,
+        # status=False).count()
+        eq_count = 0
+        rq_count = 0
+        for i in range(1, 8):
+            eq_qs = EquipmentInfoService.get_equipment_info_model('', i)
+            eq_qs = eq_qs.filter(device_user_id=userID, event_time__gt=seven_days_ago, status=False)
+            if eq_qs.exists():
+                eq_count += eq_qs.count()
+                rq_count += eq_qs.filter(event_type=57).count()
         ai_count = Ai_Push_Info.objects.filter(userID_id=userID, eventTime__gt=seven_days_ago, status=False).count()
         uid_reset_count = Device_Info.objects.filter(userID_id=userID, isExist=2).count()
         res = {
@@ -115,7 +131,7 @@ def initMsgFunc(request):
             'eq_count': eq_count,  # 未读消息总数
             'rq_count': rq_count,  # 人形检测总数
             'ai_count': ai_count,  # AI消息总数
-            'uid_reset_count': uid_reset_count,# 复位的设备数量
+            'uid_reset_count': uid_reset_count,  # 复位的设备数量
         }
         return response.json(0, res)
     else:

+ 220 - 2
Model/models.py

@@ -340,6 +340,224 @@ class Equipment_Info(models.Model):
         ordering = ('-id',)
         app_label = "PushModel"
 
+
+class EquipmentInfoMonday(models.Model):
+    id = models.BigAutoField(primary_key=True, verbose_name=u'自增标记ID')
+    device_user_id = models.CharField(default='', db_index=True, blank=True, max_length=32, verbose_name=u'用户id')
+    device_uid = models.CharField(default='', db_index=True, blank=True, max_length=32, verbose_name=u'设备uid')
+    device_nick_name = models.CharField(blank=True, max_length=32, default='', verbose_name=u'设备昵称')
+    channel = models.IntegerField(default=1, blank=True, verbose_name=u'设备通道')
+    event_type = models.IntegerField(default=0, blank=True,
+                                     verbose_name=u'事件类型(0:代表空字符,1:ai人,2:ai动物,3:车,123:组合类型(人/车/动物),51:移动侦测,'
+                                                  u'52:传感器报警,53:影像遗失,54:PIR,55:门磁报警, 56:外部发报, 57:人型报警,'
+                                                  u'702:摄像头休眠,703:摄像头唤醒,'
+                                                  u'704:电量过低)')
+    status = models.BooleanField(blank=True, default=False, verbose_name=u'事件状态(0,1)')
+    alarm = models.CharField(blank=True, max_length=256, verbose_name=u'报警信息')
+    event_time = models.CharField(blank=True, db_index=True, default='', max_length=16, verbose_name=u'设备报警时间')
+    receive_time = models.CharField(blank=True, default='', max_length=16, verbose_name=u'接收到报警时间')
+    is_st = models.SmallIntegerField(default=0, verbose_name='是否截图(0:否,1:图片,2:视频)')  # 0 否,1 是图,2,视频
+    storage_location = models.SmallIntegerField(default=1, verbose_name='数据信息存储位置。1:阿里云oss,2:aws')
+    border_coords = models.TextField(default='', blank=True, verbose_name=u'ai类型图片边框位置信息')
+    add_time = models.IntegerField(verbose_name='添加时间', db_index=True, default=0)
+
+    def __str__(self):
+        return self.id
+
+    class Meta:
+        db_table = 'equipment_info_monday'
+        verbose_name = u'星期一设备信息推送表'
+        verbose_name_plural = verbose_name
+        ordering = ('-id',)
+        app_label = "PushModel"
+
+
+class EquipmentInfoTuesday(models.Model):
+    id = models.BigAutoField(primary_key=True, verbose_name=u'自增标记ID')
+    device_user_id = models.CharField(default='', db_index=True, blank=True, max_length=32, verbose_name=u'用户id')
+    device_uid = models.CharField(default='', db_index=True, blank=True, max_length=32, verbose_name=u'设备uid')
+    device_nick_name = models.CharField(blank=True, max_length=32, default='', verbose_name=u'设备昵称')
+    channel = models.IntegerField(default=1, blank=True, verbose_name=u'设备通道')
+    event_type = models.IntegerField(default=0, blank=True,
+                                     verbose_name=u'事件类型(0:代表空字符,1:ai人,2:ai动物,3:车,123:组合类型(人/车/动物),51:移动侦测,'
+                                                  u'52:传感器报警,53:影像遗失,54:PIR,55:门磁报警, 56:外部发报, 57:人型报警,'
+                                                  u'702:摄像头休眠,703:摄像头唤醒,'
+                                                  u'704:电量过低)')
+    status = models.BooleanField(blank=True, default=False, verbose_name=u'事件状态(0,1)')
+    alarm = models.CharField(blank=True, max_length=256, verbose_name=u'报警信息')
+    event_time = models.CharField(blank=True, db_index=True, default='', max_length=16, verbose_name=u'设备报警时间')
+    receive_time = models.CharField(blank=True, default='', max_length=16, verbose_name=u'接收到报警时间')
+    is_st = models.SmallIntegerField(default=0, verbose_name='是否截图(0:否,1:图片,2:视频)')  # 0 否,1 是图,2,视频
+    storage_location = models.SmallIntegerField(default=1, verbose_name='数据信息存储位置。1:阿里云oss,2:aws')
+    border_coords = models.TextField(default='', blank=True, verbose_name=u'ai类型图片边框位置信息')
+    add_time = models.IntegerField(verbose_name='添加时间', db_index=True, default=0)
+
+    def __str__(self):
+        return self.id
+
+    class Meta:
+        db_table = 'equipment_info_tuesday'
+        verbose_name = u'星期二设备信息推送表'
+        verbose_name_plural = verbose_name
+        ordering = ('-id',)
+        app_label = "PushModel"
+
+
+class EquipmentInfoWednesday(models.Model):
+    id = models.BigAutoField(primary_key=True, verbose_name=u'自增标记ID')
+    device_user_id = models.CharField(default='', db_index=True, blank=True, max_length=32, verbose_name=u'用户id')
+    device_uid = models.CharField(default='', db_index=True, blank=True, max_length=32, verbose_name=u'设备uid')
+    device_nick_name = models.CharField(blank=True, max_length=32, default='', verbose_name=u'设备昵称')
+    channel = models.IntegerField(default=1, blank=True, verbose_name=u'设备通道')
+    event_type = models.IntegerField(default=0, blank=True,
+                                     verbose_name=u'事件类型(0:代表空字符,1:ai人,2:ai动物,3:车,123:组合类型(人/车/动物),51:移动侦测,'
+                                                  u'52:传感器报警,53:影像遗失,54:PIR,55:门磁报警, 56:外部发报, 57:人型报警,'
+                                                  u'702:摄像头休眠,703:摄像头唤醒,'
+                                                  u'704:电量过低)')
+    status = models.BooleanField(blank=True, default=False, verbose_name=u'事件状态(0,1)')
+    alarm = models.CharField(blank=True, max_length=256, verbose_name=u'报警信息')
+    event_time = models.CharField(blank=True, db_index=True, default='', max_length=16, verbose_name=u'设备报警时间')
+    receive_time = models.CharField(blank=True, default='', max_length=16, verbose_name=u'接收到报警时间')
+    is_st = models.SmallIntegerField(default=0, verbose_name='是否截图(0:否,1:图片,2:视频)')  # 0 否,1 是图,2,视频
+    storage_location = models.SmallIntegerField(default=1, verbose_name='数据信息存储位置。1:阿里云oss,2:aws')
+    border_coords = models.TextField(default='', blank=True, verbose_name=u'ai类型图片边框位置信息')
+    add_time = models.IntegerField(verbose_name='添加时间', db_index=True, default=0)
+
+    def __str__(self):
+        return self.id
+
+    class Meta:
+        db_table = 'equipment_info_wednesday'
+        verbose_name = u'星期三设备信息推送表'
+        verbose_name_plural = verbose_name
+        ordering = ('-id',)
+        app_label = "PushModel"
+
+
+class EquipmentInfoThursday(models.Model):
+    id = models.BigAutoField(primary_key=True, verbose_name=u'自增标记ID')
+    device_user_id = models.CharField(default='', db_index=True, blank=True, max_length=32, verbose_name=u'用户id')
+    device_uid = models.CharField(default='', db_index=True, blank=True, max_length=32, verbose_name=u'设备uid')
+    device_nick_name = models.CharField(blank=True, max_length=32, default='', verbose_name=u'设备昵称')
+    channel = models.IntegerField(default=1, blank=True, verbose_name=u'设备通道')
+    event_type = models.IntegerField(default=0, blank=True,
+                                     verbose_name=u'事件类型(0:代表空字符,1:ai人,2:ai动物,3:车,123:组合类型(人/车/动物),51:移动侦测,'
+                                                  u'52:传感器报警,53:影像遗失,54:PIR,55:门磁报警, 56:外部发报, 57:人型报警,'
+                                                  u'702:摄像头休眠,703:摄像头唤醒,'
+                                                  u'704:电量过低)')
+    status = models.BooleanField(blank=True, default=False, verbose_name=u'事件状态(0,1)')
+    alarm = models.CharField(blank=True, max_length=256, verbose_name=u'报警信息')
+    event_time = models.CharField(blank=True, db_index=True, default='', max_length=16, verbose_name=u'设备报警时间')
+    receive_time = models.CharField(blank=True, default='', max_length=16, verbose_name=u'接收到报警时间')
+    is_st = models.SmallIntegerField(default=0, verbose_name='是否截图(0:否,1:图片,2:视频)')  # 0 否,1 是图,2,视频
+    storage_location = models.SmallIntegerField(default=1, verbose_name='数据信息存储位置。1:阿里云oss,2:aws')
+    border_coords = models.TextField(default='', blank=True, verbose_name=u'ai类型图片边框位置信息')
+    add_time = models.IntegerField(verbose_name='添加时间', db_index=True, default=0)
+
+    def __str__(self):
+        return self.id
+
+    class Meta:
+        db_table = 'equipment_info_thursday'
+        verbose_name = u'星期四设备信息推送表'
+        verbose_name_plural = verbose_name
+        ordering = ('-id',)
+        app_label = "PushModel"
+
+
+class EquipmentInfoFriday(models.Model):
+    id = models.BigAutoField(primary_key=True, verbose_name=u'自增标记ID')
+    device_user_id = models.CharField(default='', db_index=True, blank=True, max_length=32, verbose_name=u'用户id')
+    device_uid = models.CharField(default='', db_index=True, blank=True, max_length=32, verbose_name=u'设备uid')
+    device_nick_name = models.CharField(blank=True, max_length=32, default='', verbose_name=u'设备昵称')
+    channel = models.IntegerField(default=1, blank=True, verbose_name=u'设备通道')
+    event_type = models.IntegerField(default=0, blank=True,
+                                     verbose_name=u'事件类型(0:代表空字符,1:ai人,2:ai动物,3:车,123:组合类型(人/车/动物),51:移动侦测,'
+                                                  u'52:传感器报警,53:影像遗失,54:PIR,55:门磁报警, 56:外部发报, 57:人型报警,'
+                                                  u'702:摄像头休眠,703:摄像头唤醒,'
+                                                  u'704:电量过低)')
+    status = models.BooleanField(blank=True, default=False, verbose_name=u'事件状态(0,1)')
+    alarm = models.CharField(blank=True, max_length=256, verbose_name=u'报警信息')
+    event_time = models.CharField(blank=True, db_index=True, default='', max_length=16, verbose_name=u'设备报警时间')
+    receive_time = models.CharField(blank=True, default='', max_length=16, verbose_name=u'接收到报警时间')
+    is_st = models.SmallIntegerField(default=0, verbose_name='是否截图(0:否,1:图片,2:视频)')  # 0 否,1 是图,2,视频
+    storage_location = models.SmallIntegerField(default=1, verbose_name='数据信息存储位置。1:阿里云oss,2:aws')
+    border_coords = models.TextField(default='', blank=True, verbose_name=u'ai类型图片边框位置信息')
+    add_time = models.IntegerField(verbose_name='添加时间', db_index=True, default=0)
+
+    def __str__(self):
+        return self.id
+
+    class Meta:
+        db_table = 'equipment_info_friday'
+        verbose_name = u'星期五设备信息推送表'
+        verbose_name_plural = verbose_name
+        ordering = ('-id',)
+        app_label = "PushModel"
+
+
+class EquipmentInfoSaturday(models.Model):
+    id = models.BigAutoField(primary_key=True, verbose_name=u'自增标记ID')
+    device_user_id = models.CharField(default='', db_index=True, blank=True, max_length=32, verbose_name=u'用户id')
+    device_uid = models.CharField(default='', db_index=True, blank=True, max_length=32, verbose_name=u'设备uid')
+    device_nick_name = models.CharField(blank=True, max_length=32, default='', verbose_name=u'设备昵称')
+    channel = models.IntegerField(default=1, blank=True, verbose_name=u'设备通道')
+    event_type = models.IntegerField(default=0, blank=True,
+                                     verbose_name=u'事件类型(0:代表空字符,1:ai人,2:ai动物,3:车,123:组合类型(人/车/动物),51:移动侦测,'
+                                                  u'52:传感器报警,53:影像遗失,54:PIR,55:门磁报警, 56:外部发报, 57:人型报警,'
+                                                  u'702:摄像头休眠,703:摄像头唤醒,'
+                                                  u'704:电量过低)')
+    status = models.BooleanField(blank=True, default=False, verbose_name=u'事件状态(0,1)')
+    alarm = models.CharField(blank=True, max_length=256, verbose_name=u'报警信息')
+    event_time = models.CharField(blank=True, db_index=True, default='', max_length=16, verbose_name=u'设备报警时间')
+    receive_time = models.CharField(blank=True, default='', max_length=16, verbose_name=u'接收到报警时间')
+    is_st = models.SmallIntegerField(default=0, verbose_name='是否截图(0:否,1:图片,2:视频)')  # 0 否,1 是图,2,视频
+    storage_location = models.SmallIntegerField(default=1, verbose_name='数据信息存储位置。1:阿里云oss,2:aws')
+    border_coords = models.TextField(default='', blank=True, verbose_name=u'ai类型图片边框位置信息')
+    add_time = models.IntegerField(verbose_name='添加时间', db_index=True, default=0)
+
+    def __str__(self):
+        return self.id
+
+    class Meta:
+        db_table = 'equipment_info_saturday'
+        verbose_name = u'星期六设备信息推送表'
+        verbose_name_plural = verbose_name
+        ordering = ('-id',)
+        app_label = "PushModel"
+
+
+class EquipmentInfoSunday(models.Model):
+    id = models.BigAutoField(primary_key=True, verbose_name=u'自增标记ID')
+    device_user_id = models.CharField(default='', db_index=True, blank=True, max_length=32, verbose_name=u'用户id')
+    device_uid = models.CharField(default='', db_index=True, blank=True, max_length=32, verbose_name=u'设备uid')
+    device_nick_name = models.CharField(blank=True, max_length=32, default='', verbose_name=u'设备昵称')
+    channel = models.IntegerField(default=1, blank=True, verbose_name=u'设备通道')
+    event_type = models.IntegerField(default=0, blank=True,
+                                     verbose_name=u'事件类型(0:代表空字符,1:ai人,2:ai动物,3:车,123:组合类型(人/车/动物),51:移动侦测,'
+                                                  u'52:传感器报警,53:影像遗失,54:PIR,55:门磁报警, 56:外部发报, 57:人型报警,'
+                                                  u'702:摄像头休眠,703:摄像头唤醒,'
+                                                  u'704:电量过低)')
+    status = models.BooleanField(blank=True, default=False, verbose_name=u'事件状态(0,1)')
+    alarm = models.CharField(blank=True, max_length=256, verbose_name=u'报警信息')
+    event_time = models.CharField(blank=True, db_index=True, default='', max_length=16, verbose_name=u'设备报警时间')
+    receive_time = models.CharField(blank=True, default='', max_length=16, verbose_name=u'接收到报警时间')
+    is_st = models.SmallIntegerField(default=0, verbose_name='是否截图(0:否,1:图片,2:视频)')  # 0 否,1 是图,2,视频
+    storage_location = models.SmallIntegerField(default=1, verbose_name='数据信息存储位置。1:阿里云oss,2:aws')
+    border_coords = models.TextField(default='', blank=True, verbose_name=u'ai类型图片边框位置信息')
+    add_time = models.IntegerField(verbose_name='添加时间', db_index=True, default=0)
+
+    def __str__(self):
+        return self.id
+
+    class Meta:
+        db_table = 'equipment_info_sunday'
+        verbose_name = u'星期天设备信息推送表'
+        verbose_name_plural = verbose_name
+        ordering = ('-id',)
+        app_label = "PushModel"
+
+
 class Ai_Push_Info(models.Model):
     id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
     devUid = models.CharField(default='', db_index=True, blank=True, max_length=32, verbose_name=u'设备ID')
@@ -1502,10 +1720,10 @@ class UIDModel(models.Model):
     uid = models.CharField(max_length=20, null=False, db_index=True, unique=True, verbose_name='设备id')
     mac = models.CharField(max_length=17, null=True, default='', verbose_name='设备id对应的mac地址')
     uid_extra = models.TextField(default='', verbose_name='uid的额外描述')
-    status = models.SmallIntegerField(default=0, verbose_name='使用状态')   # 0:未分配,1:已分配,2:已使用
+    status = models.SmallIntegerField(default=0, verbose_name='使用状态')   # 0:未使用, 2:已使用
     add_time = models.IntegerField(default=0, verbose_name='添加时间')
     update_time = models.IntegerField(default=0, verbose_name='更新时间')
-    area = models.SmallIntegerField(default=0, verbose_name='区域')  #0:国内;1:国外
+    area = models.SmallIntegerField(default=0, verbose_name='区域')   # 0:国内, 1:国外
     vpg = models.ForeignKey(VPGModel, to_field='id', default=1, on_delete=models.DO_NOTHING, verbose_name='关联VPG表的id')
     p2p_type = models.IntegerField(default=1, verbose_name='p2p类型。1:宸云,2:tutk')
     full_uid_code = models.CharField(max_length=256, default='', verbose_name='宸云完整uid')

+ 2 - 1
Object/IOTCore/IotObject.py

@@ -24,12 +24,13 @@ class IOTObject(metaclass=ABCMeta):
 
 class IOTClient(IOTObject):
 
-    def __init__(self, region_id = 1):
+    def __init__(self, region_id=1):
 
         if region_id == 1:
             self.client = boto3.client('iot', region_name=AWS_IOT_SES_ACCESS_CHINA_REGION,
                                        aws_access_key_id=AWS_IOT_SES_ACCESS_CHINA_ID,
                                        aws_secret_access_key=AWS_IOT_SES_ACCESS_CHINA_SECRET)
+            # 终端节点: https://cn-northwest-1.console.amazonaws.cn/iot/home?region=cn-northwest-1#/settings
             self.endpoint = 'a250bbr0p9u7as-ats.iot.cn-northwest-1.amazonaws.com.cn'
             self.iotrole = AWS_IOT_SES_ACCESS_CHINA_ROLE
 

+ 1 - 4
Object/UrlTokenObject.py

@@ -34,10 +34,7 @@ class UrlTokenObject:
             if self.token is None:
                 return False
             res = jwt.decode(token, '12345', algorithms='HS256')
-            Url = res.get('Url', None)
-            if not Url:
-                return False
-            self.Url = Url
+            self.Url = res.get('Url', 'null')
             self.mci = res.get('mci', 'null')
             self.user_id = res.get('user_id', 'null')
             self.uid = res.get('uid', 'null')

+ 60 - 2
Object/utils/LocalDateTimeUtil.py

@@ -56,6 +56,64 @@ def get_last_month():
     return last_month_date
 
 
+def get_before_days_timestamp(timestamp, days=1):
+    """
+    获取之前日期时间戳-秒级
+    @param timestamp: 时间戳
+    @param days: 天数
+    @return: (timestamp - second * hour * days) 时间戳
+    """
+    if days:
+        second = 3600
+        hour = 24
+        if days > 0:
+            return timestamp - second * hour * days
+    return 0
+
+
+def date_to_week(str_date):
+    """
+    日期获取星期几
+    @param str_date 日期 例:2022-03-03
+    @return: int 1-7
+    """
+    if str_date:
+        return datetime.datetime.strptime(str_date, "%Y-%m-%d").weekday() + 1
+    return datetime.datetime.now().weekday() + 1
+
+
+def format_date_to_week(str_date, str_format):
+    """
+    日期获取星期几
+    @param str_format:  %Y-%m-%d
+    @param str_date 日期 例:2022-03-03
+    @return: int 1-7
+    """
+    if str_date:
+        return datetime.datetime.strptime(str_date, str_format).weekday() + 1
+    return 0
+
+
+def get_start_and_end_time(date, str_format):
+    """
+    根据日期获取当日开始and结束时间戳
+    @param date: 日期 例:2022-03-07
+    @param str_format: 格式 例:%Y-%m-%d
+    @return: start_time,end_time
+    """
+    if date:
+        today = datetime.datetime.strptime(date, str_format)
+        day = today + datetime.timedelta(days=1)
+        start_time = int(time.mktime(time.strptime(str(today.date()), '%Y-%m-%d')))
+        end_time = int(time.mktime(time.strptime(str(day.date()), '%Y-%m-%d'))) - 1
+        return start_time, end_time
+    return 0
+
+
 if __name__ == "__main__":
-    start_time, end_time = get_today_date(True)
-    print('--- start_time = {} end_time = {}'.format(start_time, end_time))
+    dd = str(1650791368303)
+    print(dd[0:10])
+    print(dd[10:])
+    dateArray = datetime.datetime.utcfromtimestamp(1650791368)
+    print(dateArray.date())
+    print(get_start_and_end_time('20220317', '%Y%m%d'))

+ 80 - 0
SensorGateway/SensorGatewayController.py

@@ -0,0 +1,80 @@
+# -*- coding: utf-8 -*-
+"""
+@Time : 2022/4/26 9:01
+@Auth : Locky
+@File :SensorGatewayController.py
+@IDE :PyCharm
+"""
+import random
+import string
+
+from django.views import View
+
+from Object.ResponseObject import ResponseObject
+from Service.CommonService import CommonService
+
+
+class SensorGateway(View):
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.GET, request, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.POST, request, operation)
+
+    def validation(self, request_dict, request, operation):
+        response = ResponseObject()
+        if operation == 'getSensorId':  # 返回唯一标识id给设备
+            return self.getSensorId(request_dict, response)
+        elif operation == 'registerToAWSIoTCore':  # 注册到AWS IoT Core
+            return self.registerToAWSIoTCore(request_dict, response)
+        else:
+            return response.json(404)
+
+    @staticmethod
+    def getSensorId(request_dict, response):
+        """
+        传感器设备获取设备id
+        @param request_dict: 请求参数
+        @time_stamp: 时间戳
+        @time_stamp_token: 时间戳token
+        @param response: 响应对象
+        @return: sensorId 六位的随机id
+        """
+        time_stamp = request_dict.get('time_stamp', None)
+        time_stamp_token = request_dict.get('time_stamp_token', None)
+
+        if not all([time_stamp, time_stamp_token]):
+            return response.json(444, {'param': 'time_stamp, time_stamp_token'})
+        try:
+            # 时间戳token校验
+            if not CommonService.check_time_stamp_token_without_distance(time_stamp, time_stamp_token):
+                return response.json(13)
+
+            sensor_id = ''.join(random.sample(string.ascii_letters + string.digits, 6))
+            return response.json(0, {'sensor_id': sensor_id})
+        except Exception as e:
+            return response.json(500, repr(e))
+
+    @staticmethod
+    def registerToAWSIoTCore(request_dict, response):
+        """
+        传感器设备注册到AWS IoT Core
+        @param request_dict: 请求参数
+        @request_dict sensor_id: 设备id
+        @param response: 响应对象
+        @return: res iot证书等数据
+        """
+        sensor_id = request_dict.get('sensor_id', None)
+        time_stamp = request_dict.get('time_stamp', None)
+        time_stamp_token = request_dict.get('time_stamp_token', None)
+
+        if not all([sensor_id, time_stamp, time_stamp_token]):
+            return response.json(444, {'param': 'sensor_id, time_stamp, time_stamp_token'})
+        try:
+            return response.json(0)
+        except Exception as e:
+            return response.json(500, repr(e))

+ 20 - 0
Service/CommonService.py

@@ -454,6 +454,26 @@ class CommonService:
             print(e)
             return False
 
+    @staticmethod
+    def check_time_stamp_token_without_distance(time_stamp, time_stamp_token):
+        """
+        用于没有RTC设备的时间戳token校验
+        @param time_stamp: 时间戳
+        @param time_stamp_token: 时间戳token
+        @return: boolean True/False
+        """
+
+        if not all([time_stamp, time_stamp_token]):
+            return False
+        try:
+            token = CommonService.decode_data(time_stamp_token)
+            if token != time_stamp:
+                return False
+            return True
+        except Exception as e:
+            print(e)
+            return False
+
     @staticmethod
     def req_publish_mqtt_msg(thing_name, topic_name, msg):
         # 通用发布MQTT消息函数

+ 222 - 0
Service/EquipmentInfoService.py

@@ -0,0 +1,222 @@
+# -*- encoding: utf-8 -*-
+"""
+@File    : EquipmentInfoService.py
+@Time    : 2022/4/14 17:28
+@Author  : stephen
+@Email   : zhangdongming@asj6.wecom.work
+@Software: PyCharm
+"""
+import datetime
+import time
+
+from django.db.models import Value, CharField
+
+from Model.models import EquipmentInfoMonday, EquipmentInfoTuesday, EquipmentInfoWednesday, EquipmentInfoThursday, \
+    EquipmentInfoFriday, EquipmentInfoSaturday, EquipmentInfoSunday
+from Object.utils import LocalDateTimeUtil
+
+"""
+设备分表查询Service    
+因数据量不断增加,单表保留近七天数据进行分表优化设计
+进行拆分为七张表星期一至星期天进行分表存储。分担单表存储读写压力。
+"""
+
+
+class EquipmentInfoService:
+
+    @staticmethod
+    def get_equipment_info_model(dt, val=0):
+
+        """
+        根据日期判断是星期几,返回相应的Model对象
+        @param val: 1-7代表week
+        @param dt: 日期 例:2022-03-03
+        @return: 星期一至星期天equipment_info对象实例
+        """
+        week = 1
+        if dt:
+            week = LocalDateTimeUtil.date_to_week(dt)
+        if 0 < val < 8:
+            week = val
+        equipment_info = None
+        if week == 1:
+            equipment_info = EquipmentInfoMonday.objects.all().annotate(tab_val=Value('1', output_field=CharField()))
+        elif week == 2:
+            equipment_info = EquipmentInfoTuesday.objects.all().annotate(tab_val=Value('2', output_field=CharField()))
+        elif week == 3:
+            equipment_info = EquipmentInfoWednesday.objects.all().annotate(tab_val=Value('3', output_field=CharField()))
+        elif week == 4:
+            equipment_info = EquipmentInfoThursday.objects.all().annotate(tab_val=Value('4', output_field=CharField()))
+        elif week == 5:
+            equipment_info = EquipmentInfoFriday.objects.all().annotate(tab_val=Value('5', output_field=CharField()))
+        elif week == 6:
+            equipment_info = EquipmentInfoSaturday.objects.all().annotate(tab_val=Value('6', output_field=CharField()))
+        elif week == 7:
+            equipment_info = EquipmentInfoSunday.objects.all().annotate(tab_val=Value('7', output_field=CharField()))
+        return equipment_info
+
+    @classmethod
+    def find_by_start_time_equipment_info(cls, page, size, user_id, start_time, end_time, event_type,
+                                          uid_list):
+        """
+        通过start_time查找指定日期当天设备消息推送
+        @param page: 页数
+        @param size: 每页条数
+        @param user_id: 设备用户id
+        @param start_time: 开始时间
+        @param end_time: 结束时间
+        @param event_type: 事件类型
+        @param uid_list: 设备uid列表
+        @return: result 查询结果
+        """
+        if start_time and end_time:
+            start_date = datetime.datetime.fromtimestamp(int(start_time))
+            # 根据开始日期,获取设备信息查询对象
+            qs = EquipmentInfoService.get_equipment_info_model(str(start_date.date()), 0)
+            # 调用查询方法
+            qs = cls.query_equipment_info(qs, user_id, start_time, end_time, event_type,
+                                          uid_list)
+            # 时区问题
+            week = LocalDateTimeUtil.date_to_week(str(start_date.date()))
+            if week > 0:
+                # 根据筛选日期 查找昨天数据
+                yesterday = 7 if week == 1 else week - 1
+                yesterday_info = EquipmentInfoService.get_equipment_info_model('', yesterday)
+                yesterday_info = cls.query_equipment_info(yesterday_info, user_id, start_time, end_time, event_type,
+                                                          uid_list)
+
+                # 根据筛选日期 查找明天数据
+                tomorrow = 1 if week == 7 else week + 1
+                tomorrow_info = EquipmentInfoService.get_equipment_info_model('', tomorrow)
+                tomorrow_info = cls.query_equipment_info(tomorrow_info, user_id, start_time, end_time, event_type,
+                                                         uid_list)
+                qs = qs.union(yesterday_info, tomorrow_info, all=True)
+            if qs.exists():
+                count = qs.count()
+                qs_page = cls.get_equipment_info_page(qs, page, size)
+                return qs_page, count
+        return None, 0
+
+    @classmethod
+    def get_equipment_info_week_all(cls, page, size, user_id, start_time, end_time, event_type,
+                                    uid_list):
+        """
+        分表查询近七天设备消息推送
+        @param page: 页数
+        @param size: 分页大小
+        @param user_id: 设备用户id
+        @param start_time: 事件开始时间
+        @param end_time: 事件结束时间
+        @param event_type: 事件类型
+        @param uid_list: uid列表
+        @return: qs_page, count 结果集
+        """
+        # 星期一设备信息查询
+        monday_qs = EquipmentInfoService.get_equipment_info_model('', 1)
+        monday_qs = cls.query_equipment_info(monday_qs, user_id, start_time, end_time, event_type,
+                                             uid_list)
+        # 星期二设备信息查询
+        tuesday_qs = EquipmentInfoService.get_equipment_info_model('', 2)
+        tuesday_qs = cls.query_equipment_info(tuesday_qs, user_id, start_time, end_time, event_type,
+                                              uid_list)
+        # 星期三设备信息查询
+        wednesday_qs = EquipmentInfoService.get_equipment_info_model('', 3)
+        wednesday_qs = cls.query_equipment_info(wednesday_qs, user_id, start_time, end_time, event_type,
+                                                uid_list)
+        # 星期四设备信息查询
+        thursday_qs = EquipmentInfoService.get_equipment_info_model('', 4)
+        thursday_qs = cls.query_equipment_info(thursday_qs, user_id, start_time, end_time, event_type,
+                                               uid_list)
+        # 星期五设备信息查询
+        friday_qs = EquipmentInfoService.get_equipment_info_model('', 5)
+        friday_qs = cls.query_equipment_info(friday_qs, user_id, start_time, end_time, event_type,
+                                             uid_list)
+        # 星期六设备信息查询
+        saturday_qs = EquipmentInfoService.get_equipment_info_model('', 6)
+        saturday_qs = cls.query_equipment_info(saturday_qs, user_id, start_time, end_time, event_type,
+                                               uid_list)
+        # 星期天设备信息查询
+        sunday_qs = EquipmentInfoService.get_equipment_info_model('', 7)
+        sunday_qs = cls.query_equipment_info(sunday_qs, user_id, start_time, end_time, event_type,
+                                             uid_list)
+        result = monday_qs.union(tuesday_qs, wednesday_qs, thursday_qs, friday_qs, saturday_qs, sunday_qs, all=True)
+        count = result.count()
+        qs_page = cls.get_equipment_info_page(result, page, size)
+        return qs_page, count
+
+    @classmethod
+    def query_equipment_info(cls, qs, user_id, start_time, end_time, event_type,
+                             uid_list):
+        """
+        设备信息条件查询,根据分表设计,默认条件event_time大于七天前时间
+        @param qs: 设备信息查询对象
+        @param user_id: 设备用户id
+        @param start_time: 开始时间
+        @param end_time: 结束时间
+        @param event_type: 事件类型
+        @param uid_list: 设备uid列表
+        @return: result 设备信息结果集
+        """
+        now_time = int(time.time())
+        # 获取七天前时间戳
+        seven_days_before_time = LocalDateTimeUtil.get_before_days_timestamp(now_time, 7)
+        # 默认查询当前表event_time大于七天前时间
+        qs = qs.filter(event_time__gt=seven_days_before_time)
+        if user_id:
+            qs = qs.filter(device_user_id=user_id)
+        if event_type:
+            # 兼容AI查询
+            if ',' in event_type:
+                eventTypeList = event_type.split(',')
+                eventTypeList = [int(i.strip()) for i in eventTypeList]
+                qs = qs.filter(event_type__in=eventTypeList)
+            else:
+                qs = qs.filter(event_type=event_type)
+        if start_time and end_time:
+            qs = qs.filter(event_time__range=(start_time, end_time))
+        if uid_list:
+            uid_list = uid_list.split(',')
+            qs = qs.filter(device_uid__in=uid_list)
+        return qs
+
+    @classmethod
+    def get_equipment_info_page(cls, equipment_info_qs, page, size):
+        """
+        获取查询结果集进行排序、分页,遍历重命名字典key(主要针对原函数返回结果集)
+        @param equipment_info_qs: 设备信息结果集
+        @param page: 页数
+        @param size: 分页大小
+        @return: qs_page 遍历后的设备信息结果集
+        """
+        equipment_info_qs = equipment_info_qs.values('id', 'device_uid', 'device_nick_name', 'channel', 'event_type',
+                                                     'status', 'alarm',
+                                                     'event_time', 'receive_time', 'is_st', 'add_time',
+                                                     'storage_location', 'border_coords', 'tab_val')
+
+        equipment_info_qs = equipment_info_qs.order_by('-event_time')
+        qs_page = equipment_info_qs[(page - 1) * size:page * size]
+        if not qs_page or not qs_page.exists() or qs_page.count == 0:
+            return qs_page
+        for item in qs_page:
+            # 星期表值
+            tab_val = item['tab_val']
+            # id = 星期表值+id
+            item['id'] = int(tab_val + str(item['id']))
+            item['devUid'] = item['device_uid']
+            item['devNickName'] = item['device_nick_name']
+            item['Channel'] = item['channel']
+            item['eventType'] = item['event_type']
+            item['eventTime'] = item['event_time']
+            item['receiveTime'] = item['receive_time']
+            item['addTime'] = item['add_time']
+            item['borderCoords'] = item['border_coords']
+            item.pop('device_uid')
+            item.pop('device_nick_name')
+            item.pop('channel')
+            item.pop('event_type')
+            item.pop('event_time')
+            item.pop('receive_time')
+            item.pop('add_time')
+            item.pop('border_coords')
+            item.pop('tab_val')
+        return qs_page

+ 9 - 6
Service/ModelService.py

@@ -1,12 +1,12 @@
-import logging
+import json
 import time
 
 import requests
+from django.db.models import Q
 
 from Ansjer.config import BASE_DIR
 from Model.models import *
-import json
-from django.db.models import Q
+from Service.EquipmentInfoService import EquipmentInfoService
 
 
 # 针对模型封装的复用性代码
@@ -149,7 +149,6 @@ class ModelService:
         else:
             return True
 
-
     # 通过用户名获取userIDLIST
     @staticmethod
     def get_user_list_by_username(username):
@@ -162,6 +161,11 @@ class ModelService:
         notify_alexa_delete(userID, uid)
         ei_qs = Equipment_Info.objects.filter(userID_id=userID, devUid=uid)
         ei_qs.delete()
+        for i in range(1, 8):
+            eq_list = EquipmentInfoService.get_equipment_info_model('', i)
+            eq_list = eq_list.filter(device_user_id=userID, device_uid=uid)
+            if eq_list.exists():
+                eq_list.delete()
         # ei_count = ei_qs.count()
         # while (ei_count > 1000):
         #     ei_qs[0:1000].delete()
@@ -174,7 +178,6 @@ class ModelService:
         uid_list = Device_Info.objects.filter(userID_id=userID).values_list('UID', flat=True)
         return list(uid_list)
 
-
     @staticmethod
     def notify_alexa_add(uid, userID, nickname, encrypt_pwd):
         url = 'https://www.zositech.xyz/deviceStatus/addOrUpdate'
@@ -194,7 +197,7 @@ class ModelService:
         file_path = '/'.join((BASE_DIR, 'static/delete_device.log'))
         file = open(file_path, 'a+')
         file.write(ip + "; username:" + userID + "; time:" + time.strftime(
-                "%Y-%m-%d %H:%M:%S", time.localtime()) + "; " + operation)
+            "%Y-%m-%d %H:%M:%S", time.localtime()) + "; " + operation)
         file.write('\n')
         file.flush()
         file.close()

+ 5 - 0
Service/TemplateService.py

@@ -85,6 +85,11 @@ class TemplateService:
             'Cloudsum/userappversion',
             'Cloudsum/usercount',
             'Cloudsum/usercloud',
+            'paymentCycle/queryPayCycle',
+            'paymentCycle/cancelPayCycle',
+            'payCycle/paypalCycleNotify',
+            'payCycle/paypalCycleReturn',
+            'payCycle/test',
         ]
         return apiList