繁体   English   中英

如何增加/减少购物车中产品的数量?

[英]How to increase / decrease the quantity of a product in a shopping cart?

我在实现从购物车中添加或删除产品的逻辑时遇到了一些困难。

首先在我的数据库级别:

  • 每个购物篮包括:购物篮 ID、产品 ID、客户 ID 和数量。

这意味着用户实际上有“几个篮子”(一个产品=一个篮子)

后端

以下是我如何使用 sequelize 创建模型/关系:

 // Inside db.config.js db.paniers = sequelize.define('panier', { id: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true, field: 'PAN_ID' }, userId: { type: Sequelize.INTEGER, references: { model: db.users, key: 'USE_ID' }, primaryKey: true, allowNull: false, field: 'USE_ID' }, produitId: { type: Sequelize.INTEGER, references: { model: db.produits, key: 'PRO_ID' }, primaryKey: true, allowNull: false, field: 'PRO_ID' }, quantite: { type: Sequelize.INTEGER, allowNull: false, field: 'PAN_QUANTITE' } }, { tableName: 'PANIER' });

然后对于查询,进行两个查询:

  • 一个显示关于购物车的信息(购物车 ID、产品 ID、产品名称、产品价格、产品图片、购物车数量)

  • 另一个更新数量。

这是我如何进行 axios 查询和 POSTMAN 下的结果

 const APIURL = 'http://localhost:8090/api'; // Get the details of the cart export const getDetails = (userId) => axios.get(`${APIURL}/panier/details/${userId}`, { userId: userId, }); // Update the quantity of the cart export const updateQuantite = (produitId) => axios.put(`${APIURL}/panier/${produitId}`, { produitId: produitId, });

 // Result for the userId 1 (getDetails) { "PRO_ID": 1, "PRO_NOM": "Un immeuble", "PRO_PRIX": "1515", "PRO_URL": "58afa4f2-41b1-42f7-a371-6d267784c44e.jpg", "PAN_QUANTITE": 1, "PAN_ID": 1 }, { "PRO_ID": 2, "PRO_NOM": "Model", "PRO_PRIX": "102", "PRO_URL": "a76fbe76-a183-49fa-84ee-40d5da08b91f.png", "PAN_QUANTITE": 1, "PAN_ID": 2 }

这是我的两个控制器管理他的路线:

 // Display the informations of the basket exports.getDetails = (req, res) => { const queryResult = db.sequelize.query( 'SELECT P.PRO_ID, PRO_NOM, PRO_PRIX, PRO_URL, PA.PAN_QUANTITE, PA.PAN_ID\n' + 'FROM panier AS PA INNER JOIN produit AS P ON PA.PRO_ID = P.PRO_ID\n' + 'WHERE USE_ID =:id', { replacements: { id: req.params.userId }, type: QueryTypes.SELECT } ).then(panier => { res.json(panier); }).catch(err => res.status(400).send(err)); } // Modify the quantity of a basket exports.update = (req, res) => { Paniers.update({ quantite: req.body.quantite }, { where: { produitId: req.params.produitId } }).then(panier => { res.json(panier); }).catch(err => res.status(400).send(err)); }

前端

