mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-03 01:40:21 +08:00
Track admin users pagination in frontend data layer
This commit is contained in:
@@ -3,7 +3,7 @@ import { cachedRequest } from '@/utils/cache'
|
|||||||
import type { UserSession as SessionRecord } from '@/types/session'
|
import type { UserSession as SessionRecord } from '@/types/session'
|
||||||
import type { BillingPlan, UserPlanEntitlement } from './billing'
|
import type { BillingPlan, UserPlanEntitlement } from './billing'
|
||||||
|
|
||||||
export type UserRole = 'admin' | 'user'
|
export type UserRole = 'admin' | 'audit_admin' | 'user'
|
||||||
export type ListPolicyMode = 'inherit' | 'unrestricted' | 'specific' | 'deny_all'
|
export type ListPolicyMode = 'inherit' | 'unrestricted' | 'specific' | 'deny_all'
|
||||||
export type RateLimitPolicyMode = 'inherit' | 'system' | 'custom'
|
export type RateLimitPolicyMode = 'inherit' | 'system' | 'custom'
|
||||||
export type FeatureSettings = Record<string, unknown>
|
export type FeatureSettings = Record<string, unknown>
|
||||||
@@ -264,8 +264,29 @@ export interface GetAllUsersOptions {
|
|||||||
cacheTtlMs?: number
|
cacheTtlMs?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface AdminUsersListResponse {
|
||||||
|
items: User[]
|
||||||
|
total: number
|
||||||
|
skip: number
|
||||||
|
limit: number
|
||||||
|
has_more: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeAdminUsersListResponse(payload: User[] | AdminUsersListResponse): AdminUsersListResponse {
|
||||||
|
if (Array.isArray(payload)) {
|
||||||
|
return {
|
||||||
|
items: payload,
|
||||||
|
total: payload.length,
|
||||||
|
skip: 0,
|
||||||
|
limit: payload.length,
|
||||||
|
has_more: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return payload
|
||||||
|
}
|
||||||
|
|
||||||
export const usersApi = {
|
export const usersApi = {
|
||||||
async getAllUsers(options: GetAllUsersOptions = {}): Promise<User[]> {
|
async getAllUsersPage(options: GetAllUsersOptions = {}): Promise<AdminUsersListResponse> {
|
||||||
const cacheTtlMs = options.cacheTtlMs ?? 0
|
const cacheTtlMs = options.cacheTtlMs ?? 0
|
||||||
const params: Record<string, string | number> = {}
|
const params: Record<string, string | number> = {}
|
||||||
const search = options.search?.trim()
|
const search = options.search?.trim()
|
||||||
@@ -292,15 +313,20 @@ export const usersApi = {
|
|||||||
return cachedRequest(
|
return cachedRequest(
|
||||||
cacheKey,
|
cacheKey,
|
||||||
async () => {
|
async () => {
|
||||||
const response = await apiClient.get<User[]>('/api/admin/users', {
|
const response = await apiClient.get<User[] | AdminUsersListResponse>('/api/admin/users', {
|
||||||
params: Object.keys(params).length > 0 ? params : undefined,
|
params: Object.keys(params).length > 0 ? params : undefined,
|
||||||
})
|
})
|
||||||
return response.data
|
return normalizeAdminUsersListResponse(response.data)
|
||||||
},
|
},
|
||||||
cacheTtlMs,
|
cacheTtlMs,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async getAllUsers(options: GetAllUsersOptions = {}): Promise<User[]> {
|
||||||
|
const response = await this.getAllUsersPage(options)
|
||||||
|
return response.items
|
||||||
|
},
|
||||||
|
|
||||||
async getUser(userId: string): Promise<User> {
|
async getUser(userId: string): Promise<User> {
|
||||||
const response = await apiClient.get<User>(`/api/admin/users/${userId}`)
|
const response = await apiClient.get<User>(`/api/admin/users/${userId}`)
|
||||||
return response.data
|
return response.data
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import {
|
|||||||
type ResolveUserBatchSelectionResponse,
|
type ResolveUserBatchSelectionResponse,
|
||||||
type UserBatchActionRequest,
|
type UserBatchActionRequest,
|
||||||
type UserBatchActionResponse,
|
type UserBatchActionResponse,
|
||||||
|
type UserRole,
|
||||||
type UserGroup,
|
type UserGroup,
|
||||||
type UserGroupMember,
|
type UserGroupMember,
|
||||||
type UpsertUserGroupRequest,
|
type UpsertUserGroupRequest,
|
||||||
@@ -24,21 +25,32 @@ import { parseApiError } from '@/utils/errorParser'
|
|||||||
|
|
||||||
export const useUsersStore = defineStore('users', () => {
|
export const useUsersStore = defineStore('users', () => {
|
||||||
const users = ref<User[]>([])
|
const users = ref<User[]>([])
|
||||||
|
const total = ref(0)
|
||||||
|
const skip = ref(0)
|
||||||
|
const limit = ref(0)
|
||||||
|
const hasMore = ref(false)
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const error = ref<string | null>(null)
|
const error = ref<string | null>(null)
|
||||||
|
|
||||||
async function fetchUsers(options: {
|
async function fetchUsers(options: {
|
||||||
cacheTtlMs?: number
|
cacheTtlMs?: number
|
||||||
search?: string
|
search?: string
|
||||||
role?: 'admin' | 'user'
|
role?: UserRole
|
||||||
is_active?: boolean
|
is_active?: boolean
|
||||||
group_id?: string
|
group_id?: string
|
||||||
|
skip?: number
|
||||||
|
limit?: number
|
||||||
} = {}) {
|
} = {}) {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
error.value = null
|
error.value = null
|
||||||
|
|
||||||
try {
|
try {
|
||||||
users.value = await usersApi.getAllUsers(options)
|
const response = await usersApi.getAllUsersPage(options)
|
||||||
|
users.value = response.items
|
||||||
|
total.value = response.total
|
||||||
|
skip.value = response.skip
|
||||||
|
limit.value = response.limit
|
||||||
|
hasMore.value = response.has_more
|
||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
error.value = parseApiError(err, '获取用户列表失败')
|
error.value = parseApiError(err, '获取用户列表失败')
|
||||||
} finally {
|
} finally {
|
||||||
@@ -296,6 +308,10 @@ export const useUsersStore = defineStore('users', () => {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
users,
|
users,
|
||||||
|
total,
|
||||||
|
skip,
|
||||||
|
limit,
|
||||||
|
hasMore,
|
||||||
loading,
|
loading,
|
||||||
error,
|
error,
|
||||||
fetchUsers,
|
fetchUsers,
|
||||||
|
|||||||
Reference in New Issue
Block a user