Plateforme de commande de produits culturels créatifs basée sur Java Spring Boot et mini-programme WeChat

Ce projet propose une solution e-commerce pour les produits culturels créatifs en combinant Java Spring Boot (backend) et un mini-programme WeChat (frontend). L'objectif est de résoudre les problèmes de présentation limitée, de gestion désordonnée des commandes et de faible engagement des utilisateurs. Le système offre une expérience personnalisée et scénarisée pour la vente et la diffusion des produits culturels.

Architecture technique

  • Backend : Java Spring Boot, gestion des API REST, couche métier pour produits, commandes, stocks et analyse des besoins utilisateur.
  • Frontend : Mini-programme WeChat (Vue.js pour la logique, WXML/WXSS pour l'interface).
  • Base de données : MySQL pour les données structurées (produits avec catégories, prix, stock ; commandes avec statut de paiement, adresse de livraison, suivi logistique).
  • Cache : Redis pour les produits populaires et l’historique de navigation, améliorant la réactivité en haute charge.

Modules principaux

  • Affichage des produits : présentation par images, vidéos courtes, avec filtres par IP, catégories.
  • Commande en ligne : achat en un clic, paiement intégré, possibilité de laisser des remarques personnalisées.
  • Suivi de commande : mise à jour en temps réel du statut, notifications de livraison et de réception.
  • Interaction IP : informations sur les IP culturelles, partage des produits généré par l’utilisateur pour renforcer la notoriété.

Extrait de code : API d'authentification

@RestController
@RequestMapping("/api/auth")
public class AuthController {

    @Autowired
    private UserService userService;

    @Autowired
    private TokenService tokenService;

    @PostMapping("/login")
    public R login(@RequestParam String login, @RequestParam String motDePasse, HttpServletRequest req) {
        // Vérification de l'utilisateur
        UserEntity user = userService.getUserByLogin(login);
        if (user == null || !user.getMotDePasse().equals(motDePasse)) {
            return R.erreur("Identifiant ou mot de passe incorrect");
        }
        // Génération du token
        String token = tokenService.genererToken(user.getId(), login, "users", user.getRole());
        return R.ok().mettre("token", token);
    }
}

@Service
public class TokenService {

    @Autowired
    private TokenRepository tokenRepo;

    public String genererToken(Long userId, String username, String tableName, String role) {
        TokenEntity existing = tokenRepo.findByUserIdAndRole(userId, role);
        String nouveauToken = UUID.randomUUID().toString().replace("-", "").substring(0, 32);
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        cal.add(Calendar.HOUR_OF_DAY, 1); // Expire dans 1h

        if (existing != null) {
            existing.setToken(nouveauToken);
            existing.setDateExpiration(cal.getTime());
            tokenRepo.save(existing);
        } else {
            tokenRepo.save(new TokenEntity(userId, username, tableName, role, nouveauToken, cal.getTime()));
        }
        return nouveauToken;
    }
}

Intercepteur de validation de token

@Component
public class TokenInterceptor implements HandlerInterceptor {

    public static final String HEADER_TOKEN = "Authorization";

    @Autowired
    private TokenService tokenService;

    @Override
    public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object handler) throws Exception {
        // Gérer CORS
        resp.setHeader("Access-Control-Allow-Origin", req.getHeader("Origin"));
        resp.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        resp.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
        if (req.getMethod().equals("OPTIONS")) {
            resp.setStatus(HttpStatus.OK.value());
            return false;
        }

        // Vérifier si l'endpoint nécessite une authentification
        if (handler instanceof HandlerMethod) {
            IgnoreAuth ignore = ((HandlerMethod) handler).getMethodAnnotation(IgnoreAuth.class);
            if (ignore != null) return true;
        }

        String token = req.getHeader(HEADER_TOKEN);
        if (token != null && !token.isEmpty()) {
            TokenEntity entity = tokenService.getToken(token);
            if (entity != null) {
                req.getSession().setAttribute("userId", entity.getUserId());
                req.getSession().setAttribute("role", entity.getRole());
                req.getSession().setAttribute("tableName", entity.getTableName());
                req.getSession().setAttribute("username", entity.getUsername());
                return true;
            }
        }

        // Réponse JSON 401
        resp.setContentType("application/json; charset=UTF-8");
        resp.setStatus(401);
        resp.getWriter().write("{\"code\":401,\"message\":\"Veuillez vous connecter\"}");
        return false;
    }
}

Structure de la table token (MySQL)

DROP TABLE IF EXISTS `session_token`;
CREATE TABLE `session_token` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'Identifiant',
  `utilisateur_id` bigint(20) NOT NULL COMMENT 'ID utilisateur',
  `nom_utilisateur` varchar(100) NOT NULL COMMENT 'Nom d'utilisateur',
  `nom_table` varchar(100) DEFAULT NULL COMMENT 'Nom de la table source',
  `role` varchar(100) DEFAULT NULL COMMENT 'Rôle',
  `token` varchar(200) NOT NULL COMMENT 'Token',
  `date_creation` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `date_expiration` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;

-- Exemple d'insertions
INSERT INTO `session_token` VALUES (1, 23, 'cd01', 'etudiant', 'Etudiant', 'abc123def456', '2023-02-23 21:46:45', '2023-03-15 14:01:36');
INSERT INTO `session_token` VALUES (2, 1, 'admin', 'users', 'Administrateur', 'xyz789ghi012', '2023-02-27 19:37:01', '2023-03-17 18:23:02');

Étiquettes: SpringBoot mini-programme-wechat MybatisPlus vue MySQL

Publié le 20 juin à 16h36