12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118 |
- import json
- import logging
- import threading
- import time
- from datetime import datetime
- import requests
- from django.db import transaction
- from django.db.models import Q
- from django.views import View
- from 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, LOGGER, CONFIG_TEST, \
- SERVER_DOMAIN
- from Controller.CheckUserData import DataValid
- from Controller.UnicomCombo.UnicomComboController import UnicomComboView
- from 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, SerialUnbindUID, \
- DeviceNetInfo
- from Object.AWS.S3Email import S3Email
- from Object.RedisObject import RedisObject
- from Object.TokenObject import TokenObject
- from Object.uidManageResponseObject import uidManageResponseObject
- from Service.AlgorithmService import AlgorithmBaseOn35
- from Service.CommonService import CommonService
- from Service.EquipmentInfoService import EquipmentInfoService
- from Service.VodHlsService import SplitVodHlsObject
- from AdminController.CloudServiceManage.AgentDeviceController import AgentDeviceView
- class 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)
- elif operation == 'saveUserNetInfo':
- return self.save_user_net_info(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):
- LOGGER.error(f'{serial_number}时间戳校验失败time:{time_stamp},tk:{token}')
- 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:
- redisObj = RedisObject()
- # 查询app是否已扫码,未扫码不能进行绑定
- # 如果没扫码设置24小时的缓存,扫码后删除缓存
- scanned_serial_key = serial + 'scanned_serial'
- if redisObj.get_data(scanned_serial_key):
- return response.json(5)
- app_scanned_serial_qs = AppScannedSerial.objects.filter(serial=serial).values('region_country')
- if not app_scanned_serial_qs.exists() and is_verify != '1':
- redisObj.set_data(scanned_serial_key, 1, 24*60*60)
- LOGGER.info(f'{serial}当前序列号未进行APP扫码')
- return response.json(5)
- # 判断序列号是否刚解绑,刚解绑1分钟内不能进行绑定
- 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)
- # 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)
- # 判断序列号是否已和企业关联
- 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:
- region_country = app_scanned_serial_qs[0]['region_country']
- # 获取并判断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
- company_serial_qs = UIDCompanySerialModel.objects.filter(company_serial_id=company_serial.id)
- if company_serial_qs.exists():
- return response.json(380)
- # 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()
- 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': int(time.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()
- 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)
- redisObj.del_data(key=key)
- return response.json(0, res)
- elif company_serial.status == 3: # 已占用
- redisObj.del_data(key=key)
- 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:
- return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(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)))
- try:
- # 异步调用客户代理平台同步序列号绑定UID
- serial_number = serial + '11A'
- agent_thread = threading.Thread(target=AgentDeviceView.device_binding_or_unbinding,
- args=(serial_number, 1))
- agent_thread.start()
- except Exception as e:
- LOGGER.error('异步更新定制客户序列号状态一次: 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)
- LOGGER.info('请求获取UID{},userId:{},ip:{}'.format(serial_number, user_id, ip))
- # 查询用户国家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)
- # 扫码后删除缓存
- redis_obj = RedisObject()
- scanned_serial_key = serial + 'scanned_serial'
- redis_obj.del_data(scanned_serial_key)
- 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_CN or CONFIG_INFO == CONFIG_TEST:
- return response.json(0)
- # 不是美洲服,请求美洲域名保存数据
- 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=10)
- assert r.status_code == 200
- res = r.json()
- assert res['result_code'] == 0
- except Exception as e:
- pass
- # 美洲服,处理请求和保存数据
- 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
- @classmethod
- def save_user_net_info(cls, request_dict, response):
- """
- 保存用户网络信息
- @return:
- """
- serial = request_dict.get('serial', None)
- username = request_dict.get('username', None)
- wifi_name = request_dict.get('wifi_name', None)
- wifi_password = request_dict.get('wifi_password', None)
- time_stamp = request_dict.get('time_stamp', None)
- token = request_dict.get('time_stamp_token', None)
- if not all([serial, username, wifi_name, wifi_password, time_stamp, token]):
- return response.json(444)
- if len(serial) < 14:
- return response.json(444, '序列号长度小于14')
- # 根据序列号获取p2p类型,设备类型信息
- serial_number = serial[:9]
- p2p_type = serial[9:10]
- device_type = int(serial[10:14], 16)
- # 请求绑定uid或查询uid
- data = {
- 'serial_number': serial_number,
- 'p2ptype': p2p_type,
- 'time_stamp': time_stamp,
- 'token': token,
- 'is_verify': '1'
- }
- url = SERVER_DOMAIN + 'serialNumber/attachUID'
- try:
- r = requests.post(url=url, data=data, timeout=30)
- assert r.status_code == 200
- r = r.json()
- if r['result_code'] != 0:
- return response.json(r['result_code'])
- uid = CommonService.decode_data(r['result']['uid'])
- # 查询用户是否存在,不存在则创建
- device_user_qs = Device_User.objects.filter(username=username).values('userID')
- if device_user_qs.exists():
- user_id = device_user_qs[0]['userID']
- # 判断设备是否已被其他账号添加
- device_info_qs = Device_Info.objects.filter(~Q(userID_id=user_id), UID=uid).values('id')
- if device_info_qs.exists():
- return response.json(174)
- # 已保存过,更新网络信息
- device_info_qs = Device_Info.objects.filter(userID_id=user_id, UID=uid).values('id')
- if device_info_qs.exists():
- device_id = device_info_qs[0]['id']
- device_net_info_qs = DeviceNetInfo.objects.filter(device_id=device_id)
- if device_net_info_qs.exists():
- device_net_info_qs.update(wifi_name=wifi_name, wifi_password=wifi_password)
- else:
- # 创建用户设备和设备网络数据
- cls.creat_device_data(user_id, serial, uid, device_type, username, wifi_name, wifi_password)
- else:
- # 判断设备是否已被其他账号添加
- device_info_qs = Device_Info.objects.filter(UID=uid).values('id')
- if device_info_qs.exists():
- return response.json(174)
- password = ''
- user_id = CommonService.getUserID(μs=False, setOTAID=True)
- user_data = {
- 'userID': user_id,
- 'username': username,
- 'NickName': username,
- 'password': password,
- 'is_active': True,
- 'user_isValid': True
- }
- # 判断用户名是手机号还是邮箱
- if DataValid().mobile_validate(username):
- user_data['phone'] = username
- elif DataValid().email_validate(username):
- user_data['userEmail'] = username
- else:
- return response.json(444)
- Device_User.objects.create(**user_data)
- # 创建用户设备和设备网络数据
- cls.creat_device_data(user_id, serial, uid, device_type, username, wifi_name, wifi_password)
- # 生成或更新扫码记录
- serial = serial[:6]
- now_time = int(time.time())
- app_scanned_serial_qs = AppScannedSerial.objects.filter(serial=serial)
- if app_scanned_serial_qs.exists():
- app_scanned_serial_qs.update(update_time=now_time)
- else:
- AppScannedSerial.objects.create(serial=serial, add_time=now_time, update_time=now_time)
- 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 creat_device_data(user_id, serial, uid, device_type, username, wifi_name, wifi_password):
- """
- @param user_id:
- @param serial:
- @param uid:
- @param device_type:
- @param username:
- @param wifi_name:
- @param wifi_password:
- @return:
- """
- nickname = serial[:6]
- device_id = CommonService.getUserID(getUser=False)
- Device_Info.objects.create(
- id=device_id, userID_id=user_id, serial_number=serial[:9], UID=uid, NickName=nickname,
- Type=device_type, View_Account='admin', View_Password='admin', vodPrimaryMaster=username,
- vodPrimaryUserID=user_id
- )
- DeviceNetInfo.objects.create(
- device_id=device_id, wifi_name=wifi_name, wifi_password=wifi_password
- )
- # 创建或更新设备影子昵称
- uid_set_qs = UidSetModel.objects.filter(uid=uid)
- if uid_set_qs.exists():
- uid_set_qs.update(nickname=nickname)
- else:
- UidSetModel.objects.create(uid=uid, nickname=nickname)
|