doc: 格式化文档

This commit is contained in:
Argo-Tianyi 2021-12-30 13:31:40 +08:00
parent eea8838963
commit 39aa8bfd1d
28 changed files with 1150 additions and 1176 deletions

View File

@ -1,50 +1,49 @@
using BootstrapAdmin.DataAccess.Models;
using Microsoft.EntityFrameworkCore;
namespace BootstrapAdmin.DataAccess.EFCore
namespace BootstrapAdmin.DataAccess.EFCore;
/// <summary>
///
/// </summary>
public class BootstrapAdminContext : DbContext
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="options"></param>
public BootstrapAdminContext(DbContextOptions<BootstrapAdminContext> options) : base(options)
{
}
/// <summary>
///
/// </summary>
public class BootstrapAdminContext : DbContext
[NotNull]
public DbSet<Dict>? Dicts { get; set; }
/// <summary>
///
/// </summary>
[NotNull]
public DbSet<User>? Users { get; set; }
/// <summary>
///
/// </summary>
[NotNull]
public DbSet<Navigation>? Navigations { get; set; }
/// <summary>
///
/// </summary>
/// <param name="modelBuilder"></param>
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="options"></param>
public BootstrapAdminContext(DbContextOptions<BootstrapAdminContext> options) : base(options)
{
}
/// <summary>
///
/// </summary>
[NotNull]
public DbSet<Dict>? Dicts { get; set; }
/// <summary>
///
/// </summary>
[NotNull]
public DbSet<User>? Users { get; set; }
/// <summary>
///
/// </summary>
[NotNull]
public DbSet<Navigation>? Navigations { get; set; }
/// <summary>
///
/// </summary>
/// <param name="modelBuilder"></param>
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().Ignore(u => u.Period);
modelBuilder.Entity<User>().Ignore(u => u.NewPassword);
modelBuilder.Entity<User>().Ignore(u => u.CofirmPassword);
modelBuilder.Entity<User>().Ignore(u => u.IsReset);
}
modelBuilder.Entity<User>().Ignore(u => u.Period);
modelBuilder.Entity<User>().Ignore(u => u.NewPassword);
modelBuilder.Entity<User>().Ignore(u => u.CofirmPassword);
modelBuilder.Entity<User>().Ignore(u => u.IsReset);
}
}

View File

@ -4,50 +4,49 @@ using BootstrapAdmin.Web.Core;
using BootstrapBlazor.Components;
using Microsoft.EntityFrameworkCore;
namespace Microsoft.Extensions.DependencyInjection
namespace Microsoft.Extensions.DependencyInjection;
/// <summary>
///
/// </summary>
public static class ServicesExtensions
{
/// <summary>
///
/// </summary>
public static class ServicesExtensions
/// <param name="services"></param>
/// <param name="optionConfigure"></param>
/// <param name="lifetime"></param>
/// <returns></returns>
public static IServiceCollection AddEFCoreDataAccessServices(this IServiceCollection services, Action<IServiceProvider, DbContextOptionsBuilder> optionConfigure, ServiceLifetime lifetime = ServiceLifetime.Singleton)
{
/// <summary>
///
/// </summary>
/// <param name="services"></param>
/// <param name="optionConfigure"></param>
/// <param name="lifetime"></param>
/// <returns></returns>
public static IServiceCollection AddEFCoreDataAccessServices(this IServiceCollection services, Action<IServiceProvider, DbContextOptionsBuilder> optionConfigure, ServiceLifetime lifetime = ServiceLifetime.Singleton)
{
services.AddDbContextFactory<BootstrapAdminContext>(optionConfigure, lifetime);
services.AddDbContextFactory<BootstrapAdminContext>(optionConfigure, lifetime);
services.AddServices();
return services;
}
/// <summary>
///
/// </summary>
/// <param name="services"></param>
/// <param name="optionConfigure"></param>
/// <param name="lifetime"></param>
/// <returns></returns>
public static IServiceCollection AddEFCoreDataAccessServices(this IServiceCollection services, Action<DbContextOptionsBuilder> optionConfigure, ServiceLifetime lifetime = ServiceLifetime.Singleton)
{
services.AddDbContextFactory<BootstrapAdminContext>(optionConfigure, lifetime);
services.AddServices();
return services;
}
/// <summary>
///
/// </summary>
/// <param name="services"></param>
/// <param name="optionConfigure"></param>
/// <param name="lifetime"></param>
/// <returns></returns>
public static IServiceCollection AddEFCoreDataAccessServices(this IServiceCollection services, Action<DbContextOptionsBuilder> optionConfigure, ServiceLifetime lifetime = ServiceLifetime.Singleton)
{
services.AddDbContextFactory<BootstrapAdminContext>(optionConfigure, lifetime);
services.AddServices();
return services;
}
services.AddServices();
return services;
}
private static IServiceCollection AddServices(this IServiceCollection services)
{
// 增加数据服务
services.AddSingleton(typeof(IDataService<>), typeof(DefaultDataService<>));
private static IServiceCollection AddServices(this IServiceCollection services)
{
// 增加数据服务
services.AddSingleton(typeof(IDataService<>), typeof(DefaultDataService<>));
services.AddSingleton<INavigation, NavigationsService>();
services.AddSingleton<IDict, DictService>();
return services;
}
services.AddSingleton<INavigation, NavigationsService>();
services.AddSingleton<IDict, DictService>();
return services;
}
}

View File

@ -5,91 +5,90 @@
using BootstrapBlazor.Components;
using Microsoft.EntityFrameworkCore;
namespace BootstrapAdmin.DataAccess.EFCore.Services
namespace BootstrapAdmin.DataAccess.EFCore.Services;
/// <summary>
/// EFCore ORM 的 IDataService 接口实现
/// </summary>
class DefaultDataService<TModel> : DataServiceBase<TModel> where TModel : class, new()
{
private IDbContextFactory<BootstrapAdminContext> DbFactory { get; }
/// <summary>
/// EFCore ORM 的 IDataService 接口实现
/// 构造函数
/// </summary>
class DefaultDataService<TModel> : DataServiceBase<TModel> where TModel : class, new()
public DefaultDataService(IDbContextFactory<BootstrapAdminContext> factory) => DbFactory = factory;
/// <summary>
/// 删除方法
/// </summary>
/// <param name="models"></param>
/// <returns></returns>
public override async Task<bool> DeleteAsync(IEnumerable<TModel> models)
{
private IDbContextFactory<BootstrapAdminContext> DbFactory { get; }
// 通过模型获取主键列数据
// 支持批量删除
var context = DbFactory.CreateDbContext();
context.RemoveRange(models);
return await context.SaveChangesAsync() > 0;
}
/// <summary>
/// 构造函数
/// </summary>
public DefaultDataService(IDbContextFactory<BootstrapAdminContext> factory) => DbFactory = factory;
/// <summary>
/// 删除方法
/// </summary>
/// <param name="models"></param>
/// <returns></returns>
public override async Task<bool> DeleteAsync(IEnumerable<TModel> models)
/// <summary>
/// 保存方法
/// </summary>
/// <param name="model"></param>
/// <param name="changedType"></param>
/// <returns></returns>
public override async Task<bool> SaveAsync(TModel model, ItemChangedType changedType)
{
var context = DbFactory.CreateDbContext();
if (changedType == ItemChangedType.Add)
{
// 通过模型获取主键列数据
// 支持批量删除
var context = DbFactory.CreateDbContext();
context.RemoveRange(models);
return await context.SaveChangesAsync() > 0;
context.Entry(model).State = EntityState.Added;
}
/// <summary>
/// 保存方法
/// </summary>
/// <param name="model"></param>
/// <param name="changedType"></param>
/// <returns></returns>
public override async Task<bool> SaveAsync(TModel model, ItemChangedType changedType)
else
{
var context = DbFactory.CreateDbContext();
if (changedType == ItemChangedType.Add)
{
context.Entry(model).State = EntityState.Added;
}
else
{
context.Entry(model).State = EntityState.Modified;
}
return await context.SaveChangesAsync() > 0;
context.Entry(model).State = EntityState.Modified;
}
return await context.SaveChangesAsync() > 0;
}
/// <summary>
/// 查询方法
/// </summary>
/// <param name="option"></param>
/// <returns></returns>
public override Task<QueryData<TModel>> QueryAsync(QueryPageOptions option)
/// <summary>
/// 查询方法
/// </summary>
/// <param name="option"></param>
/// <returns></returns>
public override Task<QueryData<TModel>> QueryAsync(QueryPageOptions option)
{
var context = DbFactory.CreateDbContext();
var ret = new QueryData<TModel>()
{
var context = DbFactory.CreateDbContext();
var ret = new QueryData<TModel>()
{
IsSorted = true,
IsFiltered = true,
IsSearch = true
};
IsSorted = true,
IsFiltered = true,
IsSearch = true
};
var filters = option.Filters.Concat(option.Searchs).Concat(option.CustomerSearchs);
if (option.IsPage)
{
var items = context.Set<TModel>()
.Where(filters.GetFilterLambda<TModel>(), filters.Any())
.Sort(option.SortName!, option.SortOrder, !string.IsNullOrEmpty(option.SortName))
.Count(out var count)
.Page((option.PageIndex - 1) * option.PageItems, option.PageItems);
var filters = option.Filters.Concat(option.Searchs).Concat(option.CustomerSearchs);
if (option.IsPage)
{
var items = context.Set<TModel>()
.Where(filters.GetFilterLambda<TModel>(), filters.Any())
.Sort(option.SortName!, option.SortOrder, !string.IsNullOrEmpty(option.SortName))
.Count(out var count)
.Page((option.PageIndex - 1) * option.PageItems, option.PageItems);
ret.TotalCount = count;
ret.Items = items;
}
else
{
var items = context.Set<TModel>()
.Where(filters.GetFilterLambda<TModel>(), filters.Any())
.Sort(option.SortName!, option.SortOrder, !string.IsNullOrEmpty(option.SortName))
.Count(out var count);
ret.TotalCount = count;
ret.Items = items;
}
return Task.FromResult(ret);
ret.TotalCount = count;
ret.Items = items;
}
else
{
var items = context.Set<TModel>()
.Where(filters.GetFilterLambda<TModel>(), filters.Any())
.Sort(option.SortName!, option.SortOrder, !string.IsNullOrEmpty(option.SortName))
.Count(out var count);
ret.TotalCount = count;
ret.Items = items;
}
return Task.FromResult(ret);
}
}

