Skip to content

Commit 07912c6

Browse files
authored
Merge pull request #88 from swyp-app-team-4/feat#61-search-api
Feat#61 API 오류 개선
2 parents ff9e99c + fa22692 commit 07912c6

5 files changed

Lines changed: 78 additions & 79 deletions

File tree

src/main/java/boombimapi/domain/member/presentation/controller/AdminController.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public ResponseEntity<LoginToken> adminLogin(@Valid @RequestBody AdminLoginReq r
4545
}
4646

4747

48-
@PostMapping("/join")
48+
//@PostMapping("/join")
4949
public void adminJoin(@Valid @RequestBody AdminLoginReq req) {
5050
Member admin = Member.builder()
5151
.id(UUID.randomUUID().toString())

src/main/java/boombimapi/domain/search/application/impl/SearchServiceImpl.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,6 @@ private List<SearchRes> sortedCongestion(List<MemberPlace> memberPlaceEntities,
181181
if (latestMember != null) {
182182
result.add(SearchRes.of(memberPlace.getId(), memberPlace.getName(), latestMember.getCreatedAt(),
183183
latestMember.getCongestionLevel().getName(), memberPlace.getAddress(), memberPlace.getImageUrl(), PlaceType.MEMBER_PLACE, favoriteFlag));
184-
}else{
185-
result.add(SearchRes.of(memberPlace.getId(), memberPlace.getName(), memberPlace.getCreatedAt(),
186-
"여유", memberPlace.getAddress(), memberPlace.getImageUrl(), PlaceType.MEMBER_PLACE, favoriteFlag));
187184
}
188185
}
189186

src/main/java/boombimapi/domain/vote/application/service/impl/VoteServiceImpl.java

Lines changed: 74 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -70,16 +70,18 @@ public class VoteServiceImpl implements VoteService {
7070
@Transactional(noRollbackFor = BoombimException.class)
7171
public void registerVote(String userId, VoteRegisterReq req) {
7272
Member user = userRepository.findById(userId).orElse(null);
73-
if (user == null)
74-
throw new BoombimException(ErrorCode.USER_NOT_EXIST);
73+
if (user == null) throw new BoombimException(ErrorCode.USER_NOT_EXIST);
74+
75+
//위도 경도 100m 맞는지 true면 있음 false면 없음 ==> 이제부터 300m로 통일 == > 이거 기능 날라감 ㅜㅜㅜ
76+
/**
77+
* boolean result = isWithin300Meters(
78+
* req.posLatitude(), req.posLongitude(),
79+
* req.userLatitude(), req.userLongitude()
80+
* );
81+
* if (!result) throw new BoombimException(ErrorCode.OUT_OF_300M_RADIUS);
82+
*
83+
* */
7584

76-
//위도 경도 100m 맞는지 true면 있음 false면 없음 ==> 이제부터 300m로 통일
77-
boolean result = isWithin300Meters(
78-
req.posLatitude(), req.posLongitude(),
79-
req.userLatitude(), req.userLongitude()
80-
);
81-
if (!result)
82-
throw new BoombimException(ErrorCode.OUT_OF_300M_RADIUS);
8385

8486
// 중복 검사인지 확인
8587
Vote vote = voteRepository.findByPosIdAndIsVoteActivateTrue(req.posId()).orElse(null);
@@ -105,32 +107,32 @@ public void registerVote(String userId, VoteRegisterReq req) {
105107
throw new BoombimException(ErrorCode.DUPLICATE_POS_ID);
106108
}
107109

108-
String posImage = getPosImage(req.posName());
110+
// String posImage = getPosImage(req.posName());
109111

110-
log.info(posImage);
112+
String posImage = "https://gamehackspring.s3.ap-northeast-2.amazonaws.com/appicon.png";
111113

112114
// 공식 장소 테이블 추가
113115
ResolveMemberPlaceResponse resolveMemberPlaceResponse =
114-
memberPlaceService
115-
.resolveMemberPlace(
116-
ResolveMemberPlaceRequest.of(
117-
req.posId(),
118-
req.posName(),
119-
req.address(),
120-
req.posLatitude(),
121-
req.posLongitude(),
122-
posImage));
116+
memberPlaceService
117+
.resolveMemberPlace(
118+
ResolveMemberPlaceRequest.of(
119+
req.posId(),
120+
req.posName(),
121+
req.address(),
122+
req.posLatitude(),
123+
req.posLongitude(),
124+
posImage));
123125
MemberPlace memberPlace = memberPlaceRepository.findById(resolveMemberPlaceResponse.memberPlaceId())
124-
.orElseThrow(() -> new BoombimException(MEMBER_PLACE_NOT_FOUND));
126+
.orElseThrow(() -> new BoombimException(MEMBER_PLACE_NOT_FOUND));
125127

126128
Vote vb = Vote.builder()
127-
.member(user)
128-
.memberPlace(memberPlace)
129-
.posId(req.posId())
130-
.posImage(posImage)
131-
.posName(req.posName())
132-
.latitude(req.posLatitude())
133-
.longitude(req.posLongitude()).build();
129+
.member(user)
130+
.memberPlace(memberPlace)
131+
.posId(req.posId())
132+
.posImage(posImage)
133+
.posName(req.posName())
134+
.latitude(req.posLatitude())
135+
.longitude(req.posLongitude()).build();
134136
voteRepository.save(vb);
135137

136138
vb.updateEndTime(30);
@@ -146,28 +148,26 @@ public void registerVote(String userId, VoteRegisterReq req) {
146148
@Override
147149
public void answerVote(String userId, VoteAnswerReq req) {
148150
Member user = userRepository.findById(userId).orElse(null);
149-
if (user == null)
150-
throw new BoombimException(ErrorCode.USER_NOT_EXIST);
151+
if (user == null) throw new BoombimException(ErrorCode.USER_NOT_EXIST);
151152

152153
Vote vote = voteRepository.findById(req.voteId()).orElse(null);
153-
if (vote == null)
154-
throw new BoombimException(ErrorCode.VOTE_NOT_EXIST);
154+
if (vote == null) throw new BoombimException(ErrorCode.VOTE_NOT_EXIST);
155155

156156
// 투표 종료됐는데 투표할려고 할때
157-
if (!vote.isVoteActivate())
158-
throw new BoombimException(ErrorCode.VOTE_ALREADY_CLOSED);
157+
if (!vote.isVoteActivate()) throw new BoombimException(ErrorCode.VOTE_ALREADY_CLOSED);
158+
159+
// 본인 투표 막기 즉 본인이 올린거 투표 못하게 해야됨
160+
if(vote.getMember().getId().equals(user.getId())) throw new BoombimException(ErrorCode.SELF_VOTE_NOT_ALLOWED);
159161

160162
// 같은 투표 중복자 막기
161163
VoteAnswer voteAnswer = voteAnswerRepository.findByMemberAndVote(user, vote).orElse(null);
162-
if (voteAnswer != null)
163-
throw new BoombimException(ErrorCode.DUPLICATE_VOTE_USER);
164+
if (voteAnswer != null) throw new BoombimException(ErrorCode.DUPLICATE_VOTE_USER);
164165

165-
log.info(String.valueOf(req.voteAnswerType()));
166166
// 투표 완료
167167
voteAnswerRepository.save(VoteAnswer.builder()
168-
.member(user)
169-
.vote(vote)
170-
.answerType(req.voteAnswerType()).build());
168+
.member(user)
169+
.vote(vote)
170+
.answerType(req.voteAnswerType()).build());
171171

172172
// =======
173173
// 여기서 혼잡도 정보한테도 넘겨야됨
@@ -229,9 +229,9 @@ private List<VoteRes> voteList(Member user, double latitude, double longitude) {
229229
boolean voteFlag = voteUsercheck(vote, user);
230230

231231
voteResList.add(
232-
VoteRes.of(vote.getId(), profileTopThree(vote), (long) vote.getVoteDuplications().size(), vote.getCreatedAt(), vote.getPosName(),
233-
vote.getPosImage(),
234-
voteAnswer.get(0), voteAnswer.get(1), voteAnswer.get(2), voteAnswer.get(3), "투표하기", voteFlag));
232+
VoteRes.of(vote.getId(), profileTopThree(vote), (long) vote.getVoteDuplications().size(), vote.getCreatedAt(), vote.getPosName(),
233+
vote.getPosImage(),
234+
voteAnswer.get(0), voteAnswer.get(1), voteAnswer.get(2), voteAnswer.get(3), "투표하기", voteFlag));
235235
}
236236

237237
return voteResList;
@@ -246,9 +246,9 @@ private List<MyVoteRes> myVoteList(Member user) {
246246
List<Long> voteAnswer = voteAnswerCnt(vote);
247247
boolean voteFlag = voteUsercheck(vote, user);
248248
myVoteRes.add(
249-
MyVoteRes.of(vote.getId(), profileTopThree(vote), (long) vote.getVoteDuplications().size(), vote.getCreatedAt(), vote.getPosName(),
250-
voteAnswer.get(0), voteAnswer.get(1), voteAnswer.get(2), voteAnswer.get(3),
251-
"내 질문", vote.getVoteStatus(), voteFlag));
249+
MyVoteRes.of(vote.getId(), profileTopThree(vote), (long) vote.getVoteDuplications().size(), vote.getCreatedAt(), vote.getPosName(),
250+
voteAnswer.get(0), voteAnswer.get(1), voteAnswer.get(2), voteAnswer.get(3),
251+
"내 질문", vote.getVoteStatus(), voteFlag));
252252
}
253253

254254
/// 투표 중복꺼 가져오기 즉 중속
@@ -261,16 +261,16 @@ private List<MyVoteRes> myVoteList(Member user) {
261261
List<Long> voteAnswer = voteAnswerCnt(vote);
262262
boolean voteFlag = voteUsercheck(vote, user);
263263
myVoteRes.add(
264-
MyVoteRes.of(vote.getId(), profileTopThree(vote), (long) vote.getVoteDuplications().size(), vote.getCreatedAt(), vote.getPosName(),
265-
voteAnswer.get(0), voteAnswer.get(1), voteAnswer.get(2), voteAnswer.get(3), "내 질문", vote.getVoteStatus(), voteFlag));
264+
MyVoteRes.of(vote.getId(), profileTopThree(vote), (long) vote.getVoteDuplications().size(), vote.getCreatedAt(), vote.getPosName(),
265+
voteAnswer.get(0), voteAnswer.get(1), voteAnswer.get(2), voteAnswer.get(3), "내 질문", vote.getVoteStatus(), voteFlag));
266266
}
267267

268268
return myVoteRes;
269269
}
270270

