mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 01:10:23 +08:00
Fix admin users pagination follow-ups
This commit is contained in:
@@ -274,7 +274,6 @@ import type {
|
|||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
open: boolean
|
open: boolean
|
||||||
users: User[]
|
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
@@ -295,8 +294,11 @@ const {
|
|||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const saving = ref(false)
|
const saving = ref(false)
|
||||||
const groups = ref<UserGroup[]>([])
|
const groups = ref<UserGroup[]>([])
|
||||||
|
const dialogUsers = ref<User[]>([])
|
||||||
const editingGroupId = ref<string | null>(null)
|
const editingGroupId = ref<string | null>(null)
|
||||||
const memberUserIds = ref<string[]>([])
|
const memberUserIds = ref<string[]>([])
|
||||||
|
const USER_OPTIONS_CACHE_TTL_MS = 30 * 1000
|
||||||
|
let dialogUsersLoadedAt = 0
|
||||||
|
|
||||||
const form = ref({
|
const form = ref({
|
||||||
name: '',
|
name: '',
|
||||||
@@ -311,7 +313,7 @@ const form = ref({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const selectedGroup = computed(() => groups.value.find((group) => group.id === editingGroupId.value) ?? null)
|
const selectedGroup = computed(() => groups.value.find((group) => group.id === editingGroupId.value) ?? null)
|
||||||
const userOptions = computed(() => props.users.map((user) => ({
|
const userOptions = computed(() => dialogUsers.value.map((user) => ({
|
||||||
label: `${user.username}${user.email ? ` (${user.email})` : ''}`,
|
label: `${user.username}${user.email ? ` (${user.email})` : ''}`,
|
||||||
value: user.id,
|
value: user.id,
|
||||||
})))
|
})))
|
||||||
@@ -334,8 +336,11 @@ function handleDialogUpdate(value: boolean): void {
|
|||||||
async function loadDialogData(): Promise<void> {
|
async function loadDialogData(): Promise<void> {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
try {
|
try {
|
||||||
const response = await usersStore.listUserGroups()
|
const [groupsResponse] = await Promise.all([
|
||||||
groups.value = response.items
|
usersStore.listUserGroups(),
|
||||||
|
ensureDialogUsers(),
|
||||||
|
])
|
||||||
|
groups.value = groupsResponse.items
|
||||||
if (editingGroupId.value && !groups.value.some((group) => group.id === editingGroupId.value)) {
|
if (editingGroupId.value && !groups.value.some((group) => group.id === editingGroupId.value)) {
|
||||||
editingGroupId.value = null
|
editingGroupId.value = null
|
||||||
}
|
}
|
||||||
@@ -354,6 +359,16 @@ async function loadDialogData(): Promise<void> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function ensureDialogUsers(): Promise<void> {
|
||||||
|
const now = Date.now()
|
||||||
|
if (dialogUsersLoadedAt > 0 && now - dialogUsersLoadedAt < USER_OPTIONS_CACHE_TTL_MS) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
dialogUsers.value = await usersStore.listAllUsers({ cacheTtlMs: USER_OPTIONS_CACHE_TTL_MS })
|
||||||
|
dialogUsersLoadedAt = Date.now()
|
||||||
|
}
|
||||||
|
|
||||||
async function selectGroup(groupId: string): Promise<void> {
|
async function selectGroup(groupId: string): Promise<void> {
|
||||||
const group = groups.value.find((item) => item.id === groupId)
|
const group = groups.value.find((item) => item.id === groupId)
|
||||||
if (!group) return
|
if (!group) return
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { ref } from 'vue'
|
|||||||
import {
|
import {
|
||||||
usersApi,
|
usersApi,
|
||||||
type User,
|
type User,
|
||||||
|
type GetAllUsersOptions,
|
||||||
type CreateUserRequest,
|
type CreateUserRequest,
|
||||||
type UpdateUserRequest,
|
type UpdateUserRequest,
|
||||||
type ApiKey,
|
type ApiKey,
|
||||||
@@ -31,6 +32,7 @@ export const useUsersStore = defineStore('users', () => {
|
|||||||
const hasMore = ref(false)
|
const hasMore = ref(false)
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const error = ref<string | null>(null)
|
const error = ref<string | null>(null)
|
||||||
|
let fetchUsersRequestId = 0
|
||||||
|
|
||||||
async function fetchUsers(options: {
|
async function fetchUsers(options: {
|
||||||
cacheTtlMs?: number
|
cacheTtlMs?: number
|
||||||
@@ -41,20 +43,44 @@ export const useUsersStore = defineStore('users', () => {
|
|||||||
skip?: number
|
skip?: number
|
||||||
limit?: number
|
limit?: number
|
||||||
} = {}) {
|
} = {}) {
|
||||||
|
const requestId = ++fetchUsersRequestId
|
||||||
loading.value = true
|
loading.value = true
|
||||||
error.value = null
|
error.value = null
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await usersApi.getAllUsersPage(options)
|
const response = await usersApi.getAllUsersPage(options)
|
||||||
|
if (requestId !== fetchUsersRequestId) return
|
||||||
users.value = response.items
|
users.value = response.items
|
||||||
total.value = response.total
|
total.value = response.total
|
||||||
skip.value = response.skip
|
skip.value = response.skip
|
||||||
limit.value = response.limit
|
limit.value = response.limit
|
||||||
hasMore.value = response.has_more
|
hasMore.value = response.has_more
|
||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
|
if (requestId !== fetchUsersRequestId) return
|
||||||
error.value = parseApiError(err, '获取用户列表失败')
|
error.value = parseApiError(err, '获取用户列表失败')
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
if (requestId === fetchUsersRequestId) {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function listAllUsers(options: Omit<GetAllUsersOptions, 'skip' | 'limit'> = {}): Promise<User[]> {
|
||||||
|
const pageSize = 1000
|
||||||
|
const allUsers: User[] = []
|
||||||
|
let skip = 0
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
const response = await usersApi.getAllUsersPage({
|
||||||
|
...options,
|
||||||
|
skip,
|
||||||
|
limit: pageSize,
|
||||||
|
})
|
||||||
|
allUsers.push(...response.items)
|
||||||
|
if (!response.has_more || response.items.length === 0) {
|
||||||
|
return allUsers
|
||||||
|
}
|
||||||
|
skip += response.items.length
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -315,6 +341,7 @@ export const useUsersStore = defineStore('users', () => {
|
|||||||
loading,
|
loading,
|
||||||
error,
|
error,
|
||||||
fetchUsers,
|
fetchUsers,
|
||||||
|
listAllUsers,
|
||||||
createUser,
|
createUser,
|
||||||
updateUser,
|
updateUser,
|
||||||
deleteUser,
|
deleteUser,
|
||||||
|
|||||||
@@ -843,7 +843,6 @@
|
|||||||
|
|
||||||
<UserGroupsDialog
|
<UserGroupsDialog
|
||||||
:open="showUserGroupsDialog"
|
:open="showUserGroupsDialog"
|
||||||
:users="usersStore.users"
|
|
||||||
@close="showUserGroupsDialog = false"
|
@close="showUserGroupsDialog = false"
|
||||||
@changed="handleUserGroupsChanged"
|
@changed="handleUserGroupsChanged"
|
||||||
/>
|
/>
|
||||||
@@ -1947,7 +1946,6 @@ async function handleUserFormSubmit(data: UserFormData & { password?: string; un
|
|||||||
updateData.password = data.password
|
updateData.password = data.password
|
||||||
}
|
}
|
||||||
await usersStore.updateUser(data.id, updateData)
|
await usersStore.updateUser(data.id, updateData)
|
||||||
await loadUserWallets()
|
|
||||||
success('用户信息已更新')
|
success('用户信息已更新')
|
||||||
} else {
|
} else {
|
||||||
// 创建用户
|
// 创建用户
|
||||||
@@ -1965,10 +1963,10 @@ async function handleUserFormSubmit(data: UserFormData & { password?: string; un
|
|||||||
if (data.is_active === false && newUser) {
|
if (data.is_active === false && newUser) {
|
||||||
await usersStore.updateUser(newUser.id, { is_active: false })
|
await usersStore.updateUser(newUser.id, { is_active: false })
|
||||||
}
|
}
|
||||||
await loadUserWallets()
|
|
||||||
success('用户创建成功')
|
success('用户创建成功')
|
||||||
}
|
}
|
||||||
closeUserFormDialog()
|
closeUserFormDialog()
|
||||||
|
await refreshUsers()
|
||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
const title = data.id ? '更新用户失败' : '创建用户失败'
|
const title = data.id ? '更新用户失败' : '创建用户失败'
|
||||||
error(parseApiError(err, '未知错误'), title)
|
error(parseApiError(err, '未知错误'), title)
|
||||||
@@ -2272,6 +2270,10 @@ async function deleteUser(user: User) {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await usersStore.deleteUser(user.id)
|
await usersStore.deleteUser(user.id)
|
||||||
|
if (usersStore.users.length === 0 && currentPage.value > 1) {
|
||||||
|
currentPage.value -= 1
|
||||||
|
}
|
||||||
|
await refreshUsers()
|
||||||
success('用户已删除')
|
success('用户已删除')
|
||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
error(parseApiError(err, '未知错误'), '删除用户失败')
|
error(parseApiError(err, '未知错误'), '删除用户失败')
|
||||||
|
|||||||
Reference in New Issue
Block a user