GHD预测计算

This commit is contained in:
2025-03-14 22:37:20 +08:00
parent 04263f304e
commit e7307e0bd0
7 changed files with 525 additions and 7 deletions

View File

@@ -0,0 +1,243 @@
const app = getApp();
Page({
data: {
// 基础数据
ba: '', // 骨龄
ca: '', // 实际年龄
igf1: '', // IGF-1值
igfbp3: '', // IGFBP-3值
// 计算结果
showResult: false,
probability: null,
calculationDetails: null,
// 参考范围
referenceRanges: {
igf1: {
male: [
{ ageRange: '0-1', min: 55, max: 327 },
{ ageRange: '1-3', min: 51, max: 303 },
{ ageRange: '3-5', min: 49, max: 289 },
{ ageRange: '5-7', min: 52, max: 297 },
{ ageRange: '7-9', min: 57, max: 316 },
{ ageRange: '9-11', min: 88, max: 474 },
{ ageRange: '11-13', min: 110, max: 565 },
{ ageRange: '13-15', min: 202, max: 957 },
{ ageRange: '15-17', min: 193, max: 731 }
],
female: [
{ ageRange: '0-1', min: 55, max: 327 },
{ ageRange: '1-3', min: 51, max: 303 },
{ ageRange: '3-5', min: 49, max: 289 },
{ ageRange: '5-7', min: 52, max: 297 },
{ ageRange: '7-9', min: 57, max: 316 },
{ ageRange: '9-11', min: 88, max: 474 },
{ ageRange: '11-13', min: 183, max: 850 },
{ ageRange: '13-15', min: 261, max: 1096 },
{ ageRange: '15-17', min: 238, max: 996 }
]
},
igfbp3: {
male: [
{ ageRange: '0-1', min: 0.7, max: 3.6 },
{ ageRange: '1-3', min: 0.8, max: 3.9 },
{ ageRange: '3-5', min: 0.9, max: 4.3 },
{ ageRange: '5-7', min: 1.0, max: 4.7 },
{ ageRange: '7-9', min: 1.1, max: 5.2 },
{ ageRange: '9-11', min: 1.3, max: 5.6 },
{ ageRange: '11-13', min: 1.4, max: 6.1 },
{ ageRange: '13-15', min: 1.6, max: 6.8 },
{ ageRange: '15-17', min: 1.8, max: 7.1 }
],
female: [
{ ageRange: '0-1', min: 0.7, max: 3.6 },
{ ageRange: '1-3', min: 0.8, max: 3.9 },
{ ageRange: '3-5', min: 0.9, max: 4.3 },
{ ageRange: '5-7', min: 1.0, max: 4.7 },
{ ageRange: '7-9', min: 1.1, max: 5.2 },
{ ageRange: '9-11', min: 1.3, max: 5.6 },
{ ageRange: '11-13', min: 1.5, max: 6.3 },
{ ageRange: '13-15', min: 1.7, max: 7.3 },
{ ageRange: '15-17', min: 1.9, max: 7.9 }
]
}
}
},
// 输入处理
inputBA(e) {
// 只允许输入数字和小数点
const value = e.detail.value.replace(/[^\d.]/g, '');
// 确保只有一个小数点
const formattedValue = value.replace(/\.+/g, '.');
this.setData({ ba: formattedValue });
},
inputCA(e) {
const value = e.detail.value.replace(/[^\d.]/g, '');
const formattedValue = value.replace(/\.+/g, '.');
this.setData({ ca: formattedValue });
},
inputIGF1(e) {
const value = e.detail.value.replace(/[^\d.]/g, '');
const formattedValue = value.replace(/\.+/g, '.');
this.setData({ igf1: formattedValue });
},
inputIGFBP3(e) {
const value = e.detail.value.replace(/[^\d.]/g, '');
const formattedValue = value.replace(/\.+/g, '.');
this.setData({ igfbp3: formattedValue });
},
// 计算GHD概率
calculate() {
const { ba, ca, igf1, igfbp3 } = this.data;
// 输入验证
if (!this.validateInput()) return;
try {
// 将字符串转换为数字
const baNum = parseFloat(ba);
const caNum = parseFloat(ca);
const igf1Num = parseFloat(igf1);
const igfbp3Num = parseFloat(igfbp3);
// 计算 BA-CA
const baCaDiff = baNum - caNum;
// 计算 Y = LN(P/1-P)
const y = this.calculateY(baCaDiff, igf1Num, igfbp3Num);
// 计算概率 P
const p = this.calculateProbability(y);
// 计算各因素的贡献
const contributions = this.calculateContributions(baCaDiff, igf1Num, igfbp3Num);
// 显示结果
this.setData({
showResult: true,
probability: p,
calculationDetails: {
steps: [
`步骤1设置方程右边为 Y`,
`Y = 3.726 - 0.876×(BA-CA) - 0.058×(IGF-1) + 0.229×(IGFBP-3)`,
`Y = 3.726 - 0.876×(${baNum.toFixed(2)} - ${caNum.toFixed(2)}) - 0.058×${igf1Num.toFixed(2)} + 0.229×${igfbp3Num.toFixed(2)}`,
`Y = 3.726 - 0.876×(${baCaDiff.toFixed(2)}) - 0.058×${igf1Num.toFixed(2)} + 0.229×${igfbp3Num.toFixed(2)}`,
`Y = 3.726 - ${(0.876 * baCaDiff).toFixed(4)} - ${(0.058 * igf1Num).toFixed(4)} + ${(0.229 * igfbp3Num).toFixed(4)}`,
`Y = ${y.toFixed(4)}`,
``,
`步骤2解指数方程`,
`P/(1-P) = e^Y`,
`P/(1-P) = e^${y.toFixed(4)}`,
`P/(1-P) = ${Math.exp(y).toFixed(4)}`,
``,
`步骤3求概率 P`,
`P = e^Y / (1 + e^Y)`,
`P = ${p.toFixed(4)}`,
``,
`GHD预测概率${(p * 100).toFixed(2)}%`
].join('\n'),
interpretation: this.getInterpretation(p)
}
});
} catch (error) {
wx.showToast({
title: error.message || '计算失败',
icon: 'none'
});
}
},
// 输入验证
validateInput() {
const { ba, ca, igf1, igfbp3 } = this.data;
if (!ba || !ca || !igf1 || !igfbp3) {
wx.showToast({
title: '请填写完整信息',
icon: 'none'
});
return false;
}
// 验证输入是否为有效数字
const baNum = parseFloat(ba);
const caNum = parseFloat(ca);
const igf1Num = parseFloat(igf1);
const igfbp3Num = parseFloat(igfbp3);
if (isNaN(baNum) || isNaN(caNum) || isNaN(igf1Num) || isNaN(igfbp3Num)) {
wx.showToast({
title: '请输入有效数字',
icon: 'none'
});
return false;
}
// 验证数值范围
if (baNum <= 0 || caNum <= 0) {
wx.showToast({
title: '年龄必须大于0',
icon: 'none'
});
return false;
}
return true;
},
// 计算Y值
calculateY(baCaDiff, igf1, igfbp3) {
return 3.726 - 0.876 * baCaDiff - 0.058 * igf1 + 0.229 * igfbp3;
},
// 计算概率
calculateProbability(y) {
const expY = Math.exp(y);
return expY / (1 + expY);
},
// 计算各因素的贡献
calculateContributions(baCaDiff, igf1, igfbp3) {
// Implementation of calculateContributions method
},
// 获取解释文本
getInterpretation(p) {
const percentage = (p * 100).toFixed(2);
let interpretation = `预测结果显示该患者患有GHD的概率为${percentage}%\n\n`;
if (p >= 0.8) {
interpretation += '预测结果提示GHD可能性较大建议进一步进行相关检查。';
} else if (p >= 0.5) {
interpretation += '预测结果提示存在GHD可能建议进行相关检查。';
} else {
interpretation += '预测结果提示GHD可能性较小但仍需结合临床表现进行综合判断。';
}
return interpretation;
},
// 重置表单
reset() {
this.setData({
ba: '',
ca: '',
igf1: '',
igfbp3: '',
showResult: false,
probability: null,
calculationDetails: null
});
},
// 返回上一页
onClickLeft() {
wx.navigateBack();
}
});

