Explorar o código

新增联通首次添加设备激活出厂绑定无限流量接口

zhangdongming hai 1 ano
pai
achega
bd06c631bb

+ 2 - 2
Ansjer/server_urls/unicom_url.py

@@ -10,12 +10,12 @@ from django.urls import re_path
 
 from Controller.UnicomCombo import UnicomComboController, UnicomComboPayNotifyController, UnicomComboTaskController
 from AdminController import UnicomManageController
-from Controller.UnicomCombo.WXTechController import WXTechController
+from Controller.UnicomCombo import WXTechController
 
 urlpatterns = [
     re_path(r'^api/(?P<operation>.*)$', UnicomComboController.UnicomComboView.as_view()),
     re_path(r'^wap/pay/(?P<operation>.*)$', UnicomComboPayNotifyController.UnicomComboPayNotifyView.as_view()),
     re_path(r'^combo/cron/(?P<operation>.*)$', UnicomComboTaskController.UnicomComboTaskView.as_view()),
     re_path(r'^manage/(?P<operation>.*)$',UnicomManageController.UnicomManageControllerView.as_view()),
-    re_path(r'^open/wxtech/(?P<operation>.*)$', WXTechController.SmartSocketView.as_view()),
+    re_path(r'^open/wxtech/(?P<operation>.*)$', WXTechController.WXTechControllerView.as_view()),
 ]

+ 2 - 1
Controller/EquipmentManagerV3.py

@@ -16,12 +16,12 @@ from Controller.CheckUserData import RandomStr
 from Controller.DeviceConfirmRegion import Device_Region
 from Controller.SensorGateway.EquipmentFamilyController import EquipmentFamilyView
 from Controller.UnicomCombo.UnicomComboController import UnicomComboView
+from Controller.UnicomCombo.WXTechController import WXTechControllerView
 from Model.models import Device_Info, UID_Bucket, UID_Preview, UidSetModel, UidChannelSetModel, \
     Device_User, iotdeviceInfoModel, UIDCompanySerialModel, UnicomDeviceInfo, CountryModel, \
     DeviceCloudPhotoInfo, UidPushModel, ExperienceContextModel, LogModel
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
-from Object.utils import LocalDateTimeUtil
 from Service.CommonService import CommonService
 from Service.EquipmentInfoService import EquipmentInfoService
 from Service.ModelService import ModelService
@@ -397,6 +397,7 @@ class EquipmentManagerV3(View):
                 # 领取4G体验套餐
                 res = UnicomComboView.user_activate_flow(unicom_device_info_qs[0].iccid)
                 logging.info('{}联通领取体验流量:{}'.format(unicom_device_info_qs[0].iccid, res))
+                WXTechControllerView.activate_flow_package(serial_number, 'system', user_id)
             if not unicom_device_info_qs[0].user_id:
                 # 生成4G免费订单
                 UnicomComboView.experience_order_4G(unicom_device_info_qs[0].iccid,

+ 461 - 398
Controller/UnicomCombo/WXTechController.py

@@ -25,426 +25,489 @@ from Service.CommonService import CommonService
 COMBO_ID = 'DX-DX-FDX-JCB-1G-15天-4DX-ASJ-YTC-AT-2022123020221230144615'
 
 
-class WXTechController(View):
-    class SmartSocketView(View):
-        def get(self, request, *args, **kwargs):
-            request.encoding = 'utf-8'
-            operation = kwargs.get('operation')
-            return self.validation(request.GET, request, operation)
+class WXTechControllerView(View):
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.GET, request, operation)
 
-        def post(self, request, *args, **kwargs):
-            request.encoding = 'utf-8'
-            operation = kwargs.get('operation')
-            return self.validation(request.POST, request, operation)
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.POST, request, operation)
 
