Skip to content

Commit 7138b24

Browse files
authored
Merge pull request #322 from DevKor-github/develop
#319~#321 반영해 배포
2 parents 93213fa + 23a2374 commit 7138b24

40 files changed

Lines changed: 1124 additions & 36 deletions

File tree

src/main/java/org/devkor/apu/saerok_server/domain/collection/application/CollectionQueryService.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ public GetNearbyCollectionsResponse getNearbyCollections(GetNearbyCollectionsCom
214214
boolean isLikedByMe = command.userId() != null && myLikeMap.getOrDefault(c.getId(), false);
215215
String userProfileImageUrl = profileImageMap.get(c.getUser().getId());
216216
String thumbnailProfileImageUrl = thumbnailProfileImageMap.get(c.getUser().getId());
217+
boolean isMine = command.userId() != null && command.userId().equals(c.getUser().getId());
217218

218219
return collectionWebMapper.toGetNearbyCollectionsResponseItem(
219220
c,
@@ -223,7 +224,8 @@ public GetNearbyCollectionsResponse getNearbyCollections(GetNearbyCollectionsCom
223224
thumbnailProfileImageUrl,
224225
likeCount,
225226
commentCount,
226-
isLikedByMe
227+
isLikedByMe,
228+
isMine
227229
);
228230
})
229231
.toList();

