Explorar o código

Merge branch 'test' of ssh://192.168.136.99:10022/servers/ASJServer into ghl

 Conflicts:
	Controller/SensorGateway/SmartSceneController.py
guanhailong %!s(int64=3) %!d(string=hai) anos
pai
achega
3890cd0044

+ 205 - 55
Controller/SensorGateway/SmartSceneController.py

@@ -9,9 +9,10 @@ import time
 from django.core.exceptions import ObjectDoesNotExist
 from django.views import View
 
-from Model.models import FamilyRoomDevice, GatewaySubDevice, FamilyRoom, SmartScene, EffectiveTime
+from Model.models import FamilyRoomDevice, GatewaySubDevice, FamilyRoom, SmartScene, EffectiveTime, Device_Info
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
+from Service.CommonService import CommonService
 
 
 class SmartSceneView(View):
@@ -39,7 +40,16 @@ class SmartSceneView(View):
             return self.task_devices(request_dict, user_id, response)
         elif operation == 'create':  # 创建智能场景
             return self.create_smart_scene(request_dict, user_id, response)
-
+        elif operation == 'scene-list':  # 查询智能场景列表
+            return self.scene_list(request_dict, user_id, response)
+        elif operation == 'update-status':  # 更新智能场景状态
+            return self.update_status(request_dict, response)
+        elif operation == 'detail':  # 查询智能场景详情
+            return self.scene_detail(request_dict, response)
+        elif operation == 'edit':  # 编辑智能场景
+            return self.edit_smart_scene(request_dict, response)
+        elif operation == 'delete':  # 删除智能场景
+            return self.delete_smart_scene(request_dict, response)
         else:
             return response.json(414)
 
@@ -58,21 +68,24 @@ class SmartSceneView(View):
         if not any([device_id, sub_device_id]):
             return response.json(444, {'error param': 'deviceId or subDeviceId'})
         try:
-            if device_id:
-                gateway_sub_device_qs = GatewaySubDevice.objects.filter(device_id=device_id)
-            else:
-                gateway_sub_device_qs = GatewaySubDevice.objects.filter(id=sub_device_id)
+            if sub_device_id:
+                device_id = GatewaySubDevice.objects.get(id=sub_device_id).device_id
+            gateway_sub_device_qs = GatewaySubDevice.objects.filter(device_id=device_id)
             if not gateway_sub_device_qs.exists():
                 return response.json(173)
             gateway_sub_device_qs = gateway_sub_device_qs.values('id', 'device_type', 'nickname', 'status')
             sub_device_list = []
             for gateway_sub_device in gateway_sub_device_qs:
-                room_id = FamilyRoomDevice.objects.filter(sub_device=gateway_sub_device['id']).values('room_id')[0][
-                    'room_id']
-                try:
-                    gateway_sub_device['room_name'] = FamilyRoom.objects.get(id=room_id).name
-                except ObjectDoesNotExist:
+                family_room_device_qs = FamilyRoomDevice.objects.filter(sub_device=gateway_sub_device['id']).\
+                    values('room_id')
+                if not family_room_device_qs.exists():
                     gateway_sub_device['room_name'] = ''
+                else:
+                    room_id = family_room_device_qs[0]['room_id']
+                    try:
+                        gateway_sub_device['room_name'] = FamilyRoom.objects.get(id=room_id).name
+                    except ObjectDoesNotExist:
+                        gateway_sub_device['room_name'] = ''
                 gateway_sub_device.pop('id')
                 sub_device_list.append(gateway_sub_device)
             return response.json(0, sub_device_list)
@@ -80,7 +93,7 @@ class SmartSceneView(View):
             return response.json(500, repr(e))
 
     @staticmethod
-    def task_devices(request_dict, response):
+    def task_devices(request_dict, user_id, response):
         """
         添加任务-查询设备
         @param request_dict: 请求参数
@@ -93,34 +106,9 @@ class SmartSceneView(View):
 
         if not all([device_id]):
             return response.json(444)
-
-        device_qs = FamilyRoomDevice.objects.filter(device_id=device_id,sub_device=0)
-        if not device_qs.exists():
-            return response.json(173)
-        gate_way = GatewaySubDevice.objects.filter(device_id=device_id)
-        if not gate_way.exists():
-            return response.json(173)
         try:
-            gate_way = gate_way.values('id', 'device_type', 'nickname', 'status')
-            gate_way_list = []
-            for gate_int in gate_way:
-                gate_way.exists()
-                gate_way_list.append(gate_int)
-            device_qs = device_qs.values('family_id', 'device_id', 'room_id', 'device__Type', 'device__NickName',
-                                             'device__UID')
-            device_qs_list = []
-            for device_int in device_qs:
-                device_qs.exists()
-                device_qs_list.append(device_int)
-            device_qs = device_qs.first()
-            room_id = device_qs['room_id']
-            room_qs = FamilyRoom.objects.filter(id=room_id).values('name')
-            room_qs_list = []
-            for room_int in room_qs:
-                room_qs.exists()
-                room_qs_list.append(room_int)
-            repe = {'device_qs_list': device_qs_list, 'gate_way_list': gate_way_list, 'room_qs_list': room_qs_list}
-            return response.json(0, repe)
+            device_info_qs = GatewaySubDevice.objects.filter(device__userID_id=user_id)
+            return response.json(0)
         except Exception as e:
             return response.json(500, repr(e))
 
@@ -131,7 +119,7 @@ class SmartSceneView(View):
         @param request_dict: 请求参数
         @param user_id: 用户id
         @request_dict deviceId: 网关设备id
-        @request_dict gatewaySubId: 子设备id
+        @request_dict subDeviceId: 子设备id
         @request_dict sceneName: 场景名称
         @request_dict conditions: 条件
         @request_dict tasks: 任务
@@ -143,7 +131,7 @@ class SmartSceneView(View):
         @return: response
         """
         device_id = request_dict.get('deviceId', None)
