You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
SmartGymManagementSystem/TrainingPlanService.java

296 lines
13 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package com.gym.service;
import com.gym.model.TrainingPlan;
import com.gym.model.User;
import com.gym.repository.TrainingPlanRepository;
import com.gym.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Optional;
// 需要导入的包
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
@Service
public class TrainingPlanService {
@Autowired
private TrainingPlanRepository trainingPlanRepository;
@Autowired
private UserRepository userRepository;
// 创建训练计划
public TrainingPlan createPlan(TrainingPlan plan, Long memberId, Long coachId) {
// 验证会员是否存在
User member = userRepository.findById(memberId)
.orElseThrow(() -> new RuntimeException("会员不存在"));
// 验证教练是否存在
User coach = userRepository.findById(coachId)
.orElseThrow(() -> new RuntimeException("教练不存在"));
// 验证角色
if (!"MEMBER".equals(member.getRole())) {
throw new RuntimeException("该用户不是会员");
}
if (!"COACH".equals(coach.getRole())) {
throw new RuntimeException("该用户不是教练");
}
plan.setMember(member);
plan.setCoach(coach);
plan.setCompletedDays(0);
plan.setProgress(0.0);
plan.setStatus("ACTIVE");
plan.setCreateTime(LocalDateTime.now());
plan.setUpdateTime(LocalDateTime.now());
// 如果提供了开始和结束日期,计算周期
if (plan.getStartDate() != null && plan.getEndDate() != null) {
long days = ChronoUnit.DAYS.between(plan.getStartDate(), plan.getEndDate());
plan.setDurationWeeks((int) (days / 7));
}
return trainingPlanRepository.save(plan);
}
// 获取所有训练计划
public List<TrainingPlan> getAllPlans() {
return trainingPlanRepository.findAll();
}
// 根据ID获取训练计划
public Optional<TrainingPlan> getPlanById(Long id) {
return trainingPlanRepository.findById(id);
}
// 获取会员的训练计划
public List<TrainingPlan> getMemberPlans(Long memberId) {
return trainingPlanRepository.findByMemberId(memberId);
}
// 获取教练制定的训练计划
public List<TrainingPlan> getCoachPlans(Long coachId) {
return trainingPlanRepository.findByCoachId(coachId);
}
// 获取活跃的训练计划
public List<TrainingPlan> getActivePlansByMember(Long memberId) {
return trainingPlanRepository.findActivePlansByMember(memberId);
}
// 更新训练计划
public TrainingPlan updatePlan(Long id, TrainingPlan updatedPlan) {
return trainingPlanRepository.findById(id)
.map(plan -> {
if (updatedPlan.getGoal() != null) {
plan.setGoal(updatedPlan.getGoal());
}
if (updatedPlan.getDailyPlan() != null) {
plan.setDailyPlan(updatedPlan.getDailyPlan());
}
if (updatedPlan.getDietAdvice() != null) {
plan.setDietAdvice(updatedPlan.getDietAdvice());
}
if (updatedPlan.getTrainingContent() != null) {
plan.setTrainingContent(updatedPlan.getTrainingContent());
}
if (updatedPlan.getRestDays() != null) {
plan.setRestDays(updatedPlan.getRestDays());
}
if (updatedPlan.getDifficultyLevel() != null) {
plan.setDifficultyLevel(updatedPlan.getDifficultyLevel());
}
if (updatedPlan.getWarmupSuggestions() != null) {
plan.setWarmupSuggestions(updatedPlan.getWarmupSuggestions());
}
if (updatedPlan.getCooldownSuggestions() != null) {
plan.setCooldownSuggestions(updatedPlan.getCooldownSuggestions());
}
if (updatedPlan.getPrecautions() != null) {
plan.setPrecautions(updatedPlan.getPrecautions());
}
plan.setUpdateTime(LocalDateTime.now());
return trainingPlanRepository.save(plan);
})
.orElseThrow(() -> new RuntimeException("训练计划不存在"));
}
// 更新训练进度
public TrainingPlan updateProgress(Long id, Integer completedDays) {
return trainingPlanRepository.findById(id)
.map(plan -> {
plan.setCompletedDays(completedDays);
// 计算进度
if (plan.getDurationWeeks() != null && plan.getDurationWeeks() > 0) {
int totalDays = plan.getDurationWeeks() * 7;
double progress = (double) completedDays / totalDays * 100;
plan.setProgress(Math.min(progress, 100.0));
// 如果进度达到100%,标记为完成
if (progress >= 100) {
plan.setStatus("COMPLETED");
}
}
plan.setUpdateTime(LocalDateTime.now());
return trainingPlanRepository.save(plan);
})
.orElseThrow(() -> new RuntimeException("训练计划不存在"));
}
// 标记为完成
public TrainingPlan markAsCompleted(Long id) {
return trainingPlanRepository.findById(id)
.map(plan -> {
plan.setStatus("COMPLETED");
plan.setProgress(100.0);
plan.setUpdateTime(LocalDateTime.now());
return trainingPlanRepository.save(plan);
})
.orElseThrow(() -> new RuntimeException("训练计划不存在"));
}
// 暂停训练计划
public TrainingPlan pausePlan(Long id) {
return trainingPlanRepository.findById(id)
.map(plan -> {
plan.setStatus("PAUSED");
plan.setUpdateTime(LocalDateTime.now());
return trainingPlanRepository.save(plan);
})
.orElseThrow(() -> new RuntimeException("训练计划不存在"));
}
// 恢复训练计划
public TrainingPlan resumePlan(Long id) {
return trainingPlanRepository.findById(id)
.map(plan -> {
plan.setStatus("ACTIVE");
plan.setUpdateTime(LocalDateTime.now());
return trainingPlanRepository.save(plan);
})
.orElseThrow(() -> new RuntimeException("训练计划不存在"));
}
// AI训练推荐基于简单规则
public String recommendTraining(User member) {
String goal = member.getFitnessGoal();
Double weight = member.getWeight();
Double height = member.getHeight();
Integer age = member.getAge();
if (goal == null) {
goal = "保持健康";
}
StringBuilder recommendation = new StringBuilder();
recommendation.append("💪 基于您的信息,推荐训练计划:\n\n");
// 计算BMI
if (height != null && weight != null && height > 0) {
double bmi = weight / ((height / 100) * (height / 100));
recommendation.append("📊 您的BMI: ").append(String.format("%.1f", bmi)).append("\n");
if (bmi < 18.5) {
recommendation.append("⚠️ 体重偏轻,建议增加肌肉训练\n");
} else if (bmi > 24) {
recommendation.append("⚠️ 体重偏重,建议增加有氧运动\n");
}
}
// 基于目标推荐
switch (goal.toLowerCase()) {
case "减脂":
recommendation.append("🎯 目标:减脂\n");
recommendation.append("🏃 训练建议:\n");
recommendation.append(" • 每周4-5次有氧运动跑步、游泳、动感单车\n");
recommendation.append(" • 每次45-60分钟\n");
recommendation.append(" • 心率保持在120-150次/分钟\n");
recommendation.append(" • 配合力量训练每周2-3次\n");
recommendation.append("🍎 饮食建议:\n");
recommendation.append(" • 控制碳水化合物摄入\n");
recommendation.append(" • 增加蛋白质摄入\n");
recommendation.append(" • 多喝水,少喝含糖饮料\n");
break;
case "增肌":
recommendation.append("🎯 目标:增肌\n");
recommendation.append("🏋️ 训练建议:\n");
recommendation.append(" • 每周4-5次力量训练\n");
recommendation.append(" • 重点训练:卧推、深蹲、硬拉、引体向上\n");
recommendation.append(" • 每组8-12次每个动作3-4组\n");
recommendation.append(" • 组间休息60-90秒\n");
recommendation.append("🍗 饮食建议:\n");
recommendation.append(" • 增加蛋白质摄入体重×1.5-2克/天)\n");
recommendation.append(" • 适量碳水化合物提供能量\n");
recommendation.append(" • 训练后30分钟内补充蛋白质\n");
break;
case "塑形":
recommendation.append("🎯 目标:塑形\n");
recommendation.append("🤸 训练建议:\n");
recommendation.append(" • 每周3-4次全身训练\n");
recommendation.append(" • 结合力量和有氧训练\n");
recommendation.append(" • 重点:核心训练、臀部训练\n");
recommendation.append(" • 每组12-15次中等重量\n");
recommendation.append("🥗 饮食建议:\n");
recommendation.append(" • 均衡饮食,控制总热量\n");
recommendation.append(" • 多吃蔬菜水果\n");
recommendation.append(" • 减少加工食品\n");
break;
default:
recommendation.append("🎯 目标:保持健康\n");
recommendation.append("🏃 训练建议:\n");
recommendation.append(" • 每周3-4次运动\n");
recommendation.append(" • 每次30-45分钟\n");
recommendation.append(" • 结合有氧和力量训练\n");
recommendation.append(" • 保持中等强度\n");
recommendation.append("🥦 饮食建议:\n");
recommendation.append(" • 均衡营养,多样化饮食\n");
recommendation.append(" • 控制盐、糖、油摄入\n");
recommendation.append(" • 每天喝足水\n");
}
return recommendation.toString();
}
// 获取统计数据
public Map<String, Object> getStats(Long memberId) {
Map<String, Object> stats = new HashMap<>();
List<TrainingPlan> allPlans = trainingPlanRepository.findByMemberId(memberId);
List<TrainingPlan> activePlans = trainingPlanRepository.findActivePlansByMember(memberId);
Long completedCount = trainingPlanRepository.countCompletedPlansByMember(memberId);
stats.put("totalPlans", allPlans.size());
stats.put("activePlans", activePlans.size());
stats.put("completedPlans", completedCount);
// 计算平均进度
double avgProgress = allPlans.stream()
.mapToDouble(TrainingPlan::getProgress)
.average()
.orElse(0.0);
stats.put("averageProgress", String.format("%.1f%%", avgProgress));
// 按目标分类统计
Map<String, Long> goalStats = allPlans.stream()
.collect(Collectors.groupingBy(TrainingPlan::getGoal, Collectors.counting()));
stats.put("goalDistribution", goalStats);
return stats;
}
}