-        def delete(self, request, *args, **kwargs):
-            request.encoding = 'utf-8'
-            operation = kwargs.get('operation')
-            delete = QueryDict(request.body)
-            if not delete:
-                delete = request.GET
-            return self.validation(delete, request, operation)
+    def delete(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        delete = QueryDict(request.body)
+        if not delete:
+            delete = request.GET
+        return self.validation(delete, request, operation)
 
-        def put(self, request, *args, **kwargs):
-            request.encoding = 'utf-8'
-            operation = kwargs.get('operation')
-            put = QueryDict(request.body)
-            return self.validation(put, request, operation)
+    def put(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        put = QueryDict(request.body)
+        return self.validation(put, request, operation)
 
-        def validation(self, request_dict, request, operation):
-            if operation == 'deleteCardPackage':
-                return self.delete_card_package(request_dict, ResponseObject('cn'))
-            elif operation == 'packageRefund':
-                return self.wx_package_refund(request_dict, ResponseObject('cn'))
-            token_code, user_id, response = CommonService \
-                .verify_token_get_user_id(request_dict, request)
-            if token_code != 0:
-                return response.json(token_code)
-            if operation == 'getCardsInfo':
-                return self.get_cards_info(request_dict, response)
-            elif operation == 'getExperiencePackage':
-                return self.get_experience_package(request_dict, response)
-            elif operation == 'createOrder':
-                return self.create_order_package(user_id, request_dict, response)
-            elif operation == 'exchangePackage':
-                return self.wx_exchange_package(request_dict, response, request, user_id)
-            elif operation == 'getPackageBySerialNumber':
-                return self.get_package_by_serial_number(request_dict, response, request, user_id)
-            elif operation == 'create4GFlowPackage':
-                return self.create_4G_flow_package(request_dict, response, request, user_id)
+    def validation(self, request_dict, request, operation):
+        if operation == 'deleteCardPackage':
+            return self.delete_card_package(request_dict, ResponseObject('cn'))
+        elif operation == 'packageRefund':
+            return self.wx_package_refund(request_dict, ResponseObject('cn'))
+        token_code, user_id, response = CommonService \
+            .verify_token_get_user_id(request_dict, request)
+        if token_code != 0:
+            return response.json(token_code)
+        if operation == 'getCardsInfo':
+            return self.get_cards_info(request_dict, response)
+        elif operation == 'getExperiencePackage':
+            return self.get_experience_package(request_dict, response)
+        elif operation == 'createOrder':
+            return self.create_order_package(user_id, request_dict, response)
+        elif operation == 'exchangePackage':
+            return self.wx_exchange_package(request_dict, response, request, user_id)
+        elif operation == 'getPackageBySerialNumber':
+            return self.get_package_by_serial_number(request_dict, response, request, user_id)
+        elif operation == 'create4GFlowPackage':
+            return self.create_4G_flow_package(request_dict, response, request, user_id)
 
-        @classmethod
-        def wx_package_refund(cls, request_dict, response):
-            """
-            五兴套餐退订
-            """
-            try:
-                serial_number = request_dict.get('serialNumber', None)
-                if not serial_number:
-                    return response(444)
-                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)
-                order_info_qs = Order_Model.objects.filter(UID=uid, order_type=3).values('trade_no') \
-                    .order_by('-payTime')
-                if not order_info_qs.exists():
-                    return response(173)
-                iccid = device_qs[0]['iccid']
-                trade_no = order_info_qs[0]['trade_no']
-                data = {'iccid': iccid, 'operator': 3, 'orderNumber': trade_no}
-                wx_tech = WXTechObject()
-                res = wx_tech.package_refund(**data)
-                if res['code'] == '0':
-                    return response.json(0)
-                return response.json(10059)
-            except Exception as e:
-                LOGGER.info('*****WXTechController.get_cards_info:errLine:{}, errMsg:{}'
-                            .format(e.__traceback__.tb_lineno, repr(e)))
-                return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+    @classmethod
+    def wx_package_refund(cls, request_dict, response):
+        """
+        五兴套餐退订
+        """
+        try:
+            serial_number = request_dict.get('serialNumber', None)
+            if not serial_number:
+                return response(444)
+            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)
+            order_info_qs = Order_Model.objects.filter(UID=uid, order_type=3).values('trade_no') \
+                .order_by('-payTime')
+            if not order_info_qs.exists():
+                return response(173)
+            iccid = device_qs[0]['iccid']
+            trade_no = order_info_qs[0]['trade_no']
+            data = {'iccid': iccid, 'operator': 3, 'orderNumber': trade_no}
+            wx_tech = WXTechObject()
+            res = wx_tech.package_refund(**data)
+            if res['code'] == '0':
+                return response.json(0)
+            return response.json(10059)
+        except Exception as e:
+            LOGGER.info('*****WXTechController.get_cards_info:errLine:{}, errMsg:{}'
+                        .format(e.__traceback__.tb_lineno, repr(e)))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
-        @classmethod
-        def get_cards_info(cls, request_dict, response):
-            """
-            五兴单卡获取信息
-            """
-            try:
-                LOGGER.info('*****WXTechController.get_cards_info:params:{}'.format(request_dict))
-                iccid = request_dict.get('iccid', None)
-                operator = int(request_dict.get('operator', 3))
-                if not iccid:
-                    return response.json(444)
-                data = {'iccid': iccid, 'operator': operator}
-                wx_tech = WXTechObject()
-                return response.json(0, wx_tech.get_cards_info(**data))
-            except Exception as e:
-                LOGGER.info('*****WXTechController.get_cards_info:errLine:{}, errMsg:{}'
-                            .format(e.__traceback__.tb_lineno, repr(e)))
-                return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+    @classmethod
+    def get_cards_info(cls, request_dict, response):
+        """
+        五兴单卡获取信息
+        """
+        try:
+            LOGGER.info('*****WXTechController.get_cards_info:params:{}'.format(request_dict))
+            iccid = request_dict.get('iccid', None)
+            operator = int(request_dict.get('operator', 3))
+            if not iccid:
+                return response.json(444)
+            data = {'iccid': iccid, 'operator': operator}
+            wx_tech = WXTechObject()
+            return response.json(0, wx_tech.get_cards_info(**data))
+        except Exception as e:
+            LOGGER.info('*****WXTechController.get_cards_info:errLine:{}, errMsg:{}'
+                        .format(e.__traceback__.tb_lineno, repr(e)))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
+    @classmethod
+    def get_experience_package(cls, request_dict, response):
+        """
+        获取体验套餐
+        """
+        try:
+            LOGGER.info('*****WXTechController.get_experience_package:params{}'.format(request_dict))
+            serial_no = request_dict.get('serialNo', None)
+            if not serial_no:
+                return response.json(444)
+            serial_no = serial_no[0:9]
+            # 查询是否注册iccid
+            unicom_device_qs = UnicomDeviceInfo.objects.filter(serial_no=serial_no) \
+                .values('serial_no', 'user_id', 'iccid')
+            if not unicom_device_qs.exists():
+                return response.json(173)
+            unicom_device_qs = unicom_device_qs.first()
+            iccid = unicom_device_qs['iccid']
+            # 查看是否体验过免费套餐
+            experience_history_qs = UnicomComboExperienceHistory.objects.filter(iccid=iccid)
+            if experience_history_qs.exists():
+                return response.json(10062)
+            combo_info_qs = UnicomCombo.objects.filter(combo_type=1, status=0, is_del=False) \
+                .values('combo_name')
+            if not combo_info_qs.exists():
+                return response.json(173)
+            result = {'comboName': combo_info_qs[0]['combo_name']}
+            return response.json(0, result)
+        except Exception as e:
+            LOGGER.info('*****WXTechController.get_experience_package:errLine:{}, errMsg:{}'
+                        .format(e.__traceback__.tb_lineno, repr(e)))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
+    @classmethod
+    def create_order_package(cls, user_id, request_dict, response):
+        """
+        五兴电信领取1G15天流量体验包
+        """
+        try:
+            LOGGER.info('*****WXTechController.create_order_package:params:{}'.format(request_dict))
+            serial_no = request_dict.get('serialNo', None)
+            operator = request_dict.get('operator', None)
+            if not all([operator, serial_no]):
+                return response.json(444)
+            serial_no = serial_no[0:9]
+            unicom_device_qs = UnicomDeviceInfo.objects.filter(serial_no=serial_no) \
+                .values('serial_no', 'user_id', 'iccid')
+            if not unicom_device_qs.exists():
+                return response.json(173)
+            unicom_device_qs = unicom_device_qs.first()
+            iccid = unicom_device_qs['iccid']
+            # 查看是否体验过免费套餐
+            experience_history_qs = UnicomComboExperienceHistory.objects.filter(iccid=iccid)
+            if experience_history_qs.exists():
+                return response.json(10062)
+            data = {'iccid': iccid, 'operator': WXOperatorEnum(int(operator)).value,
+                    'startType': str(WXStartTypeEnum.EFFECTIVE_IMMEDIATELY.value), 'packageCode': COMBO_ID}
+            wx_tech = WXTechObject()
+            # 请求五兴API创建套餐接口
+            res = wx_tech.create_order_package(**data)
+            LOGGER.info('*****五兴创建体验套餐信息:{}'.format(res))
+            if res['code'] == '0':
+                trade_no = res['data']['orderNumber']
+                experience_history_vo = {'iccid': iccid, 'experience_type': 0, 'do_time': int(time.time())}
+                UnicomComboExperienceHistory.objects.create(**experience_history_vo)
+                order_res = cls.created_order(serial_no, user_id, trade_no, pay_type=10)
+                UnicomDeviceInfo.objects.filter(serial_no=serial_no) \
+                    .update(user_id=user_id, updated_time=int(time.time()))
+                LOGGER.info('*****系统创建体验订单:{}'.format(order_res))
+                return response.json(0)
+            return response.json(10063)
+        except Exception as e:
+            LOGGER.info('*****WXTechController.create_order_package:errLine:{}, errMsg:{}'
+                        .format(e.__traceback__.tb_lineno, repr(e)))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
-        @classmethod
-        def get_experience_package(cls, request_dict, response):
-            """
-            获取体验套餐
-            """
-            try:
-                LOGGER.info('*****WXTechController.get_experience_package:params{}'.format(request_dict))
-                serial_no = request_dict.get('serialNo', None)
-                if not serial_no:
-                    return response.json(444)
-                serial_no = serial_no[0:9]
+    @classmethod
+    def created_order(cls, serial_no, user_id, trade_no, combo_id=None, pay_type=10, order_type=3):
+        """
+        创建系统订单
+        """
+        combo_info_qs = UnicomCombo.objects.filter(is_del=False)
+        if combo_id:
+            combo_info_qs = combo_info_qs.filter(id=int(combo_id))
+        else:
+            combo_info_qs = combo_info_qs.filter(combo_type=1, status=0)
+        combo_info_qs = combo_info_qs.values('id', 'combo_name', 'price', 'virtual_price', 'remark') \
+            .order_by('sort')
+        if not combo_info_qs.exists():
+            return False
+        combo_info_vo = combo_info_qs[0]
+        n_time = int(time.time())
+        # 根据序列号获取UID
+        uid = CommonService.query_uid_with_serial(serial_no)
+        order_id = CommonService.createOrderID()
+        # 生成订单必须添加该字段
+        rank_id, ai_rank_id = UnicomComboView().get_cloud_or_ai_combo()
+        order_dict = {'orderID': order_id, 'UID': uid, 'rank_id': rank_id, 'ai_rank_id': ai_rank_id,
+                      'userID_id': user_id, 'desc': combo_info_vo['combo_name'], 'payType': pay_type,
+                      'payTime': n_time, 'price': combo_info_vo['price'], 'addTime': n_time,
+                      'updTime': n_time, 'status': 1, 'currency': 'CNY',
+                      'unify_combo_id': str(combo_info_vo['id']), 'order_type': order_type,
+                      'store_meal_name': combo_info_vo['combo_name'],
+                      'trade_no': trade_no}
+        Order_Model.objects.create(**order_dict)
+        return order_id
+
+    @classmethod
+    def delete_card_package(cls, request_dict, response):
+        """
+        PC工具清空卡片的所有套餐订购记录
+        """
+        try:
+            LOGGER.info('*****WXTechController.delete_card_package:params:{}'.format(request_dict))
+            sign = request_dict.get('sign', None)
+            serial_no = request_dict.get('serialNo', None)
+            time_stamp = request_dict.get('timeStamp', None)
+            if not CommonService.check_time_stamp_token(sign, time_stamp):
+                return response.json(13)
                 # 查询是否注册iccid