-        sub_device_id = request_dict.get('gatewaySubId', None)
+        sub_device_id = request_dict.get('subDeviceId', None)
         scene_name = request_dict.get('sceneName', None)
         conditions = request_dict.get('conditions', None)
         tasks = request_dict.get('tasks', None)
@@ -169,27 +157,189 @@ class SmartSceneView(View):
                 'created_time': now_time,
                 'updated_time': now_time,
             }
+
+            # 处理传网关设备id和子设备id的情况
             if device_id:
                 smart_scene_dict['device_id'] = device_id
+                device_info_qs = Device_Info.objects.filter(id=device_id).values('serial_number')
+                if not device_info_qs.exists():
+                    return response.json(173)
+                serial_number = device_info_qs[0]['serial_number']
             else:
                 smart_scene_dict['sub_device_id'] = sub_device_id
-            if is_all_day:
+                sub_device_qs = GatewaySubDevice.objects.filter(id=sub_device_id).values('device__serial_number')
+                if not sub_device_qs.exists():
+                    return response.json(173)
+                serial_number = sub_device_qs[0]['device__serial_number']
+
+            if not is_all_day:  # 没传时间
                 SmartScene.objects.create(**smart_scene_dict)
             else:
-                start_time = request_dict.get('startTime', None)
-                end_time = request_dict.get('endTime', None)
-                repeat = request_dict.get('repeat', None)
-                if not all([start_time, end_time, repeat]):
-                    return response.json(444, {'error param': 'startTime and endTime and repeat'})
-                effective_time_qs = EffectiveTime.objects.filter(start_time=start_time, end_time=end_time,
-                                                                 repeat=repeat).values('id')
-                if effective_time_qs.exists():
-                    effective_time_id = effective_time_qs[0]['id']
+                if is_all_day == '0':
+                    effective_time_qs = EffectiveTime.objects.filter(is_all_day=True).values('id')
+                    if effective_time_qs.exists():
+                        effective_time_id = effective_time_qs[0]['id']
+                    else:
+                        effective_time_id = EffectiveTime.objects.create(is_all_day=True).id
+                    smart_scene_dict['effective_time_id'] = effective_time_id
+                    SmartScene.objects.create(**smart_scene_dict)
                 else:
