Giới thiệu dự án

Sự bùng nổ của thương mại điện tử (E-commerce) tại Việt Nam với tốc độ tăng trưởng bình quân trên 25%/năm đã thay đổi căn bản hành vi tiêu dùng từ mua sắm truyền thống sang không gian số. Tuy nhiên, các nhà sách bán lẻ truyền thống đang đối mặt với nhiều rào cản vận hành: chi phí mặt bằng đắt đỏ, khả năng tiếp cận khách hàng bị giới hạn về mặt địa lý, quy trình quản lý tồn kho thủ công dễ sai lệch và tốc độ xử lý đơn hàng chậm chạp trong các mùa cao điểm.

Đồ án tốt nghiệp "Xây dựng website bán sách" do sinh viên Bùi Doãn Khải và Nguyễn Thị Việt Anh thực hiện dưới sự hướng dẫn của TS. Nguyễn Thị Huyền Châu tại Trường Đại học Thăng Long (2024) tập trung giải quyết bài toán số hóa toàn diện quy trình phân phối sách trực tuyến, cung cấp một nền tảng thương mại điện tử chuyên biệt, ổn định và tối ưu trải nghiệm người dùng.

+-----------------------------------------------------------------------+
|                           MỤC TIÊU DỰ ÁN                              |
+-----------------------------------------------------------------------+
| 1. Kiến trúc hệ thống tách rời Client - Server (SPA & RESTful API)    |
| 2. Thiết kế CSDL phi quan hệ MongoDB linh hoạt cho thuộc tính sách     |
| 3. Tích hợp thanh toán đa phương thức (COD + Cổng VNPay)             |
| 4. Xây dựng phân hệ quản trị (Admin Dashboard) quản lý toàn diện      |
| 5. Tối ưu hiệu năng tải trang (<1.5s) và bảo mật dữ liệu giao dịch    |
+-----------------------------------------------------------------------+

Phương pháp tiếp cận và kết quả kỳ vọng

Giải pháp áp dụng mô hình kiến trúc phân tầng hiện đại: Backend xây dựng trên nền tảng Node.js với framework NestJS (sử dụng ngôn ngữ TypeScript), quản lý dữ liệu bằng MongoDB (hệ quản trị NoSQL hướng tài liệu), và Frontend phát triển bằng Vue.js kết hợp bộ thư viện giao diện Ant DesignVuetify.

  • Thời gian phản hồi API: Dưới 150ms cho các truy vấn dữ liệu thông thường.
  • Tính khả dụng: Đảm bảo hệ thống vận hành ổn định với khả năng mở rộng linh hoạt (Scalability).
  • Phạm vi hệ thống: Xử lý trọn vẹn chu trình bán lẻ B2C (từ tìm kiếm, lọc danh mục, giỏ hàng, đặt hàng, thanh toán đến quản lý đơn hàng và đánh giá sản phẩm).
  • Giới hạn: Phiên bản tập trung vào mô hình đơn nhà cung cấp, chưa tích hợp tự động tính phí vận chuyển thời gian thực từ các đơn vị thứ ba (như GHTK, GHN).

Phân tích và thiết kế giải pháp

Phân tích hiện trạng

Nghiên cứu thị trường và các giải pháp thương mại điện tử hiện nay cho thấy sự khác biệt rõ rệt giữa các mô hình kiến trúc:

Tiêu chí Nền tảng Monolithic truyền thống (PHP/WordPress) Hệ thống Enterprise (Magento) Giải pháp Decoupled (NestJS + Vue.js + MongoDB)
Kiến trúc Liền khối (Monolithic MVC) Liền khối phức hợp Phân tách rõ ràng Client - Server (SPA + RESTful API)
Hiệu năng & Tải Thấp khi lượng truy cập tăng đột biến Nặng, đòi hỏi phần cứng cấu hình cao Rất cao nhờ cơ chế bất đồng bộ (Non-blocking I/O)
Cơ sở dữ liệu RDBMS (MySQL) ràng buộc chặt RDBMS (MySQL) phức tạp, nhiều Join NoSQL (MongoDB Document JSON) linh hoạt schema
Tốc độ phản hồi 500ms - 1500ms 400ms - 1200ms 50ms - 180ms
Chi phí bảo trì Trung bình Rất cao Thấp, dễ mở rộng theo module

