hookehuyr

feat(底部导航): 添加未读消息红点提示功能

在底部导航栏的"我的"图标上添加未读消息红点提示
通过调用用户信息接口获取未读消息数量
未登录或接口失败时默认不显示红点
...@@ -39,6 +39,7 @@ declare module 'vue' { ...@@ -39,6 +39,7 @@ declare module 'vue' {
39 UserAgreement: typeof import('./components/ui/UserAgreement.vue')['default'] 39 UserAgreement: typeof import('./components/ui/UserAgreement.vue')['default']
40 VanActionSheet: typeof import('vant/es')['ActionSheet'] 40 VanActionSheet: typeof import('vant/es')['ActionSheet']
41 VanBackTop: typeof import('vant/es')['BackTop'] 41 VanBackTop: typeof import('vant/es')['BackTop']
42 + VanBadge: typeof import('vant/es')['Badge']
42 VanButton: typeof import('vant/es')['Button'] 43 VanButton: typeof import('vant/es')['Button']
43 VanCalendar: typeof import('vant/es')['Calendar'] 44 VanCalendar: typeof import('vant/es')['Calendar']
44 VanCell: typeof import('vant/es')['Cell'] 45 VanCell: typeof import('vant/es')['Cell']
......
1 <!-- 1 <!--
2 * @Date: 2025-03-20 20:36:36 2 * @Date: 2025-03-20 20:36:36
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-12-01 16:14:16 4 + * @LastEditTime: 2025-12-08 13:49:00
5 * @FilePath: /mlaj/src/components/layout/BottomNav.vue 5 * @FilePath: /mlaj/src/components/layout/BottomNav.vue
6 * @Description: 文件描述 6 * @Description: 文件描述
7 --> 7 -->
...@@ -18,18 +18,20 @@ ...@@ -18,18 +18,20 @@
18 'text-gray-500': !isActive(item.path) 18 'text-gray-500': !isActive(item.path)
19 }" 19 }"
20 > 20 >
21 - <svg 21 + <van-badge :dot="item.path === '/profile' && unread_msg_count > 0">
22 - xmlns="http://www.w3.org/2000/svg" 22 + <svg
23 - class="h-6 w-6 mb-1" 23 + xmlns="http://www.w3.org/2000/svg"
24 - :class="{ 24 + class="h-6 w-6 mb-1"
25 - 'text-green-500': isActive(item.path), 25 + :class="{
26 - 'text-gray-500': !isActive(item.path) 26 + 'text-green-500': isActive(item.path),
27 - }" 27 + 'text-gray-500': !isActive(item.path)
28 - fill="none" 28 + }"
29 - viewBox="0 0 24 24" 29 + fill="none"
30 - stroke="currentColor" 30 + viewBox="0 0 24 24"
31 - v-html="item.icon" 31 + stroke="currentColor"
32 - /> 32 + v-html="item.icon"
33 + />
34 + </van-badge>
33 <span class="text-xs">{{ item.name }}</span> 35 <span class="text-xs">{{ item.name }}</span>
34 </div> 36 </div>
35 </div> 37 </div>
...@@ -37,15 +39,44 @@ ...@@ -37,15 +39,44 @@
37 </template> 39 </template>
38 40
39 <script setup> 41 <script setup>
40 -import { computed } from 'vue' 42 +import { ref, computed, onMounted } from 'vue'
41 import { useRoute, useRouter } from 'vue-router' 43 import { useRoute, useRouter } from 'vue-router'
42 import { useAuth } from '@/contexts/auth' 44 import { useAuth } from '@/contexts/auth'
43 import { showToast } from 'vant' 45 import { showToast } from 'vant'
46 +import { getUserInfoAPI } from '@/api/users'
44 47
45 const route = useRoute() 48 const route = useRoute()
46 const router = useRouter() 49 const router = useRouter()
47 const { currentUser } = useAuth() 50 const { currentUser } = useAuth()
48 51
52 +/**
53 + * @var {import('vue').Ref<number>} unread_msg_count
54 + * @description 未读消息数量,来源于 getUserInfoAPI() 的返回值;用于控制“我的”图标右上角红点显示
55 + */
56 +const unread_msg_count = ref(0)
57 +
58 +/**
59 + * @function load_unread_msg_count
60 + * @description 拉取用户信息,提取未读消息数量;未登录或接口失败时默认为 0
61 + * @returns {Promise<void>}
62 + */
63 +async function load_unread_msg_count() {
64 + try {
65 + const { code, data } = await getUserInfoAPI()
66 + if (code) {
67 + unread_msg_count.value = +data.unread_msg_count || 0
68 + } else {
69 + unread_msg_count.value = 0
70 + }
71 + } catch (e) {
72 + unread_msg_count.value = 0
73 + }
74 +}
75 +
76 +onMounted(() => {
77 + load_unread_msg_count()
78 +})
79 +
49 const navItems = [ 80 const navItems = [
50 { 81 {
51 name: '首页', 82 name: '首页',
......