healthapp
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.
 
 
 
 
 
 

289 lines
8.0 KiB

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
}