feat: 分页加载和用户编码
1. 前端List.jsx: 实现分页加载,每次50条,滚动到底部自动加载更多 2. 后端auth.py: 注册时自动生成用户编码(0001开始) 3. 模型schemas: 添加user_code字段
This commit is contained in:
parent
ef638f18c4
commit
2c0056c827
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue