88 lines
2.3 KiB
JavaScript
88 lines
2.3 KiB
JavaScript
|
|
import { getCache, setCache } from '@/utils/cache'
|
|||
|
|
import { getThemeApi } from '@/api/page/theme.js'
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 主题令牌的本地应用器
|
|||
|
|
*
|
|||
|
|
* 后端 GET wx/theme 返回 { css_vars, tokens, layout, ... }。
|
|||
|
|
* 注意:微信小程序里不要用动态 import() 拉 API——经常静默失败,看起来像「没请求主题」。
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
const STORAGE_KEY = 'theme_tokens'
|
|||
|
|
const STORAGE_VARS_KEY = 'theme_css_vars'
|
|||
|
|
|
|||
|
|
/** 内置兜底主题(与后端第一套轻奢香槟金对齐) */
|
|||
|
|
export const FALLBACK_VARS = {
|
|||
|
|
'--color-primary': '#B08D57',
|
|||
|
|
'--color-primary-soft': '#d9b97f',
|
|||
|
|
'--color-bg': '#FAF7F2',
|
|||
|
|
'--color-bg-soft': '#f5f2ec',
|
|||
|
|
'--color-surface': '#ffffff',
|
|||
|
|
'--color-text': '#1C1917',
|
|||
|
|
'--color-text-soft': '#666666',
|
|||
|
|
'--color-border': '#E7DFD3',
|
|||
|
|
'--radius-md': '16rpx',
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 拉取主题并落地;失败不抛,走缓存/兜底
|
|||
|
|
*/
|
|||
|
|
export async function loadAndApplyTheme() {
|
|||
|
|
let theme = null
|
|||
|
|
try {
|
|||
|
|
// eslint-disable-next-line no-console
|
|||
|
|
console.log('[theme] GET theme …')
|
|||
|
|
theme = await getThemeApi()
|
|||
|
|
// eslint-disable-next-line no-console
|
|||
|
|
console.log('[theme] ok', theme && theme.code, theme && theme.fallback)
|
|||
|
|
} catch (e) {
|
|||
|
|
// eslint-disable-next-line no-console
|
|||
|
|
console.warn('[theme] request failed', e)
|
|||
|
|
}
|
|||
|
|
if (!theme || !theme.css_vars) {
|
|||
|
|
theme = {
|
|||
|
|
css_vars: getCache(STORAGE_VARS_KEY) || FALLBACK_VARS,
|
|||
|
|
tokens: getCache(STORAGE_KEY) || {},
|
|||
|
|
fallback: true,
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
applyTheme(theme)
|
|||
|
|
return theme
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/** 写入缓存;H5 同步到 documentElement */
|
|||
|
|
export function applyTheme(theme) {
|
|||
|
|
if (!theme) return
|
|||
|
|
const vars = theme.css_vars || FALLBACK_VARS
|
|||
|
|
setCache(STORAGE_VARS_KEY, vars)
|
|||
|
|
if (theme.tokens) {
|
|||
|
|
setCache(STORAGE_KEY, theme.tokens)
|
|||
|
|
}
|
|||
|
|
applyVarsToDom(vars)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export function applyVarsToDom(vars) {
|
|||
|
|
if (!vars) return
|
|||
|
|
// #ifdef H5
|
|||
|
|
try {
|
|||
|
|
const root = document.documentElement
|
|||
|
|
Object.entries(vars).forEach(([k, v]) => {
|
|||
|
|
root.style.setProperty(k, String(v))
|
|||
|
|
})
|
|||
|
|
} catch (e) {
|
|||
|
|
// ignore
|
|||
|
|
}
|
|||
|
|
// #endif
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export function getActiveVars() {
|
|||
|
|
return getCache(STORAGE_VARS_KEY) || FALLBACK_VARS
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export function varsToStyleString(vars) {
|
|||
|
|
const obj = vars || getActiveVars()
|
|||
|
|
return Object.entries(obj)
|
|||
|
|
.map(([k, v]) => `${k}: ${v}`)
|
|||
|
|
.join('; ')
|
|||
|
|
}
|