From 6867f3e1e6a70a3d0fb0c987fbe86f12558e0198 Mon Sep 17 00:00:00 2001 From: HouYunFei <1844025705@qq.com> Date: Sat, 30 May 2026 13:08:43 +0800 Subject: [PATCH] =?UTF-8?q?feat(config):=20=E6=94=AF=E6=8C=81=E9=80=9A?= =?UTF-8?q?=E8=BF=87URL=E5=8F=82=E6=95=B0=E8=87=AA=E5=8A=A8=E9=85=8D?= =?UTF-8?q?=E7=BD=AEAPI=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增通过URL查询参数baseUrl/baseurl和apiKey/apikey自动填充配置的功能 - 实现读取参数后从地址栏自动移除相关参数的安全机制 - 添加后台是否允许自定义渠道的检查逻辑 - 集成Ant Design的消息提示和对话框组件用于用户反馈 - 更新文档说明New API自动配置的使用方法和参数格式 - 优化配置初始化流程以处理外部软件跳转场景 --- CHANGELOG.md | 4 +++ README.md | 12 ++++++- docs/pending-test.md | 1 + .../components/layout/client-root-init.tsx | 32 ++++++++++++++++++- 4 files changed, 47 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7af8e12..4d507a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased ++ [新增] 支持New API跳转并自动填入Base URL和API Key配置。 + +## v0.1.0 - 2026-05-30 + ## v0.1.0 - 2026-05-26 + [优化] 优化我的画布、我的素材导出功能 diff --git a/README.md b/README.md index f7553b8..077c2cc 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,17 @@ docker compose -f docker-compose.local.yml up -d --build 如需要拉取提示词,可前往:`http://localhost:3000/admin/prompts` +## New API 自动配置 + +如果使用 New API,可在 `系统设置 -> 聊天方式 -> 添加聊天设置` 中填入: + +```text +https://infinite-canvas-cpco.onrender.com?apiKey={key}&baseUrl={address} +``` + +跳转后会自动打开配置弹窗并填入 API Key 和 Base URL。 +如果自己部署了,可以把 `https://infinite-canvas-cpco.onrender.com` 替换成你部署的地址。 + ## 效果展示 @@ -89,7 +100,6 @@ docker compose -f docker-compose.local.yml up -d --build 本项目使用 GNU Affero General Public License v3.0,见 [LICENSE](LICENSE)。 - ## Star History diff --git a/docs/pending-test.md b/docs/pending-test.md index 5867f38..989c14d 100644 --- a/docs/pending-test.md +++ b/docs/pending-test.md @@ -1,5 +1,6 @@ # 待测试 +- 外部软件可通过 URL 查询参数 `baseUrl`/`baseurl` 和 `apiKey`/`apikey` 跳转到前端;读取后会从地址栏移除这些参数,后台允许自定义渠道时会自动切到自定义渠道、填入配置并打开配置弹窗,未允许时会打开配置弹窗并提示无法导入。 - 画布项目导出改为下载 `.zip` 压缩包,包内包含 `projects.json` 和当前画布引用到的本地图片、视频文件,避免只导出 JSON 时丢失媒体内容。 - 画布库支持多选后一键导出多个画布项目,导出的压缩包可一次恢复多个项目。 - 画布项目导入改为读取新版 `.zip` 压缩包,会先按 `projects.json` 中的文件映射恢复图片、视频到本地存储,再插入画布项目,导入成功后仍停留在画布库。 diff --git a/web/src/components/layout/client-root-init.tsx b/web/src/components/layout/client-root-init.tsx index f4a8131..3523ee4 100644 --- a/web/src/components/layout/client-root-init.tsx +++ b/web/src/components/layout/client-root-init.tsx @@ -1,16 +1,22 @@ "use client"; import type { ReactNode } from "react"; -import { useEffect } from "react"; +import { useEffect, useRef } from "react"; import { usePathname } from "next/navigation"; +import { App } from "antd"; import { useConfigStore } from "@/stores/use-config-store"; import { useUserStore } from "@/stores/use-user-store"; export function ClientRootInit({ children }: { children: ReactNode }) { + const { message } = App.useApp(); + const handledConfigParams = useRef(false); const pathname = usePathname(); const hydrateUser = useUserStore((state) => state.hydrateUser); const loadPublicSettings = useConfigStore((state) => state.loadPublicSettings); + const publicSettings = useConfigStore((state) => state.publicSettings); + const updateConfig = useConfigStore((state) => state.updateConfig); + const openConfigDialog = useConfigStore((state) => state.openConfigDialog); const isLoginPage = pathname === "/login" || pathname === "/admin/login"; useEffect(() => { @@ -21,5 +27,29 @@ export function ClientRootInit({ children }: { children: ReactNode }) { if (!isLoginPage) void hydrateUser(); }, [hydrateUser, isLoginPage]); + useEffect(() => { + if (handledConfigParams.current) return; + const searchParams = new URLSearchParams(window.location.search); + const baseUrl = searchParams.get("baseUrl") || searchParams.get("baseurl"); + const apiKey = searchParams.get("apiKey") || searchParams.get("apikey"); + if (!baseUrl && !apiKey) return; + if (!publicSettings) return; + handledConfigParams.current = true; + searchParams.delete("baseUrl"); + searchParams.delete("baseurl"); + searchParams.delete("apiKey"); + searchParams.delete("apikey"); + window.history.replaceState(null, "", `${window.location.pathname}${searchParams.size ? `?${searchParams}` : ""}${window.location.hash}`); + if (!publicSettings.modelChannel.allowCustomChannel) { + openConfigDialog(false); + message.error("后台未允许用户自定义渠道,请联系管理员进行配置"); + return; + } + updateConfig("channelMode", "local"); + if (baseUrl) updateConfig("baseUrl", baseUrl); + if (apiKey) updateConfig("apiKey", apiKey); + openConfigDialog(false); + }, [message, openConfigDialog, publicSettings, updateConfig]); + return <>{children}; }