parent
0690425149
commit
c86e4774e1
@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Infrastructure.Domain;
|
||||
|
||||
namespace Application.Domain.Entities
|
||||
{
|
||||
[Display(Name = "权限")]
|
||||
public class Permission : BaseEntity, IDisableUpdate, IDisableDelete
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Number { get; set; }
|
||||
public Guid? CategoryId { get; set; }
|
||||
public PermissionCategory Category { get; set; } = new PermissionCategory();
|
||||
|
||||
public List<RolePermission> RolePermissions { get; set; } = new List<RolePermission>();
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Infrastructure.Domain;
|
||||
|
||||
namespace Application.Domain.Entities
|
||||
{
|
||||
[Display(Name = "权限分类")]
|
||||
public class PermissionCategory : BaseTreeEntity<PermissionCategory>
|
||||
{
|
||||
public List<Permission> Permissions { get; set; } = new List<Permission>();
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Infrastructure.Domain;
|
||||
|
||||
namespace Application.Domain.Entities
|
||||
{
|
||||
[Display(Name = "角色")]
|
||||
public class Role : BaseEntity
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public List<UserRole> UserRoles { get; set; } = new List<UserRole>();
|
||||
public List<RolePermission> RolePermissions { get; set; } = new List<RolePermission>();
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Infrastructure.Domain;
|
||||
|
||||
namespace Application.Domain.Entities
|
||||
{
|
||||
[Display(Name = "角色权限")]
|
||||
public class RolePermission : BaseEntity
|
||||
{
|
||||
public Guid RoleId { get; set; }
|
||||
public Guid PermissionId { get; set; }
|
||||
public Role Role { get; set; }
|
||||
public Permission Permission { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Infrastructure.Domain;
|
||||
|
||||
namespace Application.Domain.Entities
|
||||
{
|
||||
[Display(Name = "用户")]
|
||||
public class User : BaseEntity, IDisableDelete
|
||||
{
|
||||
/// <summary>
|
||||
/// 登录名
|
||||
/// </summary>
|
||||
public string UserName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 加密混淆随机数
|
||||
/// </summary>
|
||||
public string SecurityStamp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 加密密码
|
||||
/// </summary>
|
||||
public string PasswordHash { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 邮箱
|
||||
/// </summary>
|
||||
public string Email { get; set; }
|
||||
|
||||
public List<UserRole> UserRoles { get; set; } = new List<UserRole>();
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Infrastructure.Domain;
|
||||
|
||||
namespace Application.Domain.Entities
|
||||
{
|
||||
[Display(Name = "用户角色")]
|
||||
public class UserRole : BaseEntity
|
||||
{
|
||||
public Guid UserId { get; set; }
|
||||
public Guid RoleId { get; set; }
|
||||
public User User { get; set; }
|
||||
public Role Role { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Application.Models
|
||||
{
|
||||
[Display(Name = "修改密码")]
|
||||
public class ChangePasswordModel
|
||||
{
|
||||
[Required(ErrorMessage = nameof(RequiredAttribute))]
|
||||
[DataType(DataType.Password)]
|
||||
[Display(Name = "当前密码")]
|
||||
public string OldPassword { get; set; }
|
||||
|
||||
[Required(ErrorMessage = nameof(RequiredAttribute))]
|
||||
[StringLength(100, MinimumLength = 6, ErrorMessage = "密码长度范围为{2}-{1}")]
|
||||
[DataType(DataType.Password)]
|
||||
[Display(Name = "新密码")]
|
||||
public string NewPassword { get; set; }
|
||||
|
||||
[DataType(DataType.Password)]
|
||||
[Display(Name = "确认新密码")]
|
||||
[Compare(nameof(NewPassword), ErrorMessage = "{0}和{1}不符")]
|
||||
public string ConfirmNewPassword { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Infrastructure.Application;
|
||||
|
||||
namespace Application.Models
|
||||
{
|
||||
[Display(Name = "权限")]
|
||||
public class EditPermissionModel : EditModel
|
||||
{
|
||||
[Display(Name = "分类")]
|
||||
public string CategoryName { get; set; }
|
||||
|
||||
[Display(Name = "名称"), Required]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Display(Name = "编号"), Required]
|
||||
public string Number { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Infrastructure.Application;
|
||||
|
||||
namespace Application.Models
|
||||
{
|
||||
[Display(Name = "角色")]
|
||||
public class EditRoleModel : EditModel
|
||||
{
|
||||
[Display(Name = "名称"), Required]
|
||||
public string Name { get; set; }
|
||||
|
||||
[DataType("MultiSelectList")]
|
||||
[Display(Name = "权限")]
|
||||
public List<Guid> Permissions { get; set; } = new List<Guid>();
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Infrastructure.Application;
|
||||
|
||||
namespace Application.Models
|
||||
{
|
||||
[Display(Name = "用户")]
|
||||
public class EditUserModel : EditModel
|
||||
{
|
||||
[Required(ErrorMessage = nameof(RequiredAttribute))]
|
||||
[RegularExpression("^[a-zA-Z0-9]+$", ErrorMessage = "用户名只能由数字和字母组成")]
|
||||
[StringLength(30, MinimumLength = 5, ErrorMessage = "用户名长度为5-30")]
|
||||
[Display(Name = "用户名")]
|
||||
public string UserName { get; set; }
|
||||
|
||||
[DataType("MultiSelectList")]
|
||||
[Display(Name = "角色")]
|
||||
public List<Guid> Roles { get; set; } = new List<Guid>();
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Application.Models
|
||||
{
|
||||
[Display(Name = "忘记密码")]
|
||||
public class ForgotPasswordModel
|
||||
{
|
||||
[Required(ErrorMessage = nameof(RequiredAttribute))]
|
||||
[DataType(DataType.EmailAddress)]
|
||||
[RegularExpression(@"^\w+@\w+\.\w+$", ErrorMessage = "邮箱格式错误")]
|
||||
[Display(Name = "邮箱")]
|
||||
[Remote("HasEmail", "Account", ErrorMessage = "邮箱不存在")]
|
||||
public string Email { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Infrastructure.Web;
|
||||
using Infrastructure.Web.DataAnnotations;
|
||||
|
||||
namespace Application.Models
|
||||
{
|
||||
[Display(Name = "登录")]
|
||||
public class LoginModel
|
||||
{
|
||||
[Display(Name = "用户名")]
|
||||
[Required(ErrorMessage = nameof(RequiredAttribute))]
|
||||
public string UserName { get; set; }
|
||||
|
||||
[Display(Name = "密码")]
|
||||
[Required(ErrorMessage = nameof(RequiredAttribute))]
|
||||
[DataType(DataType.Password)]
|
||||
public string Password { get; set; }
|
||||
|
||||
//[ImageCaptcha, UIHint("ImageCaptcha")]
|
||||
//[Display(Name = "验证码")]
|
||||
//[Required(ErrorMessage = nameof(RequiredAttribute))]
|
||||
//public string ImageCaptcha { get; set; }
|
||||
|
||||
[Display(Name = "记住我")]
|
||||
public bool RememberMe { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Infrastructure.Web.DataAnnotations;
|
||||
using Infrastructure.Web.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Application.Models
|
||||
{
|
||||
[Display(Name = "邮箱注册")]
|
||||
public class RegisterModel
|
||||
{
|
||||
[Required(ErrorMessage = nameof(RequiredAttribute))]
|
||||
[RegularExpression("^[a-zA-Z0-9]+$", ErrorMessage = "用户名只能由数字和字母组成")]
|
||||
[StringLength(30, MinimumLength = 5, ErrorMessage = "用户名长度为5-30")]
|
||||
[Display(Name = "用户名")]
|
||||
[Remote("UserNameNotUsed", "Account", ErrorMessage = "用户名已存在")]
|
||||
public string UserName { get; set; }
|
||||
|
||||
[Required(ErrorMessage = nameof(RequiredAttribute))]
|
||||
[StringLength(100, MinimumLength = 6, ErrorMessage = "密码长度范围为{2}-{1}")]
|
||||
[DataType(DataType.Password)]
|
||||
[Display(Name = "登录密码")]
|
||||
public string Password { get; set; }
|
||||
|
||||
[DataType(DataType.Password)]
|
||||
[Display(Name = "确认密码")]
|
||||
[Compare("Password", ErrorMessage = "确认密码输入错误")]
|
||||
public string ConfirmPassword { get; set; }
|
||||
|
||||
[Required(ErrorMessage = nameof(RequiredAttribute))]
|
||||
[DataType(DataType.EmailAddress)]
|
||||
[RegularExpression(@"^\w+@\w+\.\w+$", ErrorMessage = "邮箱格式错误")]
|
||||
[Display(Name = "邮箱")]
|
||||
[Remote("EmailNotUsed", "Account", ErrorMessage = "邮箱已占用")]
|
||||
public string Email { get; set; }
|
||||
|
||||
[MustBeTrue(ErrorMessage = nameof(MustBeTrueAttribute))]
|
||||
[AdditionalMetadata("用户服务协议", "/")]
|
||||
[Display(Name = "我阅读并同意")]
|
||||
[UIHint("MustBeTrue")]
|
||||
public bool AgreeWith { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Application.Models
|
||||
{
|
||||
[Display(Name = "重设密码")]
|
||||
public class ResetPasswordModel
|
||||
{
|
||||
[HiddenInput(DisplayValue = false)]
|
||||
[ScaffoldColumn(true)]
|
||||
public string Id { get; set; }
|
||||
|
||||
[Required(ErrorMessage = nameof(RequiredAttribute))]
|
||||
[StringLength(100, MinimumLength = 6, ErrorMessage = "密码长度范围为{2}-{1}")]
|
||||
[DataType(DataType.Password)]
|
||||
[Display(Name = "登录密码")]
|
||||
public string Password { get; set; }
|
||||
|
||||
[DataType(DataType.Password)]
|
||||
[Display(Name = "确认密码")]
|
||||
[Compare("Password", ErrorMessage = "确认密码输入错误")]
|
||||
public string ConfirmPassword { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Application.Domain.Entities;
|
||||
using Infrastructure.Data;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace IoTNode.Areas.Admin.Controllers
|
||||
{
|
||||
[Area("Admin")]
|
||||
public class AjaxController
|
||||
{
|
||||
private readonly ILogger<AjaxController> _logger;
|
||||
private readonly IRepository<Role> _roleRepo;
|
||||
private readonly IRepository<Permission> _permissionRepo;
|
||||
|
||||
public AjaxController(ILogger<AjaxController> logger,
|
||||
IRepository<Role> roleRepo,
|
||||
IRepository<Permission> permissionRepo)
|
||||
{
|
||||
this._logger = logger;
|
||||
this._roleRepo = roleRepo;
|
||||
this._permissionRepo = permissionRepo;
|
||||
}
|
||||
|
||||
#region Role
|
||||
|
||||
public MultiSelectList GetRoleMultiSelectList(IEnumerable<Guid> selected)
|
||||
{
|
||||
if (selected == null)
|
||||
{
|
||||
selected = new List<Guid>();
|
||||
}
|
||||
var list = this._roleRepo.ReadOnlyTable()
|
||||
.OrderBy(o => o.DisplayOrder)
|
||||
.Select(o => new { o.Id, o.Name })
|
||||
.ToList();
|
||||
return new MultiSelectList(list, "Id", "Name", selected);
|
||||
}
|
||||
|
||||
#endregion Role
|
||||
|
||||
#region Permission
|
||||
|
||||
public MultiSelectList GetPermissionMultiSelectList(IEnumerable<Guid> selectedValues)
|
||||
{
|
||||
if (selectedValues == null)
|
||||
{
|
||||
selectedValues = new List<Guid>();
|
||||
}
|
||||
var list = this._permissionRepo.Table()
|
||||
.Include(o => o.Category)
|
||||
.OrderBy(o => o.DisplayOrder)
|
||||
.ThenBy(o => o.UpdatedOn)
|
||||
.Select(o => new { o.Id, o.Name, Group = o.Category.Name })
|
||||
.ToList();
|
||||
return new MultiSelectList(list, "Id", "Name", selectedValues, "Group");
|
||||
}
|
||||
|
||||
#endregion Permission
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
using System.Linq;
|
||||
using Infrastructure.Data;
|
||||
using Infrastructure.Web.Mvc;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Application.Domain.Entities;
|
||||
using Application.Models;
|
||||
using Infrastructure.Application;
|
||||
|
||||
namespace IoTNode.Areas.Admin.Controllers
|
||||
{
|
||||
[Authorize]
|
||||
[Area(nameof(Admin))]
|
||||
public class PermissionController : CrudController<Permission, PagedListModel<EditPermissionModel>, EditPermissionModel, EditPermissionModel>
|
||||
{
|
||||
public PermissionController(IRepository<Permission> repo) : base(repo)
|
||||
{
|
||||
}
|
||||
|
||||
public override IQueryable<Permission> Include(IQueryable<Permission> query)
|
||||
{
|
||||
return query.Include(o => o.Category).ThenInclude(o => o.Parent);
|
||||
}
|
||||
|
||||
public override void ToModel(Permission entity, EditPermissionModel model)
|
||||
{
|
||||
model.CategoryName = entity.Category.GetFullName();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
using System.Linq;
|
||||
using Infrastructure.Data;
|
||||
using Infrastructure.Extensions;
|
||||
using Infrastructure.Web.Mvc;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Application.Domain.Entities;
|
||||
using Application.Models;
|
||||
using Infrastructure.Application;
|
||||
|
||||
namespace IoTNode.Areas.Admin.Controllers
|
||||
{
|
||||
[Authorize]
|
||||
[Area(nameof(Admin))]
|
||||
public class RoleController : CrudController<Role, PagedListModel<EditRoleModel>, EditRoleModel, EditRoleModel>
|
||||
{
|
||||
private readonly IRepository<Role> _roleRepo;
|
||||
private readonly AjaxController _ajax;
|
||||
|
||||
public RoleController(IRepository<Role> roleRepo, AjaxController ajax) : base(roleRepo)
|
||||
{
|
||||
this._roleRepo = roleRepo;
|
||||
this._ajax = ajax;
|
||||
}
|
||||
|
||||
public override IQueryable<Role> Include(IQueryable<Role> query)
|
||||
{
|
||||
return query.Include(o => o.RolePermissions).ThenInclude(o => o.Permission).ThenInclude(o => o.Category).ThenInclude(o => o.Parent);
|
||||
}
|
||||
|
||||
public override void ToModel(Role entity, EditRoleModel model)
|
||||
{
|
||||
if (entity != null)
|
||||
{
|
||||
model.Permissions = entity.RolePermissions.Select(o => o.PermissionId).ToList();
|
||||
}
|
||||
this.ViewData.MultiSelectList(o => model.Permissions, () => this._ajax.GetPermissionMultiSelectList(model.Permissions));
|
||||
}
|
||||
|
||||
public override void ToEntity(EditRoleModel model, Role entity)
|
||||
{
|
||||
foreach (var id in entity.RolePermissions.Select(o => o.PermissionId).ToList())
|
||||
{
|
||||
if (!model.Permissions.Any(o => o == id))
|
||||
{
|
||||
entity.RolePermissions.RemoveAll(o => o.PermissionId == id);
|
||||
}
|
||||
}
|
||||
foreach (var id in model.Permissions)
|
||||
{
|
||||
if (!entity.RolePermissions.Any(o => o.PermissionId == id))
|
||||
{
|
||||
entity.RolePermissions.Add(new RolePermission { PermissionId = id });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
using System.Linq;
|
||||
using Application.Domain.Entities;
|
||||
using Application.Models;
|
||||
using Infrastructure.Application;
|
||||
using Infrastructure.Data;
|
||||
using Infrastructure.Extensions;
|
||||
using Infrastructure.Security;
|
||||
using Infrastructure.Web.Mvc;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace IoTNode.Areas.Admin.Controllers
|
||||
{
|
||||
[Authorize]
|
||||
[Area(nameof(Admin))]
|
||||
public class UserController : CrudController<User, PagedListModel<EditUserModel>, EditUserModel, EditUserModel>
|
||||
{
|
||||
private readonly IRepository<User> _userRepo;
|
||||
private readonly IEncryptionService _encrypitonService;
|
||||
private readonly AjaxController _ajax;
|
||||
|
||||
public UserController(IRepository<User> userRepo, IEncryptionService encrypitonService, AjaxController ajax) : base(userRepo)
|
||||
{
|
||||
this._userRepo = userRepo;
|
||||
this._encrypitonService = encrypitonService;
|
||||
this._ajax = ajax;
|
||||
}
|
||||
|
||||
public override IQueryable<User> Include(IQueryable<User> query)
|
||||
{
|
||||
return query.Include(o => o.UserRoles).ThenInclude(o => o.Role);
|
||||
}
|
||||
|
||||
public override void ToModel(User entity, EditUserModel model)
|
||||
{
|
||||
if (entity != null)
|
||||
{
|
||||
model.Roles = entity.UserRoles.Select(o => o.RoleId).ToList();
|
||||
}
|
||||
this.ViewData.MultiSelectList(o => model.Roles, () => this._ajax.GetRoleMultiSelectList(model.Roles));
|
||||
}
|
||||
|
||||
public override void ToEntity(EditUserModel model, User entity)
|
||||
{
|
||||
foreach (var id in entity.UserRoles.Select(o => o.RoleId).ToList())
|
||||
{
|
||||
if (!model.Roles.Any(o => o == id))
|
||||
{
|
||||
entity.UserRoles.RemoveAll(o => o.RoleId == id);
|
||||
}
|
||||
}
|
||||
foreach (var id in model.Roles)
|
||||
{
|
||||
if (!entity.UserRoles.Any(o => o.RoleId == id))
|
||||
{
|
||||
entity.UserRoles.Add(new UserRole { RoleId = id });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnEdit(User entity, EditUserModel model)
|
||||
{
|
||||
model.UserName = entity.UserName;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,148 @@
|
||||
using Application.Domain.Entities;
|
||||
using Infrastructure.Data;
|
||||
using Infrastructure.Domain;
|
||||
using Infrastructure.Email;
|
||||
using Infrastructure.Extensions;
|
||||
using Infrastructure.Security;
|
||||
using Infrastructure.UI;
|
||||
using Infrastructure.Web;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace IoT.UI.Shard
|
||||
{
|
||||
public class IoTServiceStartup : BaseStartup
|
||||
{
|
||||
public IoTServiceStartup(IConfiguration configuration, IHostingEnvironment env) : base(configuration, env)
|
||||
{
|
||||
}
|
||||
|
||||
public override void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddTransient<IEmailSender, EmptyEmailSender>();
|
||||
base.ConfigureServices(services);
|
||||
}
|
||||
|
||||
public override void ConfigureOptions(IServiceCollection services)
|
||||
{
|
||||
services.ConfigureOptions(new FileConfigureOptions(_env, new List<string> { "IoT.Shared" }));
|
||||
}
|
||||
|
||||
public override void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
|
||||
{
|
||||
base.Configure(app, env, loggerFactory);
|
||||
}
|
||||
|
||||
public override Task ValidatePrincipal(CookieValidatePrincipalContext arg)
|
||||
{
|
||||
return Task.Run(() =>
|
||||
{
|
||||
var userRepo = arg.HttpContext.RequestServices.GetService<IRepository<User>>();
|
||||
|
||||
var userName = arg.Principal.Identity.Name;
|
||||
var userPermissions = userRepo.ReadOnlyTable().Where(o => o.UserName == userName)
|
||||
.SelectMany(o => o.UserRoles)
|
||||
.Select(o => o.Role)
|
||||
.SelectMany(o => o.RolePermissions)
|
||||
.Select(o => o.Permission.Number)
|
||||
.ToList();
|
||||
var currentPermissions = arg.Principal.Claims.Where(o => o.Type == "Role").Select(o => o.Value).ToList();
|
||||
if (!currentPermissions.SequenceEqual(userPermissions))
|
||||
{
|
||||
arg.HttpContext.SignOutAsync();
|
||||
arg.HttpContext.SignIn(userName, userPermissions, arg.Properties.IsPersistent);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.Entity<PermissionCategory>().HasOne(o => o.Parent).WithMany(o => o.Children).HasForeignKey(o => o.ParentId).OnDelete(DeleteBehavior.SetNull);
|
||||
modelBuilder.Entity<Permission>().HasOne(o => o.Category).WithMany(o => o.Permissions).HasForeignKey(o => o.CategoryId).OnDelete(DeleteBehavior.SetNull);
|
||||
modelBuilder.Entity<UserRole>().HasOne(o => o.User).WithMany(o => o.UserRoles).HasForeignKey(o => o.UserId);
|
||||
modelBuilder.Entity<UserRole>().HasOne(o => o.Role).WithMany(o => o.UserRoles).HasForeignKey(o => o.RoleId);
|
||||
modelBuilder.Entity<RolePermission>().HasOne(o => o.Role).WithMany(o => o.RolePermissions).HasForeignKey(o => o.RoleId);
|
||||
modelBuilder.Entity<RolePermission>().HasOne(o => o.Permission).WithMany(o => o.RolePermissions).HasForeignKey(o => o.PermissionId);
|
||||
modelBuilder.Entity<User>().HasIndex(o => o.UserName).IsUnique();
|
||||
modelBuilder.Entity<User>().HasIndex(o => o.Email).IsUnique();
|
||||
modelBuilder.Entity<Role>().HasIndex(o => o.Name).IsUnique();
|
||||
modelBuilder.Entity<PermissionCategory>().HasIndex(o => o.Number).IsUnique();
|
||||
modelBuilder.Entity<Permission>().HasIndex(o => o.Number).IsUnique();
|
||||
modelBuilder.Entity<UserRole>().HasIndex(o => new { o.UserId, o.RoleId }).IsUnique();
|
||||
modelBuilder.Entity<RolePermission>().HasIndex(o => new { o.RoleId, o.PermissionId }).IsUnique();
|
||||
}
|
||||
|
||||
public override void Seed(DbContext dbContext, IServiceProvider serviceProvider, IConfiguration configuration)
|
||||
{
|
||||
dbContext.Set<PermissionCategory>().Add(new PermissionCategory
|
||||
{
|
||||
Name = "配置",
|
||||
Number = "Configuration",
|
||||
Permissions = new List<Permission> {
|
||||
new Permission { Name = "查询配置", Number = "ListConfiguration",DisplayOrder =1 },
|
||||
new Permission { Name = "修改配置", Number = "EditConfiguration",DisplayOrder =2 }
|
||||
}
|
||||
}); int i = 1;
|
||||
var skipReadCollection = new string[] { "Permission" };
|
||||
var skipAddCollection = new string[] { "Permission", "Setting" };
|
||||
foreach (var item in dbContext.Model.GetEntityTypes())
|
||||
{
|
||||
var type = item.ClrType;
|
||||
var name = type.GetDisplayName();
|
||||
var number = type.Name;
|
||||
var category = new PermissionCategory
|
||||
{
|
||||
Name = name,
|
||||
Number = type.Name,
|
||||
DisplayOrder = i
|
||||
};
|
||||
category.Permissions.Add(new Permission { Name = $"查询{name}", Number = $"List{number}", DisplayOrder = 10 * i + 1 });
|
||||
if (!skipReadCollection.Contains(type.Name))
|
||||
{
|
||||
category.Permissions.Add(new Permission { Name = $"查看{name}", Number = $"Read{number}", DisplayOrder = 10 * i + 2 });
|
||||
}
|
||||
if (!skipAddCollection.Contains(type.Name))
|
||||
{
|
||||
category.Permissions.Add(new Permission { Name = $"添加{name}", Number = $"Add{number}", DisplayOrder = 10 * i + 3 });
|
||||
}
|
||||
if (!typeof(IDisableUpdate).IsAssignableFrom(type))
|
||||
{
|
||||
category.Permissions.Add(new Permission { Name = $"修改{name}", Number = $"Edit{number}", DisplayOrder = 10 * i + 4 });
|
||||
}
|
||||
if (!typeof(IDisableDelete).IsAssignableFrom(type))
|
||||
{
|
||||
category.Permissions.Add(new Permission { Name = $"删除{name}", Number = $"Delete{number}", DisplayOrder = 10 * i + 5 });
|
||||
}
|
||||
dbContext.Set<PermissionCategory>().Add(category);
|
||||
i += 1;
|
||||
}
|
||||
dbContext.SaveChanges();
|
||||
var adminRole = new Role { Name = "管理员", IsReadOnly = true };
|
||||
foreach (var item in dbContext.Set<Permission>())
|
||||
{
|
||||
adminRole.RolePermissions.Add(new RolePermission { Permission = item, IsReadOnly = true });
|
||||
}
|
||||
var encryptionService = serviceProvider.GetService<IEncryptionService>();
|
||||
var securityStam = "123456";
|
||||
dbContext.Set<User>().Add(new User
|
||||
{
|
||||
UserName = "admin",
|
||||
SecurityStamp = securityStam,
|
||||
PasswordHash = encryptionService.CreatePasswordHash("123456", securityStam),
|
||||
Email = "test@test.com",
|
||||
UserRoles = new List<UserRole> { new UserRole { Role = adminRole } }
|
||||
});
|
||||
dbContext.SaveChanges();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
@model ChangePasswordModel
|
||||
@{
|
||||
HtmlTitle = ViewContext.ViewData.ModelMetadata.ModelType.GetDisplayName();
|
||||
}
|
||||
@Html.EditorForModel()
|
@ -0,0 +1,8 @@
|
||||
@model ForgotPasswordModel
|
||||
@{
|
||||
Layout = "/Views/Shared/_Layout.cshtml";
|
||||
DisableBackUrl = true;
|
||||
HtmlTitle = ViewContext.ViewData.ModelMetadata.ModelType.GetDisplayName();
|
||||
}
|
||||
@ViewBag.Message
|
||||
@Html.EditorForModel()
|
@ -0,0 +1,3 @@
|
||||
@{
|
||||
HtmlTitle = "用户中心";
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
@model LoginModel
|
||||
@{
|
||||
Layout = "/Views/Shared/_Layout.cshtml";
|
||||
DisableBackUrl = true;
|
||||
HtmlTitle = ViewContext.ViewData.ModelMetadata.ModelType.GetDisplayName();
|
||||
}
|
||||
@Html.EditorForModel()
|
@ -0,0 +1,7 @@
|
||||
@model RegisterModel
|
||||
@{
|
||||
Layout = "/Views/Shared/_Layout.cshtml";
|
||||
DisableBackUrl = true;
|
||||
HtmlTitle = ViewContext.ViewData.ModelMetadata.ModelType.GetDisplayName();
|
||||
}
|
||||
@Html.EditorForModel()
|
@ -0,0 +1,7 @@
|
||||
@model ResetPasswordModel
|
||||
@{
|
||||
Layout = "/Views/Shared/_Layout.cshtml";
|
||||
DisableBackUrl = true;
|
||||
HtmlTitle = ViewContext.ViewData.ModelMetadata.ModelType.GetDisplayName();
|
||||
}
|
||||
@Html.EditorForModel()
|
@ -0,0 +1,21 @@
|
||||
<section class="sidebar" style="height: auto;">
|
||||
<ul class="sidebar-menu" data-widget="tree">
|
||||
<li class="@GetClass("Index")"><a href="@Url.Action("Index")"><i class="fa fa-circle-o"></i><span>用户中心</span></a></li>
|
||||
<li class="@GetClass("ChangePassword")"><a href="@Url.Action("ChangePassword")"><i class="fa fa-circle-o"></i><span>修改密码</span></a></li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
@functions{
|
||||
public string GetClass(params string[] controllers)
|
||||
{
|
||||
if (controllers.Select(o => o.ToLower()).Contains(this.ViewContext.RouteData.Values["controller"].ToString().ToLower()))
|
||||
{
|
||||
if (controllers.Length > 1)
|
||||
{
|
||||
return "active open";
|
||||
}
|
||||
return "active";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
@inject IConfiguration cfg
|
||||
@{
|
||||
var total = cfg.GetValue<int>("CaptchaSeconds");
|
||||
var sec = total;
|
||||
var session = this.Context.Session;
|
||||
var model = session.Get<CodeCaptchaModel>(CodeCaptchaModel.Key);
|
||||
if (model != null)
|
||||
{
|
||||
sec = (int)(model.ExpireDateUtc - DateTime.UtcNow).TotalSeconds;
|
||||
}
|
||||
}
|
||||
<script>
|
||||
var total = @total;
|
||||
var sec = @sec;
|
||||
var timer;
|
||||
function StartTimer(sec) {
|
||||
if (sec > 0) {
|
||||
$('#send-code').attr("disabled", "disabled").attr("value", "重发" + sec + "秒");
|
||||
timer = setTimeout('StartTimer("' + (sec - 1) + '")', 1000);
|
||||
}
|
||||
else {
|
||||
$('#send-code').removeAttr("disabled").attr("value", "发送验证码");
|
||||
EndTimer();
|
||||
}
|
||||
}
|
||||
function EndTimer() {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
$(function () {
|
||||
if (sec > 0 && sec < total) {
|
||||
StartTimer(sec);
|
||||
}
|
||||
});
|
||||
$(function () {
|
||||
$('#send-code').click(function () {
|
||||
$(this).attr("disabled", "disabled");
|
||||
if (!valid()) {
|
||||
$(this).removeAttr("disabled");
|
||||
return;
|
||||
}
|
||||
var url = getUrl();
|
||||
$.getJSON(url, function (json) {
|
||||
if (json.success) {
|
||||
StartTimer(json.data);
|
||||
}
|
||||
else {
|
||||
alert(json.data);
|
||||
$(this).removeAttr("disabled");
|
||||
}
|
||||
}).fail(function () {
|
||||
$(this).removeAttr("disabled")
|
||||
});
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
Loading…
Reference in new issue