diff --git a/user-service/build.gradle b/user-service/build.gradle index 6889f5ea..175cc031 100644 --- a/user-service/build.gradle +++ b/user-service/build.gradle @@ -84,7 +84,6 @@ dependencies { implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.1.0' implementation 'org.springdoc:springdoc-openapi-starter-webmvc-api:2.1.0' - } dependencyManagement { diff --git a/user-service/src/main/java/com/waither/userservice/controller/SettingController.java b/user-service/src/main/java/com/waither/userservice/controller/SettingController.java index cf4f64a9..5f55849d 100644 --- a/user-service/src/main/java/com/waither/userservice/controller/SettingController.java +++ b/user-service/src/main/java/com/waither/userservice/controller/SettingController.java @@ -33,7 +33,7 @@ public ApiResponse getRegion(@AuthUser User user) { return ApiResponse.onSuccess(settingQueryService.getRegion(user)); } - // 알림 설정 조회 +// // 알림 설정 조회 @GetMapping("/noti") public ApiResponse getNotification(@AuthUser User user) { return ApiResponse.onSuccess(settingQueryService.getNotification(user)); @@ -68,45 +68,51 @@ public ApiResponse getUserInfo(@AuthUser User user) { // 사용자 맞춤 서비스 제공 @PutMapping("/custom") public ApiResponse updateCustom(@AuthUser User user, @RequestBody SettingReqDto.CustomDto customDto) { - settingService.updateBooleanSetting(user, "CUSTOM", customDto.custom()); - return ApiResponse.onSuccess("사용자 맞춤 서비스 제공이 " + customDto.custom() + "로 바뀌었습니다."); + settingService.updateCustom(user, customDto); + return ApiResponse.onSuccess("설정값 변경이 완료되었습니다."); + } + + // 메인 화면 날씨 상세 정보 보기 (강수량, 퓽향/풍속, 미세먼지) + @PatchMapping("/display") + public ApiResponse updateDisplay(@AuthUser User user, @RequestBody SettingReqDto.DisplayDto displayDto) { + settingService.updateDisplay(user, displayDto); + return ApiResponse.onSuccess( + "설정값 변경이 완료되었습니다."); } // 외출 알림 설정 @PutMapping("/noti/out-alert") public ApiResponse updateOutAlert(@AuthUser User user, @RequestBody SettingReqDto.OutAlertDto outAlertDto) { - settingService.updateBooleanSetting(user, "OUT_ALERT" , outAlertDto.outAlert()); - return ApiResponse.onSuccess("외출 알림 설정이 " + outAlertDto.outAlert() + "로 바뀌었습니다."); + settingService.updateOutAlert(user, outAlertDto); + return ApiResponse.onSuccess("설정값 변경이 완료되었습니다."); } // 알림 설정 (요일 & 시간) @PutMapping("/noti/out-alert-set") public ApiResponse updateOutAlertSet(@AuthUser User user, @RequestBody SettingReqDto.OutAlertSetDto outAlertSetDto) { settingService.updateOutAlertSet(user, outAlertSetDto); - return ApiResponse.onSuccess( - outAlertSetDto.days() + "요일, " - + outAlertSetDto.outTime() + "시로 알림 설정이 바뀌었습니다."); + return ApiResponse.onSuccess("설정값 변경이 완료되었습니다."); } // 기상 특보 알림 설정 @PutMapping("/noti/climate-alert") public ApiResponse updateClimateAlert(@AuthUser User user, @RequestBody SettingReqDto.ClimateAlertDto climateAlertDto) { - settingService.updateBooleanSetting(user, "CUSTOM", climateAlertDto.climateAlert()); - return ApiResponse.onSuccess("기상 특보 알림 설정이 " + climateAlertDto.climateAlert() + "로 바뀌었습니다."); + settingService.updateClimateAlert(user, climateAlertDto); + return ApiResponse.onSuccess("설정값 변경이 완료되었습니다."); } // 사용자 맞춤 예보 설정 @PutMapping("/noti/user-alert") public ApiResponse updateUserAlert(@AuthUser User user, @RequestBody SettingReqDto.UserAlertDto userAlertDto) { - settingService.updateBooleanSetting(user, "USER_ALERT", userAlertDto.userAlert()); - return ApiResponse.onSuccess("사용자 맞춤 예보 설정이 " + userAlertDto.userAlert() + "로 바뀌었습니다."); + settingService.updateUserAlert(user, userAlertDto); + return ApiResponse.onSuccess("설정값 변경이 완료되었습니다."); } // 강설 정보 알림 설정 @PutMapping("/noti/snow-alert") public ApiResponse updateSnowAlert(@AuthUser User user, @RequestBody SettingReqDto.SnowAlertDto snowAlertDto) { - settingService.updateBooleanSetting(user, "SNOW_ALERT", snowAlertDto.snowAlert()); - return ApiResponse.onSuccess("강설 정보 알림 설정이 " + snowAlertDto.snowAlert() + "로 바뀌었습니다."); + settingService.updateSnowAlert(user, snowAlertDto); + return ApiResponse.onSuccess("설정값 변경이 완료되었습니다."); } // 바람 세기 알림 @@ -114,40 +120,28 @@ public ApiResponse updateSnowAlert(@AuthUser User user, @RequestBody Set public ApiResponse updateWind(@AuthUser User user, @RequestBody SettingReqDto.WindDto windDto) { settingService.updateWind(user, windDto); return ApiResponse.onSuccess( - "바람 세기 알림 설정이 " + windDto.windAlert() + "로 바뀌었습니다. " - + "강도는 " + windDto.windDegree() + " m/s 이상 일 때 알림이 발송 됩니다."); + "설정값 변경이 완료되었습니다."); } - // 메인 화면 날씨 상세 정보 보기 (강수량, 퓽향/풍속, 미세먼지) - @PutMapping("/display") - public ApiResponse updateDisplay(@AuthUser User user, @RequestBody SettingReqDto.DisplayDto displayDto) { - settingService.updateDisplay(user, displayDto); - return ApiResponse.onSuccess( - "강수량 보기는 " + displayDto.precipitation() + "로, " - + "풍향/풍속 보기는 " + displayDto.wind() + "로, " - + "미세먼지 보기는 " + displayDto.dust() + "로 " - + "설정되었습니다."); + // 직장 지역 레포트 알림 받기 + @PutMapping("/region-report") + public ApiResponse updateRegionReport(@AuthUser User user, @RequestBody SettingReqDto.RegionReportDto regionReportDto) { + settingService.updateRegionReport(user, regionReportDto); + return ApiResponse.onSuccess("설정값 변경이 완료되었습니다."); } // 직장 지역 설정 @PutMapping("/region") public ApiResponse updateRegion(@AuthUser User user, @RequestBody SettingReqDto.RegionDto regionDto) { settingService.updateRegion(user, regionDto); - return ApiResponse.onSuccess("직장 지역 설정이 " + regionDto.regionName() + "로 바뀌었습니다."); - } - - // 직장 지역 레포트 알림 받기 - @PutMapping("/region-report") - public ApiResponse updateRegionReport(@AuthUser User user, @RequestBody SettingReqDto.RegionReportDto regionReportDto) { - settingService.updateBooleanSetting(user, "REGION_REPORT", regionReportDto.regionReport()); - return ApiResponse.onSuccess("직장 지역 레포트 알림 설정이 " + regionReportDto.regionReport() + "로 바뀌었습니다."); + return ApiResponse.onSuccess("설정값 변경이 완료되었습니다."); } // 사용자 가중치 설정 @PutMapping("/user-weight") public ApiResponse updateWeight(@AuthUser User user, @RequestBody SettingReqDto.WeightDto weightDto) { settingService.updateWeight(user, weightDto); - return ApiResponse.onSuccess("사용자 가중치가 " + weightDto.weight() + "로 바뀌었습니다."); + return ApiResponse.onSuccess("설정값 변경이 완료되었습니다."); } } diff --git a/user-service/src/main/java/com/waither/userservice/controller/SurveyController.java b/user-service/src/main/java/com/waither/userservice/controller/SurveyController.java index 42e5834a..803564eb 100644 --- a/user-service/src/main/java/com/waither/userservice/controller/SurveyController.java +++ b/user-service/src/main/java/com/waither/userservice/controller/SurveyController.java @@ -4,7 +4,6 @@ import com.waither.userservice.entity.User; import com.waither.userservice.global.annotation.AuthUser; import com.waither.userservice.global.response.ApiResponse; -import com.waither.userservice.service.queryService.SurveyQueryService; import com.waither.userservice.service.commandService.SurveyService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -17,12 +16,16 @@ public class SurveyController { private final SurveyService surveyService; - private final SurveyQueryService surveyQueryService; - @PostMapping("/submit") public ApiResponse createSurvey(@AuthUser User user, @RequestBody SurveyReqDto.SurveyRequestDto surveyRequestDto) { surveyService.createSurvey(user, surveyRequestDto); return ApiResponse.onSuccess("survey 생성완료"); } +// @PostMapping("/reset") +// public ApiResponse resetServeyData(@AuthUser User user) { +// surveyService.resetSurveyData(user); +// return ApiResponse.onSuccess("사용자의 설문 정보를 초기화 하였습니다."); +// } + } diff --git a/user-service/src/main/java/com/waither/userservice/converter/RegionConverter.java b/user-service/src/main/java/com/waither/userservice/converter/RegionConverter.java index 46b530f9..0dbffd99 100644 --- a/user-service/src/main/java/com/waither/userservice/converter/RegionConverter.java +++ b/user-service/src/main/java/com/waither/userservice/converter/RegionConverter.java @@ -1,7 +1,11 @@ package com.waither.userservice.converter; import com.waither.userservice.entity.Region; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import lombok.experimental.UtilityClass; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public class RegionConverter { // Region 기본값으로 설정 diff --git a/user-service/src/main/java/com/waither/userservice/converter/SettingConverter.java b/user-service/src/main/java/com/waither/userservice/converter/SettingConverter.java index f4a7c24e..84e765d9 100644 --- a/user-service/src/main/java/com/waither/userservice/converter/SettingConverter.java +++ b/user-service/src/main/java/com/waither/userservice/converter/SettingConverter.java @@ -4,6 +4,9 @@ import com.waither.userservice.entity.Region; import com.waither.userservice.entity.Setting; import com.waither.userservice.entity.User; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import lombok.experimental.UtilityClass; import java.time.DayOfWeek; import java.util.AbstractMap; @@ -11,7 +14,7 @@ import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; - +@NoArgsConstructor(access = AccessLevel.PRIVATE) public class SettingConverter { // Setting을 기본값으로 설정 @@ -40,18 +43,9 @@ public static SettingResDto.RegionNameDto toRegionNameDto(Setting setting) { } public static SettingResDto.NotificationDto toNotificationDto(Setting setting) { - List days = Stream.of( - new AbstractMap.SimpleEntry<>(DayOfWeek.SUNDAY, setting.isSun()), - new AbstractMap.SimpleEntry<>(DayOfWeek.MONDAY, setting.isMon()), - new AbstractMap.SimpleEntry<>(DayOfWeek.TUESDAY, setting.isTue()), - new AbstractMap.SimpleEntry<>(DayOfWeek.WEDNESDAY, setting.isWed()), - new AbstractMap.SimpleEntry<>(DayOfWeek.THURSDAY, setting.isThu()), - new AbstractMap.SimpleEntry<>(DayOfWeek.FRIDAY, setting.isFri()), - new AbstractMap.SimpleEntry<>(DayOfWeek.SATURDAY, setting.isSat()) - ) - .filter(Map.Entry::getValue) - .map(entry -> entry.getKey().toString()) - .collect(Collectors.toList()); + List days = setting.getDays().stream() + .map(Enum::toString) + .toList(); return new SettingResDto.NotificationDto( setting.isOutAlert(), diff --git a/user-service/src/main/java/com/waither/userservice/converter/SurveyConverter.java b/user-service/src/main/java/com/waither/userservice/converter/SurveyConverter.java index dc1f19e7..d76a0107 100644 --- a/user-service/src/main/java/com/waither/userservice/converter/SurveyConverter.java +++ b/user-service/src/main/java/com/waither/userservice/converter/SurveyConverter.java @@ -2,12 +2,17 @@ import com.waither.userservice.dto.request.SurveyReqDto; import com.waither.userservice.entity.*; -import com.waither.userservice.entity.type.Season; +import com.waither.userservice.entity.enums.Season; import com.waither.userservice.global.exception.CustomException; import com.waither.userservice.global.response.ErrorCode; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import lombok.experimental.UtilityClass; -import static com.waither.userservice.service.commandService.SurveyService.calculateMedian; +import static com.waither.userservice.util.CalculateUtil.calculateMedian; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) public class SurveyConverter { // UserData 기본값으로 설정 diff --git a/user-service/src/main/java/com/waither/userservice/converter/UserConverter.java b/user-service/src/main/java/com/waither/userservice/converter/UserConverter.java index 621ec5bb..0971c582 100644 --- a/user-service/src/main/java/com/waither/userservice/converter/UserConverter.java +++ b/user-service/src/main/java/com/waither/userservice/converter/UserConverter.java @@ -2,9 +2,13 @@ import com.waither.userservice.dto.request.UserReqDto; import com.waither.userservice.entity.User; -import com.waither.userservice.entity.type.UserStatus; +import com.waither.userservice.entity.enums.UserStatus; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import lombok.experimental.UtilityClass; import org.springframework.security.crypto.password.PasswordEncoder; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public class UserConverter { public static User toUser(UserReqDto.SignUpRequestDto requestDto, PasswordEncoder passwordEncoder) { diff --git a/user-service/src/main/java/com/waither/userservice/dto/request/SettingReqDto.java b/user-service/src/main/java/com/waither/userservice/dto/request/SettingReqDto.java index 04a1f1fc..678807ff 100644 --- a/user-service/src/main/java/com/waither/userservice/dto/request/SettingReqDto.java +++ b/user-service/src/main/java/com/waither/userservice/dto/request/SettingReqDto.java @@ -31,14 +31,14 @@ public record SnowAlertDto( ) { } public record WindDto( - boolean windAlert, + Boolean windAlert, Integer windDegree ) { } public record DisplayDto( - boolean precipitation, - boolean wind, - boolean dust + Boolean precipitation, + Boolean wind, + Boolean dust ) {} public record RegionDto( diff --git a/user-service/src/main/java/com/waither/userservice/dto/response/SettingResDto.java b/user-service/src/main/java/com/waither/userservice/dto/response/SettingResDto.java index 4cbb54f3..2e6f7d26 100644 --- a/user-service/src/main/java/com/waither/userservice/dto/response/SettingResDto.java +++ b/user-service/src/main/java/com/waither/userservice/dto/response/SettingResDto.java @@ -28,9 +28,9 @@ public record WindDto( ) { } public record DisplayDto( - boolean rainfallDisplay, - boolean windDisplay, - boolean dustDisplay + boolean precipitation, + boolean wind, + boolean dust ) { } public record WeightDto( diff --git a/user-service/src/main/java/com/waither/userservice/entity/Setting.java b/user-service/src/main/java/com/waither/userservice/entity/Setting.java index 94fb5826..b78b690a 100644 --- a/user-service/src/main/java/com/waither/userservice/entity/Setting.java +++ b/user-service/src/main/java/com/waither/userservice/entity/Setting.java @@ -2,7 +2,11 @@ import com.waither.userservice.global.BaseEntity; import jakarta.persistence.*; + +import java.time.DayOfWeek; import java.time.LocalTime; +import java.util.HashSet; +import java.util.Set; import lombok.*; import org.hibernate.annotations.DynamicInsert; @@ -35,20 +39,11 @@ public class Setting extends BaseEntity { private LocalTime outTime; // 월 ~ 금 알림 - @Column(name = "sun", nullable = false) - private boolean sun; - @Column(name = "mon", nullable = false) - private boolean mon; - @Column(name = "tue", nullable = false) - private boolean tue; - @Column(name = "wed", nullable = false) - private boolean wed; - @Column(name = "thu", nullable = false) - private boolean thu; - @Column(name = "fri", nullable = false) - private boolean fri; - @Column(name = "sat", nullable = false) - private boolean sat; + @ElementCollection + @CollectionTable(name = "setting_days", joinColumns = @JoinColumn(name = "setting_id")) + @Column(name = "day") + @Enumerated(EnumType.STRING) + private Set days = new HashSet<>(); // 기상 특보 알림 @Column(name = "climateAlert", nullable = false) @@ -76,11 +71,9 @@ public class Setting extends BaseEntity { // 강수량 보기 @Column(name = "precipitation", nullable = false) private boolean precipitation; - // 풍량/풍속 보기 @Column(name = "wind", nullable = false) private boolean wind; - // 미세먼지 보기 @Column(name = "dust", nullable = false) private boolean dust; diff --git a/user-service/src/main/java/com/waither/userservice/entity/Survey.java b/user-service/src/main/java/com/waither/userservice/entity/Survey.java index a31a4409..ed443dca 100644 --- a/user-service/src/main/java/com/waither/userservice/entity/Survey.java +++ b/user-service/src/main/java/com/waither/userservice/entity/Survey.java @@ -1,12 +1,11 @@ package com.waither.userservice.entity; -import com.waither.userservice.entity.type.Season; +import com.waither.userservice.entity.enums.Season; import com.waither.userservice.global.BaseEntity; import jakarta.persistence.*; import lombok.*; import java.time.LocalDateTime; -import java.time.LocalTime; @Builder @Getter diff --git a/user-service/src/main/java/com/waither/userservice/entity/User.java b/user-service/src/main/java/com/waither/userservice/entity/User.java index ac52d455..04f3e53d 100644 --- a/user-service/src/main/java/com/waither/userservice/entity/User.java +++ b/user-service/src/main/java/com/waither/userservice/entity/User.java @@ -1,6 +1,6 @@ package com.waither.userservice.entity; -import com.waither.userservice.entity.type.UserStatus; +import com.waither.userservice.entity.enums.UserStatus; import com.waither.userservice.global.BaseEntity; import jakarta.persistence.*; import lombok.*; @@ -80,11 +80,11 @@ public void setSetting(Setting setSetting) { setting = setSetting; } - public void setUserData(List userData) { + public void setUserData(List userData) { UserData = userData; } - public void setUserMedian(List userMedian) { + public void setUserMedian(List userMedian) { UserMedian = userMedian; } } diff --git a/user-service/src/main/java/com/waither/userservice/entity/UserData.java b/user-service/src/main/java/com/waither/userservice/entity/UserData.java index ad20eabc..d1b79bce 100644 --- a/user-service/src/main/java/com/waither/userservice/entity/UserData.java +++ b/user-service/src/main/java/com/waither/userservice/entity/UserData.java @@ -1,7 +1,9 @@ package com.waither.userservice.entity; -import com.waither.userservice.entity.type.Season; +import com.waither.userservice.entity.enums.Season; import com.waither.userservice.global.BaseEntity; +import com.waither.userservice.global.exception.CustomException; +import com.waither.userservice.global.response.ErrorCode; import jakarta.persistence.*; import lombok.*; @@ -35,4 +37,37 @@ public class UserData extends BaseEntity { public void setUser(User user) { this.user = user; } + public Double getLevel(int level) { + return switch (level) { + case 1 -> level1; + case 2 -> level2; + case 3 -> level3; + case 4 -> level4; + case 5 -> level5; + default -> throw new CustomException(ErrorCode.INVALID_LEVEL_VALUE); + }; + } + + public void updateLevelValue(int level, double newValue) { + switch (level) { + case 1: + this.level1 = newValue; + break; + case 2: + this.level2 = newValue; + break; + case 3: + this.level3 = newValue; + break; + case 4: + this.level4 = newValue; + break; + case 5: + this.level5 = newValue; + break; + default: + throw new CustomException(ErrorCode.INVALID_LEVEL_VALUE); + } + } + } \ No newline at end of file diff --git a/user-service/src/main/java/com/waither/userservice/entity/UserMedian.java b/user-service/src/main/java/com/waither/userservice/entity/UserMedian.java index cc6019c5..b6b5e869 100644 --- a/user-service/src/main/java/com/waither/userservice/entity/UserMedian.java +++ b/user-service/src/main/java/com/waither/userservice/entity/UserMedian.java @@ -1,10 +1,12 @@ package com.waither.userservice.entity; -import com.waither.userservice.entity.type.Season; +import com.waither.userservice.entity.enums.Season; import com.waither.userservice.global.BaseEntity; import jakarta.persistence.*; import lombok.*; +import static com.waither.userservice.util.CalculateUtil.calculateMedian; + @Builder @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -34,5 +36,13 @@ public class UserMedian extends BaseEntity { public void setUser(User user) { this.user = user; } + + public void updateMedianValue(UserData userData) { + this.medianOf1And2 = calculateMedian(userData.getLevel1(), userData.getLevel2()); + this.medianOf2And3 = calculateMedian(userData.getLevel2(), userData.getLevel3()); + this.medianOf3And4 = calculateMedian(userData.getLevel3(), userData.getLevel4()); + this.medianOf4And5 = calculateMedian(userData.getLevel4(), userData.getLevel5()); + } + } diff --git a/user-service/src/main/java/com/waither/userservice/entity/type/Season.java b/user-service/src/main/java/com/waither/userservice/entity/enums/Season.java similarity index 58% rename from user-service/src/main/java/com/waither/userservice/entity/type/Season.java rename to user-service/src/main/java/com/waither/userservice/entity/enums/Season.java index f1f48b15..66049d29 100644 --- a/user-service/src/main/java/com/waither/userservice/entity/type/Season.java +++ b/user-service/src/main/java/com/waither/userservice/entity/enums/Season.java @@ -1,4 +1,4 @@ -package com.waither.userservice.entity.type; +package com.waither.userservice.entity.enums; public enum Season { SPRING_AUTUMN, diff --git a/user-service/src/main/java/com/waither/userservice/entity/type/UserStatus.java b/user-service/src/main/java/com/waither/userservice/entity/enums/UserStatus.java similarity index 70% rename from user-service/src/main/java/com/waither/userservice/entity/type/UserStatus.java rename to user-service/src/main/java/com/waither/userservice/entity/enums/UserStatus.java index ced2ffe0..5ac566bb 100644 --- a/user-service/src/main/java/com/waither/userservice/entity/type/UserStatus.java +++ b/user-service/src/main/java/com/waither/userservice/entity/enums/UserStatus.java @@ -1,4 +1,4 @@ -package com.waither.userservice.entity.type; +package com.waither.userservice.entity.enums; public enum UserStatus { diff --git a/user-service/src/main/java/com/waither/userservice/global/jwt/userdetails/PrincipalDetailsService.java b/user-service/src/main/java/com/waither/userservice/global/jwt/userdetails/PrincipalDetailsService.java index c1bfce45..183121bb 100644 --- a/user-service/src/main/java/com/waither/userservice/global/jwt/userdetails/PrincipalDetailsService.java +++ b/user-service/src/main/java/com/waither/userservice/global/jwt/userdetails/PrincipalDetailsService.java @@ -1,6 +1,8 @@ package com.waither.userservice.global.jwt.userdetails; import com.waither.userservice.entity.User; +import com.waither.userservice.global.exception.CustomException; +import com.waither.userservice.global.response.ErrorCode; import com.waither.userservice.repository.UserRepository; import lombok.RequiredArgsConstructor; import org.springframework.security.core.userdetails.UserDetails; @@ -24,6 +26,6 @@ public UserDetails loadUserByUsername(String email) throws UsernameNotFoundExcep User user = userEntity.get(); return new PrincipalDetails(user.getEmail(),user.getPassword(), user.getRole()); } - throw new UsernameNotFoundException("사용자가 존재하지 않습니다."); + throw new CustomException(ErrorCode.USER_NOT_FOUND); } } \ No newline at end of file diff --git a/user-service/src/main/java/com/waither/userservice/global/response/ErrorCode.java b/user-service/src/main/java/com/waither/userservice/global/response/ErrorCode.java index 18c09b2f..b9e29d80 100644 --- a/user-service/src/main/java/com/waither/userservice/global/response/ErrorCode.java +++ b/user-service/src/main/java/com/waither/userservice/global/response/ErrorCode.java @@ -32,9 +32,9 @@ public enum ErrorCode implements BaseErrorCode { // 이메일 관련 에러 INVALID_CODE(HttpStatus.BAD_REQUEST, "EMAIL400_0", "인증번호가 일치하지 않아요. 다시 한 번 확인해주세요."), - INVALID_Account(HttpStatus.BAD_REQUEST, "EMAIL400_1", "인증되지 않은 이메일입니다."), - AUTH_CODE_EXPIRED(HttpStatus.BAD_REQUEST, "EMAIL400_1", "다시 인증 번호를 요청해주세요."), - VERIFIED_CHECK_EXPIRED(HttpStatus.BAD_REQUEST, "EMAIL400_1", "인증 완료 후 유효기간이 경과하였습니다. 다시 인증 번호를 요청해주세요."), + INVALID_ACCOUNT(HttpStatus.BAD_REQUEST, "EMAIL400_1", "인증되지 않은 이메일입니다."), + AUTH_CODE_EXPIRED(HttpStatus.BAD_REQUEST, "EMAIL400_2", "다시 인증 번호를 요청해주세요."), + VERIFIED_CHECK_EXPIRED(HttpStatus.BAD_REQUEST, "EMAIL400_3", "인증 완료 후 유효기간이 경과하였습니다. 다시 인증 번호를 요청해주세요."), UNABLE_TO_SEND_EMAIL(HttpStatus.INTERNAL_SERVER_ERROR, "EMAIL500_0", "이메일을 전송하는 도중, 에러가 발생했습니다."), NO_SUCH_ALGORITHM(HttpStatus.INTERNAL_SERVER_ERROR, "EMAIL500_1", "이메일 인증 코드를 생성할 수 없습니다."), @@ -48,10 +48,18 @@ public enum ErrorCode implements BaseErrorCode { USER_ALREADY_EXIST(HttpStatus.BAD_REQUEST, "USER400_6", "사용자가 이미 존재합니다."), // 세팅 관련 에러 - UNSUPPORTED_SETTING_TYPE(HttpStatus.BAD_REQUEST, "SETTING400_1", "body에 사용할 수 없는 setting key가 있습니다."), + INACTIVE_CUSTOM_SETTING(HttpStatus.BAD_REQUEST, "SETTING400_1" + , "사용자 맞춤 서비스 제공을 켜지 않으면 사용할 수 없는 기능입니다."), + INACTIVE_OUT_ALERT_SETTING(HttpStatus.BAD_REQUEST, "SETTING400_2" + , "외출 시간 알림 받기을 켜지 않으면 사용할 수 없는 기능입니다."), + OUT_TIME_NULL(HttpStatus.BAD_REQUEST, "SETTING400_3", "외출 시간이 지정되지 않았습니다."), // 설문 관련 에러 - INVALID_SEASON(HttpStatus.BAD_REQUEST, "SURVEY400_1", "정의되지 않은 계절입니다."); + INVALID_SEASON(HttpStatus.BAD_REQUEST, "SURVEY400_1", "정의되지 않은 계절입니다."), + NO_USER_DATA_FOUND(HttpStatus.BAD_REQUEST, "SURVEY400_2", "해당 사용자와 계절에 대한 UserData를 찾을 수 없습니다."), + NO_USER_MEDIAN_FOUND(HttpStatus.BAD_REQUEST, "SURVEY400_3", "해당 사용자와 계절에 대한 UserMedian을 찾을 수 없습니다."), + INVALID_LEVEL_VALUE(HttpStatus.BAD_REQUEST, "SURVEY400_4", "정의되지 않은 Level 입니다."), + IGNORE_SURVEY_ANSWER(HttpStatus.BAD_REQUEST, "SURVEY400_5", "상위 레벨보다 높거나 하위 레벨보다 낮은 값이 계산되었습니다. 답변을 무시합니다."); private final HttpStatus httpStatus; private final String code; diff --git a/user-service/src/main/java/com/waither/userservice/repository/UserDataRepository.java b/user-service/src/main/java/com/waither/userservice/repository/UserDataRepository.java index 2d2737c4..f99c21dc 100644 --- a/user-service/src/main/java/com/waither/userservice/repository/UserDataRepository.java +++ b/user-service/src/main/java/com/waither/userservice/repository/UserDataRepository.java @@ -1,7 +1,12 @@ package com.waither.userservice.repository; +import com.waither.userservice.entity.User; import com.waither.userservice.entity.UserData; +import com.waither.userservice.entity.enums.Season; import org.springframework.data.jpa.repository.JpaRepository; +import java.util.Optional; + public interface UserDataRepository extends JpaRepository { + Optional findByUserAndSeason(User user, Season season); } diff --git a/user-service/src/main/java/com/waither/userservice/repository/UserMedianRepository.java b/user-service/src/main/java/com/waither/userservice/repository/UserMedianRepository.java index 65094643..9092a90c 100644 --- a/user-service/src/main/java/com/waither/userservice/repository/UserMedianRepository.java +++ b/user-service/src/main/java/com/waither/userservice/repository/UserMedianRepository.java @@ -1,7 +1,14 @@ package com.waither.userservice.repository; +import com.waither.userservice.entity.User; +import com.waither.userservice.entity.UserData; import com.waither.userservice.entity.UserMedian; +import com.waither.userservice.entity.enums.Season; import org.springframework.data.jpa.repository.JpaRepository; +import java.util.Optional; + public interface UserMedianRepository extends JpaRepository { + Optional findByUserAndSeason(User user, Season season); + } diff --git a/user-service/src/main/java/com/waither/userservice/service/commandService/SettingService.java b/user-service/src/main/java/com/waither/userservice/service/commandService/SettingService.java index e5714cf7..81c226a9 100644 --- a/user-service/src/main/java/com/waither/userservice/service/commandService/SettingService.java +++ b/user-service/src/main/java/com/waither/userservice/service/commandService/SettingService.java @@ -10,6 +10,7 @@ import com.waither.userservice.global.response.ErrorCode; import com.waither.userservice.repository.RegionRepository; import com.waither.userservice.repository.SettingRepository; +import com.waither.userservice.repository.UserRepository; import org.springframework.transaction.annotation.Transactional; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -18,6 +19,8 @@ import java.time.DayOfWeek; import java.util.EnumSet; import java.util.List; +import java.util.Optional; +import java.util.Set; import java.util.stream.Collectors; @Slf4j @@ -26,105 +29,124 @@ @RequiredArgsConstructor public class SettingService { + private final UserRepository userRepository; private final SettingRepository settingRepository; private final RegionRepository regionRepository; - // 토글 설정 변경 - public void updateBooleanSetting(User user, String settingType, Boolean value) { + /* --------- Update --------- */ + + // 사용자 맞춤 서비스 제공 설정 변경 + public void updateCustom(User user, SettingReqDto.CustomDto customDto) { + user.setCustom(customDto.custom()); + userRepository.save(user); + } + + // 메인 화면 날씨 상세 정보 변경 + public void updateDisplay(User user, SettingReqDto.DisplayDto displayDto) { Setting setting = user.getSetting(); - switch (settingType) { - // 사용자 맞춤 서비스 제공 설정 변경 - case "CUSTOM": - user.setCustom(value); - break; - // 외출 알림 설정 변경 - case "OUT_ALERT": - setting.setOutAlert(value); - break; - // 기상 특보 알림 설정 변경 - case "CLIMATE_ALERT": - setting.setClimateAlert(value); - break; - // 사용자 맞춤 예보 설정 변경 - case "USER_ALERT": - setting.setUserAlert(value); - break; - // 강설 정보 알림 설정 변경 - case "SNOW_ALERT": - setting.setSnowAlert(value); - break; - // 직장 지역 레포트 알림 받기 - case "REGION_REPORT": - setting.setRegionReport(value); - break; - default: - throw new CustomException(ErrorCode.UNSUPPORTED_SETTING_TYPE); + if (displayDto.precipitation() != null) { + setting.setPrecipitation(displayDto.precipitation()); + } + if (displayDto.wind() != null) { + setting.setWind(displayDto.wind()); + } + if (displayDto.dust() != null) { + setting.setDust(displayDto.dust()); } settingRepository.save(setting); } - // 바람 세기 알림 설정 변경 - public void updateWind(User user, SettingReqDto.WindDto windDto) { + // 알림 설정 변경 (요일 & 시간) + public void updateOutAlertSet(User user, SettingReqDto.OutAlertSetDto outAlertSetDto) { Setting setting = user.getSetting(); + if (!setting.isOutAlert()) { + throw new CustomException(ErrorCode.INACTIVE_OUT_ALERT_SETTING); + } + updateDays(setting, outAlertSetDto.days()); - setting.setWindAlert(windDto.windAlert()); - setting.setWindDegree(windDto.windDegree()); + if (outAlertSetDto.outTime() != null) { + setting.setOutTime(outAlertSetDto.outTime()); + } + setting.setOutTime(outAlertSetDto.outTime()); settingRepository.save(setting); } - // 메인 화면 날씨 상세 정보 변경 - public void updateDisplay(User user, SettingReqDto.DisplayDto displayDto) { - Setting setting = user.getSetting(); + // 요일 설정 업데이트 + public void updateDays(Setting setting, List daysToUpdate) { + EnumSet selectedDays = daysToUpdate.stream() + .map(day -> DayOfWeek.valueOf(day.toUpperCase())) + .collect(Collectors.toCollection(() -> EnumSet.noneOf(DayOfWeek.class))); - setting.setPrecipitation(displayDto.precipitation()); - setting.setWind(displayDto.wind()); - setting.setDust(displayDto.dust()); - settingRepository.save(setting); + setting.setDays(selectedDays); } - // 직장 지역 설정 - public void updateRegion(User user, SettingReqDto.RegionDto regionDto) { - Region region = user.getSetting().getRegion(); - region.update(regionDto.regionName(), regionDto.longitude(), regionDto.latitude()); - regionRepository.save(region); + // 외출 알림 설정 변경 + public void updateOutAlert(User user, SettingReqDto.OutAlertDto outAlertDto) { + Setting setting = user.getSetting(); + setting.setOutAlert(outAlertDto.outAlert()); + settingRepository.save(setting); } - // 사용자 가중치 설정 - public void updateWeight(User user, SettingReqDto.WeightDto weightDto) { + // 기상 특보 알림 설정 변경 + public void updateClimateAlert(User user, SettingReqDto.ClimateAlertDto climateAlertDto) { Setting setting = user.getSetting(); - setting.setWeight(weightDto.weight()); + setting.setClimateAlert(climateAlertDto.climateAlert()); settingRepository.save(setting); } - - // 알림 설정 변경 (요일 & 시간) - public void updateOutAlertSet(User user, SettingReqDto.OutAlertSetDto outAlertSetDto) { + // 사용자 맞춤 예보 설정 변경 + public void updateUserAlert(User user, SettingReqDto.UserAlertDto userAlertDto) { + if (!user.isCustom()) { + throw new CustomException(ErrorCode.INACTIVE_CUSTOM_SETTING); + } Setting setting = user.getSetting(); + setting.setUserAlert(userAlertDto.userAlert()); + settingRepository.save(setting); + } - // 요일 설정 - updateDays(setting, outAlertSetDto.days()); - - // 외출 시간 설정 - if (outAlertSetDto.outTime() != null) { - setting.setOutTime(outAlertSetDto.outTime()); + // 강설 정보 알림 설정 변경 + public void updateSnowAlert(User user, SettingReqDto.SnowAlertDto snowAlertDto) { + if (!user.isCustom()) { + throw new CustomException(ErrorCode.INACTIVE_CUSTOM_SETTING); } + Setting setting = user.getSetting(); + setting.setSnowAlert(snowAlertDto.snowAlert()); settingRepository.save(setting); } - // 요일 설정 업데이트 - private void updateDays(Setting setting, List days) { - EnumSet selectedDays = days.stream() - .map(day -> DayOfWeek.valueOf(day.toUpperCase())) - .collect(Collectors.toCollection(() -> EnumSet.noneOf(DayOfWeek.class))); + // 바람 세기 알림 설정 변경 + public void updateWind(User user, SettingReqDto.WindDto windDto) { + if (!user.isCustom()) { + throw new CustomException(ErrorCode.INACTIVE_CUSTOM_SETTING); + } + Setting setting = user.getSetting(); + if (windDto.windAlert() != null) { + setting.setWindAlert(windDto.windAlert()); + } + if (windDto.windDegree() != null) { + setting.setWindDegree(windDto.windDegree()); + } + settingRepository.save(setting); + } - setting.setSun(selectedDays.contains(DayOfWeek.SUNDAY)); - setting.setMon(selectedDays.contains(DayOfWeek.MONDAY)); - setting.setTue(selectedDays.contains(DayOfWeek.TUESDAY)); - setting.setWed(selectedDays.contains(DayOfWeek.WEDNESDAY)); - setting.setThu(selectedDays.contains(DayOfWeek.THURSDAY)); - setting.setFri(selectedDays.contains(DayOfWeek.FRIDAY)); - setting.setSat(selectedDays.contains(DayOfWeek.SATURDAY)); + // 직장 지역 레포트 알림 받기 + public void updateRegionReport(User user, SettingReqDto.RegionReportDto regionReportDto) { + Setting setting = user.getSetting(); + setting.setRegionReport(regionReportDto.regionReport()); settingRepository.save(setting); } + // 직장 지역 설정 + public void updateRegion(User user, SettingReqDto.RegionDto regionDto) { + Region region = user.getSetting().getRegion(); + region.update(regionDto.regionName(), regionDto.longitude(), regionDto.latitude()); + regionRepository.save(region); + } + + // 사용자 가중치 설정 + public void updateWeight(User user, SettingReqDto.WeightDto weightDto) { + Setting setting = user.getSetting(); + setting.setWeight(weightDto.weight()); + settingRepository.save(setting); + } } diff --git a/user-service/src/main/java/com/waither/userservice/service/commandService/SurveyService.java b/user-service/src/main/java/com/waither/userservice/service/commandService/SurveyService.java index 52f23029..8b88deda 100644 --- a/user-service/src/main/java/com/waither/userservice/service/commandService/SurveyService.java +++ b/user-service/src/main/java/com/waither/userservice/service/commandService/SurveyService.java @@ -3,14 +3,21 @@ import com.waither.userservice.converter.SurveyConverter; import com.waither.userservice.dto.request.SurveyReqDto; import com.waither.userservice.entity.*; -import com.waither.userservice.entity.type.Season; +import com.waither.userservice.entity.enums.Season; +import com.waither.userservice.global.exception.CustomException; +import com.waither.userservice.global.response.ErrorCode; import com.waither.userservice.repository.SurveyRepository; +import com.waither.userservice.repository.UserDataRepository; +import com.waither.userservice.repository.UserMedianRepository; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.security.core.parameters.P; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.time.LocalDateTime; +import java.util.Arrays; +import java.util.List; @Slf4j @Service @@ -19,23 +26,48 @@ public class SurveyService { private final SurveyRepository surveyRepository; + private final UserDataRepository userDataRepository; + private final UserMedianRepository userMedianRepository; + @Transactional public void createSurvey(User user, SurveyReqDto.SurveyRequestDto surveyRequestDto) { - Survey survey = SurveyConverter.toSurvey(surveyRequestDto, getTemp(surveyRequestDto.time()), getCurrentSeason()); + Double temp = getTemp(surveyRequestDto.time()); + Survey survey = SurveyConverter.toSurvey(surveyRequestDto, temp, getCurrentSeason()); survey.setUser(user); + + UserData userData = userDataRepository.findByUserAndSeason(user, survey.getSeason()) + .orElseThrow(() -> new CustomException(ErrorCode.NO_USER_DATA_FOUND)); + UserMedian userMedian = userMedianRepository.findByUserAndSeason(user, survey.getSeason()) + .orElseThrow(() -> new CustomException(ErrorCode.NO_USER_MEDIAN_FOUND)); + + updateUserData(userData, surveyRequestDto.ans(), temp); + updateUserMedian(userData, userMedian); + surveyRepository.save(survey); } - public static double calculateMedian(double value1, double value2) { - return (value1 + value2) / 2; + private void updateUserData(UserData userData, Integer ans, Double temp) { + + double newValue = (userData.getLevel(ans) + temp) / 2 ; + + if (!isValidLevelValue(userData, ans, newValue)) { + throw new CustomException(ErrorCode.IGNORE_SURVEY_ANSWER); + } + + userData.updateLevelValue(ans, newValue); + userDataRepository.save(userData); + } + + private void updateUserMedian(UserData userData, UserMedian userMedian) { + userMedian.updateMedianValue(userData); + userMedianRepository.save(userMedian); } - // Todo: 해당 시각의 체감 온도 받아오기 (Weather-Service) + // Todo: 해당 시각의 체감 온도 받아오기 (Weather-Service로 부터) public Double getTemp(LocalDateTime time) { return 18.0; } - // Todo: 봄여름가을겨울 기준 변경 가능성 있음 public static Season getCurrentSeason() { LocalDateTime now = LocalDateTime.now(); int month = now.getMonthValue(); @@ -52,4 +84,12 @@ public static Season getCurrentSeason() { } } + // 상위, 하위 온도가 해당 온도를 넘는가 + private boolean isValidLevelValue(UserData userData, Integer ans, Double newValue) { + Double lowerLevelValue = ans > 1 ? userData.getLevel(ans - 1) : Double.MIN_VALUE; + Double upperLevelValue = ans < 5 ? userData.getLevel(ans + 1) : Double.MAX_VALUE; + + return newValue >= lowerLevelValue && newValue <= upperLevelValue; + } + } diff --git a/user-service/src/main/java/com/waither/userservice/service/commandService/UserService.java b/user-service/src/main/java/com/waither/userservice/service/commandService/UserService.java index 9945eeff..52ec96a7 100644 --- a/user-service/src/main/java/com/waither/userservice/service/commandService/UserService.java +++ b/user-service/src/main/java/com/waither/userservice/service/commandService/UserService.java @@ -6,7 +6,7 @@ import com.waither.userservice.converter.UserConverter; import com.waither.userservice.dto.request.UserReqDto; import com.waither.userservice.entity.*; -import com.waither.userservice.entity.type.Season; +import com.waither.userservice.entity.enums.Season; import com.waither.userservice.global.jwt.dto.JwtDto; import com.waither.userservice.global.jwt.util.JwtUtil; import com.waither.userservice.global.util.RedisUtil; @@ -46,6 +46,7 @@ public class UserService { // 회원가입 public void signup(UserReqDto.SignUpRequestDto requestDto) { + // Todo : 다시 풀기 // if (!verifiedAccounts(requestDto.email())) { // throw new CustomException(ErrorCode.INVALID_Account); // } diff --git a/user-service/src/main/java/com/waither/userservice/service/queryService/SettingQueryService.java b/user-service/src/main/java/com/waither/userservice/service/queryService/SettingQueryService.java index 05f715f6..638725db 100644 --- a/user-service/src/main/java/com/waither/userservice/service/queryService/SettingQueryService.java +++ b/user-service/src/main/java/com/waither/userservice/service/queryService/SettingQueryService.java @@ -14,30 +14,37 @@ @RequiredArgsConstructor public class SettingQueryService { + // 사용자 맞춤 서비스 제공 조회 public SettingResDto.CustomDto getUserCustom(User user) { return SettingConverter.toCustomDto(user); } - public SettingResDto.RegionNameDto getRegion(User user){ - return SettingConverter.toRegionNameDto(user.getSetting()); - } + // 알림 설정 조회 public SettingResDto.NotificationDto getNotification(User user) { return SettingConverter.toNotificationDto(user.getSetting()); } - public SettingResDto.WindDto getWind(User user) { - return SettingConverter.toWindDto(user.getSetting()); - } - + // 메인 화면 날씨 상세 정보 조회 public SettingResDto.DisplayDto getDisplay(User user) { return SettingConverter.toDisplayDto(user.getSetting()); } + // 바람 세기 설정 조회 + public SettingResDto.WindDto getWind(User user) { + return SettingConverter.toWindDto(user.getSetting()); + } + + // 사용자 가중치 설정 조회 public SettingResDto.WeightDto getWeight(User user) { return SettingConverter.toWeightDto(user.getSetting()); } + // 직장 지역 설정 조회 + public SettingResDto.RegionNameDto getRegion(User user){ + return SettingConverter.toRegionNameDto(user.getSetting()); + } + // 개인 정보 설정 조회 public SettingResDto.UserInfoDto getUserInfo(User user) { return SettingConverter.toUserInfoDto(user); } diff --git a/user-service/src/main/java/com/waither/userservice/service/queryService/SurveyQueryService.java b/user-service/src/main/java/com/waither/userservice/service/queryService/SurveyQueryService.java deleted file mode 100644 index 71aa8d50..00000000 --- a/user-service/src/main/java/com/waither/userservice/service/queryService/SurveyQueryService.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.waither.userservice.service.queryService; - -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Slf4j -@Service -@Transactional(readOnly = true) -@RequiredArgsConstructor -public class SurveyQueryService { - - -} diff --git a/user-service/src/main/java/com/waither/userservice/util/CalculateUtil.java b/user-service/src/main/java/com/waither/userservice/util/CalculateUtil.java new file mode 100644 index 00000000..11b5633d --- /dev/null +++ b/user-service/src/main/java/com/waither/userservice/util/CalculateUtil.java @@ -0,0 +1,13 @@ +package com.waither.userservice.util; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class CalculateUtil { + + public static double calculateMedian(double value1, double value2) { + return (value1 + value2) / 2; + } + +}