-                    effective_time_id = EffectiveTime.objects.create(start_time=start_time, end_time=end_time,
-                                                                     repeat=repeat).id
-                smart_scene_dict['effective_time_id'] = effective_time_id
-                SmartScene.objects.create(**smart_scene_dict)
+                    start_time = int(request_dict.get('startTime', None))
+                    end_time = int(request_dict.get('endTime', None))
+                    repeat = int(request_dict.get('repeat', None))
+                    if not all([start_time, end_time, repeat]):
+                        return response.json(444, {'error param': 'startTime and endTime and repeat'})
+                    effective_time_qs = EffectiveTime.objects.filter(start_time=start_time, end_time=end_time,
+                                                                     repeat=repeat).values('id')
+                    if effective_time_qs.exists():
+                        effective_time_id = effective_time_qs[0]['id']
+                    else:
+                        effective_time_id = EffectiveTime.objects.create(start_time=start_time, end_time=end_time,
+                                                                         repeat=repeat).id
+                    smart_scene_dict['effective_time_id'] = effective_time_id
+                    SmartScene.objects.create(**smart_scene_dict)
+
+            # 发布MQTT消息通知网关设备
+            thing_name = serial_number
+            topic_name = 'loocam/gateway_sensor/{}/smart_scene'.format(serial_number)
+            msg = ''
+            success = CommonService.req_publish_mqtt_msg(thing_name, topic_name, msg)
+            if not success:
+                return response.json(10044)
+
+            return response.json(0)
+        except Exception as e:
+            return response.json(500, repr(e))
+
+    @staticmethod
+    def scene_list(request_dict, user_id, response):
+        """
+        查询智能场景列表
+        @param request_dict: 请求参数
+        @param user_id: 用户id
+        @request_dict deviceId: 网关设备id
+        @request_dict subDeviceId: 子设备id
+        @param response: 响应对象
+        @return: response
+        """
+        device_id = request_dict.get('deviceId', None)
+        sub_device_id = request_dict.get('subDeviceId', None)
+
+        if not any([device_id, sub_device_id]):
+            return response.json(444, {'error param': 'deviceId or subDeviceId'})
+        try:
+            if device_id:
+                smart_scene_qs = SmartScene.objects.filter(user_id=user_id, device_id=device_id)
+            else:
+                smart_scene_qs = SmartScene.objects.filter(user_id=user_id, sub_device_id=sub_device_id)
+            if not smart_scene_qs.exists():
+                return response.json(173)
+            smart_scene_qs = smart_scene_qs.values('id', 'scene_name', 'is_enable')
+            return response.json(0, list(smart_scene_qs))
+        except Exception as e:
+            return response.json(500, repr(e))
+
+    @staticmethod
+    def update_status(request_dict, response):
+        """
+        更新智能场景状态
+        @param request_dict: 请求参数
+        @request_dict smartSceneId: 智能场景id
+        @request_dict isEnable: 状态,True or False
+        @param response: 响应对象
+        @return: response
+        """
+        smart_scene_id = request_dict.get('smartSceneId', None)
+        is_enable = request_dict.get('isEnable', None)
+
+        if not all([smart_scene_id, is_enable]):
+            return response.json(444, {'error param': 'smartSceneId and status'})
+        try:
+            SmartScene.objects.filter(id=smart_scene_id).update(is_enable=is_enable)
+            return response.json(0)
+        except Exception as e:
+            return response.json(500, repr(e))
+
+    @staticmethod
+    def scene_detail(request_dict, response):
+        """
+        查询智能场景详情
+        @param request_dict: 请求参数
+        @request_dict smartSceneId: 智能场景id
+        @param response: 响应对象
+        @return: response
+        """
+        smart_scene_id = request_dict.get('smartSceneId', None)
+
+        if not smart_scene_id:
+            return response.json(444, {'error param': 'smartSceneId'})
+        try:
+            smart_scene_qs = SmartScene.objects.filter(id=smart_scene_id).values('id', 'scene_name', 'conditions',
+                                                                                 'tasks', 'effective_time_id')
+            if not smart_scene_qs.exists():
+                return response.json(173)
+            res = {
+                'scene_name': smart_scene_qs[0]['scene_name'],
+                'condition': eval(smart_scene_qs[0]['conditions']),
+                'task': eval(smart_scene_qs[0]['tasks']),
+            }
+
+            # 如果存在关联的时间数据,组织时间数据
+            try:
+                effective_time_qs = EffectiveTime.objects.get(id=smart_scene_qs[0]['effective_time_id'])
+            except ObjectDoesNotExist:
+                return response.json(0, res)
+
+            if effective_time_qs.is_all_day:    # 全天
+                time_dict = {'all_day': 1}
+            else:
+                time_dict = {
+                    'start_time': effective_time_qs.start_time,
+                    'end_time': effective_time_qs.end_time,
+                    'repeat': effective_time_qs.repeat,
+                }
+            res['time'] = time_dict
+            return response.json(0, res)
+        except Exception as e:
+            return response.json(500, repr(e))
+
+    @staticmethod
+    def edit_smart_scene(request_dict, response):
+        """
+        编辑智能场景
+        @param request_dict: 请求参数
+        @request_dict smartSceneId: 智能场景id
+        @param response: 响应对象
+        @return: response
+        """
+        smart_scene_id = request_dict.get('smartSceneId', None)
+
+        if not smart_scene_id:
+            return response.json(444, {'error param': 'smartSceneId'})
+        try:
+            smart_scene_qs = SmartScene.objects.filter(id=smart_scene_id).values('id', 'scene_name', 'conditions',
+                                                                                 'tasks', 'effective_time_id')
+            if not smart_scene_qs.exists():
+                return response.json(173)
+            return response.json(0, list(smart_scene_qs))
+        except Exception as e:
+            return response.json(500, repr(e))
+
+    @staticmethod
+    def delete_smart_scene(request_dict, response):
+        """
+        删除智能场景
+        @param request_dict: 请求参数
+        @request_dict smartSceneId: 智能场景id
+        @param response: 响应对象
+        @return: response
+        """
+        smart_scene_id = request_dict.get('smartSceneId', None)
+
+        if not smart_scene_id:
+            return response.json(444, {'error param': 'smartSceneId'})
+        try:
+            SmartScene.objects.filter(id=smart_scene_id).delete()
             return response.json(0)
         except Exception as e:
             return response.json(500, repr(e))

+ 138 - 12
Controller/UnicomCombo/UnicomComboController.py

@@ -6,6 +6,7 @@
 @Email   : zhangdongming@asj6.wecom.work
 @Software: PyCharm
 """
+import datetime
 import json
 import logging
 import time
@@ -15,7 +16,7 @@ from django.http import HttpResponse, JsonResponse
 from django.views.generic.base import View
 
 from Model.models import UnicomDeviceInfo, UnicomCombo, Pay_Type, Order_Model, Store_Meal, AiStoreMeal, \
-    UnicomComboOrderInfo
+    UnicomComboOrderInfo, UnicomComboExperienceHistory
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Object.UnicomObject import UnicomObjeect
@@ -52,6 +53,9 @@ class UnicomComboView(View):
         elif operation == 'device-bind':
             response = ResponseObject('cn')
             return self.device_add(request_dict, response)
+        elif operation == 'device-status':
+            response = ResponseObject('cn')
+            return self.update_device_status(request_dict, response)
         else:
             token = TokenObject(request.META.get('HTTP_AUTHORIZATION'))
             lang = request_dict.get('lang', token.lang)
@@ -68,6 +72,10 @@ class UnicomComboView(View):
             elif operation == 'get-device-info':
                 return self.get_device_info(request_dict, response)
 
+    @classmethod
+    def update_device_status(cls, request_dict, response):
+        pass
+
     @classmethod
     def get_device_info(cls, request_dict, response):
         """
