mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-22 07:03:53 +08:00
fix: 修复语言切换接口请求异常的问题
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import type { uniappRequestAdapter } from '@alova/adapter-uniapp'
|
||||
import type { IResponse } from './types'
|
||||
import type { Language } from '@/store/lang'
|
||||
import AdapterUniapp from '@alova/adapter-uniapp'
|
||||
import { createAlova } from 'alova'
|
||||
import { createServerTokenAuthentication } from 'alova/client'
|
||||
@@ -8,6 +9,16 @@ import { getEnvBaseUrl } from '@/utils'
|
||||
import { toast } from '@/utils/toast'
|
||||
import { ContentTypeEnum, ResultEnum, ShowMessage } from './enum'
|
||||
|
||||
// 语言映射, 用于设置 Accept-language 头
|
||||
const langMap: Record<Language, string> = {
|
||||
zh_CN: 'zh-CN',
|
||||
en: 'en',
|
||||
zh_TW: 'zh-TW',
|
||||
de: 'de',
|
||||
vi: 'vi',
|
||||
pt_BR: 'pt-BR',
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建请求实例
|
||||
*/
|
||||
@@ -51,6 +62,7 @@ const alovaInstance = createAlova({
|
||||
// 检查混合内容错误(HTTPS页面请求HTTP接口)
|
||||
const currentProtocol = typeof window !== 'undefined' && window.location.protocol
|
||||
const requestProtocol = method.baseURL?.split(':')[0]
|
||||
const currentLang = langMap[uni.getStorageSync('app_language') as Language || 'zh_CN']
|
||||
if (currentProtocol === 'https:' && requestProtocol === 'http') {
|
||||
const errorMessage = '无法配置http协议地址,请检查接口地址'
|
||||
throw new Error(errorMessage)
|
||||
@@ -60,6 +72,7 @@ const alovaInstance = createAlova({
|
||||
method.config.headers = {
|
||||
'Content-Type': ContentTypeEnum.JSON,
|
||||
'Accept': 'application/json, text/plain, */*',
|
||||
'Accept-language': currentLang,
|
||||
...method.config.headers,
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ export default {
|
||||
'login.navigationTitle': 'Anmelden',
|
||||
'login.fetchConfigError': 'Konfiguration konnte nicht abgerufen werden:',
|
||||
'login.selectLanguage': 'Sprache auswählen',
|
||||
'login.selectLanguageTip': 'Vi',
|
||||
'login.selectLanguageTip': 'De',
|
||||
'login.welcomeBack': 'Willkommen zurück',
|
||||
'login.pleaseLogin': 'Bitte melden Sie sich an',
|
||||
'login.enterUsername': 'Bitte Benutzernamen eingeben',
|
||||
|
||||
@@ -11,7 +11,7 @@ export default {
|
||||
'login.navigationTitle': 'Login',
|
||||
'login.fetchConfigError': 'Failed to fetch configuration:',
|
||||
'login.selectLanguage': 'Select Language',
|
||||
'login.selectLanguageTip': '中文',
|
||||
'login.selectLanguageTip': 'En',
|
||||
'login.welcomeBack': 'Welcome Back',
|
||||
'login.pleaseLogin': 'Please log in to your account',
|
||||
'login.enterUsername': 'Please enter username',
|
||||
|
||||
@@ -11,7 +11,7 @@ export default {
|
||||
'login.navigationTitle': 'Entrar',
|
||||
'login.fetchConfigError': 'Falha ao buscar configuração:',
|
||||
'login.selectLanguage': 'Selecionar Idioma',
|
||||
'login.selectLanguageTip': '中文',
|
||||
'login.selectLanguageTip': 'Pt',
|
||||
'login.welcomeBack': 'Bem-vindo de Volta',
|
||||
'login.pleaseLogin': 'Por favor, entre na sua conta',
|
||||
'login.enterUsername': 'Por favor, insira o nome de usuário',
|
||||
|
||||
@@ -11,7 +11,7 @@ export default {
|
||||
'login.navigationTitle': 'Đăng nhập',
|
||||
'login.fetchConfigError': 'Không thể tải cấu hình:',
|
||||
'login.selectLanguage': 'Chọn ngôn ngữ',
|
||||
'login.selectLanguageTip': 'de',
|
||||
'login.selectLanguageTip': 'Vi',
|
||||
'login.welcomeBack': 'Chào mừng trở lại',
|
||||
'login.pleaseLogin': 'Vui lòng đăng nhập vào tài khoản của bạn',
|
||||
'login.enterUsername': 'Vui lòng nhập tên đăng nhập',
|
||||
|
||||
@@ -11,7 +11,7 @@ export default {
|
||||
'login.navigationTitle': '登录',
|
||||
'login.fetchConfigError': '获取配置失败:',
|
||||
'login.selectLanguage': '选择语言',
|
||||
'login.selectLanguageTip': 'En',
|
||||
'login.selectLanguageTip': '中文',
|
||||
'login.welcomeBack': '欢迎回来',
|
||||
'login.pleaseLogin': '请登录您的账户',
|
||||
'login.enterUsername': '请输入用户名',
|
||||
|
||||
@@ -11,7 +11,7 @@ export default {
|
||||
'login.navigationTitle': '登錄',
|
||||
'login.fetchConfigError': '獲取配置失敗:',
|
||||
'login.selectLanguage': '選擇語言',
|
||||
'login.selectLanguageTip': '简体',
|
||||
'login.selectLanguageTip': '繁體',
|
||||
'login.welcomeBack': '歡迎回來',
|
||||
'login.pleaseLogin': '請登錄您的賬戶',
|
||||
'login.enterUsername': '請輸入用戶名',
|
||||
|
||||
@@ -127,10 +127,10 @@ async function saveServerBaseUrl() {
|
||||
uni.request({
|
||||
url: `${getEnvBaseUrl()}/user/pub-config`,
|
||||
method: 'GET',
|
||||
success: (res) => {
|
||||
success: (res: any) => {
|
||||
if (res.statusCode === 200) {
|
||||
configStore.setConfig(res.data.data)
|
||||
uni.setStorageSync('config', res.data.data.sm2PubKey)
|
||||
uni.setStorageSync('config', res.data.data)
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
@@ -165,6 +165,7 @@ const showLanguageSheet = ref(false)
|
||||
function handleLanguageChange(lang: Language) {
|
||||
changeLanguage(lang)
|
||||
showLanguageSheet.value = false
|
||||
currentLanguage.value = lang
|
||||
toast.success(t('settings.languageChanged'))
|
||||
}
|
||||
|
||||
@@ -225,7 +226,8 @@ function clearAllCacheAfterUrlChange() {
|
||||
|
||||
// 重新获取缓存信息
|
||||
getCacheInfo()
|
||||
} catch (error) {
|
||||
}
|
||||
catch (error) {
|
||||
console.error('清除缓存失败:', error)
|
||||
}
|
||||
}
|
||||
@@ -250,7 +252,8 @@ async function clearCache() {
|
||||
}
|
||||
},
|
||||
})
|
||||
} catch (error) {
|
||||
}
|
||||
catch (error) {
|
||||
console.error('清除缓存失败:', error)
|
||||
toast.error(t('settings.clearCacheFailed'))
|
||||
}
|
||||
@@ -262,7 +265,7 @@ function showAbout() {
|
||||
title: t('settings.aboutApp', { appName: import.meta.env.VITE_APP_TITLE }),
|
||||
content: t('settings.aboutContent', {
|
||||
appName: import.meta.env.VITE_APP_TITLE,
|
||||
version: '0.9.1'
|
||||
version: '0.9.1',
|
||||
}),
|
||||
showCancel: false,
|
||||
confirmText: t('common.confirm'),
|
||||
@@ -278,7 +281,7 @@ onMounted(async () => {
|
||||
|
||||
// 动态设置导航栏标题为国际化文本
|
||||
uni.setNavigationBarTitle({
|
||||
title: t('settings.title')
|
||||
title: t('settings.title'),
|
||||
})
|
||||
})
|
||||
</script>
|
||||
@@ -296,8 +299,10 @@ onMounted(async () => {
|
||||
</text>
|
||||
</view>
|
||||
|
||||
<view class="border border-[#eeeeee] rounded-[24rpx] bg-[#fbfbfb] p-[32rpx] overflow-hidden"
|
||||
style="box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.06);">
|
||||
<view
|
||||
class="overflow-hidden border border-[#eeeeee] rounded-[24rpx] bg-[#fbfbfb] p-[32rpx]"
|
||||
style="box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.06);"
|
||||
>
|
||||
<view class="mb-[24rpx]">
|
||||
<text class="text-[28rpx] text-[#232338] font-semibold">
|
||||
{{ t('settings.serverApiUrl') }}
|
||||
@@ -308,11 +313,13 @@ onMounted(async () => {
|
||||
</view>
|
||||
|
||||
<view class="mb-[24rpx]">
|
||||
<view class="w-full rounded-[16rpx] border border-[#eeeeee] bg-[#f5f7fb] overflow-hidden">
|
||||
<wd-input v-model="baseUrlInput" type="text" clearable :maxlength="200"
|
||||
<view class="w-full overflow-hidden border border-[#eeeeee] rounded-[16rpx] bg-[#f5f7fb]">
|
||||
<wd-input
|
||||
v-model="baseUrlInput" type="text" clearable :maxlength="200"
|
||||
:placeholder="t('settings.enterServerUrl')"
|
||||
custom-class="!border-none !bg-transparent h-[64rpx] px-[24rpx] items-center"
|
||||
input-class="text-[28rpx] text-[#232338]" @input="validateUrl" @blur="validateUrl" />
|
||||
input-class="text-[28rpx] text-[#232338]" @input="validateUrl" @blur="validateUrl"
|
||||
/>
|
||||
</view>
|
||||
<text v-if="urlError" class="mt-[8rpx] block text-[24rpx] text-[#ff4d4f]">
|
||||
{{ urlError }}
|
||||
@@ -320,14 +327,18 @@ onMounted(async () => {
|
||||
</view>
|
||||
|
||||
<view class="flex gap-[16rpx]">
|
||||
<wd-button type="primary"
|
||||
<wd-button
|
||||
type="primary"
|
||||
custom-class="flex-1 h-[88rpx] rounded-[20rpx] text-[28rpx] font-semibold bg-[#336cff] border-none shadow-[0_4rpx_16rpx_rgba(51,108,255,0.3)] active:shadow-[0_2rpx_8rpx_rgba(51,108,255,0.4)] active:scale-98"
|
||||
@click="saveServerBaseUrl">
|
||||
@click="saveServerBaseUrl"
|
||||
>
|
||||
{{ t('settings.saveSettings') }}
|
||||
</wd-button>
|
||||
<wd-button type="default"
|
||||
<wd-button
|
||||
type="default"
|
||||
custom-class="flex-1 h-[88rpx] rounded-[20rpx] text-[28rpx] font-semibold bg-white border-[#eeeeee] text-[#65686f] active:bg-[#f5f7fb]"
|
||||
@click="resetServerBaseUrl">
|
||||
@click="resetServerBaseUrl"
|
||||
>
|
||||
{{ t('settings.resetDefault') }}
|
||||
</wd-button>
|
||||
</view>
|
||||
@@ -342,12 +353,15 @@ onMounted(async () => {
|
||||
</text>
|
||||
</view>
|
||||
|
||||
<view class="border border-[#eeeeee] rounded-[24rpx] bg-[#fbfbfb] p-[32rpx]"
|
||||
style="box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.06);">
|
||||
<view
|
||||
class="border border-[#eeeeee] rounded-[24rpx] bg-[#fbfbfb] p-[32rpx]"
|
||||
style="box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.06);"
|
||||
>
|
||||
<view class="space-y-[16rpx]">
|
||||
<!-- 缓存信息展示,参考插件样式 -->
|
||||
<view
|
||||
class="flex items-center justify-between border border-[#eeeeee] rounded-[16rpx] bg-[#f5f7fb] p-[24rpx] transition-all active:bg-[#eef3ff]">
|
||||
class="flex items-center justify-between border border-[#eeeeee] rounded-[16rpx] bg-[#f5f7fb] p-[24rpx] transition-all active:bg-[#eef3ff]"
|
||||
>
|
||||
<view>
|
||||
<text class="text-[28rpx] text-[#232338] font-medium">
|
||||
{{ t('settings.totalCacheSize') }}
|
||||
@@ -363,7 +377,8 @@ onMounted(async () => {
|
||||
|
||||
<!-- 清除缓存按钮,参考插件编辑按钮样式 -->
|
||||
<view
|
||||
class="flex items-center justify-between border border-[#eeeeee] rounded-[16rpx] bg-[#f5f7fb] p-[24rpx]">
|
||||
class="flex items-center justify-between border border-[#eeeeee] rounded-[16rpx] bg-[#f5f7fb] p-[24rpx]"
|
||||
>
|
||||
<view>
|
||||
<text class="text-[28rpx] text-[#232338] font-medium">
|
||||
{{ t('settings.cacheClear') }}
|
||||
@@ -374,7 +389,8 @@ onMounted(async () => {
|
||||
</view>
|
||||
<view
|
||||
class="cursor-pointer rounded-[24rpx] bg-[rgba(255,107,107,0.1)] px-[28rpx] py-[16rpx] text-[24rpx] text-[#ff6b6b] font-semibold transition-all duration-300 active:scale-95 active:bg-[#ff6b6b] active:text-white"
|
||||
@click="clearCache">
|
||||
@click="clearCache"
|
||||
>
|
||||
{{ t('settings.clearCache') }}
|
||||
</view>
|
||||
</view>
|
||||
@@ -390,11 +406,14 @@ onMounted(async () => {
|
||||
</text>
|
||||
</view>
|
||||
|
||||
<view class="border border-[#eeeeee] rounded-[24rpx] bg-[#fbfbfb] p-[32rpx]"
|
||||
style="box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.06);">
|
||||
<view
|
||||
class="border border-[#eeeeee] rounded-[24rpx] bg-[#fbfbfb] p-[32rpx]"
|
||||
style="box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.06);"
|
||||
>
|
||||
<view
|
||||
class="flex cursor-pointer items-center justify-between border border-[#eeeeee] rounded-[16rpx] bg-[#f5f7fb] p-[24rpx] transition-all active:bg-[#eef3ff]"
|
||||
@click="showAbout">
|
||||
@click="showAbout"
|
||||
>
|
||||
<view>
|
||||
<text class="text-[28rpx] text-[#232338] font-medium">
|
||||
{{ t('settings.aboutUs') }}
|
||||
@@ -416,11 +435,14 @@ onMounted(async () => {
|
||||
</text>
|
||||
</view>
|
||||
|
||||
<view class="border border-[#eeeeee] rounded-[24rpx] bg-[#fbfbfb] p-[32rpx]"
|
||||
style="box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.06);">
|
||||
<view
|
||||
class="border border-[#eeeeee] rounded-[24rpx] bg-[#fbfbfb] p-[32rpx]"
|
||||
style="box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.06);"
|
||||
>
|
||||
<view
|
||||
class="flex cursor-pointer items-center justify-between border border-[#eeeeee] rounded-[16rpx] bg-[#f5f7fb] p-[24rpx] transition-all active:bg-[#eef3ff]"
|
||||
@click="showLanguageSheet = true">
|
||||
@click="showLanguageSheet = true"
|
||||
>
|
||||
<view>
|
||||
<text class="text-[32rpx] text-[#232338] font-medium">
|
||||
{{ t('settings.language') }}
|
||||
@@ -430,8 +452,8 @@ onMounted(async () => {
|
||||
</text>
|
||||
</view>
|
||||
<view class="flex items-center">
|
||||
<text class="text-[32rpx] text-[#9d9ea3] font-semibold mr-[16rpx]">
|
||||
{{supportedLanguages.find(lang => lang.code === currentLanguage)?.name}}
|
||||
<text class="mr-[16rpx] text-[32rpx] text-[#9d9ea3] font-semibold">
|
||||
{{ supportedLanguages.find(lang => lang.code === currentLanguage)?.name }}
|
||||
</text>
|
||||
<wd-icon name="arrow-right" custom-class="text-[32rpx] text-[#9d9ea3]" />
|
||||
</view>
|
||||
@@ -443,8 +465,10 @@ onMounted(async () => {
|
||||
<wd-action-sheet v-model="showLanguageSheet" :title="t('settings.selectLanguage')" :close-on-click-modal="true">
|
||||
<view class="language-sheet">
|
||||
<scroll-view scroll-y class="language-list">
|
||||
<view v-for="lang in supportedLanguages" :key="lang.code" class="language-item"
|
||||
@click="handleLanguageChange(lang.code)">
|
||||
<view
|
||||
v-for="lang in supportedLanguages" :key="lang.code" class="language-item"
|
||||
@click="handleLanguageChange(lang.code)"
|
||||
>
|
||||
<text class="language-name">
|
||||
{{ lang.name }}
|
||||
</text>
|
||||
|
||||
@@ -670,10 +670,10 @@ export default {
|
||||
'home.wish': 'Vamos ter um dia maravilhoso!',
|
||||
'home.languageModel': 'LLM',
|
||||
'home.voiceModel': 'TTS',
|
||||
'home.configureRole': 'Configurar Papel',
|
||||
'home.voiceprintRecognition': 'Impressão Vocal',
|
||||
'home.configureRole': 'ConfRoles',
|
||||
'home.voiceprintRecognition': 'RecVoz',
|
||||
'home.deviceManagement': 'Dispositivos',
|
||||
'home.chatHistory': 'Histórico de Chat',
|
||||
'home.chatHistory': 'Conversa',
|
||||
'home.lastConversation': 'Última Conversa',
|
||||
'home.noConversation': 'Nenhuma conversa',
|
||||
'home.justNow': 'Agora mesmo',
|
||||
|
||||
Reference in New Issue
Block a user