# 分页使用指南 ## 📋 概述 小虾 SaaS 提供统一的分页接口,支持内存分页和数据库分页。 --- ## 🔧 基本使用 ### 1. API 端点添加分页 ```python from fastapi import APIRouter, Depends from packages.application.common.pagination import PaginationParams, PaginatedResponse router = APIRouter() @router.get("/projects", response_model=PaginatedResponse[ProjectResponse]) async def list_projects( pagination: PaginationParams = Depends(), user_id: str = Depends(get_current_user_id), ): # 获取分页数据 projects, total = project_repo.find_by_user_paginated( user_id=user_id, offset=pagination.offset, limit=pagination.limit, ) # 返回分页响应 return PaginatedResponse.create( data=projects, params=pagination, total=total, ) ``` ### 2. 请求分页数据 ```bash # 默认第一页,每页 20 条 GET /api/v1/projects # 指定页码和每页数量 GET /api/v1/projects?page=2&page_size=10 # 获取更多数据 GET /api/v1/projects?page=1&page_size=50 ``` ### 3. 响应格式 ```json { "data": [ { "id": "project-1", "name": "项目 1" }, { "id": "project-2", "name": "项目 2" } ], "pagination": { "page": 1, "page_size": 20, "total": 156, "total_pages": 8, "has_next": true, "has_prev": false } } ``` --- ## 🗄️ Repository 实现 ### InMemory Repository(内存分页) ```python from packages.application.common.pagination import paginate, PaginationParams class InMemoryProjectRepository: def find_by_workspace_paginated( self, workspace_id: str, pagination: PaginationParams, ): # 获取所有项目 all_projects = [p for p in self._storage.values() if p.workspace_id == workspace_id] # 使用内存分页 return paginate(all_projects, pagination) ``` ### PostgreSQL Repository(数据库分页) ```python class PostgresProjectRepository: def find_by_workspace_paginated( self, workspace_id: str, offset: int, limit: int, ) -> tuple[List[Project], int]: conn = self._get_connection() try: with conn.cursor() as cur: # 获取总数 cur.execute( "SELECT COUNT(*) FROM projects WHERE workspace_id = %s", (workspace_id,) ) total = cur.fetchone()["count"] # 获取分页数据 cur.execute(""" SELECT * FROM projects WHERE workspace_id = %s ORDER BY created_at DESC LIMIT %s OFFSET %s """, (workspace_id, limit, offset)) projects = [self._row_to_project(row) for row in cur.fetchall()] return projects, total finally: conn.close() ``` --- ## 📱 前端使用 ### React 示例 ```typescript import { useState, useEffect } from 'react'; function ProjectList() { const [projects, setProjects] = useState([]); const [pagination, setPagination] = useState(null); const [page, setPage] = useState(1); useEffect(() => { fetch(`/api/v1/projects?page=${page}&page_size=20`) .then(res => res.json()) .then(data => { setProjects(data.data); setPagination(data.pagination); }); }, [page]); return (