@@ -94,17 +102,21 @@ class UnicomComboView(View):
         """
         iccid = request_dict.get('iccid', None)
         serial_no = request_dict.get('serialNo', None)
-        if not all([iccid, serial_no]):
+        time_stamp = request_dict.get('timeStamp', None)
+        sign = request_dict.get('sign', None)
+        if not all([iccid, serial_no, sign, time_stamp]):
             return response.json(444)
+            # 时间戳token校验
+        if not CommonService.check_time_stamp_token(sign, time_stamp):
+            return response.json(13)
         n_time = int(time.time())
         try:
             with transaction.atomic():
                 # 待完善代码 根据uid与用户id验证系统设备
                 unicom_device_qs = UnicomDeviceInfo.objects.filter(iccid=iccid)
                 if unicom_device_qs.exists():
-                    return response.json(174)
-                unicom_device_serial_qs = UnicomDeviceInfo.objects.filter(serial_no=serial_no)
-                if unicom_device_serial_qs.exists():
+                    if unicom_device_qs.first().status == 1 and unicom_device_qs.first().serial_no == serial_no:
+                        cls.user_activate_flow(iccid)
                     return response.json(174)
                 unicom_obj = UnicomObjeect()
                 result = unicom_obj.verify_device(iccid=iccid)
@@ -115,6 +127,7 @@ class UnicomComboView(View):
                             return response.json(173)
                         params = {'iccid': iccid, 'serial_no': serial_no, 'updated_time': n_time,
                                   'created_time': n_time}
+                        cls.is_activate(iccid)
                         UnicomDeviceInfo.objects.create(**params)
                     return response.json(0)
                 else:
@@ -123,6 +136,53 @@ class UnicomComboView(View):
             print(e)
             return response.json(177, repr(e))
 
+    @classmethod
+    def user_activate_flow(cls, iccid):
+        """
+        用户激活初始化流量套餐
+        @param iccid:
+        @return:
+        """
+        logger = logging.getLogger('info')
+        try:
+            while transaction.atomic():
+                now_time = int(time.time())
+                unicom_device_info_qs = UnicomDeviceInfo.objects.filter(iccid=iccid)
+                if not unicom_device_info_qs.exists():
+                    return False
+                unicom_device_info_qs = unicom_device_info_qs.first()
+                if unicom_device_info_qs.status != 1:
+                    logger.info('用户激活iccid={},业务系统状态为{}'.format(iccid, unicom_device_info_qs.status))
+                    return False
+                # 联通业务逻辑
+                unicom_api = UnicomObjeect()
+                re_data = {'iccid': iccid}
+                result = unicom_api.query_device_status(**re_data)
+                res_dict = unicom_api.get_text_dict(result)
+                # 状态不等于1(激活)时进行激活 1:激活;2:停用
+                if res_dict['data']['status'] != 1:
+                    re_data = {"iccid": iccid, "status": 1}
+                    unicom_api.update_device_state(**re_data)
+                # 查看是否体验过免费套餐
+                experience_history_qs = UnicomComboExperienceHistory.objects.filter(iccid=iccid)
+                if not experience_history_qs.exists():
+                    logger.info('用户首次激活iccid={}'.format(iccid))
+                    combo_qs = UnicomCombo.objects.filter(combo_type=1, status=0, is_del=False) \
+                        .values('id', 'expiration_type', 'expiration_days', 'combo_type')
+                    if combo_qs.exists():
+                        combo_qs = combo_qs.first()
+                        # 保存体验记录
+                        experience_history_vo = {'iccid': iccid, 'experience_type': 0, 'do_time': now_time}
+                        UnicomComboExperienceHistory.objects.create(**experience_history_vo)
+                        # 保存套餐激活信息
+                        cls.create_combo_order_info('', 0, iccid, combo_qs['id'])
+                # 修改业务联通卡设备激活信息
+                UnicomDeviceInfo.objects.filter(iccid=iccid).update(status=2, updated_time=now_time)
+                return True
+        except Exception as e:
+            print(e)
+            return False
+
     @classmethod
     def save_unicom_combo(cls, request_dict, response):
         """
@@ -376,17 +436,33 @@ class UnicomComboView(View):
 
     @classmethod
     def create_combo_order_info(cls, order_id, activate_type, iccid, combo_id):
+        """
+        创建套餐生效记录
+        @param order_id: 订单id
+        @param activate_type: 激活类型
+        @param iccid: 联通20位iccid
+        @param combo_id: 套餐id
+        @return: True Or False
+        """
         logger = logging.getLogger('info')
         logger.info('创建联通订单套餐信息,订单id{}'.format(order_id))
         try:
+            today = datetime.datetime.today()
+            year = today.year
+            month = today.month
             with transaction.atomic():
                 unicom_combo_qs = UnicomCombo.objects.filter(id=int(combo_id)).values()
                 if unicom_combo_qs.exists():
                     unicom_combo = unicom_combo_qs.first()
                     now_time = int(time.time())
