[回馈]ASP.NET Core MVC开发实战之商城系统(一)

  • [回馈]ASP.NET Core MVC开发实战之商城系统(一)已关闭评论
  • 114 次浏览
  • A+
所属分类:.NET技术
摘要

经过一段时间的准备,新的一期【ASP.NET Core MVC开发实战之商城系统】已经开始,今天着重讲解布局设计,环境搭建,系统配置,及首页商品类型,banner条,友情链接等功能的开发。

经过一段时间的准备,新的一期【ASP.NET Core MVC开发实战之商城系统】已经开始,今天着重讲解布局设计,环境搭建,系统配置,及首页商品类型,banner条,友情链接等功能的开发。

[回馈]ASP.NET Core MVC开发实战之商城系统(一)

 

首页布局设计

 

首页是商城系统的门面,首页的设计的好坏关系着用户的体验,在本示例中,首页主要分为以下几个模块,如下所示:

[回馈]ASP.NET Core MVC开发实战之商城系统(一)

 

项目环境搭建

 

1. 安装第三方库

 

所谓“工欲善其事必先利其器”,在开发程序之前,先将项目配置好。项目需要安装的第三方库,可通过Nuget包管理器进行安装。

目前程序用到的第三方库有三个:

  • 日志组件:NLog,NLog.Web.AspNetCore,主要用于记录系统日子。
  • 数据库组件:目前采用SqlSugarCore,访问数据库程序。

具体安装库和版本如下所示:

[回馈]ASP.NET Core MVC开发实战之商城系统(一)

 

2. 启动配置

 

汽配启动配置主要配置注入服务,及路由,主要有以下几个:

  • Session服务,由于到进行用户身份验证,所以需要用到Session。
  • 鉴权/授权组件,主要用于什么验证及权限管理。
  • 日志组件,记录程序执行过程的日志,便于问题分析和解决。
  • 路由控制器注入。

具体配置【Program.cs】参照如下所示:

using EasyBuyShop.DAL; using EasyBuyShop.Utils; using Microsoft.AspNetCore.Authentication.Cookies; using NLog.Web;  var builder = WebApplication.CreateBuilder(args);  // Add services to the container. builder.Services.AddControllersWithViews();  //1. 往容器中添加Session服务,启用Session服务 builder.Services.AddSession(option => {     option.IdleTimeout = TimeSpan.FromMinutes(10);     option.Cookie.Name = "DemoMvcCore"; });  //添加鉴权服务 builder.Services.AddAuthentication(options => {     options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;  }).AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options => {     options.LoginPath = "/Auth/Login";     options.LogoutPath = "/Auth/Logout"; });  // NLog: Setup NLog for Dependency injection builder.Logging.ClearProviders(); builder.Host.UseNLog();  LogHelper.LoadConfiguration();  var app = builder.Build();  //启动时获取数据库连接字符串 BaseDal.ConnStr = app.Configuration.GetConnectionString("Default");  // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) {     app.UseExceptionHandler("/Home/Error");     // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.     app.UseHsts(); }  //2.使用Session中间件,主要用于拦截Http请求 app.UseSession();  app.UseHttpsRedirection(); app.UseStaticFiles();  app.UseRouting();  app.UseAuthentication();  app.UseAuthorization();  app.MapControllerRoute(     name: "default",     pattern: "{controller=Home}/{action=Index}/{id?}");  app.Run();

 

3. 配置文件

 

配置文件【appsetting.json】主要配置数据库连接字符串,及其他信息。如下所示:

{   "ConnectionStrings": {     "Default": "Server=localhost;Database=EasyBuyShop;Trusted_Connection=True;User Id=sa;Password=abc123"   },   "Logging": {     "LogLevel": {       "Default": "Information",       "Microsoft.AspNetCore": "Warning"     }   },   "AllowedHosts": "*" }

 

4. 日志配置

 

日志配置【nlog.config】主要配置NLog组件需要的日志保存路径以及层级等信息。如下所示:

