function parseDays(data, key, legacyKey) { let value = parseInt(data[key], 10) if (isNaN(value) && legacyKey) { value = parseInt(data[legacyKey], 10) } if (isNaN(value)) return 0 return value } /** * 解析管理后台耗卡作废/删除允许天数(兼容旧版合并配置项) */ export function parseConsumeAdminPolicy(data = {}) { return { voidDays: parseDays(data, 'adminConsumeVoidEditableDays', 'adminConsumeCancelEditableDays'), deleteDays: parseDays(data, 'adminConsumeDeleteEditableDays', 'adminConsumeCancelEditableDays') } } export function canConsumeAdminOperationByDays(row, days) { if (!row) return false if (days === 0) return true const baseTime = row.hksj ? new Date(row.hksj) : null if (!baseTime || isNaN(baseTime.getTime())) return true const elapsedDays = (Date.now() - baseTime.getTime()) / 86400000 return elapsedDays <= days } /** * 规范化业务配置表单字段(保存前/加载后) */ export function normalizeBusinessConfigFields(form) { const next = { ...form } const intField = (key, defaultValue) => { if (next[key] === '' || next[key] == null) { next[key] = defaultValue return } const n = parseInt(next[key], 10) next[key] = isNaN(n) ? defaultValue : n } intField('consumeEditableDays', 3) intField('consumeAllowCrossMonthEdit', 0) intField('adminConsumeVoidEditableDays', 0) intField('adminConsumeDeleteEditableDays', 0) intField('sleepRemindDays', 30) intField('sleepReturnDays', 60) intField('commissionTierHelpSwitch', 1) intField('memberCustomTagMaxCount', 5) const decimalField = (key, defaultValue) => { if (next[key] === '' || next[key] == null) { next[key] = defaultValue return } const n = parseFloat(next[key]) next[key] = isNaN(n) || n <= 0 ? defaultValue : n } decimalField('largeAmountBillingThreshold', 50000) decimalField('largeAmountConsumeThreshold', 50000) decimalField('largeAmountRefundThreshold', 50000) decimalField('largeAmountTransferThreshold', 50000) next.largeAmountBillingThreshold = String(next.largeAmountBillingThreshold) next.largeAmountConsumeThreshold = String(next.largeAmountConsumeThreshold) next.largeAmountRefundThreshold = String(next.largeAmountRefundThreshold) next.largeAmountTransferThreshold = String(next.largeAmountTransferThreshold) if (next.abnormalConsumeAmountTolerance === '' || next.abnormalConsumeAmountTolerance == null) { next.abnormalConsumeAmountTolerance = 0.01 } else { const tolerance = parseFloat(next.abnormalConsumeAmountTolerance) next.abnormalConsumeAmountTolerance = isNaN(tolerance) || tolerance < 0 ? 0.01 : tolerance } next.abnormalConsumeAmountTolerance = String(next.abnormalConsumeAmountTolerance) if (!next.tkGiftItemIds) { next.tkGiftItemIds = '61' } else { // 只保留一个赠送品项(取第一项) const first = String(next.tkGiftItemIds) .split(/[,,;;]/) .map(s => s.trim()) .filter(Boolean)[0] next.tkGiftItemIds = first || '61' } return next }