完善登录

This commit is contained in:
陈淳
2023-01-31 18:08:27 +08:00
parent b7260ed982
commit 5fb09c1c4a
77 changed files with 2333 additions and 288 deletions

View File

@@ -4,6 +4,387 @@
<name>Yi.RBAC.Domain</name>
</assembly>
<members>
<member name="T:Yi.RBAC.Domain.Identity.AccountManager">
<summary>
用户领域服务
</summary>
</member>
<member name="M:Yi.RBAC.Domain.Identity.AccountManager.LoginValidationAsync(System.String,System.String,System.Action{Yi.RBAC.Domain.Identity.Entities.UserEntity})">
<summary>
登录效验
</summary>
<param name="userName"></param>
<param name="password"></param>
<param name="userAction"></param>
<returns></returns>
</member>
<member name="M:Yi.RBAC.Domain.Identity.AccountManager.ExistAsync(System.String,System.Action{Yi.RBAC.Domain.Identity.Entities.UserEntity})">
<summary>
判断账户合法存在
</summary>
<param name="userName"></param>
<param name="userAction"></param>
<returns></returns>
</member>
<member name="M:Yi.RBAC.Domain.Identity.AccountManager.UserInfoToClaim(Yi.RBAC.Domain.Identity.Dtos.UserRoleMenuDto)">
<summary>
令牌转换
</summary>
<param name="dto"></param>
<returns></returns>
</member>
<member name="T:Yi.RBAC.Domain.Identity.Entities.DeptEntity">
<summary>
部门表
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.DeptEntity.Id">
<summary>
主键
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.DeptEntity.IsDeleted">
<summary>
逻辑删除
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.DeptEntity.CreationTime">
<summary>
创建时间
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.DeptEntity.CreatorId">
<summary>
创建者
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.DeptEntity.LastModifierId">
<summary>
最后修改者
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.DeptEntity.LastModificationTime">
<summary>
最后修改时间
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.DeptEntity.OrderNum">
<summary>
排序
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.DeptEntity.State">
<summary>
状态
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.DeptEntity.DeptName">
<summary>
部门名称
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.DeptEntity.DeptCode">
<summary>
部门编码
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.DeptEntity.Leader">
<summary>
负责人
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.DeptEntity.ParentId">
<summary>
父级id
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.DeptEntity.Remark">
<summary>
描述
</summary>
</member>
<member name="T:Yi.RBAC.Domain.Identity.Entities.MenuEntity">
<summary>
菜单表
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.MenuEntity.Id">
<summary>
主键
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.MenuEntity.IsDeleted">
<summary>
逻辑删除
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.MenuEntity.CreationTime">
<summary>
创建时间
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.MenuEntity.CreatorId">
<summary>
创建者
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.MenuEntity.LastModifierId">
<summary>
最后修改者
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.MenuEntity.LastModificationTime">
<summary>
最后修改时间
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.MenuEntity.OrderNum">
<summary>
排序
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.MenuEntity.State">
<summary>
状态
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.MenuEntity.MenuName">
<summary>
菜单名
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.MenuEntity.MenuType">
<summary>
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.MenuEntity.PermissionCode">
<summary>
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.MenuEntity.ParentId">
<summary>
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.MenuEntity.MenuIcon">
<summary>
菜单图标
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.MenuEntity.Router">
<summary>
菜单组件路由
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.MenuEntity.IsLink">
<summary>
是否为外部链接
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.MenuEntity.IsCache">
<summary>
是否缓存
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.MenuEntity.IsShow">
<summary>
是否显示
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.MenuEntity.Remark">
<summary>
描述
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.MenuEntity.Component">
<summary>
组件路径
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.MenuEntity.Query">
<summary>
路由参数
</summary>
</member>
<member name="T:Yi.RBAC.Domain.Identity.Entities.MenuEntityExtensions">
<summary>
实体扩展
</summary>
</member>
<member name="M:Yi.RBAC.Domain.Identity.Entities.MenuEntityExtensions.Vue3RouterBuild(System.Collections.Generic.List{Yi.RBAC.Domain.Identity.Entities.MenuEntity})">
<summary>
构建vue3路由
</summary>
<param name="menus"></param>
<returns></returns>
</member>
<member name="T:Yi.RBAC.Domain.Identity.Entities.PostEntity">
<summary>
岗位表
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.PostEntity.Id">
<summary>
主键
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.PostEntity.IsDeleted">
<summary>
逻辑删除
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.PostEntity.CreationTime">
<summary>
创建时间
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.PostEntity.CreatorId">
<summary>
创建者
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.PostEntity.LastModifierId">
<summary>
最后修改者
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.PostEntity.LastModificationTime">
<summary>
最后修改时间
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.PostEntity.OrderNum">
<summary>
排序
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.PostEntity.State">
<summary>
状态
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.PostEntity.PostCode">
<summary>
岗位编码
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.PostEntity.PostName">
<summary>
岗位名称
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.PostEntity.Remark">
<summary>
描述
</summary>
</member>
<member name="T:Yi.RBAC.Domain.Identity.Entities.RoleDeptEntity">
<summary>
角色部门关系表
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.RoleDeptEntity.Id">
<summary>
主键
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.RoleDeptEntity.RoleId">
<summary>
角色id
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.RoleDeptEntity.DeptId">
<summary>
部门id
</summary>
</member>
<member name="T:Yi.RBAC.Domain.Identity.Entities.RoleEntity">
<summary>
角色表
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.RoleEntity.Id">
<summary>
主键
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.RoleEntity.IsDeleted">
<summary>
逻辑删除
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.RoleEntity.CreationTime">
<summary>
创建时间
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.RoleEntity.CreatorId">
<summary>
创建者
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.RoleEntity.LastModifierId">
<summary>
最后修改者
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.RoleEntity.LastModificationTime">
<summary>
最后修改时间
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.RoleEntity.OrderNum">
<summary>
排序
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.RoleEntity.RoleName">
<summary>
角色名
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.RoleEntity.RoleCode">
<summary>
角色编码
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.RoleEntity.Remark">
<summary>
描述
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.RoleEntity.DataScope">
<summary>
角色数据范围
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.RoleEntity.State">
<summary>
状态
</summary>
</member>
<member name="T:Yi.RBAC.Domain.Identity.Entities.RoleMenuEntity">
<summary>
角色菜单关系表
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.RoleMenuEntity.Id">
<summary>
主键
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.RoleMenuEntity.RoleId">
<summary>
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.RoleMenuEntity.MenuId">
<summary>
</summary>
</member>
<member name="T:Yi.RBAC.Domain.Identity.Entities.UserEntity">
<summary>
用户表
@@ -119,6 +500,78 @@
排序
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.UserEntity.State">
<summary>
状态
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.UserEntity.Roles">
<summary>
角色
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.UserEntity.Posts">
<summary>
岗位
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.UserEntity.Dept">
<summary>
部门
</summary>
</member>
<member name="M:Yi.RBAC.Domain.Identity.Entities.UserEntity.BuildPassword(System.String)">
<summary>
构建密码MD5盐值加密
</summary>
</member>
<member name="M:Yi.RBAC.Domain.Identity.Entities.UserEntity.JudgePassword(System.String)">
<summary>
判断密码和加密后的密码是否相同
</summary>
<param name="password"></param>
<returns></returns>
</member>
<member name="T:Yi.RBAC.Domain.Identity.Entities.UserPostEntity">
<summary>
用户岗位表
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.UserPostEntity.Id">
<summary>
主键
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.UserPostEntity.UserId">
<summary>
用户id
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.UserPostEntity.PostId">
<summary>
岗位id
</summary>
</member>
<member name="T:Yi.RBAC.Domain.Identity.Entities.UserRoleEntity">
<summary>
用户角色关系表
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.UserRoleEntity.Id">
<summary>
主键
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.UserRoleEntity.RoleId">
<summary>
角色id
</summary>
</member>
<member name="P:Yi.RBAC.Domain.Identity.Entities.UserRoleEntity.UserId">
<summary>
用户id
</summary>
</member>
<member name="M:Yi.RBAC.Domain.Identity.Repositories.IUserRepository.GetUserAllInfoAsync(System.Int64)">
<summary>
获取当前登录用户的所有信息
@@ -126,26 +579,20 @@
<param name="userId"></param>
<returns></returns>
</member>
<member name="T:Yi.RBAC.Domain.Identity.UserManager">
<member name="M:Yi.RBAC.Domain.Identity.UserManager.GiveUserSetRoleAsync(System.Collections.Generic.List{System.Int64},System.Collections.Generic.List{System.Int64})">
<summary>
用户领域服务
用户设置角色
</summary>
</member>
<member name="M:Yi.RBAC.Domain.Identity.UserManager.LoginValidationAsync(System.String,System.String,System.Action{Yi.RBAC.Domain.Identity.Entities.UserEntity})">
<summary>
登录效验
</summary>
<param name="userName"></param>
<param name="password"></param>
<param name="userAction"></param>
<param name="userIds"></param>
<param name="roleIds"></param>
<returns></returns>
</member>
<member name="M:Yi.RBAC.Domain.Identity.UserManager.ExistAsync(System.String,System.Action{Yi.RBAC.Domain.Identity.Entities.UserEntity})">
<member name="M:Yi.RBAC.Domain.Identity.UserManager.GiveUserSetPostAsync(System.Collections.Generic.List{System.Int64},System.Collections.Generic.List{System.Int64})">
<summary>
判断账户合法存在
给用户设置岗位
</summary>
<param name="userName"></param>
<param name="userAction"></param>
<param name="userIds"></param>
<param name="postIds"></param>
<returns></returns>
</member>
</members>