<?xml version="1.0" encoding="utf-8" ?> <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       autoReload="true"       internalLogLevel="Info"       internalLogFile="Logsinternal-nlog-AspNetCore.txt">  	<!-- enable asp.net core layout renderers --> 	<extensions> 		<add assembly="NLog.Web.AspNetCore"/> 	</extensions>  	<!-- the targets to write to --> 	<targets> 		<!-- File Target for all log messages with basic details --> 		<target xsi:type="File" name="allfile" fileName="${basedir}Logsnlog-all-${shortdate}.log" 				layout="${longdate}|${event-properties:item=EventId:whenEmpty=0}|${level:uppercase=true}|${logger}|${message} ${exception:format=tostring}" />  		<!-- File Target for own log messages with extra web details using some ASP.NET core renderers --> 		<target xsi:type="File" name="ownFile-web" fileName="${basedir}Logsnlog-own-${shortdate}.log" 				layout="${longdate}|${event-properties:item=EventId:whenEmpty=0}|${level:uppercase=true}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action}" />  		<!--Console Target for hosting lifetime messages to improve Docker / Visual Studio startup detection --> 		<target xsi:type="Console" name="lifetimeConsole" layout="${MicrosoftConsoleLayout}" /> 	</targets>  	<!-- rules to map from logger name to target --> 	<rules> 		<!--All logs, including from Microsoft--> 		<logger name="*" minlevel="Info" writeTo="allfile" />  		<!--Output hosting lifetime messages to console target for faster startup detection --> 		<logger name="*" minlevel="Info" writeTo="lifetimeConsole, ownFile-web" final="true" />  		<!--Skip non-critical Microsoft logs and so log only own logs (BlackHole) --> 		<logger name="Microsoft.*" minlevel="Info" final="true" /> 		<logger name="System.Net.Http.*" minlevel="Info" final="true" />  		<logger name="*" minlevel="Info" writeTo="ownFile-web" /> 	</rules> </nlog>

注意:NLog日志组件不支持相对路径配置,如果想让日志保存在程序根目录,需要通过${basedir}进行配置,否则日志如法保存。

 

页面布局

 

其中Header,Footer,前台各个页面都会用到,所以采用Layout布局页面展示【_Layout.cshtml】。如下所示:

<!DOCTYPE html> <html lang="en"> <head>     <meta charset="utf-8" />     <meta name="viewport" content="width=device-width, initial-scale=1.0" />     <title>@ViewData["Title"] - 易购商城</title>     <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />     <link rel="stylesheet" href="~/css/shop_style.css" />     <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />     <link rel="stylesheet" href="~/EasyBuyShop.styles.css" asp-append-version="true" /> </head> <body>     <header class="py-3 mb-3 border-bottom container" style="padding-left: 0px;padding-right: 0px;">         <div class="container-fluid d-grid gap-3 align-items-center" style="grid-template-columns: 1fr 9fr;width:100%;padding-left: 0px;padding-right: 0px;">             <div class="dropdown">                 <a href="/Home/Index" class="d-flex align-items-center col-lg-4 mb-2 mb-lg-0 link-dark text-decoration-none dropdown-toggle">                     <h2>易购商城</h2>                 </a>             </div>              <div class="d-flex align-items-center">                 <form class="w-100 me-3" role="search" action="/Product/Index/">                     <div>                         <input type="search" class="form-control" placeholder="商品名称" aria-label="Search" style="width:85%;display:inline-block;line-height:1.7" name="productName">                         <button type="submit" class="btn btn-outline-primary">搜索</button>                     </div>                 </form>                  <div class="flex-shrink-0 dropdown">                     @if (!string.IsNullOrEmpty(ViewBag.UserName))                     {                         <a href="#" class="d-block link-dark text-decoration-none dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">                             <span>@ViewBag.RealName</span>                         </a>                         <ul class="dropdown-menu text-small shadow" style="">                             <li><a class="dropdown-item" href="/Cart/Index">购物车</a></li>                             <li><a class="dropdown-item" href="/Personal/Setting">设置</a></li>                             <li><a class="dropdown-item" href="/Personal/Index">个人信息</a></li>                             <li><hr class="dropdown-divider"></li>                             <li><a class="dropdown-item" href="/Auth/Logout">登出</a></li>                         </ul>                     }                     else                     {                         <a href="/Auth/Login" class="d-block link-dark text-decoration-none">                             <span>亲,请登录</span>                         </a>                     }                                      </div>             </div>         </div>     </header>     <div class="container" style="padding-left:0px;padding-right:0px;">         <main role="main" class="pb-3">             @RenderBody()         </main>     </div>     <footer class="py-3 my-4 border-top footer text-muted" style="line-height:10px;margin-bottom:0.5rem!important;">         <p class="text-center text-muted">© 2023-2024 易购商城 老码识途 公子小六</p>     </footer>     <script src="~/lib/jquery/dist/jquery.min.js"></script>     <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>     <script src="~/js/site.js" asp-append-version="true"></script>     @await RenderSectionAsync("Scripts", required: false) </body> </html>

