// components/im-input/utils.ts import type { FormatType } from '../../types/components/input' import { FORMAT_CONFIGS } from './constants' import { validator } from '../../index' /** * 格式化手机号 */ export const formatPhone = (value: string): string => { if (!value) return '' const config = FORMAT_CONFIGS.phone let result = '' let valueIndex = 0 for (let i = 0; i < config.pattern.length; i++) { if (config.pattern[i] === config.placeholder && valueIndex < value.length) { result += value[valueIndex] valueIndex++ } else { result += config.pattern[i] } } return result } /** * 格式化银行卡号 */ export const formatBankCard = (value: string): string => { if (!value) return '' const config = FORMAT_CONFIGS.bankCard let result = '' let valueIndex = 0 for (let i = 0; i < config.pattern.length; i++) { if (config.pattern[i] === config.placeholder && valueIndex < value.length) { result += value[valueIndex] valueIndex++ } else { result += config.pattern[i] } } return result } /** * 格式化身份证号 */ export const formatIdCard = (value: string): string => { if (!value) return '' const config = FORMAT_CONFIGS.idCard if (value.length <= 6) { return value } if (value.length <= 14) { return value.substring(0, 6) + '*'.repeat(value.length - 6) } return value.substring(0, 6) + '*'.repeat(8) + value.substring(value.length - 4) } /** * 格式化金额 */ export const formatAmount = (value: string | number): string => { if (!value && value !== 0) return '' const strValue = String(value).replace(/,/g, '') if (!strValue) return '' // 处理负数 const isNegative = strValue.startsWith('-') const absValue = isNegative ? strValue.slice(1) : strValue // 分割整数和小数部分 const [integer, decimal = ''] = absValue.split('.') // 格式化整数部分 const formattedInteger = integer.replace(/\B(?=(\d{3})+(?!\d))/g, ',') // 组合结果 let result = formattedInteger if (decimal) { result += '.' + decimal } if (isNegative) { result = '-' + result } return result } /** * 解析格式化值 */ export const parseFormattedValue = (value: string, formatType: FormatType): string => { if (!value) return '' switch (formatType) { case 'phone': return value.replace(/\s/g, '') case 'bankCard': return value.replace(/\s/g, '').replace(/\*/g, '') case 'idCard': return value.replace(/\*/g, '') case 'amount': return value.replace(/,/g, '') default: return value } } /** * 获取格式化函数 */ export const getFormatter = (formatType: FormatType) => { switch (formatType) { case 'phone': return formatPhone case 'bankCard': return formatBankCard case 'idCard': return formatIdCard case 'amount': return formatAmount default: return (value: string) => value } } /** * 验证输入值 */ export const validateInput = ( value: string, type: string, maxlength?: number ): { valid: boolean; message?: string } => { // 验证最大长度 if (maxlength && value.length > maxlength) { return { valid: false, message: `长度不能超过 ${maxlength} 个字符` } } // 根据类型验证 switch (type) { case 'email': if (value && !validator.isEmail(value)) { return { valid: false, message: '请输入有效的邮箱地址' } } break case 'tel': case 'phone': if (value && !validator.isMobilePhone(value)) { return { valid: false, message: '请输入有效的手机号码' } } break case 'url': if (value && !validator.isURL(value)) { return { valid: false, message: '请输入有效的URL地址' } } break case 'idcard': if (value && !validator.isChineseIDCard(value)) { return { valid: false, message: '请输入有效的身份证号码' } } break case 'number': if (value && !validator.isNumber(value)) { return { valid: false, message: '请输入有效的数字' } } break case 'digit': if (value && !validator.isInteger(value)) { return { valid: false, message: '请输入整数' } } break } return { valid: true } } /** * 防抖函数 */ export const debounce = any>( func: T, wait: number ): ((...args: Parameters) => void) => { let timeout: ReturnType | null = null return (...args: Parameters) => { if (timeout) clearTimeout(timeout) timeout = setTimeout(() => func(...args), wait) } } /** * 节流函数 */ export const throttle = any>( func: T, limit: number ): ((...args: Parameters) => void) => { let inThrottle: boolean = false return (...args: Parameters) => { if (!inThrottle) { func(...args) inThrottle = true setTimeout(() => (inThrottle = false), limit) } } }