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

news2024/9/24 21:23:36

添加购物车

  • 一、引言
  • 二、前端
    • 2.1引入轻组件
    • 2.2为图片添加点击事件
    • 2.3创建addShoppingCart函数
  • 三、后端
  • 四、运行效果
  • 五、导航条跳转

一、引言

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

二、前端

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

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属性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2067864.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

08 内置函数

目录 日期函数字符串函数数学函数其他函数 1. 日期函数 函数名称描述current_date&#xff08;&#xff09;当前日期current_time&#xff08;&#xff09;当前时间current_timestamp&#xff08;&#xff09;当前时间戳date(datetime)返回datetime参数的日期部分date_add(da…

Java 继承Thread 和 实现Runnable的关联

在java中创建线程的最常用的两种方法 1.继承Thread类 2.继承Runnable接口 但是实现了Runnable接口之后&#xff0c;这个类不能自己启动&#xff0c;需要将其传递给一个Thread实例对象&#xff0c;然后通过Thread对象的start() 方法进行启动&#xff0c;因为只有Thread类中的 …

【系统架构设计】软件架构设计(1)

【系统架构设计】软件架构设计&#xff08;1&#xff09; 软件架构概述架构需求与软件质量属性软件架构风格数据流风格批处理序列管道-过滤器2者风格比较 仓库风格--黑板系统 层次系统架构风格二层及三层C/S架构风格MVCMVP 面向服务的架构 软件架构概述 基于架构的软件开发模型…

无心剑中译莎士比亚《吾爱稀罕胜天仙》

莎士比亚十四行诗第130首 Sonnet 130 吾爱稀罕胜天仙 My mistress’ eyes are nothing like the sun; Coral is far more red than her lips’ red; If snow be white, why then her breasts are dun; If hairs be wires, black wires grow on her head. I have seen roses d…

C++相关概念和易错语法(29)(lambda、function、bind)

1.lambda lamba表达式本质是匿名函数 书写格式&#xff1a;[ 捕捉列表 ] ( 参数 ) mutable -> 返回值 { 函数体 } 下面我会由简到难分享lambda的用法和它的理解 &#xff08;1&#xff09;基本使用和理解 我们先来看一段代码 我认为第一次看这个表达式应该还是能够…

LeetCode.55.跳跃游戏(贪心算法思路)

题目描述&#xff1a; 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 输…

为什么大公司不愿意使用 Python 作为 Web 后端开发语言?

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storm…

使用uart串口配置TMC2209模块

串口配置的优点&#xff1a; 通过串口助手配置TMC2209的寄存器实现转速&#xff0c;方向&#xff0c;细分数等寄存器设置。最大细分可达256。 TMC2209串口配置数据发送格式&#xff1a; 通过数据手册可知&#xff0c;TMC2209写入数据需要发送64位16进制。 前面0~7位是同步保…

OpenStack云计算平台实战

项目一 任务一 了解云计算 目前主流的开源云计算平台如下&#xff1a; OpenStack。OpenStack是一个提供IAAS开源解决方案的全球性项目&#xff0c;由Rackspace公司和NASA共同创办&#xff0c;采用了Apache2.0许可证&#xff0c;可以随意使用。OpenStack并不要求使用专门的硬…

“走进孔子博物馆 赓续千年乐章”孔乐古筝专场音乐会圆满成功!

2024年8月11日下午&#xff0c;备受期待的“走进孔子博物馆 赓续千年乐章”孔乐古筝专场音乐会在孔子博物馆隆重举行。此次音乐会不仅吸引了众多古筝艺术爱好者前来观看&#xff0c;更是一次将中华传统文化精髓与现代艺术相结合的盛会。现场座无虚席&#xff0c;观众朋友们共同…

C语言基础(十三)

指针的用法&#xff1a; 测试代码1&#xff1a; #include "date.h" #include <stdio.h> #include <stdlib.h> int main() { int time getTime();int n 3, m 4; // 使用malloc函数动态分配n行的指针数组&#xff0c;并将其赋值给二级指针arr。…

链表的插入操作——CSP-J1真题详解

【题目】 假设有一个链表的节点定义如下: struct Node { int data; Node* next; }; 现在有一个指向链表头部的指针&#xff1a;Node* head。如果想要在链表中插入一个新的节点&#xff0c;其成员 data 的值为 42&#xff0c;并使新节点成为链表的第一个节点&#xff0c;下面…

LLM和VLM算法常见面试题

LLM相关问题&#xff1a; Bert和GPT的区别 Bert和GPT是两种不同类型的自然语言处理&#xff08;NLP&#xff09;模型&#xff0c;具有一些重要的区别。 模型架构&#xff1a;Bert是基于Transformer架构的模型&#xff0c;它是一个预训练的双向编码器。GPT也是基于Transformer…

【最大的和】

题目 思路 最大序列和的一般做法 dp前缀最大值 dp尾缀最大值 枚举分界点 代码 #include <bits/stdc.h> using namespace std;const int N 5e410; int a[N]; int um[N], dm[N], s; int main() {int t;cin >> t;um[0] INT_MIN;while(t--){int n;cin >> …

【Linux操作系统】进程间通信(1)

目录 一、认识进程间通信二、匿名管道三、命名管道 一、认识进程间通信 进程间不能直接传递数据&#xff0c;因为进程具有独立性&#xff0c;直接传递会破坏进程的独立性。 进程间通信是什么&#xff1f; 一个进程把自己的数据交给另一个进程。 为什么要有进程间通信&#xf…

ThreadLocal解惑

目录 1、ThreadLocal是什么? 2、ThreadLocal实现原理 3、设置线程变量的2种方式 4、关于ThreadLocal的内存泄漏问题 5、使用过程中的注意事项和误区 1、ThreadLocal是什么? 比较书面的回答&#xff1a; 类如其名&#xff0c;线程本地变量。当使用 ThreadLocal 维护变量时…

防爆巡检机器人:工业安全领域的璀璨明星

在当今快速发展的工业领域&#xff0c;安全与效率是企业追求的双核动力。特别是在石油、化工、钢铁冶金、燃气等高风险、高爆炸性的行业中&#xff0c;如何确保生产环境的绝对安全&#xff0c;同时提升巡检效率&#xff0c;成为了企业亟需解决的重大课题。正是在这样的背景下&a…

leetcode 438 找到字符串中所有字母异位词

leetcode 438 找到字符串中所有字母异位词 正文 正文 本题和 leetcode 49 字母异位分词 有些类似&#xff0c;只是 49 题中要求我们找出所有的异位词并进行存储&#xff0c;而本题我们只需要找出异位词对应的索引值。因此&#xff0c;我们无需用到字典&#xff0c;只需使用列表…

理解线程 ID 和 LWP

序言 在不同的系统中&#xff0c;为了更好地管理用户可能会采取不同的编号。比如在学校的教务系统中&#xff0c;管理学生使用的是学号&#xff1b;但是在住宿系统中&#xff0c;为了更加方便的获取一个学生的寝室信息&#xff0c;可能会采取结合你是哪一栋&#xff0c;哪一层&…

MindSearch 部署的到 Hugging Face Space

和原有的CPU版本相比区别是把internstudio换成了github codespace。 随着硅基流动提供了免费的 InternLM2.5-7B-Chat 服务&#xff08;免费的 InternLM2.5-7B-Chat 真的很香&#xff09;&#xff0c;MindSearch 的部署与使用也就迎来了纯 CPU 版本&#xff0c;进一步降低了部署…