View File

@ -2,53 +2,52 @@
using BootstrapAdmin.Web.Core;
using BootstrapBlazor.Components;
namespace BootstrapAdmin.DataAccess.EFCore.Services
namespace BootstrapAdmin.DataAccess.EFCore.Services;
class DictService : IDict
{
class DictService : IDict
public Dictionary<string, string> GetApps()
{
public Dictionary<string, string> GetApps()
{
throw new NotImplementedException();
}
throw new NotImplementedException();
}
public Dictionary<string, string> GetLogins()
{
throw new NotImplementedException();
}
public Dictionary<string, string> GetLogins()
{
throw new NotImplementedException();
}
public Dictionary<string, string> GetThemes()
{
throw new NotImplementedException();
}
public Dictionary<string, string> GetThemes()
{
throw new NotImplementedException();
}
public string GetWebFooter()
{
throw new NotImplementedException();
}
public string GetWebFooter()
{
throw new NotImplementedException();
}
public string GetWebTitle()
{
throw new NotImplementedException();
}
public string GetWebTitle()
{
throw new NotImplementedException();
}
public bool IsDemo()
{
throw new NotImplementedException();
}
public bool IsDemo()
{
throw new NotImplementedException();
}
public bool SaveDemo(bool isDemo)
{
throw new NotImplementedException();
}
public bool SaveDemo(bool isDemo)
{
throw new NotImplementedException();
}
public bool AuthenticateDemo(string code)
{
throw new NotImplementedException();
}
public bool AuthenticateDemo(string code)
{
throw new NotImplementedException();
}
public bool SaveHealthCheck(bool enable = true)
{
throw new NotImplementedException();
}
public bool SaveHealthCheck(bool enable = true)
{
throw new NotImplementedException();
}
}

View File

@ -2,41 +2,40 @@
using BootstrapAdmin.DataAccess.Models;
using Microsoft.EntityFrameworkCore;
namespace BootstrapAdmin.DataAccess.EFCore.Services
namespace BootstrapAdmin.DataAccess.EFCore.Services;
/// <summary>
///
/// </summary>
class NavigationsService : INavigation
{
private IDbContextFactory<BootstrapAdminContext> DbFactory { get; set; }
/// <summary>
///
/// </summary>
class NavigationsService : INavigation
/// <param name="factory"></param>
public NavigationsService(IDbContextFactory<BootstrapAdminContext> factory) => DbFactory = factory;
/// <summary>
/// 获得指定用户名可访问的所有菜单集合
/// </summary>
/// <param name="userName">当前用户名</param>
/// <returns>未层次化的菜单集合</returns>
public List<Navigation> GetAllMenus(string userName)
{
private IDbContextFactory<BootstrapAdminContext> DbFactory { get; set; }
using var context = DbFactory.CreateDbContext();
//return context..Fetch<Models.Navigations>($"select n.ID, n.ParentId, n.Name, n.{order}, n.Icon, n.Url, n.Category, n.Target, n.IsResource, n.Application, d.Name as CategoryName, ln.Name as ParentName from Navigations n inner join Dicts d on n.Category = d.Code and d.Category = @Category and d.Define = 0 left join Navigations ln on n.ParentId = ln.ID inner join (select nr.NavigationID from Users u inner join UserRole ur on ur.UserID = u.ID inner join NavigationRole nr on nr.RoleID = ur.RoleID where u.UserName = @UserName union select nr.NavigationID from Users u inner join UserGroup ug on u.ID = ug.UserID inner join RoleGroup rg on rg.GroupID = ug.GroupID inner join NavigationRole nr on nr.RoleID = rg.RoleID where u.UserName = @UserName union select n.ID from Navigations n where EXISTS (select UserName from Users u inner join UserRole ur on u.ID = ur.UserID inner join Roles r on ur.RoleID = r.ID where u.UserName = @UserName and r.RoleName = @RoleName)) nav on n.ID = nav.NavigationID", new { UserName = userName, Category = "菜单", RoleName = "Administrators" });
return new List<Navigation>();
}
/// <summary>
///
/// </summary>
/// <param name="factory"></param>
public NavigationsService(IDbContextFactory<BootstrapAdminContext> factory) => DbFactory = factory;
public List<string> GetMenusByRoleId(string? roleId)
{
throw new NotImplementedException();
}
/// <summary>
/// 获得指定用户名可访问的所有菜单集合
/// </summary>
/// <param name="userName">当前用户名</param>
/// <returns>未层次化的菜单集合</returns>
public List<Navigation> GetAllMenus(string userName)
{
using var context = DbFactory.CreateDbContext();
//return context..Fetch<Models.Navigations>($"select n.ID, n.ParentId, n.Name, n.{order}, n.Icon, n.Url, n.Category, n.Target, n.IsResource, n.Application, d.Name as CategoryName, ln.Name as ParentName from Navigations n inner join Dicts d on n.Category = d.Code and d.Category = @Category and d.Define = 0 left join Navigations ln on n.ParentId = ln.ID inner join (select nr.NavigationID from Users u inner join UserRole ur on ur.UserID = u.ID inner join NavigationRole nr on nr.RoleID = ur.RoleID where u.UserName = @UserName union select nr.NavigationID from Users u inner join UserGroup ug on u.ID = ug.UserID inner join RoleGroup rg on rg.GroupID = ug.GroupID inner join NavigationRole nr on nr.RoleID = rg.RoleID where u.UserName = @UserName union select n.ID from Navigations n where EXISTS (select UserName from Users u inner join UserRole ur on u.ID = ur.UserID inner join Roles r on ur.RoleID = r.ID where u.UserName = @UserName and r.RoleName = @RoleName)) nav on n.ID = nav.NavigationID", new { UserName = userName, Category = "菜单", RoleName = "Administrators" });
return new List<Navigation>();
}
public List<string> GetMenusByRoleId(string? roleId)
{
throw new NotImplementedException();
}
public bool SaveMenusByRoleId(string? roleId, List<string> menuIds)
{
throw new NotImplementedException();
}
public bool SaveMenusByRoleId(string? roleId, List<string> menuIds)
{
throw new NotImplementedException();
}
}

View File

@ -1,33 +1,32 @@
using System.ComponentModel;
namespace BootstrapAdmin.DataAccess.Models
namespace BootstrapAdmin.DataAccess.Models;
/// <summary>
/// 后台数据库脚本执行日志实体类
/// </summary>
public class DBLog
{
/// <summary>
/// 后台数据库脚本执行日志实体类
/// 获得/设置 主键ID
/// </summary>
public class DBLog
{
/// <summary>
/// 获得/设置 主键ID
/// </summary>
public string? Id { get; set; }
public string? Id { get; set; }
/// <summary>
/// 获得/设置 当前登陆名
/// </summary>
[DisplayName("所属用户")]
public string? UserName { get; set; }
/// <summary>
/// 获得/设置 当前登陆名
/// </summary>
[DisplayName("所属用户")]
public string? UserName { get; set; }
/// <summary>
/// 获得/设置 数据库执行脚本
/// </summary>
[DisplayName("脚本内容")]
public string SQL { get; set; } = "";
/// <summary>
/// 获得/设置 数据库执行脚本
/// </summary>
[DisplayName("脚本内容")]
public string SQL { get; set; } = "";
/// <summary>
/// 获取/设置 用户角色关联状态 checked 标示已经关联 '' 标示未关联
/// </summary>
[DisplayName("执行时间")]
public DateTime LogTime { get; set; }
}
/// <summary>
/// 获取/设置 用户角色关联状态 checked 标示已经关联 '' 标示未关联
/// </summary>
[DisplayName("执行时间")]
public DateTime LogTime { get; set; }
}

View File

@ -2,43 +2,42 @@
using System.ComponentModel.DataAnnotations;
namespace BootstrapAdmin.DataAccess.Models
namespace BootstrapAdmin.DataAccess.Models;
/// <summary>
/// 字典配置项
/// </summary>
public class Dict
{
/// <summary>
/// 字典配置项
/// 获得/设置 字典主键 数据库自增列
/// </summary>
public class Dict
{
/// <summary>
/// 获得/设置 字典主键 数据库自增列
/// </summary>
public string? Id { get; set; }
public string? Id { get; set; }
/// <summary>
/// 获得/设置 字典标签
/// </summary>
[Required(ErrorMessage = "{0}不可为空")]
[Display(Name = "字典标签")]
public string Category { get; set; } = "";
/// <summary>
/// 获得/设置 字典标签
/// </summary>
[Required(ErrorMessage = "{0}不可为空")]
[Display(Name = "字典标签")]
public string Category { get; set; } = "";
/// <summary>
/// 获得/设置 字典名称
/// </summary>
[Required(ErrorMessage = "{0}不可为空")]
[Display(Name = "字典名称")]
public string Name { get; set; } = "";
/// <summary>
/// 获得/设置 字典名称
/// </summary>
[Required(ErrorMessage = "{0}不可为空")]
[Display(Name = "字典名称")]
public string Name { get; set; } = "";
/// <summary>
/// 获得/设置 字典字典值
/// </summary>
[Required(ErrorMessage = "{0}不可为空")]
[Display(Name = "字典代码")]
public string Code { get; set; } = "";
/// <summary>
/// 获得/设置 字典字典值
/// </summary>
[Required(ErrorMessage = "{0}不可为空")]
[Display(Name = "字典代码")]
public string Code { get; set; } = "";
/// <summary>
/// 获得/设置 字典定义值 0 表示系统使用1 表示用户自定义 默认为 1
/// </summary>
[Display(Name = "字典类型")]
public EnumDictDefine Define { get; set; } = EnumDictDefine.Customer;
}
/// <summary>
/// 获得/设置 字典定义值 0 表示系统使用1 表示用户自定义 默认为 1
/// </summary>
[Display(Name = "字典类型")]
public EnumDictDefine Define { get; set; } = EnumDictDefine.Customer;
}

