# -*- 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)