40 lines
1.5 KiB
TypeScript
40 lines
1.5 KiB
TypeScript
import { SONG_DURATION_MAX_SECONDS, SONG_DURATION_MIN_SECONDS } from '../config/constants.ts'
|
|
|
|
/** 时长差异容差(秒),差异不超过此值视为一致 */
|
|
export const DURATION_TOLERANCE_SECONDS = 5
|
|
|
|
export type SongDurationOutcome = 'keep' | 'clear' | 'fill' | 'nocheck'
|
|
|
|
export interface SongDurationDecision {
|
|
outcome: SongDurationOutcome
|
|
durationSeconds: number | null
|
|
}
|
|
|
|
/** 归一化已有时长:非法值或越出合法区间视为无时长 */
|
|
export function normalizeStoredDuration(value: unknown): number | null {
|
|
if (value === null || value === undefined || value === '') return null
|
|
const parsed = Number(value)
|
|
if (!Number.isFinite(parsed)) return null
|
|
const seconds = Math.floor(parsed)
|
|
if (seconds < SONG_DURATION_MIN_SECONDS || seconds > SONG_DURATION_MAX_SECONDS) return null
|
|
return seconds
|
|
}
|
|
|
|
/** 时长决策:库中无值且平台可查则补齐,有值但与平台不符则清空 */
|
|
export function decideDurationOutcome(
|
|
storedDurationSeconds: number | null,
|
|
actualDurationSeconds: number | null,
|
|
toleranceSeconds: number = DURATION_TOLERANCE_SECONDS
|
|
): SongDurationDecision {
|
|
if (actualDurationSeconds === null) {
|
|
return { outcome: 'nocheck', durationSeconds: storedDurationSeconds }
|
|
}
|
|
if (storedDurationSeconds === null) {
|
|
return { outcome: 'fill', durationSeconds: actualDurationSeconds }
|
|
}
|
|
if (Math.abs(actualDurationSeconds - storedDurationSeconds) > toleranceSeconds) {
|
|
return { outcome: 'clear', durationSeconds: null }
|
|
}
|
|
return { outcome: 'keep', durationSeconds: storedDurationSeconds }
|
|
}
|