[回饋]ASP.NET Core MVC開發實戰之商城系統(五)

来源:https://www.cnblogs.com/hsiang/archive/2023/08/03/17602215.html
-Advertisement-
Play Games

經過一段時間的準備,新的一期【ASP.NET Core MVC開發實戰之商城系統】已經開始,在之前的文章中,講解了商城系統的整體功能設計,頁面佈局設計,環境搭建,系統配置,及首頁【商品類型,banner條,友情鏈接,降價促銷,新品爆款】,商品列表頁面,商品詳情等功能的開發,今天繼續講解購物車功能開發... ...


經過一段時間的準備,新的一期【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開發實戰之商城系統第五部分內容,後續將繼續介紹其他模塊,敬請期待。


作者:小六公子
出處:http://www.cnblogs.com/hsiang/
本文版權歸作者和博客園共有,寫文不易,支持原創,歡迎轉載【點贊】,轉載請保留此段聲明,且在文章頁面明顯位置給出原文連接,謝謝。
關註個人公眾號,定時同步更新技術及職場文章


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本文主要從源碼的角度解析了 ThreadLocal,並分析了發生記憶體泄漏的原因及正確用法,最後對它的應用場景進行了簡單介紹。 ...
  • 拆分列是`pandas`中常用的一種數據操作,它可以將一個包含多個值的列按照指定的規則拆分成多個新列,方便進行後續的分析和處理。拆分列的使用場景比較廣泛,以下是一些常見的應用場景: 1. 處理日期數據:在日期數據中,經常會將年、月、日等信息合併成一列,通過拆分列可以將其拆分成多個新列,方便進行時間序 ...
  • ## 教程簡介 JUnit是一個Java語言的單元測試框架。它由Kent Beck和Erich Gamma建立,逐漸成為源於Kent Beck的sUnit的xUnit家族中最為成功的一個。 JUnit有它自己的JUnit擴展生態圈。多數Java的開發環境都已經集成了JUnit作為單元測試的工具。JU ...
  • > 服務發現與負載均衡。 # 一、背景 在微服務架構中,這裡以開發環境「Dev」為基礎來描述,在K8S集群中通常會開放:路由網關、註冊中心、配置中心等相關服務,可以被集群外部訪問; ![](https://img2023.cnblogs.com/blog/1691717/202308/1691717 ...
  • ### 歡迎訪問我的GitHub > 這裡分類和彙總了欣宸的全部原創(含配套源碼):[https://github.com/zq2599/blog_demos](https://github.com/zq2599/blog_demos) ### 本篇概覽 - 本文是《quarkus依賴註入》系列的第 ...
  • # Unity Shader編輯器工具類ShaderUtil 常用函數和用法 ![Unity Shader](https://cdn.pixabay.com/photo/2017/08/30/01/05/milky-way-2695569_960_720.jpg) Unity的Shader編輯器工具 ...
  • 實現目標,在一個ListBox中選擇一個子項進行拖拽到另一個ListBox中,拖拽到某一子項區域進行替換 axaml代碼 1 <ListBox 2 Name="consumableListBox" 3 Margin="5" 4 ItemsSource="{Binding ConsumableList ...
  • # Unity IFilterBuildAssemblies Unity IFilterBuildAssemblies是Unity引擎中的一個非常有用的功能,它可以讓開發者在構建項目時自定義哪些程式集需要被包含在構建中,哪些程式集需要被排除在建之外。這個功能可以幫助開發者更好地控制項目的構建過程,減 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...