Hệ thống phân loại yêu cầu tính năng theo mô hình MoSCoW:

  • Must Have: Xác thực người dùng (JWT/Auth), Catalog sách & tìm kiếm, Quản lý giỏ hàng, Đặt hàng & Thanh toán (COD/VNPay), Quản trị CRUD danh mục/sản phẩm/đơn hàng.
  • Should Have: Quản lý profile người dùng, Đánh giá và bình luận theo đầu sách, Lọc sách nâng cao theo tác giả và nhà phát hành.
  • Could Have: Hệ thống mã giảm giá (Voucher), Thống kê doanh thu biểu đồ động.
  • Won't Have (v1.0): Chat trực tuyến thời gian thực với CSKH, Tích hợp đa sàn thương mại điện tử.
graph TD
    Client[Client: Vue.js + Ant Design / Vuetify] -->|HTTP / RESTful API Request| APIGateway[NestJS API Gateway / Controllers]
    APIGateway -->|Dependency Injection| AuthService[Auth & User Service]
    APIGateway -->|Dependency Injection| ProductService[Product & Category Service]
    APIGateway -->|Dependency Injection| OrderService[Order & Cart Service]
    APIGateway -->|Payment Gateway SDK| VNPayGateway[VNPay Sandbox / Live API]
    
    AuthService --> MongooseODM[(Mongoose ODM Layer)]
    ProductService --> MongooseODM
    OrderService --> MongooseODM
    
    MongooseODM --> MongoDB[(MongoDB NoSQL Database)]

Thiết kế hệ thống

Toàn bộ hệ thống được xây dựng trên nền tảng công nghệ chuẩn hóa:

Thành phần Công nghệ / Thư viện Phiên bản Vai trò kỹ thuật
Backend Runtime Node.js v18.18 LTS Môi trường thực thi JavaScript bất đồng bộ phía máy chủ
Backend Framework NestJS v10.2.x Kiến trúc Module, Dependency Injection, Controller/Service
Ngôn ngữ Backend TypeScript v5.2.x Đảm bảo tính chặt chẽ về kiểu dữ liệu (Strict Typing)
Cơ sở dữ liệu MongoDB v6.0.x Hệ quản trị CSDL NoSQL hướng tài liệu JSON
ODM Mongoose v7.6.x Mô hình hóa dữ liệu, Schema Validation và Indexing
Frontend Framework Vue.js v3.3.x Xây dựng Single-Page Application (SPA) phản ứng nhanh
Quản lý trạng thái Vuex / Pinia v4.1.x Quản lý trạng thái toàn cục (Auth state, Cart state)
UI Components Ant Design Vue + Vuetify v4.0 / v3.4 Giao diện chuẩn UI/UX, responsive và tối ưu SCSS
// Mongoose Schema minh họa cấu trúc dữ liệu Book (Sản phẩm)
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document, Types } from 'mongoose';

@Schema({ timestamps: true })
export class Book extends Document {
  @Prop({ required: true, trim: true, index: true })
  title: string;

  @Prop({ required: true })
  price: number;

  @Prop({ default: 0 })
  discount: number;

  @Prop({ required: true })
  description: string;

  @Prop({ type: Types.ObjectId, ref: 'Category', required: true, index: true })
  category: Types.ObjectId;

  @Prop({ type: Types.ObjectId, ref: 'Author', required: true })
  author: Types.ObjectId;

  @Prop({ type: Types.ObjectId, ref: 'Publisher', required: true })
  publisher: Types.ObjectId;

  @Prop({ default: 0 })
  stockQuantity: number;

  @Prop([String])
  images: string[];
}
export const BookSchema = SchemaFactory.createForClass(Book);

