瀏覽代碼

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

 Conflicts:
	Controller/AppAccountManagement.py
guanhailong 2 年之前
父節點
當前提交
ae12db7395

+ 58 - 6
AdminController/DeviceManagementController.py

@@ -14,7 +14,7 @@ from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, AWS_ACCESS_
     AWS_SES_ACCESS_REGION
 from Model.models import Device_Info, UidSetModel, LogModel, UID_Bucket, Unused_Uid_Meal, Order_Model, StsCrdModel, \
     VodHlsModel, ExperienceContextModel, DeviceTypeModel, Equipment_Info, UidUserModel, ExperienceAiModel, AiService, \
-    AppBundle, App_Info, AppDeviceType, DeviceNameLanguage, AppVersionNumber
+    AppBundle, App_Info, AppDeviceType, DeviceNameLanguage, AppVersionNumber, UIDCompanySerialModel
 from Object.AWS.AmazonS3Util import AmazonS3Util
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
@@ -79,9 +79,10 @@ class DeviceManagement(View):
                 return self.edit_app_device_type(request_dict, response)
             elif operation == 'deleteAppDeviceType':  # 删除app设备类型数据
                 return self.delete_app_device_type(request_dict, response)
-
             elif operation == 'getAppBundle':  # 获取app版本包
                 return self.get_app_bundle(response)
+            elif operation == 'resetAll':  # 重置设备主用户/云存/AI
+                return self.reset_all(request, request_dict, response)
             else:
                 return response.json(444, 'operation')
 
@@ -445,12 +446,23 @@ class DeviceManagement(View):
     def del_device_data(request_dict, response):
         uidList = request_dict.get('uidList', None)
         delDataOptions = request_dict.get('delDataOptions', None)
-
-        if not all([uidList, delDataOptions]):
+        serialNumberList = request_dict.get('serialNumberList', None)
+        if not all([uidList or serialNumberList, delDataOptions]):
             return response.json(444)
         try:
             with transaction.atomic():
-                uidList = uidList.splitlines()  # 按行('\r', '\r\n', \n')切割字符串返回列表
+                if uidList:
+                    #  uid
+                    uidList = uidList.splitlines()  # 按行('\r', '\r\n', \n')切割字符串返回列表
+                else:
+                    #  序列号
+                    serialNumberList = serialNumberList.splitlines()  # 按行('\r', '\r\n', \n')切割字符串返回列表
+                    serial_number_list = []
+                    for serial_number in serialNumberList:
+                        serial_number_list.append(serial_number[0:6])
+                    uid_company_serial_qs = UIDCompanySerialModel.objects.filter(
+                        company_serial__serial_number__in=serial_number_list).values('uid__uid')
+                    uidList = [item[key] for item in uid_company_serial_qs for key in item]
                 # 根据删除项删除相关数据
                 if '设备信息数据' in delDataOptions:
                     Device_Info.objects.filter(UID__in=uidList).delete()
@@ -485,7 +497,7 @@ class DeviceManagement(View):
         version_number = request_dict.get('versionNumber', None)
         if not all([lang, app_bundle_id, version_number]):
             return response.json(444)
-        if lang != 'cn':
+        if lang != 'cn' and lang != 'cn_tw':
             lang = 'en'
         if version_number >= '2.6.2.1':  # 判断是否低于2.6.2.1版本
             return self.newAppVersion(response, app_bundle_id, lang, version_number)  # 获取2.6.2.1及以上版本设备信息图标
@@ -707,3 +719,43 @@ class DeviceManagement(View):
         except Exception as e:
             print(e)
             return response.json(500, repr(e))
+
+    @staticmethod
+    def reset_all(request, request_dict, response):
+        uid = request_dict.get('uid', None)
+        if not uid:
+            return response.json(444)
+        try:
+            # 记录操作日志
+            ip = CommonService.get_ip_address(request)
+            content = json.loads(json.dumps(request_dict))
+            log = {
+                'ip': ip,
+                'user_id': 2,
+                'status': 200,
+                'time': int(time.time()),
+                'url': 'deviceManagement/resetAll',
+                'content': json.dumps(content),
+                'operation': '{}重置所有'.format(uid),
+            }
+            with transaction.atomic():
+                LogModel.objects.create(**log)
+                # 删除主用户
+                Device_Info.objects.filter(UID=uid).update(vodPrimaryUserID='', vodPrimaryMaster='')
+                # 删除云存
+                UID_Bucket.objects.filter(uid=uid).delete()
+                Unused_Uid_Meal.objects.filter(uid=uid).delete()
+                Order_Model.objects.filter(UID=uid, order_type=0).delete()
+                StsCrdModel.objects.filter(uid=uid).delete()
+                VodHlsModel.objects.filter(uid=uid).delete()
+                # 删除vod_hls分表数据
+                split_vod_hls_obj = SplitVodHlsObject()
+                split_vod_hls_obj.del_vod_hls_data(uid=uid)
+                ExperienceContextModel.objects.filter(uid=uid).delete()
+                # 删除AI
+                ExperienceAiModel.objects.filter(uid=uid).delete()
+                AiService.objects.filter(uid=uid).delete()
+                return response.json(0)
+        except Exception as e:
+            print(e)
+            return response.json(500, repr(e))

+ 27 - 8
AdminController/ServeManagementController.py

@@ -17,11 +17,13 @@ from django.views.generic.base import View
 
 from Ansjer.config import PAYPAL_CRD
 from Controller.Cron.CronTaskController import CronUpdateDataView
+from Controller.UnicomCombo.UnicomComboTaskController import UnicomComboTaskView
 from Model.models import VodBucketModel, CDKcontextModel, Store_Meal, Order_Model, \
     UID_Bucket, ExperienceContextModel, Lang, CloudLogModel, UidSetModel, Unused_Uid_Meal, \
     Device_Info, DeviceTypeModel, UnicomComboOrderInfo, AiService
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
+from Object.UnicomObject import UnicomObjeect
 from Service.CommonService import CommonService
 
 
@@ -723,7 +725,8 @@ class serveManagement(View):
 
             order_ql = omqs.values("orderID", "UID", "userID__username", "userID__NickName", "channel", "desc", "price",
                                    "refunded_amount", "currency", "addTime", "updTime", "paypal", "payType",
-                                   "rank__day", "rank__price", "status", "order_type", "paymentID", "trade_no")
+                                   "rank__day", "rank__price", "status", "order_type", "paymentID", "trade_no",
+                                   "payTime")
             order_ql = order_ql.order_by('-addTime')  # 根据CDK创建时间降序排序
             order_ql = order_ql[(page - 1) * line:page * line]
             for order in order_ql:
@@ -745,6 +748,7 @@ class serveManagement(View):
                     'rank__price': order['rank__price'],
                     'status': order['status'],
                     'order_type': order['order_type'],
+                    'payTime': order['payTime'] if order['payTime'] else 'N/A'
                 }
                 #  订单显示(或不显示)停用/退款功能
                 if order['order_type'] == 0:  # 云存
@@ -1596,13 +1600,28 @@ class serveManagement(View):
                     # return response.json(10059)  # 未使用套餐类型重复
                 #  联通4G套餐
                 if orderType == '2' and payType != '10':
-                    return response.json(10059)
-                    # unicom_combo_order_info_qs = UnicomComboOrderInfo.objects.filter(order_id=orderID & ~Q(status=2)).values(
-                    #     'expire_time')
-                    # if not unicom_combo_order_info_qs.exists():
-                    #     return response.json(173)
-                    # unicom_combo_order_info_qs.update(expire_time=nowTime)
-                    # return response.json(0)
+                    now_time = int(time.time())
+                    combo_info_qs = UnicomComboOrderInfo.objects.filter(~Q(status=2), order_id=orderID)
+                    if not combo_info_qs.exists():
+                        return response.json(10059)
+                    iccid = combo_info_qs.first().iccid
+                    combo_info_qs.update(status=2, updated_time=now_time)
+                    combo_info_qs = UnicomComboOrderInfo.objects.filter(status=1)
+                    if combo_info_qs:
+                        return response.json(10059)
+                    unicom_api = UnicomObjeect()
+                    usage_flow = unicom_api.get_flow_usage_total(iccid)
+                    today = datetime.datetime.today()
+                    year = today.year
+                    month = today.month
+                    task_view = UnicomComboTaskView()
+                    result = task_view.query_unused_combo_and_activate(iccid, year, month, usage_flow)
+                    if not result:
+                        # 停用设备
+                        unicom_api.change_device_to_disable(iccid)
+                    else:
+                        unicom_api.change_device_to_activate(iccid)
+                    return response.json(0)
                 return response.json(173)
         except Exception as e:
             print(e)

+ 119 - 2
AdminController/UserManageController.py

@@ -23,9 +23,10 @@ from django.views.decorators.csrf import csrf_exempt
 from django.views.generic import TemplateView
 
 from Ansjer.config import SERVER_DOMAIN, OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET
-from Controller.CheckUserData import DataValid
+from Controller.CheckUserData import DataValid, RandomStr
 from Model.models import Device_User, Role, UserExModel, CountryModel, MenuModel, FeedBackModel, StatResModel, \
-    SysMassModel, App_Info, SysMsgModel
+    SysMassModel, App_Info, SysMsgModel, DeviceSuperPassword
+from Object.RedisObject import RedisObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Service.CommonService import CommonService
@@ -306,6 +307,12 @@ class UserManagement(View):
                 return self.collectFeedBack(request_dict, response)
             elif operation == 'exportFeedBack':
                 return self.exportFeedBack(request_dict, response)
+            if operation == 'customerServiceManagement':  # 审核用户请求/生成超级密码
+                return self.customerServiceManagement(request_dict, response)
+            if operation == 'getDeviceSuperPassword':  # 查询超级密码请求表
+                return self.getDeviceSuperPassword(request_dict, response)
+            if operation == 'deleteInformation':  # 删除超级密码请求表
+                return self.deleteInformation(request_dict, response)
             else:
                 return response.json(404)
 
@@ -760,3 +767,113 @@ class UserManagement(View):
             return response.json(0, {'list': feed_back_list})
         except Exception as e:
             print(e)
