[回馈]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是嵌入式脚本语言&…...
OpenClaw备份恢复:千问3.5-35B-A3B-FP8配置迁移指南
OpenClaw备份恢复:千问3.5-35B-A3B-FP8配置迁移指南 1. 为什么需要备份OpenClaw配置 上周我的开发机突然硬盘故障,不得不重装系统。当我准备重新部署OpenClaw时,突然意识到一个严重问题——过去三个月精心调试的千问3.5模型配置、飞书机器人…...
Android安全漏洞案例分析:血淋淋的教训
Android安全漏洞案例分析:血淋淋的教训 Android安全漏洞案例分析:血淋淋的教训 案例一:Secret Token泄露导致账户劫持 漏洞危害:攻击者获取用户全部权限 某社交App在客户端硬编码了API密钥,攻击者通过反编译获取密钥…...
千问3.5-27B知识库应用:OpenClaw变身技术问答助手
千问3.5-27B知识库应用:OpenClaw变身技术问答助手 1. 为什么需要本地化技术问答助手? 去年我在开发一个开源项目时,遇到了一个奇怪的Docker网络问题。当时在Stack Overflow上搜索了半天,找到的答案要么过时,要么不适…...
2026年4月如何集成OpenClaw?华为云保姆级10分钟安装及百炼APIKey配置方法
2026年4月如何集成OpenClaw?华为云保姆级10分钟安装及百炼APIKey配置方法。OpenClaw(原Clawdbot)作为2026年主流的AI自动化助理平台,可通过阿里云轻量服务器实现724小时稳定运行,并快速接入钉钉,让AI在企业…...
30个核心概念一次讲明白,小白也能轻松入门大模型(收藏版)
这几年,AI 几乎成了人人都在谈的话题。 有人在聊大模型,有人在说智能体,有人担心算力不够,也有人被“参数”、“微调”、“多模态”、“RAG”这些词绕得头晕。 结果就是:听了很多,越听越乱。 这篇文章是用尽…...
浅谈MIKEURBAN计算进度条停止的解决方法
01 问题昨天晚上,一个同事拿着笔记本对着我说,为什么我的MIKE URBAN计算进度条一直停滞在5%,停止了。我说是不是兼容问题,要不重新安装下软件吧。最终还是很感谢某同事找到了解决方法。02 解决方法MIKE URBAN低版本的通常分为了32…...
火影AI绘画实战:用忍者绘卷Z-Image Turbo生成鸣人、佐助角色图教程
火影AI绘画实战:用忍者绘卷Z-Image Turbo生成鸣人、佐助角色图教程 1. 教程概述与准备工作 如果你是火影忍者的粉丝,现在可以通过AI技术轻松生成你最喜欢的角色图像。本教程将带你使用"忍者绘卷Z-Image Turbo"这个专门为火影风格优化的AI绘画…...
如何3步掌握Home Assistant SSH Web终端:从零到精通的管理指南 ✨
如何3步掌握Home Assistant SSH Web终端:从零到精通的管理指南 ✨ 【免费下载链接】app-ssh Advanced SSH & Web Terminal - Home Assistant Community Apps 项目地址: https://gitcode.com/gh_mirrors/ad/app-ssh 在智能家居系统的日常维护中࿰…...
从零开始:Java使用通用物体识别-ResNet18镜像实现图像分类
从零开始:Java使用通用物体识别-ResNet18镜像实现图像分类 你是否想过,用Java写几行代码,就能让程序看懂一张图片里有什么?过去,这可能需要搭建复杂的Python环境、学习深度学习框架、处理繁琐的模型部署。但现在&…...
AI集成开发工程师的技术实践与转型之路
第一章:技术架构演进与AI融合趋势 1.1 传统开发范式的演进 现代软件开发正经历从单一业务系统向智能化业务系统的转型。传统的.NET技术栈作为企业级应用开发的基石,其技术架构也在不断演进: // 典型的三层架构示例 public class BusinessLogic {private readonly IDataAc…...
