feat:增加上传博客图片模块

This commit is contained in:
2025-10-25 22:53:46 +08:00
parent 6512c536dc
commit f6d1096dbc
7 changed files with 89 additions and 10 deletions

View File

@@ -1,6 +1,6 @@
from typing import List
from fastapi import APIRouter, Depends, Query, Request
from fastapi import APIRouter, Depends, Query, Request, UploadFile, File
from sqlalchemy.orm import Session
from config.auth import verify_token
@@ -10,7 +10,7 @@ from schemas.blog import BlogResponse, BlogQuery, BlogCategoryResponse, BlogStat
from schemas.blog_elastic import BlogSearch
from schemas.pagination import PageResult
from config.database import get_db
from service import blog_service, blog_elastic_service
from service import blog_service, blog_elastic_service, file_service
router = APIRouter(
prefix="/blog",
@@ -19,6 +19,11 @@ router = APIRouter(
)
@router.post("/file/upload", summary="上传博客图片", response_model=str)
async def sync_all_blog(md5: str, file: UploadFile = File(...)):
return await file_service.upload_file(md5, file)
@router.get("/sync", summary="同步博客到elastic", response_model=bool)
def sync_all_blog(db: Session = Depends(get_db)):
return blog_elastic_service.sync_all_blog(db)
@@ -46,12 +51,14 @@ def query_blog_by_condition(query: BlogQuery = Depends(),
def query_blog_by_id(blog_id: int, db: Session = Depends(get_db)):
return blog_service.query_blog_by_id(db, blog_id)
@router.get("/all/page", summary="分页查询博客", response_model=PageResult[BlogResponse])
def query_blog_by_page(current_page: int = Query(1, ge=1, alias="currentPage", description="当前页码"),
page_size: int = Query(10, ge=1, le=100, alias="pageSize", description="每页数量"),
db: Session = Depends(get_db), _=Depends(verify_token)):
return blog_service.query_blog_by_page(db, current_page, page_size, True)
@router.post("", summary="新增博客内容", response_model=bool)
def add_blog(blog: BlogCreate, db: Session = Depends(get_db), _=Depends(verify_token)):
return blog_service.add_blog(db, blog)

15
config/rustfs.py Normal file
View File

@@ -0,0 +1,15 @@
import boto3
from botocore.client import Config
from config.setting import settings
access_key = 'jRxroVX8PUuSOia71qE4'
secret_access = 'RZE82VATN1Gqj9xy3d5OzFvHoDBgwJ4PSf7IKuei'
s3 = boto3.client('s3',
endpoint_url=f'http://{settings.RUSTFS_HOST}:{settings.RUSTFS_PORT}',
aws_access_key_id=access_key,
aws_secret_access_key=secret_access,
config=Config(signature_version='s3v4'),
region_name='cn-east-1'
)

View File

@@ -8,6 +8,8 @@ class Settings(BaseSettings):
DB_PASSWORD: str
ES_HOST: str
FLUENTD_HOST: str
RUSTFS_HOST:str
RUSTFS_PORT: str
class Config:
env_file = ".env" # 指定.env文件路径

View File

@@ -1 +1 @@
fastapi~=0.115.12
fastapi~=0.115.12

View File

@@ -1,6 +1,6 @@
from typing import Optional
from pydantic import BaseModel, Field
from pydantic import BaseModel
from datetime import datetime

View File

@@ -17,11 +17,12 @@ def sync_all_blog(db: Session) -> bool:
if settings.ENVIRONMENT == 'dev':
return True
query = select(
stmt = select(
Blog.id,
Blog.title,
BlogCategory.name.label("category"),
BlogContent.content.label("content"),
Blog.is_approved.label("isApproved"),
Blog.create_time.label("createTime"),
Blog.update_time.label("updateTime"),
).select_from(Blog).outerjoin(
@@ -29,7 +30,7 @@ def sync_all_blog(db: Session) -> bool:
).outerjoin(
BlogContent, Blog.content_id == BlogContent.id
)
results = db.execute(query).fetchall()
results = db.execute(stmt).fetchall()
actions = [
{
@@ -40,6 +41,7 @@ def sync_all_blog(db: Session) -> bool:
"title": blog.title,
"category": blog.category,
"content": blog.content.decode("utf-8"),
"isApproved": blog.isApproved,
"createTime": blog.createTime.strftime("%Y-%m-%d %H:%M:%S"),
"updateTime": blog.updateTime.strftime("%Y-%m-%d %H:%M:%S")
}
@@ -106,10 +108,23 @@ def search_blog(keyword: str) -> List[BlogSearch]:
# 构造查询请求
body = {
"query": {
"multi_match": {
"query": keyword,
"fields": ["title^3", "content"],
"type": "phrase"
"bool": {
"must": [
{
"multi_match": {
"query": keyword,
"fields": ["title^3", "content"],
"type": "phrase"
}
}
],
"filter": [
{
"term": {
"isApproved": 1
}
}
]
}
},
"highlight": {

40
service/file_service.py Normal file
View File

@@ -0,0 +1,40 @@
from fastapi import UploadFile, File, HTTPException
from config.rustfs import s3
from config.setting import settings
ALLOWED_IMAGE_TYPES = [
"image/jpeg",
"image/png",
"image/gif",
"image/webp",
"image/svg+xml",
]
BUCKET = 'blog'
NGINX_PROXY = 'rustfs'
async def upload_file(md5: str, file: UploadFile = File(...)) -> str:
# 校验文件类型是否是图片
if file.content_type not in ALLOWED_IMAGE_TYPES:
raise HTTPException(
status_code=400,
detail="只允许上传图片文件 (JPEG, PNG, GIF, WEBP, SVG)"
)
file_ext = file.filename.split('.')[-1]
unique_filename = f"{md5}.{file_ext}"
file_content = await file.read()
# 上传到S3
s3.put_object(
Bucket=BUCKET,
Key=unique_filename,
Body=file_content,
ContentType=file.content_type
)
# 返回文件url
return f"{NGINX_PROXY}/{BUCKET}/{unique_filename}"