feat: 消息通知

This commit is contained in:
2026-05-31 09:51:57 +08:00
parent 1cc85f1c46
commit 74b6045220
10 changed files with 637 additions and 243 deletions

View File

@@ -1,11 +1,13 @@
import { createRouter, createWebHistory } from 'vue-router'
import { useUserInfoStore } from '@/stores/userInfo'
import { useGlobalStore } from '@/stores/global'
import { getUserLanguage } from '@/api/user'
import { fetchAllUnreadMessage } from '@/api/notification'
import i18n from '@/lang/index'
// 语言映射:后端格式 -> i18n 格式
const backendToI18nLanguage: Record<string, string> = {
'en': 'ENGLISH',
en: 'ENGLISH',
'zh-CN': 'CHINESE_SIMPLIFIED'
}
@@ -19,122 +21,126 @@ let languageSynced = false
* 3. 路由的name默认是文件名,如果文件名与name不一致,通过defineOptions({ name: 'componentName' })来设置
*/
const router = createRouter({
routes: [
{
path: '/',
name: 'home',
component: () => import('../views/home/index.vue')
},
{
path: '/collectionStory',
name: 'collectionStory',
component: () => import('../views/collectionStory/index.vue')
},
{
path: '/brand',
name: 'brand',
component: () => import('../views/brand/index.vue')
},
{
path: '/brand/:id',
name: 'brandDetail',
component: () => import('../views/brandDetail/index.vue')
},
{
path: '/digitalItem',
name: 'digitalItem',
component: () => import('../views/digitalItem/index.vue'),
meta: { cache: true }
},
{
path: '/digitalItem/:id',
name: 'digitalItemDetail',
component: () => import('../views/digitalDetail/index.vue')
},
{
path: '/settings',
name: 'settings',
component: () => import('@/views/setting/index.vue'),
meta: { cache: true }
},
{
path: '/shoppingCart', // 购物车
name: 'shoppingCart',
component: () => import('@/views/shoppingCart/index.vue')
},
{
path: '/notifications',
name: 'notifications',
component: () => import('@/views/notifications/index.vue')
},
{
path: '/wardrobe',
name: 'wardrobe',
component: () => import('@/views/wardrobe/index.vue')
},
{
path:'/account',
name:'account',
component:()=>import('@/views/account/index.vue')
},
{
path:'/pay',
name:'pay',
component:()=>import('@/views/pay/index.vue')
},
{
path: '/:pathMatch(.*)',
name: '404',
component: () => import('../views/404.vue')
}
],
history: createWebHistory('/')
routes: [
{
path: '/',
name: 'home',
component: () => import('../views/home/index.vue')
},
{
path: '/collectionStory',
name: 'collectionStory',
component: () => import('../views/collectionStory/index.vue')
},
{
path: '/brand',
name: 'brand',
component: () => import('../views/brand/index.vue')
},
{
path: '/brand/:id',
name: 'brandDetail',
component: () => import('../views/brandDetail/index.vue')
},
{
path: '/digitalItem',
name: 'digitalItem',
component: () => import('../views/digitalItem/index.vue'),
meta: { cache: true }
},
{
path: '/digitalItem/:id',
name: 'digitalItemDetail',
component: () => import('../views/digitalDetail/index.vue')
},
{
path: '/settings',
name: 'settings',
component: () => import('@/views/setting/index.vue'),
meta: { cache: true }
},
{
path: '/shoppingCart', // 购物车
name: 'shoppingCart',
component: () => import('@/views/shoppingCart/index.vue')
},
{
path: '/notifications',
name: 'notifications',
component: () => import('@/views/notifications/index.vue')
},
{
path: '/wardrobe',
name: 'wardrobe',
component: () => import('@/views/wardrobe/index.vue')
},
{
path: '/account',
name: 'account',
component: () => import('@/views/account/index.vue')
},
{
path: '/pay',
name: 'pay',
component: () => import('@/views/pay/index.vue')
},
{
path: '/:pathMatch(.*)',
name: '404',
component: () => import('../views/404.vue')
}
],
history: createWebHistory('/')
})
router.beforeEach((to, from, next) => {
next()
next()
})
router.afterEach(async () => {
// 检查用户是否已登录
const userInfoStore = useUserInfoStore()
const token = userInfoStore.state.token
if (!token) {
languageSynced = false // 未登录时重置同步状态
languageSynced = false
return
}
// 如果已经同步过,跳过
const globalStore = useGlobalStore()
fetchAllUnreadMessage().then((res) => {
console.log(res)
globalStore.setUnredCount(res.totalUnread)
})
if (languageSynced) {
return
}
try {
// 获取用户语言设置
const response = await getUserLanguage()
const userLanguage = (response as any)?.language // 后端返回 'en' 或 'zh-CN'
if (!userLanguage) {
return
}
// 转换为 i18n 格式
const i18nLanguage = backendToI18nLanguage[userLanguage]
if (!i18nLanguage) {
return
}
// 获取当前 i18n 语言
const currentLocale = i18n.global.locale.value
// 如果用户语言和本地 i18n 不一致,更新 i18n
if (i18nLanguage !== currentLocale) {
i18n.global.locale.value = i18nLanguage as 'ENGLISH' | 'CHINESE_SIMPLIFIED'
localStorage.setItem('language', i18nLanguage)
}
// 标记已同步
languageSynced = true
} catch (error) {