import logging import os import traceback import uuid import time import datetime from urllib import parse from django.http import FileResponse from rest_framework import status from rest_framework.permissions import IsAuthenticated from rest_framework.views import APIView from rest_framework_jwt.authentication import JSONWebTokenAuthentication from ChaCeRndTrans import settings from ChaCeRndTrans.basic import CCAIResponse from ChaCeRndTrans.code import SERVER_ERROR, PARAMS_ERR from utils.custom import RbacPermission, create_operation_history_log, generate_random_str from common.models import OperationHistoryLog logger = logging.getLogger('error') class UploadFileAPIView(APIView): ''' 上传附件 ''' authentication_classes = (JSONWebTokenAuthentication,) permission_classes = (IsAuthenticated,) def post(self, request, *args, **kwargs): upload_file = request.FILES.get("file", None) file_type = request.data.get("file_type", None) try: if not upload_file or not file_type: return CCAIResponse(msg="上传失败", status=status.HTTP_400_BAD_REQUEST) if upload_file.size > settings.MAX_FILE_SIZE: return CCAIResponse(msg="上传文件需小于或等于10M", status=status.HTTP_400_BAD_REQUEST) # 上传的是学员模板 # if file_type == "template-xlsx" or file_type == "template-xls": # name = os.path.splitext(upload_file.name)[0] # ext = os.path.splitext(upload_file.name)[-1] # file_name = name + generate_random_str(3) + ext # path_1, path_2 = file_type.split("-") # # 本地存储目录 # save_path = os.path.join(settings.FILE_PATH, path_1, path_2) # save_path = save_path.replace('\\', '/') # # 如果不存在则创建目录 # if not os.path.exists(save_path): # os.makedirs(save_path) # files = os.listdir(save_path) # 查找路径下的所有的文件夹及文件 # if path_2 == "xlsx": # n_path = os.path.join(settings.FILE_PATH, path_1, "xls") # if os.path.exists(n_path): # files2 = os.listdir(n_path) # 查找路径下的所有的文件夹及文件 # else: # files2 = [] # else: # n_path = os.path.join(settings.FILE_PATH, path_1, "xlsx") # if os.path.exists(n_path): # files2 = os.listdir(n_path) # 查找路径下的所有的文件夹及文件 # else: # files2 = [] # file_path = open(save_path + "/" + file_name, 'wb') # for chunk in upload_file.chunks(): # file_path.write(chunk) # file_path.close() # # 删除曾经的旧模板 # if len(files) > 0: # for each in files: # # 删除文件 # os.remove(save_path + "/" + each) # if len(files2) > 0: # for each in files: # # 删除文件 # os.remove(save_path + "/" + each) # # 操作记录 # # info = { # # "des": "上传模板", # # "detail": "后端存储路径: " + save_path + "/" + file_name # # } # # create_operation_history_log(request, info, OperationHistoryLog) # return CCAIResponse("success", status=status.HTTP_200_OK) # 文件名进行url编码 # file_name = parse.quote(upload_file.name) file_name = upload_file.name name = os.path.splitext(upload_file.name)[0] ext = os.path.splitext(upload_file.name)[-1] ct = time.time() # 取得系统时间 local_time = time.localtime(ct) date_head = time.strftime("%Y%m%d%H%M%S", local_time) # 格式化时间 date_m_secs = str(datetime.datetime.now().timestamp()).split(".")[-1] # 毫秒级时间戳 time_stamp = "%s%.3s" % (date_head, date_m_secs) # 拼接时间字符串 # print(time_stamp) # 本地存储目录 save_path = os.path.join(settings.FILE_PATH, file_type) save_path = save_path.replace('\\', '/') # save_path = os.path.join(settings.FILE_PATH, file_type) # 前端显示目录 start = file_name.rindex('.') # name = file_name[0: start] # type = file_name[start:] show_path = os.path.join(settings.SHOW_UPLOAD_PATH, file_type, time_stamp + ext) show_path = show_path.replace('\\', '/') # 如果不存在则创建目录 if not os.path.exists(save_path): os.makedirs(save_path) file_path = open(save_path + '/' + time_stamp + ext, 'wb') for chunk in upload_file.chunks(): file_path.write(chunk) file_path.close() # 操作记录 # info = { # "des": "上传附件", # "detail": "后端存储路径: " + save_path + "/" + file_name + ", 前端显示路径: " + show_path # } # create_operation_history_log(request, info, OperationHistoryLog) return CCAIResponse(show_path) except Exception as e: logger.error("upload file failed: \n%s" % traceback.format_exc()) return CCAIResponse("上传失败", SERVER_ERROR) class DeleteFileAPIView(APIView): ''' 删除附件 ''' def post(self, request, *args, **kwargs): tempdict = request.data.copy() if 'upload_url' not in tempdict and tempdict['upload_url'] == '': return CCAIResponse("upload_url参数不能为空!", status=status.HTTP_400_BAD_REQUEST) upload_url = tempdict['upload_url'].replace(settings.SHOW_UPLOAD_PATH, settings.FILE_PATH) start = upload_url.rindex('/') # name_start = upload_url.rindex('_') # type_start = upload_url.rindex('.') #拼接本地文件路劲 # local_path = upload_url[0: start] + '/' + upload_url[name_start+1: type_start] # local_url = local_path + upload_url[start: name_start] + upload_url[type_start:] local_path = upload_url[0: start + 1] import os if os.path.exists(upload_url): # 如果文件存在 # 删除文件,可使用以下两种方法。 os.remove(upload_url) # 删除空目录,不是空目录时候rmdir不会删除 try: os.rmdir(local_path) except Exception as e: logger.error("rmdir failed: \n%s" % traceback.format_exc()) # 操作记录 # info = { # "des": "删除附件", # "detail": "后端存储路径: " + local_path # } # create_operation_history_log(request, info, OperationHistoryLog) return CCAIResponse("success") else: return CCAIResponse("文件不存在") class DownLoadFileAPIView(APIView): ''' 下载附件 ''' authentication_classes = (JSONWebTokenAuthentication,) permission_classes = (IsAuthenticated,) def post(self, request, *args, **kwargs): download_file = request.data.get("ccw_file_path") try: if download_file is None or download_file == "": return CCAIResponse(PARAMS_ERR, SERVER_ERROR) re_file = download_file.replace('/upload/file/', settings.FILE_PATH) file = open(re_file, 'rb') # url解码 file_name = parse.unquote(file.name) response = FileResponse(file) response['Content-Type'] = 'application/octet-stream' response['Content-Disposition'] = 'attachment;filename="' + file_name + '"' # 操作记录 # info = { # "des": "下载附件", # "detail": "后端存储路径: " + re_file + ", url解码文件名: " + file_name # } # create_operation_history_log(request, info, OperationHistoryLog) return response except Exception as e: logger.error("download file failed: \n%s" % traceback.format_exc()) return CCAIResponse("下载失败", SERVER_ERROR)