+
+    def customerServiceManagement(self, request_dict, response):
+        """
+        审核用户请求/生成超级密码
+        @param request_dict:请求参数
+        @param response:响应对象
+        @return:
+        """
+        ID = request_dict.get('ID', None)
+        userID = request_dict.get('userID', None)
+        uid = request_dict.get('uid', None)
+        status = request_dict.get('status', None)
+        hint = request_dict.get('hint', None)
+        lang = request_dict.get('lang', 'en')
+        if not all({ID, uid, userID}):
+            return response.json(444)
+        now = int(time.time())
+        try:
+            with transaction.atomic():
+                device_super_password_qs = DeviceSuperPassword.objects.filter(id=ID, uid=uid, userID=userID)
+                if not device_super_password_qs.exists():
+                    return response.json(173)
+                status = int(status)
+                if status == 1:
+                    # 验证码生成
+                    super_code = RandomStr(6, True)
+                    super_password_id = "super_password_%s" % userID
+                    redisObj = RedisObject()
+                    redis = redisObj.set_data(key=super_password_id, val=super_code, expire=86400)
+                    if redis is False:
+                        return response.json(121)
+                    device_super_password_qs.update(status=status)
+                    if lang == 'en':
+                        msg = "Your authorization code is " + super_code + ",valid within 24 hours"
+                    else:
+                        msg = "您的授权代码:" + super_code + ",24小时内有效"
+                    SysMsgModel.objects.create(userID_id=userID, msg=msg, addTime=now, updTime=now, uid=uid,
+                                               eventType=2)
+                    return response.json(0)
+                if status == 0 and len(hint) > 1:
+                    device_super_password_qs.update(status=status, hint=hint)
+                    msg = hint
+                    SysMsgModel.objects.create(userID_id=userID, msg=msg, addTime=now, updTime=now, uid=uid,
+                                               eventType=2)
+                    return response.json(0)
+                return response.json(177)
+        except Exception as e:
+            print('修改状态异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            return response.json(500, repr(e))
+
+    def getDeviceSuperPassword(self, request_dict, response):
+        """
+        查询用户请求表
+        @param request_dict:请求参数
+        @param response:响应对象
+        @return:
+        """
+        pageNo = request_dict.get('pageNo', None)
+        pageSize = request_dict.get('pageSize', None)
+        status = request_dict.get('status', None)
+        userID = request_dict.get('userID', None)
+        uid = request_dict.get('uid', None)
+        if not all([pageNo, pageSize]):
+            return response.json(444)
+        page = int(pageNo)
+        line = int(pageSize)
+        try:
+            device_super_password_qs = DeviceSuperPassword.objects.all()
+            if status:
+                device_super_password_qs = device_super_password_qs.filter(status=status)
+            if userID:
+                device_super_password_qs = device_super_password_qs.filter(userID=userID)
+            if uid:
+                device_super_password_qs = device_super_password_qs.filter(uid=uid)
+            if not device_super_password_qs.exists():
+                return response.json(0, [])
+            count = device_super_password_qs.count()
+            device_super_password_qs = device_super_password_qs.values('id',
+                                                                       'uid',
+                                                                       'userID',
+                                                                       'orderID',
+                                                                       'describe',
+                                                                       'purchase_channel',
+                                                                       'addTime',
+                                                                       'status',
+                                                                       'buyTime',
+                                                                       'hint',
+                                                                       'lang',
+                                                                       'userID__username')
+            device_super_password_qs = device_super_password_qs.order_by('-addTime')[
+                                       (page - 1) * line:page * line]
+            return response.json(0, {'list': list(device_super_password_qs), 'count': count})
+        except Exception as e:
+            print('查询异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            return response.json(500, repr(e))
+
+    def deleteInformation(self, request_dict, response):
+        """
+        删除信息
+        @param request_dict:请求参数
+        @param response:响应对象
+        """
+        ID = request_dict.get('id', None)
+        if not ID:
+            return response.json(444)
+        device_super_password_qs = DeviceSuperPassword.objects.filter(id=ID)
+        if not device_super_password_qs.exists():
+            return response.json(173)
+        device_super_password_qs.delete()
+        return response.json(0)

+ 3 - 3
Ansjer/eur_config/config_formal.py

@@ -40,9 +40,9 @@ TUTK_PUSH_DOMAIN = 'http://push.iotcplatform.com/tpns'
 
 # PayPal
 PAYPAL_CRD = {
-    "mode": "sandbox",  # sandbox or live
-    "client_id": "AVLoQVq3xHZ6FrF4mxHwlCPgVBAw4Fw5RtMkuxmYd23SkUTIY643n2g3KdK-Al8wV05I28lza5uoQbAA",
-    "client_secret": "EO8kRc8yioDk0i2Qq-QMcVFfwkmyMJorTvBSLDTnxDJJ_wb9VoM_0jkUY9iEng2Flp1ze8wQOGpH5nB2"
+    "mode": "live",  # sandbox or live
+    "client_id": "AdSRd6WBn-qLl9OiQHQuNYTDFSx0ZX0RUttqa58au8bPzoGYQUrt8bc6591RmH8_pEAIPijdvVYSVXyI",
+    "client_secret": "ENT-J08N3Fw0B0uAokg4RukljAwO9hFHPf8whE6-Dwd8oBWJO8AWMgpdTKpfB1pOy89t4bsFEzMWDowm"
 }
 PAYPAL_WEB_HOOK_ID = '3YH86681TH784461T'
 PAYPAL_WEB_HOOK_ID_TWO = '7TN87895N70389928'

+ 225 - 334
Ansjer/urls.py

@@ -1,6 +1,6 @@
-from django.conf.urls import url
 from django.contrib import admin
-from django.urls import path, re_path
+from django.urls import include
+from django.urls import re_path
 
 from AdminController import UserManageController, RoleController, MenuController, TestServeController, \
     ServeManagementController, LogManagementController, DeviceManagementController, VersionManagementController, \
@@ -22,353 +22,246 @@ from Controller import FeedBack, EquipmentOTA, EquipmentInfo, AdminManage, AppIn
     OrderTaskController, HistoryUIDController, UIDManageUserController, SerialNumberController, CompanyController, \
     RegionController, VPGController, LanguageController, TestController, DeviceConfirmRegion, S3GetStsController, \
     DetectControllerV2, PcInfo, PctestController, DeviceDebug, PaymentCycle, \
-    DeviceLogController, CouponController, AiController, ShadowController, AppAccountManagement
+    DeviceLogController, CouponController, AiController, ShadowController, SuperPasswordTool
 from Controller.Cron import CronTaskController
 from Controller.MessagePush import EquipmentMessagePush
-from Controller.Surveys import CloudStorageController
 from Controller.SensorGateway import SensorGatewayController, EquipmentFamilyController
-from django.urls import include
-
+from Controller.Surveys import CloudStorageController
 from Controller.UserDevice import UserDeviceShareController
 
 urlpatterns = [
-    url(r'^testApi/(?P<operation>.*)$', TestApi.testView.as_view()),
-    url(r'^account/authcode$', UserController.authCodeView.as_view()),
-    url(r'^v3/account/generatepictureCodeView/$', UserController.generatePictureCodeView.as_view()),
-    url(r'^v3/account/imageCodeRegister/$', UserController.Image_Code_RegisterView.as_view()),
-    url(r'^account/register$', UserController.registerView.as_view()),
-    url(r'^account/login$', UserController.v2LoginView.as_view()),
-    url(r'^account/logout$', UserController.LogoutView.as_view()),
-    url(r'^account/noPasslogin$', UserController.noPasslogin.as_view()),
-    url(r'^account/changePwd$', UserController.ChangePwdView.as_view()),
-    url(r'^account/forget$', UserController.ForgetPwdView.as_view()),
-    url(r'^account/email-re-pwd$', UserController.EmailResetPwdView.as_view()),
-    url(r'^account/refreshTk$', UserController.refreshTokenView.as_view()),
-    url(r'^v3/account/refreshTk$', UserController.refreshTokenViewV3.as_view()),
-    url(r'^v3/account/deleteUser$', UserController.DeleteUser.as_view()),
-    url(r'^favicon.ico$', UserManger.success, name=u'favicon.ico'),
-    url(r'^account/showUserMore$', UserManger.showUserMoreView.as_view()),
-    url(r'^account/perfectUserInfo$', UserManger.perfectUserInfoView.as_view()),
-    url(r'^account/getAvatar/(?P<filePath>.*)$', UserManger.getAvatarView.as_view()),
-    url(r'^account/delUser$', UserManger.delUserInterface),
-    url(r'^account/setUserValid$', UserManger.setUserValidView.as_view()),
-    url(r'^account/showAllUser$', UserManger.showAllUserInterface),
-    url(r'^account/help$', LogManager.HelpView.as_view()),
-    url(r'^account/searchUser$', shareUserPermission.searchUserView.as_view()),
-    path('accounts', AdminManage.search_user_by_content),  # 多条件搜索用户信息admin
-    url(r'^account/shareUserEquipment$', shareUserPermission.shareUserEquipmentView.as_view()),
-    url(r'^account/unsharedUserEquipment$', shareUserPermission.unsharedUserEquipmentView.as_view()),
-    url(r'^response/success$', UserManger.success),
-    url(r'^equipment/queryUserEquipment$', EquipmentManager.queryUserEquipmentInterface),
-    url(r'^equipment/addNewUserEquipment$', EquipmentManager.addNewUserEquipmentInterface),
-    url(r'^equipment/delUserEquipment$', EquipmentManager.delUserEquipmentInterface),
-    url(r'^equipment/modifyUserEquipment$', EquipmentManager.modifyUserEquipmentInterface),
-    url(r'^equipment/showAllUserEquipment$', EquipmentManager.showAllUserEquipmentInterface),
-    url(r'^equipment/findEquipmentInfo$', EquipmentManager.findEquipmentInfoInterface),
-    # 新删除设备接口
-    url(r'^equipment/delete', EquipmentManager.deleteInterface),
-    url(r'^equipment/batchDelete', EquipmentManager.batchDeleteInterface),
-    url(r'^equipment/add', EquipmentManager.addInterface),
-    url(r'^equipment/admin_add', EquipmentManager.admin_addInterface),
-    url(r'^equipment/admin_modify', EquipmentManager.admin_modifyInterface),
-
-    url(r'^equipment/query', EquipmentManager.queryInterface),
-    # 获取设备影子信息接口
-    url(r'^equipment/flow$', EquipmentManager.uid_status),
-
-    url(r'^OTA/uploads$', OTAEquipment.getUploadFiletoDirView.as_view()),
-    url(r'^OTA/download$', OTAEquipment.downloadUpdataFileUrl),
-    url(r'^OTA/downloads/(\w+)/(\w+[\w+]*.+[^_w]*.\w+)$', OTAEquipment.downloadUpdataFileUrlInterface),
-    url(r'^OTA/getEquipmentVersion$', OTAEquipment.getEquipmentVersionInterface),
-    url(r'^OTA/getUpdataFileUrl$', OTAEquipment.getUpdataFileUrlInterface),
-    url(r'^OTA/addNewEquipmentVersion$', OTAEquipment.addNewEquipmentVersionInterface),
-
-    url(r'^roles/addNewRole$', PermissionManager.addNewRoleView.as_view()),
-    url(r'^roles/queryRole$', PermissionManager.queryRoleView.as_view()),
-    url(r'^roles/delRole$', PermissionManager.delRoleView.as_view()),
-    url(r'^roles/modifyRole$', PermissionManager.modifyRoleView.as_view()),
-    url(r'^perms/addNewPerms$', PermissionManager.addNewPermsView.as_view()),
-    url(r'^perms/delPerms$', PermissionManager.delPermsView.as_view()),
-    url(r'^perms/queryPerms$', PermissionManager.queryPermsView.as_view()),
-    url(r'^perms/modifyPerms$', PermissionManager.modifyPermsView.as_view()),
-    url(r'^permsManager/queryRolePerms$', PermissionManager.queryRolePermsView.as_view()),
-    url(r'^uploads/upgrade$', OTAEquipment.getUploadFiletoDirView.as_view()),
-    url(r'^upgrade/download/(\w+.[^_w]*\w+.\w+)$', CheckUserData.download_file),
-    url(r'^downloads/upgrade/(\w+)/(\w+.[^_w]*\w+.\w+)$', OTAEquipment.downloadUpdataFileUrlInterface),
-    url(r'^getOTAurl/getUpdataFileUrl$', OTAEquipment.getUpdataFileUrlInterface),
-    url(r'^equipment/info', EquipmentInfo.EquipmentInfo.as_view()),
-    url(r'^adminManage/manage', AdminManage.AdminManage.as_view()),  # 管理员专属view
-    url(r'^equipment/OTA', EquipmentOTA.EquipmentOTA.as_view()),  # OTA重构类
-    url(r'^userbrandinfo/(?P<operation>.*)$', UserBrandController.UserBrandInfo.as_view()),  # 用户登录的手机端品牌记录统计信息表
-
-    url(r'^uidset/(?P<operation>.*)$', UidSetController.UidSetView.as_view()),
-    url(r'^appInfo', AppInfo.AppInfo.as_view()),  # app版本信息
-
-    url(r'^meal/manage', MealManage.MealManage.as_view()),
-    url(r'^device/manage$', DeviceManage.DeviceManage.as_view()),
-    # 设备在线
-    url(r'^device/online$', EquipmentStatus.EquipmentOnline),
-    # 设备离线
-    url(r'^device/offline$', EquipmentStatus.EquipmentOffline),
-    # 设备离线
-    url(r'^device/updateIP$', EquipmentStatus.updateIP),
-    # 系统ctr
-    url(r'^sys/updateLog', SysManage.updateLog),
-    url(r'^devices/(\w+)/logs$', DeviceLog.DeviceLog),
-    url(r'^devices/(\w+)$', DeviceManage.Devices),
-    # 访问日志 mongodb版
-    url(r'^LogAccess$', LogAccess.LogAccess),
-    # 上传操作文档
-    url(r'^HelpCHM/upload$', LogManager.upload_help_chm),
-    url(r'^admin/userIDs$', AdminManage.getUserIds),
-    path('eq/delById', EquipmentInfo.deleteExpireEquipmentInfoById),
-    # 新需求ota接口
-    url(r'^OTA/getNewVer', OTAEquipment.getNewVerInterface),
-    url(r'^OTA/uploadsPack$', OTAEquipment.uploadOTAInterfaceView.as_view()),
-    url(r'^OTA/downloadsPack/(?P<fullPath>[0-9\w/.\-]+)', OTAEquipment.downloadOTAInterface),
-    url(r'^dlotapack/(?P<fullPath>[0-9\w/.\-]+)', OTAEquipment.downloadOTAInterfaceV2),
-    url(r'^OTA/getDownLoadOTApackUrl$', OTAEquipment.getDownLoadOTApackUrl),
-    url(r'^OTA/checkMaxVersion$', OTAEquipment.checkMaxVersion),
-
-    # h获取验证码    # v2接口
-    url(r'^v2/account/authcode$', UserController.v2authCodeView.as_view()),
-    url(r'^v2/account/register$', UserController.v2registerView.as_view()),
-    url(r'^v2/account/forgetCode$', UserController.v2forgetPwdCodeView.as_view()),
-    url(r'^v2/account/resetPwdByCode$', UserController.v2resetPwdByCodeView.as_view()),
-
-    # 重置密码验证码校验
-    url(r'^v2/authcode/verify$', UserController.verifyAuthcode.as_view()),
-    url(r'^v2/account/logout$', UserController.V2LogoutView.as_view()),
-    url(r'^v2/account/login$', UserController.v3LoginView.as_view()),
-    url(r'^v3/account/login$', UserController.v3LoginView.as_view()),
-    url(r'^account/oneClickLogin$', UserController.oneClickLoginView.as_view()),
-    url(r'^account/createPwd$', UserController.createPwd.as_view()),
-
-    # 用户删除/注销
-    url(r'^account/delete$', UserController.deleteAccount),
-
-    # 确认地区
-    url(r'^user/confirmRegion$', UserController.confirmRegion),
-
-    # 验证码登录
-    url(r'^account/loginCode$', UserController.loginCodeView.as_view()),
-    url(r'^v3/account/loginByCode$', UserController.v3LoginByCodeView.as_view()),
-
-    # 指纹登录
-    url(r'^v3/account/loginByFingerprint$', UserController.v3LoginByFingerprintView.as_view()),
-    url(r'^v3/account/setFingerprint$', UserController.v3SetFingerprintView.as_view()),
-
-    # 推送项目接口
-    url(r'^detect/(?P<operation>.*)$', DetectController.DetectControllerView.as_view()),
-    url(r'^detectV2/(?P<operation>.*)$', DetectControllerV2.DetectControllerViewV2.as_view()),
-
-    # 新增
-    url(r'^cloudVod/(?P<operation>.*)$', CloudVod.CloudVodView.as_view()),
-    url(r'^meal/(?P<operation>.*)$', MealManage.MealView.as_view()),
-    url(r'^order/(?P<operation>.*)$', OrderContrller.OrderView.as_view()),
-    url(r'^appCol/(?P<operation>.*)$', AppColophon.AppColView.as_view()),
-    url(r'^vodBucket/(?P<operation>.*)$', VodBucket.VodBucketView.as_view()),
-    url(r'^UIDBucket/(?P<operation>.*)$', VodBucket.UidBucketView.as_view()),
-    url(r'^EquipmentVersion/(?P<operation>.*)$', EquipmentOTA.EquipmentVersionView.as_view()),
-
-    url(r'^deviceShare/(?P<operation>.*)$', DeviceShare.DeviceShareView.as_view()),
-    url(r'^appVer/views$', AppInfo.AppVersionView.as_view()),
-
-    # 屏蔽
-    url(r'^user/initInfo$', UserController.InitInfoView.as_view()),
-    url(r'^user/information/(?P<operation>.*)$', UserController.InitUserInformationView.as_view()),
-    # 获取时区相关信息
-    url(r'^getTZ$', EquipmentStatus.getTZ),
-
-    # oss授权
-    url(r'^stsOss/(?P<operation>.*)$', StsOssController.StsOssView.as_view()),
-
-    # 用户反馈信息
-    url(r'^feedback/(?P<operation>.*)$', FeedBack.FeedBackView.as_view()),
-    url(r'^uidpreview/(?P<operation>.*)$', UIDPreview.UIDPreview.as_view()),
-    url(r'^sysmsg/(?P<operation>.*)$', SysMsg.SysMsgView.as_view()),
-    url(r'^sysfile/(?P<filePath>.*)$', SysManage.getStatView.as_view()),
-
-    url(r'^equipment/flowUpdate', EquipmentManager.update_uid_set),
-
-    url(r'^log/getUploadUrl', EquipmentStatus.getUploadLogUrl),
-    url(r'^app/getIdData', AppInfo.AppIdDataView.as_view()),
-    url(r'^wechat/authsign', UserController.wxAuthSignView.as_view()),
-    url(r'^wechat/perfect', UserController.wxPerfectView.as_view()),
-    # 分区分流
-    path('Test', Test.Test.as_view()),
-    # 微信绑定的用户获取验证码
-    url(r'^oauth/authcode', UserController.OauthAuthCodeView.as_view()),
-    url(r'^oauth/perfect', UserController.OauthPerfectView.as_view()),
-    url(r'^oauth/unbunding', UserController.UnbundingWXView.as_view()),
-
-    url(r'^equipment/judge', EquipmentManager.judgeInterface),
-
-    # ap模式,新增设备表
-    url(r'^uiduser/add', UidUser.addInterface),
-    url(r'^uiduser/query', UidUser.queryInterface),
-    url(r'^uiduser/update', UidUser.updateInterface),
-    url(r'^uiduser/delete', UidUser.deleteInterface),
-    url(r'^uid_user/(?P<operation>.*)$', UidUser.UidUserView.as_view()),
-    # add query update delete
-    url(r'^v2/equipment/(?P<operation>.*)$', EquipmentManagerV2.EquipmentManagerV2.as_view()),
-
-    url(r'^msg/init', SysManage.initMsgFunc),
-
-    url(r'^oss_crd/(?P<operation>.*)$', OssCrd.OssCrdView.as_view()),
-    url(r'^push_deploy/(?P<operation>.*)$', PushDeploy.PushDeployView.as_view()),
-    url(r'^oalexa/auth', UserController.alexaAuthView.as_view()),
-    url(r'^oalexa/discoveryuid', UserController.alexaUidView.as_view()),
-
-    url(r'^appset/(?P<operation>.*)$', AppSetController.AppSetView.as_view()),
-    url(r'^application/(?P<operation>.*)$', ApplicationController.ApplicationView.as_view()),
-    url(r'^login/oauth/(?P<operation>.*)$', ApplicationController.AuthView.as_view()),
-    url(r'^grant/code/(?P<operation>.*)$', ApplicationController.GrantCodeView.as_view()),
-    url(r'^user/ex/(?P<operation>.*)$', UserExController.UserExView.as_view()),
-    url(r'^v3/equipment/(?P<operation>.*)$', EquipmentManagerV3.EquipmentManagerV3.as_view()),
-    url(r'^cloudstorage/(?P<operation>.*)$', CloudStorage.CloudStorageView.as_view()),
-    url(r'^payCycle/(?P<operation>.*)$', PaymentCycle.PaypalCycleNotify.as_view()),  # 周期扣款
-    url(r'^paypalCycleNotify/(?P<operation>.*)$', PaymentCycle.PaypalCycleNotify.as_view()),  # paypal周期扣款订阅通知
-    url(r'^paymentCycle/(?P<operation>.*)$', PaymentCycle.payCycle.as_view()),  # paypal周期扣款
-
-    # AI服务
-    url(r'^AiService/(?P<operation>.*)$', AiController.AiView.as_view()),
-    # 消息提醒
-    url(r'^app/setting/notification/(?P<operation>.*)$', EquipmentMessagePush.EquipmentMessagePushView.as_view()),
-
-    # 新增解密的接口
-    url(r'^v3/account/changePwd$', UserController.v3ChangePwdView.as_view()),
-    url(r'^v3/account/resetPwdByCode$', UserController.v3resetPwdByCodeView.as_view()),
-    url(r'^v3/account/register$', UserController.v3registerView.as_view()),
-    url(r'^v3/uiduser/add', UidUser.v3addInterface),
-    url(r'^v3/uiduser/query', UidUser.v3queryInterface),
-    # 判断节假日接口
-    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'^statistcs/appFrequencyMonth$', StatisticsController.statistcsAppFrequency),
-    url(r'^statistcs/appFrequencyYear$', StatisticsController.statistcsAppFrequencyYear),
-    url(r'^statistcs/pushDay$', StatisticsController.statistcsPushDay),
-    url(r'^statistcs/pushMonth$', StatisticsController.statistcsPushMonth),
-
-    # 统计alexa连接数
-    url(r'^alexa/(?P<operation>.*)$', Alexa.AlexaConnectNum.as_view()),
-
-    # FAQ
-    url(r'^faq/upload', FAQController.FAQUploadView.as_view()),
-    url(r'^faq/image/(?P<filePath>.*)$', FAQController.getFAQImage.as_view()),
-    url(r'^faq/(?P<operation>.*)$', FAQController.FAQView.as_view()),
-
-    # 苹果登录
-    url(r'^ios/authsign', UserController.AppleAuthLogin.as_view()),
-    # app/设备上传日志接口
-    url(r'^appLog/(?P<operation>.*)$', AppLogController.AppLogView.as_view()),
-    url(r'^deviceLog/(?P<operation>.*)$', DeviceLogController.DeviceLogView.as_view()),
-    # 本地登录接口
-    url(r'^local/(?P<operation>.*)$', UserController.LocalUserView.as_view()),
-
-    url(r'^account/updateUserCountry', UserController.updateUserCountry),
-    url(r'^equipmentVersionLimit/(?P<operation>.*)$', EquipmentVersionLimit.EquipmentVersionLimitView.as_view()),
-
-    # 订阅邮件
-    url(r'^account/subscribe$', UserController.SubscribeEmailView.as_view()),
-    url(r'^account/subscribe/download$', UserController.SubscribeEmailView.as_view()),
-
-    # 语音提示
-    url(r'^voicePrompt/(?P<operation>.*)$', VoicePromptController.VoicePromptView.as_view()),
-    # 设备类型
-    url(r'^deviceType/(?P<operation>.*)$', DeviceTypeController.DeviceTypeView.as_view()),
-
-    # cdk(激活码)
-    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()),
-
-    # 云存服务统计
-    url(r'^Cloudsum/(?P<operation>.*)$', Cloudsum.Cloudsum.as_view()),
-    # 设备ip地区统计
-    url(r'^device/StatisticsIpRegion$', DeviceConfirmRegion.StatisticsIpRegion.as_view()),
-
-    # Iot Core
-    re_path('iot/(?P<operation>.*)$', IotCoreController.IotCoreView.as_view()),
-
-    # S3预签名
-    url(r's3_getsts/(?P<operation>.*)$', S3GetStsController.S3GetStsView.as_view()),
-
-    # 云分配UID
-    path('admin/', admin.site.urls),
+    re_path(r'^testApi/(?P<operation>.*)', TestApi.testView.as_view()),
+    re_path(r'^account/authcode', UserController.authCodeView.as_view()),
+    re_path(r'^v3/account/generatepictureCodeView/$', UserController.generatePictureCodeView.as_view()),
+    re_path(r'^v3/account/imageCodeRegister/$', UserController.Image_Code_RegisterView.as_view()),
+    re_path(r'^account/register$', UserController.registerView.as_view()),
+    re_path(r'^account/login$', UserController.v2LoginView.as_view()),
+    re_path(r'^account/logout$', UserController.LogoutView.as_view()),
+    re_path(r'^account/noPasslogin$', UserController.noPasslogin.as_view()),
+    re_path(r'^account/changePwd$', UserController.ChangePwdView.as_view()),
+    re_path(r'^account/forget$', UserController.ForgetPwdView.as_view()),
+    re_path(r'^account/email-re-pwd$', UserController.EmailResetPwdView.as_view()),
+    re_path(r'^account/refreshTk$', UserController.refreshTokenView.as_view()),
+    re_path(r'^v3/account/refreshTk$', UserController.refreshTokenViewV3.as_view()),
+    re_path(r'^v3/account/deleteUser$', UserController.DeleteUser.as_view()),
+    re_path(r'^favicon.ico$', UserManger.success, name=u'favicon.ico'),
+    re_path(r'^account/showUserMore$', UserManger.showUserMoreView.as_view()),
+    re_path(r'^account/perfectUserInfo$', UserManger.perfectUserInfoView.as_view()),
+    re_path(r'^account/getAvatar/(?P<filePath>.*)$', UserManger.getAvatarView.as_view()),
+    re_path(r'^account/delUser$', UserManger.delUserInterface),
+    re_path(r'^account/setUserValid$', UserManger.setUserValidView.as_view()),
+    re_path(r'^account/showAllUser$', UserManger.showAllUserInterface),
+    re_path(r'^account/help$', LogManager.HelpView.as_view()),
+    re_path(r'^account/searchUser$', shareUserPermission.searchUserView.as_view()),
+    re_path('accounts', AdminManage.search_user_by_content),  # 多条件搜索用户信息admin
+    re_path(r'^account/shareUserEquipment$', shareUserPermission.shareUserEquipmentView.as_view()),
+    re_path(r'^account/unsharedUserEquipment$', shareUserPermission.unsharedUserEquipmentView.as_view()),
+    re_path(r'^response/success$', UserManger.success),
+    re_path(r'^equipment/queryUserEquipment$', EquipmentManager.queryUserEquipmentInterface),
+    re_path(r'^equipment/addNewUserEquipment$', EquipmentManager.addNewUserEquipmentInterface),
+    re_path(r'^equipment/delUserEquipment$', EquipmentManager.delUserEquipmentInterface),
+    re_path(r'^equipment/modifyUserEquipment$', EquipmentManager.modifyUserEquipmentInterface),
+    re_path(r'^equipment/showAllUserEquipment$', EquipmentManager.showAllUserEquipmentInterface),
+    re_path(r'^equipment/findEquipmentInfo$', EquipmentManager.findEquipmentInfoInterface),
+    re_path(r'^equipment/delete', EquipmentManager.deleteInterface),
+    re_path(r'^equipment/batchDelete', EquipmentManager.batchDeleteInterface),
+    re_path(r'^equipment/add', EquipmentManager.addInterface),
+    re_path(r'^equipment/admin_add', EquipmentManager.admin_addInterface),
+    re_path(r'^equipment/admin_modify', EquipmentManager.admin_modifyInterface),
+    re_path(r'^equipment/query', EquipmentManager.queryInterface),
+    re_path(r'^equipment/flow$', EquipmentManager.uid_status),
+    re_path(r'^OTA/uploads$', OTAEquipment.getUploadFiletoDirView.as_view()),
+    re_path(r'^OTA/download$', OTAEquipment.downloadUpdataFileUrl),
+    re_path(r'^OTA/downloads/(\w+)/(\w+[\w+]*.+[^_w]*.\w+)$', OTAEquipment.downloadUpdataFileUrlInterface),
+    re_path(r'^OTA/getEquipmentVersion$', OTAEquipment.getEquipmentVersionInterface),
+    re_path(r'^OTA/getUpdataFileUrl$', OTAEquipment.getUpdataFileUrlInterface),
+    re_path(r'^OTA/addNewEquipmentVersion$', OTAEquipment.addNewEquipmentVersionInterface),
+    re_path(r'^roles/addNewRole$', PermissionManager.addNewRoleView.as_view()),
+    re_path(r'^roles/queryRole$', PermissionManager.queryRoleView.as_view()),
+    re_path(r'^roles/delRole$', PermissionManager.delRoleView.as_view()),
+    re_path(r'^roles/modifyRole$', PermissionManager.modifyRoleView.as_view()),
+    re_path(r'^perms/addNewPerms$', PermissionManager.addNewPermsView.as_view()),
+    re_path(r'^perms/delPerms$', PermissionManager.delPermsView.as_view()),
+    re_path(r'^perms/queryPerms$', PermissionManager.queryPermsView.as_view()),
+    re_path(r'^perms/modifyPerms$', PermissionManager.modifyPermsView.as_view()),
+    re_path(r'^permsManager/queryRolePerms$', PermissionManager.queryRolePermsView.as_view()),
+    re_path(r'^uploads/upgrade$', OTAEquipment.getUploadFiletoDirView.as_view()),
+    re_path(r'^upgrade/download/(\w+.[^_w]*\w+.\w+)$', CheckUserData.download_file),
+    re_path(r'^downloads/upgrade/(\w+)/(\w+.[^_w]*\w+.\w+)$', OTAEquipment.downloadUpdataFileUrlInterface),
+    re_path(r'^getOTAurl/getUpdataFileUrl$', OTAEquipment.getUpdataFileUrlInterface),
+    re_path(r'^equipment/info', EquipmentInfo.EquipmentInfo.as_view()),
+    re_path(r'^adminManage/manage', AdminManage.AdminManage.as_view()),
+    re_path(r'^equipment/OTA', EquipmentOTA.EquipmentOTA.as_view()),
+    re_path(r'^userbrandinfo/(?P<operation>.*)$', UserBrandController.UserBrandInfo.as_view()),
+    re_path(r'^uidset/(?P<operation>.*)$', UidSetController.UidSetView.as_view()),
+    re_path(r'^appInfo', AppInfo.AppInfo.as_view()),
+    re_path(r'^meal/manage', MealManage.MealManage.as_view()),
+    re_path(r'^device/manage$', DeviceManage.DeviceManage.as_view()),
+    re_path(r'^device/online$', EquipmentStatus.EquipmentOnline),
+    re_path(r'^device/offline$', EquipmentStatus.EquipmentOffline),
+    re_path(r'^device/updateIP$', EquipmentStatus.updateIP),
+    re_path(r'^sys/updateLog', SysManage.updateLog),
+    re_path(r'^devices/(\w+)/logs$', DeviceLog.DeviceLog),
+    re_path(r'^devices/(\w+)$', DeviceManage.Devices),
+    re_path(r'^LogAccess$', LogAccess.LogAccess),
+    re_path(r'^HelpCHM/upload$', LogManager.upload_help_chm),
+    re_path(r'^admin/userIDs$', AdminManage.getUserIds),
+    re_path('eq/delById', EquipmentInfo.deleteExpireEquipmentInfoById),
+    re_path(r'^OTA/getNewVer', OTAEquipment.getNewVerInterface),
+    re_path(r'^OTA/uploadsPack$', OTAEquipment.uploadOTAInterfaceView.as_view()),
+    re_path(r'^OTA/downloadsPack/(?P<fullPath>[0-9\w/.\-]+)', OTAEquipment.downloadOTAInterface),
+    re_path(r'^dlotapack/(?P<fullPath>[0-9\w/.\-]+)', OTAEquipment.downloadOTAInterfaceV2),
+    re_path(r'^OTA/getDownLoadOTApackUrl$', OTAEquipment.getDownLoadOTApackUrl),
+    re_path(r'^OTA/checkMaxVersion$', OTAEquipment.checkMaxVersion),
+    re_path(r'^v2/account/authcode$', UserController.v2authCodeView.as_view()),
+    re_path(r'^v2/account/register$', UserController.v2registerView.as_view()),
+    re_path(r'^v2/account/forgetCode$', UserController.v2forgetPwdCodeView.as_view()),
+    re_path(r'^v2/account/resetPwdByCode$', UserController.v2resetPwdByCodeView.as_view()),
+    re_path(r'^v2/authcode/verify$', UserController.verifyAuthcode.as_view()),
+    re_path(r'^v2/account/logout$', UserController.V2LogoutView.as_view()),
+    re_path(r'^v2/account/login$', UserController.v3LoginView.as_view()),
+    re_path(r'^v3/account/login$', UserController.v3LoginView.as_view()),
+    re_path(r'^account/oneClickLogin$', UserController.oneClickLoginView.as_view()),
+    re_path(r'^account/createPwd$', UserController.createPwd.as_view()),
+    re_path(r'^account/delete$', UserController.deleteAccount),
+    re_path(r'^user/confirmRegion$', UserController.confirmRegion),
+    re_path(r'^account/loginCode$', UserController.loginCodeView.as_view()),
+    re_path(r'^v3/account/loginByCode$', UserController.v3LoginByCodeView.as_view()),
+    re_path(r'^v3/account/loginByFingerprint$', UserController.v3LoginByFingerprintView.as_view()),
+    re_path(r'^v3/account/setFingerprint$', UserController.v3SetFingerprintView.as_view()),
+    re_path(r'^detect/(?P<operation>.*)$', DetectController.DetectControllerView.as_view()),
+    re_path(r'^detectV2/(?P<operation>.*)$', DetectControllerV2.DetectControllerViewV2.as_view()),
+    re_path(r'^cloudVod/(?P<operation>.*)$', CloudVod.CloudVodView.as_view()),
+    re_path(r'^meal/(?P<operation>.*)$', MealManage.MealView.as_view()),
+    re_path(r'^order/(?P<operation>.*)$', OrderContrller.OrderView.as_view()),
+    re_path(r'^appCol/(?P<operation>.*)$', AppColophon.AppColView.as_view()),
+    re_path(r'^vodBucket/(?P<operation>.*)$', VodBucket.VodBucketView.as_view()),
+    re_path(r'^UIDBucket/(?P<operation>.*)$', VodBucket.UidBucketView.as_view()),
+    re_path(r'^EquipmentVersion/(?P<operation>.*)$', EquipmentOTA.EquipmentVersionView.as_view()),
+    re_path(r'^deviceShare/(?P<operation>.*)$', DeviceShare.DeviceShareView.as_view()),
+    re_path(r'^appVer/views$', AppInfo.AppVersionView.as_view()),
+    re_path(r'^user/initInfo$', UserController.InitInfoView.as_view()),
+    re_path(r'^user/information/(?P<operation>.*)$', UserController.InitUserInformationView.as_view()),
+    re_path(r'^getTZ$', EquipmentStatus.getTZ),
+    re_path(r'^stsOss/(?P<operation>.*)$', StsOssController.StsOssView.as_view()),
+    re_path(r'^feedback/(?P<operation>.*)$', FeedBack.FeedBackView.as_view()),
+    re_path(r'^uidpreview/(?P<operation>.*)$', UIDPreview.UIDPreview.as_view()),
+    re_path(r'^sysmsg/(?P<operation>.*)$', SysMsg.SysMsgView.as_view()),
+    re_path(r'^sysfile/(?P<filePath>.*)$', SysManage.getStatView.as_view()),
+    re_path(r'^equipment/flowUpdate', EquipmentManager.update_uid_set),
+    re_path(r'^log/getUploadUrl', EquipmentStatus.getUploadLogUrl),
+    re_path(r'^app/getIdData', AppInfo.AppIdDataView.as_view()),
+    re_path(r'^wechat/authsign', UserController.wxAuthSignView.as_view()),
+    re_path(r'^wechat/perfect', UserController.wxPerfectView.as_view()),
+    re_path(r'^Test', Test.Test.as_view()),
+    re_path(r'^oauth/authcode', UserController.OauthAuthCodeView.as_view()),
+    re_path(r'^oauth/perfect', UserController.OauthPerfectView.as_view()),
+    re_path(r'^oauth/unbunding', UserController.UnbundingWXView.as_view()),
+    re_path(r'^equipment/judge', EquipmentManager.judgeInterface),
+    re_path(r'^uiduser/add', UidUser.addInterface),
+    re_path(r'^uiduser/query', UidUser.queryInterface),
+    re_path(r'^uiduser/update', UidUser.updateInterface),
+    re_path(r'^uiduser/delete', UidUser.deleteInterface),
+    re_path(r'^uid_user/(?P<operation>.*)$', UidUser.UidUserView.as_view()),
+    re_path(r'^v2/equipment/(?P<operation>.*)$', EquipmentManagerV2.EquipmentManagerV2.as_view()),
+    re_path(r'^msg/init', SysManage.initMsgFunc),
+    re_path(r'^oss_crd/(?P<operation>.*)$', OssCrd.OssCrdView.as_view()),
+    re_path(r'^push_deploy/(?P<operation>.*)$', PushDeploy.PushDeployView.as_view()),
+    re_path(r'^oalexa/auth', UserController.alexaAuthView.as_view()),
+    re_path(r'^oalexa/discoveryuid', UserController.alexaUidView.as_view()),
+    re_path('appset/(?P<operation>.*)', AppSetController.AppSetView.as_view()),
+    re_path(r'^application/(?P<operation>.*)$', ApplicationController.ApplicationView.as_view()),
+    re_path(r'^login/oauth/(?P<operation>.*)$', ApplicationController.AuthView.as_view()),
+    re_path(r'^grant/code/(?P<operation>.*)$', ApplicationController.GrantCodeView.as_view()),
+    re_path(r'^user/ex/(?P<operation>.*)$', UserExController.UserExView.as_view()),
+    re_path(r'^v3/equipment/(?P<operation>.*)$', EquipmentManagerV3.EquipmentManagerV3.as_view()),
+    re_path(r'^cloudstorage/(?P<operation>.*)$', CloudStorage.CloudStorageView.as_view()),
+    re_path(r'^payCycle/(?P<operation>.*)$', PaymentCycle.PaypalCycleNotify.as_view()),
+    re_path(r'^paypalCycleNotify/(?P<operation>.*)$', PaymentCycle.PaypalCycleNotify.as_view()),
+    re_path(r'^paymentCycle/(?P<operation>.*)$', PaymentCycle.payCycle.as_view()),
+    re_path(r'^AiService/(?P<operation>.*)$', AiController.AiView.as_view()),
+    re_path(r'^app/setting/notification/(?P<operation>.*)$', EquipmentMessagePush.EquipmentMessagePushView.as_view()),
+    re_path(r'^v3/account/changePwd$', UserController.v3ChangePwdView.as_view()),
+    re_path(r'^v3/account/resetPwdByCode$', UserController.v3resetPwdByCodeView.as_view()),
+    re_path(r'^v3/account/register$', UserController.v3registerView.as_view()),
+    re_path(r'^v3/uiduser/add', UidUser.v3addInterface),
+    re_path(r'^v3/uiduser/query', UidUser.v3queryInterface),
+    re_path(r'^date/(?P<operation>.*)$', DateController.DateConView.as_view()),
+    re_path(r'^equipment/flow_test$', EquipmentManager.uid_status_test),
+    re_path(r'^account/appFrequency/(?P<operation>.*)$', UserController.UserAppFrequencyView.as_view()),
+    re_path(r'^v2/userbrand/(?P<operation>.*)$', UserBrandControllerV2.UserBrandV2.as_view()),
+    re_path(r'^statistcs/appFrequencyMonth$', StatisticsController.statistcsAppFrequency),
+    re_path(r'^statistcs/appFrequencyYear$', StatisticsController.statistcsAppFrequencyYear),
+    re_path(r'^statistcs/pushDay$', StatisticsController.statistcsPushDay),
+    re_path(r'^statistcs/pushMonth$', StatisticsController.statistcsPushMonth),
+    re_path(r'^alexa/(?P<operation>.*)$', Alexa.AlexaConnectNum.as_view()),
+    re_path(r'^faq/upload', FAQController.FAQUploadView.as_view()),
+    re_path(r'^faq/image/(?P<filePath>.*)$', FAQController.getFAQImage.as_view()),
+    re_path(r'^faq/(?P<operation>.*)$', FAQController.FAQView.as_view()),
+    re_path(r'^ios/authsign', UserController.AppleAuthLogin.as_view()),
+    re_path(r'^appLog/(?P<operation>.*)$', AppLogController.AppLogView.as_view()),
+    re_path(r'^deviceLog/(?P<operation>.*)$', DeviceLogController.DeviceLogView.as_view()),
+    re_path(r'^local/(?P<operation>.*)$', UserController.LocalUserView.as_view()),
+    re_path(r'^account/updateUserCountry', UserController.updateUserCountry),
+    re_path(r'^equipmentVersionLimit/(?P<operation>.*)$', EquipmentVersionLimit.EquipmentVersionLimitView.as_view()),
+    re_path(r'^account/subscribe$', UserController.SubscribeEmailView.as_view()),
+    re_path(r'^account/subscribe/download$', UserController.SubscribeEmailView.as_view()),
+    re_path(r'^voicePrompt/(?P<operation>.*)$', VoicePromptController.VoicePromptView.as_view()),
+    re_path(r'^deviceType/(?P<operation>.*)$', DeviceTypeController.DeviceTypeView.as_view()),
+    re_path(r'^cdk/(?P<operation>.*)$', CDKController.CDKView.as_view()),
+    re_path(r'^cloudTransfer/(?P<operation>.*)$', CloudTransfer.cloudTestView.as_view()),
+    re_path(r'^coupon/(?P<operation>.*)$', CouponController.CouponView.as_view()),
+    re_path(r'^Cloudsum/(?P<operation>.*)$', Cloudsum.Cloudsum.as_view()),
+    re_path(r'^device/StatisticsIpRegion$', DeviceConfirmRegion.StatisticsIpRegion.as_view()),
+    re_path('iot/(?P<operation>.*)', IotCoreController.IotCoreView.as_view()),
+    re_path(r's3_getsts/(?P<operation>.*)$', S3GetStsController.S3GetStsView.as_view()),
+    re_path('admin/', admin.site.urls),
     re_path('user/(?P<operation>.*)', UIDManageUserController.UserView.as_view()),
     re_path('uid/(?P<operation>.*)', UIDController.UIDView.as_view()),
     re_path('history/(?P<operation>.*)', HistoryUIDController.HistoryUIDView.as_view()),
     re_path('^log/(?P<operation>.*)', LogController.LogView.as_view()),
     re_path('orderTask/(?P<operation>.*)', OrderTaskController.OrderTaskView.as_view()),
-    path('upload', FileController.UploadUIDFileView.as_view()),
-    path('download', FileController.DownloadUIDFileView.as_view()),
-    path('sales', SalesController.SalesView.as_view()),
-    path('device/online', SalesController.DeviceOnlineView.as_view()),
+    re_path('^upload', FileController.UploadUIDFileView.as_view()),
+    re_path('^download', FileController.DownloadUIDFileView.as_view()),
+    re_path('sales', SalesController.SalesView.as_view()),
+    re_path('device/online', SalesController.DeviceOnlineView.as_view()),
     re_path('serialNumber/(?P<operation>.*)', SerialNumberController.SerialNumberView.as_view()),
-    path('deviceShadow/update', ShadowController.update_device_shadow),
+    re_path('deviceShadow/update', ShadowController.update_device_shadow),
     re_path('company/(?P<operation>.*)', CompanyController.CompanyView.as_view()),
     re_path('region/(?P<operation>.*)', RegionController.RegionView.as_view()),
     re_path('vpg/(?P<operation>.*)', VPGController.VPGView.as_view()),
-    path('vpgUid/uid', VPGController.do_upload_uid),
+    re_path('vpgUid/uid', VPGController.do_upload_uid),
     re_path('language/(?P<operation>.*)', LanguageController.LanguageView.as_view()),
-
     re_path('test/(?P<operation>.*)', TestController.TestView.as_view()),
-    # 日志管理系统
-    url(r'^OperatingLogs/(?P<operation>.*)$', OperatingLogs.OperatingLogsView.as_view()),
-    url(r'^ProcessInfo/(?P<operation>.*)$', ProcessInfo.ProcessInfoView.as_view()),
-    url(r'^Cloudsum/(?P<operation>.*)$', Cloudsum.Cloudsum.as_view()),
-
-    url(r'regionCountry/(?P<operation>.*$)', RegionCountryController.RegionCountryView.as_view()),
-
-    # 验证验证码
-    url(r'verifyCode/(?P<operation>.*$)', VerifyCodeController.VerifyCodeView.as_view()),
-
-    # 设备确定分配地区
-    url(r'^device/confirmRegion$', DeviceConfirmRegion.ConfirmRegion.as_view()),
-    url(r'^device/confirmRegionV2$', DeviceConfirmRegion.ConfirmRegionV2.as_view()),
-    url(r'^device/confirmCountry$', DeviceConfirmRegion.confirm_country_with_ip),
-
-    # pc端软件信息
-    url(r'^pcInfo/(?P<operation>.*)$', PcInfo.PcInfo.as_view()),
-
-    # pc端测试软件
-    url(r'^pcTest/(?P<operation>.*)$', PctestController.PcTest.as_view()),
-
-    # 设备debug
+    re_path(r'^OperatingLogs/(?P<operation>.*)$', OperatingLogs.OperatingLogsView.as_view()),
+    re_path(r'^ProcessInfo/(?P<operation>.*)$', ProcessInfo.ProcessInfoView.as_view()),
+    re_path(r'^Cloudsum/(?P<operation>.*)$', Cloudsum.Cloudsum.as_view()),
+    re_path(r'regionCountry/(?P<operation>.*$)', RegionCountryController.RegionCountryView.as_view()),
+    re_path(r'verifyCode/(?P<operation>.*$)', VerifyCodeController.VerifyCodeView.as_view()),
+    re_path(r'^device/confirmRegion$', DeviceConfirmRegion.ConfirmRegion.as_view()),
+    re_path(r'^device/confirmRegionV2$', DeviceConfirmRegion.ConfirmRegionV2.as_view()),
+    re_path(r'^device/confirmCountry$', DeviceConfirmRegion.confirm_country_with_ip),
+    re_path(r'^pcInfo/(?P<operation>.*)$', PcInfo.PcInfo.as_view()),
+    re_path(r'^pcTest/(?P<operation>.*)$', PctestController.PcTest.as_view()),
     re_path('deviceDebug/(?P<operation>.*)', DeviceDebug.DeviceDebug.as_view()),
-
-    # 问卷调查
-    url(r'^api/surveys/(?P<operation>.*)$', CloudStorageController.CloudStorageView.as_view()),
-    # 设备分享
-    url(r'^api/device/share/(?P<operation>.*)$', UserDeviceShareController.UserDeviceShareView.as_view()),
-
-    # 网关家庭模块
-    url(r'^app/sensor/gateway/(?P<operation>.*)$', EquipmentFamilyController.EquipmentFamilyView.as_view()),
-    url(r'^loocam/', include("Ansjer.server_urls.loocam_url")),
-    # 联通4G套餐模块
-    url(r'^unicom/', include("Ansjer.server_urls.unicom_url")),
-    # 算法小店
-    url(r'^algorithm-shop/', include("Ansjer.server_urls.algorithm_shop_url")),
-    # KVS模块
-    url(r'^kvs/', include("Ansjer.server_urls.kvs_url")),
-    # 超级密码模块
-    re_path('appAccout/(?P<operation>.*)', AppAccountManagement.AppAccoutView.as_view()),
-
-    # 传感器网关
+    re_path(r'^api/surveys/(?P<operation>.*)$', CloudStorageController.CloudStorageView.as_view()),
+    re_path(r'^api/device/share/(?P<operation>.*)$', UserDeviceShareController.UserDeviceShareView.as_view()),
+    re_path(r'^app/sensor/gateway/(?P<operation>.*)$', EquipmentFamilyController.EquipmentFamilyView.as_view()),
+    re_path(r'^loocam/', include("Ansjer.server_urls.loocam_url")),
+    re_path(r'^unicom/', include("Ansjer.server_urls.unicom_url")),
+    re_path(r'^algorithm-shop/', include("Ansjer.server_urls.algorithm_shop_url")),
+    re_path(r'^kvs/', include("Ansjer.server_urls.kvs_url")),
+    re_path('appAccout/(?P<operation>.*)', SuperPasswordTool.SuperPasswordView.as_view()),
     re_path('sensorGateway/(?P<operation>.*)', SensorGatewayController.SensorGateway.as_view()),
-
-    # 后台界面接口 -----------------------------------------------------
-    # 用户登录信息等
-    url(r'^login$', UserManageController.LoginView.as_view()),
-    url(r'^noPasslogin$', UserManageController.LoginView.as_view()),
-    url(r'^userInfo$', UserManageController.GetPermissions.as_view()),
-    url(r'^router/getList$', UserManageController.GetList.as_view()),
+    re_path(r'^api/surveys/(?P<operation>.*)$', CloudStorageController.CloudStorageView.as_view()),
+    re_path(r'^api/device/share/(?P<operation>.*)$', UserDeviceShareController.UserDeviceShareView.as_view()),
+
+    # 后台界面接口 -------------------------------------------------------------------------------------------------------
+    # 登录,用户信息,权限
+    re_path(r'^login$', UserManageController.LoginView.as_view()),
+    re_path(r'^noPasslogin$', UserManageController.LoginView.as_view()),
+    re_path(r'^userInfo$', UserManageController.GetPermissions.as_view()),
+    re_path(r'^router/getList$', UserManageController.GetList.as_view()),
     # 角色管理
     re_path('roleManagement/(?P<operation>.*)', RoleController.RoleView.as_view()),
     # 菜单管理
@@ -393,13 +286,11 @@ urlpatterns = [
     re_path(r'serial/(?P<operation>.*)', SerialManageController.SerialView.as_view()),
     # 数据系统模块
     re_path(r'^dataManagement/', include("Ansjer.server_urls.datasystem_url")),
-    # 后台界面接口 -----------------------------------------------------
+    # 后台界面接口 -------------------------------------------------------------------------------------------------------
 
-    # 定时删除任务接口
+    # 定时任务接口
     re_path(r'^cron/del/(?P<operation>.*)', CronTaskController.CronDelDataView.as_view()),
-    # 定时更新任务接口
     re_path(r'^cron/update/(?P<operation>.*)', CronTaskController.CronUpdateDataView.as_view()),
-    # 定时收集数据任务接口
     re_path(r'^cron/collect/(?P<operation>.*)', CronTaskController.CronCollectDataView.as_view()),
 
     re_path('(?P<path>.*)', LogManager.errorPath),

+ 0 - 232
Controller/AppAccountManagement.py

@@ -1,232 +0,0 @@
-# -*- encoding: utf-8 -*-
-"""
-@File    : UserDeviceShareController.py
-@Time    : 2023/2/3 13:25
-@Author  : guanhailong
-@Email   : guanhailong@asj6.wecom.work
-@Software: PyCharm
-"""
-import datetime
-import time
-
-from django.db import transaction
-
-from Controller.CheckUserData import RandomStr
-from Model.models import Device_User, Device_Info, DeviceSuperPassword, SysMsgModel
-from Object.RedisObject import RedisObject
-from Object.ResponseObject import ResponseObject
-from Object.TokenObject import TokenObject
-from django.views import View
-
-from Service.CommonService import CommonService
-
-
-class AppAccoutView(View):
-    def get(self, request, *args, **kwargs):
-        request.encoding = 'utf-8'
-        operation = kwargs.get('operation')
-        request_dict = request.GET
-        return self.validation(request_dict, request, operation)
-
-    def post(self, request, *args, **kwargs):
-        request.encoding = 'utf-8'
-        operation = kwargs.get('operation')
-        request_dict = request.GET
-        return self.validation(request_dict, request, operation)
-
-    def validation(self, request_dict, request, operation):
-        token = TokenObject(request.META.get('HTTP_AUTHORIZATION'))
-        lang = request_dict.get('lang', token.lang)
-        response = ResponseObject(lang)
-        userID = token.userID
-        if token.code != 0:
-            return response.json(token.code)
-        if operation == 'getAuthorizationCode':  # 获取用户请求/生成授权码
-            return self.getAuthorizationCode(request_dict, response, userID)
-        if operation == 'customerServiceManagement':  # 编辑超级密码请求表
-            return self.customerServiceManagement(request_dict, response)
-        if operation == 'getDeviceSuperPassword':  # 查询超级密码请求表
-            return self.getDeviceSuperPassword(request_dict, response)
-        if operation == 'verifyTheVerificationCode':  # 检验验证码
-            return self.verifyTheVerificationCode(request_dict, response, userID)
-        if operation == 'deleteInformation':  # 删除信息
-            return self.deleteInformation(request_dict, response)
-        else:
-            return response.json(404)
-
-    def getAuthorizationCode(self, request_dict, response, userID):
-        """
-        @param uid:设备id
-        @param request_dict:请求参数
-        @param response:响应对象
-        @param describe:需求描述
-        @param Purchase_channel:购买渠道描述
-        @param orderID:订单id
-        @param buyTime:购买时间
-        @return:
-        """
-        uid = request_dict.get('uid', None)
-        describe = request_dict.get('describe', None)
-        if not all([uid, describe]):
-            return response.json(444)
-        purchase_channel = request_dict.get('purchase_channel', None)
-        orderID = request_dict.get('orderID', None)
-        buyTime = request_dict.get('buyTime', None)
-        lang = request_dict.get('lang', 'en')
-        try:
-            now = int(time.time())
-            addTime = now
-            device_info_qs = Device_Info.objects.filter(UID=uid, userID_id=userID)
-            if not device_info_qs.exists():
-                return response.json(173)
-            if buyTime:
-                buyTime = datetime.datetime.strptime(buyTime, '%Y-%m-%d')
-                buyTime = CommonService.str_to_timestamp(str_time=str(buyTime))
-            DeviceSuperPassword.objects.create(uid=uid, orderID=orderID, describe=describe,
-                                               purchase_channel=purchase_channel, addTime=addTime, userID_id=userID,
-                                               buyTime=buyTime, status=0, lang=lang)
-            # 验证码生成
-            super_code = RandomStr(6, True)
-            super_password_id = "super_password_%s" % userID
-            redisObj = RedisObject()
-            redisObj.set_data(key=super_password_id, val=super_code, expire=86400)
-
-            return response.json(0)
-        except Exception as e:
-            print('生成验证码异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
-            return response.json(500, repr(e))
-
-    def customerServiceManagement(self, request_dict, response):
-        """
-        @param request_dict:请求参数
-        @param response:响应对象
-        @param hint:提示内容
-        @return:
-        """
-        userID = request_dict.get('userID', None)
-        uid = request_dict.get('uid', None)
-        status = request_dict.get('status', None)
-        hint = request_dict.get('hint', None)
-        lang = request_dict.get('lang', 'en')
-        if not all({uid, userID}):
-            return response.json(444)
-        now = int(time.time())
-        try:
-            with transaction.atomic():
-                device_super_password_qs = DeviceSuperPassword.objects.filter(uid=uid, userID=userID)
-                if not device_super_password_qs.exists():
-                    return response.json(173)
-                status = int(status)
-                authcode = ''
-                if status == 1:
-                    device_super_password_qs.update(status=status)
-                    super_password_id = 'super_password_' + userID
-                    redisObj = RedisObject()
-                    # redis里面的验证码
-                    redis_super_code = redisObj.get_data(key=super_password_id)
-                    # 验证用户输入的验证码和redis中的验证码
-                    if redis_super_code is False:
-                        return response.json(120)
-                    authcode = CommonService.encode_data(redis_super_code)
-                if status == 0 and len(hint) > 1:
-                    device_super_password_qs.update(status=status, hint=hint)
-                    msg = hint
-                    SysMsgModel.objects.create(userID_id=userID, msg=msg, addTime=now, updTime=now, uid=uid,
-                                               eventType=2)
-                    return response.json(0)
-                authcode = CommonService.decode_data(authcode)
-                if status == 1:
-                    if lang == 'en':
-                        msg = "Your authorization code is " + authcode + ",valid within 24 hours"
-                    else:
-                        msg = "您的授权代码:" + authcode + ",24小时内有效"
-                    SysMsgModel.objects.create(userID_id=userID, msg=msg, addTime=now, updTime=now, uid=uid,
-                                               eventType=2)
-                    return response.json(0)
-                return response.json(177)
-        except Exception as e:
-            print('修改状态异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
-            return response.json(500, repr(e))
-
-    def getDeviceSuperPassword(self, request_dict, response):
-        """
-        @param request_dict:请求参数
-        @param response:响应对象
-        @return:
-        """
-        pageNo = request_dict.get('pageNo', None)
-        pageSize = request_dict.get('pageSize', None)
-        status = request_dict.get('status', None)
-        userID = request_dict.get('userID', None)
-        uid = request_dict.get('uid', None)
-        if not all([pageNo, pageSize]):
-            return response.json(444)
-        page = int(pageNo)
-        line = int(pageSize)
-        try:
-            device_super_password_qs = DeviceSuperPassword.objects.all()
-            if status:
-                device_super_password_qs = device_super_password_qs.filter(status=status)
-            if userID:
-                device_super_password_qs = device_super_password_qs.filter(userID=userID)
-            if uid:
-                device_super_password_qs = device_super_password_qs.filter(uid=uid)
-            if not device_super_password_qs.exists():
-                return response.json(0, [])
-            count = device_super_password_qs.count()
-            device_super_password_qs = device_super_password_qs.values('id',
-                                                                       'uid',
-                                                                       'userID',
-                                                                       'orderID',
-                                                                       'describe',
-                                                                       'purchase_channel',
-                                                                       'addTime',
-                                                                       'status',
-                                                                       'buyTime',
-                                                                       'hint',
-                                                                       'lang')
-            device_super_password_qs = device_super_password_qs.order_by('-addTime')[
-                                       (page - 1) * line:page * line]
-            return response.json(0, {'list': list(device_super_password_qs), 'count': count})
-        except Exception as e:
-            print('查询异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
-            return response.json(500, repr(e))
-
-    def verifyTheVerificationCode(self, request_dict, response, userID):
-        """
-        @param request_dict:请求参数
-        @param response:响应对象
-        @param userID:用户ID
-        @param authcode:验证码
-        @return:
-        """
-        authcode = request_dict.get('authcode', None)
-        if authcode:
-            authcode = CommonService.decode_data(authcode)
-            super_password_id = 'super_password_' + userID
-            redisObj = RedisObject()
-            # redis里面的验证码
-            redis_image_code = redisObj.get_data(key=super_password_id)
-            # 验证用户输入的验证码和redis中的验证码
-            if redis_image_code is False or authcode.lower() != redis_image_code.lower():
-                return response.json(121)
-            else:
-                return response.json(0)
-        else:
-            return response.json(444)
-
-    def deleteInformation(self, request_dict, response):
-        """
-        @param request_dict:请求参数
-        @param response:响应对象
-        @param id:主键
-        """
-        id = request_dict.get('id', None)
-        if not id:
-            return response.json(444)
-        device_super_password_qs = DeviceSuperPassword.objects.filter(id=id)
-        if not device_super_password_qs.exists():
-            return response.json(173)
-        device_super_password_qs.delete()
-        return response.json(0)
-

+ 39 - 25
Controller/CloudStorage.py

@@ -27,7 +27,7 @@ from Controller.CloudPhoto.CloudServiceController import CloudServiceController
 from Controller.PaymentCycle import Paypal
 from Model.models import Device_Info, Order_Model, Store_Meal, VodHlsModel, UID_Bucket, StsCrdModel, \
     ExperienceContextModel, Pay_Type, CDKcontextModel, Device_User, SysMsgModel, Unused_Uid_Meal, PromotionRuleModel, \
-    VideoPlaybackTimeModel, CouponModel, VodBucketModel, VodHlsSummary
+    VideoPlaybackTimeModel, CouponModel, VodBucketModel, VodHlsSummary, VodHlsTag
 from Object.AWS.AmazonS3Util import AmazonS3Util
 from Object.AWS.S3Email import S3Email
 from Object.AliPayObject import AliPayObject
@@ -296,11 +296,12 @@ class CloudStorageView(View):
         now_time = int(time.time())
 
         split_vod_hls_obj = SplitVodHlsObject()
-        vod_hls_qs = split_vod_hls_obj.get_vod_hls_data(uid=uid, channel=channel, start_time=start_time,
-                                                        end_time__gte=now_time).values("sec", "fg", "bucket_id")
+        vod_hls_qs = split_vod_hls_obj.get_vod_hls_data(uid=uid, channel=channel, start_time__gte=start_time,
+                                                        end_time__gte=now_time).values("sec", "fg", "bucket_id",
+                                                                                       'start_time')[:10]
         if not vod_hls_qs.exists():
             return response.json(173)
-        fg = int(vod_hls_qs[0]['fg'])
+        vod_hls_qs = sorted(vod_hls_qs, key=lambda item: item['start_time'])[:10]
         bucket_id = vod_hls_qs[0]['bucket_id']
         vod_bucket_qs = VodBucketModel.objects.filter(id=bucket_id).values('bucket', 'region', 'mold')
         if not vod_bucket_qs.exists():
@@ -317,16 +318,20 @@ class CloudStorageView(View):
         playlist_entries = []
         # ts_count = fg & 0xf
         # fg 64位整型,低四位代表ts文件总数,然后进行位运算,一次移四位,每四位转为十进制即为当前ts文件的秒数
-        for i in range(15):
-            shift = (i + 1) * 4
-            duration = (fg >> shift) & 0xf
-            if duration > 0:
-                ts_file = '{uid}/vod{channel}/{time}/ts{i}.ts'.format(uid=uid, channel=channel, time=start_time, i=i)
-                response_url = s3_obj.generate_file_obj_url(bucket_name, ts_file)
-                playlist_entries.append({
-                    'name': response_url,
-                    'duration': duration,
-                })
+        for item in vod_hls_qs:
+            fg = int(item['fg'])
+            temp_time = item['start_time']
+            for i in range(15):
+                shift = (i + 1) * 4
+                duration = (fg >> shift) & 0xf
+                if duration > 0:
+                    ts_file = '{uid}/vod{channel}/{time}/ts{i}.ts'.format(uid=uid, channel=channel, time=temp_time,
+                                                                          i=i)
+                    response_url = s3_obj.generate_file_obj_url(bucket_name, ts_file)
+                    playlist_entries.append({
+                        'name': response_url,
+                        'duration': duration,
+                    })
 
         playlist = PlaylistGenerator(playlist_entries).generate()
         response = HttpResponse(playlist)
@@ -451,6 +456,7 @@ class CloudStorageView(View):
         end_time = request_dict.get('endTime', None)
         uid = request_dict.get('uid', None)
         channel = request_dict.get('channel', None)
+        event_types = request_dict.get('eventTypes', None)
 
         if not all([uid, channel, start_time, end_time]):
             return response.json(444)
@@ -472,8 +478,8 @@ class CloudStorageView(View):
                 "dvQsModelOverTime": device_info_qs_time_over,
             })
 
-        if device_info_qs[0]['vodPrimaryUserID'] != user_id:
-            return response.json(10034)
+        # if device_info_qs[0]['vodPrimaryUserID'] != user_id:
+        #     return response.json(10034)
         now_time = int(time.time())
         uid_bucket_qs = UID_Bucket.objects.filter(uid=uid, endTime__gte=now_time, channel=channel).values(
             'bucket_id').order_by('addTime')
@@ -486,13 +492,19 @@ class CloudStorageView(View):
             "dvQsModelOverTime": device_info_qs_time_over,
             "UidBucketModelOverTime": uid_bucket_qs_time_over,
         })
-
+        type_list = []
+        if event_types:
+            if ',' in event_types:
+                type_list = event_types.split(',')
+                type_list = [int(i.strip()) for i in type_list]
+            else:
+                type_list = [int(event_types)]
         split_vod_hls_obj = SplitVodHlsObject()
-        vod_hls_qs = split_vod_hls_obj.get_vod_hls_data(uid=uid, channel=channel, end_time__gte=now_time,
-                                                        start_time__range=(start_time, end_time)).values("id",
-                                                                                                         "start_time",
-                                                                                                         "sec", "fg",
-                                                                                                         "bucket_id")
+        vod_hls_qs = split_vod_hls_obj.get_vod_hls_data(uid=uid, channel=channel,
+                                                        end_time__gte=now_time,
+                                                        start_time__range=(start_time, end_time),
+                                                        type_list=type_list) \
+            .values("id", "start_time", "sec", "fg", "bucket_id")
 
         vod_play_list = []
         if not vod_hls_qs.exists():
@@ -541,7 +553,8 @@ class CloudStorageView(View):
                 'thumb': response_url,
                 'sec': vod['sec'],
                 'ts_num': ts_num,
-                'vod_id': vod['id']
+                'vod_id': vod['id'],
+                'types': split_vod_hls_obj.query_tag_type_list(vod['id'])
             })
         vod_play_list = sorted(vod_play_list, key=lambda item: -item['start_time'])
         generate_presigned_over_time = int(time.time())
