mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-28 08:44:41 +08:00
fix(proxy): stabilize live takeover and provider editing
- Skip live writes when takeover is active and proxy is running - Refresh live backups from provider edits during takeover - Sync live tokens to DB without clobbering real keys with placeholders - Avoid injecting extra placeholder keys into Claude live env - Reapply takeover after proxy listen address/port changes - In takeover mode, edit dialog uses DB config and keeps API key state in sync
This commit is contained in:
@@ -578,6 +578,7 @@ function App() {
|
||||
}}
|
||||
onSubmit={handleEditProvider}
|
||||
appId={activeApp}
|
||||
isProxyTakeover={isProxyRunning && isTakeoverActive}
|
||||
/>
|
||||
|
||||
{usageProvider && (
|
||||
|
||||
@@ -16,6 +16,7 @@ interface EditProviderDialogProps {
|
||||
onOpenChange: (open: boolean) => void;
|
||||
onSubmit: (provider: Provider) => Promise<void> | void;
|
||||
appId: AppId;
|
||||
isProxyTakeover?: boolean; // 代理接管模式下不读取 live(避免显示被接管后的代理配置)
|
||||
}
|
||||
|
||||
export function EditProviderDialog({
|
||||
@@ -24,6 +25,7 @@ export function EditProviderDialog({
|
||||
onOpenChange,
|
||||
onSubmit,
|
||||
appId,
|
||||
isProxyTakeover = false,
|
||||
}: EditProviderDialogProps) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
@@ -50,6 +52,16 @@ export function EditProviderDialog({
|
||||
return;
|
||||
}
|
||||
|
||||
// 代理接管模式:Live 配置已被代理改写,读取 live 会导致编辑界面展示代理地址/占位符等内容
|
||||
// 因此直接回退到 SSOT(数据库)配置,避免用户困惑与误保存
|
||||
if (isProxyTakeover) {
|
||||
if (!cancelled) {
|
||||
setLiveSettings(null);
|
||||
setHasLoadedLive(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const currentId = await providersApi.getCurrent(appId);
|
||||
if (currentId && provider.id === currentId) {
|
||||
@@ -82,7 +94,7 @@ export function EditProviderDialog({
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [open, provider?.id, appId, hasLoadedLive]); // 只依赖 provider.id,不依赖整个 provider 对象
|
||||
}, [open, provider?.id, appId, hasLoadedLive, isProxyTakeover]); // 只依赖 provider.id,不依赖整个 provider 对象
|
||||
|
||||
const initialSettingsConfig = useMemo(() => {
|
||||
return (liveSettings ?? provider?.settingsConfig ?? {}) as Record<
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useState, useCallback } from "react";
|
||||
import { useEffect, useState, useCallback } from "react";
|
||||
import type { ProviderCategory } from "@/types";
|
||||
import {
|
||||
getApiKeyFromConfig,
|
||||
@@ -32,6 +32,28 @@ export function useApiKeyState({
|
||||
return "";
|
||||
});
|
||||
|
||||
// 当外部通过 form.reset / 读取 live 等方式更新配置时,同步回 API Key 状态
|
||||
// - 仅在 JSON 可解析时同步,避免用户编辑 JSON 过程中因临时无效导致输入框闪烁
|
||||
useEffect(() => {
|
||||
if (!initialConfig) return;
|
||||
|
||||
try {
|
||||
JSON.parse(initialConfig);
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
|
||||
// 仅当配置确实包含 API Key 字段时才同步(避免无意清空用户正在输入的 key)
|
||||
if (!hasApiKeyField(initialConfig, appType)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const extracted = getApiKeyFromConfig(initialConfig, appType);
|
||||
if (extracted !== apiKey) {
|
||||
setApiKey(extracted);
|
||||
}
|
||||
}, [initialConfig, appType, apiKey]);
|
||||
|
||||
const handleApiKeyChange = useCallback(
|
||||
(key: string) => {
|
||||
setApiKey(key);
|
||||
|
||||
Reference in New Issue
Block a user