iT邦幫忙

2021 iThome 鐵人賽

DAY 25
0
Modern Web

從實作學習ASP.NET Core - 30天的購物網站系列 第 25

【從實作學習ASP.NET Core】Day25 | 前台 | 結帳流程

我們簡單定義結帳流程為 [ 購物車 -> 輸入訂單資料 -> 建立訂單 -> 付款 ]
昨天已經完成購物車了,今天就繼續把輸入訂單資料和建立訂單的部分完成


訂單模型

建立訂單模型,訂單是要存進資料庫的,所以是需要建立資料表的
還是老樣子用 Add-MigrationUpdate-Database 移轉資料庫

public class Order
{
    public int Id { get; set; }
    public DateTime OrderDate { get; set; }        //訂單建立時間
    
    public string UserId { get; set; }             //付款者ID
    public string UserName { get; set; }           //付款者帳號
    
    public string ReceiverName { get; set; }       //收貨者姓名
    public string ReceiverAdress { get; set; }     //收貨者地址
    public string ReceiverPhone { get; set; }      //收貨者電話
    
    public int Total { get; set; }                 //訂單總額
    public List<OrderItem> OrderItem { get; set; } //訂單內容
    public bool isPaid { get; set; }               //付款狀態
}

public class OrderItem
{
    public int Id { get; set; }
    public int OrderId { get; set; }
    public int ProductId { get; set; }
    public int Amount { get; set; }
    public int SubTotal { get; set; }
}

訂單控制器

新建一個控制器 OrderController.csController 資料夾
並且加入[Authorize]將他設為驗證狀態,必須要登入才能進行結帳動作
這個控制器會需要三個主要 Action :

  • Checkout():填寫訂單資料
  • CreateOrder():建立訂單
  • ReviewOrder():顯示訂單

配合對應的 [填寫訂單資料] 和 [顯示訂單] 兩個頁面

  • Checkout.cshtml
  • ReviewOrder.cshtml

填寫訂單資料

接收來自購物車的資料,加上訂單欄位填寫

public IActionResult Checkout()
{
    if (SessionHelper.GetObjectFromJson<List<OrderItem>>(HttpContext.Session, "cart") == null)
    {
        return RedirectToAction("Index", "Cart");
    }

    var myOrder = new Order()
    {
        UserId = _userManager.GetUserId(User),     //取得訂購人ID
        UserName = _userManager.GetUserName(User), //取得訂購人帳號
        OrderItem = SessionHelper.                 //取得購物車資料
            GetObjectFromJson<List<OrderItem>>(HttpContext.Session, "cart")
    };
    myOrder.Total = myOrder.OrderItem.Sum(m => m.SubTotal); //計算訂單總額

    ViewBag.CartItems = SessionHelper.
        GetObjectFromJson<List<CartItem>>(HttpContext.Session, "cart");

    return View(myOrder);
}

前端可以直接用 Edit 模板下去改排版

點選建立訂單按鈕以後觸發 CreateOrder() 把填寫好的資料儲存到資料庫裡

建立訂單

[HttpPost]
public async Task<IActionResult> CreateOrder(Order order)
{
    if (ModelState.IsValid)
    {
        order.OrderDate = DateTime.Now;    //取得當前時間
        order.isPaid = false;              //付款狀態預設為False
        order.OrderItem = SessionHelper.   //綁定訂單內容
            GetObjectFromJson<List<OrderItem>>(HttpContext.Session, "cart");

        _context.Add(order);               //將訂單寫入資料庫
        await _context.SaveChangesAsync();
        SessionHelper.Remove(HttpContext.Session, "cart");

        //完成後畫面移轉至ReviewOrder()
        return RedirectToAction("ReviewOrder", new {  Id = order.Id } );
    }
    return View("Checkout");
}

顯示訂單

public async Task<IActionResult> ReviewOrder(int? Id)
{
    if(Id == null)
    {
        return NotFound();
    }
    //從資料庫取得訂單資料
    var order = await _context.Order.FirstOrDefaultAsync(m => m.Id == Id);
    if(order.UserId != _userManager.GetUserId(User))
    {
        return NotFound();
    }
    else
    {
        //取得訂單內容
        order.OrderItem = await _context.OrderItem 
            .Where(p => p.OrderId == Id).ToListAsync();
        ViewBag.orderItems = GetOrderItems(order.Id);
    }
    return View(order);
}
// 取得商品詳細資料
private List<CartItem> GetOrderItems(int orderId)
{
    var OrderItems = _context.OrderItem.Where(p => p.OrderId == orderId).ToList();
    List<CartItem> orderItems = new List<CartItem>();
    foreach (var orderitem in OrderItems)
    {
        CartItem item = new CartItem(orderitem);
        item.Product = _context.Product.Single(x => x.Id == orderitem.ProductId);
        orderItems.Add(item);
    }
    return orderItems;
 }

能夠顯示到這邊就代表著訂單已經成功寫入資料庫囉
訂單畫面上立即付款的部分先不用理他,明天會進一步講要怎麼使用 PayPal Checkout 來付款


上一篇
【從實作學習ASP.NET Core】Day24 | 前台 | Session 購物車 (2)
下一篇
【從實作學習ASP.NET Core】Day26 | 前台 | PayPal 訂單付款 (1)
系列文
從實作學習ASP.NET Core - 30天的購物網站30

尚未有邦友留言

立即登入留言