From b6b022e4ca8b36e286ed7c247b12fc68d2bb6917 Mon Sep 17 00:00:00 2001 From: chenxing Date: Mon, 28 Sep 2026 15:04:02 +0800 Subject: [PATCH] =?UTF-8?q?[CMS-VISUAL]=20E=20=E5=89=8D=E7=AB=AF=E9=85=8D?= =?UTF-8?q?=E5=A5=97:=20=E7=BC=96=E8=BE=91=E4=B8=8B=E6=9E=B6=E4=B8=BB?= =?UTF-8?q?=E9=A2=98=E7=AB=99=E7=82=B9=E6=97=B6=E6=8C=89=E5=88=AB=E5=90=8D?= =?UTF-8?q?=E8=A1=A8=E5=91=88=E7=8E=B0=E5=BD=92=E4=B8=80=E4=B8=BB=E9=A2=98?= =?UTF-8?q?=EF=BC=88=E4=B8=8E=E5=90=8E=E7=AB=AF=20DEPRECATED=5FALIASES=20?= =?UTF-8?q?=E5=90=8C=E6=9E=84=EF=BC=8C=E4=B8=8D=E8=AF=AF=E6=8A=A5=E6=9C=AA?= =?UTF-8?q?=E6=B3=A8=E5=86=8C=EF=BC=8C181=20=E6=B5=8B=E8=AF=95=E7=BB=BF?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/__tests__/themeEdit.spec.ts | 21 +++++++++++++++++---- src/utils/themeEdit.ts | 23 ++++++++++++++++++++++- 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/__tests__/themeEdit.spec.ts b/src/__tests__/themeEdit.spec.ts index 89236cf..dc6865c 100644 --- a/src/__tests__/themeEdit.spec.ts +++ b/src/__tests__/themeEdit.spec.ts @@ -8,21 +8,34 @@ import { resolveEditableTheme } from "@/utils/themeEdit"; */ describe("resolveEditableTheme 站点编辑主题归一(任务三)", () => { it("注册中的主题原值保留且不告警", () => { - expect(resolveEditableTheme("mint-breeze", ["default", "mint-breeze"])).toEqual({ - theme: "mint-breeze", + expect(resolveEditableTheme("scholar-blue", ["default", "scholar-blue"])).toEqual({ + theme: "scholar-blue", unregistered: false, }); }); + it("docs/20 E:下架主题解析为保留主题 + colorScheme 预设(不误报未注册)", () => { + expect(resolveEditableTheme("classic-red", ["default", "scholar-blue", "campus-glow"])).toEqual({ + theme: "default", + unregistered: false, + aliasColorScheme: "classic-red", + }); + expect(resolveEditableTheme("poly-blue", ["default", "scholar-blue", "campus-glow"])).toEqual({ + theme: "scholar-blue", + unregistered: false, + aliasColorScheme: "poly", + }); + }); + it("未注册主题保留原值并标记 unregistered(不再归一 default)", () => { - expect(resolveEditableTheme("ghost-theme", ["default", "mint-breeze"])).toEqual({ + expect(resolveEditableTheme("ghost-theme", ["default", "scholar-blue"])).toEqual({ theme: "ghost-theme", unregistered: true, }); }); it("空主题归一 default(站点未选过皮肤的场景)", () => { - expect(resolveEditableTheme(undefined, ["default", "mint-breeze"])).toEqual({ + expect(resolveEditableTheme(undefined, ["default", "scholar-blue"])).toEqual({ theme: "default", unregistered: false, }); diff --git a/src/utils/themeEdit.ts b/src/utils/themeEdit.ts index 8d9c2ae..217db61 100644 --- a/src/utils/themeEdit.ts +++ b/src/utils/themeEdit.ts @@ -5,17 +5,38 @@ * 新行为:保留原值交服务端注册表校验(保存未注册主题会被明确拒绝),仅提示告警。 */ export interface EditableTheme { - /** 编辑表单主题值(未注册时保留原值,不再偷偷归一 default) */ + /** 编辑表单主题值(未注册时保留原值,不再偷偷归一 default;下架别名解析为保留主题) */ theme: string; /** 主题未在注册列表中(保存将被服务端拒绝,需提示用户改选或先上传) */ unregistered: boolean; + /** docs/20 E:下架主题别名解析到的 colorScheme 预设(保存后保持原配色;非别名为 undefined) */ + aliasColorScheme?: string; } +/** docs/20 E:下架主题别名表(与后端 ThemeRegistry.DEPRECATED_ALIASES 同构,两侧同步维护) */ +const DEPRECATED_ALIASES: Record = { + "blue-white": { target: "default", colorScheme: "blue-white" }, + "classic-red": { target: "default", colorScheme: "classic-red" }, + "fresh-mint": { target: "default", colorScheme: "fresh-mint" }, + "warm-kinder": { target: "default", colorScheme: "warm-kinder" }, + "academic-navy": { target: "scholar-blue", colorScheme: "navy" }, + "campus-azure": { target: "scholar-blue", colorScheme: "azure" }, + "poly-blue": { target: "scholar-blue", colorScheme: "poly" }, + "agri-forest": { target: "scholar-blue", colorScheme: "agri" }, + "jade-normal": { target: "scholar-blue", colorScheme: "jade" }, + "mint-breeze": { target: "scholar-blue", colorScheme: "mint" }, +}; + export function resolveEditableTheme(rowTheme: string | undefined, themeNames: string[]): EditableTheme { const value = rowTheme || "default"; if (!themeNames.length) { // 列表加载失败/为空:无法判定注册状态,保留原值且不误报(由服务端校验兜底) return { theme: value, unregistered: false }; } + // docs/20 E:下架主题 → 呈现归一后的保留主题(与服务端保存归一化一致,不误报"未注册") + const alias = DEPRECATED_ALIASES[value]; + if (alias && themeNames.includes(alias.target)) { + return { theme: alias.target, unregistered: false, aliasColorScheme: alias.colorScheme }; + } return { theme: value, unregistered: !themeNames.includes(value) }; }