refactor: 国际化文本迁移至全局 locales/messages.js

将组件级 i18n 对象重构为统一由全局 locales/messages.js 管理,确保中英文语言切换时正确显示对应文本。

- 新增 utils/i18n.js 国际化工具函数
- 更新 store/$t.mixin.js 翻译混入逻辑
- 迁移 pkgService、pkgBooking、pkgAccount、pkgExplore、pages 等共 58 个组件的中英文文本至全局消息表
This commit is contained in:
liangjian
2026-07-24 13:43:41 +08:00
parent 445bd850f4
commit 6e721ccc7e
58 changed files with 1810 additions and 4065 deletions

View File

@@ -3,9 +3,9 @@
<view class="section-header tn-flex tn-flex-row-between tn-flex-col-center">
<view class="title-wrap tn-flex tn-flex-col-center">
<view class="title-accent"></view>
<text class="section-title">{{ t('sectionTitle') }}</text>
<text class="section-title">{{ $tr('房间配置') }}</text>
</view>
<text class="section-subtitle">{{ t('sectionSubtitle', { count: assetList.length }) }}</text>
<text class="section-subtitle">{{ $tr('{count} 项配置', { count: assetList.length }) }}</text>
</view>
<view class="asset-grid">
@@ -53,11 +53,7 @@ export default {
default: 'zh'
}
},
methods: {
t(key, params = {}) {
return this.$tm('pkgExplore.room_detail.room_detail', key, params)
}
}
methods: {}
}
</script>

View File

@@ -2,7 +2,7 @@
<view class="room-hero">
<view v-if="showVrPanel" class="hero-vr-panel" @click="openVR">
<image v-if="vrPoster" :src="vrPoster" mode="aspectFill" class="hero-image"></image>
<view v-else class="hero-empty tn-flex tn-flex-col-center tn-flex-row-center">{{ t('noImage') }}</view>
<view v-else class="hero-empty tn-flex tn-flex-col-center tn-flex-row-center">{{ $tr('暂无图片') }}</view>
<view class="hero-vr-glow"></view>
<view class="vr-center-entry">
<view class="vr-center-ring vr-center-ring--outer"></view>
@@ -11,8 +11,8 @@
<text class="tn-icon-vr vr-center-core-icon"></text>
</view>
<view class="vr-center-text">
<view class="vr-center-title">{{ t('vrPreview') }}</view>
<view class="vr-center-desc">{{ t('vrPreviewDesc') }}</view>
<view class="vr-center-title">{{ $tr('VR预览') }}</view>
<view class="vr-center-desc">{{ $tr('切换到沉浸式看房模式。') }}</view>
</view>
</view>
</view>
@@ -30,7 +30,7 @@
</swiper-item>
</swiper>
<view v-else class="hero-empty tn-flex tn-flex-col-center tn-flex-row-center">
{{ t('noImage') }}
{{ $tr('暂无图片') }}
</view>
<view class="hero-mask"></view>
@@ -46,7 +46,7 @@
@click="switchMedia('image')"
>
<text class="tn-icon-image media-tab-icon"></text>
<text>{{ t('imageTab') }}</text>
<text>{{ $tr('图片') }}</text>
</view>
<view
class="media-tab"
@@ -54,7 +54,7 @@
@click="switchMedia('vr')"
>
<text class="tn-icon-vr media-tab-icon"></text>
<text>{{ t('vrPreview') }}</text>
<text>{{ $tr('VR预览') }}</text>
</view>
</view>
@@ -65,7 +65,7 @@
<!-- 引导下滑箭头 -->
<view class="scroll-down-hint tn-flex tn-flex-direction-column tn-flex-col-center">
<text class="hint-text">{{ t('swipeUpHint') }}</text>
<text class="hint-text">{{ $tr('上滑查看详情') }}</text>
<text class="tn-icon-up arrow-icon"></text>
</view>
</view>
@@ -113,9 +113,6 @@ export default {
}
},
methods: {
t(key) {
return this.$tm('pkgExplore.room_detail.room_detail', key)
},
onSwiperChange(e) {
this.currentImageIndex = e.detail.current;
this.$emit('swiper-change', e);

View File

@@ -2,7 +2,7 @@
<view class="room-info-wrapper">
<view class="section-panel" v-if="basicInfoRows.length">
<view class="section-header">
<text class="section-title">{{ t('basicInfo') }}</text>
<text class="section-title">{{ $tr('基础信息') }}</text>
</view>
<view class="info-list">
<view v-for="item in basicInfoRows" :key="item.label" class="info-row tn-flex tn-flex-row-between tn-flex-col-center">
@@ -16,7 +16,7 @@
<view class="section-panel" v-if="displayDescriptions.length">
<view class="section-header">
<text class="section-title">{{ isRoomType ? t('roomTypeDesc') : t('roomDesc') }}</text>
<text class="section-title">{{ isRoomType ? $tr('房型介绍') : $tr('房间介绍') }}</text>
</view>
<view class="desc-wrap" :class="{ 'desc-wrap--collapsed': isDescCollapsed }">
<view
@@ -32,7 +32,7 @@
class="expand-btn tn-flex tn-flex-row-center tn-flex-col-center"
@click="toggleDesc"
>
<text>{{ isDescCollapsed ? t('expandAll') : t('collapse') }}</text>
<text>{{ isDescCollapsed ? $tr('展开全部') : $tr('收起') }}</text>
<text :class="isDescCollapsed ? 'tn-icon-down' : 'tn-icon-up'" class="expand-icon"></text>
</view>
</view>
@@ -69,9 +69,6 @@ export default {
}
},
methods: {
t(key) {
return this.$tm('pkgExplore.room_detail.room_detail', key)
},
toggleDesc() {
this.isDescCollapsed = !this.isDescCollapsed;
}

View File

@@ -1,7 +1,7 @@
<template>
<view class="section-panel" v-if="bookingRuleRows.length">
<view class="section-header">
<text class="section-title">{{ isRoomType ? t('bookingRules') : t('bookingInfo') }}</text>
<text class="section-title">{{ isRoomType ? $tr('预订规则') : $tr('预订信息') }}</text>
</view>
<view class="rule-list">
<view v-for="item in bookingRuleRows" :key="item.label" class="rule-item tn-flex tn-flex-row-between tn-flex-col-center">
@@ -31,11 +31,7 @@ export default {
default: 'zh'
}
},
methods: {
t(key) {
return this.$tm('pkgExplore.room_detail.room_detail', key)
}
}
methods: {}
}
</script>

