mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-03 01:40:21 +08:00
feat: 添加 Provider Ops 扩展操作系统,支持余额监控
主要更改: - 新增 Provider Ops 服务框架,支持通过架构配置执行余额查询等扩展操作 - 后端:添加 provider_ops 服务层和 API 路由 - 前端:添加 ProviderAuthDialog 组件配置认证信息 - 前端:添加 providerOps API 和认证模板系统 UI/组件优化: - Input 组件:新增 masked 属性,使用 CSS 遮蔽敏感信息,避免触发密码管理器 - Pagination 组件:移除首页/末页/上下页按钮,改为页码跳转输入框 - KeyFormDialog:使用 masked 属性简化 API Key 输入逻辑 - ProviderManagement:重新设计表格布局,显示余额监控数据
This commit is contained in:
@@ -310,6 +310,7 @@ export interface ProviderWithEndpointsSummary {
|
||||
unhealthy_endpoints: number
|
||||
api_formats: string[]
|
||||
endpoint_health_details: EndpointHealthDetail[]
|
||||
ops_configured: boolean // 是否配置了扩展操作(余额监控等)
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}
|
||||
|
||||
353
frontend/src/api/providerOps.ts
Normal file
353
frontend/src/api/providerOps.ts
Normal file
@@ -0,0 +1,353 @@
|
||||
/**
|
||||
* Provider 操作 API
|
||||
*
|
||||
* 提供 Provider 扩展操作相关的 API:
|
||||
* - 架构管理
|
||||
* - 连接管理
|
||||
* - 操作执行(余额查询、签到等)
|
||||
*/
|
||||
|
||||
import client from './client'
|
||||
|
||||
// ==================== Types ====================
|
||||
|
||||
/** 认证类型 */
|
||||
export type ConnectorAuthType = 'api_key' | 'session_login' | 'oauth' | 'cookie' | 'none'
|
||||
|
||||
/** 操作类型 */
|
||||
export type ProviderActionType =
|
||||
| 'query_balance'
|
||||
| 'checkin'
|
||||
| 'claim_quota'
|
||||
| 'refresh_token'
|
||||
| 'get_usage'
|
||||
| 'get_models'
|
||||
| 'custom'
|
||||
|
||||
/** 操作状态 */
|
||||
export type ActionStatus =
|
||||
| 'success'
|
||||
| 'auth_failed'
|
||||
| 'auth_expired'
|
||||
| 'rate_limited'
|
||||
| 'network_error'
|
||||
| 'parse_error'
|
||||
| 'not_configured'
|
||||
| 'not_supported'
|
||||
| 'already_done'
|
||||
| 'unknown_error'
|
||||
|
||||
/** 连接状态 */
|
||||
export type ConnectorStatus = 'disconnected' | 'connecting' | 'connected' | 'expired' | 'error'
|
||||
|
||||
/** 架构信息 */
|
||||
export interface ArchitectureInfo {
|
||||
architecture_id: string
|
||||
display_name: string
|
||||
description: string
|
||||
supported_auth_types: Array<{
|
||||
type: string
|
||||
display_name: string
|
||||
}>
|
||||
supported_actions: Array<{
|
||||
type: string
|
||||
display_name: string
|
||||
description: string
|
||||
config_schema: Record<string, any>
|
||||
}>
|
||||
default_connector: string | null
|
||||
}
|
||||
|
||||
/** 连接状态响应 */
|
||||
export interface ConnectionStatusResponse {
|
||||
status: ConnectorStatus
|
||||
auth_type: ConnectorAuthType
|
||||
connected_at: string | null
|
||||
expires_at: string | null
|
||||
last_error: string | null
|
||||
}
|
||||
|
||||
/** Provider 操作状态响应 */
|
||||
export interface ProviderOpsStatusResponse {
|
||||
provider_id: string
|
||||
is_configured: boolean
|
||||
architecture_id: string | null
|
||||
connection_status: ConnectionStatusResponse
|
||||
enabled_actions: string[]
|
||||
}
|
||||
|
||||
/** 余额信息 */
|
||||
export interface BalanceInfo {
|
||||
total_granted: number | null
|
||||
total_used: number | null
|
||||
total_available: number | null
|
||||
expires_at: string | null
|
||||
currency: string
|
||||
extra: Record<string, any>
|
||||
}
|
||||
|
||||
/** 签到信息 */
|
||||
export interface CheckinInfo {
|
||||
reward: number | null
|
||||
streak_days: number | null
|
||||
next_reward: number | null
|
||||
message: string | null
|
||||
extra: Record<string, any>
|
||||
}
|
||||
|
||||
/** 操作结果响应 */
|
||||
export interface ActionResultResponse {
|
||||
status: ActionStatus
|
||||
action_type: ProviderActionType
|
||||
data: BalanceInfo | CheckinInfo | Record<string, unknown> | null
|
||||
message: string | null
|
||||
executed_at: string
|
||||
response_time_ms: number | null
|
||||
cache_ttl_seconds: number
|
||||
}
|
||||
|
||||
/** 连接器配置请求 */
|
||||
export interface ConnectorConfigRequest {
|
||||
auth_type: ConnectorAuthType
|
||||
config: Record<string, any>
|
||||
credentials: Record<string, any>
|
||||
}
|
||||
|
||||
/** 操作配置请求 */
|
||||
export interface ActionConfigRequest {
|
||||
enabled: boolean
|
||||
config: Record<string, any>
|
||||
}
|
||||
|
||||
/** 保存配置请求 */
|
||||
export interface SaveConfigRequest {
|
||||
architecture_id: string
|
||||
base_url?: string
|
||||
connector: ConnectorConfigRequest
|
||||
actions: Record<string, ActionConfigRequest>
|
||||
schedule: Record<string, string>
|
||||
}
|
||||
|
||||
/** 连接请求 */
|
||||
export interface ConnectRequest {
|
||||
credentials?: Record<string, any>
|
||||
}
|
||||
|
||||
/** 执行操作请求 */
|
||||
export interface ExecuteActionRequest {
|
||||
config?: Record<string, any>
|
||||
}
|
||||
|
||||
// ==================== API Functions ====================
|
||||
|
||||
const BASE_URL = '/api/admin/provider-ops'
|
||||
|
||||
/**
|
||||
* 获取所有可用的架构
|
||||
*/
|
||||
export async function getArchitectures(): Promise<ArchitectureInfo[]> {
|
||||
const response = await client.get<ArchitectureInfo[]>(`${BASE_URL}/architectures`)
|
||||
return response.data
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定架构的详情
|
||||
*/
|
||||
export async function getArchitecture(architectureId: string): Promise<ArchitectureInfo> {
|
||||
const response = await client.get<ArchitectureInfo>(
|
||||
`${BASE_URL}/architectures/${architectureId}`
|
||||
)
|
||||
return response.data
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 Provider 的操作状态
|
||||
*/
|
||||
export async function getProviderOpsStatus(
|
||||
providerId: string
|
||||
): Promise<ProviderOpsStatusResponse> {
|
||||
const response = await client.get<ProviderOpsStatusResponse>(
|
||||
`${BASE_URL}/providers/${providerId}/status`
|
||||
)
|
||||
return response.data
|
||||
}
|
||||
|
||||
/** Provider 操作配置响应(脱敏) */
|
||||
export interface ProviderOpsConfigResponse {
|
||||
provider_id: string
|
||||
is_configured: boolean
|
||||
architecture_id?: string
|
||||
base_url?: string
|
||||
connector?: {
|
||||
auth_type: string
|
||||
config: Record<string, any>
|
||||
credentials: Record<string, any>
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 Provider 的操作配置(脱敏)
|
||||
*/
|
||||
export async function getProviderOpsConfig(
|
||||
providerId: string
|
||||
): Promise<ProviderOpsConfigResponse> {
|
||||
const response = await client.get<ProviderOpsConfigResponse>(
|
||||
`${BASE_URL}/providers/${providerId}/config`
|
||||
)
|
||||
return response.data
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存 Provider 的操作配置
|
||||
*/
|
||||
export async function saveProviderOpsConfig(
|
||||
providerId: string,
|
||||
config: SaveConfigRequest
|
||||
): Promise<{ success: boolean; message: string }> {
|
||||
const response = await client.put<{ success: boolean; message: string }>(
|
||||
`${BASE_URL}/providers/${providerId}/config`,
|
||||
config
|
||||
)
|
||||
return response.data
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除 Provider 的操作配置
|
||||
*/
|
||||
export async function deleteProviderOpsConfig(
|
||||
providerId: string
|
||||
): Promise<{ success: boolean; message: string }> {
|
||||
const response = await client.delete<{ success: boolean; message: string }>(
|
||||
`${BASE_URL}/providers/${providerId}/config`
|
||||
)
|
||||
return response.data
|
||||
}
|
||||
|
||||
/**
|
||||
* 建立与 Provider 的连接
|
||||
*/
|
||||
export async function connectProvider(
|
||||
providerId: string,
|
||||
request?: ConnectRequest
|
||||
): Promise<{ success: boolean; message: string }> {
|
||||
const response = await client.post<{ success: boolean; message: string }>(
|
||||
`${BASE_URL}/providers/${providerId}/connect`,
|
||||
request || {}
|
||||
)
|
||||
return response.data
|
||||
}
|
||||
|
||||
/**
|
||||
* 断开与 Provider 的连接
|
||||
*/
|
||||
export async function disconnectProvider(
|
||||
providerId: string
|
||||
): Promise<{ success: boolean; message: string }> {
|
||||
const response = await client.post<{ success: boolean; message: string }>(
|
||||
`${BASE_URL}/providers/${providerId}/disconnect`
|
||||
)
|
||||
return response.data
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行指定操作
|
||||
*/
|
||||
export async function executeAction(
|
||||
providerId: string,
|
||||
actionType: ProviderActionType,
|
||||
request?: ExecuteActionRequest
|
||||
): Promise<ActionResultResponse> {
|
||||
const response = await client.post<ActionResultResponse>(
|
||||
`${BASE_URL}/providers/${providerId}/actions/${actionType}`,
|
||||
request || {}
|
||||
)
|
||||
return response.data
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取余额(优先返回缓存,后台异步刷新)
|
||||
* @param providerId Provider ID
|
||||
* @param refresh 是否触发后台刷新(默认 true)
|
||||
*/
|
||||
export async function getBalance(
|
||||
providerId: string,
|
||||
refresh: boolean = true
|
||||
): Promise<ActionResultResponse> {
|
||||
const response = await client.get<ActionResultResponse>(
|
||||
`${BASE_URL}/providers/${providerId}/balance`,
|
||||
{ params: { refresh } }
|
||||
)
|
||||
return response.data
|
||||
}
|
||||
|
||||
/**
|
||||
* 立即刷新余额(同步等待结果)
|
||||
*/
|
||||
export async function refreshBalance(providerId: string): Promise<ActionResultResponse> {
|
||||
const response = await client.post<ActionResultResponse>(
|
||||
`${BASE_URL}/providers/${providerId}/balance`
|
||||
)
|
||||
return response.data
|
||||
}
|
||||
|
||||
/**
|
||||
* 签到(快捷方法)
|
||||
*/
|
||||
export async function checkin(providerId: string): Promise<ActionResultResponse> {
|
||||
const response = await client.post<ActionResultResponse>(
|
||||
`${BASE_URL}/providers/${providerId}/checkin`
|
||||
)
|
||||
return response.data
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量查询余额
|
||||
*/
|
||||
export async function batchQueryBalance(
|
||||
providerIds?: string[]
|
||||
): Promise<Record<string, ActionResultResponse>> {
|
||||
const response = await client.post<Record<string, ActionResultResponse>>(
|
||||
`${BASE_URL}/batch/balance`,
|
||||
providerIds
|
||||
)
|
||||
return response.data
|
||||
}
|
||||
|
||||
/** 验证认证请求 */
|
||||
export interface VerifyAuthRequest {
|
||||
architecture_id: string
|
||||
base_url: string
|
||||
connector: ConnectorConfigRequest
|
||||
actions?: Record<string, ActionConfigRequest>
|
||||
schedule?: Record<string, string>
|
||||
}
|
||||
|
||||
/** 验证认证响应 */
|
||||
export interface VerifyAuthResponse {
|
||||
success: boolean
|
||||
message?: string
|
||||
data?: {
|
||||
username?: string
|
||||
display_name?: string
|
||||
email?: string
|
||||
quota?: number
|
||||
used_quota?: number
|
||||
request_count?: number
|
||||
extra?: Record<string, any>
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证 Provider 认证配置
|
||||
* 在保存前测试认证是否有效
|
||||
*/
|
||||
export async function verifyProviderAuth(
|
||||
providerId: string,
|
||||
config: VerifyAuthRequest
|
||||
): Promise<VerifyAuthResponse> {
|
||||
const response = await client.post<VerifyAuthResponse>(
|
||||
`${BASE_URL}/providers/${providerId}/verify`,
|
||||
config
|
||||
)
|
||||
return response.data
|
||||
}
|
||||
Reference in New Issue
Block a user