From 1bfe7964b361e86a3b1f80733d3924f097755d78 Mon Sep 17 00:00:00 2001
From: "Ray.Hao" <1490493387@qq.com>
Date: Fri, 15 May 2026 23:27:56 +0800
Subject: [PATCH] =?UTF-8?q?refactor(mine):=20=E6=81=A2=E5=A4=8D=E4=B8=AA?=
=?UTF-8?q?=E4=BA=BA=E4=B8=AD=E5=BF=83=E9=A1=B5=E9=9D=A2=E4=BC=98=E5=8C=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 修复暗黑模式图标颜色问题
- 优化页面布局,新增系统设置入口
- 重构异步代码为 async/await 模式
---
.cursor/rules/css-style-guide.mdc | 274 ------------------------------
components.d.ts | 3 +
skills-lock.json | 10 --
src/pages/mine/account/index.vue | 74 ++++----
src/pages/mine/index.vue | 31 +++-
src/styles/theme.scss | 2 +-
6 files changed, 63 insertions(+), 331 deletions(-)
delete mode 100644 .cursor/rules/css-style-guide.mdc
delete mode 100644 skills-lock.json
diff --git a/.cursor/rules/css-style-guide.mdc b/.cursor/rules/css-style-guide.mdc
deleted file mode 100644
index 2e3628f..0000000
--- a/.cursor/rules/css-style-guide.mdc
+++ /dev/null
@@ -1,274 +0,0 @@
----
-alwaysApply: true
----
-
-# CSS样式与UnoCSS使用规范
-
-## 样式选择原则
-
-### UnoCSS原子类使用规则
-
-- **≤5个原子类**: 直接使用UnoCSS原子类
-- **>5个原子类**: 必须提取为语义化CSS类,避免模板膨胀
-
-```vue
-
-
-```
-
-### 优先使用UnoCSS预设shortcuts
-
-参考 [unocss.config.ts](mdc:unocss.config.ts) 中定义的shortcuts:
-
-```typescript
-// 已定义的shortcuts,优先使用
-"flex-center": "flex justify-center items-center"
-"flex-start": "flex justify-start items-center"
-"flex-between": "flex justify-between items-center"
-"flex-col-center": "flex flex-col items-center"
-```
-
-## CSS类命名规范
-
-### BEM命名规范
-
-严格遵循BEM (Block\_\_Element--Modifier) 命名规范:
-
-```scss
-// Block: 独立的功能组件
-.user-profile {
-}
-
-// Element: Block的子元素
-.user-profile__avatar {
-}
-.user-profile__action {
-}
-.user-profile__badge {
-}
-
-// Modifier: Block或Element的状态/变体
-.user-profile--dark {
-}
-.user-profile__action--active {
-}
-```
-
-### 命名要求
-
-1. **使用简短、易理解的英文单词**
-2. **符合业务场景语义**
-3. **避免缩写,除非是通用缩写**
-
-```scss
-// ✅ 好的命名
-.user-profile__action
-.stats-card
-.service-icon
-.tool-item
-
-// ❌ 坏的命名
-.up-act
-.sc
-.si
-.ti
-```
-
-## 样式组织原则
-
-### 1. 复用性判断
-
-- 同一组合在项目中出现 >3次 → 提取为语义化类
-- 具备明确语义的区域 → 提取为语义化类
-- 需要主题适配的样式 → 提取为语义化类
-
-### 2. 常用组合添加到shortcuts
-
-当发现重复的原子类组合时,添加到 [unocss.config.ts](mdc:unocss.config.ts):
-
-```typescript
-shortcuts: [
- {
- // 现有shortcuts...
-
- // 新增常用组合
- "card-container": "mx-30rpx my-20rpx bg-white rounded-16rpx shadow-sm",
- "action-button": "flex-center w-70rpx h-70rpx bg-white bg-opacity-90 rounded-full",
- },
-];
-```
-
-### 3. 主题适配
-
-使用wot-design-uni的CSS变量或自定义变量:
-
-```scss
-// ✅ 使用主题变量
-.service-icon {
- background-color: var(--wot-color-bg-light, #f3f4f6);
-}
-
-// ✅ 响应式主题色
-:color="themeStore.isDark ? '#fff' : '#333'";
-```
-
-### 4. 暗黑模式适配规则
-
-#### 优先级顺序
-
-1. **优先使用wot-design-uni内置变量** - 自动适配暗黑模式
-2. **使用项目 [theme.scss](mdc:src/styles/theme.scss) 定义的变量** - 统一管理主题色
-3. **最后考虑组件内部定义** - 仅用于特殊场景
-
-#### 自定义主题变量定义
-
-当需要自定义颜色时,必须在 [theme.scss](mdc:src/styles/theme.scss) 中定义:
-
-```scss
-/* 在 theme.scss 中添加自定义变量 */
-:root,
-page {
- --custom-text-color: #333333;
- --custom-bg-color: #ffffff;
- --custom-border-color: #e5e7eb;
-}
-
-.wot-theme-dark {
- --custom-text-color: #ffffff;
- --custom-bg-color: #1a1a1a;
- --custom-border-color: #374151;
-}
-```
-
-#### 组件中使用主题变量
-
-```scss
-// ✅ 推荐:使用wot内置变量
-.my-component {
- background-color: var(--wot-color-bg);
- color: var(--wot-color-text);
-}
-
-// ✅ 推荐:使用theme.scss定义的变量
-.my-component {
- background-color: var(--custom-bg-color);
- border-color: var(--custom-border-color);
-}
-
-// ❌ 避免:组件内部硬编码暗黑模式
-.my-component {
- background-color: #ffffff;
-}
-.wot-theme-dark .my-component {
- background-color: #1a1a1a;
-}
-```
-
-#### 图标和文字颜色适配
-
-```vue
-
-
-
-
-
- 文本
-
-
-
-```
-
-## 实践示例
-
-### 数据统计卡片
-
-```vue
-
-
-
-
- 0.00
- 我的余额
-
-
-
-```
-
-### 用户操作按钮
-
-```vue
-
-
-
-
-
-
-
-```
-
-## 禁止项
-
-❌ **不要在SCSS中重复定义UnoCSS已提供的工具类**
-❌ **不要使用 `@apply` 指令**
-❌ **不要把一次性样式放到全局**
-❌ **不要使用非语义化的类名**
-❌ **不要在模板中堆叠超过5个原子类**
-❌ **不要混用UnoCSS原子类和自定义CSS类** - 一个元素应该只使用原子类或只使用自定义类,避免样式管理混乱
-
-### 混用问题示例
-
-```vue
-
-内容
-内容
-
-
-内容
-
-
-内容
-内容
-```
-
-### 解决方案
-
-当需要混用时,选择以下方案之一:
-
-1. **原子类数量≤5个**:移除自定义类,只使用原子类
-2. **原子类数量>5个**:将所有样式合并到自定义类中
-3. **语义明确的区域**:优先使用自定义类,将原子类样式合并进去
-
-## 组件库样式覆盖
-
-使用wot-design-uni组件时:
-
-- 使用 `custom-class` 传入类名
-- 使用 `:deep()` 进行样式穿透
-- 添加 `!important` 提升优先级
-
-```vue
-
- 退出登录
-
-
-
-```
diff --git a/components.d.ts b/components.d.ts
index 172664f..c2552c6 100644
--- a/components.d.ts
+++ b/components.d.ts
@@ -10,6 +10,7 @@ declare module 'vue' {
CuDateQuery: typeof import('./src/components/cu-date-query/index.vue')['default']
CustomNavbar: typeof import('./src/components/custom-navbar/index.vue')['default']
CustomTree: typeof import('./src/components/custom-tree/index.vue')['default']
+ EmptyState: typeof import('./src/components/empty-state/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']
@@ -23,6 +24,7 @@ declare module 'vue' {
WdButton: typeof import('wot-design-uni/components/wd-button/wd-button.vue')['default']
WdCalendar: typeof import('wot-design-uni/components/wd-calendar/wd-calendar.vue')['default']
WdCard: typeof import('wot-design-uni/components/wd-card/wd-card.vue')['default']
+ WdCascader: typeof import('wot-design-uni/components/wd-cascader/wd-cascader.vue')['default']
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']
WdCheckbox: typeof import('wot-design-uni/components/wd-checkbox/wd-checkbox.vue')['default']
@@ -33,6 +35,7 @@ declare module 'vue' {
WdDivider: typeof import('wot-design-uni/components/wd-divider/wd-divider.vue')['default']
WdDropMenu: typeof import('wot-design-uni/components/wd-drop-menu/wd-drop-menu.vue')['default']
WdDropMenuItem: typeof import('wot-design-uni/components/wd-drop-menu-item/wd-drop-menu-item.vue')['default']
+ WdEmpty: typeof import('wot-design-uni/components/wd-empty/wd-empty.vue')['default']
WdFab: typeof import('wot-design-uni/components/wd-fab/wd-fab.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']
diff --git a/skills-lock.json b/skills-lock.json
deleted file mode 100644
index 4a3686e..0000000
--- a/skills-lock.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "version": 1,
- "skills": {
- "wot-ui": {
- "source": "wot-ui/wot-starter",
- "sourceType": "github",
- "computedHash": "b4f8b0577871b28dd12278f26961d015e378d7d4f11435599631f1ee6860c8eb"
- }
- }
-}
diff --git a/src/pages/mine/account/index.vue b/src/pages/mine/account/index.vue
index 685a0d8..ac9d175 100644
--- a/src/pages/mine/account/index.vue
+++ b/src/pages/mine/account/index.vue
@@ -273,58 +273,56 @@ const handleOpenDialog = (type: DialogType) => {
* @param contactType 联系方式类型 MOBILE: 手机号码 EMAIL: 邮箱
*/
const handleSendVerificationCode = async (contactType: string) => {
- if (contactType === "MOBILE") {
- mobileBindingFormRef.value.validate("mobile").then(({ valid }: { valid: boolean }) => {
+ try {
+ if (contactType === "MOBILE") {
+ const { valid } = await mobileBindingFormRef.value.validate("mobile");
if (valid) {
- UserAPI.sendVerificationCode(mobileBindingForm.mobile!, "MOBILE").then(() => {
- uni.showToast({ title: "验证码已发送", icon: "none" });
- startMobileCountdown();
- });
+ await UserAPI.sendVerificationCode(mobileBindingForm.mobile!, "MOBILE");
+ uni.showToast({ title: "验证码已发送", icon: "none" });
+ startMobileCountdown();
}
- });
- } else if (contactType === "EMAIL") {
- emailBindingFormRef.value.validate("email").then(({ valid }: { valid: boolean }) => {
+ } else if (contactType === "EMAIL") {
+ const { valid } = await emailBindingFormRef.value.validate("email");
if (valid) {
- UserAPI.sendVerificationCode(emailBindingForm.email!, "EMAIL").then(() => {
- uni.showToast({ title: "验证码已发送", icon: "none" });
- startEmailCountdown();
- });
+ await UserAPI.sendVerificationCode(emailBindingForm.email!, "EMAIL");
+ uni.showToast({ title: "验证码已发送", icon: "none" });
+ startEmailCountdown();
}
- });
+ }
+ } catch (error) {
+ console.error("发送验证码失败:", error);
}
};
// 提交表单
-function handleSubmit() {
- if (dialog.type === DialogType.PASSWORD) {
- passwordChangeFormRef.value.validate().then(({ valid }: { valid: boolean }) => {
+async function handleSubmit() {
+ try {
+ if (dialog.type === DialogType.PASSWORD) {
+ const { valid } = await passwordChangeFormRef.value.validate();
if (valid) {
- UserAPI.changePassword(passwordChangeForm).then(() => {
- uni.showToast({ title: "密码修改成功", icon: "none" });
- dialog.visible = false;
- });
+ await UserAPI.changePassword(passwordChangeForm);
+ uni.showToast({ title: "密码修改成功", icon: "none" });
+ dialog.visible = false;
}
- });
- } else if (dialog.type === DialogType.MOBILE) {
- mobileBindingFormRef.value.validate().then(({ valid }: { valid: boolean }) => {
+ } else if (dialog.type === DialogType.MOBILE) {
+ const { valid } = await mobileBindingFormRef.value.validate();
if (valid) {
- UserAPI.bindMobile(mobileBindingForm).then(() => {
- uni.showToast({ title: "手机号绑定成功", icon: "none" });
- dialog.visible = false;
- loadUserProfile();
- });
+ await UserAPI.bindMobile(mobileBindingForm);
+ uni.showToast({ title: "手机号绑定成功", icon: "none" });
+ dialog.visible = false;
+ loadUserProfile();
}
- });
- } else if (dialog.type === DialogType.EMAIL) {
- emailBindingFormRef.value.validate().then(({ valid }: { valid: boolean }) => {
+ } else if (dialog.type === DialogType.EMAIL) {
+ const { valid } = await emailBindingFormRef.value.validate();
if (valid) {
- UserAPI.bindEmail(emailBindingForm).then(() => {
- uni.showToast({ title: "邮箱绑定成功", icon: "none" });
- dialog.visible = false;
- loadUserProfile();
- });
+ await UserAPI.bindEmail(emailBindingForm);
+ uni.showToast({ title: "邮箱绑定成功", icon: "none" });
+ dialog.visible = false;
+ loadUserProfile();
}
- });
+ }
+ } catch (error) {
+ console.error("提交表单失败:", error);
}
}
diff --git a/src/pages/mine/index.vue b/src/pages/mine/index.vue
index 6c10661..c516bd8 100644
--- a/src/pages/mine/index.vue
+++ b/src/pages/mine/index.vue
@@ -159,9 +159,19 @@
帮助与支持
{
router.push({ path: "/pages/mine/settings/theme/index" });
};
+// 系统设置
+const openSettings = () => {
+ router.push({ path: "/pages/mine/settings/index" });
+};
+
// 用户协议
const openUserAgreement = () => {
router.push({ path: "/pages/mine/settings/agreement/index" });
@@ -844,6 +855,10 @@ const openOfficialAccount = () => {
height: 72rpx;
border-radius: 22rpx;
+ &--primary {
+ background: rgba(77, 128, 240, 0.12);
+ }
+
&--warning {
background: var(--color-warning-light);
}
@@ -853,11 +868,11 @@ const openOfficialAccount = () => {
}
&--success {
- background: var(--color-success-light);
+ background: rgba(52, 209, 157, 0.12);
}
&--teal {
- background: var(--color-success-light);
+ background: rgba(52, 209, 157, 0.12);
}
}
diff --git a/src/styles/theme.scss b/src/styles/theme.scss
index 7c44cda..c234f8d 100644
--- a/src/styles/theme.scss
+++ b/src/styles/theme.scss
@@ -146,7 +146,7 @@ page {
--color-text-secondary: #9ca3af;
--color-text-placeholder: #6b7280;
--color-text-disabled: #4b5563;
- --color-text-inverse: #1f2937;
+ --color-text-inverse: #ffffff;
// -----------------------------------------------------------------------
// 边框颜色