-                unicom_device_qs = UnicomDeviceInfo.objects.filter(serial_no=serial_no) \
-                    .values('serial_no', 'user_id', 'iccid')
-                if not unicom_device_qs.exists():
-                    return response.json(173)
-                unicom_device_qs = unicom_device_qs.first()
-                iccid = unicom_device_qs['iccid']
-                # 查看是否体验过免费套餐
-                experience_history_qs = UnicomComboExperienceHistory.objects.filter(iccid=iccid)
-                if experience_history_qs.exists():
-                    return response.json(10062)
-                combo_info_qs = UnicomCombo.objects.filter(combo_type=1, status=0, is_del=False) \
-                    .values('combo_name')
-                if not combo_info_qs.exists():
-                    return response.json(173)
-                result = {'comboName': combo_info_qs[0]['combo_name']}
-                return response.json(0, result)
-            except Exception as e:
-                LOGGER.info('*****WXTechController.get_experience_package:errLine:{}, errMsg:{}'
-                            .format(e.__traceback__.tb_lineno, repr(e)))
-                return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            unicom_device_qs = UnicomDeviceInfo.objects.filter(serial_no=serial_no) \
+                .values('serial_no', 'user_id', 'iccid')
+            if not unicom_device_qs.exists():
+                return response.json(173)
+            iccid = unicom_device_qs[0]['iccid']
+            data = {'iccids': iccid, 'operator': WXOperatorEnum.TELECOM.value}
+            wx_tech = WXTechObject()
+            res = wx_tech.delete_card_package(**data)
+            if res['code'] == '0':
+                UnicomComboExperienceHistory.objects.filter(iccid=iccid).delete()
+                return response.json(0)
+            return response.json(177)
+        except Exception as e:
+            LOGGER.info('*****WXTechController.delete_card_package:errLine:{}, errMsg:{}'
+                        .format(e.__traceback__.tb_lineno, repr(e)))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
-        @classmethod
-        def create_order_package(cls, user_id, request_dict, response):
-            """
-            五兴电信领取1G15天流量体验包
-            """
-            try:
-                LOGGER.info('*****WXTechController.create_order_package:params:{}'.format(request_dict))
-                serial_no = request_dict.get('serialNo', None)
-                operator = request_dict.get('operator', None)
-                if not all([operator, serial_no]):
-                    return response.json(444)
-                serial_no = serial_no[0:9]
-                unicom_device_qs = UnicomDeviceInfo.objects.filter(serial_no=serial_no) \
-                    .values('serial_no', 'user_id', 'iccid')
-                if not unicom_device_qs.exists():
-                    return response.json(173)
-                unicom_device_qs = unicom_device_qs.first()
-                iccid = unicom_device_qs['iccid']
-                # 查看是否体验过免费套餐
-                experience_history_qs = UnicomComboExperienceHistory.objects.filter(iccid=iccid)
-                if experience_history_qs.exists():
-                    return response.json(10062)
-                data = {'iccid': iccid, 'operator': WXOperatorEnum(int(operator)).value,
-                        'startType': str(WXStartTypeEnum.EFFECTIVE_IMMEDIATELY.value), 'packageCode': COMBO_ID}
+    @classmethod
+    def wx_exchange_package(cls, request_dict, response, request, user_id):
+        """
+        使用兑换码订购五兴五年流量套餐包
+        """
+        ip = CommonService.get_ip_address(request)
+        try:
+            code = request_dict.get('code')
+            serial_number = request_dict.get('serialNumber')
+            LOGGER.info('*****WXTechController.wx_exchange_package:params,{}'.format(request_dict))
+            if not all([code, serial_number]):
+                return response.json(444)  # 参数缺失
+            # 校验兑换码格式是否正确
+            if not (code.isalnum() and len(code) == 10):
+                return response.json(10067)  # 兑换码格式错误
+            device_info_qs = UnicomDeviceInfo.objects.filter(serial_no=serial_number) \
+                .values('iccid', 'card_type')
+            if not device_info_qs.exists():
+                return response.json(173)  # 设备信息不存在
+            #  查询兑换码信息
+            exchange_code_qs = ExchangeCode.objects.filter(code=code, status=False) \
+                .values('package_id', 'expire_time', 'package_type')
+            if not exchange_code_qs.exists():
+                return response.json(10066)  # 兑换码无效
+            combo_id = exchange_code_qs[0]['package_id']
+            # 获取五兴套餐套餐编码
+            package_info_qs = UnicomCombo.objects.filter(id=combo_id, is_del=False) \
+                .values('package_id')
+            if not package_info_qs.exists():
+                return response.json(173)
+            package_code = package_info_qs[0]['package_id']
+            iccid = device_info_qs[0]['iccid']
+            # 兑换码套餐类型
+            card_type = device_info_qs[0]['card_type']
+            if card_type == 0:  # 联通无限流量兑换码
+                result = cls.exchange_unicom_package(serial_number, iccid,
+                                                     user_id, combo_id)
+                if result:
+                    exchange_code_qs.update(status=True, updated_time=int(time.time()))
+                    cls.save_log(ip, 10065, '兑换成功{},{}'.format(serial_number, code))
+                    return response.json(10065)
+            elif card_type == 1:  # 五兴电信无限流量兑换码
+                # 五兴订购流量包请求参数
+                data = {'iccid': iccid, 'operator': WXOperatorEnum.TELECOM.value,
+                        'startType': str(WXStartTypeEnum.EFFECTIVE_IMMEDIATELY.value), 'packageCode': package_code}
                 wx_tech = WXTechObject()
