feat(用户信息): 添加未读消息数量提取功能并优化显示逻辑
在多个模块中添加统一的未读消息数量提取函数,支持从不同字段获取未读数量 优化底部导航栏的未读消息显示逻辑,改为计算属性方式 移除冗余代码并更新用户信息处理逻辑
Showing
3 changed files
with
63 additions
and
32 deletions
| ... | @@ -39,10 +39,9 @@ | ... | @@ -39,10 +39,9 @@ |
| 39 | </template> | 39 | </template> |
| 40 | 40 | ||
| 41 | <script setup> | 41 | <script setup> |
| 42 | -import { ref, computed, onMounted } from 'vue' | 42 | +import { computed } from 'vue' |
| 43 | import { useRoute, useRouter } from 'vue-router' | 43 | import { useRoute, useRouter } from 'vue-router' |
| 44 | import { useAuth } from '@/contexts/auth' | 44 | import { useAuth } from '@/contexts/auth' |
| 45 | -import { showToast } from 'vant' | ||
| 46 | import { useUserInfo } from '@/composables/useUserInfo' | 45 | import { useUserInfo } from '@/composables/useUserInfo' |
| 47 | 46 | ||
| 48 | const route = useRoute() | 47 | const route = useRoute() |
| ... | @@ -50,32 +49,10 @@ const router = useRouter() | ... | @@ -50,32 +49,10 @@ const router = useRouter() |
| 50 | const { currentUser } = useAuth() | 49 | const { currentUser } = useAuth() |
| 51 | const { getUserInfoFromLocal } = useUserInfo() | 50 | const { getUserInfoFromLocal } = useUserInfo() |
| 52 | 51 | ||
| 53 | -/** | 52 | +const unread_msg_count = computed(() => { |
| 54 | - * @var {import('vue').Ref<number>} unread_msg_count | 53 | + const userInfo = currentUser.value || getUserInfoFromLocal() |
| 55 | - * @description 未读消息数量,来源于 getUserInfoAPI() 的返回值;用于控制"我的"图标右上角红点显示 | 54 | + const count = Number(userInfo?.unread_msg_count || 0) |
| 56 | - */ | 55 | + return Number.isFinite(count) ? count : 0 |
| 57 | -const unread_msg_count = ref(0) | ||
| 58 | - | ||
| 59 | -/** | ||
| 60 | - * @function load_unread_msg_count | ||
| 61 | - * @description 拉取用户信息,提取未读消息数量;未登录或接口失败时默认为 0 | ||
| 62 | - * @returns {Promise<void>} | ||
| 63 | - */ | ||
| 64 | -async function load_unread_msg_count() { | ||
| 65 | - try { | ||
| 66 | - const userInfo = getUserInfoFromLocal() | ||
| 67 | - if (userInfo) { | ||
| 68 | - unread_msg_count.value = +userInfo.unread_msg_count || 0 | ||
| 69 | - } else { | ||
| 70 | - unread_msg_count.value = 0 | ||
| 71 | - } | ||
| 72 | - } catch (e) { | ||
| 73 | - unread_msg_count.value = 0 | ||
| 74 | - } | ||
| 75 | -} | ||
| 76 | - | ||
| 77 | -onMounted(() => { | ||
| 78 | - load_unread_msg_count() | ||
| 79 | }) | 56 | }) |
| 80 | 57 | ||
| 81 | const navItems = [ | 58 | const navItems = [ | ... | ... |
| ... | @@ -21,6 +21,29 @@ export function useUserInfo() { | ... | @@ -21,6 +21,29 @@ export function useUserInfo() { |
| 21 | const error = ref(null) | 21 | const error = ref(null) |
| 22 | 22 | ||
| 23 | /** | 23 | /** |
| 24 | + * 从数据中提取未读消息数量 | ||
| 25 | + * @param {Object} data - 包含用户信息的响应数据 | ||
| 26 | + * @returns {number|null} 未读消息数量,或 null 如果无法提取 | ||
| 27 | + */ | ||
| 28 | + | ||
| 29 | + const get_unread_msg_count = (data) => { | ||
| 30 | + const candidates = [ | ||
| 31 | + data?.unread_msg_count, | ||
| 32 | + data?.user?.unread_msg_count, | ||
| 33 | + data?.user?.unread, | ||
| 34 | + data?.unread_msg, | ||
| 35 | + data?.unread, | ||
| 36 | + ] | ||
| 37 | + | ||
| 38 | + for (const value of candidates) { | ||
| 39 | + const num = Number(value) | ||
| 40 | + if (Number.isFinite(num)) return num | ||
| 41 | + } | ||
| 42 | + | ||
| 43 | + return null | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | + /** | ||
| 24 | * 刷新用户信息 | 47 | * 刷新用户信息 |
| 25 | * @returns {Promise<Object>} 用户信息对象 | 48 | * @returns {Promise<Object>} 用户信息对象 |
| 26 | * @throws {Error} 获取失败时抛出错误 | 49 | * @throws {Error} 获取失败时抛出错误 |
| ... | @@ -40,6 +63,11 @@ export function useUserInfo() { | ... | @@ -40,6 +63,11 @@ export function useUserInfo() { |
| 40 | ...data.checkin | 63 | ...data.checkin |
| 41 | } | 64 | } |
| 42 | 65 | ||
| 66 | + const unread = get_unread_msg_count(data) | ||
| 67 | + if (unread !== null) { | ||
| 68 | + mergedUser.unread_msg_count = unread | ||
| 69 | + } | ||
| 70 | + | ||
| 43 | // 更新本地存储 | 71 | // 更新本地存储 |
| 44 | localStorage.setItem('currentUser', JSON.stringify(mergedUser)) | 72 | localStorage.setItem('currentUser', JSON.stringify(mergedUser)) |
| 45 | 73 | ... | ... |
| 1 | /* | 1 | /* |
| 2 | * @Date: 2025-03-20 21:11:31 | 2 | * @Date: 2025-03-20 21:11:31 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2025-12-18 11:17:16 | 4 | + * @LastEditTime: 2026-01-18 22:32:53 |
| 5 | * @FilePath: /mlaj/src/contexts/auth.js | 5 | * @FilePath: /mlaj/src/contexts/auth.js |
| 6 | * @Description: 认证上下文管理模块,提供用户认证状态管理、登录登出功能 | 6 | * @Description: 认证上下文管理模块,提供用户认证状态管理、登录登出功能 |
| 7 | */ | 7 | */ |
| ... | @@ -12,7 +12,6 @@ import { logoutAPI, getUserInfoAPI } from '@/api/users' | ... | @@ -12,7 +12,6 @@ import { logoutAPI, getUserInfoAPI } from '@/api/users' |
| 12 | import { getAuthInfoAPI } from '@/api/auth' | 12 | import { getAuthInfoAPI } from '@/api/auth' |
| 13 | import { clearAuthHeaders, setAuthHeaders } from '@/utils/axios' | 13 | import { clearAuthHeaders, setAuthHeaders } from '@/utils/axios' |
| 14 | import { applyUserInfoAuth, getUserInfoFromStorage, removeUserInfoFromStorage } from '@/utils/auth_user_info' | 14 | import { applyUserInfoAuth, getUserInfoFromStorage, removeUserInfoFromStorage } from '@/utils/auth_user_info' |
| 15 | -import { ONE_DAY_MS } from '@/common/constants' | ||
| 16 | 15 | ||
| 17 | // 创建认证上下文的Symbol key,用于provide/inject依赖注入 | 16 | // 创建认证上下文的Symbol key,用于provide/inject依赖注入 |
| 18 | // 使用Symbol确保key的唯一性,避免命名冲突 | 17 | // 使用Symbol确保key的唯一性,避免命名冲突 |
| ... | @@ -32,6 +31,23 @@ export function provideAuth() { | ... | @@ -32,6 +31,23 @@ export function provideAuth() { |
| 32 | // 加载状态标志,用于控制加载动画等UI展示 | 31 | // 加载状态标志,用于控制加载动画等UI展示 |
| 33 | const loading = ref(true) | 32 | const loading = ref(true) |
| 34 | 33 | ||
| 34 | + const get_unread_msg_count = (data) => { | ||
| 35 | + const candidates = [ | ||
| 36 | + data?.unread_msg_count, | ||
| 37 | + data?.user?.unread_msg_count, | ||
| 38 | + data?.user?.unread, | ||
| 39 | + data?.unread_msg, | ||
| 40 | + data?.unread, | ||
| 41 | + ] | ||
| 42 | + | ||
| 43 | + for (const value of candidates) { | ||
| 44 | + const num = Number(value) | ||
| 45 | + if (Number.isFinite(num)) return num | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | + return null | ||
| 49 | + } | ||
| 50 | + | ||
| 35 | /** | 51 | /** |
| 36 | * 检查登录token是否过期 | 52 | * 检查登录token是否过期 |
| 37 | * @returns {boolean} true表示token有效,false表示token已过期 | 53 | * @returns {boolean} true表示token有效,false表示token已过期 |
| ... | @@ -67,7 +83,12 @@ export function provideAuth() { | ... | @@ -67,7 +83,12 @@ export function provideAuth() { |
| 67 | // 从服务器获取用户信息并更新本地存储 | 83 | // 从服务器获取用户信息并更新本地存储 |
| 68 | const { code, data } = await getUserInfoAPI(); | 84 | const { code, data } = await getUserInfoAPI(); |
| 69 | if (code === 1) { | 85 | if (code === 1) { |
| 70 | - currentUser.value = { ...data.user, ...data.checkin } | 86 | + const unread = get_unread_msg_count(data) |
| 87 | + currentUser.value = { | ||
| 88 | + ...data.user, | ||
| 89 | + ...data.checkin, | ||
| 90 | + ...(unread !== null ? { unread_msg_count: unread } : {}), | ||
| 91 | + } | ||
| 71 | localStorage.setItem('currentUser', JSON.stringify(currentUser.value)) | 92 | localStorage.setItem('currentUser', JSON.stringify(currentUser.value)) |
| 72 | // 重新设置认证头 | 93 | // 重新设置认证头 |
| 73 | const userInfo = getUserInfoFromStorage() | 94 | const userInfo = getUserInfoFromStorage() |
| ... | @@ -97,7 +118,12 @@ export function provideAuth() { | ... | @@ -97,7 +118,12 @@ export function provideAuth() { |
| 97 | try { | 118 | try { |
| 98 | const userRes = await getUserInfoAPI(); | 119 | const userRes = await getUserInfoAPI(); |
| 99 | if (userRes.code === 1) { | 120 | if (userRes.code === 1) { |
| 100 | - currentUser.value = { ...userRes.data.user, ...userRes.data.checkin } | 121 | + const unread = get_unread_msg_count(userRes.data) |
| 122 | + currentUser.value = { | ||
| 123 | + ...userRes.data.user, | ||
| 124 | + ...userRes.data.checkin, | ||
| 125 | + ...(unread !== null ? { unread_msg_count: unread } : {}), | ||
| 126 | + } | ||
| 101 | } else { | 127 | } else { |
| 102 | currentUser.value = { ...data.user, ...data.checkin } | 128 | currentUser.value = { ...data.user, ...data.checkin } |
| 103 | } | 129 | } | ... | ... |
-
Please register or login to post a comment