diff --git a/src/main/java/space/space_spring/controller/PayController.java b/src/main/java/space/space_spring/controller/PayController.java index adea96b4..efebbfb0 100644 --- a/src/main/java/space/space_spring/controller/PayController.java +++ b/src/main/java/space/space_spring/controller/PayController.java @@ -4,14 +4,18 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.*; import space.space_spring.argument_resolver.jwtLogin.JwtLoginAuth; -import space.space_spring.dto.pay.*; -import space.space_spring.entity.UserSpace; +import space.space_spring.dto.pay.dto.PayReceiveInfoDto; +import space.space_spring.dto.pay.dto.PayRequestInfoDto; +import space.space_spring.dto.pay.dto.PayTargetInfoDto; +import space.space_spring.dto.pay.dto.TotalPayInfoDto; +import space.space_spring.dto.pay.request.PostPayCompleteRequest; +import space.space_spring.dto.pay.request.PostPayCreateRequest; +import space.space_spring.dto.pay.response.*; import space.space_spring.response.BaseResponse; import space.space_spring.service.PayService; import space.space_spring.util.userSpace.UserSpaceUtils; import java.util.List; -import java.util.Optional; @RestController @RequiredArgsConstructor @@ -47,7 +51,7 @@ private void validateIsUserInSpace(Long userId, Long spaceId) { } /** - * 내가 요청한 정산 view + * 내가 요청한 정산 조회 */ @GetMapping("/space/{spaceId}/pay/request") public BaseResponse showRequestPayListForUser(@JwtLoginAuth Long userId, @PathVariable Long spaceId) { @@ -63,6 +67,24 @@ public BaseResponse showRequestPayListForUser(@JwtLog return new BaseResponse<>(new GetRequestPayViewResponse(payRequestInfoDtoListInComplete, payRequestInfoDtoListComplete)); } + /** + * 내가 요청받은 정산 조회 + */ + @GetMapping("/space/{spaceId}/pay/receive") + public BaseResponse showReceivePayListForUser(@JwtLoginAuth Long userId, @PathVariable Long spaceId) { + // TODO 1. 유저가 스페이스에 속하는 지 검증 -> 추후에 인터셉터에서 처리하게끔 리펙토링 필요 + validateIsUserInSpace(userId, spaceId); + + // TODO 2. 유저가 요청받은 정산 중 현재 진행중인 정산 리스트 get -> 정산 타겟 유저가 정산 안했을 경우 : isComplete = false + List payReceiveInfoDtoListInComplete = payService.getPayReceiveInfoForUser(userId, spaceId, false); + + // TODO 3. 유저가 요청받은 정산 중 완료한 정산 리스트 get -> 정산 타겟 유저가 정산 했을 경우 : isComplete = true + List payReceiveInfoDtoListComplete = payService.getPayReceiveInfoForUser(userId, spaceId, true); + + return new BaseResponse<>(new GetReceivePayViewResponse(payReceiveInfoDtoListInComplete, payReceiveInfoDtoListComplete)); + } + + /** * 유저가 최근 정산받은 은행 계좌 정보 조회 * 해당 api는 유저가 속한 스페이스의 정보가 필요없다고 판단해서 spaceId 를 request로 받지 않음 @@ -92,11 +114,38 @@ public BaseResponse createPay(@JwtLoginAuth Long userId, @PathVariable L } // TODO 3. PostPayCreateRequest의 bankName, bankAccountNum 검증 - // 이거 해야할까?? 프론트단 분들과 논의 필요 + // 만약 이걸 해야할 경우, @RequestBody 를 validate 하는 방식으로 검증 수행해야 할 듯 // TODO 4. 정산 생성 payService.createPay(userId, spaceId, postPayCreateRequest); return new BaseResponse<>("정산 생성 성공"); } + + /** + * 하나의 정산에 대한 상세정보 조회 + */ + @GetMapping("/space/{spaceId}/pay/{payRequestId}") + public BaseResponse showTotalPayInfo(@JwtLoginAuth Long userId, @PathVariable Long spaceId, @PathVariable Long payRequestId) { + + // TODO 1. 유저가 스페이스에 속하는 지 검증 + validateIsUserInSpace(userId, spaceId); + + // TODO 2. 정산 상세 정보 조회 + return new BaseResponse<>(payService.getTotalPayInfo(spaceId, payRequestId)); + } + + /** + * 정산 타겟 유저의 정산 완료 처리 + */ + @PostMapping("/space/{spaceId}/pay/complete") + public BaseResponse setPayComplete(@JwtLoginAuth Long userId, @PathVariable Long spaceId, @RequestBody PostPayCompleteRequest postPayCompleteRequest) { + + // TODO 1. 유저가 스페이스에 속하는 지 검증 + validateIsUserInSpace(userId, spaceId); + + // TODO 2. 정산 타겟 유저의 정산 완료 처리 + return new BaseResponse<>(payService.setPayRequestTargetToComplete(postPayCompleteRequest.getPayRequestTargetId())); + } + } diff --git a/src/main/java/space/space_spring/controller/SpaceController.java b/src/main/java/space/space_spring/controller/SpaceController.java index 057154ce..62b49e63 100644 --- a/src/main/java/space/space_spring/controller/SpaceController.java +++ b/src/main/java/space/space_spring/controller/SpaceController.java @@ -5,22 +5,21 @@ import org.springframework.validation.BindingResult; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; import space.space_spring.argument_resolver.jwtLogin.JwtLoginAuth; -import space.space_spring.dto.space.GetUserInfoBySpaceResponse; -import space.space_spring.dto.space.PostSpaceCreateRequest; -import space.space_spring.dto.space.PostSpaceCreateResponse; +import space.space_spring.dto.space.response.GetUserInfoBySpaceResponse; +import space.space_spring.dto.space.request.PostSpaceCreateRequest; -import space.space_spring.entity.UserSpace; +import space.space_spring.exception.MultipartFileException; import space.space_spring.exception.SpaceException; import space.space_spring.response.BaseResponse; import space.space_spring.service.S3Uploader; import space.space_spring.service.SpaceService; -import space.space_spring.util.userSpace.UserSpaceUtils; import java.io.IOException; -import java.util.Optional; import static space.space_spring.response.status.BaseExceptionResponseStatus.INVALID_SPACE_CREATE; +import static space.space_spring.response.status.BaseExceptionResponseStatus.IS_NOT_IMAGE_FILE; import static space.space_spring.util.bindingResult.BindingResultUtils.getErrorMessage; @RestController @@ -30,33 +29,37 @@ public class SpaceController { private final SpaceService spaceService; - private final UserSpaceUtils userSpaceUtils; private final S3Uploader s3Uploader; private final String spaceImgDirName = "spaceImg"; - @PostMapping("/create") - public BaseResponse createSpace(@JwtLoginAuth Long userId, @Validated @ModelAttribute PostSpaceCreateRequest postSpaceCreateRequest, BindingResult bindingResult) throws IOException { + @PostMapping("") + public BaseResponse createSpace(@JwtLoginAuth Long userId, @Validated @ModelAttribute PostSpaceCreateRequest postSpaceCreateRequest, BindingResult bindingResult) throws IOException { if (bindingResult.hasErrors()) { throw new SpaceException(INVALID_SPACE_CREATE, getErrorMessage(bindingResult)); } // TODO 1. 스페이스 썸네일을 s3에 upload - String spaceImgUrl = s3Uploader.upload(postSpaceCreateRequest.getSpaceProfileImg(), spaceImgDirName); + String spaceImgUrl = processSpaceImage(postSpaceCreateRequest.getSpaceProfileImg()); // TODO 2. s3에 저장하고 받은 이미지 url 정보와 spaceName 정보로 space create 작업 수행 - return new BaseResponse<>(spaceService.createSpace(userId, postSpaceCreateRequest.getSpaceName(), spaceImgUrl)); + spaceService.createSpace(userId, postSpaceCreateRequest.getSpaceName(), spaceImgUrl); + + return new BaseResponse<>("스페이스 생성 성공"); } - /** - * 테스트 용 - */ - @GetMapping("/{spaceId}") - public BaseResponse getSpaceHome(@JwtLoginAuth Long userId, @PathVariable Long spaceId) { - Optional userInSpace = userSpaceUtils.isUserInSpace(userId, spaceId); - log.info("userInSpace.get().getUserName() = {}", userInSpace.get().getUserName()); - log.info("userInspace.get().getUserSpaceAuth() = {}", userInSpace.get().getUserSpaceAuth()); + private String processSpaceImage(MultipartFile spaceProfileImg) throws IOException { + if (spaceProfileImg == null) { + return null; + } + validateImageFile(spaceProfileImg); + return s3Uploader.upload(spaceProfileImg, spaceImgDirName); - return new BaseResponse<>("스페이스에 속한 유저만 걸러내는 작업 테스트 성공"); + } + + private void validateImageFile(MultipartFile spaceProfileImg) { + if (!s3Uploader.isFileImage(spaceProfileImg)) { + throw new MultipartFileException(IS_NOT_IMAGE_FILE); + } } /** diff --git a/src/main/java/space/space_spring/controller/UserController.java b/src/main/java/space/space_spring/controller/UserController.java index fc7f3be9..0a053a27 100644 --- a/src/main/java/space/space_spring/controller/UserController.java +++ b/src/main/java/space/space_spring/controller/UserController.java @@ -7,14 +7,14 @@ import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import space.space_spring.argument_resolver.jwtLogin.JwtLoginAuth; -import space.space_spring.dto.user.*; +import space.space_spring.dto.user.request.PostUserLoginRequest; +import space.space_spring.dto.user.request.PostUserSignupRequest; +import space.space_spring.dto.user.response.GetSpaceInfoForUserResponse; import space.space_spring.exception.UserException; import space.space_spring.response.BaseResponse; import space.space_spring.service.UserService; import space.space_spring.util.userSpace.UserSpaceUtils; -import java.util.List; - import static space.space_spring.response.status.BaseExceptionResponseStatus.*; import static space.space_spring.util.bindingResult.BindingResultUtils.getErrorMessage; @@ -31,25 +31,29 @@ public class UserController { * 회원가입 */ @PostMapping("/signup") - public BaseResponse signup(@Validated @RequestBody PostUserSignupRequest postUserSignupRequest, BindingResult bindingResult) { + public BaseResponse signup(@Validated @RequestBody PostUserSignupRequest postUserSignupRequest, BindingResult bindingResult) { if (bindingResult.hasErrors()) { throw new UserException(INVALID_USER_SIGNUP, getErrorMessage(bindingResult)); } - return new BaseResponse<>(userService.signup(postUserSignupRequest)); + + userService.signup(postUserSignupRequest); + + return new BaseResponse<>("로컬 회원가입 성공"); } /** * 로그인 */ @PostMapping("/login") - public BaseResponse login(@Validated @RequestBody PostUserLoginRequest postUserLoginRequest, BindingResult bindingResult, HttpServletResponse response) { + public BaseResponse login(@Validated @RequestBody PostUserLoginRequest postUserLoginRequest, BindingResult bindingResult, HttpServletResponse response) { if (bindingResult.hasErrors()) { throw new UserException(INVALID_USER_LOGIN, getErrorMessage(bindingResult)); } String jwtLogin = userService.login(postUserLoginRequest); response.setHeader("Authorization", "Bearer " + jwtLogin); - return new BaseResponse<>(new PostUserLoginResponse("로그인 성공")); + + return new BaseResponse<>("로컬 로그인 성공"); } /** @@ -61,8 +65,6 @@ public BaseResponse showUserSpaceList(@JwtLoginAuth @RequestParam int size, @RequestParam Long lastUserSpaceId) { - log.info("userId = {}", userId); - return new BaseResponse<>(userService.getSpaceListForUser(userId, size, lastUserSpaceId)); } diff --git a/src/main/java/space/space_spring/dao/PayDao.java b/src/main/java/space/space_spring/dao/PayDao.java index a3321288..777c5239 100644 --- a/src/main/java/space/space_spring/dao/PayDao.java +++ b/src/main/java/space/space_spring/dao/PayDao.java @@ -4,13 +4,14 @@ import jakarta.persistence.PersistenceContext; import jakarta.persistence.TypedQuery; import org.springframework.stereotype.Repository; -import space.space_spring.dto.pay.RecentPayRequestBankInfoDto; +import space.space_spring.dto.pay.dto.PayRequestInfoDto; +import space.space_spring.dto.pay.dto.RecentPayRequestBankInfoDto; +import space.space_spring.dto.pay.dto.TotalPayInfoDto; import space.space_spring.entity.PayRequest; import space.space_spring.entity.PayRequestTarget; import space.space_spring.entity.Space; import space.space_spring.entity.User; -import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -88,4 +89,14 @@ public PayRequestTarget createPayRequestTarget(PayRequest payRequest, Long targe em.persist(payRequestTarget); return payRequestTarget; } + + public PayRequest findPayRequestById(Long payRequestId) { + + return em.find(PayRequest.class, payRequestId); + } + + public PayRequestTarget findPayRequestTargetById(Long payRequestTargetId) { + return em.find(PayRequestTarget.class, payRequestTargetId); + } + } diff --git a/src/main/java/space/space_spring/dao/SpaceDao.java b/src/main/java/space/space_spring/dao/SpaceDao.java index 604b23a4..1786868c 100644 --- a/src/main/java/space/space_spring/dao/SpaceDao.java +++ b/src/main/java/space/space_spring/dao/SpaceDao.java @@ -4,11 +4,6 @@ import jakarta.persistence.PersistenceContext; import org.springframework.stereotype.Repository; import space.space_spring.entity.Space; -import space.space_spring.entity.User; -import space.space_spring.entity.UserSpace; -import space.space_spring.dto.space.PostSpaceCreateRequest; - -import static space.space_spring.entity.enumStatus.UserSpaceAuth.MANAGER; @Repository public class SpaceDao { diff --git a/src/main/java/space/space_spring/dao/UserDao.java b/src/main/java/space/space_spring/dao/UserDao.java index f38f2846..1814c5b1 100644 --- a/src/main/java/space/space_spring/dao/UserDao.java +++ b/src/main/java/space/space_spring/dao/UserDao.java @@ -6,7 +6,6 @@ import jakarta.persistence.TypedQuery; import org.springframework.stereotype.Repository; import space.space_spring.entity.User; -import space.space_spring.dto.user.PostUserSignupRequest; import space.space_spring.entity.enumStatus.UserSignupType; @Repository diff --git a/src/main/java/space/space_spring/dao/UserSpaceDao.java b/src/main/java/space/space_spring/dao/UserSpaceDao.java index d89fb717..c02228da 100644 --- a/src/main/java/space/space_spring/dao/UserSpaceDao.java +++ b/src/main/java/space/space_spring/dao/UserSpaceDao.java @@ -4,9 +4,9 @@ import jakarta.persistence.PersistenceContext; import jakarta.persistence.TypedQuery; import org.springframework.stereotype.Repository; -import space.space_spring.dto.user.GetSpaceInfoForUserResponse; -import space.space_spring.dto.user.SpaceChoiceViewDto; -import space.space_spring.dto.userSpace.UserProfileImgAndNameDto; +import space.space_spring.dto.user.dto.SpaceChoiceInfo; +import space.space_spring.dto.user.dto.SpaceChoiceViewDto; +import space.space_spring.dto.userSpace.UserInfoInSpace; import space.space_spring.entity.Space; import space.space_spring.entity.User; import space.space_spring.entity.UserSpace; @@ -31,7 +31,7 @@ public UserSpace createUserSpace(User manager, Space saveSpace) { public Optional findUserSpaceByUserAndSpace(User user, Space space) { TypedQuery query = em.createQuery( - "SELECT us FROM UserSpace us WHERE us.user = :user AND us.space = :space", UserSpace.class); + "SELECT us FROM UserSpace us WHERE us.user = :user AND us.space = :space AND us.status = 'ACTIVE'", UserSpace.class); query.setParameter("user", user); query.setParameter("space", space); @@ -41,7 +41,7 @@ public Optional findUserSpaceByUserAndSpace(User user, Space space) { public SpaceChoiceViewDto getSpaceChoiceView(User userByUserId, int size, Long lastUserSpaceId) { // 유저가 현재 속해있는 스페이스의 정보만을 return하기 위해 status가 active인 것만 select - String jpql = "SELECT us.userSpaceId, s.spaceName, s.spaceProfileImg " + + String jpql = "SELECT us.userSpaceId, s.spaceId, s.spaceName, s.spaceProfileImg " + "FROM UserSpace us JOIN us.space s " + "WHERE us.user = :user AND us.status = 'ACTIVE' " + "AND us.userSpaceId > :lastUserSpaceId ORDER BY us.userSpaceId ASC"; @@ -52,41 +52,60 @@ public SpaceChoiceViewDto getSpaceChoiceView(User userByUserId, int size, Long l query.setMaxResults(size); List results = query.getResultList(); - List> responseList = new ArrayList<>(); - Long newLastUserSpaceId = null; - for (Object[] result : results) { - Long userSpaceId = (Long) result[0]; - String spaceName = (String) result[1]; - String spaceProfileImg = (String) result[2]; - Map spaceNameAndProfileImgMap = new HashMap<>(); - spaceNameAndProfileImgMap.put("spaceName", spaceName); - spaceNameAndProfileImgMap.put("spaceProfileImg", spaceProfileImg); - responseList.add(spaceNameAndProfileImgMap); - newLastUserSpaceId = userSpaceId; - } + List spaceChoiceInfoList = mapToSpaceChoiceInfoList(results); + + Long newLastUserSpaceId = determineLastUserSpaceId(results); + + return new SpaceChoiceViewDto(spaceChoiceInfoList, newLastUserSpaceId); + } - // 데이터가 마지막임을 알리기 위해 -1 설정 + private Long determineLastUserSpaceId(List results) { if (results.isEmpty()) { - newLastUserSpaceId = -1L; + return -1L; // 더 이상 조회할 데이터가 없음을 표시 } + // results가 비어있지 않다면 마지막 userSpaceId를 반환 + return (Long) results.get(results.size() - 1)[0]; + } + + private List mapToSpaceChoiceInfoList(List results) { + List spaceChoiceInfoList = new ArrayList<>(); + for (Object[] result : results) { + Long spaceId = (Long) result[1]; + String spaceName = (String) result[2]; + String spaceProfileImg = (String) result[3]; - return new SpaceChoiceViewDto(responseList, newLastUserSpaceId); + SpaceChoiceInfo spaceChoiceInfo = new SpaceChoiceInfo(spaceId, spaceName, spaceProfileImg); + spaceChoiceInfoList.add(spaceChoiceInfo); + } + return spaceChoiceInfoList; } - public List findUserProfileImgAndName(Space space) { - String jpql = "SELECT us.userName, us.userProfileImg FROM UserSpace us WHERE us.space = :space"; + public List findUserInfoInSpace(Space space) { + String jpql = "SELECT us.user.userId, us.userName, us.userProfileImg, us.userSpaceAuth " + + "FROM UserSpace us WHERE us.space = :space"; TypedQuery query = em.createQuery(jpql, Object[].class); query.setParameter("space", space); List results = query.getResultList(); - List responseList = new ArrayList<>(); + + return mapToUserInfoInSpace(results); + } + + private List mapToUserInfoInSpace(List results) { + List userInfoInSpaceList = new ArrayList<>(); + for (Object[] result : results) { - String userName = (String) result[0]; - String profileImg = (String) result[1]; - responseList.add(new UserProfileImgAndNameDto(userName, profileImg)); + Long userId = (Long) result[0]; + String userName = (String) result[1]; + String profileImgUrl = (String) result[2]; + String userAuth = (String) result[3]; + + UserInfoInSpace userInfoInSpace = new UserInfoInSpace(userId, userName, profileImgUrl, userAuth); + userInfoInSpaceList.add(userInfoInSpace); } - return responseList; + return userInfoInSpaceList; } + } diff --git a/src/main/java/space/space_spring/dto/pay/PayReceiveInfoDto.java b/src/main/java/space/space_spring/dto/pay/dto/PayReceiveInfoDto.java similarity index 70% rename from src/main/java/space/space_spring/dto/pay/PayReceiveInfoDto.java rename to src/main/java/space/space_spring/dto/pay/dto/PayReceiveInfoDto.java index 0d57aeb2..61146f5a 100644 --- a/src/main/java/space/space_spring/dto/pay/PayReceiveInfoDto.java +++ b/src/main/java/space/space_spring/dto/pay/dto/PayReceiveInfoDto.java @@ -1,4 +1,4 @@ -package space.space_spring.dto.pay; +package space.space_spring.dto.pay.dto; import lombok.AllArgsConstructor; import lombok.Getter; @@ -7,6 +7,8 @@ @AllArgsConstructor public class PayReceiveInfoDto { + private Long payRequestTargetId; + private String payCreatorName; private int requestAmount; diff --git a/src/main/java/space/space_spring/dto/pay/PayRequestInfoDto.java b/src/main/java/space/space_spring/dto/pay/dto/PayRequestInfoDto.java similarity index 84% rename from src/main/java/space/space_spring/dto/pay/PayRequestInfoDto.java rename to src/main/java/space/space_spring/dto/pay/dto/PayRequestInfoDto.java index 92dfa440..4c289bd2 100644 --- a/src/main/java/space/space_spring/dto/pay/PayRequestInfoDto.java +++ b/src/main/java/space/space_spring/dto/pay/dto/PayRequestInfoDto.java @@ -1,4 +1,4 @@ -package space.space_spring.dto.pay; +package space.space_spring.dto.pay.dto; import lombok.AllArgsConstructor; import lombok.Getter; @@ -7,6 +7,8 @@ @AllArgsConstructor public class PayRequestInfoDto { + private Long payRequestId; + private int totalAmount; // 정산 총 금액 private int receiveAmount; // 현재까지 받은 금액 diff --git a/src/main/java/space/space_spring/dto/pay/dto/PayTargetInfoDto.java b/src/main/java/space/space_spring/dto/pay/dto/PayTargetInfoDto.java new file mode 100644 index 00000000..971e84c3 --- /dev/null +++ b/src/main/java/space/space_spring/dto/pay/dto/PayTargetInfoDto.java @@ -0,0 +1,19 @@ +package space.space_spring.dto.pay.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class PayTargetInfoDto { + + private Long targetUserId; + + private String targetUserName; + + private String targetUserProfileImg; + + private int requestAmount; + + private boolean isComplete; +} diff --git a/src/main/java/space/space_spring/dto/pay/RecentPayRequestBankInfoDto.java b/src/main/java/space/space_spring/dto/pay/dto/RecentPayRequestBankInfoDto.java similarity index 83% rename from src/main/java/space/space_spring/dto/pay/RecentPayRequestBankInfoDto.java rename to src/main/java/space/space_spring/dto/pay/dto/RecentPayRequestBankInfoDto.java index 3a540d50..3c070998 100644 --- a/src/main/java/space/space_spring/dto/pay/RecentPayRequestBankInfoDto.java +++ b/src/main/java/space/space_spring/dto/pay/dto/RecentPayRequestBankInfoDto.java @@ -1,4 +1,4 @@ -package space.space_spring.dto.pay; +package space.space_spring.dto.pay.dto; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/src/main/java/space/space_spring/dto/pay/dto/TotalPayInfoDto.java b/src/main/java/space/space_spring/dto/pay/dto/TotalPayInfoDto.java new file mode 100644 index 00000000..5a2de372 --- /dev/null +++ b/src/main/java/space/space_spring/dto/pay/dto/TotalPayInfoDto.java @@ -0,0 +1,31 @@ +package space.space_spring.dto.pay.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.ArrayList; +import java.util.List; + +@Getter +@AllArgsConstructor +public class TotalPayInfoDto { + + private Long payRequestId; + + private String bankName; + + private String bankAccountNum; + + private int totalAmount; + + private int receiveAmount; + + private int totalTargetNum; + + private int receiveTargetNum; + + private List payTargetInfoDtoList = new ArrayList<>(); + + private boolean isComplete; + +} diff --git a/src/main/java/space/space_spring/dto/pay/request/PostPayCompleteRequest.java b/src/main/java/space/space_spring/dto/pay/request/PostPayCompleteRequest.java new file mode 100644 index 00000000..bfb53dd0 --- /dev/null +++ b/src/main/java/space/space_spring/dto/pay/request/PostPayCompleteRequest.java @@ -0,0 +1,14 @@ +package space.space_spring.dto.pay.request; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class PostPayCompleteRequest { + + private Long payRequestTargetId; + +} diff --git a/src/main/java/space/space_spring/dto/pay/PostPayCreateRequest.java b/src/main/java/space/space_spring/dto/pay/request/PostPayCreateRequest.java similarity index 92% rename from src/main/java/space/space_spring/dto/pay/PostPayCreateRequest.java rename to src/main/java/space/space_spring/dto/pay/request/PostPayCreateRequest.java index c50a1a53..295f57fa 100644 --- a/src/main/java/space/space_spring/dto/pay/PostPayCreateRequest.java +++ b/src/main/java/space/space_spring/dto/pay/request/PostPayCreateRequest.java @@ -1,4 +1,4 @@ -package space.space_spring.dto.pay; +package space.space_spring.dto.pay.request; import lombok.AllArgsConstructor; import lombok.Getter; @@ -6,7 +6,6 @@ import java.util.ArrayList; import java.util.List; -import java.util.Map; @Getter @NoArgsConstructor diff --git a/src/main/java/space/space_spring/dto/pay/GetPayViewResponse.java b/src/main/java/space/space_spring/dto/pay/response/GetPayViewResponse.java similarity index 67% rename from src/main/java/space/space_spring/dto/pay/GetPayViewResponse.java rename to src/main/java/space/space_spring/dto/pay/response/GetPayViewResponse.java index 2d2b7305..a3904f4d 100644 --- a/src/main/java/space/space_spring/dto/pay/GetPayViewResponse.java +++ b/src/main/java/space/space_spring/dto/pay/response/GetPayViewResponse.java @@ -1,7 +1,9 @@ -package space.space_spring.dto.pay; +package space.space_spring.dto.pay.response; import lombok.AllArgsConstructor; import lombok.Getter; +import space.space_spring.dto.pay.dto.PayReceiveInfoDto; +import space.space_spring.dto.pay.dto.PayRequestInfoDto; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/space/space_spring/dto/pay/response/GetReceivePayViewResponse.java b/src/main/java/space/space_spring/dto/pay/response/GetReceivePayViewResponse.java new file mode 100644 index 00000000..e9f7e3f3 --- /dev/null +++ b/src/main/java/space/space_spring/dto/pay/response/GetReceivePayViewResponse.java @@ -0,0 +1,17 @@ +package space.space_spring.dto.pay.response; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import space.space_spring.dto.pay.dto.PayReceiveInfoDto; + +import java.util.ArrayList; +import java.util.List; + +@Getter +@AllArgsConstructor +public class GetReceivePayViewResponse { + + private List payReceiveInfoDtoListIncomplete = new ArrayList<>(); + + private List payReceiveInfoDtoListComplete = new ArrayList<>(); +} diff --git a/src/main/java/space/space_spring/dto/pay/GetRecentPayRequestBankInfoResponse.java b/src/main/java/space/space_spring/dto/pay/response/GetRecentPayRequestBankInfoResponse.java similarity index 72% rename from src/main/java/space/space_spring/dto/pay/GetRecentPayRequestBankInfoResponse.java rename to src/main/java/space/space_spring/dto/pay/response/GetRecentPayRequestBankInfoResponse.java index 42b348d9..2e2f9ef0 100644 --- a/src/main/java/space/space_spring/dto/pay/GetRecentPayRequestBankInfoResponse.java +++ b/src/main/java/space/space_spring/dto/pay/response/GetRecentPayRequestBankInfoResponse.java @@ -1,7 +1,8 @@ -package space.space_spring.dto.pay; +package space.space_spring.dto.pay.response; import lombok.AllArgsConstructor; import lombok.Getter; +import space.space_spring.dto.pay.dto.RecentPayRequestBankInfoDto; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/space/space_spring/dto/pay/GetRequestPayViewResponse.java b/src/main/java/space/space_spring/dto/pay/response/GetRequestPayViewResponse.java similarity index 77% rename from src/main/java/space/space_spring/dto/pay/GetRequestPayViewResponse.java rename to src/main/java/space/space_spring/dto/pay/response/GetRequestPayViewResponse.java index 0ee5860a..82b83ada 100644 --- a/src/main/java/space/space_spring/dto/pay/GetRequestPayViewResponse.java +++ b/src/main/java/space/space_spring/dto/pay/response/GetRequestPayViewResponse.java @@ -1,7 +1,8 @@ -package space.space_spring.dto.pay; +package space.space_spring.dto.pay.response; import lombok.AllArgsConstructor; import lombok.Getter; +import space.space_spring.dto.pay.dto.PayRequestInfoDto; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/space/space_spring/dto/pay/response/PostPayCompleteResponse.java b/src/main/java/space/space_spring/dto/pay/response/PostPayCompleteResponse.java new file mode 100644 index 00000000..e2399a43 --- /dev/null +++ b/src/main/java/space/space_spring/dto/pay/response/PostPayCompleteResponse.java @@ -0,0 +1,14 @@ +package space.space_spring.dto.pay.response; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class PostPayCompleteResponse { + + private Long payRequestId; + + private boolean isComplete; // 유저가 돈 낸 정산의 완료 여부 + +} diff --git a/src/main/java/space/space_spring/dto/space/GetUserInfoBySpaceResponse.java b/src/main/java/space/space_spring/dto/space/GetUserInfoBySpaceResponse.java deleted file mode 100644 index 4ffbec25..00000000 --- a/src/main/java/space/space_spring/dto/space/GetUserInfoBySpaceResponse.java +++ /dev/null @@ -1,15 +0,0 @@ -package space.space_spring.dto.space; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import space.space_spring.dto.userSpace.UserProfileImgAndNameDto; - -import java.util.ArrayList; -import java.util.List; - -@Getter -@AllArgsConstructor -public class GetUserInfoBySpaceResponse { - - private List userProfileImgAndNameDtoList = new ArrayList<>(); -} diff --git a/src/main/java/space/space_spring/dto/space/PostSpaceCreateResponse.java b/src/main/java/space/space_spring/dto/space/PostSpaceCreateResponse.java deleted file mode 100644 index bc0c2031..00000000 --- a/src/main/java/space/space_spring/dto/space/PostSpaceCreateResponse.java +++ /dev/null @@ -1,12 +0,0 @@ -package space.space_spring.dto.space; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -@Getter -@AllArgsConstructor -public class PostSpaceCreateResponse { - - private Long spaceId; - private String spaceImgUrl; // 사진 url이 잘 생성됐는지 확인하는 용도 -} diff --git a/src/main/java/space/space_spring/dto/space/PostSpaceCreateRequest.java b/src/main/java/space/space_spring/dto/space/request/PostSpaceCreateRequest.java similarity index 77% rename from src/main/java/space/space_spring/dto/space/PostSpaceCreateRequest.java rename to src/main/java/space/space_spring/dto/space/request/PostSpaceCreateRequest.java index f92e5774..42d7964b 100644 --- a/src/main/java/space/space_spring/dto/space/PostSpaceCreateRequest.java +++ b/src/main/java/space/space_spring/dto/space/request/PostSpaceCreateRequest.java @@ -1,12 +1,12 @@ -package space.space_spring.dto.space; +package space.space_spring.dto.space.request; +import jakarta.annotation.Nullable; import jakarta.validation.constraints.NotBlank; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import org.hibernate.validator.constraints.Length; import org.springframework.web.multipart.MultipartFile; -import space.space_spring.validator.ValidFile; @Getter @Setter @@ -17,6 +17,6 @@ public class PostSpaceCreateRequest { @NotBlank(message = "스페이스 이름은 공백일 수 없습니다.") private String spaceName; - @ValidFile(message = "스페이스 프로필 이미지는 공백일 수 없습니다.") + @Nullable private MultipartFile spaceProfileImg; // 스페이스 프로필 이미지 (썸네일) } diff --git a/src/main/java/space/space_spring/dto/space/response/GetUserInfoBySpaceResponse.java b/src/main/java/space/space_spring/dto/space/response/GetUserInfoBySpaceResponse.java new file mode 100644 index 00000000..726d158e --- /dev/null +++ b/src/main/java/space/space_spring/dto/space/response/GetUserInfoBySpaceResponse.java @@ -0,0 +1,15 @@ +package space.space_spring.dto.space.response; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import space.space_spring.dto.userSpace.UserInfoInSpace; + +import java.util.ArrayList; +import java.util.List; + +@Getter +@AllArgsConstructor +public class GetUserInfoBySpaceResponse { + + private List userInfoInSpaceList = new ArrayList<>(); +} diff --git a/src/main/java/space/space_spring/dto/user/PostUserLoginResponse.java b/src/main/java/space/space_spring/dto/user/PostUserLoginResponse.java deleted file mode 100644 index 29b631c5..00000000 --- a/src/main/java/space/space_spring/dto/user/PostUserLoginResponse.java +++ /dev/null @@ -1,11 +0,0 @@ -package space.space_spring.dto.user; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -@Getter -@AllArgsConstructor -public class PostUserLoginResponse { - - private String successMsg; -} diff --git a/src/main/java/space/space_spring/dto/user/PostUserSignupResponse.java b/src/main/java/space/space_spring/dto/user/PostUserSignupResponse.java deleted file mode 100644 index 6d34b743..00000000 --- a/src/main/java/space/space_spring/dto/user/PostUserSignupResponse.java +++ /dev/null @@ -1,11 +0,0 @@ -package space.space_spring.dto.user; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -@Getter -@AllArgsConstructor -public class PostUserSignupResponse { - - private Long userId; -} diff --git a/src/main/java/space/space_spring/dto/user/dto/SpaceChoiceInfo.java b/src/main/java/space/space_spring/dto/user/dto/SpaceChoiceInfo.java new file mode 100644 index 00000000..c62eb499 --- /dev/null +++ b/src/main/java/space/space_spring/dto/user/dto/SpaceChoiceInfo.java @@ -0,0 +1,15 @@ +package space.space_spring.dto.user.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class SpaceChoiceInfo { + + private Long spaceId; + + private String spaceName; + + private String profileImgUrl; +} \ No newline at end of file diff --git a/src/main/java/space/space_spring/dto/user/SpaceChoiceViewDto.java b/src/main/java/space/space_spring/dto/user/dto/SpaceChoiceViewDto.java similarity index 59% rename from src/main/java/space/space_spring/dto/user/SpaceChoiceViewDto.java rename to src/main/java/space/space_spring/dto/user/dto/SpaceChoiceViewDto.java index 381db4da..64f58dbe 100644 --- a/src/main/java/space/space_spring/dto/user/SpaceChoiceViewDto.java +++ b/src/main/java/space/space_spring/dto/user/dto/SpaceChoiceViewDto.java @@ -1,15 +1,16 @@ -package space.space_spring.dto.user; +package space.space_spring.dto.user.dto; import lombok.AllArgsConstructor; import lombok.Getter; import java.util.List; -import java.util.Map; @Getter @AllArgsConstructor public class SpaceChoiceViewDto { - private List> spaceNameAndProfileImgList; + private List spaceChoiceInfoList; + private Long lastUserSpaceId; + } diff --git a/src/main/java/space/space_spring/dto/user/PostUserLoginRequest.java b/src/main/java/space/space_spring/dto/user/request/PostUserLoginRequest.java similarity index 72% rename from src/main/java/space/space_spring/dto/user/PostUserLoginRequest.java rename to src/main/java/space/space_spring/dto/user/request/PostUserLoginRequest.java index 69f8768f..763beb83 100644 --- a/src/main/java/space/space_spring/dto/user/PostUserLoginRequest.java +++ b/src/main/java/space/space_spring/dto/user/request/PostUserLoginRequest.java @@ -1,4 +1,4 @@ -package space.space_spring.dto.user; +package space.space_spring.dto.user.request; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.Pattern; @@ -11,7 +11,8 @@ @NoArgsConstructor public class PostUserLoginRequest { - @Pattern(regexp = "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,6}$", message = "이메일 형식에 맞지 않습니다.") // 이메일 정규표현식 확인 필요함 + // '@', '.' 이 있어야 함 + @Pattern(regexp = "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}$", message = "이메일 형식에 맞지 않습니다.") @NotBlank private String email; diff --git a/src/main/java/space/space_spring/dto/user/PostUserSignupRequest.java b/src/main/java/space/space_spring/dto/user/request/PostUserSignupRequest.java similarity index 79% rename from src/main/java/space/space_spring/dto/user/PostUserSignupRequest.java rename to src/main/java/space/space_spring/dto/user/request/PostUserSignupRequest.java index c483849d..982a5ce1 100644 --- a/src/main/java/space/space_spring/dto/user/PostUserSignupRequest.java +++ b/src/main/java/space/space_spring/dto/user/request/PostUserSignupRequest.java @@ -1,4 +1,4 @@ -package space.space_spring.dto.user; +package space.space_spring.dto.user.request; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.Pattern; @@ -14,7 +14,8 @@ @AllArgsConstructor public class PostUserSignupRequest { - @Pattern(regexp = "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,6}$", message = "이메일 형식에 맞지 않습니다.") // 이메일 정규표현식 확인 필요함 + // '@', '.' 이 있어야 함 + @Pattern(regexp = "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}$", message = "이메일 형식에 맞지 않습니다.") @NotBlank private String email; diff --git a/src/main/java/space/space_spring/dto/user/GetSpaceInfoForUserResponse.java b/src/main/java/space/space_spring/dto/user/response/GetSpaceInfoForUserResponse.java similarity index 59% rename from src/main/java/space/space_spring/dto/user/GetSpaceInfoForUserResponse.java rename to src/main/java/space/space_spring/dto/user/response/GetSpaceInfoForUserResponse.java index 053b77e0..86f73c48 100644 --- a/src/main/java/space/space_spring/dto/user/GetSpaceInfoForUserResponse.java +++ b/src/main/java/space/space_spring/dto/user/response/GetSpaceInfoForUserResponse.java @@ -1,11 +1,10 @@ -package space.space_spring.dto.user; +package space.space_spring.dto.user.response; import lombok.AllArgsConstructor; import lombok.Getter; -import lombok.Setter; +import space.space_spring.dto.user.dto.SpaceChoiceInfo; import java.util.List; -import java.util.Map; @Getter @AllArgsConstructor @@ -15,6 +14,6 @@ public class GetSpaceInfoForUserResponse { private Long lastUserSpaceId; - private List> spaceInfoList; + private List spaceInfoList; } \ No newline at end of file diff --git a/src/main/java/space/space_spring/dto/userSpace/UserProfileImgAndNameDto.java b/src/main/java/space/space_spring/dto/userSpace/UserInfoInSpace.java similarity index 53% rename from src/main/java/space/space_spring/dto/userSpace/UserProfileImgAndNameDto.java rename to src/main/java/space/space_spring/dto/userSpace/UserInfoInSpace.java index ab17cd9b..865007d2 100644 --- a/src/main/java/space/space_spring/dto/userSpace/UserProfileImgAndNameDto.java +++ b/src/main/java/space/space_spring/dto/userSpace/UserInfoInSpace.java @@ -5,9 +5,13 @@ @Getter @AllArgsConstructor -public class UserProfileImgAndNameDto { +public class UserInfoInSpace { - private String profileImgUrl; + private Long userId; private String userName; + + private String profileImgUrl; + + private String userAuth; // 해당 스페이스에서의 유저 권한 (manager vs normal) } diff --git a/src/main/java/space/space_spring/entity/PayRequest.java b/src/main/java/space/space_spring/entity/PayRequest.java index 2b0030c6..d921b7df 100644 --- a/src/main/java/space/space_spring/entity/PayRequest.java +++ b/src/main/java/space/space_spring/entity/PayRequest.java @@ -41,4 +41,8 @@ public void savePayRequest(User payCreateUser, Space space, int totalAmount, Str this.bankAccountNum = bankAccountNum; this.isComplete = isComplete; } + + public void changeCompleteStatus(boolean isComplete) { + this.isComplete = isComplete; + } } diff --git a/src/main/java/space/space_spring/entity/PayRequestTarget.java b/src/main/java/space/space_spring/entity/PayRequestTarget.java index e2c8d8e1..c2495833 100644 --- a/src/main/java/space/space_spring/entity/PayRequestTarget.java +++ b/src/main/java/space/space_spring/entity/PayRequestTarget.java @@ -31,4 +31,8 @@ public void savePayRequestTarget(PayRequest payRequest, Long targetUserId, int r this.requestAmount = requestAmount; this.isComplete = isComplete; } + + public void changeCompleteStatus(boolean isComplete) { + this.isComplete = isComplete; + } } diff --git a/src/main/java/space/space_spring/exception/MultipartFileException.java b/src/main/java/space/space_spring/exception/MultipartFileException.java new file mode 100644 index 00000000..3292f14a --- /dev/null +++ b/src/main/java/space/space_spring/exception/MultipartFileException.java @@ -0,0 +1,20 @@ +package space.space_spring.exception; + +import lombok.Getter; +import space.space_spring.response.status.ResponseStatus; + +@Getter +public class MultipartFileException extends RuntimeException { + + private final ResponseStatus exceptionStatus; + + public MultipartFileException(ResponseStatus exceptionStatus) { + super(exceptionStatus.getMessage()); + this.exceptionStatus = exceptionStatus; + } + + public MultipartFileException(ResponseStatus exceptionStatus, String message) { + super(message); + this.exceptionStatus = exceptionStatus; + } +} diff --git a/src/main/java/space/space_spring/response/status/BaseExceptionResponseStatus.java b/src/main/java/space/space_spring/response/status/BaseExceptionResponseStatus.java index 0e2e52d3..3999db2c 100644 --- a/src/main/java/space/space_spring/response/status/BaseExceptionResponseStatus.java +++ b/src/main/java/space/space_spring/response/status/BaseExceptionResponseStatus.java @@ -76,8 +76,12 @@ public enum BaseExceptionResponseStatus implements ResponseStatus { /** * 8000: Chat 오류 */ - INVALID_CHATROOM_CREATE(8000, HttpStatus.BAD_REQUEST.value(), "채팅방 생성 요청에서 잘못된 값이 존재합니다."); + INVALID_CHATROOM_CREATE(8000, HttpStatus.BAD_REQUEST.value(), "채팅방 생성 요청에서 잘못된 값이 존재합니다."), + /** + * 9000 : MultipartFile 오류 + */ + IS_NOT_IMAGE_FILE(9000, HttpStatus.BAD_REQUEST.value(), "지원되는 이미지 파일의 형식이 아닙니다."); private final int code; private final int status; diff --git a/src/main/java/space/space_spring/service/PayService.java b/src/main/java/space/space_spring/service/PayService.java index 6bade187..35e80e8b 100644 --- a/src/main/java/space/space_spring/service/PayService.java +++ b/src/main/java/space/space_spring/service/PayService.java @@ -4,17 +4,22 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import space.space_spring.dao.PayDao; -import space.space_spring.dto.pay.*; -import space.space_spring.entity.PayRequest; -import space.space_spring.entity.PayRequestTarget; -import space.space_spring.entity.Space; -import space.space_spring.entity.User; +import space.space_spring.dao.UserDao; +import space.space_spring.dao.UserSpaceDao; +import space.space_spring.dto.pay.dto.*; +import space.space_spring.dto.pay.request.PostPayCreateRequest; +import space.space_spring.dto.pay.response.GetRecentPayRequestBankInfoResponse; +import space.space_spring.dto.pay.response.PostPayCompleteResponse; +import space.space_spring.entity.*; +import space.space_spring.exception.UserSpaceException; import space.space_spring.util.space.SpaceUtils; import space.space_spring.util.user.UserUtils; import java.util.ArrayList; import java.util.List; -import java.util.Map; +import java.util.Optional; + +import static space.space_spring.response.status.BaseExceptionResponseStatus.USER_IS_NOT_IN_SPACE; @Service @RequiredArgsConstructor @@ -23,6 +28,8 @@ public class PayService { private final PayDao payDao; private final UserUtils userUtils; private final SpaceUtils spaceUtils; + private final UserDao userDao; + private final UserSpaceDao userSpaceDao; @Transactional public List getPayRequestInfoForUser(Long userId, Long spaceId, boolean isComplete) { @@ -36,34 +43,43 @@ public List getPayRequestInfoForUser(Long userId, Long spaceI List payRequestListByUser = payDao.findPayRequestListByUser(userByUserId, spaceBySpaceId, isComplete); // TODO 4. return 타입 구성 + // + // 3-1. 각 payRequest 에 해당하는 모든 payRequestTarget 을 loop로 돌면서 데이터 수집 List payRequestInfoDtoList = new ArrayList<>(); for (PayRequest payRequest : payRequestListByUser) { - // 하나의 정산 요청에 대하여 ,,, - int totalAmount = payRequest.getTotalAmount(); - int receiveAmount = 0; - int totalTargetNum = 0; - int receiveTargetNum = 0; - - List payRequestTargetList = payDao.findPayRequestTargetListByPayRequest(payRequest); - for (PayRequestTarget payRequestTarget : payRequestTargetList) { - if (payRequestTarget.isComplete()) { - // 해당 타겟이 돈을 낸 경우 - receiveAmount += payRequestTarget.getRequestAmount(); - receiveTargetNum++; - } - - totalTargetNum++; - } - - PayRequestInfoDto payRequestInfoDto = new PayRequestInfoDto(totalAmount, receiveAmount, totalTargetNum, receiveTargetNum); + PayRequestInfoDto payRequestInfoDto = createPayRequestInfoDto(payRequest); payRequestInfoDtoList.add(payRequestInfoDto); } return payRequestInfoDtoList; } + private PayRequestInfoDto createPayRequestInfoDto(PayRequest payRequest) { + Long payRequestId = payRequest.getPayRequestId(); + int totalAmount = payRequest.getTotalAmount(); + int receiveAmount = 0; + int totalTargetNum = 0; + int receiveTargetNum = 0; + + List payRequestTargetList = payDao.findPayRequestTargetListByPayRequest(payRequest); + + for (PayRequestTarget payRequestTarget : payRequestTargetList) { + if (payRequestTarget.isComplete()) { + // 해당 타겟이 돈을 낸 경우 + receiveAmount += payRequestTarget.getRequestAmount(); + receiveTargetNum++; + } + + totalTargetNum++; + } + + return new PayRequestInfoDto( + payRequestId, totalAmount, receiveAmount, totalTargetNum, receiveTargetNum + ); + } + @Transactional public List getPayReceiveInfoForUser(Long userId, Long spaceId, boolean isComplete) { // TODO 1. userId에 해당하는 유저 find @@ -80,17 +96,20 @@ public List getPayReceiveInfoForUser(Long userId, Long spaceI List payReceiveInfoDtoList = new ArrayList<>(); for (PayRequestTarget payRequestTarget : payRequestTargetListByUser) { - String payCreatorName = payRequestTarget.getPayRequest().getPayCreateUser().getUserName(); // 리펙토링 필요 - int requestAmount = payRequestTarget.getRequestAmount(); - - PayReceiveInfoDto payReceiveInfoDto = new PayReceiveInfoDto(payCreatorName, requestAmount); - + PayReceiveInfoDto payReceiveInfoDto = createPayReceiveInfoDto(payRequestTarget); payReceiveInfoDtoList.add(payReceiveInfoDto); } return payReceiveInfoDtoList; } + private PayReceiveInfoDto createPayReceiveInfoDto(PayRequestTarget payRequestTarget) { + String payCreatorName = payRequestTarget.getPayRequest().getPayCreateUser().getUserName(); // 리펙토링 필요 + int requestAmount = payRequestTarget.getRequestAmount(); + + return new PayReceiveInfoDto(payRequestTarget.getPayRequestTargetId(), payCreatorName, requestAmount); + } + @Transactional public GetRecentPayRequestBankInfoResponse getRecentPayRequestBankInfoForUser(Long userId) { // TODO 1. userId에 해당하는 유저 find @@ -124,5 +143,97 @@ public List createPay(Long userId, Long spaceId, PostPayCreate return resultList; } + /** + * 하나의 정산에 대한 상세정보 조회 + */ + @Transactional + public TotalPayInfoDto getTotalPayInfo(Long spaceId, Long payRequestId) { + // TODO 1. spaceId로 Space 엔티티 find + Space spaceBySpaceId = spaceUtils.findSpaceBySpaceId(spaceId); + + // TODO 2. payRequestId 로 PayRequest 엔티티 find + PayRequest payRequestById = payDao.findPayRequestById(payRequestId); + + // TODO 3. PayRequest로 해당 정산의 정보 get + PayRequestInfoDto payRequestInfoDto = createPayRequestInfoDto(payRequestById); + + // TODO 4. PayRequest의 PayRequestTarget find + List payRequestTargetListByPayRequest = payDao.findPayRequestTargetListByPayRequest(payRequestById); + + // TODO 5. 정산 타겟 유저 정보 get + List payTargetInfoDtoList = new ArrayList<>(); + for (PayRequestTarget payRequestTarget : payRequestTargetListByPayRequest) { + PayTargetInfoDto payTargetInfoDto = createPayTargetInfoDto(payRequestTarget, spaceBySpaceId); + payTargetInfoDtoList.add(payTargetInfoDto); + } + + // TODO 6. return 타입 구성 + return new TotalPayInfoDto( + payRequestId, + payRequestById.getBankName(), + payRequestById.getBankAccountNum(), + payRequestById.getTotalAmount(), + payRequestInfoDto.getReceiveAmount(), + payRequestInfoDto.getTotalTargetNum(), + payRequestInfoDto.getReceiveTargetNum(), + payTargetInfoDtoList, + payRequestById.isComplete() + ); + } + + private PayTargetInfoDto createPayTargetInfoDto(PayRequestTarget payRequestTarget, Space space) { + Long targetUserId = payRequestTarget.getTargetUserId(); + User userByUserId = userDao.findUserByUserId(targetUserId); + + UserSpace userSpace = userSpaceDao.findUserSpaceByUserAndSpace(userByUserId, space) + .orElseThrow(() -> new UserSpaceException(USER_IS_NOT_IN_SPACE)); + + String userName = userSpace.getUserName(); + String userProfileImg = userSpace.getUserProfileImg(); + + return new PayTargetInfoDto( + payRequestTarget.getTargetUserId(), + userName, + userProfileImg, + payRequestTarget.getRequestAmount(), + payRequestTarget.isComplete() + ); + } + + /** + * 정산 타겟 유저의 정산 완료 처리 + */ + @Transactional + public PostPayCompleteResponse setPayRequestTargetToComplete(Long payRequestTargetId) { + + // TODO 1. payRequestTargetId로 PayRequestTarget find + PayRequestTarget payRequestTargetById = payDao.findPayRequestTargetById(payRequestTargetId); + + // TODO 2. 해당 PayRequestTarget 정산 완료 처리 + payRequestTargetById.changeCompleteStatus(true); + + // TODO 3. PayRequest의 완료 여부 파악 + PayRequest payRequest = payRequestTargetById.getPayRequest(); + boolean payRequestCompleteStatus = isPayRequestComplete(payRequest); + if (payRequestCompleteStatus) { + payRequest.changeCompleteStatus(true); + } + + // TODO 4. return 타입 구성 + return new PostPayCompleteResponse( + payRequest.getPayRequestId(), + payRequestCompleteStatus + ); + } + + private boolean isPayRequestComplete(PayRequest payRequest) { + List payRequestTargetListByPayRequest = payDao.findPayRequestTargetListByPayRequest(payRequest); + for (PayRequestTarget payRequestTarget : payRequestTargetListByPayRequest) { + if (!payRequestTarget.isComplete()) { + return false; + } + } + return true; + } } diff --git a/src/main/java/space/space_spring/service/S3Uploader.java b/src/main/java/space/space_spring/service/S3Uploader.java index 3fa8e348..1eb4eb17 100644 --- a/src/main/java/space/space_spring/service/S3Uploader.java +++ b/src/main/java/space/space_spring/service/S3Uploader.java @@ -9,6 +9,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; +import space.space_spring.validator.AllowedImageFileExtensions; import java.io.File; import java.io.FileOutputStream; @@ -26,7 +27,7 @@ public class S3Uploader { private String bucket; //MultipartFile을 전달 받아 File로 전환 후 S3 업로드 - public String upload(MultipartFile multipartFile, String dirName) throws IOException{// dirName의 디렉토리가 S3 Bucket 내부에 생성됨 + public String upload(MultipartFile multipartFile, String dirName) throws IOException{// dirName의 디렉토리가 S3 Bucket 내부에 생성됨 File uploadFile = convert(multipartFile).orElseThrow(()-> new IllegalArgumentException("MultipartFile -> File 전환 실패")); //System.out.p @@ -64,4 +65,14 @@ private Optional convert(MultipartFile file) throws IOException { } return Optional.empty(); } + + // MultipartFile이 지원하는 이미지 파일 형식인지 검증 + public boolean isFileImage(MultipartFile file) { + String fileName = file.getOriginalFilename(); + String extension = fileName.substring(fileName.lastIndexOf(".") + 1); + + log.info("extension : {}", extension); + + return AllowedImageFileExtensions.contains(extension); + } } diff --git a/src/main/java/space/space_spring/service/SpaceService.java b/src/main/java/space/space_spring/service/SpaceService.java index f17c12f8..92972ced 100644 --- a/src/main/java/space/space_spring/service/SpaceService.java +++ b/src/main/java/space/space_spring/service/SpaceService.java @@ -6,15 +6,12 @@ import space.space_spring.dao.SpaceDao; import space.space_spring.dao.UserDao; import space.space_spring.dao.UserSpaceDao; -import space.space_spring.dto.space.GetUserInfoBySpaceResponse; -import space.space_spring.dto.space.PostSpaceCreateResponse; +import space.space_spring.dto.space.response.GetUserInfoBySpaceResponse; import space.space_spring.entity.Space; import space.space_spring.entity.User; -import space.space_spring.dto.space.PostSpaceCreateRequest; import space.space_spring.entity.UserSpace; import space.space_spring.util.space.SpaceUtils; -import java.util.List; @Service @RequiredArgsConstructor @@ -26,7 +23,7 @@ public class SpaceService { private final SpaceUtils spaceUtils; @Transactional - public PostSpaceCreateResponse createSpace(Long userId, String spaceName, String spaceImgUrl) { + public Long createSpace(Long userId, String spaceName, String spaceImgUrl) { // TODO 1. 스페이스 생성 정보 db insert Space saveSpace = spaceDao.saveSpace(spaceName, spaceImgUrl); @@ -35,7 +32,7 @@ public PostSpaceCreateResponse createSpace(Long userId, String spaceName, String User manager = userDao.findUserByUserId(userId); UserSpace userSpace = userSpaceDao.createUserSpace(manager, saveSpace); - return new PostSpaceCreateResponse(saveSpace.getSpaceId(), spaceImgUrl); + return saveSpace.getSpaceId(); } @Transactional @@ -44,6 +41,6 @@ public GetUserInfoBySpaceResponse findUserInfoBySpace(Long spaceId) { Space spaceBySpaceId = spaceUtils.findSpaceBySpaceId(spaceId); // TODO 2. 스페이스의 모든 유저 정보 return - return new GetUserInfoBySpaceResponse(userSpaceDao.findUserProfileImgAndName(spaceBySpaceId)); + return new GetUserInfoBySpaceResponse(userSpaceDao.findUserInfoInSpace(spaceBySpaceId)); } } diff --git a/src/main/java/space/space_spring/service/UserService.java b/src/main/java/space/space_spring/service/UserService.java index 551e5720..1b712feb 100644 --- a/src/main/java/space/space_spring/service/UserService.java +++ b/src/main/java/space/space_spring/service/UserService.java @@ -5,7 +5,10 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import space.space_spring.dao.UserSpaceDao; -import space.space_spring.dto.user.*; +import space.space_spring.dto.user.dto.SpaceChoiceViewDto; +import space.space_spring.dto.user.request.PostUserLoginRequest; +import space.space_spring.dto.user.request.PostUserSignupRequest; +import space.space_spring.dto.user.response.GetSpaceInfoForUserResponse; import space.space_spring.entity.enumStatus.UserSignupType; import space.space_spring.jwt.JwtLoginProvider; import space.space_spring.dao.UserDao; @@ -27,7 +30,7 @@ public class UserService { private final UserUtils userUtils; @Transactional - public PostUserSignupResponse signup(PostUserSignupRequest postUserSignupRequest) { + public Long signup(PostUserSignupRequest postUserSignupRequest) { // TODO 1. 이메일 중복 검사(아이디 중복 검사) validateEmailForLocalSignup(postUserSignupRequest.getEmail()); @@ -40,7 +43,7 @@ public PostUserSignupResponse signup(PostUserSignupRequest postUserSignupRequest User saveUser = userDao.saveUser(email, password, userName, LOCAL); - return new PostUserSignupResponse(saveUser.getUserId()); + return saveUser.getUserId(); } private void validateEmailForLocalSignup(String email) { @@ -76,23 +79,14 @@ public GetSpaceInfoForUserResponse getSpaceListForUser(Long userId, int size, Lo // TODO 1. userId로 User find User userByUserId = userUtils.findUserByUserId(userId); - // TODO 2. user가 속한 스페이스가 없는 경우 -> 예외처리 ?? - // (현재 lastUserSpaceId가 -1 & 스페이스 info list는 빈 껍데기로 response가 전달됨) - validateSpaceListForUser(userByUserId); - - // TODO 3. 특정 유저가 속해있는 스페이스 정보들을 get -> 무한 스크롤 구현 + // TODO 2. 특정 유저가 속해있는 스페이스 정보들을 get -> 무한 스크롤 구현 SpaceChoiceViewDto spaceChoiceViewDto = userSpaceDao.getSpaceChoiceView(userByUserId, size, lastUserSpaceId); - // TODO 4. find userName + // TODO 3. find userName String userName = userByUserId.getUserName(); - // TODO 5. return - return new GetSpaceInfoForUserResponse(userName, spaceChoiceViewDto.getLastUserSpaceId(), spaceChoiceViewDto.getSpaceNameAndProfileImgList()); - } - - private void validateSpaceListForUser(User userByUserId) { - // 프론트 개발자 분들과 상의해서 결정해야할 거 같음 - + // TODO 4. return + return new GetSpaceInfoForUserResponse(userName, spaceChoiceViewDto.getLastUserSpaceId(), spaceChoiceViewDto.getSpaceChoiceInfoList()); } } diff --git a/src/main/java/space/space_spring/validator/AllowedImageFileExtensions.java b/src/main/java/space/space_spring/validator/AllowedImageFileExtensions.java new file mode 100644 index 00000000..b863798d --- /dev/null +++ b/src/main/java/space/space_spring/validator/AllowedImageFileExtensions.java @@ -0,0 +1,35 @@ +package space.space_spring.validator; + +import lombok.Getter; + +@Getter +public enum AllowedImageFileExtensions { + /** + * 허용가능한 이미지 파일 확장자 list + */ + JPEG("jpeg"), + JPG("jpg"), + PNG("png"), + GIF("gif"), + WebP("webp"), + SVG("svg"), + BMP("bmp"), + TIF("tif"), + TIFF("tiff"), + HEIC("heic"); + + private String extension; + + AllowedImageFileExtensions(String extension) { + this.extension = extension; + } + + public static boolean contains(String extension) { + for (AllowedImageFileExtensions allowedImageFileExtensions : AllowedImageFileExtensions.values()) { + if (allowedImageFileExtensions.getExtension().equals(extension)) { + return true; + } + } + return false; + } +} diff --git a/src/main/java/space/space_spring/validator/ValidFile.java b/src/main/java/space/space_spring/validator/ValidFile.java deleted file mode 100644 index 6981573c..00000000 --- a/src/main/java/space/space_spring/validator/ValidFile.java +++ /dev/null @@ -1,18 +0,0 @@ -package space.space_spring.validator; - -import jakarta.validation.Constraint; -import jakarta.validation.Payload; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Target(ElementType.FIELD) -@Retention(RetentionPolicy.RUNTIME) -@Constraint(validatedBy = ValidFileValidator.class) -public @interface ValidFile { - String message() default "유효하지 않은 파일입니다."; - Class[] groups() default {}; - Class[] payload() default {}; -} diff --git a/src/main/java/space/space_spring/validator/ValidFileValidator.java b/src/main/java/space/space_spring/validator/ValidFileValidator.java deleted file mode 100644 index 73f814b9..00000000 --- a/src/main/java/space/space_spring/validator/ValidFileValidator.java +++ /dev/null @@ -1,14 +0,0 @@ -package space.space_spring.validator; - -import jakarta.validation.ConstraintValidator; -import jakarta.validation.ConstraintValidatorContext; -import org.springframework.web.multipart.MultipartFile; - -public class ValidFileValidator implements ConstraintValidator { - - // multipartFile이 null 이 아니거나 비어있지 않으면 검증로직 통과 - @Override - public boolean isValid(MultipartFile multipartFile, ConstraintValidatorContext constraintValidatorContext) { - return multipartFile != null && !multipartFile.isEmpty(); - } -} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index fbe4dd4f..fb5e0036 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -107,4 +107,10 @@ spring: messages: basename: errors +--- +spring: + servlet: + multipart: + max-file-size: 5MB + max-request-size: 5MB \ No newline at end of file diff --git a/src/test/java/space/space_spring/service/PayServiceTest.java b/src/test/java/space/space_spring/service/PayServiceTest.java index 9dcddfdd..777228eb 100644 --- a/src/test/java/space/space_spring/service/PayServiceTest.java +++ b/src/test/java/space/space_spring/service/PayServiceTest.java @@ -8,9 +8,9 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import space.space_spring.dao.PayDao; -import space.space_spring.dto.pay.PayReceiveInfoDto; -import space.space_spring.dto.pay.PayRequestInfoDto; -import space.space_spring.dto.pay.PostPayCreateRequest; +import space.space_spring.dto.pay.dto.PayReceiveInfoDto; +import space.space_spring.dto.pay.dto.PayRequestInfoDto; +import space.space_spring.dto.pay.request.PostPayCreateRequest; import space.space_spring.entity.PayRequest; import space.space_spring.entity.PayRequestTarget; import space.space_spring.entity.Space; @@ -20,13 +20,10 @@ import space.space_spring.util.user.UserUtils; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.when; -import static org.junit.jupiter.api.Assertions.*; @ExtendWith(MockitoExtension.class) class PayServiceTest {