@@ -618,9 +631,10 @@ class CloudStorageView(View):
             )
             # 创建分表数据
             split_vod_hls_obj = SplitVodHlsObject()
-            split_vod_hls_obj.creat_vod_hls_data(uid=uid, channel=channel, start_time=start_time, end_time=end_time,
-                                                 bucket_id=bucket_id, fg=fg, sec=sec)
+            vod_vo, week = split_vod_hls_obj.creat_vod_hls_data(uid=uid, channel=channel, start_time=start_time,
+                                                                end_time=end_time, bucket_id=bucket_id, fg=fg, sec=sec)
 
+            split_vod_hls_obj.cloud_vod_hls_tag(vod_vo.id, week, uid, start_time)
             end_time_stamp = datetime.datetime.fromtimestamp(int(start_time))
             end_time_str = datetime.datetime(end_time_stamp.year, end_time_stamp.month, 1)
             end_time_stamp = CommonService.str_to_timestamp(end_time_str.strftime('%Y-%m-%d %H:%M:%S'))

+ 38 - 21
Controller/Cron/CronTaskController.py

@@ -325,44 +325,57 @@ class CronUpdateDataView(View):
     @classmethod
     def reqUpdateSerialStatus(cls, response):
         redis_obj = RedisObject()
+        logger = logging.getLogger('info')
         # 更新已使用序列号其他服务器的状态
