From 801d61f9a6b2e0796f51d32c81475748cbcc9c36 Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 19 Feb 2026 00:12:27 +0800 Subject: [PATCH] fix(admin): auto-fill provider base url and block email autofill --- .../settings/admin-settings-client.tsx | 96 ++++++++++++------- 1 file changed, 62 insertions(+), 34 deletions(-) diff --git a/app/(admin)/settings/admin-settings-client.tsx b/app/(admin)/settings/admin-settings-client.tsx index 4c5cc7a7b..58b8636e0 100644 --- a/app/(admin)/settings/admin-settings-client.tsx +++ b/app/(admin)/settings/admin-settings-client.tsx @@ -379,6 +379,32 @@ const PROVIDER_TYPES = [ { value: "fal-video", label: "FAL 视频生成" }, ]; +const PROVIDER_DEFAULT_BASE_URL: Record = { + alibaba: "https://dashscope.aliyuncs.com/compatible-mode/v1", + "alibaba-image": + "https://dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation", + "ruxa-image": "https://api.ruxa.ai", + "fal-image": "https://fal.run", + "fal-video": "https://fal.run", + zhipu: "https://open.bigmodel.cn/api/paas/v4", + "volcano-multimodal": "https://ark.cn-beijing.volces.com/api/v3", + openai: "https://api.openai.com/v1", + "huanke-gemini": "https://api.huandutech.com/v1", + "qianwen-video": "https://dashscope.aliyuncs.com/api/v1/services/aigc/video-generation", + "doubao-video": "https://ark.cn-beijing.volces.com/api/v3", + "volcano-vision": "https://ark.cn-beijing.volces.com", + "volcano-video": "https://ark.cn-beijing.volces.com/api/v3", +}; + +function getProviderDefaultBaseUrl(type?: string) { + if (!type) return ""; + return PROVIDER_DEFAULT_BASE_URL[type] || ""; +} + +function isHttpUrlLike(value: string) { + return /^https?:\/\//i.test(value.trim()); +} + export function AdminSettingsClient() { const [activeTab, setActiveTab] = useState("users"); @@ -1693,7 +1719,7 @@ export function AdminSettingsClient() { id: "", name: "", type: "openai", - baseUrl: "", + baseUrl: getProviderDefaultBaseUrl("openai"), apiKey: "", isEnabled: true, }); @@ -1705,8 +1731,20 @@ export function AdminSettingsClient() { const method = editingProvider ? "PUT" : "POST"; const isNewProvider = !editingProvider; const isVolcanoVideo = providerForm.type === 'volcano-video'; + const defaultBaseUrl = getProviderDefaultBaseUrl(providerForm.type); + const normalizedBaseUrl = providerForm.baseUrl.trim(); let requestData: any = editingProvider ? { ...providerForm, id: editingProvider } : providerForm; + + if ( + defaultBaseUrl && + (!normalizedBaseUrl || !isHttpUrlLike(normalizedBaseUrl) || normalizedBaseUrl.includes("@")) + ) { + requestData.baseUrl = defaultBaseUrl; + } else { + requestData.baseUrl = normalizedBaseUrl; + } + if (editingProvider && !providerForm.apiKey) { const { apiKey, ...restData } = requestData; requestData = restData; @@ -5434,24 +5472,25 @@ export function AdminSettingsClient() { setProviderForm({ ...providerForm, baseUrl: e.target.value })} - placeholder={ - providerForm.type === "ruxa-image" - ? "https://api.ruxa.ai" - : providerForm.type === "fal-image" - ? "https://fal.run" - : providerForm.type === "fal-video" - ? "https://fal.run" - : providerForm.type === "doubao-video" - ? "https://ark.cn-beijing.volces.com/api/v3" - : providerForm.type === "zhipu" - ? "https://open.bigmodel.cn/api/paas/v4" - : providerForm.type === "volcano-multimodal" - ? "https://ark.cn-beijing.volces.com/api/v3" - : "https://api.openai.com/v1" - } + autoComplete="off" + inputMode="url" + placeholder={getProviderDefaultBaseUrl(providerForm.type) || "https://api.openai.com/v1"} />
@@ -5494,6 +5521,7 @@ export function AdminSettingsClient() { type={showApiKey ? "text" : "password"} value={providerForm.apiKey} onChange={(e) => setProviderForm({ ...providerForm, apiKey: e.target.value })} + autoComplete="new-password" placeholder={editingProvider ? "留空则不修改" : "sk-..."} />