Răsfoiți Sursa

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

peng 3 ani în urmă
părinte
comite
2c3b792974

+ 4 - 4
AdminController/UserManageController.py

@@ -354,13 +354,13 @@ class UserManagement(View):
             if username or NickName or phone or userEmail:
                 # 条件查询
                 if username:
-                    device_user_qs = Device_User.objects.filter(username__contains=username)
+                    device_user_qs = Device_User.objects.filter(username__icontains=username)
                 if NickName:
-                    device_user_qs = Device_User.objects.filter(NickName__contains=NickName)
+                    device_user_qs = Device_User.objects.filter(NickName__icontains=NickName)
                 if phone:
-                    device_user_qs = Device_User.objects.filter(phone__contains=phone)
+                    device_user_qs = Device_User.objects.filter(phone__icontains=phone)
                 if userEmail:
-                    device_user_qs = Device_User.objects.filter(userEmail__contains=userEmail)
+                    device_user_qs = Device_User.objects.filter(userEmail__icontains=userEmail)
                 if not device_user_qs.exists():
                     return response.json(0)
                 total = len(device_user_qs)

+ 123 - 0
AdminController/dataSystemManagement/BusinessDataController.py

@@ -0,0 +1,123 @@
+# -*- encoding: utf-8 -*-
+"""
+@File    : UserDataController.py
+@Time    : 2022/8/16 10:44
+@Author  : peng
+@Email   : zhangdongming@asj6.wecom.work
+@Software: PyCharm
+"""
+
+import requests
+from django.db.models import Q, Count, Sum
+from django.views.generic.base import View
+
+from Model.models import VodHlsModel, VideoPlaybackTimeModel
+from Service.CommonService import CommonService
+
+
+# 业务数据
+class BusinessDataView(View):
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.GET, request, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.POST, request, operation)
+
+    def validation(self, request_dict, request, operation):
+        token_code, user_id, response = CommonService.verify_token_get_user_id(request_dict, request)
+        if token_code != 0:
+            return response.json(token_code)
+        if operation == 'vodData':  # 查询设备云存储数据
+            return self.query_device_vod_business(request_dict, response)
+        elif operation == 'global/vodData':  # 查询全球设备云存储数据
+            return self.query_global_device_vod_business(request, request_dict, response)
+        else:
+            return response.json(414)
+
+    @classmethod
+    def query_device_vod_business(cls, request_dict, response):
+        """
+        查询设备云存储数据
+        @param request_dict:请求参数
+        @request_dict startTime:开始时间
+        @request_dict endTime:结束时间
+        @param response:响应对象
+        @return:
+        """
+        start_time = request_dict.get('startTime', None)
+        end_time = request_dict.get('endTime', None)
+        if not all([start_time, end_time]):
+            return response.json(444, {'error param': 'startTime or endTime'})
+        try:
+            vod_hls_qs = VodHlsModel.objects.filter(time__range=(start_time, end_time))
+            video_play_qs = VideoPlaybackTimeModel.objects.filter(startTime__range=(start_time, end_time),
+                                                                  playMode='could')
+            upload_duration_qs = vod_hls_qs.values('uid').annotate(uploadFrequency=Count('uid')).order_by(
+                'uploadFrequency')
+            upload_device_count = len(upload_duration_qs)  # 上传设备数量
+            uid_list = []
+            for item in upload_duration_qs:
+                item['uploadDuration'] = vod_hls_qs.filter(uid=item['uid']).aggregate(total=Sum('sec'))['total']
+                item['playDuration'] = video_play_qs.filter(uid=item['uid']).aggregate(total=Sum('duration'))['total']
+                item['playDuration'] = item['playDuration'] if item['playDuration'] else 0
+                item['playFrequency'] = video_play_qs.filter(uid=item['uid'], playMode='cloud').count()
+                uid_list.append(item['uid'])
+
+            video_play_qs = video_play_qs.filter(~Q(uid__in=uid_list))
+            play_duration_qs = video_play_qs.values('uid').annotate(playFrequency=Count('uid')).order_by(
+                'playFrequency')
+            play_device_count = play_duration_qs.count()
+            for item in play_duration_qs:
+                item['uploadFrequency'] = 0
+                item['uploadDuration'] = 0
+                item['playDuration'] = video_play_qs.filter(uid=item['uid']).aggregate(total=Sum('duration'))['total']
+                item['playDuration'] = item['playDuration'] if item['playDuration'] else 0
+            res = {
+                'uploadDeviceCount': upload_device_count,
+                'playDeviceCount': play_device_count,
+                'vodData': list(upload_duration_qs) + list(play_duration_qs)
+            }
+            return response.json(0, res)
+        except Exception as e:
+            return response.json(500, repr(e))
+
+    @classmethod
+    def query_global_device_vod_business(cls, request, request_dict, response):
+        """
+        查询全球设备云存储数据
+        @param request:请求
+        @param request_dict:请求参数
+        @param response:响应对象
+        @return:
+        """
+        url_list = CommonService.get_domain_name()
+        try:
+            headers = {
+                'Authorization': request.META.get('HTTP_AUTHORIZATION')
+            }
+            upload_device_count = 0
+            play_device_count = 0
+            vod_list = []
+            for url in url_list:
+                url = url + request.path.replace('global/', '')
+                res = requests.get(url=url, params=request_dict, headers=headers)
+                result = res.json()
+                if result['result_code'] == 0:
+                    upload_device_count += int(result['result']['uploadDeviceCount'])
+                    play_device_count += int(result['result']['playDeviceCount'])
+                    vod_list += result['result']['vodData']
+                else:
+                    return response.json(result['result_code'])
+            res = {
+                'uploadDeviceCount': upload_device_count,
+                'playDeviceCount': play_device_count,
+                'vodData': vod_list
+            }
+            return response.json(0, res)
+        except Exception as e:
+            return response.json(500, repr(e))

+ 431 - 0
AdminController/dataSystemManagement/DeviceDataController.py

@@ -0,0 +1,431 @@
+# -*- encoding: utf-8 -*-
+"""
+@File    : UserDataController.py
+@Time    : 2022/8/16 10:44
+@Author  : peng
+@Email   : zhangdongming@asj6.wecom.work
+@Software: PyCharm
+"""
+
+import datetime
+
+import requests
+from django.db.models import Count
+from django.views.generic.base import View
+
+from Ansjer.config import DEVICE_TYPE
+from Model.models import Device_Info, CountryModel, Order_Model
+from Service.CommonService import CommonService
+
+
+# 设备数据
+class DeviceDataView(View):
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.GET, request, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.POST, request, operation)
+
+    def validation(self, request_dict, request, operation):
+        token_code, user_id, response = CommonService.verify_token_get_user_id(request_dict, request)
+        if token_code != 0:
+            return response.json(token_code)
+        if operation == 'type':  # 统计设备类型
+            return self.type_statistics(response)
+        if operation == 'regional':  # 设备地区分布
+            return self.regional_statistics(response)
+        if operation == 'addDevice':  # 查询设备增长数据(数据有些许差异)
+            return self.add_device(request_dict, response)
+        if operation == 'active':  # 设备活跃数据
+            return self.device_active(request_dict, response)
+        if operation == 'global/regional':  # 全球设备分布
+            return self.global_regional(request, request_dict, response)
+        if operation == 'global/type':  # 全球设备类型
+            return self.golbal_type(request, request_dict, response)
+        else:
+            return response.json(414)
+
+    @classmethod
+    def golbal_type(cls, request, request_dict, response):
+        """
+        全球设备类型分布
+        @param request:请求
+        @param request_dict:请求参数
+        @param response: 响应对象
+        """
+        url_list = CommonService.get_domain_name()
+        try:
+            headers = {
+                'Authorization': request.META.get('HTTP_AUTHORIZATION')
+            }
+            type_list = []
+            type_count = 0
+            for url in url_list:
+                url = url + request.path.replace('global/', '')
+                res = requests.get(url=url, params=request_dict, headers=headers)
+                result = res.json()
+                if result['result_code'] == 0:
+                    for item in result['result']['region']:
+                        flag = 0
+                        for each in type_list:
+                            if item['countryName'] == each['countryName']:
+                                each['count'] += item['count']
+                                type_count += item['count']
+                                each['countryType'] += item['countryType']
+                                type_count += item['countryType']
+                                flag = 1
+                                break
+                        if flag == 0:
+                            type_list.append(item)
+                            type_count += item['count']
+                    for item in type_list:
+                        item['rate'] = round(item['count'] / type_count * 100, 2)
+                else:
+                    return response.json(result['result_code'])
+            res = {
+                'type': CommonService.list_sort(type_list)
+            }
+            return response.json(0, res)
+        except Exception as e:
+            print(e)
+            return response.json(500)
+
+    @classmethod
+    def global_regional(cls, request, request_dict, response):
+        """
+        全球设备分布
+        @param request:请求
+        @param request_dict:请求参数
+        @param response:响应对象
+        @return:
+        """
+        url_list = CommonService.get_domain_name()
+        try:
+            headers = {
+                'Authorization': request.META.get('HTTP_AUTHORIZATION')
+            }
+            device_list = []
+            device_count = 0
+            region_list = []
+            region_count = 0
+            for url in url_list:
+                url = url + request.path.replace('global/', '')
+                res = requests.get(url=url, params=request_dict, headers=headers)
+                result = res.json()
+                if result['result_code'] == 0:
+                    # 处理地区
+                    for item in result['result']['countries']:
+                        flag = 0
+                        for each in device_list:
+                            if each['countryName'] == item['countryName']:
+                                each['count'] += int(item['count'])
+                                device_count += int(item['count'])
+                                flag = 1
+                                break
+                        if flag == 0:
+                            device_list.append(item)
+                            device_count += int(item['count'])
+                    for item in device_list:
+                        rate = round(item['count'] / device_count * 100, 2)
+                        item['rate'] = rate
+                    for item in result['result']['continent']:
+                        flag = 0
+                        for each in region_list:
+                            if each['continentName'] == item['continentName']:
+                                each['count'] += item['count']
+                                region_count += item['count']
+                                flag = 1
+                                break
+                        if flag == 0:
+                            region_list.append(item)
+                            region_count += item['count']
+                    for item in region_list:
+                        item['rate'] = round(item['count'] / region_count * 100, 2)
+                else:
+                    return response.json(result['result_code'])
+            res = {
+                'countries': CommonService.list_sort(device_list[:20]),
+                'continent': region_list
+            }
+            return response.json(0, res)
+        except Exception as e:
+            return response.json(500, repr(e))
+
+    @classmethod
+    def device_active(cls, request_dict, response):
+        order_type = request_dict.get('orderType', None)
+        if not order_type:
+            return response.json(444)
+        order_type = int(order_type)
+        order_type_qs = Order_Model.objects.filter(order_type=order_type).values('UID').order_by('UID').distinct()
+        try:
+            order_type_list = []
+            for order in order_type_qs:
+                UID = order['UID']
+                device_info_qs = Device_Info.objects.filter(UID=UID).values('Type').order_by('Type').distinct()
+                if not device_info_qs.exists():
+                    continue
+                device_info_qs = device_info_qs[0]['Type']
+                order_type_list.append(device_info_qs)
+            type_list = []
+            for i in order_type_list:
+                if i not in type_list:
+                    type_list.append(i)
+
+            return response.json(0, type_list)
+        except Exception as e:
+            print(e)
+            return response.json(500)
+
+    @classmethod
+    def add_device(cls, request_dict, response):
+        """
+        查询设备增长数据
+        @param request_dict:请求参数
+        @request_dict starTime:开始时间
+        @request_dict endTime:结束时间
+        @param response:响应对象
+        """
+        start_time = request_dict.get('startTime', None)  # 时间戳
+        end_time = request_dict.get('endTime', None)
+        unit_time = request_dict.get('unitTime', None)
+        order_type = request_dict.get('orderType', None)
+        if not all([start_time, end_time, unit_time, order_type]):
+            return response.json(444, {'error param': 'startTime or endTime or timeUnit or order_type'})
+        order_type = int(order_type)
+        start_time = datetime.datetime.fromtimestamp(int(start_time))
+        end_time = datetime.datetime.fromtimestamp(int(end_time))
+        time_list = CommonService.cutting_time(start_time, end_time, unit_time)
+        try:
+            device_info_qs = Device_Info.objects.filter(data_joined__range=(start_time, end_time))
+            device_count_qs = device_info_qs.count()
+            device_type_qs = device_info_qs.values('UID').order_by('UID').distinct()
+            info_list = []
+            count_unique = device_type_qs.count()
+            # 统计该时间段的设备数量(去重)
+            for item in time_list:
+                start_time = datetime.datetime.fromtimestamp(int(item[0]))
+                end_time = datetime.datetime.fromtimestamp(int(item[1]))
+                info_dict = {
+                    'startTime': item[0],
+                    'endTime': item[1]
+                }
+                count = 0
+                for device_type in device_type_qs:
+                    uid = device_type['UID']
+                    device_test_qs = Device_Info.objects.filter(data_joined__lt=start_time, UID=uid).values()
+                    if device_test_qs.exists():
+                        continue
+                    else:
+                        count += 1
+                        device_only_qs = device_info_qs.filter(UID=uid).values()
+                        device_only = device_only_qs[0]
+                        # res = {
+                        #     'country': '',
+                        #     'count': ''
+                        # }
+                        #
+                        # for country in device_only:
+
+
+                info_dict['count'] = count
+                info_list.append(info_dict)
+
+
+
+
+        #         info_list.append(info_dict)
+        #     # 统计地区设备数量
+        #     device_info_country_qs = device_info_qs.values('userID__region_country').annotate(
+        #         count=Count('userID__region_country')).order_by('-count')
+        #     region_list = []
+        #     for item in device_info_country_qs:
+        #         country_id = item['userID__region_country']
+        #         country_qs = CountryModel.objects.filter(id=country_id).values('country_name', 'id')
+        #         country_name = country_qs[0]['country_name'] if country_qs.exists() else '未知区域'
+        #         count = device_info_qs.filter(userID__region_country=item['userID__region_country']).values(
+        #             'UID').annotate(count=Count('UID', distinct=True)).order_by('-count').count()
+        #         rate = round(count / count_unique * 100, 2)
+        #         country_dict = {
+        #             'countryName': country_name,
+        #             'count': count,
+        #             'rate': rate
+        #         }
+        #         region_list.append(country_dict)
+        #     # 统计设备类型数量
+        #     device_info_type_qs = device_info_qs.values('Type').annotate(
+        #         count=Count('Type', distinct=True)).order_by('-count')
+        #     count = device_info_type_qs.count()
+        #     # count_list = []
+        #     # for device_info_country in device_info_type_qs:
+        #     #     type = device_info_country['Type']
+        #     #     count_list.append(type)
+        #     device_info_type_qs = device_info_type_qs.values('Type').distinct()
+        #     type_list = []
+        #     for device_type in device_info_type_qs:
+        #         type = device_type['Type']
+        #         name = DEVICE_TYPE.get(type, '未知类型')
+        #         name = name if name != 'UNKOWN' else '未知类型'
+        #         total = device_info_qs.filter(Type=device_type['Type']).values('UID').annotate(
+        #             count=Count('UID', distinct=True)).order_by('-count').count()
+        #         rate = round(total / count_unique * 100, 2)  # count_unique 有误,跟device_info_type_qs 总数合不上 (可以看151行)
+        #         type_dict = {
+        #             'type': name,
+        #             'count': total,
+        #             'rate': rate
+        #         }
+        #         type_list.append(type_dict)
+        #     # 统计设备版本数量
+        #     device_info_type_qs = device_info_qs.values('UID').annotate(
+        #         count=Count('UID', distinct=True)).order_by('-count')
+        #     count = device_info_type_qs.count()
+        #     uid_list = []
+        #     for device_clound in device_info_type_qs:
+        #         uid = device_clound['UID']
+        #         uid_list.append(uid)
+        #     order_model_qs = Order_Model.objects.filter(UID__in=uid_list).values('UID').annotate(
+        #         count=Count('UID', distinct=True)).values('order_type').order_by('order_type')
+        #     count = order_model_qs.count()
+        #     order_type_list = []
+        #     for order_model in order_model_qs:
+        #         orderType = order_model['order_type']
+        #         order_type_list.append(orderType)
+        #     version_list = []
+        #     res = {}
+        #     if order_type == 0:
+        #         res['name'] = '云存'
+        #     elif order_type == 1:
+        #         res['name'] = 'AI'
+        #     elif order_type == 2:
+        #         res['name'] = '联通4G'
+        #     res['total'] = order_type_list.count(order_type)
+        #     version_list.append(res)
+        #
+        #     res = {
+        #         'info': info_list,
+        #         'region': region_list,
+        #         'type': type_list,
+        #         'version': version_list
+        #     }
+            return response.json(0, info_list)
+        except Exception as e:
+            return response.json(500, repr(e))
+
+    @classmethod
+    def regional_statistics(cls, response):
+        """
+        统计地区设备数量
+        @param response:响应对象
+        """
+        device_country_qs = Device_Info.objects.all().values('userID__region_country').annotate(
+            count=Count('userID__region_country')).order_by('-count')
+        device_info_qs = Device_Info.objects.values('UID').order_by('UID').distinct()
+        count = device_info_qs.count()
+        if not device_country_qs.exists():
+            return response.json(444)
+        res = {}
+        try:
+            device_country_list = []
+            continent_list = []
+            for device_country in device_country_qs:
+                country_id = device_country['userID__region_country']
+                country_qs = CountryModel.objects.filter(id=country_id).values('country_name', 'region__name')
+                if not country_qs.exists():
+                    name = '未知地区'
+                else:
+                    name = country_qs[0]['country_name']
+                count = Device_Info.objects.filter(
+                    userID__region_country=device_country['userID__region_country']).values('UID').annotate(
+                    count=Count('UID', distinct=True)).order_by('-count').count()
+
+                device_country_list.append({
+                    'countryName': name,
+                    'count': count
+                })
+                if country_qs.exists():
+                    flag = 0
+                    for each in continent_list:
+                        if country_qs[0]['region__name'] == each['continentName']:
+                            each['count'] += count
+                            flag = 1
+                            break
+                    if flag == 0:
+                        continent_list.append({
+                            'continentName': country_qs[0]['region__name'],
+                            'count': count
+                        })
+            for item in continent_list:
+                item['rate'] = round(item['count'] / count * 100, 2)
+            res['countries'] = device_country_list
+            res['continent'] = continent_list
+            return response.json(0, res)
+        except Exception as e:
+            print(e)
+            return response.json(500)
+
+    @classmethod
+    def type_statistics(cls, response):
+        """
+        统计设备类型
+        @param response:响应对象
+        @return:
+        """
+        device_info_qs = Device_Info.objects.all().values('Type').annotate(count=Count('Type')).order_by('-count')
+        if not device_info_qs.exists():
+            return response.json(444)
+        res = {}
+        try:
+            device_info_list = []
+            for device_info in device_info_qs:
+                type = device_info['Type']
+                name = DEVICE_TYPE.get(type, '未知类型')
+                name = name if name != 'UNKOWN' else '未知类型'
+                count = Device_Info.objects.filter(Type=device_info['Type']).values('UID').annotate(
+                    count=Count('UID', distinct=True)).order_by('-count').count()
+                device_info_list.append({
+                    'type': name,
+                    'count': count
+                })
+
+            device_country_qs = Device_Info.objects.all().values('userID__region_country').annotate(
+                count=Count('userID__region_country')).order_by('-count')
+            device_country_list = []
+            for device_country in device_country_qs:
+                country_id = device_country['userID__region_country']
+                country_qs = CountryModel.objects.filter(id=country_id).values('country_name', 'region__name')
+                if not country_qs.exists():
+                    country_name = '未知地区'
+                else:
+                    country_name = country_qs[0]['country_name']
+                device_type_qs = Device_Info.objects.filter(userID__region_country=country_id).values('Type').annotate(count=Count('Type', distinct=True)).order_by('-count')
+                country_type_list = []
+                for device_type in device_type_qs:
+                    type = device_type['Type']
+                    name = DEVICE_TYPE.get(type, '未知类型')
+                    name = name if name != 'UNKOWN' else '未知类型'
+                    count = device_type_qs.filter(Type=device_type['Type']).values('UID').annotate(
+                        count=Count('UID', distinct=True)).order_by('-count').count()
+                    country_type_list.append({
+                        'type': name,
+                        'count': count
+                    })
+                count = Device_Info.objects.filter(
+                    userID__region_country=device_country['userID__region_country']).values('UID').annotate(
+                    count=Count('UID', distinct=True)).order_by('-count').count()
+
+                device_country_list.append({
+                    'countryName': country_name,
+                    'count': count,
+                    'countryType': country_type_list
+                })
+            res['type'] = device_info_list
+            res['region'] = device_country_list
+            return response.json(0, res)
+        except Exception as e:
+            print(e)
+            return response.json(500)

