#!/usr/bin/env python3 # -*- coding: utf-8 -*- import json import logging import random import requests 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, MacModel 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, SERVER_TYPE, SERVER_DOMAIN_US, SERVER_DOMAIN_CN from Service.ModelService import ModelService from Object.AWS.S3Email import S3Email 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': 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) elif operation == 'changeSerialNumberStatus': return self.changeSerialNumberStatus(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) 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) p2p_type = request_dict.get('p2ptype', 1) 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] if serial_number[9:10]: p2p_type = serial_number[9:10] try: if not country_id: if SERVER_TYPE == 'Ansjer.us_config.formal_settings': # 国外正式配置使用固定ip进行测试 ip = '67.220.90.13' else: 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 with transaction.atomic(): count = 0 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_type). \ order_by('id') if not uid_qs.exists(): return response.json(173) 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(174) 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) # 修改其他数据库的序列号使用状态为已占用 company_serial_id = company_serial.id data = {'company_serial_id': company_serial_id, 'status': 3} if SERVER_TYPE == 'Ansjer.us_config.formal_settings': url = '{}serialNumber/changeSerialNumberStatus'.format(SERVER_DOMAIN_CN) elif SERVER_TYPE == 'Ansjer.cn_config.formal_settings': url = '{}serialNumber/changeSerialNumberStatus'.format(SERVER_DOMAIN_US) requests.post(url=url, data=data, timeout=2) 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] 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(): # 删除iot设备信息表数据 iot = iotdeviceInfoModel.objects.filter(serial_number=serial) if iot.exists(): iot.delete() uid = uid_serial.uid.uid 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() dv_qs = Device_Info.objects.filter(UID=uid) if dv_qs.exists(): # 删除设备 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() # 修改其他数据库的序列号使用状态为已使用 company_serial_id = company_serial_qs.id data = {'company_serial_id': company_serial_id, 'status': 1} if SERVER_TYPE == 'Ansjer.us_config.formal_settings': url = '{}serialNumber/changeSerialNumberStatus'.format(SERVER_DOMAIN_CN) elif SERVER_TYPE == 'Ansjer.cn_config.formal_settings': url = '{}serialNumber/changeSerialNumberStatus'.format(SERVER_DOMAIN_US) requests.post(url=url, data=data, timeout=2) 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)) 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): company_serial_id = request_dict.get('company_serial_id', None) status = request_dict.get('status', None) if not all([company_serial_id, status]): return response(444) try: # 更新CompanySerialModel表的序列号使用状态 CompanySerialModel.objects.filter(id=company_serial_id).update(status=int(status)) return response.json(0) except Exception as e: djangoLogger = logging.getLogger('django') djangoLogger.exception(repr(e)) return response.json(500, str(e))