manualThemeStore.ts 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. import type { ThemeColorOption, ThemeMode, ThemeState } from '@/composables/types/theme'
  2. import { defineStore } from 'pinia'
  3. import { themeColorOptions } from '@/composables/types/theme'
  4. /**
  5. * 完整版主题状态管理
  6. * 支持手动切换主题、主题色选择、跟随系统主题等完整功能
  7. */
  8. export const useManualThemeStore = defineStore('manualTheme', {
  9. state: (): ThemeState => ({
  10. theme: 'light',
  11. followSystem: true, // 是否跟随系统主题
  12. hasUserSet: false, // 用户是否手动设置过主题
  13. currentThemeColor: themeColorOptions[0],
  14. themeVars: {
  15. darkBackground: '#0f0f0f',
  16. darkBackground2: '#1a1a1a',
  17. darkBackground3: '#242424',
  18. darkBackground4: '#2f2f2f',
  19. darkBackground5: '#3d3d3d',
  20. darkBackground6: '#4a4a4a',
  21. darkBackground7: '#606060',
  22. darkColor: '#ffffff',
  23. darkColor2: '#e0e0e0',
  24. darkColor3: '#a0a0a0',
  25. colorTheme: themeColorOptions[0].primary,
  26. },
  27. }),
  28. getters: {
  29. isDark: state => state.theme === 'dark',
  30. },
  31. actions: {
  32. /**
  33. * 手动切换主题
  34. * @param mode 指定主题模式,不传则自动切换
  35. */
  36. toggleTheme(mode?: ThemeMode) {
  37. this.theme = mode || (this.theme === 'light' ? 'dark' : 'light')
  38. this.hasUserSet = true // 标记用户已手动设置
  39. this.followSystem = false // 不再跟随系统
  40. this.setNavigationBarColor()
  41. },
  42. /**
  43. * 设置是否跟随系统主题
  44. * @param follow 是否跟随系统
  45. */
  46. setFollowSystem(follow: boolean) {
  47. this.followSystem = follow
  48. if (follow) {
  49. this.hasUserSet = false
  50. this.initTheme() // 重新获取系统主题
  51. }
  52. },
  53. /**
  54. * 设置导航栏颜色
  55. */
  56. setNavigationBarColor() {
  57. uni.setNavigationBarColor({
  58. frontColor: this.theme === 'light' ? '#000000' : '#ffffff',
  59. backgroundColor: this.theme === 'light' ? '#ffffff' : '#000000',
  60. })
  61. },
  62. /**
  63. * 设置主题色
  64. * @param color 主题色选项
  65. */
  66. setCurrentThemeColor(color: ThemeColorOption) {
  67. this.currentThemeColor = color
  68. this.themeVars.colorTheme = color.primary
  69. },
  70. /**
  71. * 获取系统主题
  72. * @returns 系统主题模式
  73. */
  74. getSystemTheme(): ThemeMode {
  75. try {
  76. // #ifdef MP-WEIXIN
  77. // 微信小程序使用 getAppBaseInfo
  78. const appBaseInfo = uni.getAppBaseInfo()
  79. if (appBaseInfo && appBaseInfo.theme) {
  80. return appBaseInfo.theme as ThemeMode
  81. }
  82. // #endif
  83. // #ifndef MP-WEIXIN
  84. // 其他平台使用 getSystemInfoSync
  85. const systemInfo = uni.getSystemInfoSync()
  86. if (systemInfo && systemInfo.theme) {
  87. return systemInfo.theme as ThemeMode
  88. }
  89. // #endif
  90. }
  91. catch (error) {
  92. console.warn('获取系统主题失败:', error)
  93. }
  94. return 'light' // 默认返回 light
  95. },
  96. /**
  97. * 初始化主题
  98. */
  99. initTheme() {
  100. // 如果用户已手动设置且不跟随系统,保持当前主题
  101. if (this.hasUserSet && !this.followSystem) {
  102. console.log('使用用户设置的主题:', this.theme)
  103. this.setNavigationBarColor()
  104. return
  105. }
  106. // 获取系统主题
  107. const systemTheme = this.getSystemTheme()
  108. // 如果是首次启动或跟随系统,使用系统主题
  109. if (!this.hasUserSet || this.followSystem) {
  110. this.theme = systemTheme
  111. if (!this.hasUserSet) {
  112. this.followSystem = true
  113. console.log('首次启动,使用系统主题:', this.theme)
  114. }
  115. else {
  116. console.log('跟随系统主题:', this.theme)
  117. }
  118. }
  119. this.setNavigationBarColor()
  120. },
  121. },
  122. })