-                    combo_order_data = {'iccid': iccid, 'status': 0, 'combo_id': int(combo_id),
+                    combo_order_qs = UnicomComboOrderInfo.objects.filter(status=1, iccid=iccid)
+                    status = 0
+                    if not combo_order_qs.exists():
+                        status = 1
+                    combo_order_data = {'iccid': iccid, 'status': status, 'combo_id': int(combo_id),
                                         'updated_time': now_time,
-                                        'created_time': now_time}
+                                        'created_time': now_time,
+                                        'year': year, 'month': month}
                     if order_id:
                         combo_order_data['order_id'] = order_id
                     # 有效期类型 1 等于自然月,0天数
@@ -397,20 +473,31 @@ class UnicomComboView(View):
                             next_start_time, end_time = cls.get_next_month_data_time()
                             combo_order_data['activation_time'] = next_start_time
                             combo_order_data['expire_time'] = end_time
+                            combo_order_data['status'] = 0
                         else:
                             start_time, month_end_time = cls.get_month_start_and_end_time()
-                            combo_order_data['activation_time'] = start_time
+                            combo_order_data['activation_time'] = now_time
                             combo_order_data['expire_time'] = month_end_time
-                            combo_order_data['status'] = 1
 
                     elif unicom_combo['expiration_type'] == 0:
                         days = unicom_combo['expiration_days']
                         zero_today, end_time = cls.get_data_time(days)
-                        combo_order_data['activation_time'] = zero_today
+                        combo_order_data['activation_time'] = now_time
                         combo_order_data['expire_time'] = end_time
-                        combo_order_data['status'] = 1
+                        # 联通业务逻辑
+                    unicom_api = UnicomObjeect()
+                    if status == 1:
+                        re_data = {'iccid': iccid}
+                        result = unicom_api.query_device_status(**re_data)
+                        res_dict = unicom_api.get_text_dict(result)
+                        # 状态不等于1(激活)时进行激活 1:激活;2:停用
+                        if res_dict and res_dict['data']['status'] != 1:
+                            re_data = {"iccid": iccid, "status": 1}
+                            unicom_api.update_device_state(**re_data)
+                        flow_total_usage = unicom_api.get_flow_usage_total(year, month, iccid)
+                        combo_order_data['flow_total_usage'] = str(flow_total_usage)
                     UnicomComboOrderInfo.objects.create(**combo_order_data)
-                    logger.info('保存信息success')
+                    logger.info('保存套餐支付信息success')
                 return True
         except Exception as e:
             print(e)
@@ -452,3 +539,42 @@ class UnicomComboView(View):
         month_end = LocalDateTimeUtil.get_cur_month_end()
         start_time, month_end_time = LocalDateTimeUtil.get_start_and_end_time(month_end, '%Y-%m-%d')
         return zero_today, month_end_time
+
+    @staticmethod
+    def is_activate(iccid):
+        """
+        根据iccid判断是否激活,未激活则修改为激活状态
+        @param iccid:
+        @return:
+        """
+        if iccid:
+            unicom_api = UnicomObjeect()
+            re_data = {'iccid': iccid}
+            result = unicom_api.query_device_status(**re_data)
+            res_dict = unicom_api.get_text_dict(result)
+            # 状态不等于1(激活)时进行激活 1:激活;2:停用
+            if res_dict['data']['status'] != 1:
+                re_data = {"iccid": iccid, "status": 1}
+                unicom_api.update_device_state(**re_data)
+                return True
+        return None
+
+    @classmethod
+    def get_test_sign(cls, request_dict, response):
+        """
+        测试盐加密解密
+        @param request_dict:
+        @param response:
+        @return:
+        """
+        verify = request_dict.get('verify', False)
+        if verify:
+            sign = request_dict.get('sign')
+            time_stamp = request_dict.get('timeStamp')
+            sign = CommonService.check_time_stamp_token(sign, time_stamp)
+            if not sign:
+                return response.json(13)
+            return response.json(0)
+        now_time = int(time.time())
+        sign = CommonService.encode_data(str(now_time))
+        return response.json(0, {'sign': sign, 'timeStamp': now_time})

+ 129 - 22
Controller/UnicomCombo/UnicomComboTaskController.py

