wip: 临时提交

This commit is contained in:
Ray.Hao
2025-05-29 10:04:25 +08:00
parent 8962f01b09
commit 913f434a43
10 changed files with 639 additions and 1118 deletions

1
components.d.ts vendored
View File

@@ -27,6 +27,7 @@ declare module 'vue' {
WdCellGroup: typeof import('wot-design-uni/components/wd-cell-group/wd-cell-group.vue')['default']
WdConfigProvider: typeof import('wot-design-uni/components/wd-config-provider/wd-config-provider.vue')['default']
WdDivider: typeof import('wot-design-uni/components/wd-divider/wd-divider.vue')['default']
WdForm: typeof import('wot-design-uni/components/wd-form/wd-form.vue')['default']
WdGrid: typeof import('wot-design-uni/components/wd-grid/wd-grid.vue')['default']
WdGridItem: typeof import('wot-design-uni/components/wd-grid-item/wd-grid-item.vue')['default']
WdIcon: typeof import('wot-design-uni/components/wd-icon/wd-icon.vue')['default']

View File

@@ -20,25 +20,4 @@ onHide(() => {
});
</script>
<style lang="scss">
/* H5 环境样式变量设置 */
:root {
--primary-color: #165dff;
--primary-color-light: #94bfff;
--primary-color-dark: #0e3c9b;
}
/* 小程序环境样式变量设置 */
page {
--primary-color: #165dff;
--primary-color-light: #94bfff;
--primary-color-dark: #0e3c9b;
background: #f8f8f8;
}
/* 动态加载小程序主题色的钩子 */
/* 用于通过小程序原生API获取主题色并应用 */
.theme-container {
display: none;
}
</style>
<style lang="scss"></style>

View File

@@ -1,4 +1,4 @@
import { ref, watch } from "vue";
import { ref, watch, computed } from "vue";
import type { ConfigProviderThemeVars } from "wot-design-uni";
/* 默认的主题色列表 */
@@ -41,83 +41,79 @@ const getStoredThemeColor = (): string => {
}
};
/* 保存主题模式到存储 */
const saveThemeToStorage = (theme: "light" | "dark") => {
try {
uni.setStorageSync(THEME_STORAGE_KEY, theme);
} catch (error) {
console.error("保存主题模式失败:", error);
}
};
/* 主题状态 */
export const theme = ref<"light" | "dark">(getStoredTheme());
export const currentThemeColor = ref<string>(getStoredThemeColor());
/* 保存主题色到存储 */
const saveThemeColorToStorage = (color: string) => {
try {
uni.setStorageSync(THEME_COLOR_STORAGE_KEY, color);
} catch (error) {
console.error("保存主题色失败:", error);
}
};
/* 主题变量(供 ConfigProvider 使用) */
export const themeVars = computed<ConfigProviderThemeVars>(() => ({
colorTheme: currentThemeColor.value,
// 按钮颜色
buttonPrimaryBgColor: currentThemeColor.value,
buttonPrimaryColor: "#ffffff",
// 开关颜色
switchOnBgColor: currentThemeColor.value,
// 其他组件颜色
cellIconColor: currentThemeColor.value,
tagPrimaryBgColor: currentThemeColor.value,
tagPrimaryColor: "#ffffff",
}));
/* 应用主题到根元素 */
const applyThemeToRoot = () => {
// 获取根元素
const root = document.documentElement;
const body = document.body;
/* 应用暗黑模式的 body 样式 */
const applyDarkModeBodyStyle = (isDark: boolean) => {
// #ifdef H5
if (typeof document !== "undefined") {
const body = document.body;
if (isDark) {
body.style.backgroundColor = "#1a1a1a";
body.style.color = "#f5f5f5";
body.classList.add("wot-theme-dark");
} else {
body.style.backgroundColor = "#f8f8f8";
body.style.color = "#333";
body.classList.remove("wot-theme-dark");
}
// 应用暗黑模式
if (theme.value === "dark") {
root.setAttribute("data-theme", "dark");
body.classList.add("wot-theme-dark");
} else {
root.removeAttribute("data-theme");
body.classList.remove("wot-theme-dark");
}
// 应用主题色类
// 移除所有主题色类
root.className = root.className.replace(/theme-color-\w+/g, "").trim();
// 添加当前主题色类
const colorClass = `theme-color-${currentThemeColor.value.replace("#", "")}`;
root.classList.add(colorClass);
// #endif
// #ifdef MP
// 小程序环境设置页面样式
try {
const pages = getCurrentPages();
if (pages.length > 0) {
const currentPage = pages[pages.length - 1];
if (currentPage && currentPage.$vm) {
// 这里可以根据需要设置页面样式
console.log("小程序暗黑模式:", isDark ? "开启" : "关闭");
}
// 小程序环境下通过设置页面的 data-theme 属性
const pages = getCurrentPages();
if (pages.length > 0) {
const currentPage = pages[pages.length - 1] as any;
if (currentPage) {
currentPage.setData?.({
"data-theme": theme.value,
themeColor: currentThemeColor.value,
});
}
} catch (error) {
console.error("设置小程序页面样式失败:", error);
}
// #endif
};
/* 主题状态 */
export const theme = ref<"light" | "dark">(getStoredTheme());
/* 主题变量 */
export const themeVars = ref<ConfigProviderThemeVars>({
colorTheme: getStoredThemeColor(),
});
/* 监听主题模式变化,应用 body 样式 */
/* 监听主题模式变化 */
watch(
theme,
(newTheme) => {
saveThemeToStorage(newTheme);
applyDarkModeBodyStyle(newTheme === "dark");
uni.setStorageSync(THEME_STORAGE_KEY, newTheme);
applyThemeToRoot();
},
{ immediate: true }
);
/* 监听主题色变化,保存到存储 */
/* 监听主题色变化 */
watch(
() => themeVars.value.colorTheme,
currentThemeColor,
(newColor) => {
if (newColor) {
saveThemeColorToStorage(newColor);
}
uni.setStorageSync(THEME_COLOR_STORAGE_KEY, newColor);
applyThemeToRoot();
},
{ immediate: true }
);
@@ -129,31 +125,21 @@ export const toggleTheme = () => {
/* 设置主题色 */
export const setThemeColor = (color: string) => {
themeVars.value = {
...themeVars.value,
colorTheme: color,
};
currentThemeColor.value = color;
};
/* 重置主题 */
export const resetTheme = () => {
theme.value = "light";
setThemeColor(colorColumns[0].value);
currentThemeColor.value = colorColumns[0].value;
};
/* 初始化主题 */
export const initTheme = () => {
// 应用当前主题的 body 样式
applyDarkModeBodyStyle(theme.value === "dark");
// 确保主题变量已正确设置
if (!themeVars.value.colorTheme) {
themeVars.value.colorTheme = getStoredThemeColor();
}
applyThemeToRoot();
console.log("主题初始化完成:", {
mode: theme.value,
color: themeVars.value.colorTheme,
color: currentThemeColor.value,
});
};
@@ -162,6 +148,7 @@ export const useTheme = () => {
return {
theme,
themeVars,
currentThemeColor,
toggleTheme,
setThemeColor,
resetTheme,

View File

@@ -2,8 +2,7 @@ import { createSSRApp } from "vue";
import App from "./App.vue";
import "uno.css";
import "@/styles/global.scss";
import "@/styles/wot-theme.scss";
import "@/styles/theme.scss";
import { setupStore } from "@/store";

View File

@@ -62,33 +62,33 @@
<view class="card-container">
<view class="card-header">
<view class="card-title">
<wd-icon name="tools" size="18" :color="themeStore.primaryColor" />
<wd-icon name="tools" size="18" :color="currentThemeColor" />
<text>常用工具</text>
</view>
</view>
<view class="tools-grid">
<view class="tool-item" @click="navigateToProfile">
<view class="tool-icon">
<wd-icon name="user" size="24" :color="themeStore.primaryColor" />
<wd-icon name="user" size="24" :color="currentThemeColor" />
</view>
<view class="tool-label">个人资料</view>
</view>
<view class="tool-item" @click="navigateToFAQ">
<view class="tool-icon">
<wd-icon name="help-circle" size="24" :color="themeStore.primaryColor" />
<wd-icon name="help-circle" size="24" :color="currentThemeColor" />
</view>
<view class="tool-label">常见问题</view>
</view>
<view class="tool-item" @click="handleQuestionFeedback">
<view class="tool-icon">
<wd-icon name="check-circle" size="24" :color="themeStore.primaryColor" />
<wd-icon name="check-circle" size="24" :color="currentThemeColor" />
</view>
<view class="tool-label">问题反馈</view>
</view>
<view class="tool-item" @click="navigateToAbout">
<view class="tool-icon">
<wd-icon name="info-circle" size="24" :color="themeStore.primaryColor" />
<wd-icon name="info-circle" size="24" :color="currentThemeColor" />
</view>
<view class="tool-label">关于我们</view>
</view>
@@ -99,7 +99,7 @@
<view class="card-container">
<view class="card-header">
<view class="card-title">
<wd-icon name="star" size="18" :color="themeStore.primaryColor" />
<wd-icon name="star" size="18" :color="currentThemeColor" />
<text>推荐服务</text>
</view>
</view>
@@ -107,7 +107,7 @@
<view class="service-item" @click="navigateToSection('services', 'vip')">
<view class="service-left">
<view class="service-icon">
<wd-icon name="dong" size="22" :color="themeStore.primaryColor" />
<wd-icon name="dong" size="22" :color="currentThemeColor" />
</view>
<view class="service-info">
<view class="service-name">会员中心</view>
@@ -119,7 +119,7 @@
<view class="service-item" @click="navigateToSection('services', 'coupon')">
<view class="service-left">
<view class="service-icon">
<wd-icon name="discount" size="22" :color="themeStore.primaryColor" />
<wd-icon name="discount" size="22" :color="currentThemeColor" />
</view>
<view class="service-info">
<view class="service-name">优惠券</view>
@@ -131,7 +131,7 @@
<view class="service-item" @click="navigateToSection('services', 'invite')">
<view class="service-left">
<view class="service-icon">
<wd-icon name="share" size="22" :color="themeStore.primaryColor" />
<wd-icon name="share" size="22" :color="currentThemeColor" />
</view>
<view class="service-info">
<view class="service-name">邀请有礼</view>
@@ -152,14 +152,15 @@
</template>
<script lang="ts" setup>
import { onShow } from "@dcloudio/uni-app";
import { useToast } from "wot-design-uni";
import { useUserStore } from "@/store/modules/user.store";
import { useThemeStore } from "@/store/modules/theme.store";
import { useTheme } from "@/composables/useTheme";
import { computed } from "vue";
const toast = useToast();
const userStore = useUserStore();
const themeStore = useThemeStore();
const { currentThemeColor } = useTheme();
const userInfo = computed(() => userStore.userInfo);
const isLogin = computed(() => !!userInfo.value);
const defaultAvatar = "/static/images/default-avatar.png";
@@ -246,7 +247,7 @@ onShow(() => {
.mine-container {
min-height: 100vh;
padding-bottom: 100rpx;
background-color: #f5f7fa;
background-color: var(--wot-color-bg-page);
}
// 用户信息卡片
@@ -262,7 +263,7 @@ onShow(() => {
left: 0;
z-index: 0;
height: 240rpx;
background: linear-gradient(to bottom, var(--primary-color), var(--primary-color-light));
background: linear-gradient(to bottom, var(--wot-color-theme), var(--primary-color-light));
}
.user-info {
@@ -333,7 +334,7 @@ onShow(() => {
line-height: 32rpx;
color: #fff;
text-align: center;
background-color: #ff4d4f;
background-color: var(--wot-color-danger);
border: 2rpx solid #fff;
border-radius: 16rpx;
}
@@ -347,9 +348,9 @@ onShow(() => {
display: flex;
padding: 30rpx 20rpx;
margin: 20rpx 30rpx;
background: #fff;
background: var(--wot-color-bg-container);
border-radius: 16rpx;
box-shadow: 0 6rpx 16rpx rgba(0, 0, 0, 0.04);
box-shadow: var(--wot-card-shadow);
.stat-item {
display: flex;
@@ -361,19 +362,19 @@ onShow(() => {
margin-bottom: 8rpx;
font-size: 36rpx;
font-weight: 600;
color: #333;
color: var(--wot-color-text);
}
.stat-label {
font-size: 26rpx;
color: #666;
color: var(--wot-color-text-secondary);
}
}
.divider {
width: 1px;
margin: 0 20rpx;
background-color: #eee;
background-color: var(--wot-color-border);
}
}
@@ -381,16 +382,16 @@ onShow(() => {
.card-container {
margin: 24rpx 30rpx;
overflow: hidden;
background: #fff;
background: var(--wot-color-bg-container);
border-radius: 16rpx;
box-shadow: 0 6rpx 16rpx rgba(0, 0, 0, 0.04);
box-shadow: var(--wot-card-shadow);
.card-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 20rpx 24rpx;
border-bottom: 1rpx solid #f5f5f5;
border-bottom: 1rpx solid var(--wot-color-border);
.card-title {
display: flex;
@@ -400,7 +401,7 @@ onShow(() => {
margin-left: 12rpx;
font-size: 28rpx;
font-weight: 600;
color: #333;
color: var(--wot-color-text);
}
}
@@ -481,7 +482,7 @@ onShow(() => {
width: 90rpx;
height: 90rpx;
margin-bottom: 12rpx;
background-color: rgba(var(--primary-color-rgb), 0.08);
background-color: var(--wot-color-bg-light);
border-radius: 18rpx;
transition: transform 0.2s;
@@ -492,7 +493,7 @@ onShow(() => {
.tool-label {
font-size: 24rpx;
color: #555;
color: var(--wot-color-text);
}
}
}
@@ -503,8 +504,13 @@ onShow(() => {
display: flex;
align-items: center;
justify-content: space-between;
padding: 30rpx 24rpx;
border-bottom: 1rpx solid #f5f5f5;
padding: 24rpx;
border-bottom: 1rpx solid var(--wot-color-border);
transition: background-color 0.2s;
&:active {
background-color: var(--wot-color-bg-light);
}
&:last-child {
border-bottom: none;
@@ -518,25 +524,24 @@ onShow(() => {
display: flex;
align-items: center;
justify-content: center;
width: 70rpx;
height: 70rpx;
background-color: rgba(var(--primary-color-rgb), 0.08);
width: 80rpx;
height: 80rpx;
margin-right: 20rpx;
background-color: var(--wot-color-bg-light);
border-radius: 16rpx;
}
.service-info {
margin-left: 20rpx;
.service-name {
margin-bottom: 6rpx;
font-size: 28rpx;
font-weight: 500;
color: #333;
color: var(--wot-color-text);
}
.service-desc {
margin-top: 8rpx;
font-size: 24rpx;
color: #999;
color: var(--wot-color-text-secondary);
}
}
}
@@ -545,7 +550,7 @@ onShow(() => {
// 退出登录按钮
.logout-btn-container {
margin: 60rpx 30rpx;
padding: 20rpx 30rpx;
}
</style>
@@ -560,17 +565,17 @@ onShow(() => {
font-size: 32rpx !important;
font-weight: bold !important;
color: #fff !important;
background-color: var(--primary-color) !important;
border: 2rpx solid var(--primary-color) !important;
background-color: var(--wot-color-theme) !important;
border: none !important;
border-radius: 40rpx !important;
box-shadow: 0 4rpx 12rpx rgba(var(--primary-color-rgb), 0.3) !important;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.15) !important;
}
.btn-login {
width: 160rpx !important;
height: 60rpx !important;
font-size: 26rpx !important;
color: var(--primary-color) !important;
color: var(--wot-color-theme) !important;
background-color: #fff !important;
border: none !important;
border-radius: 30rpx !important;

View File

@@ -7,127 +7,87 @@
</view>
<!-- 暗黑模式设置 -->
<wd-card class="setting-section">
<view class="section-header">
<wd-icon name="moon" size="20" :color="theme === 'dark' ? '#FFD700' : '#666'" />
<text class="section-title">外观模式</text>
<wd-card custom-class="setting-card">
<view class="setting-item">
<view class="setting-info">
<wd-icon name="moon" size="20" :color="currentThemeColor" />
<text class="setting-label">暗黑模式</text>
</view>
<wd-switch :model-value="theme === 'dark'" @change="toggleTheme" />
</view>
<wd-cell title="暗黑模式" :value="theme === 'dark' ? '已开启' : '已关闭'">
<wd-switch :model-value="theme === 'dark'" @change="handleToggleDarkMode" />
</wd-cell>
</wd-card>
<!-- 主题色设置 -->
<wd-card class="setting-section">
<view class="section-header">
<wd-icon name="palette" size="20" color="#666" />
<text class="section-title">主题色</text>
<!-- 主题色选择 -->
<wd-card custom-class="setting-card">
<view class="setting-header">
<wd-icon name="palette" size="20" :color="currentThemeColor" />
<text class="setting-title">主题色</text>
</view>
<!-- 预设颜色选择 -->
<view class="color-section">
<text class="color-label">预设主题色</text>
<view class="color-grid">
<view
v-for="(color, index) in colorColumns"
:key="index"
class="color-item"
:class="{ active: currentThemeColor === color.value }"
@click="handleSelectColor(color.value)"
>
<view
class="color-preview"
:style="{
backgroundColor: color.value,
border: currentThemeColor === color.value ? '3px solid #fff' : '1px solid #e0e0e0',
}"
>
<text v-if="currentThemeColor === color.value" class="check-icon"></text>
</view>
<text class="color-name">{{ color.label }}</text>
<view class="color-grid">
<view
v-for="item in colorColumns"
:key="item.value"
class="color-item"
:class="{ active: currentThemeColor === item.value }"
@click="setThemeColor(item.value)"
>
<view class="color-box" :style="{ backgroundColor: item.value }">
<wd-icon v-if="currentThemeColor === item.value" name="check" size="16" color="#fff" />
</view>
<text class="color-label">{{ item.label }}</text>
</view>
</view>
<!-- 当前主题色显示 -->
<view class="current-theme-section">
<view class="current-theme-item">
<text class="current-theme-label">当前主题色</text>
<view class="current-theme-value">
<view
class="current-color-preview"
:style="{ backgroundColor: currentThemeColor }"
></view>
<text class="current-color-text">{{ currentThemeColor }}</text>
</view>
</view>
</view>
<!-- 自定义颜色 -->
<wd-cell title="自定义颜色" is-link @click="showCustomInput">
<wd-icon name="edit" size="16" color="#999" />
</wd-cell>
</wd-card>
<!-- 预览区域 -->
<wd-card class="setting-section">
<view class="section-header">
<wd-icon name="eye" size="20" color="#666" />
<text class="section-title">效果预览</text>
<!-- 自定义颜色 -->
<wd-card custom-class="setting-card">
<view class="setting-item" @click="showCustomColorPopup = true">
<view class="setting-info">
<wd-icon name="edit" size="20" :color="currentThemeColor" />
<text class="setting-label">自定义颜色</text>
</view>
<view class="custom-color-preview">
<view class="color-box small" :style="{ backgroundColor: currentThemeColor }"></view>
<text class="color-value">{{ currentThemeColor }}</text>
<wd-icon name="arrow-right" size="14" color="#999" />
</view>
</view>
</wd-card>
<wd-divider />
<wd-grid :column="2" border>
<wd-grid-item>
<!-- 预览效果 -->
<wd-card custom-class="setting-card">
<view class="preview-section">
<text class="preview-title">预览效果</text>
<view class="preview-items">
<wd-button type="primary" size="small">主要按钮</wd-button>
</wd-grid-item>
<wd-grid-item>
<text class="preview-text" :style="{ color: currentThemeColor }">主题色文本</text>
</wd-grid-item>
<wd-grid-item>
<view class="preview-border" :style="{ borderColor: currentThemeColor }">主题色边框</view>
</wd-grid-item>
<wd-grid-item>
<wd-tag type="primary" size="small">标签</wd-tag>
</wd-grid-item>
</wd-grid>
<wd-button type="primary" plain size="small">次要按钮</wd-button>
<wd-tag type="primary">标签</wd-tag>
</view>
</view>
</wd-card>
<!-- 操作按钮 -->
<wd-card class="action-section">
<wd-button type="info" size="large" block @click="handleResetTheme">重置为默认主题</wd-button>
</wd-card>
<!-- 重置按钮 -->
<view class="action-buttons">
<wd-button block @click="handleReset">恢复默认</wd-button>
</view>
<!-- 自定义颜色输入弹窗 -->
<wd-popup v-model="showCustomColorInput" position="bottom" :safe-area-inset-bottom="true">
<!-- 自定义颜色弹窗 -->
<wd-popup v-model="showCustomColorPopup" position="bottom" closeable>
<view class="custom-color-popup">
<view class="popup-header">
<text class="popup-title">自定义主题色</text>
<wd-icon name="close" size="20" color="#999" @click="showCustomColorInput = false" />
</view>
<wd-divider />
<view class="color-input-section">
<view class="input-label">请输入十六进制颜色值</view>
<view class="input-container">
<view class="color-preview-small" :style="{ backgroundColor: customColor }"></view>
<wd-input
v-model="customColor"
placeholder="例如: #165DFF"
:maxlength="7"
class="color-input"
/>
</view>
<view class="input-tip">支持格式#RGB #RRGGBB</view>
<view class="color-preview-large" :style="{ backgroundColor: customColor }"></view>
<wd-input v-model="customColor" placeholder="请输入颜色值,如 #FF6B6B" clearable />
<text class="input-tip">支持 HEX 格式颜色值</text>
</view>
<wd-divider />
<view class="popup-actions">
<wd-button type="info" size="large" @click="showCustomColorInput = false">取消</wd-button>
<wd-button type="primary" size="large" @click="applyCustomColor">应用</wd-button>
<wd-button type="info" block @click="showCustomColorPopup = false">取消</wd-button>
<wd-button type="primary" block @click="applyCustomColor">应用</wd-button>
</view>
</view>
</wd-popup>
@@ -135,119 +95,58 @@
</template>
<script lang="ts" setup>
import { onLoad, onShow } from "@dcloudio/uni-app";
import { useTheme, colorColumns } from "@/composables/useTheme";
import { ref, computed, onMounted, nextTick } from "vue";
import { ref } from "vue";
import { onShow } from "@dcloudio/uni-app";
import { useTheme } from "@/composables/useTheme";
const { theme, themeVars, toggleTheme, setThemeColor, resetTheme } = useTheme();
const { theme, currentThemeColor, colorColumns, toggleTheme, setThemeColor, resetTheme } =
useTheme();
// 自定义颜色输入
const customColor = ref("");
const showCustomColorInput = ref(false);
// 当前选中的主题色
const currentThemeColor = computed(() => {
return themeVars.value.colorTheme || colorColumns[0].value;
});
// 选择预设颜色
const handleSelectColor = (color: string) => {
setThemeColor(color);
customColor.value = color;
// 提示
uni.showToast({
title: "主题色已更新",
icon: "success",
duration: 1500,
});
};
// 显示自定义颜色输入
const showCustomInput = () => {
showCustomColorInput.value = true;
customColor.value = currentThemeColor.value;
};
// 自定义颜色相关
const showCustomColorPopup = ref(false);
const customColor = ref(currentThemeColor.value);
// 应用自定义颜色
const applyCustomColor = () => {
// 验证颜色格式
const colorRegex = /^#([0-9A-F]{6}|[0-9A-F]{3})$/i;
const colorRegex = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/;
if (!colorRegex.test(customColor.value)) {
uni.showToast({
title: "请输入有效的颜色",
title: "请输入正确的颜色格式",
icon: "none",
duration: 2000,
});
return;
}
// 转换3位颜色值为6位
let color = customColor.value;
if (color.length === 4) {
color = "#" + color[1] + color[1] + color[2] + color[2] + color[3] + color[3];
}
setThemeColor(color);
showCustomColorInput.value = false;
// 提示
setThemeColor(customColor.value);
showCustomColorPopup.value = false;
uni.showToast({
title: "自定义主题色已应用",
title: "主题色已更新",
icon: "success",
duration: 1500,
});
};
// 重置为默认主题
const handleResetTheme = () => {
// 重置主题
const handleReset = () => {
uni.showModal({
title: "确认重置",
content: "确定要重置为默认主题吗?",
title: "提示",
content: "确定要恢复默认主题吗?",
success: (res) => {
if (res.confirm) {
resetTheme();
customColor.value = colorColumns[0].value;
customColor.value = currentThemeColor.value;
uni.showToast({
title: "已重置为默认主题",
title: "已恢复默认",
icon: "success",
duration: 1500,
});
}
},
});
};
// 切换暗黑模式
const handleToggleDarkMode = () => {
toggleTheme();
nextTick(() => {
uni.showToast({
title: `已切换到${theme.value === "dark" ? "暗黑" : "浅色"}模式`,
icon: "success",
duration: 1500,
});
});
};
onLoad(() => {
// 初始化自定义颜色输入框
customColor.value = currentThemeColor.value;
});
onMounted(() => {
// 初始化自定义颜色输入框
customColor.value = currentThemeColor.value;
});
// 页面显示时确保主题色同步
// 页面显示时更新自定义颜色值
onShow(() => {
customColor.value = currentThemeColor.value;
console.log("主题设置页面显示,当前主题:", {
mode: theme.value,
color: currentThemeColor.value,
});
});
</script>
@@ -255,384 +154,180 @@ onShow(() => {
.theme-settings-container {
min-height: 100vh;
padding: 20rpx;
background-color: var(--wot-color-bg-light, #f8f9fa);
transition: background-color 0.3s ease;
// 强制 Wot 组件应用暗黑模式样式
:deep(.wd-card) {
background: var(--wot-card-bg-color, #fff);
border-radius: 16rpx;
box-shadow: var(--wot-card-shadow, 0 2rpx 12rpx rgba(0, 0, 0, 0.05));
transition: background-color 0.3s ease;
}
:deep(.wd-cell) {
color: var(--wot-color-text, #333);
background-color: var(--wot-card-bg-color, #fff);
.wd-cell__title {
color: var(--wot-color-text, #333) !important;
}
.wd-cell__value {
color: var(--wot-color-text-secondary, #666) !important;
}
.wd-cell__right-icon {
color: var(--wot-color-text-secondary, #999) !important;
}
}
:deep(.wd-grid-item) {
color: var(--wot-color-text, #333) !important;
background-color: var(--wot-card-bg-color, #fff) !important;
}
// 专门为颜色预览块重置背景色
:deep(.color-item) {
background-color: transparent !important;
.color-preview {
background-color: inherit !important;
}
}
:deep(.wd-button) {
&[type="primary"] {
color: #fff !important;
background-color: var(--wot-color-theme, #165dff) !important;
}
&[type="info"] {
color: #fff !important;
background-color: var(--wot-color-info, #909399) !important;
}
}
:deep(.wd-input) {
color: var(--wot-color-text, #333) !important;
background-color: var(--wot-card-bg-color, #fff) !important;
}
:deep(.wd-popup) {
background-color: var(--wot-popup-bg-color, #fff) !important;
}
.custom-color-popup {
padding: 40rpx 30rpx;
background: var(--wot-popup-bg-color, #fff);
border-radius: 20rpx 20rpx 0 0;
}
background-color: var(--wot-color-bg-page);
}
.page-header {
padding: 40rpx 20rpx;
margin-bottom: 30rpx;
text-align: center;
background: linear-gradient(135deg, var(--wot-color-theme, #165dff) 0%, #667eea 100%);
background: linear-gradient(135deg, var(--wot-color-theme) 0%, var(--primary-color-light) 100%);
border-radius: 16rpx;
.page-title {
display: block;
margin-bottom: 10rpx;
font-size: 36rpx;
font-weight: bold;
color: #fff;
}
.page-subtitle {
font-size: 26rpx;
color: rgba(255, 255, 255, 0.8);
}
}
.page-title {
display: block;
margin-bottom: 10rpx;
font-size: 36rpx;
font-weight: bold;
color: #fff;
.setting-card {
margin-bottom: 20rpx;
background-color: var(--wot-color-bg-container) !important;
border-radius: 16rpx !important;
:deep(.wd-card__body) {
padding: 30rpx !important;
}
}
.page-subtitle {
font-size: 26rpx;
color: rgba(255, 255, 255, 0.8);
}
.setting-section {
margin-bottom: 30rpx;
}
.section-header {
.setting-item {
display: flex;
align-items: center;
padding: 30rpx 30rpx 20rpx;
border-bottom: 1rpx solid var(--wot-color-border, #f0f0f0);
justify-content: space-between;
.setting-info {
display: flex;
gap: 20rpx;
align-items: center;
}
.setting-label {
font-size: 30rpx;
color: var(--wot-color-text);
}
}
.section-title {
margin-left: 12rpx;
font-size: 32rpx;
font-weight: 600;
color: var(--wot-color-text, #333);
}
.setting-header {
display: flex;
gap: 20rpx;
align-items: center;
margin-bottom: 30rpx;
.color-section {
padding: 30rpx;
}
.color-label {
margin-bottom: 20rpx;
font-size: 28rpx;
color: var(--wot-color-text-secondary, #666);
.setting-title {
font-size: 30rpx;
font-weight: 600;
color: var(--wot-color-text);
}
}
.color-grid {
display: flex;
flex-wrap: wrap;
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20rpx;
justify-content: space-between;
}
.color-item {
position: relative;
display: flex;
flex-direction: column;
gap: 10rpx;
align-items: center;
justify-content: center;
width: calc(25% - 15rpx);
padding: 10rpx;
cursor: pointer;
transition: all 0.3s ease;
.color-preview {
position: relative;
&.active .color-box {
box-shadow: 0 6rpx 20rpx rgba(0, 0, 0, 0.15);
transform: scale(1.1);
}
.color-box {
display: flex;
align-items: center;
justify-content: center;
width: 60rpx;
height: 60rpx;
margin-bottom: 8rpx;
border-radius: 12rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
}
.check-icon {
font-size: 24rpx;
font-weight: bold;
color: #fff;
text-shadow: 0 1rpx 2rpx rgba(0, 0, 0, 0.5);
}
.color-name {
font-size: 22rpx;
line-height: 1.2;
color: var(--wot-color-text-secondary, #666);
text-align: center;
}
&.active .color-preview {
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.2);
transform: scale(1.05);
}
&:active .color-preview {
transform: scale(0.95);
}
}
.current-theme-section {
padding: 30rpx;
}
.current-theme-item {
display: flex;
align-items: center;
justify-content: space-between;
}
.current-theme-label {
font-size: 28rpx;
color: var(--wot-color-text-secondary, #666);
}
.current-theme-value {
display: flex;
align-items: center;
}
.current-color-preview {
width: 40rpx;
height: 40rpx;
border: 2rpx solid var(--wot-color-border, #f0f0f0);
border-radius: 8rpx;
}
.current-color-text {
margin-left: 10rpx;
font-size: 28rpx;
font-weight: 500;
}
.preview-text {
font-size: 28rpx;
font-weight: 500;
}
.preview-border {
display: flex;
align-items: center;
justify-content: center;
width: 200rpx;
height: 60rpx;
font-size: 26rpx;
color: var(--wot-color-text-secondary, #666);
border: 2rpx solid;
border-radius: 8rpx;
}
.action-section {
:deep(.wd-card) {
padding: 30rpx;
background: var(--wot-card-bg-color, #fff);
border-radius: 16rpx;
box-shadow: var(--wot-card-shadow, 0 2rpx 12rpx rgba(0, 0, 0, 0.05));
}
}
.popup-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 30rpx;
}
.popup-title {
font-size: 32rpx;
font-weight: 600;
color: var(--wot-color-text, #333);
}
.color-input-section {
margin-bottom: 40rpx;
}
.input-label {
margin-bottom: 20rpx;
font-size: 28rpx;
color: var(--wot-color-text-secondary, #666);
}
.input-container {
display: flex;
gap: 20rpx;
align-items: center;
margin-bottom: 10rpx;
}
.color-preview-small {
flex-shrink: 0;
width: 60rpx;
height: 60rpx;
border: 2rpx solid var(--wot-color-border, #f0f0f0);
border-radius: 8rpx;
}
.color-input {
flex: 1;
}
.input-tip {
margin-left: 80rpx;
font-size: 24rpx;
color: var(--wot-color-text-placeholder, #999);
}
.popup-actions {
display: flex;
gap: 20rpx;
}
/* 响应式布局 */
@media (max-width: 750rpx) {
.color-grid {
grid-template-columns: repeat(3, 1fr);
}
}
@media (max-width: 600rpx) {
.color-grid {
grid-template-columns: repeat(2, 1fr);
}
}
// 全局暗黑模式适配(针对当前页面)
:global([data-theme="dark"]) .theme-settings-container {
color: var(--wot-color-text, #fff) !important;
background-color: var(--wot-color-bg, #1a1a1a) !important;
.page-header {
background: linear-gradient(135deg, var(--wot-color-theme, #165dff) 0%, #4a5568 100%);
}
.section-title {
color: var(--wot-color-text, #fff) !important;
&.small {
width: 40rpx;
height: 40rpx;
}
}
.color-label {
color: var(--wot-color-text-secondary, #d1d5db) !important;
font-size: 22rpx;
color: var(--wot-color-text-secondary);
}
}
.custom-color-preview {
display: flex;
gap: 15rpx;
align-items: center;
.color-value {
font-size: 26rpx;
color: var(--wot-color-text-secondary);
}
}
.preview-section {
.preview-title {
display: block;
margin-bottom: 20rpx;
font-size: 28rpx;
color: var(--wot-color-text-secondary);
}
.preview-text {
color: var(--wot-color-text, #fff) !important;
.preview-items {
display: flex;
flex-wrap: wrap;
gap: 20rpx;
align-items: center;
}
}
.preview-border {
color: var(--wot-color-text-secondary, #d1d5db) !important;
}
.action-buttons {
padding: 0 20rpx;
margin-top: 40rpx;
}
.popup-title {
color: var(--wot-color-text, #fff) !important;
}
.custom-color-popup {
padding: 40rpx 30rpx;
background-color: var(--wot-color-bg-container);
.input-label {
color: var(--wot-color-text-secondary, #d1d5db) !important;
}
.popup-header {
margin-bottom: 40rpx;
text-align: center;
.input-tip {
color: var(--wot-color-text-placeholder, #9ca3af) !important;
}
:deep(.wd-card) {
background: var(--wot-card-bg-color, #2a2a2a) !important;
}
:deep(.wd-cell) {
color: var(--wot-color-text, #fff) !important;
background-color: var(--wot-card-bg-color, #2a2a2a) !important;
.wd-cell__title {
color: var(--wot-color-text, #fff) !important;
}
.wd-cell__value {
color: var(--wot-color-text-secondary, #d1d5db) !important;
}
.wd-cell__right-icon {
color: var(--wot-color-text-secondary, #9ca3af) !important;
.popup-title {
font-size: 32rpx;
font-weight: 600;
color: var(--wot-color-text);
}
}
:deep(.wd-grid-item) {
color: var(--wot-color-text, #fff) !important;
background-color: var(--wot-card-bg-color, #2a2a2a) !important;
.color-input-section {
margin-bottom: 40rpx;
.color-preview-large {
width: 100%;
height: 120rpx;
margin-bottom: 30rpx;
border: 2rpx solid var(--wot-color-border);
border-radius: 16rpx;
}
.input-tip {
display: block;
margin-top: 15rpx;
font-size: 24rpx;
color: var(--wot-color-text-placeholder);
text-align: center;
}
}
// 专门为颜色预览块重置背景色
:deep(.color-item) {
background-color: transparent !important;
}
:deep(.wd-input) {
color: var(--wot-color-text, #fff) !important;
background-color: var(--wot-card-bg-color, #2a2a2a) !important;
}
:deep(.wd-popup) {
background-color: var(--wot-popup-bg-color, #2a2a2a) !important;
}
.custom-color-popup {
background: var(--wot-popup-bg-color, #2a2a2a) !important;
.popup-actions {
display: flex;
gap: 20rpx;
}
}
</style>

View File

@@ -0,0 +1,148 @@
/**
* 微信授权服务
* 处理微信登录授权、获取用户信息等功能
*/
import { ref } from "vue";
import { getAccessToken } from "@/utils/auth";
// 定义微信授权状态
export const wxAuthState = ref({
isLogining: false,
authDenied: false,
});
/**
* 获取微信登录凭证
* @returns Promise 返回登录凭证code
*/
export function getWxLoginCode(): Promise<string> {
return new Promise((resolve, reject) => {
// #ifdef MP-WEIXIN
uni.login({
provider: "weixin",
success: (res) => {
if (res.code) {
resolve(res.code);
} else {
reject(new Error("获取微信登录凭证失败"));
}
},
fail: (err) => {
reject(err);
},
});
// #endif
// #ifndef MP-WEIXIN
reject(new Error("当前环境不支持微信登录"));
// #endif
});
}
/**
* 获取微信用户手机号
* @param e 微信授权返回的事件对象
* @returns Promise 返回包含加密数据的对象
*/
export function getWxPhoneNumber(
e: any
): Promise<{ code: string; encryptedData?: string; iv?: string }> {
return new Promise((resolve, reject) => {
wxAuthState.value.isLogining = true;
// 判断授权是否成功
if (e.detail.errMsg !== "getPhoneNumber:ok") {
wxAuthState.value.isLogining = false;
wxAuthState.value.authDenied = true;
reject(new Error("用户拒绝授权"));
return;
}
// 获取登录凭证code
getWxLoginCode()
.then((code) => {
// 在微信小程序环境下可以获取encryptedData和iv
// #ifdef MP-WEIXIN
resolve({
code,
encryptedData: e.detail.encryptedData,
iv: e.detail.iv,
});
// #endif
// 其他环境或新版本接口
// #ifndef MP-WEIXIN
resolve({
code,
// 新版本接口在e.detail.code中包含手机号获取凭证
...(e.detail.code ? { phoneCode: e.detail.code } : {}),
});
// #endif
})
.catch((err) => {
reject(err);
})
.finally(() => {
wxAuthState.value.isLogining = false;
});
});
}
/**
* 检查微信会话有效性
* 检查本地token是否存在如存在则检查其有效性
*/
export function checkWxSession(): Promise<boolean> {
return new Promise((resolve) => {
const token = getAccessToken();
if (!token) {
resolve(false);
return;
}
// 调用后端接口验证token有效性
uni.request({
url: "/api/v1/auth/check-session",
method: "GET",
header: {
Authorization: `Bearer ${token}`,
},
success: (res: any) => {
if (res.statusCode === 200 && res.data.valid) {
resolve(true);
} else {
resolve(false);
}
},
fail: () => {
resolve(false);
},
});
});
}
/**
* 获取微信用户信息(如头像、昵称等)
* 注意此接口在2021年4月后的小程序新版本中需要额外授权
*/
export function getWxUserProfile(): Promise<any> {
return new Promise((resolve, reject) => {
// #ifdef MP-WEIXIN
uni.getUserProfile({
desc: "用于完善用户资料",
success: (res) => {
resolve(res.userInfo);
},
fail: (err) => {
reject(err);
},
});
// #endif
// #ifndef MP-WEIXIN
reject(new Error("当前环境不支持获取用户信息"));
// #endif
});
}

View File

@@ -1,244 +0,0 @@
/**
* 全局样式变量
*/
/*
* 主题颜色 - 会被theme.ts中的动态设置覆盖
* 这里作为默认值和IDE提示
*/
:root {
/* 主色 */
--primary-color: #165dff;
--primary-color-light: #94bfff;
--primary-color-dark: #0e3c9b;
/* 功能色 */
--success-color: #0fc6c2;
--warning-color: #ff7d00;
--danger-color: #f5222d;
--info-color: #86909c;
/* 文字颜色 */
--text-primary: #1d2129;
--text-regular: #4e5969;
--text-secondary: #86909c;
--text-placeholder: #c9cdd4;
--text-inverse: #ffffff;
/* 边框颜色 */
--border-color: #e5e6eb;
--border-light: #f2f3f5;
/* 背景颜色 */
--bg-white: #ffffff;
--bg-light: #f2f3f5;
--bg-gray: #f7f8fa;
}
/**
* 主题相关的通用类
*/
/* 主色文本 */
.text-primary {
color: var(--primary-color) !important;
}
/* 主色背景 */
.bg-primary {
color: #fff;
background-color: var(--primary-color) !important;
}
/* 主色边框 */
.border-primary {
border-color: var(--primary-color) !important;
}
/* 主色按钮样式 */
.btn-primary {
color: #fff;
background-color: var(--primary-color);
border: none;
border-radius: 8rpx;
transition: opacity 0.3s;
&:active {
opacity: 0.8;
}
}
/* 圆角按钮 */
.btn-rounded {
border-radius: 45rpx !important;
}
/* 次级按钮 */
.btn-secondary {
color: var(--primary-color);
background-color: #fff;
border: 1px solid var(--primary-color);
border-radius: 8rpx;
transition: background-color 0.3s;
&:active {
background-color: rgba(22, 93, 255, 0.05);
}
}
/**
* 字体大小
*/
.font-xs {
font-size: 24rpx;
}
.font-sm {
font-size: 28rpx;
}
.font-md {
font-size: 32rpx;
}
.font-lg {
font-size: 36rpx;
}
.font-xl {
font-size: 40rpx;
}
/**
* 边距辅助类
*/
.mt-10 {
margin-top: 10rpx;
}
.mt-20 {
margin-top: 20rpx;
}
.mt-30 {
margin-top: 30rpx;
}
.mt-40 {
margin-top: 40rpx;
}
.mb-10 {
margin-bottom: 10rpx;
}
.mb-20 {
margin-bottom: 20rpx;
}
.mb-30 {
margin-bottom: 30rpx;
}
.mb-40 {
margin-bottom: 40rpx;
}
.ml-10 {
margin-left: 10rpx;
}
.ml-20 {
margin-left: 20rpx;
}
.ml-30 {
margin-left: 30rpx;
}
.ml-40 {
margin-left: 40rpx;
}
.mr-10 {
margin-right: 10rpx;
}
.mr-20 {
margin-right: 20rpx;
}
.mr-30 {
margin-right: 30rpx;
}
.mr-40 {
margin-right: 40rpx;
}
.p-10 {
padding: 10rpx;
}
.p-20 {
padding: 20rpx;
}
.p-30 {
padding: 30rpx;
}
.p-40 {
padding: 40rpx;
}
/**
* 布局辅助类
*/
.flex {
display: flex;
}
.flex-wrap {
flex-wrap: wrap;
}
.flex-column {
flex-direction: column;
}
.items-center {
align-items: center;
}
.items-start {
align-items: flex-start;
}
.items-end {
align-items: flex-end;
}
.justify-center {
justify-content: center;
}
.justify-between {
justify-content: space-between;
}
.justify-around {
justify-content: space-around;
}
.justify-start {
justify-content: flex-start;
}
.justify-end {
justify-content: flex-end;
}
/**
* 其他辅助类
*/
.text-center {
text-align: center;
}
.text-left {
text-align: left;
}
.text-right {
text-align: right;
}
.rounded-sm {
border-radius: 4rpx;
}
.rounded {
border-radius: 8rpx;
}
.rounded-lg {
border-radius: 16rpx;
}
.rounded-xl {
border-radius: 24rpx;
}
.rounded-full {
border-radius: 9999rpx;
}

186
src/styles/theme.scss Normal file
View File

@@ -0,0 +1,186 @@
/**
* 统一主题系统
* 简洁易懂,一个文件搞定所有主题
*/
/* 亮色主题(默认) */
:root,
page {
/* ===== 主题色 ===== */
--wot-color-theme: #165dff;
--primary-color: var(--wot-color-theme);
--primary-color-light: #94bfff;
--primary-color-dark: #0e3c9b;
/* ===== 功能色 ===== */
--wot-color-success: #0fc6c2;
--wot-color-warning: #ff7d00;
--wot-color-danger: #f5222d;
--wot-color-info: #86909c;
/* ===== 文本颜色 ===== */
--wot-color-text: #1d2129;
--wot-color-text-secondary: #4e5969;
--wot-color-text-placeholder: #86909c;
--wot-color-text-disabled: #c9cdd4;
/* ===== 背景颜色 ===== */
--wot-color-bg: #ffffff;
--wot-color-bg-page: #f5f7fa;
--wot-color-bg-light: #f8f9fa;
--wot-color-bg-container: #ffffff;
/* ===== 边框颜色 ===== */
--wot-color-border: #e5e6eb;
--wot-color-border-light: #f2f3f5;
/* ===== 组件专用变量 ===== */
--wot-card-bg-color: var(--wot-color-bg-container);
--wot-card-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
--wot-cell-bg-color: var(--wot-color-bg-container);
--wot-popup-bg-color: var(--wot-color-bg-container);
--wot-navbar-bg-color: var(--wot-color-bg-container);
--wot-tabbar-bg-color: var(--wot-color-bg-container);
}
/* 暗黑主题 */
[data-theme="dark"],
[data-theme="dark"] page,
.wot-theme-dark,
.wot-theme-dark page {
/* ===== 主题色(暗黑模式下稍微调亮) ===== */
--wot-color-theme: #4080ff;
--primary-color: var(--wot-color-theme);
--primary-color-light: #6fa0ff;
--primary-color-dark: #2060df;
/* ===== 功能色 ===== */
--wot-color-success: #1dd1cc;
--wot-color-warning: #ff8c1a;
--wot-color-danger: #ff4757;
--wot-color-info: #9ca3af;
/* ===== 文本颜色 ===== */
--wot-color-text: #ffffff;
--wot-color-text-secondary: #d1d5db;
--wot-color-text-placeholder: #9ca3af;
--wot-color-text-disabled: #6b7280;
/* ===== 背景颜色 ===== */
--wot-color-bg: #1a1a1a;
--wot-color-bg-page: #0f0f0f;
--wot-color-bg-light: #2a2a2a;
--wot-color-bg-container: #1f1f1f;
/* ===== 边框颜色 ===== */
--wot-color-border: #404040;
--wot-color-border-light: #606060;
/* ===== 组件专用变量 ===== */
--wot-card-bg-color: var(--wot-color-bg-container);
--wot-card-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.3);
--wot-cell-bg-color: var(--wot-color-bg-container);
--wot-popup-bg-color: var(--wot-color-bg-container);
--wot-navbar-bg-color: var(--wot-color-bg-container);
--wot-tabbar-bg-color: var(--wot-color-bg-container);
}
/* 动态主题色类(这些会被 useTheme 动态应用到根元素) */
.theme-color-165DFF {
--wot-color-theme: #165dff;
--primary-color: #165dff;
}
.theme-color-0FC6C2 {
--wot-color-theme: #0fc6c2;
--primary-color: #0fc6c2;
}
.theme-color-722ED1 {
--wot-color-theme: #722ed1;
--primary-color: #722ed1;
}
.theme-color-F5222D {
--wot-color-theme: #f5222d;
--primary-color: #f5222d;
}
.theme-color-FA8C16 {
--wot-color-theme: #fa8c16;
--primary-color: #fa8c16;
}
.theme-color-FADB14 {
--wot-color-theme: #fadb14;
--primary-color: #fadb14;
}
.theme-color-52C41A {
--wot-color-theme: #52c41a;
--primary-color: #52c41a;
}
.theme-color-EB2F96 {
--wot-color-theme: #eb2f96;
--primary-color: #eb2f96;
}
.theme-color-13C2C2 {
--wot-color-theme: #13c2c2;
--primary-color: #13c2c2;
}
.theme-color-1890FF {
--wot-color-theme: #1890ff;
--primary-color: #1890ff;
}
.theme-color-CD5C5C {
--wot-color-theme: #cd5c5c;
--primary-color: #cd5c5c;
}
.theme-color-228B22 {
--wot-color-theme: #228b22;
--primary-color: #228b22;
}
/* 全局基础样式 */
page {
color: var(--wot-color-text);
background-color: var(--wot-color-bg-page);
transition:
background-color 0.3s ease,
color 0.3s ease;
}
/* H5 环境下的 body 样式 */
/* #ifdef H5 */
body {
color: var(--wot-color-text);
background-color: var(--wot-color-bg-page);
transition:
background-color 0.3s ease,
color 0.3s ease;
}
/* #endif */
/* 通用组件样式重置 */
view,
text,
button,
input,
textarea {
transition:
background-color 0.3s ease,
color 0.3s ease,
border-color 0.3s ease;
}
/* 确保所有 Wot 组件使用主题变量 */
:deep(.wd-button--primary) {
background-color: var(--wot-color-theme) !important;
border-color: var(--wot-color-theme) !important;
}
:deep(.wd-cell) {
background-color: var(--wot-cell-bg-color) !important;
}
:deep(.wd-navbar) {
background-color: var(--wot-navbar-bg-color) !important;
}
:deep(.wd-tabbar) {
background-color: var(--wot-tabbar-bg-color) !important;
}

View File

@@ -1,235 +0,0 @@
/**
* Wot Design Uni 主题变量定制
* 基于 ConfigProvider 的 CSS 变量系统
*/
/*
* 全局 Wot 主题变量
* 这些变量会被 ConfigProvider 自动应用到所有 Wot 组件
*/
:root,
page {
/* ===== 主题色系 ===== */
--wot-color-theme: #165dff;
--wot-color-success: #0fc6c2;
--wot-color-warning: #ff7d00;
--wot-color-danger: #f5222d;
--wot-color-info: #86909c;
/* ===== 中性色系 ===== */
--wot-color-white: #ffffff;
--wot-color-black: #000000;
--wot-color-gray-1: #f7f8fa;
--wot-color-gray-2: #f2f3f5;
--wot-color-gray-3: #e5e6eb;
--wot-color-gray-4: #c9cdd4;
--wot-color-gray-5: #86909c;
--wot-color-gray-6: #4e5969;
--wot-color-gray-7: #272e3b;
--wot-color-gray-8: #1d2129;
/* ===== 文本颜色 ===== */
--wot-color-text: #1d2129;
--wot-color-text-secondary: #4e5969;
--wot-color-text-placeholder: #86909c;
--wot-color-text-disabled: #c9cdd4;
/* ===== 背景颜色 ===== */
--wot-color-bg: #ffffff;
--wot-color-bg-light: #f7f8fa;
--wot-color-bg-dark: #f2f3f5;
/* ===== 边框颜色 ===== */
--wot-color-border: #e5e6eb;
--wot-color-border-light: #f2f3f5;
/* ===== 按钮相关变量 ===== */
--wot-button-primary-bg-color: var(--wot-color-theme);
--wot-button-primary-color: #ffffff;
--wot-button-primary-border-color: var(--wot-color-theme);
--wot-button-success-bg-color: var(--wot-color-success);
--wot-button-success-color: #ffffff;
--wot-button-success-border-color: var(--wot-color-success);
--wot-button-warning-bg-color: var(--wot-color-warning);
--wot-button-warning-color: #ffffff;
--wot-button-warning-border-color: var(--wot-color-warning);
--wot-button-danger-bg-color: var(--wot-color-danger);
--wot-button-danger-color: #ffffff;
--wot-button-danger-border-color: var(--wot-color-danger);
--wot-button-info-bg-color: var(--wot-color-info);
--wot-button-info-color: #ffffff;
--wot-button-info-border-color: var(--wot-color-info);
/* ===== 输入框相关变量 ===== */
--wot-input-border-color: var(--wot-color-border);
--wot-input-focus-border-color: var(--wot-color-theme);
--wot-input-placeholder-color: var(--wot-color-text-placeholder);
--wot-input-disabled-bg-color: var(--wot-color-bg-light);
/* ===== 开关相关变量 ===== */
--wot-switch-on-bg-color: var(--wot-color-theme);
--wot-switch-off-bg-color: var(--wot-color-gray-3);
/* ===== 卡片相关变量 ===== */
--wot-card-bg-color: #ffffff;
--wot-card-border-color: var(--wot-color-border);
--wot-card-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
/* ===== Cell 相关变量 ===== */
--wot-cell-bg-color: #ffffff;
--wot-cell-border-color: var(--wot-color-border);
--wot-cell-title-color: var(--wot-color-text);
--wot-cell-value-color: var(--wot-color-text-secondary);
/* ===== 标签相关变量 ===== */
--wot-tag-primary-bg-color: var(--wot-color-theme);
--wot-tag-primary-color: #ffffff;
--wot-tag-success-bg-color: var(--wot-color-success);
--wot-tag-success-color: #ffffff;
--wot-tag-warning-bg-color: var(--wot-color-warning);
--wot-tag-warning-color: #ffffff;
--wot-tag-danger-bg-color: var(--wot-color-danger);
--wot-tag-danger-color: #ffffff;
/* ===== 图标相关变量 ===== */
--wot-icon-color: var(--wot-color-text-secondary);
/* ===== 分割线相关变量 ===== */
--wot-divider-color: var(--wot-color-border);
/* ===== 弹窗相关变量 ===== */
--wot-popup-bg-color: #ffffff;
--wot-popup-border-radius: 16rpx;
/* ===== 网格相关变量 ===== */
--wot-grid-border-color: var(--wot-color-border);
}
/* ===== 暗黑模式变量 ===== */
[data-theme="dark"],
.wot-theme-dark {
/* 主题色在暗黑模式下稍微调亮 */
--wot-color-theme: #4080ff;
--wot-color-success: #1dd1cc;
--wot-color-warning: #ff8c1a;
--wot-color-danger: #ff4757;
--wot-color-info: #9ca3af;
/* 中性色系 - 暗黑模式 */
--wot-color-white: #1a1a1a;
--wot-color-black: #ffffff;
--wot-color-gray-1: #2a2a2a;
--wot-color-gray-2: #404040;
--wot-color-gray-3: #606060;
--wot-color-gray-4: #808080;
--wot-color-gray-5: #9ca3af;
--wot-color-gray-6: #d1d5db;
--wot-color-gray-7: #e5e7eb;
--wot-color-gray-8: #f3f4f6;
/* 文本颜色 - 暗黑模式 */
--wot-color-text: #ffffff;
--wot-color-text-secondary: #d1d5db;
--wot-color-text-placeholder: #9ca3af;
--wot-color-text-disabled: #6b7280;
/* 背景颜色 - 暗黑模式 */
--wot-color-bg: #1a1a1a;
--wot-color-bg-light: #2a2a2a;
--wot-color-bg-dark: #404040;
/* 边框颜色 - 暗黑模式 */
--wot-color-border: #404040;
--wot-color-border-light: #606060;
/* 卡片相关变量 - 暗黑模式 */
--wot-card-bg-color: #2a2a2a;
--wot-card-border-color: var(--wot-color-border);
--wot-card-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.3);
/* Cell 相关变量 - 暗黑模式 */
--wot-cell-bg-color: #2a2a2a;
/* 弹窗相关变量 - 暗黑模式 */
--wot-popup-bg-color: #2a2a2a;
/* 输入框相关变量 - 暗黑模式 */
--wot-input-disabled-bg-color: var(--wot-color-bg-light);
}
/* ===== 动态主题色支持 ===== */
/* 这些变量会被 useTheme composable 动态设置 */
.theme-blue {
--wot-color-theme: #165dff;
}
.theme-green {
--wot-color-theme: #0fc6c2;
}
.theme-orange {
--wot-color-theme: #ff7d00;
}
.theme-red {
--wot-color-theme: #f5222d;
}
.theme-purple {
--wot-color-theme: #722ed1;
}
.theme-pink {
--wot-color-theme: #eb2f96;
}
.theme-cyan {
--wot-color-theme: #13c2c2;
}
.theme-yellow {
--wot-color-theme: #faad14;
}
.theme-lime {
--wot-color-theme: #a0d911;
}
.theme-indigo {
--wot-color-theme: #2f54eb;
}
.theme-teal {
--wot-color-theme: #08979c;
}
.theme-brown {
--wot-color-theme: #8c6239;
}
/* ===== 全局样式增强 ===== */
/* 确保暗黑模式下的全局样式 */
[data-theme="dark"] {
color: var(--wot-color-text);
background-color: var(--wot-color-bg);
}
/* H5 环境下的 body 样式 */
/* #ifdef H5 */
body.dark {
color: #ffffff !important;
background-color: #1a1a1a !important;
}
/* #endif */
/* 小程序环境下的 page 样式 */
/* #ifndef H5 */
page.dark {
color: #ffffff !important;
background-color: #1a1a1a !important;
}
/* #endif */