| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536 | # -*- encoding: utf-8 -*-"""@File    : WXTechController.py@Time    : 2023/5/6 16:40@Author  : stephen@Email   : zhangdongming@asj6.wecom.work@Software: PyCharm"""import timefrom django.http import QueryDictfrom django.views import Viewfrom Ansjer.config import LOGGERfrom Controller.UnicomCombo.UnicomComboController import UnicomComboViewfrom Model.models import UnicomDeviceInfo, Order_Model, UnicomComboExperienceHistory, UnicomCombo, ExchangeCode, \    LogModel, SerialNumberPackagefrom Object.Enums.WXOperatorEnum import WXOperatorEnumfrom Object.Enums.WXStartTypeEnum import WXStartTypeEnumfrom Object.ResponseObject import ResponseObjectfrom Object.WXTechObject import WXTechObjectfrom Service.CommonService import CommonService# 五兴科技电信套餐编码 1G-15天流量包COMBO_ID = 'DX-DX-FDX-JCB-1G-15天-4DX-ASJ-YTC-AT-2022123020221230144615'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 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 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, request)        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.get_uid_by_serial_number(serial_number)            order_info_qs = Order_Model.objects.filter(UID=uid, order_type=3).values('trade_no') \                .order_by('-payTime')            if not order_info_qs.exists():                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_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, request):        """        五兴电信领取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', 'card_type')            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)            ip = CommonService.get_ip_address(request)            experience_history_vo = {'iccid': iccid, 'experience_type': 0, 'do_time': int(time.time())}            app_user_id = unicom_device_qs['user_id'] if unicom_device_qs['user_id'] else user_id            if unicom_device_qs['card_type'] == 0:  # 珠海联通                flow_combo_qs = UnicomCombo.objects.filter(combo_type=1, is_del=False, status=0).order_by('sort')                free_result = False                if flow_combo_qs.exists():                    # 生成免费体验套餐                    free_result = UnicomComboView() \                        .generate_flow_package(serial_no, flow_combo_qs.first().id, app_user_id)                    UnicomComboExperienceHistory.objects.create(**experience_history_vo)                if not unicom_device_qs['user_id']:                    UnicomDeviceInfo.objects.filter(iccid=iccid) \                        .update(user_id=app_user_id, updated_time=int(time.time()))                factory_result = cls.activate_flow_package(serial_no, ip, app_user_id)  # 检测并激活出厂无限流量                cls.save_log(ip, 0, '{}激活免费套餐{},出厂无限流量{}'.format(serial_no, free_result, factory_result))                return response.json(0)            elif unicom_device_qs['card_type'] == 1:  # 五兴电信                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']                    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))                    factory_result = cls.activate_flow_package(serial_no, ip, app_user_id)  # 检测并激活出厂无限流量                    cls.save_log(ip, 0, '{}激活免费套餐{},出厂无限流量{}'.format(serial_no, True, factory_result))                    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 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.get_uid_by_serial_number(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)            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 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()))                    # 校验是否两个重叠无限流量套餐 修改套餐数据                    UnicomComboView().update_flow_package_order_by_iccid(iccid)                    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 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    @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 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 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)  # 设备信息不存在            serial_package_qs = SerialNumberPackage.objects.filter(serial_number=serial_number, status=1)            if not serial_package_qs:                return response.json(10064)            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']            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)            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)))    @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']            # 兑换码套餐类型            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)                    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 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
 |