diff --git a/VERSION b/VERSION
index 03c6728..3dcdac5 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-VERSION=v1.2.4
+VERSION=1.2.9
diff --git a/config/VERSION b/config/VERSION
index 92448f4..3dcdac5 100644
--- a/config/VERSION
+++ b/config/VERSION
@@ -1 +1 @@
-VERSION=1.2.6
+VERSION=1.2.9
diff --git a/frontend/src/pages/Admin.jsx b/frontend/src/pages/Admin.jsx
index 7e80183..82a0e40 100644
--- a/frontend/src/pages/Admin.jsx
+++ b/frontend/src/pages/Admin.jsx
@@ -126,7 +126,8 @@ export default function Admin() {
const updateData = {
username: editingUser.username,
email: editingUser.email,
- role: editingUser.role
+ role: editingUser.role,
+ user_code: editingUser.user_code
}
// 如果有新密码,添加到更新数据
@@ -145,7 +146,9 @@ export default function Admin() {
if (!res.ok) {
const data = await res.json()
- throw new Error(data.detail || '更新失败')
+ // 新格式: {error: {code, message}} 或旧格式: {detail}
+ const errorMsg = data.error?.message || data.detail || '更新失败'
+ throw new Error(errorMsg)
}
alert('更新成功!')
@@ -362,6 +365,18 @@ export default function Admin() {
+
+
+
+ setEditingUser({ ...editingUser, user_code: e.target.value })}
+ placeholder="4位数字,如:0001"
+ maxLength={4}
+ style={{ width: '100%', padding: '10px', background: 'rgba(255,255,255,0.05)', border: '1px solid rgba(255,255,255,0.1)', borderRadius: '8px', color: '#fff' }}
+ />
+
{/* 第二部分:修改密码 */}
diff --git a/frontend/src/pages/List.jsx b/frontend/src/pages/List.jsx
index 90a51a8..6efda12 100644
--- a/frontend/src/pages/List.jsx
+++ b/frontend/src/pages/List.jsx
@@ -16,8 +16,9 @@ export default function List() {
const [search, setSearch] = useState('')
const [isAdmin, setIsAdmin] = useState(false)
const [page, setPage] = useState(1)
- const [hasMore, setHasMore] = useState(true)
const [loadingMore, setLoadingMore] = useState(false)
+ const [hasMore, setHasMore] = useState(true)
+ const [total, setTotal] = useState(0)
useEffect(() => {
// 检查是否管理员
@@ -61,28 +62,17 @@ export default function List() {
window.removeEventListener('focus', fetchCollections)
}
}, [])
-
- // 滚动加载更多
- useEffect(() => {
- const handleScroll = () => {
- if (loading || loadingMore || !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(false)
- }
- }
-
- window.addEventListener('scroll', handleScroll)
- return () => window.removeEventListener('scroll', handleScroll)
- }, [loading, loadingMore, hasMore, page])
- const fetchCollections = async () => {
- // set loading based on reset
+ const fetchCollections = async (reset = true) => {
+ if (!reset && (loading || loadingMore || !hasMore)) return
+ if (reset) {
+ setLoading(true)
+ } else {
+ setLoadingMore(true)
+ }
const token = localStorage.getItem('token')
try {
- const res = await fetch('/api/collections?page=1&limit=50', {
+ const res = await fetch(`/api/collections?page=${page}&limit=50`, {
headers: token ? { 'Authorization': 'Bearer ' + token } : {}
})
@@ -100,6 +90,12 @@ export default function List() {
if (!Array.isArray(list) && list && Array.isArray(list.items)) {
list = list.items
}
+ // 获取总数
+ if (data.pagination && data.pagination.total) {
+ setTotal(data.pagination.total)
+ } else if (reset) {
+ setTotal(list.length)
+ }
// 应用筛选条件
// 用户ID筛选(从URL获取)
@@ -139,14 +135,17 @@ export default function List() {
console.log(`筛选:${filterType} = ${filter}, 结果:${list.length}条`)
}
- // 分页处理
- if (page === 1) {
+ if (reset) {
setCollections(list || [])
+ setPage(1)
} else {
- setCollections(prev => [...prev, ...(list || [])])
+ setCollections(prev => [...prev, ...list])
+ }
+ if (list.length < 50) {
+ setHasMore(false)
+ } else {
+ setPage(p => p + 1)
}
- setHasMore((list || []).length >= 50)
- if (page > 1) setPage(p => p + 1)
} catch (e) {
console.error('Fetch collections error:', e)
// 网络错误也跳转到登录页
@@ -155,6 +154,7 @@ export default function List() {
window.location.hash = '#/login'
}
setLoading(false)
+ setLoadingMore(false)
}
const refresh = () => {
@@ -165,6 +165,22 @@ export default function List() {
window.refreshList = refresh
return () => { delete window.refreshList }
}, [])
+
+ // 滚动加载更多
+ useEffect(() => {
+ const handleScroll = () => {
+ if (loading || loadingMore || !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(false)
+ }
+ }
+
+ window.addEventListener('scroll', handleScroll)
+ return () => window.removeEventListener('scroll', handleScroll)
+ }, [loading, loadingMore, hasMore, page])
const goDetail = (id) => {
// 保存当前列表的URL(包含筛选条件),用于返回时恢复
@@ -454,7 +470,7 @@ export default function List() {
-
我的藏品 ({filteredCollections.length})
+
我的藏品 ({total || filteredCollections.length})
{filter && filterType && (