feat(user): 我的页面消息菜单添加未读红点
- 新增 showMessageBadge 计算属性,从 userStore.unreadMsgCount 读取 - 为菜单项添加 key 属性,用于识别消息菜单 - 添加 .menu-badge 样式,与 TabBar 红点保持一致 - 红点仅在未读消息数大于 0 时显示 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Showing
2 changed files
with
51 additions
and
3 deletions
| 1 | +## [2026-02-13] - 我的页面消息红点显示 | ||
| 2 | + | ||
| 3 | +### 新增 | ||
| 4 | +- 我的页面消息菜单项添加未读红点显示 | ||
| 5 | +- 新增 showMessageBadge 计算属性,从 userStore.unreadMsgCount 读取未读状态 | ||
| 6 | +- 添加 .menu-badge 样式,与 TabBar 红点保持一致 | ||
| 7 | + | ||
| 8 | +### 优化 | ||
| 9 | +- 为菜单项添加 key 属性,便于识别特定菜单项 | ||
| 10 | +- 红点逻辑与 TabBar 完全一致,确保同步显示 | ||
| 11 | + | ||
| 12 | +--- | ||
| 13 | + | ||
| 14 | +**详细信息**: | ||
| 15 | +- **影响文件**: src/pages/mine/index.vue | ||
| 16 | +- **技术栈**: Vue 3, Pinia | ||
| 17 | +- **测试状态**: 已通过 | ||
| 18 | +- **备注**: 红点在 unreadMsgCount > 0 时显示 | ||
| 19 | + | ||
| 20 | +--- | ||
| 21 | + | ||
| 1 | ## [2026-02-12] - 优化反馈列表和消息页面图片加载 | 22 | ## [2026-02-12] - 优化反馈列表和消息页面图片加载 |
| 2 | 23 | ||
| 3 | ### 新增 | 24 | ### 新增 | ... | ... |
| ... | @@ -56,10 +56,12 @@ | ... | @@ -56,10 +56,12 @@ |
| 56 | class="flex items-center justify-between p-[24rpx] rounded-[20rpx] active:bg-gray-50 transition-all duration-200" | 56 | class="flex items-center justify-between p-[24rpx] rounded-[20rpx] active:bg-gray-50 transition-all duration-200" |
| 57 | @tap="handleMenuClick(item)"> | 57 | @tap="handleMenuClick(item)"> |
| 58 | <view class="flex items-center"> | 58 | <view class="flex items-center"> |
| 59 | - <!-- Icon with soft background --> | 59 | + <!-- Icon with soft background and badge --> |
| 60 | - <view class="w-[72rpx] h-[72rpx] rounded-[20rpx] flex items-center justify-center mr-[24rpx]" | 60 | + <view class="w-[72rpx] h-[72rpx] rounded-[20rpx] flex items-center justify-center mr-[24rpx] relative" |
| 61 | :class="item.bgClass"> | 61 | :class="item.bgClass"> |
| 62 | <IconFont :name="item.icon" size="22" :color="item.iconColor" /> | 62 | <IconFont :name="item.icon" size="22" :color="item.iconColor" /> |
| 63 | + <!-- 消息红点(与 TabBar 样式保持一致)--> | ||
| 64 | + <view v-if="item.key === 'message' && showMessageBadge" class="menu-badge"></view> | ||
| 63 | </view> | 65 | </view> |
| 64 | <text class="text-[30rpx] text-gray-800 font-medium tracking-wide">{{ item.title }}</text> | 66 | <text class="text-[30rpx] text-gray-800 font-medium tracking-wide">{{ item.title }}</text> |
| 65 | </view> | 67 | </view> |
| ... | @@ -108,6 +110,11 @@ const userStore = useUserStore() | ... | @@ -108,6 +110,11 @@ const userStore = useUserStore() |
| 108 | const userInfo = computed(() => userStore.userInfo) | 110 | const userInfo = computed(() => userStore.userInfo) |
| 109 | 111 | ||
| 110 | /** | 112 | /** |
| 113 | + * @description 是否显示消息红点(与 TabBar 逻辑一致) | ||
| 114 | + */ | ||
| 115 | +const showMessageBadge = computed(() => userStore.unreadMsgCount > 0) | ||
| 116 | + | ||
| 117 | +/** | ||
| 111 | * @description 页面加载时获取用户信息(首次进入) | 118 | * @description 页面加载时获取用户信息(首次进入) |
| 112 | */ | 119 | */ |
| 113 | useLoad(() => { | 120 | useLoad(() => { |
| ... | @@ -132,6 +139,7 @@ useDidShow(() => { | ... | @@ -132,6 +139,7 @@ useDidShow(() => { |
| 132 | // Using subtle background colors for icons to add vitality without being "playful" | 139 | // Using subtle background colors for icons to add vitality without being "playful" |
| 133 | const menuItems = [ | 140 | const menuItems = [ |
| 134 | { | 141 | { |
| 142 | + key: 'plan', | ||
| 135 | title: '我的计划书', | 143 | title: '我的计划书', |
| 136 | icon: 'order', | 144 | icon: 'order', |
| 137 | path: '/pages/plan/index', | 145 | path: '/pages/plan/index', |
| ... | @@ -139,6 +147,7 @@ const menuItems = [ | ... | @@ -139,6 +147,7 @@ const menuItems = [ |
| 139 | bgClass: 'bg-blue-50' | 147 | bgClass: 'bg-blue-50' |
| 140 | }, | 148 | }, |
| 141 | { | 149 | { |
| 150 | + key: 'message', | ||
| 142 | title: '我的消息', | 151 | title: '我的消息', |
| 143 | icon: 'message', | 152 | icon: 'message', |
| 144 | path: '/pages/message/index', | 153 | path: '/pages/message/index', |
| ... | @@ -146,6 +155,7 @@ const menuItems = [ | ... | @@ -146,6 +155,7 @@ const menuItems = [ |
| 146 | bgClass: 'bg-emerald-50' | 155 | bgClass: 'bg-emerald-50' |
| 147 | }, | 156 | }, |
| 148 | { | 157 | { |
| 158 | + key: 'favorites', | ||
| 149 | title: '我的收藏', | 159 | title: '我的收藏', |
| 150 | icon: 'star', | 160 | icon: 'star', |
| 151 | path: '/pages/favorites/index', | 161 | path: '/pages/favorites/index', |
| ... | @@ -153,6 +163,7 @@ const menuItems = [ | ... | @@ -153,6 +163,7 @@ const menuItems = [ |
| 153 | bgClass: 'bg-amber-50' | 163 | bgClass: 'bg-amber-50' |
| 154 | }, | 164 | }, |
| 155 | { | 165 | { |
| 166 | + key: 'help', | ||
| 156 | title: '帮助中心', | 167 | title: '帮助中心', |
| 157 | icon: 'service', | 168 | icon: 'service', |
| 158 | path: '/pages/help-center/index', | 169 | path: '/pages/help-center/index', |
| ... | @@ -160,6 +171,7 @@ const menuItems = [ | ... | @@ -160,6 +171,7 @@ const menuItems = [ |
| 160 | bgClass: 'bg-indigo-50' | 171 | bgClass: 'bg-indigo-50' |
| 161 | }, | 172 | }, |
| 162 | { | 173 | { |
| 174 | + key: 'feedback', | ||
| 163 | title: '意见反馈', | 175 | title: '意见反馈', |
| 164 | icon: 'edit', | 176 | icon: 'edit', |
| 165 | path: '/pages/feedback-list/index', | 177 | path: '/pages/feedback-list/index', |
| ... | @@ -228,5 +240,20 @@ const handleLogout = async () => { | ... | @@ -228,5 +240,20 @@ const handleLogout = async () => { |
| 228 | </script> | 240 | </script> |
| 229 | 241 | ||
| 230 | <style lang="less"> | 242 | <style lang="less"> |
| 231 | -/* No custom CSS needed, all Tailwind */ | 243 | +/** |
| 244 | + * 菜单红点样式(与 TabBar 保持一致) | ||
| 245 | + * @description 使用行业标准的小红点设计:右上角、16rpx、红色背景 | ||
| 246 | + */ | ||
| 247 | +.menu-badge { | ||
| 248 | + position: absolute; | ||
| 249 | + top: -4rpx; | ||
| 250 | + right: -4rpx; | ||
| 251 | + width: 16rpx; | ||
| 252 | + height: 16rpx; | ||
| 253 | + background-color: #ff4d4f; | ||
| 254 | + border-radius: 50%; | ||
| 255 | + border: 2rpx solid #fff; | ||
| 256 | + box-shadow: 0 2rpx 8rpx rgba(255, 77, 79, 0.3); | ||
| 257 | + z-index: 1; | ||
| 258 | +} | ||
| 232 | </style> | 259 | </style> | ... | ... |
-
Please register or login to post a comment