@@ -6,6 +6,7 @@
 @Email   : zhangdongming@asj6.wecom.work
 @Software: PyCharm
 """
+import datetime
 import logging
 import time
 
@@ -34,6 +35,14 @@ class UnicomComboTaskView(View):
         print(request)
         if operation == 'check-activate':
             return self.check_activate_combo(request_dict, response)
+        elif operation == 'check-flow':
+            return self.check_flow_usage(response)
+        elif operation == 'check-expire':
+            today = datetime.datetime.today()
+            year = today.year
+            month = today.month
+            self.query_unused_combo_and_activate(request_dict.get('iccid'), year, month, '666')
+            return response.json(0)
 
     @classmethod
     def check_activate_combo(cls, request_dict, response):
@@ -54,39 +63,137 @@ class UnicomComboTaskView(View):
             return response.json(0)
         try:
             now_time = int(time.time())
+            today = datetime.datetime.today()
+            year = today.year
+            month = today.month
             with transaction.atomic():
                 unicom_api = UnicomObjeect()
-
                 for item in combo_order_info_qs:
                     if item['order_id']:
                         order_id = item['order_id']
                         order_qs = Order_Model.objects.filter(orderID=order_id, status=1)
                         if not order_qs.exists():
-                            logger.info('当前已付款联通订单套餐不存在:orderId={}'.format(order_id))
+                            continue
+                        combo_order_qs = UnicomComboOrderInfo.objects.filter(status=1, iccid=item['iccid'])
+                        # 当前已有套餐正在使用则跳出当前循环
+                        if combo_order_qs.exists():
                             continue
                         combo_id = item['combo_id']
                         combo_qs = UnicomCombo.objects.filter(id=combo_id).values()
-                        if combo_qs.exists():
-                            item['status'] = 1
-                            item['updated_time'] = now_time
-                            params = {'iccid': item['iccid']}
-                            result = unicom_api.verify_device(**params)
-                            result = unicom_api.get_text_dict(result)
-                            if result and result['success']:
-                                # 1:已激活;2:可激活;3:已停用;4:已失效;5:可测试;6:库存;7:已更换;8:已清除;
-                                status = result['data']['status']
-                                if status != 1:
-                                    up_data = {'iccid': item['iccid'], 'status': 1}
-                                    device_result = UnicomObjeect.update_device_state(**up_data)
-                                    device_result = UnicomObjeect.get_text_dict(device_result)
-                                    if device_result and device_result['success']:
-                                        UnicomComboOrderInfo.objects.filter(id=item['id']) \
-                                            .update(status=1, updated_time=now_time)
-                                else:
-                                    UnicomComboOrderInfo.objects.filter(id=item['id']) \
-                                        .update(status=1, updated_time=now_time)
-                                logger.info('激活成功,订单编号:{}'.format(order_id))
+                        if not combo_qs.exists():
+                            continue
+                        flow_total_usage = unicom_api.get_flow_usage_total(year, month, item['iccid'])
+                        flow_total_usage = str(flow_total_usage)
+
+                        params = {'iccid': item['iccid']}
+                        result = unicom_api.query_device_status(**params)
+                        res_dict = unicom_api.get_text_dict(result)
+                        # 状态不等于1(激活)时进行激活 1:激活;2:停用
+                        if res_dict['data']['status'] != 1:
+                            re_data = {"iccid": item['iccid'], "status": 1}
+                            unicom_api.update_device_state(**re_data)
+                            UnicomComboOrderInfo.objects.filter(id=item['id']) \
+                                .update(status=1, updated_time=now_time, year=year, month=month,
+                                        flow_total_usage=flow_total_usage)
+                        else:
+                            UnicomComboOrderInfo.objects.filter(id=item['id']) \
+                                .update(status=1, updated_time=now_time, year=year, month=month,
+                                        flow_total_usage=flow_total_usage)
+                        logger.info('激活成功,订单编号:{}'.format(order_id))
             return response.json(0)
         except Exception as e:
             print(e)
             return response.json(177, repr(e))
+
+    @classmethod
+    def check_flow_usage(cls, response):
+        """
+        检查流量使用情况
+        @return:
+        """
+        logger = logging.getLogger('info')
+        logger.info('进入检查流量使用情况')
+        try:
+            combo_order_qs = UnicomComboOrderInfo.objects.filter(status=1).values()
+            if not combo_order_qs.exists():
+                return response.json(0)
+            today = datetime.datetime.today()
+            year = today.year
+            month = today.month
+            unicom_api = UnicomObjeect()
+            now_time = int(time.time())
+            for item in combo_order_qs:
+                iccid = item['iccid']
+                usage_flow = float(item['flow_total_usage']) if item['flow_total_usage'] else 0.0
+                combo_id = item['combo_id']
+                combo_qs = UnicomCombo.objects.filter(id=combo_id).values()
+                if combo_qs.exists():
+                    combo_qs = combo_qs.first()
+                    flow_total = combo_qs['flow_total']
+                    # 查询当前月用量历史
+                    month_usage_flow = unicom_api.get_flow_usage_total(year, month, iccid)
+                    is_expire = False
+                    if item['year'] == year and item['month'] == month:
+                        if month_usage_flow > 0:
+                            # 初始套餐已使用流量 + 套餐总流量
+                            flow = usage_flow + flow_total
+                            if month_usage_flow >= flow:
+                                is_expire = True
+                    else:
+                        activate_year = item['year']
+                        activate_month = item['month']
+                        # 上月使用流量
+                        last_usage_flow = unicom_api.get_flow_usage_total(activate_year, activate_month, iccid)
+                        # 上月套餐实际使用量
+                        actual_usage_flow = last_usage_flow - usage_flow
+                        # 剩余
+                        surplus_flow = flow_total - actual_usage_flow
+                        # result = Decimal(surplus_flow).quantize(Decimal('0.00'))
+                        if month_usage_flow > 0:
+                            if month_usage_flow >= surplus_flow:
+                                is_expire = True
+                    # 检查是否有当月未使用套餐 没有则停卡
+                    if is_expire:
+                        UnicomComboOrderInfo.objects.filter(id=item['id']).update(status=2, updated_time=now_time)
+                        activate_status = cls.query_unused_combo_and_activate(iccid, year, month,
+                                                                              month_usage_flow)
+                        if not activate_status:
+                            re_data = {"iccid": iccid, "status": 2}
+                            unicom_api.update_device_state(**re_data)
+
+            return response.json(0)
+        except Exception as e:
+            logger.info('网关推送消息异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            return response.json(177, repr(e))
+
+    @staticmethod
+    def query_unused_combo_and_activate(iccid, year, month, usage_flow):
+        """
+        查询未使用套餐并激活
+        @param iccid:
+        @param year:
+        @param month:
+        @param usage_flow:
+        @return:
+        """
+        try:
+            now_time = int(time.time())
+            combo_order_qs = UnicomComboOrderInfo.objects.filter(expire_time__gt=now_time, status=0,
+                                                                 iccid=iccid).order_by(
+                'created_time')
+            if not combo_order_qs.exists():
+                return False
+
+            combo_order = combo_order_qs.first()
+            upd_data = {
+                'status': 1,
+                'year': year,
+                'month': month,
+                'flow_total_usage': str(usage_flow),
+                'updated_time': now_time,
+            }
+            UnicomComboOrderInfo.objects.filter(id=combo_order.id).update(**upd_data)
+            return True
+        except Exception as e:
+            print(e)
+            return False

+ 11 - 6
Model/models.py

@@ -2644,9 +2644,10 @@ class SmartScene(models.Model):
 
 class EffectiveTime(models.Model):
     id = models.AutoField(primary_key=True, verbose_name=u'自增标记id')
-    start_time = models.CharField(default='', max_length=10, verbose_name=u'开始时间')
-    end_time = models.CharField(default='', max_length=10, verbose_name=u'结束时间')
-    repeat = models.CharField(default='', max_length=32, verbose_name=u'重复周期')
+    is_all_day = models.BooleanField(default=False, verbose_name=u'是否全天')
+    start_time = models.SmallIntegerField(default=0, verbose_name=u'开始时间')
+    end_time = models.SmallIntegerField(default=0, verbose_name=u'结束时间')
+    repeat = models.SmallIntegerField(default=0, verbose_name=u'重复周期')
 
     class Meta:
         db_table = 'effective_time'
@@ -2659,6 +2660,8 @@ class UnicomCombo(models.Model):
     package_id = models.CharField(default='', max_length=32, verbose_name=u'联通套餐id')
     combo_name = models.CharField(default='', max_length=32, verbose_name=u'套餐名称')
     status = models.SmallIntegerField(default=0, verbose_name='状态{0:开启,1:停用}')
+    # 套餐类型 0:商用,1:初始化赠送
+    combo_type = models.SmallIntegerField(default=0, verbose_name='套餐类型')
     flow_total = models.IntegerField(default=0, blank=True, verbose_name=u'流量总量值 单位(MB)')
     expiration_days = models.IntegerField(default=0, blank=True, verbose_name=u'有效期天数')
     expiration_type = models.SmallIntegerField(default=0, verbose_name=u'有效期类型,0=天,1=月,2=年')
@@ -2685,6 +2688,9 @@ class UnicomComboOrderInfo(models.Model):
     order_id = models.CharField(blank=True, default='', max_length=32, verbose_name=u'关联订单表')
     combo = models.ForeignKey(UnicomCombo, to_field='id', default='', on_delete=models.CASCADE,
                               verbose_name=u'联通套餐表')
+    year = models.IntegerField(default=0, verbose_name='使用年')
+    month = models.IntegerField(default=0, verbose_name='使用月')
+    flow_total_usage = models.CharField(blank=True, default='', max_length=32, verbose_name=u'激活时当月已用流量')
     next_month_activate = models.BooleanField(blank=True, default=False, verbose_name=u'下月激活')
     activation_time = models.IntegerField(default=0, verbose_name='激活时间')
     expire_time = models.IntegerField(default=0, verbose_name='过期时间')
@@ -2700,9 +2706,8 @@ class UnicomComboOrderInfo(models.Model):
 
 class UnicomDeviceInfo(models.Model):
     id = models.AutoField(primary_key=True, verbose_name=u'自增标记Id')
-    iccid = models.CharField(default='', max_length=32, verbose_name=u'完整的20位纯数字ICCID')
+    iccid = models.CharField(db_index=True, unique=True, max_length=32, verbose_name=u'完整的20位纯数字ICCID')
     status = models.SmallIntegerField(default=0, verbose_name=u'状态{0:可测试,1:测试完成,2:已使用}')
-    before_usage_history = models.CharField(blank=True, default='', max_length=32, verbose_name=u'激活前用量历史')
     serial_no = models.CharField(default='', max_length=32, verbose_name=u'设备序列号')
     user_id = models.CharField(blank=True, max_length=32, verbose_name=u'用户id')
     main_card = models.SmallIntegerField(default=0, verbose_name=u'状态{0:主卡,1:拔插卡}')
@@ -2759,7 +2764,7 @@ class UnicomComboExperienceHistory(models.Model):
     id = models.AutoField(primary_key=True)
     # 0: 免费体验, 1: 激活码
     experience_type = models.SmallIntegerField(default=0, verbose_name='体验类型')
-    serial_no = models.CharField(max_length=32, default='', verbose_name='设备序列号')
+    iccid = models.CharField(max_length=32, default='', verbose_name='联通20位ICCID')
     do_time = models.IntegerField(default=0, verbose_name='激活时间')
 
     class Meta:

+ 56 - 3
Object/UnicomObject.py

@@ -7,6 +7,7 @@
 @Software: PyCharm
 """
 import base64
