健身计划评估 - KMP鸿蒙科学制定个人方案
本文介绍了一个基于Kotlin Multiplatform框架的健身计划评估系统,该系统可跨平台运行于Android、iOS、Web和OpenHarmony等平台。系统包含用户管理、健身计划管理、多维度评估等功能,支持从运动强度、时长、频率、恢复时间等维度进行科学评估,并提供个性化健身建议。通过KMP框架实现代码复用,结合OpenHarmony系统特性,为健身爱好者提供科学的健身决策辅助工具。系统

目录
概述
健身已成为现代生活中重要的健康管理方式。无论是为了减肥、增肌还是提升体质,制定合适的健身计划对于达成健身目标至关重要。然而,面对众多健身方式和复杂的身体数据,健身爱好者往往难以制定最优的健身计划。健身计划评估系统是帮助用户了解自身情况、评估健身计划质量、制定科学健身方案的重要工具。本文档介绍如何在 Kotlin Multiplatform (KMP) 框架下,结合 OpenHarmony 鸿蒙操作系统,实现一个功能完整的健身计划评估系统。
健身计划评估系统是一个综合性的健身管理平台,它不仅能够对健身计划进行多维度评估,还能够进行计划对比、生成健身建议、提供个性化的健身方案。通过KMP框架的跨端能力,这个工具可以在Android、iOS、Web和OpenHarmony等多个平台上运行,为健身爱好者提供了一个强大的健身决策辅助工具。
健身计划评估的重要性
健身计划评估在现代健身中的重要性日益凸显:
- 目标达成:科学的计划能够帮助用户更快达成健身目标。
- 效率提升:合理的计划能够提升健身效率,减少浪费时间。
- 伤害预防:科学的计划能够预防运动伤害。
- 动力维持:明确的计划能够帮助用户维持健身动力。
- 体质改善:系统的计划能够显著改善身体素质。
工具的核心价值
健身计划评估系统提供以下价值:
- 多维度评估:从运动强度、运动时长、运动频率、恢复时间等多个维度进行评估
- 计划对比:支持多个健身计划的对比分析
- 个性化推荐:根据用户身体数据提供个性化的健身方案
- 进度追踪:提供健身进度的实时追踪和分析
- 健身建议:根据评估结果提供科学的健身建议
- 跨平台支持:一份代码可在多个平台运行,提高开发效率
健身计划基础
核心概念
健身计划评分(Fitness Plan Rating):对健身计划的综合评价,通常用0-100的分数表示。
运动强度(Exercise Intensity):健身计划中运动的强度等级。
运动时长(Exercise Duration):每次健身的时间长度。
运动频率(Exercise Frequency):每周的健身次数。
恢复时间(Recovery Time):运动后的恢复时间。
目标匹配度(Goal Matching):健身计划与用户目标的匹配程度。
常见的健身计划评估维度
强度维度:低强度、中强度、高强度等。
时间维度:短期计划、中期计划、长期计划等。
类型维度:有氧运动、力量训练、柔韧性训练等。
频率维度:每周运动次数、每次运动时长等。
恢复维度:恢复时间、恢复方式等。
效果维度:预期效果、实际效果等。
影响健身计划评分的关键因素
用户体质:不同体质需要不同的健身计划。
健身目标:减肥、增肌、提升体质等不同目标需要不同计划。
运动经验:初学者和有经验者需要不同的计划。
时间可用性:用户能够投入的时间影响计划制定。
运动偏好:用户喜欢的运动类型影响计划制定。
身体状况:是否有伤病等身体状况影响计划制定。
核心评估方法
1. 强度评估
评估健身计划的运动强度是否合理。
2. 时长评估
评估健身计划的运动时长是否充分。
3. 频率评估
评估健身计划的运动频率是否合适。
4. 恢复评估
评估健身计划的恢复时间是否充足。
5. 目标匹配评估
评估健身计划与用户目标的匹配程度。
6. 个性化推荐
根据用户身体数据提供个性化的健身方案。
Kotlin 源代码
// FitnessPlanAssessmentSystem.kt
import java.time.LocalDateTime
import kotlin.math.pow
data class UserProfile(
val userId: String,
val name: String,
val age: Int,
val weight: Double,
val height: Double,
val fitnessGoal: String,
val experienceLevel: String
)
data class FitnessPlan(
val planId: String,
val planName: String,
val intensity: String,
val durationPerSession: Int,
val frequencyPerWeek: Int,
val recoveryTime: Int,
val exerciseTypes: List<String>,
val targetMuscles: List<String>
)
data class PlanRating(
val planId: String,
val planName: String,
val intensityScore: Double,
val durationScore: Double,
val frequencyScore: Double,
val recoveryScore: Double,
val goalMatchScore: Double,
val overallScore: Double,
val ratingLevel: String,
val recommendations: List<String>,
val timestamp: String
)
data class AssessmentMetrics(
val totalPlans: Long,
val averageScore: Double,
val bestIntensityPlan: String,
val bestDurationPlan: String,
val averageFrequency: Double,
val mostRecommendedExerciseType: String
)
data class PlanComparison(
val plans: List<PlanRating>,
val bestIntensity: String,
val bestDuration: String,
val bestFrequency: String,
val bestRecovery: String,
val recommendation: String
)
class FitnessPlanAssessmentSystem {
private val users = mutableListOf<UserProfile>()
private val plans = mutableListOf<FitnessPlan>()
private val ratings = mutableListOf<PlanRating>()
private var userIdCounter = 0
private var planIdCounter = 0
// 添加用户
fun addUser(
name: String,
age: Int,
weight: Double,
height: Double,
fitnessGoal: String,
experienceLevel: String
): UserProfile {
val id = "USER${++userIdCounter}"
val user = UserProfile(id, name, age, weight, height, fitnessGoal, experienceLevel)
users.add(user)
return user
}
// 添加健身计划
fun addPlan(
planName: String,
intensity: String,
durationPerSession: Int,
frequencyPerWeek: Int,
recoveryTime: Int,
exerciseTypes: List<String>,
targetMuscles: List<String>
): FitnessPlan {
val id = "PLAN${++planIdCounter}"
val plan = FitnessPlan(
id, planName, intensity, durationPerSession, frequencyPerWeek,
recoveryTime, exerciseTypes, targetMuscles
)
plans.add(plan)
return plan
}
// 评估健身计划
fun assessPlan(
planId: String,
userId: String,
intensityScore: Double,
durationScore: Double,
frequencyScore: Double,
recoveryScore: Double,
goalMatchScore: Double
): PlanRating {
val plan = plans.find { it.planId == planId }
?: return PlanRating("", "", 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, "", emptyList(), "")
// 确保分数在0-100范围内
val intensity = minOf(maxOf(intensityScore, 0.0), 100.0)
val duration = minOf(maxOf(durationScore, 0.0), 100.0)
val frequency = minOf(maxOf(frequencyScore, 0.0), 100.0)
val recovery = minOf(maxOf(recoveryScore, 0.0), 100.0)
val goalMatch = minOf(maxOf(goalMatchScore, 0.0), 100.0)
// 计算综合评分(加权平均)
val overallScore = intensity * 0.25 + duration * 0.20 + frequency * 0.20 + recovery * 0.15 + goalMatch * 0.20
// 判断评分等级
val ratingLevel = when {
overallScore >= 90 -> "优秀计划"
overallScore >= 80 -> "良好计划"
overallScore >= 70 -> "推荐计划"
overallScore >= 60 -> "一般计划"
else -> "需要改进"
}
// 生成建议
val recommendations = generateRecommendations(
intensity, duration, frequency, recovery, goalMatch, plan
)
val rating = PlanRating(
planId, plan.planName, intensity, duration, frequency, recovery, goalMatch,
overallScore, ratingLevel, recommendations, LocalDateTime.now().toString()
)
ratings.add(rating)
return rating
}
// 生成建议
private fun generateRecommendations(
intensity: Double,
duration: Double,
frequency: Double,
recovery: Double,
goalMatch: Double,
plan: FitnessPlan
): List<String> {
val recommendations = mutableListOf<String>()
if (intensity >= 80) {
recommendations.add("💪 运动强度合理,能够有效刺激肌肉")
} else if (intensity < 60) {
recommendations.add("💪 运动强度偏低,可能效果不够理想")
}
if (duration >= 80) {
recommendations.add("⏱️ 运动时长充分,能够达到预期效果")
} else if (duration < 60) {
recommendations.add("⏱️ 运动时长偏短,建议增加运动时间")
}
if (frequency >= 80) {
recommendations.add("📅 运动频率合理,能够保持训练效果")
} else if (frequency < 60) {
recommendations.add("📅 运动频率偏低,建议增加训练次数")
}
if (recovery >= 80) {
recommendations.add("😴 恢复时间充足,有利于肌肉生长")
} else if (recovery < 60) {
recommendations.add("😴 恢复时间不足,容易导致过度训练")
}
if (goalMatch >= 85) {
recommendations.add("🎯 计划与目标高度匹配,强烈推荐")
} else if (goalMatch < 70) {
recommendations.add("🎯 计划与目标匹配度一般,需要调整")
}
if (plan.exerciseTypes.contains("力量训练")) {
recommendations.add("🏋️ 包含力量训练,有利于增肌")
}
return recommendations
}
// 获取评估指标
fun getAssessmentMetrics(): AssessmentMetrics {
if (ratings.isEmpty()) {
return AssessmentMetrics(0, 0.0, "", "", 0.0, "")
}
val totalPlans = plans.size.toLong()
val averageScore = ratings.map { it.overallScore }.average()
val bestIntensityPlan = ratings.maxByOrNull { it.intensityScore }?.planName ?: ""
val bestDurationPlan = ratings.maxByOrNull { it.durationScore }?.planName ?: ""
val averageFrequency = plans.map { it.frequencyPerWeek }.average()
val exerciseTypeCount = mutableMapOf<String, Int>()
for (plan in plans) {
for (type in plan.exerciseTypes) {
exerciseTypeCount[type] = (exerciseTypeCount[type] ?: 0) + 1
}
}
val mostRecommendedExerciseType = exerciseTypeCount.maxByOrNull { it.value }?.key ?: ""
return AssessmentMetrics(
totalPlans, averageScore, bestIntensityPlan, bestDurationPlan,
averageFrequency, mostRecommendedExerciseType
)
}
// 获取所有评估
fun getAllRatings(): List<PlanRating> {
return ratings.toList()
}
// 计划对比
fun comparePlans(planIds: List<String>): PlanComparison {
val comparisonRatings = ratings.filter { it.planId in planIds }
val bestIntensity = comparisonRatings.maxByOrNull { it.intensityScore }?.planName ?: ""
val bestDuration = comparisonRatings.maxByOrNull { it.durationScore }?.planName ?: ""
val bestFrequency = comparisonRatings.maxByOrNull { it.frequencyScore }?.planName ?: ""
val bestRecovery = comparisonRatings.maxByOrNull { it.recoveryScore }?.planName ?: ""
val avgScore = comparisonRatings.map { it.overallScore }.average()
val recommendation = when {
avgScore >= 85 -> "这些计划整体评分很高,都值得选择"
avgScore >= 75 -> "这些计划评分良好,可根据偏好选择"
else -> "这些计划评分一般,建议选择评分最高的"
}
return PlanComparison(
comparisonRatings, bestIntensity, bestDuration, bestFrequency, bestRecovery, recommendation
)
}
// 生成健身报告
fun generateFitnessReport(): Map<String, Any> {
val metrics = getAssessmentMetrics()
return mapOf(
"timestamp" to LocalDateTime.now().toString(),
"metrics" to metrics,
"ratings" to ratings.toList(),
"topPlans" to ratings.sortedByDescending { it.overallScore }.take(5),
"recommendations" to generateGeneralRecommendations(metrics)
)
}
// 生成通用建议
private fun generateGeneralRecommendations(metrics: AssessmentMetrics): List<String> {
val recommendations = mutableListOf<String>()
if (metrics.averageScore >= 80) {
recommendations.add("📊 整体计划质量高,选择丰富")
} else if (metrics.averageScore < 70) {
recommendations.add("📊 整体计划质量一般,建议选择高评分计划")
}
if (metrics.averageFrequency >= 4) {
recommendations.add("📅 平均训练频率较高,需要注意恢复")
}
recommendations.add("✅ 根据个人情况选择计划,坚持训练,享受健身的快乐")
return recommendations
}
// 清空数据
fun clearData() {
users.clear()
plans.clear()
ratings.clear()
}
}
fun main() {
val system = FitnessPlanAssessmentSystem()
// 添加用户
system.addUser("张三", 28, 75.0, 175.0, "增肌", "中级")
// 添加健身计划
system.addPlan(
"增肌计划A",
"高强度",
60,
4,
48,
listOf("力量训练", "有氧运动"),
listOf("胸肌", "背肌", "腿部")
)
system.addPlan(
"增肌计划B",
"中强度",
45,
3,
72,
listOf("力量训练", "柔韧性训练"),
listOf("全身")
)
// 评估计划
val rating1 = system.assessPlan("PLAN1", "USER1", 90.0, 85.0, 88.0, 80.0, 92.0)
val rating2 = system.assessPlan("PLAN2", "USER1", 80.0, 75.0, 70.0, 85.0, 78.0)
println("健身计划评估结果:")
println("${rating1.planName}: ${String.format("%.2f", rating1.overallScore)} (${rating1.ratingLevel})")
println("${rating2.planName}: ${String.format("%.2f", rating2.overallScore)} (${rating2.ratingLevel})")
// 生成报告
val report = system.generateFitnessReport()
println("\n健身报告已生成")
}
Kotlin代码说明:这个Kotlin实现提供了完整的健身计划评估功能。FitnessPlanAssessmentSystem 类能够管理用户信息和健身计划、进行计划评估、进行计划对比、生成健身报告。通过使用数据类和科学的计算方法,代码既简洁又准确。系统支持多维度的计划分析,从单个计划的详细评分到整个系统的趋势分析,为健身爱好者提供了全面的健身决策支持。
JavaScript 编译代码
// FitnessPlanAssessmentSystem.js
class UserProfile {
constructor(userId, name, age, weight, height, fitnessGoal, experienceLevel) {
this.userId = userId;
this.name = name;
this.age = age;
this.weight = weight;
this.height = height;
this.fitnessGoal = fitnessGoal;
this.experienceLevel = experienceLevel;
}
}
class FitnessPlan {
constructor(planId, planName, intensity, durationPerSession, frequencyPerWeek, recoveryTime, exerciseTypes, targetMuscles) {
this.planId = planId;
this.planName = planName;
this.intensity = intensity;
this.durationPerSession = durationPerSession;
this.frequencyPerWeek = frequencyPerWeek;
this.recoveryTime = recoveryTime;
this.exerciseTypes = exerciseTypes;
this.targetMuscles = targetMuscles;
}
}
class PlanRating {
constructor(planId, planName, intensityScore, durationScore, frequencyScore, recoveryScore, goalMatchScore, overallScore, ratingLevel, recommendations, timestamp) {
this.planId = planId;
this.planName = planName;
this.intensityScore = intensityScore;
this.durationScore = durationScore;
this.frequencyScore = frequencyScore;
this.recoveryScore = recoveryScore;
this.goalMatchScore = goalMatchScore;
this.overallScore = overallScore;
this.ratingLevel = ratingLevel;
this.recommendations = recommendations;
this.timestamp = timestamp;
}
}
class AssessmentMetrics {
constructor(totalPlans, averageScore, bestIntensityPlan, bestDurationPlan, averageFrequency, mostRecommendedExerciseType) {
this.totalPlans = totalPlans;
this.averageScore = averageScore;
this.bestIntensityPlan = bestIntensityPlan;
this.bestDurationPlan = bestDurationPlan;
this.averageFrequency = averageFrequency;
this.mostRecommendedExerciseType = mostRecommendedExerciseType;
}
}
class FitnessPlanAssessmentSystem {
constructor() {
this.users = [];
this.plans = [];
this.ratings = [];
this.userIdCounter = 0;
this.planIdCounter = 0;
}
addUser(name, age, weight, height, fitnessGoal, experienceLevel) {
const id = `USER${++this.userIdCounter}`;
const user = new UserProfile(id, name, age, weight, height, fitnessGoal, experienceLevel);
this.users.push(user);
return user;
}
addPlan(planName, intensity, durationPerSession, frequencyPerWeek, recoveryTime, exerciseTypes, targetMuscles) {
const id = `PLAN${++this.planIdCounter}`;
const plan = new FitnessPlan(id, planName, intensity, durationPerSession, frequencyPerWeek, recoveryTime, exerciseTypes, targetMuscles);
this.plans.push(plan);
return plan;
}
assessPlan(planId, userId, intensityScore, durationScore, frequencyScore, recoveryScore, goalMatchScore) {
const plan = this.plans.find(p => p.planId === planId);
if (!plan) return null;
const intensity = Math.min(Math.max(intensityScore, 0), 100);
const duration = Math.min(Math.max(durationScore, 0), 100);
const frequency = Math.min(Math.max(frequencyScore, 0), 100);
const recovery = Math.min(Math.max(recoveryScore, 0), 100);
const goalMatch = Math.min(Math.max(goalMatchScore, 0), 100);
const overallScore = intensity * 0.25 + duration * 0.20 + frequency * 0.20 + recovery * 0.15 + goalMatch * 0.20;
let ratingLevel;
if (overallScore >= 90) ratingLevel = "优秀计划";
else if (overallScore >= 80) ratingLevel = "良好计划";
else if (overallScore >= 70) ratingLevel = "推荐计划";
else if (overallScore >= 60) ratingLevel = "一般计划";
else ratingLevel = "需要改进";
const recommendations = this.generateRecommendations(intensity, duration, frequency, recovery, goalMatch, plan);
const rating = new PlanRating(planId, plan.planName, intensity, duration, frequency, recovery, goalMatch, overallScore, ratingLevel, recommendations, new Date().toISOString());
this.ratings.push(rating);
return rating;
}
generateRecommendations(intensity, duration, frequency, recovery, goalMatch, plan) {
const recommendations = [];
if (intensity >= 80) {
recommendations.push("💪 运动强度合理,能够有效刺激肌肉");
} else if (intensity < 60) {
recommendations.push("💪 运动强度偏低,可能效果不够理想");
}
if (duration >= 80) {
recommendations.push("⏱️ 运动时长充分,能够达到预期效果");
} else if (duration < 60) {
recommendations.push("⏱️ 运动时长偏短,建议增加运动时间");
}
if (frequency >= 80) {
recommendations.push("📅 运动频率合理,能够保持训练效果");
} else if (frequency < 60) {
recommendations.push("📅 运动频率偏低,建议增加训练次数");
}
if (recovery >= 80) {
recommendations.push("😴 恢复时间充足,有利于肌肉生长");
} else if (recovery < 60) {
recommendations.push("😴 恢复时间不足,容易导致过度训练");
}
if (goalMatch >= 85) {
recommendations.push("🎯 计划与目标高度匹配,强烈推荐");
} else if (goalMatch < 70) {
recommendations.push("🎯 计划与目标匹配度一般,需要调整");
}
if (plan.exerciseTypes.includes("力量训练")) {
recommendations.push("🏋️ 包含力量训练,有利于增肌");
}
return recommendations;
}
getAssessmentMetrics() {
if (this.ratings.length === 0) {
return new AssessmentMetrics(0, 0, "", "", 0, "");
}
const totalPlans = this.plans.length;
const averageScore = this.ratings.reduce((sum, r) => sum + r.overallScore, 0) / this.ratings.length;
const bestIntensityPlan = this.ratings.reduce((max, r) => r.intensityScore > max.intensityScore ? r : max).planName;
const bestDurationPlan = this.ratings.reduce((max, r) => r.durationScore > max.durationScore ? r : max).planName;
const averageFrequency = this.plans.reduce((sum, p) => sum + p.frequencyPerWeek, 0) / this.plans.length;
const exerciseTypeCount = {};
for (const plan of this.plans) {
for (const type of plan.exerciseTypes) {
exerciseTypeCount[type] = (exerciseTypeCount[type] || 0) + 1;
}
}
const mostRecommendedExerciseType = Object.keys(exerciseTypeCount).reduce((a, b) => exerciseTypeCount[a] > exerciseTypeCount[b] ? a : b, "");
return new AssessmentMetrics(totalPlans, averageScore, bestIntensityPlan, bestDurationPlan, averageFrequency, mostRecommendedExerciseType);
}
getAllRatings() {
return this.ratings;
}
comparePlans(planIds) {
const comparisonRatings = this.ratings.filter(r => planIds.includes(r.planId));
const bestIntensity = comparisonRatings.reduce((max, r) => r.intensityScore > max.intensityScore ? r : max).planName;
const bestDuration = comparisonRatings.reduce((max, r) => r.durationScore > max.durationScore ? r : max).planName;
const bestFrequency = comparisonRatings.reduce((max, r) => r.frequencyScore > max.frequencyScore ? r : max).planName;
const bestRecovery = comparisonRatings.reduce((max, r) => r.recoveryScore > max.recoveryScore ? r : max).planName;
const avgScore = comparisonRatings.reduce((sum, r) => sum + r.overallScore, 0) / comparisonRatings.length;
let recommendation;
if (avgScore >= 85) recommendation = "这些计划整体评分很高,都值得选择";
else if (avgScore >= 75) recommendation = "这些计划评分良好,可根据偏好选择";
else recommendation = "这些计划评分一般,建议选择评分最高的";
return {
plans: comparisonRatings,
bestIntensity: bestIntensity,
bestDuration: bestDuration,
bestFrequency: bestFrequency,
bestRecovery: bestRecovery,
recommendation: recommendation
};
}
generateFitnessReport() {
const metrics = this.getAssessmentMetrics();
return {
timestamp: new Date().toISOString(),
metrics: metrics,
ratings: this.ratings,
topPlans: this.ratings.sort((a, b) => b.overallScore - a.overallScore).slice(0, 5),
recommendations: this.generateGeneralRecommendations(metrics)
};
}
generateGeneralRecommendations(metrics) {
const recommendations = [];
if (metrics.averageScore >= 80) {
recommendations.push("📊 整体计划质量高,选择丰富");
} else if (metrics.averageScore < 70) {
recommendations.push("📊 整体计划质量一般,建议选择高评分计划");
}
if (metrics.averageFrequency >= 4) {
recommendations.push("📅 平均训练频率较高,需要注意恢复");
}
recommendations.push("✅ 根据个人情况选择计划,坚持训练,享受健身的快乐");
return recommendations;
}
clearData() {
this.users = [];
this.plans = [];
this.ratings = [];
}
}
// 使用示例
const system = new FitnessPlanAssessmentSystem();
system.addUser("张三", 28, 75, 175, "增肌", "中级");
system.addPlan(
"增肌计划A",
"高强度",
60,
4,
48,
["力量训练", "有氧运动"],
["胸肌", "背肌", "腿部"]
);
system.addPlan(
"增肌计划B",
"中强度",
45,
3,
72,
["力量训练", "柔韧性训练"],
["全身"]
);
const rating1 = system.assessPlan("PLAN1", "USER1", 90, 85, 88, 80, 92);
const rating2 = system.assessPlan("PLAN2", "USER1", 80, 75, 70, 85, 78);
console.log("健身计划评估结果:");
console.log(`${rating1.planName}: ${rating1.overallScore.toFixed(2)} (${rating1.ratingLevel})`);
console.log(`${rating2.planName}: ${rating2.overallScore.toFixed(2)} (${rating2.ratingLevel})`);
const report = system.generateFitnessReport();
console.log("\n健身报告已生成");
JavaScript代码说明:JavaScript版本是Kotlin代码的直接转译。我们使用ES6的class语法定义各个类,使用数学函数进行计算。整体逻辑和算法与Kotlin版本保持一致,确保跨平台的一致性。JavaScript的灵活性使得代码更加简洁,同时保持了清晰的结构和完整的功能。
ArkTS 调用代码
// FitnessPlanAssessmentPage.ets
import { FitnessPlanAssessmentSystem } from './FitnessPlanAssessmentSystem';
@Entry
@Component
struct FitnessPlanAssessmentPage {
@State planName: string = '增肌计划A';
@State intensity: string = '高强度';
@State durationPerSession: number = 60;
@State frequencyPerWeek: number = 4;
@State recoveryTime: number = 48;
@State intensityScore: number = 85;
@State durationScore: number = 80;
@State frequencyScore: number = 85;
@State recoveryScore: number = 80;
@State goalMatchScore: number = 85;
@State selectedTab: number = 0;
@State ratings: Array<any> = [];
@State metrics: any = null;
@State isLoading: boolean = false;
@State errorMessage: string = '';
@State report: any = null;
private system: FitnessPlanAssessmentSystem = new FitnessPlanAssessmentSystem();
private intensityOptions = ['低强度', '中强度', '高强度'];
addAndAssessPlan() {
if (!this.planName.trim()) {
this.errorMessage = '请输入计划名称';
return;
}
this.isLoading = true;
this.errorMessage = '';
try {
this.system.addUser("用户1", 28, 75, 175, "增肌", "中级");
this.system.addPlan(
this.planName,
this.intensity,
this.durationPerSession,
this.frequencyPerWeek,
this.recoveryTime,
["力量训练", "有氧运动"],
["胸肌", "背肌"]
);
this.system.assessPlan(
"PLAN1",
"USER1",
this.intensityScore,
this.durationScore,
this.frequencyScore,
this.recoveryScore,
this.goalMatchScore
);
this.ratings = this.system.getAllRatings();
this.metrics = this.system.getAssessmentMetrics();
AlertDialog.show({ message: '计划已添加并评估' });
// 重置表单
this.planName = '';
this.intensityScore = 80;
this.durationScore = 80;
this.frequencyScore = 80;
this.recoveryScore = 80;
this.goalMatchScore = 80;
} catch (error) {
this.errorMessage = '操作失败: ' + error.message;
} finally {
this.isLoading = false;
}
}
generateReport() {
this.isLoading = true;
try {
this.report = this.system.generateFitnessReport();
} catch (error) {
this.errorMessage = '生成报告失败: ' + error.message;
} finally {
this.isLoading = false;
}
}
getRatingLevelColor(level: string): string {
switch (level) {
case '优秀计划': return '#FFD700';
case '良好计划': return '#4CAF50';
case '推荐计划': return '#FF9800';
case '一般计划': return '#F44336';
case '需要改进': return '#D32F2F';
default: return '#999999';
}
}
build() {
Column() {
Text('健身计划评估系统')
.fontSize(24)
.fontWeight(FontWeight.Bold)
.margin({ top: 20, bottom: 20 })
Tabs({ barPosition: BarPosition.Start }) {
TabContent() {
Column() {
Text('添加计划').fontSize(14).fontWeight(FontWeight.Bold).margin({ bottom: 15 })
Text('计划名称:').fontSize(12).margin({ bottom: 5 })
TextInput({ placeholder: '增肌计划A' })
.value(this.planName)
.onChange((value: string) => { this.planName = value; })
.height(40).padding(10).border({ width: 1, color: '#cccccc' }).margin({ bottom: 15 })
Row() {
Column() {
Text('运动强度:').fontSize(12).margin({ bottom: 5 })
Select(this.intensityOptions.map(t => ({ value: t })))
.value(this.intensity)
.onSelect((index: number, value?: string) => {
this.intensity = value || '中强度';
})
}
.flex(1)
Column() {
Text('每周频率:').fontSize(12).margin({ bottom: 5 })
TextInput({ placeholder: '4' })
.type(InputType.Number)
.value(this.frequencyPerWeek.toString())
.onChange((value: string) => { this.frequencyPerWeek = parseInt(value) || 0; })
.height(40).padding(10).border({ width: 1, color: '#cccccc' })
}
.flex(1)
.margin({ left: 10 })
}
.margin({ bottom: 15 })
Row() {
Column() {
Text('每次时长(分):').fontSize(12).margin({ bottom: 5 })
TextInput({ placeholder: '60' })
.type(InputType.Number)
.value(this.durationPerSession.toString())
.onChange((value: string) => { this.durationPerSession = parseInt(value) || 0; })
.height(40).padding(10).border({ width: 1, color: '#cccccc' })
}
.flex(1)
Column() {
Text('恢复时间(小时):').fontSize(12).margin({ bottom: 5 })
TextInput({ placeholder: '48' })
.type(InputType.Number)
.value(this.recoveryTime.toString())
.onChange((value: string) => { this.recoveryTime = parseInt(value) || 0; })
.height(40).padding(10).border({ width: 1, color: '#cccccc' })
}
.flex(1)
.margin({ left: 10 })
}
.margin({ bottom: 15 })
Text('强度评分:').fontSize(12).margin({ bottom: 5 })
Slider({ value: this.intensityScore, min: 0, max: 100, step: 5 })
.onChange((value: number) => { this.intensityScore = value; })
.margin({ bottom: 15 })
Row() {
Column() {
Text('时长评分:').fontSize(12).margin({ bottom: 5 })
Slider({ value: this.durationScore, min: 0, max: 100, step: 5 })
.onChange((value: number) => { this.durationScore = value; })
}
.flex(1)
Column() {
Text('频率评分:').fontSize(12).margin({ bottom: 5 })
Slider({ value: this.frequencyScore, min: 0, max: 100, step: 5 })
.onChange((value: number) => { this.frequencyScore = value; })
}
.flex(1)
.margin({ left: 10 })
}
.margin({ bottom: 15 })
Row() {
Column() {
Text('恢复评分:').fontSize(12).margin({ bottom: 5 })
Slider({ value: this.recoveryScore, min: 0, max: 100, step: 5 })
.onChange((value: number) => { this.recoveryScore = value; })
}
.flex(1)
Column() {
Text('目标匹配:').fontSize(12).margin({ bottom: 5 })
Slider({ value: this.goalMatchScore, min: 0, max: 100, step: 5 })
.onChange((value: number) => { this.goalMatchScore = value; })
}
.flex(1)
.margin({ left: 10 })
}
.margin({ bottom: 15 })
Button('添加并评估').width('100%').height(40).margin({ bottom: 15 })
.onClick(() => { this.addAndAssessPlan(); }).enabled(!this.isLoading)
if (this.errorMessage) {
Text(this.errorMessage).fontSize(12).fontColor('#F44336').margin({ bottom: 15 })
}
}
.padding(15)
}
.tabBar('➕ 添加计划')
TabContent() {
Column() {
if (this.ratings.length > 0) {
Text('计划评估').fontSize(16).fontWeight(FontWeight.Bold).margin({ bottom: 15 })
List() {
ForEach(this.ratings, (rating: any) => {
ListItem() {
Column() {
Row() {
Text(rating.planName).fontSize(14).fontWeight(FontWeight.Bold).flex(1)
Text(rating.ratingLevel).fontSize(12).fontColor(this.getRatingLevelColor(rating.ratingLevel))
.fontWeight(FontWeight.Bold)
}
.margin({ bottom: 10 })
Row() {
Text('综合评分:').fontSize(11)
Text(rating.overallScore.toFixed(1)).fontSize(11).fontWeight(FontWeight.Bold)
.fontColor('#2196F3')
}
.margin({ bottom: 5 })
Row() {
Column() {
Text('强度:').fontSize(10).fontColor('#999999')
Text(rating.intensityScore.toFixed(0)).fontSize(10).fontWeight(FontWeight.Bold)
}
.flex(1)
Column() {
Text('时长:').fontSize(10).fontColor('#999999')
Text(rating.durationScore.toFixed(0)).fontSize(10).fontWeight(FontWeight.Bold)
}
.flex(1)
Column() {
Text('频率:').fontSize(10).fontColor('#999999')
Text(rating.frequencyScore.toFixed(0)).fontSize(10).fontWeight(FontWeight.Bold)
}
.flex(1)
Column() {
Text('恢复:').fontSize(10).fontColor('#999999')
Text(rating.recoveryScore.toFixed(0)).fontSize(10).fontWeight(FontWeight.Bold)
}
.flex(1)
}
}
.padding(10).border({ width: 1, color: '#eeeeee' }).borderRadius(5)
}
}, (rating: any) => rating.planId)
}
} else {
Text('请先添加计划').fontSize(12).fontColor('#999999')
}
}
.padding(15)
}
.tabBar('⭐ 评估列表')
TabContent() {
Column() {
if (this.metrics) {
Text('评估指标').fontSize(16).fontWeight(FontWeight.Bold).margin({ bottom: 15 })
Row() {
Column() {
Text('平均评分').fontSize(11).fontColor('#999999')
Text(this.metrics.averageScore.toFixed(1)).fontSize(18)
.fontWeight(FontWeight.Bold).fontColor('#2196F3').margin({ top: 5 })
}
.flex(1).alignItems(HorizontalAlign.Center).padding(15).backgroundColor('#F5F5F5').borderRadius(5)
Column() {
Text('计划总数').fontSize(11).fontColor('#999999')
Text(this.metrics.totalPlans.toString()).fontSize(18)
.fontWeight(FontWeight.Bold).fontColor('#4CAF50').margin({ top: 5 })
}
.flex(1).alignItems(HorizontalAlign.Center).padding(15).backgroundColor('#F5F5F5').borderRadius(5)
.margin({ left: 10 })
}
.margin({ bottom: 15 })
Column() {
Row() {
Text('最佳强度计划:').fontSize(12)
Text(this.metrics.bestIntensityPlan).fontSize(12).fontWeight(FontWeight.Bold)
}
.margin({ bottom: 10 })
Row() {
Text('最佳时长计划:').fontSize(12)
Text(this.metrics.bestDurationPlan).fontSize(12).fontWeight(FontWeight.Bold)
}
.margin({ bottom: 10 })
Row() {
Text('平均训练频率:').fontSize(12)
Text(this.metrics.averageFrequency.toFixed(1) + '次/周').fontSize(12).fontWeight(FontWeight.Bold)
}
}
.padding(10).backgroundColor('#F5F5F5').borderRadius(5)
} else {
Text('请先添加计划').fontSize(12).fontColor('#999999')
}
}
.padding(15)
}
.tabBar('📊 指标')
TabContent() {
Column() {
Button('生成报告').width('100%').height(40).margin({ bottom: 15 })
.onClick(() => { this.generateReport(); })
if (this.report) {
Text('健身报告').fontSize(16).fontWeight(FontWeight.Bold).margin({ bottom: 15 })
if (this.report.recommendations && this.report.recommendations.length > 0) {
Text('建议:').fontSize(14).fontWeight(FontWeight.Bold).margin({ bottom: 10 })
Column() {
ForEach(this.report.recommendations, (rec: string, index: number) => {
Row() {
Text('•').fontSize(14).fontWeight(FontWeight.Bold).margin({ right: 10 })
Text(rec).fontSize(11).flex(1)
}
.padding(10).margin({ bottom: 8 }).backgroundColor('#E3F2FD').borderRadius(5)
}, (rec: string, index: number) => index.toString())
}
}
}
}
.padding(15)
}
.tabBar('📈 报告')
}
.width('100%')
.flex(1)
}
.padding(10)
.width('100%')
.height('100%')
}
}
ArkTS代码说明:这个ArkTS实现展示了如何在OpenHarmony应用中集成健身计划评估系统。通过使用标签页组件,用户可以在添加计划、查看评估列表、查看评估指标和生成报告之间切换。UI设计直观,提供了良好的用户体验。每个标签页都有不同的功能,用户可以全面地进行计划评估和健身建议。
评估指标详解
计划评分维度
强度评分:健身计划的运动强度是否合理,范围0-100。
时长评分:每次运动的时长是否充分,范围0-100。
频率评分:每周运动频率是否合适,范围0-100。
恢复评分:运动后的恢复时间是否充足,范围0-100。
目标匹配评分:计划与用户目标的匹配程度,范围0-100。
综合评分:五个维度的加权平均,权重分别为25%、20%、20%、15%、20%。
评分等级
优秀计划:综合评分90-100分,计划质量优秀。
良好计划:综合评分80-89分,计划质量良好。
推荐计划:综合评分70-79分,计划质量一般。
一般计划:综合评分60-69分,计划质量较差。
需要改进:综合评分0-59分,计划质量很差。
实战应用
应用场景1:个人健身计划制定
健身爱好者可以使用这个系统评估不同的健身计划,制定最适合自己的健身方案。
应用场景2:健身房管理
健身房可以使用这个系统评估会员的健身计划,提供专业的指导建议。
应用场景3:健身教练工具
健身教练可以使用这个系统为客户制定和评估个性化的健身计划。
应用场景4:健身研究
健身研究机构可以使用这个系统进行计划评估和健身效果分析。
总结
健身计划评估系统是现代健身中的重要工具。通过KMP框架和OpenHarmony操作系统的结合,我们可以实现一个功能完整、高效可靠的计划评估系统。
这个工具不仅能够对健身计划进行多维度评分,还能够进行计划对比、生成健身建议、提供个性化的健身方案。通过本文介绍的Kotlin实现、JavaScript编译和ArkTS调用,健身爱好者可以快速构建自己的健身决策系统。
在实际应用中,健身计划评估的价值远不止于此。从提升训练效率到优化身体素质,从支持健身决策到促进健身产业发展,计划评估都发挥着重要的作用。通过持续改进和优化,可以构建更加科学和高效的健身评估体系。
掌握好健身计划评估的方法和工具,对于提升健身效果和实现健身目标都有重要的帮助。通过这个系统的学习和使用,希望能够帮助健身爱好者更好地了解自身情况,制定科学的健身计划,享受健身的快乐。欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
更多推荐
所有评论(0)