首次提交:初始化项目代码
This commit is contained in:
@@ -0,0 +1,340 @@
|
||||
// utils/themeGlobal.js
|
||||
// 全局主题适配器 - 处理导航栏、TabBar 等全局UI主题
|
||||
import { THEME_PRESETS, getThemeConfigFromStorage, THEME_CHANGE_EVENT } from './theme'
|
||||
|
||||
let isInitializing = false
|
||||
let currentThemeConfig = null
|
||||
|
||||
/**
|
||||
* 应用全局主题到导航栏和TabBar
|
||||
* @param {Object} themeConfig 主题配置对象
|
||||
*/
|
||||
export const applyGlobalTheme = (themeConfig) => {
|
||||
if (!themeConfig || isInitializing) return
|
||||
|
||||
try {
|
||||
const app = getApp({ allowDefault: true })
|
||||
if (app) {
|
||||
app.globalData = app.globalData || {}
|
||||
app.globalData.themeConfig = themeConfig
|
||||
}
|
||||
|
||||
currentThemeConfig = themeConfig
|
||||
|
||||
setTimeout(() => {
|
||||
applyNavigationBarTheme(themeConfig)
|
||||
applyTabBarThemeSafe(themeConfig)
|
||||
}, 100)
|
||||
|
||||
console.log('【全局主题】已应用到导航栏和TabBar')
|
||||
} catch (e) {
|
||||
console.error('【全局主题】应用失败:', e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全应用TabBar主题(先检查是否在TabBar页面)
|
||||
* @param {Object} themeConfig 主题配置
|
||||
*/
|
||||
const applyTabBarThemeSafe = (themeConfig) => {
|
||||
try {
|
||||
const pages = getCurrentPages()
|
||||
if (pages.length === 0) {
|
||||
console.warn('【全局主题】当前无页面,跳过TabBar设置')
|
||||
return
|
||||
}
|
||||
|
||||
const currentPage = pages[pages.length - 1]
|
||||
const currentRoute = currentPage.route || ''
|
||||
|
||||
const tabBarPages = ['pages/index/index', 'pages/todo/todo', 'pages/bill/bill', 'pages/mine/mine']
|
||||
|
||||
if (tabBarPages.includes(currentRoute)) {
|
||||
applyTabBarTheme(themeConfig)
|
||||
} else {
|
||||
console.log('【全局主题】当前非TabBar页面,跳过TabBar设置')
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('【全局主题】TabBar安全检测失败:', e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 强制应用TabBar主题(先检查当前页面是否是TabBar页面)
|
||||
* @param {Object} themeConfig 主题配置
|
||||
*/
|
||||
export const forceApplyTabBarTheme = (themeConfig) => {
|
||||
try {
|
||||
const pages = getCurrentPages()
|
||||
if (pages.length === 0) {
|
||||
console.log('【全局主题】当前无页面,跳过TabBar设置')
|
||||
return
|
||||
}
|
||||
|
||||
const currentPage = pages[pages.length - 1]
|
||||
const currentRoute = currentPage.route || ''
|
||||
|
||||
const tabBarPages = ['pages/index/index', 'pages/todo/todo', 'pages/bill/bill', 'pages/mine/mine']
|
||||
|
||||
if (!tabBarPages.includes(currentRoute)) {
|
||||
console.log('【全局主题】当前非TabBar页面(' + currentRoute + '),跳过TabBar设置')
|
||||
return
|
||||
}
|
||||
|
||||
uni.setTabBarStyle({
|
||||
color: validateColor(themeConfig.textSecondary),
|
||||
selectedColor: validateColor(themeConfig.primaryColor),
|
||||
backgroundColor: validateColor(themeConfig.cardBgColor),
|
||||
borderStyle: themeConfig.bgColor === '#1a202c' ? 'black' : 'white',
|
||||
success: () => {
|
||||
console.log('【全局主题】强制刷新TabBar样式成功')
|
||||
},
|
||||
fail: (err) => {
|
||||
console.warn('【全局主题】强制刷新TabBar样式失败:', err)
|
||||
}
|
||||
})
|
||||
} catch (e) {
|
||||
console.error('【全局主题】强制刷新TabBar失败:', e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 应用导航栏主题
|
||||
* @param {Object} themeConfig 主题配置
|
||||
*/
|
||||
export const applyNavigationBarTheme = (themeConfig) => {
|
||||
try {
|
||||
const bgColor = validateColor(themeConfig.bgColor)
|
||||
const isDark = isDarkColor(bgColor)
|
||||
|
||||
console.log('【全局主题】设置导航栏颜色 - bgColor:', bgColor, 'isDark:', isDark)
|
||||
|
||||
if (isDark) {
|
||||
setNavBarWhite(bgColor)
|
||||
} else {
|
||||
setNavBarBlack(bgColor)
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('【全局主题】导航栏主题设置失败:', e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 简化版本:直接应用导航栏主题(页面调用)
|
||||
*/
|
||||
export const refreshNavBarTheme = () => {
|
||||
try {
|
||||
if (!currentThemeConfig) {
|
||||
currentThemeConfig = getThemeConfigFromStorage() || THEME_PRESETS['default']
|
||||
}
|
||||
applyNavigationBarTheme(currentThemeConfig)
|
||||
} catch (e) {
|
||||
console.error('【全局主题】刷新导航栏失败:', e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断颜色是否为深色
|
||||
* @param {string} color 颜色值
|
||||
* @returns {boolean} 是否为深色
|
||||
*/
|
||||
const isDarkColor = (color) => {
|
||||
if (!color || color.length < 7) return false
|
||||
|
||||
const hex = color.replace('#', '')
|
||||
const r = parseInt(hex.substr(0, 2), 16)
|
||||
const g = parseInt(hex.substr(2, 2), 16)
|
||||
const b = parseInt(hex.substr(4, 2), 16)
|
||||
const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255
|
||||
|
||||
return luminance <= 0.5
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置导航栏为白色前景(用于深色背景)
|
||||
*/
|
||||
const setNavBarWhite = (bgColor) => {
|
||||
try {
|
||||
console.log('【全局主题】调用 setNavigationBarColor - frontColor: white, #ffffff:', bgColor)
|
||||
|
||||
uni.setNavigationBarColor({
|
||||
frontColor: '#ffffff',
|
||||
backgroundColor: bgColor,
|
||||
success: () => {
|
||||
console.log('【全局主题】导航栏颜色设置成功(白色前景)')
|
||||
},
|
||||
fail: (err) => {
|
||||
console.warn('【全局主题】导航栏颜色设置失败(白色前景):', err)
|
||||
}
|
||||
})
|
||||
} catch (e) {
|
||||
console.error('【全局主题】setNavBarWhite 失败:', e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置导航栏为黑色前景(用于浅色背景)
|
||||
*/
|
||||
const setNavBarBlack = (bgColor) => {
|
||||
try {
|
||||
console.log('【全局主题】调用 setNavigationBarColor - frontColor: #000000, bgColor:', bgColor)
|
||||
|
||||
uni.setNavigationBarColor({
|
||||
frontColor: '#000000',
|
||||
backgroundColor: bgColor,
|
||||
success: () => {
|
||||
console.log('【全局主题】导航栏颜色设置成功(黑色前景)')
|
||||
},
|
||||
fail: (err) => {
|
||||
console.warn('【全局主题】导航栏颜色设置失败(黑色前景):', err)
|
||||
console.log('【全局主题】尝试只设置背景色')
|
||||
uni.setNavigationBarColor({
|
||||
backgroundColor: bgColor,
|
||||
success: () => {
|
||||
console.log('【全局主题】导航栏背景色设置成功')
|
||||
},
|
||||
fail: (err2) => {
|
||||
console.warn('【全局主题】导航栏背景色设置也失败:', err2)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
} catch (e) {
|
||||
console.error('【全局主题】setNavBarBlack 失败:', e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证并修复颜色值
|
||||
* @param {string} color 颜色值
|
||||
* @returns {string} 验证后的颜色值
|
||||
*/
|
||||
const validateColor = (color) => {
|
||||
if (!color) return '#ffffff'
|
||||
|
||||
if (!color.startsWith('#')) {
|
||||
return '#' + color
|
||||
}
|
||||
|
||||
if (color.length === 4) {
|
||||
return '#' + color[1] + color[1] + color[2] + color[2] + color[3] + color[3]
|
||||
}
|
||||
|
||||
return color
|
||||
}
|
||||
|
||||
/**
|
||||
* 应用TabBar主题
|
||||
* @param {Object} themeConfig 主题配置
|
||||
*/
|
||||
export const applyTabBarTheme = (themeConfig) => {
|
||||
try {
|
||||
uni.setTabBarStyle({
|
||||
color: validateColor(themeConfig.textSecondary),
|
||||
selectedColor: validateColor(themeConfig.primaryColor),
|
||||
backgroundColor: validateColor(themeConfig.cardBgColor),
|
||||
borderStyle: themeConfig.bgColor === '#1a202c' ? 'black' : 'white',
|
||||
success: () => {
|
||||
console.log('【全局主题】TabBar样式设置成功')
|
||||
},
|
||||
fail: (err) => {
|
||||
console.warn('【全局主题】TabBar样式设置失败:', err)
|
||||
}
|
||||
})
|
||||
} catch (e) {
|
||||
console.error('【全局主题】TabBar主题设置失败:', e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据背景色判断前景色(文字颜色)
|
||||
* @param {string} bgColor 背景色
|
||||
* @returns {string} '#000000' 或 '#ffffff'
|
||||
*/
|
||||
export const getFrontColor = (bgColor) => {
|
||||
return isDarkColor(bgColor) ? '#ffffff' : '#000000'
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化全局主题(在App.vue或页面入口调用)
|
||||
*/
|
||||
export const initGlobalTheme = () => {
|
||||
isInitializing = true
|
||||
|
||||
try {
|
||||
const themeConfig = getThemeConfigFromStorage() || THEME_PRESETS['default']
|
||||
currentThemeConfig = themeConfig
|
||||
|
||||
setTimeout(() => {
|
||||
applyGlobalTheme(themeConfig)
|
||||
isInitializing = false
|
||||
}, 300)
|
||||
} catch (e) {
|
||||
console.error('【全局主题】初始化失败:', e)
|
||||
isInitializing = false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册全局主题变更监听
|
||||
*/
|
||||
export const registerGlobalThemeListener = () => {
|
||||
uni.$on(THEME_CHANGE_EVENT, (themeData) => {
|
||||
try {
|
||||
let newThemeConfig = null
|
||||
|
||||
if (themeData?.config) {
|
||||
newThemeConfig = themeData.config
|
||||
} else if (themeData?.key && THEME_PRESETS[themeData.key]) {
|
||||
newThemeConfig = THEME_PRESETS[themeData.key]
|
||||
}
|
||||
|
||||
if (newThemeConfig) {
|
||||
applyGlobalTheme(newThemeConfig)
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('【全局主题】监听处理失败:', e)
|
||||
}
|
||||
})
|
||||
|
||||
console.log('【全局主题】已注册主题变更监听')
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除全局主题监听
|
||||
*/
|
||||
export const unregisterGlobalThemeListener = () => {
|
||||
uni.$off(THEME_CHANGE_EVENT)
|
||||
console.log('【全局主题】已移除主题变更监听')
|
||||
}
|
||||
|
||||
/**
|
||||
* 在页面onShow中调用的混入(用于页面自动应用全局主题)
|
||||
*/
|
||||
export const globalThemeMixin = {
|
||||
onShow() {
|
||||
const themeConfig = getThemeConfigFromStorage() || THEME_PRESETS['default']
|
||||
applyNavigationBarTheme(themeConfig)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 页面级导航栏刷新方法(简化调用)
|
||||
*/
|
||||
export const onPageShow = () => {
|
||||
refreshNavBarTheme()
|
||||
}
|
||||
|
||||
export default {
|
||||
applyGlobalTheme,
|
||||
applyNavigationBarTheme,
|
||||
applyTabBarTheme,
|
||||
forceApplyTabBarTheme,
|
||||
initGlobalTheme,
|
||||
registerGlobalThemeListener,
|
||||
unregisterGlobalThemeListener,
|
||||
getFrontColor,
|
||||
refreshNavBarTheme,
|
||||
onPageShow,
|
||||
globalThemeMixin
|
||||
}
|
||||
Reference in New Issue
Block a user