feat(i18n): 实现国际化支持并优化 WebSocket 连接
- 移除 App.vue 中的固定语言设置 - 在 i18n.ts 中实现系统语言自动检测和手动设置支持 - 添加语言切换时重新连接 WebSocket 的逻辑 - 在 profile 页面添加语言设置入口 - 优化 WebSocket连接过程,添加 accept-language头
This commit is contained in:
parent
c524bf34f5
commit
462a2b23a9
@ -17,7 +17,6 @@ const router = useRouter()
|
|||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const slideDirection = ref('slide-left')
|
const slideDirection = ref('slide-left')
|
||||||
const { locale } = useI18n()
|
const { locale } = useI18n()
|
||||||
// locale.value = 'en-US'
|
|
||||||
// 记录路由历史
|
// 记录路由历史
|
||||||
const routeHistory = ref([])
|
const routeHistory = ref([])
|
||||||
|
|
||||||
|
@ -78,6 +78,13 @@ fetchData()
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 设置选项 -->
|
||||||
|
<div class="px-16px mb-20px">
|
||||||
|
<van-cell-group inset>
|
||||||
|
<van-cell :title="$t('settings.language')" is-link @click="router.push('/profile/language')" />
|
||||||
|
</van-cell-group>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- 列表内容 -->
|
<!-- 列表内容 -->
|
||||||
<div class="grow-1 flex flex-col">
|
<div class="grow-1 flex flex-col">
|
||||||
<div class="border-b-1px border-b-#D3D3D3 px-16px">
|
<div class="border-b-1px border-b-#D3D3D3 px-16px">
|
||||||
|
@ -15,22 +15,59 @@ export default defineNuxtPlugin(() => {
|
|||||||
if (import.meta.client) {
|
if (import.meta.client) {
|
||||||
const i18n = useNuxtApp().$i18n
|
const i18n = useNuxtApp().$i18n
|
||||||
const { setLocale } = i18n
|
const { setLocale } = i18n
|
||||||
|
const nuxtApp = useNuxtApp()
|
||||||
|
|
||||||
// 暂时设置固定语言,用于调试
|
// 获取系统语言
|
||||||
// 可以根据需要修改这里的语言代码:'zh-CN' | 'en-US' | 'ja-JP' | 'zh-TW'
|
const getSystemLanguage = () => {
|
||||||
/* const fixedLang = 'zh-CN'
|
const browserLang = navigator.language
|
||||||
setLocale(fixedLang)
|
|
||||||
Locale.use(fixedLang)*/
|
// 将浏览器语言映射到应用支持的语言
|
||||||
|
if (browserLang.startsWith('zh')) {
|
||||||
|
return browserLang.includes('TW') || browserLang.includes('HK') ? 'zh-TW' : 'zh-CN'
|
||||||
|
} else if (browserLang.startsWith('ja')) {
|
||||||
|
return 'ja-JP'
|
||||||
|
} else if (browserLang.startsWith('en')) {
|
||||||
|
return 'en-US'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 默认返回中文
|
||||||
|
return 'zh-CN'
|
||||||
|
}
|
||||||
|
|
||||||
// 原自动检测系统语言的逻辑(暂时注释)
|
// 获取用户手动设置的语言或系统语言
|
||||||
const lang = localStorage.getItem('lang')
|
const lang = localStorage.getItem('lang')
|
||||||
if (lang) {
|
if (lang) {
|
||||||
|
// 用户手动设置了语言,优先使用
|
||||||
setLocale(lang as TypeLocale)
|
setLocale(lang as TypeLocale)
|
||||||
Locale.use(lang)
|
Locale.use(lang)
|
||||||
|
} else {
|
||||||
|
// 用户未手动设置语言,使用系统语言
|
||||||
|
const systemLang = getSystemLanguage()
|
||||||
|
setLocale(systemLang as TypeLocale)
|
||||||
|
Locale.use(systemLang)
|
||||||
|
|
||||||
|
// 将系统语言保存到 localStorage,以便下次使用
|
||||||
|
localStorage.setItem('lang', systemLang)
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
setLocale(i18n.locale.value)
|
// 监听系统语言变化(当用户未手动设置语言时)
|
||||||
Locale.use(i18n.locale.value)
|
window.addEventListener('languagechange', () => {
|
||||||
}
|
// 只有当用户未手动设置语言时,才跟随系统语言变化
|
||||||
|
if (!localStorage.getItem('lang')) {
|
||||||
|
const systemLang = getSystemLanguage()
|
||||||
|
setLocale(systemLang as TypeLocale)
|
||||||
|
Locale.use(systemLang)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 监听语言变化,当语言变化时,如果有活跃的 WebSocket 连接,则重新连接
|
||||||
|
watch(() => i18n.locale.value, (newLocale) => {
|
||||||
|
// 如果 WebSocket 插件已加载并且有活跃连接
|
||||||
|
if (nuxtApp.$ws) {
|
||||||
|
// 使用 refreshConnection 方法刷新 WebSocket 连接
|
||||||
|
console.log('语言已更改为:', newLocale, '正在更新 WebSocket 连接')
|
||||||
|
nuxtApp.$ws.refreshConnection()
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -3,22 +3,39 @@ import {authStore} from "@/stores/auth";
|
|||||||
export default defineNuxtPlugin(() => {
|
export default defineNuxtPlugin(() => {
|
||||||
const config = useRuntimeConfig()
|
const config = useRuntimeConfig()
|
||||||
const { token } = authStore()
|
const { token } = authStore()
|
||||||
|
const i18n = useNuxtApp().$i18n
|
||||||
|
|
||||||
const ws = reactive({
|
const ws = reactive({
|
||||||
instance: null as WebSocket | null,
|
instance: null as WebSocket | null,
|
||||||
isConnected: false,
|
isConnected: false,
|
||||||
|
currentPath: '', // 保存当前连接的路径
|
||||||
|
currentData: null as Record<string, any> | null, // 保存当前连接的数据
|
||||||
|
|
||||||
// 修改 connect 方法接收路径和数据对象
|
// 修改 connect 方法接收路径和数据对象
|
||||||
connect(path: string, data?: Record<string, any>) {
|
connect(path: string, data?: Record<string, any>) {
|
||||||
|
// 保存当前连接的路径和数据,以便后续重连使用
|
||||||
|
this.currentPath = path
|
||||||
|
this.currentData = data || null
|
||||||
|
|
||||||
if (this.instance?.readyState === WebSocket.OPEN) {
|
if (this.instance?.readyState === WebSocket.OPEN) {
|
||||||
this.instance.close()
|
this.instance.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 构建查询字符串
|
// 构建查询字符串
|
||||||
const queryString =data
|
const queryString =data
|
||||||
? '?' + Object.entries({ token: token.value,...data})
|
? '?' + Object.entries({
|
||||||
|
token: token.value,
|
||||||
|
'accept-language': i18n.locale.value, // 添加当前语言作为 accept-language
|
||||||
|
...data
|
||||||
|
})
|
||||||
|
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
|
||||||
|
.join('&')
|
||||||
|
: '?' + Object.entries({
|
||||||
|
token: token.value,
|
||||||
|
'accept-language': i18n.locale.value // 即使没有其他数据,也添加语言
|
||||||
|
})
|
||||||
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
|
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
|
||||||
.join('&')
|
.join('&')
|
||||||
: ''
|
|
||||||
|
|
||||||
// 构建完整的 WebSocket URL
|
// 构建完整的 WebSocket URL
|
||||||
const wsUrl = `${config.public.NUXT_PUBLIC_SOCKET_URL}${path}${queryString}`
|
const wsUrl = `${config.public.NUXT_PUBLIC_SOCKET_URL}${path}${queryString}`
|
||||||
@ -50,13 +67,24 @@ export default defineNuxtPlugin(() => {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// 更新重连方法以支持数据对象
|
// 更新重连方法以支持数据对象
|
||||||
reconnect(path: string, data?: Record<string, any>) {
|
reconnect(path?: string, data?: Record<string, any>) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
console.log('尝试重新连接...')
|
console.log('尝试重新连接...')
|
||||||
this.connect(path, data)
|
// 如果提供了新的路径和数据,则使用新的;否则使用保存的当前路径和数据
|
||||||
|
this.connect(path || this.currentPath, data || this.currentData || undefined)
|
||||||
}, 3000)
|
}, 3000)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 使用当前保存的路径和数据重新连接
|
||||||
|
refreshConnection() {
|
||||||
|
if (this.currentPath) {
|
||||||
|
console.log('刷新 WebSocket 连接,使用当前语言:', i18n.locale.value)
|
||||||
|
this.connect(this.currentPath, this.currentData || undefined)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false // 如果没有当前连接信息,返回 false
|
||||||
|
},
|
||||||
|
|
||||||
// 发送消息
|
// 发送消息
|
||||||
send(data: any) {
|
send(data: any) {
|
||||||
if (this.instance?.readyState === WebSocket.OPEN) {
|
if (this.instance?.readyState === WebSocket.OPEN) {
|
||||||
|
Loading…
Reference in New Issue
Block a user