From d1582f33e83e8521f7e60cdf6bfc2ad7129ee8e8 Mon Sep 17 00:00:00 2001 From: 134 Date: Thu, 20 Aug 2026 22:12:33 +0800 Subject: [PATCH] fix(bbyy): isolate production branding from E2E defaults --- .../settings/admin-settings-client.tsx | 22 ++++++------ app/api/site-settings/route.ts | 34 +++++++++---------- components/canvas/CanvasChatPanel.tsx | 2 +- components/home/lovart-home.tsx | 2 +- components/home/lovart/utils.ts | 2 +- components/layout/brand-top-bar.tsx | 2 +- components/style-pro/StyleProWorkspace.tsx | 2 +- lib/db/queries.ts | 4 +-- lib/db/schema.ts | 6 ++-- scripts/deploy-production-atomic.sh | 5 +++ .../routes/production-local-fallbacks.test.ts | 12 +++++++ 11 files changed, 55 insertions(+), 38 deletions(-) diff --git a/app/(admin)/settings/admin-settings-client.tsx b/app/(admin)/settings/admin-settings-client.tsx index 5f516b036..2cc67412e 100644 --- a/app/(admin)/settings/admin-settings-client.tsx +++ b/app/(admin)/settings/admin-settings-client.tsx @@ -2182,7 +2182,7 @@ export function AdminSettingsClient() { usageTimeEnabled: false, usageTimeStart: "08:00", usageTimeEnd: "20:00", - usageTimeMessage: "由壹点累了也是需要休息的", + usageTimeMessage: "BuYi 累了也是需要休息的", defaultTheme: "system", bannerEnabled: true, bannerText: "限时特惠:升级会员最高立享 45% OFF!", @@ -2224,7 +2224,7 @@ export function AdminSettingsClient() { agentWorkflowDefaultModelId: null, canvasDetailDefaultModelId: null, canvasDetailAgentModelId: null, - lovartComposerPrefix: "让「由壹点AI」", + lovartComposerPrefix: "让「𝗕𝘂𝗬𝗶」", lovartComposerPreviewTexts: [ "打造引人注目的社交媒体视觉", "帮我把这张产品图做成高级电商海报", @@ -2240,8 +2240,8 @@ export function AdminSettingsClient() { lovartPromoText: "现在升级,立享 Kling 3.0 与 Nano Banana Pro,最高 5 折优惠", lovartPromoActionText: "立即升级", - lovartHeroTitle: "由壹点AI 让设计更简单", - lovartHeroSubtitle: "懂你的设计代理,帮你搞定一切", + lovartHeroTitle: "𝗕𝘂𝗬𝗶 让设计触手可及", + lovartHeroSubtitle: "下达指令,即刻呈现", surpriseCategories: ["全部", "精选"], membershipConfig: defaultMembershipConfig, membershipUserOverrides: defaultMembershipUserOverrides, @@ -2302,7 +2302,7 @@ export function AdminSettingsClient() { usageTimeStart: siteSettingsData.usageTimeStart || "08:00", usageTimeEnd: siteSettingsData.usageTimeEnd || "20:00", usageTimeMessage: - siteSettingsData.usageTimeMessage || "由壹点累了也是需要休息的", + siteSettingsData.usageTimeMessage || "BuYi 累了也是需要休息的", defaultTheme: siteSettingsData.defaultTheme || "system", bannerEnabled: siteSettingsData.bannerEnabled ?? true, bannerText: @@ -2398,7 +2398,7 @@ export function AdminSettingsClient() { (siteSettingsData as any).canvasDetailAgentModelId || null, lovartComposerPrefix: String((siteSettingsData as any).lovartComposerPrefix || "").trim() || - "让「由壹点AI」", + "让「𝗕𝘂𝗬𝗶」", lovartComposerPreviewTexts: Array.isArray( siteSettingsData.lovartComposerPreviewTexts ) @@ -2500,9 +2500,9 @@ export function AdminSettingsClient() { lovartPromoActionText: siteSettingsData.lovartPromoActionText || "立即升级", lovartHeroTitle: - siteSettingsData.lovartHeroTitle || "由壹点AI 让设计更简单", + siteSettingsData.lovartHeroTitle || "𝗕𝘂𝗬𝗶 让设计触手可及", lovartHeroSubtitle: - siteSettingsData.lovartHeroSubtitle || "懂你的设计代理,帮你搞定一切", + siteSettingsData.lovartHeroSubtitle || "下达指令,即刻呈现", surpriseCategories: Array.isArray(siteSettingsData.surpriseCategories) ? siteSettingsData.surpriseCategories .map((item: any) => String(item).trim()) @@ -10524,7 +10524,7 @@ export function AdminSettingsClient() { lovartComposerPrefix: e.target.value.slice(0, 40), }) } - placeholder="让「由壹点AI」" + placeholder="让「𝗕𝘂𝗬𝗶」" value={siteSettings.lovartComposerPrefix} />
@@ -10726,7 +10726,7 @@ export function AdminSettingsClient() { lovartHeroTitle: e.target.value, }) } - placeholder="由壹点AI 让设计更简单" + placeholder="𝗕𝘂𝗬𝗶 让设计触手可及" value={siteSettings.lovartHeroTitle} />
@@ -10740,7 +10740,7 @@ export function AdminSettingsClient() { lovartHeroSubtitle: e.target.value, }) } - placeholder="懂你的设计代理,帮你搞定一切" + placeholder="下达指令,即刻呈现" value={siteSettings.lovartHeroSubtitle} /> diff --git a/app/api/site-settings/route.ts b/app/api/site-settings/route.ts index 36a5256f0..adfa919cb 100644 --- a/app/api/site-settings/route.ts +++ b/app/api/site-settings/route.ts @@ -399,7 +399,7 @@ function normalizeLovartComposerPreviewTexts(value: unknown): string[] { function normalizeLovartComposerPrefix(value: unknown): string { const normalized = String(value || "").trim(); if (!normalized) { - return "让「由壹点AI」"; + return "让「𝗕𝘂𝗬𝗶」"; } return normalized.slice(0, 40); } @@ -573,7 +573,7 @@ const PUBLIC_SITE_SETTINGS_SCOPES = new Set([ ]); const HOME_SITE_SETTINGS_FALLBACK: Record = { - siteName: "AI Chatbot", + siteName: "𝗕𝘂𝗬𝗶", siteLogo: null, siteLogoDark: null, favicon: null, @@ -583,11 +583,11 @@ const HOME_SITE_SETTINGS_FALLBACK: Record = { bannerText: "限时特惠:升级会员最高立享 45% OFF!", bannerLink: null, bannerActionText: "立即查看", - lovartHeroTitle: "由壹点AI 让设计更简单", - lovartHeroSubtitle: "懂你的设计代理,帮你搞定一切", + lovartHeroTitle: "𝗕𝘂𝗬𝗶 让设计触手可及", + lovartHeroSubtitle: "下达指令,即刻呈现", surpriseCategories: ["全部", "精选"], canvasDefaultModelId: null, - lovartComposerPrefix: "让「由壹点AI」", + lovartComposerPrefix: "让「𝗕𝘂𝗬𝗶」", lovartComposerPreviewTexts: [], lovartPromptTagVisibility: {}, contactConfig: normalizeContactConfig(undefined), @@ -664,7 +664,7 @@ async function readScopedSiteSettings(keys: string[]) { function createBrandingSettings(settings: Record | undefined) { return { - siteName: String(settings?.siteName || "AI Chatbot"), + siteName: String(settings?.siteName || "𝗕𝘂𝗬𝗶"), siteLogo: settings?.siteLogo || null, siteLogoDark: settings?.siteLogoDark || null, favicon: settings?.favicon || null, @@ -822,7 +822,7 @@ async function getScopedPublicSiteSettings( usageTimeStart: typedSettings?.usageTimeStart || "08:00", usageTimeEnd: typedSettings?.usageTimeEnd || "20:00", usageTimeMessage: - typedSettings?.usageTimeMessage || "由壹点累了也是需要休息的", + typedSettings?.usageTimeMessage || "BuYi 累了也是需要休息的", }); } @@ -953,9 +953,9 @@ async function getScopedPublicSiteSettings( typedSettings?.lovartPromoText || "现在升级,立享 Kling 3.0 与 Nano Banana Pro,最高 5 折优惠", lovartPromoActionText: typedSettings?.lovartPromoActionText || "立即升级", - lovartHeroTitle: typedSettings?.lovartHeroTitle || "由壹点AI 让设计更简单", + lovartHeroTitle: typedSettings?.lovartHeroTitle || "𝗕𝘂𝗬𝗶 让设计触手可及", lovartHeroSubtitle: - typedSettings?.lovartHeroSubtitle || "懂你的设计代理,帮你搞定一切", + typedSettings?.lovartHeroSubtitle || "下达指令,即刻呈现", surpriseCategories: normalizeSurpriseCategories( valueByKey.get(HOME_SURPRISE_CATEGORIES_KEY) ), @@ -1476,7 +1476,7 @@ export async function GET(request: NextRequest) { usageTimeEnabled: false, usageTimeStart: "08:00", usageTimeEnd: "20:00", - usageTimeMessage: "由壹点累了也是需要休息的", + usageTimeMessage: "BuYi 累了也是需要休息的", bannerEnabled: true, bannerText: "限时特惠:升级会员最高立享 45% OFF!", bannerLink: null, @@ -1525,8 +1525,8 @@ export async function GET(request: NextRequest) { canvasDetailAgentModelId: null, lovartPromoText: "现在升级,立享 Kling 3.0 与 Nano Banana Pro,最高 5 折优惠", lovartPromoActionText: "立即升级", - lovartHeroTitle: "由壹点AI 让设计更简单", - lovartHeroSubtitle: "懂你的设计代理,帮你搞定一切", + lovartHeroTitle: "𝗕𝘂𝗬𝗶 让设计触手可及", + lovartHeroSubtitle: "下达指令,即刻呈现", surpriseCategories, aiDetailGenerationEnabled, lovartComposerPrefix, @@ -1546,8 +1546,8 @@ export async function GET(request: NextRequest) { baseSettings.lovartPromoText || "现在升级,立享 Kling 3.0 与 Nano Banana Pro,最高 5 折优惠", lovartPromoActionText: baseSettings.lovartPromoActionText || "立即升级", - lovartHeroTitle: baseSettings.lovartHeroTitle || "由壹点AI 让设计更简单", - lovartHeroSubtitle: baseSettings.lovartHeroSubtitle || "懂你的设计代理,帮你搞定一切", + lovartHeroTitle: baseSettings.lovartHeroTitle || "𝗕𝘂𝗬𝗶 让设计触手可及", + lovartHeroSubtitle: baseSettings.lovartHeroSubtitle || "下达指令,即刻呈现", notification, surpriseCategories, aiDetailGenerationEnabled, @@ -3119,7 +3119,7 @@ export async function PUT(request: NextRequest) { usageTimeEnabled: siteSettingsPayload.usageTimeEnabled ?? false, usageTimeStart: siteSettingsPayload.usageTimeStart ?? "08:00", usageTimeEnd: siteSettingsPayload.usageTimeEnd ?? "20:00", - usageTimeMessage: siteSettingsPayload.usageTimeMessage ?? "由壹点累了也是需要休息的", + usageTimeMessage: siteSettingsPayload.usageTimeMessage ?? "BuYi 累了也是需要休息的", bannerEnabled: siteSettingsPayload.bannerEnabled ?? true, bannerText: siteSettingsPayload.bannerText ?? "限时特惠:升级会员最高立享 45% OFF!", bannerLink: siteSettingsPayload.bannerLink, @@ -3144,8 +3144,8 @@ export async function PUT(request: NextRequest) { siteSettingsPayload.lovartPromoText ?? "现在升级,立享 Kling 3.0 与 Nano Banana Pro,最高 5 折优惠", lovartPromoActionText: siteSettingsPayload.lovartPromoActionText ?? "立即升级", - lovartHeroTitle: siteSettingsPayload.lovartHeroTitle ?? "由壹点AI 让设计更简单", - lovartHeroSubtitle: siteSettingsPayload.lovartHeroSubtitle ?? "懂你的设计代理,帮你搞定一切", + lovartHeroTitle: siteSettingsPayload.lovartHeroTitle ?? "𝗕𝘂𝗬𝗶 让设计触手可及", + lovartHeroSubtitle: siteSettingsPayload.lovartHeroSubtitle ?? "下达指令,即刻呈现", updatedBy: session.user.id, }) .returning(); diff --git a/components/canvas/CanvasChatPanel.tsx b/components/canvas/CanvasChatPanel.tsx index a475ab9bb..a57566f80 100644 --- a/components/canvas/CanvasChatPanel.tsx +++ b/components/canvas/CanvasChatPanel.tsx @@ -1334,7 +1334,7 @@ type VideoStoryboardStreamData = // 建议卡片数据 - 已移除 const SUGGESTIONS: { title: string; desc: string; image: string }[] = []; -const CANVAS_COMPOSER_PREFIX_DEFAULT = "让「由壹点AI」"; +const CANVAS_COMPOSER_PREFIX_DEFAULT = "让「𝗕𝘂𝗬𝗶」"; const CANVAS_COMPOSER_PREVIEW_TEXTS_DEFAULT = [ "打造引人注目的社交媒体视觉", "帮我把这张产品图做成高级电商海报", diff --git a/components/home/lovart-home.tsx b/components/home/lovart-home.tsx index afa9f43fc..b29e55d83 100644 --- a/components/home/lovart-home.tsx +++ b/components/home/lovart-home.tsx @@ -345,7 +345,7 @@ type LovartPromptTagKey = (typeof PROMPT_TAGS)[number]["key"]; type LovartPromptTagVisibility = Record; const FEATURED_PAGE_SIZE = 24; -const COMPOSER_PREFIX_DEFAULT = "让「由壹点AI」"; +const COMPOSER_PREFIX_DEFAULT = "让「𝗕𝘂𝗬𝗶」"; function SidebarSvgIcon({ iconUrl, diff --git a/components/home/lovart/utils.ts b/components/home/lovart/utils.ts index 0fada024e..73e67c042 100644 --- a/components/home/lovart/utils.ts +++ b/components/home/lovart/utils.ts @@ -101,7 +101,7 @@ export type LovartPromptTagVisibility = Record; export const MASONRY_HEIGHTS = [420, 290, 340, 470, 300, 360, 430, 320]; export const FEATURED_PAGE_SIZE = 24; -export const COMPOSER_PREFIX_DEFAULT = "让「由壹点AI」"; +export const COMPOSER_PREFIX_DEFAULT = "让「𝗕𝘂𝗬𝗶」"; export function normalizeComposerPreviewTail(text: string, fixedPrefix: string) { const trimmed = text.trim(); diff --git a/components/layout/brand-top-bar.tsx b/components/layout/brand-top-bar.tsx index 1518f87e3..c91b4d35d 100644 --- a/components/layout/brand-top-bar.tsx +++ b/components/layout/brand-top-bar.tsx @@ -29,7 +29,7 @@ export function BrandTopBar({ showBrand = true, siteName, }: BrandTopBarProps) { - const resolvedSiteName = String(siteName || "").trim() || "由壹点AI"; + const resolvedSiteName = String(siteName || "").trim() || "𝗕𝘂𝗬𝗶"; const positionClass = position === "fixed" ? "fixed left-0 top-0 z-40 w-full" diff --git a/components/style-pro/StyleProWorkspace.tsx b/components/style-pro/StyleProWorkspace.tsx index 42ce88349..c8071ac5e 100644 --- a/components/style-pro/StyleProWorkspace.tsx +++ b/components/style-pro/StyleProWorkspace.tsx @@ -1118,7 +1118,7 @@ export function StyleProWorkspace({ persistedState?.sourceImageUrl, ]); - const siteName = brandingData?.siteName || "由壹点AI"; + const siteName = brandingData?.siteName || "𝗕𝘂𝗬𝗶"; const logo = brandingData?.siteLogoDark || brandingData?.siteLogo || ""; const selectedOptionLabels = useMemo(() => { diff --git a/lib/db/queries.ts b/lib/db/queries.ts index 778e81e49..aa6e0bc37 100644 --- a/lib/db/queries.ts +++ b/lib/db/queries.ts @@ -4725,8 +4725,8 @@ export async function getSiteSettings() { canvasDetailAgentModelId: null, lovartPromoText: "现在升级,立享 Kling 3.0 与 Nano Banana Pro,最高 5 折优惠", lovartPromoActionText: "立即升级", - lovartHeroTitle: "由壹点AI 让设计更简单", - lovartHeroSubtitle: "懂你的设计代理,帮你搞定一切", + lovartHeroTitle: "𝗕𝘂𝗬𝗶 让设计触手可及", + lovartHeroSubtitle: "下达指令,即刻呈现", }; try { const [settings, videoCanvasEnabledSetting, videoCanvasSidebarEnabledSetting] = diff --git a/lib/db/schema.ts b/lib/db/schema.ts index be4af92b5..708d377b4 100644 --- a/lib/db/schema.ts +++ b/lib/db/schema.ts @@ -475,7 +475,7 @@ export const siteSettings = pgTable("SiteSettings", { usageTimeEnabled: boolean("usageTimeEnabled").notNull().default(false), // 是否启用时间限制 usageTimeStart: varchar("usageTimeStart", { length: 5 }).default("08:00"), // 开始时间(HH:mm) usageTimeEnd: varchar("usageTimeEnd", { length: 5 }).default("20:00"), // 结束时间(HH:mm) - usageTimeMessage: text("usageTimeMessage").default("由壹点累了也是需要休息的"), // 超时提示词 + usageTimeMessage: text("usageTimeMessage").default("BuYi 累了也是需要休息的"), // 超时提示词 // 广告横幅设置 bannerEnabled: boolean("bannerEnabled").notNull().default(true), // 是否显示广告横幅 bannerText: text("bannerText").default("限时特惠:升级会员最高立享 45% OFF!"), // 广告横幅文字 @@ -505,8 +505,8 @@ export const siteSettings = pgTable("SiteSettings", { "现在升级,立享 Kling 3.0 与 Nano Banana Pro,最高 5 折优惠" ), lovartPromoActionText: varchar("lovartPromoActionText", { length: 32 }).default("立即升级"), - lovartHeroTitle: text("lovartHeroTitle").default("由壹点AI 让设计更简单"), - lovartHeroSubtitle: text("lovartHeroSubtitle").default("懂你的设计代理,帮你搞定一切"), + lovartHeroTitle: text("lovartHeroTitle").default("𝗕𝘂𝗬𝗶 让设计触手可及"), + lovartHeroSubtitle: text("lovartHeroSubtitle").default("下达指令,即刻呈现"), updatedAt: timestamp("updatedAt").notNull().defaultNow(), updatedBy: uuid("updatedBy").references(() => user.id), }); diff --git a/scripts/deploy-production-atomic.sh b/scripts/deploy-production-atomic.sh index e200f40f5..e11e3c90b 100755 --- a/scripts/deploy-production-atomic.sh +++ b/scripts/deploy-production-atomic.sh @@ -7,6 +7,11 @@ candidate_dir="$(mktemp -d "${app_dir}/.next-candidate.XXXXXX")" previous_dir="${app_dir}/.next-previous-$(date +%Y%m%dT%H%M%S)" build_container="ai-chatbot-build-$(date +%s)" +if grep -Eq '^[[:space:]]*CANVAS_E2E_LOCAL[[:space:]]*=[[:space:]]*"?true"?[[:space:]]*$' "${app_dir}/.env.local"; then + echo "Refusing production deployment while CANVAS_E2E_LOCAL=true." >&2 + exit 1 +fi + cleanup_candidate() { if [ -d "$candidate_dir" ]; then rm -rf -- "$candidate_dir" diff --git a/tests/routes/production-local-fallbacks.test.ts b/tests/routes/production-local-fallbacks.test.ts index 6deffcecc..a9dce008f 100644 --- a/tests/routes/production-local-fallbacks.test.ts +++ b/tests/routes/production-local-fallbacks.test.ts @@ -41,3 +41,15 @@ test("production deploy stages the main build and retains active static chunks", ); expect(deployScript).toContain('curl -fsS "$MAIN_INTERNAL_URL/ping"'); }); + +test("atomic production deploy rejects the local E2E fallback switch", () => { + const deployScript = readFileSync( + resolve(process.cwd(), "scripts/deploy-production-atomic.sh"), + "utf8" + ); + + expect(deployScript).toContain("CANVAS_E2E_LOCAL"); + expect(deployScript).toContain( + "Refusing production deployment while CANVAS_E2E_LOCAL=true." + ); +});