Prechádzať zdrojové kódy

Merge remote-tracking branch 'remotes/origin/dev' into test

tanghongbin 5 rokov pred
rodič
commit
e840167417

+ 31 - 0
Ansjer/config.py

@@ -126,3 +126,34 @@ FCM_CONFIG = {
     'com.ansjer.accloud_a': 'AAAAb9YP3rk:APA91bFm06w8b9OKQ0gz0iaWFuRqRIkvgAz6z7Gp3dBU_X-LNGJQd1hc1QR2W7QzBglF8SHtERA45a2lbdLRa5qv7hxfd6W_sJLBK7dA8jklsOQBvy505oUzTwMKWy4TwH-exps9KrhO',
     'com.ansjer.zccloud_ab': 'AAAAb9YP3rk:APA91bHu8u-CTpcd0g6lKPo0WNVqCi8jZub1cPPbSAY9AucT1HxlF65ZDUko9iG8q2ch17bwu9YWHpK1xI1gHSRXCslLvZlXEmHZC0AG3JKg15XuUvlFKACIajUFV-pOeGRT8tM6-31I',
 }
+
+DEVICE_TYPE = {
+    0: 'UNKOWN',
+    1: 'DVR',
+    2: 'NVR',
+    3: 'POENVR',
+    4: 'WIRELESSNVR',
+    5: 'POEIPC',
+    6: 'BOLTIPC',
+    7: 'IPC',
+    8: 'KAPIANJI',
+    9: 'FISHEYE',
+    10: 'C512',
+    11: 'C611',
+    12: 'C612',
+    13: 'C199',
+    14: 'C190',
+    15: 'C199_PRO',
+    10001: 'DVRPTZ'
+}
+
+APP_FREQUENT = {
+    0: 'UNKOWN',
+    1: '每天',
+    2: '三天',
+    3: '一周',
+    4: '两周',
+    5: '一个月',
+    6: '一个月以上',
+
+}

+ 10 - 3
Ansjer/urls.py

@@ -3,12 +3,14 @@ from django.urls import path, re_path
 
 from Controller import FeedBack, EquipmentOTA, EquipmentInfo, AdminManage, AppInfo, \
     AccessLog, DynamoDBLog, Test, MealManage, DeviceManage, EquipmentStatus, SysManage, DeviceLog, LogAccess, \
-    AppColophon, DateController,\
+    AppColophon, DateController, \
     EquipmentManager, LogManager, PermissionManager, OTAEquipment, shareUserPermission, UidSetController, \
     UserManger, CheckUserData, \
     UserController, CloudVod, OrderContrller, VodBucket, DetectController, DeviceShare, UserBrandController, \
