mirror of
https://gh-proxy.org/https://github.com/klinsmaya/SQLBot.git
synced 2026-11-08 01:06:59 +08:00
feat: Terminology module
This commit is contained in:
@@ -12,6 +12,7 @@ SECRET_KEY=y5txe1mRmS_JpOrUzFzHEu-kIQn3lf7ll0AOv9DQh0s
|
||||
FIRST_SUPERUSER=[email protected]
|
||||
FIRST_SUPERUSER_PASSWORD=123456 # Change this to your pwd
|
||||
|
||||
TOKEN_KEY="X-SQLBOT-TOKEN"
|
||||
|
||||
# Postgres
|
||||
POSTGRES_SERVER=localhost
|
||||
|
||||
@@ -18,7 +18,8 @@ fileConfig(config.config_file_name)
|
||||
# target_metadata = mymodel.Base.metadata
|
||||
# target_metadata = None
|
||||
|
||||
from apps.system.models.user import SQLModel # noqa
|
||||
# from apps.system.models.user import SQLModel # noqa
|
||||
from apps.settings.models.setting_models import SQLModel
|
||||
from common.core.config import settings # noqa
|
||||
|
||||
target_metadata = SQLModel.metadata
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
"""002_ddl_autogenerate
|
||||
|
||||
Revision ID: 1c8bcc7e25c8
|
||||
Revises: 5348b743b05f
|
||||
Create Date: 2025-04-25 17:47:18.795288
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import sqlmodel.sql.sqltypes
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '1c8bcc7e25c8'
|
||||
down_revision = '5348b743b05f'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_table('terms',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('term', sqlmodel.sql.sqltypes.AutoString(length=255), nullable=False),
|
||||
sa.Column('definition', sqlmodel.sql.sqltypes.AutoString(length=255), nullable=False),
|
||||
sa.Column('domain', sqlmodel.sql.sqltypes.AutoString(length=255), nullable=False),
|
||||
sa.Column('create_time', sa.Integer(), nullable=False),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
op.create_index(op.f('ix_terms_id'), 'terms', ['id'], unique=False)
|
||||
op.drop_table('sys_user')
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_table('sys_user',
|
||||
sa.Column('id', sa.BIGINT(), autoincrement=True, nullable=False),
|
||||
sa.Column('account', sa.VARCHAR(length=255), autoincrement=False, nullable=False),
|
||||
sa.Column('name', sa.VARCHAR(length=255), autoincrement=False, nullable=False),
|
||||
sa.Column('password', sa.VARCHAR(length=255), autoincrement=False, nullable=False),
|
||||
sa.Column('email', sa.VARCHAR(length=255), autoincrement=False, nullable=True),
|
||||
sa.Column('oid', sa.BIGINT(), autoincrement=False, nullable=False),
|
||||
sa.Column('status', sa.INTEGER(), autoincrement=False, nullable=False),
|
||||
sa.Column('create_time', sa.BIGINT(), autoincrement=False, nullable=False),
|
||||
sa.PrimaryKeyConstraint('id', name='sys_user_pkey')
|
||||
)
|
||||
op.drop_index(op.f('ix_terms_id'), table_name='terms')
|
||||
op.drop_table('terms')
|
||||
# ### end Alembic commands ###
|
||||
+2
-1
@@ -1,10 +1,11 @@
|
||||
from fastapi import APIRouter
|
||||
|
||||
from apps.system.api import login, user
|
||||
|
||||
from apps.settings.api import terminology
|
||||
|
||||
api_router = APIRouter()
|
||||
api_router.include_router(login.router)
|
||||
api_router.include_router(user.router)
|
||||
api_router.include_router(terminology.router)
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
from typing import Optional
|
||||
from fastapi import APIRouter, Depends, Request
|
||||
from apps.settings.models.setting_models import term_model
|
||||
# from common.core.db import get_session
|
||||
from common.core.deps import SessionDep
|
||||
from common.core.pagination import Paginator
|
||||
from common.core.schemas import PaginatedResponse, PaginationParams
|
||||
router = APIRouter(tags=["Settings"], prefix="/settings/terminology")
|
||||
|
||||
|
||||
@router.get("/pager/{pageNum}/{pageSize}", response_model=PaginatedResponse[term_model])
|
||||
async def pager(
|
||||
session: SessionDep,
|
||||
pageNum: int,
|
||||
pageSize: int
|
||||
):
|
||||
pagination = PaginationParams(page=pageNum, size=pageSize)
|
||||
paginator = Paginator(session)
|
||||
filters = {}
|
||||
return await paginator.get_paginated_response(
|
||||
model=term_model,
|
||||
pagination=pagination,
|
||||
**filters)
|
||||
@@ -0,0 +1,12 @@
|
||||
from sqlmodel import Field, SQLModel
|
||||
|
||||
|
||||
class term_model(SQLModel, table=True):
|
||||
__tablename__ = "terms"
|
||||
|
||||
id: int = Field(primary_key=True, index=True)
|
||||
term: str = Field(max_length=255)
|
||||
definition: str = Field(max_length=255)
|
||||
domain: str = Field(max_length=255)
|
||||
create_time: int = Field(default=0)
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
from pydantic import BaseModel
|
||||
|
||||
class term_schema(BaseModel):
|
||||
id: int
|
||||
term: str
|
||||
definition: str
|
||||
domain: str
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
from sqlmodel.ext.asyncio.session import AsyncSession
|
||||
from sqlmodel import select, func, SQLModel
|
||||
from typing import Type, TypeVar, Sequence, Optional
|
||||
from common.core.schemas import PaginationParams, PaginatedResponse
|
||||
|
||||
ModelT = TypeVar('ModelT', bound=SQLModel)
|
||||
|
||||
class Paginator:
|
||||
def __init__(self, session: AsyncSession):
|
||||
self.session = session
|
||||
|
||||
async def paginate(
|
||||
self,
|
||||
model: Type[ModelT],
|
||||
page: int = 1,
|
||||
size: int = 20,
|
||||
order_by: Optional[str] = None,
|
||||
desc: bool = False,
|
||||
**filters
|
||||
) -> tuple[Sequence[ModelT], int]:
|
||||
offset = (page - 1) * size
|
||||
stmt = select(model)
|
||||
|
||||
for field, value in filters.items():
|
||||
if value is not None:
|
||||
stmt = stmt.where(getattr(model, field) == value)
|
||||
|
||||
if order_by:
|
||||
column = getattr(model, order_by)
|
||||
stmt = stmt.order_by(column.desc() if desc else column.asc())
|
||||
|
||||
count_stmt = select(func.count()).select_from(model)
|
||||
for field, value in filters.items():
|
||||
if value is not None:
|
||||
count_stmt = count_stmt.where(getattr(model, field) == value)
|
||||
|
||||
total = (await self.session.execute(count_stmt)).scalar_one()
|
||||
|
||||
stmt = stmt.offset(offset).limit(size)
|
||||
|
||||
result = await self.session.execute(stmt)
|
||||
items = result.scalars().all()
|
||||
|
||||
return items, total
|
||||
|
||||
async def get_paginated_response(
|
||||
self,
|
||||
model: Type[ModelT],
|
||||
pagination: PaginationParams,
|
||||
**filters
|
||||
) -> PaginatedResponse[ModelT]:
|
||||
items, total = await self.paginate(
|
||||
model=model,
|
||||
page=pagination.page,
|
||||
size=pagination.size,
|
||||
order_by=pagination.order_by,
|
||||
desc=pagination.desc,
|
||||
**filters
|
||||
)
|
||||
|
||||
total_pages = (total + pagination.size - 1) // pagination.size
|
||||
|
||||
return PaginatedResponse[ModelT](
|
||||
items=items,
|
||||
total=total,
|
||||
page=pagination.page,
|
||||
size=pagination.size,
|
||||
total_pages=total_pages
|
||||
)
|
||||
@@ -1,4 +1,3 @@
|
||||
from typing import Optional
|
||||
from fastapi import HTTPException, Request
|
||||
from fastapi.security import OAuth2PasswordBearer
|
||||
from pydantic import BaseModel
|
||||
@@ -6,6 +5,7 @@ from sqlmodel import SQLModel
|
||||
from starlette.status import HTTP_403_FORBIDDEN, HTTP_401_UNAUTHORIZED
|
||||
from common.core.config import settings
|
||||
from fastapi.security.utils import get_authorization_scheme_param
|
||||
from typing import Generic, TypeVar, Optional
|
||||
class TokenPayload(BaseModel):
|
||||
account: str | None = None
|
||||
id: int | None = None
|
||||
@@ -28,4 +28,22 @@ class XOAuth2PasswordBearer(OAuth2PasswordBearer):
|
||||
)
|
||||
else:
|
||||
return None
|
||||
return param
|
||||
return param
|
||||
|
||||
|
||||
|
||||
|
||||
T = TypeVar('T')
|
||||
|
||||
class PaginationParams(BaseModel):
|
||||
page: int = 1
|
||||
size: int = 20
|
||||
order_by: Optional[str] = None
|
||||
desc: bool = False
|
||||
|
||||
class PaginatedResponse(BaseModel, Generic[T]):
|
||||
items: list[T]
|
||||
total: int
|
||||
page: int
|
||||
size: int
|
||||
total_pages: int
|
||||
Reference in New Issue
Block a user