Skip to content

Commit

Permalink
[SPR-152] feat: 암장 데이터 추가 및 수정 기능 구현
Browse files Browse the repository at this point in the history
* [SPR-152] feat: 프로필 변경, 암장 서비스 변경기능 구현

* [SPR-152] feat: 암장 배경, 프로필 사진, 서비스 수정기능 구현

* [SPR-152] feat: 암장 약도, 가격표 데이터 추가 및 수정기능 구현

* [SPR-152] feat: SwaggerApiError 추가
  • Loading branch information
eple0329 authored Feb 16, 2024
1 parent 67deca4 commit 1185503
Show file tree
Hide file tree
Showing 7 changed files with 172 additions and 36 deletions.
2 changes: 1 addition & 1 deletion config
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ public class ClimbingGym extends BaseTimeEntity {

private String profileImageUrl;

public void updateProfileImageUrl(String profileImageUrl) {
this.profileImageUrl = profileImageUrl;
}

private Float AverageRating = 0.0F;

private Float sumRating = 0.0F;
Expand All @@ -51,15 +55,24 @@ public class ClimbingGym extends BaseTimeEntity {

private String address;

private String location;

@Column(columnDefinition = "json")
private String businessHours;

@Column(columnDefinition = "json")
private String priceList;

public void updateGymInfo(String tel, String address, String businessHours) {
this.tel = tel;
this.address = address;
this.businessHours = businessHours;
}

public void updateGymPriceList(String priceList) {
this.priceList = priceList;
}


public void reviewCreate(Float rating) {
this.sumRating += rating;
Expand Down Expand Up @@ -90,7 +103,7 @@ public void averageRatingCalculate() {

private int serviceBitMask = 0;

public void updateServiceBitMask(int value){
public void updateServiceBitMask(int value) {
this.serviceBitMask = value;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.climeet.climeet_backend.domain.climbinggym;

import com.climeet.climeet_backend.domain.climbinggym.dto.ClimbingGymRequestDto.UpdateClimbingGymInfoRequest;
import com.climeet.climeet_backend.domain.climbinggym.dto.ClimbingGymRequestDto.UpdateClimbingGymPriceRequest;
import com.climeet.climeet_backend.domain.climbinggym.dto.ClimbingGymRequestDto.UpdateClimbingGymServiceRequest;
import com.climeet.climeet_backend.domain.climbinggym.dto.ClimbingGymResponseDto.AcceptedClimbingGymSimpleResponse;
import com.climeet.climeet_backend.domain.climbinggym.dto.ClimbingGymResponseDto.AcceptedClimbingGymSimpleResponseWithFollow;
import com.climeet.climeet_backend.domain.climbinggym.dto.ClimbingGymResponseDto.ClimbingGymAverageLevelDetailResponse;
Expand All @@ -19,12 +20,15 @@
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
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.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

@Tag(name = "ClimbingGym", description = "암장 관련 API")
@RestController
Expand Down Expand Up @@ -60,7 +64,7 @@ public ResponseEntity<ClimbingGymDetailResponse> getClimbingGymInfo(
}


@Operation(summary = "암장 프로필 정보 (탭) 불러오기")
@Operation(summary = "암장 프로필 정보 (탭) 불러오기", description = "탭에 들어가는 데이터는 null이 존재할 가능성이 상당히 높습니다.\n 또한 영업시간에서 특정 요일만 값이 없다면 정기휴일입니다.")
@SwaggerApiError({ErrorStatus._EMPTY_CLIMBING_GYM, ErrorStatus._ERROR_JSON_PARSE})
@GetMapping("/{gymId}/tab")
public ResponseEntity<ClimbingGymTabInfoResponse> getClimbingGymTabInfo(
Expand All @@ -69,23 +73,58 @@ public ResponseEntity<ClimbingGymTabInfoResponse> getClimbingGymTabInfo(
}

@Operation(summary = "암장 크롤링 정보 입력")
@PostMapping("/info")
@PostMapping("/{gymId}/info")
public ResponseEntity<ClimbingGymInfoResponse> updateClimbingGymInfo(
@RequestBody UpdateClimbingGymInfoRequest updateClimbingGymInfoRequest) {
@PathVariable Long gymId) {
return ResponseEntity.ok(
climbingGymService.updateClimbingGymInfo(updateClimbingGymInfoRequest));
climbingGymService.updateClimbingGymInfo(gymId));
}

@Operation(summary = "암장 실력분포 조회")
@SwaggerApiError({ErrorStatus._EMPTY_CLIMBING_GYM, ErrorStatus._EMPTY_AVERAGE_LEVEL_DATA})
@GetMapping("/{gymId}/graph/level")
@GetMapping("/{gymId}/skill-distribution")
public ResponseEntity<List<ClimbingGymAverageLevelDetailResponse>> getFollowingUserAverageLevelInClimbingGym(
@PathVariable Long gymId, @CurrentUser User user) {
return ResponseEntity.ok(
climbingGymService.getFollowingUserAverageLevelInClimbingGym(gymId));
}

@Operation(summary = "암장 배경사진 변경 (1개만 등록 가능)")
@SwaggerApiError({ErrorStatus._EMPTY_MANAGER, ErrorStatus._EMPTY_BACKGROUND_IMAGE})
@PatchMapping("/background-image")
public ResponseEntity<String> changeClimbingGymBackgroundImage(@CurrentUser User user,
@RequestPart MultipartFile image) {
return ResponseEntity.ok(climbingGymService.changeClimbingGymBackgroundImage(user, image));
}

@Operation(summary = "암장 프로필 이미지 변경 (1개만 등록 가능)")
@SwaggerApiError({ErrorStatus._EMPTY_MANAGER})
@PatchMapping("/profile-image")
public ResponseEntity<String> changeClimbingGymProfileImage(@CurrentUser User user,
@RequestPart MultipartFile image) {
return ResponseEntity.ok(climbingGymService.changeClimbingGymProfileImage(user, image));
}

@Operation(summary = "암장 제공 서비스 수정", description = "**Enum 설명**\n\n**ServiceBitmask** : 샤워\\_시설, 샤워\\_용품, 수건\\_제공, 간이\\_세면대, 초크\\_대여, 암벽화\\_대여, 삼각대\\_대여, 운동복\\_대여")
@SwaggerApiError({ErrorStatus._EMPTY_MANAGER})
@PatchMapping("/service")
public ResponseEntity<String> updateClimbingGymService(@CurrentUser User user,
@RequestBody UpdateClimbingGymServiceRequest updateClimbingGymServiceRequest) {
climbingGymService.updateClimbingGymService(user, updateClimbingGymServiceRequest);
return ResponseEntity.ok("암장 제공 서비스를 정상적으로 변경했습니다.");
}

@Operation(summary = "기본 가격(제공) 추가 & 수정")
@SwaggerApiError({ErrorStatus._EMPTY_MANAGER, ErrorStatus._ERROR_JSON_PARSE})
@PostMapping("/price")
public ResponseEntity<String> updateClimbingGymPrice(@CurrentUser User user,
@RequestBody UpdateClimbingGymPriceRequest updateClimbingGymPriceRequest) {
climbingGymService.updateClimbingGymPrice(user, updateClimbingGymPriceRequest);
return ResponseEntity.ok("암장 기본 제공을 정상적으로 변경했습니다.");
}

@Operation(summary = "Manager가 등록된 암장 검색 기능 + 팔로잉 여부")
@SwaggerApiError({})
@GetMapping("/search/follow")
public ResponseEntity<PageResponseDto<List<AcceptedClimbingGymSimpleResponseWithFollow>>> getAcceptedClimbingGymSearchingListWithFollow(
@RequestParam("gymname") String gymName, @RequestParam int page, @RequestParam int size,
Expand All @@ -95,5 +134,4 @@ public ResponseEntity<PageResponseDto<List<AcceptedClimbingGymSimpleResponseWith
climbingGymService.searchAcceptedClimbingGymWithFollow(gymName, page, size, user));
}


}
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.climeet.climeet_backend.domain.climbinggym;

import com.climeet.climeet_backend.domain.climbinggym.dto.ClimbingGymRequestDto.UpdateClimbingGymPriceRequest;
import com.climeet.climeet_backend.domain.climbinggym.dto.ClimbingGymRequestDto.UpdateClimbingGymServiceRequest;

import static com.climeet.climeet_backend.domain.climbinggym.BitmaskConverter.convertBitmaskToServiceList;

import com.climeet.climeet_backend.domain.climbinggym.dto.ClimbingGymRequestDto.UpdateClimbingGymInfoRequest;
import com.climeet.climeet_backend.domain.climbinggym.dto.ClimbingGymResponseDto.AcceptedClimbingGymSimpleResponse;
import com.climeet.climeet_backend.domain.climbinggym.dto.ClimbingGymResponseDto.AcceptedClimbingGymSimpleResponseWithFollow;
import com.climeet.climeet_backend.domain.climbinggym.dto.ClimbingGymResponseDto.ClimbingGymAverageLevelDetailResponse;
Expand All @@ -24,6 +26,8 @@
import com.climeet.climeet_backend.global.common.PageResponseDto;
import com.climeet.climeet_backend.global.response.code.status.ErrorStatus;
import com.climeet.climeet_backend.global.response.exception.GeneralException;
import com.climeet.climeet_backend.global.s3.S3Service;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
Expand All @@ -38,6 +42,7 @@
import org.springframework.data.domain.Slice;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClient;
import org.springframework.web.multipart.MultipartFile;

@RequiredArgsConstructor
@Service
Expand All @@ -49,6 +54,8 @@ public class ClimbingGymService {
private final FollowRelationshipRepository followRelationshipRepository;
private final RouteRecordRepository routeRecordRepository;
private final DifficultyMappingRepository difficultyMappingRepository;
private final S3Service s3Service;
private final BitmaskConverter bitmaskConverter;

@Value("${cloud.aws.lambda.crawling-uri}")
private String crawlingUri;
Expand Down Expand Up @@ -129,19 +136,20 @@ public ClimbingGymTabInfoResponse getClimbingGymTabInfo(Long gymId) {
climbingGym.getBusinessHours(),
new TypeReference<Map<String, List<String>>>() {
});
Map<String, String> priceList = objectMapper.readValue(
climbingGym.getPriceList(),
new TypeReference<Map<String, String>>() {
});
return ClimbingGymTabInfoResponse.toDTO(climbingGymRepository.save(climbingGym),
businessHoursMap, serviceList);
businessHoursMap, serviceList, priceList);
} catch (Exception e) {
throw new GeneralException(ErrorStatus._ERROR_JSON_PARSE);
}
}


public ClimbingGymInfoResponse updateClimbingGymInfo(

UpdateClimbingGymInfoRequest updateClimbingGymInfoRequest) {
ClimbingGym climbingGym = climbingGymRepository.findById(
updateClimbingGymInfoRequest.getGymId())
public ClimbingGymInfoResponse updateClimbingGymInfo(Long gymId) {
ClimbingGym climbingGym = climbingGymRepository.findById(gymId)
.orElseThrow(() -> new GeneralException(ErrorStatus._EMPTY_CLIMBING_GYM));

RestClient restClient = RestClient.create();
Expand Down Expand Up @@ -205,23 +213,55 @@ public List<ClimbingGymAverageLevelDetailResponse> getFollowingUserAverageLevelI
.toList();
}

private DifficultyMapping getClosestGymDifficulty(Integer level,
List<DifficultyMapping> difficultyMappingList) {
DifficultyMapping difficulty = null;
int minDifference = Integer.MAX_VALUE;
int closestDifficulty = Integer.MAX_VALUE;
public String changeClimbingGymBackgroundImage(User user, MultipartFile image) {
Manager manager = managerRepository.findById(user.getId())
.orElseThrow(() -> new GeneralException(ErrorStatus._EMPTY_MANAGER));

for (DifficultyMapping mapping : difficultyMappingList) {
int difference = Math.abs(level - mapping.getDifficulty());
if (difference < minDifference || (difference == minDifference
&& mapping.getDifficulty() < closestDifficulty)) {
minDifference = difference;
closestDifficulty = mapping.getDifficulty();
difficulty = mapping;
}
}
ClimbingGymBackgroundImage climbingGymBackgroundImage = climbingGymBackgroundImageRepository.findByClimbingGym(
manager.getClimbingGym())
.orElseThrow(() -> new GeneralException(ErrorStatus._EMPTY_BACKGROUND_IMAGE));

return difficulty;
String backgroundImageUrl = s3Service.uploadFile(image).getImgUrl();
climbingGymBackgroundImage.changeImgUrl(backgroundImageUrl);
climbingGymBackgroundImageRepository.save(climbingGymBackgroundImage);

return backgroundImageUrl;
}

public String changeClimbingGymProfileImage(User user, MultipartFile image) {
Manager manager = managerRepository.findById(user.getId())
.orElseThrow(() -> new GeneralException(ErrorStatus._EMPTY_MANAGER));
ClimbingGym climbingGym = manager.getClimbingGym();
String profileImageUrl = s3Service.uploadFile(image).getImgUrl();
climbingGym.updateProfileImageUrl(profileImageUrl);
climbingGymRepository.save(climbingGym);
return profileImageUrl;
}

public void updateClimbingGymService(User user,
UpdateClimbingGymServiceRequest updateClimbingGymServiceRequest) {
Manager manager = managerRepository.findById(user.getId())
.orElseThrow(() -> new GeneralException(ErrorStatus._EMPTY_MANAGER));
ClimbingGym climbingGym = manager.getClimbingGym();
climbingGym.updateServiceBitMask(bitmaskConverter.convertServiceListToBitmask(
updateClimbingGymServiceRequest.getServiceList()));
climbingGymRepository.save(climbingGym);
}

public void updateClimbingGymPrice(User user,
UpdateClimbingGymPriceRequest updateClimbingGymPriceRequest) {
Manager manager = managerRepository.findById(user.getId())
.orElseThrow(() -> new GeneralException(ErrorStatus._EMPTY_MANAGER));
ClimbingGym climbingGym = manager.getClimbingGym();

ObjectMapper objectMapper = new ObjectMapper();
try {
climbingGym.updateGymPriceList(objectMapper.writeValueAsString(
updateClimbingGymPriceRequest.getPriceMapList()));
climbingGymRepository.save(climbingGym);
} catch (Exception e) {
throw new GeneralException(ErrorStatus._ERROR_JSON_PARSE);
}
}

public PageResponseDto<List<AcceptedClimbingGymSimpleResponseWithFollow>> searchAcceptedClimbingGymWithFollow(
Expand Down Expand Up @@ -265,4 +305,23 @@ public PageResponseDto<List<AcceptedClimbingGymSimpleResponseWithFollow>> search

}

private DifficultyMapping getClosestGymDifficulty(Integer level,
List<DifficultyMapping> difficultyMappingList) {
DifficultyMapping difficulty = null;
int minDifference = Integer.MAX_VALUE;
int closestDifficulty = Integer.MAX_VALUE;

for (DifficultyMapping mapping : difficultyMappingList) {
int difference = Math.abs(level - mapping.getDifficulty());
if (difference < minDifference || (difference == minDifference
&& mapping.getDifficulty() < closestDifficulty)) {
minDifference = difference;
closestDifficulty = mapping.getDifficulty();
difficulty = mapping;
}
}

return difficulty;
}

}
Original file line number Diff line number Diff line change
@@ -1,14 +1,26 @@
package com.climeet.climeet_backend.domain.climbinggym.dto;

import com.climeet.climeet_backend.domain.climbinggym.enums.ServiceBitmask;
import java.util.List;
import java.util.Map;
import lombok.Getter;
import lombok.NoArgsConstructor;

public class ClimbingGymRequestDto {

@Getter
@NoArgsConstructor
public static class UpdateClimbingGymInfoRequest {
private Long gymId;
public static class UpdateClimbingGymServiceRequest {

private List<ServiceBitmask> serviceList;

}

@Getter
@NoArgsConstructor
public static class UpdateClimbingGymPriceRequest {

private Map<String, String> priceMapList;
}

}
Loading

0 comments on commit 1185503

Please sign in to comment.