manualThemeStore.ts 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  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. * @param isFollw 是否是跟随系统
  36. */
  37. toggleTheme(mode?: ThemeMode, isFollw: boolean = false) {
  38. this.theme = mode || (this.theme === 'light' ? 'dark' : 'light')
  39. if (!isFollw) {
  40. // 如果不是跟随系统,是手动切换
  41. this.hasUserSet = true // 标记用户已手动设置
  42. this.followSystem = false // 不再跟随系统
  43. }
  44. this.setNavigationBarColor()
  45. },
  46. /**
  47. * 设置是否跟随系统主题
  48. * @param follow 是否跟随系统
  49. */
  50. setFollowSystem(follow: boolean) {
  51. this.followSystem = follow
  52. if (follow) {
  53. this.hasUserSet = false
  54. this.initTheme() // 重新获取系统主题
  55. }
  56. },
  57. /**
  58. * 设置导航栏颜色
  59. */
  60. setNavigationBarColor() {
  61. uni.setNavigationBarColor({
  62. frontColor: this.theme === 'light' ? '#000000' : '#ffffff',
  63. backgroundColor: this.theme === 'light' ? '#ffffff' : '#000000',
  64. })
  65. },
  66. /**
  67. * 设置主题色
  68. * @param color 主题色选项
  69. */
  70. setCurrentThemeColor(color: ThemeColorOption) {
  71. this.currentThemeColor = color
  72. this.themeVars.colorTheme = color.primary
  73. },
  74. /**
  75. * 获取系统主题
  76. * @returns 系统主题模式
  77. */
  78. getSystemTheme(): ThemeMode {
  79. try {
  80. // #ifdef MP-WEIXIN
  81. // 微信小程序使用 getAppBaseInfo
  82. const appBaseInfo = uni.getAppBaseInfo()
  83. if (appBaseInfo && appBaseInfo.theme) {
  84. return appBaseInfo.theme as ThemeMode
  85. }
  86. // #endif
  87. // #ifndef MP-WEIXIN
  88. // 其他平台使用 getSystemInfoSync
  89. const systemInfo = uni.getSystemInfoSync()
  90. if (systemInfo && systemInfo.theme) {
  91. return systemInfo.theme as ThemeMode
  92. }
  93. // #endif
  94. }
  95. catch (error) {
  96. console.warn('获取系统主题失败:', error)
  97. }
  98. return 'light' // 默认返回 light
  99. },
  100. /**
  101. * 初始化主题
  102. */
  103. initTheme() {
  104. // 如果用户已手动设置且不跟随系统,保持当前主题
  105. if (this.hasUserSet && !this.followSystem) {
  106. console.log('使用用户设置的主题:', this.theme)
  107. this.setNavigationBarColor()
  108. return
  109. }
  110. // 获取系统主题
  111. const systemTheme = this.getSystemTheme()
  112. // 如果是首次启动或跟随系统,使用系统主题
  113. if (!this.hasUserSet || this.followSystem) {
  114. this.theme = systemTheme
  115. if (!this.hasUserSet) {
  116. this.followSystem = true
  117. console.log('首次启动,使用系统主题:', this.theme)
  118. }
  119. else {
  120. console.log('跟随系统主题:', this.theme)
  121. }
  122. }
  123. this.setNavigationBarColor()
  124. },
  125. },
  126. })