定義 model

建立關聯

建立假資料

引入 express-handlebar

引入 routes

// routes/index.js

const express = require('express')
const router = express.Router()

const productController = require('../controllers/productController.js')
const cartController = require('../controllers/cartController.js')

router.get('/products', productController.getProducts)

router.get('/cart', cartController.getCart)

module.exports = router
// controller/productController.js

const db = require('../models')
const Product = db.Product

const productController = {
  // 取所有產品
  getProducts: async (req, res) => {
    try {
      const products = await Product.findAndCountAll({ offset: 0, limit: 3 })
      return res.render('products', { products })
    } catch (e) {
      console.log(e)
    }
  }
}

module.exports = productController
// controller/cartController.js

const db = require('../models')
const Cart = db.Cart
const CartItem = db.CartItem
const PAGE_LIMIT = 10
const PAGE_OFFSET = 0

const cartController = {
  // 取所有產品
  getCart: async (req, res) => {
    try {
      const cart = await Cart.findOne({ include: 'items' })
      const totalPrice = cart.items.length > 0 ? cart.items.map(d => d.price * d.CartItem.quantity).reduce((a, b) => a + b) : 0
      return res.render('cart', { cart, totalPrice })
    } catch (e) {
      console.log(e)
    }
  }
}

module.exports = cartController
// views/products.hbs

<div class="row">
    <div class="col-md-9">
        <div class="row">

            {{#each products.rows}}
                <div class="col-md-4">
                    <div class="card mb-4 shadow-sm">
                        <img class="bd-placeholder-img card-img-top" width="100%" height="225" src="{{this.dataValues.image}}">
                        <div class="card-body">
                            <p class="card-text">
                                <h4><a href="/products/{{this.dataValues.id}}">{{this.dataValues.id}} {{this.dataValues.name}}</a></h4>
                                <span>{{this.description}}</span>
                            </p>
                            <div class="d-flex justify-content-between align-items-center">
                                <small class="text-muted">$ {{this.dataValues.price}}</small>
                                <div class="btn-group">

                                    <form action="/cart" method="POST">
                                        <input type="hidden" name="productId" value="{{this.dataValues.id}}">
                                        <button type="submit" class="btn btn-sm btn-outline-secondary">Add to Cart</button>
                                    </form>

                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            {{/each}}

        </div>
    </div>
</div>
// views/cart.hbs

<h1>顯示購物車</h1>

<div>
    <table class="table">
        <thead>
        <tr>
            <th scope="col">#</th>
            <th scope="col">Price</th>
            <th scope="col">quantity</th>
            <th scope="col">Subtotal</th>
            <th scope="col">#</th>
        </tr>
        </thead>
        <tbody>
        {{#each cart.items}}
            <tr>
                <td>
                    <div style="display: flow-root;">
                        <img src="{{this.dataValues.image}}" class="card-img" alt="..." style="height: 100px;width: auto;">
                        <span>{{this.dataValues.name}}</span>
                    </div>
                </td>
                <td><p>$ {{this.dataValues.price}}</p></td>
                <td>
                    <div style="display: flex;">
                        <form action="/cartItem/{{this.CartItem.dataValues.id}}/add" method="POST">
                            <button type="submit" class="btn btn-sm btn-outline-secondary">+</button>
                        </form>
                        <span style="margin: 0 20px;">
                            {{this.CartItem.dataValues.quantity}}
                        </span>
                        <form action="/cartItem/{{this.CartItem.dataValues.id}}/sub" method="POST">
                            <button type="submit" class="btn btn-sm btn-outline-secondary">-</button>
                        </form>
                    </div>
                </td>
                <td>{{this.dataValues.price}} * {{this.CartItem.dataValues.quantity}}</td>
                <td>
                    <form action="/cartItem/{{this.CartItem.dataValues.id}}?_method=DELETE" method="POST">
                        <button type="submit" class="btn btn-link">
                            <i class="fas fa-trash"></i>
                        </button>
                    </form>
                </td>
            </tr>
        {{/each}}
        <tr>
            <td></td>
            <td></td>
            <td style="text-align: right;"><h2>Total: </h2></td>
            <td><h2>{{totalPrice}}</h2></td>
            <td></td>
        </tr>
        </tbody>
    </table>
</div>