Files
bodyWeight/miniprogram/pages/supplementPersonal/supplementPersonal.ts
T

150 lines
3.5 KiB
TypeScript

/** 表单数据模型 */
interface PersonalForm {
/** 姓名 */
name: string
/** 身份证号 */
idCard: string
/** 性别(由身份证解析,只读) */
gender: string
/** 年龄(由身份证解析,只读) */
age: string
/** 身高(cm) */
height: string
}
/** 身份证解析结果 */
interface IdCardParsed {
/** 性别,空字符串表示解析失败 */
gender: string
/** 年龄,空字符串表示解析失败 */
age: string
}
/**
* 完善个人信息页
* 收集姓名、身份证号、身高,并根据身份证自动解析性别与年龄
* 提交后进入首页(tabBar)
*/
Page({
data: {
// 表单数据
form: {
name: '', // 姓名
idCard: '', // 身份证号
gender: '', // 性别(由身份证解析,只读)
age: '', // 年龄(由身份证解析,只读)
height: '' // 身高(cm)
} as PersonalForm
},
/**
* 姓名输入
*/
onNameInput(e: WechatMiniprogram.Input) {
this.setData({
'form.name': e.detail.value
});
},
/**
* 身份证号输入
* 长度满 18 位时自动解析性别与年龄,否则清空
*/
onIdCardInput(e: WechatMiniprogram.Input) {
const idCard = (e.detail.value || '').trim().toUpperCase();
const parsed = this.parseIdCard(idCard);
this.setData({
'form.idCard': idCard,
'form.gender': parsed.gender,
'form.age': parsed.age
});
},
/**
* 身高输入
*/
onHeightInput(e: WechatMiniprogram.Input) {
this.setData({
'form.height': e.detail.value
});
},
/**
* 解析身份证号,返回性别与年龄
* @param idCard 18 位身份证号
*/
parseIdCard(idCard: string): IdCardParsed {
// 简单校验:18 位且前 17 位为数字
const reg = /^\d{17}[\dX]$/;
if (!reg.test(idCard)) {
return { gender: '', age: '' };
}
// 性别:第 17 位奇数为男,偶数为女
const genderCode = parseInt(idCard.charAt(16), 10);
const gender = genderCode % 2 === 1 ? '男' : '女';
// 出生日期:第 7-14 位
const year = parseInt(idCard.substr(6, 4), 10);
const month = parseInt(idCard.substr(10, 2), 10);
const day = parseInt(idCard.substr(12, 2), 10);
// 基本合法性校验
if (
!year || !month || !day ||
month < 1 || month > 12 ||
day < 1 || day > 31
) {
return { gender: '', age: '' };
}
// 计算周岁(看是否过了今年生日)
const now = new Date();
let age = now.getFullYear() - year;
const nowMonth = now.getMonth() + 1;
const nowDay = now.getDate();
if (nowMonth < month || (nowMonth === month && nowDay < day)) {
age -= 1;
}
if (age < 0 || age > 150) {
return { gender: '', age: '' };
}
return { gender, age: String(age) };
},
/**
* 提交表单
* 必填:姓名、身份证号(18 位且解析成功)、身高
* 未通过时 toast 提示,通过后进入首页(tabBar)
*/
onSubmit() {
const { name, idCard, gender, age, height } = this.data.form;
const heightNum = parseFloat(height);
if (!name.trim()) {
wx.showToast({ title: '请填写姓名', icon: 'none' });
return;
}
if (idCard.length !== 18) {
wx.showToast({ title: '请填写正确的身份证号', icon: 'none' });
return;
}
if (!gender || !age) {
wx.showToast({ title: '身份证号有误,请检查', icon: 'none' });
return;
}
if (!height || isNaN(heightNum) || heightNum <= 0) {
wx.showToast({ title: '请填写身高', icon: 'none' });
return;
}
// TODO: 此处后续接入用户信息保存接口
wx.switchTab({
url: '/pages/home/home'
});
}
});