Skip to content

Commit

Permalink
Merge pull request #108 from UMC-TripPiece/91-map-color-and-edit
Browse files Browse the repository at this point in the history
feat: Add HEX color handling and map-related updates
  • Loading branch information
StoneCAU authored Jan 9, 2025
2 parents 7e32e9e + 9fdb510 commit f0d0cde
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 84 deletions.
16 changes: 9 additions & 7 deletions src/main/java/umc/TripPiece/converter/MapConverter.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ public class MapConverter {
// MapRequestDto -> Map 변환
public static Map toMap(MapRequestDto requestDto, City city) {
return new Map(
null, // visitId는 자동 생성됨
null,
requestDto.getUserId(),
requestDto.getCountryCode(),
requestDto.getColor(),
Collections.emptyList(), // 초기 colors 리스트를 빈 리스트로 설정
city // City 필드 추가
requestDto.getColor(), // String 값 그대로 설정
Collections.emptyList(),
city
);
}

Expand All @@ -28,7 +28,7 @@ public static MapResponseDto toMapResponseDto(Map map) {
map.getVisitId(),
map.getUserId(),
map.getCountryCode(),
map.getColor()
map.getColor() // String 값 반환
);
}

Expand All @@ -42,7 +42,9 @@ public static MapResponseDto.getMarkerResponse toMarkerResponseDto(Map map, Stri
.cityName(cityName)
.build();
}
public static MapResponseDto.searchDto toSearchDto(City city){

// 도시 정보를 검색 DTO로 변환
public static MapResponseDto.searchDto toSearchDto(City city) {
return new MapResponseDto.searchDto(
city.getName(),
city.getCountry().getName(),
Expand All @@ -52,4 +54,4 @@ public static MapResponseDto.searchDto toSearchDto(City city){
city.getId()
);
}
}
}
13 changes: 4 additions & 9 deletions src/main/java/umc/TripPiece/domain/Map.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import umc.TripPiece.domain.enums.Color;

