feat:增加查询博客相邻记录功能
This commit is contained in:
@@ -5,7 +5,8 @@ from sqlalchemy.orm import Session
|
|||||||
|
|
||||||
from config.auth import verify_token
|
from config.auth import verify_token
|
||||||
from schemas.blog import BlogResponse, BlogQuery, BlogCategoryResponse, BlogStatsResponse, \
|
from schemas.blog import BlogResponse, BlogQuery, BlogCategoryResponse, BlogStatsResponse, \
|
||||||
BlogLatestResponse, BlogCommentCreate, BlogCommentResponse, BlogVisitResponse, BlogCreate, BlogUpdate
|
BlogLatestResponse, BlogCommentCreate, BlogCommentResponse, BlogVisitResponse, BlogCreate, BlogUpdate, \
|
||||||
|
BlogAdjacentResponse
|
||||||
from schemas.blog_elastic import BlogSearch
|
from schemas.blog_elastic import BlogSearch
|
||||||
from schemas.pagination import PageResult
|
from schemas.pagination import PageResult
|
||||||
from config.database import get_db
|
from config.database import get_db
|
||||||
@@ -61,6 +62,11 @@ def delete_blog(blog_id: int, db: Session = Depends(get_db), _=Depends(verify_to
|
|||||||
return blog_service.delete_blog(db, blog_id)
|
return blog_service.delete_blog(db, blog_id)
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/{blog_id}/adjacent", summary="查询相邻博客", response_model=List[BlogAdjacentResponse])
|
||||||
|
def query_blog_latest(blog_id: int, db: Session = Depends(get_db)):
|
||||||
|
return blog_service.query_blog_adjacent(db, blog_id)
|
||||||
|
|
||||||
|
|
||||||
@router.put("/{blog_id}/comment", summary="新增博客评论", response_model=bool)
|
@router.put("/{blog_id}/comment", summary="新增博客评论", response_model=bool)
|
||||||
def add_blog_comment(blog_id: int, blog_comment: BlogCommentCreate, request: Request, db: Session = Depends(get_db)):
|
def add_blog_comment(blog_id: int, blog_comment: BlogCommentCreate, request: Request, db: Session = Depends(get_db)):
|
||||||
return blog_service.add_blog_comment(db, request, blog_id, blog_comment)
|
return blog_service.add_blog_comment(db, request, blog_id, blog_comment)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ from sqlalchemy.orm import sessionmaker
|
|||||||
|
|
||||||
from config.setting import settings
|
from config.setting import settings
|
||||||
|
|
||||||
DATABASE_URL = f"mysql+pymysql://{settings.DB_USER}:{settings.DB_PASSWORD}@{settings.DB_HOST}:{settings.DB_PORT}/{settings.DB_NAME}"
|
DATABASE_URL = f"mysql+pymysql://root:{settings.DB_PASSWORD}@{settings.DB_HOST}:3306/blog"
|
||||||
|
|
||||||
engine = create_engine(url=DATABASE_URL, pool_pre_ping=True, pool_recycle=3600)
|
engine = create_engine(url=DATABASE_URL, pool_pre_ping=True, pool_recycle=3600)
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,16 @@
|
|||||||
from elasticsearch import Elasticsearch
|
from elasticsearch import Elasticsearch
|
||||||
|
|
||||||
|
from config.setting import settings
|
||||||
from schemas.blog_elastic import BLOG_MAPPING
|
from schemas.blog_elastic import BLOG_MAPPING
|
||||||
from config.logging import logger
|
from config.logging import logger
|
||||||
|
|
||||||
ES_HOSTS = "http://host.docker.internal:9200"
|
ES_HOST = f"http://{settings.ES_HOST}:9200"
|
||||||
ES_USER = "elastic"
|
ES_USER = "elastic"
|
||||||
ES_PASSWORD = "19940822Cxx"
|
ES_PASSWORD = "19940822Cxx"
|
||||||
BLOG_INDEX = "blog"
|
BLOG_INDEX = "blog"
|
||||||
|
|
||||||
# 注意Python的elasticsearch的版本要和服务器的一致
|
# 注意Python的elasticsearch的版本要和服务器的一致
|
||||||
es = Elasticsearch(ES_HOSTS, http_auth=(ES_USER, ES_PASSWORD))
|
es = Elasticsearch(ES_HOST, http_auth=(ES_USER, ES_PASSWORD))
|
||||||
|
|
||||||
if not es.indices.exists(index=BLOG_INDEX):
|
if not es.indices.exists(index=BLOG_INDEX):
|
||||||
es.indices.create(index=BLOG_INDEX, body=BLOG_MAPPING)
|
es.indices.create(index=BLOG_INDEX, body=BLOG_MAPPING)
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ logger.add(
|
|||||||
|
|
||||||
logger.add(
|
logger.add(
|
||||||
log_to_fluent,
|
log_to_fluent,
|
||||||
level="INFO", # 处理 INFO 及以上级别
|
level=LOG_LEVEL, # 处理 INFO 及以上级别
|
||||||
format="{message}", # 原始消息(实际使用结构化数据)
|
format="{message}", # 原始消息(实际使用结构化数据)
|
||||||
backtrace=True, # 启用堆栈回溯
|
backtrace=True, # 启用堆栈回溯
|
||||||
diagnose=True # 显示诊断信息
|
diagnose=True # 显示诊断信息
|
||||||
|
|||||||
@@ -2,13 +2,11 @@ from pydantic_settings import BaseSettings
|
|||||||
|
|
||||||
|
|
||||||
class Settings(BaseSettings):
|
class Settings(BaseSettings):
|
||||||
DB_HOST: str
|
ENVIRONMENT: str
|
||||||
DB_PORT: int
|
|
||||||
DB_USER: str
|
|
||||||
DB_PASSWORD: str
|
|
||||||
DB_NAME: str
|
|
||||||
|
|
||||||
LOG_LEVEL: str
|
LOG_LEVEL: str
|
||||||
|
DB_HOST: str
|
||||||
|
DB_PASSWORD: str
|
||||||
|
ES_HOST: str
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
env_file = ".env" # 指定.env文件路径
|
env_file = ".env" # 指定.env文件路径
|
||||||
|
|||||||
@@ -83,6 +83,14 @@ class BlogLatestResponse(BaseModel):
|
|||||||
from_attributes = True
|
from_attributes = True
|
||||||
|
|
||||||
|
|
||||||
|
class BlogAdjacentResponse(BaseModel):
|
||||||
|
id: int
|
||||||
|
title: str
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
from_attributes = True
|
||||||
|
|
||||||
|
|
||||||
class BlogCommentCreate(BaseModel):
|
class BlogCommentCreate(BaseModel):
|
||||||
parentId: int
|
parentId: int
|
||||||
name: str
|
name: str
|
||||||
|
|||||||
@@ -8,11 +8,15 @@ from sqlalchemy import select
|
|||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
from config.elastic import es, BLOG_INDEX
|
from config.elastic import es, BLOG_INDEX
|
||||||
|
from config.setting import settings
|
||||||
from models.blog import Blog, BlogCategory, BlogContent
|
from models.blog import Blog, BlogCategory, BlogContent
|
||||||
from schemas.blog_elastic import BlogElastic, BlogSearch
|
from schemas.blog_elastic import BlogElastic, BlogSearch
|
||||||
|
|
||||||
|
|
||||||
def sync_all_blog(db: Session) -> bool:
|
def sync_all_blog(db: Session) -> bool:
|
||||||
|
if settings.ENVIRONMENT == 'dev':
|
||||||
|
return True
|
||||||
|
|
||||||
query = select(
|
query = select(
|
||||||
Blog.id,
|
Blog.id,
|
||||||
Blog.title,
|
Blog.title,
|
||||||
@@ -54,6 +58,9 @@ def sync_all_blog(db: Session) -> bool:
|
|||||||
|
|
||||||
|
|
||||||
def add_blog_elastic(blog: BlogElastic) -> bool:
|
def add_blog_elastic(blog: BlogElastic) -> bool:
|
||||||
|
if settings.ENVIRONMENT == 'dev':
|
||||||
|
return True
|
||||||
|
|
||||||
now = datetime.now()
|
now = datetime.now()
|
||||||
blog.createTime = now.strftime("%Y-%m-%d %H:%M:%S")
|
blog.createTime = now.strftime("%Y-%m-%d %H:%M:%S")
|
||||||
blog.updateTime = now.strftime("%Y-%m-%d %H:%M:%S")
|
blog.updateTime = now.strftime("%Y-%m-%d %H:%M:%S")
|
||||||
@@ -64,10 +71,14 @@ def add_blog_elastic(blog: BlogElastic) -> bool:
|
|||||||
body=blog.model_dump()
|
body=blog.model_dump()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
logger.info(f"成功新增博客 {blog.id} 到 Elasticsearch")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def update_blog_elastic(blog: BlogElastic) -> bool:
|
def update_blog_elastic(blog: BlogElastic) -> bool:
|
||||||
|
if settings.ENVIRONMENT == 'dev':
|
||||||
|
return True
|
||||||
|
|
||||||
now = datetime.now()
|
now = datetime.now()
|
||||||
blog.updateTime = now.strftime("%Y-%m-%d %H:%M:%S")
|
blog.updateTime = now.strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
|
||||||
@@ -77,12 +88,17 @@ def update_blog_elastic(blog: BlogElastic) -> bool:
|
|||||||
body=blog.model_dump()
|
body=blog.model_dump()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
logger.info(f"成功修改博客 {blog.id} 到 Elasticsearch")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def delete_blog(blog_id: int) -> bool:
|
def delete_blog(blog_id: int) -> bool:
|
||||||
|
if settings.ENVIRONMENT == 'dev':
|
||||||
|
return True
|
||||||
|
|
||||||
es.delete(index=BLOG_INDEX, id=blog_id)
|
es.delete(index=BLOG_INDEX, id=blog_id)
|
||||||
|
|
||||||
|
logger.info(f"成功删除博客 {blog_id} 到 Elasticsearch")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
from fastapi import Request
|
from fastapi import Request
|
||||||
from sqlalchemy import select, func, desc, and_
|
from sqlalchemy import select, func, desc, and_, asc, delete
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
from models.blog import Blog, BlogCategory, BlogVisit, BlogContent, BlogComment
|
from models.blog import Blog, BlogCategory, BlogVisit, BlogContent, BlogComment
|
||||||
from schemas.blog import BlogResponse, BlogQuery, BlogCategoryResponse, BlogStatsResponse, \
|
from schemas.blog import BlogResponse, BlogQuery, BlogCategoryResponse, BlogStatsResponse, \
|
||||||
BlogLatestResponse, BlogCommentCreate, BlogCommentResponse, BlogVisitResponse, BlogCreate, BlogUpdate
|
BlogLatestResponse, BlogCommentCreate, BlogCommentResponse, BlogVisitResponse, BlogCreate, BlogUpdate, \
|
||||||
|
BlogAdjacentResponse
|
||||||
from schemas.blog_elastic import BlogElastic
|
from schemas.blog_elastic import BlogElastic
|
||||||
from schemas.pagination import PageResult
|
from schemas.pagination import PageResult
|
||||||
from schemas.paginate_query import paginate_query
|
from schemas.paginate_query import paginate_query
|
||||||
@@ -82,6 +83,8 @@ def query_blog_by_condition(db: Session, blog_query: BlogQuery) -> List[BlogResp
|
|||||||
|
|
||||||
|
|
||||||
def query_blog_by_id(db: Session, blog_id: int) -> BlogResponse:
|
def query_blog_by_id(db: Session, blog_id: int) -> BlogResponse:
|
||||||
|
check_blog_exist(db, blog_id)
|
||||||
|
|
||||||
query = db.query(
|
query = db.query(
|
||||||
Blog.id.label("id"),
|
Blog.id.label("id"),
|
||||||
Blog.title.label("title"),
|
Blog.title.label("title"),
|
||||||
@@ -104,8 +107,6 @@ def query_blog_by_id(db: Session, blog_id: int) -> BlogResponse:
|
|||||||
).filter(Blog.id == blog_id)
|
).filter(Blog.id == blog_id)
|
||||||
|
|
||||||
blog = query.first()
|
blog = query.first()
|
||||||
if blog[0] is None:
|
|
||||||
raise AppException("博客不存在")
|
|
||||||
|
|
||||||
return BlogResponse.from_orm(blog)
|
return BlogResponse.from_orm(blog)
|
||||||
|
|
||||||
@@ -140,7 +141,8 @@ def add_blog(db: Session, blog: BlogCreate) -> bool:
|
|||||||
|
|
||||||
|
|
||||||
def add_blog_category(db: Session, category: str) -> int:
|
def add_blog_category(db: Session, category: str) -> int:
|
||||||
db_blog_category = db.query(BlogCategory).filter(BlogCategory.name == category).first()
|
db_blog_category = db.execute(select(BlogCategory).where(BlogCategory.name == category)).scalar_one_or_none()
|
||||||
|
|
||||||
if db_blog_category is None:
|
if db_blog_category is None:
|
||||||
db_new_blog_category = BlogCategory(name=category)
|
db_new_blog_category = BlogCategory(name=category)
|
||||||
db.add(db_new_blog_category)
|
db.add(db_new_blog_category)
|
||||||
@@ -161,9 +163,7 @@ def add_blog_content(db: Session, content: str) -> int:
|
|||||||
|
|
||||||
|
|
||||||
def update_blog(db: Session, blog_id: int, blog: BlogUpdate) -> bool:
|
def update_blog(db: Session, blog_id: int, blog: BlogUpdate) -> bool:
|
||||||
db_blog = db.query(Blog).filter(Blog.id == blog_id).first()
|
db_blog = check_blog_exist(db, blog_id)
|
||||||
if not db_blog:
|
|
||||||
raise AppException("博客不存在")
|
|
||||||
|
|
||||||
update_data = blog.model_dump(exclude_unset=True)
|
update_data = blog.model_dump(exclude_unset=True)
|
||||||
|
|
||||||
@@ -186,7 +186,7 @@ def update_blog(db: Session, blog_id: int, blog: BlogUpdate) -> bool:
|
|||||||
|
|
||||||
|
|
||||||
def update_blog_category(db: Session, category: str) -> int:
|
def update_blog_category(db: Session, category: str) -> int:
|
||||||
db_blog_category = db.query(BlogCategory).filter(BlogCategory.name == category).first()
|
db_blog_category = db.execute(select(BlogCategory).where(BlogCategory.name == category)).scalar_one_or_none()
|
||||||
|
|
||||||
if db_blog_category is None:
|
if db_blog_category is None:
|
||||||
return add_blog_category(db, category)
|
return add_blog_category(db, category)
|
||||||
@@ -195,12 +195,9 @@ def update_blog_category(db: Session, category: str) -> int:
|
|||||||
|
|
||||||
|
|
||||||
def update_blog_content(db: Session, blog_content_id: int, blog_content: str) -> bool:
|
def update_blog_content(db: Session, blog_content_id: int, blog_content: str) -> bool:
|
||||||
db_blog_content = db.query(BlogContent).filter(BlogContent.id == blog_content_id).first()
|
db_blog_content = check_blog_content_exist(db, blog_content_id)
|
||||||
if not db_blog_content:
|
|
||||||
raise AppException("博客内容不存在")
|
|
||||||
|
|
||||||
db_blog_content.content = blog_content.encode('utf-8')
|
db_blog_content.content = blog_content.encode('utf-8')
|
||||||
|
|
||||||
db.commit()
|
db.commit()
|
||||||
db.refresh(db_blog_content)
|
db.refresh(db_blog_content)
|
||||||
|
|
||||||
@@ -208,24 +205,19 @@ def update_blog_content(db: Session, blog_content_id: int, blog_content: str) ->
|
|||||||
|
|
||||||
|
|
||||||
def delete_blog(db: Session, blog_id: int) -> bool:
|
def delete_blog(db: Session, blog_id: int) -> bool:
|
||||||
db_blog = db.query(Blog).filter(Blog.id == blog_id).first()
|
db_blog = check_blog_exist(db, blog_id)
|
||||||
if not db_blog:
|
|
||||||
raise AppException("博客不存在")
|
|
||||||
|
|
||||||
delete_blog_content(db, db_blog.content_id)
|
delete_blog_content(db, db_blog.content_id)
|
||||||
|
db.execute(delete(Blog).where(Blog.id == blog_id))
|
||||||
db.delete(db_blog)
|
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def delete_blog_content(db: Session, blog_content_id: int) -> bool:
|
def delete_blog_content(db: Session, blog_content_id: int) -> bool:
|
||||||
db_blog_content = db.query(BlogContent).filter(BlogContent.id == blog_content_id).first()
|
check_blog_content_exist(db, blog_content_id)
|
||||||
if not db_blog_content:
|
|
||||||
raise AppException("博客内容不存在")
|
|
||||||
|
|
||||||
db.delete(db_blog_content)
|
db.execute(delete(BlogContent).where(BlogContent.id == blog_content_id))
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
return True
|
return True
|
||||||
@@ -265,6 +257,35 @@ def query_blog_latest(db: Session) -> List[BlogLatestResponse]:
|
|||||||
return [BlogLatestResponse.from_orm(result) for result in results]
|
return [BlogLatestResponse.from_orm(result) for result in results]
|
||||||
|
|
||||||
|
|
||||||
|
def query_blog_adjacent(db: Session, blog_id: int) -> List[BlogAdjacentResponse]:
|
||||||
|
check_blog_exist(db, blog_id)
|
||||||
|
|
||||||
|
prev_result = db.execute(
|
||||||
|
select(Blog.id, Blog.title)
|
||||||
|
.where(Blog.id < blog_id)
|
||||||
|
.order_by(desc(Blog.id))
|
||||||
|
.limit(1)
|
||||||
|
).first()
|
||||||
|
|
||||||
|
next_result = db.execute(
|
||||||
|
select(Blog.id, Blog.title)
|
||||||
|
.where(Blog.id > blog_id)
|
||||||
|
.order_by(asc(Blog.id))
|
||||||
|
.limit(1)
|
||||||
|
).first()
|
||||||
|
|
||||||
|
return [
|
||||||
|
BlogAdjacentResponse(
|
||||||
|
id=prev_result[0] if prev_result else 0,
|
||||||
|
title=prev_result[1] if prev_result else ""
|
||||||
|
),
|
||||||
|
BlogAdjacentResponse(
|
||||||
|
id=next_result[0] if next_result else 0,
|
||||||
|
title=next_result[1] if next_result else ""
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def add_blog_visit(db: Session, blog_visit: BlogVisit):
|
def add_blog_visit(db: Session, blog_visit: BlogVisit):
|
||||||
db.add(blog_visit)
|
db.add(blog_visit)
|
||||||
db.commit()
|
db.commit()
|
||||||
@@ -305,15 +326,14 @@ def query_blog_comment(db: Session, blog_id: int) -> List[BlogCommentResponse]:
|
|||||||
|
|
||||||
|
|
||||||
def add_blog_comment(db: Session, request: Request, blog_id: int, blog_comment: BlogCommentCreate) -> bool:
|
def add_blog_comment(db: Session, request: Request, blog_id: int, blog_comment: BlogCommentCreate) -> bool:
|
||||||
blog = db.query(Blog).filter(Blog.id == blog_id).first()
|
check_blog_exist(db, blog_id)
|
||||||
if not blog:
|
|
||||||
raise AppException("博客不存在")
|
|
||||||
|
|
||||||
if blog_comment.parentId != 0:
|
if blog_comment.parentId != 0:
|
||||||
parent_comment = db.query(BlogComment).filter(
|
parent_comment = db.execute(
|
||||||
BlogComment.id == blog_comment.parentId,
|
select(BlogComment)
|
||||||
BlogComment.blog_id == blog_id
|
.where(BlogComment.id == blog_comment.parentId)
|
||||||
).first()
|
.where(BlogComment.blog_id == blog_id)
|
||||||
|
).scalar_one_or_none()
|
||||||
|
|
||||||
if not parent_comment:
|
if not parent_comment:
|
||||||
raise AppException("父评论不存在")
|
raise AppException("父评论不存在")
|
||||||
@@ -334,3 +354,20 @@ def add_blog_comment(db: Session, request: Request, blog_id: int, blog_comment:
|
|||||||
db.refresh(db_comment)
|
db.refresh(db_comment)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def check_blog_exist(db: Session, blog_id: int) -> Blog:
|
||||||
|
result = db.execute(select(Blog).where(Blog.id == blog_id)).scalar_one_or_none()
|
||||||
|
|
||||||
|
if not result:
|
||||||
|
raise AppException("博客不存在")
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def check_blog_content_exist(db: Session, blog_content_id: int) -> BlogContent:
|
||||||
|
result = db.execute(select(BlogContent).where(BlogContent.id == blog_content_id)).scalar_one_or_none()
|
||||||
|
if not result:
|
||||||
|
raise AppException("博客内容不存在")
|
||||||
|
|
||||||
|
return result
|
||||||
|
|||||||
Reference in New Issue
Block a user