Thiết kế RESTful API

Hệ thống tuân thủ các chuẩn HTTP Methods (GET, POST, PUT, DELETE) với mã phản hồi HTTP chuẩn (200 OK, 201 Created, 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 500 Server Error).

GET    /api/v1/books            -> Lấy danh sách sách có phân trang và bộ lọc
GET    /api/v1/books/:id        -> Lấy chi tiết sách theo ID
POST   /api/v1/auth/signup      -> Đăng ký tài khoản người dùng
POST   /api/v1/auth/signin      -> Đăng nhập và trả về JWT Bearer Token
POST   /api/v1/orders           -> Tạo đơn hàng mới (COD / VNPay)
GET    /api/v1/orders/my-orders -> Lịch sử đơn hàng cá nhân của User
PUT    /api/v1/orders/:id/status-> Cập nhật trạng thái đơn hàng (Dành cho Admin)
POST   /api/v1/vnpay/create-payment-url -> Tạo URL thanh toán bảo mật qua VNPay

Kiến trúc bảo mật (Security Considerations)

  • Mã hóa mật khẩu người dùng bằng thuật toán băm Bcrypt với Salt Rounds = 10.
  • Xác thực và phân quyền bằng JSON Web Token (JWT), kiểm soát truy cập phân tầng (Role-Based Access Control - RBAC) phân tách rõ ràng giữa AdminCustomer.
  • Xử lý kiểm tra dữ liệu đầu vào (Input Validation) bằng class-validator và DTO (Data Transfer Object) để chống tấn công NoSQL Injection và XSS.

Phương pháp luận phát triển (Methodology)

Dự án áp dụng mô hình phát triển phần mềm Agile/Scrum chia thành 5 giai đoạn chính trong 14 tuần:

  1. Tuần 1 - 3: Khảo sát yêu cầu, phân tích bài toán và thiết kế kiến trúc hệ thống, thiết kế CSDL MongoDB.
  2. Tuần 4 - 7: Phát triển hệ thống Backend RESTful API với NestJS, cấu hình bảo mật JWT và hoàn thành toàn bộ CRUD core services.
  3. Tuần 8 - 10: Xây dựng giao diện Frontend SPA với Vue.js, tích hợp Ant Design & Vuetify, kết nối API qua Axios.
  4. Tuần 11 - 12: Tích hợp cổng thanh toán trực tuyến VNPay Sandbox, hoàn thiện quy trình Checkout và xử lý đơn hàng.
  5. Tuần 13 - 14: Kiểm thử toàn diện (Unit Testing, Integration Testing, UAT), sửa lỗi và tối ưu hiệu năng triển khai.

Implementation và kết quả

Quy trình phát triển và thuật toán cốt lõi

Quy trình xử lý đơn hàng và tích hợp cổng thanh toán trực tuyến VNPay là thành phần nghiệp vụ cốt lõi, đòi hỏi tính toàn vẹn dữ liệu giao dịch cao.

// Xử lý tạo URL thanh toán an toàn với chữ ký bảo mật SHA-512 cho VNPay
import * as crypto from 'crypto';
import * as querystring from 'qs';

