Ecom2 10 16 Vxthinh
Ecom2 10 16 Vxthinh
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
• 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
// [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
// [GET] /products
module.exports.index = async (req,res)=>{
try{
const find = {
status: "active",
deleted: false
}
//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)];
})
//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
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
}
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
}
//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)];
})
//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;
}
}
//[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
}
console.log(cart.products)
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