-        used_serial_redis_list_len = redis_obj.llen(USED_SERIAL_REDIS_LIST)
-        if used_serial_redis_list_len > 0:
-            used_serial_redis_list = []
-            for i in range(used_serial_redis_list_len):
-                used_serial_redis_list.append(redis_obj.lpop(USED_SERIAL_REDIS_LIST))
-            request_thread = threading.Thread(target=cls.do_request_thread, args=(str(used_serial_redis_list), 3))
-            request_thread.start()
+        used_serial_redis_list = redis_obj.lrange(USED_SERIAL_REDIS_LIST, 0, -1)  # 读取redis已使用序列号
+        logger.info('---请求更新序列号接口---used_serial_redis_list:{}---status:{}'.format(used_serial_redis_list, 3))
+        if used_serial_redis_list:
+            used_serial_redis_list = [str(i, 'utf-8') for i in used_serial_redis_list]
+            cls.do_request_function(used_serial_redis_list, 3)
         # 更新未使用序列号其他服务器的状态
-        unused_serial_redis_list_len = redis_obj.llen(UNUSED_SERIAL_REDIS_LIST)
-        if unused_serial_redis_list_len > 0:
-            unused_serial_redis_list = []
-            for i in range(unused_serial_redis_list_len):
-                unused_serial_redis_list.append(redis_obj.lpop(UNUSED_SERIAL_REDIS_LIST))
-            request_thread = threading.Thread(target=cls.do_request_thread, args=(str(unused_serial_redis_list), 1))
-            request_thread.start()
+        unused_serial_redis_list = redis_obj.lrange(UNUSED_SERIAL_REDIS_LIST, 0, -1)  # 读取redis未使用序列号
+        logger.info('---请求更新序列号接口---unused_serial_redis_list:{}---status:{}'.format(unused_serial_redis_list, 1))
+        if unused_serial_redis_list:
+            unused_serial_redis_list = [str(i, 'utf-8') for i in unused_serial_redis_list]
+            cls.do_request_function(unused_serial_redis_list, 1)
         return response.json(0)
 
     @staticmethod
