diff --git a/core/src/main/java/com/pocket/core/exception/album/AlbumCustomException.java b/core/src/main/java/com/pocket/core/exception/album/AlbumCustomException.java new file mode 100644 index 0000000..91d79a6 --- /dev/null +++ b/core/src/main/java/com/pocket/core/exception/album/AlbumCustomException.java @@ -0,0 +1,18 @@ +package com.pocket.core.exception.album; + +import com.pocket.core.exception.common.BaseErrorCode; +import lombok.Getter; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@Getter +@ResponseStatus(HttpStatus.BAD_REQUEST) +public class AlbumCustomException extends RuntimeException { + + private final BaseErrorCode errorCode; + + public AlbumCustomException(BaseErrorCode errorCode) { + this.errorCode = errorCode; + } + +} diff --git a/core/src/main/java/com/pocket/core/exception/album/AlbumErrorCode.java b/core/src/main/java/com/pocket/core/exception/album/AlbumErrorCode.java new file mode 100644 index 0000000..bcd0cd6 --- /dev/null +++ b/core/src/main/java/com/pocket/core/exception/album/AlbumErrorCode.java @@ -0,0 +1,24 @@ +package com.pocket.core.exception.album; + +import com.pocket.core.exception.common.ApiResponse; +import com.pocket.core.exception.common.BaseErrorCode; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.http.HttpStatus; + +@Getter +@AllArgsConstructor +public enum AlbumErrorCode implements BaseErrorCode { + ALBUM_NOT_FOUND(HttpStatus.BAD_REQUEST, "400", "해당 앨범이 존재하지 않습니다."); + + private final HttpStatus httpStatus; + private final String code; + private final String message; + + @Override + public ApiResponse getErrorResponse() { + return ApiResponse.onFailure(code, message); + } + + +} diff --git a/core/src/main/java/com/pocket/core/exception/common/GlobalExceptionHandler.java b/core/src/main/java/com/pocket/core/exception/common/GlobalExceptionHandler.java index 319ef9f..982ac34 100644 --- a/core/src/main/java/com/pocket/core/exception/common/GlobalExceptionHandler.java +++ b/core/src/main/java/com/pocket/core/exception/common/GlobalExceptionHandler.java @@ -1,6 +1,8 @@ package com.pocket.core.exception.common; + +import com.pocket.core.exception.jwt.SecurityCustomException; +import com.pocket.core.exception.jwt.SecurityErrorCode; import com.pocket.core.exception.photobooth.PhotoBoothCustomException; -import com.pocket.core.exception.photobooth.PhotoBoothErrorCode; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ExceptionHandler; @@ -18,4 +20,13 @@ public ResponseEntity> handlePhotoBoothNotFound(Phot return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST); } + @ExceptionHandler(SecurityCustomException.class) + public ResponseEntity> handleSecurityException(SecurityCustomException ex) { + ApplicationResponse response = new ApplicationResponse<>( + new ApplicationResult(Integer.parseInt(ex.getErrorCode().getCode()), ex.getErrorCode().getMessage()), + null + ); + return new ResponseEntity<>(response, ex.getErrorCode().getHttpStatus()); + } + } diff --git a/core/src/main/java/com/pocket/core/exception/photobooth/PhotoBoothErrorCode.java b/core/src/main/java/com/pocket/core/exception/photobooth/PhotoBoothErrorCode.java index b4c5ea5..af51bfe 100644 --- a/core/src/main/java/com/pocket/core/exception/photobooth/PhotoBoothErrorCode.java +++ b/core/src/main/java/com/pocket/core/exception/photobooth/PhotoBoothErrorCode.java @@ -9,7 +9,8 @@ @Getter @AllArgsConstructor public enum PhotoBoothErrorCode implements BaseErrorCode { - PHOTOBOOTH_NOT_FOUND(HttpStatus.BAD_REQUEST, "400", "해당 포토부스가 존재하지 않습니다."); + PHOTOBOOTH_NOT_FOUND(HttpStatus.BAD_REQUEST, "400", "해당 포토부스가 존재하지 않습니다."), + PHOTOBOOTHBRAND_NOT_FOUND(HttpStatus.BAD_REQUEST, "400", "해당 포토부스 브랜드가 존재하지 않습니다."); private final HttpStatus httpStatus; private final String code; diff --git a/domain/src/main/java/com/pocket/domain/dto/album/AlbumHashtagResponseDto.java b/domain/src/main/java/com/pocket/domain/dto/album/AlbumHashtagResponseDto.java new file mode 100644 index 0000000..a6ccd6c --- /dev/null +++ b/domain/src/main/java/com/pocket/domain/dto/album/AlbumHashtagResponseDto.java @@ -0,0 +1,14 @@ +package com.pocket.domain.dto.album; + +import java.util.List; + +public record AlbumHashtagResponseDto( + String photoUrl, + List hashtags, + Integer year, + Integer month, + Integer date, + String memo, + boolean isLiked +) { +} diff --git a/domain/src/main/java/com/pocket/domain/dto/album/AlbumResponseDto.java b/domain/src/main/java/com/pocket/domain/dto/album/AlbumResponseDto.java new file mode 100644 index 0000000..a89c6f8 --- /dev/null +++ b/domain/src/main/java/com/pocket/domain/dto/album/AlbumResponseDto.java @@ -0,0 +1,9 @@ +package com.pocket.domain.dto.album; + +public record AlbumResponseDto( + Long albumId, + String photoUrl, + boolean like +) { + +} diff --git a/domain/src/main/java/com/pocket/domain/dto/album/NearAlbumInfo.java b/domain/src/main/java/com/pocket/domain/dto/album/NearAlbumInfo.java new file mode 100644 index 0000000..f9ca737 --- /dev/null +++ b/domain/src/main/java/com/pocket/domain/dto/album/NearAlbumInfo.java @@ -0,0 +1,10 @@ +package com.pocket.domain.dto.album; + +import com.pocket.domain.entity.photobooth.PhotoBoothBrand; + +public record NearAlbumInfo( + String photoUrl, + double x, + double y +) { +} diff --git a/domain/src/main/java/com/pocket/domain/entity/image/Image.java b/domain/src/main/java/com/pocket/domain/entity/image/Image.java index 8c6b94b..9471ec7 100644 --- a/domain/src/main/java/com/pocket/domain/entity/image/Image.java +++ b/domain/src/main/java/com/pocket/domain/entity/image/Image.java @@ -23,9 +23,9 @@ public class Image extends BaseEntity { @Column(name = "image_url") private String imageUrl; - private String year; - private String month; - private String date; + private Integer year; + private Integer month; + private Integer date; public Image(ImageType type) { this.type = type; @@ -34,9 +34,9 @@ public Image(ImageType type) { public void makeAlbumImage(AlbumRegisterRequestDto dto, String filePath) { this.type = ImageType.PHOTO; this.imageUrl = filePath; - this.year = dto.year(); - this.month = dto.month(); - this.date = dto.date(); + this.year = Integer.parseInt(dto.year()); + this.month = Integer.parseInt(dto.month()); + this.date = Integer.parseInt(dto.date()); } public void makeReviewImage(String filePath) { diff --git a/domain/src/main/java/com/pocket/domain/entity/photobooth/PhotoBoothBrand.java b/domain/src/main/java/com/pocket/domain/entity/photobooth/PhotoBoothBrand.java index 6b71623..04b51e9 100644 --- a/domain/src/main/java/com/pocket/domain/entity/photobooth/PhotoBoothBrand.java +++ b/domain/src/main/java/com/pocket/domain/entity/photobooth/PhotoBoothBrand.java @@ -1,7 +1,9 @@ package com.pocket.domain.entity.photobooth; -public enum PhotoBoothBrand { +import com.pocket.core.exception.photobooth.PhotoBoothCustomException; +import com.pocket.core.exception.photobooth.PhotoBoothErrorCode; +public enum PhotoBoothBrand { LIFE4CUT("인생네컷"), PHOTOISM("포토이즘"), PHOTOGRAY("포토그레이"), @@ -14,14 +16,22 @@ public enum PhotoBoothBrand { PHOTOSIGNATURE("포토시그니처"), UNKNOWN("존재하지 않음"); - final private String name; + private final String koreanName; - PhotoBoothBrand(String name) { - this.name = name; + PhotoBoothBrand(String koreanName) { + this.koreanName = koreanName; } - public String getName() { - return this.name; + public String getKoreanName() { + return koreanName; } -} + public static PhotoBoothBrand fromKoreanName(String koreanName) { + for (PhotoBoothBrand brand : PhotoBoothBrand.values()) { + if (brand.getKoreanName().equals(koreanName)) { + return brand; + } + } + throw new PhotoBoothCustomException(PhotoBoothErrorCode.PHOTOBOOTHBRAND_NOT_FOUND); + } +} \ No newline at end of file diff --git a/domain/src/main/java/com/pocket/domain/port/album/AlbumDeletePort.java b/domain/src/main/java/com/pocket/domain/port/album/AlbumDeletePort.java new file mode 100644 index 0000000..924700e --- /dev/null +++ b/domain/src/main/java/com/pocket/domain/port/album/AlbumDeletePort.java @@ -0,0 +1,7 @@ +package com.pocket.domain.port.album; + +public interface AlbumDeletePort { + + void deleteAlbum(Long albumId); + +} diff --git a/domain/src/main/java/com/pocket/domain/port/album/AlbumFavoritePort.java b/domain/src/main/java/com/pocket/domain/port/album/AlbumFavoritePort.java new file mode 100644 index 0000000..c72b5f1 --- /dev/null +++ b/domain/src/main/java/com/pocket/domain/port/album/AlbumFavoritePort.java @@ -0,0 +1,11 @@ +package com.pocket.domain.port.album; + +import com.pocket.domain.dto.album.AlbumResponseDto; + +import java.util.List; + +public interface AlbumFavoritePort { + + List getFavoriteAlbums(String userEmail); + +} diff --git a/domain/src/main/java/com/pocket/domain/port/album/AlbumGetByBrandPort.java b/domain/src/main/java/com/pocket/domain/port/album/AlbumGetByBrandPort.java new file mode 100644 index 0000000..1812d52 --- /dev/null +++ b/domain/src/main/java/com/pocket/domain/port/album/AlbumGetByBrandPort.java @@ -0,0 +1,11 @@ +package com.pocket.domain.port.album; + +import com.pocket.domain.dto.album.AlbumResponseDto; + +import java.util.List; + +public interface AlbumGetByBrandPort { + + List getAlbumByBrand(String brandName, String userEmail); + +} diff --git a/domain/src/main/java/com/pocket/domain/port/album/AlbumGetByDatePort.java b/domain/src/main/java/com/pocket/domain/port/album/AlbumGetByDatePort.java new file mode 100644 index 0000000..41b4a3c --- /dev/null +++ b/domain/src/main/java/com/pocket/domain/port/album/AlbumGetByDatePort.java @@ -0,0 +1,11 @@ +package com.pocket.domain.port.album; + +import com.pocket.domain.dto.album.AlbumResponseDto; + +import java.util.List; + +public interface AlbumGetByDatePort { + + List getAlbumByDate(Integer year, Integer month, String userEmail); + +} diff --git a/domain/src/main/java/com/pocket/domain/port/album/AlbumGetByLocationPort.java b/domain/src/main/java/com/pocket/domain/port/album/AlbumGetByLocationPort.java new file mode 100644 index 0000000..4c13f4f --- /dev/null +++ b/domain/src/main/java/com/pocket/domain/port/album/AlbumGetByLocationPort.java @@ -0,0 +1,11 @@ +package com.pocket.domain.port.album; + +import com.pocket.domain.dto.album.NearAlbumInfo; + +import java.util.List; + +public interface AlbumGetByLocationPort { + + List getAlbumByLocation(double currentLat, double currentLon, String userEmail); + +} diff --git a/domain/src/main/java/com/pocket/domain/port/album/AlbumHashtagPort.java b/domain/src/main/java/com/pocket/domain/port/album/AlbumHashtagPort.java new file mode 100644 index 0000000..f03369d --- /dev/null +++ b/domain/src/main/java/com/pocket/domain/port/album/AlbumHashtagPort.java @@ -0,0 +1,11 @@ +package com.pocket.domain.port.album; + +import com.pocket.domain.dto.album.AlbumHashtagResponseDto; + +import java.util.List; + +public interface AlbumHashtagPort { + + List getAlbumByHashtag(String hashtag, String userEmail); + +} diff --git a/domain/src/main/java/com/pocket/domain/port/album/AlbumLikePort.java b/domain/src/main/java/com/pocket/domain/port/album/AlbumLikePort.java new file mode 100644 index 0000000..f40bc89 --- /dev/null +++ b/domain/src/main/java/com/pocket/domain/port/album/AlbumLikePort.java @@ -0,0 +1,7 @@ +package com.pocket.domain.port.album; + +public interface AlbumLikePort { + + void likeAlbum(Long albumId); + +} diff --git a/domain/src/main/java/com/pocket/domain/service/album/AlbumService.java b/domain/src/main/java/com/pocket/domain/service/album/AlbumService.java index 6e59407..24c128f 100644 --- a/domain/src/main/java/com/pocket/domain/service/album/AlbumService.java +++ b/domain/src/main/java/com/pocket/domain/service/album/AlbumService.java @@ -1,20 +1,101 @@ package com.pocket.domain.service.album; import com.pocket.core.aop.annotation.DomainService; -import com.pocket.domain.dto.album.AlbumRegisterRequestDto; -import com.pocket.domain.dto.album.AlbumRegisterResponseDto; -import com.pocket.domain.port.album.AlbumRegisterPort; -import com.pocket.domain.usecase.album.AlbumRegisterUseCase; +import com.pocket.domain.dto.album.*; +import com.pocket.domain.port.album.*; +import com.pocket.domain.port.file.FileDownloadPort; +import com.pocket.domain.usecase.album.*; import lombok.RequiredArgsConstructor; +import java.util.List; +import java.util.stream.Collectors; + @DomainService @RequiredArgsConstructor -public class AlbumService implements AlbumRegisterUseCase { +public class AlbumService implements AlbumRegisterUseCase, AlbumLikeUseCase, AlbumGetByDateUseCase, AlbumGetByBrandUseCase, AlbumGetByLocationUseCase, AlbumDeleteUseCase, AlbumHashtagUseCase, AlbumFavoriteUseCase +{ + private final FileDownloadPort fileDownloadPort; private final AlbumRegisterPort albumRegisterPort; + private final AlbumLikePort albumLikePort; + private final AlbumGetByDatePort albumGetByDatePort; + private final AlbumGetByBrandPort albumGetByBrandPort; + private final AlbumGetByLocationPort albumGetByLocationPort; + private final AlbumDeletePort albumDeletePort; + private final AlbumHashtagPort albumHashtagPort; + private final AlbumFavoritePort albumFavoritePort; public AlbumRegisterResponseDto registerPhotoResponse(AlbumRegisterRequestDto albumRegisterRequestDto, String name) { return albumRegisterPort.registerPhoto(albumRegisterRequestDto, name); } + @Override + public void likeAlbum(Long albumId) { + albumLikePort.likeAlbum(albumId); + } + + @Override + public List getAlbumByDate(Integer year, Integer month, String userEmail) { + List albumResponseDtos = albumGetByDatePort.getAlbumByDate(year, month, userEmail); + + return albumResponseDtos.stream() + .map(dto -> { + String presignedUrl = dto.photoUrl().isEmpty() ? "" : fileDownloadPort.getDownloadPresignedUrl(dto.photoUrl()); + return new AlbumResponseDto(dto.albumId(), presignedUrl, dto.like()); + }) + .collect(Collectors.toList()); + } + + + @Override + public List getAlbumByBrand(String brandName, String userEmail) { + List albumResponseDtos = albumGetByBrandPort.getAlbumByBrand(brandName, userEmail); + + return albumResponseDtos.stream() + .map(dto -> { + String presignedUrl = dto.photoUrl().isEmpty() ? "" : fileDownloadPort.getDownloadPresignedUrl(dto.photoUrl()); + return new AlbumResponseDto(dto.albumId(), presignedUrl, dto.like()); + }) + .collect(Collectors.toList()); + } + + public List getAlbumByLocation(double currentLat, double currentLon, String userEmail) { + List nearAlbumInfos = albumGetByLocationPort.getAlbumByLocation(currentLat, currentLon, userEmail); + + return nearAlbumInfos.stream() + .map(dto -> { + String presignedUrl = dto.photoUrl().isEmpty() ? "" : fileDownloadPort.getDownloadPresignedUrl(dto.photoUrl()); + return new NearAlbumInfo(presignedUrl, dto.x(), dto.y()); + }) + .collect(Collectors.toList()); + } + + public void deleteAlbum(Long albumId) { + albumDeletePort.deleteAlbum(albumId); + } + + @Override + public List getAlbumByHashtag(String hashtag, String userEmail) { + List albumHashtagResponseDtos = albumHashtagPort.getAlbumByHashtag(hashtag, userEmail); + + return albumHashtagResponseDtos.stream() + .map(dto -> { + String presignedUrl = dto.photoUrl().isEmpty() ? "" : fileDownloadPort.getDownloadPresignedUrl(dto.photoUrl()); + return new AlbumHashtagResponseDto(presignedUrl, dto.hashtags(), dto.year(), dto.month(), dto.date(), dto.memo(), dto.isLiked()); + }) + .collect(Collectors.toList()); + } + + + @Override + public List getFavoriteAlbums(String userEmail) { + List albumResponseDtos = albumFavoritePort.getFavoriteAlbums(userEmail); + + return albumResponseDtos.stream() + .map(dto -> { + String presignedUrl = dto.photoUrl().isEmpty() ? "" : fileDownloadPort.getDownloadPresignedUrl(dto.photoUrl()); + return new AlbumResponseDto(dto.albumId(), presignedUrl, dto.like()); + }) + .collect(Collectors.toList()); + } } \ No newline at end of file diff --git a/domain/src/main/java/com/pocket/domain/usecase/album/AlbumDeleteUseCase.java b/domain/src/main/java/com/pocket/domain/usecase/album/AlbumDeleteUseCase.java new file mode 100644 index 0000000..44436f7 --- /dev/null +++ b/domain/src/main/java/com/pocket/domain/usecase/album/AlbumDeleteUseCase.java @@ -0,0 +1,7 @@ +package com.pocket.domain.usecase.album; + +public interface AlbumDeleteUseCase { + + void deleteAlbum(Long albumId); + +} diff --git a/domain/src/main/java/com/pocket/domain/usecase/album/AlbumFavoriteUseCase.java b/domain/src/main/java/com/pocket/domain/usecase/album/AlbumFavoriteUseCase.java new file mode 100644 index 0000000..314ac7f --- /dev/null +++ b/domain/src/main/java/com/pocket/domain/usecase/album/AlbumFavoriteUseCase.java @@ -0,0 +1,11 @@ +package com.pocket.domain.usecase.album; + +import com.pocket.domain.dto.album.AlbumResponseDto; + +import java.util.List; + +public interface AlbumFavoriteUseCase { + + List getFavoriteAlbums(String userEmail); + +} diff --git a/domain/src/main/java/com/pocket/domain/usecase/album/AlbumGetByBrandUseCase.java b/domain/src/main/java/com/pocket/domain/usecase/album/AlbumGetByBrandUseCase.java new file mode 100644 index 0000000..30a2e20 --- /dev/null +++ b/domain/src/main/java/com/pocket/domain/usecase/album/AlbumGetByBrandUseCase.java @@ -0,0 +1,11 @@ +package com.pocket.domain.usecase.album; + +import com.pocket.domain.dto.album.AlbumResponseDto; + +import java.util.List; + +public interface AlbumGetByBrandUseCase { + + List getAlbumByBrand(String brandName, String userEmail); + +} diff --git a/domain/src/main/java/com/pocket/domain/usecase/album/AlbumGetByDateUseCase.java b/domain/src/main/java/com/pocket/domain/usecase/album/AlbumGetByDateUseCase.java new file mode 100644 index 0000000..5f20b5e --- /dev/null +++ b/domain/src/main/java/com/pocket/domain/usecase/album/AlbumGetByDateUseCase.java @@ -0,0 +1,11 @@ +package com.pocket.domain.usecase.album; + +import com.pocket.domain.dto.album.AlbumResponseDto; + +import java.util.List; + +public interface AlbumGetByDateUseCase { + + List getAlbumByDate(Integer year, Integer month, String userEmail); + +} diff --git a/domain/src/main/java/com/pocket/domain/usecase/album/AlbumGetByLocationUseCase.java b/domain/src/main/java/com/pocket/domain/usecase/album/AlbumGetByLocationUseCase.java new file mode 100644 index 0000000..72fabe4 --- /dev/null +++ b/domain/src/main/java/com/pocket/domain/usecase/album/AlbumGetByLocationUseCase.java @@ -0,0 +1,11 @@ +package com.pocket.domain.usecase.album; + +import com.pocket.domain.dto.album.NearAlbumInfo; + +import java.util.List; + +public interface AlbumGetByLocationUseCase { + + List getAlbumByLocation(double currentLat, double currentLon, String userEmail); + +} diff --git a/domain/src/main/java/com/pocket/domain/usecase/album/AlbumHashtagUseCase.java b/domain/src/main/java/com/pocket/domain/usecase/album/AlbumHashtagUseCase.java new file mode 100644 index 0000000..7250f6f --- /dev/null +++ b/domain/src/main/java/com/pocket/domain/usecase/album/AlbumHashtagUseCase.java @@ -0,0 +1,11 @@ +package com.pocket.domain.usecase.album; + +import com.pocket.domain.dto.album.AlbumHashtagResponseDto; + +import java.util.List; + +public interface AlbumHashtagUseCase { + + List getAlbumByHashtag(String hashtag, String userEmail); + +} diff --git a/domain/src/main/java/com/pocket/domain/usecase/album/AlbumLikeUseCase.java b/domain/src/main/java/com/pocket/domain/usecase/album/AlbumLikeUseCase.java new file mode 100644 index 0000000..2528c74 --- /dev/null +++ b/domain/src/main/java/com/pocket/domain/usecase/album/AlbumLikeUseCase.java @@ -0,0 +1,7 @@ +package com.pocket.domain.usecase.album; + +public interface AlbumLikeUseCase { + + void likeAlbum(Long albumId); + +} diff --git a/inbounds/src/main/java/com/pocket/inbounds/album/presentation/AlbumContollerDocs.java b/inbounds/src/main/java/com/pocket/inbounds/album/presentation/AlbumContollerDocs.java index bb2d9ef..d4c342f 100644 --- a/inbounds/src/main/java/com/pocket/inbounds/album/presentation/AlbumContollerDocs.java +++ b/inbounds/src/main/java/com/pocket/inbounds/album/presentation/AlbumContollerDocs.java @@ -2,8 +2,7 @@ import com.nimbusds.oauth2.sdk.ErrorResponse; import com.pocket.core.exception.common.ApplicationResponse; -import com.pocket.domain.dto.album.AlbumRegisterRequestDto; -import com.pocket.domain.dto.album.AlbumRegisterResponseDto; +import com.pocket.domain.dto.album.*; import com.pocket.domain.dto.user.UserInfoDTO; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.Content; @@ -12,7 +11,11 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; + +import java.util.List; @Tag(name = "Album", description = "Album API") public interface AlbumContollerDocs { @@ -28,4 +31,85 @@ public interface AlbumContollerDocs { ApplicationResponse postPhoto( @RequestBody AlbumRegisterRequestDto requestDto, @AuthenticationPrincipal UserInfoDTO user); + + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "400", description = "BAD REQUEST", + content = {@Content(schema = @Schema(implementation = ErrorResponse.class))}), + @ApiResponse(responseCode = "500", description = "INTERNAL SERVER ERROR", + content = {@Content(schema = @Schema(implementation = ErrorResponse.class))}) + }) + @Operation(summary = "앨범 좋아요", description = "특정 앨범에 좋아요를 표시하는 API") + ApplicationResponse likeAlbum(@PathVariable("album_id") Long albumId); + + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "400", description = "BAD REQUEST", + content = {@Content(schema = @Schema(implementation = ErrorResponse.class))}), + @ApiResponse(responseCode = "500", description = "INTERNAL SERVER ERROR", + content = {@Content(schema = @Schema(implementation = ErrorResponse.class))}) + }) + @Operation(summary = "월별 앨범 조회", description = "특정 연도와 월에 대한 앨범을 조회하는 API") + ApplicationResponse> getAlbumByDate( + @PathVariable("year") Integer year, + @PathVariable("month") Integer month, + @AuthenticationPrincipal UserInfoDTO user); + + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "400", description = "BAD REQUEST", + content = {@Content(schema = @Schema(implementation = ErrorResponse.class))}), + @ApiResponse(responseCode = "500", description = "INTERNAL SERVER ERROR", + content = {@Content(schema = @Schema(implementation = ErrorResponse.class))}) + }) + @Operation(summary = "브랜드별 앨범 조회", description = "특정 포토부스 브랜드에 대한 앨범을 조회하는 API") + ApplicationResponse> getAlbumByBrand( + @PathVariable("brand_name") String brandName, + @AuthenticationPrincipal UserInfoDTO user); + + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "400", description = "BAD REQUEST", + content = {@Content(schema = @Schema(implementation = ErrorResponse.class))}), + @ApiResponse(responseCode = "500", description = "INTERNAL SERVER ERROR", + content = {@Content(schema = @Schema(implementation = ErrorResponse.class))}) + }) + @Operation(summary = "위치 기반 앨범 조회", description = "사용자 위치 주변의 앨범을 조회하는 API") + ApplicationResponse> getAlbumByLocation( + @RequestParam("lat") double lat, + @RequestParam("lon") double lon, + @AuthenticationPrincipal UserInfoDTO user); + + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "400", description = "BAD REQUEST", + content = {@Content(schema = @Schema(implementation = ErrorResponse.class))}), + @ApiResponse(responseCode = "500", description = "INTERNAL SERVER ERROR", + content = {@Content(schema = @Schema(implementation = ErrorResponse.class))}) + }) + @Operation(summary = "앨범 삭제", description = "특정 앨범을 삭제하는 API") + ApplicationResponse deleteAlbum(@PathVariable("album_id") Long albumId); + + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "400", description = "BAD REQUEST", + content = {@Content(schema = @Schema(implementation = ErrorResponse.class))}), + @ApiResponse(responseCode = "500", description = "INTERNAL SERVER ERROR", + content = {@Content(schema = @Schema(implementation = ErrorResponse.class))}) + }) + @Operation(summary = "해시태그로 앨범 검색", description = "특정 해시태그가 포함된 앨범을 조회하는 API") + ApplicationResponse> getAlbumByHashtag( + @PathVariable("hashtag") String hashtag, + @AuthenticationPrincipal UserInfoDTO user); + + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "400", description = "BAD REQUEST", + content = {@Content(schema = @Schema(implementation = ErrorResponse.class))}), + @ApiResponse(responseCode = "500", description = "INTERNAL SERVER ERROR", + content = {@Content(schema = @Schema(implementation = ErrorResponse.class))}) + }) + @Operation(summary = "즐겨찾기 앨범 검색 (마이페이지)", description = "좋아요가 눌린 앨범을 조회하는 API") + ApplicationResponse> getFavoriteAlbums( + @AuthenticationPrincipal UserInfoDTO user); } diff --git a/inbounds/src/main/java/com/pocket/inbounds/album/presentation/AlbumController.java b/inbounds/src/main/java/com/pocket/inbounds/album/presentation/AlbumController.java index 46cd288..18f54c1 100644 --- a/inbounds/src/main/java/com/pocket/inbounds/album/presentation/AlbumController.java +++ b/inbounds/src/main/java/com/pocket/inbounds/album/presentation/AlbumController.java @@ -1,16 +1,15 @@ package com.pocket.inbounds.album.presentation; import com.pocket.core.exception.common.ApplicationResponse; -import com.pocket.domain.dto.album.AlbumRegisterRequestDto; -import com.pocket.domain.dto.album.AlbumRegisterResponseDto; +import com.pocket.domain.dto.album.*; import com.pocket.domain.dto.user.UserInfoDTO; -import com.pocket.domain.usecase.album.AlbumRegisterUseCase; +import com.pocket.domain.usecase.album.*; +import jakarta.persistence.criteria.CriteriaBuilder; import lombok.RequiredArgsConstructor; import org.springframework.security.core.annotation.AuthenticationPrincipal; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; + +import java.util.List; @RestController @RequiredArgsConstructor @@ -18,6 +17,13 @@ public class AlbumController implements AlbumContollerDocs{ private final AlbumRegisterUseCase albumRegisterUseCase; + private final AlbumLikeUseCase albumLikeUseCase; + private final AlbumGetByDateUseCase albumGetByDateUseCase; + private final AlbumGetByBrandUseCase albumGetByBrandUseCase; + private final AlbumGetByLocationUseCase albumGetByLocationUseCase; + private final AlbumDeleteUseCase albumDeleteUseCase; + private final AlbumHashtagUseCase albumHashtagUseCase; + private final AlbumFavoriteUseCase albumFavoriteUseCase; @PostMapping public ApplicationResponse postPhoto( @@ -28,4 +34,78 @@ public ApplicationResponse postPhoto( return ApplicationResponse.ok(response); } + + // 좋아요 기능 + @PostMapping("/like/{album_id}") + public ApplicationResponse likeAlbum( + @PathVariable("album_id") Long albumId + ) { + albumLikeUseCase.likeAlbum(albumId); + return ApplicationResponse.ok("Success"); + } + + + // 월별 조회 + @GetMapping("/date/{year}/{month}") + public ApplicationResponse> getAlbumByDate( + @PathVariable("year") Integer year, + @PathVariable("month") Integer month, + @AuthenticationPrincipal UserInfoDTO user + ) { + List response = albumGetByDateUseCase.getAlbumByDate(year, month, user.email()); + return ApplicationResponse.ok(response); + } + + // 포토부스별 조회 + @GetMapping("/photobooth/{brand_name}") + public ApplicationResponse> getAlbumByBrand( + @PathVariable("brand_name") String brandName, + @AuthenticationPrincipal UserInfoDTO user + ) { + List response = albumGetByBrandUseCase.getAlbumByBrand(brandName, user.email()); + return ApplicationResponse.ok(response); + } + + // 위치별 조회? + @GetMapping("/location") + public ApplicationResponse> getAlbumByLocation( + @RequestParam("lat") double lat, + @RequestParam("lon") double lon, + @AuthenticationPrincipal UserInfoDTO user + ) { + List response = albumGetByLocationUseCase.getAlbumByLocation(lat, lon, user.email()); + return ApplicationResponse.ok(response); + } + + + // 삭제 기능 + @DeleteMapping("/{album_id}") + public ApplicationResponse deleteAlbum( + @PathVariable("album_id") Long albumId + ) { + albumDeleteUseCase.deleteAlbum(albumId); + return ApplicationResponse.ok("Success"); + } + + + // 해시태그 검색 기능 + @GetMapping("/hashtag/{hashtag}") + public ApplicationResponse> getAlbumByHashtag( + @PathVariable("hashtag") String hashtag, + @AuthenticationPrincipal UserInfoDTO user + ) { + List response = albumHashtagUseCase.getAlbumByHashtag(hashtag, user.email()); + return ApplicationResponse.ok(response); + } + + + // 즐겨찾기 검색 + @GetMapping("/favorite") + public ApplicationResponse> getFavoriteAlbums( + @AuthenticationPrincipal UserInfoDTO user + ) { + List response = albumFavoriteUseCase.getFavoriteAlbums(user.email()); + return ApplicationResponse.ok(response); + } + } diff --git a/outbound/src/main/java/com/pocket/outbound/adapter/album/adapter/AlbumDeleteAdapter.java b/outbound/src/main/java/com/pocket/outbound/adapter/album/adapter/AlbumDeleteAdapter.java new file mode 100644 index 0000000..a732054 --- /dev/null +++ b/outbound/src/main/java/com/pocket/outbound/adapter/album/adapter/AlbumDeleteAdapter.java @@ -0,0 +1,23 @@ +package com.pocket.outbound.adapter.album.adapter; + +import com.pocket.core.aop.annotation.AdapterService; +import com.pocket.domain.port.album.AlbumDeletePort; +import com.pocket.outbound.repository.album.AlbumHashTagRepository; +import com.pocket.outbound.repository.album.AlbumRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.transaction.annotation.Transactional; + +@AdapterService +@RequiredArgsConstructor +public class AlbumDeleteAdapter implements AlbumDeletePort { + + private final AlbumHashTagRepository albumHashTagRepository; + private final AlbumRepository albumRepository; + + @Override + @Transactional + public void deleteAlbum(Long albumId) { + albumHashTagRepository.deleteByJpaAlbum_Id(albumId); + albumRepository.deleteById(albumId); + } +} diff --git a/outbound/src/main/java/com/pocket/outbound/adapter/album/adapter/AlbumFavoriteAdapter.java b/outbound/src/main/java/com/pocket/outbound/adapter/album/adapter/AlbumFavoriteAdapter.java new file mode 100644 index 0000000..b5fe1bc --- /dev/null +++ b/outbound/src/main/java/com/pocket/outbound/adapter/album/adapter/AlbumFavoriteAdapter.java @@ -0,0 +1,35 @@ +package com.pocket.outbound.adapter.album.adapter; + +import com.pocket.core.aop.annotation.AdapterService; +import com.pocket.domain.dto.album.AlbumResponseDto; +import com.pocket.domain.port.album.AlbumFavoritePort; +import com.pocket.outbound.entity.album.JpaAlbum; +import com.pocket.outbound.repository.album.AlbumRepository; +import lombok.RequiredArgsConstructor; + +import java.util.List; +import java.util.stream.Collectors; + + +@AdapterService +@RequiredArgsConstructor +public class AlbumFavoriteAdapter implements AlbumFavoritePort { + + private final AlbumRepository albumRepository; + + @Override + public List getFavoriteAlbums(String userEmail) { + List jpaAlbums = albumRepository.findByJpaUserUserEmail(userEmail); + + List likedAlbums = jpaAlbums.stream() + .filter(JpaAlbum::isLiked) // isLiked가 true인 요소만 필터링 + .toList(); + + return likedAlbums.stream() + .map(jpaAlbum -> new AlbumResponseDto( + jpaAlbum.getId(), + jpaAlbum.getImage().getImageUrl(), + jpaAlbum.isLiked())) + .collect(Collectors.toList()); + } +} diff --git a/outbound/src/main/java/com/pocket/outbound/adapter/album/adapter/AlbumGetByBrandAdapter.java b/outbound/src/main/java/com/pocket/outbound/adapter/album/adapter/AlbumGetByBrandAdapter.java new file mode 100644 index 0000000..9bc615a --- /dev/null +++ b/outbound/src/main/java/com/pocket/outbound/adapter/album/adapter/AlbumGetByBrandAdapter.java @@ -0,0 +1,33 @@ +package com.pocket.outbound.adapter.album.adapter; + +import com.pocket.core.aop.annotation.AdapterService; +import com.pocket.domain.dto.album.AlbumResponseDto; +import com.pocket.domain.entity.photobooth.PhotoBoothBrand; +import com.pocket.domain.port.album.AlbumGetByBrandPort; +import com.pocket.outbound.entity.album.JpaAlbum; +import com.pocket.outbound.repository.album.AlbumRepository; +import lombok.RequiredArgsConstructor; + +import java.util.List; +import java.util.stream.Collectors; + +@AdapterService +@RequiredArgsConstructor +public class AlbumGetByBrandAdapter implements AlbumGetByBrandPort { + + private final AlbumRepository albumRepository; + + @Override + public List getAlbumByBrand(String brandName, String userEmail) { + PhotoBoothBrand brand = PhotoBoothBrand.fromKoreanName(brandName); + List albums = albumRepository.findByJpaUserUserEmailAndPhotoBoothPhotoBoothPhotoBoothBrand(userEmail,brand); + + return albums.stream() + .map(jpaAlbum -> new AlbumResponseDto( + jpaAlbum.getId(), + jpaAlbum.getImage().getImageUrl(), + jpaAlbum.isLiked())) + .collect(Collectors.toList()); + } + +} diff --git a/outbound/src/main/java/com/pocket/outbound/adapter/album/adapter/AlbumGetByDateAdapter.java b/outbound/src/main/java/com/pocket/outbound/adapter/album/adapter/AlbumGetByDateAdapter.java new file mode 100644 index 0000000..132badf --- /dev/null +++ b/outbound/src/main/java/com/pocket/outbound/adapter/album/adapter/AlbumGetByDateAdapter.java @@ -0,0 +1,31 @@ +package com.pocket.outbound.adapter.album.adapter; + +import com.pocket.core.aop.annotation.AdapterService; +import com.pocket.domain.dto.album.AlbumResponseDto; +import com.pocket.domain.port.album.AlbumGetByDatePort; +import com.pocket.outbound.entity.album.JpaAlbum; +import com.pocket.outbound.repository.album.AlbumRepository; +import lombok.RequiredArgsConstructor; + +import java.util.List; +import java.util.stream.Collectors; + + +@AdapterService +@RequiredArgsConstructor +public class AlbumGetByDateAdapter implements AlbumGetByDatePort { + + private final AlbumRepository albumRepository; + + @Override + public List getAlbumByDate(Integer year, Integer month, String userEmail) { + List albums = albumRepository.findByJpaUserUserEmailAndImageYearAndImageMonth(userEmail, year, month); + + return albums.stream() + .map(jpaAlbum -> new AlbumResponseDto( + jpaAlbum.getId(), + jpaAlbum.getImage().getImageUrl(), + jpaAlbum.isLiked())) + .collect(Collectors.toList()); + } +} diff --git a/outbound/src/main/java/com/pocket/outbound/adapter/album/adapter/AlbumGetByLocationAdapter.java b/outbound/src/main/java/com/pocket/outbound/adapter/album/adapter/AlbumGetByLocationAdapter.java new file mode 100644 index 0000000..40aea47 --- /dev/null +++ b/outbound/src/main/java/com/pocket/outbound/adapter/album/adapter/AlbumGetByLocationAdapter.java @@ -0,0 +1,47 @@ +package com.pocket.outbound.adapter.album.adapter; + +import com.pocket.core.aop.annotation.AdapterService; +import com.pocket.core.exception.user.UserCustomException; +import com.pocket.core.exception.user.UserErrorCode; +import com.pocket.core.util.DistanceCalculator; +import com.pocket.domain.dto.album.NearAlbumInfo; +import com.pocket.domain.port.album.AlbumGetByLocationPort; +import com.pocket.outbound.entity.JpaUser; +import com.pocket.outbound.entity.album.JpaAlbum; +import com.pocket.outbound.repository.UserRepository; +import com.pocket.outbound.repository.album.AlbumRepository; +import lombok.RequiredArgsConstructor; + +import java.util.List; +import java.util.stream.Collectors; + + + +@AdapterService +@RequiredArgsConstructor +public class AlbumGetByLocationAdapter implements AlbumGetByLocationPort { + + private final AlbumRepository albumRepository; + + @Override + public List getAlbumByLocation(double currentLat, double currentLon, String userEmail) { + List allAlbums = albumRepository.findByJpaUserUserEmail(userEmail); + + List albumList = allAlbums.stream() + .filter(album -> { + double distance = DistanceCalculator.haversineDistance( + currentLat, currentLon,album.getPhotoBooth().getPhotoBooth().getX(), album.getPhotoBooth().getPhotoBooth().getY() + ); + return distance <= 2.0; + }) + .toList(); + + return albumList.stream() + .map(jpaAlbum -> new NearAlbumInfo( + jpaAlbum.getImage().getImageUrl(), + jpaAlbum.getPhotoBooth().getPhotoBooth().getX(), + jpaAlbum.getPhotoBooth().getPhotoBooth().getY() + )) + .collect(Collectors.toList()); + } +} diff --git a/outbound/src/main/java/com/pocket/outbound/adapter/album/adapter/AlbumHashtagAdapter.java b/outbound/src/main/java/com/pocket/outbound/adapter/album/adapter/AlbumHashtagAdapter.java new file mode 100644 index 0000000..595176f --- /dev/null +++ b/outbound/src/main/java/com/pocket/outbound/adapter/album/adapter/AlbumHashtagAdapter.java @@ -0,0 +1,53 @@ +package com.pocket.outbound.adapter.album.adapter; + +import com.pocket.core.aop.annotation.AdapterService; +import com.pocket.core.exception.user.UserCustomException; +import com.pocket.core.exception.user.UserErrorCode; +import com.pocket.domain.dto.album.AlbumHashtagResponseDto; +import com.pocket.domain.port.album.AlbumHashtagPort; +import com.pocket.outbound.entity.JpaUser; +import com.pocket.outbound.entity.album.JpaAlbumHashTag; +import com.pocket.outbound.repository.UserRepository; +import com.pocket.outbound.repository.album.AlbumHashTagRepository; +import lombok.RequiredArgsConstructor; + +import java.util.List; +import java.util.stream.Collectors; + +@AdapterService +@RequiredArgsConstructor +public class AlbumHashtagAdapter implements AlbumHashtagPort { + + private final UserRepository userRepository; + private final AlbumHashTagRepository albumHashTagRepository; + + @Override + public List getAlbumByHashtag(String hashtag, String userEmail) { + JpaUser user = userRepository.findByUserEmail(userEmail) + .orElseThrow(() -> new UserCustomException(UserErrorCode.NO_USER_INFO)); + + List albumHashTags = albumHashTagRepository.findByJpaAlbum_JpaUserAndJpaHashtag_HashTag_Content(user, hashtag); + + return albumHashTags.stream() + .map(jpaAlbumHashTag -> { + var album = jpaAlbumHashTag.getJpaAlbum(); + + // 해당 앨범과 관련된 해시태그 목록 가져오기 + List hashtags = albumHashTagRepository.findByJpaAlbum_Id(album.getId()).stream() + .map(tag -> tag.getJpaHashtag().getHashTag().getContent()) + .collect(Collectors.toList()); + + // AlbumHashtagResponseDto 구성 + return new AlbumHashtagResponseDto( + album.getImage().getImageUrl(), + hashtags, + album.getImage().getYear(), + album.getImage().getMonth(), + album.getImage().getDate(), + album.getMemo().getContent(), + album.isLiked() + ); + }) + .collect(Collectors.toList()); + } +} diff --git a/outbound/src/main/java/com/pocket/outbound/adapter/album/adapter/AlbumLikeAdapter.java b/outbound/src/main/java/com/pocket/outbound/adapter/album/adapter/AlbumLikeAdapter.java new file mode 100644 index 0000000..5a0a623 --- /dev/null +++ b/outbound/src/main/java/com/pocket/outbound/adapter/album/adapter/AlbumLikeAdapter.java @@ -0,0 +1,27 @@ +package com.pocket.outbound.adapter.album.adapter; + +import com.pocket.core.aop.annotation.AdapterService; +import com.pocket.core.exception.album.AlbumCustomException; +import com.pocket.core.exception.album.AlbumErrorCode; +import com.pocket.domain.port.album.AlbumLikePort; +import com.pocket.outbound.entity.album.JpaAlbum; +import com.pocket.outbound.repository.album.AlbumRepository; +import lombok.RequiredArgsConstructor; + + +@AdapterService +@RequiredArgsConstructor +public class AlbumLikeAdapter implements AlbumLikePort { + + private final AlbumRepository albumRepository; + + @Override + public void likeAlbum(Long albumId) { + JpaAlbum album = albumRepository.findById(albumId) + .orElseThrow(() -> new AlbumCustomException(AlbumErrorCode.ALBUM_NOT_FOUND)); + + album.toggleLike(); + albumRepository.save(album); + } + +} diff --git a/outbound/src/main/java/com/pocket/outbound/adapter/album/adapter/AlbumRegisterAdapter.java b/outbound/src/main/java/com/pocket/outbound/adapter/album/adapter/AlbumRegisterAdapter.java index 73bcd5c..1ab01b7 100644 --- a/outbound/src/main/java/com/pocket/outbound/adapter/album/adapter/AlbumRegisterAdapter.java +++ b/outbound/src/main/java/com/pocket/outbound/adapter/album/adapter/AlbumRegisterAdapter.java @@ -35,23 +35,33 @@ public class AlbumRegisterAdapter implements AlbumRegisterPort { @Override public AlbumRegisterResponseDto registerPhoto(AlbumRegisterRequestDto dto, String name) { + // 포토 부스 찾기 JpaPhotoBooth photoBooth = photoBoothRepository.findById(dto.photoboothId()) .orElseThrow(() -> new PhotoBoothCustomException(PhotoBoothErrorCode.PHOTOBOOTH_NOT_FOUND)); + // 사용자 찾기 JpaUser jpaUser = userRepository.findByUserName(name) .orElseThrow(() -> new UserCustomException(UserErrorCode.NO_USER_INFO)); + // 앨범 생성 JpaAlbum photoEntity = albumOutBoundMapper.toJpaAlbum(dto, photoBooth, jpaUser); albumRepository.save(photoEntity); + // 해시태그 처리 for (String hashtag : dto.hashtag()) { - JpaHashTag hashtagEntity = albumOutBoundMapper.toJpaHashTag(hashtag, jpaUser); - JpaAlbumHashTag imageHashtagEntity = albumOutBoundMapper.toJpaAlbumHashTag(photoEntity, hashtagEntity); + JpaHashTag hashtagEntity = hashtagRepository.findByHashTag_ContentAndJpaUser_Id(hashtag, jpaUser.getId()) + .orElseGet(() -> { + // 해시태그가 존재하지 않으면 새로 생성 + JpaHashTag newHashTag = albumOutBoundMapper.toJpaHashTag(hashtag, jpaUser); + return hashtagRepository.save(newHashTag); + }); - hashtagRepository.save(hashtagEntity); - photoHashtagRepository.save(imageHashtagEntity); + // 앨범-해시태그 매핑 엔티티 생성 및 저장 + JpaAlbumHashTag albumHashtagEntity = albumOutBoundMapper.toJpaAlbumHashTag(photoEntity, hashtagEntity); + photoHashtagRepository.save(albumHashtagEntity); } + // 응답 DTO 생성 및 반환 return new AlbumRegisterResponseDto( dto.photoboothId(), dto.year(), diff --git a/outbound/src/main/java/com/pocket/outbound/adapter/album/mapper/AlbumOutBoundMapper.java b/outbound/src/main/java/com/pocket/outbound/adapter/album/mapper/AlbumOutBoundMapper.java index 1a99fec..809f6c4 100644 --- a/outbound/src/main/java/com/pocket/outbound/adapter/album/mapper/AlbumOutBoundMapper.java +++ b/outbound/src/main/java/com/pocket/outbound/adapter/album/mapper/AlbumOutBoundMapper.java @@ -27,6 +27,7 @@ public JpaAlbum toJpaAlbum(AlbumRegisterRequestDto dto, JpaPhotoBooth photoBooth .jpaUser(jpaUser) .memo(memo) .image(image) + .isLiked(false) .build(); } diff --git a/outbound/src/main/java/com/pocket/outbound/config/SecurityConfig.java b/outbound/src/main/java/com/pocket/outbound/config/SecurityConfig.java index 45f0313..83c2084 100644 --- a/outbound/src/main/java/com/pocket/outbound/config/SecurityConfig.java +++ b/outbound/src/main/java/com/pocket/outbound/config/SecurityConfig.java @@ -55,13 +55,12 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti "/v3/api-docs/**", "/api/v1/photobooth/**", "/api/v1/review/**", - "/api/v1/album/**", "/v1/public/**", "/page").permitAll(); // 로그인 필요 authz.requestMatchers("/v1/user/**", - "/api/v1/album", + "/api/v1/album/**", "/api/v1/review").authenticated(); // 그 외의 모든 요청은 인증 필요 diff --git a/outbound/src/main/java/com/pocket/outbound/entity/album/JpaAlbum.java b/outbound/src/main/java/com/pocket/outbound/entity/album/JpaAlbum.java index 0647d4e..dbc6228 100644 --- a/outbound/src/main/java/com/pocket/outbound/entity/album/JpaAlbum.java +++ b/outbound/src/main/java/com/pocket/outbound/entity/album/JpaAlbum.java @@ -39,5 +39,10 @@ public class JpaAlbum { @JoinColumn(name = "photobooth_id") private JpaPhotoBooth photoBooth; + private boolean isLiked; + + public void toggleLike() { + this.isLiked = !this.isLiked; + } } diff --git a/outbound/src/main/java/com/pocket/outbound/entity/review/JpaReviewImage.java b/outbound/src/main/java/com/pocket/outbound/entity/review/JpaReviewImage.java index 80bde7e..49f1443 100644 --- a/outbound/src/main/java/com/pocket/outbound/entity/review/JpaReviewImage.java +++ b/outbound/src/main/java/com/pocket/outbound/entity/review/JpaReviewImage.java @@ -1,6 +1,6 @@ package com.pocket.outbound.entity.review; -import com.pocket.domain.entity.image.Image; +import com.pocket.domain.entity.image. Image; import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/outbound/src/main/java/com/pocket/outbound/repository/album/AlbumHashTagRepository.java b/outbound/src/main/java/com/pocket/outbound/repository/album/AlbumHashTagRepository.java index ca218b2..c8c9b22 100644 --- a/outbound/src/main/java/com/pocket/outbound/repository/album/AlbumHashTagRepository.java +++ b/outbound/src/main/java/com/pocket/outbound/repository/album/AlbumHashTagRepository.java @@ -1,7 +1,18 @@ package com.pocket.outbound.repository.album; +import com.pocket.domain.entity.album.HashTag; +import com.pocket.outbound.entity.JpaUser; import com.pocket.outbound.entity.album.JpaAlbumHashTag; import org.springframework.data.jpa.repository.JpaRepository; +import java.util.List; + public interface AlbumHashTagRepository extends JpaRepository { + + List findByJpaAlbum_JpaUserAndJpaHashtag_HashTag_Content(JpaUser user, String hashTag); + + List findByJpaAlbum_Id(Long albumId); + + void deleteByJpaAlbum_Id(Long albumId); + } diff --git a/outbound/src/main/java/com/pocket/outbound/repository/album/AlbumRepository.java b/outbound/src/main/java/com/pocket/outbound/repository/album/AlbumRepository.java index 48c671d..fd9cfe1 100644 --- a/outbound/src/main/java/com/pocket/outbound/repository/album/AlbumRepository.java +++ b/outbound/src/main/java/com/pocket/outbound/repository/album/AlbumRepository.java @@ -1,8 +1,17 @@ package com.pocket.outbound.repository.album; +import com.pocket.domain.entity.photobooth.PhotoBoothBrand; import com.pocket.outbound.entity.album.JpaAlbum; import org.springframework.data.jpa.repository.JpaRepository; +import java.util.List; + public interface AlbumRepository extends JpaRepository { + List findByJpaUserUserEmailAndPhotoBoothPhotoBoothPhotoBoothBrand(String userEmail, PhotoBoothBrand brand); + + List findByJpaUserUserEmailAndImageYearAndImageMonth(String userEmail, Integer year, Integer month); + + List findByJpaUserUserEmail(String userEmail); + } diff --git a/outbound/src/main/java/com/pocket/outbound/repository/album/HashTagRepository.java b/outbound/src/main/java/com/pocket/outbound/repository/album/HashTagRepository.java index b061f5f..ac5b691 100644 --- a/outbound/src/main/java/com/pocket/outbound/repository/album/HashTagRepository.java +++ b/outbound/src/main/java/com/pocket/outbound/repository/album/HashTagRepository.java @@ -3,5 +3,9 @@ import com.pocket.outbound.entity.album.JpaHashTag; import org.springframework.data.jpa.repository.JpaRepository; +import java.util.Optional; + public interface HashTagRepository extends JpaRepository { + + Optional findByHashTag_ContentAndJpaUser_Id(String hashtag, Long userId); }