Conception et implémentation d'une mini-application de commerce de vêtements traditionnels chinois avec Spring Boot, Vue et UniApp

Le développement d'une plateforme de commerce en ligne pour les vêtements traditionnels chinois (Hanfu) requiert une architecture robuste. Ce projet combine une architecture backend avec Spring Boot, un frontend web réactif avec Vue.js et une application mobile multiplateforme via UniApp. L'objectif est de créer un système complet permettant aux utilisateurs de parcourir, commander et gérer les produits de manière transparente sur différentes plateformes.

Stack technique détaillée

Backend : Spring Boot

Spring Boot simplifie le développement des applications Java en fournissant un ensemble d'outils préconfigurés. Sa fonctionnalité de démarrage rapide et ses dépendances intégrées permettent une mise en route immédiate. Le framework supporte nativement des serveurs comme Tomcat et offre une intégration facile avec des bibliothèques de sécurité (Spring Security), de données (Spring Data) et de services cloud (Spring Cloud). Cette modularité accélère le développement et la maintenance des services backand.

Frontend web : Vue.js

Vue.js utilise un DOM virtuel pour optimiser les performances d'interface. Son modèle de liaison de données réactif garantit que l'interface utilisateur se met à jour automatiquement lorsque l'état de l'application change. Cette approche par composants favorise la réutilisabilité du code et une structure claire de l'application, permettant aux développeurs de se concentrer sur la logique métier plutôt que sur les manipulations manuelles du DOM.

Couche de données : MyBatis-Plus

MyBatis-Plus étend les fonctionnalités de MyBatis pour réduire le code boilerplate. Il fournit des annotations et des assistants pour les opérations CRUD courantes, ainsi que des outils de pagination et de requêtes dynamiques. Le générateur de code automatique peut produier des classes d'entités et des interfaces de mapping, accélérant ainsi la mise en place de la couche d'accès aux données pour diverses bases de données relationnelles.

Processus de test du système

La phase de validation est cruciale pour assurer la qualité et la fiabilité de l'application. Une approche de boîte noire est adoptée pour tester les fonctionnalités du point de vue de l'utilisateur, en identifiant les écarts par rapport aux exigences et en corrigeant les défauts.

Objectifs des tests

L'objectif principal est de simuler des scénarios d'utilisation réels pour détecter les problèmes potentiels. Cela permet d'améliorer l'expérience utilisateur en s'assurant que toutes les interactions répondent aux attentes. Les tests vérifient non seulement la fonctionnalité mais aussi la cohérence logique et la robustesse du système face à des entrées inattendues.

Exemples de cas de test fonctionnels

Pour la fonctionnalité de connexion, les tests incluent la validation des identifiants et des codes de vérification. Voici un exemple de structure de test :

Entrée Résultat attendu Résultat observé Analyse
Nom d'utilisateur : admin, Mot de passe : passe123, Code : correct Connexion réussie L'utilisateur accède au tableau de bord Conforme à l'attente
Nom d'utilisateur : admin, Mot de passe : secret999, Code : correct Message d'erreur de mot de passe L'interface affiche une erreur de mot de passe Conforme à l'attente
Nom d'utilisateur : (vide), Mot de passe : passe123, Code : correct Champ nom d'utilisateur obligatoire Un message d'erreur indique que le nom est requis Conforme à l'attente

Pour la gestion des utilisateurs, les tests couvrent les opérations d'ajout, de modification et de suppression. Par exemple :

Action Résultat attendu Résultat observé Analyse
Ajout d'un nouvel utilisateur avec des informations valides L'utilisateur apparaît dans la liste L'enregistrement est visible dans l'interface d'administration Succès
Tentative d'ajout avec un nom d'utilisateur déjà existant Message d'erreur indiquant une duplication L'application empêche l'ajout et notifie l'administrateur Comportement correct

Conclusion des tests

À l'issue du cycle de test, le système répond aux exigences fonctionnelles spécifiées. Les résultats démontrent une couverture adéquate des scénarios critiques et une expérience utilisateur cohérente. Des ajustements ont été apportés pour renforcer la validation des entrées et la gestion des erreurs, garantissant ainsi une plateforme stable pour le commerce de Hanfu.

Extraits de code révisés

Voici des exemples de code issus de l'implémentation backend. Les noms de variables et la structure logique ont été modifiés pour clarifier l'illustration, tout en conservant la fonctionnalité originale.

