Net8

新建项目 Shop.Admin

新建 Api,Model,Interface, Service 层
数据库模型设计(角色 用户 菜单)

SqlSugar 安装

公用表

 public class IBase
 {
     /// <summary>
     /// 主键
     /// </summary>
     [SugarColumn(IsPrimaryKey = true)] 
     public string Id { get; set; }

 }
/// <summary>
/// 公用
/// </summary>
public class IEntity:IBase
{
    /// <summary>
    /// 描述
    /// </summary>
    [SugarColumn(IsNullable =true)]
    public string Description {  get; set; }

    /// <summary>
    /// 创建人ID
    /// </summary>
    [SugarColumn(IsNullable =false)]
    public string CreateUserId {  get; set; }

    /// <summary>
    /// 修改人id
    /// </summary>
    [SugarColumn(IsNullable =true)]
    public string ModifyUserId {  get; set; }

    /// <summary>
    /// 创建日期
    /// </summary>
    [SugarColumn(IsNullable = false)]
    public DateTime CreateTime { get; set; }

    /// <summary>
    /// 修改日期
    /// </summary>
    [SugarColumn(IsNullable =false)]
    public DateTime ModifyDate { get; set; }

    /// <summary>
    /// 是否删除
    /// </summary>
    [SugarColumn(IsNullable =false)]
    public bool IsDeleted { get; set; }


}

