11.购物车页面下订单

一、前端处理

1. 引入订单模态框

引入模态框组件,增加交互体验:

<div class="modal modal-lg fade" id="orderModal">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h1 class="modal-title fs-5 text-danger fw-bold">确认订单</h1>
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
            </div>
            <div class="modal-body" id="orderContent">
                <table class="table align-middle">
                    <thead>
                    <tr>
                        <th class="px-3" style="width: 120px;">餐品</th>
                        <th style="width: 300px;">描述</th>
                        <th>价格</th>
                        <th>数量</th>
                    </tr>
                    </thead>
                    <tbody id="orderList">
                     <tr>
                <td class="p-2">
                    <img src="meal/pic?meal_pic=food01.jpeg" class="rounded" 
style="width:100px;" />
                </td>
                <td >
                  XXX
                </td>
                <td class=" fs-5 text-danger">
                  ¥50
                </td>
                <td>
                  2                
                </td>
            </tr>
                    </tbody>
                </table>
            </div>
            <div class="modal-footer">
                <div id="orderInfo" class="align-middle"></div>
                <button id="payingBtn" class="btn btn-danger" style="display: none;"
                        type="button" disabled>
                    <span class="spinner-border spinner-border-sm"></span>
                    <span>支付中...</span>
                </button>
                <button id="payBtn" type="button" class="btn btn-danger" style="display:block;">
                确认支付
                </button>
            </div>
        </div>
    </div>
</div>

2.创建模态框对象、添加事件响应函数、定义下订单函数

创建模态框对象,转化为对象才可以使用模态框组件:

    const orderModal = new bootstrap.Modal(document.querySelector("#orderModal"));

在购物车页面,为下订单按钮添加事件响应函数:

	<button onclick="placeOrder()" type="button" class="btn btn-warning text-white" style="width:100px;">下订单

最后在购物车页面js部分,定义下订单函数,也就是实现下订单哪里调用的函数:

    const placeOrder = async () => {
        let total = 0;
        let totalPrice = 0;
        const boxes = document.querySelectorAll(".my-box:checked");
        if (!boxes.length) {
            toast("错误!", "请选择要购买的商品!");
            return;
        }
        const idArgs = [...boxes].map(box => `meal_id=${box.value}`).join("&");
        const resp = await fetch(`cart/chklist?${idArgs}`);
        if (!resp.ok) {
            toast("错误!", "查询失败!");
            return;
        }
        const result = await resp.json();
        if (!result.success) {
            toast("失败!", result.message);
            return;
        }
        const chklist = result.data;
        let innerHTML = ``;
        for (let i = 0; i < chklist.length; i++) {
            const meal = chklist[i];
            total += meal.s_num;
            totalPrice += meal.s_num * meal.meal_price;
            innerHTML += ` <tr>
                        <td class="p-2">
                            <img src="meal/pic?meal_pic=${meal.meal_pic}" class="rounded"
                                 style="width:100px;"/>
                        </td>
                        <td>
                            ${meal.meal_desc}
                        </td>
                        <td class=" fs-5 text-danger">
                            ¥${meal.meal_price}
                        </td>
                        <td>
                            ${meal.s_num}
                        </td>
                    </tr>`;
        }
        document.querySelector("#orderList").innerHTML = innerHTML;
        document.querySelector("#orderInfo").innerHTML = `<span class="align-middle">已选</span>
                    <span class="text-danger align-middle">${total}</span>
                    <span class="align-middle">件,总价</span>
                    <span class="fw-bold fs-3 text-danger align-middle">¥${totalPrice}</span>`;
        orderModal.show();
    }

对一些关键代码进行解释:

  1. let total = 0; 和 let totalPrice = 0;:初始化两个变量,分别用于存储选中商品的数量总和和价格总和。

  2. const boxes = document.querySelectorAll(".my-box:checked");:使用 querySelectorAll 方法选择所有被选中的 .my-box 元素(通常是复选框),这些元素代表用户想要购买的商品。