View File

@ -1,22 +1,21 @@
using System.ComponentModel;
namespace BootstrapAdmin.DataAccess.Models
namespace BootstrapAdmin.DataAccess.Models;
/// <summary>
/// 字典定义值 0 表示系统使用1 表示用户自定义 默认为 1
/// </summary>
public enum EnumDictDefine
{
/// <summary>
/// 字典定义值 0 表示系统使用1 表示用户自定义 默认为 1
/// 系统使用
/// </summary>
public enum EnumDictDefine
{
/// <summary>
/// 系统使用
/// </summary>
[Description("系统使用")]
System,
[Description("系统使用")]
System,
/// <summary>
/// 用户自定义
/// </summary>
[Description("自定义")]
Customer
}
/// <summary>
/// 用户自定义
/// </summary>
[Description("自定义")]
Customer
}

View File

@ -1,22 +1,21 @@
using System.ComponentModel;
namespace BootstrapAdmin.DataAccess.Models
namespace BootstrapAdmin.DataAccess.Models;
/// <summary>
/// 菜单分类 0 表示系统菜单 1 表示用户自定义菜单
/// </summary>
public enum EnumNavigationCategory
{
/// <summary>
/// 菜单分类 0 表示系统菜单 1 表示用户自定义菜单
/// 系统使用
/// </summary>
public enum EnumNavigationCategory
{
/// <summary>
/// 系统使用
/// </summary>
[Description("系统使用")]
System,
[Description("系统使用")]
System,
/// <summary>
/// 用户自定义
/// </summary>
[Description("自定义")]
Customer
}
/// <summary>
/// 用户自定义
/// </summary>
[Description("自定义")]
Customer
}

View File

@ -1,26 +1,25 @@
using System.ComponentModel;
namespace BootstrapAdmin.DataAccess.Models
namespace BootstrapAdmin.DataAccess.Models;
/// <summary>
/// 资源类型枚举 0 表示菜单 1 表示资源 2 表示按钮
/// </summary>
public enum EnumResource
{
/// <summary>
/// 资源类型枚举 0 表示菜单 1 表示资源 2 表示按钮
///
/// </summary>
public enum EnumResource
{
/// <summary>
///
/// </summary>
[Description("菜单")]
Navigation,
/// <summary>
///
/// </summary>
[Description("资源")]
Resource,
/// <summary>
///
/// </summary>
[Description("代码块")]
Block
}
[Description("菜单")]
Navigation,
/// <summary>
///
/// </summary>
[Description("资源")]
Resource,
/// <summary>
///
/// </summary>
[Description("代码块")]
Block
}

View File

@ -1,37 +1,36 @@
using System.ComponentModel.DataAnnotations;
namespace BootstrapAdmin.DataAccess.Models
namespace BootstrapAdmin.DataAccess.Models;
/// <summary>
/// Group 实体类
/// </summary>
public class Group
{
/// <summary>
/// Group 实体类
/// 获得/设置 主键 ID
/// </summary>
public class Group
{
/// <summary>
/// 获得/设置 主键 ID
/// </summary>
public string? Id { get; set; }
public string? Id { get; set; }
/// <summary>
/// 获得/设置 群组名称
/// </summary>
[Display(Name = "群组名称")]
[NotNull]
public string? GroupName { get; set; }
/// <summary>
/// 获得/设置 群组名称
/// </summary>
[Display(Name = "群组名称")]
[NotNull]
public string? GroupName { get; set; }
/// <summary>
/// 获得/设置 群组编码
/// </summary>
[Display(Name = "群组编码")]
[NotNull]
public string? GroupCode { get; set; }
/// <summary>
/// 获得/设置 群组编码
/// </summary>
[Display(Name = "群组编码")]
[NotNull]
public string? GroupCode { get; set; }
/// <summary>
/// 获得/设置 群组描述
/// </summary>
[Display(Name = "群组描述")]
public string? Description { get; set; }
/// <summary>
/// 获得/设置 群组描述
/// </summary>
[Display(Name = "群组描述")]
public string? Description { get; set; }
public override string ToString() => $"{GroupName} ({GroupCode})";
}
public override string ToString() => $"{GroupName} ({GroupCode})";
}

View File

@ -1,63 +1,62 @@
using System.ComponentModel;
namespace Bootstrap.DataAccess
namespace Bootstrap.DataAccess;
/// <summary>
/// 登录用户信息实体类
/// </summary>
public class LoginLog
{
/// <summary>
/// 登录用户信息实体类
/// 获得/设置 Id
/// </summary>
public class LoginLog
{
/// <summary>
/// 获得/设置 Id
/// </summary>
public string? Id { get; set; }
public string? Id { get; set; }
/// <summary>
/// 获得/设置 用户名
/// </summary>
[DisplayName("登录名称")]
public string UserName { get; set; } = "";
/// <summary>
/// 获得/设置 用户名
/// </summary>
[DisplayName("登录名称")]
public string UserName { get; set; } = "";
/// <summary>
/// 获得/设置 登录时间
/// </summary>
[DisplayName("登录时间")]
public DateTime LoginTime { get; set; }
/// <summary>
/// 获得/设置 登录时间
/// </summary>
[DisplayName("登录时间")]
public DateTime LoginTime { get; set; }
/// <summary>
/// 获得/设置 登录IP地址
/// </summary>
[DisplayName("主机")]
public string Ip { get; set; } = "";
/// <summary>
/// 获得/设置 登录IP地址
/// </summary>
[DisplayName("主机")]
public string Ip { get; set; } = "";
/// <summary>
/// 获得/设置 登录浏览器
/// </summary>
[DisplayName("浏览器")]
public string Browser { get; set; } = "";
/// <summary>
/// 获得/设置 登录浏览器
/// </summary>
[DisplayName("浏览器")]
public string Browser { get; set; } = "";
/// <summary>
/// 获得/设置 登录操作系统
/// </summary>
[DisplayName("操作系统")]
public string OS { get; set; } = "";
/// <summary>
/// 获得/设置 登录操作系统
/// </summary>
[DisplayName("操作系统")]
public string OS { get; set; } = "";
/// <summary>
/// 获得/设置 登录地点
/// </summary>
[DisplayName("登录地点")]
public string City { get; set; } = "";
/// <summary>
/// 获得/设置 登录地点
/// </summary>
[DisplayName("登录地点")]
public string City { get; set; } = "";
/// <summary>
/// 获得/设置 登录是否成功
/// </summary>
[DisplayName("登录结果")]
public string Result { get; set; } = "";
/// <summary>
/// 获得/设置 登录是否成功
/// </summary>
[DisplayName("登录结果")]
public string Result { get; set; } = "";
/// <summary>
/// 获得/设置 用户 UserAgent
/// </summary>
[DisplayName("登录名称")]
public string UserAgent { get; set; } = "";
}
/// <summary>
/// 获得/设置 用户 UserAgent
/// </summary>
[DisplayName("登录名称")]
public string UserAgent { get; set; } = "";
}

View File

@ -2,76 +2,75 @@
using System.ComponentModel.DataAnnotations;
namespace BootstrapAdmin.DataAccess.Models
namespace BootstrapAdmin.DataAccess.Models;
/// <summary>
/// Bootstrap Admin 后台管理菜单相关操作实体类
/// </summary>
public class Navigation
{
/// <summary>
/// Bootstrap Admin 后台管理菜单相关操作实体类
/// 获得/设置 菜单主键ID
/// </summary>
public class Navigation
{
/// <summary>
/// 获得/设置 菜单主键ID
/// </summary>
public string? Id { set; get; }
public string? Id { set; get; }
/// <summary>
/// 获得/设置 父级菜单ID 默认为 0
/// </summary>
public string ParentId { set; get; } = "0";
/// <summary>
/// 获得/设置 父级菜单ID 默认为 0
/// </summary>
public string ParentId { set; get; } = "0";
/// <summary>
/// 获得/设置 菜单名称
/// </summary>
[Display(Name = "名称")]
[NotNull]
public string? Name { get; set; }
/// <summary>
/// 获得/设置 菜单名称
/// </summary>
[Display(Name = "名称")]
[NotNull]
public string? Name { get; set; }
/// <summary>
/// 获得/设置 菜单序号
/// </summary>
[Display(Name = "序号")]
public int Order { get; set; }
/// <summary>
/// 获得/设置 菜单序号
/// </summary>
[Display(Name = "序号")]
public int Order { get; set; }
/// <summary>
/// 获得/设置 菜单图标
/// </summary>
[Display(Name = "图标")]
public string? Icon { get; set; }
/// <summary>
/// 获得/设置 菜单图标
/// </summary>
[Display(Name = "图标")]
public string? Icon { get; set; }
/// <summary>
/// 获得/设置 菜单URL地址
/// </summary>
[NotNull]
[Display(Name = "地址")]
public string? Url { get; set; }
/// <summary>
/// 获得/设置 菜单URL地址
/// </summary>
[NotNull]
[Display(Name = "地址")]
public string? Url { get; set; }
/// <summary>
/// 获得/设置 菜单分类, 0 表示系统菜单 1 表示用户自定义菜单
/// </summary>
[Display(Name = "类别")]
public EnumNavigationCategory Category { get; set; }
/// <summary>
/// 获得/设置 菜单分类, 0 表示系统菜单 1 表示用户自定义菜单
/// </summary>
[Display(Name = "类别")]
public EnumNavigationCategory Category { get; set; }
/// <summary>
/// 获得/设置 链接目标
/// </summary>
[Display(Name = "目标")]
public string? Target { get; set; }
/// <summary>
/// 获得/设置 链接目标
/// </summary>
[Display(Name = "目标")]
public string? Target { get; set; }
/// <summary>
/// 获得/设置 是否为资源文件, 0 表示菜单 1 表示资源 2 表示按钮
/// </summary>
[Display(Name = "类型")]
public EnumResource IsResource { get; set; }
/// <summary>
/// 获得/设置 是否为资源文件, 0 表示菜单 1 表示资源 2 表示按钮
/// </summary>
[Display(Name = "类型")]
public EnumResource IsResource { get; set; }
/// <summary>
/// 获得/设置 所属应用程序此属性由BA后台字典表分配
/// </summary>
[Display(Name = "所属应用")]
public string? Application { get; set; }
/// <summary>
/// 获得/设置 所属应用程序此属性由BA后台字典表分配
/// </summary>
[Display(Name = "所属应用")]
public string? Application { get; set; }
/// <summary>
///
/// </summary>
public bool HasChildren { get; set; }
}
/// <summary>
///
/// </summary>
public bool HasChildren { get; set; }
}

