mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-10-14 12:02:27 +08:00
feat(subscription): show expiry times to minute
This commit is contained in:
@@ -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('')
|
||||
})
|
||||
})
|
||||
@@ -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,使用本地时间)
|
||||
*/
|
||||
|
||||
@@ -351,7 +351,7 @@
|
||||
: 'text-gray-700 dark:text-gray-300'
|
||||
"
|
||||
>
|
||||
{{ formatDateOnly(value) }}
|
||||
{{ formatDateTimeToMinute(value) }}
|
||||
</span>
|
||||
<div v-if="getDaysRemaining(value) !== null" class="text-xs text-gray-500">
|
||||
{{ getDaysRemaining(value) }} {{ t('admin.subscriptions.daysRemaining') }}
|
||||
@@ -598,7 +598,7 @@
|
||||
<span class="font-medium text-gray-900 dark:text-white">
|
||||
{{
|
||||
extendingSubscription.expires_at
|
||||
? formatDateOnly(extendingSubscription.expires_at)
|
||||
? formatDateTimeToMinute(extendingSubscription.expires_at)
|
||||
: t('admin.subscriptions.noExpiration')
|
||||
}}
|
||||
</span>
|
||||
@@ -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'
|
||||
|
||||
@@ -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')})`
|
||||
|
||||
Reference in New Issue
Block a user