package service import ( "errors" "time" "health-ai/internal/model" "health-ai/internal/repository/impl" ) type HealthService struct { healthRepo *impl.HealthRepository constitutionRepo *impl.ConstitutionRepository userRepo *impl.UserRepositoryImpl } func NewHealthService() *HealthService { return &HealthService{ healthRepo: impl.NewHealthRepository(), constitutionRepo: impl.NewConstitutionRepository(), userRepo: impl.NewUserRepository(), } } // ================= 响应结构体 ================= // HealthProfileResponse 健康档案响应 type HealthProfileResponse struct { Profile *model.HealthProfile `json:"profile"` Lifestyle *model.LifestyleInfo `json:"lifestyle"` MedicalHistory []model.MedicalHistory `json:"medical_history"` FamilyHistory []model.FamilyHistory `json:"family_history"` AllergyRecords []model.AllergyRecord `json:"allergy_records"` Constitution *ConstitutionScore `json:"constitution,omitempty"` } // ================= Service 方法 ================= // GetHealthProfile 获取完整健康档案 func (s *HealthService) GetHealthProfile(userID uint) (*HealthProfileResponse, error) { resp := &HealthProfileResponse{} // 获取基础档案 profile, err := s.healthRepo.GetProfileByUserID(userID) if err == nil && profile.ID > 0 { resp.Profile = profile } // 获取生活习惯 lifestyle, err := s.healthRepo.GetLifestyleByUserID(userID) if err == nil && lifestyle.ID > 0 { resp.Lifestyle = lifestyle } // 获取病史 if profile != nil && profile.ID > 0 { resp.MedicalHistory, _ = s.healthRepo.GetMedicalHistories(profile.ID) resp.FamilyHistory, _ = s.healthRepo.GetFamilyHistories(profile.ID) resp.AllergyRecords, _ = s.healthRepo.GetAllergyRecords(profile.ID) } // 获取最新体质信息 constitution, err := s.constitutionRepo.GetLatestAssessment(userID) if err == nil && constitution.ID > 0 { resp.Constitution = &ConstitutionScore{ Type: constitution.PrimaryConstitution, Name: model.ConstitutionNames[constitution.PrimaryConstitution], Description: model.ConstitutionDescriptions[constitution.PrimaryConstitution], } } return resp, nil } // GetBasicProfile 获取基础档案 func (s *HealthService) GetBasicProfile(userID uint) (*model.HealthProfile, error) { profile, err := s.healthRepo.GetProfileByUserID(userID) if err != nil { return nil, errors.New("健康档案不存在") } return profile, nil } // GetLifestyle 获取生活习惯 func (s *HealthService) GetLifestyle(userID uint) (*model.LifestyleInfo, error) { lifestyle, err := s.healthRepo.GetLifestyleByUserID(userID) if err != nil { return nil, errors.New("生活习惯信息不存在") } return lifestyle, nil } // GetMedicalHistory 获取病史列表 func (s *HealthService) GetMedicalHistory(userID uint) ([]model.MedicalHistory, error) { profile, err := s.healthRepo.GetProfileByUserID(userID) if err != nil { return nil, errors.New("请先填写基础信息") } return s.healthRepo.GetMedicalHistories(profile.ID) } // GetFamilyHistory 获取家族病史列表 func (s *HealthService) GetFamilyHistory(userID uint) ([]model.FamilyHistory, error) { profile, err := s.healthRepo.GetProfileByUserID(userID) if err != nil { return nil, errors.New("请先填写基础信息") } return s.healthRepo.GetFamilyHistories(profile.ID) } // GetAllergyRecords 获取过敏记录列表 func (s *HealthService) GetAllergyRecords(userID uint) ([]model.AllergyRecord, error) { profile, err := s.healthRepo.GetProfileByUserID(userID) if err != nil { return nil, errors.New("请先填写基础信息") } return s.healthRepo.GetAllergyRecords(profile.ID) } // DeleteMedicalHistory 删除病史记录 func (s *HealthService) DeleteMedicalHistory(userID, historyID uint) error { // TODO: 验证记录属于该用户 return s.healthRepo.DeleteMedicalHistory(historyID) } // DeleteFamilyHistory 删除家族病史记录 func (s *HealthService) DeleteFamilyHistory(userID, historyID uint) error { // TODO: 验证记录属于该用户 return s.healthRepo.DeleteFamilyHistory(historyID) } // DeleteAllergyRecord 删除过敏记录 func (s *HealthService) DeleteAllergyRecord(userID, recordID uint) error { // TODO: 验证记录属于该用户 return s.healthRepo.DeleteAllergyRecord(recordID) } // ================= 更新请求结构体 ================= // UpdateHealthProfileInput 更新健康档案输入 type UpdateHealthProfileInput struct { Name string BirthDate string Gender string Height float64 Weight float64 BloodType string Occupation string MaritalStatus string Region string } // UpdateLifestyleInput 更新生活习惯输入 type UpdateLifestyleInput struct { SleepTime string WakeTime string SleepQuality string MealRegularity string DietPreference string DailyWaterML int ExerciseFrequency string ExerciseType string ExerciseDurationMin int IsSmoker *bool // 使用指针以区分未设置和false AlcoholFrequency string } // UpdateHealthProfile 更新健康档案 func (s *HealthService) UpdateHealthProfile(userID uint, input *UpdateHealthProfileInput) (*model.HealthProfile, error) { // 获取或创建健康档案 profile, err := s.healthRepo.GetProfileByUserID(userID) if err != nil { // 创建新档案 profile = &model.HealthProfile{ UserID: userID, } } // 更新字段(只更新非空值) if input.Name != "" { profile.Name = input.Name } if input.BirthDate != "" { // 解析日期字符串 parsedDate, err := time.Parse("2006-01-02", input.BirthDate) if err == nil { profile.BirthDate = &parsedDate } } if input.Gender != "" { profile.Gender = input.Gender } if input.Height > 0 { profile.Height = input.Height } if input.Weight > 0 { profile.Weight = input.Weight // 计算BMI if profile.Height > 0 { heightM := profile.Height / 100 profile.BMI = profile.Weight / (heightM * heightM) } } if input.BloodType != "" { profile.BloodType = input.BloodType } if input.Occupation != "" { profile.Occupation = input.Occupation } if input.MaritalStatus != "" { profile.MaritalStatus = input.MaritalStatus } if input.Region != "" { profile.Region = input.Region } // 保存或更新 if profile.ID == 0 { if err := s.healthRepo.CreateProfile(profile); err != nil { return nil, err } } else { if err := s.healthRepo.UpdateProfile(profile); err != nil { return nil, err } } return profile, nil } // UpdateLifestyle 更新生活习惯 func (s *HealthService) UpdateLifestyle(userID uint, input *UpdateLifestyleInput) (*model.LifestyleInfo, error) { // 获取或创建生活习惯记录 lifestyle, err := s.healthRepo.GetLifestyleByUserID(userID) if err != nil { // 创建新记录 lifestyle = &model.LifestyleInfo{ UserID: userID, } } // 更新字段(只更新非空值) if input.SleepTime != "" { lifestyle.SleepTime = input.SleepTime } if input.WakeTime != "" { lifestyle.WakeTime = input.WakeTime } if input.SleepQuality != "" { lifestyle.SleepQuality = input.SleepQuality } if input.MealRegularity != "" { lifestyle.MealRegularity = input.MealRegularity } if input.DietPreference != "" { lifestyle.DietPreference = input.DietPreference } if input.DailyWaterML > 0 { lifestyle.DailyWaterML = input.DailyWaterML } if input.ExerciseFrequency != "" { lifestyle.ExerciseFrequency = input.ExerciseFrequency } if input.ExerciseType != "" { lifestyle.ExerciseType = input.ExerciseType } if input.ExerciseDurationMin > 0 { lifestyle.ExerciseDurationMin = input.ExerciseDurationMin } if input.IsSmoker != nil { lifestyle.IsSmoker = *input.IsSmoker } if input.AlcoholFrequency != "" { lifestyle.AlcoholFrequency = input.AlcoholFrequency } // 保存或更新 if lifestyle.ID == 0 { if err := s.healthRepo.CreateLifestyle(lifestyle); err != nil { return nil, err } } else { if err := s.healthRepo.UpdateLifestyle(lifestyle); err != nil { return nil, err } } return lifestyle, nil }