export const WORK_ORDER_ACCEPTANCE_MODE = { STANDARD: 'standard', FRIEND_GIFT: 'friend_gift', } as const export type WorkOrderAcceptanceMode = | (typeof WORK_ORDER_ACCEPTANCE_MODE)[keyof typeof WORK_ORDER_ACCEPTANCE_MODE] | (string & {}) export const DEFAULT_GIFT_COOLDOWN_HOURS = 72 export const MAX_GIFT_COOLDOWN_HOURS = 24 * 30 export const MAX_GIFT_COOLDOWN_MINUTES = MAX_GIFT_COOLDOWN_HOURS * 60 /** 好友赠送模式的落库阶段;gift_ready 由 gift_available_at 到点后实时计算,不落库。 */ export const WORK_ORDER_GIFT_PHASE = { MATERIAL_REQUIRED: 'material_required', MATERIAL_SUBMITTED: 'material_submitted', FRIEND_COUNTDOWN: 'friend_countdown', GIFT_READY: 'gift_ready', } as const export type WorkOrderGiftPhase = | (typeof WORK_ORDER_GIFT_PHASE)[keyof typeof WORK_ORDER_GIFT_PHASE] | (string & {}) export function normalizeWorkOrderAcceptanceMode(value: unknown): WorkOrderAcceptanceMode { const mode = String(value || '').trim() return mode === WORK_ORDER_ACCEPTANCE_MODE.FRIEND_GIFT ? WORK_ORDER_ACCEPTANCE_MODE.FRIEND_GIFT : WORK_ORDER_ACCEPTANCE_MODE.STANDARD } export function isFriendGiftAcceptanceMode(value: unknown): boolean { return normalizeWorkOrderAcceptanceMode(value) === WORK_ORDER_ACCEPTANCE_MODE.FRIEND_GIFT } /** 冷却小时数收敛到 [0, 30 天],默认 3 天。0 用于选择按分钟配置。 */ export function normalizeWorkOrderGiftCooldownHours(value: unknown): number { const hours = Number(value) if (!Number.isFinite(hours) || hours < 0) return DEFAULT_GIFT_COOLDOWN_HOURS return Math.min(MAX_GIFT_COOLDOWN_HOURS, Math.round(hours)) } /** 按分钟配置时的总分钟数,最大 30 天。 */ export function normalizeWorkOrderGiftCooldownMinutes(value: unknown): number { const minutes = Number(value) if (!Number.isFinite(minutes)) return 0 return Math.min(MAX_GIFT_COOLDOWN_MINUTES, Math.max(0, Math.round(minutes))) } export type WorkOrderGiftSource = { acceptance_mode?: string | null gift_phase?: string | null gift_available_at?: string | null friend_added_at?: string | null } export function isWorkOrderGiftAvailable(source: WorkOrderGiftSource): boolean { if (!isFriendGiftAcceptanceMode(source.acceptance_mode)) return false const availableAt = Date.parse(String(source.gift_available_at || '')) return Number.isFinite(availableAt) && availableAt <= Date.now() } /** 好友赠送单已由后台确认加好友后,取消/脱离打手不再退还押金,押金只能经验收结算。 */ export function isWorkOrderGiftDepositForfeitable(source: WorkOrderGiftSource): boolean { return isFriendGiftAcceptanceMode(source.acceptance_mode) && Boolean(source.friend_added_at) } /** 返回当前赠送阶段;冷却到点后返回实时计算的 gift_ready。 */ export function resolveWorkOrderGiftPhase(source: WorkOrderGiftSource): string { if (!isFriendGiftAcceptanceMode(source.acceptance_mode)) return '' const phase = String(source.gift_phase || '').trim() if (phase === WORK_ORDER_GIFT_PHASE.FRIEND_COUNTDOWN && isWorkOrderGiftAvailable(source)) { return WORK_ORDER_GIFT_PHASE.GIFT_READY } return phase }