Web bán hàng bằng Spring MVC – Giỏ hàng và thanh toán đơn hàng

Tiếp tục loạt bài hướng dẫn xây dựng Web bán hàng bằng Spring MVC thì Team Việt Dev sẽ trình bày phần giỏ hàng và thanh toán đơn hàng.

Phần trước chúng ta đã hoàn thành phần thiết kế giao diện trang bán hàng, hiển thị danh mục sản phẩmhiển thị danh sách sản phẩm theo danh mục cũng như hiển thị thông tin chi tiết sản phẩm. Bây giờ tiếp tục là phần giỏ hàng và thanh toán đơn hàng.

Bước 1: Đầu tiên bạn tạo lớp Cart.java để lưu thông tin sản phẩm cũng như số lượng sản phẩm vào trong giỏ hàng.

package com.teamvietdev.model;

/**
 *
 * @author TVD
 */
public class Cart {

    private Product product;
    private int quantity;

    public Cart() {
    }

    public Cart(Product product, int quantity) {
        this.product = product;
        this.quantity = quantity;
    }

    public Product getProduct() {
        return product;
    }

    public void setProduct(Product product) {
        this.product = product;
    }

    public int getQuantity() {
        return quantity;
    }

    public void setQuantity(int quantity) {
        this.quantity = quantity;
    }

}

Bước 2: Sau đó chúng ta sẽ tạo lớp ControllerCart.java để xử lý thêm sản phẩm vào trong giỏ hàng, xóa sản phẩm trong giỏ hàng… Viết các phương thức cho lớp giỏ hàng như thêm sản phẩm vào giỏ hàng, cập nhật giỏ hàng, xóa giỏ hàng, tính tổng số lượng sản phẩm và tổng tiền có trong giỏ hàng.

package com.teamvietdev.controller;

import com.teamvietdev.model.Cart;
import com.teamvietdev.model.Product;
import com.teamvietdev.service.ProductService;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 *
 * @author TVD
 */
@Controller
@RequestMapping(value = "cart")
public class ControllerCart {

    @Autowired
    private ProductService productService;

    @RequestMapping(value = "add/{productId}.html", method = RequestMethod.GET)
    public String viewAdd(ModelMap mm, HttpSession session, @PathVariable("productId") long productId) {
        HashMap<Long, Cart> cartItems = (HashMap<Long, Cart>) session.getAttribute("myCartItems");
        if (cartItems == null) {
            cartItems = new HashMap<>();
        }
        Product product = productService.findById(productId);
        if (product != null) {
            if (cartItems.containsKey(productId)) {
                Cart item = cartItems.get(productId);
                item.setProduct(product);
                item.setQuantity(item.getQuantity() + 1);
                cartItems.put(productId, item);
            } else {
                Cart item = new Cart();
                item.setProduct(product);
                item.setQuantity(1);
                cartItems.put(productId, item);
            }
        }
        session.setAttribute("myCartItems", cartItems);
        session.setAttribute("myCartTotal", totalPrice(cartItems));
        session.setAttribute("myCartNum", cartItems.size());
        return "pages/cart";
    }

    @RequestMapping(value = "sub/{productId}.html", method = RequestMethod.GET)
    public String viewUpdate(ModelMap mm, HttpSession session, @PathVariable("productId") long productId) {
        HashMap<Long, Cart> cartItems = (HashMap<Long, Cart>) session.getAttribute("myCartItems");
        if (cartItems == null) {
            cartItems = new HashMap<>();
        }
        session.setAttribute("myCartItems", cartItems);
        return "pages/cart";
    }

    @RequestMapping(value = "remove/{productId}.html", method = RequestMethod.GET)
    public String viewRemove(ModelMap mm, HttpSession session, @PathVariable("productId") long productId) {
        HashMap<Long, Cart> cartItems = (HashMap<Long, Cart>) session.getAttribute("myCartItems");
        if (cartItems == null) {
            cartItems = new HashMap<>();
        }
        if (cartItems.containsKey(productId)) {
            cartItems.remove(productId);
        }
        session.setAttribute("myCartItems", cartItems);
        session.setAttribute("myCartTotal", totalPrice(cartItems));
        session.setAttribute("myCartNum", cartItems.size());
        return "pages/cart";
    }

    public double totalPrice(HashMap<Long, Cart> cartItems) {
        int count = 0;
        for (Map.Entry<Long, Cart> list : cartItems.entrySet()) {
            count += list.getValue().getProduct().getProductPrice() * list.getValue().getQuantity();
        }
        return count;
    }

}

