Merge remote-tracking branch 'origin/master'

# Conflicts:
#	data/db.mv.db
This commit is contained in:
Anton Romanov 2022-03-11 14:28:30 +04:00
commit ad84219799
8 changed files with 160 additions and 4 deletions

View File

@ -6,6 +6,7 @@
package ru.ulstu.controller; package ru.ulstu.controller;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.validation.BindingResult; import org.springframework.validation.BindingResult;
@ -14,14 +15,21 @@ import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import ru.ulstu.model.News; import ru.ulstu.model.News;
import ru.ulstu.model.OffsetablePageRequest;
import ru.ulstu.service.NewsService; import ru.ulstu.service.NewsService;
import javax.validation.Valid; import javax.validation.Valid;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@Controller @Controller
@RequestMapping("news") @RequestMapping("news")
public class NewsController { public class NewsController {
private final static int DEFAULT_PAGE_SIZE = 10;
private final NewsService newsService; private final NewsService newsService;
public NewsController(NewsService newsService) { public NewsController(NewsService newsService) {
@ -29,8 +37,21 @@ public class NewsController {
} }
@GetMapping("/news") @GetMapping("/news")
public String index(Model model) { public String listNews(Model model,
model.addAttribute("news", newsService.getAll()); @RequestParam Optional<Integer> page,
@RequestParam Optional<Integer> size) {
int currentPage = page.orElse(1);
int pageSize = size.orElse(DEFAULT_PAGE_SIZE);
Page<News> newsPage = newsService.getNews(new OffsetablePageRequest(currentPage - 1, pageSize));
model.addAttribute("news", newsPage);
int totalPages = newsPage.getTotalPages();
if (totalPages > 0) {
List<Integer> pageNumbers = IntStream.rangeClosed(1, totalPages)
.boxed()
.collect(Collectors.toList());
model.addAttribute("pageNumbers", pageNumbers);
}
return "news"; return "news";
} }

View File

@ -0,0 +1,93 @@
package ru.ulstu.model;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import java.io.Serializable;
public class OffsetablePageRequest implements Pageable, Serializable {
private final int offset;
private final int count;
private final Sort sort;
public OffsetablePageRequest(int page, long pageSize) {
this(pageSize * page, pageSize, Sort.by("id"));
}
public OffsetablePageRequest(long offset, long count, Sort sort) {
if (offset < 0) {
throw new IllegalArgumentException("Offset value must not be less than zero!");
}
if (count < 1) {
throw new IllegalArgumentException("Count value must not be less than one!");
}
this.offset = (int) offset;
this.count = (int) count;
this.sort = sort;
}
@Override
public Sort getSort() {
return sort;
}
@Override
public int getPageSize() {
return count;
}
@Override
public int getPageNumber() {
return offset / count;
}
@Override
public long getOffset() {
return offset;
}
@Override
public boolean hasPrevious() {
return offset > 0;
}
@Override
public Pageable next() {
return new OffsetablePageRequest(getOffset() + getPageSize(), getPageSize(), getSort());
}
@Override
public Pageable previousOrFirst() {
return hasPrevious() ? previous() : first();
}
public Pageable previous() {
return getOffset() == 0 ? this : new OffsetablePageRequest(getOffset() - getPageSize(), getPageSize(), getSort());
}
@Override
public Pageable first() {
return new OffsetablePageRequest(0, getPageSize(), getSort());
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
final OffsetablePageRequest other = (OffsetablePageRequest) obj;
return this.offset == other.offset && this.count == other.count;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + offset;
result = prime * result + count;
return result;
}
}

View File

@ -1,5 +1,7 @@
package ru.ulstu.repository; package ru.ulstu.repository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import ru.ulstu.model.News; import ru.ulstu.model.News;
@ -7,4 +9,6 @@ import java.util.List;
public interface NewsRepository extends JpaRepository<News, Integer> { public interface NewsRepository extends JpaRepository<News, Integer> {
List<News> findFirst3ByOrderByDateDesc(); List<News> findFirst3ByOrderByDateDesc();
Page<News> findByOrderByDateDesc(Pageable pageable);
} }

View File

@ -1,5 +1,7 @@
package ru.ulstu.service; package ru.ulstu.service;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import ru.ulstu.model.News; import ru.ulstu.model.News;
import ru.ulstu.repository.NewsRepository; import ru.ulstu.repository.NewsRepository;
@ -50,4 +52,8 @@ public class NewsService {
public List<News> getLast() { public List<News> getLast() {
return newsRepository.findFirst3ByOrderByDateDesc(); return newsRepository.findFirst3ByOrderByDateDesc();
} }
public Page<News> getNews(Pageable pageable) {
return newsRepository.findByOrderByDateDesc(pageable);
}
} }

View File

@ -32,3 +32,24 @@
.link-dark, .link-dark:visited, .link-dark:focus, .link-dark:any-link { .link-dark, .link-dark:visited, .link-dark:focus, .link-dark:any-link {
color: black; color: black;
} }
.pagination {
display: inline-block;
}
.pagination a {
color: black;
float: left;
padding: 5px 5px;
text-decoration: none;
}
.pagination a.active {
background-color: gray;
color: white;
border-radius: 2px;
}
footer {
height: 50px;
}

View File

@ -7,7 +7,7 @@
<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring4-4.dtd"> <!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring4-4.dtd">
<html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{default}"> <html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{default}">
<div class="container" layout:fragment="content"> <div class="container" layout:fragment="content">
<a href="/editNews/0" class="btn btn-outline-dark"> <a href="/news/editNews/0" class="btn btn-outline-dark">
<i class="fa fa-plus-square" aria-hidden="true">Добавить новость</i> <i class="fa fa-plus-square" aria-hidden="true">Добавить новость</i>
</a> </a>
</div> </div>

View File

@ -64,6 +64,7 @@
<div layout:fragment="content"> <div layout:fragment="content">
</div> </div>
</div> </div>
<footer></footer>
</div> </div>
</body> </body>
</html> </html>

View File

@ -36,5 +36,15 @@
class="news-date"></div> class="news-date"></div>
<hr/> <hr/>
</div> </div>
<div th:if="${news.totalPages > 0}" class="pagination">
<span style="float: left; padding: 5px 5px;">Страницы:</span>
</div>
<div th:if="${news.totalPages > 0}" class="pagination"
th:each="pageNumber : ${pageNumbers}">
<a th:href="@{/news/news(size=${news.size}, page=${pageNumber})}"
th:text=${pageNumber}
th:class="${pageNumber == news.number+1} ? active"></a>
</div>
</div> </div>
</html> </html>