Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions alembic/versions/1791499b5d10_增加时间信息.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
"""增加时间信息

Revision ID: 1791499b5d10
Revises: e04ed2119f01
Create Date: 2025-04-13 10:20:44.770496

"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = '1791499b5d10'
down_revision: Union[str, None] = 'e04ed2119f01'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
"""Upgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('articles', sa.Column('create_time', sa.DateTime(), nullable=False))
op.add_column('articles', sa.Column('update_time', sa.DateTime(), nullable=False))
op.add_column('folders', sa.Column('create_time', sa.DateTime(), nullable=False))
op.add_column('folders', sa.Column('update_time', sa.DateTime(), nullable=False))
op.add_column('notes', sa.Column('create_time', sa.DateTime(), nullable=False))
op.add_column('notes', sa.Column('update_time', sa.DateTime(), nullable=False))
# ### end Alembic commands ###


def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('notes', 'update_time')
op.drop_column('notes', 'create_time')
op.drop_column('folders', 'update_time')
op.drop_column('folders', 'create_time')
op.drop_column('articles', 'update_time')
op.drop_column('articles', 'create_time')
# ### end Alembic commands ###
38 changes: 38 additions & 0 deletions alembic/versions/4df692d79c60_增加时间信息2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"""增加时间信息2

Revision ID: 4df692d79c60
Revises: 1791499b5d10
Create Date: 2025-04-13 10:25:25.139263

"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = '4df692d79c60'
down_revision: Union[str, None] = '1791499b5d10'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
"""Upgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('groups', sa.Column('create_time', sa.DateTime(), nullable=False))
op.add_column('groups', sa.Column('update_time', sa.DateTime(), nullable=False))
op.add_column('tags', sa.Column('create_time', sa.DateTime(), nullable=False))
op.add_column('tags', sa.Column('update_time', sa.DateTime(), nullable=False))
# ### end Alembic commands ###


def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('tags', 'update_time')
op.drop_column('tags', 'create_time')
op.drop_column('groups', 'update_time')
op.drop_column('groups', 'create_time')
# ### end Alembic commands ###
32 changes: 32 additions & 0 deletions alembic/versions/d60fdc9865f8_改变时区.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""改变时区"

Revision ID: d60fdc9865f8
Revises: 4df692d79c60
Create Date: 2025-04-13 10:35:50.120925

"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = 'd60fdc9865f8'
down_revision: Union[str, None] = '4df692d79c60'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
"""Upgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
pass
# ### end Alembic commands ###


def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
pass
# ### end Alembic commands ###
32 changes: 32 additions & 0 deletions alembic/versions/f1242bbcad2d_改变时区撤销.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""改变时区撤销

Revision ID: f1242bbcad2d
Revises: d60fdc9865f8
Create Date: 2025-04-13 10:38:58.146909

"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = 'f1242bbcad2d'
down_revision: Union[str, None] = 'd60fdc9865f8'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
"""Upgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
pass
# ### end Alembic commands ###


def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
pass
# ### end Alembic commands ###
4 changes: 2 additions & 2 deletions app/api/v1/endpoints/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@
def create_access_token(data: dict, expires_delta: timedelta = None):
to_encode = data.copy()
if expires_delta:
expire = datetime.utcnow() + expires_delta
expire = datetime.now() + expires_delta
else:
expire = datetime.utcnow() + timedelta(minutes=15)
expire = datetime.now() + timedelta(minutes=15)
to_encode.update({"exp": expire})
encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
return encoded_jwt
Expand Down
18 changes: 15 additions & 3 deletions app/api/v1/endpoints/note.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from fastapi import APIRouter, HTTPException, Depends
from sqlalchemy.orm import Session
from app.schemas.note import NoteCreate, NoteUpdate
from app.schemas.note import NoteCreate, NoteUpdate, NoteFind
from app.utils.get_db import get_db
from app.curd.note import create_note_in_db, delete_note_in_db, update_note_in_db
from app.curd.note import create_note_in_db, delete_note_in_db, update_note_in_db, find_notes_in_db

router = APIRouter()

Expand All @@ -24,4 +24,16 @@ def update_note(note_id: int, content: str, db: Session = Depends(get_db)):
updated_note = update_note_in_db(note_id, note, db)
if not updated_note:
raise HTTPException(status_code=404, detail="Note not found")
return {"msg": "Note updated successfully", "note_id": updated_note.id}
return {"msg": "Note updated successfully", "note_id": updated_note.id}

@router.get("", response_model=dict)
def get_notes(note_find: NoteFind = Depends(), db: Session = Depends(get_db)):
notes, total_count = find_notes_in_db(note_find, db)
return {
"pagination": {
"total_count": total_count,
"page": note_find.page,
"page_size": note_find.page_size
},
"notes": [note.model_dump() for note in notes]
}
20 changes: 18 additions & 2 deletions app/curd/note.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from sqlalchemy.orm import Session
from app.models.model import Note
from app.schemas.note import NoteCreate, NoteUpdate
from app.schemas.note import NoteCreate, NoteUpdate, NoteFind, NoteResponse

def create_note_in_db(note: NoteCreate, db: Session):
new_note = Note(content=note.content, article_id=note.article_id)
Expand All @@ -22,4 +22,20 @@ def update_note_in_db(note_id: int, note: NoteUpdate, db: Session):
existing_note.content = note.content
db.commit()
db.refresh(existing_note)
return existing_note
return existing_note

def find_notes_in_db(note_find: NoteFind, db: Session):
query = db.query(Note)

