From 3eed51fd3e6663da92361e85a99973b9309a6e28 Mon Sep 17 00:00:00 2001 From: zhongming4762 Date: Wed, 29 Oct 2025 20:03:21 +0800 Subject: [PATCH] feat: increase support for multiple time zones MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 优化实现方法 --- .../backend-mock/api/timezone/getTimezoneOptions.ts | 6 +++++- apps/backend-mock/api/timezone/setTimezone.ts | 10 +++++++++- apps/backend-mock/utils/mock-data.ts | 2 +- .../src/widgets/timezone/timezone-button.vue | 5 +++-- packages/stores/src/modules/timezone.ts | 11 ++++++----- playground/src/api/core/timezone.ts | 13 ++++--------- 6 files changed, 28 insertions(+), 19 deletions(-) diff --git a/apps/backend-mock/api/timezone/getTimezoneOptions.ts b/apps/backend-mock/api/timezone/getTimezoneOptions.ts index 20b54ca8..6c241864 100644 --- a/apps/backend-mock/api/timezone/getTimezoneOptions.ts +++ b/apps/backend-mock/api/timezone/getTimezoneOptions.ts @@ -3,5 +3,9 @@ import { TIME_ZONE_OPTIONS } from '~/utils/mock-data'; import { useResponseSuccess } from '~/utils/response'; export default eventHandler(() => { - return useResponseSuccess(TIME_ZONE_OPTIONS); + const data = TIME_ZONE_OPTIONS.map((o) => ({ + label: `${o.timezone} (GMT${o.offset >= 0 ? `+${o.offset}` : o.offset})`, + value: o.timezone, + })); + return useResponseSuccess(data); }); diff --git a/apps/backend-mock/api/timezone/setTimezone.ts b/apps/backend-mock/api/timezone/setTimezone.ts index 9ec00a50..34d8f19e 100644 --- a/apps/backend-mock/api/timezone/setTimezone.ts +++ b/apps/backend-mock/api/timezone/setTimezone.ts @@ -1,5 +1,6 @@ import { eventHandler, readBody } from 'h3'; import { verifyAccessToken } from '~/utils/jwt-utils'; +import { TIME_ZONE_OPTIONS } from '~/utils/mock-data'; import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response'; import { setTimezone } from '~/utils/timezone-utils'; @@ -8,7 +9,14 @@ export default eventHandler(async (event) => { if (!userinfo) { return unAuthorizedResponse(event); } - const { timezone } = await readBody(event); + const body = await readBody<{ timezone?: unknown }>(event); + const timezone = + typeof body?.timezone === 'string' ? body.timezone : undefined; + const allowed = TIME_ZONE_OPTIONS.some((o) => o.timezone === timezone); + if (!timezone || !allowed) { + setResponseStatus(event, 400); + return useResponseError('Bad Request', 'Invalid timezone'); + } setTimezone(timezone); return useResponseSuccess({}); }); diff --git a/apps/backend-mock/utils/mock-data.ts b/apps/backend-mock/utils/mock-data.ts index 54cfa506..165c9ed0 100644 --- a/apps/backend-mock/utils/mock-data.ts +++ b/apps/backend-mock/utils/mock-data.ts @@ -9,7 +9,7 @@ export interface UserInfo { export interface TimezoneOption { offset: number; - timeZone: string; + timezone: string; } export const MOCK_USERS: UserInfo[] = [ diff --git a/packages/effects/layouts/src/widgets/timezone/timezone-button.vue b/packages/effects/layouts/src/widgets/timezone/timezone-button.vue index 78f71933..5d691f35 100644 --- a/packages/effects/layouts/src/widgets/timezone/timezone-button.vue +++ b/packages/effects/layouts/src/widgets/timezone/timezone-button.vue @@ -30,8 +30,9 @@ const [Modal, modalApi] = useVbenModal({ onConfirm: async () => { try { modalApi.setState({ confirmLoading: true }); - if (timezoneRef.value) { - await timezoneStore.setTimezone(unref(timezoneRef)); + const timezone = unref(timezoneRef); + if (timezone) { + await timezoneStore.setTimezone(timezone); } modalApi.close(); } finally { diff --git a/packages/stores/src/modules/timezone.ts b/packages/stores/src/modules/timezone.ts index 31904aef..c0b8873e 100644 --- a/packages/stores/src/modules/timezone.ts +++ b/packages/stores/src/modules/timezone.ts @@ -13,7 +13,7 @@ interface TimezoneHandler { value: string; }[] >; - onTimezoneChange?: (timezone: string) => Promise; + setTimezone?: (timezone: string) => Promise; } /** @@ -63,13 +63,12 @@ const useTimezoneStore = defineStore( getTimezone() || new Intl.DateTimeFormat().resolvedOptions().timeZone, ); - const timezoneHandler = getTimezoneHandler(); - /** * 初始化时区 * Initialize the timezone */ async function initTimezone() { + const timezoneHandler = getTimezoneHandler(); const timezone = await timezoneHandler.getTimezone?.(); if (timezone) { timezoneRef.value = timezone; @@ -84,7 +83,8 @@ const useTimezoneStore = defineStore( * @param timezone 时区字符串 */ async function setTimezone(timezone: string) { - await timezoneHandler.onTimezoneChange?.(timezone); + const timezoneHandler = getTimezoneHandler(); + await timezoneHandler.setTimezone?.(timezone); timezoneRef.value = timezone; // 设置dayjs默认时区 setDefaultTimezone(timezone); @@ -95,7 +95,8 @@ const useTimezoneStore = defineStore( * Get the timezone options */ async function getTimezoneOptions() { - return await timezoneHandler.getTimezoneOptions(); + const timezoneHandler = getTimezoneHandler(); + return (await timezoneHandler.getTimezoneOptions?.()) || []; } initTimezone().catch((error) => { diff --git a/playground/src/api/core/timezone.ts b/playground/src/api/core/timezone.ts index c21f808d..559ed4b2 100644 --- a/playground/src/api/core/timezone.ts +++ b/playground/src/api/core/timezone.ts @@ -6,14 +6,9 @@ import { requestClient } from '#/api/request'; * 获取系统支持的时区列表 */ export async function getTimezoneOptionsApi() { - const dataList = - (await requestClient.get( - '/timezone/getTimezoneOptions', - )) || []; - return dataList.map((item) => ({ - label: item.timezone, - value: item.timezone, - })); + return await requestClient.get( + '/timezone/getTimezoneOptions', + ); } /** * 获取用户时区 @@ -25,6 +20,6 @@ export async function getTimezoneApi(): Promise { * 设置用户时区 * @param timezone 时区 */ -export async function setTimezoneApi(timezone: string) { +export async function setTimezoneApi(timezone: string): Promise { return requestClient.post('/timezone/setTimezone', { timezone }); }