+ 266 - 0
AdminController/dataSystemManagement/HomeDataController.py

@@ -0,0 +1,266 @@
+# -*- encoding: utf-8 -*-
+"""
+@File    : UserDataController.py
+@Time    : 2022/8/16 10:44
+@Author  : peng
+@Email   : zhangdongming@asj6.wecom.work
+@Software: PyCharm
+"""
+import datetime
+import openpyxl
+import requests
+
+from django.db.models import Sum
+from django.http import HttpResponse
+from django.utils.encoding import escape_uri_path
+from django.views.generic.base import View
+
+from Model.models import VideoPlaybackTimeModel, Device_User, Device_Info, Order_Model
+from Service.CommonService import CommonService
+
+
+# 业务数据
+class HomeDataView(View):
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.GET, request, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.POST, request, operation)
+
+    def validation(self, request_dict, request, operation):
+        token_code, user_id, response = CommonService.verify_token_get_user_id(request_dict, request)
+        if token_code != 0:
+            return response.json(token_code)
+        if operation == 'allData':  # 查询首页数据
+            return self.query_all_data(response)
+        elif operation == 'salesVolume':  # 查询销售额数据
+            return self.query_sales_volume_data(request_dict, response)
+        elif operation == 'global/allData':  # 查询全球首页数据
+            return self.query_global_all_data(request, request_dict, response)
+        elif operation == 'global/salesVolume':  # 查询全球销售额数据
+            return self.query_global_sales_volume_data(request, request_dict, response)
+        elif operation == 'exportData':  # 查询全球销售额数据
+            return self.export_data(request_dict, response)
+        else:
+            return response.json(414)
+
+    @classmethod
+    def query_all_data(cls, response):
+        """
+        查询首页数据
+        @param response:响应对象
+        @return:
+        """
+        end_time = datetime.datetime.today().replace(hour=0, minute=0, second=0, microsecond=0)
+        start_time = end_time + datetime.timedelta(days=-1)
+        end_time_stamp = CommonService.str_to_timestamp(end_time.strftime('%Y-%m-%d %H:%M:%S'))
+        start_time_stamp = CommonService.str_to_timestamp(start_time.strftime('%Y-%m-%d %H:%M:%S'))
+        try:
+            user_increase_count = Device_User.objects.filter(data_joined__range=(start_time, end_time)).count()
+            user_active_count = Device_User.objects.filter(last_login__range=(start_time, end_time)).count()
+            user_all_count = Device_User.objects.filter(data_joined__lte=end_time).count()
+            device_increase_count = Device_Info.objects.filter(data_joined__range=(start_time, end_time)).values(
+                'UID').distinct().count()
+            device_active_count = VideoPlaybackTimeModel.objects.filter(
+                startTime__range=(start_time_stamp, end_time_stamp)).values('uid').distinct().count()
+            device_all_count = Device_Info.objects.filter(data_joined__lte=end_time).values('UID').distinct().count()
+            order_qs = Order_Model.objects.filter(status=1, addTime__range=(start_time_stamp, end_time_stamp))
+            order_total = order_qs.aggregate(total=Sum('price'))['total']
+            vod_order_total = order_qs.filter(order_type=0).aggregate(total=Sum('price'))['total']
+            ai_order_total = order_qs.filter(order_type=1).aggregate(total=Sum('price'))['total']
+            unicom_order_total = order_qs.filter(order_type=2).aggregate(total=Sum('price'))['total']
+            order_all_qs = Order_Model.objects.filter(status=1, addTime__lte=end_time_stamp)
+            order_all_total = order_all_qs.aggregate(total=Sum('price'))['total']
+            vod_order_all_total = order_all_qs.filter(order_type=0).aggregate(total=Sum('price'))['total']
+            ai_order_all_total = order_all_qs.filter(order_type=1).aggregate(total=Sum('price'))['total']
+            unicom_order_all_total = order_all_qs.filter(order_type=2).aggregate(total=Sum('price'))['total']
+            res = {
+                'userIncreaseCount': user_increase_count,
+                'userActiveCount': user_active_count,
+                'userAllCount': user_all_count,
+                'deviceIncreaseCount': device_increase_count,
+                'deviceActiveCount': device_active_count,
+                'deviceAllCount': device_all_count,
+                'orderTotal': round(order_total, 2) if order_total else 0,
+                'vodOrderTotal': round(vod_order_total, 2) if vod_order_total else 0,
+                'aiOrderTotal': round(ai_order_total, 2) if ai_order_total else 0,
+                'unicomOrderTotal': round(unicom_order_total, 2) if unicom_order_total else 0,
+                'orderAllTotal': round(order_all_total, 2) if order_all_total else 0,
+                'vodOrderAllTotal': round(vod_order_all_total, 2) if vod_order_all_total else 0,
+                'aiOrderAllTotal': round(ai_order_all_total, 2) if ai_order_all_total else 0,
+                'unicomOrderAllTotal': round(unicom_order_all_total, 2) if unicom_order_all_total else 0,
+            }
+            return response.json(0, res)
+        except Exception as e:
+            return response.json(500, repr(e))
+
+    @classmethod
+    def query_sales_volume_data(cls, request_dict, response):
+        """
+        查询销售额数据
+        @param request_dict:请求参数
+        @request_dict startTime:开始时间
+        @request_dict endTime:结束时间
+        @request_dict timeUnit:时间单位
+        @param response:响应对象
+        @return:
+        """
+        start_time = request_dict.get('startTime', None)
+        end_time = request_dict.get('endTime', None)
+        time_unit = request_dict.get('timeUnit', None)
+        if not all([start_time, end_time, time_unit]):
+            return response.json(444, {'error param': 'startTime or endTime or timeUnit'})
+        try:
+            order_qs = Order_Model.objects.filter(addTime__range=(start_time, end_time))
+            start_time = datetime.datetime.fromtimestamp(int(start_time))
+            end_time = datetime.datetime.fromtimestamp(int(end_time))
+            time_list = CommonService.cutting_time(start_time, end_time, time_unit)
+            order_list = []
+            for item in time_list:
+                total = order_qs.filter(addTime__range=item).aggregate(total=Sum('price'))['total']
+                res = {
+                    'total': round(total, 2) if total else 0,
+                    'startTime': item[0],
+                    'endTime': item[1]
+                }
+                order_list.append(res)
+            return response.json(0, order_list)
+        except Exception as e:
+            return response.json(500, repr(e))
+
+    @classmethod
+    def query_global_all_data(cls, request, request_dict, response):
+        """
+        查询全球首页数据
+        @param request:请求
+        @param request_dict:请求参数
+        @param response:响应对象
+        @return:
+        """
+        url_list = CommonService.get_domain_name()
+        try:
+            headers = {
+                'Authorization': request.META.get('HTTP_AUTHORIZATION')
+            }
+            user_increase_count = 0
+            user_active_count = 0
+            user_all_count = 0
+            device_increase_count = 0
+            device_active_count = 0
+            device_all_count = 0
+            order_total = 0
+            vod_order_total = 0
+            ai_order_total = 0
+            unicom_order_total = 0
+            order_all_total = 0
+            vod_order_all_total = 0
+            ai_order_all_total = 0
+            unicom_order_all_total = 0
+            for url in url_list:
+                url = url + request.path.replace('global/', '')
+                res = requests.get(url=url, params=request_dict, headers=headers)
+                result = res.json()
+                user_increase_count += result['result']['userIncreaseCount']
+                user_active_count += result['result']['userActiveCount']
+                user_all_count += result['result']['userAllCount']
+                device_increase_count += result['result']['deviceIncreaseCount']
+                device_active_count += result['result']['deviceActiveCount']
+                device_all_count += result['result']['deviceAllCount']
+                order_total += result['result']['orderTotal']
+                vod_order_total += result['result']['vodOrderTotal']
+                ai_order_total += result['result']['aiOrderTotal']
+                unicom_order_total += result['result']['unicomOrderTotal']
+                order_all_total += result['result']['orderAllTotal']
+                vod_order_all_total += result['result']['vodOrderAllTotal']
+                ai_order_all_total += result['result']['aiOrderAllTotal']
+                unicom_order_all_total += result['result']['unicomOrderAllTotal']
+            res = {
+                'userIncreaseCount': user_increase_count,
+                'userActiveCount': user_active_count,
+                'userAllCount': user_all_count,
+                'deviceIncreaseCount': device_increase_count,
+                'deviceActiveCount': device_active_count,
+                'deviceAllCount': device_all_count,
+                'orderTotal': order_total,
+                'vodOrderTotal': vod_order_total,
+                'aiOrderTotal': ai_order_total,
+                'unicomOrderTotal': unicom_order_total,
+                'orderAllTotal': order_all_total,
+                'vodOrderAllTotal': vod_order_all_total,
+                'aiOrderAllTotal': ai_order_all_total,
+                'unicomOrderAllTotal': unicom_order_all_total,
+            }
+            return response.json(0, res)
+        except Exception as e:
+            return response.json(500, repr(e))
+
+    @classmethod
+    def query_global_sales_volume_data(cls, request, request_dict, response):
+        """
+        查询全球销售额数据
+        @param request:请求
+        @param request_dict:请求参数
+        @param response:响应对象
+        @return:
+        """
+        url_list = CommonService.get_domain_name()
+        try:
+            headers = {
+                'Authorization': request.META.get('HTTP_AUTHORIZATION')
+            }
+            order_list = []
+            for url in url_list:
+                url = url + request.path.replace('global/', '')
+                res = requests.get(url=url, params=request_dict, headers=headers)
+                result = res.json()
+                for item in result['result']:
+                    flag = 0
+                    for each in order_list:
+                        if item['startTime'] == each['startTime'] and item['endTime'] == each['endTime']:
+                            each['total'] += item['total']
+                            break
+                    if flag == 0:
+                        order_list.append(item)
+            return response.json(0, order_list)
+        except Exception as e:
+            return response.json(500, repr(e))
+
+
+    @classmethod
+    def export_data(cls, request_dict, response):
+        """
+        下载文件
+        @param request_dict:请求参数
+        @request_dict tableData:表格数据
+        @request_dict fileName:文件名
+        @param response:响应对象
+        @return:
+        """
+        table_data = request_dict.get('tableData', None)
+        sheet_name = request_dict.get('fileName', None)
+        if not all([table_data, sheet_name]):
+            return response.json(444, {'error param': 'tableData or fileName'})
+        table_data = eval(table_data)
+        file_name = sheet_name + '.xlsx'
+        try:
+            res = HttpResponse(content_type='application/octet-stream')
+            res['Content-Disposition'] = 'attachment; filename={}'.format(escape_uri_path(file_name))
+            wb = openpyxl.Workbook()
+            sh = wb.create_sheet(sheet_name, 0)
+            for row, data in enumerate(table_data):
+                if row == 0:
+                    sh.append(list(data.keys()))
+                sh.append(list(data.values()))
+            wb.save(res)
+            # with open(file_path, 'rb') as f:
+            #     res = HttpResponse(f)
+            #     res['Content-Type'] = 'application/octet-stream'
+            #     res['Content-Disposition'] = 'attachment;filename="{}"'.format(file_name)
+            return res
+        except Exception as e:
+            return response.json(500, repr(e))

