export { protocolStatusLabel, protocolStatusDisplayLabel, protocolStatusTagType, payStatusLabel, payStatusTagType, payModeLabel, payModeTagType } from './status-tag-registry' export { loadTransferTypeDict, getTransferTypeOptions, TRANSFER_TYPE_DICT, resolveTransferTypeLabel as transferTypeLabel, resolveTransferTypeTagType as transferTypeTagType } from './transfer-type-dict' export function formatPaymentDueDate(d: unknown) { const s = String(d || '') if (!s) return '-' if (s.length === 8) return `${s.slice(0, 4)}-${s.slice(4, 6)}-${s.slice(6, 8)}` return s } export const PAYMENT_DUE_WARN_DAYS = 15 function parsePaymentDueYmd(ymd: unknown): Date | null { const raw = String(ymd || '').replace(/\D/g, '') if (raw.length !== 8) return null const y = Number(raw.slice(0, 4)) const m = Number(raw.slice(4, 6)) - 1 const d = Number(raw.slice(6, 8)) const dt = new Date(y, m, d) if (dt.getFullYear() !== y || dt.getMonth() !== m || dt.getDate() !== d) return null return dt } function startOfLocalDay(d: Date) { return new Date(d.getFullYear(), d.getMonth(), d.getDate()) } export function isPaymentDueWithinWarnWindow( installmentDueDate: unknown, warnDays = PAYMENT_DUE_WARN_DAYS ) { const due = parsePaymentDueYmd(installmentDueDate) if (!due) return false const today = startOfLocalDay(new Date()) const limit = new Date(today) limit.setDate(limit.getDate() + warnDays) return due.getTime() <= limit.getTime() } export function formatPaymentAmount(v: unknown) { if (v == null || v === '') return '-' const n = Number(v) if (Number.isNaN(n)) return String(v) return '¥' + n.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) }