View File

@@ -0,0 +1,11 @@
{
"usingComponents": {
"van-nav-bar": "/miniprogram/miniprogram_npm/@vant/weapp/nav-bar/index",
"van-overlay": "/miniprogram/miniprogram_npm/@vant/weapp/overlay/index",
"van-field": "/miniprogram/miniprogram_npm/@vant/weapp/field/index",
"van-button": "/miniprogram/miniprogram_npm/@vant/weapp/button/index",
"van-toast": "/miniprogram/miniprogram_npm/@vant/weapp/toast/index"
},
"navigationBarTitleText": "GHD预测计算",
"navigationStyle": "custom"
}

View File

@@ -0,0 +1,83 @@
<van-nav-bar
title="GHD预测计算"
left-text=""
left-arrow
bind:click-left="onClickLeft"
class="nav-bar custom-nav"
/>
<view class="container">
<!-- 输入表单 -->
<view class="form-container">
<view class="form-group">
<text class="form-label">骨龄(岁)</text>
<input
class="form-input"
type="text"
placeholder="请输入骨龄,精确到小数点后两位"
bindinput="inputBA"
value="{{ba}}"
/>
</view>
<view class="form-group">
<text class="form-label">实际年龄(岁)</text>
<input
class="form-input"
type="text"
placeholder="请输入实际年龄,精确到小数点后两位"
bindinput="inputCA"
value="{{ca}}"
/>
</view>
<view class="form-group">
<text class="form-label">IGF-1值</text>
<input
class="form-input"
type="text"
placeholder="请输入IGF-1检验值精确到小数点后两位"
bindinput="inputIGF1"
value="{{igf1}}"
/>
</view>
<view class="form-group">
<text class="form-label">IGFBP-3值</text>
<input
class="form-input"
type="text"
placeholder="请输入IGFBP-3检验值精确到小数点后两位"
bindinput="inputIGFBP3"
value="{{igfbp3}}"
/>
</view>
<view class="button-group">
<view class="button" bindtap="calculate">计算</view>
<view class="button secondary" bindtap="reset">重置</view>
</view>
</view>
<!-- 计算结果 -->
<view class="result-container" wx:if="{{showResult}}">
<text class="result-title">计算结果</text>
<!-- 计算过程 -->
<view class="calculation-process">
<text class="process-title">计算过程:</text>
<view class="process-steps">
<text>{{calculationDetails.steps}}</text>
</view>
</view>
<!-- 结果解释 -->
<view class="result-interpretation">
<text class="interpretation-text">{{calculationDetails.interpretation}}</text>
</view>
<view class="tips">
本计算结果仅供参考具体诊断请咨询专业医生。预测模型基于二元Logistic回归分析。
</view>
</view>
</view>

