#!/usr/bin/env python3 # -*- coding: utf-8 -*- import json import logging import time import requests from django.db import transaction from django.views import View from Ansjer.config import CRCKey, SERVER_DOMAIN_US, SERVER_DOMAIN_CN, CONFIG_INFO, CONFIG_TEST, CONFIG_US, \ CONFIG_CN 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 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 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): token = TokenObject(request_dict.get('token', None)) response = uidManageResponseObject() if operation == 'getUID': return self.do_get_uid(request_dict, response) elif 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 == 'create': return self.do_create(request_dict, response) elif operation == 'changeSerialNumberStatus': return self.changeSerialNumberStatus(request_dict, response) elif operation == 'getRegionInfo': return self.get_region_info(request_dict, response) else: if token.code != 0: return response.json(token.code) # if operation == 'create': # return self.do_create(request_dict, response) elif operation == 'list': return self.do_list(token.userID, request_dict, response) elif operation == 'update': return self.do_update(token.userID, request_dict, response) else: return response.json(404) def do_create(self, request_dict, response): quantity = int(request_dict.get('quantity', 0)) if not quantity: return response.json(444) try: try: sum = SerialNumberModel.objects.last().id except: sum = 0 serial_number_bulk = [] now_time = int(time.time()) algorithm = AlgorithmBaseOn35() for i in range(quantity): serial_number = algorithm.getLetter(sum) sum += 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, repr(e)) def do_list(self, userID, request_dict, response): # perm = ModelService.check_perm_uid_manage(userID, 0) # if not perm: # return response.json(309) page = request_dict.get('page', None) line = request_dict.get('limit', None) serial_number = request_dict.get('serial_number', None) status = request_dict.get('status', None) if page and line: page = int(page) line = int(line) serial_qs = SerialNumberModel.objects.filter().order_by('-id') if serial_number: serial_qs = serial_qs.filter(serial_number__contains=serial_number) if status: serial_qs = serial_qs.filter(status=status) count = serial_qs.count() start = (page - 1) * line end = start + line serial_qs = serial_qs[start: end].values() res = { 'count': count, 'data': list(serial_qs) } return response.json(0, res) else: return response.json(444) def do_attach_uid(self, request_dict, response, request): serial_number = request_dict.get('serial_number', None) company_id = request_dict.get('company_id', None) token = request_dict.get('token', None) time_stamp = request_dict.get('time_stamp', None) if not all([serial_number, company_id, 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] full_serial = serial_number[0:9] try: # 判断序列号是否已和企业关联 company_serial_qs = CompanySerialModel.objects.filter(company__secret=company_id, 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 # redis加锁,防止同一个序列号重复绑定 key = serial + 'do_attach_uid' redisObj = RedisObject() isLock = redisObj.CONN.setnx(key, 1) redisObj.CONN.expire(key, 60) if not isLock: return response.json(5) # 获取并判断region_id region_id = request_dict.get('region_id', None) region_id = int(region_id) if region_id else CommonService.confirm_region_id(request) if region_id not in [1, 2, 3, 4]: return response.json(444, {'invalid region_id': region_id}) p2p_type = request_dict.get('p2ptype', 1) if serial_number[9:10]: p2p_type = serial_number[9:10] p2p_type = int(p2p_type) # 尚云: 地区为亚洲分配美洲的uid if p2p_type == 1 and region_id == 2: region_id = 3 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('id') 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.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) # 修改其他数据库的序列号使用状态为已占用 update_success = self.update_serial_status(serial=serial, status=3) try: assert update_success except AssertionError: return response.json(378) redisObj.del_data(key=key) return response.json(0, res) return response.json(5) elif company_serial.status == 2: # 返回uid uid_qs = UIDCompanySerialModel.objects.filter(company_serial_id=company_serial.id) if not uid_qs.exists(): return response.json(173) 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 response.json(0, res) elif company_serial.status == 3: return response.json(10042) except Exception as e: djangoLogger = logging.getLogger('django') djangoLogger.exception(repr(e)) return response.json(176, str(e)) 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) def do_detach_uid(self, 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()) 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] try: with transaction.atomic(): uid = uid_serial.uid.uid company_serial_qs.update(status=1) # 更新序列号状态 # 删除设备相关数据,参考后台的设备重置删除的数据 Device_Info.objects.filter(UID=uid).delete() UidSetModel.objects.filter(uid=uid).delete() UidUserModel.objects.filter(UID=uid).delete() iotdeviceInfoModel.objects.filter(serial_number=serial).delete() # 删除推送消息 for val in range(1, 8): EquipmentInfoService.get_equipment_info_model('', val).filter(device_uid=uid).delete() # 重置设备云存 UID_Bucket.objects.filter(uid=uid).delete() Unused_Uid_Meal.objects.filter(uid=uid).delete() Order_Model.objects.filter(UID=uid).delete() StsCrdModel.objects.filter(uid=uid).delete() VodHlsModel.objects.filter(uid=uid).delete() ExperienceContextModel.objects.filter(uid=uid).delete() # 重置AI ExperienceAiModel.objects.filter(uid=uid).delete() AiService.objects.filter(uid=uid).delete() # 修改其他数据库的序列号使用状态为已使用 update_success = self.update_serial_status(serial=serial, status=1) try: assert update_success except AssertionError: return response.json(378) UIDModel.objects.filter(uid=uid).update(status=0, mac='') # 重置uid的使用状态为未使用 uid_serial.delete() # 记录操作日志 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/detachUID', 'operation': '序列号{}解绑uid: {}'.format(serial, uid), } LogModel.objects.create(**log) return response.json(0) except Exception as e: djangoLogger = logging.getLogger('django') djangoLogger.exception(repr(e)) return response.json(176, str(e)) @staticmethod def update_serial_status(serial, status): if CONFIG_INFO == CONFIG_TEST: # 测试服不处理 return True server_domain = SERVER_DOMAIN_CN if CONFIG_INFO == CONFIG_US: server_domain = SERVER_DOMAIN_CN elif CONFIG_INFO == CONFIG_CN: server_domain = SERVER_DOMAIN_US url = server_domain + 'serialNumber/changeSerialNumberStatus' data = {'serial': serial, 'status': status} req_res = requests.post(url=url, data=data, timeout=2) if req_res.status_code != 200: return False req_res = req_res.json() if req_res['result_code'] != 0: return False return True def do_update(self, userID, request_dict, response): # perm = ModelService.check_perm_uid_manage(userID, 0) # if not perm: # return response.json(309) id = request_dict.get('id', None) status = request_dict.get('status', None) if id and status: serial_number_qs = SerialNumberModel.objects.filter(id=id) if serial_number_qs.exists(): serial_number_qs.update(**{'status': status}) return response.json(0) else: return response.json(173) else: return response.json(444) # 序列号绑定和解绑uid时修改其他数据库序列号的使用状态 def changeSerialNumberStatus(self, request_dict, response): serial = request_dict.get('serial', None) status = request_dict.get('status', None) if not all([serial, status]): return response(444) try: # 更新CompanySerialModel表的序列号使用状态 update = CompanySerialModel.objects.filter(serial_number=serial).update(status=int(status)) if update: return response.json(0) else: return response.json(378) except Exception as e: djangoLogger = logging.getLogger('django') djangoLogger.exception(repr(e)) return response.json(500, str(e)) @staticmethod def get_region_info(request_dict, response): """ 根据序列号状态确认uid地区 @param request_dict: 请求参数 @param response: 响应对象 @request_dict endTime: 结束时间 @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(10044, {'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})