-                # 请求五兴API创建套餐接口
+                # 请求五兴API订购套餐接口
                 res = wx_tech.create_order_package(**data)
-                LOGGER.info('*****五兴创建体验套餐信息:{}'.format(res))
+                LOGGER.info('*****五兴订购年卡套餐结果:{}'.format(res))
                 if res['code'] == '0':
                     trade_no = res['data']['orderNumber']
-                    experience_history_vo = {'iccid': iccid, 'experience_type': 0, 'do_time': int(time.time())}
-                    UnicomComboExperienceHistory.objects.create(**experience_history_vo)
-                    order_res = cls.created_order(serial_no, user_id, trade_no, pay_type=10)
-                    UnicomDeviceInfo.objects.filter(serial_no=serial_no) \
-                        .update(user_id=user_id, updated_time=int(time.time()))
-                    LOGGER.info('*****系统创建体验订单:{}'.format(order_res))
-                    return response.json(0)
-                return response.json(10063)
-            except Exception as e:
-                LOGGER.info('*****WXTechController.create_order_package:errLine:{}, errMsg:{}'
-                            .format(e.__traceback__.tb_lineno, repr(e)))
-                return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+                    cls.created_order(serial_number, user_id, trade_no, combo_id, 11)
+                    exchange_code_qs.update(status=True, updated_time=int(time.time()))
+                    cls.save_log(ip, 10065, '兑换成功{},{}'.format(serial_number, code))
+                    return response.json(10065)
+            cls.save_log(ip, 10068, '兑换失败{},{}'.format(serial_number, code))
+            return response.json(10068)
+        except Exception as e:
+            LOGGER.info('*****WXTechController.wx_exchange_package:errLine:{}, errMsg:{}'
+                        .format(e.__traceback__.tb_lineno, repr(e)))
+            cls.save_log(ip, 500, '兑换内部错误')
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
-        @classmethod
-        def created_order(cls, serial_no, user_id, trade_no, combo_id=None, pay_type=10, order_type=3):
-            """
-            创建系统订单
-            """
-            combo_info_qs = UnicomCombo.objects.filter(is_del=False)
-            if combo_id:
-                combo_info_qs = combo_info_qs.filter(id=int(combo_id))
-            else:
-                combo_info_qs = combo_info_qs.filter(combo_type=1, status=0)
-            combo_info_qs = combo_info_qs.values('id', 'combo_name', 'price', 'virtual_price', 'remark') \
-                .order_by('sort')
-            if not combo_info_qs.exists():
-                return False
-            combo_info_vo = combo_info_qs[0]
-            n_time = int(time.time())
-            # 根据序列号获取UID
-            uid = CommonService.query_uid_with_serial(serial_no)
-            order_id = CommonService.createOrderID()
-            # 生成订单必须添加该字段
-            rank_id, ai_rank_id = UnicomComboView().get_cloud_or_ai_combo()
-            order_dict = {'orderID': order_id, 'UID': uid, 'rank_id': rank_id, 'ai_rank_id': ai_rank_id,
-                          'userID_id': user_id, 'desc': combo_info_vo['combo_name'], 'payType': pay_type,
-                          'payTime': n_time, 'price': combo_info_vo['price'], 'addTime': n_time,
-                          'updTime': n_time, 'status': 1, 'currency': 'CNY',
-                          'unify_combo_id': str(combo_info_vo['id']), 'order_type': order_type,
-                          'store_meal_name': combo_info_vo['combo_name'],
-                          'trade_no': trade_no}
-            Order_Model.objects.create(**order_dict)
-            return order_id
+    @classmethod
+    def exchange_unicom_package(cls, serial_number, iccid, user_id, combo_id):
+        try:
+            # 通过兑换码创建订单记录
+            order_id = cls.created_order(serial_number, user_id, 'ansjer', combo_id, 11, 2)
+            # 根据订单信息创建流量套餐包
+            UnicomComboView.create_combo_order_info(order_id, 0, iccid, combo_id)
+            return True
+        except Exception as e:
+            LOGGER.info('*****WXTechController.exchange_unicom_package:errLine:{}, errMsg:{}'
+                        .format(e.__traceback__.tb_lineno, repr(e)))
+            return False
 
