feat(proxy): implement independent failover queue management

Add a new failover queue system that operates independently from provider
sortIndex, allowing users to configure failover order per app type.

Backend changes:
- Add failover_queue table to schema.rs for persistent storage
- Create dao/failover.rs with CRUD operations for queue management
- Add Tauri commands for queue operations (get, add, remove, reorder, toggle)
- Refactor provider_router.rs select_providers() to use failover queue:
  - Current provider always takes first priority
  - Queue providers ordered by queue_order as fallback
  - Only providers with open circuit breakers are included

Frontend changes:
- Add FailoverQueueItem type to proxy.ts
- Extend failover.ts API with queue management methods
- Add React Query hooks for queue data fetching and mutations
- Create FailoverQueueManager component with drag-and-drop reordering
- Integrate queue management into SettingsPage under "Auto Failover"
- Add i18n translations for zh and en locales
This commit is contained in:
Jason
2025-12-12 16:13:07 +08:00
parent c42a0dccaf
commit 5d424b1383
15 changed files with 1198 additions and 47 deletions
+50
View File
@@ -3,6 +3,7 @@ import type {
ProviderHealth,
CircuitBreakerConfig,
CircuitBreakerStats,
FailoverQueueItem,
} from "@/types/proxy";
export interface Provider {
@@ -21,6 +22,8 @@ export interface Provider {
}
export const failoverApi = {
// ========== 旧版代理目标 API(保留向后兼容)==========
// 获取代理目标列表
async getProxyTargets(appType: string): Promise<Provider[]> {
return invoke("get_proxy_targets", { appType });
@@ -35,6 +38,8 @@ export const failoverApi = {
return invoke("set_proxy_target", { providerId, appType, enabled });
},
// ========== 熔断器 API ==========
// 获取供应商健康状态
async getProviderHealth(
providerId: string,
@@ -70,4 +75,49 @@ export const failoverApi = {
): Promise<CircuitBreakerStats | null> {
return invoke("get_circuit_breaker_stats", { providerId, appType });
},
// ========== 故障转移队列 API(新) ==========
// 获取故障转移队列
async getFailoverQueue(appType: string): Promise<FailoverQueueItem[]> {
return invoke("get_failover_queue", { appType });
},
// 获取可添加到队列的供应商(不在队列中的)
async getAvailableProvidersForFailover(appType: string): Promise<Provider[]> {
return invoke("get_available_providers_for_failover", { appType });
},
// 添加供应商到故障转移队列
async addToFailoverQueue(
appType: string,
providerId: string,
): Promise<void> {
return invoke("add_to_failover_queue", { appType, providerId });
},
// 从故障转移队列移除供应商
async removeFromFailoverQueue(
appType: string,
providerId: string,
): Promise<void> {
return invoke("remove_from_failover_queue", { appType, providerId });
},
// 重新排序故障转移队列
async reorderFailoverQueue(
appType: string,
providerIds: string[],
): Promise<void> {
return invoke("reorder_failover_queue", { appType, providerIds });
},
// 设置故障转移队列项的启用状态
async setFailoverItemEnabled(
appType: string,
providerId: string,
enabled: boolean,
): Promise<void> {
return invoke("set_failover_item_enabled", { appType, providerId, enabled });
},
};