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

📅 Day 6:后臺管理系統開發(Admin Panel)

? 今日目標:

  • 創建管理員頁面布局
  • 實現商品管理(CRUD)
  • 實現訂單管理(查看、狀態變更)
  • 添加權限控制(僅管理員可訪問)
  • 提交 Git 版本記錄進度

🧩 功能概覽

頁面功能
/Admin/Dashboard.cshtml后臺首頁儀表盤
/Admin/Products/Index.cshtml商品列表
/Admin/Products/Create.cshtml添加商品
/Admin/Products/Edit.cshtml編輯商品
/Admin/Products/Delete.cshtml刪除商品
/Admin/Orders/Index.cshtml訂單管理(查看、修改狀態)

🛠? 知識點預覽

技術內容
身份驗證使用 [Authorize(Roles = "Admin")] 控制訪問權限
數據模型復用 Product, Order, OrderItem 模型
CRUD 操作使用 Razor Pages 實現創建、讀取、更新、刪除
UI 設計使用 Bootstrap 構建簡潔的后臺界面
分頁支持可選實現分頁功能

🔐 第一步:添加管理員授權檢查

在所有 Admin 頁面模型中添加:

[Authorize(Roles = "Admin")]
public class IndexModel : PageModel
{// ...
}

并在 _Layout.cshtml 中添加后臺導航鏈接:

@if (User.IsInRole("Admin"))
{<li class="nav-item"><a class="nav-link" href="/Admin/Dashboard">后臺管理</a></li>
}

🧱 第二步:創建 Admin 頁面結構

創建以下文件夾和頁面結構:

/Pages/Admin/
├── Dashboard.cshtml
├── Products/
│   ├── Index.cshtml
│   ├── Create.cshtml
│   ├── Edit.cshtml
│   └── Delete.cshtml
└── Orders/├── Index.cshtml└── Details.cshtml

📦 第三步:實現商品管理(CRUD)

? Product Index 頁面(列出所有商品)

Index.cshtml.cs
using Microsoft.AspNetCore.Mvc.RazorPages;
using ECommercePlatform.Models;namespace ECommercePlatform.Pages.Admin.Products
{[Authorize(Roles = "Admin")]public class IndexModel : PageModel{private readonly ApplicationDbContext _context;public IndexModel(ApplicationDbContext context){_context = context;}public IList<Product> Products { get; set; } = new List<Product>();public void OnGet(){Products = _context.Products.ToList();}}
}
Index.cshtml
@page
@model ECommercePlatform.Pages.Admin.Products.IndexModel<h2>商品管理</h2><a asp-page="/Admin/Products/Create" class="btn btn-primary mb-3">添加新商品</a><table class="table table-bordered"><thead><tr><th>名稱</th><th>價格</th><th>庫存</th><th>操作</th></tr></thead><tbody>@foreach (var product in Model.Products){<tr><td>@product.Name</td><td>$@product.Price</td><td>@product.Stock</td><td><a asp-page="/Admin/Products/Edit" asp-route-id="@product.Id" class="btn btn-warning btn-sm">編輯</a><a asp-page="/Admin/Products/Delete" asp-route-id="@product.Id" class="btn btn-danger btn-sm">刪除</a></td></tr>}</tbody>
</table>

? Product Create 頁面(添加商品)

Create.cshtml.cs
using Microsoft.AspNetCore.Mvc.RazorPages;
using ECommercePlatform.Models;namespace ECommercePlatform.Pages.Admin.Products
{[Authorize(Roles = "Admin")]public class CreateModel : PageModel{private readonly ApplicationDbContext _context;public CreateModel(ApplicationDbContext context){_context = context;}[BindProperty]public Product Product { get; set; } = new();public IActionResult OnPost(){if (!ModelState.IsValid){return Page();}_context.Products.Add(Product);_context.SaveChanges();return RedirectToPage("/Admin/Products/Index");}}
}
Create.cshtml
@page
@model ECommercePlatform.Pages.Admin.Products.CreateModel<h2>添加新商品</h2><form method="post"><div class="form-group"><label>名稱</label><input asp-for="Product.Name" class="form-control" /></div><div class="form-group"><label>價格</label><input asp-for="Product.Price" class="form-control" /></div><div class="form-group"><label>庫存</label><input asp-for="Product.Stock" class="form-control" /></div><div class="form-group"><label>圖片地址</label><input asp-for="Product.ImageUrl" class="form-control" /></div><button type="submit" class="btn btn-success mt-2">提交</button>
</form>

? Product Edit 頁面(編輯商品)

