Présentation de l'Architecture
Ce projet est une solution complète de vente en gros de fruits et légumes, reposant sur l'écosystème Java EE. Il adopte le modèle d'architecture MVC strict en utilisant le framework SSM (Spring, SpringMVC, MyBatis) combiné à JSP pour la couche vue. L'interface est conçue avec Bootstrap pour garantir une expérience utilisateur fluide et réactive.
Environnement Technique Requis
- JDK : Version 8 ou supérieure
- Base de données : MySQL 5.7+
- Serveur d'application : Apache Tomcat 8+
- IDE compatibles : IntelliJ IDEA, Eclipse, MyEclipse, Spring Tool Suite
Fonctionnalités Principales
Module Front-office (Client)
- Inscription et authentification des utilisateurs
- Consultation des annonces et actualités
- Catalogage et recherche de produits agricoles
- Gestion du panier et processus de validation de commande
- Système de notation et d'évaluation des produits
Module Back-office (Administration)
- Gestion des comptes utilisateurs et administrateurs
- Publication et gestion des annonces
- Administration des catégories de produits
- Configuration des villes et des points de livraison
- Suivi des commandes et gestion des évaluations
Exemples d'Implémentation
La logique métier est structurée autour de contrôleurs Spring MVC. Ci-dessous, des exemples refactorisés illustrant le traitement des commandes et l'administration des données.
Validation du Panier et Création de Commande
Ce contrôleur gère la transformation du panier en une commande officielle, met à jour les statistiques de vente et vide le panier de l'utilisateur.
@Controller
@RequestMapping("/commande")
public class CommandeControleur extends ControleurBase {
@Autowired
private PanierService panierService;
@Autowired
private ProduitService produitService;
@Autowired
private LigneCommandeService ligneCommandeService;
@Autowired
private CommandeService commandeService;
@PostMapping("/valider.action")
public String validerCommande(HttpServletRequest requete) {
String utilisateurId = (String) requete.getSession().getAttribute("utilisateurId");
if (utilisateurId == null) {
return "redirect:/connexion";
}
List<Panier> articlesPanier = panierService.obtenirParUtilisateur(utilisateurId);
String codeCommande = GenerateurId.genererUUID();
double montantTotal = 0.0;
for (Panier article : articlesPanier) {
LigneCommande lc = new LigneCommande();
lc.setId(GenerateurId.genererUUID());
lc.setProduitId(article.getProduitId());
lc.setQuantite(article.getQuantite());
lc.setCodeCommande(codeCommande);
lc.setPrixUnitaire(article.getPrix());
lc.setPointLivraisonId(requete.getParameter("pointLivraisonId"));
lc.setVilleId(requete.getParameter("villeId"));
lc.setDateLivraisonPrevue(requete.getParameter("dateLivraison"));
ligneCommandeService.ajouter(lc);
Produit p = produitService.trouverParId(article.getProduitId());
p.setVentes(p.getVentes() + article.getQuantite());
produitService.mettreAJour(p);
montantTotal += article.getPrix() * article.getQuantite();
panierService.supprimer(article.getId());
}
Commande nouvelleCommande = new Commande();
nouvelleCommande.setCode(codeCommande);
nouvelleCommande.setUtilisateurId(utilisateurId);
nouvelleCommande.setMontantTotal(montantTotal);
nouvelleCommande.setStatut("EN_ATTENTE");
nouvelleCommande.setDateCreation(LocalDate.now().toString());
commandeService.ajouter(nouvelleCommande);
return "redirect:/commande/historique.action";
}
}
Gestion Administrative et Pagination
Ce composant démontre la gestion standard du back-office, incluant la pagination simplifiée et la suppression par lot via l'API Spring.
@Controller
@RequestMapping("/admin/utilisateur")
public class AdminUtilisateurControleur {
@Autowired
private UtilisateurService utilisateurService;
@GetMapping("/liste.action")
public String listerUtilisateurs(@RequestParam(defaultValue = "0") int page, Model modele) {
List<Utilisateur> tousUtilisateurs = utilisateurService.listerTout();
int taillePage = 10;
int totalElements = tousUtilisateurs.size();
int totalPages = (int) Math.ceil((double) totalElements / taillePage);
int debut = Math.min(page * taillePage, totalElements);
int fin = Math.min(debut + taillePage, totalElements);
List<Utilisateur> pageCourante = tousUtilisateurs.subList(debut, fin);
modele.addAttribute("utilisateurs", pageCourante);
modele.addAttribute("pageCourante", page);
modele.addAttribute("totalPages", totalPages);
return "admin/liste_utilisateurs";
}
@PostMapping("/supprimerLots.action")
public String supprimerParLots(@RequestParam("ids") String[] identifiants) {
for (String uid : identifiants) {
utilisateurService.supprimer(uid);
}
return "redirect:/admin/utilisateur/liste.action";
}
@PostMapping("/mettreAJour.action")
public String modifierUtilisateur(Utilisateur utilisateur) {
utilisateurService.mettreAJour(utilisateur);
return "redirect:/admin/utilisateur/liste.action";
}
}
Recherche Floue par Critères
Pour filtrer les catégories ou les produits, l'application utilise un mécanisme de recherceh dynamique basé sur les propriétés du modèle.
@Controller
@RequestMapping("/admin/categorie")
public class CategorieControleur {
@Autowired
private CategorieService categorieService;
@GetMapping("/recherche.action")
public String rechercherParCritere(@RequestParam(required = false) String critere,
@RequestParam(required = false) String valeur,
Model modele) {
Categorie filtre = new Categorie();
if (critere != null) {
switch (critere) {
case "nom":
filtre.setNom(valeur);
break;
case "description":
filtre.setDescription(valeur);
break;
case "dateAjout":
filtre.setDateAjout(valeur);
break;
}
}
List<Categorie> resultats = categorieService.rechercherSimilaire(filtre);
modele.addAttribute("categories", resultats);
return "admin/recherche_categorie";
}
}