-        @classmethod
-        def delete_card_package(cls, request_dict, response):
-            """
-            PC工具清空卡片的所有套餐订购记录
-            """
-            try:
-                LOGGER.info('*****WXTechController.delete_card_package:params:{}'.format(request_dict))
-                sign = request_dict.get('sign', None)
-                serial_no = request_dict.get('serialNo', None)
-                time_stamp = request_dict.get('timeStamp', None)
-                if not CommonService.check_time_stamp_token(sign, time_stamp):
-                    return response.json(13)
-                    # 查询是否注册iccid
-                unicom_device_qs = UnicomDeviceInfo.objects.filter(serial_no=serial_no) \
-                    .values('serial_no', 'user_id', 'iccid')
-                if not unicom_device_qs.exists():
-                    return response.json(173)
-                iccid = unicom_device_qs[0]['iccid']
-                data = {'iccids': iccid, 'operator': WXOperatorEnum.TELECOM.value}
-                wx_tech = WXTechObject()
-                res = wx_tech.delete_card_package(**data)
-                if res['code'] == '0':
-                    UnicomComboExperienceHistory.objects.filter(iccid=iccid).delete()
-                    return response.json(0)
-                return response.json(177)
-            except Exception as e:
-                LOGGER.info('*****WXTechController.delete_card_package:errLine:{}, errMsg:{}'
-                            .format(e.__traceback__.tb_lineno, repr(e)))
-                return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+    @staticmethod
+    def save_log(ip, code, operation):
+        """
+        保存操作日志
+        @param ip: ip地址
+        @param code: 状态码
+        @param operation: 操作说明
+        @return: 保存结果
+        """
+        try:
+            log = {
+                'ip': ip,
+                'user_id': 1,
+                'status': code,
+                'time': int(time.time()),
+                'operation': operation,
+                'url': 'unicom/open/wxtech/exchangePackage',
+            }
+            LogModel.objects.create(**log)
+            return True
+        except Exception as e:
+            LOGGER.info('*****WXTechController.save_log:errLine:{}, errMsg:{}'
+                        .format(e.__traceback__.tb_lineno, repr(e)))
+            return False
 
