From 33796030222a16ec40a5291e0c29deafe5e2babd Mon Sep 17 00:00:00 2001 From: cugxuan Date: Sun, 19 Jul 2026 22:43:35 +0800 Subject: [PATCH] feat(subscription): show expiry times to minute --- .../__tests__/formatDateTimeToMinute.spec.ts | 15 +++++++++++++ frontend/src/utils/format.ts | 21 +++++++++++++++++++ .../src/views/admin/SubscriptionsView.vue | 6 +++--- frontend/src/views/user/SubscriptionsView.vue | 4 ++-- 4 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 frontend/src/utils/__tests__/formatDateTimeToMinute.spec.ts diff --git a/frontend/src/utils/__tests__/formatDateTimeToMinute.spec.ts b/frontend/src/utils/__tests__/formatDateTimeToMinute.spec.ts new file mode 100644 index 0000000000..1e881adb18 --- /dev/null +++ b/frontend/src/utils/__tests__/formatDateTimeToMinute.spec.ts @@ -0,0 +1,15 @@ +import { describe, expect, it } from 'vitest' + +import { formatDateTimeToMinute } from '../format' + +describe('formatDateTimeToMinute', () => { + it('formats local date and time without seconds', () => { + const value = new Date(2026, 6, 19, 20, 30, 45) + + expect(formatDateTimeToMinute(value, 'en-GB')).toBe('19/07/2026, 20:30') + }) + + it('returns an empty string for an invalid date', () => { + expect(formatDateTimeToMinute(new Date('invalid'), 'en-GB')).toBe('') + }) +}) diff --git a/frontend/src/utils/format.ts b/frontend/src/utils/format.ts index 481fe397ef..787bd4b545 100644 --- a/frontend/src/utils/format.ts +++ b/frontend/src/utils/format.ts @@ -149,6 +149,27 @@ export function formatDateTime( return formatDate(date, options, localeOverride) } +/** + * 格式化日期时间(精确到分钟) + */ +export function formatDateTimeToMinute( + date: string | Date | null | undefined, + localeOverride?: string +): string { + return formatDate( + date, + { + year: 'numeric', + month: '2-digit', + day: '2-digit', + hour: '2-digit', + minute: '2-digit', + hour12: false + }, + localeOverride + ) +} + /** * 格式化为 date 控件值(YYYY-MM-DD,使用本地时间) */ diff --git a/frontend/src/views/admin/SubscriptionsView.vue b/frontend/src/views/admin/SubscriptionsView.vue index 3f6e73a8cd..85ae5f0a80 100644 --- a/frontend/src/views/admin/SubscriptionsView.vue +++ b/frontend/src/views/admin/SubscriptionsView.vue @@ -351,7 +351,7 @@ : 'text-gray-700 dark:text-gray-300' " > - {{ formatDateOnly(value) }} + {{ formatDateTimeToMinute(value) }}
{{ getDaysRemaining(value) }} {{ t('admin.subscriptions.daysRemaining') }} @@ -598,7 +598,7 @@ {{ extendingSubscription.expires_at - ? formatDateOnly(extendingSubscription.expires_at) + ? formatDateTimeToMinute(extendingSubscription.expires_at) : t('admin.subscriptions.noExpiration') }} @@ -764,7 +764,7 @@ import { adminAPI } from '@/api/admin' import type { UserSubscription, Group, GroupPlatform, SubscriptionType } from '@/types' import type { SimpleUser } from '@/api/admin/usage' import type { Column } from '@/components/common/types' -import { formatDateOnly } from '@/utils/format' +import { formatDateTimeToMinute } from '@/utils/format' import { getPersistedPageSize } from '@/composables/usePersistedPageSize' import AppLayout from '@/components/layout/AppLayout.vue' import TablePageLayout from '@/components/layout/TablePageLayout.vue' diff --git a/frontend/src/views/user/SubscriptionsView.vue b/frontend/src/views/user/SubscriptionsView.vue index b76f87582b..744529848a 100644 --- a/frontend/src/views/user/SubscriptionsView.vue +++ b/frontend/src/views/user/SubscriptionsView.vue @@ -256,7 +256,7 @@ import subscriptionsAPI from '@/api/subscriptions' import type { UserSubscription } from '@/types' import AppLayout from '@/components/layout/AppLayout.vue' import Icon from '@/components/icons/Icon.vue' -import { formatDateOnly } from '@/utils/format' +import { formatDateTimeToMinute } from '@/utils/format' import { hasPeakRate, formatPeakRateWindow, serverTimezoneLabel } from '@/utils/peak-rate' import { platformBorderClass, platformBadgeClass, platformButtonClass, platformLabel } from '@/utils/platformColors' import { getRemainingDurationParts, isOneTimeDailyQuota, type RemainingDurationParts } from '@/utils/subscriptionQuota' @@ -322,7 +322,7 @@ function formatExpirationDate(expiresAt: string): string { return t('userSubscriptions.status.expired') } - const dateStr = formatDateOnly(expires) + const dateStr = formatDateTimeToMinute(expires) if (days === 0) { return `${dateStr} (${t('common.today')})`