-    StsOssController, UIDPreview, OssCrd, SysMsg, UidUser, EquipmentManagerV2,EquipmentManagerV3, PushDeploy, AppSetController,\
-    ApplicationController, UserExController, CloudStorage, TestApi
+    StsOssController, UIDPreview, OssCrd, SysMsg, UidUser, EquipmentManagerV2, EquipmentManagerV3, PushDeploy, \
+    AppSetController, \
+    ApplicationController, UserExController, CloudStorage, TestApi, UserBrandControllerV2, GenerateDataController, \
+    StatisticsController
 
 urlpatterns = [
     url(r'^testApi/(?P<operation>.*)$', TestApi.testView.as_view()),
@@ -203,6 +205,11 @@ urlpatterns = [
     url(r'^date/(?P<operation>.*)$', DateController.DateConView.as_view()),
 
     url(r'^equipment/flow_test$', EquipmentManager.uid_status_test),
+    url(r'^account/appFrequency/(?P<operation>.*)$', UserController.UserAppFrequencyView.as_view()),
+    url(r'^v2/userbrand/(?P<operation>.*)$', UserBrandControllerV2.UserBrandV2.as_view()),
+    url(r'^test/add$', GenerateDataController.GenerateDataView.as_view()),
+    url(r'^statistcs/appFrequencyMonth$', StatisticsController.statistcsAppFrequency),
+    url(r'^statistcs/appFrequencyYear$', StatisticsController.statistcsAppFrequencyYear),
     # app 设备消息模板
     # 路由加参数参考
     # url(r'^(?P<path>.*)/(?P<UID>.*)/lls$', Test.Test.as_view(), name=u'gg'),

+ 215 - 2
Controller/AdminManage.py

@@ -1,16 +1,20 @@
 # -*- coding: utf-8 -*-
+import time
+
+from django.db.models import Count,Q
 from django.views.decorators.csrf import csrf_exempt
 from django.views.generic import TemplateView
 from django.utils.decorators import method_decorator
 from django.contrib.auth.hashers import make_password  # 对密码加密模块
-from Model.models import Device_Info, Role, UserExModel
+from Model.models import Device_Info, Role, UserExModel, User_Brand, UidSetModel, UserAppFrequencyModel, \
+    AppFrequencyStatisticsModel, AppFrequencyYearStatisticsModel
 from Service.ModelService import ModelService
 from django.utils import timezone
 from Model.models import Access_Log, Device_User
 from django.views.decorators.http import require_http_methods
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
-from Ansjer.config import OFF_LINE_TIME_DELTA
+from Ansjer.config import OFF_LINE_TIME_DELTA, DEVICE_TYPE
 import datetime, simplejson as json
 from Service.CommonService import CommonService
 from Object.RedisObject import RedisObject
@@ -64,6 +68,16 @@ class AdminManage(TemplateView):
             return self.getAllUID(userID, response)
         if operation == 'getAllDeviceArea':
             return self.getAllDeviceArea(userID, response)
+        if operation == 'getUserBrand':
+            return self.getUserBrand(userID, response)
+        if operation == 'getAreaDeviceType':
+            return self.getAreaDeviceType(userID, response)
+        if operation == 'getDeviceType':
+            return self.getDeviceType(userID, response)
+        if operation == 'getAppFrequency':
+            return self.getAppFrequency(userID, request_dict, response)
+        if operation == 'getHistoryAppFrequency':
+            return self.getAllAppFrequency(userID, response)
 
     def resetUserPwd(self, request_dict, userID, response):
         own_permission = ModelService.check_perm(userID=userID, permID=50)
@@ -213,6 +227,204 @@ class AdminManage(TemplateView):
             res = {'count': uid_list.count(), 'uid_list': list(uid_list)}
         return response.json(0, res)
 
+    def getUserBrand(self, userID, response):
+        own_permission = ModelService.check_perm(userID=userID, permID=30)
+        if own_permission is not True:
+            return response.json(404)
+        # 手机型号统计
+        print('手机型号统计:')
+        ub_qs = User_Brand.objects.values('deviceSupplier', 'deviceModel').annotate(value=Count('id')).order_by()
+        res = {
+            'value': 0,
+            'data': []
+        }
+        data = res['data']
+        tmpDict = {}
+        for ub in ub_qs:
+            deviceSupplier = ub['deviceSupplier']
+            if not tmpDict.__contains__(deviceSupplier):
+                tmpDict[deviceSupplier] = {
+                    'name': deviceSupplier,
+                    'value': 0,
+                    'children': []
+                }
+
+            item = tmpDict[deviceSupplier]
+            item['value'] = item['value'] + ub['value']
+            res['value'] = res['value'] + item['value']
+            model = {
+                'name': ub['deviceModel'],
+                'value': ub['value']
+            }
+            item['children'].append(model)
+
+        for k, v in tmpDict.items():
+            data.append(v)
+
+        print(res)
+        return response.json(0, res)
+
+    def getAreaDeviceType(self, userID, response):
+        own_permission = ModelService.check_perm(userID=userID, permID=30)
+        if own_permission is not True:
+            return response.json(404)
+        print('区域设备类型统计:')
+        di_qs = Device_Info.objects.values('area', 'Type').annotate(value=Count('UID', distinct=True)).order_by()
+        res = {
+            'quantity': 0,
+            'data': []
+        }
+        data = res['data']
+        tmpDict = {}
+        tmpDict['null'] = {
+            'area': '未知',
+            'quantity': 0,
+            'models': []
+        }
+        for di in di_qs:
+            area = di['area']
+            if area is None or area == '':
+                area = 'null'
+
+            if not tmpDict.__contains__(area):
+                tmpDict[area] = {
+                    'area': area,
+                    'quantity': 0,
+                    'models': []
+                }
+
+            item = tmpDict[area]
+            item['quantity'] = item['quantity'] + di['value']
+            res['quantity'] = res['quantity'] + item['quantity']
+            model = {
+                'model': DEVICE_TYPE[di['Type']],
+                'quantity': di['value']
+            }
+            item['models'].append(model)
+
+        for k, v in tmpDict.items():
+            data.append(v)
+        return response.json(0, res)
+
+    def getDeviceType(self, userID, response):
+        own_permission = ModelService.check_perm(userID=userID, permID=30)
+        if own_permission is not True:
+            return response.json(404)
+        # 设备类型统计
+        di_qs = Device_Info.objects.values('Type').annotate(quantity=Count('UID', distinct=True)).order_by()
+
+        # 设备型号统计
+        us_qs = UidSetModel.objects.values('deviceModel').annotate(quantity=Count('id')).order_by()
+
+        res = {
+            'type_data': {
+                'quantity': 0,
+                'data': []
+            },
+            'model_data': {
+                'quantity': 0,
+                'data': []
+            }
+        }
+        type_data = res['type_data']
+        data = type_data['data']
+        quantity = 0
+        for di in di_qs:
+            di['Type'] = DEVICE_TYPE[di['Type']]
+            quantity += di['quantity']
+            data.append(di)
+        type_data['quantity'] = quantity
+
+        model_data = res['model_data']
+        data = model_data['data']
+        quantity = 0
+        for us in us_qs:
+            data.append(us)
+            quantity += us['quantity']
+        model_data['quantity'] = quantity
+        return response.json(0, res)
+
+    def getAppFrequency(self, userID, request_dict, response):
+        own_permission = ModelService.check_perm(userID=userID, permID=30)
+        if own_permission is not True:
+            return response.json(404)
+
+        # 当前的年份
+        current_time = int(time.time())
+        localtime = time.localtime(current_time)
+        current_year = localtime.tm_year
+        current_month = localtime.tm_mon
+
+        start_year = end_year = current_year
+        end_month = current_month
+        start_month = 1
+
+        result = []
+        if end_month != 12:
+            start_month = end_month + 1
+            start_year = current_year - 1
+
+        time_struct = [start_year, start_month, 0, 0, 0, 0, 0, 0, 0]
+        key_formal = '{year}{month}'
+        for i in range(12):
+            result.append({
+                'date_time': key_formal.format(year=time_struct[0], month=str(time_struct[1]).zfill(2)),
+                'data': None
+            })
+
+            month = time_struct[1] + 1
+            if month > 12:
+                time_struct[0] = time_struct[0] + 1
+                time_struct[1] = 1
+            else:
+                time_struct[1] = month
+        #
+        afs_qs = {}
+        if start_year == end_year:
+            afs_qs = list(AppFrequencyStatisticsModel.objects.filter(year=start_year, month__gte=start_month, month__lte=end_month).values().order_by('-year', 'month'))
+        else:
+            afs_qs = list(AppFrequencyStatisticsModel.objects.filter(year=start_year, month__gte=start_month).values().order_by('-year', 'month'))
+            tmps_qs = list(AppFrequencyStatisticsModel.objects.filter(year=end_year, month__lte=end_month).values().order_by('-year', 'month'))
+            for tmp in tmps_qs:
+                afs_qs.append(tmp)
+
+        tmp_dict = {}
+
+        for afs in afs_qs:
+            key = key_formal.format(year=afs['year'], month=str(afs['month']).zfill(2))
+            tmp_dict[key] = json.loads(afs['data'])
+
+        for res in result:
+            if tmp_dict.__contains__(res['date_time']):
+                res['data'] = tmp_dict[res['date_time']]
+        print(result)
+
+        return response.json(0, result)
+
+    def getAllAppFrequency(self, userID, response):
+        own_permission = ModelService.check_perm(userID=userID, permID=30)
+        if own_permission is not True:
+            return response.json(404)
+
+        # 取出请求年份的统计好的数据
+        print('start')
+        time_struct = time.localtime()
+        current_year = time_struct.tm_year
+        start_year = current_year - 5 + 1
+        afs_qs = AppFrequencyYearStatisticsModel.objects.filter(year__gte=start_year, year__lt=current_year).order_by(
+            '-year')
+        if afs_qs.exists():
+            afs_qs = afs_qs.values('id', 'data', 'num', 'year')
+            res = []
+            for afs in afs_qs:
+                res.append({
+                    'year': afs['year'],
+                    'data': json.loads(afs['data'])
+                })
+            return response.json(0, res)
+        else:
+            return response.json(0, [])
+
 
 @require_http_methods(["GET"])
 def getUserIds(request):
@@ -299,3 +511,4 @@ def search_user_by_content(request):
         sqlDict['count'] = count
         return response.json(0, sqlDict)
     return response.json(0, {'datas': [], 'count': 0})
+

+ 2 - 0
Controller/DeviceShare.py

@@ -167,6 +167,8 @@ class DeviceShareView(View):
                     sharerDvqs.primaryMaster = primaryMaster
                     sharerDvqs.data_joined = None
                     sharerDvqs.save()
+                    redisObj = RedisObject(db=8)
+                    redisObj.del_data(key='uid_qs_' + userID)
                 except Exception as e:
                     return response.json(10, repr(e))
                 else:

+ 6 - 4
Controller/EquipmentManager.py

@@ -15,6 +15,7 @@ from Object.ETkObject import ETkObject
 import oss2
 from django.http import JsonResponse
 from Object.RedisObject import RedisObject
+import logging
 
 
 #     查询用户设备
@@ -371,6 +372,8 @@ def addInterface(request):
                             'nickname': NickName,
                         }
                         UidSetModel.objects.create(**uid_set_create_dict)
+                    else:
+                        us_qs.update(nickname=NickName)
                     pk = CommonService.getUserID(getUser=False)
                     userDevice = Device_Info(id=pk, userID_id=userID, UID=UID,
                                              NickName=NickName, View_Account=View_Account,
@@ -957,10 +960,9 @@ def update_device_shadow(request):
         request_dict = request.GET
     else:
         return response.json(444)
-    # etk = request_dict.get('etk', None)
-    # eto = ETkObject(etk)
-    # uid = eto.uid
-    uid = request_dict.get('uid', None)
+    etk = request_dict.get('etk', None)
+    eto = ETkObject(etk)
+    uid = eto.uid
     if uid:
         # 重置按钮
         is_reset = request_dict.get('is_reset', None)

+ 2 - 0
Controller/EquipmentManagerV2.py

@@ -86,6 +86,8 @@ class EquipmentManagerV2(View):
                                 'nickname': NickName,
                             }
                             UidSetModel.objects.create(**uid_set_create_dict)
+                        else:
+                            us_qs.update(nickname=NickName)
                         pk = CommonService.getUserID(getUser=False)
                         userDevice = Device_Info(id=pk, userID_id=userID, UID=UID,
                                                  NickName=NickName, View_Account=View_Account,

+ 4 - 2
Controller/EquipmentManagerV3.py

@@ -89,6 +89,8 @@ class EquipmentManagerV3(View):
                                 'nickname': NickName,
                             }
                             UidSetModel.objects.create(**uid_set_create_dict)
+                        else:
+                            us_qs.update(nickname=NickName)
                         pk = CommonService.getUserID(getUser=False)
                         userDevice = Device_Info(id=pk, userID_id=userID, UID=UID,
                                                  NickName=NickName, View_Account=View_Account,
@@ -165,8 +167,8 @@ class EquipmentManagerV3(View):
                     }
                     UidSetModel.objects.create(**uid_set_create_dict)
                 Device_Info.objects.filter(UID=uid).update(NickName=nickname)
-                redisObj = RedisObject(db=8)
-                redisObj.del_data(key='uid_qs_' + userID)
+            redisObj = RedisObject(db=8)
+            redisObj.del_data(key='uid_qs_' + userID)
             return response.json(0, res)
 
     # 新查询设备字段

+ 137 - 0
Controller/StatisticsController.py

@@ -0,0 +1,137 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+import json
+import time
+
+from django.db.models import Count
+from django.views.decorators.csrf import csrf_exempt
+
+from Model.models import UserAppFrequencyModel, AppFrequencyStatisticsModel, Device_User, \
+    AppFrequencyYearStatisticsModel
+from Object.ResponseObject import ResponseObject
+from Object.TokenObject import TokenObject
+
+
+@csrf_exempt
+def statistcsAppFrequency(request):
+    request.encoding = 'utf-8'
+    response = ResponseObject()
+    if request.method == 'POST':
+        request_dict = request.POST
+    elif request.method == 'GET':
+        request_dict = request.GET
+    else:
+        return response.json(444)
+
+    token = TokenObject(request_dict.get('token', None))
+    if token.code != 0:
+        return response.json(token.code)
+
+    target_year = request_dict.get('year', None)
+    target_month = request_dict.get('month', None)
+
+    localtime = time.localtime()
+    current_month = localtime.tm_mon
+    current_year = localtime.tm_year
+
+    if target_year and target_month:
+        current_year = int(target_year)
+        current_month = int(target_month)
+
+    time_struct = [current_year, 1, 1, 0, 0, 0, 0, 0, 0]
+
+    # 该月的开始时间
+    time_struct[1] = current_month
+    start_time = time.mktime(tuple(time_struct))
+
+    # 该月的结束时间
+    time_struct[1] = current_month + 1
+    end_time = time.mktime(tuple(time_struct))
+
+    # 统计该月的数据
+    uaf_qs = UserAppFrequencyModel.objects.filter(data_time__gte=start_time, data_time__lt=end_time) \
+        .values('type').annotate(quantity=Count('id')).order_by()
+
+    afs_qs = AppFrequencyStatisticsModel.objects.filter(year=current_year, month=current_month)
+
+    if afs_qs.exists():
+        afs_qs.update(data=json.dumps(uaf_qs))
+    else:
+        data = {
+            'data': json.dumps(list(uaf_qs)),
+            'month': current_month,
+            'year': current_year
+        }
+        AppFrequencyStatisticsModel.objects.create(**data)
+    return response.json(0)
+
+
+@csrf_exempt
+def statistcsAppFrequencyYear(request):
+    request.encoding = 'utf-8'
+    response = ResponseObject()
+    if request.method == 'POST':
+        request_dict = request.POST
+    elif request.method == 'GET':
+        request_dict = request.GET
+    else:
+        return response.json(444)
+
+    token = TokenObject(request_dict.get('token', None))
+    if token.code != 0:
+        return response.json(token.code)
+
+    year = request_dict.get('year', None)
+
+    localtime = time.localtime()
+
+    current_year = localtime.tm_year
+    if year:
+        current_year = int(year)
+
+    afs_qs = AppFrequencyStatisticsModel.objects.filter(year=current_year).values('data', 'month')
+    # num = Device_User.objects.count()
+    num = 300000
+
+    res = []
+    result = {
+        0: 0,
+        1: 0,
+        2: 0,
+        3: 0,
+        4: 0,
+        5: 0,
+        6: 0
+    }
+    quantity = 0
+    for afs in afs_qs:
+        data = json.loads(afs['data'])
+        for item in data:
+            result[item['type']] += item['quantity']
+            quantity += item['quantity']
+
+    tmps = []
+    for k, v in result.items():
+        tmp = {
+            'type': k,
+            'value': round(v / 12 / num, 3)
+        }
+        tmps.append(tmp)
+    res.append({
+        'year': current_year,
+        'data': tmps
+    })
+    print(res)
+
+    afys_qs = AppFrequencyYearStatisticsModel.objects.filter(year=current_year)
+    #
+    if afys_qs.exists():
+        afys_qs.update(data=json.dumps(res))
+    else:
+        data = {
+            'data': json.dumps(res),
+            'year': current_year,
+            'num': num
+        }
+        AppFrequencyYearStatisticsModel.objects.create(**data)
+    return response.json(0)

+ 79 - 13
Controller/UidSetController.py

@@ -13,6 +13,9 @@
 """
 import time
 import traceback
+
+from django.db.models import Count
+
 from Object.RedisObject import RedisObject
 import simplejson as json
 from django.utils.decorators import method_decorator
@@ -20,7 +23,7 @@ from django.views.decorators.csrf import csrf_exempt
 from django.views.generic.base import View
 
 from Model.models import UidSetModel, Device_User, Device_Info, UidPushModel, Equipment_Info, UID_Preview, UID_Bucket, \
-    VodHlsModel, Order_Model, OssCrdModel, UidUserModel, UidChannelSetModel
+    VodHlsModel, Order_Model, OssCrdModel, UidUserModel, UidChannelSetModel, User_Brand
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Service.CommonService import CommonService
@@ -81,9 +84,11 @@ class UidSetView(View):
         elif operation == 'update':
             return self.do_update(request_dict, response)
         elif operation == 'updateSet':
-            return self.do_update_set(request_dict, response)
+            return self.do_update_set(request, request_dict, response)
         elif operation == 'updateChannel':
             return self.do_update_channel_set(request_dict, response)
+        # elif operation == 'test':
+        #     return self.do_test(response)
         else:
             return response.json(444, 'error path')
 
@@ -194,16 +199,16 @@ class UidSetView(View):
                     else:
                         val = val + 1
                         print('UidUserModel表没有数据')
-                #有后台管理 设备配置表UidSetModel ---uid --本身,
-                #有后台管理 设备关联用户推送表Equipment_Info --devUid --独立没有儿子的,
-                #有后台管理             设备预览图表UID_Preview ---uid---孤立,
-                #有后台管理 设备关联套餐表UID_Bucket ---uid---孤立,
-                #有后台管理            云存回放信息表VodHlsModel ---uid---孤立,
-                #有后台管理 订单信息表Order_Model --UID----独立没有儿子的,
-                #有后台管理 用户设备信息表(最多信息量的表)Device_Info ---UID---孤立,
+                # 有后台管理 设备配置表UidSetModel ---uid --本身,
+                # 有后台管理 设备关联用户推送表Equipment_Info --devUid --独立没有儿子的,
+                # 有后台管理             设备预览图表UID_Preview ---uid---孤立,
+                # 有后台管理 设备关联套餐表UID_Bucket ---uid---孤立,
+                # 有后台管理            云存回放信息表VodHlsModel ---uid---孤立,
+                # 有后台管理 订单信息表Order_Model --UID----独立没有儿子的,
+                # 有后台管理 用户设备信息表(最多信息量的表)Device_Info ---UID---孤立,
                 #           设备证书OssCrdModel ---uid---孤立
                 # 有后台管理 设备ap表 UidUserModel
-                #设备绑定UidPushModel---关联表---设备配置表UidSetModel---配置表的详情有显示
+                # 设备绑定UidPushModel---关联表---设备配置表UidSetModel---配置表的详情有显示
 
                 # raise DatabaseError     #测试用,检测是否能捕捉错误
                 if val == 9:
@@ -317,11 +322,11 @@ class UidSetView(View):
             errorInfo = traceback.format_exc()
             return response.json(500, {'details': errorInfo})
 
-    def do_update_set(self, request_dict, response):
+    def do_update_set(self, request, request_dict, response):
         uid = request_dict.get('uid', None)
         deviceContent = request_dict.get('content', None)
         token = request_dict.get('token', None)
-        print(deviceContent)
+        # print(deviceContent)
         if not deviceContent or not uid:
             return response.json(444, 'content,uid')
         tko = TokenObject(token)
@@ -336,7 +341,28 @@ class UidSetView(View):
             redisObj.del_data(key='uid_qs_' + userID)
             deviceData = json.loads(deviceContent)
             uid_set_qs = UidSetModel.objects.filter(uid=uid)
-            uid_set_qs.update(**deviceData)
+            if not uid_set_qs.exists():
+                # 由于uid_set表和device_info表设备数量不一致,所以添加以下逻辑把device_info表中的相关信息保存到uid_set表
+                di_qs = Device_Info.objects.filter(UID=uid, userID=userID)
+                if di_qs.exists():
+                    di = di_qs[0]
+                    nowTime = int(time.time())
+                    uid_set_create_dict = {
+                        'uid': di.UID,
+                        'addTime': nowTime,
+                        'updTime': nowTime,
+                        'ip': CommonService.get_ip_address(request),
+                        'channel': di.ChannelIndex,
+                        'nickname': di.NickName,
+                    }
+                    for k, v in deviceData.items():
+                        uid_set_create_dict[k] = v
+                    UidSetModel.objects.create(**uid_set_create_dict)
+                else:
+                    return response.json(177)
+            else:
+                uid_set_qs.update(**deviceData)
+            print('update success')
         except Exception as e:
             return response.json(177, repr(e))
         else:
@@ -383,3 +409,43 @@ class UidSetView(View):
             return response.json(177, repr(e))
         else:
             return response.json(0)
+
+    # def do_test(self, response):
+    #     di_qs = Device_Info.objects.values('Type').annotate(c=Count('UID', distinct=True)).order_by()
+    #     for di in di_qs:
+    #         print(di)
+    #
+    #     # 设备总数量
+    #     count = Device_Info.objects.values('UID').distinct().count()
+    #     print('设备总数量:' + str(count))
+    #
+    #     # 设备型号统计
+    #     print('设备型号统计:')
+    #     us_qs = UidSetModel.objects.values('deviceModel').annotate(c=Count('id')).order_by()
+    #     for us in us_qs:
+    #         print(us)
+    #
+    #     # 手机品牌类型统计
+    #     print('手机品牌类型统计:')
+    #     ub_qs = User_Brand.objects.values('deviceSupplier').annotate(c=Count('id')).order_by()
+    #     for ub in ub_qs:
+    #         print(ub)
+    #
+    #     # 手机型号统计
+    #     print('手机型号统计:')
+    #     ub_qs = User_Brand.objects.values('deviceSupplier', 'deviceModel').annotate(c=Count('id')).order_by()
+    #     for ub in ub_qs:
+    #         print(ub)
+    #
+    #     # 区域统计
+    #     print('区域统计:')
+    #     di_qs = Device_Info.objects.values('area').annotate(c=Count('UID', distinct=True)).order_by()
+    #     for di in di_qs:
+    #         print(di)
+    #
+    #     # 区域设备类型统计
+    #     print('区域设备类型统计:')
+    #     di_qs = Device_Info.objects.values('area', 'Type').annotate(c=Count('UID', distinct=True)).order_by()
+    #     for di in di_qs:
+    #         print(di)
+    #     return response.json(0)

+ 88 - 0
Controller/UserBrandControllerV2.py

@@ -0,0 +1,88 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+from django.utils.decorators import method_decorator
+from django.views.decorators.csrf import csrf_exempt
+from django.views.generic.base import View
+
+from Model.models import User_Brand, Device_User
+from Object.ResponseObject import ResponseObject
+from Object.TokenObject import TokenObject
+
+
+class UserBrandV2(View):
+    @method_decorator(csrf_exempt)
+    def dispatch(self, *args, **kwargs):
+        return super(UserBrandV2, self).dispatch(*args, **kwargs)
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        request_dict = request.GET
+        return self.validate(request_dict, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        request_dict = request.POST
+        return self.validate(request_dict, operation)
+
+    def validate(self, request_dict, operation):
+        token = request_dict.get('token', None)
+
+        response = ResponseObject()
+        token = TokenObject(token)
+
+        if token.code != 0:
+            return response.json(token.code)
+
+        if operation == 'add':
+            return self.do_add(token.userID, request_dict, response)
+        elif operation == 'query':
+            return self.do_query(token.userID, request_dict, response)
+        else:
+            return response.json(404)
+
+    def do_add(self, userID, request_dict, response):
+        deviceSupplier = request_dict.get('deviceSupplier', None)
+        deviceModel = request_dict.get('deviceModel', None)
+        osType = request_dict.get('osType', None)
+        osVersion = request_dict.get('osVersion', None)
+
+        if userID and deviceSupplier and deviceModel and osType and osVersion:
+            ub_qs = User_Brand.objects.filter(userID=userID)
+            if ub_qs.exists():
+                update = {
+                    'deviceSupplier': deviceSupplier,
+                    'deviceModel': deviceModel,
+                    'osType': osType,
+                    'osVersion': osVersion
+                }
+                ub_qs.update(**update)
+                return response.json(0)
+            else:
+                user = Device_User.objects.filter(userID=userID)
+                if not user.exists():
+                    return response.json(104)
+                data = {
+                    'userID': user[0],
+                    'deviceSupplier': deviceSupplier,
+                    'deviceModel': deviceModel,
+                    'osType': osType,
+                    'osVersion': osVersion
+                }
+                User_Brand.objects.create(**data)
+                return response.json(0)
+        else:
+            return response.json(444)
+
+    def do_query(self, userID, request_dict, response):
+
+        if not userID:
+            return response.json(444)
+        else:
+            ub_qs = User_Brand.objects.filter(userID=userID)
+            data = None
+            if ub_qs.exists():
+                data = ub_qs.values('id', 'deviceSupplier', 'deviceModel', 'osType', 'osVersion')[0]
+
+            return response.json(0, {'data': data})

+ 75 - 1
Controller/UserController.py

@@ -27,7 +27,8 @@ from ratelimit.decorators import ratelimit
 
 from Ansjer.config import AuthCode_Expire, SERVER_DOMAIN, APNS_CONFIG, JPUSH_CONFIG, FCM_CONFIG, TUTK_PUSH_DOMAIN
 from Controller.CheckUserData import DataValid, date_handler, RandomStr
-from Model.models import Device_User, Role, UidPushModel, UserOauth2Model, UserExModel, Device_Info,UidSetModel
+from Model.models import Device_User, Role, UidPushModel, UserOauth2Model, UserExModel, Device_Info, UidSetModel, \
+    UserAppFrequencyModel
 from Object.AWS.SesClassObject import SesClassObject
 from Object.AliSmsObject import AliSmsObject
 from Object.RedisObject import RedisObject
@@ -2930,8 +2931,81 @@ class Image_Code_RegisterView(TemplateView):
         return response.json(0, res)
 
 
+class UserAppFrequencyView(TemplateView):
+    @method_decorator(csrf_exempt)
+    def dispatch(self, *args, **kwargs):
+        return super(UserAppFrequencyView, self).dispatch(*args, **kwargs)
 
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.POST
+        operation = kwargs.get('operation')
+        return self.validates(request_dict, operation)
 
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.GET
+        operation = kwargs.get('operation')
+        return self.validates(request_dict, operation)
+
+    def validates(self, request_dict, operation):
+        token = request_dict.get('token', None)
+        response = ResponseObject()
+
+        token = TokenObject(token)
+        if token.code != 0:
+            return response.json(token.code)
+
+        if operation == 'refresh':
+            return self.do_refresh(request_dict, token.userID, response)
+        else:
+            return response.json(404)
+
+    def do_refresh(self, request_dict, userID, response):
+        # return response.json(0)
+        type = request_dict.get('type', None)
+        month = request_dict.get('month', None)
+        if not type or not month:
+            return response.json(444, 'type')
+        else:
+            type = int(type)
+            now_time = int(time.time())
+            month = int(month)
+            uaf_qs = UserAppFrequencyModel.objects.filter(user__userID=userID)
+
+            if not uaf_qs.exists():
+                user = Device_User.objects.filter(userID=userID)[0]
+                data = {
+                    'user': user,
+                    'type': type,
+                    'data_time': month,
+                    'add_time': now_time,
+                    'update_time': now_time,
+                }
+                UserAppFrequencyModel.objects.create(**data)
+                return response.json(0)
+            else:
+                updateMonth = time.strftime('%m', time.localtime(month))
+                uaf = uaf_qs.values('id', 'type', 'data_time')[0]
+                dbMonth = time.strftime('%m', time.localtime(int(uaf['data_time'])))
+                print('update month is ' + updateMonth)
+                print('db month is ' + dbMonth)
+                if updateMonth == dbMonth:
+                    UserAppFrequencyModel.objects.filter(id=uaf['id']).update(type=type)
+                    return response.json(0)
+                elif updateMonth > dbMonth:
+                    user = Device_User.objects.filter(userID=userID)[0]
+                    data = {
+                        'user': user,
+                        'type': type,
+                        'data_time': month,
+                        'add_time': now_time,
+                        'update_time': now_time,
+                    }
+                    UserAppFrequencyModel.objects.create(**data)
+                    return response.json(0)
+                else:
+                    return response.json(444, 'month')
 
 
 

+ 39 - 0
Model/models.py

@@ -908,3 +908,42 @@ class GrantCodeModel(models.Model):
         ordering = ('-add_time',)
         verbose_name = u'授权码表'
         db_table = 'oauth_grant_code'
+
+
+class UserAppFrequencyModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    user = models.ForeignKey(Device_User, to_field='userID', on_delete=models.CASCADE, verbose_name='关联设备用户表')
+    type = models.SmallIntegerField(default=0, verbose_name='使用频率类型') # 1:每天,2:三天,3:一周,4:两周,5:一个月,6:一个月以上
+    data_time = models.IntegerField(default=0, verbose_name='数据时间')
+    add_time = models.IntegerField(default=0, verbose_name='添加时间')
+    update_time = models.IntegerField(default=0, verbose_name='更新时间')
+
+    class Meta:
+        verbose_name = '用户使用APP频率表'
+        verbose_name_plural = verbose_name
+        db_table = 'user_app_frequency'
+        ordering = ('-add_time',)
+
+
+class AppFrequencyStatisticsModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    data = models.TextField(default='', verbose_name='统计好的数据')
+    month = models.IntegerField(default=0, verbose_name='月份')
+    year = models.IntegerField(default=0, verbose_name='年份')
+
+    class Meta:
+        verbose_name = 'app月使用频率统计表'
+        verbose_name_plural = verbose_name
+        db_table = 'app_frequency_statistics'
+
+
+class AppFrequencyYearStatisticsModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    data = models.TextField(default='', verbose_name='统计好的数据')
+    year = models.IntegerField(default=0, verbose_name='年份')
+    num = models.IntegerField(default=0, verbose_name='总人数')
+
+    class Meta:
+        verbose_name = 'app使用频率统计表,年度统计'
+        verbose_name_plural = verbose_name
+        db_table = 'app_frequency_year_statistics'

+ 1 - 0
Service/TemplateService.py

@@ -78,6 +78,7 @@ class TemplateService:
             'v3/account/register',
             'v3/account/changePwd',
             'v3/account/resetPwdByCode',
+            'account/appFrequency',
         ]
         return apiList