agePickerOptions.js 3.09 KB
/**
 * 特殊年龄选项在 Picker 内部使用字符串前缀编码,
 * 用来和普通数字年龄值(如 "003")区分。
 */
export const SPECIAL_AGE_VALUE_PREFIX = '__special_age__:'

/**
 * 未选择年龄时,Picker 默认定位到 18 岁。
 */
export const DEFAULT_AGE_PICKER_VALUE = '018'

/**
 * 清洗配置里的特殊年龄选项,去掉空值和多余空格。
 */
const normalizeSpecialOptions = (specialOptions = []) => {
  return specialOptions
    .map(option => String(option ?? '').trim())
    .filter(Boolean)
}

/**
 * 构建 NutUI Picker 需要的年龄选项列。
 * 特殊年龄项会排在最前面,随后才是 0-120 岁的普通年龄。
 */
export function buildAgePickerColumn({ specialOptions = [], minAge = 0, maxAge = 120 } = {}) {
  const normalizedSpecialOptions = normalizeSpecialOptions(specialOptions)
  const numericOptions = Array.from({ length: maxAge - minAge + 1 }, (_, index) => {
    const age = minAge + index
    return {
      text: `${age} 岁`,
      value: String(age).padStart(3, '0')
    }
  })

  const specialAgeOptions = normalizedSpecialOptions.map(option => ({
    text: option,
    value: `${SPECIAL_AGE_VALUE_PREFIX}${option}`
  }))

  return [...specialAgeOptions, ...numericOptions]
}

/**
 * 将表单里的年龄值转换成输入框展示文案。
 * 数字年龄显示为 "X 岁",特殊年龄文本原样显示。
 */
export function formatAgeDisplayValue(value) {
  if (value === null || value === undefined) {
    return ''
  }

  if (typeof value === 'number' && !Number.isNaN(value)) {
    return `${value} 岁`
  }

  const normalizedValue = String(value).trim()
  if (!normalizedValue) {
    return ''
  }

  if (/^\d+$/.test(normalizedValue)) {
    return `${parseInt(normalizedValue, 10)} 岁`
  }

  return normalizedValue
}

/**
 * 将外部年龄值转换成 Picker 内部 value。
 * 普通年龄会变成三位数字字符串,特殊年龄会追加内部前缀。
 */
export function normalizeAgePickerValue(value, specialOptions = [], defaultValue = DEFAULT_AGE_PICKER_VALUE) {
  if (value === null || value === undefined || value === '') {
    return defaultValue
  }

  const normalizedSpecialOptions = normalizeSpecialOptions(specialOptions)

  if (typeof value === 'string') {
    const normalizedValue = value.trim()
    if (normalizedSpecialOptions.includes(normalizedValue)) {
      return `${SPECIAL_AGE_VALUE_PREFIX}${normalizedValue}`
    }

    if (/^\d+$/.test(normalizedValue)) {
      return String(parseInt(normalizedValue, 10)).padStart(3, '0')
    }

    return defaultValue
  }

  if (typeof value === 'number' && !Number.isNaN(value)) {
    return String(value).padStart(3, '0')
  }

  return defaultValue
}

/**
 * 将 Picker 返回值还原成表单实际存储值。
 * 特殊年龄返回原始文本,普通年龄返回数字。
 */
export function parseAgePickerValue(value) {
  if (typeof value !== 'string') {
    return null
  }

  if (value.startsWith(SPECIAL_AGE_VALUE_PREFIX)) {
    return value.slice(SPECIAL_AGE_VALUE_PREFIX.length)
  }

  const parsedValue = parseInt(value, 10)
  return Number.isNaN(parsedValue) ? null : parsedValue
}