Edit.cshtml.cs
using Microsoft.AspNetCore.Mvc.RazorPages;
using ECommercePlatform.Models;namespace ECommercePlatform.Pages.Admin.Products
{[Authorize(Roles = "Admin")]public class EditModel : PageModel{private readonly ApplicationDbContext _context;public EditModel(ApplicationDbContext context){_context = context;}[BindProperty]public Product Product { get; set; } = new();public IActionResult OnGet(int id){var product = _context.Products.Find(id);if (product == null) return NotFound();Product = product;return Page();}public IActionResult OnPost(){if (!ModelState.IsValid){return Page();}_context.Products.Update(Product);_context.SaveChanges();return RedirectToPage("/Admin/Products/Index");}}
}
Edit.cshtml
@page
@model ECommercePlatform.Pages.Admin.Products.EditModel<h2>編輯商品</h2><form method="post"><input type="hidden" asp-for="Product.Id" /><div class="form-group"><label>名稱</label><input asp-for="Product.Name" class="form-control" /></div><div class="form-group"><label>價格</label><input asp-for="Product.Price" class="form-control" /></div><div class="form-group"><label>庫存</label><input asp-for="Product.Stock" class="form-control" /></div><div class="form-group"><label>圖片地址</label><input asp-for="Product.ImageUrl" class="form-control" /></div><button type="submit" class="btn btn-success mt-2">保存</button>
</form>

? Product Delete 頁面(刪除商品)

Delete.cshtml.cs
using Microsoft.AspNetCore.Mvc.RazorPages;
using ECommercePlatform.Models;namespace ECommercePlatform.Pages.Admin.Products
{[Authorize(Roles = "Admin")]public class DeleteModel : PageModel{private readonly ApplicationDbContext _context;public DeleteModel(ApplicationDbContext context){_context = context;}public Product? Product { get; set; }public IActionResult OnGet(int id){Product = _context.Products.Find(id);if (Product == null) return NotFound();return Page();}public IActionResult OnPost(int id){var product = _context.Products.Find(id);if (product != null){_context.Products.Remove(product);_context.SaveChanges();}return RedirectToPage("/Admin/Products/Index");}}
}
Delete.cshtml
@page
@model ECommercePlatform.Pages.Admin.Products.DeleteModel<h2>確認刪除?</h2>
<p>你確定要刪除商品:<strong>@Model.Product?.Name</strong></p><form method="post"><button type="submit" class="btn btn-danger">確認刪除</button><a asp-page="/Admin/Products/Index" class="btn btn-secondary">取消</a>
</form>

🧾 第四步:實現訂單管理(查看 + 修改狀態)

? Orders/Index.cshtml.cs

using Microsoft.AspNetCore.Mvc.RazorPages;
using ECommercePlatform.Models;namespace ECommercePlatform.Pages.Admin.Orders
{[Authorize(Roles = "Admin")]public class IndexModel : PageModel{private readonly ApplicationDbContext _context;public IndexModel(ApplicationDbContext context){_context = context;}public IList<Order> Orders { get; set; } = new List<Order>();public void OnGet(){Orders = _context.Orders.Include(o => o.Items).ToList();}}
}
Orders/Index.cshtml
@page
@model ECommercePlatform.Pages.Admin.Orders.IndexModel<h2>訂單管理</h2><table class="table table-bordered"><thead><tr><th>訂單號</th><th>用戶ID</th><th>總金額</th><th>狀態</th><th>操作</th></tr></thead><tbody>@foreach (var order in Model.Orders){<tr><td>@order.Id</td><td>@order.UserId</td><td>$@order.TotalAmount</td><td>@order.Status</td><td><a asp-page="/Admin/Orders/Details" asp-route-id="@order.Id" class="btn btn-info btn-sm">查看詳情</a></td></tr>}</tbody>
</table>

? Orders/Details.cshtml.cs

using Microsoft.AspNetCore.Mvc.RazorPages;
using ECommercePlatform.Models;namespace ECommercePlatform.Pages.Admin.Orders
{[Authorize(Roles = "Admin")]public class DetailsModel : PageModel{private readonly ApplicationDbContext _context;public DetailsModel(ApplicationDbContext context){_context = context;}public Order? Order { get; set; }public IActionResult OnGet(int id){Order = _context.Orders.Include(o => o.Items).FirstOrDefault(o => o.Id == id);if (Order == null) return NotFound();return Page();}public IActionResult OnPostUpdateStatus(int id, string status){var order = _context.Orders.Find(id);if (order != null){Enum.TryParse(status, out OrderStatus parsedStatus);order.Status = parsedStatus;_context.SaveChanges();}return RedirectToPage("/Admin/Orders/Details", new { id });}}
}
Orders/Details.cshtml
@page
@model ECommercePlatform.Pages.Admin.Orders.DetailsModel<h2>訂單詳情 - #@Model.Order?.Id</h2><p>用戶ID: @Model.Order?.UserId</p>
<p>日期: @Model.Order?.OrderDate</p>
<p>狀態:<form method="post" class="d-inline"><input type="hidden" name="id" value="@Model.Order?.Id" /><select name="status" asp-for="Order.Status" asp-items="Html.GetEnumSelectList<OrderStatus>()" onchange="this.form.submit()"></select></form>
</p><h4>商品列表:</h4>
<table class="table table-bordered"><thead><tr><th>商品名</th><th>單價</th><th>數量</th><th>總價</th></tr></thead><tbody>@foreach (var item in Model.Order?.Items ?? new()){<tr><td>@item.ProductName</td><td>$@item.Price</td><td>@item.Quantity</td><td>$@item.TotalPrice</td></tr>}</tbody>
</table>

