Nguyên do của sự tăng trưởng trên không những nhờ sự thúc đẩy trong chuyển đổi hành vi mua hàng của người tiêu dùng sau đại dịch COVID-19, mà còn do các hoạt động quảng cáo - những ưu đã
MÔ TẢ ĐỀ TÀI
Phát biểu bài toán
1.1.1 Đặt vấn đề Đại dịch COVID-19 đã mang đến những thách thức chưa từng có cho ngành thời trang
Do đó, đòi hỏi các nhà bán lẻ nói riêng và các doanh nghiệp cần nắm bắt xu thế và tiến hành quy trình chuyển đổi số Sự thay đổi hành vi của người tiêu dùng và môi trường kinh doanh một cách nhanh chóng đã khiến các nền tảng thương mại điện tử và mạng xã hội bùng nổ lên và trở thành những kênh mua sắm trực tuyến phổ biến nhất gần đây Nguyên do của sự tăng trưởng trên không những nhờ sự thúc đẩy trong chuyển đổi hành vi mua hàng của người tiêu dùng sau đại dịch COVID-19, mà còn do các hoạt động quảng cáo - những ưu đãi không giới hạn cùng những chiến dịch truyền thông chớp nhoáng thúc đẩy bởi những nhà phát triển nền tảng thương mại điện tử ở Việt Nam với mục đích gia tăng số lượng người dùng và tổng giá trị hàng hóa trong cuộc đua tranh giành thị trường Đặc biệt hơn, ngành thời trang đang là một trong những ngành có doanh thu thương mại điện tử lớn nhất đối với người dùng trực tuyến tại thị trường tiêu dùng Việt Nam
Tuy vậy, hiện nay, các nền tảng thương mại điện tử đang đối mặt với nhiều thách thức trong việc quản lý, lưu trữ dữ liệu và tính ứng dụng thực tiễn Sự phát triển nhanh chóng của thời đại số đặt ra các câu hỏi cho các doanh nghiệp cũng như các nhà bán lẻ phải đối mặt và cần được giải quyết để có thể xây dựng một nền tảng thương mại điện tử đáp ứng các nhu cầu trên Điển hình như, một trang thương mại điện tử cần phải quản lý và lưu trữ một lượng lớn thông tin về khách hàng, sản phẩm, đơn đặt hàng, giao hàng và thanh toán Chính vì vậy, các thao tác quản lý dữ liệu và thiết kế dữ liệu phải được tích hợp và truy xuất một cách nhanh chóng, giải quyết sự tương tranh, đảm bảo dữ liệu chính xác và an toàn Một thách thức khác đó là việc xây dựng và cải tiến nền tảng giúp nâng cao doanh số và trải nghiệm người dùng như tối ưu hóa giao diện người dùng, cải tiến tính năng tìm kiếm và đề xuất, tích hợp chức năng thanh toán trực tiếp…
Nắm bắt xu thế cùng tầm quan trọng trong tối ưu hóa nền tảng trong cuộc đua số, chúng em đã quyết định lựa chọn đề tài của mình là “Xây dựng trang web bán giày thể thao” - một mặt hàng tiềm năng trong ngành công nghiệp đa sản phẩm Nền tảng của chúng em được tiến hành với mục đích cung cấp trải nghiệm mua sắm trực tuyến thuận tiện, nơi khách hàng có thể dễ dàng thao tác và thỏa sức mua sắm cho bản thân những đôi giày thể thao yêu thích chúng
Trang 13 em mong muốn việc quản lý, lưu trữ và xử lý dữ liệu trở nên dễ tiếp cận và đơn giản, cho phép các nhà bán lẻ xử lý thông tin một cách nhanh chóng và hiệu quả Với nền tảng này, hy vọng các nhà bán lẻ cũng như doanh nghiệp có thể quản lý các cửa hàng trực tuyến một cách dễ dàng và tối đa hóa tiềm năng kinh doanh của họ
1.1.3 Mục tiêu của đề tài
Mục tiêu trang web của chúng em là tạo ra một trải nghiệm mua sắm trực tuyến dễ dàng và tiện lợi cho người dùng, đặc biệt là trong bối cảnh thị trường thương mại điện tử đang đối mặt với nhiều thách thức về quản lý, lưu trữ dữ liệu và tính ứng dụng thực tiễn Sự chuyển dịch kinh doanh từ mô trình truyền thống sang mô hình thương mại điện tử của thị trường giúp chúng em hiểu rõ tầm quan trọng của việc tăng cường cải tiến và phát triển mạnh mẽ một nền tảng giữa người tiêu dùng và nhà sản xuất Ngoài ra, chúng em cũng giải quyết những vấn đề quan trọng như tối ưu hóa quản lý, lưu trữ và phân tích thông tin cho khách hàng, phát triển các tính năng của trang chúng em hy vọng rằng nền tảng của mình đáp ứng mục tiêu: minh bạch, an toàn, chính xác và tiện dụng
Trong quá trình thực hiện đề tài, nhóm đã sử dụng một số công cụ để phục vụ cho việc triển khai đề tài, bao gồm:
- Công cụ quản lý CSDL: Oracle
- Công cụ vẽ sơ đồ phân tích thiết kế: StarUML
- Công cụ xây dựng ứng dụng: Visual Studio Code, Eclipse, IntelliJ IDEA
- Công cụ quản lý mã nguồn: Github, Git.
Xác định và phân tích yêu cầu
1.2.1 Khảo sát hệ thống hiện có
- Nhóm đã thực hiện khảo sát trang web thương mại điện tử myshoes.vn, một trang web có độ uy tín cao và hướng tiếp cận tương tự với mô hình B2C của nhóm Thông qua quá trình khảo sát về cách trình bày sản phẩm, quy trình hoạt động của giỏ hàng, đặt hàng, nhóm nhận thấy một số điểm:
+ Đa dạng sản phẩm: Trang web cung cấp một loạt các sản phẩm giày đa dạng từ nhiều thương hiệu khác nhau, đáp ứng nhu cầu và phong cách của các khách hàng
+ Dễ sử dụng: Giao diện trực quan và dễ sử dụng của trang web giúp người dùng dễ dàng tìm kiếm, xem thông tin sản phẩm và thực hiện mua hàng
+ Thông tin sản phẩm chi tiết: Trang web cung cấp thông tin chi tiết về từng sản phẩm, bao gồm hình ảnh, mô tả, thông số kỹ thuật và đánh giá từ người dùng, giúp người mua có cái nhìn đầy đủ về sản phẩm trước khi quyết định mua
+ Chính sách đổi trả linh hoạt: Trang web có chính sách đổi trả dễ dàng và linh hoạt, giúp khách hàng yên tâm mua hàng và đảm bảo quyền lợi của họ
+ Bổ sung tính năng bộ lọc sản phẩm và sắp xếp tìm kiếm theo nhiều tiêu chí khác nhau tránh việc tra cứu thông tin sản phẩm gặp nhiều khó khăn trong trường hợp kết quả tìm kiếm hiển thị số lượng lớn thông tin trả về
Hình 1.2-1 Minh họa nhược điểm trang web myshoes.vn -1
+ Tối ưu hóa quy trình thanh toán và đặt hàng: chưa có tính năng tự động cập nhật trạng thái đơn hàng sau khi thanh toán thành công
Hình 1.2-2 Minh họa nhược điểm trang web myshoes.vn -2
1.2.3 Yêu cầu phi chức năng
Thiết kế CSDL
1.3.1 Mô hình thực thể mối kết hợp
Hình 1.3-1 Mô hình thực thể mối kết hợp
1.3.2 Thiết kế mô hình quan hệ
USERS (ID, NAME, USERNAME, EMAIL, PASSWORD, ADDRESS, PHONE, GENDER,
USER_ROLE (USER_ID, ROLE_ID)
PRODUCTS (ID, PRODUCT_NAME, CATEGORY, PRODUCT_PRICE, IMG_URL,
DESCRIPTION, QUANTITY, BRAND_NAME, DESIGNER)
CART (CARTID, USER_ID, TOTAL)
CART_DETAILS (CARTDETAILS_ID, CARTID, PRODUCT_ID, QUANTITY, TOTAL) SHIPINFO (SHIPPINGID, USER_ID, FULLNAME, EMAIL, PHONE, ADDRESS, CITY,
POSTCODE, COUNTRY, NOTE, SHIPDATE, INVOICEID)
INVOICE (INVOICEID, USER_ID, STATUS, ORDER_DATE, SHIP_ADDRESS,
INVOICE_DETAILS (INVOICE_DETAILS_ID, INVOICEID, PRODUCT_ID,
PRODUCTREVIEW (REVIEWID, USER_ID, PRODUCT_ID, RATING, COMMENTS,
1.3.3 Bảng thuyết minh quan hệ và thuộc tính
Kiểu dữ liệu Diễn giải
Tự động number(10, 0) Mã phân quyền
NAME Not Null varchar2(20) Tên loại phân quyền
Tự động number(19, 0) Mã người dùng
Unique varchar2(20) Tên người dùng
Unique varchar2(50) Địa chỉ email của người dùng
PASSWORD Not Null varchar2(120) Mật khẩu của người dùng được mã hóa
ADDRESS varchar2(255) Địa chỉ của người dùng
Unique varchar2(255) Số điện thoại của người dùng
GENDER varchar2(255) Giới tính của người dùng
BIRTH varchar2(255) Ngày sinh của người dùng
ROLE Not Null varchar2(255) Loại phân quyền của người dùng
ACCOUNTNONLOCKED Not Null 1 number(1, 0) Tình trạng tài khoản người dùng (1: đang mở, 0: bị chặn)
USER_ID Khóa chính number(19, 0) Mã người dùng
ROLE_ID Khóa chính number(10, 0) Mã phân quyền
Tự động number(19, 0) Mã sản phẩm
Unique varchar2(255) Tên sản phẩm
CATEGORY varchar2(255) Phân loại của sản phẩm
PRODUCT_PRICE number(19, 2) Giá sản phẩm
IMG_URL varchar2(255) Đường link hình ảnh của sản phẩm
DESCRIPTION varchar2(255) Mô tả sản phẩm
QUANTITY Not Null number(10, 0) Số lượng sản phẩm hiện có trong cửa hàng
BRAND_NAME varchar2(255) Thương hiệu của sản phẩm
DESIGNER varchar2(255) Tên người thiết kế ra sản phẩm
Tự động number(19, 0) Mã giỏ hàng
USER_ID Khóa ngoại number(19, 0) Mã người dùng
TOTAL number(19, 2) Tổng giá trị các sản phẩm trong giỏ hàng
Tự động number(19, 0) Mã chi tiết giỏ hàng
CARTID Khóa ngoại number(19, 0) Mã giỏ hàng
PRODUCT_ID Khóa ngoại number(19, 0) Mã sản phẩm hiện có trong giỏ hàng
QUANTITY Not Null number(10, 0) Số lượng sản phẩm hiện có trong giỏ hàng
TOTAL number(19, 2) Giá trị của từng loại sản phẩm trong giỏ hàng (Quantity * ProductPrice)
Tự động number(19, 0) Mã giao hàng
USER_ID Khóa ngoại number(19, 0) Mã khách hàng
FULLNAME Not Null varchar2(255) Họ tên người nhận
EMAIL Not Null varchar2(50) Địa chỉ email của người nhận
PHONE Not Null varchar2(255) Số điện thoại của người nhận
ADDRESS Not Null varchar2(255) Địa chỉ nhận hàng
CITY Not Null varchar2(255) Thành phố
POSTCODE Not Null varchar2(255) Mã bưu điện
COUNTRY Not Null varchar2(255) Quốc gia
NOTE varchar2(255) Ghi chú cho đơn vị giao hàng
SHIPDATE Not Null timestamp(6) Ngày giao hàng
INVOICEID Khóa ngoại number(19, 0) Mã hóa đơn
Tự động number(19, 0) Mã thương hiệu
BRANDNAME varchar2(255) Tên thương hiệu
Tự động number(19, 0) Mã phân loại
CATEGORYNAME varchar2(255) Tên phân loại
Tự động number(19, 0) Mã hóa đơn
USER_ID Khóa ngoại number(19, 0) Mã người dùng
STATUS Chưa thanh toán varchar2(255) Trạng thái hóa đơn
(Chưa thanh toán/ Đã thanh toán/ Thành công)
ORDER_DATE timestamp(6) Ngày tạo hóa đơn
SHIP_ADDRESS varchar2(255) Địa chỉ giao hàng
TOTAL_PRICE number(19, 2) Tổng trị giá hóa đơn
INVOICE_DETAILS_ID Khóa chính
Tự động number(19, 0) Mã chi tiết hóa đơn
INVOICEID Khóa ngoại number(19, 0) Mã hóa đơn
PRODUCT_ID Khóa ngoại number(19, 0) Mã sản phẩm
QUANTITY Not Null number(10, 0) Số lượng sản phẩm mua
DISCOUNT number(19, 2) Chiết khấu đơn hàng
PRICE number(19, 2) Giá trị của từng loại sản phẩm trong hóa đơn (Quantity * ProductPrice)
Tự động number(19, 0) Mã đánh giá
USER_ID Khóa ngoại number(19, 0) Mã người dùng
PRODUCT_ID Khóa ngoại number(19, 0) Mã sản phẩm được đánh giá
RATING Not Null number(1, 1) Đánh giá (thang 1 đến 5)
COMMENTS varchar2(255) Nội dung đánh giá
REVIEWDATE timestamp(6) Ngày viết đánh giá
1.3.4 Mô tả ràng buộc toàn vẹn
Ràng buộc 1: Thuộc tính id (mã khách hàng) trong bảng USER là duy nhất
• Nội dung: ∀user1, user2 ∈ USER: user1.id ≠ user2.id
Ràng buộc 2: Thuộc tính id trong bảng ROLE là duy nhất
• Nội dung: ∀role1, role2 ∈ ROLE: role1.id ≠ role2.id
Ràng buộc 3: Thuộc tính Id trong bảng PRODUCT là duy nhất
• Nội dung: ∀p1, p2 ∈ PRODUCT: p1.id ≠ p2.id
Ràng buộc 4: Thuộc tính CartId trong bảng CART là duy nhất
• Nội dung: ∀c1, c2 ∈ Cart: c1 CartId ≠ c2 CartId
Ràng buộc 5: Thuộc tính SHIPPINGID trong bảng SHIPPING là duy nhất
• Nội dung: ∀c1, c2 ∈ SHIPPING: c1 SHIPPINGID ≠ c2 SHIPPINGID
Ràng buộc 6: Thuộc tính BRANDID trong bảng BRAND là duy nhất
• Nội dung: ∀c1, c2 ∈ BRAND: c1 BRANDID ≠ c2 BRANDID
Ràng buộc 7: Thuộc tính CATEGORYID trong bảng CATEGORY là duy nhất
• Nội dung: ∀c1, c2 ∈ CATEGORY: c1 CATEGORYID ≠ c2 CATEGORYID
Ràng buộc 8: Thuộc tính REVIEWID trong bảng REVIEW là duy nhất
• Nội dung: ∀c1, c2 ∈ REVIEW: c1 REVIEWID ≠ c2 REVIEWID
Ràng buộc 9: Thuộc tính INVOICEID trong bảng INVOICE là duy nhất
• Nội dung: ∀c1, c2 ∈ INVOICE: c1 INVOICEID ≠ c2 INVOICEID
Ràng buộc 10: Mỗi giỏ hàng được gắn liền với một người dùng cụ thể
• Nội dung: ∀ c ∈ CART, ∃ u ∈ USER: c.UserID = u.id
Ràng buộc 11: Chi tiết giỏ hàng mô tả chi tiết của giỏ hàng bao gồm các sản phẩm trong giỏ hàng
• Nội dung: ∀cd ∈ CARTDETAILS, ∃ c ∈ CART, ∀ p ∈ PRODUCT: cd.CartID = c.CartID ∧ cd.ProductID = p.Id
Ràng buộc 12: Thông tin giao hàng bao gồm một khách hàng, một hóa đơn cụ thể
• Nội dung: ∀s ∈ SHIPINFO, ∃ u ∈ USER, ∃ i ∈ INVOICE: s.UserID = u.id ∧ s.InvoiceID = i.InvoiceID
Ràng buộc 13: Mỗi hóa đơn thuộc một khách hàng
• Nội dung: ∀i ∈ INVOICE, ∃ u ∈ USER: i.UserID = u.id
Ràng buộc 14: Mỗi chi tiết hóa đơn thuộc một hóa đơn và bao gồm nhiều sản phẩm
• Nội dung: ∀cthd ∈ INVOICEDETAILS, ∃ i ∈ INVOICE:
Ràng buộc 15: Mỗi lượt đánh giá sản phẩm bao gồm một khách hàng và một sản phẩm
• Nội dung: ∀review ∈ PRODUCTREVIEW, ∃ u ∈ USER, ∃ p ∈ PRODUCT: review.ProductId = p.id ∧ review.UserID = u.id
Ràng buộc 16: Ngày tạo hóa đơn phải lớn hơn ngày sinh của khách hàng
• Nội dung: ∀ i ∈ INVOICE, ∀ u ∈ USER: i.UserID = u.id ∧ i.OrderDay > u.Birth
Ràng buộc 17: Ngày giao hàng phải lớn hơn ngày tạo hóa đơn
• Nội dung: ∀ i ∈ INVOICE, ∀ s ∈ SHIPINFO: i InvoiceID = s.InvoiceID ∧ i.OrderDay < s.SHIPDATE
Ràng buộc 18: Ngày sinh của khách hàng phải nhỏ hơn ngày hiện tại
• Nội dung: ∀ u ∈ USER: u.Birth < SYSDAY
Ràng buộc 19: Số lượng sản phẩm nhập vào phải lớn hơn 0
Ràng buộc 20: Khách hàng phải mua sản phẩm đó mới được đánh giá
• Nội dung: ∀s ∈ SHIPINFO, ∃ u ∈ USER, ∃ i ∈ INVOICE: s.UserID = u.id ∧ s.InvoiceID = i.InvoiceID
XÂY DỰNG CÁC GIAO TÁC
Trigger
Trigger là một trường hợp đặc biệt của store procedure, nó sẽ có hiệu lực khi chúng ta thay đổi dữ liệu trên một bảng dữ liệu cụ thể, hoặc các xử lý làm thay đổi dữ liệu của các lệnh: insert, update, delete Trigger có thể chứa các lệnh truy vấn từ các bảng khác hoặc bao gồm những lệnh SQL phức tạp
Một số thuận lợi khi sử dụng trigger:
- Trigger chạy một cách tự động: chúng được kích hoạt ngay tức thì khi có sự thay đổi dữ liệu trên bảng dữ liệu
- Trigger có thể thực hiện cascade khi việc thi hành có ảnh hưởng đến những bảng liên quan
- Trigger có những hiệu lực ít bị hạn chế hơn so với ràng buộc giá trị nghĩa là có thể ràng buộc tham chiếu đến những cột của những bảng dữ liệu khác
- Khi trigger được kích hoạt bởi 1 lệnh Transact-SQL insert để thêm một bộ mới vào bảng AAA thì bộ mới này được lưu tạm thời vào một bảng tạm có tên là inserted có cùng cấu trúc với bảng AAA Khi kết thúc trigger này thì bộ dữ liệu mới thật sự lưu xuống CSDL
- Tương tự đối với lệnh delete, các bộ dữ liệu bị xóa sẽ chuyển tạm vào bảng tạm deleted
2.1.2 Cú pháp lệnh tạo Trigger
CREATE [OR REPLACE] TRIGGER
/*Lệnh REPLACE dùng để thay thế nội dung trigger cũ*/
AFTER|BEFORE INSERT OR UPDATE OR DELETE
- CREATE [OR REPLACE] TRIGGER trigger_name: tạo hoặc thay thế một trigger đã tồn tại thành trigger_name
- {INSERT [OR] | UPDATE [OR] | DELETE}: chỉ định cụ thể lệnh nào thuộc loại lệnh DML được thực thi
- ON table_name: chỉ định trigger sẽ được thực thi trên bảng nào
- [FOR EACH ROW]: cho biết cụ thể trigger sẽ thực thi trên từng dòng
1 trg_update_product_quantity Insert, delete, update
INVOICE_DETAILS Cập nhật số lượng sản phẩm khi có thay đổi trong chi tiết hóa đơn
2 Trg_check_product_quantity Insert INVOICE_DETAILS Kiểm tra số lượng sản phẩm trong kho khi tạo hóa đơn
3 Trg_ validate_brandname Insert, update
PRODUCTS Brandname chỉ thuộc các giá trị trong bảng brand như: nike, adidas, puma, adlv, balenciaga, mlb, drew, essential
4 Trg_ validate_category Insert, update
PRODUCTS Category chỉ thuộc trong bảng category: lifestyle, running, basketball
6 Trg_birth_user Insert, update
USERS Ngày sinh của khách hàng phải nhỏ hơn ngày hiện tại
7 Trg_order_date Insert, update
INVOICES Ngày tạo hóa đơn bằng ngày hiện tại
8 Trg_review PRODUCTREVIEW Khách hàng phải mua sản phẩm đó mới được đánh giá
2.1.2.1 Cập nhật số lượng sản phẩm khi có thay đổi trong chi tiết hóa đơn
Mô tả: Trigger này sẽ tự động cập nhật số lượng sản phẩm trong kho khi có thay đổi trong chi tiết hóa đơn Khi một hóa đơn được cập nhật (thêm mới, sửa đổi hoặc xóa), trigger sẽ kiểm tra các thay đổi trong chi tiết hóa đơn và cập nhật số lượng sản phẩm tương ứng trong kho
Hình 2.1-1 Trigger cập nhật sản phẩm khi có thay đổi trong chi tiết hóa đơn -1
Hình 2.1-2 Trigger cập nhật sản phẩm khi có thay đổi trong chi tiết hóa đơn -2
Trong trigger này, chúng ta sử dụng trigger "AFTER INSERT OR UPDATE OR DELETE" để xử lý các sự kiện sau khi hóa đơn được chèn, cập nhật hoặc xóa từ bảng INVOICE_DETAILS Khi có sự thay đổi trong chi tiết hóa đơn, chúng ta sẽ lấy mã sản phẩm (:NEW.PRODUCT_ID hoặc :OLD.PRODUCT_ID) và tính toán sự thay đổi số lượng (:NEW.QUANTITY - :OLD.QUANTITY hoặc :OLD.QUANTITY) để cập nhật số lượng sản phẩm trong kho
2.1.2.2 Kiểm tra số lượng sản phẩm trong kho khi tạo hóa đơn
Mô tả: Trigger này sẽ kiểm tra số lượng sản phẩm trong kho khi một hóa đơn mới được tạo Nếu số lượng sản phẩm trong kho không đủ để đáp ứng yêu cầu của hóa đơn, trigger sẽ ngăn chặn việc tạo hóa đơn và hiển thị một thông báo lỗi
Hình 2.1-3 Trigger kiểm tra số lượng sản phẩm trong kho khi tạo hóa đơn
Trong trigger này, chúng ta sử dụng trigger "BEFORE INSERT" để kiểm tra số lượng sản phẩm trước khi hóa đơn được chèn vào bảng INVOICE_DETAILS Chúng ta lấy số lượng sản phẩm có sẵn trong kho dựa trên PRODUCT_ID trong hóa đơn mới được chèn (:NEW.PRODUCT_ID) Sau đó, chúng ta so sánh số lượng yêu cầu trong hóa đơn (:NEW.QUANTITY) với số lượng có sẵn trong kho Nếu số lượng yêu cầu lớn hơn số lượng
Trang 32 có sẵn, chúng ta sẽ sử dụng lệnh RAISE_APPLICATION_ERROR để hiển thị một thông báo lỗi với mã lỗi -20001 và nội dung 'Số lượng sản phẩm không đủ trong kho'
2.1.2.3 Brandname chỉ thuộc các giá trị trong bảng BRAND
Mô tả: Nếu brandname không tồn tại trong bảng brand thì sẽ thông báo lỗi
Hình 2.1-4 Trigger Brandname chỉ thuộc giá trị trong bảng brand
2.1.2.4 Category chỉ thuộc trong bảng CATEGORY
Mô tả: Nếu category không thuộc trong bảng category thì sẽ thông báo lỗi
Hình 2.1-5 Trigger Category chỉ thuộc trong bảng CATEGORY
2.1.2.5 Ngày sinh của khách hàng phải nhỏ hơn ngày hiện tại
- Trigger sẽ được kích hoạt trước khi có sự thêm mới hoặc cập nhật trong bảng USER
- Khi có sự thay đổi, trigger sẽ kiểm tra xem ngày sinh của khách hàng có nhỏ hơn ngày hiện tại hay không
- Nếu ngày sinh không hợp lệ, trigger sẽ ngăn chặn hành động thêm mới hoặc cập nhật và in ra một thông báo lỗi
Hình 2.1-6 Trigger Trg_birth_user
2.1.2.6 Ngày tạo hóa đơn bằng ngày hiện tại
Mô tả: Ngày tạo hóa đơn bằng ngày hiện tại
Hình 2.1-7 Trigger TRG_ORDER_DATE
2.1.2.7 Khách hàng phải mua sản phẩm đó mới được đánh giá
Mô tả: Trigger này được sử dụng để đảm bảo rằng khách hàng chỉ có thể đánh giá sản phẩm nếu họ đã mua sản phẩm đó trước đó Khi có một bản ghi mới được chèn vào bảng ProductReview, trigger này sẽ kiểm tra xem khách hàng đã mua sản phẩm đó chưa Nếu khách hàng không có bản ghi trong bảng Invoice_Details tương ứng với sản phẩm, trigger sẽ ngăn việc chèn dữ liệu mới và hiển thị một thông báo lỗi
Hình 2.1-8 Trigger trg_check_product_purchase
Các Stored Procedure
Thủ tục là một chương trình con để thực hiện một hành động cụ thể nào đó Mỗi Procedure trong Oracle có tên riêng và có thể được gọi đến mỗi khi cần dùng
2.2.2 Cú pháp tạo thủ tục
CREATE [OR REPLACE] PROCEDURE
[(parameter1 [model] datatypel, parameter2 [mode2] datatype2, )]
END; /*Kết thúc thủ tục*/
Một số lưu ý khi viết procedure:
- IN: Đây là tham số mặc định, tham số này là sẽ là dữ liệu truyền vào
- OUT: Tham số này sẽ là dữ liệu truyền ra
- IN OUT: Là tham số đặc, vừa là tham số đầu vào vừa là tham số đầu ra, và thường giá trị ban đầu bị thay đổi
BEGIN procedure name (parameter1, parameter2);
STT Tên Procedure Tham số truyền vào
1 GetProductDetails Id sản phẩm Nhận vào mã sản phẩm và trả về thông tin chi tiết về sản phẩm đó
Thêm vào giỏ hàng của user với sản phẩm và số lượng tương ứng
3 CreateInvoice UserId Tạo hóa đơn của người dùng
4 GetInvoice InvoiceID Lấy ra hóa đơn và chi tiết hóa đơn dựa vào invoiceID
5 GetUserInvoices UserID Lấy ra tất cả các hóa đơn của User
6 ClearCartItems CartID Xóa tất cả sản phẩm ra khỏi giỏ hàng khi đã đặt hàng
7 GetInvoice InvoiceID Lấy ra sản phẩm có trong hóa đơn
8 GetUserInvoices UserID Lấy ra tất cả hóa đơn của user
9 GetCartDetails UserID Lấy ra thông tin giỏ hàng của user
10 GetTopSellingProducts TopCount Lấy ra top sản phẩm đã bán nhiều nhất của cửa hàng
Lấy ra top sản phẩm đã bán nhiều nhất của cửa hàng trong tháng của 1 năm
2.2.4 Mô tả một số stored procedure
2.2.4.1 In ra chi tiết sản phẩm
- Mô tả: Lấy ra chi tiết của sản phẩm được truyền id vào
2 Lấy thông tin chi tiết sản phẩm từ bảng PRODUCTS dựa trên mã sản phẩm tương ứng với tham số truyền vào
3 Hiển thị thông tin chi tiết sản phẩm
Khi thực gọi thủ tục:
2.2.4.2 Thêm sản phẩm vào giỏ hàng
- Mô tả: Thêm sản phẩm vào giỏ hàng
2 Lấy mã giỏ hàng, giá sản phẩm dựa trên mã người dùng tương ứng với tham số truyền vào
3 Procedure tính toán tổng giá trị v_total của chi tiết sản phẩm thông qua giá sản phẩm và số lượng truyền vào Dựa vào đó thực hiện thêm chi tiết vào giỏ hàng
4 Thực hiện cập nhật lại trị giá giỏ hàng ở bảng CART tương ứng với mã giỏ hàng lấy được ở bước 2
5 Hiển thị thông tin sản phẩm vừa được thêm vào giỏ hàng
Khi thực thi thủ tục:
Giả sử ta thêm vào giỏ hàng của user có id là 283 sản phẩm có id 6 với số lượng bằng 3 Đầu tiên ta kiểm tra giỏ hàng của user 283, biết user này có id giỏ hàng tương ứng là 41
Sau khi thực thi, xem lại giỏ hàng của user 283:
Sản phẩm số 6 với số lượng bằng 3 đã được thêm vào giỏ hàng
- Mô tả: Thanh toán các sản phẩm trong giỏ hàng của user
1 Khi truyền vào id của user, sản phẩm trong giỏ hàng của user sẽ được thanh toán Tạo ra hóa đơn với các chi tiết hóa đơn là các sản phẩm có trong giỏ hàng (tương tự Cart_Details)
2 Kết hợp với trigger check_product_quantity, khi thủ tục được thực thi sẽ kiểm tra số lượng sản phẩm trong giỏ hàng còn đủ hay không, nếu không đủ sản phẩm thì hóa đơn sẽ không được tạo
3 Khi hóa đơn đã được tạo, trigger trg_update_product_quantity sẽ được kích hoạt, số lượng sản phẩm trong kho sẽ được cập nhật lại theo như hóa đơn đã tạo
4 Cùng lúc, trigger Trg_DeleteCartItems sẽ được kích hoạt, các sản phẩm trong giỏ hàng (Cart_details) sẽ bị xóa ra khỏi giỏ hàng
Mô tả: Khi truyền vào id của user, sản phẩm trong giỏ hàng của user sẽ được thanh toán
Tạo ra hóa đơn với các chi tiết hóa đơn là các sản phẩm có trong giỏ hàng (tương tự Cart_Details)
Kết hợp với trigger check_product_quantity, khi thủ tục được thực thi sẽ kiểm tra số lượng sản phẩm trong giỏ hàng còn đủ hay không, nếu không đủ sản phẩm thì hóa đơn sẽ không được tạo
Sau đó, khi hóa đơn đã được tạo, trigger trg_update_product_quantity sẽ được kích hoạt, số lượng sản phẩm trong kho sẽ được cập nhật lại theo như hóa đơn đã tạo
Cùng lúc, Stored ClearCartItems sẽ được kích hoạt, các sản phẩm trong giỏ hàng (Cart_details) sẽ bị xóa ra khỏi giỏ hàng
Giả sử ta sẽ tạo hóa đơn của người dùng 283
Lúc này giỏ hàng của người dùng 283 (giỏ hàng 41):
Giỏ hàng không còn sản phẩm nào
2.2.4.4 Lấy ra hóa đơn và chi tiết hóa đơn dựa vào InvoiceID
- Mô tả: In ra màn hình thông tin của hóa đơn tương ứng
2 Lấy thông tin hóa đơn dựa trên mã sản phẩm tương ứng với tham số truyền vào
3 Hiển thị thông tin hóa đơn cùng thông tin chi tiết hóa đơn ứng với mã hóa đơn đó
Ví dụ: Ta lấy ra hóa đơn 155
2.2.4.5 Lấy ra tất cả các hóa đơn của User
- Mô tả: Lấy ra tất cả hóa đơn của user
2 Hiển thị mã người dùng
3 Thông qua vòng lặp FOR thực hiện tìm kiếm các hóa đơn có mã người dùng tương ứng với tham số truyền vào và lưu trữ vào biến invoice_ rec để hiển thị thông tin hóa đơn
4 Trường hợp ngoại lệ: nếu người dùng chưa từng đặt hàng, in ra thông báo Không tìm thấy hóa đơn cho người dùng hoặc nếu xảy ra lỗi trong quá trình thực hiện, in ra thông báo Đã xảy ra lỗi trong quá trình lấy hóa đơn
Ví dụ: Lấy ra tất cả hóa đơn của User 283
XỬ LÝ ĐỒNG THỜI
Các trường hợp gây mất nhất quán dữ liệu
Transaction là sự hợp nhất nhiều công việc thành một khối công việc Khối công việc này được xem là hoàn tất khi tất cả các công việc đều hoàn tất Và ngược lại, nếu một trong các công việc thất bại thì khối công việc được xem như thất bại
Ví dụ: Chúng ta cần thực hiện một nghiệp vụ chuyển tiền, chuyển 500 từ tài khoản A sang tài khoản B, chúng ta cần thực hiện theo 2 bước:
- 500 sẽ được trừ ở tài khoản A
- 500 sẽ được cộng ở tài khoản B
Giả sử như chúng ta thực hiện thành công tại bước 1, tuy nhiên tại bước 2 quá trình thực hiện tại bước 2 bị thất bại (lý do mất điện) => Ngân hàng sẽ bị mất tiền ở khoảng này Với Transaction, khi có điện chúng ta sẽ có 2 lựa chọn để thực hiện:
- Trả lại 500 vào tài khoản A.
- Hoặc thực hiện cộng tiền vào tài khoản B
Kết quả khi thực hiện Transaction:
- Thành công => Transaction đã được chuyển giao (Commited)
- Không thành công => Transaction bị hủy bỏ
Tình trạng này xảy ra khi có nhiều hơn một giao tác cùng thực hiện cập nhật trên 1 đơn vị dữ liệu Khi đó, tác dụng của giao tác cập nhật thực hiện sau sẽ đè lên tác dụng của thao tác cập nhật trước.
Hình 3.1-1 Minh họa lost update
Tình trạng này xảy ra khi một giao tác T1 vừa thực hiện xong thao tác đọc trên một đơn vị dữ liệu (nhưng chưa commit) thì giao tác khác (T2) lại thay đổi (ghi) trên đơn vị dữ liệu này Điều này làm cho lần đọc sau đó của T1 không còn nhìn thấy dữ liệu ban đầu nữa
Hình 3.1-2 Minh họa non-repeatable read
Là tình trạng mà một giao tác đang thao tác trên một tập dữ liệu nhưng giao tác khác lại chèn thêm các dòng dữ liệu vào tập dữ liệu mà giao tác kia quan tâm
Hình 3.1-3 Minh họa Phantom Read
Xảy ra khi một giao tác thực hiện đọc trên một đơn vị dữ liệu mà đơn vị dữ liệu này đang bị cập nhật bởi một giao tác khác nhưng việc cập nhật chưa được xác nhận
Hình 3.1-4 Minh họa Dirty Read
Trong truy suất đồng thời, deadlock là một trang thái trong đó các giao tác chờ nhau về mặt tài nguyên làm cho hệ thống đứng yên
Các mức cô lập và cơ chế khóa trong hệ quản trị cơ sở dữ liệu
Khi transaction thực hiện ở mức này, các truy vấn vẫn có thể truy nhập vào các bản ghi đang được cập nhật bởi một transaction khác và nhận được dữ liệu tại thời điểm đó mặc dù dữ liệu đó chưa được commit (uncommited data) Nếu vì lý do nào đó transaction ban đầu rollback lại những cập nhật, dữ liệu sẽ trở lại giá trị cũ Khi đó transaction thứ hai nhận được dữ liệu sai
- Đặc điểm: o Không thiết lập Shared Lock trên những đơn vị dữ liệu cần đọc Do đó không phải chờ khi đọc dữ liệu (kể cả khi dữ liệu đang bị lock bởi giao tác khác) o Vẫn tạo Exclusive Lock trên đơn vị dữ liệu được ghi, Exclusive Lock được giữ cho đến hết giao tác
- Ưu điểm: Tốc độ xử lý rất nhanh và không cản trở các giao tác thực hiện việc cập nhật dữ liệu
- Khuyết điểm: Có khả năng xảy ra mọi vấn đề truy xuất đồng thời: Dirty Read, Phantom Read, Non-repeatable read, Lost Update
3.2.2 Read Committed Đây là mức isolation mặc định, nếu bạn không đặt gì cả thì transaction sẽ hoạt động ở mức này Transaction sẽ không đọc được dữ liệu đang được cập nhật mà phải đợi đến khi việc cập nhật thực hiện xong Vì thế nó tránh được dirty read như ở mức Read Uncommitted
- Đặc điểm o Đây là mức độ cô lập mặc định của Oracle o Tạo Shared Lock trên đơn vị dữ liệu được đọc, Shared Lock được giải phóng ngay sau khi đọc xong dữ liệu o Tạo Exclusive Lock trên đơn vị dữ liệu được ghi, Exclusive Lock được giữ cho đến hết giao tác
- Ưu điểm: o Giải quyết vấn đề Dirty Read o Shared Lock được giải phóng ngay, không cần phải giữ cho đến hết giao tác nên không cản trở nhiều đến thao tác cập nhật của các giao tác khác
- Khuyết điểm: Chưa giải quyết được vấn đề Non-repeatable Read, Phantom Read, Lost Update.Phải chờ nếu đơn vị dữ liệu cần đọc đang được giữ khoá ghi (xlock)
Mức isolation này hoạt động nhứ mức read commit nhưng nâng thêm một nấc nữa bằng cách ngăn không cho transaction ghi vào dữ liệu đang được đọc bởi một transaction khác cho đến khi transaction khác đó hoàn tất
- Đặc điểm: o Tạo Shared Lock trên đơn vị dữ liệu được đọc và giữ shared lock này đến hết giao tác
➔ Các giao tác khác phải chờ đến khi giao tác này kết thúc nếu muốn cập nhật, thay đổi giá trị trên đơn vị dữ liệu này o Repeatable Read = Read Committed + Giải quyết Non-repeatable Read o Tạo Exclusive Lock trên đơn vị dữ liệu được ghi, Exclusive Lock được giữ cho đến hết giao tác
- Ưu điểm: Giải quyết vấn đề Dirty Read và Non-repeatable Read
- Khuyết điểm: Chưa giải quyết được vấn đề Phantom Read, do vẫn cho phép insert những dòng dữ liệu thỏa điều kiện thiết lập shared lock Phải chờ nếu đơn vị dữ liệu cần đọc đang được giữ khoá ghi (xlock)
Mức isolation này tăng thêm một cấp nữa và khóa toàn bộ dải các bản ghi có thể bị ảnh hưởng bởi một transaction khác, dù là UPDATE/DELETE bản ghi đã có hay INSERT bản ghi mới
- Đặc điểm: o Tạo Shared Lock trên đơn vị dữ liệu được đọc và giữ shared lock này đến hết giao tác
➔ Các giao tác khác phải chờ đến khi giao tác này kết thúc nếu muốn cập nhật, thay đổi giá trị trên đơn vị dữ liệu này o Không cho phép Insert những dòng dữ liệu thỏa mãn điều kiện thiết lập Shared Lock (sử dụng Key Range Lock) ➔ Serializable = Repeatable Read + Giải quyết Phantom Read o Tạo Exclusive Lock trên đơn vị dữ liệu được ghi, Exclusive Lock được giữ cho đến hết giao tác
- Ưu điểm: Giải quyết thêm được vấn đề Phantom Read
- Khuyết điểm: Phải chờ nếu đơn vị dữ liệu cần đọc đang được giữ khoá ghi (xlock) Cản trở nhiều đến việc cập nhật dữ liệu của các giao tác khác.
Minh họa kịch bản đồ án môn học
Trong cửa hàng, có 2 quản lý là Dương và Khánh Cả 2 đều sở hữu tài khoản nắm quyền admin của trang web cửa hàng và có thể chỉnh sửa giá cả của sản phẩm
Khoảng giữa năm 2019, khi 1 đôi giày (Air Jordan 1 Retro High OG Shadow 2018) bỗng dưng được một người nổi tiếng sử dụng và nổi tiếng trên các trang mạng xã hội Trở thành một hiện tượng mạng, với sự bùng nổ lượt tìm kiếm và lượt mua mạnh, 2 quản lý nhận biết được điều này và quyết định tăng giá đôi giày đang bán ở trang web cửa hàng mình lên nhằm kiếm lời Dương quyết định tăng giá đôi giày từ 2.000.000đ lên 3.000.000đ, còn Khánh thì chỉ tăng giá lên 2.500.000đ
Tuy nhiên, vì cả 2 nắm bắt tin tức nhanh và cùng lúc thay đổi giá mà không báo trước cho nhau Dương đã tăng giá lên 3.000.000đ, trong khi Khánh cũng thực hiện tăng giá lên 2.500.000đ Khi khách hàng truy cập vào trang web thì thấy giá của sản phẩm là 2.500.000đ
Do không có sự thống nhất ý kiến giữa 2 người nên vấn đề lost update đã xảy ra
Session 1 Session 2 Giải thích set transaction isolation level read committed;
No action Session 1 thiết lập mức cô lập là read committed
Select id, product_price from Products
No action Session 1 truy vấn xem thông tin giá của sản phẩm có id = 4
No action Session 1 tiến hành cập nhật giá của sản phẩm có id = 4 Lúc này, Session 1 đang giữ khóa của sản phẩm có id =4
UPDATE Products SET product_price = 2500000 WHERE id = 4;
Session 2 tiến hành cập nhật giá của sản phẩm có id = 4 Việp cập nhật của Session 2 chưa được thực hiện vì Session 1 đang giữ khóa
Commit; No action Session 1 commit và nhả khóa
No action Commit; Lúc này Session 2 commit, bởi vì Session 2 đã thực hiện thay đổi dữ liệu trước khi Session 1 commit nên dẫn đến Session 1 đã bị mất dữ liệu
Select id, product_price from Products
No action Khi Session 1 truy vấn xem lại sản phẩm có id = 4, thì giá trị của sản phẩm là 2.500.000đ
Vấn đề xảy ra: Session 1 truy vấn xem giá cả của sản phẩm, sau đó tiến hành thay đổi giá cả sản phẩm nhưng chưa commit dữ liệu, Session 2 update và ghi đè lên nên dẫn đến mất dữ liệu
Do mặc định transaction ban đầu là READ COMMITED Vì vậy, vấn đề lost update đã xảy ra Ta có 2 cách giải quyết:
- Session 1 sử dụng câu lệnh “Lock Table Products IN Exclusive Mode” khi update dữ liệu
- Thay mức cô lập mặc định (Read commited) thành Serializable để giải quyết
Vào một ngày, quản lý muốn xem thông tin top 5 sản phẩm được bán nhiều nhất tháng 6/2023, bao gồm mã sản phẩm, tên sản phẩm và số lượng đã bán Lúc này quản lý lấy thông tin để làm thống kê và lấy ra thông tin sản phẩm bán chạy nhất trong tháng, thì có 1 người mua sản phẩm thuộc top 2 một số lượng lớn khiến cho số lượng sản phẩm đã bán của sản phẩm này tăng lên nhiều và nhảy lên vị trí top 1 Như vậy khi quản lý xem lại thông tin top 5 thì có sự thay đổi thông tin ở vị trí xếp hạng và số lượng sản phẩm đã bán
Tình trạng non-repeatable read đã xảy ra
Lần xem đầu tiên, sản phẩm bán chạy nhất có ID 18 và đã bán 33 sản phẩm, sản phẩm bán chạy thứ 2 có ID 6 và bán được 31 sản phẩm: (1)
Sau khi xem lại, bảng xếp hạng có sự thay đổi Sản phẩm số 6 đã có sự thay đổi của Total Sold từ 31 lên 35 và nhảy lên top 1: (2)
Session 1 Session 2 Giải thích set transaction isolation level read committed;
No action Session 1 thiết lập mức cô lập là read committed. EXECUTE
No action Session 1 lấy ra top 5 sản phẩm bán chạy nhất trong tháng 6/2023 Kết quả (1)
User có id 283 thanh toán và tạo hóa đơn
Select * from invoice_details where invoiceid = 187 product _id quantity price
Sản phẩm số 6 đã được bán thêm 4 sản phẩm
Session 1 lấy ra top 5 sản phẩm bán chạy nhất trong tháng 6/2023 Kết quả (2)
Vấn đề xảy ra: Khi Session 1 đang xem top 5 sản phẩm bán chạy nhất tháng 6/2023 thì sau đó Session 2 tạo hóa đơn và mua thêm 4 sản phẩm Session 1 xem lại top 5 sản phẩm thì có sự thay đổi so với lúc trước
Do mặc định transaction ban đầu là READ COMMITED Vì vậy, vấn đề non-repeatable read đã xảy ra Thay mức cô lập mặc định (Read commited) thành Serializable để giải quyết vấn đề trên
Quản lý Nhi đang thực hiện xem danh sách sản phẩm có trong cửa hàng thì lúc này một quản lý khác nhập hàng mới về, sau đó tiến thành thêm sản phẩm mới này vào cửa hàng Nhi xem lại danh sách sản phẩm của cửa hàng thì thấy xuất hiện sản phẩm mới
Tình trạng Phantom Read đã xảy ra
Session 1 Session 2 Giải thích set transaction isolation level read committed;
No action Session 1 thiết lập mức cô lập là read committed
Trang 57 select id, quantity, product_price from products;
No action Session 1 lấy ra mã sản phẩm, số lượng sản phẩm trong kho và giá trị sản phẩm
No action Insert into PRODUCTS
1234560 select id, quantity, product_price from products;
No action Session 1 lấy ra mã sản phẩm, số lượng sản phẩm trong kho và giá trị sản phẩm
Vấn đề xảy ra: Hai lần truy vấn dữ liệu trả về 2 kết quả khác nhau Lần thứ 2 nhiều hơn lần thứ nhất Đây là vấn đề Phantom Read khi một Session đọc dữ liệu 2 lần, Session 2 cập nhật dữ liệu giữa hai lần đọc Lần thứ 2 cho ra kết quả nhiều hơn lần đọc thứ nhất
Do mặc định transaction ban đầu là READ COMMITED Vì vậy, vấn đề non-repeatable read đã xảy ra Thay mức cô lập mặc định (Read commited) thành Serializable để giải quyết vấn đề trên
Dương và Khánh là 2 quản lý của cửa hàng Dương cập nhật giá tiền của sản phẩm 7 nhưng chưa commit, Khánh cập nhật giá tiền của sản phẩm 8 nhưng chưa commit Sau đó, Dương tiếp tục cập nhật giá tiền của sản phẩm của 8 và Khánh cập nhật giá tiền của sản phẩm
7 ➔ Gây ra trường hợp deadlock
Session 1 cập nhật giá sản phẩm 7 thành
SET product_price = 22000 WHERE id = 8;
Session 2 cập nhật giá sản phẩm 8 thành
Session 1 cập nhật giá sản phẩm 8 thành
SET product_price = 25000 WHERE id = 7;
Session 2 cập nhật giá sản phẩm 7 thành
25000 Báo lỗi “deadlock detected while waiting for resource”
Vẫn đang chạy commit; Session 1 commit
Thông báo “1 row updated.” Session 2 đã cập nhật giá sản phẩm 7 thành
Select id, quantity, product_price from products where id = 7 or id = 8;
Select id, quantity, product_price from products where id = 7 or id
Vì Session 2 chưa commit nên dữ liệu ở Session 1 vẫn chưa được cập nhật
Commit; Session 2 commit dữ liệu và kết thúc
Vấn đề xảy ra: Session 1 và Session 2 luân phiên cập nhật giá trị của sản phẩm 7 và 8 dẫn đến xảy ra deadlock
Commit ngay sau khi cập nhật dữ liệu để nhả khóa
THIẾT KẾ GIAO DIỆN
Môi trường cài đặt
+ Oracle: Cơ sở dữ liệu để lưu trữ và truy xuất dữ liệu
+ Java Spring Boot: Framework hỗ trợ xây dựng back-end
+ ReactJS: Thư viện hỗ trợ xây dựng giao diện web
4.1.2 Môi trường phát triển và triển khai hệ thống
- Hệ điều hành: Windows 10, Windows 11
- Công cụ quản lý CSDL: Oracle, Oracle SQL Developer
- Công cụ vẽ sơ đồ phân tích thiết kế: StarUML
- Công cụ xây dựng ứng dụng: Visual Studio Code, IntelliJ IDEA
- Công cụ quản lý mã nguồn: Git, Github
- Trình biên dịch/phiên dịch: Java Development Kit (JDK) cho java
- Trình quản lý gói: npm (Node Package Manager) cho Node.js Maven cho Java
- Hệ điều hành: Windows 10, Windows 11
- Cài đặt: Oracle, Java Developer Kit (JDK), Node.js, npm (Node Package Manager), Maven
- Các dịch vụ bên ngoài: Dịch vụ email, Dịch vụ VNPAY
Màn hình giao diện
Header: Thành phần Header sẽ gồm một hình logo của trang web ở góc trái, phần navigation điều hướng ở giữa Góc phải là icon giỏ hàng và đăng nhập Khi người dùng đăng nhập thành công sẽ xuất hiện avatar của người dùng và username thay cho đăng nhập
Hình 4.2-1 Thành phần Header của giao diện
Footer: Thành phần Footer được chia thành 4 cột, với tên website, giới thiệu website nằm ở góc trái Ba cột còn lại là nội dung, tương ứng với các phần gồm: Top Categories, Useful Links, Contact chứa các đường dẫn đến các thông tin của website
Hình 4.2-2 Thành phần Footer của giao diện
Hình 4.2-3 Giao diện Đăng nhập
Mô tả chức năng màn hình đăng nhập: Người dùng sẽ đăng nhập với username và password của mình Nếu đăng nhập thành công sẽ hiện thông báo thành công và chuyển đến trang chủ, nếu đăng nhập thất bại sẽ hiện thông báo thất bại và người dùng phải đăng nhập lại Ngoài ra nếu chưa có tài khoản người dùng có thể click vào Tạo tài khoản sẽ được di chuyển đến trang đăng ký tài khoản
Hình 4.2-4 Giao diện Đăng ký
Mô tả chức năng trang đăng ký tài khoản: Người dùng khi đăng ký tài khoản điền tất cả các thông tin vào form đăng ký như giao diện Nếu thông tin chính xác và các trường như username, email, số điện thoại, ngày sinh hợp lệ, không trùng thì hệ thống sẽ thông báo đăng ký tài khoản thành công và chuyển đến màn hình đăng nhập Nêu thông tin không chính xác hệ thống sẽ báo lỗi và đăng ký lại
Hình 4.2-5 Giao diện Trang chủ - 1
Hình 4.2-6 Giao diện Trang chủ - 2
Hình 4.2-7 Giao diện Trang chủ - 3
Hình 4.2-8 Giao diện Trang chủ - 4
Mô tả chức năng trang chủ: Hiển thị các thông tin tổng quan về website, ngoài ra hiển thị các mục của cửa hàng như: Sản phẩm nổi bật, Sản phẩm bán chạy, Phổ biến trong doanh mục
Hình 4.2-9 Giao diện Cửa hàng - 1
Hình 4.2-10 Giao diện Cửa hàng - 2
Mô tả chức năng trang cửa hàng: Hiển thị slider chứa các banner giới thiệu, khuyến mãi
Ngoài ra trang cửa hàng có phần tìm kiếm sản phẩm, bộ lọc theo giá và sắp xếp tăng dần, giảm dần Có phần phân trang cho việc hiển thị sản phẩm
Hình 4.2-11 Giao diện Liên hệ
Mô tả chức năng trang liên hệ: Hiển thị các thông tin về cửa hàng Ngoài ra còn có form điền phản hồi của người dùng dành cho cửa hàng
4.2.7 Trang chi tiết sản phẩm
Hình 4.2-12 Giao diện Chi tiết sản phẩm - 1
Hình 4.2-13 Giao diện Chi tiết sản phẩm - 2
Hình 4.2-14 Giao diện Chi tiết sản phẩm - 3
Hình 4.2-15 Giao diện Chi tiết sản phẩm - 4
Mô tả chức năng trang chi tiết sản phẩm: Người dùng có thể xem được chi tiết toàn bộ thông tin về sản phẩm đó Bên cạnh đó hệ thống còn hiện thị các sản phẩm liên quan, đánh giá của người mua về sản phẩm
Hình 4.2-16 Giao diện Giỏ hàng
Mô tả chức năng trang giỏ hàng: Hiển thị các thông tin và giá tiền về sản phẩm mà người mua bỏ vào trong giỏ hàng Ngoài ra người dùng sẽ chỉ thanh toán được khi đã đăng nhập và sẽ được di chuyển đến trang thanh toán Nếu chưa đăng nhập sẽ không thanh toán được và di chuyển đến trang đăng nhập
Hình 4.2-17 Giao diện Thanh toán
Mô tả chức năng trang thanh toán: Người dùng sẽ nhập các thông tin để giao hàng Hiển thị hóa đơn cho người dùng Nếu người dùng chọn thanh toán khi nhận hàng, hệ thống sẽ xác nhận hóa đơn chưa thanh toán Nếu thanh toán qua VNPAY hệ thống sẽ xác nhận hóa đơn đã thanh toán Ngoài ra khi thanh toán, hệ thồng sẽ gửi email về đơn hàng về cho người dùng Và thông tin hóa đơn sẽ được lưu trong lịch sử mua hàng
Hình 4.2-18 Giao diện Thanh toán VNPAY
Hình 4.2-19 Giao diện Gửi email xác nhận đặt hàng thành công
4.2.10 Trang thông tin cá nhân
Hình 4.2-20 Giao diện Tài khoản của tôi
Mô tả chức năng trang tài khoản của tôi: Hiển thị chi tiết các thông tin của tài khoản đã đăng ký Ngoài ra còn cho phép người dùng sửa đổi thông tin
Hình 4.2-21 Giao diện Sửa hồ sơ
Hình 4.2-22 Giao diện Đổi mật khẩu
Mô tả chức năng trang đổi mật khẩu: Người dùng muốn thay đổi mật khẩu điền các thông tin như yêu cầu
4.2.12 Trang lịch sử mua hàng
Hình 4.2-23 Giao diện Lịch sử mua hàng
Mô tả chức năng trang lịch sử mua hàng: Hiển thị toàn bộ danh sách hóa đơn người dùng đã thanh toán
Hình 4.2-24 Giao diện Thông báo
Mô tả chức năng trang thông báo: Hiển thị các khuyến mãi, ưu đãi, thông báo về cho người dùng
4.2.14 Trang thống kê - Dành cho Admin
Hình 4.2-25 Giao diện Thống kê - 1
Hình 4.2-26 Giao diện Thống kê - 2
Mô tả chức năng dashboard: Hiển thị biểu đồ về các thông tin như số người đăng nhập, số sản phẩm được bán
4.2.15 Trang quản lý sản phẩm
Hình 4.2-27 Giao diện Quản lý sản phẩm
Mô tả chức năng trang quản lý sản phẩm: Nơi để người quản lý có thể thực hiện các chức thêm xóa sửa sản phẩm Ngoài ra có thể xuất toàn bộ sản phẩm hiện có ra file excel
Hình 4.2-28 Giao diện Thêm sản phẩm
Hình 4.2-29 Giao diện Sửa sản phẩm
Hình 4.2-30 Giao diện Xóa sản phẩm
4.2.16 Trang quản lý người dùng
Hình 4.2-31 Giao diện Quản lý người dùng
Mô tả trang quản lý người dùng: nhằm mục đích quản lý thông tin, tra cứu và thực hiện các hoạt động liên quan đến khách hàng Có thể xuất toàn bộ người dùng ra file excel
Hình 4.2-32 Giao diện Sửa thông tin người dùng
4.2.17 Trang quản lý hóa đơn
Hình 4.2-35 Giao diện Quản lý hóa đơn
Mô tả chức năng trang quản lý hóa đơn: Hiển thị các hóa đơn trong hệ thống đã thanh toán và tình trạng của hóa đơn