Files
2026-07-03 11:45:16 +08:00

185 lines
5.6 KiB
JavaScript

export default {
namespaced: true,
state: {
// 字体缩放比例:1.0=默认, 1.25=大, 1.5=较大, 2.0=最大
fontScale: 1.0,
// 字体大小标签
fontScaleLabel: '默认'
},
mutations: {
/**
* 设置字体缩放比例
* @param {Object} state - Vuex state
* @param {Object} payload - { scale: number, label: string }
*/
SET_FONT_SCALE(state, payload) {
state.fontScale = payload.scale
state.fontScaleLabel = payload.label
}
},
actions: {
/**
* 初始化字体设置
* 从本地存储读取用户设置,如果没有则使用默认值
*/
initFontScale({ commit }) {
try {
// 优先读取用户手动设置
const savedFontSize = uni.getStorageSync('userFontScale')
if (savedFontSize) {
const fontLabels = {
1.0: '默认',
1.25: '大',
1.5: '较大',
2.0: '最大'
}
const label = fontLabels[savedFontSize] || '自定义'
commit('SET_FONT_SCALE', { scale: savedFontSize, label })
console.log('[Vuex字体] 初始化成功,使用用户设置:', savedFontSize)
} else {
// 读取系统自动检测的字体缩放
const systemScale = uni.getStorageSync('fontScale') || 1.0
const fontLabels = {
1.0: '默认',
1.25: '大',
1.5: '较大',
2.0: '最大'
}
const label = fontLabels[systemScale] || '跟随系统'
commit('SET_FONT_SCALE', { scale: systemScale, label })
console.log('[Vuex字体] 初始化成功,使用系统设置:', systemScale)
}
} catch (error) {
console.error('[Vuex字体] 初始化失败:', error)
commit('SET_FONT_SCALE', { scale: 1.0, label: '默认' })
}
},
/**
* 设置字体缩放
* @param {Object} param - { commit, dispatch }
* @param {Object} payload - { scale: number, label: string }
*/
setFontScale({ commit, dispatch }, payload) {
try {
// 更新 Vuex state
commit('SET_FONT_SCALE', payload)
// 持久化到本地存储
uni.setStorageSync('userFontScale', payload.scale)
console.log('[Vuex字体] 字体已设置为:', payload.label, '(', payload.scale, ')')
// 应用字体变化到 DOM
dispatch('applyFontScale', payload.scale)
} catch (error) {
console.error('[Vuex字体] 设置失败:', error)
}
},
/**
* 应用字体缩放到 DOM
* 直接操作根元素字体大小,使所有 rem 单位自动缩放
*/
applyFontScale(_, scale) {
const rootFontSize = Math.round(16 * scale * 100) / 100 // 16px 基准
console.log(`[Vuex字体] 应用字体缩放: ${rootFontSize}px (scale=${scale})`)
// #ifdef H5 || APP-PLUS
try {
// 设置 document.documentElement
if (typeof document !== 'undefined' && document.documentElement) {
document.documentElement.style.fontSize = rootFontSize + 'px'
console.log('[Vuex字体] ✓ documentElement.fontSize 已设置为', rootFontSize + 'px')
}
// 设置所有 page 元素
if (typeof document !== 'undefined') {
const pages = document.querySelectorAll('page')
if (pages.length > 0) {
pages.forEach(p => p.style.fontSize = rootFontSize + 'px')
console.log('[Vuex字体] ✓ 已设置', pages.length, '个 page 元素')
}
// 设置 body
if (document.body) {
document.body.style.fontSize = rootFontSize + 'px'
}
}
} catch (e) {
console.warn('[Vuex字体] DOM操作失败:', e)
}
// #endif
// #ifdef APP-PLUS
// 广播到所有 webview,确保已打开的页面也更新字体
setTimeout(() => {
try {
const allWebviews = plus.webview.all()
let count = 0
allWebviews.forEach(webview => {
try {
const fontSize = rootFontSize + 'px'
webview.evalJS(`
if (document.documentElement) document.documentElement.style.fontSize = '${fontSize}';
if (document.body) document.body.style.fontSize = '${fontSize}';
document.querySelectorAll('page').forEach(function(p){ p.style.fontSize = '${fontSize}'; });
`)
count++
} catch (e2) {}
})
console.log(`[Vuex字体] 已广播到 ${count}/${allWebviews.length} 个webview`)
} catch (e) {
console.warn('[Vuex字体] 广播失败:', e)
}
}, 200)
// #endif
// 保存到本地存储,以便其他页面读取
uni.setStorageSync('fontScale', scale)
},
/**
* 重置字体为默认大小
*/
resetFontScale({ commit, dispatch }) {
try {
// 清除用户设置
uni.removeStorageSync('userFontScale')
// 更新 Vuex state
commit('SET_FONT_SCALE', { scale: 1.0, label: '默认' })
// 应用默认字体
dispatch('applyFontScale', 1.0)
console.log('[Vuex字体] 已恢复默认字体大小')
} catch (error) {
console.error('[Vuex字体] 重置失败:', error)
}
}
},
getters: {
/**
* 获取当前字体缩放比例
*/
fontScale: state => state.fontScale,
/**
* 获取当前字体大小标签
*/
fontScaleLabel: state => state.fontScaleLabel
}
}