feat(users): add batch API store methods

This commit is contained in:
RWDai
2026-05-07 19:16:49 +08:00
parent 8fa90e8ecf
commit ea014e0d89
2 changed files with 104 additions and 3 deletions

View File

@@ -45,6 +45,59 @@ export interface UpdateUserRequest {
rate_limit?: number | null
}
export interface UserBatchSelectionFilters {
search?: string
role?: 'admin' | 'user'
is_active?: boolean
}
export interface UserBatchSelection {
user_ids?: string[]
filters?: UserBatchSelectionFilters | null
}
export interface UserBatchSelectionItem {
user_id: string
username: string
email?: string | null
role: 'admin' | 'user'
is_active: boolean
}
export interface ResolveUserBatchSelectionResponse {
total: number
items: UserBatchSelectionItem[]
}
export interface UserBatchAccessControlPayload {
allowed_providers?: string[] | null
allowed_api_formats?: string[] | null
allowed_models?: string[] | null
rate_limit?: number | null
}
export type UserBatchAction = 'enable' | 'disable' | 'update_access_control'
export interface UserBatchActionRequest {
selection: UserBatchSelection
action: UserBatchAction
payload?: UserBatchAccessControlPayload | null
}
export interface UserBatchActionFailure {
user_id: string
reason: string
}
export interface UserBatchActionResponse {
total: number
success: number
failed: number
failures: UserBatchActionFailure[]
action?: string
modified_fields?: string[]
}
export interface ApiKey {
id: string // UUID
key?: string // 完整的 key只在创建时返回
@@ -98,6 +151,24 @@ export const usersApi = {
return response.data
},
async resolveBatchSelection(
selection: UserBatchSelection
): Promise<ResolveUserBatchSelectionResponse> {
const response = await apiClient.post<ResolveUserBatchSelectionResponse>(
'/api/admin/users/resolve-selection',
selection
)
return response.data
},
async batchAction(request: UserBatchActionRequest): Promise<UserBatchActionResponse> {
const response = await apiClient.post<UserBatchActionResponse>(
'/api/admin/users/batch-action',
request
)
return response.data
},
async deleteUser(userId: string): Promise<void> {
await apiClient.delete(`/api/admin/users/${userId}`)
},
@@ -113,12 +184,12 @@ export const usersApi = {
},
async revokeUserSession(userId: string, sessionId: string): Promise<{ message: string }> {
const response = await apiClient.delete(`/api/admin/users/${userId}/sessions/${sessionId}`)
const response = await apiClient.delete<{ message: string }>(`/api/admin/users/${userId}/sessions/${sessionId}`)
return response.data
},
async revokeAllUserSessions(userId: string): Promise<{ message: string; revoked_count: number }> {
const response = await apiClient.delete(`/api/admin/users/${userId}/sessions`)
const response = await apiClient.delete<{ message: string; revoked_count: number }>(`/api/admin/users/${userId}/sessions`)
return response.data
},
@@ -157,7 +228,7 @@ export const usersApi = {
},
// 管理员统计
async getUsageStats(): Promise<Record<string, unknown>> {
const response = await apiClient.get('/api/admin/usage/stats')
const response = await apiClient.get<Record<string, unknown>>('/api/admin/usage/stats')
return response.data
}
}

View File

@@ -8,6 +8,10 @@ import {
type ApiKey,
type UpsertUserApiKeyRequest,
type UserSession,
type UserBatchSelection,
type ResolveUserBatchSelectionResponse,
type UserBatchActionRequest,
type UserBatchActionResponse,
} from '@/api/users'
import { parseApiError } from '@/utils/errorParser'
@@ -83,6 +87,30 @@ export const useUsersStore = defineStore('users', () => {
}
}
async function resolveBatchSelection(
selection: UserBatchSelection
): Promise<ResolveUserBatchSelectionResponse> {
try {
return await usersApi.resolveBatchSelection(selection)
} catch (err: unknown) {
error.value = parseApiError(err, '解析用户选择失败')
throw err
}
}
async function batchAction(request: UserBatchActionRequest): Promise<UserBatchActionResponse> {
loading.value = true
error.value = null
try {
return await usersApi.batchAction(request)
} catch (err: unknown) {
error.value = parseApiError(err, '批量操作用户失败')
throw err
} finally {
loading.value = false
}
}
async function getUserApiKeys(userId: string): Promise<ApiKey[]> {
try {
return await usersApi.getUserApiKeys(userId)
@@ -169,6 +197,8 @@ export const useUsersStore = defineStore('users', () => {
createUser,
updateUser,
deleteUser,
resolveBatchSelection,
batchAction,
getUserApiKeys,
createApiKey,
updateApiKey,