Conception et Implémentation d'un Système de Gestion d'Emprunt de Livres
Ce projet se concentre sur la création d'un système complet et efficace pour la gestion des emprunts de livres. L'architecture repose sur un modèle B/S (Navigateur/Serveur), avec un développement backend en Java utilisant les frameworks Spring Boot et MyBatis. La persistance des données est assurée par une base de données MySQL, tandis que l'interface utilisateur est construite avec Vue.js pour une expérience interactive. Le système distingue deux rôles principaux : administrateur et utilisateur. L'administrateur peut gérer les utilisateurs, les catégories de livres, les informations sur les livres, les emprunts, les retraits, les retours et les annonces, offrant ainsi un contrôle complet sur les ressources et les processus. L'utilisateur bénéficie de recommandations personnalisées, de la consultation des livres et des annonces, ainsi que de fonctionnalités telles que la recherche, les commentaires et la demande d'emprunt, avec la possibilité de gérer son compte, ses favoris et ses emprunts via le centre personnel.
Conception des Modules Fonctionnels
La conception des modules fonctionnels est structurée autour des rôles administrateur et utilisateur. Pour l'administrateur, le système inclut : un tableau de bord avec des statistiques clés sur les utilisateurs, les livres et les emprunts ; la gestion des utilisateurs avec des opérations CRUD ; la gestion des catégories de livres pour une classification flexible ; la gestion des informations sur les livres (ajout, modifictaion, suppression, recherche) ; le suivi des emprunts, retraits et retours ; et la gestion des annonces (publication, modification, suppression). Pour l'utilisateur, le tableau de bord offre des recommandations basées sur les favoris et affiche les livres et annonces ; le module d'informations sur les livres permet la recherche, la consultation des détails, les commentaires et les demandes d'emprunt ; le module d'annonces fournit les mises à jour du système ; et le centre personnel permet la gestion du compte, des favoris et la visualisation des historiques d'emprunts, retraits et retours. Cette conception vise à optimiser la gestion des emprunts et à améliorer l'expérience utilisateur.
Implémentation Fonctionnelle
L'implémentation comprend des interfaces pour les utilisateurs et les administrateurs, avec des fonctionnalités telles que la navigation, la recherche et la gestion des données. Les captures d'écran des interfaces ne sont pas incluses ici, mais le système offre une interaction fluide grâce à Vue.js et une logique backend robuste via Spring Boot.
Extraits de Code Clés
Téléversement de Fichiers
/**
* Contrôleur pour le téléversement et le téléchargement de fichiers
*/
@RestController
@RequestMapping("media")
public class GestionnaireFichiers {
@Autowired
private ServiceConfiguration configService;
/**
* Téléverser un fichier
*/
@PostMapping("/envoyer")
public ResponseEntity<Map<String, Object>> envoyerFichier(@RequestParam("fichier") MultipartFile fichier, String type) throws Exception {
if (fichier.isEmpty()) {
throw new RuntimeException("Le fichier ne peut pas être vide");
}
String extension = fichier.getOriginalFilename().substring(fichier.getOriginalFilename().lastIndexOf(".") + 1);
File cheminBase = new File(ResourceUtils.getURL("classpath:static").getPath());
if (!cheminBase.exists()) {
cheminBase = new File("");
}
File repertoireTeleversement = new File(cheminBase.getAbsolutePath(), "/uploads/");
if (!repertoireTeleversement.exists()) {
repertoireTeleversement.mkdirs();
}
String nomFichier = System.currentTimeMillis() + "." + extension;
File destination = new File(repertoireTeleversement.getAbsolutePath() + "/" + nomFichier);
fichier.transferTo(destination);
if (StringUtils.isNotBlank(type) && type.equals("1")) {
EntiteConfiguration configEntite = configService.rechercherUn(new CritereEntite().eq("nom", "fichierImage"));
if (configEntite == null) {
configEntite = new EntiteConfiguration();
configEntite.setNom("fichierImage");
configEntite.setValeur(nomFichier);
} else {
configEntite.setValeur(nomFichier);
}
configService.insereOuMiseAJour(configEntite);
}
Map<String, Object> reponse = new HashMap<>();
reponse.put("fichier", nomFichier);
return ResponseEntity.ok(reponse);
}
}
Téléchargement de Fichiers
/**
* Télécharger un fichier
*/
@GetMapping("/telecharger")
public ResponseEntity<byte[]> telechargerFichier(@RequestParam String nomFichier) {
try {
File cheminBase = new File(ResourceUtils.getURL("classpath:static").getPath());
if (!cheminBase.exists()) {
cheminBase = new File("");
}
File repertoireTeleversement = new File(cheminBase.getAbsolutePath(), "/uploads/");
if (!repertoireTeleversement.exists()) {
repertoireTeleversement.mkdirs();
}
File fichier = new File(repertoireTeleversement.getAbsolutePath() + "/" + nomFichier);
if (fichier.exists()) {
HttpHeaders entetes = new HttpHeaders();
entetes.setContentType(MediaType.APPLICATION_OCTET_STREAM);
entetes.setContentDispositionFormData("attachment", nomFichier);
return new ResponseEntity<>(FileUtils.readFileToByteArray(fichier), entetes, HttpStatus.OK);
}
} catch (IOException e) {
e.printStackTrace();
}
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
Inscription d'Utilisateur
/**
* Inscription d'un nouvel utilisateur
*/
@PostMapping("/inscrire")
public ResponseEntity<Map<String, Object>> inscrireUtilisateur(@RequestBody EntiteUtilisateur utilisateur) {
EntiteUtilisateur existant = serviceUtilisateur.rechercherUn(new CritereEntite().eq("nomUtilisateur", utilisateur.getNomUtilisateur()));
if (existant != null) {
Map<String, Object> erreur = new HashMap<>();
erreur.put("message", "L'utilisateur existe déjà");
return ResponseEntity.badRequest().body(erreur);
}
Long identifiant = System.currentTimeMillis();
utilisateur.setId(identifiant);
serviceUtilisateur.insere(utilisateur);
Map<String, Object> succes = new HashMap<>();
succes.put("message", "Inscription réussie");
return ResponseEntity.ok(succes);
}
/**
* Déconnexion de l'utilisateur
*/
@PostMapping("/deconnexion")
public ResponseEntity<String> deconnexionUtilisateur(HttpServletRequest requete) {
requete.getSession().invalidate();
return ResponseEntity.ok("Déconnexion réussie");
}
/**
* Obtenir les informations de session de l'utilisateur courant
*/
@GetMapping("/session")
public ResponseEntity<EntiteUtilisateur> obtenirUtilisateurCourant(HttpServletRequest requete) {
Long id = (Long) requete.getSession().getAttribute("identifiantUtilisateur");
EntiteUtilisateur utilisateur = serviceUtilisateur.rechercherParId(id);
return ResponseEntity.ok(utilisateur);
}