ASP.NET Core MVC开发实战之商城系统(二)

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

开发工具及技术


在本商城系统实例中,主要用到的开发工具和技术,如下所示:
  • 开发工具,Visual Studio 2022 
  • 数据库,SQL Server Management Studio 2012
  • 开发框架,基于.Net 6.0的ASP.NET Core MVC
  • 前端框架,基于项目自带的bootstrap,jQuery等前端库。

页面布局


根据前一篇文章的讲解,在首页除了商品类型,banner条,友情链接外,还有降价促销,新品爆款两个部分,为首页产品展示的核心,具体布局如下所示:
ASP.NET Core MVC开发实战之商城系统(二)

数据表设计


产品表Product,主要用于存储产品的详细信息,包括产品名称,价格,店铺ID等内容,具体如下所示:
ASP.NET Core MVC开发实战之商城系统(二)
建表语句,如下所示:
CREATE TABLE [dbo].[EB_Product](  [Id] [bigint] IDENTITY(1,1) NOT NULL,  [ShopId] [bigint] NULL,  [Name] [varchar](100) NULL,  [CategoryId] [bigint] NULL,  [SubCategoryId] [bigint] NULL,  [Price] [money] NULL,  [Preferential] [numeric](18, 4) NULL,  [PreferentialPrice] [money] NULL,  [Description] [text] NULL,  [Brand] [varchar](50) NULL,  [BasicStyle] [varchar](50) NULL,  [ProductStyle] [varchar](50) NULL,  [Year] [varchar](50) NULL,  [Season] [varchar](50) NULL,  [Scenario] [varchar](50) NULL,  [ImageUrl] [varchar](500) NULL,  [CreateTime] [datetime] NULL,  [CreateUser] [varchar](50) NULL,  [LastEditTime] [datetime] NULL,  [LastEditUser] [varchar](50) NULL) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

商品实体创建


