"use client"; import { Database, Edit, Loader2, Plus, RefreshCw, Save, Search, Trash2, Upload, } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Switch } from "@/components/ui/switch"; import { Textarea } from "@/components/ui/textarea"; import type { ThreeDModelAliasEntry } from "@/lib/model3d/model-alias-config"; import { cn, formatBeijingTime } from "@/lib/utils"; import type { AdminAiProvider, LocalAiModel3dSectionsProps, } from "../../_lib/types"; import { LocalAiGroupHeading, LocalAiSectionShell, LocalAiSectionSummary, } from "../local-ai-section-shell"; export function LocalAiModel3dSections({ tripo3dConfig, setTripo3dConfig, tripoProviders, filteredTripoProviders, enabledTripoProviderCount, tripoProviderSearch, setTripoProviderSearch, tripoProviderBusyId, worldlabs3dConfig, setWorldlabs3dConfig, worldlabsKeyPoolConfig, setWorldlabsKeyPoolConfig, worldlabsApiKeysDraft, setWorldlabsApiKeysDraft, worldlabsProviders, filteredWorldlabsProviders, enabledWorldlabsProviderCount, worldlabsProviderSearch, setWorldlabsProviderSearch, worldlabsProviderBusyId, threeDModelAliasConfig, setThreeDModelAliasConfig, kittycadCadConfig, setKittycadCadConfig, isTestingKittycadCad, isLocalAiSectionExpanded, toggleLocalAiSection, getProviderDefaultBaseUrl, handleEditTripoPoolProvider, handleToggleTripoPoolProvider, handleDeleteProvider, handleSaveTripo3dConfig, handleAddTripo3dPoolKey, handleImportWorldlabs3dPoolKeys, handleAddWorldlabs3dPoolKey, handleEditWorldlabsPoolProvider, handleToggleWorldlabsPoolProvider, handleSaveWorldlabs3dConfig, handleAddThreeDModelAliasEntry, handleThreeDModelAliasEntryChange, handleRemoveThreeDModelAliasEntry, handleResetThreeDModelAliasConfig, handleSaveThreeDModelAliasConfig, handleTestKittycadCadConfig, handleSaveKittycadCadConfig, }: LocalAiModel3dSectionsProps) { return ( <> 配置无限画布 3D 生成功能使用的 Tripo3D 接口,保存后写入数据库 AI 提供商配置。 } expanded={isLocalAiSectionExpanded("tripo3d")} id="local-ai-section-tripo3d" onToggle={() => toggleLocalAiSection("tripo3d")} summary={ 0 ? "enabled" : "warning", }, { label: `${enabledTripoProviderCount} 个启用中`, tone: enabledTripoProviderCount > 0 ? "enabled" : "warning", }, ]} /> } title="Tripo3D API 配置" >
setTripo3dConfig({ ...tripo3dConfig, name: e.target.value }) } placeholder="Tripo3D" value={tripo3dConfig.name} />
setTripo3dConfig({ ...tripo3dConfig, baseUrl: e.target.value, }) } placeholder={getProviderDefaultBaseUrl("tripo-3d")} value={tripo3dConfig.baseUrl} />
默认:{getProviderDefaultBaseUrl("tripo-3d")}
setTripo3dConfig({ ...tripo3dConfig, apiKey: e.target.value, }) } placeholder={ tripo3dConfig.providerId ? "留空则不修改当前 Key" : "请输入 Tripo3D API Key" } type="password" value={tripo3dConfig.apiKey} />
Tripo3D Key 池
当前共 {tripoProviders.length} 个 Key,已启用{" "} {enabledTripoProviderCount} 个。生成任务会轮询使用可用 Key。
setTripoProviderSearch(e.target.value)} placeholder="搜索名称 / Key / API 地址" value={tripoProviderSearch} />
{filteredTripoProviders.length ? ( filteredTripoProviders.map((provider: AdminAiProvider) => (
{provider.name}
{provider.isEnabled ? "已启用" : "已禁用"}
Key: {provider.apiKey}
API: {provider.baseUrl}
创建时间: {formatBeijingTime(provider.createdAt)}
void handleToggleTripoPoolProvider(provider, checked) } /> {provider.isEnabled ? "启用中" : "已停用"}
)) ) : (
{tripoProviders.length ? "没有匹配到符合筛选条件的 Tripo3D Key。" : "当前还没有导入任何 Tripo3D Key。"}
)}
关闭后 3D 生成接口将不可用
setTripo3dConfig({ ...tripo3dConfig, isEnabled: checked }) } /> {tripo3dConfig.isEnabled ? "已开启" : "已关闭"}
配置无限画布 3D 世界模式使用的 World Labs 接口,保存后写入数据库 AI 提供商配置。 } expanded={isLocalAiSectionExpanded("worldlabs3d")} id="local-ai-section-worldlabs3d" onToggle={() => toggleLocalAiSection("worldlabs3d")} summary={ 0 ? "enabled" : "warning", }, { label: `${enabledWorldlabsProviderCount} 个启用中`, tone: enabledWorldlabsProviderCount > 0 ? "enabled" : "warning", }, ]} /> } title="World Labs API 配置" >
setWorldlabs3dConfig({ ...worldlabs3dConfig, name: e.target.value, }) } placeholder="World Labs" value={worldlabs3dConfig.name} />
setWorldlabs3dConfig({ ...worldlabs3dConfig, baseUrl: e.target.value, }) } placeholder={getProviderDefaultBaseUrl("worldlabs-3d")} value={worldlabs3dConfig.baseUrl} />
默认:{getProviderDefaultBaseUrl("worldlabs-3d")}
setWorldlabs3dConfig({ ...worldlabs3dConfig, apiKey: e.target.value, }) } placeholder={ worldlabs3dConfig.providerId ? "留空则不修改当前 Key" : "请输入 World Labs API Key" } type="password" value={worldlabs3dConfig.apiKey} />
setWorldlabsKeyPoolConfig((prev) => ({ ...prev, importToken: e.target.value, })) } placeholder="供 /api/worldlabs/key-pool/import 调用的 Bearer Token" type="password" value={worldlabsKeyPoolConfig.importToken} />
用于 Python 脚本通过 /api/worldlabs/key-pool/import 批量导入新 Key;后台管理员在本页面导入时不需要额外填写令牌。
每行一个 World Labs API Key,导入时会自动跳过已存在或重复的 Key。