Service d'authentification

@IgnoreAuth
@PostMapping("/authentification")
public ResponseEntity connexion(String identifiant, String secret, String captcha, HttpServletRequest requete) {
   UtilisateurEntity utilisateur = serviceUtilisateur.recupererParCondition(
       new ConditionEntite<utilisateurentity>().eq("identifiant", identifiant)
   );
   if (utilisateur == null || !utilisateur.getMotDePasse().equals(secret)) {
      return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Identifiants incorrects");
   }
   String jetonAcces = serviceJeton.creerJeton(utilisateur.getId(), identifiant, "utilisateurs", utilisateur.getRole());
   return ResponseEntity.ok().body(Collections.singletonMap("jeton", jetonAcces));
}</utilisateurentity>
@Override
public String creerJeton(Long idUtilisateur, String nomUtilisateur, String tableRef, String role) {
    JetonEntity jetonExistant = recupererParCondition(
        new ConditionEntite<jetonentity>().eq("idutilisateur", idUtilisateur).eq("role", role)
    );
    String nouveauJeton = GenerateurAleatoire.creerChaine(32);
    Date maintenant = new Date();
    Date expiration = DateUtils.addHeures(maintenant, 1);
    
    if (jetonExistant != null) {
        jetonExistant.setJeton(nouveauJeton);
        jetonExistant.setDateExpiration(expiration);
        mettreAJour(jetonExistant);
    } else {
        inserer(new JetonEntity(idUtilisateur, nomUtilisateur, tableRef, role, nouveauJeton, expiration));
    }
    return nouveauJeton;
}</jetonentity>

Intercepteur d'autorisation

@Component
public class IntercepteurAuthentification implements HandlerInterceptor {

    private static final String CLE_JETON = "Authorization";
    
    @Autowired
    private ServiceJeton serviceJeton;
    
    @Override
    public boolean preHandle(HttpServletRequest requete, HttpServletResponse reponse, Object handler) throws Exception {
        // Configuration CORS
        reponse.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
        reponse.setHeader("Access-Control-Max-Age", "3600");
        reponse.setHeader("Access-Control-Allow-Origin", requete.getHeader("Origin"));
        
        if (requete.getMethod().equalsIgnoreCase("OPTIONS")) {
            reponse.setStatus(HttpServletResponse.SC_OK);
            return false;
        }
        
        AnnotationIgnorerAuth annotationIgnorer;
        if (handler instanceof HandlerMethod) {
            annotationIgnorer = ((HandlerMethod) handler).getMethodAnnotation(AnnotationIgnorerAuth.class);
        } else {
            return true;
        }
        
        String tokenRecu = requete.getHeader(CLE_JETON);
        
        if (annotationIgnorer != null) {
            return true;
        }
        
        JetonEntity jetonValide = null;
        if (StringUtils.hasText(tokenRecu)) {
            jetonValide = serviceJeton.validerJeton(tokenRecu);
        }
        
        if (jetonValide != null) {
            requete.getSession().setAttribute("idUtilisateur", jetonValide.getIdUtilisateur());
            requete.getSession().setAttribute("role", jetonValide.getRole());
            requete.getSession().setAttribute("nomUtilisateur", jetonValide.getNomUtilisateur());
            return true;
        }
        
        reponse.setContentType("application/json;charset=UTF-8");
        reponse.getWriter().write("{\"erreur\": \"Authentification requise\", \"code\": 401}");
        return false;
    }
}

Structure de la base de données

La table principale pour la gestion des jetons d'accès est définie comme suit :

CREATE TABLE jetons_acces (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    id_utilisateur BIGINT NOT NULL,
    nom_utilisateur VARCHAR(100) NOT NULL,
    table_reference VARCHAR(100),
    role_utilisateur VARCHAR(100),
    jeton VARCHAR(200) NOT NULL,
    date_creation TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    date_expiration TIMESTAMP,
    INDEX idx_utilisateur (id_utilisateur),
    INDEX idx_jeton (jeton)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Des données exemple peuvent être insérées pour initialiser les sessions de test, avec des rôles différents tels que administrateur, vandeur et client.

Étiquettes: Spring Boot Vue.js uniapp MyBatis-Plus application mobile

Publié le 31 juillet à 17h15