Nancy简单实战之NancyMusicStore(四):实现购物车

原文:Nancy简单实战之NancyMusicStore(四):实现购物车

前言

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

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

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 cookieCookieBasedSessions.Enable(pipelines);//Prevent errors on LinuxStaticConfiguration.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<Cart>(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 existsAddCartItem(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<Album>(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 ViewModelvar viewModel = new ShoppingCartViewModel{CartItems = cart.GetCartItems(),CartTotal = cart.GetTotal()};// Return the viewreturn View["Index", viewModel];
};

视图如下 :

@inherits Nancy.ViewEngines.Razor.NancyRazorViewBase<NancyMusicStore.ViewModels.ShoppingCartViewModel>
@{ViewBag.Title = "Shopping Cart";
}
<h3><em>Review</em> your cart:
</h3>
<p class="button"><a href="javascript:;">Checkout >></a>
</p>
<div id="update-message">
</div>
<table><tr><th>Album Name</th><th>Price (each)</th><th>Quantity</th><th></th></tr>@foreach (var item in Model.CartItems){<tr id="row-@item.RecordId"><td><a href="/store/details/@item.AlbumId">@item.Title</a></td><td>@item.Price</td><td id="item-count-@item.RecordId">@item.Count</td><td><a href="javascript:void(0);" class="RemoveLink" data-id="@item.RecordId">Remove from cart</a></td></tr>}<tr><td>Total</td><td></td><td></td><td id="cart-total">@Model.CartTotal</td></tr>
</table>

具体效果如下所示:

shoppingcart

从购物车中删除商品

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

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

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

