1. 项目第六阶段:购物车
页面样式
购物车
我的订单
结算
1.1 购物车模块分析
1.2、购物车实现
1.2.1 购物车模型
1.2.2 购物车的测试
创建 pojo/CartItem
package com.atguigu.pojo; import java.math.BigDecimal; /** * 购物车的商品相 */ public class CartItem { private Integer id; private String name; private Integer count; private BigDecimal Price; private BigDecimal totalPrice; public CartItem() { } public CartItem(Integer id, String name, Integer count, BigDecimal price, BigDecimal totalPrice) { this.id = id; this.name = name; this.count = count; Price = price; this.totalPrice = totalPrice; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getCount() { return count; } public void setCount(Integer count) { this.count = count; } public BigDecimal getTotalPrice() { return totalPrice; } public void setTotalPrice(BigDecimal totalPrice) { this.totalPrice = totalPrice; } public BigDecimal getPrice() { return Price; } public void setPrice(BigDecimal price) { Price = price; } @Override public String toString() { return "CartIem{" + "id=" + id + ", name='" + name + '\'' + ", count=" + count + ", totalPrice=" + totalPrice + '}'; } }
创建 pojo/Cart
package com.atguigu.pojo; import java.math.BigDecimal; import java.util.LinkedHashMap; import java.util.Map; /** * 购物车对象 */ public class Cart { // private Integer totalCount; // private BigDecimal totalPrice; /** * key是商品编号 * value是商品信息 */ private Map<Integer,CartItem> items=new LinkedHashMap<>(); /** * 添加商品项 * @param cartItem */ public void addItem(CartItem cartItem){ //Crtl+Shift+T // 先查看购物车中是否添加过此商品,如果已添加,则数量累加,总金额更新,如果,没有添加过,直接放入集合中即可 CartItem item = items.get(cartItem.getId()); if (item==null){ //之前没添加 items.put(cartItem.getId(),cartItem); }else { //已添加 item.setCount(item.getCount()+1);//数量累加 item.setTotalPrice(cartItem.getPrice().multiply(new BigDecimal(item.getCount())));//总金额更新 } } /* * 删除商品项 */ public void deleteItem(Integer id){ items.remove(id); } /* * 清空购物车 */ public void clear(){ items.clear(); } /* * 修改商品数量 */ public void updateCount(Integer id,Integer count){ //先查看购物车中是否有次商品。如果有,则修改数量,更新总金额 CartItem cartItem = items.get(id); if (cartItem!=null){ cartItem.setCount(count);//修改数量 cartItem.setTotalPrice(cartItem.getPrice().multiply(new BigDecimal(cartItem.getCount())));//总金额更新 } } public Integer getTotalCount() { Integer totalCount=0; for (Map.Entry<Integer,CartItem> entry:items.entrySet()) { totalCount+=entry.getValue().getCount(); } return totalCount; } // public void setTotalCount(Integer totalCount) { // this.totalCount = totalCount; // } public BigDecimal getTotalPrice() { BigDecimal totalPrice =new BigDecimal(0); for (Map.Entry<Integer,CartItem> entry:items.entrySet()) { totalPrice=totalPrice.add(entry.getValue().getTotalPrice()); } return totalPrice; } // public void setTotalPrice(BigDecimal totalPrice) { // this.totalPrice = totalPrice; // } public Map<Integer, CartItem> getItems() { return items; } public void setItems(Map<Integer, CartItem> items) { this.items = items; } @Override public String toString() { return "Cart{" + "totalCount=" + getTotalCount() + ", totalPrice=" + getTotalPrice() + ", items=" + items + '}'; } }
测试 创建 test/CartTest
package com.atguigu.test; import com.atguigu.pojo.Cart; import com.atguigu.pojo.CartItem; import org.junit.Test; import java.math.BigDecimal; public class CartTest { @Test public void addItem() { Cart cart=new Cart(); cart.addItem(new CartItem(1,"java",1,new BigDecimal(1000),new BigDecimal(1000))); cart.addItem(new CartItem(1,"java",1,new BigDecimal(1000),new BigDecimal(1000))); cart.addItem(new CartItem(2,"数据结构与算法",1,new BigDecimal(100),new BigDecimal(100))); System.out.println(cart); } @Test public void deleteItem() { Cart cart=new Cart(); cart.addItem(new CartItem(1,"java",1,new BigDecimal(1000),new BigDecimal(1000))); cart.addItem(new CartItem(1,"java",1,new BigDecimal(1000),new BigDecimal(1000))); cart.addItem(new CartItem(2,"数据结构与算法",1,new BigDecimal(100),new BigDecimal(100))); cart.deleteItem(1); System.out.println(cart); } @Test public void clear() { Cart cart=new Cart(); cart.addItem(new CartItem(1,"java",1,new BigDecimal(1000),new BigDecimal(1000))); cart.addItem(new CartItem(1,"java",1,new BigDecimal(1000),new BigDecimal(1000))); cart.addItem(new CartItem(2,"数据结构与算法",1,new BigDecimal(100),new BigDecimal(100))); cart.deleteItem(1); cart.clear(); System.out.println(cart); } @Test public void updateCount() { Cart cart=new Cart(); cart.addItem(new CartItem(1,"java",1,new BigDecimal(1000),new BigDecimal(1000))); cart.addItem(new CartItem(1,"java",1,new BigDecimal(1000),new BigDecimal(1000))); cart.addItem(new CartItem(2,"数据结构与算法",1,new BigDecimal(100),new BigDecimal(100))); cart.deleteItem(1); cart.clear(); cart.addItem(new CartItem(1,"java",1,new BigDecimal(1000),new BigDecimal(1000))); cart.updateCount(1,10); System.out.println(cart); } }
1.3、加入购物车功能的实现
创建 CartServlet,并配置web.xml
package com.atguigu.web; import com.atguigu.pojo.Book; import com.atguigu.pojo.Cart; import com.atguigu.pojo.CartItem; import com.atguigu.service.BookService; import com.atguigu.service.impl.BookServiceImpl; import com.atguigu.utils.WebUtils; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class CartServlet extends BaseServlet{ private BookService bookService=new BookServiceImpl(); /** * 加入购物车 * @param req * @param resp * @throws ServletException * @throws IOException */ protected void addItem(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // System.out.println("加入购物车"); // System.out.println("商品编号:"+req.getParameter("id")); //获取请求的参数 商品编号 int id= WebUtils.parseInt(req.getParameter("id"),0); //调用bookService.queryBookById(id):Book 得到图书的信息 Book book=bookService.queryBookById(id); //把图书信息,转换成为CartItem商品项 CartItem cartItem=new CartItem(book.getId(), book.getName(), 1,book.getPrice(),book.getPrice()); //调用Cart.addItem(CartItem):添加商品项 Cart cart= (Cart) req.getSession().getAttribute("cart"); if (cart==null){ cart=new Cart(); req.getSession().setAttribute("cart",cart); } cart.addItem(cartItem); System.out.println(cart); //重定向回商品列表页面 // resp.sendRedirect(req.getContextPath()); // System.out.println("请求头Referer的值:"+req.getHeader("Referer")); //重定向回原来商品所在地址页面 resp.sendRedirect(req.getHeader("Referer")); } }
修改 index.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>书城首页</title> <%--静态包含 base标签,css样式,jquery文件 --%> <%@ include file="/pages/common/head.jsp"%> <script type="text/javascript"> $(function (){ //给加入购物车按钮绑定单击事件 $("button.addToCart").click(function (){ /** * 在事件响应的function函数中,有一个this对象,这个this对象,是当前正在响应事件的dom对象 * @type {*|jQuery} */ var bookId= $(this).attr("bookId"); location.href="http://localhost:8080/book/cartServlet?action=addItem&id="+bookId; }); }); </script> </head> <body> <div id="header"> <img class="logo_ing" alt="" src="static/img/logo.gif"> <span class= "wel_word">网上书城</span> <div> <%-- 如果用户还没有登录,显示【登录和注册的菜单】--%> <c:if test="${empty sessionScope.user}"> <a href="pages/user/login.jsp">登录</a> <a href="pages/user/regist.jsp">注册</a> </c:if> <%-- 如果已经登录,显示登录之后的用户信息--%> <c:if test="${not empty sessionScope.user}"> <span>欢迎<span class="um_span">${sessionScope.user.username}</span>光临尚硅谷书城</span> <a href="pages/order/order.jsp">我的订单</a> <a href="userServlet?action=logout">注销</a> </c:if> <a href="pages/cart/cart.jsp">购物车</a> <a href="pages/manager/manager.jsp">后台管理</a> </div> <div id="main"> <div id="book"> <div class="book_cond"> <form action="client/bookServlet" method="get"> <input type="hidden" name="action" value="pageByPrice"> 价格:<input id="min" type="text" name="min" value="${param.min}">元 - <input id="max" type="text" name="max" value="${param.max}">元 <input type="submit" value="查询"/> </form> </div> <div style="..."> <span>您的购物车中有3件商品</span> <div> 您刚刚将<span style="...">时间简史</span>加入到了购物车中 </div> </div> <div> <c:forEach items="${requestScope.page.items}" var="book"> <div class="b_list"> <div class="img_div"> <img class="book_img" alt="${book.imgPath}"/> </div> <div class="book_info"> <div class="book_name"> <span class="sp1">书名:</span> <span class="sp2">${book.name}</span> </div> <div class="book_author"> <span class="sp1">作者:</span> <span class="sp2">${book.author}</span> </div> <div class= "book_price"> <span class="sp1">价格:</span> <span class="sp2">¥${book.price}</span> </div> <div class="book_sales"> <span class="sp1">销量:</span> <span class="sp2">${book.sales}</span> </div> <div class="book_amount"> <span class="sp1">库存:</span> <span class="sp2">${book.stock}</span> </div> <div class="book_add"> <button bookId="${book.id}" class="addToCart">加入购物车:</button> </div> </div> </div> </c:forEach> </div> </div> <%-- 静态包含分页条 --%> <%@include file="/pages/common/page_nav.jsp"%> </div> </div> <%--静态包含页脚内容--%> <%@include file="/pages/common/footer.jsp"%> </body> </html>
1.4 购物车的展示
修改 cart.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%-- Created by IntelliJ IDEA. User: lenovo Date: 2021/8/21 Time: 下午 02:49 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>购物车</title> <%--静态包含 base标签,css样式,jquery文件 --%> <%@ include file="/pages/common/head.jsp"%> </head> <body> <div id="header"> <img class="logo_img" alt="" src="static/img/logo.gif"> <span class="wel_word">购物车</span> <%-- 静态包含登录成功之后的菜单--%> <%@ include file="/pages/common/login_sucess_menu.jsp"%> </div> <div id="main"> <table> <tr> <td>商品名称</td> <td>数量</td> <td>单价</td> <td>金额</td> <td>操作</td> </tr> <c:if test="${empty sessionScope.cart.items}"> <%-- 如果购物车为空的情况 --%> <td colspan="5"><a href="index.jsp"> 亲,当前购物车为空!快跟小伙伴们去浏览商品吧!!!</a></td> </c:if> <c:if test="${not empty sessionScope.cart.items}"> <%-- 如果购物车非空的情况 --%> <c:forEach items="${sessionScope.cart.items}" var="entry"> <tr> <td>${entry.value.name}</td> <td>${entry.value.count}</td> <td>${entry.value.price}</td> <td>${entry.value.totalPrice}</td> <td><a href="#">删除</a></td> </tr> </c:forEach> </c:if> </table> <c:if test="${not empty sessionScope.cart.items}"> <div class="cart_info"> <span class="cart_span">购物车中共有<span class="b_count">${sessionScope.cart.totalCount}</span>件商品</span> <span class="cart_span">总金额<span class="b_price">${sessionScope.cart.totalPrice}</span>元</span> <span class="cart_span"><a href="#">清空购物车</a></span> <span class="cart span"><a href="pages/cart/checkout.jsp">去结账</a></span> </div> </c:if> </div> <%--静态包含页脚内容--%> <%@include file="/pages/common/footer.jsp"%> </body> </html>
1.5 删除购物车的商品项
修改 CartServlet
package com.atguigu.web; import com.atguigu.pojo.Book; import com.atguigu.pojo.Cart; import com.atguigu.pojo.CartItem; import com.atguigu.service.BookService; import com.atguigu.service.impl.BookServiceImpl; import com.atguigu.utils.WebUtils; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class CartServlet extends BaseServlet{ private BookService bookService=new BookServiceImpl(); /** * 加入购物车 * @param req * @param resp * @throws ServletException * @throws IOException */ protected void addItem(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // System.out.println("加入购物车"); // System.out.println("商品编号:"+req.getParameter("id")); //获取请求的参数 商品编号 int id= WebUtils.parseInt(req.getParameter("id"),0); //调用bookService.queryBookById(id):Book 得到图书的信息 Book book=bookService.queryBookById(id); //把图书信息,转换成为CartItem商品项 CartItem cartItem=new CartItem(book.getId(), book.getName(), 1,book.getPrice(),book.getPrice()); //调用Cart.addItem(CartItem):添加商品项 Cart cart= (Cart) req.getSession().getAttribute("cart"); if (cart==null){ cart=new Cart(); req.getSession().setAttribute("cart",cart); } cart.addItem(cartItem); System.out.println(cart); //重定向回商品列表页面 // resp.sendRedirect(req.getContextPath()); // System.out.println("请求头Referer的值:"+req.getHeader("Referer")); //重定向回原来商品所在地址页面 resp.sendRedirect(req.getHeader("Referer")); } /** * 删除商品项 * @param req * @param resp * @throws ServletException * @throws IOException */ protected void deleteItem(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //获取请求的参数 商品编号 int id= WebUtils.parseInt(req.getParameter("id"),0); //获取购物车对象 Cart cart= (Cart) req.getSession().getAttribute("cart"); if (cart!=null){ //删除了购物车商品项 cart.deleteItem(id); //重定向回原来商品所在地址页面 resp.sendRedirect(req.getHeader("Referer")); } } }
修改 cart.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%-- Created by IntelliJ IDEA. User: lenovo Date: 2021/8/21 Time: 下午 02:49 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>购物车</title> <%--静态包含 base标签,css样式,jquery文件 --%> <%@ include file="/pages/common/head.jsp"%> <script type="text/javascript"> $(function (){ //给删除绑定单击事件 $("a.deleteItem").click(function (){ return confirm("你确定要删除吗【"+$(this).parent().parent().find("td:first").text()+"】?"); }); }); </script> </head> <body> <div id="header"> <img class="logo_img" alt="" src="static/img/logo.gif"> <span class="wel_word">购物车</span> <%-- 静态包含登录成功之后的菜单--%> <%@ include file="/pages/common/login_sucess_menu.jsp"%> </div> <div id="main"> <table> <tr> <td>商品名称</td> <td>数量</td> <td>单价</td> <td>金额</td> <td>操作</td> </tr> <c:if test="${empty sessionScope.cart.items}"> <%-- 如果购物车为空的情况 --%> <td colspan="5"><a href="index.jsp"> 亲,当前购物车为空!快跟小伙伴们去浏览商品吧!!!</a></td> </c:if> <c:if test="${not empty sessionScope.cart.items}"> <%-- 如果购物车非空的情况 --%> <c:forEach items="${sessionScope.cart.items}" var="entry"> <tr> <td>${entry.value.name}</td> <td>${entry.value.count}</td> <td>${entry.value.price}</td> <td>${entry.value.totalPrice}</td> <td><a class="deleteItem" href="cartServlet?action=deleteItem&id=${entry.value.id}">删除</a></td> </tr> </c:forEach> </c:if> </table> <c:if test="${not empty sessionScope.cart.items}"> <div class="cart_info"> <span class="cart_span">购物车中共有<span class="b_count">${sessionScope.cart.totalCount}</span>件商品</span> <span class="cart_span">总金额<span class="b_price">${sessionScope.cart.totalPrice}</span>元</span> <span class="cart_span"><a href="#">清空购物车</a></span> <span class="cart span"><a href="pages/cart/checkout.jsp">去结账</a></span> </div> </c:if> </div> <%--静态包含页脚内容--%> <%@include file="/pages/common/footer.jsp"%> </body> </html>
1.6 清空购物车
修改 CartServlet
package com.atguigu.web; import com.atguigu.pojo.Book; import com.atguigu.pojo.Cart; import com.atguigu.pojo.CartItem; import com.atguigu.service.BookService; import com.atguigu.service.impl.BookServiceImpl; import com.atguigu.utils.WebUtils; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class CartServlet extends BaseServlet{ private BookService bookService=new BookServiceImpl(); /** * 加入购物车 * @param req * @param resp * @throws ServletException * @throws IOException */ protected void addItem(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // System.out.println("加入购物车"); // System.out.println("商品编号:"+req.getParameter("id")); //获取请求的参数 商品编号 int id= WebUtils.parseInt(req.getParameter("id"),0); //调用bookService.queryBookById(id):Book 得到图书的信息 Book book=bookService.queryBookById(id); //把图书信息,转换成为CartItem商品项 CartItem cartItem=new CartItem(book.getId(), book.getName(), 1,book.getPrice(),book.getPrice()); //调用Cart.addItem(CartItem):添加商品项 Cart cart= (Cart) req.getSession().getAttribute("cart"); if (cart==null){ cart=new Cart(); req.getSession().setAttribute("cart",cart); } cart.addItem(cartItem); // System.out.println(cart); //重定向回商品列表页面 // resp.sendRedirect(req.getContextPath()); // System.out.println("请求头Referer的值:"+req.getHeader("Referer")); //重定向回原来商品所在地址页面 resp.sendRedirect(req.getHeader("Referer")); } /** * 删除商品项 * @param req * @param resp * @throws ServletException * @throws IOException */ protected void deleteItem(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //获取请求的参数 商品编号 int id= WebUtils.parseInt(req.getParameter("id"),0); //获取购物车对象 Cart cart= (Cart) req.getSession().getAttribute("cart"); if (cart!=null){ //删除了购物车商品项 cart.deleteItem(id); //重定向回原来商品所在地址页面 resp.sendRedirect(req.getHeader("Referer")); } } /** * 清空购物车 * @param req * @param resp * @throws ServletException * @throws IOException */ protected void clear(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //获取购物车对象 Cart cart= (Cart) req.getSession().getAttribute("cart"); if (cart!=null){ //清空购物车 cart.clear(); //重定向回原来商品所在地址页面 resp.sendRedirect(req.getHeader("Referer")); } } }
修改 cart.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%-- Created by IntelliJ IDEA. User: lenovo Date: 2021/8/21 Time: 下午 02:49 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>购物车</title> <%--静态包含 base标签,css样式,jquery文件 --%> <%@ include file="/pages/common/head.jsp"%> <script type="text/javascript"> $(function (){ //给删除绑定单击事件 $("a.deleteItem").click(function (){ return confirm("你确定要删除吗【"+$(this).parent().parent().find("td:first").text()+"】?"); }); //给清空购物车绑定单击事件 $("#clearCart").click(function (){ return confirm("你确定要清空购物车吗?"); }); }); </script> </head> <body> <div id="header"> <img class="logo_img" alt="" src="static/img/logo.gif"> <span class="wel_word">购物车</span> <%-- 静态包含登录成功之后的菜单--%> <%@ include file="/pages/common/login_sucess_menu.jsp"%> </div> <div id="main"> <table> <tr> <td>商品名称</td> <td>数量</td> <td>单价</td> <td>金额</td> <td>操作</td> </tr> <c:if test="${empty sessionScope.cart.items}"> <%-- 如果购物车为空的情况 --%> <td colspan="5"><a href="index.jsp"> 亲,当前购物车为空!快跟小伙伴们去浏览商品吧!!!</a></td> </c:if> <c:if test="${not empty sessionScope.cart.items}"> <%-- 如果购物车非空的情况 --%> <c:forEach items="${sessionScope.cart.items}" var="entry"> <tr> <td>${entry.value.name}</td> <td>${entry.value.count}</td> <td>${entry.value.price}</td> <td>${entry.value.totalPrice}</td> <td><a class="deleteItem" href="cartServlet?action=deleteItem&id=${entry.value.id}">删除</a></td> </tr> </c:forEach> </c:if> </table> <c:if test="${not empty sessionScope.cart.items}"> <div class="cart_info"> <span class="cart_span">购物车中共有<span class="b_count">${sessionScope.cart.totalCount}</span>件商品</span> <span class="cart_span">总金额<span class="b_price">${sessionScope.cart.totalPrice}</span>元</span> <span class="cart_span"><a id="clearCart" href="cartServlet?action=clear">清空购物车</a></span> <span class="cart span"><a href="pages/cart/checkout.jsp">去结账</a></span> </div> </c:if> </div> <%--静态包含页脚内容--%> <%@include file="/pages/common/footer.jsp"%> </body> </html>