+import datetime
 import json
 from decimal import Decimal
 
@@ -15,6 +16,7 @@ from Crypto.Cipher import AES
 
 from Ansjer.config import unicomAppUrl, unicomAppId, unicomAppSecret, unicomTenantId, \
     unicomEncodeKey, unicomIvKey, unicomUserName, unicomPassword, unicomPushKey
+from Object.RedisObject import RedisObject
 from Object.utils import SM3Util
 from Object.utils.SymmetricCryptoUtil import AESencrypt
 
@@ -227,8 +229,59 @@ class UnicomObjeect:
             return json.loads(result.text)
         return None
 
+    @staticmethod
+    def unicom_flow_usage_cache(key, expire=0, **usage_data):
+        """
+        流量用量历史优先查询缓存
+        @param key: 缓存key
+        @param expire: 失效时间
+        @param usage_data: 查询参数
+        @return: 返回结果dict
+        """
+        redis = RedisObject()
+        usage_history = redis.get_data(key)
+        if usage_history:
+            usage_history = json.loads(usage_history)
+        else:
+            usage_history = UnicomObjeect().query_device_usage_history(**usage_data)
+            usage_history = UnicomObjeect().get_text_dict(usage_history)
+            redis.set_data(key=key, val=json.dumps(usage_history), expire=expire)
+        return usage_history
+
+    @staticmethod
+    def get_flow_usage_total(usage_year, usage_month, iccid):
+        """
+        查询当月用量历史
+        @param usage_year: 使用年
+        @param usage_month: 使用月
+        @param iccid: 联通id
+        @return: flow_total_usage 当月实际使用流量
+        """
+        flow_key = 'ASJ:UNICOM:FLOW:{}'
+        usage_data = {'iccid': iccid}
+        usage_history = UnicomObjeect().unicom_flow_usage_cache(flow_key.format(iccid), (60 * 10 + 3), **usage_data)
+        # 当月实际总使用流量
+        flow_total_usage = 0
+        if usage_history and usage_history['success']:
+            device_usage_history_list = usage_history['data']['deviceUsageHistory']
+            if device_usage_history_list:
+                for item in device_usage_history_list:
+                    if item['year'] == usage_year and item['month'] == usage_month:
+                        flow_total_usage += item['flowTotalUsage']
+                        break
+        return flow_total_usage
+
 
 if __name__ == '__main__':