export class VnPayService {
  createPaymentUrl(orderId: string, amount: number, ipAddr: string): string {
    const vnp_TmnCode = process.env.VNP_TMN_CODE;
    const vnp_HashSecret = process.env.VNP_HASH_SECRET;
    const vnp_Url = process.env.VNP_URL;
    const vnp_ReturnUrl = process.env.VNP_RETURN_URL;

    let vnp_Params: Record<string, any> = {
      vnp_Version: '2.1.0',
      vnp_Command: 'pay',
      vnp_TmnCode: vnp_TmnCode,
      vnp_Locale: 'vn',
      vnp_CurrCode: 'VND',
      vnp_TxnRef: orderId,
      vnp_OrderInfo: `Thanh toan don hang ${orderId}`,
      vnp_OrderType: 'billpayment',
      vnp_Amount: amount * 100,
      vnp_ReturnUrl: vnp_ReturnUrl,
      vnp_IpAddr: ipAddr,
      vnp_CreateDate: new Date().toISOString().replace(/[-:T.]/g, '').slice(0, 14),
    };

    // Sắp xếp các tham số theo alphabet
    vnp_Params = Object.keys(vnp_Params).sort().reduce((result, key) => {
      result[key] = vnp_Params[key];
      return result;
    }, {});

    const signData = querystring.stringify(vnp_Params, { encode: false });
    const hmac = crypto.createHmac('sha512', vnp_HashSecret);
    const signed = hmac.update(Buffer.from(signData, 'utf-8')).digest('hex');
    vnp_Params['vnp_SecureHash'] = signed;

    return `${vnp_Url}?${querystring.stringify(vnp_Params, { encode: false })}`;
  }
}
// Xử lý quản lý giỏ hàng Reactive trong Vuex / Pinia Store
export const useCartStore = {
  state: () => ({
    items: [],
  }),
  mutations: {
    ADD_TO_CART(state, book) {
      const existingItem = state.items.find(item => item.bookId === book._id);
      if (existingItem) {
        if (existingItem.quantity < book.stockQuantity) {
          existingItem.quantity += 1;
        }
      } else {
        state.items.push({
          bookId: book._id,
          title: book.title,
          price: book.price - (book.price * book.discount / 100),
          quantity: 1,
          image: book.images[0]
        });
      }
    },
    UPDATE_QUANTITY(state, { bookId, quantity }) {
      const item = state.items.find(i => i.bookId === bookId);
      if (item && quantity > 0) {
        item.quantity = quantity;
      }
    }
  }
};

Kiểm thử và đánh giá hiệu năng (Testing & Validation)

Hệ thống trải qua các bài kiểm thử nghiêm ngặt bao gồm Unit Test (Jest), kiểm thử tải bằng công cụ Apache Benchmark (ab), và kiểm thử chấp nhận người dùng (User Acceptance Testing - UAT).

==================================================================================
KẾT QUẢ BENCHMARK TẢI HỆ THỐNG (APACHE BENCHMARK - 500 CONCURRENT USERS)
==================================================================================
Tổng số Request thực hiện          : 10,000 requests
Độ đồng thời (Concurrency Level)   : 500
Thời gian hoàn thành               : 11.76 giây
Tốc độ xử lý (Throughput)          : 850.34 requests/second
Thời gian phản hồi trung bình (API): 117.6 ms (Latency)
Tỷ lệ lỗi (Error Rate)             : 0.00 %
==================================================================================
Hạng mục kiểm thử Số lượng kịch bản Đạt (Pass) Tỷ lệ thành công
Xác thực & Người dùng 12 test cases 12 100%
Tìm kiếm & Bộ lọc dữ liệu 18 test cases 18 100%
Giỏ hàng & Đặt hàng 20 test cases 20 100%
Cổng thanh toán VNPay 15 test cases 15 100%
Phân hệ Quản trị Admin 25 test cases 25 100%

Kết quả đạt được

Hệ thống đã triển khai thành công 100% các Use Case đề ra trong mục tiêu ban đầu:

  • Phân hệ Khách hàng: Đăng ký, đăng nhập, tìm kiếm theo từ khóa/danh mục, quản lý giỏ hàng tức thời, đặt hàng thanh toán COD và VNPay, theo dõi lịch sử đơn hàng cá nhân.
  • Phân hệ Quản trị: Quản lý người dùng, quản lý sản phẩm sách, danh mục, tác giả, nhà phát hành và cập nhật trạng thái đơn hàng theo thời gian thực.
  • Điểm số Lighthouse: Đạt 94 điểm Performance, 98 điểm SEO, 92 điểm Accessibility và 95 điểm Best Practices trên môi trường máy tính để bàn.

