跟著AI學習C#之項目實戰-電商平臺 Day5

📅 Day 5:訂單提交與支付模擬

? 今日目標:

  • 創建 OrderOrderItem 模型
  • 實現從購物車生成訂單的功能
  • 模擬支付流程(成功/失敗頁面)
  • 添加訂單狀態跟蹤(如“待付款”、“已發貨”等)
  • 提交 Git 版本記錄進度

🧩 功能概覽

頁面功能
/Checkout/Index.cshtml確認訂單信息
/Checkout/Success.cshtml支付成功頁面
/Checkout/Failed.cshtml支付失敗頁面
/Orders/Index.cshtml我的訂單列表
數據庫模型Order, OrderItem

🛠? 知識點預覽

技術內容
數據模型Order 表示訂單,OrderItem 表示訂單中的商品
購物車轉訂單將 Session 中的購物車數據保存為訂單
支付模擬使用按鈕或自動跳轉模擬支付結果
用戶身份驗證只有登錄用戶才能下單
UI 設計Bootstrap + Razor Pages 構建訂單確認頁

🧱 第一步:創建訂單相關模型

Models 文件夾中創建以下兩個類:

? Order.cs

using System.ComponentModel.DataAnnotations;namespace ECommercePlatform.Models
{public enum OrderStatus{Pending,Paid,Shipped,Completed,Cancelled}public class Order{public int Id { get; set; }[Required]public string UserId { get; set; } = string.Empty;public DateTime OrderDate { get; set; } = DateTime.Now;public decimal TotalAmount { get; set; }public OrderStatus Status { get; set; } = OrderStatus.Pending;public List<OrderItem> Items { get; set; } = new();}
}

? OrderItem.cs

namespace ECommercePlatform.Models
{public class OrderItem{public int Id { get; set; }public int ProductId { get; set; }public string ProductName { get; set; } = string.Empty;public decimal Price { get; set; }public int Quantity { get; set; }public decimal TotalPrice => Price * Quantity;public int OrderId { get; set; }public Order Order { get; set; } = null!;}
}

🧰 第二步:更新數據庫上下文

打開 ApplicationDbContext.cs 并添加以下代碼:

public DbSet<Order> Orders { get; set; }
public DbSet<OrderItem> OrderItems { get; set; }

然后執行遷移命令:

dotnet ef migrations add AddOrderAndOrderItem
dotnet ef database update

🛒 第三步:創建訂單服務邏輯

? 創建 Services/IOrderService.cs

using ECommercePlatform.Models;public interface IOrderService
{Task<int> CreateOrderFromCart(string userId, IList<CartItem> cartItems);Task<IList<Order>> GetOrdersByUser(string userId);Task<Order?> GetOrderById(int id, string userId);
}

? 創建 Services/OrderService.cs

using Microsoft.AspNetCore.Identity;
using ECommercePlatform.Models;
using ECommercePlatform.Services;public class OrderService : IOrderService
{private readonly ApplicationDbContext _context;private readonly UserManager<IdentityUser> _userManager;public OrderService(ApplicationDbContext context, UserManager<IdentityUser> userManager){_context = context;_userManager = userManager;}public async Task<int> CreateOrderFromCart(string userId, IList<CartItem> cartItems){if (cartItems.Count == 0) throw new ArgumentException("購物車為空");var order = new Order{UserId = userId,OrderDate = DateTime.Now,TotalAmount = cartItems.Sum(i => i.TotalPrice),Items = cartItems.Select(i => new OrderItem{ProductId = i.ProductId,ProductName = i.Name,Price = i.Price,Quantity = i.Quantity}).ToList()};_context.Orders.Add(order);await _context.SaveChangesAsync();return order.Id;}public async Task<IList<Order>> GetOrdersByUser(string userId){return await _context.Orders.Include(o => o.Items).Where(o => o.UserId == userId).OrderByDescending(o => o.OrderDate).ToListAsync();}public async Task<Order?> GetOrderById(int id, string userId){return await _context.Orders.Include(o => o.Items).FirstOrDefaultAsync(o => o.Id == id && o.UserId == userId);}
}

注冊服務到 Program.cs

builder.Services.AddScoped<IOrderService, OrderService>();

📋 第四步:創建訂單確認頁面(Checkout/Index)

? Checkout/Index.cshtml.cs

