diff --git a/src/main/java/com/carely/backend/code/ErrorCode.java b/src/main/java/com/carely/backend/code/ErrorCode.java index fca2e45..72cee8b 100644 --- a/src/main/java/com/carely/backend/code/ErrorCode.java +++ b/src/main/java/com/carely/backend/code/ErrorCode.java @@ -52,7 +52,7 @@ public enum ErrorCode { ALREADY_APPROVED(HttpStatus.NOT_ACCEPTABLE, "이미 승인된 약속입니다."), ALREADY_HAS_CERTIFICATE(HttpStatus.NOT_ACCEPTABLE, "이미 자격증이 존재하여 발급할 수 없습니다."), TOTAL_TIME_NOT_ENOUGH(HttpStatus.NOT_ACCEPTABLE, "실습 시간이 충분하지 않아 자격증을 발급할 수 없습니다."), - + NO_FILE(HttpStatus.NOT_ACCEPTABLE, "요양보호사로 회원가입 시 자격증 사진이 필요합니다."), diff --git a/src/main/java/com/carely/backend/controller/UserController.java b/src/main/java/com/carely/backend/controller/UserController.java index e0ccd95..e31e374 100644 --- a/src/main/java/com/carely/backend/controller/UserController.java +++ b/src/main/java/com/carely/backend/controller/UserController.java @@ -41,9 +41,9 @@ public class UserController implements UserAPI { private final RefreshRepository refreshRedisRepository; private final JWTUtil jwtUtil; - @PostMapping(value = "/register", produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity registerUser(@RequestPart("registerDTO") RegisterDTO registerDTO) throws IOException { - RegisterDTO.Res res = userService.register(registerDTO); + @PostMapping(value = "/register", consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity registerUser(@RequestPart("registerDTO") RegisterDTO registerDTO, @RequestPart MultipartFile file) throws IOException { + RegisterDTO.Res res = userService.register(registerDTO, file); return ResponseEntity .status(SuccessCode.SUCCESS_REGISTER.getStatus().value()) .body(new ResponseDTO<>(SuccessCode.SUCCESS_REGISTER, res)); diff --git a/src/main/java/com/carely/backend/controller/docs/UserAPI.java b/src/main/java/com/carely/backend/controller/docs/UserAPI.java index 442a54b..bfc6533 100644 --- a/src/main/java/com/carely/backend/controller/docs/UserAPI.java +++ b/src/main/java/com/carely/backend/controller/docs/UserAPI.java @@ -34,14 +34,20 @@ public interface UserAPI { examples = @ExampleObject(value = "{ \"status\": 200, \"code\": \"SUCCESS_REGISTER\", \"message\": \"회원가입을 성공했습니다.\", \"data\": { \"kakaoId\": \"377747839\", \"userType\": \"VOLUNTEER\", \"username\": \"김은서\", \"age\": 22, \"phoneNum\": \"010-8230-2512\", \"address\": \"경기도 과천시 과천동 376-17\", \"detailAddress\": \"202호\", \"locationAuthentication\": true } }") ) ), + @ApiResponse(responseCode = "406", description = "요양보호사이지만 이미지 파일이 없는 경우", + content = @Content(mediaType = "application/json", + schema = @Schema(implementation = ErrorResponseDTO.class), + examples = @ExampleObject(value = "{ \"status\": 406, \"error\": \"CONFLICT\", \"code\": \"NO_FILE\", \"message\": \"요양보호사로 회원가입 시 자격증 사진이 필요합니다.\" }")) + ), @ApiResponse(responseCode = "409", description = "데이베이스에 존재하는 회원이 회원가입을 진행할 경우", content = @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponseDTO.class), examples = @ExampleObject(value = "{ \"status\": 409, \"error\": \"CONFLICT\", \"code\": \"DUPLICATE_USERNAME\", \"message\": \"중복된 유저 이름입니다.\" }")) ), + }) - public ResponseEntity registerUser(@RequestPart("registerDTO") RegisterDTO registerDTO) throws IOException; + public ResponseEntity registerUser(@RequestPart("registerDTO") RegisterDTO registerDTO, @RequestPart MultipartFile file) throws IOException; @Operation(summary = "access token 재발급하기", parameters = { diff --git a/src/main/java/com/carely/backend/domain/User.java b/src/main/java/com/carely/backend/domain/User.java index 14401a0..e1723a8 100644 --- a/src/main/java/com/carely/backend/domain/User.java +++ b/src/main/java/com/carely/backend/domain/User.java @@ -49,6 +49,9 @@ public class User extends BaseEntity { //주민등록번호 private String identity; + //자격증 이미지 + private String certificateImage; + // ai 요약 @Column(columnDefinition = "TEXT") private String aiSummary; @@ -81,7 +84,7 @@ public class User extends BaseEntity { @Builder(builderMethodName = "userBuilder") public User(String kakaoId, UserType userType, String role, String username, Integer age, String phoneNum, String city, String address, String detailAddress, Boolean locationAuthentication, Boolean shareLocation, - String talk, String eat, String toilet, String bath, String walk, String story, String identity + String talk, String eat, String toilet, String bath, String walk, String story, String identity, String imageUrl ) { this.kakaoId = kakaoId; this.userType = userType; @@ -102,6 +105,7 @@ public User(String kakaoId, UserType userType, String role, String username, Int this.story = story; this.certificateCheck = false; this.identity = identity; + this.certificateImage = imageUrl; } // 로그인 diff --git a/src/main/java/com/carely/backend/dto/user/RegisterDTO.java b/src/main/java/com/carely/backend/dto/user/RegisterDTO.java index a582c0d..77b2e37 100644 --- a/src/main/java/com/carely/backend/dto/user/RegisterDTO.java +++ b/src/main/java/com/carely/backend/dto/user/RegisterDTO.java @@ -8,6 +8,7 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; +import org.springframework.web.multipart.MultipartFile; @Getter @Builder @@ -56,6 +57,8 @@ public class RegisterDTO { @NotNull private Boolean shareLocation; + private String identity; + @Getter @Builder @NoArgsConstructor diff --git a/src/main/java/com/carely/backend/exception/GlobalHandleException.java b/src/main/java/com/carely/backend/exception/GlobalHandleException.java index 73ccd1c..135c552 100644 --- a/src/main/java/com/carely/backend/exception/GlobalHandleException.java +++ b/src/main/java/com/carely/backend/exception/GlobalHandleException.java @@ -71,6 +71,13 @@ protected ResponseEntity handleAlreadyHasCertificateException( .body(new ErrorResponseDTO(ErrorCode.ALREADY_HAS_CERTIFICATE)); } + @ExceptionHandler(NoFileException.class) + protected ResponseEntity handleNoFileException(final NoFileException e) { + return ResponseEntity + .status(ErrorCode.NO_FILE.getStatus().value()) + .body(new ErrorResponseDTO(ErrorCode.NO_FILE)); + } + @ExceptionHandler(TotalTimeNotEnoughException.class) protected ResponseEntity handleTotalTimeNotEnoughException(final TotalTimeNotEnoughException e) { return ResponseEntity diff --git a/src/main/java/com/carely/backend/exception/NoFileException.java b/src/main/java/com/carely/backend/exception/NoFileException.java new file mode 100644 index 0000000..31583cb --- /dev/null +++ b/src/main/java/com/carely/backend/exception/NoFileException.java @@ -0,0 +1,7 @@ +package com.carely.backend.exception; + +public class NoFileException extends RuntimeException{ + public NoFileException(String message) { + super(message); + } +} diff --git a/src/main/java/com/carely/backend/service/UserService.java b/src/main/java/com/carely/backend/service/UserService.java index 19a0197..2d0806c 100644 --- a/src/main/java/com/carely/backend/service/UserService.java +++ b/src/main/java/com/carely/backend/service/UserService.java @@ -6,10 +6,12 @@ import com.carely.backend.dto.user.*; import com.carely.backend.exception.DuplicateUsernameException; import com.carely.backend.exception.KakaoIdNotFoundException; +import com.carely.backend.exception.NoFileException; import com.carely.backend.exception.UserNotFoundException; import com.carely.backend.repository.UserRepository; import com.carely.backend.repository.VolunteerRepository; import com.carely.backend.service.kakao.KakaoAddressService; +import com.carely.backend.service.ocr.OCRService; import com.carely.backend.service.parser.AddressParser; import lombok.RequiredArgsConstructor; import org.springframework.security.core.userdetails.UsernameNotFoundException; @@ -27,9 +29,15 @@ public class UserService { private final UserRepository userRepository; private final VolunteerRepository volunteerRepository; + private final OCRService ocrService; // private final KakaoAddressService kakaoAddressService; - public RegisterDTO.Res register(RegisterDTO registerDTO) { + public RegisterDTO.Res register(RegisterDTO registerDTO, MultipartFile file) throws IOException { + if (file.isEmpty() && registerDTO.getUserType().equals(UserType.CARE_WORKER)) { + throw new NoFileException("파일 없는데"); + } + String imageUrl = ocrService.uploadCertificateImage(file, registerDTO.getKakaoId()); + String username = registerDTO.getUsername(); UserType userType = registerDTO.getUserType(); String kakaoId = registerDTO.getKakaoId(); @@ -79,6 +87,8 @@ public RegisterDTO.Res register(RegisterDTO registerDTO) { .latitude(latitude) .longitude(longitude) .certificateCheck(false) + .identity(registerDTO.getIdentity()) + .certificateImage(imageUrl) .build(); return RegisterDTO.Res.toDTO(userRepository.save(user)); diff --git a/src/main/java/com/carely/backend/service/ocr/OCRService.java b/src/main/java/com/carely/backend/service/ocr/OCRService.java index a744864..54726e3 100644 --- a/src/main/java/com/carely/backend/service/ocr/OCRService.java +++ b/src/main/java/com/carely/backend/service/ocr/OCRService.java @@ -6,6 +6,7 @@ import com.carely.backend.exception.UserNotMatchException; import com.carely.backend.repository.UserRepository; import com.carely.backend.service.certificate.CertificateService; +import com.carely.backend.service.s3.S3Uploader; import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; import org.json.JSONArray; @@ -15,6 +16,7 @@ import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; @@ -28,8 +30,20 @@ @Service @RequiredArgsConstructor public class OCRService { - private final UserRepository userRepository; - private final CertificateService certificateService; + private S3Uploader s3Uploader; + private UserRepository userRepository; + + public String uploadCertificateImage(MultipartFile file, String kakaoId) throws IOException { + User user = userRepository.findByKakaoId(kakaoId) + .orElseThrow(() -> new UsernameNotFoundException("사용자를 찾을 수 없습니다.")); + + return s3Uploader.upload(file, "certificate"); + } + + + + //private final UserRepository userRepository; + //private final CertificateService certificateService; @Value("${google.vision.api-key}") private String apiKey;