/** 身份证解析结果 */ export interface IdCardParsed { /** 性别文本(男/女),解析失败返回空字符串 */ gender: string /** 年龄文本,解析失败返回空字符串 */ age: string /** 生日 YYYY-MM-DD */ birthday: string /** 性别 1=男 2=女 */ sex: number } /** storage 中 userInfo 的类型 */ export interface StorageUserInfo { id: string userId: string parentUserId: string | null scaleDeviceId: string deviceId: string | null deviceType: string dataType: number userType: string | null idCard: string height: number weight: number birthday: string sex: number avatar: string | null phone: string | null thirdId: string realname: string bmi: number createBy: string createTime: string updateBy: string | null updateTime: string | null delFlag: number sn: string | null workNo: string | null remark: string | null relationType: string | null sex_dictText: string connectDeviceInfo: string } /** 校验身份证号格式是否合法 */ export const isIdCardValid = (idCard: string): boolean => { if (idCard.length !== 18) return false // 前 17 位必须为数字 if (!/^\d{17}$/.test(idCard.slice(0, 17))) return false // 第 18 位为数字或 X if (!/^[\dXx]$/.test(idCard[17])) return false return true } /** 解析身份证号,提取性别、年龄、生日 */ export const parseIdCard = (idCard: string): IdCardParsed => { const empty: IdCardParsed = { gender: '', age: '', birthday: '', sex: 0 } if (!isIdCardValid(idCard)) return empty // 第 17 位奇数为男,偶数为女 const sexCode = parseInt(idCard[16], 10) const sex = sexCode % 2 === 1 ? 1 : 2 // 第 7-14 位为生日 YYYYMMDD const year = parseInt(idCard.slice(6, 10), 10) const month = parseInt(idCard.slice(10, 12), 10) const day = parseInt(idCard.slice(12, 14), 10) // 计算年龄 const now = new Date() const birth = new Date(year, month - 1, day) let age = now.getFullYear() - year if (now.getMonth() < month - 1 || (now.getMonth() === month - 1 && now.getDate() < day)) { age-- } return { gender: sex === 1 ? '男' : '女', age: String(age), birthday: `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`, sex, } }