diff --git a/app/(admin)/settings/admin-settings-client.tsx b/app/(admin)/settings/admin-settings-client.tsx index db207a13b..a03444fea 100644 --- a/app/(admin)/settings/admin-settings-client.tsx +++ b/app/(admin)/settings/admin-settings-client.tsx @@ -479,6 +479,25 @@ const PROVIDER_DEFAULT_BASE_URL: Record = { "volcano-video": "https://ark.cn-beijing.volces.com/api/v3", }; +const LEMON_OPENAI_BASE_URL = "https://new.lemonapi.site/v1"; + +const LEMON_PROVIDER_PRESET = { + name: "LemonAPI Gemini", + type: "openai" as const, + baseUrl: LEMON_OPENAI_BASE_URL, +}; + +const LEMON_MODEL_PRESETS = [ + { + modelId: "[L]gemini-3.1-pro-preview", + displayName: "Gemini-3.1-pro-preview", + supportsVision: true, + supportsImageGen: false, + isMultimodal: true, + description: "LemonAPI OpenAI兼容 Gemini 3.1 Pro 预设模型", + }, +]; + function getProviderDefaultBaseUrl(type?: string) { if (!type) return ""; return PROVIDER_DEFAULT_BASE_URL[type] || ""; @@ -488,6 +507,10 @@ function isHttpUrlLike(value: string) { return /^https?:\/\//i.test(value.trim()); } +function isLemonApiBaseUrl(value?: string | null) { + return String(value || "").trim().replace(/\/+$/, "") === LEMON_OPENAI_BASE_URL; +} + export function AdminSettingsClient() { const [activeTab, setActiveTab] = useState("users"); @@ -2249,6 +2272,9 @@ export function AdminSettingsClient() { const method = editingProvider ? "PUT" : "POST"; const isNewProvider = !editingProvider; const isVolcanoVideo = providerForm.type === 'volcano-video'; + const isLemonProvider = + providerForm.type === "openai" && + isLemonApiBaseUrl(providerForm.baseUrl || getProviderDefaultBaseUrl(providerForm.type)); const defaultBaseUrl = getProviderDefaultBaseUrl(providerForm.type); const normalizedBaseUrl = providerForm.baseUrl.trim(); @@ -2306,6 +2332,15 @@ export function AdminSettingsClient() { toast.warning('预设模型添加失败,请手动点击"快速添加预设模型"按钮'); } } + + if (isNewProvider && isLemonProvider && providerId) { + try { + await handleQuickAddLemonModels(providerId); + } catch (modelError) { + console.error("[Auto Add Lemon Models] Error:", modelError); + toast.warning('LemonAPI 预设模型添加失败,请手动点击"快速添加 Gemini 预设模型"按钮'); + } + } } catch (error) { toast.error("保存提供商失败"); } @@ -2412,6 +2447,69 @@ export function AdminSettingsClient() { } }; + const handleUseLemonProviderPreset = () => { + setProviderForm({ + id: "", + name: LEMON_PROVIDER_PRESET.name, + type: LEMON_PROVIDER_PRESET.type, + baseUrl: LEMON_PROVIDER_PRESET.baseUrl, + apiKey: "", + isEnabled: true, + }); + setEditingProvider(null); + setShowProviderDialog(true); + }; + + const handleQuickAddLemonModels = async (providerId: string) => { + try { + toast.info("正在添加 LemonAPI Gemini 预设模型..."); + + let addedCount = 0; + let duplicateCount = 0; + + for (const preset of LEMON_MODEL_PRESETS) { + const response = await fetch("/api/admin/ai-models", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + providerId, + modelId: preset.modelId, + displayName: preset.displayName, + description: preset.description, + supportsVision: preset.supportsVision, + supportsImageGen: preset.supportsImageGen, + isEnabled: true, + isHidden: false, + isDefault: false, + isAgentModel: false, + agentCodingModelId: "", + isMultimodal: preset.isMultimodal, + sortOrder: 0, + }), + }); + + if (response.ok) { + addedCount += 1; + continue; + } + + duplicateCount += 1; + } + + if (addedCount > 0) { + toast.success(`成功添加 ${addedCount} 个 LemonAPI 预设模型`); + mutateModels(); + } + + if (addedCount === 0 && duplicateCount > 0) { + toast.warning("LemonAPI 预设模型可能已存在"); + } + } catch (error) { + console.error("[Quick Add Lemon Models] Error:", error); + toast.error("添加 LemonAPI 预设模型失败"); + } + }; + // --- AI 模型逻辑 --- const resetModelForm = () => { setModelForm({ @@ -6443,17 +6541,21 @@ export function AdminSettingsClient() { -
+
AI 提供商 配置 AI 服务提供商
- - - - - + + + + + {editingProvider ? "编辑提供商" : "添加提供商"} @@ -6544,8 +6646,9 @@ export function AdminSettingsClient() { - - + + +
@@ -6570,6 +6673,17 @@ export function AdminSettingsClient() { 快速添加预设模型 )} + {provider.type === "openai" && isLemonApiBaseUrl(provider.baseUrl) && ( + + )}