diff --git a/src/main/java/com/onebridge/ouch/apiPayload/code/error/DiagnosisErrorCode.java b/src/main/java/com/onebridge/ouch/apiPayload/code/error/DiagnosisErrorCode.java new file mode 100644 index 0000000..11f2960 --- /dev/null +++ b/src/main/java/com/onebridge/ouch/apiPayload/code/error/DiagnosisErrorCode.java @@ -0,0 +1,20 @@ +package com.onebridge.ouch.apiPayload.code.error; + +import org.springframework.http.HttpStatus; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum DiagnosisErrorCode implements ErrorCode { + + SYMPTOM_NOT_FOUND(HttpStatus.NOT_FOUND, "DIAGNOSIS401", "입력한 증상이 존재하지 않습니다."), + DIAGNOSIS_NOT_FOUND(HttpStatus.NOT_FOUND, "DIAGNOSIS402", "자가진단표가 존재하지 않습니다."), + SYMPTOM_ALREADY_ADDED(HttpStatus.BAD_REQUEST, "DIAGNOSIS403", "해당 증상이 이미 존재합니다."), + ; + + private final HttpStatus httpStatus; + private final String code; + private final String message; +} diff --git a/src/main/java/com/onebridge/ouch/controller/selfDiagnosis/SelfDiagnosisController.java b/src/main/java/com/onebridge/ouch/controller/selfDiagnosis/SelfDiagnosisController.java new file mode 100644 index 0000000..115f44b --- /dev/null +++ b/src/main/java/com/onebridge/ouch/controller/selfDiagnosis/SelfDiagnosisController.java @@ -0,0 +1,112 @@ +package com.onebridge.ouch.controller.selfDiagnosis; + +import java.util.List; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.onebridge.ouch.apiPayload.ApiResponse; +import com.onebridge.ouch.dto.selfDiagnosis.request.AddSymptomsToDiagnosisRequest; +import com.onebridge.ouch.dto.selfDiagnosis.request.DiagnosisCreateRequest; +import com.onebridge.ouch.dto.selfDiagnosis.request.DiagnosisUpdateRequest; +import com.onebridge.ouch.dto.selfDiagnosis.response.GetDiagnosisByUserIdResponse; +import com.onebridge.ouch.dto.selfDiagnosis.response.GetDiagnosisResponse; +import com.onebridge.ouch.dto.selfDiagnosis.response.GetSymptomsOfDiagnosisResponse; +import com.onebridge.ouch.security.authorization.UserId; +import com.onebridge.ouch.service.selfDiagnosis.SelfDiagnosisService; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; + +@Tag(name = "자가진단표 API", description = "자가진단표 API 입니다.") +@RestController +@RequestMapping("/self-diagnosis") +@RequiredArgsConstructor +public class SelfDiagnosisController { + + private final SelfDiagnosisService selfDiagnosisService; + + //자가진단표 생성 + @Operation(summary = "자가진단표 생성 API", description = "자가진단표 생성 API 입니다.") + @PostMapping + public ResponseEntity> createDiagnosis( //request dto 에 userid 지우기 + @RequestBody @Valid DiagnosisCreateRequest request, + @UserId Long userId + ) { + selfDiagnosisService.createDiagnosis(request, userId); + return ResponseEntity.ok(ApiResponse.successWithNoData()); + } + + //(자가진단표)id로 자가진단표 조회 + @Operation(summary = "자가진단표 조회 API", description = "자가진단표 조회 API 입니다.") + @GetMapping("/{diagnosisId}") + public ResponseEntity> getDiagnosisById( + @PathVariable Long diagnosisId, + @UserId Long userId + ) { + GetDiagnosisResponse response = selfDiagnosisService.getDiagnosis(diagnosisId, userId); + return ResponseEntity.ok(ApiResponse.success(response)); + } + + //사용자 모든 자가진단표 조회 + @Operation(summary = "특정 사용자의 모든 자가진단표 조회 API", description = "특정 사용자의 모든 자가진단표 조회 API 입니다.") + @GetMapping + public ResponseEntity>> getAllDiagnosisByUserId( + @UserId Long userId + ) { + List list = selfDiagnosisService.getAllDiagnosisByUserId(userId); + return ResponseEntity.ok(ApiResponse.success(list)); + } + + //자가진단표 삭제 + @Operation(summary = "자가진단표 삭제 API", description = "자가진단표 삭제 API 입니다.") + @DeleteMapping("/{diagnosisId}") + public ResponseEntity> deleteDiagnosis(@PathVariable Long diagnosisId, + @UserId Long userId + ) { + selfDiagnosisService.deleteDiagnosis(diagnosisId, userId); + return ResponseEntity.ok(ApiResponse.successWithNoData()); + } + + //특정 자가진단표의 증상 목록 조회 + @Operation(summary = "특정 자가진단표의 증상 목록 조회 API", description = "특정 자가진단표의 증상 목록 조회 API 입니다.") + @GetMapping("/{diagnosisId}/symptoms") + public ResponseEntity> getSymptomsOfDiagnosis( + @PathVariable Long diagnosisId, + @UserId Long userId + ) { + GetSymptomsOfDiagnosisResponse response = selfDiagnosisService.getSymptomsOfDiagnosis(diagnosisId, userId); + return ResponseEntity.ok(ApiResponse.success(response)); + } + + //자가진단표 수정 + @Operation(summary = "자가진단표 수정 API", description = "자가진단표 수정 API 입니다.") + @PutMapping("/{diagnosisId}") + public ResponseEntity> updateDiagnosis(@PathVariable Long diagnosisId, + @RequestBody @Valid DiagnosisUpdateRequest request, + @UserId Long userId + ) { + selfDiagnosisService.updateDiagnosis(diagnosisId, userId, request); + return ResponseEntity.ok(ApiResponse.successWithNoData()); + } + + //자가진단표에 증상 추가 + @Operation(summary = "특정 자가진단표에 증상 추가 API", description = "특정 자가진단표에 증상 추가 API 입니다.") + @PostMapping("/{diagnosisId}/symptoms") + public ResponseEntity> addSymptomsToSelfDiagnosis(@PathVariable Long diagnosisId, + @RequestBody @Valid AddSymptomsToDiagnosisRequest request, + @UserId Long userId + ) { + selfDiagnosisService.addSymptomsToSelfDiagnosis(diagnosisId, request, userId); + return ResponseEntity.ok(ApiResponse.successWithNoData()); + } +} diff --git a/src/main/java/com/onebridge/ouch/controller/symptom/SymptomController.java b/src/main/java/com/onebridge/ouch/controller/symptom/SymptomController.java new file mode 100644 index 0000000..ce40010 --- /dev/null +++ b/src/main/java/com/onebridge/ouch/controller/symptom/SymptomController.java @@ -0,0 +1,33 @@ +package com.onebridge.ouch.controller.symptom; + +import java.util.List; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.onebridge.ouch.apiPayload.ApiResponse; +import com.onebridge.ouch.dto.symptom.response.GetSymptomResponse; +import com.onebridge.ouch.service.symptom.SymptomService; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; + +@Tag(name = "증상 API", description = "증상 API 입니다.") +@RestController +@RequestMapping("/symptoms") +@RequiredArgsConstructor +public class SymptomController { + + private final SymptomService symptomService; + + //증상 목록 조회 + @Operation(summary = "증상 목록 조회 API", description = "증상 목록 조회 API 입니다.") + @GetMapping + public ResponseEntity>> getSymptomsList() { + List list = symptomService.getSymptomsList(); + return ResponseEntity.ok(ApiResponse.success(list)); + } +} diff --git a/src/main/java/com/onebridge/ouch/controller/user/UserController.java b/src/main/java/com/onebridge/ouch/controller/user/UserController.java index 4415df9..52f89e7 100644 --- a/src/main/java/com/onebridge/ouch/controller/user/UserController.java +++ b/src/main/java/com/onebridge/ouch/controller/user/UserController.java @@ -1,83 +1,39 @@ package com.onebridge.ouch.controller.user; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PatchMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import com.onebridge.ouch.dto.MessageResponse; -import com.onebridge.ouch.dto.MessageResponseDetailed; -import com.onebridge.ouch.dto.user.request.MypageUserInfoUpdateRequest; -import com.onebridge.ouch.dto.user.response.MypageUserInfoResponse; +import com.onebridge.ouch.apiPayload.ApiResponse; import com.onebridge.ouch.dto.user.response.UserInfoResponse; +import com.onebridge.ouch.security.authorization.UserId; import com.onebridge.ouch.service.user.UserService; -import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; @RestController -@RequestMapping("/api") +@RequestMapping("/users") +@RequiredArgsConstructor public class UserController { private final UserService userService; - public UserController(UserService userService) { - this.userService = userService; - } - - //유저 조회(테스트용) - @GetMapping("/users/{userId}") - public UserInfoResponse getUserInfo(@PathVariable Long userId) { - return userService.getUserInfo(userId); + //유저 조회 + @GetMapping + public ResponseEntity> getUserInfo( + @UserId Long userId) { + UserInfoResponse response = userService.getUserInfo(userId); + return ResponseEntity.ok(ApiResponse.success(response)); } //유저 탈퇴(비활성화) - @PatchMapping("/users/{userId}") - public ResponseEntity deactivateUser(@PathVariable Long userId) { + @DeleteMapping + public ResponseEntity> deactivateUser( + @UserId Long userId) { userService.deactivateUser(userId); - MessageResponse body = new MessageResponse("Your account has been deactivated."); - HttpHeaders header = new HttpHeaders(); - header.add(HttpHeaders.CONTENT_TYPE, "application/json"); - - return new ResponseEntity<>(body, header, HttpStatus.OK); - } - - //유저 삭제(테스트용) - @DeleteMapping("/users/{userId}") - public ResponseEntity deleteUser(@PathVariable Long userId) { - userService.deleteUser(userId); - MessageResponse body = new MessageResponse("Your account has been deleted."); - HttpHeaders header = new HttpHeaders(); - header.add(HttpHeaders.CONTENT_TYPE, "application/json"); - - return new ResponseEntity<>(body, header, HttpStatus.OK); - } - - //마이페이지(내 정보) 조회 - @GetMapping("/mypage/users/{userId}") - public MypageUserInfoResponse myPageGetUserInfo(@PathVariable Long userId) { - return userService.myPageGetUserInfo(userId); - } - - //내 정보 수정 (사용자로부터 모든 필드의 값을 받아 put 요청 처리) - @PutMapping("/mypage/users/{userId}") - public ResponseEntity> myPageUpdateUserInfo(@PathVariable Long userId, - @RequestBody @Valid MypageUserInfoUpdateRequest request) { - // System.out.println("userId = " + userId); - userService.myPageUpdateUserInfo(userId, request); - MessageResponseDetailed body = new MessageResponseDetailed<>( - true, - "COMMON200", - "요청이 성공적으로 처리되었습니다.", - "유저 정보가 성공적으로 수정되었습니다." - ); - return ResponseEntity.ok(body); + return ResponseEntity.ok(ApiResponse.successWithNoData()); } } diff --git a/src/main/java/com/onebridge/ouch/converter/SelfDiagnosisConverter.java b/src/main/java/com/onebridge/ouch/converter/SelfDiagnosisConverter.java new file mode 100644 index 0000000..a866d9d --- /dev/null +++ b/src/main/java/com/onebridge/ouch/converter/SelfDiagnosisConverter.java @@ -0,0 +1,84 @@ +package com.onebridge.ouch.converter; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.stereotype.Component; + +import com.onebridge.ouch.domain.SelfDiagnosis; +import com.onebridge.ouch.domain.Symptom; +import com.onebridge.ouch.domain.User; +import com.onebridge.ouch.domain.mapping.DiagnosisSymptom; +import com.onebridge.ouch.dto.selfDiagnosis.request.DiagnosisCreateRequest; +import com.onebridge.ouch.dto.selfDiagnosis.request.DiagnosisUpdateRequest; +import com.onebridge.ouch.dto.selfDiagnosis.response.DiagnosisUpdateResponse; +import com.onebridge.ouch.dto.selfDiagnosis.response.GetDiagnosisByUserIdResponse; +import com.onebridge.ouch.dto.selfDiagnosis.response.GetDiagnosisResponse; +import com.onebridge.ouch.dto.selfDiagnosis.response.GetSymptomsOfDiagnosisResponse; + +@Component +public class SelfDiagnosisConverter { + + public DiagnosisUpdateResponse diagnosisToDiagnosisUpdateResponse(SelfDiagnosis updatedDiagnosis) { + List symptoms = symptomListForResponseDto(updatedDiagnosis); + return new DiagnosisUpdateResponse(updatedDiagnosis.getId(), updatedDiagnosis.getVisitType(), symptoms, + updatedDiagnosis.getDuration(), updatedDiagnosis.getPainSeverity(), updatedDiagnosis.getAdditionalNote(), + updatedDiagnosis.getCreatedAt().toString()); + } + + public GetDiagnosisResponse diagnosisToGetDiagnosisResponse(SelfDiagnosis diagnosis) { + List symptoms = symptomListForResponseDto(diagnosis); + return new GetDiagnosisResponse(diagnosis.getUser().getId(), diagnosis.getVisitType(), symptoms, + diagnosis.getDuration(), + diagnosis.getPainSeverity(), diagnosis.getAdditionalNote(), diagnosis.getCreatedAt().toString()); + } + + public GetDiagnosisByUserIdResponse diagnosisToGetDiagnosisByUserIdResponse(SelfDiagnosis diagnosis) { + List symptoms = symptomListForResponseDto(diagnosis); + return new GetDiagnosisByUserIdResponse(diagnosis.getId(), diagnosis.getVisitType(), symptoms, + diagnosis.getDuration(), diagnosis.getPainSeverity(), diagnosis.getAdditionalNote(), + diagnosis.getCreatedAt().toString()); + } + + public GetSymptomsOfDiagnosisResponse diagnosisToGetSymptomsOfDiagnosisResponse(SelfDiagnosis diagnosis) { + List symptoms = symptomListForResponseDto(diagnosis); + return new GetSymptomsOfDiagnosisResponse(symptoms); + } + + public SelfDiagnosis diagnosisCreateRequestToSelfDiagnosis(DiagnosisCreateRequest request, User user) { + return SelfDiagnosis.builder() + .user(user) + .visitType(request.getVisitType()) + .diagnosisSymptomList(new ArrayList<>()) + .duration(request.getDuration()) + .painSeverity(request.getPainSeverity()) + .additionalNote(request.getAdditionalNote()) + .build(); + } + + public DiagnosisSymptom buildDiagnosisSymptom(SelfDiagnosis selfDiagnosis, Symptom foundSymptom) { + return DiagnosisSymptom.builder() + .selfDiagnosis(selfDiagnosis) + .symptom(foundSymptom) + .build(); + } + + public SelfDiagnosis diagnosisUpdateRequestToSelfDiagnosis(SelfDiagnosis diagnosis, User user, + DiagnosisUpdateRequest request) { + return diagnosis.toBuilder() + .visitType(request.getVisitType()) + .diagnosisSymptomList(new ArrayList<>()) + .duration(request.getDuration()) + .painSeverity(request.getPainSeverity()) + .additionalNote(request.getAdditionalNote()) + .build(); + } + + public List symptomListForResponseDto(SelfDiagnosis selfDiagnosis) { + List symptoms = new ArrayList<>(); + for (DiagnosisSymptom symptom : selfDiagnosis.getDiagnosisSymptomList()) { + symptoms.add(symptom.getSymptom().getName()); + } + return symptoms; + } +} diff --git a/src/main/java/com/onebridge/ouch/converter/SymptomConverter.java b/src/main/java/com/onebridge/ouch/converter/SymptomConverter.java new file mode 100644 index 0000000..3727f55 --- /dev/null +++ b/src/main/java/com/onebridge/ouch/converter/SymptomConverter.java @@ -0,0 +1,20 @@ +package com.onebridge.ouch.converter; + +import java.util.List; + +import org.springframework.stereotype.Component; + +import com.onebridge.ouch.domain.Symptom; +import com.onebridge.ouch.dto.symptom.response.GetSymptomResponse; + +@Component +public class SymptomConverter { + + public GetSymptomResponse symptomToGetSymptomsResponse(Symptom symptom) { + return new GetSymptomResponse(symptom.getId(), symptom.getName()); + } + + public List symptomsToGetSymptomsResponse(List symptoms) { + return symptoms.stream().map(this::symptomToGetSymptomsResponse).toList(); + } +} diff --git a/src/main/java/com/onebridge/ouch/converter/UserConverter.java b/src/main/java/com/onebridge/ouch/converter/UserConverter.java index 1235fdb..8a316db 100644 --- a/src/main/java/com/onebridge/ouch/converter/UserConverter.java +++ b/src/main/java/com/onebridge/ouch/converter/UserConverter.java @@ -3,7 +3,6 @@ import org.springframework.stereotype.Component; import com.onebridge.ouch.domain.User; -import com.onebridge.ouch.dto.user.response.MypageUserInfoResponse; import com.onebridge.ouch.dto.user.response.UserInfoResponse; @Component @@ -14,8 +13,4 @@ public UserInfoResponse convertToUserInfoResponse(User user) { user.getPhoneNumber(), user.getGender(), user.getBirthday(), user.getEmail(), user.getLanguage().getId(), user.getNation().getId()); } - - public MypageUserInfoResponse convertToMypageUserInfoResponse(User user) { - return new MypageUserInfoResponse(user.getNickname(), user.getEmail(), user.getLanguage().getId()); - } } diff --git a/src/main/java/com/onebridge/ouch/domain/SelfDiagnosis.java b/src/main/java/com/onebridge/ouch/domain/SelfDiagnosis.java index b9f2ade..927183b 100644 --- a/src/main/java/com/onebridge/ouch/domain/SelfDiagnosis.java +++ b/src/main/java/com/onebridge/ouch/domain/SelfDiagnosis.java @@ -4,14 +4,17 @@ import java.util.List; import com.onebridge.ouch.domain.common.BaseEntity; +import com.onebridge.ouch.domain.enums.SymptomDuration; +import com.onebridge.ouch.domain.enums.VisitType; import com.onebridge.ouch.domain.mapping.DiagnosisSymptom; import jakarta.persistence.*; import lombok.*; +import lombok.experimental.SuperBuilder; @Entity @Getter -@Builder +@Builder(toBuilder = true) @NoArgsConstructor(access = AccessLevel.PROTECTED) @AllArgsConstructor public class SelfDiagnosis extends BaseEntity { @@ -30,4 +33,13 @@ public class SelfDiagnosis extends BaseEntity { @OneToMany(mappedBy = "selfDiagnosis", cascade = CascadeType.ALL, orphanRemoval = true) private List diagnosisSymptomList = new ArrayList<>(); + private VisitType visitType; + + private SymptomDuration duration; + + private Integer painSeverity; + + @Column(columnDefinition = "TEXT") + private String additionalNote; + } diff --git a/src/main/java/com/onebridge/ouch/domain/common/BaseEntity.java b/src/main/java/com/onebridge/ouch/domain/common/BaseEntity.java index 1d4870d..a4906a9 100644 --- a/src/main/java/com/onebridge/ouch/domain/common/BaseEntity.java +++ b/src/main/java/com/onebridge/ouch/domain/common/BaseEntity.java @@ -7,12 +7,17 @@ import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; -import jakarta.persistence.*; -import lombok.*; +import jakarta.persistence.EntityListeners; +import jakarta.persistence.MappedSuperclass; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; @MappedSuperclass @EntityListeners(AuditingEntityListener.class) @Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) public abstract class BaseEntity { @CreatedDate diff --git a/src/main/java/com/onebridge/ouch/domain/enums/SymptomDuration.java b/src/main/java/com/onebridge/ouch/domain/enums/SymptomDuration.java new file mode 100644 index 0000000..f77a93d --- /dev/null +++ b/src/main/java/com/onebridge/ouch/domain/enums/SymptomDuration.java @@ -0,0 +1,5 @@ +package com.onebridge.ouch.domain.enums; + +public enum SymptomDuration { + LESS_THAN_1_DAY, ONE_TO_3_DAYS, MORE_THAN_3_DAYS, MORE_THAN_1_WEEK, MORE_THAN_1_MONTH +} diff --git a/src/main/java/com/onebridge/ouch/domain/enums/VisitType.java b/src/main/java/com/onebridge/ouch/domain/enums/VisitType.java new file mode 100644 index 0000000..c418a48 --- /dev/null +++ b/src/main/java/com/onebridge/ouch/domain/enums/VisitType.java @@ -0,0 +1,5 @@ +package com.onebridge.ouch.domain.enums; + +public enum VisitType { + HOSPITAL, PHARMACY +} diff --git a/src/main/java/com/onebridge/ouch/dto/selfDiagnosis/request/AddSymptomsToDiagnosisRequest.java b/src/main/java/com/onebridge/ouch/dto/selfDiagnosis/request/AddSymptomsToDiagnosisRequest.java new file mode 100644 index 0000000..71d1658 --- /dev/null +++ b/src/main/java/com/onebridge/ouch/dto/selfDiagnosis/request/AddSymptomsToDiagnosisRequest.java @@ -0,0 +1,13 @@ +package com.onebridge.ouch.dto.selfDiagnosis.request; + +import java.util.List; + +import jakarta.validation.constraints.NotNull; +import lombok.Getter; + +@Getter +public class AddSymptomsToDiagnosisRequest { + + @NotNull(message = "Please enter symptoms to add.") + private List symptoms; +} diff --git a/src/main/java/com/onebridge/ouch/dto/selfDiagnosis/request/DiagnosisCreateRequest.java b/src/main/java/com/onebridge/ouch/dto/selfDiagnosis/request/DiagnosisCreateRequest.java new file mode 100644 index 0000000..72ab9cd --- /dev/null +++ b/src/main/java/com/onebridge/ouch/dto/selfDiagnosis/request/DiagnosisCreateRequest.java @@ -0,0 +1,35 @@ +package com.onebridge.ouch.dto.selfDiagnosis.request; + +import java.util.List; + +import com.onebridge.ouch.domain.enums.SymptomDuration; +import com.onebridge.ouch.domain.enums.VisitType; + +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.Getter; + +@Getter +public class DiagnosisCreateRequest { + + // @NotNull(message = "User Id is required.") + // private Long userId; + + @NotNull(message = "Visit type is required.") + private VisitType visitType; + + @NotEmpty(message = "At least one symptom is required.") + private List symptoms; + + @NotNull(message = "Symptom duration is required.") + private SymptomDuration duration; + + @NotNull(message = "Pain severity is required.") + @Min(value = 0, message = "통증 정도는 최소 0 이상이어야 합니다.") + @Max(value = 10, message = "통증 정도는 최대 10 이하여야 합니다.") + private Integer painSeverity; + + private String additionalNote; +} diff --git a/src/main/java/com/onebridge/ouch/dto/selfDiagnosis/request/DiagnosisUpdateRequest.java b/src/main/java/com/onebridge/ouch/dto/selfDiagnosis/request/DiagnosisUpdateRequest.java new file mode 100644 index 0000000..22680b7 --- /dev/null +++ b/src/main/java/com/onebridge/ouch/dto/selfDiagnosis/request/DiagnosisUpdateRequest.java @@ -0,0 +1,32 @@ +package com.onebridge.ouch.dto.selfDiagnosis.request; + +import java.util.List; + +import com.onebridge.ouch.domain.enums.SymptomDuration; +import com.onebridge.ouch.domain.enums.VisitType; + +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.Getter; + +@Getter +public class DiagnosisUpdateRequest { + + @NotNull(message = "Visit type is required.") + private VisitType visitType; + + @NotEmpty(message = "At least one symptom is required.") + private List symptoms; + + @NotNull(message = "Symptom duration is required.") + private SymptomDuration duration; + + @NotNull(message = "Pain severity is required.") + @Min(value = 0, message = "통증 정도는 최소 0 이상이어야 합니다.") + @Max(value = 10, message = "통증 정도는 최대 10 이하여야 합니다.") + private Integer painSeverity; + + private String additionalNote; +} diff --git a/src/main/java/com/onebridge/ouch/dto/selfDiagnosis/response/DiagnosisUpdateResponse.java b/src/main/java/com/onebridge/ouch/dto/selfDiagnosis/response/DiagnosisUpdateResponse.java new file mode 100644 index 0000000..d599a4b --- /dev/null +++ b/src/main/java/com/onebridge/ouch/dto/selfDiagnosis/response/DiagnosisUpdateResponse.java @@ -0,0 +1,22 @@ +package com.onebridge.ouch.dto.selfDiagnosis.response; + +import java.util.List; + +import com.onebridge.ouch.domain.enums.SymptomDuration; +import com.onebridge.ouch.domain.enums.VisitType; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class DiagnosisUpdateResponse { + + private Long id; + private VisitType visitType; + private List symptoms; + private SymptomDuration duration; + private Integer painSeverity; + private String additionalNote; + private String createdAt; +} diff --git a/src/main/java/com/onebridge/ouch/dto/selfDiagnosis/response/GetDiagnosisByUserIdResponse.java b/src/main/java/com/onebridge/ouch/dto/selfDiagnosis/response/GetDiagnosisByUserIdResponse.java new file mode 100644 index 0000000..33aceeb --- /dev/null +++ b/src/main/java/com/onebridge/ouch/dto/selfDiagnosis/response/GetDiagnosisByUserIdResponse.java @@ -0,0 +1,22 @@ +package com.onebridge.ouch.dto.selfDiagnosis.response; + +import java.util.List; + +import com.onebridge.ouch.domain.enums.SymptomDuration; +import com.onebridge.ouch.domain.enums.VisitType; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class GetDiagnosisByUserIdResponse { + + private Long diagnosisId; + private VisitType visitType; + private List symptoms; + private SymptomDuration duration; + private Integer painSeverity; + private String additionalNote; + private String createdAt; +} diff --git a/src/main/java/com/onebridge/ouch/dto/selfDiagnosis/response/GetDiagnosisResponse.java b/src/main/java/com/onebridge/ouch/dto/selfDiagnosis/response/GetDiagnosisResponse.java new file mode 100644 index 0000000..6efdeb1 --- /dev/null +++ b/src/main/java/com/onebridge/ouch/dto/selfDiagnosis/response/GetDiagnosisResponse.java @@ -0,0 +1,22 @@ +package com.onebridge.ouch.dto.selfDiagnosis.response; + +import java.util.List; + +import com.onebridge.ouch.domain.enums.SymptomDuration; +import com.onebridge.ouch.domain.enums.VisitType; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class GetDiagnosisResponse { + + private Long userId; + private VisitType visitType; + private List symptoms; + private SymptomDuration duration; + private Integer painSeverity; + private String additionalNote; + private String createdAt; +} diff --git a/src/main/java/com/onebridge/ouch/dto/selfDiagnosis/response/GetSymptomsOfDiagnosisResponse.java b/src/main/java/com/onebridge/ouch/dto/selfDiagnosis/response/GetSymptomsOfDiagnosisResponse.java new file mode 100644 index 0000000..3d84f94 --- /dev/null +++ b/src/main/java/com/onebridge/ouch/dto/selfDiagnosis/response/GetSymptomsOfDiagnosisResponse.java @@ -0,0 +1,13 @@ +package com.onebridge.ouch.dto.selfDiagnosis.response; + +import java.util.List; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class GetSymptomsOfDiagnosisResponse { + + private List symptoms; +} diff --git a/src/main/java/com/onebridge/ouch/dto/symptom/response/GetSymptomResponse.java b/src/main/java/com/onebridge/ouch/dto/symptom/response/GetSymptomResponse.java new file mode 100644 index 0000000..71a80ec --- /dev/null +++ b/src/main/java/com/onebridge/ouch/dto/symptom/response/GetSymptomResponse.java @@ -0,0 +1,13 @@ +package com.onebridge.ouch.dto.symptom.response; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class GetSymptomResponse { + + private long id; + + private String name; +} diff --git a/src/main/java/com/onebridge/ouch/dto/user/request/UserUpdateRequest.java b/src/main/java/com/onebridge/ouch/dto/user/request/UserUpdateRequest.java deleted file mode 100644 index c38b99a..0000000 --- a/src/main/java/com/onebridge/ouch/dto/user/request/UserUpdateRequest.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.onebridge.ouch.dto.user.request; - -import java.time.LocalDate; - -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -public class UserUpdateRequest { - - private String loginId; - - private String password; - - private String name; - - private String nickname; - - private String phoneNumber; - - private LocalDate birthday; - - private String email; - - private String address; -} diff --git a/src/main/java/com/onebridge/ouch/dto/user/response/AllUsersResponse.java b/src/main/java/com/onebridge/ouch/dto/user/response/AllUsersResponse.java deleted file mode 100644 index e4f3360..0000000 --- a/src/main/java/com/onebridge/ouch/dto/user/response/AllUsersResponse.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.onebridge.ouch.dto.user.response; - -import java.time.LocalDate; - -import com.onebridge.ouch.domain.enums.UserStatus; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Getter -@AllArgsConstructor -@NoArgsConstructor -public class AllUsersResponse { - - private Long id; - - private String loginId; - - private String password; - - private String name; - - private String nickname; - - private String phoneNumber; - - private LocalDate birthday; - - private String email; - - private String address; - - private UserStatus status; -} diff --git a/src/main/java/com/onebridge/ouch/dto/user/response/MypageUserInfoResponse.java b/src/main/java/com/onebridge/ouch/dto/user/response/MypageUserInfoResponse.java deleted file mode 100644 index 16729be..0000000 --- a/src/main/java/com/onebridge/ouch/dto/user/response/MypageUserInfoResponse.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.onebridge.ouch.dto.user.response; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -@AllArgsConstructor -@Getter -public class MypageUserInfoResponse { - - private String nickname; - - private String email; - - private Long languageId; -} diff --git a/src/main/java/com/onebridge/ouch/dto/user/response/UserSignupResponse.java b/src/main/java/com/onebridge/ouch/dto/user/response/UserSignupResponse.java deleted file mode 100644 index a927f55..0000000 --- a/src/main/java/com/onebridge/ouch/dto/user/response/UserSignupResponse.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.onebridge.ouch.dto.user.response; - -import java.time.LocalDate; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -@AllArgsConstructor -@Getter -public class UserSignupResponse { - - private Long id; - - private LocalDate createdAt; -} diff --git a/src/main/java/com/onebridge/ouch/repository/Symptom/SymptomRepository.java b/src/main/java/com/onebridge/ouch/repository/Symptom/SymptomRepository.java new file mode 100644 index 0000000..15be2fd --- /dev/null +++ b/src/main/java/com/onebridge/ouch/repository/Symptom/SymptomRepository.java @@ -0,0 +1,19 @@ +package com.onebridge.ouch.repository.Symptom; + +import java.util.List; +import java.util.Optional; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import com.onebridge.ouch.domain.Symptom; + +@Repository +public interface SymptomRepository extends JpaRepository { + + boolean existsByName(String name); + + Optional findByName(String name); + + List findByNameIn(List names); +} diff --git a/src/main/java/com/onebridge/ouch/repository/selfDiagnosis/SelfDiagnosisRepository.java b/src/main/java/com/onebridge/ouch/repository/selfDiagnosis/SelfDiagnosisRepository.java new file mode 100644 index 0000000..14d56ed --- /dev/null +++ b/src/main/java/com/onebridge/ouch/repository/selfDiagnosis/SelfDiagnosisRepository.java @@ -0,0 +1,17 @@ +package com.onebridge.ouch.repository.selfDiagnosis; + +import java.util.List; +import java.util.Optional; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import com.onebridge.ouch.domain.SelfDiagnosis; + +@Repository +public interface SelfDiagnosisRepository extends JpaRepository { + + List findAllByUserId(Long userId); + + Optional findByIdAndUserId(Long id, Long userId); +} diff --git a/src/main/java/com/onebridge/ouch/service/selfDiagnosis/SelfDiagnosisService.java b/src/main/java/com/onebridge/ouch/service/selfDiagnosis/SelfDiagnosisService.java new file mode 100644 index 0000000..b4b3903 --- /dev/null +++ b/src/main/java/com/onebridge/ouch/service/selfDiagnosis/SelfDiagnosisService.java @@ -0,0 +1,172 @@ +package com.onebridge.ouch.service.selfDiagnosis; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.onebridge.ouch.apiPayload.code.error.CommonErrorCode; +import com.onebridge.ouch.apiPayload.code.error.DiagnosisErrorCode; +import com.onebridge.ouch.apiPayload.exception.OuchException; +import com.onebridge.ouch.converter.SelfDiagnosisConverter; +import com.onebridge.ouch.domain.SelfDiagnosis; +import com.onebridge.ouch.domain.Symptom; +import com.onebridge.ouch.domain.User; +import com.onebridge.ouch.domain.mapping.DiagnosisSymptom; +import com.onebridge.ouch.dto.selfDiagnosis.request.AddSymptomsToDiagnosisRequest; +import com.onebridge.ouch.dto.selfDiagnosis.request.DiagnosisCreateRequest; +import com.onebridge.ouch.dto.selfDiagnosis.request.DiagnosisUpdateRequest; +import com.onebridge.ouch.dto.selfDiagnosis.response.DiagnosisUpdateResponse; +import com.onebridge.ouch.dto.selfDiagnosis.response.GetDiagnosisByUserIdResponse; +import com.onebridge.ouch.dto.selfDiagnosis.response.GetDiagnosisResponse; +import com.onebridge.ouch.dto.selfDiagnosis.response.GetSymptomsOfDiagnosisResponse; +import com.onebridge.ouch.repository.Symptom.SymptomRepository; +import com.onebridge.ouch.repository.selfDiagnosis.SelfDiagnosisRepository; +import com.onebridge.ouch.repository.user.UserRepository; + +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class SelfDiagnosisService { + + private final SelfDiagnosisRepository selfDiagnosisRepository; + private final SymptomRepository symptomRepository; + private final UserRepository userRepository; + private final SelfDiagnosisConverter selfDiagnosisConverter; + + //자가진단표 생성 + @Transactional + public void createDiagnosis(DiagnosisCreateRequest request, Long userId) { + User user = userRepository.findById(userId) + .orElseThrow(() -> new OuchException(CommonErrorCode.MEMBER_NOT_FOUND)); + + //일단 증상 리스트는 비워둔 채로 SelfDiagnosis 객체 생성 + SelfDiagnosis selfDiagnosis = selfDiagnosisConverter.diagnosisCreateRequestToSelfDiagnosis(request, user); + + List symptomNames = request.getSymptoms(); + List foundSymptoms = symptomRepository.findByNameIn(symptomNames); + + // 이름으로 빠르게 찾기 위해 Map 으로 변환 + Map symptomMap = foundSymptoms.stream() + .collect(Collectors.toMap(Symptom::getName, s -> s)); + + for (String symptomName : symptomNames) { + Symptom foundSymptom = symptomMap.get(symptomName); + if (foundSymptom == null) { + throw new OuchException(DiagnosisErrorCode.SYMPTOM_NOT_FOUND); + } + + DiagnosisSymptom diagnosisSymptom = selfDiagnosisConverter.buildDiagnosisSymptom(selfDiagnosis, + foundSymptom); + selfDiagnosis.getDiagnosisSymptomList().add(diagnosisSymptom); + } + + selfDiagnosisRepository.save(selfDiagnosis); + } + + //특정 자가진단표 조회 + @Transactional(readOnly = true) + public GetDiagnosisResponse getDiagnosis(Long diagnosisId, Long userId) { + SelfDiagnosis diagnosis = selfDiagnosisRepository.findByIdAndUserId(diagnosisId, userId) + .orElseThrow(() -> new OuchException(DiagnosisErrorCode.DIAGNOSIS_NOT_FOUND)); + + return selfDiagnosisConverter.diagnosisToGetDiagnosisResponse(diagnosis); + } + + //특정 사용자의 모든 자가진단표 조회 + @Transactional(readOnly = true) + public List getAllDiagnosisByUserId(Long userId) { + List diagnosisList = selfDiagnosisRepository.findAllByUserId(userId); + + List responseList = new ArrayList<>(); + for (SelfDiagnosis diagnosis : diagnosisList) { + responseList.add(selfDiagnosisConverter.diagnosisToGetDiagnosisByUserIdResponse(diagnosis)); + } + + return responseList; + } + + //특정 자가진단표 삭제 + @Transactional + public void deleteDiagnosis(Long diagnosisId, Long userId) { + SelfDiagnosis diagnosis = selfDiagnosisRepository.findByIdAndUserId(diagnosisId, userId) + .orElseThrow(() -> new OuchException(DiagnosisErrorCode.DIAGNOSIS_NOT_FOUND)); + + selfDiagnosisRepository.delete(diagnosis); + } + + //특정 자가진단표의 증상 목록 조회 + @Transactional(readOnly = true) + public GetSymptomsOfDiagnosisResponse getSymptomsOfDiagnosis(Long diagnosisId, Long userId) { + SelfDiagnosis diagnosis = selfDiagnosisRepository.findByIdAndUserId(diagnosisId, userId) + .orElseThrow(() -> new OuchException(DiagnosisErrorCode.DIAGNOSIS_NOT_FOUND)); + + return selfDiagnosisConverter.diagnosisToGetSymptomsOfDiagnosisResponse(diagnosis); + } + + //자가진단표 수정 + @Transactional + public DiagnosisUpdateResponse updateDiagnosis(Long diagnosisId, Long userId, DiagnosisUpdateRequest request) { + SelfDiagnosis diagnosis = selfDiagnosisRepository.findByIdAndUserId(diagnosisId, userId) + .orElseThrow(() -> new OuchException(DiagnosisErrorCode.DIAGNOSIS_NOT_FOUND)); + + User user = userRepository.findById(userId) + .orElseThrow(() -> new OuchException(CommonErrorCode.MEMBER_NOT_FOUND)); + + SelfDiagnosis updatedDiagnosis = selfDiagnosisConverter.diagnosisUpdateRequestToSelfDiagnosis(diagnosis, user, + request); + + List symptomNames = request.getSymptoms(); + List foundSymptoms = symptomRepository.findByNameIn(symptomNames); + + // 이름으로 빠르게 찾기 위해 Map 으로 변환 + Map symptomMap = foundSymptoms.stream() + .collect(Collectors.toMap(Symptom::getName, s -> s)); + + for (String symptomName : symptomNames) { + Symptom foundSymptom = symptomMap.get(symptomName); + if (foundSymptom == null) { + throw new OuchException(DiagnosisErrorCode.SYMPTOM_NOT_FOUND); + } + + DiagnosisSymptom diagnosisSymptom = selfDiagnosisConverter.buildDiagnosisSymptom(updatedDiagnosis, + foundSymptom); + updatedDiagnosis.getDiagnosisSymptomList().add(diagnosisSymptom); + } + + selfDiagnosisRepository.save(updatedDiagnosis); + + return selfDiagnosisConverter.diagnosisToDiagnosisUpdateResponse(updatedDiagnosis); + } + + //특정 자가진단표에 증상 추가 + @Transactional + public void addSymptomsToSelfDiagnosis(Long diagnosisId, AddSymptomsToDiagnosisRequest request, Long userId) { + + SelfDiagnosis diagnosis = selfDiagnosisRepository.findByIdAndUserId(diagnosisId, userId) + .orElseThrow(() -> new OuchException(DiagnosisErrorCode.DIAGNOSIS_NOT_FOUND)); + + for (String symptom : request.getSymptoms()) { + + if (diagnosis.getDiagnosisSymptomList() + .stream() + .anyMatch(diagnosisSymptom -> diagnosisSymptom.getSymptom().getName().equals(symptom))) { + throw new OuchException(DiagnosisErrorCode.SYMPTOM_ALREADY_ADDED); + } + + Symptom foundSymptom = symptomRepository.findByName(symptom) + .orElseThrow(() -> new OuchException(DiagnosisErrorCode.SYMPTOM_NOT_FOUND)); + + DiagnosisSymptom diagnosisSymptom = selfDiagnosisConverter.buildDiagnosisSymptom(diagnosis, foundSymptom); + + diagnosis.getDiagnosisSymptomList().add(diagnosisSymptom); + + } + } +} + + diff --git a/src/main/java/com/onebridge/ouch/service/symptom/SymptomService.java b/src/main/java/com/onebridge/ouch/service/symptom/SymptomService.java new file mode 100644 index 0000000..f6c1945 --- /dev/null +++ b/src/main/java/com/onebridge/ouch/service/symptom/SymptomService.java @@ -0,0 +1,27 @@ +package com.onebridge.ouch.service.symptom; + +import java.util.List; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.onebridge.ouch.converter.SymptomConverter; +import com.onebridge.ouch.domain.Symptom; +import com.onebridge.ouch.dto.symptom.response.GetSymptomResponse; +import com.onebridge.ouch.repository.Symptom.SymptomRepository; + +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class SymptomService { + + private final SymptomRepository symptomRepository; + private final SymptomConverter symptomConverter; + + @Transactional + public List getSymptomsList() { + List symptoms = symptomRepository.findAll(); + return symptomConverter.symptomsToGetSymptomsResponse(symptoms); + } +} diff --git a/src/main/java/com/onebridge/ouch/service/user/UserService.java b/src/main/java/com/onebridge/ouch/service/user/UserService.java index cf0b474..fa7ad70 100644 --- a/src/main/java/com/onebridge/ouch/service/user/UserService.java +++ b/src/main/java/com/onebridge/ouch/service/user/UserService.java @@ -3,40 +3,38 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import com.onebridge.ouch.apiPayload.code.error.CommonErrorCode; +import com.onebridge.ouch.apiPayload.exception.OuchException; import com.onebridge.ouch.converter.UserConverter; -import com.onebridge.ouch.domain.Nation; import com.onebridge.ouch.domain.User; import com.onebridge.ouch.domain.enums.UserStatus; -import com.onebridge.ouch.dto.user.request.MypageUserInfoUpdateRequest; -import com.onebridge.ouch.dto.user.response.MypageUserInfoResponse; import com.onebridge.ouch.dto.user.response.UserInfoResponse; import com.onebridge.ouch.repository.nation.NationRepository; import com.onebridge.ouch.repository.user.UserRepository; +import lombok.AllArgsConstructor; + @Service +@AllArgsConstructor public class UserService { private final UserRepository userRepository; private final NationRepository nationRepository; private final UserConverter userConverter; - public UserService(UserRepository userRepository, NationRepository nationRepository, UserConverter userConverter) { - this.userRepository = userRepository; - this.nationRepository = nationRepository; - this.userConverter = userConverter; - } - + //유저 조회(테스트용) @Transactional(readOnly = true) public UserInfoResponse getUserInfo(Long id) { - User user = userRepository.findById(id).orElseThrow(() -> new RuntimeException("User not found")); + User user = userRepository.findById(id).orElseThrow(() -> new OuchException(CommonErrorCode.MEMBER_NOT_FOUND)); return userConverter.convertToUserInfoResponse(user); } + //유저 탈퇴(비활성화) @Transactional public void deactivateUser(Long userId) { User user = userRepository.findById(userId) - .orElseThrow(() -> new RuntimeException("User not found")); + .orElseThrow(() -> new OuchException(CommonErrorCode.MEMBER_NOT_FOUND)); User deactivatedUser = user.toBuilder() .status(UserStatus.INACTIVE) @@ -44,38 +42,6 @@ public void deactivateUser(Long userId) { userRepository.save(deactivatedUser); } - - @Transactional - public void deleteUser(Long id) { - User user = userRepository.findById(id).orElseThrow(() -> new RuntimeException("User not found")); - userRepository.delete(user); - } - - @Transactional(readOnly = true) - public MypageUserInfoResponse myPageGetUserInfo(Long userId) { - User user = userRepository.findById(userId) - .orElseThrow(() -> new RuntimeException("User not found")); - return userConverter.convertToMypageUserInfoResponse(user); - } - - @Transactional - public void myPageUpdateUserInfo(Long userId, MypageUserInfoUpdateRequest request) { - User user = userRepository.findById(userId) - .orElseThrow(() -> new RuntimeException("User not found")); - - Nation wantedNation = nationRepository.findById(request.getNationId()) - .orElseThrow(() -> new RuntimeException("Nation not found")); - - User updatedUser = user.toBuilder() - .nickname(request.getNickname()) - .phoneNumber(request.getPhoneNumber()) - .gender(request.getGender()) - .email(request.getEmail()) - .nation(wantedNation) - .build(); - - userRepository.save(updatedUser); - } }