View File

@@ -0,0 +1,108 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Core.CurrentUsers;
using Yi.Framework.Core.Exceptions;
using Yi.Framework.Ddd.Repositories;
using Yi.RBAC.Domain.Identity.Dtos;
using Yi.RBAC.Domain.Identity.Entities;
using Yi.RBAC.Domain.Shared.Identity.ConstClasses;
namespace Yi.RBAC.Domain.Identity
{
/// <summary>
/// 用户领域服务
/// </summary>
[AppService]
public class AccountManager
{
private readonly IRepository<UserEntity> _repository;
public AccountManager(IRepository<UserEntity> repository)
{
_repository = repository;
}
/// <summary>
/// 登录效验
/// </summary>
/// <param name="userName"></param>
/// <param name="password"></param>
/// <param name="userAction"></param>
/// <returns></returns>
public async Task LoginValidationAsync(string userName, string password, Action<UserEntity>? userAction = null)
{
var user = new UserEntity();
if (await ExistAsync(userName, o => user = o))
{
if (userAction is not null)
{
userAction.Invoke(user);
}
if (user.Password == MD5Helper.SHA2Encode(password, user.Salt))
{
return;
}
throw new UserFriendlyException(UserConst._错误);
}
throw new UserFriendlyException(UserConst._不存在);
}
/// <summary>
/// 判断账户合法存在
/// </summary>
/// <param name="userName"></param>
/// <param name="userAction"></param>
/// <returns></returns>
public async Task<bool> ExistAsync(string userName, Action<UserEntity>? userAction = null)
{
var user = await _repository.GetFirstAsync(u => u.UserName == userName && u.State == true);
if (userAction is not null)
{
userAction.Invoke(user);
}
if (user == null)
{
return false;
}
return true;
}
/// <summary>
/// 令牌转换
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
public Dictionary<string, object> UserInfoToClaim(UserRoleMenuDto dto)
{
var claims = new Dictionary<string, object>();
claims.Add(nameof(ICurrentUser.Id), dto.User.Id);
claims.Add(nameof(ICurrentUser.UserName), dto.User.UserName);
if (dto.User.Email is not null)
{
claims.Add(nameof(ICurrentUser.Email), dto.User.Email);
}
if (dto.User.Phone is not null)
{
claims.Add(nameof(ICurrentUser.PhoneNumber), dto.User.Phone);
}
if (UserConst.Admin.Equals(dto.User.UserName))
{
claims.Add(nameof(ICurrentUser.Permission), UserConst.AdminPermissionCode);
}
else
{
claims.Add(nameof(ICurrentUser.Permission), dto.PermissionCodes.Where(x => !string.IsNullOrEmpty(x)));
}
return claims;
}
}
}

