diff --git a/.env.development b/.env.development
index ac161a7..7bf5903 100644
--- a/.env.development
+++ b/.env.development
@@ -8,3 +8,5 @@ VITE_APP_BASE_API = '/dev-api'
# API 服务器的 URL
VITE_APP_API_URL = https://api.youlai.tech
+
+VITE_APP_WS_ENDPOINT= ws://localhost:4096/ws
\ No newline at end of file
diff --git a/README-theme.md b/README-theme.md
new file mode 100644
index 0000000..4493fbd
--- /dev/null
+++ b/README-theme.md
@@ -0,0 +1,190 @@
+# Wot Design Uni 主题系统使用指南
+
+## 概述
+
+本项目基于 Wot Design Uni 的 CSS 变量系统实现了完整的主题定制功能,支持:
+
+- 🌙 暗黑模式切换
+- 🎨 12 种预设主题色
+- 🎯 自定义主题色
+- 💾 持久化存储
+- 📱 多平台兼容(H5、小程序)
+
+## 核心文件
+
+### 1. 主题变量文件
+
+- `src/styles/wot-theme.scss` - Wot Design Uni CSS 变量定制
+- `src/uni.scss` - 引入主题变量文件
+
+### 2. 主题 Composable
+
+- `src/composables/useTheme.ts` - 主题状态管理和工具函数
+
+### 3. 主题设置页面
+
+- `src/pages/mine/settings/theme/index.vue` - 主题设置界面
+- `src/pages/test-wot-theme.vue` - 主题测试页面
+
+## 使用方法
+
+### 1. 在组件中使用主题
+
+```vue
+
+
+
+
+
+
+ 主要按钮
+
+
+ 使用主题色的文本
+
+
+
+
+
+
+```
+
+### 2. 可用的 CSS 变量
+
+#### 主题色系
+
+- `--wot-color-theme` - 主题色
+- `--wot-color-success` - 成功色
+- `--wot-color-warning` - 警告色
+- `--wot-color-danger` - 危险色
+- `--wot-color-info` - 信息色
+
+#### 文本颜色
+
+- `--wot-color-text` - 主要文本色
+- `--wot-color-text-secondary` - 次要文本色
+- `--wot-color-text-placeholder` - 占位符文本色
+
+#### 背景颜色
+
+- `--wot-color-bg` - 主背景色
+- `--wot-color-bg-light` - 浅背景色
+- `--wot-card-bg-color` - 卡片背景色
+
+#### 边框颜色
+
+- `--wot-color-border` - 边框色
+- `--wot-color-border-light` - 浅边框色
+
+### 3. 预设主题色
+
+项目提供 12 种预设主题色:
+
+```javascript
+const colorColumns = [
+ { 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: "自然绿" },
+];
+```
+
+## 暗黑模式适配
+
+### 自动适配
+
+所有使用 Wot CSS 变量的组件都会自动适配暗黑模式。
+
+### 手动适配
+
+对于自定义组件,使用 CSS 变量即可:
+
+```scss
+.my-component {
+ background-color: var(--wot-card-bg-color, #fff);
+ color: var(--wot-color-text, #333);
+ border: 1px solid var(--wot-color-border, #e5e6eb);
+}
+```
+
+## 测试页面
+
+访问 `/pages/test-wot-theme` 可以测试:
+
+- 暗黑模式切换
+- 主题色切换
+- CSS 变量效果
+- 各种 Wot 组件的主题适配
+
+## 注意事项
+
+1. **CSS 变量优先级**:使用 `var(--variable-name, fallback)` 格式提供回退值
+2. **暗黑模式检测**:通过 `[data-theme="dark"]` 选择器自动切换
+3. **持久化存储**:主题设置会自动保存到本地存储
+4. **平台兼容**:H5 和小程序环境都有相应的适配处理
+
+## 扩展主题
+
+### 添加新的主题色
+
+1. 在 `colorColumns` 数组中添加新颜色
+2. 在 `wot-theme.scss` 中添加对应的 CSS 类
+
+```scss
+.theme-custom {
+ --wot-color-theme: #your-color;
+}
+```
+
+### 自定义 CSS 变量
+
+在 `wot-theme.scss` 中添加新的变量:
+
+```scss
+:root {
+ --wot-custom-color: #your-color;
+}
+
+[data-theme="dark"] {
+ --wot-custom-color: #your-dark-color;
+}
+```
+
+## 故障排除
+
+1. **主题色不生效**:检查是否正确引入了 `wot-theme.scss`
+2. **暗黑模式样式异常**:确认使用了正确的 CSS 变量
+3. **小程序兼容问题**:检查条件编译是否正确
+
+## 更新日志
+
+- ✅ 修复了暗黑模式切换无效的问题
+- ✅ 完善了 Wot Design Uni CSS 变量系统
+- ✅ 优化了主题设置页面的 UI 组件
+- ✅ 添加了完整的主题测试页面
diff --git a/components.d.ts b/components.d.ts
index 3f5fa27..1560d44 100644
--- a/components.d.ts
+++ b/components.d.ts
@@ -11,7 +11,6 @@ declare module 'vue' {
CuDict: typeof import('./src/components/cu-dict/index.vue')['default']
CuDictLabel: typeof import('./src/components/cu-dict-label/index.vue')['default']
CuPicker: typeof import('./src/components/cu-picker/index.vue')['default']
- DaTree: typeof import('./src/components/da-tree/index.vue')['default']
Loading1: typeof import('./src/components/qiun-loading/loading1.vue')['default']
Loading2: typeof import('./src/components/qiun-loading/loading2.vue')['default']
Loading3: typeof import('./src/components/qiun-loading/loading3.vue')['default']
@@ -27,10 +26,11 @@ declare module 'vue' {
WdCell: typeof import('wot-design-uni/components/wd-cell/wd-cell.vue')['default']
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']
- WdForm: typeof import('wot-design-uni/components/wd-form/wd-form.vue')['default']
+ WdDivider: typeof import('wot-design-uni/components/wd-divider/wd-divider.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']
+ WdInput: typeof import('wot-design-uni/components/wd-input/wd-input.vue')['default']
WdMessageBox: typeof import('wot-design-uni/components/wd-message-box/wd-message-box.vue')['default']
WdNavbar: typeof import('wot-design-uni/components/wd-navbar/wd-navbar.vue')['default']
WdNoticeBar: typeof import('wot-design-uni/components/wd-notice-bar/wd-notice-bar.vue')['default']
diff --git a/docs/theme-system-guide.md b/docs/theme-system-guide.md
new file mode 100644
index 0000000..1467e05
--- /dev/null
+++ b/docs/theme-system-guide.md
@@ -0,0 +1,311 @@
+# 主题系统使用指南
+
+## 概述
+
+本项目基于 Wot Design Uni 的 ConfigProvider 组件实现了完整的主题系统,支持:
+
+- 🌙 暗黑/浅色模式切换
+- 🎨 12种预设主题色
+- 🎯 自定义主题色
+- 💾 主题设置持久化存储
+- 📱 多平台兼容(H5、小程序)
+
+## 核心文件
+
+### 1. useTheme Composable (`src/composables/useTheme.ts`)
+
+主题管理的核心逻辑,提供:
+
+```typescript
+const {
+ theme, // 当前主题模式 'light' | 'dark'
+ themeVars, // ConfigProviderThemeVars 主题变量
+ toggleTheme, // 切换主题模式
+ setThemeColor, // 设置主题色
+ resetTheme, // 重置主题
+ initTheme, // 初始化主题
+ colorColumns, // 预设主题色列表
+} = useTheme();
+```
+
+### 2. 布局文件
+
+#### Tabbar 布局 (`src/layouts/tabbar.vue`)
+
+```vue
+
+
+
+
+
+```
+
+#### Default 布局 (`src/layouts/default.vue`)
+
+```vue
+
+
+
+
+
+```
+
+### 3. 主题设置页面 (`src/pages/mine/settings/theme/index.vue`)
+
+提供用户界面来:
+
+- 切换暗黑/浅色模式
+- 选择预设主题色
+- 输入自定义主题色
+- 预览主题效果
+- 重置主题设置
+
+## 主题变量
+
+### 支持的 ConfigProviderThemeVars
+
+根据 Wot Design Uni 文档,主要使用:
+
+```typescript
+interface ConfigProviderThemeVars {
+ colorTheme?: string; // 主题色
+ buttonPrimaryBgColor?: string; // 主按钮背景色
+ buttonPrimaryColor?: string; // 主按钮文字色
+ // ... 更多变量
+}
+```
+
+### 预设主题色
+
+```typescript
+const colorColumns = [
+ { 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: "自然绿" },
+];
+```
+
+## 暗黑模式实现
+
+### 1. ConfigProvider 主题切换
+
+```vue
+
+
+
+```
+
+### 2. 全局样式适配
+
+在 `src/uni.scss` 中定义:
+
+```scss
+.wot-theme-dark {
+ background-color: #1a1a1a !important;
+ color: #f5f5f5 !important;
+
+ /* H5 环境 body 样式 */
+ body {
+ background-color: #1a1a1a !important;
+ color: #f5f5f5 !important;
+ }
+
+ /* 其他组件暗黑模式适配 */
+}
+```
+
+### 3. 动态 Body 样式
+
+在 `useTheme` 中自动处理:
+
+```typescript
+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");
+ }
+ }
+ // #endif
+};
+```
+
+## 持久化存储
+
+主题设置自动保存到本地存储:
+
+```typescript
+// 存储键名
+const THEME_STORAGE_KEY = "app_theme_mode";
+const THEME_COLOR_STORAGE_KEY = "app_theme_color";
+
+// 自动监听变化并保存
+watch(
+ theme,
+ (newTheme) => {
+ saveThemeToStorage(newTheme);
+ applyDarkModeBodyStyle(newTheme === "dark");
+ },
+ { immediate: true }
+);
+```
+
+## 使用示例
+
+### 在页面中使用主题
+
+```vue
+
+
+ 主题色按钮
+ 主题色文本
+
+
+
+
+```
+
+### 在组件中响应主题变化
+
+```vue
+
+
+
+
+
+
+
+
+
+```
+
+## 最佳实践
+
+### 1. 组件开发
+
+- 使用 Wot Design Uni 组件时,主题色会自动应用
+- 自定义组件需要手动适配暗黑模式
+- 使用 `:class="{ 'wot-theme-dark': theme === 'dark' }"` 来应用暗黑模式样式
+
+### 2. 样式编写
+
+```scss
+.my-component {
+ background-color: #fff;
+ color: #333;
+
+ // 暗黑模式适配
+ .wot-theme-dark & {
+ background-color: #2a2a2a;
+ color: #f5f5f5;
+ }
+}
+```
+
+### 3. 主题色使用
+
+```vue
+
+
+
+
+
+
+```
+
+## 注意事项
+
+1. **ConfigProvider 包裹**:确保页面被 ConfigProvider 包裹才能应用主题
+2. **样式优先级**:暗黑模式样式需要足够的优先级,必要时使用 `!important`
+3. **平台兼容**:小程序和 H5 的样式处理略有不同,使用条件编译处理
+4. **性能考虑**:主题切换时避免频繁的 DOM 操作
+
+## 扩展功能
+
+### 添加新的主题色
+
+在 `colorColumns` 中添加新的颜色:
+
+```typescript
+export const colorColumns = [
+ // ... 现有颜色
+ { value: "#FF6B6B", label: "珊瑚红" },
+ { value: "#4ECDC4", label: "薄荷绿" },
+];
+```
+
+### 添加更多主题变量
+
+```typescript
+const themeVars = ref({
+ colorTheme: getStoredThemeColor(),
+ buttonPrimaryBgColor: getStoredThemeColor(),
+ // 添加更多变量
+});
+```
+
+### 自定义暗黑模式样式
+
+在 `uni.scss` 中添加更多组件的暗黑模式适配:
+
+```scss
+.wot-theme-dark {
+ // 新组件的暗黑模式样式
+ .my-custom-component {
+ background-color: #2a2a2a;
+ color: #f5f5f5;
+ }
+}
+```
diff --git a/src/App.vue b/src/App.vue
index 3f5185a..39fedec 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -1,14 +1,14 @@
-
-
diff --git a/src/components/da-tree/props.ts b/src/components/da-tree/props.ts
deleted file mode 100644
index 4b710df..0000000
--- a/src/components/da-tree/props.ts
+++ /dev/null
@@ -1,197 +0,0 @@
-export default {
- /**
- * 树的数据
- */
- data: {
- type: Array,
- default: () => [],
- },
- /**
- * 主题色
- */
- themeColor: {
- type: String,
- default: "#007aff",
- },
- /**
- * 是否开启多选,默认单选
- */
- showCheckbox: {
- type: Boolean,
- default: false,
- },
- /**
- * 默认选中的节点,注意单选时为单个key,多选时为key的数组
- */
- defaultCheckedKeys: {
- type: [Array, String, Number],
- default: null,
- },
- /**
- * 是否默认展开全部
- */
- defaultExpandAll: {
- type: Boolean,
- default: false,
- },
- /**
- * 默认展开的节点
- */
- defaultExpandedKeys: {
- type: Array,
- default: null,
- },
- /**
- * 筛选关键词
- */
- filterValue: {
- type: String,
- default: "",
- },
- /**
- * 是否自动展开到选中的节点,默认不展开
- */
- expandChecked: {
- type: Boolean,
- default: false,
- },
-
- /**
- * (旧)字段对应内容,默认为 {label: 'label',key: 'key', children: 'children', disabled: 'disabled', append: 'append'}
- * 注意:1.5.0版本后不再兼容
- */
- field: {
- type: Object,
- default: null,
- },
- /**
- * 标签字段(新,拆分了)
- */
- labelField: {
- type: String,
- default: "label",
- },
- /**
- * 值字段(新,拆分了)
- */
- valueField: {
- type: String,
- default: "value",
- },
- /**
- * 下级字段(新,拆分了)
- */
- childrenField: {
- type: String,
- default: "children",
- },
- /**
- * 禁用字段(新,拆分了)
- */
- disabledField: {
- type: String,
- default: "disabled",
- },
- /**
- * 末级节点字段(新,拆分了)
- */
- leafField: {
- type: String,
- default: "leaf",
- },
- /**
- * 副标签字段(新,拆分了)
- */
- appendField: {
- type: String,
- default: "append",
- },
- /**
- * 排序字段(新,拆分了)
- */
- sortField: {
- type: String,
- default: "sort",
- },
- /**
- * Api数据返回后的结果路径,支持嵌套如`data.list`
- */
- resultField: {
- type: String,
- default: "",
- },
- isLeafFn: {
- type: Function,
- default: null,
- },
- /**
- * 是否显示单选图标,默认显示
- */
- showRadioIcon: {
- type: Boolean,
- default: true,
- },
- /**
- * 单选时只允许选中末级,默认可随意选中
- */
- onlyRadioLeaf: {
- type: Boolean,
- default: false,
- },
- /**
- * 多选时,是否执行父子不关联的任意勾选,默认父子关联
- */
- checkStrictly: {
- type: Boolean,
- default: false,
- },
- /**
- * 为 true 时,空的 children 数组会显示展开图标
- */
- loadMode: {
- type: Boolean,
- default: false,
- },
- /**
- * 异步加载接口
- */
- loadApi: {
- type: Function,
- default: null,
- },
- /**
- * 是否总在首次的时候加载一下内容,来比对是否一致
- */
- alwaysFirstLoad: {
- type: Boolean,
- default: false,
- },
- /**
- * 是否渲染(操作)禁用值
- */
- checkedDisabled: {
- type: Boolean,
- default: false,
- },
- /**
- * 是否返回已禁用的但已选中的key
- */
- packDisabledkey: {
- type: Boolean,
- default: true,
- },
- /**
- * 选择框的位置,可选 left/right
- */
- checkboxPlacement: {
- type: String,
- default: "left",
- },
- /**
- * 子项缩进距离,默认40,单位rpx
- */
- indent: {
- type: Number,
- default: 40,
- },
-};
diff --git a/src/components/da-tree/readme.md b/src/components/da-tree/readme.md
deleted file mode 100644
index fa3f318..0000000
--- a/src/components/da-tree/readme.md
+++ /dev/null
@@ -1,310 +0,0 @@
-# da-tree
-
-一个基于 Vue3 的 tree(树)组件,同时支持主题换色,可能是最适合你的 tree(树)组件
-
-组件一直在更新,遇到问题可在下方讨论。
-
-`同时更新 Vue2 版本,在此查看 ===>` **[Vue2 版](https://ext.dcloud.net.cn/plugin?id=12692)**
-
-### 关于使用
-
-可在右侧的`使用 HBuilderX 导入插件`或`下载示例项目ZIP`,方便快速上手。
-
-可通过下方的示例及文档说明,进一步了解使用组件相关细节参数。
-
-插件地址:https://ext.dcloud.net.cn/plugin?id=12384
-
-### 组件示例
-
-```jsx
-
- 多选
-
-
-
-
-
-
-
-
-
- 单选
-
- 默认展开指定节点
-
- 异步加载数据
-
-
-```
-
-```js
-import { defineComponent, ref } from "vue";
-
-/**
- * 模拟创建一个接口数据
- */
-function GetApiData(currentNode) {
- const { key } = currentNode;
-
- return new Promise((resolve) => {
- setTimeout(() => {
- // 模拟返回空数据
- if (key.indexOf("-") > -1) {
- return resolve(null);
- // return resolve([])
- }
-
- return resolve([
- {
- id: `${key}-1`,
- name: `行政部X${key}-1`,
- },
- {
- id: `${key}-2`,
- name: `财务部X${key}-2`,
- append: "定义了末项数据",
- leaf: true,
- },
- {
- id: `${key}-3`,
- name: `资源部X${key}-3`,
- },
- {
- id: `${key}-4`,
- name: `资源部X${key}-3`,
- append: "被禁用,无展开图标",
- disabled: true,
- },
- ]);
- }, 2000);
- });
-}
-
-import DaTree from "@/components/da-tree/index.vue";
-export default defineComponent({
- components: { DaTree },
- setup() {
- const DaTreeRef = ref();
- // key的类型必须对应树数据key的类型
- const defaultCheckedKeysValue = ref(["211", "222"]);
- const defaultCheckedKeysValue2 = ref("222");
- const defaultExpandKeysValue3 = ref(["212", "231"]);
- const roomTreeData = ref([
- {
- id: "2",
- name: "行政中心",
- children: [
- {
- id: "21",
- name: "行政部",
- children: [
- {
- id: "211",
- name: "行政一部",
- children: null,
- },
- {
- id: "212",
- name: "行政二部",
- children: [],
- disabled: true,
- },
- ],
- },
- {
- id: "22",
- name: "财务部",
- children: [
- {
- id: "221",
- name: "财务一部",
- children: [],
- disabled: true,
- },
- {
- id: "222",
- name: "财务二部",
- children: [],
- },
- ],
- },
- {
- id: "23",
- name: "人力资源部",
- children: [
- {
- id: "231",
- name: "人力一部",
- children: [],
- },
- {
- id: "232",
- name: "人力二部",
- append: "更多示例,请下载示例项目查看",
- },
- ],
- },
- ],
- },
- ]);
- function doExpandTree(keys, expand) {
- DaTreeRef.value?.setExpandedKeys(keys, expand);
-
- const gek = DaTreeRef.value?.getExpandedKeys();
- console.log("当前已展开的KEY ==>", gek);
- }
- function doCheckedTree(keys, checked) {
- DaTreeRef.value?.setCheckedKeys(keys, checked);
-
- const gek = DaTreeRef.value?.getCheckedKeys();
- console.log("当前已选中的KEY ==>", gek);
- }
- function handleTreeChange(allSelectedKeys, currentItem) {
- console.log("handleTreeChange ==>", allSelectedKeys, currentItem);
- }
- function handleExpandChange(expand, currentItem) {
- console.log("handleExpandChange ==>", expand, currentItem);
- }
- return {
- DaTreeRef,
- roomTreeData,
- defaultCheckedKeysValue,
- defaultCheckedKeysValue2,
- defaultExpandKeysValue3,
- handleTreeChange,
- handleExpandChange,
- GetApiData,
- doExpandTree,
- doCheckedTree,
- };
- },
-});
-```
-
-** 更多示例请下载/导入示例项目 ZIP 查看 **
-
-### 组件参数
-
-| 属性 | 类型 | 默认值 | 必填 | 说明 |
-| :------------------ | :------------------------------ | :--------- | :--- | :--------------------------------------------------------------------------- |
-| data | `Array` | - | 是 | 树的数据 |
-| themeColor | `String` | `#007aff` | 否 | 主题色,十六进制 |
-| defaultCheckedKeys | `Array` \| `Number` \| `String` | - | 否 | 默认选中的节点,单选为单个 key,多选为 key 的数组 |
-| showCheckbox | `Boolean` | `false` | 否 | 是否开启多选,默认单选 |
-| checkStrictly | `Boolean` | `false` | 否 | 多选时,是否执行父子不关联的任意勾选,默认父子关联 |
-| showRadioIcon | `Boolean` | `true` | 否 | 是否显示单选图标,默认显示 |
-| onlyRadioLeaf | `Boolean` | `true` | 否 | 单选时只允许选中末级,默认可随意选中 |
-| defaultExpandAll | `Boolean` | `false` | 否 | 是否默认展开全部 |
-| defaultExpandedKeys | `Array` | - | 否 | 默认展开的节点 |
-| indent | `Number` | `40` | 否 | 子项缩进距离,单位 rpx |
-| checkboxPlacement | `String` | `left` | 否 | 选择框的位置,可选 left/right |
-| loadMode | `Boolean` | `false` | 否 | 为 true 时,空的 children 数组会显示展开图标 |
-| loadApi | `Function` | - | 否 | 选择框的位置,可选 left/right |
-| checkedDisabled | `Boolean` | `false` | 否 | 是否渲染禁用值,默认不渲染 |
-| packDisabledkey | `Boolean` | `true` | 否 | 是否返回已禁用的但已选中的 key,默认返回禁用已选值 |
-| expandChecked | `Boolean` | `false` | 否 | 是否自动展开到选中的节点,默认不展开 |
-| alwaysFirstLoad | `Boolean` | `false` | 否 | 是否总在首次的时候加载一下内容,默认不加载,否则只有展开末级节点才会加载数据 |
-| isLeafFn | `Function` | - | 否 | 自定义函数返回来控制数据项的末项 |
-| field | `Object` | - | 否 | 字段对应内容,格式参考下方(1.5.0 后移除,请用单独的字段匹配) |
-| labelField | `String` | `label` | 否 | 指定节点对象中某个属性为标签字段,默认`label` |
-| valueField | `String` | `value` | 否 | 指定节点对象中某个属性为值字段,默认`value` |
-| childrenField | `String` | `children` | 否 | 指定节点对象中某个属性为子树节点字段,默认`children` |
-| disabledField | `String` | `disabled` | 否 | 指定节点对象中某个属性为禁用字段,默认`disabled` |
-| appendField | `String` | `append` | 否 | 指定节点对象中某个属性为副标签字段,默认`append` |
-| leafField | `String` | `leaf` | 否 | 指定节点对象中某个属性为末级节点字段,默认`leaf` |
-| sortField | `String` | `sort` | 否 | 指定节点对象中某个属性为排序字段,默认`sort` |
-| filterValue | `String` | - | 否 | 搜索筛选的关键词,通过输入关键词筛选内容 |
-
-**field 格式(1.5.0 后移除,请用单独的字段匹配)**
-
-```js
-{
- label: 'label',
- key: 'key',
- children: 'children',
- disabled: 'disabled',
- append: 'append'
-}
-```
-
-### 组件事件
-
-| 事件名称 | 回调参数 | 说明 |
-| :------- | :-------------------------------------- | :-------------- |
-| change | `(allCheckedKeys, currentItem) => void` | 选中时回调 |
-| expand | `(expandState, currentItem) => void` | 展开/收起时回调 |
-
-### 组件方法
-
-| 方法名称 | 参数 | 说明 |
-| :------------------ | :--------------- | :------------------------------------------------------------------------------------------------ |
-| setCheckedKeys | `(keys,checked)` | 设置指定 key 的节点选中/取消选中的状态。注: keys 单选时为 key,多选时为 key 的数组 |
-| setExpandedKeys | `(keys,expand)` | 设置指定 key 的节点展开/收起的状态,当 keys 为 all 时即代表展开/收起全部。注:keys 为数组或 `all` |
-| getCheckedKeys | - | 返回已选的 key |
-| getHalfCheckedKeys | - | 返回半选的 key |
-| getUncheckedKeys | - | 返回未选的 key |
-| getCheckedNodes | - | 返回已选的节点 |
-| getUncheckedNodes | - | 返回未选的节点 |
-| getHalfCheckedNodes | - | 返回半选的节点 |
-| getExpandedKeys | - | 返回已展开的 key |
-| getUnexpandedKeys | - | 返回未展开的 key |
-| getExpandedNodes | - | 返回已展开的节点 |
-| getUnexpandedNodes | - | 返回未展开的节点 |
-
-### 组件版本
-
-v1.4.2
-
-### 差异化
-
-已通过测试
-
-> - H5 页面
-> - 微信小程序
-> - 支付宝、钉钉小程序
-> - 字节跳动、抖音、今日头条小程序
-> - 百度小程序
-> - 飞书小程序
-> - QQ 小程序
-> - 京东小程序
-
-未测试
-
-> - 快手小程序由于非企业用户暂无演示
-> - 快应用、360 小程序因 Vue3 支持的原因暂无演示
-
-### 开发组
-
-[@CRLANG](https://crlang.com)
diff --git a/src/components/da-tree/utils.ts b/src/components/da-tree/utils.ts
deleted file mode 100644
index 5a6ca0b..0000000
--- a/src/components/da-tree/utils.ts
+++ /dev/null
@@ -1,153 +0,0 @@
-/** 未选 */
-export const unCheckedStatus = 0;
-/** 半选 */
-export const halfCheckedStatus = 1;
-/** 选中 */
-export const isCheckedStatus = 2;
-
-/**
- * 深拷贝内容
- * @param originData 拷贝对象
- * @author crlang(https://crlang.com)
- */
-export function deepClone(originData: any): any {
- const type = Object.prototype.toString.call(originData);
- let data: any;
- if (type === "[object Array]") {
- data = [];
- for (let i = 0; i < originData.length; i++) {
- data.push(deepClone(originData[i]));
- }
- } else if (type === "[object Object]") {
- data = {} as Record;
- for (const prop in originData) {
- if (Object.prototype.hasOwnProperty.call(originData, prop)) {
- // 非继承属性
- data[prop] = deepClone(originData[prop]);
- }
- }
- } else {
- data = originData;
- }
- return data;
-}
-
-/**
- * 获取所有指定的节点
- * @param list 列表
- * @param type 类型
- * @param value 值
- * @param packDisabledkey 是否包含禁用节点
- * @author crlang(https://crlang.com)
- */
-export function getAllNodes(list: any[], type: string, value: any, packDisabledkey = true): any[] {
- if (!list || list.length === 0) {
- return [];
- }
-
- const res = [];
- for (let i = 0; i < list.length; i++) {
- const item = list[i];
- if (item[type] === value) {
- if ((packDisabledkey && item.disabled) || !item.disabled) {
- res.push(item);
- }
- }
- }
-
- return res;
-}
-
-/**
- * 获取所有指定的key值
- * @param list 列表
- * @param type 类型
- * @param value 值
- * @param packDisabledkey 是否包含禁用节点
- * @author crlang(https://crlang.com)
- */
-export function getAllNodeKeys(
- list: any[],
- type: string,
- value: any,
- packDisabledkey = true
-): string[] | null {
- if (!list || list.length === 0) {
- return null;
- }
-
- const res: string[] = [];
- for (let i = 0; i < list.length; i++) {
- const item = list[i];
- if (item[type] === value) {
- if ((packDisabledkey && item.disabled) || !item.disabled) {
- res.push(item.key);
- }
- }
- }
-
- return res.length ? res : null;
-}
-
-/**
- * 错误输出
- * @param msg 错误消息
- * @param args 附加参数
- */
-export function logError(msg: string, ...args: any[]): void {
- console.error(`DaTree: ${msg}`, ...args);
-}
-
-const toString = Object.prototype.toString;
-
-export function is(val: any, type: string): boolean {
- return toString.call(val) === `[object ${type}]`;
-}
-
-/**
- * 是否对象(Object)
- * @param val 值
- */
-export function isObject(val: any): boolean {
- return val !== null && is(val, "Object");
-}
-
-/**
- * 是否数字(Number)
- * @param val 值
- */
-export function isNumber(val: any): boolean {
- return is(val, "Number");
-}
-
-/**
- * 是否字符串(String)
- * @param val 值
- */
-export function isString(val: any): boolean {
- return is(val, "String");
-}
-
-/**
- * 是否函数方法(Function)
- * @param val 值
- */
-export function isFunction(val: any): boolean {
- return typeof val === "function";
-}
-
-/**
- * 是否布尔(Boolean)
- * @param val 值
- */
-export function isBoolean(val: any): boolean {
- return is(val, "Boolean");
-}
-
-/**
- * 是否数组(Array)
- * @param val 值
- */
-export function isArray(val: any): boolean {
- return val && Array.isArray(val);
-}
diff --git a/src/composables/useTheme.ts b/src/composables/useTheme.ts
index b5ab3ee..2f7ea7c 100644
--- a/src/composables/useTheme.ts
+++ b/src/composables/useTheme.ts
@@ -1,59 +1,130 @@
-import { ref, computed } from "vue";
+import { ref, watch } from "vue";
import type { ConfigProviderThemeVars } from "wot-design-uni";
-/* 默认的主题list */
+/* 默认的主题色列表 */
export const colorColumns = [
- {
- value: "#0055FE",
- label: "蓝色",
- },
- {
- value: "#CD5C5C",
- label: "红色",
- },
- {
- value: "#228B22",
- label: "绿色",
- },
+ { 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: "自然绿" },
];
-/* 默认的主题 */
-export const initThemState = "light";
+/* 存储键名 */
+const THEME_STORAGE_KEY = "app_theme_mode";
+const THEME_COLOR_STORAGE_KEY = "app_theme_color";
-/* 默认的主题变量 - 只使用wot-design-uni支持的变量 */
-export const initThemeVars: ConfigProviderThemeVars = {
- colorTheme: colorColumns[0].value,
+/* 从存储中获取主题模式 */
+const getStoredTheme = (): "light" | "dark" => {
+ try {
+ const stored = uni.getStorageSync(THEME_STORAGE_KEY);
+ return stored === "dark" ? "dark" : "light";
+ } catch {
+ return "light";
+ }
};
-/* 暗黑模式主题变量 */
-export const darkThemeVars: ConfigProviderThemeVars = {
- colorTheme: colorColumns[0].value,
+/* 从存储中获取主题色 */
+const getStoredThemeColor = (): string => {
+ try {
+ const stored = uni.getStorageSync(THEME_COLOR_STORAGE_KEY);
+ return stored || colorColumns[0].value;
+ } catch {
+ return colorColumns[0].value;
+ }
+};
+
+/* 保存主题模式到存储 */
+const saveThemeToStorage = (theme: "light" | "dark") => {
+ try {
+ uni.setStorageSync(THEME_STORAGE_KEY, theme);
+ } catch (error) {
+ console.error("保存主题模式失败:", error);
+ }
+};
+
+/* 保存主题色到存储 */
+const saveThemeColorToStorage = (color: string) => {
+ try {
+ uni.setStorageSync(THEME_COLOR_STORAGE_KEY, color);
+ } catch (error) {
+ console.error("保存主题色失败:", error);
+ }
+};
+
+/* 应用暗黑模式的 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");
+ }
+ }
+ // #endif
+
+ // #ifdef MP
+ // 小程序环境中设置页面样式
+ try {
+ const pages = getCurrentPages();
+ if (pages.length > 0) {
+ const currentPage = pages[pages.length - 1];
+ if (currentPage && currentPage.$vm) {
+ // 这里可以根据需要设置页面样式
+ console.log("小程序暗黑模式:", isDark ? "开启" : "关闭");
+ }
+ }
+ } catch (error) {
+ console.error("设置小程序页面样式失败:", error);
+ }
+ // #endif
};
/* 主题状态 */
-export const themeState = ref(initThemState);
+export const theme = ref<"light" | "dark">(getStoredTheme());
/* 主题变量 */
-export const themeVars = ref(initThemeVars);
-
-/* 计算属性:根据主题状态返回对应的主题变量 */
-export const computedThemeVars = computed(() => {
- const baseVars = themeState.value === "dark" ? darkThemeVars : initThemeVars;
- return {
- ...baseVars,
- ...themeVars.value,
- };
+export const themeVars = ref({
+ colorTheme: getStoredThemeColor(),
});
-/* 切换主题 */
+/* 监听主题模式变化,应用 body 样式 */
+watch(
+ theme,
+ (newTheme) => {
+ saveThemeToStorage(newTheme);
+ applyDarkModeBodyStyle(newTheme === "dark");
+ },
+ { immediate: true }
+);
+
+/* 监听主题色变化,保存到存储 */
+watch(
+ () => themeVars.value.colorTheme,
+ (newColor) => {
+ if (newColor) {
+ saveThemeColorToStorage(newColor);
+ }
+ },
+ { immediate: true }
+);
+
+/* 切换主题模式 */
export const toggleTheme = () => {
- themeState.value = themeState.value === "light" ? "dark" : "light";
- // 更新主题变量
- const newBaseVars = themeState.value === "dark" ? darkThemeVars : initThemeVars;
- themeVars.value = {
- ...newBaseVars,
- colorTheme: themeVars.value.colorTheme, // 保持用户选择的主题色
- };
+ theme.value = theme.value === "light" ? "dark" : "light";
};
/* 设置主题色 */
@@ -64,13 +135,37 @@ export const setThemeColor = (color: string) => {
};
};
+/* 重置主题 */
+export const resetTheme = () => {
+ theme.value = "light";
+ setThemeColor(colorColumns[0].value);
+};
+
+/* 初始化主题 */
+export const initTheme = () => {
+ // 应用当前主题的 body 样式
+ applyDarkModeBodyStyle(theme.value === "dark");
+
+ // 确保主题变量已正确设置
+ if (!themeVars.value.colorTheme) {
+ themeVars.value.colorTheme = getStoredThemeColor();
+ }
+
+ console.log("主题初始化完成:", {
+ mode: theme.value,
+ color: themeVars.value.colorTheme,
+ });
+};
+
/* 导出主题相关的工具 */
export const useTheme = () => {
return {
- themeState,
- themeVars: computedThemeVars,
+ theme,
+ themeVars,
toggleTheme,
setThemeColor,
+ resetTheme,
+ initTheme,
colorColumns,
};
};
diff --git a/src/layouts/default.vue b/src/layouts/default.vue
index 54d7c3e..bdd524f 100644
--- a/src/layouts/default.vue
+++ b/src/layouts/default.vue
@@ -1,11 +1,7 @@
-
+
+
+
diff --git a/src/main.ts b/src/main.ts
index a2d3100..5a1b638 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -3,6 +3,7 @@ import App from "./App.vue";
import "uno.css";
import "@/styles/global.scss";
+import "@/styles/wot-theme.scss";
import { setupStore } from "@/store";
diff --git a/src/pages/index/index.vue b/src/pages/index/index.vue
index 3ce1e8c..0702165 100644
--- a/src/pages/index/index.vue
+++ b/src/pages/index/index.vue
@@ -252,6 +252,18 @@ onReady(() => {
loadVisitStatsData();
loadVisitTrendData();
});
+
+onShow(() => {
+ // 确保 tabbar 状态正确
+ const pages = getCurrentPages();
+ if (pages.length > 0) {
+ const currentPage = pages[pages.length - 1];
+ if (currentPage.route === "pages/index/index") {
+ // 通过事件通知 tabbar 布局更新状态
+ uni.$emit("updateTabbar", "index");
+ }
+ }
+});
diff --git a/src/pages/mine/settings/theme/index.vue b/src/pages/mine/settings/theme/index.vue
index 2b60615..cffd9ab 100644
--- a/src/pages/mine/settings/theme/index.vue
+++ b/src/pages/mine/settings/theme/index.vue
@@ -7,18 +7,18 @@
-
+
-
-
+
+
-
+
-
+
+
-
+
-
-
+
+
+
+
主要按钮
-
-
+
+
主题色文本
-
-
+
+
主题色边框
-
-
+
+
标签
-
-
-
+
+
+
-
- 重置为默认主题
-
+
+ 重置为默认主题
+
@@ -88,21 +107,24 @@
+
+
请输入十六进制颜色值
-
支持格式:#RGB 或 #RRGGBB
+
+