+ 814 - 0
AdminController/dataSystemManagement/ServiceDataController.py

@@ -0,0 +1,814 @@
+# -*- encoding: utf-8 -*-
+"""
+@File    : UserDataController.py
+@Time    : 2022/8/16 10:44
+@Author  : peng
+@Email   : zhangdongming@asj6.wecom.work
+@Software: PyCharm
+"""
+
+from django.db.models import Q, Count, Sum
+from django.views.generic.base import View
+from Ansjer.config import DEVICE_TYPE
+import datetime
+import requests
+
+from Model.models import Order_Model, CountryModel, Device_Info, DeviceTypeModel, UidSetModel, UnicomCombo
+from Service.CommonService import CommonService
+
+
+# 服务数据
+class ServiceDataView(View):
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.GET, request, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.POST, request, operation)
+
+    def validation(self, request_dict, request, operation):
+        token_code, user_id, response = CommonService.verify_token_get_user_id(request_dict, request)
+        if token_code != 0:
+            return response.json(token_code)
+        if operation == 'payOrder':  # 查询付费订单数据
+            return self.query_pay_order(request_dict, response)
+        elif operation == 'freeOrder':  # 查询免费订单数据
+            return self.query_free_order(request_dict, response)
+        elif operation == 'firstPayOrder':  # 查询首次付费订单数据
+            return self.query_first_pay_order(request_dict, response)
+        elif operation == 'repeatPayOrder':  # 查询复购订单数据
+            return self.query_repeat_pay_order(request_dict, response)
+        elif operation == 'global/payOrder':  # 查询全球付费订单数据
+            return self.query_global_pay_order(request, request_dict, response)
+        elif operation == 'global/freeOrder':  # 查询全球免费订单数据
+            return self.query_global_free_order(request, request_dict, response)
+        elif operation == 'global/firstPayOrder':  # 查询全球首次付费订单数据
+            return self.query_global_first_pay_order(request, request_dict, response)
+        elif operation == 'global/repeatPayOrder':  # 查询全球复购订单数据
+            return self.query_global_repeat_pay_order(request, request_dict, response)
+        else:
+            return response.json(414)
+
+    @classmethod
+    def query_pay_order(cls, request_dict, response):
+        """
+        查询付费订单数据
+        @param request_dict:请求参数
+        @request_dict startTime:开始时间
+        @request_dict endTime:结束时间
+        @request_dict timeUnit:时间单位
+        @request_dict storeMealType:套餐类型
+        @param response:响应对象
+        @return:
+        """
+        start_time = request_dict.get('startTime', None)
+        end_time = request_dict.get('endTime', None)
+        time_unit = request_dict.get('timeUnit', None)
+        store_meal_type = request_dict.get('storeMealType', None)
+        if not all([start_time, end_time, time_unit, store_meal_type]):
+            return response.json(444, {'error param': 'startTime or endTime or timeUnit or storeMealType'})
+        try:
+            store_meal_type = int(store_meal_type)
+            order_qs = Order_Model.objects.filter(order_type=store_meal_type, status=1,
+                                                  addTime__range=(start_time, end_time)).filter(
+                ~Q(price='0.00') & ~Q(price='0'))
+            count = order_qs.count()
+            total = order_qs.aggregate(total=Sum('price'))['total']
+            start_time = datetime.datetime.fromtimestamp(int(start_time))
+            end_time = datetime.datetime.fromtimestamp(int(end_time))
+            time_list = CommonService.cutting_time(start_time, end_time, time_unit)
+
+            # 订单数量统计
+            order_list = []
+            for item in time_list:
+                order_temp_qs = order_qs.filter(addTime__range=item)
+                order_dict = {
+                    'count': order_temp_qs.count(),
+                    'startTime': item[0],
+                    'endTime': item[1]
+                }
+                order_list.append(order_dict)
+
+            # 区域订单统计
+            region_list = []
+            region_qs = order_qs.values('userID__region_country').annotate(count=Count('UID')).order_by('-count')
+            for item in region_qs:
+                country_id = item['userID__region_country']
+                country_qs = CountryModel.objects.filter(id=country_id).values('country_name')
+                country_name = country_qs[0]['country_name'] if country_qs.exists() else '未知区域'
+                rate = round(item['count'] / count * 100, 2)
+                region_dict = {
+                    'countryName': country_name,
+                    'count': item['count'],
+                    'rate': rate
+                }
+                region_list.append(region_dict)
+
+            # 设备类型订单统计
+            device_type_list = []
+            device_type_qs = order_qs.values('UID').annotate(count=Count('UID')).order_by('count')
+            uid_list = []
+            uid_type_dict = {}
+            for item in device_type_qs:
+                uid_list.append(item['UID'])
+                device_temp_qs = Device_Info.objects.filter(UID=item['UID']).values('Type')
+                if device_temp_qs.exists():
+                    if device_temp_qs[0]['Type'] not in uid_type_dict:
+                        uid_type_dict[device_temp_qs[0]['Type']] = []
+                    uid_type_dict[device_temp_qs[0]['Type']].append(item['UID'])
+            # device_qs = Device_Info.objects.filter(UID__in=uid_list).values('Type').annotate(
+            #     count=Count('Type', distinct=True)).order_by('-count')
+            for k, v in uid_type_dict.items():
+                type_name = DEVICE_TYPE.get(k, '未知类型')
+                type_name = type_name if type_name != 'UNKOWN' else '未知类型'
+                device_count = order_qs.filter(UID__in=v).count()
+                type_rate = round(device_count / count * 100, 2)
+                temp_total = order_qs.filter(UID__in=v).aggregate(total=Sum('price'))['total']
+                total_rate = round(temp_total / total * 100, 2)
+                device_temp_qs = {
+                    'typeName': type_name,
+                    'count': device_count,
+                    'typeRate': type_rate,
+                    'totalMoney': temp_total,
+                    'totalRate': total_rate
+                }
+                device_type_list.append(device_temp_qs)
+
+            # 套餐订单统计
+            store_meal_list = []
+            if store_meal_type == 0:
+                store_meal_qs = order_qs.values('rank').annotate(count=Count('rank')).order_by('-count')
+            elif store_meal_type == 1:
+                store_meal_qs = order_qs.values('ai_rank').annotate(count=Count('ai_rank')).order_by('-count')
+            else:
+                store_meal_qs = order_qs.values('unify_combo_id').annotate(count=Count('unify_combo_id')).order_by(
+                    '-count')
+            for item in store_meal_qs:
+                if store_meal_type == 0:
+                    store_meal_id = item['rank']
+                    store_meal_content_qs = store_meal_qs.filter(rank=store_meal_id, rank__lang__lang='cn').values(
+                        'rank__lang__content')
+                    store_meal_name = store_meal_content_qs[0][
+                        'rank__lang__content'] if store_meal_content_qs.exists() else '未知套餐'
+                elif store_meal_type == 1:
+                    store_meal_id = item['ai_rank']
+                    store_meal_content_qs = store_meal_qs.filter(ai_rank=store_meal_id,
+                                                                 ai_rank__lang__lang='cn').values(
+                        'ai_rank__lang__content')
+                    store_meal_name = store_meal_content_qs[0][
+                        'ai_rank__lang__content'] if store_meal_content_qs.exists() else '未知套餐'
+                else:
+                    store_meal_id = item['unify_combo_id']
+                    store_meal_content_qs = UnicomCombo.objects.filter(id=store_meal_id).values(
+                        'combo_name')
+                    store_meal_name = store_meal_content_qs[0][
+                        'combo_name'] if store_meal_content_qs.exists() else '未知套餐'
+                rate = round(item['count'] / count * 100, 2)
+                store_meal_dict = {
+                    'storeMealId': store_meal_id,
+                    'count': item['count'],
+                    'storeMealName': store_meal_name,
+                    'rate': rate
+                }
+                store_meal_list.append(store_meal_dict)
+            res = {
+                'orders': order_list,
+                'regions': region_list,
+                'deviceType': device_type_list,
+                'storeMeal': store_meal_list,
+            }
+            return response.json(0, res)
+        except Exception as e:
+            return response.json(500, repr(e))
+
+    @classmethod
+    def query_free_order(cls, request_dict, response):
+        """
+        查询免费订单数据
+        @param request_dict:请求参数
+        @request_dict startTime:开始时间
+        @request_dict endTime:结束时间
+        @request_dict timeUnit:时间单位
+        @request_dict storeMealType:套餐类型
+        @param response:响应对象
+        @return:
+        """
+        start_time = request_dict.get('startTime', None)
+        end_time = request_dict.get('endTime', None)
+        time_unit = request_dict.get('timeUnit', None)
+        store_meal_type = request_dict.get('storeMealType', None)
+        if not all([start_time, end_time, time_unit, store_meal_type]):
+            return response.json(444, {'error param': 'startTime or endTime or timeUnit or storeMealType'})
+        try:
+            store_meal_type = int(store_meal_type)
+            order_qs = Order_Model.objects.filter(order_type=store_meal_type, status=1,
+                                                  addTime__range=(start_time, end_time)).filter(
+                Q(price='0.00') | Q(price='0'))
+            count = order_qs.count()
+            uidset_qs = UidSetModel.objects.filter(addTime__range=(start_time, end_time))
+            start_time = datetime.datetime.fromtimestamp(int(start_time))
+            end_time = datetime.datetime.fromtimestamp(int(end_time))
+            time_list = CommonService.cutting_time(start_time, end_time, time_unit)
+            # 转化率
+            if store_meal_type == 0:
+                uidset_count = uidset_qs.filter(is_vod=1).count()
+            elif store_meal_type == 1:
+                uidset_count = uidset_qs.filter(is_ai=1).count()
+            else:
+                uidset_count = uidset_qs.filter(mobile_4g=1).count()
+            order_device_count = order_qs.values('UID').distinct().order_by('UID').count()
+            inversion_rate = round(order_device_count / uidset_count * 100, 2)
+            # 订单数量统计
+            order_list = []
+            for item in time_list:
+                order_temp_qs = order_qs.filter(addTime__range=item)
+                order_dict = {
+                    'count': order_temp_qs.count(),
+                    'startTime': item[0],
+                    'endTime': item[1]
+                }
+                order_list.append(order_dict)
+
+            # 区域订单统计
+            region_list = []
+            region_qs = order_qs.values('userID__region_country').annotate(count=Count('UID')).order_by('-count')
+            for item in region_qs:
+                country_id = item['userID__region_country']
+                country_qs = CountryModel.objects.filter(id=country_id).values('country_name')
+                country_name = country_qs[0]['country_name'] if country_qs.exists() else '未知区域'
+                rate = round(item['count'] / count * 100, 2)
+                region_dict = {
+                    'countryName': country_name,
+                    'count': item['count'],
+                    'rate': rate
+                }
+                region_list.append(region_dict)
+
+            # 设备类型订单统计
+            device_type_list = []
+            device_type_qs = order_qs.values('UID').annotate(count=Count('UID')).order_by('count')
+            uid_dict = {}
+            for item in device_type_qs:
+                device_qs = Device_Info.objects.filter(UID=item['UID']).values('Type')
+                device_type = device_qs[0]['Type'] if device_qs.exists() else 0
+                if device_type not in uid_dict:
+                    uid_dict[device_type] = []
+                uid_dict[device_type].append(item['UID'])
+
+            for k, v in uid_dict.items():
+                type_name = DEVICE_TYPE.get(k, '未知类型')
+                type_name = type_name if type_name != 'UNKOWN' else '未知类型'
+                device_count = order_qs.filter(UID__in=v).count()
+                type_rate = round(device_count / count * 100, 2)
+                device_temp_qs = {
+                    'typeName': type_name,
+                    'count': device_count,
+                    'typeRate': type_rate,
+                }
+                device_type_list.append(device_temp_qs)
+
+            res = {
+                'orders': order_list,
+                'regions': region_list,
+                'deviceType': device_type_list,
+                'inversionRate': inversion_rate,
+                'newDeviceCount': uidset_count,
+                'orderDeviceCount': order_device_count
+            }
+            return response.json(0, res)
+        except Exception as e:
+            return response.json(500, repr(e))
+
+    @classmethod
+    def query_first_pay_order(cls, request_dict, response):
+        """
+        查询首次付费订单数据
+        @param request_dict:请求参数
+        @request_dict startTime:开始时间
+        @request_dict endTime:结束时间
+        @request_dict timeUnit:时间单位
+        @request_dict storeMealType:套餐类型
+        @param response:响应对象
+        @return:
+        """
+        start_time = request_dict.get('startTime', None)
+        end_time = request_dict.get('endTime', None)
+        time_unit = request_dict.get('timeUnit', None)
+        store_meal_type = request_dict.get('storeMealType', None)
+        if not all([start_time, end_time, time_unit, store_meal_type]):
+            return response.json(444, {'error param': 'startTime or endTime or timeUnit or storeMealType'})
+        try:
+            order_gte_start_time_qs = Order_Model.objects.filter(order_type=store_meal_type, status=1,
+                                                                 addTime__lte=start_time).filter(
+                ~Q(price='0.00') & ~Q(price='0'))
+            uid_list = []
+            for item in order_gte_start_time_qs:
+                uid_list.append(item.UID)
+            order_qs = Order_Model.objects.filter(order_type=store_meal_type, status=1,
+                                                  addTime__range=(start_time, end_time)).filter(~Q(price='0.00'),
+                                                                                                ~Q(UID__in=uid_list),
+                                                                                                ~Q(price='0'))
+            count = order_qs.count()
+            start_time = datetime.datetime.fromtimestamp(int(start_time))
+            end_time = datetime.datetime.fromtimestamp(int(end_time))
+            time_list = CommonService.cutting_time(start_time, end_time, time_unit)
+
+            # 订单数量统计
+            order_list = []
+            for item in time_list:
+                order_temp_qs = order_qs.filter(addTime__range=item)
+                order_dict = {
+                    'count': order_temp_qs.count(),
+                    'startTime': item[0],
+                    'endTime': item[1]
+                }
+                order_list.append(order_dict)
+
+            # 区域订单统计
+            region_list = []
+            region_qs = order_qs.values('userID__region_country').annotate(count=Count('UID')).order_by('-count')
+            for item in region_qs:
+                country_id = item['userID__region_country']
+                country_qs = CountryModel.objects.filter(id=country_id).values('country_name')
+                country_name = country_qs[0]['country_name'] if country_qs.exists() else '未知区域'
+                rate = round(item['count'] / count * 100, 2)
+                region_dict = {
+                    'countryName': country_name,
+                    'count': item['count'],
+                    'rate': rate
+                }
+                region_list.append(region_dict)
+
+            # 设备类型订单统计
+            device_type_list = []
+            device_type_qs = order_qs.values('UID').annotate(count=Count('UID')).order_by('count')
+            uid_dict = {}
+            for item in device_type_qs:
+                device_qs = Device_Info.objects.filter(UID=item['UID']).values('Type')
+                device_type = device_qs[0]['Type'] if device_qs.exists() else 0
+                if device_type not in uid_dict:
+                    uid_dict[device_type] = []
+                uid_dict[device_type].append(item['UID'])
+            for k, v in uid_dict.items():
+                type_name = DEVICE_TYPE.get(k, '未知类型')
+                type_name = type_name if type_name != 'UNKOWN' else '未知类型'
+                device_count = order_qs.filter(UID__in=v).count()
+                type_rate = round(device_count / count * 100, 2)
+                device_temp_qs = {
+                    'typeName': type_name,
+                    'count': device_count,
+                    'typeRate': type_rate,
+                }
+                device_type_list.append(device_temp_qs)
+
+            res = {
+                'orders': order_list,
+                'regions': region_list,
+                'deviceType': device_type_list,
+            }
+            return response.json(0, res)
+        except Exception as e:
+            return response.json(500, repr(e))
+
+    @classmethod
+    def query_repeat_pay_order(cls, request_dict, response):
+        """
+        查询复购订单数据
+        @param request_dict:请求参数
+        @request_dict startTime:开始时间
+        @request_dict endTime:结束时间
+        @request_dict timeUnit:时间单位
+        @request_dict storeMealType:套餐类型
+        @param response:响应对象
+        @return:
+        """
+        start_time = request_dict.get('startTime', None)
+        end_time = request_dict.get('endTime', None)
+        time_unit = request_dict.get('timeUnit', None)
+        store_meal_type = request_dict.get('storeMealType', None)
+        if not all([start_time, end_time, time_unit, store_meal_type]):
+            return response.json(444, {'error param': 'startTime or endTime or timeUnit or storeMealType'})
+        try:
+            order_gte_start_time_qs = Order_Model.objects.filter(order_type=store_meal_type, status=1,
+                                                                 addTime__lte=start_time).filter(
+                ~Q(price='0.00') & ~Q(price='0'))
+            uid_list = []
+            for item in order_gte_start_time_qs:
+                uid_list.append(item.UID)
+            order_qs = Order_Model.objects.filter(order_type=store_meal_type, status=1,
+                                                  addTime__range=(start_time, end_time)).filter(
+                ~Q(price='0.00'), ~Q(price='0'), Q(UID__in=uid_list))
+            total = order_qs.count()
+
+            # 订单复购率
+            count = order_qs.count()
+            repeat_rate = round(count / total * 100, 2)
+
+            start_time = datetime.datetime.fromtimestamp(int(start_time))
+            end_time = datetime.datetime.fromtimestamp(int(end_time))
+            time_list = CommonService.cutting_time(start_time, end_time, time_unit)
+            # 订单数量统计
+            order_list = []
+            for item in time_list:
+                order_temp_qs = order_qs.filter(addTime__range=item)
+                order_dict = {
+                    'count': order_temp_qs.count(),
+                    'startTime': item[0],
+                    'endTime': item[1]
+                }
+                order_list.append(order_dict)
+
+            # 区域订单统计
+            region_list = []
+            region_qs = order_qs.values('userID__region_country').annotate(count=Count('UID')).order_by('-count')
+            for item in region_qs:
+                country_id = item['userID__region_country']
+                country_qs = CountryModel.objects.filter(id=country_id).values('country_name')
+                country_name = country_qs[0]['country_name'] if country_qs.exists() else '未知区域'
+                rate = round(item['count'] / count * 100, 2)
+                region_dict = {
+                    'countryName': country_name,
+                    'count': item['count'],
+                    'rate': rate
+                }
+                region_list.append(region_dict)
+
+            # 设备类型订单统计
+            device_type_list = []
+            device_type_qs = order_qs.values('UID').annotate(count=Count('UID')).order_by('count')
+            uid_dict = {}
+            for item in device_type_qs:
+                device_qs = Device_Info.objects.filter(UID=item['UID']).values('Type')
+                device_type = device_qs[0]['Type'] if device_qs.exists() else 0
+                if device_type not in uid_dict:
+                    uid_dict[device_type] = []
+                uid_dict[device_type].append(item['UID'])
+            for k, v in uid_dict.items():
+                type_name = DEVICE_TYPE.get(k, '未知类型')
+                type_name = type_name if type_name != 'UNKOWN' else '未知类型'
+                device_count = order_qs.filter(UID__in=v).count()
+                type_rate = round(device_count / count * 100, 2)
+                device_temp_qs = {
+                    'typeName': type_name,
+                    'count': device_count,
+                    'typeRate': type_rate,
+                }
+                device_type_list.append(device_temp_qs)
+
+            res = {
+                'orders': order_list,
+                'regions': region_list,
+                'deviceType': device_type_list,
+                'repeatRate': repeat_rate,
+                'repeatCount': count,
+                'orderCount': total
+            }
+            return response.json(0, res)
+        except Exception as e:
+            return response.json(500, repr(e))
+
+    @classmethod
+    def query_global_pay_order(cls, request, request_dict, response):
+        """
+        查询全球付费订单数据
+        @param request:请求
+        @param request_dict:请求参数
+        @param response:响应对象
+        @return:
+        """
+        url_list = CommonService.get_domain_name()
+        try:
+            headers = {
+                'Authorization': request.META.get('HTTP_AUTHORIZATION')
+            }
+            order_list = []
+            region_list = []
+            region_count = 0
+            device_type_list = []
+            device_type_count = 0
+            device_type_total = 0
+            store_meal_list = []
+            store_meal_count = 0
+            for url in url_list:
+                url = url + request.path.replace('global/', '')
+                res = requests.get(url=url, params=request_dict, headers=headers)
+                result = res.json()
+                if result['result_code'] == 0:
+                    # 处理订单
+                    for item in result['result']['orders']:
+                        flag = 0
+                        for each in order_list:
+                            if each['startTime'] == item['startTime'] and each['endTime'] == item['endTime']:
+                                each['count'] += int(item['count'])
+                                flag = 1
+                                break
+                        if flag == 0:
+                            order_list.append(item)
+                    # 处理地区
+                    for item in result['result']['regions']:
+                        flag = 0
+                        for each in region_list:
+                            if each['countryName'] == item['countryName']:
+                                each['count'] += int(item['count'])
+                                region_count += int(item['count'])
+                                flag = 1
+                                break
+                        if flag == 0:
+                            region_list.append(item)
+                            region_count += int(item['count'])
+                    for item in region_list:
+                        rate = round(item['count'] / region_count * 100, 2)
+                        item['rate'] = rate
+                    # 处理设备类型
+                    for item in result['result']['deviceType']:
+                        flag = 0
+                        for each in device_type_list:
+                            if each['typeName'] == item['typeName']:
+                                each['count'] += int(item['count'])
+                                item['totalMoney'] += item['totalMoney']
+                                device_type_count += int(item['count'])
+                                device_type_total += item['totalMoney']
+                                flag = 1
+                                break
+                        if flag == 0:
+                            device_type_list.append(item)
+                            device_type_count += int(item['count'])
+                            device_type_total += item['totalMoney']
+                    for item in device_type_list:
+                        type_rate = round(item['count'] / device_type_count * 100, 2)
+                        total_rate = round(item['totalMoney'] / device_type_total * 100, 2)
+                        item['typeRate'] = type_rate
+                        item['totalRate'] = total_rate
+                    # 处理套餐
+                    for item in result['result']['storeMeal']:
+                        flag = 0
+                        for each in store_meal_list:
+                            if each['storeMealId'] == item['storeMealId']:
+                                each['count'] += int(item['count'])
+                                store_meal_count += int(item['count'])
+                                flag = 1
+                                break
+                        if flag == 0:
+                            store_meal_list.append(item)
+                            store_meal_count += int(item['count'])
+                    for item in store_meal_list:
+                        rate = round(item['count'] / store_meal_count * 100, 2)
+                        item['rate'] = rate
+                else:
+                    return response.json(result['result_code'])
+            res = {
+                'orders': order_list,
+                'regions': CommonService.list_sort(region_list),
+                'deviceType': CommonService.list_sort(device_type_list),
+                'storeMeal': CommonService.list_sort(store_meal_list)
+            }
+            return response.json(0, res)
+        except Exception as e:
+            return response.json(500, repr(e))
+
+    @classmethod
+    def query_global_free_order(cls, request, request_dict, response):
+        """
+        查询全球免费订单数据
+        @param request:请求
+        @param request_dict:请求参数
+        @param response:响应对象
+        @return:
+        """
+        url_list = CommonService.get_domain_name()
+        try:
+            headers = {
+                'Authorization': request.META.get('HTTP_AUTHORIZATION')
+            }
+            order_list = []
+            region_list = []
+            region_count = 0
+            device_type_list = []
+            device_type_count = 0
+            new_device_count = 0
+            order_device_count = 0
+            for url in url_list:
+                url = url + request.path.replace('global/', '')
+                res = requests.get(url=url, params=request_dict, headers=headers)
+                result = res.json()
+                if result['result_code'] == 0:
+                    # 处理订单
+                    for item in result['result']['orders']:
+                        flag = 0
+                        for each in order_list:
+                            if each['startTime'] == item['startTime'] and each['endTime'] == item['endTime']:
+                                each['count'] += int(item['count'])
+                                flag = 1
+                                break
+                        if flag == 0:
+                            order_list.append(item)
+                    # 处理地区
+                    for item in result['result']['regions']:
+                        flag = 0
+                        for each in region_list:
+                            if each['countryName'] == item['countryName']:
+                                each['count'] += int(item['count'])
+                                region_count += int(item['count'])
+                                flag = 1
+                                break
+                        if flag == 0:
+                            region_list.append(item)
+                            region_count += int(item['count'])
+                    for item in region_list:
+                        rate = round(item['count'] / region_count * 100, 2)
+                        item['rate'] = rate
+                    # 处理设备类型
+                    for item in result['result']['deviceType']:
+                        flag = 0
+                        for each in device_type_list:
+                            if each['typeName'] == item['typeName']:
+                                each['count'] += int(item['count'])
+                                device_type_count += int(item['count'])
+                                flag = 1
+                                break
+                        if flag == 0:
+                            device_type_list.append(item)
+                            device_type_count += int(item['count'])
+                    for item in device_type_list:
+                        type_rate = round(item['count'] / device_type_count * 100, 2)
+                        item['typeRate'] = type_rate
+                    # 处理转化率
+                    new_device_count += int(result['result']['newDeviceCount'])
+                    order_device_count += int(result['result']['orderDeviceCount'])
+                else:
+                    return response.json(result['result_code'])
+            inversion_rate = round(order_device_count / new_device_count * 100, 2)
+            res = {
+                'orders': order_list,
+                'regions': CommonService.list_sort(region_list),
+                'deviceType': CommonService.list_sort(device_type_list),
+                'newDeviceCount': new_device_count,
+                'orderDeviceCount': order_device_count,
+                'inversionRate': inversion_rate
+            }
+            return response.json(0, res)
+        except Exception as e:
+            return response.json(500, repr(e))
+
+    @classmethod
+    def query_global_first_pay_order(cls, request, request_dict, response):
+        """
+        查询全球首次付费订单数据
+        @param request:请求
+        @param request_dict:请求参数
+        @param response:响应对象
+        @return:
+        """
+        url_list = CommonService.get_domain_name()
+        try:
+            headers = {
+                'Authorization': request.META.get('HTTP_AUTHORIZATION')
+            }
+            order_list = []
+            region_list = []
+            region_count = 0
+            device_type_list = []
+            device_type_count = 0
+            for url in url_list:
+                url = url + request.path.replace('global/', '')
+                res = requests.get(url=url, params=request_dict, headers=headers)
+                result = res.json()
+                if result['result_code'] == 0:
+                    # 处理订单
+                    for item in result['result']['orders']:
+                        flag = 0
+                        for each in order_list:
+                            if each['startTime'] == item['startTime'] and each['endTime'] == item['endTime']:
+                                each['count'] += int(item['count'])
+                                flag = 1
+                                break
+                        if flag == 0:
+                            order_list.append(item)
+                    # 处理地区
+                    for item in result['result']['regions']:
+                        flag = 0
+                        for each in region_list:
+                            if each['countryName'] == item['countryName']:
+                                each['count'] += int(item['count'])
+                                region_count += int(item['count'])
+                                flag = 1
+                                break
+                        if flag == 0:
+                            region_list.append(item)
+                            region_count += int(item['count'])
+                    for item in region_list:
+                        rate = round(item['count'] / region_count * 100, 2)
+                        item['rate'] = rate
+                    # 处理设备类型
+                    for item in result['result']['deviceType']:
+                        flag = 0
+                        for each in device_type_list:
+                            if each['typeName'] == item['typeName']:
+                                each['count'] += int(item['count'])
+                                device_type_count += int(item['count'])
+                                flag = 1
+                                break
+                        if flag == 0:
+                            device_type_list.append(item)
+                            device_type_count += int(item['count'])
+                    for item in device_type_list:
+                        type_rate = round(item['count'] / device_type_count * 100, 2)
+                        item['typeRate'] = type_rate
+                else:
+                    return response.json(result['result_code'])
+            res = {
+                'orders': order_list,
+                'regions': CommonService.list_sort(region_list),
+                'deviceType': CommonService.list_sort(device_type_list),
+            }
+            return response.json(0, res)
+        except Exception as e:
+            return response.json(500, repr(e))
+
+    @classmethod
+    def query_global_repeat_pay_order(cls, request, request_dict, response):
+        """
+        查询全球复购订单数据
+        @param request:请求
+        @param request_dict:请求参数
+        @param response:响应对象
+        @return:
+        """
+        url_list = CommonService.get_domain_name()
+        try:
+            headers = {
+                'Authorization': request.META.get('HTTP_AUTHORIZATION')
+            }
+            order_list = []
+            region_list = []
+            region_count = 0
+            device_type_list = []
+            device_type_count = 0
+            repeat_count = 0
+            order_count = 0
+            for url in url_list:
+                url = url + request.path.replace('global/', '')
+                res = requests.get(url=url, params=request_dict, headers=headers)
+                result = res.json()
+                if result['result_code'] == 0:
+                    # 处理订单
+                    for item in result['result']['orders']:
+                        flag = 0
+                        for each in order_list:
+                            if each['startTime'] == item['startTime'] and each['endTime'] == item['endTime']:
+                                each['count'] += int(item['count'])
+                                flag = 1
+                                break
+                        if flag == 0:
+                            order_list.append(item)
+                    # 处理地区
+                    for item in result['result']['regions']:
+                        flag = 0
+                        for each in region_list:
+                            if each['countryName'] == item['countryName']:
+                                each['count'] += int(item['count'])
+                                region_count += int(item['count'])
+                                flag = 1
+                                break
+                        if flag == 0:
+                            region_list.append(item)
+                            region_count += int(item['count'])
+                    for item in region_list:
+                        rate = round(item['count'] / region_count * 100, 2)
+                        item['rate'] = rate
+                    # 处理设备类型
+                    for item in result['result']['deviceType']:
+                        flag = 0
+                        for each in device_type_list:
+                            if each['typeName'] == item['typeName']:
+                                each['count'] += int(item['count'])
+                                device_type_count += int(item['count'])
+                                flag = 1
+                                break
+                        if flag == 0:
+                            device_type_list.append(item)
+                            device_type_count += int(item['count'])
+                    for item in device_type_list:
+                        type_rate = round(item['count'] / device_type_count * 100, 2)
+                        item['typeRate'] = type_rate
+                    # 处理订单复购率
+                    repeat_count += result['result']['repeatCount']
+                    order_count += result['result']['orderCount']
+                else:
+                    return response.json(result['result_code'])
+            repeat_rate = round(repeat_count / order_count * 100, 2)
+            res = {
+                'orders': order_list,
+                'regions': CommonService.list_sort(region_list),
+                'deviceType': CommonService.list_sort(device_type_list),
+                'repeatRate': repeat_rate,
+                'repeatCount': repeat_count,
+                'orderCount': order_count
+            }
+            return response.json(0, res)
+        except Exception as e:
+            return response.json(500, repr(e))