+
+    today = datetime.datetime.today()
+    year = today.year
+    month = today.month
+    print(year)
+    print(month)
+    print(type(year))
+    if not '':
+        print('为空')
     price = '12.13'
     print(float(price))
     discount = '6'
@@ -240,10 +293,10 @@ if __name__ == '__main__':
     print(unicom_api.createSign(**data))
     # result = unicom_api.generate_token()
     # result = unicom_api.refresh_token('5d0c0f30-99bd-4f17-9614-3524495b05d4')
-    params = {'iccid': '89860620170009628001'}
-    response = unicom_api.verify_device(**params)
+    params = {'iccid': '89860621330065433774', 'status': 2}
+    # response = unicom_api.verify_device(**params)
     # response = unicom_api.query_device_status(**params)
-    # response = unicom_api.update_device_state(**params)
+    response = unicom_api.update_device_state(**params)
     # response = unicom_api.query_device_usage_history(**params)
     # response = unicom_api.query_current_renew_list_usage_details(**params)
     # unicom_api.get_device_batch_detail()

+ 6 - 5
Service/EquipmentInfoService.py

@@ -162,7 +162,6 @@ class EquipmentInfoService:
         # 获取七天前时间戳
         seven_days_before_time = LocalDateTimeUtil.get_before_days_timestamp(now_time, 7)
         # 默认查询当前表event_time大于七天前时间
-        qs = qs.filter(event_time__gt=seven_days_before_time)
         if user_id:
             qs = qs.filter(device_user_id=user_id)
         if event_type:
@@ -173,7 +172,9 @@ class EquipmentInfoService:
             else:
                 qs = qs.filter(event_type=event_type)
         if start_time and end_time:
-            qs = qs.filter(event_time__range=(start_time, end_time))
+            qs = qs.filter(event_time__range=(int(start_time), int(end_time)))
+        else:
+            qs = qs.filter(event_time__range=(seven_days_before_time, now_time))
         if uid_list:
             uid_list = uid_list.split(',')
             qs = qs.filter(device_uid__in=uid_list)
@@ -268,9 +269,9 @@ class EquipmentInfoService:
         comb_ai_event_type = []
         for i in range(1, len(type) + 1):  # 计算所有组合,如[1, 2, 3, 4], 4取1,4取2,4取3,4取4
             for s in itertools.combinations(type, i):
-                    s_list = list(s)
-                    s_list = [str(v) for v in s_list]
-                    comb_ai_event_type.append(s_list)
+                s_list = list(s)
+                s_list = [str(v) for v in s_list]
+                comb_ai_event_type.append(s_list)
         regroup_list = []
         for val in comb_ai_event_type:  # 组合ai类型组合,如[[2,3],[1,3]] -> [23, 13]
             val = ''.join(val)