| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- <template>
- <uni-popup
- class="language-popup"
- ref="languageRef"
- type="bottom"
- :is-mask-click="false"
- borderRadius="10px 10px 0 0"
- >
- <view class="popup-content">
- <view class="popup-header">
- <text style="width: 100%">{{ $t("index.languageChange") }}</text>
- <text class="close-btn" @click="close">×</text>
- </view>
- <view class="language-options">
- <view
- v-for="(item, index) in locales"
- :key="item.code"
- class="language-option"
- :class="{ selected: getDisplayLanguageCode === item.code }"
- @click="handleLanguageSelection(item.code)"
- >
- {{ item.text }}
- </view>
- </view>
- </view>
- </uni-popup>
- </template>
- <script setup>
- import { computed, ref, watch, onMounted } from "vue";
- import { useI18n } from "vue-i18n";
- // 定义语言映射关系
- const LANGUAGE_MAPPING = {
- 'zh-Hans': 'zh-Hans',
- 'zh-CN': 'zh-Hans',
- 'en': 'en',
- 'ru': 'ru',
- 'auto': 'auto'
- }
- const emit = defineEmits(['close', 'language-change'])
- const { t, locale } = useI18n({
- useScope: 'global'
- })
- // 语言列表
- const locales = [
- { text: t('locale.auto'), code: 'auto' },
- { text: t('locale.en'), code: 'en' },
- { text: t('locale.zh-hans'), code: 'zh-Hans' },
- { text: t('locale.ru'), code: 'ru' }
- ]
- // 当前选择的语言(存储在本地的设置)
- const selectedLanguage = ref(uni.getStorageSync("language") || "auto");
- // 获取系统语言并映射到支持的语言
- const getSystemLanguage = () => {
- try {
- const systemLang = uni.getSystemInfoSync().language;
- console.log("🚀 ~ getSystemLanguage ~ systemLang:", systemLang)
-
- // 检查是否在映射表中
- if (LANGUAGE_MAPPING[systemLang]) {
- return LANGUAGE_MAPPING[systemLang];
- }
-
- // 检查语言前缀(例如 "en-US" -> "en")
- const langPrefix = systemLang.split('-')[0];
- if (SUPPORTED_LANGUAGES.includes(langPrefix)) {
- return langPrefix;
- }
-
- // 默认返回中文
- return 'zh-Hans';
- } catch (error) {
- console.error('获取系统语言失败:', error);
- return 'zh-Hans';
- }
- }
- // 计算属性:获取实际使用的语言代码
- const activeLanguage = computed(() => {
- if (selectedLanguage.value === "auto") {
- return getSystemLanguage();
- }
- return LANGUAGE_MAPPING[selectedLanguage.value] || selectedLanguage.value;
- });
- // 计算属性:用于显示的语言代码(处理auto选项)
- const getDisplayLanguageCode = computed(() => {
- return selectedLanguage.value === "auto" ? "auto" : activeLanguage.value;
- });
- const languageRef = ref(null);
- onMounted(() => {
- console.log("language-popup mounted", activeLanguage.value);
- console.log("language-popup mounted", uni.getSystemInfoSync().language);
- // 初始化时设置语言
- setAppLanguage(activeLanguage.value);
- });
- // 设置应用语言
- const setAppLanguage = (lang) => {
- try {
- locale.value = lang;
- uni.setLocale(lang);
- emit("language-change", lang);
- } catch (error) {
- console.error("Failed to set locale:", error);
- }
- };
- // 打开弹窗
- const open = () => {
- languageRef.value.open();
- };
- // 关闭弹窗
- const close = () => {
- languageRef.value.close();
- };
- // 处理语言选择
- const handleLanguageSelection = (lang) => {
- console.log("🚀 ~ handleLanguageSelection ~ lang:", lang)
- console.log("🚀 ~ handleLanguageSelection ~ selectedLanguage.value:", selectedLanguage.value)
- if (lang === selectedLanguage.value) {
- console.log(`🚀 ~ handleLanguageSelection ~ uni.getStorageSync("language"):`, uni.getStorageSync("language"))
- if (!uni.getStorageSync("language") ) {
- uni.setStorageSync("language", lang);
- }
- close();
- return;
- }
- uni.showModal({
- content: t("index.language-change-confirm"),
- cancelText: t("operation.cancel"),
- confirmText: t("operation.confirm"),
- success: (res) => {
- if (res.confirm) {
- // 更新选择的语言
- selectedLanguage.value = lang;
- // 保存到本地存储
- uni.setStorageSync("language", lang);
- // 设置应用语言
- setAppLanguage(activeLanguage.value);
- close();
- }
- },
- });
- };
- // 监听语言变化
- watch(selectedLanguage, (newVal) => {
- console.log("Language changed to:", newVal);
- });
- // 提供外部方法
- const expose = {
- open,
- };
- defineExpose(expose);
- </script>
- <style lang="scss" scoped>
- .language-popup {
- position: fixed;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- background-color: rgba(0, 0, 0, 0.5);
- display: flex;
- justify-content: center;
- align-items: center;
- z-index: 999;
- }
- .popup-content {
- background-color: #fff;
- width: 100%;
- // max-width: 300px;
- border-radius: 10px 10px 0px 0px;
- overflow: hidden;
- }
- .popup-header {
- padding: 15px;
- background-color: #007aff;
- color: #fff;
- display: flex;
- justify-content: space-between;
- align-items: center;
- text-align: center;
- }
- .close-btn {
- font-size: 20px;
- cursor: pointer;
- }
- .language-options {
- padding: 15px;
- }
- .language-option {
- padding: 10px;
- border-bottom: 1px solid #eee;
- cursor: pointer;
- text-align: center;
- }
- .language-option:last-child {
- border-bottom: none;
- }
- .language-option.selected {
- color: #007aff;
- font-weight: bold;
- }
- </style>
|