feat(pool): 批量操作对话框改为服务端分页筛选,新增凭据导出功能

- 批量操作对话框从全量加载改为服务端分页+筛选,支持搜索和快捷选择器的服务端过滤
- 新增 resolve-selection API,支持"全选筛选结果"时解析完整匹配列表
- 新增批量导出凭据功能(仅 OAuth 账号),并发下载后导出为 JSON 文件
- 将快捷选择器和全文搜索的匹配逻辑从前端迁移到后端,统一复用
- 提取 pool key 序列化与过滤的公共函数,消除 AdminListPoolKeysAdapter 中的重复代码
- entrypoint.sh 增加 PostgreSQL 就绪等待,避免数据库未启动时迁移失败
This commit is contained in:
fawney19
2026-03-11 18:18:59 +08:00
parent 1a1bce3e8c
commit b45f021bba
6 changed files with 994 additions and 492 deletions

View File

@@ -169,6 +169,24 @@ export interface PoolKeysQuery {
page_size?: number
search?: string
status?: 'all' | 'active' | 'cooldown' | 'inactive'
quick_selectors?: string[]
search_scope?: 'name' | 'full'
}
export interface PoolKeySelectionRequest {
search?: string
quick_selectors?: string[]
}
export interface PoolKeySelectionItem {
key_id: string
key_name: string
auth_type: string
}
export interface PoolKeySelectionResponse {
total: number
items: PoolKeySelectionItem[]
}
export interface PoolBatchAction {
@@ -203,13 +221,29 @@ export async function listPoolKeys(
providerId: string,
params: PoolKeysQuery = {},
): Promise<PoolKeysPageResponse> {
const key = `pool:keys:${providerId}|${params.page ?? ''}|${params.page_size ?? ''}|${params.search ?? ''}|${params.status ?? ''}`
const normalizedParams = {
...params,
quick_selectors: params.quick_selectors?.length ? params.quick_selectors.join(',') : undefined,
}
const key = `pool:keys:${providerId}|${normalizedParams.page ?? ''}|${normalizedParams.page_size ?? ''}|${normalizedParams.search ?? ''}|${normalizedParams.status ?? ''}|${normalizedParams.quick_selectors ?? ''}|${normalizedParams.search_scope ?? ''}`
return dedupedRequest(key, async () => {
const response = await client.get<PoolKeysPageResponse>(`/api/admin/pool/${providerId}/keys`, { params })
const response = await client.get<PoolKeysPageResponse>(`/api/admin/pool/${providerId}/keys`, { params: normalizedParams })
return response.data
})
}
export async function resolvePoolKeySelection(
providerId: string,
body: PoolKeySelectionRequest,
): Promise<PoolKeySelectionResponse> {
const response = await client.post<PoolKeySelectionResponse>(
`/api/admin/pool/${providerId}/keys/resolve-selection`,
body,
{ timeout: POOL_BATCH_ACTION_TIMEOUT_MS },
)
return response.data
}
export async function batchActionPoolKeys(
providerId: string,
body: PoolBatchAction,