📦 第五步:提交 Git 版本

git add .
git commit -m "Day6: Added admin panel with product management and order management"

📝 今日總結

今天你完成了:

? 創建后臺管理頁面(Dashboard + Products + Orders)
? 實現商品的增刪改查(CRUD)
? 實現訂單查看與狀態變更
? 添加管理員權限控制
? 提交版本控制記錄


📆 明日計劃(Day7)

我們將進入 部署準備與優化階段

  • 添加靜態資源(CSS/JS 圖片等)
  • 優化頁面樣式與交互體驗
  • 添加分頁功能(商品、訂單列表)
  • 配置生產環境設置(appsettings.Production.json)
  • 準備發布部署(dotnet publish)

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

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

相關文章

使用OpcUaHelper在C# WinForms中連接OPC UA服務器并讀取數據

使用OpcUaHelper在C# WinForms中連接OPC UA服務器并讀取數據 下面是一個完整的示例&#xff0c;展示如何使用OpcUaHelper庫在C# WinForms應用程序中連接OPC UA服務器并讀取數據。 1. 準備工作 首先&#xff0c;確保你已經安裝了OpcUaHelper NuGet包。可以通過NuGet包管理器控…

鴻蒙應用開發中的數據存儲:SQLite與Preferences全面解析

在鴻蒙&#xff08;HarmonyOS&#xff09;應用開發中&#xff0c;數據存儲是構建功能完整、用戶體驗良好的應用程序的關鍵環節。鴻蒙系統提供了多種數據存儲解決方案&#xff0c;其中SQLite數據庫和Preferences&#xff08;偏好設置&#xff09;是最常用的兩種方式。本文將深入…

夏至之日,共赴實時 AI 之約:RTE Open Day@AGI Playground 2025 回顧

每年 RTE 開發者社區的重磅活動—— RTE Open Day &#xff0c;也在六月的 AGI Playground 現場開啟今年的行程。這是 RTE Open Day 第五期現場&#xff0c;這期我們的關鍵詞是 「Real-Time AI」 和 「Voice Agent」&#xff0c;不僅有來自社區的 16 個項目&#xff0c;還有兩場…

Tomcat性能調優指南

文章目錄 一、Tomcat性能調優概述為什么需要調優Tomcat&#xff1f; 二、Tomcat架構與性能關鍵點三、JVM調優1. 內存配置優化2. 垃圾回收優化3. 其他JVM優化參數 四、連接器(Connector)調優1. NIO vs APR/Native2. 高級NIO配置 五、線程池優化六、會話管理優化1. 會話超時配置2…

Swift 小技巧:用單邊區間優雅處理模糊范圍

進入正題之前先科普一下 Swift 區間的知識。 Swift 中的區間有兩種類型&#xff1a;閉區間和半開區間。 閉區間&#xff1a;用 a...b 表示&#xff0c;包含 a 和 b。半開區間&#xff1a;用 a..<b 表示&#xff0c;包含 a 但不包含 b。 舉個例子 想判斷一個數字是否在 0 …

Tang Prime 20K板OV2640例程

準備用Tang Prime 20K開發板進行OV2640攝像頭采集驗證。 Tang Primer 20K是由開源硬件廠商SiPEED矽速科技推出&#xff0c;是一款以 GW2A-LV18PG256C8/I7 為主芯片的核心板&#xff0c;準備了 2 個擴展板&#xff0c;Dock 和 Lite。板卡包含有HDMI輸出&#xff0c;DVP接口&…

基于Anaconda環境開發IntelliJ IDEA實用JSON轉Java實體插件

在軟件開發中&#xff0c;將JSON數據轉換為Java實體類是常見需求。借助Anaconda環境強大的包管理能力與IntelliJ IDEA的插件開發體系&#xff0c;我們可以打造一款高效實用的JSON轉Java實體插件&#xff0c;顯著提升開發效率。下面將從需求分析、技術選型、開發實現到優化部署&…

idea運行到遠程機器 和 idea遠程JVM調試

一、idea運行到遠程機器 適用場景&#xff0c;本地連接不上遠程機器的部分組件&#xff0c;如&#xff1a;redis、數據庫。 缺點&#xff1a;每次修改程序&#xff0c;會復制所有的 依賴和class 啟動比較慢。 工作原理&#xff1a;遠程機器和本機器&#xff0c;都會啟動一個端口…

