diff --git a/build.gradle b/build.gradle index a804775..32a8f52 100644 --- a/build.gradle +++ b/build.gradle @@ -40,6 +40,9 @@ dependencies { //test testImplementation 'org.springframework.security:spring-security-test' testImplementation 'org.springframework.boot:spring-boot-starter-test' + + //data + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' } tasks.named('test') { diff --git a/src/main/java/fr/eni/enchere/bll/ArticleService.java b/src/main/java/fr/eni/enchere/bll/ArticleService.java index c64477d..f87c72b 100644 --- a/src/main/java/fr/eni/enchere/bll/ArticleService.java +++ b/src/main/java/fr/eni/enchere/bll/ArticleService.java @@ -2,6 +2,8 @@ package fr.eni.enchere.bll; import fr.eni.enchere.bo.Article; import fr.eni.enchere.bo.SearchArticleCritere; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import java.util.List; @@ -13,5 +15,5 @@ public interface ArticleService { void deleteArticle(int id); void updateArticle(int id); List
findArticleByTitle(String title); - List
searchArticle(SearchArticleCritere critere); + Page
searchArticlePageable(SearchArticleCritere critere, Pageable pageable); } diff --git a/src/main/java/fr/eni/enchere/bll/ArticleServiceImpl.java b/src/main/java/fr/eni/enchere/bll/ArticleServiceImpl.java index ffdf089..7f22302 100644 --- a/src/main/java/fr/eni/enchere/bll/ArticleServiceImpl.java +++ b/src/main/java/fr/eni/enchere/bll/ArticleServiceImpl.java @@ -3,6 +3,8 @@ package fr.eni.enchere.bll; import fr.eni.enchere.bo.Article; import fr.eni.enchere.bo.SearchArticleCritere; import fr.eni.enchere.dal.ArticleRepository; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import java.util.List; @@ -45,8 +47,9 @@ public class ArticleServiceImpl implements ArticleService{ return articleRepository.findArticleByTitle(title); } + @Override - public List
searchArticle(SearchArticleCritere critere) { - return articleRepository.searchArticle(critere); + public Page
searchArticlePageable(SearchArticleCritere critere, Pageable pageable) { + return articleRepository.searchArticlePageable(critere, pageable); } } diff --git a/src/main/java/fr/eni/enchere/controllers/AccueilController.java b/src/main/java/fr/eni/enchere/controllers/AccueilController.java index 21fb32c..31c1773 100644 --- a/src/main/java/fr/eni/enchere/controllers/AccueilController.java +++ b/src/main/java/fr/eni/enchere/controllers/AccueilController.java @@ -10,6 +10,8 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.stereotype.Controller; @@ -44,7 +46,7 @@ public class AccueilController { } @GetMapping({"/", "/accueil"}) - public String viewAccueil(HttpServletRequest request, @AuthenticationPrincipal UserDetails userDetails, @RequestParam(required = false) String searchTitle, @RequestParam(required = false) Integer searchCategory, Model model, @RequestParam(value = "venteOption", required = false) String[] venteOptions, @RequestParam(value = "achatOption", required = false) String[] achatOptions) { + public String viewAccueil(HttpServletRequest request, @AuthenticationPrincipal UserDetails userDetails, @RequestParam(required = false) String searchTitle, @RequestParam(required = false) Integer searchCategory, @RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "6") int size, Model model, @RequestParam(value = "venteOption", required = false) String[] venteOptions, @RequestParam(value = "achatOption", required = false) String[] achatOptions) { model.addAttribute("categories", categorieService.findAllCategories()); model.addAttribute("requestURI", request.getRequestURI()); SearchArticleCritere critere = new SearchArticleCritere(); @@ -55,15 +57,21 @@ public class AccueilController { } critere.setVenteOptions(venteOptions); critere.setAchatOptions(achatOptions); - model.addAttribute("articles", articleService.searchArticle(critere)); + + // Pagination + Page
articlePage = articleService.searchArticlePageable(critere, PageRequest.of(page, size)); + model.addAttribute("articles", articlePage.getContent()); + model.addAttribute("currentPage", page); + model.addAttribute("totalPages", articlePage.getTotalPages()); + return "accueil"; } @PostMapping("/accueil") - public String handleSearch(HttpServletRequest request, @AuthenticationPrincipal UserDetails userDetails, @RequestParam("searchTitle") String searchTitle, @RequestParam(value = "searchCategory", required = false) Integer searchCategory, Model model, @RequestParam(value = "venteOption", required = false) String[] venteOptions, @RequestParam(value = "achatOption", required = false) String[] achatOptions ) { + public String handleSearch(HttpServletRequest request, @AuthenticationPrincipal UserDetails userDetails, @RequestParam(required = false) String searchTitle, @RequestParam(required = false) Integer searchCategory, @RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "6") int size, Model model, @RequestParam(value = "venteOption", required = false) String[] venteOptions, @RequestParam(value = "achatOption", required = false) String[] achatOptions) { - return viewAccueil(request, userDetails, searchTitle, searchCategory, model, venteOptions, achatOptions); + return viewAccueil(request, userDetails, searchTitle, searchCategory, page, size, model, venteOptions, achatOptions); } diff --git a/src/main/java/fr/eni/enchere/controllers/LanguageController.java b/src/main/java/fr/eni/enchere/controllers/LanguageController.java index 71f4eb3..90549ad 100644 --- a/src/main/java/fr/eni/enchere/controllers/LanguageController.java +++ b/src/main/java/fr/eni/enchere/controllers/LanguageController.java @@ -23,7 +23,6 @@ public class LanguageController { @GetMapping("/change-language") public String changeLanguage(HttpServletRequest request, HttpServletResponse response, Locale locale) { LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request); - System.out.println(locale.getLanguage()); if (localeResolver != null) { if (locale.getLanguage().equals("en")) { localeResolver.setLocale(request, response, Locale.FRENCH); // Changer la langue en français @@ -31,7 +30,15 @@ public class LanguageController { localeResolver.setLocale(request, response, Locale.ENGLISH); // Changer la langue en anglais } } - return "redirect:/"; + + String referer = request.getHeader("Referer"); + + if (referer != null && !referer.isEmpty()) { + return "redirect:" + referer; + } else { + return "redirect:/"; + } } + } diff --git a/src/main/java/fr/eni/enchere/dal/ArticleRepository.java b/src/main/java/fr/eni/enchere/dal/ArticleRepository.java index 61a1bcb..5d6c084 100644 --- a/src/main/java/fr/eni/enchere/dal/ArticleRepository.java +++ b/src/main/java/fr/eni/enchere/dal/ArticleRepository.java @@ -2,12 +2,14 @@ package fr.eni.enchere.dal; import fr.eni.enchere.bo.Article; import fr.eni.enchere.bo.SearchArticleCritere; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import java.util.List; public interface ArticleRepository { List
findAllArticle(); - List
searchArticle(SearchArticleCritere critere); + Page
searchArticlePageable(SearchArticleCritere critere, Pageable pageable); Article findArticleById(int id); List
findArticleByTitle(String title); int saveArticle(Article article); diff --git a/src/main/java/fr/eni/enchere/dal/ArticleRepositoryImpl.java b/src/main/java/fr/eni/enchere/dal/ArticleRepositoryImpl.java index dc9f0f6..016c4f4 100644 --- a/src/main/java/fr/eni/enchere/dal/ArticleRepositoryImpl.java +++ b/src/main/java/fr/eni/enchere/dal/ArticleRepositoryImpl.java @@ -8,6 +8,9 @@ import fr.eni.enchere.controllers.AccueilController; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Primary; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; @@ -87,7 +90,7 @@ public class ArticleRepositoryImpl implements ArticleRepository { } @Override - public List
searchArticle(SearchArticleCritere critere) { + public Page
searchArticlePageable(SearchArticleCritere critere, Pageable pageable) { StringBuilder sql = new StringBuilder("SELECT DISTINCT a.*, u.* FROM ARTICLES_VENDUS a "); sql.append("JOIN UTILISATEURS u ON a.no_utilisateur = u.no_utilisateur "); sql.append("LEFT JOIN ENCHERES e ON a.no_article = e.no_article "); @@ -165,8 +168,104 @@ public class ArticleRepositoryImpl implements ArticleRepository { sql.append(")"); } + System.out.println(); + // Compte le nombre total d'articles + int totalCount = countArticlePageable(critere); + + // Ajoute la pagination à la requête SQL + sql.append(" LIMIT ? OFFSET ?"); + params.add(pageable.getPageSize()); + params.add(pageable.getOffset()); + + // Exécute la requête paginée List
articles = jdbcTemplate.query(sql.toString(), new HomeArticleRowMapper(), params.toArray()); + // Crée une Page
à partir des résultats et des informations de pagination + return new PageImpl<>(articles, pageable, totalCount); + } + + public int countArticlePageable(SearchArticleCritere critere) { + StringBuilder sql = new StringBuilder("SELECT COUNT(a.no_article) FROM ARTICLES_VENDUS a "); + sql.append("JOIN UTILISATEURS u ON a.no_utilisateur = u.no_utilisateur "); + sql.append("LEFT JOIN ENCHERES e ON a.no_article = e.no_article "); + sql.append("WHERE 1 = 1 AND a.isDelete = 0"); + List params = new ArrayList<>(); + + if (critere.getNoCategorie() != null) { + sql.append(" AND a.no_categorie = ?"); + params.add(critere.getNoCategorie()); + } + if (critere.getTitle() != null && !critere.getTitle().isEmpty()) { + sql.append(" AND a.nom_article LIKE ?"); + params.add('%' + critere.getTitle() + '%'); + } + + if (critere.getVenteOptions() != null && critere.getVenteOptions().length > 0) { + sql.append(" AND ("); + boolean isFirstCondition = true; + for (String option : critere.getVenteOptions()) { + if (option.equals("venteEnCours")) { + if (!isFirstCondition) { + sql.append(" OR "); + } + sql.append(" (a.date_debut_encheres <= NOW() AND a.date_fin_encheres >= NOW()) "); + isFirstCondition = false; + } + if (option.equals("ventesNonDebutees")) { + if (!isFirstCondition) { + sql.append(" OR "); + } + sql.append(" (a.date_debut_encheres > NOW()) "); + isFirstCondition = false; + } + if (option.equals("ventesTerminees")) { + if (!isFirstCondition) { + sql.append(" OR "); + } + sql.append(" (a.date_fin_encheres < NOW()) "); + isFirstCondition = false; + } + } + sql.append(") AND a.no_utilisateur = ?"); + params.add(critere.getNoVendeur()); + } + + if (critere.getAchatOptions() != null && critere.getAchatOptions().length > 0) { + sql.append(" AND ("); + boolean isFirstCondition = true; + for (String option : critere.getAchatOptions()) { + if (option.equals("encheresOuvertes")) { + if (!isFirstCondition) { + sql.append(" OR "); + } + sql.append(" (a.date_debut_encheres <= NOW() AND a.date_fin_encheres >= NOW()) "); + isFirstCondition = false; + } + if (option.equals("enchereEnCours")) { + if (!isFirstCondition) { + sql.append(" OR "); + } + sql.append(" (e.no_utilisateur = ? AND a.date_debut_encheres <= NOW() AND a.date_fin_encheres >= NOW()) "); + isFirstCondition = false; + params.add(critere.getNoVendeur()); + } + if (option.equals("enchereRemportees")) { + if (!isFirstCondition) { + sql.append(" OR "); + } + sql.append(" (e.no_utilisateur = ? AND e.montant_enchere = (SELECT MAX(montant_enchere) FROM ENCHERES WHERE no_article = a.no_article)) "); + isFirstCondition = false; + params.add(critere.getNoVendeur()); + } + } + + sql.append(")"); + } + + // Exécute la requête paginée + int articles = jdbcTemplate.queryForObject(sql.toString(), Integer.class, params.toArray()); + + // Retourne le nombre d'articles return articles; } diff --git a/src/main/resources/i18n/messages_en.properties b/src/main/resources/i18n/messages_en.properties index bf564d1..983d2eb 100644 --- a/src/main/resources/i18n/messages_en.properties +++ b/src/main/resources/i18n/messages_en.properties @@ -12,6 +12,10 @@ home.sell.finish = My completed sales home.button.search = Search home.button.lang = Passer en fran\u00E7ais home.button.lang2 = EN +home.button.first = First +home.button.end = End +home.button.next = Next +home.button.previous = Previous home.credit = My credits: home.nav.enchere = Auctions home.nav.vend = Sell an item diff --git a/src/main/resources/i18n/messages_fr.properties b/src/main/resources/i18n/messages_fr.properties index 99c630e..9899f21 100644 --- a/src/main/resources/i18n/messages_fr.properties +++ b/src/main/resources/i18n/messages_fr.properties @@ -12,6 +12,10 @@ home.sell.finish = Mes ventes termin\u00E9es home.button.search = Recherche home.button.lang = Switch to English home.button.lang2 = FR +home.button.first = D\u00e9but +home.button.end = Fin +home.button.next = Suivant +home.button.previous = Pr\u00e9cedent home.credit = Mes cr\u00e9dits : home.nav.enchere = Encheres home.nav.vend = Vendre un article @@ -20,7 +24,7 @@ home.profil.profil = Profil home.profil.logout = D\u00e9connexion home.article.sellprice = Prix de vente: home.article.seller = Vendeur: -home.article.end = Fin de l'ench\u00E8re: +home.article.end = Fin de l'ench\u00E8re: footer.desc = Cr\u00e9\u00e9e par l'association "Les objets sont nos amis", ENI-Ench\u00e9res a pour objectif d'aider ses membres \u00E0 vendre ou acheter des objets de tout genre. footer. @@ -116,4 +120,5 @@ article.details.address.unknown = Adresse inconnue article.details.validation.amount.required = Le montant de l'ench\u00E8re est requis. -edit.article.title = Modifier mon article \ No newline at end of file +edit.article.title = Modifier mon article + diff --git a/src/main/resources/templates/accueil.html b/src/main/resources/templates/accueil.html index c07b3ed..1afb727 100644 --- a/src/main/resources/templates/accueil.html +++ b/src/main/resources/templates/accueil.html @@ -143,6 +143,42 @@ + +
+
+ +
+
diff --git a/src/main/resources/templates/admin.html b/src/main/resources/templates/admin.html index d43feae..8f21436 100644 --- a/src/main/resources/templates/admin.html +++ b/src/main/resources/templates/admin.html @@ -5,57 +5,54 @@ -
-

Liste des catégories modifiées

- - - - - - - - - - - - - -
NomAction
-
- - - -
-
-
- - -
-
-
- - +
+

Liste des catégories modifiées

+
+ + + + + + + + + + + + + +
NomAction
+ + + + + + +
+ + +
+
+
+
+ +
-

Liste des utilisateurs

- - - - - - - - - - - - - - - - - - - + +

Liste des utilisateurs

+
+
IDPseudoNomPrénomEmailAction
+ + + + + + + + + + + @@ -64,31 +61,31 @@ - -
IDPseudoNomPrénomEmailAction
- + - +
- +
- +
- +
- + + +
diff --git a/src/main/resources/templates/modele-page.html b/src/main/resources/templates/modele-page.html index fc45ee0..308a6ae 100644 --- a/src/main/resources/templates/modele-page.html +++ b/src/main/resources/templates/modele-page.html @@ -45,6 +45,7 @@