From 2c0056c8277e5032294d0c70c710dcc63a928ae3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BE=99=E5=A4=A7?= Date: Sun, 22 Mar 2026 19:16:08 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=88=86=E9=A1=B5=E5=8A=A0=E8=BD=BD?= =?UTF-8?q?=E5=92=8C=E7=94=A8=E6=88=B7=E7=BC=96=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 前端List.jsx: 实现分页加载,每次50条,滚动到底部自动加载更多 2. 后端auth.py: 注册时自动生成用户编码(0001开始) 3. 模型schemas: 添加user_code字段 --- backend/app/models/models.py | 1 + backend/app/routers/auth.py | 17 ++++++++++++- backend/app/schemas/schemas.py | 1 + frontend/src/pages/List.jsx | 45 +++++++++++++++++++++++++++++++--- 4 files changed, 59 insertions(+), 5 deletions(-) diff --git a/backend/app/models/models.py b/backend/app/models/models.py index 5f9df82..4d96a70 100644 --- a/backend/app/models/models.py +++ b/backend/app/models/models.py @@ -16,6 +16,7 @@ class User(Base): # f99 系统字段 f99_90_id = Column(String(36), primary_key=True, default=generate_uuid) + user_code = Column(String(10), unique=True, nullable=True, index=True) # 用户编码 f99_91_user_id = Column(String(36), unique=True, nullable=False, index=True) f01_01_name = Column(String(255), unique=True, nullable=False, index=True) # username email = Column(String(255), unique=True, nullable=True, index=True) diff --git a/backend/app/routers/auth.py b/backend/app/routers/auth.py index c962983..6d49d97 100644 --- a/backend/app/routers/auth.py +++ b/backend/app/routers/auth.py @@ -10,6 +10,20 @@ from app.schemas.schemas import Token, UserCreate, UserResponse router = APIRouter(prefix="/api/auth", tags=["认证"]) + + +def generate_user_code(db): + """生成用户编码,从0001开始""" + # 查找最大的user_code + max_code = db.query(User.user_code).filter(User.user_code != None).order_by(User.user_code.desc()).first() + if max_code and max_code[0]: + try: + num = int(max_code[0]) + 1 + return f"{num:04d}" + except: + pass + return "0001" + @router.post("/register", response_model=UserResponse) def register(user_data: UserCreate, db: Session = Depends(get_db)): """用户注册""" @@ -35,7 +49,8 @@ def register(user_data: UserCreate, db: Session = Depends(get_db)): hashed_password = get_password_hash(user_data.password) user = User( f99_90_id=str(uuid.uuid4()), - f99_91_user_id=str(uuid.uuid4()), # 生成唯一 user_id + f99_91_user_id=str(uuid.uuid4()), + user_code=generate_user_code(db), f01_01_name=user_data.f01_01_name, email=user_data.email, phone=user_data.phone, diff --git a/backend/app/schemas/schemas.py b/backend/app/schemas/schemas.py index 0ba1bae..9ef13c3 100644 --- a/backend/app/schemas/schemas.py +++ b/backend/app/schemas/schemas.py @@ -37,6 +37,7 @@ class UserResponse(UserBase): f99_90_id: str = Field(..., alias="id") f01_01_name: str = Field(..., alias="username") role: str + user_code: Optional[str] = None f99_92_created_at: Optional[datetime] = Field(None, alias="created_at") f99_93_updated_at: Optional[datetime] = Field(None, alias="updated_at") diff --git a/frontend/src/pages/List.jsx b/frontend/src/pages/List.jsx index 1624077..66203d0 100644 --- a/frontend/src/pages/List.jsx +++ b/frontend/src/pages/List.jsx @@ -15,6 +15,9 @@ export default function List() { const [key, setKey] = useState(0) const [search, setSearch] = useState('') const [isAdmin, setIsAdmin] = useState(false) + const [page, setPage] = useState(1) + const [hasMore, setHasMore] = useState(true) + const [initialLoad, setInitialLoad] = useState(true) useEffect(() => { // 检查是否管理员 @@ -46,7 +49,19 @@ export default function List() { setFilter('') setFilterType('') } - fetchCollections() + // 滚动加载更多 + const handleScroll = () => { + if (loading || !hasMore) return + const scrollTop = window.scrollY || document.documentElement.scrollTop + const scrollHeight = document.documentElement.scrollHeight + const clientHeight = document.documentElement.clientHeight + if (scrollTop + clientHeight >= scrollHeight - 100) { + fetchCollections(true) + } + } + + window.addEventListener('scroll', handleScroll) + return () => window.removeEventListener('scroll', handleScroll) } handleHashChange() @@ -59,11 +74,21 @@ export default function List() { } }, []) - const fetchCollections = async () => { - setLoading(true) + const fetchCollections = async (reset = false) => { const token = localStorage.getItem('token') + const currentPage = reset ? 1 : page + try { - const res = await fetch('/api/collections?limit=100', { + if (reset) { + setCollections([]) + setPage(1) + setLoading(true) + setInitialLoad(true) + } else { + setLoading(true) + } + + const res = await fetch(`/api/collections?page=${currentPage}&limit=50`, { headers: token ? { 'Authorization': 'Bearer ' + token } : {} }) @@ -82,6 +107,18 @@ export default function List() { list = list.items } + // 分页处理 + if (reset) { + setCollections(list || []) + } else { + setCollections(prev => [...prev, ...(list || [])]) + } + + // 判断是否还有更多数据 + const receivedCount = list ? list.length : 0 + setHasMore(receivedCount >= 50) + if (!initialLoad) setPage(prev => prev + 1) + // 应用筛选条件 // 用户ID筛选(从URL获取) if (userIdFilter) {