Skip to content

Commit

Permalink
Merge pull request #117 from Happy-HOBAK/feat/#116
Browse files Browse the repository at this point in the history
[#116] ์ „์ฒด ์œ ์ €์˜ ํ–‰๋ณต ์ง€๋„ API ๊ตฌ์ถ•
  • Loading branch information
KkomSang authored Jun 1, 2024
2 parents 416bc67 + c581a4b commit 7f2ec1b
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
package com.hobak.happinessql.domain.report.api;

import com.hobak.happinessql.domain.report.application.AverageHappinessService;
import com.hobak.happinessql.domain.report.application.TrendPopularActivityService;
import com.hobak.happinessql.domain.report.application.TrendRecommendService;
import com.hobak.happinessql.domain.report.application.TrendSummaryService;
import com.hobak.happinessql.domain.report.application.*;
import com.hobak.happinessql.domain.report.domain.AgeGroup;
import com.hobak.happinessql.domain.report.dto.AverageHappinessResponseDto;
import com.hobak.happinessql.domain.report.dto.SummaryResponseDto;
import com.hobak.happinessql.domain.report.dto.TrendPopularActivitiyResponseDto;
import com.hobak.happinessql.domain.report.dto.TrendRecommendActivityResponseDto;
import com.hobak.happinessql.domain.report.dto.*;
import com.hobak.happinessql.domain.user.application.UserFindService;
import com.hobak.happinessql.domain.user.domain.Gender;
import com.hobak.happinessql.domain.user.domain.User;
Expand Down Expand Up @@ -36,6 +30,7 @@ public class TrendController {
private final TrendPopularActivityService trendPopularActivityService;
private final TrendRecommendService trendRecommendService;
private final TrendSummaryService trendSummaryService;
private final TrendLocationRankingService trendLocationRankingService;

@Operation(summary = "๋Œ€ํ•œ๋ฏผ๊ตญ ํ‰๊ท  ํ–‰๋ณต์ง€์ˆ˜", description = "์ „์ฒด ์œ ์ €์˜ ํ‰๊ท  ํ–‰๋ณต์ง€์ˆ˜์™€ ๊ทธ์— ๋”ฐ๋ฅธ ์ˆ˜์ค€์„ ํŒ๋‹จํ•ฉ๋‹ˆ๋‹ค.")
@GetMapping("/happiness")
Expand Down Expand Up @@ -68,4 +63,12 @@ public DataResponseDto<Object> getSummary(@RequestParam(required = false) AgeGro
if(responseDto == null) return DataResponseDto.of("์•„์ง์€ ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์–ด์š”.", "ํ–‰๋ณต ํŠธ๋ Œ๋“œ์˜ ํ–‰๋ณต ์ข…ํ•ฉ ๋ฆฌํฌํŠธ๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ์กฐํšŒํ–ˆ์Šต๋‹ˆ๋‹ค.");
return DataResponseDto.of(responseDto, "ํ–‰๋ณต ํŠธ๋ Œ๋“œ์˜ ํ–‰๋ณต ์ข…ํ•ฉ ๋ฆฌํฌํŠธ๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ์กฐํšŒํ–ˆ์Šต๋‹ˆ๋‹ค.");
}

@Operation(summary = "ํ–‰๋ณต๋„๊ฐ€ ๋†’์€ ์žฅ์†Œ์™€ ํ™œ๋™ Top3", description = "์ „์ฒด ์œ ์ €๊ฐ€ ํ–‰๋ณตํ–ˆ๋˜ ์žฅ์†Œ Top 3์˜ ์ด๋ฆ„, ์œ„์น˜, ๊ทธ ์žฅ์†Œ์—์„œ ๊ฐ€์žฅ ํ–‰๋ณต๋„๊ฐ€ ๋†’์•˜๋˜ ํ™œ๋™์„ ์กฐํšŒํ•ฉ๋‹ˆ๋‹ค.")
@GetMapping("/top-locations")
public DataResponseDto<List<LocationActivityRankingResponseDto>> getTop3HappiestLocations(@AuthenticationPrincipal UserDetails userDetails) {
User user = userFindService.findByUserDetails(userDetails);
List<LocationActivityRankingResponseDto> responseDto = trendLocationRankingService.getTop3HappyLocationsWithActivities(user);
return DataResponseDto.of(responseDto, "ํ–‰๋ณต๋„๊ฐ€ ๋†’์€ ์žฅ์†Œ์™€ ํ™œ๋™ Top3๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ์กฐํšŒํ–ˆ์Šต๋‹ˆ๋‹ค.");
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.hobak.happinessql.domain.report.application;

import com.hobak.happinessql.domain.record.domain.Location;
import com.hobak.happinessql.domain.record.domain.Record;
import com.hobak.happinessql.domain.report.converter.ReportConverter;
import com.hobak.happinessql.domain.report.dto.LocationActivityRankingResponseDto;
import com.hobak.happinessql.domain.report.dto.LocationRankingResponseDto;

import java.util.*;
Expand All @@ -15,6 +17,7 @@ public static String getHappiestLocation(List<Record> records) {
}

// ๋„์‹œ์™€ ๊ตฌ๋ฅผ ๊ธฐ์ค€์œผ๋กœ Record ๊ทธ๋ฃนํ™”
// TODO : ๋‚˜์ค‘์— ์ฃผ์„ ์‚ญ์ œ ๋ฐ ๋žœ๋ค ๋Œ๋ฆฌ๋Š” ๋กœ์ง ๋ฉ”์„œ๋“œ๋กœ ์ถ”์ถœํ•ด์„œ Ranking ๊ด€๋ จ ๋ฉ”์„œ๋“œ์—๋„ ์ถ”๊ฐ€
Map<String, List<Record>> locationRecordsMap = groupRecordsByLocation(records);

// ์œ„์น˜๋ณ„ ํ‰๊ท  ํ–‰๋ณต๋„์™€ ๋นˆ๋„ ๊ณ„์‚ฐ
Expand Down Expand Up @@ -82,6 +85,51 @@ public static List<LocationRankingResponseDto> getLocationRankings(List<Record>
return locationRankings;
}

public static List<LocationActivityRankingResponseDto> getLocationActivityRankings(List<Record> records, int topCount) {
List<LocationActivityRankingResponseDto> locationActivityRankings = new ArrayList<>();
if(records == null || records.isEmpty()) {
for(int i = 0; i < topCount; i++) {
locationActivityRankings.add(ReportConverter.toLocationActivityRankingResponseDto(i + 1, null, null));
}
return locationActivityRankings;
}

Map<String, List<Record>> locationRecordsMap = groupRecordsByLocation(records);

Map<String, Double> locationAverageHappiness = calculateLocationAverageHappiness(locationRecordsMap);
Map<String, Integer> locationFrequency = calculateLocationFrequency(locationRecordsMap);

List<String> sortedLocations = sortLocations(locationAverageHappiness, locationFrequency);

for(int i = 0; i < sortedLocations.size(); i++) {
String locationStr = sortedLocations.get(i);
List<Record> locationRecords = locationRecordsMap.get(locationStr);

Record happiestRecord = locationRecords.stream()
.max(Comparator.comparingInt(Record::getHappiness))
.orElse(null);

Location location = happiestRecord != null ? happiestRecord.getLocation() : null;
String happiesActivity = happiestRecord != null ? happiestRecord.getActivity().getName() : null;

LocationActivityRankingResponseDto dto = ReportConverter.toLocationActivityRankingResponseDto(
i+1,
location,
happiesActivity
);
locationActivityRankings.add(dto);
}

while(locationActivityRankings.size() < topCount) {
locationActivityRankings.add(ReportConverter.toLocationActivityRankingResponseDto(locationActivityRankings.size() + 1, null, null));
}

return locationActivityRankings.stream()
.limit(topCount)
.collect(Collectors.toList());

}

private static Map<String, List<Record>> groupRecordsByLocation(List<Record> records) {
return records.stream()
.filter(record -> record.getLocation() != null)
Expand Down Expand Up @@ -145,5 +193,4 @@ private static List<String> sortLocations(Map<String, Double> locationAverageHap
.map(Map.Entry::getKey)
.toList();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.hobak.happinessql.domain.report.application;

import com.hobak.happinessql.domain.record.domain.Record;
import com.hobak.happinessql.domain.record.repository.RecordRepository;
import com.hobak.happinessql.domain.report.dto.LocationActivityRankingResponseDto;
import com.hobak.happinessql.domain.user.domain.User;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@RequiredArgsConstructor
public class TrendLocationRankingService {

private final RecordRepository recordRepository;

public List<LocationActivityRankingResponseDto> getTop3HappyLocationsWithActivities(User user) {
List<Record> records = recordRepository.findAllByUser(user);
return LocationHappinessAnalyzer.getLocationActivityRankings(records, 3);

}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.hobak.happinessql.domain.report.converter;

import com.hobak.happinessql.domain.record.domain.Location;
import com.hobak.happinessql.domain.report.domain.HappinessLevel;
import com.hobak.happinessql.domain.report.domain.TimeOfDay;
import com.hobak.happinessql.domain.report.dto.*;
Expand Down Expand Up @@ -30,6 +31,17 @@ public static LocationRankingResponseDto toLocationRankingResponseDto(int rankin
.build();
}

public static LocationActivityRankingResponseDto toLocationActivityRankingResponseDto(int ranking, Location location, String happinesActivity) {
return LocationActivityRankingResponseDto.builder()
.ranking(ranking)
.location(location != null ? location.getCity() + " " + location.getDistrict() : null)
.latitude(location != null ? location.getLatitude() : null)
.longitude(location != null ? location.getLongitude() : null)
.happiestActivity(happinesActivity)
.build();

}

public static ReportGraphResponseDto toReportGraphResponseDto(ArrayList<String> labels, ArrayList<Double> happiness){
return ReportGraphResponseDto.builder()
.labels(labels)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.hobak.happinessql.domain.report.dto;


import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class LocationActivityRankingResponseDto {
private int ranking;
private String location;
private Double latitude;
private Double longitude;
private String happiestActivity;

@Builder
public LocationActivityRankingResponseDto(int ranking, String location, Double latitude, Double longitude, String happiestActivity) {
this.ranking = ranking;
this.location = location;
this.latitude = latitude;
this.longitude = longitude;
this.happiestActivity = happiestActivity;
}
}

0 comments on commit 7f2ec1b

Please sign in to comment.