feat(theme): 设置页「主题」导航组 + iframe 预览页 + 学校默认档对接(主题设置 S2)

- Settings.vue:新增「主题」导航组(组级不设 adminOnly),mytheme「我的主题」所有人可见、schooltheme「本校默认」item 级 adminOnly + 入 ADMIN_PANES 双保险(NavItem 扩展 adminOnly 字段,navGroups 组级+item 级双层过滤);两个 pane 左色块右预览 iframe——候选档经 ?yh-theme=/yh-side=/yh-grad= URL 覆盖参数拼进 #/theme-preview src,切候选即换 src 重载;档位清单本轮硬编码 5 档(主色取通道 tokens);「跟随学校默认」=删用户键、「跟随系统默认」=clearSchTheme 清空学校配置;当前生效档与来源(我的选择/学校默认/系统默认)经 resolveEffectiveThemeState 标注
- views/ThemePreview.vue(新增):纯展示预览页——顶栏 .header-container + 左菜单 .left-menu + 面包屑 + iview Table 写死 4 行,DOM 结构对齐 Notice layout,观感由通道 CSS 按档位类驱动;根容器 pointer-events:none,无搜索/分页/ThemeSwitcher;挂载时动态 append 通道 init(baseHost + /static/js/yh-theme-init.js,判重防双挂)——仅该 document 吃通道 CSS,UserHome 本体 index.html 不加 loader(定案)
- App.vue:/theme-preview 顶层独立分支(不进桌面框架、不依赖登录态与 isRouterAlive——未登录直开不白屏);菜单白名单加 /theme-preview;登录成功后异步拉 schTheme 写 localStorage[yh-theme-sch-default](失败/空不写不报错,推荐值语义)
- router/routes.ts:登记 /theme-preview(实际渲染走 App.vue 分支;若后续引入守卫须列入免登录白名单——注释已写明)
- BaseApi:getSchTheme / saveSchThemeState / clearSchTheme 三封装
- src/utils/theme.ts:YschTheme npm run sync 下发(版本 20260930-1248-4e12e6d,含 SCHOOL_DEFAULT_STORAGE_KEY 与 resolveEffectiveThemeState 新导出)
This commit is contained in:
chenxing
2026-09-30 12:59:35 +08:00
parent 0ded3cce9f
commit 357c0edb52
6 changed files with 657 additions and 6 deletions
+23
View File
@@ -181,6 +181,29 @@ class Base extends Abstract {
return this.postRequest({ url, params: { logoUrl } });
}
// ===== 学校默认主题档(主题设置 2026-09-30;后端契约见 SchSettingsController)=====
/**
* 读本校默认主题档(已登录可读):{themeState: "<ThemeState JSON>" | null}——
* null 表示未配置(前端"不写键、不报错"),登录后调一次写 localStorage["yh-theme-sch-default"]
*/
getSchTheme() {
const url = path + "/schTheme";
return this.getRequest<{ themeState: string | null; schId: number }>({ url });
}
/** 保存本校默认主题档(仅学校管理员):themeState 为整份 ThemeState JSON 字符串 */
saveSchThemeState(themeState: string) {
const url = path + "/saveSchThemeState";
return this.postRequest({ url, params: { themeState } });
}
/** 清空本校默认主题档(仅学校管理员;置空后读侧返回 null) */
clearSchTheme() {
const url = path + "/clearSchTheme";
return this.postRequest({ url });
}
savUserRole(info: any) {
const url = path + "/user/savUserRole";
return this.postRequest({ url, data: info as any });