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) }; }