src/main/java/org/devkor/apu/saerok_server/domain/collection/core/repository/CollectionRepository.java

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public List<UserBirdCollection> findNearby(Point ref, double radiusMeters, Long
5555

5656
if (isMineOnly && userId != null) {
5757
String sqlMineOnly = """
58-
SELECT *
58+
SELECT c.*
5959
FROM user_bird_collection c
6060
WHERE ST_DWithin(
6161
c.location::geography,
@@ -79,8 +79,9 @@ ORDER BY ST_Distance(
7979
}
8080

8181
String sqlAll = """
82-
SELECT *
82+
SELECT c.*
8383
FROM user_bird_collection c
84+
LEFT JOIN bird b ON b.id = c.bird_id
8485
WHERE ST_DWithin(
8586
c.location::geography,
8687
CAST(:refPoint AS geography),
@@ -90,6 +91,11 @@ WHERE ST_DWithin(
9091
c.access_level = 'PUBLIC'
9192
OR (CAST(:userId AS bigint) IS NOT NULL AND c.user_id = :userId)
9293
)
94+
AND (
95+
c.bird_id IS NULL
96+
OR b.conservation_grade = 'NONE'
97+
OR (CAST(:userId AS bigint) IS NOT NULL AND c.user_id = :userId)
98+
)
9399
ORDER BY ST_Distance(
94100
c.location::geography,
95101
CAST(:refPoint AS geography)
@@ -130,6 +136,7 @@ WHERE ST_DWithin(
130136
String sql = """
131137
SELECT COUNT(*)
132138
FROM user_bird_collection c
139+
LEFT JOIN bird b ON b.id = c.bird_id
133140
WHERE ST_DWithin(
134141
c.location::geography,
135142
CAST(:refPoint AS geography),
@@ -139,6 +146,11 @@ WHERE ST_DWithin(
139146
c.access_level = 'PUBLIC'
140147
OR (CAST(:userId AS bigint) IS NOT NULL AND c.user_id = :userId)
141148
)
149+
AND (
150+
c.bird_id IS NULL
151+
OR b.conservation_grade = 'NONE'
152+
OR (CAST(:userId AS bigint) IS NOT NULL AND c.user_id = :userId)
153+
)
142154
""";
143155

144156
var query = em.createNativeQuery(sql)
@@ -203,6 +215,7 @@ WITH candidates AS (
203215
ST_Distance(c.location::geography, CAST(:refPoint AS geography)) AS dist,
204216
ST_SnapToGrid(ST_Transform(c.location, 3857), :gridSize, :gridSize) AS cell_id
205217
FROM user_bird_collection c
218+
LEFT JOIN bird b ON b.id = c.bird_id
206219
WHERE ST_DWithin(
207220
c.location::geography,
208221
CAST(:refPoint AS geography),
@@ -212,6 +225,11 @@ WHERE ST_DWithin(
212225
c.access_level = 'PUBLIC'
213226
OR (CAST(:userId AS bigint) IS NOT NULL AND c.user_id = :userId)
214227
)
228+
AND (
229+
c.bird_id IS NULL
230+
OR b.conservation_grade = 'NONE'
231+
OR (CAST(:userId AS bigint) IS NOT NULL AND c.user_id = :userId)
232+
)
215233
), ranked AS (
216234
SELECT id,
217235
dist,
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package org.devkor.apu.saerok_server.domain.collection.core.service;
2+
3+
import org.devkor.apu.saerok_server.domain.collection.core.entity.UserBirdCollection;
4+
import org.devkor.apu.saerok_server.domain.dex.bird.core.entity.Bird;
5+
import org.devkor.apu.saerok_server.domain.dex.bird.core.enums.ConservationGrade;
6+
7+
public final class CollectionLocationMasker {
8+
9+
private CollectionLocationMasker() {
10+
}
11+
12+
public static Double latitude(UserBirdCollection collection, boolean isOwner) {
13+
if (shouldMaskLocation(collection, isOwner) || collection == null || collection.getLocation() == null) {
14+
return null;
15+
}
16+
return collection.getLatitude();
17+
}
18+
19+
public static Double longitude(UserBirdCollection collection, boolean isOwner) {
20+
if (shouldMaskLocation(collection, isOwner) || collection == null || collection.getLocation() == null) {
21+
return null;
22+
}
23+
return collection.getLongitude();
24+
}
25+
26+
public static String locationAlias(UserBirdCollection collection, boolean isOwner) {
27+
if (shouldMaskLocation(collection, isOwner) || collection == null) {
28+
return null;
29+
}
30+
return collection.getLocationAlias();
31+
}
32+
33+
public static String address(UserBirdCollection collection, boolean isOwner) {
34+
if (shouldMaskLocation(collection, isOwner) || collection == null) {
35+
return null;
36+
}
37+
return collection.getAddress();
38+
}
39+
40+
public static boolean shouldMaskLocation(UserBirdCollection collection, boolean isOwner) {
41+
if (isOwner || collection == null) {
42+
return false;
43+
}
44+
45+
Bird bird = collection.getBird();
46+
if (bird == null) {
47+
return false;
48+
}
49+
50+
ConservationGrade grade = bird.getConservationGrade();
51+
return grade != null && grade.shouldHideLocation();
52+
}
53+
}

src/main/java/org/devkor/apu/saerok_server/domain/collection/mapper/CollectionWebMapper.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@
99
import org.devkor.apu.saerok_server.domain.collection.application.dto.DeleteCollectionCommand;
1010
import org.devkor.apu.saerok_server.domain.collection.application.dto.*;
1111
import org.devkor.apu.saerok_server.domain.collection.core.entity.UserBirdCollection;
12+
import org.devkor.apu.saerok_server.domain.collection.core.service.CollectionLocationMasker;
1213
import org.mapstruct.Mapper;
1314
import org.mapstruct.Mapping;
1415
import org.mapstruct.MappingConstants;
1516
import org.mapstruct.Named;
1617

1718
@Mapper(
18-
componentModel = MappingConstants.ComponentModel.SPRING
19+
componentModel = MappingConstants.ComponentModel.SPRING,
20+
imports = CollectionLocationMasker.class
1921
)
2022
public interface CollectionWebMapper {
2123

@@ -58,6 +60,10 @@ public interface CollectionWebMapper {
5860
@Mapping(target = "commentCount", source = "commentCount")
5961
@Mapping(target = "isLiked", source = "isLiked")
6062
@Mapping(target = "isMine", source = "isMine")
63+
@Mapping(target = "latitude", expression = "java(CollectionLocationMasker.latitude(collection, isMine))")
64+
@Mapping(target = "longitude", expression = "java(CollectionLocationMasker.longitude(collection, isMine))")
65+
@Mapping(target = "locationAlias", expression = "java(CollectionLocationMasker.locationAlias(collection, isMine))")
66+
@Mapping(target = "address", expression = "java(CollectionLocationMasker.address(collection, isMine))")
6167
GetCollectionDetailResponse toGetCollectionDetailResponse(UserBirdCollection collection, String imageUrl, String userProfileImageUrl, String thumbnailProfileImageUrl, long likeCount, long commentCount, boolean isLiked, boolean isMine);
6268

6369
@Mapping(target = "collectionId", source = "collection.id")
@@ -71,7 +77,11 @@ public interface CollectionWebMapper {
7177
@Mapping(target = "user.nickname", source = "collection.user.nickname")
7278
@Mapping(target = "user.profileImageUrl", source = "userProfileImageUrl")
7379
@Mapping(target = "user.thumbnailProfileImageUrl", source = "thumbnailProfileImageUrl")
74-
GetNearbyCollectionsResponse.Item toGetNearbyCollectionsResponseItem(UserBirdCollection collection, String imageUrl, String thumbnailUrl, String userProfileImageUrl, String thumbnailProfileImageUrl, long likeCount, long commentCount, boolean isLiked);
80+
@Mapping(target = "latitude", expression = "java(CollectionLocationMasker.latitude(collection, isMine))")
81+
@Mapping(target = "longitude", expression = "java(CollectionLocationMasker.longitude(collection, isMine))")
82+
@Mapping(target = "locationAlias", expression = "java(CollectionLocationMasker.locationAlias(collection, isMine))")
83+
@Mapping(target = "address", expression = "java(CollectionLocationMasker.address(collection, isMine))")
84+
GetNearbyCollectionsResponse.Item toGetNearbyCollectionsResponseItem(UserBirdCollection collection, String imageUrl, String thumbnailUrl, String userProfileImageUrl, String thumbnailProfileImageUrl, long likeCount, long commentCount, boolean isLiked, boolean isMine);
7585

7686
@Named("getBirdId")
7787
default Long getBirdId(UserBirdCollection collection) {

src/main/java/org/devkor/apu/saerok_server/domain/community/application/CommunityDataAssembler.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,14 @@ public List<CommunityCollectionInfo> toCollectionInfos(List<UserBirdCollection>
6060
long commentCount = collectionCommentRepository.countByCollectionId(collection.getId());
6161
boolean isLiked = userId != null && collectionLikeRepository.existsByUserIdAndCollectionId(userId, collection.getId());
6262
boolean isPopular = popularStatusMap.getOrDefault(collection.getId(), false);
63+
boolean isMine = userId != null && userId.equals(collection.getUser().getId());
6364

6465
Long suggestionUserCount = collection.getBird() == null
6566
? suggestionUserCounts.getOrDefault(collection.getId(), 0L)
6667
: null;
6768

6869
return communityWebMapper.toCommunityCollectionInfo(
69-
collection, imageUrl, thumbnailImageUrl, userProfileImageUrl, thumbnailProfileImageUrl, likeCount, commentCount, isLiked, isPopular, suggestionUserCount
70+
collection, imageUrl, thumbnailImageUrl, userProfileImageUrl, thumbnailProfileImageUrl, likeCount, commentCount, isLiked, isPopular, suggestionUserCount, isMine
7071
);
7172
})
7273
.toList();

src/main/java/org/devkor/apu/saerok_server/domain/community/mapper/CommunityWebMapper.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.devkor.apu.saerok_server.domain.community.mapper;
22

33
import org.devkor.apu.saerok_server.domain.collection.core.entity.UserBirdCollection;
4+
import org.devkor.apu.saerok_server.domain.collection.core.service.CollectionLocationMasker;
45
import org.devkor.apu.saerok_server.domain.community.api.dto.common.CommunityCollectionInfo;
56
import org.devkor.apu.saerok_server.domain.community.api.dto.common.CommunityFreeBoardPostInfo;
67
import org.devkor.apu.saerok_server.domain.community.api.dto.common.CommunityUserInfo;
@@ -11,18 +12,18 @@
1112
import org.mapstruct.Mapping;
1213
import org.mapstruct.MappingConstants;
1314

14-
@Mapper(componentModel = MappingConstants.ComponentModel.SPRING, imports = OffsetDateTimeLocalizer.class)
15+
@Mapper(componentModel = MappingConstants.ComponentModel.SPRING, imports = {OffsetDateTimeLocalizer.class, CollectionLocationMasker.class})
1516
public interface CommunityWebMapper {
1617

1718
@Mapping(target = "collectionId", source = "collection.id")
1819
@Mapping(target = "imageUrl", source = "imageUrl")
1920
@Mapping(target = "thumbnailImageUrl", source = "thumbnailImageUrl")
2021
@Mapping(target = "discoveredDate", source = "collection.discoveredDate")
2122
@Mapping(target = "createdAt", expression = "java(OffsetDateTimeLocalizer.toSeoulLocalDateTime(collection.getCreatedAt()))")
22-
@Mapping(target = "latitude", source = "collection.latitude")
23-
@Mapping(target = "longitude", source = "collection.longitude")
24-
@Mapping(target = "locationAlias", source = "collection.locationAlias")
25-
@Mapping(target = "address", source = "collection.address")
23+
@Mapping(target = "latitude", expression = "java(CollectionLocationMasker.latitude(collection, isMine))")
24+
@Mapping(target = "longitude", expression = "java(CollectionLocationMasker.longitude(collection, isMine))")
25+
@Mapping(target = "locationAlias", expression = "java(CollectionLocationMasker.locationAlias(collection, isMine))")
26+
@Mapping(target = "address", expression = "java(CollectionLocationMasker.address(collection, isMine))")
2627
@Mapping(target = "note", source = "collection.note")
2728
@Mapping(target = "likeCount", source = "likeCount")
2829
@Mapping(target = "commentCount", source = "commentCount")
@@ -41,7 +42,8 @@ CommunityCollectionInfo toCommunityCollectionInfo(
4142
Long commentCount,
4243
Boolean isLiked,
4344
Boolean isPopular,
44-
Long suggestionUserCount
45+
Long suggestionUserCount,
46+
boolean isMine
4547
);
4648

4749
@Mapping(target = "userId", source = "user.id")

src/main/java/org/devkor/apu/saerok_server/domain/dex/bird/api/dto/response/BirdDetailResponse.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.devkor.apu.saerok_server.domain.dex.bird.api.dto.response;
22

33
import io.swagger.v3.oas.annotations.media.Schema;
4+
import org.devkor.apu.saerok_server.domain.dex.bird.core.enums.ConservationGrade;
45

56
import java.util.List;
67

@@ -15,6 +16,9 @@ public class BirdDetailResponse {
1516
@Schema(description = "학명", example = "Pica pica")
1617
public String scientificName;
1718

19+
@Schema(description = "보호등급", example = "NONE", allowableValues = {"NONE", "GRADE_I", "GRADE_II"})
20+
public ConservationGrade conservationGrade;
21+
1822
@Schema(description = "분류학적 정보")
1923
public BirdTaxonomy taxonomy;
2024

src/main/java/org/devkor/apu/saerok_server/domain/dex/bird/api/dto/response/BirdFullSyncResponse.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import io.swagger.v3.oas.annotations.media.Schema;
44
import lombok.Data;
5+
import org.devkor.apu.saerok_server.domain.dex.bird.core.enums.ConservationGrade;
56
import org.devkor.apu.saerok_server.domain.dex.bird.core.enums.HabitatType;
67

78
import java.time.OffsetDateTime;
@@ -36,6 +37,9 @@ public static class BirdProfileItem {
3637
@Schema(description = "NIBR URL", example = "http://nibr...")
3738
private String nibrUrl;
3839

40+
@Schema(description = "보호등급", example = "NONE", allowableValues = {"NONE", "GRADE_I", "GRADE_II"})
41+
private ConservationGrade conservationGrade;
42+
3943
@Schema(description = "서식지 목록")
4044
private List<HabitatType> habitats;
4145

src/main/java/org/devkor/apu/saerok_server/domain/dex/bird/api/dto/response/BirdSearchResponse.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import io.swagger.v3.oas.annotations.media.Schema;
44
import lombok.Data;
5+
import org.devkor.apu.saerok_server.domain.dex.bird.core.enums.ConservationGrade;
56

67
import java.util.List;
78

@@ -24,6 +25,9 @@ public static class BirdSearchItem {
2425
@Schema(description = "학명", example = "Pica pica")
2526
public String scientificName;
2627

28+
@Schema(description = "보호등급", example = "NONE", allowableValues = {"NONE", "GRADE_I", "GRADE_II"})
29+
public ConservationGrade conservationGrade;
30+
2731
@Schema(description = "썸네일 이미지 URL", example = "https://example.com/images/bird-thumb.jpg")
2832
public String thumbImageUrl;
2933
}

src/main/java/org/devkor/apu/saerok_server/domain/dex/bird/core/entity/Bird.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import jakarta.persistence.*;
44
import lombok.Getter;
55
import org.devkor.apu.saerok_server.domain.dex.bird.core.contract.HasBodyLength;
6+
import org.devkor.apu.saerok_server.domain.dex.bird.core.enums.ConservationGrade;
67
import org.devkor.apu.saerok_server.global.shared.entity.SoftDeletableAuditable;
78

89
import java.util.List;
@@ -31,6 +32,10 @@ public class Bird extends SoftDeletableAuditable implements HasBodyLength {
3132
@Column(name = "nibr_url")
3233
private String nibrUrl;
3334

35+
@Enumerated(EnumType.STRING)
36+
@Column(name = "conservation_grade", nullable = false)
37+
private ConservationGrade conservationGrade = ConservationGrade.NONE;
38+
3439
@OneToMany(mappedBy = "bird", cascade = CascadeType.ALL, orphanRemoval = true)
3540
private List<BirdImage> images;
3641

0 commit comments

Comments
 (0)