Files
szjs/pages/heightSdsCalculator/heightSdsCalculator.js
renjianbo 5d4928cc30 优化
2026-01-06 15:59:20 +08:00

267 lines
6.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const app = getApp();
// 添加正态分布相关的数学函数
const normalDistribution = {
// 误差函数的近似计算
erf(x) {
// 误差函数的系数
const a1 = 0.254829592;
const a2 = -0.284496736;
const a3 = 1.421413741;
const a4 = -1.453152027;
const a5 = 1.061405429;
const p = 0.3275911;
// 取绝对值
const sign = (x >= 0) ? 1 : -1;
x = Math.abs(x);
// 误差函数近似公式的计算
const t = 1.0 / (1.0 + p * x);
const y = 1.0 - (((((a5 * t + a4) * t) + a3) * t + a2) * t + a1) * t * Math.exp(-x * x);
return sign * y;
},
// 计算百分位数
calculatePercentile(sds) {
return (1 + this.erf(sds / Math.sqrt(2))) / 2 * 100;
}
};
Page({
data: {
// 基础数据
age: '',
height: '',
gender: 'male',
// 计算结果
showResult: false,
sdsValue: null,
calculationDetails: null,
growthEvaluation: '',
// 参考数据
standardData: {
male: [
{ age: 1, mean: 76.5, sd: 3.0 },
{ age: 2, mean: 88.5, sd: 3.5 },
{ age: 3, mean: 96.8, sd: 3.8 },
{ age: 4, mean: 103.5, sd: 4.2 },
{ age: 5, mean: 110.0, sd: 4.5 },
{ age: 6, mean: 116.5, sd: 4.8 },
{ age: 7, mean: 124.0, sd: 5.0 },
{ age: 8, mean: 129.5, sd: 5.2 },
{ age: 9, mean: 134.5, sd: 5.5 },
{ age: 10, mean: 138.5, sd: 5.8 },
{ age: 11, mean: 143.0, sd: 6.0 },
{ age: 12, mean: 150.0, sd: 6.5 },
{ age: 13, mean: 156.5, sd: 7.0 },
{ age: 14, mean: 163.0, sd: 7.2 },
{ age: 15, mean: 168.0, sd: 6.2 },
{ age: 16, mean: 171.5, sd: 5.8 },
{ age: 17, mean: 173.5, sd: 5.5 },
{ age: 18, mean: 174.5, sd: 5.2 }
],
female: [
{ age: 1, mean: 75.0, sd: 2.9 },
{ age: 2, mean: 87.2, sd: 3.4 },
{ age: 3, mean: 95.6, sd: 3.7 },
{ age: 4, mean: 102.5, sd: 4.0 },
{ age: 5, mean: 108.5, sd: 4.3 },
{ age: 6, mean: 115.0, sd: 4.6 },
{ age: 7, mean: 122.5, sd: 4.8 },
{ age: 8, mean: 127.5, sd: 5.0 },
{ age: 9, mean: 132.5, sd: 5.2 },
{ age: 10, mean: 137.0, sd: 5.5 },
{ age: 11, mean: 142.0, sd: 5.8 },
{ age: 12, mean: 148.0, sd: 6.0 },
{ age: 13, mean: 154.0, sd: 6.2 },
{ age: 14, mean: 158.5, sd: 5.8 },
{ age: 15, mean: 160.5, sd: 5.5 },
{ age: 16, mean: 161.5, sd: 5.2 },
{ age: 17, mean: 162.0, sd: 5.0 },
{ age: 18, mean: 162.5, sd: 4.8 }
]
}
},
// 输入处理
inputAge(e) {
this.setData({
age: Number(e.detail.value)
});
},
inputHeight(e) {
this.setData({
height: Number(e.detail.value)
});
},
selectGender(e) {
this.setData({
gender: e.currentTarget.dataset.gender
});
},
// 计算SDS
calculate() {
const { age, height, gender } = this.data;
// 输入验证
if (!this.validateInput(age, height)) return;
try {
// 获取标准数据
const standardData = this.getStandardData(age, gender);
if (!standardData) {
throw new Error('未找到对应年龄的标准数据');
}
// 计算SDS
const sds = this.calculateSDS(
Number(height),
Number(standardData.mean),
Number(standardData.sd)
);
// 计算中间值,用于显示
const difference = Number(height) - Number(standardData.mean);
// 获取评价
const evaluation = this.getGrowthEvaluation(sds);
// 显示结果
this.setData({
showResult: true,
sdsValue: Number(sds.toFixed(2)),
calculationDetails: {
height: Number(height).toFixed(1),
mean: Number(standardData.mean).toFixed(1),
sd: Number(standardData.sd).toFixed(1),
formula: `身高SDS = (${height} - ${standardData.mean}) / ${standardData.sd}`,
calculation: ` = (${height} - ${standardData.mean}) / ${standardData.sd}`,
difference: ` = ${difference.toFixed(1)} / ${standardData.sd}`,
result: ` = ${sds.toFixed(2)}`,
interpretation: this.getInterpretation(sds)
},
growthEvaluation: evaluation
});
} catch (error) {
wx.showToast({
title: error.message || '计算失败',
icon: 'none'
});
}
},
// 输入验证
validateInput(age, height) {
if (!age || !height) {
wx.showToast({
title: '请填写完整信息',
icon: 'none'
});
return false;
}
if (age < 1 || age > 18) {
wx.showToast({
title: '年龄必须在1-18岁之间',
icon: 'none'
});
return false;
}
if (height <= 0) {
wx.showToast({
title: '身高必须大于0',
icon: 'none'
});
return false;
}
return true;
},
// 获取标准数据
getStandardData(age, gender) {
return this.data.standardData[gender].find(item => item.age === age);
},
// 计算SDS值
calculateSDS(height, mean, sd) {
// 输入验证
if (typeof height !== 'number' || typeof mean !== 'number' || typeof sd !== 'number') {
throw new Error('输入参数必须为数字');
}
// SDS = (个体身高 - 平均身高) / 标准差
const sds = (height - mean) / sd;
// 验证计算结果
if (isNaN(sds) || !isFinite(sds)) {
throw new Error('计算结果无效');
}
// 计算过程已隐藏
return sds;
},
// 获取生长评价
getGrowthEvaluation(sds) {
// 根据标准更新评价标准
if (sds < -2) {
return '可能存在生长迟缓';
} else if (sds > 2) {
return '可能存在生长过快';
} else {
return '正常范围';
}
},
// 重置表单
reset() {
this.setData({
age: '',
height: '',
gender: 'male',
showResult: false,
sdsValue: null,
calculationDetails: null,
growthEvaluation: ''
});
},
// 返回上一页
onClickLeft() {
wx.navigateBack();
},
// 修改计算百分位数的方法
calculatePercentile(sds) {
const percentile = normalDistribution.calculatePercentile(sds);
return percentile.toFixed(1);
},
// 获取解释文本
getInterpretation(sds) {
const percentile = this.calculatePercentile(sds);
let interpretation = `身高SDS值${sds.toFixed(2)}\n`;
interpretation += `该儿童身高位于同年龄同性别儿童的第${percentile}百分位\n`;
// 根据SDS值添加解释
if (sds === 0) {
interpretation += '身高等于平均值';
} else if (sds > 0) {
interpretation += `高于平均值${(Math.abs(sds) * 100).toFixed(1)}%`;
} else {
interpretation += `低于平均值${(Math.abs(sds) * 100).toFixed(1)}%`;
}
return interpretation;
}
});