if note_find.id is not None:
query = query.filter(Note.id == note_find.id)
elif note_find.article_id is not None:
query = query.filter(Note.article_id == note_find.article_id)

totol_count = query.count()
# 添加分页逻辑
if note_find.page is not None and note_find.page_size is not None:
offset = (note_find.page - 1) * note_find.page_size
query = query.offset(offset).limit(note_find.page_size)
notes = [NoteResponse.model_validate(note) for note in query.all()]
return notes, totol_count
6 changes: 5 additions & 1 deletion app/main.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from fastapi import FastAPI
from app.routers.router import include_routers
from fastapi_pagination import add_pagination

app = FastAPI()

Expand All @@ -12,4 +13,7 @@ def read_item(item_id: int, q: str = None):
return {"item_id": item_id, "q": q}

# 注册路由
include_routers(app)
include_routers(app)

# 注册分页功能
add_pagination(app)
15 changes: 13 additions & 2 deletions app/models/model.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from sqlalchemy import Column, Integer, String, Boolean, Table, ForeignKey, UniqueConstraint, CheckConstraint, Text
from sqlalchemy import Column, Integer, String, Boolean, Table, ForeignKey, UniqueConstraint, CheckConstraint, Text, DateTime
from sqlalchemy.orm import relationship
from sqlalchemy.sql import func
from app.db.base_class import Base

# 多对多关系表
Expand Down Expand Up @@ -28,6 +29,8 @@ class Group(Base):
leader = Column(Integer)
users = relationship('User', secondary=user_group, back_populates='groups')
folders = relationship('Folder', back_populates='group')
create_time = Column(DateTime, default=func.now(), nullable=False) # 创建时间
update_time = Column(DateTime, default=func.now(), onupdate=func.now(), nullable=False) # 更新时间

class Folder(Base):
__tablename__ = 'folders'
Expand All @@ -37,6 +40,9 @@ class Folder(Base):

user_id = Column(Integer, ForeignKey('users.id'))
group_id = Column(Integer, ForeignKey('groups.id'))

create_time = Column(DateTime, default=func.now(), nullable=False) # 创建时间
update_time = Column(DateTime, default=func.now(), onupdate=func.now(), nullable=False) # 更新时间

# 关系定义
user = relationship('User', back_populates='folders')
Expand All @@ -53,6 +59,8 @@ class Article(Base):
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
name = Column(String(30), nullable=False)
folder_id = Column(Integer, ForeignKey('folders.id'))
create_time = Column(DateTime, default=func.now(), nullable=False) # 创建时间
update_time = Column(DateTime, default=func.now(), onupdate=func.now(), nullable=False) # 更新时间

folder = relationship('Folder', back_populates='articles')
notes = relationship('Note', back_populates='article')
Expand All @@ -64,6 +72,8 @@ class Note(Base):
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
content = Column(Text) # 将 content 字段类型改为 Text,以支持存储大量文本
article_id = Column(Integer, ForeignKey('articles.id'))
create_time = Column(DateTime, default=func.now(), nullable=False) # 创建时间
update_time = Column(DateTime, default=func.now(), onupdate=func.now(), nullable=False) # 更新时间

article = relationship('Article', back_populates='notes')

Expand All @@ -73,5 +83,6 @@ class Tag(Base):
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
content = Column(String(30))
article_id = Column(Integer, ForeignKey('articles.id'))

create_time = Column(DateTime, default=func.now(), nullable=False) # 创建时间
update_time = Column(DateTime, default=func.now(), onupdate=func.now(), nullable=False) # 更新时间
article = relationship('Article', back_populates='tags')
4 changes: 3 additions & 1 deletion app/routers/router.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
from fastapi import Depends
from app.utils.auth import get_current_user
from app.api.v1.endpoints.auth import router as auth_router
from app.api.v1.endpoints.note import router as note_router

def include_auth_router(app):
app.include_router(auth_router, prefix="/public", tags=["auth"])

def include_note_router(app):
app.include_router(note_router, prefix="/notes", tags=["note"])
app.include_router(note_router, prefix="/notes", tags=["note"], dependencies=[Depends(get_current_user)])

def include_routers(app):
include_auth_router(app)
Expand Down
16 changes: 16 additions & 0 deletions app/schemas/note.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from datetime import datetime
from pydantic import BaseModel

class NoteCreate(BaseModel):
Expand All @@ -11,3 +12,18 @@ class NoteUpdate(BaseModel):
id: int
content: str

class NoteFind(BaseModel):
id: int | None = None
article_id: int | None = None
page: int | None = None
page_size: int | None = None

class NoteResponse(BaseModel):
id: int
content: str
article_id: int
create_time: datetime
update_time: datetime

class Config:
from_attributes = True
20 changes: 20 additions & 0 deletions app/utils/auth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from fastapi.security import OAuth2PasswordBearer
from jwt import PyJWTError, decode
from app.core.config import settings
from fastapi import Depends, HTTPException
# 配置 OAuth2PasswordBearer
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/auth/login")

def get_current_user(token: str = Depends(oauth2_scheme)):
try:
payload = decode(token, settings.SECRET_KEY, algorithms=[settings.ALGORITHM])
email: str = payload.get("sub")
if email is None:
raise HTTPException(
status_code=401, detail="Invalid authentication credentials"
)
return {"email": email}
except PyJWTError:
raise HTTPException(
status_code=401, detail="Invalid authentication credentials"
)
Empty file added app/utils/middleware.py
Empty file.