+ 378 - 0
AdminController/dataSystemManagement/UserDataController.py

@@ -0,0 +1,378 @@
+# -*- encoding: utf-8 -*-
+"""
+@File    : UserDataController.py
+@Time    : 2022/8/16 10:44
+@Author  : peng
+@Email   : zhangdongming@asj6.wecom.work
+@Software: PyCharm
+"""
+
+from django.db.models import Count
+from django.views.generic.base import View
+import datetime
+import requests
+
+from Model.models import Device_User, CountryModel
+from Service.CommonService import CommonService
+
+
+# 用户数据
+class UserDataView(View):
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.GET, request, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.POST, request, operation)
+
+    def validation(self, request_dict, request, operation):
+        token_code, user_id, response = CommonService.verify_token_get_user_id(request_dict, request)
+        if token_code != 0:
+            return response.json(token_code)
+        if operation == 'increase':  # 查询用户新增数据
+            return self.user_increase(request_dict, response)
+        elif operation == 'active':  # 查询用户活跃数据
+            return self.user_active(request_dict, response)
+        elif operation == 'region':  # 查询用户地区分布
+            return self.user_region(response)
+        elif operation == 'global/increase':  # 查询全球用户新增数据
+            return self.global_user_increase(request, request_dict, response)
+        elif operation == 'global/active':  # 查询全球用户活跃数据
+            return self.global_user_active(request, request_dict, response)
+        elif operation == 'global/region':  # 查询全球用户地区分布
+            return self.global_user_region(request, response)
+        else:
+            return response.json(414)
+
+    @classmethod
+    def user_increase(cls, request_dict, response):
+        """
+        查询用户增长数据
+        @param request_dict:请求参数
+        @request_dict startTime:开始时间
+        @request_dict endTime:结束时间
+        @request_dict timeUnit:时间单位
+        @param response:响应对象
+        @return:
+        """
+        start_time = request_dict.get('startTime', None)
+        end_time = request_dict.get('endTime', None)
+        time_unit = request_dict.get('timeUnit', None)
+        if not all([start_time, end_time, time_unit]):
+            return response.json(444, {'error param': 'startTime or endTime or timeUnit'})
+        start_time = datetime.datetime.fromtimestamp(int(start_time))
+        end_time = datetime.datetime.fromtimestamp(int(end_time))
+        time_list = CommonService.cutting_time(start_time, end_time, time_unit)
+        try:
+            user_qs = Device_User.objects.filter(data_joined__range=(start_time, end_time))
+            user_list = []
+            count = user_qs.count()
+            for item in time_list:
+                s_time = datetime.datetime.fromtimestamp(int(item[0]))
+                e_time = datetime.datetime.fromtimestamp(int(item[1]))
+                user_date_qs = user_qs.filter(last_login__range=(s_time, e_time))
+                rate = round(user_date_qs.count() / count * 100, 2)
+                user_dict = {
+                    'count': user_date_qs.count(),
+                    'rate': rate,
+                    'startTime': item[0],
+                    'endTime': item[1]
+                }
+                user_list.append(user_dict)
+            user_country_qs = user_qs.values('region_country').annotate(count=Count('region_country')).order_by(
+                '-count')
+            region_list = []
+            for item in user_country_qs:
+                country_id = item['region_country']
+                country_qs = CountryModel.objects.filter(id=country_id).values('country_name')
+                country_name = country_qs[0]['country_name'] if country_qs.exists() else '未知区域'
+                rate = round(item['count'] / count * 100, 2)
+                country_dict = {
+                    'countryName': country_name,
+                    'count': item['count'],
+                    'rate': rate
+                }
+                region_list.append(country_dict)
+            res = {
+                'user': user_list,
+                'region': region_list
+            }
+            return response.json(0, res)
+        except Exception as e:
+            return response.json(500, repr(e))
+
+    @classmethod
+    def user_active(cls, request_dict, response):
+        """
+        查询用户活跃数据
+        @param request_dict:请求参数
+        @request_dict startTime:开始时间
+        @request_dict endTime:结束时间
+        @request_dict timeUnit:时间单位
+        @param response:响应对象
+        @return:
+        """
+        start_time = request_dict.get('startTime', None)
+        end_time = request_dict.get('endTime', None)
+        time_unit = request_dict.get('timeUnit', None)
+        if not all([start_time, end_time, time_unit]):
+            return response.json(444, {'error param': 'startTime or endTime or timeUnit'})
+        start_time = datetime.datetime.fromtimestamp(int(start_time))
+        end_time = datetime.datetime.fromtimestamp(int(end_time))
+        time_list = CommonService.cutting_time(start_time, end_time, time_unit)
+        try:
+            user_qs = Device_User.objects.filter(last_login__range=(start_time, end_time))
+            user_list = []
+            count = user_qs.count()
+            for item in time_list:
+                s_time = datetime.datetime.fromtimestamp(int(item[0]))
+                e_time = datetime.datetime.fromtimestamp(int(item[1]))
+                user_date_qs = user_qs.filter(last_login__range=(s_time, e_time))
+                rate = round(user_date_qs.count() / count * 100, 2)
+                user_dict = {
+                    'count': user_date_qs.count(),
+                    'rate': rate,
+                    'startTime': item[0],
+                    'endTime': item[1]
+                }
+                user_list.append(user_dict)
+            user_country_qs = user_qs.values('region_country').annotate(count=Count('region_country')).order_by(
+                '-count')
+            region_list = []
+            for item in user_country_qs:
+                country_id = item['region_country']
+                country_qs = CountryModel.objects.filter(id=country_id).values('country_name')
+                country_name = country_qs[0]['country_name'] if country_qs.exists() else '未知区域'
+                rate = round(item['count'] / count * 100, 2)
+                country_dict = {
+                    'countryName': country_name,
+                    'count': item['count'],
+                    'rate': rate
+                }
+                region_list.append(country_dict)
+            res = {
+                'user': user_list,
+                'region': region_list
+            }
+            return response.json(0, res)
+        except Exception as e:
+            return response.json(500, repr(e))
+
+    @classmethod
+    def user_region(cls, response):
+        """
+        查询用户地区分布
+        @param response:响应对象
+        @return:
+        """
+        res = {
+            'countries': [],
+        }
+        try:
+            user_qs = Device_User.objects.all()
+            count = user_qs.count()
+            user_qs = user_qs.values('region_country').annotate(count=Count('region_country')).order_by('-count')
+            continent_list = []
+            for item in user_qs:
+                country_id = item['region_country']
+                country_qs = CountryModel.objects.filter(id=country_id).values('country_name', 'region__name')
+                item['countryName'] = country_qs[0]['country_name'] if country_qs.exists() else '未知区域'
+                item['rate'] = round(item['count'] / count * 100, 2)
+                if country_qs.exists():
+                    flag = 0
+                    for each in continent_list:
+                        if country_qs[0]['region__name'] == each['continentName']:
+                            each['count'] += item['count']
+                            flag = 1
+                            break
+                    if flag == 0:
+                        continent_list.append({
+                            'continentName': country_qs[0]['region__name'],
+                            'count': item['count']
+                        })
+            for item in continent_list:
+                item['rate'] = round(item['count'] / count * 100, 2)
+            res['countries'] = list(user_qs)
+            res['continent'] = continent_list
+            return response.json(0, res)
+        except Exception as e:
+            return response.json(500, repr(e))
+
+    @classmethod
+    def global_user_increase(cls, request, request_dict, response):
+        """
+        查询全球用户新增数据
+        @param request:请求
+        @param request_dict:请求参数
+        @param response:响应对象
+        @return:
+        """
+        url_list = CommonService.get_domain_name()
+        try:
+            headers = {
+                'Authorization': request.META.get('HTTP_AUTHORIZATION')
+            }
+            user_list = []
+            user_count = 0
+            region_list = []
+            region_count = 0
+            for url in url_list:
+                url = url + request.path.replace('global/', '')
+                res = requests.get(url=url, params=request_dict, headers=headers)
+                result = res.json()
+                if result['result_code'] == 0:
+                    for item in result['result']['user']:
+                        flag = 0
+                        for each in user_list:
+                            if item['startTime'] == each['startTime'] and item['endTime'] == each['endTime']:
+                                each['count'] += item['count']
+                                user_count += item['count']
+                                flag = 1
+                                break
+                        if flag == 0:
+                            user_list.append(item)
+                            user_count += item['count']
+                    for item in user_list:
+                        item['rate'] = round(item['count'] / user_count * 100, 2)
+                    for item in result['result']['region']:
+                        flag = 0
+                        for each in region_list:
+                            if item['countryName'] == each['countryName']:
+                                each['count'] += item['count']
+                                region_count += item['count']
+                                flag = 1
+                                break
+                        if flag == 0:
+                            region_list.append(item)
+                            region_count += item['count']
+                    for item in region_list:
+                        item['rate'] = round(item['count'] / region_count * 100, 2)
+                else:
+                    return response.json(result['result_code'])
+            res = {
+                'user': user_list,
+                'region': CommonService.list_sort(region_list)
+            }
+            return response.json(0, res)
+        except Exception as e:
+            return response.json(500, repr(e))
+
+    @classmethod
+    def global_user_active(cls, request, request_dict, response):
+        """
+        查询全球用户活跃数据
+        @param request:请求
+        @param request_dict:请求参数
+        @param response:响应对象
+        @return:
+        """
+        url_list = CommonService.get_domain_name()
+        try:
+            headers = {
+                'Authorization': request.META.get('HTTP_AUTHORIZATION')
+            }
+            user_list = []
+            user_count = 0
+            region_list = []
+            region_count = 0
+            for url in url_list:
+                url = url + request.path.replace('global/', '')
+                res = requests.get(url=url, params=request_dict, headers=headers)
+                result = res.json()
+                if result['result_code'] == 0:
+                    for item in result['result']['user']:
+                        flag = 0
+                        for each in user_list:
+                            if item['startTime'] == each['startTime'] and item['endTime'] == each['endTime']:
+                                each['count'] += item['count']
+                                user_count += item['count']
+                                flag = 1
+                                break
+                        if flag == 0:
+                            user_list.append(item)
+                            user_count += item['count']
+                    for item in user_list:
+                        item['rate'] = round(item['count'] / user_count * 100, 2)
+                    for item in result['result']['region']:
+                        flag = 0
+                        for each in region_list:
+                            if item['countryName'] == each['countryName']:
+                                each['count'] += item['count']
+                                region_count += item['count']
+                                flag = 1
+                                break
+                        if flag == 0:
+                            region_list.append(item)
+                            region_count += item['count']
+                    for item in region_list:
+                        item['rate'] = round(item['count'] / region_count * 100, 2)
+                else:
+                    return response.json(result['result_code'])
+            res = {
+                'user': user_list,
+                'region': CommonService.list_sort(region_list)
+            }
+            return response.json(0, res)
+        except Exception as e:
+            return response.json(500, repr(e))
+
+    @classmethod
+    def global_user_region(cls, request, response):
+        """
+        查询全球用户地区分布
+        @param request:请求
+        @param response:响应对象
+        @return:
+        """
+        url_list = CommonService.get_domain_name()
+        try:
+            headers = {
+                'Authorization': request.META.get('HTTP_AUTHORIZATION')
+            }
+            user_list = []
+            region_list = []
+            user_count = 0
+            for url in url_list:
+                url = url + request.path.replace('global/', '')
+                res = requests.get(url=url, headers=headers)
+                result = res.json()
+                if result['result_code'] == 0:
+                    # 处理地区
+                    for item in result['result']['countries']:
+                        flag = 0
+                        for each in user_list:
+                            if each['countryName'] == item['countryName']:
+                                each['count'] += int(item['count'])
+                                user_count += int(item['count'])
+                                flag = 1
+                                break
+                        if flag == 0:
+                            user_list.append(item)
+                            user_count += int(item['count'])
+                    for item in user_list:
+                        rate = round(item['count'] / user_count * 100, 2)
+                        item['rate'] = rate
+                    for item in result['result']['continent']:
+                        flag = 0
+                        for each in region_list:
+                            if each['continentName'] == item['continentName']:
+                                each['count'] += item['count']
+                                flag = 1
+                                break
+                        if flag == 0:
+                            region_list.append(item)
+                    for item in region_list:
+                        item['rate'] = round(item['count'] / user_count * 100, 2)
+                else:
+                    return response.json(result['result_code'])
+            res = {
+                'countries': CommonService.list_sort(user_list[:20]),
+                'continent': CommonService.list_sort(region_list)
+            }
+            return response.json(0, res)
+        except Exception as e:
+            return response.json(500, repr(e))