View File

@ -1,30 +1,29 @@
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
namespace BootstrapAdmin.DataAccess.Models
namespace BootstrapAdmin.DataAccess.Models;
/// <summary>
/// Role 实体类
/// </summary>
public class Role
{
/// <summary>
/// Role 实体类
/// 获得/设置 角色主键ID
/// </summary>
public class Role
{
/// <summary>
/// 获得/设置 角色主键ID
/// </summary>
public string? Id { get; set; }
public string? Id { get; set; }
/// <summary>
/// 获得/设置 角色名称
/// </summary>
[DisplayName("角色名称")]
[NotNull]
public string? RoleName { get; set; }
/// <summary>
/// 获得/设置 角色名称
/// </summary>
[DisplayName("角色名称")]
[NotNull]
public string? RoleName { get; set; }
/// <summary>
/// 获得/设置 角色描述
/// </summary>
[DisplayName("角色描述")]
[NotNull]
public string? Description { get; set; }
}
/// <summary>
/// 获得/设置 角色描述
/// </summary>
[DisplayName("角色描述")]
[NotNull]
public string? Description { get; set; }
}

View File

@ -1,152 +1,151 @@
using System.ComponentModel.DataAnnotations;
namespace BootstrapAdmin.DataAccess.Models
namespace BootstrapAdmin.DataAccess.Models;
/// <summary>
///
/// </summary>
public class User
{
/// <summary>
///
/// 获得/设置 系统登录用户名
/// </summary>
public class User
{
/// <summary>
/// 获得/设置 系统登录用户名
/// </summary>
[Display(Name = "登录名称")]
public string? UserName { get; set; }
/// <summary>
/// 获得/设置 用户显示名称
/// </summary>
[Display(Name = "显示名称")]
[Required(ErrorMessage = "{0}不可为空")]
[MaxLength(50, ErrorMessage = "{0}不能超过 50 个字符")]
public string? DisplayName { get; set; }
/// <summary>
/// 获得/设置 用户头像图标路径
/// </summary>
[Display(Name = "用户头像")]
public string? Icon { get; set; }
/// <summary>
/// 获得/设置 用户设置样式表名称
/// </summary>
[Display(Name = "主题")]
public string? Css { get; set; }
/// <summary>
/// 获得/设置 用户默认登陆 App 标识
/// </summary>
[Display(Name = "默认 APP")]
public string? App { get; set; }
/// <summary>
/// 获得/设置 用户主键ID
/// </summary>
public string? Id { get; set; }
/// <summary>
/// 获取/设置 密码
/// </summary>
[Display(Name = "密码")]
[Required(ErrorMessage = "{0}不可为空")]
public string? Password { get; set; }
/// <summary>
/// 获取/设置 密码盐
/// </summary>
public string? PassSalt { get; set; }
/// <summary>
/// 获得/设置 用户注册时间
/// </summary>
[Display(Name = "注册时间")]
public DateTime RegisterTime { get; set; } = DateTime.Now;
/// <summary>
/// 获得/设置 用户被批复时间
/// </summary>
[Display(Name = "授权时间")]
public DateTime? ApprovedTime { get; set; }
/// <summary>
/// 获得/设置 用户批复人
/// </summary>
[Display(Name = "授权人")]
public string? ApprovedBy { get; set; }
/// <summary>
/// 获得/设置 用户的申请理由
/// </summary>
[Display(Name = "说明")]
public string? Description { get; set; }
/// <summary>
/// 获得/设置 通知描述 2分钟内为刚刚
/// </summary>
public string? Period { get; set; }
/// <summary>
/// 获得/设置 新密码
/// </summary>
[Display(Name = "新密码")]
[Required(ErrorMessage = "{0}不可为空")]
[NotNull]
public string? NewPassword { get; set; }
/// <summary>
/// 获得/设置 新密码
/// </summary>
[Display(Name = "确认密码")]
[Required(ErrorMessage = "{0}不可为空")]
[Compare("NewPassword", ErrorMessage = "{0}与{1}不一致")]
[NotNull]
public string? ConfirmPassword { get; set; }
/// <summary>
/// 获得/设置 是否重置密码
/// </summary>
public int IsReset { get; set; }
/// <summary>
/// 获得/设置 默认格式为 DisplayName (UserName)
/// </summary>
/// <returns></returns>
public override string ToString() => $"{DisplayName} ({UserName})";
}
[Display(Name = "登录名称")]
public string? UserName { get; set; }
/// <summary>
/// 用户状态枚举类型
/// 获得/设置 用户显示名称
/// </summary>
public enum UserStates
{
/// <summary>
/// 更改密码
/// </summary>
ChangePassword,
[Display(Name = "显示名称")]
[Required(ErrorMessage = "{0}不可为空")]
[MaxLength(50, ErrorMessage = "{0}不能超过 50 个字符")]
public string? DisplayName { get; set; }
/// <summary>
/// 更改样式
/// </summary>
ChangeTheme,
/// <summary>
/// 获得/设置 用户头像图标路径
/// </summary>
[Display(Name = "用户头像")]
public string? Icon { get; set; }
/// <summary>
/// 更改显示名称
/// </summary>
ChangeDisplayName,
/// <summary>
/// 获得/设置 用户设置样式表名称
/// </summary>
[Display(Name = "主题")]
public string? Css { get; set; }
/// <summary>
/// 审批用户
/// </summary>
ApproveUser,
/// <summary>
/// 获得/设置 用户默认登陆 App 标识
/// </summary>
[Display(Name = "默认 APP")]
public string? App { get; set; }
/// <summary>
/// 拒绝用户
/// </summary>
RejectUser,
/// <summary>
/// 获得/设置 用户主键ID
/// </summary>
public string? Id { get; set; }
/// <summary>
/// 保存默认应用
/// </summary>
SaveApp
}
/// <summary>
/// 获取/设置 密码
/// </summary>
[Display(Name = "密码")]
[Required(ErrorMessage = "{0}不可为空")]
public string? Password { get; set; }
/// <summary>
/// 获取/设置 密码盐
/// </summary>
public string? PassSalt { get; set; }
/// <summary>
/// 获得/设置 用户注册时间
/// </summary>
[Display(Name = "注册时间")]
public DateTime RegisterTime { get; set; } = DateTime.Now;
/// <summary>
/// 获得/设置 用户被批复时间
/// </summary>
[Display(Name = "授权时间")]
public DateTime? ApprovedTime { get; set; }
/// <summary>
/// 获得/设置 用户批复人
/// </summary>
[Display(Name = "授权人")]
public string? ApprovedBy { get; set; }
/// <summary>
/// 获得/设置 用户的申请理由
/// </summary>
[Display(Name = "说明")]
public string? Description { get; set; }
/// <summary>
/// 获得/设置 通知描述 2分钟内为刚刚
/// </summary>
public string? Period { get; set; }
/// <summary>
/// 获得/设置 新密码
/// </summary>
[Display(Name = "新密码")]
[Required(ErrorMessage = "{0}不可为空")]
[NotNull]
public string? NewPassword { get; set; }
/// <summary>
/// 获得/设置 新密码
/// </summary>
[Display(Name = "确认密码")]
[Required(ErrorMessage = "{0}不可为空")]
[Compare("NewPassword", ErrorMessage = "{0}与{1}不一致")]
[NotNull]
public string? ConfirmPassword { get; set; }
/// <summary>
/// 获得/设置 是否重置密码
/// </summary>
public int IsReset { get; set; }
/// <summary>
/// 获得/设置 默认格式为 DisplayName (UserName)
/// </summary>
/// <returns></returns>
public override string ToString() => $"{DisplayName} ({UserName})";
}
/// <summary>
/// 用户状态枚举类型
/// </summary>
public enum UserStates
{
/// <summary>
/// 更改密码
/// </summary>
ChangePassword,
/// <summary>
/// 更改样式
/// </summary>
ChangeTheme,
/// <summary>
/// 更改显示名称
/// </summary>
ChangeDisplayName,
/// <summary>
/// 审批用户
/// </summary>
ApproveUser,
/// <summary>
/// 拒绝用户
/// </summary>
RejectUser,
/// <summary>
/// 保存默认应用
/// </summary>
SaveApp
}

View File