Đổi mới và đóng góp

  1. Kiến trúc Module hóa cao trên nền NestJS & TypeScript: Tận dụng triệt để nguyên lý Dependency Injection (DI) giúp mã nguồn backend tách biệt rõ ràng giữa Business Logic và Data Access Layer, tăng 45% khả năng bảo trì và tái sử dụng mã nguồn so với các dự án ExpressJS truyền thống.
  2. Cơ chế lưu trữ linh hoạt với MongoDB NoSQL: Tối ưu hóa việc lưu trữ thông tin sách đa dạng (kích thước, loại bìa, tác giả, dịch giả) trong các tài liệu JSON không đòi hỏi cấu trúc bảng cố định, tăng tốc độ truy vấn tìm kiếm lên gấp 3 lần so với cơ sở dữ liệu quan hệ có nhiều phép kết nối bảng (JOIN).
  3. Trải nghiệm giao diện Single-Page Application (SPA): Kết hợp Vue 3 với sức mạnh của Ant Design và Vuetify, đem lại trải nghiệm mượt mà, chuyển trang không cần tải lại toàn bộ nội dung (Zero full-page reloads), giảm thiểu 60% lượng băng thông mạng truyền tải giữa Client và Server.

Ứng dụng thực tế và triển khai

Kịch bản triển khai thực tế

Website được thiết kế phù hợp cho các nhà sách độc lập, chuỗi phân phối sách vừa và nhỏ hoặc các thư viện trường học có nhu cầu số hóa kênh phát hành tài liệu chuyên khảo.

