diff --git a/backend/app/admin/schema/config.py b/backend/app/admin/schema/config.py index 7f5231dc..a96456a7 100644 --- a/backend/app/admin/schema/config.py +++ b/backend/app/admin/schema/config.py @@ -15,11 +15,11 @@ class SaveConfigParam(SchemaBase): class AnyConfigSchemaBase(SchemaBase): name: str - type: str | None + type: str | None = None key: str value: str is_frontend: bool - remark: str | None + remark: str | None = None class CreateAnyConfigParam(AnyConfigSchemaBase): diff --git a/backend/common/pagination.py b/backend/common/pagination.py index 6e7f0a74..577b61ea 100644 --- a/backend/common/pagination.py +++ b/backend/common/pagination.py @@ -22,10 +22,12 @@ SchemaT = TypeVar('SchemaT') -class _Params(BaseModel, AbstractParams): +class PageParams(BaseModel): page: int = Query(1, ge=1, description='Page number') size: int = Query(20, gt=0, le=100, description='Page size') # 默认 20 条记录 + +class _PageParams(PageParams, AbstractParams): def to_raw_params(self) -> RawParams: return RawParams( limit=self.size, @@ -33,7 +35,7 @@ def to_raw_params(self) -> RawParams: ) -class _Page(AbstractPage[T], Generic[T]): +class _CustomPage(AbstractPage[T], Generic[T]): items: Sequence[T] # 数据 total: int # 总数据数 page: int # 第n页 @@ -41,15 +43,15 @@ class _Page(AbstractPage[T], Generic[T]): total_pages: int # 总页数 links: Dict[str, str | None] # 跳转链接 - __params_type__ = _Params # 使用自定义的Params + __params_type__ = _PageParams @classmethod def create( cls, items: Sequence[T], + params: _PageParams, total: int, - params: _Params, - ) -> _Page[T]: + ) -> _CustomPage[T]: page = params.page size = params.size total_pages = math.ceil(total / params.size) @@ -64,7 +66,7 @@ def create( class _PageData(BaseModel, Generic[DataT]): - page_data: DataT | None = None + data: DataT | None = None async def paging_data(db: AsyncSession, select: Select, page_data_schema: SchemaT) -> dict: @@ -76,10 +78,11 @@ async def paging_data(db: AsyncSession, select: Select, page_data_schema: Schema :param page_data_schema: :return: """ - _paginate = await paginate(db, select) - page_data = _PageData[_Page[page_data_schema]](page_data=_paginate).model_dump()['page_data'] + paginated_data = await paginate(db, select) + # 参考:https://docs.pydantic.dev/dev/concepts/models/#generic-models + page_data = _PageData[_CustomPage[page_data_schema]](page_data=paginated_data).model_dump()['data'] return page_data # 分页依赖注入 -DependsPagination = Depends(pagination_ctx(_Page)) +DependsPagination = Depends(pagination_ctx(_CustomPage)) diff --git a/backend/pyproject.toml b/backend/pyproject.toml index ab39291e..f96cc99a 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -21,7 +21,7 @@ dependencies = [ "celery==5.3.6", "cryptography==41.0.7", "fast-captcha==0.3.2", - "fastapi[all]==0.111.0", + "fastapi[all]==0.115.0", "fastapi-limiter==0.1.6", "fastapi-pagination==0.12.13", "gunicorn==21.2.0", diff --git a/backend/requirements.txt b/backend/requirements.txt index 13666186..72612463 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -32,7 +32,7 @@ ecdsa==0.19.0 email-validator==2.2.0 exceptiongroup==1.2.2 ; python_full_version < '3.11' fast-captcha==0.3.2 -fastapi==0.111.0 +fastapi==0.115.0 fastapi-cli==0.0.5 fastapi-limiter==0.1.6 fastapi-oauth20==0.0.1a2 diff --git a/backend/uv.lock b/backend/uv.lock index 0aa700a4..9a470f85 100644 --- a/backend/uv.lock +++ b/backend/uv.lock @@ -435,29 +435,22 @@ wheels = [ [[package]] name = "fastapi" -version = "0.111.0" +version = "0.115.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "email-validator" }, - { name = "fastapi-cli" }, - { name = "httpx" }, - { name = "jinja2" }, - { name = "orjson" }, { name = "pydantic" }, - { name = "python-multipart" }, { name = "starlette" }, { name = "typing-extensions" }, - { name = "ujson" }, - { name = "uvicorn", extra = ["standard"] }, ] -sdist = { url = "https://files.pythonhosted.org/packages/0e/1f/f4a99e92c583780787e04b05aa9d8a8db9ec76d091d81545948a006f5b44/fastapi-0.111.0.tar.gz", hash = "sha256:b9db9dd147c91cb8b769f7183535773d8741dd46f9dc6676cd82eab510228cd7", size = 288414 } +sdist = { url = "https://files.pythonhosted.org/packages/7b/5e/bf0471f14bf6ebfbee8208148a3396d1a23298531a6cc10776c59f4c0f87/fastapi-0.115.0.tar.gz", hash = "sha256:f93b4ca3529a8ebc6fc3fcf710e5efa8de3df9b41570958abf1d97d843138004", size = 302295 } wheels = [ - { url = "https://files.pythonhosted.org/packages/e6/33/de41e554e5a187d583906e10d53bfae5fd6c07e98cbf4fe5262bd37e739a/fastapi-0.111.0-py3-none-any.whl", hash = "sha256:97ecbf994be0bcbdadedf88c3150252bed7b2087075ac99735403b1b76cc8fc0", size = 91993 }, + { url = "https://files.pythonhosted.org/packages/06/ab/a1f7eed031aeb1c406a6e9d45ca04bff401c8a25a30dd0e4fd2caae767c3/fastapi-0.115.0-py3-none-any.whl", hash = "sha256:17ea427674467486e997206a5ab25760f6b09e069f099b96f5b55a32fb6f1631", size = 94625 }, ] [package.optional-dependencies] all = [ { name = "email-validator" }, + { name = "fastapi-cli", extra = ["standard"] }, { name = "httpx" }, { name = "itsdangerous" }, { name = "jinja2" }, @@ -539,7 +532,7 @@ requires-dist = [ { name = "celery-aio-pool", specifier = "==0.1.0rc6" }, { name = "cryptography", specifier = "==41.0.7" }, { name = "fast-captcha", specifier = "==0.3.2" }, - { name = "fastapi", extras = ["all"], specifier = "==0.111.0" }, + { name = "fastapi", extras = ["all"], specifier = "==0.115.0" }, { name = "fastapi-limiter", specifier = "==0.1.6" }, { name = "fastapi-oauth20", specifier = ">=0.0.1a2" }, { name = "fastapi-pagination", specifier = "==0.12.13" }, @@ -590,6 +583,11 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/24/ea/4b5011012ac925fe2f83b19d0e09cee9d324141ec7bf5e78bb2817f96513/fastapi_cli-0.0.5-py3-none-any.whl", hash = "sha256:e94d847524648c748a5350673546bbf9bcaeb086b33c24f2e82e021436866a46", size = 9489 }, ] +[package.optional-dependencies] +standard = [ + { name = "uvicorn", extra = ["standard"] }, +] + [[package]] name = "fastapi-limiter" version = "0.1.6"