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

@@ -9,7 +9,7 @@
:fixed="true"
class="glass-nav-bar"
>
<view class="nav-title" :style="{ opacity: navTitleOpacity, color: navTitleColor }">{{ displayName || t('navDetail') }}</view>
<view class="nav-title" :style="{ opacity: navTitleOpacity, color: navTitleColor }">{{ displayName || $tr('房型详情') }}</view>
</tn-nav-bar>
<swiper
@@ -50,7 +50,7 @@
<view class="compact-hero-panel">
<view v-if="showVrPanel" class="compact-vr-panel" @click="openVR">
<image v-if="vrPoster" :src="vrPoster" mode="aspectFill" class="compact-hero-image"></image>
<view v-else class="compact-hero-empty tn-flex tn-flex-col-center tn-flex-row-center">{{ t('noImage') }}</view>
<view v-else class="compact-hero-empty tn-flex tn-flex-col-center tn-flex-row-center">{{ $tr('暂无图片') }}</view>
<view class="compact-vr-glow"></view>
</view>
<swiper
@@ -65,7 +65,7 @@
<image class="compact-hero-image" :src="image" mode="aspectFill"></image>
</swiper-item>
</swiper>
<view v-else class="compact-hero-empty tn-flex tn-flex-col-center tn-flex-row-center">{{ t('noImage') }}</view>
<view v-else class="compact-hero-empty tn-flex tn-flex-col-center tn-flex-row-center">{{ $tr('暂无图片') }}</view>
<view class="compact-hero-mask"></view>
<view class="compact-hero-topbar tn-flex tn-flex-row-between tn-flex-col-center">
<view v-if="hasVR" class="compact-media-tabs">
@@ -74,17 +74,17 @@
:class="{ 'compact-media-tab--active': currentMediaType === 'image' }"
@click="switchMedia('image')"
>
{{ t('imageTab') }}
{{ $tr('图片') }}
</view>
<view
class="compact-media-tab"
:class="{ 'compact-media-tab--active': currentMediaType === 'vr' }"
@click="switchMedia('vr')"
>
{{ t('vrTab') }}
{{ $tr('VR') }}
</view>
</view>
<view v-if="galleryList.length" class="compact-hero-counter">{{ t('imageCount', { count: galleryList.length }) }}</view>
<view v-if="galleryList.length" class="compact-hero-counter">{{ $tr('{count} 张图片', { count: galleryList.length }) }}</view>
</view>
<view class="compact-hero-action-layer">
<view v-if="showVrPanel" class="compact-hero-center-action" @click="openVR">
@@ -94,8 +94,8 @@
<text class="tn-icon-vr compact-hero-core-icon"></text>
</view>
<view class="compact-hero-action-text">
<view class="compact-hero-action-title">{{ t('vrPreview') }}</view>
<view class="compact-hero-action-desc">{{ t('vrPreviewDesc') }}</view>
<view class="compact-hero-action-title">{{ $tr('VR预览') }}</view>
<view class="compact-hero-action-desc">{{ $tr('切换到沉浸式看房模式。') }}</view>
</view>
</view>
<view v-else class="compact-hero-center-action" @click="previewImage">
@@ -105,8 +105,8 @@
<text class="tn-icon-image compact-hero-core-icon"></text>
</view>
<view class="compact-hero-action-text">
<view class="compact-hero-action-title">{{ t('viewLargeImage') }}</view>
<view class="compact-hero-action-desc">{{ t('viewLargeImageDesc') }}</view>
<view class="compact-hero-action-title">{{ $tr('查看大图') }}</view>
<view class="compact-hero-action-desc">{{ $tr('点击查看当前图片的大图预览。') }}</view>
</view>
</view>
</view>
@@ -147,7 +147,7 @@
<view class="action-left tn-flex tn-flex-col-center">
<button class="action-icon-btn" open-type="share">
<text class="tn-icon-share-circle action-icon-font"></text>
<text class="action-icon-text">{{ t('share') }}</text>
<text class="action-icon-text">{{ $tr('分享') }}</text>
</button>
</view>
<view class="action-right tn-flex tn-flex-col-center">
@@ -159,7 +159,7 @@
class="action-btn action-btn--primary"
@click="handleApplyStay"
>
<text>{{ t('applyStay') }}</text>
<text>{{ $tr('申请入住') }}</text>
</view>
</view>
</view>
@@ -680,7 +680,7 @@ export default {
return this.detailData.priceValue !== '' && this.detailData.priceValue !== null
},
primaryActionText() {
return this.isRoomType ? this.t('applyViewing') : this.t('bookRoom')
return this.isRoomType ? this.$tr('预约看房') : this.$tr('立即预订')
},
summaryBadges() {
const badges = []
@@ -693,30 +693,30 @@ export default {
badges.push(localizePayMethodText(this.detailData.payMethod, this.language))
}
if (this.isRoomType && this.detailData.needApproval === true) {
badges.push(this.t('needApproval'))
badges.push(this.$tr('需审核'))
}
if (this.isRoomType && this.detailData.needApproval === false) {
badges.push(this.t('noApprovalNeeded'))
badges.push(this.$tr('无需审核'))
}
return badges
},
basicInfoRows() {
const rows = this.isRoomType
? [
{ label: this.t('roomTypeNameLabel'), value: this.displayName },
{ label: this.t('englishNameLabel'), value: this.showEnglishName ? (this.detailData.nameEnDisplay || this.detailData.nameEn) : '' },
{ label: this.t('areaLabel'), value: this.language === 'en' ? (this.detailData.areaNameEnDisplay || this.detailData.areaNameEn || this.detailData.areaName) : (this.detailData.areaName || '') },
{ label: this.t('payMethodLabel'), value: localizePayMethodText(this.detailData.pricePlan.matchedStrategies || this.detailData.payMethod, this.language) },
{ label: this.t('priceLabel'), value: this.hasPrice ? `¥${this.detailData.priceValue}` : '' }
{ label: this.$tr('房型名称'), value: this.displayName },
{ label: this.$tr('英文名称'), value: this.showEnglishName ? (this.detailData.nameEnDisplay || this.detailData.nameEn) : '' },
{ label: this.$tr('所属区域'), value: this.language === 'en' ? (this.detailData.areaNameEnDisplay || this.detailData.areaNameEn || this.detailData.areaName) : (this.detailData.areaName || '') },
{ label: this.$tr('支付方式'), value: localizePayMethodText(this.detailData.pricePlan.matchedStrategies || this.detailData.payMethod, this.language) },
{ label: this.$tr('价格'), value: this.hasPrice ? `¥${this.detailData.priceValue}` : '' }
]
: [
{ label: this.t('roomCodeLabel'), value: this.detailData.roomCode },
{ label: this.t('roomTypeLabel'), value: this.language === 'en' ? (this.detailData.roomTypeNameEnDisplay || this.detailData.roomTypeNameEn || this.detailData.roomTypeName) : (this.detailData.roomTypeName || '') },
{ label: this.t('buildingLabel'), value: this.language === 'en' ? (this.detailData.buildingNameEnDisplay || this.detailData.buildingNameEn || this.detailData.buildingName) : (this.detailData.buildingName || '') },
{ label: this.t('unitLabel'), value: this.language === 'en' ? (this.detailData.buildingSectionNameEnDisplay || this.detailData.buildingSectionNameEn || this.detailData.buildingSectionName) : (this.detailData.buildingSectionName || '') },
{ label: this.t('floorLabel'), value: this.language === 'en' ? (this.detailData.floorNameEnDisplay || this.detailData.floorNameEn || this.detailData.floorName) : (this.detailData.floorName || '') },
{ label: this.t('orientationLabel'), value: this.language === 'en' ? (this.detailData.orientationEn || this.detailData.orientation) : (this.detailData.orientation || '') },
{ label: this.t('statusLabel'), value: localizeKnownStatusText(this.detailData.statusText, this.language) }
{ label: this.$tr('房号'), value: this.detailData.roomCode },
{ label: this.$tr('房型'), value: this.language === 'en' ? (this.detailData.roomTypeNameEnDisplay || this.detailData.roomTypeNameEn || this.detailData.roomTypeName) : (this.detailData.roomTypeName || '') },
{ label: this.$tr('楼栋'), value: this.language === 'en' ? (this.detailData.buildingNameEnDisplay || this.detailData.buildingNameEn || this.detailData.buildingName) : (this.detailData.buildingName || '') },
{ label: this.$tr('单元'), value: this.language === 'en' ? (this.detailData.buildingSectionNameEnDisplay || this.detailData.buildingSectionNameEn || this.detailData.buildingSectionName) : (this.detailData.buildingSectionName || '') },
{ label: this.$tr('楼层'), value: this.language === 'en' ? (this.detailData.floorNameEnDisplay || this.detailData.floorNameEn || this.detailData.floorName) : (this.detailData.floorName || '') },
{ label: this.$tr('朝向'), value: this.language === 'en' ? (this.detailData.orientationEn || this.detailData.orientation) : (this.detailData.orientation || '') },
{ label: this.$tr('状态'), value: localizeKnownStatusText(this.detailData.statusText, this.language) }
]
return rows.filter((item) => item.value)
@@ -798,22 +798,19 @@ export default {
},
onShareAppMessage() {
return {
title: this.displayName || this.t('shareTitle'),
title: this.displayName || this.$tr('房型详情'),
path: this.buildSharePath(),
imageUrl: this.detailData.image || ''
}
},
onShareTimeline() {
return {
title: this.displayName || this.t('shareTitle'),
title: this.displayName || this.$tr('房型详情'),
query: this.buildShareQuery(),
imageUrl: this.detailData.image || ''
}
},
methods: {
t(key, params = {}) {
return this.$tm('pkgExplore.room_detail.room_detail', key, params)
},
scheduleAutoSwitch() {
if (this.hasAutoSwitched || this.currentSwiperIndex !== 0) {
return
@@ -870,7 +867,7 @@ export default {
},
previewImage() {
if (!this.galleryList.length) {
uni.showToast({ title: this.t('noPreviewImage'), icon: 'none' })
uni.showToast({ title: this.$tr('暂无预览图片'), icon: 'none' })
return
}
uni.previewImage({
@@ -892,15 +889,15 @@ export default {
this.sourceAreaData && this.sourceAreaData.lng
)
if (latitude === null || longitude === null) {
uni.showToast({ title: this.t('noLocation'), icon: 'none' });
uni.showToast({ title: this.$tr('暂无位置信息'), icon: 'none' });
return;
}
uni.openLocation({
latitude,
longitude,
name: this.language === 'en'
? (detail.buildingNameEnDisplay || detail.buildingNameEn || detail.areaNameEnDisplay || detail.areaNameEn || detail.buildingName || detail.areaName || this.displayName || this.t('apartmentName'))
: (detail.buildingName || detail.areaName || this.displayName || this.t('apartmentName')),
? (detail.buildingNameEnDisplay || detail.buildingNameEn || detail.areaNameEnDisplay || detail.areaNameEn || detail.buildingName || detail.areaName || this.displayName || this.$tr('公寓'))
: (detail.buildingName || detail.areaName || this.displayName || this.$tr('公寓')),
address: this.language === 'en'
? (detail.addressEnDisplay || detail.addressEn || detail.address || (this.sourceAreaData && (this.sourceAreaData.addressEnDisplay || this.sourceAreaData.addressEn || this.sourceAreaData.address)) || '')
: (detail.address || (this.sourceAreaData && this.sourceAreaData.address) || ''),
@@ -908,14 +905,14 @@ export default {
});
},
openVR() {
const titleZh = `${this.displayName || this.t('roomTypeFallback')} ${this.t('vrViewingTitle')}`
const titleZh = `${this.displayName || this.$tr('房型')} ${this.$tr('VR看房')}`
const englishName = this.detailData.roomTypeNameEnDisplay
|| this.detailData.roomTypeNameEn
|| this.detailData.nameEnDisplay
|| this.detailData.nameEn
|| this.displayName
|| this.t('roomTypeFallback')
const titleEn = `${englishName} ${this.t('vrViewingTitle')}`
|| this.$tr('房型')
const titleEn = `${englishName} ${this.$tr('VR看房')}`
uni.navigateTo({
url: `/pkgExplore/vr_preview/vr_preview?title=${encodeURIComponent(this.language === 'en' ? titleEn : titleZh)}&titleZh=${encodeURIComponent(titleZh)}&titleEn=${encodeURIComponent(titleEn)}&poster=${encodeURIComponent(this.vrPoster || '')}`
})
@@ -1045,10 +1042,10 @@ export default {
if (!ensureBookingAccess({
language: this.$getLanguage(),
loginTitle: this.t('loginTitle'),
loginTitle: this.$tr('请先登录'),
loginContent: this.isRoomType
? this.t('roomTypeApplyLoginContent')
: this.t('allRoomsLoginContent'),
? this.$tr('请先登录后再提交该房型的看房申请。')
: this.$tr('请先登录后再预订该房间。'),
loginRedirectUrl: targetUrl
})) {
return
@@ -1068,8 +1065,8 @@ export default {
handleApplyStay() {
const serviceEntryUrl = this.buildServiceEntryUrl({
path: '/pkgService/submit_request/submit_request',
title: `${this.displayName || this.t('roomTypeFallback')} ${this.t('stayApplicationSuffix')}`,
desc: `${this.t('roomTypeCodePrefix')}${this.detailData.roomTypeCode || ''}.${this.hasPrice ? ` ${this.t('pricePrefix')}¥${this.detailData.priceValue}.` : ''}${this.detailData.pricePlan.matchedStrategies || this.detailData.payMethod ? ` ${this.t('payMethodPrefix')}${localizePayMethodText(this.detailData.pricePlan.matchedStrategies || this.detailData.payMethod, this.language)}.` : ''}`,
title: `${this.displayName || this.$tr('房型')} ${this.$tr('入住申请')}`,
desc: `${this.$tr('房型编码:')}${this.detailData.roomTypeCode || ''}.${this.hasPrice ? ` ${this.$tr('价格:')}¥${this.detailData.priceValue}.` : ''}${this.detailData.pricePlan.matchedStrategies || this.detailData.payMethod ? ` ${this.$tr('支付方式:')}${localizePayMethodText(this.detailData.pricePlan.matchedStrategies || this.detailData.payMethod, this.language)}.` : ''}`,
key: 'roomTypeSubmitList',
payload: {
sourceType: 'area-room-type',
@@ -1091,8 +1088,8 @@ export default {
if (!ensureBookingAccess({
language: this.$getLanguage(),
loginTitle: this.t('loginTitle'),
loginContent: this.t('stayLoginContent'),
loginTitle: this.$tr('请先登录'),
loginContent: this.$tr('请先登录后再提交入住申请。'),
loginRedirectUrl: serviceEntryUrl
})) {
return