-        @classmethod
-        def wx_exchange_package(cls, request_dict, response, request, user_id):
-            """
-            使用兑换码订购五兴五年流量套餐包
-            """
-            ip = CommonService.get_ip_address(request)
-            try:
-                code = request_dict.get('code')
-                serial_number = request_dict.get('serialNumber')
-                LOGGER.info('*****WXTechController.wx_exchange_package:params,{}'.format(request_dict))
-                if not all([code, serial_number]):
-                    return response.json(444)  # 参数缺失
-                # 校验兑换码格式是否正确
-                if not (code.isalnum() and len(code) == 10):
-                    return response.json(10067)  # 兑换码格式错误
-                device_info_qs = UnicomDeviceInfo.objects.filter(serial_no=serial_number) \
-                    .values('iccid', 'card_type')
-                if not device_info_qs.exists():
-                    return response.json(173)  # 设备信息不存在
-                #  查询兑换码信息
-                exchange_code_qs = ExchangeCode.objects.filter(code=code, status=False) \
-                    .values('package_id', 'expire_time', 'package_type')
-                if not exchange_code_qs.exists():
-                    return response.json(10066)  # 兑换码无效
-                combo_id = exchange_code_qs[0]['package_id']
-                # 获取五兴套餐套餐编码
-                package_info_qs = UnicomCombo.objects.filter(id=combo_id, is_del=False) \
-                    .values('package_id')
-                if not package_info_qs.exists():
-                    return response.json(173)
-                package_code = package_info_qs[0]['package_id']
-                iccid = device_info_qs[0]['iccid']
-                # 兑换码套餐类型
-                card_type = device_info_qs[0]['card_type']
-                if card_type == 0:  # 联通无限流量兑换码
-                    result = cls.exchange_unicom_package(serial_number, iccid,
-                                                         user_id, combo_id)
-                    if result:
-                        exchange_code_qs.update(status=True, updated_time=int(time.time()))
-                        cls.save_log(ip, 10065, '兑换成功{},{}'.format(serial_number, code))
-                        return response.json(10065)
-                elif card_type == 1:  # 五兴电信无限流量兑换码
-                    # 五兴订购流量包请求参数
-                    data = {'iccid': iccid, 'operator': WXOperatorEnum.TELECOM.value,
-                            'startType': str(WXStartTypeEnum.EFFECTIVE_IMMEDIATELY.value), 'packageCode': package_code}
-                    wx_tech = WXTechObject()
-                    # 请求五兴API订购套餐接口
-                    res = wx_tech.create_order_package(**data)
-                    LOGGER.info('*****五兴订购年卡套餐结果:{}'.format(res))
-                    if res['code'] == '0':
-                        trade_no = res['data']['orderNumber']
-                        cls.created_order(serial_number, user_id, trade_no, combo_id, 11)
-                        exchange_code_qs.update(status=True, updated_time=int(time.time()))
-                        cls.save_log(ip, 10065, '兑换成功{},{}'.format(serial_number, code))
-                        return response.json(10065)
-                cls.save_log(ip, 10068, '兑换失败{},{}'.format(serial_number, code))
-                return response.json(10068)
-            except Exception as e:
-                LOGGER.info('*****WXTechController.wx_exchange_package:errLine:{}, errMsg:{}'
-                            .format(e.__traceback__.tb_lineno, repr(e)))
-                cls.save_log(ip, 500, '兑换内部错误')
-                return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+    @classmethod
+    def get_package_by_serial_number(cls, request_dict, response, request, user_id):
+        """
+        根据序列号获取无限流量套餐信息
+        """
+        try:
+            serial_number = request_dict.get('serialNumber', None)
+            if not serial_number:
+                return response.json(444)
+            serial_package_qs = SerialNumberPackage.objects.filter(serial_number=serial_number, status=1)
+            data = {}
+            if not serial_package_qs:
+                return response.json(0, data)
+            serial_package = serial_package_qs.first()
+            package_id = serial_package.package_id
+            package_info_qs = UnicomCombo.objects.filter(id=package_id).values('combo_name')
+            if not package_info_qs.exists():
+                return response.json(0, data)
+            result = {'comboName': package_info_qs[0]['combo_name']}
+            return response.json(110, result)
+        except Exception as e:
+            LOGGER.info('*****WXTechController.get_package_by_serial_number:errLine:{}, errMsg:{}'
+                        .format(e.__traceback__.tb_lineno, repr(e)))
+            return response.json(503)
 
-        @classmethod
-        def exchange_unicom_package(cls, serial_number, iccid, user_id, combo_id):
-            try:
-                # 通过兑换码创建订单记录
-                order_id = cls.created_order(serial_number, user_id, 'ansjer', combo_id, 11, 2)
-                # 根据订单信息创建流量套餐包
-                UnicomComboView.create_combo_order_info(order_id, 0, iccid, combo_id)
-                return True
-            except Exception as e:
-                LOGGER.info('*****WXTechController.exchange_unicom_package:errLine:{}, errMsg:{}'
-                            .format(e.__traceback__.tb_lineno, repr(e)))
-                return False
+    @classmethod
+    def create_4G_flow_package(cls, request_dict, response, request, user_id):
+        """
+        创建4G流量套餐(出厂序列号绑定套餐)
+        """
+        ip = CommonService.get_ip_address(request)
+        serial_number = ''
+        try:
+            serial_number = request_dict.get('serialNumber')
+            if not serial_number:
+                return response.json(0)
+            device_info_qs = UnicomDeviceInfo.objects.filter(serial_no=serial_number) \
+                .values('iccid', 'card_type')
+            if not device_info_qs.exists():
+                return response.json(173)  # 设备信息不存在
 
