feat: 添加 BMI 计算和训练计划排课功能
- 新增 BMI 计算工具,支持用户输入体重和身高计算 BMI 值,并根据结果提供分类和建议 - 在训练计划中集成排课功能,允许用户选择和安排训练动作 - 更新个人信息页面,添加出生日期字段,支持用户完善个人资料 - 优化训练计划卡片样式,提升用户体验 - 更新相关依赖,确保项目兼容性和功能完整性
This commit is contained in:
154
utils/bmi.ts
Normal file
154
utils/bmi.ts
Normal file
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* BMI 计算和分类工具函数
|
||||
*/
|
||||
|
||||
export interface BMIResult {
|
||||
value: number;
|
||||
category: BMICategory;
|
||||
color: string;
|
||||
backgroundColor: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export interface BMICategory {
|
||||
name: string;
|
||||
range: string;
|
||||
description: string;
|
||||
advice: string;
|
||||
encouragement: string;
|
||||
}
|
||||
|
||||
// BMI 分类标准(基于中国成人标准)
|
||||
export const BMI_CATEGORIES: BMICategory[] = [
|
||||
{
|
||||
name: '偏瘦',
|
||||
range: '< 18.5',
|
||||
description: '体重偏轻',
|
||||
advice: '建议适当增加营养摄入,进行力量训练增加肌肉量',
|
||||
encouragement: '每一份营养都是对身体的投资,坚持下去你会更强壮!💪'
|
||||
},
|
||||
{
|
||||
name: '正常',
|
||||
range: '18.5 - 23.9',
|
||||
description: '体重正常',
|
||||
advice: '保持良好的饮食和运动习惯,继续维持健康体重',
|
||||
encouragement: '太棒了!你的身体状态很健康,继续保持这份活力!✨'
|
||||
},
|
||||
{
|
||||
name: '偏胖',
|
||||
range: '24.0 - 27.9',
|
||||
description: '体重偏重',
|
||||
advice: '建议控制饮食,增加有氧运动,逐步减重',
|
||||
encouragement: '改变从今天开始,每一次运动都让你更接近理想的自己!🌟'
|
||||
},
|
||||
{
|
||||
name: '肥胖',
|
||||
range: '≥ 28.0',
|
||||
description: '肥胖',
|
||||
advice: '建议咨询专业医生,制定科学的减重计划',
|
||||
encouragement: '健康之路虽有挑战,但你有勇气迈出第一步就已经很了不起!🚀'
|
||||
}
|
||||
];
|
||||
|
||||
// BMI 颜色方案(越健康颜色越绿)
|
||||
const BMI_COLORS = {
|
||||
underweight: {
|
||||
color: '#8B7355', // 棕色文字
|
||||
backgroundColor: '#FFF4E6', // 浅橙色背景
|
||||
},
|
||||
normal: {
|
||||
color: '#2D5016', // 深绿色文字
|
||||
backgroundColor: '#E8F5E8', // 浅绿色背景
|
||||
},
|
||||
overweight: {
|
||||
color: '#B45309', // 橙色文字
|
||||
backgroundColor: '#FEF3C7', // 浅黄色背景
|
||||
},
|
||||
obese: {
|
||||
color: '#B91C1C', // 红色文字
|
||||
backgroundColor: '#FEE2E2', // 浅红色背景
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 计算 BMI 值
|
||||
* @param weight 体重(kg)
|
||||
* @param height 身高(cm)
|
||||
* @returns BMI 值,保留一位小数
|
||||
*/
|
||||
export function calculateBMI(weight: number, height: number): number {
|
||||
if (weight <= 0 || height <= 0) {
|
||||
throw new Error('体重和身高必须大于0');
|
||||
}
|
||||
|
||||
// 身高转换为米
|
||||
const heightInMeters = height / 100;
|
||||
const bmi = weight / (heightInMeters * heightInMeters);
|
||||
|
||||
return Math.round(bmi * 10) / 10;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 BMI 值获取分类
|
||||
* @param bmi BMI 值
|
||||
* @returns BMI 分类信息
|
||||
*/
|
||||
export function getBMICategory(bmi: number): BMICategory {
|
||||
if (bmi < 18.5) {
|
||||
return BMI_CATEGORIES[0]; // 偏瘦
|
||||
} else if (bmi < 24.0) {
|
||||
return BMI_CATEGORIES[1]; // 正常
|
||||
} else if (bmi < 28.0) {
|
||||
return BMI_CATEGORIES[2]; // 偏胖
|
||||
} else {
|
||||
return BMI_CATEGORIES[3]; // 肥胖
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 BMI 值获取颜色
|
||||
* @param bmi BMI 值
|
||||
* @returns 颜色配置
|
||||
*/
|
||||
export function getBMIColors(bmi: number): { color: string; backgroundColor: string } {
|
||||
if (bmi < 18.5) {
|
||||
return BMI_COLORS.underweight;
|
||||
} else if (bmi < 24.0) {
|
||||
return BMI_COLORS.normal;
|
||||
} else if (bmi < 28.0) {
|
||||
return BMI_COLORS.overweight;
|
||||
} else {
|
||||
return BMI_COLORS.obese;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取完整的 BMI 结果
|
||||
* @param weight 体重(kg)
|
||||
* @param height 身高(cm)
|
||||
* @returns 完整的 BMI 分析结果
|
||||
*/
|
||||
export function getBMIResult(weight: number, height: number): BMIResult {
|
||||
const bmi = calculateBMI(weight, height);
|
||||
const category = getBMICategory(bmi);
|
||||
const colors = getBMIColors(bmi);
|
||||
|
||||
return {
|
||||
value: bmi,
|
||||
category,
|
||||
color: colors.color,
|
||||
backgroundColor: colors.backgroundColor,
|
||||
description: category.description
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否有足够的数据计算 BMI
|
||||
* @param weight 体重
|
||||
* @param height 身高
|
||||
* @returns 是否可以计算 BMI
|
||||
*/
|
||||
export function canCalculateBMI(weight?: number, height?: number): boolean {
|
||||
return typeof weight === 'number' && weight > 0 &&
|
||||
typeof height === 'number' && height > 0;
|
||||
}
|
||||
Reference in New Issue
Block a user