feat(theme): CMS 站点主题弱联动 + campus-green 色值对齐(T3)——新增 utils/cmsTheme 映射适配器(SKIN_MAP/PARAM_ALIASE/colorScheme 预设,未映射一律 null 回落);App.vue 皮肤三层优先级 stale-while-revalidate(缓存先画、后台刷新、失败静默);svc.ts 加 hallApi.site;campus-green 四色与 CMS campus-glow 同源对齐并升 1.1.0;theme-base.css 克制补丁 view-ui 实际使用的 Checkbox/Radio/Page/Modal.confirm/dyn-file-btn 交互态
This commit is contained in:
+42
-4
@@ -5,23 +5,31 @@
|
||||
* 与后台前端(front/)刻意不同:不渲染平台模块菜单(app_module 是管理端契约),
|
||||
* 只做两个入口——办事大厅、我的办件(详情/办理页从列表进入)。
|
||||
*
|
||||
* 皮肤:启动时按运行时配置(env-config 的 theme/themeParams)应用皮肤包;
|
||||
* 未配置 → default;未注册 → default(整页回退,见 utils/theme.ts)。
|
||||
* 皮肤三层优先级(T3 弱联动,2026-10-03):
|
||||
* CMS 站点推荐(/api/hall/site 的 theme/themeParams,经 utils/cmsTheme 映射;
|
||||
* stale-while-revalidate——localStorage 缓存先画、后台刷新,失败静默)
|
||||
* > env-config 部署级皮肤 > default。
|
||||
* 推荐值、不保证生效:任一层缺失/非法都回落下一层(utils/theme.ts)。
|
||||
*/
|
||||
import { onMounted, ref } from "vue";
|
||||
import { baseApi } from "@/api/module/base";
|
||||
import config from "@/assets/config/host.config";
|
||||
import { applyTheme, resolveTheme, type ThemeManifest } from "@/utils/theme";
|
||||
import { toHallSkin } from "@/utils/cmsTheme";
|
||||
import { useSite } from "@/utils/site";
|
||||
import { hallApi } from "@/api/module/svc";
|
||||
|
||||
const userName = ref("");
|
||||
const theme = ref<ThemeManifest>(resolveTheme(null));
|
||||
// CMS 指南页来路(T4 回跳闭环):仅 /#/apply 深链带合法 from 参数时非空
|
||||
const { portalFrom } = useSite();
|
||||
const { portalFrom, currentSiteCode } = useSite();
|
||||
|
||||
onMounted(async () => {
|
||||
// 皮肤先应用(首屏观感),再拉用户信息——用户信息失败不影响办理页面使用
|
||||
// ① 基线:env-config 部署级皮肤(现状语义不变,先应用保证首屏观感)
|
||||
theme.value = applyTheme(config.theme, config.themeParams);
|
||||
// ② 站点推荐:CMS 站点主题(弱联动)——缓存先画,后台刷新
|
||||
applySiteThemeRecommend();
|
||||
// 用户信息失败不影响办理页面使用
|
||||
try {
|
||||
const user: any = await baseApi.getUserInfo().send();
|
||||
userName.value = user?.name || "";
|
||||
@@ -32,6 +40,36 @@ onMounted(async () => {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 站点主题推荐应用(stale-while-revalidate):
|
||||
* 未登录时该请求会 302 跳 CAS(与 items 同行为,页面本来就要登录);
|
||||
* 任何失败静默保留现皮肤——推荐、不保证生效,绝不阻塞首屏。
|
||||
*/
|
||||
async function applySiteThemeRecommend() {
|
||||
const code = currentSiteCode.value; // useSite() 模块级 ref,当前视图 onMounted 已 resolve
|
||||
if (!code) return;
|
||||
const cacheKey = `svchall.public.siteTheme.${code}`;
|
||||
// ① stale:同步读缓存立即应用(二次访问无闪色)
|
||||
try {
|
||||
const cached = JSON.parse(localStorage.getItem(cacheKey) || "null");
|
||||
const stale = toHallSkin(cached);
|
||||
if (stale) theme.value = applyTheme(stale.name, stale.params);
|
||||
} catch {
|
||||
// 坏缓存当没有
|
||||
}
|
||||
// ② revalidate:后台刷新(失败静默保留现皮肤——推荐、不保证生效)
|
||||
try {
|
||||
const info: any = await hallApi.site(code).send();
|
||||
const pick = toHallSkin({ theme: info?.theme, themeParams: info?.themeParams });
|
||||
localStorage.setItem(cacheKey, JSON.stringify({
|
||||
theme: info?.theme || null, themeParams: info?.themeParams || null,
|
||||
}));
|
||||
if (pick) theme.value = applyTheme(pick.name, pick.params);
|
||||
} catch (e) {
|
||||
console.warn("[public-hall] 站点主题获取失败,沿用当前皮肤", e);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
Reference in New Issue
Block a user