-        @staticmethod
-        def save_log(ip, code, operation):
-            """
-            保存操作日志
-            @param ip: ip地址
-            @param code: 状态码
-            @param operation: 操作说明
-            @return: 保存结果
-            """
-            try:
-                log = {
-                    'ip': ip,
-                    'user_id': 1,
-                    'status': code,
-                    'time': int(time.time()),
-                    'operation': operation,
-                    'url': 'unicom/open/wxtech/exchangePackage',
-                }
-                LogModel.objects.create(**log)
-                return True
-            except Exception as e:
-                LOGGER.info('*****WXTechController.save_log:errLine:{}, errMsg:{}'
-                            .format(e.__traceback__.tb_lineno, repr(e)))
-                return False
+            serial_package_qs = SerialNumberPackage.objects.filter(serial_number=serial_number, status=1)
+            if not serial_package_qs:
+                return response.json(10064)
 
-        @classmethod
-        def get_package_by_serial_number(cls, request_dict, response, request, user_id):
-            """
-            根据序列号获取无限流量套餐信息
-            """
-            try:
-                serial_number = request_dict.get('serialNumber', None)
-                if not serial_number:
-                    return response.json(444)
-                serial_package_qs = SerialNumberPackage.objects.filter(serial_number=serial_number, status=1)
-                data = {}
-                if not serial_package_qs:
-                    return response.json(0, data)
-                serial_package = serial_package_qs.first()
-                package_id = serial_package.package_id
-                package_info_qs = UnicomCombo.objects.filter(id=package_id).values('combo_name')
-                if not package_info_qs.exists():
-                    return response.json(0, data)
-                result = {'comboName': package_info_qs[0]['combo_name']}
-                return response.json(110, result)
-            except Exception as e:
-                LOGGER.info('*****WXTechController.get_package_by_serial_number:errLine:{}, errMsg:{}'
-                            .format(e.__traceback__.tb_lineno, repr(e)))
-                return response.json(503)
+            combo_id = serial_package_qs.first().package_id
+            # 获取餐套餐信息
+            package_info_qs = UnicomCombo.objects.filter(id=combo_id, is_del=False) \
+                .values('package_id', 'combo_name')
+            if not package_info_qs.exists():
+                return response.json(173)
+            # 得到五兴电信运营商套餐编码
+            package_code = package_info_qs[0]['package_id']
+            combo_name = package_info_qs[0]['combo_name']
+            iccid = device_info_qs[0]['iccid']
 
-        @classmethod
-        def create_4G_flow_package(cls, request_dict, response, request, user_id):
-            """
-            创建4G流量套餐(出厂序列号绑定套餐)
-            """
-            ip = CommonService.get_ip_address(request)
-            serial_number = ''
-            try:
-                serial_number = request_dict.get('serialNumber')
-                if not serial_number:
-                    return response.json(0)
-                device_info_qs = UnicomDeviceInfo.objects.filter(serial_no=serial_number) \
-                    .values('iccid', 'card_type')
-                if not device_info_qs.exists():
-                    return response.json(173)  # 设备信息不存在
+            n_time = int(time.time())
+            # 兑换码套餐类型
+            card_type = device_info_qs[0]['card_type']
+            if card_type == 0:  # 订购联通流量套餐
+                result = cls.exchange_unicom_package(serial_number, iccid,
+                                                     user_id, combo_id)
+                serial_package_qs.update(status=2, updated_time=n_time, updated_by=user_id)
+                if result:
+                    cls.save_log(ip, 10071, '{}领取{}成功{}'.format(serial_number, combo_name, user_id))
+                    return response.json(10071)
+            elif card_type == 1:  # 订购五兴电信流量套餐
+                # 五兴订购流量包请求参数
+                data = {'iccid': iccid, 'operator': WXOperatorEnum.TELECOM.value,
+                        'startType': str(WXStartTypeEnum.EFFECTIVE_IMMEDIATELY.value), 'packageCode': package_code}
+                wx_tech = WXTechObject()
+                # 请求五兴API订购套餐接口
+                res = wx_tech.create_order_package(**data)
+                LOGGER.info('*****五兴订购套餐结果:{}'.format(res))
+                if res['code'] == '0':
+                    trade_no = res['data']['orderNumber']
+                    cls.created_order(serial_number, user_id, trade_no, combo_id, 11)
+                    serial_package_qs.update(status=2, updated_time=n_time, updated_by=user_id)
+                    cls.save_log(ip, 10071, '{}领取{}成功{}'.format(serial_number, combo_name, user_id))
+                    return response.json(10071)
 
