feat(theme): 实现主题切换系统并优化经销商相关页面

- 新增主题切换系统,支持智能主题和手动选择
- 更新经销商首页、团队、订单、提现等页面样式
- 添加主题相关的Hook和样式工具函数
- 优化部分组件样式以适配新主题
This commit is contained in:
2025-08-19 00:08:26 +08:00
parent 8efeb9a5bd
commit 9d9762ef17
23 changed files with 739 additions and 264 deletions

179
src/user/theme/index.tsx Normal file
View File

@@ -0,0 +1,179 @@
import React, { useState, useEffect } from 'react'
import { View, Text } from '@tarojs/components'
import { Cell, CellGroup, Radio } from '@nutui/nutui-react-taro'
import { gradientThemes, GradientTheme, gradientUtils } from '@/styles/gradients'
import Taro from '@tarojs/taro'
import FixedButton from "@/components/FixedButton";
const ThemeSelector: React.FC = () => {
const [selectedTheme, setSelectedTheme] = useState<string>('')
const [currentTheme, setCurrentTheme] = useState<GradientTheme | null>(null)
// 获取当前主题
useEffect(() => {
const savedTheme = Taro.getStorageSync('user_theme') || 'auto'
setSelectedTheme(savedTheme)
if (savedTheme === 'auto') {
// 自动主题根据用户ID生成
const userId = Taro.getStorageSync('userId') || '1'
const theme = gradientUtils.getThemeByUserId(userId)
setCurrentTheme(theme)
} else {
// 手动选择的主题
const theme = gradientThemes.find(t => t.name === savedTheme)
setCurrentTheme(theme || gradientThemes[0])
}
}, [])
// 保存主题设置
const saveTheme = (themeName: string) => {
try {
Taro.setStorageSync('user_theme', themeName)
setSelectedTheme(themeName)
if (themeName === 'auto') {
const userId = Taro.getStorageSync('userId') || '1'
const theme = gradientUtils.getThemeByUserId(userId)
setCurrentTheme(theme)
} else {
const theme = gradientThemes.find(t => t.name === themeName)
setCurrentTheme(theme || gradientThemes[0])
}
Taro.showToast({
title: '主题已保存',
icon: 'success',
})
// 延迟返回,让用户看到效果
setTimeout(() => {
Taro.navigateBack()
}, 1000)
} catch (error) {
Taro.showToast({
title: '保存失败',
icon: 'error',
})
}
}
// 预览主题
const previewTheme = (themeName: string) => {
if (themeName === 'auto') {
const userId = Taro.getStorageSync('userId') || '1'
const theme = gradientUtils.getThemeByUserId(userId)
setCurrentTheme(theme)
} else {
const theme = gradientThemes.find(t => t.name === themeName)
setCurrentTheme(theme || gradientThemes[0])
}
}
return (
<View className="min-h-screen bg-gray-50">
{/* 当前主题预览 */}
{currentTheme && (
<View
className="mx-4 mt-4 rounded-xl p-6 text-center"
style={{
background: currentTheme.background,
color: currentTheme.textColor
}}
>
<Text className="text-lg font-bold mb-2"></Text>
<Text className="text-sm opacity-90 px-2">{currentTheme.description}</Text>
<View className="mt-4 flex justify-center space-x-4">
<View
className="w-8 h-8 rounded-full"
style={{ backgroundColor: currentTheme.primary }}
></View>
{currentTheme.secondary && (
<View
className="w-8 h-8 rounded-full"
style={{ backgroundColor: currentTheme.secondary }}
></View>
)}
</View>
</View>
)}
{/* 主题选择 */}
<View className="mt-4">
<CellGroup>
<Cell
className="px-4 py-2"
title={
<View className="flex items-center justify-between w-full">
<View>
<Text className="font-medium"></Text>
<Text className="text-sm text-gray-500 mt-1">
ID自动选择个性化主题
</Text>
</View>
<Radio
checked={selectedTheme === 'auto'}
onChange={() => {
setSelectedTheme('auto')
previewTheme('auto')
}}
/>
</View>
}
onClick={() => {
setSelectedTheme('auto')
previewTheme('auto')
}}
/>
</CellGroup>
<View className="mt-4">
<Text className="text-sm text-gray-600 px-4 mb-2"></Text>
<CellGroup>
{gradientThemes.map((theme) => (
<Cell
key={theme.name}
className="px-4 py-3"
title={
<View className="flex items-center justify-between w-full">
<View className="flex items-center">
<View
className="w-6 h-6 rounded-full mr-3"
style={{ background: theme.background }}
></View>
<View>
<Text className="font-medium">{theme.description.split(' - ')[0]}</Text>
<Text className="text-sm text-gray-500 mt-1">
{theme.description.split(' - ')[1]}
</Text>
</View>
</View>
<Radio
checked={selectedTheme === theme.name}
onChange={() => {
setSelectedTheme(theme.name)
previewTheme(theme.name)
}}
/>
</View>
}
onClick={() => {
setSelectedTheme(theme.name)
previewTheme(theme.name)
}}
/>
))}
</CellGroup>
</View>
</View>
{/* 保存按钮 */}
<FixedButton text={'保存主题设置'} background={currentTheme?.background || '#1890ff'} onClick={() => saveTheme(selectedTheme)} />
{/* 底部安全区域 */}
<View className="h-20"></View>
</View>
)
}
export default ThemeSelector