@ -1,13 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<PackageReference Include="BootstrapBlazor" Version="6.1.1" />
<!--<PackageReference Include="BootstrapBlazor" Version="6.1.1" />-->
<PackageReference Include="Longbow.Security.Cryptography" Version="5.2.0" />
<PackageReference Include="Microsoft.Data.Sqlite" Version="6.0.0" />
<PackageReference Include="PetaPoco.Extensions" Version="5.2.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\..\BootstrapBlazor\src\BootstrapBlazor\BootstrapBlazor.csproj" />
<ProjectReference Include="..\BootstrapAdmin.Web.Core\BootstrapAdmin.Web.Core.csproj" />
</ItemGroup>

View File

@ -2,73 +2,72 @@
using PetaPoco;
using System.Reflection;
namespace BootstrapAdmin.DataAccess.PetaPoco
namespace BootstrapAdmin.DataAccess.PetaPoco;
class BootstrapAdminConventionMapper : ConventionMapper
{
class BootstrapAdminConventionMapper : ConventionMapper
/// <summary>
///
/// </summary>
/// <param name="pocoType"></param>
/// <returns></returns>
public override TableInfo GetTableInfo(Type pocoType)
{
/// <summary>
///
/// </summary>
/// <param name="pocoType"></param>
/// <returns></returns>
public override TableInfo GetTableInfo(Type pocoType)
var ti = base.GetTableInfo(pocoType);
ti.AutoIncrement = true;
// 支持 Oracle 数据库
ti.SequenceName = $"SEQ_{ti.TableName.ToUpperInvariant()}_ID";
ti.TableName = pocoType.Name switch
{
var ti = base.GetTableInfo(pocoType);
ti.AutoIncrement = true;
// 支持 Oracle 数据库
ti.SequenceName = $"SEQ_{ti.TableName.ToUpperInvariant()}_ID";
ti.TableName = pocoType.Name switch
{
_ => $"{pocoType.Name}s"
};
return ti;
}
/// <summary>
///
/// </summary>
/// <param name="pocoProperty"></param>
/// <returns></returns>
public override ColumnInfo GetColumnInfo(PropertyInfo pocoProperty) => pocoProperty.DeclaringType?.Name switch
{
nameof(Models.User) => GetUserColumnInfo(pocoProperty),
nameof(Models.Navigation) => GetNavigationColumnInfo(pocoProperty),
_ => base.GetColumnInfo(pocoProperty)
_ => $"{pocoType.Name}s"
};
return ti;
}
private ColumnInfo GetUserColumnInfo(PropertyInfo pocoProperty)
{
var ci = base.GetColumnInfo(pocoProperty);
var resultColumns = new List<string>
/// <summary>
///
/// </summary>
/// <param name="pocoProperty"></param>
/// <returns></returns>
public override ColumnInfo GetColumnInfo(PropertyInfo pocoProperty) => pocoProperty.DeclaringType?.Name switch
{
nameof(Models.User) => GetUserColumnInfo(pocoProperty),
nameof(Models.Navigation) => GetNavigationColumnInfo(pocoProperty),
_ => base.GetColumnInfo(pocoProperty)
};
private ColumnInfo GetUserColumnInfo(PropertyInfo pocoProperty)
{
var ci = base.GetColumnInfo(pocoProperty);
var resultColumns = new List<string>
{
nameof(Models.User.Period),
nameof(Models.User.NewPassword),
nameof(Models.User.ConfirmPassword),
nameof(Models.User.IsReset)
};
ci.ResultColumn = resultColumns.Any(c => c == ci.ColumnName);
return ci;
}
ci.ResultColumn = resultColumns.Any(c => c == ci.ColumnName);
return ci;
}
private ColumnInfo GetNavigationColumnInfo(PropertyInfo pocoProperty)
{
var ci = base.GetColumnInfo(pocoProperty);
var resultColumns = new List<string>
private ColumnInfo GetNavigationColumnInfo(PropertyInfo pocoProperty)
{
var ci = base.GetColumnInfo(pocoProperty);
var resultColumns = new List<string>
{
nameof(Models.Navigation.HasChildren)
};
ci.ResultColumn = resultColumns.Any(c => c == ci.ColumnName);
return ci;
}
public override Func<object?, object?> GetFromDbConverter(PropertyInfo targetProperty, Type sourceType) => targetProperty.PropertyType.IsEnum && sourceType == typeof(string)
? new StringToEnumConverter(targetProperty.PropertyType).ConvertFromDb
: base.GetFromDbConverter(targetProperty, sourceType);
public override Func<object?, object?> GetToDbConverter(PropertyInfo targetProperty) => targetProperty.PropertyType.IsEnum
? new StringToEnumConverter(targetProperty.PropertyType).ConvertToDb
: base.GetToDbConverter(targetProperty);
ci.ResultColumn = resultColumns.Any(c => c == ci.ColumnName);
return ci;
}
public override Func<object?, object?> GetFromDbConverter(PropertyInfo targetProperty, Type sourceType) => targetProperty.PropertyType.IsEnum && sourceType == typeof(string)
? new StringToEnumConverter(targetProperty.PropertyType).ConvertFromDb
: base.GetFromDbConverter(targetProperty, sourceType);
public override Func<object?, object?> GetToDbConverter(PropertyInfo targetProperty) => targetProperty.PropertyType.IsEnum
? new StringToEnumConverter(targetProperty.PropertyType).ConvertToDb
: base.GetToDbConverter(targetProperty);
}

View File

@ -1,59 +1,58 @@
namespace BootstrapAdmin.DataAccess.PetaPoco.Coverters
namespace BootstrapAdmin.DataAccess.PetaPoco.Coverters;
/// <summary>
/// 字符串转枚举转换器
/// </summary>
public class StringToEnumConverter
{
private Type TargetType { get; set; }
/// <summary>
/// 字符串转枚举转换器
///
/// </summary>
public class StringToEnumConverter
/// <param name="targetType"></param>
public StringToEnumConverter(Type targetType) => TargetType = targetType;
/// <summary>
///
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public object? ConvertFromDb(object? value)
{
private Type TargetType { get; set; }
if (value == null) throw new ArgumentNullException(nameof(value));
/// <summary>
///
/// </summary>
/// <param name="targetType"></param>
public StringToEnumConverter(Type targetType) => TargetType = targetType;
/// <summary>
///
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public object? ConvertFromDb(object? value)
object? ret;
if (value != null && Enum.TryParse(TargetType, value.ToString(), true, out var v))
{
if (value == null) throw new ArgumentNullException(nameof(value));
object? ret;
if (value != null && Enum.TryParse(TargetType, value.ToString(), true, out var v))
{
ret = v;
}
else
{
throw new InvalidCastException($"{value} 无法转化为 {TargetType.Name} 成员");
}
return ret;
ret = v;
}
/// <summary>
///
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public object? ConvertToDb(object? value)
else
{
object? ret;
var field = value?.ToString();
if (!string.IsNullOrEmpty(field) && Enum.IsDefined(TargetType, field))
{
ret = field;
}
else
{
throw new InvalidCastException($"{TargetType.Name} 未定义 {field} 成员");
}
return ret;
throw new InvalidCastException($"{value} 无法转化为 {TargetType.Name} 成员");
}
return ret;
}
/// <summary>
///
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public object? ConvertToDb(object? value)
{
object? ret;
var field = value?.ToString();
if (!string.IsNullOrEmpty(field) && Enum.IsDefined(TargetType, field))
{
ret = field;
}
else
{
throw new InvalidCastException($"{TargetType.Name} 未定义 {field} 成员");
}
return ret;
}
}

View File

