博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Nancy简单实战之NancyMusicStore(四):实现购物车
阅读量:6249 次
发布时间:2019-06-22

本文共 7430 字,大约阅读时间需要 24 分钟。

原文:

前言

上一篇,我们完成了商品的详情和商品的管理,这一篇我们来完成最后的一个购物车功能。

购物车,不外乎这几个功能:添加商品到购物车,删除购物车中的商品,对购物车中的商品进行结算。

MVC MusicStore中,在Models文件夹中添加了一个ShoppingCart类来处理这一块的内容

这个类就类似我们的业务逻辑层,所以这里也采用了和它一样的做法。

取购物车

首先来看一下取购物车这个静态方法:

public static ShoppingCart GetCart(NancyContext context){    var cart = new ShoppingCart();    cart.ShoppingCartId = cart.GetCartId(context);    return cart;}

取购物车,其实只是给购物车类里面的ShoppingCartId赋值,而ShoppingCartId值是来自GetCartId方法:

public string GetCartId(NancyContext context){    if (context.Request.Session[CartSessionKey] == null)    {        if (context.CurrentUser != null)        {            context.Request.Session[CartSessionKey] = context.CurrentUser.UserName;        }        else        {            Guid tempCartId = Guid.NewGuid();            context.Request.Session[CartSessionKey] = tempCartId.ToString();        }    }    return context.Request.Session[CartSessionKey].ToString();}

在MVC MusicStrore中,这个方法的参数用的是HttpContextBase,而在Nancy中,Nancy有自己的Context

所以自然就是直接用Nancy自带的Context。这里是每次都会为新用户创建一个guid存储在session中

并用这个session作为购物车的唯一标识。

在Nancy中,用到了session的话,需要在启动器中启用Session,不然Session会一直是空的。

我们在CustomerBootstrapper类的ApplicationStartup方法中添加启动Cookie的代码,具体如下:

