Format season episodes in calendar tags

This commit is contained in:
jxxghp
2026-06-28 09:58:11 +08:00
parent 0776bc9fa0
commit 59abda63e3
2 changed files with 42 additions and 8 deletions
+37
View File
@@ -66,6 +66,43 @@ export const prefixWithPlus = (value: number) => (value > 0 ? `+${value}` : valu
// 格式化为Sxx
export const formatSeason = (value: string) => (value ? `S${value.padStart(2, '0')}` : '')
/**
* 格式化为 SxxExx 季集标识,多个连续集会合并为范围。
*/
export function formatSeasonEpisode(
season: number | string | null | undefined,
episodeNumbers: number[],
): string {
const seasonText = season === null || season === undefined || season === '' ? '' : formatSeason(String(season))
const normalizedNumbers = [...new Set(episodeNumbers)]
.map(number => Number(number))
.filter(number => Number.isFinite(number) && number > 0)
.sort((first, second) => first - second)
if (!normalizedNumbers.length) return seasonText
const formatEpisode = (number: number) => `E${String(number).padStart(2, '0')}`
const ranges: string[] = []
let start = normalizedNumbers[0]
let end = normalizedNumbers[0]
for (let index = 1; index < normalizedNumbers.length; index++) {
const currentNumber = normalizedNumbers[index]
if (currentNumber === end + 1) {
end = currentNumber
} else {
ranges.push(start === end ? `${seasonText}${formatEpisode(start)}` : `${seasonText}${formatEpisode(start)}-${formatEpisode(end)}`)
start = currentNumber
end = currentNumber
}
}
ranges.push(start === end ? `${seasonText}${formatEpisode(start)}` : `${seasonText}${formatEpisode(start)}-${formatEpisode(end)}`)
return ranges.join('、')
}
// 格式化为xx[TGMK]B
export function formatFileSize(bytes: number, decimals = 2, prefix = false) {
// 负数标记
+5 -8
View File
@@ -7,7 +7,7 @@ import FullCalendar from '@fullcalendar/vue3'
import type { Ref } from 'vue'
import type { MediaInfo, Subscribe, TmdbEpisode } from '@/api/types'
import api from '@/api'
import { formatDateDifference, formatEp, parseDate } from '@/@core/utils/formatters'
import { formatDateDifference, formatEp, formatSeasonEpisode, parseDate } from '@/@core/utils/formatters'
import { useI18n } from 'vue-i18n'
import { useDisplay } from 'vuetify'
import { getCurrentLocale } from '@/plugins/i18n'
@@ -526,12 +526,9 @@ function getMobileEventSubtitle(event: CalendarEventInfo) {
// 获取移动端集季标识。
function getMobileEventEpisodeTag(event: CalendarEventInfo) {
if (event.mediaType === '电影') return t('calendar.movie')
if (!event.subtitle && !event.season) return ''
if (!event.episodeNumbers.length && !event.season) return ''
const seasonText = event.season ? `S${event.season}` : ''
const episodeText = event.subtitle ? `E${event.subtitle}` : ''
return `${seasonText}${episodeText}`
return formatSeasonEpisode(event.season, event.episodeNumbers)
}
// 获取移动端时长标识。
@@ -829,8 +826,8 @@ onActivated(() => {
</template>
</VImg>
<span v-if="calendarEvent.subtitle" class="mobile-calendar-poster-episode">
EP {{ calendarEvent.subtitle }}
<span v-if="getMobileEventEpisodeTag(calendarEvent)" class="mobile-calendar-poster-episode">
{{ getMobileEventEpisodeTag(calendarEvent) }}
</span>
</div>