wip: 临时提交

This commit is contained in:
ray
2025-05-29 08:28:46 +08:00
parent 9fba279490
commit 8962f01b09
23 changed files with 1457 additions and 2372 deletions

View File

@@ -38,6 +38,7 @@
import { useUserStore } from "@/store/modules/user.store";
import { checkLogin } from "@/utils/auth";
import { computed, ref } from "vue";
import { onLoad } from "@dcloudio/uni-app";
const userStore = useUserStore();
const isLogin = computed(() => !!userStore.userInfo);
@@ -200,6 +201,39 @@ onLoad(() => {
.settings-container {
min-height: 100vh;
padding: 20px;
color: var(--wot-color-text, #333);
background-color: var(--wot-color-bg-light, #f8f8f8);
// 强制 Wot 组件应用暗黑模式样式
:deep(.wd-cell-group) {
overflow: hidden;
background-color: var(--wot-card-bg-color, #fff);
border-radius: 16rpx;
}
: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-button) {
&.logout-btn {
color: #fff !important;
background-color: var(--wot-color-theme, var(--primary-color)) !important;
}
}
.loading-mask {
position: fixed;
@@ -216,7 +250,7 @@ onLoad(() => {
.loading-content {
padding: 30rpx 40rpx;
text-align: center;
background-color: rgba(255, 255, 255, 0.95);
background-color: var(--wot-card-bg-color, rgba(255, 255, 255, 0.95));
border-radius: 12rpx;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.15);
@@ -224,8 +258,8 @@ onLoad(() => {
width: 60rpx;
height: 60rpx;
margin: 0 auto 20rpx;
border: 4rpx solid #f3f3f3;
border-top: 4rpx solid #409eff;
border: 4rpx solid var(--wot-color-border, #f3f3f3);
border-top: 4rpx solid var(--wot-color-theme, #409eff);
border-radius: 50%;
animation: spin 1s linear infinite;
}
@@ -233,7 +267,7 @@ onLoad(() => {
.loading-text {
font-size: 28rpx;
font-weight: 500;
color: #333;
color: var(--wot-color-text, #333);
}
}
}
@@ -255,10 +289,10 @@ onLoad(() => {
font-size: 32rpx;
font-weight: 500;
color: #fff;
background-color: var(--primary-color);
background-color: var(--wot-color-theme, var(--primary-color));
border: none;
border-radius: 45rpx;
box-shadow: 0 4rpx 12rpx rgba(var(--primary-color-rgb), 0.3);
box-shadow: 0 4rpx 12rpx rgba(22, 93, 255, 0.3);
transition: opacity 0.2s;
&:active {
@@ -266,4 +300,40 @@ onLoad(() => {
}
}
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
// 全局暗黑模式适配(针对当前页面)
:global([data-theme="dark"]) .settings-container {
color: var(--wot-color-text, #fff) !important;
background-color: var(--wot-color-bg, #1a1a1a) !important;
:deep(.wd-cell-group) {
background-color: 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;
}
}
}
</style>

View File

@@ -7,18 +7,18 @@
</view>
<!-- 暗黑模式设置 -->
<view class="setting-section">
<wd-card class="setting-section">
<view class="section-header">
<wd-icon name="moon" size="20" :color="isDark ? '#FFD700' : '#666'" />
<wd-icon name="moon" size="20" :color="theme === 'dark' ? '#FFD700' : '#666'" />
<text class="section-title">外观模式</text>
</view>
<wd-cell title="暗黑模式" :value="isDark ? '已开启' : '已关闭'">
<wd-switch v-model="isDark" @change="toggleDarkMode" />
<wd-cell title="暗黑模式" :value="theme === 'dark' ? '已开启' : '已关闭'">
<wd-switch :model-value="theme === 'dark'" @change="handleToggleDarkMode" />
</wd-cell>
</view>
</wd-card>
<!-- 主题色设置 -->
<view class="setting-section">
<wd-card class="setting-section">
<view class="section-header">
<wd-icon name="palette" size="20" color="#666" />
<text class="section-title">主题色彩</text>
@@ -26,59 +26,78 @@
<!-- 预设颜色选择 -->
<view class="color-section">
<view class="color-label">预设主题色</view>
<text class="color-label">预设主题色</text>
<view class="color-grid">
<view
v-for="(color, index) in extendedThemeColors"
v-for="(color, index) in colorColumns"
:key="index"
class="color-item"
:class="{ active: currentThemeColor === color.value }"
:style="{ backgroundColor: color.value }"
@click="handleSelectColor(color.value)"
>
<wd-icon v-if="currentThemeColor === color.value" name="check" color="#fff" size="16" />
<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>
</view>
</view>
<!-- 当前主题色显示 -->
<wd-cell title="当前主题色" :value="currentThemeColor">
<view class="current-color-preview" :style="{ backgroundColor: currentThemeColor }"></view>
</wd-cell>
<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>
</view>
</wd-card>
<!-- 预览区域 -->
<view class="setting-section">
<wd-card class="setting-section">
<view class="section-header">
<wd-icon name="eye" size="20" color="#666" />
<text class="section-title">效果预览</text>
</view>
<view class="preview-container">
<view class="preview-item">
<wd-divider />
<wd-grid :column="2" border>
<wd-grid-item>
<wd-button type="primary" size="small">主要按钮</wd-button>
</view>
<view class="preview-item">
</wd-grid-item>
<wd-grid-item>
<text class="preview-text" :style="{ color: currentThemeColor }">主题色文本</text>
</view>
<view class="preview-item">
</wd-grid-item>
<wd-grid-item>
<view class="preview-border" :style="{ borderColor: currentThemeColor }">主题色边框</view>
</view>
<view class="preview-item">
</wd-grid-item>
<wd-grid-item>
<wd-tag type="primary" size="small">标签</wd-tag>
</view>
</view>
</view>
</wd-grid-item>
</wd-grid>
</wd-card>
<!-- 操作按钮 -->
<view class="action-section">
<wd-button type="info" size="large" block @click="resetTheme">重置为默认主题</wd-button>
</view>
<wd-card class="action-section">
<wd-button type="info" size="large" block @click="handleResetTheme">重置为默认主题</wd-button>
</wd-card>
<!-- 自定义颜色输入弹窗 -->
<wd-popup v-model="showCustomColorInput" position="bottom" :safe-area-inset-bottom="true">
@@ -88,21 +107,24 @@
<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>
<input
<wd-input
v-model="customColor"
type="text"
placeholder="例如: #165DFF"
:maxlength="7"
class="color-input"
maxlength="7"
/>
</view>
<view class="input-tip">支持格式#RGB #RRGGBB</view>
</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>
@@ -114,61 +136,23 @@
<script lang="ts" setup>
import { onLoad, onShow } from "@dcloudio/uni-app";
import { useTheme } from "@/composables/useTheme";
import { useThemeStore } from "@/store/modules/theme.store";
import { applyThemeOnPageShow } from "@/utils/theme";
import { ref, computed, watch, onMounted } from "vue";
import { useTheme, colorColumns } from "@/composables/useTheme";
import { ref, computed, onMounted, nextTick } from "vue";
const { toggleTheme, themeVars, themeState, setThemeColor } = useTheme();
const themeStore = useThemeStore();
// 暗黑模式状态
const isDark = ref(false);
const { theme, themeVars, toggleTheme, setThemeColor, resetTheme } = useTheme();
// 自定义颜色输入
const customColor = ref("");
const showCustomColorInput = ref(false);
// 扩展的预设主题色
const extendedThemeColors = [
{ value: "#165DFF", label: "蓝色" },
{ value: "#0FC6C2", label: "青绿色" },
{ value: "#722ED1", label: "紫色" },
{ value: "#F5222D", label: "红色" },
{ value: "#FA8C16", label: "橙色" },
{ value: "#FADB14", label: "黄色" },
{ value: "#52C41A", label: "绿色" },
{ value: "#EB2F96", label: "粉色" },
{ value: "#13C2C2", label: "青色" },
{ value: "#1890FF", label: "天蓝色" },
{ value: "#CD5C5C", label: "经典红" },
{ value: "#228B22", label: "自然绿" },
];
// 当前选中的主题色
const currentThemeColor = computed(() => {
return themeVars.value.colorTheme || themeStore.primaryColor || extendedThemeColors[0].value;
return themeVars.value.colorTheme || colorColumns[0].value;
});
// 监听暗黑模式变化
watch(themeState, (newTheme) => {
isDark.value = newTheme === "dark";
});
// 暗黑模式切换
const toggleDarkMode = () => {
toggleTheme();
};
// 选择预设颜色
const handleSelectColor = (color: string) => {
// 同时更新两个store的主题色
if (setThemeColor) {
setThemeColor(color);
} else {
themeVars.value.colorTheme = color;
}
themeStore.setPrimaryColor(color);
setThemeColor(color);
customColor.value = color;
// 提示
@@ -204,13 +188,7 @@ const applyCustomColor = () => {
color = "#" + color[1] + color[1] + color[2] + color[2] + color[3] + color[3];
}
// 同时更新两个store的主题色
if (setThemeColor) {
setThemeColor(color);
} else {
themeVars.value.colorTheme = color;
}
themeStore.setPrimaryColor(color);
setThemeColor(color);
showCustomColorInput.value = false;
// 提示
@@ -222,27 +200,14 @@ const applyCustomColor = () => {
};
// 重置为默认主题
const resetTheme = () => {
const handleResetTheme = () => {
uni.showModal({
title: "确认重置",
content: "确定要重置为默认主题吗?",
success: (res) => {
if (res.confirm) {
const defaultColor = extendedThemeColors[0].value;
// 同时更新两个store的主题色
if (setThemeColor) {
setThemeColor(defaultColor);
} else {
themeVars.value.colorTheme = defaultColor;
}
themeStore.setPrimaryColor(defaultColor);
customColor.value = defaultColor;
// 重置为浅色模式
if (themeState.value === "dark") {
toggleTheme();
}
resetTheme();
customColor.value = colorColumns[0].value;
uni.showToast({
title: "已重置为默认主题",
@@ -254,31 +219,35 @@ const resetTheme = () => {
});
};
// 切换暗黑模式
const handleToggleDarkMode = () => {
toggleTheme();
nextTick(() => {
uni.showToast({
title: `已切换到${theme.value === "dark" ? "暗黑" : "浅色"}模式`,
icon: "success",
duration: 1500,
});
});
};
onLoad(() => {
// 初始化自定义颜色输入框
customColor.value = currentThemeColor.value;
});
onMounted(() => {
// 初始化暗黑模式状态
isDark.value = themeState.value === "dark";
// 初始化自定义颜色输入框
customColor.value = currentThemeColor.value;
});
// 页面显示时重新应用主题(解决小程序环境问题)
// 页面显示时确保主题色同步
onShow(() => {
// 在小程序环境中,页面显示时重新应用主题
if (typeof document === "undefined") {
applyThemeOnPageShow(currentThemeColor.value);
// 为了确保样式应用,我们可以在页面中设置内联样式
// 这样可以绕过小程序的CSS变量限制
const pages = getCurrentPages();
const currentPage = pages[pages.length - 1];
if (currentPage) {
console.log("当前页面重新应用主题色");
}
}
customColor.value = currentThemeColor.value;
console.log("主题设置页面显示,当前主题:", {
mode: theme.value,
color: currentThemeColor.value,
});
});
</script>
@@ -286,15 +255,81 @@ onShow(() => {
.theme-settings-container {
min-height: 100vh;
padding: 20rpx;
background-color: #f8f9fa;
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;
}
}
.page-header {
padding: 40rpx 20rpx;
margin-bottom: 30rpx;
text-align: center;
background: linear-gradient(135deg, #165dff 0%, #667eea 100%);
background: linear-gradient(135deg, var(--wot-color-theme, #165dff) 0%, #667eea 100%);
border-radius: 16rpx;
}
@@ -313,25 +348,20 @@ onShow(() => {
.setting-section {
margin-bottom: 30rpx;
overflow: hidden;
background: #fff;
border-radius: 16rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
transition: background-color 0.3s ease;
}
.section-header {
display: flex;
align-items: center;
padding: 30rpx 30rpx 20rpx;
border-bottom: 1rpx solid #f0f0f0;
border-bottom: 1rpx solid var(--wot-color-border, #f0f0f0);
}
.section-title {
margin-left: 12rpx;
font-size: 32rpx;
font-weight: 600;
color: #333;
color: var(--wot-color-text, #333);
}
.color-section {
@@ -341,58 +371,95 @@ onShow(() => {
.color-label {
margin-bottom: 20rpx;
font-size: 28rpx;
color: #666;
color: var(--wot-color-text-secondary, #666);
}
.color-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
display: flex;
flex-wrap: wrap;
gap: 20rpx;
justify-content: space-between;
}
.color-item {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 80rpx;
height: 80rpx;
width: calc(25% - 15rpx);
padding: 10rpx;
cursor: pointer;
border-radius: 12rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
.color-preview {
position: relative;
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);
}
}
.color-item.active {
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.2);
transform: scale(1.1);
.current-theme-section {
padding: 30rpx;
}
.color-item:active {
transform: scale(0.95);
.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 #f0f0f0;
border: 2rpx solid var(--wot-color-border, #f0f0f0);
border-radius: 8rpx;
}
.preview-container {
display: flex;
flex-direction: column;
gap: 20rpx;
padding: 30rpx;
}
.preview-item {
display: flex;
align-items: center;
justify-content: center;
padding: 20rpx;
background: #f8f9fa;
border-radius: 12rpx;
.current-color-text {
margin-left: 10rpx;
font-size: 28rpx;
font-weight: 500;
}
.preview-text {
@@ -407,22 +474,18 @@ onShow(() => {
width: 200rpx;
height: 60rpx;
font-size: 26rpx;
color: #666;
color: var(--wot-color-text-secondary, #666);
border: 2rpx solid;
border-radius: 8rpx;
}
.action-section {
padding: 30rpx;
background: #fff;
border-radius: 16rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
}
.custom-color-popup {
padding: 40rpx 30rpx;
background: #fff;
border-radius: 20rpx 20rpx 0 0;
: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 {
@@ -435,7 +498,7 @@ onShow(() => {
.popup-title {
font-size: 32rpx;
font-weight: 600;
color: #333;
color: var(--wot-color-text, #333);
}
.color-input-section {
@@ -445,7 +508,7 @@ onShow(() => {
.input-label {
margin-bottom: 20rpx;
font-size: 28rpx;
color: #666;
color: var(--wot-color-text-secondary, #666);
}
.input-container {
@@ -459,28 +522,18 @@ onShow(() => {
flex-shrink: 0;
width: 60rpx;
height: 60rpx;
border: 2rpx solid #f0f0f0;
border: 2rpx solid var(--wot-color-border, #f0f0f0);
border-radius: 8rpx;
}
.color-input {
flex: 1;
height: 60rpx;
padding: 0 20rpx;
font-size: 28rpx;
background: #fff;
border: 2rpx solid #e0e0e0;
border-radius: 8rpx;
}
.color-input:focus {
border-color: #165dff;
}
.input-tip {
margin-left: 80rpx;
font-size: 24rpx;
color: #999;
color: var(--wot-color-text-placeholder, #999);
}
.popup-actions {
@@ -501,52 +554,85 @@ onShow(() => {
}
}
/* 暗黑模式适配 */
:deep(.wd-config-provider[data-theme="dark"]) {
.theme-settings-container {
background-color: #1a1a1a;
// 全局暗黑模式适配(针对当前页面)
: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%);
}
.setting-section {
background: #2a2a2a;
.section-title {
color: var(--wot-color-text, #fff) !important;
}
.section-header {
border-bottom-color: #404040;
.color-label {
color: var(--wot-color-text-secondary, #d1d5db) !important;
}
.section-title {
color: #fff;
}
.preview-text {
color: var(--wot-color-text, #fff) !important;
}
.preview-border {
color: var(--wot-color-text-secondary, #d1d5db) !important;
}
.popup-title {
color: var(--wot-color-text, #fff) !important;
}
.input-label {
color: var(--wot-color-text-secondary, #d1d5db) !important;
}
.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;
}
}
.preview-container .preview-item {
background: #404040;
:deep(.wd-grid-item) {
color: var(--wot-color-text, #fff) !important;
background-color: var(--wot-card-bg-color, #2a2a2a) !important;
}
.action-section {
background: #2a2a2a;
// 专门为颜色预览块重置背景色
: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: #2a2a2a;
.popup-title {
color: #fff;
}
.input-label {
color: #ccc;
}
.color-input {
color: #fff;
background: #404040;
border-color: #606060;
&:focus {
border-color: #165dff;
}
}
background: var(--wot-popup-bg-color, #2a2a2a) !important;
}
}
</style>