feat(admin): batch update user limits

This commit is contained in:
zhaozewu
2026-07-16 15:37:35 +08:00
parent 09c6c6d740
commit 7947619cc3
31 changed files with 1243 additions and 9 deletions
@@ -11,9 +11,12 @@ vi.mock('@/api/client', () => ({
}))
import {
batchUpdateLimits,
bindUserAuthIdentity,
type AdminBindAuthIdentityRequest,
type AdminBoundAuthIdentity,
type BatchUpdateUserLimitsRequest,
type BatchUpdateUserLimitsResponse,
} from '@/api/admin/users'
type Assert<T extends true> = T
@@ -63,6 +66,20 @@ const requestContractExact: Assert<
const responseContractExact: Assert<
IsExact<AdminBoundAuthIdentity, ExpectedAdminBoundAuthIdentity>
> = true
const batchRequestContractExact: Assert<
IsExact<
BatchUpdateUserLimitsRequest,
{
user_ids: number[]
all?: boolean
concurrency?: number
rpm_limit?: number
}
>
> = true
const batchResponseContractExact: Assert<
IsExact<BatchUpdateUserLimitsResponse, { affected: number }>
> = true
describe('admin users api auth identity binding', () => {
beforeEach(() => {
@@ -114,4 +131,20 @@ describe('admin users api auth identity binding', () => {
expect(requestContractExact).toBe(true)
expect(responseContractExact).toBe(true)
})
it('posts batch limit updates once with only the supplied limit fields', async () => {
const request: BatchUpdateUserLimitsRequest = {
user_ids: [4, 7],
all: false,
rpm_limit: 0,
}
post.mockResolvedValue({ data: { affected: 2 } satisfies BatchUpdateUserLimitsResponse })
const result = await batchUpdateLimits(request)
expect(post).toHaveBeenCalledWith('/admin/users/batch-limits', request)
expect(result).toEqual({ affected: 2 })
expect(batchRequestContractExact).toBe(true)
expect(batchResponseContractExact).toBe(true)
})
})
+23
View File
@@ -44,6 +44,17 @@ export interface AdminBoundAuthIdentity {
channel?: AdminBoundAuthIdentityChannel | null
}
export interface BatchUpdateUserLimitsRequest {
user_ids: number[]
all?: boolean
concurrency?: number
rpm_limit?: number
}
export interface BatchUpdateUserLimitsResponse {
affected: number
}
/**
* List all users with pagination
* @param page - Page number (default: 1)
@@ -184,6 +195,17 @@ export async function updateConcurrency(id: number, concurrency: number): Promis
return update(id, { concurrency })
}
/** Overwrite concurrency and/or RPM limits for multiple users in one request. */
export async function batchUpdateLimits(
request: BatchUpdateUserLimitsRequest
): Promise<BatchUpdateUserLimitsResponse> {
const { data } = await apiClient.post<BatchUpdateUserLimitsResponse>(
'/admin/users/batch-limits',
request
)
return data
}
/**
* Toggle user status
* @param id - User ID
@@ -385,6 +407,7 @@ export const usersAPI = {
delete: deleteUser,
updateBalance,
updateConcurrency,
batchUpdateLimits,
toggleStatus,
getUserApiKeys,
getUserUsageStats,