7.添加购物车以及完善导航条跳转

一、引言

在前几篇文章中,我们一步一步慢慢的实现了项目的建立,从数据库获取数据显示在页面,商品大图查看,查询和商品分页功能,以及登录退出,涉及一些模态框和轻组件的使用。到这里应该对于前后端的数据的交互比较了解了,从后端到前端再到我们所看见的网页,就是这样一步一步建立起来的。
你眼中所看到的效果功能是怎么实现的,
在学习的过程中,会逐渐发现很多代码其实都是做重复的动作,只是对于细节的处理逻辑略有不同。
我们学习这个项目,并不是单单学习怎么去做这么个商城项目,我们更多的是学他们的代码的逻辑,前后端怎么一起实现的功能,去理解代码为什么这么写,去学习他们代码的架构,层次。一句话,学习怎么学习!

二、前端

现在我们来实现添加购物车:把商品添加到购物车中去。
目的:用户点击商品卡片那个购物小车,完成该商品的购物车添加,针对成功与否提示相关信息。

2.1引入轻组件

在首页index.html,根据自己网页来,引入轻组件用来提示操作信息,前面也引入过,不多叙述了。
两步:

  1. 引入组件代码。
<div class="toast-container position-fixed top-0 start-50 translate-middle-x mt
1">
    <div id="toast" class="toast opacity-100 bg-white">
        <div class="toast-header">
            <strong class="me-auto"></strong>
            <button type="button" class="btn-close" data-bs-dismiss="toast">
            </button>
        </div>
        <div class="toast-body"></div>
    </div>
</div>
  1. 组件转换对象,创建函数来自定义显示提示。
    //创建轻组件对象
    const toastObj = new bootstrap.Toast(document.querySelector(`#toast`), {delay: 2200});

    const toast = (title = "信息", msg = "") => {
        document.querySelector('#toast .me-auto').innerHTML = title;
        document.querySelector('#toast .toast-body').innerHTML = msg;
        toastObj.show();
    }

2.2为图片添加点击事件

<img onclick="addShoppingCart(${list[i].meal_id})" 
src="./images/shopping-cart.png" style="height:35px;cursor: pointer;" 
class="pe-1">

这里是为小车图片添加onclick属性,实现点击调用添加购物车函数。
其中参数是商品的id,从list对象中获取,list是我们在getMealList函数中建立的:
const list = pageObj.recList;
而其中recList中数据是这样的:
在这里插入图片描述
在这里给大家回忆一下,避免产生疑惑哪来的list[i]。

2.3创建addShoppingCart函数

接下来,在上面调用了addShoppingCart函数,所以现在来实现这个函数。

 const addShoppingCart = async(meal_id) => {
        const resp = await fetch(`./meal/add-cart?meal_id=${meal_id}`);
        if (!resp.ok) return;
        const result = await resp.json();
        if (!result.success) {
            toast("错误", result.message);
            console.log("错误", result.message);
            return;
        }
        toast("成功", "加购物车成功");
    };
  1. 将meal_id通过fetch函数,指定路径包含参数像后端发起请求,返回响应。
  2. 判断响应状态,解析json数据,判断数据对象,根据result.success做出不同的提示,调用组件函数显示不同的提示。

前面类似的写过,所以这里简单叙述。
前端就完成了。
现在来实现后端的逻辑。

三、后端

  1. 老规矩,一个新的功能方法,我们先添加新的路径在WebServlet注解中:
  "/meal/add-cart"
  1. 在判断路径的switch分支结构中也加上新的case板块:
            case "/meal/add-cart":
                mealAddCart(req, resp);
                break;
  1. 最后实现mealAddCart函数:
 private void mealAddCart(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        User user = (User) req.getSession().getAttribute("CurrUser");
        if (user == null) {
            MyWeb.printJson(resp, R.err("请先登录!"));
            return;
        }
        String meal_id = req.getParameter("meal_id");
        String selSql = "select sm_store from t_meal where meal_id = ?";
        Dao dao = DaoCreater.currentDao();
        int meal_num = dao.queryInteger(selSql, meal_id);
        if (meal_num < 1) {
            MyWeb.printJson(resp, R.err("库存不足!"));
            return;
        }
        String updSql = "update t_shoppingcart set s_num = s_num + 1 where u_id = ? and meal_id = ?";
        int count = dao.update(updSql, user.getU_id(), meal_id);
        if (count == 0) {
            String insSql = "insert into t_shoppingcart (u_id,meal_id,s_num) values(?,?,1)";
            dao.update(insSql,user.getU_id(),meal_id);
        }
        MyWeb.printJson(resp,R.OK());
    }
  1. 加购物车之前我们得判断有没有用户信息,也就是有没有登录,没有就要在返回的响应中告诉前端,让前端来处理。
    如果登录了,就开始获取请求中包含的数据。其中getParameter 方法返回与指定参数名称相关联的值。如果请求中不存在该参数,它将返回 null。通常用于从表单提交或URL中读取用户输入的数据,然后根据这些数据进行进一步的处理。我们在URL中参数名是meal_id,所以我们指定获取参数meal_id。
  2. 定义sql语句用来查询数据库中的库存量,sm_store是我们在数据库存储库存量的变量名,在这里? 是一个占位符,用于后续的参数绑定以防止SQL注入攻击,queryInteger(selSql, meal_id);会执行sql语句进行数据库查询,meal_id会取代?的位置组成完整的sql语句。
  3. 接下来判断获取的库存量,没有了就返回响应告诉前端,我没货了,让前端在告诉用户。如果有库存就进行继续。
  4. 既然库存有,那么我们就要像购物车中更新数据,没数据就添加数据。
    查询t_shoppingcart表中指定u_id和meal_id的s_num,就是说查找这个用户有没有这款商品,有就让数量加一,没有就就什么也不做,在这里count是所影响的行数。
  5. 后续判断等于0,那么说明u_id和meal_id相关联的数据没有,也就是此前这个用户没添加过该商品到购物车。所以向表中u_id和meal_id相关联的s-num数据设置为一,执行sql操作。
    最后完成后返回包含成功的响应给前端处理。
    到这里就完成了。
    可以启动项目查找bug了[坏笑],如果运行不成功的话。

