位置: IT常识 - 正文
推荐整理分享JavaWeb购物系统(六)购物车订单模块的实现(java web购物系统),希望有所帮助,仅作参考,欢迎阅读内容。
文章相关热门搜索词:javaweb购物网站,购物系统java代码,javaweb购物商城,javaweb购物网站,java在线购物系统,javaweb购物车系统,javaweb购物网站,java在线购物系统,内容如对您有帮助,希望把文章链接给更多的朋友!
有订单时的效果图 无订单时的效果图 订单详情页
功能生成订单订单页的展示查看订单详情正文说明和购物车同样的,首先得知道我们的订单对应的哪个实体对象。一个用户可能有多条订单记录,一个订单里边可以包含多个商品(也可以理解为多个购物项)。理清这个逻辑之后,我们就可以得到两个实体:订单实体类和详细的订单项 对应到界面上就是如下图:
order.jsp(订单页)<%@ page import="com.service.OrderService" %><%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%><%@ page import="com.myUtil.ProcessUtil" %><%@ page import="com.entity.Order" %><%@ page import="java.util.List" %><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><%-- Created by IntelliJ IDEA. User: huawei Date: 2022/10/22 Time: 20:02 To change this template use File | Settings | File Templates.--%><%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head> <title>我的订单</title> <!-- 新 Bootstrap5 核心 CSS 文件 --> <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/5.1.1/css/bootstrap.min.css"> <%--icon图标--%> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.9.1/font/bootstrap-icons.css"> <!-- popper.min.js 用于弹窗、提示、下拉菜单 --> <script src="https://cdn.staticfile.org/popper.js/2.9.3/umd/popper.min.js"></script> <!-- 最新的 Bootstrap5 核心 JavaScript 文件 --> <script src="https://cdn.staticfile.org/twitter-bootstrap/5.1.1/js/bootstrap.min.js"></script> <script type="text/javascript" src="script/jquery-3.6.0.min.js"></script></head><body><% OrderService orderService = new OrderService(); String userId = ProcessUtil.getUserIdBySessionId(session); List<Order> orderList= orderService.showAllOrder(userId); if (orderList!=null && orderList.size()!=0){ session.setAttribute("orderList",orderList); }%><nav class="navbar-expand-lg navbar navbar-dark bg-primary"> <div class="container-fluid "> <a class="navbar-brand" href="#">我的订单</a> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarNavDropdown"> <ul class="navbar-nav"> <li class="nav-item"> <a class="nav-link active" aria-current="page" href="/MyProject/index.jsp">Home</a> </li> </ul> </div> </div></nav><c:if test="${empty sessionScope.orderList}"> <div class="container" > <div class="card position-relative" style="margin: 50px;height: 280px;background: #ffffff url(img/CartBackground.png) no-repeat; background-position: center left;"> <div class="position-absolute top-50 start-50 translate-middle"> <h7> 您还未购买过任何商品哦!赶紧行动吧!您可以: </h7><br> <a class="btn btn-primary btn-lg" href="/MyProject/index.jsp">购物</a> </div> </div> </div></c:if><c:if test="${!empty sessionScope.orderList}"> <div class="container"> <div class="card"> <table class="table table-hover text-center"> <tr> <td>订单号</td> <td>下单时间</td> <td>总价</td> <td>状态</td> <td>详情</td> </tr> <c:forEach items="${sessionScope.orderList}" var="order"> <tr style="vertical-align: middle !important;text-align: center;"> <td> <%--<img style="width: 100px;height: 100px" src="${or}"/>--%> <span>${order.id}</span> </td> <td> <%--分割下单时间--%> <c:set value="${fn:split(order.create_time,'T')}" var="time"></c:set> <c:forEach var="tm" items="${time}"> ${tm} </c:forEach> </td> <td>${order.price}</td> <td>0</td> <td><a type="submit" class="btn btn-danger" href="/MyProject/orderDetail.jsp?orderId=${order.id}">查看</a></td> </tr> </c:forEach> </table> <div class="row justify-content-between"> </div> </div> </div></c:if></body></html>订单的展示这里通过在jsp页面,调用service层的showAllOrder()来获取所有的订单列表。然后通过for-Each来将列表的每条信息渲染到前端页面
订单的查看和前面几节讲的留言删除、删除购物项思路一样,通过携带唯一标识ID(下单时间的毫秒数)来查看对应订单的详细信息。因为查看订单详情需要跳转页面,所有我们这里采用<a></a>标签来进行跳转。相关代码:
<td><a type="submit" class="btn btn-danger" href="/MyProject/orderDetail.jsp?orderId=${order.id}">查看</a></td>orderDetail.jsp(订单详情页)<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><%@ page import="com.entity.OrderItem" %><%@ page import="com.service.OrderItemService" %><%@ page import="java.util.List" %><%@ page import="com.service.OrderService" %><%@ page import="com.myUtil.ProcessUtil" %><%-- Created by IntelliJ IDEA. User: huawei Date: 2022/10/22 Time: 22:40 To change this template use File | Settings | File Templates.--%><%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head> <title>订单详情页</title> <!-- 新 Bootstrap5 核心 CSS 文件 --> <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/5.1.1/css/bootstrap.min.css"> <%--icon图标--%> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.9.1/font/bootstrap-icons.css"> <!-- popper.min.js 用于弹窗、提示、下拉菜单 --> <script src="https://cdn.staticfile.org/popper.js/2.9.3/umd/popper.min.js"></script> <!-- 最新的 Bootstrap5 核心 JavaScript 文件 --> <script src="https://cdn.staticfile.org/twitter-bootstrap/5.1.1/js/bootstrap.min.js"></script> <script type="text/javascript" src="script/jquery-3.6.0.min.js"></script></head><body><% OrderItemService orderItemService = new OrderItemService();// String orderId = (String)session.getAttribute("orderId");// if (orderId==null){ // 当用户重新登录之后/重启服务器,seesion域中会清空orderId。所以需要 String orderId = request.getParameter("orderId");// } List<OrderItem> orderItems = orderItemService.showAllOrderItem(orderId); if (orderItems !=null && orderItems.size()!=0){ session.setAttribute("orderItems",orderItems); }%><nav class="navbar-expand-lg navbar navbar-dark bg-primary"> <div class="container-fluid "> <a class="navbar-brand" href="#">订单详情页</a> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarNavDropdown"> <ul class="navbar-nav"> <li class="nav-item"> <a class="nav-link active" aria-current="page" href="/MyProject/index.jsp">Home</a> </li> </ul> </div> </div></nav><c:if test="${!empty sessionScope.orderItems}"> <div class="container"> <div class="card"> <table class="table table-hover text-center"> <tr> <td>订单号</td> <td>商品名称</td> <td>价格</td> <td>数量</td> <td>总价格</td> </tr> <c:forEach items="${sessionScope.orderItems}" var="orderItem"> <tr style="vertical-align: middle !important;text-align: center;"> <td>${orderItem.order_id}</td> <td> <img style="width: 100px;height: 100px" src="${orderItem.img}"/> <span>${orderItem.name}</span> </td> <td>${orderItem.price}</td> <td>${orderItem.count}</td> <td>${orderItem.total_price}</td> </tr> </c:forEach> </table> </div> </div></c:if></body></html>订单详情的展示在上边查看详情页按钮的代码中可以看到,跳转的不是Controller层,而是跳转到了orderDetail.jsp页面。在详情页面,通过请求携带的订单Id,来获取数据库的中的订单项数据。
不知道大家到这里会不会很奇怪?订单项是一个对象,订单也是一个对象。我们的订单和订单项的展示,都需要从数据库来获取,那么这两个对象是什么时候存储到数据库中的呢?
别急。下边就是答案: 当我们在购物车中点击结算按钮的时候,他就会生成订单对象以及和它对应的订单项。 我们这里解释一下,它的前后端是如何处理的:
// 结算$("#settlement").click( function () { $.post( "/MyProject/orderProcessServlet", { method: "" }, function (data) { if ("success" == data){ alert("订单生成成功!"); location.reload(true); } }, "json" ) })这段js代码在上一章节中,因为它属于购物车部分。是发送结算请求。请求地址是/orderProcessServlet,即我们的订单对应的Controller层。
OrderProcessServlet(订单处理层)package com.controller;import com.entity.*;import com.google.gson.Gson;import com.myUtil.JdbcUtil;import com.myUtil.ProcessUtil;import com.service.OrderService;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;import java.io.IOException;public class OrderProcessServlet extends HttpServlet { private OrderService orderService = new OrderService(); @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { HttpSession session = request.getSession(); Cart cart = (Cart) session.getAttribute("cart"); String userId = ProcessUtil.getUserIdBySessionId(session); if (cart==null || cart.getItems().size()==0){ response.sendRedirect("/MyProject/index.jsp"); return; } if (cart!=null){ // 对生成订单进行事务控制 String orderId = null; try { orderId = orderService.saveOrder(cart, Integer.parseInt(userId)); JdbcUtil.commit(); session.setAttribute("orderId",orderId); response.getWriter().write(new Gson().toJson("success")); } catch (Exception e) { // 如果出错事务回滚 JdbcUtil.rollback(); e.printStackTrace(); } } } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { doPost(request, response); }}orederService(订单处理的业务层)package com.service;import com.dao.GoodsDao;import com.dao.OrderDao;import com.dao.OrderItemDao;import com.entity.*;import java.time.LocalDateTime;import java.util.HashMap;import java.util.List;public class OrderService { private OrderDao orderDao = new OrderDao(); private OrderItemDao orderItemDao = new OrderItemDao(); private GoodsDao goodsDao = new GoodsDao(); // 生成订单 public String saveOrder(Cart cart, Integer userId){ // 生成订单号 String orderId = String.valueOf(System.currentTimeMillis()); // 订单生成时间 LocalDateTime createTime = LocalDateTime.now(); Order order = new Order(orderId,createTime,cart.getTotalPrice(),0,userId); // 保存order表到数据库 orderDao.addOrder(order); // 构建orderItem,并保存到数据库 HashMap<Integer, ShopCarItem> items = cart.getItems(); for (Integer goodId : items.keySet()) { ShopCarItem item = items.get(goodId); OrderItem orderItem = new OrderItem(null, item.getImg(), item.getGoodsName(), item.getPrice(), item.getNumber(), item.getTotalPrice(), orderId); orderItemDao.addOrderItem(orderItem); // 得到商品信息 Goods goods = goodsDao.showDataById(String.valueOf(goodId)); // 更新库存 goods.setInventory(goods.getInventory() - item.getNumber()); // 更新到数据库 goodsDao.updateStock(goods); } // 清空购物车 cart.removeAll(); return orderId; } // 显示所有订单 public List<Order> showAllOrder(String userId){ return orderDao.showAllOrder(userId); }}接着上边的逻辑,当生成订单请求发过来之后,在这Controller层调用Service层的saveOrder()进行了订单的生成,而且在Service层我们进行了订单保存,订单项的保存。而且我们注意到saveOrder()的参数是Cart购物车对象和用户Id。因为订单和订单项的所有信息都是从购物车来获取的,而且每个订单得有对应的用户(我们得保证自己的订单不能出现在别人的页面上,对吧^_^)。 当然生成订单之后还得清空购物车。
orderItemServicepackage com.service;import com.dao.OrderItemDao;import com.entity.OrderItem;import java.util.List;public class OrderItemService { private OrderItemDao orderItemDao = new OrderItemDao(); // 显示所有订单项 public List<OrderItem> showAllOrderItem(String orderId){ return orderItemDao.showAllOrderItem(orderId); }}orderDaopackage com.dao;import com.entity.Order;import java.util.List;public class OrderDao extends BasicDao<Order> { // 生成订单 public Boolean addOrder(Order order){ String sql = "INSERT INTO `order` VALUES('"+order.getId()+"','"+order.getCreate_time()+"',"+order.getPrice()+","+order.getStatus()+","+order.getMember_id()+")"; return dmlData(sql); } // 显示所有订单 public List<Order> showAllOrder(String userId){ String sql = "SELECT * FROM `order` WHERE `member_id`='" + userId + "'"; List<Order> orders = queryMulti(sql, Order.class); if (orders!=null){ return orders; } return null; }}orderItemDaopackage com.dao;import com.entity.OrderItem;import java.util.List;public class OrderItemDao extends BasicDao<OrderItem>{ // 添加订单项 public Boolean addOrderItem(OrderItem orderItem){ String sql = "INSERT INTO `order_item` VALUES(NULL,'"+ orderItem.getImg() +"','"+ orderItem.getName() + "',"+ orderItem.getPrice() +","+ orderItem.getCount() +","+ orderItem.getTotal_price() +",'"+ orderItem.getOrder_id() +"')"; return dmlData(sql); } // 显示所有订单项 public List<OrderItem> showAllOrderItem(String orderId){ String sql = "SELECT * FROM `order_item` WHERE `order_id`='"+ orderId +"'"; List<OrderItem> orderItems = queryMulti(sql, OrderItem.class); if (orderItems != null){ return orderItems; } return null; }}order(订单实体类)订单实体类拥有属性:
订单号(订单结算的毫秒时间)订单生成时间订单金额订单状态(这里我们没有太多的功能,所以默认是0)订单所属者(每个订单属于哪个用户)package com.entity;import java.math.BigDecimal;import java.time.LocalDateTime;public class Order { // 订单号 private String id; // 订单生成时间 private LocalDateTime create_time; // 订单金额 private BigDecimal price; // 订单状态 private Integer status; // 该订单对应的用户id private Integer member_id; public Order() { } public Order(String id, LocalDateTime create_time, BigDecimal price, Integer status, Integer member_id) { this.id = id; this.create_time = create_time; this.price = price; this.status = status; this.member_id = member_id; } public String getId() { return id; } public void setId(String id) { this.id = id; } public LocalDateTime getCreate_time() { return create_time; } public void setCreate_time(LocalDateTime create_time) { this.create_time = create_time; } public BigDecimal getPrice() { return price; } public void setPrice(BigDecimal price) { this.price = price; } public Integer getStatus() { return status; } public void setStatus(Integer status) { this.status = status; } public Integer getMember_id() { return member_id; } public void setMember_id(Integer member_id) { this.member_id = member_id; } @Override public String toString() { return "Order{" + "id='" + id + '\'' + ", create_time=" + create_time + ", price=" + price + ", status=" + status + ", member_id=" + member_id + '}'; }}orderItem(订单项实体类)订单项的实体类拥有的属性:
订单项唯一的标识Id商品图片商品的价格商品数量订单项的总价格订单项的所属的订单(订单项都是从属于某一个订单)package com.entity;import java.math.BigDecimal;public class OrderItem { // 订单项的自增ID private Integer id; // 商品图片 private String img; // 商品名 private String name; // 商品价格 private BigDecimal price; // 商品数量 private Integer count; // 订单项的总价 private BigDecimal total_price; // 对应的订单号 private String order_id; public OrderItem() { } @Override public String toString() { return "OrderItem{" + "id=" + id + ", img='" + img + '\'' + ", name='" + name + '\'' + ", price=" + price + ", count=" + count + ", total_price=" + total_price + ", order_id='" + order_id + '\'' + '}'; } public String getImg() { return img; } public void setImg(String img) { this.img = img; } public OrderItem(Integer id, String img, String name, BigDecimal price, Integer count, BigDecimal total_price, String order_id) { this.id = id; this.img = img; this.name = name; this.price = price; this.count = count; this.total_price = total_price; this.order_id = order_id; } 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 BigDecimal getPrice() { return price; } public void setPrice(BigDecimal price) { this.price = price; } public Integer getCount() { return count; } public void setCount(Integer count) { this.count = count; } public BigDecimal getTotal_price() { return total_price; } public void setTotal_price(BigDecimal total_price) { this.total_price = total_price; } public String getOrder_id() { return order_id; } public void setOrder_id(String order_id) { this.order_id = order_id; }}order表的设计列名数据类型长度主键?非空?自增?idvarchar64√√create_timedatetime√pricedecimal11,2√statuetinyint32√memberint√orderItem表的设计列名数据类型长度主键?非空?自增?idint√√√imgvarchar500√namevarchar500√pricedecimal11,2√countint√total_pricedecimal11,2√order_idvarchar64√这里我们得保证实体类的属性名要和对应表的字段名保持一致!!!
上一篇:【uni-app】小程序实现微信在线聊天(私聊/群聊)(小程序uniapp怎么用)
下一篇:Linn of Quoich瀑布旁的碗状岩石洞,苏格兰阿伯丁郡 (© AWL Images/Danita Delimont)(fall 瀑布)
友情链接: 武汉网站建设