Files
BYW-VoiceHub/server/utils/submission-restriction-policy.ts
T

49 lines
2.0 KiB
TypeScript

export type SubmissionRestrictionMode = 'none' | 'semester' | 'window'
export type SubmissionRestrictionScope = 'self' | 'all'
export interface SubmissionRestrictionPolicy {
mode: SubmissionRestrictionMode
sameSongHours: number | null
sameArtistHours: number | null
scope: SubmissionRestrictionScope
}
export interface SubmissionRestrictionSettings {
enableSubmissionRestriction?: boolean | null
sameSongRestrictionHours?: number | string | null
sameArtistRestrictionHours?: number | string | null
submissionRestrictionScope?: string | null
}
/** 归一化限制时长:非正整数一律视为未配置 */
export function normalizeRestrictionHours(value: unknown): number | null {
if (value === null || value === undefined || value === '') return null
const parsed = Number(value)
if (!Number.isFinite(parsed)) return null
const hours = Math.floor(parsed)
return hours >= 1 ? hours : null
}
/**
* 重复投稿限制口径(投稿与预检共用,两处的判定必须完全一致):
* - 开关关闭:不做任何重复投稿限制,普通用户可重复投稿已排期或已播放的歌曲
* - 开关开启且未配置时长:沿用本学期同一首歌不可重复投稿的规则
* - 开关开启且配置时长:按排期后的冷却窗口判定同一首歌 / 同一歌手
*/
export function resolveSubmissionRestrictionPolicy(
settings: SubmissionRestrictionSettings | null | undefined
): SubmissionRestrictionPolicy {
const sameSongHours = normalizeRestrictionHours(settings?.sameSongRestrictionHours)
const sameArtistHours = normalizeRestrictionHours(settings?.sameArtistRestrictionHours)
const scope: SubmissionRestrictionScope =
settings?.submissionRestrictionScope === 'self' ? 'self' : 'all'
if (!settings?.enableSubmissionRestriction) {
return { mode: 'none', sameSongHours, sameArtistHours, scope }
}
const mode: SubmissionRestrictionMode = sameSongHours || sameArtistHours ? 'window' : 'semester'
return { mode, sameSongHours, sameArtistHours, scope }
}