@ -7,176 +7,175 @@ using PetaPoco;
using System.Linq.Expressions;
using System.Reflection;
namespace BootstrapAdmin.Web.Extensions
namespace BootstrapAdmin.Web.Extensions;
/// <summary>
///
/// </summary>
public static class DatabaseExtensions
{
/// <summary>
///
/// </summary>
public static class DatabaseExtensions
/// <typeparam name="TModel"></typeparam>
/// <returns></returns>
public static Task<List<TModel>> FetchAsync<TModel>(this IDatabase db, QueryPageOptions options)
{
/// <summary>
///
/// </summary>
/// <typeparam name="TModel"></typeparam>
/// <returns></returns>
public static Task<List<TModel>> FetchAsync<TModel>(this IDatabase db, QueryPageOptions options)
var sql = new Sql();
// 处理模糊查询
if (options.Searchs.Any())
{
var sql = new Sql();
// 处理模糊查询
if (options.Searchs.Any())
{
var searchTextSql = new Sql();
AnalysisExpression(options.Searchs.GetFilterLambda<TModel>(FilterLogic.Or), db, searchTextSql);
sql.Append(searchTextSql.ToString().Replace("\nAND", "\nOR"), searchTextSql.Arguments);
}
// 处理高级搜索与过滤
var filters = options.Filters.Concat(options.CustomerSearchs);
if (filters.Any())
{
AnalysisExpression(filters.GetFilterLambda<TModel>(), db, sql);
}
var sortName = options.SortName;
var sortOrder = options.SortOrder;
if (!string.IsNullOrEmpty(sortName) && sortOrder != SortOrder.Unset)
{
sql.OrderBy(sortOrder == SortOrder.Asc ? sortName : $"{sortName} desc");
}
return db.FetchAsync<TModel>(sql);
var searchTextSql = new Sql();
AnalysisExpression(options.Searchs.GetFilterLambda<TModel>(FilterLogic.Or), db, searchTextSql);
sql.Append(searchTextSql.ToString().Replace("\nAND", "\nOR"), searchTextSql.Arguments);
}
/// <summary>
///
/// </summary>
/// <typeparam name="TModel"></typeparam>
/// <returns></returns>
public static Task<Page<TModel>> PageAsync<TModel>(this IDatabase db, QueryPageOptions options)
// 处理高级搜索与过滤
var filters = options.Filters.Concat(options.CustomerSearchs);
if (filters.Any())
{
var sql = new Sql();
// 处理模糊查询
if (options.Searchs.Any())
{
var searchTextSql = new Sql();
AnalysisExpression(options.Searchs.GetFilterLambda<TModel>(FilterLogic.Or), db, searchTextSql);
sql.Append(searchTextSql.ToString().Replace("\nAND", "OR"), searchTextSql.Arguments);
}
// 处理高级搜索与过滤
var filters = options.Filters.Concat(options.CustomerSearchs);
if (filters.Any())
{
AnalysisExpression(filters.GetFilterLambda<TModel>(), db, sql);
}
var sortName = options.SortName;
var sortOrder = options.SortOrder;
if (!string.IsNullOrEmpty(sortName) && sortOrder != SortOrder.Unset)
{
sql.OrderBy(sortOrder == SortOrder.Asc ? sortName : $"{sortName} desc");
}
return db.PageAsync<TModel>(options.PageIndex, options.PageItems, sql);
AnalysisExpression(filters.GetFilterLambda<TModel>(), db, sql);
}
private static void AnalysisExpression(Expression expression, IDatabase db, Sql sql)
var sortName = options.SortName;
var sortOrder = options.SortOrder;
if (!string.IsNullOrEmpty(sortName) && sortOrder != SortOrder.Unset)
{
switch (expression.NodeType)
{
case ExpressionType.Lambda:
if (expression is LambdaExpression exp)
{
AnalysisExpression(exp.Body, db, sql);
}
break;
case ExpressionType.AndAlso:
if (expression is BinaryExpression andExp)
{
AnalysisExpression(andExp.Left, db, sql);
AnalysisExpression(andExp.Right, db, sql);
}
break;
case ExpressionType.OrElse:
if (expression is BinaryExpression orExp)
{
AnalysisExpression(orExp.Left, db, sql);
AnalysisExpression(orExp.Right, db, sql);
}
break;
case ExpressionType.Call:
if (expression is MethodCallExpression callExp)
{
if (callExp.Method.Name == "Contains")
{
if (callExp.Object is MemberExpression callLeft)
{
var callColName = GetColumnName(callLeft.Member) ?? callLeft.Member.Name;
var p = (callExp.Arguments[0] as ConstantExpression)?.Value;
if (p != null)
{
sql.Where($"{db.Provider.EscapeSqlIdentifier(callColName)} like @0", $"%{p}%");
}
}
}
}
break;
case ExpressionType.Equal:
case ExpressionType.NotEqual:
case ExpressionType.GreaterThan:
case ExpressionType.GreaterThanOrEqual:
case ExpressionType.LessThan:
case ExpressionType.LessThanOrEqual:
if (expression is BinaryExpression binaryExp)
{
MemberExpression? left = null;
if (binaryExp.Left is MethodCallExpression methodLeft && methodLeft.Method.Name == "ToString" && methodLeft.Object is MemberExpression p && p.Type.IsEnum)
{
// 枚举转字符串
left = p;
}
else if (binaryExp.Left is MemberExpression m)
{
left = m;
}
if (left != null)
{
// 查找 PetaPoco.Column 标签
var columnName = GetColumnName(left.Member) ?? left.Member.Name;
// 查找操作符右侧
if (binaryExp.Right is ConstantExpression right)
{
var v = right.Value;
if (v != null)
{
var val = v.GetType().IsEnum ? v.ToString() : v;
var operatorExp = GetOperatorExpression(expression);
sql.Where($"{db.Provider.EscapeSqlIdentifier(columnName)} {operatorExp} @0", val);
}
}
}
}
break;
}
sql.OrderBy(sortOrder == SortOrder.Asc ? sortName : $"{sortName} desc");
}
private static string? GetColumnName(MemberInfo member) => member.CustomAttributes
.FirstOrDefault(i => i.AttributeType == typeof(ColumnAttribute))?.NamedArguments
.FirstOrDefault(i => i.MemberName == "Name").TypedValue.Value?.ToString();
private static string GetOperatorExpression(Expression expression) => expression.NodeType switch
{
ExpressionType.Equal => "=",
ExpressionType.NotEqual => "!=",
ExpressionType.GreaterThan => ">",
ExpressionType.GreaterThanOrEqual => ">=",
ExpressionType.LessThan => "<",
ExpressionType.LessThanOrEqual => "<=",
_ => ""
};
return db.FetchAsync<TModel>(sql);
}
/// <summary>
///
/// </summary>
/// <typeparam name="TModel"></typeparam>
/// <returns></returns>
public static Task<Page<TModel>> PageAsync<TModel>(this IDatabase db, QueryPageOptions options)
{
var sql = new Sql();
// 处理模糊查询
if (options.Searchs.Any())
{
var searchTextSql = new Sql();
AnalysisExpression(options.Searchs.GetFilterLambda<TModel>(FilterLogic.Or), db, searchTextSql);
sql.Append(searchTextSql.ToString().Replace("\nAND", "OR"), searchTextSql.Arguments);
}
// 处理高级搜索与过滤
var filters = options.Filters.Concat(options.CustomerSearchs);
if (filters.Any())
{
AnalysisExpression(filters.GetFilterLambda<TModel>(), db, sql);
}
var sortName = options.SortName;
var sortOrder = options.SortOrder;
if (!string.IsNullOrEmpty(sortName) && sortOrder != SortOrder.Unset)
{
sql.OrderBy(sortOrder == SortOrder.Asc ? sortName : $"{sortName} desc");
}
return db.PageAsync<TModel>(options.PageIndex, options.PageItems, sql);
}
private static void AnalysisExpression(Expression expression, IDatabase db, Sql sql)
{
switch (expression.NodeType)
{
case ExpressionType.Lambda:
if (expression is LambdaExpression exp)
{
AnalysisExpression(exp.Body, db, sql);
}
break;
case ExpressionType.AndAlso:
if (expression is BinaryExpression andExp)
{
AnalysisExpression(andExp.Left, db, sql);
AnalysisExpression(andExp.Right, db, sql);
}
break;
case ExpressionType.OrElse:
if (expression is BinaryExpression orExp)
{
AnalysisExpression(orExp.Left, db, sql);
AnalysisExpression(orExp.Right, db, sql);
}
break;
case ExpressionType.Call:
if (expression is MethodCallExpression callExp)
{
if (callExp.Method.Name == "Contains")
{
if (callExp.Object is MemberExpression callLeft)
{
var callColName = GetColumnName(callLeft.Member) ?? callLeft.Member.Name;
var p = (callExp.Arguments[0] as ConstantExpression)?.Value;
if (p != null)
{
sql.Where($"{db.Provider.EscapeSqlIdentifier(callColName)} like @0", $"%{p}%");
}
}
}
}
break;
case ExpressionType.Equal:
case ExpressionType.NotEqual:
case ExpressionType.GreaterThan:
case ExpressionType.GreaterThanOrEqual:
case ExpressionType.LessThan:
case ExpressionType.LessThanOrEqual:
if (expression is BinaryExpression binaryExp)
{
MemberExpression? left = null;
if (binaryExp.Left is MethodCallExpression methodLeft && methodLeft.Method.Name == "ToString" && methodLeft.Object is MemberExpression p && p.Type.IsEnum)
{
// 枚举转字符串
left = p;
}
else if (binaryExp.Left is MemberExpression m)
{
left = m;
}
if (left != null)
{
// 查找 PetaPoco.Column 标签
var columnName = GetColumnName(left.Member) ?? left.Member.Name;
// 查找操作符右侧
if (binaryExp.Right is ConstantExpression right)
{
var v = right.Value;
if (v != null)
{
var val = v.GetType().IsEnum ? v.ToString() : v;
var operatorExp = GetOperatorExpression(expression);
sql.Where($"{db.Provider.EscapeSqlIdentifier(columnName)} {operatorExp} @0", val);
}
}
}
}
break;
}
}
private static string? GetColumnName(MemberInfo member) => member.CustomAttributes
.FirstOrDefault(i => i.AttributeType == typeof(ColumnAttribute))?.NamedArguments
.FirstOrDefault(i => i.MemberName == "Name").TypedValue.Value?.ToString();
private static string GetOperatorExpression(Expression expression) => expression.NodeType switch
{
ExpressionType.Equal => "=",
ExpressionType.NotEqual => "!=",
ExpressionType.GreaterThan => ">",
ExpressionType.GreaterThanOrEqual => ">=",
ExpressionType.LessThan => "<",
ExpressionType.LessThanOrEqual => "<=",
_ => ""
};
}

View File