graph LR
    UserRequest[Người dùng truy cập] --> Nginx[Nginx Reverse Proxy / SSL Let's Encrypt]
    Nginx --> StaticApp[Vue.js Static Build Files]
    Nginx --> PM2Cluster[PM2 Cluster: Node.js / NestJS Instances]
    PM2Cluster --> MongoCloud[(MongoDB Atlas Cloud Cluster)]

Phân tích chi phí và hiệu quả đầu tư (Cost-Benefit Analysis & ROI)

  • Chi phí hạ tầng máy chủ: 1 Cloud VPS (2 vCPU, 4GB RAM) trị giá khoảng $12 - $20/tháng; CSDL MongoDB Atlas Free/Shared Tier ($0 - $10/tháng).
  • Chi phí vận hành: Giảm 70% chi phí nhân sự ghi chép và xử lý đơn hàng thủ công tại quầy.
  • Thời gian hoàn vốn (ROI): Ước tính từ 3 đến 6 tháng đối với cửa hàng sách quy mô nhỏ nhờ mở rộng doanh thu bán hàng online 24/7.

Hạn chế và hướng phát triển

  • Hạn chế kỹ thuật hiện tại: Chưa tích hợp công cụ tìm kiếm toàn văn chuyên sâu (như Elasticsearch) cho các tập dữ liệu lên đến hàng trăm nghìn đầu sách; chức năng bình luận/đánh giá ở giai đoạn đầu áp dụng Mockup UI data và cần hoàn thiện trọn vẹn phần lưu trữ tương tác đa người dùng.
  • Hướng phát triển tương lai:
    1. Tích hợp thuật toán gợi ý sách thông minh dựa trên lịch sử mua sắm và hành vi duyệt sách của người dùng (Recommendation System).
    2. Mở rộng tính năng phát hành sách điện tử (E-book) và sách nói (Audiobook) có bảo vệ bản quyền số (DRM).
    3. Kết nối API đồng bộ vận chuyển tự động với các hãng giao nhận (Giao Hàng Nhanh, Giao Hàng Tiết Kiệm, Viettel Post).
    4. Phát triển ứng dụng di động đa nền tảng (Mobile App) bằng React Native hoặc Flutter sử dụng chung hạ tầng NestJS API hiện có.

Đối tượng hưởng lợi

  • Sinh viên & Giảng viên Công nghệ Thông tin: Nguồn tài liệu tham khảo chuẩn mực về đồ án tốt nghiệp ứng dụng Fullstack (NestJS, Vue.js, MongoDB) với đầy đủ quy trình phân tích ca sử dụng (Use Case), biểu đồ tuần tự (Sequence Diagram) và sơ đồ kiến trúc.
  • Lập trình viên (Developers): Cung cấp mẫu thiết kế Clean Architecture trong NestJS, kỹ thuật tích hợp cổng thanh toán VNPay chuẩn bảo mật HMAC-SHA512 và quản lý trạng thái Vuex tối ưu.
  • Chủ doanh nghiệp & Nhà sách: Giải pháp công nghệ tinh gọn, chi phí đầu tư thấp để nhanh chóng thiết lập kênh bán lẻ trực tuyến hoàn chỉnh.
  • Nhà nghiên cứu ứng dụng: Cung cấp số liệu benchmark thực tế về hiệu năng của kiến trúc phi tập trung trên nền tảng JavaScript/TypeScript.

Câu hỏi thường gặp

1. Yêu cầu phần cứng và phần mềm tối thiểu để triển khai hệ thống là gì?

Máy chủ cần tối thiểu 1 vCPU, 2GB RAM, hệ điều hành Ubuntu 20.04/22.04 LTS, cài đặt sẵn Node.js runtime (v18.x trở lên), MongoDB v6.x, công cụ quản lý tiến trình PM2 và Nginx làm Web Server/Reverse Proxy.

2. Hệ thống xử lý khả năng mở rộng (Scalability) khi lượng truy cập tăng vọt như thế nào?

Nhờ kiến trúc Stateless của NestJS và xác thực JWT, hệ thống có thể dễ dàng mở rộng theo chiều ngang (Horizontal Scaling) bằng cách nhân bản các Node.js instance qua PM2 Cluster Mode hoặc triển khai trên Docker container kết hợp Nginx Load Balancer.

3. Quy trình tích hợp cổng thanh toán VNPay có đảm bảo an toàn giao dịch không?

Hệ thống sử dụng cơ chế tạo mã băm bảo mật HMAC-SHA512 với khóa bí mật (vnp_HashSecret) được lưu trữ trong biến môi trường máy chủ. Khi VNPay phản hồi kết quả giao dịch, hệ thống thực hiện kiểm tra đối soát chữ ký số trước khi cập nhật trạng thái đơn hàng nhằm chống gian lận dữ liệu.

4. Chi phí duy trì hệ thống định kỳ hàng tháng là bao nhiêu?

Chi phí duy trì hệ thống cơ bản ước tính khoảng 300.000 VNĐ – 600.000 VNĐ/tháng bao gồm tiền thuê máy chủ Cloud VPS, tên miền (.vn hoặc .com) và chứng chỉ bảo mật SSL miễn phí từ Let's Encrypt.

5. Dữ liệu NoSQL MongoDB có đảm bảo tính toàn vẹn khi quản lý tồn kho không?

Hệ thống sử dụng Mongoose middleware kết hợp Atomic Operators (như $inc, $set) của MongoDB trong quá trình cập nhật số lượng sách tồn kho tại thời điểm đặt hàng, ngăn ngừa xung đột dữ liệu (Race Conditions) khi nhiều khách hàng cùng mua một đầu sách.


Kết luận

Khóa luận tốt nghiệp "Xây dựng website bán sách" của nhóm sinh viên Trường Đại học Thăng Long đã giải quyết xuất sắc bài toán xây dựng nền tảng thương mại điện tử hiện đại. Bằng việc kết hợp sức mạnh của NestJS, Vue.js, MongoDB cùng cổng thanh toán VNPay, dự án không chỉ đạt được hiệu năng vận hành vượt trội mà còn mang lại giá trị thực tiễn cao cho quá trình chuyển đổi số trong lĩnh vực bán lẻ tri thức. Đây là mô hình tham khảo toàn diện, đóng góp thiết thực cho cộng đồng học thuật cũng như các doanh nghiệp đang tìm kiếm giải pháp thương mại điện tử tối ưu chi phí và hiệu quả.