3. if (!boxes.length) {:检查是否有商品被选中。如果没有,显示一个错误提示,并返回,不继续执行函数。

  1. const idArgs = [...boxes].map(box => meal_id=${box.value}).join("&");:将选中的商品的 value 属性(也就是商品的ID)转换成查询字符串格式,用于后续的请求,向后端传达参数。

  2. const resp = await fetch(cart/chklist?${idArgs});:使用 fetch 方法向服务器发送请求,获取选中商品的详细信息。请求的URL包含了之前生成的查询字符串。

6. if (!resp.ok) {:检查响应是否成功。如果不成功,显示错误提示,并返回。

  1. const result = await resp.json();:解析响应的JSON数据。

  2. if (!result.success) {:检查从服务器返回的结果是否表示成功。如果不成功,显示错误提示,并返回。

  3. const chklist = result.data;:获取服务器返回的商品列表。

  4. let innerHTML = ``;:初始化一个字符串,用于构建订单列表的HTML内容。

  5. for (let i = 0; i < chklist.length; i++) {:遍历商品列表,为每个商品构建HTML表格行。

在循环内部,构建每个商品的HTML表格行,包括商品图片、描述、单价和数量。
也就是在引入的模态框中orderList元素的静态内容如下,在循环中做成动态的,获取每一个商品:

<tr>
                <td class="p-2">
                    <img src="meal/pic?meal_pic=food01.jpeg" class="rounded" 
style="width:100px;" />
                </td>
                <td >
                  XXX
                </td>
                <td class=" fs-5 text-danger">
                  ¥50
                </td>
                <td>
                  2                
                </td>
            </tr>

  1. document.querySelector("#orderList").innerHTML = innerHTML;:将构建好的HTML表格行插入为 #orderList 元素的内容,显示订单列表。

  2. document.querySelector("#orderInfo").innerHTML = ...:更新订单信息,包括已选商品的数量和总价,也是用反引号拼接模态框中orderInfo元素的内容,获取动态数据。

  3. orderModal.show();:显示订单模态框,通常是一个弹出窗口,用于让用户确认订单详情。

整个函数的流程是:检查用户是否选择了商品,获取商品信息,构建订单列表和订单信息,最后显示订单模态框供用户确认。

二、后端处理

关于购物车功能的实现,所以在CartServlet类中进行。依旧三步法,修改代码逻辑就好了。

2.1加注解路径,加case子块

增加路径 “/cart/chklist”,来调用新的方法:

 @WebServlet({
        "/cart/list",
        "/cart/num",
        "/cart/del",
        "/cart/chklist"
 })

相应的增加新的case子块:

case "/cart/chklist":
                cartChkList(req,resp);
                break;

最后实现调用的函数。

2.1 实现cartChkList函数

    private void cartChkList(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        {
            User user = (User) req.getSession().getAttribute("CurrUser");
            if (user == null) {
                MyWeb.printJson(resp, R.err("请先登录"));
                return;
            }
            String[] mealIds = req.getParameterValues("meal_id");
            if (mealIds == null || mealIds.length == 0) {
                MyWeb.printJson(resp, R.err("请选择商品!"));
                return;
            }
            String condition = Arrays.stream(mealIds).map(id -> "s.meal_id=" + id).collect(Collectors.joining(" or "));
            List<ShoppingCart> list = DaoCreater.currentDao().queryBeanList(ShoppingCart.class, "select s.*, m.meal_desc,m.meal_pic,m.meal_price from t_shoppingcart s join t_meal m on s.meal_id = m.meal_id where u_id = ? and (" + condition + ")", user.getU_id());
            MyWeb.printJson(resp, R.OK(list));
        }

    }

在函数中,代码也是异常的熟悉,主要流程是判断登录状态,判断商品选中状态,获取数据(参数),执行数据库操作,返回响应(包含数据信息)。

  1. User user = (User) req.getSession().getAttribute("CurrUser");:从HTTP请求的会话中获取当前登录的用户对象。

  2. if (user == null) {:检查用户是否已经登录。如果用户未登录,返回一个错误信息,并终止方法的执行。

  3. String[] mealIds = req.getParameterValues("meal_id");:从HTTP请求中获取名为 meal_id 的参数值,这个参数通常是由前端发送的,包含了用户想要查询的商品ID。

4. if (mealIds == null || mealIds.length == 0) {:检查是否有商品ID被发送。如果没有,返回一个错误信息,并终止方法的执行。

  1. String condition = Arrays.stream(mealIds).map(id -> "s.meal_id=" + id).collect(Collectors.joining(" or "));:将商品ID数组转换为SQL查询条件字符串,用于后续的数据库查询。每个ID都被转换成 s.meal_id=某个ID 的形式,并且使用 or 连接,以便查询任何一个匹配的商品。关于这行代码,在上一篇文章中有更详细的解释,这里就不在重复解释了。

  2. List<ShoppingCart> list = DaoCreater.currentDao().queryBeanList(ShoppingCart.class, ...);:使用DAO(Data Access Object)模式查询数据库,获取购物车中的商品信息。查询包括购物车表 t_shoppingcart 和商品表 t_meal 的连接查询,条件是用户ID和商品ID。

  3. MyWeb.printJson(resp, R.OK(list));:将查询结果包装在一个响应对象中,并以JSON格式发送回客户端。

打这里购物车下订单操作就完成了。
用户选择商品点击下订单,会跳出模态框让用户确认,在模态框中进行支付然后加到订单页面中去,数据库中数据也会对应变化。
模态框中的操作在下一篇文章中进行…

  • 9
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
由于提供微商城项目的所有代码过于庞大,无法在这里一一展示。但是,我可以提供一些参考代码和思路,帮助你完成微商城项目的创建和开发。 首先,你需要在电脑目录中完成微商城项目的创建。在命令行中输入以下命令即可创建名为wxshop的微商城项目: ``` vue create wxshop ``` 然后按照提示选择自己需要的配置即可。接下来进入wxshop项目的目录中,输入以下命令安装所需的依赖: ``` cd wxshop npm install ``` 安装完成后,即可在该项目中进行开发和实现微商城的各种功能。接下来,我们来看一下微商城项目的设计和实现。 一、商城首页 商城首页需要实现新闻资讯栏目、图片分享功能和商品购卖功能。其中,新闻资讯栏目可以展示最新的商城资讯、图片分享功能可以展示商城中的图片并进行分享,商品购卖功能可以实现商城中的商品购买和销售。 1. 新闻资讯栏目的设计与实现 在首页中添加一个新闻资讯栏目,用来展示商城的最新资讯。可以通过调用后台接口获取最新的资讯,并将其展示在页面中。 2. 图片分享功能的设计与实现 在首页中添加一个图片分享功能,用来展示商城中的图片并进行分享。可以通过调用后台接口获取商城中的图片,并将其展示在页面中。用户可以选择将图片分享到自己的社交媒体账号上。 3. 商品购卖功能的设计与实现 在首页中添加一个商品购卖功能,用来实现商城中的商品购买和销售。可以通过调用后台接口获取商城中的商品信息,并将其展示在页面中。用户可以选择购买商品并进行支付操作。 二、分类 分类需要实现商品分类列表,以便用户可以浏览和选择自己感兴趣的商品分类。 1. 商品分类列表的设计与实现 在分类页面中展示商品的分类列表。可以通过调用后台接口获取商品分类信息,并将其展示在页面中。用户可以选择自己感兴趣的商品分类,并查看该分类下的所有商品信息。 三、我的 我的需要实现登录和注册功能、收货地址功能和订单列表功能。其中,登录和注册功能可以让用户注册和登录商城账号,收货地址功能可以让用户添加和管理自己的收货地址,订单列表功能可以让用户查看和管理自己的订单信息。 1. 登录和注册功能的实现 在我的页面中添加登录和注册功能。用户可以通过输入自己的账号和密码进行登录或注册操作。可以通过调用后台接口实现登录和注册功能。 2. 收货地址功能的实现 在我的页面中添加收货地址功能。用户可以选择添加和管理自己的收货地址,包括添加、修改和删除收货地址等操作。可以通过调用后台接口实现收货地址功能。 3. 订单列表功能的实现 在我的页面中添加订单列表功能。用户可以查看和管理自己的订单信息,包括查看订单详情、取消订单和确认收货等操作。可以通过调用后台接口实现订单列表功能。 四、购物车 购物车需要实现询问导航栏的切换、获取商品数据并展示在页面中、展示商品列表信息页面并能把商品添加到购物车页面中、完成购物车页面的设计和展示并能实现购物车中商品数量通过按钮进行增加和减少操作、购物车询问自动计算机商品金额和完成购物车中提交订单。 1. 实现购物车询问导航栏的切换 在导航栏中添加购物车按钮,用户可以通过点击购物车按钮进入购物车页面。 2. 获取商品数据并展示在页面中 在购物车页面中获取商品数据,并将其展示在页面中。可以通过调用后台接口获取商品信息。 3. 展示商品列表信息页面并能把商品添加到购物车页面中 在商品列表页面中展示商品的信息,并将其添加到购物车页面中。用户可以选择自己感兴趣的商品,并将其添加到购物车中。 4. 完成购物车页面的设计和展示并能实现购物车中商品数量通过按钮进行增加和减少操作,当数量小于0时此商品在购物车中消失 在购物车页面中展示已添加的商品信息,并实现商品数量通过按钮进行增加和减少操作。当商品数量小于0时,该商品将从购物车中消失。 5. 购物车询问自动计算机商品金额 在购物车页面中实现自动计算商品金额的功能。当用户选择商品并添加到购物车中时,系统自动计算出商品的总金额,并展示在页面中。 6. 完成购物车中提交订单购物车页面中添加提交订单功能。用户可以选择已添加的商品,并进行支付操作。可以通过调用后台接口实现提交订单功能。 以上是微商城项目的设计和实现的一些参考代码和思路。由于该项目较为复杂,可能需要更多的代码和细节方面的处理。如果需要更多帮助,请随时问我。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值