@ -14,66 +14,65 @@ using System.Collections.Specialized;
using System.Data.Common;
using System.Text;
namespace Microsoft.Extensions.DependencyInjection
namespace Microsoft.Extensions.DependencyInjection;
/// <summary>
///
/// </summary>
public static class ServicesExtensions
{
/// <summary>
///
/// </summary>
public static class ServicesExtensions
/// <param name="services"></param>
/// <returns></returns>
public static IServiceCollection AddPetaPocoDataAccessServices(this IServiceCollection services)
{
/// <summary>
///
/// </summary>
/// <param name="services"></param>
/// <returns></returns>
public static IServiceCollection AddPetaPocoDataAccessServices(this IServiceCollection services)
services.TryAddSingleton<IDatabase>(provider =>
{
services.TryAddSingleton<IDatabase>(provider =>
{
//TODO: 后期改造成自定适配
var configuration = provider.GetRequiredService<IConfiguration>();
var connString = configuration.GetConnectionString("bb");
var db = new Database<SQLiteDatabaseProvider>(connString, new BootstrapAdminConventionMapper());
var connString = configuration.GetConnectionString("bb");
var db = new Database<SQLiteDatabaseProvider>(connString, new BootstrapAdminConventionMapper());
var logger = provider.GetRequiredService<ILogger<Database>>();
db.ExceptionThrown += (sender, e) =>
var logger = provider.GetRequiredService<ILogger<Database>>();
db.ExceptionThrown += (sender, e) =>
{
var message = e.Exception.Format(new NameValueCollection()
{
var message = e.Exception.Format(new NameValueCollection()
{
[nameof(db.LastCommand)] = db.LastCommand,
[nameof(db.LastArgs)] = string.Join(",", db.LastArgs)
});
logger.LogInformation(message);
};
var env = provider.GetRequiredService<IWebHostEnvironment>();
if (env.IsDevelopment())
[nameof(db.LastCommand)] = db.LastCommand,
[nameof(db.LastArgs)] = string.Join(",", db.LastArgs)
});
logger.LogInformation(message);
};
var env = provider.GetRequiredService<IWebHostEnvironment>();
if (env.IsDevelopment())
{
db.CommandExecuted += (sender, args) =>
{
db.CommandExecuted += (sender, args) =>
var parameters = new StringBuilder();
foreach (DbParameter p in args.Command.Parameters)
{
var parameters = new StringBuilder();
foreach (DbParameter p in args.Command.Parameters)
{
parameters.AppendFormat("{0}: {1} ", p.ParameterName, p.Value);
}
logger.LogInformation(args.Command.CommandText);
logger.LogInformation(parameters.ToString());
};
parameters.AppendFormat("{0}: {1} ", p.ParameterName, p.Value);
}
logger.LogInformation(args.Command.CommandText);
logger.LogInformation(parameters.ToString());
};
return db;
});
};
return db;
});
// 增加数据服务
services.AddSingleton(typeof(IDataService<>), typeof(DefaultDataService<>));
// 增加数据服务
services.AddSingleton(typeof(IDataService<>), typeof(DefaultDataService<>));
// 增加业务服务
services.AddSingleton<INavigation, NavigationService>();
services.AddSingleton<IDict, DictService>();
services.AddSingleton<IUser, UserService>();
services.AddSingleton<ILogin, LoginService>();
services.AddSingleton<IRole, RoleService>();
services.AddSingleton<IGroup, GroupService>();
services.AddSingleton<IApp, AppService>();
return services;
}
// 增加业务服务
services.AddSingleton<INavigation, NavigationService>();
services.AddSingleton<IDict, DictService>();
services.AddSingleton<IUser, UserService>();
services.AddSingleton<ILogin, LoginService>();
services.AddSingleton<IRole, RoleService>();
services.AddSingleton<IGroup, GroupService>();
services.AddSingleton<IApp, AppService>();
return services;
}
}

View File

@ -1,13 +1,12 @@
using PetaPoco;
namespace BootstrapAdmin.DataAccess.PetaPoco.Services
namespace BootstrapAdmin.DataAccess.PetaPoco.Services;
abstract class BaseDatabase
{
abstract class BaseDatabase
{
/// <summary>
///
/// </summary>
[NotNull]
protected IDatabase? Database { get; set; }
}
/// <summary>
///
/// </summary>
[NotNull]
protected IDatabase? Database { get; set; }
}

View File

@ -7,80 +7,79 @@ using BootstrapBlazor.Components;
using PetaPoco;
using PetaPoco.Extensions;
namespace BootstrapBlazor.DataAcces.PetaPoco.Services
namespace BootstrapBlazor.DataAcces.PetaPoco.Services;
/// <summary>
/// PetaPoco ORM 的 IDataService 接口实现
/// </summary>
class DefaultDataService<TModel> : DataServiceBase<TModel> where TModel : class, new()
{
private IDatabase Database { get; }
/// <summary>
/// PetaPoco ORM 的 IDataService 接口实现
/// 构造函数
/// </summary>
class DefaultDataService<TModel> : DataServiceBase<TModel> where TModel : class, new()
public DefaultDataService(IDatabase db) => Database = db;
/// <summary>
/// 删除方法
/// </summary>
/// <param name="models"></param>
/// <returns></returns>
public override Task<bool> DeleteAsync(IEnumerable<TModel> models)
{
private IDatabase Database { get; }
// 通过模型获取主键列数据
// 支持批量删除
Database.DeleteBatch(models);
return Task.FromResult(true);
}
/// <summary>
/// 构造函数
/// </summary>
public DefaultDataService(IDatabase db) => Database = db;
/// <summary>
/// 删除方法
/// </summary>
/// <param name="models"></param>
/// <returns></returns>
public override Task<bool> DeleteAsync(IEnumerable<TModel> models)
/// <summary>
/// 保存方法
/// </summary>
/// <param name="model"></param>
/// <param name="changedType"></param>
/// <returns></returns>
public override async Task<bool> SaveAsync(TModel model, ItemChangedType changedType)
{
if (changedType == ItemChangedType.Add)
{
// 通过模型获取主键列数据
// 支持批量删除
Database.DeleteBatch(models);
return Task.FromResult(true);
await Database.InsertAsync(model);
}
/// <summary>
/// 保存方法
/// </summary>
/// <param name="model"></param>
/// <param name="changedType"></param>
/// <returns></returns>
public override async Task<bool> SaveAsync(TModel model, ItemChangedType changedType)
else
{
if (changedType == ItemChangedType.Add)
{
await Database.InsertAsync(model);
}
else
{
await Database.UpdateAsync(model);
}
return true;
await Database.UpdateAsync(model);
}
return true;
}
/// <summary>
/// 查询方法
/// </summary>
/// <param name="option"></param>
/// <returns></returns>
public override async Task<QueryData<TModel>> QueryAsync(QueryPageOptions option)
/// <summary>
/// 查询方法
/// </summary>
/// <param name="option"></param>
/// <returns></returns>
public override async Task<QueryData<TModel>> QueryAsync(QueryPageOptions option)
{
var ret = new QueryData<TModel>()
{
var ret = new QueryData<TModel>()
{
IsSorted = true,
IsFiltered = true,
IsSearch = true
};
IsSorted = true,
IsFiltered = true,
IsSearch = true
};
if (option.IsPage)
{
var items = await Database.PageAsync<TModel>(option);
if (option.IsPage)
{
var items = await Database.PageAsync<TModel>(option);
ret.TotalCount = Convert.ToInt32(items.TotalItems);
ret.Items = items.Items;
}
else
{
var items = await Database.FetchAsync<TModel>(option);
ret.TotalCount = items.Count;
ret.Items = items;
}
return ret;
ret.TotalCount = Convert.ToInt32(items.TotalItems);
ret.Items = items.Items;
}
else
{
var items = await Database.FetchAsync<TModel>(option);
ret.TotalCount = items.Count;
ret.Items = items;
}
return ret;
}
}

View File

@ -5,20 +5,19 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BootstrapAdmin.DataAccess.PetaPoco.Services
namespace BootstrapAdmin.DataAccess.PetaPoco.Services;
class LoginService : ILogin
{
class LoginService : ILogin
/// <summary>
///
/// </summary>
/// <param name="userName"></param>
/// <param name="result"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public Task<bool> Log(string userName, bool result)
{
/// <summary>
///
/// </summary>
/// <param name="userName"></param>
/// <param name="result"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public Task<bool> Log(string userName, bool result)
{
return Task.FromResult(true);
}
return Task.FromResult(true);
}
}

View File

@ -2,60 +2,59 @@
using BootstrapAdmin.Web.Core;
using PetaPoco;
namespace BootstrapAdmin.DataAccess.PetaPoco.Services
namespace BootstrapAdmin.DataAccess.PetaPoco.Services;
/// <summary>
///
/// </summary>
class NavigationService : BaseDatabase, INavigation
{
/// <summary>
///
/// </summary>
class NavigationService : BaseDatabase, INavigation
/// <param name="db"></param>
public NavigationService(IDatabase db) => Database = db;
/// <summary>
/// 获得指定用户名可访问的所有菜单集合
/// </summary>
/// <param name="userName">当前用户名</param>
/// <returns>未层次化的菜单集合</returns>
public List<Navigation> GetAllMenus(string userName)
{
/// <summary>
///
/// </summary>
/// <param name="db"></param>
public NavigationService(IDatabase db) => Database = db;
var order = Database.Provider.EscapeSqlIdentifier("Order");
return Database.Fetch<Models.Navigation>($"select n.ID, n.ParentId, n.Name, n.{order}, n.Icon, n.Url, n.Category, n.Target, n.IsResource, n.Application, ln.Name as ParentName from Navigations n inner join Dicts d on n.Category = d.Code and d.Category = @Category and d.Define = 'System' left join Navigations ln on n.ParentId = ln.ID inner join (select nr.NavigationID from Users u inner join UserRole ur on ur.UserID = u.ID inner join NavigationRole nr on nr.RoleID = ur.RoleID where u.UserName = @UserName union select nr.NavigationID from Users u inner join UserGroup ug on u.ID = ug.UserID inner join RoleGroup rg on rg.GroupID = ug.GroupID inner join NavigationRole nr on nr.RoleID = rg.RoleID where u.UserName = @UserName union select n.ID from Navigations n where EXISTS (select UserName from Users u inner join UserRole ur on u.ID = ur.UserID inner join Roles r on ur.RoleID = r.ID where u.UserName = @UserName and r.RoleName = @RoleName)) nav on n.ID = nav.NavigationID ORDER BY n.Application, n.{order}", new { UserName = userName, Category = "菜单", RoleName = "Administrators" });
}
/// <summary>
/// 获得指定用户名可访问的所有菜单集合
/// </summary>
/// <param name="userName">当前用户名</param>
/// <returns>未层次化的菜单集合</returns>
public List<Navigation> GetAllMenus(string userName)
/// <summary>
///
/// </summary>
/// <param name="roleId"></param>
/// <returns></returns>
public List<string> GetMenusByRoleId(string? roleId) => Database.Fetch<string>("select NavigationID from NavigationRole where RoleID = @0", roleId);
/// <summary>
///
/// </summary>
/// <param name="roleId"></param>
/// <param name="menuIds"></param>
/// <returns></returns>
public bool SaveMenusByRoleId(string? roleId, List<string> menuIds)
{
var ret = false;
try
{
var order = Database.Provider.EscapeSqlIdentifier("Order");
return Database.Fetch<Models.Navigation>($"select n.ID, n.ParentId, n.Name, n.{order}, n.Icon, n.Url, n.Category, n.Target, n.IsResource, n.Application, ln.Name as ParentName from Navigations n inner join Dicts d on n.Category = d.Code and d.Category = @Category and d.Define = 'System' left join Navigations ln on n.ParentId = ln.ID inner join (select nr.NavigationID from Users u inner join UserRole ur on ur.UserID = u.ID inner join NavigationRole nr on nr.RoleID = ur.RoleID where u.UserName = @UserName union select nr.NavigationID from Users u inner join UserGroup ug on u.ID = ug.UserID inner join RoleGroup rg on rg.GroupID = ug.GroupID inner join NavigationRole nr on nr.RoleID = rg.RoleID where u.UserName = @UserName union select n.ID from Navigations n where EXISTS (select UserName from Users u inner join UserRole ur on u.ID = ur.UserID inner join Roles r on ur.RoleID = r.ID where u.UserName = @UserName and r.RoleName = @RoleName)) nav on n.ID = nav.NavigationID ORDER BY n.Application, n.{order}", new { UserName = userName, Category = "菜单", RoleName = "Administrators" });
Database.BeginTransaction();
Database.Execute("delete from NavigationRole where RoleID = @0", roleId);
Database.InsertBatch("NavigationRole", menuIds.Select(g => new { NavigationID = g, RoleID = roleId }));
Database.CompleteTransaction();
ret = true;
}
/// <summary>
///
/// </summary>
/// <param name="roleId"></param>
/// <returns></returns>
public List<string> GetMenusByRoleId(string? roleId) => Database.Fetch<string>("select NavigationID from NavigationRole where RoleID = @0", roleId);
/// <summary>
///
/// </summary>
/// <param name="roleId"></param>
/// <param name="menuIds"></param>
/// <returns></returns>
public bool SaveMenusByRoleId(string? roleId, List<string> menuIds)
catch (Exception)
{
var ret = false;
try
{
Database.BeginTransaction();
Database.Execute("delete from NavigationRole where RoleID = @0", roleId);
Database.InsertBatch("NavigationRole", menuIds.Select(g => new { NavigationID = g, RoleID = roleId }));
Database.CompleteTransaction();
ret = true;
}
catch (Exception)
{
Database.AbortTransaction();
throw;
}
return ret;
Database.AbortTransaction();
throw;
}
return ret;
}
}