import java.util.ArrayList;
import java.util.List;
Expand All @@ -30,18 +29,14 @@ public class Map {
@Column(name = "country_code", nullable = false)
private String countryCode;

@Enumerated(EnumType.STRING)
@Column(name = "color")
private Color color; // 단일 색상
private String color; // 변경: String 타입으로 수정하여 요청된 hex 값을 저장 가능

// 여러 색상을 위한 필드 추가
@ElementCollection(targetClass = Color.class)
@ElementCollection
@CollectionTable(name = "map_colors", joinColumns = @JoinColumn(name = "map_id"))
@Column(name = "color")
@Enumerated(EnumType.STRING)
private List<Color> colors = new ArrayList<>(); // 다중 색상
@Column(name = "colors")
private List<String> colors = new ArrayList<>(); // 다중 색상 처리

// City와 연관 관계 추가
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "city_id", nullable = false)
private City city;
Expand Down
15 changes: 10 additions & 5 deletions src/main/java/umc/TripPiece/domain/enums/Color.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ public enum Color {
CYAN("25CEC1"),
RED("FD2D69");

private String code;
private final String code;
private static final Map<String, Color> BY_CODE = new HashMap<>();

static {
for (Color c : values()) {
BY_CODE.put(c.code, c);
BY_CODE.put(c.code.toUpperCase(), c); // 대소문자 구분 없도록 처리
}
}

Expand All @@ -26,11 +26,16 @@ public String getCode() {
return code;
}

public static Color fromString(String code) {
Color color = BY_CODE.get(code);
public static Color fromHex(String hexCode) {
if (hexCode == null || hexCode.isBlank()) {
throw new IllegalArgumentException("Color code cannot be null or empty.");
}

Color color = BY_CODE.get(hexCode.toUpperCase());
if (color == null) {
throw new IllegalArgumentException("Unknown color code: " + code);
throw new IllegalArgumentException("Unknown color code: " + hexCode);
}

return color;
}
}
115 changes: 59 additions & 56 deletions src/main/java/umc/TripPiece/service/MapService.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,114 +29,117 @@ public class MapService {
private final MapRepository mapRepository;
private final CityRepository cityRepository;
private final JWTUtil jwtUtil;
private final TravelRepository travelRepository;
private final UserRepository userRepository;
private final CountryRepository countryRepository;

// 유저별 맵 리스트를 조회하는 메소드
// 유저별 맵 리스트를 조회
public List<MapResponseDto> getMapsByUserId(Long userId) {
return mapRepository.findByUserId(userId).stream()
.map(MapConverter::toMapResponseDto)
.collect(Collectors.toList());
}

// 맵 생성 시 선택한 도시 정보도 함께 저장하는 메소드
// 맵 생성 시 도시 정보 포함
@Transactional
public MapResponseDto createMapWithCity(MapRequestDto requestDto) {
City city = cityRepository.findById(requestDto.getCityId()).orElseThrow(() ->
new IllegalArgumentException("City not found with id: " + requestDto.getCityId()));
City city = cityRepository.findById(requestDto.getCityId())
.orElseThrow(() -> new IllegalArgumentException("City not found with id: " + requestDto.getCityId()));

Map map = MapConverter.toMap(requestDto, city);
Map savedMap = mapRepository.save(map);
return MapConverter.toMapResponseDto(savedMap);
}

// 유저별 방문한 나라와 도시 통계를 반환하는 메소드
public MapStatsResponseDto getMapStatsByUserId(Long userId) {
long countryCount = mapRepository.countDistinctCountryCodeByUserId(userId);
long cityCount = mapRepository.countDistinctCityByUserId(userId);

List<String> countryCodes = mapRepository.findDistinctCountryCodesByUserId(userId);
List<Long> cityIds = mapRepository.findDistinctCityIdsByUserId(userId);

User user = userRepository.findById(userId).orElseThrow(() -> new IllegalArgumentException("User not found"));
String profileImg = user.getProfileImg();
String nickname = user.getNickname();

return new MapStatsResponseDto(countryCount, cityCount, countryCodes, cityIds, profileImg, nickname);
}

// 마커 반환 기능
@Transactional
public List<MapResponseDto.getMarkerResponse> getMarkers(String token) {
Long userId = jwtUtil.getUserIdFromToken(token);
List<Travel> travels = travelRepository.findByUserId(userId);
List<MapResponseDto.getMarkerResponse> markers = new ArrayList<>();

for (Travel travel : travels) {
City city = travel.getCity();
Country country = city.getCountry();
Map map = mapRepository.findByCountryCodeAndUserId(country.getCode(), userId);
MapResponseDto.getMarkerResponse marker = MapConverter.toMarkerResponseDto(map, travel.getThumbnail(), country.getName(), city.getName());
markers.add(marker);
}

return markers;
}

// 맵 색상 수정 메서드
// 맵 색상 수정
@Transactional
public MapResponseDto updateMapColor(Long mapId, String newColor) {
Map map = mapRepository.findById(mapId)
.orElseThrow(() -> new IllegalArgumentException("Map not found with id: " + mapId));
Color color = Color.valueOf(newColor); // 문자열을 Color 객체로 변환
map.setColor(color); // Color 객체 설정

map.setColor(newColor); // 요청된 hex 값을 설정
Map updatedMap = mapRepository.save(map);
return MapConverter.toMapResponseDto(updatedMap);
}

// 맵 색상 삭제 메서드
// 맵 색상 삭제
@Transactional
public void deleteMapColor(Long mapId) {
Map map = mapRepository.findById(mapId)
.orElseThrow(() -> new IllegalArgumentException("Map not found with id: " + mapId));

map.setColor(null); // 색상 삭제
mapRepository.save(map);
}

// 여러 색상 선택 메서드
// 여러 색상 선택 업데이트
@Transactional
public MapResponseDto updateMultipleMapColors(Long mapId, List<String> colorStrings) {
Map map = mapRepository.findById(mapId)
.orElseThrow(() -> new IllegalArgumentException("Map not found with id: " + mapId));
List<Color> colors = colorStrings.stream()
.map(Color::valueOf) // 각 문자열을 Color로 변환
.collect(Collectors.toList());
map.setColors(colors); // 다중 색상 설정

map.setColors(colorStrings); // 다중 색상 설정
Map updatedMap = mapRepository.save(map);
return MapConverter.toMapResponseDto(updatedMap);
}

// 유저별 방문한 나라와 도시 통계 반환
public MapStatsResponseDto getMapStatsByUserId(Long userId) {
long countryCount = mapRepository.countDistinctCountryCodeByUserId(userId);
long cityCount = mapRepository.countDistinctCityByUserId(userId);

List<String> countryCodes = mapRepository.findDistinctCountryCodesByUserId(userId);
List<Long> cityIds = mapRepository.findDistinctCityIdsByUserId(userId);

User user = userRepository.findById(userId)
.orElseThrow(() -> new IllegalArgumentException("User not found with id: " + userId));

return new MapStatsResponseDto(
countryCount,
cityCount,
countryCodes,
cityIds,
user.getProfileImg(),
user.getNickname()
);
}

// 도시 및 국가 검색
public List<MapResponseDto.searchDto> searchCitiesCountry(String keyword) {
if (keyword == null || keyword.trim().isEmpty()) {
return Collections.emptyList(); // 빈 리스트를 반환
return new ArrayList<>();
}

List<City> cities = cityRepository.findByNameIgnoreCase(keyword);
List<Country> countries = countryRepository.findByNameIgnoreCase(keyword);

List<MapResponseDto.searchDto> searched = new ArrayList<>();
List<MapResponseDto.searchDto> results = new ArrayList<>();

if (!cities.isEmpty()){
searched.addAll(cities.stream().map(MapConverter::toSearchDto).toList());
if (!cities.isEmpty()) {
results.addAll(cities.stream().map(MapConverter::toSearchDto).collect(Collectors.toList()));
}

if(!countries.isEmpty()){
countries.forEach(country -> {
if (!countries.isEmpty()) {
for (Country country : countries) {
List<City> citiesInCountry = cityRepository.findByCountryId(country.getId());
searched.addAll(citiesInCountry.stream().map(MapConverter::toSearchDto).toList());
});
results.addAll(citiesInCountry.stream().map(MapConverter::toSearchDto).collect(Collectors.toList()));
}
}

return searched;
return results;
}

// 마커 반환
public List<MapResponseDto.getMarkerResponse> getMarkers(String token) {
Long userId = jwtUtil.getUserIdFromToken(token);
List<Map> maps = mapRepository.findByUserId(userId);

return maps.stream()
.map(map -> MapConverter.toMarkerResponseDto(
map,
"", // 마커 이미지 URL 추가 필요 시 수정
map.getCity().getCountry().getName(),
map.getCity().getName()
))
.collect(Collectors.toList());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ public class MapRequestDto {
@NotBlank
private String countryCode;

@NotNull
private Color color;
@NotBlank
private String color; // 변경: String 타입으로 수정

private Long cityId; // 추가: 선택한 도시 ID
}
private Long cityId;
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public class MapResponseDto {
private Long visitId;
private Long userId;
private String countryCode;
private Color color;
private String color; // 변경: String 타입으로 수정

public MapResponseDto(Map map) {
this.visitId = map.getVisitId();
Expand All @@ -24,7 +24,7 @@ public MapResponseDto(Map map) {
@AllArgsConstructor
@Builder
public static class getMarkerResponse {
private Color color;
private String color;
private String markerImg;
private String countryCode;
private String countryName;
Expand All @@ -43,4 +43,4 @@ public static class searchDto {
private Long logCount;
private Long cityId;
}
}
}

0 comments on commit f0d0cde

Please sign in to comment.