public int RemoveFromCart(int id)
{string getItemCmd = "public.get_cart_item_by_cartid_and_recordid";var cartItem = DBHelper.QueryFirstOrDefault<Cart>(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{<script type="text/javascript">$(function () {$(".RemoveLink").click(function () {var recordToDelete = $(this).attr("data-id");if (recordToDelete != '') {$.post("/shoppingcart/removefromcart", { "id": recordToDelete },function (data) {if (data.ItemCount == 0) {$('#row-' + data.deleteid).fadeOut('slow');} else {$('#item-count-' + data.deleteId).text(data.itemCount);}$('#cart-total').text(data.cartTotal);$('#update-message').text(data.message);$('#cart-status').text('Cart (' + data.cartCount + ')');});}});});</script>
}

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

购物车结算

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

checkout

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

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

然后再考虑其他事情。

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

Post["/addressandpayment"] = _ =>
{var order = this.Bind<Order>();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 cartorderTotal += (item.Count * item.Price);}UpdateOrderTotal(order.OrderId, orderTotal);         // Empty the shopping cartEmptyCart();// Return the OrderId as the confirmation numberreturn order.OrderId;
}

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

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

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

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

本文也已经同步到 Nancy之大杂烩

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/390407.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《七步掌握业务分析》读书笔记六

分析技术和呈现格式 词汇表 强有力沟通的一个重要内容是一致地使用术语和惯用语。每次谈话都涉及对术语的共同理解。 工作流图&#xff08;也称为流程图、UNL活动图和过程图&#xff09; 工作流程把一个或多个业务过程的细节可视化地呈现出来&#xff0c;以澄清理解或提出过程改…

个人作业——软件工程实践总结作业

一、请回望暑假时的第一次作业&#xff0c;你对于软件工程课程的想象 1&#xff09;对比开篇博客你对课程目标和期待&#xff0c;“希望通过实践锻炼&#xff0c;增强计算机专业的能力和就业竞争力”&#xff0c;对比目前的所学所练所得&#xff0c;在哪些方面达到了你的期待和…

(转)在阿里,我们如何管理代码分支?

阿里妹导读&#xff1a;代码分支模式的选择并没有绝对的正确和错误之分&#xff0c;关键是与项目的规模和发布节奏相匹配。阿里协同研发平台在经过众多实践历练后&#xff0c;总结出了一套独创的分支管理方法&#xff1a;AoneFlow&#xff0c;通过兼备灵活高效与简单实用的流程…

WIN10系统 截图或者某些程序时屏幕会自动放大怎么办

右击这个应用程序&#xff0c;兼容性&#xff0c;以兼容模式运行&#xff0c;同时勾选高DPI设置时禁止显示缩放即可

hugo 能做web开发吗_如何自托管Hugo Web应用

hugo 能做web开发吗After hosting with Netlify for a few years, I decided to head back to self hosting. There are a few reasons for that, but the main reasoning was that I had more control over how things worked. 在Netlify托管了几年之后&#xff0c;我决定回到…

5187. 收集足够苹果的最小花园周长

给你一个用无限二维网格表示的花园&#xff0c;每一个 整数坐标处都有一棵苹果树。整数坐标 (i, j) 处的苹果树有 |i| |j| 个苹果。 你将会买下正中心坐标是 (0, 0) 的一块 正方形土地 &#xff0c;且每条边都与两条坐标轴之一平行。 给你一个整数 neededApples &#xff0c…

虚拟机 VMware Workstation12 安装OS X 系统

Windows下虚拟机安装Mac OS X —– VMware Workstation12安装Mac OS X 10.11本文即将介绍WIN虚拟MAC的教程。完整详细教程&#xff08;包含安装中的一些问题&#xff09;【并且适用其他mac os x版本】Windows下 VM12虚拟机安装OS X 10.11(详细教程) 工具/原料 Mac OS X 10.11 镜…

北大CIO走进龙泉寺交流研讨会圆满举行

缘起 2016年4月16日&#xff0c;北京大学信息化与信息管理研究中心秘书长姚乐博士与国家非物质文化遗产蔚县剪纸传承人周淑英女士一起在龙泉寺拜见了中国佛教协会会长、龙泉寺主持学诚法师。在拜见学诚法师时&#xff0c;姚乐博士与学诚法师聊到了“贤二机器僧”和人工智能。姚…

Centos7 Docker私有仓库搭建

Centos7 Docker私有仓库搭建 仓库&#xff1a;集中存放镜像的地方&#xff0c;可分为公共仓库和私有仓库&#xff08;公共仓库"http://hub.docker.com"或国内的"http://www.daocloud.io"&#xff09; Registry&#xff1a;注册服务器才是存放仓库具体的服务…

VIM 编辑器

2019独角兽企业重金招聘Python工程师标准>>> VIM 相对于VI 的提升 VIM 支持多级撤销VIM 可以跨平台运行VIM 支持语法高亮VIM 支持图形界面VIM 编辑器的操作模式 Command Mode -命令模式Insert Mode -输入模式Last Lin Mode -底行模式#使用yum 命令安装vim 软件&…

大型运输行业实战_day12_1_权限管理实现

1.业务分析 权限说的是不同的用户对同一个系统有不同访问权限,其设计的本质是:给先给用户分配好URL,然后在访问的时候判断该用户是否有当前访问的URL. 2.实现 2.1数据库设计标准5表权限结构 2.2.sql语句实现,根据用户id查询该用户所有的资源 sql语句: SELECT ur.user_id, r.u…

linux 安装maven

2019独角兽企业重金招聘Python工程师标准>>> 目录:/usr/local/maven 1.下载 wget http://mirrors.hust.edu.cn/apache/maven/maven-3/3.5.3/binaries/apache-maven-3.5.3-bin.tar.gz 2.解压 tar -zxvf apache-maven-3.5.3-bin.tar.gz 3.配置 vi /etc/profile #讲下面…

如何在React Native中使用react-navigation 5处理导航

React-navigation is the navigation library that comes to my mind when we talk about navigation in React Native. 当我们谈论React Native中的导航时&#xff0c;React-navigation是我想到的导航库。 Im a big fan of this library and its always the first solution I…

8597 石子划分问题 dpdp,只考虑第一次即可

8597 石子划分问题 时间限制:500MS 内存限制:1000K提交次数:155 通过次数:53 题型: 编程题 语言: G;GCC;VC Description 给定n个石子&#xff0c;其重量分别为a1,a2,a3,...,an。 要求将其划分为m份&#xff0c;每一份的划分费用定义为这份石子中最大重量与最小重量差的平方。…

802. 找到最终的安全状态

在有向图中&#xff0c;以某个节点为起始节点&#xff0c;从该点出发&#xff0c;每一步沿着图中的一条有向边行走。如果到达的节点是终点&#xff08;即它没有连出的有向边&#xff09;&#xff0c;则停止。 对于一个起始节点&#xff0c;如果从该节点出发&#xff0c;无论每…

第01章—快速构建

spring boot 系列学习记录&#xff1a;http://www.cnblogs.com/jinxiaohang/p/8111057.html 码云源码地址&#xff1a;https://gitee.com/jinxiaohang/springboot 一、Spring Initializr 使用教程 &#xff08;IntelliJ IDEA&#xff09; 具体步骤&#xff1a; 1、打开IDEA &am…

鱼眼镜头的distortion校正【matlab】

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 作者&#xff1a;WWC %%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% 功能&#xff1a;畸变矫正 clc; clear; close all; %% 读取图像 Aimread(D:\文件及下载相关\图片\distortion2.jpg)…

C# 使用WinApi操作剪切板Clipboard

前言&#xff1a; 最近正好写一个程序&#xff0c;需要操作剪切板 功能很简单&#xff0c;只需要从剪切板内读取字符串&#xff0c;然后清空剪切板&#xff0c;然后再把字符串导入剪切板 我想当然的使用我最拿手的C#来完成这项工作&#xff0c;原因无他&#xff0c;因为.Net框架…

专访赵加雨:WebRTC在网易云信的落地

去年的这个时候&#xff0c;在市面上公开表示使用WebRTC的公司还没几家&#xff0c;但2018年以来&#xff0c;宣布采用或支持WebRTC的公司已经越来越多。实时音视频提供商网易云信也在自研的NRTC中集成了WebRTC。在他们眼里&#xff0c;2017年是WebRTC的转折之年&#xff0c;而…

1、Linux命令随笔

1 Linux命令总结2 3 man 命令帮助;4 help 命令的帮助&#xff08;bash的内置命令&#xff09;;5 ls list,查看目录列表;6 -ld&#xff1a;查看目录权限;7 -l:(long)长格式显示属性;8 -F:给不同的文件类型结尾加标识9 -p:给目录加斜线10 …