Files
uni-fans-score/pages/setting/index.vue
T

184 lines
4.8 KiB
Vue

<template>
<view class="setting-page">
<view class="group">
<view class="item" @click="showLanguageSelector">
<text class="label">{{ $t('settings.language') }}</text>
<view class="right">
<text class="value">{{ currentLanguageText }}</text>
<uv-icon name="arrow-right" size="16" color="#c8c8c8"></uv-icon>
</view>
</view>
</view>
<view class="group">
<view class="item" @click="navigateTo('/pages/legal/agreement')">
<text class="label">{{ $t('user.userAgreement') }}</text>
<uv-icon name="arrow-right" size="16" color="#c8c8c8"></uv-icon>
</view>
<view class="item" @click="navigateTo('/pages/legal/privacy')">
<text class="label">{{ $t('user.privacyPolicy') }}</text>
<uv-icon name="arrow-right" size="16" color="#c8c8c8"></uv-icon>
</view>
</view>
<view class="group">
<view class="item" @click="handleLogout">
<text class="label">{{ $t('user.logout') }}</text>
<uv-icon name="arrow-right" size="16" color="#c8c8c8"></uv-icon>
</view>
</view>
</view>
</template>
<script setup>
import { ref, computed, onMounted, getCurrentInstance } from 'vue'
import { userLogout } from '@/config/api/user.js'
import { useI18n } from '@/utils/i18n.js'
const { t: $t } = useI18n()
// 获取全局 i18n 实例
const instance = getCurrentInstance()
const globalI18n = instance?.appContext?.config?.globalProperties?.$i18n
// 设置页面标题
onMounted(() => {
uni.setNavigationBarTitle({
title: $t('settings.title')
})
})
// 当前语言
const currentLanguage = ref(uni.getStorageSync('language') || 'zh-CN')
// 当前语言文本显示
const currentLanguageText = computed(() => {
return currentLanguage.value === 'zh-CN' ? '简体中文' : 'English'
})
const navigateTo = (url) => {
uni.navigateTo({ url })
}
// 显示语言选择器
const showLanguageSelector = () => {
uni.showActionSheet({
itemList: ['简体中文', 'English'],
success: (res) => {
const lang = res.tapIndex === 0 ? 'zh-CN' : 'en-US'
if (lang !== currentLanguage.value) {
console.log('========================================')
console.log('=== 用户选择切换语言 ===')
console.log('旧语言:', currentLanguage.value)
console.log('新语言:', lang)
// 1. 保存到缓存
uni.setStorageSync('language', lang)
console.log('✓ 语言已保存到缓存')
// 2. 立即更新 i18n 实例(重要!)
if (globalI18n) {
console.log('✓ 正在更新 globalI18n.locale...')
console.log(' 更新前:', globalI18n.locale)
globalI18n.locale = lang
console.log(' 更新后:', globalI18n.locale)
console.log('✓ 测试翻译:', globalI18n.t('common.loading'))
} else {
console.warn('✗ globalI18n 不存在!')
console.warn(' instance:', !!instance)
console.warn(' appContext:', !!instance?.appContext)
console.warn(' globalProperties:', !!instance?.appContext?.config?.globalProperties)
}
// 3. 更新当前语言状态
currentLanguage.value = lang
console.log('========================================')
// 4. 提示用户
uni.showToast({
title: lang === 'zh-CN' ? '语言已切换,正在刷新...' : 'Language switched, refreshing...',
icon: 'none',
duration: 800
})
// 5. 延迟后重新加载应用(确保 i18n 更新已生效)
setTimeout(() => {
console.log('=== 准备 reLaunch 到首页 ===')
// 使用 reLaunch 完全重启应用
uni.reLaunch({
url: '/pages/index/index',
success: () => {
console.log('✓ 页面已重新加载')
},
fail: (err) => {
console.error('✗ 页面重载失败:', err)
}
})
}, 800)
}
}
})
}
const handleLogout = async () => {
uni.showModal({
title: $t('common.tips'),
content: $t('user.confirmLogout'),
success: async (res) => {
if (res.confirm) {
const response = await userLogout();
if (response.code == 200) {
uni.showToast({ title: $t('user.logoutSuccess'), icon: 'none' })
setTimeout(() => {
uni.removeStorageSync('token')
uni.removeStorageSync('userInfo')
uni.reLaunch({ url: '/pages/login/index' })
}, 1200)
}
}
}
})
}
</script>
<style lang="scss" scoped>
.setting-page {
min-height: 100vh;
background-color: #f6f6f6;
padding-bottom: env(safe-area-inset-bottom);
}
.group {
margin-top: 20rpx;
background-color: #ffffff;
border-top: 1rpx solid #f0f0f0;
border-bottom: 1rpx solid #f0f0f0;
}
.item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 28rpx 30rpx;
border-top: 1rpx solid #f5f5f5;
}
.item:first-child {
border-top: none;
}
.label {
font-size: 30rpx;
color: #333333;
}
.right {
display: flex;
align-items: center;
gap: 8rpx;
}
.value {
font-size: 28rpx;
color: #999999;
}
</style>