布局页面效果如下所示:

页头【Header】包含一个Form表单,用于查询商品信息,如下所示:

[回馈]ASP.NET Core MVC开发实战之商城系统(一)

页脚【Footer】用于设置版权信息,如下所示:

[回馈]ASP.NET Core MVC开发实战之商城系统(一)

 

商品类型功能

 

首先每一个商品有类型,类型分为大类【Category】,中类,小类【SubCategory】,细类等,本文为了简化,只分为大类,小类两种。

 

1. 数据库设计

 

数据表结构设计如下:

大类Category表,如下所示:

[回馈]ASP.NET Core MVC开发实战之商城系统(一)

建表语句如下所示:

CREATE TABLE [dbo].[EB_Category]( 	[Id] [bigint] IDENTITY(1,1) NOT NULL, 	[Category] [varchar](100) NULL, 	[Description] [varchar](500) NULL, 	[CreateTime] [datetime] NULL, 	[CreateUser] [varchar](50) NULL, 	[LastEditTime] [datetime] NULL, 	[LastEditUser] [varchar](50) NULL ) ON [PRIMARY]

小类SubCategory表,如下所示:

[回馈]ASP.NET Core MVC开发实战之商城系统(一)

注意:数据表中的分类内容,是从某宝抄下来的,然后整理好后,导入数据库。

建表语句如下所示:

CREATE TABLE [dbo].[EB_SubCategory]( 	[Id] [bigint] IDENTITY(1,1) NOT NULL, 	[CategoryId] [bigint] NULL, 	[SubCategory] [varchar](100) NULL, 	[Description] [varchar](500) NULL, 	[CreateTime] [datetime] NULL, 	[CreateUser] [varchar](50) NULL, 	[LastEditTime] [datetime] NULL, 	[LastEditUser] [varchar](50) NULL ) ON [PRIMARY]

 

2. 项目模型创建

 

SqlSurgar采用模型对象映射ORM操作数据库,所以需要先创建模型对象。

大类Category模型对象,如下所示:

using SqlSugar;  namespace EasyBuyShop.Models {     [SugarTable("EB_Category")]     public class Category : EntityModel     {         [SugarColumn(ColumnName ="Category")]         public string CategoryName { get; set; }          public string Description { get; set; }     } }

小类SubCategory模型对象,如下所示:

using SqlSugar;  namespace EasyBuyShop.Models {     [SqlSugar.SugarTable("EB_SubCategory")]     public class SubCategory : EntityModel     {         public long CategoryId { get; set; }          [SugarColumn(ColumnName = "SubCategory")]         public string SubCategoryName { get; set; }         public string Description { get; set; }     } }

其中EntityModel为模型基类,为公共类型,如下所示:

using SqlSugar; using System.ComponentModel.DataAnnotations.Schema; using System.Security.Principal;  namespace EasyBuyShop.Models {     public class EntityModel     {         [SugarColumn(IsNullable = false, IsIdentity = true)]         [DatabaseGenerated(DatabaseGeneratedOption.Identity)]         public int Id { get; set; }         public DateTime CreateTime { get; set; }         public string CreateUser { get; set; }         public DateTime LastEditTime { get; set; }         public string LastEditUser { get; set; }     } }

 

3. 数据库操作类

 

数据库操作类位于DAL层,每一个表都有对应的DAL层,如下所示:

大类Category数据表操作DAL层,如下所示:

using EasyBuyShop.Models;  namespace EasyBuyShop.DAL {     public class CategoryDal:BaseDal     {         public CategoryDal()         {          }          public List<Category> GetCategories()         {             return this.getTList<Category>();         }     } }

小类SubCategory数据表操作DAL层,如下所示:

using EasyBuyShop.Models;  namespace EasyBuyShop.DAL {     public class SubCategoryDal : BaseDal     {         public List<SubCategory> GetSubCategories()         {             return this.getTList<SubCategory>();         }     } }

其中BaseDal为基类,数据库操作的公共方法,如下所示:

