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

@@ -30,7 +30,7 @@
<view class="sheet-handle"></view>
<view class="sheet-header">
<text class="sheet-title">{{ t('controlPanel') }}</text>
<text class="sheet-title">{{ $tr('控制面板') }}</text>
<text class="sheet-subtitle">{{ functionCountText }}</text>
</view>
@@ -46,7 +46,7 @@
<text class="tn-icon-set panel-icon"></text>
<text>{{ getFunctionLabel(func) }}</text>
</view>
<view class="status-tag" v-if="!isFunctionSupported(func)">{{ t('pendingTag') }}</view>
<view class="status-tag" v-if="!isFunctionSupported(func)">{{ $tr('待完善') }}</view>
</view>
<!-- Switch Theme -->
@@ -60,7 +60,7 @@
<block v-else-if="isSlideFunction(func)">
<view class="slider-container">
<view class="slider-header">
<text class="slider-label">{{ t('sliderLabel') }}</text>
<text class="slider-label">{{ $tr('亮度 / 数值') }}</text>
<text class="slider-value">{{ controlValue }}%</text>
</view>
<slider
@@ -76,7 +76,7 @@
@change="handleControlValueChange"
/>
<view class="slider-apply-btn" :class="{ 'is-disabled': isSubmitting }" @click="submitSlideValue(index)">
<text>{{ t('applySetting') }}</text>
<text>{{ $tr('应用设置') }}</text>
</view>
</view>
</block>
@@ -86,22 +86,22 @@
<view class="control-row curtain-row">
<view class="curtain-btn" :class="{ 'is-active': curtainAction === 'open', 'is-disabled': isSubmitting }" @click="operateCurtain(index, 'open')">
<text class="tn-icon-up"></text>
<text class="btn-label">{{ t('curtainOpen') }}</text>
<text class="btn-label">{{ $tr('打开') }}</text>
</view>
<view class="curtain-btn stop-btn" :class="{ 'is-active': curtainAction === 'stop', 'is-disabled': isSubmitting }" @click="operateCurtain(index, 'stop')">
<text class="tn-icon-minus"></text>
<text class="btn-label">{{ t('curtainPause') }}</text>
<text class="btn-label">{{ $tr('暂停') }}</text>
</view>
<view class="curtain-btn" :class="{ 'is-active': curtainAction === 'close', 'is-disabled': isSubmitting }" @click="operateCurtain(index, 'close')">
<text class="tn-icon-down"></text>
<text class="btn-label">{{ t('curtainClose') }}</text>
<text class="btn-label">{{ $tr('关闭') }}</text>
</view>
</view>
</block>
<view v-else class="unsupported-box" @click="notifyUnsupportedFunction(index)">
<text class="tn-icon-warning"></text>
<text>{{ t('unsupportedBoxText') }}</text>
<text>{{ $tr('当前功能暂未开放使用,点击反馈') }}</text>
</view>
</view>
@@ -173,68 +173,6 @@ function resolveRefreshIntervalMs(value, fallback = 1000) {
}
export default {
i18n: {
zh: {
controlPanel: '控制面板',
pendingTag: '待完善',
sliderLabel: '亮度 / 数值',
applySetting: '应用设置',
curtainOpen: '打开',
curtainPause: '暂停',
curtainClose: '关闭',
unsupportedBoxText: '当前功能暂未开放使用,点击反馈',
deviceDetail: '设备详情',
currentRoom: '当前房间',
functionCount: '{count}项功能',
commandSending: '指令下发中...',
syncHint: '操作完成后会自动刷新设备状态',
deviceMissing: '设备信息缺失',
unsupportedFunction: '{name}操作功能未完善',
unknownSchema: '未识别到参数模板',
schemaApplied: '{name}参数已下发',
actionSuccess: '操作成功',
deviceIdMissing: '设备ID缺失',
functionCodeMissing: '功能编码缺失',
commandFailed: '指令下发失败',
deviceClosed: '已关闭',
deviceEnabled: '已开启',
deviceOpened: '已打开',
curtainOpened: '窗帘已打开',
curtainClosed: '窗帘已关闭',
curtainPaused: '窗帘已暂停',
sliderUpdated: '滑块值已更新'
},
en: {
controlPanel: 'Control Panel',
pendingTag: 'Pending',
sliderLabel: 'Brightness / Value',
applySetting: 'Apply',
curtainOpen: 'Open',
curtainPause: 'Pause',
curtainClose: 'Close',
unsupportedBoxText: 'This function is not available yet. Tap to send feedback.',
deviceDetail: 'Device Details',
currentRoom: 'Current Room',
functionCount: '{count} functions',
commandSending: 'Sending command...',
syncHint: 'Device status refreshes automatically after each action',
deviceMissing: 'Missing device information',
unsupportedFunction: '{name} is not fully supported yet',
unknownSchema: 'No parameter template recognized',
schemaApplied: '{name} parameters sent',
actionSuccess: 'Action completed',
deviceIdMissing: 'Missing device ID',
functionCodeMissing: 'Missing function code',
commandFailed: 'Failed to send command',
deviceClosed: 'Closed',
deviceEnabled: 'Enabled',
deviceOpened: 'Opened',
curtainOpened: 'Curtain opened',
curtainClosed: 'Curtain closed',
curtainPaused: 'Curtain paused',
sliderUpdated: 'Slider value updated'
}
},
data() {
return {
brandId: DEFAULT_BRAND_ID,
@@ -257,10 +195,10 @@ export default {
return this.$getLanguage()
},
deviceName() {
return this.device.deviceName || this.t('deviceDetail')
return this.device.deviceName || this.$tr('设备详情')
},
displayRoomName() {
return this.roomName || this.roomCode || this.t('currentRoom')
return this.roomName || this.roomCode || this.$tr('当前房间')
},
controlType() {
return inferDeviceControlType(this.device)
@@ -273,16 +211,16 @@ export default {
},
functionCountText() {
const count = this.deviceFunctions.length
return count ? this.t('functionCount', { count }) : this.controlTypeLabel
return count ? this.$tr('{count}项功能', { count }) : this.controlTypeLabel
},
statusText() {
return buildDeviceStateText(this.device)
},
syncHintText() {
if (this.isSubmitting) {
return this.t('commandSending')
return this.$tr('指令下发中...')
}
return this.t('syncHint')
return this.$tr('操作完成后会自动刷新设备状态')
},
deviceFunctions() {
return getDeviceFunctions(this.device)
@@ -306,7 +244,7 @@ export default {
const parsedDevice = safeParseDevice(options.device)
if (!parsedDevice) {
uni.showToast({
title: this.t('deviceMissing'),
title: this.$tr('设备信息缺失'),
icon: 'none'
})
return
@@ -327,9 +265,6 @@ export default {
this.stopDevicePolling()
},
methods: {
t(key, params) {
return this.$tm('pkgService.device_control.device_control', key, params)
},
goBack() {
uni.navigateBack()
},
@@ -613,7 +548,7 @@ export default {
? this.getDeviceFunctionByIndex(funcOrIndex)
: funcOrIndex
uni.showToast({
title: this.t('unsupportedFunction', { name: this.getFunctionLabel(func) }),
title: this.$tr('{name}操作功能未完善', { name: this.getFunctionLabel(func) }),
icon: 'none'
})
},
@@ -676,7 +611,7 @@ export default {
const fields = this.getFunctionFields(func, index)
if (!fields.length) {
uni.showToast({
title: this.t('unknownSchema'),
title: this.$tr('未识别到参数模板'),
icon: 'none'
})
return
@@ -688,11 +623,11 @@ export default {
return result
}, {})
this.executeCommand(func, payload, this.t('schemaApplied', { name: this.getFunctionLabel(func) }))
this.executeCommand(func, payload, this.$tr('{name}参数已下发', { name: this.getFunctionLabel(func) }))
},
executeCommand(func, command, successText = this.t('actionSuccess')) {
executeCommand(func, command, successText = this.$tr('操作成功')) {
if (!this.device || !this.device.deviceNo) {
uni.showToast({ title: this.t('deviceIdMissing'), icon: 'none' })
uni.showToast({ title: this.$tr('设备ID缺失'), icon: 'none' })
return Promise.resolve()
}
@@ -703,7 +638,7 @@ export default {
const functionCode = String((func && func.functionCode) || '').trim()
if (!functionCode) {
uni.showToast({ title: this.t('functionCodeMissing'), icon: 'none' })
uni.showToast({ title: this.$tr('功能编码缺失'), icon: 'none' })
return Promise.resolve()
}
@@ -720,7 +655,7 @@ export default {
.catch((error) => {
console.error('execute device command failed', error)
uni.showToast({
title: (error && (error.message || error.msg)) || this.t('commandFailed'),
title: (error && (error.message || error.msg)) || this.$tr('指令下发失败'),
icon: 'none'
})
})
@@ -734,14 +669,14 @@ export default {
if (this.isSubmitting) {
return
}
this.executeCommand(func, this.buildSwitchCommandPayload(index, !this.device.active), this.device.active ? this.t('deviceClosed') : this.t('deviceEnabled'))
this.executeCommand(func, this.buildSwitchCommandPayload(index, !this.device.active), this.device.active ? this.$tr('已关闭') : this.$tr('已开启'))
},
setSwitchState(index = 0, value) {
const func = this.getDeviceFunctionByIndex(index)
if (this.isSubmitting) {
return
}
this.executeCommand(func, this.buildSwitchCommandPayload(index, !!value), value ? this.t('deviceOpened') : this.t('deviceClosed'))
this.executeCommand(func, this.buildSwitchCommandPayload(index, !!value), value ? this.$tr('已打开') : this.$tr('已关闭'))
},
operateCurtain(index = 0, action) {
const func = this.getDeviceFunctionByIndex(index)
@@ -751,7 +686,7 @@ export default {
this.executeCommand(
func,
this.buildCurtainCommandPayload(index, action),
action === 'open' ? this.t('curtainOpened') : (action === 'close' ? this.t('curtainClosed') : this.t('curtainPaused'))
action === 'open' ? this.$tr('窗帘已打开') : (action === 'close' ? this.$tr('窗帘已关闭') : this.$tr('窗帘已暂停'))
)
},
handleControlValueChange(event) {
@@ -765,7 +700,7 @@ export default {
this.executeCommand(
func,
this.buildSlideCommandPayload(index, this.controlValue),
this.t('sliderUpdated')
this.$tr('滑块值已更新')
)
}
}