[回馈]ASP.NET Core MVC开发实战之商城系统(五)
经过一段时间的准备,新的一期【ASP.NET Core MVC开发实战之商城系统】已经开始,在之前的文章中,讲解了商城系统的整体功能设计,页面布局设计,环境搭建,系统配置,及首页【商品类型,banner条,友情链接,降价促销,新品爆款】,商品列表页面,商品详情等功能的开发,今天继续讲解购物车功能开发,仅供学习分享使用,如有不足之处,还请指正。

购物车功能说明
在首页或者商品列表页面,如果用户对商品感兴趣,可以点击快捷方式,将商品加入购物车;或者在商品详情页面,选择对应的商品参数后,将商品加入购物车。商品加入购物车的渠道是有多种,而用户也可以对已经加入购物车的商品进行购买,或者删除购物车。每一个用户都有各自的购物车,相互之间独立,所以购物车功能需要用户先进行登录,才能查看。
购物车功能设计
根据购物车功能说明,购物车主要显示已添加的商品列表,并可以删除,或者选择商品进行购买,设计页面如下所示:

购物车功能开发
购物车主要展示用户选择的商品信息。
1. 数据表创建
购物车表EB_Cart主要用于存储商品信息,用户信息,数量,及个人喜好等内容,如下所示:

购物车表创建语句如下所示:
CREATE TABLE [dbo].[EB_Cart]([Id] [bigint] IDENTITY(1,1) NOT NULL,[ProductId] [bigint] NULL,[CustomerId] [bigint] NULL,[Quantity] [int] NULL,[Remark] [varchar](200) NULL,[CreateTime] [datetime] NULL,[CreateUser] [varchar](50) NULL,[LastEditTime] [datetime] NULL,[LastEditUser] [varchar](50) NULL
) ON [PRIMARY]
2. 购物车实体创建
购物车实体和数据表结构保持一致,方便进行映射。如下所示:
using SqlSugar;namespace EasyBuyShop.Models
{/// <summary>/// 购物车/// </summary>[SugarTable("EB_Cart")]public class Cart:EntityModel{public long ProductId { get; set; }public long CustomerId { get; set; }/// <summary>/// 数量/// </summary>public int Quantity { get; set; }public string Remark { get; set; }}
}
3. 数据处理层DAL
购物车列表,主要包括添加购物车,删除,查询等功能,DAL层代码如下所示:
using EasyBuyShop.Models;
using EasyBuyShop.Utils;namespace EasyBuyShop.DAL
{public class CartDal:BaseDal{/// <summary>/// 获取购物车列表/// </summary>/// <param name="userId"></param>/// <returns></returns>public List<Cart> GetCartListByUserId(long userId){try{using (var db = this.GetDb(BaseDal.ConnStr)){return db.Queryable<Cart>().Where(r => r.CustomerId == userId).ToList();}}catch (Exception ex){LogHelper.Fatal(ex.Message);return new List<Cart>();}}public int DeleteById(long id){try{using (var db = this.GetDb(BaseDal.ConnStr)){int cnt = db.Deleteable<Cart>(r => r.Id == id).ExecuteCommand();return cnt;}}catch (Exception ex){LogHelper.Fatal(ex.Message);return -1;}}public Cart GetCart(long id){try{using (var db = this.GetDb(BaseDal.ConnStr)){return db.Queryable<Cart>().First(r => r.Id == id);}}catch (Exception ex){LogHelper.Fatal(ex.Message);return null;}}}
}
4. 控制器获取
控制器方法主要包括添加购物车【1.首页或商品列表快捷添加购物车 2.商品详情页面添加购物车】,查询购物车, 删除购物车,代码如下所示:
using EasyBuyShop.DAL;
using EasyBuyShop.Models;
using Microsoft.AspNetCore.Mvc;namespace EasyBuyShop.Controllers
{/// <summary>/// 购物车控制器/// </summary>public class CartController : Controller{/// <summary>/// 购物车列表页面/// </summary>/// <returns></returns>public IActionResult Index(){var userId = HttpContext.Session.GetInt32("userid");if (userId == null){return Redirect("/Auth/login");}var cartDal = new CartDal();var productDal = new ProductDal();var cartList = cartDal.GetCartListByUserId((long)userId);var products = productDal.GetProductListByIds(cartList.Select(r => r.ProductId).ToList());ViewData["CartList"] = cartList;ViewData["ProductList"]= products;var username = HttpContext.Session.GetString("username");var realName = HttpContext.Session.GetString("realname");ViewData["Username"] = username;ViewData["RealName"] = realName;return View();}/// <summary>/// 首页或商品列表,快捷加入购物车/// </summary>/// <param name="productId"></param>/// <returns></returns>[HttpPost]public IActionResult Add(int productId){Msg msg = new Msg();var userId = HttpContext.Session.GetInt32("userid");var userName= HttpContext.Session.GetString("username");if (userId == null){msg.code = -1;msg.message = "尚未登录";return Json(msg);}var productDal = new ProductDal();var product = productDal.GetProduct(productId);if (product != null){var cartDal = new CartDal();var cart=new Cart();cart.ProductId = productId;cart.CustomerId = userId.Value;cart.Quantity = 1;cart.Remark= string.Empty;cart.CreateUser = userName;cart.CreateTime=DateTime.Now;cart.LastEditUser = userName;cart.LastEditTime = DateTime.Now;int id = cartDal.InsertT<Cart>(cart);if(id > 0){msg.code = 0;msg.message = "成功";return Json(msg);}else{msg.code = -1;msg.message = "加入购物车失败";return Json(msg);}}else{msg.code = -1;msg.message = "商品不存在";return Json(msg);}}/// <summary>/// 商品详情页面加入购物车/// </summary>/// <returns></returns>[HttpPost]public IActionResult AddWithForm(){Msg msg = new Msg();var userId = HttpContext.Session.GetInt32("userid");var userName = HttpContext.Session.GetString("username");if (userId == null){msg.code = -1;msg.message = "尚未登录";return Json(msg);}var productId =long.Parse( Request.Form["productId"]);var quantity = int.Parse(Request.Form["quantity"]);var color = Request.Form["color"];var size = Request.Form["size"];var remark = $"颜色:{color},大小:{size}";var productDal = new ProductDal();var product = productDal.GetProduct(productId);if (product != null){var cartDal = new CartDal();var cart = new Cart();cart.ProductId = productId;cart.CustomerId = userId.Value;cart.Quantity = quantity;cart.Remark = remark;cart.CreateUser = userName;cart.CreateTime = DateTime.Now;cart.LastEditUser = userName;cart.LastEditTime = DateTime.Now;int id = cartDal.InsertT<Cart>(cart);if (id > 0){msg.code = 0;msg.message = "成功";}else{msg.code = -1;msg.message = "加入购物车失败";}}else{msg.code = -1;msg.message = "商品不存在";}return Redirect("/Cart/Index");}/// <summary>/// 移除购物车/// </summary>/// <param name="Id"></param>/// <returns></returns>public ActionResult Delete(int Id){var cartDal =new CartDal();if(cartDal.DeleteById(Id) > 0){//成功}else{//删除失败}return View();}}
}
5. 视图层展示
在Views/Cart/Index.cshtml购物车视图中,接收控制器传递的参数。如下所示:
@{var totalPrice = 0.0M;
}
<div class="content-wrap"><div class="content"><!-- shopping-cart-area start --><div class="cart-area ptb-100"><form action="/Purchase/BuyWithCart" method="post"><div class="container"><div class="row"><div class="col-lg-12 col-md-12 col-sm-12 col-xs-12"><div class="table-content table-responsive"><table><thead><tr><th class="product-check">选择</th><th class="product-price">图片</th><th class="product-name">产品名称</th><th class="product-price">价格</th><th class="product-price">优惠价格</th><th class="product-quantity">数量</th><th class="product-subtotal">总计</th><th class="product-name">删除</th></tr></thead><tbody>@{var cartList = ViewData["CartList"] as List<Cart>;var productList = ViewData["ProductList"] as List<Product>;if (cartList.Count > 0){foreach (var cart in cartList){var product = productList.FirstOrDefault(r => r.Id == cart.ProductId);totalPrice = totalPrice + (product.PreferentialPrice * cart.Quantity);<tr><td class="product-check"><input type="checkbox" value="@(cart.Id)" name="chkCart" style="width:25px;height:25px;" checked="checked" onchange="javascript:checkCartProduct(this);" /></td><td class="product-thumbnail"><a href="/Product/Detail/@(product.Id)"><img src="@(product.ImageUrl)" alt="" width="100" height="100"></a></td><td class="product-name"><a href="/Product/Detail/@(product.Id)">@product.Name</a><br /><span style="font-size:12px; color:lightgray">备注:@(string.IsNullOrEmpty(cart.Remark) ? "无" : cart.Remark)</span></td><td class="product-price"><span class="amount">@(Math.Round(product.Price, 2))</span></td><td class="product-price"><span class="amount">@(Math.Round(product.PreferentialPrice, 2))</span></td><td class="product-quantity"><input value="@(cart.Quantity)" type="number"></td><td class="product-subtotal">@(Math.Round(product.PreferentialPrice * cart.Quantity, 2))</td><td class="product-remove"><a href="/Cart/Delete/@(cart.Id)"><i class="fa fa-times"><font style="font-size:14px;">删除</font></i></a></td></tr>}}else{<tr><td colspan="7">购物车暂无商品</td></tr>}}</tbody></table></div></div></div><div class="row tax-coupon-div"><div class="col-md-7 col-sm-12 col-xs-12"></div><div class="col-md-5 col-sm-12 col-xs-12"><div class="cart-total"><ul><li class="cart-black">总计<span>@totalPrice</span></li></ul><div class="cart-total-btn"><div class="cart-total-btn1 f-left"></div><div class="cart-total-btn2 f-right"><input type="submit" value="购买" class="go-btn" onclick="javascript:return checkSubmit();" style="background-color: rgb(255, 80, 0);border-width:0px;margin-top:5px;" /></div></div></div></div></div></div></form></div><!-- shopping-cart-area end --></div><!-- content end -->
</div>
<!-- content-wrap end -->
<script src="~/js/shop.js"></script>
购物车页面展示
运行程序,点击登录,在登录成功后,在右上角个人名称,点击下拉菜单,选择购物车,然后打开购物车页面,如下所示:

以上就是ASP.NET Core MVC开发实战之商城系统第五部分内容,后续将继续介绍其他模块,敬请期待。
相关文章:
[回馈]ASP.NET Core MVC开发实战之商城系统(五)
经过一段时间的准备,新的一期【ASP.NET Core MVC开发实战之商城系统】已经开始,在之前的文章中,讲解了商城系统的整体功能设计,页面布局设计,环境搭建,系统配置,及首页【商品类型,ba…...
iPhone 8透明屏的透明度高吗?
iPhone 8是苹果公司于2017年推出的一款智能手机,它采用了全新的设计和技术,其中一个亮点就是透明屏。 透明屏是指屏幕具有透明度,可以透过屏幕看到背后的物体。 iPhone 8的透明屏采用了最新的OLED技术,这种技术可以实现更高的对比…...
Vue2 第十五节 组件间通信方式
1.组件的自定义事件 2.全局事件总线 3.消息订阅与发布 一.组件的自定义事件 1.1 绑定自定义事件 ① 自定义事件就是一种组件间通信方式,用于子组件和父组件之间传递数据 ② props来实现子组件给父组件传递数据 (1)先给父组件中绑定一个…...
maven的下载与安装
文章目录 1 官网下载地址2 设置环境变量3 设置仓库地址4 添加阿里云的中央镜像 1 官网下载地址 https://maven.apache.org/ 下载 2 设置环境变量 MAVEN_HOME PATH mvn -v验证 3 设置仓库地址 仓库地址 4 添加阿里云的中央镜像 阿里云中央镜像...
BroadcastChannel 实现浏览器tab无刷新通讯
前提须知 使用 BroadcastChannel 来实现浏览器tab通讯必须是同源的BroadcastChannel 支持多tab间通讯mdn 链接 具体使用 发送方使用 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewpor…...
98. Python基础教程:try...except...finally语句
【目录】 文章目录 1. try...except...finally语法介绍2. try...except...finally执行顺序3. 捕获特定类型的异常4. 捕获所有类型的异常5. 实操练习-打开txt文件并输出文件内容 【正文】 在今天的课程中,我们将学习Python中的异常处理语句try...except...finally。 …...
c语言实现简单的tcp客户端
功能:实现一个简单的tcp客户端,连接本地端口8888的tcp服务端,并发送一条报文。 /* * File: main.c* Author: vincent** Created on 2023年8月3日, 上午9:56*/#include <stdio.h> #include <stdlib.h> #include <string.h…...
RocketMQ详解及注意事项
RocketMQ是阿里巴巴开源的一款分布式消息中间件,具有高吞吐量、高可用性、可扩展性和稳定性强等特点,广泛应用于异步消息、应用解耦、流量削峰填谷等场景。本文将详细介绍RocketMQ的基本架构、工作流程、消息模型,并列出在使用RocketMQ时需要…...
选择适合的项目管理系统,了解有哪些选择和推荐
随着科技的进步和全球竞争的加剧,项目管理已经成为企业成功的关键要素。为了更好地组织和监控项目,许多企业和组织正在采用项目管理系统(PMS)。本文将探讨项目管理系统的主要组成部分以及其在实际应用中的优势。 “项目管理系统有哪些?国际上比较常见的…...
linux基础命令-cd
切换当前工作目录使用 cd 命令 在 Linux 操作系统中,cd 是一个常用的命令,用于切换当前的工作目录。工作目录是用户当前所在的文件夹,执行命令时将会在该目录中进行操作。cd 命令的功能是更改当前工作目录到指定的目录位置。在本文中…...
MySQL数据库分库分表备份
分库备份 创建脚本并编写 [rootlocalhost scripts]# vim bak_db_v1.sh #!/bin/bash 备份的路径 bak_path/backup/db 账号密码 mysql_cmd-uroot -pRedHat123 需要排除的数据库 exclude_dbinformation_schema|mysql|performance_schema|sys 检验备份路径是否存在&#…...
PyTorch 中的累积梯度
https://stackoverflow.com/questions/62067400/understanding-accumulated-gradients-in-pytorch 有一个小的计算图,两次前向梯度累积的结果,可以看到梯度是严格相等的。 代码: import numpy as np import torchclass ExampleLinear(torch…...
【面试精品】运维工程师需要具备的核心能力有哪些?
运维,在部分没有接触过IT的小伙伴的概念中觉得是一个比较低级的职位,很容易从字面理解为运营、维护. 很多朋友认为,无论IDC机房运维、网络运维、桌面运维、Linux系统运维、数据库运维、云计算运维、等在互联网公司中的工作就是安装系统&…...
微服务实战项目-学成在线-选课学习(支付与学习中心)模块
微服务实战项目-学成在线-选课学习(支付与学习中心)模块 1 模块需求分析 1.1 模块介绍 本模块实现了学生选课、下单支付、学习的整体流程。 网站的课程有免费和收费两种,对于免费课程学生选课后可直接学习,对于收费课程学生需要下单且支付成功方可选…...
postman和jmeter的区别何在?
小伙伴们大家好呀,前段时间笔者做了一个小调查,发现软件测试行业做功能测试和接口测试的人相对比较多。在测试工作中,有高手,自然也会有小白,但有一点我们无法否认,就是每一个高手都是从小白开始的…...
maven安装(windows)
环境 maven:Apache Maven 3.5.2 jdk环境:jdk 1.8.0_192 系统版本:win10 一、安装 apache官网下载需要的版本,然后解压缩,解压路径尽量不要有空格和中文 官网下载地址 https://maven.apache.org/download.cgihttps:…...
自学安全卷不动,是放弃还是继续?
有天我想去搜一下怎么约女孩子看电影比较不油腻的时候,突然看到一个话题“自学网络安全的人都是什么感受”。 因为我的粉丝们大部分都是在自学或者是准备入行的大学生,所以我很认真一个一个去看了下别人的回答。基本都是劝退自学为主,因为自学…...
Django实现音乐网站 ⑶
使用Python Django框架制作一个音乐网站,在系列文章2的基础上继续开发,本篇主要是后台单曲、专辑、首页轮播图表模块开发。 目录 后台单曲、专辑表模块开发 表结构设计 单曲表(singe)结构 专辑表(album)…...
(13) Qt事件系统(two)
目录 事件分发函数 无边框窗口拖动 自定义事件 发送事件的函数 自定义事件 系统定义的事件号 自定义事件号 自定义事件类 发送和处理事件 sendEvent与postEvent的区别 栈区对象 堆区对象 事件传播机制 事件传播的过程 事件传播到父组件 鼠标单击事件与按钮单击信…...
PHP的知识概要
PHP技术基础 1、PHP是Hypertext Preprocessor的缩写,是基于服务器端运行的脚本程序语言,可以实现数据库和网页之间的数据交互。PHP可以单独运行,也可镶嵌在HTML文件 中。它具有开发快速、性能稳定的优点。 2、PHP是嵌入式脚本语言&…...
RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...
LLM基础1_语言模型如何处理文本
基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...
(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...
python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...
ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...
