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

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

-
Session服务,由于到进行用户身份验证,所以需要用到Session。 -
鉴权/授权组件,主要用于什么验证及权限管理。 -
日志组件,记录程序执行过程的日志,便于问题分析和解决。 -
路由组件注入。
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 injectionbuilder.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();
{"ConnectionStrings": {"Default": "Server=localhost;Database=EasyBuyShop;Trusted_Connection=True;User Id=sa;Password=abc123"},"Logging": {"LogLevel": {"Default": "Information","Microsoft.AspNetCore": "Warning"}},"AllowedHosts": "*"}
<?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="\Logs\internal-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}\Logs\nlog-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}\Logs\nlog-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>
页面布局
<!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>


商品类型功能

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]

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]
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; }}}
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; }}}
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; }}}
using EasyBuyShop.Models;namespace EasyBuyShop.DAL{public class CategoryDal:BaseDal{public CategoryDal(){}public List<Category> GetCategories(){return this.getTList<Category>();}}}
using EasyBuyShop.Models;namespace EasyBuyShop.DAL{public class SubCategoryDal : BaseDal{public List<SubCategory> GetSubCategories(){return this.getTList<SubCategory>();}}}
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;}}}}
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();}
<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>

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" 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" 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" 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" 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" width="119" height="61"></a></li><li data-spm="19985674833"><a target="_blank" href=""><img src="~/imgs/others/juhuasuan.gif" width="119" height="61"></a></li><li data-spm="19985674834"><a target="_blank" href=""><img src="~/imgs/others/chaojiyouxuan.png" 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" width="119" height="61"></a></li><li data-spm="19985674837"><a target="_blank" href=""><img src="~/imgs/others/tianmaochaoshi.gif" width="119" height="61"></a></li><li data-spm="19985674838"><a target="_blank" href=""><img src="~/imgs/others/ailijiankang.png" width="119" height="61"></a></li></ul></div></div></div>
