2026-04-20 11:21:21 +08:00
|
|
|
|
import { createRouter, createWebHistory } from 'vue-router'
|
2026-05-28 13:45:59 +08:00
|
|
|
|
import { useUserInfoStore } from '@/stores/userInfo'
|
|
|
|
|
|
import { getUserLanguage } from '@/api/user'
|
|
|
|
|
|
import i18n from '@/lang/index'
|
|
|
|
|
|
|
|
|
|
|
|
// 语言映射:后端格式 -> i18n 格式
|
|
|
|
|
|
const backendToI18nLanguage: Record<string, string> = {
|
|
|
|
|
|
'en': 'ENGLISH',
|
|
|
|
|
|
'zh-CN': 'CHINESE_SIMPLIFIED'
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 语言同步状态缓存(避免每次路由切换都请求)
|
|
|
|
|
|
let languageSynced = false
|
2026-04-20 11:21:21 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 路由缓存机制:
|
|
|
|
|
|
* 1. 设置路由的meta属性为{ cache: true },表示需要缓存
|
|
|
|
|
|
* 2. App.vue中使用RouteCache组件,通过路由的name来进行匹配
|
|
|
|
|
|
* 3. 路由的name默认是文件名,如果文件名与name不一致,通过defineOptions({ name: 'componentName' })来设置
|
|
|
|
|
|
*/
|
|
|
|
|
|
const router = createRouter({
|
2026-04-22 10:30:55 +08:00
|
|
|
|
routes: [
|
|
|
|
|
|
{
|
|
|
|
|
|
path: '/',
|
|
|
|
|
|
name: 'home',
|
|
|
|
|
|
component: () => import('../views/home/index.vue')
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
path: '/collectionStory',
|
|
|
|
|
|
name: 'collectionStory',
|
|
|
|
|
|
component: () => import('../views/collectionStory/index.vue')
|
2026-04-22 10:43:40 +08:00
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
path: '/brand',
|
|
|
|
|
|
name: 'brand',
|
|
|
|
|
|
component: () => import('../views/brand/index.vue')
|
2026-04-22 10:30:55 +08:00
|
|
|
|
},
|
2026-05-11 16:16:59 +08:00
|
|
|
|
{
|
|
|
|
|
|
path: '/brand/:id',
|
|
|
|
|
|
name: 'brandDetail',
|
|
|
|
|
|
component: () => import('../views/brandDetail/index.vue')
|
|
|
|
|
|
},
|
2026-05-04 15:53:13 +08:00
|
|
|
|
{
|
|
|
|
|
|
path: '/digitalItem',
|
|
|
|
|
|
name: 'digitalItem',
|
|
|
|
|
|
component: () => import('../views/digitalItem/index.vue'),
|
|
|
|
|
|
meta: { cache: true }
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
path: '/digitalItem/:id',
|
|
|
|
|
|
name: 'digitalItemDetail',
|
|
|
|
|
|
component: () => import('../views/digitalDetail/index.vue')
|
|
|
|
|
|
},
|
2026-04-22 10:30:55 +08:00
|
|
|
|
{
|
|
|
|
|
|
path: '/settings',
|
|
|
|
|
|
name: 'settings',
|
|
|
|
|
|
component: () => import('@/views/setting/index.vue'),
|
|
|
|
|
|
meta: { cache: true }
|
|
|
|
|
|
},
|
2026-04-23 11:48:22 +08:00
|
|
|
|
{
|
2026-05-04 15:53:13 +08:00
|
|
|
|
path: '/shoppingCart', // 购物车
|
2026-04-23 11:48:22 +08:00
|
|
|
|
name: 'shoppingCart',
|
|
|
|
|
|
component: () => import('@/views/shoppingCart/index.vue')
|
|
|
|
|
|
},
|
2026-04-23 09:39:12 +08:00
|
|
|
|
{
|
|
|
|
|
|
path: '/notifications',
|
|
|
|
|
|
name: 'notifications',
|
|
|
|
|
|
component: () => import('@/views/notifications/index.vue')
|
|
|
|
|
|
},
|
2026-04-23 15:20:22 +08:00
|
|
|
|
{
|
|
|
|
|
|
path: '/wardrobe',
|
|
|
|
|
|
name: 'wardrobe',
|
|
|
|
|
|
component: () => import('@/views/wardrobe/index.vue')
|
|
|
|
|
|
},
|
2026-05-04 15:53:13 +08:00
|
|
|
|
{
|
|
|
|
|
|
path:'/account',
|
|
|
|
|
|
name:'account',
|
|
|
|
|
|
component:()=>import('@/views/account/index.vue')
|
|
|
|
|
|
},
|
2026-05-28 11:31:37 +08:00
|
|
|
|
{
|
|
|
|
|
|
path:'/pay',
|
|
|
|
|
|
name:'pay',
|
|
|
|
|
|
component:()=>import('@/views/pay/index.vue')
|
|
|
|
|
|
},
|
2026-04-22 10:30:55 +08:00
|
|
|
|
{
|
|
|
|
|
|
path: '/:pathMatch(.*)',
|
|
|
|
|
|
name: '404',
|
|
|
|
|
|
component: () => import('../views/404.vue')
|
|
|
|
|
|
}
|
2026-04-22 10:43:40 +08:00
|
|
|
|
],
|
|
|
|
|
|
history: createWebHistory('/')
|
2026-04-20 11:21:21 +08:00
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
router.beforeEach((to, from, next) => {
|
2026-04-22 10:30:55 +08:00
|
|
|
|
next()
|
2026-04-20 11:21:21 +08:00
|
|
|
|
})
|
|
|
|
|
|
|
2026-05-28 13:45:59 +08:00
|
|
|
|
router.afterEach(async () => {
|
|
|
|
|
|
// 检查用户是否已登录
|
|
|
|
|
|
const userInfoStore = useUserInfoStore()
|
|
|
|
|
|
const token = userInfoStore.state.token
|
|
|
|
|
|
|
|
|
|
|
|
if (!token) {
|
|
|
|
|
|
languageSynced = false // 未登录时重置同步状态
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 如果已经同步过,跳过
|
|
|
|
|
|
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) {
|
|
|
|
|
|
// 静默失败,不影响页面正常加载
|
|
|
|
|
|
console.warn('Failed to sync user language:', error)
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
2026-04-20 11:21:21 +08:00
|
|
|
|
|
|
|
|
|
|
export default router
|