#!/usr/bin/env python3 # -*- coding: utf-8 -*- import json import logging import random import time from django.db import transaction from django.views import View from Controller.DetectController import DetectControllerView from Controller.DeviceConfirmRegion import Device_Region from Model.models import SerialNumberModel, CompanySerialModel, UIDCompanySerialModel, CompanyModel, RegionModel, \ CountryModel, UIDModel, Device_Info, iotdeviceInfoModel, UidPushModel, LogModel from Object.RedisObject import RedisObject from Object.uidManageResponseObject import uidManageResponseObject from Object.TokenObject import TokenObject from Service.AlgorithmService import AlgorithmBaseOn35 from Service.CommonService import CommonService from Ansjer.config import CRCKey from Service.ModelService import ModelService 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 == 'getSerial': return self.do_get_serial_number(request_dict, response) elif operation == 'attachUID': return self.do_attach_uid(request_dict, response, request) elif operation == 'detachUID': return self.do_detach_uid(request, request_dict, response) elif operation == 'create': return self.do_create(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)) p2p = int(request_dict.get('p2p', 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, p2p=p2p)) # 开启事务写入 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)) # 提供给pc端获取序列号 def do_get_serial_number(self, request_dict, response): quantity = request_dict.get('quantity', None) company_id = request_dict.get('company_id', None) token = request_dict.get('token', None) time_stamp = request_dict.get('time_stamp', None) p2p_type = request_dict.get('p2p_type', None) if token and time_stamp and quantity and company_id: token = int(CommonService.decode_data(token)) time_stamp = int(time_stamp) now_time = int(time.time()) distance = now_time - time_stamp if token != time_stamp or distance > 60000 or distance < -60000: # 为了全球化时间控制在一天内 return response.json(404) redisObject = RedisObject() key = 'serial_lock' value = redisObject.lpop(key) count = 0 while value is False and count < 5: time.sleep(1) value = redisObject.lpop(key) count += 1 if count == 5 and value is False: # 暂时注释 return response.json(5) quantity = int(quantity) company_serial_qs = CompanySerialModel.objects.filter(company__secret=company_id, status=0, p2p=p2p_type) if not company_serial_qs.exists(): redisObject.rpush(key, value) return response.json(373) # 存在对应的企业 company_serial_qs = company_serial_qs[0:quantity] # company_serial_qs = company_serial_qs.values('id', 'serial_number__serial_number', 'company__mark') data = [] ids = [] for serial in company_serial_qs: ids.append(serial.id) data.append(serial.serial_number + serial.company.mark) CompanySerialModel.objects.filter(id__in=ids).update(status=1) redisObject.rpush(key, value) return response.json(0, data) else: return response.json(444) 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) @transaction.atomic def do_attach_uid(self, request_dict, response, request): serial_number = request_dict.get('serial_number', None) country_id = request_dict.get('country_id', 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]) or len(serial_number) != 9: return response.json(444) token = int(CommonService.decode_data(token)) time_stamp = int(time_stamp) now_time = int(time.time()) distance = now_time - time_stamp if token != time_stamp or distance > 60000 or distance < -60000: # 为了全球化时间控制在一天内 return response.json(404) mark = serial_number[6:9] serial = serial_number[0:6] try: if not country_id: ip = CommonService.get_ip_address(request) country_id = Device_Region().get_device_region(ip) # 判断序列号是否已和企业关联 company_serial_qs = CompanySerialModel.objects.filter(company__secret=company_id, serial_number=serial) if not company_serial_qs.exists(): return response.json(173) # 当序列号已关联UID company_serial = company_serial_qs[0] if company_serial.status == 0: # 该序列号未绑定企业 return response.json(173) elif company_serial.status == 1: # 绑定uid save_point = transaction.savepoint() # 设置事务保存点 count = 0 # 获取序列号的p2p类型 p2p = SerialNumberModel.objects.filter(serial_number=serial).values('p2p')[0]['p2p'] while count < 3: # 查询是否存在未绑定序列号的uid uid_qs = UIDModel.objects.filter(vpg__company_id=company_serial.company.id, vpg__region_id=country_id, status=0, p2p_type=p2p). \ order_by('id') if not uid_qs.exists(): return response.json(173) uid = uid_qs[0] 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=serial_number) 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), 'mac': CommonService.encode_data(uid.mac), '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, 'operation': '绑定uid', 'content': json.dumps(content), 'url': 'serialNumber/attachUID', } LogModel.objects.create(**log) transaction.savepoint_commit(save_point) # 提交事务 return response.json(0, res) return response.json(5) else: 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']), 'mac': CommonService.encode_data(uid['uid__mac']), '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) except Exception as e: if save_point: transaction.savepoint_rollback(save_point) # 事务回滚 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 and len(serial_number) == 9: token = int(CommonService.decode_data(token)) time_stamp = int(time_stamp) now_time = int(time.time()) distance = now_time - time_stamp if token != time_stamp or distance > 60000 or distance < -60000: # 为了全球化时间控制在一天内 return response.json(404) 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): serial_number = request_dict.get('serial_number', None) token = request_dict.get('token', None) time_stamp = request_dict.get('time_stamp', None) if not all([token, time_stamp, serial_number]): return response.json(444) token = int(CommonService.decode_data(token)) time_stamp = int(time_stamp) now_time = int(time.time()) distance = now_time - time_stamp if token != time_stamp or distance > 60000 or distance < -60000: # 为了全球化时间控制在一天内 return response.json(404) serial = serial_number[0:6] 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] # 删除iot设备信息表数据 iot = iotdeviceInfoModel.objects.filter(serial_number=serial) if iot.exists(): iot.delete() company_serial_qs = CompanySerialModel.objects.filter(id=uid_serial.company_serial.id) if company_serial_qs.exists(): company_serial = company_serial_qs[0] company_serial.status = 1 company_serial.save() mark = company_serial.company.mark dv_qs = Device_Info.objects.filter(serial_number=serial_number + mark) if dv_qs.exists(): # a.主用户删除设备 uid = dv_qs[0].UID dv_qs.delete() # 删除设备影子信息uid_set 外键关联删除设备推送配置信息 uid_push up_qs = UidPushModel.objects.filter(uid_set__uid=uid) DetectControllerView().do_delete_redis(uid) if up_qs.count() > 1: UidPushModel.objects.filter(uid_set__uid=uid).delete() else: up_qs.delete() UIDModel.objects.filter(uid=uid_serial.uid.uid).update(status=0) # 重置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, 'operation': '解绑uid', 'content': json.dumps(content), 'url': 'serialNumber/detachUID', } LogModel.objects.create(**log) return response.json(0) 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) p2p = request_dict.get('p2p', None) if id and status: serial_number_qs = SerialNumberModel.objects.filter(id=id) if serial_number_qs.exists(): serial_number_qs.update(**{'status': status, 'p2p': p2p}) return response.json(0) else: return response.json(173) else: return response.json(444)