View File

@ -1,57 +1,56 @@
using Bootstrap.Security.Blazor;
using BootstrapAdmin.Web.Core;
namespace BootstrapAdmin.Web.Services
namespace BootstrapAdmin.Web.Services;
/// <summary>
///
/// </summary>
public class AdminService : IBootstrapAdminService
{
private IUser User { get; set; }
private INavigation Navigations { get; set; }
/// <summary>
///
/// </summary>
public class AdminService : IBootstrapAdminService
/// <param name="user"></param>
/// <param name="navigations"></param>
public AdminService(IUser user, INavigation navigations)
{
private IUser User { get; set; }
User = user;
Navigations = navigations;
}
private INavigation Navigations { get; set; }
/// <summary>
/// 通过用户名获取角色集合方法
/// </summary>
/// <param name="userName"></param>
/// <returns></returns>
public List<string> GetRoles(string userName) => User.GetRoles(userName);
/// <summary>
///
/// </summary>
/// <param name="user"></param>
/// <param name="navigations"></param>
public AdminService(IUser user, INavigation navigations)
/// <summary>
/// 通过用户名获取授权 App 集合方法
/// </summary>
/// <param name="userName"></param>
/// <returns></returns>
public List<string> GetApps(string userName) => User.GetApps(userName);
/// <summary>
/// 通过用户名检查当前请求 Url 是否已授权方法
/// </summary>
/// <param name="userName"></param>
/// <param name="url"></param>
/// <returns></returns>
public Task<bool> AuhorizingNavigation(string userName, string url)
{
var ret = false;
if (Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out var uri))
{
User = user;
Navigations = navigations;
}
/// <summary>
/// 通过用户名获取角色集合方法
/// </summary>
/// <param name="userName"></param>
/// <returns></returns>
public List<string> GetRoles(string userName) => User.GetRoles(userName);
/// <summary>
/// 通过用户名获取授权 App 集合方法
/// </summary>
/// <param name="userName"></param>
/// <returns></returns>
public List<string> GetApps(string userName) => User.GetApps(userName);
/// <summary>
/// 通过用户名检查当前请求 Url 是否已授权方法
/// </summary>
/// <param name="userName"></param>
/// <param name="url"></param>
/// <returns></returns>
public Task<bool> AuhorizingNavigation(string userName, string url)
{
var ret = false;
if (Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out var uri))
{
ret = Navigations.GetAllMenus(userName)
.Any(m => m.Url.Contains(uri.AbsolutePath, StringComparison.OrdinalIgnoreCase));
}
return Task.FromResult(ret);
ret = Navigations.GetAllMenus(userName)
.Any(m => m.Url.Contains(uri.AbsolutePath, StringComparison.OrdinalIgnoreCase));
}
return Task.FromResult(ret);
}
}

View File

@ -1,64 +1,63 @@
namespace BootstrapAdmin.Web.Core
namespace BootstrapAdmin.Web.Core;
/// <summary>
/// Dict 字典表接口
/// </summary>
public interface IDict
{
/// <summary>
/// Dict 字典表接口
/// 获得 配置所有的 App 集合
/// </summary>
public interface IDict
{
/// <summary>
/// 获得 配置所有的 App 集合
/// </summary>
/// <returns></returns>
Dictionary<string, string> GetApps();
/// <returns></returns>
Dictionary<string, string> GetApps();
/// <summary>
/// 获得 配置所有的登录页集合
/// </summary>
/// <returns></returns>
Dictionary<string, string> GetLogins();
/// <summary>
/// 获得 配置所有的登录页集合
/// </summary>
/// <returns></returns>
Dictionary<string, string> GetLogins();
/// <summary>
/// 获得 配置所有的主题集合
/// </summary>
/// <returns></returns>
Dictionary<string, string> GetThemes();
/// <summary>
/// 获得 配置所有的主题集合
/// </summary>
/// <returns></returns>
Dictionary<string, string> GetThemes();
/// <summary>
/// 获取当前系统配置是否为演示模式
/// </summary>
/// <returns></returns>
bool IsDemo();
/// <summary>
/// 获取当前系统配置是否为演示模式
/// </summary>
/// <returns></returns>
bool IsDemo();
/// <summary>
/// 保存当前网站是否为演示系统
/// </summary>
/// <param name="isDemo"></param>
/// <returns></returns>
bool SaveDemo(bool isDemo);
/// <summary>
/// 保存当前网站是否为演示系统
/// </summary>
/// <param name="isDemo"></param>
/// <returns></returns>
bool SaveDemo(bool isDemo);
/// <summary>
/// 保存健康检查
/// </summary>
/// <returns></returns>
bool SaveHealthCheck(bool enable = true);
/// <summary>
/// 保存健康检查
/// </summary>
/// <returns></returns>
bool SaveHealthCheck(bool enable = true);
/// <summary>
/// 获得当前授权码是否有效可更改网站设置
/// </summary>
/// <param name="code"></param>
/// <returns></returns>
bool AuthenticateDemo(string code);
/// <summary>
/// 获得当前授权码是否有效可更改网站设置
/// </summary>
/// <param name="code"></param>
/// <returns></returns>
bool AuthenticateDemo(string code);
/// <summary>
/// 获取 站点 Title 配置信息
/// </summary>
/// <returns></returns>
string GetWebTitle();
/// <summary>
/// 获取 站点 Title 配置信息
/// </summary>
/// <returns></returns>
string GetWebTitle();
/// <summary>
/// 获取站点 Footer 配置信息
/// </summary>
/// <returns></returns>
string GetWebFooter();
}
/// <summary>
/// 获取站点 Footer 配置信息
/// </summary>
/// <returns></returns>
string GetWebFooter();
}

View File

@ -1,16 +1,15 @@
namespace BootstrapAdmin.Web.Core
namespace BootstrapAdmin.Web.Core;
/// <summary>
///
/// </summary>
public interface ILogin
{
/// <summary>
///
/// </summary>
public interface ILogin
{
/// <summary>
///
/// </summary>
/// <param name="userName"></param>
/// <param name="result"></param>
/// <returns></returns>
Task<bool> Log(string userName, bool result);
}
/// <param name="userName"></param>
/// <param name="result"></param>
/// <returns></returns>
Task<bool> Log(string userName, bool result);
}

View File

@ -1,30 +1,29 @@
using BootstrapAdmin.DataAccess.Models;
namespace BootstrapAdmin.Web.Core
namespace BootstrapAdmin.Web.Core;
/// <summary>
///
/// </summary>
public interface INavigation
{
/// <summary>
///
/// </summary>
public interface INavigation
{
/// <summary>
///
/// </summary>
/// <returns></returns>
List<Navigation> GetAllMenus(string userName);
/// <returns></returns>
List<Navigation> GetAllMenus(string userName);
/// <summary>
///
/// </summary>
/// <param name="roleId"></param>
/// <returns></returns>
List<string> GetMenusByRoleId(string? roleId);
/// <summary>
///
/// </summary>
/// <param name="roleId"></param>
/// <returns></returns>
List<string> GetMenusByRoleId(string? roleId);
/// <summary>
///
/// </summary>
/// <param name="roleId"></param>
/// <returns></returns>
bool SaveMenusByRoleId(string? roleId, List<string> menuIds);
}
/// <summary>
///
/// </summary>
/// <param name="roleId"></param>
/// <returns></returns>
bool SaveMenusByRoleId(string? roleId, List<string> menuIds);
}