77 lines
2.4 KiB
Python
77 lines
2.4 KiB
Python
# -*- coding = utf-8 -*-
|
|
# @Time : 2025/2/13 下午4:50
|
|
# @File : routes.py
|
|
# @Software : PyCharm
|
|
# @Author : xingc
|
|
# @Desc :
|
|
import hashlib
|
|
import logging
|
|
import os
|
|
from io import BytesIO
|
|
from typing import Literal
|
|
|
|
from fastapi import APIRouter, UploadFile, File, status, HTTPException, Depends
|
|
from PIL import Image
|
|
|
|
from config import settings
|
|
from . import schema
|
|
from core.base.schema import BaseResponse
|
|
|
|
logger = logging.getLogger(__name__)
|
|
file_router = APIRouter(prefix='/file', tags=['文件存储模块'])
|
|
|
|
|
|
@file_router.post('/{upload_type}/upload', response_model=BaseResponse[schema.FileOut])
|
|
async def upload_file(
|
|
upload_type: Literal['card', 'chat', 'avatar'],
|
|
file: UploadFile = File(...)
|
|
):
|
|
# 验证文件类型
|
|
if file.content_type not in settings.UPLOADED_ALLOWED_MIME_TYPES:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_415_UNSUPPORTED_MEDIA_TYPE,
|
|
detail=f'Unsupported media type: {file.content_type}'
|
|
)
|
|
|
|
# 验证文件大小
|
|
if file.size > settings.UPLOADED_MAX_FILE_SIZE:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_413_REQUEST_ENTITY_TOO_LARGE,
|
|
detail=f'File exceeds maximum size'
|
|
)
|
|
|
|
try:
|
|
file_chunks = await file.read()
|
|
file_hash = hashlib.sha256(file_chunks).hexdigest()
|
|
file_name = f'{file_hash}.jpg'
|
|
dirname_args = [settings.UPLOADED_FILES_DIR, upload_type.lower()]
|
|
if upload_type.lower() != 'card':
|
|
dirname_args.append('test')
|
|
|
|
save_path = os.path.join(*dirname_args)
|
|
save_file_path = os.path.join(*dirname_args, file_name)
|
|
if os.path.exists(save_file_path) is False:
|
|
# 创建目录
|
|
os.makedirs(save_path, exist_ok=True)
|
|
|
|
img = Image.open(BytesIO(file_chunks))
|
|
img = img.convert("RGB")
|
|
img.save(save_file_path, format="JPEG")
|
|
|
|
file_info = {
|
|
'filename': file_name,
|
|
'content_type': file.content_type,
|
|
'size': os.path.getsize(save_path),
|
|
'hash': file_hash,
|
|
'url': save_file_path
|
|
}
|
|
return {'data': file_info}
|
|
|
|
except Exception as e:
|
|
logger.error(f'Upload failed: {str(e)}')
|
|
logger.exception(e)
|
|
raise HTTPException(
|
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
detail=f'File upload failed'
|
|
)
|