Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Step3 2 #2

Merged
merged 3 commits into from
May 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
- [x] 예약이 있는 테마를 삭제 요청시 에러

- [ ] 사용자 예약 기능 추가
- [x] 인기 테마 기능 추가

# API 명세

Expand Down
9 changes: 9 additions & 0 deletions src/main/java/roomescape/controller/ThemeController.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package roomescape.controller;

import java.net.URI;
import java.time.LocalDate;
import java.util.List;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
Expand All @@ -9,6 +10,7 @@
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.RestController;
import roomescape.dto.ThemeRequest;
import roomescape.dto.ThemeResponse;
Expand All @@ -29,6 +31,13 @@ public List<ThemeResponse> findAll() {
return themeService.findAll();
}

@GetMapping("/ranking")
public List<ThemeResponse> findAndOrderByPopularity(@RequestParam LocalDate start,
@RequestParam LocalDate end,
@RequestParam int count) {
return themeService.findAndOrderByPopularity(start, end, count);
}

@PostMapping
public ResponseEntity<ThemeResponse> save(@RequestBody ThemeRequest themeRequest) {
ThemeResponse saved = themeService.save(themeRequest);
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/roomescape/controller/UserController.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,9 @@ public class UserController {
public String reservationPage() {
return "reservation";
}

@GetMapping("/")
public String bestThemePage() {
return "index";
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package roomescape.repository;

import java.sql.PreparedStatement;
import java.time.LocalDate;
import java.util.List;
import java.util.Optional;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Repository;
Expand All @@ -12,31 +14,35 @@
@Repository
public class JdbcTemplateThemeRepository implements ThemeRepository {
private final JdbcTemplate jdbcTemplate;
private RowMapper<Theme> themeRowMapper = (rs, rowNum) -> {
long id = rs.getLong("id");
String name = rs.getString("name");
String description = rs.getString("description");
String thumbnail = rs.getString("thumbnail");
return new Theme(id, name, description, thumbnail);
};
;

public JdbcTemplateThemeRepository(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}

@Override
public List<Theme> findAll() {
return jdbcTemplate.query("select ID, NAME, DESCRIPTION, THUMBNAIL from THEME", (rs, rowNum) -> {
long id = rs.getLong(1);
String name = rs.getString(2);
String description = rs.getString(3);
String thumbnail = rs.getString(4);
return new Theme(id, name, description, thumbnail);
});
return jdbcTemplate.query("select ID, NAME, DESCRIPTION, THUMBNAIL from THEME", themeRowMapper);
}

@Override
public List<Theme> findAndOrderByPopularity(LocalDate start, LocalDate end, int count) {
return jdbcTemplate.query(
"select th.*, count(*) as count from theme th join reservation r on r.theme_id = th.id where PARSEDATETIME(r.date,'yyyy-MM-dd') >= PARSEDATETIME(?,'yyyy-MM-dd') and PARSEDATETIME(r.date,'yyyy-MM-dd') <= PARSEDATETIME(?,'yyyy-MM-dd') group by th.id order by count desc limit ?",
themeRowMapper, start, end, count);
}

@Override
public Optional<Theme> findById(long id) {
List<Theme> themes = jdbcTemplate.query("select id, name, description, thumbnail from theme where id = ?",
(rs, rowNum) -> {
String name = rs.getString("name");
String description = rs.getString("description");
String thumbnail = rs.getString("thumbnail");
return new Theme(id, name, description, thumbnail);
}, id);
themeRowMapper, id);
return themes.stream().findFirst();
}

Expand Down
3 changes: 3 additions & 0 deletions src/main/java/roomescape/repository/ThemeRepository.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package roomescape.repository;

import java.time.LocalDate;
import java.util.List;
import java.util.Optional;
import roomescape.domain.Theme;

public interface ThemeRepository {
List<Theme> findAll();

List<Theme> findAndOrderByPopularity(LocalDate start, LocalDate end, int count);

Optional<Theme> findById(long id);

Theme save(Theme theme);
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/roomescape/service/ThemeService.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package roomescape.service;

import java.time.LocalDate;
import java.util.List;
import org.springframework.stereotype.Service;
import roomescape.domain.Theme;
Expand Down Expand Up @@ -42,6 +43,12 @@ public List<ThemeResponse> findAll() {
.toList();
}

public List<ThemeResponse> findAndOrderByPopularity(LocalDate start, LocalDate end, int count) {
return themeRepository.findAndOrderByPopularity(start, end, count).stream()
.map(this::toResponse)
.toList();
}

public void delete(long id) {
//todo : 변수명 고민
boolean invalidDelete = reservationRepository.findAll().stream()
Expand Down
72 changes: 44 additions & 28 deletions src/main/resources/static/js/ranking.js
Original file line number Diff line number Diff line change
@@ -1,44 +1,60 @@
document.addEventListener('DOMContentLoaded', () => {
/*
TODO: [3단계] 인기 테마 - 인기 테마 목록 조회 API 호출
*/
requestRead('/') // 인기 테마 목록 조회 API endpoint
.then(render)
.catch(error => console.error('Error fetching times:', error));
/*
TODO: [3단계] 인기 테마 - 인기 테마 목록 조회 API 호출
*/
const today = new Date();
let startDate = formatDate(minusDay(today, 7));
let endDate = formatDate(minusDay(today, 1));
const count = 10;
const endpoint = `/themes/ranking?start=${startDate}&end=${endDate}&count=${count}`;
requestRead(endpoint) // 인기 테마 목록 조회 API endpoint
.then(render)
.catch(error => console.error('Error fetching times:', error));
});

function minusDay(date, minusValue) {
return new Date(new Date(date).setDate(date.getDate() - minusValue));
}

function formatDate(date) {
const year = date.getFullYear();
const month = ('0' + (date.getMonth() + 1)).slice(-2);
const day = ('0' + date.getDate()).slice(-2);
return year + '-' + month + '-' + day;
}

function render(data) {
const container = document.getElementById('theme-ranking');

/*
TODO: [3단계] 인기 테마 - 인기 테마 목록 조회 API 호출 후 렌더링
response 명세에 맞춰 name, thumbnail, description 값 설정
*/
data.forEach(theme => {
const name = '';
const thumbnail = '';
const description = '';

const htmlContent = `
const container = document.getElementById('theme-ranking');

/*
TODO: [3단계] 인기 테마 - 인기 테마 목록 조회 API 호출 후 렌더링
response 명세에 맞춰 name, thumbnail, description 값 설정
*/
data.forEach(theme => {
const name = theme.name;
const thumbnail = theme.thumbnail;
const description = theme.description;

const htmlContent = `
<img class="mr-3 img-thumbnail" src="${thumbnail}" alt="${name}">
<div class="media-body">
<h5 class="mt-0 mb-1">${name}</h5>
${description}
</div>
`;

const div = document.createElement('li');
div.className = 'media my-4';
div.innerHTML = htmlContent;
const div = document.createElement('li');
div.className = 'media my-4';
div.innerHTML = htmlContent;

container.appendChild(div);
})
container.appendChild(div);
})
}

function requestRead(endpoint) {
return fetch(endpoint)
.then(response => {
if (response.status === 200) return response.json();
throw new Error('Read failed');
});
return fetch(endpoint)
.then(response => {
if (response.status === 200) return response.json();
throw new Error('Read failed');
});
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package roomescape.repository;


import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
Expand All @@ -21,6 +23,11 @@ public List<Theme> findAll() {
return new ArrayList<>(themes);
}

@Override
public List<Theme> findAndOrderByPopularity(LocalDate start, LocalDate end, int count) {
return null;
}

@Override
public Optional<Theme> findById(long id) {
return themes.stream()
Expand Down