微信小程序接入騰訊云短信驗證碼流程

以下是針對 AA公司微信小程序接入騰訊云短信驗證碼 的 全流程操作指南&#xff0c;包含資質申請、簽名/模板配置、代碼對接的完整解決方案&#xff1a; 一、資質申請&#xff08;必須通過審核才能發短信&#xff09; 1?? 進入資質管理頁 路徑&#xff1a;騰訊云控制臺 → 短…

阿里云OSS文件上傳完整實現方案

一、前言 阿里云對象存儲服務(OSS)是一種海量、安全、低成本、高可靠的云存儲服務。本文將詳細介紹如何在Spring Boot項目中集成阿里云OSS實現文件上傳功能。 二、準備工作 1. 獲取OSS配置信息 在開始前&#xff0c;您需要準備以下OSS配置信息&#xff1a; endpoint: OSS服…

【軟考--軟件設計師】10.2 關系型數據庫

10 模式分解 分解 模式分解:將一個關系模式分解為多個子模式 模式分解就是模式規范化的工具&#xff0c;模式分解使用無損連接和保持函數依賴來衡量模式分解后是否導致原有模式中部分信息丟失。 無損連接 保持函數依賴 11、事務管理 事務的ACID性質: (1)原子性(Atomicit…

python訓練day44 預訓練模型

預訓練模型發展史 預訓練模型的訓練策略 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pyplot as plt# 設置中文字體支持 plt.rcParams["…

[論文閱讀]MISSRce

論文title: MISSRec: Pre-training and Transferring Multi-modal Interest-aware Sequence Representation for Recommendation

Redis學習筆記——黑馬點評 附近商鋪到UV統計 完結

前言&#xff1a; 今天完結了Redis的所有實戰篇。 學習收獲&#xff1a; GEO數據結構&#xff1a; GEO就是Geolocation的簡寫形式&#xff0c;代表地理坐標。Redis在3.2版本中加入對Geo的支持&#xff0c;存儲、管理和操作地理空間數據的特殊數據結構&#xff0c;它能高效處…

【客戶端排查】mac電腦怎么查看客戶端的實時運行日志

先退出客戶端&#xff1b;打開訪達里的應用程序&#xff1b; 打開【顯示包內容】&#xff1b; 找到MacOS 雙擊里面的終端程序&#xff1b; 雙擊后&#xff0c;客戶端會自動啟動&#xff0c;且可以在終端中查看客戶端的實時日志啦~

HarmonyOS NEXT倉頡開發語言實戰案例:健身App

各位好&#xff0c;今日分享一個健身app的首頁&#xff1a; 這個頁面看起比之前的案例要稍微復雜一些&#xff0c;主要在于頂部部分&#xff0c;有重疊的背景&#xff0c;還有偏移的部分。重疊布局可以使用Stack容器實現&#xff0c;超出容器范圍的偏移可以使用負數間距來實現&…

TreeMap源碼分析 紅黑樹

今天嘗試刨一下TreeMap的祖墳。 底層結構對比 先來看一下與HashMap、LinkedHashMap和TreeMap的對比&#xff0c;同時就當是復習一下&#xff1a; HashMap使用數組存儲數據&#xff0c;并使用單向鏈表結構存儲hash沖突數據&#xff0c;同一個沖突桶中數據量大的時候&#xff…

華為云Flexus+DeepSeek征文|基于Dify構建拍照識題智能學習助手

華為云FlexusDeepSeek征文&#xff5c;基于Dify構建拍照識題智能學習助手 一、構建拍照識題智能學習助手前言二、構建拍照識題智能學習助手環境2.1 基于FlexusX實例的Dify平臺2.2 基于MaaS的模型API商用服務 三、構建拍照識題智能學習助手實戰3.1 配置Dify環境3.2 配置Dify工具…

題解:CF2120E Lanes of Cars

根據貪心&#xff0c;不難想到每次會把最長隊伍末尾的那輛車移動到最短隊伍的末尾。但由于 k k k 的存在&#xff0c;會導致一些冗余移動的存在。設需要挪動 C C C 輛車&#xff0c;則怒氣值可以表示為 f ( C ) k C f(C) kC f(C)kC&#xff0c;其中 f ( C ) f(C) f(C) 是…

Excel基礎:選擇和移動

本文演示Excel中基礎的選擇和移動操作&#xff0c;并在最后提供了一張思維導圖&#xff0c;方便記憶。 文章目錄 一、選擇1.1 基礎選擇1.1.1 選擇單個單元格1.1.2 選擇連續范圍 1.2 行列選擇1.2.1 選擇整行整列1.2.2 選擇多行多列 1.3 全選1.3.1 全選所有單元格1.3.2 智能選擇…