first init
This commit is contained in:
6
core/routers/file/__init__.py
Normal file
6
core/routers/file/__init__.py
Normal file
@@ -0,0 +1,6 @@
|
||||
# -*- coding = utf-8 -*-
|
||||
# @Time : 2025/2/13 下午4:01
|
||||
# @File : __init__.py.py
|
||||
# @Software : PyCharm
|
||||
# @Author : xingc
|
||||
# @Desc : 文件存储模块
|
||||
76
core/routers/file/routes.py
Normal file
76
core/routers/file/routes.py
Normal file
@@ -0,0 +1,76 @@
|
||||
# -*- 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'
|
||||
)
|
||||
14
core/routers/file/schema.py
Normal file
14
core/routers/file/schema.py
Normal file
@@ -0,0 +1,14 @@
|
||||
# -*- coding = utf-8 -*-
|
||||
# @Time : 2025/2/13 下午5:01
|
||||
# @File : schema.py
|
||||
# @Software : PyCharm
|
||||
# @Author : xingc
|
||||
# @Desc :
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class FileOut(BaseModel):
|
||||
filename: str
|
||||
content_type: str
|
||||
size: int
|
||||
hash: str
|
||||
Reference in New Issue
Block a user