-    def do_request_thread(serial_redis_list, status):
+    def do_request_function(serial_redis_list, status):
         """
         请求更新序列号线程
         @param serial_redis_list: 序列号redis列表
         @param status: 状态, 1: 未使用, 3: 已占用
         """
         data = {
-            'serial_redis_list': serial_redis_list,
+            'serial_redis_list': str(serial_redis_list),
             'status': status
         }
         # 确认域名列表
         orders_domain_name_list = CommonService.get_orders_domain_name_list()
-
+        redis_obj = RedisObject()
         logger = logging.getLogger('info')
         logger.info('---请求更新序列号线程---data:{},orders_domain_name_list:{}'.format(data, orders_domain_name_list))
+        try:
+            flag = 0  # 请求标志位
+            for domain_name in orders_domain_name_list:
+                url = '{}cron/update/updateSerialStatus'.format(domain_name)
+                response = requests.post(url=url, data=data, timeout=5)
+                logger.info('---请求更新序列号响应时间---time:{}'.format(response.elapsed.total_seconds()))
+                result = response.json()
+                if result['result_code'] != 0:  # 请求失败修改标志位
+                    flag = 1
+                    break
+            if flag == 0:  # 请求成功删除redis序列号
+                if status == 1:
+                    for i in serial_redis_list:
+                        redis_obj.lrem(UNUSED_SERIAL_REDIS_LIST, 0, i)
+                elif status == 3:
+                    for i in serial_redis_list:
+                        redis_obj.lrem(USED_SERIAL_REDIS_LIST, 0, i)
+        except Exception as e:
+            logger.info('---更新序列号状态异常---:{}'.format(repr(e)))
 
-        for domain_name in orders_domain_name_list:
-            url = '{}cron/update/updateSerialStatus'.format(domain_name)
-            requests.post(url=url, data=data, timeout=2)
 
     @staticmethod
     def updateSerialStatus(request_dict, response):
@@ -379,11 +392,15 @@ class CronUpdateDataView(View):
         logger.info('---更新序列号状态参数---serial_redis_list:{},status:{}'.format(serial_redis_list, status))
         if not all([serial_redis_list, status]):
             return response.json(444)
+        now_time = int(time.time())
         try:
             serial_redis_list = eval(serial_redis_list)
-            CompanySerialModel.objects.filter(serial_number__in=serial_redis_list).update(status=int(status))
+            CompanySerialModel.objects.filter(serial_number__in=serial_redis_list).update(status=int(status),
+                                                                                          update_time=now_time)
+            return response.json(0)
         except Exception as e:
             logger.info('---更新序列号状态异常---:{}'.format(repr(e)))
+            return response.json(500)
 
 
 class CronCollectDataView(View):

+ 27 - 2
Controller/DetectControllerV2.py

@@ -11,12 +11,13 @@ from django.views.generic.base import View
 from Ansjer.config import DETECT_PUSH_DOMAIN, DETECT_PUSH_DOMAINS, DETECT_PUSH_DOMAIN_JIUAN, DETECT_PUSH_DOMAINS_JIUAN, \
     OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY
 from Ansjer.config import PUSH_REDIS_ADDRESS
