| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963 | import jsonimport loggingimport threadingimport timefrom datetime import datetimeimport requestsfrom django.db import transactionfrom django.views import Viewfrom Ansjer.config import CRCKey, CONFIG_INFO, CONFIG_US, CONFIG_EUR, \    CONFIG_CN, USED_SERIAL_REDIS_LIST, UNUSED_SERIAL_REDIS_LIST, SERVER_DOMAIN_US, REGION_ID_LIST, SERVER_DOMAIN_TEST, \    SERVER_DOMAIN_LIST, SERVER_DOMAIN_CN, SERVER_DOMAIN_EUR, RESET_REGION_ID_SERIAL_REDIS_LIST, LOGGERfrom Controller.UnicomCombo.UnicomComboController import UnicomComboViewfrom Model.models import SerialNumberModel, CompanySerialModel, UIDCompanySerialModel, UIDModel, Device_Info, \    iotdeviceInfoModel, LogModel, UidSetModel, UID_Bucket, \    Unused_Uid_Meal, Order_Model, StsCrdModel, VodHlsModel, ExperienceContextModel, UidUserModel, ExperienceAiModel, \    AiService, DeviceDomainRegionModel, RegionModel, UidPushModel, AppScannedSerial, Device_User, SerialUnbindUIDfrom Object.AWS.S3Email import S3Emailfrom Object.RedisObject import RedisObjectfrom Object.TokenObject import TokenObjectfrom Object.uidManageResponseObject import uidManageResponseObjectfrom Service.AlgorithmService import AlgorithmBaseOn35from Service.CommonService import CommonServicefrom Service.EquipmentInfoService import EquipmentInfoServicefrom Service.VodHlsService import SplitVodHlsObjectfrom AdminController.CloudServiceManage.AgentDeviceController import AgentDeviceViewclass SerialNumberView(View):    def get(self, request, *args, **kwargs):        request.encoding = 'utf-8'        operation = kwargs.get('operation', None)        request_dict = request.GET        return self.validate(request_dict, operation, request)    def post(self, request, *args, **kwargs):        request.encoding = 'utf-8'        operation = kwargs.get('operation', None)        request_dict = request.POST        return self.validate(request_dict, operation, request)    def validate(self, request_dict, operation, request):        response = uidManageResponseObject()        if operation == 'attachUID':  # 绑定uid            return self.do_attach_uid(request_dict, response, request)        elif operation == 'detachUID':  # 解绑uid            return self.do_detach_uid(request, request_dict, response)        elif operation == 'get-uid':  # app获取uid            token_code, user_id, res = CommonService.verify_token_get_user_id(request_dict, request)            return self.get_uid(request_dict, response, request, user_id)        elif operation == 'create':  # 创建序列号            return self.do_create(request_dict, response)        elif operation == 'getUID':  # 根据序列号获取uid            return self.do_get_uid(request_dict, response)        elif operation == 'getRegionInfo':  # 根据序列号状态确认uid地区(PC工具使用)            return self.get_region_info(request_dict, response)        elif operation == 'saveRegion':  # 保存设备地区信息(app使用)            return self.save_region(request, request_dict, response)        elif operation == 'getDomain':  # 获取域名(设备使用)            return self.get_domain(request_dict, response)        elif operation == 'resetRegionId':  # 重置地区id            return self.reset_region_id(request_dict, response)        elif operation == 'get-status':  # 获取序列号绑定信息            return self.check_serial_status(request_dict, response)        elif operation == 'getUidRegion':  # 根据序列号获取uid地区            return self.get_uid_region(request_dict, response)        elif operation == 'getGlobalUidRegion':  # 获取序列号在全球服绑定uid的地区            return self.get_global_uid_region(request_dict, response)        elif operation == 'getIoTCoreBySerialNumber':  # 根据序列号获取iot core            return self.get_iot_core_by_serial_number(request_dict, response)        else:            return response.json(414)    @staticmethod    def do_create(request_dict, response):        quantity = int(request_dict.get('quantity', 0))        if not quantity:            return response.json(444)        try:            try:                number = SerialNumberModel.objects.last().id            except:                number = 0            serial_number_bulk = []            now_time = int(time.time())            algorithm = AlgorithmBaseOn35()            for i in range(quantity):                serial_number = algorithm.getLetter(number)                number += 1  # sum每次递增1                # 前面补0至六位                serial_number = (6 - len(serial_number)) * '0' + serial_number                serial_number_bulk.append(SerialNumberModel(serial_number=serial_number, add_time=now_time))            # 开启事务写入            with transaction.atomic():                SerialNumberModel.objects.bulk_create(serial_number_bulk)            return response.json(0)        except Exception as e:            print(e)            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))    def do_attach_uid(self, request_dict, response, request):        serial_number = request_dict.get('serial_number', None)        token = request_dict.get('token', None)        time_stamp = request_dict.get('time_stamp', None)        is_verify = request_dict.get('is_verify', None)        if not all([serial_number, token, time_stamp]):            return response.json(444)        # 时间戳token校验        if not CommonService.check_time_stamp_token(token, time_stamp):            return response.json(13)        now_time = int(time.time())        serial = serial_number[0:6]        company_identity = serial_number[6:9]        full_serial = serial_number[0:9]        # 根据企业标识确认企业秘钥        company_secret = ''        if company_identity == '11A':            company_secret = 'MTEyMTNB'        elif company_identity == '11L':            company_secret = 'VmXEWnBR'        elif company_identity == '11Z':            company_secret = 'ZsKWcxdD'        try:            # 判断序列号是否刚解绑,刚解绑1分钟内不能进行绑定            redisObj = RedisObject()            unused_serial_redis_list = redisObj.lrange(UNUSED_SERIAL_REDIS_LIST, 0, -1)            unused_serial_redis_list = [str(i, 'utf-8') for i in unused_serial_redis_list]            if serial in unused_serial_redis_list:                return response.json(5)            # 判断序列号是否未清除uid数据            serial_unbind_uid_qs = SerialUnbindUID.objects.filter(serial=serial, status=0)            if serial_unbind_uid_qs.exists():                return response.json(5)            # 判断序列号是否已和企业关联            company_serial_qs = CompanySerialModel.objects.filter(company__secret=company_secret, serial_number=serial)            if not company_serial_qs.exists():                return response.json(173)            company_serial = company_serial_qs[0]            if company_serial.status == 0:  # 该序列号未绑定企业                return response.json(173)            elif company_serial.status == 1:  # 绑定uid                # is_verify: '1',跳过查询扫码记录                if is_verify == '1':                    region_country = 0                else:                    # 查询app是否已扫码,未扫码不能进行绑定                    app_scanned_serial_qs = AppScannedSerial.objects.filter(serial=serial).values('region_country')                    if not app_scanned_serial_qs.exists():                        LOGGER.info(f'{serial}当前序列号未进行APP扫码')                        return response.json(5)                    region_country = app_scanned_serial_qs[0]['region_country']                # redis加锁,防止同一个序列号重复绑定                key = serial + 'do_attach_uid'                is_lock = redisObj.CONN.setnx(key, 1)                if not is_lock:                    return response.json(5)                redisObj.CONN.expire(key, 60)                # 获取并判断region_id                region_id = CommonService.confirm_region_id(region_country)                if region_id not in REGION_ID_LIST:                    return response.json(444, {'invalid region_id': region_id})                # 获取p2p类型                p2p_type = request_dict.get('p2ptype', None)                if serial_number[9:10]:                    p2p_type = serial_number[9:10]                elif not p2p_type:                    return response.json(444, {'param': 'p2ptype'})                p2p_type = int(p2p_type)                with transaction.atomic():                    count = 0                    while count < 3:                        # 查询是否存在未绑定序列号的uid                        uid_qs = UIDModel.objects.filter(vpg__company_id=company_serial.company.id,                                                         vpg__region_id=region_id, status=0, p2p_type=p2p_type). \                            order_by('update_time')                        if not uid_qs.exists():                            return response.json(375)                        uid = uid_qs[0]                        # 判断uid是否已绑定过序列号                        uid_company_serial_qs = UIDCompanySerialModel.objects.filter(uid_id=uid.id)                        if uid_company_serial_qs.exists():                            return response.json(377)                        result = UIDModel.objects.filter(id=uid.id, status=0).update(status=2, update_time=now_time)                        if int(result) <= 0:  # 更新失败                            count += 1                            continue                        # UID关联【企业关联序列号】表创建数据                        UIDCompanySerialModel.objects.create(uid_id=uid.id, company_serial_id=company_serial.id,                                                             add_time=now_time, update_time=now_time)                        company_serial.status = 2                        company_serial.update_time = now_time                        company_serial.save()                        dev = Device_Info.objects.filter(UID=uid.uid)                        if dev.exists():                            dev.update(serial_number=full_serial)                        full_uid_code = uid.full_uid_code                        if uid.platform in CRCKey.keys():                            full_uid_code += ':' + CRCKey[uid.platform]                        res = {                            'full_uid_code': CommonService.encode_data(full_uid_code),                            'uid': CommonService.encode_data(uid.uid),                            'extra': uid.uid_extra,                            'platform': uid.platform,                            'initString': uid.init_string,                            'initStringApp': uid.init_string_app,                        }                        # 记录操作日志                        ip = CommonService.get_ip_address(request)                        content = json.loads(json.dumps(request_dict))                        log = {                            'ip': ip,                            'user_id': 1,                            'status': 200,                            'time': now_time,                            'content': json.dumps(content),                            'url': 'serialNumber/attachUID',                            'operation': '序列号{}绑定uid: {}'.format(serial, uid.uid),                        }                        LogModel.objects.create(**log)                        redisObj.del_data(key=key)                        # 处理序列号状态和计算剩余uid数量线程                        thread = threading.Thread(target=self.rpush_serial_and_count_uid, args=(serial, p2p_type,                                                                                                redisObj))                        thread.start()                        # 异步调用客户代理平台同步序列号绑定UID                        agent_thread = threading.Thread(target=AgentDeviceView.device_binding_or_unbinding,                                                        args=(full_serial, 1))                        agent_thread.start()                        return response.json(0, res)                    return response.json(5)            elif company_serial.status == 2:  # 返回uid                res = self.get_uid_info_by_serial(company_serial.id)                # 记录操作日志                ip = CommonService.get_ip_address(request)                content = json.loads(json.dumps(request_dict))                log = {                    'ip': ip,                    'user_id': 1,                    'status': 200,                    'time': now_time,                    'content': json.dumps(content),                    'url': 'serialNumber/attachUID',                    'operation': '序列号{}获取uid: {}'.format(serial, CommonService.decode_data(res['uid'])),                }                LogModel.objects.create(**log)                return response.json(0, res)            elif company_serial.status == 3:  # 已占用                sync_success = self.sync_serial_data_and_log(request, company_serial.id, serial_number, now_time)                if not sync_success:                    return response.json(10042)                return response.json(0, self.get_uid_info_by_serial(company_serial.id))        except Exception as e:            djangoLogger = logging.getLogger('django')            djangoLogger.exception(repr(e))            return response.json(176, str(e))    @classmethod    def get_uid_info_by_serial(cls, company_serial_id):        """        根据企业关联序列号ID返回UID信息        """        uid_qs = UIDCompanySerialModel.objects.filter(company_serial_id=company_serial_id)        if not uid_qs.exists():            return {}        uid = uid_qs.values('uid__uid', 'uid__mac', 'uid__uid_extra', 'uid__full_uid_code',                            'uid__platform', 'uid__init_string', 'uid__init_string_app')[0]        full_uid_code = uid['uid__full_uid_code']        if uid['uid__platform'] in CRCKey.keys():            full_uid_code += ':' + CRCKey[uid['uid__platform']]        res = {            'full_uid_code': CommonService.encode_data(full_uid_code),            'uid': CommonService.encode_data(uid['uid__uid']),            'extra': uid['uid__uid_extra'],            'platform': uid['uid__platform'],            'initString': uid['uid__init_string'],            'initStringApp': uid['uid__init_string_app'],        }        return res    @classmethod    def check_serial_status(cls, request_dict, response):        serial_number = request_dict.get('serial_number', None)        if not serial_number:            return response.json(444)        serial = serial_number[0:6]        company_identity = serial_number[6:9]        # 根据企业标识确认企业秘钥        company_secret = ''        if company_identity == '11A':            company_secret = 'MTEyMTNB'        elif company_identity == '11L':            company_secret = 'VmXEWnBR'        elif company_identity == '11Z':            company_secret = 'ZsKWcxdD'        try:            # 判断序列号是否已和企业关联            company_serial_qs = CompanySerialModel.objects.filter(company__secret=company_secret, serial_number=serial)            if not company_serial_qs.exists():                return response.json(173)            company_serial = company_serial_qs[0]            # 获取企业序列号是否绑定UID            uid_company_qs = UIDCompanySerialModel.objects.filter(company_serial_id=company_serial.id) \                .values('uid__uid', 'uid__mac', 'uid__uid_extra', 'uid__status', 'uid__area', 'uid__vpg_id',                        'uid__p2p_type', 'uid__full_uid_code', 'uid__platform',                        'uid__init_string', 'uid__init_string_app')            uid_info = {}            if uid_company_qs.exists():                # 更新被同步数据的uid的状态为3(数据被同步)                uid = uid_company_qs[0]['uid__uid']                UIDModel.objects.filter(uid=uid).update(status=3)                uid_info['uid'] = uid                uid_info['mac'] = uid_company_qs[0]['uid__mac']                uid_info['uid_extra'] = uid_company_qs[0]['uid__uid_extra']                uid_info['status'] = uid_company_qs[0]['uid__status']                uid_info['area'] = uid_company_qs[0]['uid__area']                uid_info['vpg_id'] = uid_company_qs[0]['uid__vpg_id']                uid_info['p2p_type'] = uid_company_qs[0]['uid__p2p_type']                uid_info['full_uid_code'] = uid_company_qs[0]['uid__full_uid_code']                uid_info['platform'] = uid_company_qs[0]['uid__platform']                uid_info['init_string'] = uid_company_qs[0]['uid__init_string']                uid_info['init_string_app'] = uid_company_qs[0]['uid__init_string_app']            results = {'serial': company_serial.serial_number, 'status': company_serial.status,                       'uidInfo': uid_info}            return response.json(0, results)        except Exception as e:            LOGGER.info('查询序列号异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))            return response.json(176, str(e))    @staticmethod    def rpush_serial_and_count_uid(serial, p2p_type, redis_obj):        """        处理序列号状态和计算剩余uid数量线程        @param serial: 序列号        @param p2p_type: p2p类型        @param redis_obj: redis对象        @return:        """        # 写入已使用序列号redis列表        redis_obj.rpush(USED_SERIAL_REDIS_LIST, serial)        p2p_type = int(p2p_type)        platform = '尚云' if p2p_type == 1 else 'tutk'        redis_key = 'uid_count_warning_time_limit_' + platform        redis_obj = RedisObject()        time_limit = redis_obj.get_data(redis_key)        if not time_limit:            vpg_id = 1            if CONFIG_INFO == CONFIG_US:                vpg_id = 3            elif CONFIG_INFO == CONFIG_EUR:                vpg_id = 4            try:                # 尚云剩余uid数量少于1000,尚云剩余uid数量少于5000,发送邮件提醒                unused_uid_count = UIDModel.objects.filter(vpg_id=vpg_id, p2p_type=p2p_type, status=0).count()                warning_count = 1000 if p2p_type == 1 else 5000                if unused_uid_count < warning_count:                    # 限制一天提醒一次                    redis_obj.set_data(redis_key, 1, 60 * 60 * 24)                    email_content = '{}服{}的uid数量少于{}个,剩余数量:{},请及时处理'.format(                        CONFIG_INFO, platform, warning_count, unused_uid_count)                    S3Email().faEmail(email_content, 'servers@ansjer.com')            except Exception as e:                LOGGER.info('发送提醒邮件异常: error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))    @staticmethod    def sync_serial_data_and_log(request, company_serial_id, serial, now_time):        """        同步序列号数据和记录日志        @param company_serial_id: 企业关联序列号 ID        @param request: 请求        @param serial: 序列号        @param now_time: 当前时间        @return : bool        """        redis = RedisObject()        key = f'BIND:UID:LIMIT:{serial}'        serial_obj = redis.get_data(key)        # 序列号已占用一天写一次日志记录        if serial_obj:            return False        ip = CommonService.get_ip_address(request)        operation = '{}序列号占用,APP扫码已停用同步UID'.format(serial)        log = {            'ip': ip,            'user_id': 1,            'status': 200,            'time': now_time,            'url': 'serialNumber/attachUID',            'operation': operation        }        LogModel.objects.create(**log)        redis.set_data(key, '1', 86400)        return False        # sync_result = False        # # 测试服和国内服不同步        # if CONFIG_INFO == 'test' or CONFIG_INFO == 'cn':        #     return sync_result        # try:        #     # 判断当前序列号是否绑定UID        #     uid_serial_qs = UIDCompanySerialModel.objects.filter(company_serial_id=company_serial_id)        #     if uid_serial_qs.exists():        #         operation += ',已绑定UID,不同步数据'        #         log['operation'] = operation        #         LogModel.objects.create(**log)        #         return sync_result        #        #     region = 'us'        #     # 欧洲服同步美洲服,美洲服同步国内服数据        #     if CONFIG_INFO == 'eur':        #         domain_name = 'https://www.dvema.com/'        #     else:        #         region = 'cn'        #         domain_name = 'https://www.zositechc.cn/'        #        #     url = domain_name + 'serialNumber/get-status'        #     response = requests.get(url=url, params={'serial_number': serial}, timeout=15)        #        #     if response.status_code != 200:        #         operation += '查询{}服UID数据响应状态码异常:{}'.format(region, response.status_code)        #         log['operation'] = operation        #         LogModel.objects.create(**log)        #         return sync_result        #        #     results = json.loads(response.text)        #     if results['result_code'] != 0:        #         operation += '查询{}服UID数据result_code异常:{}'.format(region, results['result_code'])        #         log['operation'] = operation        #         LogModel.objects.create(**log)        #         return sync_result        #        #     # 其它服没有绑定uid        #     uid_info = results['result']['uidInfo']        #     if not uid_info:        #         operation += '{}服没有绑定UID'.format(region)        #         log['operation'] = operation        #         LogModel.objects.create(**log)        #         return sync_result        #     # 同步uid数据        #     if uid_info['p2p_type'] == 1:        #         operation += '尚云UID不同步数据'        #     else:        #         uid_qs = UIDModel.objects.filter(uid=uid_info['uid'])        #         if not uid_qs.exists():        #             uid_info['add_time'] = now_time        #             uid_info['update_time'] = now_time        #             uid_id = UIDModel.objects.create(**uid_info).id        #         else:        #             if uid_qs.first().status == 2:  # 判断uid是否被使用        #                 operation += 'uid{}已被使用'.format(uid_info['uid'])        #                 log['operation'] = operation        #                 LogModel.objects.create(**log)        #                 return sync_result        #             else:        #                 uid_qs.update(status=2, update_time=now_time)        #                 uid_id = uid_qs.first().id        #        #         # 企业序列号关联 uid        #         UIDCompanySerialModel.objects.create(        #             uid_id=uid_id, company_serial_id=company_serial_id, add_time=now_time, update_time=now_time)        #         # 修改企业序列号状态为2(绑定uid)        #         CompanySerialModel.objects.filter(id=company_serial_id) \        #             .update(status=2, update_time=now_time)        #         sync_iot_result = SerialNumberView.sync_iot_core_data(domain_name, serial)        #        #         operation += '同步{}服uid数据成功,同步iot数据结果:{}'.format(region, sync_iot_result)        #         sync_result = True        #        #     # 记录日志        #     log['operation'] = operation        #     LogModel.objects.create(**log)        #     return sync_result        #        # except Exception as e:        #     operation += '同步数据异常,error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e))        #     log['operation'] = operation        #     LogModel.objects.create(**log)        #     return sync_result    def do_get_uid(self, request_dict, response):        serial_number = request_dict.get('serial_number', None)        token = request_dict.get('token', None)        time_stamp = request_dict.get('time_stamp', None)        if token and time_stamp and serial_number:            # 时间戳token校验            if not CommonService.check_time_stamp_token(token, time_stamp):                return response.json(13)            mark = serial_number[6:9]            serial = serial_number[0:6]            uid_company_serial_qs = UIDCompanySerialModel.objects.filter(company_serial__company__mark=mark,                                                                         company_serial__serial_number__serial_number=serial)            if uid_company_serial_qs.exists():                uid = uid_company_serial_qs.values('uid__uid', 'uid__mac', 'uid__uid_extra')[0]                res = {                    'uid': CommonService.encode_data(uid['uid__uid']),                    'mac': CommonService.encode_data(uid['uid__mac']),                    'extra': uid['uid__uid_extra']                }                return response.json(0, res)            else:                return response.json(173)        else:            return response.json(444)    @staticmethod    def do_detach_uid(request, request_dict, response):        token = request_dict.get('token', None)        time_stamp = request_dict.get('time_stamp', None)        serial_number = request_dict.get('serial_number', None)        if not all([token, time_stamp, serial_number]):            return response.json(444)        # 时间戳token校验        if not CommonService.check_time_stamp_token(token, time_stamp):            return response.json(13)        now_time = int(time.time())        # 记录操作日志        ip = CommonService.get_ip_address(request)        content = json.loads(json.dumps(request_dict))        serial = serial_number[0:6]        company_serial_qs = CompanySerialModel.objects.filter(serial_number=serial).values('status')        if not company_serial_qs.exists():            return response.json(379)        status = company_serial_qs[0]['status']        if status == 1:            return response.json(0, {'success': '序列号未绑定uid'})        elif status == 3:            return response.json(10043)        uid_serial_qs = UIDCompanySerialModel.objects.filter(company_serial__serial_number=serial)        if not uid_serial_qs.exists():            return response.json(173)        uid_serial = uid_serial_qs[0]        # 判断序列号是否刚绑定uid,刚绑定需要过1分钟才能解绑        redisObj = RedisObject()        used_serial_redis_list = redisObj.lrange(USED_SERIAL_REDIS_LIST, 0, -1)        used_serial_redis_list = [str(i, 'utf-8') for i in used_serial_redis_list]        if serial in used_serial_redis_list:            return response.json(5)        # 判断序列号是否未清除uid数据        serial_unbind_uid_qs = SerialUnbindUID.objects.filter(serial=serial, status=0)        if serial_unbind_uid_qs.exists():            return response.json(5)        try:            uid = uid_serial.uid.uid            # 写入序列号解绑uid表            SerialUnbindUID.objects.create(serial=serial, uid=uid, created_time=now_time, updated_time=now_time)            end_time = int(time.time())            # 记录操作日志            log = {                'ip': ip,                'user_id': 1,                'status': 200,                'time': now_time,                'content': json.dumps(content),                'url': 'serialNumber/detachUID',                'operation': '序列号{}加入解绑队列uid:{}:{}秒'.format(serial, uid, end_time-now_time),            }            LogModel.objects.create(**log)            return response.json(0)        except Exception as e:            log = {                'ip': ip,                'user_id': 1,                'status': 200,                'time': now_time,                'content': json.dumps(content) + '异常:{}'.format(repr(e)),                'url': 'serialNumber/detachUID',                'operation': '序列号{}解绑uid异常'.format(serial),            }            LogModel.objects.create(**log)            return response.json(176, str(e))    def get_uid(self, request_dict, response, request, user_id):        """        app获取序列号        @param request_dict:        @param response:        @param request:        @param user_id:        @return:        """        token = request_dict.get('token', None)        time_stamp = request_dict.get('time_stamp', None)        company_secret = request_dict.get('company_id', None)        serial_number = request_dict.get('serial_number', None)        if not all([token, time_stamp, company_secret, serial_number]):            return response.json(444)        # 时间戳token校验        if not CommonService.check_time_stamp_token(token, time_stamp):            return response.json(13)        now_time = int(time.time())        serial = serial_number[0:6]        # 判断序列号是否已和企业关联        company_serial_qs = CompanySerialModel.objects.filter(company__secret=company_secret, serial_number=serial)        if not company_serial_qs.exists():            return response.json(173)        company_serial = company_serial_qs[0]        try:            # 添加或更新扫码记录            ip = CommonService.get_ip_address(request)            # 查询用户国家id            region_country = 0            # ios请求头没传token,user_id为None            if user_id:                device_user_qs = Device_User.objects.filter(userID=user_id).values('region_country')                if device_user_qs.exists():                    region_country = device_user_qs[0]['region_country']            data = {                'ip': ip,                'update_time': now_time,                'region_country': region_country            }            app_scanned_serial_qs = AppScannedSerial.objects.filter(serial=serial)            if app_scanned_serial_qs.exists():                app_scanned_serial_qs.update(**data)            else:                data['serial'] = serial                data['add_time'] = now_time                AppScannedSerial.objects.create(**data)            if company_serial.status == 0 or company_serial.status == 1:  # 未使用                UnicomComboView().is_4g_device(serial_number, request_dict, request)                return response.json(173)            elif company_serial.status == 2:  # 返回uid                res = self.get_uid_info_by_serial(company_serial.id)                return response.json(0, res)            elif company_serial.status == 3:  # 已占用                sync_success = self.sync_serial_data_and_log(request, company_serial.id, serial_number, now_time)                if not sync_success:                    return response.json(10044)                return response.json(0, self.get_uid_info_by_serial(company_serial.id))        except Exception as e:            error_logger = logging.getLogger('django')            error_logger.exception(repr(e))            return response.json(176, str(e))    @staticmethod    def get_region_info(request_dict, response):        """        根据序列号状态确认uid地区        @param request_dict: 请求参数        @param response: 响应对象        @request_dict serial_number: 序列号        @return: response        """        serial_number = request_dict.get('serial_number', None)        if not serial_number:            return response(444)        company_serial_qs = CompanySerialModel.objects.filter(serial_number=serial_number[:6]).values('status')        if not company_serial_qs.exists():            return response.json(173)        status = company_serial_qs[0]['status']        if status == 2:            if CONFIG_INFO == CONFIG_CN:                return response.json(0, {'region': 1})            elif CONFIG_INFO == CONFIG_US:                return response.json(0, {'region': 3})        elif status == 3:            if CONFIG_INFO == CONFIG_CN:                return response.json(0, {'region': 3})            elif CONFIG_INFO == CONFIG_US:                return response.json(0, {'region': 1})        return response.json(0)    @staticmethod    def save_region(request, request_dict, response):        """        保存设备地区信息        @param request: 请求体        @param request_dict: 请求参数        @param response: 响应对象        @request_dict token: 令牌        @request_dict time_stamp: 时间戳        @return: response        """        token = request_dict.get('token', None)        serial_number = request_dict.get('serial_number', None)        if not all([serial_number, token]):            return response(444)        try:            serial_number = serial_number[:6]            # 不是美洲服,请求美洲域名保存数据            if CONFIG_INFO != CONFIG_US:                # token认证                token_obj = TokenObject(token)                if token_obj.code != 0:                    return response.json(token_obj.code)                response.lang = token_obj.lang                url = SERVER_DOMAIN_US + 'serialNumber/saveRegion'                data = request_dict.dict()                data['ip'] = CommonService.get_ip_address(request)                data['region_id'] = CommonService.confirm_region_id()                try:                    r = requests.post(url=url, data=data, timeout=15)                    assert r.status_code == 200                    res = r.json()                    assert res['result_code'] == 0                except (TimeoutError, AssertionError):                    return response.json(5)            # 美洲服,处理请求和保存数据            else:                data = {}                # 处理其他服务器发起请求的情况                region_id = request_dict.get('region_id', None)                if region_id is not None:                    region_id = int(region_id)                    data['region_id'] = region_id                    data['ip'] = request_dict.get('ip', '')                else:                    # token认证                    token_obj = TokenObject(token)                    if token_obj.code != 0:                        return response.json(token_obj.code)                    response.lang = token_obj.lang                    region_id = CommonService.confirm_region_id()                    data['region_id'] = region_id                    data['ip'] = CommonService.get_ip_address(request)                # 写入数据                device_domain_region_qs = DeviceDomainRegionModel.objects.filter(serial_number=serial_number). \                    values('region_id')                if not device_domain_region_qs.exists():                    data['serial_number'] = serial_number                    DeviceDomainRegionModel.objects.create(**data)                else:                    # 设备解绑过uid,更新region_id                    if device_domain_region_qs[0]['region_id'] == 0:                        device_domain_region_qs.update(**data)            return response.json(0)        except Exception as e:            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))    @staticmethod    def get_domain(request_dict, response):        """        设备获取域名        @param request_dict: 请求参数        @param response: 响应对象        @request_dict serial_number: 序列号        @request_dict time_stamp_token: 时间戳token        @request_dict time_stamp: 时间戳        @return: response        """        serial_number = request_dict.get('serial_number', None)        time_stamp_token = request_dict.get('time_stamp_token', None)        time_stamp = request_dict.get('time_stamp', None)        if not all([serial_number, time_stamp_token, time_stamp]):            return response.json(444)        # 时间戳token校验        if not CommonService.check_time_stamp_token(time_stamp_token, time_stamp):            return response.json(13)        try:            serial_number = serial_number[:6]            device_domain_region_qs = DeviceDomainRegionModel.objects.filter(serial_number=serial_number).values(                'region_id')            if not device_domain_region_qs.exists():                return response.json(173)            region_id = device_domain_region_qs[0]['region_id']            region_qs = RegionModel.objects.filter(id=region_id).values('api', 'push_api')            if not region_qs.exists():                return response.json(173)            # 国内和测试的推送存储地区为国内            push_region = 2 if region_id in [1, 5] else 1            res = {                'api': region_qs[0]['api'],                'push_api': region_qs[0]['push_api'],                'push_region': push_region            }            return response.json(0, res)        except Exception as e:            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))    @staticmethod    def reset_region_id(request_dict, response):        """        重置地区id        @param request_dict: 请求参数        @param response: 响应对象        @request_dict serial_number: 序列号        @return: response        """        serial_number = request_dict.get('serial_number', None)        if not serial_number:            return response(444)        try:            serial_number = serial_number[:6]            DeviceDomainRegionModel.objects.filter(serial_number=serial_number).update(region_id=0)            return response.json(0)        except Exception as e:            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))    @staticmethod    def get_uid_region(request_dict, response):        """        根据序列号获取uid地区        @param request_dict: 请求参数        @param response: 响应对象        @request_dict serial_number: 序列号        @return: response        """        serial_number = request_dict.get('serial_number', None)        if not serial_number:            return response(444)        try:            serial_number = serial_number[:6]            uid_company_serial_qs = UIDCompanySerialModel.objects.filter(                company_serial__serial_number=serial_number).values('uid__uid')            res = []            for item in uid_company_serial_qs:                res.append({'uid': item['uid__uid']})            return response.json(0, res)        except Exception as e:            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))    @staticmethod    def get_global_uid_region(request_dict, response):        """        获取序列号在全球服绑定uid的地区        @param request_dict: 请求参数        @param response: 响应对象        @request_dict serial_number: 序列号        @return: response        """        orders_domain_name_list = SERVER_DOMAIN_LIST        if SERVER_DOMAIN_TEST in orders_domain_name_list:            orders_domain_name_list.remove(SERVER_DOMAIN_TEST)        uid_list = []        try:            for orders_domain_name in orders_domain_name_list:                url = orders_domain_name + 'serialNumber/getUidRegion'                res = requests.post(url=url, data=request_dict)                result = res.json()                if result['result_code'] != 0:                    return response.json(result['result_code'])                if orders_domain_name == SERVER_DOMAIN_CN:                    for item in result['result']:                        item['region'] = 1                        uid_list.append(item)                elif orders_domain_name == SERVER_DOMAIN_US:                    for item in result['result']:                        item['region'] = 3                        uid_list.append(item)                elif orders_domain_name == SERVER_DOMAIN_EUR:                    for item in result['result']:                        item['region'] = 4                        uid_list.append(item)            return response.json(0, uid_list)        except Exception as e:            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))    @classmethod    def get_iot_core_by_serial_number(cls, request_dict, response):        """        根据序列号查询iot core        """        try:            serial_number = request_dict.get('serialNumber', None)            if not serial_number:                return response.json(444)            serial = serial_number[0:6]            LOGGER.info('根据序列号查询IoTC:{}'.format(serial_number))            device_iot_qs = iotdeviceInfoModel.objects.filter(serial_number=serial)            if not device_iot_qs.exists():                return response.json(173)            iot_vo = device_iot_qs.first()            iot_dto = {                'serial_number': iot_vo.serial_number,                'uid': iot_vo.uid,                'certificate_id': iot_vo.certificate_id,                'certificate_pem': iot_vo.certificate_pem,                'public_key': iot_vo.public_key,                'private_key': iot_vo.private_key,                'thing_name': iot_vo.thing_name,                'thing_groups': iot_vo.thing_groups,                'endpoint': iot_vo.endpoint,                'token_iot_number': iot_vo.token_iot_number,                'add_time': iot_vo.add_time.strftime("%Y-%m-%d %H:%M:%S"),                'update_time': iot_vo.update_time.strftime("%Y-%m-%d %H:%M:%S")            }            return response.json(0, {'iotInfo': iot_dto})        except Exception as e:            LOGGER.info('查询序列号异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))            return response.json(176, str(e))    @staticmethod    def sync_iot_core_data(domain_name, serial_number):        """        同步iot core 数据        @param domain_name: 域名        @param serial_number: 序列号        """        try:            serial = serial_number[0:6]            device_iot_qs = iotdeviceInfoModel.objects.filter(serial_number=serial)            if device_iot_qs.exists():                return False            url = domain_name + 'serialNumber/getIoTCoreBySerialNumber'            response = requests.get(url=url, params={'serialNumber': serial_number}, timeout=15)            if response.status_code != 200:                return False            results = json.loads(response.text)            if results['result_code'] != 0:                return False            iot_vo = results['result']['iotInfo']            iot_vo['add_time'] = datetime.strptime(iot_vo['add_time'], "%Y-%m-%d %H:%M:%S")            iot_vo['update_time'] = datetime.strptime(iot_vo['update_time'], "%Y-%m-%d %H:%M:%S")            iotdeviceInfoModel.objects.create(**iot_vo)            return True        except Exception as e:            LOGGER.info('{}同步iot异常,errLine:{}, errMsg:{}'.format(serial_number, e.__traceback__.tb_lineno, repr(e)))            return False
 |