View File

@@ -6,10 +6,10 @@
<template v-if="hasPrice">
<text class="price-symbol">¥</text>
<text class="price-value">{{ detailData.priceValue }}</text>
<text class="price-unit">{{ t('priceUnit') }}</text>
<text class="price-unit">{{ $tr('/月') }}</text>
</template>
<template v-else>
<text class="price-empty">{{ t('pricePending') }}</text>
<text class="price-empty">{{ $tr('待定') }}</text>
</template>
</view>
@@ -40,7 +40,7 @@
<view class="address-info">
<view class="address-text tn-text-ellipsis">{{ shortAddress }}</view>
<view class="address-sub tn-flex tn-flex-col-center">
<text class="address-sub-text">{{ t('addressHint') }}</text>
<text class="address-sub-text">{{ $tr('查看地图位置') }}</text>
<text class="tn-icon-right address-sub-icon"></text>
</view>
</view>
@@ -48,7 +48,7 @@
<view class="address-right">
<view class="nav-btn tn-flex tn-flex-row-center tn-flex-col-center">
<text class="tn-icon-navigation-fill"></text>
<text class="nav-text">{{ t('navigate') }}</text>
<text class="nav-text">{{ $tr('导航') }}</text>
</view>
</view>
</view>
@@ -91,19 +91,16 @@ export default {
shortAddress() {
const addr = this.displayAddress;
if (!addr) {
return this.t('noAddress')
return this.$tr('暂无地址')
}
if (this.language === 'en') {
return addr
}
const short = addr.replace(/^(?:.*?省|.*?自治区)?(?:.*?市|.*?自治州)?/, '');
return short.trim() ? short : (addr || this.t('noAddress'));
return short.trim() ? short : (addr || this.$tr('暂无地址'));
}
},
methods: {
t(key) {
return this.$tm('pkgExplore.room_detail.room_detail', key)
},
handleAddressClick() {
this.$emit('open-map', this.detailData)
}