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

Merge remote-tracking branch 'origin/master'

linhaohong 1 жил өмнө
parent
commit
6eac38e261
36 өөрчлөгдсөн 843 нэмэгдсэн , 339 устгасан
  1. 31 3
      AdminController/AiServeController.py
  2. 42 1
      AdminController/DeviceManagementController.py
  3. 6 2
      AdminController/SerialManageController.py
  4. 2 1
      AdminController/ServeManagementController.py
  5. 3 3
      AdminController/UnicomManageController.py
  6. 190 20
      AdminController/UserManageController.py
  7. 1 1
      Ansjer/Config/gatewaySensorConfig.py
  8. 1 1
      Ansjer/cn_config/config_formal.py
  9. 2 2
      Ansjer/config.py
  10. 5 5
      Controller/AiController.py
  11. 12 9
      Controller/CloudStorage.py
  12. 6 4
      Controller/Cron/CronTaskController.py
  13. 13 15
      Controller/DetectController.py
  14. 3 0
      Controller/DetectControllerV2.py
  15. 2 2
      Controller/DeviceConfirmRegion.py
  16. 1 66
      Controller/EquipmentInfo.py
  17. 2 2
      Controller/InitController.py
  18. 19 8
      Controller/PaymentCycle.py
  19. 8 4
      Controller/SerialNumberController.py
  20. 64 23
      Controller/ShadowController.py
  21. 12 5
      Controller/SysMsg.py
  22. 39 29
      Controller/TestApi.py
  23. 70 3
      Controller/UnicomCombo/UnicomComboController.py
  24. 10 2
      Controller/UnicomCombo/UnicomComboPayNotifyController.py
  25. 2 2
      Controller/UnicomCombo/WXTechController.py
  26. 2 2
      Controller/UserController.py
  27. 1 1
      Controller/VoicePromptController.py
  28. 38 25
      Controller/WeatherControl.py
  29. 62 3
      Model/models.py
  30. 22 7
      Object/ApschedulerObject.py
  31. 137 2
      Object/IPWeatherObject.py
  32. 2 0
      Object/uidManageResponseObject.py
  33. 25 2
      Service/CommonService.py
  34. 1 72
      Service/EquipmentInfoService.py
  35. 2 2
      Service/TemplateService.py
  36. 5 10
      Service/VodHlsService.py

+ 31 - 3
AdminController/AiServeController.py

@@ -5,7 +5,7 @@ import time
 from django.db.models import F
 from django.views.generic.base import View
 
-from Model.models import Lang, AiStoreMeal, AiService, Order_Model, Device_User, CountryModel, UidSetModel
+from Model.models import Lang, AiStoreMeal, AiService, Order_Model, Device_User, CountryModel, UidSetModel, Device_Info
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Service.CommonService import CommonService
@@ -305,6 +305,8 @@ class AiServeView(View):
         pageNo = request_dict.get('pageNo', None)
         pageSize = request_dict.get('pageSize', None)
         uid = request_dict.get('uid', None)
+        order_id = request_dict.get('orderId', None)
+        serialNumber = request_dict.get('serialNumber', None)
         if not all([pageNo, pageSize]):
             return response.json(444)
 
@@ -314,7 +316,12 @@ class AiServeView(View):
             ai_service_qs = AiService.objects.all()
             if uid:
                 ai_service_qs = ai_service_qs.filter(uid__contains=uid)
-
+            if serialNumber:
+                device_info_qs = Device_Info.objects.filter(serial_number=serialNumber).values('UID')
+                uid = device_info_qs[0]['UID'] if device_info_qs.exists() else 'N/A'
+                ai_service_qs = ai_service_qs.filter(uid__icontains=uid)
+            if order_id:
+                ai_service_qs = ai_service_qs.filter(orders_id=order_id)
             if not ai_service_qs.exists():
                 return response.json(0, [])
 
@@ -327,12 +334,33 @@ class AiServeView(View):
                 'use_status',
                 'detect_status',
                 'detect_group',
+                'orders_id',
                 'endTime',
                 'addTime',
                 'updTime', 'user_name').order_by('-addTime')
             ai_service_qs = ai_service_qs[(page - 1) * line:page * line]
+            ai_service_list = []
+            for ai_service in ai_service_qs:
+                data = {
+                    'id': ai_service['id'],
+                    'uid': ai_service['uid'],
+                    'channel': ai_service['channel'],
+                    'use_status': ai_service['use_status'],
+                    'detect_status': ai_service['detect_status'],
+                    'detect_group': ai_service['detect_group'],
+                    'endTime': ai_service['endTime'],
+                    'addTime': ai_service['addTime'],
+                    'updTime': ai_service['updTime'],
+                    'user_name': ai_service['user_name'],
+                    'order_id': ai_service['orders_id'],
+                    'serial_number': 'N/A'
+                }
+                device_info_qs = Device_Info.objects.filter(UID=ai_service['uid']).values('serial_number')
+                if device_info_qs.exists():
+                    data['serial_number'] = device_info_qs[0]['serial_number'] if device_info_qs[0]['serial_number'] else 'N/A'
+                ai_service_list.append(data)
             return response.json(
-                0, {'list': list(ai_service_qs), 'total': count})
+                0, {'list': ai_service_list, 'total': count})
         except Exception as e:
             print(e)
             return response.json(500, repr(e))

+ 42 - 1
AdminController/DeviceManagementController.py

@@ -8,6 +8,7 @@ import oss2
 from django.db import transaction
 from django.db.models import Q, F
 from django.views.generic.base import View
+from django.forms.models import model_to_dict
 
 from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, \
     AWS_SES_ACCESS_REGION, UNUSED_SERIAL_REDIS_LIST
@@ -48,6 +49,8 @@ class DeviceManagement(View):
             return self.get_device_icon(request_dict, response)
         elif operation == 'addAppDeviceType':  # 添加app设备类型数据并上传图标
             return self.add_app_device_type(request_dict, response, request)
+        elif operation == 'getUidPush':  # 查询推送信息
+            return self.get_uid_push(request_dict, response)
         else:
             tko = TokenObject(
                 request.META.get('HTTP_AUTHORIZATION'),
@@ -445,7 +448,7 @@ class DeviceManagement(View):
                 # 上传序列号文件且选中序列号解绑uid
                 if serialNumberList is not None and '序列号解绑uid' in delDataOptions:
                     # 解绑uid数据
-                    UIDModel.objects.filter(uid__in=uidList).update(status=0)
+                    UIDModel.objects.filter(uid__in=uidList, status=2).update(status=0)
                     UIDCompanySerialModel.objects.filter(uid__uid__in=uidList).delete()
                     CompanySerialModel.objects.filter(serial_number__in=serial_number_list).update(status=1)
                     UidPushModel.objects.filter(uid_set__uid__in=uidList).delete()
@@ -810,3 +813,41 @@ class DeviceManagement(View):
         except Exception as e:
             print(e)
             return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
+    def get_uid_push(self, request_dict, response):
+        """
+        查询设备信息图标
+        @param request_dict: 请求参数
+        @request_dict id: id
+        @param response: 响应对象
+        @return:
+        """
+        uid = request_dict.get('UID', None)
+        if not uid:
+            return response.json(444)
+        try:
+            uid_set_qs = UidSetModel.objects.get(uid=uid)
+            data = model_to_dict(uid_set_qs)
+            # uid_set查uid_push
+            uid_pushes_qs = UidPushModel.objects.filter(uid_set_id=uid_set_qs.id).select_related('userID')
+            uid_push_data = []
+            # 保存uid_pushes_qs列表
+            for item in uid_pushes_qs:
+                item_dict = model_to_dict(item)
+                # 添加 username 字段
+                item_dict['username'] = item.userID.username if item.userID else None
+                uid_push_data.append(item_dict)
+            data["uid_push"] = uid_push_data
+            return response.json(0, data)
+
+        except Exception as e:
+            print(e)
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
+
+
+
+
+
+
+

+ 6 - 2
AdminController/SerialManageController.py

@@ -319,8 +319,10 @@ class SerialView(View):
             if not uid_company_serial_qs.exists():
                 return response.json(173)
 
+            uid = uid_company_serial_qs[0]['uid__uid']
+
             res_data = {
-                'uid': uid_company_serial_qs[0]['uid__uid'],
+                'uid': uid,
                 'mac': uid_company_serial_qs[0]['uid__mac'],
                 'uid_extra': uid_company_serial_qs[0]['uid__uid_extra'],
                 'status': uid_company_serial_qs[0]['uid__status'],
@@ -349,8 +351,10 @@ class SerialView(View):
                 res_data['endpoint'] = iot_device_info_qs[0]['endpoint']
                 res_data['token_iot_number'] = iot_device_info_qs[0]['token_iot_number']
 
-            # 修改序列号状态为占用
+            # 修改序列号状态为占用,uid状态为3(数据被同步)
             CompanySerialModel.objects.filter(serial_number=serial).update(status=3)
+            UIDModel.objects.filter(uid=uid).update(status=3)
+
             return response.json(0, {'res_data': res_data})
         except Exception as e:
             return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))

+ 2 - 1
AdminController/ServeManagementController.py

@@ -771,6 +771,7 @@ class serveManagement(View):
                     'rank__day': order['rank__day'],
                     'rank__price': order['rank__price'],
                     'status': order['status'],
+                    'refund_status': 1 if order['status'] in [1, 4, 6] else 2,  # 订单显示(或不显示)退款功能
                     'order_type': order['order_type'],
                     'payTime': order['payTime'] if order['payTime'] else 'N/A',
                     'serialNumber': 'N/A' if serialNumber == order['UID'] else serialNumber,
@@ -1662,7 +1663,7 @@ class serveManagement(View):
                         if not unused_meal_qs.exists():
                             UID_Bucket.objects.filter(uid=uid).update(has_unused=0, updateTime=nowTime)
                         return response.json(0)
-                    unused_uid_Meal_qs = Unused_Uid_Meal.objects.filter(uid=uid, bucket_id=bucket_id)
+                    unused_uid_Meal_qs = Unused_Uid_Meal.objects.filter(uid=uid, bucket_id=bucket_id, order_id='')
                     if unused_uid_Meal_qs.exists():  # 如果通过uid查询到未使用套餐则删除套餐
                         unused_uid_Meal_qs.first().delete()
                         unused_meal_qs = Unused_Uid_Meal.objects.filter(uid=uid)

+ 3 - 3
AdminController/UnicomManageController.py

@@ -165,7 +165,7 @@ class UnicomManageControllerView(View):
                     res = wx_tech.delete_card_package(**data)
                     if res['code'] == '0':
                         UnicomComboExperienceHistory.objects.filter(iccid=iccid).delete()
-                        LOGGER.info(f"{serial_number}电信重置流量成功:{json.loads(response.text)}")
+                        LOGGER.info(f"{serial_number}电信重置流量成功:{json.dumps(res)}")
                         return response.json(0)
                     return response.json(176)
                 flow_push_qs = UnicomFlowPush.objects.filter(serial_no=serial_number)
@@ -652,7 +652,7 @@ class UnicomManageControllerView(View):
                 if unicom_combo is False:
                     return response.json(178)
                 rank_id, ai_rank_id = UnicomComboView.get_cloud_or_ai_combo()  # 生成订单必须添加该字段
