From a3ec20975b1dabc18cba75e026649b1b8e912188 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BE=AF=E5=9D=A4=E9=A1=BA?= <3077265015@qq.com> Date: Mon, 1 Jul 2024 17:26:08 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E6=A8=A1=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...23\350\256\276\350\256\241\357\274\211.md" | 118 ++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 "\344\276\257\345\235\244\351\241\272/20240701-\347\256\241\347\220\206\351\241\271\347\233\256\346\250\241\346\235\277\357\274\210RBAC\345\256\236\344\275\223\350\256\276\350\256\241\357\274\211.md" diff --git "a/\344\276\257\345\235\244\351\241\272/20240701-\347\256\241\347\220\206\351\241\271\347\233\256\346\250\241\346\235\277\357\274\210RBAC\345\256\236\344\275\223\350\256\276\350\256\241\357\274\211.md" "b/\344\276\257\345\235\244\351\241\272/20240701-\347\256\241\347\220\206\351\241\271\347\233\256\346\250\241\346\235\277\357\274\210RBAC\345\256\236\344\275\223\350\256\276\350\256\241\357\274\211.md" new file mode 100644 index 0000000..2b26ce5 --- /dev/null +++ "b/\344\276\257\345\235\244\351\241\272/20240701-\347\256\241\347\220\206\351\241\271\347\233\256\346\250\241\346\235\277\357\274\210RBAC\345\256\236\344\275\223\350\256\276\350\256\241\357\274\211.md" @@ -0,0 +1,118 @@ +## 项目构建及说明 + +### *.Api 向外提供接口服务的层 + - dotnet new webapi -n Admin2024.Api + +### *.Application 应用层/服务层 + - dotnet new classlib -n Admin2024.Application +领域层金额应用层不知道项目中使用的ORM和Database Provider。只依赖于仓储接口 + - dotnet new classlib -n Admin2024.Application.Contracts + +### *.Application.Shared 定义应用接口及Dto + - dotnet new classlib -n Admin2024.Application.Shared + +### *.Domain 领域层 核心层 + - dotnet new classlib -n Admin2024.Domain + +### *.EntityFrameworkCore ORM工具之一 + - dotnet new classlib -n Admin2024.EntityFrameworkCore + +### *.Infrastructure 基础设施层 + - dotnet new classlib -n Admin2024.Infrastructure + +## 解决方案 + - dotnet new sln -n Admin2024 +### 将项目添加到解决方案 + - dotnet sln add .\Admin2024.Api\ .\Admin2024.Application\ + +## RBAC实体设计 +``` + + +namespace Admin2024.Domain.Entity; + +public abstract class BaseEntity +{ + public Guid Id { get; set; }//主键id + public bool IsActived { get; set; }//是否启用/激活 + public bool IsDeleted { get; set; }//是否删除 + public DateTime CreatedAt { get; set; }//创建时间 + public Guid CreatedBy { get; set; }//创建人 + public DateTime UpdatedAt { get; set; }//最后更新时间 + public Guid UpdatedBy { get; set; }//最后更新人 + public int DisplayOrder { get; set; }//显示顺序,数字越大越靠前 + public string? Remarks { get; set; }//备注 +} +``` + +``` +namespace Admin2024.Domain.Entity.System; + +public class AppUser : BaseEntity +{ + public string UserName { get; set;}=null!; //用户名 + public string Password { get; set;}=null!; //密码 + public string Salt { get; set;}=null!; //盐//随机加密字符串 + public string Nickname { get; set;}=null!; //昵称 + + public string Auatar { get; set;}=null!; //头像 + public string Telephone { get; set;}=null!; //手机号 + public string Weixin { get; set;}=null!; //微信号 + public string QQ { get; set;}=null!; //QQ号 +} + +``` +``` +namespace Admin2024.Domain.Entity.System; + +public class AppRole : BaseEntity +{ + public string RoleName { get; set;}=null!; + public string? Descript{ get; set;} + +} +``` +``` +namespace Admin2024.Domain.Entity.System; + +public class AppPermission : BaseEntity +{ + public Guid AppResourceId { get; set;} + public Guid AppOperationId { get; set;} + //public virtual AppResource? AppResource{ get; set;} + // public virtual AppResource? AppOperation{ get; set;} + +} +``` +``` +namespace Admin2024.Domain.Entity.System; + +public class AppOperation : BaseEntity +{ + //操作名称,比如有读取(查找、过滤)、新增、修改、导入、导出、打印、放大、最大化 + public string OperationName { get; set;}=null!; + public Guid ? Descript { get; set;} + +} +``` +``` +namespace Admin2024.Domain.Entity.System; + +public class AppResource : BaseEntity +{ + public string ResourceName { get; set;}=null!; + public string Url { get; set;}=null!; + +} + +``` + +``` +namespace Admin2024.Domain.Entity.System; + +public class AppUserRole : BaseEntity +{ + public Guid AppUserId { get; set; } + public Guid AppRoleId { get; set;} +} +``` \ No newline at end of file -- Gitee From a5b5c9a571da2024d726801bbe83495f89de2c86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BE=AF=E5=9D=A4=E9=A1=BA?= <3077265015@qq.com> Date: Tue, 2 Jul 2024 16:18:19 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E5=AE=9E=E4=BD=93=E3=80=81=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...23\345\202\250\346\216\245\345\217\243.md" | 115 ++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 "\344\276\257\345\235\244\351\241\272/20240702-\345\241\253\345\205\205\351\203\250\345\210\206\345\256\236\344\275\223\350\241\214\344\270\272\343\200\201\351\200\232\347\224\250\344\273\223\345\202\250\346\216\245\345\217\243.md" diff --git "a/\344\276\257\345\235\244\351\241\272/20240702-\345\241\253\345\205\205\351\203\250\345\210\206\345\256\236\344\275\223\350\241\214\344\270\272\343\200\201\351\200\232\347\224\250\344\273\223\345\202\250\346\216\245\345\217\243.md" "b/\344\276\257\345\235\244\351\241\272/20240702-\345\241\253\345\205\205\351\203\250\345\210\206\345\256\236\344\275\223\350\241\214\344\270\272\343\200\201\351\200\232\347\224\250\344\273\223\345\202\250\346\216\245\345\217\243.md" new file mode 100644 index 0000000..3694e84 --- /dev/null +++ "b/\344\276\257\345\235\244\351\241\272/20240702-\345\241\253\345\205\205\351\203\250\345\210\206\345\256\236\344\275\223\350\241\214\344\270\272\343\200\201\351\200\232\347\224\250\344\273\223\345\202\250\346\216\245\345\217\243.md" @@ -0,0 +1,115 @@ +### 填充部分领域的实体行为 +``` +public class AppUser : BaseEntity +{ + private List _appRoles=new List(); + ······ + public void SetPassword(string password) + { + this.Password = password; + } + public void AllocateRole(AppRole appRole) + { + _appRoles.Add(appRole);//分配了角色 + } + public void RemoveRole(AppRole appRole) + { + _appRoles.Remove(appRole); + } + //移除 + public void RemoveRole(string roleName) + { + var role=_appRoles.FirstOrDefault(x => x.RoleName==roleName); + if (role!=null) + { + _appRoles.Remove(role); + } + } + //权限 + public bool HasPermssion() + { + return true; + } +} + +``` + +``` +public class AppRole : BaseEntity +{ + private List _appPermission=new List(); + public string RoleName { get; set;}=null!; + public string? Description{ get; set;} + + //一般用于ORM工具初始化对象 + public AppRole() + { + + } + public AppRole(string roleName,string description) + { + RoleName=roleName; + Description=description; + } + //角色 + + //分配权限 + public void AllocatePermission(AppPermission appPermission) + { + _appPermission.Add(appPermission); + } + + //移除权限 + public void RemovePermission(AppPermission appPermission) + { + _appPermission.Remove(appPermission) ; + } + + //判断有无权限 + public bool HasPermssion(AppResource appResource,AppOperation appOperation) + { + return _appPermission.Any(x => x.AppResourceId == appResource.Id + && x.AppOperationId == appOperation.Id); + } + //判断有没有权限 + public bool HasPermssion(Guid resourceId,Guid operationId) + { + return _appPermission.Any(x => x.AppResourceId == resourceId + && x.AppOperationId == operationId); + } + +} +``` +``` +namespace Admin2024.Domain.Entity.System; + + +//权限 +public class AppRolePermission : BaseEntity +{ + public Guid AppRoleId { get; set;} + public Guid AppPermissionId { get; set;} +} +``` + + + +### 完成通用仓储接口 + +``` +using Admin2024.Domain.Entity; +namespace Admin2024.Domain.Interface; + +public interface IRepository where T : BaseEntity +{ + //根据id获取实体 + Task GetByIdAsync(Guid id); + //获取实体列表 + Task> GetListAsync(); + Task CreateAsync(T entity); + Task UpdateAsync(Guid id, T entity); + Task DeleteAsync(Guid id); + + +} +``` \ No newline at end of file -- Gitee From 7f3f98c242ebc34afd294e37ab4d04677fd22c1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BE=AF=E5=9D=A4=E9=A1=BA?= <3077265015@qq.com> Date: Wed, 3 Jul 2024 15:33:01 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=BA=93=E4=B8=8A?= =?UTF-8?q?=E4=B8=8B=E6=96=87=E3=80=81=E6=B3=A8=E5=86=8C=E5=88=B0=E5=AE=B9?= =?UTF-8?q?=E5=99=A8=E3=80=81=E7=94=9F=E6=88=90=E8=BF=81=E7=A7=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...37\346\210\220\350\277\201\347\247\273.md" | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 "\344\276\257\345\235\244\351\241\272/20240703-\346\225\260\346\215\256\345\272\223\344\270\212\344\270\213\346\226\207\343\200\201\346\263\250\345\206\214\345\210\260\345\256\271\345\231\250\343\200\201\347\224\237\346\210\220\350\277\201\347\247\273.md" diff --git "a/\344\276\257\345\235\244\351\241\272/20240703-\346\225\260\346\215\256\345\272\223\344\270\212\344\270\213\346\226\207\343\200\201\346\263\250\345\206\214\345\210\260\345\256\271\345\231\250\343\200\201\347\224\237\346\210\220\350\277\201\347\247\273.md" "b/\344\276\257\345\235\244\351\241\272/20240703-\346\225\260\346\215\256\345\272\223\344\270\212\344\270\213\346\226\207\343\200\201\346\263\250\345\206\214\345\210\260\345\256\271\345\231\250\343\200\201\347\224\237\346\210\220\350\277\201\347\247\273.md" new file mode 100644 index 0000000..b7f8a1a --- /dev/null +++ "b/\344\276\257\345\235\244\351\241\272/20240703-\346\225\260\346\215\256\345\272\223\344\270\212\344\270\213\346\226\207\343\200\201\346\263\250\345\206\214\345\210\260\345\256\271\345\231\250\343\200\201\347\224\237\346\210\220\350\277\201\347\247\273.md" @@ -0,0 +1,90 @@ +### 数据库上下文 + - 安装工具包 + - dotnet add package Microsoft.EntityFrameworkCore + - dotnet add package Npgsql.EntityFrameworkCore.PostgreSQL数据库驱动包 + - dotnet restore 还原驱动包 + - dotnet add reference ..\ 将文件引入 + - 编写数据库上下文 +``` +using Microsoft.EntityFrameworkCore; +using Admin2024.Domain; +using Admin2024.Domain.Entity.System; +namespace Admin2024.EntityFrameworkCore; + +public class Admin2024DbContext : DbContext +{ + public Admin2024DbContext(DbContextOptionsoptions): base(options) + { + + } + public DbSet AppUsers { get; set; } + public DbSet AppRole { get; set; } + public DbSet AppUserRole { get; set; } + public DbSet AppPermission { get; set; } + public DbSet AppResource { get; set; } + public DbSet AppRolePermission { get; set; } + public DbSet AppOperation { get; set; } +} +``` + - 数据库语句 + +``` + "AllowedHosts": "*", + "ConnectionStrings": { + "pg":"server=域名;database=admin_数据库名称demo;uid=pastgres;pwd:" + } +``` + - 注册数据库上下文到容器 +``` +namespace Admin2024.Api; + +public class Program +{ + public static void Main(string[] args) + { + CreateBuilder(args).Build().Run(); + } + private static IHostBuilder CreateBuilder(string[] args) + { + return Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder=> + { + webBuilder.UseStartup(); + }); + } +} + +``` +``` +using Admin2024.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; +namespace Admin2024.Api; + +public class Startup +{ + private readonly IConfiguration _configuration; + public Startup(IConfiguration configuration) + { + _configuration = configuration; + } + public void Configuration(IApplicationBuilder app) + { + app.UseRouting(); + app.UseEndpoints(endpoints => + { + endpoints.MapControllers(); + }); + } + public void ConfigureServices(IServiceCollection services) + { + services.AddControllers(); + services.AddDbContext(opt=> + { + opt.UseNpgsql(_configuration.GetConnectionString("pg")); + }); + } +} +``` + - 迁移 + - dotnet ef migrations add Init_Rbac -p .\Admin2024.EntityFrameworkCore -s .\Admin2024.Api + - 更新到数据库 + - dotnet ef database update -p .\Admin2024.EntityFrameworkCore -s .\Admin2024.Api \ No newline at end of file -- Gitee From dae23b1d388f74fbc13dce39dc7db1de1efe2ab1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BE=AF=E5=9D=A4=E9=A1=BA?= <3077265015@qq.com> Date: Sun, 7 Jul 2024 19:07:42 +0800 Subject: [PATCH 4/4] tj --- ...to\343\200\201\345\256\236\347\216\260.md" | 52 +++++++++++++++++++ ...15\347\275\256\346\250\241\345\236\213.md" | 28 ++++++++++ 2 files changed, 80 insertions(+) create mode 100644 "\344\276\257\345\235\244\351\241\272/20240704-\347\224\250\346\210\267\345\256\236\344\275\223\343\200\201\346\234\215\345\212\241\345\261\202\346\216\245\345\217\243\345\217\212Dto\343\200\201\345\256\236\347\216\260.md" create mode 100644 "\344\276\257\345\235\244\351\241\272/20240705-\345\210\233\345\273\272\345\271\266\351\205\215\347\275\256\346\250\241\345\236\213.md" diff --git "a/\344\276\257\345\235\244\351\241\272/20240704-\347\224\250\346\210\267\345\256\236\344\275\223\343\200\201\346\234\215\345\212\241\345\261\202\346\216\245\345\217\243\345\217\212Dto\343\200\201\345\256\236\347\216\260.md" "b/\344\276\257\345\235\244\351\241\272/20240704-\347\224\250\346\210\267\345\256\236\344\275\223\343\200\201\346\234\215\345\212\241\345\261\202\346\216\245\345\217\243\345\217\212Dto\343\200\201\345\256\236\347\216\260.md" new file mode 100644 index 0000000..ff3c904 --- /dev/null +++ "b/\344\276\257\345\235\244\351\241\272/20240704-\347\224\250\346\210\267\345\256\236\344\275\223\343\200\201\346\234\215\345\212\241\345\261\202\346\216\245\345\217\243\345\217\212Dto\343\200\201\345\256\236\347\216\260.md" @@ -0,0 +1,52 @@ +``` +namespace Admin2024.Application.Contracts.AppUser; + +public interface IAppUserAppService +{ + Task Registry(CreateAppUserDto createAppUserDto); + + void Login(string username, string password); + + void Logout(string token); + + void DisableUser(); + + void Delete(); + + void Update(UpdateAppUserDto updateAppUserDto); + + void ModifyPassword(string password); + + void AllocateRoleToUser(); + + +} +``` +``` +namespace Admin2024.Application.Contracts.AppUser; + +public class AppUserDto +{ + public Guid Id{get;set;} + public string Username{get;set;}=null!; + public string Password{get;set;}=null!; +} +``` +``` +namespace Admin2024.Application.Contracts.AppUser; + +public class CreateAppUserDto +{ + public string Username { get; set; } = null!; + public string Password { get; set; } = null!; + public string ConfirmPassword { get; set; } = null!; +} +``` +``` +namespace Admin2024.Application.Contracts.AppUser; + +public class UpdateAppUserDto +{ + +} +``` \ No newline at end of file diff --git "a/\344\276\257\345\235\244\351\241\272/20240705-\345\210\233\345\273\272\345\271\266\351\205\215\347\275\256\346\250\241\345\236\213.md" "b/\344\276\257\345\235\244\351\241\272/20240705-\345\210\233\345\273\272\345\271\266\351\205\215\347\275\256\346\250\241\345\236\213.md" new file mode 100644 index 0000000..bb1f886 --- /dev/null +++ "b/\344\276\257\345\235\244\351\241\272/20240705-\345\210\233\345\273\272\345\271\266\351\205\215\347\275\256\346\250\241\345\236\213.md" @@ -0,0 +1,28 @@ +### 创建并配置模型 +- EF Core 使用元数据模型来描述如何将应用程序的实体类型映射到基础数据库。 +- 此模型是使用一组约定构建的,这些约定是寻找常见模式的启发式方法。 然后,可以使用映射特性(也称为数据注释)自定义模型 +- 在 OnModelCreating 中调用 ModelBuilder 方法(也称为 Fluent API),这两者都将替代约定执行的配置。 + +- 大多数配置可以应用于面向任何数据存储的模型。 +- 提供程序还可以启用特定于特定数据存储的配置,也可以忽略不支持或不适用的配置。 +- 有关提供程序特定配置的文档,请参阅数据库提供程序部分。 + +### fluent API 配置模型 +- 可在派生上下文中替代 OnModelCreating 方法,并使用 Fluent API 来配置模型 + +### 分组配置 +- 为了减小 OnModelCreating 方法的大小,可以将实体类型的所有配置提取到实现 IEntityTypeConfiguration 的单独类中。 + + +### 生成id的几种方式 +- UUID (无序,基本可以认为不会重复,有根据mac地址生成(这种会暴露隐私)、时间、或者名称生成) +- 数据库自增主键(分表的情况下会有问题,无法保证唯一性) +- redis的INCR和INCEBY(实际项目中没见过这样做的) +- 雪花算法生成id(有序,不需要依赖中间件,但是因为有序可能会暴露隐私,导致安全问题;依赖时间戳,若时间快了重新校准,有时钟回拨问题) +2. 雪花算法 +### 雪花算法介绍 +- 雪花算法的原理就是生成一个的 64 位比特位的 long 类型的唯一 id。 +- 1:最高 1 位是符号位,固定值 0,表示id 是正整数 +- 41:接下来 41 位存储毫秒级时间戳,2^41/(1000606024365)=69,大概可以使用 69 年。 +- 10:再接下 10 位存储机器码,包括 5 位 datacenterId 和 5 位 workerId。最多可以部署 2^10=1024 台机器。 +- 12:最后 12 位存储序列号。同一毫秒时间戳时,通过这个递增的序列号来区分。即对于同一台机器而言,同一毫秒时间戳下,可以生成 2^12=4096 个不重复 id。 \ No newline at end of file -- Gitee