Như giao diện mình sẽ hiển thị thông tin về giỏ hàng trong header.jsp

<li>
	<div class="cart">
       <a href="#" class="cart-in"> </a>
       <span> <c:out value="${sessionScope.myCartNum}"/></span>
    </div>
        <ul class="sub-icon1 list">
            <h3>Recently added items (<c:out value="${sessionScope.myCartNum}"/>)</h3>
                <div class="shopping_cart">
                    <c:forEach var="map" items="${sessionScope.myCartItems}">
                        <div class="cart_box">
                            <div class="message">
                                <div class="alert-close"> </div> 
                                <div class="list_img"><img src="${pageContext.request.contextPath}/resources/pages/images/14.jpg" class="img-responsive" alt=""></div>
                                <div class="list_desc"><h4><a href="#"><c:out value="${map.value.product.productName}"/></a></h4><c:out value="${map.value.quantity}"/> x
                                    $<c:out value="${map.value.product.productPrice}"/> = <span class="actual"> $<c:out value="${map.value.quantity * map.value.product.productPrice}"/></span></div>
                                <div class="clearfix"></div>
                            </div>
                        </div>
                    </c:forEach>
                </div>
                <div class="total">
                    <div class="total_left">Total: </div>
                    <div class="total_right">$<c:out value="${sessionScope.myCartTotal}"/></div>
                    <div class="clearfix"> </div>
                </div>
                <div class="login_buttons">
                    <div class="check_button"><a href="checkout.html">Check out</a></div>
                    <div class="clearfix"></div>
                </div>
                <div class="clearfix"></div>
    </ul>
</li>

Kết quả sau khi chạy đoạn mã trên:

Web bán hàng bằng Spring MVC – Giỏ hàng và thanh toán đơn hàng

Trang cart.jsp hiển thị thông tin giỏ hàng.

<%-- 
    Document   : cart
    Created on : 25-Nov-2018, 11:56:43 AM
    Author     : TVD
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>cart</title>
    </head>
    <body>

        <jsp:include page="header.jsp"></jsp:include>

            <br/><br/>

            <div class="container">
                <div class="content">
                    <div class="shopping_cart">
                    <c:forEach var="map" items="${sessionScope.myCartItems}">
                        <div class="cart_box">
                            <div class="message">
                                <div class="list_img"><img src="${pageContext.request.contextPath}/resources/pages/images/pi1.jpg" class="img-responsive" alt=""></div>
                                <div class="list_close"><a href="${pageContext.request.contextPath}/cart/remove/${map.value.product.productId}.html">Remove item</a></div> 
                                <div class="list_desc"><h4><a href="#"><c:out value="${map.value.product.productName}"/></a></h4><c:out value="${map.value.quantity}"/> x
                                    $<c:out value="${map.value.product.productPrice}"/> = <span class="actual"> $<c:out value="${map.value.quantity * map.value.product.productPrice}"/></span></div>
                                <div class="clearfix"></div>
                            </div>
                        </div>
                    </c:forEach>
                </div>
                <div class="total">
                    <div class="total_right">Free Shipping</div>
                    <div class="clearfix"> </div>
                    <div class="total_right">Total: $<c:out value="${sessionScope.myCartTotal}"/></div>
                    <div class="clearfix"> </div>
                    <div class="total_right">VAT (10%): <c:out value="${sessionScope.myCartTotal * 0.1}"/></div>
                    <div class="clearfix"> </div>
                    <div class="total_right">Pay: $<c:out value="${sessionScope.myCartTotal + (sessionScope.myCartTotal * 0.1)}"/></div>
                    <div class="clearfix"> </div>
                </div>
                <div class="login_buttons">
                    <div class="check_button"><a href="checkout.html">Check out</a></div>
                    <div class="clearfix"></div>
                </div>
                <div class="clearfix"></div>
            </div>
            <div class="clearfix"></div>

        </div>

        <br/><br/>

        <jsp:include page="footer.jsp"></jsp:include>

    </body>
</html>

Kết quả sau khi chạy đoạn mã trên:

Web bán hàng bằng Spring MVC – Giỏ hàng và thanh toán đơn hàng