protected override void ApplicationStartup(TinyIoCContainer container,IPipelines pipelines){    //enable the cookie    CookieBasedSessions.Enable(pipelines);    //Prevent errors on Linux    StaticConfiguration.DisableErrorTraces = false;}

购物车商品数量

还记得我们在布局_Layout.cshtml里面还有一个购物车中的商品数量还没有实现。我们现在把这个功能补上。

在ShoppingCart中添加下面取数的方法,这个方法是根据购物车的id去数据取出相应的数据。

public int GetCount(){    string cmd = "public.get_total_count_by_cartid";    var res = DBHelper.ExecuteScalar(cmd, new    {        cid = ShoppingCartId    }, null, null, CommandType.StoredProcedure);    return Convert.ToInt32(res);}

然后我们新建一个ShopCartModule.cs,并在构造函数中添加取数的方法。

Get["/cartsummary"] = _ =>{    var cart = ShoppingCart.GetCart(this.Context);    return Response.AsJson(cart.GetCount());};

最后在_Layout.cshtml中用ajax调用这个方法即可:

$.ajax({    url: "/shoppingcart/cartsummary",    method: "get",    dataType: "json",    success: function (res) {        $("#cart-status").text('Cart (' + res + ')');    }});

这样我们就彻底把布局页完成了。下面是具体的效果

12932

下面就专注购物车的其他实现了。

添加商品到购物车

添加商品到购物车,有这两种情况:

  • 添加了一个购物车中没有的商品(要向购物车中插一条记录)

  • 添加了一个购物车中已经有了的商品(要向购物车中更新一条记录)

所以我们就可以得到下面的实现(ShoppingCart):

public void AddToCart(Album album){    string getItemCmd = "public.get_cart_item_by_cartid_and_albumid";    var cartItem = DBHelper.QueryFirstOrDefault
(getItemCmd, new { cid = ShoppingCartId, aid = album.AlbumId }, null, null, CommandType.StoredProcedure); string addToCartCmd = string.Empty; if (cartItem == null) { // Create a new cart item if no cart item exists AddCartItem(cartItem, album.AlbumId); } else { UpdateCartItem(cartItem); }}

在添加之前都要向根据购物车标识和专辑(商品)标识去判断。此时我们在Module中的实现就比较简单了

Get["/addtocart/{id:int}"] = _ =>{    int id = 0;    if (int.TryParse(_.id, out id))    {        string cmd = "public.get_album_by_aid";        var addedAlbum = DBHelper.QueryFirstOrDefault
(cmd, new { aid = id }, null, null, CommandType.StoredProcedure); var cart = ShoppingCart.GetCart(this.Context); cart.AddToCart(addedAlbum); } return Response.AsRedirect("~/");};

后台逻辑处理好了,我们把商品加入购物车的入口在那呢?入口就在商品详情页下面的【Add to cart】按钮

12955

当我们把加入购物车后,可以看到右上角的数量在改变,同时跳转回了首页。

12959

购物车首页

我们已经完成了添加商品到购物车,但是我们还看不到我们购物车里面有些什么商品,所以要有一个购物车首页。

购物车的首页,本质就是一个列表,这个列表所列了购物车内的所有商品,包含了这些商品的基本信息和购物车的订单总金额。

Get["/index"] = _ =>{    var cart = ShoppingCart.GetCart(this.Context);    // Set up our ViewModel    var viewModel = new ShoppingCartViewModel    {        CartItems = cart.GetCartItems(),        CartTotal = cart.GetTotal()    };    // Return the view    return View["Index", viewModel];};

视图如下 :

@inherits Nancy.ViewEngines.Razor.NancyRazorViewBase
@{ ViewBag.Title = "Shopping Cart";}

Review your cart:

Checkout >>

@foreach (var item in Model.CartItems) {
}
Album Name Price (each) Quantity
@item.Title @item.Price @item.Count Remove from cart
Total @Model.CartTotal

具体效果如下所示:

shoppingcart

从购物车中删除商品

删除购物车中的商品也是同样的有两种情况

  • 一种是让购物车中的商品数量减1

  • 一种是从购物车中直接删掉商品,不同的是删除的同时返回了商品的数量,这个数量用于在页面展示。

public int RemoveFromCart(int id){    string getItemCmd = "public.get_cart_item_by_cartid_and_recordid";    var cartItem = DBHelper.QueryFirstOrDefault
(getItemCmd, new { cid = ShoppingCartId, rid = id }, null, null, CommandType.StoredProcedure); int itemCount = 0; if (cartItem != null) { if (cartItem.Count > 1) { UpdateCartItemCount(cartItem, itemCount); } else { RemoveCartItem(cartItem.RecordId); } } return itemCount;}

同时还要在购物车列表页面添加相应的JS处理

@section scripts{    }

最后的话就是结算,下面进入我们的结算操作

购物车结算

购物车结算,也就是提交订单,也就是填写一些用户的相关信息,比如:姓名、地址、联系电话等等这些信息,见下图。

checkout

我们在Modules文件夹中添加一个CheckOutModule.cs用来处理结算相关的功能。

要结算,必须要登录,所以我们要首先添加需要授权的这句代码this.RequiresAuthentication();

然后再考虑其他事情。

提交订单的后台操作如下:

Post["/addressandpayment"] = _ =>{    var order = this.Bind
(); order.Username = this.Context.CurrentUser.UserName; order.OrderDate = DateTime.UtcNow; string cmd = "public.add_order"; var res = DBHelper.ExecuteScalar(cmd, new { odate = order.OrderDate, uname = order.Username, fname = order.FirstName, lname = order.LastName, adr = order.Address, cn = order.City, sn = order.State, pcode = order.PostalCode, cname = order.Country, ph = order.Phone, ea = order.Email, t = order.Total }, null, null, CommandType.StoredProcedure); if (Convert.ToInt32(res) != 0) { order.OrderId = Convert.ToInt32(res); var cart = ShoppingCart.GetCart(this.Context); cart.CreateOrder(order); string redirectUrl = string.Format("/checkout/complete/{0}", res.ToString()); return Response.AsRedirect(redirectUrl); } return View["AddressAndPayment"];};

先是创建了一张订单,这张订单只包含了一些用户信息。订单创建好了之后才去创建订单明细,最后就是返回订单完成页:

complete

创建订单明细的方法也是写在Models下面的ShoppingCart中,具体如下:

public int CreateOrder(Order order){    decimal orderTotal = 0;    var cartItems = GetCartItems();                            foreach (var item in cartItems)    {                        AddOrderDetails(new OrderDetail        {            AlbumId = item.AlbumId,            OrderId = order.OrderId,            UnitPrice = item.Price,            Quantity = item.Count        });        // Set the order total of the shopping cart        orderTotal += (item.Count * item.Price);    }    UpdateOrderTotal(order.OrderId, orderTotal);             // Empty the shopping cart    EmptyCart();    // Return the OrderId as the confirmation number    return order.OrderId;}

这里做的操作主要有三个:

  1. 把购物车中的商品插入到订单明细表中
  2. 更新订单主表的总金额
  3. 清空当前的购物车

到这里,我们的NancyMusicStore已经是到了收尾阶段。就差部署上线了啊!!

所以在下一篇,将是介绍Nancy的部署,分别在Windows和Linux下部署。

本文也已经同步到

转载地址:http://wvria.baihongyu.com/

你可能感兴趣的文章
我的友情链接
查看>>
压缩与解压(rar-linux)
查看>>
jQuery常用函数(一):基础
查看>>
linux fsck命令参数及用法详解
查看>>
关于java类执行的顺序
查看>>
我的友情链接
查看>>
迟来的2017总结文
查看>>
java 散列算法计算重复数据
查看>>
我的友情链接
查看>>
TCP/UDP Socket编程步骤
查看>>
RabbitMQ与PHP
查看>>
内存对齐模式与结构体
查看>>
最大子数组和
查看>>
fir.im Weekly - 聊聊让人向往的远程开发工作
查看>>
give root password for maintenance错误解决办法!
查看>>
web 应用的常见 漏洞有哪些
查看>>
linux sort
查看>>
Find命令使用详解
查看>>
CentOS7安装mysql5.7.16后,第一次登陆的默认密码
查看>>
学习之linux下cal,ls
查看>>