+ 3 - 0
Ansjer/config.py

@@ -101,6 +101,9 @@ elif SERVER_TYPE == 'Ansjer.us_config.test_settings':
     from Ansjer.us_config.config_test import *
 elif SERVER_TYPE == 'Ansjer.us_config.formal_settings':
     from Ansjer.us_config.config_formal import *
+# 欧洲
+elif SERVER_TYPE == 'Ansjer.eur_config.formal_settings':
+    from Ansjer.eur_config.config_formal import *
 
 # 国内
 elif SERVER_TYPE == 'Ansjer.cn_config.formal_settings':

+ 13 - 3
Ansjer/eur_config/config_formal.py

@@ -20,8 +20,8 @@ NGINX_RTMP_STAT = 'http://www.dvema.com/stat'
 SERVER_DOMAIN_SSL = 'https://www.dvema.com/'
 SERVER_DOMAIN = 'http://www.dvema.com/'
 DOMAIN_HOST = 'www.dvema.com'
-SERVER_HOST = 'backendserver.5tgle2.0001.usw1.cache.amazonaws.com'
-PUSH_REDIS_ADDRESS = 'pushredis.5tgle2.0001.usw1.cache.amazonaws.com'
+SERVER_HOST = 'server-redis.av1kep.ng.0001.euw1.cache.amazonaws.com'
+PUSH_REDIS_ADDRESS = 'push-redis.av1kep.ng.0001.euw1.cache.amazonaws.com'
 # PAYPAL_CRD = {
 #     "mode": "live",  # sandbox or live
 #     "client_id": "AdSRd6WBn-qLl9OiQHQuNYTDFSx0ZX0RUttqa58au8bPzoGYQUrt8bc6591RmH8_pEAIPijdvVYSVXyI",
@@ -133,4 +133,14 @@ APNS_MODE = 'prod'
 BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
 SERVER_TYPE = os.environ.get('DJANGO_SETTINGS_MODULE')
 
-TUTK_PUSH_DOMAIN = 'http://push.iotcplatform.com/tpns'
+TUTK_PUSH_DOMAIN = 'http://push.iotcplatform.com/tpns'
+
+# aws api key
+AWS_ARN_S3 = 'arn:aws:s3'
+REGION_NAME = 'us-east-1'
+ACCESS_KEY_ID = 'AKIA2E67UIMD45Y3HL53'
+SECRET_ACCESS_KEY = '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'
+
+# 存储桶名
+AVATAR_BUCKET = 'avatar-us'         # 头像存储桶
+LOG_BUCKET = 'ansjer-statres'       # 日志存储桶

+ 5 - 5
Ansjer/eur_config/formal_settings.py

@@ -70,19 +70,19 @@ TEMPLATES = [
     },
 ]
 
-WSGI_APPLICATION = 'Ansjer.us_config.formal_wsgi.application'
+WSGI_APPLICATION = 'Ansjer.eur_config.formal_wsgi.application'
 
 
 # 服务器类型
 DATABASE_DATA = 'Ansjer81'
-SERVER_HOST = 'database-2.clraczw4p0yj.us-west-1.rds.amazonaws.com'
+SERVER_HOST = 'server-eur.chi0brrjyz8l.eu-west-1.rds.amazonaws.com'
 DATABASES_USER = 'azrds'
-DATABASES_PASS = 'azrds.x.x'
+DATABASES_PASS = '47vo87fikT19cekVoSq1'
 
 DATABASE_DATA2 = 'Ansjer81'
-SERVER_HOST2 = 'ansjerpush.clraczw4p0yj.us-west-1.rds.amazonaws.com'
+SERVER_HOST2 = 'push-eur.chi0brrjyz8l.eu-west-1.rds.amazonaws.com'
 DATABASES_USER2 = 'azrds'
