mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-04-05 10:36:40 +08:00
feat(openclaw): add additive mode frontend support
- Add getOpenClawLiveProviderIds() API for querying live config - Update ProviderList to query OpenClaw live IDs - Rename isOpenCodeMode to isAdditiveMode (covers OpenCode + OpenClaw) - Update ProviderCard shouldAutoQuery and isActiveProvider logic - Update App.tsx onRemoveFromConfig and invalidateQueries for OpenClaw
This commit is contained in:
17
src/App.tsx
17
src/App.tsx
@@ -425,10 +425,19 @@ function App() {
|
|||||||
const { provider, action } = confirmAction;
|
const { provider, action } = confirmAction;
|
||||||
|
|
||||||
if (action === "remove") {
|
if (action === "remove") {
|
||||||
|
// Remove from live config only (for additive mode apps like OpenCode/OpenClaw)
|
||||||
|
// Does NOT delete from database - provider remains in the list
|
||||||
await providersApi.removeFromLiveConfig(provider.id, activeApp);
|
await providersApi.removeFromLiveConfig(provider.id, activeApp);
|
||||||
await queryClient.invalidateQueries({
|
// Invalidate queries to refresh the isInConfig state
|
||||||
queryKey: ["opencodeLiveProviderIds"],
|
if (activeApp === "opencode") {
|
||||||
});
|
await queryClient.invalidateQueries({
|
||||||
|
queryKey: ["opencodeLiveProviderIds"],
|
||||||
|
});
|
||||||
|
} else if (activeApp === "openclaw") {
|
||||||
|
await queryClient.invalidateQueries({
|
||||||
|
queryKey: ["openclawLiveProviderIds"],
|
||||||
|
});
|
||||||
|
}
|
||||||
toast.success(
|
toast.success(
|
||||||
t("notifications.removeFromConfigSuccess", {
|
t("notifications.removeFromConfigSuccess", {
|
||||||
defaultValue: "已从配置移除",
|
defaultValue: "已从配置移除",
|
||||||
@@ -642,7 +651,7 @@ function App() {
|
|||||||
setConfirmAction({ provider, action: "delete" })
|
setConfirmAction({ provider, action: "delete" })
|
||||||
}
|
}
|
||||||
onRemoveFromConfig={
|
onRemoveFromConfig={
|
||||||
activeApp === "opencode"
|
activeApp === "opencode" || activeApp === "openclaw"
|
||||||
? (provider) =>
|
? (provider) =>
|
||||||
setConfirmAction({ provider, action: "remove" })
|
setConfirmAction({ provider, action: "remove" })
|
||||||
: undefined
|
: undefined
|
||||||
|
|||||||
@@ -62,10 +62,13 @@ export function ProviderActions({
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const iconButtonClass = "h-8 w-8 p-1";
|
const iconButtonClass = "h-8 w-8 p-1";
|
||||||
|
|
||||||
const isOpenCodeMode = appId === "opencode" && !isOmo;
|
// 累加模式应用(OpenCode 非 OMO 和 OpenClaw)
|
||||||
|
const isAdditiveMode =
|
||||||
|
(appId === "opencode" && !isOmo) || appId === "openclaw";
|
||||||
|
|
||||||
|
// 故障转移模式下的按钮逻辑(累加模式和 OMO 应用不支持故障转移)
|
||||||
const isFailoverMode =
|
const isFailoverMode =
|
||||||
!isOpenCodeMode && !isOmo && isAutoFailoverEnabled && onToggleFailover;
|
!isAdditiveMode && !isOmo && isAutoFailoverEnabled && onToggleFailover;
|
||||||
|
|
||||||
const handleMainButtonClick = () => {
|
const handleMainButtonClick = () => {
|
||||||
if (isOmo) {
|
if (isOmo) {
|
||||||
@@ -74,7 +77,8 @@ export function ProviderActions({
|
|||||||
} else {
|
} else {
|
||||||
onSwitch();
|
onSwitch();
|
||||||
}
|
}
|
||||||
} else if (isOpenCodeMode) {
|
} else if (isAdditiveMode) {
|
||||||
|
// 累加模式:切换配置状态(添加/移除)
|
||||||
if (isInConfig) {
|
if (isInConfig) {
|
||||||
if (onRemoveFromConfig) {
|
if (onRemoveFromConfig) {
|
||||||
onRemoveFromConfig();
|
onRemoveFromConfig();
|
||||||
@@ -112,7 +116,8 @@ export function ProviderActions({
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isOpenCodeMode) {
|
// 累加模式(OpenCode 非 OMO / OpenClaw)
|
||||||
|
if (isAdditiveMode) {
|
||||||
if (isInConfig) {
|
if (isInConfig) {
|
||||||
return {
|
return {
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -180,7 +185,7 @@ export function ProviderActions({
|
|||||||
|
|
||||||
const canDelete = isOmo
|
const canDelete = isOmo
|
||||||
? !(isLastOmo && isCurrent)
|
? !(isLastOmo && isCurrent)
|
||||||
: isOpenCodeMode
|
: isAdditiveMode
|
||||||
? true
|
? true
|
||||||
: !isCurrent;
|
: !isCurrent;
|
||||||
|
|
||||||
|
|||||||
@@ -133,7 +133,10 @@ export function ProviderCard({
|
|||||||
|
|
||||||
const usageEnabled = provider.meta?.usage_script?.enabled ?? false;
|
const usageEnabled = provider.meta?.usage_script?.enabled ?? false;
|
||||||
|
|
||||||
const shouldAutoQuery = appId === "opencode" ? isInConfig : isCurrent;
|
// 获取用量数据以判断是否有多套餐
|
||||||
|
// 累加模式应用(OpenCode/OpenClaw):使用 isInConfig 代替 isCurrent
|
||||||
|
const shouldAutoQuery =
|
||||||
|
appId === "opencode" || appId === "openclaw" ? isInConfig : isCurrent;
|
||||||
const autoQueryInterval = shouldAutoQuery
|
const autoQueryInterval = shouldAutoQuery
|
||||||
? provider.meta?.usage_script?.autoQueryInterval || 0
|
? provider.meta?.usage_script?.autoQueryInterval || 0
|
||||||
: 0;
|
: 0;
|
||||||
@@ -176,9 +179,14 @@ export function ProviderCard({
|
|||||||
onOpenWebsite(displayUrl);
|
onOpenWebsite(displayUrl);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 判断是否是"当前使用中"的供应商
|
||||||
|
// - OMO 供应商:使用 isCurrent
|
||||||
|
// - 累加模式应用(OpenCode 非 OMO / OpenClaw):不存在"当前"概念,始终返回 false
|
||||||
|
// - 故障转移模式:代理实际使用的供应商(activeProviderId)
|
||||||
|
// - 普通模式:isCurrent
|
||||||
const isActiveProvider = isOmo
|
const isActiveProvider = isOmo
|
||||||
? isCurrent
|
? isCurrent
|
||||||
: appId === "opencode"
|
: appId === "opencode" || appId === "openclaw"
|
||||||
? false
|
? false
|
||||||
: isAutoFailoverEnabled
|
: isAutoFailoverEnabled
|
||||||
? activeProviderId === provider.id
|
? activeProviderId === provider.id
|
||||||
|
|||||||
@@ -84,12 +84,25 @@ export function ProviderList({
|
|||||||
enabled: appId === "opencode",
|
enabled: appId === "opencode",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// OpenClaw: 查询 live 配置中的供应商 ID 列表,用于判断 isInConfig
|
||||||
|
const { data: openclawLiveIds } = useQuery({
|
||||||
|
queryKey: ["openclawLiveProviderIds"],
|
||||||
|
queryFn: () => providersApi.getOpenClawLiveProviderIds(),
|
||||||
|
enabled: appId === "openclaw",
|
||||||
|
});
|
||||||
|
|
||||||
|
// 判断供应商是否已添加到配置(累加模式应用:OpenCode/OpenClaw)
|
||||||
const isProviderInConfig = useCallback(
|
const isProviderInConfig = useCallback(
|
||||||
(providerId: string): boolean => {
|
(providerId: string): boolean => {
|
||||||
if (appId !== "opencode") return true; // 非 OpenCode 应用始终返回 true
|
if (appId === "opencode") {
|
||||||
return opencodeLiveIds?.includes(providerId) ?? false;
|
return opencodeLiveIds?.includes(providerId) ?? false;
|
||||||
|
}
|
||||||
|
if (appId === "openclaw") {
|
||||||
|
return openclawLiveIds?.includes(providerId) ?? false;
|
||||||
|
}
|
||||||
|
return true; // 其他应用始终返回 true
|
||||||
},
|
},
|
||||||
[appId, opencodeLiveIds],
|
[appId, opencodeLiveIds, openclawLiveIds],
|
||||||
);
|
);
|
||||||
|
|
||||||
const { data: isAutoFailoverEnabled } = useAutoFailoverEnabled(appId);
|
const { data: isAutoFailoverEnabled } = useAutoFailoverEnabled(appId);
|
||||||
|
|||||||
@@ -98,6 +98,14 @@ export const providersApi = {
|
|||||||
async getOpenCodeLiveProviderIds(): Promise<string[]> {
|
async getOpenCodeLiveProviderIds(): Promise<string[]> {
|
||||||
return await invoke("get_opencode_live_provider_ids");
|
return await invoke("get_opencode_live_provider_ids");
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 OpenClaw live 配置中的供应商 ID 列表
|
||||||
|
* 用于前端判断供应商是否已添加到 openclaw.json
|
||||||
|
*/
|
||||||
|
async getOpenClawLiveProviderIds(): Promise<string[]> {
|
||||||
|
return await invoke("get_openclaw_live_provider_ids");
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|||||||
Reference in New Issue
Block a user