-from Model.models import Device_Info, VodHlsModel, Equipment_Info, UidSetModel, UidPushModel, CompanyModel, SysMsgModel, \
+from Model.models import Device_Info, Equipment_Info, UidSetModel, UidPushModel, CompanyModel, SysMsgModel, \
     AiService, VodBucketModel
 from Object.ETkObject import ETkObject
 from Object.RedisObject import RedisObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
+from Object.utils import LocalDateTimeUtil
 from Service.CommonService import CommonService
 from Service.EquipmentInfoService import EquipmentInfoService
 from Service.VodHlsService import SplitVodHlsObject
@@ -57,6 +58,9 @@ class DetectControllerViewV2(View):
             # 更新推送延迟
             elif operation == 'updateInterval':
                 return self.do_update_interval(userID, request_dict, response)
+            # 修改推送报警开关、手动报警开关
+            elif operation == 'updateAlarmpushOrManualalarm':
+                return self.do_update_alarmpush_or_manualalarm(userID, request_dict, response)
             else:
                 return response.json(414)
         else:
@@ -269,7 +273,8 @@ class DetectControllerViewV2(View):
 
             else:
                 # 默认查询近七天消息推送
-                qs, count = EquipmentInfoService.get_equipment_info_week_all(page, line, userID, startTime, endTime,
+                def_time = LocalDateTimeUtil.get_before_days_timestamp(int(time.time()), 8)
+                qs, count = EquipmentInfoService.get_equipment_info_week_all(page, line, userID, def_time, endTime,
                                                                              eventType,
                                                                              request_dict.get('uids', None))
             uids = request_dict.get('uids', None)
@@ -422,6 +427,26 @@ class DetectControllerViewV2(View):
         else:
             return response.json(0)
 
+    def do_update_alarmpush_or_manualalarm(self, user_id, request_dict, response):
+        uid = request_dict.get('uid', None)
+        status = request_dict.get('status', None)
+        alarm_type = request_dict.get('alarm_type', None)
+        if not all([uid, status, alarm_type]):
+            return response.json(444, 'uid or status or alarm_type')
+        # 查询设备是否属于该用户
+        device_info_qs = Device_Info.objects.filter(userID_id=user_id, UID=uid)
+        if not device_info_qs.exists():
+            return response.json(14)
+        thing_name = CommonService.query_serial_with_uid(uid)  # 存在序列号则为使用序列号作为物品名
+        topic_name = 'ansjer/generic/{}'.format(thing_name)
+        msg = {
+            'commandType': alarm_type,
+            'enable': status
+        }
+        req_success = CommonService.req_publish_mqtt_msg(thing_name, topic_name, msg)
+        if not req_success:
+            return response.json(10044)
+        return response.json(0)
 
 # 这个接口没有调用过,不敢动
 # http://test.dvema.com/detect/add?uidToken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiJQMldOR0pSRDJFSEE1RVU5MTExQSJ9.xOCI5lerk8JOs5OcAzunrKCfCrtuPIZ3AnkMmnd-bPY&n_time=1526845794&channel=1&event_type=51&is_st=0

+ 17 - 11
Controller/EquipmentManagerV3.py

@@ -15,6 +15,7 @@ from Ansjer.config import OSS_STS_ACCESS_SECRET, OSS_STS_ACCESS_KEY
 from Controller.CheckUserData import RandomStr
 from Controller.DeviceConfirmRegion import Device_Region
 from Controller.SensorGateway.EquipmentFamilyController import EquipmentFamilyView
+from Controller.UnicomCombo.UnicomComboController import UnicomComboView
 from Model.models import Device_Info, UID_Bucket, UID_Preview, UidSetModel, UidChannelSetModel, \
     Device_User, iotdeviceInfoModel, UIDCompanySerialModel, UnicomDeviceInfo, CountryModel, \
     DeviceCloudPhotoInfo
@@ -297,12 +298,20 @@ class EquipmentManagerV3(View):
         @param serial_number: 序列号
         @return: True | False
         """
-        unicom_device_info_qs = UnicomDeviceInfo.objects.filter(serial_no=serial_number)
-        if not unicom_device_info_qs.exists():
+        try:
+            unicom_device_info_qs = UnicomDeviceInfo.objects.filter(serial_no=serial_number)
+            if not unicom_device_info_qs.exists():
+                return False
+            if not unicom_device_info_qs[0].user_id:
+                n_time = int(time.time())
+                # 生成4G免费订单
+                UnicomComboView.experience_order_4G(unicom_device_info_qs[0].iccid,
+                                                    serial_number, user_id, False)
+                unicom_device_info_qs.update(user_id=user_id, updated_time=n_time)
+            return True
+        except Exception as e:
+            logging.info('创建体验4G订单异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
             return False
-        if not unicom_device_info_qs[0].user_id:
-            unicom_device_info_qs.update(user_id=user_id)
-        return True
 
     def do_batch_add(self, userID, request_dict, response, request):
         # 批量添加设备
@@ -956,19 +965,17 @@ class EquipmentManagerV3(View):
         """
         测试工具删除设备
         @param request_dict: 请求数据
-        @request_dict user_id: 用户id
         @request_dict uid: uid
         @request_dict time_stamp: 时间戳
         @request_dict time_stamp_token: 时间戳token
         @param response: 响应
         @return: response
         """
-        user_id = request_dict.get('user_id')
         uid = request_dict.get('uid')
         time_stamp = request_dict.get('time_stamp', None)
         time_stamp_token = request_dict.get('time_stamp_token', None)
 
-        if not all([user_id, uid, time_stamp, time_stamp_token]):
+        if not all([uid, time_stamp, time_stamp_token]):
             return response.json(444)
 
         try:
@@ -977,11 +984,10 @@ class EquipmentManagerV3(View):
                 return response.json(13)
 
             with transaction.atomic():
-                Device_Info.objects.filter(userID_id=user_id, UID=uid).delete()
+                Device_Info.objects.filter(UID=uid).delete()
                 # 删除推送消息
                 for val in range(1, 8):
-                    EquipmentInfoService.get_equipment_info_model('', val). \
-                        filter(device_user_id=user_id, device_uid=uid).delete()
+                    EquipmentInfoService.get_equipment_info_model('', val).filter(device_uid=uid).delete()
             return response.json(0)
         except Exception as e:
             return response.json(500, repr(e))

+ 2 - 1
Controller/FeedBack.py

@@ -361,7 +361,8 @@ class FeedBackView(View):
                                                                                    channel=channel,
                                                                                    event_time=event_time,
                                                                                    index=index)
-                    s3.copy_obj(PUSH_BUCKET, PUSH_INACCURATE_BUCKET, file_path)
+                    if s3.get_object(PUSH_BUCKET, file_path):
+                        s3.copy_obj(PUSH_BUCKET, PUSH_INACCURATE_BUCKET, file_path)
             PushInaccurateFeedback.objects.create(equipment_info_id=equipment_info_id, user_id=user_id,
                                                   event_type=event_type, uid=uid, channel=channel,
                                                   add_time=now_time, tag=tag, is_st=is_st, event_time=event_time)

+ 72 - 4
Controller/SerialNumberController.py

@@ -1,5 +1,6 @@
 import json
 import logging
+import threading
 import time
 
 import requests
@@ -12,6 +13,7 @@ from Model.models import SerialNumberModel, CompanySerialModel, UIDCompanySerial
     iotdeviceInfoModel, LogModel, UidSetModel, UID_Bucket, \
     Unused_Uid_Meal, Order_Model, StsCrdModel, VodHlsModel, ExperienceContextModel, UidUserModel, ExperienceAiModel, \
     AiService, DeviceDomainRegionModel, RegionModel
+from Object.AWS.S3Email import S3Email
 from Object.RedisObject import RedisObject
 from Object.TokenObject import TokenObject
 from Object.uidManageResponseObject import uidManageResponseObject
@@ -169,6 +171,7 @@ class SerialNumberView(View):
                                                              add_time=now_time, update_time=now_time)
 
                         company_serial.status = 2
+                        company_serial.update_time = now_time
                         company_serial.save()
 
                         dev = Device_Info.objects.filter(UID=uid.uid)
@@ -201,9 +204,13 @@ class SerialNumberView(View):
                             'operation': '序列号{}绑定uid: {}'.format(serial, uid.uid),
                         }
                         LogModel.objects.create(**log)
-                        if CONFIG_INFO != CONFIG_TEST:  # 不为测试服,则序列号写入redis列表
-                            redisObj.rpush(USED_SERIAL_REDIS_LIST, serial)
                         redisObj.del_data(key=key)
+
+                        # 处理序列号状态和计算剩余uid数量线程
+                        thread = threading.Thread(target=self.rpush_serial_and_count_uid, args=(serial, p2p_type,
+                                                                                                redisObj))
+                        thread.start()
+
                         return response.json(0, res)
                     return response.json(5)
             elif company_serial.status == 2:  # 返回uid
@@ -224,13 +231,73 @@ class SerialNumberView(View):
                     'initStringApp': uid['uid__init_string_app'],
                 }
                 return response.json(0, res)
-            elif company_serial.status == 3:
+            elif company_serial.status == 3:    # 已占用
+                self.log_and_send_email(request, serial, now_time)
                 return response.json(10042)
         except Exception as e:
             djangoLogger = logging.getLogger('django')
             djangoLogger.exception(repr(e))
             return response.json(176, str(e))
 
+    @staticmethod
+    def rpush_serial_and_count_uid(serial, p2p_type, redis_obj):
+        """
+        处理序列号状态和计算剩余uid数量线程
+        @param serial: 序列号
+        @param p2p_type: p2p类型
+        @param redis_obj: redis对象
+        @return:
+        """
+        # 测试服不处理
+        if CONFIG_INFO != CONFIG_TEST:
+            redis_obj.rpush(USED_SERIAL_REDIS_LIST, serial)
+
+            vpg_id = 1
+            if CONFIG_INFO == 'us':
+                vpg_id = 3
+            elif CONFIG_INFO == 'eur':
+                vpg_id = 4
+            p2p_type = int(p2p_type)
+
+            # 剩余uid数量少于2000邮件提醒
+            unused_uid_count = UIDModel.objects.filter(vpg_id=vpg_id, p2p_type=p2p_type, status=0).count()
+            warning_count = 2000
+            if unused_uid_count < warning_count:
+                platform = '尚云' if p2p_type == 1 else 'tutk'
+                email_content = '{}服{]的uid数量少于{}个,请及时处理'.format(CONFIG_INFO, platform, warning_count)
+                S3Email().faEmail(email_content, 'servers@ansjer.com')
+
+    @staticmethod
+    def log_and_send_email(request, serial, now_time):
+        """
+        记录占用操作日志及发送邮件通知
+        @param request:
+        @param serial:
+        @param now_time:
+        @return:
+        """
+        if CONFIG_INFO == CONFIG_US:
+            # 不为国内ip记录日志
+            ip = CommonService.get_ip_address(request)
+            ip_info = CommonService.getIpIpInfo(ip, 'CN')
+            country_code = ip_info['country_code']
+            if country_code != 'CN':
+                operation = '序列号占用:{}'.format(serial)
+                log_qs = LogModel.objects.filter(operation=operation)
+                if not log_qs.exists():
+                    log = {
+                        'ip': ip,
+                        'user_id': 1,
+                        'status': 200,
+                        'time': now_time,
+                        'operation': operation,
+                        'url': 'serialNumber/attachUID',
+                    }
+                    LogModel.objects.create(**log)
+                    # 邮件通知
+                    email_content = '国外服发现序列号占用操作: {]'.format(serial)
+                    S3Email().faEmail(email_content, 'servers@ansjer.com')
+
     def do_get_uid(self, request_dict, response):
         serial_number = request_dict.get('serial_number', None)
         token = request_dict.get('token', None)
@@ -290,7 +357,8 @@ class SerialNumberView(View):
         try:
             with transaction.atomic():
                 uid = uid_serial.uid.uid
-                company_serial_qs.update(status=1)  # 更新序列号状态
+                # 更新序列号状态
+                company_serial_qs.update(status=1, update_time=now_time)
                 # 删除设备相关数据,参考后台的设备重置删除的数据
                 Device_Info.objects.filter(UID=uid).delete()
                 UidSetModel.objects.filter(uid=uid).delete()

+ 111 - 0
Controller/SuperPasswordTool.py

@@ -0,0 +1,111 @@
+# -*- encoding: utf-8 -*-
+"""
+@File    : UserDeviceShareController.py
+@Time    : 2023/2/3 13:25
+@Author  : guanhailong
+@Email   : guanhailong@asj6.wecom.work
+@Software: PyCharm
+"""
+import datetime
+import time
+import logging
+
+from Model.models import Device_User, DeviceSuperPassword
+from Object.RedisObject import RedisObject
+from Object.ResponseObject import ResponseObject
+from Object.TokenObject import TokenObject
+from django.views import View
+
+from Service.CommonService import CommonService
+
+
+class SuperPasswordView(View):
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        request_dict = request.GET
+        return self.validation(request_dict, request, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        request_dict = request.POST
+        return self.validation(request_dict, request, operation)
+
+    def validation(self, request_dict, request, operation):
+        tko = TokenObject(
+            request.META.get('HTTP_AUTHORIZATION'))
+        lang = request_dict.get('lang', tko.lang)
+        logger = logging.getLogger('info')
+        logger.info("传参语言{}".format(lang))
+        response = ResponseObject(lang)
+        if tko.code != 0:
+            return response.json(tko.code)
+        userID = tko.userID
+        if operation == 'getAuthorizationCode':  # 用户提交请求
+            return self.getAuthorizationCode(request_dict, response, userID)
+        if operation == 'verifyTheVerificationCode':  # 检验验证码
+            return self.verifyTheVerificationCode(request_dict, response, userID)
+        else:
+            return response.json(404)
+
+    @staticmethod
+    def getAuthorizationCode(request_dict, response, userID):
+        """
+        用户提交请求
+        @param request_dict:请求参数
+        @param response:响应对象
+        @param userID:用户ID
+        @return:
+        """
+        uid = request_dict.get('uid', None)
+        describe = request_dict.get('describe', None)
+        if not all([uid, describe]):
+            return response.json(444)
+        purchase_channel = request_dict.get('purchase_channel', None)
+        orderID = request_dict.get('orderID', None)
+        buyTime = request_dict.get('buyTime', None)
+        lang = request_dict.get('lang', 'en')
+        try:
+            now = int(time.time())
+            addTime = now
+            device_user_qs = Device_User.objects.filter(userID=userID)
+            if not device_user_qs.exists():
+                return response.json(173)
+            if buyTime:
+                buyTime = datetime.datetime.strptime(buyTime, '%Y-%m-%d')
+                buyTime = CommonService.str_to_timestamp(str_time=str(buyTime))
+            DeviceSuperPassword.objects.create(uid=uid, orderID=orderID, describe=describe,
+                                               purchase_channel=purchase_channel, addTime=addTime, userID_id=userID,
+                                               buyTime=buyTime, status=0, lang=lang)
+
+            return response.json(0)
+        except Exception as e:
+            print('生成验证码异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            return response.json(500, repr(e))
+
+    @staticmethod
+    def verifyTheVerificationCode(request_dict, response, userID):
+        """
+        检验验证码
+        @param request_dict:请求参数
+        @param response:响应对象
+        @param userID:用户ID
+        @return:
+        """
+        authcode = request_dict.get('authcode', None)
+        if authcode:
+            authcode = CommonService.decode_data(authcode)
+            if not len(authcode) == 6:
+                return response.json(121)
+            super_password_id = 'super_password_' + userID
+            redisObj = RedisObject()
+            # redis里面的验证码
+            redis_image_code = redisObj.get_data(key=super_password_id)
+            # 验证用户输入的验证码和redis中的验证码
+            if redis_image_code is False or authcode.lower() != redis_image_code.lower():
+                return response.json(121)
+            else:
+                return response.json(0)
+        else:
+            return response.json(444)

+ 30 - 3
Controller/TestApi.py

@@ -17,6 +17,7 @@ import traceback
 import botocore
 import cv2
 from botocore import client
+from django.db import transaction
 
 from Controller.DeviceConfirmRegion import Device_Region
 from Object.AWS.AmazonS3Util import AmazonS3Util
@@ -35,15 +36,15 @@ from boto3.session import Session
 import oss2
 import paypalrestsdk
 import logging
-from aliyunsdkcore import client
 from django.http import JsonResponse, HttpResponse
 from django.utils.decorators import method_decorator
 from django.views.decorators.csrf import csrf_exempt
 from django.views.generic.base import View
 from django.contrib.auth.hashers import make_password  # 对密码加密模块
-from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, OSS_ROLE_ARN, AWS_ACCESS_KEY_ID, \
+from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, AWS_ACCESS_KEY_ID, \
     AWS_SECRET_ACCESS_KEY, SERVER_TYPE, AWS_SES_ACCESS_REGION
-from Model.models import Order_Model, Store_Meal, OssCrdModel, StsCrdModel, DeviceLogModel, VodBucketModel
+from Model.models import Order_Model, Store_Meal, DeviceLogModel, VodBucketModel, \
+    TestSerialRepetition
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Service.CommonService import CommonService
@@ -156,9 +157,35 @@ class testView(View):
             return self.play_m3u8(request_dict, response)
         elif operation == 'generate_video':
             return self.generate_video(request_dict, response)
+        elif operation == 'serial-repetition':  # 用与测试序列号重复接口
+            response = ResponseObject('cn')
+            return self.serial_repetition_test(request_dict, response)
         else:
             return 123
 
+    @classmethod
+    def serial_repetition_test(cls, request_dict, response):
+        try:
+            serial_no = request_dict.get('serialNo', None)
+            if not serial_no:
+                return response.json(444)
+            with transaction.atomic():
+                first_serial = serial_no[:6]
+                first_serial_qs = TestSerialRepetition.objects.filter(serial_number__icontains=first_serial)
+                if first_serial_qs.exists():
+                    return response.json(174)
+                serial_qs = TestSerialRepetition.objects.filter(serial_number=serial_no)
+                if not serial_qs.exists():
+                    n_time = int(time.time())
+                    params = {'serial_number': serial_no, 'created_time': n_time}
+                    TestSerialRepetition.objects.create(**params)
+                    return response.json(0)
+                else:
+                    return response.json(174)
+        except Exception as e:
+            logging.info('异常错误,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            return response.json(178, e)
+
     @classmethod
     def generate_video(cls, request_dict, response):
         # 设计抽取图片规则通过消息随机还是时间随机,调试copy S3对象查询是否携带失效时间

+ 51 - 15
Controller/UnicomCombo/UnicomComboController.py

@@ -19,7 +19,8 @@ from django.http import HttpResponse, JsonResponse
 from django.views.generic.base import View
 
 from Model.models import UnicomDeviceInfo, UnicomCombo, Pay_Type, Order_Model, Store_Meal, AiStoreMeal, \
-    UnicomComboOrderInfo, UnicomComboExperienceHistory, UnicomDeviceStatusChangePush, SysMsgModel, UnicomFlowPush
+    UnicomComboOrderInfo, UnicomComboExperienceHistory, UnicomDeviceStatusChangePush, SysMsgModel, UnicomFlowPush, \
+    LogModel
 from Object.RedisObject import RedisObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
@@ -58,9 +59,9 @@ class UnicomComboView(View):
         elif operation == 'device-status-change':  # SIM卡修改状态,异步通知接口
             return self.device_status_change_push(request_dict, request)
         elif operation == 'device-bind':  # 服务器保存设备的ICCID
-            return self.device_add(request_dict, response)
-        elif operation == 'device-status':  # PC调用解绑SIM卡用户,清除套餐数据
-            return self.update_device_status(request_dict, response)
+            return self.iccid_bind_serial_no(request, request_dict, response)
+        elif operation == 'device-status':  # PC调用解绑SIM卡用户,清除流量套餐数据
+            return self.update_device_status(request, request_dict, response)
         elif operation == 'update-card':  # 更新SIM类型
             return self.update_device_card_type(request_dict, response)
         elif operation == 'xxx-sign':  # 获取签名用于测试
@@ -245,7 +246,7 @@ class UnicomComboView(View):
                 expire_qs.update(sort=100)
 
     @classmethod
-    def update_device_status(cls, request_dict, response):
+    def update_device_status(cls, request, request_dict, response):
         """
         重置SIM卡绑定状态修改为测试完成,以及重置流量,删除订单信息、删除系统消息
         """
@@ -287,10 +288,12 @@ class UnicomComboView(View):
                     combo_experience_history_qs = UnicomComboExperienceHistory.objects.filter(iccid=iccid)
                     if combo_experience_history_qs.exists():
                         combo_experience_history_qs.delete()
-                    # 删除4G套餐订单
-                    Order_Model.objects.filter(orderID__in=order_list).delete()
                     redis.set_data(key, iccid, 60 * 30)  # 缓存当前SIM卡,记录为半个小时内无法赠送免费流量套餐。
                     UnicomObjeect().change_device_to_activate(iccid)
+                    logger.info('4GResetFlow相关订单号:{}'.format(order_list))
+                    describe = '重置4G流量序列号{},iccid:{}'.format(serial_no, iccid)
+                    ip = CommonService.get_ip_address(request)
+                    cls.create_operation_log('unicom/api/device-status', ip, request_dict, describe)
                 return response.json(0)
         except Exception as e:
             print(e.args)
@@ -355,12 +358,9 @@ class UnicomComboView(View):
         return response.json(0, dict(unicom_device_info_qs.first()))
 
     @classmethod
-    def device_add(cls, request_dict, response):
+    def iccid_bind_serial_no(cls, request, request_dict, response):
         """
-        设备绑定iccid
-        @param request_dict:
-        @param response:
-        @return:
+        iccid绑定设备序列号
         """
         iccid = request_dict.get('iccid', None)
         serial_no = request_dict.get('serialNo', None)
@@ -380,8 +380,9 @@ class UnicomComboView(View):
             logger.info('--->参数验证通过,sign验证通过')
             redis = RedisObject()
             with transaction.atomic():
-                # 待完善代码 根据uid与用户id验证系统设备
-                unicom_device_qs = UnicomDeviceInfo.objects.filter(serial_no=serial_no)
+                ip = CommonService.get_ip_address(request)
+                # 待完善代码 根据uid与用户id验证系统设备mdcmd
+                unicom_device_qs = UnicomDeviceInfo.objects.filter(iccid=iccid)
                 if unicom_device_qs.exists():
                     if unicom_device_qs.first().status == 1:
                         key = 'ASJ:UNICOM:RESET:{}'.format(serial_no)
@@ -390,7 +391,12 @@ class UnicomComboView(View):
                             logger.info('--->三十分后再次访问接口生效赠送流量套餐')
                             return response.json(0, 'Thirty minutes later to visit again take effect')
                         cls.user_activate_flow(iccid)
-                    unicom_device_qs.update(main_card=sim, updated_time=n_time)
+                    if unicom_device_qs.first().serial_no != serial_no:
+                        unicom_device_qs.update(main_card=sim, updated_time=n_time, serial_no=serial_no)
+                        cls.create_operation_log('unicom/api/device-bind',
+                                                 ip, request_dict, '4G序列号{}新绑定{}'.format(serial_no, iccid))
+                    elif unicom_device_qs.first().main_card != sim:
+                        unicom_device_qs.update(main_card=sim, updated_time=n_time)
                     return response.json(0)
                 if sim == 0:
                     return response.json(0, '外置卡不保存相关信息{}'.format(serial_no))
@@ -411,6 +417,8 @@ class UnicomComboView(View):
                             return response.json(173)
                         unicom_obj.change_device_to_activate(iccid)
                         UnicomDeviceInfo.objects.create(**params)
+                        cls.create_operation_log('unicom/api/device-bind',
+                                                 ip, request_dict, '4G序列号{}绑定{}'.format(serial_no, iccid))
                     return response.json(0)
                 else:
                     logger.info('--->设备请求绑定{}验证失败'.format(iccid))
@@ -914,3 +922,31 @@ class UnicomComboView(View):
                 continue
             cls.experience_order_4G(item['iccid'], u_device_qs[0]['serial_no'], u_device_qs[0]['user_id'], False)
         return response.json(0)
+
+    @classmethod
+    def create_operation_log(cls, url, ip, request_dict, describe):
+        """
+        创建操作日志
+        @param url: 请求路径
+        @param describe: 描述
+        @param ip: 当前IP
+        @param request_dict: 请求参数
+        @return: True | False
+        """
+        try:
+            # 记录操作日志
+            content = json.loads(json.dumps(request_dict))
+            log = {
+                'ip': ip,
+                'user_id': 1,
+                'status': 200,
+                'time': int(time.time()),
+                'content': json.dumps(content),
+                'url': url,
+                'operation': describe,
+            }
+            LogModel.objects.create(**log)
+            return True
+        except Exception as e:
+            print('日志异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            return False

+ 8 - 4
Controller/UserController.py

@@ -876,7 +876,7 @@ class v2authCodeView(TemplateView):
         )
         if send_res is not True:
             return response.json(44)
-        if reds.set_data(key=email + '_identifyingCode', val=identifyingCode, expire=300) is not True:
+        if reds.set_data(key=email + '_identifyingCode', val=identifyingCode, expire=600) is not True:
             return response.json(10, 'error')
         return response.json(0)
 
@@ -2143,10 +2143,11 @@ class v3LoginView(TemplateView):
         if all([app_bundle_id, app_type, push_type, token_val, m_code, tz]):
             gateway_push_qs = GatewayPush.objects.filter(user_id=userID, m_code=m_code)
             if gateway_push_qs.exists():
-                gateway_push_qs.update(token_val=token_val, logout=False)
+                gateway_push_qs.update(token_val=token_val, push_type=push_type, logout=False)
             else:
                 GatewayPush.objects.create(user_id=userID, app_bundle_id=app_bundle_id, app_type=app_type,
                                            push_type=push_type, token_val=token_val, m_code=m_code, lang=lang, tz=tz)
+            UidPushModel.objects.filter(userID=userID, m_code=m_code).update(token_val=token_val, push_type=push_type)
 
         now_time = datetime.datetime.utcnow().replace(tzinfo=utc).astimezone(utc)
         region_country = users['region_country']
@@ -2367,6 +2368,9 @@ class InitInfoView(View):
                         'userID_id': userID,
                         'region': lang
                     }
+                    device_user = Device_User.objects.filter(userID=userID)
+                    if not device_user.exists():
+                        return response.json(173)
                     user_ex = UserExModel.objects.create(**create_dict)
 
                 country_ip_qs = CountryIPModel.objects.filter(user_ex_id=user_ex.id)
@@ -2399,7 +2403,7 @@ class InitInfoView(View):
             gateway_push_qs = GatewayPush.objects.filter(user_id=user_id, m_code=m_code)
             if gateway_push_qs.exists():
                 if gateway_push_qs.first().token_val != token_val:
-                    gateway_push_qs.update(token_val=token_val, logout=False)
+                    gateway_push_qs.update(token_val=token_val, push_type=push_type, logout=False)
             else:
                 GatewayPush.objects.create(user_id=user_id, app_bundle_id=app_bundle_id, app_type=app_type,
                                            push_type=push_type, token_val=token_val, m_code=m_code, lang=lang, tz=tz)
@@ -3412,7 +3416,7 @@ class generatePictureCodeView(TemplateView):
             redisObj.set_data(key=image_code_id, val=valid_code_str, expire=120)
             image_code_val = redisObj.get_data(key=image_code_id)
             print("________获取验证码的值" + image_code_val)
-            return HttpResponse(data)
+            return HttpResponse(data, 'image/png')
 
 
 class Image_Code_RegisterView(TemplateView):

+ 41 - 3
Model/models.py

@@ -1377,7 +1377,7 @@ class UidPushModel(models.Model):
     uid_set = models.ForeignKey(UidSetModel, to_field='id', on_delete=models.CASCADE)
     appBundleId = models.CharField(blank=True, max_length=32, verbose_name=u'appID')
     app_type = models.IntegerField(default=0, verbose_name=u'app类型 1:ios,2:安卓')
-    push_type = models.IntegerField(default=0, verbose_name=u'推送类型')  # 0,apns 1,安卓gcm 2,极光
+    push_type = models.IntegerField(default=0, verbose_name=u'推送类型')  # 0: apns, 1: 安卓gcm, 2: 极光, 3:华为, 4:小米, 5:vivo, 6:oppo, 7:魅族
     token_val = models.CharField(default='', max_length=500, verbose_name=u'设备验证令牌')
     m_code = models.CharField(default='', max_length=64, verbose_name='手机唯一标识')
     addTime = models.IntegerField(verbose_name='添加时间', default=0)
@@ -1397,7 +1397,7 @@ class GatewayPush(models.Model):
     user_id = models.CharField(default='', max_length=32, db_index=True, verbose_name=u'用户id')
     app_bundle_id = models.CharField(default='', max_length=32, verbose_name=u'app包id')
     app_type = models.IntegerField(default=0, verbose_name=u'app类型')  # 1: ios, 2: 安卓
-    push_type = models.IntegerField(default=0, verbose_name=u'推送类型')  # 0: apns, 1: 安卓gcm, 2: 极光
+    push_type = models.IntegerField(default=0, verbose_name=u'推送类型')  # 0: apns, 1: 安卓gcm, 2: 极光, 3:华为, 4:小米, 5:vivo, 6:oppo, 7:魅族
     token_val = models.CharField(default='', max_length=500, verbose_name=u'设备验证令牌')
     m_code = models.CharField(default='', max_length=64, db_index=True, verbose_name='手机唯一标识')
     lang = models.CharField(default='en', max_length=8, verbose_name='推送语言')
@@ -1826,7 +1826,7 @@ class CDKcontextModel(models.Model):
     rank = models.ForeignKey(Store_Meal, to_field='id', default='', on_delete=models.CASCADE, verbose_name='套餐类型')
     # order = models.ForeignKey(Order_Model, blank=True, max_length=20, to_field='orderID', on_delete=models.CASCADE, verbose_name='订单id', unique=True)
     order = models.CharField(max_length=20, blank=True, unique=True, verbose_name='订单id')
-    express_id = models.CharField(blank=True, max_length=20, verbose_name='速卖通订单id')
+    express_id = models.CharField(blank=True, max_length=128, verbose_name='速卖通订单id')
 
     # 备用字段
     spare_1 = models.CharField(default='', blank=True, max_length=64, verbose_name=u'备用字段1')
@@ -3334,3 +3334,41 @@ class DeviceSuperPassword(models.Model):
         db_table = 'device_super_password'
         verbose_name = '超级密码请求表'
         verbose_name_plural = verbose_name
+
+
+class VodHlsTag(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name='自增id')
+    uid = models.CharField(blank=True, db_index=True, max_length=32, verbose_name=u'设备UID')
+    vod_hls_id = models.IntegerField(default=0, db_index=True, verbose_name='云存hlsId')
+    tab_num = models.SmallIntegerField(default=0, verbose_name='所在表编号')
+    ai_event_time = models.IntegerField(default=0, db_index=True, verbose_name='ai事件事件')
+    created_time = models.IntegerField(default=0, verbose_name='创建时间')
+
+    class Meta:
+        db_table = 'vod_hls_tag'
+        verbose_name = '云存hls标签'
+        verbose_name_plural = verbose_name
+
+
+class VodHlsTagType(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name='自增id')
+    tag_id = models.IntegerField(default=0, db_index=True, verbose_name='云存关联AI标签ID')
+    type = models.SmallIntegerField(default=0, db_index=True, verbose_name='标签类型')
+    created_time = models.IntegerField(default=0, verbose_name='创建时间')
+
+    class Meta:
+        db_table = 'vod_hls_tag_type'
+        verbose_name = '云存hls关联标签类型'
+        verbose_name_plural = verbose_name
+
+
+class TestSerialRepetition(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name='自增id')
+    serial_number = models.CharField(blank=True, unique=True, db_index=True, max_length=20, default='',
+                                     verbose_name='序列号')
+    created_time = models.IntegerField(default=0, verbose_name='创建时间')
+
+    class Meta:
+        db_table = 'test_serial_repetition'
+        verbose_name = '测试序列号重复问题'
+        verbose_name_plural = verbose_name

+ 45 - 0
Object/Enums/DeviceTypeEnum.py

@@ -0,0 +1,45 @@
+# -*- encoding: utf-8 -*-
+"""
+@File    : MessageTypeEnum.py
+@Time    : 2023/2/13 15:50
+@Author  : stephen
+@Email   : zhangdongming@asj6.wecom.work
+@Software: PyCharm
+"""
+from enum import IntEnum, unique
+
+
+@unique
+class DeviceTypeEnum(IntEnum):
+
+    ASJ_DEVICE_TYPE_DVR = 1  # DVR
+    ASJ_DEVICE_TYPE_NVR = 2  # NVR
+    ASJ_DEVICE_TYPE_POE_NVR = 3  # POE NVR
+    ASJ_DEVICE_TYPE_WIRELESS_NVR = 4  # 无线 NVR
+    ASJ_DEVICE_TYPE_POE_IPC = 5  # POE IPC
+    ASJ_DEVICE_TYPE_BOLT_IPC = 6  # bolt ipc
+    ASJ_DEVICE_TYPE_IPC = 7  # IPC
+    ASJ_DEVICE_TYPE_KAPIANJI = 8  # 客户使用
+    ASJ_DEVICE_TYPE_FISHEYE = 9  # 客户使用
+    ASJ_DEVICE_TYPE_PTZ_IPC = 10  # PTZ IPC
+    ASJ_DEVICE_TYPE_C611 = 11  # 智能摄像机 C611
+    ASJ_DEVICE_TYPE_C612 = 12  # 智能摄像机 C612
+    ASJ_DEVICE_TYPE_C199 = 13  # 智能摄像机 C199
+    ASJ_DEVICE_TYPE_C190 = 14  # 智能摄像机 C190
+    ASJ_DEVICE_TYPE_C199PRO = 15  # 智能摄像机 C199Pro
+    ASJ_DEVICE_TYPE_C115 = 16  # 智能摄像机 C115
+    ASJ_DEVICE_TYPE_C289 = 17  # 智能摄像机 C289
+    ASJ_DEVICE_TYPE_C308 = 18  # 智能摄像机 C308
+    ASJ_DEVICE_TYPE_C513 = 20  # 智能摄像机 C513
+    ASJ_DEVICE_TYPE_C308_5M = 21  # 智能摄像机 C308_5M
+    ASJ_DEVICE_TYPE_C190Pro = 22  # 智能摄像机 C190Pro
+    ASJ_DEVICE_TYPE_C287 = 23  # 智能摄像机 C287
+    ASJ_DEVICE_TYPE_C516 = 24  # 智能摄像机 C516
+    ASJ_DEVICE_TYPE_C188 = 25  # 智能摄像机 C188
+    ASJ_DEVICE_TYPE_C2894G = 26  # 智能摄像机 C289 带4G网络
+    ASJ_DEVICE_TYPE_C296 = 27  # 智能摄像机 C296
+    ASJ_DEVICE_TYPE_C183 = 28  # 智能摄像机 C183
+    ASJ_DEVICE_TYPE_C518 = 29  # 智能摄像机 C518
+    ASJ_DEVICE_TYPE_C290 = 30  # 智能摄像机 C290
+    ASJ_DEVICE_TYPE_C182 = 31  # 智能摄像机 C182
+    ASJ_DEVICE_TYPE_C225 = 32  # 智能摄像机 C225

+ 31 - 0
Object/Enums/MessageTypeEnum.py

@@ -0,0 +1,31 @@
+# -*- encoding: utf-8 -*-
+"""
+@File    : MessageTypeEnum.py
+@Time    : 2023/2/13 15:50
+@Author  : stephen
+@Email   : zhangdongming@asj6.wecom.work
+@Software: PyCharm
+"""
+from enum import IntEnum, unique
+
+
+@unique
+class MessageTypeEnum(IntEnum):
+    AI_HUMAN_SHAPE = 1  # ai人形
+    AI_CAT = 2  # ai车型
+    AI_PET = 3  # ai宠物
+    AI_PARCEL = 4  # ai包裹
+    MOTION_DETECTION = 51  # 移动侦测
+    SENSOR_ALARM = 52  # 传感器报警
+    IMAGE_LOSS = 53  # 影像遗失
+    PIR = 54  # PIR
+    DOOR_MAGNETIC_ALARM = 55  # 门磁报警
+    EXTERNAL_TRANSMISSION = 56  # 外部发报
+    HUMAN_SHAPE = 57  # 人形报警
+    CAT = 58  # 车型
+    PET = 59  # 宠物
+    FACE = 60  # 人脸
+    ABNORMAL_SOUND = 61  # 异响
+    CAMERA_SLEEP = 702  # 摄像头休眠
+    CAMERA_WAKE_UP = 703  # 摄像头唤醒
+    LOW_BATTERY = 704  # 电量过低

+ 24 - 0
Object/Enums/OrderEnum.py

@@ -0,0 +1,24 @@
+# -*- encoding: utf-8 -*-
+"""
+@File    : OrderEnum.py
+@Time    : 2023/2/7 9:09
+@Author  : stephen
+@Email   : zhangdongming@asj6.wecom.work
+@Software: PyCharm
+"""
+from enum import IntEnum, unique
+
+
+@unique
+class OrderTypeEnum(IntEnum):
+    WAIT = 0  # 待支付
+    SUCCESS = 1  # 支付成功
+    CANCEL = 2  # 取消支付
+    REFUND_FAIL = 4  # 退款失败
+    REFUND = 5  # 全额退款
+    REBATES = 6  # 部分退款
+    PAYPAL_REFUND = 7  # PayPal已退款
+    BEING_PROCESSED = 9  # 处理中
+    FAIL = 10  # 支付失败
+
+

+ 8 - 0
Object/RedisObject.py

@@ -85,6 +85,14 @@ class RedisObject:
     def lrange(self, name, start, end):
         return self.CONN.lrange(name, start, end)
 
+    # 删除列表指定数据
+    def lrem(self, name, num, value):
+        """
+        num:列表方向,删除个数(0:所有)
+        value:删除的值
+        """
+        return self.CONN.lrem(name, num, value)
+
     def get_ttl(self, key):
         ttl = self.CONN.ttl(key)
         if ttl:

+ 1 - 1
Object/ResponseObject.py

@@ -258,4 +258,4 @@ class ResponseObject(object):
         if res is None:
             res = {}
         result = self.formal(code, res)
-        return HttpResponse(result)
+        return HttpResponse(result, content_type='application/json,charset=utf-8')

+ 2 - 0
Service/EquipmentInfoService.py

@@ -174,6 +174,8 @@ class EquipmentInfoService:
             qs = qs.filter(event_type__in=eventTypeList)
         if start_time and end_time:
             qs = qs.filter(event_time__range=(start_time, end_time))
+        else:
+            qs = qs.filter(event_time__range=(start_time, now_time))
         if uid_list:
             uid_list = uid_list.split(',')
             qs = qs.filter(device_uid__in=uid_list)

+ 131 - 19
Service/VodHlsService.py

@@ -2,33 +2,46 @@
 # @File      : VodHlsService.py
 # @Time      : 2023/2/1 15:57
 import datetime
-from Model.models import VodHlsMon, VodHlsTues, VodHlsWed, VodHlsThur, VodHlsFri, VodHlsSat, VodHlsSun
-from Service.CommonService import CommonService
+
+from django.db import connection
 from django.db.models import Count
 
+from Model.models import VodHlsMon, VodHlsTues, VodHlsWed, VodHlsThur, VodHlsFri, VodHlsSat, VodHlsSun, VodHlsTag, \
+    AiService, VodHlsTagType
+from Service.CommonService import CommonService
+
+
 class SplitVodHlsObject:
     # VodHls分表功能类
 
-    def creat_vod_hls_data(self, **kwargs):
+    @classmethod
+    def creat_vod_hls_data(cls, **kwargs):
         """
         分表保存云存信息数据
         """
         start_time = kwargs.get('start_time')
         week = datetime.datetime.fromtimestamp(int(start_time)).isoweekday()
         if week == 1:
-            VodHlsMon.objects.create(**kwargs)
+            vod_hls_mon = VodHlsMon.objects.create(**kwargs)
+            return vod_hls_mon, week
         elif week == 2:
-            VodHlsTues.objects.create(**kwargs)
+            vod_hls_tues = VodHlsTues.objects.create(**kwargs)
+            return vod_hls_tues, week
         elif week == 3:
-            VodHlsWed.objects.create(**kwargs)
+            vod_hls_wed = VodHlsWed.objects.create(**kwargs)
+            return vod_hls_wed, week
         elif week == 4:
-            VodHlsThur.objects.create(**kwargs)
+            vod_hls_thur = VodHlsThur.objects.create(**kwargs)
+            return vod_hls_thur, week
         elif week == 5:
-            VodHlsFri.objects.create(**kwargs)
+            vod_hls_fri = VodHlsFri.objects.create(**kwargs)
+            return vod_hls_fri, week
         elif week == 6:
-            VodHlsSat.objects.create(**kwargs)
+            vod_hls_sat = VodHlsSat.objects.create(**kwargs)
+            return vod_hls_sat, week
         elif week == 7:
-            VodHlsSun.objects.create(**kwargs)
+            vod_hls_sun = VodHlsSun.objects.create(**kwargs)
+            return vod_hls_sun, week
 
     def del_vod_hls_data(self, **kwargs):
         """
@@ -85,18 +98,25 @@ class SplitVodHlsObject:
                     day_list.append(week)
             for week in day_list:
                 if week == 1:
+                    kwargs = self.vod_query_param(week, **kwargs)
                     vod_hls_mon = VodHlsMon.objects.filter(**kwargs)
                 elif week == 2:
+                    kwargs = self.vod_query_param(week, **kwargs)
                     vod_hls_tus = VodHlsTues.objects.filter(**kwargs)
                 elif week == 3:
+                    kwargs = self.vod_query_param(week, **kwargs)
                     vod_hls_wed = VodHlsWed.objects.filter(**kwargs)
                 elif week == 4:
+                    kwargs = self.vod_query_param(week, **kwargs)
                     vod_hls_thur = VodHlsThur.objects.filter(**kwargs)
                 elif week == 5:
+                    kwargs = self.vod_query_param(week, **kwargs)
                     vod_hls_fri = VodHlsFri.objects.filter(**kwargs)
                 elif week == 6:
+                    kwargs = self.vod_query_param(week, **kwargs)
                     vod_hls_sat = VodHlsSat.objects.filter(**kwargs)
                 elif week == 7:
+                    kwargs = self.vod_query_param(week, **kwargs)
                     vod_hls_sun = VodHlsSun.objects.filter(**kwargs)
             vod_hls = vod_hls.union(vod_hls_mon, vod_hls_tus, vod_hls_wed, vod_hls_thur, vod_hls_fri, vod_hls_sat,
                                     vod_hls_sun)
@@ -109,7 +129,8 @@ class SplitVodHlsObject:
         vod_hls_sat = VodHlsSat.objects.filter(**kwargs)
         vod_hls_sun = VodHlsSun.objects.filter(**kwargs)
 
-        vod_hls = vod_hls.union(vod_hls_mon, vod_hls_tus, vod_hls_wed, vod_hls_thur, vod_hls_fri, vod_hls_sat, vod_hls_sun)
+        vod_hls = vod_hls.union(vod_hls_mon, vod_hls_tus, vod_hls_wed, vod_hls_thur, vod_hls_fri, vod_hls_sat,
+                                vod_hls_sun)
         return vod_hls
 
     def get_vod_hls_date(self, **kwargs):
@@ -119,19 +140,110 @@ class SplitVodHlsObject:
         """
 
         vod_hls_mon = VodHlsMon.objects.extra(select={'date': "FROM_UNIXTIME(start_time,'%%Y-%%m-%%d')"}).values(
-             'date').filter(**kwargs).annotate(count=Count('start_time')).order_by('-date')
+            'date').filter(**kwargs).annotate(count=Count('start_time')).order_by('-date')
         vod_hls_tus = VodHlsTues.objects.extra(select={'date': "FROM_UNIXTIME(start_time,'%%Y-%%m-%%d')"}).values(
-             'date').filter(**kwargs).annotate(count=Count('start_time')).order_by('-date')
+            'date').filter(**kwargs).annotate(count=Count('start_time')).order_by('-date')
         vod_hls_wed = VodHlsWed.objects.extra(select={'date': "FROM_UNIXTIME(start_time,'%%Y-%%m-%%d')"}).values(
-             'date').filter(**kwargs).annotate(count=Count('start_time')).order_by('-date')
+            'date').filter(**kwargs).annotate(count=Count('start_time')).order_by('-date')
         vod_hls_thur = VodHlsThur.objects.extra(select={'date': "FROM_UNIXTIME(start_time,'%%Y-%%m-%%d')"}).values(
-             'date').filter(**kwargs).annotate(count=Count('start_time')).order_by('-date')
+            'date').filter(**kwargs).annotate(count=Count('start_time')).order_by('-date')
         vod_hls_fri = VodHlsFri.objects.extra(select={'date': "FROM_UNIXTIME(start_time,'%%Y-%%m-%%d')"}).values(
-             'date').filter(**kwargs).annotate(count=Count('start_time')).order_by('-date')
+            'date').filter(**kwargs).annotate(count=Count('start_time')).order_by('-date')
         vod_hls_sat = VodHlsSat.objects.extra(select={'date': "FROM_UNIXTIME(start_time,'%%Y-%%m-%%d')"}).values(
-             'date').filter(**kwargs).annotate(count=Count('start_time')).order_by('-date')
+            'date').filter(**kwargs).annotate(count=Count('start_time')).order_by('-date')
         vod_hls_sun = VodHlsSun.objects.extra(select={'date': "FROM_UNIXTIME(start_time,'%%Y-%%m-%%d')"}).values(
-             'date').filter(**kwargs).annotate(count=Count('start_time')).order_by('-date')
+            'date').filter(**kwargs).annotate(count=Count('start_time')).order_by('-date')
 
         vod_hls = vod_hls_mon.union(vod_hls_tus, vod_hls_wed, vod_hls_thur, vod_hls_fri, vod_hls_sat, vod_hls_sun)
-        return vod_hls
+        return vod_hls
+
+    @classmethod
+    def cloud_vod_hls_tag(cls, vod_id, num, uid, start_time):
+        """
+        云存回调信息关联标签
+        @param vod_id: 云存回放信息id
+        @param num: 所在表编号
+        @param uid: 设备UID
+        @param start_time: 云存开始时间
+        @return: True | False
+        """
+        try:
+            # 查询设备是否有使用中的ai服务
+            # ai_service_qs = AiService.objects \
+            #     .filter(uid=uid, detect_status=1, use_status=1, endTime__gt=start_time) \
+            #     .values('detect_group')
+            # if not ai_service_qs.exists():
+            #     return False
+            start_time = int(start_time)
+            end_time = start_time + 5
+            vod_tag_qs = VodHlsTag.objects.filter(ai_event_time__range=(start_time, end_time), uid=uid)
+            if not vod_tag_qs.exists():
+                return False
+            vod_tag_qs.update(vod_hls_id=vod_id, tab_num=num)
+            return True
+        except Exception as e:
+            print('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            return False
+
+    @classmethod
+    def vod_query_param(cls, week, **kwargs):
+        vod_ids = cls.query_tag_by_types(kwargs.get('uid'),
+                                         kwargs.get('start_time__range'),
+                                         kwargs.get('type_list'), week)
+        if vod_ids:
+            kwargs['id__in'] = vod_ids
+        kwargs.pop('type_list')
+        return kwargs
+
+    @classmethod
+    def query_tag_by_types(cls, uid, time, types, num):
+        """
+        根据类型查询云存标签关联ID
+        @return:
+        """
+        try:
+            if not types or len(types) == 0:
+                return []
+            cursor = connection.cursor()
+            param_list = [int(time[0]), int(time[1]), uid, num]
+            sql = 'SELECT vod_hls_id FROM '
+            sql += 'vod_hls_tag vht INNER JOIN vod_hls_tag_type vhtt ON vht.id = vhtt.tag_id '
+            sql += 'WHERE vht.ai_event_time >= %s AND vht.ai_event_time <= %s '
+            sql += 'AND vht.uid = %s '
+            sql += 'AND tab_num = %s '
+            if types:
+                sql += 'AND vhtt.type IN %s '
+                param_list.append(types)
+            sql += 'GROUP BY vht.vod_hls_id '
+
+            cursor.execute(sql, param_list)
+            data_list = cursor.fetchall()
+            cursor.close()  # 执行完,关闭
+            connection.close()
+            data_list = [val[0] for val in data_list]
+            return data_list
+        except Exception as e:
+            print('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            return False
+
+    @classmethod
+    def query_tag_type_list(cls, vod_id):
+        """
+        根据云存ID获取AI类型
+        @return:
+        """
+        try:
+            cursor = connection.cursor()
+            sql = 'SELECT vhtt.type FROM '
+            sql += 'vod_hls_tag vht INNER JOIN vod_hls_tag_type vhtt ON vht.id = vhtt.tag_id '
+            sql += 'WHERE vht.vod_hls_id = %s  '
+
+            cursor.execute(sql, [vod_id])
+            data_list = cursor.fetchall()
+            cursor.close()  # 执行完,关闭
+            connection.close()
+            data_list = [val[0] for val in data_list]
+            return data_list
+        except Exception as e:
+            print('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            return []