-                serial_package_qs = SerialNumberPackage.objects.filter(serial_number=serial_number, status=1)
-                if not serial_package_qs:
-                    return response.json(10064)
+            cls.save_log(ip, 10064, '无效卡类型{}领取{}失败{}'.format(serial_number, combo_name, user_id))
+            return response.json(10064)
+        except Exception as e:
+            LOGGER.info('*****WXTechController.wx_exchange_package:errLine:{}, errMsg:{}'
+                        .format(e.__traceback__.tb_lineno, repr(e)))
+            cls.save_log(ip, 500, f'{serial_number}领取流量套餐异常')
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
-                combo_id = serial_package_qs.first().package_id
-                # 获取餐套餐信息
-                package_info_qs = UnicomCombo.objects.filter(id=combo_id, is_del=False) \
-                    .values('package_id', 'combo_name')
-                if not package_info_qs.exists():
-                    return response.json(173)
-                # 得到五兴电信运营商套餐编码
-                package_code = package_info_qs[0]['package_id']
-                combo_name = package_info_qs[0]['combo_name']
-                iccid = device_info_qs[0]['iccid']
+    @classmethod
+    def activate_flow_package(cls, serial_number, ip, user_id):
+        """
+        激活序列号出厂绑定无限流量套餐
+        @param serial_number: 9位序列号
+        @param ip: ip地址
+        @param user_id: 用户id
+        @return: True | False
+        """
+        try:
+            if not serial_number:
+                return False
+            serial_package_qs = SerialNumberPackage.objects.filter(serial_number=serial_number, status=1)
+            if not serial_package_qs:
+                return False
+            device_info_qs = UnicomDeviceInfo.objects.filter(serial_no=serial_number) \
+                .values('iccid', 'card_type')
+            if not device_info_qs.exists():
+                LOGGER.info('*****激活无限流量iccid不存在:{}'.format(serial_number))
+                return False
+            combo_id = serial_package_qs.first().package_id
+            # 获取餐套餐信息
+            package_info_qs = UnicomCombo.objects.filter(id=combo_id, is_del=False) \
+                .values('package_id', 'combo_name')
+            if not package_info_qs.exists():
+                return False
+            # 得到五兴电信运营商套餐编码
+            n_time = int(time.time())
+            iccid = device_info_qs[0]['iccid']
+            package_code = package_info_qs[0]['package_id']
+            combo_name = package_info_qs[0]['combo_name']
 
-                n_time = int(time.time())
-                # 兑换码套餐类型
-                card_type = device_info_qs[0]['card_type']
-                if card_type == 0:  # 订购联通流量套餐
-                    result = cls.exchange_unicom_package(serial_number, iccid,
-                                                         user_id, combo_id)
+            # 兑换码套餐类型
+            card_type = device_info_qs[0]['card_type']
+            if card_type == 0:  # 订购联通流量套餐
+                result = cls.exchange_unicom_package(serial_number, iccid,
+                                                     user_id, combo_id)
+                serial_package_qs.update(status=2, updated_time=n_time, updated_by=user_id)
+                if result:
+                    cls.save_log(ip, 10071, '{}领取{}成功{}'.format(serial_number, combo_name, user_id))
+                    return True
+            elif card_type == 1:  # 订购五兴电信流量套餐
+                # 五兴订购流量包请求参数
+                data = {'iccid': iccid, 'operator': WXOperatorEnum.TELECOM.value,
+                        'startType': str(WXStartTypeEnum.EFFECTIVE_IMMEDIATELY.value), 'packageCode': package_code}
+                wx_tech = WXTechObject()
+                # 请求五兴API订购套餐接口
+                res = wx_tech.create_order_package(**data)
+                LOGGER.info('*****五兴订购套餐结果:{}'.format(res))
+                if res['code'] == '0':
+                    trade_no = res['data']['orderNumber']
+                    cls.created_order(serial_number, user_id, trade_no, combo_id, 11)
                     serial_package_qs.update(status=2, updated_time=n_time, updated_by=user_id)
-                    if result:
-                        cls.save_log(ip, 10071, '{}领取{}成功{}'.format(serial_number, combo_name, user_id))
-                        return response.json(10071)
-                elif card_type == 1:  # 订购五兴电信流量套餐
-                    # 五兴订购流量包请求参数
-                    data = {'iccid': iccid, 'operator': WXOperatorEnum.TELECOM.value,
-                            'startType': str(WXStartTypeEnum.EFFECTIVE_IMMEDIATELY.value), 'packageCode': package_code}
-                    wx_tech = WXTechObject()
-                    # 请求五兴API订购套餐接口
-                    res = wx_tech.create_order_package(**data)
-                    LOGGER.info('*****五兴订购套餐结果:{}'.format(res))
-                    if res['code'] == '0':
-                        trade_no = res['data']['orderNumber']
-                        cls.created_order(serial_number, user_id, trade_no, combo_id, 11)
-                        serial_package_qs.update(status=2, updated_time=n_time, updated_by=user_id)
-                        cls.save_log(ip, 10071, '{}领取{}成功{}'.format(serial_number, combo_name, user_id))
-                        return response.json(10071)
+                    cls.save_log(ip, 10071, '{}领取{}成功{}'.format(serial_number, combo_name, user_id))
+                    return True
 
-                cls.save_log(ip, 10064, '无效卡类型{}领取{}失败{}'.format(serial_number, combo_name, user_id))
-                return response.json(10064)
-            except Exception as e:
-                LOGGER.info('*****WXTechController.wx_exchange_package:errLine:{}, errMsg:{}'
-                            .format(e.__traceback__.tb_lineno, repr(e)))
-                cls.save_log(ip, 500, f'{serial_number}领取流量套餐异常')
-                return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            cls.save_log(ip, 10064, '无效卡类型{}领取{}失败{}'.format(serial_number, combo_name, user_id))
+            return False
+        except Exception as e:
+            LOGGER.info('*****WXTechController.activate_flow_package:errLine:{}, errMsg:{}'
+                        .format(e.__traceback__.tb_lineno, repr(e)))
+            cls.save_log(ip, 500, f'{serial_number}领取流量套餐异常')
+            return False