using Microsoft.AspNetCore.Mvc.RazorPages;
using ECommercePlatform.Services;
using ECommercePlatform.Models;namespace ECommercePlatform.Pages.Checkout
{[Authorize]public class IndexModel : PageModel{private readonly IShoppingCartService _cartService;private readonly UserManager<IdentityUser> _userManager;public IndexModel(IShoppingCartService cartService, UserManager<IdentityUser> userManager){_cartService = cartService;_userManager = userManager;}public IList<CartItem> CartItems { get; set; } = new List<CartItem>();public decimal TotalPrice { get; set; }public async Task<IActionResult> OnGetAsync(){CartItems = _cartService.GetCartItems();TotalPrice = _cartService.GetTotalPrice();if (CartItems.Count == 0){return RedirectToPage("/Cart/Index");}return Page();}public async Task<IActionResult> OnPostAsync(){var user = await _userManager.GetUserAsync(User);if (user == null) return NotFound();var cartItems = _cartService.GetCartItems();if (cartItems.Count == 0) return BadRequest();// 創建訂單var orderService = HttpContext.RequestServices.GetService<IOrderService>();var orderId = await orderService.CreateOrderFromCart(user.Id, cartItems);// 清空購物車_cartService.ClearCart();return RedirectToPage("/Checkout/Success", new { id = orderId });}}
}

? Checkout/Index.cshtml

@page
@model ECommercePlatform.Pages.Checkout.IndexModel<h2>確認訂單</h2><table class="table"><thead><tr><th>名稱</th><th>單價</th><th>數量</th><th>總價</th></tr></thead><tbody>@foreach (var item in Model.CartItems){<tr><td>@item.Name</td><td>$@item.Price</td><td>@item.Quantity</td><td>$@item.TotalPrice</td></tr>}</tbody>
</table><h4>總計:$@Model.TotalPrice</h4><form method="post"><button type="submit" class="btn btn-success">立即支付</button>
</form>

? 第五步:創建支付成功頁面(Checkout/Success)

? Success.cshtml.cs

using Microsoft.AspNetCore.Mvc.RazorPages;namespace ECommercePlatform.Pages.Checkout
{public class SuccessModel : PageModel{public void OnGet(int id){// 這里可以顯示訂單編號或詳細信息}}
}

? Success.cshtml

@page
@model ECommercePlatform.Pages.Checkout.SuccessModel<h2>? 支付成功!</h2>
<p>您的訂單已提交。訂單號:@Request.Query["id"]</p>
<a asp-page="/Orders/Index" class="btn btn-primary">查看我的訂單</a>

? 第六步:創建支付失敗頁面(Checkout/Failed)

? Failed.cshtml.cs

using Microsoft.AspNetCore.Mvc.RazorPages;namespace ECommercePlatform.Pages.Checkout
{public class FailedModel : PageModel{public void OnGet(){}}
}

? Failed.cshtml

@page
@model ECommercePlatform.Pages.Checkout.FailedModel<h2>? 支付失敗</h2>
<p>請返回重新嘗試支付。</p>
<a asp-page="/Cart/Index" class="btn btn-warning">返回購物車</a>

📦 第七步:創建我的訂單頁面(Orders/Index)

? Orders/Index.cshtml.cs

using Microsoft.AspNetCore.Mvc.RazorPages;
using ECommercePlatform.Services;
using ECommercePlatform.Models;
using Microsoft.AspNetCore.Identity;namespace ECommercePlatform.Pages.Orders
{[Authorize]public class IndexModel : PageModel{private readonly IOrderService _orderService;private readonly UserManager<IdentityUser> _userManager;public IndexModel(IOrderService orderService, UserManager<IdentityUser> userManager){_orderService = orderService;_userManager = userManager;}public IList<Order> Orders { get; set; } = new List<Order>();public async Task OnGetAsync(){var user = await _userManager.GetUserAsync(User);if (user != null){Orders = await _orderService.GetOrdersByUser(user.Id);}}}
}

? Orders/Index.cshtml

@page
@model ECommercePlatform.Pages.Orders.IndexModel<h2>我的訂單</h2>@if (Model.Orders.Count == 0)
{<p>暫無訂單。</p>
}
else
{<table class="table"><thead><tr><th>訂單號</th><th>日期</th><th>總金額</th><th>狀態</th><th>操作</th></tr></thead><tbody>@foreach (var order in Model.Orders){<tr><td>@order.Id</td><td>@order.OrderDate.ToShortDateString()</td><td>$@order.TotalAmount</td><td>@order.Status</td><td><a asp-page="/Orders/Details" asp-route-id="@order.Id" class="btn btn-info btn-sm">查看詳情</a></td></tr>}</tbody></table>
}

📦 第八步:提交 Git 版本

git add .
git commit -m "Day5: Added order submission and payment simulation with order status tracking"

📝 今日總結

今天你完成了:

? 創建 OrderOrderItem 模型
? 實現從購物車生成訂單的功能
? 模擬支付流程(成功/失敗頁面)
? 訂單狀態跟蹤(Pending、Paid、Shipped 等)
? 提交版本控制記錄


📆 明日計劃(Day6)

我們將進入 后臺管理系統開發階段

  • 創建管理員頁面
  • 實現商品管理(CRUD)
  • 實現訂單管理(查看、狀態變更)
  • 權限控制(僅管理員可見)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/912232.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/912232.shtml
英文地址,請注明出處:http://en.pswp.cn/news/912232.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

復雜驅動開發-TLE9471的休眠流程與定時喚醒

文章目錄 前言休眠流程定時喚醒功能總結 前言 開發SBC時非常重要的一環就是開發休眠流程&#xff0c;其目的是為了保證接KL30的ECU在休眠模式下盡可能小的消耗低壓蓄電池的電量&#xff0c;防止車輛放置長時間后出現虧電。而定時喚醒功能在部分ECU中會有需求休眠后定期對車輛狀…

Spark 之 Reuse

src/main/scala/org/apache/spark/sql/execution/reuse/ReuseExchangeAndSubquery.scala case object ReuseExchangeAndSubquery extends Rule[SparkPlan] {def apply(plan: SparkPlan): SparkPlan = {if (conf.exchan

Solidity學習 - 錯誤處理

文章目錄 前言EVM錯誤處理機制EVM錯誤處理的核心特性程序中的錯誤處理 錯誤拋出方法require()函數require()觸發異常的場景關鍵特性 assert()函數assert()觸發異常的場景關鍵特性 require() vs assert()&#xff1a;選擇指南revert()函數關鍵特性 異常捕獲&#xff1a;try/catc…

如何永久刪除Android上的短信[無法恢復]

當您不再保留 Android 設備時&#xff0c;您將需要徹底刪除所有私人數據&#xff0c;包括短信。因此&#xff0c;有必要了解如何永久刪除Android上的短信。現在&#xff0c;閱讀本指南&#xff0c;掌握消除信息的實用方法。 第 1 部分&#xff1a;如何一鍵永久刪除 Android 上的…

P12894 [藍橋杯 2025 國 Java B] 智能交通信號燈

[Problem] \color{blue}{\texttt{[Problem]}} [Problem] 給定一個長度為 n n n 的數組 a 1 … n a_{1\dots n} a1…n?&#xff0c;進行 m m m 次一下操作&#xff1a; 給定 l , r l,r l,r&#xff0c;求出 ∑ l ≤ i < j ≤ r mex { a i , a j } \sum\limits_{l \le…

華為云Flexus+DeepSeek征文|基于華為云一鍵部署的 Dify-LLM 平臺構建智能試卷生成助手

目錄 前言 1 華為云Dify-LLM應用平臺部署 1.1 一鍵部署平臺簡介 1.2 四步完成部署流程 2 接入華為云 DeepSeek 自定義大模型 2.1 ModelArts Studio 模型服務介紹 2.2 配置自定義大模型 3 創建試卷生成工具&#xff08;工作流&#xff09; 3.1 設計 DSL 工作流 3.2 工…

嵌入式硬件與應用篇---寄存器GPIO控制

在 ARM 架構中&#xff0c;通過 32 位寄存器控制 GPIO&#xff08;通用輸入輸出&#xff09;的核心步驟和方法可分為以下幾個關鍵環節&#xff0c;結合不同芯片的實現差異&#xff0c;具體操作需參考對應的數據手冊&#xff1a; 一、GPIO 控制的核心步驟 1. 使能 GPIO 時鐘 …

Fiddler中文版抓包工具在跨域與OAuth調試中的深度應用

跨域和OAuth授權流程一直是Web和移動開發中最容易踩坑的領域。復雜的CORS配置、重定向中的Token傳遞、授權碼流程的跳轉&#xff0c;以及多域名環境下的Cookie共享&#xff0c;常常讓開發者陷入調試困境。此時&#xff0c;一款能夠精準捕獲、修改、重放請求的抓包工具顯得至關重…

React用戶交互事件

在React中處理用戶交互事件&#xff08;如點擊、輸入、提交等&#xff09;的方式與原生JavaScript類似&#xff0c;但有一些語法差異和最佳實踐。以下是常見交互事件的處理方法及代碼示例&#xff1a; 一、基本事件處理&#xff08;點擊、輸入等&#xff09; 1. 點擊事件&…

DHT11 STM32 HAL驅動庫 整數

dht11.h #ifndef __DHT11_H #define __DHT11_H#include "stm32f1xx_hal.h" // 根據實際芯片型號調整&#xff08;如stm32f4xx_hal.h&#xff09;// DHT11數據結構 typedef struct {GPIO_TypeDef *GPIOx; // GPIO端口&#xff08;如GPIOA&#xff09;uint16_t GP…

【Actix Web 精要】Rust Web 服務開發核心技術與實戰指南

目錄 一、Actix Web 核心架構解析1.1 核心組件交互流程1.2 關鍵組件說明&#xff1a; 二、項目初始化與配置2.1 創建項目2.2 添加依賴 (Cargo.toml)2.3 項目結構 三、核心模塊實現3.1 配置管理 (src/config.rs)3.2 應用狀態管理 (src/main.rs)3.3 數據模型 (src/models/user.rs…

從URL到視頻:用Python和AI構建自動化內容講解視頻生成管道

摘要 本文旨在從技術層面&#xff0c;深入探討并實踐一個將任意網頁鏈接&#xff08;如飛書文檔、博客文章&#xff09;自動轉換為帶有配音和字幕的講解視頻的系統。我們將詳細拆解整個實現流程&#xff0c;覆蓋從內容抓取與解析、利用大語言模型&#xff08;LLM&#xff09;智…

Java 使用 Easy Excel 進行 Excel 數據導入導出

1. 通過 Maven 下載 Easy Excel 依賴包 在項目的 pom.xml 文件中添加以下依賴&#xff1a; <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.1.1</version> <!-- 使用最新版本 -->…

國產化條碼類庫Spire.Barcode教程:如何使用 C# 讀取 PDF 中的條碼(兩種方法輕松實現)

在 PDF 文檔的 .NET 平臺處理流程中&#xff0c;使用 C# 讀取 PDF 條碼 是一項常見需求&#xff0c;特別適用于處理掃描件或電子表單。無論是物流、金融、醫療還是制造行業&#xff0c;PDF 文檔中經常包含用于追蹤或識別的條碼。這些條碼可能是嵌入圖像&#xff0c;也可能是矢量…

2023國賽數字取證-流量分析

數據取證 - 1 A 集團的?絡安全監控系統發現惡意份?正在實施?級可持續攻擊&#xff08;APT&#xff09;&#xff0c;并抓取了部分可疑流量包。請 您根據捕捉到的流量包&#xff0c;搜尋出?絡攻擊線索&#xff0c;分解出隱藏的惡意程序&#xff0c;并分析惡意程序的?為。 …

【預約小程序】-健身房預約課程小程序——仙盟創夢IDE

東方仙盟-坐擁萬個代碼 免費報表 阿雪技術觀 讓我們積極投身于技術共享的浪潮中&#xff0c;不僅僅是作為受益者&#xff0c;更要成為貢獻者。無論是分享自己的代碼、撰寫技術博客&#xff0c;還是參與開源項目的維護和改進&#xff0c;每一個小小的舉動都可能成為推動技術進…

SmartETL中數據庫操作與流程解耦的設計與應用

正如ETL這個概念本身所指示的&#xff0c;數據庫讀寫訪問是ETL的最常用甚至是最主要的操作。現代信息系統的設計與運行基本都是圍繞數據庫展開的&#xff0c;很多應用的核心功能都是對數據庫的CRUD&#xff08;創建、檢索、更新、刪除&#xff09;操作。 SmartETL框架設計之初…

【記錄解決問題】activiti--sql 轉義符設置

一、背景 %、&#xff01;、_在sql查詢時需要轉義&#xff0c;轉義的語法 like %?2% escape ?#{escapeCharacter()}二、activiti轉義配置 String wildcardEscapeClause ""; if (this.databaseWildcardEscapeCharacter ! null && this.databaseWildcard…

Unity AR構建維護系統的以AI驅動增強現實知識檢索系統

本博客概述了為維護開發的AI驅動增強現實&#xff08;AR&#xff09;知識檢索系統的開發過程&#xff0c;該系統集成了Unity用于AR、Python服務器用于后端處理&#xff0c;以及ChatGPT用于自然語言處理。該系統允許維護工人通過AR設備&#xff08;如HoloLens 2&#xff09;查詢…

Java面向對象核心:方法值傳遞與封裝機制精講

文章目錄 Java面向對象編程核心筆記一、方法值傳遞機制1. 基本數據類型傳遞2. 引用數據類型傳遞值傳遞總結 二、面向對象核心概念1. 類與對象關系2. 類定義規范3. 對象創建與使用 三、封裝機制詳解1. 封裝三大要素2. 封裝示例&#xff08;GirlFriend類&#xff09;3. 測試類4. …