MỤC LỤC DANH MỤC HÌNH ẢNH 1 CHƯƠNG 1 TỔNG QUAN CÔNG NGHỆ SỬ DỤNG XÂY DỰNG WEBSITE 6 1 Framework Spring. 6 1.1 Giới thiệu 6 1.2 Lợi ích sử dụng 6 1.3 Mục đích sử dụng chính trong đề tài 7 2 ReactJS 7 2.1 Giới thiệu 7 2.2 Lợi ích sử dụng 7 2.3 Mục đích sử dụng chính trong đề tài 8 3 Hệ quản trị cơ sở dữ liệu MySQL 8 3.1 Giới thiệu 8 3.2 Lợi ích sử dụng 8 3.3 Mục đích sử dụng 9 CHƯƠNG 2 PHÂN TÍCH THIẾT KẾ HỆ THỐNG WEBSITE 10 1 Khảo sát các trang web bán hàng điện tử liên quan. 10 1.1 Lựa chọn trang web khảo sát. 10 1.2 Các thành phần giao diện và chức năng của trang web thegioididong.com. 10 2 Đặc tả các yêu cầu cho trang web 18 2.1 Phần quản lý trong admin. 18 2.2 Phần quản lý người dùng 19 2.3 Yêu cầu giao diện sử dụng 19 2.4 Yêu cầu phi chức năng 19 3 Các chức năng của trang web 20 3.1 Chức năng quản lý hệ thống 20 3.2 Chức năng giới thiệu sản phẩm 20 4 Biểu đồ Use – case 20 4.1 Biểu đồ Use – case tổng quát 20 4.2 Use – case đăng nhập 21 4.3 Use – case quản lý sản phẩm 22 4.4 Use – case quản lý giỏ hàng 23 4.5 Use – case thanh toán 23 4.6 Use – case quản lý đơn hàng 24 4.7 Use – case quản lý quảng cáo trên giao diện 24 CHƯƠNG 3 THAO TÁC VÀ LƯU TRỮ DỮ LIỆU 26 1 Các công nghệ tương tác với dữ liệu. 26 1.1 Giao diện lập trình ứng dụng JPA 26 1.2 ORM tools – Hibernate. 28 1.3 DAO Design Pattern 28 1.4 Spring Data JPA 30 1.5 Kiến trúc tổng quát 31 2 Tạo Entity Hibernate định hình dữ liệu lưu trữ. 31 2.1 Lưu trữ thông tin đăng nhập tài khoản người dùng 31 2.2 Lưu trữ thông tin liên quan User 33 2.3 Lưu trữ thông tin liên lạc của người dùng 34 2.4 Lưu trữ phân loại quyền hạn. 35 2.5 Lưu trữ các thương hiệu hàng hóa 36 2.6 Lưu trữ các phân loại sản phẩm 37 2.7 Lưu trữ thông tin sản phẩm 38 2.8 Lưu trữ thông tin về thông số sản phẩm 40 2.9 Lưu trữ hình ảnh sản phẩm 42 2.10 Lưu trữ các đánh giá sản phẩm 43 2.11 Lưu trữ thông tin giỏ hàng 44 2.12 Lưu trữ thông tin đơn hàng 45 2.13 Lưu trữ thông tin các sản phẩm trong đơn hàng 47 2.14 Lưu trữ hình ảnh quảng cáo đầu trang web 48 2.15 ER Diagram quan hệ giữa các bảng trong csdl. 50 3 Tạo các DAO dựa trên Sping Data JPA 50 3.1 User Repository 51 3.2 User Credential Repository 51 3.3 User Contact Repository 52 3.4 Role Repository 52 3.5 Product Repository 52 3.6 ProductCriteria Repository 53 3.7 Product Details Repository 53 3.8 Product Image Repository 54 3.9 Review Repository 54 3.10 Brand Repository 55 3.11 Category Repository 55 3.12 Cart Repository 56 3.13 Order Repository 56 3.14 OrderItem Repository 57 3.15 HeaderImage Repository 57 4 Kết nối cơ sở dữ liệu với Spring Boot 57 CHƯƠNG 4 Xây dựng RESTful Web Service 59 1 Đăng ký, đăng nhập, bảo mật thông tin. 59 1.1 Một số khái niệm 59 1.2 Tạo tài khoản người dùng mới 63 1.3 Xác nhận Email cho tài khoản đã tạo. 66 1.4 Đăng nhập với tài khoản 70 1.5 Đăng nhập thông qua tài khoản FaceBook và Google 71 1.6 Gửi yêu cầu với Jwt access token. 75 1.7 Phân quyền người dùng 76 1.8 Thay đổi mật khẩu khi quên mật khẩu 77 1.9 Trang Profile của User 81 2 Quản lý sản phẩm 84 2.1 Cấu hình upload file 84 2.2 Thêm sản phẩm 85 2.3 Hiển thị thông tin sản phẩm 88 2.4 Đánh giá sản phẩm 93 2.5 Cập nhật sản phẩm 94 2.6 Xóa sản phẩm 96 3 Quản lý giỏ hàng 97 3.1 Thêm sản phẩm vào giỏ hàng 97 3.2 Hiển thị thông tin giỏ hàng 99 3.3 Cập nhật sản phẩm trong giỏ hàng 100 3.4 Xóa sản phẩm ra khỏi giỏ hàng 101 4 Thanh toán 102 5 Quản lý đơn hàng 109 5.1 Hiển thị đơn hàng cho người dùng 109 5.2 Hiển thị tất cả đơn hàng cho Admin 111 5.3 Cập nhật đơn hàng 113 6 Quản lý hình ảnh quảng cáo đầu trang chủ 114 6.1 Thêm quảng cáo 115 6.2 Sửa quảng cáo 116 6.3 Hiển thị 116 CHƯƠNG 5 KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN 118 1 Kết luận 118 1.1 Tích cực 118 1.2 Hạn chế 118 2 Hướng phát triển 119 Tài liệu tham khảo 120 Bảng phân công công việc 121
TỔNG QUAN CÔNG NGHỆ SỬ DỤNG XÂY DỰNG WEBSITE .6
Giới thiệu
Spring là một framework phát triển ứng dụng Java phổ biến, được hàng triệu lập trình viên tin dùng Nó hỗ trợ tạo ra các ứng dụng có hiệu suất cao, dễ dàng kiểm thử và cho phép tái sử dụng mã nguồn hiệu quả.
Spring là một mã nguồn mở, được phát triển, chia sẻ và có cộng đồng người dùng rất lớn.
Spring Framework được xây dựng dựa trên 2 nguyên tắc design chính là:
Dependency Injection và Aspect Oriented Programming.
Spring cung cấp những tính năng cốt lõi hỗ trợ phát triển ứng dụng Java Desktop, mobile và Java Web Mục tiêu chính của Spring là đơn giản hóa quá trình phát triển các ứng dụng J2EE thông qua mô hình POJO (Plain Old Java Object).
Lợi ích sử dụng
Spring cho phép lập trình viên sử dụng POJOs, giúp giảm thiểu sự phức tạp khi làm việc với EJB (Enterprise Java Beans), ứng dụng, luồng chạy và cấu hình Nhờ đó, quy trình phát triển trở nên đơn giản và hiệu quả hơn.
Spring được tổ chức theo mô hình mô đun, cho phép nhà phát triển chỉ tập trung vào các gói và lớp tính năng cần thiết cho dự án của mình mà không phải lo lắng về các phần không liên quan Điều này giúp tối ưu hóa quy trình phát triển ứng dụng và nâng cao hiệu quả làm việc.
Spring hỗ trợ sử dụng khá nhiều công nghệ như ORM Framework, các logging framework, JEE, các thư viện tạo lịch trình (Quartz và JDK timer)…
Module Web của Spring được thiết kế theo mô hình MVC nên nó cung cấp đầy đủ các tính năng giúp thay thế các web framework khác như Struts.
Mục đích sử dụng chính trong đề tài
Công nghệ chính trong đồ án này là RESTful API, được sử dụng để xây dựng và cung cấp dữ liệu cần thiết cho việc hiển thị giao diện trang web.
Giới thiệu
React là một thư viện UI được phát triển bởi Facebook, giúp xây dựng các thành phần UI tương tác cao, có trạng thái và có thể tái sử dụng Thư viện này không chỉ được sử dụng tại Facebook trong môi trường sản xuất mà còn là nền tảng chính để phát triển Instagram.
Một trong những ưu điểm nổi bật của React là khả năng hoạt động không chỉ trên phía client mà còn có thể render trên server, cho phép kết nối linh hoạt giữa hai môi trường React thực hiện việc so sánh sự thay đổi giữa các giá trị của lần render hiện tại và lần render trước đó, từ đó cập nhật một cách tối ưu nhất các thay đổi trên DOM.
Lợi ích sử dụng
Lợi ích đầu tiên của ReactJS là khả năng tạo ra một DOM ảo, nơi các component được lưu trữ Việc sử dụng DOM ảo này giúp cải thiện hiệu suất làm việc đáng kể, vì ReactJS sẽ tính toán trước các thay đổi cần thiết trước khi thực hiện chúng trên DOM thực Điều này giúp tránh những thao tác tốn kém trên DOM mà không phát sinh thêm chi phí.
Một trong những lợi ích nổi bật của ReactJS là cú pháp JSX, giúp việc viết mã JavaScript trở nên dễ dàng hơn bằng cách cho phép kết hợp giữa HTML và JavaScript Điều này cho phép chúng ta thêm đoạn mã trực tiếp vào hàm render mà không cần phải nối chuỗi, tạo ra sự tiện lợi và linh hoạt Việc chuyển đổi HTML thành các hàm khởi động được thực hiện thông qua bộ biến đổi JSX, làm nổi bật tính năng độc đáo của ReactJS.
ReactJS cung cấp nhiều công cụ phát triển hữu ích, giúp việc viết mã và sửa lỗi trở nên dễ dàng hơn nhờ vào các ứng dụng hỗ trợ phong phú.
Mục đích sử dụng chính trong đề tài
Xây dựng các Component giao diện tương tác với hệ thống Backend của trang web thông qua việc gửi các request đến các RESTful API.
3 Hệ quản trị cơ sở dữ liệu MySQL
Giới thiệu
MySQL là phần mềm quản lý hệ thống cơ sở dữ liệu, cho phép lưu trữ thông tin một cách có tổ chức và rõ ràng Cơ sở dữ liệu là hệ thống giúp sắp xếp và phân loại thông tin một cách ngăn nắp, phục vụ cho việc truy xuất và quản lý dữ liệu hiệu quả.
Lợi ích sử dụng
Khả năng mở rộng và tính linh hoạt.
Máy chủ cơ sở dữ liệu MySQL nổi bật với tính linh hoạt và khả năng xử lý các ứng dụng lớn, cho phép quản lý kho dữ liệu khổng lồ lên đến hàng terabytes Nó hỗ trợ nhiều nền tảng, bao gồm tất cả các phiên bản của Windows, Unix và Linux Hơn nữa, với mã nguồn mở, MySQL cho phép người dùng tùy chỉnh theo nhu cầu để tối ưu hóa hiệu suất của máy chủ cơ sở dữ liệu.
Với kiến trúc storage-engine, MySQL cho phép cấu hình máy chủ cơ sở dữ liệu cho các ứng dụng chuyên biệt, đáp ứng nhu cầu của cả website lớn phục vụ hàng triệu người/ngày và hệ thống xử lý giao dịch tốc độ cao MySQL cung cấp khả năng xử lý mạnh mẽ, cùng với các tiện ích tải tốc độ cao, cơ chế xử lý nâng cao và bộ nhớ caches, đảm bảo đầy đủ tính năng cho hệ thống doanh nghiệp hiện đại.
MySQL đảm bảo sự tin cậy và có thể sử dụng ngay MySQL đưa ra nhiều tùy chọn
Mục đích sử dụng
Lưu trữ dữ liệu trang web thông qua hỗ trợ của các POJO được tạo trong dự án spring framework.
PHÂN TÍCH THIẾT KẾ HỆ THỐNG WEBSITE
Lựa chọn trang web khảo sát
Trong đồ án này, nhóm nghiên cứu các thành phần giao diện và tính năng thiết yếu của một website bán hàng điện tử, lấy Thế Giới Di Động (www.thegioididong.com) làm ví dụ khảo sát.
Công ty TNHH Thế Giới Di Động, được thành lập vào tháng 03/2004 bởi năm đồng sáng lập, chuyên hoạt động trong lĩnh vực mua bán và sửa chữa thiết bị điện thoại di động, thiết bị kỹ thuật số và thương mại điện tử Với kinh nghiệm từ thị trường di động những năm 1990 và nghiên cứu thói quen mua sắm của người tiêu dùng Việt Nam, thegioididong.com đã phát triển một mô hình kinh doanh độc đáo Công ty nổi bật với phong cách tư vấn bán hàng chuyên nghiệp và trang web www.thegioididong.com, trở thành cẩm nang điện thoại di động và kênh thương mại điện tử hàng đầu tại Việt Nam.
Các thành phần giao diện và chức năng của trang web thegioididong.com
1.2.1 Giao diện đầu trang chủ
Trên giao diện trang chủ, thanh điều hướng giúp người dùng dễ dàng nhận diện các loại sản phẩm mà công ty cung cấp.
Dưới thanh điều hướng, phần nội dung giới thiệu các chương trình kinh doanh và sự kiện của công ty được trình bày qua một slider quảng cáo bên trái Bên cạnh slider, khung banner nằm ở bên phải nhằm mục đích nổi bật các sản phẩm mà công ty muốn thu hút sự chú ý của người dùng.
Hình 2-1 Giao diện đầu trang chủ thegioididong
1.2.2 Giao diện danh sách sản phẩm ở trang chủ
Dưới thanh điều hướng và các slider, banner quảng cáo, chúng tôi giới thiệu một số sản phẩm nổi bật và sản phẩm mới mà công ty đang cung cấp.
Danh sách sản phẩm chỉ hiển thị một số lượng nhất định các sản phẩm, không bao gồm toàn bộ Các sản phẩm được trình bày tách biệt dựa trên các khung giao diện khác nhau.
Các danh sách sản phẩm được phân chia theo các loại khác nhau để dễ dàng phân biệt như: “điện thoại nổi bật”, “điện thoại mới”, “laptop nổi bật”…
Hình 2-2 Hiển thị sản phẩm ở trang chủ
1.2.3 Thông tin sản phẩm được hiện thị ở trang chủ
Thông tin một sản phẩm được hiển thị ở trang chủ bao gồm các thành phần sau:
Giá sản phẩm có giảm giá.
Phần trăm giảm giá (nếu có giảm giá).
Hình 2-3 Giao diện sản phẩm ở trang chủ thegioididong
1.2.4 Giao diện trang sản phẩm
Giao diện sản phẩm chứa các thông tin chi tiết hơn của sản phẩm Bao gồm các thành phần sau:
Phần phía trên gồm: Slider hình ảnh sản phẩm, tên sản phẩm, giá tiền, đánh giá, giảm giá.
Hình 2-4 Phần trên trang chi tiết sản phẩm thegioididong
Phần nội dung phía dưới gồm: Thông tin đánh giá mô ta sản phẩm nằm bên trái và bảng cấu hình sản phẩm nằm bên phải.
Hình 2-5 Phần dưới trang chi tiết sản phẩm thegioididong
Khung bình luận và đánh giá của khách hàng về sản phẩm được đặt ở cuối trang, bao gồm đánh giá sao và nội dung bình luận bằng văn bản.
Hình 2-6 Bình luận sản phẩm trong trang chi tiết sản phẩm thegioididong
Giỏ hàng là khu vực lưu trữ tạm thời các sản phẩm mà người dùng đã chọn, chờ đợi để hoàn tất thanh toán sau khi lựa chọn thành công Trong giỏ hàng, người dùng có thể tìm thấy các thông tin quan trọng liên quan đến sản phẩm đã thêm.
Danh sách sản phẩm với mỗi sản phẩm hiển thị các thông tin như: tên sản phẩm giá tiền, giá tiền với giảm giá, số lượng.
Thông tin liên hệ gồm tên khách hàng, số điện thoại, địa chỉ…
Hình 2-7 Giao diện giỏ hàng thegioididong
1.2.6 Giao diện trang đặt hàng
Chứa thông tin các đơn hàng của chính khách hàng đã đặt trước đó Gồm các thông tin như:
Giá tiền cho mỗi sản phẩm
Số lượng cho mỗi sản phẩm
Tổng tiền cho tất cả sản phẩm
Hình 2-8 Giao diện đơn hàng của khách hàng thegioididong
Ngoài ra khách hàng có thể tự hủy đơn hàng của chính bản thân
Hình 2-9 Giao diện đơn hàng bị khách hàng hủy thegioididong
2 Đặc tả các yêu cầu cho trang web
Sau khi khảo sát các trang web hiện có, nhóm thực hiện đồ án đã tiến hành xác định và đặc tả các yêu cầu cần thiết cho trang web của dự án.
Phần quản lý trong admin
Admin quản lý toàn bộ các hoạt động của cửa hàng.
Quản lý giao dịch, thanh toán, mua hàng, xử lý đơn hàng của khách hàng.
Quản lý hóa đơn: khi khách hàng mua hàng sẽ có hóa đơn mua gồm số tên khách hàng, địa chỉ nhận, ngày nhận…
Quản lý sản phẩm trong cửa hàng, thêm, sửa, xóa sản phẩm cập nhật hình ảnh, quản lý số lượng, giảm giá, thông tin chi tiết…
Quản lý giao diện như slider ảnh, banner…
Quản lý đơn đặt hàng: cập nhật trạng thái đơn hàng, gửi mail trạng thái hiện tại của đơn hàng cho người dùng.
Tài khoản có quyền admin có tất cả các quyền của một tài khoản user bình thường nào khác
Phần quản lý người dùng
Tài khoản người dùng sẽ bị giới hạn quyền thao tác với trang web nếu tài khoản không có quyền admin.
Người dùng có thể xem tất cả các thông tin sản phẩm của cửa hàng, hình ảnh, văn bản, giá cả, thông số kỹ thuật, nhãn hiệu…
Có thể lọc sản phẩm theo nhu cầu mua hàng.
Người dùng có thể dễ dàng thêm sản phẩm vào giỏ hàng, điều chỉnh số lượng sản phẩm theo nhu cầu và xem tổng giá trị giỏ hàng trước khi thực hiện thanh toán.
Xem trạng thái đơn hàng đã đặt trong phần danh sách đơn hàng, có thể hủy đơn hàng trước khi nhận hàng.
Yêu cầu giao diện sử dụng
Website không nên quá phức tạp
Dung lượng không quá lớn
Thanh menu, điều hướng đơn giản dễ sử dụng
Sản phẩm đầy đủ thông tin, hình ảnh.
Hiển thị thông báo ra giao diện khi có lỗi xảy ra.
Giao diện tương thích với các trình duyệt phổ biến.
Font chữ đơn giản dễ nhìn, mùa sắc trang web hài hòa.
Yêu cầu phi chức năng
Giao diện hệ thống phải dễ sử dụng, trực quan, thân thiện với người dùng.
Tốc độ xử lý nhanh chóng, chính xác
Tính bảo mật và độ an toàn cao.
Trang web tương thích với các trình duyệt khác nhau.
3 Các chức năng của trang web
Chức năng quản lý hệ thống
Quản lý đơn hàng các giao dịch.
Quản lý danh sách sản phẩm.
Quản lý cập nhật sản phẩm.
Quản lý quyền người dùng, hiển thị giao diện cho phù hợp.
Quản lý slider và banner quảng cáo
Gửi mail khi đặt hàng, đăng ký.
Thay đổi mật khẩu tài khoản qua gmail.
Chức năng giới thiệu sản phẩm
Quảng cáo sản phẩm qua slider và banner
Hiện thị danh sách sản phẩm, lọc sản phẩm theo tìm kiếm
Hiển thị thông tin sản phẩm (nhà cung cấp, giá, giảm giá, thông số sản phẩm…).
Biểu đồ Use – case tổng quát
Hình 2-10 Biểu đồ use - case tổng quát
Use – case đăng nhập
Hình 2-11 Biểu đồ Use - case đăng nhập
Tác nhân: người dùng chung.
Mô tả: Use – case cho người dùng đăng nhập vào hệ thống. Điều kiện trước: Người dùng chưa đăng nhập trước đó.
Chọn chức năng đăng nhập
Nhập thông tin đăng nhập vào form
Người dùng đăng nhập vào trang web
Hiện thị thêm thông tin dựa theo quyền
- Thông tin đăng nhập sai
Hiển thị thông báo lỗi thông tin đăng nhập
Yêu cầu nhập lại thông tin để tiếp tục đăng nhập
Use – case quản lý sản phẩm
Mô tả: Use – case cho admin quản lý danh sách, thông tin sản phẩm. Điều kiện trước: Người dùng đã đăng nhập với tài khoản Admin.
Admin tìm kiếm sản phẩm trên shop
Admin nhấn vào các nút chỉnh sửa, xóa trên giao diện sản phẩm
Thay đổi thông tin sản phẩm
Use – case quản lý giỏ hàng
Hình 2-12 Use - case quản lý giỏ hàng
Mô tả: Use – case cho phép người dùng quản lý danh sách sản phẩm trong giỏ hàng. Điều kiện trước: Người dùng đã đăng nhập vào trang web.
User thêm sản phẩm vào giỏ hàng
Use – case thanh toán
Hình 2-13 Use - case thanh toán
Để thực hiện thanh toán cho các sản phẩm đã chọn trong giỏ hàng, người dùng cần đảm bảo đã đăng nhập vào trang web Sau khi đăng nhập, giỏ hàng sẽ hiển thị các sản phẩm mà người dùng đã thêm vào để tiến hành thanh toán.
Nhấn vào nút thanh toán trong giao diện giỏ hàng
Lựa chọn phương thức thanh toán
Use – case quản lý đơn hàng
Hình 2-14 Use - case quản lý đơn hàng
Mô tả: Use – case cho admin quản lý danh sách, trạng thái của các đơn hàng. Điều kiện trước: Người dùng đã đăng nhập với tài khoản Admin.
Admin vào trang quản lý đơn hàng được hiển thị trên giao diện
Cập nhật trạng thái các đơn hàng
Gửi mail trạng thái đơn hàng
Use – case quản lý quảng cáo trên giao diện
Để quản lý danh sách hình ảnh quảng cáo trên slider và banner đầu trang chủ, người dùng cần đăng nhập với tài khoản Admin Quá trình này cho phép admin thực hiện các thao tác cần thiết để cập nhật và tối ưu hóa nội dung quảng cáo, đảm bảo hiển thị hiệu quả nhất trên trang web.
Admin vào trang quản lý Header
Thêm, sửa, xóa, cập nhật các hình ảnh vào thông tin
THAO TÁC VÀ LƯU TRỮ DỮ LIỆU
Giao diện lập trình ứng dụng JPA
JPA (Java Persistence API) là một giao diện lập trình ứng dụng trong Java, cung cấp phương pháp quản lý các mối quan hệ dữ liệu hiệu quả trong các ứng dụng sử dụng nền tảng Java.
JPA là cầu nối giữa đối tượng Java và cơ sở dữ liệu quan hệ, bao gồm các đặc tả mà không có phương thức thực thi Để hoạt động, JPA cần một JPA implementation thực hiện các đặc tả này Các công cụ ORM như Hibernate và TopLink cung cấp trình triển khai cho JPA.
JPA bao gồm ba thành phần chính là: Entity, EntityManager, và EntityManagerFactory Ngoài ra còn có, EntityTransaction, Persistence, Query.
An entity represents a corresponding table in a database, typically consisting of simple POJO classes that include only getter and setter methods.
Dưới đây là một số đặc điểm của một Entity:
Entity có thể tương tác với cơ sở dữ liệu quan hệ.
Entity được xác định thông qua một định danh (id), tương đương với khóa chính trong table của cơ sở dữ liệu quan hệ.
Entity hỗ trợ kế thừa giống như những class Java khác.
EntityManager là một interface cung cấp các API cho việc tương tác với các Entity. Một số chức năng cơ bản của EntityManager như:
Persist: phương thức này dùng để lưu một thực thể mới tạo vào cơ sở dữ liệu.
Merge: dùng để cập nhật trạng thái của entity vào cơ sở dữ liệu.
Remove: xóa một instance của entity.
EntityManagerFactory được dùng để tạo ra một instance của EntityManager.
Một Persistence định nghĩa một tập hợp các Entity class được quản lý bởi 1 instacne của EntityManager trong ứng dụng.
Persistence (javax.persistence.Persistence) class bao gồm các phương thức static để lấy instance của EntityManagerFactory.
Một Transaction là một tập hợp các thao tác trong đó tất cả các thao tác phải được thực hiện thành công hoặc tất cả thất bại.
Một database transaction bao gồm một tập hợp các câu lệnh SQL được committed hoặc rolled back trong một unit.
EntityTransaction có mối quan hệ 1-1 với EntityManager, và mọi thao tác bắt đầu từ EntityManager đều diễn ra trong một Transaction Đối tượng EntityManager đóng vai trò quan trọng trong việc tạo ra EntityTransaction.
Query Đây là một interface, được mỗi nhà cung cấp JPA implement để có được các đối tượng quan hệ đáp ứng các tiêu chí (criteria) truy vấn.
ORM tools – Hibernate
ORM viết tắt của object-relational-mapping, công nghệ cho phép chuyển đổi từ các object trong ngôn ngữ hướng đối tượng sang database quan hệ và ngược lại.
Hình 3-16 ORM Layer trong JPA
Hibernate là một trong những công cụ ORM phổ biến nhất cho ứng dụng Java Kể từ phiên bản 3.2, Hibernate đã cung cấp một JPA Implement, được sử dụng rộng rãi trong cộng đồng lập trình viên.
DAO Design Pattern
Mẫu thiết kế DAO (Data Access Object) là một phương pháp phổ biến trong việc truy xuất cơ sở dữ liệu, nhằm cung cấp các phương thức truy cập dữ liệu ở mức thấp Các tầng dịch vụ hoặc tầng nghiệp vụ (high-level) sẽ sử dụng DAO để lấy dữ liệu từ cơ sở dữ liệu, giúp che giấu cách thực hiện của các phương thức cấp thấp Điều này thực hiện theo nguyên tắc Tách logic (Separation of Logic), tạo ra sự phân tách rõ ràng giữa các tầng trong ứng dụng.
Các service hay business layer sẽ không giao tiếp trực tiếp với DB để lấy dữ liệu.
Các service sẽ giao tiếp với lớp trung gian DAO, sau đó lớp DAO sẽ giao tiếp với
DB để truy vấn dữ liệu.
Mô hình DAO (Data Access Object) dựa trên các nguyên tắc thiết kế như abstraction và encapsulation, giúp bảo vệ ứng dụng khỏi sự thay đổi trong lớp lưu trữ Nhờ đó, khi có sự thay đổi về cơ sở dữ liệu, chẳng hạn như chuyển từ Oracle sang MySQL hoặc thay đổi công nghệ lưu trữ từ file sang database, ứng dụng vẫn hoạt động ổn định mà không cần thay đổi mã nguồn chính.
Các thành phần cấu thành:
BusinessObject: Là phần sẽ sử dụng DAO để lấy dữ liệu
DAO: Là một interface chứa các phương thức trừu tượng để cho có thể truy cập vào DataSource
DAOImp: thực hiện cài đặt chi tiết các phương thức trừu tượng trong DAO, lớp này sẽ thao tác trực tiếp với DataSource.
DataSource : là nơi chứa dữ liệu, nó có thể là database, xml, json, text file, webservice, …
TransferObject: Là một Pojo (Plain old Java object) Object, được sử dụng để lưu dữ liệu.
Hình 3-17 Data Access Object Design Pattern
Spring Data JPA
Spring Data JPA là một lớp được xây dựng trên nền tảng JPA, tận dụng các chức năng của JPA như ánh xạ thực thể, vòng đời thực thể và truy vấn JPA Nó cung cấp các tính năng như kho lưu trữ không cần mã (no-code repository) và khả năng khởi tạo truy vấn thông qua tên hàm, giúp đơn giản hóa quy trình phát triển ứng dụng.
Spring Data JPA cung một tập hợp các repository interface, chỉ cần extend để có được sự cung cấp mặc định của các hàm CRUD (thêm, tạo, sửa, xóa…).
Công dụng của một số hàm mặc định:
Thêm, xóa, sửa một hoặc nhiều.
Tìm kiếm theo khóa chính
Kiểm tra có tồn tại dựa vào khóa chính được truyền vào.
Giảm thiểu tối đa boilerplate code
Một tính năng hữu ích của Spring Data JPA là khả năng tạo truy vấn database dựa trên tên hàm Đối với các truy vấn đơn giản, người dùng chỉ cần định nghĩa tên hàm trong repository bắt đầu bằng "findBy", tiếp theo là tên các thuộc tính tương ứng, kết hợp với các phép AND và OR Spring Data sẽ tự động sinh ra câu truy vấn cho chúng ta.
When creating a method in the Repository Interface, such as findByTitle(String title), Spring Data JPA automatically generates a query to search for entities based on the title, using the input parameter value in the query.
Kiến trúc tổng quát
Hình 3-18 Kiến trúc Controller-Service - Repository
Controller: là tầng giao tiếp với bên ngoài và handler các request từ bên ngoài tới hệ thống.
Service Layer: Thực hiện các nghiệp vụ và xử lý logic
Tầng Repository chịu trách nhiệm giao tiếp với cơ sở dữ liệu và các thiết bị lưu trữ, xử lý các truy vấn và cung cấp dữ liệu cho tầng Service theo yêu cầu Tầng này được hỗ trợ bởi Spring Data JPA.
2 Tạo Entity Hibernate định hình dữ liệu lưu trữ.
Lưu trữ thông tin đăng nhập tài khoản người dùng
Các thông tin được lưu trữ bao gồm của tài khoản người dùng như Email và
Trong cơ sở dữ liệu người dùng, thuộc tính "id" có kiểu dữ liệu Long, đại diện cho Id duy nhất của mỗi người dùng Thuộc tính "email" với kiểu dữ liệu String chứa địa chỉ email của người dùng, yêu cầu không được trùng lặp Mật khẩu đăng nhập được lưu trữ dưới thuộc tính "password" cũng có kiểu String Thuộc tính "provider" là một enum có tên "AuthProvider", bao gồm các giá trị như local, facebook và google Cuối cùng, thuộc tính "provider_id" có kiểu dữ liệu Long, là Id nhận được khi người dùng đăng nhập qua các nhà cung cấp dịch vụ.
Facebook và Google user_id User Quan hệ @OneToOne với User roles Set Quan hệ @ManyToMany với bảng
Role, tạo bảng phụ user_roles
2.1.2 Table user_credentials được tạo từ Hibernate UserCredentital Entity user_credentials
Khóa, liên kết id Bigint Khóa chính email Varchar password Varchar provider Varchar provider_id Varchar user_id Bigint Trường “id” bảng “User”
Lưu trữ thông tin liên quan User
Lưu trữ thông tin tài khoản người dùng bao gồm tên và ngày khởi tạo, với nhiều kiểu dữ liệu được định dạng và liên kết thông qua các bảng khác nhau.
The article outlines the attributes of a User entity in a database schema Each User has a unique identifier, denoted as "id" of type Long, and is associated with a "userCredential" of type UserCredential in a one-to-one relationship The "createdDate" attribute, of type Date, indicates the account creation date, while "name" is a String representing the user's name Additionally, "userInfo" contains contact details such as phone number and address, and the "products" attribute is a set of Product entities, establishing a one-to-many relationship mapped by the "brand" in the Product entity.
Danh sách các sản phẩm đã thêm vào (dùng khi admin thêm sản phẩm). reviews Set
Quan hệ @OneToMany với Review
Danh sách các bình luận sản phẩm người dùng đã bình luận orders Set
Quan hệ @OneToMany với Order
Danh sách các đơn hàng của người dùng avatarUrl String Đường dẫn ảnh đại diện của người dùng
2.2.2 Table User được tạo từ Hibernate User Entity users Tên thuộc tính
Khóa, liên kết id Bigint Khóa chính avatarUrl Varchar created_date Date name Varchar user_info_id Bigint
Lưu trữ thông tin liên lạc của người dùng
Lưu trữ các thông tin liên lạc như: địa chỉ, quốc gia, tỉnh thành, số điện thoại…
Trong cơ sở dữ liệu, thuộc tính của người dùng bao gồm: "id" (kiểu Long) là một mã định danh duy nhất cho mỗi người dùng; "phone" (kiểu String) lưu trữ số điện thoại; "country" (kiểu String) chỉ định quốc gia; "province" (kiểu String) thể hiện tỉnh hoặc thành phố; "district" (kiểu String) mô tả quận hoặc huyện; "detail" (kiểu String) cung cấp địa chỉ nhà hoặc địa chỉ liên hệ chi tiết; và "user" (kiểu User) thiết lập quan hệ @OneToOne với thực thể User.
Xác định thông tin liên lạc của User nào
Lưu trữ phân loại quyền hạn
Tên thuộc tính Kiểu dữ liệu Mô tả id Integer Id duy nhất cho mỗi User name ERole (enum) Danh sách quyền người dùng gồm: admin, user
2.4.2 Table Role được tạo từ Hibernate Role Entity roles Tên thuộc tính
Khóa, liên kết id Int Khóa chính name Varchar
Bảng phụ được Hibernate tạo khi sử dụng mối quan hệ ràng buộc @ManyToMany giữa User Entity và Role Entity. user_roles Tên thuộc tính
Khóa, liên kết user_id bigint Khóa chính role_id int Khóa chính
Lưu trữ các thương hiệu hàng hóa
Lưu trữ danh sách thương hiệu hàng hóa đang kinh doanh.
The article outlines the following attributes: "id" as a Long data type representing a unique identifier for each user, "name" as a String indicating the brand name, and "products" as a Set that establishes a @OneToMany relationship, mapped by the "brand" attribute in the Product table.
Danh sách các sản phẩm có thương hiệu là thương hiệu hiện tại.
2.5.2 Table brand được tạo từ Hibernate Brand Entiy brands Tên thuộc tính
Khóa, liên kết id Bigint Khóa chính name Varchar
Lưu trữ các phân loại sản phẩm
Lưu trữ danh sách các loại sản phẩm đang kinh doanh: điện thoại, laptop.
The article outlines the attributes of a User entity in a database schema, specifying that the "id" is a unique identifier of type Long for each user The "name" attribute is a String representing the brand name, while "products" is a Set that establishes a one-to-many relationship with the "category" attribute in the Product table, mapped by the @OneToMany annotation.
Danh sách các sản phẩm có phân loại là phân loại hiện tại.
2.6.2 Table Category được tạo từ Hibernate Category Entity categories Tên thuộc tính
Khóa, liên kết id Bigint Khóa chính name Varchar
Lưu trữ thông tin sản phẩm
Các thông tin được lưu trữ bao gồm: người tạo, phân loại, brand, mô tả…
Tên thuộc tính Kiểu dữ liệu Mô tả id Long Id duy nhất cho mỗi sản phẩm. user User Quan hệ @ManyToOne với User.
Tài khoản lưu sản phẩm vào Csdl. category Category Quan hệ @ManyToOne với Category.
Phân loại sản phẩm brand Brand Quan hệ @ManyToOne với Brand
The product brand includes essential details such as the creation date, product name, description, price, available quantity, discount percentage, product specifications, and a set of product images.
Quan hệ @OneToMany, mappedBy với thuộc tính “product” trong bảng
Danh sách các hình ảnh của sản phẩm hiện tại. reviews Set Quan hệ @OneToMany, mappedBy với thuộc tính “product” trong bảng Review.
Danh sách các đánh giá của sản phẩm hiện tại.
2.7.2 Bảng products được tạo từ Hibernate Product Entity products Tên thuộc tính Kiểu dữ liệu
Khóa, liên kết id Bigint Khóa chính created_date datetime description String discount int name Varchar price Int quantity Int
Brand_id Bigint references Brand(id)
Category_id Bigint references Category(id)
User_id Bigint references User(id)
Lưu trữ thông tin về thông số sản phẩm
Lưu trữ các thông tin thống số, cấu hình của thiết bị điện tử mà cửa hàng kinh doanh như: thông số Pin, màn hình, cổng kết nối…
Tên thuộc tính Kiểu dữ liệu Mô tả id Long Id duy nhất cho mỗi mục thông số. product Product Quan hệ @OneToOne mappedBy với “details” trong Product Entity
Identify the product details including CPU, RAM, hard drive, display, size, graphic card, operating system, design, front camera, rear camera, chip name, internal memory, SIM type, and battery capacity.
2.8.2 Bảng product_details được tạo từ Hibernate ProductDetails Entity product_details Tên thuộc tính Kiểu dữ liệu
Khóa, liên kết id Bigint Khóa chính cpu Varchar ram Varchar hardDrive Varchar display Varchar size Varchar graphicCard Varchar operatingSyste m
Varchar design Varchar fontCamera Varchar rearCamera Varchar chipName Varchar internalMemory Varchar sim Varchar batteryCapacity Varchar
Lưu trữ hình ảnh sản phẩm
Lưu trữ các thông tin hình ảnh của sản phẩm như: id, loại ảnh…
Tên thuộc tính Kiểu dữ liệu Mô tả id Long Id duy nhất cho mỗi ảnh type EProductImageTypeDisplay
Ảnh cần được phân loại thành một trong các loại: Slider hoặc Official Tên ảnh phải được định dạng là một chuỗi ký tự (String) và phải đi kèm với tiêu đề cụ thể Danh sách sản phẩm phải được phân loại theo phân loại hiện tại, với mối quan hệ @ManyToOne xác định sản phẩm liên quan đến ảnh hiện tại.
2.9.2 Bảng product_images được tạo từ Hibernate ProductImage Entity. product_images Tên thuộc tính
Khóa, liên kết id Bigint Khóa chính name Varchar type Varchar product_id Bigint references Product(id)
Lưu trữ các đánh giá sản phẩm
Lưu trữ các đánh giá của người dùng dành cho sản phẩm Nội dung đánh giá bao gồm văn bản bình luận và số sao đánh giá sản phẩm.
Tên thuộc tính Kiểu dữ liệu Mô tả id int Id duy nhất cho mỗi ảnh product Product Quan hệ @ManyToOne với Product
Xác định sản phẩm được bình luận user User Quan hệ @ManyToOne User
Xác định người đánh giá rating float Số sao đánh giá comment String Nội dung đánh giá time Date Thời điểm đánh giá
2.10.2 Bảng reviews được tạo từ Hibernate Review Entity reviews Tên thuộc tính
Khóa, liên kết id int Khóa chính comment varchar rating float time datetime product_id bigint references Product(id) user_id bigint references User(id)
Lưu trữ thông tin giỏ hàng
Lưu trữ thông tin sản phẩm trong giỏ hàng cho từng người dùng là rất quan trọng Mỗi sản phẩm sẽ được ghi nhận thành một dòng riêng trong bảng carts của cơ sở dữ liệu Các đơn hàng sẽ được phân biệt thông qua cột user trong bảng, giúp quản lý hiệu quả hơn.
Trong bài viết này, chúng ta sẽ xem xét các thuộc tính quan trọng của sản phẩm trong giỏ hàng Đầu tiên, thuộc tính "id" có kiểu dữ liệu Long, đại diện cho một ID duy nhất Tiếp theo, thuộc tính "user" là kiểu dữ liệu User, xác định người dùng liên quan Thuộc tính "enable" có kiểu dữ liệu Boolean, cho biết liệu sản phẩm trong giỏ hàng có được thêm vào danh sách thanh toán hay không Cuối cùng, thuộc tính "product" là kiểu dữ liệu Product, thiết lập mối quan hệ @OneToOne với sản phẩm.
Xác định sản phẩm trong giỏ hàng quantity int Số lượng cho từng sản phẩm trong giỏ hàng
2.11.2 Bảng carts được tạo từ Hibernate Cart Entity carts Tên thuộc tính
Khóa, liên kết id Bigint Khóa chính enable bit quantity int product_id Bigint references Product(id) user_id Bigint references User(id)
Lưu trữ thông tin đơn hàng
Lưu trữ các thông tin cơ bản của đơn hàng như: ngày tạo, ngày cập nhật, trạng thái đơn hàng…
Tên thuộc tính Kiểu dữ liệu Mô tả id String Id duy nhất, sử dụng uuid user User Quan hệ @ManyToOne với User.
Xác định User của đơn hàng hiện tại orderItems Set Danh sách các sản phẩm trong đơn hàng status EOrderStatus
Các trạng thái của đơn hàng gồm: Open, Confirmed, Shipping, Collected,
Returned, Canceled. settled Boolean Đơn hàng đã được thanh toán hay chưa paymentMethod EPaymentMethod
Các loại hình thanh toán bao gồm: COD và Stripe Đối với thanh toán qua Stripe, cần lưu trữ id của phiên thanh toán dưới dạng chuỗi stripeChargeId Thời điểm đơn hàng được tạo sẽ được ghi nhận là createdDate, trong khi updatedDate sẽ lưu lại thời điểm đơn hàng được cập nhật.
2.12.2 Bảng orders được tạo từ Hibernate Order Entity orders Tên thuộc tính Kiểu dữ liệu
The article discusses a database schema for a payment system, highlighting key attributes such as a primary key, created date, payment method, settlement status, charge ID from Stripe, and an updated date It also references the user ID linked to the User table, indicating a relational database structure that efficiently manages payment records.
Lưu trữ thông tin các sản phẩm trong đơn hàng
Lưu một vài thông tin sản phẩm cho mỗi mục sản phẩm trong đơn hàng
Để tránh việc thông tin đơn hàng bị thay đổi khi dữ liệu trên bảng sản phẩm được cập nhật, không nên liên kết trực tiếp với bảng dữ liệu sản phẩm.
Đơn hàng sẽ luôn giữ nguyên thông tin sản phẩm ban đầu
Tên thuộc tính Kiểu dữ liệu Mô tả id Long Id duy nhất cho mỗi order item order Order Quan hệ @ManyToOne với Order.
Identify the current OrderItem's order, including productId (Long) to store the product ID, productName (String) for the product name, price (int) for the product price, discount (int) for the discount percentage, quantity (int) for the amount of product, and total (long) for the total amount after applying the discount.
2.13.2 Bảng order_items được tạo từ Hibernate OrderItem Entity orders Tên thuộc tính
Khóa, liên kết id bigint Khóa chính product_id bigint product_name varchar price int quantity int discount int order_id varchar references Order(id)
Lưu trữ hình ảnh quảng cáo đầu trang web
Hình ảnh quảng cáo sản phẩm đầu trang web gồm Slider và Banner.
Trong cơ sở dữ liệu, thuộc tính "id" có kiểu dữ liệu là int, đại diện cho mã định danh duy nhất của mỗi hình ảnh Thuộc tính "title" có kiểu dữ liệu là String, dùng để lưu trữ tiêu đề của hình ảnh Cuối cùng, thuộc tính "fileUploadName" cũng có kiểu dữ liệu String, chứa tên hình ảnh được lưu trữ trong thư mục.
Upload linkTo String Đường dẫn hình ảnh sẽ link đến type EHeaderIamgeType
Loại ảnh Gồm: Banner, Slider enable Boolean Có hiển thị hình ảnh hay không createDate Date Thời điểm khởi tạo modifyDate Date Thời điểm thay đổi, cập nhật
2.14.2 Bảng header_images được tạo từ Hibernate HeaderImage Entity header_iamges Tên thuộc tính Kiểu dữ liệu
Khóa, liên kết id int Khóa chính file_upload_nam e varchar link_to varchar title varchar type varchar create_date datetime modify_date datetimg
ER Diagram quan hệ giữa các bảng trong csdl
Bảng 3-27 ER Diagram của Database
3 Tạo các DAO dựa trên Sping Data JPA
Create interfaces that extend JpaRepository in Spring Data JPA to establish a repository and leverage the features offered by Spring Data JPA.
In Spring applications, interfaces annotated with @Repository indicate that they serve as repositories This annotation allows for the addition of custom support methods beyond those provided by default by Spring Data JPA.
User Repository
User Credential Repository
User Contact Repository
Role Repository
Product Repository
ProductCriteria Repository
Đây là một repository được thiết lập nhằm trả về một Page - một đối tượng do Spring Data JPA định nghĩa, dùng để hỗ trợ phân trang sản phẩm Repository này cho phép tìm kiếm sản phẩm dựa trên nhiều điều kiện khác nhau, bao gồm giá sản phẩm, cách sắp xếp và tên sản phẩm.
Product Details Repository
Product Image Repository
Review Repository
Brand Repository
Category Repository
Cart Repository
Order Repository
OrderItem Repository
HeaderImage Repository
4 Kết nối cơ sở dữ liệu với Spring Boot
Spring Boot simplifies the configuration of database connections To enable Spring to connect to a database, it is essential to configure the necessary parameters in the application.properties file.
Một số loại cấu hình quan trọng:
spring.datasource.driver-class-name
Xây dựng RESTful Web Service
Một số khái niệm
Spring Security là một dự án quan trọng trong hệ sinh thái Spring, cung cấp các dịch vụ bảo mật toàn diện cho ứng dụng doanh nghiệp dựa trên Java EE Nó hỗ trợ hai cơ chế bảo mật cơ bản, giúp tăng cường an ninh cho các ứng dụng.
Authentication is the process of establishing a principal, which can refer to a person, device, or system capable of performing actions within your application.
Phân quyền (Authorization) hay kiểm soát truy cập (Access-control) là quá trình xác định xem một principal có quyền thực hiện hành động trong ứng dụng hay không Trước khi tiến hành phân quyền, principal phải được xác thực thông qua Authentication Hai cơ chế này rất phổ biến trong các dịch vụ bảo mật, không chỉ riêng Spring Security.
1.1.1.2 Các thành phần cốt lỗi
SecurityContext là interface quan trọng trong Spring Security, chịu trách nhiệm lưu trữ toàn bộ thông tin liên quan đến bảo mật trong ứng dụng Khi Spring Security được kích hoạt, SecurityContext cũng sẽ tự động được khởi động.
Không thể truy cập trực tiếp vào SecurityContext; thay vào đó, lớp SecurityContextHolder sẽ được sử dụng để lưu trữ security context hiện tại của ứng dụng Lớp này bao gồm chi tiết về principal đang tương tác với ứng dụng, và Spring Security sử dụng một đối tượng Authentication để biểu diễn thông tin này.
User Details is a core interface of Spring Security that represents a principal in a more extended and specific manner It includes several essential methods that define user-related information and functionality.
getAuthorities(): trả về danh sách các quyền của người dùng
getPassword(): trả về password đã dùng trong qúa trình xác thực
getUsername(): trả về username đã dùng trong qúa trình xác thực
isAccountNonExpired(): trả về true nếu tài khoản của người dùng chưa hết hạn
isAccountNonLocked(): trả về true nếu người dùng chưa bị khóa
isCredentialsNonExpired(): trả về true nếu chứng thực (mật khẩu) của người dùng chưa hết hạn
isEnabled(): trả về true nếu người dùng đã được kích hoạt
User DetailsService là một interface với phương thức duy nhất là loadUser ByUsername(String username), dùng để trả về một UserDetails dựa trên username của người dùng Phương thức này cho phép tìm kiếm trong cơ sở dữ liệu để lấy record phù hợp với username, và có thể thay thế username bằng các trường khác như email.
Một GrantedAuthority là một quyền được ban cho principal Các quyền đều có tiền tố là ROLE_, ví dụ như ROLE_ADMIN, ROLE_MEMBER
WebSecurityConfigurerAdapter là một interface tiện ích của Spring Security giúp chúng ta cài đặt các thông tin dễ dàng hơn
WebSecurityConfig, kế thừa từ WebSecurityConfigurerAdapter, chứa toàn bộ cấu hình cho Spring Security được sử dụng trên Server trong đồ án, bao gồm thiết lập CORS, phân quyền cho từng Endpoint và xử lý lỗi đăng nhập.
JWT là một phương tiện đại diện cho các yêu cầu chuyển giao giữa hai bên Client –
Chuỗi JWT (JSON Web Token) bao gồm ba phần chính: header, payload và signature, được phân tách bằng dấu “.” Thông tin trong chuỗi này được định dạng bằng JSON, giúp xác thực và truyền tải dữ liệu một cách an toàn giữa các bên.
Phần header sẽ chứa kiểu dữ liệu , và thuật toán sử dụng để mã hóa ra chuỗi JWT
Phần payload sẽ chứa các thông tin mình muốn đặt trong chuỗi Token như username, userId…
Phần signature sẽ được tạo ra bằng cách mã hóa phần header , payload kèm theo một chuỗi secret (khóa bí mật).
1.1.1.2 Khởi tạo JWT ở Server trang web.
TokenProvider: class được khởi tạo với mục đích tạo, xác nhận các JWT token phục vụ cho việc bảo mật và quản lý quyền hạn User.
appPropetites connects to the application.properties file to retrieve environment variables essential for generating JWT tokens, including app.auth.tokenSecret, which defines the secret in the signature, and app.auth.tokenExpirationMsec, which specifies the token's expiration duration.
createToken: Tạo Jwt gồm các phần thông tin. o Subject: UserCredential id có được từ Authentication (Authentication là một
Khi một người dùng đăng nhập thành công, hệ thống sẽ tạo ra một đối tượng chứa thông tin quan trọng Đối tượng này bao gồm thời điểm được tạo (IssuedAt), thời hạn sử dụng của token (Expiration) và thuật toán mã hóa cùng với bí mật chữ ký (Sign).
getUserIdFromToken: lấy UserCredential id từ JWT để có thể lấy ra các dữ liệu khác về User từ database.
validateJwtToken: kiểm tra một JWT token có hợp lệ.
Spring Framework cung cấp một API để gửi email, bao gồm một vài interface và một vài lớp hỗ trợ.
Utilizing Thymeleaf templates for email creation is an effective approach in Spring Mail By leveraging Thymeleaf, developers can dynamically generate email content, enhancing the overall user experience and ensuring that messages are visually appealing and personalized.
Các file cấu hình bao gồm:
application.properties: dựa trên Spring Boot cấu hình các thuộc tính khi gửi mail thông qua Spring Mail như: protocol, host, port, username, password…
ThymeleafTemplateConfig: cấu hình thư mục lưu trữ các templates, định dạng các thuộc tính của các template.
The EmailSenderService is a class within the Service Layer that features a sendMail function, which sends emails based on two parameters: a Mail Object and a template name The Mail Object includes properties such as from, to, subject, attachments, and props The templateName refers to the name of the template located in the directory containing the list of Thymeleaf templates.
* Email sẽ được gửi từ một tài khoản mặc định được cấu hình trước trong file application.property thông qua tham số spring.mail.username.
Tạo tài khoản người dùng mới
Hình 4-36 Tạo tài khoản mới
SignupRequest (email, name, password, confirmPassword):
confirmPassword: mật khẩu xác nhận
Hình 4-37 Nhập liệu SignupRequest phía Client
Quá trình Server xử lý:
B1: Kiểm tra email đã tồn tại Nếu tồn tại => Xử lý ngoại lệ.
B2: Tạo một UserCredential mới với các thông tin mặc định.
Trường hợp thành công: message là “Đăng ký thành công”.
Hình 4-38 Thông báo đăng ký thành công
* Ở phía Client giao diện sẽ tự động chuyển sang trang đăng nhập.
Trường hợp trùng lặp email đăng ký: Xử lý ngoại lệ trả về một MessageResponse với message là “Email ‘email đăng ký’ đã được sử dụng”.
Hình 4-39 Thông báo lỗi đăng ký với Email trùng lặp
Sau khi bạn tạo tài khoản thành công, hệ thống sẽ gửi một email xác nhận đến địa chỉ email mà bạn đã sử dụng Chỉ sau khi xác nhận, người dùng mới có thể bắt đầu sử dụng tài khoản vừa được tạo.
Xác nhận Email cho tài khoản đã tạo
Tài khoản Local cần xác nhận email đăng ký trước khi có thể đăng nhập vào trang web, trong khi tài khoản Social không yêu cầu xác nhận email.
Khi người dùng tạo tài khoản trên trang web, một email xác nhận sẽ được gửi đến họ Nếu người dùng đăng nhập vào tài khoản mà chưa xác nhận email, trang web sẽ gợi ý tùy chọn "gửi lại email xác nhận" để họ có thể hoàn tất quá trình xác thực.
Hình 4-40 Gợi ý gửi lại email xác nhận
Quá trình xử lý việc gửi mail xác nhận phía Server.
Hình 4-41 Quá trình xử lý gửi lại email xác nhận
Thông báo cho người dùng việc gửi mail đã thành công.
Hình 4-42 Thông báo gửi Mail thành công
Người dùng truy cập vào email sẽ tìm thấy được email xác nhận được gửi với các thông tin sau.
Hình 4-43 Email với đường dẫn xác nhận được gửi
Khi người dùng nhấn vào đường dẫn sẽ được điều hướng sang một trang phía
Client Trang phía Client này sẽ tự động gửi yêu cầu xác nhận với Jwt token đến Server để xử lý.
Hình 4-44 Xử lý xác nhận Email dựa trên Token nhận được
Hiển thị thông báo khi xác nhận email thành công.
Hình 4-45 Thông báo khi xác nhận Email thành công
Khi Token hết hạn, người dùng sẽ nhận được thông báo kèm theo nút "gửi lại email xác nhận" để có thể gửi lại email xác nhận một lần nữa.
Hiển thị thông báo trong trường hợp Token đã hết hạn sử dụng
Hình 4-46 Thông báo khi Token Verify Email hết hạn
Thông báo khi người dùng tiếp tục gửi token xác nhận Email khi tài khoản đã có Email được xác nhận
Hình 4-47 Hiển thị thông báo Email đã được xác nhận
Đăng nhập với tài khoản
Hình 4-48 Quá trình đăng nhập với Spring Security
Sau khi đăng nhập thành công giao diện trang web sẽ chuyển về lại trang chủ
Hình 4-49 Đăng nhập thành công
* Trường hợp kết quả xác minh là sai (email hoặc password không đúng) thì Spring security sẽ xử lý lỗi thông qua authenticationEntryPoint là
RestAuthenticationEntryPoint với thông báo “Email hoặc mật khẩu không chính xác”.
Hình 4-50 Đăng nhập với thông tin tài khoản sai
Đăng nhập thông qua tài khoản FaceBook và Google
Spring Framework bao gồm một module mang tên Spring OAuth2, cho phép tương tác với các API của các nền tảng như Facebook và Google, nhằm thu thập thông tin cần thiết hỗ trợ quá trình phát triển ứng dụng.
1.5.1 Cấu hình OAuth2 dựa trên Spring boot
Yêu cầu các tham số cấu hình sau trong file application.properties:
spring.security.oauth2.client.registration.{Provider}.client-id
spring.security.oauth2.client.registration.{Provider}.client-secret
spring.security.oauth2.client.registration.{Provider}.redirect-uri
spring.security.oauth2.client.registration.{Provider}.scope
Trong đó, Provider là facebook và google Các giá trị tham số phải được lấy từ các ứng dụng/Project của bản thân được tạo trên google, facebook.
Hình 4-51 Tạo ứng dụng trên Google
Hình 4-52 Tạo ứng dụng trên Facebook
1.5.2 Thiết lập Spring Security hỗ trợ Social Login
Thêm các thuộc tính cấu hình vào class WebSecurityConfig như:
Xây dựng các lớp hỗ trợ đăng nhập và lưu trữ:
Lưu các thông tin của Oauth2 Authorization Request (clientId, redirectUrl, scope…) tạm thời trên Cookie.
Một Class thuộc Service Layer, được kế thừa từ class DefaultOAuth2UserService của Spring Security
Có một phương thức mặc định là loadUser với tham số là một
OAuth2UserRequest chứa các thông tin của User, phương thức trả về một
Authentication cho Spring Security và được gọi tự động sau khi quá trình Authorization với các Social Provider thực hiện thành công
Hàm loadUser sẽ được ghi đè lại để thực hiện các công việc sau.
B1: kiểm tra email có được từ OAuth2UserRequest có tồn tại trong Csdl
Nếu có và trùng lặp Provider thì trả về lỗi cho Client
B2: Tạo tài khoản mới và lưu thông tin vào Csdl.
B3: Trả về một UserPrincipal dựa trên các thông tin có được.
Một class kế thừa từ SimpleUrlAuthenticationSuccessHandler của Spring
Security Công việc chính là khởi tạo Token và đính kèm vào Redirect Uri cho Client.
1.5.3 Tổng quá quá trình Social Login
Hình 4-53 Quá trình Social Login
Gửi yêu cầu với Jwt access token
Upon successful login, the server sends an access token to the client The client then attaches this access token in the Authorization header for every request made to the server.
Xác minh Token trong request từ phía Client để xác định quyền truy cập được thực hiện ở Server dựa trên các bước:
Hình 4-54 Server xử lý Request với token
Phân quyền người dùng
Sau khi đăng nhập thành công người dùng được phân quyền dựa trên các quyền có được từ UserDetails thông qua phương thức getAuthorities().
Spring Security sẽ dựa vào cấu hình authorizeRequests trong WebSecurityConfig để xác định các quyền yêu cầu để sử dụng các EndPoint của Webservice.
Ngoài cấu hình trong WebSecurityConfig, có thể sử dụng trực tiếp Anotation
@PreAuthorize với quyền cụ thể trên các phương thức thuộc lớp Controller để xác định quyền yêu cầu sử dụng.
Nếu người dùng chưa đăng nhập và cố gắng truy cập vào các trang nội dung yêu cầu quyền hạn, trang web sẽ tự động chuyển hướng họ đến trang đăng nhập.
Nếu người dùng đã đăng nhập nhưng cố gắng truy cập vào các trang nội dung yêu cầu quyền hạn cao hơn quyền hiện tại của tài khoản, hệ thống sẽ tự động chuyển hướng họ về trang chủ.
Thay đổi mật khẩu khi quên mật khẩu
1.8.1 Gửi email xác nhận đổi lại mật khẩu
Khi người dùng quên mật khẩu đăng nhập Nhấn vào dòng chữ quên mật khẩu ở Form đăng nhập để tiến hành cập nhật lại mật khẩu.
Hình 4-55 Tính năng lấy lại mật khẩu ở Form đăng nhập
Hình 4-56 Form nhập Email cần reset password
Sau đó thông tin sẽ được gửi đến Server và tiến hành xử lý.
Hình 4-57 Gửi mail xác nhận reset password
Sử dụng Jwt để tăng tính bảo mật cho việc thay đổi mật khẩu
Jwt được tạo có phần payload chứa thông tin “email” người dùng yêu cầu đổi mật khẩu
Mail được gửi thông qua EmailSenderService.
Email không tồn tại trong csdl
Hình 4-58 Email xác nhận reset password không tồn tại
Mail được gửi thành công
Hình 4-59 Gửi email reset password thành công
Mail xác nhận được gửi với đường dẫn đến trang đổi mật khẩu.
Khi người dùng nhấp vào "đường dẫn" trong email, họ sẽ được chuyển đến giao diện để tiến hành đổi mật khẩu mới Đường dẫn này sẽ bao gồm Jwt token được tạo ra trước đó.
Hình 4-60 Trang đổi mật khẩu mới
Sau khi nhập xong thông tin dữ liệu sẽ được xử lý ở Server thông qua các bước sau
Lỗi khi mật khẩu xác nhận không chính xác
Hình 4-62 Thông báo đổi mật khẩu với mật khẩu xác nhận không chính xác Đổi mật khẩu thành công
Hình 4-63 Thông báo đổi mật khẩu thành công
Để tránh việc sử dụng mã token để đổi mật khẩu nhiều lần, các đường dẫn từ token JWT sẽ có thời hạn sử dụng nhất định Khi sử dụng token hết hạn, người dùng sẽ nhận được thông báo lỗi.
Hình 4-64 Thời gian đổi mật khẩu hết hạn
Trang Profile của User
Hình 4-65 Trang Profile người dùng
Để xem thông tin khách hàng và đơn hàng đã đặt, người dùng cần đăng nhập với quyền User trên Server Phần thông tin đơn hàng sẽ được trình bày chi tiết trong các mục sau.
Các thông tin của khách hàng có được thông qua Request đến Endpoint user/me ở phía Server.
Hình 4-66 Lấy thông tin người dùng hiện tại
Hình 4-67 Cấu trúc JSON(UserInfoResponse) trả về
Để đổi mật khẩu, người dùng chỉ cần nhấn vào nút “đổi mật khẩu” trên trang Profile Sau đó, một email xác nhận sẽ được gửi đến địa chỉ email hiện tại của người dùng Các bước thực hiện tiếp theo tương tự như hướng dẫn trong phần “thay đổi mật khẩu khi quên mật khẩu”.
1.9.2.2 Thay đổi thông tin liên hệ
Người dùng nhập thông tin mới và gửi yêu cầu thay đổi thông tin đến Server.
Hình 4-68 Form nhập thông tin liên hệ mới
Server thực hiện xác định người dùng hiện tại và tiến hành cập nhật dữ liệu.
Hình 4-69 Thay đổi thông tin liên hệ phía Server
Thông báo và hiển thị dữ liệu cập nhật sau khi quá trình cập nhật thành công.
Hình 4-70 Thông báo hiển thị thông tin liên lạc sau khi cập nhật
Cấu hình upload file
Các hình ảnh của các sản phẩm sẽ được upload và lưu trữ vào một thư mục trong project thay vì lưu trực tiếp vào Database.
Xây dựng một class thuộc Service Layer là FileStorageServiceImpl chứa các phương thức hỗ trợ việc upload cũng như xóa bỏ hình ảnh FileStorageServiceImpl được implements từ interface FilesStorageService.
Các Enpoint hỗ trợ tính năng Upload
Post => /files/upload: upload thủ công một file bất kỳ.
Get => /files: chứa thông tin của tất cả các file đã upload Tên file trong thư mục upload và đường dẫn để lấy dữ liệu trực tiếp.
Hình 4-72 Thông tin các file được upload thông qua Endpoint
Get => /files/{filename}: dữ liệu cụ thể của từng file upload Tìm kiếm dựa trên filename.
Thêm sản phẩm
Yêu cầu quyền hạn Admin để thực hiện việc thêm sản phẩm mới cho trang web.
Sau khi đăng nhập với tài khoản Admin, vào mục “Thêm sản phẩm” để chuyển đến Form thêm sản phẩm.
To add a product, fill in all required product information and click the "Add Product" button The client will compile the details and send a request to the server to process the addition of the product to the shop's website.
Hình 4-73 Form thêm sản phẩm
Khi người dùng nhập thiếu thông tin sản phẩm, thì sẽ hiển thị thông báo lỗi cho người dùng nhập đầy đủ các thông tin.
Hình 4-74 Xử lý nhập thiếu thông tin phía Client
2.2.2 Thêm sản phẩm phía Server
Server nhận và xử lý Request từ Client theo các bước:
Hình 4-75 Xử lý thêm hình ảnh phía Server
Trong đó Form Data gửi đến Server được chia thành các phần riêng biệt sau:
Khi thông tin sản phẩm không đầy đủ, bao gồm các văn bản và số liệu, hệ thống sẽ trả về danh sách lỗi yêu cầu thông tin cho các thuộc tính còn thiếu.
Hình 4-76 Xử lý lỗi thiếu thông tin khi thêm sản phẩm phía Server
1 File ảnh chính của sản phẩm
Danh sách các file ảnh cho phần slider ảnh giới thiệu sản phẩm.
Client hiển thị thông báo sau khi thêm sản phẩm thành công.
Hình 4-77 Thông báo thêm sản phẩm thành công
Hiển thị thông tin sản phẩm
2.3.1 Danh sách sản phẩm được hiển thị theo nhu cầu
Tùy thuộc vào giao diện và yêu cầu sản phẩm, trang web sẽ hiển thị danh sách sản phẩm phù hợp Trên trang chủ, chỉ có một số sản phẩm được hiển thị mà không có bộ lọc hay thanh tìm kiếm.
Hình 4-78 Hiển thị danh sách sản phẩm ở trang chủ
Danh sách sản phẩm ở trang sản phẩm theo phân loại sẽ có bộ lọc theo giá, sắp xếp sản phẩm và thanh tìm kiếm dựa theo tên sản phẩm.
Hình 4-79 Danh sách sản phẩm ở trang sản phẩm theo phân loại
2.3.2 Lấy dữ liệu danh sách sản phẩm từ Server
Client gửi yêu cầu đến Server kèm theo các thuộc tính như: phân trang, giá cả, tên, thương hiệu, phân loại,…
Sau đó Server dựa trên các thuộc tính của yêu cầu để trả về các dữ liệu sản phẩm phù hợp.
2.3.2.1 ProductPage Object Đây là một Object phục vụ việc phân trang, giới hạn số lượng dữ liệu trả về Khi khởi tạo thì yêu cầu các thuộc tính sau:
Page: xác định vị trí trang sản phẩm hiện tại
Size: số lượng sản phẩm trên một trang
SortBy: lựa chọn sắp xếp theo trường dữ liệu nào
Object với các thuộc tính được dừ để lọc danh sách sản phẩm theo các tiêu chí khác nhau:
Category: phân loại sản phẩm
JPA Criteria API cho phép ta tạo ra các câu truy vấn bằng Java Object thay vì việc khai báo trực tiếp trong String (JPQL).
Việc sử dụng Criteria API trong Java giúp xây dựng các lệnh truy vấn phức tạp một cách linh hoạt và động, cho phép lọc sản phẩm theo nhiều tiêu chí mà không cần phải hardcode trong một chuỗi Điều này không chỉ giúp tái sử dụng mã dễ dàng mà còn đảm bảo tính chính xác ngay từ giai đoạn biên dịch, nhờ vào việc sử dụng các đối tượng Java.
The ProductCriteriaRepository is a repository designed to utilize the Criteria API for querying based on specific criteria such as product name, price, and record quantity, which are derived from the ProductPage Object and ProductSearchCriteria Object.
Các tiêu chí tìm kiếm được đặt trong request url trước khi chuyển thành
ProductPage Object và ProductSearchCriteria Object.
Hình 4-80 Các tiêu chí tìm kiếm danh sách sản phẩm gửi đến Server thông qua url query parameters
2.3.2.4 Sơ đồ các bước lấy danh sách sản phẩm.
Tại ProductCriteriaRepository, chúng tôi chuyển đổi các Product Object thành ProductResponse để bổ sung thông tin liên quan đến sản phẩm, chẳng hạn như bình luận sản phẩm, từ danh sách sản phẩm được lấy từ Server.
Trong đó một Page Product được trả về cho Client dưới dạng JSON bao gồm các dữ liệu như sau:
Hình 4-82 Dữ liệu danh sách sản phẩm trả về
Client sẽ sử dụng các dữ liệu trên để hiển thị danh sách sản phẩm cũng như phân trang cho danh sách sản phẩm.
2.3.3 Trang thông tin chi tiết của sản phẩm
2.3.3.1 Giao diện trang chi tiết sản phẩm
Khi người dùng Click vào một sản phẩm trong danh sách sản phẩm Người dùng sẽ được điều hướng sang trang chi tiết của sản phẩm đó.
Phía trên giao diện là hình ảnh sản phẩm, slider hình ảnh giới thiệu, giá cả, giảm giá…
Hình 4-83 Giao diện phía trên trang chi tiết sản phẩm
Phía dưới giao diện là hình ảnh bảng thông số sản phẩm và danh sách các bình luận.
Hình 4-84 Giao diện phía dưới trang chi tiết sản phẩm
2.3.3.2 Dữ liệu trang chi tiết sản phẩm
Client sử dụng dữ liệu từ danh sách sản phẩm để xây dựng trang chi tiết sản phẩm.
Hình 4-85 Thông tin của mỗi sản phẩm trong danh sách sản phẩm
Đánh giá sản phẩm
Người dùng phải đăng nhập để có thể đánh giá sản phẩm
Một đánh giá sản phẩm bao gồm các thông tin:
Đánh giá số sao sản phẩm
Nội dung bình luận sản phẩm
Hình 4-86 Điền đánh giá sản phẩm
Quá trình thêm đánh giá sản phẩm
Hình 4-87 Quá trình đánh giá sản phẩm được thêm
Hình 4-88 Hiển thị thông báo và đánh giá sau khi đánh giá được thêm thành công
Người dùng chỉ có thể có một đánh giá duy nhất cho mỗi sản phẩm.
Cập nhật sản phẩm
Yêu cầu quyền Admin để thực hiện việc cập nhật thông tin sản phẩm.
Admin nhấn vào nút “Chỉnh sửa” trên giao diện sản phẩm để chuyển đến Form chỉnh sửa hình ảnh
Hình 4-89 Nút "chỉnh sửa" sử dụng cho việc cập nhật thông tin sản phẩm
Khách hàng sẽ sử dụng thông tin hiện có của sản phẩm để tự động điền vào mẫu Form cập nhật sản phẩm Dưới đây là một số lưu ý quan trọng khi thực hiện việc cập nhật thông tin sản phẩm.
Loại sản phẩm là trường thông tin cố định không thể thay đổi.
Các hình ảnh của sản phẩm sẽ được giữ nguyên nếu không chọn hình ảnh mới
Hình 4-90 Các thông tin hiện tại của sản phẩm trong Form cập nhật sản phẩm
Sau khi điều chỉnh các thông tin cần thiết, hãy nhấn “Sửa thông tin sản phẩm” ở cuối Form để gửi yêu cầu cập nhật thông tin sản phẩm cùng với các thông tin đã chỉnh sửa đến Server.
Hình 4-91 Quá trình xử lý cập nhật sản phẩm
Hình 4-92 Thông báo cập nhật thông tin sản phẩm thành công
Xóa sản phẩm
Cần quyền Admin để xóa sản phẩm.
Admin nhấn vào nút “Xóa” trên giao diện sản phẩm để xóa sản phẩm.
Một popup sẽ hiển thị để xác nhận lại việc lựa chọn xóa sản phẩm.
Hình 4-93 Popup xác nhận xóa sản phẩm
Client gửi yêu cầu xóa sản phẩm đến Server kèm theo Id của sản phẩm sẽ xóa.
Để hiển thị các yếu tố giao diện liên quan đến việc quản lý giỏ hàng, như nút "thêm vào giỏ hàng" và trang giỏ hàng, người dùng cần phải đăng nhập trước.
Thêm sản phẩm vào giỏ hàng
Nhấn “Thêm vào giỏ hàng” ở trang chi tiết sản phẩm để thêm sản phẩm vào giỏ hàng
Khách hàng gửi yêu cầu thêm sản phẩm vào giỏ hàng cùng với ID sản phẩm đến máy chủ Sản phẩm sẽ được thêm vào giỏ hàng với số lượng mặc định là "1".
Hình 4-95 Thêm sản phẩm vào giỏ hàng
Hình 4-96 Thêm sản phẩm vào giỏ hàng thành công
Sản phẩm chỉ có thể thêm vào giỏ hàng một lần
Hình 4-97 Thông báo sản phẩm đã thêm vào giỏ hàng
Hiển thị thông tin giỏ hàng
Nhấn vào mục “Giỏ hàng” trên thanh điều hướng để mở trang quản lý giỏ hàng
Hình 4-98 Trang quản lý giỏ hàng
Quá trình lấy dữ liệu giỏ hàng từ Server:
Hình 4-99 Lấy dữ liệu giỏ hàng
Dữ liêu trả về dưới dạng JSON:
Hình 4-100 Dữ liệu giỏ hàng trả về từ Server dạng JSON
Cập nhật sản phẩm trong giỏ hàng
Ta có thể cập nhật số lượng sản phẩm và trạng thái (chọn hoặc không chọn mua) sản phẩm có trong giỏ hàng.
Khi có sự thay đổi trong giỏ hàng, Client sẽ gửi yêu cầu cập nhật đến Server, bao gồm các thông tin cần thiết như mã ID của giỏ hàng, số lượng sản phẩm, và trạng thái sản phẩm (đang chọn mua hay không).
Khi cập nhật giỏ hàng, chúng ta cần điều chỉnh số lượng sản phẩm còn lại cho phù hợp Các yêu cầu cập nhật giỏ hàng sẽ được phân loại thành nhiều dạng khác nhau.
Có thay đổi thuộc tính “Chọn mua”: o Thay đổi “không chọn mua” sang “chọn mua”:
Số lượng sản phẩm còn lại = Số lượng sản phẩm hiện tại – số lượng sản phẩm trong giỏ hàng. o Thay đổi “chọn mua” sang “không chọn mua”:
Số lượng sản phẩm còn lịa = Số lượng sản phẩm hiện tại + số lượng sản phẩm trong giỏ hàng.
Chỉ thay đổi số lượng sản phẩm và đang trong trạng thái “Chọn mua”
Số lượng sản phẩm còn lại = Số lượng sản phẩm hiện tại + Số lượng cũ sản phẩm trong giỏ hàng – Số lượng mới sản phẩm trong giỏ hàng.
Hình 4-101 Quy trình cập nhật giỏ hàng
Xóa sản phẩm ra khỏi giỏ hàng
Để xóa sản phẩm khỏi giỏ hàng, hãy nhấn vào biểu tượng xóa trên giao diện sản phẩm trong giỏ hàng Sau đó, Client sẽ gửi yêu cầu xóa kèm theo CartId đến Server.
Hình 4-102 Quy trình xóa sản phẩm trong giỏ hàng
Hình 4-103 Thông báo xóa sản phẩm trong giỏ hàng thành công
Nhấn nút “Tiến Hành Thanh Toán” trong trang giỏ hàng để chuyển đến trang thanh toán.
Hình 4-104 Trang thanh toán giỏ hàng
Người dùng cần cung cấp đầy đủ thông tin liên lạc trước khi thực hiện thanh toán và có thể chỉnh sửa thông tin này ngay trên trang thanh toán Quá trình cập nhật thông tin liên lạc diễn ra tương tự như khi người dùng cập nhật thông tin trên trang Profile.
Có 2 phương thức thanh toán chính là: thanh toán khi nhận hàng và thanh toán qua Stripe.
4.1.1 Thanh toán khi nhận hàng
Nhấn vào nút thanh toán khi nhận hàng để tạo đơn hàng mới Client gửi yêu cầu tạo đơn hàng
Quá trình xử lý tạo đơn hàng mới.
Hình 4-105 Quá trình xử lý thêm đơn hàng thanh toán COD Đơn hàng được lặp dựa trên các sản phẩm trong giỏ hàng đang “Chọn mua”.
Giá trị “settled” được lưu của đơn hàng mặc định là False (đơn hàng chưa được thanh toán).
Sau khi thêm đơn hàng thành công người dùng sẽ được điều hướng về trang Profile để xem đơn hàng
Hình 4-106 Hiển thị đơn hàng trang Profile
Stripe là nền tảng phần mềm hàng đầu cho kinh doanh trực tuyến, xử lý hàng tỷ đô la mỗi năm cho doanh nghiệp toàn cầu Nó cung cấp SDK cho thiết bị Android và iOS, cùng với Stripe API hỗ trợ nhiều ngôn ngữ lập trình như Ruby, Python, Java, và GO.
Hình 4-107 Tạo tài khoản Stripe
Publishable key Đây là key mà Stripe cung cấp để sử dụng dành cho native khi sử dụng Stripe SDK
Nó được sử dụng để tạo ra được EphemeralKey dùng cho việc thêm card.
Cấu hình Secret key ở file application.properties phía Server.
Như tên gọi của nó, key này là thông tin quan trọng cần được bảo mật Với key này, chúng ta có khả năng thực hiện các giao dịch như thanh toán, xóa lịch sử giao dịch và hoàn tiền.
Cấu hình Publishable key ở phía Client.
1 App gửi credit card infomation lên Stripe.
2 Stripe xử lý và trả về token.
3 App gửi token cho back-end.
4 Server giao tiếp với Stripe qua Stripe's API.
5 Khi giao dịch xong thì Stripe trả về kết quả cho server.
6 Server thông báo cho app kết quả của giao dịch.
4.1.2.3 Tạo một phiên thanh toán dựa trên Stripe API
Hình 4-108 Tạo một Stripe Session thanh toán
4.1.2.4 Thêm đơn hàng sau khi thanh toán thành công dựa trên Stripe webhook
Webhook là tính năng cho phép website tự động thông báo và gửi dữ liệu thời gian thực đến các hệ thống khi có sự kiện xảy ra, như khách hàng đăng ký, điền form, mua hàng hay gửi email Tính năng này giúp hệ thống của bạn hoạt động chủ động hơn và nâng cao khả năng trao đổi thông tin.
Sử dụng Stripe webhook được hỗ trợ bởi Stripe để bắt sự kiện người dùng thực hiện thanh toán thành công
Sau khi thanh toán thành công, Server sẽ nhận sự kiện từ Stripe Webhook, cho phép xác nhận rằng người dùng đã hoàn tất thanh toán đơn hàng, từ đó tiến hành lưu trữ thông tin đơn hàng vào cơ sở dữ liệu.
Tải file Stripe CLI exe từ trang https://github.com/stripe/stripe-cli/releases/latest. Đăng nhập Stripe thông qua Stripe CLI
Hình 4-109 Đăng nhập từ Stripe CLI
Trang đăng nhập sẽ tự động mở trên Browser
Hình 4-110 Đăng nhập Stripe CLI trên Browser
Sau đó khởi chạy Stripe CLI
Listen dùng để xác định Endpoint nhận thông tin từ Webhook sẽ là: https://localhost:8443/payment/stripe/webhooks
skip-verify: sẽ bỏ qua certificate verification của trang web.
Đoạn mã sau phần “Your webhook signing secret” cần được tích hợp vào Controller xử lý của Endpoint nhằm xác minh tính chính xác của dữ liệu nhận được từ Endpoint.
Mỗi khi có sự kiện xảy ra Stripe webhook sẽ Post các thông tin đến Enpoint được xác định.
Hình 4-112 Webhook Post các sự kiện đến Endpoint
Khi nhận được Event Session thanh toán thành công (checkout.session.completed) Server sẽ lưu đơn hàng và CSDL
Hình 4-113 Lưu đơn hàng khi nhận được Event Webhook checkout.session.completed
Khi thanh toán qua Stripe thành công, đơn hàng sẽ có dữ liệu cột “settled” là True, kèm theo một chagre_id của phiên thanh toán.
Hiển thị đơn hàng cho người dùng
Người dùng có thể truy cập vào trang Profile để xem lại các đơn hàng đã đặt.
Hình 4-114 Danh sách đơn hàng đã đặt ở trang Profile User
Quá trình lấy dữ liệu từ Server
Hình 4-115 Lấy dữ liệu các đơn hàng thuộc về một User
Dữ liệu dạng JSON được trả về:
Hình 4-116 Dữ liệu JSON danh sách đơn hàng của một User
Hiển thị tất cả đơn hàng cho Admin
5.2.1 Hiển thị danh sách đơn hàng
Dữ liệu từ Endpoint /orders/admin cho phép quản trị viên lọc đơn hàng dựa trên mã đơn hàng, tên khách hàng và trạng thái.
Hình 4-117 Trang quản lý đơn hàng Admin
Quá trinh xử lý lấy dữ liệu đơn hàng khi Admin truy cập vào trang QL đơn hàng.
Hình 4-118 Lấy dữ liệu trang QL đơn hàng Admin
Một Page chứa các trường thông tin sau đây.
Hình 4-119 Dữ liệu JSON trang QL đơn hàng Admin
Cập nhật đơn hàng
User có thể hủy đơn hàng trước khi đơn nhận đơn hàng
Admins can update the order status to reflect the current state of the order The available order statuses include Open, Confirmed, Shipping, Collected, Returned, and Canceled.
Server yêu cầu Client cung cấp thông tin về Id đơn hàng cần cập nhật Sau đó, Server xác định đơn hàng và cập nhật trạng thái cho phù hợp Các endpoint xử lý phía Server bao gồm:
orders/{id}/update: Cập nhật trạng thái đơn hàng
orders/{id}/cancel: Hủy đơn hàng
orders/{id}/return: Trả về đơn hàng
Các trạng thái đơn hàng có thể thay đổi như sau:
Hình 4-120 Thay đổi trạng thái đơn hàng
Khi đơn hàng bị hủy, dữ liệu đơn hàng vẫn được lưu trữ trong cơ sở dữ liệu mà không bị xóa, đồng thời số lượng sản phẩm trong đơn hàng sẽ được hoàn lại cho Shop.
6 Quản lý hình ảnh quảng cáo đầu trang chủ
Admin có thể vào trang quản lý quảng cáo để thêm, sửa, xóa, cập nhật các slider và banner quảng cáo đầu trang chủ.
Hình 4-121 Slider và Banner quảng cáo đầu trang chủ
Hình 4-122 Trang quản lý quảng cáo
Thêm quảng cáo
Admin cần điền đầy đủ thông tin vào Form và nhấn “thêm ảnh” Sau đó, Client sẽ gửi yêu cầu thêm ảnh quảng cáo cùng với thông tin liên quan đến Server để tiến hành xử lý.
Hình 4-123 Xử lý thêm ảnh quảng cáo
Số lượng banner quảng cáo tối đa được phép là 4 để đảm bảo giao diện không bị vỡ Khi người dùng cố gắng thêm banner quảng cáo vượt quá số lượng này, Server sẽ trả về lỗi cho Client với thông báo tương ứng.
Hình 4-124 Trường hợp banner quảng cáo đã đủ 4 mục
Thông báo khi thêm hình ảnh quảng cáo thành công.
Sửa quảng cáo
Nhấn vào nút cập nhật trên mỗi quảng cáo trong danh sách quảng cáo để cập nhật thông tin cho hình ảnh quảng cáo.
Hình 4-125 Form cập nhật thông tin quảng cáo
Dữ liệu mới sẽ được đưa đến Server và cập nhật lại cho quảng cáo cũ Việc xác định quảng cáo thông qua Id của các quảng cáo.
Hiển thị
Ta lấy dữ liệu hình ảnh bằng phương thức Get đến Endpoint /header-images.
Ở trang chủ ta chỉ cần các dữ liệu hình ảnh quảng cáo đã enable.
Ở trang QL quảng cáo của admin dữ liệu hình ảnh quảng cáo sẽ được lấy tất cả.
Dữ liệu của các quảng cáo được Server trả về dưới dạng JSON gồm các trường dữ liệu sau:
Hình 4-126 Dữ liệu JSON của danh sách các quảng cáo