| |
| |
| |
| |
|
|
| import { apiClient } from '../client' |
| import type { |
| Account, |
| CreateAccountRequest, |
| UpdateAccountRequest, |
| PaginatedResponse, |
| AccountUsageInfo, |
| WindowStats, |
| ClaudeModel, |
| AccountUsageStatsResponse, |
| TempUnschedulableStatus, |
| AdminDataPayload, |
| AdminDataImportResult, |
| CheckMixedChannelRequest, |
| CheckMixedChannelResponse |
| } from '@/types' |
|
|
| |
| |
| |
| |
| |
| |
| |
| export async function list( |
| page: number = 1, |
| pageSize: number = 20, |
| filters?: { |
| platform?: string |
| type?: string |
| status?: string |
| group?: string |
| search?: string |
| lite?: string |
| }, |
| options?: { |
| signal?: AbortSignal |
| } |
| ): Promise<PaginatedResponse<Account>> { |
| const { data } = await apiClient.get<PaginatedResponse<Account>>('/admin/accounts', { |
| params: { |
| page, |
| page_size: pageSize, |
| ...filters |
| }, |
| signal: options?.signal |
| }) |
| return data |
| } |
|
|
| export interface AccountListWithEtagResult { |
| notModified: boolean |
| etag: string | null |
| data: PaginatedResponse<Account> | null |
| } |
|
|
| export async function listWithEtag( |
| page: number = 1, |
| pageSize: number = 20, |
| filters?: { |
| platform?: string |
| type?: string |
| status?: string |
| group?: string |
| search?: string |
| lite?: string |
| }, |
| options?: { |
| signal?: AbortSignal |
| etag?: string | null |
| } |
| ): Promise<AccountListWithEtagResult> { |
| const headers: Record<string, string> = {} |
| if (options?.etag) { |
| headers['If-None-Match'] = options.etag |
| } |
|
|
| const response = await apiClient.get<PaginatedResponse<Account>>('/admin/accounts', { |
| params: { |
| page, |
| page_size: pageSize, |
| ...filters |
| }, |
| headers, |
| signal: options?.signal, |
| validateStatus: (status) => (status >= 200 && status < 300) || status === 304 |
| }) |
|
|
| const etagHeader = typeof response.headers?.etag === 'string' ? response.headers.etag : null |
| if (response.status === 304) { |
| return { |
| notModified: true, |
| etag: etagHeader, |
| data: null |
| } |
| } |
|
|
| return { |
| notModified: false, |
| etag: etagHeader, |
| data: response.data |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| export async function getById(id: number): Promise<Account> { |
| const { data } = await apiClient.get<Account>(`/admin/accounts/${id}`) |
| return data |
| } |
|
|
| |
| |
| |
| |
| |
| export async function create(accountData: CreateAccountRequest): Promise<Account> { |
| const { data } = await apiClient.post<Account>('/admin/accounts', accountData) |
| return data |
| } |
|
|
| |
| |
| |
| |
| |
| |
| export async function update(id: number, updates: UpdateAccountRequest): Promise<Account> { |
| const { data } = await apiClient.put<Account>(`/admin/accounts/${id}`, updates) |
| return data |
| } |
|
|
| |
| |
| |
| export async function checkMixedChannelRisk( |
| payload: CheckMixedChannelRequest |
| ): Promise<CheckMixedChannelResponse> { |
| const { data } = await apiClient.post<CheckMixedChannelResponse>('/admin/accounts/check-mixed-channel', payload) |
| return data |
| } |
|
|
| |
| |
| |
| |
| |
| export async function deleteAccount(id: number): Promise<{ message: string }> { |
| const { data } = await apiClient.delete<{ message: string }>(`/admin/accounts/${id}`) |
| return data |
| } |
|
|
| |
| |
| |
| |
| |
| |
| export async function toggleStatus(id: number, status: 'active' | 'inactive'): Promise<Account> { |
| return update(id, { status }) |
| } |
|
|
| |
| |
| |
| |
| |
| export async function testAccount(id: number): Promise<{ |
| success: boolean |
| message: string |
| latency_ms?: number |
| }> { |
| const { data } = await apiClient.post<{ |
| success: boolean |
| message: string |
| latency_ms?: number |
| }>(`/admin/accounts/${id}/test`) |
| return data |
| } |
|
|
| |
| |
| |
| |
| |
| export async function refreshCredentials(id: number): Promise<Account> { |
| const { data } = await apiClient.post<Account>(`/admin/accounts/${id}/refresh`) |
| return data |
| } |
|
|
| |
| |
| |
| |
| |
| |
| export async function getStats(id: number, days: number = 30): Promise<AccountUsageStatsResponse> { |
| const { data } = await apiClient.get<AccountUsageStatsResponse>(`/admin/accounts/${id}/stats`, { |
| params: { days } |
| }) |
| return data |
| } |
|
|
| |
| |
| |
| |
| |
| export async function clearError(id: number): Promise<Account> { |
| const { data } = await apiClient.post<Account>(`/admin/accounts/${id}/clear-error`) |
| return data |
| } |
|
|
| |
| |
| |
| |
| |
| export async function getUsage(id: number, source?: 'passive' | 'active'): Promise<AccountUsageInfo> { |
| const { data } = await apiClient.get<AccountUsageInfo>(`/admin/accounts/${id}/usage`, { |
| params: source ? { source } : undefined |
| }) |
| return data |
| } |
|
|
| |
| |
| |
| |
| |
| export async function clearRateLimit(id: number): Promise<Account> { |
| const { data } = await apiClient.post<Account>( |
| `/admin/accounts/${id}/clear-rate-limit` |
| ) |
| return data |
| } |
|
|
| |
| |
| |
| |
| |
| export async function recoverState(id: number): Promise<Account> { |
| const { data } = await apiClient.post<Account>(`/admin/accounts/${id}/recover-state`) |
| return data |
| } |
|
|
| |
| |
| |
| |
| |
| export async function resetAccountQuota(id: number): Promise<Account> { |
| const { data } = await apiClient.post<Account>( |
| `/admin/accounts/${id}/reset-quota` |
| ) |
| return data |
| } |
|
|
| |
| |
| |
| |
| |
| export async function getTempUnschedulableStatus(id: number): Promise<TempUnschedulableStatus> { |
| const { data } = await apiClient.get<TempUnschedulableStatus>( |
| `/admin/accounts/${id}/temp-unschedulable` |
| ) |
| return data |
| } |
|
|
| |
| |
| |
| |
| |
| export async function resetTempUnschedulable(id: number): Promise<{ message: string }> { |
| const { data } = await apiClient.delete<{ message: string }>( |
| `/admin/accounts/${id}/temp-unschedulable` |
| ) |
| return data |
| } |
|
|
| |
| |
| |
| |
| |
| |
| export async function generateAuthUrl( |
| endpoint: string, |
| config: { proxy_id?: number } |
| ): Promise<{ auth_url: string; session_id: string }> { |
| const { data } = await apiClient.post<{ auth_url: string; session_id: string }>(endpoint, config) |
| return data |
| } |
|
|
| |
| |
| |
| |
| |
| |
| export async function exchangeCode( |
| endpoint: string, |
| exchangeData: { session_id: string; code: string; state?: string; proxy_id?: number } |
| ): Promise<Record<string, unknown>> { |
| const { data } = await apiClient.post<Record<string, unknown>>(endpoint, exchangeData) |
| return data |
| } |
|
|
| |
| |
| |
| |
| |
| export async function batchCreate(accounts: CreateAccountRequest[]): Promise<{ |
| success: number |
| failed: number |
| results: Array<{ success: boolean; account?: Account; error?: string }> |
| }> { |
| const { data } = await apiClient.post<{ |
| success: number |
| failed: number |
| results: Array<{ success: boolean; account?: Account; error?: string }> |
| }>('/admin/accounts/batch', { accounts }) |
| return data |
| } |
|
|
| |
| |
| |
| |
| |
| export async function batchUpdateCredentials(request: { |
| account_ids: number[] |
| field: string |
| value: any |
| }): Promise<{ |
| success: number |
| failed: number |
| results: Array<{ account_id: number; success: boolean; error?: string }> |
| }> { |
| const { data } = await apiClient.post<{ |
| success: number |
| failed: number |
| results: Array<{ account_id: number; success: boolean; error?: string }> |
| }>('/admin/accounts/batch-update-credentials', request) |
| return data |
| } |
|
|
| |
| |
| |
| |
| |
| |
| export async function bulkUpdate( |
| accountIds: number[], |
| updates: Record<string, unknown> |
| ): Promise<{ |
| success: number |
| failed: number |
| success_ids?: number[] |
| failed_ids?: number[] |
| results: Array<{ account_id: number; success: boolean; error?: string }> |
| }> { |
| const { data } = await apiClient.post<{ |
| success: number |
| failed: number |
| success_ids?: number[] |
| failed_ids?: number[] |
| results: Array<{ account_id: number; success: boolean; error?: string }> |
| }>('/admin/accounts/bulk-update', { |
| account_ids: accountIds, |
| ...updates |
| }) |
| return data |
| } |
|
|
| |
| |
| |
| |
| |
| export async function getTodayStats(id: number): Promise<WindowStats> { |
| const { data } = await apiClient.get<WindowStats>(`/admin/accounts/${id}/today-stats`) |
| return data |
| } |
|
|
| export interface BatchTodayStatsResponse { |
| stats: Record<string, WindowStats> |
| } |
|
|
| |
| |
| |
| |
| |
| export async function getBatchTodayStats(accountIds: number[]): Promise<BatchTodayStatsResponse> { |
| const { data } = await apiClient.post<BatchTodayStatsResponse>('/admin/accounts/today-stats/batch', { |
| account_ids: accountIds |
| }) |
| return data |
| } |
|
|
| |
| |
| |
| |
| |
| |
| export async function setSchedulable(id: number, schedulable: boolean): Promise<Account> { |
| const { data } = await apiClient.post<Account>(`/admin/accounts/${id}/schedulable`, { |
| schedulable |
| }) |
| return data |
| } |
|
|
| |
| |
| |
| |
| |
| export async function getAvailableModels(id: number): Promise<ClaudeModel[]> { |
| const { data } = await apiClient.get<ClaudeModel[]>(`/admin/accounts/${id}/models`) |
| return data |
| } |
|
|
| export interface CRSPreviewAccount { |
| crs_account_id: string |
| kind: string |
| name: string |
| platform: string |
| type: string |
| } |
|
|
| export interface PreviewFromCRSResult { |
| new_accounts: CRSPreviewAccount[] |
| existing_accounts: CRSPreviewAccount[] |
| } |
|
|
| export async function previewFromCrs(params: { |
| base_url: string |
| username: string |
| password: string |
| }): Promise<PreviewFromCRSResult> { |
| const { data } = await apiClient.post<PreviewFromCRSResult>('/admin/accounts/sync/crs/preview', params) |
| return data |
| } |
|
|
| export async function syncFromCrs(params: { |
| base_url: string |
| username: string |
| password: string |
| sync_proxies?: boolean |
| selected_account_ids?: string[] |
| }): Promise<{ |
| created: number |
| updated: number |
| skipped: number |
| failed: number |
| items: Array<{ |
| crs_account_id: string |
| kind: string |
| name: string |
| action: string |
| error?: string |
| }> |
| }> { |
| const { data } = await apiClient.post<{ |
| created: number |
| updated: number |
| skipped: number |
| failed: number |
| items: Array<{ |
| crs_account_id: string |
| kind: string |
| name: string |
| action: string |
| error?: string |
| }> |
| }>('/admin/accounts/sync/crs', params) |
| return data |
| } |
|
|
| export async function exportData(options?: { |
| ids?: number[] |
| filters?: { |
| platform?: string |
| type?: string |
| status?: string |
| search?: string |
| } |
| includeProxies?: boolean |
| }): Promise<AdminDataPayload> { |
| const params: Record<string, string> = {} |
| if (options?.ids && options.ids.length > 0) { |
| params.ids = options.ids.join(',') |
| } else if (options?.filters) { |
| const { platform, type, status, search } = options.filters |
| if (platform) params.platform = platform |
| if (type) params.type = type |
| if (status) params.status = status |
| if (search) params.search = search |
| } |
| if (options?.includeProxies === false) { |
| params.include_proxies = 'false' |
| } |
| const { data } = await apiClient.get<AdminDataPayload>('/admin/accounts/data', { params }) |
| return data |
| } |
|
|
| export async function importData(payload: { |
| data: AdminDataPayload |
| skip_default_group_bind?: boolean |
| }): Promise<AdminDataImportResult> { |
| const { data } = await apiClient.post<AdminDataImportResult>('/admin/accounts/data', { |
| data: payload.data, |
| skip_default_group_bind: payload.skip_default_group_bind |
| }) |
| return data |
| } |
|
|
| |
| |
| |
| |
| export async function getAntigravityDefaultModelMapping(): Promise<Record<string, string>> { |
| const { data } = await apiClient.get<Record<string, string>>( |
| '/admin/accounts/antigravity/default-model-mapping' |
| ) |
| return data |
| } |
|
|
| |
| |
| |
| |
| |
| |
| export async function refreshOpenAIToken( |
| refreshToken: string, |
| proxyId?: number | null, |
| endpoint: string = '/admin/openai/refresh-token' |
| ): Promise<Record<string, unknown>> { |
| const payload: { refresh_token: string; proxy_id?: number } = { |
| refresh_token: refreshToken |
| } |
| if (proxyId) { |
| payload.proxy_id = proxyId |
| } |
| const { data } = await apiClient.post<Record<string, unknown>>(endpoint, payload) |
| return data |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| export async function validateSoraSessionToken( |
| sessionToken: string, |
| proxyId?: number | null, |
| endpoint: string = '/admin/sora/st2at' |
| ): Promise<Record<string, unknown>> { |
| const payload: { session_token: string; proxy_id?: number } = { |
| session_token: sessionToken |
| } |
| if (proxyId) { |
| payload.proxy_id = proxyId |
| } |
| const { data } = await apiClient.post<Record<string, unknown>>(endpoint, payload) |
| return data |
| } |
|
|
| |
| |
| |
| export interface BatchOperationResult { |
| total: number |
| success: number |
| failed: number |
| errors?: Array<{ account_id: number; error: string }> |
| warnings?: Array<{ account_id: number; warning: string }> |
| } |
|
|
| |
| |
| |
| |
| |
| export async function batchClearError(accountIds: number[]): Promise<BatchOperationResult> { |
| const { data } = await apiClient.post<BatchOperationResult>('/admin/accounts/batch-clear-error', { |
| account_ids: accountIds |
| }) |
| return data |
| } |
|
|
| |
| |
| |
| |
| |
| export async function batchRefresh(accountIds: number[]): Promise<BatchOperationResult> { |
| const { data } = await apiClient.post<BatchOperationResult>('/admin/accounts/batch-refresh', { |
| account_ids: accountIds, |
| }, { |
| timeout: 120000 |
| }) |
| return data |
| } |
|
|
| export const accountsAPI = { |
| list, |
| listWithEtag, |
| getById, |
| create, |
| update, |
| checkMixedChannelRisk, |
| delete: deleteAccount, |
| toggleStatus, |
| testAccount, |
| refreshCredentials, |
| getStats, |
| clearError, |
| getUsage, |
| getTodayStats, |
| getBatchTodayStats, |
| clearRateLimit, |
| recoverState, |
| resetAccountQuota, |
| getTempUnschedulableStatus, |
| resetTempUnschedulable, |
| setSchedulable, |
| getAvailableModels, |
| generateAuthUrl, |
| exchangeCode, |
| refreshOpenAIToken, |
| validateSoraSessionToken, |
| batchCreate, |
| batchUpdateCredentials, |
| bulkUpdate, |
| previewFromCrs, |
| syncFromCrs, |
| exportData, |
| importData, |
| getAntigravityDefaultModelMapping, |
| batchClearError, |
| batchRefresh |
| } |
|
|
| export default accountsAPI |
|
|