View File

@@ -0,0 +1,175 @@
/* pages/ghdCalculator/ghdCalculator.wxss *//* 页面容器 */
.container {
padding: 40rpx;
background: #f5f5f5;
min-height: 100vh;
}
/* 输入表单 */
.form-container {
width: 100%;
background: #fff;
border-radius: 24rpx;
padding: 0rpx;
background: #f5f5f5;
box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.05);
}
.form-group {
margin-bottom: 40rpx;
}
.form-label {
font-size: 28rpx;
color: #333;
margin-bottom: 16rpx;
display: inline-block;
font-weight: bold;
}
.form-input {
width: 90%;
height: 80rpx;
background: #ffffff;
border-radius: 16rpx;
padding: 0 24rpx;
font-size: 28rpx;
}
/* 性别选择 */
.gender-group {
display: flex;
margin: 20rpx 0;
}
.gender-item {
flex: 1;
text-align: center;
padding: 20rpx;
border: 2rpx solid #eee;
border-radius: 16rpx;
margin: 0 10rpx;
}
.gender-item.active {
border-color: #27C2A7;
background: #e6f7f4;
}
/* 按钮样式 */
.button-group {
margin-top: 40rpx;
}
.button {
height: 80rpx;
line-height: 80rpx;
text-align: center;
border-radius: 16rpx;
font-size: 28rpx;
color: #fff;
background: #27C2A7;
}
.button.secondary {
background: #fff;
border: 2rpx solid #27C2A7;
color: #27C2A7;
margin-top: 20rpx;
}
/* 结果展示 */
.result-container {
margin-top: 40rpx;
background: #fff;
border-radius: 24rpx;
padding: 40rpx;
}
.result-title {
font-size: 32rpx;
font-weight: bold;
color: #333;
text-align: center;
margin-bottom: 40rpx;
}
.result-item {
display: flex;
justify-content: space-between;
padding: 20rpx 0;
border-bottom: 2rpx solid #eee;
}
.result-label {
font-size: 28rpx;
color: #666;
}
.result-value {
font-size: 28rpx;
color: #333;
font-weight: bold;
}
.result-value.green {
color: #27C2A7;
}
.result-value.red {
color: #ff4c00;
}
/* 图表容器 */
.chart-container {
margin-top: 40rpx;
height: 400rpx;
}
/* 提示信息 */
.tips {
font-size: 24rpx;
color: #999;
margin-top: 20rpx;
line-height: 1.6;
}
.calculation-process {
margin: 20rpx 0;
padding: 20rpx;
background-color: #f8f8f8;
border-radius: 10rpx;
}
.process-title {
font-size: 28rpx;
color: #333;
margin-bottom: 10rpx;
}
.process-steps {
display: flex;
flex-direction: column;
font-family: monospace;
font-size: 28rpx;
color: #666;
}
.process-steps text {
margin: 5rpx 0;
white-space: pre;
}
.result-interpretation {
margin: 20rpx 0;
padding: 20rpx;
background-color: #fff;
border-radius: 10rpx;
border: 1px solid #eee;
}
.interpretation-text {
font-size: 28rpx;
color: #333;
white-space: pre-line;
}