using EasyBuyShop.Utils; using SqlSugar;  namespace EasyBuyShop.DAL {     public class BaseDal     {          public static string ConnStr = string.Empty;         /// <summary>         /// 获取程序数据库操作对象         /// </summary>         /// <param name="strConn">数据库连接字符串</param>         /// <returns></returns>         public SqlSugarClient GetDb(string strConn)         {             var db = new SqlSugarClient(                 new ConnectionConfig()                 {                     ConnectionString = strConn,                     DbType = DbType.SqlServer,                     IsAutoCloseConnection = true,                     InitKeyType = InitKeyType.Attribute,                     AopEvents = new AopEvents                     {                         OnLogExecuting = (sql, p) =>                         {                             LogHelper.Info(sql);                             LogHelper.Info(string.Join(",", p?.Select(it => it.ParameterName + ":" + it.Value)));                         }                     }                 });             return db;         }            /// <summary>         /// 查询所有的用户记录         /// </summary>         /// <returns></returns>         public List<T> getTList<T>()         {             try             {                 return this.GetDb(ConnStr).Queryable<T>().ToList();             }             catch (Exception ex)             {                 LogHelper.Fatal(ex.Message);                 return null;             }         }           /// <summary>         /// 插入一条记录         /// </summary>         /// <param name="model"></param>         /// <returns></returns>         public int InsertT<T>(T model) where T : class, new()         {             try             {                 return this.GetDb(ConnStr).Insertable<T>(model).ExecuteCommand();             }             catch (Exception ex)             {                 LogHelper.Fatal(ex.Message);                 return -1;             }         }      } }

 

4. 商品类型控制器部分

 

商品类型只是首页【/Home/Index】的一小部分,首页的控制器获取到商品类型信息,然后传递到视图层即可。如下所示:

public IActionResult Index() {     CategoryDal categoryDal = new CategoryDal();     SubCategoryDal subCategoryDal = new SubCategoryDal();     var categories = categoryDal.GetCategories();     var subCategories = subCategoryDal.GetSubCategories();     ViewData["Categories"] = categories;     ViewData["SubCategories"] = subCategories;     return View(); }

 

5. 商品类型视图部分

 

商品类型视图在首页【/Home/Index.cshtml】中,如下所示:

<div mxs="x30_:_" class="left-nav" data-spm="1998549605" style="width: 280px;height: 280px;position: absolute;left: 0px;top: 0;z-index: 2;"> 	<div class="chanel-list-wrap" id="J_MAIN_CHANEL" style="background-color: #F8F8F8;border: 1px solid #eee;border-radius: 12px;font: 12px/1.5 tahoma, arial;height: 100%;"> 		@foreach(var category in ViewData["Categories"] as List<Category>) 		{ 			var id = category.Id;  			var subCategories = ViewData["SubCategories"] as List<SubCategory>;  			var subCategoriesById = subCategories.Where(r => r.CategoryId == id); 			<div class="chanel-container"> 				<div class="chanel-container-inner clearfix" style="border-radius: 12px 12px 0 0;"> 					<div class="chanel-tags-wrap"> 						<div class="chanel-title"> 							<a href="" class="atbfont" target="_blank">ↂ</a> 							<a href="" class="title" target="_blank">@category.CategoryName</a> 						</div> 						<div class="chanel-tags clearfix"> 							@foreach(var subCategory in subCategoriesById) 							{ 								<a href="/Product/Index/?CategoryId=@(id)&subCategoryId=@(subCategory.Id)" class="" target="_blank">@subCategory.SubCategoryName</a> 							} 						</div> 					</div> 				</div> 			</div> 		} 	</div> </div>

 

6. 商品类型示例

 

商品类型示例效果图,如下所示:

[回馈]ASP.NET Core MVC开发实战之商城系统(一)

 

banner条及友情链接

 

banner条主要用与广告位之类的显示,友情链接主要用于链接其他网站或者站内页面。目前banner条设计了两张静态图,友情链接参考了某宝内容,视图文件如下所示:

<div mxa="x30_:b" class="main-right clearfix"> 	<div mxa="x30_:c" class="main-right-top" style="height: 280px;position: relative;z-index: 1;font-size: 0;"> 		<div mxa="x30_:d" class="slide-container clearfix"> 			<div mxa="x30_:e" class="slide-wrap swiper swiper-container-horizontal" id="index-mainSlide"> 				<div mxa="x30_:f" class="slide-con swiper-wrapper" style="height:280px;position:relative;left:0px;display:flex"> 					<div class="con-pannel swiper-slide swiper-slide-duplicate-active" data-swiper-slide-index="1"> 						<a href="#" target="_blank"> 							<img class="swiper-lazy swiper-lazy-loaded" src="~/imgs/001.jpg" alt="[回馈]ASP.NET Core MVC开发实战之商城系统(一)" width="730" height="280" /> 						</a> 					</div> 					<div class="con-pannel swiper-slide swiper-slide-duplicate-active" data-swiper-slide-index="0"> 						<a href="#" target="_blank"> 							<img class="swiper-lazy swiper-lazy-loaded" src="~/imgs/002.jpg" alt="[回馈]ASP.NET Core MVC开发实战之商城系统(一)" width="730" height="280" /> 						</a> 					</div> 					<div class="con-pannel swiper-slide swiper-slide-duplicate-active" data-swiper-slide-index="1"> 						<a href="#" target="_blank"> 							<img class="swiper-lazy swiper-lazy-loaded" src="~/imgs/001.jpg" alt="[回馈]ASP.NET Core MVC开发实战之商城系统(一)" width="730" height="280" /> 						</a> 					</div> 					<div class="con-pannel swiper-slide swiper-slide-duplicate-active" data-swiper-slide-index="0"> 						<a href="#" target="_blank"> 							<img class="swiper-lazy swiper-lazy-loaded" src="~/imgs/002.jpg" alt="[回馈]ASP.NET Core MVC开发实战之商城系统(一)" width="730" height="280" /> 						</a> 					</div> 				</div> 			</div> 		</div> 		<div mxa="x30_:g" class="bl-right-navigation"> 			<div mxs="x30_:e" class="right-brands-title" data-spm="19985674830"> 				<a target="_blank" href="/Home/Index" style="color:#ff0036;"><i class="atbfont">✮</i>我的商城</a> 			</div> 			<ul mxa="x30_:h" class="right-brands-list clearfix"> 				<li data-spm="19985674831"> 					<a target="_blank" href="/Home/Index" style="text-decoration: none!important;"> 						<i class="atbfont" style="font-size: 22px;color:#c50a0a;">易购商城</i> 					</a> 				</li> 				<li data-spm="19985674832"> 					<a target="_blank" href=""> 						<img src="~/imgs/others/taobao.gif" alt="[回馈]ASP.NET Core MVC开发实战之商城系统(一)" width="119" height="61"> 					</a> 				</li> 				<li data-spm="19985674833"> 					<a target="_blank" href=""> 						<img src="~/imgs/others/juhuasuan.gif" alt="[回馈]ASP.NET Core MVC开发实战之商城系统(一)" width="119" height="61"> 					</a> 				</li> 				<li data-spm="19985674834"> 					<a target="_blank" href=""> 						<img src="~/imgs/others/chaojiyouxuan.png" alt="[回馈]ASP.NET Core MVC开发实战之商城系统(一)" width="119" height="61"> 					</a> 				</li> 				<li data-spm="19985674835"> 					<a target="_blank" href="" style="text-decoration: none!important;"> 						<i class="atbfont" style="font-size: 22px;color:#ff4400;">九块九</i> 					</a> 				</li> 				<li data-spm="19985674836"> 					<a target="_blank" href=""> 						<img src="~/imgs/others/tianmaoguoji.png" alt="[回馈]ASP.NET Core MVC开发实战之商城系统(一)" width="119" height="61"> 					</a> 				</li> 				<li data-spm="19985674837"> 					<a target="_blank" href=""> 						<img src="~/imgs/others/tianmaochaoshi.gif" alt="[回馈]ASP.NET Core MVC开发实战之商城系统(一)" width="119" height="61"> 					</a> 				</li> 				<li data-spm="19985674838"> 					<a target="_blank" href=""> 						<img src="~/imgs/others/ailijiankang.png" alt="[回馈]ASP.NET Core MVC开发实战之商城系统(一)" width="119" height="61"> 					</a> 				</li> 			</ul> 		</div> 	</div> </div>

以上就是ASP.NET Core MVC开发实战之商城系统(环境搭建及首页设计) 的全部内容,后续将继续介绍其他模块。