feat(i18n): fix the problem of using the default language after language acquisition fails

This commit is contained in:
qianmoQ 2024-11-23 22:31:55 +08:00
parent 5583aae80c
commit 97f1ee0bd8
5 changed files with 124 additions and 34 deletions

View File

@ -127,18 +127,5 @@
<artifactId>datacap-executor-spi</artifactId>
<version>${project.version}</version>
</dependency>
<!-- Sql Parser -->
<dependency>
<groupId>io.edurt.datacap</groupId>
<artifactId>datacap-parser-trino</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.edurt.datacap</groupId>
<artifactId>datacap-parser-mysql</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -15,6 +15,7 @@ public interface Adapter
default List<Object> handlerFormatter(PluginManager pluginManager, String format, List<String> headers, List<Object> columns)
{
return ConvertFilter.filter(pluginManager, format)
.map(file -> {
ConvertRequest request = new ConvertRequest();

View File

@ -2,59 +2,123 @@ import { createI18n } from 'vue-i18n'
import { inject, provide, ref } from 'vue'
import I18nService from '@/services/i18n'
// 默认语言配置
// Default locale
const DEFAULT_LOCALE = 'zh_cn'
const DEFAULT_MESSAGES = {
zh_cn: {
// 基础的回退翻译
// Basic fallback translation
common: {
loading: 'Loading...',
networkError: 'Network error',
loadingFailed: 'Loading failed'
}
}
}
const language = (navigator.language || 'en').toLocaleLowerCase()
const i18n = createI18n({
fallbackLocale: 'zh_cn',
fallbackLocale: DEFAULT_LOCALE,
globalInjection: true,
legacy: false,
silentFallbackWarn: true,
fallbackWarn: false,
silentTranslationWarn: true,
missingWarn: false,
locale: localStorage.getItem('locale') || language.split('-')[0] || 'zh_cn',
messages: {}
locale: localStorage.getItem('locale') || language.split('-')[0] || DEFAULT_LOCALE,
messages: DEFAULT_MESSAGES
})
export const I18N_KEY = Symbol('i18n-handler')
export const loadingState = ref(false)
export const loadingText = ref('')
export const errorState = ref(false)
export const errorMessage = ref('')
export function provideI18nHandler()
{
const resetState = () => {
loadingState.value = false
loadingText.value = ''
errorState.value = false
errorMessage.value = ''
}
const loadLocale = async (locale: string) => {
// 如果请求的语言包已经加载过,直接使用
// If the requested language package has been loaded, use it directly
// @ts-ignore
if (i18n.global.availableLocales.includes(locale) &&
Object.keys(i18n.global.getLocaleMessage(locale)).length > 1) {
// @ts-ignore
i18n.global.locale.value = locale
localStorage.setItem('locale', locale)
return true
}
resetState()
loadingState.value = true
loadingText.value = 'Loading language...'
loadingText.value = i18n.global.t('common.loading')
try {
const response = await I18nService.getLocale(locale)
if (response.status) {
i18n.global.setLocaleMessage(locale, response.data)
if (response.status && response.data && Object.keys(response.data).length > 0) {
i18n.global.setLocaleMessage(locale, {
...DEFAULT_MESSAGES[DEFAULT_LOCALE],
...response.data
})
// @ts-ignore
i18n.global.locale.value = locale
localStorage.setItem('locale', locale)
resetState()
return true
}
else {
throw new Error('Invalid locale data received')
}
}
catch (error) {
errorState.value = true
errorMessage.value = error instanceof Error ? error.message : i18n.global.t('common.loadingFailed')
// 如果加载失败,确保至少有基础翻译可用
// Ensure that at least the basic translation is available
// @ts-ignore
if (!i18n.global.availableLocales.includes(locale)) {
i18n.global.setLocaleMessage(locale, DEFAULT_MESSAGES[DEFAULT_LOCALE])
}
// 如果当前语言加载失败,尝试回退到默认语言
// If the current language fails to load, try to fall back to the default language
if (locale !== DEFAULT_LOCALE &&
!i18n.global.availableLocales.includes(i18n.global.locale.value)) {
i18n.global.locale.value = DEFAULT_LOCALE
localStorage.setItem('locale', DEFAULT_LOCALE)
}
console.error('Failed to load locale:', error)
return false
}
finally {
loadingState.value = false
}
return false
}
provide(I18N_KEY, {
const i18nHandler = {
loadLocale,
loadingState,
loadingText
})
return {
loadLocale,
loadingState,
loadingText
loadingText,
errorState,
errorMessage,
resetState
}
provide(I18N_KEY, i18nHandler)
return i18nHandler
}
// Hook

View File

@ -66,9 +66,27 @@ export class HttpUtils
message: error.message,
status: false
}
if (error.code === 'ERR_NETWORK') {
router.push('/common/not_network?redirect=' + router.currentRoute.value.fullPath)
// 检查当前路由,避免重复重定向
// Current route path, avoid repeated redirection
const currentPath = router.currentRoute.value.path
const isAlreadyOnErrorPage = currentPath.startsWith('/common/not_network')
if (error.code === 'ERR_NETWORK' && !isAlreadyOnErrorPage) {
// 记录用户原始请求的页面路径
// Record the original page path of the user
const originalPath = router.currentRoute.value.fullPath
router.push({
path: '/common/not_network',
query: {
redirect: originalPath
},
// 替换当前的历史记录,这样用户点击后退时不会陷入循环
// Replace the current history record, so that the user can not enter a loop
replace: true
})
}
return response
}

View File

@ -1,12 +1,22 @@
<template>
<div class="relative">
<div class="relative min-h-screen">
<!-- Loading State -->
<div class="relative" v-if="loadingState" style="height: 100vh;">
<ShadcnSpin v-model="loadingState" fixed>
{{ loadingText }}
</ShadcnSpin>
</div>
<div v-show="!loadingState">
<!-- Error State -->
<div v-if="errorState && !loadingState" class="fixed inset-0 flex items-center justify-center bg-background/80 backdrop-blur-sm">
<div class="flex flex-col items-center space-y-4">
<ShadcnText type="h3">{{ errorMessage }}</ShadcnText>
<ShadcnButton @click="handleRetry">Retry 重试</ShadcnButton>
</div>
</div>
<!-- Content -->
<div v-show="!loadingState && !errorState">
<slot/>
</div>
</div>
@ -16,9 +26,15 @@
import { onBeforeMount } from 'vue'
import { provideI18nHandler } from '@/i18n/I18n'
const { loadLocale, loadingState, loadingText } = provideI18nHandler()
const {
loadLocale,
loadingState,
loadingText,
errorState,
errorMessage
} = provideI18nHandler()
onBeforeMount(async () => {
const handleRetry = async () => {
try {
const locale = localStorage.getItem('locale') || 'zh_cn'
await loadLocale(locale)
@ -26,5 +42,9 @@ onBeforeMount(async () => {
catch (error) {
console.error('Failed to load locale:', error)
}
}
onBeforeMount(async () => {
await handleRetry()
})
</script>