From d352fac2f1025100952bc382c97699be0da35ad0 Mon Sep 17 00:00:00 2001 From: duanshuwen Date: Wed, 3 Jun 2026 21:03:04 +0800 Subject: [PATCH] feat(i18n): add full multi-language support for app modules Add new i18n modules for booking, goods, order, and service features across en-US, zh-CN, th-TH locales Extend existing quick module translations with new card, date, and page title strings Replace all hardcoded static text in UI components with vue-i18n translation hooks Update the main i18n registry and login page language switching to support the new translations --- src/components/Calender/index.vue | 40 +++-- src/components/DateRangeSection/index.vue | 11 +- src/components/FormCard/index.vue | 34 ++-- src/components/ModuleTitle/index.vue | 7 +- src/components/Qrcode/index.vue | 6 +- src/components/RefundPopup/index.vue | 11 +- src/components/SumCard/index.vue | 8 +- src/components/SwipeCards/index.vue | 5 +- src/components/UseDateRange/index.vue | 5 +- src/i18n/messages.ts | 16 ++ src/i18n/modules/booking/en-US.ts | 36 ++++ src/i18n/modules/booking/index.ts | 12 ++ src/i18n/modules/booking/th-TH.ts | 36 ++++ src/i18n/modules/booking/zh-CN.ts | 36 ++++ src/i18n/modules/common/en-US.ts | 83 +++++++++ src/i18n/modules/common/th-TH.ts | 83 +++++++++ src/i18n/modules/common/zh-CN.ts | 83 +++++++++ src/i18n/modules/goods/en-US.ts | 32 ++++ src/i18n/modules/goods/index.ts | 12 ++ src/i18n/modules/goods/th-TH.ts | 32 ++++ src/i18n/modules/goods/zh-CN.ts | 32 ++++ src/i18n/modules/home/en-US.ts | 167 ++++++++++++++++++ src/i18n/modules/home/th-TH.ts | 167 ++++++++++++++++++ src/i18n/modules/home/zh-CN.ts | 167 ++++++++++++++++++ src/i18n/modules/order/en-US.ts | 92 ++++++++++ src/i18n/modules/order/index.ts | 12 ++ src/i18n/modules/order/th-TH.ts | 92 ++++++++++ src/i18n/modules/order/zh-CN.ts | 92 ++++++++++ src/i18n/modules/quick/en-US.ts | 9 + src/i18n/modules/quick/th-TH.ts | 9 + src/i18n/modules/quick/zh-CN.ts | 9 + src/i18n/modules/service/en-US.ts | 24 +++ src/i18n/modules/service/index.ts | 12 ++ src/i18n/modules/service/th-TH.ts | 24 +++ src/i18n/modules/service/zh-CN.ts | 24 +++ src/i18n/ui-hardcoded.test.ts | 159 +++++++++++++++++ .../components/ConactSection/index.vue | 17 +- .../booking/components/DetailPopup/index.vue | 9 +- .../components/FooterSection/index.vue | 5 +- .../booking/components/UserSection/index.vue | 15 +- src/pages/booking/index.vue | 23 ++- .../goods/components/DateSelector/index.vue | 11 +- .../goods/components/GoodPackage/index.vue | 5 +- .../goods/components/LocationCard/index.vue | 12 +- src/pages/goods/index.vue | 13 +- .../ActivityListComponent/index.vue | 11 +- .../home/components/AddCarCard/index.vue | 9 +- .../home/components/AiTabSwitch/index.vue | 9 +- .../home/components/AnswerComponent/index.vue | 7 +- .../home/components/ChatCardAi/index.vue | 5 +- src/pages/home/components/ChatGuide/index.vue | 16 +- .../home/components/ChatInputArea/index.vue | 7 +- .../home/components/ChatMainList/index.vue | 26 +-- .../home/components/ChatQuickAccess/index.vue | 14 +- .../components/CreateServiceOrder/index.vue | 43 +++-- .../components/DetailCardComponent/index.vue | 5 +- .../DetailCardGoodsContentList/index.vue | 5 +- .../components/QuickQuestions/index.vue | 10 +- .../home/components/DrawerSection/index.vue | 20 ++- src/pages/home/components/Feedback/index.vue | 32 ++-- .../LongTextGuideCardPreview/index.vue | 87 ++++----- .../home/components/MoreService/index.vue | 39 ++-- .../home/components/NoticeMessage/detail.vue | 8 +- .../home/components/NoticeMessage/index.vue | 12 +- .../components/OpenMapComponent/index.vue | 13 +- .../components/QuickBookingCalender/index.vue | 28 +-- .../QuickBookingContentList/index.vue | 6 +- .../components/SurveyQuestionnaire/index.vue | 7 +- src/pages/login/index.vue | 8 +- .../order/components/AmtSection/index.vue | 11 +- .../order/components/FooterSection/index.vue | 23 +-- .../order/components/GoodsInfo/index.vue | 11 +- .../components/OrderCard/OrderCardContent.vue | 45 ++--- .../order/components/OrderCard/index.vue | 42 +++-- .../order/components/OrderInfo/index.vue | 11 +- .../order/components/OrderQrcode/index.vue | 21 ++- .../components/OrderStatusInfo/index.vue | 21 +-- src/pages/order/components/Tabs/index.vue | 17 +- src/pages/order/components/UserInfo/index.vue | 7 +- .../order/components/VoucherList/index.vue | 15 +- src/pages/order/detail.vue | 9 +- src/pages/order/list.vue | 9 +- src/pages/quick/components/Card/index.vue | 6 +- src/pages/quick/index.vue | 12 +- .../service/components/OrderCard/index.vue | 29 +-- src/pages/service/index.vue | 9 +- 86 files changed, 2132 insertions(+), 382 deletions(-) create mode 100644 src/i18n/modules/booking/en-US.ts create mode 100644 src/i18n/modules/booking/index.ts create mode 100644 src/i18n/modules/booking/th-TH.ts create mode 100644 src/i18n/modules/booking/zh-CN.ts create mode 100644 src/i18n/modules/goods/en-US.ts create mode 100644 src/i18n/modules/goods/index.ts create mode 100644 src/i18n/modules/goods/th-TH.ts create mode 100644 src/i18n/modules/goods/zh-CN.ts create mode 100644 src/i18n/modules/order/en-US.ts create mode 100644 src/i18n/modules/order/index.ts create mode 100644 src/i18n/modules/order/th-TH.ts create mode 100644 src/i18n/modules/order/zh-CN.ts create mode 100644 src/i18n/modules/service/en-US.ts create mode 100644 src/i18n/modules/service/index.ts create mode 100644 src/i18n/modules/service/th-TH.ts create mode 100644 src/i18n/modules/service/zh-CN.ts create mode 100644 src/i18n/ui-hardcoded.test.ts diff --git a/src/components/Calender/index.vue b/src/components/Calender/index.vue index b3a1922..9c4e8ae 100644 --- a/src/components/Calender/index.vue +++ b/src/components/Calender/index.vue @@ -6,8 +6,9 @@
- 日历选择 - 选择住宿日期,以下价格为单晚参考价 + {{ t("common.calendar.title") }} + {{ + t("common.calendar.stayDateHint") }}
@@ -61,12 +62,15 @@ import { watch, onBeforeUnmount, } from "vue"; +import { useI18n } from "vue-i18n"; // 定义组件名称 defineOptions({ name: "Calendar", }); +const { t } = useI18n(); + // van-popup组件引用 const popup = ref(null); const show = ref(false); @@ -140,7 +144,15 @@ const emit = defineEmits([ ]); // 响应式数据 -const weekDays = ref(["一", "二", "三", "四", "五", "六", "日"]); +const weekDays = computed(() => [ + t("common.calendar.weekdays.monday"), + t("common.calendar.weekdays.tuesday"), + t("common.calendar.weekdays.wednesday"), + t("common.calendar.weekdays.thursday"), + t("common.calendar.weekdays.friday"), + t("common.calendar.weekdays.saturday"), + t("common.calendar.weekdays.sunday"), +]); const selectedDates = ref([]); const currentYear = ref(new Date().getFullYear()); const isRangeSelecting = ref(false); @@ -163,7 +175,7 @@ const yearMonthsGrid = computed(() => { months.push({ key: `${year}-${month}`, - title: `${year}年${month}月`, + title: t("common.calendar.monthTitle", { year, month }), year: year, month: month, grid: generateCalendarGrid(year, month), @@ -298,13 +310,13 @@ const getDateLabel = (dateStr) => { if (props.mode === "range") { if (dateStr === rangeStart.value && dateStr === rangeEnd.value) { // 当入住和离店是同一天时,显示"住/离" - return "住/离"; + return t("common.calendar.labels.stayAndLeave"); } if (dateStr === rangeStart.value) { - return "入住"; + return t("common.calendar.labels.checkIn"); } if (dateStr === rangeEnd.value) { - return "离店"; + return t("common.calendar.labels.checkOut"); } } @@ -367,7 +379,7 @@ const getDateLabelClass = (dateInfo) => { const handleDateClick = (dateInfo) => { if (!dateInfo) return; if (dateInfo.disabled) { - showToast("该日期不可选"); + showToast(t("common.calendar.errors.disabledDate")); // 仍然触发点击事件,供上层参考 emit("date-click", { date: dateInfo.date, @@ -421,11 +433,11 @@ const handleRangeSelection = (dateInfo) => { dateInfo.price !== undefined && dateInfo.price !== "-"; if (!hasPrice) { - showToast('所选日期不可预订,请重新选择'); + showToast(t("common.calendar.errors.dateUnavailable")); return; } if (dateInfo.stock !== undefined && Number(dateInfo.stock) <= 0) { - showToast("所选日期库存不足,请选择其他日期"); + showToast(t("common.calendar.errors.stockUnavailable")); return; } } @@ -438,7 +450,7 @@ const handleRangeSelection = (dateInfo) => { // 否则为结束日期(完成选择) if (rangeStart.value === dateInfo.date) { - showToast("离店日期不能与入住日期相同"); + showToast(t("common.calendar.errors.sameDate")); return; } @@ -453,7 +465,7 @@ const handleRangeSelection = (dateInfo) => { // 检查日期跨度是否超过28天 const daysBetween = calculateDaysBetween(rangeStart.value, rangeEnd.value); if (daysBetween > 28) { - showToast("预定时间不能超过28天"); + showToast(t("common.calendar.errors.maxRange")); rangeStart.value = null; rangeEnd.value = null; isRangeSelecting.value = false; @@ -467,7 +479,7 @@ const handleRangeSelection = (dateInfo) => { (d) => d.price === null || d.price === undefined || d.price === "-", ); if (missing) { - showToast("所选区间包含无价格日期,请重新选择"); + showToast(t("common.calendar.errors.missingPrice")); rangeStart.value = null; rangeEnd.value = null; return; @@ -478,7 +490,7 @@ const handleRangeSelection = (dateInfo) => { return item && item.stock !== undefined && Number(item.stock) <= 0; }); if (badStock) { - showToast("所选区间包含库存不足的日期,请重新选择"); + showToast(t("common.calendar.errors.rangeStockUnavailable")); rangeStart.value = null; rangeEnd.value = null; return; diff --git a/src/components/DateRangeSection/index.vue b/src/components/DateRangeSection/index.vue index 2805de5..d51a509 100644 --- a/src/components/DateRangeSection/index.vue +++ b/src/components/DateRangeSection/index.vue @@ -1,19 +1,19 @@ diff --git a/src/pages/home/components/QuickBookingContentList/index.vue b/src/pages/home/components/QuickBookingContentList/index.vue index 516ab34..c814d54 100644 --- a/src/pages/home/components/QuickBookingContentList/index.vue +++ b/src/pages/home/components/QuickBookingContentList/index.vue @@ -29,7 +29,8 @@ /{{ item.stockUnitLabel }}
- 下单 + {{ + t("home.quickBooking.order") }}
@@ -40,10 +41,13 @@ diff --git a/src/pages/order/components/OrderQrcode/index.vue b/src/pages/order/components/OrderQrcode/index.vue index a598f22..6957372 100644 --- a/src/pages/order/components/OrderQrcode/index.vue +++ b/src/pages/order/components/OrderQrcode/index.vue @@ -4,10 +4,10 @@
- 核销凭证 + {{ t("order.qrcode.title") }}
- 请向工作人员出示此码 + {{ t("order.qrcode.instruction") }}
@@ -25,11 +25,11 @@
- 总计{{ selectedVoucher.count }}{{ selectedVoucher.unit }} + {{ t("order.qrcode.total") }}{{ selectedVoucher.count }}{{ selectedVoucher.unit }}
- 剩{{ selectedVoucher.count - selectedVoucher.writeOffCount - }}{{ selectedVoucher.unit }}可用 + {{ t("order.qrcode.remaining") }}{{ selectedVoucher.count - selectedVoucher.writeOffCount + }}{{ selectedVoucher.unit }}{{ t("order.qrcode.available") }}
@@ -38,14 +38,14 @@ class="flex flex-col w-full items-center justify-center rounded-[8px] border border-ink-200 pt-[16px] pb-[32px] mt-[12px]">
- 凭证{{ + {{ t("order.qrcode.voucher") }}{{ selectedVoucherList.length > 1 ? currentVoucherIndex + 1 : "" }}
- 此码仅可核销{{ + {{ t("order.qrcode.onlyVerify") }}{{ selectedVoucher.count - selectedVoucher.writeOffCount - }}份 + }}{{ t("order.qrcode.unit") }}
@@ -77,7 +77,7 @@ -
扫码后点击下一张
+
{{ t("order.qrcode.swipeHint") }}
@@ -92,8 +92,11 @@ diff --git a/src/pages/order/components/Tabs/index.vue b/src/pages/order/components/Tabs/index.vue index fd4bfe7..89a5065 100644 --- a/src/pages/order/components/Tabs/index.vue +++ b/src/pages/order/components/Tabs/index.vue @@ -28,23 +28,23 @@ import { ref, reactive, + computed, onMounted, nextTick, watch, getCurrentInstance, } from "vue"; +import { useI18n } from "vue-i18n"; // 获取组件实例 const instance = getCurrentInstance(); +const { t } = useI18n(); // Props const props = defineProps({ tabs: { type: Array, - default: () => [ - { label: "全部订单", value: "all" }, - { label: "服务工单", value: "service" }, - ], + default: () => [], }, defaultActive: { type: Number, @@ -61,7 +61,11 @@ const emit = defineEmits(["change", "update:modelValue"]); // 响应式数据 const activeIndex = ref(props.defaultActive); -const tabList = ref(props.tabs); +const defaultTabs = computed(() => [ + { label: t("order.tabs.all"), value: "all" }, + { label: t("order.tabs.service"), value: "service" }, +]); +const tabList = computed(() => props.tabs.length ? props.tabs : defaultTabs.value); const indicatorLeft = ref(0); const indicatorWidth = ref(0); const tabItemRects = reactive([]); @@ -164,8 +168,7 @@ watch( // 监听tabs变化 watch( () => props.tabs, - (newTabs) => { - tabList.value = newTabs; + () => { // 重置初始化状态 indicatorInitialized.value = false; // 重新初始化指示器 diff --git a/src/pages/order/components/UserInfo/index.vue b/src/pages/order/components/UserInfo/index.vue index e1ee993..46366c9 100644 --- a/src/pages/order/components/UserInfo/index.vue +++ b/src/pages/order/components/UserInfo/index.vue @@ -2,12 +2,12 @@
- 住客姓名 + {{ t("order.user.guestName") }} {{ item.visitorName }}
- 联系电话 + {{ t("order.user.phone") }} {{ contactPhone }}
@@ -15,6 +15,9 @@ diff --git a/src/pages/service/index.vue b/src/pages/service/index.vue index e4d9e4a..c3db8ec 100644 --- a/src/pages/service/index.vue +++ b/src/pages/service/index.vue @@ -1,14 +1,15 @@