其实这里有个疑问,购物车数据增加了,库存的数据是不是应该减少相应的,后续再说吧。

四、运行效果

  1. 没登录之前添加购物车:
    在这里插入图片描述
  2. 登陆后添加购物车:
    在这里插入图片描述
    还有库存不足,应该也没有问题。那么就基本实现了。

五、导航条跳转

在首页我们还有一些导航条没实现跳转,以及其他页面跳转需要完成,同时getCurrUser函数也需要复制到其他页面以显示当前用户,我们先完成这些繁琐的工作。
看过前面的应该自己就会加了,这里直接上部分代码为例:

        <ul class="nav nav-pills ms-5">
            <li class="nav-item">
                <a class="nav-link bg-white text-danger fw-bolder" href="index.html">首页</a>
            </li>
            <li class="nav-item">
                <a class="nav-link text-white" href="cart.html">购物车</a>
            </li>
            <li class="nav-item">
                <a class="nav-link text-white" href="order.html">订单</a>
            </li>
        </ul>

在href属性添加其他相应网页html文件就行了。
提一句:这里这些都是<a标签的,所以自带超链接,不需要像按钮那样加onclick属性。

  • 16
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于node.js的购物车系统可以通过以下步骤实现: 1. 首先,需要安装node.js和npm包管理器。可以在官网上下载安装包,也可以使用命令行安装。 2. 创建一个新的node.js项目,并使用npm安装所需的依赖包,例如express、body-parser、mysql等。 3. 设计数据库结构,并使用mysql创建相应的表格。 4. 创建服务器,并使用express框架处理HTTP请求和响应。可以使用路由来处理不同的URL请求。 5. 实现用户注册和登录功能,可以使用session来保存用户信息。 6. 实现商品搜索和展示功能,可以使用mysql数据库来存储商品信息,并使用模板引擎来渲染页面。 7. 实现购物车功能,可以使用session来保存用户的购物车信息,并使用ajax来实现添加、删除、修改购物车商品的功能。 8. 实现订单功能,可以使用mysql数据库来存储订单信息,并使用模板引擎来渲染订单页面。 9. 最后,进行测试和部署。 以下是一个简单的node.js购物车系统的代码示例: ```javascript // 引入依赖包 const express = require('express'); const bodyParser = require('body-parser'); const session = require('express-session'); const mysql = require('mysql'); // 创建服务器 const app = express(); // 设置中间件 app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()); app.use(session({ secret: 'shoppingcart', resave: false, saveUninitialized: true, cookie: { secure: false } })); // 连接数据库 const connection = mysql.createConnection({ host: 'localhost', user: 'root', password: 'password', database: 'shoppingcart' }); connection.connect(); // 处理用户注册请求 app.post('/register', (req, res) => { const { username, password } = req.body; const sql = `INSERT INTO users (username, password) VALUES ('${username}', '${password}')`; connection.query(sql, (err, result) => { if (err) throw err; res.send('注册成功'); }); }); // 处理用户登录请求 app.post('/login', (req, res) => { const { username, password } = req.body; const sql = `SELECT * FROM users WHERE username='${username}' AND password='${password}'`; connection.query(sql, (err, result) => { if (err) throw err; if (result.length > 0) { req.session.user = result[0]; res.send('登录成功'); } else { res.send('用户名或密码错误'); } }); }); // 处理商品搜索请求 app.get('/search', (req, res) => { const { keyword } = req.query; const sql = `SELECT * FROM products WHERE name LIKE '%${keyword}%'`; connection.query(sql, (err, result) => { if (err) throw err; res.render('search', { products: result }); }); }); // 处理添加购物车请求 app.post('/addtocart', (req, res) => { const { product } = req.body; if (!req.session.cart) { req.session.cart = []; } req.session.cart.push(product); res.send('添加成功'); }); // 处理查看购物车请求 app.get('/cart', (req, res) => { const { cart } = req.session; res.render('cart', { cart }); }); // 处理提交订单请求 app.post('/submitorder', (req, res) => { const { cart } = req.session; const sql = `INSERT INTO orders (user_id, products) VALUES (${req.session.user.id}, '${JSON.stringify(cart)}')`; connection.query(sql, (err, result) => { if (err) throw err; req.session.cart = []; res.send('提交成功'); }); }); // 启动服务器 app.listen(3000, () => { console.log('Server started on port 3000'); }); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值