-                uid = CommonService.query_uid_with_serial(serialNo)  # 获取序列号或UID
+                uid = CommonService.get_uid_by_serial_number(serialNo)  # 获取序列号或UID
                 # 获取套餐信息
                 order_dict = {
                     'orderID': order_id,
@@ -1233,7 +1233,7 @@ class UnicomManageControllerView(View):
             desc = '{} 转移后,前orderId:{}'.format(order_data['store_meal_name'], old_order_id)
             order_data['desc'] = desc
             now_order = CommonService.createOrderID()
-            uid = CommonService.query_uid_with_serial(target_serial_number)
+            uid = CommonService.get_uid_by_serial_number(target_serial_number)
             order_data['orderID'] = now_order
             order_data['UID'] = uid
             order_data['currency'] = 'CNY'

+ 190 - 20
AdminController/UserManageController.py

@@ -1,19 +1,7 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-"""
-@Copyright (C) ansjer cop Video Technology Co.,Ltd.All rights reserved.
-@AUTHOR: ASJRD018
-@NAME: AnsjerFormal
-@software: PyCharm
-@DATE: 2018/9/11 15:08
-@Version: python3.6
-@MODIFY DECORD:ansjer dev
-@file: UserController.py
-@Contact: chanjunkai@163.com
-"""
 import datetime
 import time
 import oss2
+import requests
 from django.contrib.auth.hashers import make_password, check_password  # 对密码加密模块
 from django.db import transaction
 from django.db.models import Q
@@ -22,10 +10,13 @@ from django.utils.timezone import utc
 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 Ansjer.config import SERVER_DOMAIN, OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, AWS_ACCESS_KEY_ID, \
+    AWS_SECRET_ACCESS_KEY, AWS_SES_ACCESS_REGION, DETECT_PUSH_DOMAINS
 from Controller.CheckUserData import DataValid, RandomStr
 from Model.models import Device_User, Role, UserExModel, CountryModel, MenuModel, FeedBackModel, StatResModel, \
-    SysMassModel, App_Info, SysMsgModel, DeviceSuperPassword
+    SysMassModel, App_Info, SysMsgModel, DeviceSuperPassword, CustomizedPush, DeviceTypeModel
+from Object.AWS.AmazonS3Util import AmazonS3Util
+from Object.ApschedulerObject import ApschedulerObject
 from Object.RedisObject import RedisObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
@@ -283,6 +274,10 @@ class UserManagement(View):
             return self.replyFeedBack(request_dict, response)
         elif operation == 'sendSysMsgToUser':
             return self.sendSysMsgToUser(request_dict, response)
+        elif operation == 'getCountryList':  # 查询国家列表
+            return self.getCountryList(response)
+        elif operation == 'getDeviceTypeList':  # 查询设备型号列表
+            return self.getDeviceTypeList(response)
         else:
             tko = TokenObject(request.META.get('HTTP_AUTHORIZATION'), returntpye='pc')
             if tko.code != 0:
@@ -307,14 +302,19 @@ class UserManagement(View):
                 return self.collectFeedBack(request_dict, response)
             elif operation == 'exportFeedBack':
                 return self.exportFeedBack(request_dict, response)
-            if operation == 'customerServiceManagement':  # 审核用户请求/生成超级密码
+            elif operation == 'customerServiceManagement':  # 审核用户请求/生成超级密码
                 return self.customerServiceManagement(request_dict, response)
-            if operation == 'getDeviceSuperPassword':  # 查询超级密码请求表
+            elif operation == 'getDeviceSuperPassword':  # 查询超级密码请求表
                 return self.getDeviceSuperPassword(request_dict, response)
-            if operation == 'deleteInformation':  # 删除超级密码请求表
+            elif operation == 'deleteInformation':  # 删除超级密码请求表
                 return self.deleteInformation(request_dict, response)
+            # 定制推送
+            elif operation == 'getCustomizedPushList':  # 查询定制推送列表
+                return self.getCustomizedPushList(request_dict, response)
+            elif operation == 'addOrEditCustomizedPush':  # 新增/编辑推送内容
+                return self.addOrEditCustomizedPush(request, request_dict, response)
             else:
-                return response.json(404)
+                return response.json(414)
 
     def getUserInfo(self, userID, request_dict, response):
         """
@@ -387,7 +387,7 @@ class UserManagement(View):
             return response.json(0, {'list': user_list, 'total': total})
         except Exception as e:
             print(e)
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def AddOrEditAccount(self, userID, request_dict, response):
         """
@@ -883,3 +883,173 @@ class UserManagement(View):
             return response.json(173)
         device_super_password_qs.delete()
         return response.json(0)
+
+    @staticmethod
+    def getCustomizedPushList(request_dict, response):
+        title = request_dict.get('title', None)
+        country = request_dict.get('country', None)
+        device_type = request_dict.get('device_type', None)
+        push_satus = request_dict.get('push_satus', None)
+        page = request_dict.get('pageNo', None)
+        line = request_dict.get('pageSize', None)
+
+        if not all([page, line]):
+            return response.json(444)
+
+        page = int(page)
+        line = int(line)
+
+        try:
+            customized_push_qs = CustomizedPush.objects.all()
+            if title:
+                customized_push_qs = customized_push_qs.filter(title=title)
+            if country:
+                customized_push_qs = customized_push_qs.filter(country=country)
+            if device_type:
+                customized_push_qs = customized_push_qs.filter(device_type__contains=device_type)
+            if push_satus:
+                customized_push_qs = customized_push_qs.filter(push_satus=push_satus)
+            if not customized_push_qs.exists():
+                return response.json(0, [])
+            total = customized_push_qs.count()
+            customized_push_qs = customized_push_qs.\
+                values('id', 'title', 'msg', 'link', 'icon_link', 'country', 'device_type', 'register_period',
+                       'time_zone', 'push_time', 'push_app', 'push_satus')
+            customized_push_qs = customized_push_qs[(page - 1) * line:page * line]
+            customized_push_list = []
+            for customized_push in customized_push_qs:
+                # 格式化数据
+                register_period = customized_push['register_period'] + '年'
+                time_zone = 'UTC ' + customized_push['time_zone']
+
+                customized_push_list.append({
+                    'customized_push_id': customized_push['id'],
+                    'title': customized_push['title'],
+                    'msg': customized_push['msg'],
+                    'link': customized_push['link'],
+                    'icon_link': customized_push['icon_link'],
+                    'country': customized_push['country'],
+                    'device_type': customized_push['device_type'],
+                    'register_period': register_period,
+                    'time_zone': time_zone,
+                    'push_time': customized_push['push_time'],
+                    'push_app': customized_push['push_app'],
+                    'push_satus': customized_push['push_satus']
+                })
+            return response.json(0, {'list': customized_push_list, 'total': total})
+        except Exception as e:
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
+    @classmethod
+    def addOrEditCustomizedPush(cls, request, request_dict, response):
+        title = request_dict.get('title', None)
+        msg = request_dict.get('msg', None)
+        link = request_dict.get('link', None)
+        icon = request.FILES.get('icon', None)
+        country = request_dict.get('country', None)
+        device_type = request_dict.get('deviceType', None)
+        register_period = request_dict.get('registerPeriod', None)
+        time_zone = request_dict.get('timeZone', None)
+        push_time = request_dict.get('pushTime', None)
+        push_app = request_dict.get('pushApp', None)
+        is_edit = request_dict.get('isEdit', None)
+
+        if not all([title, msg, link, country, device_type, register_period, time_zone, push_time, push_app]):
+            return response.json(444)
+
+        # 截掉UTC和空格
+        time_zone = time_zone[4:]
+        try:
+            push_timestamp = CommonService.convert_to_timestamp(float(time_zone), push_time)
+            if push_timestamp <= int(time.time()):
+                return response.json(806)
+            customized_push_data = {
+                'title': title,
+                'msg': msg,
+                'link': link,
+                'country': country,
+                'device_type': device_type,
+                'register_period': register_period,
+                'time_zone': time_zone,
+                'push_time': push_time,
+                'push_timestamp': push_timestamp,
+                'push_app': push_app
+            }
+            icon_link = ''
+            if icon is not None:
+                icon_name = icon.name
+                icon_link = 'https://ansjerfilemanager.s3.amazonaws.com/customized-push/' + icon_name
+                customized_push_data['icon_link'] = icon_link
+
+                if icon_link:
+                    # 上传没有上传过的图片到S3
+                    customized_push_qs = CustomizedPush.objects.filter(icon_link=icon_link)
+                    if not customized_push_qs.exists():
+                        bucket = 'ansjerfilemanager'
+                        file_key = 'customized-push/' + icon_name
+                        s3 = AmazonS3Util(AWS_ACCESS_KEY_ID[1], AWS_SECRET_ACCESS_KEY[1], AWS_SES_ACCESS_REGION)
+                        s3.upload_file_obj(
+                            bucket,
+                            file_key,
+                            icon,
+                            {'ContentType': icon.content_type, 'ACL': 'public-read'})
+
+            apscheduler_obj = ApschedulerObject()
+            if is_edit:     # 编辑
+                customized_push_id = request_dict.get('customizedPushId', None)
+                if not customized_push_id:
+                    return response.json(444)
+                customized_push_data['push_satus'] = False
+                CustomizedPush.objects.filter(id=customized_push_id).update(**customized_push_data)
+                apscheduler_obj.del_job('customizedPushId_{}'.format(customized_push_id))  # 删除旧定时任务
+            else:           # 新增
+                customized_push = CustomizedPush.objects.create(**customized_push_data)
+                customized_push_id = customized_push.id
+
+            # 创建定时任务
+            task_id = 'customized_push_id_{}'.format(customized_push_id)
+            apscheduler_obj.create_date_job(func=cls.req_customized_push, task_id=task_id, time_stamp=push_timestamp,
+                                            args=(customized_push_id,))
+            return response.json(0)
+        except Exception as e:
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
+    @staticmethod
+    def req_customized_push(customized_push_id):
+        """
+        请求定制化推送
+        @param customized_push_id:
+        @return:
+        """
+        data = {'customized_push_id': customized_push_id}
+        print(data)
+        url = DETECT_PUSH_DOMAINS + 'customized_push/start'
+        req = requests.post(url=url, data=data, timeout=8)
+
+    @staticmethod
+    def getCountryList(response):
+        try:
+            country_qs = CountryModel.objects.filter().values('country_name')
+            if not country_qs.exists():
+                return response.json(173)
+
+            country_list = []
+            for country in country_qs:
+                country_list.append(country['country_name'])
+            return response.json(0, {'list': country_list})
+        except Exception as e:
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
+    @staticmethod
+    def getDeviceTypeList(response):
+        try:
+            device_type_qs = DeviceTypeModel.objects.filter().values('name')
+            if not device_type_qs.exists():
+                return response.json(173)
+
+            device_type_list = []
+            for device_type in device_type_qs:
+                device_type_list.append(device_type['name'])
+            return response.json(0, {'list': device_type_list})
+        except Exception as e:
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))

+ 1 - 1
Ansjer/Config/gatewaySensorConfig.py