产品表对应的项目模型实体,和数据表一一对应,如下所示:
using SqlSugar; namespace EasyBuyShop.Models{    [SugarTable("EB_Product")]    public class Product : EntityModel    {        /// <summary>        /// 店铺ID        /// </summary>        public long ShopId { get; set; }         /// <summary>        /// 产品名称        /// </summary>        public string Name { get; set; }         /// <summary>        /// 大类ID        /// </summary>        public long CategoryId { get; set; }         /// <summary>        /// 小类ID        /// </summary>        public long SubCategoryId { get; set; }         /// <summary>        /// 价格        /// </summary>        public decimal Price { get; set; }         /// <summary>        /// 打折后价格        /// </summary>        public decimal PreferentialPrice { get; set; }         /// <summary>        /// 品牌        /// </summary>        public string Brand { get; set; }         /// <summary>        /// 折扣        /// </summary>        public decimal Preferential { get; set; }        public string Description { get; set; }         /// <summary>        /// 基础风格        /// </summary>        public string BasicStyle { get; set; }         /// <summary>        /// 产品风格        /// </summary>        public string ProductStyle { get; set; }         /// <summary>        /// 年份        /// </summary>        public string Year { get; set; }         /// <summary>        /// 季节        /// </summary>        public string Season { get; set; }         /// <summary>        /// 主要场景        /// </summary>        public string Scenario { get; set; }         /// <summary>        /// 主图片Url        /// </summary>        public string ImageUrl { get; set; }    }}

数据处理层DAL


数据处理层用于和数据库进行交互,本次主要用于获取折扣Top3,和新品Top100这两种条件的的商品列表,如下所示:
using EasyBuyShop.Models;using EasyBuyShop.Utils; namespace EasyBuyShop.DAL{    public class ProductDal:BaseDal    {        /// <summary>        /// 新品前100        /// </summary>        /// <returns></returns>        public List<Product> GetTopNew100()        {            try            {                using (var db = this.GetDb(BaseDal.ConnStr))                {                    return db.Queryable<Product>().OrderByDescending(r => r.Id).Take(100).ToList();                }            }            catch (Exception ex)            {                LogHelper.Fatal(ex.Message);                return new List<Product>();            }        }         /// <summary>        /// 折扣Top3        /// </summary>        /// <returns></returns>        public List<Product> GetTopDisCount3()        {            try            {                using (var db = this.GetDb(BaseDal.ConnStr))                {                    return db.Queryable<Product>().OrderByDescending(r => r.Preferential).Take(3).ToList();                }            }            catch (Exception ex)            {                LogHelper.Fatal(ex.Message);                return new List<Product>();            }        }    }}
注意:上述功能采用SqlSugar自带的方法实现,会根据Lamada表达式生成对应的SQL语句,可减少手写SQL的繁琐。

控制器获取


因为降价促销和新品爆款,也是首页的一部分,所以需要在首页控制器HomeController中,获取对应商品,传递到视图层,如下所示:
using EasyBuyShop.DAL;using EasyBuyShop.Models;using Microsoft.AspNetCore.Mvc;using System.Diagnostics; namespace EasyBuyShop.Controllers{    public class HomeController : Controller    {        private readonly ILogger<HomeController> logger;         public HomeController(ILogger<HomeController> logger)        {            this.logger = logger;        }         public IActionResult Index()        {            CategoryDal categoryDal = new CategoryDal();            SubCategoryDal subCategoryDal = new SubCategoryDal();            ProductDal productDal = new ProductDal();            var categories = categoryDal.GetCategories();            var subCategories = subCategoryDal.GetSubCategories();            var topNew100Product = productDal.GetTopNew100();            var topDiscount3Product = productDal.GetTopDisCount3();            ViewData["Categories"] = categories;            ViewData["SubCategories"] = subCategories;            ViewData["TopNew100"] = topNew100Product;            ViewData["TopDiscount3"] = topDiscount3Product;            var username = HttpContext.Session.GetString("username");            var realName = HttpContext.Session.GetString("realname");            ViewBag.Username = username;            ViewBag.RealName = realName;            return View();        }    }}
注意:控制器方法中,往视图层传递数据采用ViewData和ViewBag实现,也可采用其他方式实现。具体ViewData和ViewBag传递数据之间的差异,可参考之前写的相关文章

视图层呈现数据


在Views/Home/Index.cshtml视图页面中,降价促销为一行三列,展示降价Top3的商品,具体如下所示:
<!-- banner style 2 start --><div class="banner-style-2 pt-100">  <div class="container" style="margin-left:0px;margin-right:0px;padding-right:0px;padding-left:0px;">    <div class="row">      @foreach (var topDiscount in ViewData["TopDiscount3"] as List<Product>)      {        <div class="col-md-4">          <div class="banner-style-2-img mb-res">            <img src="@topDiscount.ImageUrl" alt="">            <div class="banner-style-2-dec">              <h4>@topDiscount.Brand</h4>              <h3>降价 @(Math.Round( topDiscount.Preferential*100,0))% 销售</h3>              <a href="" onclick="javascript:buy(@(topDiscount.Id));return false;">购买</a><br>            </div>          </div>          <div class="shop-title f-left">            <h3><a href="/Product/Detail/@(topDiscount.Id)">@topDiscount.Name</a></h3>          </div>        </div>      }    </div>  </div></div><!-- banner style 2 end -->
新品爆款源码如下所示:
<!-- shop area start --><div class="portfolio-area pt-100 pb-70" style="padding-top:100px;padding-bottom:70px;">  <div class="container">    <div class="section-title text-center mb-50">      <h2>新品爆款 <i class="fa fa-shopping-cart"></i></h2>    </div>    <div class="row portfolio-style-2">      <div class="grid" style="position: relative; height: 100%;">        @foreach (var topNewProduct in ViewData["TopNew100"] as List<Product>)        {          <div class="col-md-3 col-sm-6 col-xs-12 mb-30">            <div class="single-shop">              <div class="shop-img">                <a href="/Product/Detail/@(topNewProduct.Id)"><img src="@topNewProduct.ImageUrl" alt=""></a>                <div class="shop-quick-view">                  <a href="/Product/Detail/@(topNewProduct.Id)" data-toggle="modal" data-target="#quick-view" title="预览">                    <i class="pe-7s-look"></i>                  </a>                </div>                <div class="price-up-down">                  <span class="sale-new">新品</span>                </div>                <div class="button-group">                  <a href="#" title="添加购物车" onclick="javascript:addCart(@(topNewProduct.Id));return false;">                    <i class="pe-7s-cart"></i>                    添加购物车                  </a>                  <a class="wishlist" href="#" onclick="javascript:buy(@(topNewProduct.Id));return false;" title="立即购买">                    <i class="pe-7s-like"></i>                    立即购买                  </a>                </div>              </div>              <div class="shop-text-all">                <div class="title-color fix">                  <div class="shop-title f-left">                    <h3><a href="/Product/Detail/@(topNewProduct.Id)">@topNewProduct.Name</a></h3>                  </div>                  <span class="price f-right">                    <span class="new">$@topNewProduct.PreferentialPrice</span>                  </span>                </div>                <div class="fix">                  <span class="f-left">@(topNewProduct.BasicStyle) | @(topNewProduct.ProductStyle)</span>                </div>              </div>            </div>          </div>        }      </div>    </div>  </div></div><!-- shop area end -->
其中视图层代码,采用Razor表达式for循环,展示列表中的内容。

页面展示


降价促销功能,运行如下所示:
ASP.NET Core MVC开发实战之商城系统(二)
新品爆款功能,运行如下所示:
ASP.NET Core MVC开发实战之商城系统(二)
以上就是ASP.NET Core MVC开发实战之商城系统第二部分内容。后续将继续介绍其他模块。关于本系列其他文章,可参考以下链接:
ASP.NET Core MVC开发实战之商城系统(开篇)
ASP.NET Core MVC开发实战之商城系统(一)