View File

@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yi.RBAC.Domain.Identity.Entities;
namespace Yi.RBAC.Domain.Identity.Dtos
{
public class UserRoleMenuDto
{
public UserEntity User { get; set; } = new();
public HashSet<RoleEntity> Roles { get; set; } = new();
public HashSet<MenuEntity> Menus { get; set; } = new();
public List<string> RoleCodes { get; set; } = new();
public List<string> PermissionCodes { get; set; } = new();
}
}

View File

@@ -0,0 +1,85 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json.Serialization;
using SqlSugar;
using Yi.Framework.Data.Auditing;
using Yi.Framework.Data.Entities;
using Yi.Framework.Ddd.Entities;
namespace Yi.RBAC.Domain.Identity.Entities
{
/// <summary>
/// 部门表
///</summary>
[SugarTable("Dept")]
public partial class DeptEntity : IEntity<long>, ISoftDelete, IAuditedObject, IOrderNum, IState
{
/// <summary>
/// 主键
/// </summary>
[SugarColumn(IsPrimaryKey = true)]
public long Id { get; set; }
/// <summary>
/// 逻辑删除
/// </summary>
public bool IsDeleted { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public DateTime CreationTime { get; set; } = DateTime.Now;
/// <summary>
/// 创建者
/// </summary>
public long? CreatorId { get; set; }
/// <summary>
/// 最后修改者
/// </summary>
public long? LastModifierId { get; set; }
/// <summary>
/// 最后修改时间
/// </summary>
public DateTime? LastModificationTime { get; set; }
/// <summary>
/// 排序
/// </summary>
public int OrderNum { get; set; } = 0;
/// <summary>
/// 状态
/// </summary>
public bool State { get; set; }
/// <summary>
/// 部门名称
///</summary>
public string DeptName { get; set; }=string.Empty;
/// <summary>
/// 部门编码
///</summary>
[SugarColumn(ColumnName = "DeptCode")]
public string DeptCode { get; set; } = string.Empty;
/// <summary>
/// 负责人
///</summary>
[SugarColumn(ColumnName = "Leader")]
public string? Leader { get; set; }
/// <summary>
/// 父级id
///</summary>
[SugarColumn(ColumnName = "ParentId")]
public long ParentId { get; set; }
/// <summary>
/// 描述
///</summary>
[SugarColumn(ColumnName = "Remark")]
public string? Remark { get; set; }
}
}

View File

@@ -0,0 +1,196 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json.Serialization;
using SqlSugar;
using Yi.Framework.Data.Auditing;
using Yi.Framework.Data.Entities;
using Yi.Framework.Ddd.Entities;
using Yi.RBAC.Domain.Shared.Identity.Dtos;
using Yi.RBAC.Domain.Shared.Identity.EnumClasses;
namespace Yi.RBAC.Domain.Identity.Entities
{
/// <summary>
/// 菜单表
///</summary>
[SugarTable("Menu")]
public partial class MenuEntity : IEntity<long>, ISoftDelete, IAuditedObject, IOrderNum, IState
{
/// <summary>
/// 主键
/// </summary>
[SugarColumn(IsPrimaryKey = true)]
public long Id { get; set; }
/// <summary>
/// 逻辑删除
/// </summary>
public bool IsDeleted { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public DateTime CreationTime { get; set; } = DateTime.Now;
/// <summary>
/// 创建者
/// </summary>
public long? CreatorId { get; set; }
/// <summary>
/// 最后修改者
/// </summary>
public long? LastModifierId { get; set; }
/// <summary>
/// 最后修改时间
/// </summary>
public DateTime? LastModificationTime { get; set; }
/// <summary>
/// 排序
/// </summary>
public int OrderNum { get; set; } = 0;
/// <summary>
/// 状态
/// </summary>
public bool State { get; set; }
/// <summary>
/// 菜单名
/// </summary>
public string MenuName { get; set; } = string.Empty;
/// <summary>
///
///</summary>
[SugarColumn(ColumnName = "MenuType")]
public MenuTypeEnum MenuType { get; set; } = MenuTypeEnum.Menu;
/// <summary>
///
///</summary>
[SugarColumn(ColumnName = "PermissionCode")]
public string? PermissionCode { get; set; }
/// <summary>
///
///</summary>
[SugarColumn(ColumnName = "ParentId")]
public long ParentId { get; set; }
/// <summary>
/// 菜单图标
///</summary>
[SugarColumn(ColumnName = "MenuIcon")]
public string? MenuIcon { get; set; }
/// <summary>
/// 菜单组件路由
///</summary>
[SugarColumn(ColumnName = "Router")]
public string? Router { get; set; }
/// <summary>
/// 是否为外部链接
///</summary>
[SugarColumn(ColumnName = "IsLink")]
public bool IsLink { get; set; }
/// <summary>
/// 是否缓存
///</summary>
[SugarColumn(ColumnName = "IsCache")]
public bool IsCache { get; set; }
/// <summary>
/// 是否显示
///</summary>
[SugarColumn(ColumnName = "IsShow")]
public bool IsShow { get; set; } = true;
/// <summary>
/// 描述
///</summary>
[SugarColumn(ColumnName = "Remark")]
public string? Remark { get; set; }
/// <summary>
/// 组件路径
///</summary>
[SugarColumn(ColumnName = "Component")]
public string? Component { get; set; }
/// <summary>
/// 路由参数
///</summary>
[SugarColumn(ColumnName = "Query")]
public string? Query { get; set; }
[SugarColumn(IsIgnore = true)]
public List<MenuEntity>? Children { get; set; }
}
/// <summary>
/// 实体扩展
/// </summary>
public static class MenuEntityExtensions
{
/// <summary>
/// 构建vue3路由
/// </summary>
/// <param name="menus"></param>
/// <returns></returns>
public static List<Vue3RouterDto> Vue3RouterBuild(this List<MenuEntity> menus)
{
menus = menus.Where(m => m.MenuType != MenuTypeEnum.Component).ToList();
List<Vue3RouterDto> routers = new();
foreach (var m in menus)
{
var r = new Vue3RouterDto();
r.OrderNum = m.OrderNum;
var routerName = m.Router?.Split("/").LastOrDefault();
r.Id = m.Id;
r.ParentId = m.ParentId;
//开头大写
r.Name = routerName?.First().ToString().ToUpper() + routerName?.Substring(1);
r.Path = m.Router!;
r.Hidden = !m.IsShow;
if (m.MenuType == MenuTypeEnum.Catalogue)
{
r.Redirect = "noRedirect";
r.AlwaysShow = true;
//判断是否为最顶层的路由
if (0 == m.ParentId)
{
r.Component = "Layout";
}
else
{
r.Component = "ParentView";
}
}
if (m.MenuType == MenuTypeEnum.Menu)
{
r.Redirect = "noRedirect";
r.AlwaysShow = true;
r.Component = m.Component!;
r.AlwaysShow = false;
}
r.Meta = new Meta
{
Title = m.MenuName!,
Icon = m.MenuIcon!,
NoCache = !m.IsCache
};
if (m.IsLink)
{
r.Meta.link = m.Router!;
r.AlwaysShow = false;
}
routers.Add(r);
}
return TreeHelper.SetTree(routers);
}
}
}

View File

@@ -0,0 +1,77 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json.Serialization;
using SqlSugar;
using Yi.Framework.Data.Auditing;
using Yi.Framework.Data.Entities;
using Yi.Framework.Ddd.Entities;
namespace Yi.RBAC.Domain.Identity.Entities
{
/// <summary>
/// 岗位表
///</summary>
[SugarTable("Post")]
public partial class PostEntity : IEntity<long>, ISoftDelete, IAuditedObject, IOrderNum, IState
{
/// <summary>
/// 主键
/// </summary>
[SugarColumn(IsPrimaryKey = true)]
public long Id { get; set; }
/// <summary>
/// 逻辑删除
/// </summary>
public bool IsDeleted { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public DateTime CreationTime { get; set; } = DateTime.Now;
/// <summary>
/// 创建者
/// </summary>
public long? CreatorId { get; set; }
/// <summary>
/// 最后修改者
/// </summary>
public long? LastModifierId { get; set; }
/// <summary>
/// 最后修改时间
/// </summary>
public DateTime? LastModificationTime { get; set; }
/// <summary>
/// 排序
/// </summary>
public int OrderNum { get; set; } = 0;
/// <summary>
/// 状态
/// </summary>
public bool State { get; set; }
/// <summary>
/// 岗位编码
///</summary>
[SugarColumn(ColumnName = "PostCode")]
public string PostCode { get; set; }=string.Empty;
/// <summary>
/// 岗位名称
///</summary>
[SugarColumn(ColumnName = "PostName")]
public string PostName { get; set; } = string.Empty;
/// <summary>
/// 描述
///</summary>
[SugarColumn(ColumnName = "Remark")]
public string? Remark { get; set; }
}
}

View File

@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json.Serialization;
using SqlSugar;
using Yi.Framework.Ddd.Entities;
namespace Yi.RBAC.Domain.Identity.Entities;
/// <summary>
/// 角色部门关系表
///</summary>
[SugarTable("RoleDept")]
public partial class RoleDeptEntity : IEntity<long>
{
/// <summary>
/// 主键
/// </summary>
[SugarColumn(IsPrimaryKey = true)]
public long Id { get; set; }
/// <summary>
/// 角色id
///</summary>
[SugarColumn(ColumnName = "RoleId")]
public long? RoleId { get; set; }
/// <summary>
/// 部门id
///</summary>
[SugarColumn(ColumnName = "DeptId")]
public long? DeptId { get; set; }
}

View File

@@ -0,0 +1,91 @@
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Data.Auditing;
using Yi.Framework.Data.Entities;
using Yi.Framework.Ddd.Entities;
using Yi.RBAC.Domain.Shared.Identity.EnumClasses;
namespace Yi.RBAC.Domain.Identity.Entities
{
/// <summary>
/// 角色表
/// </summary>
[SugarTable("Role")]
public class RoleEntity : IEntity<long>, ISoftDelete, IAuditedObject, IOrderNum, IState
{
/// <summary>
/// 主键
/// </summary>
[SugarColumn(IsPrimaryKey = true)]
public long Id { get; set; }
/// <summary>
/// 逻辑删除
/// </summary>
public bool IsDeleted { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public DateTime CreationTime { get; set; } = DateTime.Now;
/// <summary>
/// 创建者
/// </summary>
public long? CreatorId { get; set; }
/// <summary>
/// 最后修改者
/// </summary>
public long? LastModifierId { get; set; }
/// <summary>
/// 最后修改时间
/// </summary>
public DateTime? LastModificationTime { get; set; }
/// <summary>
/// 排序
/// </summary>
public int OrderNum { get; set; } = 0;
/// <summary>
/// 角色名
/// </summary>
public string RoleName { get; set; } = string.Empty;
/// <summary>
/// 角色编码
///</summary>
[SugarColumn(ColumnName = "RoleCode")]
public string RoleCode { get; set; } = string.Empty;
/// <summary>
/// 描述
///</summary>
[SugarColumn(ColumnName = "Remark")]
public string? Remark { get; set; }
/// <summary>
/// 角色数据范围
///</summary>
[SugarColumn(ColumnName = "DataScope")]
public DataScopeEnum DataScope { get; set; } = DataScopeEnum.ALL;
/// <summary>
/// 状态
/// </summary>
public bool State { get; set; }
[Navigate(typeof(RoleMenuEntity), nameof(RoleMenuEntity.RoleId), nameof(RoleMenuEntity.MenuId))]
public List<MenuEntity> Menus { get; set; }
[Navigate(typeof(RoleDeptEntity), nameof(RoleDeptEntity.RoleId), nameof(RoleDeptEntity.DeptId))]
public List<DeptEntity> Depts { get; set; }
}
}

View File

@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json.Serialization;
using SqlSugar;
using Yi.Framework.Ddd.Entities;
namespace Yi.RBAC.Domain.Identity.Entities;
/// <summary>
/// 角色菜单关系表
///</summary>
[SugarTable("RoleMenu")]
public partial class RoleMenuEntity : IEntity<long>
{
/// <summary>
/// 主键
/// </summary>
[SugarColumn(IsPrimaryKey = true)]
public long Id { get; set; }
/// <summary>
///
///</summary>
[SugarColumn(ColumnName = "RoleId")]
public long RoleId { get; set; }
/// <summary>
///
///</summary>
[SugarColumn(ColumnName = "MenuId")]
public long MenuId { get; set; }
}

View File

@@ -15,7 +15,7 @@ namespace Yi.RBAC.Domain.Identity.Entities
/// 用户表
/// </summary>
[SugarTable("User")]
public class UserEntity : IEntity<long>, ISoftDelete, IAuditedObject, IOrderNum
public class UserEntity : IEntity<long>, ISoftDelete, IAuditedObject, IOrderNum,IState
{
/// <summary>
/// 主键
@@ -128,6 +128,71 @@ namespace Yi.RBAC.Domain.Identity.Entities
/// 排序
/// </summary>
public int OrderNum { get; set; } = 0;
/// <summary>
/// 状态
/// </summary>
public bool State { get; set; } = true;
/// <summary>
/// 角色
/// </summary>
[Navigate(typeof(UserRoleEntity), nameof(UserRoleEntity.UserId), nameof(UserRoleEntity.RoleId))]
public List<RoleEntity> Roles { get; set; }
/// <summary>
/// 岗位
/// </summary>
[Navigate(typeof(UserPostEntity), nameof(UserPostEntity.UserId), nameof(UserPostEntity.PostId))]
public List<PostEntity> Posts { get; set; }
/// <summary>
/// 部门
/// </summary>
[Navigate(NavigateType.OneToOne, nameof(DeptId))]
public DeptEntity? Dept { get; set; }
/// <summary>
/// 构建密码MD5盐值加密
/// </summary>
public UserEntity BuildPassword(string? password = null)
{
//如果不传值那就把自己的password当作传进来的password
if (password == null)
{
if (Password == null)
{
throw new ArgumentNullException(nameof(Password));
}
password = Password;
}
Salt = MD5Helper.GenerateSalt();
Password = MD5Helper.SHA2Encode(password, Salt);
return this;
}
/// <summary>
/// 判断密码和加密后的密码是否相同
/// </summary>
/// <param name="password"></param>
/// <returns></returns>
public bool JudgePassword(string password)
{
if (this.Salt is null)
{
throw new ArgumentNullException(this.Salt);
}
var p = MD5Helper.SHA2Encode(password, Salt);
if (Password == MD5Helper.SHA2Encode(password, Salt))
{
return true;
}
return false;
}
}

View File

@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json.Serialization;
using SqlSugar;
using Yi.Framework.Ddd.Entities;
namespace Yi.RBAC.Domain.Identity.Entities;
/// <summary>
/// 用户岗位表
///</summary>
[SugarTable("UserPost")]
public partial class UserPostEntity : IEntity<long>
{
/// <summary>
/// 主键
/// </summary>
[SugarColumn(IsPrimaryKey = true)]
public long Id { get; set; }
/// <summary>
/// 用户id
/// </summary>
[SugarColumn(ColumnName = "UserId")]
public long UserId { get; set; }
/// <summary>
/// 岗位id
///</summary>
[SugarColumn(ColumnName = "PostId")]
public long PostId { get; set; }
}

View File

@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using SqlSugar;
using Yi.Framework.Ddd.Entities;
namespace Yi.RBAC.Domain.Identity.Entities
{
/// <summary>
/// 用户角色关系表
///</summary>
[SugarTable("UserRole")]
public partial class UserRoleEntity : IEntity<long>
{
/// <summary>
/// 主键
/// </summary>
[SugarColumn(IsPrimaryKey = true)]
public long Id { get; set; }
/// <summary>
/// 角色id
/// </summary>
public long RoleId { get; set; }
/// <summary>
/// 用户id
/// </summary>
public long UserId { get; set; }
}
}

View File

@@ -4,6 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Ddd.Repositories;
using Yi.RBAC.Domain.Identity.Dtos;
using Yi.RBAC.Domain.Identity.Entities;
using Yi.RBAC.Domain.Shared.Identity.Dtos;

View File

@@ -3,70 +3,80 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Core.Exceptions;
using Yi.Framework.Ddd.Repositories;
using Yi.RBAC.Domain.Identity.Entities;
using Yi.RBAC.Domain.Shared.Identity.ConstClasses;
namespace Yi.RBAC.Domain.Identity
{
/// <summary>
/// 用户领域服务
/// </summary>
[AppService]
public class UserManager
{
private readonly IRepository<UserEntity> _repository;
public UserManager(IRepository<UserEntity> repository)
{
_repository = repository;
}
private readonly IRepository<UserRoleEntity> _repositoryUserRole;
private readonly IRepository<UserPostEntity> _repositoryUserPost;
public UserManager(IRepository<UserEntity> repository, IRepository<UserRoleEntity> repositoryUserRole, IRepository<UserPostEntity> repositoryUserPost) =>
(_repository, _repositoryUserRole, _repositoryUserPost) =
(repository, repositoryUserRole, repositoryUserPost);
/// <summary>
/// 登录效验
/// 给用户设置角色
/// </summary>
/// <param name="userName"></param>
/// <param name="password"></param>
/// <param name="userAction"></param>
/// <param name="userIds"></param>
/// <param name="roleIds"></param>
/// <returns></returns>
public async Task LoginValidationAsync(string userName, string password, Action<UserEntity>? userAction = null)
public async Task GiveUserSetRoleAsync(List<long> userIds, List<long>? roleIds)
{
var user = new UserEntity();
if (await ExistAsync(userName, o => user = o))
//删除用户之前所有的用户角色关系(物理删除,没有恢复的必要)
await _repositoryUserRole.DeleteAsync(u => userIds.Contains(u.UserId));
if (roleIds is not null)
{
if (userAction is not null)
//遍历用户
foreach (var userId in userIds)
{
userAction.Invoke(user);
//添加新的关系
List<UserRoleEntity> userRoleEntities = new();
foreach (var roleId in roleIds)
{
userRoleEntities.Add(new UserRoleEntity() { Id = SnowflakeHelper.NextId, UserId = userId, RoleId = roleId });
}
//一次性批量添加
await _repositoryUserRole.InsertRangeAsync(userRoleEntities);
}
if (user.Password != MD5Helper.SHA2Encode(password, user.Salt))
{
return;
}
throw new UserFriendlyException(UserConst._错误);
}
throw new UserFriendlyException(UserConst._不存在);
}
/// <summary>
/// 判断账户合法存在
/// 给用户设置岗位
/// </summary>
/// <param name="userName"></param>
/// <param name="userAction"></param>
/// <param name="userIds"></param>
/// <param name="postIds"></param>
/// <returns></returns>
public async Task<bool> ExistAsync(string userName, Action<UserEntity>? userAction = null)
public async Task GiveUserSetPostAsync(List<long> userIds, List<long>? postIds)
{
var user = await _repository.GetFirstAsync(u => u.UserName == userName && u.IsDeleted == false);
if (userAction is not null)
//删除用户之前所有的用户角色关系(物理删除,没有恢复的必要)
await _repositoryUserPost.DeleteAsync(u => userIds.Contains(u.UserId));
if (postIds is not null)
{
userAction.Invoke(user);
//遍历用户
foreach (var userId in userIds)
{
//添加新的关系
List<UserPostEntity> userPostEntities = new();
foreach (var post in postIds)
{
userPostEntities.Add(new UserPostEntity() { Id = SnowflakeHelper.NextId, UserId = userId, PostId = post });
}
//一次性批量添加
await _repositoryUserPost.InsertRangeAsync(userPostEntities);
}
}
if (user == null)
{
return false;
}
return true;
}
}
}
}

View File

@@ -1,27 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Data.DataSeeds;
using Yi.Framework.Ddd.Repositories;
using Yi.RBAC.Domain.School.Entities;
namespace Yi.RBAC.Domain.School.DataSeeds
{
[AppService(typeof(IDataSeed))]
public class StudentDataSeed : AbstractDataSeed<StudentEntity>
{
public StudentDataSeed(IRepository<StudentEntity> repository) : base(repository)
{
}
public override List<StudentEntity> GetSeedData()
{
return new List<StudentEntity>() { new StudentEntity { Id = SnowflakeHelper.NextId, Name = "你好", Phone = "123", Height = 188, IsDeleted = false } ,
new StudentEntity { Id = SnowflakeHelper.NextId, Name = "你好1", Phone = "123", Height = 188, IsDeleted = false },
new StudentEntity { Id = SnowflakeHelper.NextId, Name = "你好2", Phone = "123", Height = 188, IsDeleted = false }
};
}
}
}

View File

@@ -1,25 +0,0 @@
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Data.Entities;
using Yi.Framework.Ddd.Entities;
namespace Yi.RBAC.Domain.School.Entities
{
[SugarTable("Student")]
public class StudentEntity : IEntity<long>,ISoftDelete
{
[SugarColumn(IsPrimaryKey = true)]
public long Id { get; set; }
public string Name { get; set; }
public int? Height { get; set; }
public string? Phone { get; set; }
public bool IsDeleted { get; set; } = false;
}
}