发布于 2026-01-06 9 阅读
0

使用 MERN 技术栈构建电子商务网站 - 第 4 部分(购物车和订单)

使用 MERN 技术栈构建电子商务网站 - 第 4 部分(购物车和订单)

大家好!这是我们最近开始的MERN技术栈系列教程的第四部分。在第一部分中,我们学习了如何搭建项目,并了解了项目中将要用到的各种技术;在第二部分中,我们借助Mongoose和MongoDB开发了项目所需的所有模型。

在第三部分,我们开始构建 REST API,用于处理项目中的身份验证和商品信息。现在,在第四部分,我们将完成后端部分的构建,包括构建 REST API 来处理 Web 应用程序的购物车和订单功能,以及使用 Stripe Checkout 处理支付。

注意:我会在 Medium 网站上发布所有文章的完整详细版本。这里我会提供概述,并分部分提供各个页面的代码。
所以,请点击此处前往 Medium 阅读全文(这些是友情链接,所以不用担心付费墙。)

正如我们在上一部分中看到的,我们在根目录中创建了名为 routes 和 controllers 的文件夹。

我们还在每个文件夹内创建了四个文件——分别代表身份验证、商品、购物车和订单。

注意:本教程将只处理与购物车和订单相关的路由和控制器,因为我们在上一个教程中已经处理了身份验证和商品。

路线

购物车路线

const { Router } = require('express');
const cartController = require('../controllers/cartControllers');
const router = Router();

router.get('/cart/:id',cartController.get_cart_items);
router.post('/cart/:id',cartController.add_cart_item);
router.delete('/cart/:userId/:itemId',cartController.delete_item);

module.exports = router;
Enter fullscreen mode Exit fullscreen mode

订单路线

const { Router } = require('express');
const orderController = require('../controllers/orderControllers');
const router = Router();

router.get('/order/:id',orderController.get_orders);
router.post('/order/:id',orderController.checkout);

module.exports = router;
Enter fullscreen mode Exit fullscreen mode

控制器

购物车控制器

const Cart = require('../models/Cart');
const Item = require('../models/Item');

module.exports.get_cart_items = async (req,res) => {
    const userId = req.params.id;
    try{
        let cart = await Cart.findOne({userId});
        if(cart && cart.items.length>0){
            res.send(cart);
        }
        else{
            res.send(null);
        }
    }
    catch(err){
        console.log(err);
        res.status(500).send("Something went wrong");
    }
}

module.exports.add_cart_item = async (req,res) => {
    const userId = req.params.id;
    const { productId, quantity } = req.body;

    try{
        let cart = await Cart.findOne({userId});
        let item = await Item.findOne({_id: productId});
        if(!item){
            res.status(404).send('Item not found!')
        }
        const price = item.price;
        const name = item.title;

        if(cart){
            // if cart exists for the user
            let itemIndex = cart.items.findIndex(p => p.productId == productId);

            // Check if product exists or not
            if(itemIndex > -1)
            {
                let productItem = cart.items[itemIndex];
                productItem.quantity += quantity;
                cart.items[itemIndex] = productItem;
            }
            else {
                cart.items.push({ productId, name, quantity, price });
            }
            cart.bill += quantity*price;
            cart = await cart.save();
            return res.status(201).send(cart);
        }
        else{
            // no cart exists, create one
            const newCart = await Cart.create({
                userId,
                items: [{ productId, name, quantity, price }],
                bill: quantity*price
            });
            return res.status(201).send(newCart);
        }       
    }
    catch (err) {
        console.log(err);
        res.status(500).send("Something went wrong");
    }
}

module.exports.delete_item = async (req,res) => {
    const userId = req.params.userId;
    const productId = req.params.itemId;
    try{
        let cart = await Cart.findOne({userId});
        let itemIndex = cart.items.findIndex(p => p.productId == productId);
        if(itemIndex > -1)
        {
            let productItem = cart.items[itemIndex];
            cart.bill -= productItem.quantity*productItem.price;
            cart.items.splice(itemIndex,1);
        }
        cart = await cart.save();
        return res.status(201).send(cart);
    }
    catch (err) {
        console.log(err);
        res.status(500).send("Something went wrong");
    }
}
Enter fullscreen mode Exit fullscreen mode

订单控制员

const Order = require('../models/order');
const Cart = require('../models/Cart');
const User = require('../models/User');
const config = require('config');
const stripe = require('stripe')(config.get('StripeAPIKey'));

module.exports.get_orders = async (req,res) => {
    const userId = req.params.id;
    Order.find({userId}).sort({date:-1}).then(orders => res.json(orders));
}

module.exports.checkout = async (req,res) => {
    try{
        const userId = req.params.id;
        const {source} = req.body;
        let cart = await Cart.findOne({userId});
        let user = await User.findOne({_id: userId});
        const email = user.email;
        if(cart){
            const charge = await stripe.charges.create({
                amount: cart.bill,
                currency: 'inr',
                source: source,
                receipt_email: email
            })
            if(!charge) throw Error('Payment failed');
            if(charge){
                const order = await Order.create({
                    userId,
                    items: cart.items,
                    bill: cart.bill
                });
                const data = await Cart.findByIdAndDelete({_id:cart.id});
                return res.status(201).send(order);
            }
        }
        else{
            res.status(500).send("You do not have items in cart");
        }
    }
    catch(err){
        console.log(err);
        res.status(500).send("Something went wrong");
    }
}
Enter fullscreen mode Exit fullscreen mode

好了,第四部分就到这里。我们终于总结了本系列的后端部分,接下来将从下一篇教程开始讲解客户端,也就是 React 和 Redux 代码。

要阅读完整教程,请前往 Medium 阅读完整文章

文章来源:https://dev.to/shubham1710/build-an-e-commerce-website-with-mern-stack-part-4-cart-and-orders-9mb