-DATABASES_PASS2 = 'azrds.x.x'
+DATABASES_PASS2 = '5T0LVKsXwHFkYNTTa5UG'
 
 DATABASES = {
     'default': {

+ 20 - 0
Ansjer/server_urls/datasystem_url.py

@@ -0,0 +1,20 @@
+# -*- encoding: utf-8 -*-
+"""
+@File    : datasysytem_url.py
+@Time    : 2022/8/16 10:38
+@Author  : peng
+@Email   : zhangdongming@asj6.wecom.work
+@Software: PyCharm
+"""
+from django.urls import re_path
+
+from AdminController.dataSystemManagement import UserDataController, DeviceDataController, ServiceDataController, \
+    BusinessDataController, HomeDataController
+
+urlpatterns = [
+    re_path(r'^userData/(?P<operation>.*)$', UserDataController.UserDataView.as_view()),
+    re_path(r'^deviceData/(?P<operation>.*)$', DeviceDataController.DeviceDataView.as_view()),
+    re_path(r'^serviceData/(?P<operation>.*)$', ServiceDataController.ServiceDataView.as_view()),
+    re_path(r'^businessData/(?P<operation>.*)$', BusinessDataController.BusinessDataView.as_view()),
+    re_path(r'^homeData/(?P<operation>.*)$', HomeDataController.HomeDataView.as_view()),
+]

+ 3 - 16
Ansjer/urls.py

@@ -21,7 +21,7 @@ from Controller import FeedBack, EquipmentOTA, EquipmentInfo, AdminManage, AppIn
     VerifyCodeController, FileController, UIDController, LogController, SalesController, \
     OrderTaskController, HistoryUIDController, UIDManageUserController, SerialNumberController, CompanyController, \
     RegionController, VPGController, LanguageController, TestController, DeviceConfirmRegion, S3GetStsController, \
-    DetectControllerV2, ShadowController, TestDetectController, PcInfo, PctestController, DeviceDebug, PaymentCycle, \
+    DetectControllerV2, PcInfo, PctestController, DeviceDebug, PaymentCycle, \
     DeviceLogController, CouponController, AiController
 from Controller.Cron import CronTaskController
 from Controller.MessagePush import EquipmentMessagePush
@@ -160,16 +160,9 @@ urlpatterns = [
     url(r'^v3/account/loginByFingerprint$', UserController.v3LoginByFingerprintView.as_view()),
     url(r'^v3/account/setFingerprint$', UserController.v3SetFingerprintView.as_view()),
 
-    url(r'^detect/detect_group_push$', DetectController.NotificationView.detect_group_push),
-    url(r'^detect/add$', DetectController.PushNotificationView.as_view()),
     # 推送项目接口
     url(r'^detect/(?P<operation>.*)$', DetectController.DetectControllerView.as_view()),
-    url(r'^notify/push$', DetectController.NotificationView.as_view()),
     url(r'^detectV2/(?P<operation>.*)$', DetectControllerV2.DetectControllerViewV2.as_view()),
-    url(r'^notifyV2/push$', DetectControllerV2.NotificationView.as_view()),
-    url(r'^deviceShadow/update$', ShadowController.update_device_shadow),
-    url(r'^deviceShadow/generateUTK$', ShadowController.generate_utk),
-    url(r'^test/notify/push$', TestDetectController.NotificationView.as_view()),
 
     # 新增
     url(r'^cloudVod/(?P<operation>.*)$', CloudVod.CloudVodView.as_view()),
@@ -200,8 +193,6 @@ urlpatterns = [
 
     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()),
@@ -296,15 +287,9 @@ urlpatterns = [
     url(r'^cdk/(?P<operation>.*)$', CDKController.CDKView.as_view()),
     # 云存转移功能
     url(r'^cloudTransfer/(?P<operation>.*)$', CloudTransfer.cloudTestView.as_view()),
-
     # 优惠券
     url(r'^coupon/(?P<operation>.*)$', CouponController.CouponView.as_view()),
 
-    # app 设备消息模板
-    # 路由加参数参考
-    # url(r'^(?P<path>.*)/(?P<UID>.*)/lls$', Test.Test.as_view(), name=u'gg'),
-    # testing....................
-
     # 云存服务统计
     url(r'^Cloudsum/(?P<operation>.*)$', Cloudsum.Cloudsum.as_view()),
     # 设备ip地区统计
@@ -400,6 +385,8 @@ urlpatterns = [
     re_path(r'surveys/(?P<operation>.*)', SurveysManageController.SurveysView.as_view()),
     # 序列号管理
     re_path(r'serial/(?P<operation>.*)', SerialManageController.SerialView.as_view()),
+    # 数据系统模块
+    re_path(r'^dataManagement/', include("Ansjer.server_urls.datasystem_url")),
     # 后台界面接口 -----------------------------------------------------
 
     # 定时删除任务接口

+ 14 - 6
Controller/CloudTransfer.py

@@ -6,16 +6,17 @@
 @IDE :PyCharm
 """
 import time
+
 from django.db import transaction
+from django.db.models import Q
 from django.views.generic.base import View
 
+from Model.models import Device_User, Device_Info, Order_Model, UID_Bucket, StsCrdModel, VodHlsModel, Unused_Uid_Meal, \
+    VodBucketModel, UnicomDeviceInfo
+from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Service.CommonService import CommonService
 from Service.ModelService import ModelService
-from Object.ResponseObject import ResponseObject
-from django.db.models import Q
-from Model.models import Device_User, Device_Info, Order_Model, UID_Bucket, StsCrdModel, VodHlsModel, Unused_Uid_Meal, \
-    VodBucketModel, UIDMainUser
 
 
 class cloudTestView(View):
@@ -59,8 +60,8 @@ class cloudTestView(View):
 
         try:
             # 查询该userID下是否存在此设备
-            old_deviceInfo_qs = Device_Info.objects.filter(userID_id=oldUserID, UID=uid, isExist=1).values('isShare',
-                                                                                                           'vodPrimaryUserID')
+            old_deviceInfo_qs = Device_Info.objects.filter(userID_id=oldUserID, UID=uid, isExist=1) \
+                .values('isShare', 'vodPrimaryUserID', 'serial_number')
             if not old_deviceInfo_qs.exists():
                 return response.json(10008)
 
@@ -101,6 +102,7 @@ class cloudTestView(View):
             vodPrimaryMaster = newUserName
 
             with transaction.atomic():
+                serial_number = old_deviceInfo_qs[0]['serial_number']
                 # 更新旧设备的userID,设备添加时间,关闭推送消息提醒
                 old_deviceInfo_qs.update(userID=newUserID, data_joined=now_time, NotificationMode=0)
                 # 更新设备的主用户信息
@@ -108,6 +110,12 @@ class cloudTestView(View):
                                                            vodPrimaryMaster=vodPrimaryMaster)
                 VodHlsModel.objects.filter(uid=uid).delete()
 
+                if not serial_number:
+                    serial_number = CommonService.query_serial_with_uid(uid)
+                u_dev_info_qs = UnicomDeviceInfo.objects.filter(serial_no=serial_number)
+                if u_dev_info_qs.exists():
+                    now_time = int(time.time())
+                    u_dev_info_qs.update(user_id=newUserID, updated_time=now_time)
                 # UIDMainUser.objects.filter(UID=uid).delete()
                 # uid_main_dict = {
                 #     'UID': uid,

+ 0 - 736
Controller/DetectController.py

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

+ 0 - 553
Controller/DetectControllerV2.py

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

+ 110 - 183
Controller/EquipmentManager.py

@@ -1,26 +1,27 @@
+import logging
 import re
+import threading
 import time
 import traceback
-import threading
-import logging
 
+import oss2
 import requests
 import simplejson as json
+from django.db import transaction
+from django.db.models import Q
 from django.utils import timezone
+
+from Ansjer.config import OSS_STS_ACCESS_SECRET, OSS_STS_ACCESS_KEY, BASE_DIR
+from Ansjer.config import PUSH_REDIS_ADDRESS
+from Controller.DetectController import DetectControllerView
 from Model.models import Device_User, Device_Info, UID_Bucket, UID_Preview, UidSetModel, UidPushModel, \
-    UIDCompanySerialModel, iotdeviceInfoModel, UIDMainUser, UidChannelSetModel, LogModel
-from django.db.models import Q
+    UIDCompanySerialModel, iotdeviceInfoModel, UidChannelSetModel, LogModel, UnicomDeviceInfo, SysMsgModel
+from Object.RedisObject import RedisObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Service.CommonService import CommonService
 from Service.ModelService import ModelService
-from Ansjer.config import OSS_STS_ACCESS_SECRET, OSS_STS_ACCESS_KEY, BASE_DIR
-from Object.ETkObject import ETkObject
-import oss2
-from django.http import JsonResponse
-from Object.RedisObject import RedisObject
-from Controller.DetectController import DetectControllerView
-from Ansjer.config import PUSH_REDIS_ADDRESS
+
 
 #     查询用户设备
 def queryUserEquipmentInterface(request):
@@ -165,7 +166,8 @@ def delUserEquipmentInterface(request):
 
         if dv_qs.exists():
             uid = dv_qs[0].UID
-            asy = threading.Thread(target=ModelService.add_log, args=(CommonService.get_ip_address(request), userID, 'deleteV1'))
+            asy = threading.Thread(target=ModelService.add_log,
+                                   args=(CommonService.get_ip_address(request), userID, 'deleteV1'))
             asy.start()
 
             print('删除')
@@ -233,7 +235,9 @@ def modifyUserEquipmentInterface(request):
             uid = qs[0].UID
             if uid == '98UXAA8BRPA35VAL111A':
                 asy = threading.Thread(target=ModelService.update_log,
-                                       args=(CommonService.get_ip_address(request), userID, 'modifyV0', deviceContent, id))
+                                       args=(
+                                           CommonService.get_ip_address(request), userID, 'modifyV0', deviceContent,
+                                           id))
                 asy.start()
             nickname = qs[0].NickName
             # 增加设备影子信息修改昵称 start
@@ -410,7 +414,8 @@ def addInterface(request):
                 primaryMaster = ''
                 isShare = False
 
-                is_bind = Device_Info.objects.filter(UID=UID, isShare=False).values('userID__userID', 'primaryUserID', 'primaryMaster')
+                is_bind = Device_Info.objects.filter(UID=UID, isShare=False).values('userID__userID', 'primaryUserID',
+                                                                                    'primaryMaster')
 
                 if main_exist.exists():
                     vodPrimaryUserID = main_exist[0]['vodPrimaryUserID']
@@ -422,7 +427,8 @@ def addInterface(request):
                     isShare = True
 
                 isusermain = False
-                if (vodPrimaryUserID != userID and vodPrimaryUserID != '') or (primaryUserID != userID and primaryUserID != ''):
+                if (vodPrimaryUserID != userID and vodPrimaryUserID != '') or (
+                        primaryUserID != userID and primaryUserID != ''):
                     isusermain = True
 
                 # 判断是否有已绑定用户
@@ -480,7 +486,8 @@ def addInterface(request):
                     userDevice = Device_Info(id=pk, userID_id=userID, UID=UID,
                                              NickName=NickName, View_Account=View_Account,
                                              View_Password=View_Password, Type=Type, ChannelIndex=ChannelIndex,
-                                             version=version, vodPrimaryUserID=vodPrimaryUserID, vodPrimaryMaster=vodPrimaryMaster)
+                                             version=version, vodPrimaryUserID=vodPrimaryUserID,
+                                             vodPrimaryMaster=vodPrimaryMaster)
                     userDevice.save()
                     uid_serial_qs = UIDCompanySerialModel.objects.filter(
                         uid__uid=UID)
@@ -507,7 +514,8 @@ def addInterface(request):
                                         {'userID': userID, 'UID': UID, 'uid_nick': uid_channel_set['channel_name'],
                                          'channel': uid_channel_set['channel'], 'password': View_Password})
                         else:
-                            data_list = [{'userID': userID, 'UID': UID, 'uid_nick': NickName, 'password': View_Password}]
+                            data_list = [
+                                {'userID': userID, 'UID': UID, 'uid_nick': NickName, 'password': View_Password}]
 
                         # 请求Alexa服务器更新事件网关
                         data_list = json.dumps(data_list)
@@ -521,22 +529,24 @@ def addInterface(request):
                                                                     'View_Account',
                                                                     'View_Password', 'ChannelIndex', 'Type',
                                                                     'isShare',
-                                                                    'primaryUserID', 'primaryMaster', 'vodPrimaryUserID', 'vodPrimaryMaster', 'userID__userEmail',
+                                                                    'primaryUserID', 'primaryMaster',
+                                                                    'vodPrimaryUserID', 'vodPrimaryMaster',
+                                                                    'userID__userEmail',
                                                                     'data_joined', 'version',
-                                                                    'isVod', 'isExist', 'isCameraOpenCloud', 'serial_number')
+                                                                    'isVod', 'isExist', 'isCameraOpenCloud',
+                                                                    'serial_number')
                     dvql = CommonService.qs_to_list(dvqs)
                     ubqs = UID_Bucket.objects.filter(uid=UID). \
                         values('bucket__content', 'status', 'channel', 'endTime', 'uid')
                     res = dvql[0]
                     res['vod'] = list(ubqs)
 
-
                     # 新增获取IOT证书内容
                     iotqs = iotdeviceInfoModel.objects.filter(serial_number=dvql[0]['serial_number'])
                     if iotqs.exists():
                         res['iot'] = {
-                                'endpoint': iotqs[0].endpoint,
-                                'token_iot_number': iotqs[0].endpoint
+                            'endpoint': iotqs[0].endpoint,
+                            'token_iot_number': iotqs[0].endpoint
                         }
 
                     if isMainUserExists:
@@ -795,50 +805,55 @@ def deleteInterface(request):
     if not userID:
         return response.json(309)
     try:
-        dv_qs = Device_Info.objects.filter(userID_id=userID, id=id)
-        if not dv_qs.exists():
-            return response.json(14)
-        uid = dv_qs[0].UID
-        if userID == dv_qs[0].vodPrimaryUserID:
-            Device_Info.objects.filter(UID=uid).update(vodPrimaryUserID='', vodPrimaryMaster='')
+        with transaction.atomic():
+            dv_qs = Device_Info.objects.filter(userID_id=userID, id=id)
+            if not dv_qs.exists():
+                return response.json(14)
+            uid = dv_qs[0].UID
+            serial_number = dv_qs[0].serial_number
+            if userID == dv_qs[0].vodPrimaryUserID:
+                Device_Info.objects.filter(UID=uid).update(vodPrimaryUserID='', vodPrimaryMaster='')
 
-        if dv_qs[0].isShare:
-            dv_qs.delete()
-        else:
-            # a.主用户删除设备
-            dv_qs.delete()
-            # 删除设备影子信息uid_set   外键关联删除设备推送配置信息 uid_push
-            up_qs = UidPushModel.objects.filter(uid_set__uid=uid)
-            DetectControllerView().do_delete_redis(uid)
-            if up_qs.count() > 1:
-                UidPushModel.objects.filter(uid_set__uid=uid, userID_id=userID).delete()
-                redisObj = RedisObject(db=6, SERVER_HOST=PUSH_REDIS_ADDRESS)
-                ykey = '{uid}_redis_qs'.format(uid=uid)
-                if ykey:
-                    redisObj.del_data(key=ykey)
+            if dv_qs[0].isShare:
+                dv_qs.delete()
             else:
-                up_qs.delete()
-            # b.删除次用户设备
-            Device_Info.objects.filter(UID=uid, isShare=True, primaryUserID=userID).delete()
-            # 异步删除推送消息
-        asy = threading.Thread(target=ModelService.del_eq_info, args=(userID, uid))
-        asy.start()
+                # a.主用户删除设备
+                dv_qs.delete()
+                # 删除设备影子信息uid_set   外键关联删除设备推送配置信息 uid_push
+                up_qs = UidPushModel.objects.filter(uid_set__uid=uid)
+                DetectControllerView().do_delete_redis(uid)
+                if up_qs.count() > 1:
+                    UidPushModel.objects.filter(uid_set__uid=uid, userID_id=userID).delete()
+                    redisObj = RedisObject(db=6, SERVER_HOST=PUSH_REDIS_ADDRESS)
+                    ykey = '{uid}_redis_qs'.format(uid=uid)
+                    if ykey:
+                        redisObj.del_data(key=ykey)
+                else:
+                    up_qs.delete()
+                # b.删除次用户设备
+                Device_Info.objects.filter(UID=uid, isShare=True, primaryUserID=userID).delete()
 
-        # 记录操作日志
-        now_time = int(time.time())
-        ip = CommonService.get_ip_address(request)
-        content = json.loads(json.dumps(request_dict))
-        log = {
-            'ip': ip,
-            'user_id': 1,
-            'status': 200,
-            'time': now_time,
-            'content': json.dumps(content),
-            'url': 'equipment/delete',
-            'operation': '{}删除设备,uid:{}'.format(userID, uid),
-        }
-        LogModel.objects.create(**log)
+            if not serial_number:
+                serial_number = CommonService.query_serial_with_uid(uid)
+            del_unicom_info(userID, serial_number)
+            # 异步删除推送消息
+            asy = threading.Thread(target=ModelService.del_eq_info, args=(userID, uid))
+            asy.start()
 
+            # 记录操作日志
+            now_time = int(time.time())
+            ip = CommonService.get_ip_address(request)
+            content = json.loads(json.dumps(request_dict))
+            log = {
+                'ip': ip,
+                'user_id': 1,
+                'status': 200,
+                'time': now_time,
+                'content': json.dumps(content),
+                'url': 'equipment/delete',
+                'operation': '{}删除设备,uid:{}'.format(userID, uid),
+            }
+            LogModel.objects.create(**log)
     except Exception as e:
         errorInfo = traceback.format_exc()
         print('删除数据库记录错误: %s' % errorInfo)
@@ -846,6 +861,22 @@ def deleteInterface(request):
     else:
         return response.json(0)
 
+
+def del_unicom_info(user_id, serial_no):
+    """
+    解绑联通绑定用户信息
+    @param user_id: 用户id
+    @param serial_no: 序列号
+    """
+    u_dev_info_qs = UnicomDeviceInfo.objects.filter(serial_no=serial_no)
+    if u_dev_info_qs.exists():
+        now_time = int(time.time())
+        u_dev_info_qs.update(user_id='', updated_time=now_time)
+        sys_msg_qs = SysMsgModel.objects.filter(userID_id=user_id, uid=serial_no)
+        if sys_msg_qs.exists():
+            sys_msg_qs.delete()
+
+
 # 批量删除设备
 def batchDeleteInterface(request):
     '''
@@ -926,6 +957,7 @@ def batchDeleteInterface(request):
     else:
         return response.json(0)
 
+
 # 新查询设备字段
 def queryInterface(request):
     request.encoding = 'utf-8'
@@ -959,8 +991,10 @@ def queryInterface(request):
         # count = dvqs.count()
         dvql = dvqs[(page - 1) * line:page * line].values('id', 'userID', 'NickName', 'UID', 'View_Account',
                                                           'View_Password', 'ChannelIndex', 'Type', 'isShare',
-                                                          'primaryUserID', 'primaryMaster', 'data_joined', 'version', 'vodPrimaryUserID', 'vodPrimaryMaster', 'userID__userEmail',
-                                                          'isVod', 'isExist', 'NotificationMode', 'isCameraOpenCloud', 'serial_number')
+                                                          'primaryUserID', 'primaryMaster', 'data_joined', 'version',
+                                                          'vodPrimaryUserID', 'vodPrimaryMaster', 'userID__userEmail',
+                                                          'isVod', 'isExist', 'NotificationMode', 'isCameraOpenCloud',
+                                                          'serial_number')
         dvls = CommonService.qs_to_list(dvql)
         uid_list = []
         serial_number_list = []
@@ -972,8 +1006,7 @@ def queryInterface(request):
             uid_list.append(dvl['UID'])
             serial_number_list.append(dvl['serial_number'][0:6])
 
-
-        #新增获取IOT证书内容
+        # 新增获取IOT证书内容
         iotqs = iotdeviceInfoModel.objects.filter(serial_number__in=serial_number_list)
 
         ubqs = UID_Bucket.objects.filter(uid__in=uid_list). \
@@ -984,7 +1017,7 @@ def queryInterface(request):
         nowTime = int(time.time())
         data = []
         # 设备拓展信息表
-        us_qs = UidSetModel.objects.filter(uid__in=uid_list).\
+        us_qs = UidSetModel.objects.filter(uid__in=uid_list). \
             values('uid', 'version', 'nickname', 'detect_interval', 'is_ptz')
         uv_dict = {}
         for us in us_qs:
@@ -994,17 +1027,17 @@ def queryInterface(request):
                                   'detect_interval': us['detect_interval']}
 
         for p in dvls:
-            #新增IOT
+            # 新增IOT
             p['iot'] = []
             for iot in iotqs:
                 if p['serial_number'][0:6] == iot.serial_number:
-                        p['iot'].append(
-                            {
-                                'endpoint':iot.endpoint,
-                                'token_iot_number':iot.token_iot_number
+                    p['iot'].append(
+                        {
+                            'endpoint': iot.endpoint,
+                            'token_iot_number': iot.token_iot_number
 
-                            }
-                        )
+                        }
+                    )
 
             p['vod'] = []
             for dm in ubqs:
@@ -1014,7 +1047,7 @@ def queryInterface(request):
             p['preview'] = []
             for up in upqs:
                 if p['UID'] == up['uid']:
-                    obj = 'uid_preview/{uid}/channel_{channel}.png'.\
+                    obj = 'uid_preview/{uid}/channel_{channel}.png'. \
                         format(uid=up['uid'], channel=up['channel'])
                     img_sign = bucket.sign_url('GET', obj, 300)
                     p['preview'].append(img_sign)
@@ -1059,7 +1092,7 @@ def uid_status(request):
     # 判断用户是否绑定设备
     qs = UidSetModel.objects.filter(uid=uid).values('uid', 'detect_status', 'detect_interval', 'version', 'ucode',
                                                     'p2p_region', 'tz', 'video_code', 'channel', 'cloud_vod', 'id',
-                                                    'detect_group', 'is_alexa', 'region_alexa','is_ptz')
+                                                    'detect_group', 'is_alexa', 'region_alexa', 'is_ptz')
 
     # 调试
     debugOnes = int(time.time())
@@ -1116,6 +1149,7 @@ def uid_status(request):
     else:
         return response.json(0)
 
+
 def uid_status_test(request):
     request.encoding = 'utf-8'
     response = ResponseObject()
@@ -1174,7 +1208,6 @@ def uid_status_test(request):
         return response.json(0)
 
 
-
 def update_uid_set(request):
     request.encoding = 'utf-8'
     response = ResponseObject()
@@ -1219,109 +1252,3 @@ def update_uid_set(request):
             return response.json(14)
     else:
         return response.json(tko.code)
-
-
-# 测试环境
-# test.shadow.dvema.com
-# 生产环境
-# shadow.dvema.com
-# http://test.dvema.com/deviceShadow/update?etk=JVJWbFpFU0VOV1FsbEVTMFpOU2xKWFFURXhNVUU9Xz0=&ucode=1234&version=1324&p2p_region=CN
-# 设备影子更新
-def update_device_shadow(request):
-    request.encoding = 'utf-8'
-    response = ResponseObject()
-    if request.method == 'POST':
-        request_dict = request.POST
-    elif request.method == 'GET':
-        request_dict = request.GET
-    else:
-        return response.json(444)
-    etk = request_dict.get('etk', None)
-    eto = ETkObject(etk)
-    uid = eto.uid
-    if uid:
-        # 重置按钮
-        is_reset = request_dict.get('is_reset', None)
-        # 传1则重置设备信息
-        if is_reset == '1':
-
-            UidSetModel.objects.filter(uid=uid).delete()
-            # 重置设备,判断设备为已删除
-            nowTime = int(time.time())
-            uid_bucket = UID_Bucket.objects.filter(uid=uid, endTime__gte=nowTime).values('id', 'has_unused').order_by('addTime')
-            if not uid_bucket.exists():
-                di_qs = Device_Info.objects.filter(UID=uid)
-                di_qs.update(isExist=2)
-
-            # 清除redis缓存
-            # data = di_qs.values()
-            # redisObj = RedisObject(db=8)
-            # for di in data:
-            #     key = 'uid_qs_' + di['userID_id']
-            #     redis_value = redisObj.get_data(key=key)
-            #     if redis_value is not False:
-            #         redisObj.del_data(key)
-
-        ucode = request_dict.get('ucode', None)
-        version = request_dict.get('version', None)
-        p2p_region = request_dict.get('p2p_region', None)
-        tz = request_dict.get('tz', None)
-        video_code = request_dict.get('video_code', None)
-        ip = CommonService.get_ip_address(request)
-        channel = request_dict.get('channel', None)
-        cloud_vod = request_dict.get('cloud_vod', None)
-        push_status = request_dict.get('push_status', None)
-        pwd = request_dict.get('pwd', None)
-        resetTime = request_dict.get('resetTime', None)
-        is_ptz = request_dict.get('is_ptz', None)
-        is_alexa = request_dict.get('is_alexa', None)
-        is_ai = request_dict.get('is_ai', None)
-
-        us_qs = UidSetModel.objects.filter(uid=uid)
-        # 更新
-        nowTime = int(time.time())
-
-        print('-------')
-        print(resetTime)
-        print('-------')
-        qs_dict = {
-            'updTime': nowTime,
-            'ip': ip
-        }
-        if channel:
-            qs_dict['channel'] = channel
-        if p2p_region:
-            qs_dict['p2p_region'] = p2p_region
-        if ucode:
-            qs_dict['ucode'] = ucode
-        if version:
-            qs_dict['version'] = version
-        if tz:
-            qs_dict['tz'] = tz
-        if video_code:
-            qs_dict['video_code'] = video_code
-        if cloud_vod:
-            qs_dict['cloud_vod'] = cloud_vod
-        if push_status:
-            qs_dict['detect_status'] = push_status
-        if pwd:
-            qs_dict['pwd'] = pwd
-        if is_ptz:
-            qs_dict['is_ptz'] = is_ptz
-        if is_alexa:
-            qs_dict['is_alexa'] = is_alexa
-        if is_ai:
-            qs_dict['is_ai'] = is_ai
-        if us_qs.exists():
-            us_qs.update(**qs_dict)
-            # 如果推送状态开启,返回推送url
-            return JsonResponse(status=200, data={'code': 0, 'msg': 'success', 'data': {}})
-        # 新增
-        else:
-            qs_dict['uid'] = uid
-            qs_dict['addTime'] = nowTime
-            UidSetModel.objects.create(**qs_dict)
-            # 如果推送状态开启,返回推送url
-            return JsonResponse(status=200, data={'code': 0, 'msg': 'success', 'data': {}})
-    else:
-        return JsonResponse(status=200, data={'code': 403, 'msg': 'error etk'})

+ 4 - 2
Controller/EquipmentManagerV3.py

@@ -628,7 +628,7 @@ class EquipmentManagerV3(View):
         # 设备拓展信息表
         us_qs = UidSetModel.objects.filter(uid__in=uid_list).values('id', 'uid', 'version', 'nickname', 'ucode',
                                                                     'detect_status', 'detect_group',
-                                                                    'detect_interval',
+                                                                    'detect_interval', 'isSupportFourPoint',
                                                                     'region_alexa', 'is_alexa', 'deviceModel',
                                                                     'TimeZone', 'TimeStatus', 'SpaceUsable',
                                                                     'SpaceSum', 'MirrorType', 'RecordType',
@@ -662,7 +662,8 @@ class EquipmentManagerV3(View):
                 'is_ptz': us['is_ptz'],
                 'double_wifi': us['double_wifi'],
                 'mobile4G': us['mobile_4g'],
-                'is_ai': us['is_ai']
+                'is_ai': us['is_ai'],
+                'isSupportFourPoint': us['isSupportFourPoint'],
             }
             # 从uid_channel里面取出通道配置信息
             ucs_qs = UidChannelSetModel.objects.filter(uid__id=us['id']).values('channel', 'channel_name',
@@ -767,6 +768,7 @@ class EquipmentManagerV3(View):
                 p['double_wifi'] = uv_dict[p_uid]['double_wifi']
                 p['mobile4G'] = uv_dict[p_uid]['mobile4G']
                 p['is_ai'] = uv_dict[p_uid]['is_ai']
+                p['isSupportFourPoint'] = uv_dict[p_uid]['isSupportFourPoint']
                 # 设备昵称 调用影子信息昵称,先阶段不可
                 if uv_dict[p_uid]['nickname']:
                     p['NickName'] = uv_dict[p_uid]['nickname']

+ 42 - 1
Controller/EquipmentOTA.py

@@ -1,15 +1,19 @@
 import hashlib
 import os
 import uuid
+from wsgiref.util import FileWrapper
 
 import simplejson as json
 import time
+
+from django.http import HttpResponse
 from django.utils import timezone
 from django.utils.decorators import method_decorator
 from django.views.decorators.csrf import csrf_exempt
 from django.views.generic.base import View
 
 from Ansjer.config import BASE_DIR, SERVER_DOMAIN
+from Controller.OTAEquipment import getMD5orSHA265
 from Model.models import Equipment_Version, EquipmentVersionLimitModel, CountryIPModel
 from Object.RedisObject import RedisObject
 from Object.ResponseObject import ResponseObject
@@ -166,7 +170,8 @@ class EquipmentVersionView(View):
             return response.json(444, 'error path')
         elif operation == 'checkVer':
             return self.do_check_value(request_dict, response)
-            # return self.do_check_ver(request_dict, response)
+        elif operation == 'checkIpcVer':
+            return self.check_ipc_ver(request_dict, response)
 
         token = request_dict.get('token', None)
         # 设备主键uid
@@ -335,6 +340,42 @@ class EquipmentVersionView(View):
         print(url)
         return response.json(0, res)
 
+    @staticmethod
+    def check_ipc_ver(request_dict, response):
+        """
+        NVR获取IPC升级链接
+        @param request_dict: 请求参数
+        @request_dict lang: 语言
+        @request_dict code: 网关设备id
+        @request_dict now_ver: 设备当前版本
+        @param response: 响应对象
+        @return: response
+        """
+        lang = request_dict.get('lang', None)
+        code = request_dict.get('code', None)
+        now_ver = request_dict.get('now_ver', None)
+
+        if not all([code, lang, now_ver]):
+            return response.json(902, {'param': 'code, lang, ver'})
+        equipment_version_qs = Equipment_Version.objects.filter(code=code, status=1, lang=lang).order_by('-data_joined')
+        if not equipment_version_qs.exists():
+            return response.json(902)
+        equipment = equipment_version_qs[0]
+        file_path = equipment.filePath
+        max_ver = equipment.max_ver
+        if now_ver > max_ver:
+            return response.json(902)
+        url = SERVER_DOMAIN + 'OTA/downloadsPack/' + file_path
+        file_name = file_path[file_path.rindex('/')+1:]
+        res = {
+            "url": url,
+            "fileName": file_name,
+            "fileSize": equipment.fileSize,
+            "Description": equipment.Description,
+            "softwareVersion": equipment.softwareVersion
+        }
+        return response.json(0, res)
+
     def do_query(self, request_dict, response):
         mci = request_dict.get('mci', None)
         page = request_dict.get('page', None)

+ 8 - 3
Controller/IotCoreController.py

@@ -131,7 +131,7 @@ class IotCoreView(View):
             else:
                 # 获取并判断region_id是否有效
                 region_id = request_dict.get('region_id', None)
-                region_id = int(region_id) if region_id else CommonService.confirm_region_id(request)
+                region_id = int(region_id) if region_id else CommonService.confirm_region_id()
                 if region_id not in [1, 2, 3, 4]:
                     return response.json(444, {'invalid region_id': region_id})
 
@@ -180,13 +180,12 @@ class IotCoreView(View):
         @return: response
         """
         uid = request_dict.get('uid', '')
-        region_id = request_dict.get('region_id', None)
         time_stamp = request_dict.get('time_stamp', None)
         time_stamp_token = request_dict.get('time_stamp_token', None)
         device_version = request_dict.get('device_version', None)
         language = request_dict.get('language', None)
 
-        if not all([region_id, time_stamp, time_stamp_token, device_version, language]):
+        if not all([time_stamp, time_stamp_token, device_version, language]):
             return response.json(444)
 
         # 时间戳token校验
@@ -198,6 +197,12 @@ class IotCoreView(View):
             if not CommonService.check_time_stamp_token(time_stamp_token, time_stamp):
                 return response.json(13)
 
+        # 获取并判断region_id是否有效
+        region_id = request_dict.get('region_id', None)
+        region_id = int(region_id) if region_id else CommonService.confirm_region_id()
+        if region_id not in [1, 2, 3, 4]:
+            return response.json(444, {'invalid region_id': region_id})
+
         company_mark = '11A'
         thing_name_suffix = uid
         if not uid:

+ 1 - 1
Controller/SensorGateway/EquipmentFamilyController.py

@@ -568,7 +568,7 @@ class EquipmentFamilyView(View):
         @param response: 响应
         @return: 家庭列表items
         """
-        lang = request_dict.get('lang', 'cn')
+        lang = request_dict.get('lang', 'en')
         if user_id:
             with transaction.atomic():
                 user_family_qs = UserFamily.objects.filter(user_id=user_id)

+ 4 - 1
Controller/SensorGateway/GatewayFamilyMemberController.py

@@ -88,6 +88,9 @@ class GatewayFamilyMemberView(View):
                 for item in items:
                     family_member_join_qs = FamilyMemberJoin.objects.filter(id=int(item))
                     if family_member_join_qs.exists():
+                        sys_msg_qs = SysMsgModel.objects.filter(eventType=705, uid=item)
+                        if sys_msg_qs.exists():
+                            sys_msg_qs.delete()
                         family_member_join_qs.delete()
             return response.json(0)
         except Exception as e:
@@ -259,7 +262,7 @@ class GatewayFamilyMemberView(View):
                     'addTime': now_time,
                     'updTime': now_time,
                     'userID_id': family_join['user_id'] if join_type == 1 else family_join['family__user_id'],
-                    'eventType': 705
+                    'eventType': 0
                 }
                 if confirm == 'confirm':
                     msg_text = cls.get_confirm_text(nick_name, family_name, join_type, True, lang)

+ 5 - 9
Controller/SensorGateway/GatewayFamilyRoomController.py

@@ -8,7 +8,7 @@
 """
 
 from django.db import transaction
-from django.db.models import Q, Count, F
+from django.db.models import Q, Count
 from django.views.generic.base import View
 
 from Controller.SensorGateway.EquipmentFamilyController import EquipmentFamilyView
@@ -255,14 +255,10 @@ class GatewayFamilyRoomView(View):
             'sort': []
         }
         try:
-            family_room_device_qs = FamilyRoomDevice.objects.filter(family_id=family_id).values('device_id',
-                                                                                                'device__Type',
-                                                                                                'device__NickName',
-                                                                                                'room_id',
-                                                                                                'sub_device',
-                                                                                                'category',
-                                                                                                ).order_by(
-                'sort', '-device__data_joined')
+            family_room_device_qs = FamilyRoomDevice.objects.filter(family_id=family_id)
+            family_room_device_qs = family_room_device_qs.filter(~Q(device__isExist=2)) \
+                .values('device_id', 'device__Type', 'device__NickName', 'room_id',
+                        'sub_device', 'category', ).order_by('sort', '-device__data_joined')
 
             if not family_room_device_qs.exists():
                 return response.json(0, device_room)

+ 10 - 2
Controller/SensorGateway/SmartSceneController.py

@@ -237,7 +237,6 @@ class SmartSceneView(View):
                 if not device_info_qs.exists():
                     return response.json(173)
                 serial_number = device_info_qs[0]['serial_number']
-                msg['sensor_delay'] = tasks_list[0]['delay_time']
             else:  # 子设备设置场景
                 if not sub_device_id:
                     return response.json(444, {'error param': 'subDeviceId'})
@@ -320,6 +319,11 @@ class SmartSceneView(View):
                         'sensor_type': int(task['device_type']),
                         'sensor_action': int(task['event_type'])
                     }
+
+                    # 延时
+                    if 'delay_time' in task and task['delay_time'] != 0:
+                        task_temp['sensor_delay'] = task['delay_time']
+
                     sub_device_id = task.get('subDeviceId', None)
                     if sub_device_id:
                         sub_device_qs = GatewaySubDevice.objects.filter(id=sub_device_id).values('src_addr').first()
@@ -608,7 +612,6 @@ class SmartSceneView(View):
                 if not device_qs.exists():
                     return response.json(173)
                 serial_number = device_qs[0]['serial_number']
-                msg['sensor_delay'] = tasks_list[0]['delay_time']
 
             task_list = []
             for task in tasks_list:
@@ -616,6 +619,11 @@ class SmartSceneView(View):
                     'sensor_type': int(task['device_type']),
                     'sensor_action': int(task['event_type'])
                 }
+
+                # 延时
+                if 'delay_time' in task and task['delay_time'] != 0:
+                    task_temp['sensor_delay'] = task['delay_time']
+
                 task_sub_device_id = task.get('subDeviceId', None)
                 if task_sub_device_id:
                     sub_device_qs = GatewaySubDevice.objects.filter(id=task_sub_device_id).values('src_addr').first()

+ 0 - 165
Controller/ShadowController.py

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

+ 0 - 708
Controller/TestDetectController.py

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

+ 14 - 6
Controller/UnicomCombo/UnicomComboController.py

@@ -25,6 +25,7 @@ from Object.UnicomObject import UnicomObjeect
 from Object.utils import LocalDateTimeUtil
 from Object.utils.PayUtil import PayService
 from Service.CommonService import CommonService
+from Object.RedisObject import RedisObject
 
 
 class UnicomComboView(View):
@@ -201,19 +202,21 @@ class UnicomComboView(View):
         logger = logging.getLogger('info')
 
         serial_no = request_dict.get('serialNo', None)
-        iccid = request_dict.get('iccid', None)
         time_stamp = request_dict.get('timeStamp', None)
         sign = request_dict.get('sign', None)
-        if not all([iccid, serial_no, sign, time_stamp]):
+        if not all([serial_no, sign, time_stamp]):
             return response.json(444)
-        logger.info('PC工具进入重置ICCID{}'.format(iccid))
+        logger.info('PC工具进入重置ICCID{}'.format(serial_no))
         try:
             if not CommonService.check_time_stamp_token(sign, time_stamp):
                 return response.json(13)
             now_time = int(time.time())
+            redis = RedisObject()
             with transaction.atomic():
-                device_info_qs = UnicomDeviceInfo.objects.filter(iccid=iccid, serial_no=serial_no)
+                device_info_qs = UnicomDeviceInfo.objects.filter(serial_no=serial_no)
                 if device_info_qs.exists():
+                    iccid = device_info_qs.first().iccid
+                    key = 'ASJ:UNICOM:RESET:{}'.format(serial_no)
                     flow_push_qs = UnicomFlowPush.objects.filter(serial_no=serial_no)
                     if flow_push_qs.exists():
                         flow_push_qs.delete()
@@ -221,14 +224,13 @@ class UnicomComboView(View):
                     if sys_msg_qs.exists():
                         sys_msg_qs.delete()
                     device_info_qs.update(status=1, updated_time=now_time, user_id='')
-
                     combo_order_qs = UnicomComboOrderInfo.objects.filter(iccid=iccid)
                     if combo_order_qs.exists():
                         combo_order_qs.delete()
                     combo_experience_history_qs = UnicomComboExperienceHistory.objects.filter(iccid=iccid)
                     if combo_experience_history_qs.exists():
                         combo_experience_history_qs.delete()
-
+                    redis.set_data(key, iccid, 60 * 30)
                 return response.json(0)
         except Exception as e:
             print(e.args)
@@ -302,11 +304,17 @@ class UnicomComboView(View):
         n_time = int(time.time())
         try:
             logger.info('--->参数验证通过,sign验证通过')
+            redis = RedisObject()
             with transaction.atomic():
                 # 待完善代码 根据uid与用户id验证系统设备
                 unicom_device_qs = UnicomDeviceInfo.objects.filter(iccid=iccid)
                 if unicom_device_qs.exists():
                     if unicom_device_qs.first().status == 1 and unicom_device_qs.first().serial_no == serial_no:
+                        key = 'ASJ:UNICOM:RESET:{}'.format(serial_no)
+                        reset_cache = redis.get_data(key)
+                        if reset_cache:
+                            logger.info('--->三十分后再次访问接口生效赠送流量套餐')
+                            return response.json(0, 'Thirty minutes later to visit again take effect')
                         cls.user_activate_flow(iccid)
                     return response.json(0)
                 unicom_obj = UnicomObjeect()

+ 2 - 0
Model/models.py

@@ -1184,8 +1184,10 @@ class UidSetModel(models.Model):
     is_human = models.IntegerField(default=0, verbose_name='是否支持人形追踪。0:不支持,1:支持')
     is_custom_voice = models.IntegerField(default=0, verbose_name='是否支持自定义语音。0:不支持,1:支持')
     double_wifi = models.IntegerField(default=0, verbose_name='是否支持双频wifi。0:不支持,1:支持')
+    isSupportFourPoint = models.SmallIntegerField(default=0, verbose_name='是否支持预置点')    # 0:不支持, 1:支持
     mobile_4g = models.IntegerField(default=0, verbose_name='是否支持4g。0:不支持,1:支持')
     is_ptz = models.IntegerField(default=0, verbose_name='是否支持云台。0:不支持,1:支持')
+    is_vod = models.IntegerField(default=0, verbose_name='是否支持云存储。0:不支持,1:支持')
     is_ai = models.IntegerField(default=2, verbose_name='是否支持ai')  # 0,关闭,1开启,2,不支持
     is_notification = models.IntegerField(blank=True, default=1, verbose_name='新加-消息提醒开关')  # 0:关闭,1:开启
     new_detect_interval = models.IntegerField(blank=True, verbose_name='新加-消息提醒间隔', default=60)  # 秒

+ 88 - 14
Service/CommonService.py

@@ -6,6 +6,7 @@ import time
 from base64 import encodebytes
 from pathlib import Path
 from random import Random
+from dateutil.relativedelta import relativedelta
 
 import OpenSSL.crypto as ct
 import ipdb
@@ -15,7 +16,8 @@ from django.core import serializers
 from django.utils import timezone
 from pyipip import IPIPDatabase
 
-from Ansjer.config import BASE_DIR, SERVER_DOMAIN_SSL, CONFIG_INFO, CONFIG_TEST, CONFIG_CN
+from Ansjer.config import BASE_DIR, SERVER_DOMAIN_SSL, CONFIG_INFO, CONFIG_TEST, CONFIG_CN, SERVER_DOMAIN_TEST, \
+    SERVER_DOMAIN_CN, SERVER_DOMAIN_US, CONFIG_US, CONFIG_EUR
 from Controller.CheckUserData import RandomStr
 from Model.models import iotdeviceInfoModel, Device_Info, CountryModel, RegionModel, UIDModel
 from Object.ResponseObject import ResponseObject
@@ -623,25 +625,33 @@ GCqvlyw5dfxNA+EtxNE2wCW/LW7ENJlACgcfgPlBZtpLheWoZB/maw4=
             return thing_name_suffix
 
     @staticmethod
-    def confirm_region_id(request):
+    def confirm_region_id(request=None):
         """
         根据配置信息确定region_id
         @param request: 请求体
         @return: region_id
         """
         region_id = 3
-        if CONFIG_INFO == CONFIG_TEST or CONFIG_INFO == CONFIG_CN:
-            region_id = 1
-        else:  # 国外配置暂时通过ip确认
-            ip = CommonService.get_ip_address(request)
-            ipInfo = CommonService.getIpIpInfo(ip, 'CN')
-            if ipInfo['country_code']:
-                country_qs = CountryModel.objects.filter(country_code=ipInfo['country_code']).values('region__id')
-                if country_qs.exists():
-                    region_id = country_qs[0]['region__id']
-            else:  # 不存在默认返回美洲地区api
-                region_qs = RegionModel.objects.filter(continent_code='NA').values("id")
-                region_id = region_qs[0]['id']
+        if request is None:
+            if CONFIG_INFO == CONFIG_TEST or CONFIG_INFO == CONFIG_CN:
+                region_id = 1
+            elif CONFIG_INFO == CONFIG_US:
+                region_id = 3
+            elif CONFIG_INFO == CONFIG_EUR:
+                region_id = 4
+        else:
+            if CONFIG_INFO == CONFIG_TEST or CONFIG_INFO == CONFIG_CN:
+                region_id = 1
+            else:  # 国外配置暂时通过ip确认
+                ip = CommonService.get_ip_address(request)
+                ipInfo = CommonService.getIpIpInfo(ip, 'CN')
+                if ipInfo['country_code']:
+                    country_qs = CountryModel.objects.filter(country_code=ipInfo['country_code']).values('region__id')
+                    if country_qs.exists():
+                        region_id = country_qs[0]['region__id']
+                else:  # 不存在默认返回美洲地区api
+                    region_qs = RegionModel.objects.filter(continent_code='NA').values("id")
+                    region_id = region_qs[0]['id']
         return region_id
 
     @staticmethod
@@ -659,3 +669,67 @@ GCqvlyw5dfxNA+EtxNE2wCW/LW7ENJlACgcfgPlBZtpLheWoZB/maw4=
             return token_obj.code, token_obj.userID, response
         except Exception as e:
             print(e)
+
+    @staticmethod
+    def cutting_time(start_time, end_time, time_unit):
+        """
+        按时间单位切割时间段
+        @param start_time: 开始时间
+        @param end_time: 结束时间
+        @param time_unit: 时间单位
+        @return: time_list 切割后的时间列表
+        """
+
+        time_list = []
+        while True:
+            if time_unit == 'day':
+                temp_time = start_time + relativedelta(days=1)
+            elif time_unit == 'week':
+                temp_time = start_time + relativedelta(days=7)
+            elif time_unit == 'month':
+                temp_time = start_time + relativedelta(months=1)
+            elif time_unit == 'quarter':
+                temp_time = start_time + relativedelta(months=3)
+            elif time_unit == 'year':
+                temp_time = start_time + relativedelta(years=1)
+            else:
+                break
+            if temp_time < end_time:
+                time_tuple = (CommonService.str_to_timestamp(start_time.strftime('%Y-%m-%d %H:%M:%S')),
+                              CommonService.str_to_timestamp(temp_time.strftime('%Y-%m-%d %H:%M:%S')))
+                time_list.append(time_tuple)
+                start_time = temp_time
+            else:
+                time_tuple = (CommonService.str_to_timestamp(start_time.strftime('%Y-%m-%d %H:%M:%S')),
+                              CommonService.str_to_timestamp(end_time.strftime('%Y-%m-%d %H:%M:%S')))
+                if time_tuple not in time_list:
+                    time_list.append(time_tuple)
+                break
+        if not time_list:
+            time_tuple = (CommonService.str_to_timestamp(start_time.strftime('%Y-%m-%d %H:%M:%S')),
+                          CommonService.str_to_timestamp(end_time.strftime('%Y-%m-%d %H:%M:%S')))
+            time_list = [time_tuple]
+        return time_list
+
+    @staticmethod
+    def get_domain_name():
+        """
+        获取域名
+        @return: domain_name_list 域名列表
+        """
+
+        if CONFIG_INFO == CONFIG_TEST:
+            domain_name_list = [SERVER_DOMAIN_TEST[:-1]]
+        elif CONFIG_INFO == CONFIG_CN or CONFIG_INFO == CONFIG_US:
+            domain_name_list = [SERVER_DOMAIN_US[:-1], SERVER_DOMAIN_CN[:-1]]
+        else:
+            domain_name_list = []
+        return domain_name_list
+
+    @staticmethod
+    def list_sort(e):
+        """
+        列表排序
+        @param e: 列表元素
+        """
+        return sorted(e, key=lambda item: -item['count'])

+ 15 - 0
eur_formal_manage.py

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