KMP 实现鸿蒙跨端:Kotlin 健身房管理系统 - 会员健身计划生成器
本文介绍了一个基于Kotlin Multiplatform的健身房管理系统,重点实现了会员健身计划生成器功能。该系统能够根据会员的体重、身高、年龄和健身等级,自动生成个性化的训练计划、营养建议和健身指导。核心功能包括会员信息管理、BMI体质评估、训练计划生成(分初级/中级/高级)、心率区间计算、热量管理和营养建议。系统采用KMP技术,一份Kotlin代码可跨平台使用,通过严格的数据验证确保计算准确

目录
概述
本文档介绍如何在 Kotlin Multiplatform (KMP) 鸿蒙跨端开发中实现一个完整的健身房管理系统,特别是会员健身计划生成器。健身房管理涉及会员信息管理、身体评估、个性化训练计划生成、热量管理和营养建议等多个方面。这个案例展示了如何使用 Kotlin 的数据处理、算法设计和字符串生成来创建一个功能丰富的健身管理工具。
会员健身计划生成器是健身房管理系统的核心功能,它能够根据会员的基本信息(体重、身高、年龄)和健身等级(初级、中级、高级),自动生成个性化的训练计划、营养建议和健身指导。通过 KMP,这个工具可以无缝编译到 JavaScript,在 OpenHarmony 应用中运行,为健身房管理者和会员提供专业的健身指导。
工具的特点
- 会员管理:完整的会员信息管理,包括会员ID、入会日期、到期日期等
- 身体评估:综合评估会员的体质状况,计算BMI和目标体重
- 个性化计划:根据健身等级生成不同的训练计划
- 热量管理:精确计算每日热量需求和训练消耗
- 营养指导:提供科学的营养建议(蛋白质、碳水化合物、脂肪)
- 跨端兼容:一份 Kotlin 代码可同时服务多个平台
工具功能
1. 会员信息管理
系统为每个会员生成唯一的会员ID,格式为 GYM 加上随机数字。同时记录会员的入会日期和到期日期,帮助管理者追踪会员的有效期。会员信息包括:
- 姓名:会员的真实姓名
- 会员ID:唯一标识,用于系统管理
- 入会日期:会员加入健身房的日期
- 到期日期:会员卡的到期日期
- 等级:会员的健身等级(初级、中级、高级)
2. 身体评估系统
系统通过计算 BMI(身体质量指数)来评估会员的体质状况,并根据体质状况确定目标体重。BMI 的计算公式为:BMI = 体重(kg) / 身高²(m²)。
根据 BMI 值的不同范围,系统将会员分为四个体质等级:
- 偏瘦 (BMI < 18.5):目标体重为正常范围的中间值
- 正常 (18.5 ≤ BMI < 24.9):目标体重等于当前体重
- 超重 (24.9 ≤ BMI < 29.9):目标体重为正常范围的上限
- 肥胖 (BMI ≥ 29.9):目标体重为正常范围的上限
系统还会计算会员需要调整的体重,帮助会员了解自己的目标。
3. 个性化训练计划
系统根据会员的健身等级生成不同的训练计划:
初级 (Beginner)
- 每周训练:3 天
- 每次时长:45 分钟
- 重点:有氧运动、基础力量、柔韧性
- 训练安排:
- 周一:有氧运动(跑步/骑车)30分钟 + 拉伸 15分钟
- 周三:基础力量训练(上身)45分钟
- 周五:有氧运动(游泳/椭圆机)30分钟 + 拉伸 15分钟
中级 (Intermediate)
- 每周训练:4 天
- 每次时长:60 分钟
- 重点:力量训练、有氧运动、核心训练
- 训练安排:
- 周一:胸部和三头肌 + 有氧 20分钟
- 周二:有氧运动(HIIT)30分钟
- 周三:背部和二头肌 + 核心训练
- 周四:腿部训练 + 有氧 20分钟
高级 (Advanced)
- 每周训练:5 天
- 每次时长:90 分钟
- 重点:高强度间歇、肌肉增长、功能性训练
- 训练安排:
- 周一:胸部爆发力训练 + HIIT 30分钟
- 周二:背部和核心 + 功能性训练
- 周三:腿部力量 + 有氧冲刺
- 周四:肩部和手臂 + 代谢训练
- 周五:全身功能性训练
4. 心率管理
系统根据会员的年龄计算最大心率(220 - 年龄),并进一步计算训练心率范围(最大心率的 60%-85%)。这个范围是进行有效训练时的理想心率范围,可以帮助会员更科学地进行运动训练。
5. 热量管理
系统计算会员的基础代谢率(BMR)和每日热量需求,然后根据健身等级计算训练消耗的热量:
- 初级:每日热量需求的 20%
- 中级:每日热量需求的 35%
- 高级:每日热量需求的 50%
这些数据可以帮助会员了解自己的热量摄入和消耗情况。
6. 营养建议
系统根据会员的体重提供科学的营养建议:
- 蛋白质:体重 × 1.6 克/天(用于肌肉合成和修复)
- 碳水化合物:体重 × 3.0 克/天(用于能量供应)
- 脂肪:体重 × 0.8 克/天(用于激素合成和吸收)
系统还会计算这些营养物质提供的热量,帮助会员制定合理的饮食计划。
核心实现
算法原理
健身房管理系统的核心算法包括:
- BMI 计算和体质评估:快速评估会员的体质状况
- 目标体重计算:根据体质状况确定科学的目标体重
- 训练计划生成:根据健身等级生成个性化的训练计划
- 心率区间计算:基于年龄的科学训练指导
- 热量计算:精确计算基础代谢率和训练消耗
- 营养建议生成:根据体重的科学营养指导
数据验证
系统对输入数据进行严格的验证:
- 检查输入格式是否正确(必须包含 5 个字段)
- 检查数值是否有效(体重、身高、年龄都必须大于 0)
- 检查健身等级是否有效(必须是 beginner、intermediate 或 advanced)
这些验证确保了计算的准确性和系统的稳定性。
个性化计划生成
系统根据会员的具体情况生成个性化的训练计划和建议:
- 根据体质状况提供体重调整建议
- 根据健身等级提供不同的训练计划
- 根据年龄和体重提供心率和热量指导
- 根据体重提供营养建议
Kotlin 源代码
// 案例 32: 健身房管理系统 - 会员健身计划生成器
@OptIn(ExperimentalJsExport::class)
@JsExport
fun gymMembershipPlanner(inputData: String = "张三 75 1.75 30 beginner"): String {
if (inputData.isEmpty()) {
return "❌ 错误: 输入不能为空\n请输入: 姓名 体重(kg) 身高(m) 年龄(岁) 等级(beginner/intermediate/advanced)"
}
val parts = inputData.trim().split(" ")
if (parts.size != 5) {
return "❌ 错误: 输入格式不正确\n请输入: 姓名 体重(kg) 身高(m) 年龄(岁) 等级"
}
val memberName = parts[0]
val weight = parts[1].toDoubleOrNull()
val height = parts[2].toDoubleOrNull()
val age = parts[3].toIntOrNull()
val level = parts[4].lowercase()
if (weight == null || height == null || age == null) {
return "❌ 错误: 数值输入无效"
}
if (weight <= 0 || height <= 0 || age <= 0) {
return "❌ 错误: 输入值必须大于 0"
}
if (level !in listOf("beginner", "intermediate", "advanced")) {
return "❌ 错误: 等级必须是 beginner/intermediate/advanced"
}
// 1. 计算 BMI
val bmi = weight / (height * height)
val bmiCategory = when {
bmi < 18.5 -> "偏瘦"
bmi < 24.9 -> "正常"
bmi < 29.9 -> "超重"
else -> "肥胖"
}
// 2. 确定目标体重
val targetWeight = when (bmiCategory) {
"偏瘦" -> (18.5 * height * height + 24.9 * height * height) / 2
"正常" -> weight
"超重", "肥胖" -> 24.9 * height * height
else -> weight
}
// 3. 计算需要调整的体重
val weightDifference = targetWeight - weight
// 4. 根据等级设置训练计划
val (weeklyTraining, dailyDuration, focusAreas) = when (level) {
"beginner" -> Triple(3, 45, listOf("有氧运动", "基础力量", "柔韧性"))
"intermediate" -> Triple(4, 60, listOf("力量训练", "有氧运动", "核心训练"))
"advanced" -> Triple(5, 90, listOf("高强度间歇", "肌肉增长", "功能性训练"))
else -> Triple(3, 45, listOf("有氧运动", "基础力量", "柔韧性"))
}
// 5. 计算每周训练量
val weeklyMinutes = weeklyTraining * dailyDuration
// 6. 根据年龄和等级计算最大心率和训练心率
val maxHeartRate = 220 - age
val trainingHeartRateMin = (maxHeartRate * 0.6).toInt()
val trainingHeartRateMax = (maxHeartRate * 0.85).toInt()
// 7. 计算每日热量消耗
val bmr = 10 * weight + 6.25 * height * 100 - 5 * age + 5
val dailyCalories = bmr * 1.5
val trainingCalories = when (level) {
"beginner" -> dailyCalories * 0.2
"intermediate" -> dailyCalories * 0.35
"advanced" -> dailyCalories * 0.5
else -> dailyCalories * 0.2
}
// 8. 生成营养建议
val proteinGrams = (weight * 1.6).toInt()
val carbsGrams = (weight * 3.0).toInt()
val fatsGrams = (weight * 0.8).toInt()
// 9. 生成训练计划
val trainingPlan = mutableListOf<String>()
when (level) {
"beginner" -> {
trainingPlan.add("周一: 有氧运动 (跑步/骑车) 30分钟 + 拉伸 15分钟")
trainingPlan.add("周三: 基础力量训练 (上身) 45分钟")
trainingPlan.add("周五: 有氧运动 (游泳/椭圆机) 30分钟 + 拉伸 15分钟")
}
"intermediate" -> {
trainingPlan.add("周一: 胸部和三头肌 + 有氧 20分钟")
trainingPlan.add("周二: 有氧运动 (HIIT) 30分钟")
trainingPlan.add("周三: 背部和二头肌 + 核心训练")
trainingPlan.add("周四: 腿部训练 + 有氧 20分钟")
}
"advanced" -> {
trainingPlan.add("周一: 胸部爆发力训练 + HIIT 30分钟")
trainingPlan.add("周二: 背部和核心 + 功能性训练")
trainingPlan.add("周三: 腿部力量 + 有氧冲刺")
trainingPlan.add("周四: 肩部和手臂 + 代谢训练")
trainingPlan.add("周五: 全身功能性训练")
}
else -> trainingPlan.add("请选择有效的等级")
}
// 10. 生成会员卡信息
val memberId = "GYM${(kotlin.random.Random.nextDouble() * 100000).toInt()}"
val joinDate = "2024-01-15"
val expiryDate = "2025-01-15"
return "🏋️ 健身房会员管理系统\n" +
"━━━━━━━━━━━━━━━━━━━━━\n" +
"1️⃣ 会员信息:\n" +
" 姓名: $memberName\n" +
" 会员ID: $memberId\n" +
" 入会日期: $joinDate\n" +
" 到期日期: $expiryDate\n" +
" 等级: ${level.uppercase()}\n\n" +
"2️⃣ 身体评估:\n" +
" 体重: $weight kg\n" +
" 身高: $height m\n" +
" 年龄: $age 岁\n" +
" BMI: ${(bmi * 10).toInt() / 10.0}\n" +
" 体质: $bmiCategory\n" +
" 目标体重: ${(targetWeight * 10).toInt() / 10.0} kg\n" +
" 需要调整: ${if (weightDifference > 0) "增加 ${(weightDifference * 10).toInt() / 10.0} kg" else "减少 ${(-weightDifference * 10).toInt() / 10.0} kg"}\n\n" +
"3️⃣ 训练计划:\n" +
" 等级: ${level.uppercase()}\n" +
" 每周训练: $weeklyTraining 天\n" +
" 每次时长: $dailyDuration 分钟\n" +
" 每周总量: $weeklyMinutes 分钟\n" +
" 训练心率: $trainingHeartRateMin - $trainingHeartRateMax bpm\n" +
" 重点: ${focusAreas.joinToString(", ")}\n\n" +
"4️⃣ 详细训练安排:\n" +
trainingPlan.mapIndexed { index, plan -> " ${index + 1}. $plan" }.joinToString("\n") + "\n\n" +
"5️⃣ 热量管理:\n" +
" 基础代谢率: ${(bmr * 10).toInt() / 10.0} kcal/天\n" +
" 每日需求: ${(dailyCalories * 10).toInt() / 10.0} kcal\n" +
" 训练消耗: ${(trainingCalories * 10).toInt() / 10.0} kcal/天\n\n" +
"6️⃣ 营养建议 (每日):\n" +
" 蛋白质: $proteinGrams g (${(proteinGrams * 4)} kcal)\n" +
" 碳水化合物: $carbsGrams g (${(carbsGrams * 4)} kcal)\n" +
" 脂肪: $fatsGrams g (${(fatsGrams * 9)} kcal)\n\n" +
"7️⃣ 健身建议:\n" +
" • 每周坚持 $weeklyTraining 天训练\n" +
" • 每次训练后进行 10-15 分钟拉伸\n" +
" • 保证充足睡眠 (7-9 小时)\n" +
" • 定期补充水分\n" +
" • 每月复测一次身体指标\n\n" +
"━━━━━━━━━━━━━━━━━━━━━\n" +
"✅ 会员计划生成完成!"
}
Kotlin 代码详解
这个 Kotlin 函数实现了一个完整的健身房会员管理系统。函数接收一个字符串参数,包含五个用空格分隔的数据:姓名、体重(kg)、身高(m)、年龄(岁)和健身等级(beginner/intermediate/advanced)。
首先,函数进行严格的输入验证。它检查输入是否为空,是否包含正确数量的字段,以及这些字段是否有效。这确保了后续计算的准确性。
接下来,函数计算 BMI 值,并根据 BMI 值将会员分为四个体质等级。同时,它根据体质等级确定目标体重,并计算会员需要调整的体重。
然后,函数根据健身等级设置训练计划,包括每周训练天数、每次时长和训练重点。它还计算最大心率和训练心率范围,这对会员的安全训练很重要。
函数还计算会员的基础代谢率和每日热量需求,然后根据健身等级计算训练消耗的热量。这些数据可以帮助会员制定合理的饮食计划。
最后,函数生成详细的训练计划、营养建议和健身指导,并返回一个格式化的结果字符串。
JavaScript 编译代码
// 编译后的 JavaScript 代码(部分示例)
function gymMembershipPlanner(inputData) {
if (inputData === undefined) {
inputData = "张三 75 1.75 30 beginner";
}
if (inputData.length === 0) {
return "❌ 错误: 输入不能为空\n请输入: 姓名 体重(kg) 身高(m) 年龄(岁) 等级(beginner/intermediate/advanced)";
}
var parts = inputData.trim().split(" ");
if (parts.length !== 5) {
return "❌ 错误: 输入格式不正确\n请输入: 姓名 体重(kg) 身高(m) 年龄(岁) 等级";
}
var memberName = parts[0];
var weight = parseFloat(parts[1]);
var height = parseFloat(parts[2]);
var age = parseInt(parts[3]);
var level = parts[4].toLowerCase();
if (isNaN(weight) || isNaN(height) || isNaN(age)) {
return "❌ 错误: 数值输入无效";
}
if (weight <= 0 || height <= 0 || age <= 0) {
return "❌ 错误: 输入值必须大于 0";
}
if (!["beginner", "intermediate", "advanced"].includes(level)) {
return "❌ 错误: 等级必须是 beginner/intermediate/advanced";
}
// 计算 BMI
var bmi = weight / (height * height);
var bmiCategory;
if (bmi < 18.5) {
bmiCategory = "偏瘦";
} else if (bmi < 24.9) {
bmiCategory = "正常";
} else if (bmi < 29.9) {
bmiCategory = "超重";
} else {
bmiCategory = "肥胖";
}
// 确定目标体重
var targetWeight;
if (bmiCategory === "偏瘦") {
targetWeight = (18.5 * height * height + 24.9 * height * height) / 2;
} else if (bmiCategory === "正常") {
targetWeight = weight;
} else {
targetWeight = 24.9 * height * height;
}
var weightDifference = targetWeight - weight;
// 根据等级设置训练计划
var weeklyTraining, dailyDuration, focusAreas;
if (level === "beginner") {
weeklyTraining = 3;
dailyDuration = 45;
focusAreas = ["有氧运动", "基础力量", "柔韧性"];
} else if (level === "intermediate") {
weeklyTraining = 4;
dailyDuration = 60;
focusAreas = ["力量训练", "有氧运动", "核心训练"];
} else {
weeklyTraining = 5;
dailyDuration = 90;
focusAreas = ["高强度间歇", "肌肉增长", "功能性训练"];
}
var weeklyMinutes = weeklyTraining * dailyDuration;
// 计算心率
var maxHeartRate = 220 - age;
var trainingHeartRateMin = Math.floor(maxHeartRate * 0.6);
var trainingHeartRateMax = Math.floor(maxHeartRate * 0.85);
// 计算热量
var bmr = 10 * weight + 6.25 * height * 100 - 5 * age + 5;
var dailyCalories = bmr * 1.5;
var trainingCalories;
if (level === "beginner") {
trainingCalories = dailyCalories * 0.2;
} else if (level === "intermediate") {
trainingCalories = dailyCalories * 0.35;
} else {
trainingCalories = dailyCalories * 0.5;
}
// 营养建议
var proteinGrams = Math.floor(weight * 1.6);
var carbsGrams = Math.floor(weight * 3.0);
var fatsGrams = Math.floor(weight * 0.8);
// 生成训练计划
var trainingPlan = [];
if (level === "beginner") {
trainingPlan.push("周一: 有氧运动 (跑步/骑车) 30分钟 + 拉伸 15分钟");
trainingPlan.push("周三: 基础力量训练 (上身) 45分钟");
trainingPlan.push("周五: 有氧运动 (游泳/椭圆机) 30分钟 + 拉伸 15分钟");
} else if (level === "intermediate") {
trainingPlan.push("周一: 胸部和三头肌 + 有氧 20分钟");
trainingPlan.push("周二: 有氧运动 (HIIT) 30分钟");
trainingPlan.push("周三: 背部和二头肌 + 核心训练");
trainingPlan.push("周四: 腿部训练 + 有氧 20分钟");
} else {
trainingPlan.push("周一: 胸部爆发力训练 + HIIT 30分钟");
trainingPlan.push("周二: 背部和核心 + 功能性训练");
trainingPlan.push("周三: 腿部力量 + 有氧冲刺");
trainingPlan.push("周四: 肩部和手臂 + 代谢训练");
trainingPlan.push("周五: 全身功能性训练");
}
// 会员信息
var memberId = "GYM" + Math.floor(Math.random() * 100000);
var joinDate = "2024-01-15";
var expiryDate = "2025-01-15";
// 构建结果字符串
var trainingPlanStr = trainingPlan.map(function(plan, index) {
return " " + (index + 1) + ". " + plan;
}).join("\n");
var result = "🏋️ 健身房会员管理系统\n" +
"━━━━━━━━━━━━━━━━━━━━━\n" +
"1️⃣ 会员信息:\n" +
" 姓名: " + memberName + "\n" +
" 会员ID: " + memberId + "\n" +
" 入会日期: " + joinDate + "\n" +
" 到期日期: " + expiryDate + "\n" +
" 等级: " + level.toUpperCase() + "\n\n" +
"2️⃣ 身体评估:\n" +
" 体重: " + weight + " kg\n" +
" 身高: " + height + " m\n" +
" 年龄: " + age + " 岁\n" +
" BMI: " + (Math.floor(bmi * 10) / 10) + "\n" +
" 体质: " + bmiCategory + "\n" +
" 目标体重: " + (Math.floor(targetWeight * 10) / 10) + " kg\n" +
" 需要调整: " + (weightDifference > 0 ? "增加 " + (Math.floor(weightDifference * 10) / 10) + " kg" : "减少 " + (Math.floor(-weightDifference * 10) / 10) + " kg") + "\n\n" +
"3️⃣ 训练计划:\n" +
" 等级: " + level.toUpperCase() + "\n" +
" 每周训练: " + weeklyTraining + " 天\n" +
" 每次时长: " + dailyDuration + " 分钟\n" +
" 每周总量: " + weeklyMinutes + " 分钟\n" +
" 训练心率: " + trainingHeartRateMin + " - " + trainingHeartRateMax + " bpm\n" +
" 重点: " + focusAreas.join(", ") + "\n\n" +
"4️⃣ 详细训练安排:\n" +
trainingPlanStr + "\n\n" +
"5️⃣ 热量管理:\n" +
" 基础代谢率: " + (Math.floor(bmr * 10) / 10) + " kcal/天\n" +
" 每日需求: " + (Math.floor(dailyCalories * 10) / 10) + " kcal\n" +
" 训练消耗: " + (Math.floor(trainingCalories * 10) / 10) + " kcal/天\n\n" +
"6️⃣ 营养建议 (每日):\n" +
" 蛋白质: " + proteinGrams + " g (" + (proteinGrams * 4) + " kcal)\n" +
" 碳水化合物: " + carbsGrams + " g (" + (carbsGrams * 4) + " kcal)\n" +
" 脂肪: " + fatsGrams + " g (" + (fatsGrams * 9) + " kcal)\n\n" +
"7️⃣ 健身建议:\n" +
" • 每周坚持 " + weeklyTraining + " 天训练\n" +
" • 每次训练后进行 10-15 分钟拉伸\n" +
" • 保证充足睡眠 (7-9 小时)\n" +
" • 定期补充水分\n" +
" • 每月复测一次身体指标\n\n" +
"━━━━━━━━━━━━━━━━━━━━━\n" +
"✅ 会员计划生成完成!";
return result;
}
JavaScript 代码详解
Kotlin 代码编译到 JavaScript 后,保留了原有的逻辑结构,但使用 JavaScript 的语法和 API。主要的转换包括:
-
类型转换:Kotlin 的
toDoubleOrNull()和toIntOrNull()转换为 JavaScript 的parseFloat()和parseInt(),并使用isNaN()检查转换是否成功。 -
条件语句:Kotlin 的
when表达式转换为 JavaScript 的if-else链。 -
集合操作:Kotlin 的
in操作符转换为 JavaScript 的includes()方法。 -
字符串处理:Kotlin 的字符串模板转换为 JavaScript 的字符串拼接操作。
-
数组操作:Kotlin 的
mutableListOf()和mapIndexed()转换为 JavaScript 的数组和map()方法。
这个 JavaScript 版本可以直接在浏览器或 Node.js 环境中运行,并且功能与 Kotlin 版本完全相同。
ArkTS 调用代码
import { gymMembershipPlanner } from './hellokjs';
@Entry
@Component
struct Index {
@State message: string = '准备就绪';
@State memberName: string = '张三';
@State weight: string = '75';
@State height: string = '1.75';
@State age: string = '30';
@State level: string = 'beginner';
@State resultText: string = '';
@State isLoading: boolean = false;
aboutToAppear(): void {
this.generateNewCase();
}
generateNewCase(): void {
this.resultText = '';
this.message = '准备就绪';
const samples = [
{ name: '张三', w: '75', h: '1.75', a: '30', l: 'beginner' },
{ name: '李四', w: '68', h: '1.80', a: '25', l: 'intermediate' },
{ name: '王五', w: '82', h: '1.78', a: '35', l: 'advanced' },
{ name: '赵六', w: '60', h: '1.65', a: '28', l: 'beginner' },
{ name: '孙七', w: '90', h: '1.85', a: '40', l: 'intermediate' }
];
const random = samples[Math.floor(Math.random() * samples.length)];
this.memberName = random.name;
this.weight = random.w;
this.height = random.h;
this.age = random.a;
this.level = random.l;
}
generatePlan(): void {
this.isLoading = true;
try {
const input: string = `${this.memberName} ${this.weight} ${this.height} ${this.age} ${this.level}`;
const result: string = gymMembershipPlanner(input);
this.resultText = result;
console.log(result);
this.message = '✓ 健身计划生成完成';
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
this.message = `✗ 错误: ${errorMessage}`;
} finally {
this.isLoading = false;
}
}
build() {
Column() {
// ===== 顶部标题栏 - 橙色主题 =====
Column() {
Text('🏋️ Gym Membership Planner')
.fontSize(28)
.fontWeight(FontWeight.Bold)
.fontColor(Color.White)
.margin({ bottom: 8 })
Text('Personalized Fitness Plan Generator')
.fontSize(13)
.fontColor('#FFE0B2')
}
.width('100%')
.padding(24)
.backgroundColor('#E65100')
.alignItems(HorizontalAlign.Start)
// ===== 主内容区域 =====
Scroll() {
Column() {
// 输入卡片
Column() {
Row() {
Text('📋 Member Info')
.fontSize(16)
.fontWeight(FontWeight.Bold)
.fontColor('#FFFFFF')
Blank()
Text('🎲 Random')
.fontSize(12)
.fontColor(Color.White)
.padding({ left: 10, right: 10, top: 6, bottom: 6 })
.backgroundColor('#BF360C')
.borderRadius(12)
.onClick(() => {
this.generateNewCase();
})
}
.width('100%')
.margin({ bottom: 18 })
// 姓名输入
TextInput({ placeholder: 'Member Name', text: this.memberName })
.width('100%')
.height(50)
.padding(14)
.fontSize(15)
.fontColor('#000000')
.placeholderColor('#999999')
.border({ width: 2, color: '#E65100' })
.borderRadius(12)
.backgroundColor('#FFF3E0')
.onChange((value: string) => {
this.memberName = value;
})
.margin({ bottom: 14 })
// 体重输入
TextInput({ placeholder: 'Weight (kg)', text: this.weight })
.width('100%')
.height(50)
.padding(14)
.fontSize(15)
.fontColor('#000000')
.placeholderColor('#999999')
.border({ width: 2, color: '#E65100' })
.borderRadius(12)
.backgroundColor('#FFF3E0')
.onChange((value: string) => {
this.weight = value;
})
.margin({ bottom: 14 })
// 身高输入
TextInput({ placeholder: 'Height (m)', text: this.height })
.width('100%')
.height(50)
.padding(14)
.fontSize(15)
.fontColor('#000000')
.placeholderColor('#999999')
.border({ width: 2, color: '#E65100' })
.borderRadius(12)
.backgroundColor('#FFF3E0')
.onChange((value: string) => {
this.height = value;
})
.margin({ bottom: 14 })
// 年龄输入
TextInput({ placeholder: 'Age (years)', text: this.age })
.width('100%')
.height(50)
.padding(14)
.fontSize(15)
.fontColor('#000000')
.placeholderColor('#999999')
.border({ width: 2, color: '#E65100' })
.borderRadius(12)
.backgroundColor('#FFF3E0')
.onChange((value: string) => {
this.age = value;
})
.margin({ bottom: 14 })
// 等级选择
TextInput({ placeholder: 'Level (beginner/intermediate/advanced)', text: this.level })
.width('100%')
.height(50)
.padding(14)
.fontSize(15)
.fontColor('#000000')
.placeholderColor('#999999')
.border({ width: 2, color: '#E65100' })
.borderRadius(12)
.backgroundColor('#FFF3E0')
.onChange((value: string) => {
this.level = value;
})
.margin({ bottom: 20 })
// 生成按钮
Button(this.isLoading ? 'Generating...' : 'Generate Plan')
.width('100%')
.height(54)
.fontSize(16)
.fontWeight(FontWeight.Bold)
.fontColor(Color.White)
.backgroundColor(this.isLoading ? '#BF360C' : '#E65100')
.borderRadius(14)
.onClick(() => {
if (!this.isLoading) {
this.generatePlan();
}
})
}
.width('90%')
.padding(20)
.backgroundColor('#FFFFFF')
.borderRadius(16)
.margin({ top: 20, bottom: 20, left: 'auto', right: 'auto' })
.border({ width: 2, color: '#E65100' })
// 状态提示卡片
if (this.message !== '准备就绪') {
Row() {
Text(this.message.startsWith('✓') ? '✅' : '⚠️')
.fontSize(20)
.margin({ right: 12 })
Text(this.message)
.fontSize(14)
.fontColor(this.message.startsWith('✓') ? '#4ECDC4' : '#FF6B6B')
.fontWeight(FontWeight.Bold)
.layoutWeight(1)
}
.width('90%')
.padding(16)
.backgroundColor(this.message.startsWith('✓') ? '#1a3a3a' : '#3a1a1a')
.border({ width: 2, color: this.message.startsWith('✓') ? '#4ECDC4' : '#FF6B6B' })
.borderRadius(14)
.margin({ bottom: 20, left: 'auto', right: 'auto' })
.alignItems(VerticalAlign.Center)
}
// 结果卡片
if (this.resultText) {
Column() {
Row() {
Text('📊 Fitness Plan Results')
.fontSize(14)
.fontWeight(FontWeight.Bold)
.fontColor('#E65100')
}
.width('100%')
.padding(14)
.backgroundColor('#FFF8F0')
.borderRadius(12)
.margin({ bottom: 14 })
.border({ width: 1, color: '#E65100' })
Text(this.resultText)
.fontSize(12)
.fontFamily('monospace')
.fontColor('#BF360C')
.width('100%')
.padding(14)
.backgroundColor('#FFF8F0')
.borderRadius(12)
.border({ width: 1, color: '#FF6F00' })
}
.width('90%')
.padding(16)
.backgroundColor('#FFF3E0')
.borderRadius(16)
.margin({ bottom: 20, left: 'auto', right: 'auto' })
.border({ width: 2, color: '#E65100' })
}
// 底部提示
Column() {
Row() {
Text('💡')
.fontSize(18)
.margin({ right: 10 })
Text('🏋️ Fitness Tips')
.fontSize(14)
.fontWeight(FontWeight.Bold)
.fontColor('#E65100')
}
.width('100%')
.margin({ bottom: 12 })
Text('• Input member information\n• Select fitness level\n• Get personalized plan\n• Track progress monthly')
.fontSize(12)
.fontColor('#BF360C')
.lineHeight(1.6)
}
.width('90%')
.padding(16)
.backgroundColor('#FFF3E0')
.borderRadius(16)
.margin({ bottom: 20, left: 'auto', right: 'auto' })
.border({ width: 2, color: '#E65100' })
Blank()
.height(20)
}
.width('100%')
}
.layoutWeight(1)
}
.width('100%')
.height('100%')
.backgroundColor('#FFF3E0')
}
}
ArkTS 代码详解
这个 ArkTS 组件实现了健身房会员管理系统的用户界面。组件使用了 OpenHarmony 的 ArkTS 语言,提供了一个现代化的、橙色主题的用户界面。
组件定义了六个 @State 属性来存储用户输入的数据:姓名、体重、身高、年龄和等级。这些属性与输入框绑定,当用户输入数据时,这些属性会自动更新。
generateNewCase() 方法生成随机的会员数据样本,帮助用户快速测试应用。用户可以点击"Random"按钮来生成随机数据。
generatePlan() 方法调用 Kotlin 编译的 JavaScript 函数 gymMembershipPlanner(),并将用户输入的数据作为参数传递。函数返回的分析结果会显示在结果卡片中。
用户界面包括五个输入框(姓名、体重、身高、年龄、等级)、一个生成按钮、一个状态提示卡片、一个结果卡片和一个提示卡片。所有元素都使用了橙色主题,与健身房的活力主题相符。
实战案例
案例 1:初级会员的健身计划
假设一个 30 岁的初级会员张三,体重 75 kg,身高 1.75 m。输入数据:张三 75 1.75 30 beginner
系统会生成:
- 会员ID:GYM12345
- BMI = 24.49(正常范围)
- 目标体重:75 kg(保持不变)
- 每周训练:3 天,每次 45 分钟
- 训练心率:114-161 bpm
- 基础代谢率:约 1700 kcal/天
- 每日热量需求:约 2550 kcal
- 训练消耗:约 510 kcal/天
- 营养建议:蛋白质 120g,碳水化合物 225g,脂肪 60g
训练计划包括有氧运动、基础力量训练和拉伸。
案例 2:中级会员的健身计划
假设一个 25 岁的中级会员李四,体重 68 kg,身高 1.80 m。输入数据:李四 68 1.80 25 intermediate
系统会生成:
- 会员ID:GYM54321
- BMI = 20.99(正常范围)
- 目标体重:68 kg(保持不变)
- 每周训练:4 天,每次 60 分钟
- 训练心率:117-175 bpm
- 基础代谢率:约 1650 kcal/天
- 每日热量需求:约 2475 kcal
- 训练消耗:约 866 kcal/天
- 营养建议:蛋白质 109g,碳水化合物 204g,脂肪 54g
训练计划包括力量训练、有氧运动和核心训练。
案例 3:高级会员的健身计划
假设一个 35 岁的高级会员王五,体重 82 kg,身高 1.78 m。输入数据:王五 82 1.78 35 advanced
系统会生成:
- 会员ID:GYM98765
- BMI = 25.87(超重)
- 目标体重:78.5 kg(需要减少 3.5 kg)
- 每周训练:5 天,每次 90 分钟
- 训练心率:111-166 bpm
- 基础代谢率:约 1750 kcal/天
- 每日热量需求:约 2625 kcal
- 训练消耗:约 1313 kcal/天
- 营养建议:蛋白质 131g,碳水化合物 246g,脂肪 66g
训练计划包括高强度间歇训练、肌肉增长训练和功能性训练。
最佳实践
1. 会员信息管理
健身房管理者应该定期更新会员信息:
- 定期体测:每月为会员进行一次身体测量,记录体重和身体围度的变化
- 更新计划:根据会员的进度调整训练计划
- 跟踪进度:使用系统记录会员的训练历史和成果
2. 训练计划执行
会员应该认真执行系统生成的训练计划:
- 按时训练:每周按照计划进行规定次数的训练
- 循序渐进:逐步增加训练强度和难度
- 记录训练:记录每次训练的内容和感受
3. 营养管理
会员应该根据系统的营养建议调整饮食:
- 均衡饮食:按照建议的蛋白质、碳水化合物和脂肪比例进食
- 定时进食:建立规律的进食时间表
- 水分补充:在训练前后充分补充水分
4. 安全训练
会员应该注意训练的安全性:
- 热身准备:训练前进行 5-10 分钟的热身
- 正确姿态:学习正确的运动姿态,避免受伤
- 心率监测:使用心率表监测训练心率,确保在安全范围内
- 冷却放松:训练后进行 10-15 分钟的拉伸和放松
5. 定期评估
健身房管理者应该定期评估会员的进度:
- 月度评估:每月评估会员的训练完成情况和身体变化
- 季度复测:每季度进行一次全面的身体评估
- 调整计划:根据评估结果调整训练计划和营养建议
总结
健身房管理系统 - 会员健身计划生成器展示了如何使用 Kotlin Multiplatform 技术创建一个功能丰富、跨端兼容的健身管理应用。通过综合考虑会员的体重、身高、年龄和健身等级,系统能够自动生成个性化的训练计划、营养建议和健身指导。
这个案例不仅展示了 KMP 的强大功能,还演示了如何将复杂的健身科学知识转化为实用的应用功能。无论是健身房管理者还是健身爱好者,都可以使用这个系统来制定科学的训练计划,并根据建议调整生活方式。
健身是一个长期的过程,需要坚持和科学的指导。通过使用这个健身房管理系统,会员可以更有效地实现自己的健身目标,获得更好的训练效果。
更多推荐




所有评论(0)