跟着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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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 智能选择…