Bước 3: Sau khi xong phần giỏ hàng, chúng ta sẽ thiết kế thêm về phần thực hiện tiến hành thanh toán đơn hàng. Mình sẽ làm chức năng này đơn giản, tạo trang checkout.jsp với phần hiển thị thông tin về đơn hàng, bên dưới là phần để người dùng nhập thông tin thanh toán như họ tên, địa chỉ email hay địa chỉ giao hàng.

Web bán hàng bằng Spring MVC – Giỏ hàng và thanh toán đơn hàng

Mã nguồn giao diện trang checkout.jsp

<form:form method="POST" action="${pageContext.request.contextPath}/cart/checkout.html" modelAttribute="receipt">
      <h3>Want to work with me?</h3>
      <div>
            <span>Your Name</span>
            <form:input path="receiptName"  />
      </div>
      <div>
            <span>Your Email</span>	
            <form:input path="receiptMail"  />
      </div>
      <div>
            <span>Your Address</span>	
            <form:input path="receiptAddress"  />
      </div>
      <input type="submit" value="SEND" >	
</form:form>

Tạo lớp Receipt.java và ReceiptItem.java để lưu thông tin hóa đơn mua hàng.

Lớp Receipt.java

package com.teamvietdev.model;

import java.io.Serializable;
import java.sql.Timestamp;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;

/**
 *
 * @author TVD
 */
@Entity(name = "receipt")
public class Receipt implements Serializable {

    @Id
    @GeneratedValue
    private long receiptId;
    private String receiptName;
    private String receiptMail;
    private String receiptAddress;
    private Timestamp receiptDate;
    private boolean receiptStatus;
    @OneToMany(fetch = FetchType.LAZY)
    @JoinColumn(name = "receiptItemId")
    private List<ReceiptItem> listReceiptItem;

    // get & set
   
}

Lớp ReceiptItem.java

package com.teamvietdev.model;

import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;

/**
 *
 * @author TVD
 */
@Entity(name = "receipt_item")
public class ReceiptItem implements Serializable {

    @Id
    @GeneratedValue
    private long receiptItemId;
    @ManyToOne
    @JoinColumn(name = "receiptId")
    private Receipt receipt;
    @OneToOne
    @JoinColumn(name = "productId")
    private Product product;
    private int receiptItemQuantity;
    private double receiptItemPrice;
    private int receiptItemSale;
    private boolean receiptItemStatus;

    // get & set

}

Bây giờ bạn mở lớp ControllerCart.java xử lý khi người dùng nhấn thanh toán đơn hàng.

@RequestMapping(value = "checkout.html", method = RequestMethod.POST)
public String viewCheckout(ModelMap mm, HttpSession session, @ModelAttribute("receipt") Receipt receipt) {
        HashMap<Long, Cart> cartItems = (HashMap<Long, Cart>) session.getAttribute("myCartItems");
        if (cartItems == null) {
            cartItems = new HashMap<>();
        }
        receipt.setReceiptDate(new Timestamp(new Date().getTime()));
        receipt.setReceiptStatus(true);
        receiptService.create(receipt);
        for (Map.Entry<Long, Cart> entry : cartItems.entrySet()) {
            ReceiptItem receiptItem = new ReceiptItem();
            receiptItem.setReceipt(receipt);
            receiptItem.setProduct(entry.getValue().getProduct());
            receiptItem.setReceiptItemPrice(entry.getValue().getProduct().getProductPrice());
            receiptItem.setReceiptItemSale(entry.getValue().getProduct().getProductSale());
            receiptItem.setReceiptItemQuantity(entry.getValue().getQuantity());
            receiptItem.setReceiptItemStatus(true);
            receiptItemService.create(receiptItem);
        }
        cartItems = new HashMap<>();
        session.setAttribute("myCartItems", cartItems);
        session.setAttribute("myCartTotal", 0);
        session.setAttribute("myCartNum", 0);
        return "pages/success";
}

Cấu trúc thư mục bố trí như sau:

Web bán hàng bằng Spring MVC – Giỏ hàng và thanh toán đơn hàng

 

Lời kết: Trong thời gian tới Team Việt Dev sẽ tiếp tục chia sẻ thêm nhiều bài viết trong loạt bài hướng dẫn xây dựng web bán hàng bằng Spring MVC… miễn phí đến bạn đọc, các bạn nhớ theo dõi kênh để có được những chia sẻ mới nhất.

(Tác giả: Team Việt Dev)

2 Comments

  1. Anh 28/10/2023 Reply
  2. Anh 28/10/2023 Reply

Bình luận