271271
// 허버사인 공식 500m 반경 파악
272272
public boolean isWithin300Meters(double posLatitude, double posLongitude,
273-
double userLatitude, double userLongitude) {
273+
double userLatitude, double userLongitude) {
274274

275275
final double EARTH_RADIUS = 6371000; // 지구 반지름 (m)
276276

@@ -280,8 +280,8 @@ public boolean isWithin300Meters(double posLatitude, double posLongitude,
280280

281281
// Haversine 공식
282282
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
283-
Math.cos(Math.toRadians(posLatitude)) * Math.cos(Math.toRadians(userLatitude)) *
284-
Math.sin(dLon / 2) * Math.sin(dLon / 2);
283+
Math.cos(Math.toRadians(posLatitude)) * Math.cos(Math.toRadians(userLatitude)) *
284+
Math.sin(dLon / 2) * Math.sin(dLon / 2);
285285

286286
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
287287

@@ -294,7 +294,7 @@ public boolean isWithin300Meters(double posLatitude, double posLongitude,
294294
public List<Long> voteAnswerCnt(Vote vote) {
295295
List<VoteAnswer> voteAnswer = voteAnswerRepository.findByVote(vote);
296296
Map<VoteAnswerType, Long> counts = voteAnswer.stream()
297-
.collect(Collectors.groupingBy(VoteAnswer::getAnswerType, Collectors.counting()));
297+
.collect(Collectors.groupingBy(VoteAnswer::getAnswerType, Collectors.counting()));
298298

299299
long relaxedCount = counts.getOrDefault(VoteAnswerType.RELAXED, 0L);
300300
long commonlyCount = counts.getOrDefault(VoteAnswerType.COMMONLY, 0L);
@@ -328,9 +328,9 @@ private List<Vote> calculate300(double latitude, double longitude) {
328328

329329
// 3) 하버사인으로 500m 이내만 남기고, 거리 기준 정렬
330330
List<Vote> within300m = candidates.stream()
331-
.filter(v -> distanceMeters(latitude, longitude, v.getLatitude(), v.getLongitude()) <= RADIUS_M)
332-
.sorted(Comparator.comparingDouble(v -> distanceMeters(latitude, longitude, v.getLatitude(), v.getLongitude())))
333-
.toList();
331+
.filter(v -> distanceMeters(latitude, longitude, v.getLatitude(), v.getLongitude()) <= RADIUS_M)
332+
.sorted(Comparator.comparingDouble(v -> distanceMeters(latitude, longitude, v.getLatitude(), v.getLongitude())))
333+
.toList();
334334

335335
return within300m;
336336
}
@@ -341,8 +341,8 @@ private static double distanceMeters(double lat1, double lon1, double lat2, doub
341341
double dLat = Math.toRadians(lat2 - lat1);
342342
double dLon = Math.toRadians(lon2 - lon1);
343343
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
344-
+ Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2))
345-
* Math.sin(dLon / 2) * Math.sin(dLon / 2);
344+
+ Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2))
345+
* Math.sin(dLon / 2) * Math.sin(dLon / 2);
346346
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
347347
return R * c;
348348
}
@@ -363,21 +363,21 @@ private boolean voteUsercheck(Vote vote, Member user) {
363363
// 상위 3건 유저 프로필 이미지 링크
364364
public List<String> profileTopThree(Vote vote) {
365365
return vote.getVoteAnswers().stream()
366-
.map(voteAnswer -> voteAnswer.getMember().getProfile()) // Member의 프로필 URL 추출
367-
.filter(Objects::nonNull) // null 값 제거 (안전)
368-
.limit(3) // 최대 3개만
369-
.toList();
366+
.map(voteAnswer -> voteAnswer.getMember().getProfile()) // Member의 프로필 URL 추출
367+
.filter(Objects::nonNull) // null 값 제거 (안전)
368+
.limit(3) // 최대 3개만
369+
.toList();
370370
}
371371

372372
private String getPosImage(String posName) {
373373
try {
374374
// 네이버 이미지 검색 API 호출
375375
NaverImageSearchRes response = naverImageClient.searchImages(
376-
posName + " 전경", // 검색어 보정 (예: "부평남초등학교 전경")
377-
10, // 여러 개 가져오기
378-
1,
379-
"sim", // 정확도순
380-
"large" // 큰 이미지 우선
376+
posName + " 전경", // 검색어 보정 (예: "부평남초등학교 전경")
377+
10, // 여러 개 가져오기
378+
1,
379+
"sim", // 정확도순
380+
"large" // 큰 이미지 우선
381381
);
382382

383383
if (response.items() == null || response.items().isEmpty()) {
@@ -387,13 +387,13 @@ private String getPosImage(String posName) {
387387

388388
// 후보 중에서 "급식/식단/메뉴" 같은 거 제외하고 첫 번째 반환
389389
return response.items().stream()
390-
.filter(item -> !item.title().contains("급식"))
391-
.filter(item -> !item.title().contains("식단"))
392-
.filter(item -> !item.title().contains("메뉴"))
393-
.filter(item -> !item.title().contains("사람"))
394-
.findFirst()
395-
.map(NaverImageSearchRes.Item::link) // DTO 맞게 수정
396-
.orElse(response.items().get(0).link());
390+
.filter(item -> !item.title().contains("급식"))
391+
.filter(item -> !item.title().contains("식단"))
392+
.filter(item -> !item.title().contains("메뉴"))
393+
.filter(item -> !item.title().contains("사람"))
394+
.findFirst()
395+
.map(NaverImageSearchRes.Item::link) // DTO 맞게 수정
396+
.orElse(response.items().get(0).link());
397397

398398
} catch (FeignException e) {
399399
log.error("❌ 네이버 이미지 API 호출 실패: {}", e.getMessage(), e);
@@ -410,7 +410,7 @@ private void createCongestion(Vote vote, VoteAnswerType answerType, String userI
410410
throw new BoombimException(ErrorCode.CONGESTION_LEVEL_NOT_FOUND);
411411

412412
memberCongestionService.createMemberCongestion(userId,
413-
CreateMemberCongestionRequest.of(vote.getMemberPlace().getId(), congestionLevel.getId(), "", vote.getLatitude(), vote.getLongitude()));
413+
CreateMemberCongestionRequest.of(vote.getMemberPlace().getId(), congestionLevel.getId(), "", vote.getLatitude(), vote.getLongitude()));
414414
}
415415

416416

src/main/java/boombimapi/global/infra/exception/error/ErrorCode.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ public enum ErrorCode {
7272
DUPLICATE_VOTE_USER(-504, "이미 투표했습니다.", 409),
7373
NO_PERMISSION_TO_CLOSE_VOTE(-505, "투표 종료 권한이 없습니다.", 403),
7474
VOTE_ALREADY_CLOSED(-506, "종료된 투표입니다.", 400),
75+
SELF_VOTE_NOT_ALLOWED(-507, "본인이 생성한 투표에는 참여할 수 없습니다.", 409),
76+
7577

7678
// member place & member congestion
7779
MEMBER_PLACE_NOT_FOUND(-600, "해당 장소가 등록되지 않았습니다.", 406),

src/main/resources/application-prod.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ spring:
1212
password: ${DB_PASSWORD}
1313
jpa:
1414
hibernate:
15-
ddl-auto: create
15+
ddl-auto: none
1616
properties:
1717
hibernate:
1818
default_schema: root # 기본 스키마

0 commit comments

Comments
 (0)