我們簡單定義結帳流程為 [ 購物車 -> 輸入訂單資料 -> 建立訂單 -> 付款 ]
昨天已經完成購物車了,今天就繼續把輸入訂單資料和建立訂單的部分完成
建立訂單模型,訂單是要存進資料庫的,所以是需要建立資料表的
還是老樣子用 Add-Migration
、Update-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.cs
到 Controller 資料夾
並且加入[Authorize]
將他設為驗證狀態,必須要登入才能進行結帳動作
這個控制器會需要三個主要 Action :
配合對應的 [填寫訂單資料] 和 [顯示訂單] 兩個頁面
接收來自購物車的資料,加上訂單欄位填寫
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
來付款