0% found this document useful (0 votes)
12 views19 pages

Ecom2 10 16 Vxthinh

The document outlines the design and implementation of a web application, including class diagrams, package layers, and code generation for various models such as Customer, Product, and Order. It details the controller logic for handling requests related to home, products, cart, and search functionalities, along with the schemas for database interactions. The document serves as a comprehensive guide for developers to understand the structure and functionality of the application.

Uploaded by

eltad2003
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views19 pages

Ecom2 10 16 Vxthinh

The document outlines the design and implementation of a web application, including class diagrams, package layers, and code generation for various models such as Customer, Product, and Order. It details the controller logic for handling requests related to home, products, cart, and search functionalities, along with the schemas for database interactions. The document serves as a comprehensive guide for developers to understand the structure and functionality of the application.

Uploaded by

eltad2003
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 19

1. Biểu đồ lớp, phân tích nhóm.

2. Biểu đồ lớp thiết kế


3. Package – Layer

4. Sinh code từ thiết kế

A. Model

• Customer
const userSchema = new mongoose.Schema(
{
fullName: String,
cart_id: String,
email: String,
password: String,
tokenUser: {
type: String,
default: genString.generateRandomString(20)
},
phone: String,
avatar: String,
status: {
type: String,
default: 'active'
},
);
• Product

const productSchema = new mongoose.Schema(


{
title : String,
category_id: {
type: String,
default: "",
},
description: String,
brand_id: String,
type: String,
color: String,
price: Number,
size: [Number],
discountPercentage: Number,
stock: Number,
soldQuantity: { type: Number, default: 0 },
ratings: [{ type: Number, min: 0, max: 5 }],
thumbnail: String,
status: String,
featured: String,
position: Number,
createBy :{
accountId: String,
createdAt: {
type: Date,
default: Date.now
}
},
slug: {
type: String,
slug:"title",
unique: true
},
deleted: {
type: Boolean,
default: false
},
},
);
• Product Category

const productCategorySchema = new mongoose.Schema(


{
title : String,
description: String,
parent_id: {
type: String,
default: ""
},
thumbnail: String,
status: String,
position: Number,
slug: {
type: String,
slug:"title",
unique: true
},
deleted: {
type: Boolean,
default: false
},
deletedTime: Date
},
{
timestamps: true
}
);
• Cart
const cartSchema = new mongoose.Schema(
{
products: [{
product_id: String,
quantity: Number
}],
deleted: {
type: Boolean,
default: false
},
slug: {
type: String,
unique: false
}
},
{
timestamps: true
}
);

• Order
const orderSchema = new mongoose.Schema(
{
user_id: String,
cart_id : String,
userInfor: {
fullName: String,
phone: Number,
address: String
},
products: [
{
product_id: String,
quantity: Number,
price: Number,
discountPercentage: Number
}
],
deleted: {
type: Boolean,
default: false
},
},
{
timestamps: true
}
);

B. Controller

• Home

const systemConfig = require("../../config/system");


const productsCategory = require('../../model/products-category.model')
const Product = require("../../model/products.model");
const Account = require("../../model/accounts.model")
const articalCategory = require("../../model/artical-categoty.model")
const createTreeHelper = require("../../helper/createTree")

// [GET] /home
module.exports.index = async (req,res)=>{
//featured product
const featuredProducts = await Product.find(
{deleted: false, status:"active", featured:"1"})
const newProducts = featuredProducts.map(item => {
item.newPrice = (
(item.price*(100 - item.discountPercentage))/100
).toFixed(0)
return item;
})
const lastestProducts = await Product.find({
deleted: false,
status: "active",

}).sort({position: "desc"}).limit(6)
const lastestProductsUpdate = lastestProducts.map(item => {
item.newPrice = (
(item.price*(100 - item.discountPercentage))/100
).toFixed(0)
return item;
})
const saleProducts = await Product.find({
deleted: false,
status: "active"
}).sort({discountPercentage: "desc"}).limit(6)
const saleProductsUpdate = saleProducts.map(item => {
item.newPrice = (
(item.price*(100 - item.discountPercentage))/100
).toFixed(0)
return item;
})
const category = await productsCategory.find({
deleted: false,
status: "active"
})
const articalCategorys = await articalCategory.find({deleted: false,
status: "active"})
res.render("client/page/home/index",{
pageTitle: "Trang chu",
featuredProducts: newProducts,
lastestProducts: lastestProductsUpdate,
saleProducts: saleProductsUpdate,
productCategorys: category,
articalCategorys: articalCategorys
});
}

• Product

const Product = require("../../model/products.model");


const productsCategory = require("../../model/products-category.model");
const paginationHelper = require("../../helper/pagination");
const CategoryHelper = require("../../helper/product-category")
const Brand = require("../../model/brands.model")

// [GET] /products
module.exports.index = async (req,res)=>{
try{
const find = {
status: "active",
deleted: false
}

const brands = await Brand.find(find)


const siderVar = {
size : [35,36,37,38,39,40,41,42,43,44,45],
type : ["Low-top","Mid-top","High-top"],
price : [500000,1000000,1500000,3000000,5000000],
brands : brands
}

//sale products
const saleProducts = await Product.find({
deleted: false,
status: "active"
}).sort({discountPercentage: "desc"}).limit(6)
const saleProductsUpdate = saleProducts.map(item => {
item.newPrice = (
(item.price*(100 - item.discountPercentage))/100
).toFixed(0)
return item;
})
//end sale products

//sort
const sort = {}
const sortKey = req.query.sortKey;
const sortValue = req.query.sortValue;
if(sortKey && sortValue){
sort[sortKey] = sortValue
}
else{
sort.position = 'desc'
}
//end sort

// brand checkbox
const brand_id = req.query.brand
if(brand_id){
find.brand_id = brand_id
}
// end brand checkbox

//type checkbox
if(req.query.type){
const typeList = req.query.type.split("-")
const type = typeList.map(item=>{
return siderVar.type[parseInt(item)];
})

find.type = {$in: type};


}
//end type checkbox

//price ratio
if(req.query.priceRadio){
const priceIdx = parseInt(req.query.priceRadio)
find.price = {$lt: siderVar.price[priceIdx] }
}
//end price ratio

//price input
if(req.query.priceInput){
const priceInput = req.query.priceInput.split("-").map(item =>{
return parseInt(item)
})
if(priceInput.length >0){
find.price = {
$gt: priceInput[0],
$lt: priceInput[1]
}
}
}
//end price input

//pagination
const limitedItem = 16

const countProducts = await Product.countDocuments(find);


const paginationObject = paginationHelper(countProducts, req.query,
limitedItem);
//end pagination

const products = await Product


.find(find)
.sort(sort)
.limit(paginationObject.limitedItem)
.skip(paginationObject.skip);

const newProducts = products.map(item=>{


item.newPrice = (item.price*(100-
item.discountPercentage)/100).toFixed(0);
return item;
})

res.render("client/page/product/index",{
pageTitle: "Trang sản phẩm",
products: newProducts,
pagination: paginationObject,
siderVar : siderVar,
saleProducts: saleProductsUpdate
});
}
catch(e){
res.redirect("/products")
}

// [GET] /products/detail/:slug
module.exports.detail = async (req,res)=>{
try{
const slug = req.params.slug
const find = {
deleted: false,
status: 'active',
slug: slug
}

const product = await Product.findOne(find)

if(product){
if(product.category_id){
const category = await productsCategory.findOne({
_id: product.category_id,
status: "active",
deleted: false
})
product.category = category
}

product.newPrice = (product.price*(100-
product.discountPercentage)/100).toFixed(0);

res.render("client/page/product/detail",{
pageTitle: "Trang chi tiết sản phẩm",
product: product
});
}
else{
res.redirect('/products')
}

}
catch(error){
res.redirect('/products')
}

}
// [GET] /products/:slugCategory
module.exports.productOfCategory = async (req,res)=>{
// try{
const sort = {

}
const find = {
status: "active",
deleted: false
}
const brands = await Brand.find(find)
const siderVar = {
size : [35,36,37,38,39,40,41,42,43,44,45],
type : ["Low-top","Mid-top","High-top"],
price : [500000,1000000,1500000,3000000,5000000],
brands : brands
}

const slug = req.params.slugCategory;

const productCategory = await productsCategory.findOne({


slug : slug,
deleted: false
})
const listSubCategory = await
CategoryHelper.getSubCategory(productCategory.id)
const listSubCategoryId = await listSubCategory.map(item => {
return item.id
})

find.category_id = {$in : [productCategory.id,...listSubCategoryId]};

//sort
const sortKey = req.query.sortKey;
const sortValue = req.query.sortValue;
if(sortKey && sortValue){
sort[sortKey] = sortValue
}
else{
sort.position = 'desc'
}
const brand_id = req.query.brand
if(brand_id){
find.brand_id = brand_id
}
if(req.query.type){
const typeList = req.query.type.split("-")
const type = typeList.map(item=>{
return siderVar.type[parseInt(item)];
})

find.type = {$in: type};


}
if(req.query.priceRadio){
const priceIdx = parseInt(req.query.priceRadio)
find.price = {$lt: siderVar.price[priceIdx] }
}
if(req.query.priceInput){
const priceInput = req.query.priceInput.split("-").map(item =>{
return parseInt(item)
})
if(priceInput.length > 0 && priceInput[0] && priceInput[1]){
find.price = {
$gt: priceInput[0],
$lt: priceInput[1]
}
}
}
const limitedItem = 16

const countProducts = await Product.countDocuments(find);


const paginationObject = paginationHelper(countProducts, req.query,
limitedItem);
const products = await Product
.find(find)
.sort(sort)
.limit(paginationObject.limitedItem)
.skip(paginationObject.skip);

const productsUpdate = products.map(item=>{


item.newPrice = (item.price*(100-
item.discountPercentage)/100).toFixed(0);
return item;
})

//sale products
const saleProducts = await Product.find({
deleted: false,
status: "active"
}).sort({discountPercentage: "desc"}).limit(6)
const saleProductsUpdate = saleProducts.map(item => {
item.newPrice = (
(item.price*(100 - item.discountPercentage))/100
).toFixed(0)
return item;
})
res.render("client/page/product/index",{
pageTitle: productCategory.title,
siderVar : siderVar,
pagination: paginationObject,
products : productsUpdate,
saleProducts: saleProductsUpdate
})
}

• Cart
const Cart = require("../../model/carts.model");
const Product = require("../../model/products.model");
//[get] /cart
module.exports.index = async(req,res) =>{
try{
const cartId = req.cookies.cartId;

const cart = await Cart.findOne({


_id: cartId
})
if(cart.products.length >0){
for (const product of cart.products) {
const productId = product.product_id;
const productInfor = await Product.findOne({
_id: productId
})
productInfor.newPrice = (productInfor.price*(100-
productInfor.discountPercentage)/100).toFixed(0);
product.productInfor = productInfor
product.totalPrice = product.quantity * productInfor.newPrice
}
}

cart.total = cart.products.reduce((sum, item)=>sum+item.totalPrice,0)


res.render("client/page/cart/index.pug",{
pageTitle: "Giỏ hàng",
cart: cart
})
}
catch(e){

}
}
//[get] /delete/:productId
module.exports.delete = async(req,res) =>{
const productId = req.params.productId
const cartId = req.cookies.cartId;

await Cart.updateOne({
_id: cartId
},{
"$pull": {products: {"product_id": productId}}
})
req.flash("success", "Xóa thành công")
res.redirect("back")
}
//[post] /cart/add/:productId
module.exports.addPost = async(req,res) =>{
const cartId = req.cookies.cartId;
const productId = req.params.productId;
const quantity = parseInt(req.body.quantity);

const cartObject = {
product_id : productId,
quantity: quantity
}

const cart = await Cart.findOne({


_id: cartId
})

console.log(cart.products)

const existProduct = cart.products.find(item => item.product_id == productId)


if(existProduct){
const curQuantity = quantity + existProduct.quantity;
await Cart.updateOne(
{
_id: cartId,
'products.product_id': productId
},
{
'products.$.quantity': curQuantity
}
)
}
else{
await Cart.updateOne(
{
_id: cartId
},
{
$push: {products : cartObject}
}
)
}

req.flash("success", "Thêm vào giỏ hàng thành công")


res.redirect("back")
}
//[get] /update/:productId/:quantity
module.exports.update = async (req,res) =>{
const productId = req.params.productId
const cartId = req.cookies.cartId;
const quantity = req.params.quantity

console.log(quantity)
await Cart.updateOne({
_id: cartId,
'products.product_id': productId
},{
'products.$.quantity': quantity
})
req.flash("success", "Cập nhật thành công")
res.redirect("back")
}

• Search

• const systemConfig = require("../../config/system");
• const productsCategory = require('../../model/products-category.model')
• const Product = require("../../model/products.model");
• const Account = require("../../model/accounts.model")

• // [GET] /search
• module.exports.index = async (req,res)=>{
• // try{
• const siderVar = {
• size : [35,36,37,38,39,40,41,42,43,44,45],
• type : ["Low-top","Mid-top","High-top"],
• price : [500000,1000000,1500000,3000000,5000000],
• }

• const keyword = req.query.keyword;
• let newProducts = []
• if(keyword){
• const keywordRegrex = new RegExp(keyword, "i")

• const products = await Product.find({
• title: keywordRegrex,
• status: "active",
• deleted: false
• })
• newProducts = products.map(item=>{
• item.newPrice = (item.price*(100-
item.discountPercentage)/100).toFixed(0);
• return item;
• })

• }
• res.render("client/page/search/index",{
• pageTitle: "Trang tìm kiếm sản phẩm",
• keyword: keyword,
• products: newProducts,
• siderVar: siderVar
• });

• Checkout
• const Cart = require("../../model/carts.model");
• const Product = require("../../model/products.model");
• const Order = require("../../model/orders.model");
• //[get] /checkout
• module.exports.index = async(req,res) =>{
• const cartId = req.cookies.cartId;

• const cart = await Cart.findOne({
• _id: cartId
• })
• if(cart.products.length >0){
• for (const product of cart.products) {
• const productId = product.product_id;
• const productInfor = await Product.findOne({
• _id: productId
• })
• productInfor.newPrice = (productInfor.price*(100-
productInfor.discountPercentage)/100).toFixed(0);
• product.productInfor = productInfor
• product.totalPrice = product.quantity * productInfor.newPrice
• }
• }
• cart.total = cart.products.reduce((sum, item)=>sum+item.totalPrice,0)
• res.render("client/page/checkout/index.pug",{
• pageTitle: "Thanh toán",
• cart: cart
• })
• }
• //[post] /order
• module.exports.order = async (req, res) =>{
• const cartId = req.cookies.cartId
• const cart = await Cart.findOne({
• _id: cartId
• })
• const products = []

• for(const product of cart.products) {
• const productInfor = await Product.findOne({
• _id: product.product_id
• })

• const objectProduct = {
• product_id : product.product_id,
• price: productInfor.price,
• discountPercentage: productInfor.discountPercentage,
• quantity: product.quantity
• }

• products.push(objectProduct)
• }
• const objectOder = {
• cart_id : cartId,
• userInfor: req.body,
• products: products
• }

• const order = new Order(objectOder)
• order.save();

• await Cart.updateOne({
• _id: cartId
• },{
• products: []
• })

• res.redirect(`/checkout/success/${order.id}`)

• }
• // [get] /checkout/success/:orderId
• module.exports.success = async (req, res)=>{
• const orderId = req.params.orderId;

• const order = await Order.findOne({
• _id: orderId
• })

• for(const product of order.products) {
• const productInfor = await Product.findOne({
• _id: product.product_id
• })

• productInfor.newPrice = (productInfor.price*(100-
productInfor.discountPercentage)/100).toFixed(0);
• product.productInfor = productInfor
• product.totalPrice = product.quantity * productInfor.newPrice
• }

• order.total = order.products.reduce((sum, item)=>sum+item.totalPrice,0)
• res.render("client/page/checkout/success",{
• pageTitle: "Đặt hàng thành công",
• order: order
• })
• }

5. Giao diện

• Home

• Search

• Cart
• Checkout

You might also like