用户表设计

 /// <summary>
 /// 用户表
 /// </summary>
 public class Users:IEntity
 {
     /// <summary>
     /// 用户名
     /// </summary>
     [SugarColumn(IsNullable =false)]
     public string Name { get; set; }


     /// <summary>
     /// 昵称
     /// </summary>
     [SugarColumn(IsNullable =false)]
     public string NickName { get; set; }

     /// <summary>
     /// 密码
     /// </summary>
     [SugarColumn(IsNullable =false)]
     public string Password {  get; set; }

     /// <summary>
     /// 用户类型(0=超级管理员,1=普通用户)
     /// </summary>
     [SugarColumn(IsNullable =false)]
     public int UserType { get; set; }

     /// <summary>
     /// 是否启用(0=未启用,1=启用)
     /// </summary>
     [SugarColumn(IsNullable =false)]
     public bool IsEnable {  get; set; }

     /// <summary>
     /// 头像
     /// </summary>
     [SugarColumn(IsNullable = true)]
     public string Avatar { get; set; }

角色表设计

/// <summary>
/// 角色表
/// </summary>
public class Role:IEntity
{
    /// <summary>
    /// 名称
    /// </summary>
    [SugarColumn(IsNullable =false)]
    public string Name { get; set; }

    /// <summary>
    /// 排序
    /// </summary>
    [SugarColumn(IsNullable =false)]
    public int Order {  get; set; }

    /// <summary>
    /// 是否启用 (0=未启用,1=启用)
    /// </summary>
    [SugarColumn(IsNullable =false)]
    public bool IsEnable {  get; set; }

    //用例1:主键模式 Role(主表)表中的 和CreateUserId 和Users(子表)中的主键关联 
    [Navigate(NavigateType.OneToOne, nameof(CreateUserId))]//一对一
    public Users  UserInfo { get; set; }

菜单表设计

 /// <summary>
 /// 菜单表
 /// </summary>
 public class Menu:IEntity
 {
     /// <summary>
     /// 名称
     /// </summary>
     [SugarColumn(IsNullable =false)]
     public string Title { get; set; }

     /// <summary>
     /// 页面路径
     /// </summary>
     [SugarColumn(IsNullable =false,Length =500)]
     public string Path {  get; set; }

     /// <summary>
     /// 路由地址
     /// </summary>
     [SugarColumn(IsNullable =false)]
     public string Component {  get; set; }

     /// <summary>
     /// 父级Id
     /// </summary>
     [SugarColumn(IsNullable =false)]
     public string ParentId {  get; set; }

     /// <summary>
     /// 排序
     /// </summary>
     [SugarColumn(IsNullable =false)]
     public int Order {  get; set; }

     /// <summary>
     /// 是否启用(0=未启用,1=启用)
     /// </summary>
     [SugarColumn(IsNullable = false)]
     public bool IsEnable { get; set; }

     /// <summary>
     /// 图标
     /// </summary>
     [SugarColumn(IsNullable = false)]
     public string Icon { get; set; }

     /// <summary>
     /// 菜单类型 (0=目录,1=菜单,1=按钮)
     /// </summary>
     [SugarColumn(IsNullable = false)]
     public int menuType {  get; set; }

用户角色关系表设计

/// <summary>
/// 用户角色关系
/// </summary>
public class UserRoleRelation:IBase
{
    /// <summary>
    /// 用户主键
    /// </summary>
    [SugarColumn(IsNullable =false)]
    public string UserId {  get; set; }

    /// <summary>
    /// 角色主键
    /// </summary>
    [SugarColumn(IsNullable =false)]
    public string RoleId { get; set; }

}

菜单角色关系表设计

 /// <summary>
 /// 菜单角色关系
 /// </summary>
 public class MenuRoleRelation: IBase
 {
     /// <summary>
     /// 菜单主键
     /// </summary>
     public string MenuId {  get; set; }

     /// <summary>
     /// 角色主键
     /// </summary>
     public string RoleId {  get; set; }

 }
实体Dto 表

登录

/// <summary>
/// 用户登录
/// </summary>
public class LoginReq
{
    [Required(ErrorMessage = "自定义的错误信息1")]
    public string UserName { get; set; }
    [Required(ErrorMessage = "自定义的错误信息2")]
    public string PassWord { get; set; }
}

用户

public class UserAdd
{
    public string Name { get; set; }
    public string NickName { get; set; }
    public string Password { get; set; }
    public bool IsEnable { get; set; }
    public string Description { get; set; }
}
 public class UserEdit
 {
     public string Id { get; set; }
     public string Name { get; set; }
     public string NickName { get; set; }
     public string Password { get; set; }
     //public int UserType { get; set; }
     public bool IsEnable { get; set; }
     public string Description { get; set; }
     public string Avatar { get; set; }
 }
    public class UserReq
    {
        public string Name { get; set; }
        public string NickName { get; set; }
        public int UserType { get; set; }
        public bool IsEnable { get; set; }
        public string Description { get; set; }
        public int PageIndex { get; set; }
        public int PageSize { get; set; }
    }
public class UserRes
{
    /// <summary>
    /// 主键
    /// </summary>
    public string Id { get; set; }
    /// <summary>
    /// 用户名
    /// </summary> 
    public string Name { get; set; }
    /// <summary>
    /// 昵称
    /// </summary> 
    public string NickName { get; set; }
    /// <summary>
    /// 密码
    /// </summary>
    public string Password { get; set; }
    /// <summary>
    /// 用户类型
    /// </summary>
    public int UserType { get; set; }
    /// <summary>
    /// 角色名
    /// </summary>
    public string RoleName { get; set; }
    /// <summary>
    /// 创建人
    /// </summary> 
    public string CreateUserName { get; set; }
    /// <summary>
    /// 创建日期
    /// </summary> 
    public DateTime CreateDate { get; set; }
    /// <summary>
    /// 修改人Id
    /// </summary> 
    public string ModifyUserName { get; set; }
    /// <summary>
    /// 修改日期
    /// </summary> 
    public DateTime? ModifyDate { get; set; }
    /// <summary>
    /// 是否启用
    /// </summary>
    public bool IsEnable { get; set; }
    /// <summary>
    /// 是否删除
    /// </summary>
    public bool IsDeleted { get; set; }
    /// <summary>
    /// 描述
    /// </summary>
    public string Description { get; set; }
    /// <summary>
    /// 头像
    /// </summary>
    public string Avatar { get; set; }
}

角色

  public class RoleAdd
  {
      public string Name { get; set; }
      public int Order { get; set; }
      public bool IsEnable { get; set; }
      public string Description { get; set; }
  }
 public class RoleEdit
 {
     public string Id { get; set; }
     public string Name { get; set; }
     public int Order { get; set; }
     public bool IsEnable { get; set; }
     public string Description { get; set; }
 }
    public class RoleReq
    {
        public string Name { get; set; } 
        [DefaultValue("Hello")]
        public string Description { get; set; }
        public int PageIndex { get; set; }
        public int PageSize { get; set; }
    }
public class RoleRes
{
    public string Id { get; set; }
    /// <summary>
    /// 名称
    /// </summary> 
    public string Name { get; set; }
    /// <summary>
    /// 排序
    /// </summary> 
    public int Order { get; set; }
    /// <summary>
    /// 是否启用(0=未启用,1=启用)
    /// </summary> 
    public bool IsEnable { get; set; } 
    /// <summary>
    /// 描述
    /// </summary> 
    public string Description { get; set; }
    /// <summary>
    /// 创建人
    /// </summary> 
    public string CreateUserName { get; set; }
    /// <summary>
    /// 创建日期
    /// </summary> 
    public DateTime CreateDate { get; set; }
    /// <summary>
    /// 修改人Id
    /// </summary> 
    public string ModifyUserName { get; set; }
    /// <summary>
    /// 修改日期
    /// </summary> 
    public DateTime? ModifyDate { get; set; }
    /// <summary>
    /// 是否删除
    /// </summary> 
    public int IsDeleted { get; set; }
}

菜单

 public class MenuAdd
 {
     public string Name { get; set; }
     public string Index { get; set; }
     public string FilePath { get; set; }
     public string ParentId { get; set; }
     public int Order { get; set; }
     public bool IsEnable { get; set; }
     public string Icon { get; set; }
     public string Description { get; set; }
     public int menuType { get; set; } = 0;
 }
public class MenuEdit
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string Index { get; set; }
    public string FilePath { get; set; }
    public string ParentId { get; set; }
    public int Order { get; set; }
    public bool IsEnable { get; set; }
    public string Icon { get; set; }
    public string Description { get; set; }
    public int menuType { get; set; } 
}
 public class MenuReq
 {
     public string Name { get; set; }
     public string Index { get; set; }
     public string FilePath { get; set; } 
     public string Description { get; set; }
 }
 public class MenuRes
 {
     [SugarColumn(IsTreeKey = true)]
     public string Id { get; set; }
     public string Name { get; set; }
     public string Index { get; set; }
     public string FilePath { get; set; }
     public string ParentId { get; set; }
     public string ParentName { get; set; }
     public int Order { get; set; }
     public bool IsEnable { get; set; }
     public string Icon { get; set; }
     public string Description { get; set; }
     public DateTime CreateDate { get; set; }    
     /// <summary>
     /// 子级
     /// </summary>
     [SqlSugar.SugarColumn(IsIgnore = true)]
     public List<MenuRes> Children { get; set; }
 }

创建控制器并生成初始数据 ToolController

    /// <summary>
    /// 初始化数据库
    /// </summary>
    /// <returns></returns>
    [HttpGet]
    public async Task<bool> InitData()
    {

        //1. 创建数据库
        _db.DbMaintenance.CreateDatabase();

        //2. 通过反射,加载程序集,读取到所有的类型,然后根据实体创建表
        string nspace = "Model.Entitys";
        Type[] ass = Assembly.LoadFrom(AppContext.BaseDirectory+"Model.dll")
            .GetTypes().Where(p=>p.Namespace == nspace).ToArray();
        //3. 创建表
        _db.CodeFirst.SetStringDefaultLength(200).InitTables(ass);

        // 初始化数据
        Users user = new Users()
        {
            Id = Guid.NewGuid().ToString(),
            Name = "admin",
            NickName = "炒鸡管理员",
            Password = "123456",
            UserType = 0,
            IsEnable = true,
            Description = "数据库初始化时默认添加的炒鸡管理员",
            CreateDate = DateTime.Now,
            CreateUserId = "",
        };
        // 插入数据并返回用户ID
        string userId = (await _db.Insertable(user).ExecuteReturnEntityAsync()).Id;

        var m1 = new Menu()
        {
            Id = Guid.NewGuid().ToString(),
            Title = "系统管理",
            Component = "",
            Path = "/system",
            ParentId = "",
            Order = 1,
            IsEnable = true,
            Icon = "folder",
            MenuType = 0,
            Description = "数据库初始化时默认添加的默认菜单",
            CreateDate = DateTime.Now,
            CreateUserId = userId
        };
        string mid1 = (await _db.Insertable(m1).ExecuteReturnEntityAsync()).Id;
        // 菜单
        var m11 = new Menu()
        {
            Id = Guid.NewGuid().ToString(),
            Title = "菜单管理",
            Component = "/system/menu",
            Path = "/system/menu",
            ParentId = mid1,
            Order = 1,
            IsEnable = true,
            Icon = "notebook",
            MenuType =0,
            Description = "数据库初始化时默认添加的默认菜单",
            CreateDate = DateTime.Now,
            CreateUserId = userId
        };
        await _db.Insertable(m11).ExecuteReturnEntityAsync();
        
        // 角色
        var m2 = new Menu()
        {
            Id = Guid.NewGuid().ToString(),
            Title = "角色管理",
            Component = "/system/role",
            Path = "/system/role",
            ParentId = mid1,
            Order = 1,
            IsEnable = true,
            Icon = "folder",
            Description = "数据库初始化时默认添加的默认菜单",
            CreateDate = DateTime.Now,
            CreateUserId = userId,
            MenuType = 0,
        };
        await _db.Insertable(m2).ExecuteReturnEntityAsync();

        // 用户
        var m3 = new Menu()
        {
            Id = Guid.NewGuid().ToString(),
            Title = "用户管理",
            Component = "/system/userr",
            Path = "/system/user",
            ParentId = mid1,
            Order = 1,
            IsEnable = true,
            Icon = "notebook",
            Description = "数据库初始化时默认添加的默认菜单",
            CreateDate = DateTime.Now,
            CreateUserId = userId,
            MenuType = 0,
        };
        return await _db.Insertable(m3).ExecuteCommandIdentityIntoEntityAsync();

    }


}
Autofac 安装

Autofac 批量注册
autofac 安装
autofac.DependencyInjection 安装

API项目中新建 Config 文件夹并创建AutofacModuleRegister类

/// <summary>
/// 批量注册依赖注入模块
/// </summary>
public class AutofacModuleRegister:Autofac.Module
{

    protected override void Load(ContainerBuilder builder)
    {
        Assembly InterfaceAssembly = Assembly.Load("Interface");
        Assembly ServicesAssembly = Assembly.Load("Services");
builder.RegisterAssemblyTypes(InterfaceAssembly, ServicesAssembly).AsImplementedInterfaces();
    }
}
备注: 项目引用  Model,Interface, Service 层

Program.cs 注册 AutofacModuleRegister 类

// 替换内置IOC容器为Autofac
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
builder.Host.ConfigureContainer<ContainerBuilder>(builder =>
{
    builder.RegisterModule (new AutofacModuleRegister());
});
AutoMapper 安装

作用: Dto 与实体之间的映射,代替手动赋值

API项目中新建 Config 文件夹并创建AutoMapperConfigs类

   /// <summary>
   /// Dto 映射关系
   /// </summary>
   public class AutoMapperConfigs:Profile
   {
       
       public AutoMapperConfigs() 
       {
           // 角色
           CreateMap<RoleAdd, Role>();
           CreateMap<RoleEdit, Role>();
           // 用户
           CreateMap<UserAdd, Users>();
           CreateMap<UserEdit, Users>();
           // 菜单
           CreateMap<MenuAdd, Menu>();
           CreateMap<MenuEdit, Menu>();
       }
   }

// Program.cs 注册  Automapper 映射
builder.Services.AddAutoMapper(typeof(AutoMapperConfigs));
创建接口层和服务层
 /// <summary>
 /// 接口层
 /// </summary>
 public interface IUserService
 {
     /// <summary>
     /// 获取用户信息
     /// </summary>
     /// <param name="req"></param>
     /// <returns></returns>
     Task<UserRes> GetUser(LoginReq req);

 }
/// <summary>
/// 实现层
/// </summary>
public class UserService : IUserService
{
    private ISqlSugarClient _db { get; set; }

    public UserService(ISqlSugarClient db) 
    { 
        _db = db;
    }

    /// <summary>
    /// /获取用户
    /// </summary>
    /// <param name="req"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public async Task<UserRes> GetUser(LoginReq req)
    {
        var user = await _db.Queryable<Users>().Where(n=>n.Name == req.UserName  &&  n.Password == req.PassWord)
            // 属性手动赋值
            // automapper 
            // 通过sqlsugar 自带的功能实现  true- 把Users 自动映射到UserRes
            .Select(p=> new UserRes() { },true).FirstAsync();
        return user;
    }

}

JWT token

Microsoft.AspNetCore.Authentication.JwtBearer Service 安装

/// <summary>
/// jwt token
/// </summary>
public interface ICustomJWTService
{

    /// <summary>
    /// 获取Tokne
    /// </summary>
    /// <param name="user"></param>
    /// <returns></returns>
    Task<string> GetToken(UserRes user);


}
/// <summary>
/// jwt token 实现层
/// </summary>
public class CustomJWTService : ICustomJWTService
{
    // 来自 appsettings.json 配置文件
    private readonly JWTTokenOptions _jWTToken;

    public CustomJWTService(IOptionsMonitor<JWTTokenOptions> jWTToken)
    {
        _jWTToken = jWTToken.CurrentValue;
    }

    public async Task<string> GetToken(UserRes user)
    {
        var result =await  Task.Run(() => {

            var claims = new[]
            {
                new Claim("Id",user.Id),
                new Claim("NickName",user.NickName),
                new Claim("Name",user.Name),
                new Claim("UserType",user.UserType.ToString()),
                new Claim("Avatar",user.Avatar==null?"":user.Avatar)
            };

            //需要加密:需要加密key:
            //Nuget引入:Microsoft.IdentityModel.Tokens
            SymmetricSecurityKey key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jWTToken.SecurityKey));

            SigningCredentials creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

            //Nuget引入:System.IdentityModel.Tokens.Jwt
            JwtSecurityToken token = new JwtSecurityToken(
             issuer: _jWTToken.Issuer,
             audience: _jWTToken.Audience,
             claims: claims,
             expires: DateTime.Now.AddMinutes(10),//10分钟有效期 
             notBefore: null,
             signingCredentials: creds);

            string res = new JwtSecurityTokenHandler().WriteToken(token);
            return res;

        });
        return result;
    }
}
    /// <summary>
    /// 获取 Token
    /// </summary>
    /// <param name="req"></param>
    /// <returns></returns>
    [HttpPost("GetToken")]
    public async Task<ApiResult> GetToken([FromBody] LoginReq req)
    {
        // 通过模型验证
        if (ModelState.IsValid)
        {
            UserRes user = await _userService.GetUser(req);
            if (user == null)
            {
                return ResultHelper.Error("账号不存在,用户名或密码错误!");
            }
            _logger.LogInformation("登录");
            return ResultHelper.Success(await _jwtService.GetToken(user));
        }
        else
        {
            return ResultHelper.Error("参数错误!");
        }

    }

}

设置JSON返回的日期格式

安装 Microsoft.AspNetCore.Mvc.NewtonsoftJson
Program.cs 配置

// 设置JSON返回的日期格式

builder.Services.AddControllers().AddNewtonsoftJson(options =>
{
    // 忽略循环引用
    options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
    // 统一设置API的日期格式
    options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
    // 设置JSON返回格式同model一致(默认JSON里的首字母为小写,这里改为同后端Mode一致)
    options.SerializerSettings.ContractResolver = new DefaultContractResolver();
});
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,588评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,456评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,146评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,387评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,481评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,510评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,522评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,296评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,745评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,039评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,202评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,901评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,538评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,165评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,415评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,081评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,085评论 2 352

推荐阅读更多精彩内容