#!/usr/bin/env python3 # -*- coding: utf-8 -*- import base64 import json import logging import os import time import zipfile import xlwt from django.db.models import Count from django.http import StreamingHttpResponse, HttpResponse, QueryDict from django.utils.decorators import method_decorator from django.views import View from django.views.decorators.csrf import csrf_exempt from django.db import transaction from AnsjerUIDManage.config import BASE_DIR from Model.models import UIDModel, UserUIDModel, UserModel, LogModel, MacModel, OrderTaskModel, OrderUIDModel, \ SerialNumberModel, OrderSerialNumberModel, UserSerialNumberModel, CompanySerialModel from Object.RedisObject import RedisObject from Object.TokenObject import TokenObject from Object.ResponseObject import ResponseObject from Service.CommonService import CommonService from bulk_update.helper import bulk_update class UploadUIDFileView(View): @method_decorator(csrf_exempt) def dispatch(self, request, *args, **kwargs): return super(UploadUIDFileView, self).dispatch(request, *args, **kwargs) def get(self, request, *args, **kwargs): request.encoding = 'utf-8' request_dict = request.GET fileName = request.FILES.get('fileName', None) return self.validate(fileName, request_dict, request) def post(self, request, *args, **kwargs): request.encoding = 'utf-8' request_dict = request.POST fileName = request.FILES.get('fileName', None) return self.validate(fileName, request_dict, request) def validate(self, fileName, request_dict, request): token = request_dict.get('token', None) area = request_dict.get('area', None) isReset = request_dict.get('isReset', 0) content = request_dict.get('fileName', None) print('content') print(content) content = base64.b64decode(content).decode().strip() content = content[3:(len(content) - 3)] uids = content.split('\n') # print(uids) # print(len(uids)) response = ResponseObject() tko = TokenObject(token) if tko.code != 0: return response.json(tko.code) # if not fileName and not area: # return response.json(444, 'fileName,area') data = {} duplicate = [] for line in uids: if len(line) < 20: continue if data.__contains__(line): duplicate.append(line) else: data[line] = '' if isReset == 0: return self.do_insert(data, duplicate, area, response, request, tko) else: return self.do_reset(data, response, area, request, tko) @transaction.atomic def do_insert(self, data, duplicate, area, response, request, token): bulk = [] count = 0 add_time = int(time.time()) update_time = int(time.time()) keys = data.keys() # 获取最新的mac mac = MacModel.objects.filter().values('id', 'value', 'is_active')[0] if not mac['is_active']: return response.json(175) # redisObject = RedisObject(db=3) key = '' tmpMac = mac['value'] savePoint = None for item in keys: key = item.strip() # value = redisObject.get_data(key) # if value is False: # # redisObject.set_data(key, '1', 600) # else: # duplicate.append(key) # continue bulk.append(UIDModel( uid=item.strip(), uid_extra='', status=0, add_time=add_time, update_time=update_time, area=area, mac=mac['value'] )) try: try: if (count % 5000) == 0: savePoint = transaction.savepoint() UIDModel.objects.bulk_create(bulk) bulk.clear() data = { 'value': mac['value'], 'is_active': tmpMac is not None } MacModel.objects.filter().update(**data) except Exception as e: # print('--------------------------error 5000') # print(repr(e)) if savePoint: transaction.rollback(savePoint) djangoLogger = logging.getLogger('django') djangoLogger.exception(repr(e)) return response.json(174, str(e)) else: savePoint = None except Exception as e: # print('--------------------------error 5001') # print(repr(e)) return response.json(174, str(e)) count += 1 tmpMac = CommonService.updateMac(mac['value']) if tmpMac is None: # 能分配的mac已用完 break else: mac['value'] = tmpMac # 当bulk不足5000时,还有数据要插入 try: try: savePoint = transaction.savepoint() # 事务保存点 if len(bulk) > 0: UIDModel.objects.bulk_create(bulk) bulk.clear() except Exception as e: # print('--------------------------error') # print(repr(e)) if savePoint: transaction.rollback(savePoint) return response.json(174) else: del data del bulk data = { 'value': mac['value'], 'is_active': tmpMac is not None } MacModel.objects.filter().update(**data) except Exception as e: # print('--------------------------error 1111') # print(repr(e)) return response.json(174) # print('重复:') # print(duplicate) operation = self.formatOperation(operation='上传', quantity=int(count), area=int(area)) print(operation) self.add_log(request, operation, token) if tmpMac is None: return response.json(175, {'last_uid': key}) return response.json(0, {'count': count, 'duplicate_count': len(duplicate), 'data': duplicate}) def do_reset(self, data, response, area, request, token): keys = data.keys() uids = [] count = 0 for key in keys: uids.append(key.strip()) if len(uids) % 5000 == 0: count += self.do_update_uid_status(uids, area) uids.clear() if len(uids) > 0: count += self.do_update_uid_status(uids, area) uids.clear() operation = self.formatOperation('重置', int(count), int(area)) self.add_log(request, operation, token) return response.json(0) def do_update_uid_status(self, uids, area): uid_qs = UIDModel.objects.filter(uid__in=uids, area=area, status=2) if uid_qs.exists(): uid_ids = [] for uid in uid_qs: if uid.status == 2: uid.status = 1 uid_ids.append(uid.id) UIDModel.objects.bulk_update(uid_qs, fields=['status']) try: OrderUIDModel.objects.filter(uid__id__in=tuple(uid_ids)).delete() except Exception as e: print(e) return uid_qs.count() return 0 def add_log(self, request, operation, token): ip = CommonService.get_ip_address(request) now_time = time.time() content = json.loads(json.dumps(request.POST)) user_qs = UserModel.objects.filter(id=token.userID) if content.__contains__('fileName'): del content['fileName'] log = { 'status': 200, 'content': json.dumps(content), 'ip': ip, 'time': now_time, 'url': 'upload', 'operation': operation, 'user': user_qs[0] } try: LogModel.objects.create(**log) except Exception as e: print('出错') print(repr(e)) def formatOperation(self, operation, quantity, area): str = '{operation}{quantity}个{area}UID' if area == 0: return str.format(operation=operation, quantity=quantity, area='国内') else: return str.format(operation=operation, quantity=quantity, area='国外') class UploadSerialNumberFileView(View): # 上传文件重置序列号使用状态 @method_decorator(csrf_exempt) def dispatch(self, request, *args, **kwargs): return super(UploadSerialNumberFileView, self).dispatch(request, *args, **kwargs) def get(self, request, *args, **kwargs): request.encoding = 'utf-8' request_dict = request.GET return self.reset_serial_number(request_dict, request) def post(self, request, *args, **kwargs): request.encoding = 'utf-8' request_dict = request.POST return self.reset_serial_number(request_dict, request) def reset_serial_number(self, request_dict, request): token = request_dict.get('token', None) p2p = request_dict.get('area', None) isReset = request_dict.get('isReset', 0) content = request_dict.get('fileName', None) print('content: ', content) response = ResponseObject() tko = TokenObject(token) if tko.code != 0: return response.json(tko.code) if not p2p or not content: return response.json(444, 'p2p, content') try: content = base64.b64decode(content).decode().strip() content = content[3:(len(content)-3)] serial_number_list = content.split('\r\n') print('serial_number_list', serial_number_list) # 重置使用状态为已下载的序列号为已分配 serial_number_qs = SerialNumberModel.objects.filter(serial_number__in=serial_number_list, p2p=p2p, use_status=2) count = serial_number_qs.count() # 需要重置的序列号个数 if count: with transaction.atomic(): serial_number_qs.update(use_status=1) OrderSerialNumberModel.objects.filter(serial_number__in=serial_number_qs).delete() operation = self.formatOperation('重置', int(count), p2p) self.add_log(request, operation, tko) return response.json(0) except Exception as e: # print(e) return response.json(500, repr(e)) def add_log(self, request, operation, token): ip = CommonService.get_ip_address(request) now_time = time.time() content = json.loads(json.dumps(request.POST)) user_qs = UserModel.objects.filter(id=token.userID) if content.__contains__('fileName'): del content['fileName'] log = { 'status': 200, 'content': json.dumps(content), 'ip': ip, 'time': now_time, 'url': 'upload', 'operation': operation, 'user': user_qs[0] } LogModel.objects.create(**log) def formatOperation(self, operation, quantity, p2p): operate = '{operation}{quantity}个{p2p}序列号' p2p = '宸云' if p2p == '1' else 'TUTK' return operate.format(operation=operation, quantity=quantity, p2p=p2p) class DownloadUIDFileView(View): @method_decorator(csrf_exempt) def dispatch(self, request, *args, **kwargs): return super(DownloadUIDFileView, self).dispatch(request, *args, **kwargs) def get(self, request, *args, **kwargs): request.encoding = 'utf-8' request_dict = request.GET return self.validate(request_dict) def post(self, request, *args, **kwargs): request.encoding = 'utf-8' request_dict = request.POST return self.validate(request_dict) def validate(self, request_dict): token = request_dict.get('token', None) area = request_dict.get('area', None) quantity = int(request_dict.get('quantity', None)) fileType = request_dict.get('fileType', None) order_number = request_dict.get('order_number', None) board = request_dict.get('board', None) plan = request_dict.get('plan', None) checksum = request_dict.get('checksum', None) ic_model = request_dict.get('ic_model', None) order_quantity = request_dict.get('order_quantity', None) response = ResponseObject() # print(area) # print(quantity) token = TokenObject(token) if token.code != 0: return response.json(token.code) if not area or not order_number or not board or not plan or not checksum or not ic_model or not order_quantity or not fileType: return response.json(444) area = int(area) if area >= 0 and quantity > 0: # 保存订单信息 now_time = int(time.time()) order = { 'order_number': order_number, 'board': board, 'plan': plan, 'checksum': checksum, 'ic_model': ic_model, 'quantity': order_quantity, 'add_time': now_time } tmp = OrderTaskModel.objects.create(**order) print(tmp) order = OrderTaskModel.objects.filter(order_number=order_number).order_by('-add_time')[0] uid_qs = UserUIDModel.objects.filter(user__id=token.userID, uid__status=1, uid__area=area) uid_values = uid_qs.values('uid__id', 'uid__uid', 'uid__mac', 'uid__uid_extra', 'uid__add_time', 'uid__update_time', 'uid__area') count = uid_values.count() if count < quantity: return response.json(444, '设备UID不足') if uid_values.exists(): uid_values = uid_values[0:quantity] uid_qs = uid_qs[0: quantity] if fileType == 'txt': # return self.download_txt(uid_values, uid_qs, order) # return self.download_excel(uid_values, order) return self.download_zip(uid_values, order) elif fileType == 'excel': return self.download_excel(uid_values, order) else: return response.json(444, 'fileType') else: return response.json(444, '111') else: return response.json(444, '222') def download_txt(self, uid_values, uid_qs, order): updates = [] updates_uid = [] content = '' now_time = int(time.time()) for i in range(len(uid_values)): # print(item) item = uid_values[i] mac: str = item['uid__mac'] index = mac.rfind(':') tmp = mac[0:index] + '\t' + mac[index:] content += tmp + '\t' content += item['uid__uid'].strip() content += '\r\n' uidModel = UIDModel( id=item['uid__id'], uid=item['uid__uid'], mac=item['uid__mac'], uid_extra=item['uid__uid_extra'], status=2, add_time=item['uid__add_time'], update_time=now_time, area=item['uid__area'] ) updates.append(uidModel) order_uid = OrderUIDModel(uid=uidModel, order=order, add_time=now_time, update_time=now_time) updates_uid.append(order_uid) if len(updates) % 5000 == 0: UIDModel.objects.bulk_update(updates, fields=["status"]) OrderUIDModel.objects.bulk_create(updates_uid) updates.clear() updates_uid.clear() # print(item['uid__uid']) if len(updates) > 0: UIDModel.objects.bulk_update(updates, fields=["status"]) OrderUIDModel.objects.bulk_create(updates_uid) updates.clear() updates_uid.clear() del updates del updates_uid content = content[0:len(content) - 1] response = StreamingHttpResponse(content) response['Content-Type'] = 'application/octet-stream' response['Content-Disposition'] = 'attachment;filename=UID'+time.strftime('-%Y-%m-%d-%H-%M-%S', time.localtime()) + '.txt' return response def download_excel(self, uid_qs, order): response = HttpResponse(content_type='application/vnd.ms-excel') response['Content-Disposition'] = 'attachment; filename=UID' + time.strftime('-%Y-%m-%d-%H-%M-%S', time.localtime()) + '.xls' workbook = xlwt.Workbook(encoding='utf-8') sheet1 = workbook.add_sheet('UID') # row1 = [u'设备UID'] # for i in range(0, len(row1)): # sheet1.write(0, i, row1[i]) num = 1 updates = [] updates_uid = [] now_time = int(time.time()) for item in uid_qs: uid = item['uid__uid'] mac = item['uid__mac'] index = mac.rfind(':') sheet1.write(num, 0, mac[0:index]) sheet1.write(num, 1, mac[index:]) sheet1.write(num, 2, uid) num += 1 uidModel = UIDModel( id=item['uid__id'], uid=item['uid__uid'], mac=item['uid__mac'], uid_extra=item['uid__uid_extra'], status=2, add_time=item['uid__add_time'], update_time=now_time, area=item['uid__area'] ) updates.append(uidModel) order_uid = OrderUIDModel(uid=uidModel, order=order, add_time=now_time, update_time=now_time) updates_uid.append(order_uid) if len(updates) % 5000 == 0: UIDModel.objects.bulk_update(updates, fields=["status"]) OrderUIDModel.objects.bulk_create(updates_uid) updates.clear() updates_uid.clear() # print(item['uid__uid']) if len(updates) > 0: UIDModel.objects.bulk_update(updates, fields=["status"]) OrderUIDModel.objects.bulk_create(updates_uid) updates.clear() updates_uid.clear() UIDModel.objects.bulk_update(updates, fields=["status"]) workbook.save(response) return response def download_zip(self, uid_qs, order): dir_name = 'static/' + time.strftime('%Y_%m_%d_%H_%M_%S', time.localtime()) path = '/'.join((BASE_DIR, dir_name)).replace('\\', '/') + '/' if not os.path.exists(path): os.mkdir(path) filename = time.strftime('_%Y_%m_%d_%H_%M_%S', time.localtime()) txt_filename = 'UID' + filename + '.txt' excel_filename = 'UID' + filename + '.xls' txt_file = open(path + txt_filename, 'w+') workbook = xlwt.Workbook(encoding='utf-8') sheet1 = workbook.add_sheet('UID') num = 1 updates = [] updates_uid = [] content = '' now_time = int(time.time()) for i in range(len(uid_qs)): # print(item) item = uid_qs[i] uid = item['uid__uid'] mac = item['uid__mac'] index = mac.rfind(':') tmp = mac[0:index] + '\t' + mac[index:] content += tmp + '\t' content += item['uid__uid'].strip() content += '\r\n' sheet1.write(num, 0, mac[0:index]) sheet1.write(num, 1, mac[index:]) sheet1.write(num, 2, uid) num += 1 uidModel = UIDModel( id=item['uid__id'], uid=item['uid__uid'], mac=item['uid__mac'], uid_extra=item['uid__uid_extra'], status=2, add_time=item['uid__add_time'], update_time=now_time, area=item['uid__area'] ) updates.append(uidModel) order_uid = OrderUIDModel(uid=uidModel, order=order, add_time=now_time, update_time=now_time) updates_uid.append(order_uid) if len(updates) % 5000 == 0: UIDModel.objects.bulk_update(updates, fields=["status"]) OrderUIDModel.objects.bulk_create(updates_uid) updates.clear() updates_uid.clear() # print(item['uid__uid']) if len(updates) > 0: UIDModel.objects.bulk_update(updates, fields=["status"]) OrderUIDModel.objects.bulk_create(updates_uid) updates.clear() updates_uid.clear() del updates del updates_uid content = content[0:len(content) - 1] txt_file.write(content) txt_file.close() workbook.save(path + excel_filename) zip_name = path[0:path.rfind('/')] + '.zip' return self.get_zip(path, os.listdir(path), zip_name) def get_zip(self, path, files, zip_name): zp = zipfile.ZipFile(zip_name, 'w', zipfile.ZIP_DEFLATED) for file in files: zp.write(filename=(path + file), arcname=str(file)) zp.close() response = StreamingHttpResponse(open(zip_name, 'rb')) response['content_type'] = "application/octet-stream" response['Content-Disposition'] = 'attachment; filename=UID' + time.strftime('_%Y_%m_%d_%H_%M_%S', time.localtime()) + '.zip' return response class DownloadSerialNumberFileView(View): @method_decorator(csrf_exempt) def dispatch(self, request, *args, **kwargs): return super(DownloadSerialNumberFileView, self).dispatch(request, *args, **kwargs) def get(self, request, *args, **kwargs): request.encoding = 'utf-8' request_dict = request.GET return self.validate(request_dict) def post(self, request, *args, **kwargs): request.encoding = 'utf-8' request_dict = request.POST return self.validate(request_dict) def validate(self, request_dict): token = request_dict.get('token', None) area = request_dict.get('area', None) quantity = int(request_dict.get('quantity', None)) fileType = request_dict.get('fileType', None) order_number = request_dict.get('order_number', None) board = request_dict.get('board', None) plan = request_dict.get('plan', None) checksum = request_dict.get('checksum', None) ic_model = request_dict.get('ic_model', None) order_quantity = request_dict.get('order_quantity', None) response = ResponseObject() # print(area) # print(quantity) token = TokenObject(token) if token.code != 0: return response.json(token.code) if not area or not order_number or not board or not plan or not checksum or not ic_model or not order_quantity or not fileType: return response.json(444) area = int(area) if area >= 0 and quantity > 0: # 保存订单信息 now_time = int(time.time()) order = { 'order_number': order_number, 'board': board, 'plan': plan, 'checksum': checksum, 'ic_model': ic_model, 'quantity': order_quantity, 'add_time': now_time } tmp = OrderTaskModel.objects.create(**order) print(tmp) order = OrderTaskModel.objects.filter(order_number=order_number).order_by('-add_time')[0] user_qs = UserModel.objects.filter(id=token.userID) if not user_qs.exists(): return response.json(9) user = user_qs[0] result = UserSerialNumberModel.objects.filter(user__id=user.id, serial_number__p2p=area, serial_number__use_status=1).aggregate( num=Count('serial_number__use_status')) us_qs = UserSerialNumberModel.objects.filter(user__id=user.id, serial_number__p2p=area, serial_number__use_status=1).values('serial_number__serial_number') sns = [] for us in us_qs: sns.append(us['serial_number__serial_number']) cs_qs = CompanySerialModel.objects.filter(serial_number__in=sns, status=1).values('serial_number') sns = [] for cs in cs_qs: sns.append(cs['serial_number']) sn_qs = SerialNumberModel.objects.filter(serial_number__in=sns) count = result['num'] if count < quantity: return response.json(444, '序列号不足') if sn_qs.exists(): sn_qs = sn_qs[0: quantity] if fileType == 'txt': # return self.download_txt(uid_values, uid_qs, order) # return self.download_excel(uid_values, order) fileTypeName = 'chenyun' if area == 2: fileTypeName = 'tutk' return self.download_zip(sn_qs, order , fileTypeName ) else: return response.json(444, 'fileType') else: return response.json(444, '111') else: return response.json(444, '222') def download_zip(self, sn_qs, order , fileTypeName): dir_name = 'static/' + time.strftime('%Y_%m_%d_%H_%M_%S', time.localtime()) path = '/'.join((BASE_DIR, dir_name)).replace('\\', '/') + '/' if not os.path.exists(path): os.mkdir(path) filename = time.strftime('_%Y_%m_%d_%H_%M_%S', time.localtime()) txt_filename = 'SerialNumber' + fileTypeName +'_'+ filename + '.txt' excel_filename = 'SerialNumber' + fileTypeName + '_' + filename + '.xls' txt_file = open(path + txt_filename, 'w+') workbook = xlwt.Workbook(encoding='utf-8') sheet1 = workbook.add_sheet('SerialNumber') num = 0 updates = [] updates_serial_number = [] content = '' now_time = int(time.time()) for i in range(len(sn_qs)): # print(item) item = sn_qs[i] serial_number = item.serial_number sheet1.write(num, 0, serial_number + '11A') num += 1 content += serial_number.strip() + '11A' content += '\n' serialNumberModel = SerialNumberModel( id=item.id, serial_number = serial_number, status=item.status, use_status=2, p2p=item.p2p, add_time=item.add_time ) updates.append(serialNumberModel) order_serial_number = OrderSerialNumberModel(serial_number=item, order=order, add_time=now_time, update_time=now_time) updates_serial_number.append(order_serial_number) if len(updates) % 5000 == 0: bulk_update(updates) OrderSerialNumberModel.objects.bulk_create(updates_serial_number) updates.clear() updates_serial_number.clear() # print(item['uid__uid']) if len(updates) > 0: bulk_update(updates) OrderSerialNumberModel.objects.bulk_create(updates_serial_number) updates.clear() updates_serial_number.clear() del updates del updates_serial_number content = content[0:len(content) - 1] txt_file.write(content) txt_file.close() workbook.save(path + excel_filename) zip_name = path[0:path.rfind('/')] + '.zip' return self.get_zip(path, os.listdir(path), zip_name , fileTypeName) def get_zip(self, path, files, zip_name, fileTypeName ): zp = zipfile.ZipFile(zip_name, 'w', zipfile.ZIP_DEFLATED) for file in files: zp.write(filename=(path + file), arcname=str(file)) zp.close() response = StreamingHttpResponse(open(zip_name, 'rb')) response['content_type'] = "application/octet-stream" response['Content-Disposition'] = 'attachment; filename=SerialNumber_'+ fileTypeName + time.strftime('_%Y_%m_%d_%H_%M_%S', time.localtime()) + '.zip' return response