View File

@@ -61,10 +61,15 @@ Page({
// 性发育图表
go_peizhen() {
if (this.checkLoginAndNavigate()) {
wx.showToast({
title: '功能正在开发中',
icon: 'none'
// if (this.checkLoginAndNavigate()) {
// wx.showToast({
// title: '功能正在开发中',
// icon: 'none'
// })
// }
if (this.checkLoginAndNavigate()) {
wx.navigateTo({
url: '/pages/ghdCalculator/ghdCalculator'
})
}
},

View File

@@ -16,12 +16,12 @@
<view class="name" style="margin-top: 30rpx;"><text>{{"生长发育相关参考计算和图表"}}</text></view>
<view class="main" style="margin-top: 32rpx;">
<!-- <view class="main-item" bindtap="go_peizhen">
<view class="main-item" bindtap="go_peizhen">
<image style="height: 86rpx;width: 86rpx;margin-left: 64rpx;margin-top: 40rpx;" src="../image/home/生长曲线图@2x.png" mode="aspectFit"></image>
<view class="title-view">
<text class="main-title">生长曲线图</text>
<text class="main-title">GHD预测计算</text>
</view>
</view> -->
</view>
<view class="main-item" style="background-color: #EDFFFC;" bindtap="go_cpp">
<image style="height: 86rpx;width: 86rpx;margin-left: 64rpx;margin-top: 40rpx;" src="../image/home/计算收藏@2x.png" mode="aspectFit"></image>
<view class="title-view">