@@ -37,7 +37,7 @@ EVENT_TYPE = {
     # 门磁
     'door_magnet_opening': 2150,
     'door_magnet_closure': 2151,
-    'door_magnet_removal': 2152,
+    'door_magnet_removal': 2156,
     'door_magnet_low_power': 2153,
     'door_magnet_start_detection': 2154,
     'door_magnet_closure_detection': 2155,

+ 1 - 1
Ansjer/cn_config/config_formal.py

@@ -32,7 +32,7 @@ DOMAIN_HOST = 'www.zositechc.cn'
 SERVER_DOMAIN = 'https://www.zositechc.cn/'
 SERVER_DOMAIN_SSL = 'https://www.zositechc.cn/'
 NGINX_RTMP_STAT = 'http://www.zositechc.cn/stat'
-DETECT_PUSH_DOMAIN = 'https://push.zositechc.cn/'
+DETECT_PUSH_DOMAIN = 'http://push.zositechc.cn/'
 DETECT_PUSH_DOMAINS = 'https://push.zositechc.cn/'
 DETECT_PUSH_DOMAIN_JIUAN = 'http://jiuan.push.zositechc.cn/'
 DETECT_PUSH_DOMAINS_JIUAN = 'https://jiuan.push.zositechc.cn/'

+ 2 - 2
Ansjer/config.py

@@ -88,7 +88,7 @@ AWS_SECRET_ACCESS_KEY = ['aI9gxcAKPmiGgPy9axrtFKzjYGbvpuytEX4xWweL', 'ckYLg4Lo9Z
 AWS_ARN = ['arn:aws-cn:s3', 'arn:aws:s3']
 
 # 尚云服务器CRCKey
-CRCKey = {'AUS': 'CRCKey', 'ACN': 'CRCKey'}  # {平台名:CRCKey值}
+CRCKey = {'AUS': 'CRCKey', 'ACN': 'CRCKey', 'AEU': 'CRCKey'}  # {平台名:CRCKey值}
 
 # 各个服务器域名
 SERVER_DOMAIN_US = 'http://www.dvema.com/'
@@ -457,7 +457,7 @@ APP_TYPE = {
     2: 'android'
 }
 
-ALGORITHM_COMBO_TYPES = [51, 57, 58, 60, 59, 61, 62, 63, 64, 65, 66, 67, 68, 69]
+ALGORITHM_COMBO_TYPES = [51, 57, 58, 60, 59, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70]
 
 # 联通Unicom config
 # 应用地址,请向开发人员索取

+ 5 - 5
Controller/AiController.py

@@ -58,11 +58,11 @@ class AiView(View):
             # 套餐相关接口
             if operation == 'commoditylist':        # 查询套餐列表
                 return self.commodity_list(request_dict, response)
-            elif operation == 'experienceOrder':    # 体验套餐
-                return self.experience_order(request_dict, user_id, response)
-            elif operation == 'createpayorder':     # 创建支付订单
-                return self.create_pay_order(request_dict, request, user_id, response)
-            elif operation == 'queryorderlist':     # 查询订单列表
+            # elif operation == 'experienceOrder':  # 体验套餐
+            #     return self.experience_order(request_dict, user_id, response)
+            # elif operation == 'createpayorder':  # 创建支付订单
+            #     return self.create_pay_order(request_dict, request, user_id, response)
+            elif operation == 'queryorderlist':  # 查询订单列表
                 return self.query_order_list(request_dict, user_id, response)
             elif operation == 'getUsingPackage':    # 获取当前使用套餐
                 return self.get_using_package(request_dict, response)

+ 12 - 9
Controller/CloudStorage.py

@@ -568,11 +568,11 @@ class CloudStorageView(View):
                       'uid={uid}&channel={channel}&time={time}&sign=tktktktk'. \
                 format(server_domain=SERVER_DOMAIN_SSL, uid=uid_token, channel=vod['channel'], time=vod['start_time'])
             ts_num = int(vod['fg']) & 0xf
-            dict_item = [item for item in tag_type_list if item['vod_hls_id'] == vod['id']]
+            # dict_item = [item for item in tag_type_list if item['vod_hls_id'] == vod['id']]
             types = []
-            if dict_item:
-                tag_qs = VodHlsTagType.objects.filter(tag_id=dict_item[0]['id']).values('type')
-                types = [val['type'] for val in tag_qs]
+            # if dict_item:
+            #     tag_qs = VodHlsTagType.objects.filter(tag_id=dict_item[0]['id']).values('type')
+            #     types = [val['type'] for val in tag_qs]
 
             vod_play_list.append({
                 'start_time': vod['start_time'],
@@ -651,7 +651,7 @@ class CloudStorageView(View):
             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)
+            split_vod_hls_obj.cloud_vod_hls_tag(vod_vo.id, week, uid, start_time, sec)  # 云存关联AI标签
             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'))
@@ -1198,7 +1198,7 @@ class CloudStorageView(View):
         now_time = int(time.time())
         store_qs = Store_Meal.objects.filter(id=rank, pay_type=pay_type, lang__lang=lang, is_show=0). \
             values('currency', 'price', 'lang__content', 'day', 'commodity_type', 'lang__title', 'expire',
-                   'commodity_code', 'discount_price', 'bucket__mold', 'cycle_config_id')
+                   'commodity_code', 'discount_price', 'bucket__mold', 'cycle_config_id', 'is_ai')
         if not store_qs.exists():
             return response.json(173)
         store_meal_qs = Store_Meal.objects.filter(id=rank, lang__lang='cn', is_show=0).values('lang__title',
@@ -1209,6 +1209,8 @@ class CloudStorageView(View):
             store_meal_name = '未知套餐'
         currency = store_qs[0]['currency']
         price = store_qs[0]['price']
+        is_ai = store_qs[0]['is_ai']
+        order_type = 1 if is_ai else 0
         if is_select_discount == '1':
             price = float(store_qs[0]['price']) + float(store_qs[0]['discount_price'])
         content = store_qs[0]['lang__content']
@@ -1254,7 +1256,7 @@ class CloudStorageView(View):
                 Order_Model.objects.create(orderID=order_id, UID=uid, channel=channel, userID_id=user_id,
                                            desc=content, payType=pay_type, payTime=now_time,
                                            price=price, currency=currency, addTime=now_time,
-                                           updTime=now_time,
+                                           updTime=now_time, order_type=order_type,
                                            pay_url=sub_info['url'], isSelectDiscounts=is_select_discount,
                                            commodity_code=commodity_code, commodity_type=commodity_type,
                                            rank_id=rank, plan_id=sub_info['plan_id'], coupon_id=coupon_id,
@@ -1289,7 +1291,7 @@ class CloudStorageView(View):
                     Order_Model.objects.create(orderID=order_id, UID=uid, channel=channel, userID_id=user_id,
                                                desc=content, payType=pay_type, payTime=now_time,
                                                price=price, currency=currency, addTime=now_time,
-                                               updTime=now_time,
+                                               updTime=now_time, order_type=order_type,
                                                pay_url=approval_url, isSelectDiscounts=is_select_discount,
                                                commodity_code=commodity_code, commodity_type=commodity_type,
                                                rank_id=rank, paymentID=payment_id, coupon_id=coupon_id,
@@ -1440,6 +1442,7 @@ class CloudStorageView(View):
         if not uid_set_qs.exists():
             return response.json(173)
         is_ai = 1 if uid_set_qs[0]['is_ai'] != 2 else 0
+        order_type = 1 if is_ai and CONFIG_INFO != CONFIG_CN else 0
         use_flag = True
         end_time = CommonService.calcMonthLater(expire)
         try:
@@ -1470,7 +1473,7 @@ class CloudStorageView(View):
                 Order_Model.objects.create(orderID=order_id, UID=uid, channel=channel, userID_id=user_id,
                                            desc=store_qs[0]['lang__content'], payType=pay_type, payTime=now_time,
                                            price=store_qs[0]['price'], currency=store_qs[0]['currency'],
-                                           addTime=now_time,
+                                           addTime=now_time, order_type=order_type,
                                            updTime=now_time,
                                            pay_url="体验版", store_meal_name=store_meal_name,
                                            commodity_code=commodity_code, commodity_type=store_qs[0]['commodity_type'],

+ 6 - 4
Controller/Cron/CronTaskController.py

@@ -97,10 +97,12 @@ class CronDelDataView(View):
                           '72V201254AA',
                           'V82301850AA',
                           'V82301850XA',
-                          '72V201257AA']
+                          '72V201257AA', '72V201256AA']
             UidSetModel.objects.filter(ucode__in=ucode_list, is_human=0).update(is_human=1)
-            ucode_list = ['72V201257AA', '72V201254AA']
+
+            ucode_list = ['72V201257AA', '72V201254AA']  # 4G规格码
             UidSetModel.objects.filter(ucode__in=ucode_list, mobile_4g=0).update(mobile_4g=1)
+
             # 根据设备规格码定时更新默认算法类型类型
             ucode_list = ['823C01552AA', '823C01550AA', '823C01550XA', 'C18201550KA',
                           '823C01550TA', '823C01550VA', '823C01850XA', 'C18201850KA',
@@ -118,7 +120,7 @@ class CronDelDataView(View):
                           '823C01550VA', '823C01850XA', 'C18201850KA', '823C01850TA', '823C01850VA',
                           '730201450AA', '730201450MA', '730201450NA', '72V201252AA', '72V201253AA',
                           '72V201353AA', '72V201354AA', '72V201355AA', '72V201254AA', 'C22501850VA',
-                          'V82301850AA', 'V82301850XA', '72V201257AA']
+                          'V82301850AA', 'V82301850XA', '72V201257AA', '72V201256AA']
             UidSetModel.objects.filter(ucode__in=ucode_list, is_custom_voice=0).update(is_custom_voice=1)
 
             # 根据设备规格码更新is_ai
@@ -126,7 +128,7 @@ class CronDelDataView(View):
                           '823C01550VA', '823C01850XA', 'C18201850KA', '823C01850TA', '823C01850VA',
                           '730201450AA', '730201450MA', '730201450NA', '72V201252AA', '72V201253AA',
                           '72V201353AA', '72V201354AA', '72V201355AA', '72V201254AA', 'C22501850VA',
-                          'V82301850AA', 'V82301850XA', '72V201257AA']
+                          'V82301850AA', 'V82301850XA', '72V201257AA', '72V201256AA']
             UidSetModel.objects.filter(ucode__in=ucode_list, is_ai=2).update(is_ai=1)
             return response.json(0)
         except Exception as e:

+ 13 - 15
Controller/DetectController.py

@@ -26,13 +26,14 @@ from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, DETECT_PUSH
     JPUSH_CONFIG, FCM_CONFIG, APNS_CONFIG, \
     BASE_DIR, APNS_MODE, SERVER_TYPE, LOGGER
 from Ansjer.config import PUSH_REDIS_ADDRESS
-from Model.models import Device_Info, VodHlsModel, Equipment_Info, UidSetModel, UidPushModel, SysMsgModel, \
+from Model.models import Device_Info, Equipment_Info, UidSetModel, UidPushModel, SysMsgModel, \
     VodBucketModel
 from Object.ETkObject import ETkObject
 from Object.RedisObject import RedisObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Object.UidTokenObject import UidTokenObject
+from Object.utils import LocalDateTimeUtil
 from Service.CommonService import CommonService
 from Service.EquipmentInfoService import EquipmentInfoService
 from Service.VodHlsService import SplitVodHlsObject
@@ -85,22 +86,19 @@ class DetectControllerView(View):
         startTime = request_dict.get('startTime', None)
         endTime = request_dict.get('endTime', None)
         eventType = request_dict.get('eventType', None)
-        # qs = Equipment_Info.objects.filter(userID_id=userID).order_by('-eventTime')
-        # if startTime and endTime:
-        #     qs = qs.filter(eventTime__range=(startTime, endTime))
-        # if eventType:
-        #     qs = qs.filter(eventType=eventType)
+        uids = request_dict.get('uids', None)
         try:
-            if startTime and endTime:
-                qs, count = EquipmentInfoService.find_by_start_time_equipment_info(page, line, userID, startTime,
-                                                                                   endTime, eventType,
-                                                                                   request_dict.get('uids', None))
+            uid_list = []
+            if uids:
+                uid_list = uids.split(',')
 
-            else:
-                # 默认查询近七天消息推送
-                qs, count = EquipmentInfoService.get_equipment_info_week_all(page, line, userID, startTime, endTime,
-                                                                             eventType,
-                                                                             request_dict.get('uids', None))
+            if not startTime and not endTime:
+                # 默认查询近七天内数据
+                endTime = int(time.time())
+                startTime = LocalDateTimeUtil.get_before_days_timestamp(endTime, 7)
+
+            qs, count = EquipmentInfoService. \
+                union_equipment_info(userID, uid_list, eventType, startTime, endTime, page, line)
             logger.info('<<<|||分表查询结果count:{}'.format(count))
             uids = request_dict.get('uids', None)
             if uids:

+ 3 - 0
Controller/DetectControllerV2.py

@@ -273,7 +273,10 @@ class DetectControllerViewV2(View):
                 etk = etkObj.encrypt(uid)
 
                 if company_secrete == 'MTEyMTNB':
+                    d_type = device_info_qs[0].Type
                     url = DETECT_PUSH_DOMAIN
+                    if d_type in [103, 26]:
+                        url = DETECT_PUSH_DOMAINS
                     urls = DETECT_PUSH_DOMAINS
                 else:
                     url = DETECT_PUSH_DOMAIN_JIUAN

+ 2 - 2
Controller/DeviceConfirmRegion.py

@@ -26,7 +26,7 @@ class ConfirmRegion(View):
             device_domain_qs = DeviceDomainModel.objects.filter(ip=ip)
 
             # 获取国家编码
-            ip_addr_qs = IPAddr.objects.filter(ip=ip).values('country_code')
+            ip_addr_qs = IPAddr.objects.filter(ip=ip, is_geoip2=False).values('country_code')
             if ip_addr_qs.exists():
                 country_code = ip_addr_qs[0]['country_code']
             else:
@@ -93,7 +93,7 @@ class ConfirmRegionV2(View):
             data_dict['ip'] = ip
 
             # 获取国家编码
-            ip_addr_qs = IPAddr.objects.filter(ip=ip).values('country_code')
+            ip_addr_qs = IPAddr.objects.filter(ip=ip, is_geoip2=False).values('country_code')
             if ip_addr_qs.exists():
                 country_code = ip_addr_qs[0]['country_code']
             else:

+ 1 - 66
Controller/EquipmentInfo.py

@@ -57,72 +57,7 @@ class EquipmentInfo(View):
             return response.json(444, {"parm": "operation"})
 
     def add_info(self, request_dict, userID, response):
-        devUid = request_dict.get('devUid', None)
-        Channel = request_dict.get('Channel', None)
-        eventType = request_dict.get('eventType', None)
-        eventTime = request_dict.get('eventTime', None)
-        receiveTime = request_dict.get('receiveTime', None)
-        alarm = request_dict.get('alarm', None)
-        if not devUid or not Channel or not eventType or not eventTime or not alarm or not receiveTime:
-            return response.json(444, 'devUid, Channel, eventType, eventTime, alarm, receiveTime')
-        own_device = ModelService.check_own_device(userID, UID=devUid)
-        if own_device is not True:
-            return response.json(14)
-        device_info = Device_Info.objects.filter(UID=devUid, userID_id=userID)
-        if not device_info.exists():
-            return response.json(14)
-        try:
-
-            nowTime = int(time.time())
-            equipment_info = Equipment_Info(
-                userID_id=userID,
-                devUid=devUid,
-                Channel=Channel,
-                eventType=eventType,
-                receiveTime=receiveTime,
-                eventTime=eventTime,
-                devNickName=device_info[0].NickName,
-                addTime=nowTime,
-                alarm=alarm)
-            equipment_info.save()
-            uid_push_qs = UidPushModel.objects.filter(uid_set__uid=devUid, uid_set__detect_status=1). \
-                values('token_val', 'app_type', 'appBundleId', 'm_code', 'push_type', 'userID_id', 'userID__NickName',
-                       'lang', 'm_code', 'tz', 'uid_set__nickname', 'uid_set__detect_interval', 'uid_set__detect_group',
-                       'uid_set__channel')
-            tz = '0'
-            if uid_push_qs.exists():
-                tz = uid_push_qs.first().tz
-            local_date_time = CommonService.get_now_time_str(n_time=nowTime, tz=tz, lang='cn')
-            local_date_time = local_date_time[0:10]
-            equipment_info_vo = EquipmentInfoService.get_equipment_info_obj(
-                local_date_time,
-                device_user_id=userID,
-                event_time=nowTime,
-                event_type=eventType,
-                device_uid=devUid,
-                device_nick_name=device_info[0].NickName,
-                channel=Channel,
-                alarm=alarm,
-                receive_time=receiveTime,
-                add_time=nowTime,
-            )
-            equipment_info_vo.save()
-        except Exception:
-            errorInfo = traceback.format_exc()
-            print(errorInfo)
-            return response.json(500, errorInfo)
-        else:
-            if equipment_info.id:
-                return response.json(0, {'infoID': equipment_info.id,
-                                         'devUid': devUid,
-                                         'Channel': Channel,
-                                         'alarm': alarm,
-                                         'eventType': eventType,
-                                         'eventTime': eventTime,
-                                         'receiveTime': receiveTime,
-                                         'devNickName': equipment_info.devNickName})
-            else:
-                return response.json(500)
+        return response.json(0)
 
     def query_info(self, request_dict, userID, response):
         page = int(request_dict.get('page', None))

+ 2 - 2
Controller/InitController.py

@@ -10,7 +10,7 @@ from django.views import View
 
 from Model.models import Device_User, Device_Info, Order_Model, UidPushModel, UserExModel, UserOauth2Model, \
     UidUserModel, GrantCodeModel, UserAppFrequencyModel, \
-    AppLogModel, UserFamily, FamilyMember, FamilyMemberJoin, SmartScene, DeviceSuperPassword, SceneLog
+    AppLogModel, UserFamily, FamilyMember, FamilyMemberJoin, SmartScene, DeviceSuperPassword
 from Object.RedisObject import RedisObject
 from Object.ResponseObject import ResponseObject
 
@@ -37,9 +37,9 @@ class InitView(View):
     def health_check(request_dict):
         try:
             redis_obj = RedisObject()
+            redis_obj.set_data('health_check', 1)
             response = ResponseObject()
             Device_Info.objects.filter().values('id').first()
-            SceneLog.objects.filter().values('id').first()
             return response.json(0)
         except Exception as e:
             return HttpResponse(repr(e), status=500)

+ 19 - 8
Controller/PaymentCycle.py

@@ -26,7 +26,7 @@ PAY_LOGGER = logging.getLogger('pay')
 class Paypal:
     # 检查是否有重复订阅
     def checkSubscriptions(userID, uid, rank):
-        hasOrder = Order_Model.objects.filter(UID=uid, rank=rank)
+        hasOrder = Order_Model.objects.filter(UID=uid)
         hasOrder = hasOrder.filter(~Q(agreement_id='')).values('agreement_id', 'orderID').order_by('-addTime')[0:1]
         if not hasOrder.exists():
             return True
@@ -240,8 +240,11 @@ class PaypalCycleNotify(View):
                         update_status = UID_Bucket.objects.filter(id=uid_bucket_id).update(has_unused=1)
                         use_flag = False
                     else:  # 云存服务已过期则重新开通云存服务
-                        update_status = UID_Bucket.objects.filter(id=uid_bucket_id).update(uid=UID, channel=channel, bucket_id=bucketId,
-                                                                           endTime=endTime, updateTime=nowTime)
+                        update_status = UID_Bucket.objects.filter(id=uid_bucket_id).update(uid=UID, channel=channel,
+                                                                                           bucket_id=bucketId,
+                                                                                           endTime=endTime,
+                                                                                           updateTime=nowTime,
+                                                                                           use_status=1)
 
                 else:
                     ub_cqs = UID_Bucket.objects.create \
@@ -406,7 +409,7 @@ class PaypalCycleNotify(View):
             order_qs = Order_Model.objects.filter(orderID=order_id).values('UID', 'channel', 'commodity_code', 'rank',
                                                                            'isSelectDiscounts', 'plan_id', 'desc',
                                                                            'payType', 'currency', 'addTime',
-                                                                           'commodity_type', 'updTime',
+                                                                           'commodity_type', 'updTime', 'order_type',
                                                                            'userID__userID', 'uid_bucket_id',
                                                                            'userID__username', 'userID__region_country'
                                                                            )
@@ -441,6 +444,7 @@ class PaypalCycleNotify(View):
             username = order_qs[0]['userID__username']
             channel = order_qs[0]['channel']
             rank = order_qs[0]['rank']
+            order_type = order_qs[0]['order_type']
             store_meal_qs = Store_Meal.objects.filter(id=rank).values("day", "bucket_id", "bucket__storeDay", "expire",
                                                                       "is_ai")
             if not store_meal_qs.exists():
@@ -463,16 +467,23 @@ class PaypalCycleNotify(View):
                     if ubq['use_status'] == 1 and ubq['endTime'] > nowTime:  # 套餐使用中并且未过期
                         Unused_Uid_Meal.objects.create(uid=UID, channel=channel, addTime=nowTime, is_ai=is_ai,
                                                        order_id=orderID, expire=expire, bucket_id=bucketId)
-                        UID_Bucket.objects.filter(id=ubq['id']).update(has_unused=1)
+                        update_status = UID_Bucket.objects.filter(id=ubq['id']).update(has_unused=1)
                         use_flag = False
                     else:  # 已过期或者不相同的套餐加入未使用的关联套餐表
-                        UID_Bucket.objects.filter(id=uid_bucket_id).update(uid=UID, channel=channel, bucket_id=bucketId,
-                                                                           endTime=endTime, updateTime=nowTime)
+                        update_status = UID_Bucket.objects.filter(id=uid_bucket_id).update(uid=UID, channel=channel,
+                                                                                           bucket_id=bucketId,
+                                                                                           endTime=endTime,
+                                                                                           updateTime=nowTime,
+                                                                                           use_status=1)
 
                 else:
                     ub_cqs = UID_Bucket.objects.create(uid=UID, channel=channel, bucket_id=bucketId, endTime=endTime,
                                                        addTime=nowTime, updateTime=nowTime, use_status=1)
                     uid_bucket_id = ub_cqs.id
+                    update_status = True
+                PAY_LOGGER.info(
+                    'uid:{},uid_bucket_id:{},update_status:{},order_id:{}'.format(UID, uid_bucket_id, update_status,
+                                                                                  orderID))
                 dvq = Device_Info.objects.filter(UID=UID, vodPrimaryUserID='', vodPrimaryMaster='')
                 if dvq.exists():
                     dvq_set_update_dict = {
@@ -491,7 +502,7 @@ class PaypalCycleNotify(View):
                                            desc=desc, payType=pay_type, payTime=nowTime,
                                            price=amount.get('total'),
                                            currency=order_qs[0]['currency'], addTime=nowTime,
-                                           updTime=nowTime,
+                                           updTime=nowTime, order_type=order_type,
                                            pay_url='', isSelectDiscounts=0,
                                            commodity_code=commodity_code,
                                            commodity_type=commodity_type, rank_id=rank, paymentID='',

+ 8 - 4
Controller/SerialNumberController.py

@@ -296,7 +296,11 @@ class SerialNumberView(View):
                         'uid__init_string', 'uid__init_string_app')
             uid_info = {}
             if uid_company_qs.exists():
-                uid_info['uid'] = uid_company_qs[0]['uid__uid']
+                # 更新被同步数据的uid的状态为3(数据被同步)
+                uid = uid_company_qs[0]['uid__uid']
+                UIDModel.objects.filter(uid=uid).update(status=3)
+
+                uid_info['uid'] = uid
                 uid_info['mac'] = uid_company_qs[0]['uid__mac']
                 uid_info['uid_extra'] = uid_company_qs[0]['uid__uid_extra']
                 uid_info['status'] = uid_company_qs[0]['uid__status']
@@ -554,8 +558,8 @@ class SerialNumberView(View):
                 else:
                     redisObj.rpush(RESET_REGION_ID_SERIAL_REDIS_LIST, serial)
 
-                # 重置uid的使用状态为未使用,更新时间
-                UIDModel.objects.filter(uid=uid).update(status=0, mac='', update_time=now_time)
+                # 重置已使用的uid的使用状态为未使用,更新时间
+                UIDModel.objects.filter(uid=uid, status=2).update(status=0, mac='', update_time=now_time)
                 uid_serial.delete()
 
                 # 记录操作日志
@@ -627,7 +631,7 @@ class SerialNumberView(View):
             elif company_serial.status == 3:  # 已占用
                 sync_success = self.sync_serial_data_and_log(request, company_serial.id, serial_number, now_time)
                 if not sync_success:
-                    return response.json(10042)
+                    return response.json(10044)
                 return response.json(0, self.get_uid_info_by_serial(company_serial.id))
         except Exception as e:
             error_logger = logging.getLogger('django')

+ 64 - 23
Controller/ShadowController.py

@@ -3,12 +3,12 @@ import time
 
 from django.http import JsonResponse
 
-from Ansjer.config import SERVER_TYPE, LOGGER
-from Model.models import Device_Info, UidSetModel, UID_Preview, VoicePromptModel, UID_Bucket, UidChannelSetModel, \
+from Ansjer.config import SERVER_TYPE, LOGGER, CONFIG_INFO, CONFIG_CN
+from Model.models import Device_Info, UidSetModel, UID_Preview, VoicePromptModel, UidChannelSetModel, \
     AiService, CountryModel, CityInformation, IPAddr
 from Object.ETkObject import ETkObject
 from Service.CommonService import CommonService
-from Object.IPWeatherObject import IPQuery
+from Object.IPWeatherObject import IPQuery, GeoIP2
 
 
 # 更新设备影子
@@ -66,17 +66,8 @@ def update_device_shadow(request):
             AiService.objects.filter(uid=uid, use_status=1).update(detect_status=0, detect_group='')
             LOGGER.info('{}v2重置成功'.format(uid))
 
-            # 和新ip的city_id不一致,更新tb_city_information_id
-            uid_set_qs = UidSetModel.objects.filter(uid=uid).values('ip', 'tb_city_information_id')
-            if uid_set_qs.exists():
-                # 查询ip区级信息
-                district = get_district(ip)
-
-                city_information_qs = CityInformation.objects.filter(district=district).values('city_id')
-                if city_information_qs.exists():
-                    city_id = city_information_qs[0]['city_id']
-                    if uid_set_qs[0]['tb_city_information_id'] != city_id:
-                        uid_set_qs.update(tb_city_information_id=city_id)
+            # 更新ip信息
+            update_ip_info(ip, uid)
 
         ucode = request_dict.get('ucode', None)
         version = request_dict.get('version', None)
@@ -144,13 +135,7 @@ def update_device_shadow(request):
             qs_dict['tb_country'] = country
         LOGGER.info('{} qs_dict: {}'.format(uid, qs_dict))
 
-        # 查询ip区级信息
-        district = get_district(ip)
-
-        city_information_qs = CityInformation.objects.filter(district=district).values('city_id')
-        if city_information_qs.exists():
-            city_id = city_information_qs[0]['city_id']
-            qs_dict['tb_city_information_id'] = city_id
+        save_ip_info(ip, qs_dict)
 
         us_qs = UidSetModel.objects.filter(uid=uid)
         if us_qs.exists():
@@ -171,12 +156,68 @@ def update_device_shadow(request):
         return JsonResponse(status=200, data={'code': 1000001, 'update_shadow_error': repr(e)})
 
 
+def save_ip_info(ip, qs_dict):
+    """
+    保存ip信息
+    根据服务器配置使用不同的服务, 国内:阿里云, 测试,国外:geoip2
+    @param ip:
+    @param qs_dict:
+    @return:
+    """
+    if CONFIG_INFO == CONFIG_CN:
+        # 查询ip区级信息
+        district = get_district(ip)
+
+        city_information_qs = CityInformation.objects.filter(district=district).values('city_id')
+        if city_information_qs.exists():
+            city_id = city_information_qs[0]['city_id']
+            qs_dict['tb_city_information_id'] = city_id
+    else:
+        ip_addr_qs = IPAddr.objects.filter(ip=ip, is_geoip2=True)
+        if not ip_addr_qs.exists():
+            GeoIP2(ip)
+
+
+def update_ip_info(ip, uid):
+    """
+    更新ip信息
+    根据服务器配置使用不同的服务, 国内:阿里云, 测试,国外:geoip2
+    @param ip:
+    @param uid:
+    @return:
+    """
+    if CONFIG_INFO == CONFIG_CN:
+        # 和新ip的city_id不一致,更新tb_city_information_id
+        uid_set_qs = UidSetModel.objects.filter(uid=uid).values('ip', 'tb_city_information_id')
+        if uid_set_qs.exists():
+            # 查询ip区级信息
+            district = get_district(ip)
+
+            city_information_qs = CityInformation.objects.filter(district=district).values('city_id')
+            if city_information_qs.exists():
+                city_id = city_information_qs[0]['city_id']
+                if uid_set_qs[0]['tb_city_information_id'] != city_id:
+                    uid_set_qs.update(tb_city_information_id=city_id)
+    else:
+        ip_addr_qs = IPAddr.objects.filter(ip=ip, is_geoip2=True)
+        if not ip_addr_qs.exists():
+            GeoIP2(ip)
+
+
 def get_district(ip):
-    ip_addr_qs = IPAddr.objects.filter(ip=ip).values('district', 'city')
+    ip_addr_qs = IPAddr.objects.filter(ip=ip, is_geoip2=False).values('district', 'city')
     if ip_addr_qs.exists():
         district = ip_addr_qs[0]['district']
+        city = ip_addr_qs[0]['city']
+        # 区级信息为空或city_information表查询不到区级信息,使用城市数据
         if district == '':
-            district = ip_addr_qs[0]['city']
+            district = city
+        else:
+            city_information_qs = CityInformation.objects.filter(district=district)
+            if not city_information_qs.exists():
+                city_qs = CityInformation.objects.filter(district=city)
+                if city_qs.exists():
+                    district = city
     else:
         ip_qs = IPQuery(ip)
         district = ip_qs.district

+ 12 - 5
Controller/SysMsg.py

@@ -12,6 +12,7 @@
 @Contact: chanjunkai@163.com
 """
 import time
+import re
 
 from django.views.generic.base import View
 
@@ -133,7 +134,7 @@ class SysMsgView(View):
                         SysMsgModel.objects.create(**create_data)
                         fb_qs.update(status=1)
                     except Exception as e:
-                        return response.json(500, repr(e))
+                        return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
                     else:
                         return response.json(0, {'status': 1, 'updTime': nowTime})
                 else:
@@ -154,7 +155,8 @@ class SysMsgView(View):
         try:
             # 如果没有系统消息,周视ios用户暂时生成消息并返回
             if not sm_qs.exists():
-                user_ex_qs = UserExModel.objects.filter(userID_id=userID, appBundleId='com.ansjer.zccloud').values('region')
+                user_ex_qs = UserExModel.objects.filter(userID_id=userID, appBundleId='com.ansjer.zccloud').values(
+                    'region')
                 if not user_ex_qs.exists():
                     return response.json(0, [])
                 now_time = int(time.time())
@@ -182,14 +184,19 @@ class SysMsgView(View):
 
             count = sm_qs.count()
             sm_qs = sm_qs[(page - 1) * line:page * line]. \
-                values('status', 'id', 'msg', 'addTime', 'updTime', 'uid', 'eventType')
+                values('status', 'id', 'msg', 'addTime', 'updTime', 'uid', 'eventType', 'title', 'jumpLink')
             data_res = []
             uid_list = []
 
             for sm_q in sm_qs:
-                sm_q['jumpLink'] = ''
                 if sm_q['eventType'] > 0:
                     uid_list.append(sm_q['uid'])
+                if sm_q['eventType'] == 2:
+                    msg = sm_q['msg']
+                    number_list = re.findall('\d+', msg)
+                    for number in number_list:
+                        if len(number) == 6:
+                            sm_q['code'] = number
                 data_res.append(sm_q)
             if uid_list:
                 uid_set_qs = UidSetModel.objects.filter(uid__in=uid_list).values('uid', 'nickname')
@@ -201,7 +208,7 @@ class SysMsgView(View):
                     data_res.append(sm_q)
             return response.json(0, {'data': data_res, 'count': count})
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def do_query_by_admin(self, userID, request_dict, response):
         own_perm = ModelService.check_perm(userID, 30)

+ 39 - 29
Controller/TestApi.py

@@ -986,56 +986,66 @@ class testView(View):
             if not serial_number:
                 return response.json(0)
             results_data = []
-            if not CONFIG_INFO == 'cn':
+            if not CONFIG_INFO == "cn":
                 return response.json(0, results_data)
             local_response = cls.getSerialNumberInfo(request_dict, response)
             res = json.loads(local_response.content)
-            res['result']['server'] = 1
-            res['result']['serverName'] = '中国服'
-            res['result']['domainName'] = 'https://www.zositechc.cn'
-            results_data.append(res['result'])
-            res1 = requests.post("http://www.dvema.com/testApi/getSerialNumberInfo",
-                                 data={'serialNumber': serial_number}, timeout=15)
+            res["result"]["server"] = 1
+            res["result"]["serverName"] = "中国服"
+            res["result"]["domainName"] = "https://www.zositechc.cn"
+            results_data.append(res["result"])
+
+            res1 = requests.post("https://www.dvema.com/testApi/getSerialNumberInfo",
+                                 data={"serialNumber": serial_number}, timeout=15)
             results1 = json.loads(res1.text)
-            results1['result']['server'] = 2
-            results1['result']['serverName'] = '美国服'
-            results1['result']['domainName'] = 'https://www.dvema.com'
-            results_data.append(results1['result'])
+            results1["result"]["server"] = 2
+            results1["result"]["serverName"] = "美国服"
+            results1["result"]["domainName"] = "https://www.dvema.com"
+            results_data.append(results1["result"])
+
             res2 = requests.post("https://api.zositeche.com/testApi/getSerialNumberInfo",
                                  data={'serialNumber': serial_number}, timeout=15)
             results2 = json.loads(res2.text)
             results2['result']['server'] = 3
-            results2['result']['serverName'] = '欧洲服'
-            results2['result']['domainName'] = 'https://api.zositeche.com'
+            results2["result"]["serverName"] = "欧洲服"
+            results2["result"]["domainName"] = "https://api.zositeche.com"
             results_data.append(results2['result'])
+
+            res3 = requests.post("https://test.zositechc.cn/testApi/getSerialNumberInfo",
+                                 data={'serialNumber': serial_number}, timeout=15)
+            results3 = json.loads(res3.text)
+            results3['result']['server'] = 4
+            results3["result"]["serverName"] = "测试服"
+            results3["result"]["domainName"] = "https://test.zositeche.cn"
+            results_data.append(results3['result'])
+
             is_ok = True
-            operation = ''
-            status_log = ''
+            operation = ""
+            status_log = ""
             for item in results_data:
-                if item['status'] == '绑定uid':
+                if item["status"] == "绑定uid":
                     is_ok = False
-                    operation = '{}序列号已绑定UID'.format(serial_number)
-                    LOGGER.info('序列号检测状态已绑定:{}'.format(serial_number))
+                    operation = "检测{}序列号已绑定UID".format(serial_number)
+                    LOGGER.info("序列号检测状态已绑定:{}".format(serial_number))
                     break
-                elif item['status'] == '已占用':
-                    status_log = '序列号检测状态已占用:{}'.format(serial_number)
+                elif item["status"] == "已占用":
+                    status_log = "序列号检测状态已占用:{}".format(serial_number)
             if is_ok:
                 LOGGER.info(status_log)
-                LOGGER.info('序列号检测状态正常{}'.format(serial_number))
+                LOGGER.info("序列号检测状态正常{}".format(serial_number))
                 return response.json(0, results_data)
             log = {
-                'ip': CommonService.get_ip_address(request),
-                'user_id': 1,
-                'status': 200,
-                'time': int(time.time()),
-                'operation': operation,
-                'url': 'testApi/get-serial-details',
+                "ip": CommonService.get_ip_address(request),
+                "user_id": 1,
+                "status": 200,
+                "time": int(time.time()),
+                "operation": operation,
+                "url": "testApi/get-serial-details",
             }
             LogModel.objects.create(**log)
             return response.json(0, results_data)
         except Exception as e:
-            LOGGER.info('扫码检测序列号异常详情,errLine:{}, errMsg:{}'
-                        .format(e.__traceback__.tb_lineno, repr(e)))
+            LOGGER.info("异常详情,errLine:{}, errMsg:{}".format(e.__traceback__.tb_lineno, repr(e)))
             return response.json(500)
 
     @staticmethod

+ 70 - 3
Controller/UnicomCombo/UnicomComboController.py

@@ -21,7 +21,7 @@ from django.views.generic.base import View
 from Ansjer.config import LOGGER
 from Model.models import UnicomDeviceInfo, UnicomCombo, Pay_Type, Order_Model, Store_Meal, AiStoreMeal, \
     UnicomComboOrderInfo, UnicomComboExperienceHistory, UnicomDeviceStatusChangePush, SysMsgModel, LogModel, \
-    DeviceLiveRestrict
+    DeviceLiveRestrict, OrderPayLog
 from Object.EIoTClubObject import EIoTClubObject
 from Object.Enums.WXOperatorEnum import WXOperatorEnum
 from Object.RedisObject import RedisObject
@@ -202,7 +202,7 @@ class UnicomComboView(View):
                     return False
                 c_time = combo_order_qs[0].created_time
                 # 根据序列号获取UID
-                uid = CommonService.query_uid_with_serial(serial_no)
+                uid = CommonService.get_uid_by_serial_number(serial_no)
                 order_id = CommonService.createOrderID()
                 rank_id, ai_rank_id = cls.get_cloud_or_ai_combo()  # 生成订单必须添加该字段
                 order_dict = {'orderID': order_id, 'UID': uid, 'rank_id': rank_id, 'ai_rank_id': ai_rank_id,
@@ -613,7 +613,7 @@ class UnicomComboView(View):
                 if not price:
                     return response.json(173)
                 unicom_device_qs = unicom_device_qs.first()
-                device_uid = CommonService.query_uid_with_serial(unicom_device_qs['serial_no'])
+                device_uid = CommonService.get_uid_by_serial_number(unicom_device_qs['serial_no'])
                 order_id = CommonService.createOrderID()
                 rank_id, ai_rank_id = cls.get_cloud_or_ai_combo()
 
@@ -627,6 +627,8 @@ class UnicomComboView(View):
 
                 params = 'lang=cn' + '&activateType=' + activate_type
                 logger.info('激活类型:{}'.format(activate_type))
+                serial_number = unicom_device_qs['serial_no']
+
                 result = {'result_code': 0, 'reason': 'success', 'error_code': 0}
                 if pay_type == 2:  # 支付宝
                     pay_price = PayService.get_two_float(price, 2)
@@ -637,6 +639,7 @@ class UnicomComboView(View):
                                                                              notify_url,
                                                                              unicom_combo_qs['remark'], response)
                     res_data = {'redirectUrl': order_dict['pay_url'], 'orderID': order_id}
+                    cls.create_order_pay_log(order_id, f'{serial_number}购买联通4G套餐', notify_url, 'aliPay', 'SUCCESS')
                 elif pay_type == 3:  # 微信支付
                     notify_url = 'unicom/wap/pay/wechat-notify'
                     ip = CommonService.get_ip_address(request)
@@ -647,6 +650,7 @@ class UnicomComboView(View):
                                                                    unicom_combo_qs['remark'],
                                                                    response)
                     result['result'] = sign_params
+                    cls.create_order_pay_log(order_id, f'{serial_number}购买联通4G套餐', notify_url, 'wechatPay', 'SUCCESS')
                 else:
                     return response.json(444, {'param': 'pay_type'})
 
@@ -1140,3 +1144,66 @@ class UnicomComboView(View):
                 '{}update_flow_package_order_by_iccid,errLine:{}, errMsg:{}'.format(iccid, e.__traceback__.tb_lineno,
                                                                                     repr(e)))
             return False
+
+    @staticmethod
+    def create_order_pay_log(order_id, business_name, api_url, sender, access_result):
+        """
+        订单支付日志
+        @param order_id: 订单ID
+        @param business_name: 业务名称
+        @param api_url: 回调api地址
+        @param sender: 发送方/调用方
+        @param access_result: 获取支付请求结果
+        @return: True | False
+        """
+        try:
+            LOGGER.info(f'***创建订单支付日志order_id={order_id}')
+            now_time = int(time.time())
+            params = {
+                'order_id': order_id,
+                'business_name': business_name,
+                'api_url': api_url, 'sender': sender, 'access_result': access_result, 'created_time': now_time,
+                'updated_time': now_time,
+            }
+            OrderPayLog.objects.create(**params)
+            return True
+        except Exception as e:
+            LOGGER.info('{}create_order_pay_log,errLine:{}, errMsg:{}'.
+                        format(order_id, e.__traceback__.tb_lineno, repr(e)))
+            return False
+
+    @staticmethod
+    def save_order_pay_log(order_id, trade_no, api_url, sender, access_result, response_content):
+        """
+        保存订单支付日志
+        @param order_id: 订单ID
+        @param trade_no: 交易流水号
+        @param api_url: 异步回调API
+        @param sender: 发送方/调用方
+        @param access_result: 调用结果
+        @param response_content: 响应内容
+        @return: True | False
+        """
+        try:
+            LOGGER.info(f'***保存支付回调记录order_id={order_id},流水号={trade_no}')
+            now_time = int(time.time())
+            params = {
+                'access_result': access_result,
+                'updated_time': now_time,
+                'trans_serial_no': trade_no,
+                'response_content': response_content
+            }
+            pay_log_qs = OrderPayLog.objects.filter(order_id=order_id)
+            if pay_log_qs.exists():
+                pay_log_qs.update(**params)
+                return True
+            params['order_id'] = order_id
+            params['api_url'] = api_url
+            params['sender'] = sender
+            params['created_time'] = now_time
+            OrderPayLog.objects.create(**params)
+            return True
+        except Exception as e:
+            LOGGER.info('{}save_order_pay_log,errLine:{}, errMsg:{}'.
+                        format(order_id, e.__traceback__.tb_lineno, repr(e)))
+            return False

+ 10 - 2
Controller/UnicomCombo/UnicomComboPayNotifyController.py

@@ -60,7 +60,7 @@ class UnicomComboPayNotifyView(View):
             passback_params = re_data['passback_params']
             params = dict([(k, v[0]) for k, v in parse_qs(unquote(passback_params)).items()])
             activate_type = int(params['activateType'])
-            logger.info('支付宝异步回调参数:{},携带参数{}', re_data, params)
+            logger.info('支付宝异步回调参数:{},携带参数{}'.format(re_data, params))
             signature = re_data['sign']
             re_data.pop('sign')
             order_id = re_data['out_trade_no']
@@ -74,6 +74,8 @@ class UnicomComboPayNotifyView(View):
 
             order_qs = Order_Model.objects.filter(orderID=order_id)
             if not order_qs.exists():
+                UnicomComboView().save_order_pay_log(order_id, re_data["trade_no"],
+                                                     'unicom/wap/pay/wechat-notify', 'aliPay', 'FAILED', re_data)
                 logger.info('系统订单不存在:{}'.format(order_id))
                 return HttpResponse('fail')
             order_qs = order_qs.filter(status=0)
@@ -86,6 +88,9 @@ class UnicomComboPayNotifyView(View):
             success = alipay.verify(re_data, signature)
             if not success or re_data["trade_status"] not in ("TRADE_SUCCESS", "TRADE_FINISHED"):
                 return HttpResponse('fail')
+
+            UnicomComboView().save_order_pay_log(order_id, re_data["trade_no"],
+                                                 'unicom/wap/pay/wechat-notify', 'aliPay', 'SUCCESS', re_data)
             return cls.order_pay_notify(order_id, re_data["trade_no"], activate_type, notify_key.format(order_id),
                                         order_qs, redisObj)
         except Exception as e:
@@ -117,6 +122,8 @@ class UnicomComboPayNotifyView(View):
             order_id = re_data['out_trade_no']  # 商户订单号
             order_qs = Order_Model.objects.filter(orderID=order_id)
             if not order_qs.exists():
+                UnicomComboView().save_order_pay_log(order_id, re_data["transaction_id"],
+                                                     'unicom/wap/pay/ali-notify', 'wechatPay', 'FAILED', re_data)
                 return HttpResponse(pay.xml_to_dict({'return_code': 'FAIL'}))
             order_qs = order_qs.filter(status=0)
             if not order_qs.exists():
@@ -138,7 +145,8 @@ class UnicomComboPayNotifyView(View):
             redisObj.CONN.expire(notify_key.format(order_id), 60)
             if not isLock:
                 return HttpResponse(pay.xml_to_dict({'return_code': 'FAIL'}))
-
+            UnicomComboView().save_order_pay_log(order_id, re_data["transaction_id"],
+                                                 'unicom/wap/pay/ali-notify', 'wechatPay', 'SUCCESS', re_data)
             return cls.order_pay_notify(order_id, re_data["transaction_id"], activate_type, notify_key.format(order_id),
                                         order_qs,
                                         redisObj, True)

+ 2 - 2
Controller/UnicomCombo/WXTechController.py

@@ -84,7 +84,7 @@ class WXTechControllerView(View):
             device_qs = UnicomDeviceInfo.objects.filter(serial_no=serial_number).values('iccid')
             if not device_qs.exists():
                 return response(173)
-            uid = CommonService.query_uid_with_serial(serial_number)
+            uid = CommonService.get_uid_by_serial_number(serial_number)
             order_info_qs = Order_Model.objects.filter(UID=uid, order_type=3).values('trade_no') \
                 .order_by('-payTime')
             if not order_info_qs.exists():
@@ -232,7 +232,7 @@ class WXTechControllerView(View):
         combo_info_vo = combo_info_qs[0]
         n_time = int(time.time())
         # 根据序列号获取UID
-        uid = CommonService.query_uid_with_serial(serial_no)
+        uid = CommonService.get_uid_by_serial_number(serial_no)
         order_id = CommonService.createOrderID()
         # 生成订单必须添加该字段
         rank_id, ai_rank_id = UnicomComboView().get_cloud_or_ai_combo()

+ 2 - 2
Controller/UserController.py

@@ -857,7 +857,7 @@ class v2authCodeView(TemplateView):
         identifyingCode = reds.get_data(key=email + '_identifyingCode')
         # 是否以获取邮箱验证码
         if identifyingCode:
-            return response.json(89)
+            return response.json(0)
         user_qs = Device_User.objects.filter(username=email)
         email_qs = Device_User.objects.filter(userEmail=email)
         # 邮箱用户是否已存在
@@ -878,7 +878,7 @@ class v2authCodeView(TemplateView):
         )
         if send_res is not True:
             return response.json(44)
-        if reds.set_data(key=email + '_identifyingCode', val=identifyingCode, expire=600) is not True:
+        if reds.set_data(key=email + '_identifyingCode', val=identifyingCode, expire=60) is not True:
             return response.json(10, 'error')
         return response.json(0)
 

+ 1 - 1
Controller/VoicePromptController.py

@@ -225,7 +225,7 @@ class VoicePromptView(View):
             res['system'] = {}
             res['custom'] = {}
             auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
-            bucket = oss2.Bucket(auth, 'oss-cn-shenzhen.aliyuncs.com', 'ansjer-static-resources')
+            bucket = oss2.Bucket(auth, 'https://oss-cn-shenzhen.aliyuncs.com', 'ansjer-static-resources')
             if system_qs.exists():
                 system_qs = system_qs.values('id', 'title', 'filename', 'type')
                 for system in system_qs:

+ 38 - 25
Controller/WeatherControl.py

@@ -6,12 +6,10 @@
 """
 import datetime
 
-from Ansjer.config import LOGGER
-import time
-
+from Ansjer.config import CONFIG_INFO, CONFIG_CN
 from django.views import View
-from Object.IPWeatherObject import WeatherInfo
-from Model.models import UidSetModel, CityInformation
+from Object.IPWeatherObject import WeatherInfo, OpenWeatherMap
+from Model.models import UidSetModel, IPAddr
 from Object.ResponseObject import ResponseObject
 from Object.RedisObject import RedisObject
 from Service.CommonService import CommonService
@@ -21,14 +19,14 @@ class WeatherView(View):
     def get(self, request, *args, **kwargs):
         request.encoding = 'utf-8'
         operation = kwargs.get('operation')
-        return self.validation(request.GET, operation, request)
+        return self.validation(request.GET, operation)
 
     def post(self, request, *args, **kwargs):
         request.encoding = 'utf-8'
         operation = kwargs.get('operation')
-        return self.validation(request.POST, operation, request)
+        return self.validation(request.POST, operation)
 
-    def validation(self, request_dict, operation, request):
+    def validation(self, request_dict, operation):
         lang = request_dict.get('lang', 'en')
         response = ResponseObject(lang)
         if operation == 'get':  # 获取天气
@@ -48,27 +46,42 @@ class WeatherView(View):
         uid = request_dict.get('uid')
         if not uid:
             return response.json(444, 'uid')
-        uid_set_qs = UidSetModel.objects.filter(uid=uid).values('tb_city_information_id')
+
+        uid_set_qs = UidSetModel.objects.filter(uid=uid).values('tb_city_information_id', 'ip')
         if not uid_set_qs.exists():
             return response.json(173)
-        redis_obj = RedisObject()
-        city_id = uid_set_qs[0]['tb_city_information_id']
-        if city_id == 0:
-            return response.json(10, '请更新设备影子地区信息')
-        today = datetime.datetime.today()
-        now_time = datetime.datetime(today.year, today.month, today.day, today.hour)
-        time_stamp = CommonService.str_to_timestamp(now_time.strftime('%Y-%m-%d %H:%M:%S'))
+
         try:
-            weather = redis_obj.get_data('city_id_{}_{}_weather'.format(city_id, time_stamp))
-            if weather:
-                temp, humidity = weather.split('/')
+            # 根据服务器配置使用不同的服务, 国内:阿里云墨迹天气, 测试,国外:OpenWeatherMap
+            if CONFIG_INFO == CONFIG_CN:
+                city_id = uid_set_qs[0]['tb_city_information_id']
+                if city_id == 0:
+                    return response.json(10, '请更新设备影子地区信息')
+
+                today = datetime.datetime.today()
+                now_time = datetime.datetime(today.year, today.month, today.day, today.hour)
+                time_stamp = CommonService.str_to_timestamp(now_time.strftime('%Y-%m-%d %H:%M:%S'))
+                key = 'city_id_{}_{}_weather'.format(city_id, time_stamp)
+
+                redis_obj = RedisObject()
+                weather = redis_obj.get_data(key)
+                if weather:
+                    temp, humidity = weather.split('/')
+                else:
+                    city_obj = WeatherInfo(city_id)
+                    temp, humidity = city_obj.get_city_weather()
+                    if temp and humidity:
+                        redis_obj.set_ex_data(key, '{}/{}'.format(temp, humidity), 3600)
             else:
-                city_obj = WeatherInfo(city_id)
-                temp, humidity = city_obj.get_city_weather()
-                if temp and humidity:
-                    redis_obj.set_ex_data('city_id_{}_{}_weather'.format(city_id, time_stamp),
-                                          '{}/{}'.format(temp, humidity), 3600)
-            if not all([temp, humidity]):
+                ip = uid_set_qs[0]['ip']
+                ip_addr_qs = IPAddr.objects.filter(ip=ip, is_geoip2=True).values('lat', 'lon')
+                if not ip_addr_qs.exists():
+                    return response.json(173)
+                lat, lon = ip_addr_qs[0]['lat'], ip_addr_qs[0]['lon']
+                open_weather_map = OpenWeatherMap(lat, lon)
+                temp, humidity = open_weather_map.get_weather()
+
+            if temp is None and humidity is None:
                 return response.json(10, '获取天气失败')
             return response.json(0, {'temp': temp, 'humidity': humidity})
         except Exception as e:

+ 62 - 3
Model/models.py

@@ -1905,11 +1905,14 @@ class UID_Preview(models.Model):
 class SysMsgModel(models.Model):
     id = models.AutoField(primary_key=True, verbose_name='自增id')
     userID_id = models.CharField(default='', db_index=True, blank=True, max_length=32, verbose_name=u'用户ID')
-    msg = models.TextField(blank=True, default='', verbose_name=u'发送内容')
+    title = models.CharField(default='', max_length=64, verbose_name='标题')
+    msg = models.TextField(blank=True, default='', verbose_name='发送内容')
     status = models.SmallIntegerField(verbose_name='是否已读', default=0)  # 0:否,1:是
     addTime = models.IntegerField(verbose_name='添加时间', default=0)
     updTime = models.IntegerField(verbose_name='更新时间', default=0)
-    eventType = models.IntegerField(verbose_name='消息类型', default=0)  # 默认系统消息类型,0系统消息,1 ipcamera消息,2 超级密码
+    # 消息类型, 0:系统通知, 702:休眠, 704:低电量
+    eventType = models.IntegerField(verbose_name='消息类型', default=0)
+    jumpLink = models.TextField(default='', verbose_name='跳转链接')
     uid = models.CharField(default='', max_length=20, db_index=True, verbose_name='设备UID')
 
     class Meta:
@@ -2635,7 +2638,7 @@ class UIDModel(models.Model):
     uid = models.CharField(max_length=20, null=False, db_index=True, unique=True, verbose_name='设备id')
     mac = models.CharField(max_length=17, null=True, default='', verbose_name='设备id对应的mac地址')
     uid_extra = models.TextField(default='', verbose_name='uid的额外描述')
-    status = models.SmallIntegerField(default=0, verbose_name='使用状态')  # 0:未使用, 2:已使用
+    status = models.SmallIntegerField(default=0, verbose_name='使用状态')  # 0:未使用, 2:已使用, 3:数据被同步
     add_time = models.IntegerField(default=0, verbose_name='添加时间')
     update_time = models.IntegerField(default=0, verbose_name='更新时间')
     area = models.SmallIntegerField(default=0, verbose_name='区域')  # 0:国内, 1:国外
@@ -4246,12 +4249,25 @@ class IPAddr(models.Model):
     city = models.CharField(default='', max_length=32, verbose_name='市')
     region = models.CharField(default='', max_length=32, verbose_name='省/州')
     country_code = models.CharField(default='', max_length=8, verbose_name='国家编码')
+    lat = models.FloatField(default=0, verbose_name='经度')
+    lon = models.FloatField(default=0, verbose_name='纬度')
+    is_geoip2 = models.BooleanField(default=False, verbose_name='是否为geoip2解析')
 
     class Meta:
         db_table = 'ip_addr'
         verbose_name = 'ip地址信息'
 
 
+class OpenWeatherMapCallCount(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name='主键')
+    month = models.CharField(default='', max_length=20, verbose_name='月份')
+    count = models.IntegerField(default=1, verbose_name='api调用次数')
+
+    class Meta:
+        db_table = 'open_weather_map_call_count'
+        verbose_name = 'OpenWeatherMap调用次数'
+
+
 class DeviceLiveRestrict(models.Model):
     id = models.AutoField(primary_key=True, verbose_name='主键')
     device_type = models.IntegerField(default=0, verbose_name='设备类型id')
@@ -4283,6 +4299,28 @@ class SerialNumberPackage(models.Model):
         verbose_name_plural = verbose_name
 
 
+class CustomizedPush(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name='主键')
+    title = models.CharField(default='', max_length=64, verbose_name='标题')
+    msg = models.TextField(default='', verbose_name='内容')
+    link = models.TextField(default='', verbose_name='链接')
+    icon_link = models.TextField(default='', verbose_name='预览图链接')
+    country = models.CharField(default='', max_length=32, verbose_name='国家')
+    # 多选型号用,分开
+    device_type = models.TextField(default='', verbose_name='设备类型')
+    register_period = models.CharField(default='', max_length=32, verbose_name='注册年限')
+    time_zone = models.CharField(default='', max_length=8, verbose_name='时区')
+    push_time = models.CharField(default='', max_length=32, verbose_name='推送时间')
+    push_timestamp = models.IntegerField(default=0, verbose_name='推送时间戳')
+    push_app = models.CharField(default='', max_length=64, verbose_name='推送APP')
+    # False:待推送, True:已推送
+    push_satus = models.BooleanField(default=False, verbose_name='推送状态')
+
+    class Meta:
+        db_table = 'customized_push'
+        verbose_name = '定制化推送'
+
+
 class AbnormalOrder(models.Model):
     id = models.AutoField(primary_key=True, verbose_name='主键')
     order_id = models.CharField(max_length=30, db_index=True, verbose_name='订单ID', blank=True, default='')
@@ -4300,3 +4338,24 @@ class AbnormalOrder(models.Model):
     class Meta:
         db_table = 'abnormal_order'
         verbose_name = '异常订单表'
+
+
+class OrderPayLog(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name='主键'),
+    order_id = models.CharField(max_length=30, db_index=True, verbose_name='订单ID', blank=True, default='')
+    order_no = models.CharField(max_length=30, verbose_name='订单号', blank=True, default='')
+    trans_serial_no = models.CharField(max_length=30, verbose_name='流水号', blank=True, default='')
+    business_name = models.CharField(max_length=30, verbose_name='业务名称', blank=True, default='')
+    sender = models.CharField(max_length=30, verbose_name='发送方/调用方', blank=True, default='')
+    api_url = models.CharField(max_length=64, verbose_name='接口地址', blank=True, default='')
+    request_content = models.JSONField(null=True, verbose_name='请求内容')
+    response_content = models.JSONField(null=True, verbose_name='响应内容')
+    # SUCCESS, FAILED, EXCEPTION, ERROR
+    response_times = models.BigIntegerField(verbose_name='接收调用耗时,响应时长,单位ms', default=0)
+    access_result = models.CharField(max_length=30, verbose_name='接口调用状态', blank=True, default='')
+    created_time = models.IntegerField(default=0, verbose_name='创建时间')
+    updated_time = models.IntegerField(default=0, verbose_name='修改时间')
+
+    class Meta:
+        db_table = 'order_pay_log'
+        verbose_name = '订单支付日志'

+ 22 - 7
Object/ApschedulerObject.py

@@ -1,7 +1,6 @@
 import time
 from apscheduler.schedulers.background import BackgroundScheduler
 from django_apscheduler.jobstores import DjangoJobStore
-from Ansjer.config import LOGGER
 from django_apscheduler.models import DjangoJob
 import datetime
 
@@ -17,13 +16,29 @@ class ApschedulerObject:
         now_time = time.time()
         print('hello world:[{}]'.format(now_time))
 
-    def cron_job(self, task_id, day_of_week, hour, minute):  # 周期任务
-        self.scheduler.add_job(self.auto_hello, 'cron', day_of_week=day_of_week, hour=hour, minute=minute,
-                               replace_existing=True, id=task_id, max_instances=1, coalesce=True)
+    def create_cron_job(self, func, task_id, day_of_week, hour, minute, args):  # 周期任务
+        job = self.scheduler.add_job(func=func, trigger='cron', day_of_week=day_of_week, hour=hour, minute=minute,
+                                     replace_existing=True, id=task_id, max_instances=1, coalesce=False, args=args,
+                                     misfire_grace_time=300)
+        print(job)
 
-    def date_job(self, task_id, time_stamp):  # 时间点任务
-        self.scheduler.add_job(self.auto_hello, 'date', run_date=datetime.datetime.fromtimestamp(time_stamp),
-                               replace_existing=True, id=task_id, max_instances=1, coalesce=True)
+    def create_interval_job(self, func, task_id, minutes, start_time, end_time, args):  # 间隔任务
+        self.scheduler.add_job(func=func, trigger='interval', minutes=minutes,
+                               start_date=datetime.datetime.fromtimestamp(start_time),
+                               end_date=datetime.datetime.fromtimestamp(end_time),
+                               replace_existing=True, id=task_id, max_instances=1, coalesce=False, args=args)
+
+    def create_date_job(self, func, task_id, time_stamp, args):
+        """
+        创建时间点任务
+        @param func:
+        @param task_id:
+        @param time_stamp:
+        @param args:
+        @return:
+        """
+        self.scheduler.add_job(func=func, trigger='date', run_date=datetime.datetime.fromtimestamp(time_stamp),
+                               replace_existing=True, id=task_id, max_instances=1, coalesce=False, args=args)
 
     @staticmethod
     def del_job(task_id):  # 删除任务

+ 137 - 2
Object/IPWeatherObject.py

@@ -1,9 +1,15 @@
 # @Author    : Rocky
 # @File      : IPWeatherObject.py
 # @Time      : 2023/8/16 8:56
+import datetime
+
+import geoip2.webservice
 import requests
 
-from Model.models import IPAddr
+from Model.models import IPAddr, OpenWeatherMapCallCount
+from Object.RedisObject import RedisObject
+from Service.CommonService import CommonService
+from Ansjer.config import LOGGER
 
 
 class IPQuery:
@@ -42,7 +48,7 @@ class IPQuery:
                     city += '市'
 
                 # ip地址信息存表或更新
-                ip_addr_qs = IPAddr.objects.filter(ip=ip)
+                ip_addr_qs = IPAddr.objects.filter(ip=ip, is_geoip2=False)
                 if ip_addr_qs.exists():
                     ip_addr_qs.update(district=district, city=city, region=region, country_code=country_id)
                 else:
@@ -58,6 +64,10 @@ class IPQuery:
 
 
 class WeatherInfo:
+    """
+    阿里云墨迹天气服务
+    https://market.aliyun.com/products/57096001/cmapi013828.html?spm=5176.2020520132.101.19.2b8f7218NuiGPd#sku=yuncode782800000
+    """
     def __init__(self, city_id):
         self.appcode = 'd7d63b34b1d54214be446608a57ff0a2'
         self.headers = {'Authorization': 'APPCODE ' + self.appcode,
@@ -85,3 +95,128 @@ class WeatherInfo:
                 # 返回天气列表
                 return result['data']['hourly']
         return None
+
+
+class GeoIP2:
+    """
+    MaxMind GeoIP2查询国外ip
+    同时保存ip信息
+    https://www.maxmind.com/
+    """
+
+    def __init__(self, ip):
+        self.account_id = 938644
+        self.license_key = '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'
+        self.license_key_sandbox = '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'
+
+        try:
+            with geoip2.webservice.Client(self.account_id, self.license_key) as client:
+                # You can also use `client.city` or `client.insights`
+                # `client.insights` is not available to GeoLite2 users
+                response = client.city(ip)
+
+                # 经纬度精确到小数点两位
+                lat = round(response.location.latitude, 2)
+                lon = round(response.location.longitude, 2)
+
+                # 获取中文或英文城市名,省/州
+                city = ''
+                city_names = response.city.names
+                city_cn = city_names.get('zh-CN')
+                if city_cn:
+                    city = city_cn
+                elif city_names.get('en'):
+                    city = city_names['en']
+
+                region = ''
+                subdivisions_names = response.subdivisions[0].names
+                region_cn = subdivisions_names.get('zh-CN')
+                if region_cn:
+                    region = region_cn
+                elif subdivisions_names.get('en'):
+                    region = subdivisions_names['en']
+
+                country_code = response.country.iso_code
+
+                # 保存ip信息
+                ip_addr_data = {
+                    'ip': ip,
+                    'lat': lat,
+                    'lon': lon,
+                    'city': city,
+                    'region': region,
+                    'country_code': country_code,
+                    'is_geoip2': True
+                }
+                IPAddr.objects.create(**ip_addr_data)
+
+        except Exception as e:
+            LOGGER.info('GeoIP2解析ip异常:error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
+
+class OpenWeatherMap:
+    """
+    OpenWeatherMap查询国外天气服务
+    https://openweathermap.org/
+    """
+
+    def __init__(self, lat, lon):
+        self.appid = '7a6cd7dfeb034ededa451ed575788857'
+        self.lat = lat  # 纬度
+        self.lon = lon  # 经度
+
+    def get_weather(self):
+        """
+        从缓存查询天气数据
+        或者查询当前天气,并缓存数据
+        @return: temp, humidity
+        """
+        # 查询缓存数据
+        today = datetime.datetime.today()
+        now_time = datetime.datetime(today.year, today.month, today.day, today.hour)
+        str_time = now_time.strftime('%Y-%m-%d %H:%M:%S')
+        time_stamp = CommonService.str_to_timestamp(str_time)
+        key = 'weather:lat:{}_lon:{}_time_stamp:{}'.format(self.lat, self.lon, time_stamp)
+
+        redis_obj = RedisObject()
+        weather = redis_obj.get_data(key)
+        if weather:
+            temp, humidity = weather.split('/')
+        else:
+            temp, humidity = self.get_current_weather(str_time[:7])
+            if temp is not None and humidity is not None:
+                key = 'weather:lat:{}_lon:{}_time_stamp:{}'.format(self.lat, self.lon, time_stamp)
+                redis_obj.set_ex_data(key, '{}/{}'.format(temp, humidity), 3600)
+        return temp, humidity
+
+    def get_current_weather(self, month):
+        """
+        根据经纬度获取当前天气
+        @param month: 年月份
+        @return: temp, humidity
+        """
+        url = 'https://api.openweathermap.org/data/2.5/weather'
+        params = {
+            'lat': self.lat,
+            'lon': self.lon,
+            'appid': self.appid,
+            'units': 'metric'   # 公制单位,温度单位:摄氏度
+        }
+        res = requests.get(url=url, params=params, timeout=10)
+
+        # 记录调用次数
+        open_weather_map_call_count_qs = OpenWeatherMapCallCount.objects.filter(month=month).values('count')
+        if not open_weather_map_call_count_qs.exists():
+            OpenWeatherMapCallCount.objects.create(month=month)
+        else:
+            count = open_weather_map_call_count_qs[0]['count'] + 1
+            open_weather_map_call_count_qs.update(count=count)
+
+        if res.status_code != 200:
+            return None, None
+        res_data = eval(res.text)
+        if res_data['cod'] != 200:
+            return None, None
+        temp = int(res_data['main']['temp'])
+        humidity = int(res_data['main']['humidity'])
+        return temp, humidity

+ 2 - 0
Object/uidManageResponseObject.py

@@ -63,6 +63,7 @@ class uidManageResponseObject(object):
             10041: '已超出序列号剩余可绑定数',
             10042: '序列号已被占用',
             10043: '无法解绑,序列号的状态为被占用',
+            10044: '请联系客服',
         }
 
         data_en = {
@@ -116,6 +117,7 @@ class uidManageResponseObject(object):
             10041: 'The remaining number of serial numbers that can be bound has exceeded',
             10042: 'Serial number is already occupied',
             10043: 'Unable to unbind, the status of the serial number is occupied',
+            10044: 'Please contact customer service',
         }
 
         msg = data_cn if self.lang == 'cn' else data_en

+ 25 - 2
Service/CommonService.py

@@ -1,13 +1,14 @@
 import base64
+import calendar
 import datetime
-import ipdb
 import time
 from base64 import encodebytes
+from distutils.version import LooseVersion
 from pathlib import Path
 from random import Random
-from distutils.version import LooseVersion
 
 import OpenSSL.crypto as ct
+import ipdb
 import requests
 import simplejson as json
 from dateutil.relativedelta import relativedelta
@@ -786,6 +787,28 @@ GCqvlyw5dfxNA+EtxNE2wCW/LW7ENJlACgcfgPlBZtpLheWoZB/maw4=
                 continue
         return version_list
 
+    @staticmethod
+    def convert_to_timestamp(timezone_offset, time_string):
+        """
+        时间字符串转为时间戳
+        @param timezone_offset: 时区
+        @param time_string: 时间字符串
+        @return: timestamp
+        """
+        datetime_obj = datetime.datetime.strptime(time_string, '%Y-%m-%d %H:%M:%S')
+
+        # 创建一个表示指定时区的timedelta对象
+        utc_offset = datetime.timedelta(hours=timezone_offset)
+
+        # 调整时区
+        datetime_obj = datetime_obj - utc_offset
+
+        # datetime.datetime对象 -> str
+        time_str_utc = datetime_obj.strftime("%Y-%m-%d %H:%M:%S")
+        timestamp = calendar.timegm(time.strptime(time_str_utc, '%Y-%m-%d %H:%M:%S'))
+
+        return timestamp
+
     @staticmethod
     def get_uid_by_serial_number(serial_number):
         """

+ 1 - 72
Service/EquipmentInfoService.py

@@ -8,10 +8,9 @@
 """
 import datetime
 import itertools
-import logging
 import time
 
-from django.db.models import Value, CharField, Q, F
+from django.db.models import Value, CharField, Q
 
 from Model.models import EquipmentInfoMonday, EquipmentInfoTuesday, EquipmentInfoWednesday, EquipmentInfoThursday, \
     EquipmentInfoFriday, EquipmentInfoSaturday, EquipmentInfoSunday, EquipmentInfo1, EquipmentInfo2, EquipmentInfo3, \
@@ -300,36 +299,6 @@ class EquipmentInfoService:
             regroup_list.append(int(val))
         return regroup_list
 
-    @staticmethod
-    def get_equipment_info_obj(dt, **kwargs):
-        """
-        根据日期判断是星期几,返回相应的对象实例
-        @param dt: 日期 例:2022-03-03
-        @param kwargs: 设备信息属性值
-        @return: 星期一至星期天equipment_info对象实例
-        """
-        logger = logging.getLogger('info')
-        week = LocalDateTimeUtil.date_to_week(dt)
-        logger.info('本周{}'.format(str(week)))
-        equipment_info = None
-        if week == 1:
-            equipment_info = EquipmentInfoMonday(**kwargs)
-        elif week == 2:
-            equipment_info = EquipmentInfoTuesday(**kwargs)
-        elif week == 3:
-            equipment_info = EquipmentInfoWednesday(**kwargs)
-        elif week == 4:
-            equipment_info = EquipmentInfoThursday(**kwargs)
-        elif week == 5:
-            equipment_info = EquipmentInfoFriday(**kwargs)
-        elif week == 6:
-            equipment_info = EquipmentInfoSaturday(**kwargs)
-        elif week == 7:
-            equipment_info = EquipmentInfoSunday(**kwargs)
-        logger.info(type(equipment_info))
-        logger.info(equipment_info)
-        return equipment_info
-
     @classmethod
     def get_combo_types(cls, event_type, event_tag):
         """
@@ -470,46 +439,6 @@ class EquipmentInfoService:
         else:
             return ',' + str(event_type) + ','
 
-    @staticmethod
-    def update_equipment_answer_status(user_id, uid, event_time):
-        """
-        更新一键通话消息状态
-        @param user_id: 用户id
-        @param uid: uid
-        @param event_time: 事件时间
-        @return updated_flag: bool
-        """
-        updated_flag = False
-        updated = EquipmentInfoMonday.objects.filter(device_user_id=user_id, device_uid=uid, event_time=event_time,
-                                                     event_type__in=[606, 607]).update(answer_status=1)
-        if updated:
-            updated_flag = True
-        updated = EquipmentInfoTuesday.objects.filter(device_user_id=user_id, device_uid=uid, event_time=event_time,
-                                                      event_type__in=[606, 607]).update(answer_status=1)
-        if updated:
-            updated_flag = True
-        updated = EquipmentInfoWednesday.objects.filter(device_user_id=user_id, device_uid=uid, event_time=event_time,
-                                                        event_type__in=[606, 607]).update(answer_status=1)
-        if updated:
-            updated_flag = True
-        updated = EquipmentInfoThursday.objects.filter(device_user_id=user_id, device_uid=uid, event_time=event_time,
-                                                       event_type__in=[606, 607]).update(answer_status=1)
-        if updated:
-            updated_flag = True
-        updated = EquipmentInfoFriday.objects.filter(device_user_id=user_id, device_uid=uid, event_time=event_time,
-                                                     event_type__in=[606, 607]).update(answer_status=1)
-        if updated:
-            updated_flag = True
-        updated = EquipmentInfoSaturday.objects.filter(device_user_id=user_id, device_uid=uid, event_time=event_time,
-                                                       event_type__in=[606, 607]).update(answer_status=1)
-        if updated:
-            updated_flag = True
-        updated = EquipmentInfoSunday.objects.filter(device_user_id=user_id, device_uid=uid, event_time=event_time,
-                                                     event_type__in=[606, 607]).update(answer_status=1)
-        if updated:
-            updated_flag = True
-        return updated_flag
-
     @classmethod
     def union_equipment_info(cls, user_id, uid_list, event_type, start_time, end_time, page, line):
         """

+ 2 - 2
Service/TemplateService.py

@@ -31,7 +31,7 @@ class TemplateService:
 <div class="content"
      style="overflow: hidden;padding:30px 10% 70px 10%;margin:0 10%;background-color: #fff;box-shadow:0 4px 20px rgba(0,0,0,0.1);word-break: break-all;">
     <h2 style="margin: 30px 0;">Hello, {username}</h2>
-    <p style="margin-bottom: 40px;">请输入验证码完成注册,有效期10分钟:</p>
+    <p style="margin-bottom: 40px;">请输入验证码完成注册,有效期1分钟:</p>
     <span style="padding: 10px 20px; font-size: 24px;background-color: #EB6F5A;border-radius:4px;color:#fff;">{captcha}</span>
 </div>
 </body>
@@ -51,7 +51,7 @@ class TemplateService:
 <div class="content"
      style="overflow: hidden;padding:30px 10% 70px 10%;margin:0 10%;background-color: #fff;box-shadow:0 4px 20px rgba(0,0,0,0.1);word-break: break-all;">
     <h2 style="margin: 30px 0;">Hello, {username}</h2>
-    <p style="margin-bottom: 40px;">Please input code to reg. only valid in 10 minutes!</p>
+    <p style="margin-bottom: 40px;">Please input code to reg. only valid in 1 minutes!</p>
     <span style="padding: 10px 20px; font-size: 24px;background-color: #EB6F5A;border-radius:4px;color:#fff;">{captcha}</span>
 </div>
 </body>

+ 5 - 10
Service/VodHlsService.py

@@ -174,31 +174,26 @@ class SplitVodHlsObject:
         return vod_hls
 
     @classmethod
-    def cloud_vod_hls_tag(cls, vod_id, num, uid, start_time):
+    def cloud_vod_hls_tag(cls, vod_id, num, uid, start_time, sec):
         """
         云存回调信息关联标签
         @param vod_id: 云存回放信息id
-        @param num: 所在表编号
+        @param num: 云存所在表编号
         @param uid: 设备UID
         @param start_time: 云存开始时间
+        @param sec: 云存片段秒数
         @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
+            end_time = start_time + sec
             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)))
+            print('cloud_vod_hls_tag异常详情,uid:{},errLine:{},errMsg:{}'.format(uid, e.__traceback__.tb_lineno, repr(e)))
             return False
 
     @classmethod