这就是我的信息的显示方式(仍在开发中,这就是为什么它看起来不像任何东西^^')

为用户显示 2 个篮子,带有 2 个按钮:加号和减号

这是我迷路的地方......这是我的购物车pagePage.js:

 import React, { useState, useEffect } from 'react'; import { Card, CardHeader, CardMedia, Grid, ButtonGroup, Button} from '@material-ui/core'; import PayPal from '../services/PayPal/paypal' import {getDetails, updateQuantite, getAllPanier, get} from '../services/API/panier' export default function PanierPage() { // Récupération des détails des paniers const [paniers, setPaniers] = useState([]) const getPaniersDetails = () => [ getDetails(JSON.parse(localStorage.getItem('User')).id).then(response => { setPaniers(response.data) console.log(response) }).catch(err => console.log(err)) ] const handleIncrement = (id) => { updateQuantite(id).then(response => { //??? }).catch(err => console.log(err)) } const handleDecrement = () => { } // Affichage des détails des paniers const paniersAffichage = paniers.map((panier) => ( <Grid container> <Card key={panier.PAN_ID}> <CardHeader title={panier.PRO_NOM}/> <CardMedia image={`http://localhost:8090/${panier.PRO_URL}`}/> <Button onClick={() => handleIncrement(panier.PRO_ID)}> + </Button> {panier.PAN_QUANTITE} <Button onClick={handleDecrement}> - </Button> </Card> </Grid> )); // Chargement des produits useEffect(() => { getPaniersDetails(); }, []) return ( <> <Grid> {paniersAffichage} </Grid> <PayPal/> </> ); }

解释:

  • 我在“getPaniersDetails”中获取我的购物篮信息,我在其中指出用户 ID,然后将其加载到我的 useEffect 中。

  • basketsDisplay 允许我显示相关用户的购物篮。

  • 我在每张卡片中为映射提供购物车的 ID,然后显示信息……点击“+”时,我想增加数量,所以我给它提供了产品 ID。

  • 因此,handleIncrement 将使用“updateQuantite”处理此操作。

  • 这就是我阻止的地方,我觉得自己在不同的 ID 之间混在一起。 特别是在表的购物车 ID 和我的查询(SELECT)的购物车 ID 之间

我敢肯定,设置起来非常简单,但在我看来,这对我来说似乎很复杂......

如果我错过了任何重要的点告诉我,我会尽力改变我的帖子

您的 object model 没有多大意义。

我会改变它以使其更具活力。

如果您有用户,并且他们有一个购物篮属性,那么这种方法更有意义。

注意:下面的代码是一个粗略的大纲,但应该让您知道如何去做。

interface Database {
    users: User[]; // Array of users.
}

interface User {
    id: number;
    username: string;
    passwordHash: string;
    baskets: Basket[];
}

interface Basket {
    id: number;
    items: Item[]; // array of items;
    date: string;
}

interface Item {
    id: number; // ID of the item.
    name: string;
    imgURL: string;
    description: string[];
    quantity: number;
}

现在,如果我们想要接收数据并将数据发送到数据库,我们会这样做。

interface Basket {
    items: string[]; // list of item id's.
}

// You want to use a session token instead of the user id so noone but the user can access their basket. 
// Normaly baskets will be local to the browser or app and not sored on a servers database. 
// Only past orders should be stored. But in this example, we are storing the current basket too.
async function getBasket(sessionToken: string){
    return await axios.get(`${api.host}/basket`, { 
        headers: {
            Session-Token: sessionToken, // used to identify the user
            Content-Type: "application/json",
        }
    }).data;
}

// we send the basket object, which is just a list of IDs, and the session token.
async function setBasket(basket: Basket, sessionToken: string){
    return await axios.put(`${api.host}/basket`, { 
        headers: {
            Session-Token: sessionToken, // used to identify the user
            Content-Type: "application/json",
        }
    }).data;
}

现在在服务器端,我们可以使用 express 处理请求。

要使用 express 实现会话,有 npm 模块express-session ,它是 express 的中间件。 当用户登录时,他们将获得一个 header,他们将把它保存为 cookie 以用于他们未来的请求。 当他们注销时,session 将从您的服务器中删除,并且 cookie 在客户端上被删除。

为了增加安全性,您可以在 session 上设置过期时间。 用户必须重新登录并获得新的 session。


// check the documentation to tune it to what you need.
app.use(session({
  secret: 'mySuperSecret',
  resave: false,
  saveUninitialized: true,
  cookie: { secure: true }
}))

app.get("/basket", async(req, res) => {
    // here we first check if the session exists.
    if(req.session.views){
        // if it does, then we return the list of baskets.
        const { baskets } = await getUser(req.session.userID);
        res.sendStatus(200).send([success: true, data: baskets]);
    }
    // if not, then we will return a 403 error.
    // we also send a response that matches the layout of the normal response.
    res.sendStatus(403).send([success: false, data: []]);
    
})

app.put("/basket", (req, res) => {
    // here we first check if the session exists.
    if(req.session.views){
        // if it does, then we add the basket to the user.
        addBasket(req.session.userID, basket)
            .then(res.sendStatus(204).send([success: true, data: []]))
    }
    // if not, then we will return a 403 error.
    // we also send a response that matches the layout of the normal response.
    res.sendStatus(403).send([success: false, data: []]);
})

如果您有任何问题,请在评论部分提出。 我有空时会回复。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM